OSDN Git Service

LE Privacy 1.2 and LE secure connections
[android-x86/system-bt.git] / btif / src / btif_dm.c
index 2957847..2e687e1 100644 (file)
  *
  *
  ***********************************************************************************/
+
+#define LOG_TAG "bt_btif_dm"
+
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include <hardware/bluetooth.h>
 
-#include <utils/Log.h>
 #include <cutils/properties.h>
 #include "gki.h"
 #include "btu.h"
-#include "bd.h"
+#include "btcore/include/bdaddr.h"
 #include "bta_api.h"
 #include "btif_api.h"
 #include "btif_util.h"
 #include "btif_storage.h"
 #include "btif_hh.h"
 #include "btif_config.h"
+#include "btif_sdp.h"
 
 #include "bta_gatt_api.h"
+#include "include/stack_config.h"
+
+#include "osi/include/log.h"
 
 /******************************************************************************
 **  Device specific workarounds
@@ -109,11 +118,18 @@ BOOLEAN blacklistPairingRetries(BD_ADDR bd_addr)
 
 #define MAX_SDP_BL_ENTRIES 3
 
+#define BOND_TYPE_UNKNOWN     0
+#define BOND_TYPE_PERSISTENT  1
+#define BOND_TYPE_TEMPORARY   2
+
+#define ENCRYPTED_BREDR       2
+#define ENCRYPTED_LE          4
+
 typedef struct
 {
     bt_bond_state_t state;
     BD_ADDR bd_addr;
-    UINT8   is_temp;
+    UINT8   bond_type;
     UINT8   pin_code_len;
     UINT8   is_ssp;
     UINT8   auth_req;
@@ -212,6 +228,7 @@ static btif_dm_local_key_cb_t ble_local_key_cb;
 static void btif_dm_ble_key_notif_evt(tBTA_DM_SP_KEY_NOTIF *p_ssp_key_notif);
 static void btif_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl);
 static void btif_dm_ble_passkey_req_evt(tBTA_DM_PIN_REQ *p_pin_req);
+static void btif_dm_ble_key_nc_req_evt(tBTA_DM_SP_KEY_NOTIF *p_notif_req) ;
 #endif
 
 static void bte_scan_filt_param_cfg_evt(UINT8 action_type,
@@ -227,7 +244,7 @@ extern bt_status_t btif_hf_execute_service(BOOLEAN b_enable);
 extern bt_status_t btif_av_execute_service(BOOLEAN b_enable);
 extern bt_status_t btif_hh_execute_service(BOOLEAN b_enable);
 extern bt_status_t btif_hf_client_execute_service(BOOLEAN b_enable);
-extern bt_status_t btif_mce_execute_service(BOOLEAN b_enable);
+extern bt_status_t btif_sdp_execute_service(BOOLEAN b_enable);
 extern int btif_hh_connect(bt_bdaddr_t *bd_addr);
 extern void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16);
 
@@ -239,6 +256,7 @@ extern void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UIN
 bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
                                                 BOOLEAN b_enable)
 {
+    BTIF_TRACE_DEBUG("%s service_id: %d", __FUNCTION__, service_id);
     /* Check the service_ID and invoke the profile's BT state changed API */
     switch (service_id)
     {
@@ -247,7 +265,7 @@ bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
          {
               btif_hf_execute_service(b_enable);
          }break;
-         case BTA_A2DP_SERVICE_ID:
+         case BTA_A2DP_SOURCE_SERVICE_ID:
          {
               btif_av_execute_service(b_enable);
          }break;
@@ -259,9 +277,9 @@ bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
          {
              btif_hf_client_execute_service(b_enable);
          }break;
-         case BTA_MAP_SERVICE_ID:
+         case BTA_SDP_SERVICE_ID:
          {
-             btif_mce_execute_service(b_enable);
+             btif_sdp_execute_service(b_enable);
          }break;
          default:
               BTIF_TRACE_ERROR("%s: Unknown service being enabled", __FUNCTION__);
@@ -289,11 +307,11 @@ static BOOLEAN check_eir_remote_name(tBTA_DM_SEARCH *p_search_data,
     /* Check EIR for remote name and services */
     if (p_search_data->inq_res.p_eir)
     {
-        p_eir_remote_name = BTA_CheckEirData(p_search_data->inq_res.p_eir,
+        p_eir_remote_name = BTM_CheckEirData(p_search_data->inq_res.p_eir,
                 BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
         if (!p_eir_remote_name)
         {
-            p_eir_remote_name = BTA_CheckEirData(p_search_data->inq_res.p_eir,
+            p_eir_remote_name = BTM_CheckEirData(p_search_data->inq_res.p_eir,
                     BTM_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
         }
 
@@ -362,7 +380,7 @@ BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod)
                                sizeof(uint32_t), &remote_cod);
     if (btif_storage_get_remote_device_property((bt_bdaddr_t *)remote_bdaddr, &prop_name) == BT_STATUS_SUCCESS)
     {
-        BTIF_TRACE_ERROR("%s: remote_cod = 0x%06x", __FUNCTION__, remote_cod);
+        LOG_INFO("%s remote_cod = 0x%08x cod = 0x%08x", __func__, remote_cod, cod);
         if ((remote_cod & 0x7ff) == cod)
             return TRUE;
     }
@@ -402,8 +420,8 @@ BOOLEAN check_hid_le(const bt_bdaddr_t *remote_bdaddr)
         if (remote_dev_type == BT_DEVICE_DEVTYPE_BLE)
         {
             bdstr_t bdstr;
-            bd2str(remote_bdaddr, &bdstr);
-            if(btif_config_exist("Remote", bdstr, "HidAppId"))
+            bdaddr_to_string(remote_bdaddr, bdstr, sizeof(bdstr));
+            if(btif_config_exist(bdstr, "HidAppId"))
                 return TRUE;
         }
     }
@@ -427,7 +445,6 @@ BOOLEAN check_sdp_bl(const bt_bdaddr_t *remote_bdaddr)
     UINT16 manufacturer = 0;
     UINT8 lmp_ver = 0;
     UINT16 lmp_subver = 0;
-    tBTM_STATUS btm_status;
     bt_property_t prop_name;
     bt_remote_version_t info;
     bt_status_t status;
@@ -437,7 +454,7 @@ BOOLEAN check_sdp_bl(const bt_bdaddr_t *remote_bdaddr)
         return FALSE;
 
 /* fetch additional info about remote device used in iop query */
-    btm_status = BTM_ReadRemoteVersion(*(BD_ADDR*)remote_bdaddr, &lmp_ver,
+    BTM_ReadRemoteVersion(*(BD_ADDR*)remote_bdaddr, &lmp_ver,
                     &manufacturer, &lmp_subver);
 
 
@@ -469,7 +486,7 @@ static void bond_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr, bt_bond
     if ( (pairing_cb.state == state) && (state == BT_BOND_STATE_BONDING) )
         return;
 
-    if (pairing_cb.is_temp)
+    if (pairing_cb.bond_type == BOND_TYPE_TEMPORARY)
     {
        state = BT_BOND_STATE_NONE;
     }
@@ -505,7 +522,7 @@ static void btif_update_remote_version_property(bt_bdaddr_t *p_bd)
     btm_status = BTM_ReadRemoteVersion(*(BD_ADDR*)p_bd, &lmp_ver,
                           &mfct_set, &lmp_subver);
 
-    ALOGD("remote version info [%s]: %x, %x, %x", bd2str(p_bd, &bdstr),
+    LOG_DEBUG("remote version info [%s]: %x, %x, %x", bdaddr_to_string(p_bd, bdstr, sizeof(bdstr)),
                lmp_ver, mfct_set, lmp_subver);
 
     if (btm_status == BTM_SUCCESS)
@@ -549,16 +566,16 @@ static void btif_update_remote_properties(BD_ADDR bd_addr, BD_NAME bd_name,
 
     /* class of device */
     cod = devclass2uint(dev_class);
-    BTIF_TRACE_DEBUG("%s():cod is 0x%06x", __FUNCTION__, cod);
+    BTIF_TRACE_DEBUG("%s cod is 0x%06x", __func__, cod);
     if ( cod == 0) {
        /* Try to retrieve cod from storage */
-        BTIF_TRACE_DEBUG("%s():cod is 0, checking cod from storage", __FUNCTION__);
+        BTIF_TRACE_DEBUG("%s cod is 0, checking cod from storage", __func__);
         BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
             BT_PROPERTY_CLASS_OF_DEVICE, sizeof(cod), &cod);
         status = btif_storage_get_remote_device_property(&bdaddr, &properties[num_properties]);
-        BTIF_TRACE_DEBUG("%s():cod retreived from storage is 0x%06x", __FUNCTION__, cod);
+        BTIF_TRACE_DEBUG("%s cod retrieved from storage is 0x%06x", __func__, cod);
         if ( cod == 0) {
-            BTIF_TRACE_DEBUG("%s():cod is again 0, set as unclassified", __FUNCTION__);
+            BTIF_TRACE_DEBUG("%s cod is again 0, set as unclassified", __func__);
             cod = COD_UNCLASSIFIED;
         }
     }
@@ -628,19 +645,19 @@ static void btif_dm_cb_create_bond(bt_bdaddr_t *bd_addr, tBTA_TRANSPORT transpor
     int device_type;
     int addr_type;
     bdstr_t bdstr;
-    bd2str(bd_addr, &bdstr);
+    bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr));
     if (transport == BT_TRANSPORT_LE)
     {
-        if (!btif_config_get_int("Remote", (char const *)&bdstr,"DevType", &device_type))
+        if (!btif_config_get_int((char const *)&bdstr,"DevType", &device_type))
         {
-            btif_config_set_int("Remote", bdstr, "DevType", BT_DEVICE_TYPE_BLE);
+            btif_config_set_int(bdstr, "DevType", BT_DEVICE_TYPE_BLE);
         }
         if (btif_storage_get_remote_addr_type(bd_addr, &addr_type) != BT_STATUS_SUCCESS)
         {
             btif_storage_set_remote_addr_type(bd_addr, BLE_ADDR_PUBLIC);
         }
     }
-    if((btif_config_get_int("Remote", (char const *)&bdstr,"DevType", &device_type) &&
+    if((btif_config_get_int((char const *)&bdstr,"DevType", &device_type) &&
        (btif_storage_get_remote_addr_type(bd_addr, &addr_type) == BT_STATUS_SUCCESS) &&
        (device_type == BT_DEVICE_TYPE_BLE)) || (transport == BT_TRANSPORT_LE))
     {
@@ -697,13 +714,33 @@ void btif_dm_cb_remove_bond(bt_bdaddr_t *bd_addr)
 ** Function         btif_dm_get_connection_state
 **
 ** Description      Returns whether the remote device is currently connected
+**                  and whether encryption is active for the connection
 **
-** Returns          0 if not connected
+** Returns          0 if not connected; 1 if connected and > 1 if connection is
+**                  encrypted
 **
 *******************************************************************************/
 uint16_t btif_dm_get_connection_state(const bt_bdaddr_t *bd_addr)
 {
-    return BTA_DmGetConnectionState((UINT8 *)bd_addr->address);
+    uint8_t *bda = (uint8_t*)bd_addr->address;
+    uint16_t rc = BTA_DmGetConnectionState(bda);
+
+    if (rc != 0)
+    {
+        uint8_t flags = 0;
+
+        BTM_GetSecurityFlagsByTransport(bda, &flags, BT_TRANSPORT_BR_EDR);
+        BTIF_TRACE_DEBUG("%s: security flags (BR/EDR)=0x%02x", __FUNCTION__, flags);
+        if (flags & BTM_SEC_FLAG_ENCRYPTED)
+            rc |= ENCRYPTED_BREDR;
+
+        BTM_GetSecurityFlagsByTransport(bda, &flags, BT_TRANSPORT_LE);
+        BTIF_TRACE_DEBUG("%s: security flags (LE)=0x%02x", __FUNCTION__, flags);
+        if (flags & BTM_SEC_FLAG_ENCRYPTED)
+            rc |= ENCRYPTED_LE;
+    }
+
+    return rc;
 }
 
 /*******************************************************************************
@@ -818,8 +855,8 @@ static void btif_dm_pin_req_evt(tBTA_DM_PIN_REQ *p_pin_req)
 
     cod = devclass2uint(p_pin_req->dev_class);
 
-    if ( cod == 0) {
-        BTIF_TRACE_DEBUG("%s():cod is 0, set as unclassified", __FUNCTION__);
+    if (cod == 0) {
+        BTIF_TRACE_DEBUG("%s cod is 0, set as unclassified", __func__);
         cod = COD_UNCLASSIFIED;
     }
 
@@ -908,9 +945,9 @@ static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_ssp_cfm_req)
     if (p_ssp_cfm_req->just_works && !(p_ssp_cfm_req->loc_auth_req & BTM_AUTH_BONDS) &&
         !(p_ssp_cfm_req->rmt_auth_req & BTM_AUTH_BONDS) &&
         !(check_cod((bt_bdaddr_t*)&p_ssp_cfm_req->bd_addr, COD_HID_POINTING)))
-        pairing_cb.is_temp = TRUE;
+        pairing_cb.bond_type = BOND_TYPE_TEMPORARY;
     else
-        pairing_cb.is_temp = FALSE;
+        pairing_cb.bond_type = BOND_TYPE_PERSISTENT;
 
     pairing_cb.is_ssp = TRUE;
 
@@ -938,8 +975,8 @@ static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_ssp_cfm_req)
 
     cod = devclass2uint(p_ssp_cfm_req->dev_class);
 
-    if ( cod == 0) {
-        ALOGD("cod is 0, set as unclassified");
+    if (cod == 0) {
+        LOG_DEBUG("%s cod is 0, set as unclassified", __func__);
         cod = COD_UNCLASSIFIED;
     }
 
@@ -973,8 +1010,8 @@ static void btif_dm_ssp_key_notif_evt(tBTA_DM_SP_KEY_NOTIF *p_ssp_key_notif)
     pairing_cb.is_ssp = TRUE;
     cod = devclass2uint(p_ssp_key_notif->dev_class);
 
-    if ( cod == 0) {
-        ALOGD("cod is 0, set as unclassified");
+    if (cod == 0) {
+        LOG_DEBUG("%s cod is 0, set as unclassified", __func__);
         cod = COD_UNCLASSIFIED;
     }
 
@@ -1003,11 +1040,11 @@ static void btif_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
     if ( (p_auth_cmpl->success == TRUE) && (p_auth_cmpl->key_present) )
     {
         if ((p_auth_cmpl->key_type < HCI_LKEY_TYPE_DEBUG_COMB)  || (p_auth_cmpl->key_type == HCI_LKEY_TYPE_AUTH_COMB) ||
-            (p_auth_cmpl->key_type == HCI_LKEY_TYPE_CHANGED_COMB) || (!pairing_cb.is_temp))
+            (p_auth_cmpl->key_type == HCI_LKEY_TYPE_CHANGED_COMB) || pairing_cb.bond_type == BOND_TYPE_PERSISTENT)
         {
             bt_status_t ret;
-            BTIF_TRACE_DEBUG("%s: Storing link key. key_type=0x%x, is_temp=%d",
-                __FUNCTION__, p_auth_cmpl->key_type, pairing_cb.is_temp);
+            BTIF_TRACE_DEBUG("%s: Storing link key. key_type=0x%x, bond_type=%d",
+                __FUNCTION__, p_auth_cmpl->key_type, pairing_cb.bond_type);
             ret = btif_storage_add_bonded_device(&bd_addr,
                                 p_auth_cmpl->key, p_auth_cmpl->key_type,
                                 pairing_cb.pin_code_len);
@@ -1015,9 +1052,9 @@ static void btif_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
         }
         else
         {
-            BTIF_TRACE_DEBUG("%s: Temporary key. Not storing. key_type=0x%x, is_temp=%d",
-                __FUNCTION__, p_auth_cmpl->key_type, pairing_cb.is_temp);
-            if(pairing_cb.is_temp)
+            BTIF_TRACE_DEBUG("%s: Temporary key. Not storing. key_type=0x%x, bond_type=%d",
+                __FUNCTION__, p_auth_cmpl->key_type, pairing_cb.bond_type);
+            if(pairing_cb.bond_type == BOND_TYPE_TEMPORARY)
             {
                 BTIF_TRACE_DEBUG("%s: sending BT_BOND_STATE_NONE for Temp pairing",
                         __FUNCTION__);
@@ -1037,15 +1074,14 @@ static void btif_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
 
         if (check_sdp_bl(&bd_addr) && check_cod_hid(&bd_addr, COD_HID_MAJOR))
         {
-            ALOGW("%s:skip SDP",
-                              __FUNCTION__);
+            LOG_WARN("%s:skip SDP", __FUNCTION__);
             skip_sdp = TRUE;
         }
         if(!pairing_cb.is_local_initiated && skip_sdp)
         {
             bond_state_changed(status, &bd_addr, state);
 
-            ALOGW("%s: Incoming HID Connection",__FUNCTION__);
+            LOG_WARN("%s: Incoming HID Connection",__FUNCTION__);
             bt_property_t prop;
             bt_bdaddr_t bd_addr;
             bt_uuid_t  uuid;
@@ -1208,7 +1244,7 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
             p_search_data = (tBTA_DM_SEARCH *)p_param;
             bdcpy(bdaddr.address, p_search_data->inq_res.bd_addr);
 
-            BTIF_TRACE_DEBUG("%s() %s device_type = 0x%x\n", __FUNCTION__, bd2str(&bdaddr, &bdstr),
+            BTIF_TRACE_DEBUG("%s() %s device_type = 0x%x\n", __FUNCTION__, bdaddr_to_string(&bdaddr, bdstr, sizeof(bdstr)),
 #if (BLE_INCLUDED == TRUE)
                     p_search_data->inq_res.device_type);
 #else
@@ -1218,8 +1254,8 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
 
             cod = devclass2uint (p_search_data->inq_res.dev_class);
 
-            if ( cod == 0) {
-                ALOGD("cod is 0, set as unclassified");
+            if (cod == 0) {
+                LOG_DEBUG("%s cod is 0, set as unclassified", __func__);
                 cod = COD_UNCLASSIFIED;
             }
 
@@ -1324,6 +1360,12 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
             */
            if (btif_dm_inquiry_in_progress == FALSE)
            {
+#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
+               tBTA_DM_BLE_PF_FILT_PARAMS adv_filt_param;
+               memset(&adv_filt_param, 0, sizeof(tBTA_DM_BLE_PF_FILT_PARAMS));
+               BTA_DmBleScanFilterSetup(BTA_DM_BLE_SCAN_COND_DELETE, 0, &adv_filt_param, NULL,
+                                        bte_scan_filt_param_cfg_evt, 0);
+#endif
                HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb, BT_DISCOVERY_STOPPED);
            }
         }
@@ -1377,8 +1419,8 @@ static void btif_dm_search_services_evt(UINT16 event, char *p_param)
                  for (i=0; i < p_data->disc_res.num_uuids; i++)
                  {
                       char temp[256];
-                      uuid_to_string((bt_uuid_t*)(p_data->disc_res.p_uuid_list + (i*MAX_UUID_SIZE)), temp);
-                      BTIF_TRACE_ERROR("Index: %d uuid:%s", i, temp);
+                      uuid_to_string_legacy((bt_uuid_t*)(p_data->disc_res.p_uuid_list + (i*MAX_UUID_SIZE)), temp);
+                      LOG_INFO("%s index:%d uuid:%s", __func__, i, temp);
                  }
             }
 
@@ -1437,8 +1479,8 @@ static void btif_dm_search_services_evt(UINT16 event, char *p_param)
                     j--;
                 }
 
-                uuid_to_string(&uuid, temp);
-                BTIF_TRACE_ERROR(" uuid:%s", temp);
+                uuid_to_string_legacy(&uuid, temp);
+                LOG_INFO("%s uuid:%s", __func__, temp);
 
                 bdcpy(bd_addr.address, p_data->disc_ble_res.bd_addr);
                 prop.type = BT_PROPERTY_UUIDS;
@@ -1587,7 +1629,7 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
 
              btif_storage_load_autopair_device_list();
 
-             btif_enable_bluetooth_evt(p_data->enable.status, p_data->enable.bd_addr);
+             btif_enable_bluetooth_evt(p_data->enable.status);
         }
         break;
 
@@ -1717,31 +1759,41 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
                 case BTA_LE_KEY_PENC:
                     BTIF_TRACE_DEBUG("Rcv BTA_LE_KEY_PENC");
                     pairing_cb.ble.is_penc_key_rcvd = TRUE;
-                    memcpy(pairing_cb.ble.penc_key.ltk,p_data->ble_key.key_value.penc_key.ltk, 16);
-                    memcpy(pairing_cb.ble.penc_key.rand, p_data->ble_key.key_value.penc_key.rand,8);
-                    pairing_cb.ble.penc_key.ediv = p_data->ble_key.key_value.penc_key.ediv;
-                    pairing_cb.ble.penc_key.sec_level = p_data->ble_key.key_value.penc_key.sec_level;
+                    memcpy(pairing_cb.ble.penc_key.ltk,
+                           p_data->ble_key.p_key_value->penc_key.ltk, 16);
+                    memcpy(pairing_cb.ble.penc_key.rand,
+                           p_data->ble_key.p_key_value->penc_key.rand,8);
+                    pairing_cb.ble.penc_key.ediv = p_data->ble_key.p_key_value->penc_key.ediv;
+                    pairing_cb.ble.penc_key.sec_level =
+                           p_data->ble_key.p_key_value->penc_key.sec_level;
 
                     for (i=0; i<16; i++)
                     {
-                        BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.ltk[%d]=0x%02x",i,pairing_cb.ble.penc_key.ltk[i]);
+                        BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.ltk[%d]=0x%02x",
+                                          i,pairing_cb.ble.penc_key.ltk[i]);
                     }
                     for (i=0; i<8; i++)
                     {
-                        BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.rand[%d]=0x%02x",i,pairing_cb.ble.penc_key.rand[i]);
+                        BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.rand[%d]=0x%02x",
+                                          i,pairing_cb.ble.penc_key.rand[i]);
                     }
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.ediv=0x%04x",pairing_cb.ble.penc_key.ediv);
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.sec_level=0x%02x",pairing_cb.ble.penc_key.sec_level);
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.key_size=0x%02x",pairing_cb.ble.penc_key.key_size);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.ediv=0x%04x",
+                        pairing_cb.ble.penc_key.ediv);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.sec_level=0x%02x",
+                        pairing_cb.ble.penc_key.sec_level);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.penc_key.key_size=0x%02x",
+                        pairing_cb.ble.penc_key.key_size);
                     break;
 
                 case BTA_LE_KEY_PID:
                     BTIF_TRACE_DEBUG("Rcv BTA_LE_KEY_PID");
                     pairing_cb.ble.is_pid_key_rcvd = TRUE;
