1 /*
2  * Copyright (c) 2021-2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <errno.h>
7 #include <stdbool.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include <zephyr/autoconf.h>
14 #include <zephyr/bluetooth/audio/audio.h>
15 #include <zephyr/bluetooth/audio/bap.h>
16 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
17 #include <zephyr/bluetooth/audio/lc3.h>
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/bluetooth/byteorder.h>
20 #include <zephyr/bluetooth/crypto.h>
21 #include <zephyr/bluetooth/gap.h>
22 #include <zephyr/bluetooth/hci_types.h>
23 #include <zephyr/bluetooth/iso.h>
24 #include <zephyr/bluetooth/uuid.h>
25 #include <zephyr/kernel.h>
26 #include <zephyr/net_buf.h>
27 #include <zephyr/sys/printk.h>
28 #include <zephyr/sys/util.h>
29 #include <zephyr/sys/util_macro.h>
30 #include <zephyr/toolchain.h>
31 
32 #include "bap_common.h"
33 #include "bap_stream_tx.h"
34 #include "bstests.h"
35 #include "common.h"
36 
37 #define SUPPORTED_CHAN_COUNTS          BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1, 2)
38 #define SUPPORTED_MIN_OCTETS_PER_FRAME 30
39 #define SUPPORTED_MAX_OCTETS_PER_FRAME 155
40 #define SUPPORTED_MAX_FRAMES_PER_SDU   1
41 
42 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
43 CREATE_FLAG(flag_source_started);
44 
45 static struct audio_test_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
46 /* We always default to the mandatory-to-support preset_16_2_1 */
47 static struct bt_bap_lc3_preset preset_16_2_1 = BT_BAP_LC3_BROADCAST_PRESET_16_2_1(
48 	BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
49 static struct bt_bap_lc3_preset preset_16_1_1 = BT_BAP_LC3_BROADCAST_PRESET_16_1_1(
50 	BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
51 static struct bt_audio_codec_cfg *codec_cfg = &preset_16_2_1.codec_cfg;
52 
53 static uint8_t bis_codec_data[] = {
54 	BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CFG_CHAN_ALLOC,
55 			    BT_BYTES_LIST_LE32(BT_AUDIO_LOCATION_FRONT_CENTER)),
56 };
57 static unsigned long subgroup_cnt_arg = 1;
58 static unsigned long streams_per_subgroup_cnt_arg = 1;
59 
60 static K_SEM_DEFINE(sem_stream_started, 0U, ARRAY_SIZE(broadcast_source_streams));
61 static K_SEM_DEFINE(sem_stream_stopped, 0U, ARRAY_SIZE(broadcast_source_streams));
62 
validate_stream_codec_cfg(const struct bt_bap_stream * stream)63 static void validate_stream_codec_cfg(const struct bt_bap_stream *stream)
64 {
65 	const struct bt_audio_codec_cfg *stream_codec_cfg = stream->codec_cfg;
66 	const struct bt_audio_codec_cfg *exp_codec_cfg = codec_cfg;
67 	enum bt_audio_location chan_allocation;
68 	uint8_t frames_blocks_per_sdu;
69 	size_t min_sdu_size_required;
70 	uint16_t octets_per_frame;
71 	uint8_t chan_cnt;
72 	int ret;
73 	int exp_ret;
74 
75 	if (stream_codec_cfg->id != BT_HCI_CODING_FORMAT_LC3) {
76 		/* We can only validate LC3 codecs */
77 		return;
78 	}
79 
80 	ret = bt_audio_codec_cfg_get_freq(stream_codec_cfg);
81 	exp_ret = bt_audio_codec_cfg_get_freq(exp_codec_cfg);
82 	if (ret >= 0) {
83 		const int freq = bt_audio_codec_cfg_freq_to_freq_hz(ret);
84 		const int exp_freq = bt_audio_codec_cfg_freq_to_freq_hz(exp_ret);
85 
86 		if (freq != exp_freq) {
87 			FAIL("Invalid frequency: %d Expected: %d\n", freq, exp_freq);
88 
89 			return;
90 		}
91 	} else {
92 		FAIL("Could not get frequency: %d\n", ret);
93 
94 		return;
95 	}
96 
97 	ret = bt_audio_codec_cfg_get_frame_dur(stream_codec_cfg);
98 	exp_ret = bt_audio_codec_cfg_get_frame_dur(exp_codec_cfg);
99 	if (ret >= 0) {
100 		const int frm_dur_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret);
101 		const int exp_frm_dur_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(exp_ret);
102 
103 		if (frm_dur_us != exp_frm_dur_us) {
104 			FAIL("Invalid frame duration: %d Exp: %d\n", frm_dur_us, exp_frm_dur_us);
105 
106 			return;
107 		}
108 	} else {
109 		FAIL("Could not get frame duration: %d\n", ret);
110 
111 		return;
112 	}
113 
114 	/* The broadcast source sets the channel allocation in the BIS to
115 	 * BT_AUDIO_LOCATION_FRONT_CENTER
116 	 */
117 	ret = bt_audio_codec_cfg_get_chan_allocation(stream_codec_cfg, &chan_allocation, true);
118 	if (ret == 0) {
119 		if (chan_allocation != BT_AUDIO_LOCATION_FRONT_CENTER) {
120 			FAIL("Unexpected channel allocation: 0x%08X", chan_allocation);
121 
122 			return;
123 		}
124 
125 		chan_cnt = bt_audio_get_chan_count(chan_allocation);
126 	} else {
127 		FAIL("Could not get subgroup channel allocation: %d\n", ret);
128 
129 		return;
130 	}
131 
132 	if (chan_cnt == 0 || (BIT(chan_cnt - 1) & SUPPORTED_CHAN_COUNTS) == 0) {
133 		FAIL("Unsupported channel count: %u\n", chan_cnt);
134 
135 		return;
136 	}
137 
138 	ret = bt_audio_codec_cfg_get_octets_per_frame(stream_codec_cfg);
139 	if (ret > 0) {
140 		octets_per_frame = (uint16_t)ret;
141 	} else {
142 		FAIL("Could not get subgroup octets per frame: %d\n", ret);
143 
144 		return;
145 	}
146 
147 	if (!IN_RANGE(octets_per_frame, SUPPORTED_MIN_OCTETS_PER_FRAME,
148 		      SUPPORTED_MAX_OCTETS_PER_FRAME)) {
149 		FAIL("Unsupported octets per frame: %u\n", octets_per_frame);
150 
151 		return;
152 	}
153 
154 	ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(stream_codec_cfg, true);
155 	if (ret > 0) {
156 		frames_blocks_per_sdu = (uint8_t)ret;
157 	} else {
158 		FAIL("Could not get frame blocks per SDU: %d\n", ret);
159 
160 		return;
161 	}
162 
163 	/* An SDU can consist of X frame blocks, each with Y frames (one per channel) of size Z in
164 	 * them. The minimum SDU size required for this is X * Y * Z.
165 	 */
166 	min_sdu_size_required = chan_cnt * octets_per_frame * frames_blocks_per_sdu;
167 	if (min_sdu_size_required > stream->qos->sdu) {
168 		FAIL("With %zu channels and %u octets per frame and %u frames per block, SDUs "
169 		     "shall be at minimum %zu, but the stream has been configured for %u\n",
170 		     chan_cnt, octets_per_frame, frames_blocks_per_sdu, min_sdu_size_required,
171 		     stream->qos->sdu);
172 
173 		return;
174 	}
175 }
176 
stream_started_cb(struct bt_bap_stream * stream)177 static void stream_started_cb(struct bt_bap_stream *stream)
178 {
179 	struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
180 	struct bt_bap_ep_info info;
181 	int err;
182 
183 	test_stream->seq_num = 0U;
184 	test_stream->tx_cnt = 0U;
185 
186 	err = bt_bap_ep_get_info(stream->ep, &info);
187 	if (err != 0) {
188 		FAIL("Failed to get EP info: %d\n", err);
189 		return;
190 	}
191 
192 	if (info.state != BT_BAP_EP_STATE_STREAMING) {
193 		FAIL("Unexpected EP state: %d\n", info.state);
194 		return;
195 	}
196 
197 	if (info.dir != BT_AUDIO_DIR_SOURCE) {
198 		FAIL("Unexpected info.dir: %d\n", info.dir);
199 		return;
200 	}
201 
202 	if (!info.can_send) {
203 		FAIL("info.can_send is false\n");
204 		return;
205 	}
206 
207 	if (info.can_recv) {
208 		FAIL("info.can_recv is true\n");
209 		return;
210 	}
211 
212 	if (info.paired_ep != NULL) {
213 		FAIL("Unexpected info.paired_ep: %p\n", info.paired_ep);
214 		return;
215 	}
216 
217 	err = bap_stream_tx_register(stream);
218 	if (err != 0) {
219 		FAIL("Failed to register stream %p for TX: %d\n", stream, err);
220 		return;
221 	}
222 
223 	printk("Stream %p started\n", stream);
224 	validate_stream_codec_cfg(stream);
225 	k_sem_give(&sem_stream_started);
226 }
227 
steam_stopped_cb(struct bt_bap_stream * stream,uint8_t reason)228 static void steam_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
229 {
230 	int err;
231 
232 	printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
233 
234 	err = bap_stream_tx_unregister(stream);
235 	if (err != 0) {
236 		FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
237 		return;
238 	}
239 
240 	k_sem_give(&sem_stream_stopped);
241 }
242 
243 static struct bt_bap_stream_ops stream_ops = {
244 	.started = stream_started_cb,
245 	.stopped = steam_stopped_cb,
246 	.sent = bap_stream_tx_sent_cb,
247 };
248 
source_started_cb(struct bt_bap_broadcast_source * source)249 static void source_started_cb(struct bt_bap_broadcast_source *source)
250 {
251 	printk("Broadcast source %p started\n", source);
252 	SET_FLAG(flag_source_started);
253 }
254 
source_stopped_cb(struct bt_bap_broadcast_source * source,uint8_t reason)255 static void source_stopped_cb(struct bt_bap_broadcast_source *source, uint8_t reason)
256 {
257 	printk("Broadcast source %p stopped with reason 0x%02X\n", source, reason);
258 	UNSET_FLAG(flag_source_started);
259 }
260 
setup_broadcast_source(struct bt_bap_broadcast_source ** source,bool encryption)261 static int setup_broadcast_source(struct bt_bap_broadcast_source **source, bool encryption)
262 {
263 	struct bt_bap_broadcast_source_stream_param
264 		stream_params[ARRAY_SIZE(broadcast_source_streams)];
265 	struct bt_bap_broadcast_source_subgroup_param
266 		subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
267 	const unsigned long stream_cnt = subgroup_cnt_arg * streams_per_subgroup_cnt_arg;
268 	struct bt_bap_broadcast_source_param create_param;
269 	int err;
270 
271 	if (stream_cnt > ARRAY_SIZE(stream_params)) {
272 		printk("Unable to create broadcast source with %lu subgroups with %lu streams each "
273 		       "(%lu total)\n",
274 		       subgroup_cnt_arg, streams_per_subgroup_cnt_arg, stream_cnt);
275 		return -ENOMEM;
276 	}
277 
278 	(void)memset(broadcast_source_streams, 0,
279 		     sizeof(broadcast_source_streams));
280 
281 	for (size_t i = 0; i < stream_cnt; i++) {
282 		stream_params[i].stream =
283 			bap_stream_from_audio_test_stream(&broadcast_source_streams[i]);
284 		bt_bap_stream_cb_register(stream_params[i].stream,
285 					    &stream_ops);
286 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
287 		stream_params[i].data_len = ARRAY_SIZE(bis_codec_data);
288 		stream_params[i].data = bis_codec_data;
289 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
290 	}
291 
292 	for (size_t i = 0U; i < subgroup_cnt_arg; i++) {
293 		subgroup_params[i].params_count = streams_per_subgroup_cnt_arg;
294 		subgroup_params[i].params = &stream_params[i * streams_per_subgroup_cnt_arg];
295 		subgroup_params[i].codec_cfg = codec_cfg;
296 	}
297 
298 	create_param.params_count = subgroup_cnt_arg;
299 	create_param.params = subgroup_params;
300 	create_param.qos = &preset_16_2_1.qos;
301 	create_param.packing = BT_ISO_PACKING_SEQUENTIAL;
302 	create_param.encryption = encryption;
303 	if (encryption) {
304 		memcpy(create_param.broadcast_code, BROADCAST_CODE, sizeof(BROADCAST_CODE));
305 	}
306 
307 	printk("Creating broadcast source with %lu subgroups and %lu streams\n", subgroup_cnt_arg,
308 	       stream_cnt);
309 	err = bt_bap_broadcast_source_create(&create_param, source);
310 	if (err != 0) {
311 		printk("Unable to create broadcast source: %d\n", err);
312 		return err;
313 	}
314 
315 	for (size_t i = 0U; i < stream_cnt; i++) {
316 		struct audio_test_stream *test_stream = &broadcast_source_streams[i];
317 
318 		test_stream->tx_sdu_size = preset_16_1_1.qos.sdu;
319 	}
320 
321 	return 0;
322 }
323 
test_broadcast_source_get_base(struct bt_bap_broadcast_source * source,struct net_buf_simple * base_buf)324 static void test_broadcast_source_get_base(struct bt_bap_broadcast_source *source,
325 					   struct net_buf_simple *base_buf)
326 {
327 	int err;
328 
329 	err = bt_bap_broadcast_source_get_base(source, base_buf);
330 	if (err != 0) {
331 		FAIL("Failed to get encoded BASE: %d\n", err);
332 		return;
333 	}
334 }
335 
setup_extended_adv(struct bt_bap_broadcast_source * source,struct bt_le_ext_adv ** adv)336 static int setup_extended_adv(struct bt_bap_broadcast_source *source, struct bt_le_ext_adv **adv)
337 {
338 	/* Broadcast Audio Streaming Endpoint advertising data */
339 	NET_BUF_SIMPLE_DEFINE(ad_buf, BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE);
340 	NET_BUF_SIMPLE_DEFINE(base_buf, 128);
341 	struct bt_data ext_ad;
342 	struct bt_data per_ad;
343 	uint32_t broadcast_id;
344 	int err;
345 
346 	setup_broadcast_adv(adv);
347 
348 	err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE);
349 	if (err) {
350 		printk("Unable to generate broadcast ID: %d\n", err);
351 		return err;
352 	}
353 
354 	/* Setup extended advertising data */
355 	net_buf_simple_add_le16(&ad_buf, BT_UUID_BROADCAST_AUDIO_VAL);
356 	net_buf_simple_add_le24(&ad_buf, broadcast_id);
357 	ext_ad.type = BT_DATA_SVC_DATA16;
358 	ext_ad.data_len = ad_buf.len;
359 	ext_ad.data = ad_buf.data;
360 	err = bt_le_ext_adv_set_data(*adv, &ext_ad, 1, NULL, 0);
361 	if (err != 0) {
362 		printk("Failed to set extended advertising data: %d\n", err);
363 		return err;
364 	}
365 
366 	/* Setup periodic advertising data */
367 	test_broadcast_source_get_base(source, &base_buf);
368 
369 	per_ad.type = BT_DATA_SVC_DATA16;
370 	per_ad.data_len = base_buf.len;
371 	per_ad.data = base_buf.data;
372 	err = bt_le_per_adv_set_data(*adv, &per_ad, 1);
373 	if (err != 0) {
374 		printk("Failed to set periodic advertising data: %d\n", err);
375 		return err;
376 	}
377 
378 	/* Start extended advertising */
379 	err = bt_le_ext_adv_start(*adv, BT_LE_EXT_ADV_START_DEFAULT);
380 	if (err) {
381 		printk("Failed to start extended advertising: %d\n", err);
382 		return err;
383 	}
384 
385 	/* Enable Periodic Advertising */
386 	err = bt_le_per_adv_start(*adv);
387 	if (err) {
388 		printk("Failed to enable periodic advertising: %d\n", err);
389 		return err;
390 	}
391 
392 	return 0;
393 }
394 
test_broadcast_source_reconfig(struct bt_bap_broadcast_source * source,struct bt_le_ext_adv * adv)395 static void test_broadcast_source_reconfig(struct bt_bap_broadcast_source *source,
396 					   struct bt_le_ext_adv *adv)
397 {
398 	struct bt_bap_broadcast_source_stream_param
399 		stream_params[ARRAY_SIZE(broadcast_source_streams)];
400 	struct bt_bap_broadcast_source_subgroup_param
401 		subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
402 	const unsigned long stream_cnt = subgroup_cnt_arg * streams_per_subgroup_cnt_arg;
403 	struct bt_bap_broadcast_source_param reconfig_param;
404 	NET_BUF_SIMPLE_DEFINE(base_buf, 128);
405 	struct bt_data per_ad;
406 	int err;
407 
408 	for (size_t i = 0; i < stream_cnt; i++) {
409 		stream_params[i].stream =
410 			bap_stream_from_audio_test_stream(&broadcast_source_streams[i]);
411 		stream_params[i].data_len = ARRAY_SIZE(bis_codec_data);
412 		stream_params[i].data = bis_codec_data;
413 	}
414 
415 	codec_cfg = &preset_16_1_1.codec_cfg;
416 	for (size_t i = 0U; i < subgroup_cnt_arg; i++) {
417 		subgroup_params[i].params_count = streams_per_subgroup_cnt_arg;
418 		subgroup_params[i].params = &stream_params[i * streams_per_subgroup_cnt_arg];
419 		subgroup_params[i].codec_cfg = codec_cfg; /* update the cfg 16_1_1 */
420 	}
421 
422 	reconfig_param.params_count = subgroup_cnt_arg;
423 	reconfig_param.params = subgroup_params;
424 	reconfig_param.qos = &preset_16_1_1.qos; /* update the QoS from 16_2_1 to 16_1_1 */
425 	reconfig_param.packing = BT_ISO_PACKING_SEQUENTIAL;
426 	reconfig_param.encryption = false;
427 
428 	printk("Reconfiguring broadcast source\n");
429 	err = bt_bap_broadcast_source_reconfig(source, &reconfig_param);
430 	if (err != 0) {
431 		FAIL("Unable to reconfigure broadcast source: %d\n", err);
432 		return;
433 	}
434 
435 	for (size_t i = 0U; i < stream_cnt; i++) {
436 		struct audio_test_stream *test_stream = &broadcast_source_streams[i];
437 
438 		test_stream->tx_sdu_size = preset_16_1_1.qos.sdu;
439 	}
440 
441 	/* Update the BASE */
442 	test_broadcast_source_get_base(source, &base_buf);
443 
444 	per_ad.type = BT_DATA_SVC_DATA16;
445 	per_ad.data_len = base_buf.len;
446 	per_ad.data = base_buf.data;
447 	err = bt_le_per_adv_set_data(adv, &per_ad, 1);
448 	if (err != 0) {
449 		FAIL("Failed to set periodic advertising data: %d\n", err);
450 	}
451 }
452 
test_broadcast_source_start(struct bt_bap_broadcast_source * source,struct bt_le_ext_adv * adv)453 static void test_broadcast_source_start(struct bt_bap_broadcast_source *source,
454 					struct bt_le_ext_adv *adv)
455 {
456 	const unsigned long stream_cnt = subgroup_cnt_arg * streams_per_subgroup_cnt_arg;
457 	int err;
458 
459 	printk("Starting broadcast source\n");
460 	err = bt_bap_broadcast_source_start(source, adv);
461 	if (err != 0) {
462 		FAIL("Unable to start broadcast source: %d\n", err);
463 		return;
464 	}
465 
466 	/* Wait for all to be started */
467 	printk("Waiting for %lu streams to be started\n", stream_cnt);
468 	for (size_t i = 0U; i < stream_cnt; i++) {
469 		k_sem_take(&sem_stream_started, K_FOREVER);
470 	}
471 
472 	WAIT_FOR_FLAG(flag_source_started);
473 }
474 
test_broadcast_source_update_metadata(struct bt_bap_broadcast_source * source,struct bt_le_ext_adv * adv)475 static void test_broadcast_source_update_metadata(struct bt_bap_broadcast_source *source,
476 						  struct bt_le_ext_adv *adv)
477 {
478 	uint8_t new_metadata[] = BT_AUDIO_CODEC_CFG_LC3_META(BT_AUDIO_CONTEXT_TYPE_ALERTS);
479 	struct bt_data per_ad;
480 	int err;
481 
482 	NET_BUF_SIMPLE_DEFINE(base_buf, 128);
483 
484 	printk("Updating metadata\n");
485 	err = bt_bap_broadcast_source_update_metadata(source, new_metadata,
486 						      ARRAY_SIZE(new_metadata));
487 	if (err != 0) {
488 		FAIL("Failed to update metadata broadcast source: %d\n", err);
489 		return;
490 	}
491 
492 	/* Get the new BASE */
493 	test_broadcast_source_get_base(source, &base_buf);
494 
495 	/* Update the periodic advertising data with the new BASE */
496 	per_ad.type = BT_DATA_SVC_DATA16;
497 	per_ad.data_len = base_buf.len;
498 	per_ad.data = base_buf.data;
499 	err = bt_le_per_adv_set_data(adv, &per_ad, 1);
500 	if (err != 0) {
501 		FAIL("Failed to set periodic advertising data: %d\n", err);
502 	}
503 }
504 
test_broadcast_source_stop(struct bt_bap_broadcast_source * source)505 static void test_broadcast_source_stop(struct bt_bap_broadcast_source *source)
506 {
507 	const unsigned long stream_cnt = subgroup_cnt_arg * streams_per_subgroup_cnt_arg;
508 	int err;
509 
510 	printk("Stopping broadcast source\n");
511 
512 	err = bt_bap_broadcast_source_stop(source);
513 	if (err != 0) {
514 		FAIL("Unable to stop broadcast source: %d\n", err);
515 		return;
516 	}
517 
518 	/* Wait for all to be stopped */
519 	printk("Waiting for %lu streams to be stopped\n", stream_cnt);
520 	for (size_t i = 0U; i < stream_cnt; i++) {
521 		k_sem_take(&sem_stream_stopped, K_FOREVER);
522 	}
523 
524 	WAIT_FOR_UNSET_FLAG(flag_source_started);
525 }
526 
test_broadcast_source_delete(struct bt_bap_broadcast_source * source)527 static void test_broadcast_source_delete(struct bt_bap_broadcast_source *source)
528 {
529 	int err;
530 
531 	printk("Deleting broadcast source\n");
532 
533 	err = bt_bap_broadcast_source_delete(source);
534 	if (err != 0) {
535 		FAIL("Unable to stop broadcast source: %d\n", err);
536 		return;
537 	}
538 }
539 
stop_extended_adv(struct bt_le_ext_adv * adv)540 static int stop_extended_adv(struct bt_le_ext_adv *adv)
541 {
542 	int err;
543 
544 	err = bt_le_per_adv_stop(adv);
545 	if (err) {
546 		printk("Failed to stop periodic advertising: %d\n", err);
547 		return err;
548 	}
549 
550 	err = bt_le_ext_adv_stop(adv);
551 	if (err) {
552 		printk("Failed to stop extended advertising: %d\n", err);
553 		return err;
554 	}
555 
556 	err = bt_le_ext_adv_delete(adv);
557 	if (err) {
558 		printk("Failed to delete extended advertising: %d\n", err);
559 		return err;
560 	}
561 
562 	return 0;
563 }
564 
init(void)565 static void init(void)
566 {
567 	static struct bt_bap_broadcast_source_cb broadcast_source_cb = {
568 		.started = source_started_cb,
569 		.stopped = source_stopped_cb,
570 	};
571 	int err;
572 
573 	err = bt_enable(NULL);
574 	if (err) {
575 		FAIL("Bluetooth init failed (err %d)\n", err);
576 		return;
577 	}
578 
579 	printk("Bluetooth initialized\n");
580 	bap_stream_tx_init();
581 
582 	err = bt_bap_broadcast_source_register_cb(&broadcast_source_cb);
583 	if (err != 0) {
584 		FAIL("Failed to register broadcast source callbacks (err %d)\n", err);
585 		return;
586 	}
587 }
588 
test_main(void)589 static void test_main(void)
590 {
591 	struct bt_bap_broadcast_source *source;
592 	struct bt_le_ext_adv *adv;
593 	int err;
594 
595 	init();
596 
597 	err = setup_broadcast_source(&source, false);
598 	if (err != 0) {
599 		FAIL("Unable to setup broadcast source: %d\n", err);
600 		return;
601 	}
602 
603 	err = setup_extended_adv(source, &adv);
604 	if (err != 0) {
605 		FAIL("Failed to setup extended advertising: %d\n", err);
606 		return;
607 	}
608 
609 	test_broadcast_source_start(source, adv);
610 
611 	/* Wait for other devices to have received data */
612 	backchannel_sync_wait_any();
613 
614 	/* Wait for other devices to let us know when we can stop the source */
615 	backchannel_sync_wait_any();
616 
617 	test_broadcast_source_stop(source);
618 
619 	test_broadcast_source_delete(source);
620 	source = NULL;
621 
622 	err = stop_extended_adv(adv);
623 	if (err != 0) {
624 		FAIL("Unable to stop extended advertising: %d\n", err);
625 		return;
626 	}
627 	adv = NULL;
628 
629 	/* Recreate broadcast source to verify that it's possible */
630 	printk("Recreating broadcast source\n");
631 	err = setup_broadcast_source(&source, false);
632 	if (err != 0) {
633 		FAIL("Unable to setup broadcast source: %d\n", err);
634 		return;
635 	}
636 
637 	printk("Deleting broadcast source\n");
638 	test_broadcast_source_delete(source);
639 	source = NULL;
640 
641 	PASS("Broadcast source passed\n");
642 }
643 
test_main_update(void)644 static void test_main_update(void)
645 {
646 	struct bt_bap_broadcast_source *source;
647 	struct bt_le_ext_adv *adv;
648 	int err;
649 
650 	init();
651 
652 	err = setup_broadcast_source(&source, false);
653 	if (err != 0) {
654 		FAIL("Unable to setup broadcast source: %d\n", err);
655 		return;
656 	}
657 
658 	err = setup_extended_adv(source, &adv);
659 	if (err != 0) {
660 		FAIL("Failed to setup extended advertising: %d\n", err);
661 		return;
662 	}
663 
664 	test_broadcast_source_reconfig(source, adv);
665 
666 	test_broadcast_source_start(source, adv);
667 
668 	/* Wait for other devices to have received data */
669 	backchannel_sync_wait_any();
670 
671 	/* Update metadata while streaming */
672 	test_broadcast_source_update_metadata(source, adv);
673 
674 	/* Wait for other devices to have received metadata update */
675 	backchannel_sync_wait_any();
676 
677 	/* Wait for other devices to let us know when we can stop the source */
678 	backchannel_sync_wait_any();
679 
680 	test_broadcast_source_stop(source);
681 
682 	test_broadcast_source_delete(source);
683 	source = NULL;
684 
685 	err = stop_extended_adv(adv);
686 	if (err != 0) {
687 		FAIL("Unable to stop extended advertising: %d\n", err);
688 		return;
689 	}
690 	adv = NULL;
691 
692 	PASS("Broadcast source passed\n");
693 }
694 
test_main_encrypted(void)695 static void test_main_encrypted(void)
696 {
697 	struct bt_bap_broadcast_source *source;
698 	struct bt_le_ext_adv *adv;
699 	int err;
700 
701 	init();
702 
703 	err = setup_broadcast_source(&source, true);
704 	if (err != 0) {
705 		FAIL("Unable to setup broadcast source: %d\n", err);
706 		return;
707 	}
708 
709 	err = setup_extended_adv(source, &adv);
710 	if (err != 0) {
711 		FAIL("Failed to setup extended advertising: %d\n", err);
712 		return;
713 	}
714 
715 	test_broadcast_source_start(source, adv);
716 
717 	/* Wait for other devices to have received data */
718 	backchannel_sync_wait_any();
719 
720 	/* Wait for other devices to let us know when we can stop the source */
721 	backchannel_sync_wait_any();
722 
723 	test_broadcast_source_stop(source);
724 
725 	test_broadcast_source_delete(source);
726 	source = NULL;
727 
728 	err = stop_extended_adv(adv);
729 	if (err != 0) {
730 		FAIL("Unable to stop extended advertising: %d\n", err);
731 		return;
732 	}
733 	adv = NULL;
734 
735 	PASS("Broadcast source encrypted passed\n");
736 }
737 
test_args(int argc,char * argv[])738 static void test_args(int argc, char *argv[])
739 {
740 	for (size_t argn = 0; argn < argc; argn++) {
741 		const char *arg = argv[argn];
742 
743 		if (strcmp(arg, "subgroup_cnt") == 0) {
744 			arg = argv[++argn];
745 			subgroup_cnt_arg = strtoul(arg, NULL, 10);
746 
747 			if (!IN_RANGE(subgroup_cnt_arg, 1,
748 				      CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT)) {
749 				FAIL("Invalid number of subgroups: %lu\n", subgroup_cnt_arg);
750 			}
751 		} else if (strcmp(arg, "streams_per_subgroup_cnt") == 0) {
752 			arg = argv[++argn];
753 			streams_per_subgroup_cnt_arg = strtoul(arg, NULL, 10);
754 
755 			if (!IN_RANGE(streams_per_subgroup_cnt_arg, 1,
756 				      CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT)) {
757 				FAIL("Invalid number of streams per subgroup: %lu\n",
758 				     streams_per_subgroup_cnt_arg);
759 			}
760 		} else if (strcmp(arg, "vs_codec") == 0) {
761 			codec_cfg = &vs_codec_cfg;
762 		} else if (strcmp(arg, "lc3_codec") == 0) {
763 			codec_cfg = &preset_16_2_1.codec_cfg;
764 		} else {
765 			FAIL("Invalid arg: %s\n", arg);
766 		}
767 	}
768 }
769 
770 static const struct bst_test_instance test_broadcast_source[] = {
771 	{
772 		.test_id = "broadcast_source",
773 		.test_pre_init_f = test_init,
774 		.test_tick_f = test_tick,
775 		.test_main_f = test_main,
776 		.test_args_f = test_args,
777 	},
778 	{
779 		.test_id = "broadcast_source_update",
780 		.test_pre_init_f = test_init,
781 		.test_tick_f = test_tick,
782 		.test_main_f = test_main_update,
783 		.test_args_f = test_args,
784 	},
785 	{
786 		.test_id = "broadcast_source_encrypted",
787 		.test_pre_init_f = test_init,
788 		.test_tick_f = test_tick,
789 		.test_main_f = test_main_encrypted,
790 		.test_args_f = test_args,
791 	},
792 	BSTEST_END_MARKER,
793 };
794 
test_broadcast_source_install(struct bst_test_list * tests)795 struct bst_test_list *test_broadcast_source_install(struct bst_test_list *tests)
796 {
797 	return bst_add_tests(tests, test_broadcast_source);
798 }
799 
800 #else /* CONFIG_BT_BAP_BROADCAST_SOURCE */
801 
test_broadcast_source_install(struct bst_test_list * tests)802 struct bst_test_list *test_broadcast_source_install(struct bst_test_list *tests)
803 {
804 	return tests;
805 }
806 
807 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
808