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, <v_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