1 /*
2  * Copyright (c) 2022 Bose Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 /** @file
7  *  @brief Bluetooth LE-Audio codec LTV parsing
8  *
9  *  Helper functions to parse codec config data as specified in the Bluetooth assigned numbers for
10  *  Generic Audio.
11  */
12 
13 #include <stdlib.h>
14 
15 #include <zephyr/bluetooth/audio/audio.h>
16 #include <zephyr/sys/byteorder.h>
17 #include <zephyr/sys/check.h>
18 
19 #include <zephyr/logging/log.h>
20 
21 LOG_MODULE_REGISTER(bt_audio_codec, CONFIG_BT_AUDIO_CODEC_LOG_LEVEL);
22 
bt_audio_codec_cfg_freq_to_freq_hz(enum bt_audio_codec_config_freq freq)23 int bt_audio_codec_cfg_freq_to_freq_hz(enum bt_audio_codec_config_freq freq)
24 {
25 	switch (freq) {
26 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ:
27 		return 8000;
28 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ:
29 		return 11025;
30 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ:
31 		return 16000;
32 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ:
33 		return 22050;
34 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ:
35 		return 24000;
36 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ:
37 		return 32000;
38 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ:
39 		return 44100;
40 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ:
41 		return 48000;
42 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ:
43 		return 88200;
44 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ:
45 		return 96000;
46 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ:
47 		return 176400;
48 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ:
49 		return 192000;
50 	case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ:
51 		return 384000;
52 	default:
53 		return -EINVAL;
54 	}
55 }
56 
bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz)57 int bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz)
58 {
59 	switch (freq_hz) {
60 	case 8000U:
61 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ;
62 	case 11025U:
63 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ;
64 	case 16000U:
65 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ;
66 	case 22050U:
67 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ;
68 	case 24000U:
69 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ;
70 	case 32000U:
71 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ;
72 	case 44100U:
73 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ;
74 	case 48000U:
75 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ;
76 	case 88200U:
77 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ;
78 	case 96000U:
79 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ;
80 	case 176400U:
81 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ;
82 	case 192000U:
83 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ;
84 	case 384000U:
85 		return BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ;
86 	default:
87 		return -EINVAL;
88 	}
89 }
90 
91 struct search_type_param {
92 	bool found;
93 	uint8_t type;
94 	uint8_t data_len;
95 	const uint8_t **data;
96 };
97 
parse_cb(struct bt_data * data,void * user_data)98 static bool parse_cb(struct bt_data *data, void *user_data)
99 {
100 	struct search_type_param *param = (struct search_type_param *)user_data;
101 
102 	if (param->type == data->type) {
103 		param->found = true;
104 		param->data_len = data->data_len;
105 		*param->data = data->data;
106 
107 		return false;
108 	}
109 
110 	return true;
111 }
112 
113 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
114 
init_net_buf_simple_from_codec_cfg(struct net_buf_simple * buf,struct bt_audio_codec_cfg * codec_cfg)115 static void init_net_buf_simple_from_codec_cfg(struct net_buf_simple *buf,
116 					       struct bt_audio_codec_cfg *codec_cfg)
117 {
118 	buf->__buf = codec_cfg->data;
119 	buf->data = codec_cfg->data;
120 	buf->size = sizeof(codec_cfg->data);
121 	buf->len = codec_cfg->data_len;
122 }
123 
bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg * codec_cfg,uint8_t type,const uint8_t ** data)124 uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type,
125 				   const uint8_t **data)
126 {
127 	struct search_type_param param = {
128 		.found = false,
129 		.type = type,
130 		.data_len = 0,
131 		.data = data,
132 	};
133 	int err;
134 
135 	CHECKIF(codec_cfg == NULL) {
136 		LOG_DBG("codec is NULL");
137 		return 0;
138 	}
139 
140 	CHECKIF(data == NULL) {
141 		LOG_DBG("data is NULL");
142 		return 0;
143 	}
144 
145 	*data = NULL;
146 
147 	err = bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, parse_cb, &param);
148 	if (err != 0 && err != -ECANCELED) {
149 		LOG_DBG("Could not parse the data: %d", err);
150 		return 0;
151 	}
152 
153 	if (param.data == NULL) {
154 		LOG_DBG("Could not find the type %u", type);
155 		return 0;
156 	}
157 
158 	return param.data_len;
159 }
160 
bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg * codec_cfg,uint8_t type,const uint8_t * data,size_t data_len)161 int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type,
162 			       const uint8_t *data, size_t data_len)
163 {
164 	CHECKIF(codec_cfg == NULL) {
165 		LOG_DBG("codec_cfg is NULL");
166 		return -EINVAL;
167 	}
168 
169 	CHECKIF(data == NULL) {
170 		LOG_DBG("data is NULL");
171 		return -EINVAL;
172 	}
173 
174 	CHECKIF(data_len == 0U || data_len > UINT8_MAX) {
175 		LOG_DBG("Invalid data_len %zu", data_len);
176 		return -EINVAL;
177 	}
178 
179 	for (uint16_t i = 0U; i < codec_cfg->data_len;) {
180 		uint8_t *len = &codec_cfg->data[i++];
181 		const uint8_t data_type = codec_cfg->data[i++];
182 		const uint8_t value_len = *len - sizeof(data_type);
183 
184 		if (data_type == type) {
185 			uint8_t *value = &codec_cfg->data[i];
186 
187 			if (data_len == value_len) {
188 				memcpy(value, data, data_len);
189 			} else {
190 				const int16_t diff = data_len - value_len;
191 				uint8_t *old_next_data_start;
192 				uint8_t *new_next_data_start;
193 				uint8_t data_len_to_move;
194 
195 				/* Check if this is the last value in the buffer */
196 				if (value + value_len == codec_cfg->data + codec_cfg->data_len) {
197 					data_len_to_move = 0U;
198 				} else {
199 					old_next_data_start = value + value_len + 1;
200 					new_next_data_start = value + data_len + 1;
201 					data_len_to_move = codec_cfg->data_len -
202 							   (old_next_data_start - codec_cfg->data);
203 				}
204 
205 				if (diff < 0) {
206 					/* In this case we need to move memory around after the copy
207 					 * to fit the new shorter data
208 					 */
209 
210 					memcpy(value, data, data_len);
211 					if (data_len_to_move > 0U) {
212 						memmove(new_next_data_start, old_next_data_start,
213 							data_len_to_move);
214 					}
215 				} else {
216 					/* In this case we need to move memory around before
217 					 * the copy to fit the new longer data
218 					 */
219 					if ((codec_cfg->data_len + diff) >
220 					    ARRAY_SIZE(codec_cfg->data)) {
221 						LOG_DBG("Cannot fit data_len %zu in buf with len "
222 							"%u and size %u",
223 							data_len, codec_cfg->data_len,
224 							ARRAY_SIZE(codec_cfg->data));
225 						return -ENOMEM;
226 					}
227 
228 					if (data_len_to_move > 0) {
229 						memmove(new_next_data_start, old_next_data_start,
230 							data_len_to_move);
231 					}
232 
233 					memcpy(value, data, data_len);
234 				}
235 
236 				codec_cfg->data_len += diff;
237 				*len += diff;
238 			}
239 
240 			return codec_cfg->data_len;
241 		}
242 
243 		i += value_len;
244 	}
245 
246 	/* If we reach here, we did not find the data in the buffer, so we simply add it */
247 	if ((codec_cfg->data_len + data_len) <= ARRAY_SIZE(codec_cfg->data)) {
248 		struct net_buf_simple buf;
249 
250 		init_net_buf_simple_from_codec_cfg(&buf, codec_cfg);
251 
252 		net_buf_simple_add_u8(&buf, data_len + sizeof(type));
253 		net_buf_simple_add_u8(&buf, type);
254 		if (data_len > 0) {
255 			net_buf_simple_add_mem(&buf, data, data_len);
256 		}
257 		codec_cfg->data_len = buf.len;
258 	} else {
259 		LOG_DBG("Cannot fit data_len %zu in codec_cfg with len %u and size %u", data_len,
260 			codec_cfg->data_len, ARRAY_SIZE(codec_cfg->data));
261 		return -ENOMEM;
262 	}
263 
264 	return codec_cfg->data_len;
265 }
266 
bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg * codec_cfg)267 int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg)
268 {
269 	enum bt_audio_codec_config_freq freq;
270 	const uint8_t *data;
271 	uint8_t data_len;
272 
273 	CHECKIF(codec_cfg == NULL) {
274 		LOG_DBG("codec is NULL");
275 		return -EINVAL;
276 	}
277 
278 	data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FREQ, &data);
279 	if (data == NULL) {
280 		return -ENODATA;
281 	}
282 
283 	if (data_len != sizeof(uint8_t)) {
284 		return -EBADMSG;
285 	}
286 
287 	freq = data[0];
288 	if (bt_audio_codec_cfg_freq_to_freq_hz(freq) < 0) {
289 		LOG_DBG("Invalid freq value: 0x%02X", freq);
290 		return -EBADMSG;
291 	}
292 
293 	return freq;
294 }
295 
bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_codec_config_freq freq)296 int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg,
297 				enum bt_audio_codec_config_freq freq)
298 {
299 	uint8_t freq_u8;
300 
301 	if (bt_audio_codec_cfg_freq_to_freq_hz(freq) < 0) {
302 		LOG_DBG("Invalid freq value: %d", freq);
303 		return -EINVAL;
304 	}
305 
306 	freq_u8 = (uint8_t)freq;
307 
308 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FREQ, &freq_u8,
309 					  sizeof(freq_u8));
310 }
311 
bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg * codec_cfg)312 int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg)
313 {
314 	const uint8_t *data;
315 	uint8_t data_len;
316 
317 	CHECKIF(codec_cfg == NULL) {
318 		LOG_DBG("codec is NULL");
319 		return -EINVAL;
320 	}
321 
322 	data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_DURATION, &data);
323 	if (data == NULL) {
324 		return -ENODATA;
325 	}
326 
327 	if (data_len != sizeof(uint8_t)) {
328 		return -EBADMSG;
329 	}
330 
331 	switch (data[0]) {
332 	case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5:
333 		return 7500;
334 	case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10:
335 		return 10000;
336 	default:
337 		return -EBADMSG;
338 	}
339 }
340 
bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_location * chan_allocation)341 int bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg *codec_cfg,
342 					   enum bt_audio_location *chan_allocation)
343 {
344 	const uint8_t *data;
345 	uint8_t data_len;
346 
347 	*chan_allocation = 0;
348 
349 	CHECKIF(codec_cfg == NULL) {
350 		LOG_DBG("codec is NULL");
351 		return -EINVAL;
352 	}
353 
354 	CHECKIF(chan_allocation == NULL) {
355 		return -EINVAL;
356 	}
357 
358 	data_len =
359 		bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, &data);
360 	if (data == NULL) {
361 		return -ENODATA;
362 	}
363 
364 	if (data_len != sizeof(uint32_t)) {
365 		return -EBADMSG;
366 	}
367 
368 	*chan_allocation = sys_get_le32(data);
369 
370 	return 0;
371 }
372 
bt_audio_codec_cfg_set_chan_allocation(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_location chan_allocation)373 int bt_audio_codec_cfg_set_chan_allocation(struct bt_audio_codec_cfg *codec_cfg,
374 					   enum bt_audio_location chan_allocation)
375 {
376 	uint32_t chan_allocation_u32;
377 
378 	if ((chan_allocation & BT_AUDIO_LOCATION_ANY) != chan_allocation) {
379 		LOG_DBG("Invalid chan_allocation value: 0x%08X", chan_allocation);
380 		return -EINVAL;
381 	}
382 
383 	chan_allocation_u32 = sys_cpu_to_le32((uint32_t)chan_allocation);
384 
385 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC,
386 					  (const uint8_t *)&chan_allocation_u32,
387 					  sizeof(chan_allocation_u32));
388 }
389 
bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg * codec_cfg)390 int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *codec_cfg)
391 {
392 	const uint8_t *data;
393 	uint8_t data_len;
394 
395 	CHECKIF(codec_cfg == NULL) {
396 		LOG_DBG("codec is NULL");
397 		return -EINVAL;
398 	}
399 
400 	data_len =
401 		bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN, &data);
402 	if (data == NULL) {
403 		return -ENODATA;
404 	}
405 
406 	if (data_len != sizeof(uint16_t)) {
407 		return -EBADMSG;
408 	}
409 
410 	return sys_get_le16(data);
411 }
412 
bt_audio_codec_cfg_set_octets_per_frame(struct bt_audio_codec_cfg * codec_cfg,uint16_t octets_per_frame)413 int bt_audio_codec_cfg_set_octets_per_frame(struct bt_audio_codec_cfg *codec_cfg,
414 					    uint16_t octets_per_frame)
415 {
416 	uint16_t octets_per_frame_le16;
417 
418 	octets_per_frame_le16 = sys_cpu_to_le16(octets_per_frame);
419 
420 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN,
421 					  (uint8_t *)&octets_per_frame_le16,
422 					  sizeof(octets_per_frame_le16));
423 }
424 
bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg * codec_cfg,bool fallback_to_default)425 int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg,
426 						bool fallback_to_default)
427 {
428 	const uint8_t *data;
429 	uint8_t data_len;
430 
431 	CHECKIF(codec_cfg == NULL) {
432 		LOG_DBG("codec is NULL");
433 		return -EINVAL;
434 	}
435 
436 	data_len = bt_audio_codec_cfg_get_val(codec_cfg,
437 					      BT_AUDIO_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU, &data);
438 	if (data == NULL) {
439 		if (fallback_to_default) {
440 			return 1;
441 		}
442 
443 		return -ENODATA;
444 	}
445 
446 	if (data_len != sizeof(uint8_t)) {
447 		return -EBADMSG;
448 	}
449 
450 	return data[0];
451 }
452 
bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg * codec_cfg,uint8_t frame_blocks)453 int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec_cfg,
454 						uint8_t frame_blocks)
455 {
456 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU,
457 					  &frame_blocks, sizeof(frame_blocks));
458 }
459 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
460 
461 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 ||                                             \
462 	CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0
463 
codec_meta_get_val(const uint8_t meta[],size_t meta_len,uint8_t type,const uint8_t ** data)464 static int codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t type,
465 			      const uint8_t **data)
466 {
467 	struct search_type_param param = {
468 		.type = type,
469 		.data_len = 0,
470 		.data = data,
471 	};
472 	int err;
473 
474 	CHECKIF(meta == NULL) {
475 		LOG_DBG("meta is NULL");
476 		return -EINVAL;
477 	}
478 
479 	CHECKIF(data == NULL) {
480 		LOG_DBG("data is NULL");
481 		return -EINVAL;
482 	}
483 
484 	*data = NULL;
485 
486 	err = bt_audio_data_parse(meta, meta_len, parse_cb, &param);
487 	if (err != 0 && err != -ECANCELED) {
488 		LOG_DBG("Could not parse the meta data: %d", err);
489 		return err;
490 	}
491 
492 	if (!param.found) {
493 		LOG_DBG("Could not find the type %u", type);
494 		return -ENODATA;
495 	}
496 
497 	return param.data_len;
498 }
499 
codec_meta_get_pref_context(const uint8_t meta[],size_t meta_len)500 static int codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len)
501 {
502 	const uint8_t *data;
503 	int ret;
504 
505 	CHECKIF(meta == NULL) {
506 		LOG_DBG("meta is NULL");
507 		return -EINVAL;
508 	}
509 
510 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, &data);
511 	if (data == NULL) {
512 		return -ENODATA;
513 	}
514 
515 	if (ret != sizeof(uint16_t)) {
516 		return -EBADMSG;
517 	}
518 
519 	return sys_get_le16(data);
520 }
521 
codec_meta_get_stream_context(const uint8_t meta[],size_t meta_len)522 static int codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len)
523 {
524 	const uint8_t *data;
525 	int ret;
526 
527 	CHECKIF(meta == NULL) {
528 		LOG_DBG("meta is NULL");
529 		return -EINVAL;
530 	}
531 
532 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, &data);
533 	if (data == NULL) {
534 		return -ENODATA;
535 	}
536 
537 	if (ret != sizeof(uint16_t)) {
538 		return -EBADMSG;
539 	}
540 
541 	return sys_get_le16(data);
542 }
543 
codec_meta_get_program_info(const uint8_t meta[],size_t meta_len,const uint8_t ** program_info)544 static int codec_meta_get_program_info(const uint8_t meta[], size_t meta_len,
545 				       const uint8_t **program_info)
546 {
547 	const uint8_t *data;
548 	int ret;
549 
550 	CHECKIF(meta == NULL) {
551 		LOG_DBG("meta is NULL");
552 		return -EINVAL;
553 	}
554 
555 	CHECKIF(program_info == NULL) {
556 		LOG_DBG("program_info is NULL");
557 		return -EINVAL;
558 	}
559 
560 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, &data);
561 	if (data == NULL) {
562 		return -ENODATA;
563 	}
564 
565 	*program_info = data;
566 
567 	return ret;
568 }
569 
codec_meta_get_stream_lang(const uint8_t meta[],size_t meta_len)570 static int codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len)
571 {
572 	const uint8_t *data;
573 	int ret;
574 
575 	CHECKIF(meta == NULL) {
576 		LOG_DBG("meta is NULL");
577 		return -EINVAL;
578 	}
579 
580 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_STREAM_LANG, &data);
581 	if (data == NULL) {
582 		return -ENODATA;
583 	}
584 
585 	if (ret != 3) { /* Stream language is 3 octets */
586 		return -EBADMSG;
587 	}
588 
589 	return sys_get_le24(data);
590 }
591 
codec_meta_get_ccid_list(const uint8_t meta[],size_t meta_len,const uint8_t ** ccid_list)592 static int codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len,
593 				    const uint8_t **ccid_list)
594 {
595 	const uint8_t *data;
596 	int ret;
597 
598 	CHECKIF(meta == NULL) {
599 		LOG_DBG("meta is NULL");
600 		return -EINVAL;
601 	}
602 
603 	CHECKIF(ccid_list == NULL) {
604 		LOG_DBG("ccid_list is NULL");
605 		return -EINVAL;
606 	}
607 
608 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_CCID_LIST, &data);
609 	if (data == NULL) {
610 		return -ENODATA;
611 	}
612 
613 	*ccid_list = data;
614 
615 	return ret;
616 }
617 
codec_meta_get_parental_rating(const uint8_t meta[],size_t meta_len)618 static int codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len)
619 {
620 	const uint8_t *data;
621 	int ret;
622 
623 	CHECKIF(meta == NULL) {
624 		LOG_DBG("meta is NULL");
625 		return -EINVAL;
626 	}
627 
628 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, &data);
629 	if (data == NULL) {
630 		return -ENODATA;
631 	}
632 
633 	if (ret != sizeof(uint8_t)) {
634 		return -EBADMSG;
635 	}
636 
637 	return data[0];
638 }
639 
codec_meta_get_program_info_uri(const uint8_t meta[],size_t meta_len,const uint8_t ** program_info_uri)640 static int codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len,
641 					   const uint8_t **program_info_uri)
642 {
643 	const uint8_t *data;
644 	int ret;
645 
646 	CHECKIF(meta == NULL) {
647 		LOG_DBG("meta is NULL");
648 		return -EINVAL;
649 	}
650 
651 	CHECKIF(program_info_uri == NULL) {
652 		LOG_DBG("program_info_uri is NULL");
653 		return -EINVAL;
654 	}
655 
656 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, &data);
657 	if (data == NULL) {
658 		return -ENODATA;
659 	}
660 
661 	*program_info_uri = data;
662 
663 	return ret;
664 }
665 
codec_meta_get_audio_active_state(const uint8_t meta[],size_t meta_len)666 static int codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len)
667 {
668 	const uint8_t *data;
669 	int ret;
670 
671 	CHECKIF(meta == NULL) {
672 		LOG_DBG("meta is NULL");
673 		return -EINVAL;
674 	}
675 
676 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_AUDIO_STATE, &data);
677 	if (data == NULL) {
678 		return -ENODATA;
679 	}
680 
681 	if (ret != sizeof(uint8_t)) {
682 		return -EBADMSG;
683 	}
684 
685 	return data[0];
686 }
687 
codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[],size_t meta_len)688 static int codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[], size_t meta_len)
689 {
690 	const uint8_t *data;
691 
692 	CHECKIF(meta == NULL) {
693 		LOG_DBG("meta is NULL");
694 		return -EINVAL;
695 	}
696 
697 	return codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE,
698 				  &data);
699 }
700 
codec_meta_get_extended(const uint8_t meta[],size_t meta_len,const uint8_t ** extended_meta)701 static int codec_meta_get_extended(const uint8_t meta[], size_t meta_len,
702 				   const uint8_t **extended_meta)
703 {
704 	const uint8_t *data;
705 	int ret;
706 
707 	CHECKIF(meta == NULL) {
708 		LOG_DBG("meta is NULL");
709 		return -EINVAL;
710 	}
711 
712 	CHECKIF(extended_meta == NULL) {
713 		LOG_DBG("extended_meta is NULL");
714 		return -EINVAL;
715 	}
716 
717 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_EXTENDED, &data);
718 	if (data == NULL) {
719 		return -ENODATA;
720 	}
721 
722 	*extended_meta = data;
723 
724 	return ret;
725 }
726 
codec_meta_get_vendor(const uint8_t meta[],size_t meta_len,const uint8_t ** vendor_meta)727 static int codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, const uint8_t **vendor_meta)
728 {
729 	const uint8_t *data;
730 	int ret;
731 
732 	CHECKIF(meta == NULL) {
733 		LOG_DBG("meta is NULL");
734 		return -EINVAL;
735 	}
736 
737 	CHECKIF(vendor_meta == NULL) {
738 		LOG_DBG("vendor_meta is NULL");
739 		return -EINVAL;
740 	}
741 
742 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_VENDOR, &data);
743 	if (data == NULL) {
744 		return -ENODATA;
745 	}
746 
747 	*vendor_meta = data;
748 
749 	return ret;
750 }
751 
752 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg * codec_cfg,uint8_t type,const uint8_t ** data)753 int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type,
754 				    const uint8_t **data)
755 {
756 	CHECKIF(codec_cfg == NULL) {
757 		LOG_DBG("codec_cfg is NULL");
758 		return -EINVAL;
759 	}
760 
761 	return codec_meta_get_val(codec_cfg->meta, codec_cfg->meta_len, type, data);
762 }
763 
bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg * codec_cfg)764 int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg)
765 {
766 	CHECKIF(codec_cfg == NULL) {
767 		LOG_DBG("codec_cfg is NULL");
768 		return -EINVAL;
769 	}
770 
771 	return codec_meta_get_pref_context(codec_cfg->meta, codec_cfg->meta_len);
772 }
773 
bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg * codec_cfg)774 int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg *codec_cfg)
775 {
776 	CHECKIF(codec_cfg == NULL) {
777 		LOG_DBG("codec_cfg is NULL");
778 		return -EINVAL;
779 	}
780 
781 	return codec_meta_get_stream_context(codec_cfg->meta, codec_cfg->meta_len);
782 }
783 
bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** program_info)784 int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *codec_cfg,
785 					     const uint8_t **program_info)
786 {
787 	CHECKIF(codec_cfg == NULL) {
788 		LOG_DBG("codec_cfg is NULL");
789 		return -EINVAL;
790 	}
791 
792 	return codec_meta_get_program_info(codec_cfg->meta, codec_cfg->meta_len, program_info);
793 }
794 
bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg * codec_cfg)795 int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *codec_cfg)
796 {
797 	CHECKIF(codec_cfg == NULL) {
798 		LOG_DBG("codec_cfg is NULL");
799 		return -EINVAL;
800 	}
801 
802 	return codec_meta_get_stream_lang(codec_cfg->meta, codec_cfg->meta_len);
803 }
804 
bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** ccid_list)805 int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec_cfg,
806 					  const uint8_t **ccid_list)
807 {
808 	CHECKIF(codec_cfg == NULL) {
809 		LOG_DBG("codec_cfg is NULL");
810 		return -EINVAL;
811 	}
812 
813 	return codec_meta_get_ccid_list(codec_cfg->meta, codec_cfg->meta_len, ccid_list);
814 }
815 
bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg * codec_cfg)816 int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg *codec_cfg)
817 {
818 	CHECKIF(codec_cfg == NULL) {
819 		LOG_DBG("codec_cfg is NULL");
820 		return -EINVAL;
821 	}
822 
823 	return codec_meta_get_parental_rating(codec_cfg->meta, codec_cfg->meta_len);
824 }
825 
bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** program_info_uri)826 int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg *codec_cfg,
827 						 const uint8_t **program_info_uri)
828 {
829 	CHECKIF(codec_cfg == NULL) {
830 		LOG_DBG("codec_cfg is NULL");
831 		return -EINVAL;
832 	}
833 
834 	return codec_meta_get_program_info_uri(codec_cfg->meta, codec_cfg->meta_len,
835 					       program_info_uri);
836 }
837 
bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg * codec_cfg)838 int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg *codec_cfg)
839 {
840 	CHECKIF(codec_cfg == NULL) {
841 		LOG_DBG("codec_cfg is NULL");
842 		return -EINVAL;
843 	}
844 
845 	return codec_meta_get_audio_active_state(codec_cfg->meta, codec_cfg->meta_len);
846 }
847 
bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(const struct bt_audio_codec_cfg * codec_cfg)848 int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(
849 	const struct bt_audio_codec_cfg *codec_cfg)
850 {
851 	CHECKIF(codec_cfg == NULL) {
852 		LOG_DBG("codec_cfg is NULL");
853 		return -EINVAL;
854 	}
855 
856 	LOG_ERR("codec_cfg->meta_len %zu", codec_cfg->meta_len);
857 
858 	return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cfg->meta, codec_cfg->meta_len);
859 }
860 
bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** extended_meta)861 int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_cfg,
862 					 const uint8_t **extended_meta)
863 {
864 	CHECKIF(codec_cfg == NULL) {
865 		LOG_DBG("codec_cfg is NULL");
866 		return -EINVAL;
867 	}
868 
869 	return codec_meta_get_extended(codec_cfg->meta, codec_cfg->meta_len, extended_meta);
870 }
871 
bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** vendor_meta)872 int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cfg,
873 				       const uint8_t **vendor_meta)
874 {
875 	CHECKIF(codec_cfg == NULL) {
876 		LOG_DBG("codec_cfg is NULL");
877 		return -EINVAL;
878 	}
879 
880 	return codec_meta_get_vendor(codec_cfg->meta, codec_cfg->meta_len, vendor_meta);
881 }
882 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
883 
884 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0
bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap * codec_cap,uint8_t type,const uint8_t ** data)885 int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type,
886 				    const uint8_t **data)
887 {
888 	CHECKIF(codec_cap == NULL) {
889 		LOG_DBG("codec_cap is NULL");
890 		return -EINVAL;
891 	}
892 
893 	return codec_meta_get_val(codec_cap->meta, codec_cap->meta_len, type, data);
894 }
895 
bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap * codec_cap)896 int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap)
897 {
898 	CHECKIF(codec_cap == NULL) {
899 		LOG_DBG("codec_cap is NULL");
900 		return -EINVAL;
901 	}
902 
903 	return codec_meta_get_pref_context(codec_cap->meta, codec_cap->meta_len);
904 }
905 
bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap * codec_cap)906 int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap *codec_cap)
907 {
908 	CHECKIF(codec_cap == NULL) {
909 		LOG_DBG("codec_cap is NULL");
910 		return -EINVAL;
911 	}
912 
913 	return codec_meta_get_stream_context(codec_cap->meta, codec_cap->meta_len);
914 }
915 
bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** program_info)916 int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *codec_cap,
917 					     const uint8_t **program_info)
918 {
919 	CHECKIF(codec_cap == NULL) {
920 		LOG_DBG("codec_cap is NULL");
921 		return -EINVAL;
922 	}
923 
924 	return codec_meta_get_program_info(codec_cap->meta, codec_cap->meta_len, program_info);
925 }
926 
bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap * codec_cap)927 int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *codec_cap)
928 {
929 	CHECKIF(codec_cap == NULL) {
930 		LOG_DBG("codec_cap is NULL");
931 		return -EINVAL;
932 	}
933 
934 	return codec_meta_get_stream_lang(codec_cap->meta, codec_cap->meta_len);
935 }
936 
bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** ccid_list)937 int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec_cap,
938 					  const uint8_t **ccid_list)
939 {
940 	CHECKIF(codec_cap == NULL) {
941 		LOG_DBG("codec_cap is NULL");
942 		return -EINVAL;
943 	}
944 
945 	return codec_meta_get_ccid_list(codec_cap->meta, codec_cap->meta_len, ccid_list);
946 }
947 
bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap * codec_cap)948 int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap *codec_cap)
949 {
950 	CHECKIF(codec_cap == NULL) {
951 		LOG_DBG("codec_cap is NULL");
952 		return -EINVAL;
953 	}
954 
955 	return codec_meta_get_parental_rating(codec_cap->meta, codec_cap->meta_len);
956 }
957 
bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** program_info_uri)958 int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap *codec_cap,
959 						 const uint8_t **program_info_uri)
960 {
961 	CHECKIF(codec_cap == NULL) {
962 		LOG_DBG("codec_cap is NULL");
963 		return -EINVAL;
964 	}
965 
966 	return codec_meta_get_program_info_uri(codec_cap->meta, codec_cap->meta_len,
967 					       program_info_uri);
968 }
969 
bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap * codec_cap)970 int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap *codec_cap)
971 {
972 	CHECKIF(codec_cap == NULL) {
973 		LOG_DBG("codec_cap is NULL");
974 		return -EINVAL;
975 	}
976 
977 	return codec_meta_get_audio_active_state(codec_cap->meta, codec_cap->meta_len);
978 }
979 
bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(const struct bt_audio_codec_cap * codec_cap)980 int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(
981 	const struct bt_audio_codec_cap *codec_cap)
982 {
983 	CHECKIF(codec_cap == NULL) {
984 		LOG_DBG("codec_cap is NULL");
985 		return -EINVAL;
986 	}
987 
988 	return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cap->meta, codec_cap->meta_len);
989 }
990 
bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** extended_meta)991 int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_cap,
992 					 const uint8_t **extended_meta)
993 {
994 	CHECKIF(codec_cap == NULL) {
995 		LOG_DBG("codec_cap is NULL");
996 		return -EINVAL;
997 	}
998 
999 	return codec_meta_get_extended(codec_cap->meta, codec_cap->meta_len, extended_meta);
1000 }
1001 
bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** vendor_meta)1002 int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap,
1003 				       const uint8_t **vendor_meta)
1004 {
1005 	CHECKIF(codec_cap == NULL) {
1006 		LOG_DBG("codec_cap is NULL");
1007 		return -EINVAL;
1008 	}
1009 
1010 	return codec_meta_get_vendor(codec_cap->meta, codec_cap->meta_len, vendor_meta);
1011 }
1012 #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */
1013 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 ||                                       \
1014 	* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0                                          \
1015 	*/
1016 
1017 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0
1018 
bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap * codec_cap,uint8_t type,const uint8_t ** data)1019 uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type,
1020 				   const uint8_t **data)
1021 {
1022 	struct search_type_param param = {
1023 		.type = type,
1024 		.data_len = 0,
1025 		.data = data,
1026 	};
1027 	int err;
1028 
1029 	CHECKIF(codec_cap == NULL) {
1030 		LOG_DBG("codec_cap is NULL");
1031 		return 0;
1032 	}
1033 
1034 	CHECKIF(data == NULL) {
1035 		LOG_DBG("data is NULL");
1036 		return 0;
1037 	}
1038 
1039 	*data = NULL;
1040 
1041 	err = bt_audio_data_parse(codec_cap->data, codec_cap->data_len, parse_cb, &param);
1042 	if (err != 0 && err != -ECANCELED) {
1043 		LOG_DBG("Could not parse the data: %d", err);
1044 		return 0;
1045 	}
1046 
1047 	if (param.data == NULL) {
1048 		LOG_DBG("Could not find the type %u", type);
1049 		return 0;
1050 	}
1051 
1052 	return param.data_len;
1053 }
1054 
bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap * codec_cap)1055 int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap)
1056 {
1057 	const uint8_t *data;
1058 	uint8_t data_len;
1059 
1060 	CHECKIF(codec_cap == NULL) {
1061 		LOG_DBG("codec_cap is NULL");
1062 		return -EINVAL;
1063 	}
1064 
1065 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FREQ, &data);
1066 	if (data == NULL) {
1067 		return -ENODATA;
1068 	}
1069 
1070 	if (data_len != sizeof(uint16_t)) {
1071 		return -EBADMSG;
1072 	}
1073 
1074 	return sys_get_le16(data);
1075 }
1076 
bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap * codec_cap)1077 int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec_cap)
1078 {
1079 	const uint8_t *data;
1080 	uint8_t data_len;
1081 
1082 	CHECKIF(codec_cap == NULL) {
1083 		LOG_DBG("codec_cap is NULL");
1084 		return -EINVAL;
1085 	}
1086 
1087 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_DURATION, &data);
1088 	if (data == NULL) {
1089 		return -ENODATA;
1090 	}
1091 
1092 	if (data_len != sizeof(uint8_t)) {
1093 		return -EBADMSG;
1094 	}
1095 
1096 	return data[0];
1097 }
1098 
bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap * codec_cap)1099 int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap)
1100 {
1101 	const uint8_t *data;
1102 	uint8_t data_len;
1103 
1104 	CHECKIF(codec_cap == NULL) {
1105 		LOG_DBG("codec_cap is NULL");
1106 		return -EINVAL;
1107 	}
1108 
1109 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_CHAN_COUNT, &data);
1110 	if (data == NULL) {
1111 		return -ENODATA;
1112 	}
1113 
1114 	if (data_len != sizeof(uint8_t)) {
1115 		return -EBADMSG;
1116 	}
1117 
1118 	return data[0];
1119 }
1120 
bt_audio_codec_cap_get_octets_per_frame(const struct bt_audio_codec_cap * codec_cap,struct bt_audio_codec_octets_per_codec_frame * codec_frame)1121 int bt_audio_codec_cap_get_octets_per_frame(
1122 	const struct bt_audio_codec_cap *codec_cap,
1123 	struct bt_audio_codec_octets_per_codec_frame *codec_frame)
1124 {
1125 	const uint8_t *data;
1126 	uint8_t data_len;
1127 
1128 	CHECKIF(codec_cap == NULL) {
1129 		LOG_DBG("codec_cap is NULL");
1130 		return -EINVAL;
1131 	}
1132 
1133 	CHECKIF(codec_frame == NULL) {
1134 		LOG_DBG("codec_frame is NULL");
1135 		return -EINVAL;
1136 	}
1137 
1138 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FRAME_LEN, &data);
1139 	if (data == NULL) {
1140 		return -ENODATA;
1141 	}
1142 
1143 	if (data_len != sizeof(uint32_t)) {
1144 		return -EBADMSG;
1145 	}
1146 
1147 	codec_frame->min = sys_get_le16(data);
1148 	codec_frame->max = sys_get_le16(data + sizeof(codec_frame->min));
1149 
1150 	return 0;
1151 }
1152 
bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap * codec_cap)1153 int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap)
1154 {
1155 	const uint8_t *data;
1156 	uint8_t data_len;
1157 
1158 	CHECKIF(codec_cap == NULL) {
1159 		LOG_DBG("codec_cap is NULL");
1160 		return -EINVAL;
1161 	}
1162 
1163 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FRAME_COUNT, &data);
1164 	if (data == NULL) {
1165 		return -ENODATA;
1166 	}
1167 
1168 	if (data_len != sizeof(uint8_t)) {
1169 		return -EBADMSG;
1170 	}
1171 
1172 	return data[0];
1173 }
1174 
1175 #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */
1176