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

Commit 871c522e authored by Hsin-chen Chuang's avatar Hsin-chen Chuang
Browse files

btm_sco_hfp_hal_linux: Fix codec info for legacy devices

Some legacy devices don't even support HCI command Read Local Supported
Codecs, while https://r.android.com/2919865 actually relies on this
command to set up the correct codec info. This patch sets up TRANSPARENT
and CVSD without this command (follow original kernel behavior) and also
remove an unused structure.

Bug: 327547486
Tag: #floss
Test: mmm packages/modules/Bluetooth
Test: bluetooth_AdapterAUHealth.au_hfp_wbs_dut_as_sink_test.floss
      on Zork/Ezkinil (RTL8822C)
Flag: EXEMPT, Floss-only changes

Change-Id: I7c0becd09f37968464a59d891ab18c3b40efeb08
parent d19a2fa2
Loading
Loading
Loading
Loading
+27 −40
Original line number Diff line number Diff line
@@ -38,14 +38,6 @@ namespace {
bool offload_supported = false;
bool offload_enabled = false;

struct mgmt_bt_codec {
  uint8_t codec;
  uint8_t packet_size;
  uint8_t data_path;
  uint32_t data_length;
  uint8_t data[];
} __attribute__((packed));

typedef struct cached_codec_info {
  struct bt_codec inner;
  size_t pkt_size;
@@ -93,46 +85,41 @@ struct mgmt_rp_get_codec_capabilities {
#define MGMT_POLL_TIMEOUT_MS 2000

void cache_codec_capabilities(struct mgmt_rp_get_codec_capabilities* rp) {
  const uint8_t kCodecCvsd = 0x2;
  const uint8_t kCodecTransparent = 0x3;
  const uint8_t kCodecMsbc = 0x5;

  auto codecs =
      bluetooth::shim::GetController()->GetLocalSupportedBrEdrCodecIds();

  for (uint8_t codec_id : codecs) {
  // TODO(b/323087725): Query the codec capabilities and fill in c.inner.data.
  // The capabilities are not used currently so it's safe to keep this for a
  // while.
    cached_codec_info c{};
    switch (codec_id) {
      case kCodecCvsd:
        c.inner.codec = codec::CVSD;
        break;
      case kCodecTransparent:
        if (!rp->transparent_wbs_supported) {
          // Transparent wideband speech not supported, skip it.
          continue;

  // CVSD is mandatory in HFP.
  cached_codecs.push_back({
      .inner = {.codec = codec::CVSD},
  });

  // No need to check GetLocalSupportedBrEdrCodecIds. Some legacy devices don't
  // even support HCI command Read Local Supported Codecs so WBS quirk is more
  // reliable.
  if (rp->transparent_wbs_supported) {
    cached_codecs.push_back({
        .inner = {.codec = codec::MSBC_TRANSPARENT},
        .pkt_size = rp->wbs_pkt_len,
    });
  }
        c.inner.codec = codec::MSBC_TRANSPARENT;
        c.pkt_size = rp->wbs_pkt_len;
        break;
      case kCodecMsbc:

  auto codecs =
      bluetooth::shim::GetController()->GetLocalSupportedBrEdrCodecIds();
  if (std::find(codecs.begin(), codecs.end(), kCodecMsbc) != codecs.end()) {
    offload_supported = true;
        c.inner.codec = codec::MSBC;
        c.inner.data_path = rp->hci_data_path_id;
        c.pkt_size = rp->wbs_pkt_len;
        break;
      default:
        log::debug("Unsupported codec ID: {}", codec_id);
        continue;
    cached_codecs.push_back({
        .inner = {.codec = codec::MSBC, .data_path = rp->hci_data_path_id},
        .pkt_size = rp->wbs_pkt_len,
    });
  }

  for (const auto& c : cached_codecs) {
    log::info("Caching HFP codec {}, data path {}, data len {}, pkt_size {}",
              (uint64_t)c.inner.codec, c.inner.data_path, c.inner.data.size(),
              c.pkt_size);

    cached_codecs.push_back(c);
  }
}