fix(bt/bluedroid): update the newest active device in bluetooth

1: update the newest active device when an ACL link is established and
   the remote device info is not in bond list. This updates will not stored
   into NVRAM until a new device is paired.
This commit is contained in:
gongyantao 2023-09-08 18:56:47 +08:00
parent c7bde045e2
commit 3eea6650ab
11 changed files with 138 additions and 71 deletions

View File

@ -262,6 +262,32 @@ bool config_remove_section(config_t *config, const char *section)
return list_remove(config->sections, sec);
}
bool config_update_newest_section(config_t *config, const char *section)
{
assert(config != NULL);
assert(section != NULL);
list_node_t *first_node = list_begin(config->sections);
if (first_node == NULL) {
return false;
}
section_t *first_sec = list_node(first_node);
if (strcmp(first_sec->name, section) == 0) {
return true;
}
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
section_t *sec = list_node(node);
if (strcmp(sec->name, section) == 0) {
list_delete(config->sections, sec);
list_prepend(config->sections, sec);
return true;
}
}
return false;
}
bool config_remove_key(config_t *config, const char *section, const char *key)
{
assert(config != NULL);

View File

@ -107,6 +107,11 @@ void config_set_string(config_t *config, const char *section, const char *key, c
// Neither |config| nor |section| may be NULL.
bool config_remove_section(config_t *config, const char *section);
// Updates |section| to be the first section in |config|. Return true if |section| is in
// |config| and updated successfully, false otherwise.
// Neither |config| nor |section| may be NULL.
bool config_update_newest_section(config_t *config, const char *section);
// Removes one specific |key| residing in |section| of the |config|. Returns true
// if the section and key were found and the key was removed, false otherwise.
// None of |config|, |section|, or |key| may be NULL.

View File

@ -22,7 +22,7 @@ static void _btc_storage_save(void)
{
uint16_t addr_section_count = 0;
bt_bdaddr_t bd_addr;
uint32_t device_type = 0;
const btc_config_section_iter_t *need_remove_iter = NULL;
const btc_config_section_iter_t *iter = btc_config_section_begin();
@ -804,53 +804,6 @@ bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr,
return BT_STATUS_FAIL;
}
static bt_status_t btc_storage_in_fetch_bonded_ble_devices(int add)
{
bt_status_t status = BT_STATUS_FAIL;
uint32_t device_type = 0;
btc_config_lock();
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) ||
!btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) ||
((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
continue;
}
BTC_TRACE_DEBUG("%s, name = %s", __func__, name);
if (_btc_storage_in_fetch_bonded_ble_device(name, add) != BT_STATUS_SUCCESS) {
BTC_TRACE_DEBUG("Remote device:%s, no link key or ble key found", name);
} else {
status = BT_STATUS_SUCCESS;
}
}
btc_config_unlock();
return status;
}
/*******************************************************************************
**
** Function btc_storage_load_bonded_devices
**
** Description btc storage API - Loads all the bonded devices from NVRAM
** and adds to the BTA.
** Additionally, this API also invokes the adaper_properties_cb
** and remote_device_properties_cb for each of the bonded devices.
**
** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bt_status_t btc_storage_load_bonded_ble_devices(void)
{
bt_status_t status;
status = btc_storage_in_fetch_bonded_ble_devices(1);
BTC_TRACE_DEBUG("Storage load rslt %d\n", status);
return status;
}
bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num)
{
bt_bdaddr_t bd_addr;

View File

@ -307,6 +307,14 @@ bool btc_config_remove_section(const char *section)
return config_remove_section(config, section);
}
bool btc_config_update_newest_section(const char *section)
{
assert(config != NULL);
assert(section != NULL);
return config_update_newest_section(config, section);
}
void btc_config_flush(void)
{
assert(config != NULL);

View File

@ -692,6 +692,7 @@ static void btc_dm_acl_link_stat(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat)
#if (BTC_GAP_BT_INCLUDED == TRUE)
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_event_t event = ESP_BT_GAP_EVT_MAX;
bt_bdaddr_t bt_addr;
switch (p_acl_link_stat->event) {
case BTA_ACL_LINK_STAT_CONN_CMPL: {
@ -714,6 +715,17 @@ static void btc_dm_acl_link_stat(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat)
}
}
if (p_acl_link_stat->event == BTA_ACL_LINK_STAT_CONN_CMPL &&
p_acl_link_stat->link_act.conn_cmpl.status == HCI_SUCCESS) {
memcpy(bt_addr.address, p_acl_link_stat->link_act.conn_cmpl.bd_addr, sizeof(bt_addr.address));
if (btc_storage_update_active_device(&bt_addr)) {
BTC_TRACE_EVENT("Device: %02x:%02x:%02x:%02x:%02x:%02x, is not in bond list",
bt_addr.address[0], bt_addr.address[1],
bt_addr.address[2], bt_addr.address[3],
bt_addr.address[4], bt_addr.address[5]);
}
}
esp_bt_gap_cb_t cb = (esp_bt_gap_cb_t)btc_profile_cb_get(BTC_PID_GAP_BT);
if (cb) {
cb(event, &param);
@ -745,7 +757,7 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
case BTA_DM_ENABLE_EVT: {
btc_clear_services_mask();
#if (SMP_INCLUDED == TRUE)
//load the bonding device to the btm layer
//load the bonding device to the btm layer
btc_storage_load_bonded_devices();
#endif ///SMP_INCLUDED == TRUE

View File

@ -37,7 +37,7 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
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 first bonded device */
/* 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_DEVICE_RECORDS && !btc_config_has_section(bdstr)) {
const btc_config_section_iter_t *iter = btc_config_section_begin();
const btc_config_section_iter_t *remove_iter = iter;
@ -143,30 +143,31 @@ static bt_status_t btc_in_fetch_bonded_devices(int add)
btc_config_exist(name, BTC_STORAGE_SC_SUPPORT) && btc_config_exist(name, BTC_STORAGE_LINK_KEY_STR)) {
/* load bt device */
status = _btc_storage_in_fetch_bonded_bt_device(name, add);
} else {
}
if (btc_config_exist(name, BTC_BLE_STORAGE_DEV_TYPE_STR)) {
#if (BLE_INCLUDED == TRUE)
/* load ble device */
status = _btc_storage_in_fetch_bonded_ble_device(name, 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);
if (!string_is_bdaddr(remove_section)) {
remove_iter = btc_config_section_next(remove_iter);
continue;
}
/* 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);
if (!string_is_bdaddr(remove_section)) {
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 : %s", remove_section);
}
continue;
}
/* write into nvs */
btc_config_flush();
break;
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 : %s", remove_section);
}
}
/* write into nvs */
btc_config_flush();
break;
}
}
btc_config_unlock();
@ -305,6 +306,32 @@ bt_status_t btc_storage_get_bonded_bt_devices_list(bt_bdaddr_t *bond_dev, int *d
return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function btc_storage_update_active_device
**
** Description BTC storage API - Once an ACL link is established and remote
** bd_addr is already stored in NVRAM, update the config and update
** the remote device to be the newest active device, The updates will
** not be stored into NVRAM immediately.
**
** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bool btc_storage_update_active_device(bt_bdaddr_t *remote_bd_addr)
{
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
bool ret = false;
BTC_TRACE_DEBUG("Update active device: Remote device:%s\n", bdstr);
btc_config_lock();
ret = btc_config_update_newest_section(bdstr);
btc_config_unlock();
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
int btc_storage_get_num_all_bond_devices(void) {
int num_dev = 0;

View File

@ -85,8 +85,6 @@ bt_status_t btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush);
bt_status_t btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush);
bt_status_t btc_storage_load_bonded_ble_devices(void);
bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num);
int btc_storage_get_num_ble_bond_devices(void);

