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 "le_audio_types.h"
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include <vector>
24 
25 #include "le_audio_utils.h"
26 
27 namespace bluetooth::le_audio {
28 namespace types {
29 
30 using ::testing::AllOf;
31 using ::testing::Contains;
32 using ::testing::ElementsAre;
33 using ::testing::ElementsAreArray;
34 using ::testing::Eq;
35 using ::testing::Pair;
36 using ::testing::SizeIs;
37 
TEST(LeAudioLtvMapTest,test_serialization)38 TEST(LeAudioLtvMapTest, test_serialization) {
39   // clang-format off
40   const std::vector<uint8_t> ltv_test_vec{
41       0x02, 0x01, 0x0a,
42       0x03, 0x02, 0xaa, 0xbb,
43       0x04, 0x03, 0xde, 0xc0, 0xd0,
44   };
45 
46   const std::vector<uint8_t> ltv_test_vec2{
47       0x04, 0x03, 0xde, 0xc0, 0xde,
48       0x05, 0x04, 0xc0, 0xde, 0xc0, 0xde,
49   };
50 
51   const std::vector<uint8_t> ltv_test_vec_expected{
52       0x02, 0x01, 0x0a,
53       0x03, 0x02, 0xaa, 0xbb,
54       0x04, 0x03, 0xde, 0xc0, 0xde,
55       0x05, 0x04, 0xc0, 0xde, 0xc0, 0xde,
56   };
57   // clang-format on
58 
59   // Parse
60   bool success;
61   LeAudioLtvMap ltv_map = LeAudioLtvMap::Parse(ltv_test_vec.data(), ltv_test_vec.size(), success);
62   auto hash_one = ltv_map.GetHash();
63   ASSERT_TRUE(success);
64   ASSERT_NE(hash_one, 0lu);
65   ASSERT_FALSE(ltv_map.IsEmpty());
66   ASSERT_EQ((size_t)3, ltv_map.Size());
67 
68   ASSERT_TRUE(ltv_map.Find(0x03));
69   ASSERT_THAT(*(ltv_map.Find(0x03)), ElementsAre(0xde, 0xc0, 0xd0));
70 
71   LeAudioLtvMap ltv_map2 =
72           LeAudioLtvMap::Parse(ltv_test_vec2.data(), ltv_test_vec2.size(), success);
73   auto hash_two = ltv_map2.GetHash();
74   ASSERT_TRUE(success);
75   ASSERT_NE(hash_two, 0lu);
76   ASSERT_FALSE(ltv_map2.IsEmpty());
77   ASSERT_EQ((size_t)2, ltv_map2.Size());
78   ASSERT_NE(hash_one, hash_two);
79 
80   ltv_map.Append(ltv_map2);
81   ASSERT_NE(ltv_map.GetHash(), 0lu);
82   ASSERT_NE(ltv_map.GetHash(), hash_one);
83   ASSERT_NE(ltv_map.GetHash(), hash_two);
84   ASSERT_EQ((size_t)4, ltv_map.Size());
85 
86   ASSERT_TRUE(ltv_map.Find(0x01));
87   ASSERT_THAT(*(ltv_map.Find(0x01)), ElementsAre(0x0a));
88   ASSERT_TRUE(ltv_map.Find(0x02));
89   ASSERT_THAT(*(ltv_map.Find(0x02)), ElementsAre(0xaa, 0xbb));
90   ASSERT_TRUE(ltv_map.Find(0x03));
91   ASSERT_THAT(*(ltv_map.Find(0x03)), ElementsAre(0xde, 0xc0, 0xde));
92   ASSERT_TRUE(ltv_map.Find(0x04));
93   ASSERT_THAT(*(ltv_map.Find(0x04)), ElementsAre(0xc0, 0xde, 0xc0, 0xde));
94 
95   // RawPacket
96   std::vector<uint8_t> serialized(ltv_map.RawPacketSize());
97   ASSERT_TRUE(ltv_map.RawPacket(serialized.data()));
98   ASSERT_THAT(serialized, ElementsAreArray(ltv_test_vec_expected));
99   ASSERT_THAT(ltv_map2.RawPacket(), ElementsAreArray(ltv_test_vec2));
100 }
101 
TEST(LeAudioLtvMapTest,test_serialization_macros)102 TEST(LeAudioLtvMapTest, test_serialization_macros) {
103   uint64_t value = 0x08090A0B0C0D0E0F;
104 
105   auto u16vec = UINT16_TO_VEC_UINT8(value);
106   ASSERT_EQ(sizeof(uint16_t), u16vec.size());
107   ASSERT_EQ(0x0F, u16vec[0]);
108   ASSERT_EQ(0x0E, u16vec[1]);
109 
110   auto u32vec = UINT32_TO_VEC_UINT8(value);
111   ASSERT_EQ(sizeof(uint32_t), u32vec.size());
112   ASSERT_EQ(0x0F, u32vec[0]);
113   ASSERT_EQ(0x0E, u32vec[1]);
114   ASSERT_EQ(0x0D, u32vec[2]);
115   ASSERT_EQ(0x0C, u32vec[3]);
116 }
117 
TEST(LeAudioLtvMapTest,test_serialization_ltv_len_is_zero)118 TEST(LeAudioLtvMapTest, test_serialization_ltv_len_is_zero) {
119   // clang-format off
120   const std::vector<uint8_t> ltv_test_vec{
121       0x02, 0x01, 0x0a,
122       0x03, 0x02, 0xaa, 0xbb,
123       0x00, 0x00, 0x00, 0x00, 0x00,       // ltv_len == 0
124       0x05, 0x04, 0xc0, 0xde, 0xc0, 0xde,
125   };
126   // clang-format on
127 
128   // Parse
129   bool success;
130   LeAudioLtvMap ltv_map = LeAudioLtvMap::Parse(ltv_test_vec.data(), ltv_test_vec.size(), success);
131   ASSERT_TRUE(success);
132   ASSERT_FALSE(ltv_map.IsEmpty());
133   ASSERT_EQ((size_t)3, ltv_map.Size());
134 
135   ASSERT_TRUE(ltv_map.Find(0x01));
136   ASSERT_THAT(*(ltv_map.Find(0x01)), ElementsAre(0x0a));
137   ASSERT_TRUE(ltv_map.Find(0x02));
138   ASSERT_THAT(*(ltv_map.Find(0x02)), ElementsAre(0xaa, 0xbb));
139   ASSERT_TRUE(ltv_map.Find(0x04));
140   ASSERT_THAT(*(ltv_map.Find(0x04)), ElementsAre(0xc0, 0xde, 0xc0, 0xde));
141 
142   // RawPacket
143   std::vector<uint8_t> serialized(ltv_map.RawPacketSize());
144   ASSERT_TRUE(ltv_map.RawPacket(serialized.data()));
145   ASSERT_THAT(serialized, ElementsAre(0x02, 0x01, 0x0a, 0x03, 0x02, 0xaa, 0xbb, 0x05, 0x04, 0xc0,
146                                       0xde, 0xc0, 0xde));
147 }
148 
TEST(LeAudioLtvMapTest,test_serialization_ltv_len_is_one)149 TEST(LeAudioLtvMapTest, test_serialization_ltv_len_is_one) {
150   // clang-format off
151   const std::vector<uint8_t> ltv_test_vec{
152     0x02, 0x01, 0x0a,
153     0x01, 0x02,
154   };
155   // clang-format on
156 
157   // Parse
158   bool success;
159   LeAudioLtvMap ltv_map = LeAudioLtvMap::Parse(ltv_test_vec.data(), ltv_test_vec.size(), success);
160   ASSERT_TRUE(success);
161   ASSERT_FALSE(ltv_map.IsEmpty());
162   ASSERT_EQ((size_t)2, ltv_map.Size());
163 
164   ASSERT_TRUE(ltv_map.Find(0x01));
165   ASSERT_THAT(*(ltv_map.Find(0x01)), ElementsAre(0x0a));
166   ASSERT_TRUE(ltv_map.Find(0x02));
167   ASSERT_THAT(*(ltv_map.Find(0x02)), SizeIs(0));
168 
169   // RawPacket
170   std::vector<uint8_t> serialized(ltv_map.RawPacketSize());
171   ASSERT_TRUE(ltv_map.RawPacket(serialized.data()));
172   ASSERT_THAT(serialized, ElementsAreArray(ltv_test_vec));
173 }
174 
TEST(LeAudioLtvMapTest,test_serialization_ltv_len_is_invalid)175 TEST(LeAudioLtvMapTest, test_serialization_ltv_len_is_invalid) {
176   // clang-format off
177   const std::vector<uint8_t> ltv_test_vec_1{
178       0x02, 0x01, 0x0a,
179       0x04, 0x02, 0xaa, 0xbb,  // one byte missing
180   };
181   const std::vector<uint8_t> ltv_test_vec_2{
182       0x02, 0x01, 0x0a,
183       0x03, 0x02, 0xaa, 0xbb,
184       0x01,
185   };
186   const std::vector<uint8_t> ltv_test_vec_3{
187       0x02, 0x01, 0x0a,
188       0x03, 0x02, 0xaa, 0xbb,
189       0x02, 0x03,
190   };
191   // clang-format on
192 
193   // Parse
194   bool success = true;
195   LeAudioLtvMap ltv_map;
196 
197   ltv_map = LeAudioLtvMap::Parse(ltv_test_vec_1.data(), ltv_test_vec_1.size(), success);
198   ASSERT_FALSE(success);
199 
200   ltv_map = LeAudioLtvMap::Parse(ltv_test_vec_2.data(), ltv_test_vec_2.size(), success);
201   ASSERT_FALSE(success);
202 
203   ltv_map = LeAudioLtvMap::Parse(ltv_test_vec_3.data(), ltv_test_vec_3.size(), success);
204   ASSERT_FALSE(success);
205 }
206 
TEST(LeAudioLtvMapTest,test_configuration_valid)207 TEST(LeAudioLtvMapTest, test_configuration_valid) {
208   // clang-format off
209   const std::vector<uint8_t> config_ltv_vec{
210       // SamplingFreq = 48000
211       0x02, 0x01, 0x08,
212       // FrameDuration = 10000us
213       0x02, 0x02, 0x01,
214       // AudioChannelAllocation = kLeAudioLocationFrontLeft | kLeAudioLocationFrontRight
215       0x05, 0x03, 0x03, 0x00, 0x00, 0x00,
216       // OctetsPerCodecFrame = 40
217       0x03, 0x04, 40, 0x00,
218       // Unknown type entry to ignore
219       0x05, 0x06, 0x11, 0x22, 0x33, 0x44,
220       // CodecFrameBlocksPerSdu = 1
221       0x02, 0x05, 1,
222   };
223   // clang-format on
224 
225   // Parse
226   bool success = true;
227   LeAudioLtvMap ltv_map =
228           LeAudioLtvMap::Parse(config_ltv_vec.data(), config_ltv_vec.size(), success);
229   ASSERT_TRUE(success);
230 
231   // Verify the codec configuration values
232   auto config = ltv_map.GetAsCoreCodecConfig();
233 
234   // SamplingFreq = 48000
235   ASSERT_TRUE(config.sampling_frequency.has_value());
236   ASSERT_EQ(0x08, config.sampling_frequency.value());
237   ASSERT_EQ(48000u, config.GetSamplingFrequencyHz());
238 
239   // FrameDuration = 10000us
240   ASSERT_TRUE(config.frame_duration.has_value());
241   ASSERT_EQ(0x01, config.frame_duration.value());
242   ASSERT_EQ(10000u, config.GetFrameDurationUs());
243 
244   // AudioChannelAllocation = kLeAudioLocationFrontLeft | kLeAudioLocationFrontRight
245   ASSERT_TRUE(config.audio_channel_allocation.has_value());
246   ASSERT_EQ(0x00000003u, config.audio_channel_allocation.value());
247 
248   // OctetsPerCodecFrame = 40
249   ASSERT_TRUE(config.octets_per_codec_frame.has_value());
250   ASSERT_EQ(0x0028u, config.octets_per_codec_frame.value());
251 
252   // CodecFrameBlocksPerSdu = 1
253   ASSERT_TRUE(config.codec_frames_blocks_per_sdu.has_value());
254   ASSERT_EQ(0x01u, config.codec_frames_blocks_per_sdu.value());
255 }
256 
TEST(LeAudioLtvMapTest,test_capabilities_valid)257 TEST(LeAudioLtvMapTest, test_capabilities_valid) {
258   // clang-format off
259   const std::vector<uint8_t> capabilities_ltv_vec{
260       // SupportedSamplingFrequencies = 96000 and 16000
261       0x03, 0x01,
262           (uint8_t)(codec_spec_caps::kLeAudioSamplingFreq16000Hz) |
263               (uint8_t)(codec_spec_caps::kLeAudioSamplingFreq96000Hz),
264           (uint8_t)(codec_spec_caps::kLeAudioSamplingFreq16000Hz >> 8) |
265               (uint8_t)(codec_spec_caps::kLeAudioSamplingFreq96000Hz >> 8),
266       // SupportedFrameDurations = 10ms, 7.5ms, 10ms preferred
267       0x02, 0x02, codec_spec_caps::kLeAudioCodecFrameDur7500us |
268                       codec_spec_caps::kLeAudioCodecFrameDur10000us |
269                       codec_spec_caps::kLeAudioCodecFrameDurPrefer10000us,
270       // SupportedAudioChannelCounts = 0b1 | 0b2 (one and two channels)
271       0x02, 0x03, 0b01 | 0b10,
272       // SupportedOctetsPerCodecFrame = min:40, max:80
273       0x05, 0x04, 40, 00, 80, 00,
274       // Unknown type entry to ignore
275       0x05, 0x06, 0x11, 0x22, 0x33, 0x44,
276       // SupportedMaxCodecFramesPerSdu = 2
277       0x02, 0x05, 0x02,
278   };
279   // clang-format on
280 
281   // Parse
282   bool success = true;
283   LeAudioLtvMap ltv_map =
284           LeAudioLtvMap::Parse(capabilities_ltv_vec.data(), capabilities_ltv_vec.size(), success);
285   ASSERT_TRUE(success);
286 
287   // Verify the codec capabilities values
288   auto caps = ltv_map.GetAsCoreCodecCapabilities();
289 
290   // SupportedSamplingFrequencies = 96000 and 16000
291   ASSERT_TRUE(caps.HasSupportedSamplingFrequencies());
292   ASSERT_EQ(codec_spec_caps::kLeAudioSamplingFreq16000Hz |
293                     codec_spec_caps::kLeAudioSamplingFreq96000Hz,
294             caps.supported_sampling_frequencies.value());
295   // Check config values against the capabilities
296   ASSERT_FALSE(
297           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq8000Hz));
298   ASSERT_FALSE(
299           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq11025Hz));
300   ASSERT_TRUE(
301           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq16000Hz));
302   ASSERT_FALSE(
303           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq22050Hz));
304   ASSERT_FALSE(
305           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq24000Hz));
306   ASSERT_FALSE(
307           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq32000Hz));
308   ASSERT_FALSE(
309           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq44100Hz));
310   ASSERT_FALSE(
311           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq48000Hz));
312   ASSERT_FALSE(
313           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq88200Hz));
314   ASSERT_TRUE(
315           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq96000Hz));
316   ASSERT_FALSE(
317           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq176400Hz));
318   ASSERT_FALSE(
319           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq192000Hz));
320   ASSERT_FALSE(
321           caps.IsSamplingFrequencyConfigSupported(codec_spec_conf::kLeAudioSamplingFreq384000Hz));
322 
323   // SupportedFrameDurations = 10ms, 7.5ms, 10ms preferred
324   ASSERT_TRUE(caps.HasSupportedFrameDurations());
325   ASSERT_EQ(codec_spec_caps::kLeAudioCodecFrameDur7500us |
326                     codec_spec_caps::kLeAudioCodecFrameDur10000us |
327                     codec_spec_caps::kLeAudioCodecFrameDurPrefer10000us,
328             caps.supported_frame_durations.value());
329   // Check config values against the capabilities
330   ASSERT_TRUE(caps.IsFrameDurationConfigSupported(codec_spec_conf::kLeAudioCodecFrameDur7500us));
331   ASSERT_TRUE(caps.IsFrameDurationConfigSupported(codec_spec_conf::kLeAudioCodecFrameDur10000us));
332 
333   // SupportedAudioChannelCounts = 0b1 | 0b2 (one and two channels)
334   ASSERT_TRUE(caps.HasSupportedAudioChannelCounts());
335   ASSERT_EQ(codec_spec_caps::kLeAudioCodecChannelCountSingleChannel |
336                     codec_spec_caps::kLeAudioCodecChannelCountTwoChannel,
337             caps.supported_audio_channel_counts.value());
338   // Check config values against the capabilities
339   ASSERT_TRUE(caps.IsAudioChannelCountsSupported(1));
340   ASSERT_TRUE(caps.IsAudioChannelCountsSupported(2));
341   for (uint8_t i = 3; i < 8; ++i) {
342     ASSERT_FALSE(caps.IsAudioChannelCountsSupported(i));
343   }
344 
345   // SupportedOctetsPerCodecFrame = min:40, max:80
346   ASSERT_TRUE(caps.HasSupportedOctetsPerCodecFrame());
347   ASSERT_EQ(codec_spec_caps::kLeAudioCodecFrameLen40,
348             caps.supported_min_octets_per_codec_frame.value());
349   ASSERT_EQ(codec_spec_caps::kLeAudioCodecFrameLen80,
350             caps.supported_max_octets_per_codec_frame.value());
351   // Check config values against the capabilities
352   ASSERT_FALSE(caps.IsOctetsPerCodecFrameConfigSupported(codec_spec_conf::kLeAudioCodecFrameLen30));
353   ASSERT_TRUE(caps.IsOctetsPerCodecFrameConfigSupported(codec_spec_conf::kLeAudioCodecFrameLen40));
354   // Supported since: 40(min) < 60 < 80(max)
355   ASSERT_TRUE(caps.IsOctetsPerCodecFrameConfigSupported(codec_spec_conf::kLeAudioCodecFrameLen60));
356   ASSERT_TRUE(caps.IsOctetsPerCodecFrameConfigSupported(codec_spec_conf::kLeAudioCodecFrameLen80));
357   ASSERT_FALSE(
358           caps.IsOctetsPerCodecFrameConfigSupported(codec_spec_conf::kLeAudioCodecFrameLen120));
359 
360   // SupportedMaxCodecFramesPerSdu = 2
361   ASSERT_TRUE(caps.HasSupportedMaxCodecFramesPerSdu());
362   ASSERT_EQ(2, caps.supported_max_codec_frames_per_sdu.value());
363   // Check config values against the capabilities: {1,2} <= 2(max)
364   ASSERT_TRUE(caps.IsCodecFramesPerSduSupported(1));
365   ASSERT_TRUE(caps.IsCodecFramesPerSduSupported(2));
366   ASSERT_FALSE(caps.IsCodecFramesPerSduSupported(3));
367 }
368 
TEST(LeAudioLtvMapTest,test_metadata_use_guard1)369 TEST(LeAudioLtvMapTest, test_metadata_use_guard1) {
370   auto default_context = (uint16_t)bluetooth::le_audio::types::LeAudioContextType::VOICEASSISTANTS;
371   static const std::vector<uint8_t> default_metadata = {
372           bluetooth::le_audio::types::kLeAudioMetadataStreamingAudioContextLen + 1,
373           bluetooth::le_audio::types::kLeAudioMetadataTypeStreamingAudioContext,
374           (uint8_t)(default_context & 0x00FF), (uint8_t)((default_context & 0xFF00) >> 8)};
375 
376   // Parse
377   bool success = true;
378   LeAudioLtvMap ltv_map =
379           LeAudioLtvMap::Parse(default_metadata.data(), default_metadata.size(), success);
380   ASSERT_TRUE(success);
381 
382   // Verify the codec capabilities values
383   auto metadata = ltv_map.GetAsLeAudioMetadata();
384 
385   // Should fail when trying to reinterpret the LTV as configuration
386   EXPECT_DEATH(ltv_map.GetAsCoreCodecConfig(), "");
387 }
388 
TEST(LeAudioLtvMapTest,test_metadata_use_guard2)389 TEST(LeAudioLtvMapTest, test_metadata_use_guard2) {
390   auto default_context = (uint16_t)bluetooth::le_audio::types::LeAudioContextType::VOICEASSISTANTS;
391   static const std::vector<uint8_t> default_metadata = {
392           bluetooth::le_audio::types::kLeAudioMetadataStreamingAudioContextLen + 1,
393           bluetooth::le_audio::types::kLeAudioMetadataTypeStreamingAudioContext,
394           (uint8_t)(default_context & 0x00FF), (uint8_t)((default_context & 0xFF00) >> 8)};
395 
396   // Parse
397   bool success = true;
398   LeAudioLtvMap ltv_map =
399           LeAudioLtvMap::Parse(default_metadata.data(), default_metadata.size(), success);
400   ASSERT_TRUE(success);
401 
402   // Verify the codec capabilities values
403   auto metadata = ltv_map.GetAsLeAudioMetadata();
404 
405   // Should fail when trying to reinterpret the LTV as configuration
406   EXPECT_DEATH(ltv_map.GetAsCoreCodecCapabilities(), "");
407 }
408 
PrepareMetadataLtv()409 static auto PrepareMetadataLtv() {
410   ::bluetooth::le_audio::types::LeAudioLtvMap metadata_ltvs;
411   // Prepare the metadata LTVs
412   metadata_ltvs
413           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypePreferredAudioContext,
414                (uint16_t)10)
415           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeStreamingAudioContext, (uint16_t)8)
416           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeProgramInfo,
417                std::string{"ProgramInfo"})
418           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeLanguage, std::string{"ice"})
419           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList,
420                std::vector<uint8_t>{1, 2, 3})
421           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeparentalRating, (uint8_t)0x01)
422           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeProgramInfoUri,
423                std::string{"ProgramInfoUri"})
424           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeAudioActiveState, false)
425           .Add(::bluetooth::le_audio::types::
426                        kLeAudioMetadataTypeBroadcastAudioImmediateRenderingFlag,
427                true)
428           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeExtendedMetadata,
429                std::vector<uint8_t>{1, 2, 3})
430           .Add(::bluetooth::le_audio::types::kLeAudioMetadataTypeVendorSpecific,
431                std::vector<uint8_t>{1, 2, 3});
432   return metadata_ltvs;
433 }
434 
TEST(LeAudioLtvMapTest,test_metadata_valid)435 TEST(LeAudioLtvMapTest, test_metadata_valid) {
436   // Prepare the reference LTV
437   auto metadata_ltv = PrepareMetadataLtv();
438   auto raw_metadata = metadata_ltv.RawPacket();
439 
440   // Check the Parsing
441   bool success = true;
442   LeAudioLtvMap parsed_ltv_map =
443           LeAudioLtvMap::Parse(raw_metadata.data(), raw_metadata.size(), success);
444   ASSERT_TRUE(success);
445 
446   // Verify the values
447   auto metadata = metadata_ltv.GetAsLeAudioMetadata();
448   auto parsed_metadata = parsed_ltv_map.GetAsLeAudioMetadata();
449   ASSERT_EQ(parsed_metadata.preferred_audio_context.value(),
450             metadata.preferred_audio_context.value());
451   ASSERT_EQ(parsed_metadata.program_info.value(), metadata.program_info.value());
452   ASSERT_TRUE(parsed_metadata.language.has_value());
453   ASSERT_TRUE(metadata.language.has_value());
454   ASSERT_EQ(parsed_metadata.language.value(), metadata.language.value());
455   ASSERT_EQ(parsed_metadata.ccid_list.value(), metadata.ccid_list.value());
456   ASSERT_EQ(parsed_metadata.parental_rating.value(), metadata.parental_rating.value());
457   ASSERT_EQ(parsed_metadata.program_info_uri.value(), metadata.program_info_uri.value());
458   ASSERT_EQ(parsed_metadata.audio_active_state.value(), metadata.audio_active_state.value());
459   ASSERT_EQ(parsed_metadata.broadcast_audio_immediate_rendering.value(),
460             metadata.broadcast_audio_immediate_rendering.value());
461   ASSERT_EQ(parsed_metadata.extended_metadata.value(), metadata.extended_metadata.value());
462   ASSERT_EQ(parsed_metadata.vendor_specific.value(), metadata.vendor_specific.value());
463 }
464 
TEST(LeAudioLtvMapTest,test_adding_types)465 TEST(LeAudioLtvMapTest, test_adding_types) {
466   LeAudioLtvMap ltv_map;
467   ltv_map.Add(1, (uint8_t)127);
468   ltv_map.Add(2, (uint16_t)32767);
469   ltv_map.Add(3, (uint32_t)65535);
470   ltv_map.Add(4, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
471   ltv_map.Add(5, std::string("sample text"));
472   ltv_map.Add(6, true);
473 
474   ASSERT_EQ(6lu, ltv_map.Size());
475 
476   uint8_t u8;
477   auto pp = ltv_map.At(1).data();
478   STREAM_TO_UINT8(u8, pp);
479   ASSERT_EQ((uint8_t)127, u8);
480 
481   uint16_t u16;
482   pp = ltv_map.At(2).data();
483   STREAM_TO_UINT16(u16, pp);
484   ASSERT_EQ((uint16_t)32767, u16);
485 
486   uint32_t u32;
487   pp = ltv_map.At(3).data();
488   STREAM_TO_UINT32(u32, pp);
489   ASSERT_EQ((uint32_t)65535, u32);
490 
491   ASSERT_EQ((std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9}), ltv_map.At(4));
492 
493   ASSERT_EQ(std::string("sample text"), std::string(ltv_map.At(5).begin(), ltv_map.At(5).end()));
494 
495   ASSERT_EQ(true, (bool)ltv_map.At(6).data()[0]);
496 }
497 
TEST(LeAudioLtvMapTest,test_hash_sanity)498 TEST(LeAudioLtvMapTest, test_hash_sanity) {
499   LeAudioLtvMap ltv_map;
500   ASSERT_EQ(ltv_map.GetHash(), 0lu);
501 
502   auto hash = ltv_map.GetHash();
503   ltv_map.Add(0, (uint8_t)127);
504   ltv_map.Add(1, (uint16_t)32767);
505   ltv_map.Add(2, (uint32_t)65535);
506   ltv_map.Add(3, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
507 
508   ASSERT_NE(ltv_map.GetHash(), 0lu);
509   ASSERT_NE(ltv_map.GetHash(), hash);
510   ASSERT_EQ(ltv_map, ltv_map);
511 
512   // Compare hashes of equal LTV maps, filled in a different order
513   LeAudioLtvMap ltv_map_two;
514   ltv_map_two.Add(3, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
515   ltv_map_two.Add(0, (uint8_t)127);
516   ltv_map_two.Add(2, (uint32_t)65535);
517   ltv_map_two.Add(1, (uint16_t)32767);
518   ASSERT_EQ(ltv_map, ltv_map_two);
519 }
520 
TEST(LeAudioLtvMapTest,test_value_hash_sanity)521 TEST(LeAudioLtvMapTest, test_value_hash_sanity) {
522   LeAudioLtvMap ltv_map;
523 
524   ltv_map.Add(1, (uint16_t)32767);
525   auto hash = ltv_map.GetHash();
526 
527   // Same value but type size is different
528   hash = ltv_map.GetHash();
529   ltv_map.Add(1, (uint32_t)32767);
530   ASSERT_NE(ltv_map.GetHash(), hash);
531 }
532 
TEST(LeAudioLtvMapTest,test_type_change_same_value)533 TEST(LeAudioLtvMapTest, test_type_change_same_value) {
534   LeAudioLtvMap ltv_map_one;
535   ltv_map_one.Add(1, (uint16_t)32767);
536 
537   LeAudioLtvMap ltv_map_two;
538   // The same value but different type
539   ltv_map_two.Add(3, (uint16_t)32767);
540 
541   ASSERT_NE(ltv_map_one.GetHash(), ltv_map_two.GetHash());
542 }
543 
TEST(LeAudioLtvMapTest,test_add_changing_hash)544 TEST(LeAudioLtvMapTest, test_add_changing_hash) {
545   LeAudioLtvMap ltv_map;
546 
547   auto hash = ltv_map.GetHash();
548   ltv_map.Add(0, (uint8_t)127);
549   ASSERT_NE(ltv_map.GetHash(), hash);
550 
551   hash = ltv_map.GetHash();
552   ltv_map.Add(1, (uint16_t)32767);
553   ASSERT_NE(ltv_map.GetHash(), hash);
554 
555   hash = ltv_map.GetHash();
556   ltv_map.Add(2, (uint32_t)65535);
557   ASSERT_NE(ltv_map.GetHash(), hash);
558 
559   hash = ltv_map.GetHash();
560   ltv_map.Add(3, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
561   ASSERT_NE(ltv_map.GetHash(), hash);
562 }
563 
TEST(LeAudioLtvMapTest,test_update_changing_hash)564 TEST(LeAudioLtvMapTest, test_update_changing_hash) {
565   LeAudioLtvMap ltv_map;
566 
567   auto hash = ltv_map.GetHash();
568   ltv_map.Add(0, (uint8_t)127);
569   ASSERT_NE(ltv_map.GetHash(), hash);
570 
571   hash = ltv_map.GetHash();
572   ltv_map.Add(0, (uint16_t)32767);
573   ASSERT_NE(ltv_map.GetHash(), hash);
574 
575   hash = ltv_map.GetHash();
576   ltv_map.Add(0, (uint32_t)65535);
577   ASSERT_NE(ltv_map.GetHash(), hash);
578 
579   hash = ltv_map.GetHash();
580   ltv_map.Add(0, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
581   ASSERT_NE(ltv_map.GetHash(), hash);
582 }
583 
TEST(LeAudioLtvMapTest,test_update_same_not_changing_hash)584 TEST(LeAudioLtvMapTest, test_update_same_not_changing_hash) {
585   LeAudioLtvMap ltv_map;
586 
587   auto hash = ltv_map.GetHash();
588   ltv_map.Add(0, (uint8_t)127);
589   ASSERT_NE(ltv_map.GetHash(), hash);
590 
591   hash = ltv_map.GetHash();
592   ltv_map.Add(0, (uint8_t)127);
593   ASSERT_EQ(ltv_map.GetHash(), hash);
594 }
595 
TEST(LeAudioLtvMapTest,test_remove_changing_hash)596 TEST(LeAudioLtvMapTest, test_remove_changing_hash) {
597   LeAudioLtvMap ltv_map;
598 
599   auto hash = ltv_map.GetHash();
600   ltv_map.Add(0, (uint8_t)127);
601   ltv_map.Add(1, (uint16_t)32767);
602   ltv_map.Add(2, (uint32_t)65535);
603   ltv_map.Add(3, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
604 
605   hash = ltv_map.GetHash();
606   ltv_map.Remove(0);
607   ASSERT_NE(ltv_map.GetHash(), hash);
608 
609   hash = ltv_map.GetHash();
610   ltv_map.Remove(1);
611   ASSERT_NE(ltv_map.GetHash(), hash);
612 
613   hash = ltv_map.GetHash();
614   ltv_map.Remove(2);
615   ASSERT_NE(ltv_map.GetHash(), hash);
616 
617   hash = ltv_map.GetHash();
618   ltv_map.Remove(3);
619   ASSERT_NE(ltv_map.GetHash(), hash);
620 }
621 
TEST(LeAudioLtvMapTest,test_clear_changing_hash)622 TEST(LeAudioLtvMapTest, test_clear_changing_hash) {
623   LeAudioLtvMap ltv_map;
624 
625   auto hash = ltv_map.GetHash();
626   ltv_map.Add(0, (uint8_t)127);
627   ltv_map.Add(1, (uint16_t)32767);
628   ltv_map.Add(2, (uint32_t)65535);
629   ltv_map.Add(3, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
630 
631   hash = ltv_map.GetHash();
632   ltv_map.Clear();
633   ASSERT_NE(ltv_map.GetHash(), hash);
634 
635   // 2nd clear should not change it
636   hash = ltv_map.GetHash();
637   ltv_map.Clear();
638   ASSERT_EQ(ltv_map.GetHash(), hash);
639 
640   // Check if empty maps have equal hash
641   LeAudioLtvMap empty_ltv_map;
642   ASSERT_EQ(empty_ltv_map, ltv_map);
643 }
644 
TEST(LeAudioLtvMapTest,test_remove_all_changing_hash)645 TEST(LeAudioLtvMapTest, test_remove_all_changing_hash) {
646   LeAudioLtvMap ltv_map;
647 
648   auto hash = ltv_map.GetHash();
649   ltv_map.Add(0, (uint8_t)127);
650   ltv_map.Add(1, (uint16_t)32767);
651   ltv_map.Add(2, (uint32_t)65535);
652   ltv_map.Add(3, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
653 
654   LeAudioLtvMap ltv_map_1st_half;
655   ltv_map_1st_half.Add(1, (uint16_t)32767);
656   ltv_map_1st_half.Add(3, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
657 
658   LeAudioLtvMap ltv_map_2nd_half;
659   ltv_map_2nd_half.Add(0, (uint8_t)127);
660   ltv_map_2nd_half.Add(2, (uint32_t)65535);
661 
662   ASSERT_NE(ltv_map_1st_half, ltv_map_2nd_half);
663   ASSERT_NE(ltv_map, ltv_map_2nd_half);
664 
665   hash = ltv_map.GetHash();
666   ltv_map.RemoveAllTypes(ltv_map_1st_half);
667   ASSERT_NE(hash, ltv_map.GetHash());
668 
669   hash = ltv_map.GetHash();
670   ltv_map.RemoveAllTypes(ltv_map_2nd_half);
671   ASSERT_NE(hash, ltv_map.GetHash());
672 
673   // Check if empty maps have equal hash
674   LeAudioLtvMap empty_ltv_map;
675   ASSERT_EQ(empty_ltv_map, ltv_map);
676 }
677 
TEST(LeAudioLtvMapTest,test_intersection)678 TEST(LeAudioLtvMapTest, test_intersection) {
679   LeAudioLtvMap ltv_map_one;
680   ltv_map_one.Add(1, (uint16_t)32767);
681   ltv_map_one.Add(3, std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
682   ltv_map_one.Add(2, (uint32_t)65535);
683 
684   LeAudioLtvMap ltv_map_two;
685   ltv_map_two.Add(0, (uint8_t)127);
686   // Not the type is the same but value differs
687   ltv_map_two.Add(1, (uint16_t)32766);
688   ltv_map_two.Add(2, (uint32_t)65535);
689 
690   LeAudioLtvMap ltv_map_common;
691   ltv_map_common.Add(2, (uint32_t)65535);
692   ASSERT_NE(ltv_map_common.GetHash(), 0lu);
693 
694   ASSERT_EQ(ltv_map_one.GetIntersection(ltv_map_two).GetHash(), ltv_map_common.GetHash());
695   ASSERT_EQ(ltv_map_two.GetIntersection(ltv_map_one), ltv_map_common);
696 }
697 
698 constexpr types::LeAudioCodecId kLeAudioCodecIdVendor1 = {
699         .coding_format = types::kLeAudioCodingFormatVendorSpecific,
700         // Not a particular vendor - just some random numbers
701         .vendor_company_id = 0xC0,
702         .vendor_codec_id = 0xDE,
703 };
704 
705 static const set_configurations::CodecConfigSetting vendor_16_2 = {
706         .id = kLeAudioCodecIdVendor1,
707         .params = types::LeAudioLtvMap({
708                 LTV_ENTRY_SAMPLING_FREQUENCY(codec_spec_conf::kLeAudioSamplingFreq16000Hz),
709                 LTV_ENTRY_FRAME_DURATION(codec_spec_conf::kLeAudioCodecFrameDur10000us),
710                 LTV_ENTRY_AUDIO_CHANNEL_ALLOCATION(codec_spec_conf::kLeAudioLocationStereo),
711                 LTV_ENTRY_OCTETS_PER_CODEC_FRAME(40),
712         }),
713         .vendor_params = {0x01, 0x02, 0x03, 0x04},
714         .channel_count_per_iso_stream = 1,
715 };
716 
TEST(CodecConfigSettingTest,test_vendor_codec_type)717 TEST(CodecConfigSettingTest, test_vendor_codec_type) {
718   auto vendor_codec = vendor_16_2;
719   ASSERT_EQ(vendor_16_2, vendor_codec);
720 }
721 
TEST(CodecSpecTest,test_sampling_frequency_transition)722 TEST(CodecSpecTest, test_sampling_frequency_transition) {
723   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
724                     codec_spec_caps::SamplingFreqConfig2Capability(
725                             codec_spec_conf::kLeAudioSamplingFreq8000Hz)),
726             codec_spec_conf::kLeAudioSamplingFreq8000Hz);
727   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
728                     codec_spec_caps::SamplingFreqConfig2Capability(
729                             codec_spec_conf::kLeAudioSamplingFreq11025Hz)),
730             codec_spec_conf::kLeAudioSamplingFreq11025Hz);
731   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
732                     codec_spec_caps::SamplingFreqConfig2Capability(
733                             codec_spec_conf::kLeAudioSamplingFreq16000Hz)),
734             codec_spec_conf::kLeAudioSamplingFreq16000Hz);
735   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
736                     codec_spec_caps::SamplingFreqConfig2Capability(
737                             codec_spec_conf::kLeAudioSamplingFreq22050Hz)),
738             codec_spec_conf::kLeAudioSamplingFreq22050Hz);
739   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
740                     codec_spec_caps::SamplingFreqConfig2Capability(
741                             codec_spec_conf::kLeAudioSamplingFreq24000Hz)),
742             codec_spec_conf::kLeAudioSamplingFreq24000Hz);
743   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
744                     codec_spec_caps::SamplingFreqConfig2Capability(
745                             codec_spec_conf::kLeAudioSamplingFreq32000Hz)),
746             codec_spec_conf::kLeAudioSamplingFreq32000Hz);
747   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
748                     codec_spec_caps::SamplingFreqConfig2Capability(
749                             codec_spec_conf::kLeAudioSamplingFreq44100Hz)),
750             codec_spec_conf::kLeAudioSamplingFreq44100Hz);
751   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
752                     codec_spec_caps::SamplingFreqConfig2Capability(
753                             codec_spec_conf::kLeAudioSamplingFreq48000Hz)),
754             codec_spec_conf::kLeAudioSamplingFreq48000Hz);
755   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
756                     codec_spec_caps::SamplingFreqConfig2Capability(
757                             codec_spec_conf::kLeAudioSamplingFreq88200Hz)),
758             codec_spec_conf::kLeAudioSamplingFreq88200Hz);
759   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
760                     codec_spec_caps::SamplingFreqConfig2Capability(
761                             codec_spec_conf::kLeAudioSamplingFreq96000Hz)),
762             codec_spec_conf::kLeAudioSamplingFreq96000Hz);
763   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
764                     codec_spec_caps::SamplingFreqConfig2Capability(
765                             codec_spec_conf::kLeAudioSamplingFreq176400Hz)),
766             codec_spec_conf::kLeAudioSamplingFreq176400Hz);
767   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
768                     codec_spec_caps::SamplingFreqConfig2Capability(
769                             codec_spec_conf::kLeAudioSamplingFreq192000Hz)),
770             codec_spec_conf::kLeAudioSamplingFreq192000Hz);
771   ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
772                     codec_spec_caps::SamplingFreqConfig2Capability(
773                             codec_spec_conf::kLeAudioSamplingFreq384000Hz)),
774             codec_spec_conf::kLeAudioSamplingFreq384000Hz);
775 }
776 
TEST(CodecSpecTest,test_frame_duration_transition)777 TEST(CodecSpecTest, test_frame_duration_transition) {
778   ASSERT_EQ(codec_spec_conf::SingleFrameDurationCapability2Config(
779                     codec_spec_caps::FrameDurationConfig2Capability(
780                             codec_spec_conf::kLeAudioCodecFrameDur7500us)),
781             codec_spec_conf::kLeAudioCodecFrameDur7500us);
782   ASSERT_EQ(codec_spec_conf::SingleFrameDurationCapability2Config(
783                     codec_spec_caps::FrameDurationConfig2Capability(
784                             codec_spec_conf::kLeAudioCodecFrameDur10000us)),
785             codec_spec_conf::kLeAudioCodecFrameDur10000us);
786 }
787 
TEST(CodecSpecTest,test_channel_count_transition)788 TEST(CodecSpecTest, test_channel_count_transition) {
789   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
790                     codec_spec_conf::SingleChannelCountCapability2Config(
791                             codec_spec_caps::kLeAudioCodecChannelCountNone)),
792             codec_spec_caps::kLeAudioCodecChannelCountNone);
793   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
794                     codec_spec_conf::SingleChannelCountCapability2Config(
795                             codec_spec_caps::kLeAudioCodecChannelCountSingleChannel)),
796             codec_spec_caps::kLeAudioCodecChannelCountSingleChannel);
797   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
798                     codec_spec_conf::SingleChannelCountCapability2Config(
799                             codec_spec_caps::kLeAudioCodecChannelCountTwoChannel)),
800             codec_spec_caps::kLeAudioCodecChannelCountTwoChannel);
801   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
802                     codec_spec_conf::SingleChannelCountCapability2Config(
803                             codec_spec_caps::kLeAudioCodecChannelCountThreeChannel)),
804             codec_spec_caps::kLeAudioCodecChannelCountThreeChannel);
805   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
806                     codec_spec_conf::SingleChannelCountCapability2Config(
807                             codec_spec_caps::kLeAudioCodecChannelCountFourChannel)),
808             codec_spec_caps::kLeAudioCodecChannelCountFourChannel);
809   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
810                     codec_spec_conf::SingleChannelCountCapability2Config(
811                             codec_spec_caps::kLeAudioCodecChannelCountFiveChannel)),
812             codec_spec_caps::kLeAudioCodecChannelCountFiveChannel);
813   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
814                     codec_spec_conf::SingleChannelCountCapability2Config(
815                             codec_spec_caps::kLeAudioCodecChannelCountSixChannel)),
816             codec_spec_caps::kLeAudioCodecChannelCountSixChannel);
817   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
818                     codec_spec_conf::SingleChannelCountCapability2Config(
819                             codec_spec_caps::kLeAudioCodecChannelCountSevenChannel)),
820             codec_spec_caps::kLeAudioCodecChannelCountSevenChannel);
821   ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
822                     codec_spec_conf::SingleChannelCountCapability2Config(
823                             codec_spec_caps::kLeAudioCodecChannelCountEightChannel)),
824             codec_spec_caps::kLeAudioCodecChannelCountEightChannel);
825 }
826 
TEST(CodecConfigTest,test_lc3_bits_per_sample)827 TEST(CodecConfigTest, test_lc3_bits_per_sample) {
828   set_configurations::CodecConfigSetting lc3_codec_config = {
829           .id = {.coding_format = types::kLeAudioCodingFormatLC3},
830   };
831   ASSERT_EQ(utils::translateToBtLeAudioCodecConfigBitPerSample(lc3_codec_config.GetBitsPerSample()),
832             LE_AUDIO_BITS_PER_SAMPLE_INDEX_16);
833 }
834 
TEST(CodecConfigTest,test_invalid_codec_bits_per_sample)835 TEST(CodecConfigTest, test_invalid_codec_bits_per_sample) {
836   set_configurations::CodecConfigSetting invalid_codec_config = {
837           .id = {.coding_format = types::kLeAudioCodingFormatVendorSpecific}};
838   ASSERT_EQ(utils::translateToBtLeAudioCodecConfigBitPerSample(
839                     invalid_codec_config.GetBitsPerSample()),
840             LE_AUDIO_BITS_PER_SAMPLE_INDEX_NONE);
841 }
842 
843 }  // namespace types
844 }  // namespace bluetooth::le_audio
845