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

Commit 5b75bc8e authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

leaudio: Fix improper cis calculations for TWS style earbuds

With this patch code takes number of devices in the group in order to
choose best configuration when calculating required CISes.
Also it fixes how strategy is taken into account - as for now we want to
check only strategy for sink direction as this is defines group
strategy.

Also fixes unit tests and improves some important logs

Bug: 261624834
Test: atest BluetoothInstrumentationTests
Test: atest bluetooth_le_audio_test bluetooth_le_audio_client_test
Tag: #feature

Merged-In: I00a0cc426d193a78938609fce0e620a55d9102e1
Change-Id: I00a0cc426d193a78938609fce0e620a55d9102e1
(cherry picked from commit 8d3aeb57)
parent f7cfc29e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -606,6 +606,7 @@ cc_test {
        "le_audio/metrics_collector_linux.cc",
        "le_audio/mock_iso_manager.cc",
        "test/common/mock_controller.cc",
        "test/common/mock_csis_client.cc",
        "le_audio/state_machine.cc",
        "le_audio/state_machine_test.cc",
        "le_audio/storage_helper.cc",
+10 −0
Original line number Diff line number Diff line
@@ -525,6 +525,16 @@ class CsisClientImpl : public CsisClient {
    }
  }

  int GetDesiredSize(int group_id) override {
    auto csis_group = FindCsisGroup(group_id);
    if (!csis_group) {
      LOG_INFO("Unknown group %d", group_id);
      return -1;
    }

    return csis_group->GetDesiredSize();
  }

  bool SerializeSets(const RawAddress& addr, std::vector<uint8_t>& out) const {
    auto device = FindDeviceByAddress(addr);
    if (device == nullptr) {
+1 −1
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ struct hdl_pair {

/* CSIS Types */
static constexpr uint8_t kDefaultScanDurationS = 5;
static constexpr uint8_t kDefaultCsisSetSize = 2;
static constexpr uint8_t kDefaultCsisSetSize = 1;
static constexpr uint8_t kUnknownRank = 0xff;

/* Enums */
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ class CsisClient {
      bluetooth::Uuid uuid = bluetooth::groups::kGenericContextUuid) = 0;
  virtual void LockGroup(int group_id, bool lock, CsisLockCb cb) = 0;
  virtual std::vector<RawAddress> GetDeviceList(int group_id) = 0;
  virtual int GetDesiredSize(int group_id) = 0;
};
}  // namespace csis
}  // namespace bluetooth
+51 −40
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <map>

