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

Commit aa01f1d6 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Ase configuration data refactor - part 1

This change removes the `ase_cnt` counter in the
SetConfiguration struct and allows for multiple,
and distinct ASE configurations, to match the
requirements for the new AIDL for the multicodec
configuration provider.

Additionally:
 - `SetConfiguration` was renamed to `AseConfiguration` to
   match the AIDL data structures, and to avoid the confusion
   with the `AudioSetConfiguration` struct.
 - `device_cnt` and `topology` fields of the configuration were
   encapsulated inside the optional TopologyInfo struct for separation,
   as they will be absent in configurations from the AIDL config
   provider and only the legacy .json configuration handling
   code should use it (isolating the data for the legacy code path only)
 - adds `packing` parameter to the configurations to match the
   new AIDL requirements
 - other small data types improvements like using BidirectionalPair
   container which improves accessing a single direction configs
   without the need of searching through a flat container of structs
   with a `direction` field.

Bug: 295972694
Test: atest --host bluetooth_le_audio_test bluetooth_le_audio_client_test  bluetooth_test_broadcaster bluetooth_test_broadcaster_state_machine bluetooth_le_audio_codec_manager_test
Flag: EXEMPT; non-flagable refactor, verified with unit tests
Change-Id: I1a2106b5684a6dcaf2900dc0a54ec63652cf9203
parent 49e9a83f
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ using ::bluetooth::audio::aidl::BluetoothAudioCtrlAck;
using ::bluetooth::audio::le_audio::LeAudioClientInterface;
using ::bluetooth::audio::le_audio::StartRequestState;
using ::bluetooth::audio::le_audio::StreamCallbacks;
using ::bluetooth::le_audio::set_configurations::SetConfiguration;
using ::bluetooth::le_audio::set_configurations::AseConfiguration;
using ::bluetooth::le_audio::types::LeAudioCoreCodecConfig;