-                    pairing_cb.ble.pid_key.addr_type = p_data->ble_key.key_value.pid_key.addr_type;
-                    memcpy(pairing_cb.ble.pid_key.irk, p_data->ble_key.key_value.pid_key.irk, 16);
+                    pairing_cb.ble.pid_key.addr_type =
+                           p_data->ble_key.p_key_value->pid_key.addr_type;
+                    memcpy(pairing_cb.ble.pid_key.irk,
+                           p_data->ble_key.p_key_value->pid_key.irk, 16);
                     memcpy(pairing_cb.ble.pid_key.static_addr,
-                            p_data->ble_key.key_value.pid_key.static_addr,BD_ADDR_LEN);
+                           p_data->ble_key.p_key_value->pid_key.static_addr,BD_ADDR_LEN);
                     for (i=0; i<16; i++)
                     {
                         BTIF_TRACE_DEBUG("pairing_cb.ble.pid_key.irk[%d]=0x%02x"
@@ -1757,28 +1809,39 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
                 case BTA_LE_KEY_PCSRK:
                     BTIF_TRACE_DEBUG("Rcv BTA_LE_KEY_PCSRK");
                     pairing_cb.ble.is_pcsrk_key_rcvd = TRUE;
-                    pairing_cb.ble.pcsrk_key.counter = p_data->ble_key.key_value.pcsrk_key.counter;
-                    pairing_cb.ble.pcsrk_key.sec_level = p_data->ble_key.key_value.pcsrk_key.sec_level;
-                    memcpy(pairing_cb.ble.pcsrk_key.csrk,p_data->ble_key.key_value.pcsrk_key.csrk,16);
+                    pairing_cb.ble.pcsrk_key.counter =
+                           p_data->ble_key.p_key_value->pcsrk_key.counter;
+                    pairing_cb.ble.pcsrk_key.sec_level =
+                           p_data->ble_key.p_key_value->pcsrk_key.sec_level;
+                    memcpy(pairing_cb.ble.pcsrk_key.csrk,
+                           p_data->ble_key.p_key_value->pcsrk_key.csrk,16);
 
                     for (i=0; i<16; i++)
                     {
-                        BTIF_TRACE_DEBUG("pairing_cb.ble.pcsrk_key.csrk[%d]=0x%02x",i,pairing_cb.ble.pcsrk_key.csrk[i]);
+                        BTIF_TRACE_DEBUG("pairing_cb.ble.pcsrk_key.csrk[%d]=0x%02x",
+                                          i,pairing_cb.ble.pcsrk_key.csrk[i]);
                     }
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.pcsrk_key.counter=0x%08x",pairing_cb.ble.pcsrk_key.counter);
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.pcsrk_key.sec_level=0x%02x",pairing_cb.ble.pcsrk_key.sec_level);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.pcsrk_key.counter=0x%08x",
+                                      pairing_cb.ble.pcsrk_key.counter);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.pcsrk_key.sec_level=0x%02x",
+                                      pairing_cb.ble.pcsrk_key.sec_level);
                     break;
 
                 case BTA_LE_KEY_LENC:
                     BTIF_TRACE_DEBUG("Rcv BTA_LE_KEY_LENC");
                     pairing_cb.ble.is_lenc_key_rcvd = TRUE;
