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 #include "stack_config.h"
     30 
     31 #if SMP_INCLUDED == TRUE
     32     #include "smp_int.h"
     33     #include "smp_api.h"
     34     #include "l2cdefs.h"
     35     #include "l2c_int.h"
     36     #include "btm_int.h"
     37     #include "hcimsgs.h"
     38 
     39     #include "btu.h"
     40     #include "p_256_ecc_pp.h"
     41 
     42 /*******************************************************************************
     43 **
     44 ** Function         SMP_Init
     45 **
     46 ** Description      This function initializes the SMP unit.
     47 **
     48 ** Returns          void
     49 **
     50 *******************************************************************************/
     51 void SMP_Init(void)
     52 {
     53     memset(&smp_cb, 0, sizeof(tSMP_CB));
     54     smp_cb.smp_rsp_timer_ent = alarm_new("smp.smp_rsp_timer_ent");
     55 
     56 #if defined(SMP_INITIAL_TRACE_LEVEL)
     57     smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
     58 #else
     59     smp_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
     60 #endif
     61     SMP_TRACE_EVENT ("%s", __FUNCTION__);
     62 
     63     smp_l2cap_if_init();
     64     /* initialization of P-256 parameters */
     65     p_256_init_curve(KEY_LENGTH_DWORDS_P256);
     66 
     67     /* Initialize failure case for certification */
     68     smp_cb.cert_failure = stack_config_get_interface()->get_pts_smp_failure_case();
     69     if (smp_cb.cert_failure)
     70         SMP_TRACE_ERROR ("%s PTS FAILURE MODE IN EFFECT (CASE %d)", __func__, smp_cb.cert_failure);
     71 }
     72 
     73 
     74 /*******************************************************************************
     75 **
     76 ** Function         SMP_SetTraceLevel
     77 **
     78 ** Description      This function sets the trace level for SMP.  If called with
     79 **                  a value of 0xFF, it simply returns the current trace level.
     80 **
     81 **                  Input Parameters:
     82 **                      level:  The level to set the GATT tracing to:
     83 **                      0xff-returns the current setting.
     84 **                      0-turns off tracing.
     85 **                      >= 1-Errors.
     86 **                      >= 2-Warnings.
     87 **                      >= 3-APIs.
     88 **                      >= 4-Events.
     89 **                      >= 5-Debug.
     90 **
     91 ** Returns          The new or current trace level
     92 **
     93 *******************************************************************************/
     94 extern UINT8 SMP_SetTraceLevel (UINT8 new_level)
     95 {
     96     if (new_level != 0xFF)
     97         smp_cb.trace_level = new_level;
     98 
     99     return(smp_cb.trace_level);
    100 }
    101 
    102 
    103 /*******************************************************************************
    104 **
    105 ** Function         SMP_Register
    106 **
    107 ** Description      This function register for the SMP services callback.
    108 **
    109 ** Returns          void
    110 **
    111 *******************************************************************************/
    112 BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback)
    113 {
    114     SMP_TRACE_EVENT ("SMP_Register state=%d", smp_cb.state);
    115 
    116     if (smp_cb.p_callback != NULL)
    117     {
    118         SMP_TRACE_ERROR ("SMP_Register: duplicate registration, overwrite it");
    119     }
    120     smp_cb.p_callback = p_cback;
    121 
    122     return(TRUE);
    123 
    124 }
    125 
    126 /*******************************************************************************
    127 **
    128 ** Function         SMP_Pair
    129 **
    130 ** Description      This function call to perform a SMP pairing with peer device.
    131 **                  Device support one SMP pairing at one time.
    132 **
    133 ** Parameters       bd_addr - peer device bd address.
    134 **
    135 ** Returns          None
    136 **
    137 *******************************************************************************/
    138 tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
    139 {
    140     tSMP_CB   *p_cb = &smp_cb;
    141     UINT8     status = SMP_PAIR_INTERNAL_ERR;
    142 
    143     SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
    144                       __FUNCTION__, p_cb->state, p_cb->br_state, p_cb->flags);
    145     if (p_cb->state != SMP_STATE_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD ||
    146         p_cb->smp_over_br)
    147     {
    148         /* pending security on going, reject this one */
    149         return SMP_BUSY;
    150     }
    151     else
    152     {
    153         p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
    154 
    155         memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
    156 
    157         if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr))
    158         {
    159             SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__);
    160             smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
    161             return status;
    162         }
    163 
    164         return SMP_STARTED;
    165     }
    166 }
    167 
    168 /*******************************************************************************
    169 **
    170 ** Function         SMP_BR_PairWith
    171 **
    172 ** Description      This function is called to start a SMP pairing over BR/EDR.
    173 **                  Device support one SMP pairing at one time.
    174 **
    175 ** Parameters       bd_addr - peer device bd address.
    176 **
    177 ** Returns          SMP_STARTED if pairing started, otherwise reason for failure.
    178 **
    179 *******************************************************************************/
    180 tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr)
    181 {
    182     tSMP_CB   *p_cb = &smp_cb;
    183     UINT8     status = SMP_PAIR_INTERNAL_ERR;
    184 
    185     SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
    186                       __func__, p_cb->state, p_cb->br_state, p_cb->flags);
    187 
    188     if (p_cb->state != SMP_STATE_IDLE ||
    189         p_cb->smp_over_br ||
    190         p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
    191     {
    192         /* pending security on going, reject this one */
    193         return SMP_BUSY;
    194     }
    195 
    196     p_cb->role = HCI_ROLE_MASTER;
    197     p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
    198     p_cb->smp_over_br = TRUE;
    199 
    200     memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
    201 
    202     if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr))
    203     {
    204         SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.",__FUNCTION__);
    205         smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
    206         return status;
    207     }
    208 
    209     return SMP_STARTED;
    210 }
    211 
    212 /*******************************************************************************
    213 **
    214 ** Function         SMP_PairCancel
    215 **
    216 ** Description      This function call to cancel a SMP pairing with peer device.
    217 **
    218 ** Parameters       bd_addr - peer device bd address.
    219 **
    220 ** Returns          TRUE - Pairining is cancelled
    221 **
    222 *******************************************************************************/
    223 BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
    224 {
    225     tSMP_CB   *p_cb = &smp_cb;
    226     UINT8     err_code = SMP_PAIR_FAIL_UNKNOWN;
    227     BOOLEAN   status = FALSE;
    228 
    229     // PTS SMP failure test cases
    230     if (p_cb->cert_failure == 7)
    231         err_code = SMP_PASSKEY_ENTRY_FAIL;
    232     else if (p_cb->cert_failure == 8)
    233         err_code = SMP_NUMERIC_COMPAR_FAIL;
    234 
    235     BTM_TRACE_EVENT ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
    236     if ( (p_cb->state != SMP_STATE_IDLE)  &&
    237          (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) )
    238     {
    239         p_cb->is_pair_cancel = TRUE;
    240         SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown");
    241         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code);
    242         status = TRUE;
    243     }
    244 
    245     return status;
    246 }
    247 /*******************************************************************************
    248 **
    249 ** Function         SMP_SecurityGrant
    250 **
    251 ** Description      This function is called to grant security process.
    252 **
    253 ** Parameters       bd_addr - peer device bd address.
    254 **                  res     - result of the operation SMP_SUCCESS if success.
    255 **                            Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
    256 **
    257 ** Returns          None
    258 **
    259 *******************************************************************************/
    260 void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
    261 {
    262     SMP_TRACE_EVENT ("SMP_SecurityGrant ");
    263 
    264     if (smp_cb.smp_over_br)
    265     {
    266         if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
    267             smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
    268             memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
    269         {
    270             return;
    271         }
    272 
    273         /* clear the SMP_SEC_REQUEST_EVT event after get grant */
    274         /* avoid generating duplicate pair request */
    275         smp_cb.cb_evt = 0;
    276         smp_br_state_machine_event(&smp_cb, SMP_BR_API_SEC_GRANT_EVT, &res);
    277         return;
    278     }
    279 
    280     if (smp_cb.state != SMP_STATE_WAIT_APP_RSP ||
    281         smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
    282         memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
    283         return;
    284     /* clear the SMP_SEC_REQUEST_EVT event after get grant */
    285     /* avoid generate duplicate pair request */
    286     smp_cb.cb_evt = 0;
    287     smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
    288 }
    289 
    290 /*******************************************************************************
    291 **
    292 ** Function         SMP_PasskeyReply
    293 **
    294 ** Description      This function is called after Security Manager submitted
    295 **                  passkey request to the application.
    296 **
    297 ** Parameters:      bd_addr      - Address of the device for which passkey was requested
    298 **                  res          - result of the operation SMP_SUCCESS if success
    299 **                  passkey - numeric value in the range of
    300 **                  BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
    301 **
    302 *******************************************************************************/
    303 void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
    304 {
    305     tSMP_CB *p_cb = & smp_cb;
    306     UINT8   failure = SMP_PASSKEY_ENTRY_FAIL;
    307 
    308     SMP_TRACE_EVENT ("SMP_PasskeyReply: Key: %d  Result:%d",
    309                       passkey, res);
    310 
    311     /* If timeout already expired or has been canceled, ignore the reply */
    312     if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT)
    313     {
    314         SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong State: %d", p_cb->state);
    315         return;
    316     }
    317 
    318     if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
    319     {
    320         SMP_TRACE_ERROR ("SMP_PasskeyReply() - Wrong BD Addr");
    321         return;
    322     }
    323 
    324     if (btm_find_dev (bd_addr) == NULL)
    325     {
    326         SMP_TRACE_ERROR ("SMP_PasskeyReply() - no dev CB");
    327         return;
    328     }
    329 
    330     if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS)
    331     {
    332         SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey);
    333         /* send pairing failure */
    334         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    335 
    336     }
    337     else if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_ENT)
    338     {
    339         smp_sm_event(&smp_cb, SMP_SC_KEY_READY_EVT, &passkey);
    340     }
    341     else
    342     {
    343         smp_convert_string_to_tk(p_cb->tk, passkey);
    344     }
    345 
    346     return;
    347 }
    348 
    349 /*******************************************************************************
    350 **
    351 ** Function         SMP_ConfirmReply
    352 **
    353 ** Description      This function is called after Security Manager submitted
    354 **                  numeric comparison request to the application.
    355 **
    356 ** Parameters:      bd_addr      - Address of the device with which numeric
    357 **                                 comparison was requested
    358 **                  res          - comparison result SMP_SUCCESS if success
    359 **
    360 *******************************************************************************/
    361 void SMP_ConfirmReply (BD_ADDR bd_addr, UINT8 res)
    362 {
    363     tSMP_CB *p_cb = & smp_cb;
    364     UINT8   failure = SMP_NUMERIC_COMPAR_FAIL;
    365 
    366     SMP_TRACE_EVENT ("%s: Result:%d", __FUNCTION__, res);
    367 
    368     /* If timeout already expired or has been canceled, ignore the reply */
    369     if (p_cb->cb_evt != SMP_NC_REQ_EVT)
    370     {
    371         SMP_TRACE_WARNING ("%s() - Wrong State: %d", __FUNCTION__,p_cb->state);
    372         return;
    373     }
    374 
    375     if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
    376     {
    377         SMP_TRACE_ERROR ("%s() - Wrong BD Addr",__FUNCTION__);
    378         return;
    379     }
    380 
    381     if (btm_find_dev (bd_addr) == NULL)
    382     {
    383         SMP_TRACE_ERROR ("%s() - no dev CB",__FUNCTION__);
    384         return;
    385     }
    386 
    387     if (res != SMP_SUCCESS)
    388     {
    389         SMP_TRACE_WARNING ("%s() - Numeric Comparison fails",__FUNCTION__);
    390         /* send pairing failure */
    391         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    392     }
    393     else
    394     {
    395         smp_sm_event(p_cb, SMP_SC_NC_OK_EVT, NULL);
    396     }
    397 }
    398 
    399 /*******************************************************************************
    400 **
    401 ** Function         SMP_OobDataReply
    402 **
    403 ** Description      This function is called to provide the OOB data for
    404 **                  SMP in response to SMP_OOB_REQ_EVT
    405 **
    406 ** Parameters:      bd_addr     - Address of the peer device
    407 **                  res         - result of the operation SMP_SUCCESS if success
    408 **                  p_data      - simple pairing Randomizer  C.
    409 **
    410 *******************************************************************************/
    411 void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data)
    412 {
    413     tSMP_CB *p_cb = & smp_cb;
    414     UINT8   failure = SMP_OOB_FAIL;
    415     tSMP_KEY        key;
    416 
    417     SMP_TRACE_EVENT ("%s State: %d  res:%d", __FUNCTION__, smp_cb.state, res);
    418 
    419     /* If timeout already expired or has been canceled, ignore the reply */
    420     if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT)
    421         return;
    422 
    423     if (res != SMP_SUCCESS || len == 0 || !p_data)
    424     {
    425         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    426     }
    427     else
    428     {
    429         if (len > BT_OCTET16_LEN)
    430             len = BT_OCTET16_LEN;
    431 
    432         memcpy(p_cb->tk, p_data, len);
    433 
    434         key.key_type    = SMP_KEY_TYPE_TK;
    435         key.p_data      = p_cb->tk;
    436 
    437         smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
    438     }
    439 }
    440 
    441 /*******************************************************************************
    442 **
    443 ** Function         SMP_SecureConnectionOobDataReply
    444 **
    445 ** Description      This function is called to provide the SC OOB data for
    446 **                  SMP in response to SMP_SC_OOB_REQ_EVT
    447 **
    448 ** Parameters:      p_data      - pointer to the data
    449 **
    450 *******************************************************************************/
    451 void SMP_SecureConnectionOobDataReply(UINT8 *p_data)
    452 {
    453     tSMP_CB  *p_cb = &smp_cb;
    454 
    455     UINT8  failure = SMP_OOB_FAIL;
    456     tSMP_SC_OOB_DATA  *p_oob = (tSMP_SC_OOB_DATA *) p_data;
    457     if (!p_oob)
    458     {
    459         SMP_TRACE_ERROR("%s received no data",__FUNCTION__);
    460         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    461         return;
    462     }
    463 
    464     SMP_TRACE_EVENT ("%s req_oob_type: %d, loc_oob_data.present: %d, "
    465                        "peer_oob_data.present: %d",
    466                        __FUNCTION__, p_cb->req_oob_type, p_oob->loc_oob_data.present,
    467                        p_oob->peer_oob_data.present);
    468 
    469     if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_SC_OOB_REQ_EVT)
    470         return;
    471 
    472     BOOLEAN  data_missing = FALSE;
    473     switch (p_cb->req_oob_type)
    474     {
    475         case SMP_OOB_PEER:
    476             if (!p_oob->peer_oob_data.present)
    477                 data_missing = TRUE;
    478             break;
    479         case SMP_OOB_LOCAL:
    480             if (!p_oob->loc_oob_data.present)
    481                 data_missing = TRUE;
    482             break;
    483         case SMP_OOB_BOTH:
    484             if (!p_oob->loc_oob_data.present || !p_oob->peer_oob_data.present)
    485                 data_missing = TRUE;
    486             break;
    487         default:
    488             SMP_TRACE_EVENT ("Unexpected OOB data type requested. Fail OOB");
    489             data_missing = TRUE;
    490             break;
    491     }
    492 
    493     if (data_missing)
    494     {
    495         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    496         return;
    497     }
    498 
    499     p_cb->sc_oob_data = *p_oob;
    500 
    501     smp_sm_event(&smp_cb, SMP_SC_OOB_DATA_EVT, p_data);
    502 }
    503 
    504 /*******************************************************************************
    505 **
    506 ** Function         SMP_Encrypt
    507 **
    508 ** Description      This function is called to encrypt the data with the specified
    509 **                  key
    510 **
    511 ** Parameters:      key                 - Pointer to key key[0] conatins the MSB
    512 **                  key_len             - key length
    513 **                  plain_text          - Pointer to data to be encrypted
    514 **                                        plain_text[0] conatins the MSB
    515 **                  pt_len              - plain text length
    516 **                  p_out                - output of the encrypted texts
    517 **
    518 **  Returns         Boolean - request is successful
    519 *******************************************************************************/
    520 BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len,
    521                      UINT8 *plain_text, UINT8 pt_len,
    522                      tSMP_ENC *p_out)
    523 
    524 {
    525     BOOLEAN status=FALSE;
    526     status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out);
    527     return status;
    528 }
    529 
    530 /*******************************************************************************
    531 **
    532 ** Function         SMP_KeypressNotification
    533 **
    534 ** Description      This function is called to notify Security Manager about Keypress Notification.
    535 **
    536 ** Parameters:     bd_addr      Address of the device to send keypress notification to
    537 **                 value        Keypress notification parameter value
    538 **
    539 *******************************************************************************/
    540 void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value)
    541 {
    542     tSMP_CB   *p_cb = &smp_cb;
    543 
    544     SMP_TRACE_EVENT ("%s: Value: %d", __FUNCTION__,value);
    545 
    546     if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
    547     {
    548         SMP_TRACE_ERROR ("%s() - Wrong BD Addr",__FUNCTION__);
    549         return;
    550     }
    551 
    552     if (btm_find_dev (bd_addr) == NULL)
    553     {
    554         SMP_TRACE_ERROR ("%s() - no dev CB",__FUNCTION__);
    555         return;
    556     }
    557 
    558     /* Keypress Notification is used by a device with KeyboardOnly IO capabilities */
    559     /* during the passkey entry protocol */
    560     if (p_cb->local_io_capability != SMP_IO_CAP_IN)
    561     {
    562         SMP_TRACE_ERROR ("%s() - wrong local IO capabilities %d",
    563                           __FUNCTION__, p_cb->local_io_capability);
    564         return;
    565     }
    566 
    567     if (p_cb->selected_association_model != SMP_MODEL_SEC_CONN_PASSKEY_ENT)
    568     {
    569         SMP_TRACE_ERROR ("%s() - wrong protocol %d", __FUNCTION__,
    570                          p_cb->selected_association_model);
    571         return;
    572     }
    573 
    574     smp_sm_event(p_cb, SMP_KEYPRESS_NOTIFICATION_EVENT, &value);
    575 }
    576 
    577 /*******************************************************************************
    578 **
    579 ** Function         SMP_CreateLocalSecureConnectionsOobData
    580 **
    581 ** Description      This function is called to start creation of local SC OOB
    582 **                  data set (tSMP_LOC_OOB_DATA).
    583 **
    584 ** Parameters:      bd_addr      - Address of the device to send OOB data block to
    585 **
    586 **  Returns         Boolean - TRUE: creation of local SC OOB data set started.
    587 *******************************************************************************/
    588 BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to)
    589 {
    590     tSMP_CB *p_cb = &smp_cb;
    591     UINT8   *bd_addr;
    592 
    593     if (addr_to_send_to == NULL)
    594     {
    595         SMP_TRACE_ERROR ("%s addr_to_send_to is not provided",__FUNCTION__);
    596         return FALSE;
    597     }
    598 
    599     bd_addr = addr_to_send_to->bda;
    600 
    601     SMP_TRACE_EVENT ("%s addr type: %u,  BDA: %08x%04x,  state: %u, br_state: %u",
    602                       __FUNCTION__, addr_to_send_to->type,
    603                       (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8) + bd_addr[3],
    604                       (bd_addr[4]<<8)+bd_addr[5],
    605                       p_cb->state,
    606                       p_cb->br_state);
    607 
    608     if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br))
    609     {
    610         SMP_TRACE_WARNING ("%s creation of local OOB data set "\
    611             "starts only in IDLE state",__FUNCTION__);
    612         return FALSE;
    613     }
    614 
    615     p_cb->sc_oob_data.loc_oob_data.addr_sent_to = *addr_to_send_to;
    616     smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL);
    617 
    618     return TRUE;
    619 }
    620 
    621 #endif /* SMP_INCLUDED */
    622