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

Commit bc82d590 authored by Hansong Zhang's avatar Hansong Zhang
Browse files

BTM_SCO HCI path handling

Only handle CVSD case for now (just PCM).
Read data from audio service and send when we receive a packet from the
remote for now.

Tag: #refactor
Test: cert/run
Bug: 195344796
Change-Id: I647ba0392a19ba50ca4dd659aa02ade240a43afb
parent d650d346
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -60,8 +60,7 @@ typedef uint8_t esco_pcm_data_format_t;

// SCO Data Path
#define ESCO_DATA_PATH_PCM 1                /* 0x01-0xFE (PCM Chan) */
#define ESCO_DATA_PATH_HCI ((uint8_t)0x00)  /* HCI-0, 0x01-0xFE (PCM Chan) */
#define ESCO_DATA_PATH_TEST ((uint8_t)0xFF) /* 0xFF-Audio Test */
#define ESCO_DATA_PATH_HCI 0                /* HCI-0, 0x01-0xFE (PCM Chan) */
typedef uint8_t esco_data_path_t;

// eSCO constants
+3 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ cc_library_static {
        "btm/btm_main.cc",
        "acl/btm_pm.cc",
        "btm/btm_sco.cc",
        "btm/btm_sco_hci.cc",
        "btm/btm_iso.cc",
        "btm/btm_sec.cc",
        "btm/btm_scn.cc",
@@ -811,6 +812,7 @@ cc_test {
        "btm/btm_iso.cc",
        "btm/btm_main.cc",
        "btm/btm_sco.cc",
        "btm/btm_sco_hci.cc",
        "btm/btm_scn.cc",
        "btm/btm_sec.cc",
        "metrics/stack_metrics_logging.cc",
@@ -825,6 +827,7 @@ cc_test {
        "libgmock",
        "liblog",
        "libosi",
        "libudrv-uipc",
    ],
    shared_libs: [
        "libcrypto",
+1 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ source_set("stack") {
    "btm/btm_main.cc",
    "btm/btm_scn.cc",
    "btm/btm_sco.cc",
    "btm/btm_sco_hci.cc",
    "btm/btm_sec.cc",
    "btu/btu_hcif.cc",
    "btu/btu_task.cc",
+32 −12
Original line number Diff line number Diff line
@@ -40,14 +40,6 @@
#include "types/class_of_device.h"
#include "types/raw_address.h"

#ifndef ESCO_DATA_PATH
#ifdef OS_ANDROID
#define ESCO_DATA_PATH ESCO_DATA_PATH_PCM
#else
#define ESCO_DATA_PATH ESCO_DATA_PATH_HCI
#endif
#endif

extern tBTM_CB btm_cb;

namespace {
@@ -167,6 +159,16 @@ static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status,
  }
}

// Return the active (first connected) SCO connection block
static tSCO_CONN* btm_get_active_sco() {
  for (auto& link : btm_cb.sco_cb.sco_db) {
    if (link.state == SCO_ST_CONNECTED) {
      return &link;
    }
  }
  return nullptr;
}

/*******************************************************************************
 *
 * Function         btm_route_sco_data
@@ -193,13 +195,27 @@ void btm_route_sco_data(BT_HDR* p_msg) {
    return;
  }
  LOG_INFO("Received SCO packet from HCI. Dropping it since no handler so far");
  // TODO(b/195344796): Implement the SCO over HCI data path
  // std::vector<uint8_t> data(payload, payload + length);
  uint16_t handle = handle_with_flags & 0xeff;
  auto* active_sco = btm_get_active_sco();
  if (active_sco != nullptr && active_sco->hci_handle == handle) {
    // TODO: For MSBC, we need to decode here
    bluetooth::audio::sco::write(payload, length);
  }
  osi_free(p_msg);
  // For Chrome OS, we send the outgoing data after receiving an incoming one
  uint8_t out_buf[BTM_SCO_DATA_SIZE_MAX];
  auto size_read = bluetooth::audio::sco::read(out_buf, BTM_SCO_DATA_SIZE_MAX);
  auto data = std::vector<uint8_t>(out_buf, out_buf + size_read);
  // TODO: For MSBC, we need to encode here
  btm_send_sco_packet(std::move(data));
}

void btm_send_sco_packet(std::vector<uint8_t> data, uint16_t sco_handle) {
  BT_HDR* packet = btm_sco_make_packet(std::move(data), sco_handle);
void btm_send_sco_packet(std::vector<uint8_t> data) {
  auto* active_sco = btm_get_active_sco();
  if (active_sco == nullptr || data.empty()) {
    return;
  }
  BT_HDR* packet = btm_sco_make_packet(std::move(data), active_sco->hci_handle);
  bte_main_hci_send(packet, BT_EVT_TO_LM_HCI_SCO);
}

@@ -782,6 +798,8 @@ void btm_sco_connected(tHCI_STATUS hci_status, const RawAddress& bda,

      (*p->p_conn_cb)(xx);

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

      return;
    }
  }
@@ -927,6 +945,8 @@ void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason) {
  BTM_LogHistory(kBtmLogTag, bd_addr, "Disconnected",
                 base::StringPrintf("handle:0x%04x reason:%s", hci_handle,
                                    hci_reason_code_text(reason).c_str()));

  bluetooth::audio::sco::cleanup();
}

/*******************************************************************************
+29 −3
Original line number Diff line number Diff line
@@ -24,6 +24,33 @@

constexpr uint16_t kMaxScoLinks = static_cast<uint16_t>(BTM_MAX_SCO_LINKS);

#ifndef ESCO_DATA_PATH
#ifdef OS_ANDROID
#define ESCO_DATA_PATH ESCO_DATA_PATH_PCM
#else
#define ESCO_DATA_PATH ESCO_DATA_PATH_HCI
#endif
#endif

// SCO-over-HCI audio related definitions
namespace bluetooth::audio::sco {

// Initialize SCO-over-HCI socket (UIPC); the client is audio server.
void init();

// Open the socket when there is SCO connection open
void open();

// Clean up the socket when the SCO connection is done
void cleanup();

// Read from the socket (audio server) for SCO Tx
size_t read(uint8_t* p_buf, uint32_t len);

// Write to the socket from SCO Rx
size_t write(const uint8_t* buf, uint32_t len);
}  // namespace bluetooth::audio::sco

/* Define the structures needed by sco
 */

@@ -62,8 +89,6 @@ inline std::string sco_state_text(const tSCO_STATE& state) {
  }
}

typedef void(tBTM_SCO_IND_CBACK)(uint16_t sco_inx);

/* Define the structure that contains (e)SCO data */
typedef struct {
  tBTM_ESCO_CBACK* p_esco_cback; /* Callback for eSCO events     */
@@ -112,6 +137,7 @@ typedef struct {

  void Init() {
    def_esco_parms = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
    bluetooth::audio::sco::init();
  }

  uint16_t get_index(const tSCO_CONN* p_sco) const {
@@ -134,4 +160,4 @@ extern void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle);
BT_HDR* btm_sco_make_packet(std::vector<uint8_t> data, uint16_t sco_handle);

// Send a SCO packet
void btm_send_sco_packet(std::vector<uint8_t> data, uint16_t sco_handle);
void btm_send_sco_packet(std::vector<uint8_t> data);
Loading