1 /** @file
2  *  @brief Bluetooth audio shell functions
3  *
4  *  This is not to be included by the application.
5  */
6 
7 /*
8  * Copyright (c) 2023 Nordic Semiconductor ASA
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef AUDIO_SHELL_AUDIO_H
14 #define AUDIO_SHELL_AUDIO_H
15 
16 #include <stdint.h>
17 #include <stdbool.h>
18 #include <stddef.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/types.h>
22 
23 #include <zephyr/autoconf.h>
24 #include <zephyr/bluetooth/bluetooth.h>
25 #include <zephyr/bluetooth/hci_types.h>
26 #include <zephyr/bluetooth/iso.h>
27 #include <zephyr/shell/shell.h>
28 #include <zephyr/sys/atomic_types.h>
29 #include <zephyr/sys/byteorder.h>
30 #include <zephyr/sys/printk.h>
31 #include <zephyr/sys/util.h>
32 #include <zephyr/sys/util_macro.h>
33 #include <zephyr/sys_clock.h>
34 
35 #include "shell/bt.h"
36 
37 #define SHELL_PRINT_INDENT_LEVEL_SIZE 2
38 #define MAX_CODEC_FRAMES_PER_SDU      4U
39 
40 /* BIS sync is a 32-bit bitfield where BIT(0) is not allowed */
41 #define VALID_BIS_SYNC(_bis_sync) ((bis_sync & BIT(0)) == 0U && bis_sync < UINT32_MAX)
42 
43 extern struct bt_csip_set_member_svc_inst *svc_inst;
44 
45 ssize_t audio_ad_data_add(struct bt_data *data, const size_t data_size, const bool discoverable,
46 			  const bool connectable);
47 ssize_t audio_pa_data_add(struct bt_data *data_array, const size_t data_array_size);
48 ssize_t csis_ad_data_add(struct bt_data *data, const size_t data_size, const bool discoverable);
49 size_t cap_acceptor_ad_data_add(struct bt_data data[], size_t data_size, bool discoverable);
50 size_t bap_scan_delegator_ad_data_add(struct bt_data data[], size_t data_size);
51 size_t gmap_ad_data_add(struct bt_data data[], size_t data_size);
52 size_t pbp_ad_data_add(struct bt_data data[], size_t data_size);
53 ssize_t cap_initiator_ad_data_add(struct bt_data *data_array, const size_t data_array_size,
54 				  const bool discoverable, const bool connectable);
55 ssize_t cap_initiator_pa_data_add(struct bt_data *data_array, const size_t data_array_size);
56 
57 #if defined(CONFIG_BT_AUDIO)
58 /* Must guard before including audio.h as audio.h uses Kconfigs guarded by
59  * CONFIG_BT_AUDIO
60  */
61 #include <zephyr/bluetooth/audio/audio.h>
62 #include <zephyr/bluetooth/audio/bap.h>
63 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
64 #include <zephyr/bluetooth/audio/cap.h>
65 
66 unsigned long bap_get_stats_interval(void);
67 
68 #if defined(CONFIG_LIBLC3)
69 #include "lc3.h"
70 
71 #define USB_SAMPLE_RATE            48000U
72 #define LC3_MAX_SAMPLE_RATE        48000U
73 #define LC3_MAX_FRAME_DURATION_US  10000U
74 #define LC3_MAX_NUM_SAMPLES_MONO   ((LC3_MAX_FRAME_DURATION_US * LC3_MAX_SAMPLE_RATE) /            \
75 				    USEC_PER_SEC)
76 #define LC3_MAX_NUM_SAMPLES_STEREO (LC3_MAX_NUM_SAMPLES_MONO * 2U)
77 #endif /* CONFIG_LIBLC3 */
78 
79 #define LOCATION BT_AUDIO_LOCATION_FRONT_LEFT
80 #define CONTEXT                                                                                    \
81 	(BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL |                \
82 	 BT_AUDIO_CONTEXT_TYPE_MEDIA |                                                             \
83 	 COND_CODE_1(IS_ENABLED(CONFIG_BT_GMAP), (BT_AUDIO_CONTEXT_TYPE_GAME), (0)))
84 
85 const struct named_lc3_preset *gmap_get_named_preset(bool is_unicast, enum bt_audio_dir dir,
86 						     const char *preset_arg);
87 
88 struct named_lc3_preset {
89 	const char *name;
90 	struct bt_bap_lc3_preset preset;
91 };
92 
93 struct shell_stream {
94 	struct bt_cap_stream stream;
95 	struct bt_audio_codec_cfg codec_cfg;
96 	struct bt_audio_codec_qos qos;
97 	bool is_tx;
98 	bool is_rx;
99 
100 #if defined(CONFIG_LIBLC3)
101 	uint32_t lc3_freq_hz;
102 	uint32_t lc3_frame_duration_us;
103 	uint16_t lc3_octets_per_frame;
104 	uint8_t lc3_frame_blocks_per_sdu;
105 	enum bt_audio_location lc3_chan_allocation;
106 	uint8_t lc3_chan_cnt;
107 #endif /* CONFIG_LIBLC3 */
108 
109 	union {
110 #if defined(CONFIG_BT_AUDIO_TX)
111 		struct {
112 			/* The uptime tick measured when stream was connected */
113 			int64_t connected_at_ticks;
114 			uint16_t seq_num;
115 #if defined(CONFIG_LIBLC3)
116 			atomic_t lc3_enqueue_cnt;
117 			bool active;
118 			size_t encoded_cnt;
119 			size_t lc3_sdu_cnt;
120 			lc3_encoder_mem_48k_t lc3_encoder_mem;
121 			lc3_encoder_t lc3_encoder;
122 #if defined(CONFIG_USB_DEVICE_AUDIO)
123 			/* Indicates where to read left USB data in the ring buffer */
124 			size_t left_read_idx;
125 			/* Indicates where to read right USB data in the ring buffer */
126 			size_t right_read_idx;
127 			size_t right_ring_buf_fail_cnt;
128 #endif /* CONFIG_USB_DEVICE_AUDIO */
129 #endif /* CONFIG_LIBLC3 */
130 		} tx;
131 #endif /* CONFIG_BT_AUDIO_TX */
132 
133 #if defined(CONFIG_BT_AUDIO_RX)
134 		struct {
135 			struct bt_iso_recv_info last_info;
136 			size_t empty_sdu_pkts;
137 			size_t valid_sdu_pkts;
138 			size_t lost_pkts;
139 			size_t err_pkts;
140 			size_t dup_psn;
141 			size_t rx_cnt;
142 			size_t dup_ts;
143 #if defined(CONFIG_LIBLC3)
144 			lc3_decoder_mem_48k_t lc3_decoder_mem;
145 			lc3_decoder_t lc3_decoder;
146 			size_t decoded_cnt;
147 #endif /* CONFIG_LIBLC3 */
148 		} rx;
149 #endif /* CONFIG_BT_AUDIO_RX */
150 	};
151 };
152 
153 const struct named_lc3_preset *bap_get_named_preset(bool is_unicast, enum bt_audio_dir dir,
154 						    const char *preset_arg);
155 
156 size_t bap_get_rx_streaming_cnt(void);
157 size_t bap_get_tx_streaming_cnt(void);
158 void bap_foreach_stream(void (*func)(struct shell_stream *sh_stream, void *data), void *data);
159 
160 int bap_usb_init(void);
161 
162 int bap_usb_add_frame_to_usb(enum bt_audio_location lc3_chan_allocation, const int16_t *frame,
163 			     size_t frame_size, uint32_t ts);
164 void bap_usb_clear_frames_to_usb(void);
165 uint16_t get_next_seq_num(struct bt_bap_stream *bap_stream);
166 struct shell_stream *shell_stream_from_bap_stream(struct bt_bap_stream *bap_stream);
167 struct bt_bap_stream *bap_stream_from_shell_stream(struct shell_stream *sh_stream);
168 bool bap_usb_can_get_full_sdu(struct shell_stream *sh_stream);
169 void bap_usb_get_frame(struct shell_stream *sh_stream, enum bt_audio_location chan_alloc,
170 		       int16_t buffer[]);
171 size_t bap_usb_get_frame_size(const struct shell_stream *sh_stream);
172 
173 struct broadcast_source {
174 	bool is_cap;
175 	union {
176 		struct bt_bap_broadcast_source *bap_source;
177 		struct bt_cap_broadcast_source *cap_source;
178 	};
179 	struct bt_audio_codec_cfg codec_cfg;
180 	struct bt_audio_codec_qos qos;
181 };
182 
183 struct broadcast_sink {
184 	struct bt_bap_broadcast_sink *bap_sink;
185 	struct bt_le_per_adv_sync *pa_sync;
186 	uint8_t received_base[UINT8_MAX];
187 	uint8_t base_size;
188 	uint32_t broadcast_id;
189 	size_t stream_cnt;
190 	bool syncable;
191 };
192 
193 #define BAP_UNICAST_AC_MAX_CONN   2U
194 #define BAP_UNICAST_AC_MAX_SNK    (2U * BAP_UNICAST_AC_MAX_CONN)
195 #define BAP_UNICAST_AC_MAX_SRC    (2U * BAP_UNICAST_AC_MAX_CONN)
196 #define BAP_UNICAST_AC_MAX_PAIR   MAX(BAP_UNICAST_AC_MAX_SNK, BAP_UNICAST_AC_MAX_SRC)
197 #define BAP_UNICAST_AC_MAX_STREAM (BAP_UNICAST_AC_MAX_SNK + BAP_UNICAST_AC_MAX_SRC)
198 
199 #if defined(CONFIG_BT_BAP_UNICAST)
200 
201 #define UNICAST_SERVER_STREAM_COUNT                                                                \
202 	COND_CODE_1(CONFIG_BT_ASCS, (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT), \
203 		    (0))
204 #define UNICAST_CLIENT_STREAM_COUNT                                                                \
205 	COND_CODE_1(CONFIG_BT_BAP_UNICAST_CLIENT,                                                  \
206 		    (CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT +                                  \
207 		     CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT),                                  \
208 		    (0))
209 
210 extern struct shell_stream unicast_streams[CONFIG_BT_MAX_CONN * MAX(UNICAST_SERVER_STREAM_COUNT,
211 								    UNICAST_CLIENT_STREAM_COUNT)];
212 
213 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
214 
215 struct bap_unicast_ac_param {
216 	char *name;
217 	size_t conn_cnt;
218 	size_t snk_cnt[BAP_UNICAST_AC_MAX_CONN];
219 	size_t src_cnt[BAP_UNICAST_AC_MAX_CONN];
220 	size_t snk_chan_cnt;
221 	size_t src_chan_cnt;
222 };
223 
224 extern struct bt_bap_unicast_group *default_unicast_group;
225 extern struct bt_bap_ep *snks[CONFIG_BT_MAX_CONN][CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT];
226 extern struct bt_bap_ep *srcs[CONFIG_BT_MAX_CONN][CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT];
227 extern struct named_lc3_preset default_sink_preset;
228 extern struct named_lc3_preset default_source_preset;
229 
230 int bap_ac_create_unicast_group(const struct bap_unicast_ac_param *param,
231 				struct shell_stream *snk_uni_streams[], size_t snk_cnt,
232 				struct shell_stream *src_uni_streams[], size_t src_cnt);
233 
234 int cap_ac_unicast(const struct shell *sh, const struct bap_unicast_ac_param *param);
235 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
236 #endif /* CONFIG_BT_BAP_UNICAST */
237 
print_qos(const struct shell * sh,const struct bt_audio_codec_qos * qos)238 static inline void print_qos(const struct shell *sh, const struct bt_audio_codec_qos *qos)
239 {
240 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_UNICAST)
241 	shell_print(sh,
242 		    "QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u latency %u pd %u",
243 		    qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->latency,
244 		    qos->pd);
245 #else
246 	shell_print(sh, "QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u pd %u",
247 		    qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->pd);
248 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_UNICAST */
249 }
250 
251 struct print_ltv_info {
252 	const struct shell *sh;
253 	size_t indent;
254 	size_t cnt;
255 };
256 
print_ltv_elem(struct bt_data * data,void * user_data)257 static bool print_ltv_elem(struct bt_data *data, void *user_data)
258 {
259 	struct print_ltv_info *ltv_info = user_data;
260 	const size_t elem_indent = ltv_info->indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
261 
262 	shell_print(ltv_info->sh, "%*s#%zu: type 0x%02x value_len %u", ltv_info->indent, "",
263 		    ltv_info->cnt, data->type, data->data_len);
264 
265 	shell_fprintf(ltv_info->sh, SHELL_NORMAL, "%*s", elem_indent, "");
266 
267 	for (uint8_t i = 0U; i < data->data_len; i++) {
268 		shell_fprintf(ltv_info->sh, SHELL_NORMAL, "%02X", data->data[i]);
269 	}
270 
271 	shell_fprintf(ltv_info->sh, SHELL_NORMAL, "\n");
272 
273 	ltv_info->cnt++;
274 
275 	return true;
276 }
277 
print_ltv_array(const struct shell * sh,size_t indent,const uint8_t * ltv_data,size_t ltv_data_len)278 static void print_ltv_array(const struct shell *sh, size_t indent, const uint8_t *ltv_data,
279 			    size_t ltv_data_len)
280 {
281 	struct print_ltv_info ltv_info = {
282 		.sh = sh,
283 		.cnt = 0U,
284 		.indent = indent,
285 	};
286 	int err;
287 
288 	err = bt_audio_data_parse(ltv_data, ltv_data_len, print_ltv_elem, &ltv_info);
289 	if (err != 0 && err != -ECANCELED) {
290 		shell_error(sh, "%*sInvalid LTV data: %d", indent, "", err);
291 	}
292 }
293 
context_bit_to_str(enum bt_audio_context context)294 static inline char *context_bit_to_str(enum bt_audio_context context)
295 {
296 	switch (context) {
297 	case BT_AUDIO_CONTEXT_TYPE_PROHIBITED:
298 		return "Prohibited";
299 	case BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED:
300 		return "Unspecified";
301 	case BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL:
302 		return "Conversational";
303 	case BT_AUDIO_CONTEXT_TYPE_MEDIA:
304 		return "Media";
305 	case BT_AUDIO_CONTEXT_TYPE_GAME:
306 		return "Game";
307 	case BT_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL:
308 		return "Instructional";
309 	case BT_AUDIO_CONTEXT_TYPE_VOICE_ASSISTANTS:
310 		return "Voice assistant";
311 	case BT_AUDIO_CONTEXT_TYPE_LIVE:
312 		return "Live";
313 	case BT_AUDIO_CONTEXT_TYPE_SOUND_EFFECTS:
314 		return "Sound effects";
315 	case BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS:
316 		return "Notifications";
317 	case BT_AUDIO_CONTEXT_TYPE_RINGTONE:
318 		return "Ringtone";
319 	case BT_AUDIO_CONTEXT_TYPE_ALERTS:
320 		return "Alerts";
321 	case BT_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM:
322 		return "Emergency alarm";
323 	default:
324 		return "Unknown context";
325 	}
326 }
327 
print_codec_meta_pref_context(const struct shell * sh,size_t indent,enum bt_audio_context context)328 static inline void print_codec_meta_pref_context(const struct shell *sh, size_t indent,
329 						 enum bt_audio_context context)
330 {
331 	shell_print(sh, "%*sPreferred audio contexts:", indent, "");
332 
333 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
334 
335 	/* There can be up to 16 bits set in the field */
336 	for (size_t i = 0U; i < 16; i++) {
337 		const uint16_t bit_val = BIT(i);
338 
339 		if (context & bit_val) {
340 			shell_print(sh, "%*s%s (0x%04X)", indent, "", context_bit_to_str(bit_val),
341 				    bit_val);
342 		}
343 	}
344 }
345 
print_codec_meta_stream_context(const struct shell * sh,size_t indent,enum bt_audio_context context)346 static inline void print_codec_meta_stream_context(const struct shell *sh, size_t indent,
347 						   enum bt_audio_context context)
348 {
349 	shell_print(sh, "%*sStreaming audio contexts:", indent, "");
350 
351 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
352 
353 	/* There can be up to 16 bits set in the field */
354 	for (size_t i = 0U; i < 16; i++) {
355 		const uint16_t bit_val = BIT(i);
356 
357 		if (context & bit_val) {
358 			shell_print(sh, "%*s%s (0x%04X)", indent, "", context_bit_to_str(bit_val),
359 				    bit_val);
360 		}
361 	}
362 }
363 
print_codec_meta_program_info(const struct shell * sh,size_t indent,const uint8_t * program_info,uint8_t program_info_len)364 static inline void print_codec_meta_program_info(const struct shell *sh, size_t indent,
365 						 const uint8_t *program_info,
366 						 uint8_t program_info_len)
367 {
368 	shell_print(sh, "%*sProgram info:", indent, "");
369 
370 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
371 
372 	shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
373 	for (uint8_t i = 0U; i < program_info_len; i++) {
374 		shell_fprintf(sh, SHELL_NORMAL, "%c", (char)program_info[i]);
375 	}
376 
377 	shell_fprintf(sh, SHELL_NORMAL, "\n");
378 }
379 
print_codec_meta_language(const struct shell * sh,size_t indent,const uint8_t lang[BT_AUDIO_LANG_SIZE])380 static inline void print_codec_meta_language(const struct shell *sh, size_t indent,
381 					     const uint8_t lang[BT_AUDIO_LANG_SIZE])
382 {
383 	shell_print(sh, "%*sLanguage: %c%c%c", indent, "", (char)lang[0], (char)lang[1],
384 		    (char)lang[2]);
385 }
386 
print_codec_meta_ccid_list(const struct shell * sh,size_t indent,const uint8_t * ccid_list,uint8_t ccid_list_len)387 static inline void print_codec_meta_ccid_list(const struct shell *sh, size_t indent,
388 					      const uint8_t *ccid_list, uint8_t ccid_list_len)
389 {
390 	shell_print(sh, "%*sCCID list:", indent, "");
391 
392 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
393 
394 	/* There can be up to 16 bits set in the field */
395 	for (uint8_t i = 0U; i < ccid_list_len; i++) {
396 		shell_print(sh, "%*s0x%02X ", indent, "", ccid_list[i]);
397 	}
398 }
399 
parental_rating_to_str(enum bt_audio_parental_rating parental_rating)400 static inline char *parental_rating_to_str(enum bt_audio_parental_rating parental_rating)
401 {
402 	switch (parental_rating) {
403 	case BT_AUDIO_PARENTAL_RATING_NO_RATING:
404 		return "No rating";
405 	case BT_AUDIO_PARENTAL_RATING_AGE_ANY:
406 		return "Any";
407 	case BT_AUDIO_PARENTAL_RATING_AGE_5_OR_ABOVE:
408 		return "Age 5 or above";
409 	case BT_AUDIO_PARENTAL_RATING_AGE_6_OR_ABOVE:
410 		return "Age 6 or above";
411 	case BT_AUDIO_PARENTAL_RATING_AGE_7_OR_ABOVE:
412 		return "Age 7 or above";
413 	case BT_AUDIO_PARENTAL_RATING_AGE_8_OR_ABOVE:
414 		return "Age 8 or above";
415 	case BT_AUDIO_PARENTAL_RATING_AGE_9_OR_ABOVE:
416 		return "Age 9 or above";
417 	case BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE:
418 		return "Age 10 or above";
419 	case BT_AUDIO_PARENTAL_RATING_AGE_11_OR_ABOVE:
420 		return "Age 11 or above";
421 	case BT_AUDIO_PARENTAL_RATING_AGE_12_OR_ABOVE:
422 		return "Age 12 or above";
423 	case BT_AUDIO_PARENTAL_RATING_AGE_13_OR_ABOVE:
424 		return "Age 13 or above";
425 	case BT_AUDIO_PARENTAL_RATING_AGE_14_OR_ABOVE:
426 		return "Age 14 or above";
427 	case BT_AUDIO_PARENTAL_RATING_AGE_15_OR_ABOVE:
428 		return "Age 15 or above";
429 	case BT_AUDIO_PARENTAL_RATING_AGE_16_OR_ABOVE:
430 		return "Age 16 or above";
431 	case BT_AUDIO_PARENTAL_RATING_AGE_17_OR_ABOVE:
432 		return "Age 17 or above";
433 	case BT_AUDIO_PARENTAL_RATING_AGE_18_OR_ABOVE:
434 		return "Age 18 or above";
435 	default:
436 		return "Unknown rating";
437 	}
438 }
439 
print_codec_meta_parental_rating(const struct shell * sh,size_t indent,enum bt_audio_parental_rating parental_rating)440 static inline void print_codec_meta_parental_rating(const struct shell *sh, size_t indent,
441 						    enum bt_audio_parental_rating parental_rating)
442 {
443 	shell_print(sh, "%*sRating: %s (0x%02X)", indent, "",
444 		    parental_rating_to_str(parental_rating), (uint8_t)parental_rating);
445 }
446 
print_codec_meta_program_info_uri(const struct shell * sh,size_t indent,const uint8_t * program_info_uri,uint8_t program_info_uri_len)447 static inline void print_codec_meta_program_info_uri(const struct shell *sh, size_t indent,
448 						     const uint8_t *program_info_uri,
449 						     uint8_t program_info_uri_len)
450 {
451 	shell_print(sh, "%*sProgram info URI:", indent, "");
452 
453 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
454 
455 	shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
456 
457 	for (uint8_t i = 0U; i < program_info_uri_len; i++) {
458 		shell_fprintf(sh, SHELL_NORMAL, "%c", (char)program_info_uri[i]);
459 	}
460 
461 	shell_fprintf(sh, SHELL_NORMAL, "\n");
462 }
463 
print_codec_meta_audio_active_state(const struct shell * sh,size_t indent,enum bt_audio_active_state state)464 static inline void print_codec_meta_audio_active_state(const struct shell *sh, size_t indent,
465 						       enum bt_audio_active_state state)
466 {
467 	shell_print(sh, "%*sAudio active state: %s (0x%02X)", indent, "",
468 		    state == BT_AUDIO_ACTIVE_STATE_ENABLED ? "enabled" : "disabled",
469 		    (uint8_t)state);
470 }
471 
print_codec_meta_bcast_audio_immediate_rend_flag(const struct shell * sh,size_t indent)472 static inline void print_codec_meta_bcast_audio_immediate_rend_flag(const struct shell *sh,
473 								    size_t indent)
474 {
475 	shell_print(sh, "%*sBroadcast audio immediate rendering flag set", indent, "");
476 }
477 
print_codec_meta_extended(const struct shell * sh,size_t indent,const uint8_t * extended_meta,size_t extended_meta_len)478 static inline void print_codec_meta_extended(const struct shell *sh, size_t indent,
479 					     const uint8_t *extended_meta, size_t extended_meta_len)
480 {
481 	shell_print(sh, "%*sExtended metadata:", indent, "");
482 
483 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
484 
485 	shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
486 
487 	for (uint8_t i = 0U; i < extended_meta_len; i++) {
488 		shell_fprintf(sh, SHELL_NORMAL, "%u", (uint8_t)extended_meta[i]);
489 	}
490 
491 	shell_fprintf(sh, SHELL_NORMAL, "\n");
492 }
493 
print_codec_meta_vendor(const struct shell * sh,size_t indent,const uint8_t * vendor_meta,size_t vender_meta_len)494 static inline void print_codec_meta_vendor(const struct shell *sh, size_t indent,
495 					   const uint8_t *vendor_meta, size_t vender_meta_len)
496 {
497 	shell_print(sh, "%*sVendor metadata:", indent, "");
498 
499 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
500 
501 	shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
502 
503 	for (uint8_t i = 0U; i < vender_meta_len; i++) {
504 		shell_fprintf(sh, SHELL_NORMAL, "%u", (uint8_t)vendor_meta[i]);
505 	}
506 
507 	shell_fprintf(sh, SHELL_NORMAL, "\n");
508 }
509 
codec_cap_freq_bit_to_str(enum bt_audio_codec_cap_freq freq)510 static inline char *codec_cap_freq_bit_to_str(enum bt_audio_codec_cap_freq freq)
511 {
512 	switch (freq) {
513 	case BT_AUDIO_CODEC_CAP_FREQ_8KHZ:
514 		return "8000 Hz";
515 	case BT_AUDIO_CODEC_CAP_FREQ_11KHZ:
516 		return "11025 Hz";
517 	case BT_AUDIO_CODEC_CAP_FREQ_16KHZ:
518 		return "16000 Hz";
519 	case BT_AUDIO_CODEC_CAP_FREQ_22KHZ:
520 		return "22050 Hz";
521 	case BT_AUDIO_CODEC_CAP_FREQ_24KHZ:
522 		return "24000 Hz";
523 	case BT_AUDIO_CODEC_CAP_FREQ_32KHZ:
524 		return "32000 Hz";
525 	case BT_AUDIO_CODEC_CAP_FREQ_44KHZ:
526 		return "44100 Hz";
527 	case BT_AUDIO_CODEC_CAP_FREQ_48KHZ:
528 		return "48000 Hz";
529 	case BT_AUDIO_CODEC_CAP_FREQ_88KHZ:
530 		return "88200 Hz";
531 	case BT_AUDIO_CODEC_CAP_FREQ_96KHZ:
532 		return "96000 Hz";
533 	case BT_AUDIO_CODEC_CAP_FREQ_176KHZ:
534 		return "176400 Hz";
535 	case BT_AUDIO_CODEC_CAP_FREQ_192KHZ:
536 		return "192000 Hz";
537 	case BT_AUDIO_CODEC_CAP_FREQ_384KHZ:
538 		return "384000 Hz";
539 	default:
540 		return "Unknown supported frequency";
541 	}
542 }
543 
print_codec_cap_freq(const struct shell * sh,size_t indent,enum bt_audio_codec_cap_freq freq)544 static inline void print_codec_cap_freq(const struct shell *sh, size_t indent,
545 					enum bt_audio_codec_cap_freq freq)
546 {
547 	shell_print(sh, "%*sSupported sampling frequencies:", indent, "");
548 
549 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
550 	/* There can be up to 16 bits set in the field */
551 	for (size_t i = 0; i < 16; i++) {
552 		const uint16_t bit_val = BIT(i);
553 
554 		if (freq & bit_val) {
555 			shell_print(sh, "%*s%s (0x%04X)", indent, "",
556 				    codec_cap_freq_bit_to_str(bit_val), bit_val);
557 		}
558 	}
559 }
560 
codec_cap_frame_dur_bit_to_str(enum bt_audio_codec_cap_frame_dur frame_dur)561 static inline char *codec_cap_frame_dur_bit_to_str(enum bt_audio_codec_cap_frame_dur frame_dur)
562 {
563 	switch (frame_dur) {
564 	case BT_AUDIO_CODEC_CAP_DURATION_7_5:
565 		return "7.5 ms";
566 	case BT_AUDIO_CODEC_CAP_DURATION_10:
567 		return "10 ms";
568 	case BT_AUDIO_CODEC_CAP_DURATION_PREFER_7_5:
569 		return "7.5 ms preferred";
570 	case BT_AUDIO_CODEC_CAP_DURATION_PREFER_10:
571 		return "10 ms preferred";
572 	default:
573 		return "Unknown frame duration";
574 	}
575 }
576 
print_codec_cap_frame_dur(const struct shell * sh,size_t indent,enum bt_audio_codec_cap_frame_dur frame_dur)577 static inline void print_codec_cap_frame_dur(const struct shell *sh, size_t indent,
578 					     enum bt_audio_codec_cap_frame_dur frame_dur)
579 {
580 	shell_print(sh, "%*sSupported frame durations:", indent, "");
581 
582 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
583 	/* There can be up to 8 bits set in the field */
584 	for (size_t i = 0; i < 8; i++) {
585 		const uint8_t bit_val = BIT(i);
586 
587 		if (frame_dur & bit_val) {
588 			shell_print(sh, "%*s%s (0x%02X)", indent, "",
589 				    codec_cap_frame_dur_bit_to_str(bit_val), bit_val);
590 		}
591 	}
592 }
593 
codec_cap_chan_count_bit_to_str(enum bt_audio_codec_cap_chan_count chan_count)594 static inline char *codec_cap_chan_count_bit_to_str(enum bt_audio_codec_cap_chan_count chan_count)
595 {
596 	switch (chan_count) {
597 	case BT_AUDIO_CODEC_CAP_CHAN_COUNT_1:
598 		return "1 channel";
599 	case BT_AUDIO_CODEC_CAP_CHAN_COUNT_2:
600 		return "2 channels";
601 	case BT_AUDIO_CODEC_CAP_CHAN_COUNT_3:
602 		return "3 channels";
603 	case BT_AUDIO_CODEC_CAP_CHAN_COUNT_4:
604 		return "4 channels";
605 	case BT_AUDIO_CODEC_CAP_CHAN_COUNT_5:
606 		return "5 channels";
607 	case BT_AUDIO_CODEC_CAP_CHAN_COUNT_6:
608 		return "6 channels";
609 	case BT_AUDIO_CODEC_CAP_CHAN_COUNT_7:
610 		return "7 channels";
611 	case BT_AUDIO_CODEC_CAP_CHAN_COUNT_8:
612 		return "8 channels";
613 	default:
614 		return "Unknown channel count";
615 	}
616 }
617 
print_codec_cap_chan_count(const struct shell * sh,size_t indent,enum bt_audio_codec_cap_chan_count chan_count)618 static inline void print_codec_cap_chan_count(const struct shell *sh, size_t indent,
619 					      enum bt_audio_codec_cap_chan_count chan_count)
620 {
621 	shell_print(sh, "%*sSupported channel counts:", indent, "");
622 
623 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
624 	/* There can be up to 8 bits set in the field */
625 	for (size_t i = 0; i < 8; i++) {
626 		const uint8_t bit_val = BIT(i);
627 
628 		if (chan_count & bit_val) {
629 			shell_print(sh, "%*s%s (0x%02X)", indent, "",
630 				    codec_cap_chan_count_bit_to_str(bit_val), bit_val);
631 		}
632 	}
633 }
634 
print_codec_cap_octets_per_codec_frame(const struct shell * sh,size_t indent,const struct bt_audio_codec_octets_per_codec_frame * codec_frame)635 static inline void print_codec_cap_octets_per_codec_frame(
636 	const struct shell *sh, size_t indent,
637 	const struct bt_audio_codec_octets_per_codec_frame *codec_frame)
638 {
639 	shell_print(sh, "%*sSupported octets per codec frame counts:", indent, "");
640 
641 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
642 	shell_print(sh, "%*sMin: %u", indent, "", codec_frame->min);
643 	shell_print(sh, "%*sMax: %u", indent, "", codec_frame->max);
644 }
645 
print_codec_cap_max_codec_frames_per_sdu(const struct shell * sh,size_t indent,uint8_t codec_frames_per_sdu)646 static inline void print_codec_cap_max_codec_frames_per_sdu(const struct shell *sh, size_t indent,
647 							    uint8_t codec_frames_per_sdu)
648 {
649 	shell_print(sh, "%*sSupported max codec frames per SDU: %u", indent, "",
650 		    codec_frames_per_sdu);
651 }
652 
print_codec_cap(const struct shell * sh,size_t indent,const struct bt_audio_codec_cap * codec_cap)653 static inline void print_codec_cap(const struct shell *sh, size_t indent,
654 				   const struct bt_audio_codec_cap *codec_cap)
655 {
656 	shell_print(sh, "%*scodec cap id 0x%02x cid 0x%04x vid 0x%04x", indent, "", codec_cap->id,
657 		    codec_cap->cid, codec_cap->vid);
658 
659 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
660 
661 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0
662 	shell_print(sh, "%*sCodec specific capabilities:", indent, "");
663 
664 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
665 	if (codec_cap->data_len == 0U) {
666 		shell_print(sh, "%*sNone", indent, "");
667 	} else if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) {
668 		struct bt_audio_codec_octets_per_codec_frame codec_frame;
669 		int ret;
670 
671 		ret = bt_audio_codec_cap_get_freq(codec_cap);
672 		if (ret >= 0) {
673 			print_codec_cap_freq(sh, indent, (enum bt_audio_codec_cap_freq)ret);
674 		}
675 
676 		ret = bt_audio_codec_cap_get_frame_dur(codec_cap);
677 		if (ret >= 0) {
678 			print_codec_cap_frame_dur(sh, indent,
679 						  (enum bt_audio_codec_cap_frame_dur)ret);
680 		}
681 
682 		ret = bt_audio_codec_cap_get_supported_audio_chan_counts(codec_cap, true);
683 		if (ret >= 0) {
684 			print_codec_cap_chan_count(sh, indent,
685 						   (enum bt_audio_codec_cap_chan_count)ret);
686 		}
687 
688 		ret = bt_audio_codec_cap_get_octets_per_frame(codec_cap, &codec_frame);
689 		if (ret >= 0) {
690 			print_codec_cap_octets_per_codec_frame(sh, indent, &codec_frame);
691 		}
692 
693 		ret = bt_audio_codec_cap_get_max_codec_frames_per_sdu(codec_cap, true);
694 		if (ret >= 0) {
695 			print_codec_cap_max_codec_frames_per_sdu(sh, indent, (uint8_t)ret);
696 		}
697 	} else { /* If not LC3, we cannot assume it's LTV */
698 		shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
699 
700 		for (uint8_t i = 0U; i < codec_cap->data_len; i++) {
701 			shell_fprintf(sh, SHELL_NORMAL, "%*s%02X", indent, "", codec_cap->data[i]);
702 		}
703 
704 		shell_fprintf(sh, SHELL_NORMAL, "\n");
705 	}
706 
707 	/* Reduce for metadata*/
708 	indent -= SHELL_PRINT_INDENT_LEVEL_SIZE;
709 #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */
710 
711 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0
712 	shell_print(sh, "%*sCodec capabilities metadata:", indent, "");
713 
714 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
715 	if (codec_cap->meta_len == 0U) {
716 		shell_print(sh, "%*sNone", indent, "");
717 	} else {
718 		const uint8_t *data;
719 		int ret;
720 
721 		ret = bt_audio_codec_cap_meta_get_pref_context(codec_cap);
722 		if (ret >= 0) {
723 			print_codec_meta_pref_context(sh, indent, (enum bt_audio_context)ret);
724 		}
725 
726 		ret = bt_audio_codec_cap_meta_get_stream_context(codec_cap);
727 		if (ret >= 0) {
728 			print_codec_meta_stream_context(sh, indent, (enum bt_audio_context)ret);
729 		}
730 
731 		ret = bt_audio_codec_cap_meta_get_program_info(codec_cap, &data);
732 		if (ret >= 0) {
733 			print_codec_meta_program_info(sh, indent, data, (uint8_t)ret);
734 		}
735 
736 		ret = bt_audio_codec_cap_meta_get_lang(codec_cap, &data);
737 		if (ret >= 0) {
738 			print_codec_meta_language(sh, indent, data);
739 		}
740 
741 		ret = bt_audio_codec_cap_meta_get_ccid_list(codec_cap, &data);
742 		if (ret >= 0) {
743 			print_codec_meta_ccid_list(sh, indent, data, (uint8_t)ret);
744 		}
745 
746 		ret = bt_audio_codec_cap_meta_get_parental_rating(codec_cap);
747 		if (ret >= 0) {
748 			print_codec_meta_parental_rating(sh, indent,
749 							 (enum bt_audio_parental_rating)ret);
750 		}
751 
752 		ret = bt_audio_codec_cap_meta_get_audio_active_state(codec_cap);
753 		if (ret >= 0) {
754 			print_codec_meta_audio_active_state(sh, indent,
755 							    (enum bt_audio_active_state)ret);
756 		}
757 
758 		ret = bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(codec_cap);
759 		if (ret >= 0) {
760 			print_codec_meta_bcast_audio_immediate_rend_flag(sh, indent);
761 		}
762 
763 		ret = bt_audio_codec_cap_meta_get_extended(codec_cap, &data);
764 		if (ret >= 0) {
765 			print_codec_meta_extended(sh, indent, data, (uint8_t)ret);
766 		}
767 
768 		ret = bt_audio_codec_cap_meta_get_vendor(codec_cap, &data);
769 		if (ret >= 0) {
770 			print_codec_meta_vendor(sh, indent, data, (uint8_t)ret);
771 		}
772 	}
773 #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */
774 }
775 
print_codec_cfg_freq(const struct shell * sh,size_t indent,enum bt_audio_codec_cfg_freq freq)776 static inline void print_codec_cfg_freq(const struct shell *sh, size_t indent,
777 					enum bt_audio_codec_cfg_freq freq)
778 {
779 	shell_print(sh, "%*sSampling frequency: %u Hz (0x%04X)", indent, "",
780 		    bt_audio_codec_cfg_freq_to_freq_hz(freq), (uint16_t)freq);
781 }
782 
print_codec_cfg_frame_dur(const struct shell * sh,size_t indent,enum bt_audio_codec_cfg_frame_dur frame_dur)783 static inline void print_codec_cfg_frame_dur(const struct shell *sh, size_t indent,
784 					     enum bt_audio_codec_cfg_frame_dur frame_dur)
785 {
786 	shell_print(sh, "%*sFrame duration: %u us (0x%02X)", indent, "",
787 		    bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur), (uint8_t)frame_dur);
788 }
789 
chan_location_bit_to_str(enum bt_audio_location chan_allocation)790 static inline char *chan_location_bit_to_str(enum bt_audio_location chan_allocation)
791 {
792 	switch (chan_allocation) {
793 	case BT_AUDIO_LOCATION_MONO_AUDIO:
794 		return "Mono";
795 	case BT_AUDIO_LOCATION_FRONT_LEFT:
796 		return "Front left";
797 	case BT_AUDIO_LOCATION_FRONT_RIGHT:
798 		return "Front right";
799 	case BT_AUDIO_LOCATION_FRONT_CENTER:
800 		return "Front center";
801 	case BT_AUDIO_LOCATION_LOW_FREQ_EFFECTS_1:
802 		return "Low frequency effects 1";
803 	case BT_AUDIO_LOCATION_BACK_LEFT:
804 		return "Back left";
805 	case BT_AUDIO_LOCATION_BACK_RIGHT:
806 		return "Back right";
807 	case BT_AUDIO_LOCATION_FRONT_LEFT_OF_CENTER:
808 		return "Front left of center";
809 	case BT_AUDIO_LOCATION_FRONT_RIGHT_OF_CENTER:
810 		return "Front right of center";
811 	case BT_AUDIO_LOCATION_BACK_CENTER:
812 		return "Back center";
813 	case BT_AUDIO_LOCATION_LOW_FREQ_EFFECTS_2:
814 		return "Low frequency effects 2";
815 	case BT_AUDIO_LOCATION_SIDE_LEFT:
816 		return "Side left";
817 	case BT_AUDIO_LOCATION_SIDE_RIGHT:
818 		return "Side right";
819 	case BT_AUDIO_LOCATION_TOP_FRONT_LEFT:
820 		return "Top front left";
821 	case BT_AUDIO_LOCATION_TOP_FRONT_RIGHT:
822 		return "Top front right";
823 	case BT_AUDIO_LOCATION_TOP_FRONT_CENTER:
824 		return "Top front center";
825 	case BT_AUDIO_LOCATION_TOP_CENTER:
826 		return "Top center";
827 	case BT_AUDIO_LOCATION_TOP_BACK_LEFT:
828 		return "Top back left";
829 	case BT_AUDIO_LOCATION_TOP_BACK_RIGHT:
830 		return "Top back right";
831 	case BT_AUDIO_LOCATION_TOP_SIDE_LEFT:
832 		return "Top side left";
833 	case BT_AUDIO_LOCATION_TOP_SIDE_RIGHT:
834 		return "Top side right";
835 	case BT_AUDIO_LOCATION_TOP_BACK_CENTER:
836 		return "Top back center";
837 	case BT_AUDIO_LOCATION_BOTTOM_FRONT_CENTER:
838 		return "Bottom front center";
839 	case BT_AUDIO_LOCATION_BOTTOM_FRONT_LEFT:
840 		return "Bottom front left";
841 	case BT_AUDIO_LOCATION_BOTTOM_FRONT_RIGHT:
842 		return "Bottom front right";
843 	case BT_AUDIO_LOCATION_FRONT_LEFT_WIDE:
844 		return "Front left wide";
845 	case BT_AUDIO_LOCATION_FRONT_RIGHT_WIDE:
846 		return "Front right wde";
847 	case BT_AUDIO_LOCATION_LEFT_SURROUND:
848 		return "Left surround";
849 	case BT_AUDIO_LOCATION_RIGHT_SURROUND:
850 		return "Right surround";
851 	default:
852 		return "Unknown location";
853 	}
854 }
855 
print_codec_cfg_chan_allocation(const struct shell * sh,size_t indent,enum bt_audio_location chan_allocation)856 static inline void print_codec_cfg_chan_allocation(const struct shell *sh, size_t indent,
857 						   enum bt_audio_location chan_allocation)
858 {
859 	shell_print(sh, "%*sChannel allocation:", indent, "");
860 
861 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
862 
863 	if (chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO) {
864 		shell_print(sh, "%*s Mono", indent, "");
865 	} else {
866 		/* There can be up to 32 bits set in the field */
867 		for (size_t i = 0; i < 32; i++) {
868 			const uint8_t bit_val = BIT(i);
869 
870 			if (chan_allocation & bit_val) {
871 				shell_print(sh, "%*s%s (0x%08X)", indent, "",
872 					    chan_location_bit_to_str(bit_val), bit_val);
873 			}
874 		}
875 	}
876 }
877 
print_codec_cfg_octets_per_frame(const struct shell * sh,size_t indent,uint16_t octets_per_frame)878 static inline void print_codec_cfg_octets_per_frame(const struct shell *sh, size_t indent,
879 						    uint16_t octets_per_frame)
880 {
881 	shell_print(sh, "%*sOctets per codec frame: %u", indent, "", octets_per_frame);
882 }
883 
print_codec_cfg_frame_blocks_per_sdu(const struct shell * sh,size_t indent,uint8_t frame_blocks_per_sdu)884 static inline void print_codec_cfg_frame_blocks_per_sdu(const struct shell *sh, size_t indent,
885 							uint8_t frame_blocks_per_sdu)
886 {
887 	shell_print(sh, "%*sCodec frame blocks per SDU: %u", indent, "", frame_blocks_per_sdu);
888 }
889 
print_codec_cfg(const struct shell * sh,size_t indent,const struct bt_audio_codec_cfg * codec_cfg)890 static inline void print_codec_cfg(const struct shell *sh, size_t indent,
891 				   const struct bt_audio_codec_cfg *codec_cfg)
892 {
893 	shell_print(sh, "%*scodec cfg id 0x%02x cid 0x%04x vid 0x%04x count %u", indent, "",
894 		    codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len);
895 
896 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
897 
898 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
899 	shell_print(sh, "%*sCodec specific configuration:", indent, "");
900 
901 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
902 	if (codec_cfg->data_len == 0U) {
903 		shell_print(sh, "%*sNone", indent, "");
904 	} else if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
905 		enum bt_audio_location chan_allocation;
906 		int ret;
907 
908 		ret = bt_audio_codec_cfg_get_freq(codec_cfg);
909 		if (ret >= 0) {
910 			print_codec_cfg_freq(sh, indent, (enum bt_audio_codec_cfg_freq)ret);
911 		}
912 
913 		ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
914 		if (ret >= 0) {
915 			print_codec_cfg_frame_dur(sh, indent,
916 						  (enum bt_audio_codec_cfg_frame_dur)ret);
917 		}
918 
919 		ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation, false);
920 		if (ret == 0) {
921 			print_codec_cfg_chan_allocation(sh, indent, chan_allocation);
922 		}
923 
924 		ret = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg);
925 		if (ret >= 0) {
926 			print_codec_cfg_octets_per_frame(sh, indent, (uint16_t)ret);
927 		}
928 
929 		ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, false);
930 		if (ret >= 0) {
931 			print_codec_cfg_frame_blocks_per_sdu(sh, indent, (uint8_t)ret);
932 		}
933 	} else { /* If not LC3, we cannot assume it's LTV */
934 		shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
935 
936 		for (uint8_t i = 0U; i < codec_cfg->data_len; i++) {
937 			shell_fprintf(sh, SHELL_NORMAL, "%*s%02X", indent, "", codec_cfg->data[i]);
938 		}
939 
940 		shell_fprintf(sh, SHELL_NORMAL, "\n");
941 	}
942 
943 	/* Reduce for metadata*/
944 	indent -= SHELL_PRINT_INDENT_LEVEL_SIZE;
945 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
946 
947 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
948 	shell_print(sh, "%*sCodec specific metadata:", indent, "");
949 
950 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
951 	if (codec_cfg->meta_len == 0U) {
952 		shell_print(sh, "%*sNone", indent, "");
953 	} else {
954 		const uint8_t *data;
955 		int ret;
956 
957 		ret = bt_audio_codec_cfg_meta_get_pref_context(codec_cfg, true);
958 		if (ret >= 0) {
959 			print_codec_meta_pref_context(sh, indent, (enum bt_audio_context)ret);
960 		}
961 
962 		ret = bt_audio_codec_cfg_meta_get_stream_context(codec_cfg);
963 		if (ret >= 0) {
964 			print_codec_meta_stream_context(sh, indent, (enum bt_audio_context)ret);
965 		}
966 
967 		ret = bt_audio_codec_cfg_meta_get_program_info(codec_cfg, &data);
968 		if (ret >= 0) {
969 			print_codec_meta_program_info(sh, indent, data, (uint8_t)ret);
970 		}
971 
972 		ret = bt_audio_codec_cfg_meta_get_lang(codec_cfg, &data);
973 		if (ret >= 0) {
974 			print_codec_meta_language(sh, indent, data);
975 		}
976 
977 		ret = bt_audio_codec_cfg_meta_get_ccid_list(codec_cfg, &data);
978 		if (ret >= 0) {
979 			print_codec_meta_ccid_list(sh, indent, data, (uint8_t)ret);
980 		}
981 
982 		ret = bt_audio_codec_cfg_meta_get_parental_rating(codec_cfg);
983 		if (ret >= 0) {
984 			print_codec_meta_parental_rating(sh, indent,
985 							 (enum bt_audio_parental_rating)ret);
986 		}
987 
988 		ret = bt_audio_codec_cfg_meta_get_audio_active_state(codec_cfg);
989 		if (ret >= 0) {
990 			print_codec_meta_audio_active_state(sh, indent,
991 							    (enum bt_audio_active_state)ret);
992 		}
993 
994 		ret = bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(codec_cfg);
995 		if (ret >= 0) {
996 			print_codec_meta_bcast_audio_immediate_rend_flag(sh, indent);
997 		}
998 
999 		ret = bt_audio_codec_cfg_meta_get_extended(codec_cfg, &data);
1000 		if (ret >= 0) {
1001 			print_codec_meta_extended(sh, indent, data, (uint8_t)ret);
1002 		}
1003 
1004 		ret = bt_audio_codec_cfg_meta_get_vendor(codec_cfg, &data);
1005 		if (ret >= 0) {
1006 			print_codec_meta_vendor(sh, indent, data, (uint8_t)ret);
1007 		}
1008 	}
1009 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
1010 }
1011 
1012 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
1013 struct bap_broadcast_ac_param {
1014 	char *name;
1015 	size_t stream_cnt;
1016 	size_t chan_cnt;
1017 };
1018 
1019 int cap_ac_broadcast(const struct shell *sh, size_t argc, char **argv,
1020 		     const struct bap_broadcast_ac_param *param);
1021 
1022 extern struct shell_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
1023 extern struct broadcast_source default_source;
1024 extern struct named_lc3_preset default_broadcast_source_preset;
1025 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
1026 
print_base_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis * bis,void * user_data)1027 static inline bool print_base_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis *bis,
1028 					      void *user_data)
1029 {
1030 	size_t indent = 2 * SHELL_PRINT_INDENT_LEVEL_SIZE;
1031 	struct bt_bap_base_codec_id *codec_id = user_data;
1032 
1033 	shell_print(ctx_shell, "%*sBIS index: 0x%02X", indent, "", bis->index);
1034 
1035 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
1036 
1037 	/* Print CC data */
1038 	if (codec_id->id == BT_HCI_CODING_FORMAT_LC3) {
1039 		struct bt_audio_codec_cfg codec_cfg = {
1040 			.id = codec_id->id,
1041 			.cid = codec_id->cid,
1042 			.vid = codec_id->vid,
1043 		};
1044 		int err;
1045 
1046 		err = bt_bap_base_subgroup_bis_codec_to_codec_cfg(bis, &codec_cfg);
1047 		if (err == 0) {
1048 			print_codec_cfg(ctx_shell, indent, &codec_cfg);
1049 		} else {
1050 			shell_print(ctx_shell, "%*sCodec specific configuration:", indent, "");
1051 			print_ltv_array(ctx_shell, indent, bis->data, bis->data_len);
1052 		}
1053 	} else { /* If not LC3, we cannot assume it's LTV */
1054 		shell_print(ctx_shell, "%*sCodec specific configuration:", indent, "");
1055 
1056 		indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
1057 		shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, "");
1058 
1059 		for (uint8_t i = 0U; i < bis->data_len; i++) {
1060 			shell_fprintf(ctx_shell, SHELL_NORMAL, "%02X", bis->data[i]);
1061 		}
1062 
1063 		shell_fprintf(ctx_shell, SHELL_NORMAL, "\n");
1064 	}
1065 
1066 	return true;
1067 }
1068 
print_base_subgroup_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)1069 static inline bool print_base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup,
1070 					  void *user_data)
1071 {
1072 	size_t indent = 1 * SHELL_PRINT_INDENT_LEVEL_SIZE;
1073 	struct bt_bap_base_codec_id codec_id;
1074 	struct bt_audio_codec_cfg codec_cfg;
1075 	uint8_t *data;
1076 	int ret;
1077 
1078 	shell_print(ctx_shell, "Subgroup %p:", subgroup);
1079 
1080 	ret = bt_bap_base_get_subgroup_codec_id(subgroup, &codec_id);
1081 	if (ret < 0) {
1082 		return false;
1083 	}
1084 
1085 	shell_print(ctx_shell, "%*sCodec Format: 0x%02X", indent, "", codec_id.id);
1086 	shell_print(ctx_shell, "%*sCompany ID  : 0x%04X", indent, "", codec_id.cid);
1087 	shell_print(ctx_shell, "%*sVendor ID   : 0x%04X", indent, "", codec_id.vid);
1088 
1089 	ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &codec_cfg);
1090 	if (ret == 0) {
1091 		print_codec_cfg(ctx_shell, indent, &codec_cfg);
1092 	} else {
1093 		/* If we cannot store it in a codec_cfg, then we cannot easily print it as such */
1094 		ret = bt_bap_base_get_subgroup_codec_data(subgroup, &data);
1095 		if (ret < 0) {
1096 			return false;
1097 		}
1098 
1099 		shell_print(ctx_shell, "%*sCodec specific configuration:", indent, "");
1100 		indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
1101 
1102 		/* Print CC data */
1103 		if (codec_id.id == BT_HCI_CODING_FORMAT_LC3) {
1104 			print_ltv_array(ctx_shell, indent, data, (uint8_t)ret);
1105 		} else { /* If not LC3, we cannot assume it's LTV */
1106 			shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, "");
1107 
1108 			for (uint8_t i = 0U; i < (uint8_t)ret; i++) {
1109 				shell_fprintf(ctx_shell, SHELL_NORMAL, "%c", data[i]);
1110 			}
1111 
1112 			shell_fprintf(ctx_shell, SHELL_NORMAL, "\n");
1113 		}
1114 
1115 		ret = bt_bap_base_get_subgroup_codec_meta(subgroup, &data);
1116 		if (ret < 0) {
1117 			return false;
1118 		}
1119 
1120 		shell_print(ctx_shell,
1121 			    "%*sCodec specific metadata:", indent - SHELL_PRINT_INDENT_LEVEL_SIZE,
1122 			    "");
1123 
1124 		/* Print metadata */
1125 		if (codec_id.id == BT_HCI_CODING_FORMAT_LC3) {
1126 			print_ltv_array(ctx_shell, indent, data, (uint8_t)ret);
1127 		} else { /* If not LC3, we cannot assume it's LTV */
1128 			shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, "");
1129 
1130 			for (uint8_t i = 0U; i < (uint8_t)ret; i++) {
1131 				shell_fprintf(ctx_shell, SHELL_NORMAL, "%c", data[i]);
1132 			}
1133 
1134 			shell_fprintf(ctx_shell, SHELL_NORMAL, "\n");
1135 		}
1136 	}
1137 
1138 	ret = bt_bap_base_subgroup_foreach_bis(subgroup, print_base_subgroup_bis_cb, &codec_id);
1139 	if (ret < 0) {
1140 		return false;
1141 	}
1142 
1143 	return true;
1144 }
1145 
print_base(const struct bt_bap_base * base)1146 static inline void print_base(const struct bt_bap_base *base)
1147 {
1148 	int err;
1149 
1150 	shell_print(ctx_shell, "Presentation delay: %d", bt_bap_base_get_pres_delay(base));
1151 	shell_print(ctx_shell, "Subgroup count: %d", bt_bap_base_get_subgroup_count(base));
1152 
1153 	err = bt_bap_base_foreach_subgroup(base, print_base_subgroup_cb, NULL);
1154 	if (err < 0) {
1155 		shell_info(ctx_shell, "Invalid BASE: %d", err);
1156 	}
1157 }
1158 
copy_unicast_stream_preset(struct shell_stream * stream,const struct named_lc3_preset * named_preset)1159 static inline void copy_unicast_stream_preset(struct shell_stream *stream,
1160 					      const struct named_lc3_preset *named_preset)
1161 {
1162 	memcpy(&stream->qos, &named_preset->preset.qos, sizeof(stream->qos));
1163 	memcpy(&stream->codec_cfg, &named_preset->preset.codec_cfg, sizeof(stream->codec_cfg));
1164 }
1165 
copy_broadcast_source_preset(struct broadcast_source * source,const struct named_lc3_preset * named_preset)1166 static inline void copy_broadcast_source_preset(struct broadcast_source *source,
1167 						const struct named_lc3_preset *named_preset)
1168 {
1169 	memcpy(&source->qos, &named_preset->preset.qos, sizeof(source->qos));
1170 	memcpy(&source->codec_cfg, &named_preset->preset.codec_cfg, sizeof(source->codec_cfg));
1171 }
1172 #endif /* CONFIG_BT_AUDIO */
1173 
1174 #endif /* AUDIO_SHELL_AUDIO_H */
1175