Home | History | Annotate | Download | only in btm
      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 BLE device control utilities, and LE
     22  *  security functions.
     23  *
     24  ******************************************************************************/
     25 #include "bt_target.h"
     26 
     27 #if BLE_INCLUDED == TRUE
     28 
     29 #include <string.h>
     30 
     31 #include "bt_types.h"
     32 #include "hcimsgs.h"
     33 #include "btu.h"
     34 #include "btm_int.h"
     35 #include "btm_ble_api.h"
     36 #include "smp_api.h"
     37 #include "l2c_int.h"
     38 #include "gap_api.h"
     39 #include "bt_utils.h"
     40 #include "device/include/controller.h"
     41 
     42 #define LOG_TAG "bt_btm_ble"
     43 #include "osi/include/log.h"
     44 
     45 #if SMP_INCLUDED == TRUE
     46 extern BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length,
     47                                                  UINT16 tlen, UINT8 *p_signature);
     48 extern void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable);
     49 extern BOOLEAN smp_proc_ltk_request(BD_ADDR bda);
     50 #endif
     51 extern void gatt_notify_enc_cmpl(BD_ADDR bd_addr);
     52 /*******************************************************************************/
     53 /* External Function to be called by other modules                             */
     54 /*******************************************************************************/
     55 /********************************************************
     56 **
     57 ** Function         BTM_SecAddBleDevice
     58 **
     59 ** Description      Add/modify device.  This function will be normally called
     60 **                  during host startup to restore all required information
     61 **                  for a LE device stored in the NVRAM.
     62 **
     63 ** Parameters:      bd_addr          - BD address of the peer
     64 **                  bd_name          - Name of the peer device.  NULL if unknown.
     65 **                  dev_type         - Remote device's device type.
     66 **                  addr_type        - LE device address type.
     67 **
     68 ** Returns          TRUE if added OK, else FALSE
     69 **
     70 *******************************************************************************/
     71 BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE dev_type,
     72                              tBLE_ADDR_TYPE addr_type)
     73 {
     74     tBTM_SEC_DEV_REC  *p_dev_rec;
     75     UINT8               i = 0;
     76     tBTM_INQ_INFO      *p_info=NULL;
     77 
     78     BTM_TRACE_DEBUG ("BTM_SecAddBleDevice dev_type=0x%x", dev_type);
     79     p_dev_rec = btm_find_dev (bd_addr);
     80 
     81     if (!p_dev_rec)
     82     {
     83         BTM_TRACE_DEBUG("Add a new device");
     84 
     85         /* There is no device record, allocate one.
     86          * If we can not find an empty spot for this one, let it fail. */
     87         for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++)
     88         {
     89             if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE))
     90             {
     91                 BTM_TRACE_DEBUG ("allocate a new dev rec idx=0x%x ", i );
     92                 p_dev_rec = &btm_cb.sec_dev_rec[i];
     93 
     94                 /* Mark this record as in use and initialize */
     95                 memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
     96                 p_dev_rec->sec_flags = BTM_SEC_IN_USE;
     97                 memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
     98                 p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
     99                 p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE);
    100 
    101                 /* update conn params, use default value for background connection params */
    102                 p_dev_rec->conn_params.min_conn_int     =
    103                 p_dev_rec->conn_params.max_conn_int     =
    104                 p_dev_rec->conn_params.supervision_tout =
    105                 p_dev_rec->conn_params.slave_latency    = BTM_BLE_CONN_PARAM_UNDEF;
    106 
    107                 BTM_TRACE_DEBUG ("hci_handl=0x%x ",  p_dev_rec->ble_hci_handle );
    108                 break;
    109             }
    110         }
    111 
    112         if (!p_dev_rec)
    113             return(FALSE);
    114     }
    115     else
    116     {
    117         BTM_TRACE_DEBUG("Device already exist");
    118     }
    119 
    120     memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME));
    121 
    122     if (bd_name && bd_name[0])
    123     {
    124         p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
    125         BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name),
    126                        (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
    127     }
    128     p_dev_rec->device_type |= dev_type;
    129     p_dev_rec->ble.ble_addr_type = addr_type;
    130 
    131     memcpy (p_dev_rec->ble.pseudo_addr, bd_addr, BD_ADDR_LEN);
    132     /* sync up with the Inq Data base*/
    133     p_info = BTM_InqDbRead(bd_addr);
    134     if (p_info)
    135     {
    136         p_info->results.ble_addr_type = p_dev_rec->ble.ble_addr_type ;
    137         p_info->results.device_type = p_dev_rec->device_type;
    138         BTM_TRACE_DEBUG ("InqDb  device_type =0x%x  addr_type=0x%x",
    139                           p_info->results.device_type, p_info->results.ble_addr_type);
    140     }
    141 
    142     return(TRUE);
    143 }
    144 
    145 /*******************************************************************************
    146 **
    147 ** Function         BTM_SecAddBleKey
    148 **
    149 ** Description      Add/modify LE device information.  This function will be
    150 **                  normally called during host startup to restore all required
    151 **                  information stored in the NVRAM.
    152 **
    153 ** Parameters:      bd_addr          - BD address of the peer
    154 **                  p_le_key         - LE key values.
    155 **                  key_type         - LE SMP key type.
    156 *
    157 ** Returns          TRUE if added OK, else FALSE
    158 **
    159 *******************************************************************************/
    160 BOOLEAN BTM_SecAddBleKey (BD_ADDR bd_addr, tBTM_LE_KEY_VALUE *p_le_key, tBTM_LE_KEY_TYPE key_type)
    161 {
    162 #if SMP_INCLUDED == TRUE
    163     tBTM_SEC_DEV_REC  *p_dev_rec;
    164     BTM_TRACE_DEBUG ("BTM_SecAddBleKey");
    165     p_dev_rec = btm_find_dev (bd_addr);
    166     if (!p_dev_rec || !p_le_key ||
    167         (key_type != BTM_LE_KEY_PENC && key_type != BTM_LE_KEY_PID &&
    168          key_type != BTM_LE_KEY_PCSRK && key_type != BTM_LE_KEY_LENC &&
    169          key_type != BTM_LE_KEY_LCSRK && key_type != BTM_LE_KEY_LID))
    170     {
    171         BTM_TRACE_WARNING ("BTM_SecAddBleKey()  Wrong Type, or No Device record \
    172                         for bdaddr: %08x%04x, Type: %d",
    173                             (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
    174                             (bd_addr[4]<<8)+bd_addr[5], key_type);
    175         return(FALSE);
    176     }
    177 
    178     BTM_TRACE_DEBUG ("BTM_SecAddLeKey()  BDA: %08x%04x, Type: 0x%02x",
    179                       (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
    180                       (bd_addr[4]<<8)+bd_addr[5], key_type);
    181 
    182     btm_sec_save_le_key (bd_addr, key_type, p_le_key, FALSE);
    183 
    184 #if (BLE_PRIVACY_SPT == TRUE)
    185     if (key_type == BTM_LE_KEY_PID || key_type == BTM_LE_KEY_LID)
    186         btm_ble_resolving_list_load_dev (p_dev_rec);
    187 #endif
    188 
    189 #endif
    190 
    191     return(TRUE);
    192 }
    193 
    194 /*******************************************************************************
    195 **
    196 ** Function         BTM_BleLoadLocalKeys
    197 **
    198 ** Description      Local local identity key, encryption root or sign counter.
    199 **
    200 ** Parameters:      key_type: type of key, can be BTM_BLE_KEY_TYPE_ID, BTM_BLE_KEY_TYPE_ER
    201 **                            or BTM_BLE_KEY_TYPE_COUNTER.
    202 **                  p_key: pointer to the key.
    203 *
    204 ** Returns          non2.
    205 **
    206 *******************************************************************************/
    207 void BTM_BleLoadLocalKeys(UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
    208 {
    209     tBTM_DEVCB *p_devcb = &btm_cb.devcb;
    210     BTM_TRACE_DEBUG ("%s", __func__);
    211     if (p_key != NULL)
    212     {
    213         switch (key_type)
    214         {
    215             case BTM_BLE_KEY_TYPE_ID:
    216                 memcpy(&p_devcb->id_keys, &p_key->id_keys, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
    217                 break;
    218 
    219             case BTM_BLE_KEY_TYPE_ER:
    220                 memcpy(p_devcb->ble_encryption_key_value, p_key->er, sizeof(BT_OCTET16));
    221                 break;
    222 
    223             default:
    224                 BTM_TRACE_ERROR("unknow local key type: %d", key_type);
    225                 break;
    226         }
    227     }
    228 }
    229 
    230 /*******************************************************************************
    231 **
    232 ** Function         BTM_GetDeviceEncRoot
    233 **
    234 ** Description      This function is called to read the local device encryption
    235 **                  root.
    236 **
    237 ** Returns          void
    238 **                  the local device ER is copied into ble_encr_key_value
    239 **
    240 *******************************************************************************/
    241 void BTM_GetDeviceEncRoot (BT_OCTET16 ble_encr_key_value)
    242 {
    243     BTM_TRACE_DEBUG ("%s", __func__);
    244     memcpy (ble_encr_key_value, btm_cb.devcb.ble_encryption_key_value, BT_OCTET16_LEN);
    245 }
    246 
    247 /*******************************************************************************
    248 **
    249 ** Function         BTM_GetDeviceIDRoot
    250 **
    251 ** Description      This function is called to read the local device identity
    252 **                  root.
    253 **
    254 ** Returns          void
    255 **                  the local device IR is copied into irk
    256 **
    257 *******************************************************************************/
    258 void BTM_GetDeviceIDRoot (BT_OCTET16 irk)
    259 {
    260     BTM_TRACE_DEBUG ("BTM_GetDeviceIDRoot ");
    261 
    262     memcpy (irk, btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN);
    263 }
    264 
    265 /*******************************************************************************
    266 **
    267 ** Function         BTM_GetDeviceDHK
    268 **
    269 ** Description      This function is called to read the local device DHK.
    270 **
    271 ** Returns          void
    272 **                  the local device DHK is copied into dhk
    273 **
    274 *******************************************************************************/
    275 void BTM_GetDeviceDHK (BT_OCTET16 dhk)
    276 {
    277     BTM_TRACE_DEBUG ("BTM_GetDeviceDHK");
    278     memcpy (dhk, btm_cb.devcb.id_keys.dhk, BT_OCTET16_LEN);
    279 }
    280 
    281 /*******************************************************************************
    282 **
    283 ** Function         BTM_ReadConnectionAddr
    284 **
    285 ** Description      This function is called to get the local device address information
    286 **                  .
    287 **
    288 ** Returns          void
    289 **
    290 *******************************************************************************/
    291 void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, tBLE_ADDR_TYPE *p_addr_type)
    292 {
    293     tACL_CONN       *p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE);
    294 
    295     if (p_acl == NULL)
    296     {
    297         BTM_TRACE_ERROR("No connection exist!");
    298         return;
    299     }
    300     memcpy(local_conn_addr, p_acl->conn_addr, BD_ADDR_LEN);
    301     * p_addr_type = p_acl->conn_addr_type;
    302 
    303     BTM_TRACE_DEBUG ("BTM_ReadConnectionAddr address type: %d addr: 0x%02x",
    304                     p_acl->conn_addr_type, p_acl->conn_addr[0]);
    305 }
    306 
    307 /*******************************************************************************
    308 **
    309 ** Function         BTM_IsBleConnection
    310 **
    311 ** Description      This function is called to check if the connection handle
    312 **                  for an LE link
    313 **
    314 ** Returns          TRUE if connection is LE link, otherwise FALSE.
    315 **
    316 *******************************************************************************/
    317 BOOLEAN BTM_IsBleConnection (UINT16 conn_handle)
    318 {
    319 #if (BLE_INCLUDED == TRUE)
    320     UINT8                xx;
    321     tACL_CONN            *p;
    322 
    323     BTM_TRACE_API ("BTM_IsBleConnection: conn_handle: %d", conn_handle);
    324 
    325     xx = btm_handle_to_acl_index (conn_handle);
    326     if (xx >= MAX_L2CAP_LINKS)
    327         return FALSE;
    328 
    329     p = &btm_cb.acl_db[xx];
    330 
    331     return (p->transport == BT_TRANSPORT_LE);
    332 #else
    333     return FALSE;
    334 #endif
    335 }
    336 
    337 /*******************************************************************************
    338 **
    339 ** Function         BTM_ReadRemoteConnectionAddr
    340 **
    341 ** Description      This function is read the remote device address currently used
    342 **
    343 ** Parameters     pseudo_addr: pseudo random address available
    344 **                conn_addr:connection address used
    345 **                p_addr_type : BD Address type, Public or Random of the address used
    346 **
    347 ** Returns          BOOLEAN , TRUE if connection to remote device exists, else FALSE
    348 **
    349 *******************************************************************************/
    350 BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr,
    351                                                tBLE_ADDR_TYPE *p_addr_type)
    352 {
    353  BOOLEAN         st = TRUE;
    354 #if (BLE_PRIVACY_SPT == TRUE)
    355     tACL_CONN       *p = btm_bda_to_acl (pseudo_addr, BT_TRANSPORT_LE);
    356 
    357     if (p == NULL)
    358     {
    359         BTM_TRACE_ERROR("BTM_ReadRemoteConnectionAddr can not find connection"
    360                         " with matching address");
    361         return FALSE;
    362     }
    363 
    364     memcpy(conn_addr, p->active_remote_addr, BD_ADDR_LEN);
    365     *p_addr_type = p->active_remote_addr_type;
    366 #else
    367     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr);
    368 
    369     memcpy(conn_addr, pseudo_addr, BD_ADDR_LEN);
    370     if (p_dev_rec != NULL)
    371     {
    372         *p_addr_type = p_dev_rec->ble.ble_addr_type;
    373     }
    374 #endif
    375     return st;
    376 
    377 }
    378 /*******************************************************************************
    379 **
    380 ** Function         BTM_SecurityGrant
    381 **
    382 ** Description      This function is called to grant security process.
    383 **
    384 ** Parameters       bd_addr - peer device bd address.
    385 **                  res     - result of the operation BTM_SUCCESS if success.
    386 **                            Otherwise, BTM_REPEATED_ATTEMPTS is too many attempts.
    387 **
    388 ** Returns          None
    389 **
    390 *******************************************************************************/
    391 void BTM_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
    392 {
    393 #if SMP_INCLUDED == TRUE
    394     tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_REPEATED_ATTEMPTS;
    395     BTM_TRACE_DEBUG ("BTM_SecurityGrant");
    396     SMP_SecurityGrant(bd_addr, res_smp);
    397 #endif
    398 }
    399 
    400 /*******************************************************************************
    401 **
    402 ** Function         BTM_BlePasskeyReply
    403 **
    404 ** Description      This function is called after Security Manager submitted
    405 **                  passkey request to the application.
    406 **
    407 ** Parameters:      bd_addr      - Address of the device for which passkey was requested
    408 **                  res          - result of the operation BTM_SUCCESS if success
    409 **                  key_len      - length in bytes of the Passkey
    410 **                  p_passkey        - pointer to array with the passkey
    411 **                  trusted_mask - bitwise OR of trusted services (array of UINT32)
    412 **
    413 *******************************************************************************/
    414 void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
    415 {
    416 #if SMP_INCLUDED == TRUE
    417     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
    418     tSMP_STATUS      res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_PASSKEY_ENTRY_FAIL;
    419 
    420     if (p_dev_rec == NULL)
    421     {
    422         BTM_TRACE_ERROR("Passkey reply to Unknown device");
    423         return;
    424     }
    425 
    426     p_dev_rec->sec_flags   |= BTM_SEC_LE_AUTHENTICATED;
    427     BTM_TRACE_DEBUG ("BTM_BlePasskeyReply");
    428     SMP_PasskeyReply(bd_addr, res_smp, passkey);
    429 #endif
    430 }
    431 
    432 /*******************************************************************************
    433 **
    434 ** Function         BTM_BleConfirmReply
    435 **
    436 ** Description      This function is called after Security Manager submitted
    437 **                  numeric comparison request to the application.
    438 **
    439 ** Parameters:      bd_addr      - Address of the device with which numeric
    440 **                                 comparison was requested
    441 **                  res          - comparison result BTM_SUCCESS if success
    442 **
    443 *******************************************************************************/
    444 void BTM_BleConfirmReply (BD_ADDR bd_addr, UINT8 res)
    445 {
    446     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
    447     tSMP_STATUS      res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_PASSKEY_ENTRY_FAIL;
    448 
    449     if (p_dev_rec == NULL)
    450     {
    451         BTM_TRACE_ERROR("Passkey reply to Unknown device");
    452         return;
    453     }
    454 
    455     p_dev_rec->sec_flags   |= BTM_SEC_LE_AUTHENTICATED;
    456     BTM_TRACE_DEBUG ("%s", __func__);
    457     SMP_ConfirmReply(bd_addr, res_smp);
    458 }
    459 
    460 /*******************************************************************************
    461 **
    462 ** Function         BTM_BleOobDataReply
    463 **
    464 ** Description      This function is called to provide the OOB data for
    465 **                  SMP in response to BTM_LE_OOB_REQ_EVT
    466 **
    467 ** Parameters:      bd_addr     - Address of the peer device
    468 **                  res         - result of the operation SMP_SUCCESS if success
    469 **                  p_data      - simple pairing Randomizer  C.
    470 **
    471 *******************************************************************************/
    472 void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data)
    473 {
    474 #if SMP_INCLUDED == TRUE
    475     tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_OOB_FAIL;
    476     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
    477 
    478     BTM_TRACE_DEBUG ("BTM_BleOobDataReply");
    479 
    480     if (p_dev_rec == NULL)
    481     {
    482         BTM_TRACE_ERROR("BTM_BleOobDataReply() to Unknown device");
    483         return;
    484     }
    485 
    486     p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED;
    487     SMP_OobDataReply(bd_addr, res_smp, len, p_data);
    488 #endif
    489 }
    490 
    491 /******************************************************************************
    492 **
    493 ** Function         BTM_BleSetConnScanParams
    494 **
    495 ** Description      Set scan parameter used in BLE connection request
    496 **
    497 ** Parameters:      scan_interval: scan interval
    498 **                  scan_window: scan window
    499 **
    500 ** Returns          void
    501 **
    502 *******************************************************************************/
    503 void BTM_BleSetConnScanParams (UINT32 scan_interval, UINT32 scan_window)
    504 {
    505 #if SMP_INCLUDED == TRUE
    506     tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
    507     BOOLEAN     new_param = FALSE;
    508 
    509     if (BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) &&
    510         BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX))
    511     {
    512         if (p_ble_cb->scan_int != scan_interval)
    513         {
    514             p_ble_cb->scan_int = scan_interval;
    515             new_param = TRUE;
    516         }
    517 
    518         if (p_ble_cb->scan_win != scan_window)
    519         {
    520             p_ble_cb->scan_win = scan_window;
    521             new_param = TRUE;
    522         }
    523 
    524         if (new_param && p_ble_cb->conn_state == BLE_BG_CONN)
    525         {
    526             btm_ble_suspend_bg_conn();
    527         }
    528     }
    529     else
    530     {
    531         BTM_TRACE_ERROR("Illegal Connection Scan Parameters");
    532     }
    533 #endif
    534 }
    535 
    536 /********************************************************
    537 **
    538 ** Function         BTM_BleSetPrefConnParams
    539 **
    540 ** Description      Set a peripheral's preferred connection parameters
    541 **
    542 ** Parameters:      bd_addr          - BD address of the peripheral
    543 **                  scan_interval: scan interval
    544 **                  scan_window: scan window
    545 **                  min_conn_int     - minimum preferred connection interval
    546 **                  max_conn_int     - maximum preferred connection interval
    547 **                  slave_latency    - preferred slave latency
    548 **                  supervision_tout - preferred supervision timeout
    549 **
    550 ** Returns          void
    551 **
    552 *******************************************************************************/
    553 void BTM_BleSetPrefConnParams (BD_ADDR bd_addr,
    554                                UINT16 min_conn_int, UINT16 max_conn_int,
    555                                UINT16 slave_latency, UINT16 supervision_tout)
    556 {
    557     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
    558 
    559     BTM_TRACE_API ("BTM_BleSetPrefConnParams min: %u  max: %u  latency: %u  \
    560                     tout: %u",
    561                     min_conn_int, max_conn_int, slave_latency, supervision_tout);
    562 
    563     if (BTM_BLE_ISVALID_PARAM(min_conn_int, BTM_BLE_CONN_INT_MIN, BTM_BLE_CONN_INT_MAX) &&
    564         BTM_BLE_ISVALID_PARAM(max_conn_int, BTM_BLE_CONN_INT_MIN, BTM_BLE_CONN_INT_MAX) &&
    565         BTM_BLE_ISVALID_PARAM(supervision_tout, BTM_BLE_CONN_SUP_TOUT_MIN, BTM_BLE_CONN_SUP_TOUT_MAX) &&
    566         (slave_latency <= BTM_BLE_CONN_LATENCY_MAX || slave_latency == BTM_BLE_CONN_PARAM_UNDEF))
    567     {
    568         if (p_dev_rec)
    569         {
    570             /* expect conn int and stout and slave latency to be updated all together */
    571             if (min_conn_int != BTM_BLE_CONN_PARAM_UNDEF || max_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
    572             {
    573                 if (min_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
    574                     p_dev_rec->conn_params.min_conn_int = min_conn_int;
    575                 else
    576                     p_dev_rec->conn_params.min_conn_int = max_conn_int;
    577 
    578                 if (max_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
    579                     p_dev_rec->conn_params.max_conn_int = max_conn_int;
    580                 else
    581                     p_dev_rec->conn_params.max_conn_int = min_conn_int;
    582 
    583                 if (slave_latency != BTM_BLE_CONN_PARAM_UNDEF)
    584                     p_dev_rec->conn_params.slave_latency = slave_latency;
    585                 else
    586                     p_dev_rec->conn_params.slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF;
    587 
    588                 if (supervision_tout != BTM_BLE_CONN_PARAM_UNDEF)
    589                     p_dev_rec->conn_params.supervision_tout = supervision_tout;
    590                 else
    591                     p_dev_rec->conn_params.supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF;
    592 
    593             }
    594 
    595         }
    596         else
    597         {
    598             BTM_TRACE_ERROR("Unknown Device, setting rejected");
    599         }
    600     }
    601     else
    602     {
    603         BTM_TRACE_ERROR("Illegal Connection Parameters");
    604     }
    605 }
    606 
    607 /*******************************************************************************
    608 **
    609 ** Function         BTM_ReadDevInfo
    610 **
    611 ** Description      This function is called to read the device/address type
    612 **                  of BD address.
    613 **
    614 ** Parameter        remote_bda: remote device address
    615 **                  p_dev_type: output parameter to read the device type.
    616 **                  p_addr_type: output parameter to read the address type.
    617 **
    618 *******************************************************************************/
    619 void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR_TYPE *p_addr_type)
    620 {
    621     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (remote_bda);
    622     tBTM_INQ_INFO     *p_inq_info = BTM_InqDbRead(remote_bda);
    623 
    624     *p_addr_type = BLE_ADDR_PUBLIC;
    625 
    626     if (!p_dev_rec)
    627     {
    628         *p_dev_type = BT_DEVICE_TYPE_BREDR;
    629         /* Check with the BT manager if details about remote device are known */
    630         if (p_inq_info != NULL)
    631         {
    632             *p_dev_type = p_inq_info->results.device_type ;
    633             *p_addr_type = p_inq_info->results.ble_addr_type;
    634         } else {
    635             /* unknown device, assume BR/EDR */
    636             BTM_TRACE_DEBUG ("btm_find_dev_type - unknown device, BR/EDR assumed");
    637         }
    638     }
    639     else /* there is a security device record exisitng */
    640     {
    641         /* new inquiry result, overwrite device type in security device record */
    642         if (p_inq_info)
    643         {
    644             p_dev_rec->device_type          = p_inq_info->results.device_type;
    645             p_dev_rec->ble.ble_addr_type    = p_inq_info->results.ble_addr_type;
    646         }
    647         if (memcmp(p_dev_rec->bd_addr, remote_bda, BD_ADDR_LEN) == 0 &&
    648             memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0)
    649         {
    650             *p_dev_type = p_dev_rec->device_type;
    651             *p_addr_type = p_dev_rec->ble.ble_addr_type;
    652         }
    653         else if (memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0)
    654         {
    655             *p_dev_type = BT_DEVICE_TYPE_BLE;
    656             *p_addr_type = p_dev_rec->ble.ble_addr_type;
    657         }
    658         else  /* matching static adddress only */
    659         {
    660             *p_dev_type = BT_DEVICE_TYPE_BREDR;
    661             *p_addr_type = BLE_ADDR_PUBLIC;
    662         }
    663 
    664     }
    665 
    666     BTM_TRACE_DEBUG ("btm_find_dev_type - device_type = %d addr_type = %d", *p_dev_type , *p_addr_type);
    667 }
    668 
    669 
    670 /*******************************************************************************
    671 **
    672 ** Function         BTM_ReadConnectedTransportAddress
    673 **
    674 ** Description      This function is called to read the paired device/address type of other device paired
    675 **                  corresponding to the BD_address
    676 **
    677 ** Parameter        remote_bda: remote device address, carry out the transport address
    678 **                  transport: active transport
    679 **
    680 ** Return           TRUE if an active link is identified; FALSE otherwise
    681 **
    682 *******************************************************************************/
    683 BOOLEAN BTM_ReadConnectedTransportAddress(BD_ADDR remote_bda, tBT_TRANSPORT transport)
    684 {
    685     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(remote_bda);
    686     tACL_CONN *p = btm_bda_to_acl(remote_bda, transport);
    687 
    688     /* if no device can be located, return */
    689     if (p_dev_rec == NULL)
    690         return FALSE;
    691 
    692     if (transport == BT_TRANSPORT_BR_EDR)
    693     {
    694         if (btm_bda_to_acl(p_dev_rec->bd_addr, transport) != NULL)
    695         {
    696             memcpy(remote_bda, p_dev_rec->bd_addr, BD_ADDR_LEN);
    697             return TRUE;
    698         }
    699         else if (p_dev_rec->device_type & BT_DEVICE_TYPE_BREDR)
    700         {
    701             memcpy(remote_bda, p_dev_rec->bd_addr, BD_ADDR_LEN);
    702         }
    703         else
    704             memset(remote_bda, 0, BD_ADDR_LEN);
    705         return FALSE;
    706     }
    707 
    708     if (transport == BT_TRANSPORT_LE)
    709     {
    710         memcpy(remote_bda, p_dev_rec->ble.pseudo_addr, BD_ADDR_LEN);
    711         if (btm_bda_to_acl(p_dev_rec->ble.pseudo_addr, transport) != NULL)
    712             return TRUE;
    713         else
    714             return FALSE;
    715     }
    716 
    717     return FALSE;
    718 }
    719 
    720 /*******************************************************************************
    721 **
    722 ** Function         BTM_BleReceiverTest
    723 **
    724 ** Description      This function is called to start the LE Receiver test
    725 **
    726 ** Parameter       rx_freq - Frequency Range
    727 **               p_cmd_cmpl_cback - Command Complete callback
    728 **
    729 *******************************************************************************/
    730 void BTM_BleReceiverTest(UINT8 rx_freq, tBTM_CMPL_CB *p_cmd_cmpl_cback)
    731 {
    732      btm_cb.devcb.p_le_test_cmd_cmpl_cb = p_cmd_cmpl_cback;
    733 
    734      if (btsnd_hcic_ble_receiver_test(rx_freq) == FALSE)
    735      {
    736           BTM_TRACE_ERROR("%s: Unable to Trigger LE receiver test", __FUNCTION__);
    737      }
    738 }
    739 
    740 /*******************************************************************************
    741 **
    742 ** Function         BTM_BleTransmitterTest
    743 **
    744 ** Description      This function is called to start the LE Transmitter test
    745 **
    746 ** Parameter       tx_freq - Frequency Range
    747 **                       test_data_len - Length in bytes of payload data in each packet
    748 **                       packet_payload - Pattern to use in the payload
    749 **                       p_cmd_cmpl_cback - Command Complete callback
    750 **
    751 *******************************************************************************/
    752 void BTM_BleTransmitterTest(UINT8 tx_freq, UINT8 test_data_len,
    753                                  UINT8 packet_payload, tBTM_CMPL_CB *p_cmd_cmpl_cback)
    754 {
    755      btm_cb.devcb.p_le_test_cmd_cmpl_cb = p_cmd_cmpl_cback;
    756      if (btsnd_hcic_ble_transmitter_test(tx_freq, test_data_len, packet_payload) == FALSE)
    757      {
    758           BTM_TRACE_ERROR("%s: Unable to Trigger LE transmitter test", __FUNCTION__);
    759      }
    760 }
    761 
    762 /*******************************************************************************
    763 **
    764 ** Function         BTM_BleTestEnd
    765 **
    766 ** Description      This function is called to stop the in-progress TX or RX test
    767 **
    768 ** Parameter       p_cmd_cmpl_cback - Command complete callback
    769 **
    770 *******************************************************************************/
    771 void BTM_BleTestEnd(tBTM_CMPL_CB *p_cmd_cmpl_cback)
    772 {
    773      btm_cb.devcb.p_le_test_cmd_cmpl_cb = p_cmd_cmpl_cback;
    774 
    775      if (btsnd_hcic_ble_test_end() == FALSE)
    776      {
    777           BTM_TRACE_ERROR("%s: Unable to End the LE TX/RX test", __FUNCTION__);
    778      }
    779 }
    780 
    781 /*******************************************************************************
    782 ** Internal Functions
    783 *******************************************************************************/
    784 void btm_ble_test_command_complete(UINT8 *p)
    785 {
    786     tBTM_CMPL_CB   *p_cb = btm_cb.devcb.p_le_test_cmd_cmpl_cb;
    787 
    788     btm_cb.devcb.p_le_test_cmd_cmpl_cb = NULL;
    789 
    790     if (p_cb)
    791     {
    792         (*p_cb)(p);
    793     }
    794 }
    795 
    796 /*******************************************************************************
    797 **
    798 ** Function         BTM_UseLeLink
    799 **
    800 ** Description      This function is to select the underneath physical link to use.
    801 **
    802 ** Returns          TRUE to use LE, FALSE use BR/EDR.
    803 **
    804 *******************************************************************************/
    805 BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr)
    806 {
    807     tACL_CONN         *p;
    808     tBT_DEVICE_TYPE     dev_type;
    809     tBLE_ADDR_TYPE      addr_type;
    810     BOOLEAN             use_le = FALSE;
    811 
    812     if ((p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR)) != NULL)
    813     {
    814         return use_le;
    815     }
    816     else if ((p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE)) != NULL)
    817     {
    818         use_le = TRUE;
    819     }
    820     else
    821     {
    822         BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
    823         use_le = (dev_type == BT_DEVICE_TYPE_BLE);
    824     }
    825     return use_le;
    826 }
    827 
    828 
    829 /*******************************************************************************
    830 **
    831 ** Function         BTM_SetBleDataLength
    832 **
    833 ** Description      This function is to set maximum BLE transmission packet size
    834 **
    835 ** Returns          BTM_SUCCESS if success; otherwise failed.
    836 **
    837 *******************************************************************************/
    838 tBTM_STATUS BTM_SetBleDataLength(BD_ADDR bd_addr, UINT16 tx_pdu_length)
    839 {
    840     tACL_CONN *p_acl = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE);
    841     BTM_TRACE_DEBUG("%s: tx_pdu_length =%d", __FUNCTION__, tx_pdu_length);
    842 
    843     if (!controller_get_interface()->supports_ble_packet_extension())
    844     {
    845         BTM_TRACE_ERROR("%s failed, request not supported", __FUNCTION__);
    846         return BTM_ILLEGAL_VALUE;
    847     }
    848 
    849     if (!HCI_LE_DATA_LEN_EXT_SUPPORTED(p_acl->peer_le_features))
    850     {
    851         BTM_TRACE_ERROR("%s failed, peer does not support request", __FUNCTION__);
    852         return BTM_ILLEGAL_VALUE;
    853     }
    854 
    855     if (p_acl != NULL)
    856     {
    857         if (tx_pdu_length > BTM_BLE_DATA_SIZE_MAX)
    858             tx_pdu_length =  BTM_BLE_DATA_SIZE_MAX;
    859         else if (tx_pdu_length < BTM_BLE_DATA_SIZE_MIN)
    860             tx_pdu_length =  BTM_BLE_DATA_SIZE_MIN;
    861 
    862         /* always set the TxTime to be max, as controller does not care for now */
    863         btsnd_hcic_ble_set_data_length(p_acl->hci_handle, tx_pdu_length,
    864                                             BTM_BLE_DATA_TX_TIME_MAX);
    865 
    866         return BTM_SUCCESS;
    867     }
    868     else
    869     {
    870         BTM_TRACE_ERROR("%s: Wrong mode: no LE link exist or LE not supported",__FUNCTION__);
    871         return BTM_WRONG_MODE;
    872     }
    873 }
    874 
    875 /*******************************************************************************
    876 **
    877 ** Function         btm_ble_rand_enc_complete
    878 **
    879 ** Description      This function is the callback functions for HCI_Rand command
    880 **                  and HCI_Encrypt command is completed.
    881 **                  This message is received from the HCI.
    882 **
    883 ** Returns          void
    884 **
    885 *******************************************************************************/
    886 void btm_ble_rand_enc_complete (UINT8 *p, UINT16 op_code, tBTM_RAND_ENC_CB *p_enc_cplt_cback)
    887 {
    888     tBTM_RAND_ENC   params;
    889     UINT8           *p_dest = params.param_buf;
    890 
    891     BTM_TRACE_DEBUG ("btm_ble_rand_enc_complete");
    892 
    893     memset(&params, 0, sizeof(tBTM_RAND_ENC));
    894 
    895     /* If there was a callback address for vcs complete, call it */
    896     if (p_enc_cplt_cback && p)
    897     {
    898         /* Pass paramters to the callback function */
    899         STREAM_TO_UINT8(params.status, p); /* command status */
    900 
    901         if (params.status == HCI_SUCCESS)
    902         {
    903             params.opcode = op_code;
    904 
    905             if (op_code == HCI_BLE_RAND)
    906                 params.param_len = BT_OCTET8_LEN;
    907             else
    908                 params.param_len = BT_OCTET16_LEN;
    909 
    910             memcpy(p_dest, p, params.param_len);  /* Fetch return info from HCI event message */
    911         }
    912         if (p_enc_cplt_cback)
    913             (*p_enc_cplt_cback)(&params);  /* Call the Encryption complete callback function */
    914     }
    915 }
    916 
    917 
    918     #if (SMP_INCLUDED == TRUE)
    919 
    920 /*******************************************************************************
    921 **
    922 ** Function         btm_ble_get_enc_key_type
    923 **
    924 ** Description      This function is to increment local sign counter
    925 ** Returns         None
    926 **
    927 *******************************************************************************/
    928 void btm_ble_increment_sign_ctr(BD_ADDR bd_addr, BOOLEAN is_local )
    929 {
    930     tBTM_SEC_DEV_REC *p_dev_rec;
    931 
    932     BTM_TRACE_DEBUG ("btm_ble_increment_sign_ctr is_local=%d", is_local);
    933 
    934     if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
    935     {
    936         if (is_local)
    937             p_dev_rec->ble.keys.local_counter++;
    938         else
    939             p_dev_rec->ble.keys.counter++;
    940         BTM_TRACE_DEBUG ("is_local=%d local sign counter=%d peer sign counter=%d",
    941                           is_local,
    942                           p_dev_rec->ble.keys.local_counter,
    943                           p_dev_rec->ble.keys.counter);
    944     }
    945 }
    946 
    947 /*******************************************************************************
    948 **
    949 ** Function         btm_ble_get_enc_key_type
    950 **
    951 ** Description      This function is to get the BLE key type that has been exchanged
    952 **                  in betweem local device and peer device.
    953 **
    954 ** Returns          p_key_type: output parameter to carry the key type value.
    955 **
    956 *******************************************************************************/
    957 BOOLEAN btm_ble_get_enc_key_type(BD_ADDR bd_addr, UINT8 *p_key_types)
    958 {
    959     tBTM_SEC_DEV_REC *p_dev_rec;
    960 
    961     BTM_TRACE_DEBUG ("btm_ble_get_enc_key_type");
    962 
    963     if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
    964     {
    965         *p_key_types = p_dev_rec->ble.key_type;
    966         return TRUE;
    967     }
    968     return FALSE;
    969 }
    970 
    971 /*******************************************************************************
    972 **
    973 ** Function         btm_get_local_div
    974 **
    975 ** Description      This function is called to read the local DIV
    976 **
    977 ** Returns          TURE - if a valid DIV is availavle
    978 *******************************************************************************/
    979 BOOLEAN btm_get_local_div (BD_ADDR bd_addr, UINT16 *p_div)
    980 {
    981     tBTM_SEC_DEV_REC   *p_dev_rec;
    982     BOOLEAN            status = FALSE;
    983     BTM_TRACE_DEBUG ("btm_get_local_div");
    984 
    985     BTM_TRACE_DEBUG("bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
    986                      bd_addr[0],bd_addr[1],
    987                      bd_addr[2],bd_addr[3],
    988                      bd_addr[4],bd_addr[5]);
    989 
    990     *p_div = 0;
    991     p_dev_rec = btm_find_dev (bd_addr);
    992 
    993     if (p_dev_rec && p_dev_rec->ble.keys.div)
    994     {
    995         status = TRUE;
    996         *p_div = p_dev_rec->ble.keys.div;
    997     }
    998     BTM_TRACE_DEBUG ("btm_get_local_div status=%d (1-OK) DIV=0x%x", status, *p_div);
    999     return status;
   1000 }
   1001 
   1002 /*******************************************************************************
   1003 **
   1004 ** Function         btm_sec_save_le_key
   1005 **
   1006 ** Description      This function is called by the SMP to update
   1007 **                  an  BLE key.  SMP is internal, whereas all the keys shall
   1008 **                  be sent to the application.  The function is also called
   1009 **                  when application passes ble key stored in NVRAM to the btm_sec.
   1010 **                  pass_to_application parameter is false in this case.
   1011 **
   1012 ** Returns          void
   1013 **
   1014 *******************************************************************************/
   1015 void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type, tBTM_LE_KEY_VALUE *p_keys,
   1016                          BOOLEAN pass_to_application)
   1017 {
   1018     tBTM_SEC_DEV_REC *p_rec;
   1019     tBTM_LE_EVT_DATA    cb_data;
   1020     UINT8 i;
   1021 
   1022     BTM_TRACE_DEBUG ("btm_sec_save_le_key key_type=0x%x pass_to_application=%d",key_type, pass_to_application);
   1023     /* Store the updated key in the device database */
   1024 
   1025     BTM_TRACE_DEBUG("bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
   1026                      bd_addr[0],bd_addr[1],
   1027                      bd_addr[2],bd_addr[3],
   1028                      bd_addr[4],bd_addr[5]);
   1029 
   1030     if ((p_rec = btm_find_dev (bd_addr)) != NULL && (p_keys || key_type== BTM_LE_KEY_LID))
   1031     {
   1032         btm_ble_init_pseudo_addr (p_rec, bd_addr);
   1033 
   1034         switch (key_type)
   1035         {
   1036             case BTM_LE_KEY_PENC:
   1037                 memcpy(p_rec->ble.keys.pltk, p_keys->penc_key.ltk, BT_OCTET16_LEN);
   1038                 memcpy(p_rec->ble.keys.rand, p_keys->penc_key.rand, BT_OCTET8_LEN);
   1039                 p_rec->ble.keys.sec_level = p_keys->penc_key.sec_level;
   1040                 p_rec->ble.keys.ediv = p_keys->penc_key.ediv;
   1041                 p_rec->ble.keys.key_size = p_keys->penc_key.key_size;
   1042                 p_rec->ble.key_type |= BTM_LE_KEY_PENC;
   1043                 p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_KNOWN;
   1044                 if (p_keys->penc_key.sec_level == SMP_SEC_AUTHENTICATED)
   1045                     p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
   1046                 else
   1047                     p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED;
   1048                 BTM_TRACE_DEBUG("BTM_LE_KEY_PENC key_type=0x%x sec_flags=0x%x sec_leve=0x%x",
   1049                                  p_rec->ble.key_type,
   1050                                  p_rec->sec_flags,
   1051                                  p_rec->ble.keys.sec_level);
   1052                 break;
   1053 
   1054             case BTM_LE_KEY_PID:
   1055                 for (i=0; i<BT_OCTET16_LEN; i++)
   1056                 {
   1057                     p_rec->ble.keys.irk[i] = p_keys->pid_key.irk[i];
   1058                 }
   1059 
   1060                  //memcpy( p_rec->ble.keys.irk, p_keys->pid_key, BT_OCTET16_LEN); todo will crash the system
   1061                 memcpy(p_rec->ble.static_addr, p_keys->pid_key.static_addr, BD_ADDR_LEN);
   1062                 p_rec->ble.static_addr_type = p_keys->pid_key.addr_type;
   1063                 p_rec->ble.key_type |= BTM_LE_KEY_PID;
   1064                 BTM_TRACE_DEBUG("BTM_LE_KEY_PID key_type=0x%x save peer IRK",  p_rec->ble.key_type);
   1065                  /* update device record address as static address */
   1066                 memcpy(p_rec->bd_addr, p_keys->pid_key.static_addr, BD_ADDR_LEN);
   1067                 /* combine DUMO device security record if needed */
   1068                 btm_consolidate_dev(p_rec);
   1069                 break;
   1070 
   1071             case BTM_LE_KEY_PCSRK:
   1072                 memcpy(p_rec->ble.keys.pcsrk, p_keys->pcsrk_key.csrk, BT_OCTET16_LEN);
   1073                 p_rec->ble.keys.srk_sec_level = p_keys->pcsrk_key.sec_level;
   1074                 p_rec->ble.keys.counter  = p_keys->pcsrk_key.counter;
   1075                 p_rec->ble.key_type |= BTM_LE_KEY_PCSRK;
   1076                 p_rec->sec_flags |=  BTM_SEC_LE_LINK_KEY_KNOWN;
   1077                 if ( p_keys->pcsrk_key.sec_level== SMP_SEC_AUTHENTICATED)
   1078                     p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
   1079                 else
   1080                     p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED;
   1081 
   1082                 BTM_TRACE_DEBUG("BTM_LE_KEY_PCSRK key_type=0x%x sec_flags=0x%x sec_level=0x%x peer_counter=%d",
   1083                                  p_rec->ble.key_type,
   1084                                  p_rec->sec_flags,
   1085                                  p_rec->ble.keys.srk_sec_level,
   1086                                  p_rec->ble.keys.counter );
   1087                 break;
   1088 
   1089             case BTM_LE_KEY_LENC:
   1090                 memcpy(p_rec->ble.keys.lltk, p_keys->lenc_key.ltk, BT_OCTET16_LEN);
   1091                 p_rec->ble.keys.div = p_keys->lenc_key.div; /* update DIV */
   1092                 p_rec->ble.keys.sec_level = p_keys->lenc_key.sec_level;
   1093                 p_rec->ble.keys.key_size = p_keys->lenc_key.key_size;
   1094                 p_rec->ble.key_type |= BTM_LE_KEY_LENC;
   1095 
   1096                 BTM_TRACE_DEBUG("BTM_LE_KEY_LENC key_type=0x%x DIV=0x%x key_size=0x%x sec_level=0x%x",
   1097                                  p_rec->ble.key_type,
   1098                                  p_rec->ble.keys.div,
   1099                                  p_rec->ble.keys.key_size,
   1100                                  p_rec->ble.keys.sec_level );
   1101                 break;
   1102 
   1103             case BTM_LE_KEY_LCSRK:/* local CSRK has been delivered */
   1104                 memcpy (p_rec->ble.keys.lcsrk, p_keys->lcsrk_key.csrk, BT_OCTET16_LEN);
   1105                 p_rec->ble.keys.div = p_keys->lcsrk_key.div; /* update DIV */
   1106                 p_rec->ble.keys.local_csrk_sec_level = p_keys->lcsrk_key.sec_level;
   1107                 p_rec->ble.keys.local_counter  = p_keys->lcsrk_key.counter;
   1108                 p_rec->ble.key_type |= BTM_LE_KEY_LCSRK;
   1109                 BTM_TRACE_DEBUG("BTM_LE_KEY_LCSRK key_type=0x%x DIV=0x%x scrk_sec_level=0x%x local_counter=%d",
   1110                                  p_rec->ble.key_type,
   1111                                  p_rec->ble.keys.div,
   1112                                  p_rec->ble.keys.local_csrk_sec_level,
   1113                                  p_rec->ble.keys.local_counter );
   1114                 break;
   1115 
   1116             case BTM_LE_KEY_LID:
   1117                p_rec->ble.key_type |= BTM_LE_KEY_LID;
   1118                break;
   1119             default:
   1120                 BTM_TRACE_WARNING("btm_sec_save_le_key (Bad key_type 0x%02x)", key_type);
   1121                 return;
   1122         }
   1123 
   1124         BTM_TRACE_DEBUG ("BLE key type 0x%02x updated for BDA: %08x%04x (btm_sec_save_le_key)", key_type,
   1125                           (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
   1126                           (bd_addr[4]<<8)+bd_addr[5]);
   1127 
   1128         /* Notify the application that one of the BLE keys has been updated
   1129            If link key is in progress, it will get sent later.*/
   1130         if (pass_to_application && btm_cb.api.p_le_callback)
   1131         {
   1132             cb_data.key.p_key_value = p_keys;
   1133             cb_data.key.key_type = key_type;
   1134 
   1135             (*btm_cb.api.p_le_callback) (BTM_LE_KEY_EVT, bd_addr, &cb_data);
   1136         }
   1137         return;
   1138     }
   1139 
   1140     BTM_TRACE_WARNING ("BLE key type 0x%02x called for Unknown BDA or type: %08x%04x !! (btm_sec_save_le_key)", key_type,
   1141                         (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
   1142                         (bd_addr[4]<<8)+bd_addr[5]);
   1143 
   1144     if (p_rec)
   1145     {
   1146         BTM_TRACE_DEBUG ("sec_flags=0x%x", p_rec->sec_flags);
   1147     }
   1148 }
   1149 
   1150 /*******************************************************************************
   1151 **
   1152 ** Function         btm_ble_update_sec_key_size
   1153 **
   1154 ** Description      update the current lin kencryption key size
   1155 **
   1156 ** Returns          void
   1157 **
   1158 *******************************************************************************/
   1159 void btm_ble_update_sec_key_size(BD_ADDR bd_addr, UINT8 enc_key_size)
   1160 {
   1161     tBTM_SEC_DEV_REC *p_rec;
   1162 
   1163     BTM_TRACE_DEBUG("btm_ble_update_sec_key_size enc_key_size = %d", enc_key_size);
   1164 
   1165     if ((p_rec = btm_find_dev (bd_addr)) != NULL )
   1166     {
   1167         p_rec->enc_key_size = enc_key_size;
   1168     }
   1169 }
   1170 
   1171 /*******************************************************************************
   1172 **
   1173 ** Function         btm_ble_read_sec_key_size
   1174 **
   1175 ** Description      update the current lin kencryption key size
   1176 **
   1177 ** Returns          void
   1178 **
   1179 *******************************************************************************/
   1180 UINT8 btm_ble_read_sec_key_size(BD_ADDR bd_addr)
   1181 {
   1182     tBTM_SEC_DEV_REC *p_rec;
   1183 
   1184     if ((p_rec = btm_find_dev (bd_addr)) != NULL )
   1185     {
   1186         return p_rec->enc_key_size;
   1187     }
   1188     else
   1189         return 0;
   1190 }
   1191 
   1192 /*******************************************************************************
   1193 **
   1194 ** Function         btm_ble_link_sec_check
   1195 **
   1196 ** Description      Check BLE link security level match.
   1197 **
   1198 ** Returns          TRUE: check is OK and the *p_sec_req_act contain the action
   1199 **
   1200 *******************************************************************************/
   1201 void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE_SEC_REQ_ACT *p_sec_req_act)
   1202 {
   1203     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
   1204     UINT8 req_sec_level = BTM_LE_SEC_NONE, cur_sec_level = BTM_LE_SEC_NONE;
   1205 
   1206     BTM_TRACE_DEBUG ("btm_ble_link_sec_check auth_req =0x%x", auth_req);
   1207 
   1208     if (p_dev_rec == NULL)
   1209     {
   1210         BTM_TRACE_ERROR ("btm_ble_link_sec_check received for unknown device");
   1211         return;
   1212     }
   1213 
   1214     if (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING ||
   1215         p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)
   1216     {
   1217         /* race condition: discard the security request while master is encrypting the link */
   1218         *p_sec_req_act = BTM_BLE_SEC_REQ_ACT_DISCARD;
   1219     }
   1220     else
   1221     {
   1222         req_sec_level = BTM_LE_SEC_UNAUTHENTICATE;
   1223         if (auth_req & BTM_LE_AUTH_REQ_MITM)
   1224         {
   1225             req_sec_level = BTM_LE_SEC_AUTHENTICATED;
   1226         }
   1227 
   1228         BTM_TRACE_DEBUG ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags);
   1229 
   1230         /* currently encrpted  */
   1231         if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED)
   1232         {
   1233             if (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED)
   1234                 cur_sec_level = BTM_LE_SEC_AUTHENTICATED;
   1235             else
   1236                 cur_sec_level = BTM_LE_SEC_UNAUTHENTICATE;
   1237         }
   1238         else /* unencrypted link */
   1239         {
   1240             /* if bonded, get the key security level */
   1241             if (p_dev_rec->ble.key_type & BTM_LE_KEY_PENC)
   1242                 cur_sec_level = p_dev_rec->ble.keys.sec_level;
   1243             else
   1244                 cur_sec_level = BTM_LE_SEC_NONE;
   1245         }
   1246 
   1247         if (cur_sec_level >= req_sec_level)
   1248         {
   1249             /* To avoid re-encryption on an encrypted link for an equal condition encryption */
   1250             *p_sec_req_act = BTM_BLE_SEC_REQ_ACT_ENCRYPT;
   1251         }
   1252         else
   1253         {
   1254             *p_sec_req_act = BTM_BLE_SEC_REQ_ACT_PAIR; /* start the pariring process to upgrade the keys*/
   1255         }
   1256     }
   1257 
   1258     BTM_TRACE_DEBUG("cur_sec_level=%d req_sec_level=%d sec_req_act=%d",
   1259                      cur_sec_level,
   1260                      req_sec_level,
   1261                      *p_sec_req_act);
   1262 
   1263 }
   1264 
   1265 /*******************************************************************************
   1266 **
   1267 ** Function         btm_ble_set_encryption
   1268 **
   1269 ** Description      This function is called to ensure that LE connection is
   1270 **                  encrypted.  Should be called only on an open connection.
   1271 **                  Typically only needed for connections that first want to
   1272 **                  bring up unencrypted links, then later encrypt them.
   1273 **
   1274 ** Returns          void
   1275 **                  the local device ER is copied into er
   1276 **
   1277 *******************************************************************************/
   1278 tBTM_STATUS btm_ble_set_encryption (BD_ADDR bd_addr, void *p_ref_data, UINT8 link_role)
   1279 {
   1280     tBTM_STATUS         cmd = BTM_NO_RESOURCES;
   1281     tBTM_BLE_SEC_ACT    sec_act = *(tBTM_BLE_SEC_ACT *)p_ref_data ;
   1282     tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bd_addr);
   1283     tBTM_BLE_SEC_REQ_ACT sec_req_act;
   1284     tBTM_LE_AUTH_REQ    auth_req;
   1285 
   1286     if (p_rec == NULL)
   1287     {
   1288         BTM_TRACE_WARNING ("btm_ble_set_encryption (NULL device record!! sec_act=0x%x", sec_act);
   1289         return(BTM_WRONG_MODE);
   1290     }
   1291 
   1292     BTM_TRACE_DEBUG ("btm_ble_set_encryption sec_act=0x%x role_master=%d", sec_act, p_rec->role_master);
   1293 
   1294     if (sec_act == BTM_BLE_SEC_ENCRYPT_MITM)
   1295     {
   1296         p_rec->security_required |= BTM_SEC_IN_MITM;
   1297     }
   1298 
   1299     switch (sec_act)
   1300     {
   1301         case BTM_BLE_SEC_ENCRYPT:
   1302             if (link_role == BTM_ROLE_MASTER)
   1303             {
   1304                     /* start link layer encryption using the security info stored */
   1305                 cmd = btm_ble_start_encrypt(bd_addr, FALSE, NULL);
   1306                 break;
   1307             }
   1308             /* if salve role then fall through to call SMP_Pair below which will send a
   1309                sec_request to request the master to encrypt the link */
   1310         case BTM_BLE_SEC_ENCRYPT_NO_MITM:
   1311         case BTM_BLE_SEC_ENCRYPT_MITM:
   1312             if (link_role == BTM_ROLE_MASTER)
   1313             {
   1314                 auth_req = (sec_act == BTM_BLE_SEC_ENCRYPT_NO_MITM)
   1315                            ? SMP_AUTH_GEN_BOND : (SMP_AUTH_GEN_BOND | SMP_AUTH_YN_BIT);
   1316                 btm_ble_link_sec_check (bd_addr, auth_req, &sec_req_act);
   1317 
   1318                 if (sec_req_act == BTM_BLE_SEC_REQ_ACT_ENCRYPT)
   1319                 {
   1320                    cmd = btm_ble_start_encrypt(bd_addr, FALSE, NULL);
   1321                    break;
   1322                 }
   1323             }
   1324 
   1325             if (SMP_Pair(bd_addr) == SMP_STARTED)
   1326             {
   1327                 cmd = BTM_CMD_STARTED;
   1328                 p_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
   1329             }
   1330             break;
   1331 
   1332         default:
   1333             cmd = BTM_WRONG_MODE;
   1334             break;
   1335     }
   1336     return cmd;
   1337 }
   1338 
   1339 /*******************************************************************************
   1340 **
   1341 ** Function         btm_ble_ltk_request
   1342 **
   1343 ** Description      This function is called when encryption request is received
   1344 **                  on a slave device.
   1345 **
   1346 **
   1347 ** Returns          void
   1348 **
   1349 *******************************************************************************/
   1350 void btm_ble_ltk_request(UINT16 handle, UINT8 rand[8], UINT16 ediv)
   1351 {
   1352     tBTM_CB *p_cb = &btm_cb;
   1353     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
   1354     BT_OCTET8 dummy_stk = {0};
   1355 
   1356     BTM_TRACE_DEBUG ("btm_ble_ltk_request");
   1357 
   1358     p_cb->ediv = ediv;
   1359 
   1360     memcpy(p_cb->enc_rand, rand, BT_OCTET8_LEN);
   1361 
   1362     if (p_dev_rec != NULL)
   1363     {
   1364         if (!smp_proc_ltk_request(p_dev_rec->bd_addr))
   1365             btm_ble_ltk_request_reply(p_dev_rec->bd_addr, FALSE, dummy_stk);
   1366     }
   1367 
   1368 }
   1369 
   1370 /*******************************************************************************
   1371 **
   1372 ** Function         btm_ble_start_encrypt
   1373 **
   1374 ** Description      This function is called to start LE encryption.
   1375 **
   1376 **
   1377 ** Returns          BTM_SUCCESS if encryption was started successfully
   1378 **
   1379 *******************************************************************************/
   1380 tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk)
   1381 {
   1382     tBTM_CB *p_cb = &btm_cb;
   1383     tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bda);
   1384     BT_OCTET8    dummy_rand = {0};
   1385     tBTM_STATUS  rt = BTM_NO_RESOURCES;
   1386 
   1387     BTM_TRACE_DEBUG ("btm_ble_start_encrypt");
   1388 
   1389     if (!p_rec )
   1390     {
   1391         BTM_TRACE_ERROR("Link is not active, can not encrypt!");
   1392         return BTM_WRONG_MODE;
   1393     }
   1394 
   1395     if (p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING)
   1396     {
   1397         BTM_TRACE_WARNING("Link Encryption is active, Busy!");
   1398         return BTM_BUSY;
   1399     }
   1400 
   1401     p_cb->enc_handle = p_rec->ble_hci_handle;
   1402 
   1403     if (use_stk)
   1404     {
   1405         if (btsnd_hcic_ble_start_enc(p_rec->ble_hci_handle, dummy_rand, 0, stk))
   1406             rt = BTM_CMD_STARTED;
   1407     }
   1408     else if (p_rec->ble.key_type & BTM_LE_KEY_PENC)
   1409     {
   1410         if (btsnd_hcic_ble_start_enc(p_rec->ble_hci_handle, p_rec->ble.keys.rand,
   1411                                      p_rec->ble.keys.ediv, p_rec->ble.keys.pltk))
   1412             rt = BTM_CMD_STARTED;
   1413     }
   1414     else
   1415     {
   1416         BTM_TRACE_ERROR("No key available to encrypt the link");
   1417     }
   1418     if (rt == BTM_CMD_STARTED)
   1419     {
   1420         if (p_rec->sec_state == BTM_SEC_STATE_IDLE)
   1421             p_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
   1422     }
   1423 
   1424     return rt;
   1425 }
   1426 
   1427 /*******************************************************************************
   1428 **
   1429 ** Function         btm_ble_link_encrypted
   1430 **
   1431 ** Description      This function is called when LE link encrption status is changed.
   1432 **
   1433 ** Returns          void
   1434 **
   1435 *******************************************************************************/
   1436 void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable)
   1437 {
   1438     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_dev (bd_addr);
   1439     BOOLEAN             enc_cback;
   1440 
   1441     if (!p_dev_rec)
   1442     {
   1443         BTM_TRACE_WARNING ("btm_ble_link_encrypted (No Device Found!) encr_enable=%d", encr_enable);
   1444         return;
   1445     }
   1446 
   1447     BTM_TRACE_DEBUG ("btm_ble_link_encrypted encr_enable=%d", encr_enable);
   1448 
   1449     enc_cback = (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING);
   1450 
   1451     smp_link_encrypted(bd_addr, encr_enable);
   1452 
   1453     BTM_TRACE_DEBUG(" p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags);
   1454 
   1455     if (encr_enable && p_dev_rec->enc_key_size == 0)
   1456         p_dev_rec->enc_key_size = p_dev_rec->ble.keys.key_size;
   1457 
   1458     p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
   1459     if (p_dev_rec->p_callback && enc_cback)
   1460     {
   1461         if (encr_enable)
   1462             btm_sec_dev_rec_cback_event(p_dev_rec, BTM_SUCCESS, TRUE);
   1463         else if (p_dev_rec->role_master)
   1464             btm_sec_dev_rec_cback_event(p_dev_rec, BTM_ERR_PROCESSING, TRUE);
   1465 
   1466     }
   1467     /* to notify GATT to send data if any request is pending */
   1468     gatt_notify_enc_cmpl(p_dev_rec->ble.pseudo_addr);
   1469 }
   1470 
   1471 /*******************************************************************************
   1472 ** Function         btm_enc_proc_ltk
   1473 ** Description      send LTK reply when it's ready.
   1474 *******************************************************************************/
   1475 static void btm_enc_proc_ltk(tSMP_ENC *p)
   1476 {
   1477     UINT8   i;
   1478     BTM_TRACE_DEBUG ("btm_enc_proc_ltk");
   1479     if (p && p->param_len == BT_OCTET16_LEN)
   1480     {
   1481         for (i = 0; i < (BT_OCTET16_LEN - btm_cb.key_size); i ++)
   1482             p->param_buf[BT_OCTET16_LEN - i - 1] = 0;
   1483         btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p->param_buf);
   1484     }
   1485 }
   1486 
   1487 /*******************************************************************************
   1488 ** Function         btm_enc_proc_slave_y
   1489 ** Description      calculate LTK when Y is ready
   1490 *******************************************************************************/
   1491 static void btm_enc_proc_slave_y(tSMP_ENC *p)
   1492 {
   1493     UINT16  div, y;
   1494     UINT8   *pp = p->param_buf;
   1495     tBTM_CB *p_cb = &btm_cb;
   1496     tSMP_ENC output;
   1497     tBTM_SEC_DEV_REC *p_dev_rec;
   1498 
   1499     BTM_TRACE_DEBUG ("btm_enc_proc_slave_y");
   1500     if (p != NULL)
   1501     {
   1502         STREAM_TO_UINT16(y, pp);
   1503 
   1504         div = p_cb->ediv ^ y;
   1505         p_dev_rec = btm_find_dev_by_handle (p_cb->enc_handle);
   1506 
   1507         if ( p_dev_rec &&
   1508              p_dev_rec->ble.keys.div == div )
   1509         {
   1510             BTM_TRACE_DEBUG ("LTK request OK");
   1511             /* calculating LTK , LTK = E er(div) */
   1512             SMP_Encrypt(p_cb->devcb.ble_encryption_key_value, BT_OCTET16_LEN, (UINT8 *)&div, 2, &output);
   1513             btm_enc_proc_ltk(&output);
   1514         }
   1515         else
   1516         {
   1517             BTM_TRACE_DEBUG ("LTK request failed - send negative reply");
   1518             btsnd_hcic_ble_ltk_req_neg_reply(p_cb->enc_handle);
   1519             if (p_dev_rec)
   1520                 btm_ble_link_encrypted(p_dev_rec->bd_addr, 0);
   1521 
   1522         }
   1523     }
   1524 }
   1525 
   1526 /*******************************************************************************
   1527 **
   1528 ** Function         btm_ble_ltk_request_reply
   1529 **
   1530 ** Description      This function is called to send a LTK request reply on a slave
   1531 **                  device.
   1532 **
   1533 ** Returns          void
   1534 **
   1535 *******************************************************************************/
   1536 void btm_ble_ltk_request_reply(BD_ADDR bda,  BOOLEAN use_stk, BT_OCTET16 stk)
   1537 {
   1538     tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bda);
   1539     tBTM_CB *p_cb = &btm_cb;
   1540     tSMP_ENC output;
   1541 
   1542     if (p_rec == NULL)
   1543     {
   1544         BTM_TRACE_ERROR("btm_ble_ltk_request_reply received for unknown device");
   1545         return;
   1546     }
   1547 
   1548     BTM_TRACE_DEBUG ("btm_ble_ltk_request_reply");
   1549     p_cb->enc_handle = p_rec->ble_hci_handle;
   1550     p_cb->key_size = p_rec->ble.keys.key_size;
   1551 
   1552     BTM_TRACE_ERROR("key size = %d", p_rec->ble.keys.key_size);
   1553     if (use_stk)
   1554     {
   1555         btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, stk);
   1556     }
   1557     else /* calculate LTK using peer device  */
   1558     {
   1559         if (p_rec->ble.key_type & BTM_LE_KEY_LENC)
   1560             btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p_rec->ble.keys.lltk);
   1561         else
   1562             btsnd_hcic_ble_ltk_req_neg_reply(btm_cb.enc_handle);
   1563     }
   1564 }
   1565 
   1566 /*******************************************************************************
   1567 **
   1568 ** Function         btm_ble_io_capabilities_req
   1569 **
   1570 ** Description      This function is called to handle SMP get IO capability request.
   1571 **
   1572 ** Returns          void
   1573 **
   1574 *******************************************************************************/
   1575 UINT8 btm_ble_io_capabilities_req(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_LE_IO_REQ *p_data)
   1576 {
   1577     UINT8           callback_rc = BTM_SUCCESS;
   1578     BTM_TRACE_DEBUG ("btm_ble_io_capabilities_req");
   1579     if (btm_cb.api.p_le_callback)
   1580     {
   1581         /* the callback function implementation may change the IO capability... */
   1582         callback_rc = (*btm_cb.api.p_le_callback) (BTM_LE_IO_REQ_EVT, p_dev_rec->bd_addr, (tBTM_LE_EVT_DATA *)p_data);
   1583     }
   1584 #if BTM_OOB_INCLUDED == TRUE
   1585     if ((callback_rc == BTM_SUCCESS) || (BTM_OOB_UNKNOWN != p_data->oob_data))
   1586 #else
   1587     if (callback_rc == BTM_SUCCESS)
   1588 #endif
   1589     {
   1590 #if BTM_BLE_CONFORMANCE_TESTING == TRUE
   1591         if (btm_cb.devcb.keep_rfu_in_auth_req)
   1592         {
   1593             BTM_TRACE_DEBUG ("btm_ble_io_capabilities_req keep_rfu_in_auth_req = %u",
   1594                 btm_cb.devcb.keep_rfu_in_auth_req);
   1595             p_data->auth_req &= BTM_LE_AUTH_REQ_MASK_KEEP_RFU;
   1596             btm_cb.devcb.keep_rfu_in_auth_req = FALSE;
   1597         }
   1598         else
   1599         {   /* default */
   1600             p_data->auth_req &= BTM_LE_AUTH_REQ_MASK;
   1601         }
   1602 #else
   1603         p_data->auth_req &= BTM_LE_AUTH_REQ_MASK;
   1604 #endif
   1605 
   1606         BTM_TRACE_DEBUG ("btm_ble_io_capabilities_req 1: p_dev_rec->security_required = %d auth_req:%d",
   1607                           p_dev_rec->security_required, p_data->auth_req);
   1608         BTM_TRACE_DEBUG ("btm_ble_io_capabilities_req 2: i_keys=0x%x r_keys=0x%x (bit 0-LTK 1-IRK 2-CSRK)",
   1609                           p_data->init_keys,
   1610                           p_data->resp_keys);
   1611 
   1612         /* if authentication requires MITM protection, put on the mask */
   1613         if (p_dev_rec->security_required & BTM_SEC_IN_MITM)
   1614             p_data->auth_req |= BTM_LE_AUTH_REQ_MITM;
   1615 
   1616         if (!(p_data->auth_req & SMP_AUTH_BOND))
   1617         {
   1618             BTM_TRACE_DEBUG("Non bonding: No keys should be exchanged");
   1619             p_data->init_keys = 0;
   1620             p_data->resp_keys = 0;
   1621         }
   1622 
   1623         BTM_TRACE_DEBUG ("btm_ble_io_capabilities_req 3: auth_req:%d", p_data->auth_req);
   1624         BTM_TRACE_DEBUG ("btm_ble_io_capabilities_req 4: i_keys=0x%x r_keys=0x%x",
   1625                           p_data->init_keys,
   1626                           p_data->resp_keys);
   1627 
   1628         BTM_TRACE_DEBUG ("btm_ble_io_capabilities_req 5: p_data->io_cap = %d auth_req:%d",
   1629                           p_data->io_cap, p_data->auth_req);
   1630 
   1631         /* remove MITM protection requirement if IO cap does not allow it */
   1632         if ((p_data->io_cap == BTM_IO_CAP_NONE) && p_data->oob_data == SMP_OOB_NONE)
   1633             p_data->auth_req &= ~BTM_LE_AUTH_REQ_MITM;
   1634 
   1635         if (!(p_data->auth_req & SMP_SC_SUPPORT_BIT))
   1636         {
   1637             /* if Secure Connections are not supported then remove LK derivation,
   1638             ** and keypress notifications.
   1639             */
   1640             BTM_TRACE_DEBUG("%s-SC not supported -> No LK derivation, no keypress notifications",
   1641                             __func__);
   1642             p_data->auth_req &= ~SMP_KP_SUPPORT_BIT;
   1643             p_data->init_keys &= ~SMP_SEC_KEY_TYPE_LK;
   1644             p_data->resp_keys &= ~SMP_SEC_KEY_TYPE_LK;
   1645         }
   1646 
   1647         BTM_TRACE_DEBUG ("btm_ble_io_capabilities_req 6: IO_CAP:%d oob_data:%d auth_req:0x%02x",
   1648                           p_data->io_cap, p_data->oob_data, p_data->auth_req);
   1649     }
   1650     return callback_rc;
   1651 }
   1652 
   1653 /*******************************************************************************
   1654 **
   1655 ** Function         btm_ble_br_keys_req
   1656 **
   1657 ** Description      This function is called to handle SMP request for keys sent
   1658 **                  over BR/EDR.
   1659 **
   1660 ** Returns          void
   1661 **
   1662 *******************************************************************************/
   1663 UINT8 btm_ble_br_keys_req(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_LE_IO_REQ *p_data)
   1664 {
   1665     UINT8           callback_rc = BTM_SUCCESS;
   1666     BTM_TRACE_DEBUG ("%s", __func__);
   1667     if (btm_cb.api.p_le_callback)
   1668     {
   1669         /* the callback function implementation may change the IO capability... */
   1670         callback_rc = (*btm_cb.api.p_le_callback) (BTM_LE_IO_REQ_EVT, p_dev_rec->bd_addr,
   1671                                                   (tBTM_LE_EVT_DATA *)p_data);
   1672     }
   1673 
   1674     return callback_rc;
   1675 }
   1676 
   1677 #if (BLE_PRIVACY_SPT == TRUE )
   1678 /*******************************************************************************
   1679 **
   1680 ** Function         btm_ble_resolve_random_addr_on_conn_cmpl
   1681 **
   1682 ** Description      resolve random address complete on connection complete event.
   1683 **
   1684 ** Returns          void
   1685 **
   1686 *******************************************************************************/
   1687 static void btm_ble_resolve_random_addr_on_conn_cmpl(void * p_rec, void *p_data)
   1688 {
   1689     UINT8   *p = (UINT8 *)p_data;
   1690     tBTM_SEC_DEV_REC    *match_rec = (tBTM_SEC_DEV_REC *) p_rec;
   1691     UINT8       role, bda_type;
   1692     UINT16      handle;
   1693     BD_ADDR     bda;
   1694     UINT16      conn_interval, conn_latency, conn_timeout;
   1695     BOOLEAN     match = FALSE;
   1696 
   1697     ++p;
   1698     STREAM_TO_UINT16   (handle, p);
   1699     STREAM_TO_UINT8    (role, p);
   1700     STREAM_TO_UINT8    (bda_type, p);
   1701     STREAM_TO_BDADDR   (bda, p);
   1702     STREAM_TO_UINT16   (conn_interval, p);
   1703     STREAM_TO_UINT16   (conn_latency, p);
   1704     STREAM_TO_UINT16   (conn_timeout, p);
   1705 
   1706     handle = HCID_GET_HANDLE (handle);
   1707 
   1708     BTM_TRACE_EVENT ("%s", __func__);
   1709 
   1710     if (match_rec)
   1711     {
   1712         LOG_INFO("%s matched and resolved random address", __func__);
   1713         match = TRUE;
   1714         match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
   1715         memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
   1716         if (!btm_ble_init_pseudo_addr (match_rec, bda))
   1717         {
   1718             /* assign the original address to be the current report address */
   1719             memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN);
   1720         }
   1721         else
   1722         {
   1723             memcpy(bda, match_rec->bd_addr, BD_ADDR_LEN);
   1724         }
   1725     }
   1726     else
   1727     {
   1728         LOG_INFO("%s unable to match and resolve random address", __func__);
   1729     }
   1730 
   1731     btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match);
   1732 
   1733     l2cble_conn_comp (handle, role, bda, bda_type, conn_interval,
   1734                       conn_latency, conn_timeout);
   1735 
   1736     return;
   1737 }
   1738 #endif
   1739 
   1740 /*******************************************************************************
   1741 **
   1742 ** Function         btm_ble_connected
   1743 **
   1744 ** Description      This function is when a LE connection to the peer device is
   1745 **                  establsihed
   1746 **
   1747 ** Returns          void
   1748 **
   1749 *******************************************************************************/
   1750 void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role,
   1751                         tBLE_ADDR_TYPE addr_type, BOOLEAN addr_matched)
   1752 {
   1753     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
   1754     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
   1755     UNUSED(addr_matched);
   1756 
   1757     BTM_TRACE_EVENT ("btm_ble_connected");
   1758 
   1759     /* Commenting out trace due to obf/compilation problems.
   1760     */
   1761 #if (BT_USE_TRACES == TRUE)
   1762     if (p_dev_rec)
   1763     {
   1764         BTM_TRACE_EVENT ("Security Manager: btm_ble_connected :  handle:%d  enc_mode:%d  bda:%x RName:%s",
   1765                           handle,  enc_mode,
   1766                           (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5],
   1767                           p_dev_rec->sec_bd_name);
   1768 
   1769         BTM_TRACE_DEBUG ("btm_ble_connected sec_flags=0x%x",p_dev_rec->sec_flags);
   1770     }
   1771     else
   1772     {
   1773         BTM_TRACE_EVENT ("Security Manager: btm_ble_connected:   handle:%d  enc_mode:%d  bda:%x ",
   1774                           handle,  enc_mode,
   1775                           (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5]);
   1776     }
   1777 #endif
   1778 
   1779     if (!p_dev_rec)
   1780     {
   1781         /* There is no device record for new connection.  Allocate one */
   1782         if ((p_dev_rec = btm_sec_alloc_dev (bda)) == NULL)
   1783             return;
   1784     }
   1785     else    /* Update the timestamp for this device */
   1786     {
   1787         p_dev_rec->timestamp = btm_cb.dev_rec_count++;
   1788     }
   1789 
   1790     /* update device information */
   1791     p_dev_rec->device_type |= BT_DEVICE_TYPE_BLE;
   1792     p_dev_rec->ble_hci_handle = handle;
   1793     p_dev_rec->ble.ble_addr_type = addr_type;
   1794     /* update pseudo address */
   1795     memcpy(p_dev_rec->ble.pseudo_addr, bda, BD_ADDR_LEN);
   1796 
   1797     p_dev_rec->role_master = FALSE;
   1798     if (role == HCI_ROLE_MASTER)
   1799         p_dev_rec->role_master = TRUE;
   1800 
   1801 #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
   1802     if (!addr_matched)
   1803         p_dev_rec->ble.active_addr_type = BTM_BLE_ADDR_PSEUDO;
   1804 
   1805     if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_RANDOM && !addr_matched)
   1806         memcpy(p_dev_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
   1807 #endif
   1808 
   1809     p_cb->inq_var.directed_conn = BTM_BLE_CONNECT_EVT;
   1810 
   1811     return;
   1812 }
   1813 
   1814 /*****************************************************************************
   1815 **  Function        btm_ble_conn_complete
   1816 **
   1817 **  Description     LE connection complete.
   1818 **
   1819 ******************************************************************************/
   1820 void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced)
   1821 {
   1822 #if (BLE_PRIVACY_SPT == TRUE )
   1823     UINT8       *p_data = p, peer_addr_type;
   1824 #endif
   1825     UINT8       role, status, bda_type;
   1826     UINT16      handle;
   1827     BD_ADDR     bda, local_rpa, peer_rpa;
   1828     UINT16      conn_interval, conn_latency, conn_timeout;
   1829     BOOLEAN     match = FALSE;
   1830     UNUSED(evt_len);
   1831 
   1832     STREAM_TO_UINT8   (status, p);
   1833     STREAM_TO_UINT16   (handle, p);
   1834     STREAM_TO_UINT8    (role, p);
   1835     STREAM_TO_UINT8    (bda_type, p);
   1836     STREAM_TO_BDADDR   (bda, p);
   1837 
   1838     if (status == 0)
   1839     {
   1840 #if (BLE_PRIVACY_SPT == TRUE )
   1841         peer_addr_type = bda_type;
   1842         match = btm_identity_addr_to_random_pseudo (bda, &bda_type, TRUE);
   1843 
   1844         if (enhanced)
   1845         {
   1846             STREAM_TO_BDADDR   (local_rpa, p);
   1847             STREAM_TO_BDADDR   (peer_rpa, p);
   1848         }
   1849 
   1850         /* possiblly receive connection complete with resolvable random on
   1851            slave role while the device has been paired */
   1852         if (!match && role == HCI_ROLE_SLAVE && BTM_BLE_IS_RESOLVE_BDA(bda))
   1853         {
   1854             btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_conn_cmpl, p_data);
   1855         }
   1856         else
   1857 #endif
   1858         {
   1859             STREAM_TO_UINT16   (conn_interval, p);
   1860             STREAM_TO_UINT16   (conn_latency, p);
   1861             STREAM_TO_UINT16   (conn_timeout, p);
   1862             handle = HCID_GET_HANDLE (handle);
   1863 
   1864             btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match);
   1865 
   1866             l2cble_conn_comp (handle, role, bda, bda_type, conn_interval,
   1867                               conn_latency, conn_timeout);
   1868 
   1869 #if (BLE_PRIVACY_SPT == TRUE)
   1870             if (enhanced)
   1871             {
   1872                 btm_ble_refresh_local_resolvable_private_addr(bda, local_rpa);
   1873 
   1874                 if (peer_addr_type & BLE_ADDR_TYPE_ID_BIT)
   1875                     btm_ble_refresh_peer_resolvable_private_addr(bda, peer_rpa, BLE_ADDR_RANDOM);
   1876             }
   1877 #endif
   1878         }
   1879     }
   1880     else
   1881     {
   1882         role = HCI_ROLE_UNKNOWN;
   1883         if (status != HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT)
   1884         {
   1885             btm_ble_set_conn_st(BLE_CONN_IDLE);
   1886 #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
   1887             btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, TRUE);
   1888 #endif
   1889         }
   1890         else
   1891         {
   1892 #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
   1893             btm_cb.ble_ctr_cb.inq_var.adv_mode  = BTM_BLE_ADV_DISABLE;
   1894             btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, TRUE);
   1895 #endif
   1896         }
   1897     }
   1898 
   1899     btm_ble_update_mode_operation(role, bda, status);
   1900 }
   1901 
   1902 
   1903 
   1904 /*****************************************************************************
   1905 ** Function btm_ble_create_ll_conn_complete
   1906 **
   1907 ** Description LE connection complete.
   1908 **
   1909 ******************************************************************************/
   1910 void btm_ble_create_ll_conn_complete (UINT8 status)
   1911 {
   1912     if (status != HCI_SUCCESS)
   1913     {
   1914         btm_ble_set_conn_st(BLE_CONN_IDLE);
   1915         btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status);
   1916     }
   1917 }
   1918 /*****************************************************************************
   1919 **  Function        btm_proc_smp_cback
   1920 **
   1921 **  Description     This function is the SMP callback handler.
   1922 **
   1923 ******************************************************************************/
   1924 UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
   1925 {
   1926     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_dev (bd_addr);
   1927     UINT8 res = 0;
   1928 
   1929     BTM_TRACE_DEBUG ("btm_proc_smp_cback event = %d", event);
   1930 
   1931     if (p_dev_rec != NULL)
   1932     {
   1933         switch (event)
   1934         {
   1935             case SMP_IO_CAP_REQ_EVT:
   1936                 btm_ble_io_capabilities_req(p_dev_rec, (tBTM_LE_IO_REQ *)&p_data->io_req);
   1937                 break;
   1938 
   1939             case SMP_BR_KEYS_REQ_EVT:
   1940                 btm_ble_br_keys_req(p_dev_rec, (tBTM_LE_IO_REQ *)&p_data->io_req);
   1941                 break;
   1942 
   1943             case SMP_PASSKEY_REQ_EVT:
   1944             case SMP_PASSKEY_NOTIF_EVT:
   1945             case SMP_OOB_REQ_EVT:
   1946             case SMP_NC_REQ_EVT:
   1947             case SMP_SC_OOB_REQ_EVT:
   1948                 /* fall through */
   1949                 p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED;
   1950 
   1951             case SMP_SEC_REQUEST_EVT:
   1952                 if (event == SMP_SEC_REQUEST_EVT && btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
   1953                 {
   1954                     BTM_TRACE_DEBUG("%s: Ignoring SMP Security request", __func__);
   1955                     break;
   1956                 }
   1957                 memcpy (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN);
   1958                 p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
   1959                 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
   1960                 /* fall through */
   1961 
   1962             case SMP_COMPLT_EVT:
   1963                 if (btm_cb.api.p_le_callback)
   1964                 {
   1965                     /* the callback function implementation may change the IO capability... */
   1966                     BTM_TRACE_DEBUG ("btm_cb.api.p_le_callback=0x%x", btm_cb.api.p_le_callback );
   1967                    (*btm_cb.api.p_le_callback) (event, bd_addr, (tBTM_LE_EVT_DATA *)p_data);
   1968                 }
   1969 
   1970                 if (event == SMP_COMPLT_EVT)
   1971                 {
   1972                     BTM_TRACE_DEBUG ("evt=SMP_COMPLT_EVT before update sec_level=0x%x sec_flags=0x%x", p_data->cmplt.sec_level , p_dev_rec->sec_flags );
   1973 
   1974                     res = (p_data->cmplt.reason == SMP_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING;
   1975 
   1976                     BTM_TRACE_DEBUG ("after update result=%d sec_level=0x%x sec_flags=0x%x",
   1977                                       res, p_data->cmplt.sec_level , p_dev_rec->sec_flags );
   1978 
   1979                     if (p_data->cmplt.is_pair_cancel && btm_cb.api.p_bond_cancel_cmpl_callback )
   1980                     {
   1981                         BTM_TRACE_DEBUG ("Pairing Cancel completed");
   1982                         (*btm_cb.api.p_bond_cancel_cmpl_callback)(BTM_SUCCESS);
   1983                     }
   1984 #if BTM_BLE_CONFORMANCE_TESTING == TRUE
   1985                     if (res != BTM_SUCCESS)
   1986                     {
   1987                         if (!btm_cb.devcb.no_disc_if_pair_fail && p_data->cmplt.reason != SMP_CONN_TOUT)
   1988                         {
   1989                             BTM_TRACE_DEBUG ("Pairing failed - prepare to remove ACL");
   1990                             l2cu_start_post_bond_timer(p_dev_rec->ble_hci_handle);
   1991                         }
   1992                         else
   1993                         {
   1994                             BTM_TRACE_DEBUG ("Pairing failed - Not Removing ACL");
   1995                             p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
   1996                         }
   1997                     }
   1998 #else
   1999                     if (res != BTM_SUCCESS && p_data->cmplt.reason != SMP_CONN_TOUT)
   2000                     {
   2001                         BTM_TRACE_DEBUG ("Pairing failed - prepare to remove ACL");
   2002                         l2cu_start_post_bond_timer(p_dev_rec->ble_hci_handle);
   2003                     }
   2004 #endif
   2005 
   2006                     BTM_TRACE_DEBUG ("btm_cb pairing_state=%x pairing_flags=%x pin_code_len=%x",
   2007                                       btm_cb.pairing_state,
   2008                                       btm_cb.pairing_flags,
   2009                                       btm_cb.pin_code_len  );
   2010                     BTM_TRACE_DEBUG ("btm_cb.pairing_bda %02x:%02x:%02x:%02x:%02x:%02x",
   2011                                       btm_cb.pairing_bda[0], btm_cb.pairing_bda[1], btm_cb.pairing_bda[2],
   2012                                       btm_cb.pairing_bda[3], btm_cb.pairing_bda[4], btm_cb.pairing_bda[5]);
   2013 
   2014                     /* Reset btm state only if the callback address matches pairing address*/
   2015                     if(memcmp(bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) == 0)
   2016                     {
   2017                         memset (btm_cb.pairing_bda, 0xff, BD_ADDR_LEN);
   2018                         btm_cb.pairing_state = BTM_PAIR_STATE_IDLE;
   2019                         btm_cb.pairing_flags = 0;
   2020                     }
   2021 
   2022                     if (res == BTM_SUCCESS)
   2023                     {
   2024                         p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
   2025 #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
   2026                         /* add all bonded device into resolving list if IRK is available*/
   2027                         btm_ble_resolving_list_load_dev(p_dev_rec);
   2028 #endif
   2029                     }
   2030 
   2031                     btm_sec_dev_rec_cback_event(p_dev_rec, res, TRUE);
   2032                 }
   2033                 break;
   2034 
   2035             default:
   2036                 BTM_TRACE_DEBUG ("unknown event = %d", event);
   2037                 break;
   2038 
   2039 
   2040         }
   2041     }
   2042     else
   2043     {
   2044         BTM_TRACE_ERROR("btm_proc_smp_cback received for unknown device");
   2045     }
   2046 
   2047     return 0;
   2048 }
   2049 
   2050     #endif  /* SMP_INCLUDED */
   2051 
   2052 /*******************************************************************************
   2053 **
   2054 ** Function         BTM_BleDataSignature
   2055 **
   2056 ** Description      This function is called to sign the data using AES128 CMAC
   2057 **                  algorith.
   2058 **
   2059 ** Parameter        bd_addr: target device the data to be signed for.
   2060 **                  p_text: singing data
   2061 **                  len: length of the data to be signed.
   2062 **                  signature: output parameter where data signature is going to
   2063 **                             be stored.
   2064 **
   2065 ** Returns          TRUE if signing sucessul, otherwise FALSE.
   2066 **
   2067 *******************************************************************************/
   2068 BOOLEAN BTM_BleDataSignature (BD_ADDR bd_addr, UINT8 *p_text, UINT16 len,
   2069                               BLE_SIGNATURE signature)
   2070 {
   2071     tBTM_SEC_DEV_REC *p_rec = btm_find_dev (bd_addr);
   2072 
   2073     BTM_TRACE_DEBUG ("%s", __func__);
   2074     BOOLEAN ret = FALSE;
   2075     if (p_rec == NULL)
   2076     {
   2077         BTM_TRACE_ERROR("%s-data signing can not be done from unknown device", __func__);
   2078     }
   2079     else
   2080     {
   2081         UINT8 *p_mac = (UINT8 *)signature;
   2082         UINT8 *p_buf, *pp;
   2083         if ((p_buf = (UINT8 *)GKI_getbuf((UINT16)(len + 4))) != NULL)
   2084         {
   2085             BTM_TRACE_DEBUG("%s-Start to generate Local CSRK", __func__);
   2086             pp = p_buf;
   2087             /* prepare plain text */
   2088             if (p_text)
   2089             {
   2090                 memcpy(p_buf, p_text, len);
   2091                 pp = (p_buf + len);
   2092             }
   2093 
   2094             UINT32_TO_STREAM(pp, p_rec->ble.keys.local_counter);
   2095             UINT32_TO_STREAM(p_mac, p_rec->ble.keys.local_counter);
   2096 
   2097             if ((ret = aes_cipher_msg_auth_code(p_rec->ble.keys.lcsrk, p_buf, (UINT16)(len + 4),
   2098                                         BTM_CMAC_TLEN_SIZE, p_mac)) == TRUE)
   2099             {
   2100                   btm_ble_increment_sign_ctr(bd_addr, TRUE);
   2101             }
   2102 
   2103             BTM_TRACE_DEBUG("%s p_mac = %d", __func__, p_mac);
   2104             BTM_TRACE_DEBUG("p_mac[0] = 0x%02x p_mac[1] = 0x%02x p_mac[2] = 0x%02x p_mac[3] = 0x%02x",
   2105                              *p_mac, *(p_mac + 1), *(p_mac + 2), *(p_mac + 3));
   2106             BTM_TRACE_DEBUG("p_mac[4] = 0x%02x p_mac[5] = 0x%02x p_mac[6] = 0x%02x p_mac[7] = 0x%02x",
   2107                             *(p_mac + 4), *(p_mac + 5), *(p_mac + 6), *(p_mac + 7));
   2108             GKI_freebuf(p_buf);
   2109         }
   2110     }
   2111     return ret;
   2112 }
   2113 
   2114 /*******************************************************************************
   2115 **
   2116 ** Function         BTM_BleVerifySignature
   2117 **
   2118 ** Description      This function is called to verify the data signature
   2119 **
   2120 ** Parameter        bd_addr: target device the data to be signed for.
   2121 **                  p_orig:  original data before signature.
   2122 **                  len: length of the signing data
   2123 **                  counter: counter used when doing data signing
   2124 **                  p_comp: signature to be compared against.
   2125 
   2126 ** Returns          TRUE if signature verified correctly; otherwise FALSE.
   2127 **
   2128 *******************************************************************************/
   2129 BOOLEAN BTM_BleVerifySignature (BD_ADDR bd_addr, UINT8 *p_orig, UINT16 len, UINT32 counter,
   2130                                 UINT8 *p_comp)
   2131 {
   2132     BOOLEAN verified = FALSE;
   2133 #if SMP_INCLUDED == TRUE
   2134     tBTM_SEC_DEV_REC *p_rec = btm_find_dev (bd_addr);
   2135     UINT8 p_mac[BTM_CMAC_TLEN_SIZE];
   2136 
   2137     if (p_rec == NULL || (p_rec && !(p_rec->ble.key_type & BTM_LE_KEY_PCSRK)))
   2138     {
   2139         BTM_TRACE_ERROR("can not verify signature for unknown device");
   2140     }
   2141     else if (counter < p_rec->ble.keys.counter)
   2142     {
   2143         BTM_TRACE_ERROR("signature received with out dated sign counter");
   2144     }
   2145     else if (p_orig == NULL)
   2146     {
   2147         BTM_TRACE_ERROR("No signature to verify");
   2148     }
   2149     else
   2150     {
   2151         BTM_TRACE_DEBUG ("%s rcv_cnt=%d >= expected_cnt=%d", __func__, counter,
   2152                           p_rec->ble.keys.counter);
   2153 
   2154         if (aes_cipher_msg_auth_code(p_rec->ble.keys.pcsrk, p_orig, len, BTM_CMAC_TLEN_SIZE, p_mac))
   2155         {
   2156             if (memcmp(p_mac, p_comp, BTM_CMAC_TLEN_SIZE) == 0)
   2157             {
   2158                 btm_ble_increment_sign_ctr(bd_addr, FALSE);
   2159                 verified = TRUE;
   2160             }
   2161         }
   2162     }
   2163 #endif  /* SMP_INCLUDED */
   2164     return verified;
   2165 }
   2166 
   2167 /*******************************************************************************
   2168 **
   2169 ** Function         BTM_GetLeSecurityState
   2170 **
   2171 ** Description      This function is called to get security mode 1 flags and
   2172 **                  encryption key size for LE peer.
   2173 **
   2174 ** Returns          BOOLEAN TRUE if LE device is found, FALSE otherwise.
   2175 **
   2176 *******************************************************************************/
   2177 BOOLEAN BTM_GetLeSecurityState (BD_ADDR bd_addr, UINT8 *p_le_dev_sec_flags, UINT8 *p_le_key_size)
   2178 {
   2179 #if (BLE_INCLUDED == TRUE)
   2180     tBTM_SEC_DEV_REC *p_dev_rec;
   2181     UINT16 dev_rec_sec_flags;
   2182 #endif
   2183 
   2184     *p_le_dev_sec_flags = 0;
   2185     *p_le_key_size = 0;
   2186 
   2187 #if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
   2188     if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
   2189     {
   2190         BTM_TRACE_ERROR ("%s fails", __func__);
   2191         return (FALSE);
   2192     }
   2193 
   2194     if (p_dev_rec->ble_hci_handle == BTM_SEC_INVALID_HANDLE)
   2195     {
   2196         BTM_TRACE_ERROR ("%s-this is not LE device", __func__);
   2197         return (FALSE);
   2198     }
   2199 
   2200     dev_rec_sec_flags = p_dev_rec->sec_flags;
   2201 
   2202     if (dev_rec_sec_flags & BTM_SEC_LE_ENCRYPTED)
   2203     {
   2204         /* link is encrypted with LTK or STK */
   2205         *p_le_key_size = p_dev_rec->enc_key_size;
   2206         *p_le_dev_sec_flags |= BTM_SEC_LE_LINK_ENCRYPTED;
   2207 
   2208         *p_le_dev_sec_flags |= (dev_rec_sec_flags & BTM_SEC_LE_AUTHENTICATED)
   2209             ? BTM_SEC_LE_LINK_PAIRED_WITH_MITM      /* set auth LTK flag */
   2210             : BTM_SEC_LE_LINK_PAIRED_WITHOUT_MITM;  /* set unauth LTK flag */
   2211     }
   2212     else if (p_dev_rec->ble.key_type & BTM_LE_KEY_PENC)
   2213     {
   2214         /* link is unencrypted, still LTK is available */
   2215         *p_le_key_size = p_dev_rec->ble.keys.key_size;
   2216 
   2217         *p_le_dev_sec_flags |= (dev_rec_sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED)
   2218             ? BTM_SEC_LE_LINK_PAIRED_WITH_MITM      /* set auth LTK flag */
   2219             : BTM_SEC_LE_LINK_PAIRED_WITHOUT_MITM;  /* set unauth LTK flag */
   2220     }
   2221 
   2222     BTM_TRACE_DEBUG ("%s - le_dev_sec_flags: 0x%02x, le_key_size: %d",
   2223         __func__, *p_le_dev_sec_flags, *p_le_key_size);
   2224 
   2225     return TRUE;
   2226 #else
   2227     return FALSE;
   2228 #endif
   2229 }
   2230 
   2231 /*******************************************************************************
   2232 **
   2233 ** Function         BTM_BleSecurityProcedureIsRunning
   2234 **
   2235 ** Description      This function indicates if LE security procedure is
   2236 **                  currently running with the peer.
   2237 **
   2238 ** Returns          BOOLEAN TRUE if security procedure is running, FALSE otherwise.
   2239 **
   2240 *******************************************************************************/
   2241 BOOLEAN BTM_BleSecurityProcedureIsRunning(BD_ADDR bd_addr)
   2242 {
   2243 #if (BLE_INCLUDED == TRUE)
   2244     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
   2245 
   2246     if (p_dev_rec == NULL)
   2247     {
   2248         BTM_TRACE_ERROR ("%s device with BDA: %08x%04x is not found",
   2249                           __func__, (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
   2250                           (bd_addr[4]<<8)+bd_addr[5]);
   2251         return FALSE;
   2252     }
   2253 
   2254     return (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING ||
   2255             p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING);
   2256 #else
   2257     return FALSE;
   2258 #endif
   2259 }
   2260 
   2261 /*******************************************************************************
   2262 **
   2263 ** Function         BTM_BleGetSupportedKeySize
   2264 **
   2265 ** Description      This function gets the maximum encryption key size in bytes
   2266 **                  the local device can suport.
   2267 **                  record.
   2268 **
   2269 ** Returns          the key size or 0 if the size can't be retrieved.
   2270 **
   2271 *******************************************************************************/
   2272 extern UINT8 BTM_BleGetSupportedKeySize (BD_ADDR bd_addr)
   2273 {
   2274 #if ((BLE_INCLUDED == TRUE) && (L2CAP_LE_COC_INCLUDED == TRUE))
   2275     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
   2276     tBTM_LE_IO_REQ dev_io_cfg;
   2277     UINT8 callback_rc;
   2278 
   2279     if (!p_dev_rec)
   2280     {
   2281         BTM_TRACE_ERROR ("%s device with BDA: %08x%04x is not found",
   2282                          __func__,(bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
   2283                           (bd_addr[4]<<8)+bd_addr[5]);
   2284         return 0;
   2285     }
   2286 
   2287     if (btm_cb.api.p_le_callback == NULL)
   2288     {
   2289         BTM_TRACE_ERROR ("%s can't access supported key size",__func__);
   2290         return 0;
   2291     }
   2292 
   2293     callback_rc = (*btm_cb.api.p_le_callback) (BTM_LE_IO_REQ_EVT, p_dev_rec->bd_addr,
   2294                                                (tBTM_LE_EVT_DATA *) &dev_io_cfg);
   2295 
   2296     if (callback_rc != BTM_SUCCESS)
   2297     {
   2298         BTM_TRACE_ERROR ("%s can't access supported key size",__func__);
   2299         return 0;
   2300     }
   2301 
   2302     BTM_TRACE_DEBUG ("%s device supports key size = %d", __func__, dev_io_cfg.max_key_size);
   2303     return (dev_io_cfg.max_key_size);
   2304 #else
   2305     return 0;
   2306 #endif
   2307 }
   2308 
   2309 /*******************************************************************************
   2310 **  Utility functions for LE device IR/ER generation
   2311 *******************************************************************************/
   2312 /*******************************************************************************
   2313 **
   2314 ** Function         btm_notify_new_key
   2315 **
   2316 ** Description      This function is to notify application new keys have been
   2317 **                  generated.
   2318 **
   2319 ** Returns          void
   2320 **
   2321 *******************************************************************************/
   2322 static void btm_notify_new_key(UINT8 key_type)
   2323 {
   2324     tBTM_BLE_LOCAL_KEYS *p_locak_keys = NULL;
   2325 
   2326     BTM_TRACE_DEBUG ("btm_notify_new_key key_type=%d", key_type);
   2327 
   2328     if (btm_cb.api.p_le_key_callback)
   2329     {
   2330         switch (key_type)
   2331         {
   2332             case BTM_BLE_KEY_TYPE_ID:
   2333                 BTM_TRACE_DEBUG ("BTM_BLE_KEY_TYPE_ID");
   2334                 p_locak_keys = (tBTM_BLE_LOCAL_KEYS *)&btm_cb.devcb.id_keys;
   2335                 break;
   2336 
   2337             case BTM_BLE_KEY_TYPE_ER:
   2338                 BTM_TRACE_DEBUG ("BTM_BLE_KEY_TYPE_ER");
   2339                 p_locak_keys = (tBTM_BLE_LOCAL_KEYS *)&btm_cb.devcb.ble_encryption_key_value;
   2340                 break;
   2341 
   2342             default:
   2343                 BTM_TRACE_ERROR("unknown key type: %d", key_type);
   2344                 break;
   2345         }
   2346         if (p_locak_keys != NULL)
   2347             (*btm_cb.api.p_le_key_callback) (key_type, p_locak_keys);
   2348     }
   2349 }
   2350 
   2351 /*******************************************************************************
   2352 **
   2353 ** Function         btm_ble_process_er2
   2354 **
   2355 ** Description      This function is called when ER is generated, store it in
   2356 **                  local control block.
   2357 **
   2358 ** Returns          void
   2359 **
   2360 *******************************************************************************/
   2361 static void btm_ble_process_er2(tBTM_RAND_ENC *p)
   2362 {
   2363     BTM_TRACE_DEBUG ("btm_ble_process_er2");
   2364 
   2365     if (p &&p->opcode == HCI_BLE_RAND)
   2366     {
   2367         memcpy(&btm_cb.devcb.ble_encryption_key_value[8], p->param_buf, BT_OCTET8_LEN);
   2368         btm_notify_new_key(BTM_BLE_KEY_TYPE_ER);
   2369     }
   2370     else
   2371     {
   2372         BTM_TRACE_ERROR("Generating ER2 exception.");
   2373         memset(&btm_cb.devcb.ble_encryption_key_value, 0, sizeof(BT_OCTET16));
   2374     }
   2375 }
   2376 
   2377 /*******************************************************************************
   2378 **
   2379 ** Function         btm_ble_process_er
   2380 **
   2381 ** Description      This function is called when ER is generated, store it in
   2382 **                  local control block.
   2383 **
   2384 ** Returns          void
   2385 **
   2386 *******************************************************************************/
   2387 static void btm_ble_process_er(tBTM_RAND_ENC *p)
   2388 {
   2389     BTM_TRACE_DEBUG ("btm_ble_process_er");
   2390 
   2391     if (p &&p->opcode == HCI_BLE_RAND)
   2392     {
   2393         memcpy(&btm_cb.devcb.ble_encryption_key_value[0], p->param_buf, BT_OCTET8_LEN);
   2394 
   2395         if (!btsnd_hcic_ble_rand((void *)btm_ble_process_er2))
   2396         {
   2397             memset(&btm_cb.devcb.ble_encryption_key_value, 0, sizeof(BT_OCTET16));
   2398             BTM_TRACE_ERROR("Generating ER2 failed.");
   2399         }
   2400     }
   2401     else
   2402     {
   2403         BTM_TRACE_ERROR("Generating ER1 exception.");
   2404     }
   2405 }
   2406 
   2407 /*******************************************************************************
   2408 **
   2409 ** Function         btm_ble_process_irk
   2410 **
   2411 ** Description      This function is called when IRK is generated, store it in
   2412 **                  local control block.
   2413 **
   2414 ** Returns          void
   2415 **
   2416 *******************************************************************************/
   2417 static void btm_ble_process_irk(tSMP_ENC *p)
   2418 {
   2419     BTM_TRACE_DEBUG ("btm_ble_process_irk");
   2420     if (p &&p->opcode == HCI_BLE_ENCRYPT)
   2421     {
   2422         memcpy(btm_cb.devcb.id_keys.irk, p->param_buf, BT_OCTET16_LEN);
   2423         btm_notify_new_key(BTM_BLE_KEY_TYPE_ID);
   2424 
   2425 #if BLE_PRIVACY_SPT == TRUE
   2426         /* if privacy is enabled, new RPA should be calculated */
   2427         if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE)
   2428         {
   2429             btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low);
   2430         }
   2431 #endif
   2432     }
   2433     else
   2434     {
   2435         BTM_TRACE_ERROR("Generating IRK exception.");
   2436     }
   2437 
   2438     /* proceed generate ER */
   2439     if (!btsnd_hcic_ble_rand((void *)btm_ble_process_er))
   2440     {
   2441         BTM_TRACE_ERROR("Generating ER failed.");
   2442     }
   2443 }
   2444 
   2445 /*******************************************************************************
   2446 **
   2447 ** Function         btm_ble_process_dhk
   2448 **
   2449 ** Description      This function is called when DHK is calculated, store it in
   2450 **                  local control block, and proceed to generate ER, a 128-bits
   2451 **                  random number.
   2452 **
   2453 ** Returns          void
   2454 **
   2455 *******************************************************************************/
   2456 static void btm_ble_process_dhk(tSMP_ENC *p)
   2457 {
   2458 #if SMP_INCLUDED == TRUE
   2459     UINT8 btm_ble_irk_pt = 0x01;
   2460     tSMP_ENC output;
   2461 
   2462     BTM_TRACE_DEBUG ("btm_ble_process_dhk");
   2463 
   2464     if (p && p->opcode == HCI_BLE_ENCRYPT)
   2465     {
   2466         memcpy(btm_cb.devcb.id_keys.dhk, p->param_buf, BT_OCTET16_LEN);
   2467         BTM_TRACE_DEBUG("BLE DHK generated.");
   2468 
   2469         /* IRK = D1(IR, 1) */
   2470         if (!SMP_Encrypt(btm_cb.devcb.id_keys.ir, BT_OCTET16_LEN, &btm_ble_irk_pt,
   2471                          1,   &output))
   2472         {
   2473             /* reset all identity root related key */
   2474             memset(&btm_cb.devcb.id_keys, 0, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
   2475         }
   2476         else
   2477         {
   2478             btm_ble_process_irk(&output);
   2479         }
   2480     }
   2481     else
   2482     {
   2483         /* reset all identity root related key */
   2484         memset(&btm_cb.devcb.id_keys, 0, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
   2485     }
   2486 #endif
   2487 }
   2488 
   2489 /*******************************************************************************
   2490 **
   2491 ** Function         btm_ble_process_ir2
   2492 **
   2493 ** Description      This function is called when IR is generated, proceed to calculate
   2494 **                  DHK = Eir({0x03, 0, 0 ...})
   2495 **
   2496 **
   2497 ** Returns          void
   2498 **
   2499 *******************************************************************************/
   2500 static void btm_ble_process_ir2(tBTM_RAND_ENC *p)
   2501 {
   2502 #if SMP_INCLUDED == TRUE
   2503     UINT8 btm_ble_dhk_pt = 0x03;
   2504     tSMP_ENC output;
   2505 
   2506     BTM_TRACE_DEBUG ("btm_ble_process_ir2");
   2507 
   2508     if (p && p->opcode == HCI_BLE_RAND)
   2509     {
   2510         /* remembering in control block */
   2511         memcpy(&btm_cb.devcb.id_keys.ir[8], p->param_buf, BT_OCTET8_LEN);
   2512         /* generate DHK= Eir({0x03, 0x00, 0x00 ...}) */
   2513 
   2514 
   2515         SMP_Encrypt(btm_cb.devcb.id_keys.ir, BT_OCTET16_LEN, &btm_ble_dhk_pt,
   2516                     1, &output);
   2517         btm_ble_process_dhk(&output);
   2518 
   2519         BTM_TRACE_DEBUG("BLE IR generated.");
   2520     }
   2521     else
   2522     {
   2523         memset(&btm_cb.devcb.id_keys, 0, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
   2524     }
   2525 #endif
   2526 }
   2527 
   2528 /*******************************************************************************
   2529 **
   2530 ** Function         btm_ble_process_ir
   2531 **
   2532 ** Description      This function is called when IR is generated, proceed to calculate
   2533 **                  DHK = Eir({0x02, 0, 0 ...})
   2534 **
   2535 **
   2536 ** Returns          void
   2537 **
   2538 *******************************************************************************/
   2539 static void btm_ble_process_ir(tBTM_RAND_ENC *p)
   2540 {
   2541     BTM_TRACE_DEBUG ("btm_ble_process_ir");
   2542 
   2543     if (p && p->opcode == HCI_BLE_RAND)
   2544     {
   2545         /* remembering in control block */
   2546         memcpy(btm_cb.devcb.id_keys.ir, p->param_buf, BT_OCTET8_LEN);
   2547 
   2548         if (!btsnd_hcic_ble_rand((void *)btm_ble_process_ir2))
   2549         {
   2550             BTM_TRACE_ERROR("Generating IR2 failed.");
   2551             memset(&btm_cb.devcb.id_keys, 0, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
   2552         }
   2553     }
   2554 }
   2555 
   2556 /*******************************************************************************
   2557 **
   2558 ** Function         btm_ble_reset_id
   2559 **
   2560 ** Description      This function is called to reset LE device identity.
   2561 **
   2562 ** Returns          void
   2563 **
   2564 *******************************************************************************/
   2565 void btm_ble_reset_id( void )
   2566 {
   2567     BTM_TRACE_DEBUG ("btm_ble_reset_id");
   2568 
   2569     /* regenrate Identity Root*/
   2570     if (!btsnd_hcic_ble_rand((void *)btm_ble_process_ir))
   2571     {
   2572         BTM_TRACE_DEBUG("Generating IR failed.");
   2573     }
   2574 }
   2575 
   2576     #if BTM_BLE_CONFORMANCE_TESTING == TRUE
   2577 /*******************************************************************************
   2578 **
   2579 ** Function         btm_ble_set_no_disc_if_pair_fail
   2580 **
   2581 ** Description      This function indicates that whether no disconnect of the ACL
   2582 **                  should be used if pairing failed
   2583 **
   2584 ** Returns          void
   2585 **
   2586 *******************************************************************************/
   2587 void btm_ble_set_no_disc_if_pair_fail(BOOLEAN disable_disc )
   2588 {
   2589     BTM_TRACE_DEBUG ("btm_ble_set_disc_enable_if_pair_fail disable_disc=%d", disable_disc);
   2590     btm_cb.devcb.no_disc_if_pair_fail = disable_disc;
   2591 }
   2592 
   2593 /*******************************************************************************
   2594 **
   2595 ** Function         btm_ble_set_test_mac_value
   2596 **
   2597 ** Description      This function set test MAC value
   2598 **
   2599 ** Returns          void
   2600 **
   2601 *******************************************************************************/
   2602 void btm_ble_set_test_mac_value(BOOLEAN enable, UINT8 *p_test_mac_val )
   2603 {
   2604     BTM_TRACE_DEBUG ("btm_ble_set_test_mac_value enable=%d", enable);
   2605     btm_cb.devcb.enable_test_mac_val = enable;
   2606     memcpy(btm_cb.devcb.test_mac, p_test_mac_val, BT_OCTET8_LEN);
   2607 }
   2608 
   2609 /*******************************************************************************
   2610 **
   2611 ** Function         btm_ble_set_test_local_sign_cntr_value
   2612 **
   2613 ** Description      This function set test local sign counter value
   2614 **
   2615 ** Returns          void
   2616 **
   2617 *******************************************************************************/
   2618 void btm_ble_set_test_local_sign_cntr_value(BOOLEAN enable, UINT32 test_local_sign_cntr )
   2619 {
   2620     BTM_TRACE_DEBUG ("btm_ble_set_test_local_sign_cntr_value enable=%d local_sign_cntr=%d",
   2621                       enable, test_local_sign_cntr);
   2622     btm_cb.devcb.enable_test_local_sign_cntr = enable;
   2623     btm_cb.devcb.test_local_sign_cntr =  test_local_sign_cntr;
   2624 }
   2625 
   2626 /*******************************************************************************
   2627 **
   2628 ** Function         btm_set_random_address
   2629 **
   2630 ** Description      This function set a random address to local controller.
   2631 **
   2632 ** Returns          void
   2633 **
   2634 *******************************************************************************/
   2635 void btm_set_random_address(BD_ADDR random_bda)
   2636 {
   2637     tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
   2638     BOOLEAN     adv_mode = btm_cb.ble_ctr_cb.inq_var.adv_mode ;
   2639 
   2640     BTM_TRACE_DEBUG ("btm_set_random_address");
   2641 
   2642     if (adv_mode  == BTM_BLE_ADV_ENABLE)
   2643         btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE);
   2644 
   2645     memcpy(p_cb->private_addr, random_bda, BD_ADDR_LEN);
   2646     btsnd_hcic_ble_set_random_addr(p_cb->private_addr);
   2647 
   2648     if (adv_mode  == BTM_BLE_ADV_ENABLE)
   2649         btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE);
   2650 
   2651 
   2652 }
   2653 
   2654 /*******************************************************************************
   2655 **
   2656 ** Function         btm_ble_set_keep_rfu_in_auth_req
   2657 **
   2658 ** Description      This function indicates if RFU bits have to be kept as is
   2659 **                  (by default they have to be set to 0 by the sender).
   2660 **
   2661 ** Returns          void
   2662 **
   2663 *******************************************************************************/
   2664 void btm_ble_set_keep_rfu_in_auth_req(BOOLEAN keep_rfu)
   2665 {
   2666     BTM_TRACE_DEBUG ("btm_ble_set_keep_rfu_in_auth_req keep_rfus=%d", keep_rfu);
   2667     btm_cb.devcb.keep_rfu_in_auth_req = keep_rfu;
   2668 }
   2669 
   2670 #endif /* BTM_BLE_CONFORMANCE_TESTING */
   2671 
   2672 #endif /* BLE_INCLUDED */
   2673