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 
103 	printk("Stream %p started\n", stream);
104 }
105 
stopped_cb(struct bt_bap_stream * stream,uint8_t reason)106 static void stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
107 {
108 	printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
109 }
110 
pa_decode_base(struct bt_data * data,void * user_data)111 static bool pa_decode_base(struct bt_data *data, void *user_data)
112 {
113 	const struct bt_bap_base *base = bt_bap_base_get_base_from_ad(data);
114 	uint32_t base_bis_index_bitfield = 0U;
115 	int err;
116 
117 	/* Base is NULL if the data does not contain a valid BASE */
118 	if (base == NULL) {
119 		return true;
120 	}
121 
122 	err = bt_bap_base_get_bis_indexes(base, &base_bis_index_bitfield);
123 	if (err != 0) {
124 		return false;
125 	}
126 
127 	bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;
128 	k_sem_give(&sem_base_received);
129 
130 	return false;
131 }
132 
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)133 static void broadcast_pa_recv(struct bt_le_per_adv_sync *sync,
134 			const struct bt_le_per_adv_sync_recv_info *info,
135 			struct net_buf_simple *buf)
136 {
137 	bt_data_parse(buf, pa_decode_base, NULL);
138 }
139 
broadcast_pa_synced(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)140 static void broadcast_pa_synced(struct bt_le_per_adv_sync *sync,
141 			struct bt_le_per_adv_sync_synced_info *info)
142 {
143 	printk("PA synced\n");
144 	k_sem_give(&sem_pa_synced);
145 }
146 
broadcast_pa_terminated(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)147 static void broadcast_pa_terminated(struct bt_le_per_adv_sync *sync,
148 				    const struct bt_le_per_adv_sync_term_info *info)
149 {
150 	if (sync == bcast_pa_sync) {
151 		printk("PA sync %p lost with reason %u\n", sync, info->reason);
152 		bcast_pa_sync = NULL;
153 
154 		k_sem_give(&sem_pa_sync_lost);
155 	}
156 }
157 
158 static struct bt_bap_stream_ops stream_ops = {
159 	.started = started_cb,
160 	.stopped = stopped_cb,
161 	.recv = bap_stream_rx_recv_cb,
162 };
163 
164 static struct bt_le_per_adv_sync_cb broadcast_sync_cb = {
165 	.synced = broadcast_pa_synced,
166 	.recv = broadcast_pa_recv,
167 	.term = broadcast_pa_terminated,
168 };
169 
reset(void)170 static int reset(void)
171 {
172 	int err;
173 
174 	k_sem_reset(&sem_pa_synced);
175 	k_sem_reset(&sem_base_received);
176 	k_sem_reset(&sem_syncable);
177 	k_sem_reset(&sem_pa_sync_lost);
178 	UNSET_FLAG(flag_audio_received);
179 
180 	broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
181 	bis_index_bitfield = 0U;
182 	pbs_found = false;
183 
184 	if (broadcast_sink != NULL) {
185 		err = bt_bap_broadcast_sink_delete(broadcast_sink);
186 		if (err) {
187 			printk("Deleting broadcast sink failed (err %d)\n", err);
188 
189 			return err;
190 		}
191 
192 		broadcast_sink = NULL;
193 	}
194 
195 	return 0;
196 }
197 
init(void)198 static int init(void)
199 {
200 	int err;
201 
202 	err = bt_enable(NULL);
203 	if (err) {
204 		FAIL("Bluetooth enable failed (err %d)\n", err);
205 
206 		return err;
207 	}
208 
209 	printk("Bluetooth initialized\n");
210 
211 	bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
212 	bt_le_per_adv_sync_cb_register(&broadcast_sync_cb);
213 
214 	err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap);
215 	if (err) {
216 		printk("Capability register failed (err %d)\n", err);
217 
218 		return err;
219 	}
220 
221 	for (size_t i = 0U; i < ARRAY_SIZE(test_streams); i++) {
222 		streams_p[i] = bap_stream_from_audio_test_stream(&test_streams[i]);
223 		bt_bap_stream_cb_register(streams_p[i], &stream_ops);
224 	}
225 
226 	return 0;
227 }
228 
sync_broadcast_pa(const struct bt_le_scan_recv_info * info)229 static void sync_broadcast_pa(const struct bt_le_scan_recv_info *info)
230 {
231 	struct bt_le_per_adv_sync_param param;
232 	int err;
233 
234 	/* Unregister the callbacks to prevent broadcast_scan_recv to be called again */
235 	bt_le_scan_cb_unregister(&broadcast_scan_cb);
236 	err = bt_le_scan_stop();
237 	if (err != 0) {
238 		printk("Could not stop scan: %d\n", err);
239 	}
240 
241 	bt_addr_le_copy(&param.addr, info->addr);
242 	param.options = 0;
243 	param.sid = info->sid;
244 	param.skip = PA_SYNC_SKIP;
245 	param.timeout = interval_to_sync_timeout(info->interval);
246 	err = bt_le_per_adv_sync_create(&param, &bcast_pa_sync);
247 	if (err != 0) {
248 		printk("Could not sync to PA: %d\n", err);
249 	}
250 }
251 
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)252 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
253 {
254 	enum bt_pbp_announcement_feature source_features;
255 	struct bt_uuid_16 adv_uuid;
256 	uint8_t *tmp_meta;
257 	int ret;
258 
259 	if (data->type != BT_DATA_SVC_DATA16) {
260 		return true;
261 	}
262 
263 	if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
264 		return true;
265 	}
266 
267 	if (!bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
268 		/* Save broadcast_id */
269 		if (broadcast_id == BT_BAP_INVALID_BROADCAST_ID) {
270 			broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
271 		}
272 
273 		/* Found Broadcast Audio and Public Broadcast Announcement Services */
274 		if (pbs_found) {
275 			return false;
276 		}
277 	}
278 
279 	ret = bt_pbp_parse_announcement(data, &source_features, &tmp_meta);
280 	if (ret >= 0) {
281 		printk("Found Suitable Public Broadcast Announcement with %d octets of metadata\n",
282 		       ret);
283 		pbs_found = true;
284 
285 		/* Continue parsing if Broadcast Audio Announcement Service was not found */
286 		if (broadcast_id == BT_BAP_INVALID_BROADCAST_ID) {
287 			return true;
288 		}
289 
290 		return false;
291 	}
292 
293 	/* Continue parsing */
294 	return true;
295 }
296 
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)297 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info,
298 				struct net_buf_simple *ad)
299 {
300 	pbs_found = false;
301 
302 	/* We are only interested in non-connectable periodic advertisers */
303 	if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) ||
304 	     info->interval == 0) {
305 		return;
306 	}
307 
308 	bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)&broadcast_id);
309 
310 	if ((broadcast_id != BT_BAP_INVALID_BROADCAST_ID) && pbs_found) {
311 		sync_broadcast_pa(info);
312 	}
313 }
314 
test_main(void)315 static void test_main(void)
316 {
317 	int count = 0;
318 	int err;
319 
320 	init();
321 
322 	while (count < PBP_STREAMS_TO_SEND) {
323 		printk("Resetting for iteration %d\n", count);
324 		err = reset();
325 		if (err != 0) {
326 			printk("Resetting failed: %d\n", err);
327 			break;
328 		}
329 
330 		/* Register callbacks */
331 		bt_le_scan_cb_register(&broadcast_scan_cb);
332 
333 		/* Start scanning */
334 		printk("Starting scan\n");
335 		err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
336 		if (err) {
337 			printk("Scan start failed (err %d)\n", err);
338 			break;
339 		}
340 
341 		/* Wait for PA sync */
342 		printk("Waiting for PA Sync\n");
343 		err = k_sem_take(&sem_pa_synced, SEM_TIMEOUT);
344 		if (err != 0) {
345 			printk("sem_pa_synced timed out\n");
346 			break;
347 		}
348 
349 		/* Wait for BASE decode */
350 		printk("Waiting for BASE\n");
351 		err = k_sem_take(&sem_base_received, SEM_TIMEOUT);
352 		if (err != 0) {
353 			printk("sem_base_received timed out\n");
354 			break;
355 		}
356 
357 		/* Create broadcast sink */
358 		printk("Creating broadcast sink\n");
359 		err = bt_bap_broadcast_sink_create(bcast_pa_sync, broadcast_id, &broadcast_sink);
360 		if (err != 0) {
361 			printk("Sink not created!\n");
362 			break;
363 		}
364 
365 		printk("Waiting for syncable\n");
366 		err = k_sem_take(&sem_syncable, SEM_TIMEOUT);
367 		if (err != 0) {
368 			printk("sem_syncable timed out\n");
369 			break;
370 		}
371 
372 		/* Sync to broadcast source */
373 		printk("Syncing broadcast sink\n");
374 		err = bt_bap_broadcast_sink_sync(broadcast_sink, bis_index_bitfield,
375 						 streams_p, NULL);
376 		if (err != 0) {
377 			printk("Unable to sync to broadcast source: %d\n", err);
378 			break;
379 		}
380 
381 		/* Wait for data */
382 		printk("Waiting for data\n");
383 		WAIT_FOR_FLAG(flag_audio_received);
384 
385 		printk("Sending signal to broadcaster to stop\n");
386 		backchannel_sync_send_all(); /* let the broadcast source know it can stop */
387 
388 		/* Wait for the stream to end */
389 		printk("Waiting for sync lost\n");
390 		k_sem_take(&sem_pa_sync_lost, SEM_TIMEOUT);
391 
392 		count++;
393 	}
394 
395 	if (count == PBP_STREAMS_TO_SEND) {
396 		/* Pass if we synced only with the high quality broadcast */
397 		PASS("Public Broadcast sink passed\n");
398 	} else {
399 		FAIL("Public Broadcast sink failed (%d/%d)\n", count, PBP_STREAMS_TO_SEND);
400 	}
401 }
402 
403 static const struct bst_test_instance test_public_broadcast_sink[] = {
404 	{
405 		.test_id = "public_broadcast_sink",
406 		.test_pre_init_f = test_init,
407 		.test_tick_f = test_tick,
408 		.test_main_f = test_main
409 	},
410 	BSTEST_END_MARKER
411 };
412 
test_public_broadcast_sink_install(struct bst_test_list * tests)413 struct bst_test_list *test_public_broadcast_sink_install(struct bst_test_list *tests)
414 {
415 	return bst_add_tests(tests, test_public_broadcast_sink);
416 }
417 
418 #else /* !CONFIG_BT_PBP */
419 
test_public_broadcast_sink_install(struct bst_test_list * tests)420 struct bst_test_list *test_public_broadcast_sink_install(struct bst_test_list *tests)
421 {
422 	return tests;
423 }
424 
425 #endif /* CONFIG_BT_PBP */
426