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 <errno.h>
14 #include <stdbool.h>
15 #include <stddef.h>
16 #include <stdint.h>
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #include <zephyr/autoconf.h>
21 #include <zephyr/bluetooth/audio/audio.h>
22 #include <zephyr/bluetooth/bluetooth.h>
23 #include <zephyr/logging/log.h>
24 #include <zephyr/net_buf.h>
25 #include <zephyr/sys/byteorder.h>
26 #include <zephyr/sys/check.h>
27 #include <zephyr/sys/util.h>
28 
29 LOG_MODULE_REGISTER(bt_audio_codec, CONFIG_BT_AUDIO_CODEC_LOG_LEVEL);
30 
bt_audio_codec_cfg_freq_to_freq_hz(enum bt_audio_codec_cfg_freq freq)31 int bt_audio_codec_cfg_freq_to_freq_hz(enum bt_audio_codec_cfg_freq freq)
32 {
33 	switch (freq) {
34 	case BT_AUDIO_CODEC_CFG_FREQ_8KHZ:
35 		return 8000;
36 	case BT_AUDIO_CODEC_CFG_FREQ_11KHZ:
37 		return 11025;
38 	case BT_AUDIO_CODEC_CFG_FREQ_16KHZ:
39 		return 16000;
40 	case BT_AUDIO_CODEC_CFG_FREQ_22KHZ:
41 		return 22050;
42 	case BT_AUDIO_CODEC_CFG_FREQ_24KHZ:
43 		return 24000;
44 	case BT_AUDIO_CODEC_CFG_FREQ_32KHZ:
45 		return 32000;
46 	case BT_AUDIO_CODEC_CFG_FREQ_44KHZ:
47 		return 44100;
48 	case BT_AUDIO_CODEC_CFG_FREQ_48KHZ:
49 		return 48000;
50 	case BT_AUDIO_CODEC_CFG_FREQ_88KHZ:
51 		return 88200;
52 	case BT_AUDIO_CODEC_CFG_FREQ_96KHZ:
53 		return 96000;
54 	case BT_AUDIO_CODEC_CFG_FREQ_176KHZ:
55 		return 176400;
56 	case BT_AUDIO_CODEC_CFG_FREQ_192KHZ:
57 		return 192000;
58 	case BT_AUDIO_CODEC_CFG_FREQ_384KHZ:
59 		return 384000;
60 	default:
61 		return -EINVAL;
62 	}
63 }
64 
bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz)65 int bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz)
66 {
67 	switch (freq_hz) {
68 	case 8000U:
69 		return BT_AUDIO_CODEC_CFG_FREQ_8KHZ;
70 	case 11025U:
71 		return BT_AUDIO_CODEC_CFG_FREQ_11KHZ;
72 	case 16000U:
73 		return BT_AUDIO_CODEC_CFG_FREQ_16KHZ;
74 	case 22050U:
75 		return BT_AUDIO_CODEC_CFG_FREQ_22KHZ;
76 	case 24000U:
77 		return BT_AUDIO_CODEC_CFG_FREQ_24KHZ;
78 	case 32000U:
79 		return BT_AUDIO_CODEC_CFG_FREQ_32KHZ;
80 	case 44100U:
81 		return BT_AUDIO_CODEC_CFG_FREQ_44KHZ;
82 	case 48000U:
83 		return BT_AUDIO_CODEC_CFG_FREQ_48KHZ;
84 	case 88200U:
85 		return BT_AUDIO_CODEC_CFG_FREQ_88KHZ;
86 	case 96000U:
87 		return BT_AUDIO_CODEC_CFG_FREQ_96KHZ;
88 	case 176400U:
89 		return BT_AUDIO_CODEC_CFG_FREQ_176KHZ;
90 	case 192000U:
91 		return BT_AUDIO_CODEC_CFG_FREQ_192KHZ;
92 	case 384000U:
93 		return BT_AUDIO_CODEC_CFG_FREQ_384KHZ;
94 	default:
95 		return -EINVAL;
96 	}
97 }
98 
bt_audio_codec_cfg_frame_dur_to_frame_dur_us(enum bt_audio_codec_cfg_frame_dur frame_dur)99 int bt_audio_codec_cfg_frame_dur_to_frame_dur_us(enum bt_audio_codec_cfg_frame_dur frame_dur)
100 {
101 	switch (frame_dur) {
102 	case BT_AUDIO_CODEC_CFG_DURATION_7_5:
103 		return 7500;
104 	case BT_AUDIO_CODEC_CFG_DURATION_10:
105 		return 10000;
106 	default:
107 		return -EINVAL;
108 	}
109 }
110 
bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us)111 int bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us)
112 {
113 	switch (frame_dur_us) {
114 	case 7500U:
115 		return BT_AUDIO_CODEC_CFG_DURATION_7_5;
116 	case 10000U:
117 		return BT_AUDIO_CODEC_CFG_DURATION_10;
118 	default:
119 		return -EINVAL;
120 	}
121 }
122 
123 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 ||                                                 \
124 	CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 ||                                         \
125 	CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 ||                                             \
126 	CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0
127 
ltv_set_val(struct net_buf_simple * buf,uint8_t type,const uint8_t * data,size_t data_len)128 static int ltv_set_val(struct net_buf_simple *buf, uint8_t type, const uint8_t *data,
129 		       size_t data_len)
130 {
131 	size_t new_buf_len;
132 
133 	for (uint16_t i = 0U; i < buf->len;) {
134 		uint8_t *len = &buf->data[i++];
135 		const uint8_t data_type = buf->data[i++];
136 		const uint8_t value_len = *len - sizeof(data_type);
137 
138 		if (data_type == type) {
139 			uint8_t *value = &buf->data[i];
140 
141 			if (data_len == value_len) {
142 				memcpy(value, data, data_len);
143 			} else {
144 				const int16_t diff = data_len - value_len;
145 				uint8_t *old_next_data_start;
146 				uint8_t *new_next_data_start;
147 				uint8_t data_len_to_move;
148 
149 				/* Check if this is the last value in the buffer */
150 				if (value + value_len == buf->data + buf->len) {
151 					data_len_to_move = 0U;
152 				} else {
153 					old_next_data_start = value + value_len;
154 					new_next_data_start = value + data_len;
155 					data_len_to_move =
156 						buf->len - (old_next_data_start - buf->data);
157 				}
158 
159 				if (diff < 0) {
160 					/* In this case we need to move memory around after the copy
161 					 * to fit the new shorter data
162 					 */
163 
164 					memcpy(value, data, data_len);
165 					if (data_len_to_move > 0U) {
166 						memmove(new_next_data_start, old_next_data_start,
167 							data_len_to_move);
168 					}
169 				} else {
170 					/* In this case we need to move memory around before
171 					 * the copy to fit the new longer data
172 					 */
173 					if ((buf->len + diff) > buf->size) {
174 						LOG_DBG("Cannot fit data_len %zu in buf with len "
175 							"%u and size %u",
176 							data_len, buf->len, buf->size);
177 						return -ENOMEM;
178 					}
179 
180 					if (data_len_to_move > 0) {
181 						memmove(new_next_data_start, old_next_data_start,
182 							data_len_to_move);
183 					}
184 					memcpy(value, data, data_len);
185 				}
186 
187 				buf->len += diff;
188 				*len += diff;
189 			}
190 
191 			return buf->len;
192 		}
193 
194 		i += value_len;
195 	}
196 
197 	/* If we reach here, we did not find the data in the buffer, so we simply add it */
198 	new_buf_len = buf->len + 1 /* len */ + sizeof(type) + data_len;
199 	if (new_buf_len <= buf->size) {
200 		net_buf_simple_add_u8(buf, data_len + sizeof(type)); /* len */
201 		net_buf_simple_add_u8(buf, type); /* type */
202 		if (data_len > 0) {
203 			net_buf_simple_add_mem(buf, data, data_len); /* value */
204 		}
205 	} else {
206 		LOG_DBG("Cannot fit data_len %zu in codec_cfg with len %u and size %u", data_len,
207 			buf->len, buf->size);
208 		return -ENOMEM;
209 	}
210 
211 	return buf->len;
212 }
213 
ltv_unset_val(struct net_buf_simple * buf,uint8_t type)214 static int ltv_unset_val(struct net_buf_simple *buf, uint8_t type)
215 {
216 	for (uint16_t i = 0U; i < buf->len;) {
217 		uint8_t *ltv_start = &buf->data[i];
218 		const uint8_t len = buf->data[i++];
219 		const uint8_t data_type = buf->data[i++];
220 		const uint8_t value_len = len - sizeof(data_type);
221 
222 		if (data_type == type) {
223 			const uint8_t ltv_size = value_len + sizeof(data_type) + sizeof(len);
224 			uint8_t *value = &buf->data[i];
225 
226 			/* Check if this is not the last value in the buffer */
227 			if (value + value_len != buf->data + buf->len) {
228 				uint8_t *next_data_start;
229 				uint8_t data_len_to_move;
230 
231 				next_data_start = value + value_len;
232 				data_len_to_move = buf->len - (next_data_start - buf->data);
233 				memmove(ltv_start, next_data_start, data_len_to_move);
234 
235 				LOG_ERR("buf->data %p, ltv_start %p, value_len %u next_data_start "
236 					"%p data_len_to_move %u",
237 					buf->data, ltv_start, value_len, next_data_start,
238 					data_len_to_move);
239 			} /* else just reduce the length of the buffer */
240 
241 			buf->len -= ltv_size;
242 
243 			return buf->len;
244 		}
245 
246 		i += value_len;
247 	}
248 
249 	return buf->len;
250 }
251 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 ||                                           \
252 	* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 ||                                       \
253 	* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 ||                                           \
254 	* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0                                          \
255 	*/
256 
257 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
258 
init_net_buf_simple_from_codec_cfg(struct net_buf_simple * buf,struct bt_audio_codec_cfg * codec_cfg)259 static void init_net_buf_simple_from_codec_cfg(struct net_buf_simple *buf,
260 					       struct bt_audio_codec_cfg *codec_cfg)
261 {
262 	buf->__buf = codec_cfg->data;
263 	buf->data = codec_cfg->data;
264 	buf->size = sizeof(codec_cfg->data);
265 	buf->len = codec_cfg->data_len;
266 }
267 
bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_codec_cfg_type type,const uint8_t ** data)268 int bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg,
269 			       enum bt_audio_codec_cfg_type type, const uint8_t **data)
270 {
271 	CHECKIF(codec_cfg == NULL) {
272 		LOG_DBG("codec is NULL");
273 		return -EINVAL;
274 	}
275 
276 	CHECKIF(data == NULL) {
277 		LOG_DBG("data is NULL");
278 		return -EINVAL;
279 	}
280 
281 	return bt_audio_data_get_val(codec_cfg->data, codec_cfg->data_len, (uint8_t)type, data);
282 }
283 
bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_codec_cfg_type type,const uint8_t * data,size_t data_len)284 int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg,
285 			       enum bt_audio_codec_cfg_type type, const uint8_t *data,
286 			       size_t data_len)
287 {
288 	struct net_buf_simple buf;
289 	int ret;
290 
291 	CHECKIF(codec_cfg == NULL) {
292 		LOG_DBG("codec_cfg is NULL");
293 		return -EINVAL;
294 	}
295 
296 	CHECKIF(data == NULL) {
297 		LOG_DBG("data is NULL");
298 		return -EINVAL;
299 	}
300 
301 	CHECKIF(data_len == 0U || data_len > UINT8_MAX) {
302 		LOG_DBG("Invalid data_len %zu", data_len);
303 		return -EINVAL;
304 	}
305 
306 	init_net_buf_simple_from_codec_cfg(&buf, codec_cfg);
307 
308 	ret = ltv_set_val(&buf, type, data, data_len);
309 	if (ret >= 0) {
310 		codec_cfg->data_len = ret;
311 	}
312 
313 	return ret;
314 }
315 
bt_audio_codec_cfg_unset_val(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_codec_cfg_type type)316 int bt_audio_codec_cfg_unset_val(struct bt_audio_codec_cfg *codec_cfg,
317 				 enum bt_audio_codec_cfg_type type)
318 {
319 	struct net_buf_simple buf;
320 	int ret;
321 
322 	CHECKIF(codec_cfg == NULL) {
323 		LOG_DBG("codec_cfg is NULL");
324 		return -EINVAL;
325 	}
326 
327 	init_net_buf_simple_from_codec_cfg(&buf, codec_cfg);
328 
329 	ret = ltv_unset_val(&buf, type);
330 	if (ret >= 0) {
331 		codec_cfg->data_len = ret;
332 	}
333 
334 	return ret;
335 }
336 
bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg * codec_cfg)337 int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg)
338 {
339 	enum bt_audio_codec_cfg_freq freq;
340 	const uint8_t *data;
341 	uint8_t data_len;
342 
343 	CHECKIF(codec_cfg == NULL) {
344 		LOG_DBG("codec is NULL");
345 		return -EINVAL;
346 	}
347 
348 	data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CFG_FREQ, &data);
349 	if (data == NULL) {
350 		return -ENODATA;
351 	}
352 
353 	if (data_len != sizeof(uint8_t)) {
354 		return -EBADMSG;
355 	}
356 
357 	freq = data[0];
358 	if (bt_audio_codec_cfg_freq_to_freq_hz(freq) < 0) {
359 		LOG_DBG("Invalid freq value: 0x%02X", freq);
360 		return -EBADMSG;
361 	}
362 
363 	return freq;
364 }
365 
bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_codec_cfg_freq freq)366 int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg,
367 				enum bt_audio_codec_cfg_freq freq)
368 {
369 	uint8_t freq_u8;
370 
371 	if (bt_audio_codec_cfg_freq_to_freq_hz(freq) < 0) {
372 		LOG_DBG("Invalid freq value: %d", freq);
373 		return -EINVAL;
374 	}
375 
376 	freq_u8 = (uint8_t)freq;
377 
378 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CFG_FREQ, &freq_u8,
379 					  sizeof(freq_u8));
380 }
381 
bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg * codec_cfg)382 int bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg *codec_cfg)
383 {
384 	enum bt_audio_codec_cfg_frame_dur frame_dur;
385 	const uint8_t *data;
386 	uint8_t data_len;
387 
388 	CHECKIF(codec_cfg == NULL) {
389 		LOG_DBG("codec is NULL");
390 		return -EINVAL;
391 	}
392 
393 	data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CFG_DURATION, &data);
394 	if (data == NULL) {
395 		return -ENODATA;
396 	}
397 
398 	if (data_len != sizeof(uint8_t)) {
399 		return -EBADMSG;
400 	}
401 
402 	frame_dur = data[0];
403 	if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur) < 0) {
404 		LOG_DBG("Invalid frame_dur value: 0x%02X", frame_dur);
405 		return -EBADMSG;
406 	}
407 
408 	return frame_dur;
409 }
410 
bt_audio_codec_cfg_set_frame_dur(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_codec_cfg_frame_dur frame_dur)411 int bt_audio_codec_cfg_set_frame_dur(struct bt_audio_codec_cfg *codec_cfg,
412 				     enum bt_audio_codec_cfg_frame_dur frame_dur)
413 {
414 	uint8_t frame_dur_u8;
415 
416 	if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur) < 0) {
417 		LOG_DBG("Invalid freq value: %d", frame_dur);
418 		return -EINVAL;
419 	}
420 
421 	frame_dur_u8 = (uint8_t)frame_dur;
422 
423 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CFG_DURATION,
424 					  &frame_dur_u8, sizeof(frame_dur_u8));
425 }
426 
bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_location * chan_allocation,bool fallback_to_default)427 int bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg *codec_cfg,
428 					   enum bt_audio_location *chan_allocation,
429 					   bool fallback_to_default)
430 {
431 	const uint8_t *data;
432 	uint8_t data_len;
433 
434 	*chan_allocation = 0;
435 
436 	CHECKIF(codec_cfg == NULL) {
437 		LOG_DBG("codec is NULL");
438 		return -EINVAL;
439 	}
440 
441 	CHECKIF(chan_allocation == NULL) {
442 		return -EINVAL;
443 	}
444 
445 	data_len =
446 		bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CFG_CHAN_ALLOC, &data);
447 	if (data == NULL) {
448 		if (fallback_to_default && codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
449 			*chan_allocation = BT_AUDIO_LOCATION_MONO_AUDIO;
450 
451 			return 0;
452 		}
453 
454 		return -ENODATA;
455 	}
456 
457 	if (data_len != sizeof(uint32_t)) {
458 		return -EBADMSG;
459 	}
460 
461 	*chan_allocation = sys_get_le32(data);
462 
463 	return 0;
464 }
465 
bt_audio_codec_cfg_set_chan_allocation(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_location chan_allocation)466 int bt_audio_codec_cfg_set_chan_allocation(struct bt_audio_codec_cfg *codec_cfg,
467 					   enum bt_audio_location chan_allocation)
468 {
469 	uint32_t chan_allocation_u32;
470 
471 	if ((chan_allocation & BT_AUDIO_LOCATION_ANY) != chan_allocation) {
472 		LOG_DBG("Invalid chan_allocation value: 0x%08X", chan_allocation);
473 		return -EINVAL;
474 	}
475 
476 	chan_allocation_u32 = sys_cpu_to_le32((uint32_t)chan_allocation);
477 
478 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CFG_CHAN_ALLOC,
479 					  (const uint8_t *)&chan_allocation_u32,
480 					  sizeof(chan_allocation_u32));
481 }
482 
bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg * codec_cfg)483 int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *codec_cfg)
484 {
485 	const uint8_t *data;
486 	uint8_t data_len;
487 
488 	CHECKIF(codec_cfg == NULL) {
489 		LOG_DBG("codec is NULL");
490 		return -EINVAL;
491 	}
492 
493 	data_len =
494 		bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CFG_FRAME_LEN, &data);
495 	if (data == NULL) {
496 		return -ENODATA;
497 	}
498 
499 	if (data_len != sizeof(uint16_t)) {
500 		return -EBADMSG;
501 	}
502 
503 	return sys_get_le16(data);
504 }
505 
bt_audio_codec_cfg_set_octets_per_frame(struct bt_audio_codec_cfg * codec_cfg,uint16_t octets_per_frame)506 int bt_audio_codec_cfg_set_octets_per_frame(struct bt_audio_codec_cfg *codec_cfg,
507 					    uint16_t octets_per_frame)
508 {
509 	uint16_t octets_per_frame_le16;
510 
511 	octets_per_frame_le16 = sys_cpu_to_le16(octets_per_frame);
512 
513 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CFG_FRAME_LEN,
514 					  (uint8_t *)&octets_per_frame_le16,
515 					  sizeof(octets_per_frame_le16));
516 }
517 
bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg * codec_cfg,bool fallback_to_default)518 int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg,
519 						bool fallback_to_default)
520 {
521 	const uint8_t *data;
522 	uint8_t data_len;
523 
524 	CHECKIF(codec_cfg == NULL) {
525 		LOG_DBG("codec is NULL");
526 		return -EINVAL;
527 	}
528 
529 	data_len = bt_audio_codec_cfg_get_val(codec_cfg,
530 					      BT_AUDIO_CODEC_CFG_FRAME_BLKS_PER_SDU, &data);
531 	if (data == NULL) {
532 		if (fallback_to_default && codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
533 			return 1;
534 		}
535 
536 		return -ENODATA;
537 	}
538 
539 	if (data_len != sizeof(uint8_t)) {
540 		return -EBADMSG;
541 	}
542 
543 	return data[0];
544 }
545 
bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg * codec_cfg,uint8_t frame_blocks)546 int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec_cfg,
547 						uint8_t frame_blocks)
548 {
549 	return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CFG_FRAME_BLKS_PER_SDU,
550 					  &frame_blocks, sizeof(frame_blocks));
551 }
552 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
553 
554 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 ||                                             \
555 	CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0
556 
init_net_buf_simple_from_meta(struct net_buf_simple * buf,uint8_t meta[],size_t meta_len,size_t meta_size)557 static void init_net_buf_simple_from_meta(struct net_buf_simple *buf, uint8_t meta[],
558 					  size_t meta_len, size_t meta_size)
559 {
560 	buf->__buf = meta;
561 	buf->data = meta;
562 	buf->size = meta_size;
563 	buf->len = meta_len;
564 }
565 
codec_meta_get_val(const uint8_t meta[],size_t meta_len,enum bt_audio_metadata_type type,const uint8_t ** data)566 static int codec_meta_get_val(const uint8_t meta[], size_t meta_len,
567 			      enum bt_audio_metadata_type type, const uint8_t **data)
568 {
569 	CHECKIF(meta == NULL) {
570 		LOG_DBG("meta is NULL");
571 		return -EINVAL;
572 	}
573 
574 	CHECKIF(data == NULL) {
575 		LOG_DBG("data is NULL");
576 		return -EINVAL;
577 	}
578 
579 	return bt_audio_data_get_val(meta, meta_len, (uint8_t)type, data);
580 }
581 
codec_meta_set_val(uint8_t meta[],size_t meta_len,size_t meta_size,enum bt_audio_metadata_type type,const uint8_t * data,size_t data_len)582 static int codec_meta_set_val(uint8_t meta[], size_t meta_len, size_t meta_size,
583 			      enum bt_audio_metadata_type type, const uint8_t *data,
584 			      size_t data_len)
585 {
586 	struct net_buf_simple buf;
587 
588 	CHECKIF(meta == NULL) {
589 		LOG_DBG("meta is NULL");
590 		return -EINVAL;
591 	}
592 
593 	CHECKIF(data == NULL && data_len != 0) {
594 		LOG_DBG("data is NULL");
595 		return -EINVAL;
596 	}
597 
598 	CHECKIF(data_len > UINT8_MAX) {
599 		LOG_DBG("Invalid data_len %zu", data_len);
600 		return -EINVAL;
601 	}
602 
603 	init_net_buf_simple_from_meta(&buf, meta, meta_len, meta_size);
604 
605 	return ltv_set_val(&buf, (uint8_t)type, data, data_len);
606 }
607 
codec_meta_unset_val(uint8_t meta[],size_t meta_len,size_t meta_size,enum bt_audio_metadata_type type)608 static int codec_meta_unset_val(uint8_t meta[], size_t meta_len, size_t meta_size,
609 				enum bt_audio_metadata_type type)
610 {
611 	struct net_buf_simple buf;
612 
613 	CHECKIF(meta == NULL) {
614 		LOG_DBG("meta is NULL");
615 		return -EINVAL;
616 	}
617 
618 	init_net_buf_simple_from_meta(&buf, meta, meta_len, meta_size);
619 
620 	return ltv_unset_val(&buf, type);
621 }
622 
codec_meta_get_pref_context(const uint8_t meta[],size_t meta_len)623 static int codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len)
624 {
625 	const uint8_t *data;
626 	int ret;
627 
628 	CHECKIF(meta == NULL) {
629 		LOG_DBG("meta is NULL");
630 		return -EINVAL;
631 	}
632 
633 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, &data);
634 	if (data == NULL) {
635 		return -ENODATA;
636 	}
637 
638 	if (ret != sizeof(uint16_t)) {
639 		return -EBADMSG;
640 	}
641 
642 	return sys_get_le16(data);
643 }
644 
codec_meta_set_pref_context(uint8_t meta[],size_t meta_len,size_t meta_size,enum bt_audio_context ctx)645 static int codec_meta_set_pref_context(uint8_t meta[], size_t meta_len, size_t meta_size,
646 				       enum bt_audio_context ctx)
647 {
648 	uint16_t ctx_le16;
649 
650 	CHECKIF(meta == NULL) {
651 		LOG_DBG("meta is NULL");
652 		return -EINVAL;
653 	}
654 
655 	if ((ctx & BT_AUDIO_CONTEXT_TYPE_ANY) != ctx) {
656 		LOG_DBG("Invalid ctx value: %d", ctx);
657 		return -EINVAL;
658 	}
659 
660 	ctx_le16 = sys_cpu_to_le16((uint16_t)ctx);
661 
662 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT,
663 				  (const uint8_t *)&ctx_le16, sizeof(ctx_le16));
664 }
665 
codec_meta_get_stream_context(const uint8_t meta[],size_t meta_len)666 static int codec_meta_get_stream_context(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_STREAM_CONTEXT, &data);
677 	if (data == NULL) {
678 		return -ENODATA;
679 	}
680 
681 	if (ret != sizeof(uint16_t)) {
682 		return -EBADMSG;
683 	}
684 
685 	return sys_get_le16(data);
686 }
687 
codec_meta_set_stream_context(uint8_t meta[],size_t meta_len,size_t meta_size,enum bt_audio_context ctx)688 static int codec_meta_set_stream_context(uint8_t meta[], size_t meta_len, size_t meta_size,
689 					 enum bt_audio_context ctx)
690 {
691 	uint16_t ctx_le16;
692 
693 	CHECKIF(meta == NULL) {
694 		LOG_DBG("meta is NULL");
695 		return -EINVAL;
696 	}
697 
698 	if ((ctx & BT_AUDIO_CONTEXT_TYPE_ANY) != ctx) {
699 		LOG_DBG("Invalid ctx value: %d", ctx);
700 		return -EINVAL;
701 	}
702 
703 	ctx_le16 = sys_cpu_to_le16((uint16_t)ctx);
704 
705 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT,
706 				  (const uint8_t *)&ctx_le16, sizeof(ctx_le16));
707 }
708 
codec_meta_get_program_info(const uint8_t meta[],size_t meta_len,const uint8_t ** program_info)709 static int codec_meta_get_program_info(const uint8_t meta[], size_t meta_len,
710 				       const uint8_t **program_info)
711 {
712 	const uint8_t *data;
713 	int ret;
714 
715 	CHECKIF(meta == NULL) {
716 		LOG_DBG("meta is NULL");
717 		return -EINVAL;
718 	}
719 
720 	CHECKIF(program_info == NULL) {
721 		LOG_DBG("program_info is NULL");
722 		return -EINVAL;
723 	}
724 
725 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, &data);
726 	if (data == NULL) {
727 		return -ENODATA;
728 	}
729 
730 	*program_info = data;
731 
732 	return ret;
733 }
734 
codec_meta_set_program_info(uint8_t meta[],size_t meta_len,size_t meta_size,const uint8_t * program_info,size_t program_info_len)735 static int codec_meta_set_program_info(uint8_t meta[], size_t meta_len, size_t meta_size,
736 				       const uint8_t *program_info, size_t program_info_len)
737 {
738 	CHECKIF(meta == NULL) {
739 		LOG_DBG("meta is NULL");
740 		return -EINVAL;
741 	}
742 
743 	CHECKIF(program_info == NULL) {
744 		LOG_DBG("meta is NULL");
745 		return -EINVAL;
746 	}
747 
748 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO,
749 				  program_info, program_info_len);
750 }
751 
codec_meta_get_lang(const uint8_t meta[],size_t meta_len,const uint8_t ** lang)752 static int codec_meta_get_lang(const uint8_t meta[], size_t meta_len, const uint8_t **lang)
753 {
754 	const uint8_t *data;
755 	int ret;
756 
757 	CHECKIF(meta == NULL) {
758 		LOG_DBG("meta is NULL");
759 		return -EINVAL;
760 	}
761 
762 	CHECKIF(lang == NULL) {
763 		LOG_DBG("lang is NULL");
764 		return -EINVAL;
765 	}
766 
767 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_LANG, &data);
768 	if (data == NULL) {
769 		return -ENODATA;
770 	}
771 
772 	if (ret != BT_AUDIO_LANG_SIZE) {
773 		return -EBADMSG;
774 	}
775 
776 	*lang = data;
777 
778 	return 0;
779 }
780 
codec_meta_set_lang(uint8_t meta[],size_t meta_len,size_t meta_size,const uint8_t lang[BT_AUDIO_LANG_SIZE])781 static int codec_meta_set_lang(uint8_t meta[], size_t meta_len, size_t meta_size,
782 			       const uint8_t lang[BT_AUDIO_LANG_SIZE])
783 {
784 	CHECKIF(meta == NULL) {
785 		LOG_DBG("meta is NULL");
786 		return -EINVAL;
787 	}
788 
789 	CHECKIF(lang == NULL) {
790 		LOG_DBG("lang is NULL");
791 		return -EINVAL;
792 	}
793 
794 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_LANG, lang,
795 				  BT_AUDIO_LANG_SIZE);
796 }
797 
codec_meta_get_ccid_list(const uint8_t meta[],size_t meta_len,const uint8_t ** ccid_list)798 static int codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len,
799 				    const uint8_t **ccid_list)
800 {
801 	const uint8_t *data;
802 	int ret;
803 
804 	CHECKIF(meta == NULL) {
805 		LOG_DBG("meta is NULL");
806 		return -EINVAL;
807 	}
808 
809 	CHECKIF(ccid_list == NULL) {
810 		LOG_DBG("ccid_list is NULL");
811 		return -EINVAL;
812 	}
813 
814 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_CCID_LIST, &data);
815 	if (data == NULL) {
816 		return -ENODATA;
817 	}
818 
819 	*ccid_list = data;
820 
821 	return ret;
822 }
823 
codec_meta_set_ccid_list(uint8_t meta[],size_t meta_len,size_t meta_size,const uint8_t * ccid_list,size_t ccid_list_len)824 static int codec_meta_set_ccid_list(uint8_t meta[], size_t meta_len, size_t meta_size,
825 				    const uint8_t *ccid_list, size_t ccid_list_len)
826 {
827 	CHECKIF(meta == NULL) {
828 		LOG_DBG("meta is NULL");
829 		return -EINVAL;
830 	}
831 
832 	CHECKIF(ccid_list == NULL) {
833 		LOG_DBG("ccid_list is NULL");
834 		return -EINVAL;
835 	}
836 
837 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_CCID_LIST,
838 				  ccid_list, ccid_list_len);
839 }
840 
codec_meta_get_parental_rating(const uint8_t meta[],size_t meta_len)841 static int codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len)
842 {
843 	const uint8_t *data;
844 	int ret;
845 
846 	CHECKIF(meta == NULL) {
847 		LOG_DBG("meta is NULL");
848 		return -EINVAL;
849 	}
850 
851 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, &data);
852 	if (data == NULL) {
853 		return -ENODATA;
854 	}
855 
856 	if (ret != sizeof(uint8_t)) {
857 		return -EBADMSG;
858 	}
859 
860 	return data[0];
861 }
862 
codec_meta_set_parental_rating(uint8_t meta[],size_t meta_len,size_t meta_size,enum bt_audio_parental_rating parental_rating)863 static int codec_meta_set_parental_rating(uint8_t meta[], size_t meta_len, size_t meta_size,
864 					  enum bt_audio_parental_rating parental_rating)
865 {
866 	uint8_t parental_rating_u8;
867 
868 	CHECKIF(meta == NULL) {
869 		LOG_DBG("meta is NULL");
870 		return -EINVAL;
871 	}
872 
873 	if (parental_rating > BT_AUDIO_PARENTAL_RATING_AGE_18_OR_ABOVE) {
874 		LOG_DBG("Invalid parental_rating value: %d", parental_rating);
875 		return -EINVAL;
876 	}
877 
878 	parental_rating_u8 = (uint8_t)parental_rating;
879 
880 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING,
881 				  &parental_rating_u8, sizeof(parental_rating_u8));
882 }
883 
codec_meta_get_program_info_uri(const uint8_t meta[],size_t meta_len,const uint8_t ** program_info_uri)884 static int codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len,
885 					   const uint8_t **program_info_uri)
886 {
887 	const uint8_t *data;
888 	int ret;
889 
890 	CHECKIF(meta == NULL) {
891 		LOG_DBG("meta is NULL");
892 		return -EINVAL;
893 	}
894 
895 	CHECKIF(program_info_uri == NULL) {
896 		LOG_DBG("program_info_uri is NULL");
897 		return -EINVAL;
898 	}
899 
900 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, &data);
901 	if (data == NULL) {
902 		return -ENODATA;
903 	}
904 
905 	*program_info_uri = data;
906 
907 	return ret;
908 }
909 
codec_meta_set_program_info_uri(uint8_t meta[],size_t meta_len,size_t meta_size,const uint8_t * program_info_uri,size_t program_info_uri_len)910 static int codec_meta_set_program_info_uri(uint8_t meta[], size_t meta_len, size_t meta_size,
911 					   const uint8_t *program_info_uri,
912 					   size_t program_info_uri_len)
913 {
914 	CHECKIF(meta == NULL) {
915 		LOG_DBG("meta is NULL");
916 		return -EINVAL;
917 	}
918 
919 	CHECKIF(program_info_uri == NULL) {
920 		LOG_DBG("program_info_uri is NULL");
921 		return -EINVAL;
922 	}
923 
924 	return codec_meta_set_val(meta, meta_len, meta_size,
925 				  BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, program_info_uri,
926 				  program_info_uri_len);
927 }
928 
codec_meta_get_audio_active_state(const uint8_t meta[],size_t meta_len)929 static int codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len)
930 {
931 	const uint8_t *data;
932 	int ret;
933 
934 	CHECKIF(meta == NULL) {
935 		LOG_DBG("meta is NULL");
936 		return -EINVAL;
937 	}
938 
939 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_AUDIO_STATE, &data);
940 	if (data == NULL) {
941 		return -ENODATA;
942 	}
943 
944 	if (ret != sizeof(uint8_t)) {
945 		return -EBADMSG;
946 	}
947 
948 	return data[0];
949 }
950 
codec_meta_set_audio_active_state(uint8_t meta[],size_t meta_len,size_t meta_size,enum bt_audio_active_state state)951 static int codec_meta_set_audio_active_state(uint8_t meta[], size_t meta_len, size_t meta_size,
952 					     enum bt_audio_active_state state)
953 {
954 	uint8_t state_u8;
955 
956 	CHECKIF(meta == NULL) {
957 		LOG_DBG("meta is NULL");
958 		return -EINVAL;
959 	}
960 
961 	if (state != BT_AUDIO_ACTIVE_STATE_DISABLED && state != BT_AUDIO_ACTIVE_STATE_ENABLED) {
962 		LOG_DBG("Invalid state value: %d", state);
963 		return -EINVAL;
964 	}
965 
966 	state_u8 = (uint8_t)state;
967 
968 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_AUDIO_STATE,
969 				  &state_u8, sizeof(state_u8));
970 }
971 
codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[],size_t meta_len)972 static int codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[], size_t meta_len)
973 {
974 	const uint8_t *data;
975 
976 	CHECKIF(meta == NULL) {
977 		LOG_DBG("meta is NULL");
978 		return -EINVAL;
979 	}
980 
981 	return codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE,
982 				  &data);
983 }
984 
codec_meta_set_bcast_audio_immediate_rend_flag(uint8_t meta[],size_t meta_len,size_t meta_size)985 static int codec_meta_set_bcast_audio_immediate_rend_flag(uint8_t meta[], size_t meta_len,
986 							  size_t meta_size)
987 {
988 	CHECKIF(meta == NULL) {
989 		LOG_DBG("meta is NULL");
990 		return -EINVAL;
991 	}
992 
993 	return codec_meta_set_val(meta, meta_len, meta_size,
994 				  BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE, NULL, 0);
995 }
996 
codec_meta_get_assisted_listening_stream(const uint8_t meta[],size_t meta_len)997 static int codec_meta_get_assisted_listening_stream(const uint8_t meta[], size_t meta_len)
998 {
999 	const uint8_t *data;
1000 	int ret;
1001 
1002 	CHECKIF(meta == NULL) {
1003 		LOG_DBG("meta is NULL");
1004 		return -EINVAL;
1005 	}
1006 
1007 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_ASSISTED_LISTENING_STREAM,
1008 				 &data);
1009 	if (data == NULL) {
1010 		return -ENODATA;
1011 	}
1012 
1013 	if (ret != sizeof(uint8_t)) {
1014 		return -EBADMSG;
1015 	}
1016 
1017 	return data[0];
1018 }
1019 
codec_meta_set_assisted_listening_stream(uint8_t meta[],size_t meta_len,size_t meta_size,enum bt_audio_assisted_listening_stream val)1020 static int codec_meta_set_assisted_listening_stream(uint8_t meta[], size_t meta_len,
1021 						    size_t meta_size,
1022 						    enum bt_audio_assisted_listening_stream val)
1023 {
1024 	uint8_t val_u8;
1025 
1026 	CHECKIF(meta == NULL) {
1027 		LOG_DBG("meta is NULL");
1028 		return -EINVAL;
1029 	}
1030 
1031 	if (val != BT_AUDIO_ASSISTED_LISTENING_STREAM_UNSPECIFIED) {
1032 		LOG_DBG("Invalid value: %d", val);
1033 		return -EINVAL;
1034 	}
1035 
1036 	val_u8 = (uint8_t)val;
1037 
1038 	return codec_meta_set_val(meta, meta_len, meta_size,
1039 				  BT_AUDIO_METADATA_TYPE_ASSISTED_LISTENING_STREAM, &val_u8,
1040 				  sizeof(val_u8));
1041 }
1042 
codec_meta_get_broadcast_name(const uint8_t meta[],size_t meta_len,const uint8_t ** broadcast_name)1043 static int codec_meta_get_broadcast_name(const uint8_t meta[], size_t meta_len,
1044 					 const uint8_t **broadcast_name)
1045 {
1046 	const uint8_t *data;
1047 	int ret;
1048 
1049 	CHECKIF(meta == NULL) {
1050 		LOG_DBG("meta is NULL");
1051 		return -EINVAL;
1052 	}
1053 
1054 	CHECKIF(broadcast_name == NULL) {
1055 		LOG_DBG("broadcast_name is NULL");
1056 		return -EINVAL;
1057 	}
1058 
1059 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_BROADCAST_NAME, &data);
1060 	if (data == NULL) {
1061 		return -ENODATA;
1062 	}
1063 
1064 	*broadcast_name = data;
1065 
1066 	return ret;
1067 }
1068 
codec_meta_set_broadcast_name(uint8_t meta[],size_t meta_len,size_t meta_size,const uint8_t * broadcast_name,size_t broadcast_name_len)1069 static int codec_meta_set_broadcast_name(uint8_t meta[], size_t meta_len, size_t meta_size,
1070 					 const uint8_t *broadcast_name, size_t broadcast_name_len)
1071 {
1072 	CHECKIF(meta == NULL) {
1073 		LOG_DBG("meta is NULL");
1074 		return -EINVAL;
1075 	}
1076 
1077 	CHECKIF(broadcast_name == NULL) {
1078 		LOG_DBG("broadcast_name is NULL");
1079 		return -EINVAL;
1080 	}
1081 
1082 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_BROADCAST_NAME,
1083 				  broadcast_name, broadcast_name_len);
1084 }
1085 
codec_meta_get_extended(const uint8_t meta[],size_t meta_len,const uint8_t ** extended_meta)1086 static int codec_meta_get_extended(const uint8_t meta[], size_t meta_len,
1087 				   const uint8_t **extended_meta)
1088 {
1089 	const uint8_t *data;
1090 	int ret;
1091 
1092 	CHECKIF(meta == NULL) {
1093 		LOG_DBG("meta is NULL");
1094 		return -EINVAL;
1095 	}
1096 
1097 	CHECKIF(extended_meta == NULL) {
1098 		LOG_DBG("extended_meta is NULL");
1099 		return -EINVAL;
1100 	}
1101 
1102 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_EXTENDED, &data);
1103 	if (data == NULL) {
1104 		return -ENODATA;
1105 	}
1106 
1107 	*extended_meta = data;
1108 
1109 	return ret;
1110 }
1111 
codec_meta_set_extended(uint8_t meta[],size_t meta_len,size_t meta_size,const uint8_t * extended,size_t extended_len)1112 static int codec_meta_set_extended(uint8_t meta[], size_t meta_len, size_t meta_size,
1113 				   const uint8_t *extended, size_t extended_len)
1114 {
1115 	CHECKIF(meta == NULL) {
1116 		LOG_DBG("meta is NULL");
1117 		return -EINVAL;
1118 	}
1119 
1120 	CHECKIF(extended == NULL) {
1121 		LOG_DBG("extended is NULL");
1122 		return -EINVAL;
1123 	}
1124 
1125 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_EXTENDED,
1126 				  extended, extended_len);
1127 }
1128 
codec_meta_get_vendor(const uint8_t meta[],size_t meta_len,const uint8_t ** vendor_meta)1129 static int codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, const uint8_t **vendor_meta)
1130 {
1131 	const uint8_t *data;
1132 	int ret;
1133 
1134 	CHECKIF(meta == NULL) {
1135 		LOG_DBG("meta is NULL");
1136 		return -EINVAL;
1137 	}
1138 
1139 	CHECKIF(vendor_meta == NULL) {
1140 		LOG_DBG("vendor_meta is NULL");
1141 		return -EINVAL;
1142 	}
1143 
1144 	ret = codec_meta_get_val(meta, meta_len, BT_AUDIO_METADATA_TYPE_VENDOR, &data);
1145 	if (data == NULL) {
1146 		return -ENODATA;
1147 	}
1148 
1149 	*vendor_meta = data;
1150 
1151 	return ret;
1152 }
1153 
codec_meta_set_vendor(uint8_t meta[],size_t meta_len,size_t meta_size,const uint8_t * vendor,size_t vendor_len)1154 static int codec_meta_set_vendor(uint8_t meta[], size_t meta_len, size_t meta_size,
1155 				 const uint8_t *vendor, size_t vendor_len)
1156 {
1157 	CHECKIF(meta == NULL) {
1158 		LOG_DBG("meta is NULL");
1159 		return -EINVAL;
1160 	}
1161 
1162 	CHECKIF(vendor == NULL) {
1163 		LOG_DBG("vendor is NULL");
1164 		return -EINVAL;
1165 	}
1166 
1167 	return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_VENDOR, vendor,
1168 				  vendor_len);
1169 }
1170 
1171 #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)1172 int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type,
1173 				    const uint8_t **data)
1174 {
1175 	CHECKIF(codec_cfg == NULL) {
1176 		LOG_DBG("codec_cfg is NULL");
1177 		return -EINVAL;
1178 	}
1179 
1180 	return codec_meta_get_val(codec_cfg->meta, codec_cfg->meta_len, type, data);
1181 }
1182 
bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_metadata_type type,const uint8_t * data,size_t data_len)1183 int bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg *codec_cfg,
1184 				    enum bt_audio_metadata_type type, const uint8_t *data,
1185 				    size_t data_len)
1186 {
1187 	int ret;
1188 
1189 	CHECKIF(codec_cfg == NULL) {
1190 		LOG_DBG("codec_cfg is NULL");
1191 		return -EINVAL;
1192 	}
1193 
1194 	ret = codec_meta_set_val(codec_cfg->meta, codec_cfg->meta_len, ARRAY_SIZE(codec_cfg->meta),
1195 				 type, data, data_len);
1196 	if (ret >= 0) {
1197 		codec_cfg->meta_len = ret;
1198 	}
1199 
1200 	return ret;
1201 }
1202 
bt_audio_codec_cfg_meta_unset_val(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_metadata_type type)1203 int bt_audio_codec_cfg_meta_unset_val(struct bt_audio_codec_cfg *codec_cfg,
1204 				      enum bt_audio_metadata_type type)
1205 {
1206 	int ret;
1207 
1208 	CHECKIF(codec_cfg == NULL) {
1209 		LOG_DBG("codec_cfg is NULL");
1210 		return -EINVAL;
1211 	}
1212 
1213 	ret = codec_meta_unset_val(codec_cfg->meta, codec_cfg->meta_len,
1214 				   ARRAY_SIZE(codec_cfg->meta), type);
1215 	if (ret >= 0) {
1216 		codec_cfg->meta_len = ret;
1217 	}
1218 
1219 	return ret;
1220 }
1221 
bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg * codec_cfg,bool fallback_to_default)1222 int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg,
1223 					     bool fallback_to_default)
1224 {
1225 	int ret;
1226 
1227 	CHECKIF(codec_cfg == NULL) {
1228 		LOG_DBG("codec_cfg is NULL");
1229 		return -EINVAL;
1230 	}
1231 
1232 	ret = codec_meta_get_pref_context(codec_cfg->meta, codec_cfg->meta_len);
1233 
1234 	if (ret == -ENODATA && fallback_to_default && codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
1235 		return BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED;
1236 	}
1237 
1238 	return ret;
1239 }
1240 
bt_audio_codec_cfg_meta_set_pref_context(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_context ctx)1241 int bt_audio_codec_cfg_meta_set_pref_context(struct bt_audio_codec_cfg *codec_cfg,
1242 					     enum bt_audio_context ctx)
1243 {
1244 	int ret;
1245 
1246 	ret = codec_meta_set_pref_context(codec_cfg->meta, codec_cfg->meta_len,
1247 					  ARRAY_SIZE(codec_cfg->meta), ctx);
1248 	if (ret >= 0) {
1249 		codec_cfg->meta_len = ret;
1250 	}
1251 
1252 	return ret;
1253 }
1254 
bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg * codec_cfg)1255 int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg *codec_cfg)
1256 {
1257 	CHECKIF(codec_cfg == NULL) {
1258 		LOG_DBG("codec_cfg is NULL");
1259 		return -EINVAL;
1260 	}
1261 
1262 	return codec_meta_get_stream_context(codec_cfg->meta, codec_cfg->meta_len);
1263 }
1264 
bt_audio_codec_cfg_meta_set_stream_context(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_context ctx)1265 int bt_audio_codec_cfg_meta_set_stream_context(struct bt_audio_codec_cfg *codec_cfg,
1266 					       enum bt_audio_context ctx)
1267 {
1268 	int ret;
1269 
1270 	ret = codec_meta_set_stream_context(codec_cfg->meta, codec_cfg->meta_len,
1271 					    ARRAY_SIZE(codec_cfg->meta), ctx);
1272 	if (ret >= 0) {
1273 		codec_cfg->meta_len = ret;
1274 	}
1275 
1276 	return ret;
1277 }
1278 
bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** program_info)1279 int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *codec_cfg,
1280 					     const uint8_t **program_info)
1281 {
1282 	CHECKIF(codec_cfg == NULL) {
1283 		LOG_DBG("codec_cfg is NULL");
1284 		return -EINVAL;
1285 	}
1286 
1287 	return codec_meta_get_program_info(codec_cfg->meta, codec_cfg->meta_len, program_info);
1288 }
1289 
bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg * codec_cfg,const uint8_t * program_info,size_t program_info_len)1290 int bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg *codec_cfg,
1291 					     const uint8_t *program_info, size_t program_info_len)
1292 {
1293 	int ret;
1294 
1295 	ret = codec_meta_set_program_info(codec_cfg->meta, codec_cfg->meta_len,
1296 					  ARRAY_SIZE(codec_cfg->meta), program_info,
1297 					  program_info_len);
1298 	if (ret >= 0) {
1299 		codec_cfg->meta_len = ret;
1300 	}
1301 
1302 	return ret;
1303 }
1304 
bt_audio_codec_cfg_meta_get_lang(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** lang)1305 int bt_audio_codec_cfg_meta_get_lang(const struct bt_audio_codec_cfg *codec_cfg,
1306 				     const uint8_t **lang)
1307 {
1308 	CHECKIF(codec_cfg == NULL) {
1309 		LOG_DBG("codec_cfg is NULL");
1310 		return -EINVAL;
1311 	}
1312 
1313 	return codec_meta_get_lang(codec_cfg->meta, codec_cfg->meta_len, lang);
1314 }
1315 
bt_audio_codec_cfg_meta_set_lang(struct bt_audio_codec_cfg * codec_cfg,const uint8_t lang[BT_AUDIO_LANG_SIZE])1316 int bt_audio_codec_cfg_meta_set_lang(struct bt_audio_codec_cfg *codec_cfg,
1317 				     const uint8_t lang[BT_AUDIO_LANG_SIZE])
1318 {
1319 	int ret;
1320 
1321 	ret = codec_meta_set_lang(codec_cfg->meta, codec_cfg->meta_len, ARRAY_SIZE(codec_cfg->meta),
1322 				  lang);
1323 	if (ret >= 0) {
1324 		codec_cfg->meta_len = ret;
1325 	}
1326 
1327 	return ret;
1328 }
1329 
bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** ccid_list)1330 int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec_cfg,
1331 					  const uint8_t **ccid_list)
1332 {
1333 	CHECKIF(codec_cfg == NULL) {
1334 		LOG_DBG("codec_cfg is NULL");
1335 		return -EINVAL;
1336 	}
1337 
1338 	return codec_meta_get_ccid_list(codec_cfg->meta, codec_cfg->meta_len, ccid_list);
1339 }
1340 
bt_audio_codec_cfg_meta_set_ccid_list(struct bt_audio_codec_cfg * codec_cfg,const uint8_t * ccid_list,size_t ccid_list_len)1341 int bt_audio_codec_cfg_meta_set_ccid_list(struct bt_audio_codec_cfg *codec_cfg,
1342 					  const uint8_t *ccid_list, size_t ccid_list_len)
1343 {
1344 	int ret;
1345 
1346 	ret = codec_meta_set_ccid_list(codec_cfg->meta, codec_cfg->meta_len,
1347 				       ARRAY_SIZE(codec_cfg->meta), ccid_list, ccid_list_len);
1348 	if (ret >= 0) {
1349 		codec_cfg->meta_len = ret;
1350 	}
1351 
1352 	return ret;
1353 }
1354 
bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg * codec_cfg)1355 int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg *codec_cfg)
1356 {
1357 	CHECKIF(codec_cfg == NULL) {
1358 		LOG_DBG("codec_cfg is NULL");
1359 		return -EINVAL;
1360 	}
1361 
1362 	return codec_meta_get_parental_rating(codec_cfg->meta, codec_cfg->meta_len);
1363 }
1364 
bt_audio_codec_cfg_meta_set_parental_rating(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_parental_rating parental_rating)1365 int bt_audio_codec_cfg_meta_set_parental_rating(struct bt_audio_codec_cfg *codec_cfg,
1366 						enum bt_audio_parental_rating parental_rating)
1367 {
1368 	int ret;
1369 
1370 	ret = codec_meta_set_parental_rating(codec_cfg->meta, codec_cfg->meta_len,
1371 					     ARRAY_SIZE(codec_cfg->meta), parental_rating);
1372 	if (ret >= 0) {
1373 		codec_cfg->meta_len = ret;
1374 	}
1375 
1376 	return ret;
1377 }
1378 
bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** program_info_uri)1379 int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg *codec_cfg,
1380 						 const uint8_t **program_info_uri)
1381 {
1382 	CHECKIF(codec_cfg == NULL) {
1383 		LOG_DBG("codec_cfg is NULL");
1384 		return -EINVAL;
1385 	}
1386 
1387 	return codec_meta_get_program_info_uri(codec_cfg->meta, codec_cfg->meta_len,
1388 					       program_info_uri);
1389 }
1390 
bt_audio_codec_cfg_meta_set_program_info_uri(struct bt_audio_codec_cfg * codec_cfg,const uint8_t * program_info_uri,size_t program_info_uri_len)1391 int bt_audio_codec_cfg_meta_set_program_info_uri(struct bt_audio_codec_cfg *codec_cfg,
1392 						 const uint8_t *program_info_uri,
1393 						 size_t program_info_uri_len)
1394 {
1395 	int ret;
1396 
1397 	ret = codec_meta_set_program_info_uri(codec_cfg->meta, codec_cfg->meta_len,
1398 					      ARRAY_SIZE(codec_cfg->meta), program_info_uri,
1399 					      program_info_uri_len);
1400 	if (ret >= 0) {
1401 		codec_cfg->meta_len = ret;
1402 	}
1403 
1404 	return ret;
1405 }
1406 
bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg * codec_cfg)1407 int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg *codec_cfg)
1408 {
1409 	CHECKIF(codec_cfg == NULL) {
1410 		LOG_DBG("codec_cfg is NULL");
1411 		return -EINVAL;
1412 	}
1413 
1414 	return codec_meta_get_audio_active_state(codec_cfg->meta, codec_cfg->meta_len);
1415 }
1416 
bt_audio_codec_cfg_meta_set_audio_active_state(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_active_state state)1417 int bt_audio_codec_cfg_meta_set_audio_active_state(struct bt_audio_codec_cfg *codec_cfg,
1418 						   enum bt_audio_active_state state)
1419 {
1420 	int ret;
1421 
1422 	ret = codec_meta_set_audio_active_state(codec_cfg->meta, codec_cfg->meta_len,
1423 						ARRAY_SIZE(codec_cfg->meta), state);
1424 	if (ret >= 0) {
1425 		codec_cfg->meta_len = ret;
1426 	}
1427 
1428 	return ret;
1429 }
1430 
bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(const struct bt_audio_codec_cfg * codec_cfg)1431 int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(
1432 	const struct bt_audio_codec_cfg *codec_cfg)
1433 {
1434 	CHECKIF(codec_cfg == NULL) {
1435 		LOG_DBG("codec_cfg is NULL");
1436 		return -EINVAL;
1437 	}
1438 
1439 	return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cfg->meta, codec_cfg->meta_len);
1440 }
1441 
bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag(struct bt_audio_codec_cfg * codec_cfg)1442 int bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag(
1443 	struct bt_audio_codec_cfg *codec_cfg)
1444 {
1445 	int ret;
1446 
1447 	ret = codec_meta_set_bcast_audio_immediate_rend_flag(codec_cfg->meta, codec_cfg->meta_len,
1448 							     ARRAY_SIZE(codec_cfg->meta));
1449 	if (ret >= 0) {
1450 		codec_cfg->meta_len = ret;
1451 	}
1452 
1453 	return ret;
1454 }
1455 
bt_audio_codec_cfg_meta_get_assisted_listening_stream(const struct bt_audio_codec_cfg * codec_cfg)1456 int bt_audio_codec_cfg_meta_get_assisted_listening_stream(
1457 	const struct bt_audio_codec_cfg *codec_cfg)
1458 {
1459 	CHECKIF(codec_cfg == NULL) {
1460 		LOG_DBG("codec_cfg is NULL");
1461 		return -EINVAL;
1462 	}
1463 
1464 	return codec_meta_get_assisted_listening_stream(codec_cfg->meta, codec_cfg->meta_len);
1465 }
1466 
bt_audio_codec_cfg_meta_set_assisted_listening_stream(struct bt_audio_codec_cfg * codec_cfg,enum bt_audio_assisted_listening_stream val)1467 int bt_audio_codec_cfg_meta_set_assisted_listening_stream(
1468 	struct bt_audio_codec_cfg *codec_cfg, enum bt_audio_assisted_listening_stream val)
1469 {
1470 	int ret;
1471 
1472 	ret = codec_meta_set_assisted_listening_stream(codec_cfg->meta, codec_cfg->meta_len,
1473 						       ARRAY_SIZE(codec_cfg->meta), val);
1474 	if (ret >= 0) {
1475 		codec_cfg->meta_len = ret;
1476 	}
1477 
1478 	return ret;
1479 }
1480 
bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** extended_meta)1481 int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_cfg,
1482 					 const uint8_t **extended_meta)
1483 {
1484 	CHECKIF(codec_cfg == NULL) {
1485 		LOG_DBG("codec_cfg is NULL");
1486 		return -EINVAL;
1487 	}
1488 
1489 	return codec_meta_get_extended(codec_cfg->meta, codec_cfg->meta_len, extended_meta);
1490 }
1491 
bt_audio_codec_cfg_meta_set_extended(struct bt_audio_codec_cfg * codec_cfg,const uint8_t * extended_meta,size_t extended_meta_len)1492 int bt_audio_codec_cfg_meta_set_extended(struct bt_audio_codec_cfg *codec_cfg,
1493 					 const uint8_t *extended_meta, size_t extended_meta_len)
1494 {
1495 	int ret;
1496 
1497 	ret = codec_meta_set_extended(codec_cfg->meta, codec_cfg->meta_len,
1498 				      ARRAY_SIZE(codec_cfg->meta), extended_meta,
1499 				      extended_meta_len);
1500 	if (ret >= 0) {
1501 		codec_cfg->meta_len = ret;
1502 	}
1503 
1504 	return ret;
1505 }
1506 
bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** vendor_meta)1507 int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cfg,
1508 				       const uint8_t **vendor_meta)
1509 {
1510 	CHECKIF(codec_cfg == NULL) {
1511 		LOG_DBG("codec_cfg is NULL");
1512 		return -EINVAL;
1513 	}
1514 
1515 	return codec_meta_get_vendor(codec_cfg->meta, codec_cfg->meta_len, vendor_meta);
1516 }
1517 
bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg * codec_cfg,const uint8_t * vendor_meta,size_t vendor_meta_len)1518 int bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg *codec_cfg,
1519 				       const uint8_t *vendor_meta, size_t vendor_meta_len)
1520 {
1521 	int ret;
1522 
1523 	ret = codec_meta_set_vendor(codec_cfg->meta, codec_cfg->meta_len,
1524 				    ARRAY_SIZE(codec_cfg->meta), vendor_meta, vendor_meta_len);
1525 	if (ret >= 0) {
1526 		codec_cfg->meta_len = ret;
1527 	}
1528 
1529 	return ret;
1530 }
1531 
bt_audio_codec_cfg_meta_get_broadcast_name(const struct bt_audio_codec_cfg * codec_cfg,const uint8_t ** broadcast_name)1532 int bt_audio_codec_cfg_meta_get_broadcast_name(const struct bt_audio_codec_cfg *codec_cfg,
1533 					       const uint8_t **broadcast_name)
1534 {
1535 	CHECKIF(codec_cfg == NULL) {
1536 		LOG_DBG("codec_cfg is NULL");
1537 		return -EINVAL;
1538 	}
1539 
1540 	return codec_meta_get_broadcast_name(codec_cfg->meta, codec_cfg->meta_len, broadcast_name);
1541 }
1542 
bt_audio_codec_cfg_meta_set_broadcast_name(struct bt_audio_codec_cfg * codec_cfg,const uint8_t * broadcast_name,size_t broadcast_name_len)1543 int bt_audio_codec_cfg_meta_set_broadcast_name(struct bt_audio_codec_cfg *codec_cfg,
1544 					       const uint8_t *broadcast_name,
1545 					       size_t broadcast_name_len)
1546 {
1547 	int ret;
1548 
1549 	ret = codec_meta_set_broadcast_name(codec_cfg->meta, codec_cfg->meta_len,
1550 					    ARRAY_SIZE(codec_cfg->meta), broadcast_name,
1551 					    broadcast_name_len);
1552 	if (ret >= 0) {
1553 		codec_cfg->meta_len = ret;
1554 	}
1555 
1556 	return ret;
1557 }
1558 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
1559 
1560 #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)1561 int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type,
1562 				    const uint8_t **data)
1563 {
1564 	CHECKIF(codec_cap == NULL) {
1565 		LOG_DBG("codec_cap is NULL");
1566 		return -EINVAL;
1567 	}
1568 
1569 	return codec_meta_get_val(codec_cap->meta, codec_cap->meta_len, type, data);
1570 }
1571 
bt_audio_codec_cap_meta_set_val(struct bt_audio_codec_cap * codec_cap,enum bt_audio_metadata_type type,const uint8_t * data,size_t data_len)1572 int bt_audio_codec_cap_meta_set_val(struct bt_audio_codec_cap *codec_cap,
1573 				    enum bt_audio_metadata_type type, const uint8_t *data,
1574 				    size_t data_len)
1575 {
1576 	int ret;
1577 
1578 	CHECKIF(codec_cap == NULL) {
1579 		LOG_DBG("codec_cap is NULL");
1580 		return -EINVAL;
1581 	}
1582 
1583 	ret = codec_meta_set_val(codec_cap->meta, codec_cap->meta_len, ARRAY_SIZE(codec_cap->meta),
1584 				 type, data, data_len);
1585 	if (ret >= 0) {
1586 		codec_cap->meta_len = ret;
1587 	}
1588 
1589 	return ret;
1590 }
1591 
bt_audio_codec_cap_meta_unset_val(struct bt_audio_codec_cap * codec_cap,enum bt_audio_metadata_type type)1592 int bt_audio_codec_cap_meta_unset_val(struct bt_audio_codec_cap *codec_cap,
1593 				      enum bt_audio_metadata_type type)
1594 {
1595 	int ret;
1596 
1597 	CHECKIF(codec_cap == NULL) {
1598 		LOG_DBG("codec_cap is NULL");
1599 		return -EINVAL;
1600 	}
1601 
1602 	ret = codec_meta_unset_val(codec_cap->meta, codec_cap->meta_len,
1603 				   ARRAY_SIZE(codec_cap->meta), type);
1604 	if (ret >= 0) {
1605 		codec_cap->meta_len = ret;
1606 	}
1607 
1608 	return ret;
1609 }
1610 
bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap * codec_cap)1611 int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap)
1612 {
1613 	CHECKIF(codec_cap == NULL) {
1614 		LOG_DBG("codec_cap is NULL");
1615 		return -EINVAL;
1616 	}
1617 
1618 	return codec_meta_get_pref_context(codec_cap->meta, codec_cap->meta_len);
1619 }
1620 
bt_audio_codec_cap_meta_set_pref_context(struct bt_audio_codec_cap * codec_cap,enum bt_audio_context ctx)1621 int bt_audio_codec_cap_meta_set_pref_context(struct bt_audio_codec_cap *codec_cap,
1622 					     enum bt_audio_context ctx)
1623 {
1624 	int ret;
1625 
1626 	ret = codec_meta_set_pref_context(codec_cap->meta, codec_cap->meta_len,
1627 					  ARRAY_SIZE(codec_cap->meta), ctx);
1628 	if (ret >= 0) {
1629 		codec_cap->meta_len = ret;
1630 	}
1631 
1632 	return ret;
1633 }
1634 
bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap * codec_cap)1635 int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap *codec_cap)
1636 {
1637 	CHECKIF(codec_cap == NULL) {
1638 		LOG_DBG("codec_cap is NULL");
1639 		return -EINVAL;
1640 	}
1641 
1642 	return codec_meta_get_stream_context(codec_cap->meta, codec_cap->meta_len);
1643 }
1644 
bt_audio_codec_cap_meta_set_stream_context(struct bt_audio_codec_cap * codec_cap,enum bt_audio_context ctx)1645 int bt_audio_codec_cap_meta_set_stream_context(struct bt_audio_codec_cap *codec_cap,
1646 					       enum bt_audio_context ctx)
1647 {
1648 	int ret;
1649 
1650 	ret = codec_meta_set_stream_context(codec_cap->meta, codec_cap->meta_len,
1651 					    ARRAY_SIZE(codec_cap->meta), ctx);
1652 	if (ret >= 0) {
1653 		codec_cap->meta_len = ret;
1654 	}
1655 
1656 	return ret;
1657 }
1658 
bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** program_info)1659 int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *codec_cap,
1660 					     const uint8_t **program_info)
1661 {
1662 	CHECKIF(codec_cap == NULL) {
1663 		LOG_DBG("codec_cap is NULL");
1664 		return -EINVAL;
1665 	}
1666 
1667 	return codec_meta_get_program_info(codec_cap->meta, codec_cap->meta_len, program_info);
1668 }
1669 
bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap * codec_cap,const uint8_t * program_info,size_t program_info_len)1670 int bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap *codec_cap,
1671 					     const uint8_t *program_info, size_t program_info_len)
1672 {
1673 	int ret;
1674 
1675 	ret = codec_meta_set_program_info(codec_cap->meta, codec_cap->meta_len,
1676 					  ARRAY_SIZE(codec_cap->meta), program_info,
1677 					  program_info_len);
1678 	if (ret >= 0) {
1679 		codec_cap->meta_len = ret;
1680 	}
1681 
1682 	return ret;
1683 }
1684 
bt_audio_codec_cap_meta_get_lang(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** lang)1685 int bt_audio_codec_cap_meta_get_lang(const struct bt_audio_codec_cap *codec_cap,
1686 				     const uint8_t **lang)
1687 {
1688 	CHECKIF(codec_cap == NULL) {
1689 		LOG_DBG("codec_cap is NULL");
1690 		return -EINVAL;
1691 	}
1692 
1693 	return codec_meta_get_lang(codec_cap->meta, codec_cap->meta_len, lang);
1694 }
1695 
bt_audio_codec_cap_meta_set_lang(struct bt_audio_codec_cap * codec_cap,const uint8_t lang[BT_AUDIO_LANG_SIZE])1696 int bt_audio_codec_cap_meta_set_lang(struct bt_audio_codec_cap *codec_cap,
1697 				     const uint8_t lang[BT_AUDIO_LANG_SIZE])
1698 {
1699 	int ret;
1700 
1701 	ret = codec_meta_set_lang(codec_cap->meta, codec_cap->meta_len, ARRAY_SIZE(codec_cap->meta),
1702 				  lang);
1703 	if (ret >= 0) {
1704 		codec_cap->meta_len = ret;
1705 	}
1706 
1707 	return ret;
1708 }
1709 
bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** ccid_list)1710 int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec_cap,
1711 					  const uint8_t **ccid_list)
1712 {
1713 	CHECKIF(codec_cap == NULL) {
1714 		LOG_DBG("codec_cap is NULL");
1715 		return -EINVAL;
1716 	}
1717 
1718 	return codec_meta_get_ccid_list(codec_cap->meta, codec_cap->meta_len, ccid_list);
1719 }
1720 
bt_audio_codec_cap_meta_set_ccid_list(struct bt_audio_codec_cap * codec_cap,const uint8_t * ccid_list,size_t ccid_list_len)1721 int bt_audio_codec_cap_meta_set_ccid_list(struct bt_audio_codec_cap *codec_cap,
1722 					  const uint8_t *ccid_list, size_t ccid_list_len)
1723 {
1724 	int ret;
1725 
1726 	ret = codec_meta_set_ccid_list(codec_cap->meta, codec_cap->meta_len,
1727 				       ARRAY_SIZE(codec_cap->meta), ccid_list, ccid_list_len);
1728 	if (ret >= 0) {
1729 		codec_cap->meta_len = ret;
1730 	}
1731 
1732 	return ret;
1733 }
1734 
bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap * codec_cap)1735 int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap *codec_cap)
1736 {
1737 	CHECKIF(codec_cap == NULL) {
1738 		LOG_DBG("codec_cap is NULL");
1739 		return -EINVAL;
1740 	}
1741 
1742 	return codec_meta_get_parental_rating(codec_cap->meta, codec_cap->meta_len);
1743 }
1744 
bt_audio_codec_cap_meta_set_parental_rating(struct bt_audio_codec_cap * codec_cap,enum bt_audio_parental_rating parental_rating)1745 int bt_audio_codec_cap_meta_set_parental_rating(struct bt_audio_codec_cap *codec_cap,
1746 						enum bt_audio_parental_rating parental_rating)
1747 {
1748 	int ret;
1749 
1750 	ret = codec_meta_set_parental_rating(codec_cap->meta, codec_cap->meta_len,
1751 					     ARRAY_SIZE(codec_cap->meta), parental_rating);
1752 	if (ret >= 0) {
1753 		codec_cap->meta_len = ret;
1754 	}
1755 
1756 	return ret;
1757 }
1758 
bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** program_info_uri)1759 int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap *codec_cap,
1760 						 const uint8_t **program_info_uri)
1761 {
1762 	CHECKIF(codec_cap == NULL) {
1763 		LOG_DBG("codec_cap is NULL");
1764 		return -EINVAL;
1765 	}
1766 
1767 	return codec_meta_get_program_info_uri(codec_cap->meta, codec_cap->meta_len,
1768 					       program_info_uri);
1769 }
1770 
bt_audio_codec_cap_meta_set_program_info_uri(struct bt_audio_codec_cap * codec_cap,const uint8_t * program_info_uri,size_t program_info_uri_len)1771 int bt_audio_codec_cap_meta_set_program_info_uri(struct bt_audio_codec_cap *codec_cap,
1772 						 const uint8_t *program_info_uri,
1773 						 size_t program_info_uri_len)
1774 {
1775 	int ret;
1776 
1777 	ret = codec_meta_set_program_info_uri(codec_cap->meta, codec_cap->meta_len,
1778 					      ARRAY_SIZE(codec_cap->meta), program_info_uri,
1779 					      program_info_uri_len);
1780 	if (ret >= 0) {
1781 		codec_cap->meta_len = ret;
1782 	}
1783 
1784 	return ret;
1785 }
1786 
bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap * codec_cap)1787 int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap *codec_cap)
1788 {
1789 	CHECKIF(codec_cap == NULL) {
1790 		LOG_DBG("codec_cap is NULL");
1791 		return -EINVAL;
1792 	}
1793 
1794 	return codec_meta_get_audio_active_state(codec_cap->meta, codec_cap->meta_len);
1795 }
1796 
bt_audio_codec_cap_meta_set_audio_active_state(struct bt_audio_codec_cap * codec_cap,enum bt_audio_active_state state)1797 int bt_audio_codec_cap_meta_set_audio_active_state(struct bt_audio_codec_cap *codec_cap,
1798 						   enum bt_audio_active_state state)
1799 {
1800 	int ret;
1801 
1802 	ret = codec_meta_set_audio_active_state(codec_cap->meta, codec_cap->meta_len,
1803 						ARRAY_SIZE(codec_cap->meta), state);
1804 	if (ret >= 0) {
1805 		codec_cap->meta_len = ret;
1806 	}
1807 
1808 	return ret;
1809 }
1810 
bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(const struct bt_audio_codec_cap * codec_cap)1811 int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(
1812 	const struct bt_audio_codec_cap *codec_cap)
1813 {
1814 	CHECKIF(codec_cap == NULL) {
1815 		LOG_DBG("codec_cap is NULL");
1816 		return -EINVAL;
1817 	}
1818 
1819 	return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cap->meta, codec_cap->meta_len);
1820 }
1821 
bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag(struct bt_audio_codec_cap * codec_cap)1822 int bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag(
1823 	struct bt_audio_codec_cap *codec_cap)
1824 {
1825 	int ret;
1826 
1827 	ret = codec_meta_set_bcast_audio_immediate_rend_flag(codec_cap->meta, codec_cap->meta_len,
1828 							     ARRAY_SIZE(codec_cap->meta));
1829 	if (ret >= 0) {
1830 		codec_cap->meta_len = ret;
1831 	}
1832 
1833 	return ret;
1834 }
1835 
bt_audio_codec_cap_meta_get_assisted_listening_stream(const struct bt_audio_codec_cap * codec_cap)1836 int bt_audio_codec_cap_meta_get_assisted_listening_stream(
1837 	const struct bt_audio_codec_cap *codec_cap)
1838 {
1839 	CHECKIF(codec_cap == NULL) {
1840 		LOG_DBG("codec_cap is NULL");
1841 		return -EINVAL;
1842 	}
1843 
1844 	return codec_meta_get_assisted_listening_stream(codec_cap->meta, codec_cap->meta_len);
1845 }
1846 
bt_audio_codec_cap_meta_set_assisted_listening_stream(struct bt_audio_codec_cap * codec_cap,enum bt_audio_assisted_listening_stream val)1847 int bt_audio_codec_cap_meta_set_assisted_listening_stream(
1848 	struct bt_audio_codec_cap *codec_cap, enum bt_audio_assisted_listening_stream val)
1849 {
1850 	int ret;
1851 
1852 	ret = codec_meta_set_assisted_listening_stream(codec_cap->meta, codec_cap->meta_len,
1853 						       ARRAY_SIZE(codec_cap->meta), val);
1854 	if (ret >= 0) {
1855 		codec_cap->meta_len = ret;
1856 	}
1857 
1858 	return ret;
1859 }
1860 
bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** extended_meta)1861 int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_cap,
1862 					 const uint8_t **extended_meta)
1863 {
1864 	CHECKIF(codec_cap == NULL) {
1865 		LOG_DBG("codec_cap is NULL");
1866 		return -EINVAL;
1867 	}
1868 
1869 	return codec_meta_get_extended(codec_cap->meta, codec_cap->meta_len, extended_meta);
1870 }
1871 
bt_audio_codec_cap_meta_set_extended(struct bt_audio_codec_cap * codec_cap,const uint8_t * extended_meta,size_t extended_meta_len)1872 int bt_audio_codec_cap_meta_set_extended(struct bt_audio_codec_cap *codec_cap,
1873 					 const uint8_t *extended_meta, size_t extended_meta_len)
1874 {
1875 	int ret;
1876 
1877 	ret = codec_meta_set_extended(codec_cap->meta, codec_cap->meta_len,
1878 				      ARRAY_SIZE(codec_cap->meta), extended_meta,
1879 				      extended_meta_len);
1880 	if (ret >= 0) {
1881 		codec_cap->meta_len = ret;
1882 	}
1883 
1884 	return ret;
1885 }
1886 
bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** vendor_meta)1887 int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap,
1888 				       const uint8_t **vendor_meta)
1889 {
1890 	CHECKIF(codec_cap == NULL) {
1891 		LOG_DBG("codec_cap is NULL");
1892 		return -EINVAL;
1893 	}
1894 
1895 	return codec_meta_get_vendor(codec_cap->meta, codec_cap->meta_len, vendor_meta);
1896 }
1897 
bt_audio_codec_cap_meta_set_vendor(struct bt_audio_codec_cap * codec_cap,const uint8_t * vendor_meta,size_t vendor_meta_len)1898 int bt_audio_codec_cap_meta_set_vendor(struct bt_audio_codec_cap *codec_cap,
1899 				       const uint8_t *vendor_meta, size_t vendor_meta_len)
1900 {
1901 	int ret;
1902 
1903 	ret = codec_meta_set_vendor(codec_cap->meta, codec_cap->meta_len,
1904 				    ARRAY_SIZE(codec_cap->meta), vendor_meta, vendor_meta_len);
1905 	if (ret >= 0) {
1906 		codec_cap->meta_len = ret;
1907 	}
1908 
1909 	return ret;
1910 }
1911 
bt_audio_codec_cap_meta_get_broadcast_name(const struct bt_audio_codec_cap * codec_cap,const uint8_t ** broadcast_name)1912 int bt_audio_codec_cap_meta_get_broadcast_name(const struct bt_audio_codec_cap *codec_cap,
1913 					       const uint8_t **broadcast_name)
1914 {
1915 	CHECKIF(codec_cap == NULL) {
1916 		LOG_DBG("codec_cap is NULL");
1917 		return -EINVAL;
1918 	}
1919 
1920 	return codec_meta_get_broadcast_name(codec_cap->meta, codec_cap->meta_len, broadcast_name);
1921 }
1922 
bt_audio_codec_cap_meta_set_broadcast_name(struct bt_audio_codec_cap * codec_cap,const uint8_t * broadcast_name,size_t broadcast_name_len)1923 int bt_audio_codec_cap_meta_set_broadcast_name(struct bt_audio_codec_cap *codec_cap,
1924 					       const uint8_t *broadcast_name,
1925 					       size_t broadcast_name_len)
1926 {
1927 	int ret;
1928 
1929 	ret = codec_meta_set_broadcast_name(codec_cap->meta, codec_cap->meta_len,
1930 					    ARRAY_SIZE(codec_cap->meta), broadcast_name,
1931 					    broadcast_name_len);
1932 	if (ret >= 0) {
1933 		codec_cap->meta_len = ret;
1934 	}
1935 
1936 	return ret;
1937 }
1938 #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */
1939 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 ||                                       \
1940 	* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0                                          \
1941 	*/
1942 
1943 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0
1944 
init_net_buf_simple_from_codec_cap(struct net_buf_simple * buf,struct bt_audio_codec_cap * codec_cap)1945 static void init_net_buf_simple_from_codec_cap(struct net_buf_simple *buf,
1946 					       struct bt_audio_codec_cap *codec_cap)
1947 {
1948 	buf->__buf = codec_cap->data;
1949 	buf->data = codec_cap->data;
1950 	buf->size = sizeof(codec_cap->data);
1951 	buf->len = codec_cap->data_len;
1952 }
1953 
bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap * codec_cap,enum bt_audio_codec_cap_type type,const uint8_t ** data)1954 int bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap,
1955 			       enum bt_audio_codec_cap_type type, const uint8_t **data)
1956 {
1957 	CHECKIF(codec_cap == NULL) {
1958 		LOG_DBG("codec_cap is NULL");
1959 		return -EINVAL;
1960 	}
1961 
1962 	CHECKIF(data == NULL) {
1963 		LOG_DBG("data is NULL");
1964 		return -EINVAL;
1965 	}
1966 
1967 	return bt_audio_data_get_val(codec_cap->data, codec_cap->data_len, (uint8_t)type, data);
1968 }
1969 
bt_audio_codec_cap_set_val(struct bt_audio_codec_cap * codec_cap,enum bt_audio_codec_cap_type type,const uint8_t * data,size_t data_len)1970 int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap,
1971 			       enum bt_audio_codec_cap_type type, const uint8_t *data,
1972 			       size_t data_len)
1973 {
1974 	struct net_buf_simple buf;
1975 	int ret;
1976 
1977 	CHECKIF(codec_cap == NULL) {
1978 		LOG_DBG("codec_cap is NULL");
1979 		return -EINVAL;
1980 	}
1981 
1982 	CHECKIF(data == NULL) {
1983 		LOG_DBG("data is NULL");
1984 		return -EINVAL;
1985 	}
1986 
1987 	CHECKIF(data_len == 0U || data_len > UINT8_MAX) {
1988 		LOG_DBG("Invalid data_len %zu", data_len);
1989 		return -EINVAL;
1990 	}
1991 
1992 	init_net_buf_simple_from_codec_cap(&buf, codec_cap);
1993 
1994 	ret = ltv_set_val(&buf, type, data, data_len);
1995 	if (ret >= 0) {
1996 		codec_cap->data_len = ret;
1997 	}
1998 
1999 	return ret;
2000 }
2001 
bt_audio_codec_cap_unset_val(struct bt_audio_codec_cap * codec_cap,enum bt_audio_codec_cap_type type)2002 int bt_audio_codec_cap_unset_val(struct bt_audio_codec_cap *codec_cap,
2003 				 enum bt_audio_codec_cap_type type)
2004 {
2005 	struct net_buf_simple buf;
2006 	int ret;
2007 
2008 	CHECKIF(codec_cap == NULL) {
2009 		LOG_DBG("codec_cap is NULL");
2010 		return -EINVAL;
2011 	}
2012 
2013 	init_net_buf_simple_from_codec_cap(&buf, codec_cap);
2014 
2015 	ret = ltv_unset_val(&buf, type);
2016 	if (ret >= 0) {
2017 		codec_cap->data_len = ret;
2018 	}
2019 
2020 	return ret;
2021 }
2022 
bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap * codec_cap)2023 int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap)
2024 {
2025 	const uint8_t *data;
2026 	uint8_t data_len;
2027 
2028 	CHECKIF(codec_cap == NULL) {
2029 		LOG_DBG("codec_cap is NULL");
2030 		return -EINVAL;
2031 	}
2032 
2033 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_FREQ, &data);
2034 	if (data == NULL) {
2035 		return -ENODATA;
2036 	}
2037 
2038 	if (data_len != sizeof(uint16_t)) {
2039 		return -EBADMSG;
2040 	}
2041 
2042 	return sys_get_le16(data);
2043 }
2044 
bt_audio_codec_cap_set_freq(struct bt_audio_codec_cap * codec_cap,enum bt_audio_codec_cap_freq freq)2045 int bt_audio_codec_cap_set_freq(struct bt_audio_codec_cap *codec_cap,
2046 				enum bt_audio_codec_cap_freq freq)
2047 {
2048 	uint16_t freq_le16;
2049 
2050 	CHECKIF(codec_cap == NULL) {
2051 		LOG_DBG("codec_cap is NULL");
2052 		return -EINVAL;
2053 	}
2054 
2055 	if ((freq & BT_AUDIO_CODEC_CAP_FREQ_ANY) != freq) {
2056 		LOG_DBG("Invalid freq value: %d", freq);
2057 		return -EINVAL;
2058 	}
2059 
2060 	freq_le16 = sys_cpu_to_le16((uint16_t)freq);
2061 
2062 	return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_FREQ,
2063 					  (uint8_t *)&freq_le16, sizeof(freq_le16));
2064 }
2065 
bt_audio_codec_cap_get_frame_dur(const struct bt_audio_codec_cap * codec_cap)2066 int bt_audio_codec_cap_get_frame_dur(const struct bt_audio_codec_cap *codec_cap)
2067 {
2068 	const uint8_t *data;
2069 	uint8_t data_len;
2070 
2071 	CHECKIF(codec_cap == NULL) {
2072 		LOG_DBG("codec_cap is NULL");
2073 		return -EINVAL;
2074 	}
2075 
2076 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_DURATION, &data);
2077 	if (data == NULL) {
2078 		return -ENODATA;
2079 	}
2080 
2081 	if (data_len != sizeof(uint8_t)) {
2082 		return -EBADMSG;
2083 	}
2084 
2085 	return data[0];
2086 }
2087 
bt_audio_codec_cap_set_frame_dur(struct bt_audio_codec_cap * codec_cap,enum bt_audio_codec_cap_frame_dur frame_dur)2088 int bt_audio_codec_cap_set_frame_dur(struct bt_audio_codec_cap *codec_cap,
2089 				     enum bt_audio_codec_cap_frame_dur frame_dur)
2090 {
2091 	uint8_t frame_dur_u8;
2092 
2093 	CHECKIF(codec_cap == NULL) {
2094 		LOG_DBG("codec_cap is NULL");
2095 		return -EINVAL;
2096 	}
2097 
2098 	if ((frame_dur & BT_AUDIO_CODEC_CAP_DURATION_ANY) == 0) {
2099 		LOG_DBG("Invalid frame_dur value: %d", frame_dur);
2100 		return -EINVAL;
2101 	}
2102 
2103 	if ((frame_dur & BT_AUDIO_CODEC_CAP_DURATION_PREFER_7_5) != 0) {
2104 		if ((frame_dur & BT_AUDIO_CODEC_CAP_DURATION_PREFER_10) != 0) {
2105 			LOG_DBG("Cannot prefer both 7.5 and 10ms: %d", frame_dur);
2106 			return -EINVAL;
2107 		}
2108 
2109 		if ((frame_dur & BT_AUDIO_CODEC_CAP_DURATION_7_5) == 0) {
2110 			LOG_DBG("Cannot prefer 7.5ms when not supported: %d", frame_dur);
2111 			return -EINVAL;
2112 		}
2113 	}
2114 
2115 	if ((frame_dur & BT_AUDIO_CODEC_CAP_DURATION_PREFER_10) != 0 &&
2116 	    (frame_dur & BT_AUDIO_CODEC_CAP_DURATION_10) == 0) {
2117 		LOG_DBG("Cannot prefer 10ms when not supported: %d", frame_dur);
2118 		return -EINVAL;
2119 	}
2120 
2121 	frame_dur_u8 = (uint8_t)frame_dur;
2122 
2123 	return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_DURATION,
2124 					  &frame_dur_u8, sizeof(frame_dur_u8));
2125 }
2126 
bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap * codec_cap,bool fallback_to_default)2127 int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap,
2128 						       bool fallback_to_default)
2129 {
2130 	const uint8_t *data;
2131 	uint8_t data_len;
2132 
2133 	CHECKIF(codec_cap == NULL) {
2134 		LOG_DBG("codec_cap is NULL");
2135 		return -EINVAL;
2136 	}
2137 
2138 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_CHAN_COUNT, &data);
2139 	if (data == NULL) {
2140 		if (fallback_to_default && codec_cap->id == BT_HCI_CODING_FORMAT_LC3) {
2141 			return 1;
2142 		}
2143 
2144 		return -ENODATA;
2145 	}
2146 
2147 	if (data_len != sizeof(uint8_t)) {
2148 		return -EBADMSG;
2149 	}
2150 
2151 	return data[0];
2152 }
2153 
bt_audio_codec_cap_set_supported_audio_chan_counts(struct bt_audio_codec_cap * codec_cap,enum bt_audio_codec_cap_chan_count chan_count)2154 int bt_audio_codec_cap_set_supported_audio_chan_counts(
2155 	struct bt_audio_codec_cap *codec_cap, enum bt_audio_codec_cap_chan_count chan_count)
2156 {
2157 	uint8_t chan_count_u8;
2158 
2159 	CHECKIF(codec_cap == NULL) {
2160 		LOG_DBG("codec_cap is NULL");
2161 		return -EINVAL;
2162 	}
2163 
2164 	if ((chan_count & BT_AUDIO_CODEC_CAP_CHAN_COUNT_ANY) != chan_count) {
2165 		LOG_DBG("Invalid chan_count value: %d", chan_count);
2166 		return -EINVAL;
2167 	}
2168 
2169 	chan_count_u8 = (uint8_t)chan_count;
2170 
2171 	return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_CHAN_COUNT,
2172 					  &chan_count_u8, sizeof(chan_count_u8));
2173 }
2174 
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)2175 int bt_audio_codec_cap_get_octets_per_frame(
2176 	const struct bt_audio_codec_cap *codec_cap,
2177 	struct bt_audio_codec_octets_per_codec_frame *codec_frame)
2178 {
2179 	const uint8_t *data;
2180 	uint8_t data_len;
2181 
2182 	CHECKIF(codec_cap == NULL) {
2183 		LOG_DBG("codec_cap is NULL");
2184 		return -EINVAL;
2185 	}
2186 
2187 	CHECKIF(codec_frame == NULL) {
2188 		LOG_DBG("codec_frame is NULL");
2189 		return -EINVAL;
2190 	}
2191 
2192 	data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_FRAME_LEN, &data);
2193 	if (data == NULL) {
2194 		return -ENODATA;
2195 	}
2196 
2197 	if (data_len != sizeof(uint32_t)) {
2198 		return -EBADMSG;
2199 	}
2200 
2201 	codec_frame->min = sys_get_le16(data);
2202 	codec_frame->max = sys_get_le16(data + sizeof(codec_frame->min));
2203 
2204 	return 0;
2205 }
2206 
bt_audio_codec_cap_set_octets_per_frame(struct bt_audio_codec_cap * codec_cap,const struct bt_audio_codec_octets_per_codec_frame * codec_frame)2207 int bt_audio_codec_cap_set_octets_per_frame(
2208 	struct bt_audio_codec_cap *codec_cap,
2209 	const struct bt_audio_codec_octets_per_codec_frame *codec_frame)
2210 {
2211 	uint8_t codec_frame_le32[4];
2212 
2213 	CHECKIF(codec_cap == NULL) {
2214 		LOG_DBG("codec_cap is NULL");
2215 		return -EINVAL;
2216 	}
2217 
2218 	CHECKIF(codec_frame == NULL) {
2219 		LOG_DBG("codec_frame is NULL");
2220 		return -EINVAL;
2221 	}
2222 
2223 	if (codec_frame->min > codec_frame->max) {
2224 		LOG_DBG("Invalid codec_frame values: %u/%u", codec_frame->min, codec_frame->max);
2225 		return -EINVAL;
2226 	}
2227 
2228 	sys_put_le16(codec_frame->min, codec_frame_le32);
2229 	sys_put_le16(codec_frame->max, codec_frame_le32 + 2);
2230 
2231 	return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_FRAME_LEN,
2232 					  codec_frame_le32, sizeof(codec_frame_le32));
2233 }
2234 
bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap * codec_cap,bool fallback_to_default)2235 int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap,
2236 						    bool fallback_to_default)
2237 {
2238 	const uint8_t *data;
2239 	uint8_t data_len;
2240 
2241 	CHECKIF(codec_cap == NULL) {
2242 		LOG_DBG("codec_cap is NULL");
2243 		return -EINVAL;
2244 	}
2245 
2246 	data_len =
2247 		bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_FRAME_COUNT, &data);
2248 	if (data == NULL) {
2249 		if (fallback_to_default && codec_cap->id == BT_HCI_CODING_FORMAT_LC3) {
2250 			return 1;
2251 		}
2252 
2253 		return -ENODATA;
2254 	}
2255 
2256 	if (data_len != sizeof(uint8_t)) {
2257 		return -EBADMSG;
2258 	}
2259 
2260 	return data[0];
2261 }
2262 
bt_audio_codec_cap_set_max_codec_frames_per_sdu(struct bt_audio_codec_cap * codec_cap,uint8_t codec_frames_per_sdu)2263 int bt_audio_codec_cap_set_max_codec_frames_per_sdu(struct bt_audio_codec_cap *codec_cap,
2264 						    uint8_t codec_frames_per_sdu)
2265 {
2266 	CHECKIF(codec_cap == NULL) {
2267 		LOG_DBG("codec_cap is NULL");
2268 		return -EINVAL;
2269 	}
2270 
2271 	return bt_audio_codec_cap_set_val(codec_cap, BT_AUDIO_CODEC_CAP_TYPE_FRAME_COUNT,
2272 					  &codec_frames_per_sdu, sizeof(codec_frames_per_sdu));
2273 }
2274 
2275 #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */
2276