#include "audio_hal_client/audio_hal_client.h"
#include "bta_csis_api.h"
#include "bta_gatt_queue.h"
#include "bta_groups.h"
#include "bta_le_audio_api.h"
@@ -967,10 +968,16 @@ void LeAudioDeviceGroup::CigGenerateCisIds(
  uint8_t cis_count_bidir = 0;
  uint8_t cis_count_unidir_sink = 0;
  uint8_t cis_count_unidir_source = 0;
  get_cis_count(confs, GetGroupStrategy(),
  int csis_group_size =
      bluetooth::csis::CsisClient::Get()->GetDesiredSize(group_id_);
  /* If this is CSIS group, the csis_group_size will be > 0, otherwise -1.
   * If the last happen it means, group size is 1 */
  int group_size = csis_group_size > 0 ? csis_group_size : 1;

  get_cis_count(*confs, group_size, GetGroupStrategy(),
                GetAseCount(types::kLeAudioDirectionSink),
                GetAseCount(types::kLeAudioDirectionSource), &cis_count_bidir,
                &cis_count_unidir_sink, &cis_count_unidir_source);
                GetAseCount(types::kLeAudioDirectionSource), cis_count_bidir,
                cis_count_unidir_sink, cis_count_unidir_source);

  uint8_t idx = 0;
  while (cis_count_bidir > 0) {
@@ -980,7 +987,6 @@ void LeAudioDeviceGroup::CigGenerateCisIds(
        .type = CisType::CIS_TYPE_BIDIRECTIONAL,
        .conn_handle = 0,
    };

    cises_.push_back(cis_entry);
    cis_count_bidir--;
    idx++;
@@ -1045,20 +1051,23 @@ bool LeAudioDeviceGroup::CigAssignCisIds(LeAudioDevice* leAudioDevice) {
        cis_id = GetFirstFreeCisId(CisType::CIS_TYPE_BIDIRECTIONAL);
      }

      if (cis_id == kInvalidCisId) {
        LOG_ERROR(" Unable to get free Bi-Directional CIS ID");
        return false;
      }

      if (cis_id != kInvalidCisId) {
        ase->cis_id = cis_id;
        matching_bidir_ase->cis_id = cis_id;
        cises_[cis_id].addr = leAudioDevice->address_;

      LOG_INFO(" ASE ID: %d and ASE ID: %d, assigned Bi-Directional CIS ID: %d",
        LOG_INFO(
            " ASE ID: %d and ASE ID: %d, assigned Bi-Directional CIS ID: %d",
            +ase->id, +matching_bidir_ase->id, +ase->cis_id);
        continue;
      }

      LOG_WARN(
          " ASE ID: %d, unable to get free Bi-Directional CIS ID but maybe "
          "thats fine. Try using unidirectional.",
          ase->id);
    }

    if (ase->direction == types::kLeAudioDirectionSink) {
      if (cis_id == kInvalidCisId) {
        cis_id = GetFirstFreeCisId(CisType::CIS_TYPE_UNIDIRECTIONAL_SINK);
@@ -1267,7 +1276,7 @@ bool LeAudioDeviceGroup::IsConfigurationSupported(

    if (ent.direction == types::kLeAudioDirectionSink &&
        strategy != required_snk_strategy) {
      LOG_INFO(" Sink strategy mismatch (%d!=%d)",
      LOG_INFO(" Sink strategy mismatch group!=cfg.entry (%d!=%d)",
               static_cast<int>(required_snk_strategy),
               static_cast<int>(strategy));
      return false;
@@ -1535,12 +1544,12 @@ bool LeAudioDevice::ConfigureAses(
                      std::vector<uint8_t>());
    }

    DLOG(INFO) << __func__ << " device=" << address_
               << ", activated ASE id=" << +ase->id
               << ", direction=" << +ase->direction
               << ", max_sdu_size=" << +ase->max_sdu_size
               << ", cis_id=" << +ase->cis_id
               << ", target_latency=" << +ent.target_latency;
    LOG_DEBUG(
        "device=%s, activated ASE id=%d, direction=%s, max_sdu_size=%d, "
        "cis_id=%d, target_latency=%d",
        address_.ToString().c_str(), ase->id,
        (ent.direction == 1 ? "snk" : "src"), ase->max_sdu_size, ase->cis_id,
        ent.target_latency);

    ase = GetFirstInactiveAse(ent.direction, reuse_cis_id);
  }
@@ -1575,9 +1584,9 @@ bool LeAudioDeviceGroup::ConfigureAses(
  types::AudioLocations group_src_audio_locations = 0;

  for (const auto& ent : (*audio_set_conf).confs) {
    DLOG(INFO) << __func__
               << " Looking for requirements: " << audio_set_conf->name << " - "
               << (ent.direction == 1 ? "snk" : "src");
    LOG_DEBUG(" Looking for requirements: %s,  - %s",
              audio_set_conf->name.c_str(),
              (ent.direction == 1 ? "snk" : "src"));

    uint8_t required_device_cnt = ent.device_cnt;
    uint8_t max_required_ase_per_dev =
@@ -1585,10 +1594,11 @@ bool LeAudioDeviceGroup::ConfigureAses(
    uint8_t active_ase_num = 0;
    le_audio::types::LeAudioConfigurationStrategy strategy = ent.strategy;

    DLOG(INFO) << __func__ << " Number of devices: " << +required_device_cnt
               << " number of ASEs: " << +ent.ase_cnt
               << " Max ASE per device: " << +max_required_ase_per_dev
               << " strategy: " << (int)strategy;
    LOG_DEBUG(
        "Number of devices: %d number of ASEs: %d, Max ASE per device: %d "
        "strategy: %d",
        required_device_cnt, ent.ase_cnt, max_required_ase_per_dev,
        (int)strategy);

    for (auto* device = GetFirstDeviceWithActiveContext(context_type);
         device != nullptr && required_device_cnt > 0;
@@ -1621,14 +1631,14 @@ bool LeAudioDeviceGroup::ConfigureAses(

    if (required_device_cnt > 0) {
      /* Don't left any active devices if requirements are not met */
      LOG(ERROR) << __func__ << " could not configure all the devices";
      LOG_ERROR(" could not configure all the devices");
      Deactivate();
      return false;
    }
  }

  LOG(INFO) << "Choosed ASE Configuration for group: " << this->group_id_
            << " configuration: " << audio_set_conf->name;
  LOG_INFO("Choosed ASE Configuration for group: %d, configuration: %s",
           group_id_, audio_set_conf->name.c_str());

  configuration_context_type_ = context_type;
  metadata_context_type_ = metadata_context_type;
@@ -1904,21 +1914,22 @@ bool LeAudioDeviceGroup::Configure(LeAudioContextType context_type,
  const set_configurations::AudioSetConfiguration* conf =
      available_context_to_configuration_map[context_type];

  DLOG(INFO) << __func__;

  if (!conf) {
    LOG(ERROR) << __func__ << ", requested context type: "
               << loghex(static_cast<uint16_t>(context_type))
               << ", is in mismatch with cached available contexts";
    LOG_ERROR(
        ", requested context type: %s , is in mismatch with cached available "
        "contexts ",
        bluetooth::common::ToString(context_type).c_str());
    return false;
  }

  DLOG(INFO) << __func__ << " setting context type: " << int(context_type);
  LOG_DEBUG(" setting context type: %s",
            bluetooth::common::ToString(context_type).c_str());

  if (!ConfigureAses(conf, context_type, metadata_context_type, ccid_list)) {
    LOG(ERROR) << __func__ << ", requested pick ASE config context type: "
               << loghex(static_cast<uint16_t>(context_type))
               << ", is in mismatch with cached available contexts";
    LOG_ERROR(
        ", requested context type: %s , is in mismatch with cached available "
        "contexts",
        bluetooth::common::ToString(context_type).c_str());
    return false;
  }

Loading