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