1 /*
2 * Copyright (c) 2021-2025 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <stdbool.h>
9 #include <stdint.h>
10 #include <string.h>
11
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/audio/audio.h>
14 #include <zephyr/bluetooth/audio/bap.h>
15 #include <zephyr/bluetooth/addr.h>
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/gap.h>
18 #include <zephyr/bluetooth/gatt.h>
19 #include <zephyr/bluetooth/hci.h>
20 #include <zephyr/bluetooth/iso.h>
21 #include <zephyr/bluetooth/uuid.h>
22 #include <zephyr/net_buf.h>
23 #include <zephyr/sys/printk.h>
24 #include <zephyr/sys/util.h>
25 #include <zephyr/sys/util_macro.h>
26
27 #include "../../../../../subsys/bluetooth/host/hci_core.h"
28 #include "common.h"
29 #include "bap_common.h"
30 #include "bstests.h"
31 #include "syscalls/kernel.h"
32
33 #ifdef CONFIG_BT_BAP_BROADCAST_ASSISTANT
34
35 extern enum bst_result_t bst_result;
36
37 /* BASS variables */
38 static volatile uint32_t g_broadcast_id;
39 static volatile uint8_t g_recv_state_count;
40 static struct bt_bap_scan_delegator_recv_state recv_state;
41 CREATE_FLAG(flag_discovery_complete);
42 CREATE_FLAG(flag_write_complete);
43 CREATE_FLAG(flag_cb_called);
44 CREATE_FLAG(flag_broadcaster_found);
45 CREATE_FLAG(flag_pa_synced);
46 CREATE_FLAG(flag_pa_terminated);
47 CREATE_FLAG(flag_mtu_exchanged);
48 CREATE_FLAG(flag_recv_state_read);
49 CREATE_FLAG(flag_recv_state_updated);
50 CREATE_FLAG(flag_recv_state_updated_with_bis_sync);
51 CREATE_FLAG(flag_recv_state_removed);
52 CREATE_FLAG(flag_broadcast_code_requested);
53 CREATE_FLAG(flag_incorrect_broadcast_code);
54
55 /* Broadcaster variables */
56 static bt_addr_le_t g_broadcaster_addr;
57 static struct bt_le_scan_recv_info g_broadcaster_info;
58 static struct bt_le_per_adv_sync *g_pa_sync;
59
60 static uint8_t metadata[] = {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, LONG_META)};
61
phy2str(uint8_t phy)62 static const char *phy2str(uint8_t phy)
63 {
64 switch (phy) {
65 case 0: return "No packets";
66 case BT_GAP_LE_PHY_1M: return "LE 1M";
67 case BT_GAP_LE_PHY_2M: return "LE 2M";
68 case BT_GAP_LE_PHY_CODED: return "LE Coded";
69 default: return "Unknown";
70 }
71 }
72
bap_broadcast_assistant_discover_cb(struct bt_conn * conn,int err,uint8_t recv_state_count)73 static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err,
74 uint8_t recv_state_count)
75 {
76 if (err != 0) {
77 FAIL("BASS discover failed (%d)\n", err);
78 return;
79 }
80
81 printk("BASS discover done with %u recv states\n", recv_state_count);
82 g_recv_state_count = recv_state_count;
83 SET_FLAG(flag_discovery_complete);
84 }
85
bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info * info,uint32_t broadcast_id)86 static void bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info *info,
87 uint32_t broadcast_id)
88 {
89 char le_addr[BT_ADDR_LE_STR_LEN];
90
91 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
92 printk("Scan Recv: [DEVICE]: %s, broadcast_id 0x%06X, "
93 "interval (ms) %u), SID 0x%x, RSSI %i\n",
94 le_addr, broadcast_id, info->interval * 5 / 4,
95 info->sid, info->rssi);
96
97 (void)memcpy(&g_broadcaster_info, info, sizeof(g_broadcaster_info));
98 bt_addr_le_copy(&g_broadcaster_addr, info->addr);
99 g_broadcast_id = broadcast_id;
100 SET_FLAG(flag_broadcaster_found);
101 }
102
metadata_entry(struct bt_data * data,void * user_data)103 static bool metadata_entry(struct bt_data *data, void *user_data)
104 {
105 char metadata[CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE] = {0};
106
107 (void)bin2hex(data->data, data->data_len, metadata, sizeof(metadata));
108
109 printk("\t\tMetadata length %u, type %u, data: %s\n",
110 data->data_len, data->type, metadata);
111
112 return true;
113 }
114
bap_broadcast_assistant_recv_state_cb(struct bt_conn * conn,int err,const struct bt_bap_scan_delegator_recv_state * state)115 static void bap_broadcast_assistant_recv_state_cb(
116 struct bt_conn *conn, int err,
117 const struct bt_bap_scan_delegator_recv_state *state)
118 {
119 char le_addr[BT_ADDR_LE_STR_LEN];
120 char bad_code[BT_ISO_BROADCAST_CODE_SIZE * 2 + 1];
121
122 if (err != 0) {
123 FAIL("BASS recv state read failed (%d)\n", err);
124 return;
125 }
126
127 SET_FLAG(flag_recv_state_read);
128
129 if (state == NULL) {
130 /* Empty receive state */
131 return;
132 }
133
134 bt_addr_le_to_str(&state->addr, le_addr, sizeof(le_addr));
135 (void)bin2hex(state->bad_code, BT_ISO_BROADCAST_CODE_SIZE, bad_code, sizeof(bad_code));
136 printk("BASS recv state: src_id %u, addr %s, sid %u, sync_state %u, encrypt_state %u%s%s\n",
137 state->src_id, le_addr, state->adv_sid, state->pa_sync_state, state->encrypt_state,
138 state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE ? ", bad code: " : "",
139 state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE ? bad_code : "");
140
141 if (state->encrypt_state == BT_BAP_BIG_ENC_STATE_BCODE_REQ) {
142 SET_FLAG(flag_broadcast_code_requested);
143 } else if (state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
144 SET_FLAG(flag_incorrect_broadcast_code);
145 if (memcmp(state->bad_code, INCORRECT_BROADCAST_CODE, BT_ISO_BROADCAST_CODE_SIZE) !=
146 0) {
147 FAIL("Bad code is not what we sent\n");
148 return;
149 }
150
151 for (uint8_t i = 0; i < state->num_subgroups; i++) {
152 const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
153
154 if (subgroup->bis_sync != BT_BAP_BIS_SYNC_FAILED) {
155 FAIL("Invalid BIS sync value 0x%08X for failed sync\n",
156 subgroup->bis_sync);
157 return;
158 }
159 }
160 }
161
162 for (uint8_t i = 0; i < state->num_subgroups; i++) {
163 const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
164 struct net_buf_simple buf;
165
166 printk("\t[%d]: BIS sync %u, metadata_len %u\n",
167 i, subgroup->bis_sync, subgroup->metadata_len);
168
169 net_buf_simple_init_with_data(&buf, (void *)subgroup->metadata,
170 subgroup->metadata_len);
171 bt_data_parse(&buf, metadata_entry, NULL);
172
173 if (subgroup->bis_sync != 0) {
174 SET_FLAG(flag_recv_state_updated_with_bis_sync);
175 }
176 }
177
178 #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)
179 if (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
180 err = bt_le_per_adv_sync_transfer(g_pa_sync, conn,
181 BT_UUID_BASS_VAL);
182 if (err != 0) {
183 FAIL("Could not transfer periodic adv sync: %d\n", err);
184 return;
185 }
186 }
187 #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER */
188
189 memcpy(&recv_state, state, sizeof(recv_state));
190 SET_FLAG(flag_cb_called);
191 SET_FLAG(flag_recv_state_updated);
192 }
193
bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn * conn,uint8_t src_id)194 static void bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn *conn, uint8_t src_id)
195 {
196 printk("BASS recv state %u removed\n", src_id);
197 SET_FLAG(flag_cb_called);
198
199 SET_FLAG(flag_recv_state_removed);
200 }
201
bap_broadcast_assistant_scan_start_cb(struct bt_conn * conn,int err)202 static void bap_broadcast_assistant_scan_start_cb(struct bt_conn *conn, int err)
203 {
204 if (err != 0) {
205 FAIL("BASS scan start failed (%d)\n", err);
206 return;
207 }
208
209 printk("BASS scan start successful\n");
210 SET_FLAG(flag_write_complete);
211 }
212
bap_broadcast_assistant_scan_stop_cb(struct bt_conn * conn,int err)213 static void bap_broadcast_assistant_scan_stop_cb(struct bt_conn *conn, int err)
214 {
215 if (err != 0) {
216 FAIL("BASS scan stop failed (%d)\n", err);
217 return;
218 }
219
220 printk("BASS scan stop successful\n");
221 SET_FLAG(flag_write_complete);
222 }
223
bap_broadcast_assistant_add_src_cb(struct bt_conn * conn,int err)224 static void bap_broadcast_assistant_add_src_cb(struct bt_conn *conn, int err)
225 {
226 if (err != 0) {
227 FAIL("BASS add source failed (%d)\n", err);
228 return;
229 }
230
231 printk("BASS add source successful\n");
232 SET_FLAG(flag_write_complete);
233 }
234
bap_broadcast_assistant_mod_src_cb(struct bt_conn * conn,int err)235 static void bap_broadcast_assistant_mod_src_cb(struct bt_conn *conn, int err)
236 {
237 if (err != 0) {
238 FAIL("BASS modify source failed (%d)\n", err);
239 return;
240 }
241
242 printk("BASS modify source successful\n");
243 SET_FLAG(flag_write_complete);
244 }
245
bap_broadcast_assistant_broadcast_code_cb(struct bt_conn * conn,int err)246 static void bap_broadcast_assistant_broadcast_code_cb(struct bt_conn *conn, int err)
247 {
248 if (err != 0) {
249 FAIL("BASS broadcast code failed (%d)\n", err);
250 return;
251 }
252
253 printk("BASS broadcast code successful\n");
254 SET_FLAG(flag_write_complete);
255 }
256
bap_broadcast_assistant_rem_src_cb(struct bt_conn * conn,int err)257 static void bap_broadcast_assistant_rem_src_cb(struct bt_conn *conn, int err)
258 {
259 if (err != 0) {
260 FAIL("BASS remove source failed (%d)\n", err);
261 return;
262 }
263
264 printk("BASS remove source successful\n");
265 SET_FLAG(flag_write_complete);
266 }
267
268 static struct bt_bap_broadcast_assistant_cb broadcast_assistant_cbs = {
269 .discover = bap_broadcast_assistant_discover_cb,
270 .scan = bap_broadcast_assistant_scan_cb,
271 .recv_state = bap_broadcast_assistant_recv_state_cb,
272 .recv_state_removed = bap_broadcast_assistant_recv_state_removed_cb,
273 .scan_start = bap_broadcast_assistant_scan_start_cb,
274 .scan_stop = bap_broadcast_assistant_scan_stop_cb,
275 .add_src = bap_broadcast_assistant_add_src_cb,
276 .mod_src = bap_broadcast_assistant_mod_src_cb,
277 .broadcast_code = bap_broadcast_assistant_broadcast_code_cb,
278 .rem_src = bap_broadcast_assistant_rem_src_cb,
279 };
280
att_mtu_updated(struct bt_conn * conn,uint16_t tx,uint16_t rx)281 static void att_mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
282 {
283 SET_FLAG(flag_mtu_exchanged);
284 }
285
286 static struct bt_gatt_cb gatt_callbacks = {
287 .att_mtu_updated = att_mtu_updated,
288 };
289
sync_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)290 static void sync_cb(struct bt_le_per_adv_sync *sync,
291 struct bt_le_per_adv_sync_synced_info *info)
292 {
293 char le_addr[BT_ADDR_LE_STR_LEN];
294
295 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
296
297 printk("PER_ADV_SYNC[%u]: [DEVICE]: %s synced, "
298 "Interval 0x%04x (%u ms), PHY %s\n",
299 bt_le_per_adv_sync_get_index(sync), le_addr, info->interval,
300 info->interval * 5 / 4, phy2str(info->phy));
301
302 SET_FLAG(flag_pa_synced);
303 }
304
term_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)305 static void term_cb(struct bt_le_per_adv_sync *sync,
306 const struct bt_le_per_adv_sync_term_info *info)
307 {
308 char le_addr[BT_ADDR_LE_STR_LEN];
309
310 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
311
312 printk("PER_ADV_SYNC[%u]: [DEVICE]: %s sync terminated\n",
313 bt_le_per_adv_sync_get_index(sync), le_addr);
314
315 SET_FLAG(flag_pa_terminated);
316 }
317
318 static struct bt_le_per_adv_sync_cb sync_callbacks = {
319 .synced = sync_cb,
320 .term = term_cb,
321 };
322
test_exchange_mtu(void)323 static void test_exchange_mtu(void)
324 {
325 WAIT_FOR_FLAG(flag_mtu_exchanged);
326 printk("MTU exchanged\n");
327 }
328
test_bass_discover(void)329 static void test_bass_discover(void)
330 {
331 int err;
332
333 printk("Discovering BASS\n");
334 UNSET_FLAG(flag_discovery_complete);
335 err = bt_bap_broadcast_assistant_discover(default_conn);
336 if (err != 0) {
337 FAIL("Failed to discover BASS %d\n", err);
338 return;
339 }
340
341 WAIT_FOR_FLAG(flag_discovery_complete);
342
343 /* Verify that we can discover again */
344 UNSET_FLAG(flag_discovery_complete);
345 err = bt_bap_broadcast_assistant_discover(default_conn);
346 if (err != 0) {
347 FAIL("Failed to discover BASS for the second time: %d\n", err);
348 return;
349 }
350
351 WAIT_FOR_FLAG(flag_discovery_complete);
352 printk("Discovery complete\n");
353 }
354
test_bass_read_receive_states(void)355 static void test_bass_read_receive_states(void)
356 {
357 for (uint8_t i = 0U; i < g_recv_state_count; i++) {
358 int err;
359
360 UNSET_FLAG(flag_recv_state_read);
361 err = bt_bap_broadcast_assistant_read_recv_state(default_conn, i);
362 if (err != 0) {
363 FAIL("Failed to read receive state with idx %u: %d\n",
364 i, err);
365 return;
366 }
367
368 WAIT_FOR_FLAG(flag_recv_state_read);
369 }
370
371 printk("Receive state read complete\n");
372 }
373
test_bass_scan_start(void)374 static void test_bass_scan_start(void)
375 {
376 int err;
377
378 printk("Starting scan\n");
379 UNSET_FLAG(flag_write_complete);
380 err = bt_bap_broadcast_assistant_scan_start(default_conn, true);
381 if (err != 0) {
382 FAIL("Could not write scan start to BASS (err %d)\n", err);
383 return;
384 }
385
386 WAIT_FOR_FLAG(flag_write_complete);
387 WAIT_FOR_FLAG(flag_broadcaster_found);
388 printk("Scan started\n");
389 }
390
test_bass_scan_stop(void)391 static void test_bass_scan_stop(void)
392 {
393 int err;
394
395 printk("Stopping scan\n");
396 UNSET_FLAG(flag_write_complete);
397 err = bt_bap_broadcast_assistant_scan_stop(default_conn);
398 if (err != 0) {
399 FAIL("Could not write scan stop to BASS (err %d)\n", err);
400 return;
401 }
402
403 WAIT_FOR_FLAG(flag_write_complete);
404 printk("Scan stopped\n");
405 }
406
test_bass_create_pa_sync(void)407 static void test_bass_create_pa_sync(void)
408 {
409 int err;
410 struct bt_le_per_adv_sync_param sync_create_param = { 0 };
411
412 printk("Creating Periodic Advertising Sync...\n");
413 bt_addr_le_copy(&sync_create_param.addr, &g_broadcaster_addr);
414 sync_create_param.sid = g_broadcaster_info.sid;
415 sync_create_param.timeout = 0xa;
416 err = bt_le_per_adv_sync_create(&sync_create_param, &g_pa_sync);
417 if (err != 0) {
418 FAIL("Could not create PA syncs (err %d)\n", err);
419 return;
420 }
421
422 WAIT_FOR_FLAG(flag_pa_synced);
423 printk("PA synced\n");
424 }
425
test_bass_add_source(void)426 static void test_bass_add_source(void)
427 {
428 int err;
429 struct bt_bap_broadcast_assistant_add_src_param add_src_param = { 0 };
430 struct bt_bap_bass_subgroup subgroup = { 0 };
431
432 printk("Adding source\n");
433 UNSET_FLAG(flag_write_complete);
434 UNSET_FLAG(flag_cb_called);
435 bt_addr_le_copy(&add_src_param.addr, &g_broadcaster_addr);
436 add_src_param.adv_sid = g_broadcaster_info.sid;
437 add_src_param.num_subgroups = 1;
438 add_src_param.pa_interval = g_broadcaster_info.interval;
439 add_src_param.pa_sync = false;
440 add_src_param.broadcast_id = g_broadcast_id;
441 add_src_param.subgroups = &subgroup;
442 subgroup.bis_sync = 0;
443 subgroup.metadata_len = 0;
444 err = bt_bap_broadcast_assistant_add_src(default_conn, &add_src_param);
445 if (err != 0) {
446 FAIL("Could not add source (err %d)\n", err);
447 return;
448 }
449
450 WAIT_FOR_FLAG(flag_recv_state_updated);
451
452 if (!bt_addr_le_eq(&recv_state.addr, &add_src_param.addr)) {
453 char addr[BT_ADDR_LE_STR_LEN];
454 char expected_addr[BT_ADDR_LE_STR_LEN];
455
456 bt_addr_le_to_str(&recv_state.addr, addr, sizeof(addr));
457 bt_addr_le_to_str(&add_src_param.addr, expected_addr, sizeof(expected_addr));
458
459 FAIL("Unexpected addr %s != %s\n", addr, expected_addr);
460 return;
461 }
462
463 if (recv_state.adv_sid != add_src_param.adv_sid) {
464 FAIL("Unexpected SID: %u\n", recv_state.adv_sid);
465 return;
466 }
467
468 if (recv_state.pa_sync_state != BT_BAP_PA_STATE_NOT_SYNCED) {
469 FAIL("Unexpected PA sync state: %d\n", recv_state.pa_sync_state);
470 return;
471 }
472
473 if (recv_state.encrypt_state != BT_BAP_BIG_ENC_STATE_NO_ENC) {
474 FAIL("Unexpected BIG encryption state: %d\n", recv_state.pa_sync_state);
475 return;
476 }
477
478 if (recv_state.broadcast_id != add_src_param.broadcast_id) {
479 FAIL("Unexpected broadcast ID: 0x%06X != 0x%06X\n", recv_state.broadcast_id,
480 add_src_param.broadcast_id);
481 return;
482 }
483
484 if (recv_state.num_subgroups != add_src_param.num_subgroups) {
485 FAIL("Unexpected number of subgroups: %u\n", recv_state.num_subgroups);
486 return;
487 }
488
489 WAIT_FOR_FLAG(flag_cb_called);
490 WAIT_FOR_FLAG(flag_write_complete);
491
492 printk("Source added\n");
493 }
494
test_bass_mod_source(uint32_t bis_sync)495 static void test_bass_mod_source(uint32_t bis_sync)
496 {
497 int err;
498 struct bt_bap_broadcast_assistant_mod_src_param mod_src_param = { 0 };
499 struct bt_bap_bass_subgroup subgroup = {0};
500 uint32_t remote_bis_sync;
501
502 printk("Modify source\n");
503 UNSET_FLAG(flag_cb_called);
504 UNSET_FLAG(flag_write_complete);
505 UNSET_FLAG(flag_recv_state_updated);
506 mod_src_param.src_id = recv_state.src_id;
507 mod_src_param.num_subgroups = 1;
508 mod_src_param.pa_sync = true;
509 mod_src_param.subgroups = &subgroup;
510 mod_src_param.pa_interval = g_broadcaster_info.interval;
511 subgroup.bis_sync = bis_sync;
512
513 /* Leave metadata as is */
514 subgroup.metadata_len = recv_state.subgroups[0].metadata_len;
515 memcpy(subgroup.metadata, recv_state.subgroups[0].metadata, sizeof(metadata));
516
517 err = bt_bap_broadcast_assistant_mod_src(default_conn, &mod_src_param);
518 if (err != 0) {
519 FAIL("Could not modify source (err %d)\n", err);
520 return;
521 }
522
523 if (recv_state.pa_sync_state == BT_BAP_PA_STATE_NOT_SYNCED) {
524 printk("Source modified, waiting for server to PA sync\n");
525
526 WAIT_FOR_AND_CLEAR_FLAG(flag_recv_state_updated);
527 }
528
529 if (recv_state.pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
530 /* Wait for PAST to finish and then a new receive state */
531 printk("Waiting for PAST sync\n");
532 WAIT_FOR_AND_CLEAR_FLAG(flag_recv_state_updated);
533 }
534
535 if (recv_state.pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
536 FAIL("Unexpected PA sync state: %d\n", recv_state.pa_sync_state);
537 return;
538 }
539
540 if (recv_state.encrypt_state != BT_BAP_BIG_ENC_STATE_NO_ENC) {
541 FAIL("Unexpected BIG encryption state: %d\n", recv_state.pa_sync_state);
542 return;
543 }
544
545 if (recv_state.num_subgroups != mod_src_param.num_subgroups) {
546 FAIL("Unexpected number of subgroups: %u\n", recv_state.num_subgroups);
547 return;
548 }
549
550 /* Wait for another notification that updates the metadata of the subgroups */
551 if (recv_state.subgroups[0].metadata_len == 0U) {
552 printk("Waiting for another receive state update with metadata\n");
553 WAIT_FOR_AND_CLEAR_FLAG(flag_recv_state_updated);
554 }
555
556 remote_bis_sync = recv_state.subgroups[0].bis_sync;
557 if (subgroup.bis_sync == 0) {
558 if (remote_bis_sync != 0U) {
559 FAIL("Unexpected BIS sync value: %u\n", remote_bis_sync);
560 return;
561 }
562 } else {
563 printk("Waiting for BIS sync\n");
564
565 if (remote_bis_sync == 0U &&
566 recv_state.encrypt_state == BT_BAP_BIG_ENC_STATE_NO_ENC) {
567 /* Wait for another notification, which will either request a broadcast code
568 * for encrypted broadcasts, or have the BIS sync values set
569 */
570 printk("Waiting for another receive state update with BIS sync\n");
571 WAIT_FOR_AND_CLEAR_FLAG(flag_recv_state_updated);
572 remote_bis_sync = recv_state.subgroups[0].bis_sync;
573 }
574
575 if (recv_state.encrypt_state == BT_BAP_BIG_ENC_STATE_BCODE_REQ) {
576 printk("Remote is requesting broadcast code\n");
577 if (remote_bis_sync != 0U) {
578 FAIL("Unexpected BIS sync value: %u", remote_bis_sync);
579 return;
580 }
581 } else if (recv_state.encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
582 printk("Remote responded with bad code\n");
583 if (remote_bis_sync != 0U) {
584 FAIL("Unexpected BIS sync value: %u", remote_bis_sync);
585 return;
586 }
587 } else {
588 WAIT_FOR_FLAG(flag_recv_state_updated_with_bis_sync);
589 if (remote_bis_sync != subgroup.bis_sync) {
590 FAIL("Unexpected BIS sync value: %u != %u\n", remote_bis_sync,
591 subgroup.bis_sync);
592 return;
593 }
594 }
595 }
596
597 WAIT_FOR_FLAG(flag_cb_called);
598 WAIT_FOR_FLAG(flag_write_complete);
599 printk("Source modified\n");
600 }
601
test_bass_mod_source_long_meta(void)602 static void test_bass_mod_source_long_meta(void)
603 {
604 int err;
605 struct bt_bap_broadcast_assistant_mod_src_param mod_src_param = { 0 };
606 struct bt_bap_bass_subgroup subgroup = { 0 };
607 uint32_t remote_bis_sync;
608
609 printk("Long write\n");
610 UNSET_FLAG(flag_cb_called);
611 UNSET_FLAG(flag_write_complete);
612 UNSET_FLAG(flag_recv_state_updated);
613 mod_src_param.src_id = recv_state.src_id;
614 mod_src_param.num_subgroups = 1;
615 mod_src_param.pa_sync = true;
616 mod_src_param.subgroups = &subgroup;
617 mod_src_param.pa_interval = g_broadcaster_info.interval;
618 subgroup.bis_sync = recv_state.subgroups[0].bis_sync;
619
620 subgroup.metadata_len = sizeof(metadata);
621 memcpy(subgroup.metadata, metadata, sizeof(metadata));
622 err = bt_bap_broadcast_assistant_mod_src(default_conn, &mod_src_param);
623 if (err != 0) {
624 FAIL("Could not modify source (err %d)\n", err);
625 return;
626 }
627 printk("Source modified, waiting for receive state\n");
628
629 WAIT_FOR_FLAG(flag_recv_state_updated);
630
631 remote_bis_sync = recv_state.subgroups[0].bis_sync;
632 if (recv_state.pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
633 FAIL("Unexpected PA sync state: %d\n", recv_state.pa_sync_state);
634 return;
635 }
636
637 if (recv_state.encrypt_state != BT_BAP_BIG_ENC_STATE_NO_ENC) {
638 FAIL("Unexpected BIG encryption state: %d\n", recv_state.pa_sync_state);
639 return;
640 }
641
642 if (recv_state.num_subgroups != mod_src_param.num_subgroups) {
643 FAIL("Unexpected number of subgroups: %u\n", recv_state.num_subgroups);
644 return;
645 }
646
647 if (remote_bis_sync != 0U && remote_bis_sync != subgroup.bis_sync) {
648 FAIL("Unexpected BIS sync value: %u\n", remote_bis_sync);
649 return;
650 }
651
652 if (memcmp(recv_state.subgroups[0].metadata, subgroup.metadata, subgroup.metadata_len) !=
653 0) {
654 FAIL("Unexpected metadata (len %u / %u)\n", recv_state.subgroups[0].metadata_len,
655 subgroup.metadata_len);
656 return;
657 }
658
659 WAIT_FOR_FLAG(flag_cb_called);
660 WAIT_FOR_FLAG(flag_write_complete);
661 printk("Source modified with long meta\n");
662 }
663
test_bass_broadcast_code(const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])664 static void test_bass_broadcast_code(const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
665 {
666 int err;
667
668 printk("Adding broadcast code\n");
669 UNSET_FLAG(flag_write_complete);
670
671 do {
672 err = bt_bap_broadcast_assistant_set_broadcast_code(default_conn, recv_state.src_id,
673 broadcast_code);
674 if (err == -EBUSY) {
675 k_sleep(BAP_RETRY_WAIT);
676 } else if (err != 0) {
677 FAIL("Could not add broadcast code (err %d)\n", err);
678 return;
679 }
680 } while (err == -EBUSY);
681
682 WAIT_FOR_FLAG(flag_write_complete);
683 printk("Broadcast code added\n");
684 }
685
test_bass_remove_source(void)686 static void test_bass_remove_source(void)
687 {
688 int err;
689
690 printk("Removing source\n");
691 UNSET_FLAG(flag_cb_called);
692 UNSET_FLAG(flag_write_complete);
693 err = bt_bap_broadcast_assistant_rem_src(default_conn, recv_state.src_id);
694 if (err != 0) {
695 FAIL("Could not remove source (err %d)\n", err);
696 return;
697 }
698
699 WAIT_FOR_FLAG(flag_cb_called);
700 WAIT_FOR_FLAG(flag_write_complete);
701 printk("Source removed\n");
702 }
703
common_init(void)704 static int common_init(void)
705 {
706 int err;
707
708 err = bt_enable(NULL);
709
710 if (err != 0) {
711 FAIL("Bluetooth enable failed (err %d)\n", err);
712 return err;
713 }
714
715 bt_gatt_cb_register(&gatt_callbacks);
716 bt_bap_broadcast_assistant_register_cb(&broadcast_assistant_cbs);
717 bt_le_per_adv_sync_cb_register(&sync_callbacks);
718 bt_le_scan_cb_register(&common_scan_cb);
719
720 printk("Starting scan\n");
721 err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
722 if (err != 0) {
723 FAIL("Scanning failed to start (err %d)\n", err);
724 return err;
725 }
726
727 printk("Scanning successfully started\n");
728
729 WAIT_FOR_FLAG(flag_connected);
730
731 test_exchange_mtu();
732 test_bass_discover();
733 test_bass_read_receive_states();
734
735 return 0;
736 }
737
test_main_client_sync(void)738 static void test_main_client_sync(void)
739 {
740 int err;
741
742 err = common_init();
743 if (err != 0) {
744 FAIL("Bluetooth enable failed (err %d)\n", err);
745 return;
746 }
747
748 test_bass_scan_start();
749 test_bass_scan_stop();
750 test_bass_create_pa_sync();
751 test_bass_add_source();
752 test_bass_mod_source(0);
753 test_bass_mod_source_long_meta();
754 test_bass_mod_source(BT_ISO_BIS_INDEX_BIT(1) | BT_ISO_BIS_INDEX_BIT(2));
755 test_bass_broadcast_code(BROADCAST_CODE);
756
757 printk("Waiting for receive state with BIS sync\n");
758 WAIT_FOR_FLAG(flag_recv_state_updated_with_bis_sync);
759
760 test_bass_remove_source();
761
762 PASS("BAP Broadcast Assistant Client Sync Passed\n");
763 }
764
test_main_client_sync_incorrect_code(void)765 static void test_main_client_sync_incorrect_code(void)
766 {
767 int err;
768
769 err = common_init();
770 if (err != 0) {
771 FAIL("Bluetooth enable failed (err %d)\n", err);
772 return;
773 }
774
775 test_bass_scan_start();
776 test_bass_scan_stop();
777 test_bass_create_pa_sync();
778 test_bass_add_source();
779 test_bass_mod_source(BT_ISO_BIS_INDEX_BIT(1));
780 WAIT_FOR_FLAG(flag_broadcast_code_requested);
781 test_bass_broadcast_code(INCORRECT_BROADCAST_CODE);
782 WAIT_FOR_FLAG(flag_incorrect_broadcast_code);
783
784 test_bass_remove_source();
785
786 PASS("BAP Broadcast Assistant Client Sync Passed\n");
787 }
788
test_main_server_sync_client_rem(void)789 static void test_main_server_sync_client_rem(void)
790 {
791 int err;
792
793 err = common_init();
794 if (err != 0) {
795 FAIL("Bluetooth enable failed (err %d)\n", err);
796 return;
797 }
798
799 WAIT_FOR_FLAG(flag_recv_state_updated);
800
801 test_bass_broadcast_code(BROADCAST_CODE);
802
803 printk("Waiting for receive state with BIS sync\n");
804 WAIT_FOR_FLAG(flag_recv_state_updated_with_bis_sync);
805
806 test_bass_remove_source();
807
808 PASS("BAP Broadcast Assistant Server Sync Passed\n");
809 }
810
test_main_server_sync_server_rem(void)811 static void test_main_server_sync_server_rem(void)
812 {
813 int err;
814
815 err = common_init();
816 if (err != 0) {
817 FAIL("Bluetooth enable failed (err %d)\n", err);
818 return;
819 }
820
821 WAIT_FOR_FLAG(flag_recv_state_updated);
822
823 test_bass_broadcast_code(BROADCAST_CODE);
824
825 printk("Waiting for receive state with BIS sync\n");
826 WAIT_FOR_FLAG(flag_recv_state_updated_with_bis_sync);
827
828 WAIT_FOR_FLAG(flag_recv_state_removed);
829
830 PASS("BAP Broadcast Assistant Server Sync Passed\n");
831 }
832
833 static const struct bst_test_instance test_bass[] = {
834 {
835 .test_id = "bap_broadcast_assistant_client_sync",
836 .test_pre_init_f = test_init,
837 .test_tick_f = test_tick,
838 .test_main_f = test_main_client_sync,
839 },
840 {
841 .test_id = "bap_broadcast_assistant_client_sync_incorrect_code",
842 .test_pre_init_f = test_init,
843 .test_tick_f = test_tick,
844 .test_main_f = test_main_client_sync_incorrect_code,
845 },
846 {
847 .test_id = "bap_broadcast_assistant_server_sync_client_rem",
848 .test_pre_init_f = test_init,
849 .test_tick_f = test_tick,
850 .test_main_f = test_main_server_sync_client_rem,
851 },
852 {
853 .test_id = "bap_broadcast_assistant_server_sync_server_rem",
854 .test_pre_init_f = test_init,
855 .test_tick_f = test_tick,
856 .test_main_f = test_main_server_sync_server_rem,
857 },
858 BSTEST_END_MARKER,
859 };
860
test_bap_broadcast_assistant_install(struct bst_test_list * tests)861 struct bst_test_list *test_bap_broadcast_assistant_install(struct bst_test_list *tests)
862 {
863 return bst_add_tests(tests, test_bass);
864 }
865
866 #else
867
test_bap_broadcast_assistant_install(struct bst_test_list * tests)868 struct bst_test_list *test_bap_broadcast_assistant_install(struct bst_test_list *tests)
869 {
870 return tests;
871 }
872
873 #endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT */
874