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

Commit 021823b1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Handle HCI setup ESCO connection failures" into tm-dev am: a215df9a

parents df241c69 a215df9a
Loading
Loading
Loading
Loading
+70 −57
Original line number Original line Diff line number Diff line
@@ -723,8 +723,8 @@ void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class,
 * Returns          void
 * Returns          void
 *
 *
 ******************************************************************************/
 ******************************************************************************/
void btm_sco_connected(tHCI_STATUS hci_status, const RawAddress& bda,
void btm_sco_connected(const RawAddress& bda, uint16_t hci_handle,
                       uint16_t hci_handle, tBTM_ESCO_DATA* p_esco_data) {
                       tBTM_ESCO_DATA* p_esco_data) {
  tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
  tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
  uint16_t xx;
  uint16_t xx;
  bool spt = false;
  bool spt = false;
@@ -734,7 +734,63 @@ void btm_sco_connected(tHCI_STATUS hci_status, const RawAddress& bda,
    if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
    if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
         (p->state == SCO_ST_W4_CONN_RSP)) &&
         (p->state == SCO_ST_W4_CONN_RSP)) &&
        (p->rem_bd_known) && (p->esco.data.bd_addr == bda)) {
        (p->rem_bd_known) && (p->esco.data.bd_addr == bda)) {
      if (hci_status != HCI_SUCCESS) {
      BTM_LogHistory(
          kBtmLogTag, bda, "Connection created",
          base::StringPrintf("sco_idx:%hu handle:0x%04x ", xx, hci_handle));

      if (p->state == SCO_ST_LISTENING) spt = true;

      p->state = SCO_ST_CONNECTED;
      p->hci_handle = hci_handle;

      BTM_LogHistory(kBtmLogTag, bda, "Connection success",
                     base::StringPrintf("handle:0x%04x %s", hci_handle,
                                        (spt) ? "listener" : "initiator"));

      if (!btm_cb.sco_cb.esco_supported) {
        p->esco.data.link_type = BTM_LINK_TYPE_SCO;
        if (spt) {
          parms.packet_types = p->esco.setup.packet_types;
          /* Keep the other parameters the same for SCO */
          parms.max_latency_ms = p->esco.setup.max_latency_ms;
          parms.retransmission_effort = p->esco.setup.retransmission_effort;

          BTM_ChangeEScoLinkParms(xx, &parms);
        }
      } else {
        if (p_esco_data) p->esco.data = *p_esco_data;
      }

      (*p->p_conn_cb)(xx);

      bluetooth::audio::sco::open();

      return;
    }
  }
}

/*******************************************************************************
 *
 * Function         btm_sco_connection_failed
 *
 * Description      This function is called by BTIF when an (e)SCO connection
 *                  setup is failed.
 *
 * Returns          void
 *
 ******************************************************************************/
void btm_sco_connection_failed(tHCI_STATUS hci_status, const RawAddress& bda,
                               uint16_t hci_handle,
                               tBTM_ESCO_DATA* p_esco_data) {
  tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
  uint16_t xx;

  for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
    if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
         (p->state == SCO_ST_W4_CONN_RSP)) &&
        (p->rem_bd_known) &&
        (p->esco.data.bd_addr == bda || bda == RawAddress::kEmpty)) {
      /* Report the error if originator, otherwise remain in Listen mode */
      /* Report the error if originator, otherwise remain in Listen mode */
      if (p->is_orig) {
      if (p->is_orig) {
        LOG_DEBUG("SCO initiating connection failed handle:0x%04x reason:%s",
        LOG_DEBUG("SCO initiating connection failed handle:0x%04x reason:%s",
@@ -776,49 +832,6 @@ void btm_sco_connected(tHCI_STATUS hci_status, const RawAddress& bda,
      }
      }
      return;
      return;
    }
    }

      BTM_LogHistory(
          kBtmLogTag, bda, "Connection created",
          base::StringPrintf("sco_idx:%hu handle:0x%04x ", xx, hci_handle));

      if (p->state == SCO_ST_LISTENING) spt = true;

      p->state = SCO_ST_CONNECTED;
      p->hci_handle = hci_handle;

      if (hci_status == HCI_SUCCESS) {
        BTM_LogHistory(kBtmLogTag, bda, "Connection success",
                       base::StringPrintf("handle:0x%04x %s", hci_handle,
                                          (spt) ? "listener" : "initiator"));
      } else {
        BTM_LogHistory(
            kBtmLogTag, bda, "Connection failed",
            base::StringPrintf(
                "reason:%s",
                hci_reason_code_text(static_cast<tHCI_REASON>(hci_status))
                    .c_str()));
      }

      if (!btm_cb.sco_cb.esco_supported) {
        p->esco.data.link_type = BTM_LINK_TYPE_SCO;
        if (spt) {
          parms.packet_types = p->esco.setup.packet_types;
          /* Keep the other parameters the same for SCO */
          parms.max_latency_ms = p->esco.setup.max_latency_ms;
          parms.retransmission_effort = p->esco.setup.retransmission_effort;

          BTM_ChangeEScoLinkParms(xx, &parms);
        }
      } else {
        if (p_esco_data) p->esco.data = *p_esco_data;
      }

      (*p->p_conn_cb)(xx);

      bluetooth::audio::sco::open();

      return;
    }
  }
  }
}
}


