Pārlūkot izejas kodu

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.
gongyantao 2 gadi atpakaļ
vecāks
revīzija
fdc35e772b

+ 26 - 0
components/bt/common/osi/config.c

@@ -254,6 +254,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)) {
+        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)) {
+            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);

+ 5 - 0
components/bt/common/osi/include/osi/config.h

@@ -99,6 +99,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.

+ 1 - 48
components/bt/host/bluedroid/btc/core/btc_ble_storage.c

@@ -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;

+ 8 - 0
components/bt/host/bluedroid/btc/core/btc_config.c

@@ -311,6 +311,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);

+ 13 - 1
components/bt/host/bluedroid/btc/core/btc_dm.c

@@ -678,6 +678,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: {
@@ -700,6 +701,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);
@@ -731,7 +743,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
 

+ 44 - 17
components/bt/host/bluedroid/btc/core/btc_storage.c

@@ -39,7 +39,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;
@@ -145,30 +145,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();
@@ -307,6 +308,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;
+}
+
 #if (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE)
 /*******************************************************************************
  *

+ 0 - 2
components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h

@@ -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);

+ 1 - 0
components/bt/host/bluedroid/btc/include/btc/btc_config.h

@@ -28,6 +28,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);
 

+ 26 - 12
components/bt/host/bluedroid/btc/include/btc/btc_storage.h

@@ -89,6 +89,31 @@ int btc_storage_get_num_bt_bond_devices(void);
 *******************************************************************************/
 bt_status_t btc_storage_get_bonded_bt_devices_list(bt_bdaddr_t *bond_dev, int *dev_num);
 
+/*******************************************************************************
+**
+** Function         btc_storage_get_num_all_bond_devices
+**
+** Description      BTC storage API - get all the num of the bonded device from NVRAM
+**
+** Returns          the num of the bonded device
+**
+*******************************************************************************/
+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);
+
 #if (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE)
 /*******************************************************************************
  *
@@ -166,18 +191,7 @@ bt_status_t btc_storage_set_hidd(bt_bdaddr_t *remote_bd_addr);
  ******************************************************************************/
 bt_status_t btc_storage_remove_hidd(bt_bdaddr_t *remote_bd_addr);
 #endif //(defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE)
+#endif /* BTC_STORAGE_H */
 #ifdef __cplusplus
 }
 #endif
-/*******************************************************************************
-**
-** Function         btc_storage_get_num_all_bond_devices
-**
-** Description      BTC storage API - get all the num of the bonded device from NVRAM
-**
-** Returns          the num of the bonded device
-**
-*******************************************************************************/
-int btc_storage_get_num_all_bond_devices(void);
-
-#endif /* BTC_STORAGE_H */

+ 12 - 1
components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c

@@ -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);

+ 14 - 2
components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c

@@ -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);