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 "host/shell/bt.h"
36 
37 #define SHELL_PRINT_INDENT_LEVEL_SIZE 2
38 #define MAX_CODEC_FRAMES_PER_SDU      4U
39 
40 extern struct bt_csip_set_member_svc_inst *svc_inst;
41 
42 ssize_t audio_ad_data_add(struct bt_data *data, const size_t data_size, const bool discoverable,
43 			  const bool connectable);
44 ssize_t audio_pa_data_add(struct bt_data *data_array, const size_t data_array_size);
45 ssize_t csis_ad_data_add(struct bt_data *data, const size_t data_size, const bool discoverable);
46 size_t cap_acceptor_ad_data_add(struct bt_data data[], size_t data_size, bool discoverable);
47 size_t bap_scan_delegator_ad_data_add(struct bt_data data[], size_t data_size);
48 size_t gmap_ad_data_add(struct bt_data data[], size_t data_size);
49 size_t pbp_ad_data_add(struct bt_data data[], size_t data_size);
50 ssize_t cap_initiator_ad_data_add(struct bt_data *data_array, const size_t data_array_size,
51 				  const bool discoverable, const bool connectable);
52 ssize_t cap_initiator_pa_data_add(struct bt_data *data_array, const size_t data_array_size);
53 
54 #if defined(CONFIG_BT_AUDIO)
55 /* Must guard before including audio.h as audio.h uses Kconfigs guarded by
56  * CONFIG_BT_AUDIO
57  */
58 #include <zephyr/bluetooth/audio/audio.h>
59 #include <zephyr/bluetooth/audio/bap.h>
60 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
61 #include <zephyr/bluetooth/audio/cap.h>
62 
63 unsigned long bap_get_stats_interval(void);
64 
65 #if defined(CONFIG_LIBLC3)
66 #include "lc3.h"
67 
68 #define USB_SAMPLE_RATE            48000U
69 #define LC3_MAX_SAMPLE_RATE        48000U
70 #define LC3_MAX_FRAME_DURATION_US  10000U
71 #define LC3_MAX_NUM_SAMPLES_MONO   ((LC3_MAX_FRAME_DURATION_US * LC3_MAX_SAMPLE_RATE) /            \
72 				    USEC_PER_SEC)
73 #define LC3_MAX_NUM_SAMPLES_STEREO (LC3_MAX_NUM_SAMPLES_MONO * 2U)
74 #endif /* CONFIG_LIBLC3 */
75 
76 #define LOCATION BT_AUDIO_LOCATION_FRONT_LEFT
77 #define CONTEXT                                                                                    \
78 	(BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL |                \
79 	 BT_AUDIO_CONTEXT_TYPE_MEDIA |                                                             \
80 	 COND_CODE_1(IS_ENABLED(CONFIG_BT_GMAP), (BT_AUDIO_CONTEXT_TYPE_GAME), (0)))
81 
82 const struct named_lc3_preset *gmap_get_named_preset(bool is_unicast, enum bt_audio_dir dir,
83 						     const char *preset_arg);
84 
85 struct named_lc3_preset {
86 	const char *name;
87 	struct bt_bap_lc3_preset preset;
88 };
89 
90 struct shell_stream {
91 	struct bt_cap_stream stream;
92 	struct bt_audio_codec_cfg codec_cfg;
93 	struct bt_bap_qos_cfg qos;
94 	bool is_tx;
95 	bool is_rx;
96 
97 #if defined(CONFIG_LIBLC3)
98 	uint32_t lc3_freq_hz;
99 	uint32_t lc3_frame_duration_us;
100 	uint16_t lc3_octets_per_frame;
101 	uint8_t lc3_frame_blocks_per_sdu;
102 	enum bt_audio_location lc3_chan_allocation;
103 	uint8_t lc3_chan_cnt;
104 #endif /* CONFIG_LIBLC3 */
105 
106 	union {
107 #if defined(CONFIG_BT_AUDIO_TX)
108 		struct {
109 			/* The uptime tick measured when stream was connected */
110 			int64_t connected_at_ticks;
111 			uint16_t seq_num;
112 #if defined(CONFIG_LIBLC3)
113 			atomic_t lc3_enqueue_cnt;
114 			bool active;
115 			size_t encoded_cnt;
116 			size_t lc3_sdu_cnt;
117 			lc3_encoder_mem_48k_t lc3_encoder_mem;
118 			lc3_encoder_t lc3_encoder;
119 #if defined(CONFIG_USB_DEVICE_AUDIO)
120 			/* Indicates where to read left USB data in the ring buffer */
121 			size_t left_read_idx;
122 			/* Indicates where to read right USB data in the ring buffer */
123 			size_t right_read_idx;
124 			size_t right_ring_buf_fail_cnt;
125 #endif /* CONFIG_USB_DEVICE_AUDIO */
126 #endif /* CONFIG_LIBLC3 */
127 		} tx;
128 #endif /* CONFIG_BT_AUDIO_TX */
129 
130 #if defined(CONFIG_BT_AUDIO_RX)
131 		struct {
132 			struct bt_iso_recv_info last_info;
133 			size_t empty_sdu_pkts;
134 			size_t valid_sdu_pkts;
135 			size_t lost_pkts;
136 			size_t err_pkts;
137 			size_t dup_psn;
138 			size_t rx_cnt;
139 			size_t dup_ts;
140 #if defined(CONFIG_LIBLC3)
141 			lc3_decoder_mem_48k_t lc3_decoder_mem;
142 			lc3_decoder_t lc3_decoder;
143 			size_t decoded_cnt;
144 #endif /* CONFIG_LIBLC3 */
145 		} rx;
146 #endif /* CONFIG_BT_AUDIO_RX */
147 	};
148 };
149 
150 const struct named_lc3_preset *bap_get_named_preset(bool is_unicast, enum bt_audio_dir dir,
151 						    const char *preset_arg);
152 
153 size_t bap_get_rx_streaming_cnt(void);
154 size_t bap_get_tx_streaming_cnt(void);
155 void bap_foreach_stream(void (*func)(struct shell_stream *sh_stream, void *data), void *data);
156 
157 int bap_usb_init(void);
158 
159 int bap_usb_add_frame_to_usb(enum bt_audio_location lc3_chan_allocation, const int16_t *frame,
160 			     size_t frame_size, uint32_t ts);
161 void bap_usb_clear_frames_to_usb(void);
162 uint16_t get_next_seq_num(struct bt_bap_stream *bap_stream);
163 struct shell_stream *shell_stream_from_bap_stream(struct bt_bap_stream *bap_stream);
164 struct bt_bap_stream *bap_stream_from_shell_stream(struct shell_stream *sh_stream);
165 bool bap_usb_can_get_full_sdu(struct shell_stream *sh_stream);
166 void bap_usb_get_frame(struct shell_stream *sh_stream, enum bt_audio_location chan_alloc,
167 		       int16_t buffer[]);
168 size_t bap_usb_get_frame_size(const struct shell_stream *sh_stream);
169 
170 struct broadcast_source {
171 	bool is_cap;
172 	union {
173 		struct bt_bap_broadcast_source *bap_source;
174 		struct bt_cap_broadcast_source *cap_source;
175 	};
176 	struct bt_audio_codec_cfg codec_cfg;
177 	struct bt_bap_qos_cfg qos;
178 };
179 
180 struct broadcast_sink {
181 	struct bt_bap_broadcast_sink *bap_sink;
182 	struct bt_le_per_adv_sync *pa_sync;
183 	uint8_t received_base[UINT8_MAX];
184 	uint8_t base_size;
185 	uint32_t broadcast_id;
186 	size_t stream_cnt;
187 	bool syncable;
188 };
189 
190 #define BAP_UNICAST_AC_MAX_CONN   2U
191 #define BAP_UNICAST_AC_MAX_SNK    (2U * BAP_UNICAST_AC_MAX_CONN)
192 #define BAP_UNICAST_AC_MAX_SRC    (2U * BAP_UNICAST_AC_MAX_CONN)
193 #define BAP_UNICAST_AC_MAX_PAIR   MAX(BAP_UNICAST_AC_MAX_SNK, BAP_UNICAST_AC_MAX_SRC)
194 #define BAP_UNICAST_AC_MAX_STREAM (BAP_UNICAST_AC_MAX_SNK + BAP_UNICAST_AC_MAX_SRC)
195 
196 #if defined(CONFIG_BT_BAP_UNICAST)
197 
198 #define UNICAST_SERVER_STREAM_COUNT                                                                \
199 	COND_CODE_1(CONFIG_BT_ASCS_ASE_SRC, (CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT), (0)) +             \
200 	COND_CODE_1(CONFIG_BT_ASCS_ASE_SNK, (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT), (0))
201 
202 #define UNICAST_CLIENT_STREAM_COUNT                                                                \
203 	COND_CODE_1(CONFIG_BT_BAP_UNICAST_CLIENT,                                                  \
204 		    (CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT +                                  \
205 		     CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT),                                  \
206 		    (0))
207 
208 extern struct shell_stream unicast_streams[CONFIG_BT_MAX_CONN * MAX(UNICAST_SERVER_STREAM_COUNT,
209 								    UNICAST_CLIENT_STREAM_COUNT)];
210 
211 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
212 
213 struct bap_unicast_ac_param {
214 	char *name;
215 	size_t conn_cnt;
216 	size_t snk_cnt[BAP_UNICAST_AC_MAX_CONN];
217 	size_t src_cnt[BAP_UNICAST_AC_MAX_CONN];
218 	size_t snk_chan_cnt;
219 	size_t src_chan_cnt;
220 };
221 
222 extern struct bt_bap_unicast_group *default_unicast_group;
223 extern struct bt_bap_ep *snks[CONFIG_BT_MAX_CONN][CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT];
224 extern struct bt_bap_ep *srcs[CONFIG_BT_MAX_CONN][CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT];
225 extern struct named_lc3_preset default_sink_preset;
226 extern struct named_lc3_preset default_source_preset;
227 
228 int bap_ac_create_unicast_group(const struct bap_unicast_ac_param *param,
229 				struct shell_stream *snk_uni_streams[], size_t snk_cnt,
230 				struct shell_stream *src_uni_streams[], size_t src_cnt);
231 
232 int cap_ac_unicast(const struct shell *sh, const struct bap_unicast_ac_param *param);
233 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
234 #endif /* CONFIG_BT_BAP_UNICAST */
235 
print_qos(const struct shell * sh,const struct bt_bap_qos_cfg * qos)236 static inline void print_qos(const struct shell *sh, const struct bt_bap_qos_cfg *qos)
237 {
238 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_UNICAST)
239 	shell_print(sh,
240 		    "QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u latency %u pd %u",
241 		    qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->latency,
242 		    qos->pd);
243 #else
244 	shell_print(sh, "QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u pd %u",
245 		    qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->pd);
246 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_UNICAST */
247 }
248 
249 struct print_ltv_info {
250 	const struct shell *sh;
251 	size_t indent;
252 	size_t cnt;
253 };
254 
print_ltv_elem(struct bt_data * data,void * user_data)255 static bool print_ltv_elem(struct bt_data *data, void *user_data)
256 {
257 	struct print_ltv_info *ltv_info = user_data;
258 	const size_t elem_indent = ltv_info->indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
259 
260 	shell_print(ltv_info->sh, "%*s#%zu: type 0x%02x value_len %u", ltv_info->indent, "",
261 		    ltv_info->cnt, data->type, data->data_len);
262 
263 	shell_fprintf(ltv_info->sh, SHELL_NORMAL, "%*s", elem_indent, "");
264 
265 	for (uint8_t i = 0U; i < data->data_len; i++) {
266 		shell_fprintf(ltv_info->sh, SHELL_NORMAL, "%02X", data->data[i]);
267 	}
268 
269 	shell_fprintf(ltv_info->sh, SHELL_NORMAL, "\n");
270 
271 	ltv_info->cnt++;
272 
273 	return true;
274 }
275 
print_ltv_array(const struct shell * sh,size_t indent,const uint8_t * ltv_data,size_t ltv_data_len)276 static void print_ltv_array(const struct shell *sh, size_t indent, const uint8_t *ltv_data,
277 			    size_t ltv_data_len)
278 {
279 	struct print_ltv_info ltv_info = {
280 		.sh = sh,
281 		.cnt = 0U,
282 		.indent = indent,
283 	};
284 	int err;
285 
286 	err = bt_audio_data_parse(ltv_data, ltv_data_len, print_ltv_elem, &ltv_info);
287 	if (err != 0 && err != -ECANCELED) {
288 		shell_error(sh, "%*sInvalid LTV data: %d", indent, "", err);
289 	}
290 }
291 
print_codec_meta_pref_context(const struct shell * sh,size_t indent,enum bt_audio_context context)292 static inline void print_codec_meta_pref_context(const struct shell *sh, size_t indent,
293 						 enum bt_audio_context context)
294 {
295 	shell_print(sh, "%*sPreferred audio contexts:", indent, "");
296 
297 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
298 
299 	/* There can be up to 16 bits set in the field */
300 	for (size_t i = 0U; i < 16; i++) {
301 		const uint16_t bit_val = BIT(i);
302 
303 		if (context & bit_val) {
304 			shell_print(sh, "%*s%s (0x%04X)", indent, "",
305 				    bt_audio_context_bit_to_str(bit_val), bit_val);
306 		}
307 	}
308 }
309 
print_codec_meta_stream_context(const struct shell * sh,size_t indent,enum bt_audio_context context)310 static inline void print_codec_meta_stream_context(const struct shell *sh, size_t indent,
311 						   enum bt_audio_context context)
312 {
313 	shell_print(sh, "%*sStreaming audio contexts:", indent, "");
314 
315 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
316 
317 	/* There can be up to 16 bits set in the field */
318 	for (size_t i = 0U; i < 16; i++) {
319 		const uint16_t bit_val = BIT(i);
320 
321 		if (context & bit_val) {
322 			shell_print(sh, "%*s%s (0x%04X)", indent, "",
323 				    bt_audio_context_bit_to_str(bit_val), bit_val);
324 		}
325 	}
326 }
327 
print_codec_meta_program_info(const struct shell * sh,size_t indent,const uint8_t * program_info,uint8_t program_info_len)328 static inline void print_codec_meta_program_info(const struct shell *sh, size_t indent,
329 						 const uint8_t *program_info,
330 						 uint8_t program_info_len)
331 {
332 	shell_print(sh, "%*sProgram info:", indent, "");
333 
334 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
335 
336 	shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
337 	for (uint8_t i = 0U; i < program_info_len; i++) {
338 		shell_fprintf(sh, SHELL_NORMAL, "%c", (char)program_info[i]);
339 	}
340 
341 	shell_fprintf(sh, SHELL_NORMAL, "\n");
342 }
343 
print_codec_meta_language(const struct shell * sh,size_t indent,const uint8_t lang[BT_AUDIO_LANG_SIZE])344 static inline void print_codec_meta_language(const struct shell *sh, size_t indent,
345 					     const uint8_t lang[BT_AUDIO_LANG_SIZE])
346 {
347 	shell_print(sh, "%*sLanguage: %c%c%c", indent, "", (char)lang[0], (char)lang[1],
348 		    (char)lang[2]);
349 }
350 
print_codec_meta_ccid_list(const struct shell * sh,size_t indent,const uint8_t * ccid_list,uint8_t ccid_list_len)351 static inline void print_codec_meta_ccid_list(const struct shell *sh, size_t indent,
352 					      const uint8_t *ccid_list, uint8_t ccid_list_len)
353 {
354 	shell_print(sh, "%*sCCID list:", indent, "");
355 
356 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
357 
358 	/* There can be up to 16 bits set in the field */
359 	for (uint8_t i = 0U; i < ccid_list_len; i++) {
360 		shell_print(sh, "%*s0x%02X ", indent, "", ccid_list[i]);
361 	}
362 }
363 
print_codec_meta_parental_rating(const struct shell * sh,size_t indent,enum bt_audio_parental_rating parental_rating)364 static inline void print_codec_meta_parental_rating(const struct shell *sh, size_t indent,
365 						    enum bt_audio_parental_rating parental_rating)
366 {
367 	shell_print(sh, "%*sRating: %s (0x%02X)", indent, "",
368 		    bt_audio_parental_rating_to_str(parental_rating), (uint8_t)parental_rating);
369 }
370 
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)371 static inline void print_codec_meta_program_info_uri(const struct shell *sh, size_t indent,
372 						     const uint8_t *program_info_uri,
373 						     uint8_t program_info_uri_len)
374 {
375 	shell_print(sh, "%*sProgram info URI:", indent, "");
376 
377 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
378 
379 	shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
380 
381 	for (uint8_t i = 0U; i < program_info_uri_len; i++) {
382 		shell_fprintf(sh, SHELL_NORMAL, "%c", (char)program_info_uri[i]);
383 	}
384 
385 	shell_fprintf(sh, SHELL_NORMAL, "\n");
386 }
387 
print_codec_meta_audio_active_state(const struct shell * sh,size_t indent,enum bt_audio_active_state state)388 static inline void print_codec_meta_audio_active_state(const struct shell *sh, size_t indent,
389 						       enum bt_audio_active_state state)
390 {
391 	shell_print(sh, "%*sAudio active state: %s (0x%02X)", indent, "",
392 		    bt_audio_active_state_to_str(state), (uint8_t)state);
393 }
394 
print_codec_meta_bcast_audio_immediate_rend_flag(const struct shell * sh,size_t indent)395 static inline void print_codec_meta_bcast_audio_immediate_rend_flag(const struct shell *sh,
396 								    size_t indent)
397 {
398 	shell_print(sh, "%*sBroadcast audio immediate rendering flag set", indent, "");
399 }
400 
print_codec_meta_extended(const struct shell * sh,size_t indent,const uint8_t * extended_meta,size_t extended_meta_len)401 static inline void print_codec_meta_extended(const struct shell *sh, size_t indent,
402 					     const uint8_t *extended_meta, size_t extended_meta_len)
403 {
404 	shell_print(sh, "%*sExtended metadata:", indent, "");
405 
406 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
407 
408 	shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
409 
410 	for (uint8_t i = 0U; i < extended_meta_len; i++) {
411 		shell_fprintf(sh, SHELL_NORMAL, "%u", (uint8_t)extended_meta[i]);
412 	}
413 
414 	shell_fprintf(sh, SHELL_NORMAL, "\n");
415 }
416 
print_codec_meta_vendor(const struct shell * sh,size_t indent,const uint8_t * vendor_meta,size_t vender_meta_len)417 static inline void print_codec_meta_vendor(const struct shell *sh, size_t indent,
418 					   const uint8_t *vendor_meta, size_t vender_meta_len)
419 {
420 	shell_print(sh, "%*sVendor metadata:", indent, "");
421 
422 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
423 
424 	shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
425 
426 	for (uint8_t i = 0U; i < vender_meta_len; i++) {
427 		shell_fprintf(sh, SHELL_NORMAL, "%u", (uint8_t)vendor_meta[i]);
428 	}
429 
430 	shell_fprintf(sh, SHELL_NORMAL, "\n");
431 }
432 
print_codec_cap_freq(const struct shell * sh,size_t indent,enum bt_audio_codec_cap_freq freq)433 static inline void print_codec_cap_freq(const struct shell *sh, size_t indent,
434 					enum bt_audio_codec_cap_freq freq)
435 {
436 	shell_print(sh, "%*sSupported sampling frequencies:", indent, "");
437 
438 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
439 	/* There can be up to 16 bits set in the field */
440 	for (size_t i = 0; i < 16; i++) {
441 		const uint16_t bit_val = BIT(i);
442 
443 		if (freq & bit_val) {
444 			shell_print(sh, "%*s%s (0x%04X)", indent, "",
445 				    bt_audio_codec_cap_freq_bit_to_str(bit_val), bit_val);
446 		}
447 	}
448 }
449 
print_codec_cap_frame_dur(const struct shell * sh,size_t indent,enum bt_audio_codec_cap_frame_dur frame_dur)450 static inline void print_codec_cap_frame_dur(const struct shell *sh, size_t indent,
451 					     enum bt_audio_codec_cap_frame_dur frame_dur)
452 {
453 	shell_print(sh, "%*sSupported frame durations:", indent, "");
454 
455 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
456 	/* There can be up to 8 bits set in the field */
457 	for (size_t i = 0; i < 8; i++) {
458 		const uint8_t bit_val = BIT(i);
459 
460 		if (frame_dur & bit_val) {
461 			shell_print(sh, "%*s%s (0x%02X)", indent, "",
462 				    bt_audio_codec_cap_frame_dur_bit_to_str(bit_val), bit_val);
463 		}
464 	}
465 }
466 
print_codec_cap_chan_count(const struct shell * sh,size_t indent,enum bt_audio_codec_cap_chan_count chan_count)467 static inline void print_codec_cap_chan_count(const struct shell *sh, size_t indent,
468 					      enum bt_audio_codec_cap_chan_count chan_count)
469 {
470 	shell_print(sh, "%*sSupported channel counts:", indent, "");
471 
472 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
473 	/* There can be up to 8 bits set in the field */
474 	for (size_t i = 0; i < 8; i++) {
475 		const uint8_t bit_val = BIT(i);
476 
477 		if (chan_count & bit_val) {
478 			shell_print(sh, "%*s%s (0x%02X)", indent, "",
479 				    bt_audio_codec_cap_chan_count_bit_to_str(bit_val), bit_val);
480 		}
481 	}
482 }
483 
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)484 static inline void print_codec_cap_octets_per_codec_frame(
485 	const struct shell *sh, size_t indent,
486 	const struct bt_audio_codec_octets_per_codec_frame *codec_frame)
487 {
488 	shell_print(sh, "%*sSupported octets per codec frame counts:", indent, "");
489 
490 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
491 	shell_print(sh, "%*sMin: %u", indent, "", codec_frame->min);
492 	shell_print(sh, "%*sMax: %u", indent, "", codec_frame->max);
493 }
494 
print_codec_cap_max_codec_frames_per_sdu(const struct shell * sh,size_t indent,uint8_t codec_frames_per_sdu)495 static inline void print_codec_cap_max_codec_frames_per_sdu(const struct shell *sh, size_t indent,
496 							    uint8_t codec_frames_per_sdu)
497 {
498 	shell_print(sh, "%*sSupported max codec frames per SDU: %u", indent, "",
499 		    codec_frames_per_sdu);
500 }
501 
print_codec_cap(const struct shell * sh,size_t indent,const struct bt_audio_codec_cap * codec_cap)502 static inline void print_codec_cap(const struct shell *sh, size_t indent,
503 				   const struct bt_audio_codec_cap *codec_cap)
504 {
505 	shell_print(sh, "%*scodec cap id 0x%02x cid 0x%04x vid 0x%04x", indent, "", codec_cap->id,
506 		    codec_cap->cid, codec_cap->vid);
507 
508 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
509 
510 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0
511 	shell_print(sh, "%*sCodec specific capabilities:", indent, "");
512 
513 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
514 	if (codec_cap->data_len == 0U) {
515 		shell_print(sh, "%*sNone", indent, "");
516 	} else if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) {
517 		struct bt_audio_codec_octets_per_codec_frame codec_frame;
518 		int ret;
519 
520 		ret = bt_audio_codec_cap_get_freq(codec_cap);
521 		if (ret >= 0) {
522 			print_codec_cap_freq(sh, indent, (enum bt_audio_codec_cap_freq)ret);
523 		}
524 
525 		ret = bt_audio_codec_cap_get_frame_dur(codec_cap);
526 		if (ret >= 0) {
527 			print_codec_cap_frame_dur(sh, indent,
528 						  (enum bt_audio_codec_cap_frame_dur)ret);
529 		}
530 
531 		ret = bt_audio_codec_cap_get_supported_audio_chan_counts(codec_cap, true);
532 		if (ret >= 0) {
533 			print_codec_cap_chan_count(sh, indent,
534 						   (enum bt_audio_codec_cap_chan_count)ret);
535 		}
536 
537 		ret = bt_audio_codec_cap_get_octets_per_frame(codec_cap, &codec_frame);
538 		if (ret >= 0) {
539 			print_codec_cap_octets_per_codec_frame(sh, indent, &codec_frame);
540 		}
541 
542 		ret = bt_audio_codec_cap_get_max_codec_frames_per_sdu(codec_cap, true);
543 		if (ret >= 0) {
544 			print_codec_cap_max_codec_frames_per_sdu(sh, indent, (uint8_t)ret);
545 		}
546 	} else { /* If not LC3, we cannot assume it's LTV */
547 		shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
548 
549 		for (uint8_t i = 0U; i < codec_cap->data_len; i++) {
550 			shell_fprintf(sh, SHELL_NORMAL, "%*s%02X", indent, "", codec_cap->data[i]);
551 		}
552 
553 		shell_fprintf(sh, SHELL_NORMAL, "\n");
554 	}
555 
556 	/* Reduce for metadata*/
557 	indent -= SHELL_PRINT_INDENT_LEVEL_SIZE;
558 #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */
559 
560 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0
561 	shell_print(sh, "%*sCodec capabilities metadata:", indent, "");
562 
563 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
564 	if (codec_cap->meta_len == 0U) {
565 		shell_print(sh, "%*sNone", indent, "");
566 	} else {
567 		const uint8_t *data;
568 		int ret;
569 
570 		ret = bt_audio_codec_cap_meta_get_pref_context(codec_cap);
571 		if (ret >= 0) {
572 			print_codec_meta_pref_context(sh, indent, (enum bt_audio_context)ret);
573 		}
574 
575 		ret = bt_audio_codec_cap_meta_get_stream_context(codec_cap);
576 		if (ret >= 0) {
577 			print_codec_meta_stream_context(sh, indent, (enum bt_audio_context)ret);
578 		}
579 
580 		ret = bt_audio_codec_cap_meta_get_program_info(codec_cap, &data);
581 		if (ret >= 0) {
582 			print_codec_meta_program_info(sh, indent, data, (uint8_t)ret);
583 		}
584 
585 		ret = bt_audio_codec_cap_meta_get_lang(codec_cap, &data);
586 		if (ret >= 0) {
587 			print_codec_meta_language(sh, indent, data);
588 		}
589 
590 		ret = bt_audio_codec_cap_meta_get_ccid_list(codec_cap, &data);
591 		if (ret >= 0) {
592 			print_codec_meta_ccid_list(sh, indent, data, (uint8_t)ret);
593 		}
594 
595 		ret = bt_audio_codec_cap_meta_get_parental_rating(codec_cap);
596 		if (ret >= 0) {
597 			print_codec_meta_parental_rating(sh, indent,
598 							 (enum bt_audio_parental_rating)ret);
599 		}
600 
601 		ret = bt_audio_codec_cap_meta_get_audio_active_state(codec_cap);
602 		if (ret >= 0) {
603 			print_codec_meta_audio_active_state(sh, indent,
604 							    (enum bt_audio_active_state)ret);
605 		}
606 
607 		ret = bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(codec_cap);
608 		if (ret >= 0) {
609 			print_codec_meta_bcast_audio_immediate_rend_flag(sh, indent);
610 		}
611 
612 		ret = bt_audio_codec_cap_meta_get_extended(codec_cap, &data);
613 		if (ret >= 0) {
614 			print_codec_meta_extended(sh, indent, data, (uint8_t)ret);
615 		}
616 
617 		ret = bt_audio_codec_cap_meta_get_vendor(codec_cap, &data);
618 		if (ret >= 0) {
619 			print_codec_meta_vendor(sh, indent, data, (uint8_t)ret);
620 		}
621 	}
622 #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */
623 }
624 
print_codec_cfg_freq(const struct shell * sh,size_t indent,enum bt_audio_codec_cfg_freq freq)625 static inline void print_codec_cfg_freq(const struct shell *sh, size_t indent,
626 					enum bt_audio_codec_cfg_freq freq)
627 {
628 	shell_print(sh, "%*sSampling frequency: %u Hz (0x%04X)", indent, "",
629 		    bt_audio_codec_cfg_freq_to_freq_hz(freq), (uint16_t)freq);
630 }
631 
print_codec_cfg_frame_dur(const struct shell * sh,size_t indent,enum bt_audio_codec_cfg_frame_dur frame_dur)632 static inline void print_codec_cfg_frame_dur(const struct shell *sh, size_t indent,
633 					     enum bt_audio_codec_cfg_frame_dur frame_dur)
634 {
635 	shell_print(sh, "%*sFrame duration: %u us (0x%02X)", indent, "",
636 		    bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur), (uint8_t)frame_dur);
637 }
638 
print_codec_cfg_chan_allocation(const struct shell * sh,size_t indent,enum bt_audio_location chan_allocation)639 static inline void print_codec_cfg_chan_allocation(const struct shell *sh, size_t indent,
640 						   enum bt_audio_location chan_allocation)
641 {
642 	shell_print(sh, "%*sChannel allocation:", indent, "");
643 
644 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
645 
646 	if (chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO) {
647 		shell_print(sh, "%*s Mono", indent, "");
648 	} else {
649 		/* There can be up to 32 bits set in the field */
650 		for (size_t i = 0; i < 32; i++) {
651 			const uint8_t bit_val = BIT(i);
652 
653 			if (chan_allocation & bit_val) {
654 				shell_print(sh, "%*s%s (0x%08X)", indent, "",
655 					    bt_audio_location_bit_to_str(bit_val), bit_val);
656 			}
657 		}
658 	}
659 }
660 
print_codec_cfg_octets_per_frame(const struct shell * sh,size_t indent,uint16_t octets_per_frame)661 static inline void print_codec_cfg_octets_per_frame(const struct shell *sh, size_t indent,
662 						    uint16_t octets_per_frame)
663 {
664 	shell_print(sh, "%*sOctets per codec frame: %u", indent, "", octets_per_frame);
665 }
666 
print_codec_cfg_frame_blocks_per_sdu(const struct shell * sh,size_t indent,uint8_t frame_blocks_per_sdu)667 static inline void print_codec_cfg_frame_blocks_per_sdu(const struct shell *sh, size_t indent,
668 							uint8_t frame_blocks_per_sdu)
669 {
670 	shell_print(sh, "%*sCodec frame blocks per SDU: %u", indent, "", frame_blocks_per_sdu);
671 }
672 
print_codec_cfg(const struct shell * sh,size_t indent,const struct bt_audio_codec_cfg * codec_cfg)673 static inline void print_codec_cfg(const struct shell *sh, size_t indent,
674 				   const struct bt_audio_codec_cfg *codec_cfg)
675 {
676 	shell_print(sh, "%*scodec cfg id 0x%02x cid 0x%04x vid 0x%04x count %u", indent, "",
677 		    codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len);
678 
679 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
680 
681 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
682 	shell_print(sh, "%*sCodec specific configuration:", indent, "");
683 
684 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
685 	if (codec_cfg->data_len == 0U) {
686 		shell_print(sh, "%*sNone", indent, "");
687 	} else if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
688 		enum bt_audio_location chan_allocation;
689 		int ret;
690 
691 		ret = bt_audio_codec_cfg_get_freq(codec_cfg);
692 		if (ret >= 0) {
693 			print_codec_cfg_freq(sh, indent, (enum bt_audio_codec_cfg_freq)ret);
694 		}
695 
696 		ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
697 		if (ret >= 0) {
698 			print_codec_cfg_frame_dur(sh, indent,
699 						  (enum bt_audio_codec_cfg_frame_dur)ret);
700 		}
701 
702 		ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation, false);
703 		if (ret == 0) {
704 			print_codec_cfg_chan_allocation(sh, indent, chan_allocation);
705 		}
706 
707 		ret = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg);
708 		if (ret >= 0) {
709 			print_codec_cfg_octets_per_frame(sh, indent, (uint16_t)ret);
710 		}
711 
712 		ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, false);
713 		if (ret >= 0) {
714 			print_codec_cfg_frame_blocks_per_sdu(sh, indent, (uint8_t)ret);
715 		}
716 	} else { /* If not LC3, we cannot assume it's LTV */
717 		shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, "");
718 
719 		for (uint8_t i = 0U; i < codec_cfg->data_len; i++) {
720 			shell_fprintf(sh, SHELL_NORMAL, "%*s%02X", indent, "", codec_cfg->data[i]);
721 		}
722 
723 		shell_fprintf(sh, SHELL_NORMAL, "\n");
724 	}
725 
726 	/* Reduce for metadata*/
727 	indent -= SHELL_PRINT_INDENT_LEVEL_SIZE;
728 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
729 
730 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
731 	shell_print(sh, "%*sCodec specific metadata:", indent, "");
732 
733 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
734 	if (codec_cfg->meta_len == 0U) {
735 		shell_print(sh, "%*sNone", indent, "");
736 	} else {
737 		const uint8_t *data;
738 		int ret;
739 
740 		ret = bt_audio_codec_cfg_meta_get_pref_context(codec_cfg, true);
741 		if (ret >= 0) {
742 			print_codec_meta_pref_context(sh, indent, (enum bt_audio_context)ret);
743 		}
744 
745 		ret = bt_audio_codec_cfg_meta_get_stream_context(codec_cfg);
746 		if (ret >= 0) {
747 			print_codec_meta_stream_context(sh, indent, (enum bt_audio_context)ret);
748 		}
749 
750 		ret = bt_audio_codec_cfg_meta_get_program_info(codec_cfg, &data);
751 		if (ret >= 0) {
752 			print_codec_meta_program_info(sh, indent, data, (uint8_t)ret);
753 		}
754 
755 		ret = bt_audio_codec_cfg_meta_get_lang(codec_cfg, &data);
756 		if (ret >= 0) {
757 			print_codec_meta_language(sh, indent, data);
758 		}
759 
760 		ret = bt_audio_codec_cfg_meta_get_ccid_list(codec_cfg, &data);
761 		if (ret >= 0) {
762 			print_codec_meta_ccid_list(sh, indent, data, (uint8_t)ret);
763 		}
764 
765 		ret = bt_audio_codec_cfg_meta_get_parental_rating(codec_cfg);
766 		if (ret >= 0) {
767 			print_codec_meta_parental_rating(sh, indent,
768 							 (enum bt_audio_parental_rating)ret);
769 		}
770 
771 		ret = bt_audio_codec_cfg_meta_get_audio_active_state(codec_cfg);
772 		if (ret >= 0) {
773 			print_codec_meta_audio_active_state(sh, indent,
774 							    (enum bt_audio_active_state)ret);
775 		}
776 
777 		ret = bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(codec_cfg);
778 		if (ret >= 0) {
779 			print_codec_meta_bcast_audio_immediate_rend_flag(sh, indent);
780 		}
781 
782 		ret = bt_audio_codec_cfg_meta_get_extended(codec_cfg, &data);
783 		if (ret >= 0) {
784 			print_codec_meta_extended(sh, indent, data, (uint8_t)ret);
785 		}
786 
787 		ret = bt_audio_codec_cfg_meta_get_vendor(codec_cfg, &data);
788 		if (ret >= 0) {
789 			print_codec_meta_vendor(sh, indent, data, (uint8_t)ret);
790 		}
791 	}
792 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
793 }
794 
795 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
796 struct bap_broadcast_ac_param {
797 	char *name;
798 	size_t stream_cnt;
799 	size_t chan_cnt;
800 };
801 
802 int cap_ac_broadcast(const struct shell *sh, size_t argc, char **argv,
803 		     const struct bap_broadcast_ac_param *param);
804 
805 extern struct shell_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
806 extern struct broadcast_source default_source;
807 extern struct named_lc3_preset default_broadcast_source_preset;
808 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
809 
print_base_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis * bis,void * user_data)810 static inline bool print_base_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis *bis,
811 					      void *user_data)
812 {
813 	size_t indent = 2 * SHELL_PRINT_INDENT_LEVEL_SIZE;
814 	struct bt_bap_base_codec_id *codec_id = user_data;
815 
816 	shell_print(ctx_shell, "%*sBIS index: 0x%02X", indent, "", bis->index);
817 
818 	indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
819 
820 	/* Print CC data */
821 	if (codec_id->id == BT_HCI_CODING_FORMAT_LC3) {
822 		struct bt_audio_codec_cfg codec_cfg = {
823 			.id = codec_id->id,
824 			.cid = codec_id->cid,
825 			.vid = codec_id->vid,
826 		};
827 		int err;
828 
829 		err = bt_bap_base_subgroup_bis_codec_to_codec_cfg(bis, &codec_cfg);
830 		if (err == 0) {
831 			print_codec_cfg(ctx_shell, indent, &codec_cfg);
832 		} else {
833 			shell_print(ctx_shell, "%*sCodec specific configuration:", indent, "");
834 			print_ltv_array(ctx_shell, indent, bis->data, bis->data_len);
835 		}
836 	} else { /* If not LC3, we cannot assume it's LTV */
837 		shell_print(ctx_shell, "%*sCodec specific configuration:", indent, "");
838 
839 		indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
840 		shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, "");
841 
842 		for (uint8_t i = 0U; i < bis->data_len; i++) {
843 			shell_fprintf(ctx_shell, SHELL_NORMAL, "%02X", bis->data[i]);
844 		}
845 
846 		shell_fprintf(ctx_shell, SHELL_NORMAL, "\n");
847 	}
848 
849 	return true;
850 }
851 
print_base_subgroup_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)852 static inline bool print_base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup,
853 					  void *user_data)
854 {
855 	size_t indent = 1 * SHELL_PRINT_INDENT_LEVEL_SIZE;
856 	struct bt_bap_base_codec_id codec_id;
857 	struct bt_audio_codec_cfg codec_cfg;
858 	uint8_t *data;
859 	int ret;
860 
861 	shell_print(ctx_shell, "Subgroup %p:", subgroup);
862 
863 	ret = bt_bap_base_get_subgroup_codec_id(subgroup, &codec_id);
864 	if (ret < 0) {
865 		return false;
866 	}
867 
868 	shell_print(ctx_shell, "%*sCodec Format: 0x%02X", indent, "", codec_id.id);
869 	shell_print(ctx_shell, "%*sCompany ID  : 0x%04X", indent, "", codec_id.cid);
870 	shell_print(ctx_shell, "%*sVendor ID   : 0x%04X", indent, "", codec_id.vid);
871 
872 	ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &codec_cfg);
873 	if (ret == 0) {
874 		print_codec_cfg(ctx_shell, indent, &codec_cfg);
875 	} else {
876 		/* If we cannot store it in a codec_cfg, then we cannot easily print it as such */
877 		ret = bt_bap_base_get_subgroup_codec_data(subgroup, &data);
878 		if (ret < 0) {
879 			return false;
880 		}
881 
882 		shell_print(ctx_shell, "%*sCodec specific configuration:", indent, "");
883 		indent += SHELL_PRINT_INDENT_LEVEL_SIZE;
884 
885 		/* Print CC data */
886 		if (codec_id.id == BT_HCI_CODING_FORMAT_LC3) {
887 			print_ltv_array(ctx_shell, indent, data, (uint8_t)ret);
888 		} else { /* If not LC3, we cannot assume it's LTV */
889 			shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, "");
890 
891 			for (uint8_t i = 0U; i < (uint8_t)ret; i++) {
892 				shell_fprintf(ctx_shell, SHELL_NORMAL, "%c", data[i]);
893 			}
894 
895 			shell_fprintf(ctx_shell, SHELL_NORMAL, "\n");
896 		}
897 
898 		ret = bt_bap_base_get_subgroup_codec_meta(subgroup, &data);
899 		if (ret < 0) {
900 			return false;
901 		}
902 
903 		shell_print(ctx_shell,
904 			    "%*sCodec specific metadata:", indent - SHELL_PRINT_INDENT_LEVEL_SIZE,
905 			    "");
906 
907 		/* Print metadata */
908 		if (codec_id.id == BT_HCI_CODING_FORMAT_LC3) {
909 			print_ltv_array(ctx_shell, indent, data, (uint8_t)ret);
910 		} else { /* If not LC3, we cannot assume it's LTV */
911 			shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, "");
912 
913 			for (uint8_t i = 0U; i < (uint8_t)ret; i++) {
914 				shell_fprintf(ctx_shell, SHELL_NORMAL, "%c", data[i]);
915 			}
916 
917 			shell_fprintf(ctx_shell, SHELL_NORMAL, "\n");
918 		}
919 	}
920 
921 	ret = bt_bap_base_subgroup_foreach_bis(subgroup, print_base_subgroup_bis_cb, &codec_id);
922 	if (ret < 0) {
923 		return false;
924 	}
925 
926 	return true;
927 }
928 
print_base(const struct bt_bap_base * base)929 static inline void print_base(const struct bt_bap_base *base)
930 {
931 	int err;
932 
933 	shell_print(ctx_shell, "Presentation delay: %d", bt_bap_base_get_pres_delay(base));
934 	shell_print(ctx_shell, "Subgroup count: %d", bt_bap_base_get_subgroup_count(base));
935 
936 	err = bt_bap_base_foreach_subgroup(base, print_base_subgroup_cb, NULL);
937 	if (err < 0) {
938 		shell_info(ctx_shell, "Invalid BASE: %d", err);
939 	}
940 }
941 
copy_unicast_stream_preset(struct shell_stream * stream,const struct named_lc3_preset * named_preset)942 static inline void copy_unicast_stream_preset(struct shell_stream *stream,
943 					      const struct named_lc3_preset *named_preset)
944 {
945 	memcpy(&stream->qos, &named_preset->preset.qos, sizeof(stream->qos));
946 	memcpy(&stream->codec_cfg, &named_preset->preset.codec_cfg, sizeof(stream->codec_cfg));
947 }
948 
copy_broadcast_source_preset(struct broadcast_source * source,const struct named_lc3_preset * named_preset)949 static inline void copy_broadcast_source_preset(struct broadcast_source *source,
950 						const struct named_lc3_preset *named_preset)
951 {
952 	memcpy(&source->qos, &named_preset->preset.qos, sizeof(source->qos));
953 	memcpy(&source->codec_cfg, &named_preset->preset.codec_cfg, sizeof(source->codec_cfg));
954 }
955 #endif /* CONFIG_BT_AUDIO */
956 
957 #endif /* AUDIO_SHELL_AUDIO_H */
958