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