-                    pairing_cb.ble.lenc_key.div = p_data->ble_key.key_value.lenc_key.div;
-                    pairing_cb.ble.lenc_key.key_size = p_data->ble_key.key_value.lenc_key.key_size;
-                    pairing_cb.ble.lenc_key.sec_level = p_data->ble_key.key_value.lenc_key.sec_level;
-
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.lenc_key.div=0x%04x",pairing_cb.ble.lenc_key.div);
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.lenc_key.key_size=0x%02x",pairing_cb.ble.lenc_key.key_size);
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.lenc_key.sec_level=0x%02x",pairing_cb.ble.lenc_key.sec_level);
+                    pairing_cb.ble.lenc_key.div = p_data->ble_key.p_key_value->lenc_key.div;
+                    pairing_cb.ble.lenc_key.key_size =
+                           p_data->ble_key.p_key_value->lenc_key.key_size;
+                    pairing_cb.ble.lenc_key.sec_level =
+                           p_data->ble_key.p_key_value->lenc_key.sec_level;
+
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.lenc_key.div=0x%04x",
+                                      pairing_cb.ble.lenc_key.div);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.lenc_key.key_size=0x%02x",
+                                      pairing_cb.ble.lenc_key.key_size);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.lenc_key.sec_level=0x%02x",
+                                      pairing_cb.ble.lenc_key.sec_level);
                     break;
 
 
