feat(ble/bluedroid): Add BLE SMP support for multi-ADV with static random addresses

(cherry picked from commit 7986e2faa8)

Co-authored-by: zhanghaipeng <zhanghaipeng@espressif.com>
This commit is contained in:
Zhang Hai Peng
2026-06-18 10:24:49 +08:00
parent 43cc865e97
commit 68e37183f1
6 changed files with 276 additions and 20 deletions
@@ -571,6 +571,12 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport)
btm_cb.ble_ctr_cb.inq_var.connectable_mode,
p->link_role);
if (p->transport == BT_TRANSPORT_LE) {
#if (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE)
btm_ble_clear_ext_adv_ter_con_handle(p->hci_handle);
#endif
}
p_dev_rec = btm_find_dev(bda);
if ( p_dev_rec) {
BTM_TRACE_DEBUG("before update p_dev_rec->sec_flags=0x%x\n", p_dev_rec->sec_flags);
@@ -1846,6 +1846,81 @@ UINT8 btm_ble_br_keys_req(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_LE_IO_REQ *p_data)
#endif ///SMP_INCLUDED
#if (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE)
/*******************************************************************************
**
** Function btm_ble_adjust_conn_addr_for_ext_adv
**
** Description Rewrite p_acl->conn_addr / conn_addr_type from the
** per-set state in extend_adv_cb.inst[] for the ext-adv
** instance that produced this connection.
**
** The defaults written by btm_acl_created() and
** btm_ble_refresh_local_resolvable_private_addr() come
** from the global addr_mgnt_cb single slot, which in
** multi-ADV may not reflect the policy actually used on
** air for THIS connection and causes SMP c1 / f5 / f6
** to compute the wrong local address (pair fail 0x04).
**
** RPA paths (own_addr_type 0x02, or 0x03 with a valid
** local RPA in the LE Enhanced Connection Complete event)
** are left untouched. For 0x03 when the controller falls
** back to per-set identity (zero local_rpa), replace the
** global private_addr written by
** btm_ble_refresh_local_resolvable_private_addr().
**
** No-op when no ext-adv instance matches the handle
** (initiator role or legacy adv).
**
** Returns void
**
*******************************************************************************/
void btm_ble_adjust_conn_addr_for_ext_adv(UINT16 handle)
{
UINT8 inst;
tACL_CONN *p_acl;
tBLE_ADDR_TYPE on_air_type;
inst = BTM_BleGetExtAdvInstByConHandle(handle);
if (inst >= MAX_BLE_ADV_INSTANCE) {
return;
}
p_acl = btm_handle_to_acl(handle);
if (p_acl == NULL) {
BTM_TRACE_WARNING("%s: no ACL for handle 0x%04x, skip", __func__, handle);
return;
}
on_air_type = extend_adv_cb.inst[inst].own_addr_type;
if (on_air_type == BLE_ADDR_PUBLIC) {
p_acl->conn_addr_type = BLE_ADDR_PUBLIC;
memcpy(p_acl->conn_addr,
controller_get_interface()->get_address()->address,
BD_ADDR_LEN);
} else if (on_air_type == BLE_ADDR_RANDOM &&
extend_adv_cb.inst[inst].rand_addr_set) {
p_acl->conn_addr_type = BLE_ADDR_RANDOM;
memcpy(p_acl->conn_addr,
extend_adv_cb.inst[inst].rand_addr,
BD_ADDR_LEN);
} else if (on_air_type == BLE_ADDR_RANDOM_ID &&
extend_adv_cb.inst[inst].rand_addr_set &&
!BTM_BLE_IS_RESOLVE_BDA(p_acl->conn_addr)) {
/* Identity fallback: controller used per-set static random, not RPA. */
p_acl->conn_addr_type = BLE_ADDR_RANDOM;
memcpy(p_acl->conn_addr,
extend_adv_cb.inst[inst].rand_addr,
BD_ADDR_LEN);
}
BTM_TRACE_DEBUG("%s: handle=0x%04x inst=%u type=%u addr=%02x:%02x:%02x:%02x:%02x:%02x",
__func__, handle, inst, p_acl->conn_addr_type,
p_acl->conn_addr[0], p_acl->conn_addr[1], p_acl->conn_addr[2],
p_acl->conn_addr[3], p_acl->conn_addr[4], p_acl->conn_addr[5]);
}
#endif /* (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE) */
#if (BLE_PRIVACY_SPT == TRUE )
/*******************************************************************************
**
@@ -1904,6 +1979,11 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data)
l2cble_conn_comp (handle, role, bda, bda_type, conn_interval,
conn_latency, conn_timeout);
#if (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE)
/* Multi-ADV: fix up p_acl->conn_addr / conn_addr_type from per-set state. */
btm_ble_adjust_conn_addr_for_ext_adv(handle);
#endif /* (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE) */
return;
}
#endif
@@ -2067,6 +2147,12 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced)
}
}
#endif
#if (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE)
/* Multi-ADV: must run AFTER the global-addr_mgnt_cb defaults above
* so per-set state wins for connections produced by an ext-adv set. */
btm_ble_adjust_conn_addr_for_ext_adv(handle);
#endif /* (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE) */
}
} else {
role = HCI_ROLE_UNKNOWN;
@@ -6,6 +6,7 @@
#include "btm_int.h"
#include "stack/hcimsgs.h"
#include "stack/hcidefs.h"
#include "osi/allocator.h"
#include "device/controller.h"
#include <string.h>
@@ -63,7 +64,15 @@ void btm_ble_extendadvcb_init(void)
#if (BLE_50_EXTEND_ADV_EN == TRUE)
void btm_ble_advrecod_init(void)
{
memset(&adv_record[0], 0, sizeof(tBTM_EXT_ADV_RECORD)*MAX_BLE_ADV_INSTANCE);
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) {
adv_record[i].ter_con_handle = INVALID_VALUE_16BIT;
adv_record[i].invalid = false;
adv_record[i].enabled = false;
adv_record[i].instance = INVALID_VALUE_8BIT;
adv_record[i].duration = INVALID_VALUE_32BIT;
adv_record[i].max_events = INVALID_VALUE_32BIT;
adv_record[i].retry_count = 0;
}
}
#endif // #if (BLE_50_EXTEND_ADV_EN == TRUE)
@@ -197,6 +206,8 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr)
__func__, err);
status = BTM_HCI_ERROR | err;
} else {
memcpy(extend_adv_cb.inst[instance].rand_addr, rand_addr, BD_ADDR_LEN);
extend_adv_cb.inst[instance].rand_addr_set = TRUE;
// set random address success, update address info
if(extend_adv_cb.inst[instance].configured && extend_adv_cb.inst[instance].connetable) {
BTM_BleSetStaticAddr(rand_addr);
@@ -286,6 +297,8 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR
#endif // (BT_BLE_FEAT_ADV_CODING_SELECTION == TRUE)
extend_adv_cb.inst[instance].configured = true;
/* Record the post-fallback on-air address type for per-set conn_addr fixup. */
extend_adv_cb.inst[instance].own_addr_type = params->own_addr_type;
end:
if(use_rpa_addr) {
@@ -296,6 +309,7 @@ end:
} else {
// set addr success, update address info
BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr);
extend_adv_cb.inst[instance].rand_addr_set = FALSE;
}
}
cb_params.set_params.status = status;
@@ -441,6 +455,7 @@ end:
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++)
{
adv_record[i].ter_con_handle = INVALID_VALUE_16BIT;
adv_record[i].invalid = false;
adv_record[i].enabled = false;
adv_record[i].instance = INVALID_VALUE_8BIT;
@@ -455,6 +470,7 @@ end:
if (index >= MAX_BLE_ADV_INSTANCE) {
continue;
}
adv_record[index].ter_con_handle = INVALID_VALUE_16BIT;
adv_record[index].invalid = false;
adv_record[index].enabled = false;
adv_record[index].instance = INVALID_VALUE_8BIT;
@@ -472,6 +488,7 @@ end:
if (index >= MAX_BLE_ADV_INSTANCE) {
continue;
}
adv_record[index].ter_con_handle = INVALID_VALUE_16BIT;
adv_record[index].invalid = true;
adv_record[index].enabled = true;
adv_record[index].instance = ext_adv[i].instance;
@@ -520,6 +537,54 @@ tBTM_STATUS BTM_BleStartExtAdvRestart(uint16_t con_handle)
return BTM_BleStartExtAdv(true, 1, &ext_adv);
}
/*******************************************************************************
**
** Function BTM_BleGetExtAdvInstByConHandle
**
** Description Map an LE connection handle to the ext-adv instance
** whose adv-set-terminated event reported it.
**
** Returns instance index on success, 0xFF if no match.
**
*******************************************************************************/
UINT8 BTM_BleGetExtAdvInstByConHandle(UINT16 con_handle)
{
if (con_handle == INVALID_VALUE_16BIT) {
return 0xFF;
}
for (UINT8 i = 0; i < MAX_BLE_ADV_INSTANCE; i++) {
/* configured + connetable guard prevents an all-zero slot from
* spuriously matching a real conn_handle == 0. */
if (adv_record[i].ter_con_handle == con_handle &&
extend_adv_cb.inst[i].configured &&
extend_adv_cb.inst[i].connetable) {
return i;
}
}
return 0xFF;
}
/*******************************************************************************
**
** Function btm_ble_clear_ext_adv_ter_con_handle
**
** Description Clear stale ter_con_handle entries when an ACL link goes
** down so a reused connection handle cannot map to the
** wrong ext-adv instance.
**
** Returns void
**
*******************************************************************************/
void btm_ble_clear_ext_adv_ter_con_handle(UINT16 con_handle)
{
con_handle = HCID_GET_HANDLE(con_handle);
for (UINT8 i = 0; i < MAX_BLE_ADV_INSTANCE; i++) {
if (adv_record[i].ter_con_handle == con_handle) {
adv_record[i].ter_con_handle = INVALID_VALUE_16BIT;
}
}
}
tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance)
{
tBTM_STATUS status = BTM_SUCCESS;
@@ -541,6 +606,10 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance)
extend_adv_cb.inst[instance].directed = false;
extend_adv_cb.inst[instance].scannable = false;
extend_adv_cb.inst[instance].connetable = false;
extend_adv_cb.inst[instance].own_addr_type = BLE_ADDR_PUBLIC;
extend_adv_cb.inst[instance].rand_addr_set = FALSE;
memset(extend_adv_cb.inst[instance].rand_addr, 0, BD_ADDR_LEN);
adv_record[instance].ter_con_handle = INVALID_VALUE_16BIT;
}
end:
@@ -570,6 +639,10 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void)
extend_adv_cb.inst[i].directed = false;
extend_adv_cb.inst[i].scannable = false;
extend_adv_cb.inst[i].connetable = false;
extend_adv_cb.inst[i].own_addr_type = BLE_ADDR_PUBLIC;
extend_adv_cb.inst[i].rand_addr_set = FALSE;
memset(extend_adv_cb.inst[i].rand_addr, 0, BD_ADDR_LEN);
adv_record[i].ter_con_handle = INVALID_VALUE_16BIT;
}
}
@@ -1177,7 +1250,13 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params)
// adv terminated due to connection, save the adv handle and connection handle
if(params->status == 0x00) {
adv_record[params->adv_handle].ter_con_handle = params->conn_handle;
/* Store the masked handle to match what btm_ble_conn_complete() looks up. */
adv_record[params->adv_handle].ter_con_handle = HCID_GET_HANDLE(params->conn_handle);
/* Re-run the per-set conn_addr fixup in case this event arrives
* after LE (Enhanced) Connection Complete. */
#if (CONTROLLER_RPA_LIST_ENABLE == TRUE)
btm_ble_adjust_conn_addr_for_ext_adv(adv_record[params->adv_handle].ter_con_handle);
#endif
} else {
adv_record[params->adv_handle].ter_con_handle = INVALID_VALUE_16BIT;
adv_record[params->adv_handle].invalid = false;
@@ -510,6 +510,10 @@ void btm_ble_add_default_entry_to_resolving_list(void);
void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len);
#endif
#if (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE) && (CONTROLLER_RPA_LIST_ENABLE == TRUE)
void btm_ble_adjust_conn_addr_for_ext_adv(UINT16 handle);
#endif
char btm_ble_map_adv_tx_power(int tx_power_index);
#if (BLE_TOPOLOGY_CHECK == TRUE)
BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request);
@@ -531,6 +535,9 @@ BOOLEAN btm_get_current_conn_params(BD_ADDR bda, UINT16 *interval, UINT16 *laten
#if (BLE_50_FEATURE_SUPPORT == TRUE)
void btm_ble_update_phy_evt(tBTM_BLE_UPDATE_PHY *params);
void btm_ble_scan_timeout_evt(void);
#if (BLE_50_EXTEND_ADV_EN == TRUE)
void btm_ble_clear_ext_adv_ter_con_handle(UINT16 con_handle);
#endif
void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params);
void btm_ble_ext_adv_report_evt(tBTM_BLE_EXT_ADV_REPORT *params);
void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params);