1 /*
2  * Copyright (c) 2022-2025 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <errno.h>
7 #include <stdbool.h>
8 #include <stddef.h>
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <string.h>
12 
13 #include <zephyr/autoconf.h>
14 #include <zephyr/bluetooth/addr.h>
15 #include <zephyr/bluetooth/audio/aics.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/cap.h>
20 #include <zephyr/bluetooth/audio/csip.h>
21 #include <zephyr/bluetooth/audio/lc3.h>
22 #include <zephyr/bluetooth/audio/pacs.h>
23 #include <zephyr/bluetooth/audio/micp.h>
24 #include <zephyr/bluetooth/audio/vcp.h>
25 #include <zephyr/bluetooth/bluetooth.h>
26 #include <zephyr/bluetooth/byteorder.h>
27 #include <zephyr/bluetooth/gap.h>
28 #include <zephyr/bluetooth/iso.h>
29 #include <zephyr/bluetooth/uuid.h>
30 #include <zephyr/kernel.h>
31 #include <zephyr/logging/log.h>
32 #include <zephyr/logging/log_core.h>
33 #include <zephyr/net_buf.h>
34 #include <zephyr/sys/byteorder.h>
35 #include <zephyr/sys/util.h>
36 #include <zephyr/sys/util_macro.h>
37 
38 #include "bap_stream_rx.h"
39 #include "bstests.h"
40 #include "common.h"
41 #include "bap_common.h"
42 
43 LOG_MODULE_REGISTER(cap_handover_peripheral, LOG_LEVEL_DBG);
44 
45 #if defined(CONFIG_BT_CAP_ACCEPTOR)
46 extern enum bst_result_t bst_result;
47 
48 #define CAP_INITIATOR_DEV_ID 0 /* CAP initiator shall be ID 0 for these tests */
49 
50 CREATE_FLAG(flag_broadcast_code);
51 CREATE_FLAG(flag_base_received);
52 CREATE_FLAG(flag_pa_synced);
53 CREATE_FLAG(flag_syncable);
54 CREATE_FLAG(flag_pa_sync_lost);
55 CREATE_FLAG(flag_pa_request);
56 CREATE_FLAG(flag_bis_sync_requested);
57 CREATE_FLAG(flag_base_metadata_updated);
58 CREATE_FLAG(flag_stream_configured);
59 CREATE_FLAG(flag_stream_started);
60 CREATE_FLAG(flag_stream_stopped);
61 CREATE_FLAG(flag_broadcast_started);
62 CREATE_FLAG(flag_broadcast_stopped);
63 
64 static struct bt_bap_broadcast_sink *broadcast_sink;
65 static struct bt_le_per_adv_sync *pa_sync;
66 static const struct bt_bap_scan_delegator_recv_state *cached_recv_state;
67 static uint32_t cached_bis_sync_req;
68 static uint16_t cached_pa_interval;
69 static struct audio_test_stream
70 	streams[MIN(CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT,
71 		    CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT)];
72 static uint8_t received_base[UINT8_MAX];
73 static size_t received_base_size;
74 
75 static const struct bt_bap_qos_cfg_pref unicast_qos_pref =
76 	BT_BAP_QOS_CFG_PREF(true, BT_GAP_LE_PHY_2M, 0u, 60u, 20000u, 40000u, 20000u, 40000u);
77 
subgroup_data_func_cb(struct bt_data * data,void * user_data)78 static bool subgroup_data_func_cb(struct bt_data *data, void *user_data)
79 {
80 	bool *stream_context_found = (bool *)user_data;
81 
82 	LOG_DBG("type %u len %u", data->type, data->data_len);
83 
84 	if (!valid_metadata_type(data->type, data->data_len)) {
85 		return false;
86 	}
87 
88 	if (data->type == BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT) {
89 		if (data->data_len != 2) { /* Stream context size */
90 			return false;
91 		}
92 
93 		*stream_context_found = true;
94 		return false;
95 	}
96 
97 	return true;
98 }
99 
valid_subgroup_metadata_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)100 static bool valid_subgroup_metadata_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
101 {
102 	static uint8_t metadata[CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE];
103 	static size_t metadata_size;
104 	bool stream_context_found = false;
105 	uint8_t *meta;
106 	int ret;
107 
108 	ret = bt_bap_base_get_subgroup_codec_meta(subgroup, &meta);
109 	if (ret < 0) {
110 		FAIL("Could not get subgroup meta: %d\n", ret);
111 		return false;
112 	}
113 
114 	if (TEST_FLAG(flag_base_received) && (!util_eq(meta, ret, metadata, metadata_size))) {
115 		LOG_DBG("Metadata updated");
116 		SET_FLAG(flag_base_metadata_updated);
117 	}
118 
119 	metadata_size = (size_t)ret;
120 
121 	ret = bt_audio_data_parse(meta, (size_t)ret, subgroup_data_func_cb, &stream_context_found);
122 	if (ret != 0 && ret != -ECANCELED) {
123 		return false;
124 	}
125 
126 	if (!stream_context_found) {
127 		LOG_DBG("Subgroup did not have streaming context");
128 	}
129 
130 	/* if this is false, the iterator will return early with an error */
131 	return stream_context_found;
132 }
133 
base_recv_cb(struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base,size_t base_size)134 static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
135 			 size_t base_size)
136 {
137 	int ret;
138 
139 	if (TEST_FLAG(flag_base_received)) {
140 		/* Don't expect any BASE updates */
141 		return;
142 	}
143 
144 	ret = bt_bap_base_get_subgroup_count(base);
145 	if (ret < 0) {
146 		FAIL("Failed to get subgroup count: %d\n", ret);
147 		return;
148 	} else if (ret == 0) {
149 		FAIL("subgroup_count was 0\n");
150 		return;
151 	}
152 
153 	LOG_DBG("Received BASE with %d subgroups from broadcast sink %p", ret, sink);
154 
155 	ret = bt_bap_base_foreach_subgroup(base, valid_subgroup_metadata_cb, NULL);
156 	if (ret != 0) {
157 		FAIL("Failed to parse subgroups: %d\n", ret);
158 		return;
159 	}
160 
161 	(void)memcpy(received_base, base, base_size);
162 	received_base_size = base_size;
163 
164 	SET_FLAG(flag_base_received);
165 }
166 
syncable_cb(struct bt_bap_broadcast_sink * sink,const struct bt_iso_biginfo * biginfo)167 static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo)
168 {
169 	LOG_DBG("Broadcast sink %p syncable with%s encryption", sink,
170 		biginfo->encryption ? "" : "out");
171 	SET_FLAG(flag_syncable);
172 }
173 
broadcast_sink_started_cb(struct bt_bap_broadcast_sink * sink)174 static void broadcast_sink_started_cb(struct bt_bap_broadcast_sink *sink)
175 {
176 	SET_FLAG(flag_broadcast_started);
177 }
178 
broadcast_sink_stopped_cb(struct bt_bap_broadcast_sink * sink,uint8_t reason)179 static void broadcast_sink_stopped_cb(struct bt_bap_broadcast_sink *sink, uint8_t reason)
180 {
181 	SET_FLAG(flag_broadcast_stopped);
182 }
183 
bap_pa_sync_synced_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)184 static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
185 				  struct bt_le_per_adv_sync_synced_info *info)
186 {
187 	if (sync == pa_sync) {
188 		LOG_DBG("PA sync %p synced for broadcast sink with broadcast ID 0x%06X", sync,
189 			cached_recv_state->broadcast_id);
190 
191 		SET_FLAG(flag_pa_synced);
192 	} else {
193 		FAIL("Unexpected PA sync: %p\n");
194 	}
195 }
196 
bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)197 static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
198 				      const struct bt_le_per_adv_sync_term_info *info)
199 {
200 	if (sync == pa_sync) {
201 		LOG_DBG("PA sync %p lost with reason %u", sync, info->reason);
202 		pa_sync = NULL;
203 
204 		SET_FLAG(flag_pa_sync_lost);
205 	}
206 }
207 
stream_enabled_cb(struct bt_bap_stream * stream)208 static void stream_enabled_cb(struct bt_bap_stream *stream)
209 {
210 	struct bt_bap_ep_info ep_info;
211 	int err;
212 
213 	LOG_DBG("Enabled: stream %p ", stream);
214 
215 	err = bt_bap_ep_get_info(stream->ep, &ep_info);
216 	if (err != 0) {
217 		FAIL("Failed to get ep info: %d\n", err);
218 		return;
219 	}
220 
221 	if (ep_info.dir == BT_AUDIO_DIR_SINK) {
222 		/* Automatically do the receiver start ready operation */
223 		err = bt_bap_stream_start(stream);
224 
225 		if (err != 0) {
226 			FAIL("Failed to start stream: %d\n", err);
227 			return;
228 		}
229 	}
230 }
231 
stream_started_cb(struct bt_bap_stream * stream)232 static void stream_started_cb(struct bt_bap_stream *stream)
233 {
234 	struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
235 
236 	memset(&test_stream->last_info, 0, sizeof(test_stream->last_info));
237 	test_stream->rx_cnt = 0U;
238 	test_stream->valid_rx_cnt = 0U;
239 	test_stream->seq_num = 0U;
240 	test_stream->tx_cnt = 0U;
241 
242 	LOG_DBG("Started stream %p", stream);
243 
244 	SET_FLAG(flag_stream_started);
245 }
246 
stream_stopped_cb(struct bt_bap_stream * stream,uint8_t reason)247 static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
248 {
249 	LOG_DBG("Stopped stream %p with reason 0x%02X", stream, reason);
250 
251 	SET_FLAG(flag_stream_stopped);
252 }
253 
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)254 static int pa_sync_req_cb(struct bt_conn *conn,
255 			  const struct bt_bap_scan_delegator_recv_state *recv_state,
256 			  bool past_avail, uint16_t pa_interval)
257 {
258 	if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED ||
259 	    recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
260 		/* Already syncing */
261 		/* TODO: Terminate existing sync and then sync to new?*/
262 		return -EALREADY;
263 	}
264 
265 	LOG_DBG("Sync request");
266 
267 	cached_pa_interval = pa_interval;
268 	cached_recv_state = recv_state;
269 
270 	SET_FLAG(flag_pa_request);
271 
272 	return 0;
273 }
274 
pa_sync_term_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state)275 static int pa_sync_term_req_cb(struct bt_conn *conn,
276 			       const struct bt_bap_scan_delegator_recv_state *recv_state)
277 {
278 	if (pa_sync == NULL || recv_state->pa_sync_state == BT_BAP_PA_STATE_NOT_SYNCED) {
279 		return -EALREADY;
280 	}
281 
282 	UNSET_FLAG(flag_pa_request);
283 
284 	return 0;
285 }
286 
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])287 static int bis_sync_req_cb(struct bt_conn *conn,
288 			   const struct bt_bap_scan_delegator_recv_state *recv_state,
289 			   const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
290 {
291 	cached_bis_sync_req = 0U;
292 
293 	for (uint8_t i = 0U; i < recv_state->num_subgroups; i++) {
294 		cached_bis_sync_req |= bis_sync_req[i];
295 	}
296 
297 	if (cached_bis_sync_req != 0U) {
298 		SET_FLAG(flag_bis_sync_requested);
299 	} else {
300 		UNSET_FLAG(flag_bis_sync_requested);
301 	}
302 
303 	LOG_DBG("bis_sync_req 0x%08X", cached_bis_sync_req);
304 
305 	cached_recv_state = recv_state;
306 
307 	return 0;
308 }
309 
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])310 static void broadcast_code_cb(struct bt_conn *conn,
311 			      const struct bt_bap_scan_delegator_recv_state *recv_state,
312 			      const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
313 {
314 	LOG_DBG("Broadcast code received for %p", recv_state);
315 
316 	if (memcmp(broadcast_code, BROADCAST_CODE, sizeof(BROADCAST_CODE)) != 0) {
317 		FAIL("Failed to receive correct broadcast code\n");
318 		return;
319 	}
320 
321 	SET_FLAG(flag_broadcast_code);
322 }
323 
stream_alloc(void)324 static struct bt_bap_stream *stream_alloc(void)
325 {
326 	for (size_t i = 0; i < ARRAY_SIZE(streams); i++) {
327 		struct bt_bap_stream *stream = bap_stream_from_audio_test_stream(&streams[i]);
328 
329 		if (!stream->conn) {
330 			return stream;
331 		}
332 	}
333 
334 	return NULL;
335 }
336 
unicast_server_config(struct bt_conn * conn,const struct bt_bap_ep * ep,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_stream ** stream,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)337 static int unicast_server_config(struct bt_conn *conn, const struct bt_bap_ep *ep,
338 				 enum bt_audio_dir dir, const struct bt_audio_codec_cfg *codec_cfg,
339 				 struct bt_bap_stream **stream,
340 				 struct bt_bap_qos_cfg_pref *const pref,
341 				 struct bt_bap_ascs_rsp *rsp)
342 {
343 	LOG_DBG("ASE Codec Config: conn %p ep %p dir %u", conn, ep, dir);
344 
345 	print_codec_cfg(codec_cfg);
346 
347 	*stream = stream_alloc();
348 	if (*stream == NULL) {
349 		LOG_DBG("No streams available");
350 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM, BT_BAP_ASCS_REASON_NONE);
351 
352 		return -ENOMEM;
353 	}
354 
355 	LOG_DBG("ASE Codec Config stream %p", *stream);
356 
357 	SET_FLAG(flag_stream_configured);
358 
359 	*pref = unicast_qos_pref;
360 
361 	return 0;
362 }
363 
unicast_server_reconfig(struct bt_bap_stream * stream,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)364 static int unicast_server_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir,
365 				   const struct bt_audio_codec_cfg *codec_cfg,
366 				   struct bt_bap_qos_cfg_pref *const pref,
367 				   struct bt_bap_ascs_rsp *rsp)
368 {
369 	LOG_DBG("ASE Codec Reconfig: stream %p", stream);
370 
371 	print_codec_cfg(codec_cfg);
372 
373 	*pref = unicast_qos_pref;
374 
375 	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_UNSUPPORTED, BT_BAP_ASCS_REASON_NONE);
376 
377 	/* We only support one QoS at the moment, reject changes */
378 	return -ENOEXEC;
379 }
380 
unicast_server_qos(struct bt_bap_stream * stream,const struct bt_bap_qos_cfg * qos,struct bt_bap_ascs_rsp * rsp)381 static int unicast_server_qos(struct bt_bap_stream *stream, const struct bt_bap_qos_cfg *qos,
382 			      struct bt_bap_ascs_rsp *rsp)
383 {
384 	LOG_DBG("QoS: stream %p qos %p", stream, qos);
385 
386 	print_qos(qos);
387 
388 	return 0;
389 }
390 
ascs_data_func_cb(struct bt_data * data,void * user_data)391 static bool ascs_data_func_cb(struct bt_data *data, void *user_data)
392 {
393 	struct bt_bap_ascs_rsp *rsp = (struct bt_bap_ascs_rsp *)user_data;
394 
395 	if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(data->type)) {
396 		LOG_DBG("Invalid metadata type %u or length %u", data->type, data->data_len);
397 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED, data->type);
398 		return false;
399 	}
400 
401 	return true;
402 }
403 
unicast_server_enable(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)404 static int unicast_server_enable(struct bt_bap_stream *stream, const uint8_t meta[],
405 				 size_t meta_len, struct bt_bap_ascs_rsp *rsp)
406 {
407 	LOG_DBG("Enable: stream %p meta_len %zu", stream, meta_len);
408 
409 	return bt_audio_data_parse(meta, meta_len, ascs_data_func_cb, rsp);
410 }
411 
unicast_server_start(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)412 static int unicast_server_start(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
413 {
414 	LOG_DBG("Start: stream %p", stream);
415 
416 	return 0;
417 }
418 
unicast_server_metadata(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)419 static int unicast_server_metadata(struct bt_bap_stream *stream, const uint8_t meta[],
420 				   size_t meta_len, struct bt_bap_ascs_rsp *rsp)
421 {
422 	LOG_DBG("Metadata: stream %p meta_len %zu", stream, meta_len);
423 
424 	return bt_audio_data_parse(meta, meta_len, ascs_data_func_cb, rsp);
425 }
426 
unicast_server_disable(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)427 static int unicast_server_disable(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
428 {
429 	LOG_DBG("Disable: stream %p", stream);
430 
431 	return 0;
432 }
433 
unicast_server_stop(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)434 static int unicast_server_stop(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
435 {
436 	LOG_DBG("Stop: stream %p", stream);
437 
438 	return 0;
439 }
440 
unicast_server_release(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)441 static int unicast_server_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
442 {
443 	LOG_DBG("Release: stream %p", stream);
444 
445 	return 0;
446 }
447 
set_location(void)448 static void set_location(void)
449 {
450 	int err;
451 
452 	if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC)) {
453 		err = bt_pacs_set_location(BT_AUDIO_DIR_SINK, BT_AUDIO_LOCATION_FRONT_CENTER);
454 		if (err != 0) {
455 			FAIL("Failed to set sink location (err %d)\n", err);
456 			return;
457 		}
458 	}
459 
460 	if (IS_ENABLED(CONFIG_BT_PAC_SRC_LOC)) {
461 		err = bt_pacs_set_location(BT_AUDIO_DIR_SOURCE,
462 					   BT_AUDIO_LOCATION_FRONT_LEFT |
463 						   BT_AUDIO_LOCATION_FRONT_RIGHT);
464 		if (err != 0) {
465 			FAIL("Failed to set source location (err %d)\n", err);
466 			return;
467 		}
468 	}
469 
470 	LOG_DBG("Location successfully set");
471 }
472 
set_supported_contexts(void)473 static void set_supported_contexts(void)
474 {
475 	int err;
476 
477 	if (IS_ENABLED(CONFIG_BT_PAC_SNK)) {
478 		err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK, SINK_CONTEXT);
479 		if (err != 0) {
480 			FAIL("Failed to set sink supported contexts (err %d)\n", err);
481 			return;
482 		}
483 
484 		LOG_DBG("Supported sink contexts successfully set to 0x%04X", SINK_CONTEXT);
485 	}
486 
487 	if (IS_ENABLED(CONFIG_BT_PAC_SRC)) {
488 		err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE, SOURCE_CONTEXT);
489 		if (err != 0) {
490 			FAIL("Failed to set source supported contexts (err %d)\n", err);
491 			return;
492 		}
493 
494 		LOG_DBG("Supported source contexts successfully set to 0x%04X", SOURCE_CONTEXT);
495 	}
496 }
497 
set_available_contexts(void)498 static void set_available_contexts(void)
499 {
500 	if (IS_ENABLED(CONFIG_BT_PAC_SNK)) {
501 		const int err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK, SINK_CONTEXT);
502 
503 		if (err != 0) {
504 			FAIL("Failed to set sink available contexts (err %d)\n", err);
505 			return;
506 		}
507 
508 		LOG_DBG("Available sink contexts successfully set to 0x%04X", SINK_CONTEXT);
509 	}
510 
511 	if (IS_ENABLED(CONFIG_BT_PAC_SRC)) {
512 		const int err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE, SOURCE_CONTEXT);
513 
514 		if (err != 0) {
515 			FAIL("Failed to set source available contexts (err %d)\n", err);
516 			return;
517 		}
518 
519 		LOG_DBG("Available source contexts successfully set to 0x%04X", SOURCE_CONTEXT);
520 	}
521 }
522 
test_start_adv(void)523 static void test_start_adv(void)
524 {
525 	struct bt_le_ext_adv *ext_adv;
526 
527 	setup_connectable_adv(&ext_adv);
528 }
529 
register_callbacks(void)530 static void register_callbacks(void)
531 {
532 	static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = {
533 		.base_recv = base_recv_cb,
534 		.syncable = syncable_cb,
535 		.started = broadcast_sink_started_cb,
536 		.stopped = broadcast_sink_stopped_cb,
537 	};
538 	static struct bt_bap_scan_delegator_cb scan_delegator_cbs = {
539 		.pa_sync_req = pa_sync_req_cb,
540 		.pa_sync_term_req = pa_sync_term_req_cb,
541 		.bis_sync_req = bis_sync_req_cb,
542 		.broadcast_code = broadcast_code_cb,
543 	};
544 	static struct bt_bap_unicast_server_cb unicast_server_cbs = {
545 		.config = unicast_server_config,
546 		.reconfig = unicast_server_reconfig,
547 		.qos = unicast_server_qos,
548 		.enable = unicast_server_enable,
549 		.start = unicast_server_start,
550 		.metadata = unicast_server_metadata,
551 		.disable = unicast_server_disable,
552 		.stop = unicast_server_stop,
553 		.release = unicast_server_release,
554 	};
555 	static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = {
556 		.synced = bap_pa_sync_synced_cb,
557 		.term = bap_pa_sync_terminated_cb,
558 	};
559 	static struct bt_bap_stream_ops stream_ops = {
560 		.enabled = stream_enabled_cb,
561 		.started = stream_started_cb,
562 		.stopped = stream_stopped_cb,
563 		.recv = bap_stream_rx_recv_cb,
564 	};
565 	int err;
566 
567 	err = bt_bap_unicast_server_register_cb(&unicast_server_cbs);
568 	if (err != 0) {
569 		FAIL("Failed to register unicast server callbacks (err %d)\n", err);
570 
571 		return;
572 	}
573 
574 	err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
575 	if (err != 0) {
576 		FAIL("Scan deligator register failed (err %d)\n", err);
577 
578 		return;
579 	}
580 
581 	err = bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
582 	if (err != 0) {
583 		FAIL("Scan deligator register failed (err %d)\n", err);
584 
585 		return;
586 	}
587 
588 	err = bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
589 	if (err != 0) {
590 		FAIL("Scan deligator register failed (err %d)\n", err);
591 
592 		return;
593 	}
594 
595 	ARRAY_FOR_EACH_PTR(streams, stream) {
596 		bt_cap_stream_ops_register(cap_stream_from_audio_test_stream(stream), &stream_ops);
597 	}
598 }
599 
init(void)600 static void init(void)
601 {
602 	static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3(
603 		BT_AUDIO_CODEC_CAP_FREQ_ANY, BT_AUDIO_CODEC_CAP_DURATION_ANY,
604 		BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1, 2), 30, 240, 2,
605 		(BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA));
606 	const struct bt_pacs_register_param pacs_param = {
607 #if defined(CONFIG_BT_PAC_SNK)
608 		.snk_pac = true,
609 #endif /* CONFIG_BT_PAC_SNK */
610 #if defined(CONFIG_BT_PAC_SNK_LOC)
611 		.snk_loc = true,
612 #endif /* CONFIG_BT_PAC_SNK_LOC */
613 #if defined(CONFIG_BT_PAC_SRC)
614 		.src_pac = true,
615 #endif /* CONFIG_BT_PAC_SRC */
616 #if defined(CONFIG_BT_PAC_SRC_LOC)
617 		.src_loc = true,
618 #endif /* CONFIG_BT_PAC_SRC_LOC */
619 	};
620 	const struct bt_csip_set_member_register_param csip_set_member_param = {
621 		.set_size = 3,
622 		.rank = 1,
623 		.lockable = true,
624 		.sirk = TEST_SAMPLE_SIRK,
625 	};
626 	static struct bt_bap_unicast_server_register_param param = {
627 		.snk_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
628 		.src_cnt = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT,
629 	};
630 	static struct bt_csip_set_member_svc_inst *csip_set_member;
631 	static struct bt_pacs_cap pacs_cap = {
632 		.codec_cap = &codec_cap,
633 	};
634 
635 	int err;
636 
637 	err = bt_enable(NULL);
638 	if (err != 0) {
639 		FAIL("Bluetooth enable failed (err %d)\n", err);
640 		return;
641 	}
642 
643 	LOG_DBG("Bluetooth initialized");
644 
645 	err = bt_pacs_register(&pacs_param);
646 	if (err) {
647 		FAIL("Could not register PACS (err %d)\n", err);
648 		return;
649 	}
650 
651 	err = bt_cap_acceptor_register(&csip_set_member_param, &csip_set_member);
652 	if (err != 0) {
653 		FAIL("CAP acceptor failed to register (err %d)\n", err);
654 		return;
655 	}
656 
657 	err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &pacs_cap);
658 	if (err != 0) {
659 		FAIL("Broadcast capability register failed (err %d)\n", err);
660 
661 		return;
662 	}
663 
664 	err = bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &pacs_cap);
665 	if (err != 0) {
666 		FAIL("Broadcast capability register failed (err %d)\n", err);
667 
668 		return;
669 	}
670 
671 	err = bt_bap_unicast_server_register(&param);
672 	if (err != 0) {
673 		FAIL("Failed to register unicast server (err %d)\n", err);
674 
675 		return;
676 	}
677 
678 	set_supported_contexts();
679 	set_available_contexts();
680 	set_location();
681 
682 	register_callbacks();
683 }
684 
pa_sync_create(void)685 static void pa_sync_create(void)
686 {
687 	struct bt_le_per_adv_sync_param create_params = {0};
688 	int err;
689 
690 	bt_addr_le_copy(&create_params.addr, &cached_recv_state->addr);
691 	create_params.options = BT_LE_PER_ADV_SYNC_OPT_NONE;
692 	create_params.sid = cached_recv_state->adv_sid;
693 	create_params.skip = PA_SYNC_SKIP;
694 	create_params.timeout = interval_to_sync_timeout(cached_pa_interval);
695 
696 	err = bt_le_per_adv_sync_create(&create_params, &pa_sync);
697 	if (err != 0) {
698 		FAIL("Could not create Broadcast PA sync: %d\n", err);
699 		return;
700 	}
701 
702 	LOG_DBG("Waiting for PA sync");
703 	WAIT_FOR_FLAG(flag_pa_synced);
704 }
705 
create_and_sync_sink(void)706 static void create_and_sync_sink(void)
707 {
708 	struct bt_bap_stream *broadcast_streams[ARRAY_SIZE(streams)];
709 	int err;
710 
711 	LOG_DBG("Creating the broadcast sink");
712 	err = bt_bap_broadcast_sink_create(pa_sync, cached_recv_state->broadcast_id,
713 					   &broadcast_sink);
714 	if (err != 0) {
715 		FAIL("Unable to create the sink: %d\n", err);
716 		return;
717 	}
718 
719 	LOG_DBG("Broadcast source PA synced, waiting for BASE");
720 	WAIT_FOR_FLAG(flag_base_received);
721 	LOG_DBG("BASE received");
722 
723 	LOG_DBG("Waiting for BIG syncable");
724 	WAIT_FOR_FLAG(flag_syncable);
725 
726 	for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
727 		broadcast_streams[i] = bap_stream_from_audio_test_stream(&streams[i]);
728 	}
729 
730 	if (cached_bis_sync_req == 0U) {
731 		FAIL("Invalid cached_bis_sync_req: %u", cached_bis_sync_req);
732 		return;
733 	}
734 
735 	LOG_DBG("Syncing the sink to 0x%08x", cached_bis_sync_req);
736 
737 	err = bt_bap_broadcast_sink_sync(broadcast_sink, cached_bis_sync_req, broadcast_streams,
738 					 NULL);
739 	if (err != 0) {
740 		FAIL("Unable to sync the sink: %d\n", err);
741 		return;
742 	}
743 
744 	/* Wait for all to be started */
745 	LOG_DBG("Waiting for broadcast streams to be started");
746 	WAIT_FOR_FLAG(flag_broadcast_started);
747 }
748 
wait_for_data(void)749 static void wait_for_data(void)
750 {
751 	UNSET_FLAG(flag_audio_received);
752 
753 	LOG_DBG("Waiting for data");
754 	WAIT_FOR_FLAG(flag_audio_received);
755 	LOG_DBG("Data received");
756 }
757 
test_cap_handover_peripheral_unicast_to_broadcast(void)758 static void test_cap_handover_peripheral_unicast_to_broadcast(void)
759 {
760 	init();
761 
762 	test_start_adv();
763 
764 	WAIT_FOR_FLAG(flag_connected);
765 
766 	/* Wait until initiator is done starting streams */
767 	WAIT_FOR_FLAG(flag_stream_started);
768 	backchannel_sync_wait(CAP_INITIATOR_DEV_ID);
769 
770 	wait_for_data();
771 
772 	/* let initiator know we have received what we wanted */
773 	backchannel_sync_send(CAP_INITIATOR_DEV_ID);
774 
775 	/* Wait for unicast to be stopped */
776 	WAIT_FOR_FLAG(flag_stream_stopped);
777 
778 	/* Wait for a PA sync request to switch from unicast to broadcast */
779 	LOG_DBG("Waiting for PA sync request");
780 	WAIT_FOR_FLAG(flag_pa_request);
781 	pa_sync_create();
782 
783 	/* Wait for a BIG sync request to sync to broadcast */
784 	WAIT_FOR_FLAG(flag_bis_sync_requested);
785 	create_and_sync_sink();
786 
787 	wait_for_data();
788 
789 	/* let initiator know we have received what we wanted */
790 	backchannel_sync_send(CAP_INITIATOR_DEV_ID);
791 
792 	/* Wait for broadcast to be stopped */
793 	WAIT_FOR_FLAG(flag_broadcast_stopped);
794 
795 	PASS("CAP acceptor unicast passed\n");
796 }
797 
798 static const struct bst_test_instance test_cap_handover_peripheral[] = {
799 	{
800 		.test_id = "cap_handover_peripheral_unicast_to_broadcast",
801 		.test_pre_init_f = test_init,
802 		.test_tick_f = test_tick,
803 		.test_main_f = test_cap_handover_peripheral_unicast_to_broadcast,
804 	},
805 	BSTEST_END_MARKER,
806 };
807 
test_cap_handover_peripheral_install(struct bst_test_list * tests)808 struct bst_test_list *test_cap_handover_peripheral_install(struct bst_test_list *tests)
809 {
810 	return bst_add_tests(tests, test_cap_handover_peripheral);
811 }
812 
813 #else /* !(CONFIG_BT_CAP_ACCEPTOR) */
814 
test_cap_handover_peripheral_install(struct bst_test_list * tests)815 struct bst_test_list *test_cap_handover_peripheral_install(struct bst_test_list *tests)
816 {
817 	return tests;
818 }
819 
820 #endif /* CONFIG_BT_CAP_ACCEPTOR */
821