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

Commit 2a7a06a2 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

sco: Fix handling Command Status Failed.

When command status is failed, stack needs to find the SCO context which
state is SCO_ST_CONNECTING and is_orig is set to true, as this is the
one which is expecting COMMAND STATUS event.

Bug: 351301741
Bug: 358573137
Test: atest net_test_stack_btu
Flag: com.android.bluetooth.flags.fix_sco_command_status_handling
Change-Id: Ia07a98b5df7a1fd41c78e002e0083fb2d9eeaa45
parent be578012
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1905,6 +1905,7 @@ cc_test {
        "test/stack_btu_test.cc",
    ],
    static_libs: [
        "bluetooth_flags_c_lib_for_test",
        "libbase",
        "libbluetooth-types",
        "libbluetooth_gd",
@@ -1919,6 +1920,7 @@ cc_test {
        "libgmock",
        "liblog",
        "libosi",
        "server_configurable_flags",
    ],
    shared_libs: [
        "libbinder_ndk",
+34 −0
Original line number Diff line number Diff line
@@ -1065,6 +1065,40 @@ void btm_sco_connected(const RawAddress& bda, uint16_t hci_handle, tBTM_ESCO_DAT
  }
}

/*******************************************************************************
 *
 * Function         btm_sco_create_command_status_failed
 *
 * Description      This function is called by HCI when an (e)SCO connection
 *                  command status is failed.
 *
 * Returns          void
 *
 ******************************************************************************/
void btm_sco_create_command_status_failed(tHCI_STATUS hci_status) {
  for (uint16_t idx = 0; idx < BTM_MAX_SCO_LINKS; idx++) {
    tSCO_CONN* p = &btm_cb.sco_cb.sco_db[idx];
    if (p->state == SCO_ST_CONNECTING && p->is_orig) {
      log::info("SCO Connection failed to {}, reason: {}", p->esco.data.bd_addr, hci_status);
      p->state = SCO_ST_UNUSED;
      (*p->p_disc_cb)(idx);

      BTM_LogHistory(kBtmLogTag, p->esco.data.bd_addr, "Connection failed",
                     base::StringPrintf(
                             "locally_initiated reason:%s",
                             hci_reason_code_text(static_cast<tHCI_REASON>(hci_status)).c_str()));
      return;
    }
  }

  log::warn("No context found for the SCO connection failed");

  BTM_LogHistory(
          kBtmLogTag, RawAddress::kEmpty, "Connection failed",
          base::StringPrintf("locally_initiated reason:%s",
                             hci_reason_code_text(static_cast<tHCI_REASON>(hci_status)).c_str()));
}

/*******************************************************************************
 *
 * Function         btm_sco_connection_failed
+15 −3
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <base/functional/bind.h>
#include <base/location.h>
#include <bluetooth/log.h>
#include <com_android_bluetooth_flags.h>

#include <cstdint>

@@ -1040,10 +1041,16 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status, const u
    case HCI_SETUP_ESCO_CONNECTION:
    case HCI_ENH_SETUP_ESCO_CONNECTION:
      if (status != HCI_SUCCESS) {
        if (com::android::bluetooth::flags::fix_sco_command_status_handling()) {
          log::debug("flag: fix_sco_command_status_handling is enabled");
          btm_sco_create_command_status_failed(hci_status);
        } else {
          log::debug("flag: fix_sco_command_status_handling is disabled");
          STREAM_TO_UINT16(handle, p_cmd);
          RawAddress addr(RawAddress::kEmpty);
          btm_sco_connection_failed(hci_status, addr, handle, nullptr);
        }
      }
      break;

    case HCI_BLE_START_ENC:
@@ -1092,6 +1099,11 @@ void bluetooth::legacy::testing::btu_hcif_hdl_command_status(uint16_t opcode, ui
  ::btu_hcif_hdl_command_status(opcode, status, p_cmd);
}

void bluetooth::legacy::testing::btu_hcif_process_event(uint8_t controller_id,
                                                        const BT_HDR* p_msg) {
  ::btu_hcif_process_event(controller_id, p_msg);
}

/*******************************************************************************
 *
 * Function         btu_hcif_command_status_evt
+1 −0
Original line number Diff line number Diff line
@@ -32,4 +32,5 @@ void btu_hcif_send_cmd_with_cb(const base::Location& posted_from, uint16_t opcod
                               uint8_t params_len, base::OnceCallback<void(uint8_t*, uint16_t)> cb);
namespace bluetooth::legacy::testing {
void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status, const uint8_t* p_cmd);
void btu_hcif_process_event(uint8_t /* controller_id */, const BT_HDR* p_msg);
}  // namespace bluetooth::legacy::testing
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class, uint8_t
void btm_sco_connected(const RawAddress& bda, uint16_t hci_handle, tBTM_ESCO_DATA* p_esco_data);
void btm_sco_connection_failed(tHCI_STATUS hci_status, const RawAddress& bda, uint16_t hci_handle,
                               tBTM_ESCO_DATA* p_esco_data);
void btm_sco_create_command_status_failed(tHCI_STATUS hci_status);

bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason);

void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason);
Loading