Home | History | Annotate | Download | only in smp
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 1999-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 functions for the SMP L2CAP utility functions
     22  *
     23  ******************************************************************************/
     24 #include "bt_target.h"
     25 
     26 #if SMP_INCLUDED == TRUE
     27 
     28 #include "bt_types.h"
     29 #include "bt_utils.h"
     30 #include <string.h>
     31 #include <ctype.h>
     32 #include "hcidefs.h"
     33 #include "btm_ble_api.h"
     34 #include "l2c_api.h"
     35 #include "l2c_int.h"
     36 #include "smp_int.h"
     37 #include "device/include/controller.h"
     38 #include "btm_int.h"
     39 
     40 
     41 extern fixed_queue_t *btu_general_alarm_queue;
     42 
     43 #define SMP_PAIRING_REQ_SIZE    7
     44 #define SMP_CONFIRM_CMD_SIZE    (BT_OCTET16_LEN + 1)
     45 #define SMP_RAND_CMD_SIZE       (BT_OCTET16_LEN + 1)
     46 #define SMP_INIT_CMD_SIZE       (BT_OCTET16_LEN + 1)
     47 #define SMP_ENC_INFO_SIZE       (BT_OCTET16_LEN + 1)
     48 #define SMP_MASTER_ID_SIZE      (BT_OCTET8_LEN + 2 + 1)
     49 #define SMP_ID_INFO_SIZE        (BT_OCTET16_LEN + 1)
     50 #define SMP_ID_ADDR_SIZE        (BD_ADDR_LEN + 1 + 1)
     51 #define SMP_SIGN_INFO_SIZE      (BT_OCTET16_LEN + 1)
     52 #define SMP_PAIR_FAIL_SIZE      2
     53 #define SMP_SECURITY_REQUEST_SIZE  2
     54 #define SMP_PAIR_PUBL_KEY_SIZE  (1 /* opcode */ + (2*BT_OCTET32_LEN))
     55 #define SMP_PAIR_COMMITM_SIZE           (1 /* opcode */ + BT_OCTET16_LEN /*Commitment*/)
     56 #define SMP_PAIR_DHKEY_CHECK_SIZE       (1 /* opcode */ + BT_OCTET16_LEN /*DHKey Check*/)
     57 #define SMP_PAIR_KEYPR_NOTIF_SIZE       (1 /* opcode */ + 1 /*Notif Type*/)
     58 
     59 /* SMP command sizes per spec */
     60 static const UINT8 smp_cmd_size_per_spec[] =
     61 {
     62     0,
     63     SMP_PAIRING_REQ_SIZE,       /* 0x01: pairing request */
     64     SMP_PAIRING_REQ_SIZE,       /* 0x02: pairing response */
     65     SMP_CONFIRM_CMD_SIZE,       /* 0x03: pairing confirm */
     66     SMP_RAND_CMD_SIZE,          /* 0x04: pairing random */
     67     SMP_PAIR_FAIL_SIZE,         /* 0x05: pairing failed */
     68     SMP_ENC_INFO_SIZE,          /* 0x06: encryption information */
     69     SMP_MASTER_ID_SIZE,         /* 0x07: master identification */
     70     SMP_ID_INFO_SIZE,           /* 0x08: identity information */
     71     SMP_ID_ADDR_SIZE,           /* 0x09: identity address information */
     72     SMP_SIGN_INFO_SIZE,         /* 0x0A: signing information */
     73     SMP_SECURITY_REQUEST_SIZE,  /* 0x0B: security request */
     74     SMP_PAIR_PUBL_KEY_SIZE,     /* 0x0C: pairing public key */
     75     SMP_PAIR_DHKEY_CHECK_SIZE,  /* 0x0D: pairing dhkey check */
     76     SMP_PAIR_KEYPR_NOTIF_SIZE,  /* 0x0E: pairing keypress notification */
     77     SMP_PAIR_COMMITM_SIZE       /* 0x0F: pairing commitment */
     78 };
     79 
     80 static BOOLEAN smp_parameter_unconditionally_valid(tSMP_CB *p_cb);
     81 static BOOLEAN smp_parameter_unconditionally_invalid(tSMP_CB *p_cb);
     82 
     83 /* type for SMP command length validation functions */
     84 typedef BOOLEAN (*tSMP_CMD_LEN_VALID)(tSMP_CB *p_cb);
     85 
     86 static BOOLEAN smp_command_has_valid_fixed_length(tSMP_CB *p_cb);
     87 
     88 static const tSMP_CMD_LEN_VALID smp_cmd_len_is_valid[] =
     89 {
     90     smp_parameter_unconditionally_invalid,
     91     smp_command_has_valid_fixed_length, /* 0x01: pairing request */
     92     smp_command_has_valid_fixed_length, /* 0x02: pairing response */
     93     smp_command_has_valid_fixed_length, /* 0x03: pairing confirm */
     94     smp_command_has_valid_fixed_length, /* 0x04: pairing random */
     95     smp_command_has_valid_fixed_length, /* 0x05: pairing failed */
     96     smp_command_has_valid_fixed_length, /* 0x06: encryption information */
     97     smp_command_has_valid_fixed_length, /* 0x07: master identification */
     98     smp_command_has_valid_fixed_length, /* 0x08: identity information */
     99     smp_command_has_valid_fixed_length, /* 0x09: identity address information */
    100     smp_command_has_valid_fixed_length, /* 0x0A: signing information */
    101     smp_command_has_valid_fixed_length, /* 0x0B: security request */
    102     smp_command_has_valid_fixed_length, /* 0x0C: pairing public key */
    103     smp_command_has_valid_fixed_length, /* 0x0D: pairing dhkey check */
    104     smp_command_has_valid_fixed_length, /* 0x0E: pairing keypress notification */
    105     smp_command_has_valid_fixed_length  /* 0x0F: pairing commitment */
    106 };
    107 
    108 /* type for SMP command parameter ranges validation functions */
    109 typedef BOOLEAN (*tSMP_CMD_PARAM_RANGES_VALID)(tSMP_CB *p_cb);
    110 
    111 static BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb);
    112 static BOOLEAN smp_pairing_keypress_notification_is_valid(tSMP_CB *p_cb);
    113 
    114 static const tSMP_CMD_PARAM_RANGES_VALID smp_cmd_param_ranges_are_valid[] =
    115 {
    116     smp_parameter_unconditionally_invalid,
    117     smp_pairing_request_response_parameters_are_valid, /* 0x01: pairing request */
    118     smp_pairing_request_response_parameters_are_valid, /* 0x02: pairing response */
    119     smp_parameter_unconditionally_valid, /* 0x03: pairing confirm */
    120     smp_parameter_unconditionally_valid, /* 0x04: pairing random */
    121     smp_parameter_unconditionally_valid, /* 0x05: pairing failed */
    122     smp_parameter_unconditionally_valid, /* 0x06: encryption information */
    123     smp_parameter_unconditionally_valid, /* 0x07: master identification */
    124     smp_parameter_unconditionally_valid, /* 0x08: identity information */
    125     smp_parameter_unconditionally_valid, /* 0x09: identity address information */
    126     smp_parameter_unconditionally_valid, /* 0x0A: signing information */
    127     smp_parameter_unconditionally_valid, /* 0x0B: security request */
    128     smp_parameter_unconditionally_valid, /* 0x0C: pairing public key */
    129     smp_parameter_unconditionally_valid, /* 0x0D: pairing dhkey check */
    130     smp_pairing_keypress_notification_is_valid, /* 0x0E: pairing keypress notification */
    131     smp_parameter_unconditionally_valid /* 0x0F: pairing commitment */
    132 };
    133 
    134 /* type for action functions */
    135 typedef BT_HDR * (*tSMP_CMD_ACT)(UINT8 cmd_code, tSMP_CB *p_cb);
    136 
    137 static BT_HDR *smp_build_pairing_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    138 static BT_HDR *smp_build_confirm_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    139 static BT_HDR *smp_build_rand_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    140 static BT_HDR *smp_build_pairing_fail(UINT8 cmd_code, tSMP_CB *p_cb);
    141 static BT_HDR *smp_build_identity_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    142 static BT_HDR *smp_build_encrypt_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    143 static BT_HDR *smp_build_security_request(UINT8 cmd_code, tSMP_CB *p_cb);
    144 static BT_HDR *smp_build_signing_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    145 static BT_HDR *smp_build_master_id_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    146 static BT_HDR *smp_build_id_addr_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    147 static BT_HDR *smp_build_pair_public_key_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    148 static BT_HDR *smp_build_pairing_commitment_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    149 static BT_HDR *smp_build_pair_dhkey_check_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    150 static BT_HDR *smp_build_pairing_keypress_notification_cmd(UINT8 cmd_code, tSMP_CB *p_cb);
    151 
    152 static const tSMP_CMD_ACT smp_cmd_build_act[] =
    153 {
    154     NULL,
    155     smp_build_pairing_cmd,          /* 0x01: pairing request */
    156     smp_build_pairing_cmd,          /* 0x02: pairing response */
    157     smp_build_confirm_cmd,          /* 0x03: pairing confirm */
    158     smp_build_rand_cmd,             /* 0x04: pairing random */
    159     smp_build_pairing_fail,         /* 0x05: pairing failure */
    160     smp_build_encrypt_info_cmd,     /* 0x06: encryption information */
    161     smp_build_master_id_cmd,        /* 0x07: master identification */
    162     smp_build_identity_info_cmd,    /* 0x08: identity information */
    163     smp_build_id_addr_cmd,          /* 0x09: identity address information */
    164     smp_build_signing_info_cmd,     /* 0x0A: signing information */
    165     smp_build_security_request,     /* 0x0B: security request */
    166     smp_build_pair_public_key_cmd,  /* 0x0C: pairing public key */
    167     smp_build_pair_dhkey_check_cmd, /* 0x0D: pairing DHKey check */
    168     smp_build_pairing_keypress_notification_cmd, /* 0x0E: pairing keypress notification */
    169     smp_build_pairing_commitment_cmd /* 0x0F: pairing commitment */
    170 };
    171 
    172 static const UINT8 smp_association_table[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] =
    173 {
    174     /* display only */    /* Display Yes/No */   /* keyboard only */
    175                        /* No Input/Output */ /* keyboard display */
    176 
    177      /* initiator */
    178      /* model = tbl[peer_io_caps][loc_io_caps] */
    179      /* Display Only */
    180     {{SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY,
    181                                  SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY},
    182 
    183      /* Display Yes/No */
    184      {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY,
    185                                  SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY},
    186 
    187      /* Keyboard only */
    188      {SMP_MODEL_KEY_NOTIF, SMP_MODEL_KEY_NOTIF, SMP_MODEL_PASSKEY,
    189                            SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF},
    190 
    191      /* No Input No Output */
    192      {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY,
    193                                  SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY},
    194 
    195      /* keyboard display */
    196      {SMP_MODEL_KEY_NOTIF, SMP_MODEL_KEY_NOTIF, SMP_MODEL_PASSKEY,
    197                            SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF}},
    198 
    199      /* responder */
    200      /* model = tbl[loc_io_caps][peer_io_caps] */
    201      /* Display Only */
    202     {{SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF,
    203                                  SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF},
    204 
    205       /* Display Yes/No */
    206      {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF,
    207                                  SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF},
    208 
    209       /* keyboard only */
    210      {SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY,
    211                          SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY},
    212 
    213       /* No Input No Output */
    214      {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY,
    215                                  SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY},
    216 
    217       /* keyboard display */
    218      {SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY, SMP_MODEL_KEY_NOTIF,
    219                          SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY}}
    220 };
    221 
    222 static const UINT8 smp_association_table_sc[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] =
    223 {
    224      /* display only */    /* Display Yes/No */   /* keyboard only */
    225                                              /* No InputOutput */  /* keyboard display */
    226 
    227      /* initiator */
    228      /* model = tbl[peer_io_caps][loc_io_caps] */
    229 
    230      /* Display Only */
    231     {{SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
    232                                     SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_ENT},
    233 
    234      /* Display Yes/No */
    235      {SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
    236                                     SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP},
    237 
    238      /* keyboard only */
    239      {SMP_MODEL_SEC_CONN_PASSKEY_DISP, SMP_MODEL_SEC_CONN_PASSKEY_DISP, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
    240                                        SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_DISP},
    241 
    242      /* No Input No Output */
    243      {SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS,
    244                                     SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS},
    245 
    246      /* keyboard display */
    247      {SMP_MODEL_SEC_CONN_PASSKEY_DISP, SMP_MODEL_SEC_CONN_NUM_COMP, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
    248                                        SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP}},
    249 
    250      /* responder */
    251      /* model = tbl[loc_io_caps][peer_io_caps] */
    252 
    253      /* Display Only */
    254     {{SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_DISP,
    255                                     SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_DISP},
    256 
    257      /* Display Yes/No */
    258      {SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP, SMP_MODEL_SEC_CONN_PASSKEY_DISP,
    259                                     SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP},
    260 
    261      /* keyboard only */
    262      {SMP_MODEL_SEC_CONN_PASSKEY_ENT, SMP_MODEL_SEC_CONN_PASSKEY_ENT, SMP_MODEL_SEC_CONN_PASSKEY_ENT,
    263                                       SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_PASSKEY_ENT},
    264 
    265      /* No Input No Output */
    266      {SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS,
    267                                     SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_JUSTWORKS},
    268 
    269      /* keyboard display */
    270      {SMP_MODEL_SEC_CONN_PASSKEY_ENT, SMP_MODEL_SEC_CONN_NUM_COMP, SMP_MODEL_SEC_CONN_PASSKEY_DISP,
    271                        SMP_MODEL_SEC_CONN_JUSTWORKS, SMP_MODEL_SEC_CONN_NUM_COMP}}
    272 };
    273 
    274 static tSMP_ASSO_MODEL smp_select_legacy_association_model(tSMP_CB *p_cb);
    275 static tSMP_ASSO_MODEL smp_select_association_model_secure_connections(tSMP_CB *p_cb);
    276 
    277 /*******************************************************************************
    278 **
    279 ** Function         smp_send_msg_to_L2CAP
    280 **
    281 ** Description      Send message to L2CAP.
    282 **
    283 *******************************************************************************/
    284 BOOLEAN  smp_send_msg_to_L2CAP(BD_ADDR rem_bda, BT_HDR *p_toL2CAP)
    285 {
    286     UINT16 l2cap_ret;
    287     UINT16 fixed_cid = L2CAP_SMP_CID;
    288 
    289     if (smp_cb.smp_over_br)
    290     {
    291         fixed_cid = L2CAP_SMP_BR_CID;
    292     }
    293 
    294     SMP_TRACE_EVENT("%s", __FUNCTION__);
    295     smp_cb.total_tx_unacked += 1;
    296 
    297     if ((l2cap_ret = L2CA_SendFixedChnlData (fixed_cid, rem_bda, p_toL2CAP)) == L2CAP_DW_FAILED)
    298     {
    299         smp_cb.total_tx_unacked -= 1;
    300         SMP_TRACE_ERROR("SMP   failed to pass msg:0x%0x to L2CAP",
    301                          *((UINT8 *)(p_toL2CAP + 1) + p_toL2CAP->offset));
    302         return FALSE;
    303     }
    304     else
    305         return TRUE;
    306 }
    307 
    308 /*******************************************************************************
    309 **
    310 ** Function         smp_send_cmd
    311 **
    312 ** Description      send a SMP command on L2CAP channel.
    313 **
    314 *******************************************************************************/
    315 BOOLEAN smp_send_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    316 {
    317     BT_HDR *p_buf;
    318     BOOLEAN sent = FALSE;
    319     UINT8 failure = SMP_PAIR_INTERNAL_ERR;
    320     SMP_TRACE_EVENT("smp_send_cmd on l2cap cmd_code=0x%x", cmd_code);
    321     if ( cmd_code <= (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */) &&
    322          smp_cmd_build_act[cmd_code] != NULL)
    323     {
    324         p_buf = (*smp_cmd_build_act[cmd_code])(cmd_code, p_cb);
    325 
    326         if (p_buf != NULL &&
    327             smp_send_msg_to_L2CAP(p_cb->pairing_bda, p_buf))
    328         {
    329             sent = TRUE;
    330             alarm_set_on_queue(p_cb->smp_rsp_timer_ent,
    331                                SMP_WAIT_FOR_RSP_TIMEOUT_MS, smp_rsp_timeout,
    332                                NULL, btu_general_alarm_queue);
    333         }
    334     }
    335 
    336     if (!sent)
    337     {
    338         if (p_cb->smp_over_br)
    339         {
    340             smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &failure);
    341         }
    342         else
    343         {
    344             smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    345         }
    346     }
    347     return sent;
    348 }
    349 
    350 /*******************************************************************************
    351 **
    352 ** Function         smp_rsp_timeout
    353 **
    354 ** Description      Called when SMP wait for SMP command response timer expires
    355 **
    356 ** Returns          void
    357 **
    358 *******************************************************************************/
    359 void smp_rsp_timeout(UNUSED_ATTR void *data)
    360 {
    361     tSMP_CB   *p_cb = &smp_cb;
    362     UINT8 failure = SMP_RSP_TIMEOUT;
    363 
    364     SMP_TRACE_EVENT("%s state:%d br_state:%d", __FUNCTION__, p_cb->state, p_cb->br_state);
    365 
    366     if (p_cb->smp_over_br)
    367     {
    368         smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &failure);
    369     }
    370     else
    371     {
    372         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
    373     }
    374 }
    375 
    376 /*******************************************************************************
    377 **
    378 ** Function         smp_build_pairing_req_cmd
    379 **
    380 ** Description      Build pairing request command.
    381 **
    382 *******************************************************************************/
    383 BT_HDR * smp_build_pairing_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    384 {
    385     UINT8 *p;
    386     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    387                         SMP_PAIRING_REQ_SIZE + L2CAP_MIN_OFFSET);
    388 
    389     SMP_TRACE_EVENT("%s", __func__);
    390 
    391     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    392     UINT8_TO_STREAM(p, cmd_code);
    393     UINT8_TO_STREAM(p, p_cb->local_io_capability);
    394     UINT8_TO_STREAM(p, p_cb->loc_oob_flag);
    395     UINT8_TO_STREAM(p, p_cb->loc_auth_req);
    396     UINT8_TO_STREAM(p, p_cb->loc_enc_size);
    397     UINT8_TO_STREAM(p, p_cb->local_i_key);
    398     UINT8_TO_STREAM(p, p_cb->local_r_key);
    399 
    400     p_buf->offset = L2CAP_MIN_OFFSET;
    401     /* 1B ERR_RSP op code + 1B cmd_op_code + 2B handle + 1B status */
    402     p_buf->len = SMP_PAIRING_REQ_SIZE;
    403 
    404     return p_buf;
    405 }
    406 
    407 /*******************************************************************************
    408 **
    409 ** Function         smp_build_confirm_cmd
    410 **
    411 ** Description      Build confirm request command.
    412 **
    413 *******************************************************************************/
    414 static BT_HDR * smp_build_confirm_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    415 {
    416     UINT8 *p;
    417     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    418                         SMP_CONFIRM_CMD_SIZE + L2CAP_MIN_OFFSET);
    419 
    420     UNUSED(cmd_code);
    421     SMP_TRACE_EVENT("%s", __func__);
    422 
    423     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    424 
    425     UINT8_TO_STREAM(p, SMP_OPCODE_CONFIRM);
    426     ARRAY_TO_STREAM(p, p_cb->confirm, BT_OCTET16_LEN);
    427 
    428     p_buf->offset = L2CAP_MIN_OFFSET;
    429     p_buf->len = SMP_CONFIRM_CMD_SIZE;
    430 
    431     return p_buf;
    432 }
    433 
    434 /*******************************************************************************
    435 **
    436 ** Function         smp_build_rand_cmd
    437 **
    438 ** Description      Build Random command.
    439 **
    440 *******************************************************************************/
    441 static BT_HDR * smp_build_rand_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    442 {
    443     UINT8 *p;
    444     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    445                         SMP_RAND_CMD_SIZE + L2CAP_MIN_OFFSET);
    446 
    447     UNUSED(cmd_code);
    448     SMP_TRACE_EVENT("%s", __func__);
    449 
    450     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    451     UINT8_TO_STREAM(p, SMP_OPCODE_RAND);
    452     ARRAY_TO_STREAM(p, p_cb->rand, BT_OCTET16_LEN);
    453 
    454     p_buf->offset = L2CAP_MIN_OFFSET;
    455     p_buf->len = SMP_RAND_CMD_SIZE;
    456 
    457     return p_buf;
    458 }
    459 
    460 /*******************************************************************************
    461 **
    462 ** Function         smp_build_encrypt_info_cmd
    463 **
    464 ** Description      Build security information command.
    465 **
    466 *******************************************************************************/
    467 static BT_HDR * smp_build_encrypt_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    468 {
    469     UINT8 *p;
    470     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    471                         SMP_ENC_INFO_SIZE + L2CAP_MIN_OFFSET);
    472 
    473     UNUSED(cmd_code);
    474     SMP_TRACE_EVENT("%s", __func__);
    475 
    476     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    477     UINT8_TO_STREAM(p, SMP_OPCODE_ENCRYPT_INFO);
    478     ARRAY_TO_STREAM(p, p_cb->ltk, BT_OCTET16_LEN);
    479 
    480     p_buf->offset = L2CAP_MIN_OFFSET;
    481     p_buf->len = SMP_ENC_INFO_SIZE;
    482 
    483     return p_buf;
    484 }
    485 
    486 /*******************************************************************************
    487 **
    488 ** Function         smp_build_master_id_cmd
    489 **
    490 ** Description      Build security information command.
    491 **
    492 *******************************************************************************/
    493 static BT_HDR * smp_build_master_id_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    494 {
    495     UINT8 *p;
    496     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    497                         SMP_MASTER_ID_SIZE + L2CAP_MIN_OFFSET);
    498 
    499     UNUSED(cmd_code);
    500     SMP_TRACE_EVENT("%s", __func__);
    501 
    502     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    503     UINT8_TO_STREAM(p, SMP_OPCODE_MASTER_ID);
    504     UINT16_TO_STREAM(p, p_cb->ediv);
    505     ARRAY_TO_STREAM(p, p_cb->enc_rand, BT_OCTET8_LEN);
    506 
    507     p_buf->offset = L2CAP_MIN_OFFSET;
    508     p_buf->len = SMP_MASTER_ID_SIZE;
    509 
    510     return p_buf;
    511 }
    512 
    513 /*******************************************************************************
    514 **
    515 ** Function         smp_build_identity_info_cmd
    516 **
    517 ** Description      Build identity information command.
    518 **
    519 *******************************************************************************/
    520 static BT_HDR * smp_build_identity_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    521 {
    522     UINT8 *p;
    523     BT_OCTET16 irk;
    524     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    525                         SMP_ID_INFO_SIZE + L2CAP_MIN_OFFSET);
    526 
    527     UNUSED(cmd_code);
    528     UNUSED(p_cb);
    529     SMP_TRACE_EVENT("%s", __func__);
    530 
    531     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    532 
    533     BTM_GetDeviceIDRoot(irk);
    534 
    535     UINT8_TO_STREAM(p, SMP_OPCODE_IDENTITY_INFO);
    536     ARRAY_TO_STREAM(p,  irk, BT_OCTET16_LEN);
    537 
    538     p_buf->offset = L2CAP_MIN_OFFSET;
    539     p_buf->len = SMP_ID_INFO_SIZE;
    540 
    541     return p_buf;
    542 }
    543 
    544 /*******************************************************************************
    545 **
    546 ** Function         smp_build_id_addr_cmd
    547 **
    548 ** Description      Build identity address information command.
    549 **
    550 *******************************************************************************/
    551 static BT_HDR * smp_build_id_addr_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    552 {
    553     UINT8 *p;
    554     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    555                         SMP_ID_ADDR_SIZE + L2CAP_MIN_OFFSET);
    556 
    557     UNUSED(cmd_code);
    558     UNUSED(p_cb);
    559     SMP_TRACE_EVENT("%s", __func__);
    560 
    561     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    562     UINT8_TO_STREAM(p, SMP_OPCODE_ID_ADDR);
    563     UINT8_TO_STREAM(p, 0);
    564     BDADDR_TO_STREAM(p, controller_get_interface()->get_address()->address);
    565 
    566     p_buf->offset = L2CAP_MIN_OFFSET;
    567     p_buf->len = SMP_ID_ADDR_SIZE;
    568 
    569     return p_buf;
    570 }
    571 
    572 /*******************************************************************************
    573 **
    574 ** Function         smp_build_signing_info_cmd
    575 **
    576 ** Description      Build signing information command.
    577 **
    578 *******************************************************************************/
    579 static BT_HDR * smp_build_signing_info_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    580 {
    581     UINT8 *p;
    582     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    583                         SMP_SIGN_INFO_SIZE + L2CAP_MIN_OFFSET);
    584 
    585     UNUSED(cmd_code);
    586     SMP_TRACE_EVENT("%s", __func__);
    587 
    588     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    589     UINT8_TO_STREAM(p, SMP_OPCODE_SIGN_INFO);
    590     ARRAY_TO_STREAM(p, p_cb->csrk, BT_OCTET16_LEN);
    591 
    592     p_buf->offset = L2CAP_MIN_OFFSET;
    593     p_buf->len = SMP_SIGN_INFO_SIZE;
    594 
    595     return p_buf;
    596 }
    597 
    598 /*******************************************************************************
    599 **
    600 ** Function         smp_build_pairing_fail
    601 **
    602 ** Description      Build Pairing Fail command.
    603 **
    604 *******************************************************************************/
    605 static BT_HDR * smp_build_pairing_fail(UINT8 cmd_code, tSMP_CB *p_cb)
    606 {
    607     UINT8 *p;
    608     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    609                         SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET);
    610 
    611     UNUSED(cmd_code);
    612     SMP_TRACE_EVENT("%s", __func__);
    613 
    614     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    615     UINT8_TO_STREAM(p, SMP_OPCODE_PAIRING_FAILED);
    616     UINT8_TO_STREAM(p, p_cb->failure);
    617 
    618     p_buf->offset = L2CAP_MIN_OFFSET;
    619     p_buf->len = SMP_PAIR_FAIL_SIZE;
    620 
    621     return p_buf;
    622 }
    623 
    624 /*******************************************************************************
    625 **
    626 ** Function         smp_build_security_request
    627 **
    628 ** Description      Build security request command.
    629 **
    630 *******************************************************************************/
    631 static BT_HDR *smp_build_security_request(UINT8 cmd_code, tSMP_CB *p_cb)
    632 {
    633     UINT8 *p;
    634     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    635                         2 + L2CAP_MIN_OFFSET);
    636 
    637     UNUSED(cmd_code);
    638     SMP_TRACE_EVENT("%s", __func__);
    639 
    640     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    641     UINT8_TO_STREAM(p, SMP_OPCODE_SEC_REQ);
    642     UINT8_TO_STREAM(p, p_cb->loc_auth_req);
    643 
    644     p_buf->offset = L2CAP_MIN_OFFSET;
    645     p_buf->len = SMP_SECURITY_REQUEST_SIZE;
    646 
    647     SMP_TRACE_EVENT("opcode=%d auth_req=0x%x",SMP_OPCODE_SEC_REQ,  p_cb->loc_auth_req );
    648 
    649     return p_buf;
    650 }
    651 
    652 /*******************************************************************************
    653 **
    654 ** Function         smp_build_pair_public_key_cmd
    655 **
    656 ** Description      Build pairing public key command.
    657 **
    658 *******************************************************************************/
    659 static BT_HDR *smp_build_pair_public_key_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    660 {
    661     UINT8   *p;
    662     UINT8   publ_key[2*BT_OCTET32_LEN];
    663     UINT8   *p_publ_key = publ_key;
    664     BT_HDR  *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    665                         SMP_PAIR_PUBL_KEY_SIZE + L2CAP_MIN_OFFSET);
    666 
    667     UNUSED(cmd_code);
    668     SMP_TRACE_EVENT("%s", __func__);
    669 
    670     memcpy(p_publ_key, p_cb->loc_publ_key.x, BT_OCTET32_LEN);
    671     memcpy(p_publ_key + BT_OCTET32_LEN, p_cb->loc_publ_key.y, BT_OCTET32_LEN);
    672 
    673     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    674     UINT8_TO_STREAM(p, SMP_OPCODE_PAIR_PUBLIC_KEY);
    675     ARRAY_TO_STREAM(p, p_publ_key, 2*BT_OCTET32_LEN);
    676 
    677     p_buf->offset = L2CAP_MIN_OFFSET;
    678     p_buf->len = SMP_PAIR_PUBL_KEY_SIZE;
    679 
    680     return p_buf;
    681 }
    682 
    683 /*******************************************************************************
    684 **
    685 ** Function         smp_build_pairing_commitment_cmd
    686 **
    687 ** Description      Build pairing commitment command.
    688 **
    689 *******************************************************************************/
    690 static BT_HDR *smp_build_pairing_commitment_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    691 {
    692     UINT8 *p;
    693     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    694                         SMP_PAIR_COMMITM_SIZE + L2CAP_MIN_OFFSET);
    695 
    696     UNUSED(cmd_code);
    697     SMP_TRACE_EVENT("%s", __func__);
    698 
    699     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    700     UINT8_TO_STREAM(p, SMP_OPCODE_CONFIRM);
    701     ARRAY_TO_STREAM(p, p_cb->commitment, BT_OCTET16_LEN);
    702 
    703     p_buf->offset = L2CAP_MIN_OFFSET;
    704     p_buf->len = SMP_PAIR_COMMITM_SIZE;
    705 
    706     return p_buf;
    707 }
    708 
    709 /*******************************************************************************
    710 **
    711 ** Function         smp_build_pair_dhkey_check_cmd
    712 **
    713 ** Description      Build pairing DHKey check command.
    714 **
    715 *******************************************************************************/
    716 static BT_HDR *smp_build_pair_dhkey_check_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    717 {
    718     UINT8 *p;
    719     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    720                         SMP_PAIR_DHKEY_CHECK_SIZE + L2CAP_MIN_OFFSET);
    721 
    722     UNUSED(cmd_code);
    723     SMP_TRACE_EVENT("%s", __func__);
    724 
    725     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    726     UINT8_TO_STREAM(p, SMP_OPCODE_PAIR_DHKEY_CHECK);
    727     ARRAY_TO_STREAM(p, p_cb->dhkey_check, BT_OCTET16_LEN);
    728 
    729     p_buf->offset = L2CAP_MIN_OFFSET;
    730     p_buf->len = SMP_PAIR_DHKEY_CHECK_SIZE;
    731 
    732     return p_buf;
    733 }
    734 
    735 /*******************************************************************************
    736 **
    737 ** Function         smp_build_pairing_keypress_notification_cmd
    738 **
    739 ** Description      Build keypress notification command.
    740 **
    741 *******************************************************************************/
    742 static BT_HDR * smp_build_pairing_keypress_notification_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
    743 {
    744     UINT8       *p;
    745     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
    746                         SMP_PAIR_KEYPR_NOTIF_SIZE + L2CAP_MIN_OFFSET);
    747 
    748     UNUSED(cmd_code);
    749     SMP_TRACE_EVENT("%s", __func__);
    750 
    751     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
    752     UINT8_TO_STREAM(p, SMP_OPCODE_PAIR_KEYPR_NOTIF);
    753     UINT8_TO_STREAM(p, p_cb->local_keypress_notification);
    754 
    755     p_buf->offset = L2CAP_MIN_OFFSET;
    756     p_buf->len = SMP_PAIR_KEYPR_NOTIF_SIZE;
    757 
    758     return p_buf;
    759 }
    760 
    761 /*******************************************************************************
    762 **
    763 ** Function         smp_convert_string_to_tk
    764 **
    765 ** Description      This function is called to convert a 6 to 16 digits numeric
    766 **                  character string into SMP TK.
    767 **
    768 **
    769 ** Returns          void
    770 **
    771 *******************************************************************************/
    772 void smp_convert_string_to_tk(BT_OCTET16 tk, UINT32 passkey)
    773 {
    774     UINT8   *p = tk;
    775     tSMP_KEY    key;
    776     SMP_TRACE_EVENT("smp_convert_string_to_tk");
    777     UINT32_TO_STREAM(p, passkey);
    778 
    779     key.key_type    = SMP_KEY_TYPE_TK;
    780     key.p_data      = tk;
    781 
    782     smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
    783 }
    784 
    785 /*******************************************************************************
    786 **
    787 ** Function         smp_mask_enc_key
    788 **
    789 ** Description      This function is called to mask off the encryption key based
    790 **                  on the maximum encryption key size.
    791 **
    792 **
    793 ** Returns          void
    794 **
    795 *******************************************************************************/
    796 void smp_mask_enc_key(UINT8 loc_enc_size, UINT8 * p_data)
    797 {
    798     SMP_TRACE_EVENT("smp_mask_enc_key");
    799     if (loc_enc_size < BT_OCTET16_LEN)
    800     {
    801         for (; loc_enc_size < BT_OCTET16_LEN; loc_enc_size ++)
    802             * (p_data + loc_enc_size) = 0;
    803     }
    804     return;
    805 }
    806 
    807 /*******************************************************************************
    808 **
    809 ** Function         smp_xor_128
    810 **
    811 ** Description      utility function to do an biteise exclusive-OR of two bit
    812 **                  strings of the length of BT_OCTET16_LEN.
    813 **
    814 ** Returns          void
    815 **
    816 *******************************************************************************/
    817 void smp_xor_128(BT_OCTET16 a, BT_OCTET16 b)
    818 {
    819     UINT8 i, *aa = a, *bb = b;
    820 
    821     SMP_TRACE_EVENT("smp_xor_128");
    822     for (i = 0; i < BT_OCTET16_LEN; i++)
    823     {
    824         aa[i] = aa[i] ^ bb[i];
    825     }
    826 }
    827 
    828 /*******************************************************************************
    829 **
    830 ** Function         smp_cb_cleanup
    831 **
    832 ** Description      Clean up SMP control block
    833 **
    834 ** Returns          void
    835 **
    836 *******************************************************************************/
    837 void smp_cb_cleanup(tSMP_CB   *p_cb)
    838 {
    839     tSMP_CALLBACK   *p_callback = p_cb->p_callback;
    840     UINT8           trace_level = p_cb->trace_level;
    841 
    842     SMP_TRACE_EVENT("smp_cb_cleanup");
    843 
    844     alarm_free(p_cb->smp_rsp_timer_ent);
    845     memset(p_cb, 0, sizeof(tSMP_CB));
    846     p_cb->p_callback = p_callback;
    847     p_cb->trace_level = trace_level;
    848     p_cb->smp_rsp_timer_ent = alarm_new("smp.smp_rsp_timer_ent");
    849 }
    850 
    851 /*******************************************************************************
    852 **
    853 ** Function         smp_remove_fixed_channel
    854 **
    855 ** Description      This function is called to remove the fixed channel
    856 **
    857 ** Returns          void
    858 **
    859 *******************************************************************************/
    860 void smp_remove_fixed_channel(tSMP_CB *p_cb)
    861 {
    862     SMP_TRACE_DEBUG("%s", __func__);
    863 
    864     if (p_cb->smp_over_br)
    865         L2CA_RemoveFixedChnl (L2CAP_SMP_BR_CID, p_cb->pairing_bda);
    866     else
    867         L2CA_RemoveFixedChnl (L2CAP_SMP_CID, p_cb->pairing_bda);
    868 }
    869 
    870 /*******************************************************************************
    871 **
    872 ** Function         smp_reset_control_value
    873 **
    874 ** Description      This function is called to reset the control block value when
    875 **                  pairing procedure finished.
    876 **
    877 **
    878 ** Returns          void
    879 **
    880 *******************************************************************************/
    881 void smp_reset_control_value(tSMP_CB *p_cb)
    882 {
    883     SMP_TRACE_EVENT("%s", __func__);
    884 
    885     alarm_cancel(p_cb->smp_rsp_timer_ent);
    886     p_cb->flags = 0;
    887     /* set the link idle timer to drop the link when pairing is done
    888        usually service discovery will follow authentication complete, to avoid
    889        racing condition for a link down/up, set link idle timer to be
    890        SMP_LINK_TOUT_MIN to guarantee SMP key exchange */
    891     L2CA_SetIdleTimeoutByBdAddr(p_cb->pairing_bda, SMP_LINK_TOUT_MIN, BT_TRANSPORT_LE);
    892 
    893     /* We can tell L2CAP to remove the fixed channel (if it has one) */
    894     smp_remove_fixed_channel(p_cb);
    895     smp_cb_cleanup(p_cb);
    896 }
    897 
    898 /*******************************************************************************
    899 **
    900 ** Function         smp_proc_pairing_cmpl
    901 **
    902 ** Description      This function is called to process pairing complete
    903 **
    904 **
    905 ** Returns          void
    906 **
    907 *******************************************************************************/
    908 void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
    909 {
    910     tSMP_EVT_DATA   evt_data = {0};
    911     tSMP_CALLBACK   *p_callback = p_cb->p_callback;
    912     BD_ADDR         pairing_bda;
    913 
    914     SMP_TRACE_DEBUG ("smp_proc_pairing_cmpl ");
    915 
    916     evt_data.cmplt.reason = p_cb->status;
    917     evt_data.cmplt.smp_over_br = p_cb->smp_over_br;
    918 
    919     if (p_cb->status == SMP_SUCCESS)
    920         evt_data.cmplt.sec_level = p_cb->sec_level;
    921 
    922     evt_data.cmplt.is_pair_cancel  = FALSE;
    923 
    924     if (p_cb->is_pair_cancel)
    925         evt_data.cmplt.is_pair_cancel = TRUE;
    926 
    927 
    928     SMP_TRACE_DEBUG ("send SMP_COMPLT_EVT reason=0x%0x sec_level=0x%0x",
    929                       evt_data.cmplt.reason,
    930                       evt_data.cmplt.sec_level );
    931 
    932     memcpy (pairing_bda, p_cb->pairing_bda, BD_ADDR_LEN);
    933 
    934     smp_reset_control_value(p_cb);
    935 
    936     if (p_callback)
    937         (*p_callback) (SMP_COMPLT_EVT, pairing_bda, &evt_data);
    938 }
    939 
    940 /*******************************************************************************
    941 **
    942 ** Function         smp_command_has_invalid_parameters
    943 **
    944 ** Description      Checks if the received SMP command has invalid parameters i.e.
    945 **                  if the command length is valid and the command parameters are
    946 **                  inside specified range.
    947 **                  It returns TRUE if the command has invalid parameters.
    948 **
    949 ** Returns          TRUE if the command has invalid parameters, FALSE otherwise.
    950 **
    951 *******************************************************************************/
    952 BOOLEAN smp_command_has_invalid_parameters(tSMP_CB *p_cb)
    953 {
    954     UINT8 cmd_code = p_cb->rcvd_cmd_code;
    955 
    956     SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, cmd_code);
    957 
    958     if ((cmd_code > (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */)) ||
    959         (cmd_code < SMP_OPCODE_MIN))
    960     {
    961         SMP_TRACE_WARNING("Somehow received command with the RESERVED code 0x%02x", cmd_code);
    962         return TRUE;
    963     }
    964 
    965     if (!(*smp_cmd_len_is_valid[cmd_code])(p_cb))
    966         return TRUE;
    967 
    968     if (!(*smp_cmd_param_ranges_are_valid[cmd_code])(p_cb))
    969         return TRUE;
    970 
    971     return FALSE;
    972 }
    973 
    974 /*******************************************************************************
    975 **
    976 ** Function         smp_command_has_valid_fixed_length
    977 **
    978 ** Description      Checks if the received command size is equal to the size
    979 **                  according to specs.
    980 **
    981 ** Returns          TRUE if the command size is as expected, FALSE otherwise.
    982 **
    983 ** Note             The command is expected to have fixed length.
    984 *******************************************************************************/
    985 BOOLEAN smp_command_has_valid_fixed_length(tSMP_CB *p_cb)
    986 {
    987     UINT8   cmd_code = p_cb->rcvd_cmd_code;
    988 
    989     SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, cmd_code);
    990 
    991     if (p_cb->rcvd_cmd_len != smp_cmd_size_per_spec[cmd_code])
    992     {
    993         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with invalid length\
    994             0x%02x (per spec the length is 0x%02x).",
    995             cmd_code, p_cb->rcvd_cmd_len, smp_cmd_size_per_spec[cmd_code]);
    996         return FALSE;
    997     }
    998 
    999     return TRUE;
   1000 }
   1001 
   1002 /*******************************************************************************
   1003 **
   1004 ** Function         smp_pairing_request_response_parameters_are_valid
   1005 **
   1006 ** Description      Validates parameter ranges in the received SMP command
   1007 **                  pairing request or pairing response.
   1008 **                  The parameters to validate:
   1009 **                  IO capability,
   1010 **                  OOB data flag,
   1011 **                  Bonding_flags in AuthReq
   1012 **                  Maximum encryption key size.
   1013 **                  Returns FALSE if at least one of these parameters is out of range.
   1014 **
   1015 *******************************************************************************/
   1016 BOOLEAN smp_pairing_request_response_parameters_are_valid(tSMP_CB *p_cb)
   1017 {
   1018     UINT8   io_caps = p_cb->peer_io_caps;
   1019     UINT8   oob_flag = p_cb->peer_oob_flag;
   1020     UINT8   bond_flag = p_cb->peer_auth_req & 0x03; //0x03 is gen bond with appropriate mask
   1021     UINT8   enc_size = p_cb->peer_enc_size;
   1022 
   1023     SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, p_cb->rcvd_cmd_code);
   1024 
   1025     if (io_caps >= BTM_IO_CAP_MAX)
   1026     {
   1027         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with IO Capabilty \
   1028             value (0x%02x) out of range).",
   1029             p_cb->rcvd_cmd_code, io_caps);
   1030         return FALSE;
   1031     }
   1032 
   1033     if (!((oob_flag == SMP_OOB_NONE) || (oob_flag == SMP_OOB_PRESENT)))
   1034     {
   1035         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with OOB data flag value \
   1036             (0x%02x) out of range).",
   1037              p_cb->rcvd_cmd_code, oob_flag);
   1038         return FALSE;
   1039     }
   1040 
   1041     if (!((bond_flag == SMP_AUTH_NO_BOND) || (bond_flag == SMP_AUTH_BOND)))
   1042     {
   1043         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Bonding_Flags value (0x%02x)\
   1044                            out of range).",
   1045                            p_cb->rcvd_cmd_code, bond_flag);
   1046         return FALSE;
   1047     }
   1048 
   1049     if ((enc_size < SMP_ENCR_KEY_SIZE_MIN) || (enc_size > SMP_ENCR_KEY_SIZE_MAX))
   1050     {
   1051         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Maximum Encryption \
   1052             Key value (0x%02x) out of range).",
   1053             p_cb->rcvd_cmd_code, enc_size);
   1054         return FALSE;
   1055     }
   1056 
   1057     return TRUE;
   1058 }
   1059 
   1060 /*******************************************************************************
   1061 **
   1062 ** Function         smp_pairing_keypress_notification_is_valid
   1063 **
   1064 ** Description      Validates Notification Type parameter range in the received SMP command
   1065 **                  pairing keypress notification.
   1066 **                  Returns FALSE if this parameter is out of range.
   1067 **
   1068 *******************************************************************************/
   1069 BOOLEAN smp_pairing_keypress_notification_is_valid(tSMP_CB *p_cb)
   1070 {
   1071     tBTM_SP_KEY_TYPE keypress_notification = p_cb->peer_keypress_notification;
   1072 
   1073     SMP_TRACE_DEBUG("%s for cmd code 0x%02x", __func__, p_cb->rcvd_cmd_code);
   1074 
   1075     if (keypress_notification >= BTM_SP_KEY_OUT_OF_RANGE)
   1076     {
   1077         SMP_TRACE_WARNING("Rcvd from the peer cmd 0x%02x with Pairing Keypress \
   1078             Notification value (0x%02x) out of range).",
   1079             p_cb->rcvd_cmd_code, keypress_notification);
   1080         return FALSE;
   1081     }
   1082 
   1083     return TRUE;
   1084 }
   1085 
   1086 /*******************************************************************************
   1087 **
   1088 ** Function         smp_parameter_unconditionally_valid
   1089 **
   1090 ** Description      Always returns TRUE.
   1091 **
   1092 *******************************************************************************/
   1093 BOOLEAN smp_parameter_unconditionally_valid(UNUSED_ATTR tSMP_CB *p_cb)
   1094 {
   1095     return TRUE;
   1096 }
   1097 
   1098 /*******************************************************************************
   1099 **
   1100 ** Function         smp_parameter_unconditionally_invalid
   1101 **
   1102 ** Description      Always returns FALSE.
   1103 **
   1104 *******************************************************************************/
   1105 BOOLEAN smp_parameter_unconditionally_invalid(UNUSED_ATTR tSMP_CB *p_cb)
   1106 {
   1107     return FALSE;
   1108 }
   1109 
   1110 /*******************************************************************************
   1111 **
   1112 ** Function         smp_reject_unexpected_pairing_command
   1113 **
   1114 ** Description      send pairing failure to an unexpected pairing command during
   1115 **                  an active pairing process.
   1116 **
   1117 ** Returns          void
   1118 **
   1119 *******************************************************************************/
   1120 void smp_reject_unexpected_pairing_command(BD_ADDR bd_addr)
   1121 {
   1122     UINT8 *p;
   1123     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) +
   1124                         SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET);
   1125 
   1126     SMP_TRACE_DEBUG("%s", __func__);
   1127 
   1128     p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
   1129     UINT8_TO_STREAM(p, SMP_OPCODE_PAIRING_FAILED);
   1130     UINT8_TO_STREAM(p, SMP_PAIR_NOT_SUPPORT);
   1131 
   1132     p_buf->offset = L2CAP_MIN_OFFSET;
   1133     p_buf->len = SMP_PAIR_FAIL_SIZE;
   1134 
   1135     smp_send_msg_to_L2CAP(bd_addr, p_buf);
   1136 }
   1137 
   1138 /*******************************************************************************
   1139 ** Function         smp_select_association_model
   1140 **
   1141 ** Description      This function selects association model to use for STK
   1142 **                  generation. Selection is based on both sides' io capability,
   1143 **                  oob data flag and authentication request.
   1144 **
   1145 ** Note             If Secure Connections Only mode is required locally then we
   1146 **                  come to this point only if both sides support Secure Connections
   1147 **                  mode, i.e. if p_cb->secure_connections_only_mode_required = TRUE then we come
   1148 **                  to this point only if
   1149 **                      (p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT) ==
   1150 **                      (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) ==
   1151 **                      SMP_SC_SUPPORT_BIT
   1152 **
   1153 *******************************************************************************/
   1154 tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB *p_cb)
   1155 {
   1156     tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
   1157     p_cb->le_secure_connections_mode_is_used = FALSE;
   1158 
   1159     SMP_TRACE_EVENT("%s", __FUNCTION__);
   1160     SMP_TRACE_DEBUG("%s p_cb->peer_io_caps = %d p_cb->local_io_capability = %d",
   1161                        __FUNCTION__, p_cb->peer_io_caps, p_cb->local_io_capability);
   1162     SMP_TRACE_DEBUG("%s p_cb->peer_oob_flag = %d p_cb->loc_oob_flag = %d",
   1163                        __FUNCTION__, p_cb->peer_oob_flag, p_cb->loc_oob_flag);
   1164     SMP_TRACE_DEBUG("%s p_cb->peer_auth_req = 0x%02x p_cb->loc_auth_req = 0x%02x",
   1165                        __FUNCTION__, p_cb->peer_auth_req, p_cb->loc_auth_req);
   1166     SMP_TRACE_DEBUG("%s p_cb->secure_connections_only_mode_required = %s",
   1167                        __FUNCTION__, p_cb->secure_connections_only_mode_required ?
   1168                                     "TRUE" : "FALSE");
   1169 
   1170     if ((p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT) && (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT))
   1171     {
   1172         p_cb->le_secure_connections_mode_is_used = TRUE;
   1173     }
   1174 
   1175     SMP_TRACE_DEBUG("use_sc_process = %d", p_cb->le_secure_connections_mode_is_used);
   1176 
   1177     if (p_cb->le_secure_connections_mode_is_used)
   1178     {
   1179         model = smp_select_association_model_secure_connections(p_cb);
   1180     }
   1181     else
   1182     {
   1183         model = smp_select_legacy_association_model(p_cb);
   1184     }
   1185     return model;
   1186 }
   1187 
   1188 /*******************************************************************************
   1189 ** Function         smp_select_legacy_association_model
   1190 **
   1191 ** Description      This function is called to select association mode if at least
   1192 **                  one side doesn't support secure connections.
   1193 **
   1194 *******************************************************************************/
   1195 tSMP_ASSO_MODEL smp_select_legacy_association_model(tSMP_CB *p_cb)
   1196 {
   1197     tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
   1198 
   1199     SMP_TRACE_DEBUG("%s", __func__);
   1200     /* if OOB data is present on both devices, then use OOB association model */
   1201     if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && p_cb->loc_oob_flag == SMP_OOB_PRESENT)
   1202         return SMP_MODEL_OOB;
   1203 
   1204     /* else if neither device requires MITM, then use Just Works association model */
   1205     if (SMP_NO_MITM_REQUIRED (p_cb->peer_auth_req) && SMP_NO_MITM_REQUIRED(p_cb->loc_auth_req))
   1206         return SMP_MODEL_ENCRYPTION_ONLY;
   1207 
   1208     /* otherwise use IO capability to select association model */
   1209     if (p_cb->peer_io_caps < SMP_IO_CAP_MAX && p_cb->local_io_capability < SMP_IO_CAP_MAX)
   1210     {
   1211         if (p_cb->role == HCI_ROLE_MASTER)
   1212         {
   1213             model = smp_association_table[p_cb->role][p_cb->peer_io_caps]
   1214                                          [p_cb->local_io_capability];
   1215         }
   1216         else
   1217         {
   1218             model = smp_association_table[p_cb->role][p_cb->local_io_capability]
   1219                                          [p_cb->peer_io_caps];
   1220         }
   1221     }
   1222 
   1223     return model;
   1224 }
   1225 
   1226 /*******************************************************************************
   1227 ** Function         smp_select_association_model_secure_connections
   1228 **
   1229 ** Description      This function is called to select association mode if both
   1230 **                  sides support secure connections.
   1231 **
   1232 *******************************************************************************/
   1233 tSMP_ASSO_MODEL smp_select_association_model_secure_connections(tSMP_CB *p_cb)
   1234 {
   1235     tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE;
   1236 
   1237     SMP_TRACE_DEBUG("%s", __func__);
   1238     /* if OOB data is present on at least one device, then use OOB association model */
   1239     if (p_cb->peer_oob_flag == SMP_OOB_PRESENT || p_cb->loc_oob_flag == SMP_OOB_PRESENT)
   1240         return SMP_MODEL_SEC_CONN_OOB;
   1241 
   1242     /* else if neither device requires MITM, then use Just Works association model */
   1243     if (SMP_NO_MITM_REQUIRED (p_cb->peer_auth_req) && SMP_NO_MITM_REQUIRED(p_cb->loc_auth_req))
   1244         return SMP_MODEL_SEC_CONN_JUSTWORKS;
   1245 
   1246     /* otherwise use IO capability to select association model */
   1247     if (p_cb->peer_io_caps < SMP_IO_CAP_MAX && p_cb->local_io_capability < SMP_IO_CAP_MAX)
   1248     {
   1249         if (p_cb->role == HCI_ROLE_MASTER)
   1250         {
   1251             model = smp_association_table_sc[p_cb->role][p_cb->peer_io_caps]
   1252                                             [p_cb->local_io_capability];
   1253         }
   1254         else
   1255         {
   1256             model = smp_association_table_sc[p_cb->role][p_cb->local_io_capability]
   1257                                             [p_cb->peer_io_caps];
   1258         }
   1259     }
   1260 
   1261     return model;
   1262 }
   1263 
   1264 /*******************************************************************************
   1265 ** Function         smp_reverse_array
   1266 **
   1267 ** Description      This function reverses array bytes
   1268 **
   1269 *******************************************************************************/
   1270 void smp_reverse_array(UINT8 *arr, UINT8 len)
   1271 {
   1272     UINT8 i =0, tmp;
   1273 
   1274     SMP_TRACE_DEBUG("smp_reverse_array");
   1275 
   1276     for (i = 0; i < len/2; i ++)
   1277     {
   1278         tmp = arr[i];
   1279         arr[i] = arr[len -1 - i];
   1280         arr[len -1 - i] = tmp;
   1281     }
   1282 }
   1283 
   1284 /*******************************************************************************
   1285 ** Function         smp_calculate_random_input
   1286 **
   1287 ** Description      This function returns random input value to be used in commitment
   1288 **                  calculation for SC passkey entry association mode
   1289 **                  (if bit["round"] in "random" array == 1 then returns 0x81
   1290 **                   else returns 0x80).
   1291 **
   1292 ** Returns          ri value
   1293 **
   1294 *******************************************************************************/
   1295 UINT8 smp_calculate_random_input(UINT8 *random, UINT8 round)
   1296 {
   1297     UINT8 i = round/8;
   1298     UINT8 j = round%8;
   1299     UINT8 ri;
   1300 
   1301     SMP_TRACE_DEBUG("random: 0x%02x, round: %d, i: %d, j: %d", random[i], round, i, j);
   1302     ri = ((random[i] >> j) & 1) | 0x80;
   1303     SMP_TRACE_DEBUG("%s ri=0x%02x", __func__, ri);
   1304     return ri;
   1305 }
   1306 
   1307 /*******************************************************************************
   1308 ** Function         smp_collect_local_io_capabilities
   1309 **
   1310 ** Description      This function puts into IOcap array local device
   1311 **                  IOCapability, OOB data, AuthReq.
   1312 **
   1313 ** Returns          void
   1314 **
   1315 *******************************************************************************/
   1316 void smp_collect_local_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
   1317 {
   1318     SMP_TRACE_DEBUG("%s", __func__);
   1319 
   1320     iocap[0] = p_cb->local_io_capability;
   1321     iocap[1] = p_cb->loc_oob_flag;
   1322     iocap[2] = p_cb->loc_auth_req;
   1323 }
   1324 
   1325 /*******************************************************************************
   1326 ** Function         smp_collect_peer_io_capabilities
   1327 **
   1328 ** Description      This function puts into IOcap array peer device
   1329 **                  IOCapability, OOB data, AuthReq.
   1330 **
   1331 ** Returns          void
   1332 **
   1333 *******************************************************************************/
   1334 void smp_collect_peer_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
   1335 {
   1336     SMP_TRACE_DEBUG("%s", __func__);
   1337 
   1338     iocap[0] = p_cb->peer_io_caps;
   1339     iocap[1] = p_cb->peer_oob_flag;
   1340     iocap[2] = p_cb->peer_auth_req;
   1341 }
   1342 
   1343 /*******************************************************************************
   1344 ** Function         smp_collect_local_ble_address
   1345 **
   1346 ** Description      This function puts into le_addr array local device le address:
   1347 **                  le_addr[0-5] = local BD ADDR,
   1348 **                  le_addr[6] = local le address type (PUBLIC/RANDOM).
   1349 **
   1350 ** Returns          void
   1351 **
   1352 *******************************************************************************/
   1353 void smp_collect_local_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
   1354 {
   1355     tBLE_ADDR_TYPE  addr_type = 0;
   1356     BD_ADDR         bda;
   1357     UINT8           *p = le_addr;
   1358 
   1359     SMP_TRACE_DEBUG("%s", __func__);
   1360 
   1361     BTM_ReadConnectionAddr( p_cb->pairing_bda, bda, &addr_type);
   1362     BDADDR_TO_STREAM(p, bda);
   1363     UINT8_TO_STREAM(p, addr_type);
   1364 }
   1365 
   1366 /*******************************************************************************
   1367 ** Function         smp_collect_peer_ble_address
   1368 **
   1369 ** Description      This function puts into le_addr array peer device le address:
   1370 **                  le_addr[0-5] = peer BD ADDR,
   1371 **                  le_addr[6] = peer le address type (PUBLIC/RANDOM).
   1372 **
   1373 ** Returns          void
   1374 **
   1375 *******************************************************************************/
   1376 void smp_collect_peer_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
   1377 {
   1378     tBLE_ADDR_TYPE  addr_type = 0;
   1379     BD_ADDR         bda;
   1380     UINT8           *p = le_addr;
   1381 
   1382     SMP_TRACE_DEBUG("%s", __func__);
   1383 
   1384     if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, bda, &addr_type))
   1385     {
   1386         SMP_TRACE_ERROR("can not collect peer le addr information for unknown device");
   1387         return;
   1388     }
   1389 
   1390     BDADDR_TO_STREAM(p, bda);
   1391     UINT8_TO_STREAM(p, addr_type);
   1392 }
   1393 
   1394 /*******************************************************************************
   1395 ** Function         smp_check_commitment
   1396 **
   1397 ** Description      This function compares peer commitment values:
   1398 **                  - expected (i.e. calculated locally),
   1399 **                  - received from the peer.
   1400 **
   1401 ** Returns          TRUE  if the values are the same
   1402 **                  FALSE otherwise
   1403 **
   1404 *******************************************************************************/
   1405 BOOLEAN smp_check_commitment(tSMP_CB *p_cb)
   1406 {
   1407     BT_OCTET16 expected;
   1408 
   1409     SMP_TRACE_DEBUG("%s", __func__);
   1410 
   1411     smp_calculate_peer_commitment(p_cb, expected);
   1412     print128(expected, (const UINT8 *)"calculated peer commitment");
   1413     print128(p_cb->remote_commitment, (const UINT8 *)"received peer commitment");
   1414 
   1415     if (memcmp(p_cb->remote_commitment, expected, BT_OCTET16_LEN))
   1416     {
   1417         SMP_TRACE_WARNING("Commitment check fails");
   1418         return FALSE;
   1419     }
   1420 
   1421     SMP_TRACE_DEBUG("Commitment check succeeds");
   1422     return TRUE;
   1423 }
   1424 
   1425 /*******************************************************************************
   1426 **
   1427 ** Function         smp_save_secure_connections_long_term_key
   1428 **
   1429 ** Description      The function saves SC LTK as BLE key for future use as local
   1430 **                  and/or peer key.
   1431 **
   1432 ** Returns          void
   1433 **
   1434 *******************************************************************************/
   1435 void smp_save_secure_connections_long_term_key(tSMP_CB *p_cb)
   1436 {
   1437     tBTM_LE_LENC_KEYS   lle_key;
   1438     tBTM_LE_PENC_KEYS   ple_key;
   1439 
   1440     SMP_TRACE_DEBUG("%s-Save LTK as local LTK key", __func__);
   1441     memcpy(lle_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
   1442     lle_key.div = 0;
   1443     lle_key.key_size = p_cb->loc_enc_size;
   1444     lle_key.sec_level = p_cb->sec_level;
   1445     btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, (tBTM_LE_KEY_VALUE *)&lle_key, TRUE);
   1446 
   1447     SMP_TRACE_DEBUG("%s-Save LTK as peer LTK key", __func__);
   1448     ple_key.ediv = 0;
   1449     memset(ple_key.rand, 0, BT_OCTET8_LEN);
   1450     memcpy(ple_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
   1451     ple_key.sec_level = p_cb->sec_level;
   1452     ple_key.key_size  = p_cb->loc_enc_size;
   1453     btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC, (tBTM_LE_KEY_VALUE *)&ple_key, TRUE);
   1454 }
   1455 
   1456 /*******************************************************************************
   1457 **
   1458 ** Function         smp_calculate_f5_mackey_and_long_term_key
   1459 **
   1460 ** Description      The function calculates MacKey and LTK and saves them in CB.
   1461 **                  To calculate MacKey and LTK it calls smp_calc_f5(...).
   1462 **                  MacKey is used in dhkey calculation, LTK is used to encrypt
   1463 **                  the link.
   1464 **
   1465 ** Returns          FALSE if out of resources, TRUE otherwise.
   1466 **
   1467 *******************************************************************************/
   1468 BOOLEAN smp_calculate_f5_mackey_and_long_term_key(tSMP_CB *p_cb)
   1469 {
   1470     UINT8 a[7];
   1471     UINT8 b[7];
   1472     UINT8 *p_na;
   1473     UINT8 *p_nb;
   1474 
   1475     SMP_TRACE_DEBUG("%s", __func__);
   1476 
   1477     if (p_cb->role == HCI_ROLE_MASTER)
   1478     {
   1479         smp_collect_local_ble_address(a, p_cb);
   1480         smp_collect_peer_ble_address(b, p_cb);
   1481         p_na = p_cb->rand;
   1482         p_nb = p_cb->rrand;
   1483     }
   1484     else
   1485     {
   1486         smp_collect_local_ble_address(b, p_cb);
   1487         smp_collect_peer_ble_address(a, p_cb);
   1488         p_na = p_cb->rrand;
   1489         p_nb = p_cb->rand;
   1490     }
   1491 
   1492     if(!smp_calculate_f5(p_cb->dhkey, p_na, p_nb, a, b, p_cb->mac_key, p_cb->ltk))
   1493     {
   1494         SMP_TRACE_ERROR("%s failed", __func__);
   1495         return FALSE;
   1496     }
   1497 
   1498     SMP_TRACE_EVENT ("%s is completed", __func__);
   1499     return TRUE;
   1500 }
   1501 
   1502 /*******************************************************************************
   1503 **
   1504 ** Function         smp_request_oob_data
   1505 **
   1506 ** Description      Requests application to provide OOB data.
   1507 **
   1508 ** Returns          TRUE - OOB data has to be provided by application
   1509 **                  FALSE - otherwise (unexpected)
   1510 **
   1511 *******************************************************************************/
   1512 BOOLEAN smp_request_oob_data(tSMP_CB *p_cb)
   1513 {
   1514     tSMP_OOB_DATA_TYPE req_oob_type = SMP_OOB_INVALID_TYPE;
   1515 
   1516     SMP_TRACE_DEBUG("%s", __func__);
   1517 
   1518     if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && p_cb->loc_oob_flag == SMP_OOB_PRESENT)
   1519     {
   1520         /* both local and peer rcvd data OOB */
   1521         req_oob_type = SMP_OOB_BOTH;
   1522     }
   1523     else if (p_cb->peer_oob_flag == SMP_OOB_PRESENT)
   1524     {
   1525         /* peer rcvd OOB local data, local didn't receive OOB peer data */
   1526         req_oob_type = SMP_OOB_LOCAL;
   1527     }
   1528     else if (p_cb->loc_oob_flag == SMP_OOB_PRESENT)
   1529     {
   1530         req_oob_type = SMP_OOB_PEER;
   1531     }
   1532 
   1533     SMP_TRACE_DEBUG("req_oob_type = %d", req_oob_type);
   1534 
   1535     if (req_oob_type == SMP_OOB_INVALID_TYPE)
   1536         return FALSE;
   1537 
   1538     p_cb->req_oob_type = req_oob_type;
   1539     p_cb->cb_evt = SMP_SC_OOB_REQ_EVT;
   1540     smp_sm_event(p_cb, SMP_TK_REQ_EVT, &req_oob_type);
   1541 
   1542     return TRUE;
   1543 }
   1544 
   1545 
   1546 #endif
   1547 
   1548