@@ -1786,14 +1849,25 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
                 case BTA_LE_KEY_LCSRK:
                     BTIF_TRACE_DEBUG("Rcv BTA_LE_KEY_LCSRK");
                     pairing_cb.ble.is_lcsrk_key_rcvd = TRUE;
-                    pairing_cb.ble.lcsrk_key.counter = p_data->ble_key.key_value.lcsrk_key.counter;
-                    pairing_cb.ble.lcsrk_key.div = p_data->ble_key.key_value.lcsrk_key.div;
-                    pairing_cb.ble.lcsrk_key.sec_level = p_data->ble_key.key_value.lcsrk_key.sec_level;
+                    pairing_cb.ble.lcsrk_key.counter =
+                        p_data->ble_key.p_key_value->lcsrk_key.counter;
+                    pairing_cb.ble.lcsrk_key.div =
+                        p_data->ble_key.p_key_value->lcsrk_key.div;
+                    pairing_cb.ble.lcsrk_key.sec_level =
+                        p_data->ble_key.p_key_value->lcsrk_key.sec_level;
+
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.lcsrk_key.div=0x%04x",
+                        pairing_cb.ble.lcsrk_key.div);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.lcsrk_key.counter=0x%08x",
+                        pairing_cb.ble.lcsrk_key.counter);
+                    BTIF_TRACE_DEBUG("pairing_cb.ble.lcsrk_key.sec_level=0x%02x",
+                        pairing_cb.ble.lcsrk_key.sec_level);
 
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.lcsrk_key.div=0x%04x",pairing_cb.ble.lcsrk_key.div);
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.lcsrk_key.counter=0x%08x",pairing_cb.ble.lcsrk_key.counter);
-                    BTIF_TRACE_DEBUG("pairing_cb.ble.lcsrk_key.sec_level=0x%02x",pairing_cb.ble.lcsrk_key.sec_level);
+                    break;
 
