642 lines
22 KiB
C++
642 lines
22 KiB
C++
/******************************************************************************
|
|
*
|
|
* Copyright 1999-2012 Broadcom Corporation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
*
|
|
* This file contains functions for BLE controller based privacy.
|
|
*
|
|
******************************************************************************/
|
|
#include <base/logging.h>
|
|
#include <string.h>
|
|
|
|
#include "ble_advertiser.h"
|
|
#include "bt_target.h"
|
|
#include "device/include/controller.h"
|
|
#include "main/shim/acl_api.h"
|
|
#include "stack/btm/btm_dev.h"
|
|
#include "stack/include/bt_octets.h"
|
|
#include "types/raw_address.h"
|
|
#include "vendor_hcidefs.h"
|
|
|
|
extern tBTM_CB btm_cb;
|
|
|
|
/* RPA offload VSC specifics */
|
|
#define BTM_BLE_META_IRK_ENABLE 0x01
|
|
#define BTM_BLE_META_ADD_IRK_ENTRY 0x02
|
|
#define BTM_BLE_META_REMOVE_IRK_ENTRY 0x03
|
|
#define BTM_BLE_META_CLEAR_IRK_LIST 0x04
|
|
#define BTM_BLE_META_READ_IRK_ENTRY 0x05
|
|
#define BTM_BLE_META_CS_RESOLVE_ADDR 0x00000001
|
|
#define BTM_BLE_IRK_ENABLE_LEN 2
|
|
|
|
#define BTM_BLE_META_ADD_IRK_LEN 24
|
|
#define BTM_BLE_META_REMOVE_IRK_LEN 8
|
|
#define BTM_BLE_META_CLEAR_IRK_LEN 1
|
|
#define BTM_BLE_META_READ_IRK_LEN 2
|
|
#define BTM_BLE_META_ADD_WL_ATTR_LEN 9
|
|
|
|
/*******************************************************************************
|
|
* Functions implemented controller based privacy using Resolving List
|
|
******************************************************************************/
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_enq_resolving_list_pending
|
|
*
|
|
* Description add target address into resolving pending operation queue
|
|
*
|
|
* Parameters target_bda: target device address
|
|
* add_entry: true for add entry, false for remove entry
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static void btm_ble_enq_resolving_list_pending(const RawAddress& pseudo_bda,
|
|
uint8_t op_code) {
|
|
tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
|
|
|
|
p_q->resolve_q_random_pseudo[p_q->q_next] = pseudo_bda;
|
|
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();
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_brcm_find_resolving_pending_entry
|
|
*
|
|
* Description check to see if the action is in pending list
|
|
*
|
|
* Parameters true: action pending;
|
|
* false: new action
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static bool btm_ble_brcm_find_resolving_pending_entry(
|
|
const RawAddress& pseudo_addr, uint8_t action) {
|
|
tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
|
|
|
|
for (uint8_t i = p_q->q_pending; i != p_q->q_next;) {
|
|
if (p_q->resolve_q_random_pseudo[i] == pseudo_addr &&
|
|
action == p_q->resolve_q_action[i])
|
|
return true;
|
|
|
|
i++;
|
|
i %= controller_get_interface()->get_ble_resolving_list_max_size();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_deq_resolving_pending
|
|
*
|
|
* Description dequeue target address from resolving pending operation
|
|
* queue
|
|
*
|
|
* Parameters pseudo_addr: pseudo_addr device address
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static bool btm_ble_deq_resolving_pending(RawAddress& 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) {
|
|
pseudo_addr = p_q->resolve_q_random_pseudo[p_q->q_pending];
|
|
p_q->resolve_q_random_pseudo[p_q->q_pending] = RawAddress::kEmpty;
|
|
p_q->q_pending++;
|
|
p_q->q_pending %=
|
|
controller_get_interface()->get_ble_resolving_list_max_size();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_clear_irk_index
|
|
*
|
|
* Description clear IRK list index mask for availability
|
|
*
|
|
* Returns none
|
|
*
|
|
******************************************************************************/
|
|
static void btm_ble_clear_irk_index(uint8_t index) {
|
|
uint8_t byte;
|
|
uint8_t bit;
|
|
|
|
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));
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_find_irk_index
|
|
*
|
|
* Description find the first available IRK list index
|
|
*
|
|
* Returns index from 0 ~ max (127 default)
|
|
*
|
|
******************************************************************************/
|
|
static uint8_t btm_ble_find_irk_index(void) {
|
|
uint8_t i = 0;
|
|
uint8_t byte;
|
|
uint8_t 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;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_update_resolving_list
|
|
*
|
|
* Description update resolving list entry in host maintained record
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static void btm_ble_update_resolving_list(const RawAddress& pseudo_bda,
|
|
bool add) {
|
|
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;
|
|
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;
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool clear_resolving_list_bit(void* data, void* context) {
|
|
tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data);
|
|
p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
|
|
return true;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_clear_resolving_list_complete
|
|
*
|
|
* Description This function is called when command complete for
|
|
* clear resolving list
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
void btm_ble_clear_resolving_list_complete(uint8_t* p, uint16_t evt_len) {
|
|
uint8_t status = 0;
|
|
|
|
if (evt_len < 1) {
|
|
BTM_TRACE_ERROR("malformatted event packet: containing zero bytes");
|
|
return;
|
|
}
|
|
|
|
STREAM_TO_UINT8(status, p);
|
|
|
|
BTM_TRACE_DEBUG("%s status=%d", __func__, status);
|
|
|
|
if (status == HCI_SUCCESS) {
|
|
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", __func__,
|
|
btm_cb.ble_ctr_cb.resolving_list_avail_size);
|
|
|
|
list_foreach(btm_cb.sec_dev_rec, clear_resolving_list_bit, NULL);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_add_resolving_list_entry_complete
|
|
*
|
|
* Description This function is called when command complete for
|
|
* add resolving list entry
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
void btm_ble_add_resolving_list_entry_complete(uint8_t* p, uint16_t evt_len) {
|
|
uint8_t status;
|
|
|
|
if (evt_len < 1) {
|
|
BTM_TRACE_ERROR("malformatted event packet: containing zero bytes");
|
|
return;
|
|
}
|
|
|
|
STREAM_TO_UINT8(status, p);
|
|
|
|
BTM_TRACE_DEBUG("%s status = %d", __func__, status);
|
|
|
|
RawAddress pseudo_bda;
|
|
if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
|
|
BTM_TRACE_DEBUG("no pending resolving list operation");
|
|
return;
|
|
}
|
|
|
|
if (status == HCI_SUCCESS) {
|
|
btm_ble_update_resolving_list(pseudo_bda, true);
|
|
/* privacy 1.2 command complete does not have these extra byte */
|
|
if (evt_len > 2) {
|
|
/* VSC complete has one extra byte for op code, skip it here */
|
|
p++;
|
|
STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
|
|
} else
|
|
btm_cb.ble_ctr_cb.resolving_list_avail_size--;
|
|
} else if (status ==
|
|
HCI_ERR_MEMORY_FULL) /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED */
|
|
{
|
|
btm_cb.ble_ctr_cb.resolving_list_avail_size = 0;
|
|
BTM_TRACE_DEBUG("%s Resolving list Full ", __func__);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_remove_resolving_list_entry_complete
|
|
*
|
|
* Description This function is called when command complete for
|
|
* remove resolving list entry
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
void btm_ble_remove_resolving_list_entry_complete(uint8_t* p,
|
|
uint16_t evt_len) {
|
|
RawAddress pseudo_bda;
|
|
uint8_t status;
|
|
|
|
STREAM_TO_UINT8(status, p);
|
|
|
|
BTM_TRACE_DEBUG("%s status = %d", __func__, status);
|
|
|
|
if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
|
|
BTM_TRACE_ERROR("%s no pending resolving list operation", __func__);
|
|
return;
|
|
}
|
|
|
|
if (status == HCI_SUCCESS) {
|
|
/* proprietary: spec does not have these extra bytes */
|
|
if (evt_len > 2) {
|
|
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++;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_read_resolving_list_entry_complete
|
|
*
|
|
* Description This function is called when command complete for
|
|
* remove resolving list entry
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
void btm_ble_read_resolving_list_entry_complete(const uint8_t* p,
|
|
uint16_t evt_len) {
|
|
uint8_t status;
|
|
RawAddress rra, pseudo_bda;
|
|
|
|
STREAM_TO_UINT8(status, p);
|
|
|
|
BTM_TRACE_DEBUG("%s status = %d", __func__, status);
|
|
|
|
if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
|
|
BTM_TRACE_ERROR("no pending resolving list operation");
|
|
return;
|
|
}
|
|
|
|
if (status == HCI_SUCCESS) {
|
|
/* proprietary spec has extra bytes */
|
|
if (evt_len > 8) {
|
|
/* skip subcode, index, IRK value, address type, identity addr type */
|
|
p += (2 + 16 + 1 + 6);
|
|
STREAM_TO_BDADDR(rra, p);
|
|
|
|
VLOG(2) << __func__ << " peer_addr: " << rra;
|
|
} else {
|
|
STREAM_TO_BDADDR(rra, p);
|
|
}
|
|
btm_ble_refresh_peer_resolvable_private_addr(
|
|
pseudo_bda, rra, tBTM_SEC_BLE::tADDRESS_TYPE::BTM_BLE_ADDR_PSEUDO);
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
VSC that implement controller based privacy
|
|
******************************************************************************/
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_resolving_list_vsc_op_cmpl
|
|
*
|
|
* Description IRK operation VSC complete handler
|
|
*
|
|
* Parameters
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static void btm_ble_resolving_list_vsc_op_cmpl(tBTM_VSC_CMPL* p_params) {
|
|
uint8_t *p = p_params->p_param_buf, op_subcode;
|
|
uint16_t evt_len = p_params->param_len;
|
|
|
|
op_subcode = *(p + 1);
|
|
|
|
BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode);
|
|
|
|
if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) {
|
|
btm_ble_clear_resolving_list_complete(p, evt_len);
|
|
} else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) {
|
|
btm_ble_add_resolving_list_entry_complete(p, evt_len);
|
|
} else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) {
|
|
btm_ble_remove_resolving_list_entry_complete(p, evt_len);
|
|
} else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) {
|
|
btm_ble_read_resolving_list_entry_complete(p, evt_len);
|
|
} else if (op_subcode == BTM_BLE_META_IRK_ENABLE) {
|
|
/* RPA offloading enable/disabled */
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_remove_resolving_list_entry
|
|
*
|
|
* Description This function to remove an IRK entry from the list
|
|
*
|
|
* Parameters ble_addr_type: address type
|
|
* ble_addr: LE adddress
|
|
*
|
|
* Returns status
|
|
*
|
|
******************************************************************************/
|
|
tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) {
|
|
/* if controller does not support RPA offloading or privacy 1.2, skip */
|
|
if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
|
|
return BTM_WRONG_MODE;
|
|
|
|
if (controller_get_interface()->supports_ble_privacy()) {
|
|
bluetooth::shim::ACL_RemoveFromAddressResolution(
|
|
p_dev_rec->ble.identity_address_with_type);
|
|
} else {
|
|
uint8_t param[20] = {0};
|
|
uint8_t* p = param;
|
|
|
|
UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
|
|
UINT8_TO_STREAM(p, p_dev_rec->ble.identity_address_with_type.type);
|
|
BDADDR_TO_STREAM(p, p_dev_rec->ble.identity_address_with_type.bda);
|
|
|
|
BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
|
|
BTM_BLE_META_REMOVE_IRK_LEN, param,
|
|
btm_ble_resolving_list_vsc_op_cmpl);
|
|
btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
|
|
BTM_BLE_META_REMOVE_IRK_ENTRY);
|
|
}
|
|
return BTM_CMD_STARTED;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_clear_resolving_list
|
|
*
|
|
* Description This function clears the resolving list
|
|
*
|
|
* Parameters None.
|
|
*
|
|
******************************************************************************/
|
|
void btm_ble_clear_resolving_list(void) {
|
|
if (controller_get_interface()->supports_ble_privacy()) {
|
|
bluetooth::shim::ACL_ClearAddressResolution();
|
|
} else {
|
|
uint8_t param[20] = {0};
|
|
uint8_t* p = param;
|
|
|
|
UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
|
|
BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
|
|
BTM_BLE_META_CLEAR_IRK_LEN, param,
|
|
btm_ble_resolving_list_vsc_op_cmpl);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_read_resolving_list_entry
|
|
*
|
|
* Description This function read an IRK entry by index
|
|
*
|
|
* Parameters entry index.
|
|
*
|
|
* Returns true if command successfully sent, false otherwise
|
|
*
|
|
******************************************************************************/
|
|
bool btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) {
|
|
if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)) {
|
|
LOG_INFO("%s Unable to read resolving list entry as resolving bit not set",
|
|
__func__);
|
|
return false;
|
|
}
|
|
|
|
if (controller_get_interface()->supports_ble_privacy()) {
|
|
btsnd_hcic_ble_read_resolvable_addr_peer(
|
|
p_dev_rec->ble.identity_address_with_type.type,
|
|
p_dev_rec->ble.identity_address_with_type.bda);
|
|
} else {
|
|
uint8_t param[20] = {0};
|
|
uint8_t* p = param;
|
|
|
|
UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
|
|
UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index);
|
|
|
|
BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_META_READ_IRK_LEN,
|
|
param, btm_ble_resolving_list_vsc_op_cmpl);
|
|
|
|
btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
|
|
BTM_BLE_META_READ_IRK_ENTRY);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void btm_ble_ble_unsupported_resolving_list_load_dev(
|
|
tBTM_SEC_DEV_REC* p_dev_rec) {
|
|
LOG_INFO("Controller does not support BLE privacy");
|
|
uint8_t param[40] = {0};
|
|
uint8_t* p = param;
|
|
|
|
UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
|
|
ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, OCTET16_LEN);
|
|
UINT8_TO_STREAM(p, p_dev_rec->ble.identity_address_with_type.type);
|
|
BDADDR_TO_STREAM(p, p_dev_rec->ble.identity_address_with_type.bda);
|
|
|
|
BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_META_ADD_IRK_LEN,
|
|
param, btm_ble_resolving_list_vsc_op_cmpl);
|
|
|
|
btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
|
|
BTM_BLE_META_ADD_IRK_ENTRY);
|
|
return;
|
|
}
|
|
|
|
static bool is_peer_identity_key_valid(const tBTM_SEC_DEV_REC& dev_rec) {
|
|
return dev_rec.ble.key_type & BTM_LE_KEY_PID;
|
|
}
|
|
|
|
static Octet16 get_local_irk() { return btm_cb.devcb.id_keys.irk; }
|
|
|
|
void btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC& dev_rec) {
|
|
if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
|
|
LOG_INFO("Controller does not support RPA offloading or privacy 1.2");
|
|
return;
|
|
}
|
|
|
|
if (!controller_get_interface()->supports_ble_privacy()) {
|
|
return btm_ble_ble_unsupported_resolving_list_load_dev(&dev_rec);
|
|
}
|
|
|
|
// No need to check for local identity key validity. It remains unchanged.
|
|
if (!is_peer_identity_key_valid(dev_rec)) {
|
|
LOG_INFO("Peer is not an RPA enabled device:%s",
|
|
PRIVATE_ADDRESS(dev_rec.ble.identity_address_with_type));
|
|
return;
|
|
}
|
|
|
|
if (dev_rec.ble.in_controller_list & BTM_RESOLVING_LIST_BIT) {
|
|
LOG_WARN("Already in Address Resolving list device:%s",
|
|
PRIVATE_ADDRESS(dev_rec.ble.identity_address_with_type));
|
|
return;
|
|
}
|
|
|
|
const Octet16& peer_irk = dev_rec.ble.keys.irk;
|
|
const Octet16& local_irk = get_local_irk();
|
|
|
|
if (dev_rec.ble.identity_address_with_type.bda.IsEmpty()) {
|
|
dev_rec.ble.identity_address_with_type = {
|
|
.bda = dev_rec.bd_addr,
|
|
.type = dev_rec.ble.AddressType(),
|
|
};
|
|
}
|
|
|
|
bluetooth::shim::ACL_AddToAddressResolution(
|
|
dev_rec.ble.identity_address_with_type, peer_irk, local_irk);
|
|
|
|
LOG_DEBUG("Added to Address Resolving list device:%s",
|
|
PRIVATE_ADDRESS(dev_rec.ble.identity_address_with_type));
|
|
|
|
dev_rec.ble.in_controller_list |= BTM_RESOLVING_LIST_BIT;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_resolving_list_remove_dev
|
|
*
|
|
* Description This function removes the device from resolving list
|
|
*
|
|
* Parameters
|
|
*
|
|
* Returns status
|
|
*
|
|
******************************************************************************/
|
|
void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) {
|
|
BTM_TRACE_EVENT("%s", __func__);
|
|
|
|
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)) {
|
|
btm_ble_update_resolving_list(p_dev_rec->bd_addr, false);
|
|
btm_ble_remove_resolving_list_entry(p_dev_rec);
|
|
} else {
|
|
BTM_TRACE_DEBUG("Device not in resolving list");
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function btm_ble_resolving_list_init
|
|
*
|
|
* Description Initialize resolving list in host stack
|
|
*
|
|
* Parameters Max resolving list size
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
void btm_ble_resolving_list_init(uint8_t max_irk_list_sz) {
|
|
tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
|
|
uint8_t 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 == nullptr) {
|
|
// NOTE: This memory is never freed
|
|
p_q->resolve_q_random_pseudo =
|
|
(RawAddress*)osi_malloc(sizeof(RawAddress) * max_irk_list_sz);
|
|
// NOTE: This memory is never freed
|
|
p_q->resolve_q_action = (uint8_t*)osi_malloc(max_irk_list_sz);
|
|
|
|
/* RPA offloading feature */
|
|
if (btm_cb.ble_ctr_cb.irk_list_mask == NULL)
|
|
// NOTE: This memory is never freed
|
|
btm_cb.ble_ctr_cb.irk_list_mask = (uint8_t*)osi_malloc(irk_mask_size);
|
|
|
|
BTM_TRACE_DEBUG("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
|
|
}
|
|
|
|
controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
|
|
btm_ble_clear_resolving_list();
|
|
btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
|
|
}
|