mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(bt/bluedroid): prefer disconnected peers when evicting overflow bonds
When the bond list is full, drop the oldest disconnected device instead
of the oldest NVS entry, and allow a per-bond except flag so selected
devices are never auto-removed.
(cherry picked from commit bf86892eef)
Co-authored-by: zhanghaipeng <zhanghaipeng@espressif.com>
This commit is contained in:
@@ -937,6 +937,39 @@ esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_lis
|
||||
return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_set_bond_device_except(esp_bd_addr_t bd_addr, bool except)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (bd_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
return (btc_storage_set_bond_except((bt_bdaddr_t *)bd_addr, except) == BT_STATUS_SUCCESS)
|
||||
? ESP_OK : ESP_FAIL;
|
||||
#else
|
||||
(void)except;
|
||||
return ESP_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_is_bond_device_excepted(esp_bd_addr_t bd_addr, bool *excepted)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (bd_addr == NULL || excepted == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
return (btc_storage_get_bond_except((bt_bdaddr_t *)bd_addr, excepted) == BT_STATUS_SUCCESS)
|
||||
? ESP_OK : ESP_FAIL;
|
||||
#else
|
||||
return ESP_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len)
|
||||
{
|
||||
if(len != ESP_BT_OCTET16_LEN) {
|
||||
|
||||
@@ -3936,6 +3936,52 @@ int esp_ble_get_bond_device_num(void);
|
||||
*/
|
||||
esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list);
|
||||
|
||||
/**
|
||||
* @brief Protect or unprotect a bonded device from automatic eviction
|
||||
* when the bond list is full.
|
||||
*
|
||||
* `bd_addr` must already be in the BLE bond list (the same
|
||||
* address reported by `ESP_GAP_BLE_AUTH_CMPL_EVT` or
|
||||
* `esp_ble_get_bond_device_list()`). Do not pass an unbound
|
||||
* address: this API will not create a new bond section and
|
||||
* returns `ESP_FAIL`.
|
||||
*
|
||||
* Excepted devices are never selected by the overflow cleanup
|
||||
* in NVS (they stay bonded even if they are idle/disconnected).
|
||||
* `esp_ble_remove_bond_device()` still removes them explicitly.
|
||||
*
|
||||
* The flag is stored on that device's NVS bond record and
|
||||
* survives reboot. Keep the number of excepted devices
|
||||
* strictly less than the configured max bond count, otherwise
|
||||
* a new pairing may have no evictable candidate.
|
||||
*
|
||||
* @param[in] bd_addr : BD address of an already bonded peer
|
||||
* @param[in] except : true to protect, false to clear the protection
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - ESP_ERR_INVALID_ARG : bd_addr is NULL
|
||||
* - ESP_FAIL : device is not in the BLE bond list, the excepted bond
|
||||
* count would exceed (max bond count - 1), or storage write failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_set_bond_device_except(esp_bd_addr_t bd_addr, bool except);
|
||||
|
||||
/**
|
||||
* @brief Query whether a device's bond is protected from overflow eviction.
|
||||
*
|
||||
* This reads a per-device flag on that bond, not a separate except list.
|
||||
* If the address is not bonded, `*excepted` is set to false.
|
||||
*
|
||||
* @param[in] bd_addr : BD address of the peer
|
||||
* @param[out] excepted : set to true only if this device is bonded and excepted
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - ESP_ERR_INVALID_ARG : bd_addr or excepted is NULL
|
||||
* - ESP_FAIL : Bluedroid is not enabled
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_is_bond_device_excepted(esp_bd_addr_t bd_addr, bool *excepted);
|
||||
|
||||
/**
|
||||
* @brief This function is called to provide the OOB data for
|
||||
* SMP in response to ESP_GAP_BLE_OOB_REQ_EVT
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "btc/btc_ble_storage.h"
|
||||
#include "bta/bta_gatts_co.h"
|
||||
#include "btc/btc_util.h"
|
||||
#include "stack/btm_api.h"
|
||||
#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE && BLE_PERIPH_PSEUDO_ADDR_BOND == TRUE)
|
||||
#include "stack/btm_ble_api.h"
|
||||
#endif
|
||||
@@ -21,12 +22,192 @@
|
||||
//the maximum number of bonded devices
|
||||
#define BONED_DEVICES_MAX_COUNT (BTM_SEC_MAX_BONDS)
|
||||
|
||||
static bool btc_storage_bond_is_excepted(const char *section)
|
||||
{
|
||||
int except = 0;
|
||||
|
||||
return btc_config_get_int(section, BTC_BLE_STORAGE_EXCEPT_STR, &except) && (except != 0);
|
||||
}
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
/* Caller must hold btc_config_lock(). Count BLE bonds with ExceptBond set. */
|
||||
static uint16_t btc_storage_count_excepted_ble_bonds(void)
|
||||
{
|
||||
uint16_t count = 0;
|
||||
|
||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin();
|
||||
iter != btc_config_section_end();
|
||||
iter = btc_config_section_next(iter)) {
|
||||
const char *section = btc_config_section_name(iter);
|
||||
int device_type = 0;
|
||||
|
||||
if (!string_is_bdaddr(section)) {
|
||||
continue;
|
||||
}
|
||||
if (!btc_config_get_int(section, BTC_BLE_STORAGE_DEV_TYPE_STR, &device_type) ||
|
||||
!(device_type & BT_DEVICE_TYPE_BLE)) {
|
||||
continue;
|
||||
}
|
||||
if (btc_storage_bond_is_excepted(section)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Caller must hold btc_config_lock(). Warn if NVS has too many excepted bonds. */
|
||||
void btc_storage_check_excepted_bond_limit(void)
|
||||
{
|
||||
if (BONED_DEVICES_MAX_COUNT == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t except_count = btc_storage_count_excepted_ble_bonds();
|
||||
uint16_t except_max = (uint16_t)(BONED_DEVICES_MAX_COUNT - 1);
|
||||
|
||||
if (except_count > except_max) {
|
||||
BTC_TRACE_WARNING("ExceptBond count %u exceeds limit %u (max bonds %u)",
|
||||
except_count, except_max, BONED_DEVICES_MAX_COUNT);
|
||||
}
|
||||
}
|
||||
#endif /* BLE_INCLUDED == TRUE */
|
||||
|
||||
static bool btc_storage_bdaddr_is_connected(BD_ADDR addr)
|
||||
{
|
||||
/* Use BTM ACL only. BTA_DmGetConnectionState() pulls bta_dm_find_peer_device
|
||||
* from bta_dm_pm.c, which is not linked on BLE-only / no-PM builds. */
|
||||
if (BTM_IsAclConnectionUp(addr, BT_TRANSPORT_LE)) {
|
||||
return true;
|
||||
}
|
||||
if (BTM_IsAclConnectionUp(addr, BT_TRANSPORT_BR_EDR)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool btc_storage_bond_is_connected(const char *section)
|
||||
{
|
||||
bt_bdaddr_t bd_addr;
|
||||
tBTM_LE_PID_KEYS pid;
|
||||
size_t pid_len = sizeof(pid);
|
||||
|
||||
if (!string_to_bdaddr(section, &bd_addr)) {
|
||||
return false;
|
||||
}
|
||||
if (btc_storage_bdaddr_is_connected(bd_addr.address)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Section may be keyed by RPA while the live ACL uses the identity. */
|
||||
memset(&pid, 0, sizeof(pid));
|
||||
if (btc_config_get_bin(section, BTC_BLE_STORAGE_LE_KEY_PID_STR, (uint8_t *)&pid, &pid_len) &&
|
||||
pid_len == sizeof(pid) &&
|
||||
memcmp(pid.static_addr, bd_addr.address, sizeof(bd_addr.address)) != 0) {
|
||||
if (btc_storage_bdaddr_is_connected(pid.static_addr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint16_t btc_storage_count_bdaddr_sections(void)
|
||||
{
|
||||
uint16_t count = 0;
|
||||
|
||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin();
|
||||
iter != btc_config_section_end();
|
||||
iter = btc_config_section_next(iter)) {
|
||||
if (string_is_bdaddr(btc_config_section_name(iter))) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* NVS sections are newest-first. Keep updating the match so the last one is oldest.
|
||||
* The newest bdaddr section is never evicted (it is the bond just written / most recent). */
|
||||
static const char *btc_storage_find_evict_candidate(bool connected_ok)
|
||||
{
|
||||
const char *candidate = NULL;
|
||||
const char *newest = NULL;
|
||||
|
||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin();
|
||||
iter != btc_config_section_end();
|
||||
iter = btc_config_section_next(iter)) {
|
||||
const char *section = btc_config_section_name(iter);
|
||||
|
||||
if (!string_is_bdaddr(section)) {
|
||||
continue;
|
||||
}
|
||||
if (newest == NULL) {
|
||||
newest = section;
|
||||
continue;
|
||||
}
|
||||
if (btc_storage_bond_is_excepted(section)) {
|
||||
continue;
|
||||
}
|
||||
if (!connected_ok && btc_storage_bond_is_connected(section)) {
|
||||
continue;
|
||||
}
|
||||
candidate = section;
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static bool btc_storage_evict_bond_section(const char *section)
|
||||
{
|
||||
bt_bdaddr_t bd_addr;
|
||||
bdstr_t section_copy;
|
||||
|
||||
if (!section || !string_to_bdaddr(section, &bd_addr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Section name is freed by remove_section; copy before mutating the list. */
|
||||
{
|
||||
size_t name_len = strlen(section);
|
||||
if (name_len >= sizeof(section_copy)) {
|
||||
return false;
|
||||
}
|
||||
memcpy(section_copy, section, name_len + 1);
|
||||
}
|
||||
|
||||
BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_LE);
|
||||
BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_BR_EDR);
|
||||
if (btc_config_remove_section(section_copy)) {
|
||||
BTIF_TRACE_WARNING("Exceeded the maximum number of bonded devices. Deleting device info: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
bd_addr.address[0], bd_addr.address[1], bd_addr.address[2],
|
||||
bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void btc_storage_evict_overflow_bonded_devices(uint16_t max_keep)
|
||||
{
|
||||
uint16_t count = btc_storage_count_bdaddr_sections();
|
||||
|
||||
while (count > max_keep) {
|
||||
const char *victim = btc_storage_find_evict_candidate(false);
|
||||
|
||||
if (!victim) {
|
||||
/* No disconnected, non-excepted bond; fall back to the oldest connected one. */
|
||||
victim = btc_storage_find_evict_candidate(true);
|
||||
}
|
||||
if (!victim) {
|
||||
BTIF_TRACE_WARNING("Cannot evict bonded devices: remaining bonds are excepted (count=%u max=%u)",
|
||||
count, max_keep);
|
||||
break;
|
||||
}
|
||||
if (!btc_storage_evict_bond_section(victim)) {
|
||||
break;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
static void _btc_storage_save(void)
|
||||
{
|
||||
uint16_t addr_section_count = 0;
|
||||
bt_bdaddr_t bd_addr;
|
||||
|
||||
const btc_config_section_iter_t *need_remove_iter = NULL;
|
||||
const btc_config_section_iter_t *iter = btc_config_section_begin();
|
||||
|
||||
while (iter != btc_config_section_end()) {
|
||||
@@ -55,33 +236,12 @@ static void _btc_storage_save(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(addr_section_count == BONED_DEVICES_MAX_COUNT) {
|
||||
need_remove_iter = iter;
|
||||
}
|
||||
addr_section_count ++;
|
||||
iter = btc_config_section_next(iter);
|
||||
}
|
||||
/*exceeded the maximum number of bonded devices, delete them */
|
||||
if (need_remove_iter) {
|
||||
while(need_remove_iter != btc_config_section_end()) {
|
||||
const char *need_remove_section = btc_config_section_name(need_remove_iter);
|
||||
if (!string_is_bdaddr(need_remove_section)) {
|
||||
need_remove_iter = btc_config_section_next(need_remove_iter);
|
||||
continue;
|
||||
}
|
||||
need_remove_iter = btc_config_section_next(need_remove_iter);
|
||||
//delete device info
|
||||
string_to_bdaddr(need_remove_section, &bd_addr);
|
||||
BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_LE);
|
||||
BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_BR_EDR);
|
||||
//delete config info
|
||||
if (btc_config_remove_section(need_remove_section)) {
|
||||
// The need_remove_section has been freed
|
||||
BTIF_TRACE_WARNING("Exceeded the maximum number of bonded devices. Deleting the last device info: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Bond list is newest-first in NVS. Evict oldest disconnected (then oldest
|
||||
* connected) non-excepted devices until the count fits. */
|
||||
btc_storage_evict_overflow_bonded_devices(BONED_DEVICES_MAX_COUNT);
|
||||
btc_config_flush();
|
||||
}
|
||||
|
||||
@@ -282,6 +442,9 @@ static bt_status_t _btc_storage_remove_all_ble_keys(const char *name)
|
||||
ret |= btc_config_remove(name, BTC_BLE_STORAGE_PSEUDO_BOND_STR);
|
||||
}
|
||||
#endif
|
||||
if (btc_config_exist(name, BTC_BLE_STORAGE_EXCEPT_STR)) {
|
||||
ret |= btc_config_remove(name, BTC_BLE_STORAGE_EXCEPT_STR);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1172,6 +1335,87 @@ int btc_storage_get_num_ble_bond_devices(void)
|
||||
return num_dev;
|
||||
}
|
||||
|
||||
bt_status_t btc_storage_set_bond_except(bt_bdaddr_t *remote_bd_addr, bool except)
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
int device_type = 0;
|
||||
bool ret;
|
||||
|
||||
if (remote_bd_addr == NULL) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
|
||||
btc_config_lock();
|
||||
/* Require an existing BLE bond section so we do not create an empty
|
||||
* bdaddr section that would consume a bond slot. */
|
||||
if (!btc_config_has_section(bdstr)) {
|
||||
btc_config_unlock();
|
||||
BTC_TRACE_WARNING("%s: %s is not bonded, cannot set except=%d", __func__, bdstr, except);
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
if (!btc_config_get_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, &device_type)) {
|
||||
btc_config_unlock();
|
||||
BTC_TRACE_WARNING("%s: %s has no bond record, cannot set except=%d", __func__, bdstr, except);
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
if (!(device_type & BT_DEVICE_TYPE_BLE)) {
|
||||
btc_config_unlock();
|
||||
BTC_TRACE_WARNING("%s: %s is not a BLE bonded device (device_type=0x%x), cannot set except=%d",
|
||||
__func__, bdstr, device_type, except);
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
if (except) {
|
||||
if (!btc_storage_bond_is_excepted(bdstr)) {
|
||||
uint16_t except_count = btc_storage_count_excepted_ble_bonds();
|
||||
uint16_t except_max = (BONED_DEVICES_MAX_COUNT > 0)
|
||||
? (uint16_t)(BONED_DEVICES_MAX_COUNT - 1) : 0;
|
||||
|
||||
if (except_count >= except_max) {
|
||||
btc_config_unlock();
|
||||
BTC_TRACE_WARNING("%s: cannot set except for %s: excepted bond count %u reached limit %u (max bonds %u)",
|
||||
__func__, bdstr, except_count, except_max, BONED_DEVICES_MAX_COUNT);
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
}
|
||||
ret = btc_config_set_int(bdstr, BTC_BLE_STORAGE_EXCEPT_STR, 1);
|
||||
} else if (btc_config_exist(bdstr, BTC_BLE_STORAGE_EXCEPT_STR)) {
|
||||
ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_EXCEPT_STR);
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
btc_config_flush();
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s: failed to %s ExceptBond for %s", __func__,
|
||||
except ? "set" : "clear", bdstr);
|
||||
}
|
||||
btc_config_unlock();
|
||||
|
||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
bt_status_t btc_storage_get_bond_except(bt_bdaddr_t *remote_bd_addr, bool *except)
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
int except_val = 0;
|
||||
|
||||
if (remote_bd_addr == NULL || except == NULL) {
|
||||
return BT_STATUS_FAIL;
|
||||
}
|
||||
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
|
||||
btc_config_lock();
|
||||
*except = btc_config_get_int(bdstr, BTC_BLE_STORAGE_EXCEPT_STR, &except_val) && (except_val != 0);
|
||||
btc_config_unlock();
|
||||
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bt_status_t btc_storage_get_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len)
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
|
||||
@@ -36,42 +36,8 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
|
||||
BOOLEAN sc_support)
|
||||
{
|
||||
bdstr_t bdstr;
|
||||
bt_bdaddr_t bd_addr;
|
||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||
|
||||
/* device not in bond list and exceed the maximum number of bonded devices, delete the inactive bonded device */
|
||||
if (btc_storage_get_num_all_bond_devices() >= BTM_SEC_MAX_BONDS && !btc_config_has_section(bdstr)) {
|
||||
const btc_config_section_iter_t *iter = btc_config_section_begin();
|
||||
const btc_config_section_iter_t *remove_iter = NULL;
|
||||
/* find the last bdaddr-formatted device section */
|
||||
while (iter != btc_config_section_end()) {
|
||||
const char *name = btc_config_section_name(iter);
|
||||
if (name && string_is_bdaddr(name)) {
|
||||
remove_iter = iter;
|
||||
}
|
||||
iter = btc_config_section_next(iter);
|
||||
}
|
||||
|
||||
if (remove_iter != NULL) {
|
||||
const char *remove_section = btc_config_section_name(remove_iter);
|
||||
if (string_to_bdaddr(remove_section, &bd_addr)) {
|
||||
// delete device info
|
||||
BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_BR_EDR);
|
||||
BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_LE);
|
||||
|
||||
// delete config info
|
||||
if (btc_config_remove_section(remove_section)) {
|
||||
BTC_TRACE_WARNING("exceeded the maximum number of bonded devices, delete the first device info : %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
|
||||
}
|
||||
} else {
|
||||
BTC_TRACE_ERROR("Failed to convert section name to bdaddr: %s", remove_section);
|
||||
}
|
||||
} else {
|
||||
BTC_TRACE_WARNING("No bdaddr-formatted section found to remove");
|
||||
}
|
||||
}
|
||||
|
||||
BTC_TRACE_DEBUG("add to storage: Remote device:%s\n", bdstr);
|
||||
|
||||
btc_config_lock();
|
||||
@@ -79,6 +45,33 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
|
||||
ret &= btc_config_set_int(bdstr, BTC_STORAGE_PIN_LENGTH_STR, (int)pin_length);
|
||||
ret &= btc_config_set_bin(bdstr, BTC_STORAGE_LINK_KEY_STR, link_key, sizeof(LINK_KEY));
|
||||
ret &= btc_config_set_bin(bdstr, BTC_STORAGE_SC_SUPPORT, (uint8_t *)&sc_support, sizeof(sc_support));
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
/* Evict after the write so the new device is newest and is not selected. */
|
||||
btc_storage_evict_overflow_bonded_devices(BTM_SEC_MAX_BONDS);
|
||||
#else
|
||||
{
|
||||
uint16_t count = 0;
|
||||
const btc_config_section_iter_t *iter = btc_config_section_begin();
|
||||
const btc_config_section_iter_t *remove_iter = NULL;
|
||||
while (iter != btc_config_section_end()) {
|
||||
const char *name = btc_config_section_name(iter);
|
||||
if (name && string_is_bdaddr(name)) {
|
||||
count++;
|
||||
remove_iter = iter;
|
||||
}
|
||||
iter = btc_config_section_next(iter);
|
||||
}
|
||||
if (count > BTM_SEC_MAX_BONDS && remove_iter != NULL) {
|
||||
const char *remove_section = btc_config_section_name(remove_iter);
|
||||
bt_bdaddr_t bd_addr;
|
||||
if (string_to_bdaddr(remove_section, &bd_addr)) {
|
||||
BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_BR_EDR);
|
||||
BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_LE);
|
||||
btc_config_remove_section(remove_section);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* write bonded info immediately */
|
||||
btc_config_flush();
|
||||
btc_config_unlock();
|
||||
@@ -141,10 +134,13 @@ static bt_status_t btc_in_fetch_bonded_devices(int add)
|
||||
{
|
||||
bt_status_t status = BT_STATUS_FAIL;
|
||||
uint16_t dev_cnt = 0;
|
||||
const btc_config_section_iter_t *remove_iter = NULL;
|
||||
bt_bdaddr_t bd_addr;
|
||||
|
||||
btc_config_lock();
|
||||
/* Drop oldest non-excepted overflow first so excepted bonds are not trimmed. */
|
||||
btc_storage_evict_overflow_bonded_devices(BTM_SEC_MAX_BONDS);
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
btc_storage_check_excepted_bond_limit();
|
||||
#endif
|
||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); iter = btc_config_section_next(iter)) {
|
||||
const char *name = btc_config_section_name(iter);
|
||||
if (!string_is_bdaddr(name)) {
|
||||
@@ -165,25 +161,10 @@ static bt_status_t btc_in_fetch_bonded_devices(int add)
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
}
|
||||
} else {
|
||||
/* delete the exceeded device info from nvs */
|
||||
remove_iter = iter;
|
||||
while (remove_iter != btc_config_section_end()) {
|
||||
const char *remove_section = btc_config_section_name(remove_iter);
|
||||
string_to_bdaddr(remove_section, &bd_addr);
|
||||
if (!string_is_bdaddr(remove_section)) {
|
||||
remove_iter = btc_config_section_next(remove_iter);
|
||||
continue;
|
||||
}
|
||||
remove_iter = btc_config_section_next(remove_iter);
|
||||
/* delete config info */
|
||||
if (btc_config_remove_section(remove_section)) {
|
||||
BTC_TRACE_WARNING("exceeded the maximum number of bonded devices, delete the exceed device info : %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
|
||||
}
|
||||
}
|
||||
/* write into nvs */
|
||||
btc_config_flush();
|
||||
break;
|
||||
/* Leftover overflow is excepted (eviction refuses to delete them).
|
||||
* Keep the NVS entries but do not load extra BTM records. */
|
||||
BTC_TRACE_WARNING("skip loading overflow bonded device %s (excepted or no evictable candidate)", name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
btc_config_unlock();
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
* identity feature). Such sections legitimately share the peer Identity with
|
||||
* another (local,peer) bond and must be exempt from identity-based de-dup. */
|
||||
#define BTC_BLE_STORAGE_PSEUDO_BOND_STR "PseudoBond"
|
||||
/* Marks a bond that must not be auto-evicted when the bond list is full.
|
||||
* Explicit removal via esp_ble_remove_bond_device() is still allowed. */
|
||||
#define BTC_BLE_STORAGE_EXCEPT_STR "ExceptBond"
|
||||
|
||||
#define BTC_BLE_STORAGE_LOCAL_ADAPTER_STR "Adapter"
|
||||
#define BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR "LE_LOCAL_KEY_IR"
|
||||
@@ -98,6 +101,20 @@ void btc_storage_delete_duplicate_ble_devices(void);
|
||||
|
||||
void btc_storage_remove_unused_sections(uint8_t *cur_addr, tBTM_LE_PID_KEYS *del_pid_key);
|
||||
|
||||
/* Caller must hold btc_config_lock(). Evict bonds until bdaddr section count
|
||||
* is <= max_keep. Excepted bonds are never evicted. Disconnected bonds are
|
||||
* preferred over connected ones; NVS list order (oldest last) is the age key. */
|
||||
void btc_storage_evict_overflow_bonded_devices(uint16_t max_keep);
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
/* Caller must hold btc_config_lock(). Check except count against bond limit. */
|
||||
void btc_storage_check_excepted_bond_limit(void);
|
||||
#endif /* BLE_INCLUDED == TRUE */
|
||||
|
||||
bt_status_t btc_storage_set_bond_except(bt_bdaddr_t *remote_bd_addr, bool except);
|
||||
|
||||
bt_status_t btc_storage_get_bond_except(bt_bdaddr_t *remote_bd_addr, bool *except);
|
||||
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
|
||||
#define BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR "GATT_CL_SUPP_FEAT"
|
||||
|
||||
Reference in New Issue
Block a user