1 /*
2  * Copyright (c) 2022-2024 Nordic Semiconductor ASA
3  * Copyright 2023 NXP
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <zephyr/bluetooth/addr.h>
12 #include <zephyr/bluetooth/audio/audio.h>
13 #include <zephyr/bluetooth/audio/bap.h>
14 #include <zephyr/bluetooth/audio/lc3.h>
15 #include <zephyr/bluetooth/audio/pacs.h>
16 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
17 #include <zephyr/bluetooth/audio/tmap.h>
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/bluetooth/gap.h>
20 #include <zephyr/bluetooth/iso.h>
21 #include <zephyr/bluetooth/uuid.h>
22 #include <zephyr/kernel.h>
23 #include <zephyr/net_buf.h>
24 #include <zephyr/sys/byteorder.h>
25 #include <zephyr/sys/printk.h>
26 #include <zephyr/sys/util.h>
27 #include <zephyr/sys/util_macro.h>
28 
29 #define SEM_TIMEOUT K_SECONDS(10)
30 #define PA_SYNC_SKIP         5
31 #define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */
32 
33 static bool tmap_bms_found;
34 
35 static K_SEM_DEFINE(sem_pa_synced, 0U, 1U);
36 static K_SEM_DEFINE(sem_base_received, 0U, 1U);
37 static K_SEM_DEFINE(sem_syncable, 0U, 1U);
38 static K_SEM_DEFINE(sem_pa_sync_lost, 0U, 1U);
39 
40 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info,
41 				struct net_buf_simple *ad);
42 static void broadcast_scan_timeout(void);
43 
44 static void broadcast_pa_synced(struct bt_le_per_adv_sync *sync,
45 				struct bt_le_per_adv_sync_synced_info *info);
46 static void broadcast_pa_recv(struct bt_le_per_adv_sync *sync,
47 			      const struct bt_le_per_adv_sync_recv_info *info,
48 			      struct net_buf_simple *buf);
49 static void broadcast_pa_terminated(struct bt_le_per_adv_sync *sync,
50 				    const struct bt_le_per_adv_sync_term_info *info);
51 
52 static struct bt_le_scan_cb broadcast_scan_cb = {
53 	.recv = broadcast_scan_recv,
54 	.timeout = broadcast_scan_timeout
55 };
56 
57 static struct bt_le_per_adv_sync_cb broadcast_sync_cb = {
58 	.synced = broadcast_pa_synced,
59 	.recv = broadcast_pa_recv,
60 	.term = broadcast_pa_terminated,
61 };
62 
63 static struct bt_bap_broadcast_sink *broadcast_sink;
64 static uint32_t bcast_id;
65 static struct bt_le_per_adv_sync *bcast_pa_sync;
66 
67 static struct bt_bap_stream streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
68 struct bt_bap_stream *streams_p[ARRAY_SIZE(streams)];
69 
70 static const struct bt_audio_codec_cap codec = BT_AUDIO_CODEC_CAP_LC3(
71 	BT_AUDIO_CODEC_CAP_FREQ_48KHZ, BT_AUDIO_CODEC_CAP_DURATION_10,
72 	BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1), 40u, 60u, 1u, (BT_AUDIO_CONTEXT_TYPE_MEDIA));
73 
74 /* Create a mask for the maximum BIS we can sync to using the number of streams
75  * we have. We add an additional 1 since the bis indexes start from 1 and not
76  * 0.
77  */
78 static const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(streams) + 1U);
79 static uint32_t bis_index_bitfield;
80 
81 
stream_started_cb(struct bt_bap_stream * stream)82 static void stream_started_cb(struct bt_bap_stream *stream)
83 {
84 	printk("Stream %p started\n", stream);
85 }
86 
stream_stopped_cb(struct bt_bap_stream * stream,uint8_t reason)87 static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
88 {
89 	printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
90 }
91 
stream_recv_cb(struct bt_bap_stream * stream,const struct bt_iso_recv_info * info,struct net_buf * buf)92 static void stream_recv_cb(struct bt_bap_stream *stream,
93 			   const struct bt_iso_recv_info *info,
94 			   struct net_buf *buf)
95 {
96 	static uint32_t recv_cnt;
97 
98 	recv_cnt++;
99 	if ((recv_cnt % 20U) == 0U) {
100 		printk("Received %u total ISO packets\n", recv_cnt);
101 	}
102 }
103 
104 static struct bt_bap_stream_ops stream_ops = {
105 	.started = stream_started_cb,
106 	.stopped = stream_stopped_cb,
107 	.recv = stream_recv_cb
108 };
109 
110 static struct bt_pacs_cap cap = {
111 	.codec_cap = &codec,
112 };
113 
interval_to_sync_timeout(uint16_t interval)114 static uint16_t interval_to_sync_timeout(uint16_t interval)
115 {
116 	uint32_t interval_us;
117 	uint32_t timeout;
118 
119 	/* Add retries and convert to unit in 10's of ms */
120 	interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(interval);
121 	timeout =
122 		BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
123 
124 	/* Enforce restraints */
125 	timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
126 
127 	return (uint16_t)timeout;
128 }
129 
sync_broadcast_pa(const struct bt_le_scan_recv_info * info,uint32_t broadcast_id)130 static void sync_broadcast_pa(const struct bt_le_scan_recv_info *info,
131 			      uint32_t broadcast_id)
132 {
133 	struct bt_le_per_adv_sync_param param;
134 	int err;
135 
136 	/* Unregister the callbacks to prevent broadcast_scan_recv to be called again */
137 	bt_le_scan_cb_unregister(&broadcast_scan_cb);
138 	err = bt_le_scan_stop();
139 	if (err != 0) {
140 		printk("Could not stop scan: %d", err);
141 	}
142 
143 	bt_addr_le_copy(&param.addr, info->addr);
144 	param.options = 0;
145 	param.sid = info->sid;
146 	param.skip = PA_SYNC_SKIP;
147 	param.timeout = interval_to_sync_timeout(info->interval);
148 	err = bt_le_per_adv_sync_create(&param, &bcast_pa_sync);
149 	if (err != 0) {
150 		printk("Could not sync to PA: %d", err);
151 	} else {
152 		bcast_id = broadcast_id;
153 	}
154 }
155 
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)156 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
157 {
158 	uint32_t *broadcast_id = user_data;
159 	struct bt_uuid_16 adv_uuid;
160 
161 	if (data->type != BT_DATA_SVC_DATA16) {
162 		return true;
163 	}
164 
165 	if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
166 		return true;
167 	}
168 
169 	if (!bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
170 		*broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
171 		return true;
172 	}
173 
174 	if (!bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_TMAS)) {
175 		struct net_buf_simple tmas_svc_data;
176 		uint16_t uuid_val;
177 		uint16_t peer_tmap_role = 0;
178 
179 		net_buf_simple_init_with_data(&tmas_svc_data,
180 						(void *)data->data,
181 						data->data_len);
182 		uuid_val = net_buf_simple_pull_le16(&tmas_svc_data);
183 		if (tmas_svc_data.len < sizeof(peer_tmap_role)) {
184 			return false;
185 		}
186 
187 		peer_tmap_role = net_buf_simple_pull_le16(&tmas_svc_data);
188 		if ((peer_tmap_role & BT_TMAP_ROLE_BMS)) {
189 			printk("Found TMAP BMS\n");
190 			tmap_bms_found = true;
191 		}
192 
193 		return true;
194 	}
195 
196 	return true;
197 }
198 
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)199 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info,
200 				struct net_buf_simple *ad)
201 {
202 	uint32_t broadcast_id;
203 
204 	tmap_bms_found = false;
205 
206 	/* We are only interested in non-connectable periodic advertisers */
207 	if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) ||
208 	     info->interval == 0) {
209 		return;
210 	}
211 
212 	broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
213 	bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)&broadcast_id);
214 
215 	if ((broadcast_id != BT_BAP_INVALID_BROADCAST_ID) && tmap_bms_found) {
216 		sync_broadcast_pa(info, broadcast_id);
217 	}
218 }
219 
broadcast_scan_timeout(void)220 static void broadcast_scan_timeout(void)
221 {
222 	printk("Broadcast scan timed out\n");
223 }
224 
pa_decode_base(struct bt_data * data,void * user_data)225 static bool pa_decode_base(struct bt_data *data, void *user_data)
226 {
227 	const struct bt_bap_base *base = bt_bap_base_get_base_from_ad(data);
228 	uint32_t base_bis_index_bitfield = 0U;
229 	int err;
230 
231 	/* Base is NULL if the data does not contain a valid BASE */
232 	if (base == NULL) {
233 		return true;
234 	}
235 
236 	err = bt_bap_base_get_bis_indexes(base, &base_bis_index_bitfield);
237 	if (err != 0) {
238 		return false;
239 	}
240 
241 	bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;
242 	k_sem_give(&sem_base_received);
243 
244 	return false;
245 }
246 
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)247 static void broadcast_pa_recv(struct bt_le_per_adv_sync *sync,
248 			      const struct bt_le_per_adv_sync_recv_info *info,
249 			      struct net_buf_simple *buf)
250 {
251 	bt_data_parse(buf, pa_decode_base, NULL);
252 }
253 
syncable_cb(struct bt_bap_broadcast_sink * sink,const struct bt_iso_biginfo * biginfo)254 static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo)
255 {
256 	k_sem_give(&sem_syncable);
257 }
258 
base_recv_cb(struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base,size_t base_size)259 static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
260 			 size_t base_size)
261 {
262 	k_sem_give(&sem_base_received);
263 }
264 
265 static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = {
266 	.syncable = syncable_cb,
267 	.base_recv = base_recv_cb,
268 };
269 
broadcast_pa_synced(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)270 static void broadcast_pa_synced(struct bt_le_per_adv_sync *sync,
271 				struct bt_le_per_adv_sync_synced_info *info)
272 {
273 	if (sync == bcast_pa_sync) {
274 		printk("PA sync %p synced for broadcast sink with broadcast ID 0x%06X\n", sync,
275 		       bcast_id);
276 
277 		k_sem_give(&sem_pa_synced);
278 	}
279 }
280 
broadcast_pa_terminated(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)281 static void broadcast_pa_terminated(struct bt_le_per_adv_sync *sync,
282 				    const struct bt_le_per_adv_sync_term_info *info)
283 {
284 	if (sync == bcast_pa_sync) {
285 		printk("PA sync %p lost with reason %u\n", sync, info->reason);
286 		bcast_pa_sync = NULL;
287 
288 		k_sem_give(&sem_pa_sync_lost);
289 	}
290 }
291 
reset(void)292 static int reset(void)
293 {
294 	if (broadcast_sink != NULL) {
295 		int err = bt_bap_broadcast_sink_delete(broadcast_sink);
296 
297 		if (err) {
298 			printk("Deleting broadcast sink failed (err %d)\n", err);
299 
300 			return err;
301 		}
302 
303 		broadcast_sink = NULL;
304 	}
305 
306 	k_sem_reset(&sem_pa_synced);
307 	k_sem_reset(&sem_base_received);
308 	k_sem_reset(&sem_syncable);
309 	k_sem_reset(&sem_pa_sync_lost);
310 
311 	return 0;
312 }
313 
bap_broadcast_sink_init(void)314 int bap_broadcast_sink_init(void)
315 {
316 	int err;
317 
318 	bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
319 	bt_le_per_adv_sync_cb_register(&broadcast_sync_cb);
320 
321 	err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap);
322 	if (err) {
323 		printk("Capability register failed (err %d)\n", err);
324 		return err;
325 	}
326 
327 	for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) {
328 		streams[i].ops = &stream_ops;
329 	}
330 
331 	for (size_t i = 0U; i < ARRAY_SIZE(streams_p); i++) {
332 		streams_p[i] = &streams[i];
333 	}
334 
335 	return 0;
336 }
337 
bap_broadcast_sink_run(void)338 int bap_broadcast_sink_run(void)
339 {
340 	while (true) {
341 		int err = reset();
342 
343 		if (err != 0) {
344 			printk("Resetting failed: %d - Aborting\n", err);
345 			return err;
346 		}
347 
348 		bt_le_scan_cb_register(&broadcast_scan_cb);
349 		/* Start scanning */
350 		err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
351 		if (err) {
352 			printk("Scan start failed (err %d)\n", err);
353 			return err;
354 		}
355 
356 		/* Wait for PA sync */
357 		err = k_sem_take(&sem_pa_synced, SEM_TIMEOUT);
358 		if (err != 0) {
359 			printk("sem_pa_synced timed out\n");
360 			return err;
361 		}
362 		printk("Broadcast source PA synced, waiting for BASE\n");
363 
364 		/* Wait for BASE decode */
365 		err = k_sem_take(&sem_base_received, SEM_TIMEOUT);
366 		if (err != 0) {
367 			printk("sem_base_received timed out\n");
368 			return err;
369 		}
370 
371 		/* Create broadcast sink */
372 		printk("BASE received, creating broadcast sink\n");
373 		err = bt_bap_broadcast_sink_create(bcast_pa_sync, bcast_id, &broadcast_sink);
374 		if (err != 0) {
375 			printk("bt_bap_broadcast_sink_create failed: %d\n", err);
376 			return err;
377 		}
378 
379 		k_sem_take(&sem_syncable, SEM_TIMEOUT);
380 		if (err != 0) {
381 			printk("sem_syncable timed out\n");
382 			return err;
383 		}
384 
385 		/* Sync to broadcast source */
386 		printk("Syncing to broadcast\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 			return err;
392 		}
393 
394 		k_sem_take(&sem_pa_sync_lost, K_FOREVER);
395 	}
396 
397 	return 0;
398 }
399