1 /*
2  * Copyright 2023 NXP
3  * Copyright (c) 2024 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
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/audio/audio.h>
14 #include <zephyr/bluetooth/audio/bap.h>
15 #include <zephyr/bluetooth/audio/cap.h>
16 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
17 #include <zephyr/bluetooth/audio/pacs.h>
18 #include <zephyr/bluetooth/audio/pbp.h>
19 #include <zephyr/bluetooth/addr.h>
20 #include <zephyr/bluetooth/audio/lc3.h>
21 #include <zephyr/bluetooth/bluetooth.h>
22 #include <zephyr/bluetooth/gap.h>
23 #include <zephyr/bluetooth/iso.h>
24 #include <zephyr/bluetooth/uuid.h>
25 #include <zephyr/kernel.h>
26 #include <zephyr/net_buf.h>
27 #include <zephyr/sys/byteorder.h>
28 #include <zephyr/sys/printk.h>
29 #include <zephyr/sys/util.h>
30 #include <zephyr/sys/util_macro.h>
31 
32 #include "bap_stream_rx.h"
33 #include "bstests.h"
34 #include "common.h"
35 
36 #if defined(CONFIG_BT_PBP)
37 #define SEM_TIMEOUT K_SECONDS(30)
38 
39 extern enum bst_result_t bst_result;
40 
41 static bool pbs_found;
42 
43 static K_SEM_DEFINE(sem_pa_synced, 0U, 1U);
44 static K_SEM_DEFINE(sem_base_received, 0U, 1U);
45 static K_SEM_DEFINE(sem_syncable, 0U, 1U);
46 static K_SEM_DEFINE(sem_pa_sync_lost, 0U, 1U);
47 
48 static struct bt_bap_broadcast_sink *broadcast_sink;
49 static struct bt_le_per_adv_sync *bcast_pa_sync;
50 
51 static struct audio_test_stream test_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
52 static struct bt_bap_stream *streams_p[ARRAY_SIZE(test_streams)];
53 
54 static const struct bt_audio_codec_cap codec = BT_AUDIO_CODEC_CAP_LC3(
55 	BT_AUDIO_CODEC_CAP_FREQ_16KHZ | BT_AUDIO_CODEC_CAP_FREQ_24KHZ |
56 		BT_AUDIO_CODEC_CAP_FREQ_48KHZ,
57 	BT_AUDIO_CODEC_CAP_DURATION_10, BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1), 40u, 155u, 1u,
58 	BT_AUDIO_CONTEXT_TYPE_MEDIA);
59 
60 /* Create a mask for the maximum BIS we can sync to using the number of streams
61  * we have. We add an additional 1 since the bis indexes start from 1 and not
62  * 0.
63  */
64 static const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(test_streams) + 1U);
65 static uint32_t bis_index_bitfield;
66 static uint32_t broadcast_id;
67 
68 static struct bt_pacs_cap cap = {
69 	.codec_cap = &codec,
70 };
71 
72 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info,
73 				struct net_buf_simple *ad);
74 
75 static struct bt_le_scan_cb broadcast_scan_cb = {
76 	.recv = broadcast_scan_recv
77 };
78 
base_recv_cb(struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base,size_t base_size)79 static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
80 			 size_t base_size)
81 {
82 	k_sem_give(&sem_base_received);
83 }
84 
syncable_cb(struct bt_bap_broadcast_sink * sink,const struct bt_iso_biginfo * biginfo)85 static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo)
86 {
87 	printk("Broadcast sink %p is now syncable\n", sink);
88 	k_sem_give(&sem_syncable);
89 }
90 
91 static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = {
92 	.base_recv = base_recv_cb,
93 	.syncable = syncable_cb,
94 };
95 
started_cb(struct bt_bap_stream * stream)96 static void started_cb(struct bt_bap_stream *stream)
97 {
98 	struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
99 
100 	memset(&test_stream->last_info, 0, sizeof(test_stream->last_info));
101 	test_stream->rx_cnt = 0U;
102 	test_stream->valid_rx_cnt = 0U;
103 
104 	printk("Stream %p started\n", stream);
105 }
106 
stopped_cb(struct bt_bap_stream * stream,uint8_t reason)107 static void stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
108 {
109 	printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
110 }
111 
pa_decode_base(struct bt_data * data,void * user_data)112 static bool pa_decode_base(struct bt_data *data, void *user_data)
113 {
114 	const struct bt_bap_base *base = bt_bap_base_get_base_from_ad(data);
115 	uint32_t base_bis_index_bitfield = 0U;
116 	int err;
117 
118 	/* Base is NULL if the data does not contain a valid BASE */
119 	if (base == NULL) {
120 		return true;
121 	}
122 
123 	err = bt_bap_base_get_bis_indexes(base, &base_bis_index_bitfield);
124 	if (err != 0) {
125 		return false;
126 	}
127 
128 	bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;
129 	k_sem_give(&sem_base_received);
130 
131 	return false;
132 }
133 
broadcast_pa_recv(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_recv_info * info,struct net_buf_simple * buf)134 static void broadcast_pa_recv(struct bt_le_per_adv_sync *sync,
135 			const struct bt_le_per_adv_sync_recv_info *info,
136 			struct net_buf_simple *buf)
137 {
138 	bt_data_parse(buf, pa_decode_base, NULL);
139 }
140 
broadcast_pa_synced(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)141 static void broadcast_pa_synced(struct bt_le_per_adv_sync *sync,
142 			struct bt_le_per_adv_sync_synced_info *info)
143 {
144 	printk("PA synced\n");
145 	k_sem_give(&sem_pa_synced);
146 }
147 
broadcast_pa_terminated(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)148 static void broadcast_pa_terminated(struct bt_le_per_adv_sync *sync,
149 				    const struct bt_le_per_adv_sync_term_info *info)
150 {
151 	if (sync == bcast_pa_sync) {
152 		printk("PA sync %p lost with reason %u\n", sync, info->reason);
153 		bcast_pa_sync = NULL;
154 
155 		k_sem_give(&sem_pa_sync_lost);
156 	}
157 }
158 
159 static struct bt_bap_stream_ops stream_ops = {
160 	.started = started_cb,
161 	.stopped = stopped_cb,
162 	.recv = bap_stream_rx_recv_cb,
163 };
164 
165 static struct bt_le_per_adv_sync_cb broadcast_sync_cb = {
166 	.synced = broadcast_pa_synced,
167 	.recv = broadcast_pa_recv,
168 	.term = broadcast_pa_terminated,
169 };
170 
reset(void)171 static int reset(void)
172 {
173 	int err;
174 
175 	k_sem_reset(&sem_pa_synced);
176 	k_sem_reset(&sem_base_received);
177 	k_sem_reset(&sem_syncable);
178 	k_sem_reset(&sem_pa_sync_lost);
179 	UNSET_FLAG(flag_audio_received);
180 
181 	broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
182 	bis_index_bitfield = 0U;
183 	pbs_found = false;
184 
185 	if (broadcast_sink != NULL) {
186 		err = bt_bap_broadcast_sink_delete(broadcast_sink);
187 		if (err) {
188 			printk("Deleting broadcast sink failed (err %d)\n", err);
189 
190 			return err;
191 		}
192 
193 		broadcast_sink = NULL;
194 	}
195 
196 	return 0;
197 }
198 
init(void)199 static int init(void)
200 {
201 	const struct bt_pacs_register_param pacs_param = {
202 		.snk_pac = true,
203 		.snk_loc = true,
204 		.src_pac = true,
205 		.src_loc = true,
206 	};
207 	int err;
208 
209 	err = bt_enable(NULL);
210 	if (err) {
211 		FAIL("Bluetooth enable failed (err %d)\n", err);
212 
213 		return err;
214 	}
215 
216 	printk("Bluetooth initialized\n");
217 
218 	err = bt_pacs_register(&pacs_param);
219 	if (err) {
220 		FAIL("Could not register PACS (err %d)\n", err);
221 		return err;
222 	}
223 
224 	bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
225 	bt_le_per_adv_sync_cb_register(&broadcast_sync_cb);
226 
227 	err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap);
228 	if (err) {
229 		printk("Capability register failed (err %d)\n", err);
230 
231 		return err;
232 	}
233 
234 	for (size_t i = 0U; i < ARRAY_SIZE(test_streams); i++) {
235 		streams_p[i] = bap_stream_from_audio_test_stream(&test_streams[i]);
236 		bt_bap_stream_cb_register(streams_p[i], &stream_ops);
237 	}
238 
239 	return 0;
240 }
241 
sync_broadcast_pa(const struct bt_le_scan_recv_info * info)242 static void sync_broadcast_pa(const struct bt_le_scan_recv_info *info)
243 {
244 	struct bt_le_per_adv_sync_param param;
245 	int err;
246 
247 	/* Unregister the callbacks to prevent broadcast_scan_recv to be called again */
248 	bt_le_scan_cb_unregister(&broadcast_scan_cb);
249 	err = bt_le_scan_stop();
250 	if (err != 0) {
251 		printk("Could not stop scan: %d\n", err);
252 	}
253 
254 	bt_addr_le_copy(&param.addr, info->addr);
255 	param.options = 0;
256 	param.sid = info->sid;
257 	param.skip = PA_SYNC_SKIP;
258 	param.timeout = interval_to_sync_timeout(info->interval);
259 	err = bt_le_per_adv_sync_create(&param, &bcast_pa_sync);
260 	if (err != 0) {
261 		printk("Could not sync to PA: %d\n", err);
262 	}
263 }
264 
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)265 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
266 {
267 	enum bt_pbp_announcement_feature source_features;
268 	struct bt_uuid_16 adv_uuid;
269 	uint8_t *tmp_meta;
270 	int ret;
271 
272 	if (data->type != BT_DATA_SVC_DATA16) {
273 		return true;
274 	}
275 
276 	if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
277 		return true;
278 	}
279 
280 	if (!bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
281 		/* Save broadcast_id */
282 		if (broadcast_id == BT_BAP_INVALID_BROADCAST_ID) {
283 			broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
284 		}
285 
286 		/* Found Broadcast Audio and Public Broadcast Announcement Services */
287 		if (pbs_found) {
288 			return false;
289 		}
290 	}
291 
292 	ret = bt_pbp_parse_announcement(data, &source_features, &tmp_meta);
293 	if (ret >= 0) {
294 		printk("Found Suitable Public Broadcast Announcement with %d octets of metadata\n",
295 		       ret);
296 		pbs_found = true;
297 
298 		/* Continue parsing if Broadcast Audio Announcement Service was not found */
299 		if (broadcast_id == BT_BAP_INVALID_BROADCAST_ID) {
300 			return true;
301 		}
302 
303 		return false;
304 	}
305 
306 	/* Continue parsing */
307 	return true;
308 }
309 
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)310 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info,
311 				struct net_buf_simple *ad)
312 {
313 	pbs_found = false;
314 
315 	/* We are only interested in non-connectable periodic advertisers */
316 	if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) ||
317 	     info->interval == 0) {
318 		return;
319 	}
320 
321 	bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)&broadcast_id);
322 
323 	if ((broadcast_id != BT_BAP_INVALID_BROADCAST_ID) && pbs_found) {
324 		sync_broadcast_pa(info);
325 	}
326 }
327 
test_main(void)328 static void test_main(void)
329 {
330 	int count = 0;
331 	int err;
332 
333 	init();
334 
335 	while (count < PBP_STREAMS_TO_SEND) {
336 		printk("Resetting for iteration %d\n", count);
337 		err = reset();
338 		if (err != 0) {
339 			printk("Resetting failed: %d\n", err);
340 			break;
341 		}
342 
343 		/* Register callbacks */
344 		bt_le_scan_cb_register(&broadcast_scan_cb);
345 
346 		/* Start scanning */
347 		printk("Starting scan\n");
348 		err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
349 		if (err) {
350 			printk("Scan start failed (err %d)\n", err);
351 			break;
352 		}
353 
354 		/* Wait for PA sync */
355 		printk("Waiting for PA Sync\n");
356 		err = k_sem_take(&sem_pa_synced, SEM_TIMEOUT);
357 		if (err != 0) {
358 			printk("sem_pa_synced timed out\n");
359 			break;
360 		}
361 
362 		/* Wait for BASE decode */
363 		printk("Waiting for BASE\n");
364 		err = k_sem_take(&sem_base_received, SEM_TIMEOUT);
365 		if (err != 0) {
366 			printk("sem_base_received timed out\n");
367 			break;
368 		}
369 
370 		/* Create broadcast sink */
371 		printk("Creating broadcast sink\n");
372 		err = bt_bap_broadcast_sink_create(bcast_pa_sync, broadcast_id, &broadcast_sink);
373 		if (err != 0) {
374 			printk("Sink not created!\n");
375 			break;
376 		}
377 
378 		printk("Waiting for syncable\n");
379 		err = k_sem_take(&sem_syncable, SEM_TIMEOUT);
380 		if (err != 0) {
381 			printk("sem_syncable timed out\n");
382 			break;
383 		}
384 
385 		/* Sync to broadcast source */
386 		printk("Syncing broadcast sink\n");
387 		err = bt_bap_broadcast_sink_sync(broadcast_sink, bis_index_bitfield,
388 						 streams_p, NULL);
389 		if (err != 0) {
390 			printk("Unable to sync to broadcast source: %d\n", err);
391 			break;
392 		}
393 
394 		/* Wait for data */
395 		printk("Waiting for data\n");
396 		WAIT_FOR_FLAG(flag_audio_received);
397 
398 		printk("Sending signal to broadcaster to stop\n");
399 		backchannel_sync_send_all(); /* let the broadcast source know it can stop */
400 
401 		/* Wait for the stream to end */
402 		printk("Waiting for sync lost\n");
403 		k_sem_take(&sem_pa_sync_lost, SEM_TIMEOUT);
404 
405 		count++;
406 	}
407 
408 	if (count == PBP_STREAMS_TO_SEND) {
409 		/* Pass if we synced only with the high quality broadcast */
410 		PASS("Public Broadcast sink passed\n");
411 	} else {
412 		FAIL("Public Broadcast sink failed (%d/%d)\n", count, PBP_STREAMS_TO_SEND);
413 	}
414 }
415 
416 static const struct bst_test_instance test_public_broadcast_sink[] = {
417 	{
418 		.test_id = "public_broadcast_sink",
419 		.test_pre_init_f = test_init,
420 		.test_tick_f = test_tick,
421 		.test_main_f = test_main
422 	},
423 	BSTEST_END_MARKER
424 };
425 
test_public_broadcast_sink_install(struct bst_test_list * tests)426 struct bst_test_list *test_public_broadcast_sink_install(struct bst_test_list *tests)
427 {
428 	return bst_add_tests(tests, test_public_broadcast_sink);
429 }
430 
431 #else /* !CONFIG_BT_PBP */
432 
test_public_broadcast_sink_install(struct bst_test_list * tests)433 struct bst_test_list *test_public_broadcast_sink_install(struct bst_test_list *tests)
434 {
435 	return tests;
436 }
437 
438 #endif /* CONFIG_BT_PBP */
439