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