OSDN Git Service

Queue discovery and device inquiry while bonding
authorRahul Sabnis <rahulsabnis@google.com>
Thu, 20 May 2021 04:08:18 +0000 (21:08 -0700)
committerWilliam Escande <wescande@google.com>
Thu, 1 Jul 2021 22:37:05 +0000 (22:37 +0000)
Tag: #feature
Bug: 187165224
Test: Manual
Merged-In: I260c967de0f4656ee852a098a98c9ceb0e6dfbde
Change-Id: I260c967de0f4656ee852a098a98c9ceb0e6dfbde

bta/dm/bta_dm_act.cc
bta/dm/bta_dm_api.cc
bta/dm/bta_dm_int.h
bta/dm/bta_dm_main.cc
bta/include/bta_api.h
btif/src/btif_dm.cc
stack/test/common/mock_bta_dm_act.cc
test/mock/mock_bta_dm_act.cc
test/mock/mock_bta_dm_api.cc

index c3cefe6..16890ee 100644 (file)
@@ -39,6 +39,7 @@
 #include "main/shim/btm_api.h"
 #include "main/shim/dumpsys.h"
 #include "main/shim/shim.h"
+#include "osi/include/fixed_queue.h"
 #include "osi/include/log.h"
 #include "osi/include/osi.h"
 #include "stack/btm/btm_sec.h"
@@ -312,6 +313,8 @@ void BTA_dm_on_hw_off() {
   /* hw is ready, go on with BTA DM initialization */
   alarm_free(bta_dm_search_cb.search_timer);
   alarm_free(bta_dm_search_cb.gatt_close_timer);
+  osi_free(bta_dm_search_cb.p_pending_search);
+  fixed_queue_free(bta_dm_search_cb.pending_discovery_queue, osi_free);
   memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));
 
   /* notify BTA DM is now unactive */