+                case BTA_LE_KEY_LID:
+                    BTIF_TRACE_DEBUG("Rcv BTA_LE_KEY_LID");
+                    pairing_cb.ble.is_lidk_key_rcvd =  TRUE;
                     break;
 
                 default:
@@ -1814,15 +1888,22 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
             BTIF_TRACE_DEBUG("BTA_DM_BLE_PASSKEY_REQ_EVT. ");
             btif_dm_ble_passkey_req_evt(&p_data->pin_req);
             break;
+        case BTA_DM_BLE_NC_REQ_EVT:
+            BTIF_TRACE_DEBUG("BTA_DM_BLE_PASSKEY_REQ_EVT. ");
+            btif_dm_ble_key_nc_req_evt(&p_data->key_notif);
+            break;
         case BTA_DM_BLE_OOB_REQ_EVT:
             BTIF_TRACE_DEBUG("BTA_DM_BLE_OOB_REQ_EVT. ");
             break;
         case BTA_DM_BLE_LOCAL_IR_EVT:
             BTIF_TRACE_DEBUG("BTA_DM_BLE_LOCAL_IR_EVT. ");
             ble_local_key_cb.is_id_keys_rcvd = TRUE;
-            memcpy(&ble_local_key_cb.id_keys.irk[0], &p_data->ble_id_keys.irk[0], sizeof(BT_OCTET16));
-            memcpy(&ble_local_key_cb.id_keys.ir[0], &p_data->ble_id_keys.ir[0], sizeof(BT_OCTET16));
-            memcpy(&ble_local_key_cb.id_keys.dhk[0], &p_data->ble_id_keys.dhk[0], sizeof(BT_OCTET16));
+            memcpy(&ble_local_key_cb.id_keys.irk[0],
+                   &p_data->ble_id_keys.irk[0], sizeof(BT_OCTET16));
+            memcpy(&ble_local_key_cb.id_keys.ir[0],
+                   &p_data->ble_id_keys.ir[0], sizeof(BT_OCTET16));
+            memcpy(&ble_local_key_cb.id_keys.dhk[0],
+                   &p_data->ble_id_keys.dhk[0], sizeof(BT_OCTET16));
             btif_storage_add_ble_local_key( (char *)&ble_local_key_cb.id_keys.irk[0],
                                             BTIF_DM_LE_LOCAL_KEY_IR,
                                             BT_OCTET16_LEN);