+15 −2
Original line number Original line Diff line number Diff line
@@ -1138,7 +1138,12 @@ static void btu_hcif_esco_connection_comp_evt(const uint8_t* p) {
  handle = HCID_GET_HANDLE(handle);
  handle = HCID_GET_HANDLE(handle);


  data.bd_addr = bda;
  data.bd_addr = bda;
  btm_sco_connected(static_cast<tHCI_STATUS>(status), bda, handle, &data);
  if (status == HCI_SUCCESS) {
    btm_sco_connected(bda, handle, &data);
  } else {
    btm_sco_connection_failed(static_cast<tHCI_STATUS>(status), bda, handle,
                              &data);
  }
}
}


/*******************************************************************************
/*******************************************************************************
@@ -1393,7 +1398,9 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
    case HCI_ENH_SETUP_ESCO_CONNECTION:
    case HCI_ENH_SETUP_ESCO_CONNECTION:
      if (status != HCI_SUCCESS) {
      if (status != HCI_SUCCESS) {
        STREAM_TO_UINT16(handle, p_cmd);
        STREAM_TO_UINT16(handle, p_cmd);
        // Determine if initial connection failed or is a change of setup
        RawAddress addr(RawAddress::kEmpty);
        btm_sco_connection_failed(static_cast<tHCI_STATUS>(status), addr,
                                  handle, nullptr);
      }
      }
      break;
      break;


@@ -1436,6 +1443,12 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
  }
  }
}
}


void bluetooth::legacy::testing::btu_hcif_hdl_command_status(
    uint16_t opcode, uint8_t status, const uint8_t* p_cmd,
    void* p_vsc_status_cback) {
  ::btu_hcif_hdl_command_status(opcode, status, p_cmd, p_vsc_status_cback);
}

/*******************************************************************************
/*******************************************************************************
 *
 *
 * Function         btu_hcif_command_status_evt
 * Function         btu_hcif_command_status_evt
+5 −0
Original line number Original line Diff line number Diff line
@@ -53,6 +53,11 @@ void btu_hcif_send_cmd_with_cb(const base::Location& posted_from,
                               uint16_t opcode, uint8_t* params,
                               uint16_t opcode, uint8_t* params,
                               uint8_t params_len,
                               uint8_t params_len,
                               base::OnceCallback<void(uint8_t*, uint16_t)> cb);
                               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* p_vsc_status_cback);
}  // namespace bluetooth::legacy::testing


/* Functions provided by btu_task.cc
/* Functions provided by btu_task.cc
 ***********************************
 ***********************************
+6 −2
Original line number Original line Diff line number Diff line
@@ -30,8 +30,12 @@ extern void btm_sco_chk_pend_unpark(tHCI_STATUS hci_status,
                                    uint16_t hci_handle);
                                    uint16_t hci_handle);
extern void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class,
extern void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class,
                             uint8_t link_type);
                             uint8_t link_type);
extern void btm_sco_connected(tHCI_STATUS hci_status, const RawAddress& bda,
extern void btm_sco_connected(const RawAddress& bda, uint16_t hci_handle,
                              uint16_t hci_handle, tBTM_ESCO_DATA* p_esco_data);
                              tBTM_ESCO_DATA* p_esco_data);
extern void btm_sco_connection_failed(tHCI_STATUS hci_status,
                                      const RawAddress& bda,
                                      uint16_t hci_handle,
                                      tBTM_ESCO_DATA* p_esco_data);
extern bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason);
extern bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason);


void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason);
void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason);
+19 −1
Original line number Original line Diff line number Diff line
@@ -15,16 +15,34 @@
 */
 */


#include <gtest/gtest.h>
#include <gtest/gtest.h>

#include <cstdint>
#include <cstdint>
#include <map>
#include <map>
#include <string>
#include <string>


#include "stack/include/btu.h"
#include "stack/include/btu.h"
#include "stack/include/hci_error_code.h"
#include "stack/include/hcidefs.h"


std::map<std::string, int> mock_function_count_map;
std::map<std::string, int> mock_function_count_map;


/* Function for test provided by btu_hcif.cc */
void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
                                 const uint8_t* p_cmd,
                                 void* p_vsc_status_cback);

void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}
void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}


class StackBtuTest : public ::testing::Test {};
class StackBtuTest : public ::testing::Test {
 protected:
  void SetUp() override { mock_function_count_map.clear(); }
};


TEST_F(StackBtuTest, post_on_main) {}
TEST_F(StackBtuTest, post_on_main) {}

TEST_F(StackBtuTest, btm_sco_connection_failed_called) {
  uint8_t p_cmd[10];  // garbage data for testing
  bluetooth::legacy::testing::btu_hcif_hdl_command_status(
      HCI_SETUP_ESCO_CONNECTION, HCI_ERR_UNSPECIFIED, p_cmd, nullptr);
  ASSERT_EQ(1, mock_function_count_map["btm_sco_connection_failed"]);
}
Loading