@@ -335,6 +338,8 @@ void BTA_dm_on_hw_on() {
   /* hw is ready, go on with BTA DM initialization */
   alarm_free(bta_dm_search_cb.search_timer);
   alarm_free(bta_dm_search_cb.gatt_close_timer);
+  osi_free(bta_dm_search_cb.p_pending_search);
+  fixed_queue_free(bta_dm_search_cb.pending_discovery_queue, osi_free);
   memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));
   /*
    * TODO: Should alarm_free() the bta_dm_search_cb timers during
@@ -343,6 +348,7 @@ void BTA_dm_on_hw_on() {
   bta_dm_search_cb.search_timer = alarm_new("bta_dm_search.search_timer");
   bta_dm_search_cb.gatt_close_timer =
       alarm_new("bta_dm_search.gatt_close_timer");
+  bta_dm_search_cb.pending_discovery_queue = fixed_queue_new(SIZE_MAX);
 
   memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs));
   memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));
@@ -1306,6 +1312,8 @@ void bta_dm_search_cmpl() {
   bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
 
   bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
+
+  bta_dm_execute_queued_request();
 }
 
 /*******************************************************************************
@@ -1402,13 +1410,13 @@ void bta_dm_free_sdp_db() {
  *
  * Function         bta_dm_queue_search
  *
- * Description      Queues search command while search is being cancelled
+ * Description      Queues search command
  *
  * Returns          void
  *
  ******************************************************************************/
 void bta_dm_queue_search(tBTA_DM_MSG* p_data) {
-  bta_dm_search_clear_queue();
+  osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search);
   bta_dm_search_cb.p_pending_search =
       (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
   memcpy(bta_dm_search_cb.p_pending_search, p_data, sizeof(tBTA_DM_API_SEARCH));
@@ -1418,17 +1426,62 @@ void bta_dm_queue_search(tBTA_DM_MSG* p_data) {
  *
  * Function         bta_dm_queue_disc
  *
- * Description      Queues discovery command while search is being cancelled
+ * Description      Queues discovery command
  *
  * Returns          void
  *
  ******************************************************************************/
 void bta_dm_queue_disc(tBTA_DM_MSG* p_data) {
-  bta_dm_search_clear_queue();
-  bta_dm_search_cb.p_pending_discovery =
+  tBTA_DM_MSG* p_pending_discovery =
       (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
-  memcpy(bta_dm_search_cb.p_pending_discovery, p_data,
-         sizeof(tBTA_DM_API_DISCOVER));
+  memcpy(p_pending_discovery, p_data, sizeof(tBTA_DM_API_DISCOVER));
+  fixed_queue_enqueue(bta_dm_search_cb.pending_discovery_queue,
+                      p_pending_discovery);
+}
+
+/*******************************************************************************
+ *
+ * Function         bta_dm_execute_queued_request
+ *
+ * Description      Executes queued request if one exists
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+void bta_dm_execute_queued_request() {
+  if (bta_dm_search_cb.p_pending_search) {
+    // Updated queued event to search event to trigger start search
+    if (bta_dm_search_cb.p_pending_search->hdr.event ==
+        BTA_DM_API_QUEUE_SEARCH_EVT) {
+      bta_dm_search_cb.p_pending_search->hdr.event = BTA_DM_API_SEARCH_EVT;
+    }
+    LOG_INFO("%s Start pending search", __func__);
+    bta_sys_sendmsg(bta_dm_search_cb.p_pending_search);
+    bta_dm_search_cb.p_pending_search = NULL;
+  } else {
+    tBTA_DM_MSG* p_pending_discovery = (tBTA_DM_MSG*)fixed_queue_try_dequeue(
+        bta_dm_search_cb.pending_discovery_queue);
+    if (p_pending_discovery) {
+      if (p_pending_discovery->hdr.event == BTA_DM_API_QUEUE_DISCOVER_EVT) {
+        p_pending_discovery->hdr.event = BTA_DM_API_DISCOVER_EVT;
+      }
+      LOG_INFO("%s Start pending discovery", __func__);
+      bta_sys_sendmsg(p_pending_discovery);
+    }
+  }
+}
+
+/*******************************************************************************
+ *
+ * Function         bta_dm_is_search_request_queued
+ *
+ * Description      Checks if there is a queued search request
+ *
+ * Returns          bool
+ *
+ ******************************************************************************/
+bool bta_dm_is_search_request_queued() {
+  return bta_dm_search_cb.p_pending_search != NULL;
 }
 
 /*******************************************************************************
@@ -1442,7 +1495,7 @@ void bta_dm_queue_disc(tBTA_DM_MSG* p_data) {
  ******************************************************************************/
 void bta_dm_search_clear_queue() {
   osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search);
-  osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_discovery);
+  fixed_queue_flush(bta_dm_search_cb.pending_discovery_queue, osi_free);
 }
 
 /*******************************************************************************
@@ -1454,15 +1507,7 @@ void bta_dm_search_clear_queue() {
  * Returns          void
  *
  ******************************************************************************/
-void bta_dm_search_cancel_cmpl() {
-  if (bta_dm_search_cb.p_pending_search) {
-    bta_sys_sendmsg(bta_dm_search_cb.p_pending_search);
-    bta_dm_search_cb.p_pending_search = NULL;
-  } else if (bta_dm_search_cb.p_pending_discovery) {
-    bta_sys_sendmsg(bta_dm_search_cb.p_pending_discovery);
-    bta_dm_search_cb.p_pending_discovery = NULL;
-  }
-}
+void bta_dm_search_cancel_cmpl() { bta_dm_execute_queued_request(); }
 
 /*******************************************************************************
  *
index 2611ebf..8e9e4c1 100644 (file)
@@ -77,11 +77,16 @@ void BTA_DmSetDeviceName(char* p_name) {
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback) {
+void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback, bool is_bonding_or_sdp) {
   tBTA_DM_API_SEARCH* p_msg =
       (tBTA_DM_API_SEARCH*)osi_calloc(sizeof(tBTA_DM_API_SEARCH));
 
-  p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
+  /* Queue request if a device is bonding or performing service discovery */
+  if (is_bonding_or_sdp) {
+    p_msg->hdr.event = BTA_DM_API_QUEUE_SEARCH_EVT;
+  } else {
+    p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
+  }
   p_msg->p_cback = p_cback;
 
   bta_sys_sendmsg(p_msg);
@@ -129,11 +134,15 @@ void BTA_DmSearchCancel(void) {
  *
  ******************************************************************************/
 void BTA_DmDiscover(const RawAddress& bd_addr, tBTA_DM_SEARCH_CBACK* p_cback,
-                    tBT_TRANSPORT transport) {
+                    tBT_TRANSPORT transport, bool is_bonding_or_sdp) {
   tBTA_DM_API_DISCOVER* p_msg =
       (tBTA_DM_API_DISCOVER*)osi_calloc(sizeof(tBTA_DM_API_DISCOVER));
 
-  p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT;
+  if (is_bonding_or_sdp) {
+    p_msg->hdr.event = BTA_DM_API_QUEUE_DISCOVER_EVT;
+  } else {
+    p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT;
+  }
   p_msg->bd_addr = bd_addr;
   p_msg->transport = transport;
   p_msg->p_cback = p_cback;
index 6e433d2..1f5952e 100644 (file)
@@ -66,17 +66,19 @@ enum {
   BTA_DM_SDP_RESULT_EVT,
   BTA_DM_SEARCH_CMPL_EVT,
   BTA_DM_DISCOVERY_RESULT_EVT,
-  BTA_DM_DISC_CLOSE_TOUT_EVT
+  BTA_DM_DISC_CLOSE_TOUT_EVT,
+  BTA_DM_API_QUEUE_SEARCH_EVT,
+  BTA_DM_API_QUEUE_DISCOVER_EVT
 };
 
-/* data type for BTA_DM_API_SEARCH_EVT */
+/* data type for BTA_DM_API_SEARCH_EVT and BTA_DM_API_QUEUE_SEARCH_EVT */
 typedef struct {
   BT_HDR_RIGID hdr;
   tBTA_SERVICE_MASK services;
   tBTA_DM_SEARCH_CBACK* p_cback;
 } tBTA_DM_API_SEARCH;
 
-/* data type for BTA_DM_API_DISCOVER_EVT */
+/* data type for BTA_DM_API_DISCOVER_EVT and BTA_DM_API_QUEUE_DISCOVER_EVT */
 typedef struct {
   BT_HDR_RIGID hdr;
   RawAddress bd_addr;
@@ -362,7 +364,7 @@ typedef struct {
   alarm_t* search_timer;
   uint8_t service_index;
   tBTA_DM_MSG* p_pending_search;
-  tBTA_DM_MSG* p_pending_discovery;
+  fixed_queue_t* pending_discovery_queue;
   bool wait_disc;
   bool sdp_results;
   bluetooth::Uuid uuid;
@@ -536,6 +538,8 @@ extern void bta_dm_search_result(tBTA_DM_MSG* p_data);
 extern void bta_dm_discovery_cmpl(tBTA_DM_MSG* p_data);
 extern void bta_dm_queue_search(tBTA_DM_MSG* p_data);
 extern void bta_dm_queue_disc(tBTA_DM_MSG* p_data);
+extern void bta_dm_execute_queued_request();
+extern bool bta_dm_is_search_request_queued();
 extern void bta_dm_search_clear_queue();
 extern void bta_dm_search_cancel_cmpl();
 extern void bta_dm_search_cancel_notify();
index 4708500..3b84f9d 100644 (file)
@@ -81,6 +81,12 @@ bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) {
         case BTA_DM_DISC_CLOSE_TOUT_EVT:
           bta_dm_close_gatt_conn(message);
           break;
+        case BTA_DM_API_QUEUE_SEARCH_EVT:
+          bta_dm_queue_search(message);
+          break;
+        case BTA_DM_API_QUEUE_DISCOVER_EVT:
+          bta_dm_queue_disc(message);
+          break;
       }
       break;
     case BTA_DM_SEARCH_ACTIVE:
@@ -100,14 +106,20 @@ bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) {
         case BTA_DM_DISC_CLOSE_TOUT_EVT:
           bta_dm_close_gatt_conn(message);
           break;
+        case BTA_DM_API_DISCOVER_EVT:
+        case BTA_DM_API_QUEUE_DISCOVER_EVT:
+          bta_dm_queue_disc(message);
+          break;
       }
       break;
     case BTA_DM_SEARCH_CANCELLING:
       switch (p_msg->event) {
         case BTA_DM_API_SEARCH_EVT:
+        case BTA_DM_API_QUEUE_SEARCH_EVT:
           bta_dm_queue_search(message);
           break;
         case BTA_DM_API_DISCOVER_EVT:
+        case BTA_DM_API_QUEUE_DISCOVER_EVT:
           bta_dm_queue_disc(message);
           break;
         case BTA_DM_SDP_RESULT_EVT:
@@ -135,6 +147,14 @@ bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) {
         case BTA_DM_DISCOVERY_RESULT_EVT:
           bta_dm_disc_result(message);
           break;
+        case BTA_DM_API_SEARCH_EVT:
+        case BTA_DM_API_QUEUE_SEARCH_EVT:
+          bta_dm_queue_search(message);
+          break;
+        case BTA_DM_API_DISCOVER_EVT:
+        case BTA_DM_API_QUEUE_DISCOVER_EVT:
+          bta_dm_queue_disc(message);
+          break;
       }
       break;
   }
index 438e8ea..8e3eb8d 100644 (file)
@@ -698,13 +698,15 @@ extern bool BTA_DmSetVisibility(bt_scan_mode_t mode);
  *                  first performs an inquiry; for each device found from the
  *                  inquiry it gets the remote name of the device.  If
  *                  parameter services is nonzero, service discovery will be
- *                  performed on each device for the services specified.
+ *                  performed on each device for the services specified. If the
+ *                  parameter is_bonding_or_sdp is true, the request will be
+ *                  queued until bonding or sdp completes
  *
  *
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback);
+extern void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback, bool is_bonding_or_sdp);
 
 /*******************************************************************************
  *
@@ -732,7 +734,7 @@ extern void BTA_DmSearchCancel(void);
  ******************************************************************************/
 extern void BTA_DmDiscover(const RawAddress& bd_addr,
                            tBTA_DM_SEARCH_CBACK* p_cback,
-                           tBT_TRANSPORT transport);
+                           tBT_TRANSPORT transport, bool is_bonding_or_sdp);
 
 /*******************************************************************************
  *
index 867b725..49be641 100644 (file)
@@ -47,6 +47,7 @@
 
 #include "advertise_data_parser.h"
 #include "bt_common.h"
+#include "bta_dm_int.h"
 #include "bta_gatt_api.h"
 #include "btif/include/stack_manager.h"
 #include "btif_api.h"
@@ -472,6 +473,7 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr,
     pairing_cb.bd_addr = bd_addr;
   } else {
     pairing_cb = {};
+    bta_dm_execute_queued_request();
   }
 }
 
@@ -1328,6 +1330,7 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event,
         // Both SDP and bonding are done, clear pairing control block in case
         // it is not already cleared
         pairing_cb = {};
+        bta_dm_execute_queued_request();
 
         // Send one empty UUID to Java to unblock pairing intent when SDP failed
         // or no UUID is discovered
@@ -1840,6 +1843,12 @@ static void bte_scan_filt_param_cfg_evt(uint8_t ref_value, uint8_t avbl_space,
 void btif_dm_start_discovery(void) {
   BTIF_TRACE_EVENT("%s", __func__);
 
+  if (bta_dm_is_search_request_queued()) {
+    LOG_INFO("%s skipping start discovery because a request is queued",
+             __func__);
+    return;
+  }
+
   /* Cleanup anything remaining on index 0 */
   BTM_BleAdvFilterParamSetup(
       BTM_BLE_SCAN_COND_DELETE, static_cast<tBTM_BLE_PF_FILT_INDEX>(0), nullptr,
@@ -1861,7 +1870,7 @@ void btif_dm_start_discovery(void) {
   /* Will be enabled to true once inquiry busy level has been received */
   btif_dm_inquiry_in_progress = false;
   /* find nearby devices */
-  BTA_DmSearch(btif_dm_search_devices_evt);
+  BTA_DmSearch(btif_dm_search_devices_evt, is_bonding_or_sdp());
 }
 
 /*******************************************************************************
@@ -2207,7 +2216,8 @@ void btif_dm_get_remote_services(RawAddress remote_addr, const int transport) {
   BTIF_TRACE_EVENT("%s: transport=%d, remote_addr=%s", __func__, transport,
                    remote_addr.ToString().c_str());
 
-  BTA_DmDiscover(remote_addr, btif_dm_search_services_evt, transport);
+  BTA_DmDiscover(remote_addr, btif_dm_search_services_evt, transport,
+                 remote_addr != pairing_cb.bd_addr && is_bonding_or_sdp());
 }
 
 void btif_dm_enable_service(tBTA_SERVICE_ID service_id, bool enable) {
index 653caae..b7b39db 100644 (file)
@@ -105,6 +105,11 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
 void bta_dm_search_cancel() { mock_function_count_map[__func__]++; }
 void bta_dm_search_cancel_cmpl() { mock_function_count_map[__func__]++; }
 void bta_dm_search_cancel_notify() { mock_function_count_map[__func__]++; }
+void bta_dm_execute_queued_request() { mock_function_count_map[__func__]++; }
+bool bta_dm_is_search_request_queued() {
+  mock_function_count_map[__func__]++;
+  return false;
+}
 void bta_dm_search_clear_queue() { mock_function_count_map[__func__]++; }
 void bta_dm_search_cmpl() { mock_function_count_map[__func__]++; }
 void bta_dm_search_result(tBTA_DM_MSG* p_data) {
index 7b7d7d4..171613d 100644 (file)
@@ -135,6 +135,11 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
 void bta_dm_search_cancel() { mock_function_count_map[__func__]++; }
 void bta_dm_search_cancel_cmpl() { mock_function_count_map[__func__]++; }
 void bta_dm_search_cancel_notify() { mock_function_count_map[__func__]++; }
+void bta_dm_execute_queued_request() { mock_function_count_map[__func__]++; }
+bool bta_dm_is_search_request_queued() {
+  mock_function_count_map[__func__]++;
+  return false;
+}
 void bta_dm_search_clear_queue() { mock_function_count_map[__func__]++; }
 void bta_dm_search_cmpl() { mock_function_count_map[__func__]++; }
 void bta_dm_search_result(tBTA_DM_MSG* p_data) {
index 5c8b07d..5fd4e80 100644 (file)
@@ -108,7 +108,7 @@ void BTA_DmConfirm(const RawAddress& bd_addr, bool accept) {
   mock_function_count_map[__func__]++;
 }
 void BTA_DmDiscover(const RawAddress& bd_addr, tBTA_DM_SEARCH_CBACK* p_cback,
-                    tBT_TRANSPORT transport) {
+                    tBT_TRANSPORT transport, bool is_bonding_or_sd) {
   mock_function_count_map[__func__]++;
 }
 void BTA_DmLocalOob(void) { mock_function_count_map[__func__]++; }
@@ -116,7 +116,7 @@ void BTA_DmPinReply(const RawAddress& bd_addr, bool accept, uint8_t pin_len,
                     uint8_t* p_pin) {
   mock_function_count_map[__func__]++;
 }
-void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback) {
+void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback, bool is_bonding_or_sdp) {
   mock_function_count_map[__func__]++;
 }
 void BTA_DmSearchCancel(void) { mock_function_count_map[__func__]++; }