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 Original line Diff line number Diff line
@@ -38,14 +38,6 @@ namespace {
bool offload_supported = false;
bool offload_supported = false;
bool offload_enabled = 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 {
typedef struct cached_codec_info {
  struct bt_codec inner;
  struct bt_codec inner;
  size_t pkt_size;
  size_t pkt_size;
@@ -93,46 +85,41 @@ struct mgmt_rp_get_codec_capabilities {
#define MGMT_POLL_TIMEOUT_MS 2000
#define MGMT_POLL_TIMEOUT_MS 2000


void cache_codec_capabilities(struct mgmt_rp_get_codec_capabilities* rp) {
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;
  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.
  // 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
  // The capabilities are not used currently so it's safe to keep this for a
  // while.
  // while.
    cached_codec_info c{};

    switch (codec_id) {
  // CVSD is mandatory in HFP.
      case kCodecCvsd:
  cached_codecs.push_back({
        c.inner.codec = codec::CVSD;
      .inner = {.codec = codec::CVSD},
        break;
  });
      case kCodecTransparent:

        if (!rp->transparent_wbs_supported) {
  // No need to check GetLocalSupportedBrEdrCodecIds. Some legacy devices don't
          // Transparent wideband speech not supported, skip it.
  // even support HCI command Read Local Supported Codecs so WBS quirk is more
          continue;
  // 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;
  auto codecs =
        break;
      bluetooth::shim::GetController()->GetLocalSupportedBrEdrCodecIds();
      case kCodecMsbc:
  if (std::find(codecs.begin(), codecs.end(), kCodecMsbc) != codecs.end()) {
    offload_supported = true;
    offload_supported = true;
        c.inner.codec = codec::MSBC;
    cached_codecs.push_back({
        c.inner.data_path = rp->hci_data_path_id;
        .inner = {.codec = codec::MSBC, .data_path = rp->hci_data_path_id},
        c.pkt_size = rp->wbs_pkt_len;
        .pkt_size = rp->wbs_pkt_len,
        break;
    });
      default:
        log::debug("Unsupported codec ID: {}", codec_id);
        continue;
  }
  }


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

    cached_codecs.push_back(c);
  }
  }
}
}