@@ -1843,7 +1924,7 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
             break;
 
         case BTA_DM_BLE_AUTH_CMPL_EVT:
-            BTIF_TRACE_DEBUG("BTA_DM_BLE_KEY_EVT. ");
+            BTIF_TRACE_DEBUG("BTA_DM_BLE_AUTH_CMPL_EVT. ");
             btif_dm_ble_auth_cmpl_evt(&p_data->auth_cmpl);
             break;
 
@@ -1869,11 +1950,11 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
             local_le_features.max_adv_instance = cmn_vsc_cb.adv_inst_max;
             local_le_features.max_irk_list_size = cmn_vsc_cb.max_irk_list_sz;
             local_le_features.rpa_offload_supported = cmn_vsc_cb.rpa_offloading;
-            local_le_features.scan_result_storage_size_hibyte =
-                (cmn_vsc_cb.tot_scan_results_strg >> 8) & (0xFF);
-            local_le_features.scan_result_storage_size_lobyte =
-                (cmn_vsc_cb.tot_scan_results_strg) & (0xFF);
             local_le_features.activity_energy_info_supported = cmn_vsc_cb.energy_support;
+            local_le_features.scan_result_storage_size = cmn_vsc_cb.tot_scan_results_strg;
+            local_le_features.version_supported = cmn_vsc_cb.version_supported;
+            local_le_features.total_trackable_advertisers =
+                        cmn_vsc_cb.total_trackable_advertisers;
             memcpy(prop.val, &local_le_features, prop.len);
             HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1, &prop);
             break;