static ChannelMode le_audio_channel_mode2audio_hal(uint8_t channels_count) {
@@ -747,33 +747,37 @@ std::vector<AudioSetConfiguration> get_offload_capabilities() {
    str_capability_log.clear();

    if (hal_ucast_capability_to_stack_format(hal_encode_cap, encode_cap)) {
      audio_set_config.confs.push_back(SetConfiguration(
          ::bluetooth::le_audio::types::kLeAudioDirectionSink,
          hal_encode_cap.deviceCount,
          hal_encode_cap.deviceCount * hal_encode_cap.channelCountPerDevice,
          encode_cap));
      auto ase_cnt =
          hal_encode_cap.deviceCount * hal_encode_cap.channelCountPerDevice;
      while (ase_cnt--) {
        audio_set_config.confs.sink.push_back(AseConfiguration(encode_cap));
      }
      str_capability_log = " Encode Capability: " + hal_encode_cap.toString();
    }

    if (hal_ucast_capability_to_stack_format(hal_decode_cap, decode_cap)) {
      audio_set_config.confs.push_back(SetConfiguration(
          ::bluetooth::le_audio::types::kLeAudioDirectionSource,
          hal_decode_cap.deviceCount,
          hal_decode_cap.deviceCount * hal_decode_cap.channelCountPerDevice,
          decode_cap));
      auto ase_cnt =
          hal_decode_cap.deviceCount * hal_decode_cap.channelCountPerDevice;
      while (ase_cnt--) {
        audio_set_config.confs.source.push_back(AseConfiguration(decode_cap));
      }
      str_capability_log += " Decode Capability: " + hal_decode_cap.toString();
    }

    audio_set_config.topology_info = {
        {{static_cast<uint8_t>(hal_decode_cap.deviceCount),
          static_cast<uint8_t>(hal_encode_cap.deviceCount)}}};

    if (hal_bcast_capability_to_stack_format(hal_bcast_cap, bcast_cap)) {
      // Set device_cnt, ase_cnt to zero to ignore these fields for broadcast
      audio_set_config.confs.push_back(
          SetConfiguration(::bluetooth::le_audio::types::kLeAudioDirectionSink,
                           0, 0, bcast_cap));
      audio_set_config.topology_info = {{{0, 0}}};
      audio_set_config.confs.sink.push_back(AseConfiguration(bcast_cap));
      str_capability_log +=
          " Broadcast Capability: " + hal_bcast_cap.toString();
    }

    if (!audio_set_config.confs.empty()) {
    if (!audio_set_config.confs.sink.empty() ||
        !audio_set_config.confs.source.empty()) {
      offload_capabilities.push_back(audio_set_config);
      LOG(INFO) << __func__
                << ": Supported codec capability =" << str_capability_log;
+115 −70
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "broadcaster/broadcast_configuration_provider.h"
#include "broadcaster/broadcaster_types.h"
#include "device/include/controller.h"
#include "le_audio/le_audio_types.h"
#include "le_audio_set_configuration_provider.h"
#include "le_audio_utils.h"
#include "os/log.h"
@@ -39,9 +40,9 @@ using bluetooth::legacy::hci::GetInterface;
using bluetooth::le_audio::AudioSetConfigurationProvider;
using bluetooth::le_audio::btle_audio_codec_config_t;
using bluetooth::le_audio::btle_audio_codec_index_t;
using bluetooth::le_audio::set_configurations::AseConfiguration;
using bluetooth::le_audio::set_configurations::AudioSetConfiguration;
using bluetooth::le_audio::set_configurations::AudioSetConfigurations;
using bluetooth::le_audio::set_configurations::SetConfiguration;

typedef struct offloader_stream_maps {
  std::vector<bluetooth::le_audio::stream_map_info> streams_map_target;
@@ -240,11 +241,15 @@ struct codec_manager_impl {
    LOG_INFO("UpdateSupportedBroadcastConfig");

    for (const auto& adsp_audio_set_conf : adsp_capabilities) {
      if (adsp_audio_set_conf.confs.size() != 1 ||
          adsp_audio_set_conf.confs[0].device_cnt != 0) {
      ASSERT_LOG(
          adsp_audio_set_conf.topology_info.has_value(),
          "No topology info, which is required to properly configure the ASEs");
      if (adsp_audio_set_conf.confs.sink.size() != 1 ||
          adsp_audio_set_conf.topology_info->device_count.sink != 0 ||
          adsp_audio_set_conf.topology_info->device_count.source != 0) {
        continue;
      }
      auto& adsp_config = adsp_audio_set_conf.confs[0];
      auto& adsp_config = adsp_audio_set_conf.confs.sink[0];

      const types::LeAudioCoreCodecConfig core_config =
          adsp_config.codec.params.GetAsCoreCodecConfig();
@@ -627,59 +632,89 @@ struct codec_manager_impl {
    return true;
  }

  bool IsSetConfigurationMatched(const SetConfiguration& software_set_config,
                                 const SetConfiguration& adsp_set_config) {
    // Skip the check of stategry and ase_cnt due to ADSP doesn't have the info
    return (
        software_set_config.direction == adsp_set_config.direction &&
        software_set_config.device_cnt == adsp_set_config.device_cnt &&
        IsLc3ConfigMatched(software_set_config.codec, adsp_set_config.codec));
  bool IsAseConfigurationMatched(const AseConfiguration& software_ase_config,
                                 const AseConfiguration& adsp_ase_config) {
    // Skip the check of strategy due to ADSP doesn't have the info
    return IsLc3ConfigMatched(software_ase_config.codec, adsp_ase_config.codec);
  }

  bool IsAudioSetConfigurationMatched(
      const AudioSetConfiguration* software_audio_set_conf,
      std::unordered_set<uint8_t>& offload_preference_set,
      const std::vector<AudioSetConfiguration>& adsp_capabilities) {
    if (software_audio_set_conf->confs.empty()) {
    if (software_audio_set_conf->confs.sink.empty() &&
        software_audio_set_conf->confs.source.empty()) {
      return false;
    }

    std::unordered_map<uint8_t, const SetConfiguration&>
        software_set_conf_direction_map;

    for (auto& software_set_conf : software_audio_set_conf->confs) {
      // Checks offload preference supports the codec
      if (offload_preference_set.find(
              software_set_conf.codec.id.coding_format) ==
    // No match if the codec is not on the preference list
    for (auto direction : {le_audio::types::kLeAudioDirectionSink,
                           le_audio::types::kLeAudioDirectionSource}) {
      for (auto const& conf : software_audio_set_conf->confs.get(direction)) {
        if (offload_preference_set.find(conf.codec.id.coding_format) ==
            offload_preference_set.end()) {
          return false;
        }
      software_set_conf_direction_map.emplace(software_set_conf.direction,
                                              software_set_conf);
      }
    }

    // Checks any of offload config matches the input audio set config
    for (const auto& adsp_audio_set_conf : adsp_capabilities) {
      if (adsp_audio_set_conf.confs.size() !=
          software_audio_set_conf->confs.size()) {
      size_t match_cnt = 0;
      size_t expected_match_cnt = 0;

      ASSERT_LOG(adsp_audio_set_conf.topology_info.has_value(),
                 "ADSP capability is missing the topology information.");

      for (auto direction : {le_audio::types::kLeAudioDirectionSink,
                             le_audio::types::kLeAudioDirectionSource}) {
        if (software_audio_set_conf->topology_info->device_count.get(
                direction) !=
            adsp_audio_set_conf.topology_info->device_count.get(direction)) {
          continue;
        }

      size_t match_cnt = 0;
        auto const& software_set_ase_confs =
            software_audio_set_conf->confs.get(direction);
        auto const& adsp_set_ase_confs =
            adsp_audio_set_conf.confs.get(direction);

      for (auto& adsp_set_conf : adsp_audio_set_conf.confs) {
        auto it = software_set_conf_direction_map.find(adsp_set_conf.direction);
        if (!software_set_ase_confs.size() || !adsp_set_ase_confs.size()) {
          continue;
        }

        if (it == software_set_conf_direction_map.end()) {
        // Check for number of ASEs mismatch
        if (adsp_set_ase_confs.size() != software_set_ase_confs.size()) {
          LOG_ERROR(
              "%s: ADSP config size mismatches the software: %zu != %zu",
              direction == types::kLeAudioDirectionSink ? "Sink" : "Source",
              adsp_set_ase_confs.size(), software_set_ase_confs.size());
          continue;
        }

        if (IsSetConfigurationMatched(it->second, adsp_set_conf)) {
        // The expected number of ASE configs, the ADSP config needs to match
        expected_match_cnt += software_set_ase_confs.size();
        if (expected_match_cnt == 0) {
          continue;
        }

        // Check for matching configs
        for (auto const& adsp_set_conf : adsp_set_ase_confs) {
          for (auto const& software_set_conf : software_set_ase_confs) {
            if (IsAseConfigurationMatched(software_set_conf, adsp_set_conf)) {
              match_cnt++;
              // Check the next adsp config if the first software config matches
              break;
            }
          }
        }
        if (match_cnt != expected_match_cnt) {
          break;
        }
      }

      if (match_cnt == software_set_conf_direction_map.size()) {
      // Check the match count
      if (match_cnt == expected_match_cnt) {
        return true;
      }
    }
@@ -730,42 +765,52 @@ struct codec_manager_impl {
      const std::vector<btle_audio_codec_config_t>& offload_preference_set) {
    LOG_DEBUG("Print adsp_capabilities:");

    for (auto adsp : adsp_capabilities) {
      LOG_DEBUG("%s, number of confs %d", adsp.name.c_str(),
                (int)(adsp.confs.size()));
      for (auto conf : adsp.confs) {
    for (auto& adsp : adsp_capabilities) {
      LOG_DEBUG("'%s':", adsp.name.c_str());
      for (auto direction : {le_audio::types::kLeAudioDirectionSink,
                             le_audio::types::kLeAudioDirectionSource}) {
        LOG_DEBUG(
            "dir: %s: number of confs %d:",
            (direction == types::kLeAudioDirectionSink ? "sink" : "source"),
            (int)(adsp.confs.get(direction).size()));
        for (auto conf : adsp.confs.sink) {
          LOG_DEBUG(
            "codecId: %d dir: %s, dev_cnt: %d ase_cnt: %d, strategy: %s, "
            "sample_freq: %d, interval %d, channel_cnt: %d",
            conf.codec.id.coding_format,
            (conf.direction == types::kLeAudioDirectionSink ? "sink"
                                                            : "source"),
            conf.device_cnt, conf.ase_cnt,
            getStrategyString(conf.strategy).c_str(),
            conf.codec.GetSamplingFrequencyHz(), conf.codec.GetDataIntervalUs(),
              "codecId: %d, sample_freq: %d, interval %d, channel_cnt: %d",
              conf.codec.id.coding_format, conf.codec.GetSamplingFrequencyHz(),
              conf.codec.GetDataIntervalUs(),
              conf.codec.GetChannelCountPerIsoStream());

          /* TODO: How to get bits_per_sample ? */
          btle_audio_codec_config_t capa_to_add = {
              .codec_type = (conf.codec.id.coding_format ==
                             types::kLeAudioCodingFormatLC3)
                                ? btle_audio_codec_index_t::
                                      LE_AUDIO_CODEC_INDEX_SOURCE_LC3
                                : btle_audio_codec_index_t::
                                      LE_AUDIO_CODEC_INDEX_SOURCE_INVALID,
              .sample_rate = utils::translateToBtLeAudioCodecConfigSampleRate(
                  conf.codec.GetSamplingFrequencyHz()),
              .bits_per_sample =
                  utils::translateToBtLeAudioCodecConfigBitPerSample(16),
            .channel_count = utils::translateToBtLeAudioCodecConfigChannelCount(
              .channel_count =
                  utils::translateToBtLeAudioCodecConfigChannelCount(
                      conf.codec.GetChannelCountPerIsoStream()),
              .frame_duration =
                  utils::translateToBtLeAudioCodecConfigFrameDuration(
                      conf.codec.GetDataIntervalUs()),
          };

        if (conf.direction == types::kLeAudioDirectionSink) {
          LOG_DEBUG("Adding output capa %d",
                    static_cast<int>(codec_output_capa.size()));
          codec_output_capa.push_back(capa_to_add);
        } else {
          LOG_DEBUG("Adding input capa %d",
                    static_cast<int>(codec_input_capa.size()));
          codec_input_capa.push_back(capa_to_add);
          auto& capa_container = (direction == types::kLeAudioDirectionSink)
                                     ? codec_output_capa
                                     : codec_input_capa;
          if (std::find(capa_container.begin(), capa_container.end(),
                        capa_to_add) == capa_container.end()) {
            LOG_DEBUG("Adding %s capa %d",
                      (direction == types::kLeAudioDirectionSink) ? "output"
                                                                  : "input",
                      static_cast<int>(capa_container.size()));
            capa_container.push_back(capa_to_add);
          }
        }
      }
    }
+96 −68

File changed.

Preview size limit exceeded, changes collapsed.

+111 −73
Original line number Diff line number Diff line
@@ -24,8 +24,10 @@
#include "btm_iso_api.h"
#include "device/include/controller.h"
#include "internal_include/bt_trace.h"
#include "le_audio/le_audio_types.h"
#include "le_audio_set_configuration_provider.h"
#include "metrics_collector.h"
#include "os/log.h"

namespace bluetooth::le_audio {

@@ -479,9 +481,12 @@ uint8_t LeAudioDeviceGroup::GetSCA(void) const {
}

uint8_t LeAudioDeviceGroup::GetPacking(void) const {
  /* TODO: Decide about packing */
  if (!stream_conf.conf) {
    LOG_ERROR("No stream configuration has been set.");
    return bluetooth::hci::kIsoCigPackingSequential;
  }
  return stream_conf.conf->packing;
}

uint8_t LeAudioDeviceGroup::GetFraming(void) const {
  LeAudioDevice* leAudioDevice = GetFirstActiveDevice();
@@ -1218,14 +1223,13 @@ void LeAudioDeviceGroup::CigConfiguration::UnassignCis(
}

bool CheckIfStrategySupported(types::LeAudioConfigurationStrategy strategy,
                              const set_configurations::SetConfiguration& conf,
                              const LeAudioDevice& device) {
                              const set_configurations::AseConfiguration& conf,
                              uint8_t direction, const LeAudioDevice& device) {
  /* Check direction and if audio location allows to create more cises to a
   * single device.
   */
  types::AudioLocations audio_locations =
      (conf.direction == types::kLeAudioDirectionSink)
          ? device.snk_audio_locations_
      (direction == types::kLeAudioDirectionSink) ? device.snk_audio_locations_
                                                  : device.src_audio_locations_;

  LOG_DEBUG("strategy: %d, locations: %lu", (int)strategy,
@@ -1250,7 +1254,7 @@ bool CheckIfStrategySupported(types::LeAudioConfigurationStrategy strategy,
        return false;

      auto channel_count_mask =
          device.GetSupportedAudioChannelCounts(conf.direction);
          device.GetSupportedAudioChannelCounts(direction);
      auto requested_channel_count = conf.codec.params.GetAsCoreCodecConfig()
                                         .GetChannelCountPerIsoStream();
      LOG_DEBUG("Requested channel count: %d, supp. channel counts: %s",
@@ -1300,24 +1304,44 @@ bool LeAudioDeviceGroup::IsAudioSetConfigurationSupported(
   *    scenarion will be covered.
   * 3) ASEs should be filled according to performance profile.
   */
  for (const auto& ent : (*audio_set_conf).confs) {
  for (auto direction :
       {types::kLeAudioDirectionSink, types::kLeAudioDirectionSource}) {
    LOG_DEBUG("Looking for configuration: %s - %s",
              audio_set_conf->name.c_str(),
              (ent.direction == types::kLeAudioDirectionSink ? "snk" : "src"));
              (direction == types::kLeAudioDirectionSink ? "Sink" : "Source"));
    auto const& ase_confs = audio_set_conf->confs.get(direction);

    ASSERT_LOG(
        audio_set_conf->topology_info.has_value(),
        "No topology info, which is required to properly configure the ASEs");
    auto const strategy =
        audio_set_conf->topology_info->strategy.get(direction);
    auto const device_cnt =
        audio_set_conf->topology_info->device_count.get(direction);
    auto const ase_cnt = ase_confs.size();

    if (ase_cnt == 0) {
      LOG_ERROR("ASE count is 0");
      continue;
    }
    if (device_cnt == 0) {
      LOG_ERROR("Device count is 0");
      continue;
    }

    uint8_t const max_required_ase_per_dev =
        ase_cnt / device_cnt + (ase_cnt % device_cnt);

    uint8_t required_device_cnt = ent.device_cnt;
    uint8_t max_required_ase_per_dev =
        ent.ase_cnt / ent.device_cnt + (ent.ase_cnt % ent.device_cnt);
    uint8_t active_ase_num = 0;
    auto strategy = ent.strategy;
    uint8_t required_device_cnt = device_cnt;
    uint8_t active_ase_cnt = 0;

    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,
        "Number of devices: %d, number of ASEs: %zu,  Max ASE per device: %d, "
        "Strategy: %d",
        +required_device_cnt, +ase_cnt, +max_required_ase_per_dev,
        static_cast<int>(strategy));

    if (ent.direction == types::kLeAudioDirectionSink &&
    if (direction == types::kLeAudioDirectionSink &&
        strategy != required_snk_strategy) {
      LOG_DEBUG(" Sink strategy mismatch group!=cfg.entry (%d!=%d)",
                static_cast<int>(required_snk_strategy),
@@ -1328,35 +1352,38 @@ bool LeAudioDeviceGroup::IsAudioSetConfigurationSupported(
    for (auto* device = GetFirstDevice();
         device != nullptr && required_device_cnt > 0;
         device = GetNextDevice(device)) {
      /* Skip if device has ASE configured in this direction already */
      if (device->ases_.empty()) {
        LOG_ERROR("Device has no ASEs.");
        continue;
      }

      if (device->ases_.empty()) continue;
      int needed_ase_per_dev =
          std::min(static_cast<int>(max_required_ase_per_dev),
                   static_cast<int>(ase_cnt - active_ase_cnt));

      if (!device->GetCodecConfigurationSupportedPac(ent.direction,
                                                     ent.codec)) {
      for (auto const& ent : ase_confs) {
        if (!device->GetCodecConfigurationSupportedPac(direction, ent.codec)) {
          LOG_DEBUG("Insufficient PAC");
          continue;
        }

      int needed_ase = std::min(static_cast<int>(max_required_ase_per_dev),
                                static_cast<int>(ent.ase_cnt - active_ase_num));

      if (!CheckIfStrategySupported(strategy, ent, *device)) {
        if (!CheckIfStrategySupported(strategy, ent, direction, *device)) {
          LOG_DEBUG("Strategy not supported");
          continue;
        }

        for (auto& ase : device->ases_) {
        if (ase.direction != ent.direction) continue;
          if (ase.direction != direction) continue;

        active_ase_num++;
        needed_ase--;
          active_ase_cnt++;
          needed_ase_per_dev--;

        if (needed_ase == 0) break;
          if (needed_ase_per_dev == 0) break;
        }
      }

      if (needed_ase > 0) {
        LOG_DEBUG("Device has too less ASEs. Still needed ases %d", needed_ase);
      if (needed_ase_per_dev > 0) {
        LOG_DEBUG("Not enough ASEs on the device (needs %d more).",
                  needed_ase_per_dev);
        return false;
      }

@@ -1365,7 +1392,9 @@ bool LeAudioDeviceGroup::IsAudioSetConfigurationSupported(

    if (required_device_cnt > 0) {
      /* Don't left any active devices if requirements are not met */
      LOG_DEBUG(" could not configure all the devices");
      LOG_DEBUG(
          "Could not configure all the devices for direction: %s",
          (direction == types::kLeAudioDirectionSink ? "Sink" : "Source"));
      return false;
    }
  }
@@ -1427,23 +1456,20 @@ bool LeAudioDeviceGroup::ConfigureAses(
  BidirectionalPair<types::AudioLocations> group_audio_locations_memo = {
      .sink = 0, .source = 0};

  for (const auto& ent : (*audio_set_conf).confs) {
    LOG_DEBUG(" Looking for requirements: %s,  - %s",
              audio_set_conf->name.c_str(),
              (ent.direction == 1 ? "snk" : "src"));
  for (auto direction :
       {types::kLeAudioDirectionSink, types::kLeAudioDirectionSource}) {
    auto direction_str =
        (direction == types::kLeAudioDirectionSink ? "Sink" : "Source");
    LOG_DEBUG("%s: Looking for requirements: %s", direction_str,
              audio_set_conf->name.c_str());

    uint8_t required_device_cnt = ent.device_cnt;
    uint8_t max_required_ase_per_dev =
        ent.ase_cnt / ent.device_cnt + (ent.ase_cnt % ent.device_cnt);
    uint8_t active_ase_num = 0;
    bluetooth::le_audio::types::LeAudioConfigurationStrategy strategy =
        ent.strategy;
    if (audio_set_conf->confs.get(direction).empty()) {
      LOG_WARN("No %s configuration available.", direction_str);
      continue;
    }

    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);
    auto required_device_cnt = NumOfConnected();
    uint8_t active_ase_cnt = 0;

    auto configuration_closure = [&](LeAudioDevice* dev) -> void {
      /* For the moment, we configure only connected devices and when it is
@@ -1458,10 +1484,12 @@ bool LeAudioDeviceGroup::ConfigureAses(
        return;
      }

      if (!dev->ConfigureAses(ent, context_type, &active_ase_num,
                              group_audio_locations_memo,
                              metadata_context_types, ccid_lists, reuse_cis_id))
      if (!dev->ConfigureAses(audio_set_conf, direction, context_type,
                              &active_ase_cnt, group_audio_locations_memo,
                              metadata_context_types, ccid_lists,
                              reuse_cis_id)) {
        return;
      }

      required_device_cnt--;
    };
@@ -1543,9 +1571,7 @@ LeAudioDeviceGroup::GetCachedCodecConfigurationByDirection(
  if (!audio_set_conf) return std::nullopt;

  LeAudioCodecConfiguration group_config = {0, 0, 0, 0};
  for (const auto& conf : audio_set_conf->confs) {
    if (conf.direction != direction) continue;

  for (const auto& conf : audio_set_conf->confs.get(direction)) {
    if (group_config.sample_rate != 0 &&
        conf.codec.GetSamplingFrequencyHz() != group_config.sample_rate) {
      LOG(WARNING) << __func__
@@ -1576,8 +1602,12 @@ LeAudioDeviceGroup::GetCachedCodecConfigurationByDirection(
    }
    group_config.bits_per_sample = conf.codec.GetBitsPerSample();

    ASSERT_LOG(
        audio_set_conf->topology_info.has_value(),
        "No topology info, which is required to properly configure the ASEs");
    group_config.num_channels +=
        conf.codec.GetChannelCountPerIsoStream() * conf.device_cnt;
        conf.codec.GetChannelCountPerIsoStream() *
        audio_set_conf->topology_info->device_count.get(direction);
  }

  if (group_config.IsInvalid()) return std::nullopt;
@@ -1835,27 +1865,34 @@ bool LeAudioDeviceGroup::IsConfiguredForContext(
bool LeAudioDeviceGroup::IsAudioSetConfigurationSupported(
    LeAudioDevice* leAudioDevice,
    const set_configurations::AudioSetConfiguration* audio_set_conf) const {
  for (const auto& ent : (*audio_set_conf).confs) {
  for (auto direction : {le_audio::types::kLeAudioDirectionSink,
                         le_audio::types::kLeAudioDirectionSource}) {
    const auto& confs = audio_set_conf->confs.get(direction);
    if (confs.size() == 0) continue;

    LOG_INFO("Looking for requirements: %s - %s", audio_set_conf->name.c_str(),
             (ent.direction == 1 ? "snk" : "src"));
    auto pac = leAudioDevice->GetCodecConfigurationSupportedPac(ent.direction,
                                                                ent.codec);
    if (pac != nullptr) {
      LOG_INFO("Configuration is supported by device %s",
             (direction == 1 ? "snk" : "src"));
    for (const auto& ent : confs) {
      if (!leAudioDevice->GetCodecConfigurationSupportedPac(direction,
                                                            ent.codec)) {
        LOG_INFO("Configuration is NOT supported by device %s",
                 ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_));
      return true;
        return false;
      }
    }
  }

  LOG_INFO("Configuration is NOT supported by device %s",
  LOG_INFO("Configuration is supported by device %s",
           ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_));
  return false;
  return true;
}

const set_configurations::AudioSetConfiguration*
LeAudioDeviceGroup::FindFirstSupportedConfiguration(
    LeAudioContextType context_type,
    const set_configurations::AudioSetConfigurations* confs) const {
  ASSERT_LOG(confs != nullptr, "confs should not be null");

  LOG_DEBUG("context type: %s,  number of connected devices: %d",
            bluetooth::common::ToString(context_type).c_str(),
            +NumOfConnected());
@@ -1874,6 +1911,7 @@ LeAudioDeviceGroup::FindFirstSupportedConfiguration(
  /* Filter out device set for each end every scenario */
  auto required_snk_strategy = GetGroupSinkStrategy();
  for (const auto& conf : *confs) {
    ASSERT_LOG(conf != nullptr, "confs should not be null");
    if (IsAudioSetConfigurationSupported(conf, context_type,
                                         required_snk_strategy)) {
      LOG_DEBUG("found: %s", conf->name.c_str());
+29 −22

File changed.

Preview size limit exceeded, changes collapsed.

Loading