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