1 /** @file
2  *  @brief Bluetooth Basic Audio Profile shell
3  *
4  */
5 
6 /*
7  * Copyright (c) 2020 Intel Corporation
8  * Copyright (c) 2022-2023 Nordic Semiconductor ASA
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #include <errno.h>
14 #include <stdbool.h>
15 #include <stddef.h>
16 #include <stdint.h>
17 #include <string.h>
18 #include <sys/types.h>
19 
20 #include <zephyr/autoconf.h>
21 #include <zephyr/bluetooth/audio/audio.h>
22 #include <zephyr/bluetooth/audio/bap.h>
23 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
24 #include <zephyr/bluetooth/audio/cap.h>
25 #include <zephyr/bluetooth/audio/gmap.h>
26 #include <zephyr/bluetooth/audio/lc3.h>
27 #include <zephyr/bluetooth/audio/pacs.h>
28 #include <zephyr/bluetooth/addr.h>
29 #include <zephyr/bluetooth/bluetooth.h>
30 #include <zephyr/bluetooth/conn.h>
31 #include <zephyr/bluetooth/crypto.h>
32 #include <zephyr/bluetooth/gap.h>
33 #include <zephyr/bluetooth/gatt.h>
34 #include <zephyr/bluetooth/hci_types.h>
35 #include <zephyr/bluetooth/iso.h>
36 #include <zephyr/bluetooth/uuid.h>
37 #include <zephyr/kernel.h>
38 #include <zephyr/kernel/thread_stack.h>
39 #include <zephyr/net_buf.h>
40 #include <zephyr/shell/shell.h>
41 #include <zephyr/shell/shell_string_conv.h>
42 #include <zephyr/sys/__assert.h>
43 #include <zephyr/sys/atomic.h>
44 #include <zephyr/sys/printk.h>
45 #include <zephyr/sys/byteorder.h>
46 #include <zephyr/sys/time_units.h>
47 #include <zephyr/sys/util.h>
48 #include <zephyr/sys/util_macro.h>
49 #include <zephyr/sys_clock.h>
50 
51 #include "common/bt_shell_private.h"
52 #include "host/shell/bt.h"
53 #include "audio.h"
54 
55 /* Determines if we can initiate streaming */
56 #define IS_BAP_INITIATOR                                                                           \
57 	(IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SOURCE) || IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT))
58 
59 #define GENERATE_SINE_SUPPORTED (IS_ENABLED(CONFIG_LIBLC3) && !IS_ENABLED(CONFIG_USB_DEVICE_AUDIO))
60 
61 #if defined(CONFIG_BT_BAP_UNICAST)
62 
63 struct shell_stream unicast_streams[CONFIG_BT_MAX_CONN *
64 				    MAX(UNICAST_SERVER_STREAM_COUNT, UNICAST_CLIENT_STREAM_COUNT)];
65 
66 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
67 struct bt_bap_unicast_group *default_unicast_group;
68 static struct bt_bap_unicast_client_cb unicast_client_cbs;
69 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
70 struct bt_bap_ep *snks[CONFIG_BT_MAX_CONN][CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT];
71 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
72 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
73 struct bt_bap_ep *srcs[CONFIG_BT_MAX_CONN][CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT];
74 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
75 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
76 #endif /* CONFIG_BT_BAP_UNICAST */
77 
78 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
79 struct shell_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
80 struct broadcast_source default_source;
81 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
82 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
83 static struct shell_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
84 static struct broadcast_sink default_broadcast_sink;
85 #endif /* CONFIG_BT_BAP_BROADCAST_SINK */
86 
87 #if defined(CONFIG_BT_BAP_UNICAST) || defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
88 static struct bt_bap_stream *default_stream;
89 #endif /* CONFIG_BT_BAP_UNICAST || CONFIG_BT_BAP_BROADCAST_SOURCE */
90 
91 #if IS_BAP_INITIATOR
92 /* Default to 16_2_1 */
93 struct named_lc3_preset default_sink_preset = {"16_2_1",
94 					       BT_BAP_LC3_UNICAST_PRESET_16_2_1(LOCATION, CONTEXT)};
95 struct named_lc3_preset default_source_preset = {
96 	"16_2_1", BT_BAP_LC3_UNICAST_PRESET_16_2_1(LOCATION, CONTEXT)};
97 struct named_lc3_preset default_broadcast_source_preset = {
98 	"16_2_1", BT_BAP_LC3_BROADCAST_PRESET_16_2_1(LOCATION, CONTEXT)};
99 #endif /* IS_BAP_INITIATOR */
100 
101 static const struct named_lc3_preset lc3_unicast_presets[] = {
102 	{"8_1_1", BT_BAP_LC3_UNICAST_PRESET_8_1_1(LOCATION, CONTEXT)},
103 	{"8_2_1", BT_BAP_LC3_UNICAST_PRESET_8_2_1(LOCATION, CONTEXT)},
104 	{"16_1_1", BT_BAP_LC3_UNICAST_PRESET_16_1_1(LOCATION, CONTEXT)},
105 	{"16_2_1", BT_BAP_LC3_UNICAST_PRESET_16_2_1(LOCATION, CONTEXT)},
106 	{"24_1_1", BT_BAP_LC3_UNICAST_PRESET_24_1_1(LOCATION, CONTEXT)},
107 	{"24_2_1", BT_BAP_LC3_UNICAST_PRESET_24_2_1(LOCATION, CONTEXT)},
108 	{"32_1_1", BT_BAP_LC3_UNICAST_PRESET_32_1_1(LOCATION, CONTEXT)},
109 	{"32_2_1", BT_BAP_LC3_UNICAST_PRESET_32_2_1(LOCATION, CONTEXT)},
110 	{"441_1_1", BT_BAP_LC3_UNICAST_PRESET_441_1_1(LOCATION, CONTEXT)},
111 	{"441_2_1", BT_BAP_LC3_UNICAST_PRESET_441_2_1(LOCATION, CONTEXT)},
112 	{"48_1_1", BT_BAP_LC3_UNICAST_PRESET_48_1_1(LOCATION, CONTEXT)},
113 	{"48_2_1", BT_BAP_LC3_UNICAST_PRESET_48_2_1(LOCATION, CONTEXT)},
114 	{"48_3_1", BT_BAP_LC3_UNICAST_PRESET_48_3_1(LOCATION, CONTEXT)},
115 	{"48_4_1", BT_BAP_LC3_UNICAST_PRESET_48_4_1(LOCATION, CONTEXT)},
116 	{"48_5_1", BT_BAP_LC3_UNICAST_PRESET_48_5_1(LOCATION, CONTEXT)},
117 	{"48_6_1", BT_BAP_LC3_UNICAST_PRESET_48_6_1(LOCATION, CONTEXT)},
118 	/* High-reliability presets */
119 	{"8_1_2", BT_BAP_LC3_UNICAST_PRESET_8_1_2(LOCATION, CONTEXT)},
120 	{"8_2_2", BT_BAP_LC3_UNICAST_PRESET_8_2_2(LOCATION, CONTEXT)},
121 	{"16_1_2", BT_BAP_LC3_UNICAST_PRESET_16_1_2(LOCATION, CONTEXT)},
122 	{"16_2_2", BT_BAP_LC3_UNICAST_PRESET_16_2_2(LOCATION, CONTEXT)},
123 	{"24_1_2", BT_BAP_LC3_UNICAST_PRESET_24_1_2(LOCATION, CONTEXT)},
124 	{"24_2_2", BT_BAP_LC3_UNICAST_PRESET_24_2_2(LOCATION, CONTEXT)},
125 	{"32_1_2", BT_BAP_LC3_UNICAST_PRESET_32_1_2(LOCATION, CONTEXT)},
126 	{"32_2_2", BT_BAP_LC3_UNICAST_PRESET_32_2_2(LOCATION, CONTEXT)},
127 	{"441_1_2", BT_BAP_LC3_UNICAST_PRESET_441_1_2(LOCATION, CONTEXT)},
128 	{"441_2_2", BT_BAP_LC3_UNICAST_PRESET_441_2_2(LOCATION, CONTEXT)},
129 	{"48_1_2", BT_BAP_LC3_UNICAST_PRESET_48_1_2(LOCATION, CONTEXT)},
130 	{"48_2_2", BT_BAP_LC3_UNICAST_PRESET_48_2_2(LOCATION, CONTEXT)},
131 	{"48_3_2", BT_BAP_LC3_UNICAST_PRESET_48_3_2(LOCATION, CONTEXT)},
132 	{"48_4_2", BT_BAP_LC3_UNICAST_PRESET_48_4_2(LOCATION, CONTEXT)},
133 	{"48_5_2", BT_BAP_LC3_UNICAST_PRESET_48_5_2(LOCATION, CONTEXT)},
134 	{"48_6_2", BT_BAP_LC3_UNICAST_PRESET_48_6_2(LOCATION, CONTEXT)},
135 };
136 
137 static const struct named_lc3_preset lc3_broadcast_presets[] = {
138 	{"8_1_1", BT_BAP_LC3_BROADCAST_PRESET_8_1_1(LOCATION, CONTEXT)},
139 	{"8_2_1", BT_BAP_LC3_BROADCAST_PRESET_8_2_1(LOCATION, CONTEXT)},
140 	{"16_1_1", BT_BAP_LC3_BROADCAST_PRESET_16_1_1(LOCATION, CONTEXT)},
141 	{"16_2_1", BT_BAP_LC3_BROADCAST_PRESET_16_2_1(LOCATION, CONTEXT)},
142 	{"24_1_1", BT_BAP_LC3_BROADCAST_PRESET_24_1_1(LOCATION, CONTEXT)},
143 	{"24_2_1", BT_BAP_LC3_BROADCAST_PRESET_24_2_1(LOCATION, CONTEXT)},
144 	{"32_1_1", BT_BAP_LC3_BROADCAST_PRESET_32_1_1(LOCATION, CONTEXT)},
145 	{"32_2_1", BT_BAP_LC3_BROADCAST_PRESET_32_2_1(LOCATION, CONTEXT)},
146 	{"441_1_1", BT_BAP_LC3_BROADCAST_PRESET_441_1_1(LOCATION, CONTEXT)},
147 	{"441_2_1", BT_BAP_LC3_BROADCAST_PRESET_441_2_1(LOCATION, CONTEXT)},
148 	{"48_1_1", BT_BAP_LC3_BROADCAST_PRESET_48_1_1(LOCATION, CONTEXT)},
149 	{"48_2_1", BT_BAP_LC3_BROADCAST_PRESET_48_2_1(LOCATION, CONTEXT)},
150 	{"48_3_1", BT_BAP_LC3_BROADCAST_PRESET_48_3_1(LOCATION, CONTEXT)},
151 	{"48_4_1", BT_BAP_LC3_BROADCAST_PRESET_48_4_1(LOCATION, CONTEXT)},
152 	{"48_5_1", BT_BAP_LC3_BROADCAST_PRESET_48_5_1(LOCATION, CONTEXT)},
153 	{"48_6_1", BT_BAP_LC3_BROADCAST_PRESET_48_6_1(LOCATION, CONTEXT)},
154 	/* High-reliability presets */
155 	{"8_1_2", BT_BAP_LC3_BROADCAST_PRESET_8_1_2(LOCATION, CONTEXT)},
156 	{"8_2_2", BT_BAP_LC3_BROADCAST_PRESET_8_2_2(LOCATION, CONTEXT)},
157 	{"16_1_2", BT_BAP_LC3_BROADCAST_PRESET_16_1_2(LOCATION, CONTEXT)},
158 	{"16_2_2", BT_BAP_LC3_BROADCAST_PRESET_16_2_2(LOCATION, CONTEXT)},
159 	{"24_1_2", BT_BAP_LC3_BROADCAST_PRESET_24_1_2(LOCATION, CONTEXT)},
160 	{"24_2_2", BT_BAP_LC3_BROADCAST_PRESET_24_2_2(LOCATION, CONTEXT)},
161 	{"32_1_2", BT_BAP_LC3_BROADCAST_PRESET_32_1_2(LOCATION, CONTEXT)},
162 	{"32_2_2", BT_BAP_LC3_BROADCAST_PRESET_32_2_2(LOCATION, CONTEXT)},
163 	{"441_1_2", BT_BAP_LC3_BROADCAST_PRESET_441_1_2(LOCATION, CONTEXT)},
164 	{"441_2_2", BT_BAP_LC3_BROADCAST_PRESET_441_2_2(LOCATION, CONTEXT)},
165 	{"48_1_2", BT_BAP_LC3_BROADCAST_PRESET_48_1_2(LOCATION, CONTEXT)},
166 	{"48_2_2", BT_BAP_LC3_BROADCAST_PRESET_48_2_2(LOCATION, CONTEXT)},
167 	{"48_3_2", BT_BAP_LC3_BROADCAST_PRESET_48_3_2(LOCATION, CONTEXT)},
168 	{"48_4_2", BT_BAP_LC3_BROADCAST_PRESET_48_4_2(LOCATION, CONTEXT)},
169 	{"48_5_2", BT_BAP_LC3_BROADCAST_PRESET_48_5_2(LOCATION, CONTEXT)},
170 	{"48_6_2", BT_BAP_LC3_BROADCAST_PRESET_48_6_2(LOCATION, CONTEXT)},
171 };
172 
173 static bool initialized;
174 static unsigned long bap_stats_interval = 1000U;
175 
shell_stream_from_bap_stream(struct bt_bap_stream * bap_stream)176 struct shell_stream *shell_stream_from_bap_stream(struct bt_bap_stream *bap_stream)
177 {
178 	struct bt_cap_stream *cap_stream =
179 		CONTAINER_OF(bap_stream, struct bt_cap_stream, bap_stream);
180 	struct shell_stream *sh_stream = CONTAINER_OF(cap_stream, struct shell_stream, stream);
181 
182 	return sh_stream;
183 }
184 
bap_stream_from_shell_stream(struct shell_stream * sh_stream)185 struct bt_bap_stream *bap_stream_from_shell_stream(struct shell_stream *sh_stream)
186 {
187 	return &sh_stream->stream.bap_stream;
188 }
189 
bap_get_stats_interval(void)190 unsigned long bap_get_stats_interval(void)
191 {
192 	return bap_stats_interval;
193 }
194 
bap_foreach_stream(void (* func)(struct shell_stream * sh_stream,void * data),void * data)195 void bap_foreach_stream(void (*func)(struct shell_stream *sh_stream, void *data), void *data)
196 {
197 #if defined(CONFIG_BT_BAP_UNICAST)
198 	for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
199 		func(&unicast_streams[i], data);
200 	}
201 #endif /* CONFIG_BT_BAP_UNICAST */
202 
203 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
204 	for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) {
205 		func(&broadcast_source_streams[i], data);
206 	}
207 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
208 
209 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
210 	for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sink_streams); i++) {
211 		func(&broadcast_sink_streams[i], data);
212 	}
213 #endif /* CONFIG_BT_BAP_BROADCAST_SINK */
214 }
215 
216 #if defined(CONFIG_LIBLC3)
217 #include <lc3.h>
218 
get_lc3_chan_alloc_from_index(const struct shell_stream * sh_stream,uint8_t index,enum bt_audio_location * chan_alloc)219 static int get_lc3_chan_alloc_from_index(const struct shell_stream *sh_stream, uint8_t index,
220 					 enum bt_audio_location *chan_alloc)
221 {
222 	const bool has_left = (sh_stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0;
223 	const bool has_right =
224 		(sh_stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0;
225 	const bool is_mono = sh_stream->lc3_chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO;
226 	const bool is_left = index == 0 && has_left;
227 	const bool is_right = has_right && (index == 0U || (index == 1U && has_left));
228 
229 	/* LC3 is always Left before Right, so we can use the index and the stream channel
230 	 * allocation to determine if index 0 is left or right.
231 	 */
232 	if (is_left) {
233 		*chan_alloc = BT_AUDIO_LOCATION_FRONT_LEFT;
234 	} else if (is_right) {
235 		*chan_alloc = BT_AUDIO_LOCATION_FRONT_RIGHT;
236 	} else if (is_mono) {
237 		*chan_alloc = BT_AUDIO_LOCATION_MONO_AUDIO;
238 	} else {
239 		/* Not suitable for USB */
240 		return -EINVAL;
241 	}
242 
243 	return 0;
244 }
245 #endif /* CONFIG_LIBLC3 */
246 
247 #if defined(CONFIG_BT_AUDIO_TX)
248 static size_t tx_streaming_cnt;
249 
bap_get_tx_streaming_cnt(void)250 size_t bap_get_tx_streaming_cnt(void)
251 {
252 	return tx_streaming_cnt;
253 }
254 
get_next_seq_num(struct bt_bap_stream * bap_stream)255 uint16_t get_next_seq_num(struct bt_bap_stream *bap_stream)
256 {
257 	struct shell_stream *sh_stream = shell_stream_from_bap_stream(bap_stream);
258 	const uint32_t interval_us = bap_stream->qos->interval;
259 	int64_t uptime_ticks;
260 	int64_t delta_ticks;
261 	uint64_t delta_us;
262 	uint16_t seq_num;
263 
264 	if (!sh_stream->is_tx) {
265 		return 0;
266 	}
267 
268 	/* Note: This does not handle wrapping of ticks when they go above 2^(62-1) */
269 	uptime_ticks = k_uptime_ticks();
270 	delta_ticks = uptime_ticks - sh_stream->tx.connected_at_ticks;
271 
272 	delta_us = k_ticks_to_us_near64((uint64_t)delta_ticks);
273 	/* Calculate the sequence number by dividing the stream uptime by the SDU interval */
274 	seq_num = (uint16_t)(delta_us / interval_us);
275 
276 	return seq_num;
277 }
278 #endif /* CONFIG_BT_AUDIO_TX */
279 
280 #if defined(CONFIG_LIBLC3) && defined(CONFIG_BT_AUDIO_TX)
281 /* For the first call-back we push multiple audio frames to the buffer to use the
282  * controller ISO buffer to handle jitter.
283  */
284 #define PRIME_COUNT 2U
285 #define SINE_TX_POOL_SIZE (BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU))
286 NET_BUF_POOL_FIXED_DEFINE(sine_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, SINE_TX_POOL_SIZE,
287 			  CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
288 
289 #include "math.h"
290 
291 #define AUDIO_VOLUME            (INT16_MAX - 3000) /* codec does clipping above INT16_MAX - 3000 */
292 #define AUDIO_TONE_FREQUENCY_HZ   400
293 
294 static int16_t lc3_tx_buf[LC3_MAX_NUM_SAMPLES_MONO];
295 
init_lc3_encoder(struct shell_stream * sh_stream)296 static int init_lc3_encoder(struct shell_stream *sh_stream)
297 {
298 	if (sh_stream == NULL) {
299 		bt_shell_error("NULL stream to init LC3");
300 		return -EINVAL;
301 	}
302 
303 	if (!sh_stream->is_tx) {
304 		bt_shell_error("Invalid stream to init LC3 encoder");
305 		return -EINVAL;
306 	}
307 
308 	if (sh_stream->tx.lc3_encoder != NULL) {
309 		bt_shell_error("Already initialized");
310 		return -EALREADY;
311 	}
312 
313 	if (sh_stream->lc3_freq_hz == 0 || sh_stream->lc3_frame_duration_us == 0) {
314 		bt_shell_error("Invalid freq (%u) or frame duration (%u)",
315 			       sh_stream->lc3_freq_hz, sh_stream->lc3_frame_duration_us);
316 
317 		return -EINVAL;
318 	}
319 
320 	if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
321 		const size_t frame_size = bap_usb_get_frame_size(sh_stream);
322 
323 		if (frame_size > sizeof(lc3_tx_buf)) {
324 			bt_shell_error("Cannot put %u octets in lc3_tx_buf of size %zu",
325 				       frame_size, sizeof(lc3_tx_buf));
326 
327 			return -EINVAL;
328 		}
329 	}
330 
331 	bt_shell_print(
332 		"Initializing LC3 encoder for BAP stream %p with %u us duration and %u Hz "
333 		"frequency",
334 		bap_stream_from_shell_stream(sh_stream), sh_stream->lc3_frame_duration_us,
335 		sh_stream->lc3_freq_hz);
336 
337 	sh_stream->tx.lc3_encoder =
338 		lc3_setup_encoder(sh_stream->lc3_frame_duration_us, sh_stream->lc3_freq_hz,
339 				  IS_ENABLED(CONFIG_USB_DEVICE_AUDIO) ? USB_SAMPLE_RATE : 0,
340 				  &sh_stream->tx.lc3_encoder_mem);
341 	if (sh_stream->tx.lc3_encoder == NULL) {
342 		bt_shell_error("Failed to setup LC3 encoder - wrong parameters?\n");
343 		return -EINVAL;
344 	}
345 
346 	return 0;
347 }
348 
349 /**
350  * Use the math lib to generate a sine-wave using 16 bit samples into a buffer.
351  *
352  * @param buf Destination buffer
353  * @param length_us Length of the buffer in microseconds
354  * @param frequency_hz frequency in Hz
355  * @param sample_rate_hz sample-rate in Hz.
356  */
fill_lc3_tx_buf_sin(int16_t * buf,int length_us,int frequency_hz,int sample_rate_hz)357 static void fill_lc3_tx_buf_sin(int16_t *buf, int length_us, int frequency_hz, int sample_rate_hz)
358 {
359 	const uint32_t sine_period_samples = sample_rate_hz / frequency_hz;
360 	const size_t num_samples = (length_us * sample_rate_hz) / USEC_PER_SEC;
361 	const float step = 2 * 3.1415 / sine_period_samples;
362 
363 	for (size_t i = 0; i < num_samples; i++) {
364 		const float sample = sinf(i * step);
365 
366 		buf[i] = (int16_t)(AUDIO_VOLUME * sample);
367 	}
368 }
369 
encode_frame(struct shell_stream * sh_stream,uint8_t index,size_t frame_cnt,struct net_buf * out_buf)370 static bool encode_frame(struct shell_stream *sh_stream, uint8_t index, size_t frame_cnt,
371 			 struct net_buf *out_buf)
372 {
373 	const size_t total_frames = sh_stream->lc3_chan_cnt * sh_stream->lc3_frame_blocks_per_sdu;
374 	const uint16_t octets_per_frame = sh_stream->lc3_octets_per_frame;
375 	int lc3_ret;
376 
377 	if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
378 		enum bt_audio_location chan_alloc;
379 		int err;
380 
381 		err = get_lc3_chan_alloc_from_index(sh_stream, index, &chan_alloc);
382 		if (err != 0) {
383 			/* Not suitable for USB */
384 			false;
385 		}
386 
387 		/* TODO: Move the following to a function in bap_usb.c*/
388 		bap_usb_get_frame(sh_stream, chan_alloc, lc3_tx_buf);
389 	} else {
390 		/* Generate sine wave */
391 		fill_lc3_tx_buf_sin(lc3_tx_buf, sh_stream->lc3_frame_duration_us,
392 				    AUDIO_TONE_FREQUENCY_HZ, sh_stream->lc3_freq_hz);
393 	}
394 
395 	if ((sh_stream->tx.encoded_cnt % bap_stats_interval) == 0) {
396 		bt_shell_print("[%zu]: Encoding frame of size %u (%u/%u)",
397 			       sh_stream->tx.encoded_cnt, octets_per_frame, frame_cnt + 1,
398 			       total_frames);
399 	}
400 
401 	lc3_ret = lc3_encode(sh_stream->tx.lc3_encoder, LC3_PCM_FORMAT_S16, lc3_tx_buf, 1,
402 			     octets_per_frame, net_buf_tail(out_buf));
403 	if (lc3_ret == -1) {
404 		bt_shell_error("LC3 encoder failed - wrong parameters?: %d", lc3_ret);
405 
406 		return false;
407 	}
408 
409 	out_buf->len += octets_per_frame;
410 
411 	return true;
412 }
413 
encode_frame_block(struct shell_stream * sh_stream,size_t frame_cnt,struct net_buf * out_buf)414 static size_t encode_frame_block(struct shell_stream *sh_stream, size_t frame_cnt,
415 				 struct net_buf *out_buf)
416 {
417 	const uint8_t chan_cnt = sh_stream->lc3_chan_cnt;
418 	size_t encoded_frames = 0U;
419 
420 	for (uint8_t i = 0U; i < chan_cnt; i++) {
421 		/* We provide the total number of decoded frames to `decode_frame` for logging
422 		 * purposes
423 		 */
424 		if (encode_frame(sh_stream, i, frame_cnt, out_buf)) {
425 			encoded_frames++;
426 		}
427 	}
428 
429 	return encoded_frames;
430 }
431 
do_lc3_encode(struct shell_stream * sh_stream,struct net_buf * out_buf)432 static void do_lc3_encode(struct shell_stream *sh_stream, struct net_buf *out_buf)
433 {
434 	if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO) && !bap_usb_can_get_full_sdu(sh_stream)) {
435 		/* No op - Will just send empty SDU */
436 	} else {
437 		size_t frame_cnt = 0U;
438 
439 		for (uint8_t i = 0U; i < sh_stream->lc3_frame_blocks_per_sdu; i++) {
440 			frame_cnt += encode_frame_block(sh_stream, frame_cnt, out_buf);
441 
442 			sh_stream->tx.encoded_cnt++;
443 		}
444 	}
445 }
446 
lc3_audio_send_data(struct shell_stream * sh_stream)447 static void lc3_audio_send_data(struct shell_stream *sh_stream)
448 {
449 	struct bt_bap_stream *bap_stream = bap_stream_from_shell_stream(sh_stream);
450 	const uint16_t tx_sdu_len = sh_stream->lc3_frame_blocks_per_sdu * sh_stream->lc3_chan_cnt *
451 				    sh_stream->lc3_octets_per_frame;
452 	struct net_buf *buf;
453 	int err;
454 
455 	if (!sh_stream->is_tx || !sh_stream->tx.active) {
456 		/* TX has been aborted */
457 		return;
458 	}
459 
460 	if (sh_stream->tx.lc3_encoder == NULL) {
461 		bt_shell_error("LC3 encoder not setup, cannot encode data");
462 		return;
463 	}
464 
465 	if (bap_stream == NULL || bap_stream->qos == NULL) {
466 		bt_shell_error("invalid stream, aborting");
467 		return;
468 	}
469 
470 	if (tx_sdu_len == 0U || tx_sdu_len > SINE_TX_POOL_SIZE) {
471 		bt_shell_error(
472 			"Cannot send %u length SDU (from frame blocks per sdu %u, channel "
473 			"count %u and %u octets per frame) for pool size %d",
474 			tx_sdu_len, sh_stream->lc3_frame_blocks_per_sdu,
475 			sh_stream->lc3_chan_cnt, sh_stream->lc3_octets_per_frame,
476 			SINE_TX_POOL_SIZE);
477 		return;
478 	}
479 
480 	if (atomic_get(&sh_stream->tx.lc3_enqueue_cnt) == 0U) {
481 		/* no op */
482 		return;
483 	}
484 
485 	buf = net_buf_alloc(&sine_tx_pool, K_FOREVER);
486 	net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
487 
488 	do_lc3_encode(sh_stream, buf);
489 
490 	err = bt_bap_stream_send(bap_stream, buf, sh_stream->tx.seq_num);
491 	if (err < 0) {
492 		bt_shell_error("Failed to send LC3 audio data (%d)", err);
493 		net_buf_unref(buf);
494 
495 		return;
496 	}
497 
498 	if ((sh_stream->tx.lc3_sdu_cnt % bap_stats_interval) == 0U) {
499 		bt_shell_info("[%zu]: stream %p : TX LC3: %zu (seq_num %u)",
500 			      sh_stream->tx.lc3_sdu_cnt, bap_stream, tx_sdu_len,
501 			      sh_stream->tx.seq_num);
502 	}
503 
504 	sh_stream->tx.lc3_sdu_cnt++;
505 	sh_stream->tx.seq_num++;
506 	atomic_dec(&sh_stream->tx.lc3_enqueue_cnt);
507 }
508 
lc3_sent_cb(struct bt_bap_stream * bap_stream)509 static void lc3_sent_cb(struct bt_bap_stream *bap_stream)
510 {
511 	struct shell_stream *sh_stream = shell_stream_from_bap_stream(bap_stream);
512 
513 	if (!sh_stream->is_tx) {
514 		return;
515 	}
516 
517 	atomic_inc(&sh_stream->tx.lc3_enqueue_cnt);
518 }
519 
encode_and_send_cb(struct shell_stream * sh_stream,void * user_data)520 static void encode_and_send_cb(struct shell_stream *sh_stream, void *user_data)
521 {
522 	if (sh_stream->is_tx) {
523 		lc3_audio_send_data(sh_stream);
524 	}
525 }
526 
lc3_encoder_thread_func(void * arg1,void * arg2,void * arg3)527 static void lc3_encoder_thread_func(void *arg1, void *arg2, void *arg3)
528 {
529 	/* This will attempt to send on all TX streams.
530 	 * If there are no buffers available or the stream already have PRIME_COUNT outstanding SDUs
531 	 * the stream will not send anything.
532 	 *
533 	 * If USB is enabled it will attempt to read from buffered USB audio data.
534 	 * If there is no data available it will send empty SDUs
535 	 */
536 	while (true) {
537 		bap_foreach_stream(encode_and_send_cb, NULL);
538 		k_sleep(K_MSEC(1));
539 	}
540 }
541 #endif /* CONFIG_LIBLC3 && CONFIG_BT_AUDIO_TX */
542 
bap_get_named_preset(bool is_unicast,enum bt_audio_dir dir,const char * preset_arg)543 const struct named_lc3_preset *bap_get_named_preset(bool is_unicast, enum bt_audio_dir dir,
544 						    const char *preset_arg)
545 {
546 	if (is_unicast) {
547 		for (size_t i = 0U; i < ARRAY_SIZE(lc3_unicast_presets); i++) {
548 			if (!strcmp(preset_arg, lc3_unicast_presets[i].name)) {
549 				return &lc3_unicast_presets[i];
550 			}
551 		}
552 	} else {
553 		for (size_t i = 0U; i < ARRAY_SIZE(lc3_broadcast_presets); i++) {
554 			if (!strcmp(preset_arg, lc3_broadcast_presets[i].name)) {
555 				return &lc3_broadcast_presets[i];
556 			}
557 		}
558 	}
559 
560 	if (IS_ENABLED(CONFIG_BT_GMAP)) {
561 		return gmap_get_named_preset(is_unicast, dir, preset_arg);
562 	}
563 
564 	return NULL;
565 }
566 
567 #if defined(CONFIG_BT_PACS)
568 static const struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3(
569 	BT_AUDIO_CODEC_CAP_FREQ_ANY, BT_AUDIO_CODEC_CAP_DURATION_ANY,
570 	BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1, 2), 30, 240, MAX_CODEC_FRAMES_PER_SDU, CONTEXT);
571 
572 #if defined(CONFIG_BT_PAC_SNK)
573 static struct bt_pacs_cap cap_sink = {
574 	.codec_cap = &lc3_codec_cap,
575 };
576 #endif /* CONFIG_BT_PAC_SNK */
577 
578 #if defined(CONFIG_BT_PAC_SRC)
579 static struct bt_pacs_cap cap_source = {
580 	.codec_cap = &lc3_codec_cap,
581 };
582 #endif /* CONFIG_BT_PAC_SRC */
583 #endif /* CONFIG_BT_PACS */
584 
585 #if defined(CONFIG_BT_BAP_UNICAST)
set_unicast_stream(struct bt_bap_stream * stream)586 static void set_unicast_stream(struct bt_bap_stream *stream)
587 {
588 	default_stream = stream;
589 
590 	for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
591 		if (stream == bap_stream_from_shell_stream(&unicast_streams[i])) {
592 			bt_shell_print("Default stream: %u", i + 1);
593 		}
594 	}
595 }
596 
cmd_select_unicast(const struct shell * sh,size_t argc,char * argv[])597 static int cmd_select_unicast(const struct shell *sh, size_t argc, char *argv[])
598 {
599 	struct bt_bap_stream *stream;
600 	unsigned long index;
601 	int err = 0;
602 
603 	index = shell_strtoul(argv[1], 0, &err);
604 	if (err != 0) {
605 		shell_error(sh, "Could not parse index: %d", err);
606 
607 		return -ENOEXEC;
608 	}
609 
610 	if (index > ARRAY_SIZE(unicast_streams)) {
611 		shell_error(sh, "Invalid index: %lu", index);
612 
613 		return -ENOEXEC;
614 	}
615 
616 	stream = bap_stream_from_shell_stream(&unicast_streams[index]);
617 
618 	set_unicast_stream(stream);
619 
620 	return 0;
621 }
622 
623 #if defined(CONFIG_BT_BAP_UNICAST_SERVER)
624 static const struct bt_bap_qos_cfg_pref qos_pref =
625 	BT_BAP_QOS_CFG_PREF(true, BT_GAP_LE_PHY_2M, 0u, 60u, 10000u, 60000u, 10000u, 60000u);
626 
stream_alloc(void)627 static struct bt_bap_stream *stream_alloc(void)
628 {
629 	for (size_t i = 0; i < ARRAY_SIZE(unicast_streams); i++) {
630 		struct bt_bap_stream *stream = bap_stream_from_shell_stream(&unicast_streams[i]);
631 
632 		if (!stream->conn) {
633 			return stream;
634 		}
635 	}
636 
637 	return NULL;
638 }
639 
lc3_config(struct bt_conn * conn,const struct bt_bap_ep * ep,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_stream ** stream,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)640 static int lc3_config(struct bt_conn *conn, const struct bt_bap_ep *ep, enum bt_audio_dir dir,
641 		      const struct bt_audio_codec_cfg *codec_cfg, struct bt_bap_stream **stream,
642 		      struct bt_bap_qos_cfg_pref *const pref, struct bt_bap_ascs_rsp *rsp)
643 {
644 	bt_shell_print("ASE Codec Config: conn %p ep %p dir %u", conn, ep, dir);
645 
646 	print_codec_cfg(0, codec_cfg);
647 
648 	*stream = stream_alloc();
649 	if (*stream == NULL) {
650 		bt_shell_print("No unicast_streams available");
651 
652 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM, BT_BAP_ASCS_REASON_NONE);
653 
654 		return -ENOMEM;
655 	}
656 
657 	bt_shell_print("ASE Codec Config stream %p", *stream);
658 
659 	set_unicast_stream(*stream);
660 
661 	*pref = qos_pref;
662 
663 	return 0;
664 }
665 
lc3_reconfig(struct bt_bap_stream * stream,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)666 static int lc3_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir,
667 			const struct bt_audio_codec_cfg *codec_cfg,
668 			struct bt_bap_qos_cfg_pref *const pref, struct bt_bap_ascs_rsp *rsp)
669 {
670 	bt_shell_print("ASE Codec Reconfig: stream %p", stream);
671 
672 	print_codec_cfg(0, codec_cfg);
673 
674 	if (default_stream == NULL) {
675 		set_unicast_stream(stream);
676 	}
677 
678 	*pref = qos_pref;
679 
680 	return 0;
681 }
682 
lc3_qos(struct bt_bap_stream * stream,const struct bt_bap_qos_cfg * qos,struct bt_bap_ascs_rsp * rsp)683 static int lc3_qos(struct bt_bap_stream *stream, const struct bt_bap_qos_cfg *qos,
684 		   struct bt_bap_ascs_rsp *rsp)
685 {
686 	bt_shell_print("QoS: stream %p %p", stream, qos);
687 
688 	print_qos(qos);
689 
690 	return 0;
691 }
692 
lc3_enable(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)693 static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len,
694 		      struct bt_bap_ascs_rsp *rsp)
695 {
696 	bt_shell_print("Enable: stream %p meta_len %zu", stream, meta_len);
697 
698 	return 0;
699 }
700 
lc3_start(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)701 static int lc3_start(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
702 {
703 	bt_shell_print("Start: stream %p", stream);
704 
705 	return 0;
706 }
707 
meta_data_func_cb(struct bt_data * data,void * user_data)708 static bool meta_data_func_cb(struct bt_data *data, void *user_data)
709 {
710 	struct bt_bap_ascs_rsp *rsp = (struct bt_bap_ascs_rsp *)user_data;
711 
712 	if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(data->type)) {
713 		printk("Invalid metadata type %u or length %u\n", data->type, data->data_len);
714 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED, data->type);
715 		return false;
716 	}
717 
718 	return true;
719 }
720 
lc3_metadata(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)721 static int lc3_metadata(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len,
722 			struct bt_bap_ascs_rsp *rsp)
723 {
724 	bt_shell_print("Metadata: stream %p meta_len %zu", stream, meta_len);
725 
726 	return bt_audio_data_parse(meta, meta_len, meta_data_func_cb, rsp);
727 }
728 
lc3_disable(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)729 static int lc3_disable(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
730 {
731 	bt_shell_print("Disable: stream %p", stream);
732 
733 	return 0;
734 }
735 
lc3_stop(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)736 static int lc3_stop(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
737 {
738 	bt_shell_print("Stop: stream %p", stream);
739 
740 	return 0;
741 }
742 
lc3_release(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)743 static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
744 {
745 	bt_shell_print("Release: stream %p", stream);
746 
747 	if (stream == default_stream) {
748 		default_stream = NULL;
749 	}
750 
751 	return 0;
752 }
753 
754 static const struct bt_bap_unicast_server_cb unicast_server_cb = {
755 	.config = lc3_config,
756 	.reconfig = lc3_reconfig,
757 	.qos = lc3_qos,
758 	.enable = lc3_enable,
759 	.start = lc3_start,
760 	.metadata = lc3_metadata,
761 	.disable = lc3_disable,
762 	.stop = lc3_stop,
763 	.release = lc3_release,
764 };
765 #endif /* CONFIG_BT_BAP_UNICAST_SERVER */
766 
strmeta(const char * name)767 static uint16_t strmeta(const char *name)
768 {
769 	if (strcmp(name, "Unspecified") == 0) {
770 		return BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED;
771 	} else if (strcmp(name, "Conversational") == 0) {
772 		return BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL;
773 	} else if (strcmp(name, "Media") == 0) {
774 		return BT_AUDIO_CONTEXT_TYPE_MEDIA;
775 	} else if (strcmp(name, "Game") == 0) {
776 		return BT_AUDIO_CONTEXT_TYPE_GAME;
777 	} else if (strcmp(name, "Instructional") == 0) {
778 		return BT_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL;
779 	} else if (strcmp(name, "VoiceAssistants") == 0) {
780 		return BT_AUDIO_CONTEXT_TYPE_VOICE_ASSISTANTS;
781 	} else if (strcmp(name, "Live") == 0) {
782 		return BT_AUDIO_CONTEXT_TYPE_LIVE;
783 	} else if (strcmp(name, "SoundEffects") == 0) {
784 		return BT_AUDIO_CONTEXT_TYPE_SOUND_EFFECTS;
785 	} else if (strcmp(name, "Notifications") == 0) {
786 		return BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS;
787 	} else if (strcmp(name, "Ringtone") == 0) {
788 		return BT_AUDIO_CONTEXT_TYPE_RINGTONE;
789 	} else if (strcmp(name, "Alerts") == 0) {
790 		return BT_AUDIO_CONTEXT_TYPE_ALERTS;
791 	} else if (strcmp(name, "EmergencyAlarm") == 0) {
792 		return BT_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM;
793 	}
794 
795 	return 0u;
796 }
797 
set_metadata(struct bt_audio_codec_cfg * codec_cfg,const char * meta_str)798 static int set_metadata(struct bt_audio_codec_cfg *codec_cfg, const char *meta_str)
799 {
800 	uint16_t context;
801 
802 	context = strmeta(meta_str);
803 	if (context == 0) {
804 		return -ENOEXEC;
805 	}
806 
807 	/* TODO: Check the type and only overwrite the streaming context */
808 	sys_put_le16(context, codec_cfg->meta);
809 
810 	return 0;
811 }
812 
813 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
bap_ac_create_unicast_group(const struct bap_unicast_ac_param * param,struct shell_stream * snk_uni_streams[],size_t snk_cnt,struct shell_stream * src_uni_streams[],size_t src_cnt)814 int bap_ac_create_unicast_group(const struct bap_unicast_ac_param *param,
815 				struct shell_stream *snk_uni_streams[], size_t snk_cnt,
816 				struct shell_stream *src_uni_streams[], size_t src_cnt)
817 {
818 	struct bt_bap_unicast_group_stream_param snk_group_stream_params[BAP_UNICAST_AC_MAX_SNK] = {
819 		0};
820 	struct bt_bap_unicast_group_stream_param src_group_stream_params[BAP_UNICAST_AC_MAX_SRC] = {
821 		0};
822 	struct bt_bap_unicast_group_stream_pair_param pair_params[BAP_UNICAST_AC_MAX_PAIR] = {0};
823 	struct bt_bap_unicast_group_param group_param = {0};
824 	struct bt_bap_qos_cfg *snk_qos[BAP_UNICAST_AC_MAX_SNK];
825 	struct bt_bap_qos_cfg *src_qos[BAP_UNICAST_AC_MAX_SRC];
826 	size_t snk_stream_cnt = 0U;
827 	size_t src_stream_cnt = 0U;
828 	size_t pair_cnt = 0U;
829 
830 	for (size_t i = 0U; i < snk_cnt; i++) {
831 		snk_qos[i] = &snk_uni_streams[i]->qos;
832 	}
833 
834 	for (size_t i = 0U; i < src_cnt; i++) {
835 		src_qos[i] = &src_uni_streams[i]->qos;
836 	}
837 
838 	/* Create Group
839 	 *
840 	 * First setup the individual stream parameters and then match them in pairs by connection
841 	 * and direction
842 	 */
843 	for (size_t i = 0U; i < snk_cnt; i++) {
844 		snk_group_stream_params[i].qos = snk_qos[i];
845 		snk_group_stream_params[i].stream =
846 			bap_stream_from_shell_stream(snk_uni_streams[i]);
847 	}
848 	for (size_t i = 0U; i < src_cnt; i++) {
849 		src_group_stream_params[i].qos = src_qos[i];
850 		src_group_stream_params[i].stream =
851 			bap_stream_from_shell_stream(src_uni_streams[i]);
852 	}
853 
854 	for (size_t i = 0U; i < param->conn_cnt; i++) {
855 		for (size_t j = 0; j < MAX(param->snk_cnt[i], param->src_cnt[i]); j++) {
856 			if (param->snk_cnt[i] > j) {
857 				pair_params[pair_cnt].tx_param =
858 					&snk_group_stream_params[snk_stream_cnt++];
859 			} else {
860 				pair_params[pair_cnt].tx_param = NULL;
861 			}
862 
863 			if (param->src_cnt[i] > j) {
864 				pair_params[pair_cnt].rx_param =
865 					&src_group_stream_params[src_stream_cnt++];
866 			} else {
867 				pair_params[pair_cnt].rx_param = NULL;
868 			}
869 
870 			pair_cnt++;
871 		}
872 	}
873 
874 	group_param.packing = BT_ISO_PACKING_SEQUENTIAL;
875 	group_param.params = pair_params;
876 	group_param.params_count = pair_cnt;
877 
878 	return bt_bap_unicast_group_create(&group_param, &default_unicast_group);
879 }
880 
stream_dir(const struct bt_bap_stream * stream)881 static uint8_t stream_dir(const struct bt_bap_stream *stream)
882 {
883 	if (stream->conn) {
884 		uint8_t conn_index = bt_conn_index(stream->conn);
885 
886 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
887 		for (size_t i = 0; i < ARRAY_SIZE(snks[conn_index]); i++) {
888 			const struct bt_bap_ep *snk_ep = snks[conn_index][i];
889 
890 			if (snk_ep != NULL && stream->ep == snk_ep) {
891 				return BT_AUDIO_DIR_SINK;
892 			}
893 		}
894 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
895 
896 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
897 		for (size_t i = 0; i < ARRAY_SIZE(srcs[conn_index]); i++) {
898 			const struct bt_bap_ep *src_ep = srcs[conn_index][i];
899 
900 			if (src_ep != NULL && stream->ep == src_ep) {
901 				return BT_AUDIO_DIR_SOURCE;
902 			}
903 		}
904 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
905 	}
906 
907 	__ASSERT(false, "Invalid stream");
908 	return 0;
909 }
910 
print_remote_codec_cap(const struct bt_conn * conn,const struct bt_audio_codec_cap * codec_cap,enum bt_audio_dir dir)911 static void print_remote_codec_cap(const struct bt_conn *conn,
912 				   const struct bt_audio_codec_cap *codec_cap,
913 				   enum bt_audio_dir dir)
914 {
915 	bt_shell_print("conn %p: codec_cap %p dir 0x%02x", conn, codec_cap, dir);
916 
917 	print_codec_cap(0, codec_cap);
918 }
919 
920 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
add_sink(const struct bt_conn * conn,struct bt_bap_ep * ep)921 static void add_sink(const struct bt_conn *conn, struct bt_bap_ep *ep)
922 {
923 	const uint8_t conn_index = bt_conn_index(conn);
924 
925 	for (size_t i = 0U; i < ARRAY_SIZE(snks[conn_index]); i++) {
926 		if (snks[conn_index][i] == NULL) {
927 			bt_shell_print("Conn: %p, Sink #%zu: ep %p", conn, i, ep);
928 
929 			snks[conn_index][i] = ep;
930 			return;
931 		}
932 	}
933 
934 	bt_shell_error("Could not add more sink endpoints");
935 }
936 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
937 
938 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
add_source(const struct bt_conn * conn,struct bt_bap_ep * ep)939 static void add_source(const struct bt_conn *conn, struct bt_bap_ep *ep)
940 {
941 	const uint8_t conn_index = bt_conn_index(conn);
942 
943 	for (size_t i = 0U; i < ARRAY_SIZE(srcs[conn_index]); i++) {
944 		if (srcs[conn_index][i] == NULL) {
945 			bt_shell_print("Conn: %p, Source #%zu: ep %p", conn, i, ep);
946 
947 			srcs[conn_index][i] = ep;
948 			return;
949 		}
950 	}
951 
952 	bt_shell_error("Could not add more sink endpoints");
953 }
954 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
955 
pac_record_cb(struct bt_conn * conn,enum bt_audio_dir dir,const struct bt_audio_codec_cap * codec_cap)956 static void pac_record_cb(struct bt_conn *conn, enum bt_audio_dir dir,
957 			  const struct bt_audio_codec_cap *codec_cap)
958 {
959 	print_remote_codec_cap(conn, codec_cap, dir);
960 }
961 
endpoint_cb(struct bt_conn * conn,enum bt_audio_dir dir,struct bt_bap_ep * ep)962 static void endpoint_cb(struct bt_conn *conn, enum bt_audio_dir dir, struct bt_bap_ep *ep)
963 {
964 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
965 	if (dir == BT_AUDIO_DIR_SINK) {
966 		add_sink(conn, ep);
967 	}
968 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
969 
970 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
971 	if (dir == BT_AUDIO_DIR_SOURCE) {
972 		add_source(conn, ep);
973 	}
974 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0*/
975 }
976 
discover_cb(struct bt_conn * conn,int err,enum bt_audio_dir dir)977 static void discover_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir)
978 {
979 	bt_shell_print("Discover complete: err %d", err);
980 }
981 
discover_all(struct bt_conn * conn,int err,enum bt_audio_dir dir)982 static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir)
983 {
984 	/* Sinks discovery complete, now discover sources */
985 	if (dir == BT_AUDIO_DIR_SINK) {
986 		dir = BT_AUDIO_DIR_SOURCE;
987 		unicast_client_cbs.discover = discover_cb;
988 
989 		err = bt_bap_unicast_client_discover(default_conn, dir);
990 		if (err) {
991 			bt_shell_error("bt_bap_unicast_client_discover err %d", err);
992 		}
993 	}
994 }
995 
unicast_client_location_cb(struct bt_conn * conn,enum bt_audio_dir dir,enum bt_audio_location loc)996 static void unicast_client_location_cb(struct bt_conn *conn,
997 				       enum bt_audio_dir dir,
998 				       enum bt_audio_location loc)
999 {
1000 	bt_shell_print("dir %u loc %X\n", dir, loc);
1001 }
1002 
available_contexts_cb(struct bt_conn * conn,enum bt_audio_context snk_ctx,enum bt_audio_context src_ctx)1003 static void available_contexts_cb(struct bt_conn *conn,
1004 				  enum bt_audio_context snk_ctx,
1005 				  enum bt_audio_context src_ctx)
1006 {
1007 	bt_shell_print("snk ctx %u src ctx %u\n", snk_ctx, src_ctx);
1008 }
1009 
config_cb(struct bt_bap_stream * stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)1010 static void config_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code,
1011 		      enum bt_bap_ascs_reason reason)
1012 {
1013 	bt_shell_print("stream %p config operation rsp_code %u reason %u",
1014 		       stream, rsp_code, reason);
1015 
1016 	if (default_stream == NULL) {
1017 		default_stream = stream;
1018 	}
1019 }
1020 
qos_cb(struct bt_bap_stream * stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)1021 static void qos_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code,
1022 		   enum bt_bap_ascs_reason reason)
1023 {
1024 	bt_shell_print("stream %p qos operation rsp_code %u reason %u",
1025 		       stream, rsp_code, reason);
1026 }
1027 
enable_cb(struct bt_bap_stream * stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)1028 static void enable_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code,
1029 		      enum bt_bap_ascs_reason reason)
1030 {
1031 	bt_shell_print("stream %p enable operation rsp_code %u reason %u",
1032 		       stream, rsp_code, reason);
1033 }
1034 
start_cb(struct bt_bap_stream * stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)1035 static void start_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code,
1036 		     enum bt_bap_ascs_reason reason)
1037 {
1038 	bt_shell_print("stream %p start operation rsp_code %u reason %u",
1039 		       stream, rsp_code, reason);
1040 }
1041 
stop_cb(struct bt_bap_stream * stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)1042 static void stop_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code,
1043 		    enum bt_bap_ascs_reason reason)
1044 {
1045 	bt_shell_print("stream %p stop operation rsp_code %u reason %u",
1046 		       stream, rsp_code, reason);
1047 }
1048 
disable_cb(struct bt_bap_stream * stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)1049 static void disable_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code,
1050 		       enum bt_bap_ascs_reason reason)
1051 {
1052 	bt_shell_print("stream %p disable operation rsp_code %u reason %u",
1053 		       stream, rsp_code, reason);
1054 }
1055 
metadata_cb(struct bt_bap_stream * stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)1056 static void metadata_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code,
1057 			enum bt_bap_ascs_reason reason)
1058 {
1059 	bt_shell_print("stream %p metadata operation rsp_code %u reason %u",
1060 		       stream, rsp_code, reason);
1061 }
1062 
release_cb(struct bt_bap_stream * stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)1063 static void release_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code,
1064 		       enum bt_bap_ascs_reason reason)
1065 {
1066 	bt_shell_print("stream %p release operation rsp_code %u reason %u",
1067 		       stream, rsp_code, reason);
1068 }
1069 
1070 static struct bt_bap_unicast_client_cb unicast_client_cbs = {
1071 	.location = unicast_client_location_cb,
1072 	.available_contexts = available_contexts_cb,
1073 	.config = config_cb,
1074 	.qos = qos_cb,
1075 	.enable = enable_cb,
1076 	.start = start_cb,
1077 	.stop = stop_cb,
1078 	.disable = disable_cb,
1079 	.metadata = metadata_cb,
1080 	.release = release_cb,
1081 	.pac_record = pac_record_cb,
1082 	.endpoint = endpoint_cb,
1083 };
1084 
cmd_discover(const struct shell * sh,size_t argc,char * argv[])1085 static int cmd_discover(const struct shell *sh, size_t argc, char *argv[])
1086 {
1087 	static bool cbs_registered;
1088 	enum bt_audio_dir dir;
1089 	uint8_t conn_index;
1090 	int err;
1091 
1092 	if (!default_conn) {
1093 		shell_error(sh, "Not connected");
1094 		return -ENOEXEC;
1095 	}
1096 
1097 	if (!initialized) {
1098 		shell_error(sh, "Not initialized");
1099 		return -ENOEXEC;
1100 	}
1101 
1102 	if (!cbs_registered) {
1103 		err = bt_bap_unicast_client_register_cb(&unicast_client_cbs);
1104 
1105 		if (err != 0) {
1106 			shell_error(sh, "Failed to register unicast client callbacks: %d", err);
1107 			return err;
1108 		}
1109 
1110 		cbs_registered = true;
1111 	}
1112 
1113 	unicast_client_cbs.discover = discover_all;
1114 	dir = BT_AUDIO_DIR_SINK;
1115 
1116 	if (argc > 1) {
1117 		if (!strcmp(argv[1], "sink")) {
1118 			unicast_client_cbs.discover = discover_cb;
1119 		} else if (!strcmp(argv[1], "source")) {
1120 			unicast_client_cbs.discover = discover_cb;
1121 			dir = BT_AUDIO_DIR_SOURCE;
1122 		} else {
1123 			shell_error(sh, "Unsupported dir: %s", argv[1]);
1124 			return -ENOEXEC;
1125 		}
1126 	}
1127 
1128 	err = bt_bap_unicast_client_discover(default_conn, dir);
1129 	if (err != 0) {
1130 		return -ENOEXEC;
1131 	}
1132 
1133 	conn_index = bt_conn_index(default_conn);
1134 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
1135 	memset(srcs[conn_index], 0, sizeof(srcs[conn_index]));
1136 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
1137 
1138 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
1139 	memset(snks[conn_index], 0, sizeof(snks[conn_index]));
1140 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
1141 
1142 	return 0;
1143 }
1144 
cmd_config(const struct shell * sh,size_t argc,char * argv[])1145 static int cmd_config(const struct shell *sh, size_t argc, char *argv[])
1146 {
1147 	enum bt_audio_location location = BT_AUDIO_LOCATION_MONO_AUDIO;
1148 	const struct named_lc3_preset *named_preset;
1149 	struct shell_stream *uni_stream;
1150 	struct bt_bap_stream *bap_stream;
1151 	struct bt_bap_ep *ep = NULL;
1152 	enum bt_audio_dir dir;
1153 	unsigned long index;
1154 	uint8_t conn_index;
1155 	int err = 0;
1156 
1157 	if (!default_conn) {
1158 		shell_error(sh, "Not connected");
1159 		return -ENOEXEC;
1160 	}
1161 	conn_index = bt_conn_index(default_conn);
1162 
1163 	if (default_stream == NULL) {
1164 		bap_stream = bap_stream_from_shell_stream(&unicast_streams[0]);
1165 	} else {
1166 		bap_stream = default_stream;
1167 	}
1168 
1169 	index = shell_strtoul(argv[2], 0, &err);
1170 	if (err != 0) {
1171 		shell_error(sh, "Could not parse index: %d", err);
1172 
1173 		return -ENOEXEC;
1174 	}
1175 
1176 	if (index > ARRAY_SIZE(unicast_streams)) {
1177 		shell_error(sh, "Invalid index: %lu", index);
1178 
1179 		return -ENOEXEC;
1180 	}
1181 
1182 	if (false) {
1183 
1184 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
1185 	} else if (!strcmp(argv[1], "sink")) {
1186 		dir = BT_AUDIO_DIR_SINK;
1187 		ep = snks[conn_index][index];
1188 
1189 		named_preset = &default_sink_preset;
1190 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
1191 
1192 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
1193 	} else if (!strcmp(argv[1], "source")) {
1194 		dir = BT_AUDIO_DIR_SOURCE;
1195 		ep = srcs[conn_index][index];
1196 
1197 		named_preset = &default_source_preset;
1198 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
1199 	} else {
1200 		shell_error(sh, "Unsupported dir: %s", argv[1]);
1201 		return -ENOEXEC;
1202 	}
1203 
1204 	if (!ep) {
1205 		shell_error(sh, "Unable to find endpoint");
1206 		return -ENOEXEC;
1207 	}
1208 
1209 	for (size_t i = 3U; i < argc; i++) {
1210 		const char *arg = argv[i];
1211 
1212 		/* argc needs to be larger than `i` to parse the argument value */
1213 		if (argc <= i) {
1214 			shell_help(sh);
1215 
1216 			return SHELL_CMD_HELP_PRINTED;
1217 		}
1218 
1219 		if (strcmp(arg, "loc") == 0) {
1220 			unsigned long loc_bits;
1221 
1222 			arg = argv[++i];
1223 			loc_bits = shell_strtoul(arg, 0, &err);
1224 			if (err != 0) {
1225 				shell_error(sh, "Could not parse loc_bits: %d", err);
1226 
1227 				return -ENOEXEC;
1228 			}
1229 
1230 			if (loc_bits > BT_AUDIO_LOCATION_ANY) {
1231 				shell_error(sh, "Invalid loc_bits: %lu", loc_bits);
1232 
1233 				return -ENOEXEC;
1234 			}
1235 
1236 			location = (enum bt_audio_location)loc_bits;
1237 		} else if (strcmp(arg, "preset") == 0) {
1238 			if (argc > i) {
1239 				arg = argv[++i];
1240 
1241 				named_preset = bap_get_named_preset(true, dir, arg);
1242 				if (named_preset == NULL) {
1243 					shell_error(sh, "Unable to parse named_preset %s", arg);
1244 					return -ENOEXEC;
1245 				}
1246 			} else {
1247 				shell_help(sh);
1248 
1249 				return SHELL_CMD_HELP_PRINTED;
1250 			}
1251 		} else {
1252 			shell_help(sh);
1253 
1254 			return SHELL_CMD_HELP_PRINTED;
1255 		}
1256 	}
1257 
1258 	uni_stream = shell_stream_from_bap_stream(bap_stream);
1259 	copy_unicast_stream_preset(uni_stream, named_preset);
1260 
1261 	/* If location has been modified, we update the location in the codec configuration */
1262 	struct bt_audio_codec_cfg *codec_cfg = &uni_stream->codec_cfg;
1263 
1264 	for (size_t i = 0U; i < codec_cfg->data_len;) {
1265 		const uint8_t len = codec_cfg->data[i++];
1266 		uint8_t *value;
1267 		uint8_t data_len;
1268 		uint8_t type;
1269 
1270 		if (len == 0 || len > codec_cfg->data_len - i) {
1271 			/* Invalid len field */
1272 			return false;
1273 		}
1274 
1275 		type = codec_cfg->data[i++];
1276 		value = &codec_cfg->data[i];
1277 
1278 		if (type == BT_AUDIO_CODEC_CFG_CHAN_ALLOC) {
1279 			const uint32_t loc_32 = location;
1280 
1281 			sys_put_le32(loc_32, value);
1282 
1283 			shell_print(sh, "Setting location to 0x%08X", location);
1284 			break;
1285 		}
1286 
1287 		data_len = len - sizeof(type);
1288 
1289 		/* Since we are incrementing i by the value_len, we don't need to increment
1290 		 * it further in the `for` statement
1291 		 */
1292 		i += data_len;
1293 	}
1294 
1295 	if (bap_stream->ep == ep) {
1296 		err = bt_bap_stream_reconfig(bap_stream, &uni_stream->codec_cfg);
1297 		if (err != 0) {
1298 			shell_error(sh, "Unable reconfig stream: %d", err);
1299 			return -ENOEXEC;
1300 		}
1301 	} else {
1302 		err = bt_bap_stream_config(default_conn, bap_stream, ep,
1303 					   &uni_stream->codec_cfg);
1304 		if (err != 0) {
1305 			shell_error(sh, "Unable to config stream: %d", err);
1306 			return err;
1307 		}
1308 	}
1309 
1310 	shell_print(sh, "ASE config: preset %s", named_preset->name);
1311 
1312 	return 0;
1313 }
1314 
cmd_stream_qos(const struct shell * sh,size_t argc,char * argv[])1315 static int cmd_stream_qos(const struct shell *sh, size_t argc, char *argv[])
1316 {
1317 	struct bt_bap_qos_cfg *qos;
1318 	unsigned long interval;
1319 	int err = 0;
1320 
1321 	if (default_stream == NULL) {
1322 		shell_print(sh, "No stream selected");
1323 		return -ENOEXEC;
1324 	}
1325 
1326 	qos = default_stream->qos;
1327 
1328 	if (qos == NULL) {
1329 		shell_print(sh, "Stream not configured");
1330 		return -ENOEXEC;
1331 	}
1332 
1333 	interval = shell_strtoul(argv[1], 0, &err);
1334 	if (err != 0) {
1335 		return -ENOEXEC;
1336 	}
1337 
1338 	if (!IN_RANGE(interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) {
1339 		return -ENOEXEC;
1340 	}
1341 
1342 	qos->interval = interval;
1343 
1344 	if (argc > 2) {
1345 		unsigned long framing;
1346 
1347 		framing = shell_strtoul(argv[2], 0, &err);
1348 		if (err != 0) {
1349 			return -ENOEXEC;
1350 		}
1351 
1352 		if (framing != BT_ISO_FRAMING_UNFRAMED && framing != BT_ISO_FRAMING_FRAMED) {
1353 			return -ENOEXEC;
1354 		}
1355 
1356 		qos->framing = framing;
1357 	}
1358 
1359 	if (argc > 3) {
1360 		unsigned long latency;
1361 
1362 		latency = shell_strtoul(argv[3], 0, &err);
1363 		if (err != 0) {
1364 			return -ENOEXEC;
1365 		}
1366 
1367 		if (!IN_RANGE(latency, BT_ISO_LATENCY_MIN, BT_ISO_LATENCY_MAX)) {
1368 			return -ENOEXEC;
1369 		}
1370 
1371 		qos->latency = latency;
1372 	}
1373 
1374 	if (argc > 4) {
1375 		unsigned long pd;
1376 
1377 		pd = shell_strtoul(argv[4], 0, &err);
1378 		if (err != 0) {
1379 			return -ENOEXEC;
1380 		}
1381 
1382 		if (pd > BT_AUDIO_PD_MAX) {
1383 			return -ENOEXEC;
1384 		}
1385 
1386 		qos->pd = pd;
1387 	}
1388 
1389 	if (argc > 5) {
1390 		unsigned long sdu;
1391 
1392 		sdu = shell_strtoul(argv[5], 0, &err);
1393 		if (err != 0) {
1394 			return -ENOEXEC;
1395 		}
1396 
1397 		if (sdu > BT_ISO_MAX_SDU) {
1398 			return -ENOEXEC;
1399 		}
1400 
1401 		qos->sdu = sdu;
1402 	}
1403 
1404 	if (argc > 6) {
1405 		unsigned long phy;
1406 
1407 		phy = shell_strtoul(argv[6], 0, &err);
1408 		if (err != 0) {
1409 			return -ENOEXEC;
1410 		}
1411 
1412 		if (phy != BT_GAP_LE_PHY_1M && phy != BT_GAP_LE_PHY_2M &&
1413 		    phy != BT_GAP_LE_PHY_CODED) {
1414 			return -ENOEXEC;
1415 		}
1416 
1417 		qos->phy = phy;
1418 	}
1419 
1420 	if (argc > 7) {
1421 		unsigned long rtn;
1422 
1423 		rtn = shell_strtoul(argv[7], 0, &err);
1424 		if (err != 0) {
1425 			return -ENOEXEC;
1426 		}
1427 
1428 		if (rtn > BT_ISO_CONNECTED_RTN_MAX) {
1429 			return -ENOEXEC;
1430 		}
1431 
1432 		qos->rtn = rtn;
1433 	}
1434 
1435 	return 0;
1436 }
1437 
set_group_param(const struct shell * sh,struct bt_bap_unicast_group_param * group_param,struct bt_bap_unicast_group_stream_pair_param pair_param[ARRAY_SIZE (unicast_streams)],struct bt_bap_unicast_group_stream_param stream_params[ARRAY_SIZE (unicast_streams)])1438 static int set_group_param(
1439 	const struct shell *sh, struct bt_bap_unicast_group_param *group_param,
1440 	struct bt_bap_unicast_group_stream_pair_param pair_param[ARRAY_SIZE(unicast_streams)],
1441 	struct bt_bap_unicast_group_stream_param stream_params[ARRAY_SIZE(unicast_streams)])
1442 {
1443 	size_t source_cnt = 0;
1444 	size_t sink_cnt = 0;
1445 	size_t cnt = 0;
1446 
1447 	for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
1448 		struct bt_bap_stream *stream = bap_stream_from_shell_stream(&unicast_streams[i]);
1449 		struct shell_stream *uni_stream = &unicast_streams[i];
1450 
1451 		if (stream->ep != NULL) {
1452 			struct bt_bap_unicast_group_stream_param *stream_param;
1453 
1454 			stream_param = &stream_params[cnt];
1455 
1456 			stream_param->stream = stream;
1457 			if (stream_dir(stream) == BT_AUDIO_DIR_SINK) {
1458 				stream_param->qos = &uni_stream->qos;
1459 				pair_param[sink_cnt++].tx_param = stream_param;
1460 			} else {
1461 				stream_param->qos = &uni_stream->qos;
1462 				pair_param[source_cnt++].rx_param = stream_param;
1463 			}
1464 
1465 			cnt++;
1466 		}
1467 	}
1468 
1469 	if (cnt == 0U) {
1470 		shell_error(sh, "Stream cnt is 0");
1471 
1472 		return -ENOEXEC;
1473 	}
1474 
1475 	group_param->packing = BT_ISO_PACKING_SEQUENTIAL;
1476 	group_param->params = pair_param;
1477 	group_param->params_count = MAX(source_cnt, sink_cnt);
1478 
1479 	return 0;
1480 }
1481 
create_unicast_group(const struct shell * sh)1482 static int create_unicast_group(const struct shell *sh)
1483 {
1484 	struct bt_bap_unicast_group_stream_pair_param pair_param[ARRAY_SIZE(unicast_streams)] = {0};
1485 	struct bt_bap_unicast_group_stream_param stream_params[ARRAY_SIZE(unicast_streams)] = {0};
1486 	struct bt_bap_unicast_group_param group_param = {0};
1487 	int err;
1488 
1489 	err = set_group_param(sh, &group_param, pair_param, stream_params);
1490 	if (err != 0) {
1491 		return err;
1492 	}
1493 
1494 	err = bt_bap_unicast_group_create(&group_param, &default_unicast_group);
1495 	if (err != 0) {
1496 		shell_error(sh, "Unable to create default unicast group: %d", err);
1497 
1498 		return -ENOEXEC;
1499 	}
1500 
1501 	return 0;
1502 }
1503 
reconfig_unicast_group(const struct shell * sh)1504 static int reconfig_unicast_group(const struct shell *sh)
1505 {
1506 	struct bt_bap_unicast_group_stream_pair_param pair_param[ARRAY_SIZE(unicast_streams)] = {0};
1507 	struct bt_bap_unicast_group_stream_param stream_params[ARRAY_SIZE(unicast_streams)] = {0};
1508 	struct bt_bap_unicast_group_param group_param = {0};
1509 	int err;
1510 
1511 	err = set_group_param(sh, &group_param, pair_param, stream_params);
1512 	if (err != 0) {
1513 		return err;
1514 	}
1515 
1516 	err = bt_bap_unicast_group_reconfig(default_unicast_group, &group_param);
1517 	if (err != 0) {
1518 		shell_error(sh, "Unable to create default unicast group: %d", err);
1519 
1520 		return -ENOEXEC;
1521 	}
1522 
1523 	return 0;
1524 }
1525 
cmd_qos(const struct shell * sh,size_t argc,char * argv[])1526 static int cmd_qos(const struct shell *sh, size_t argc, char *argv[])
1527 {
1528 	int err;
1529 
1530 	if (default_stream == NULL) {
1531 		shell_print(sh, "No stream selected");
1532 		return -ENOEXEC;
1533 	}
1534 
1535 	if (default_conn == NULL) {
1536 		shell_error(sh, "Not connected");
1537 		return -ENOEXEC;
1538 	}
1539 
1540 	if (default_unicast_group == NULL) {
1541 		err = create_unicast_group(sh);
1542 		if (err != 0) {
1543 			return err;
1544 		}
1545 	} else {
1546 		err = reconfig_unicast_group(sh);
1547 		if (err != 0) {
1548 			return err;
1549 		}
1550 	}
1551 
1552 	err = bt_bap_stream_qos(default_conn, default_unicast_group);
1553 	if (err) {
1554 		shell_error(sh, "Unable to setup QoS: %d", err);
1555 		return -ENOEXEC;
1556 	}
1557 
1558 	return 0;
1559 }
1560 
cmd_enable(const struct shell * sh,size_t argc,char * argv[])1561 static int cmd_enable(const struct shell *sh, size_t argc, char *argv[])
1562 {
1563 	struct bt_audio_codec_cfg *codec_cfg;
1564 	int err;
1565 
1566 	if (default_stream == NULL) {
1567 		shell_error(sh, "No stream selected");
1568 		return -ENOEXEC;
1569 	}
1570 
1571 	codec_cfg = default_stream->codec_cfg;
1572 
1573 	if (argc > 1) {
1574 		err = set_metadata(codec_cfg, argv[1]);
1575 		if (err != 0) {
1576 			shell_error(sh, "Unable to handle metadata update: %d", err);
1577 			return err;
1578 		}
1579 	}
1580 
1581 	err = bt_bap_stream_enable(default_stream, codec_cfg->meta, codec_cfg->meta_len);
1582 	if (err) {
1583 		shell_error(sh, "Unable to enable Channel");
1584 		return -ENOEXEC;
1585 	}
1586 
1587 	return 0;
1588 }
1589 
cmd_stop(const struct shell * sh,size_t argc,char * argv[])1590 static int cmd_stop(const struct shell *sh, size_t argc, char *argv[])
1591 {
1592 	int err;
1593 
1594 	if (default_stream == NULL) {
1595 		shell_error(sh, "No stream selected");
1596 		return -ENOEXEC;
1597 	}
1598 
1599 	err = bt_bap_stream_stop(default_stream);
1600 	if (err) {
1601 		shell_error(sh, "Unable to stop Channel");
1602 		return -ENOEXEC;
1603 	}
1604 
1605 	return 0;
1606 }
1607 
cmd_connect(const struct shell * sh,size_t argc,char * argv[])1608 static int cmd_connect(const struct shell *sh, size_t argc, char *argv[])
1609 {
1610 	int err;
1611 
1612 	if (default_stream == NULL) {
1613 		shell_error(sh, "No stream selected");
1614 		return -ENOEXEC;
1615 	}
1616 
1617 	err = bt_bap_stream_connect(default_stream);
1618 	if (err) {
1619 		shell_error(sh, "Unable to connect stream");
1620 		return -ENOEXEC;
1621 	}
1622 
1623 	return 0;
1624 }
1625 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
1626 
cmd_metadata(const struct shell * sh,size_t argc,char * argv[])1627 static int cmd_metadata(const struct shell *sh, size_t argc, char *argv[])
1628 {
1629 	struct bt_audio_codec_cfg *codec_cfg;
1630 	int err;
1631 
1632 	if (default_stream == NULL) {
1633 		shell_error(sh, "No stream selected");
1634 		return -ENOEXEC;
1635 	}
1636 
1637 	codec_cfg = default_stream->codec_cfg;
1638 
1639 	if (argc > 1) {
1640 		err = set_metadata(codec_cfg, argv[1]);
1641 		if (err != 0) {
1642 			shell_error(sh, "Unable to handle metadata update: %d", err);
1643 			return err;
1644 		}
1645 	}
1646 
1647 	err = bt_bap_stream_metadata(default_stream, codec_cfg->meta, codec_cfg->meta_len);
1648 	if (err) {
1649 		shell_error(sh, "Unable to set Channel metadata");
1650 		return -ENOEXEC;
1651 	}
1652 
1653 	return 0;
1654 }
1655 
cmd_start(const struct shell * sh,size_t argc,char * argv[])1656 static int cmd_start(const struct shell *sh, size_t argc, char *argv[])
1657 {
1658 	int err;
1659 
1660 	if (default_stream == NULL) {
1661 		shell_error(sh, "No stream selected");
1662 		return -ENOEXEC;
1663 	}
1664 
1665 	err = bt_bap_stream_start(default_stream);
1666 	if (err) {
1667 		shell_error(sh, "Unable to start Channel");
1668 		return -ENOEXEC;
1669 	}
1670 
1671 	return 0;
1672 }
1673 
cmd_disable(const struct shell * sh,size_t argc,char * argv[])1674 static int cmd_disable(const struct shell *sh, size_t argc, char *argv[])
1675 {
1676 	int err;
1677 
1678 	if (default_stream == NULL) {
1679 		shell_error(sh, "No stream selected");
1680 		return -ENOEXEC;
1681 	}
1682 
1683 	err = bt_bap_stream_disable(default_stream);
1684 	if (err) {
1685 		shell_error(sh, "Unable to disable Channel");
1686 		return -ENOEXEC;
1687 	}
1688 
1689 	return 0;
1690 }
1691 
1692 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
conn_list_eps(struct bt_conn * conn,void * data)1693 static void conn_list_eps(struct bt_conn *conn, void *data)
1694 {
1695 	const struct shell *sh = (const struct shell *)data;
1696 	uint8_t conn_index = bt_conn_index(conn);
1697 
1698 	shell_print(sh, "Conn: %p", conn);
1699 	shell_print(sh, "  Sinks:");
1700 
1701 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
1702 	for (size_t i = 0U; i < ARRAY_SIZE(snks[conn_index]); i++) {
1703 		const struct bt_bap_ep *ep = snks[conn_index][i];
1704 
1705 		if (ep != NULL) {
1706 			struct bt_bap_ep_info ep_info;
1707 			int err;
1708 
1709 			err = bt_bap_ep_get_info(ep, &ep_info);
1710 			if (err == 0) {
1711 				shell_print(sh, "    #%u: ep %p (state: %d)", i, ep, ep_info.state);
1712 			}
1713 		}
1714 	}
1715 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
1716 
1717 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
1718 	shell_print(sh, "  Sources:");
1719 
1720 	for (size_t i = 0U; i < ARRAY_SIZE(srcs[conn_index]); i++) {
1721 		const struct bt_bap_ep *ep = srcs[conn_index][i];
1722 
1723 		if (ep != NULL) {
1724 			struct bt_bap_ep_info ep_info;
1725 			int err;
1726 
1727 			err = bt_bap_ep_get_info(ep, &ep_info);
1728 			if (err == 0) {
1729 				shell_print(sh, "    #%u: ep %p (state: %d)", i, ep, ep_info.state);
1730 			}
1731 		}
1732 	}
1733 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
1734 }
1735 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
1736 
1737 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
cmd_list(const struct shell * sh,size_t argc,char * argv[])1738 static int cmd_list(const struct shell *sh, size_t argc, char *argv[])
1739 {
1740 	shell_print(sh, "Configured Channels:");
1741 
1742 	for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
1743 		struct bt_bap_stream *stream = &unicast_streams[i].stream.bap_stream;
1744 
1745 		if (stream != NULL && stream->conn != NULL) {
1746 			shell_print(sh, "  %s#%u: stream %p dir 0x%02x group %p",
1747 				    stream == default_stream ? "*" : " ", i, stream,
1748 				    stream_dir(stream), stream->group);
1749 		}
1750 	}
1751 
1752 	bt_conn_foreach(BT_CONN_TYPE_LE, conn_list_eps, (void *)sh);
1753 
1754 	return 0;
1755 }
1756 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
1757 
cmd_release(const struct shell * sh,size_t argc,char * argv[])1758 static int cmd_release(const struct shell *sh, size_t argc, char *argv[])
1759 {
1760 	int err;
1761 
1762 	if (default_stream == NULL) {
1763 		shell_print(sh, "No stream selected");
1764 		return -ENOEXEC;
1765 	}
1766 
1767 	err = bt_bap_stream_release(default_stream);
1768 	if (err) {
1769 		shell_error(sh, "Unable to release Channel");
1770 		return -ENOEXEC;
1771 	}
1772 
1773 	return 0;
1774 }
1775 #endif /* CONFIG_BT_BAP_UNICAST */
1776 
1777 #if IS_BAP_INITIATOR
parse_config_data_args(const struct shell * sh,size_t argn,size_t argc,char * argv[],struct bt_audio_codec_cfg * codec_cfg)1778 static ssize_t parse_config_data_args(const struct shell *sh, size_t argn, size_t argc,
1779 				      char *argv[], struct bt_audio_codec_cfg *codec_cfg)
1780 {
1781 	for (; argn < argc; argn++) {
1782 		const char *arg = argv[argn];
1783 		unsigned long val;
1784 		int err = 0;
1785 
1786 		if (strcmp(arg, "freq") == 0) {
1787 			if (++argn == argc) {
1788 				shell_help(sh);
1789 
1790 				return -1;
1791 			}
1792 
1793 			arg = argv[argn];
1794 
1795 			val = shell_strtoul(arg, 0, &err);
1796 			if (err != 0) {
1797 				shell_error(sh, "Failed to parse freq from %s: %d", arg, err);
1798 
1799 				return -1;
1800 			}
1801 
1802 			if (val > UINT8_MAX) {
1803 				shell_error(sh, "Invalid freq value: %lu", val);
1804 
1805 				return -1;
1806 			}
1807 
1808 			err = bt_audio_codec_cfg_set_freq(codec_cfg,
1809 							  (enum bt_audio_codec_cfg_freq)val);
1810 			if (err < 0) {
1811 				shell_error(sh, "Failed to set freq with value %lu: %d", val, err);
1812 
1813 				return -1;
1814 			}
1815 		} else if (strcmp(arg, "dur") == 0) {
1816 			if (++argn == argc) {
1817 				shell_help(sh);
1818 
1819 				return -1;
1820 			}
1821 
1822 			arg = argv[argn];
1823 
1824 			val = shell_strtoul(arg, 0, &err);
1825 			if (err != 0) {
1826 				shell_error(sh, "Failed to parse dur from %s: %d", arg, err);
1827 
1828 				return -1;
1829 			}
1830 
1831 			if (val > UINT8_MAX) {
1832 				shell_error(sh, "Invalid dur value: %lu", val);
1833 
1834 				return -1;
1835 			}
1836 
1837 			err = bt_audio_codec_cfg_set_frame_dur(
1838 				codec_cfg, (enum bt_audio_codec_cfg_frame_dur)val);
1839 			if (err < 0) {
1840 				shell_error(sh, "Failed to set dur with value %lu: %d", val, err);
1841 
1842 				return -1;
1843 			}
1844 		} else if (strcmp(arg, "chan_alloc") == 0) {
1845 			if (++argn == argc) {
1846 				shell_help(sh);
1847 
1848 				return -1;
1849 			}
1850 
1851 			arg = argv[argn];
1852 
1853 			val = shell_strtoul(arg, 0, &err);
1854 			if (err != 0) {
1855 				shell_error(sh, "Failed to parse chan alloc from %s: %d", arg, err);
1856 
1857 				return -1;
1858 			}
1859 
1860 			if (val > UINT32_MAX) {
1861 				shell_error(sh, "Invalid chan alloc value: %lu", val);
1862 
1863 				return -1;
1864 			}
1865 
1866 			err = bt_audio_codec_cfg_set_chan_allocation(codec_cfg,
1867 								     (enum bt_audio_location)val);
1868 			if (err < 0) {
1869 				shell_error(sh, "Failed to set chan alloc with value %lu: %d", val,
1870 					    err);
1871 
1872 				return -1;
1873 			}
1874 		} else if (strcmp(arg, "frame_len") == 0) {
1875 			if (++argn == argc) {
1876 				shell_help(sh);
1877 
1878 				return -1;
1879 			}
1880 
1881 			arg = argv[argn];
1882 
1883 			val = shell_strtoul(arg, 0, &err);
1884 			if (err != 0) {
1885 				shell_error(sh, "Failed to frame len from %s: %d", arg, err);
1886 
1887 				return -1;
1888 			}
1889 
1890 			if (val > UINT16_MAX) {
1891 				shell_error(sh, "Invalid frame len value: %lu", val);
1892 
1893 				return -1;
1894 			}
1895 
1896 			err = bt_audio_codec_cfg_set_octets_per_frame(codec_cfg, (uint16_t)val);
1897 			if (err < 0) {
1898 				shell_error(sh, "Failed to set frame len with value %lu: %d", val,
1899 					    err);
1900 
1901 				return -1;
1902 			}
1903 		} else if (strcmp(arg, "frame_blks") == 0) {
1904 			if (++argn == argc) {
1905 				shell_help(sh);
1906 
1907 				return -1;
1908 			}
1909 
1910 			arg = argv[argn];
1911 
1912 			val = shell_strtoul(arg, 0, &err);
1913 			if (err != 0) {
1914 				shell_error(sh, "Failed to parse frame blks from %s: %d", arg, err);
1915 
1916 				return -1;
1917 			}
1918 
1919 			if (val > UINT8_MAX) {
1920 				shell_error(sh, "Invalid frame blks value: %lu", val);
1921 
1922 				return -1;
1923 			}
1924 
1925 			err = bt_audio_codec_cfg_set_frame_blocks_per_sdu(codec_cfg, (uint8_t)val);
1926 			if (err < 0) {
1927 				shell_error(sh, "Failed to set frame blks with value %lu: %d", val,
1928 					    err);
1929 
1930 				return -1;
1931 			}
1932 		} else { /* we are no longer parsing codec config values */
1933 			/* Decrement to return taken argument */
1934 			argn--;
1935 			break;
1936 		}
1937 	}
1938 
1939 	return argn;
1940 }
1941 
parse_config_meta_args(const struct shell * sh,size_t argn,size_t argc,char * argv[],struct bt_audio_codec_cfg * codec_cfg)1942 static ssize_t parse_config_meta_args(const struct shell *sh, size_t argn, size_t argc,
1943 				      char *argv[], struct bt_audio_codec_cfg *codec_cfg)
1944 {
1945 	for (; argn < argc; argn++) {
1946 		const char *arg = argv[argn];
1947 		unsigned long val;
1948 		int err = 0;
1949 
1950 		if (strcmp(arg, "pref_ctx") == 0) {
1951 			if (++argn == argc) {
1952 				shell_help(sh);
1953 
1954 				return -1;
1955 			}
1956 
1957 			arg = argv[argn];
1958 
1959 			val = shell_strtoul(arg, 0, &err);
1960 			if (err != 0) {
1961 				shell_error(sh, "Failed to parse pref ctx from %s: %d", arg, err);
1962 
1963 				return -1;
1964 			}
1965 
1966 			if (val > UINT16_MAX) {
1967 				shell_error(sh, "Invalid pref ctx value: %lu", val);
1968 
1969 				return -1;
1970 			}
1971 
1972 			err = bt_audio_codec_cfg_meta_set_pref_context(codec_cfg,
1973 								       (enum bt_audio_context)val);
1974 			if (err < 0) {
1975 				shell_error(sh, "Failed to set pref ctx with value %lu: %d", val,
1976 					    err);
1977 
1978 				return -1;
1979 			}
1980 		} else if (strcmp(arg, "stream_ctx") == 0) {
1981 			if (++argn == argc) {
1982 				shell_help(sh);
1983 
1984 				return -1;
1985 			}
1986 
1987 			arg = argv[argn];
1988 
1989 			val = shell_strtoul(arg, 0, &err);
1990 			if (err != 0) {
1991 				shell_error(sh, "Failed to parse stream ctx from %s: %d", arg, err);
1992 
1993 				return -1;
1994 			}
1995 
1996 			if (val > UINT16_MAX) {
1997 				shell_error(sh, "Invalid stream ctx value: %lu", val);
1998 
1999 				return -1;
2000 			}
2001 
2002 			err = bt_audio_codec_cfg_meta_set_stream_context(
2003 				codec_cfg, (enum bt_audio_context)val);
2004 			if (err < 0) {
2005 				shell_error(sh, "Failed to set stream ctx with value %lu: %d", val,
2006 					    err);
2007 
2008 				return -1;
2009 			}
2010 		} else if (strcmp(arg, "program_info") == 0) {
2011 			if (++argn == argc) {
2012 				shell_help(sh);
2013 
2014 				return -1;
2015 			}
2016 
2017 			arg = argv[argn];
2018 
2019 			err = bt_audio_codec_cfg_meta_set_program_info(codec_cfg, arg, strlen(arg));
2020 			if (err != 0) {
2021 				shell_error(sh, "Failed to set program info with value %s: %d", arg,
2022 					    err);
2023 
2024 				return -1;
2025 			}
2026 		} else if (strcmp(arg, "lang") == 0) {
2027 			if (++argn == argc) {
2028 				shell_help(sh);
2029 
2030 				return -1;
2031 			}
2032 
2033 			arg = argv[argn];
2034 
2035 			if (strlen(arg) != BT_AUDIO_LANG_SIZE) {
2036 				shell_error(sh, "Failed to parse lang from %s", arg);
2037 
2038 				return -1;
2039 			}
2040 
2041 			err = bt_audio_codec_cfg_meta_set_lang(codec_cfg, arg);
2042 			if (err < 0) {
2043 				shell_error(sh, "Failed to set lang with value %s: %d", arg, err);
2044 
2045 				return -1;
2046 			}
2047 		} else if (strcmp(arg, "ccid_list") == 0) {
2048 			uint8_t ccid_list[CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE];
2049 			size_t ccid_list_len;
2050 
2051 			if (++argn == argc) {
2052 				shell_help(sh);
2053 
2054 				return -1;
2055 			}
2056 
2057 			arg = argv[argn];
2058 
2059 			ccid_list_len = hex2bin(arg, strlen(arg), ccid_list, sizeof(ccid_list));
2060 			if (ccid_list_len == 0) {
2061 				shell_error(sh, "Failed to parse ccid list from %s", arg);
2062 
2063 				return -1;
2064 			}
2065 
2066 			err = bt_audio_codec_cfg_meta_set_ccid_list(codec_cfg, ccid_list,
2067 								    ccid_list_len);
2068 			if (err < 0) {
2069 				shell_error(sh, "Failed to set ccid list with value %s: %d", arg,
2070 					    err);
2071 
2072 				return -1;
2073 			}
2074 		} else if (strcmp(arg, "parental_rating") == 0) {
2075 			if (++argn == argc) {
2076 				shell_help(sh);
2077 
2078 				return -1;
2079 			}
2080 
2081 			arg = argv[argn];
2082 
2083 			val = shell_strtoul(arg, 0, &err);
2084 			if (err != 0) {
2085 				shell_error(sh, "Failed to parse parental rating from %s: %d", arg,
2086 					    err);
2087 
2088 				return -1;
2089 			}
2090 
2091 			if (val > UINT8_MAX) {
2092 				shell_error(sh, "Invalid parental rating value: %lu", val);
2093 
2094 				return -1;
2095 			}
2096 
2097 			err = bt_audio_codec_cfg_meta_set_parental_rating(
2098 				codec_cfg, (enum bt_audio_parental_rating)val);
2099 			if (err < 0) {
2100 				shell_error(sh, "Failed to set parental rating with value %lu: %d",
2101 					    val, err);
2102 
2103 				return -1;
2104 			}
2105 		} else if (strcmp(arg, "program_info_uri") == 0) {
2106 			if (++argn == argc) {
2107 				shell_help(sh);
2108 
2109 				return -1;
2110 			}
2111 
2112 			arg = argv[argn];
2113 
2114 			err = bt_audio_codec_cfg_meta_set_program_info_uri(codec_cfg, arg,
2115 									   strlen(arg));
2116 			if (err < 0) {
2117 				shell_error(sh, "Failed to set program info URI with value %s: %d",
2118 					    arg, err);
2119 
2120 				return -1;
2121 			}
2122 		} else if (strcmp(arg, "audio_active_state") == 0) {
2123 			if (++argn == argc) {
2124 				shell_help(sh);
2125 
2126 				return -1;
2127 			}
2128 
2129 			arg = argv[argn];
2130 
2131 			val = shell_strtoul(arg, 0, &err);
2132 			if (err != 0) {
2133 				shell_error(sh, "Failed to parse audio active state from %s: %d",
2134 					    arg, err);
2135 
2136 				return -1;
2137 			}
2138 
2139 			if (val > UINT8_MAX) {
2140 				shell_error(sh, "Invalid audio active state value: %lu", val);
2141 
2142 				return -1;
2143 			}
2144 
2145 			err = bt_audio_codec_cfg_meta_set_audio_active_state(
2146 				codec_cfg, (enum bt_audio_active_state)val);
2147 			if (err < 0) {
2148 				shell_error(sh,
2149 					    "Failed to set audio active state with value %lu: %d",
2150 					    val, err);
2151 
2152 				return -1;
2153 			}
2154 		} else if (strcmp(arg, "bcast_flag") == 0) {
2155 			err = bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag(
2156 				codec_cfg);
2157 			if (err < 0) {
2158 				shell_error(sh, "Failed to set audio active state: %d", err);
2159 
2160 				return -1;
2161 			}
2162 		} else if (strcmp(arg, "extended") == 0) {
2163 			uint8_t extended[CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE];
2164 			size_t extended_len;
2165 
2166 			if (++argn == argc) {
2167 				shell_help(sh);
2168 
2169 				return -1;
2170 			}
2171 
2172 			arg = argv[argn];
2173 
2174 			extended_len = hex2bin(arg, strlen(arg), extended, sizeof(extended));
2175 			if (extended_len == 0) {
2176 				shell_error(sh, "Failed to parse extended meta from %s", arg);
2177 
2178 				return -1;
2179 			}
2180 
2181 			err = bt_audio_codec_cfg_meta_set_extended(codec_cfg, extended,
2182 								   extended_len);
2183 			if (err < 0) {
2184 				shell_error(sh, "Failed to set extended meta with value %s: %d",
2185 					    arg, err);
2186 
2187 				return -1;
2188 			}
2189 		} else if (strcmp(arg, "vendor") == 0) {
2190 			uint8_t vendor[CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE];
2191 			size_t vendor_len;
2192 
2193 			if (++argn == argc) {
2194 				shell_help(sh);
2195 
2196 				return -1;
2197 			}
2198 
2199 			arg = argv[argn];
2200 
2201 			vendor_len = hex2bin(arg, strlen(arg), vendor, sizeof(vendor));
2202 			if (vendor_len == 0) {
2203 				shell_error(sh, "Failed to parse vendor meta from %s", arg);
2204 
2205 				return -1;
2206 			}
2207 
2208 			err = bt_audio_codec_cfg_meta_set_vendor(codec_cfg, vendor, vendor_len);
2209 			if (err < 0) {
2210 				shell_error(sh, "Failed to set vendor meta with value %s: %d", arg,
2211 					    err);
2212 
2213 				return -1;
2214 			}
2215 		} else { /* we are no longer parsing codec config meta values */
2216 			/* Decrement to return taken argument */
2217 			argn--;
2218 			break;
2219 		}
2220 	}
2221 
2222 	return argn;
2223 }
2224 
cmd_preset(const struct shell * sh,size_t argc,char * argv[])2225 static int cmd_preset(const struct shell *sh, size_t argc, char *argv[])
2226 {
2227 	const struct named_lc3_preset *named_preset;
2228 	enum bt_audio_dir dir;
2229 	bool unicast = true;
2230 
2231 	if (!strcmp(argv[1], "sink")) {
2232 		dir = BT_AUDIO_DIR_SINK;
2233 		named_preset = &default_sink_preset;
2234 	} else if (!strcmp(argv[1], "source")) {
2235 		dir = BT_AUDIO_DIR_SOURCE;
2236 		named_preset = &default_source_preset;
2237 	} else if (!strcmp(argv[1], "broadcast")) {
2238 		unicast = false;
2239 		dir = BT_AUDIO_DIR_SOURCE;
2240 
2241 		named_preset = &default_broadcast_source_preset;
2242 	} else {
2243 		shell_error(sh, "Unsupported dir: %s", argv[1]);
2244 		return -ENOEXEC;
2245 	}
2246 
2247 	if (argc > 2) {
2248 		struct bt_audio_codec_cfg *codec_cfg;
2249 
2250 		named_preset = bap_get_named_preset(unicast, dir, argv[2]);
2251 		if (named_preset == NULL) {
2252 			shell_error(sh, "Unable to parse named_preset %s", argv[2]);
2253 			return -ENOEXEC;
2254 		}
2255 
2256 		if (!strcmp(argv[1], "sink")) {
2257 			named_preset = memcpy(&default_sink_preset, named_preset,
2258 					      sizeof(default_sink_preset));
2259 			codec_cfg = &default_sink_preset.preset.codec_cfg;
2260 		} else if (!strcmp(argv[1], "source")) {
2261 			named_preset = memcpy(&default_source_preset, named_preset,
2262 					      sizeof(default_sink_preset));
2263 			codec_cfg = &default_source_preset.preset.codec_cfg;
2264 		} else if (!strcmp(argv[1], "broadcast")) {
2265 			named_preset = memcpy(&default_broadcast_source_preset, named_preset,
2266 					      sizeof(default_sink_preset));
2267 			codec_cfg = &default_broadcast_source_preset.preset.codec_cfg;
2268 		} else {
2269 			shell_error(sh, "Invalid dir: %s", argv[1]);
2270 
2271 			return -ENOEXEC;
2272 		}
2273 
2274 		if (argc > 3) {
2275 			struct bt_audio_codec_cfg codec_cfg_backup;
2276 
2277 			memcpy(&codec_cfg_backup, codec_cfg, sizeof(codec_cfg_backup));
2278 
2279 			for (size_t argn = 3; argn < argc; argn++) {
2280 				const char *arg = argv[argn];
2281 
2282 				if (strcmp(arg, "config") == 0) {
2283 					ssize_t ret;
2284 
2285 					if (++argn == argc) {
2286 						shell_help(sh);
2287 
2288 						memcpy(codec_cfg, &codec_cfg_backup,
2289 						       sizeof(codec_cfg_backup));
2290 
2291 						return SHELL_CMD_HELP_PRINTED;
2292 					}
2293 
2294 					ret = parse_config_data_args(sh, argn, argc, argv,
2295 								     codec_cfg);
2296 					if (ret < 0) {
2297 						memcpy(codec_cfg, &codec_cfg_backup,
2298 						       sizeof(codec_cfg_backup));
2299 
2300 						return -ENOEXEC;
2301 					}
2302 
2303 					argn = ret;
2304 				} else if (strcmp(arg, "meta") == 0) {
2305 					ssize_t ret;
2306 
2307 					if (++argn == argc) {
2308 						shell_help(sh);
2309 
2310 						memcpy(codec_cfg, &codec_cfg_backup,
2311 						       sizeof(codec_cfg_backup));
2312 
2313 						return SHELL_CMD_HELP_PRINTED;
2314 					}
2315 
2316 					ret = parse_config_meta_args(sh, argn, argc, argv,
2317 								     codec_cfg);
2318 					if (ret < 0) {
2319 						memcpy(codec_cfg, &codec_cfg_backup,
2320 						       sizeof(codec_cfg_backup));
2321 
2322 						return -ENOEXEC;
2323 					}
2324 
2325 					argn = ret;
2326 				} else {
2327 					shell_error(sh, "Invalid argument: %s", arg);
2328 					shell_help(sh);
2329 
2330 					return -ENOEXEC;
2331 				}
2332 			}
2333 		}
2334 	}
2335 
2336 	shell_print(sh, "%s", named_preset->name);
2337 
2338 	print_codec_cfg(0, &named_preset->preset.codec_cfg);
2339 	print_qos(&named_preset->preset.qos);
2340 
2341 	return 0;
2342 }
2343 #endif /* IS_BAP_INITIATOR */
2344 
2345 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
2346 #define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */
2347 #define PA_SYNC_SKIP         5
2348 
2349 struct bt_broadcast_info {
2350 	uint32_t broadcast_id;
2351 	char broadcast_name[BT_AUDIO_BROADCAST_NAME_LEN_MAX + 1];
2352 };
2353 
2354 static struct broadcast_sink_auto_scan {
2355 	struct broadcast_sink *broadcast_sink;
2356 	struct bt_broadcast_info broadcast_info;
2357 	struct bt_le_per_adv_sync **out_sync;
2358 } auto_scan = {
2359 	.broadcast_info = {
2360 		.broadcast_id = BT_BAP_INVALID_BROADCAST_ID,
2361 	},
2362 };
2363 
clear_auto_scan(void)2364 static void clear_auto_scan(void)
2365 {
2366 	memset(&auto_scan, 0, sizeof(auto_scan));
2367 	auto_scan.broadcast_info.broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
2368 }
2369 
interval_to_sync_timeout(uint16_t interval)2370 static uint16_t interval_to_sync_timeout(uint16_t interval)
2371 {
2372 	uint32_t interval_us;
2373 	uint32_t timeout;
2374 
2375 	/* Add retries and convert to unit in 10's of ms */
2376 	interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(interval);
2377 	timeout =
2378 		BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
2379 
2380 	/* Enforce restraints */
2381 	timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
2382 
2383 	return (uint16_t)timeout;
2384 }
2385 
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)2386 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
2387 {
2388 	struct bt_broadcast_info *sr_info = (struct bt_broadcast_info *)user_data;
2389 	struct bt_uuid_16 adv_uuid;
2390 
2391 	switch (data->type) {
2392 	case BT_DATA_SVC_DATA16:
2393 		if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
2394 			return true;
2395 		}
2396 
2397 		if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
2398 			return true;
2399 		}
2400 
2401 		if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO) != 0) {
2402 			return true;
2403 		}
2404 
2405 		sr_info->broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
2406 		return true;
2407 	case BT_DATA_BROADCAST_NAME:
2408 		if (!IN_RANGE(data->data_len, BT_AUDIO_BROADCAST_NAME_LEN_MIN,
2409 			      BT_AUDIO_BROADCAST_NAME_LEN_MAX)) {
2410 			return false;
2411 		}
2412 
2413 		memcpy(sr_info->broadcast_name, data->data, data->data_len);
2414 		sr_info->broadcast_name[data->data_len] = '\0';
2415 		return true;
2416 	default:
2417 		return true;
2418 	}
2419 }
2420 
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)2421 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad)
2422 {
2423 	struct bt_broadcast_info sr_info = {0};
2424 	char addr_str[BT_ADDR_LE_STR_LEN];
2425 	bool identified_broadcast = false;
2426 
2427 	sr_info.broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
2428 
2429 	if ((auto_scan.broadcast_info.broadcast_id == BT_BAP_INVALID_BROADCAST_ID) &&
2430 	    (strlen(auto_scan.broadcast_info.broadcast_name) == 0U)) {
2431 		/* no op */
2432 		return;
2433 	}
2434 
2435 	if (!passes_scan_filter(info, ad)) {
2436 		return;
2437 	}
2438 
2439 	bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)&sr_info);
2440 
2441 	/* Verify that it is a BAP broadcaster*/
2442 	if (sr_info.broadcast_id == BT_BAP_INVALID_BROADCAST_ID) {
2443 		return;
2444 	}
2445 
2446 	bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str));
2447 
2448 	if (sr_info.broadcast_id == auto_scan.broadcast_info.broadcast_id) {
2449 		identified_broadcast = true;
2450 	} else if ((strlen(auto_scan.broadcast_info.broadcast_name) != 0U) &&
2451 		   is_substring(auto_scan.broadcast_info.broadcast_name, sr_info.broadcast_name)) {
2452 		auto_scan.broadcast_info.broadcast_id = sr_info.broadcast_id;
2453 		identified_broadcast = true;
2454 
2455 		bt_shell_print("Found matched broadcast name '%s' with address %s",
2456 			       sr_info.broadcast_name, addr_str);
2457 	}
2458 
2459 	if (identified_broadcast && (auto_scan.broadcast_sink != NULL) &&
2460 	    (auto_scan.broadcast_sink->pa_sync == NULL)) {
2461 		struct bt_le_per_adv_sync_param create_params = {0};
2462 		int err;
2463 
2464 		bt_shell_print(
2465 			"Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X ",
2466 			sr_info.broadcast_id, addr_str, info->sid);
2467 
2468 		err = bt_le_scan_stop();
2469 		if (err != 0) {
2470 			bt_shell_error("Could not stop scan: %d", err);
2471 		}
2472 
2473 		bt_addr_le_copy(&create_params.addr, info->addr);
2474 		create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE;
2475 		create_params.sid = info->sid;
2476 		create_params.skip = PA_SYNC_SKIP;
2477 		create_params.timeout = interval_to_sync_timeout(info->interval);
2478 
2479 		bt_shell_print("Attempting to PA sync to the broadcaster");
2480 		err = bt_le_per_adv_sync_create(&create_params, auto_scan.out_sync);
2481 		if (err != 0) {
2482 			bt_shell_error("Could not create Broadcast PA sync: %d", err);
2483 		} else {
2484 			auto_scan.broadcast_sink->pa_sync = *auto_scan.out_sync;
2485 		}
2486 	}
2487 }
2488 
base_recv(struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base,size_t base_size)2489 static void base_recv(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
2490 		      size_t base_size)
2491 {
2492 	/* Don't print duplicates */
2493 	if (base_size != default_broadcast_sink.base_size ||
2494 	    memcmp(base, &default_broadcast_sink.received_base, base_size) != 0) {
2495 		bt_shell_print("Received BASE from sink %p:", sink);
2496 		(void)memcpy(&default_broadcast_sink.received_base, base, base_size);
2497 		default_broadcast_sink.base_size = base_size;
2498 
2499 		print_base(base);
2500 	}
2501 }
2502 
syncable(struct bt_bap_broadcast_sink * sink,const struct bt_iso_biginfo * biginfo)2503 static void syncable(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo)
2504 {
2505 	if (default_broadcast_sink.bap_sink == sink) {
2506 		if (default_broadcast_sink.syncable) {
2507 			return;
2508 		}
2509 
2510 		bt_shell_print("Sink %p is ready to sync %s encryption", sink,
2511 			       biginfo->encryption ? "with" : "without");
2512 		default_broadcast_sink.syncable = true;
2513 	}
2514 }
2515 
bap_pa_sync_synced_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)2516 static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
2517 				  struct bt_le_per_adv_sync_synced_info *info)
2518 {
2519 	if (auto_scan.broadcast_sink != NULL && auto_scan.out_sync != NULL &&
2520 	    sync == *auto_scan.out_sync) {
2521 		bt_shell_print("PA synced to broadcast with broadcast ID 0x%06x",
2522 			       auto_scan.broadcast_info.broadcast_id);
2523 
2524 		if (auto_scan.broadcast_sink->bap_sink == NULL) {
2525 			bt_shell_print("Attempting to create the sink");
2526 			int err;
2527 
2528 			err = bt_bap_broadcast_sink_create(sync,
2529 							   auto_scan.broadcast_info.broadcast_id,
2530 							   &auto_scan.broadcast_sink->bap_sink);
2531 			if (err != 0) {
2532 				bt_shell_error("Could not create broadcast sink: %d", err);
2533 			}
2534 		} else {
2535 			bt_shell_print("Sink is already created");
2536 		}
2537 	}
2538 
2539 	clear_auto_scan();
2540 }
2541 
bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)2542 static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
2543 				      const struct bt_le_per_adv_sync_term_info *info)
2544 {
2545 	if (default_broadcast_sink.pa_sync == sync) {
2546 		default_broadcast_sink.syncable = false;
2547 		(void)memset(&default_broadcast_sink.received_base, 0,
2548 			     sizeof(default_broadcast_sink.received_base));
2549 	}
2550 
2551 	clear_auto_scan();
2552 }
2553 
broadcast_scan_timeout_cb(void)2554 static void broadcast_scan_timeout_cb(void)
2555 {
2556 	bt_shell_print("Scan timeout");
2557 
2558 	clear_auto_scan();
2559 }
2560 
2561 static struct bt_bap_broadcast_sink_cb sink_cbs = {
2562 	.base_recv = base_recv,
2563 	.syncable = syncable,
2564 };
2565 
2566 static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = {
2567 	.synced = bap_pa_sync_synced_cb,
2568 	.term = bap_pa_sync_terminated_cb,
2569 };
2570 
2571 static struct bt_le_scan_cb bap_scan_cb = {
2572 	.timeout = broadcast_scan_timeout_cb,
2573 	.recv = broadcast_scan_recv,
2574 };
2575 #endif /* CONFIG_BT_BAP_BROADCAST_SINK */
2576 
2577 #if defined(CONFIG_BT_AUDIO_RX)
2578 static size_t rx_streaming_cnt;
2579 
bap_get_rx_streaming_cnt(void)2580 size_t bap_get_rx_streaming_cnt(void)
2581 {
2582 	return rx_streaming_cnt;
2583 }
2584 
2585 #if defined(CONFIG_LIBLC3)
2586 struct lc3_data {
2587 	void *fifo_reserved; /* 1st word reserved for use by FIFO */
2588 	struct net_buf *buf;
2589 	struct shell_stream *sh_stream;
2590 	uint32_t ts;
2591 	bool do_plc;
2592 };
2593 
2594 K_MEM_SLAB_DEFINE(lc3_data_slab, sizeof(struct lc3_data), CONFIG_BT_ISO_RX_BUF_COUNT,
2595 		  __alignof__(struct lc3_data));
2596 
2597 static int16_t lc3_rx_buf[LC3_MAX_NUM_SAMPLES_MONO];
2598 static K_FIFO_DEFINE(lc3_in_fifo);
2599 
2600 /* We only want to send USB to left/right from a single stream. If we have 2 left streams, the
2601  * outgoing audio is going to be terrible.
2602  * Since a stream can contain stereo data, both of these may be the same stream.
2603  */
2604 static struct shell_stream *usb_left_stream;
2605 static struct shell_stream *usb_right_stream;
2606 
init_lc3_decoder(struct shell_stream * sh_stream)2607 static int init_lc3_decoder(struct shell_stream *sh_stream)
2608 {
2609 	if (sh_stream == NULL) {
2610 		bt_shell_error("NULL stream to init LC3 decoder");
2611 		return -EINVAL;
2612 	}
2613 
2614 	if (!sh_stream->is_rx) {
2615 		bt_shell_error("Invalid stream to init LC3 decoder");
2616 		return -EINVAL;
2617 	}
2618 
2619 	if (sh_stream->rx.lc3_decoder != NULL) {
2620 		bt_shell_error("Already initialized");
2621 		return -EALREADY;
2622 	}
2623 
2624 	if (sh_stream->lc3_freq_hz == 0 || sh_stream->lc3_frame_duration_us == 0) {
2625 		bt_shell_error("Invalid freq (%u) or frame duration (%u)",
2626 			       sh_stream->lc3_freq_hz, sh_stream->lc3_frame_duration_us);
2627 
2628 		return -EINVAL;
2629 	}
2630 
2631 	bt_shell_print("Initializing the LC3 decoder with %u us duration and %u Hz frequency",
2632 		       sh_stream->lc3_frame_duration_us, sh_stream->lc3_freq_hz);
2633 	/* Create the decoder instance. This shall complete before stream_started() is called. */
2634 	sh_stream->rx.lc3_decoder =
2635 		lc3_setup_decoder(sh_stream->lc3_frame_duration_us, sh_stream->lc3_freq_hz,
2636 				  IS_ENABLED(CONFIG_USB_DEVICE_AUDIO) ? USB_SAMPLE_RATE : 0,
2637 				  &sh_stream->rx.lc3_decoder_mem);
2638 	if (sh_stream->rx.lc3_decoder == NULL) {
2639 		bt_shell_error("Failed to setup LC3 decoder - wrong parameters?\n");
2640 		return -EINVAL;
2641 	}
2642 
2643 	return 0;
2644 }
2645 
decode_frame(struct lc3_data * data,size_t frame_cnt)2646 static bool decode_frame(struct lc3_data *data, size_t frame_cnt)
2647 {
2648 	const struct shell_stream *sh_stream = data->sh_stream;
2649 	const size_t total_frames = sh_stream->lc3_chan_cnt * sh_stream->lc3_frame_blocks_per_sdu;
2650 	const uint16_t octets_per_frame = sh_stream->lc3_octets_per_frame;
2651 	struct net_buf *buf = data->buf;
2652 	void *iso_data;
2653 	int err;
2654 
2655 	if (data->do_plc) {
2656 		iso_data = NULL; /* perform PLC */
2657 
2658 		if ((sh_stream->rx.decoded_cnt % bap_stats_interval) == 0) {
2659 			bt_shell_print("[%zu]: Performing PLC", sh_stream->rx.decoded_cnt);
2660 		}
2661 
2662 		data->do_plc = false; /* clear flag */
2663 	} else {
2664 		iso_data = net_buf_pull_mem(data->buf, octets_per_frame);
2665 
2666 		if ((sh_stream->rx.decoded_cnt % bap_stats_interval) == 0) {
2667 			bt_shell_print("[%zu]: Decoding frame of size %u (%u/%u)",
2668 				       sh_stream->rx.decoded_cnt, octets_per_frame, frame_cnt + 1,
2669 				       total_frames);
2670 		}
2671 	}
2672 
2673 	err = lc3_decode(sh_stream->rx.lc3_decoder, iso_data, octets_per_frame, LC3_PCM_FORMAT_S16,
2674 			 lc3_rx_buf, 1);
2675 	if (err < 0) {
2676 		bt_shell_error("Failed to decode LC3 data (%u/%u - %u/%u)", frame_cnt + 1,
2677 			       total_frames, octets_per_frame * frame_cnt, buf->len);
2678 		return false;
2679 	}
2680 
2681 	return true;
2682 }
2683 
decode_frame_block(struct lc3_data * data,size_t frame_cnt)2684 static size_t decode_frame_block(struct lc3_data *data, size_t frame_cnt)
2685 {
2686 	const struct shell_stream *sh_stream = data->sh_stream;
2687 	const uint8_t chan_cnt = sh_stream->lc3_chan_cnt;
2688 	size_t decoded_frames = 0U;
2689 
2690 	for (uint8_t i = 0U; i < chan_cnt; i++) {
2691 		/* We provide the total number of decoded frames to `decode_frame` for logging
2692 		 * purposes
2693 		 */
2694 		if (decode_frame(data, frame_cnt + decoded_frames)) {
2695 			decoded_frames++;
2696 
2697 			if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
2698 				enum bt_audio_location chan_alloc;
2699 				int err;
2700 
2701 				err = get_lc3_chan_alloc_from_index(sh_stream, i, &chan_alloc);
2702 				if (err != 0) {
2703 					/* Not suitable for USB */
2704 					continue;
2705 				}
2706 
2707 				/* We only want to left or right from one stream to USB */
2708 				if ((chan_alloc == BT_AUDIO_LOCATION_FRONT_LEFT &&
2709 				     sh_stream != usb_left_stream) ||
2710 				    (chan_alloc == BT_AUDIO_LOCATION_FRONT_RIGHT &&
2711 				     sh_stream != usb_right_stream)) {
2712 					continue;
2713 				}
2714 
2715 				err = bap_usb_add_frame_to_usb(chan_alloc, lc3_rx_buf,
2716 							       sizeof(lc3_rx_buf), data->ts);
2717 				if (err == -EINVAL) {
2718 					continue;
2719 				}
2720 			}
2721 		} else {
2722 			/* If decoding failed, we clear the data to USB as it would contain
2723 			 * invalid data
2724 			 */
2725 			if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
2726 				bap_usb_clear_frames_to_usb();
2727 			}
2728 
2729 			break;
2730 		}
2731 	}
2732 
2733 	return decoded_frames;
2734 }
2735 
do_lc3_decode(struct lc3_data * data)2736 static void do_lc3_decode(struct lc3_data *data)
2737 {
2738 	struct shell_stream *sh_stream = data->sh_stream;
2739 
2740 	if (sh_stream->is_rx && sh_stream->rx.lc3_decoder != NULL) {
2741 		const uint8_t frame_blocks_per_sdu = sh_stream->lc3_frame_blocks_per_sdu;
2742 		size_t frame_cnt;
2743 
2744 		frame_cnt = 0;
2745 		for (uint8_t i = 0U; i < frame_blocks_per_sdu; i++) {
2746 			const size_t decoded_frames = decode_frame_block(data, frame_cnt);
2747 
2748 			if (decoded_frames == 0) {
2749 				break;
2750 			}
2751 
2752 			frame_cnt += decoded_frames;
2753 		}
2754 
2755 		sh_stream->rx.decoded_cnt++;
2756 	}
2757 
2758 	net_buf_unref(data->buf);
2759 }
2760 
lc3_decoder_thread_func(void * arg1,void * arg2,void * arg3)2761 static void lc3_decoder_thread_func(void *arg1, void *arg2, void *arg3)
2762 {
2763 	while (true) {
2764 		struct lc3_data *data = k_fifo_get(&lc3_in_fifo, K_FOREVER);
2765 		struct shell_stream *sh_stream = data->sh_stream;
2766 
2767 		if (sh_stream->is_rx && sh_stream->rx.lc3_decoder == NULL) {
2768 			bt_shell_warn("Decoder is NULL, discarding data from FIFO");
2769 			k_mem_slab_free(&lc3_data_slab, (void *)data);
2770 			continue; /* Wait for new data */
2771 		}
2772 
2773 		do_lc3_decode(data);
2774 
2775 		k_mem_slab_free(&lc3_data_slab, (void *)data);
2776 	}
2777 }
2778 
2779 #endif /* CONFIG_LIBLC3*/
2780 
audio_recv(struct bt_bap_stream * stream,const struct bt_iso_recv_info * info,struct net_buf * buf)2781 static void audio_recv(struct bt_bap_stream *stream,
2782 		       const struct bt_iso_recv_info *info,
2783 		       struct net_buf *buf)
2784 {
2785 	struct shell_stream *sh_stream = shell_stream_from_bap_stream(stream);
2786 
2787 	if (!sh_stream->is_rx) {
2788 		return;
2789 	}
2790 
2791 	sh_stream->rx.rx_cnt++;
2792 
2793 	if (info->ts == sh_stream->rx.last_info.ts) {
2794 		sh_stream->rx.dup_ts++;
2795 	}
2796 
2797 	if (info->seq_num == sh_stream->rx.last_info.seq_num) {
2798 		sh_stream->rx.dup_psn++;
2799 	}
2800 
2801 	if ((info->flags & BT_ISO_FLAGS_VALID) != 0) {
2802 		if (buf->len == 0U) {
2803 			sh_stream->rx.empty_sdu_pkts++;
2804 		} else {
2805 			sh_stream->rx.valid_sdu_pkts++;
2806 		}
2807 	}
2808 
2809 	if (info->flags & BT_ISO_FLAGS_ERROR) {
2810 		sh_stream->rx.err_pkts++;
2811 	}
2812 
2813 	if (info->flags & BT_ISO_FLAGS_LOST) {
2814 		sh_stream->rx.lost_pkts++;
2815 	}
2816 
2817 	if ((sh_stream->rx.rx_cnt % bap_stats_interval) == 0) {
2818 		bt_shell_print(
2819 			"[%zu]: Incoming audio on stream %p len %u ts %u seq_num %u flags %u "
2820 			"(valid %zu, dup ts %zu, dup psn %zu, err_pkts %zu, lost_pkts %zu, "
2821 			"empty SDUs %zu)",
2822 			sh_stream->rx.rx_cnt, stream, buf->len, info->ts, info->seq_num,
2823 			info->flags, sh_stream->rx.valid_sdu_pkts, sh_stream->rx.dup_ts,
2824 			sh_stream->rx.dup_psn, sh_stream->rx.err_pkts, sh_stream->rx.lost_pkts,
2825 			sh_stream->rx.empty_sdu_pkts);
2826 	}
2827 
2828 	(void)memcpy(&sh_stream->rx.last_info, info, sizeof(sh_stream->rx.last_info));
2829 
2830 #if defined(CONFIG_LIBLC3)
2831 	if (sh_stream->rx.lc3_decoder != NULL) {
2832 		const uint8_t frame_blocks_per_sdu = sh_stream->lc3_frame_blocks_per_sdu;
2833 		const uint16_t octets_per_frame = sh_stream->lc3_octets_per_frame;
2834 		const uint8_t chan_cnt = sh_stream->lc3_chan_cnt;
2835 		struct lc3_data *data;
2836 
2837 		/* Allocate a context that holds both the buffer and the stream so that we can
2838 		 * send both of these values to the LC3 decoder thread as a single struct
2839 		 * in a FIFO
2840 		 */
2841 		if (k_mem_slab_alloc(&lc3_data_slab, (void **)&data, K_NO_WAIT)) {
2842 			bt_shell_warn("Could not allocate LC3 data item");
2843 
2844 			return;
2845 		}
2846 
2847 		if ((info->flags & BT_ISO_FLAGS_VALID) == 0) {
2848 			data->do_plc = true;
2849 		} else if (buf->len != (octets_per_frame * chan_cnt * frame_blocks_per_sdu)) {
2850 			if (buf->len != 0U) {
2851 				bt_shell_error(
2852 					"Expected %u frame blocks with %u channels of size %u, but "
2853 					"length is %u",
2854 					frame_blocks_per_sdu, chan_cnt, octets_per_frame, buf->len);
2855 			}
2856 
2857 			data->do_plc = true;
2858 		}
2859 
2860 		data->buf = net_buf_ref(buf);
2861 		data->sh_stream = sh_stream;
2862 		if (info->flags & BT_ISO_FLAGS_TS) {
2863 			data->ts = info->ts;
2864 		} else {
2865 			data->ts = 0U;
2866 		}
2867 
2868 		k_fifo_put(&lc3_in_fifo, data);
2869 	}
2870 #endif /* CONFIG_LIBLC3 */
2871 }
2872 #endif /* CONFIG_BT_AUDIO_RX */
2873 
2874 #if defined(CONFIG_BT_BAP_UNICAST)
stream_enabled_cb(struct bt_bap_stream * stream)2875 static void stream_enabled_cb(struct bt_bap_stream *stream)
2876 {
2877 	bt_shell_print("Stream %p enabled", stream);
2878 
2879 	if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER)) {
2880 		struct bt_bap_ep_info ep_info;
2881 		struct bt_conn_info conn_info;
2882 		int err;
2883 
2884 		err = bt_conn_get_info(stream->conn, &conn_info);
2885 		if (err != 0) {
2886 			bt_shell_error("Failed to get conn info: %d", err);
2887 			return;
2888 		}
2889 
2890 		if (conn_info.role == BT_CONN_ROLE_CENTRAL) {
2891 			return; /* We also want to autonomously start the stream as the server */
2892 		}
2893 
2894 		err = bt_bap_ep_get_info(stream->ep, &ep_info);
2895 		if (err != 0) {
2896 			bt_shell_error("Failed to get ep info: %d", err);
2897 			return;
2898 		}
2899 
2900 		if (ep_info.dir == BT_AUDIO_DIR_SINK) {
2901 			/* Automatically do the receiver start ready operation */
2902 			err = bt_bap_stream_start(stream);
2903 
2904 			if (err != 0) {
2905 				bt_shell_error("Failed to start stream: %d", err);
2906 				return;
2907 			}
2908 		}
2909 	}
2910 }
2911 #endif /* CONFIG_BT_BAP_UNICAST */
2912 
stream_started_cb(struct bt_bap_stream * bap_stream)2913 static void stream_started_cb(struct bt_bap_stream *bap_stream)
2914 {
2915 	struct shell_stream *sh_stream = shell_stream_from_bap_stream(bap_stream);
2916 	struct bt_bap_ep_info info = {0};
2917 	int ret;
2918 
2919 	printk("Stream %p started\n", bap_stream);
2920 
2921 	ret = bt_bap_ep_get_info(bap_stream->ep, &info);
2922 	if (ret != 0) {
2923 		bt_shell_error("Failed to get EP info: %d", ret);
2924 		return;
2925 	}
2926 
2927 	sh_stream->is_rx = info.can_recv;
2928 	sh_stream->is_tx = info.can_send;
2929 
2930 #if defined(CONFIG_LIBLC3)
2931 	const struct bt_audio_codec_cfg *codec_cfg = bap_stream->codec_cfg;
2932 
2933 	if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
2934 		if (sh_stream->is_tx) {
2935 			atomic_set(&sh_stream->tx.lc3_enqueue_cnt, PRIME_COUNT);
2936 			sh_stream->tx.lc3_sdu_cnt = 0U;
2937 		}
2938 
2939 		ret = bt_audio_codec_cfg_get_freq(codec_cfg);
2940 		if (ret >= 0) {
2941 			ret = bt_audio_codec_cfg_freq_to_freq_hz(ret);
2942 
2943 			if (ret > 0) {
2944 				if (ret == 8000 || ret == 16000 || ret == 24000 || ret == 32000 ||
2945 				    ret == 48000) {
2946 					sh_stream->lc3_freq_hz = (uint32_t)ret;
2947 				} else {
2948 					bt_shell_error("Unsupported frequency for LC3: %d", ret);
2949 					sh_stream->lc3_freq_hz = 0U;
2950 				}
2951 			} else {
2952 				bt_shell_error("Invalid frequency: %d", ret);
2953 				sh_stream->lc3_freq_hz = 0U;
2954 			}
2955 		} else {
2956 			bt_shell_error("Could not get frequency: %d", ret);
2957 			sh_stream->lc3_freq_hz = 0U;
2958 		}
2959 
2960 		ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
2961 		if (ret >= 0) {
2962 			ret = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret);
2963 			if (ret > 0) {
2964 				sh_stream->lc3_frame_duration_us = (uint32_t)ret;
2965 			} else {
2966 				bt_shell_error("Invalid frame duration: %d", ret);
2967 				sh_stream->lc3_frame_duration_us = 0U;
2968 			}
2969 		} else {
2970 			bt_shell_error("Could not get frame duration: %d", ret);
2971 			sh_stream->lc3_frame_duration_us = 0U;
2972 		}
2973 
2974 		ret = bt_audio_codec_cfg_get_chan_allocation(
2975 			codec_cfg, &sh_stream->lc3_chan_allocation, false);
2976 		if (ret == 0) {
2977 			sh_stream->lc3_chan_cnt =
2978 				bt_audio_get_chan_count(sh_stream->lc3_chan_allocation);
2979 		} else {
2980 			bt_shell_error("Could not get channel allocation: %d", ret);
2981 			sh_stream->lc3_chan_allocation = BT_AUDIO_LOCATION_MONO_AUDIO;
2982 			sh_stream->lc3_chan_cnt = 1U;
2983 		}
2984 
2985 		ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true);
2986 		if (ret >= 0) {
2987 			sh_stream->lc3_frame_blocks_per_sdu = (uint8_t)ret;
2988 		} else {
2989 			bt_shell_error("Could not get frame blocks per SDU: %d", ret);
2990 			sh_stream->lc3_frame_blocks_per_sdu = 0U;
2991 		}
2992 
2993 		ret = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg);
2994 		if (ret >= 0) {
2995 			sh_stream->lc3_octets_per_frame = (uint16_t)ret;
2996 		} else {
2997 			bt_shell_error("Could not get octets per frame: %d", ret);
2998 			sh_stream->lc3_octets_per_frame = 0U;
2999 		}
3000 
3001 #if defined(CONFIG_BT_AUDIO_TX)
3002 		if (sh_stream->is_tx && sh_stream->tx.lc3_encoder == NULL) {
3003 			const int err = init_lc3_encoder(sh_stream);
3004 
3005 			if (err != 0) {
3006 				bt_shell_error("Failed to init LC3 encoder: %d", err);
3007 
3008 				return;
3009 			}
3010 
3011 			if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
3012 				/* Always mark as active when using USB */
3013 				sh_stream->tx.active = true;
3014 			}
3015 		}
3016 #endif /* CONFIG_BT_AUDIO_TX */
3017 
3018 #if defined(CONFIG_BT_AUDIO_RX)
3019 		if (sh_stream->is_rx) {
3020 			if (sh_stream->rx.lc3_decoder == NULL) {
3021 				const int err = init_lc3_decoder(sh_stream);
3022 
3023 				if (err != 0) {
3024 					bt_shell_error("Failed to init LC3 decoder: %d", err);
3025 
3026 					return;
3027 				}
3028 			}
3029 
3030 			sh_stream->rx.decoded_cnt = 0U;
3031 
3032 			if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
3033 				if ((sh_stream->lc3_chan_allocation &
3034 				     BT_AUDIO_LOCATION_FRONT_LEFT) != 0) {
3035 					if (usb_left_stream == NULL) {
3036 						bt_shell_info("Setting USB left stream to %p",
3037 							      sh_stream);
3038 						usb_left_stream = sh_stream;
3039 					} else {
3040 						bt_shell_warn("Multiple left streams started");
3041 					}
3042 				}
3043 
3044 				if ((sh_stream->lc3_chan_allocation &
3045 				     BT_AUDIO_LOCATION_FRONT_RIGHT) != 0) {
3046 					if (usb_right_stream == NULL) {
3047 						bt_shell_info("Setting USB right stream to %p",
3048 							      sh_stream);
3049 						usb_right_stream = sh_stream;
3050 					} else {
3051 						bt_shell_warn("Multiple right streams started");
3052 					}
3053 				}
3054 			}
3055 		}
3056 #endif /* CONFIG_BT_AUDIO_RX */
3057 	}
3058 #endif /* CONFIG_LIBLC3 */
3059 
3060 #if defined(CONFIG_BT_AUDIO_TX)
3061 	if (sh_stream->is_tx) {
3062 		sh_stream->tx.connected_at_ticks = k_uptime_ticks();
3063 	}
3064 #endif /* CONFIG_BT_AUDIO_TX */
3065 
3066 #if defined(CONFIG_BT_AUDIO_RX)
3067 	if (sh_stream->is_rx) {
3068 		sh_stream->rx.empty_sdu_pkts = 0U;
3069 		sh_stream->rx.valid_sdu_pkts = 0U;
3070 		sh_stream->rx.lost_pkts = 0U;
3071 		sh_stream->rx.err_pkts = 0U;
3072 		sh_stream->rx.dup_psn = 0U;
3073 		sh_stream->rx.rx_cnt = 0U;
3074 		sh_stream->rx.dup_ts = 0U;
3075 
3076 		rx_streaming_cnt++;
3077 	}
3078 #endif
3079 }
3080 
3081 #if defined(CONFIG_LIBLC3)
update_usb_streams_cb(struct shell_stream * sh_stream,void * user_data)3082 static void update_usb_streams_cb(struct shell_stream *sh_stream, void *user_data)
3083 {
3084 	if (sh_stream->is_rx) {
3085 		if (usb_left_stream == NULL &&
3086 		    (sh_stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0) {
3087 			bt_shell_info("Setting new USB left stream to %p", sh_stream);
3088 			usb_left_stream = sh_stream;
3089 		}
3090 
3091 		if (usb_right_stream == NULL &&
3092 		    (sh_stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0) {
3093 			bt_shell_info("Setting new USB right stream to %p", sh_stream);
3094 			usb_right_stream = sh_stream;
3095 		}
3096 	}
3097 }
3098 
update_usb_streams(struct shell_stream * sh_stream)3099 static void update_usb_streams(struct shell_stream *sh_stream)
3100 {
3101 	if (sh_stream->is_rx) {
3102 		if (sh_stream == usb_left_stream) {
3103 			bt_shell_info("Clearing USB left stream (%p)", usb_left_stream);
3104 			usb_left_stream = NULL;
3105 		}
3106 
3107 		if (sh_stream == usb_right_stream) {
3108 			bt_shell_info("Clearing USB right stream (%p)", usb_right_stream);
3109 			usb_right_stream = NULL;
3110 		}
3111 
3112 		bap_foreach_stream(update_usb_streams_cb, NULL);
3113 	}
3114 }
3115 #endif /* CONFIG_LIBLC3 */
3116 
clear_stream_data(struct shell_stream * sh_stream)3117 static void clear_stream_data(struct shell_stream *sh_stream)
3118 {
3119 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
3120 	if (IS_ARRAY_ELEMENT(broadcast_sink_streams, sh_stream)) {
3121 		if (default_broadcast_sink.stream_cnt != 0) {
3122 			default_broadcast_sink.stream_cnt--;
3123 		}
3124 
3125 		if (default_broadcast_sink.stream_cnt == 0) {
3126 			/* All streams in the broadcast sink has been terminated */
3127 			memset(&default_broadcast_sink.received_base, 0,
3128 			       sizeof(default_broadcast_sink.received_base));
3129 			default_broadcast_sink.broadcast_id = 0;
3130 			default_broadcast_sink.syncable = false;
3131 		}
3132 	}
3133 #endif /* CONFIG_BT_BAP_BROADCAST_SINK */
3134 
3135 #if defined(CONFIG_BT_AUDIO_RX)
3136 	if (sh_stream->is_rx) {
3137 		rx_streaming_cnt--;
3138 		memset(&sh_stream->rx, 0, sizeof(sh_stream->rx));
3139 	}
3140 #endif
3141 
3142 #if defined(CONFIG_BT_AUDIO_TX)
3143 	if (sh_stream->is_tx) {
3144 		memset(&sh_stream->tx, 0, sizeof(sh_stream->tx));
3145 	}
3146 #endif
3147 
3148 	sh_stream->is_rx = sh_stream->is_tx = false;
3149 
3150 #if defined(CONFIG_LIBLC3)
3151 	if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
3152 		update_usb_streams(sh_stream);
3153 	}
3154 #endif /* CONFIG_LIBLC3 */
3155 }
3156 
stream_stopped_cb(struct bt_bap_stream * stream,uint8_t reason)3157 static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
3158 {
3159 	struct shell_stream *sh_stream = shell_stream_from_bap_stream(stream);
3160 
3161 	printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
3162 
3163 	clear_stream_data(sh_stream);
3164 }
3165 
3166 #if defined(CONFIG_BT_BAP_UNICAST)
stream_configured_cb(struct bt_bap_stream * stream,const struct bt_bap_qos_cfg_pref * pref)3167 static void stream_configured_cb(struct bt_bap_stream *stream,
3168 				 const struct bt_bap_qos_cfg_pref *pref)
3169 {
3170 	bt_shell_print("Stream %p configured\n", stream);
3171 }
3172 
stream_released_cb(struct bt_bap_stream * stream)3173 static void stream_released_cb(struct bt_bap_stream *stream)
3174 {
3175 	struct shell_stream *sh_stream = shell_stream_from_bap_stream(stream);
3176 
3177 	bt_shell_print("Stream %p released\n", stream);
3178 
3179 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
3180 	if (default_unicast_group != NULL) {
3181 		bool group_can_be_deleted = true;
3182 
3183 		for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
3184 			const struct bt_bap_stream *bap_stream =
3185 				bap_stream_from_shell_stream(&unicast_streams[i]);
3186 
3187 			if (bap_stream->ep != NULL) {
3188 				struct bt_bap_ep_info ep_info;
3189 				int err;
3190 
3191 				err = bt_bap_ep_get_info(bap_stream->ep, &ep_info);
3192 				if (err == 0 && ep_info.state != BT_BAP_EP_STATE_CODEC_CONFIGURED &&
3193 				    ep_info.state != BT_BAP_EP_STATE_IDLE) {
3194 					group_can_be_deleted = false;
3195 					break;
3196 				}
3197 			}
3198 		}
3199 
3200 		if (group_can_be_deleted) {
3201 			int err;
3202 
3203 			bt_shell_print("All streams released, deleting group\n");
3204 
3205 			err = bt_bap_unicast_group_delete(default_unicast_group);
3206 
3207 			if (err != 0) {
3208 				bt_shell_error("Failed to delete unicast group: %d", err);
3209 			} else {
3210 				default_unicast_group = NULL;
3211 			}
3212 		}
3213 	}
3214 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
3215 
3216 	clear_stream_data(sh_stream);
3217 }
3218 #endif /* CONFIG_BT_BAP_UNICAST */
3219 
3220 static struct bt_bap_stream_ops stream_ops = {
3221 #if defined(CONFIG_BT_AUDIO_RX)
3222 	.recv = audio_recv,
3223 #endif /* CONFIG_BT_AUDIO_RX */
3224 #if defined(CONFIG_BT_BAP_UNICAST)
3225 	.configured = stream_configured_cb,
3226 	.released = stream_released_cb,
3227 	.enabled = stream_enabled_cb,
3228 #endif /* CONFIG_BT_BAP_UNICAST */
3229 	.started = stream_started_cb,
3230 	.stopped = stream_stopped_cb,
3231 #if defined(CONFIG_LIBLC3) && defined(CONFIG_BT_AUDIO_TX)
3232 	.sent = lc3_sent_cb,
3233 #endif
3234 };
3235 
3236 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
cmd_select_broadcast_source(const struct shell * sh,size_t argc,char * argv[])3237 static int cmd_select_broadcast_source(const struct shell *sh, size_t argc,
3238 				       char *argv[])
3239 {
3240 	unsigned long index;
3241 	int err = 0;
3242 
3243 	index = shell_strtoul(argv[1], 0, &err);
3244 	if (err != 0) {
3245 		shell_error(sh, "Could not parse index: %d", err);
3246 
3247 		return -ENOEXEC;
3248 	}
3249 
3250 	if (index > ARRAY_SIZE(broadcast_source_streams)) {
3251 		shell_error(sh, "Invalid index: %lu", index);
3252 
3253 		return -ENOEXEC;
3254 	}
3255 
3256 	default_stream = bap_stream_from_shell_stream(&broadcast_source_streams[index]);
3257 
3258 	return 0;
3259 }
3260 
cmd_create_broadcast(const struct shell * sh,size_t argc,char * argv[])3261 static int cmd_create_broadcast(const struct shell *sh, size_t argc,
3262 				char *argv[])
3263 {
3264 	struct bt_bap_broadcast_source_stream_param
3265 		stream_params[ARRAY_SIZE(broadcast_source_streams)];
3266 	struct bt_bap_broadcast_source_subgroup_param subgroup_param;
3267 	struct bt_bap_broadcast_source_param create_param = {0};
3268 	const struct named_lc3_preset *named_preset;
3269 	int err;
3270 
3271 	if (default_source.bap_source != NULL) {
3272 		shell_info(sh, "Broadcast source already created");
3273 		return -ENOEXEC;
3274 	}
3275 
3276 	named_preset = &default_broadcast_source_preset;
3277 
3278 	for (size_t i = 1U; i < argc; i++) {
3279 		char *arg = argv[i];
3280 
3281 		if (strcmp(arg, "enc") == 0) {
3282 			if (argc > i) {
3283 				size_t bcode_len;
3284 
3285 				i++;
3286 				arg = argv[i];
3287 
3288 				bcode_len = hex2bin(arg, strlen(arg),
3289 						    create_param.broadcast_code,
3290 						    sizeof(create_param.broadcast_code));
3291 
3292 				if (bcode_len != sizeof(create_param.broadcast_code)) {
3293 					shell_error(sh, "Invalid Broadcast Code Length: %zu",
3294 						    bcode_len);
3295 
3296 					return -ENOEXEC;
3297 				}
3298 
3299 				create_param.encryption = true;
3300 			} else {
3301 				shell_help(sh);
3302 
3303 				return SHELL_CMD_HELP_PRINTED;
3304 			}
3305 		} else if (strcmp(arg, "preset") == 0) {
3306 			if (argc > i) {
3307 
3308 				i++;
3309 				arg = argv[i];
3310 
3311 				named_preset = bap_get_named_preset(false, BT_AUDIO_DIR_SOURCE,
3312 								    arg);
3313 				if (named_preset == NULL) {
3314 					shell_error(sh, "Unable to parse named_preset %s",
3315 						    arg);
3316 
3317 					return -ENOEXEC;
3318 				}
3319 			} else {
3320 				shell_help(sh);
3321 
3322 				return SHELL_CMD_HELP_PRINTED;
3323 			}
3324 		}
3325 	}
3326 
3327 	copy_broadcast_source_preset(&default_source, named_preset);
3328 
3329 	(void)memset(stream_params, 0, sizeof(stream_params));
3330 	for (size_t i = 0; i < ARRAY_SIZE(stream_params); i++) {
3331 		stream_params[i].stream =
3332 			bap_stream_from_shell_stream(&broadcast_source_streams[i]);
3333 	}
3334 	subgroup_param.params_count = ARRAY_SIZE(stream_params);
3335 	subgroup_param.params = stream_params;
3336 	subgroup_param.codec_cfg = &default_source.codec_cfg;
3337 	create_param.params_count = 1U;
3338 	create_param.params = &subgroup_param;
3339 	create_param.qos = &default_source.qos;
3340 
3341 	err = bt_bap_broadcast_source_create(&create_param, &default_source.bap_source);
3342 	if (err != 0) {
3343 		shell_error(sh, "Unable to create broadcast source: %d", err);
3344 		return err;
3345 	}
3346 
3347 	shell_print(sh, "Broadcast source created: preset %s",
3348 		    named_preset->name);
3349 
3350 	if (default_stream == NULL) {
3351 		default_stream = bap_stream_from_shell_stream(&broadcast_source_streams[0]);
3352 	}
3353 
3354 	return 0;
3355 }
3356 
cmd_start_broadcast(const struct shell * sh,size_t argc,char * argv[])3357 static int cmd_start_broadcast(const struct shell *sh, size_t argc,
3358 			       char *argv[])
3359 {
3360 	struct bt_le_ext_adv *adv = adv_sets[selected_adv];
3361 	int err;
3362 
3363 	if (adv == NULL) {
3364 		shell_info(sh, "Extended advertising set is NULL");
3365 		return -ENOEXEC;
3366 	}
3367 
3368 	if (default_source.bap_source == NULL || default_source.is_cap) {
3369 		shell_info(sh, "Broadcast source not created");
3370 		return -ENOEXEC;
3371 	}
3372 
3373 	err = bt_bap_broadcast_source_start(default_source.bap_source, adv_sets[selected_adv]);
3374 	if (err != 0) {
3375 		shell_error(sh, "Unable to start broadcast source: %d", err);
3376 		return err;
3377 	}
3378 
3379 	return 0;
3380 }
3381 
cmd_stop_broadcast(const struct shell * sh,size_t argc,char * argv[])3382 static int cmd_stop_broadcast(const struct shell *sh, size_t argc, char *argv[])
3383 {
3384 	int err;
3385 
3386 	if (default_source.bap_source == NULL || default_source.is_cap) {
3387 		shell_info(sh, "Broadcast source not created");
3388 		return -ENOEXEC;
3389 	}
3390 
3391 	err = bt_bap_broadcast_source_stop(default_source.bap_source);
3392 	if (err != 0) {
3393 		shell_error(sh, "Unable to stop broadcast source: %d", err);
3394 		return err;
3395 	}
3396 
3397 	return 0;
3398 }
3399 
cmd_delete_broadcast(const struct shell * sh,size_t argc,char * argv[])3400 static int cmd_delete_broadcast(const struct shell *sh, size_t argc,
3401 				char *argv[])
3402 {
3403 	int err;
3404 
3405 	if (default_source.bap_source == NULL || default_source.is_cap) {
3406 		shell_info(sh, "Broadcast source not created");
3407 		return -ENOEXEC;
3408 	}
3409 
3410 	err = bt_bap_broadcast_source_delete(default_source.bap_source);
3411 	if (err != 0) {
3412 		shell_error(sh, "Unable to delete broadcast source: %d", err);
3413 		return err;
3414 	}
3415 	default_source.bap_source = NULL;
3416 
3417 	return 0;
3418 }
3419 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
3420 
3421 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
cmd_create_broadcast_sink(const struct shell * sh,size_t argc,char * argv[])3422 static int cmd_create_broadcast_sink(const struct shell *sh, size_t argc, char *argv[])
3423 {
3424 	struct bt_le_per_adv_sync *per_adv_sync = per_adv_syncs[selected_per_adv_sync];
3425 	unsigned long broadcast_id;
3426 	int err = 0;
3427 
3428 	broadcast_id = shell_strtoul(argv[1], 0, &err);
3429 	if (err != 0) {
3430 		shell_error(sh, "Could not parse broadcast_id: %d", err);
3431 
3432 		return -ENOEXEC;
3433 	}
3434 
3435 	if (broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) {
3436 		shell_error(sh, "Invalid broadcast_id: %lu", broadcast_id);
3437 
3438 		return -ENOEXEC;
3439 	}
3440 
3441 	if (per_adv_sync == NULL) {
3442 		const struct bt_le_scan_param param = {
3443 			.type = BT_LE_SCAN_TYPE_PASSIVE,
3444 			.options = BT_LE_SCAN_OPT_NONE,
3445 			.interval = BT_GAP_SCAN_FAST_INTERVAL,
3446 			.window = BT_GAP_SCAN_FAST_WINDOW,
3447 			.timeout = 1000, /* 10ms units -> 10 second timeout */
3448 		};
3449 
3450 		shell_print(sh, "No PA sync available, starting scanning for broadcast_id");
3451 
3452 		err = bt_le_scan_start(&param, NULL);
3453 		if (err) {
3454 			shell_print(sh, "Fail to start scanning: %d", err);
3455 
3456 			return -ENOEXEC;
3457 		}
3458 
3459 		auto_scan.broadcast_sink = &default_broadcast_sink;
3460 		auto_scan.broadcast_info.broadcast_id = broadcast_id;
3461 		auto_scan.out_sync = &per_adv_syncs[selected_per_adv_sync];
3462 	} else {
3463 		shell_print(sh, "Creating broadcast sink with broadcast ID 0x%06X",
3464 			    (uint32_t)broadcast_id);
3465 
3466 		err = bt_bap_broadcast_sink_create(per_adv_sync, (uint32_t)broadcast_id,
3467 						   &default_broadcast_sink.bap_sink);
3468 
3469 		if (err != 0) {
3470 			shell_error(sh, "Failed to create broadcast sink: %d", err);
3471 
3472 			return -ENOEXEC;
3473 		}
3474 	}
3475 
3476 	return 0;
3477 }
3478 
cmd_create_sink_by_name(const struct shell * sh,size_t argc,char * argv[])3479 static int cmd_create_sink_by_name(const struct shell *sh, size_t argc, char *argv[])
3480 {
3481 	const struct bt_le_scan_param param = {
3482 		.type = BT_LE_SCAN_TYPE_PASSIVE,
3483 		.options = BT_LE_SCAN_OPT_NONE,
3484 		.interval = BT_GAP_SCAN_FAST_INTERVAL,
3485 		.window = BT_GAP_SCAN_FAST_WINDOW,
3486 		.timeout = 1000, /* 10ms units -> 10 second timeout */
3487 	};
3488 	char *broadcast_name;
3489 	int err = 0;
3490 
3491 	broadcast_name = argv[1];
3492 	if (!IN_RANGE(strlen(broadcast_name), BT_AUDIO_BROADCAST_NAME_LEN_MIN,
3493 		      BT_AUDIO_BROADCAST_NAME_LEN_MAX)) {
3494 		shell_error(sh, "Broadcast name should be minimum %d and maximum %d characters",
3495 			    BT_AUDIO_BROADCAST_NAME_LEN_MIN, BT_AUDIO_BROADCAST_NAME_LEN_MAX);
3496 
3497 		return -ENOEXEC;
3498 	}
3499 
3500 	shell_print(sh, "Starting scanning for broadcast_name");
3501 
3502 	err = bt_le_scan_start(&param, NULL);
3503 	if (err) {
3504 		shell_print(sh, "Fail to start scanning: %d", err);
3505 
3506 		return -ENOEXEC;
3507 	}
3508 
3509 	memcpy(auto_scan.broadcast_info.broadcast_name, broadcast_name, strlen(broadcast_name));
3510 	auto_scan.broadcast_info.broadcast_name[strlen(broadcast_name)] = '\0';
3511 
3512 	auto_scan.broadcast_info.broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
3513 	auto_scan.broadcast_sink = &default_broadcast_sink;
3514 	auto_scan.out_sync = &per_adv_syncs[selected_per_adv_sync];
3515 
3516 	return 0;
3517 }
3518 
cmd_sync_broadcast(const struct shell * sh,size_t argc,char * argv[])3519 static int cmd_sync_broadcast(const struct shell *sh, size_t argc, char *argv[])
3520 {
3521 	struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_sink_streams)];
3522 	uint8_t bcode[BT_ISO_BROADCAST_CODE_SIZE] = {0};
3523 	bool bcode_set = false;
3524 	uint32_t bis_bitfield;
3525 	size_t stream_cnt;
3526 	int err = 0;
3527 
3528 	bis_bitfield = 0;
3529 	stream_cnt = 0U;
3530 	for (size_t argn = 1U; argn < argc; argn++) {
3531 		const char *arg = argv[argn];
3532 
3533 		if (strcmp(argv[argn], "bcode") == 0) {
3534 			size_t len;
3535 
3536 			if (++argn == argc) {
3537 				shell_help(sh);
3538 
3539 				return SHELL_CMD_HELP_PRINTED;
3540 			}
3541 
3542 			arg = argv[argn];
3543 
3544 			len = hex2bin(arg, strlen(arg), bcode, sizeof(bcode));
3545 			if (len == 0) {
3546 				shell_print(sh, "Invalid broadcast code: %s", arg);
3547 
3548 				return -ENOEXEC;
3549 			}
3550 
3551 			bcode_set = true;
3552 		} else if (strcmp(argv[argn], "bcode_str") == 0) {
3553 			if (++argn == argc) {
3554 				shell_help(sh);
3555 
3556 				return SHELL_CMD_HELP_PRINTED;
3557 			}
3558 
3559 			arg = argv[argn];
3560 
3561 			if (strlen(arg) == 0U || strlen(arg) > sizeof(bcode)) {
3562 				shell_print(sh, "Invalid broadcast code: %s", arg);
3563 
3564 				return -ENOEXEC;
3565 			}
3566 
3567 			memcpy(bcode, arg, strlen(arg));
3568 			bcode_set = true;
3569 		} else {
3570 			unsigned long val;
3571 
3572 			val = shell_strtoul(arg, 0, &err);
3573 			if (err != 0) {
3574 				shell_error(sh, "Could not parse BIS index val: %d", err);
3575 
3576 				return -ENOEXEC;
3577 			}
3578 
3579 			if (!IN_RANGE(val, BT_ISO_BIS_INDEX_MIN, BT_ISO_BIS_INDEX_MAX)) {
3580 				shell_error(sh, "Invalid index: %lu", val);
3581 
3582 				return -ENOEXEC;
3583 			}
3584 
3585 			bis_bitfield |= BT_ISO_BIS_INDEX_BIT(val);
3586 			stream_cnt++;
3587 		}
3588 	}
3589 
3590 	if (default_broadcast_sink.bap_sink == NULL) {
3591 		shell_error(sh, "No sink available");
3592 		return -ENOEXEC;
3593 	}
3594 
3595 	(void)memset(streams, 0, sizeof(streams));
3596 	for (size_t i = 0; i < ARRAY_SIZE(streams); i++) {
3597 		streams[i] = bap_stream_from_shell_stream(&broadcast_sink_streams[i]);
3598 	}
3599 
3600 	err = bt_bap_broadcast_sink_sync(default_broadcast_sink.bap_sink, bis_bitfield, streams,
3601 					 bcode_set ? bcode : NULL);
3602 	if (err != 0) {
3603 		shell_error(sh, "Failed to sync to broadcast: %d", err);
3604 		return err;
3605 	}
3606 
3607 	default_broadcast_sink.stream_cnt = stream_cnt;
3608 
3609 	return 0;
3610 }
3611 
cmd_stop_broadcast_sink(const struct shell * sh,size_t argc,char * argv[])3612 static int cmd_stop_broadcast_sink(const struct shell *sh, size_t argc,
3613 				   char *argv[])
3614 {
3615 	int err;
3616 
3617 	if (default_broadcast_sink.bap_sink == NULL) {
3618 		shell_error(sh, "No sink available");
3619 		return -ENOEXEC;
3620 	}
3621 
3622 	err = bt_bap_broadcast_sink_stop(default_broadcast_sink.bap_sink);
3623 	if (err != 0) {
3624 		shell_error(sh, "Failed to stop sink: %d", err);
3625 		return err;
3626 	}
3627 
3628 	return err;
3629 }
3630 
cmd_term_broadcast_sink(const struct shell * sh,size_t argc,char * argv[])3631 static int cmd_term_broadcast_sink(const struct shell *sh, size_t argc,
3632 				   char *argv[])
3633 {
3634 	int err;
3635 
3636 	if (default_broadcast_sink.bap_sink == NULL) {
3637 		shell_error(sh, "No sink available");
3638 		return -ENOEXEC;
3639 	}
3640 
3641 	err = bt_bap_broadcast_sink_delete(default_broadcast_sink.bap_sink);
3642 	if (err != 0) {
3643 		shell_error(sh, "Failed to term sink: %d", err);
3644 		return err;
3645 	}
3646 
3647 	default_broadcast_sink.bap_sink = NULL;
3648 	default_broadcast_sink.syncable = false;
3649 
3650 	return err;
3651 }
3652 #endif /* CONFIG_BT_BAP_BROADCAST_SINK */
3653 
cmd_set_loc(const struct shell * sh,size_t argc,char * argv[])3654 static int cmd_set_loc(const struct shell *sh, size_t argc, char *argv[])
3655 {
3656 	int err = 0;
3657 	enum bt_audio_dir dir;
3658 	enum bt_audio_location loc;
3659 	unsigned long loc_val;
3660 
3661 	if (!strcmp(argv[1], "sink")) {
3662 		dir = BT_AUDIO_DIR_SINK;
3663 	} else if (!strcmp(argv[1], "source")) {
3664 		dir = BT_AUDIO_DIR_SOURCE;
3665 	} else {
3666 		shell_error(sh, "Unsupported dir: %s", argv[1]);
3667 		return -ENOEXEC;
3668 	}
3669 
3670 	loc_val = shell_strtoul(argv[2], 16, &err);
3671 	if (err != 0) {
3672 		shell_error(sh, "Could not parse loc_val: %d", err);
3673 
3674 		return -ENOEXEC;
3675 	}
3676 
3677 	if (loc_val > BT_AUDIO_LOCATION_ANY) {
3678 		shell_error(sh, "Invalid location: %lu", loc_val);
3679 
3680 		return -ENOEXEC;
3681 	}
3682 
3683 	loc = loc_val;
3684 
3685 	err = bt_pacs_set_location(dir, loc);
3686 	if (err) {
3687 		shell_error(sh, "Set available contexts err %d", err);
3688 		return -ENOEXEC;
3689 	}
3690 
3691 	return 0;
3692 }
3693 
cmd_context(const struct shell * sh,size_t argc,char * argv[])3694 static int cmd_context(const struct shell *sh, size_t argc, char *argv[])
3695 {
3696 	int err = 0;
3697 	enum bt_audio_dir dir;
3698 	enum bt_audio_context ctx;
3699 	unsigned long ctx_val;
3700 
3701 	if (!strcmp(argv[1], "sink")) {
3702 		dir = BT_AUDIO_DIR_SINK;
3703 	} else if (!strcmp(argv[1], "source")) {
3704 		dir = BT_AUDIO_DIR_SOURCE;
3705 	} else {
3706 		shell_error(sh, "Unsupported dir: %s", argv[1]);
3707 		return -ENOEXEC;
3708 	}
3709 
3710 	ctx_val = shell_strtoul(argv[2], 16, &err);
3711 	if (err) {
3712 		shell_error(sh, "Could not parse context: %d", err);
3713 
3714 		return err;
3715 	}
3716 
3717 	if (ctx_val > BT_AUDIO_CONTEXT_TYPE_ANY) {
3718 		shell_error(sh, "Invalid context: %lu", ctx_val);
3719 
3720 		return -ENOEXEC;
3721 	}
3722 
3723 	ctx = ctx_val;
3724 
3725 	if (!strcmp(argv[3], "supported")) {
3726 		if (ctx_val == BT_AUDIO_CONTEXT_TYPE_PROHIBITED) {
3727 			shell_error(sh, "Invalid context: %lu", ctx_val);
3728 
3729 			return -ENOEXEC;
3730 		}
3731 
3732 		err = bt_pacs_set_supported_contexts(dir, ctx);
3733 		if (err) {
3734 			shell_error(sh, "Set supported contexts err %d", err);
3735 			return err;
3736 		}
3737 	} else if (!strcmp(argv[3], "available")) {
3738 		err = bt_pacs_set_available_contexts(dir, ctx);
3739 		if (err) {
3740 			shell_error(sh, "Set available contexts err %d", err);
3741 			return err;
3742 		}
3743 	} else {
3744 		shell_error(sh, "Unsupported context type: %s", argv[3]);
3745 		return -ENOEXEC;
3746 	}
3747 
3748 	return 0;
3749 }
3750 
cmd_init(const struct shell * sh,size_t argc,char * argv[])3751 static int cmd_init(const struct shell *sh, size_t argc, char *argv[])
3752 {
3753 	int err, i;
3754 
3755 	if (initialized) {
3756 		shell_print(sh, "Already initialized");
3757 		return -ENOEXEC;
3758 	}
3759 
3760 	if (argc != 1 && (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER) && argc != 3)) {
3761 		shell_error(sh, "Invalid argument count");
3762 		shell_help(sh);
3763 
3764 		return SHELL_CMD_HELP_PRINTED;
3765 	}
3766 
3767 #if defined(CONFIG_BT_BAP_UNICAST_SERVER)
3768 	unsigned long snk_cnt, src_cnt;
3769 	struct bt_bap_unicast_server_register_param unicast_server_param = {
3770 		CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
3771 		CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
3772 	};
3773 	const struct bt_pacs_register_param pacs_param = {
3774 #if defined(CONFIG_BT_PAC_SNK)
3775 		.snk_pac = true,
3776 #endif /* CONFIG_BT_PAC_SNK */
3777 #if defined(CONFIG_BT_PAC_SNK_LOC)
3778 		.snk_loc = true,
3779 #endif /* CONFIG_BT_PAC_SNK_LOC */
3780 #if defined(CONFIG_BT_PAC_SRC)
3781 		.src_pac = true,
3782 #endif /* CONFIG_BT_PAC_SRC */
3783 #if defined(CONFIG_BT_PAC_SRC_LOC)
3784 		.src_loc = true,
3785 #endif /* CONFIG_BT_PAC_SRC_LOC */
3786 	};
3787 
3788 	if (argc == 3) {
3789 		snk_cnt = shell_strtoul(argv[1], 0, &err);
3790 		if (snk_cnt > CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT) {
3791 			shell_error(sh, "Invalid Sink ASE count: %lu. Valid interval: [0, %u]",
3792 				    snk_cnt, CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT);
3793 
3794 			return -ENOEXEC;
3795 		}
3796 
3797 		unicast_server_param.snk_cnt = snk_cnt;
3798 
3799 		src_cnt = shell_strtoul(argv[2], 0, &err);
3800 		if (src_cnt > CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT) {
3801 			shell_error(sh, "Invalid Source ASE count: %lu. Valid interval: [0, %u]",
3802 				    src_cnt, CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT);
3803 
3804 			return -ENOEXEC;
3805 		}
3806 
3807 		unicast_server_param.src_cnt = src_cnt;
3808 	} else {
3809 		snk_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT;
3810 		src_cnt = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT;
3811 	}
3812 
3813 	err = bt_pacs_register(&pacs_param);
3814 	__ASSERT(err == 0, "Failed to register PACS: %d", err);
3815 
3816 	err = bt_bap_unicast_server_register(&unicast_server_param);
3817 	__ASSERT(err == 0, "Failed to register Unicast Server: %d", err);
3818 
3819 	err = bt_bap_unicast_server_register_cb(&unicast_server_cb);
3820 	__ASSERT(err == 0, "Failed to register Unicast Server Callbacks: %d", err);
3821 #endif /* CONFIG_BT_BAP_UNICAST_SERVER */
3822 
3823 #if defined(CONFIG_BT_PAC_SNK)
3824 	bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap_sink);
3825 #endif /* CONFIG_BT_PAC_SNK */
3826 #if defined(CONFIG_BT_PAC_SRC)
3827 	bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap_source);
3828 #endif /* CONFIG_BT_PAC_SNK */
3829 
3830 	if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC)) {
3831 		err = bt_pacs_set_location(BT_AUDIO_DIR_SINK, LOCATION);
3832 		__ASSERT(err == 0, "Failed to set sink location: %d", err);
3833 
3834 		err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK,
3835 						     CONTEXT);
3836 		__ASSERT(err == 0, "Failed to set sink supported contexts: %d",
3837 			 err);
3838 
3839 		err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK,
3840 						     CONTEXT);
3841 		__ASSERT(err == 0, "Failed to set sink available contexts: %d",
3842 			 err);
3843 	}
3844 
3845 	if (IS_ENABLED(CONFIG_BT_PAC_SRC_LOC)) {
3846 		err = bt_pacs_set_location(BT_AUDIO_DIR_SOURCE, LOCATION);
3847 		__ASSERT(err == 0, "Failed to set source location: %d", err);
3848 
3849 		err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE,
3850 						     CONTEXT);
3851 		__ASSERT(err == 0, "Failed to set sink supported contexts: %d",
3852 			 err);
3853 
3854 		err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
3855 						     CONTEXT);
3856 		__ASSERT(err == 0,
3857 			 "Failed to set source available contexts: %d",
3858 			 err);
3859 	}
3860 
3861 #if defined(CONFIG_BT_BAP_UNICAST)
3862 	for (i = 0; i < ARRAY_SIZE(unicast_streams); i++) {
3863 		bt_bap_stream_cb_register(bap_stream_from_shell_stream(&unicast_streams[i]),
3864 					  &stream_ops);
3865 
3866 		if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) &&
3867 		    IS_ENABLED(CONFIG_BT_CAP_INITIATOR)) {
3868 			/* If we use the cap initiator, we need to register the callbacks for CAP
3869 			 * as well, as CAP will override and use the BAP callbacks if doing a CAP
3870 			 * procedure
3871 			 */
3872 			bt_cap_stream_ops_register(&unicast_streams[i].stream, &stream_ops);
3873 		}
3874 	}
3875 #endif /* CONFIG_BT_BAP_UNICAST */
3876 
3877 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
3878 	bt_bap_broadcast_sink_register_cb(&sink_cbs);
3879 	bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
3880 	bt_le_scan_cb_register(&bap_scan_cb);
3881 
3882 	for (i = 0; i < ARRAY_SIZE(broadcast_sink_streams); i++) {
3883 		bt_bap_stream_cb_register(bap_stream_from_shell_stream(&broadcast_sink_streams[i]),
3884 					  &stream_ops);
3885 	}
3886 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
3887 
3888 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
3889 	for (i = 0; i < ARRAY_SIZE(broadcast_source_streams); i++) {
3890 		bt_bap_stream_cb_register(
3891 			bap_stream_from_shell_stream(&broadcast_source_streams[i]), &stream_ops);
3892 	}
3893 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
3894 
3895 #if defined(CONFIG_LIBLC3)
3896 #if defined(CONFIG_BT_AUDIO_RX)
3897 	static K_KERNEL_STACK_DEFINE(lc3_decoder_thread_stack, 4096);
3898 	const int lc3_decoder_thread_prio = K_PRIO_PREEMPT(5);
3899 	static struct k_thread lc3_decoder_thread;
3900 
3901 	k_thread_create(&lc3_decoder_thread, lc3_decoder_thread_stack,
3902 			K_KERNEL_STACK_SIZEOF(lc3_decoder_thread_stack), lc3_decoder_thread_func,
3903 			NULL, NULL, NULL, lc3_decoder_thread_prio, 0, K_NO_WAIT);
3904 	k_thread_name_set(&lc3_decoder_thread, "LC3 Decoder");
3905 #endif /* CONFIG_BT_AUDIO_RX */
3906 
3907 #if defined(CONFIG_BT_AUDIO_TX)
3908 	static K_KERNEL_STACK_DEFINE(lc3_encoder_thread_stack, 4096);
3909 	const int lc3_encoder_thread_prio = K_PRIO_PREEMPT(5);
3910 	static struct k_thread lc3_encoder_thread;
3911 
3912 	k_thread_create(&lc3_encoder_thread, lc3_encoder_thread_stack,
3913 			K_KERNEL_STACK_SIZEOF(lc3_encoder_thread_stack), lc3_encoder_thread_func,
3914 			NULL, NULL, NULL, lc3_encoder_thread_prio, 0, K_NO_WAIT);
3915 	k_thread_name_set(&lc3_encoder_thread, "LC3 Encoder");
3916 
3917 #endif /* CONFIG_BT_AUDIO_TX */
3918 
3919 	if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO) &&
3920 	    (IS_ENABLED(CONFIG_BT_AUDIO_RX) || IS_ENABLED(CONFIG_BT_AUDIO_TX))) {
3921 		err = bap_usb_init();
3922 		__ASSERT(err == 0, "Failed to enable USB: %d", err);
3923 	}
3924 #endif /* CONFIG_LIBLC3 */
3925 
3926 	initialized = true;
3927 
3928 	return 0;
3929 }
3930 
3931 #if defined(CONFIG_BT_AUDIO_TX)
3932 
3933 #define DATA_MTU CONFIG_BT_ISO_TX_MTU
3934 NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, DATA_MTU, CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
3935 
cmd_send(const struct shell * sh,size_t argc,char * argv[])3936 static int cmd_send(const struct shell *sh, size_t argc, char *argv[])
3937 {
3938 	static uint8_t data[DATA_MTU - BT_ISO_CHAN_SEND_RESERVE];
3939 	int ret, len;
3940 	struct net_buf *buf;
3941 
3942 	if (default_stream == NULL) {
3943 		shell_error(sh, "Invalid (NULL) stream");
3944 
3945 		return -ENOEXEC;
3946 	}
3947 
3948 	if (default_stream->qos == NULL) {
3949 		shell_error(sh, "NULL stream QoS");
3950 
3951 		return -ENOEXEC;
3952 	}
3953 
3954 	if (argc > 1) {
3955 		len = hex2bin(argv[1], strlen(argv[1]), data, sizeof(data));
3956 		if (len > default_stream->qos->sdu) {
3957 			shell_print(sh, "Unable to send: len %d > %u MTU",
3958 				    len, default_stream->qos->sdu);
3959 
3960 			return -ENOEXEC;
3961 		}
3962 	} else {
3963 		len = MIN(default_stream->qos->sdu, sizeof(data));
3964 		memset(data, 0xff, len);
3965 	}
3966 
3967 	buf = net_buf_alloc(&tx_pool, K_FOREVER);
3968 	net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
3969 
3970 	net_buf_add_mem(buf, data, len);
3971 
3972 	ret = bt_bap_stream_send(default_stream, buf, get_next_seq_num(default_stream));
3973 	if (ret < 0) {
3974 		shell_print(sh, "Unable to send: %d", -ret);
3975 		net_buf_unref(buf);
3976 
3977 		return -ENOEXEC;
3978 	}
3979 
3980 	shell_print(sh, "Sending:");
3981 	shell_hexdump(sh, data, len);
3982 
3983 	return 0;
3984 }
3985 
3986 #if GENERATE_SINE_SUPPORTED
start_sine_stream_cb(struct shell_stream * sh_stream,void * user_data)3987 static void start_sine_stream_cb(struct shell_stream *sh_stream, void *user_data)
3988 {
3989 	if (sh_stream->is_tx) {
3990 		struct bt_bap_stream *bap_stream = bap_stream_from_shell_stream(sh_stream);
3991 		const struct shell *sh = user_data;
3992 		int err;
3993 
3994 		err = init_lc3_encoder(sh_stream);
3995 		if (err != 0) {
3996 			shell_error(sh, "Failed to init LC3 %d for stream %p", err, bap_stream);
3997 
3998 			return;
3999 		}
4000 
4001 		sh_stream->tx.active = true;
4002 		sh_stream->tx.seq_num = get_next_seq_num(bap_stream_from_shell_stream(sh_stream));
4003 
4004 		shell_print(sh, "Started transmitting sine on stream %p", bap_stream);
4005 	}
4006 }
4007 
cmd_start_sine(const struct shell * sh,size_t argc,char * argv[])4008 static int cmd_start_sine(const struct shell *sh, size_t argc, char *argv[])
4009 {
4010 	bool start_all = false;
4011 
4012 	if (argc > 1) {
4013 		if (strcmp(argv[1], "all") == 0) {
4014 			start_all = true;
4015 		} else {
4016 			shell_help(sh);
4017 
4018 			return SHELL_CMD_HELP_PRINTED;
4019 		}
4020 	}
4021 
4022 	if (start_all) {
4023 		bap_foreach_stream(start_sine_stream_cb, (void *)sh);
4024 	} else {
4025 		struct shell_stream *sh_stream = shell_stream_from_bap_stream(default_stream);
4026 
4027 		start_sine_stream_cb(sh_stream, (void *)sh);
4028 	}
4029 
4030 	return 0;
4031 }
4032 
stop_sine_stream_cb(struct shell_stream * sh_stream,void * user_data)4033 static void stop_sine_stream_cb(struct shell_stream *sh_stream, void *user_data)
4034 {
4035 	if (sh_stream->is_tx) {
4036 		struct bt_bap_stream *bap_stream = bap_stream_from_shell_stream(sh_stream);
4037 		const struct shell *sh = user_data;
4038 
4039 		shell_print(sh, "Stopped transmitting on stream %p", bap_stream);
4040 
4041 		sh_stream->tx.active = false;
4042 	}
4043 }
4044 
cmd_stop_sine(const struct shell * sh,size_t argc,char * argv[])4045 static int cmd_stop_sine(const struct shell *sh, size_t argc, char *argv[])
4046 {
4047 	bool stop_all = false;
4048 
4049 	if (argc > 1) {
4050 		if (strcmp(argv[1], "all") == 0) {
4051 			stop_all = true;
4052 		} else {
4053 			shell_help(sh);
4054 
4055 			return SHELL_CMD_HELP_PRINTED;
4056 		}
4057 	}
4058 
4059 	if (stop_all) {
4060 		bap_foreach_stream(stop_sine_stream_cb, (void *)sh);
4061 	} else {
4062 		struct shell_stream *sh_stream = shell_stream_from_bap_stream(default_stream);
4063 
4064 		stop_sine_stream_cb(sh_stream, (void *)sh);
4065 	}
4066 
4067 	return 0;
4068 }
4069 #endif /* GENERATE_SINE_SUPPORTED */
4070 #endif /* CONFIG_BT_AUDIO_TX */
4071 
cmd_bap_stats(const struct shell * sh,size_t argc,char * argv[])4072 static int cmd_bap_stats(const struct shell *sh, size_t argc, char *argv[])
4073 {
4074 	if (argc == 1) {
4075 		shell_info(sh, "Current stats interval: %lu", bap_stats_interval);
4076 	} else {
4077 		int err = 0;
4078 		unsigned long interval;
4079 
4080 		interval = shell_strtoul(argv[1], 0, &err);
4081 		if (err != 0) {
4082 			shell_error(sh, "Could not parse interval: %d", err);
4083 
4084 			return -ENOEXEC;
4085 		}
4086 
4087 		if (interval == 0U) {
4088 			shell_error(sh, "Interval cannot be 0");
4089 
4090 			return -ENOEXEC;
4091 		}
4092 
4093 		bap_stats_interval = interval;
4094 	}
4095 
4096 	return 0;
4097 }
4098 
4099 #if defined(CONFIG_BT_BAP_UNICAST_SERVER)
print_ase_info(struct bt_bap_ep * ep,void * user_data)4100 static void print_ase_info(struct bt_bap_ep *ep, void *user_data)
4101 {
4102 	struct bt_bap_ep_info info;
4103 	int err;
4104 
4105 	err = bt_bap_ep_get_info(ep, &info);
4106 	if (err == 0) {
4107 		printk("ASE info: id %u state %u dir %u\n", info.id, info.state, info.dir);
4108 	}
4109 }
4110 
cmd_print_ase_info(const struct shell * sh,size_t argc,char * argv[])4111 static int cmd_print_ase_info(const struct shell *sh, size_t argc, char *argv[])
4112 {
4113 	if (!default_conn) {
4114 		shell_error(sh, "Not connected");
4115 		return -ENOEXEC;
4116 	}
4117 
4118 	bt_bap_unicast_server_foreach_ep(default_conn, print_ase_info, NULL);
4119 
4120 	return 0;
4121 }
4122 #endif /* CONFIG_BT_BAP_UNICAST_SERVER */
4123 
4124 /* 31 is a unit separator - without t the tab is seemingly ignored*/
4125 #define HELP_SEP "\n\31\t"
4126 
4127 #define HELP_CFG_DATA                                                                              \
4128 	"\n[config" HELP_SEP "[freq <frequency>]" HELP_SEP "[dur <duration>]" HELP_SEP             \
4129 	"[chan_alloc <location>]" HELP_SEP "[frame_len <frame length>]" HELP_SEP                   \
4130 	"[frame_blks <frame blocks>]]"
4131 
4132 #define HELP_CFG_META                                                                              \
4133 	"\n[meta" HELP_SEP "[pref_ctx <context>]" HELP_SEP "[stream_ctx <context>]" HELP_SEP       \
4134 	"[program_info <program info>]" HELP_SEP "[lang <ISO 639-3 lang>]" HELP_SEP                \
4135 	"[ccid_list <ccids>]" HELP_SEP "[parental_rating <rating>]" HELP_SEP                       \
4136 	"[program_info_uri <URI>]" HELP_SEP "[audio_active_state <state>]" HELP_SEP                \
4137 	"[bcast_flag]" HELP_SEP "[extended <meta>]" HELP_SEP "[vendor <meta>]]"
4138 
4139 SHELL_STATIC_SUBCMD_SET_CREATE(
4140 	bap_cmds,
4141 	SHELL_CMD_ARG(init, NULL, NULL, cmd_init, 1,
4142 		      IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER) ? 2 : 0),
4143 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
4144 	SHELL_CMD_ARG(select_broadcast, NULL, "<stream>", cmd_select_broadcast_source, 2, 0),
4145 	SHELL_CMD_ARG(create_broadcast, NULL, "[preset <preset_name>] [enc <broadcast_code>]",
4146 		      cmd_create_broadcast, 1, 2),
4147 	SHELL_CMD_ARG(start_broadcast, NULL, "", cmd_start_broadcast, 1, 0),
4148 	SHELL_CMD_ARG(stop_broadcast, NULL, "", cmd_stop_broadcast, 1, 0),
4149 	SHELL_CMD_ARG(delete_broadcast, NULL, "", cmd_delete_broadcast, 1, 0),
4150 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
4151 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
4152 	SHELL_CMD_ARG(create_broadcast_sink, NULL, "0x<broadcast_id>", cmd_create_broadcast_sink, 2,
4153 		      0),
4154 	SHELL_CMD_ARG(create_sink_by_name, NULL, "<broadcast_name>",
4155 		      cmd_create_sink_by_name, 2, 0),
4156 	SHELL_CMD_ARG(sync_broadcast, NULL,
4157 		      "0x<bis_index> [[[0x<bis_index>] 0x<bis_index>] ...] "
4158 		      "[bcode <broadcast code> || bcode_str <broadcast code as string>]",
4159 		      cmd_sync_broadcast, 2, ARRAY_SIZE(broadcast_sink_streams) + 1),
4160 	SHELL_CMD_ARG(stop_broadcast_sink, NULL, "Stops broadcast sink", cmd_stop_broadcast_sink, 1,
4161 		      0),
4162 	SHELL_CMD_ARG(term_broadcast_sink, NULL, "", cmd_term_broadcast_sink, 1, 0),
4163 #endif /* CONFIG_BT_BAP_BROADCAST_SINK */
4164 #if defined(CONFIG_BT_BAP_UNICAST)
4165 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
4166 	SHELL_CMD_ARG(discover, NULL, "[dir: sink, source]", cmd_discover, 1, 1),
4167 	SHELL_CMD_ARG(config, NULL,
4168 		      "<direction: sink, source> <index> [loc <loc_bits>] [preset <preset_name>]",
4169 		      cmd_config, 3, 4),
4170 	SHELL_CMD_ARG(stream_qos, NULL, "interval [framing] [latency] [pd] [sdu] [phy] [rtn]",
4171 		      cmd_stream_qos, 2, 6),
4172 	SHELL_CMD_ARG(connect, NULL, "Connect the CIS of the stream", cmd_connect, 1, 0),
4173 	SHELL_CMD_ARG(qos, NULL, "Send QoS configure for Unicast Group", cmd_qos, 1, 0),
4174 	SHELL_CMD_ARG(enable, NULL, "[context]", cmd_enable, 1, 1),
4175 	SHELL_CMD_ARG(stop, NULL, NULL, cmd_stop, 1, 0),
4176 	SHELL_CMD_ARG(list, NULL, NULL, cmd_list, 1, 0),
4177 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
4178 #if defined(CONFIG_BT_BAP_UNICAST_SERVER)
4179 	SHELL_CMD_ARG(print_ase_info, NULL, "Print ASE info for default connection",
4180 		      cmd_print_ase_info, 0, 0),
4181 #endif /* CONFIG_BT_BAP_UNICAST_SERVER */
4182 	SHELL_CMD_ARG(metadata, NULL, "[context]", cmd_metadata, 1, 1),
4183 	SHELL_CMD_ARG(start, NULL, NULL, cmd_start, 1, 0),
4184 	SHELL_CMD_ARG(disable, NULL, NULL, cmd_disable, 1, 0),
4185 	SHELL_CMD_ARG(release, NULL, NULL, cmd_release, 1, 0),
4186 	SHELL_CMD_ARG(select_unicast, NULL, "<stream>", cmd_select_unicast, 2, 0),
4187 #endif /* CONFIG_BT_BAP_UNICAST */
4188 #if IS_BAP_INITIATOR
4189 	SHELL_CMD_ARG(preset, NULL,
4190 		      "<sink, source, broadcast> [preset] " HELP_CFG_DATA " " HELP_CFG_META,
4191 		      cmd_preset, 2, 34),
4192 #endif /* IS_BAP_INITIATOR */
4193 #if defined(CONFIG_BT_AUDIO_TX)
4194 	SHELL_CMD_ARG(send, NULL, "Send to Audio Stream [data]", cmd_send, 1, 1),
4195 #if GENERATE_SINE_SUPPORTED
4196 	SHELL_CMD_ARG(start_sine, NULL, "Start sending a LC3 encoded sine wave [all]",
4197 		      cmd_start_sine, 1, 1),
4198 	SHELL_CMD_ARG(stop_sine, NULL, "Stop sending a LC3 encoded sine wave [all]", cmd_stop_sine,
4199 		      1, 1),
4200 #endif /* GENERATE_SINE_SUPPORTED */
4201 #endif /* CONFIG_BT_AUDIO_TX */
4202 	SHELL_CMD_ARG(bap_stats, NULL,
4203 		      "Sets or gets the statistics reporting interval in # of packets",
4204 		      cmd_bap_stats, 1, 1),
4205 	SHELL_COND_CMD_ARG(CONFIG_BT_PACS, set_location, NULL,
4206 			   "<direction: sink, source> <location bitmask>", cmd_set_loc, 3, 0),
4207 	SHELL_COND_CMD_ARG(CONFIG_BT_PACS, set_context, NULL,
4208 			   "<direction: sink, source>"
4209 			   "<context bitmask> <type: supported, available>",
4210 			   cmd_context, 4, 0),
4211 	SHELL_SUBCMD_SET_END);
4212 
cmd_bap(const struct shell * sh,size_t argc,char ** argv)4213 static int cmd_bap(const struct shell *sh, size_t argc, char **argv)
4214 {
4215 	if (argc > 1) {
4216 		shell_error(sh, "%s unknown parameter: %s",
4217 			    argv[0], argv[1]);
4218 	} else {
4219 		shell_error(sh, "%s Missing subcommand", argv[0]);
4220 	}
4221 
4222 	return -ENOEXEC;
4223 }
4224 
4225 SHELL_CMD_ARG_REGISTER(bap, &bap_cmds, "Bluetooth BAP shell commands", cmd_bap, 1, 1);
4226 
connectable_ad_data_add(struct bt_data * data_array,size_t data_array_size)4227 static size_t connectable_ad_data_add(struct bt_data *data_array, size_t data_array_size)
4228 {
4229 	static const uint8_t ad_ext_uuid16[] = {
4230 		IF_ENABLED(CONFIG_BT_MICP_MIC_DEV, (BT_UUID_16_ENCODE(BT_UUID_MICS_VAL),))
4231 		IF_ENABLED(CONFIG_BT_ASCS, (BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL),))
4232 		IF_ENABLED(CONFIG_BT_BAP_SCAN_DELEGATOR, (BT_UUID_16_ENCODE(BT_UUID_BASS_VAL),))
4233 		IF_ENABLED(CONFIG_BT_PACS, (BT_UUID_16_ENCODE(BT_UUID_PACS_VAL),))
4234 		IF_ENABLED(CONFIG_BT_TBS, (BT_UUID_16_ENCODE(BT_UUID_GTBS_VAL),))
4235 		IF_ENABLED(CONFIG_BT_TBS_BEARER_COUNT, (BT_UUID_16_ENCODE(BT_UUID_TBS_VAL),))
4236 		IF_ENABLED(CONFIG_BT_VCP_VOL_REND, (BT_UUID_16_ENCODE(BT_UUID_VCS_VAL),))
4237 		IF_ENABLED(CONFIG_BT_HAS, (BT_UUID_16_ENCODE(BT_UUID_HAS_VAL),)) /* Shall be last */
4238 	};
4239 	size_t ad_len = 0;
4240 
4241 	if (IS_ENABLED(CONFIG_BT_ASCS)) {
4242 		static uint8_t ad_bap_announcement[8] = {
4243 			BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL),
4244 			BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED,
4245 		};
4246 		enum bt_audio_context snk_context, src_context;
4247 
4248 		snk_context = bt_pacs_get_available_contexts(BT_AUDIO_DIR_SINK);
4249 		sys_put_le16(snk_context, &ad_bap_announcement[3]);
4250 
4251 		src_context = bt_pacs_get_available_contexts(BT_AUDIO_DIR_SOURCE);
4252 		sys_put_le16(src_context, &ad_bap_announcement[5]);
4253 
4254 		/* Metadata length */
4255 		ad_bap_announcement[7] = 0x00;
4256 
4257 		__ASSERT(data_array_size > ad_len, "No space for AD_BAP_ANNOUNCEMENT");
4258 		data_array[ad_len].type = BT_DATA_SVC_DATA16;
4259 		data_array[ad_len].data_len = ARRAY_SIZE(ad_bap_announcement);
4260 		data_array[ad_len].data = &ad_bap_announcement[0];
4261 		ad_len++;
4262 	}
4263 
4264 	if (IS_ENABLED(CONFIG_BT_BAP_SCAN_DELEGATOR)) {
4265 		ad_len += bap_scan_delegator_ad_data_add(&data_array[ad_len],
4266 							 data_array_size - ad_len);
4267 	}
4268 
4269 	if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR)) {
4270 		ad_len += cap_acceptor_ad_data_add(&data_array[ad_len], data_array_size - ad_len,
4271 						   true);
4272 	}
4273 
4274 	if (IS_ENABLED(CONFIG_BT_GMAP)) {
4275 		ad_len += gmap_ad_data_add(&data_array[ad_len], data_array_size - ad_len);
4276 	}
4277 
4278 	if (ARRAY_SIZE(ad_ext_uuid16) > 0) {
4279 		size_t uuid16_size;
4280 
4281 		if (data_array_size <= ad_len) {
4282 			bt_shell_warn("No space for AD_UUID16");
4283 			return ad_len;
4284 		}
4285 
4286 		data_array[ad_len].type = BT_DATA_UUID16_SOME;
4287 
4288 		if (IS_ENABLED(CONFIG_BT_HAS) && IS_ENABLED(CONFIG_BT_PRIVACY)) {
4289 			/* If the HA is in one of the GAP connectable modes and is using a
4290 			 * resolvable private address, the HA shall not include the Hearing Access
4291 			 * Service UUID in the Service UUID AD type field of the advertising data
4292 			 * or scan response.
4293 			 */
4294 			uuid16_size = ARRAY_SIZE(ad_ext_uuid16) - BT_UUID_SIZE_16;
4295 		} else {
4296 			uuid16_size = ARRAY_SIZE(ad_ext_uuid16);
4297 		}
4298 
4299 		/* We can maximum advertise 127 16-bit UUIDs = 254 octets */
4300 		data_array[ad_len].data_len = MIN(uuid16_size, 254);
4301 
4302 		data_array[ad_len].data = &ad_ext_uuid16[0];
4303 		ad_len++;
4304 	}
4305 
4306 	return ad_len;
4307 }
4308 
nonconnectable_ad_data_add(struct bt_data * data_array,const size_t data_array_size)4309 static size_t nonconnectable_ad_data_add(struct bt_data *data_array, const size_t data_array_size)
4310 {
4311 	static const uint8_t ad_ext_uuid16[] = {
4312 		IF_ENABLED(CONFIG_BT_PACS, (BT_UUID_16_ENCODE(BT_UUID_PACS_VAL),))
4313 		IF_ENABLED(CONFIG_BT_CAP_ACCEPTOR, (BT_UUID_16_ENCODE(BT_UUID_CAS_VAL),))
4314 	};
4315 	size_t ad_len = 0;
4316 
4317 	if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR)) {
4318 		static const uint8_t ad_cap_announcement[3] = {
4319 			BT_UUID_16_ENCODE(BT_UUID_CAS_VAL),
4320 			BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED,
4321 		};
4322 
4323 		__ASSERT(data_array_size > ad_len, "No space for AD_CAP_ANNOUNCEMENT");
4324 		data_array[ad_len].type = BT_DATA_SVC_DATA16;
4325 		data_array[ad_len].data_len = ARRAY_SIZE(ad_cap_announcement);
4326 		data_array[ad_len].data = &ad_cap_announcement[0];
4327 		ad_len++;
4328 	}
4329 
4330 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
4331 	if (default_source.bap_source != NULL && !default_source.is_cap) {
4332 		static uint8_t ad_bap_broadcast_announcement[5] = {
4333 			BT_UUID_16_ENCODE(BT_UUID_BROADCAST_AUDIO_VAL),
4334 		};
4335 		uint32_t broadcast_id;
4336 		int err;
4337 
4338 		err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE);
4339 		if (err != 0) {
4340 			bt_shell_error("Unable to generate broadcast ID: %d\n", err);
4341 
4342 			return 0;
4343 		}
4344 
4345 		sys_put_le24(broadcast_id, &ad_bap_broadcast_announcement[2]);
4346 		data_array[ad_len].type = BT_DATA_SVC_DATA16;
4347 		data_array[ad_len].data_len = ARRAY_SIZE(ad_bap_broadcast_announcement);
4348 		data_array[ad_len].data = ad_bap_broadcast_announcement;
4349 		ad_len++;
4350 	}
4351 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
4352 
4353 	if (ARRAY_SIZE(ad_ext_uuid16) > 0) {
4354 		if (data_array_size <= ad_len) {
4355 			bt_shell_warn("No space for AD_UUID16");
4356 			return ad_len;
4357 		}
4358 
4359 		data_array[ad_len].type = BT_DATA_UUID16_SOME;
4360 		data_array[ad_len].data_len = ARRAY_SIZE(ad_ext_uuid16);
4361 		data_array[ad_len].data = &ad_ext_uuid16[0];
4362 		ad_len++;
4363 	}
4364 
4365 	return ad_len;
4366 }
4367 
audio_ad_data_add(struct bt_data * data_array,const size_t data_array_size,const bool discoverable,const bool connectable)4368 size_t audio_ad_data_add(struct bt_data *data_array, const size_t data_array_size,
4369 			 const bool discoverable, const bool connectable)
4370 {
4371 	size_t ad_len = 0;
4372 
4373 	if (!discoverable) {
4374 		return 0;
4375 	}
4376 
4377 	if (connectable) {
4378 		ad_len += connectable_ad_data_add(data_array, data_array_size);
4379 	} else {
4380 		ad_len += nonconnectable_ad_data_add(data_array, data_array_size);
4381 	}
4382 
4383 	if (IS_ENABLED(CONFIG_BT_CAP_INITIATOR)) {
4384 		ad_len += cap_initiator_ad_data_add(data_array, data_array_size, discoverable,
4385 						    connectable);
4386 	}
4387 
4388 	return ad_len;
4389 }
4390 
audio_pa_data_add(struct bt_data * data_array,const size_t data_array_size)4391 size_t audio_pa_data_add(struct bt_data *data_array, const size_t data_array_size)
4392 {
4393 	size_t ad_len = 0;
4394 
4395 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
4396 	if (default_source.bap_source != NULL && !default_source.is_cap) {
4397 		/* Required size of the buffer depends on what has been
4398 		 * configured. We just use the maximum size possible.
4399 		 */
4400 		NET_BUF_SIMPLE_DEFINE_STATIC(base_buf, UINT8_MAX);
4401 		int err;
4402 
4403 		net_buf_simple_reset(&base_buf);
4404 
4405 		err = bt_bap_broadcast_source_get_base(default_source.bap_source, &base_buf);
4406 		if (err != 0) {
4407 			bt_shell_error("Unable to get BASE: %d\n", err);
4408 
4409 			return 0;
4410 		}
4411 
4412 		data_array[ad_len].type = BT_DATA_SVC_DATA16;
4413 		data_array[ad_len].data_len = base_buf.len;
4414 		data_array[ad_len].data = base_buf.data;
4415 		ad_len++;
4416 	} else if (IS_ENABLED(CONFIG_BT_CAP_INITIATOR)) {
4417 		return cap_initiator_pa_data_add(data_array, data_array_size);
4418 	}
4419 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
4420 
4421 	return ad_len;
4422 }
4423