Home | History | Annotate | Download | only in smp
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2008-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This file contains the implementation of the SMP interface used by
     22  *  applications that can run over an SMP.
     23  *
     24  ******************************************************************************/
     25 #include <string.h>
     26 
     27 #include "bt_target.h"
     28 #if SMP_INCLUDED == TRUE
     29     #include "smp_int.h"
     30     #include "smp_api.h"
     31     #include "l2cdefs.h"
     32     #include "l2c_int.h"
     33     #include "btm_int.h"
     34     #include "hcimsgs.h"
     35 
     36     #include "btu.h"
     37 
     38 
     39 /*******************************************************************************
     40 **
     41 ** Function         SMP_Init
     42 **
     43 ** Description      This function initializes the SMP unit.
     44 **
     45 ** Returns          void
     46 **
     47 *******************************************************************************/
     48 void SMP_Init(void)
     49 {
     50 
     51     SMP_TRACE_EVENT0 ("SMP_Init");
     52     memset(&smp_cb, 0, sizeof(tSMP_CB));
     53 
     54 #if defined(SMP_INITIAL_TRACE_LEVEL)
     55     smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
     56 #else
     57     smp_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
     58 #endif
     59 
     60     smp_l2cap_if_init();
     61 }
     62 
     63 
     64 /*******************************************************************************
     65 **
     66 ** Function         SMP_SetTraceLevel
     67 **
     68 ** Description      This function sets the trace level for SMP.  If called with
     69 **                  a value of 0xFF, it simply returns the current trace level.
     70 **
     71 **                  Input Parameters:
     72 **                      level:  The level to set the GATT tracing to:
     73 **                      0xff-returns the current setting.
     74 **                      0-turns off tracing.
     75 **                      >= 1-Errors.
     76 **                      >= 2-Warnings.
     77 **                      >= 3-APIs.
     78 **                      >= 4-Events.
     79 **                      >= 5-Debug.
     80 **
     81 ** Returns          The new or current trace level
     82 **
     83 *******************************************************************************/
     84 SMP_API extern UINT8 SMP_SetTraceLevel (UINT8 new_level)
     85 {
     86     if (new_level != 0xFF)
     87         smp_cb.trace_level = new_level;
     88 
     89     return(smp_cb.trace_level);
     90 }
     91 
     92 
     93 /*******************************************************************************
     94 **
     95 ** Function         SMP_Register
     96 **
     97 ** Description      This function register for the SMP services callback.
     98 **
     99 ** Returns          void
    100 **
    101 *******************************************************************************/
    102 BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback)
    103 {
    104     SMP_TRACE_EVENT1 ("SMP_Register state=%d", smp_cb.state);
    105 
    106     if (smp_cb.p_callback != NULL)
    107     {
    108         SMP_TRACE_ERROR0 ("SMP_Register: duplicate registration, overwrite it");
    109     }
    110     smp_cb.p_callback = p_cback;
    111 
    112     return(TRUE);
    113 
    114 }
    115 
    116 /*******************************************************************************
    117 **
    118 ** Function         SMP_Pair
    119 **
    120 ** Description      This function call to perform a SMP pairing with peer device.
    121 **                  Device support one SMP pairing at one time.
    122 **
    123 ** Parameters       bd_addr - peer device bd address.
    124 **
    125 ** Returns          None
    126 **
    127 *******************************************************************************/
    128 tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
    129 {
    130     tSMP_CB   *p_cb = &smp_cb;
    131     UINT8     status = SMP_PAIR_INTERNAL_ERR;
    132 
    133     BTM_TRACE_EVENT2 ("SMP_Pair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
    134     if (p_cb->state != SMP_ST_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
    135     {
    136         /* pending security on going, reject this one */
    137         return SMP_BUSY;
    138     }
    139     else
    140     {
    141         p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
    142 
    143         memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
    144 
    145         if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr))
    146         {
    147             SMP_TRACE_ERROR0("SMP_Pair: L2C connect fixed channel failed.");
    148             smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
    149             return status;
    150         }
    151 
    152         return SMP_STARTED;
    153     }
    154 }
    155 
    156 
    157 /*******************************************************************************
    158 **
    159 ** Function         SMP_PairCancel
    160 **
    161 ** Description      This function call to cancel a SMP pairing with peer device.
    162 **
    163 ** Parameters       bd_addr - peer device bd address.
    164 **
    165 ** Returns          TRUE - Pairining is cancelled
    166 **
    167 *******************************************************************************/
    168 BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
    169 {
    170     tSMP_CB   *p_cb = &smp_cb;
    171     UINT8     err_code = SMP_PAIR_FAIL_UNKNOWN;
    172     BOOLEAN   status = FALSE;
    173 
    174     BTM_TRACE_EVENT2 ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
    175     if ( (p_cb->state != SMP_ST_IDLE)  &&
    176          (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) )
    177     {
    178         p_cb->is_pair_cancel = TRUE;
    179         SMP_TRACE_DEBUG0("Cancel Pairing: set fail reason Unknown");
    180         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code);
    181         status = TRUE;
    182     }
    183 
    184     return status;
    185 }
    186 /*******************************************************************************
    187 **
    188 ** Function         SMP_SecurityGrant
    189 **
    190 ** Description      This function is called to grant security process.
    191 **
    192 ** Parameters       bd_addr - peer device bd address.
    193 **                  res     - result of the operation SMP_SUCCESS if success.
    194 **                            Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
    195 **
    196 ** Returns          None
    197 **
    198 *******************************************************************************/
    199 void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
    200 {
    201     SMP_TRACE_EVENT0 ("SMP_SecurityGrant ");
    202     if (smp_cb.state != SMP_ST_WAIT_APP_RSP ||
    203         smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
    204         memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
    205         return;
    206 
    207     smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
    208 }
    209 
    210 /*******************************************************************************
    211 **
    212 ** Function         SMP_PasskeyReply
    213 **
    214 ** Description      This function is called after Security Manager submitted
    215 **                  passkey request to the application.
    216 **
    217 ** Parameters:      bd_addr      - Address of the device for which passkey was requested
    218 **                  res          - result of the operation SMP_SUCCESS if success
    219 **                  passkey - numeric value in the range of
    220 **                  BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
    221 **
    222 *******************************************************************************/
    223 void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
    224 {
    225     tSMP_CB *p_cb = & smp_cb;
    226     UINT8   failure = SMP_PASSKEY_ENTRY_FAIL;
    227     tBTM_SEC_DEV_REC *p_dev_rec;
    228 
    229     SMP_TRACE_EVENT2 ("SMP_PasskeyReply: Key: %d  Result:%d",
    230                       passkey, res);
    231 
    232     /* If timeout already expired or has been canceled, ignore the reply */
    233     if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT)
    234     {
    235         SMP_TRACE_WARNING1 ("SMP_PasskeyReply() - Wrong State: %d", p_cb->state);
    236         return;
    237     }
    238 
    239     if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
    240     {
    241         SMP_TRACE_ERROR0 ("SMP_PasskeyReply() - Wrong BD Addr");
    242         return;
    243     }
    244 
    245     if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
    246     {
    247         SMP_TRACE_ERROR0 ("SMP_PasskeyReply() - no dev CB");
    248         return;
    249     }
    250 
    251 
    252     if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS)
    253     {
    254         SMP_TRACE_WARNING1 ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey);
    255         /* send pairing failure */
    256         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    257 
    258     }
    259     else
    260     {
    261         smp_convert_string_to_tk(p_cb->tk, passkey);
    262     }
    263 
    264     return;
    265 }
    266 
    267 /*******************************************************************************
    268 **
    269 ** Function         SMP_OobDataReply
    270 **
    271 ** Description      This function is called to provide the OOB data for
    272 **                  SMP in response to SMP_OOB_REQ_EVT
    273 **
    274 ** Parameters:      bd_addr     - Address of the peer device
    275 **                  res         - result of the operation SMP_SUCCESS if success
    276 **                  p_data      - simple pairing Randomizer  C.
    277 **
    278 *******************************************************************************/
    279 void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data)
    280 {
    281     tSMP_CB *p_cb = & smp_cb;
    282     UINT8   failure = SMP_OOB_FAIL;
    283     tSMP_KEY        key;
    284 
    285     SMP_TRACE_EVENT2 ("SMP_OobDataReply State: %d  res:%d",
    286                       smp_cb.state, res);
    287 
    288     /* If timeout already expired or has been canceled, ignore the reply */
    289     if (p_cb->state != SMP_ST_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT)
    290         return;
    291 
    292     if (res != SMP_SUCCESS || len == 0 || !p_data)
    293     {
    294         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    295     }
    296     else
    297     {
    298         if (len > BT_OCTET16_LEN)
    299             len = BT_OCTET16_LEN;
    300 
    301         memcpy(p_cb->tk, p_data, len);
    302 
    303         key.key_type    = SMP_KEY_TYPE_TK;
    304         key.p_data      = p_cb->tk;
    305 
    306         smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
    307     }
    308 }
    309 
    310 /*******************************************************************************
    311 **
    312 ** Function         SMP_Encrypt
    313 **
    314 ** Description      This function is called to encrypt the data with the specified
    315 **                  key
    316 **
    317 ** Parameters:      key                 - Pointer to key key[0] conatins the MSB
    318 **                  key_len             - key length
    319 **                  plain_text          - Pointer to data to be encrypted
    320 **                                        plain_text[0] conatins the MSB
    321 **                  pt_len              - plain text length
    322 **                  p_out                - output of the encrypted texts
    323 **
    324 **  Returns         Boolean - request is successful
    325 *******************************************************************************/
    326 BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len,
    327                      UINT8 *plain_text, UINT8 pt_len,
    328                      tSMP_ENC *p_out)
    329 
    330 {
    331     BOOLEAN status=FALSE;
    332     status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out);
    333     return status;
    334 }
    335 #endif /* SMP_INCLUDED */
    336 
    337 
    338