• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "devices.h"
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include "btm_api_mock.h"
24 #include "le_audio_set_configuration_provider.h"
25 #include "le_audio_types.h"
26 #include "mock_controller.h"
27 #include "mock_csis_client.h"
28 #include "os/log.h"
29 #include "stack/btm/btm_int_types.h"
30 
btm_bda_to_acl(const RawAddress & bda,tBT_TRANSPORT transport)31 tACL_CONN* btm_bda_to_acl(const RawAddress& bda, tBT_TRANSPORT transport) {
32   return nullptr;
33 }
34 
35 namespace bluetooth {
36 namespace le_audio {
37 namespace internal {
38 namespace {
39 
40 using ::le_audio::DeviceConnectState;
41 using ::le_audio::LeAudioDevice;
42 using ::le_audio::LeAudioDeviceGroup;
43 using ::le_audio::LeAudioDevices;
44 using ::le_audio::types::AseState;
45 using ::le_audio::types::AudioContexts;
46 using ::le_audio::types::LeAudioContextType;
47 using testing::_;
48 using testing::Invoke;
49 using testing::Return;
50 using testing::Test;
51 
GetTestAddress(int index)52 RawAddress GetTestAddress(int index) {
53   CHECK_LT(index, UINT8_MAX);
54   RawAddress result = {
55       {0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
56   return result;
57 }
58 
59 class LeAudioDevicesTest : public Test {
60  protected:
SetUp()61   void SetUp() override {
62     devices_ = new LeAudioDevices();
63     bluetooth::manager::SetMockBtmInterface(&btm_interface);
64     controller::SetMockControllerInterface(&controller_interface_);
65   }
66 
TearDown()67   void TearDown() override {
68     controller::SetMockControllerInterface(nullptr);
69     bluetooth::manager::SetMockBtmInterface(nullptr);
70     delete devices_;
71   }
72 
73   LeAudioDevices* devices_ = nullptr;
74   bluetooth::manager::MockBtmInterface btm_interface;
75   controller::MockControllerInterface controller_interface_;
76 };
77 
TEST_F(LeAudioDevicesTest,test_add)78 TEST_F(LeAudioDevicesTest, test_add) {
79   RawAddress test_address_0 = GetTestAddress(0);
80   ASSERT_EQ((size_t)0, devices_->Size());
81   devices_->Add(test_address_0, DeviceConnectState::CONNECTING_BY_USER);
82   ASSERT_EQ((size_t)1, devices_->Size());
83   devices_->Add(GetTestAddress(1), DeviceConnectState::CONNECTING_BY_USER, 1);
84   ASSERT_EQ((size_t)2, devices_->Size());
85   devices_->Add(test_address_0, DeviceConnectState::CONNECTING_BY_USER);
86   ASSERT_EQ((size_t)2, devices_->Size());
87   devices_->Add(GetTestAddress(1), DeviceConnectState::CONNECTING_BY_USER, 2);
88   ASSERT_EQ((size_t)2, devices_->Size());
89 }
90 
TEST_F(LeAudioDevicesTest,test_remove)91 TEST_F(LeAudioDevicesTest, test_remove) {
92   RawAddress test_address_0 = GetTestAddress(0);
93   devices_->Add(test_address_0, DeviceConnectState::CONNECTING_BY_USER);
94   RawAddress test_address_1 = GetTestAddress(1);
95   devices_->Add(test_address_1, DeviceConnectState::CONNECTING_BY_USER);
96   RawAddress test_address_2 = GetTestAddress(2);
97   devices_->Add(test_address_2, DeviceConnectState::CONNECTING_BY_USER);
98   ASSERT_EQ((size_t)3, devices_->Size());
99   devices_->Remove(test_address_0);
100   ASSERT_EQ((size_t)2, devices_->Size());
101   devices_->Remove(GetTestAddress(3));
102   ASSERT_EQ((size_t)2, devices_->Size());
103   devices_->Remove(test_address_0);
104   ASSERT_EQ((size_t)2, devices_->Size());
105 }
106 
TEST_F(LeAudioDevicesTest,test_find_by_address_success)107 TEST_F(LeAudioDevicesTest, test_find_by_address_success) {
108   RawAddress test_address_0 = GetTestAddress(0);
109   devices_->Add(test_address_0, DeviceConnectState::CONNECTING_BY_USER);
110   RawAddress test_address_1 = GetTestAddress(1);
111   devices_->Add(test_address_1, DeviceConnectState::DISCONNECTED);
112   RawAddress test_address_2 = GetTestAddress(2);
113   devices_->Add(test_address_2, DeviceConnectState::CONNECTING_BY_USER);
114   LeAudioDevice* device = devices_->FindByAddress(test_address_1);
115   ASSERT_NE(nullptr, device);
116   ASSERT_EQ(test_address_1, device->address_);
117 }
118 
TEST_F(LeAudioDevicesTest,test_find_by_address_failed)119 TEST_F(LeAudioDevicesTest, test_find_by_address_failed) {
120   RawAddress test_address_0 = GetTestAddress(0);
121   devices_->Add(test_address_0, DeviceConnectState::CONNECTING_BY_USER);
122   RawAddress test_address_2 = GetTestAddress(2);
123   devices_->Add(test_address_2, DeviceConnectState::CONNECTING_BY_USER);
124   LeAudioDevice* device = devices_->FindByAddress(GetTestAddress(1));
125   ASSERT_EQ(nullptr, device);
126 }
127 
TEST_F(LeAudioDevicesTest,test_get_by_address_success)128 TEST_F(LeAudioDevicesTest, test_get_by_address_success) {
129   RawAddress test_address_0 = GetTestAddress(0);
130   devices_->Add(test_address_0, DeviceConnectState::CONNECTING_BY_USER);
131   RawAddress test_address_1 = GetTestAddress(1);
132   devices_->Add(test_address_1, DeviceConnectState::DISCONNECTED);
133   RawAddress test_address_2 = GetTestAddress(2);
134   devices_->Add(test_address_2, DeviceConnectState::CONNECTING_BY_USER);
135   std::shared_ptr<LeAudioDevice> device =
136       devices_->GetByAddress(test_address_1);
137   ASSERT_NE(nullptr, device);
138   ASSERT_EQ(test_address_1, device->address_);
139 }
140 
TEST_F(LeAudioDevicesTest,test_get_by_address_failed)141 TEST_F(LeAudioDevicesTest, test_get_by_address_failed) {
142   RawAddress test_address_0 = GetTestAddress(0);
143   devices_->Add(test_address_0, DeviceConnectState::CONNECTING_BY_USER);
144   RawAddress test_address_2 = GetTestAddress(2);
145   devices_->Add(test_address_2, DeviceConnectState::CONNECTING_BY_USER);
146   std::shared_ptr<LeAudioDevice> device =
147       devices_->GetByAddress(GetTestAddress(1));
148   ASSERT_EQ(nullptr, device);
149 }
150 
TEST_F(LeAudioDevicesTest,test_find_by_conn_id_success)151 TEST_F(LeAudioDevicesTest, test_find_by_conn_id_success) {
152   devices_->Add(GetTestAddress(1), DeviceConnectState::CONNECTING_BY_USER);
153   RawAddress test_address_0 = GetTestAddress(0);
154   devices_->Add(test_address_0, DeviceConnectState::CONNECTING_BY_USER);
155   devices_->Add(GetTestAddress(4), DeviceConnectState::CONNECTING_BY_USER);
156   LeAudioDevice* device = devices_->FindByAddress(test_address_0);
157   device->conn_id_ = 0x0005;
158   ASSERT_EQ(device, devices_->FindByConnId(0x0005));
159 }
160 
TEST_F(LeAudioDevicesTest,test_find_by_conn_id_failed)161 TEST_F(LeAudioDevicesTest, test_find_by_conn_id_failed) {
162   devices_->Add(GetTestAddress(1), DeviceConnectState::CONNECTING_BY_USER);
163   devices_->Add(GetTestAddress(0), DeviceConnectState::CONNECTING_BY_USER);
164   devices_->Add(GetTestAddress(4), DeviceConnectState::CONNECTING_BY_USER);
165   ASSERT_EQ(nullptr, devices_->FindByConnId(0x0006));
166 }
167 
168 /* TODO: Add FindByCisConnHdl test cases (ASE) */
169 
170 }  // namespace
171 
172 namespace {
173 using namespace ::le_audio::codec_spec_caps;
174 using namespace ::le_audio::set_configurations;
175 using namespace ::le_audio::types;
176 
177 static const hdl_pair hdl_pair_nil = hdl_pair(0x0000, 0x0000);
178 
179 enum class Lc3SettingId {
180   _BEGIN,
181   LC3_8_1 = _BEGIN,
182   LC3_8_2,
183   LC3_16_1,
184   LC3_16_2,
185   LC3_24_1,
186   LC3_24_2,
187   LC3_32_1,
188   LC3_32_2,
189   LC3_441_1,
190   LC3_441_2,
191   LC3_48_1,
192   LC3_48_2,
193   LC3_48_3,
194   LC3_48_4,
195   LC3_48_5,
196   LC3_48_6,
197   LC3_VND_1,
198   _END,
199   UNSUPPORTED = _END,
200 };
201 static constexpr int Lc3SettingIdBegin = static_cast<int>(Lc3SettingId::_BEGIN);
202 static constexpr int Lc3SettingIdEnd = static_cast<int>(Lc3SettingId::_END);
203 
IsLc3SettingSupported(LeAudioContextType context_type,Lc3SettingId id)204 bool IsLc3SettingSupported(LeAudioContextType context_type, Lc3SettingId id) {
205   /* Update those values, on any change of codec linked with content type */
206   switch (context_type) {
207     case LeAudioContextType::RINGTONE:
208     case LeAudioContextType::CONVERSATIONAL:
209       if (id == Lc3SettingId::LC3_16_1 || id == Lc3SettingId::LC3_16_2 ||
210           id == Lc3SettingId::LC3_24_1 || id == Lc3SettingId::LC3_24_2 ||
211           id == Lc3SettingId::LC3_32_1 || id == Lc3SettingId::LC3_32_2 ||
212           id == Lc3SettingId::LC3_48_1 || id == Lc3SettingId::LC3_48_2 ||
213           id == Lc3SettingId::LC3_48_3 || id == Lc3SettingId::LC3_48_4 ||
214           id == Lc3SettingId::LC3_VND_1)
215         return true;
216 
217       break;
218 
219     case LeAudioContextType::MEDIA:
220     case LeAudioContextType::ALERTS:
221     case LeAudioContextType::INSTRUCTIONAL:
222     case LeAudioContextType::NOTIFICATIONS:
223     case LeAudioContextType::EMERGENCYALARM:
224     case LeAudioContextType::UNSPECIFIED:
225       if (id == Lc3SettingId::LC3_16_1 || id == Lc3SettingId::LC3_16_2 ||
226           id == Lc3SettingId::LC3_48_4 || id == Lc3SettingId::LC3_48_2 ||
227           id == Lc3SettingId::LC3_VND_1 || id == Lc3SettingId::LC3_24_2)
228         return true;
229 
230       break;
231 
232     default:
233       if (id == Lc3SettingId::LC3_16_2) return true;
234 
235       break;
236   };
237 
238   return false;
239 }
240 
241 static constexpr uint8_t kLeAudioSamplingFreqRfu = 0x0E;
GetSamplingFrequency(Lc3SettingId id)242 uint8_t GetSamplingFrequency(Lc3SettingId id) {
243   switch (id) {
244     case Lc3SettingId::LC3_8_1:
245     case Lc3SettingId::LC3_8_2:
246       return ::le_audio::codec_spec_conf::kLeAudioSamplingFreq8000Hz;
247     case Lc3SettingId::LC3_16_1:
248     case Lc3SettingId::LC3_16_2:
249       return ::le_audio::codec_spec_conf::kLeAudioSamplingFreq16000Hz;
250     case Lc3SettingId::LC3_24_1:
251     case Lc3SettingId::LC3_24_2:
252       return ::le_audio::codec_spec_conf::kLeAudioSamplingFreq24000Hz;
253     case Lc3SettingId::LC3_32_1:
254     case Lc3SettingId::LC3_32_2:
255       return ::le_audio::codec_spec_conf::kLeAudioSamplingFreq32000Hz;
256     case Lc3SettingId::LC3_441_1:
257     case Lc3SettingId::LC3_441_2:
258       return ::le_audio::codec_spec_conf::kLeAudioSamplingFreq44100Hz;
259     case Lc3SettingId::LC3_48_1:
260     case Lc3SettingId::LC3_48_2:
261     case Lc3SettingId::LC3_48_3:
262     case Lc3SettingId::LC3_48_4:
263     case Lc3SettingId::LC3_48_5:
264     case Lc3SettingId::LC3_48_6:
265     case Lc3SettingId::LC3_VND_1:
266       return ::le_audio::codec_spec_conf::kLeAudioSamplingFreq48000Hz;
267     case Lc3SettingId::UNSUPPORTED:
268       return kLeAudioSamplingFreqRfu;
269   }
270 }
271 
272 static constexpr uint8_t kLeAudioCodecLC3FrameDurRfu = 0x02;
GetFrameDuration(Lc3SettingId id)273 uint8_t GetFrameDuration(Lc3SettingId id) {
274   switch (id) {
275     case Lc3SettingId::LC3_8_1:
276     case Lc3SettingId::LC3_16_1:
277     case Lc3SettingId::LC3_24_1:
278     case Lc3SettingId::LC3_32_1:
279     case Lc3SettingId::LC3_441_1:
280     case Lc3SettingId::LC3_48_1:
281     case Lc3SettingId::LC3_48_3:
282     case Lc3SettingId::LC3_48_5:
283       return ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameDur7500us;
284     case Lc3SettingId::LC3_8_2:
285     case Lc3SettingId::LC3_16_2:
286     case Lc3SettingId::LC3_24_2:
287     case Lc3SettingId::LC3_32_2:
288     case Lc3SettingId::LC3_441_2:
289     case Lc3SettingId::LC3_48_2:
290     case Lc3SettingId::LC3_48_4:
291     case Lc3SettingId::LC3_48_6:
292     case Lc3SettingId::LC3_VND_1:
293       return ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameDur10000us;
294     case Lc3SettingId::UNSUPPORTED:
295       return kLeAudioCodecLC3FrameDurRfu;
296   }
297 }
298 
299 static constexpr uint8_t kLeAudioCodecLC3OctetsPerCodecFrameInvalid = 0;
GetOctetsPerCodecFrame(Lc3SettingId id)300 uint16_t GetOctetsPerCodecFrame(Lc3SettingId id) {
301   switch (id) {
302     case Lc3SettingId::LC3_8_1:
303       return 26;
304     case Lc3SettingId::LC3_8_2:
305     case Lc3SettingId::LC3_16_1:
306       return 30;
307     case Lc3SettingId::LC3_16_2:
308       return 40;
309     case Lc3SettingId::LC3_24_1:
310       return 45;
311     case Lc3SettingId::LC3_24_2:
312     case Lc3SettingId::LC3_32_1:
313       return 60;
314     case Lc3SettingId::LC3_32_2:
315       return 80;
316     case Lc3SettingId::LC3_441_1:
317       return 97;
318     case Lc3SettingId::LC3_441_2:
319       return 130;
320     case Lc3SettingId::LC3_48_1:
321       return 75;
322     case Lc3SettingId::LC3_48_2:
323     case Lc3SettingId::LC3_VND_1:
324       return 100;
325     case Lc3SettingId::LC3_48_3:
326       return 90;
327     case Lc3SettingId::LC3_48_4:
328       return 120;
329     case Lc3SettingId::LC3_48_5:
330       return 116;
331     case Lc3SettingId::LC3_48_6:
332       return 155;
333     case Lc3SettingId::UNSUPPORTED:
334       return kLeAudioCodecLC3OctetsPerCodecFrameInvalid;
335   }
336 }
337 
338 class PublishedAudioCapabilitiesBuilder {
339  public:
PublishedAudioCapabilitiesBuilder()340   PublishedAudioCapabilitiesBuilder() {}
341 
Add(LeAudioCodecId codec_id,uint8_t conf_sampling_frequency,uint8_t conf_frame_duration,uint8_t audio_channel_counts,uint16_t octets_per_frame,uint8_t codec_frames_per_sdu=0)342   void Add(LeAudioCodecId codec_id, uint8_t conf_sampling_frequency,
343            uint8_t conf_frame_duration, uint8_t audio_channel_counts,
344            uint16_t octets_per_frame, uint8_t codec_frames_per_sdu = 0) {
345     uint16_t sampling_frequencies =
346         SamplingFreqConfig2Capability(conf_sampling_frequency);
347     uint8_t frame_durations =
348         FrameDurationConfig2Capability(conf_frame_duration);
349     uint8_t max_codec_frames_per_sdu = codec_frames_per_sdu;
350     uint32_t octets_per_frame_range =
351         octets_per_frame | (octets_per_frame << 16);
352 
353     pac_records_.push_back(
354         acs_ac_record({.codec_id = codec_id,
355                        .codec_spec_caps = LeAudioLtvMap({
356                            {kLeAudioCodecLC3TypeSamplingFreq,
357                             UINT16_TO_VEC_UINT8(sampling_frequencies)},
358                            {kLeAudioCodecLC3TypeFrameDuration,
359                             UINT8_TO_VEC_UINT8(frame_durations)},
360                            {kLeAudioCodecLC3TypeAudioChannelCounts,
361                             UINT8_TO_VEC_UINT8(audio_channel_counts)},
362                            {kLeAudioCodecLC3TypeOctetPerFrame,
363                             UINT32_TO_VEC_UINT8(octets_per_frame_range)},
364                            {kLeAudioCodecLC3TypeMaxCodecFramesPerSdu,
365                             UINT8_TO_VEC_UINT8(max_codec_frames_per_sdu)},
366                        }),
367                        .metadata = std::vector<uint8_t>(0)}));
368   }
369 
Add(const CodecCapabilitySetting & setting,uint8_t audio_channel_counts)370   void Add(const CodecCapabilitySetting& setting,
371            uint8_t audio_channel_counts) {
372     if (setting.id != LeAudioCodecIdLc3) return;
373 
374     const LeAudioLc3Config config = std::get<LeAudioLc3Config>(setting.config);
375 
376     Add(setting.id, *config.sampling_frequency, *config.frame_duration,
377         audio_channel_counts, *config.octets_per_codec_frame);
378   }
379 
Reset()380   void Reset() { pac_records_.clear(); }
381 
Get()382   PublishedAudioCapabilities Get() {
383     return PublishedAudioCapabilities({{hdl_pair_nil, pac_records_}});
384   }
385 
386  private:
387   std::vector<acs_ac_record> pac_records_;
388 };
389 
390 struct TestGroupAseConfigurationData {
391   LeAudioDevice* device;
392   uint8_t audio_channel_counts_snk;
393   uint8_t audio_channel_counts_src;
394 
395   /* Note, do not confuse ASEs with channels num. */
396   uint8_t expected_active_channel_num_snk;
397   uint8_t expected_active_channel_num_src;
398 };
399 
400 class LeAudioAseConfigurationTest : public Test {
401  protected:
SetUp()402   void SetUp() override {
403     group_ = new LeAudioDeviceGroup(group_id_);
404     bluetooth::manager::SetMockBtmInterface(&btm_interface_);
405     controller::SetMockControllerInterface(&controller_interface_);
406     ::le_audio::AudioSetConfigurationProvider::Initialize();
407     MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_);
408     ON_CALL(mock_csis_client_module_, Get())
409         .WillByDefault(Return(&mock_csis_client_module_));
410     ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
411         .WillByDefault(Return(true));
412     ON_CALL(mock_csis_client_module_, GetDeviceList(_))
413         .WillByDefault(Invoke([this](int group_id) { return addresses_; }));
414     ON_CALL(mock_csis_client_module_, GetDesiredSize(_))
415         .WillByDefault(
416             Invoke([this](int group_id) { return (int)(addresses_.size()); }));
417   }
418 
TearDown()419   void TearDown() override {
420     controller::SetMockControllerInterface(nullptr);
421     bluetooth::manager::SetMockBtmInterface(nullptr);
422     devices_.clear();
423     addresses_.clear();
424     delete group_;
425     ::le_audio::AudioSetConfigurationProvider::Cleanup();
426   }
427 
AddTestDevice(int snk_ase_num,int src_ase_num,int snk_ase_num_cached=0,int src_ase_num_cached=0)428   LeAudioDevice* AddTestDevice(int snk_ase_num, int src_ase_num,
429                                int snk_ase_num_cached = 0,
430                                int src_ase_num_cached = 0) {
431     int index = group_->Size() + 1;
432     auto device = (std::make_shared<LeAudioDevice>(
433         GetTestAddress(index), DeviceConnectState::DISCONNECTED));
434     devices_.push_back(device);
435     LOG_INFO(" addresses %d", (int)(addresses_.size()));
436     addresses_.push_back(device->address_);
437     LOG_INFO(" Addresses %d", (int)(addresses_.size()));
438 
439     group_->AddNode(device);
440 
441     int ase_id = 1;
442     for (int i = 0; i < src_ase_num; i++) {
443       device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSource,
444                                  ase_id++);
445     }
446 
447     for (int i = 0; i < snk_ase_num; i++) {
448       device->ases_.emplace_back(0x0000, 0x0000, kLeAudioDirectionSink,
449                                  ase_id++);
450     }
451 
452     for (int i = 0; i < src_ase_num_cached; i++) {
453       struct ase ase(0x0000, 0x0000, kLeAudioDirectionSource, ase_id++);
454       ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED;
455       device->ases_.push_back(ase);
456     }
457 
458     for (int i = 0; i < snk_ase_num_cached; i++) {
459       struct ase ase(0x0000, 0x0000, kLeAudioDirectionSink, ase_id++);
460       ase.state = AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED;
461       device->ases_.push_back(ase);
462     }
463 
464     device->SetSupportedContexts(AudioContexts(kLeAudioContextAllTypes),
465                                  AudioContexts(kLeAudioContextAllTypes));
466     device->SetAvailableContexts(AudioContexts(kLeAudioContextAllTypes),
467                                  AudioContexts(kLeAudioContextAllTypes));
468     device->snk_audio_locations_ =
469         ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
470         ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
471     device->src_audio_locations_ =
472         ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
473         ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
474 
475     device->conn_id_ = index;
476     device->SetConnectionState(DeviceConnectState::CONNECTED);
477     group_->ReloadAudioDirections();
478     group_->ReloadAudioLocations();
479     return device.get();
480   }
481 
TestGroupAseConfigurationVerdict(const TestGroupAseConfigurationData & data,uint8_t directions_to_verify)482   bool TestGroupAseConfigurationVerdict(
483       const TestGroupAseConfigurationData& data, uint8_t directions_to_verify) {
484     uint8_t active_channel_num_snk = 0;
485     uint8_t active_channel_num_src = 0;
486 
487     if (directions_to_verify == 0) return false;
488     if (data.device->HaveActiveAse() == 0) return false;
489 
490     for (ase* ase = data.device->GetFirstActiveAse(); ase;
491          ase = data.device->GetNextActiveAse(ase)) {
492       if (ase->direction == kLeAudioDirectionSink)
493         active_channel_num_snk +=
494             GetAudioChannelCounts(*ase->codec_config.audio_channel_allocation);
495       else
496         active_channel_num_src +=
497             GetAudioChannelCounts(*ase->codec_config.audio_channel_allocation);
498     }
499 
500     bool result = true;
501     if (directions_to_verify & kLeAudioDirectionSink) {
502       result &=
503           (data.expected_active_channel_num_snk == active_channel_num_snk);
504     }
505     if (directions_to_verify & kLeAudioDirectionSource) {
506       result &=
507           (data.expected_active_channel_num_src == active_channel_num_src);
508     }
509 
510     return result;
511   }
512 
SetCisInformationToActiveAse(void)513   void SetCisInformationToActiveAse(void) {
514     uint8_t cis_id = 1;
515     uint16_t cis_conn_hdl = 0x0060;
516 
517     for (auto& device : devices_) {
518       for (auto& ase : device->ases_) {
519         if (ase.active) {
520           ase.cis_id = cis_id++;
521           ase.cis_conn_hdl = cis_conn_hdl++;
522         }
523       }
524     }
525   }
526 
TestSingleAseConfiguration(LeAudioContextType context_type,TestGroupAseConfigurationData * data,uint8_t data_size,const AudioSetConfiguration * audio_set_conf,uint8_t directions_to_verify)527   void TestSingleAseConfiguration(LeAudioContextType context_type,
528                                   TestGroupAseConfigurationData* data,
529                                   uint8_t data_size,
530                                   const AudioSetConfiguration* audio_set_conf,
531                                   uint8_t directions_to_verify) {
532     // the configuration should fail if there are no active ases expected
533     bool success_expected = data_size > 0;
534     uint8_t configuration_directions = 0;
535 
536     for (int i = 0; i < data_size; i++) {
537       success_expected &= (data[i].expected_active_channel_num_snk +
538                            data[i].expected_active_channel_num_src) > 0;
539 
540       /* Prepare PAC's */
541       PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder;
542       for (const auto& entry : (*audio_set_conf).confs) {
543         if (entry.direction == kLeAudioDirectionSink) {
544           configuration_directions |= kLeAudioDirectionSink;
545           snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk);
546         } else {
547           configuration_directions |= kLeAudioDirectionSource;
548           src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src);
549         }
550       }
551 
552       data[i].device->snk_pacs_ = snk_pac_builder.Get();
553       data[i].device->src_pacs_ = src_pac_builder.Get();
554     }
555 
556     /* Stimulate update of available context map */
557     group_->UpdateAudioContextTypeAvailability(AudioContexts(context_type));
558     ASSERT_EQ(success_expected,
559               group_->Configure(context_type, AudioContexts(context_type)));
560 
561     bool result = true;
562     for (int i = 0; i < data_size; i++) {
563       result &= TestGroupAseConfigurationVerdict(
564           data[i], directions_to_verify & configuration_directions);
565     }
566     ASSERT_TRUE(result);
567   }
568 
getNumOfAses(LeAudioDevice * device,uint8_t direction)569   int getNumOfAses(LeAudioDevice* device, uint8_t direction) {
570     return std::count_if(
571         device->ases_.begin(), device->ases_.end(),
572         [direction](auto& a) { return a.direction == direction; });
573   }
574 
TestGroupAseConfiguration(LeAudioContextType context_type,TestGroupAseConfigurationData * data,uint8_t data_size,uint8_t directions_to_verify=kLeAudioDirectionSink|kLeAudioDirectionSource)575   void TestGroupAseConfiguration(
576       LeAudioContextType context_type, TestGroupAseConfigurationData* data,
577       uint8_t data_size,
578       uint8_t directions_to_verify = kLeAudioDirectionSink |
579                                      kLeAudioDirectionSource) {
580     const auto* configurations =
581         ::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations(
582             context_type);
583 
584     bool success_expected = directions_to_verify != 0;
585     int num_of_matching_configurations = 0;
586     for (const auto& audio_set_conf : *configurations) {
587       bool interesting_configuration = true;
588       uint8_t configuration_directions = 0;
589 
590       // the configuration should fail if there are no active ases expected
591       PublishedAudioCapabilitiesBuilder snk_pac_builder, src_pac_builder;
592       snk_pac_builder.Reset();
593       src_pac_builder.Reset();
594 
595       /* Let's go thru devices in the group and configure them*/
596       for (int i = 0; i < data_size; i++) {
597         int num_of_ase_snk_per_dev = 0;
598         int num_of_ase_src_per_dev = 0;
599 
600         /* Prepare PAC's for each device. Also make sure configuration is in our
601          * interest to test */
602         for (const auto& entry : (*audio_set_conf).confs) {
603           /* We are interested in the configurations which contains exact number
604            * of devices and number of ases is same the number of expected ases
605            * to active
606            */
607           if (entry.device_cnt != data_size) {
608             interesting_configuration = false;
609           }
610 
611           /* Make sure the strategy is the expected one */
612           if (entry.direction == kLeAudioDirectionSink &&
613               group_->GetGroupStrategy() != entry.strategy) {
614             interesting_configuration = false;
615           }
616 
617           if (entry.direction == kLeAudioDirectionSink) {
618             configuration_directions |= kLeAudioDirectionSink;
619             num_of_ase_snk_per_dev = entry.ase_cnt / data_size;
620             snk_pac_builder.Add(entry.codec, data[i].audio_channel_counts_snk);
621           } else {
622             configuration_directions |= kLeAudioDirectionSource;
623             num_of_ase_src_per_dev = entry.ase_cnt / data_size;
624             src_pac_builder.Add(entry.codec, data[i].audio_channel_counts_src);
625           }
626 
627           data[i].device->snk_pacs_ = snk_pac_builder.Get();
628           data[i].device->src_pacs_ = src_pac_builder.Get();
629         }
630 
631         /* Make sure configuration can satisfy number of expected active ASEs*/
632         if (num_of_ase_snk_per_dev >
633             data[i].device->GetAseCount(kLeAudioDirectionSink)) {
634           interesting_configuration = false;
635         }
636 
637         if (num_of_ase_src_per_dev >
638             data[i].device->GetAseCount(kLeAudioDirectionSource)) {
639           interesting_configuration = false;
640         }
641       }
642       /* Stimulate update of available context map */
643       group_->UpdateAudioContextTypeAvailability(AudioContexts(context_type));
644       auto configuration_result =
645           group_->Configure(context_type, AudioContexts(context_type));
646 
647       /* In case of configuration #ase is same as the one we expected to be
648        * activated verify, ASEs are actually active */
649       if (interesting_configuration &&
650           (directions_to_verify == configuration_directions)) {
651         ASSERT_TRUE(configuration_result);
652 
653         bool matching_conf = true;
654         /* Check if each of the devices has activated ASEs as expected */
655         for (int i = 0; i < data_size; i++) {
656           matching_conf &= TestGroupAseConfigurationVerdict(
657               data[i], configuration_directions);
658         }
659 
660         if (matching_conf) num_of_matching_configurations++;
661       }
662       group_->Deactivate();
663       TestAsesInactive();
664     }
665 
666     if (success_expected) {
667       ASSERT_TRUE((num_of_matching_configurations > 0));
668     } else {
669       ASSERT_TRUE(num_of_matching_configurations == 0);
670     }
671   }
672 
TestAsesActive(LeAudioCodecId codec_id,uint8_t sampling_frequency,uint8_t frame_duration,uint16_t octets_per_frame)673   void TestAsesActive(LeAudioCodecId codec_id, uint8_t sampling_frequency,
674                       uint8_t frame_duration, uint16_t octets_per_frame) {
675     bool active_ase = false;
676 
677     for (const auto& device : devices_) {
678       for (const auto& ase : device->ases_) {
679         if (!ase.active) continue;
680 
681         /* Configure may request only partial ases to be activated */
682         if (!active_ase && ase.active) active_ase = true;
683 
684         ASSERT_EQ(ase.codec_id, codec_id);
685 
686         /* FIXME: Validate other codec parameters than LC3 if any */
687         ASSERT_EQ(ase.codec_id, LeAudioCodecIdLc3);
688         if (ase.codec_id == LeAudioCodecIdLc3) {
689           ASSERT_EQ(ase.codec_config.sampling_frequency, sampling_frequency);
690           ASSERT_EQ(ase.codec_config.frame_duration, frame_duration);
691           ASSERT_EQ(ase.codec_config.octets_per_codec_frame, octets_per_frame);
692         }
693       }
694     }
695 
696     ASSERT_TRUE(active_ase);
697   }
698 
TestActiveAses(void)699   void TestActiveAses(void) {
700     for (auto& device : devices_) {
701       for (const auto& ase : device->ases_) {
702         if (ase.active) {
703           ASSERT_FALSE(ase.cis_id == ::le_audio::kInvalidCisId);
704         }
705       }
706     }
707   }
708 
TestAsesInactivated(const LeAudioDevice * device)709   void TestAsesInactivated(const LeAudioDevice* device) {
710     for (const auto& ase : device->ases_) {
711       ASSERT_FALSE(ase.active);
712       ASSERT_TRUE(ase.cis_id == ::le_audio::kInvalidCisId);
713       ASSERT_TRUE(ase.cis_conn_hdl == 0);
714     }
715   }
716 
TestAsesInactive()717   void TestAsesInactive() {
718     for (const auto& device : devices_) {
719       for (const auto& ase : device->ases_) {
720         ASSERT_FALSE(ase.active);
721       }
722     }
723   }
724 
TestLc3CodecConfig(LeAudioContextType context_type)725   void TestLc3CodecConfig(LeAudioContextType context_type) {
726     for (int i = Lc3SettingIdBegin; i < Lc3SettingIdEnd; i++) {
727       // test each configuration parameter against valid and invalid value
728       std::array<Lc3SettingId, 2> test_variants = {static_cast<Lc3SettingId>(i),
729                                                    Lc3SettingId::UNSUPPORTED};
730 
731       const bool is_lc3_setting_supported =
732           IsLc3SettingSupported(context_type, static_cast<Lc3SettingId>(i));
733 
734       for (const auto sf_variant : test_variants) {
735         uint8_t sampling_frequency = GetSamplingFrequency(sf_variant);
736         for (const auto fd_variant : test_variants) {
737           uint8_t frame_duration = GetFrameDuration(fd_variant);
738           for (const auto opcf_variant : test_variants) {
739             uint16_t octets_per_frame = GetOctetsPerCodecFrame(opcf_variant);
740 
741             PublishedAudioCapabilitiesBuilder pac_builder;
742             pac_builder.Add(LeAudioCodecIdLc3, sampling_frequency,
743                             frame_duration,
744                             kLeAudioCodecLC3ChannelCountSingleChannel |
745                                 kLeAudioCodecLC3ChannelCountTwoChannel,
746                             octets_per_frame);
747             for (auto& device : devices_) {
748               /* For simplicity configure both PACs with the same
749               parameters*/
750               device->snk_pacs_ = pac_builder.Get();
751               device->src_pacs_ = pac_builder.Get();
752             }
753 
754             bool success_expected = is_lc3_setting_supported;
755             if (is_lc3_setting_supported &&
756                 (sf_variant == Lc3SettingId::UNSUPPORTED ||
757                  fd_variant == Lc3SettingId::UNSUPPORTED ||
758                  opcf_variant == Lc3SettingId::UNSUPPORTED)) {
759               success_expected = false;
760             }
761 
762             /* Stimulate update of available context map */
763             group_->UpdateAudioContextTypeAvailability(
764                 AudioContexts(context_type));
765             ASSERT_EQ(
766                 success_expected,
767                 group_->Configure(context_type, AudioContexts(context_type)));
768             if (success_expected) {
769               TestAsesActive(LeAudioCodecIdLc3, sampling_frequency,
770                              frame_duration, octets_per_frame);
771               group_->Deactivate();
772             }
773 
774             TestAsesInactive();
775           }
776         }
777       }
778     }
779   }
780 
781   const int group_id_ = 6;
782   std::vector<std::shared_ptr<LeAudioDevice>> devices_;
783   std::vector<RawAddress> addresses_;
784   LeAudioDeviceGroup* group_ = nullptr;
785   bluetooth::manager::MockBtmInterface btm_interface_;
786   controller::MockControllerInterface controller_interface_;
787   MockCsisClient mock_csis_client_module_;
788 };
789 
TEST_F(LeAudioAseConfigurationTest,test_mono_speaker_ringtone)790 TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_ringtone) {
791   LeAudioDevice* mono_speaker = AddTestDevice(1, 0);
792   TestGroupAseConfigurationData data(
793       {mono_speaker, kLeAudioCodecLC3ChannelCountSingleChannel,
794        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0});
795 
796   /* mono, change location as by default it is stereo */
797   mono_speaker->snk_audio_locations_ =
798       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
799   group_->ReloadAudioLocations();
800 
801   uint8_t direction_to_verify = kLeAudioDirectionSink;
802   TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1,
803                             direction_to_verify);
804 }
805 
TEST_F(LeAudioAseConfigurationTest,test_mono_speaker_conversational)806 TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_conversational) {
807   LeAudioDevice* mono_speaker = AddTestDevice(1, 0);
808   TestGroupAseConfigurationData data({mono_speaker,
809                                       kLeAudioCodecLC3ChannelCountSingleChannel,
810                                       kLeAudioCodecLC3ChannelCountNone, 1, 0});
811 
812   /* mono, change location as by default it is stereo */
813   mono_speaker->snk_audio_locations_ =
814       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
815   group_->ReloadAudioLocations();
816 
817   /* Microphone should be used on the phone */
818   uint8_t direction_to_verify = kLeAudioDirectionSink;
819   TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1,
820                             direction_to_verify);
821 }
822 
TEST_F(LeAudioAseConfigurationTest,test_mono_speaker_media)823 TEST_F(LeAudioAseConfigurationTest, test_mono_speaker_media) {
824   LeAudioDevice* mono_speaker = AddTestDevice(1, 0);
825   TestGroupAseConfigurationData data({mono_speaker,
826                                       kLeAudioCodecLC3ChannelCountSingleChannel,
827                                       kLeAudioCodecLC3ChannelCountNone, 1, 0});
828 
829   /* mono, change location as by default it is stereo */
830   mono_speaker->snk_audio_locations_ =
831       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
832   group_->ReloadAudioLocations();
833 
834   uint8_t direction_to_verify = kLeAudioDirectionSink;
835   TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1,
836                             direction_to_verify);
837 }
838 
TEST_F(LeAudioAseConfigurationTest,test_bounded_headphones_ringtone)839 TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_ringtone) {
840   LeAudioDevice* bounded_headphones = AddTestDevice(2, 0);
841   TestGroupAseConfigurationData data(
842       {bounded_headphones, kLeAudioCodecLC3ChannelCountTwoChannel,
843        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0});
844 
845   uint8_t direction_to_verify = kLeAudioDirectionSink;
846   TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1,
847                             direction_to_verify);
848 }
849 
TEST_F(LeAudioAseConfigurationTest,test_bounded_headphones_conversional)850 TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_conversional) {
851   LeAudioDevice* bounded_headphones = AddTestDevice(2, 0);
852   TestGroupAseConfigurationData data({bounded_headphones,
853                                       kLeAudioCodecLC3ChannelCountTwoChannel,
854                                       kLeAudioCodecLC3ChannelCountNone, 2, 0});
855 
856   uint8_t direction_to_verify = kLeAudioDirectionSink;
857   TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1,
858                             direction_to_verify);
859 }
860 
TEST_F(LeAudioAseConfigurationTest,test_bounded_headphones_media)861 TEST_F(LeAudioAseConfigurationTest, test_bounded_headphones_media) {
862   LeAudioDevice* bounded_headphones = AddTestDevice(2, 0);
863   TestGroupAseConfigurationData data({bounded_headphones,
864                                       kLeAudioCodecLC3ChannelCountTwoChannel,
865                                       kLeAudioCodecLC3ChannelCountNone, 2, 0});
866 
867   uint8_t direction_to_verify = kLeAudioDirectionSink;
868   TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1,
869                             direction_to_verify);
870 }
871 
TEST_F(LeAudioAseConfigurationTest,test_bounded_headset_ringtone_mono_microphone)872 TEST_F(LeAudioAseConfigurationTest,
873        test_bounded_headset_ringtone_mono_microphone) {
874   LeAudioDevice* bounded_headset = AddTestDevice(2, 1);
875   TestGroupAseConfigurationData data(
876       {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel,
877        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1});
878 
879   /* mono, change location as by default it is stereo */
880   bounded_headset->src_audio_locations_ =
881       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
882   group_->ReloadAudioLocations();
883 
884   TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1);
885 }
886 
TEST_F(LeAudioAseConfigurationTest,test_bounded_headset_ringtone_stereo_microphone)887 TEST_F(LeAudioAseConfigurationTest,
888        test_bounded_headset_ringtone_stereo_microphone) {
889   LeAudioDevice* bounded_headset = AddTestDevice(2, 2);
890   TestGroupAseConfigurationData data(
891       {bounded_headset,
892        kLeAudioCodecLC3ChannelCountSingleChannel |
893            kLeAudioCodecLC3ChannelCountTwoChannel,
894        kLeAudioCodecLC3ChannelCountSingleChannel |
895            kLeAudioCodecLC3ChannelCountTwoChannel,
896        2, 2});
897 
898   TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1);
899 }
900 
TEST_F(LeAudioAseConfigurationTest,test_bounded_headset_conversional)901 TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_conversional) {
902   LeAudioDevice* bounded_headset = AddTestDevice(2, 1);
903   TestGroupAseConfigurationData data(
904       {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel,
905        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1});
906 
907   TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1);
908 }
909 
TEST_F(LeAudioAseConfigurationTest,test_bounded_headset_media)910 TEST_F(LeAudioAseConfigurationTest, test_bounded_headset_media) {
911   LeAudioDevice* bounded_headset = AddTestDevice(2, 1);
912   TestGroupAseConfigurationData data(
913       {bounded_headset, kLeAudioCodecLC3ChannelCountTwoChannel,
914        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0});
915 
916   uint8_t directions_to_verify = kLeAudioDirectionSink;
917   TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1,
918                             directions_to_verify);
919 }
920 
TEST_F(LeAudioAseConfigurationTest,test_earbuds_ringtone)921 TEST_F(LeAudioAseConfigurationTest, test_earbuds_ringtone) {
922   LeAudioDevice* left = AddTestDevice(1, 1);
923   LeAudioDevice* right = AddTestDevice(1, 1);
924   TestGroupAseConfigurationData data[] = {
925       {left, kLeAudioCodecLC3ChannelCountSingleChannel,
926        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1},
927       {right, kLeAudioCodecLC3ChannelCountSingleChannel,
928        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}};
929 
930   /* Change location as by default it is stereo */
931   left->snk_audio_locations_ =
932       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
933   left->src_audio_locations_ =
934       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
935   right->snk_audio_locations_ =
936       ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
937   right->src_audio_locations_ =
938       ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
939   group_->ReloadAudioLocations();
940 
941   TestGroupAseConfiguration(LeAudioContextType::RINGTONE, data, 2);
942 }
943 
TEST_F(LeAudioAseConfigurationTest,test_earbuds_conversional)944 TEST_F(LeAudioAseConfigurationTest, test_earbuds_conversional) {
945   LeAudioDevice* left = AddTestDevice(1, 1);
946   LeAudioDevice* right = AddTestDevice(1, 1);
947   TestGroupAseConfigurationData data[] = {
948       {left, kLeAudioCodecLC3ChannelCountSingleChannel,
949        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1},
950       {right, kLeAudioCodecLC3ChannelCountSingleChannel,
951        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1}};
952 
953   /* Change location as by default it is stereo */
954   left->snk_audio_locations_ =
955       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
956   left->src_audio_locations_ =
957       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
958   right->snk_audio_locations_ =
959       ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
960   right->src_audio_locations_ =
961       ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
962   group_->ReloadAudioLocations();
963 
964   TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, data, 2);
965 }
966 
TEST_F(LeAudioAseConfigurationTest,test_earbuds_media)967 TEST_F(LeAudioAseConfigurationTest, test_earbuds_media) {
968   LeAudioDevice* left = AddTestDevice(1, 1);
969   LeAudioDevice* right = AddTestDevice(1, 1);
970   TestGroupAseConfigurationData data[] = {
971       {left, kLeAudioCodecLC3ChannelCountSingleChannel,
972        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0},
973       {right, kLeAudioCodecLC3ChannelCountSingleChannel,
974        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}};
975 
976   /* Change location as by default it is stereo */
977   left->snk_audio_locations_ =
978       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
979   left->src_audio_locations_ =
980       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
981   right->snk_audio_locations_ =
982       ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
983   right->src_audio_locations_ =
984       ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
985   group_->ReloadAudioLocations();
986 
987   uint8_t directions_to_verify = kLeAudioDirectionSink;
988   TestGroupAseConfiguration(LeAudioContextType::MEDIA, data, 2,
989                             directions_to_verify);
990 }
991 
TEST_F(LeAudioAseConfigurationTest,test_handsfree_mono_ringtone)992 TEST_F(LeAudioAseConfigurationTest, test_handsfree_mono_ringtone) {
993   LeAudioDevice* handsfree = AddTestDevice(1, 1);
994   TestGroupAseConfigurationData data(
995       {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel,
996        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1});
997 
998   handsfree->snk_audio_locations_ =
999       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
1000   handsfree->src_audio_locations_ =
1001       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
1002   group_->ReloadAudioLocations();
1003 
1004   TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1);
1005 }
1006 
TEST_F(LeAudioAseConfigurationTest,test_handsfree_stereo_ringtone)1007 TEST_F(LeAudioAseConfigurationTest, test_handsfree_stereo_ringtone) {
1008   LeAudioDevice* handsfree = AddTestDevice(1, 1);
1009   TestGroupAseConfigurationData data(
1010       {handsfree,
1011        kLeAudioCodecLC3ChannelCountSingleChannel |
1012            kLeAudioCodecLC3ChannelCountTwoChannel,
1013        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1});
1014 
1015   TestGroupAseConfiguration(LeAudioContextType::RINGTONE, &data, 1);
1016 }
1017 
TEST_F(LeAudioAseConfigurationTest,test_handsfree_mono_conversional)1018 TEST_F(LeAudioAseConfigurationTest, test_handsfree_mono_conversional) {
1019   LeAudioDevice* handsfree = AddTestDevice(1, 1);
1020   TestGroupAseConfigurationData data(
1021       {handsfree, kLeAudioCodecLC3ChannelCountSingleChannel,
1022        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 1});
1023 
1024   handsfree->snk_audio_locations_ =
1025       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
1026   handsfree->src_audio_locations_ =
1027       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
1028   group_->ReloadAudioLocations();
1029 
1030   TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1);
1031 }
1032 
TEST_F(LeAudioAseConfigurationTest,test_handsfree_stereo_conversional)1033 TEST_F(LeAudioAseConfigurationTest, test_handsfree_stereo_conversional) {
1034   LeAudioDevice* handsfree = AddTestDevice(1, 1);
1035   TestGroupAseConfigurationData data(
1036       {handsfree,
1037        kLeAudioCodecLC3ChannelCountSingleChannel |
1038            kLeAudioCodecLC3ChannelCountTwoChannel,
1039        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1});
1040 
1041   TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1);
1042 }
1043 
TEST_F(LeAudioAseConfigurationTest,test_handsfree_full_cached_conversional)1044 TEST_F(LeAudioAseConfigurationTest, test_handsfree_full_cached_conversional) {
1045   LeAudioDevice* handsfree = AddTestDevice(0, 0, 1, 1);
1046   TestGroupAseConfigurationData data(
1047       {handsfree,
1048        kLeAudioCodecLC3ChannelCountSingleChannel |
1049            kLeAudioCodecLC3ChannelCountTwoChannel,
1050        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1});
1051 
1052   TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1);
1053 }
1054 
TEST_F(LeAudioAseConfigurationTest,test_handsfree_partial_cached_conversional)1055 TEST_F(LeAudioAseConfigurationTest,
1056        test_handsfree_partial_cached_conversional) {
1057   LeAudioDevice* handsfree = AddTestDevice(1, 0, 0, 1);
1058   TestGroupAseConfigurationData data(
1059       {handsfree,
1060        kLeAudioCodecLC3ChannelCountSingleChannel |
1061            kLeAudioCodecLC3ChannelCountTwoChannel,
1062        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 1});
1063 
1064   TestGroupAseConfiguration(LeAudioContextType::CONVERSATIONAL, &data, 1);
1065 }
1066 
TEST_F(LeAudioAseConfigurationTest,test_handsfree_media_two_channels_allocation_stereo)1067 TEST_F(LeAudioAseConfigurationTest,
1068        test_handsfree_media_two_channels_allocation_stereo) {
1069   LeAudioDevice* handsfree = AddTestDevice(1, 1);
1070   TestGroupAseConfigurationData data(
1071       {handsfree,
1072        kLeAudioCodecLC3ChannelCountSingleChannel |
1073            kLeAudioCodecLC3ChannelCountTwoChannel,
1074        kLeAudioCodecLC3ChannelCountSingleChannel, 2, 0});
1075 
1076   uint8_t directions_to_verify = kLeAudioDirectionSink;
1077   TestGroupAseConfiguration(LeAudioContextType::MEDIA, &data, 1,
1078                             directions_to_verify);
1079 }
1080 
TEST_F(LeAudioAseConfigurationTest,test_lc3_config_ringtone)1081 TEST_F(LeAudioAseConfigurationTest, test_lc3_config_ringtone) {
1082   AddTestDevice(1, 1);
1083 
1084   TestLc3CodecConfig(LeAudioContextType::RINGTONE);
1085 }
1086 
TEST_F(LeAudioAseConfigurationTest,test_lc3_config_conversional)1087 TEST_F(LeAudioAseConfigurationTest, test_lc3_config_conversional) {
1088   AddTestDevice(1, 1);
1089 
1090   TestLc3CodecConfig(LeAudioContextType::CONVERSATIONAL);
1091 }
1092 
TEST_F(LeAudioAseConfigurationTest,test_lc3_config_media)1093 TEST_F(LeAudioAseConfigurationTest, test_lc3_config_media) {
1094   AddTestDevice(1, 1);
1095 
1096   TestLc3CodecConfig(LeAudioContextType::MEDIA);
1097 }
1098 
TEST_F(LeAudioAseConfigurationTest,test_unsupported_codec)1099 TEST_F(LeAudioAseConfigurationTest, test_unsupported_codec) {
1100   const LeAudioCodecId UnsupportedCodecId = {
1101       .coding_format = kLeAudioCodingFormatVendorSpecific,
1102       .vendor_company_id = 0xBAD,
1103       .vendor_codec_id = 0xC0DE,
1104   };
1105 
1106   LeAudioDevice* device = AddTestDevice(1, 0);
1107 
1108   PublishedAudioCapabilitiesBuilder pac_builder;
1109   pac_builder.Add(UnsupportedCodecId,
1110                   GetSamplingFrequency(Lc3SettingId::LC3_16_2),
1111                   GetFrameDuration(Lc3SettingId::LC3_16_2),
1112                   kLeAudioCodecLC3ChannelCountSingleChannel,
1113                   GetOctetsPerCodecFrame(Lc3SettingId::LC3_16_2));
1114   device->snk_pacs_ = pac_builder.Get();
1115   device->src_pacs_ = pac_builder.Get();
1116 
1117   ASSERT_FALSE(group_->Configure(
1118       LeAudioContextType::RINGTONE,
1119       AudioContexts(static_cast<uint16_t>(LeAudioContextType::RINGTONE))));
1120   TestAsesInactive();
1121 }
1122 
TEST_F(LeAudioAseConfigurationTest,test_reconnection_media)1123 TEST_F(LeAudioAseConfigurationTest, test_reconnection_media) {
1124   LeAudioDevice* left = AddTestDevice(2, 1);
1125   LeAudioDevice* right = AddTestDevice(2, 1);
1126 
1127   /* Change location as by default it is stereo */
1128   left->snk_audio_locations_ =
1129       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
1130   left->src_audio_locations_ =
1131       ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
1132   right->snk_audio_locations_ =
1133       ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
1134   right->src_audio_locations_ =
1135       ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
1136   group_->ReloadAudioLocations();
1137 
1138   TestGroupAseConfigurationData data[] = {
1139       {left, kLeAudioCodecLC3ChannelCountSingleChannel,
1140        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0},
1141       {right, kLeAudioCodecLC3ChannelCountSingleChannel,
1142        kLeAudioCodecLC3ChannelCountSingleChannel, 1, 0}};
1143 
1144   auto all_configurations =
1145       ::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations(
1146           LeAudioContextType::MEDIA);
1147   ASSERT_NE(nullptr, all_configurations);
1148   ASSERT_NE(all_configurations->end(), all_configurations->begin());
1149   auto configuration = *all_configurations->begin();
1150 
1151   uint8_t direction_to_verify = kLeAudioDirectionSink;
1152   TestSingleAseConfiguration(LeAudioContextType::MEDIA, data, 2, configuration,
1153                              direction_to_verify);
1154 
1155   /* Generate CISes, symulate CIG creation and assign cis handles to ASEs.*/
1156   group_->CigGenerateCisIds(LeAudioContextType::MEDIA);
1157   std::vector<uint16_t> handles = {0x0012, 0x0013};
1158   group_->CigAssignCisConnHandles(handles);
1159   group_->CigAssignCisIds(left);
1160   group_->CigAssignCisIds(right);
1161 
1162   TestActiveAses();
1163   /* Left got disconnected */
1164   left->DeactivateAllAses();
1165 
1166   /* Unassign from the group*/
1167   group_->CigUnassignCis(left);
1168 
1169   TestAsesInactivated(left);
1170 
1171   /* Prepare reconfiguration */
1172   uint8_t number_of_active_ases = 1;  // Right one
1173   auto* ase = right->GetFirstActiveAseByDirection(kLeAudioDirectionSink);
1174   ::le_audio::types::AudioLocations group_snk_audio_location =
1175       *ase->codec_config.audio_channel_allocation;
1176   ::le_audio::types::AudioLocations group_src_audio_location =
1177       *ase->codec_config.audio_channel_allocation;
1178 
1179   /* Get entry for the sink direction and use it to set configuration */
1180   std::vector<uint8_t> ccid_list;
1181   for (auto& ent : configuration->confs) {
1182     if (ent.direction == ::le_audio::types::kLeAudioDirectionSink) {
1183       left->ConfigureAses(ent, group_->GetConfigurationContextType(),
1184                           &number_of_active_ases, group_snk_audio_location,
1185                           group_src_audio_location, false,
1186                           ::le_audio::types::AudioContexts(), ccid_list);
1187     }
1188   }
1189 
1190   ASSERT_TRUE(number_of_active_ases == 2);
1191   ASSERT_TRUE(group_snk_audio_location == kChannelAllocationStereo);
1192 
1193   uint8_t directions_to_verify = ::le_audio::types::kLeAudioDirectionSink;
1194   for (int i = 0; i < 2; i++) {
1195     TestGroupAseConfigurationVerdict(data[i], directions_to_verify);
1196   }
1197 
1198   /* Before device is rejoining, and group already exist, cis handles are
1199    * assigned before sending codec config
1200    */
1201   group_->CigAssignCisIds(left);
1202   group_->CigAssignCisConnHandlesToAses(left);
1203 
1204   TestActiveAses();
1205 }
1206 }  // namespace
1207 }  // namespace internal
1208 }  // namespace le_audio
1209 }  // namespace bluetooth
1210