Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da3a103e authored by weichinweng's avatar weichinweng
Browse files

HFP: fix collision for the outgoing and incoming connection

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
Merged-In: Id5495bd3ecb1ed9e03de5bd74a61ab102604eaae
parent ad453fd0
Loading
Loading
Loading
Loading
+38 −2
Original line number Diff line number Diff line
@@ -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