1 /*
2 * Copyright (c) 2021-2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <string.h>
12
13 #include <zephyr/autoconf.h>
14 #include <zephyr/autoconf.h>
15 #include <zephyr/bluetooth/addr.h>
16 #include <zephyr/bluetooth/audio/audio.h>
17 #include <zephyr/bluetooth/audio/bap.h>
18 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
19 #include <zephyr/bluetooth/audio/lc3.h>
20 #include <zephyr/bluetooth/audio/pacs.h>
21 #include <zephyr/bluetooth/bluetooth.h>
22 #include <zephyr/bluetooth/gap.h>
23 #include <zephyr/bluetooth/hci_types.h>
24 #include <zephyr/bluetooth/iso.h>
25 #include <zephyr/bluetooth/uuid.h>
26 #include <zephyr/kernel.h>
27 #include <zephyr/net_buf.h>
28 #include <zephyr/sys/byteorder.h>
29 #include <zephyr/sys/printk.h>
30 #include <zephyr/sys/util.h>
31 #include <zephyr/sys/util_macro.h>
32 #include <zephyr/toolchain.h>
33
34 #include "bap_common.h"
35 #include "bap_stream_rx.h"
36 #include "bstests.h"
37 #include "common.h"
38
39 #if defined(CONFIG_BT_BAP_BROADCAST_SINK)
40 extern enum bst_result_t bst_result;
41
42 CREATE_FLAG(flag_broadcaster_found);
43 CREATE_FLAG(flag_base_received);
44 CREATE_FLAG(flag_base_metadata_updated);
45 CREATE_FLAG(flag_pa_synced);
46 CREATE_FLAG(flag_syncable);
47 CREATE_FLAG(flag_pa_sync_lost);
48 CREATE_FLAG(flag_pa_request);
49 CREATE_FLAG(flag_bis_sync_requested);
50 CREATE_FLAG(flag_big_sync_mic_failure);
51 CREATE_FLAG(flag_sink_started);
52
53 static struct bt_bap_broadcast_sink *g_sink;
54 static size_t stream_sync_cnt;
55 static struct bt_le_scan_recv_info broadcaster_info;
56 static bt_addr_le_t broadcaster_addr;
57 static struct bt_le_per_adv_sync *pa_sync;
58 static uint32_t broadcaster_broadcast_id;
59 static struct audio_test_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
60 static struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_sink_streams)];
61 static uint32_t requested_bis_sync;
62 static struct bt_le_ext_adv *ext_adv;
63 static const struct bt_bap_scan_delegator_recv_state *req_recv_state;
64 static uint8_t recv_state_broadcast_code[BT_ISO_BROADCAST_CODE_SIZE];
65
66 #define SUPPORTED_CHAN_COUNTS BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1, 2)
67 #define SUPPORTED_MIN_OCTETS_PER_FRAME 30
68 #define SUPPORTED_MAX_OCTETS_PER_FRAME 155
69 #define SUPPORTED_MAX_FRAMES_PER_SDU 1
70
71 /* We support 1 or 2 channels, so the maximum SDU size we support will be 2 times the maximum frame
72 * size per frame we support
73 */
74 #define SUPPORTED_MAX_SDU_SIZE (2 * SUPPORTED_MAX_FRAMES_PER_SDU * SUPPORTED_MAX_OCTETS_PER_FRAME)
75
76 BUILD_ASSERT(CONFIG_BT_ISO_RX_MTU >= SUPPORTED_MAX_SDU_SIZE);
77
78 #define SUPPORTED_CONTEXTS (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)
79
80 static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3(
81 BT_AUDIO_CODEC_CAP_FREQ_ANY, BT_AUDIO_CODEC_CAP_DURATION_ANY, SUPPORTED_CHAN_COUNTS,
82 SUPPORTED_MIN_OCTETS_PER_FRAME, SUPPORTED_MAX_OCTETS_PER_FRAME,
83 SUPPORTED_MAX_FRAMES_PER_SDU, SUPPORTED_CONTEXTS);
84
85 static K_SEM_DEFINE(sem_stream_started, 0U, ARRAY_SIZE(streams));
86 static K_SEM_DEFINE(sem_stream_stopped, 0U, ARRAY_SIZE(streams));
87
88 /* Create a mask for the maximum BIS we can sync to using the number of streams
89 * we have. We add an additional 1 since the bis indexes start from 1 and not
90 * 0.
91 */
92 static const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(streams) + 1U);
93 static uint32_t bis_index_bitfield;
94
valid_base_subgroup(const struct bt_bap_base_subgroup * subgroup)95 static bool valid_base_subgroup(const struct bt_bap_base_subgroup *subgroup)
96 {
97 struct bt_audio_codec_cfg codec_cfg = {0};
98 enum bt_audio_location chan_allocation;
99 uint8_t frames_blocks_per_sdu;
100 size_t min_sdu_size_required;
101 uint16_t octets_per_frame;
102 uint8_t chan_cnt;
103 int ret;
104
105 ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &codec_cfg);
106 if (ret < 0) {
107 printk("Could not get subgroup codec_cfg: %d\n", ret);
108
109 return false;
110 }
111
112 ret = bt_audio_codec_cfg_get_freq(&codec_cfg);
113 if (ret >= 0) {
114 const int freq = bt_audio_codec_cfg_freq_to_freq_hz(ret);
115
116 if (freq < 0) {
117 printk("Invalid subgroup frequency value: %d (%d)\n", ret, freq);
118
119 return false;
120 }
121 } else {
122 printk("Could not get subgroup frequency: %d\n", ret);
123
124 return false;
125 }
126
127 ret = bt_audio_codec_cfg_get_frame_dur(&codec_cfg);
128 if (ret >= 0) {
129 const int frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret);
130
131 if (frame_duration_us < 0) {
132 printk("Invalid subgroup frame duration value: %d (%d)\n", ret,
133 frame_duration_us);
134
135 return false;
136 }
137 } else {
138 printk("Could not get subgroup frame duration: %d\n", ret);
139
140 return false;
141 }
142
143 ret = bt_audio_codec_cfg_get_chan_allocation(&codec_cfg, &chan_allocation, true);
144 if (ret == 0) {
145 chan_cnt = bt_audio_get_chan_count(chan_allocation);
146 } else {
147 FAIL("Could not get subgroup channel allocation: %d\n", ret);
148
149 return false;
150 }
151
152 if (chan_cnt == 0 || (BIT(chan_cnt - 1) & SUPPORTED_CHAN_COUNTS) == 0) {
153 printk("Unsupported channel count: %u\n", chan_cnt);
154
155 return false;
156 }
157
158 ret = bt_audio_codec_cfg_get_octets_per_frame(&codec_cfg);
159 if (ret > 0) {
160 octets_per_frame = (uint16_t)ret;
161 } else {
162 printk("Could not get subgroup octets per frame: %d\n", ret);
163
164 return false;
165 }
166
167 if (!IN_RANGE(octets_per_frame, SUPPORTED_MIN_OCTETS_PER_FRAME,
168 SUPPORTED_MAX_OCTETS_PER_FRAME)) {
169 printk("Unsupported octets per frame: %u\n", octets_per_frame);
170
171 return false;
172 }
173
174 ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(&codec_cfg, true);
175 if (ret > 0) {
176 frames_blocks_per_sdu = (uint8_t)ret;
177 } else {
178 FAIL("Could not get frame blocks per SDU: %d\n", ret);
179
180 return false;
181 }
182
183 /* An SDU can consist of X frame blocks, each with Y frames (one per channel) of size Z in
184 * them. The minimum SDU size required for this is X * Y * Z.
185 */
186 min_sdu_size_required = chan_cnt * octets_per_frame * frames_blocks_per_sdu;
187 if (min_sdu_size_required > SUPPORTED_MAX_SDU_SIZE) {
188 printk("With %zu channels and %u octets per frame and %u frames per block, SDUs "
189 "shall be at minimum %zu, we only support %d\n",
190 chan_cnt, octets_per_frame, frames_blocks_per_sdu, min_sdu_size_required,
191 SUPPORTED_MAX_SDU_SIZE);
192
193 return false;
194 }
195
196 return true;
197 }
198
base_subgroup_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)199 static bool base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
200 {
201 static uint8_t metadata[CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE];
202 static size_t metadata_size;
203 uint8_t *meta;
204 int ret;
205
206 ret = bt_bap_base_get_subgroup_codec_meta(subgroup, &meta);
207 if (ret < 0) {
208 FAIL("Could not get subgroup meta: %d\n", ret);
209 return false;
210 }
211
212 if (TEST_FLAG(flag_base_received) &&
213 ((size_t)ret != metadata_size || memcmp(meta, metadata, metadata_size) != 0)) {
214 printk("Metadata updated\n");
215 SET_FLAG(flag_base_metadata_updated);
216 }
217
218 metadata_size = (size_t)ret;
219 (void)memcpy(metadata, meta, metadata_size);
220
221 if (!valid_base_subgroup(subgroup)) {
222 printk("Invalid or unsupported subgroup\n");
223 return false;
224 }
225
226 return true;
227 }
228
base_recv_cb(struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base,size_t base_size)229 static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
230 size_t base_size)
231 {
232 uint32_t base_bis_index_bitfield = 0U;
233 int ret;
234
235 printk("Received BASE with %d subgroups from broadcast sink %p\n",
236 bt_bap_base_get_subgroup_count(base), sink);
237
238 ret = bt_bap_base_foreach_subgroup(base, base_subgroup_cb, NULL);
239 if (ret != 0) {
240 FAIL("Failed to parse subgroups: %d\n", ret);
241 return;
242 }
243
244 ret = bt_bap_base_get_bis_indexes(base, &base_bis_index_bitfield);
245 if (ret != 0) {
246 FAIL("Failed to BIS indexes: %d\n", ret);
247 return;
248 }
249
250 bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;
251
252 SET_FLAG(flag_base_received);
253 }
254
syncable_cb(struct bt_bap_broadcast_sink * sink,const struct bt_iso_biginfo * biginfo)255 static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo)
256 {
257 printk("Broadcast sink %p syncable with%s encryption\n",
258 sink, biginfo->encryption ? "" : "out");
259 SET_FLAG(flag_syncable);
260 }
261
broadcast_sink_started_cb(struct bt_bap_broadcast_sink * sink)262 static void broadcast_sink_started_cb(struct bt_bap_broadcast_sink *sink)
263 {
264 printk("Broadcast sink %p started\n", sink);
265 SET_FLAG(flag_sink_started);
266 }
267
broadcast_sink_stopped_cb(struct bt_bap_broadcast_sink * sink,uint8_t reason)268 static void broadcast_sink_stopped_cb(struct bt_bap_broadcast_sink *sink, uint8_t reason)
269 {
270 printk("Broadcast sink %p stopped with reason 0x%02X\n", sink, reason);
271 UNSET_FLAG(flag_sink_started);
272
273 if (reason == BT_HCI_ERR_TERM_DUE_TO_MIC_FAIL) {
274 SET_FLAG(flag_big_sync_mic_failure);
275 }
276 }
277
278 static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = {
279 .base_recv = base_recv_cb,
280 .syncable = syncable_cb,
281 .started = broadcast_sink_started_cb,
282 .stopped = broadcast_sink_stopped_cb,
283 };
284
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)285 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
286 {
287 const struct bt_le_scan_recv_info *info = user_data;
288 char le_addr[BT_ADDR_LE_STR_LEN];
289 struct bt_uuid_16 adv_uuid;
290 uint32_t broadcast_id;
291
292 if (TEST_FLAG(flag_broadcaster_found)) {
293 /* no-op*/
294 return false;
295 }
296
297 if (data->type != BT_DATA_SVC_DATA16) {
298 return true;
299 }
300
301 if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
302 return true;
303 }
304
305 if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
306 return true;
307 }
308
309 if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
310 return true;
311 }
312
313 broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
314
315 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
316
317 printk("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X\n", broadcast_id,
318 le_addr, info->sid);
319
320 SET_FLAG(flag_broadcaster_found);
321
322 /* Store info for PA sync parameters */
323 memcpy(&broadcaster_info, info, sizeof(broadcaster_info));
324 bt_addr_le_copy(&broadcaster_addr, info->addr);
325 broadcaster_broadcast_id = broadcast_id;
326
327 /* Stop parsing */
328 return false;
329 }
330
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)331 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad)
332 {
333 if (info->interval != 0U) {
334 bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info);
335 }
336 }
337
338 static struct bt_le_scan_cb bap_scan_cb = {
339 .recv = broadcast_scan_recv,
340 };
341
bap_pa_sync_synced_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)342 static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
343 struct bt_le_per_adv_sync_synced_info *info)
344 {
345 if (sync == pa_sync) {
346 printk("PA sync %p synced for broadcast sink with broadcast ID 0x%06X\n", sync,
347 broadcaster_broadcast_id);
348
349 SET_FLAG(flag_pa_synced);
350 }
351 }
352
bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)353 static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
354 const struct bt_le_per_adv_sync_term_info *info)
355 {
356 if (sync == pa_sync) {
357 printk("PA sync %p lost with reason %u\n", sync, info->reason);
358 pa_sync = NULL;
359
360 SET_FLAG(flag_pa_sync_lost);
361 }
362 }
363
364 static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = {
365 .synced = bap_pa_sync_synced_cb,
366 .term = bap_pa_sync_terminated_cb,
367 };
368
369 static struct bt_pacs_cap cap = {
370 .codec_cap = &codec_cap,
371 };
372
pa_sync_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state,bool past_avail,uint16_t pa_interval)373 static int pa_sync_req_cb(struct bt_conn *conn,
374 const struct bt_bap_scan_delegator_recv_state *recv_state,
375 bool past_avail, uint16_t pa_interval)
376 {
377 if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED ||
378 recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
379 /* Already syncing */
380 /* TODO: Terminate existing sync and then sync to new?*/
381 return -EALREADY;
382 }
383
384 req_recv_state = recv_state;
385
386 SET_FLAG(flag_pa_request);
387
388 return 0;
389 }
390
pa_sync_term_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state)391 static int pa_sync_term_req_cb(struct bt_conn *conn,
392 const struct bt_bap_scan_delegator_recv_state *recv_state)
393 {
394 if (pa_sync == NULL || recv_state->pa_sync_state == BT_BAP_PA_STATE_NOT_SYNCED) {
395 return -EALREADY;
396 }
397
398 req_recv_state = recv_state;
399
400 UNSET_FLAG(flag_pa_request);
401
402 return 0;
403 }
404
bis_sync_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state,const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])405 static int bis_sync_req_cb(struct bt_conn *conn,
406 const struct bt_bap_scan_delegator_recv_state *recv_state,
407 const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
408 {
409 req_recv_state = recv_state;
410
411 printk("BIS sync request received for %p: 0x%08x\n", recv_state, bis_sync_req[0]);
412 /* We only care about a single subgroup in this test */
413 requested_bis_sync = bis_sync_req[0];
414 broadcaster_broadcast_id = recv_state->broadcast_id;
415 if (bis_sync_req[0] != 0) {
416 SET_FLAG(flag_bis_sync_requested);
417 } else {
418 UNSET_FLAG(flag_bis_sync_requested);
419 }
420
421 return 0;
422 }
423
broadcast_code_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state,const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])424 static void broadcast_code_cb(struct bt_conn *conn,
425 const struct bt_bap_scan_delegator_recv_state *recv_state,
426 const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
427 {
428 req_recv_state = recv_state;
429
430 memcpy(recv_state_broadcast_code, broadcast_code, BT_ISO_BROADCAST_CODE_SIZE);
431 }
432
scanning_state_cb(struct bt_conn * conn,bool is_scanning)433 static void scanning_state_cb(struct bt_conn *conn, bool is_scanning)
434 {
435 printk("Assistant scanning %s\n", is_scanning ? "started" : "stopped");
436
437 }
438
439 static struct bt_bap_scan_delegator_cb scan_delegator_cbs = {
440 .scanning_state = scanning_state_cb,
441 .pa_sync_req = pa_sync_req_cb,
442 .pa_sync_term_req = pa_sync_term_req_cb,
443 .bis_sync_req = bis_sync_req_cb,
444 .broadcast_code = broadcast_code_cb,
445 };
446
validate_stream_codec_cfg(const struct bt_bap_stream * stream)447 static void validate_stream_codec_cfg(const struct bt_bap_stream *stream)
448 {
449 struct bt_audio_codec_cfg *codec_cfg = stream->codec_cfg;
450 enum bt_audio_location chan_allocation;
451 uint8_t frames_blocks_per_sdu;
452 size_t min_sdu_size_required;
453 uint16_t octets_per_frame;
454 uint8_t chan_cnt;
455 int ret;
456
457 ret = bt_audio_codec_cfg_get_freq(codec_cfg);
458 if (ret >= 0) {
459 const int freq = bt_audio_codec_cfg_freq_to_freq_hz(ret);
460
461 if (freq < 0) {
462 FAIL("Invalid frequency value: %d (%d)\n", ret, freq);
463
464 return;
465 }
466 } else {
467 FAIL("Could not get frequency: %d\n", ret);
468
469 return;
470 }
471
472 ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
473 if (ret >= 0) {
474 const int frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret);
475
476 if (frame_duration_us < 0) {
477 FAIL("Invalid frame duration value: %d (%d)\n", ret, frame_duration_us);
478
479 return;
480 }
481 } else {
482 FAIL("Could not get frame duration: %d\n", ret);
483
484 return;
485 }
486
487 /* The broadcast source sets the channel allocation in the BIS to
488 * BT_AUDIO_LOCATION_FRONT_LEFT
489 */
490 ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation, true);
491 if (ret == 0) {
492 if (chan_allocation != BT_AUDIO_LOCATION_FRONT_CENTER) {
493 FAIL("Unexpected channel allocation: 0x%08X", chan_allocation);
494
495 return;
496 }
497
498 chan_cnt = bt_audio_get_chan_count(chan_allocation);
499 } else {
500 FAIL("Could not get subgroup channel allocation: %d\n", ret);
501
502 return;
503 }
504
505 if (chan_cnt == 0 || (BIT(chan_cnt - 1) & SUPPORTED_CHAN_COUNTS) == 0) {
506 FAIL("Unsupported channel count: %u\n", chan_cnt);
507
508 return;
509 }
510
511 ret = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg);
512 if (ret > 0) {
513 octets_per_frame = (uint16_t)ret;
514 } else {
515 FAIL("Could not get subgroup octets per frame: %d\n", ret);
516
517 return;
518 }
519
520 if (!IN_RANGE(octets_per_frame, SUPPORTED_MIN_OCTETS_PER_FRAME,
521 SUPPORTED_MAX_OCTETS_PER_FRAME)) {
522 FAIL("Unsupported octets per frame: %u\n", octets_per_frame);
523
524 return;
525 }
526
527 ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true);
528 if (ret > 0) {
529 frames_blocks_per_sdu = (uint8_t)ret;
530 } else {
531 FAIL("Could not get frame blocks per SDU: %d\n", ret);
532 return;
533 }
534
535 /* An SDU can consist of X frame blocks, each with Y frames (one per channel) of size Z in
536 * them. The minimum SDU size required for this is X * Y * Z.
537 */
538 min_sdu_size_required = chan_cnt * octets_per_frame * frames_blocks_per_sdu;
539 if (min_sdu_size_required > stream->qos->sdu) {
540 FAIL("With %zu channels and %u octets per frame and %u frames per block, SDUs "
541 "shall be at minimum %zu, but the stream has been configured for %u\n",
542 chan_cnt, octets_per_frame, frames_blocks_per_sdu, min_sdu_size_required,
543 stream->qos->sdu);
544
545 return;
546 }
547 }
548
stream_started_cb(struct bt_bap_stream * stream)549 static void stream_started_cb(struct bt_bap_stream *stream)
550 {
551 struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
552 struct bt_bap_ep_info info;
553 int err;
554
555 memset(&test_stream->last_info, 0, sizeof(test_stream->last_info));
556 test_stream->rx_cnt = 0U;
557
558 err = bt_bap_ep_get_info(stream->ep, &info);
559 if (err != 0) {
560 FAIL("Failed to get EP info: %d\n", err);
561 return;
562 }
563
564 if (info.state != BT_BAP_EP_STATE_STREAMING) {
565 FAIL("Unexpected EP state: %d\n", info.state);
566 return;
567 }
568
569 if (info.dir != BT_AUDIO_DIR_SINK) {
570 FAIL("Unexpected info.dir: %d\n", info.dir);
571 return;
572 }
573
574 if (info.can_send) {
575 FAIL("info.can_send is true\n");
576 return;
577 }
578
579 if (!info.can_recv) {
580 FAIL("info.can_recv is false\n");
581 return;
582 }
583
584 if (info.paired_ep != NULL) {
585 FAIL("Unexpected info.paired_ep: %p\n", info.paired_ep);
586 return;
587 }
588
589 printk("Stream %p started\n", stream);
590 k_sem_give(&sem_stream_started);
591
592 validate_stream_codec_cfg(stream);
593 }
594
stream_stopped_cb(struct bt_bap_stream * stream,uint8_t reason)595 static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
596 {
597 printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
598 k_sem_give(&sem_stream_stopped);
599 }
600
601 static struct bt_bap_stream_ops stream_ops = {
602 .started = stream_started_cb,
603 .stopped = stream_stopped_cb,
604 .recv = bap_stream_rx_recv_cb,
605 };
606
init(void)607 static int init(void)
608 {
609 int err;
610
611 err = bt_enable(NULL);
612 if (err) {
613 FAIL("Bluetooth enable failed (err %d)\n", err);
614 return err;
615 }
616
617 printk("Bluetooth initialized\n");
618
619 err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap);
620 if (err) {
621 FAIL("Capability register failed (err %d)\n", err);
622 return err;
623 }
624
625 err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
626 if (err) {
627 FAIL("Scan delegator register failed (err %d)\n", err);
628 return err;
629 }
630
631 /* Test invalid input */
632 err = bt_bap_broadcast_sink_register_cb(NULL);
633 if (err == 0) {
634 FAIL("bt_bap_broadcast_sink_register_cb did not fail with NULL cb\n");
635 return err;
636 }
637
638 err = bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
639 if (err != 0) {
640 FAIL("Sink callback register failed (err %d)\n", err);
641 return err;
642 }
643
644 bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
645 bt_le_scan_cb_register(&bap_scan_cb);
646
647 UNSET_FLAG(flag_broadcaster_found);
648 UNSET_FLAG(flag_base_received);
649 UNSET_FLAG(flag_pa_synced);
650
651 for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
652 streams[i] = bap_stream_from_audio_test_stream(&broadcast_sink_streams[i]);
653 bt_bap_stream_cb_register(streams[i], &stream_ops);
654 }
655
656 return 0;
657 }
658
pa_sync_create(void)659 static int pa_sync_create(void)
660 {
661 struct bt_le_per_adv_sync_param create_params = {0};
662
663 bt_addr_le_copy(&create_params.addr, &broadcaster_addr);
664 create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE;
665 create_params.sid = broadcaster_info.sid;
666 create_params.skip = PA_SYNC_SKIP;
667 create_params.timeout = interval_to_sync_timeout(broadcaster_info.interval);
668
669 return bt_le_per_adv_sync_create(&create_params, &pa_sync);
670 }
test_pa_sync_delete(void)671 static void test_pa_sync_delete(void)
672 {
673 int err;
674
675 err = bt_le_per_adv_sync_delete(pa_sync);
676 if (err != 0) {
677 FAIL("Unable to stop sink: %d", err);
678 return;
679 }
680
681 pa_sync = NULL;
682 }
683
test_scan_and_pa_sync(void)684 static void test_scan_and_pa_sync(void)
685 {
686 int err;
687
688 printk("Scanning for broadcast sources\n");
689 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
690 if (err != 0) {
691 FAIL("Unable to start scan for broadcast sources: %d", err);
692 return;
693 }
694
695 WAIT_FOR_FLAG(flag_broadcaster_found);
696
697 printk("Broadcast source found, stopping scan\n");
698 err = bt_le_scan_stop();
699 if (err != 0) {
700 FAIL("bt_le_scan_stop failed with %d\n", err);
701 return;
702 }
703
704 printk("Scan stopped, attempting to PA sync to the broadcaster with id 0x%06X\n",
705 broadcaster_broadcast_id);
706 err = pa_sync_create();
707 if (err != 0) {
708 FAIL("Could not create Broadcast PA sync: %d\n", err);
709 return;
710 }
711
712 printk("Waiting for PA sync\n");
713 WAIT_FOR_FLAG(flag_pa_synced);
714 }
715
test_broadcast_sink_create(void)716 static void test_broadcast_sink_create(void)
717 {
718 int err;
719
720 printk("Creating the broadcast sink\n");
721 err = bt_bap_broadcast_sink_create(pa_sync, broadcaster_broadcast_id, &g_sink);
722 if (err != 0) {
723 FAIL("Unable to create the sink: %d\n", err);
724 return;
725 }
726
727 printk("Created broadcast sink %p\n", g_sink);
728 }
729
test_broadcast_sink_create_inval(void)730 static void test_broadcast_sink_create_inval(void)
731 {
732 int err;
733
734 err = bt_bap_broadcast_sink_create(NULL, broadcaster_broadcast_id, &g_sink);
735 if (err == 0) {
736 FAIL("bt_bap_broadcast_sink_create did not fail with NULL sink\n");
737 return;
738 }
739
740 err = bt_bap_broadcast_sink_create(pa_sync, BT_BAP_INVALID_BROADCAST_ID, &g_sink);
741 if (err == 0) {
742 FAIL("bt_bap_broadcast_sink_create did not fail with invalid broadcast ID\n");
743 return;
744 }
745
746 err = bt_bap_broadcast_sink_create(pa_sync, broadcaster_broadcast_id, NULL);
747 if (err == 0) {
748 FAIL("bt_bap_broadcast_sink_create did not fail with NULL sink\n");
749 return;
750 }
751 }
752
test_broadcast_sync(const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])753 static void test_broadcast_sync(const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
754 {
755 int err;
756
757 printk("Syncing sink %p\n", g_sink);
758 err = bt_bap_broadcast_sink_sync(g_sink, bis_index_bitfield, streams, broadcast_code);
759 if (err != 0) {
760 FAIL("Unable to sync the sink: %d\n", err);
761 return;
762 }
763
764 stream_sync_cnt = POPCOUNT(bis_index_bitfield);
765 }
766
test_broadcast_sync_inval(void)767 static void test_broadcast_sync_inval(void)
768 {
769 struct bt_bap_stream *tmp_streams[ARRAY_SIZE(streams) + 1] = {0};
770 uint32_t bis_index;
771 int err;
772
773 err = bt_bap_broadcast_sink_sync(NULL, bis_index_bitfield, streams, NULL);
774 if (err == 0) {
775 FAIL("bt_bap_broadcast_sink_sync did not fail with NULL sink\n");
776 return;
777 }
778
779 bis_index = 0;
780 err = bt_bap_broadcast_sink_sync(g_sink, bis_index, streams, NULL);
781 if (err == 0) {
782 FAIL("bt_bap_broadcast_sink_sync did not fail with invalid BIS indexes: 0x%08X\n",
783 bis_index);
784 return;
785 }
786
787 bis_index = BT_ISO_BIS_INDEX_BIT(BT_ISO_BIS_INDEX_MAX + 1);
788 err = bt_bap_broadcast_sink_sync(g_sink, bis_index, streams, NULL);
789 if (err == 0) {
790 FAIL("bt_bap_broadcast_sink_sync did not fail with invalid BIS indexes: 0x%08X\n",
791 bis_index);
792 return;
793 }
794
795 err = bt_bap_broadcast_sink_sync(g_sink, bis_index, NULL, NULL);
796 if (err == 0) {
797 FAIL("bt_bap_broadcast_sink_sync did not fail with NULL streams\n");
798 return;
799 }
800
801 memcpy(tmp_streams, streams, sizeof(streams));
802 bis_index = 0U;
803 for (size_t i = 0U; i < ARRAY_SIZE(tmp_streams); i++) {
804 bis_index |= BT_ISO_BIS_INDEX_BIT(i);
805 }
806
807 err = bt_bap_broadcast_sink_sync(g_sink, bis_index, tmp_streams, NULL);
808 if (err == 0) {
809 FAIL("bt_bap_broadcast_sink_sync did not fail with NULL streams[%zu]\n",
810 ARRAY_SIZE(tmp_streams) - 1);
811 return;
812 }
813
814 bis_index = 0U;
815 for (size_t i = 0U; i < CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT + 1; i++) {
816 bis_index |= BT_ISO_BIS_INDEX_BIT(i);
817 }
818
819 err = bt_bap_broadcast_sink_sync(g_sink, bis_index, tmp_streams, NULL);
820 if (err == 0) {
821 FAIL("bt_bap_broadcast_sink_sync did not fail with invalid BIS indexes: 0x%08X\n",
822 bis_index);
823 return;
824 }
825 }
826
test_broadcast_stop(void)827 static void test_broadcast_stop(void)
828 {
829 int err;
830
831 printk("Stopping broadcast sink %p\n", g_sink);
832
833 err = bt_bap_broadcast_sink_stop(g_sink);
834 if (err != 0) {
835 FAIL("Unable to stop sink: %d", err);
836 return;
837 }
838
839 printk("Waiting for %zu streams to be stopped\n", stream_sync_cnt);
840 for (size_t i = 0U; i < stream_sync_cnt; i++) {
841 k_sem_take(&sem_stream_stopped, K_FOREVER);
842 }
843
844 WAIT_FOR_UNSET_FLAG(flag_sink_started);
845 }
846
test_broadcast_stop_inval(void)847 static void test_broadcast_stop_inval(void)
848 {
849 int err;
850
851 err = bt_bap_broadcast_sink_stop(NULL);
852 if (err == 0) {
853 FAIL("bt_bap_broadcast_sink_stop did not fail with NULL sink\n");
854 return;
855 }
856 }
857
test_broadcast_delete(void)858 static void test_broadcast_delete(void)
859 {
860 int err;
861
862 err = bt_bap_broadcast_sink_delete(g_sink);
863 if (err != 0) {
864 FAIL("Unable to stop sink: %d", err);
865 return;
866 }
867
868 /* No "sync lost" event is generated when we initialized the disconnect */
869 g_sink = NULL;
870 }
871
test_broadcast_delete_inval(void)872 static void test_broadcast_delete_inval(void)
873 {
874 int err;
875
876 err = bt_bap_broadcast_sink_delete(NULL);
877 if (err == 0) {
878 FAIL("bt_bap_broadcast_sink_delete did not fail with NULL sink\n");
879 return;
880 }
881 }
882
test_start_adv(void)883 static void test_start_adv(void)
884 {
885 const struct bt_data ad[] = {
886 BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
887 BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL),
888 BT_UUID_16_ENCODE(BT_UUID_PACS_VAL)),
889 BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL)),
890 };
891 int err;
892
893 /* Create a connectable advertising set */
894 err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN, NULL, &ext_adv);
895 if (err != 0) {
896 FAIL("Failed to create advertising set (err %d)\n", err);
897
898 return;
899 }
900
901 err = bt_le_ext_adv_set_data(ext_adv, ad, ARRAY_SIZE(ad), NULL, 0);
902 if (err != 0) {
903 FAIL("Failed to set advertising data (err %d)\n", err);
904
905 return;
906 }
907
908 err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
909 if (err != 0) {
910 FAIL("Failed to start advertising set (err %d)\n", err);
911
912 return;
913 }
914 }
915
test_common(void)916 static void test_common(void)
917 {
918 int err;
919
920 err = init();
921 if (err) {
922 FAIL("Init failed (err %d)\n", err);
923 return;
924 }
925
926 test_scan_and_pa_sync();
927
928 test_broadcast_sink_create_inval();
929 test_broadcast_sink_create();
930
931 printk("Broadcast source PA synced, waiting for BASE\n");
932 WAIT_FOR_FLAG(flag_base_received);
933 printk("BASE received\n");
934
935 printk("Waiting for BIG syncable\n");
936 WAIT_FOR_FLAG(flag_syncable);
937
938 test_broadcast_sync_inval();
939 test_broadcast_sync(NULL);
940
941 WAIT_FOR_FLAG(flag_sink_started);
942
943 /* Wait for all to be started */
944 printk("Waiting for %zu streams to be started\n", stream_sync_cnt);
945 for (size_t i = 0U; i < stream_sync_cnt; i++) {
946 k_sem_take(&sem_stream_started, K_FOREVER);
947 }
948
949 printk("Waiting for data\n");
950 WAIT_FOR_FLAG(flag_audio_received);
951 backchannel_sync_send_all(); /* let other devices know we have received what we wanted */
952
953 /* Ensure that we also see the metadata update */
954 printk("Waiting for metadata update\n");
955 WAIT_FOR_FLAG(flag_base_metadata_updated)
956
957 backchannel_sync_send_all(); /* let other devices know we have received what we wanted */
958 }
959
test_main(void)960 static void test_main(void)
961 {
962 test_common();
963
964 backchannel_sync_send_all(); /* let the broadcast source know it can stop */
965
966 /* The order of PA sync lost and BIG Sync lost is irrelevant
967 * and depend on timeout parameters. We just wait for PA first, but
968 * either way will work.
969 */
970 printk("Waiting for PA disconnected\n");
971 WAIT_FOR_FLAG(flag_pa_sync_lost);
972
973 printk("Waiting for %zu streams to be stopped\n", stream_sync_cnt);
974 for (size_t i = 0U; i < stream_sync_cnt; i++) {
975 k_sem_take(&sem_stream_stopped, K_FOREVER);
976 }
977 WAIT_FOR_UNSET_FLAG(flag_sink_started);
978
979 PASS("Broadcast sink passed\n");
980 }
981
test_sink_disconnect(void)982 static void test_sink_disconnect(void)
983 {
984 test_common();
985
986 test_broadcast_stop_inval();
987 test_broadcast_stop();
988
989 /* Retry sync*/
990 test_broadcast_sync(NULL);
991
992 WAIT_FOR_FLAG(flag_sink_started);
993
994 /* Wait for all to be started */
995 printk("Waiting for %zu streams to be started\n", stream_sync_cnt);
996 for (size_t i = 0U; i < stream_sync_cnt; i++) {
997 k_sem_take(&sem_stream_started, K_FOREVER);
998 }
999
1000 test_broadcast_stop();
1001
1002 test_broadcast_delete_inval();
1003 test_broadcast_delete();
1004
1005 backchannel_sync_send_all(); /* let the broadcast source know it can stop */
1006
1007 PASS("Broadcast sink disconnect passed\n");
1008 }
1009
test_sink_encrypted(void)1010 static void test_sink_encrypted(void)
1011 {
1012 int err;
1013
1014 err = init();
1015 if (err) {
1016 FAIL("Init failed (err %d)\n", err);
1017 return;
1018 }
1019
1020 test_scan_and_pa_sync();
1021
1022 test_broadcast_sink_create();
1023
1024 printk("Broadcast source PA synced, waiting for BASE\n");
1025 WAIT_FOR_FLAG(flag_base_received);
1026 printk("BASE received\n");
1027
1028 printk("Waiting for BIG syncable\n");
1029 WAIT_FOR_FLAG(flag_syncable);
1030
1031 test_broadcast_sync(BROADCAST_CODE);
1032
1033 WAIT_FOR_FLAG(flag_sink_started);
1034
1035 /* Wait for all to be started */
1036 printk("Waiting for %zu streams to be started\n", stream_sync_cnt);
1037 for (size_t i = 0U; i < stream_sync_cnt; i++) {
1038 k_sem_take(&sem_stream_started, K_FOREVER);
1039 }
1040
1041 printk("Waiting for data\n");
1042 WAIT_FOR_FLAG(flag_audio_received);
1043
1044 backchannel_sync_send_all(); /* let other devices know we have received data */
1045
1046 backchannel_sync_send_all(); /* let the broadcast source know it can stop */
1047
1048 /* The order of PA sync lost and BIG Sync lost is irrelevant
1049 * and depend on timeout parameters. We just wait for PA first, but
1050 * either way will work.
1051 */
1052 printk("Waiting for PA disconnected\n");
1053 WAIT_FOR_FLAG(flag_pa_sync_lost);
1054
1055 printk("Waiting for %zu streams to be stopped\n", stream_sync_cnt);
1056 for (size_t i = 0U; i < stream_sync_cnt; i++) {
1057 k_sem_take(&sem_stream_stopped, K_FOREVER);
1058 }
1059
1060 PASS("Broadcast sink encrypted passed\n");
1061 }
1062
test_sink_encrypted_incorrect_code(void)1063 static void test_sink_encrypted_incorrect_code(void)
1064 {
1065 int err;
1066
1067 err = init();
1068 if (err) {
1069 FAIL("Init failed (err %d)\n", err);
1070 return;
1071 }
1072
1073 test_scan_and_pa_sync();
1074
1075 test_broadcast_sink_create();
1076
1077 printk("Broadcast source PA synced, waiting for BASE\n");
1078 WAIT_FOR_FLAG(flag_base_received);
1079 printk("BASE received\n");
1080
1081 printk("Waiting for BIG syncable\n");
1082 WAIT_FOR_FLAG(flag_syncable);
1083
1084 test_broadcast_sync(INCORRECT_BROADCAST_CODE);
1085 /* Wait for MIC failure */
1086 WAIT_FOR_FLAG(flag_big_sync_mic_failure);
1087
1088 test_broadcast_sync(BROADCAST_CODE);
1089
1090 /* Wait for all to be started */
1091 printk("Waiting for %zu streams to be started\n", stream_sync_cnt);
1092 for (size_t i = 0U; i < stream_sync_cnt; i++) {
1093 k_sem_take(&sem_stream_started, K_FOREVER);
1094 }
1095
1096 printk("Waiting for data\n");
1097 WAIT_FOR_FLAG(flag_audio_received);
1098 printk("Data received\n");
1099
1100 backchannel_sync_send_all(); /* let other devices know we have received data */
1101 backchannel_sync_send_all(); /* let the broadcast source know it can stop */
1102
1103 PASS("Broadcast sink incorrect code passed\n");
1104 }
1105
broadcast_sink_with_assistant(void)1106 static void broadcast_sink_with_assistant(void)
1107 {
1108 int err;
1109
1110 err = init();
1111 if (err) {
1112 FAIL("Init failed (err %d)\n", err);
1113 return;
1114 }
1115
1116 test_start_adv();
1117 WAIT_FOR_FLAG(flag_connected);
1118
1119 printk("Waiting for PA sync request\n");
1120 WAIT_FOR_FLAG(flag_pa_request);
1121
1122 test_scan_and_pa_sync();
1123 test_broadcast_sink_create();
1124
1125 printk("Broadcast source PA synced, waiting for BASE\n");
1126 WAIT_FOR_FLAG(flag_base_received);
1127 printk("BASE received\n");
1128
1129 printk("Waiting for BIG syncable\n");
1130 WAIT_FOR_FLAG(flag_syncable);
1131
1132 printk("Waiting for BIG sync request\n");
1133 WAIT_FOR_FLAG(flag_bis_sync_requested);
1134 test_broadcast_sync(NULL);
1135
1136 WAIT_FOR_FLAG(flag_sink_started);
1137
1138 /* Wait for all to be started */
1139 printk("Waiting for %zu streams to be started\n", stream_sync_cnt);
1140 for (size_t i = 0U; i < stream_sync_cnt; i++) {
1141 k_sem_take(&sem_stream_started, K_FOREVER);
1142 }
1143
1144 printk("Waiting for data\n");
1145 WAIT_FOR_FLAG(flag_audio_received);
1146 backchannel_sync_send_all(); /* let other devices know we have received what we wanted */
1147
1148 /* Ensure that we also see the metadata update */
1149 printk("Waiting for metadata update\n");
1150 WAIT_FOR_FLAG(flag_base_metadata_updated)
1151 backchannel_sync_send_all(); /* let other devices know we have received what we wanted */
1152
1153 printk("Waiting for BIG sync terminate request\n");
1154 WAIT_FOR_UNSET_FLAG(flag_bis_sync_requested);
1155 test_broadcast_stop();
1156
1157 printk("Waiting for PA sync terminate request\n");
1158 WAIT_FOR_UNSET_FLAG(flag_pa_request);
1159 test_pa_sync_delete();
1160 test_broadcast_delete();
1161
1162 backchannel_sync_send_all(); /* let the broadcast source know it can stop */
1163
1164 PASS("Broadcast sink with assistant passed\n");
1165 }
1166
broadcast_sink_with_assistant_incorrect_code(void)1167 static void broadcast_sink_with_assistant_incorrect_code(void)
1168 {
1169 int err;
1170
1171 err = init();
1172 if (err) {
1173 FAIL("Init failed (err %d)\n", err);
1174 return;
1175 }
1176
1177 test_start_adv();
1178 WAIT_FOR_FLAG(flag_connected);
1179
1180 printk("Waiting for PA sync request\n");
1181 WAIT_FOR_FLAG(flag_pa_request);
1182
1183 test_scan_and_pa_sync();
1184 test_broadcast_sink_create();
1185
1186 printk("Broadcast source PA synced, waiting for BASE\n");
1187 WAIT_FOR_FLAG(flag_base_received);
1188 printk("BASE received\n");
1189
1190 printk("Waiting for BIG syncable\n");
1191 WAIT_FOR_FLAG(flag_syncable);
1192
1193 printk("Waiting for BIG sync request\n");
1194 WAIT_FOR_FLAG(flag_bis_sync_requested);
1195 test_broadcast_sync(recv_state_broadcast_code);
1196 /* Wait for MIC failure */
1197 WAIT_FOR_FLAG(flag_big_sync_mic_failure);
1198
1199 backchannel_sync_send_all(); /* let other devices know we have received data */
1200
1201 printk("Waiting for PA sync terminate request\n");
1202 WAIT_FOR_UNSET_FLAG(flag_pa_request);
1203 test_pa_sync_delete();
1204 test_broadcast_delete();
1205
1206 backchannel_sync_send_all(); /* let the broadcast source know it can stop */
1207
1208 PASS("Broadcast sink with assistant and incorrect code passed\n");
1209 }
1210
1211 static const struct bst_test_instance test_broadcast_sink[] = {
1212 {
1213 .test_id = "broadcast_sink",
1214 .test_pre_init_f = test_init,
1215 .test_tick_f = test_tick,
1216 .test_main_f = test_main,
1217 },
1218 {
1219 .test_id = "broadcast_sink_disconnect",
1220 .test_pre_init_f = test_init,
1221 .test_tick_f = test_tick,
1222 .test_main_f = test_sink_disconnect,
1223 },
1224 {
1225 .test_id = "broadcast_sink_encrypted",
1226 .test_pre_init_f = test_init,
1227 .test_tick_f = test_tick,
1228 .test_main_f = test_sink_encrypted,
1229 },
1230 {
1231 .test_id = "broadcast_sink_encrypted_incorrect_code",
1232 .test_pre_init_f = test_init,
1233 .test_tick_f = test_tick,
1234 .test_main_f = test_sink_encrypted_incorrect_code,
1235 },
1236 {
1237 .test_id = "broadcast_sink_with_assistant",
1238 .test_pre_init_f = test_init,
1239 .test_tick_f = test_tick,
1240 .test_main_f = broadcast_sink_with_assistant,
1241 },
1242 {
1243 .test_id = "broadcast_sink_with_assistant_incorrect_code",
1244 .test_pre_init_f = test_init,
1245 .test_tick_f = test_tick,
1246 .test_main_f = broadcast_sink_with_assistant_incorrect_code,
1247 },
1248 BSTEST_END_MARKER,
1249 };
1250
test_broadcast_sink_install(struct bst_test_list * tests)1251 struct bst_test_list *test_broadcast_sink_install(struct bst_test_list *tests)
1252 {
1253 return bst_add_tests(tests, test_broadcast_sink);
1254 }
1255
1256 #else /* !CONFIG_BT_BAP_BROADCAST_SINK */
1257
test_broadcast_sink_install(struct bst_test_list * tests)1258 struct bst_test_list *test_broadcast_sink_install(struct bst_test_list *tests)
1259 {
1260 return tests;
1261 }
1262
1263 #endif /* CONFIG_BT_BAP_BROADCAST_SINK */
1264