Cross transport key mapping fixes
Change-Id: I22d97303054eccc876c4a9c7c0a50e369ff4fa62
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index 1251f5d..64a084d 100644
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -2279,10 +2279,8 @@
bta_dm_search_cb.services_to_search
);
}
- if (transport == BT_TRANSPORT_LE) /*
- if ( bta_dm_search_cb.p_btm_inq_info != NULL &&
- bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE &&
- (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK))*/
+
+ if (transport == BT_TRANSPORT_LE)
{
if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK)
{
@@ -2730,14 +2728,15 @@
memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
+ // Report the BR link key based on the BR/EDR address and type
+ BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
+
if(bta_dm_cb.p_sec_cback)
- {
bta_dm_cb.p_sec_cback(event, &sec_event);
- }
}
else
{
- APPL_TRACE_WARNING(" bta_dm_new_link_key_cback() Received AMP Key?? ");
+ APPL_TRACE_WARNING("%s() Received AMP Key", __func__);
}
return BTM_CMD_STARTED;
@@ -2766,18 +2765,14 @@
memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN-1));
sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
-/* taken care of by memset [above]
- sec_event.auth_cmpl.key_present = FALSE;
- sec_event.auth_cmpl.success = FALSE;
-*/
+ // Report the BR link key based on the BR/EDR address and type
+ BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
sec_event.auth_cmpl.fail_reason = (UINT8)result;
- if(bta_dm_cb.p_sec_cback)
- {
- bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
- }
- /* delete this device entry from Sec Dev DB */
- bta_dm_remove_sec_dev_entry(bd_addr);
+ if(bta_dm_cb.p_sec_cback)
+ bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
+
+ bta_dm_remove_sec_dev_entry(bd_addr);
}
return BTM_SUCCESS;
@@ -4390,7 +4385,7 @@
case BTM_LE_COMPLT_EVT:
bdcpy(sec_event.auth_cmpl.bd_addr, bda);
- BTM_ReadDevInfo(bda, &dev_type, &sec_event.auth_cmpl.addr_type);
+ BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
p_name = BTM_SecReadDevName(bda);
if (p_name != NULL)
{
@@ -5417,7 +5412,7 @@
/* make sure the string is terminated */
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN-1] = 0;
- p_msg->disc_result.result.disc_res.device_type = BT_DEVICE_TYPE_BLE;
+ p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
if ( bta_dm_search_cb.ble_raw_used > 0 )
{
p_msg->disc_result.result.disc_res.p_raw_data = GKI_getbuf(bta_dm_search_cb.ble_raw_used);
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index 9c13be4..ac893e5 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -763,6 +763,7 @@
UINT8 fail_reason; /* The HCI reason/error code for when success=FALSE */
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
tBLE_ADDR_TYPE addr_type; /* peer device address type */
+ tBT_DEVICE_TYPE dev_type;
#endif
} tBTA_DM_AUTH_CMPL;
diff --git a/btif/co/bta_dm_co.c b/btif/co/bta_dm_co.c
index c4bdf2b..641b60c 100644
--- a/btif/co/bta_dm_co.c
+++ b/btif/co/bta_dm_co.c
@@ -31,15 +31,15 @@
tBTE_APPL_CFG bte_appl_cfg =
{
-#if SMP_INCLUDED == TRUE && SMP_LE_SC_INCLUDED == TRUE
- BTA_LE_AUTH_REQ_SC_MITM_BOND, //Authentication requirements
+#if SMP_INCLUDED == TRUE
+ BTA_LE_AUTH_REQ_SC_MITM_BOND, // Authentication requirements
#else
- BTM_AUTH_SPGB_YES, // Authentication requirements
+ BTM_AUTH_SPGB_YES, // Authentication requirements
#endif
- BTM_LOCAL_IO_CAPS_BLE, // I/O capabilities
- 7, // Initiaor key size
- 7, // Responder key size
- 16 // Maximum key size
+ BTM_LOCAL_IO_CAPS_BLE,
+ BTM_BLE_INITIATOR_KEY_SIZE,
+ BTM_BLE_RESPONDER_KEY_SIZE,
+ BTM_BLE_MAX_KEY_SIZE
};
#endif
@@ -426,10 +426,10 @@
if (bte_appl_cfg.ble_io_cap <=4)
*p_io_cap = bte_appl_cfg.ble_io_cap;
- if (bte_appl_cfg.ble_init_key<=7)
+ if (bte_appl_cfg.ble_init_key <= BTM_BLE_INITIATOR_KEY_SIZE)
*p_init_key = bte_appl_cfg.ble_init_key;
- if (bte_appl_cfg.ble_resp_key<=7)
+ if (bte_appl_cfg.ble_resp_key <= BTM_BLE_RESPONDER_KEY_SIZE)
*p_resp_key = bte_appl_cfg.ble_resp_key;
if (bte_appl_cfg.ble_max_key_size > 7 && bte_appl_cfg.ble_max_key_size <= 16)
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index aed6329..9545b36 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -129,18 +129,19 @@
{
bt_bond_state_t state;
BD_ADDR bd_addr;
- UINT8 bond_type;
- UINT8 pin_code_len;
- UINT8 is_ssp;
- UINT8 auth_req;
- UINT8 io_cap;
- UINT8 autopair_attempts;
- UINT8 timeout_retries;
- UINT8 is_local_initiated;
- UINT8 sdp_attempts;
+ UINT8 bond_type;
+ UINT8 pin_code_len;
+ UINT8 is_ssp;
+ UINT8 auth_req;
+ UINT8 io_cap;
+ UINT8 autopair_attempts;
+ UINT8 timeout_retries;
+ UINT8 is_local_initiated;
+ UINT8 sdp_attempts;
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
- BOOLEAN is_le_only;
- BOOLEAN is_le_nc;/*LE Numeric comparison*/
+ BOOLEAN is_le_only;
+ BOOLEAN is_le_nc; /* LE Numeric comparison */
+ BD_ADDR static_bdaddr;
btif_dm_ble_cb_t ble;
#endif
} btif_dm_pairing_cb_t;
@@ -203,7 +204,6 @@
static skip_sdp_entry_t sdp_blacklist[] = {{76}}; //Apple Mouse and Keyboard
-
/* This flag will be true if HCI_Inquiry is in progress */
static BOOLEAN btif_dm_inquiry_in_progress = FALSE;
@@ -486,15 +486,20 @@
static void bond_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr, bt_bond_state_t state)
{
- /* Send bonding state only once - based on outgoing/incoming we may receive duplicates */
- if ( (pairing_cb.state == state) && (state == BT_BOND_STATE_BONDING) )
+ // Send bonding state only once - based on outgoing/incoming we may receive duplicates
+ if ((pairing_cb.state == state) && (state == BT_BOND_STATE_BONDING))
+ {
+ // Cross key pairing so send callback for static address
+ if (pairing_cb.static_bdaddr != NULL)
+ HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);
return;
+ }
if (pairing_cb.bond_type == BOND_TYPE_TEMPORARY)
- {
- state = BT_BOND_STATE_NONE;
- }
- BTIF_TRACE_DEBUG("%s: state=%d prev_state=%d", __FUNCTION__, state, pairing_cb.state);
+ state = BT_BOND_STATE_NONE;
+
+ BTIF_TRACE_DEBUG("%s: state=%d, prev_state=%d, sdp_attempts = %d", __func__,
+ state, pairing_cb.state, pairing_cb.sdp_attempts);
HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);
@@ -502,12 +507,12 @@
{
pairing_cb.state = state;
bdcpy(pairing_cb.bd_addr, bd_addr->address);
+ } else {
+ if (!pairing_cb.sdp_attempts)
+ memset(&pairing_cb, 0, sizeof(pairing_cb));
+ else
+ BTIF_TRACE_DEBUG("%s: BR-EDR service discovery active", __func__);
}
- else
- {
- memset(&pairing_cb, 0, sizeof(pairing_cb));
- }
-
}
/* store remote version in bt config to always have access
@@ -531,8 +536,7 @@
if (btm_status == BTM_SUCCESS)
{
- /* always update cache to ensure we have availability whenever BTM API
- is not populated */
+ // Always update cache to ensure we have availability whenever BTM API is not populated
info.manufacturer = mfct_set;
info.sub_ver = lmp_subver;
info.version = lmp_ver;
@@ -591,7 +595,15 @@
num_properties++;
/* device type */
- dev_type = device_type;
+ bt_property_t prop_name;
+ uint8_t remote_dev_type;
+ BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_TYPE_OF_DEVICE,
+ sizeof(uint8_t), &remote_dev_type);
+ if (btif_storage_get_remote_device_property(&bdaddr, &prop_name) == BT_STATUS_SUCCESS)
+ dev_type = remote_dev_type | device_type;
+ else
+ dev_type = device_type;
+
BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type);
status = btif_storage_set_remote_device_property(&bdaddr, &properties[num_properties]);
@@ -663,14 +675,14 @@
}
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))
+ (device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE) || (transport == BT_TRANSPORT_LE))
{
- BTA_DmAddBleDevice(bd_addr->address, addr_type, BT_DEVICE_TYPE_BLE);
+ BTA_DmAddBleDevice(bd_addr->address, addr_type, device_type);
}
#endif
#if BLE_INCLUDED == TRUE
- if(is_hid && device_type != BT_DEVICE_TYPE_BLE)
+ if(is_hid && (device_type & BT_DEVICE_TYPE_BLE) == 0)
#else
if(is_hid)
#endif
@@ -708,6 +720,7 @@
if (btif_hh_virtual_unplug(bd_addr) != BT_STATUS_SUCCESS)
#endif
{
+ BTIF_TRACE_DEBUG("%s: Removing HH device", __func__);
BTA_DmRemoveDevice((UINT8 *)bd_addr->address);
}
}
@@ -1039,6 +1052,8 @@
bt_bond_state_t state = BT_BOND_STATE_NONE;
BOOLEAN skip_sdp = FALSE;
+ BTIF_TRACE_DEBUG("%s: bond state=%d", __func__, pairing_cb.state);
+
bdcpy(bd_addr.address, p_auth_cmpl->bd_addr);
if ( (p_auth_cmpl->success == TRUE) && (p_auth_cmpl->key_present) )
{
@@ -1070,6 +1085,9 @@
// Skip SDP for certain HID Devices
if (p_auth_cmpl->success)
{
+ btif_storage_set_remote_addr_type(&bd_addr, p_auth_cmpl->addr_type);
+ btif_update_remote_properties(p_auth_cmpl->bd_addr,
+ p_auth_cmpl->bd_name, NULL, p_auth_cmpl->dev_type);
pairing_cb.timeout_retries = 0;
status = BT_STATUS_SUCCESS;
state = BT_BOND_STATE_BONDED;
@@ -1104,17 +1122,25 @@
{
/* Trigger SDP on the device */
pairing_cb.sdp_attempts = 1;;
+ /* If bonded due to cross-key, save the static address too*/
+ if(pairing_cb.state == BT_BOND_STATE_BONDING &&
+ (bdcmp(p_auth_cmpl->bd_addr, pairing_cb.bd_addr) != 0))
+ {
+ BTIF_TRACE_DEBUG("%s: bonding initiated due to cross key, adding static address",
+ __func__);
+ bdcpy(pairing_cb.static_bdaddr, p_auth_cmpl->bd_addr);
+ }
if(btif_dm_inquiry_in_progress)
btif_dm_cancel_discovery();
btif_dm_get_remote_services(&bd_addr);
- }
- /* Do not call bond_state_changed_cb yet. Wait till fetch remote service is complete */
+ }
+ // Do not call bond_state_changed_cb yet. Wait until remote service discovery is complete
}
else
{
- /*Map the HCI fail reason to bt status */
+ // Map the HCI fail reason to bt status
switch(p_auth_cmpl->fail_reason)
{
case HCI_ERR_PAGE_TIMEOUT:
@@ -1428,16 +1454,23 @@
** bond_state_changed needs to be sent prior to remote_device_property
*/
if ((pairing_cb.state == BT_BOND_STATE_BONDING) &&
- (bdcmp(p_data->disc_res.bd_addr, pairing_cb.bd_addr) == 0)&&
- pairing_cb.sdp_attempts > 0)
+ ((bdcmp(p_data->disc_res.bd_addr, pairing_cb.bd_addr) == 0) ||
+ (bdcmp(p_data->disc_res.bd_addr, pairing_cb.static_bdaddr) == 0)) &&
+ pairing_cb.sdp_attempts > 0)
{
BTIF_TRACE_DEBUG("%s Remote Service SDP done. Call bond_state_changed_cb BONDED",
__FUNCTION__);
pairing_cb.sdp_attempts = 0;
+
+ // If bonding occured due to cross-key pairing, send bonding callback
+ // for static address now
+ if (bdcmp(p_data->disc_res.bd_addr, pairing_cb.static_bdaddr) == 0)
+ bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+
bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDED);
}
- if(p_data->disc_res.num_uuids != 0)
+ if (p_data->disc_res.num_uuids != 0)
{
/* Also write this to the NVRAM */
ret = btif_storage_set_remote_device_property(&bd_addr, &prop);
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
index bb640f0..b532937 100644
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -27,6 +27,7 @@
*
*
*/
+#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
@@ -215,6 +216,7 @@
} while (*p_start != 0);
*p_num_uuid = num;
}
+
static int prop2cfg(bt_bdaddr_t *remote_bd_addr, bt_property_t *prop)
{
bdstr_t bdstr = {0};
@@ -307,6 +309,7 @@
}
return TRUE;
}
+
static int cfg2prop(bt_bdaddr_t *remote_bd_addr, bt_property_t *prop)
{
bdstr_t bdstr = {0};
@@ -542,19 +545,44 @@
return BT_STATUS_SUCCESS;
}
-/************************************************************************************
-** Externs
-************************************************************************************/
+static void btif_read_le_key(const uint8_t key_type, const size_t key_len, bt_bdaddr_t bd_addr,
+ const uint8_t addr_type, const bool add_key, bool *device_added, bool *key_found)
+{
+ assert(device_added);
+ assert(key_found);
-/************************************************************************************
-** Functions
-************************************************************************************/
+ char buffer[100];
+ memset(buffer, 0, sizeof(buffer));
-/** functions are synchronous.
- * functions can be called by both internal modules such as BTIF_DM and by external entiries from HAL via BTIF_context_switch
- * For OUT parameters, caller is expected to provide the memory.
- * Caller is expected to provide a valid pointer to 'property->value' based on the property->type
- */
+ if (btif_storage_get_ble_bonding_key(&bd_addr, key_type, buffer, key_len) == BT_STATUS_SUCCESS)
+ {
+ if (add_key)
+ {
+ BD_ADDR bta_bd_addr;
+ bdcpy(bta_bd_addr, bd_addr.address);
+
+ if (!device_added)
+ {
+ BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
+ *device_added = true;
+ }
+ BTA_DmAddBleKey(bta_bd_addr, (tBTA_LE_KEY_VALUE *)buffer, key_type);
+ }
+
+ *key_found = true;
+ }
+}
+
+/*******************************************************************************
+ * Functions
+ *
+ * Functions are synchronous and can be called by both from internal modules
+ * such as BTIF_DM and by external entiries from HAL via BTIF_context_switch.
+ * For OUT parameters, the caller is expected to provide the memory.
+ * Caller is expected to provide a valid pointer to 'property->value' based on
+ * the property->type.
+ *******************************************************************************/
+
/*******************************************************************************
**
** Function btif_storage_get_adapter_property
@@ -1153,197 +1181,59 @@
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
-bt_status_t btif_in_fetch_bonded_ble_device(const char *remote_bd_addr,int add, btif_bonded_devices_t *p_bonded_devices)
+bt_status_t btif_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, btif_bonded_devices_t *p_bonded_devices)
{
int device_type;
int addr_type;
- char buf[100];
UINT32 i;
bt_bdaddr_t bd_addr;
BD_ADDR bta_bd_addr;
- BOOLEAN is_device_added =FALSE;
- BOOLEAN key_found = FALSE;
- tBTA_LE_KEY_VALUE *p;
+ bool device_added = false;
+ bool key_found = false;
- if(!btif_config_get_int(remote_bd_addr,"DevType", &device_type))
+ if (!btif_config_get_int(remote_bd_addr, "DevType", &device_type))
return BT_STATUS_FAIL;
- if(device_type == BT_DEVICE_TYPE_BLE)
+
+ if ((device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE)
{
- BTIF_TRACE_DEBUG("%s %s found a BLE device", __FUNCTION__,remote_bd_addr);
- string_to_bdaddr(remote_bd_addr, &bd_addr);
- bdcpy(bta_bd_addr, bd_addr.address);
- if (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS)
- {
- return BT_STATUS_FAIL;
- }
+ BTIF_TRACE_DEBUG("%s Found a LE device: %s", __func__, remote_bd_addr);
- memset(buf, 0, sizeof(buf));
- if (btif_storage_get_ble_bonding_key(&bd_addr,
- BTIF_DM_LE_KEY_PENC,
- buf,
- sizeof(btif_dm_ble_penc_keys_t)) == BT_STATUS_SUCCESS)
- {
- if(add)
- {
- if (!is_device_added)
- {
- BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
- is_device_added = TRUE;
- }
- p = (tBTA_LE_KEY_VALUE *)buf;
- for (i=0; i<16; i++)
- {
- BTIF_TRACE_DEBUG("penc_key.ltk[%d]=0x%02x",i,p->penc_key.ltk[i]);
- }
- for (i=0; i<8; i++)
- {
- BTIF_TRACE_DEBUG("penc_key.rand[%d]=0x%02x",i,p->penc_key.rand[i]);
- }
- BTIF_TRACE_DEBUG("p->penc_key.ediv=0x%04x",p->penc_key.ediv);
- BTIF_TRACE_DEBUG("p->penc_key.sec_level=0x%02x",p->penc_key.sec_level);
- BTIF_TRACE_DEBUG("p->penc_key.key_size=0x%02x",p->penc_key.key_size);
- BTA_DmAddBleKey (bta_bd_addr, (tBTA_LE_KEY_VALUE *)buf, BTIF_DM_LE_KEY_PENC);
- }
- key_found = TRUE;
- }
+ string_to_bdaddr(remote_bd_addr, &bd_addr);
+ bdcpy(bta_bd_addr, bd_addr.address);
- memset(buf, 0, sizeof(buf));
- if (btif_storage_get_ble_bonding_key(&bd_addr,
- BTIF_DM_LE_KEY_PID,
- buf,
- sizeof(btif_dm_ble_pid_keys_t)) == BT_STATUS_SUCCESS)
- {
- if(add)
- {
- if (!is_device_added)
- {
- BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
- is_device_added = TRUE;
- }
- p = (tBTA_LE_KEY_VALUE *)buf;
- for (i=0; i<16; i++)
- {
- BTIF_TRACE_DEBUG("p->pid_key.irk[%d]=0x%02x"
- ,i,p->pid_key.irk[i]);
- }
- BTIF_TRACE_DEBUG("p->pid_key.addr_type=%d",p->pid_key.addr_type);
- for (i=0; i<BD_ADDR_LEN; i++)
- {
- BTIF_TRACE_DEBUG("p->pid_key.static_addr[%d]=%02x"
- ,i,p->pid_key.static_addr[i]);
- }
+ if (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS)
+ {
+ addr_type = BLE_ADDR_PUBLIC;
+ btif_storage_set_remote_addr_type(&bd_addr, BLE_ADDR_PUBLIC);
+ }
- BTA_DmAddBleKey (bta_bd_addr, (tBTA_LE_KEY_VALUE *)buf, BTIF_DM_LE_KEY_PID);
- }
- key_found = TRUE;
- }
+ btif_read_le_key(BTIF_DM_LE_KEY_PENC, sizeof(btif_dm_ble_penc_keys_t),
+ bd_addr, addr_type, add, &device_added, &key_found);
- if (btif_storage_get_ble_bonding_key(&bd_addr, BTIF_DM_LE_KEY_LID, buf,
- sizeof(btif_dm_ble_pid_keys_t))== BT_STATUS_SUCCESS)
- {
- if(add)
- {
- if (!is_device_added)
- {
- BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
- is_device_added = TRUE;
- }
- p = (tBTA_LE_KEY_VALUE *)buf;
- for (i=0; i<BD_ADDR_LEN; i++)
- {
- BTIF_TRACE_DEBUG("p->pid_key.static_addr[%d]=%02x"
- ,i,p->pid_key.static_addr[i]);
- }
+ btif_read_le_key(BTIF_DM_LE_KEY_PID, sizeof(btif_dm_ble_pid_keys_t),
+ bd_addr, addr_type, add, &device_added, &key_found);
- BTA_DmAddBleKey (bta_bd_addr, (tBTA_LE_KEY_VALUE *)buf, BTIF_DM_LE_KEY_LID);
- }
- key_found = TRUE;
- }
+ btif_read_le_key(BTIF_DM_LE_KEY_LID, sizeof(btif_dm_ble_pid_keys_t),
+ bd_addr, addr_type, add, &device_added, &key_found);
- memset(buf, 0, sizeof(buf));
- if (btif_storage_get_ble_bonding_key(&bd_addr,
- BTIF_DM_LE_KEY_PCSRK,
- buf,
- sizeof(btif_dm_ble_pcsrk_keys_t)) == BT_STATUS_SUCCESS)
- {
- if(add)
- {
- if (!is_device_added)
- {
- BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
- is_device_added = TRUE;
- }
+ btif_read_le_key(BTIF_DM_LE_KEY_PCSRK, sizeof(btif_dm_ble_pcsrk_keys_t),
+ bd_addr, addr_type, add, &device_added, &key_found);
- p = (tBTA_LE_KEY_VALUE *)buf;
- for (i=0; i<16; i++)
- {
- BTIF_TRACE_DEBUG("p->pcsrk_key.csrk[%d]=0x%02x",i, p->psrk_key.csrk[i]);
- }
- BTIF_TRACE_DEBUG("p->pcsrk_key.counter=0x%08x",p->psrk_key.counter);
- BTIF_TRACE_DEBUG("p->pcsrk_key.sec_level=0x%02x",p->psrk_key.sec_level);
+ btif_read_le_key(BTIF_DM_LE_KEY_LENC, sizeof(btif_dm_ble_lenc_keys_t),
+ bd_addr, addr_type, add, &device_added, &key_found);
- BTA_DmAddBleKey (bta_bd_addr, (tBTA_LE_KEY_VALUE *)buf, BTIF_DM_LE_KEY_PCSRK);
- }
- key_found = TRUE;
- }
+ btif_read_le_key(BTIF_DM_LE_KEY_LCSRK, sizeof(btif_dm_ble_lcsrk_keys_t),
+ bd_addr, addr_type, add, &device_added, &key_found);
- memset(buf, 0, sizeof(buf));
- if (btif_storage_get_ble_bonding_key(&bd_addr,
- BTIF_DM_LE_KEY_LENC,
- buf,
- sizeof(btif_dm_ble_lenc_keys_t)) == BT_STATUS_SUCCESS)
- {
- if(add)
- {
- if (!is_device_added)
- {
- BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
- is_device_added = TRUE;
- }
- p = (tBTA_LE_KEY_VALUE *)buf;
- BTIF_TRACE_DEBUG("p->lenc_key.div=0x%04x",p->lenc_key.div);
- BTIF_TRACE_DEBUG("p->lenc_key.key_size=0x%02x",p->lenc_key.key_size);
- BTIF_TRACE_DEBUG("p->lenc_key.sec_level=0x%02x",p->lenc_key.sec_level);
+ // Fill in the bonded devices
+ if (device_added)
+ {
+ memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++], &bd_addr, sizeof(bt_bdaddr_t));
+ btif_gatts_add_bonded_dev_from_nv(bta_bd_addr);
+ }
- BTA_DmAddBleKey (bta_bd_addr, (tBTA_LE_KEY_VALUE *)buf, BTIF_DM_LE_KEY_LENC);
- }
- key_found = TRUE;
- }
-
- memset(buf, 0, sizeof(buf));
- if (btif_storage_get_ble_bonding_key(&bd_addr,
- BTIF_DM_LE_KEY_LCSRK,
- buf,
- sizeof(btif_dm_ble_lcsrk_keys_t)) == BT_STATUS_SUCCESS)
- {
- if(add)
- {
- if (!is_device_added)
- {
- BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
- is_device_added = TRUE;
- }
- p = (tBTA_LE_KEY_VALUE *)buf;
- BTIF_TRACE_DEBUG("p->lcsrk_key.div=0x%04x",p->lcsrk_key.div);
- BTIF_TRACE_DEBUG("p->lcsrk_key.counter=0x%08x",p->lcsrk_key.counter);
- BTIF_TRACE_DEBUG("p->lcsrk_key.sec_level=0x%02x",p->lcsrk_key.sec_level);
-
- BTA_DmAddBleKey (bta_bd_addr, (tBTA_LE_KEY_VALUE *)buf, BTIF_DM_LE_KEY_LCSRK);
- }
- key_found = TRUE;
- }
-
- /* Fill in the bonded devices */
- if (is_device_added)
- {
- memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++], &bd_addr, sizeof(bt_bdaddr_t));
- btif_gatts_add_bonded_dev_from_nv(bta_bd_addr);
- }
-
- if(key_found)
- return BT_STATUS_SUCCESS;
- else
- return BT_STATUS_FAIL;
+ if (key_found)
+ return BT_STATUS_SUCCESS;
}
return BT_STATUS_FAIL;
}
diff --git a/stack/btm/btm_ble.c b/stack/btm/btm_ble.c
index c72ed3f..8201c57 100644
--- a/stack/btm/btm_ble.c
+++ b/stack/btm/btm_ble.c
@@ -125,11 +125,10 @@
BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name),
(char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
}
- p_dev_rec->device_type = dev_type;
+ p_dev_rec->device_type |= dev_type;
p_dev_rec->ble.ble_addr_type = addr_type;
- BTM_TRACE_DEBUG ("p_dev_rec->device_type =0x%x addr_type=0x%x sec_flags=0x%x",
- dev_type, addr_type, p_dev_rec->sec_flags);
+ memcpy (p_dev_rec->ble.pseudo_addr, bd_addr, BD_ADDR_LEN);
/* sync up with the Inq Data base*/
p_info = BTM_InqDbRead(bd_addr);
if (p_info)
@@ -1395,7 +1394,7 @@
}
/* to notify GATT to send data if any request is pending */
- gatt_notify_enc_cmpl(p_dev_rec->bd_addr);
+ gatt_notify_enc_cmpl(p_dev_rec->ble.pseudo_addr);
}
/*******************************************************************************
diff --git a/stack/btm/btm_ble_addr.c b/stack/btm/btm_ble_addr.c
index 142b8d8..b3a3b33 100644
--- a/stack/btm/btm_ble_addr.c
+++ b/stack/btm/btm_ble_addr.c
@@ -262,6 +262,74 @@
}
return FALSE;
}
+
+/*******************************************************************************
+**
+** Function btm_ble_init_pseudo_addr
+**
+** Description This function is used to initialize pseudo address.
+** If pseudo address is not available, use dummy address
+**
+** Returns TRUE is updated; FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_init_pseudo_addr (tBTM_SEC_DEV_REC *p_dev_rec, BD_ADDR new_pseudo_addr)
+{
+ BD_ADDR dummy_bda = {0};
+
+ if (memcmp(p_dev_rec->ble.pseudo_addr, dummy_bda, BD_ADDR_LEN) == 0)
+ {
+ memcpy(p_dev_rec->ble.pseudo_addr, new_pseudo_addr, BD_ADDR_LEN);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function btm_ble_addr_resolvable
+**
+** Description This function checks if a RPA is resolvable by the device key.
+**
+** Returns TRUE is resolvable; FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_addr_resolvable (BD_ADDR rpa, tBTM_SEC_DEV_REC *p_dev_rec)
+{
+ BOOLEAN rt = FALSE;
+
+ if (!BTM_BLE_IS_RESOLVE_BDA(rpa))
+ return rt;
+
+ UINT8 rand[3];
+ tSMP_ENC output;
+ if ((p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) &&
+ (p_dev_rec->ble.key_type & BTM_LE_KEY_PID))
+ {
+ BTM_TRACE_DEBUG("%s try to resolve", __func__);
+ /* use the 3 MSB of bd address as prand */
+ rand[0] = rpa[2];
+ rand[1] = rpa[1];
+ rand[2] = rpa[0];
+
+ /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */
+ SMP_Encrypt(p_dev_rec->ble.keys.irk, BT_OCTET16_LEN,
+ &rand[0], 3, &output);
+
+ rand[0] = rpa[5];
+ rand[1] = rpa[4];
+ rand[2] = rpa[3];
+
+ if (!memcmp(output.param_buf, &rand[0], 3))
+ {
+ btm_ble_init_pseudo_addr (p_dev_rec, rpa);
+ rt = TRUE;
+ }
+ }
+ return rt;
+}
+
/*******************************************************************************
**
** Function btm_ble_match_random_bda
@@ -276,23 +344,24 @@
static BOOLEAN btm_ble_match_random_bda(UINT16 rec_index)
{
#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
- tBTM_SEC_DEV_REC *p_dev_rec;
- tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
- UINT8 rand[3];
- tSMP_ENC output;
-
/* use the 3 MSB of bd address as prand */
+
+ tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
+ UINT8 rand[3];
rand[0] = p_mgnt_cb->random_bda[2];
rand[1] = p_mgnt_cb->random_bda[1];
rand[2] = p_mgnt_cb->random_bda[0];
- BTM_TRACE_EVENT("btm_ble_match_random_bda rec_index = %d", rec_index);
+ BTM_TRACE_EVENT("%s rec_index = %d", __func__, rec_index);
if (rec_index < BTM_SEC_MAX_DEVICE_RECORDS)
{
+ tSMP_ENC output;
+ tBTM_SEC_DEV_REC *p_dev_rec;
p_dev_rec = &btm_cb.sec_dev_rec[rec_index];
- BTM_TRACE_DEBUG("sec_flags = %02x device_type = %d", p_dev_rec->sec_flags, p_dev_rec->device_type);
+ BTM_TRACE_DEBUG("sec_flags = %02x device_type = %d", p_dev_rec->sec_flags,
+ p_dev_rec->device_type);
if ((p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) &&
(p_dev_rec->ble.key_type & BTM_LE_KEY_PID))
@@ -370,7 +439,7 @@
tBTM_SEC_DEV_REC *p_dev_rec = NULL;
BTM_TRACE_EVENT ("btm_ble_map_bda_to_conn_bda");
if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL &&
- p_dev_rec->device_type == BT_DEVICE_TYPE_BLE)
+ (p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE)
{
if (p_dev_rec->ble.ble_addr_type != BLE_ADDR_PUBLIC)
{
@@ -439,8 +508,12 @@
/* assign the original address to be the current report address */
memcpy(bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
- *p_addr_type = p_dev_rec->ble.ble_addr_type;
+ /* assign the original address to be the current report address */
+ if (!btm_ble_init_pseudo_addr (p_dev_rec, bd_addr))
+ memcpy(bd_addr, p_dev_rec->ble.pseudo_addr, BD_ADDR_LEN);
+
+ *p_addr_type = p_dev_rec->ble.ble_addr_type;
return TRUE;
}
#endif
@@ -487,8 +560,8 @@
UINT8 rra_type)
{
#if BLE_PRIVACY_SPT == TRUE
- UINT8 rra_dummy = FALSE;
- BD_ADDR dummy_bda = {0};
+ UINT8 rra_dummy = FALSE;
+ BD_ADDR dummy_bda = {0};
if (memcmp(dummy_bda, rpa, BD_ADDR_LEN) == 0)
rra_dummy = TRUE;
@@ -515,7 +588,10 @@
__func__, p_sec_rec->ble.active_addr_type);
/* connection refresh remote address */
- tACL_CONN *p_acl = p_acl = btm_bda_to_acl(p_sec_rec->bd_addr, BT_TRANSPORT_LE);
+ tACL_CONN *p_acl = btm_bda_to_acl(p_sec_rec->bd_addr, BT_TRANSPORT_LE);
+ if (p_acl == NULL)
+ p_acl = btm_bda_to_acl(p_sec_rec->ble.pseudo_addr, BT_TRANSPORT_LE);
+
if (p_acl != NULL)
{
if (rra_type == BTM_BLE_ADDR_PSEUDO)
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index 46953db..8912c25 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -2654,8 +2654,10 @@
{
/* new device */
if (p_i == NULL ||
- (/* assume a DUMO device, BR/EDR inquiry is always active */
- p_i && p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE && p_i->scan_rsp))
+ /* assume a DUMO device, BR/EDR inquiry is always active */
+ (p_i &&
+ (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE &&
+ p_i->scan_rsp))
{
BTM_TRACE_WARNING("INQ RES: Extra Response Received...cancelling inquiry..");
diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h
index 9d5c493..adf0837 100644
--- a/stack/btm/btm_ble_int.h
+++ b/stack/btm/btm_ble_int.h
@@ -290,42 +290,43 @@
/*****************************************************
** BLE Inquiry
*****************************************************/
- tBTM_BLE_INQ_CB inq_var;
+ tBTM_BLE_INQ_CB inq_var;
/* observer callback and timer */
tBTM_INQ_RESULTS_CB *p_obs_results_cb;
- tBTM_CMPL_CB *p_obs_cmpl_cb;
- TIMER_LIST_ENT obs_timer_ent;
+ tBTM_CMPL_CB *p_obs_cmpl_cb;
+ TIMER_LIST_ENT obs_timer_ent;
/* background connection procedure cb value */
- tBTM_BLE_CONN_TYPE bg_conn_type;
- UINT16 scan_int;
- UINT16 scan_win;
- tBTM_BLE_SEL_CBACK *p_select_cback;
+ tBTM_BLE_CONN_TYPE bg_conn_type;
+ UINT16 scan_int;
+ UINT16 scan_win;
+ tBTM_BLE_SEL_CBACK *p_select_cback;
/* white list information */
UINT8 white_list_avail_size;
tBTM_BLE_WL_STATE wl_state;
- BUFFER_Q conn_pending_q;
- tBTM_BLE_CONN_ST conn_state;
+ BUFFER_Q conn_pending_q;
+ tBTM_BLE_CONN_ST conn_state;
/* random address management control block */
- tBTM_LE_RANDOM_CB addr_mgnt_cb;
+ tBTM_LE_RANDOM_CB addr_mgnt_cb;
- BOOLEAN enabled;
+ BOOLEAN enabled;
#if BLE_PRIVACY_SPT == TRUE
- BOOLEAN mixed_mode; /* privacy 1.2 mixed mode is on or not */
- tBTM_PRIVACY_MODE privacy_mode; /* privacy mode */
- UINT8 resolving_list_avail_size; /* resolving list available size */
- tBTM_BLE_RESOLVE_Q resolving_list_pend_q;
+ BOOLEAN mixed_mode; /* privacy 1.2 mixed mode is on or not */
+ tBTM_PRIVACY_MODE privacy_mode; /* privacy mode */
+ UINT8 resolving_list_avail_size; /* resolving list available size */
+ UINT8 *irk_list_mask; /* IRK list availability mask, up to max entry bits */
+ tBTM_BLE_RESOLVE_Q resolving_list_pend_q;
#endif
- tBTM_BLE_WL_OP wl_op_q[BTM_BLE_MAX_BG_CONN_DEV_NUM];
+ tBTM_BLE_WL_OP wl_op_q[BTM_BLE_MAX_BG_CONN_DEV_NUM];
/* current BLE link state */
- tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */
- UINT8 link_count[2]; /* total link count master and slave*/
+ tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */
+ UINT8 link_count[2]; /* total link count master and slave*/
} tBTM_BLE_CB;
#ifdef __cplusplus
diff --git a/stack/btm/btm_ble_privacy.c b/stack/btm/btm_ble_privacy.c
index b905eac..9174116 100644
--- a/stack/btm/btm_ble_privacy.c
+++ b/stack/btm/btm_ble_privacy.c
@@ -62,13 +62,12 @@
** Returns void
**
*******************************************************************************/
-void btm_ble_enq_resolving_list_pending(BD_ADDR psuedo_bda, UINT8 op_code)
+void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, UINT8 op_code)
{
- tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
+ tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
- memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], psuedo_bda, BD_ADDR_LEN);
+ memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN);
p_q->resolve_q_action[p_q->q_next] = op_code;
-
p_q->q_next ++;
p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size();
}
@@ -85,13 +84,13 @@
** Returns void
**
*******************************************************************************/
-BOOLEAN btm_ble_brcm_find_resolving_pending_entry(BD_ADDR psuedo_addr, UINT8 action)
+BOOLEAN btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr, UINT8 action)
{
tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
- for (UINT8 i = p_q->q_pending; i != p_q->q_next; )
+ for (UINT8 i = p_q->q_pending; i != p_q->q_next;)
{
- if (memcmp(p_q->resolve_q_random_pseudo[i], psuedo_addr, BD_ADDR_LEN) == 0 &&
+ if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) == 0 &&
action == p_q->resolve_q_action[i])
return TRUE;
@@ -107,52 +106,83 @@
**
** Description dequeue target address from resolving pending operation queue
**
-** Parameters psuedo_addr: psuedo_addr device address
+** Parameters pseudo_addr: pseudo_addr device address
**
** Returns void
**
*******************************************************************************/
-BOOLEAN btm_ble_deq_resolving_pending(BD_ADDR psuedo_addr)
+BOOLEAN btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr)
{
tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
if (p_q->q_next != p_q->q_pending)
{
- memcpy(psuedo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN);
+ memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN);
memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN);
-
p_q->q_pending ++;
p_q->q_pending %= controller_get_interface()->get_ble_resolving_list_max_size();
-
return TRUE;
}
+
return FALSE;
}
/*******************************************************************************
**
-** Function btm_ble_find_resolving_list_entry
+** Function btm_ble_clear_irk_index
**
-** Description find the device record if the pseudo address is currently in
-** the resolving list
+** Description clear IRK list index mask for availability
**
-** Returns pointer to the security device record; NULL otherwise
+** Returns none
**
*******************************************************************************/
-tBTM_SEC_DEV_REC * btm_ble_find_resolving_list_entry(BD_ADDR pseudo_bda)
+void btm_ble_clear_irk_index(UINT8 index)
{
- tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
+ tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
+ UINT8 byte;
+ UINT8 bit;
for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev_rec++)
{
- if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) &&
- (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
- memcmp(p_dev_rec->bd_addr, pseudo_bda, BD_ADDR_LEN) == 0)
+ if (index < controller_get_interface()->get_ble_resolving_list_max_size())
{
- return p_dev_rec ;
+ byte = index / 8;
+ bit = index % 8;
+ btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
}
}
- return NULL;
+}
+
+/*******************************************************************************
+**
+** Function btm_ble_find_irk_index
+**
+** Description find the first available IRK list index
+**
+** Returns index from 0 ~ max (127 default)
+**
+*******************************************************************************/
+UINT8 btm_ble_find_irk_index(void)
+{
+ UINT8 i = 0;
+ UINT8 byte;
+ UINT8 bit;
+
+ while (i < controller_get_interface()->get_ble_resolving_list_max_size())
+ {
+ byte = i / 8;
+ bit = i % 8;
+
+ if ((btm_cb.ble_ctr_cb.irk_list_mask[byte] & (1 << bit)) == 0)
+ {
+ btm_cb.ble_ctr_cb.irk_list_mask[byte] |= (1 << bit);
+ return i;
+ }
+ i++;
+ }
+
+ BTM_TRACE_ERROR ("%s failed, list full", __func__);
+ return i;
}
/*******************************************************************************
@@ -166,21 +196,25 @@
*******************************************************************************/
void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add)
{
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (pseudo_bda);
-
+ tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_bda);
if (p_dev_rec == NULL)
return;
if (add)
{
p_dev_rec->ble.in_controller_list |= BTM_RESOLVING_LIST_BIT;
- /* set resolving list entry index : = max- available - 1*/
- p_dev_rec->ble.resolving_list_index =
- controller_get_interface()->get_ble_resolving_list_max_size() -
- btm_cb.ble_ctr_cb.resolving_list_avail_size - 1;
- } else {
+ if (!controller_get_interface()->supports_ble_privacy())
+ p_dev_rec->ble.resolving_list_index = btm_ble_find_irk_index();
+ }
+ else
+ {
p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
- p_dev_rec->ble.resolving_list_index = 0;
+ if (!controller_get_interface()->supports_ble_privacy())
+ {
+ /* clear IRK list index mask */
+ btm_ble_clear_irk_index(p_dev_rec->ble.resolving_list_index);
+ p_dev_rec->ble.resolving_list_index = 0;
+ }
}
}
@@ -196,31 +230,37 @@
*******************************************************************************/
void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
{
- UINT8 status;
+ UINT8 status = 0;
STREAM_TO_UINT8(status, p);
- BTM_TRACE_DEBUG("%s status = %d", __func__, status);
-
- /* standard HCI status only have one status byte, if greater than 3, VSC complete received */
- if (evt_len >= 3)
- {
- /* VSC complete has one extra byte for op code and list size, skip it here */
- p ++;
- /* updated the available list size, and current list size */
- UINT8 max_resolving_list_size;
- STREAM_TO_UINT8(max_resolving_list_size, p);
- controller_get_interface()->set_ble_resolving_list_max_size(max_resolving_list_size);
- }
+ BTM_TRACE_DEBUG("%s status=%d", __func__, status);
if (status == HCI_SUCCESS)
{
- btm_cb.ble_ctr_cb.resolving_list_avail_size =
+ if (evt_len >= 3)
+ {
+ /* VSC complete has one extra byte for op code and list size, skip it here */
+ p ++;
+
+ /* updated the available list size, and current list size */
+ uint8_t irk_list_sz_max = 0;
+ STREAM_TO_UINT8(irk_list_sz_max, p);
+
+ if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
+ btm_ble_resolving_list_init(irk_list_sz_max);
+
+ uint8_t irk_mask_size = (irk_list_sz_max % 8) ?
+ (irk_list_sz_max / 8 + 1) : (irk_list_sz_max / 8);
+ memset(btm_cb.ble_ctr_cb.irk_list_mask, 0, irk_mask_size);
+ }
+
+ btm_cb.ble_ctr_cb.resolving_list_avail_size =
controller_get_interface()->get_ble_resolving_list_max_size();
- BTM_TRACE_DEBUG("%s resolving_list_avail_size = %d",
+ BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d",
__func__, btm_cb.ble_ctr_cb.resolving_list_avail_size);
- for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++)
+ for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; ++i)
btm_cb.sec_dev_rec[i].ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
}
}
@@ -237,13 +277,13 @@
*******************************************************************************/
void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
{
- UINT8 status;
+ UINT8 status;
STREAM_TO_UINT8(status, p);
BTM_TRACE_DEBUG("%s status = %d", __func__, status);
BD_ADDR pseudo_bda;
- if (!btm_ble_deq_resolving_pending( pseudo_bda))
+ if (!btm_ble_deq_resolving_pending(pseudo_bda))
{
BTM_TRACE_DEBUG("no pending resolving list operation");
return;
@@ -260,7 +300,6 @@
}
else
btm_cb.ble_ctr_cb.resolving_list_avail_size --;
-
}
else if (status == HCI_ERR_MEMORY_FULL) /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED */
{
@@ -281,10 +320,10 @@
*******************************************************************************/
void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
{
- BD_ADDR pseudo_bda;
+ BD_ADDR pseudo_bda;
+ UINT8 status;
- UINT8 status;
- STREAM_TO_UINT8 (status, p);
+ STREAM_TO_UINT8(status, p);
BTM_TRACE_DEBUG("%s status = %d", __func__, status);
@@ -299,14 +338,14 @@
/* proprietary: spec does not have these extra bytes */
if (evt_len > 2)
{
- p ++; /* skip opcode */
+ p ++; /* skip opcode */
STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
}
else
- btm_cb.ble_ctr_cb.resolving_list_avail_size ++;
-
+ btm_cb.ble_ctr_cb.resolving_list_avail_size++;
}
}
+
/*******************************************************************************
**
** Function btm_ble_read_resolving_list_entry_complete
@@ -409,14 +448,19 @@
*******************************************************************************/
tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
{
- tBTM_STATUS st = BTM_NO_RESOURCES;
+ /* if controller does not support RPA offloading or privacy 1.2, skip */
+ if (controller_get_interface()->get_ble_resolving_list_max_size())
+ return BTM_WRONG_MODE;
+ tBTM_STATUS st = BTM_NO_RESOURCES;
if (controller_get_interface()->supports_ble_privacy())
{
- if (btsnd_hcic_ble_rm_device_resolving_list (p_dev_rec->ble.static_addr_type,
- p_dev_rec->ble.static_addr))
+ if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
+ p_dev_rec->ble.static_addr))
st = BTM_CMD_STARTED;
- } else {
+ }
+ else
+ {
UINT8 param[20]= {0};
UINT8 *p = param;
@@ -424,16 +468,14 @@
UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
- st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
- BTM_BLE_META_REMOVE_IRK_LEN,
- param,
- btm_ble_resolving_list_vsc_op_cmpl);
+ st = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
+ BTM_BLE_META_REMOVE_IRK_LEN,
+ param,
+ btm_ble_resolving_list_vsc_op_cmpl);
}
if (st == BTM_CMD_STARTED)
- {
btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);
- }
return st;
}
@@ -494,8 +536,8 @@
if (controller_get_interface()->supports_ble_privacy())
{
if (btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type,
- p_dev_rec->ble.static_addr))
- st = BTM_CMD_STARTED;
+ p_dev_rec->ble.static_addr))
+ st = BTM_CMD_STARTED;
}
else
{
@@ -512,9 +554,8 @@
}
if (st == BTM_CMD_STARTED)
- {
- btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr, BTM_BLE_META_READ_IRK_ENTRY);
- }
+ btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
+ BTM_BLE_META_READ_IRK_ENTRY);
return st;
}
@@ -532,28 +573,31 @@
*******************************************************************************/
BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
{
- BOOLEAN rt = FALSE;
- tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
-
+ BOOLEAN rt = FALSE;
BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
- btm_cb.ble_ctr_cb.privacy_mode);
+ btm_cb.ble_ctr_cb.privacy_mode);
+ /* if controller does not support RPA offloading or privacy 1.2, skip */
+ if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
+ return FALSE;
+
+ BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d",
+ __func__, btm_cb.ble_ctr_cb.privacy_mode);
+
+ /* only add RPA enabled device into resolving list */
if (p_dev_rec != NULL && /* RPA is being used and PID is known */
p_dev_rec->sec_flags & BTM_SEC_IN_USE &&
- /* only add RPA enabled device into resolving list */
- (((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0
- && BTM_BLE_IS_RESOLVE_BDA(p_dev_rec->bd_addr))
- || ((p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0
- && btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE)))
+ ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
+ ((p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0 &&
+ btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE)))
{
if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
BTM_BLE_META_ADD_IRK_ENTRY) == FALSE)
{
- if (p_cb->resolving_list_avail_size > 0)
+ if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0)
{
- btm_ble_update_resolving_list( p_dev_rec->bd_addr, TRUE);
-
+ btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
if (controller_get_interface()->supports_ble_privacy())
{
UINT8 dummy_irk[HCIC_BLE_IRK_SIZE];
@@ -561,9 +605,9 @@
UINT8 *peer_irk;
if (BTM_BLE_IS_RESOLVE_BDA(p_dev_rec->bd_addr))
- peer_irk = p_dev_rec->ble.keys.irk;
+ peer_irk = p_dev_rec->ble.keys.irk;
else
- peer_irk = dummy_irk;
+ peer_irk = dummy_irk;
UINT8 *local_irk;
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE)
@@ -573,17 +617,29 @@
BD_ADDR dummy_bda = {0};
/* for device not assigning static address, use pseudo address as identity */
+ peer_irk = p_dev_rec->ble.keys.irk;
+ local_irk = btm_cb.devcb.id_keys.irk;
+
+ // do not enter IRK if peer or local device does not have privacy turned on
+ // disable, assume IRK indicate privacy could be enabled at any point,
+ // warning: this could take up unnecessary spot in controller resolving list,
+ // and could possible degrade performance; this could prevent conneccting
+ // to peripheral device which has privacy disabled but IRK delivered per
+ // standard privacy 1.2 requirement. Need FW mixed mode support to connect
+ // to both RPA and static address.
if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0)
{
memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
}
+ BTM_TRACE_DEBUG("%s:adding device to controller resolving list", __func__);
+ // use identical IRK for now
rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
- p_dev_rec->ble.static_addr, peer_irk, local_irk); // use identical IRK for now
+ p_dev_rec->ble.static_addr, peer_irk, local_irk);
}
- else
- {
+ else
+ {
UINT8 param[40] = {0};
UINT8 *p = param;
@@ -593,16 +649,16 @@
BDADDR_TO_STREAM(p,p_dev_rec->ble.static_addr);
if (BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
- BTM_BLE_META_ADD_IRK_LEN,
- param,
- btm_ble_resolving_list_vsc_op_cmpl)
- == BTM_CMD_STARTED)
+ BTM_BLE_META_ADD_IRK_LEN,
+ param,
+ btm_ble_resolving_list_vsc_op_cmpl)
+ == BTM_CMD_STARTED)
rt = TRUE;
- }
+ }
if (rt)
- btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
- BTM_BLE_META_ADD_IRK_ENTRY);
+ btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
+ BTM_BLE_META_ADD_IRK_ENTRY);
}
}
else
@@ -631,14 +687,17 @@
*******************************************************************************/
void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
{
- btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
+ btm_ble_update_resolving_list(p_dev_rec->bd_addr, FALSE);
if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
BTM_BLE_META_REMOVE_IRK_ENTRY) == FALSE)
{
+ btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
btm_ble_remove_resolving_list_entry(p_dev_rec);
- } else {
+ }
+ else
+ {
BTM_TRACE_DEBUG("Device not in resolving list");
}
}
@@ -679,6 +738,10 @@
*******************************************************************************/
void btm_ble_disable_resolving_list(void)
{
+ /* if controller does not support RPA offloading or privacy 1.2, skip */
+ if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
+ return;
+
if (btm_cb.ble_ctr_cb.enabled)
{
if (!controller_get_interface()->supports_ble_privacy())
@@ -725,7 +788,7 @@
BOOLEAN btm_ble_resolving_list_empty(void)
{
return (controller_get_interface()->get_ble_resolving_list_max_size() ==
- btm_cb.ble_ctr_cb.resolving_list_avail_size);
+ btm_cb.ble_ctr_cb.resolving_list_avail_size);
}
/*******************************************************************************
@@ -752,7 +815,6 @@
btm_ble_enable_resolving_list();
else
btm_ble_disable_resolving_list();
-
return;
}
@@ -782,13 +844,18 @@
*******************************************************************************/
void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
{
- tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
+ tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
+ UINT8 irk_mask_size = (max_irk_list_sz % 8) ?
+ (max_irk_list_sz/8 + 1) : (max_irk_list_sz/8);
if (max_irk_list_sz > 0)
{
- p_q->resolve_q_random_pseudo = (BD_ADDR*)GKI_getbuf (sizeof (BD_ADDR) *
- max_irk_list_sz);
- p_q->resolve_q_action = (UINT8*) GKI_getbuf (max_irk_list_sz);
+ p_q->resolve_q_random_pseudo = (BD_ADDR *)GKI_getbuf(sizeof(BD_ADDR) * max_irk_list_sz);
+ p_q->resolve_q_action = (UINT8 *)GKI_getbuf(max_irk_list_sz);
+
+ /* RPA offloading feature */
+ if (btm_cb.ble_ctr_cb.irk_list_mask == NULL)
+ btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)GKI_getbuf(irk_mask_size);
BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
}
@@ -810,7 +877,7 @@
*******************************************************************************/
void btm_ble_resolving_list_cleanup(void)
{
- tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
+ tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
if (p_q->resolve_q_random_pseudo)
GKI_freebuf(p_q->resolve_q_random_pseudo);
@@ -819,5 +886,9 @@
GKI_freebuf(p_q->resolve_q_action);
controller_get_interface()->set_ble_resolving_list_max_size(0);
+ if (btm_cb.ble_ctr_cb.irk_list_mask)
+ GKI_freebuf(btm_cb.ble_ctr_cb.irk_list_mask);
+
+ btm_cb.ble_ctr_cb.irk_list_mask = NULL;
}
#endif
diff --git a/stack/btm/btm_dev.c b/stack/btm/btm_dev.c
index 3053dbe..faae4f5 100644
--- a/stack/btm/btm_dev.c
+++ b/stack/btm/btm_dev.c
@@ -155,6 +155,7 @@
#endif
p_dev_rec->rmt_io_caps = io_cap;
+ p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
return(TRUE);
}
@@ -427,18 +428,26 @@
** Returns Pointer to the record or NULL
**
*******************************************************************************/
-tBTM_SEC_DEV_REC *btm_find_dev (BD_ADDR bd_addr)
+tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr)
{
tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
- int i;
if (bd_addr)
{
- for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
+ for (uint8_t i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
{
- if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
- && (!memcmp (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN)))
- return(p_dev_rec);
+ if (p_dev_rec->sec_flags & BTM_SEC_IN_USE)
+ {
+ if (!memcmp (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN))
+ return(p_dev_rec);
+
+ // If a LE random address is looking for device record
+ if (!memcmp(p_dev_rec->ble.pseudo_addr, bd_addr, BD_ADDR_LEN))
+ return (p_dev_rec);
+
+ if (btm_ble_addr_resolvable(bd_addr, p_dev_rec))
+ return(p_dev_rec);
+ }
}
}
return(NULL);
@@ -446,6 +455,59 @@
/*******************************************************************************
**
+** Function btm_consolidate_dev
+**
+** Description combine security records if identified as same peer
+**
+** Returns none
+**
+*******************************************************************************/
+void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec)
+{
+ tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
+ tBTM_SEC_DEV_REC temp_rec = *p_target_rec;
+ BD_ADDR dummy_bda = {0};
+
+ BTM_TRACE_DEBUG("%s", __func__);
+
+ for (uint8_t i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
+ {
+ if (p_target_rec!= p_dev_rec && p_dev_rec->sec_flags & BTM_SEC_IN_USE)
+ {
+ if (!memcmp (p_dev_rec->bd_addr, p_target_rec->bd_addr, BD_ADDR_LEN))
+ {
+ memcpy(p_target_rec, p_dev_rec, sizeof(tBTM_SEC_DEV_REC));
+ p_target_rec->ble = temp_rec.ble;
+ p_target_rec->enc_key_size = temp_rec.enc_key_size;
+ p_target_rec->ble_hci_handle = temp_rec.ble_hci_handle;
+ p_target_rec->conn_params = temp_rec.conn_params;
+ p_target_rec->device_type |= temp_rec.device_type;
+ p_target_rec->sec_flags |= temp_rec.sec_flags;
+
+ p_target_rec->new_encryption_key_is_p256 = temp_rec.new_encryption_key_is_p256;
+ p_target_rec->no_smp_on_br = temp_rec.no_smp_on_br;
+ /* mark the combined record as unused */
+ p_dev_rec->sec_flags &= ~BTM_SEC_IN_USE;
+ break;
+ }
+
+ /* an RPA device entry is a duplicate of the target record */
+ if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec))
+ {
+ if (memcmp(p_target_rec->ble.pseudo_addr, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)
+ {
+ p_target_rec->ble.ble_addr_type = p_dev_rec->ble.ble_addr_type;
+ p_target_rec->device_type |= p_dev_rec->device_type;
+ p_dev_rec->sec_flags &= ~BTM_SEC_IN_USE;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
** Function btm_find_or_alloc_dev
**
** Description Look for the record in the device database for the record
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index ec0a03f..a8a1090 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -467,6 +467,7 @@
typedef struct
{
+ BD_ADDR pseudo_addr; /* LE pseudo address of the device if different from device address */
tBLE_ADDR_TYPE ble_addr_type; /* LE device type: public or random address */
tBLE_ADDR_TYPE static_addr_type; /* static address type */
BD_ADDR static_addr; /* static address */
@@ -585,6 +586,9 @@
** Link encrypted with such LK can be used
** for SM over BR/EDR.
*/
+ BOOLEAN no_smp_on_br; /* if set to TRUE then SMP on BR/EDR doesn't */
+ /* work, i.e. link keys crosspairing */
+ /* SC BR/EDR->SC LE doesn't happen */
#endif
// btla-specific ++
@@ -1004,10 +1008,10 @@
extern void btm_ble_add_2_white_list_complete(UINT8 status);
extern void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len);
extern void btm_ble_clear_white_list_complete(UINT8 *p, UINT16 evt_len);
+extern BOOLEAN btm_ble_addr_resolvable(BD_ADDR rpa, tBTM_SEC_DEV_REC *p_dev_rec);
extern tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec);
extern BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec);
extern void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec);
-extern tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec);
#endif /* BLE_INCLUDED */
/* Vendor Specific Command complete evt handler */
@@ -1070,7 +1074,9 @@
extern void btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC *p_dev_rec);
extern BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT8 *p_found_idx, tBTM_SEC_DEV_REC **p_rec);
extern BOOLEAN btm_sec_is_a_bonded_dev (BD_ADDR bda);
+extern void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec);
extern BOOLEAN btm_sec_is_le_capable_dev (BD_ADDR bda);
+extern BOOLEAN btm_ble_init_pseudo_addr (tBTM_SEC_DEV_REC *p_dev_rec, BD_ADDR new_pseudo_addr);
#endif /* BLE_INCLUDED */
extern tINQ_DB_ENT *btm_inq_db_new (BD_ADDR p_bda);
diff --git a/stack/btm/btm_sec.c b/stack/btm/btm_sec.c
index c806782..33d0efc 100644
--- a/stack/btm/btm_sec.c
+++ b/stack/btm/btm_sec.c
@@ -995,6 +995,7 @@
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
if (transport == BT_TRANSPORT_LE)
{
+ btm_ble_init_pseudo_addr (p_dev_rec, bd_addr);
p_dev_rec->sec_flags &= ~ BTM_SEC_LE_MASK;
if (SMP_Pair(bd_addr) == SMP_STARTED)
@@ -4058,20 +4059,25 @@
else
{
BTM_TRACE_DEBUG ("TRYING TO DECIDE IF CAN USE SMP_BR_CHNL");
- if (p_dev_rec->new_encryption_key_is_p256 && (btm_sec_use_smp_br_chnl(p_dev_rec)))
+ if (p_dev_rec->new_encryption_key_is_p256 && (btm_sec_use_smp_br_chnl(p_dev_rec))
+ /* no LE keys are available, do deriving */
+ && (!(p_dev_rec->sec_flags &BTM_SEC_LE_LINK_KEY_KNOWN) ||
+ /* or BR key is higher security than existing LE keys */
+ (!(p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED) &&
+ (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED))))
{
BTM_TRACE_DEBUG ("link encrypted afer dedic bonding can use SMP_BR_CHNL");
if (btm_sec_is_master(p_dev_rec))
{
- // Encryption is required to start SM over BR/EDR.
- // Indicate that this is encryption after authentication.
+ // Encryption is required to start SM over BR/EDR
+ // indicate that this is encryption after authentication
BTM_SetEncryption(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR, NULL, NULL);
}
}
-
l2cu_start_post_bond_timer (p_dev_rec->hci_handle);
}
+
return;
}
@@ -4150,7 +4156,8 @@
/* For transaction collision we need to wait and repeat. There is no need */
/* for random timeout because only slave should receive the result */
- if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) || (status == HCI_ERR_DIFF_TRANSACTION_COLLISION))
+ if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) ||
+ (status == HCI_ERR_DIFF_TRANSACTION_COLLISION))
{
btm_sec_auth_collision(handle);
return;
@@ -4181,15 +4188,14 @@
BTM_TRACE_DEBUG ("after update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags );
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
- if (acl_idx != MAX_L2CAP_LINKS )
+ if (acl_idx != MAX_L2CAP_LINKS)
p_acl = &btm_cb.acl_db[acl_idx];
btm_sec_check_pending_enc_req (p_dev_rec, p_acl->transport, encr_enable);
if (p_acl && p_acl->transport == BT_TRANSPORT_LE)
{
- if (status == HCI_ERR_KEY_MISSING ||
- status == HCI_ERR_AUTH_FAILURE ||
+ if (status == HCI_ERR_KEY_MISSING || status == HCI_ERR_AUTH_FAILURE ||
status == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE)
{
p_dev_rec->sec_flags &= ~ (BTM_SEC_LE_LINK_KEY_KNOWN);
@@ -4199,29 +4205,44 @@
return;
}
else
+ {
/* BR/EDR connection, update the encryption key size to be 16 as always */
p_dev_rec->enc_key_size = 16;
+ }
- BTM_TRACE_DEBUG ("in btm_sec_encrypt_change new_encr_key_256 is %d",
- p_dev_rec->new_encryption_key_is_p256);
+ BTM_TRACE_DEBUG ("in %s new_encr_key_256 is %d",
+ __func__, p_dev_rec->new_encryption_key_is_p256);
if ((status == HCI_SUCCESS) && encr_enable && (p_dev_rec->hci_handle == handle))
{
if (p_dev_rec->new_encryption_key_is_p256)
{
if (btm_sec_use_smp_br_chnl(p_dev_rec) &&
- btm_sec_is_master(p_dev_rec))
+ btm_sec_is_master(p_dev_rec) &&
+ /* if LE key is not known, do deriving */
+ (!(p_dev_rec->sec_flags &BTM_SEC_LE_LINK_KEY_KNOWN) ||
+ /* or BR key is higher security than existing LE keys */
+ (!(p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED)
+ && (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED))))
{
/* BR/EDR is encrypted with LK that can be used to derive LE LTK */
p_dev_rec->new_encryption_key_is_p256 = FALSE;
- BTM_TRACE_DEBUG ("btm_sec_encrypt_change start SM over BR/EDR");
- SMP_BR_PairWith(p_dev_rec->bd_addr);
+ if (p_dev_rec->no_smp_on_br)
+ {
+ BTM_TRACE_DEBUG ("%s NO SM over BR/EDR", __func__);
+ }
+ else
+ {
+ BTM_TRACE_DEBUG ("%s start SM over BR/EDR", __func__);
+ SMP_BR_PairWith(p_dev_rec->bd_addr);
+ }
}
}
else
- { /* BR/EDR is successfully encrypted. Correct LK type if needed
- (BR/EDR LK derived from LE LTK was used for encryption) */
+ {
+ // BR/EDR is successfully encrypted. Correct LK type if needed
+ // (BR/EDR LK derived from LE LTK was used for encryption)
if ((encr_enable == 1) && /* encryption is ON for SSP */
/* LK type is for BR/EDR SC */
(p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256 ||
@@ -4254,7 +4275,6 @@
}
p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
-
/* If encryption setup failed, notify the waiting layer */
if (status != HCI_SUCCESS)
{
@@ -4264,7 +4284,6 @@
/* Encryption setup succeeded, execute the next security procedure, if any */
status = (UINT8)btm_sec_execute_procedure (p_dev_rec);
-
/* If there is no next procedure, or procedure failed to start, notify the caller */
if (status != BTM_CMD_STARTED)
btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
@@ -4808,23 +4827,22 @@
p_link_key, p_dev_rec->link_key_type);
}
}
-#if BTM_CROSS_TRANSP_KEY_DERIVATION == TRUE
else
{
if ((p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256) ||
(p_dev_rec->link_key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256))
{
- p_dev_rec->new_encr_key_256 = TRUE;
+ p_dev_rec->new_encryption_key_is_p256 = TRUE;
BTM_TRACE_DEBUG ("%s set new_encr_key_256 to %d",
- __func__, p_dev_rec->new_encr_key_256);
+ __func__, p_dev_rec->new_encryption_key_is_p256);
}
}
-#endif
/* If name is not known at this point delay calling callback until the name is */
/* resolved. Unless it is a HID Device and we really need to send all link keys. */
if ((!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
- && ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) != BTM_COD_MAJOR_PERIPHERAL)) )
+ && ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) != BTM_COD_MAJOR_PERIPHERAL))
+ && !ltk_derived_lk)
{
BTM_TRACE_EVENT ("btm_sec_link_key_notification() Delayed BDA: %08x%04x Type:%d",
(p_bda[0]<<24) + (p_bda[1]<<16) + (p_bda[2]<<8) + p_bda[3],
@@ -4846,7 +4864,9 @@
/* If its not us who perform authentication, we should tell stackserver */
/* that some authentication has been completed */
/* This is required when different entities receive link notification and auth complete */
- if (!(p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE))
+ if (!(p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE)
+ /* for derived key, always send authentication callback for BR channel */
+ || ltk_derived_lk)
{
if (btm_cb.api.p_auth_complete_callback)
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
@@ -4860,8 +4880,17 @@
{
if (btm_cb.api.p_link_key_callback)
{
- (*btm_cb.api.p_link_key_callback) (p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name,
- p_link_key, p_dev_rec->link_key_type);
+ if (ltk_derived_lk)
+ {
+ BTM_TRACE_DEBUG ("btm_sec_link_key_notification() LTK derived LK is saved already"
+ " (key_type = %d)", p_dev_rec->link_key_type);
+ }
+ else
+ {
+ (*btm_cb.api.p_link_key_callback) (p_bda, p_dev_rec->dev_class,
+ p_dev_rec->sec_bd_name,
+ p_link_key, p_dev_rec->link_key_type);
+ }
}
}
}
@@ -5839,12 +5868,15 @@
void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN is_le_transport)
{
tBTM_SEC_CALLBACK *p_callback = p_dev_rec->p_callback;
- tBT_TRANSPORT transport = is_le_transport ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR;
if (p_dev_rec->p_callback)
{
p_dev_rec->p_callback = NULL;
- (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, res);
+
+ if (is_le_transport)
+ (*p_callback) (p_dev_rec->ble.pseudo_addr, BT_TRANSPORT_LE, p_dev_rec->p_ref_data, res);
+ else
+ (*p_callback) (p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR, p_dev_rec->p_ref_data, res);
}
btm_sec_check_pending_reqs();
@@ -6214,11 +6246,8 @@
BOOLEAN le_capable = FALSE;
#if (BLE_INCLUDED== TRUE)
- if (p_dev_rec && ((p_dev_rec->device_type == BT_DEVICE_TYPE_DUMO) ||
- (p_dev_rec->device_type == BT_DEVICE_TYPE_BLE) ) )
- {
+ if (p_dev_rec && (p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE)
le_capable = TRUE;
- }
#endif
return le_capable;
}
diff --git a/stack/include/btm_api.h b/stack/include/btm_api.h
index de0b195..a4d1ba3 100644
--- a/stack/include/btm_api.h
+++ b/stack/include/btm_api.h
@@ -1399,6 +1399,10 @@
#define BTM_AUTH_BONDS 6 /* the general/dedicated bonding bits */
#define BTM_AUTH_YN_BIT 1 /* this is the Yes or No bit */
+#define BTM_BLE_INITIATOR_KEY_SIZE 15
+#define BTM_BLE_RESPONDER_KEY_SIZE 15
+#define BTM_BLE_MAX_KEY_SIZE 16
+
typedef UINT8 tBTM_AUTH_REQ;
enum
@@ -1613,9 +1617,10 @@
/* data type for tBTM_LE_COMPLT */
typedef struct
{
- UINT8 reason;
- UINT8 sec_level;
- BOOLEAN is_pair_cancel;
+ UINT8 reason;
+ UINT8 sec_level;
+ BOOLEAN is_pair_cancel;
+ BOOLEAN smp_over_br;
}tBTM_LE_COMPLT;
#endif
diff --git a/stack/include/smp_api.h b/stack/include/smp_api.h
index 37669b4..62ef1db 100644
--- a/stack/include/smp_api.h
+++ b/stack/include/smp_api.h
@@ -203,6 +203,14 @@
#define SMP_SEC_DEFAULT_KEY (SMP_SEC_KEY_TYPE_ENC | SMP_SEC_KEY_TYPE_ID | \
SMP_SEC_KEY_TYPE_CSRK | SMP_SEC_KEY_TYPE_LK)
+#define SMP_SC_KEY_STARTED 0 /* passkey entry started */
+#define SMP_SC_KEY_ENTERED 1 /* passkey digit entered */
+#define SMP_SC_KEY_ERASED 2 /* passkey digit erased */
+#define SMP_SC_KEY_CLEARED 3 /* passkey cleared */
+#define SMP_SC_KEY_COMPLT 4 /* passkey entry completed */
+#define SMP_SC_KEY_OUT_OF_RANGE 5 /* out of range */
+typedef UINT8 tSMP_SC_KEY_TYPE;
+
/* data type for BTM_SP_IO_REQ_EVT */
typedef struct
{
@@ -216,9 +224,10 @@
typedef struct
{
- tSMP_STATUS reason;
- tSMP_SEC_LEVEL sec_level;
- BOOLEAN is_pair_cancel;
+ tSMP_STATUS reason;
+ tSMP_SEC_LEVEL sec_level;
+ BOOLEAN is_pair_cancel;
+ BOOLEAN smp_over_br;
} tSMP_CMPL;
typedef struct
diff --git a/stack/l2cap/l2c_link.c b/stack/l2cap/l2c_link.c
index fa2fcce..97bf58d 100644
--- a/stack/l2cap/l2c_link.c
+++ b/stack/l2cap/l2c_link.c
@@ -424,16 +424,21 @@
if (p_lcb->ccb_queue.p_first_ccb != NULL || p_lcb->p_pending_ccb)
{
L2CAP_TRACE_DEBUG("l2c_link_hci_disc_comp: Restarting pending ACL request");
+ transport = p_lcb->transport;
#if BLE_INCLUDED == TRUE
/* for LE link, always drop and re-open to ensure to get LE remote feature */
if (p_lcb->transport == BT_TRANSPORT_LE)
{
- BD_ADDR bd_addr;
- memcpy(bd_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
- l2cu_release_lcb (p_lcb);
- // make sure Tx credit allocation is redistributed in between links by calling l2cu_allocate_lcb
- p_lcb = l2cu_allocate_lcb (bd_addr, FALSE, BT_TRANSPORT_LE);
- transport = BT_TRANSPORT_LE;
+ l2cb.is_ble_connecting = FALSE;
+ btm_acl_removed (p_lcb->remote_bd_addr, p_lcb->transport);
+ /* Release any held buffers */
+ BT_HDR *p_buf;
+ while (!list_is_empty(p_lcb->link_xmit_data_q))
+ {
+ p_buf = list_front(p_lcb->link_xmit_data_q);
+ list_remove(p_lcb->link_xmit_data_q, p_buf);
+ GKI_freebuf(p_buf);
+ }
}
else
#endif
diff --git a/stack/l2cap/l2c_main.c b/stack/l2cap/l2c_main.c
index 634f1cd..212d5df 100644
--- a/stack/l2cap/l2c_main.c
+++ b/stack/l2cap/l2c_main.c
@@ -186,6 +186,11 @@
STREAM_TO_UINT16 (l2cap_len, p);
STREAM_TO_UINT16 (rcv_cid, p);
+ /* for BLE channel, always notify connection when ACL data received on the link */
+ if (p_lcb && p_lcb->transport == BT_TRANSPORT_LE && p_lcb->link_state != LST_DISCONNECTING)
+ /* only process fixed channel data as channel open indication when link is not in disconnecting mode */
+ l2cble_notify_le_connection(p_lcb->remote_bd_addr);
+
/* Find the CCB for this CID */
if (rcv_cid >= L2CAP_BASE_APPL_CID)
{
@@ -261,14 +266,10 @@
counter_add("l2cap.fix.rx.pkts", 1);
/* If no CCB for this channel, allocate one */
if (p_lcb &&
- /* discard fixed channel data when link is disconnecting */
+ /* only process fixed channel data when link is open or wait for data indication */
(p_lcb->link_state != LST_DISCONNECTING) &&
- l2cu_initialize_fixed_ccb (p_lcb, rcv_cid,
- &l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
+ l2cu_initialize_fixed_ccb (p_lcb, rcv_cid, &l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
{
-#if(defined BLE_INCLUDED && (BLE_INCLUDED == TRUE))
- l2cble_notify_le_connection(p_lcb->remote_bd_addr);
-#endif
p_ccb = p_lcb->p_fixed_ccbs[rcv_cid - L2CAP_FIRST_FIXED_CHNL];
if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c
index 397a2ca..f1c6936 100644
--- a/stack/smp/smp_act.c
+++ b/stack/smp/smp_act.c
@@ -46,7 +46,7 @@
smp_generate_ltk,
smp_send_id_info,
smp_generate_csrk,
- smp_derive_link_key_from_long_term_key
+ smp_set_derive_link_key
};
/*******************************************************************************
@@ -58,7 +58,8 @@
SMP_TRACE_DEBUG("%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x",
__func__, p_cb->role, recv, p_cb->local_i_key, p_cb->local_r_key);
- if (((p_cb->le_secure_connections_mode_is_used) || (p_cb->smp_over_br)) &&
+ if (((p_cb->le_secure_connections_mode_is_used) ||
+ (p_cb->smp_over_br)) &&
((key_type == SMP_SEC_KEY_TYPE_ENC) || (key_type == SMP_SEC_KEY_TYPE_LK)))
{
/* in LE SC mode LTK, CSRK and BR/EDR LK are derived locally instead of
@@ -176,11 +177,9 @@
p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
}
-#if BTM_CROSS_TRANSP_KEY_DERIVATION == FALSE
SMP_TRACE_WARNING ("Cross transport key derivation is not supported");
p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
-#endif
SMP_TRACE_WARNING("set auth_req: 0x%02x, local_i_key: 0x%02x, local_r_key: 0x%02x",
p_cb->loc_auth_req, p_cb->local_i_key, p_cb->local_r_key);
@@ -986,6 +985,11 @@
STREAM_TO_BDADDR(pid_key.static_addr, p);
memcpy(pid_key.irk, p_cb->tk, BT_OCTET16_LEN);
+ /* to use as BD_ADDR for lk derived from ltk */
+ p_cb->id_addr_rcvd = TRUE;
+ p_cb->id_addr_type = pid_key.addr_type;
+ memcpy(p_cb->id_addr, pid_key.static_addr, BD_ADDR_LEN);
+
/* store the ID key from peer device */
if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND))
btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PID,
@@ -1217,8 +1221,8 @@
SMP_TRACE_DEBUG("%s role=%d (0-master) r_keys=0x%x i_keys=0x%x",
__func__, p_cb->role, p_cb->local_r_key, p_cb->local_i_key);
- if (p_cb->role == HCI_ROLE_SLAVE||
- (!p_cb->local_r_key && p_cb->role == HCI_ROLE_MASTER))
+ if (p_cb->role == HCI_ROLE_SLAVE ||
+ (!p_cb->local_r_key && p_cb->role == HCI_ROLE_MASTER))
{
smp_key_pick_key(p_cb, p_data);
}
@@ -1228,6 +1232,12 @@
/* state check to prevent re-entrant */
if (smp_get_state() == SMP_STATE_BOND_PENDING)
{
+ if (p_cb->derive_lk)
+ {
+ smp_derive_link_key_from_long_term_key(p_cb, NULL);
+ p_cb->derive_lk = FALSE;
+ }
+
if (p_cb->total_tx_unacked == 0)
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
else
@@ -1976,6 +1986,25 @@
/*******************************************************************************
**
+** Function smp_set_derive_link_key
+**
+** Description This function is called to set flag that indicates that
+** BR/EDR LK has to be derived from LTK after all keys are
+** distributed.
+**
+** Returns void
+**
+*******************************************************************************/
+void smp_set_derive_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
+{
+ SMP_TRACE_DEBUG ("%s", __func__);
+ p_cb->derive_lk = TRUE;
+ smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_LK, FALSE);
+ smp_key_distribution(p_cb, NULL);
+}
+
+/*******************************************************************************
+**
** Function smp_derive_link_key_from_long_term_key
**
** Description This function is called to derive BR/EDR LK from LTK.
@@ -1996,7 +2025,6 @@
}
smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_LK, FALSE);
-
SMP_TRACE_DEBUG("%s successfully completed", __FUNCTION__);
smp_key_distribution(p_cb, NULL);
}
diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h
index 24aa3ec..52b0301 100644
--- a/stack/smp/smp_int.h
+++ b/stack/smp/smp_int.h
@@ -270,6 +270,10 @@
UINT8 trace_level;
BD_ADDR pairing_bda;
tSMP_STATE state;
+ BOOLEAN derive_lk;
+ BOOLEAN id_addr_rcvd;
+ tBLE_ADDR_TYPE id_addr_type;
+ BD_ADDR id_addr;
BOOLEAN smp_over_br;
tSMP_BR_STATE br_state; /* if SMP over BR/ERD has priority over SMP */
UINT8 failure;
@@ -305,8 +309,9 @@
/* either in Secure Connections mode or not at all */
tSMP_ASSO_MODEL selected_association_model;
BOOLEAN le_secure_connections_mode_is_used;
- tBTM_SP_KEY_TYPE local_keypress_notification;
- tBTM_SP_KEY_TYPE peer_keypress_notification;
+ BOOLEAN le_sc_kp_notif_is_used;
+ tSMP_SC_KEY_TYPE local_keypress_notification;
+ tSMP_SC_KEY_TYPE peer_keypress_notification;
UINT8 round; /* authentication stage 1 round for passkey association model */
UINT32 number_to_display;
BT_OCTET16 mac_key;
@@ -447,9 +452,10 @@
extern void smp_start_passkey_verification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_process_secure_connection_oob_data(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_process_secure_connection_long_term_key(void);
-extern void smp_derive_link_key_from_long_term_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_set_local_oob_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
+extern void smp_set_derive_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
+extern void smp_derive_link_key_from_long_term_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_br_process_pairing_command(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_br_process_security_grant(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_br_process_slave_keys_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
diff --git a/stack/smp/smp_keys.c b/stack/smp/smp_keys.c
index 47d0125..f301530 100644
--- a/stack/smp/smp_keys.c
+++ b/stack/smp/smp_keys.c
@@ -1926,9 +1926,27 @@
BOOLEAN smp_calculate_link_key_from_long_term_key(tSMP_CB *p_cb)
{
tBTM_SEC_DEV_REC *p_dev_rec;
+ BD_ADDR bda_for_lk;
+ tBLE_ADDR_TYPE conn_addr_type;
SMP_TRACE_DEBUG ("%s", __func__);
+ if (p_cb->id_addr_rcvd && p_cb->id_addr_type == BLE_ADDR_PUBLIC)
+ {
+ SMP_TRACE_DEBUG ("Use rcvd identity address as BD_ADDR of LK rcvd identity address");
+ memcpy(bda_for_lk, p_cb->id_addr, BD_ADDR_LEN);
+ }
+ else if ((BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, bda_for_lk, &conn_addr_type)) &&
+ conn_addr_type == BLE_ADDR_PUBLIC)
+ {
+ SMP_TRACE_DEBUG ("Use rcvd connection address as BD_ADDR of LK");
+ }
+ else
+ {
+ SMP_TRACE_WARNING ("Don't have peer public address to associate with LK");
+ return FALSE;
+ }
+
if ((p_dev_rec = btm_find_dev (p_cb->pairing_bda)) == NULL)
{
SMP_TRACE_ERROR("%s failed to find Security Record", __func__);
@@ -1989,7 +2007,7 @@
p = notif_link_key;
ARRAY16_TO_STREAM(p, link_key);
- btm_sec_link_key_notification (p_cb->pairing_bda, notif_link_key, link_key_type);
+ btm_sec_link_key_notification (bda_for_lk, notif_link_key, link_key_type);
SMP_TRACE_EVENT ("%s is completed", __func__);
}
diff --git a/stack/smp/smp_utils.c b/stack/smp/smp_utils.c
index 9f2e532..3e592f2 100644
--- a/stack/smp/smp_utils.c
+++ b/stack/smp/smp_utils.c
@@ -942,6 +942,7 @@
SMP_TRACE_DEBUG ("smp_proc_pairing_cmpl ");
evt_data.cmplt.reason = p_cb->status;
+ evt_data.cmplt.smp_over_br = p_cb->smp_over_br;
if (p_cb->status == SMP_SUCCESS)
evt_data.cmplt.sec_level = p_cb->sec_level;