@@ -2245,8 +2326,7 @@ bt_status_t btif_dm_create_bond(const bt_bdaddr_t *bd_addr, int transport)
     bdcpy(create_bond_cb.bdaddr.address, bd_addr->address);
 
     bdstr_t bdstr;
-    BTIF_TRACE_EVENT("%s: bd_addr=%s, transport=%d", __FUNCTION__,
-            bd2str((bt_bdaddr_t *) bd_addr, &bdstr), transport);
+    BTIF_TRACE_EVENT("%s: bd_addr=%s, transport=%d", __FUNCTION__, bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)), transport);
     if (pairing_cb.state != BT_BOND_STATE_NONE)
         return BT_STATUS_BUSY;
 
@@ -2270,7 +2350,7 @@ bt_status_t btif_dm_cancel_bond(const bt_bdaddr_t *bd_addr)
 {
     bdstr_t bdstr;
 
-    BTIF_TRACE_EVENT("%s: bd_addr=%s", __FUNCTION__, bd2str((bt_bdaddr_t *)bd_addr, &bdstr));
+    BTIF_TRACE_EVENT("%s: bd_addr=%s", __FUNCTION__, bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)));
 
     /* TODO:
     **  1. Restore scan modes
@@ -2359,7 +2439,7 @@ bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *bd_addr)
 {
     bdstr_t bdstr;
 
-    BTIF_TRACE_EVENT("%s: bd_addr=%s", __FUNCTION__, bd2str((bt_bdaddr_t *)bd_addr, &bdstr));
+    BTIF_TRACE_EVENT("%s: bd_addr=%s", __FUNCTION__, bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)));
     btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_REMOVE_BOND,
                           (char *)bd_addr, sizeof(bt_bdaddr_t), NULL);
 
@@ -2475,7 +2555,9 @@ bt_status_t btif_dm_get_adapter_property(bt_property_t *prop)
         case BT_PROPERTY_BDNAME:
         {
             bt_bdname_t *bd_name = (bt_bdname_t*)prop->val;
-            strcpy((char *)bd_name->name, btif_get_default_local_name());
+            strncpy((char *)bd_name->name, (char *)btif_get_default_local_name(),
+                   sizeof(bd_name->name) - 1);
+            bd_name->name[sizeof(bd_name->name) - 1] = 0;
             prop->len = strlen((char *)bd_name->name);
         }
         break;
@@ -2517,7 +2599,7 @@ bt_status_t btif_dm_get_remote_services(bt_bdaddr_t *remote_addr)
 {
     bdstr_t bdstr;
 
-    BTIF_TRACE_EVENT("%s: remote_addr=%s", __FUNCTION__, bd2str(remote_addr, &bdstr));
+    BTIF_TRACE_EVENT("%s: remote_addr=%s", __FUNCTION__, bdaddr_to_string(remote_addr, bdstr, sizeof(bdstr)));
 
     BTA_DmDiscover(remote_addr->address, BTA_ALL_SERVICE_MASK,
                    bte_dm_search_services_evt, TRUE);
@@ -2540,7 +2622,7 @@ bt_status_t btif_dm_get_remote_service_record(bt_bdaddr_t *remote_addr,
     tSDP_UUID sdp_uuid;
     bdstr_t bdstr;
 
-    BTIF_TRACE_EVENT("%s: remote_addr=%s", __FUNCTION__, bd2str(remote_addr, &bdstr));
+    BTIF_TRACE_EVENT("%s: remote_addr=%s", __FUNCTION__, bdaddr_to_string(remote_addr, bdstr, sizeof(bdstr)));
 
     sdp_uuid.len = MAX_UUID_SIZE;
     memcpy(sdp_uuid.uu.uuid128, uuid->uu, MAX_UUID_SIZE);
@@ -2940,6 +3022,14 @@ void btif_dm_save_ble_bonding_keys(void)
                                          sizeof(btif_dm_ble_lcsrk_keys_t));
     }
 
+    if (pairing_cb.ble.is_lidk_key_rcvd)
+    {
+        btif_storage_add_ble_bonding_key(&bd_addr,
+                                         NULL,
+                                         BTIF_DM_LE_KEY_LID,
+                                         0);
+    }
+
 }
 
 
@@ -2991,7 +3081,7 @@ void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ *p_ble_req)
 
     bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
 
-    pairing_cb.is_temp = FALSE;
+    pairing_cb.bond_type = BOND_TYPE_PERSISTENT;
     pairing_cb.is_le_only = TRUE;
     pairing_cb.is_ssp = TRUE;
 
@@ -3038,7 +3128,28 @@ static void btif_dm_ble_passkey_req_evt(tBTA_DM_PIN_REQ *p_pin_req)
     HAL_CBACK(bt_hal_cbacks, pin_request_cb,
               &bd_addr, &bd_name, cod);
 }
+static void btif_dm_ble_key_nc_req_evt(tBTA_DM_SP_KEY_NOTIF *p_notif_req)
+{
+    /* TODO implement key notification for numeric comparison */
+    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
+
+    /* Remote name update */
+    btif_update_remote_properties(p_notif_req->bd_addr , p_notif_req->bd_name,
+                                          NULL, BT_DEVICE_TYPE_BLE);
 
+    bt_bdaddr_t bd_addr;
+    bdcpy(bd_addr.address, p_notif_req->bd_addr);
+
+    bt_bdname_t bd_name;
+    memcpy(bd_name.name, p_notif_req->bd_name, BD_NAME_LEN);
+
+    bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+    pairing_cb.is_ssp = FALSE;
+
+    HAL_CBACK(bt_hal_cbacks, ssp_request_cb, &bd_addr, &bd_name,
+              COD_UNCLASSIFIED, BT_SSP_VARIANT_PASSKEY_CONFIRMATION,
+              p_notif_req->passkey);
+}
 
 void btif_dm_update_ble_remote_properties( BD_ADDR bd_addr, BD_NAME bd_name,
                                            tBT_DEVICE_TYPE dev_type)