Fix device/address types and IRK value handling
Handles the device and address types based on BD address
and provides the IRK values as available.
Change-Id: I351e0aea7f5e55caefa405b34261c75e78306552
diff --git a/system/stack/btm/btm_ble.c b/system/stack/btm/btm_ble.c
index 3eed315..2bd6132 100644
--- a/system/stack/btm/btm_ble.c
+++ b/system/stack/btm/btm_ble.c
@@ -621,11 +621,11 @@
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (remote_bda);
tBTM_INQ_INFO *p_inq_info = BTM_InqDbRead(remote_bda);
- *p_dev_type = BT_DEVICE_TYPE_BREDR;
*p_addr_type = BLE_ADDR_PUBLIC;
if (!p_dev_rec)
{
+ *p_dev_type = BT_DEVICE_TYPE_BREDR;
/* Check with the BT manager if details about remote device are known */
if (p_inq_info != NULL)
{
@@ -644,8 +644,22 @@
p_dev_rec->device_type = p_inq_info->results.device_type;
p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type;
}
- *p_dev_type = p_dev_rec->device_type;
- *p_addr_type = p_dev_rec->ble.ble_addr_type;
+ if (memcmp(p_dev_rec->bd_addr, remote_bda, BD_ADDR_LEN) == 0 &&
+ memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0)
+ {
+ *p_dev_type = p_dev_rec->device_type;
+ *p_addr_type = p_dev_rec->ble.ble_addr_type;
+ }
+ else if (memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0)
+ {
+ *p_dev_type = BT_DEVICE_TYPE_BLE;
+ *p_addr_type = p_dev_rec->ble.ble_addr_type;
+ }
+ else /* matching static adddress only */
+ {
+ *p_dev_type = BT_DEVICE_TYPE_BREDR;
+ *p_addr_type = BLE_ADDR_PUBLIC;
+ }
}
@@ -1046,6 +1060,10 @@
p_rec->ble.static_addr_type = p_keys->pid_key.addr_type;
p_rec->ble.key_type |= BTM_LE_KEY_PID;
BTM_TRACE_DEBUG("BTM_LE_KEY_PID key_type=0x%x save peer IRK", p_rec->ble.key_type);
+ /* update device record address as static address */
+ memcpy(p_rec->bd_addr, p_keys->pid_key.static_addr, BD_ADDR_LEN);
+ /* combine DUMO device security record if needed */
+ btm_consolidate_dev(p_rec);
break;
case BTM_LE_KEY_PCSRK:
@@ -1751,7 +1769,8 @@
if (!p_dev_rec)
{
/* There is no device record for new connection. Allocate one */
- p_dev_rec = btm_sec_alloc_dev (bda);
+ if ((p_dev_rec = btm_sec_alloc_dev (bda)) == NULL)
+ return;
}
else /* Update the timestamp for this device */
{
@@ -1762,6 +1781,8 @@
p_dev_rec->device_type |= BT_DEVICE_TYPE_BLE;
p_dev_rec->ble_hci_handle = handle;
p_dev_rec->ble.ble_addr_type = addr_type;
+ /* update pseudo address */
+ memcpy(p_dev_rec->ble.pseudo_addr, bda, BD_ADDR_LEN);
p_dev_rec->role_master = FALSE;
if (role == HCI_ROLE_MASTER)
@@ -2386,6 +2407,12 @@
{
memcpy(btm_cb.devcb.id_keys.irk, p->param_buf, BT_OCTET16_LEN);
btm_notify_new_key(BTM_BLE_KEY_TYPE_ID);
+
+ /* if privacy is enabled, new RPA should be calculated */
+ if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE)
+ {
+ btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low);
+ }
}
else
{
diff --git a/system/stack/btm/btm_ble_privacy.c b/system/stack/btm/btm_ble_privacy.c
index db57384..c6f9d97 100644
--- a/system/stack/btm/btm_ble_privacy.c
+++ b/system/stack/btm/btm_ble_privacy.c
@@ -138,18 +138,14 @@
*******************************************************************************/
void btm_ble_clear_irk_index(UINT8 index)
{
- 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 (index < controller_get_interface()->get_ble_resolving_list_max_size())
{
- if (index < controller_get_interface()->get_ble_resolving_list_max_size())
- {
- byte = index / 8;
- bit = index % 8;
- btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
- }
+ byte = index / 8;
+ bit = index % 8;
+ btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
}
}
@@ -773,10 +769,9 @@
/* 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 &&
- ((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)))
+ (p_dev_rec->sec_flags & BTM_SEC_IN_USE) != 0 &&
+ ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
+ (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0))
{
if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
@@ -793,33 +788,10 @@
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];
- memset(dummy_irk, 0, HCIC_BLE_IRK_SIZE);
-
- UINT8 *peer_irk;
- if (BTM_BLE_IS_RESOLVE_BDA(p_dev_rec->bd_addr))
- peer_irk = p_dev_rec->ble.keys.irk;
- else
- peer_irk = dummy_irk;
-
- UINT8 *local_irk;
- if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE)
- local_irk = btm_cb.devcb.id_keys.irk;
- else
- local_irk = dummy_irk;
-
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;
+ UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
+ UINT8 *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);