1 /*
2 * Copyright 2021 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 "client_parser.h"
19
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include "le_audio_types.h"
24
25 namespace bluetooth::le_audio {
26 namespace client_parser {
27 namespace pacs {
28
TEST(LeAudioClientParserTest,testParsePacsInvalidLength)29 TEST(LeAudioClientParserTest, testParsePacsInvalidLength) {
30 std::vector<struct types::acs_ac_record> pac_recs;
31
32 const uint8_t invalid_num_records[] = {0x01};
33 ASSERT_FALSE(ParsePacs(pac_recs, sizeof(invalid_num_records), invalid_num_records));
34
35 const uint8_t no_caps_len[] = {
36 // Num records
37 0x01,
38 // Codec_ID
39 0x01,
40 0x02,
41 0x03,
42 0x04,
43 0x05,
44 };
45 ASSERT_FALSE(ParsePacs(pac_recs, sizeof(no_caps_len), no_caps_len));
46
47 const uint8_t no_metalen[] = {
48 // Num records
49 0x01,
50 // Codec_ID
51 0x01,
52 0x02,
53 0x03,
54 0x04,
55 0x05,
56 // Codec Spec. Caps. Len
57 0x00,
58 };
59 ASSERT_FALSE(ParsePacs(pac_recs, sizeof(no_metalen), no_metalen));
60 }
61
TEST(LeAudioClientParserTest,testParsePacsEmpty)62 TEST(LeAudioClientParserTest, testParsePacsEmpty) {
63 std::vector<struct types::acs_ac_record> pac_recs;
64 const uint8_t value[] = {0x00};
65
66 ASSERT_TRUE(ParsePacs(pac_recs, sizeof(value), value));
67 }
68
TEST(LeAudioClientParserTest,testParsePacsEmptyCapsEmptyMeta)69 TEST(LeAudioClientParserTest, testParsePacsEmptyCapsEmptyMeta) {
70 std::vector<struct types::acs_ac_record> pac_recs;
71
72 const uint8_t value[] = {
73 // Num records
74 0x01,
75 // Codec_ID
76 0x01,
77 0x03,
78 0x02,
79 0x05,
80 0x04,
81 // Codec Spec. Caps. Len
82 0x00,
83 // Metadata Length
84 0x00,
85 };
86 ASSERT_TRUE(ParsePacs(pac_recs, sizeof(value), value));
87
88 ASSERT_EQ(pac_recs.size(), 1u);
89 ASSERT_EQ(pac_recs[0].codec_id.coding_format, 0x01u);
90 ASSERT_EQ(pac_recs[0].codec_id.vendor_company_id, 0x0203u);
91 ASSERT_EQ(pac_recs[0].codec_id.vendor_codec_id, 0x0405u);
92 }
93
TEST(LeAudioClientParserTest,testParsePacsInvalidCapsLen)94 TEST(LeAudioClientParserTest, testParsePacsInvalidCapsLen) {
95 std::vector<struct types::acs_ac_record> pac_recs;
96
97 const uint8_t bad_capslem[] = {
98 // Num records
99 0x01,
100 // Codec_ID
101 0x01,
102 0x03,
103 0x02,
104 0x05,
105 0x04,
106 // Codec Spec. Caps. Len
107 0x05,
108 // Codec Spec. Caps.
109 0x02, // [0].length,
110 0x02, // [0].type,
111 0x03, // [0].value[0]
112 0x03, // [1].length
113 0x03, // [1].type
114 0x04, // [1].value[0]
115 0x05, // [1].value[1]
116 // Metadata Length
117 0x00,
118 };
119 ASSERT_FALSE(ParsePacs(pac_recs, sizeof(bad_capslem), bad_capslem));
120
121 std::vector<struct types::acs_ac_record> pac_recs2;
122
123 const uint8_t bad_capslen2[] = {
124 // Num records
125 0x01,
126 // Codec_ID
127 0x01,
128 0x03,
129 0x02,
130 0x05,
131 0x04,
132 // Codec Spec. Caps. Len
133 0x20,
134 // Codec Spec. Caps.
135 0x02, // [0].length
136 0x02, // [0].type
137 0x03, // [0].value[0]
138 0x03, // [1].length
139 0x03, // [1].type
140 0x04, // [1].value[0]
141 0x05, // [1].value[1]
142 // Metadata Length
143 0x00,
144 };
145 ASSERT_FALSE(ParsePacs(pac_recs2, sizeof(bad_capslen2), bad_capslen2));
146 }
147
TEST(LeAudioClientParserTest,testParsePacsInvalidCapsLtvLen)148 TEST(LeAudioClientParserTest, testParsePacsInvalidCapsLtvLen) {
149 std::vector<struct types::acs_ac_record> pac_recs;
150
151 const uint8_t bad_ltv_len[] = {
152 // Num records
153 0x01,
154 // Codec_ID
155 0x06,
156 0x00,
157 0x00,
158 0x00,
159 0x00,
160 // Codec Spec. Caps. Len
161 0x07,
162 // Codec Spec. Caps.
163 0x02, // [0].length
164 0x02, // [0].type
165 0x03, // [0].value[0]
166 0x06, // [1].bad_length
167 0x03, // [1].type
168 0x04, // [1].value[0]
169 0x05, // [1].value[1]
170 // Metadata Length
171 0x00,
172 };
173 ASSERT_FALSE(ParsePacs(pac_recs, sizeof(bad_ltv_len), bad_ltv_len));
174
175 const uint8_t bad_ltv_len2[] = {
176 // Num records
177 0x01,
178 // Codec_ID
179 0x06,
180 0x00,
181 0x00,
182 0x00,
183 0x00,
184 // Codec Spec. Caps. Len
185 0x07,
186 // Codec Spec. Caps.
187 0x02, // [0].length
188 0x02, // [0].type
189 0x03, // [0].value[0]
190 0x04, // [1].bad_length
191 0x03, // [1].type
192 0x04, // [1].value[0]
193 0x05, // [1].value[1]
194 // Metadata Length
195 0x00,
196 };
197 ASSERT_FALSE(ParsePacs(pac_recs, sizeof(bad_ltv_len2), bad_ltv_len2));
198 }
199
TEST(LeAudioClientParserTest,testParsePacsNullLtv)200 TEST(LeAudioClientParserTest, testParsePacsNullLtv) {
201 std::vector<struct types::acs_ac_record> pac_recs;
202
203 const uint8_t value[] = {
204 // Num records
205 0x01,
206 // Codec_ID
207 0x06,
208 0x00,
209 0x00,
210 0x00,
211 0x00,
212 // Codec Spec. Caps. Len
213 0x0A,
214 // Codec Spec. Caps.
215 0x02, // [0].length
216 0x02, // [0].type
217 0x03, // [0].value[0]
218 0x03, // [1].length
219 0x03, // [1].type
220 0x04, // [1].value[0]
221 0x05, // [1].value[1]
222 0x01, // [2].length <-- a capability without a value
223 0x04, // [2].type
224 0x00, // [3]length <-- this seems possible although useless
225 // Metadata Length
226 0x00,
227 };
228 ASSERT_TRUE(ParsePacs(pac_recs, sizeof(value), value));
229
230 ASSERT_EQ(pac_recs.size(), 1u);
231 ASSERT_EQ(pac_recs[0].codec_id.coding_format, 0x06u);
232 ASSERT_EQ(pac_recs[0].codec_id.vendor_company_id, 0x0000u);
233 ASSERT_EQ(pac_recs[0].codec_id.vendor_codec_id, 0x0000u);
234
235 auto codec_spec_caps = pac_recs[0].codec_spec_caps.Values();
236 ASSERT_EQ(codec_spec_caps.size(), 3u);
237 ASSERT_EQ(codec_spec_caps.count(0x02u), 1u);
238 ASSERT_EQ(codec_spec_caps[0x02u].size(), 1u);
239 ASSERT_EQ(codec_spec_caps[0x02u][0], 0x03u);
240 ASSERT_EQ(codec_spec_caps.count(0x03u), 1u);
241 ASSERT_EQ(codec_spec_caps[0x03u].size(), 2u);
242 ASSERT_EQ(codec_spec_caps[0x03u][0], 0x04u);
243 ASSERT_EQ(codec_spec_caps[0x03u][1], 0x05u);
244 ASSERT_EQ(codec_spec_caps.count(0x04u), 1u);
245 ASSERT_EQ(codec_spec_caps[0x04u].size(), 0u);
246
247 // Validate the raw data from ltv matches the original pac record data buffer
248 // Add one redundant ltv length of 0, just like in the value[] above.
249 auto ltv_raw = pac_recs[0].codec_spec_caps.RawPacket();
250 ltv_raw.push_back(0x00);
251 ASSERT_EQ(ltv_raw, pac_recs[0].codec_spec_caps_raw);
252 }
253
TEST(LeAudioClientParserTest,testParsePacsEmptyMeta)254 TEST(LeAudioClientParserTest, testParsePacsEmptyMeta) {
255 std::vector<struct types::acs_ac_record> pac_recs;
256
257 const uint8_t value[] = {
258 // Num records
259 0x01,
260 // Codec_ID
261 0x06,
262 0x00,
263 0x00,
264 0x00,
265 0x00,
266 // Codec Spec. Caps. Len
267 0x07,
268 // Codec Spec. Caps.
269 0x02, // [0].length
270 0x02, // [0].type
271 0x03, // [0].value[0]
272 0x03, // [1].length
273 0x03, // [1].type
274 0x04, // [1].value[0]
275 0x05, // [1].value[1]
276 // Metadata Length
277 0x00,
278 };
279 ASSERT_TRUE(ParsePacs(pac_recs, sizeof(value), value));
280
281 ASSERT_EQ(pac_recs.size(), 1u);
282 ASSERT_EQ(pac_recs[0].codec_id.coding_format, 0x06u);
283 ASSERT_EQ(pac_recs[0].codec_id.vendor_company_id, 0x0000u);
284 ASSERT_EQ(pac_recs[0].codec_id.vendor_codec_id, 0x0000u);
285
286 auto codec_spec_caps = pac_recs[0].codec_spec_caps.Values();
287 ASSERT_EQ(codec_spec_caps.size(), 2u);
288 ASSERT_EQ(codec_spec_caps.count(0x02u), 1u);
289 ASSERT_EQ(codec_spec_caps[0x02u].size(), 1u);
290 ASSERT_EQ(codec_spec_caps[0x02u][0], 0x03u);
291 ASSERT_EQ(codec_spec_caps.count(0x03u), 1u);
292 ASSERT_EQ(codec_spec_caps[0x03u].size(), 2u);
293 ASSERT_EQ(codec_spec_caps[0x03u][0], 0x04u);
294 ASSERT_EQ(codec_spec_caps[0x03u][1], 0x05u);
295
296 // Validate the raw data from ltv matches the original pac record data buffer
297 ASSERT_EQ(pac_recs[0].codec_spec_caps.RawPacket(), pac_recs[0].codec_spec_caps_raw);
298 }
299
TEST(LeAudioClientParserTest,testParsePacsInvalidMetaLength)300 TEST(LeAudioClientParserTest, testParsePacsInvalidMetaLength) {
301 std::vector<struct types::acs_ac_record> pac_recs;
302
303 const uint8_t value[] = {
304 // Num records
305 0x01,
306 // Codec_ID
307 0x01, 0x03, 0x02, 0x05, 0x04,
308 // Codec Spec. Caps. Len
309 0x07,
310 // Codec Spec. Caps.
311 0x02, // [0].length
312 0x02, // [0].type
313 0x03, // [0].value[0]
314 0x03, // [1].length
315 0x03, // [1].type
316 0x04, // [1].value[0]
317 0x05, // [1].value[1]
318 // Metadata Length
319 0x05,
320 // Metadata
321 0x03, // [0].length
322 0x02, // [0].type
323 0x01, // [0].value[0]
324 0x00, // [0].value[1]
325 };
326 ASSERT_FALSE(ParsePacs(pac_recs, sizeof(value), value));
327 }
328
TEST(LeAudioClientParserTest,testParsePacsValidMeta)329 TEST(LeAudioClientParserTest, testParsePacsValidMeta) {
330 std::vector<struct types::acs_ac_record> pac_recs;
331
332 const uint8_t value[] = {
333 // Num records
334 0x01,
335 // Codec_ID
336 0x06, 0x00, 0x00, 0x00, 0x00,
337 // Codec Spec. Caps. Len
338 0x07,
339 // Codec Spec. Caps.
340 0x02, // [0].length
341 0x02, // [0].type
342 0x03, // [0].value[0]
343 0x03, // [1].length
344 0x03, // [1].type
345 0x04, // [1].value[0]
346 0x05, // [1].value[1]
347 // Metadata Length
348 0x04,
349 // Metadata
350 0x03, // [0].length
351 0x02, // [0].type
352 0x01, // [0].value[0]
353 0x00, // [0].value[1]
354 };
355 ASSERT_TRUE(ParsePacs(pac_recs, sizeof(value), value));
356
357 ASSERT_EQ(pac_recs.size(), 1u);
358 ASSERT_EQ(pac_recs[0].codec_id.coding_format, 0x06u);
359 ASSERT_EQ(pac_recs[0].codec_id.vendor_company_id, 0x0000u);
360 ASSERT_EQ(pac_recs[0].codec_id.vendor_codec_id, 0x0000u);
361
362 auto codec_spec_caps = pac_recs[0].codec_spec_caps.Values();
363 ASSERT_EQ(codec_spec_caps.size(), 2u);
364 ASSERT_EQ(codec_spec_caps.count(0x02u), 1u);
365 ASSERT_EQ(codec_spec_caps[0x02u].size(), 1u);
366 ASSERT_EQ(codec_spec_caps[0x02u][0], 0x03u);
367 ASSERT_EQ(codec_spec_caps.count(0x03u), 1u);
368 ASSERT_EQ(codec_spec_caps[0x03u].size(), 2u);
369 ASSERT_EQ(codec_spec_caps[0x03u][0], 0x04u);
370 ASSERT_EQ(codec_spec_caps[0x03u][1], 0x05u);
371
372 ASSERT_EQ(pac_recs[0].metadata.size(), 4u);
373 ASSERT_EQ(pac_recs[0].metadata[0], 0x03u);
374 ASSERT_EQ(pac_recs[0].metadata[1], 0x02u);
375 ASSERT_EQ(pac_recs[0].metadata[2], 0x01u);
376 ASSERT_EQ(pac_recs[0].metadata[3], 0x00u);
377
378 // Validate the raw data from ltv matches the original pac record data buffer
379 ASSERT_EQ(pac_recs[0].codec_spec_caps.RawPacket(), pac_recs[0].codec_spec_caps_raw);
380 }
381
TEST(LeAudioClientParserTest,testParsePacsInvalidNumRecords)382 TEST(LeAudioClientParserTest, testParsePacsInvalidNumRecords) {
383 std::vector<struct types::acs_ac_record> pac_recs;
384
385 const uint8_t value[] = {
386 // Num records
387 0x02,
388 // Codec_ID
389 0x01, 0x03, 0x02, 0x05, 0x04,
390 // Codec Spec. Caps. Len
391 0x07,
392 // Codec Spec. Caps.
393 0x02, // [0].length
394 0x02, // [0].type
395 0x03, // [0].value[0]
396 0x03, // [1].length
397 0x03, // [1].type
398 0x04, // [1].value[0]
399 0x05, // [1].value[1]
400 // Metadata Length
401 0x04,
402 // Metadata
403 0x03, // [0].length
404 0x02, // [0].type
405 0x01, // [0].value[0]
406 0x00, // [0].value[1]
407 };
408 ASSERT_FALSE(ParsePacs(pac_recs, sizeof(value), value));
409 }
410
TEST(LeAudioClientParserTest,testParsePacsMultipleRecords)411 TEST(LeAudioClientParserTest, testParsePacsMultipleRecords) {
412 std::vector<struct types::acs_ac_record> pac_recs;
413
414 const uint8_t value[] = {
415 // Num records
416 0x03,
417 // Codec_ID
418 0x01, 0x03, 0x02, 0x05, 0x04,
419 // Codec Spec. Caps. Len
420 0x00,
421 // Metadata Length
422 0x00,
423 // Codec_ID
424 0x06, 0x00, 0x00, 0x00, 0x00,
425 // Codec Spec. Caps. Len
426 0x03,
427 // Codec Spec. Caps.
428 0x02, // [0].length
429 0x02, // [0].type
430 0x03, // [0].value[0]
431 // Metadata Length
432 0x04,
433 // Metadata
434 0x03, // [0].length
435 0x02, // [0].type
436 0x01, // [0].value[0]
437 0x00, // [0].value[1],
438 // Codec_ID
439 0x11, 0x13, 0x12, 0x15, 0x14,
440 // Codec Spec. Caps. Len
441 0x07,
442 // Codec Spec. Caps.
443 0x02, // [0].length
444 0x12, // [0].type
445 0x13, // [0].value[0]
446 0x03, // [1].length
447 0x13, // [1].type
448 0x14, // [1].value[0]
449 0x15, // [1].value[1]
450 // Metadata Length
451 0x04,
452 // Metadata
453 0x03, // [0].length
454 0x12, // [0].type
455 0x11, // [0].value[0]
456 0x10, // [0].value[1]
457 };
458 ASSERT_TRUE(ParsePacs(pac_recs, sizeof(value), value));
459 ASSERT_EQ(pac_recs.size(), 3u);
460
461 // Verify 1st record
462 auto& record0 = pac_recs[0];
463
464 ASSERT_EQ(record0.codec_id.coding_format, 0x01u);
465 ASSERT_EQ(record0.codec_id.vendor_company_id, 0x0203u);
466 ASSERT_EQ(record0.codec_id.vendor_codec_id, 0x0405u);
467 ASSERT_EQ(record0.codec_spec_caps_raw.size(), 0u);
468 ASSERT_EQ(record0.metadata.size(), 0u);
469
470 // Verify 2nd record
471 auto& record1 = pac_recs[1];
472
473 ASSERT_EQ(record1.codec_id.coding_format, 0x06u);
474 ASSERT_EQ(record1.codec_id.vendor_company_id, 0x0000u);
475 ASSERT_EQ(record1.codec_id.vendor_codec_id, 0x0000u);
476
477 auto codec_spec_caps1 = record1.codec_spec_caps.Values();
478 ASSERT_EQ(codec_spec_caps1.size(), 1u);
479 ASSERT_EQ(codec_spec_caps1.count(0x02u), 1u);
480 ASSERT_EQ(codec_spec_caps1[0x02u].size(), 1u);
481 ASSERT_EQ(codec_spec_caps1[0x02u][0], 0x03u);
482
483 ASSERT_EQ(record1.metadata.size(), 4u);
484 ASSERT_EQ(record1.metadata[0], 0x03u);
485 ASSERT_EQ(record1.metadata[1], 0x02u);
486 ASSERT_EQ(record1.metadata[2], 0x01u);
487 ASSERT_EQ(record1.metadata[3], 0x00u);
488
489 // Validate the raw data from ltv matches the original pac record data buffer
490 ASSERT_EQ(record1.codec_spec_caps.RawPacket(), record1.codec_spec_caps_raw);
491
492 // Verify 3rd record
493 auto& record2 = pac_recs[2];
494
495 ASSERT_EQ(record2.codec_id.coding_format, 0x11u);
496 ASSERT_EQ(record2.codec_id.vendor_company_id, 0x1213u);
497 ASSERT_EQ(record2.codec_id.vendor_codec_id, 0x1415u);
498
499 // Codec is not known to use LTV format for codec specific parameters
500 ASSERT_EQ(record2.codec_spec_caps_raw.size(), 7u);
501 ASSERT_EQ(record2.codec_spec_caps.Size(), 0u);
502 ASSERT_EQ(0, memcmp(record2.codec_spec_caps_raw.data(), value + 28,
503 record2.codec_spec_caps_raw.size()));
504
505 ASSERT_EQ(record2.metadata.size(), 4u);
506 ASSERT_EQ(record2.metadata[0], 0x03u);
507 ASSERT_EQ(record2.metadata[1], 0x12u);
508 ASSERT_EQ(record2.metadata[2], 0x11u);
509 ASSERT_EQ(record2.metadata[3], 0x10u);
510 }
511
TEST(LeAudioClientParserTest,testParsePacsVendorCodecRecords)512 TEST(LeAudioClientParserTest, testParsePacsVendorCodecRecords) {
513 std::vector<struct types::acs_ac_record> pac_recs;
514
515 const uint8_t value[] = {
516 // Num records
517 0x01,
518 // Vendor Codec_ID
519 0x01,
520 0x03,
521 0x02,
522 0x05,
523 0x04,
524 // Codec Spec. Caps. Len
525 0x0A,
526 // Codec Spec. Caps. - proprietary format
527 0x01,
528 0x02,
529 0x03,
530 0x04,
531 0x05,
532 0x06,
533 0x07,
534 0x08,
535 0x09,
536 0x0A,
537 // Metadata Length
538 0x00,
539 };
540 ASSERT_TRUE(ParsePacs(pac_recs, sizeof(value), value));
541
542 ASSERT_EQ(pac_recs.size(), 1u);
543 ASSERT_EQ(pac_recs[0].codec_id.coding_format, 0x01u);
544 ASSERT_EQ(pac_recs[0].codec_id.vendor_company_id, 0x0203u);
545 ASSERT_EQ(pac_recs[0].codec_id.vendor_codec_id, 0x0405u);
546 ASSERT_TRUE(pac_recs[0].codec_spec_caps.IsEmpty());
547 ASSERT_EQ(0x0Au, pac_recs[0].codec_spec_caps_raw.size());
548 }
549
TEST(LeAudioClientParserTest,testParseAudioLocationsInvalidLength)550 TEST(LeAudioClientParserTest, testParseAudioLocationsInvalidLength) {
551 types::AudioLocations locations = codec_spec_conf::kLeAudioLocationMonoAudio;
552 const uint8_t value1[] = {
553 0x01,
554 0x02,
555 0x03,
556 };
557 ParseAudioLocations(locations, sizeof(value1), value1);
558 ASSERT_EQ(locations, 0u);
559
560 const uint8_t value2[] = {0x01, 0x02, 0x03, 0x04, 0x05};
561 ParseAudioLocations(locations, sizeof(value2), value2);
562 ASSERT_EQ(locations, 0u);
563 }
564
TEST(LeAudioClientParserTest,testParseAudioLocations)565 TEST(LeAudioClientParserTest, testParseAudioLocations) {
566 types::AudioLocations locations = codec_spec_conf::kLeAudioLocationMonoAudio;
567 const uint8_t value1[] = {0x01, 0x02, 0x03, 0x04};
568 ParseAudioLocations(locations, sizeof(value1), value1);
569 ASSERT_EQ(locations, 0x04030201u);
570 }
571
TEST(LeAudioClientParserTest,testParseAvailableAudioContextsInvalidLength)572 TEST(LeAudioClientParserTest, testParseAvailableAudioContextsInvalidLength) {
573 types::BidirectionalPair<types::AudioContexts> avail_contexts;
574 const uint8_t value1[] = {
575 // Sink available contexts
576 0x01, 0x02,
577 // Missing Source available contexts
578 };
579
580 ParseAvailableAudioContexts(avail_contexts, sizeof(value1), value1);
581 ASSERT_EQ(avail_contexts.sink.value(), 0u);
582 ASSERT_EQ(avail_contexts.source.value(), 0u);
583 }
584
TEST(LeAudioClientParserTest,testParseAvailableAudioContexts)585 TEST(LeAudioClientParserTest, testParseAvailableAudioContexts) {
586 types::BidirectionalPair<types::AudioContexts> avail_contexts;
587 const uint8_t value1[] = {
588 // Sink available contexts
589 0x01,
590 0x02,
591 // Source available contexts
592 0x03,
593 0x04,
594 };
595
596 ParseAvailableAudioContexts(avail_contexts, sizeof(value1), value1);
597 ASSERT_EQ(avail_contexts.sink.value(), 0x0201u);
598 ASSERT_EQ(avail_contexts.source.value(), 0x0403u);
599 }
600
TEST(LeAudioClientParserTest,testParseSupportedAudioContextsInvalidLength)601 TEST(LeAudioClientParserTest, testParseSupportedAudioContextsInvalidLength) {
602 types::BidirectionalPair<types::AudioContexts> supp_contexts;
603 const uint8_t value1[] = {
604 // Sink supported contexts
605 0x01, 0x02,
606 // Missing Source supported contexts
607 };
608
609 ParseSupportedAudioContexts(supp_contexts, sizeof(value1), value1);
610 ASSERT_EQ(supp_contexts.sink.value(), 0u);
611 ASSERT_EQ(supp_contexts.source.value(), 0u);
612 }
613
TEST(LeAudioClientParserTest,testParseSupportedAudioContexts)614 TEST(LeAudioClientParserTest, testParseSupportedAudioContexts) {
615 types::BidirectionalPair<types::AudioContexts> supp_contexts;
616 const uint8_t value1[] = {
617 // Sink supported contexts
618 0x01,
619 0x02,
620 // Source supported contexts
621 0x03,
622 0x04,
623 };
624
625 ParseSupportedAudioContexts(supp_contexts, sizeof(value1), value1);
626 ASSERT_EQ(supp_contexts.sink.value(), 0x0201u);
627 ASSERT_EQ(supp_contexts.source.value(), 0x0403u);
628 }
629
630 } // namespace pacs
631
632 namespace ascs {
633
TEST(LeAudioClientParserTest,testParseAseStatusHeaderInvalidLength)634 TEST(LeAudioClientParserTest, testParseAseStatusHeaderInvalidLength) {
635 ase_rsp_hdr arh;
636 const uint8_t value1[] = {
637 // Ase ID
638 0x01,
639 // ASE State is missing here
640 };
641 ASSERT_FALSE(ParseAseStatusHeader(arh, sizeof(value1), value1));
642 }
643
TEST(LeAudioClientParserTest,testParseAseStatusHeader)644 TEST(LeAudioClientParserTest, testParseAseStatusHeader) {
645 ase_rsp_hdr arh;
646 const uint8_t value1[] = {
647 // Ase ID
648 0x01,
649 // ASE State
650 0x00, // 'Idle' state
651 // No additional ASE Params for the 'Idle' state
652 };
653 ASSERT_TRUE(ParseAseStatusHeader(arh, sizeof(value1), value1));
654 ASSERT_EQ(arh.id, 0x01u);
655 ASSERT_EQ(arh.state, 0x00u);
656
657 const uint8_t value2[] = {
658 // Ase ID
659 0x02,
660 // ASE State
661 0x04, // 'Streaming' state
662 // Additional ASE Params for the 'Streaming' state
663 // Metadata Len
664 0x03,
665 // Metadata
666 0x03, // [0].length
667 0x02, // [0].type
668 0x01, // [0].value[0]
669 0x00, // [0].value[1]
670 };
671 ASSERT_TRUE(ParseAseStatusHeader(arh, sizeof(value2), value2));
672 ASSERT_EQ(arh.id, 0x02u);
673 ASSERT_EQ(arh.state, 0x04u);
674 // Currently additional state parameters are not handled
675 }
676
TEST(LeAudioClientParserTest,testParseAseStatusCodecConfiguredStateParamsInvalidLength)677 TEST(LeAudioClientParserTest, testParseAseStatusCodecConfiguredStateParamsInvalidLength) {
678 ase_codec_configured_state_params codec_configured_state_params;
679 const uint8_t value1[] = {
680 // Ase ID
681 0x02,
682 // ASE State
683 0x01, // 'Codec Configured' state
684 // Framing
685 0x01, // Unframed
686 // Peferred PHY
687 0x02, // 2M PHY
688 // Preferred retransimssion Num.
689 0x04,
690 // Max transport Latency
691 0x05, 0x00,
692 // Pressentation delay min.
693 0x00, 0x01, 0x02, 0x03,
694 // Pressentation delay max.
695 0x00, 0x01, 0x02, 0x03,
696 // Preferred presentation delay min.
697 0x01, 0x02, 0x03,
698 // Preferred presentation delay max.
699 0x01, 0x02, 0x03,
700 // Codec ID
701 0x01, 0x02, 0x03, 0x04, 0x05,
702 // Missing Codec spec. conf. length
703 };
704
705 ASSERT_FALSE(ParseAseStatusCodecConfiguredStateParams(codec_configured_state_params,
706 sizeof(value1) - 2, value1 + 2));
707 }
708
TEST(LeAudioClientParserTest,testParseAseStatusCodecConfiguredStateParams)709 TEST(LeAudioClientParserTest, testParseAseStatusCodecConfiguredStateParams) {
710 ase_codec_configured_state_params codec_configured_state_params;
711 const uint8_t value1[] = {
712 // Ase ID
713 0x01,
714 // ASE State
715 0x01, // 'Codec Configured' state
716 // Framing
717 0x01, // Unframed
718 // Peferred PHY
719 0x02, // 2M PHY
720 // Preferred retransimssion Num.
721 0x04,
722 // Max transport Latency
723 0x05,
724 0x00,
725 // Pressentation delay min.
726 0x00,
727 0x01,
728 0x02,
729 // Pressentation delay max.
730 0x10,
731 0x11,
732 0x12,
733 // Preferred presentation delay min.
734 0x01,
735 0x02,
736 0x03,
737 // Preferred presentation delay max.
738 0x09,
739 0x10,
740 0x11,
741 // Codec ID
742 0x01,
743 0x02,
744 0x03,
745 0x04,
746 0x05,
747 // Codec spec. conf. length
748 0x00,
749 };
750
751 // State additional parameters are right after the ASE ID and state bytes
752 ASSERT_TRUE(ParseAseStatusCodecConfiguredStateParams(codec_configured_state_params,
753 sizeof(value1) - 2, value1 + 2));
754 ASSERT_EQ(codec_configured_state_params.framing, 0x01u);
755 ASSERT_EQ(codec_configured_state_params.preferred_phy, 0x02u);
756 ASSERT_EQ(codec_configured_state_params.preferred_retrans_nb, 0x04u);
757 ASSERT_EQ(codec_configured_state_params.max_transport_latency, 0x0005u);
758 ASSERT_EQ(codec_configured_state_params.pres_delay_min, 0x020100u);
759 ASSERT_EQ(codec_configured_state_params.pres_delay_max, 0x121110u);
760 ASSERT_EQ(codec_configured_state_params.preferred_pres_delay_min, 0x030201u);
761 ASSERT_EQ(codec_configured_state_params.preferred_pres_delay_max, 0x111009u);
762 ASSERT_EQ(codec_configured_state_params.codec_id.coding_format, 0x01u);
763 ASSERT_EQ(codec_configured_state_params.codec_id.vendor_company_id, 0x0302u);
764 ASSERT_EQ(codec_configured_state_params.codec_id.vendor_codec_id, 0x0504u);
765 ASSERT_EQ(codec_configured_state_params.codec_spec_conf.size(), 0u);
766
767 const uint8_t value2[] = {
768 // Ase ID
769 0x02,
770 // ASE State
771 0x01, // 'Codec Configured' state
772 // Framing
773 0x01, // Unframed
774 // Peferred PHY
775 0x02, // 2M PHY
776 // Preferred retransimssion Num.
777 0x04,
778 // Max transport Latency
779 0x05,
780 0x00,
781 // Pressentation delay min.
782 0x00,
783 0x01,
784 0x02,
785 // Pressentation delay max.
786 0x10,
787 0x11,
788 0x12,
789 // Preferred presentation delay min.
790 0x01,
791 0x02,
792 0x03,
793 // Preferred presentation delay max.
794 0x09,
795 0x10,
796 0x11,
797 // Codec ID
798 0x01,
799 0x02,
800 0x03,
801 0x04,
802 0x05,
803 // Codec spec. conf. length
804 0x05,
805 // Codec spec. conf.
806 0x0A,
807 0x0B,
808 0x0C,
809 0x0D,
810 0x0E,
811 };
812
813 // State additional parameters are right after the ASE ID and state bytes
814 ASSERT_TRUE(ParseAseStatusCodecConfiguredStateParams(codec_configured_state_params,
815 sizeof(value2) - 2, value2 + 2));
816 ASSERT_EQ(codec_configured_state_params.framing, 0x01u);
817 ASSERT_EQ(codec_configured_state_params.preferred_phy, 0x02u);
818 ASSERT_EQ(codec_configured_state_params.preferred_retrans_nb, 0x04u);
819 ASSERT_EQ(codec_configured_state_params.max_transport_latency, 0x0005u);
820 ASSERT_EQ(codec_configured_state_params.pres_delay_min, 0x020100u);
821 ASSERT_EQ(codec_configured_state_params.pres_delay_max, 0x121110u);
822 ASSERT_EQ(codec_configured_state_params.preferred_pres_delay_min, 0x030201u);
823 ASSERT_EQ(codec_configured_state_params.preferred_pres_delay_max, 0x111009u);
824 ASSERT_EQ(codec_configured_state_params.codec_id.coding_format, 0x01u);
825 ASSERT_EQ(codec_configured_state_params.codec_id.vendor_company_id, 0x0302u);
826 ASSERT_EQ(codec_configured_state_params.codec_id.vendor_codec_id, 0x0504u);
827 ASSERT_EQ(codec_configured_state_params.codec_spec_conf.size(), 5u);
828 ASSERT_EQ(codec_configured_state_params.codec_spec_conf[0], 0x0Au);
829 ASSERT_EQ(codec_configured_state_params.codec_spec_conf[1], 0x0Bu);
830 ASSERT_EQ(codec_configured_state_params.codec_spec_conf[2], 0x0Cu);
831 ASSERT_EQ(codec_configured_state_params.codec_spec_conf[3], 0x0Du);
832 ASSERT_EQ(codec_configured_state_params.codec_spec_conf[4], 0x0Eu);
833 }
834
TEST(LeAudioClientParserTest,testParseAseStatusQosConfiguredStateParamsInvalidLength)835 TEST(LeAudioClientParserTest, testParseAseStatusQosConfiguredStateParamsInvalidLength) {
836 struct ase_qos_configured_state_params rsp {
837 .cig_id = 0, .cis_id = 0
838 };
839 const uint8_t value1[] = {
840 // Ase ID
841 0x01,
842 // ASE State
843 0x02, // 'QoS Configured' state
844 0x03, // CIG_ID
845 0x04, // CIS_ID
846 };
847
848 ParseAseStatusQosConfiguredStateParams(rsp, sizeof(value1) - 2, value1 + 2);
849 ASSERT_EQ(rsp.cig_id, 0);
850 ASSERT_EQ(rsp.cis_id, 0);
851
852 const uint8_t value2[] = {
853 // Ase ID
854 0x01,
855 // ASE State
856 0x02, // 'QoS Configured' state
857 // CIG_ID
858 0x03,
859 // CIS_ID
860 0x04,
861 // SDU Interval
862 0x05, 0x06, 0x07,
863 // Framing
864 0x01,
865 // PHY
866 0x02,
867 // Max SDU
868 0x08, 0x09,
869 // Retransmission Num.
870 0x0A,
871 // Max Transport Latency
872 0x0B, 0x0C,
873 // Presentation Delay
874 0x0D, 0x0E,
875 // Missing Byte
876 };
877
878 ParseAseStatusQosConfiguredStateParams(rsp, sizeof(value2) - 2, value2 + 2);
879 ASSERT_EQ(rsp.cig_id, 0);
880 ASSERT_EQ(rsp.cis_id, 0);
881 }
882
TEST(LeAudioClientParserTest,testParseAseStatusQosConfiguredStateParams)883 TEST(LeAudioClientParserTest, testParseAseStatusQosConfiguredStateParams) {
884 struct ase_qos_configured_state_params rsp;
885 const uint8_t value[] = {
886 // Ase ID
887 0x01,
888 // ASE State - 'QoS Configured'
889 0x02,
890 // CIG_ID
891 0x03,
892 // CIS_ID
893 0x04,
894 // SDU Interval
895 0x05,
896 0x06,
897 0x07,
898 // Framing
899 0x01,
900 // PHY
901 0x02,
902 // Max SDU
903 0x18,
904 0x19,
905 // Retransmission Num.
906 0x1A,
907 // Max Transport Latency
908 0x1B,
909 0x1C,
910 // Presentation Delay
911 0x1D,
912 0x1E,
913 0x1F,
914 };
915
916 ParseAseStatusQosConfiguredStateParams(rsp, sizeof(value) - 2, value + 2);
917 ASSERT_EQ(rsp.cig_id, 0x03u);
918 ASSERT_EQ(rsp.cis_id, 0x04u);
919 ASSERT_EQ(rsp.sdu_interval, 0x070605u);
920 ASSERT_EQ(rsp.framing, 0x01u);
921 ASSERT_EQ(rsp.phy, 0x02u);
922 ASSERT_EQ(rsp.max_sdu, 0x1918u);
923 ASSERT_EQ(rsp.retrans_nb, 0x1Au);
924 ASSERT_EQ(rsp.max_transport_latency, 0x1C1Bu);
925 ASSERT_EQ(rsp.pres_delay, 0x1F1E1Du);
926 }
927
TEST(LeAudioClientParserTest,testParseAseStatusTransientStateParamsInvalidLength)928 TEST(LeAudioClientParserTest, testParseAseStatusTransientStateParamsInvalidLength) {
929 ase_transient_state_params params;
930 const uint8_t value1[] = {
931 // Ase ID
932 0x01,
933 // ASE State
934 0x03, // 'Enabling' state
935 // missing Metadata length
936 // missing Metadata
937 };
938 ParseAseStatusTransientStateParams(params, sizeof(value1) - 2, value1 + 2);
939 }
940
TEST(LeAudioClientParserTest,testParseAseStatusTransientStateParams)941 TEST(LeAudioClientParserTest, testParseAseStatusTransientStateParams) {
942 ase_transient_state_params params;
943 const uint8_t value1[] = {
944 // Ase ID
945 0x01,
946 // ASE State
947 0x03, // 'Enabling' state
948 // Metadata length
949 0x00,
950 };
951 ParseAseStatusTransientStateParams(params, sizeof(value1) - 2, value1 + 2);
952 ASSERT_EQ(params.metadata.size(), 0u);
953
954 const uint8_t value2[] = {
955 // Ase ID
956 0x01,
957 // ASE State
958 0x03, // 'Enabling' state
959 // CIG_ID
960 0x03,
961 // CIS_ID
962 0x04,
963 // Metadata length
964 0x03,
965 // Metadata
966 0x02, // [0].length
967 0x01, // [0].type
968 0x00, // [0].value[0]
969 };
970 ParseAseStatusTransientStateParams(params, sizeof(value2) - 2, value2 + 2);
971
972 ASSERT_EQ(params.metadata.size(), 3u);
973 ASSERT_EQ(params.metadata[0], 0x02u);
974 ASSERT_EQ(params.metadata[1], 0x01u);
975 ASSERT_EQ(params.metadata[2], 0x00u);
976 }
977
TEST(LeAudioClientParserTest,testParseAseCtpNotificationInvalidLength)978 TEST(LeAudioClientParserTest, testParseAseCtpNotificationInvalidLength) {
979 ctp_ntf ntf;
980 const uint8_t value1[] = {
981 // Opcode
982 0x01,
983 // Number of ASEs
984 0x02,
985 // ASE ID
986 0x01,
987 // Response Code
988 0x01,
989 // Reason
990 0x01,
991 // ASE ID
992 0x02,
993 // Response Code
994 0x02,
995 // Missing Reason
996 };
997 ParseAseCtpNotification(ntf, sizeof(value1), value1);
998
999 // In case of invalid payload at least we get the opcode
1000 ASSERT_EQ(ntf.op, 0x01u);
1001 ASSERT_EQ(ntf.entries.size(), 0u);
1002
1003 const uint8_t value2[] = {
1004 // Opcode
1005 0x01,
1006 // Missing Number of ASEs
1007 // Missing ASE ID
1008 // Missing Response Code
1009 // Missing Reason
1010 // Missing ASE ID
1011 // Missing Response Code
1012 // Missing Reason
1013 };
1014 ntf.entries.clear();
1015 ParseAseCtpNotification(ntf, sizeof(value2), value2);
1016
1017 // In case of invalid payload at least we get the opcode
1018 ASSERT_EQ(ntf.op, 0x01u);
1019 ASSERT_EQ(ntf.entries.size(), 0u);
1020
1021 const uint8_t value3[] = {
1022 // Opcode
1023 0x01,
1024 // Number of ASEs
1025 0x03,
1026 // ASE ID
1027 0x01,
1028 // Response Code
1029 0x01,
1030 // Reason
1031 0x01,
1032 // ASE ID
1033 0x02,
1034 // Response Code
1035 0x02,
1036 // Reason
1037 0x03,
1038 // Missing the entire ASE entry
1039 };
1040
1041 ntf.entries.clear();
1042 ParseAseCtpNotification(ntf, sizeof(value3), value3);
1043 // In case of invalid payload at least we get the opcode
1044 ASSERT_EQ(ntf.op, 0x01u);
1045 ASSERT_EQ(ntf.entries.size(), 0u);
1046 }
1047
TEST(LeAudioClientParserTest,testParseAseCtpNotification)1048 TEST(LeAudioClientParserTest, testParseAseCtpNotification) {
1049 ctp_ntf ntf;
1050 const uint8_t value1[] = {
1051 // Opcode
1052 0x01,
1053 // Number of ASEs
1054 0x02,
1055 // ASE ID
1056 0x01,
1057 // Response Code
1058 0x01,
1059 // Reason
1060 0x01,
1061 // ASE ID
1062 0x03,
1063 // Response Code
1064 0x02,
1065 // Reason
1066 0x03,
1067 };
1068 ParseAseCtpNotification(ntf, sizeof(value1), value1);
1069
1070 ASSERT_EQ(ntf.op, 0x01u);
1071 ASSERT_EQ(ntf.entries.size(), 2u);
1072 ASSERT_EQ(ntf.entries[0].ase_id, 0x01u);
1073 ASSERT_EQ(ntf.entries[0].response_code, 0x01u);
1074 ASSERT_EQ(ntf.entries[0].reason, 0x01);
1075 ASSERT_EQ(ntf.entries[1].ase_id, 0x03u);
1076 ASSERT_EQ(ntf.entries[1].response_code, 0x02u);
1077 ASSERT_EQ(ntf.entries[1].reason, 0x03);
1078 }
1079
TEST(LeAudioClientParserTest,testParseAseCtpNotificationConfigurationIssue)1080 TEST(LeAudioClientParserTest, testParseAseCtpNotificationConfigurationIssue) {
1081 ctp_ntf ntf;
1082 const uint8_t value1[] = {
1083 // Opcode
1084 0x01,
1085 // Number of ASEs
1086 0x02,
1087 // ASE ID
1088 0x01,
1089 // Response Code
1090 0x07,
1091 // Reason
1092 0x01,
1093 // ASE ID
1094 0x03,
1095 // Response Code
1096 0x05,
1097 // Reason
1098 0x05,
1099 };
1100 ParseAseCtpNotification(ntf, sizeof(value1), value1);
1101
1102 ASSERT_EQ(ntf.op, 0x01u);
1103 ASSERT_EQ(ntf.entries.size(), 2u);
1104 ASSERT_EQ(ntf.entries[0].ase_id, 0x01u);
1105 ASSERT_EQ(ntf.entries[0].response_code, 0x07u);
1106 ASSERT_EQ(ntf.entries[0].reason, 0x01);
1107 ASSERT_EQ(ntf.entries[1].ase_id, 0x03u);
1108 ASSERT_EQ(ntf.entries[1].response_code, 0x05u);
1109 ASSERT_EQ(ntf.entries[1].reason, 0x05);
1110 }
1111
TEST(LeAudioClientParserTest,testParseAseCtpNotificationMetadataIssue)1112 TEST(LeAudioClientParserTest, testParseAseCtpNotificationMetadataIssue) {
1113 ctp_ntf ntf;
1114 const uint8_t value1[] = {
1115 // Opcode
1116 0x01,
1117 // Number of ASEs
1118 0x02,
1119 // ASE ID
1120 0x01,
1121 // Response Code
1122 0x0A,
1123 // Reason
1124 0x01,
1125 // ASE ID
1126 0x03,
1127 // Response Code
1128 0x0D,
1129 // Reason
1130 0xFF,
1131 };
1132 ParseAseCtpNotification(ntf, sizeof(value1), value1);
1133
1134 ASSERT_EQ(ntf.op, 0x01u);
1135 ASSERT_EQ(ntf.entries.size(), 2u);
1136 ASSERT_EQ(ntf.entries[0].ase_id, 0x01u);
1137 ASSERT_EQ(ntf.entries[0].response_code, 0x0Au);
1138 ASSERT_EQ(ntf.entries[0].reason, 0x01);
1139 ASSERT_EQ(ntf.entries[1].ase_id, 0x03u);
1140 ASSERT_EQ(ntf.entries[1].response_code, 0x0Du);
1141 ASSERT_EQ(ntf.entries[1].reason, 0xFF);
1142 }
1143
TEST(LeAudioClientParserTest,testPrepareAseCtpCodecConfigEmpty)1144 TEST(LeAudioClientParserTest, testPrepareAseCtpCodecConfigEmpty) {
1145 std::vector<struct ctp_codec_conf> confs;
1146 std::vector<uint8_t> value;
1147
1148 PrepareAseCtpCodecConfig(confs, value);
1149
1150 ASSERT_EQ(value.size(), 0u);
1151 }
1152
TEST(LeAudioClientParserTest,testPrepareAseCtpCodecConfigSingle)1153 TEST(LeAudioClientParserTest, testPrepareAseCtpCodecConfigSingle) {
1154 std::vector<struct ctp_codec_conf> confs;
1155 std::vector<uint8_t> value;
1156
1157 types::LeAudioCodecId codec_id{
1158 .coding_format = 0x06, .vendor_company_id = 0x0203, .vendor_codec_id = 0x0405};
1159 types::LeAudioLtvMap codec_conf =
1160 types::LeAudioLtvMap()
1161 .Add(codec_spec_conf::kLeAudioLtvTypeSamplingFreq, (uint8_t)0x10)
1162 .Add(codec_spec_conf::kLeAudioLtvTypeFrameDuration, (uint8_t)0x03)
1163 .Add(codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation, (uint32_t)0x04050607)
1164 .Add(codec_spec_conf::kLeAudioLtvTypeOctetsPerCodecFrame, (uint16_t)0x0203);
1165
1166 confs.push_back(ctp_codec_conf{
1167 .ase_id = 0x05,
1168 .target_latency = 0x03,
1169 .target_phy = 0x02,
1170 .codec_id = codec_id,
1171 .codec_config = codec_conf.RawPacket(),
1172 });
1173 PrepareAseCtpCodecConfig(confs, value);
1174
1175 uint8_t i = 0;
1176 ASSERT_NE(value.size(), 0u);
1177 ASSERT_EQ(value[i++], 0x01); // Config Codec Opcode
1178 ASSERT_EQ(value[i++], 0x01); // Number of ASEs
1179 ASSERT_EQ(value[i++], 0x05); // ASE[0] ASE ID
1180 ASSERT_EQ(value[i++], 0x03); // ASE[0] Target Latency
1181 ASSERT_EQ(value[i++], 0x02); // ASE[0] Target Phy
1182 ASSERT_EQ(value[i++], 0x06); // ASE[0].CodecID Coding Format
1183 ASSERT_EQ(value[i++], 0x03); // ASE[0].CodecID Company ID LSB
1184 ASSERT_EQ(value[i++], 0x02); // ASE[0].CodecID Company ID MSB
1185 ASSERT_EQ(value[i++], 0x05); // ASE[0].CodecID Codec ID LSB
1186 ASSERT_EQ(value[i++], 0x04); // ASE[0].CodecID Codec ID MSB
1187
1188 // ASE[0].Codec Spec. Conf. Length - LC3 specific
1189 ASSERT_EQ(value[i++], 8 + 8); // * 4*2 bytes for 4 LTV types and lengths + 8
1190 // bytes for the values
1191 ASSERT_EQ(value[i++], 0x02); // Sampling Freq. Length
1192 ASSERT_EQ(value[i++], 0x01); // Sampling Freq. Type
1193 ASSERT_EQ(value[i++], 0x10); // Sampling Freq. Value
1194 ASSERT_EQ(value[i++], 0x02); // Frame Duration. Length
1195 ASSERT_EQ(value[i++], 0x02); // Frame Duration. Type
1196 ASSERT_EQ(value[i++], 0x03); // Frame Duration. Value
1197 ASSERT_EQ(value[i++], 0x05); // Audio Channel Allocations Length
1198 ASSERT_EQ(value[i++], 0x03); // Audio Channel Allocations Type
1199 ASSERT_EQ(value[i++], 0x07); // Audio Channel Allocations Value[0]
1200 ASSERT_EQ(value[i++], 0x06); // Audio Channel Allocations Value[1]
1201 ASSERT_EQ(value[i++], 0x05); // Audio Channel Allocations Value[2]
1202 ASSERT_EQ(value[i++], 0x04); // Audio Channel Allocations Value[3]
1203 ASSERT_EQ(value[i++], 0x03); // Octets Per Frame Length
1204 ASSERT_EQ(value[i++], 0x04); // Octets Per Frame Type
1205 ASSERT_EQ(value[i++], 0x03); // Octets Per Frame Value[0]
1206 ASSERT_EQ(value[i++], 0x02); // Octets Per Frame Value[1]
1207 ASSERT_EQ(value.size(), i);
1208 }
1209
TEST(LeAudioClientParserTest,testPrepareAseCtpCodecConfigMultiple)1210 TEST(LeAudioClientParserTest, testPrepareAseCtpCodecConfigMultiple) {
1211 std::vector<struct ctp_codec_conf> confs;
1212 std::vector<uint8_t> value;
1213
1214 types::LeAudioCodecId codec_id{
1215 .coding_format = 0x06, .vendor_company_id = 0x0203, .vendor_codec_id = 0x0405};
1216 types::LeAudioLtvMap codec_conf =
1217 types::LeAudioLtvMap()
1218 .Add(codec_spec_conf::kLeAudioLtvTypeSamplingFreq, (uint8_t)0x10)
1219 .Add(codec_spec_conf::kLeAudioLtvTypeFrameDuration, (uint8_t)0x03)
1220 .Add(codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation, (uint32_t)0x04050607)
1221 .Add(codec_spec_conf::kLeAudioLtvTypeOctetsPerCodecFrame, (uint16_t)0x0203);
1222
1223 confs.push_back(ctp_codec_conf{
1224 .ase_id = 0x05,
1225 .target_latency = 0x03,
1226 .target_phy = 0x02,
1227 .codec_id = codec_id,
1228 .codec_config = codec_conf.RawPacket(),
1229 });
1230 PrepareAseCtpCodecConfig(confs, value);
1231
1232 uint8_t i = 0;
1233 ASSERT_NE(value.size(), 0u);
1234 ASSERT_EQ(value[i++], 0x01); // Config Codec Opcode
1235 ASSERT_EQ(value[i++], 0x01); // Number of ASEs
1236 ASSERT_EQ(value[i++], 0x05); // ASE[0] ASE ID
1237 ASSERT_EQ(value[i++], 0x03); // ASE[0] Target Latency
1238 ASSERT_EQ(value[i++], 0x02); // ASE[0] Target Phy
1239 ASSERT_EQ(value[i++], 0x06); // ASE[0].CodecID Coding Format
1240 ASSERT_EQ(value[i++], 0x03); // ASE[0].CodecID Company ID LSB
1241 ASSERT_EQ(value[i++], 0x02); // ASE[0].CodecID Company ID MSB
1242 ASSERT_EQ(value[i++], 0x05); // ASE[0].CodecID Codec ID LSB
1243 ASSERT_EQ(value[i++], 0x04); // ASE[0].CodecID Codec ID MSB
1244
1245 // ASE[0].Codec Spec. Conf. Length - LC3 specific
1246 ASSERT_EQ(value[i++], 8 + 8); // * 4*2 bytes for 4 LTV types and lengths + 8
1247 // bytes for the values
1248 ASSERT_EQ(value[i++], 0x02); // Sampling Freq. Length
1249 ASSERT_EQ(value[i++], 0x01); // Sampling Freq. Type
1250 ASSERT_EQ(value[i++], 0x10); // Sampling Freq. Value
1251 ASSERT_EQ(value[i++], 0x02); // Frame Duration. Length
1252 ASSERT_EQ(value[i++], 0x02); // Frame Duration. Type
1253 ASSERT_EQ(value[i++], 0x03); // Frame Duration. Value
1254 ASSERT_EQ(value[i++], 0x05); // Audio Channel Allocations Length
1255 ASSERT_EQ(value[i++], 0x03); // Audio Channel Allocations Type
1256 ASSERT_EQ(value[i++], 0x07); // Audio Channel Allocations Value[0]
1257 ASSERT_EQ(value[i++], 0x06); // Audio Channel Allocations Value[1]
1258 ASSERT_EQ(value[i++], 0x05); // Audio Channel Allocations Value[2]
1259 ASSERT_EQ(value[i++], 0x04); // Audio Channel Allocations Value[3]
1260 ASSERT_EQ(value[i++], 0x03); // Octets Per Frame Length
1261 ASSERT_EQ(value[i++], 0x04); // Octets Per Frame Type
1262 ASSERT_EQ(value[i++], 0x03); // Octets Per Frame Value[0]
1263 ASSERT_EQ(value[i++], 0x02); // Octets Per Frame Value[1]
1264 ASSERT_EQ(value.size(), i);
1265
1266 types::LeAudioCodecId codec_id2{
1267 .coding_format = 0x16, .vendor_company_id = 0x1213, .vendor_codec_id = 0x1415};
1268 types::LeAudioLtvMap codec_conf2 =
1269 types::LeAudioLtvMap()
1270 .Add(codec_spec_conf::kLeAudioLtvTypeSamplingFreq, (uint8_t)0x11)
1271 .Add(codec_spec_conf::kLeAudioLtvTypeFrameDuration, (uint8_t)0x13)
1272 .Add(codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation, (uint32_t)0x14151617)
1273 .Add(codec_spec_conf::kLeAudioLtvTypeOctetsPerCodecFrame, (uint16_t)0x1213);
1274
1275 confs.push_back(ctp_codec_conf{
1276 .ase_id = 0x15,
1277 .target_latency = 0x13,
1278 .target_phy = 0x01,
1279 .codec_id = codec_id2,
1280 .codec_config = codec_conf2.RawPacket(),
1281 });
1282 PrepareAseCtpCodecConfig(confs, value);
1283
1284 i = 0;
1285 ASSERT_NE(value.size(), 0u);
1286 ASSERT_EQ(value[i++], 0x01); // Config Codec Opcode
1287 ASSERT_EQ(value[i++], 0x02); // Number of ASEs
1288 ASSERT_EQ(value[i++], 0x05); // ASE[0] ASE ID
1289 ASSERT_EQ(value[i++], 0x03); // ASE[0] Target Latency
1290 ASSERT_EQ(value[i++], 0x02); // ASE[0] Target Phy
1291 ASSERT_EQ(value[i++], 0x06); // ASE[0].CodecID Coding Format
1292 ASSERT_EQ(value[i++], 0x03); // ASE[0].CodecID Company ID LSB
1293 ASSERT_EQ(value[i++], 0x02); // ASE[0].CodecID Company ID MSB
1294 ASSERT_EQ(value[i++], 0x05); // ASE[0].CodecID Codec ID LSB
1295 ASSERT_EQ(value[i++], 0x04); // ASE[0].CodecID Codec ID MSB
1296
1297 // ASE[0].Codec Spec. Conf. Length - LC3 specific
1298 ASSERT_EQ(value[i++], 8 + 8); // * 4*2 bytes for 4 LTV types and lengths + 8
1299 // bytes for the values
1300 ASSERT_EQ(value[i++], 0x02); // Sampling Freq. Length
1301 ASSERT_EQ(value[i++], 0x01); // Sampling Freq. Type
1302 ASSERT_EQ(value[i++], 0x10); // Sampling Freq. Value
1303 ASSERT_EQ(value[i++], 0x02); // Frame Duration. Length
1304 ASSERT_EQ(value[i++], 0x02); // Frame Duration. Type
1305 ASSERT_EQ(value[i++], 0x03); // Frame Duration. Value
1306 ASSERT_EQ(value[i++], 0x05); // Audio Channel Allocations Length
1307 ASSERT_EQ(value[i++], 0x03); // Audio Channel Allocations Type
1308 ASSERT_EQ(value[i++], 0x07); // Audio Channel Allocations Value[0]
1309 ASSERT_EQ(value[i++], 0x06); // Audio Channel Allocations Value[1]
1310 ASSERT_EQ(value[i++], 0x05); // Audio Channel Allocations Value[2]
1311 ASSERT_EQ(value[i++], 0x04); // Audio Channel Allocations Value[3]
1312 ASSERT_EQ(value[i++], 0x03); // Octets Per Frame Length
1313 ASSERT_EQ(value[i++], 0x04); // Octets Per Frame Type
1314 ASSERT_EQ(value[i++], 0x03); // Octets Per Frame Value[0]
1315 ASSERT_EQ(value[i++], 0x02); // Octets Per Frame Value[1]
1316
1317 ASSERT_EQ(value[i++], 0x15); // ASE[1] ASE ID
1318 ASSERT_EQ(value[i++], 0x13); // ASE[1] Target Latency
1319 ASSERT_EQ(value[i++], 0x01); // ASE[1] Target Phy
1320 ASSERT_EQ(value[i++], 0x16); // ASE[1].CodecID Coding Format
1321 ASSERT_EQ(value[i++], 0x13); // ASE[1].CodecID Company ID LSB
1322 ASSERT_EQ(value[i++], 0x12); // ASE[1].CodecID Company ID MSB
1323 ASSERT_EQ(value[i++], 0x15); // ASE[1].CodecID Codec ID LSB
1324 ASSERT_EQ(value[i++], 0x14); // ASE[1].CodecID Codec ID MSB
1325
1326 // ASE[1].Codec Spec. Conf. Length - LC3 specific
1327 ASSERT_EQ(value[i++], 8 + 8); // * 4*2 bytes for 4 LTV types and lengths + 8
1328 // bytes for the values
1329 ASSERT_EQ(value[i++], 0x02); // Sampling Freq. Length
1330 ASSERT_EQ(value[i++], 0x01); // Sampling Freq. Type
1331 ASSERT_EQ(value[i++], 0x11); // Sampling Freq. Value
1332 ASSERT_EQ(value[i++], 0x02); // Frame Duration. Length
1333 ASSERT_EQ(value[i++], 0x02); // Frame Duration. Type
1334 ASSERT_EQ(value[i++], 0x13); // Frame Duration. Value
1335 ASSERT_EQ(value[i++], 0x05); // Audio Channel Allocations Length
1336 ASSERT_EQ(value[i++], 0x03); // Audio Channel Allocations Type
1337 ASSERT_EQ(value[i++], 0x17); // Audio Channel Allocations Value[0]
1338 ASSERT_EQ(value[i++], 0x16); // Audio Channel Allocations Value[1]
1339 ASSERT_EQ(value[i++], 0x15); // Audio Channel Allocations Value[2]
1340 ASSERT_EQ(value[i++], 0x14); // Audio Channel Allocations Value[3]
1341 ASSERT_EQ(value[i++], 0x03); // Octets Per Frame Length
1342 ASSERT_EQ(value[i++], 0x04); // Octets Per Frame Type
1343 ASSERT_EQ(value[i++], 0x13); // Octets Per Frame Value[0]
1344 ASSERT_EQ(value[i++], 0x12); // Octets Per Frame Value[1]
1345
1346 ASSERT_EQ(value.size(), i);
1347 }
1348
TEST(LeAudioClientParserTest,testPrepareAseCtpConfigQosEmpty)1349 TEST(LeAudioClientParserTest, testPrepareAseCtpConfigQosEmpty) {
1350 std::vector<struct ctp_qos_conf> confs;
1351 std::vector<uint8_t> value;
1352
1353 PrepareAseCtpConfigQos(confs, value);
1354 ASSERT_EQ(value.size(), 0u);
1355 }
1356
TEST(LeAudioClientParserTest,testPrepareAseCtpConfigQosSingle)1357 TEST(LeAudioClientParserTest, testPrepareAseCtpConfigQosSingle) {
1358 std::vector<struct ctp_qos_conf> confs;
1359 std::vector<uint8_t> value;
1360
1361 const ctp_qos_conf conf{.ase_id = 0x01,
1362 .cig = 0x11,
1363 .cis = 0x12,
1364 .sdu_interval = 0x00131415,
1365 .framing = 0x01,
1366 .phy = 0x01,
1367 .max_sdu = 0x0203,
1368 .retrans_nb = 0x04,
1369 .max_transport_latency = 0x0302,
1370 .pres_delay = 0x00121314};
1371 confs.push_back(conf);
1372
1373 PrepareAseCtpConfigQos(confs, value);
1374 ASSERT_NE(value.size(), 0u);
1375
1376 uint8_t i = 0;
1377 ASSERT_EQ(value[i++], 0x02u); // Config QOS Opcode
1378 ASSERT_EQ(value[i++], 0x01u); // Number of ASE
1379 ASSERT_EQ(value[i++], 0x01u); // ASE ID
1380 ASSERT_EQ(value[i++], 0x11u); // CIG ID
1381 ASSERT_EQ(value[i++], 0x12u); // CIS ID
1382 ASSERT_EQ(value[i++], 0x15u); // SDU Interval [0]
1383 ASSERT_EQ(value[i++], 0x14u); // SDU Interval [1]
1384 ASSERT_EQ(value[i++], 0x13u); // SDU Interval [2]
1385 ASSERT_EQ(value[i++], 0x01u); // Framing
1386 ASSERT_EQ(value[i++], 0x01u); // Phy
1387 ASSERT_EQ(value[i++], 0x03u); // Max SDU LSB
1388 ASSERT_EQ(value[i++], 0x02u); // Max SDU MSB
1389 ASSERT_EQ(value[i++], 0x04u); // Retransmission
1390 ASSERT_EQ(value[i++], 0x02u); // Max. Trans. Latency LSB
1391 ASSERT_EQ(value[i++], 0x03u); // Max. Trans. Latency MSB
1392 ASSERT_EQ(value[i++], 0x14u); // Pres. Delay[0]
1393 ASSERT_EQ(value[i++], 0x13u); // Pres. Delay[1]
1394 ASSERT_EQ(value[i++], 0x12u); // Pres. Delay[2]
1395 ASSERT_EQ(value.size(), i);
1396 }
1397
TEST(LeAudioClientParserTest,testPrepareAseCtpConfigQosMultiple)1398 TEST(LeAudioClientParserTest, testPrepareAseCtpConfigQosMultiple) {
1399 std::vector<struct ctp_qos_conf> confs;
1400 std::vector<uint8_t> value;
1401
1402 const ctp_qos_conf conf{.ase_id = 0x01,
1403 .cig = 0x11,
1404 .cis = 0x12,
1405 .sdu_interval = 0x131415,
1406 .framing = 0x01,
1407 .phy = 0x01,
1408 .max_sdu = 0x0203,
1409 .retrans_nb = 0x04,
1410 .max_transport_latency = 0x0302,
1411 .pres_delay = 0x121314};
1412 confs.push_back(conf);
1413
1414 const ctp_qos_conf conf2{.ase_id = 0x11,
1415 .cig = 0x21,
1416 .cis = 0x22,
1417 .sdu_interval = 0x232425,
1418 .framing = 0x02,
1419 .phy = 0x02,
1420 .max_sdu = 0x2223,
1421 .retrans_nb = 0x24,
1422 .max_transport_latency = 0x2322,
1423 .pres_delay = 0x222324};
1424 confs.push_back(conf2);
1425
1426 PrepareAseCtpConfigQos(confs, value);
1427 ASSERT_NE(value.size(), 0u);
1428
1429 uint8_t i = 0;
1430 ASSERT_EQ(value[i++], 0x02u); // Config QOS Opcode
1431 ASSERT_EQ(value[i++], 0x02u); // Number of ASE
1432 // 1st ASE Config
1433 ASSERT_EQ(value[i++], 0x01u); // ASE ID
1434 ASSERT_EQ(value[i++], 0x11u); // CIG ID
1435 ASSERT_EQ(value[i++], 0x12u); // CIS ID
1436 ASSERT_EQ(value[i++], 0x15u); // SDU Interval [0]
1437 ASSERT_EQ(value[i++], 0x14u); // SDU Interval [1]
1438 ASSERT_EQ(value[i++], 0x13u); // SDU Interval [2]
1439 ASSERT_EQ(value[i++], 0x01u); // Framing
1440 ASSERT_EQ(value[i++], 0x01u); // Phy
1441 ASSERT_EQ(value[i++], 0x03u); // Max SDU LSB
1442 ASSERT_EQ(value[i++], 0x02u); // Max SDU MSB
1443 ASSERT_EQ(value[i++], 0x04u); // Retransmission
1444 ASSERT_EQ(value[i++], 0x02u); // Max. Trans. Latency LSB
1445 ASSERT_EQ(value[i++], 0x03u); // Max. Trans. Latency MSB
1446 ASSERT_EQ(value[i++], 0x14u); // Pres. Delay[0]
1447 ASSERT_EQ(value[i++], 0x13u); // Pres. Delay[1]
1448 ASSERT_EQ(value[i++], 0x12u); // Pres. Delay[2]
1449 // 2nd ASE Config
1450 ASSERT_EQ(value[i++], 0x11u); // ASE ID
1451 ASSERT_EQ(value[i++], 0x21u); // CIG ID
1452 ASSERT_EQ(value[i++], 0x22u); // CIS ID
1453 ASSERT_EQ(value[i++], 0x25u); // SDU Interval [0]
1454 ASSERT_EQ(value[i++], 0x24u); // SDU Interval [1]
1455 ASSERT_EQ(value[i++], 0x23u); // SDU Interval [2]
1456 ASSERT_EQ(value[i++], 0x02u); // Framing
1457 ASSERT_EQ(value[i++], 0x02u); // Phy
1458 ASSERT_EQ(value[i++], 0x23u); // Max SDU LSB
1459 ASSERT_EQ(value[i++], 0x22u); // Max SDU MSB
1460 ASSERT_EQ(value[i++], 0x24u); // Retransmission
1461 ASSERT_EQ(value[i++], 0x22u); // Max. Trans. Latency LSB
1462 ASSERT_EQ(value[i++], 0x23u); // Max. Trans. Latency MSB
1463 ASSERT_EQ(value[i++], 0x24u); // Pres. Delay[0]
1464 ASSERT_EQ(value[i++], 0x23u); // Pres. Delay[1]
1465 ASSERT_EQ(value[i++], 0x22u); // Pres. Delay[2]
1466
1467 ASSERT_EQ(value.size(), i);
1468 }
1469
TEST(LeAudioClientParserTest,testPrepareAseCtpEnableEmpty)1470 TEST(LeAudioClientParserTest, testPrepareAseCtpEnableEmpty) {
1471 std::vector<struct ctp_enable> confs;
1472 std::vector<uint8_t> value;
1473
1474 PrepareAseCtpEnable(confs, value);
1475 ASSERT_EQ(value.size(), 0u);
1476 }
1477
TEST(LeAudioClientParserTest,testPrepareAseCtpEnableSingle)1478 TEST(LeAudioClientParserTest, testPrepareAseCtpEnableSingle) {
1479 std::vector<struct ctp_enable> confs;
1480 std::vector<uint8_t> value;
1481
1482 ctp_enable conf{.ase_id = 0x11, .metadata = {0x02, 0x22, 0x21}};
1483 confs.push_back(conf);
1484
1485 PrepareAseCtpEnable(confs, value);
1486 ASSERT_NE(value.size(), 0u);
1487
1488 uint8_t i = 0;
1489 ASSERT_EQ(value[i++], 0x03u); // Enable Opcode
1490 ASSERT_EQ(value[i++], 0x01u); // Number of ASEs
1491 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1492 ASSERT_EQ(value[i++], 0x03u); // Metadata Len
1493 ASSERT_EQ(value[i++], 0x02u); // Metadata[0]
1494 ASSERT_EQ(value[i++], 0x22u); // Metadata[1]
1495 ASSERT_EQ(value[i++], 0x21u); // Metadata[2]
1496 ASSERT_EQ(value.size(), i);
1497 }
1498
TEST(LeAudioClientParserTest,testPrepareAseCtpEnableMultiple)1499 TEST(LeAudioClientParserTest, testPrepareAseCtpEnableMultiple) {
1500 std::vector<struct ctp_enable> confs;
1501 std::vector<uint8_t> value;
1502
1503 ctp_enable conf{.ase_id = 0x11, .metadata = {0x02, 0x22, 0x21}};
1504 confs.push_back(conf);
1505
1506 ctp_enable conf2{.ase_id = 0x21, .metadata = {0x03, 0x35, 0x36, 0x37}};
1507 confs.push_back(conf2);
1508
1509 PrepareAseCtpEnable(confs, value);
1510 ASSERT_NE(value.size(), 0u);
1511
1512 uint8_t i = 0;
1513 ASSERT_EQ(value[i++], 0x03u); // Enable Opcode
1514 ASSERT_EQ(value[i++], 0x02u); // Number of ASEs
1515 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1516 ASSERT_EQ(value[i++], 0x03u); // ASE[0] Metadata Len
1517 ASSERT_EQ(value[i++], 0x02u); // ASE[0] Metadata[0]
1518 ASSERT_EQ(value[i++], 0x22u); // ASE[0] Metadata[1]
1519 ASSERT_EQ(value[i++], 0x21u); // ASE[0] Metadata[2]
1520 ASSERT_EQ(value[i++], 0x21u); // ASE[1] ID
1521 ASSERT_EQ(value[i++], 0x04u); // ASE[1] Metadata Len
1522 ASSERT_EQ(value[i++], 0x03u); // ASE[1] Metadata[0]
1523 ASSERT_EQ(value[i++], 0x35u); // ASE[1] Metadata[1]
1524 ASSERT_EQ(value[i++], 0x36u); // ASE[1] Metadata[2]
1525 ASSERT_EQ(value[i++], 0x37u); // ASE[1] Metadata[3]
1526 ASSERT_EQ(value.size(), i);
1527 }
1528
TEST(LeAudioClientParserTest,testPrepareAseCtpAudioReceiverStartReadyEmpty)1529 TEST(LeAudioClientParserTest, testPrepareAseCtpAudioReceiverStartReadyEmpty) {
1530 std::vector<uint8_t> ase_ids;
1531 std::vector<uint8_t> value;
1532
1533 PrepareAseCtpAudioReceiverStartReady(ase_ids, value);
1534 ASSERT_EQ(value.size(), 0u);
1535 }
1536
TEST(LeAudioClientParserTest,testPrepareAseCtpAudioReceiverStartReadySingle)1537 TEST(LeAudioClientParserTest, testPrepareAseCtpAudioReceiverStartReadySingle) {
1538 std::vector<uint8_t> ase_ids;
1539 std::vector<uint8_t> value;
1540
1541 ase_ids.push_back(0x11);
1542
1543 PrepareAseCtpAudioReceiverStartReady(ase_ids, value);
1544
1545 uint8_t i = 0;
1546 ASSERT_NE(value.size(), 0u);
1547 ASSERT_EQ(value[i++], 0x04u); // Receiver Start Ready Opcode
1548 ASSERT_EQ(value[i++], 1u); // Number of ASEs
1549 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1550 ASSERT_EQ(i, value.size());
1551 }
1552
TEST(LeAudioClientParserTest,testPrepareAseCtpAudioReceiverStartReadyMultiple)1553 TEST(LeAudioClientParserTest, testPrepareAseCtpAudioReceiverStartReadyMultiple) {
1554 std::vector<uint8_t> ase_ids;
1555 std::vector<uint8_t> value;
1556
1557 ase_ids.push_back(0x11);
1558 ase_ids.push_back(0x36);
1559
1560 PrepareAseCtpAudioReceiverStartReady(ase_ids, value);
1561
1562 uint8_t i = 0;
1563 ASSERT_NE(value.size(), 0u);
1564 ASSERT_EQ(value[i++], 0x04u); // Receiver Start Ready Opcode
1565 ASSERT_EQ(value[i++], 2u); // Number of ASEs
1566 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1567 ASSERT_EQ(value[i++], 0x36u); // ASE[0] ID
1568 ASSERT_EQ(i, value.size());
1569 }
1570
TEST(LeAudioClientParserTest,testPrepareAseCtpDisableEmpty)1571 TEST(LeAudioClientParserTest, testPrepareAseCtpDisableEmpty) {
1572 std::vector<uint8_t> ase_ids;
1573 std::vector<uint8_t> value;
1574
1575 PrepareAseCtpDisable(ase_ids, value);
1576 ASSERT_EQ(value.size(), 0u);
1577 }
1578
TEST(LeAudioClientParserTest,testPrepareAseCtpDisableSingle)1579 TEST(LeAudioClientParserTest, testPrepareAseCtpDisableSingle) {
1580 std::vector<uint8_t> ase_ids;
1581 std::vector<uint8_t> value;
1582
1583 ase_ids.push_back(0x11);
1584
1585 PrepareAseCtpDisable(ase_ids, value);
1586
1587 uint8_t i = 0;
1588 ASSERT_NE(value.size(), 0u);
1589 ASSERT_EQ(value[i++], 0x05u); // Disable Opcode
1590 ASSERT_EQ(value[i++], 1u); // Number of ASEs
1591 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1592 ASSERT_EQ(i, value.size());
1593 }
1594
TEST(LeAudioClientParserTest,testPrepareAseCtpDisableMultiple)1595 TEST(LeAudioClientParserTest, testPrepareAseCtpDisableMultiple) {
1596 std::vector<uint8_t> ase_ids;
1597 std::vector<uint8_t> value;
1598
1599 ase_ids.push_back(0x11);
1600 ase_ids.push_back(0x36);
1601
1602 PrepareAseCtpDisable(ase_ids, value);
1603
1604 uint8_t i = 0;
1605 ASSERT_NE(value.size(), 0u);
1606 ASSERT_EQ(value[i++], 0x05u); // Disable Opcode
1607 ASSERT_EQ(value[i++], 2u); // Number of ASEs
1608 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1609 ASSERT_EQ(value[i++], 0x36u); // ASE[0] ID
1610 ASSERT_EQ(i, value.size());
1611 }
1612
TEST(LeAudioClientParserTest,testPrepareAseCtpAudioReceiverStopReadyEmpty)1613 TEST(LeAudioClientParserTest, testPrepareAseCtpAudioReceiverStopReadyEmpty) {
1614 std::vector<uint8_t> ase_ids;
1615 std::vector<uint8_t> value;
1616
1617 PrepareAseCtpAudioReceiverStopReady(ase_ids, value);
1618 ASSERT_EQ(value.size(), 0u);
1619 }
1620
TEST(LeAudioClientParserTest,testPrepareAseCtpAudioReceiverStopReadySingle)1621 TEST(LeAudioClientParserTest, testPrepareAseCtpAudioReceiverStopReadySingle) {
1622 std::vector<uint8_t> ase_ids;
1623 std::vector<uint8_t> value;
1624
1625 ase_ids.push_back(0x11);
1626
1627 PrepareAseCtpAudioReceiverStopReady(ase_ids, value);
1628
1629 uint8_t i = 0;
1630 ASSERT_NE(value.size(), 0u);
1631 ASSERT_EQ(value[i++], 0x06u); // Reveicer Stop Ready Opcode
1632 ASSERT_EQ(value[i++], 1u); // Number of ASEs
1633 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1634 ASSERT_EQ(i, value.size());
1635 }
1636
TEST(LeAudioClientParserTest,testPrepareAseCtpAudioReceiverStopReadyMultiple)1637 TEST(LeAudioClientParserTest, testPrepareAseCtpAudioReceiverStopReadyMultiple) {
1638 std::vector<uint8_t> ase_ids;
1639 std::vector<uint8_t> value;
1640
1641 ase_ids.push_back(0x11);
1642 ase_ids.push_back(0x36);
1643
1644 PrepareAseCtpAudioReceiverStopReady(ase_ids, value);
1645
1646 uint8_t i = 0;
1647 ASSERT_NE(value.size(), 0u);
1648 ASSERT_EQ(value[i++], 0x06u); // Reveicer Stop Ready Opcode
1649 ASSERT_EQ(value[i++], 2u); // Number of ASEs
1650 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1651 ASSERT_EQ(value[i++], 0x36u); // ASE[0] ID
1652 ASSERT_EQ(i, value.size());
1653 }
1654
TEST(LeAudioClientParserTest,testPrepareAseCtpUpdateMetadataEmpty)1655 TEST(LeAudioClientParserTest, testPrepareAseCtpUpdateMetadataEmpty) {
1656 std::vector<struct ctp_update_metadata> confs;
1657 std::vector<uint8_t> value;
1658
1659 PrepareAseCtpUpdateMetadata(confs, value);
1660 ASSERT_EQ(value.size(), 0u);
1661 }
1662
TEST(LeAudioClientParserTest,testPrepareAseCtpUpdateMetadataSingle)1663 TEST(LeAudioClientParserTest, testPrepareAseCtpUpdateMetadataSingle) {
1664 std::vector<struct ctp_update_metadata> confs;
1665 std::vector<uint8_t> value;
1666
1667 ctp_update_metadata conf{.ase_id = 0x11, .metadata = {0x02, 0x22, 0x21}};
1668 confs.push_back(conf);
1669
1670 PrepareAseCtpUpdateMetadata(confs, value);
1671 ASSERT_NE(value.size(), 0u);
1672
1673 uint8_t i = 0;
1674 ASSERT_EQ(value[i++], 0x07u); // Update Metadata Opcode
1675 ASSERT_EQ(value[i++], 0x01u); // Number of ASEs
1676 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1677 ASSERT_EQ(value[i++], 0x03u); // Metadata Len
1678 ASSERT_EQ(value[i++], 0x02u); // Metadata[0]
1679 ASSERT_EQ(value[i++], 0x22u); // Metadata[1]
1680 ASSERT_EQ(value[i++], 0x21u); // Metadata[2]
1681 ASSERT_EQ(i, value.size());
1682 }
1683
TEST(LeAudioClientParserTest,testPrepareAseCtpUpdateMetadataMultiple)1684 TEST(LeAudioClientParserTest, testPrepareAseCtpUpdateMetadataMultiple) {
1685 std::vector<struct ctp_update_metadata> confs;
1686 std::vector<uint8_t> value;
1687
1688 ctp_update_metadata conf{.ase_id = 0x11, .metadata = {0x02, 0x22, 0x21}};
1689 confs.push_back(conf);
1690
1691 ctp_update_metadata conf2{.ase_id = 0x21, .metadata = {0x03, 0x35, 0x36, 0x37}};
1692 confs.push_back(conf2);
1693
1694 PrepareAseCtpUpdateMetadata(confs, value);
1695 ASSERT_NE(value.size(), 0u);
1696
1697 uint8_t i = 0;
1698 ASSERT_EQ(value[i++], 0x07u); // Update Metadata Opcode
1699 ASSERT_EQ(value[i++], 0x02u); // Number of ASEs
1700 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1701 ASSERT_EQ(value[i++], 0x03u); // ASE[0] Metadata Len
1702 ASSERT_EQ(value[i++], 0x02u); // ASE[0] Metadata[0]
1703 ASSERT_EQ(value[i++], 0x22u); // ASE[0] Metadata[1]
1704 ASSERT_EQ(value[i++], 0x21u); // ASE[0] Metadata[2]
1705 ASSERT_EQ(value[i++], 0x21u); // ASE[1] ID
1706 ASSERT_EQ(value[i++], 0x04u); // ASE[1] Metadata Len
1707 ASSERT_EQ(value[i++], 0x03u); // ASE[1] Metadata[0]
1708 ASSERT_EQ(value[i++], 0x35u); // ASE[1] Metadata[1]
1709 ASSERT_EQ(value[i++], 0x36u); // ASE[1] Metadata[2]
1710 ASSERT_EQ(value[i++], 0x37u); // ASE[1] Metadata[2]
1711 ASSERT_EQ(i, value.size());
1712 }
1713
TEST(LeAudioClientParserTest,testPrepareAseCtpReleaseEmpty)1714 TEST(LeAudioClientParserTest, testPrepareAseCtpReleaseEmpty) {
1715 std::vector<uint8_t> ase_ids;
1716 std::vector<uint8_t> value;
1717
1718 PrepareAseCtpRelease(ase_ids, value);
1719 ASSERT_EQ(value.size(), 0u);
1720 }
1721
TEST(LeAudioClientParserTest,testPrepareAseCtpReleaseSingle)1722 TEST(LeAudioClientParserTest, testPrepareAseCtpReleaseSingle) {
1723 std::vector<uint8_t> ase_ids;
1724 std::vector<uint8_t> value;
1725
1726 ase_ids.push_back(0x11);
1727
1728 PrepareAseCtpRelease(ase_ids, value);
1729
1730 uint8_t i = 0;
1731 ASSERT_NE(value.size(), 0u);
1732 ASSERT_EQ(value[i++], 0x08u); // Release Opcode
1733 ASSERT_EQ(value[i++], 1u); // Number of ASEs
1734 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1735 ASSERT_EQ(i, value.size());
1736 }
1737
TEST(LeAudioClientParserTest,testPrepareAseCtpReleaseMultiple)1738 TEST(LeAudioClientParserTest, testPrepareAseCtpReleaseMultiple) {
1739 std::vector<uint8_t> ase_ids;
1740 std::vector<uint8_t> value;
1741
1742 ase_ids.push_back(0x11);
1743 ase_ids.push_back(0x36);
1744
1745 PrepareAseCtpRelease(ase_ids, value);
1746
1747 uint8_t i = 0;
1748 ASSERT_NE(value.size(), 0u);
1749 ASSERT_EQ(value[i++], 0x08u); // Release Opcode
1750 ASSERT_EQ(value[i++], 2u); // Number of ASEs
1751 ASSERT_EQ(value[i++], 0x11u); // ASE[0] ID
1752 ASSERT_EQ(value[i++], 0x36u); // ASE[0] ID
1753 ASSERT_EQ(i, value.size());
1754 }
1755
1756 } // namespace ascs
1757
1758 namespace tmap {
1759
TEST(LeAudioClientParserTest,testParseTmapRoleValid)1760 TEST(LeAudioClientParserTest, testParseTmapRoleValid) {
1761 std::bitset<16> role;
1762 const uint8_t value[] = {0x3F, 0x00};
1763
1764 ASSERT_TRUE(ParseTmapRole(role, 2, value));
1765
1766 ASSERT_EQ(role, 0x003F); // All possible TMAP roles
1767 }
1768
TEST(LeAudioClientParserTest,testParseTmapRoleInvalidLen)1769 TEST(LeAudioClientParserTest, testParseTmapRoleInvalidLen) {
1770 std::bitset<16> role;
1771 const uint8_t value[] = {0x00, 0x3F};
1772
1773 ASSERT_FALSE(ParseTmapRole(role, 3, value));
1774 }
1775
1776 } // namespace tmap
1777
1778 } // namespace client_parser
1779 } // namespace bluetooth::le_audio
1780