View File

@ -36,6 +36,7 @@ bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, si
bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length);
bool btc_config_remove(const char *section, const char *key);
bool btc_config_remove_section(const char *section);
bool btc_config_update_newest_section(const char *section);
size_t btc_config_get_bin_length(const char *section, const char *key);

View File

@ -96,4 +96,18 @@ bt_status_t btc_storage_get_bonded_bt_devices_list(bt_bdaddr_t *bond_dev, int *d
*******************************************************************************/
int btc_storage_get_num_all_bond_devices(void);
/*******************************************************************************
**
** Function btc_storage_update_active_device
**
** Description BTC storage API - Once an ACL link is established and remote
** bd_addr is already stored in NVRAM, update the config and update
** the remote device to be the newest active device. The updates will
** not be stored into NVRAM immediately.
**
** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bool btc_storage_update_active_device(bt_bdaddr_t *remote_bd_addr);
#endif /* BTC_STORAGE_H */

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
@ -15,6 +15,8 @@
#include "common/bt_trace.h"
#include "osi/allocator.h"
#include "esp_gattc_api.h"
#include "btc/btc_storage.h"
#include "common/bt_defs.h"
#if (GATTC_INCLUDED == TRUE)
static inline void btc_gattc_cb_to_app(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
@ -924,6 +926,15 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
}
case BTA_GATTC_CONNECT_EVT: {
tBTA_GATTC_CONNECT *connect = &arg->connect;
bt_bdaddr_t bt_addr;
memcpy(bt_addr.address, connect->remote_bda, sizeof(bt_addr.address));
if (btc_storage_update_active_device(&bt_addr)) {
BTC_TRACE_EVENT("Device: %02x:%02x:%02x:%02x:%02x:%02x, is not in bond list",
bt_addr.address[0], bt_addr.address[1],
bt_addr.address[2], bt_addr.address[3],
bt_addr.address[4], bt_addr.address[5]);
}
gattc_if = connect->client_if;
param.connect.conn_id = BTC_GATT_GET_CONN_ID(connect->conn_id);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -16,6 +16,8 @@
#include "osi/allocator.h"
#include "btc/btc_main.h"
#include "esp_gatts_api.h"
#include "btc/btc_storage.h"
#include "common/bt_defs.h"
#if (GATTS_INCLUDED == TRUE)
@ -898,7 +900,16 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
btc_gatts_cb_to_app(ESP_GATTS_STOP_EVT, gatts_if, &param);
break;
case BTA_GATTS_CONNECT_EVT:
case BTA_GATTS_CONNECT_EVT: {
bt_bdaddr_t bt_addr;
memcpy(bt_addr.address, p_data->conn.remote_bda, sizeof(bt_addr.address));
if (btc_storage_update_active_device(&bt_addr)) {
BTC_TRACE_EVENT("Device: %02x:%02x:%02x:%02x:%02x:%02x, is not in bond list",
bt_addr.address[0], bt_addr.address[1],
bt_addr.address[2], bt_addr.address[3],
bt_addr.address[4], bt_addr.address[5]);
}
gatts_if = p_data->conn.server_if;
param.connect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id);
param.connect.link_role = p_data->conn.link_role;
@ -910,6 +921,7 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
param.connect.conn_handle = p_data->conn.conn_handle;
btc_gatts_cb_to_app(ESP_GATTS_CONNECT_EVT, gatts_if, &param);
break;
}
case BTA_GATTS_DISCONNECT_EVT:
gatts_if = p_data->conn.server_if;
param.disconnect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id);