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