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