OSDN Git Service

HFP: fix collision for the outgoing and incoming connection
authorweichinweng <weichinweng@google.com>
Wed, 11 Mar 2020 06:51:27 +0000 (14:51 +0800)
committerweichinweng <weichinweng@google.com>
Thu, 12 Mar 2020 06:02:09 +0000 (14:02 +0800)
Since the HF incoming connection and the HF outgoing connection use the
same HF control block (p_scb) at the same time, the case will cause the
btif_hf_cb flag going wrong due to collision. Then it will trigger a
crash due to a check failure when executing BTA_AG_OPEN_EVT. The patch
will ignore the outgoing connection when the connection
collision is happening.

Bug: 143128949
Test: manual

Change-Id: Id5495bd3ecb1ed9e03de5bd74a61ab102604eaae

btif/src/btif_hf.cc

index 04ad011..99063fd 100644 (file)
@@ -319,12 +319,48 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
     case BTA_AG_OPEN_EVT:
       // Check if an outoging connection is pending
       if (btif_hf_cb[idx].is_initiator) {
+        if ((p_data->open.status != BTA_AG_SUCCESS) &&
+            btif_hf_cb[idx].state != BTHF_CONNECTION_STATE_CONNECTING) {
+          if (p_data->open.bd_addr == btif_hf_cb[idx].connected_bda) {
+            LOG(WARNING) << __func__ << ": btif_hf_cb state["
+                         << p_data->open.status
+                         << "] is not expected, possible connection collision, "
+                            "ignoring AG open "
+                            "failure event for the same device "
+                         << p_data->open.bd_addr;
+          } else {
+            LOG(WARNING) << __func__ << ": btif_hf_cb state["
+                         << p_data->open.status
+                         << "] is not expected, possible connection collision, "
+                            "ignoring AG open failure "
+                            "event for the different devices btif_hf_cb bda: "
+                         << btif_hf_cb[idx].connected_bda
+                         << ", p_data bda: " << p_data->open.bd_addr
+                         << ", report disconnect state for p_data bda.";
+            bt_hf_callbacks->ConnectionStateCallback(
+                BTHF_CONNECTION_STATE_DISCONNECTED, &(p_data->open.bd_addr));
+          }
+          break;
+        }
+
         CHECK_EQ(btif_hf_cb[idx].state, BTHF_CONNECTION_STATE_CONNECTING)
             << "Control block must be in connecting state when initiating";
         CHECK(!btif_hf_cb[idx].connected_bda.IsEmpty())
             << "Remote device address must not be empty when initiating";
-        CHECK_EQ(btif_hf_cb[idx].connected_bda, p_data->open.bd_addr)
-            << "Incoming message's address must match expected one";
+        if (btif_hf_cb[idx].connected_bda != p_data->open.bd_addr) {
+          LOG(WARNING) << __func__
+                       << ": possible connection collision, ignore the "
+                          "outgoing connection for the "
+                          "different devices btif_hf_cb bda: "
+                       << btif_hf_cb[idx].connected_bda
+                       << ", p_data bda: " << p_data->open.bd_addr
+                       << ", report disconnect state for btif_hf_cb bda.";
+          bt_hf_callbacks->ConnectionStateCallback(
+              BTHF_CONNECTION_STATE_DISCONNECTED,
+              &(btif_hf_cb[idx].connected_bda));
+          reset_control_block(&btif_hf_cb[idx]);
+          btif_queue_advance();
+        }
       }
       if (p_data->open.status == BTA_AG_SUCCESS) {
         // In case this is an incoming connection