1 /*
2  * Copyright (c) 2021-2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdbool.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11 
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/addr.h>
14 #include <zephyr/bluetooth/audio/audio.h>
15 #include <zephyr/bluetooth/audio/bap.h>
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/byteorder.h>
18 #include <zephyr/bluetooth/gap.h>
19 #include <zephyr/bluetooth/iso.h>
20 #include <zephyr/bluetooth/uuid.h>
21 #include <zephyr/kernel.h>
22 #include <zephyr/net_buf.h>
23 #include <zephyr/sys/byteorder.h>
24 #include <zephyr/sys/printk.h>
25 #include <zephyr/sys/util.h>
26 #include <zephyr/sys/util_macro.h>
27 
28 #include "bstests.h"
29 #include "common.h"
30 
31 #ifdef CONFIG_BT_BAP_SCAN_DELEGATOR
32 extern enum bst_result_t bst_result;
33 
34 #define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */
35 #define PA_SYNC_SKIP              5
36 
37 CREATE_FLAG(flag_pa_synced);
38 CREATE_FLAG(flag_pa_terminated);
39 CREATE_FLAG(flag_broadcast_code_received);
40 CREATE_FLAG(flag_recv_state_updated);
41 CREATE_FLAG(flag_bis_sync_requested);
42 CREATE_FLAG(flag_bis_sync_term_requested);
43 static volatile uint32_t g_broadcast_id;
44 
45 struct sync_state {
46 	uint8_t src_id;
47 	const struct bt_bap_scan_delegator_recv_state *recv_state;
48 	bool pa_syncing;
49 	struct k_work_delayable pa_timer;
50 	struct bt_le_per_adv_sync *pa_sync;
51 	uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE];
52 	uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS];
53 } sync_states[CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT];
54 
sync_state_get(const struct bt_bap_scan_delegator_recv_state * recv_state)55 static struct sync_state *sync_state_get(const struct bt_bap_scan_delegator_recv_state *recv_state)
56 {
57 	for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
58 		if (sync_states[i].recv_state == recv_state) {
59 			return &sync_states[i];
60 		}
61 	}
62 
63 	return NULL;
64 }
65 
sync_state_get_or_new(const struct bt_bap_scan_delegator_recv_state * recv_state)66 static struct sync_state *sync_state_get_or_new(
67 	const struct bt_bap_scan_delegator_recv_state *recv_state)
68 {
69 	struct sync_state *free_state = NULL;
70 
71 	for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
72 		if (sync_states[i].recv_state == NULL &&
73 		    free_state == NULL) {
74 			free_state = &sync_states[i];
75 
76 			if (recv_state == NULL) {
77 				return free_state;
78 			}
79 		}
80 
81 		if (sync_states[i].recv_state == recv_state) {
82 			return &sync_states[i];
83 		}
84 	}
85 
86 	return free_state;
87 }
88 
sync_state_get_by_pa(struct bt_le_per_adv_sync * sync)89 static struct sync_state *sync_state_get_by_pa(struct bt_le_per_adv_sync *sync)
90 {
91 	for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
92 		if (sync_states[i].pa_sync == sync) {
93 			return &sync_states[i];
94 		}
95 	}
96 
97 	return NULL;
98 }
99 
sync_state_get_by_src_id(uint8_t src_id)100 static struct sync_state *sync_state_get_by_src_id(uint8_t src_id)
101 {
102 	for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
103 		if (sync_states[i].src_id == src_id) {
104 			return &sync_states[i];
105 		}
106 	}
107 
108 	return NULL;
109 }
110 
pa_timer_handler(struct k_work * work)111 static void pa_timer_handler(struct k_work *work)
112 {
113 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
114 	struct sync_state *state = CONTAINER_OF(dwork, struct sync_state, pa_timer);
115 
116 	state->pa_syncing = false;
117 
118 	if (state->recv_state != NULL) {
119 		enum bt_bap_pa_state pa_state;
120 
121 		if (state->recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
122 			pa_state = BT_BAP_PA_STATE_NO_PAST;
123 		} else {
124 			pa_state = BT_BAP_PA_STATE_FAILED;
125 		}
126 
127 		bt_bap_scan_delegator_set_pa_state(state->recv_state->src_id,
128 						   pa_state);
129 	}
130 
131 	FAIL("PA timeout\n");
132 }
133 
pa_sync_past(struct bt_conn * conn,struct sync_state * state,uint16_t pa_interval)134 static int pa_sync_past(struct bt_conn *conn,
135 			struct sync_state *state,
136 			uint16_t pa_interval)
137 {
138 	struct bt_le_per_adv_sync_transfer_param param = { 0 };
139 	int err;
140 
141 	param.options = BT_LE_PER_ADV_SYNC_TRANSFER_OPT_FILTER_DUPLICATES;
142 	param.skip = PA_SYNC_SKIP;
143 	param.timeout = interval_to_sync_timeout(pa_interval);
144 
145 	err = bt_le_per_adv_sync_transfer_subscribe(conn, &param);
146 	if (err != 0) {
147 		printk("Could not do PAST subscribe: %d\n", err);
148 	} else {
149 		printk("Syncing with PAST: %d\n", err);
150 		state->pa_syncing = true;
151 		k_work_init_delayable(&state->pa_timer, pa_timer_handler);
152 		(void)k_work_reschedule(&state->pa_timer,
153 					K_MSEC(param.timeout * 10));
154 	}
155 
156 	return err;
157 }
158 
pa_sync_no_past(struct sync_state * state,uint16_t pa_interval)159 static int pa_sync_no_past(struct sync_state *state,
160 			    uint16_t pa_interval)
161 {
162 	const struct bt_bap_scan_delegator_recv_state *recv_state;
163 	struct bt_le_per_adv_sync_param param = { 0 };
164 	int err;
165 
166 	recv_state = state->recv_state;
167 	state->src_id = recv_state->src_id;
168 
169 	bt_addr_le_copy(&param.addr, &recv_state->addr);
170 	param.sid = recv_state->adv_sid;
171 	param.skip = PA_SYNC_SKIP;
172 	param.timeout = interval_to_sync_timeout(pa_interval);
173 
174 	/* TODO: Validate that the advertise is broadcasting the same
175 	 * broadcast_id that the receive state has
176 	 */
177 	err = bt_le_per_adv_sync_create(&param, &state->pa_sync);
178 	if (err != 0) {
179 		printk("Could not sync per adv: %d\n", err);
180 	} else {
181 		char addr_str[BT_ADDR_LE_STR_LEN];
182 
183 		bt_addr_le_to_str(&recv_state->addr, addr_str, sizeof(addr_str));
184 		printk("PA sync pending for addr %s\n", addr_str);
185 		state->pa_syncing = true;
186 		k_work_init_delayable(&state->pa_timer, pa_timer_handler);
187 		(void)k_work_reschedule(&state->pa_timer,
188 					K_MSEC(param.timeout * 10));
189 	}
190 
191 	return err;
192 }
193 
pa_sync_term(struct sync_state * state)194 static int pa_sync_term(struct sync_state *state)
195 {
196 	int err;
197 
198 	(void)k_work_cancel_delayable(&state->pa_timer);
199 
200 	if (state->pa_sync == NULL) {
201 		return -1;
202 	}
203 
204 	printk("Deleting PA sync\n");
205 
206 	err = bt_le_per_adv_sync_delete(state->pa_sync);
207 	if (err != 0) {
208 		FAIL("Could not delete per adv sync: %d\n", err);
209 	} else {
210 		state->pa_syncing = false;
211 		state->pa_sync = NULL;
212 	}
213 
214 	return err;
215 }
216 
recv_state_updated_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state)217 static void recv_state_updated_cb(struct bt_conn *conn,
218 				  const struct bt_bap_scan_delegator_recv_state *recv_state)
219 {
220 	struct sync_state *state;
221 
222 	printk("Receive state with ID %u updated\n", recv_state->src_id);
223 
224 	state = sync_state_get_by_src_id(recv_state->src_id);
225 	if (state == NULL) {
226 		FAIL("Could not get state");
227 		return;
228 	}
229 
230 	if (state->recv_state != NULL) {
231 		if (state->recv_state != recv_state) {
232 			FAIL("Sync state receive state mismatch: %p - %p",
233 			     state->recv_state, recv_state);
234 			return;
235 		}
236 	} else {
237 		state->recv_state = recv_state;
238 	}
239 
240 	SET_FLAG(flag_recv_state_updated);
241 }
242 
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)243 static int pa_sync_req_cb(struct bt_conn *conn,
244 			  const struct bt_bap_scan_delegator_recv_state *recv_state,
245 			  bool past_avail, uint16_t pa_interval)
246 {
247 	struct sync_state *state;
248 	int err;
249 
250 	printk("PA Sync request: past_avail %u, pa_interval 0x%04x\n: %p",
251 	       past_avail, pa_interval, recv_state);
252 
253 	state = sync_state_get_or_new(recv_state);
254 	if (state == NULL) {
255 		FAIL("Could not get state");
256 		return -1;
257 	}
258 
259 	state->recv_state = recv_state;
260 	state->src_id = recv_state->src_id;
261 
262 	if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED ||
263 	    recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
264 		/* Already syncing */
265 		/* TODO: Terminate existing sync and then sync to new?*/
266 		return -1;
267 	}
268 
269 	if (past_avail) {
270 		err = pa_sync_past(conn, state, pa_interval);
271 		if (err == 0) {
272 			err = bt_bap_scan_delegator_set_pa_state(state->recv_state->src_id,
273 								 BT_BAP_PA_STATE_INFO_REQ);
274 			if (err != 0) {
275 				printk("Failed to set INFO_REQ state: %d", err);
276 			}
277 		}
278 	} else {
279 		err = pa_sync_no_past(state, pa_interval);
280 	}
281 
282 	return err;
283 }
284 
pa_sync_term_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state)285 static int pa_sync_term_req_cb(struct bt_conn *conn,
286 			       const struct bt_bap_scan_delegator_recv_state *recv_state)
287 {
288 	struct sync_state *state;
289 
290 	printk("PA Sync term request for %p\n", recv_state);
291 
292 	state = sync_state_get(recv_state);
293 	if (state == NULL) {
294 		FAIL("Could not get state\n");
295 		return -1;
296 	}
297 
298 	return pa_sync_term(state);
299 }
300 
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])301 static void broadcast_code_cb(struct bt_conn *conn,
302 			      const struct bt_bap_scan_delegator_recv_state *recv_state,
303 			      const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
304 {
305 	struct sync_state *state;
306 
307 	printk("Broadcast code received for %p\n", recv_state);
308 
309 	state = sync_state_get(recv_state);
310 	if (state == NULL) {
311 		FAIL("Could not get state\n");
312 		return;
313 	}
314 
315 	(void)memcpy(state->broadcast_code, broadcast_code, BT_ISO_BROADCAST_CODE_SIZE);
316 
317 	SET_FLAG(flag_broadcast_code_received);
318 }
319 
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])320 static int bis_sync_req_cb(struct bt_conn *conn,
321 			   const struct bt_bap_scan_delegator_recv_state *recv_state,
322 			   const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
323 {
324 	struct sync_state *state;
325 	bool sync_bis;
326 
327 	printk("BIS sync request received for %p\n", recv_state);
328 	for (int i = 0; i < CONFIG_BT_BAP_BASS_MAX_SUBGROUPS; i++) {
329 		if (bis_sync_req[i]) {
330 			sync_bis = true;
331 		}
332 
333 		printk("  [%d]: 0x%08x\n", i, bis_sync_req[i]);
334 	}
335 
336 	state = sync_state_get(recv_state);
337 	if (state == NULL) {
338 		FAIL("Could not get state\n");
339 		return -1;
340 	}
341 
342 	(void)memcpy(state->bis_sync_req, bis_sync_req,
343 		     sizeof(state->bis_sync_req));
344 
345 	if (sync_bis) {
346 		SET_FLAG(flag_bis_sync_requested);
347 	} else {
348 		SET_FLAG(flag_bis_sync_term_requested);
349 	}
350 
351 	return 0;
352 }
353 
354 static struct bt_bap_scan_delegator_cb scan_delegator_cb = {
355 	.recv_state_updated = recv_state_updated_cb,
356 	.pa_sync_req = pa_sync_req_cb,
357 	.pa_sync_term_req = pa_sync_term_req_cb,
358 	.broadcast_code = broadcast_code_cb,
359 	.bis_sync_req = bis_sync_req_cb,
360 };
361 
pa_synced_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)362 static void pa_synced_cb(struct bt_le_per_adv_sync *sync,
363 			 struct bt_le_per_adv_sync_synced_info *info)
364 {
365 	struct sync_state *state;
366 
367 	printk("PA %p synced\n", sync);
368 
369 	if (info->conn) { /* if from PAST */
370 		for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
371 			if (!sync_states[i].pa_sync) {
372 				sync_states[i].pa_sync = sync;
373 			}
374 		}
375 	}
376 
377 	state = sync_state_get_by_pa(sync);
378 	if (state == NULL) {
379 		FAIL("Could not get sync state from PA sync %p\n", sync);
380 		return;
381 	}
382 
383 	k_work_cancel_delayable(&state->pa_timer);
384 
385 	SET_FLAG(flag_pa_synced);
386 }
387 
pa_term_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)388 static void pa_term_cb(struct bt_le_per_adv_sync *sync,
389 		       const struct bt_le_per_adv_sync_term_info *info)
390 {
391 	struct sync_state *state;
392 
393 	printk("PA %p sync terminated\n", sync);
394 
395 	state = sync_state_get_by_pa(sync);
396 	if (state == NULL) {
397 		FAIL("Could not get sync state from PA sync %p\n", sync);
398 		return;
399 	}
400 
401 	k_work_cancel_delayable(&state->pa_timer);
402 
403 	SET_FLAG(flag_pa_terminated);
404 }
405 
406 static struct bt_le_per_adv_sync_cb pa_sync_cb =  {
407 	.synced = pa_synced_cb,
408 	.term = pa_term_cb,
409 };
410 
broadcast_source_found(struct bt_data * data,void * user_data)411 static bool broadcast_source_found(struct bt_data *data, void *user_data)
412 {
413 	struct bt_le_per_adv_sync_param sync_create_param = { 0 };
414 	const struct bt_le_scan_recv_info *info = user_data;
415 	char addr_str[BT_ADDR_LE_STR_LEN];
416 	struct bt_uuid_16 adv_uuid;
417 	struct sync_state *state;
418 	int err;
419 
420 
421 	if (data->type != BT_DATA_SVC_DATA16) {
422 		return true;
423 	}
424 
425 	if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
426 		return true;
427 	}
428 
429 	if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
430 		return true;
431 	}
432 
433 	if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO) != 0) {
434 		return true;
435 	}
436 
437 	g_broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
438 	bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str));
439 
440 	printk("Found BAP broadcast source with address %s and ID 0x%06X\n",
441 	       addr_str, g_broadcast_id);
442 
443 	state = sync_state_get_or_new(NULL);
444 	if (state == NULL) {
445 		FAIL("Failed to get sync state");
446 		return true;
447 	}
448 
449 	printk("Creating Periodic Advertising Sync\n");
450 	bt_addr_le_copy(&sync_create_param.addr, info->addr);
451 	sync_create_param.sid = info->sid;
452 	sync_create_param.timeout = 0xa;
453 
454 	err = bt_le_per_adv_sync_create(&sync_create_param,
455 					&state->pa_sync);
456 	if (err != 0) {
457 		FAIL("Could not create PA sync (err %d)\n", err);
458 		return true;
459 	}
460 
461 	state->pa_syncing = true;
462 
463 	return false;
464 }
465 
scan_recv_cb(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)466 static void scan_recv_cb(const struct bt_le_scan_recv_info *info,
467 			 struct net_buf_simple *ad)
468 {
469 	/* We are only interested in non-connectable periodic advertisers */
470 	if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0 ||
471 	    info->interval == 0) {
472 		return;
473 	}
474 
475 	bt_data_parse(ad, broadcast_source_found, (void *)info);
476 }
477 
478 static struct bt_le_scan_cb scan_cb = {
479 	.recv = scan_recv_cb
480 };
481 
add_source(struct sync_state * state)482 static int add_source(struct sync_state *state)
483 {
484 	struct bt_bap_scan_delegator_add_src_param param;
485 	struct bt_le_per_adv_sync_info sync_info;
486 	int res;
487 
488 	UNSET_FLAG(flag_recv_state_updated);
489 
490 	res = bt_le_per_adv_sync_get_info(state->pa_sync, &sync_info);
491 	if (res != 0) {
492 		FAIL("Failed to get PA sync info: %d)\n", res);
493 		return true;
494 	}
495 
496 	bt_addr_le_copy(&param.addr, &sync_info.addr);
497 	param.sid = sync_info.sid;
498 	param.encrypt_state = BT_BAP_BIG_ENC_STATE_NO_ENC;
499 	param.broadcast_id = g_broadcast_id;
500 	param.num_subgroups = 1U;
501 
502 	for (uint8_t i = 0U; i < param.num_subgroups; i++) {
503 		struct bt_bap_bass_subgroup *subgroup_param = &param.subgroups[i];
504 
505 		subgroup_param->bis_sync = BT_BAP_BIS_SYNC_NO_PREF;
506 		subgroup_param->metadata_len = 0U;
507 		(void)memset(subgroup_param->metadata, 0, sizeof(subgroup_param->metadata));
508 	}
509 
510 	res = bt_bap_scan_delegator_add_src(&param);
511 	if (res < 0) {
512 		return res;
513 	}
514 
515 	state->src_id = (uint8_t)res;
516 
517 	WAIT_FOR_FLAG(flag_recv_state_updated);
518 
519 	return res;
520 }
521 
add_all_sources(void)522 static void add_all_sources(void)
523 {
524 	for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
525 		struct sync_state *state = &sync_states[i];
526 
527 		if (state->pa_sync != NULL) {
528 			int res;
529 
530 			printk("[%zu]: Adding source\n", i);
531 
532 			res = add_source(state);
533 			if (res < 0) {
534 				FAIL("[%zu]: Add source failed (err %d)\n", i, res);
535 				return;
536 			}
537 
538 			printk("[%zu]: Source added with id %u\n",
539 			       i, state->src_id);
540 		}
541 	}
542 }
543 
mod_source(struct sync_state * state)544 static int mod_source(struct sync_state *state)
545 {
546 	const uint16_t pref_context = BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL;
547 	struct bt_bap_scan_delegator_mod_src_param param;
548 	const uint8_t pref_context_metadata[] = {
549 		BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT,
550 				    BT_BYTES_LIST_LE16(pref_context)),
551 	};
552 	int err;
553 
554 	UNSET_FLAG(flag_recv_state_updated);
555 
556 	param.src_id = state->src_id;
557 	param.encrypt_state = BT_BAP_BIG_ENC_STATE_NO_ENC;
558 	param.broadcast_id = g_broadcast_id;
559 	param.num_subgroups = 1U;
560 
561 	for (uint8_t i = 0U; i < param.num_subgroups; i++) {
562 		struct bt_bap_bass_subgroup *subgroup_param = &param.subgroups[i];
563 
564 		subgroup_param->bis_sync = 0U;
565 		subgroup_param->metadata_len = sizeof(pref_context_metadata);
566 		(void)memcpy(subgroup_param->metadata, pref_context_metadata,
567 			     subgroup_param->metadata_len);
568 	}
569 
570 	err = bt_bap_scan_delegator_mod_src(&param);
571 	if (err < 0) {
572 		return err;
573 	}
574 
575 	WAIT_FOR_FLAG(flag_recv_state_updated);
576 
577 	return 0;
578 }
579 
mod_all_sources(void)580 static void mod_all_sources(void)
581 {
582 	for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
583 		struct sync_state *state = &sync_states[i];
584 
585 		if (state->pa_sync != NULL) {
586 			int err;
587 
588 			printk("[%zu]: Modifying source\n", i);
589 
590 			err = mod_source(state);
591 			if (err < 0) {
592 				FAIL("[%zu]: Modify source failed (err %d)\n", i, err);
593 				return;
594 			}
595 
596 			printk("[%zu]: Source id modifed %u\n",
597 			       i, state->src_id);
598 		}
599 	}
600 }
601 
remove_source(struct sync_state * state)602 static int remove_source(struct sync_state *state)
603 {
604 	int err;
605 
606 	UNSET_FLAG(flag_recv_state_updated);
607 
608 	/* We don't actually need to sync to the BIG/BISes */
609 	err = bt_bap_scan_delegator_rem_src(state->src_id);
610 	if (err) {
611 		return err;
612 	}
613 
614 	WAIT_FOR_FLAG(flag_recv_state_updated);
615 
616 	return 0;
617 }
618 
remove_all_sources(void)619 static void remove_all_sources(void)
620 {
621 	for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
622 		struct sync_state *state = &sync_states[i];
623 
624 		if (state->recv_state != NULL) {
625 			int err;
626 
627 			printk("[%zu]: Removing source\n", i);
628 
629 			err = remove_source(state);
630 			if (err) {
631 				FAIL("[%zu]: Remove source failed (err %d)\n", err);
632 				return;
633 			}
634 
635 			printk("[%zu]: Source removed with id %u\n",
636 			       i, state->src_id);
637 
638 			printk("Terminating PA sync\n");
639 			err = pa_sync_term(state);
640 			if (err) {
641 				FAIL("[%zu]: PA sync term failed (err %d)\n", err);
642 				return;
643 			}
644 		}
645 	}
646 }
647 
sync_broadcast(struct sync_state * state)648 static int sync_broadcast(struct sync_state *state)
649 {
650 	int err;
651 	uint32_t bis_sync[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS];
652 
653 	UNSET_FLAG(flag_recv_state_updated);
654 
655 	for (size_t i = 0U; i < CONFIG_BT_BAP_BASS_MAX_SUBGROUPS; i++) {
656 		bis_sync[i] = BT_ISO_BIS_INDEX_BIT(i + 1);
657 	}
658 
659 	/* We don't actually need to sync to the BIG/BISes */
660 	err = bt_bap_scan_delegator_set_bis_sync_state(state->src_id, bis_sync);
661 
662 	if (err) {
663 		return err;
664 	}
665 
666 	WAIT_FOR_FLAG(flag_recv_state_updated);
667 
668 	return 0;
669 }
670 
sync_all_broadcasts(void)671 static void sync_all_broadcasts(void)
672 {
673 	for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
674 		struct sync_state *state = &sync_states[i];
675 
676 		if (state->pa_sync != NULL) {
677 			int res;
678 
679 			printk("[%zu]: Setting broadcast sync state\n", i);
680 
681 			res = sync_broadcast(state);
682 			if (res < 0) {
683 				FAIL("[%zu]: Broadcast sync state set failed (err %d)\n", i, res);
684 				return;
685 			}
686 
687 			printk("[%zu]: Broadcast sync state set\n", i);
688 		}
689 	}
690 }
691 
common_init(void)692 static int common_init(void)
693 {
694 	int err;
695 
696 	err = bt_enable(NULL);
697 	if (err) {
698 		FAIL("Bluetooth init failed (err %d)\n", err);
699 		return err;
700 	}
701 
702 	printk("Bluetooth initialized\n");
703 
704 	err = bt_bap_scan_delegator_register(&scan_delegator_cb);
705 	if (err) {
706 		FAIL("Scan delegator register failed (err %d)\n", err);
707 		return err;
708 	}
709 
710 	bt_le_per_adv_sync_cb_register(&pa_sync_cb);
711 
712 	err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, AD_SIZE, NULL, 0);
713 	if (err) {
714 		FAIL("Advertising failed to start (err %d)\n", err);
715 		return err;
716 	}
717 
718 	printk("Advertising successfully started\n");
719 
720 	WAIT_FOR_FLAG(flag_connected);
721 
722 	return 0;
723 }
724 
test_main_client_sync(void)725 static void test_main_client_sync(void)
726 {
727 	int err;
728 
729 	err = common_init();
730 	if (err) {
731 		FAIL("common init failed (err %d)\n", err);
732 		return;
733 	}
734 
735 	/* Wait for broadcast assistant to request us to sync to PA */
736 	WAIT_FOR_FLAG(flag_pa_synced);
737 
738 	/* Wait for broadcast assistant to send us broadcast code */
739 	WAIT_FOR_FLAG(flag_broadcast_code_received);
740 
741 	/* Mod all sources by modifying the metadata */
742 	mod_all_sources();
743 
744 	/* Wait for broadcast assistant to tell us to BIS sync */
745 	WAIT_FOR_FLAG(flag_bis_sync_requested);
746 
747 	/* Set the BIS sync state */
748 	sync_all_broadcasts();
749 
750 	/* Wait for broadcast assistant to remove source and terminate PA sync */
751 	WAIT_FOR_FLAG(flag_pa_terminated);
752 
753 	PASS("BAP Scan Delegator Client Sync passed\n");
754 }
755 
test_main_server_sync_client_rem(void)756 static void test_main_server_sync_client_rem(void)
757 {
758 	int err;
759 
760 	err = common_init();
761 	if (err) {
762 		FAIL("common init failed (err %d)\n", err);
763 		return;
764 	}
765 
766 	bt_le_scan_cb_register(&scan_cb);
767 
768 	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
769 	if (err != 0) {
770 		FAIL("Could not start scan (%d)", err);
771 		return;
772 	}
773 
774 	/* Wait for PA to sync */
775 	WAIT_FOR_FLAG(flag_pa_synced);
776 
777 	/* Add PAs as receive state sources */
778 	add_all_sources();
779 
780 	/* Wait for broadcast assistant to send us broadcast code */
781 	WAIT_FOR_FLAG(flag_broadcast_code_received);
782 
783 	/* Mod all sources by modifying the metadata */
784 	mod_all_sources();
785 
786 	/* Set the BIS sync state */
787 	sync_all_broadcasts();
788 
789 	/* For for client to remove source and thus terminate the PA */
790 	WAIT_FOR_FLAG(flag_pa_terminated);
791 
792 	PASS("BAP Scan Delegator Server Sync Client Remove passed\n");
793 }
794 
test_main_server_sync_server_rem(void)795 static void test_main_server_sync_server_rem(void)
796 {
797 	int err;
798 
799 	err = common_init();
800 	if (err) {
801 		FAIL("common init failed (err %d)\n", err);
802 		return;
803 	}
804 
805 	bt_le_scan_cb_register(&scan_cb);
806 
807 	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
808 	if (err != 0) {
809 		FAIL("Could not start scan (%d)", err);
810 		return;
811 	}
812 
813 	/* Wait for PA to sync */
814 	WAIT_FOR_FLAG(flag_pa_synced);
815 
816 	/* Add PAs as receive state sources */
817 	add_all_sources();
818 
819 	/* Wait for broadcast assistant to send us broadcast code */
820 	WAIT_FOR_FLAG(flag_broadcast_code_received);
821 
822 	/* Mod all sources by modifying the metadata */
823 	mod_all_sources();
824 
825 	/* Set the BIS sync state */
826 	sync_all_broadcasts();
827 
828 	/* Remote all sources, causing PA sync term request to trigger */
829 	remove_all_sources();
830 
831 	/* Wait for PA sync to be terminated */
832 	WAIT_FOR_FLAG(flag_pa_terminated);
833 
834 	PASS("BAP Scan Delegator Server Sync Server Remove passed\n");
835 }
836 
837 static const struct bst_test_instance test_scan_delegator[] = {
838 	{
839 		.test_id = "bap_scan_delegator_client_sync",
840 		.test_pre_init_f = test_init,
841 		.test_tick_f = test_tick,
842 		.test_main_f = test_main_client_sync,
843 	},
844 	{
845 		.test_id = "bap_scan_delegator_server_sync_client_rem",
846 		.test_pre_init_f = test_init,
847 		.test_tick_f = test_tick,
848 		.test_main_f = test_main_server_sync_client_rem,
849 	},
850 	{
851 		.test_id = "bap_scan_delegator_server_sync_server_rem",
852 		.test_pre_init_f = test_init,
853 		.test_tick_f = test_tick,
854 		.test_main_f = test_main_server_sync_server_rem,
855 	},
856 	BSTEST_END_MARKER
857 };
858 
test_scan_delegator_install(struct bst_test_list * tests)859 struct bst_test_list *test_scan_delegator_install(struct bst_test_list *tests)
860 {
861 	return bst_add_tests(tests, test_scan_delegator);
862 }
863 #else
test_scan_delegator_install(struct bst_test_list * tests)864 struct bst_test_list *test_scan_delegator_install(struct bst_test_list *tests)
865 {
866 	return tests;
867 }
868 
869 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR */
870