OSDN Git Service

HFP: Return SDP status to HFP layer
authorJack He <siyuanh@google.com>
Sun, 20 May 2018 03:05:02 +0000 (20:05 -0700)
committerJack He <siyuanh@google.com>
Mon, 21 May 2018 18:05:33 +0000 (11:05 -0700)
* Fix an error introduced in change Ic0b4498dd623d0ea31b4513d6b7861cae390bc72
  so that SDP status is sent up to the HFP BTA layer
* With SDP status correctly passed up, HFP BTA layer can correctly
  determine when to continue SDP search for HSP
* When open connection to HFP or HSP devices, use a control block's
  registered services instead of passing in opening services every time
  from BTIF layer
* Do not use a control block that are in CONNECTING or DISCONNECTING
  state
* Add a crash in btif_hf.cc:connect_int() to gurantee that no control
  block is in connecting or disconnecting state when connect_int is
  called as it should be guranteed by the btif queue configuration

Bug: 74234576
Test: connect to headset, make calls and hangup
Change-Id: I5e2bce8c2f0f51bd3fd3e85e82827c5fb5e92887

bta/ag/bta_ag_act.cc
bta/ag/bta_ag_api.cc
bta/ag/bta_ag_int.h
bta/ag/bta_ag_main.cc
bta/ag/bta_ag_sdp.cc
bta/include/bta_ag_api.h
btif/src/btif_hf.cc

index 682140c..b078c14 100644 (file)
@@ -175,8 +175,8 @@ void bta_ag_start_dereg(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
  ******************************************************************************/
 void bta_ag_start_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
   p_scb->peer_addr = data.api_open.bd_addr;
-  p_scb->open_services = data.api_open.services;
   p_scb->cli_sec_mask = data.api_open.sec_mask;
+  p_scb->open_services = p_scb->reg_services;
 
   /* Check if RFCOMM has any incoming connection to avoid collision. */
   RawAddress pending_bd_addr = RawAddress::kEmpty;
index 4616696..7497fa7 100644 (file)
@@ -127,11 +127,9 @@ void BTA_AgDeregister(uint16_t handle) {
  * Returns          void
  *
  ******************************************************************************/
-void BTA_AgOpen(uint16_t handle, const RawAddress& bd_addr, tBTA_SEC sec_mask,
-                tBTA_SERVICE_MASK services) {
+void BTA_AgOpen(uint16_t handle, const RawAddress& bd_addr, tBTA_SEC sec_mask) {
   tBTA_AG_DATA data = {};
   data.api_open.bd_addr = bd_addr;
-  data.api_open.services = services;
   data.api_open.sec_mask = sec_mask;
   do_in_bta_thread(FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, handle,
                                          BTA_AG_API_OPEN_EVT, data));
index cb5f9a9..c6b3230 100644 (file)
@@ -126,7 +126,6 @@ typedef struct {
 /* data type for BTA_AG_API_OPEN_EVT */
 typedef struct {
   RawAddress bd_addr;
-  tBTA_SERVICE_MASK services;
   tBTA_SEC sec_mask;
 } tBTA_AG_API_OPEN;
 
index ec396a3..f70027f 100644 (file)
@@ -565,7 +565,6 @@ void bta_ag_resume_open(tBTA_AG_SCB* p_scb) {
     LOG(INFO) << __func__ << ": Resume connection to " << p_scb->peer_addr
               << ", handle" << bta_ag_scb_to_idx(p_scb);
     tBTA_AG_DATA open_data = {.api_open.bd_addr = p_scb->peer_addr,
-                              .api_open.services = p_scb->open_services,
                               .api_open.sec_mask = p_scb->cli_sec_mask};
     bta_ag_sm_execute(p_scb, BTA_AG_API_OPEN_EVT, open_data);
   } else {
index c2b8bdc..8ff39fd 100644 (file)
@@ -86,8 +86,9 @@ static void bta_ag_sdp_cback(uint16_t status, uint8_t idx) {
     } else {
       event = BTA_AG_DISC_INT_RES_EVT;
     }
+    tBTA_AG_DATA disc_result = {.disc_result.status = status};
     do_in_bta_thread(FROM_HERE, base::Bind(&bta_ag_sm_execute_by_handle, idx,
-                                           event, tBTA_AG_DATA::kEmpty));
+                                           event, disc_result));
   }
 }
 
index 0f6550e..b968ae6 100644 (file)
@@ -524,8 +524,7 @@ void BTA_AgDeregister(uint16_t handle);
  * Returns          void
  *
  ******************************************************************************/
-void BTA_AgOpen(uint16_t handle, const RawAddress& bd_addr, tBTA_SEC sec_mask,
-                tBTA_SERVICE_MASK services);
+void BTA_AgOpen(uint16_t handle, const RawAddress& bd_addr, tBTA_SEC sec_mask);
 
 /*******************************************************************************
  *
index a3306ec..20af647 100644 (file)
@@ -587,33 +587,35 @@ static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG* p_data) {
  ******************************************************************************/
 static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) {
   CHECK_BTHF_INIT();
-  int i;
-  for (i = 0; i < btif_max_hf_clients;) {
-    if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
-         (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED))) {
-      i++;
-    } else {
+  if (is_connected(bd_addr)) {
+    BTIF_TRACE_WARNING("%s: device %s is already connected", __func__,
+                       bd_addr->ToString().c_str());
+    return BT_STATUS_BUSY;
+  }
+  btif_hf_cb_t* hf_cb = nullptr;
+  for (int i = 0; i < btif_max_hf_clients; i++) {
+    if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_DISCONNECTED) {
+      hf_cb = &btif_hf_cb[i];
       break;
     }
+    // Due to btif queue implementation, when connect_int is called, no btif
+    // control block should be in connecting state
+    // Crash here to prevent future code changes from breaking this mechanism
+    if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTING) {
+      LOG(FATAL) << __func__ << ": " << btif_hf_cb[i].connected_bda
+                 << ", handle " << btif_hf_cb[i].handle
+                 << ", is still in connecting state " << btif_hf_cb[i].state;
+    }
   }
-
-  if (i == btif_max_hf_clients) {
+  if (hf_cb == nullptr) {
     BTIF_TRACE_WARNING(
         "%s: Cannot connect %s: maximum %d clients already connected", __func__,
         bd_addr->ToString().c_str(), btif_max_hf_clients);
     return BT_STATUS_BUSY;
   }
-  if (is_connected(bd_addr)) {
-    BTIF_TRACE_WARNING("%s: device %s is already connected", __func__,
-                       bd_addr->ToString().c_str());
-    return BT_STATUS_BUSY;
-  }
-
-  btif_hf_cb[i].state = BTHF_CONNECTION_STATE_CONNECTING;
-  btif_hf_cb[i].connected_bda = *bd_addr;
-
-  BTA_AgOpen(btif_hf_cb[i].handle, btif_hf_cb[i].connected_bda,
-             BTIF_HF_SECURITY, BTIF_HF_SERVICES);
+  hf_cb->state = BTHF_CONNECTION_STATE_CONNECTING;
+  hf_cb->connected_bda = *bd_addr;
+  BTA_AgOpen(hf_cb->handle, hf_cb->connected_bda, BTIF_HF_SECURITY);
   return BT_STATUS_SUCCESS;
 }