1 /** @file
2 * @brief Bluetooth Common Audio Profile (CAP) Acceptor broadcast.
3 *
4 * Copyright (c) 2024 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <errno.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 #include <string.h>
13 #include <strings.h>
14
15 #include <zephyr/autoconf.h>
16 #include <zephyr/bluetooth/addr.h>
17 #include <zephyr/bluetooth/audio/audio.h>
18 #include <zephyr/bluetooth/audio/bap.h>
19 #include <zephyr/bluetooth/audio/cap.h>
20 #include <zephyr/bluetooth/bluetooth.h>
21 #include <zephyr/bluetooth/conn.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/logging/log.h>
27 #include <zephyr/logging/log_core.h>
28 #include <zephyr/net_buf.h>
29 #include <zephyr/sys/atomic.h>
30 #include <zephyr/sys/byteorder.h>
31 #include <zephyr/sys/util.h>
32 #include <zephyr/sys/util_macro.h>
33 #include <zephyr/toolchain.h>
34
35 #include "cap_acceptor.h"
36
37 LOG_MODULE_REGISTER(cap_acceptor_broadcast, LOG_LEVEL_INF);
38
39 #define NAME_LEN sizeof(CONFIG_SAMPLE_TARGET_BROADCAST_NAME) + 1
40 #define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */
41 #define PA_SYNC_SKIP 5
42
43 enum broadcast_flag {
44 FLAG_BROADCAST_SYNC_REQUESTED,
45 FLAG_BROADCAST_CODE_REQUIRED,
46 FLAG_BROADCAST_CODE_RECEIVED,
47 FLAG_BROADCAST_SYNCABLE,
48 FLAG_BROADCAST_SYNCING,
49 FLAG_BROADCAST_SYNCED,
50 FLAG_BASE_RECEIVED,
51 FLAG_PA_SYNCING,
52 FLAG_PA_SYNCED,
53 FLAG_SCANNING,
54 FLAG_NUM,
55 };
56 ATOMIC_DEFINE(flags, FLAG_NUM);
57
58 static struct broadcast_sink {
59 const struct bt_bap_scan_delegator_recv_state *req_recv_state;
60 uint8_t sink_broadcast_code[BT_ISO_BROADCAST_CODE_SIZE];
61 struct bt_bap_broadcast_sink *bap_broadcast_sink;
62 struct bt_cap_stream broadcast_stream;
63 struct bt_le_per_adv_sync *pa_sync;
64 uint8_t received_base[UINT8_MAX];
65 uint32_t requested_bis_sync;
66 uint32_t broadcast_id;
67 } broadcast_sink;
68
69 uint64_t total_broadcast_rx_iso_packet_count; /* This value is exposed to test code */
70
71 /** Starts scanning if it passes a series of check to determine if we are in the right state */
check_start_scan(void)72 static int check_start_scan(void)
73 {
74 int err;
75
76 if (atomic_test_bit(flags, FLAG_SCANNING)) {
77 return -EALREADY;
78 }
79
80 if (atomic_test_bit(flags, FLAG_PA_SYNCED)) {
81 return -EALREADY;
82 }
83
84 if (atomic_test_bit(flags, FLAG_BROADCAST_SYNCED)) {
85 return -EALREADY;
86 }
87
88 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
89 if (err != 0) {
90 LOG_ERR("Unable to start scan for CAP initiators: %d", err);
91
92 return err;
93 }
94
95 atomic_set_bit(flags, FLAG_SCANNING);
96
97 return 0;
98 }
99
broadcast_stream_started_cb(struct bt_bap_stream * bap_stream)100 static void broadcast_stream_started_cb(struct bt_bap_stream *bap_stream)
101 {
102 LOG_INF("Started bap_stream %p", bap_stream);
103 total_broadcast_rx_iso_packet_count = 0U;
104
105 atomic_clear_bit(flags, FLAG_BROADCAST_SYNCING);
106 atomic_set_bit(flags, FLAG_BROADCAST_SYNCED);
107 }
108
broadcast_stream_stopped_cb(struct bt_bap_stream * bap_stream,uint8_t reason)109 static void broadcast_stream_stopped_cb(struct bt_bap_stream *bap_stream, uint8_t reason)
110 {
111 LOG_INF("Stopped bap_stream %p with reason 0x%02X", bap_stream, reason);
112
113 atomic_clear_bit(flags, FLAG_BROADCAST_SYNCING);
114 atomic_clear_bit(flags, FLAG_BROADCAST_SYNCED);
115
116 if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {
117 (void)check_start_scan();
118 }
119 }
120
broadcast_stream_recv_cb(struct bt_bap_stream * bap_stream,const struct bt_iso_recv_info * info,struct net_buf * buf)121 static void broadcast_stream_recv_cb(struct bt_bap_stream *bap_stream,
122 const struct bt_iso_recv_info *info, struct net_buf *buf)
123 {
124 /* Triggered every time we receive an HCI data packet from the controller.
125 * A call to this does not indicate valid data
126 * (see the `info->flags` for which flags to check),
127 */
128
129 if ((total_broadcast_rx_iso_packet_count % 100U) == 0U) {
130 LOG_INF("Received %llu HCI ISO data packets", total_broadcast_rx_iso_packet_count);
131 }
132
133 total_broadcast_rx_iso_packet_count++;
134 }
135
create_broadcast_sink(void)136 static int create_broadcast_sink(void)
137 {
138 int err;
139
140 if (broadcast_sink.bap_broadcast_sink != NULL) {
141 return -EALREADY;
142 }
143
144 LOG_INF("Creating broadcast sink for broadcast ID 0x%06X", broadcast_sink.broadcast_id);
145
146 err = bt_bap_broadcast_sink_create(broadcast_sink.pa_sync, broadcast_sink.broadcast_id,
147 &broadcast_sink.bap_broadcast_sink);
148 if (err != 0) {
149 LOG_ERR("Failed to create broadcast sink: %d\n", err);
150
151 return err;
152 }
153
154 return 0;
155 }
156
157 /** Performs a series of checks to see if we are ready to sync the broadcast sink */
check_sync_broadcast(void)158 static void check_sync_broadcast(void)
159 {
160 struct bt_bap_stream *sync_stream = &broadcast_sink.broadcast_stream.bap_stream;
161 uint32_t sync_bitfield;
162 int err;
163
164 if (!atomic_test_bit(flags, FLAG_BASE_RECEIVED)) {
165 LOG_DBG("FLAG_BASE_RECEIVED");
166 return;
167 }
168
169 if (!atomic_test_bit(flags, FLAG_BROADCAST_SYNCABLE)) {
170 LOG_DBG("FLAG_BROADCAST_SYNCABLE");
171 return;
172 }
173
174 if (atomic_test_bit(flags, FLAG_BROADCAST_CODE_REQUIRED) &&
175 !atomic_test_bit(flags, FLAG_BROADCAST_CODE_RECEIVED)) {
176 LOG_DBG("FLAG_BROADCAST_CODE_REQUIRED");
177 return;
178 }
179
180 if (!atomic_test_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED)) {
181 LOG_DBG("FLAG_BROADCAST_SYNC_REQUESTED");
182 return;
183 }
184
185 if (!atomic_test_bit(flags, FLAG_PA_SYNCED)) {
186 LOG_DBG("FLAG_PA_SYNCED");
187 return;
188 }
189
190 if (atomic_test_bit(flags, FLAG_BROADCAST_SYNCED) ||
191 atomic_test_bit(flags, FLAG_BROADCAST_SYNCING)) {
192 LOG_DBG("FLAG_BROADCAST_SYNCED");
193 return;
194 }
195
196 if (broadcast_sink.requested_bis_sync == BT_BAP_BIS_SYNC_NO_PREF) {
197 uint32_t base_bis;
198
199 /* Get the first BIS index from the BASE */
200 err = bt_bap_base_get_bis_indexes(
201 (struct bt_bap_base *)broadcast_sink.received_base, &base_bis);
202 if (err != 0) {
203 LOG_ERR("Failed to get BIS indexes from BASE: %d", err);
204
205 return;
206 }
207
208 sync_bitfield = 0U;
209 for (uint8_t i = BT_ISO_BIS_INDEX_MIN; i < BT_ISO_BIS_INDEX_MAX; i++) {
210 if (base_bis & BT_ISO_BIS_INDEX_BIT(i)) {
211 sync_bitfield = BT_ISO_BIS_INDEX_BIT(i);
212
213 break;
214 }
215 }
216 } else {
217 sync_bitfield = broadcast_sink.requested_bis_sync;
218 }
219
220 LOG_INF("Syncing to broadcast with bitfield 0x%08X", sync_bitfield);
221
222 /* Sync the BIG */
223 err = bt_bap_broadcast_sink_sync(broadcast_sink.bap_broadcast_sink, sync_bitfield,
224 &sync_stream, broadcast_sink.sink_broadcast_code);
225 if (err != 0) {
226 LOG_ERR("Failed to sync the broadcast sink: %d", err);
227 } else {
228 atomic_set_bit(flags, FLAG_BROADCAST_SYNCING);
229 }
230 }
231
base_recv_cb(struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base,size_t base_size)232 static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
233 size_t base_size)
234 {
235 memcpy(broadcast_sink.received_base, base, base_size);
236
237 if (!atomic_test_and_set_bit(flags, FLAG_BASE_RECEIVED)) {
238 LOG_INF("BASE received");
239
240 check_sync_broadcast();
241 }
242 }
243
syncable_cb(struct bt_bap_broadcast_sink * sink,const struct bt_iso_biginfo * biginfo)244 static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo)
245 {
246 if (!biginfo->encryption) {
247 atomic_clear_bit(flags, FLAG_BROADCAST_CODE_REQUIRED);
248 } else {
249 atomic_set_bit(flags, FLAG_BROADCAST_CODE_REQUIRED);
250 }
251
252 if (!atomic_test_and_set_bit(flags, FLAG_BROADCAST_SYNCABLE)) {
253 LOG_INF("BIGInfo received");
254
255 check_sync_broadcast();
256 }
257 }
258
pa_timer_handler(struct k_work * work)259 static void pa_timer_handler(struct k_work *work)
260 {
261 atomic_clear_bit(flags, FLAG_PA_SYNCING);
262
263 if (broadcast_sink.pa_sync != NULL) {
264 int err;
265
266 err = bt_le_per_adv_sync_delete(broadcast_sink.pa_sync);
267 if (err != 0) {
268 LOG_ERR("Failed to delete PA sync: %d", err);
269 }
270 }
271
272 if (broadcast_sink.req_recv_state != NULL) {
273 enum bt_bap_pa_state pa_state;
274
275 if (broadcast_sink.req_recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
276 pa_state = BT_BAP_PA_STATE_NO_PAST;
277 } else {
278 pa_state = BT_BAP_PA_STATE_FAILED;
279 }
280
281 bt_bap_scan_delegator_set_pa_state(broadcast_sink.req_recv_state->src_id, pa_state);
282 }
283
284 LOG_INF("PA sync timeout");
285 }
286
287 static K_WORK_DELAYABLE_DEFINE(pa_timer, pa_timer_handler);
288
interval_to_sync_timeout(uint16_t pa_interval)289 static uint16_t interval_to_sync_timeout(uint16_t pa_interval)
290 {
291 uint16_t pa_timeout;
292
293 if (pa_interval == BT_BAP_PA_INTERVAL_UNKNOWN) {
294 /* Use maximum value to maximize chance of success */
295 pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
296 } else {
297 uint32_t interval_us;
298 uint32_t timeout;
299
300 /* Add retries and convert to unit in 10's of ms */
301 interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
302 timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
303 PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
304
305 /* Enforce restraints */
306 pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
307 }
308
309 return pa_timeout;
310 }
311
pa_sync_with_past(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state,uint16_t pa_interval)312 static int pa_sync_with_past(struct bt_conn *conn,
313 const struct bt_bap_scan_delegator_recv_state *recv_state,
314 uint16_t pa_interval)
315 {
316 struct bt_le_per_adv_sync_transfer_param param = {0};
317 int err;
318
319 param.skip = PA_SYNC_SKIP;
320 param.timeout = interval_to_sync_timeout(pa_interval);
321
322 err = bt_le_per_adv_sync_transfer_subscribe(conn, ¶m);
323 if (err != 0) {
324 LOG_ERR("Could not do PAST subscribe: %d", err);
325
326 return err;
327 }
328
329 err = bt_bap_scan_delegator_set_pa_state(recv_state->src_id, BT_BAP_PA_STATE_INFO_REQ);
330 if (err != 0) {
331 LOG_ERR("Failed to set PA state to BT_BAP_PA_STATE_INFO_REQ: %d", err);
332
333 return err;
334 }
335
336 k_work_reschedule(&pa_timer, K_MSEC(param.timeout * 10));
337
338 return 0;
339 }
340
pa_sync_without_past(const bt_addr_le_t * addr,uint8_t adv_sid,uint16_t pa_interval)341 static int pa_sync_without_past(const bt_addr_le_t *addr, uint8_t adv_sid, uint16_t pa_interval)
342 {
343 struct bt_le_per_adv_sync_param param = {0};
344 int err;
345
346 bt_addr_le_copy(¶m.addr, addr);
347 param.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE;
348 param.sid = adv_sid;
349 param.skip = PA_SYNC_SKIP;
350 param.timeout = interval_to_sync_timeout(pa_interval);
351
352 err = bt_le_per_adv_sync_create(¶m, &broadcast_sink.pa_sync);
353 if (err != 0) {
354 LOG_ERR("Failed to create PA sync: %d", err);
355
356 return err;
357 }
358
359 k_work_reschedule(&pa_timer, K_MSEC(param.timeout * 10));
360
361 return 0;
362 }
363
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)364 static int pa_sync_req_cb(struct bt_conn *conn,
365 const struct bt_bap_scan_delegator_recv_state *recv_state,
366 bool past_avail, uint16_t pa_interval)
367 {
368
369 LOG_INF("Received request to sync to PA (PAST %savailble): %u", past_avail ? "" : "not ",
370 recv_state->pa_sync_state);
371
372 broadcast_sink.req_recv_state = recv_state;
373
374 if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED ||
375 recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ ||
376 broadcast_sink.pa_sync != NULL) {
377 /* Already syncing */
378 LOG_WRN("Rejecting PA sync request because we are already syncing or synced");
379
380 return -EALREADY;
381 }
382
383 if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER) && past_avail) {
384 int err;
385
386 err = pa_sync_with_past(conn, recv_state, pa_interval);
387 if (err != 0) {
388 return err;
389 }
390
391 LOG_INF("Syncing with PAST");
392 } else {
393 int err;
394
395 err = pa_sync_without_past(&recv_state->addr, recv_state->adv_sid, pa_interval);
396 if (err != 0) {
397 return err;
398 }
399
400 LOG_INF("Syncing without PAST");
401 }
402
403 broadcast_sink.broadcast_id = recv_state->broadcast_id;
404 atomic_set_bit(flags, FLAG_PA_SYNCING);
405
406 return 0;
407 }
408
pa_sync_term_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state)409 static int pa_sync_term_req_cb(struct bt_conn *conn,
410 const struct bt_bap_scan_delegator_recv_state *recv_state)
411 {
412 int err;
413
414 broadcast_sink.req_recv_state = recv_state;
415
416 err = bt_le_per_adv_sync_delete(broadcast_sink.pa_sync);
417 if (err != 0) {
418 LOG_ERR("Failed to delete PA sync: %d", err);
419
420 return err;
421 }
422
423 k_work_cancel_delayable(&pa_timer);
424 broadcast_sink.pa_sync = NULL;
425
426 return 0;
427 }
428
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])429 static void broadcast_code_cb(struct bt_conn *conn,
430 const struct bt_bap_scan_delegator_recv_state *recv_state,
431 const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
432 {
433 LOG_INF("Broadcast code received for %p", recv_state);
434
435 broadcast_sink.req_recv_state = recv_state;
436
437 (void)memcpy(broadcast_sink.sink_broadcast_code, broadcast_code,
438 BT_ISO_BROADCAST_CODE_SIZE);
439
440 atomic_set_bit(flags, FLAG_BROADCAST_CODE_RECEIVED);
441 }
442
get_req_bis_sync(const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])443 static uint32_t get_req_bis_sync(const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
444 {
445 uint32_t bis_sync = 0U;
446
447 for (int i = 0; i < CONFIG_BT_BAP_BASS_MAX_SUBGROUPS; i++) {
448 bis_sync |= bis_sync_req[i];
449 }
450
451 return bis_sync;
452 }
453
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])454 static int bis_sync_req_cb(struct bt_conn *conn,
455 const struct bt_bap_scan_delegator_recv_state *recv_state,
456 const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
457 {
458 const uint32_t new_bis_sync_req = get_req_bis_sync(bis_sync_req);
459
460 LOG_INF("BIS sync request received for %p: 0x%08x", recv_state, bis_sync_req[0]);
461
462 if (new_bis_sync_req != BT_BAP_BIS_SYNC_NO_PREF && POPCOUNT(new_bis_sync_req) > 1U) {
463 LOG_WRN("Rejecting BIS sync request for 0x%08X as we do not support that",
464 new_bis_sync_req);
465
466 return -ENOMEM;
467 }
468
469 if (broadcast_sink.requested_bis_sync != new_bis_sync_req) {
470 return 0; /* no op */
471 }
472
473 if (atomic_test_bit(flags, FLAG_BROADCAST_SYNCED)) {
474 /* If the BIS sync request is received while we are already
475 * synced, it means that the requested BIS sync has changed.
476 */
477 int err;
478
479 /* The stream stopped callback will be called as part of this,
480 * and we do not need to wait for any events from the
481 * controller. Thus, when this returns, the broadcast sink is stopped
482 */
483 err = bt_bap_broadcast_sink_stop(broadcast_sink.bap_broadcast_sink);
484 if (err != 0) {
485 LOG_ERR("Failed to stop Broadcast Sink: %d", err);
486
487 return err;
488 }
489
490 err = bt_bap_broadcast_sink_delete(broadcast_sink.bap_broadcast_sink);
491 if (err != 0) {
492 LOG_ERR("Failed to delete Broadcast Sink: %d", err);
493
494 return err;
495 }
496 broadcast_sink.bap_broadcast_sink = NULL;
497
498 atomic_clear_bit(flags, FLAG_BROADCAST_SYNCED);
499 }
500
501 broadcast_sink.requested_bis_sync = new_bis_sync_req;
502 if (broadcast_sink.requested_bis_sync != 0U) {
503 atomic_set_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED);
504 check_sync_broadcast();
505 } else {
506 atomic_clear_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED);
507 }
508
509 return 0;
510 }
511
bap_pa_sync_synced_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)512 static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
513 struct bt_le_per_adv_sync_synced_info *info)
514 {
515 if (sync == broadcast_sink.pa_sync ||
516 (broadcast_sink.req_recv_state != NULL &&
517 bt_addr_le_eq(info->addr, &broadcast_sink.req_recv_state->addr) &&
518 info->sid == broadcast_sink.req_recv_state->adv_sid)) {
519 int err;
520
521 LOG_INF("PA sync %p synced for broadcast sink", (void *)sync);
522
523 if (broadcast_sink.pa_sync == NULL) {
524 broadcast_sink.pa_sync = sync;
525 }
526
527 k_work_cancel_delayable(&pa_timer);
528 atomic_set_bit(flags, FLAG_PA_SYNCED);
529 atomic_clear_bit(flags, FLAG_PA_SYNCING);
530
531 if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {
532 int err;
533
534 err = bt_le_scan_stop();
535 if (err != 0) {
536 LOG_ERR("Unable to stop scanning: %d", err);
537 } else {
538 atomic_clear_bit(flags, FLAG_SCANNING);
539 }
540 }
541
542 err = create_broadcast_sink();
543 if (err != 0) {
544 LOG_ERR("Failed to create broadcast sink: %d", err);
545 } else {
546 check_sync_broadcast();
547 }
548 }
549 }
550
bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)551 static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
552 const struct bt_le_per_adv_sync_term_info *info)
553 {
554 if (sync == broadcast_sink.pa_sync) {
555 int err;
556
557 LOG_INF("PA sync %p lost with reason %u", (void *)sync, info->reason);
558
559 /* Without PA we cannot sync to any new BIG - Clear data */
560 broadcast_sink.requested_bis_sync = 0;
561 broadcast_sink.pa_sync = NULL;
562 k_work_cancel_delayable(&pa_timer);
563 atomic_clear_bit(flags, FLAG_BROADCAST_SYNCABLE);
564 atomic_clear_bit(flags, FLAG_PA_SYNCED);
565 atomic_clear_bit(flags, FLAG_PA_SYNCING);
566 atomic_clear_bit(flags, FLAG_BASE_RECEIVED);
567 atomic_clear_bit(flags, FLAG_BROADCAST_CODE_REQUIRED);
568 atomic_clear_bit(flags, FLAG_BROADCAST_CODE_RECEIVED);
569 atomic_clear_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED);
570
571 err = bt_bap_scan_delegator_set_pa_state(broadcast_sink.req_recv_state->src_id,
572 BT_BAP_PA_STATE_NOT_SYNCED);
573 if (err != 0) {
574 LOG_ERR("Failed to set PA state to BT_BAP_PA_STATE_NOT_SYNCED: %d", err);
575 }
576
577 if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {
578 (void)check_start_scan();
579 }
580 }
581 }
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)582 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
583 {
584 const struct bt_le_scan_recv_info *info = user_data;
585 struct bt_le_per_adv_sync_param param = {0};
586 char le_addr[BT_ADDR_LE_STR_LEN];
587 struct bt_uuid_16 adv_uuid;
588 uint32_t broadcast_id;
589 int err;
590
591 if (data->type != BT_DATA_SVC_DATA16) {
592 return true;
593 }
594
595 if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
596 return true;
597 }
598
599 if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
600 return true;
601 }
602
603 if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
604 return true;
605 }
606
607 broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
608
609 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
610
611 LOG_INF("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X\n", broadcast_id,
612 le_addr, info->sid);
613
614 bt_addr_le_copy(¶m.addr, info->addr);
615 param.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE;
616 param.sid = info->sid;
617 param.skip = PA_SYNC_SKIP;
618 param.timeout = interval_to_sync_timeout(info->interval);
619
620 err = bt_le_per_adv_sync_create(¶m, &broadcast_sink.pa_sync);
621 if (err != 0) {
622 LOG_ERR("Failed to create PA sync: %d", err);
623 } else {
624 LOG_INF("Syncing without PAST from scan");
625
626 broadcast_sink.broadcast_id = broadcast_id;
627 atomic_set_bit(flags, FLAG_PA_SYNCING);
628 k_work_reschedule(&pa_timer, K_MSEC(param.timeout * 10));
629
630 /* Since we are scanning ourselves, we consider this as broadcast sync has been
631 * requested
632 */
633 broadcast_sink.requested_bis_sync = BT_BAP_BIS_SYNC_NO_PREF;
634 atomic_set_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED);
635 }
636
637 /* Stop parsing */
638 return false;
639 }
640
is_substring(const char * substr,const char * str)641 static bool is_substring(const char *substr, const char *str)
642 {
643 const size_t str_len = strlen(str);
644 const size_t sub_str_len = strlen(substr);
645
646 if (sub_str_len > str_len) {
647 return false;
648 }
649
650 for (size_t pos = 0; pos < str_len; pos++) {
651 if (pos + sub_str_len > str_len) {
652 return false;
653 }
654
655 if (strncasecmp(substr, &str[pos], sub_str_len) == 0) {
656 return true;
657 }
658 }
659
660 return false;
661 }
662
data_cb(struct bt_data * data,void * user_data)663 static bool data_cb(struct bt_data *data, void *user_data)
664 {
665 char *name = user_data;
666
667 switch (data->type) {
668 case BT_DATA_NAME_SHORTENED:
669 case BT_DATA_NAME_COMPLETE:
670 case BT_DATA_BROADCAST_NAME:
671 memcpy(name, data->data, MIN(data->data_len, NAME_LEN - 1));
672 return false;
673 default:
674 return true;
675 }
676 }
677
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)678 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad)
679 {
680 if (atomic_test_bit(flags, FLAG_PA_SYNCED) || atomic_test_bit(flags, FLAG_PA_SYNCING) ||
681 atomic_test_bit(flags, FLAG_BROADCAST_SYNCED) ||
682 atomic_test_bit(flags, FLAG_BROADCAST_SYNCING)) {
683 /* If we are already synced or syncing, we do not care about scan reports */
684 return;
685 }
686
687 /* Only consider advertisers with periodic advertising */
688 if (info->interval != 0U) {
689 /* call to bt_data_parse consumes netbufs so shallow clone for verbose output */
690
691 /* If broadcast_sink.req_recv_state is NULL then we have been requested by a
692 * broadcast assistant to sync to a specific broadcast source. In that case we do
693 * not apply our own broadcast name filter.
694 */
695 if (broadcast_sink.req_recv_state != NULL &&
696 strlen(CONFIG_SAMPLE_TARGET_BROADCAST_NAME) > 0U) {
697 struct net_buf_simple buf_copy;
698 char name[NAME_LEN] = {0};
699
700 net_buf_simple_clone(ad, &buf_copy);
701 bt_data_parse(&buf_copy, data_cb, name);
702 if (!(is_substring(CONFIG_SAMPLE_TARGET_BROADCAST_NAME, name))) {
703 return;
704 }
705 }
706 bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info);
707 }
708 }
709
init_cap_acceptor_broadcast(void)710 int init_cap_acceptor_broadcast(void)
711 {
712 static bool cbs_registered;
713 int err;
714
715 if (!cbs_registered) {
716 static struct bt_bap_scan_delegator_cb scan_delegator_cbs = {
717 .pa_sync_req = pa_sync_req_cb,
718 .pa_sync_term_req = pa_sync_term_req_cb,
719 .broadcast_code = broadcast_code_cb,
720 .bis_sync_req = bis_sync_req_cb,
721 };
722 static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = {
723 .base_recv = base_recv_cb,
724 .syncable = syncable_cb,
725 };
726 static struct bt_bap_stream_ops broadcast_stream_ops = {
727 .started = broadcast_stream_started_cb,
728 .stopped = broadcast_stream_stopped_cb,
729 .recv = broadcast_stream_recv_cb,
730 };
731 static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = {
732 .synced = bap_pa_sync_synced_cb,
733 .term = bap_pa_sync_terminated_cb,
734 };
735 static struct bt_le_scan_cb bap_scan_cb = {
736 .recv = broadcast_scan_recv,
737 };
738
739 err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
740 if (err != 0) {
741 LOG_ERR("Scan delegator register failed (err %d)", err);
742
743 return err;
744 }
745
746 err = bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
747 if (err != 0) {
748 LOG_ERR("Failed to register BAP broadcast sink callbacks: %d", err);
749
750 return -ENOEXEC;
751 }
752
753 bt_cap_stream_ops_register(&broadcast_sink.broadcast_stream, &broadcast_stream_ops);
754 bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
755
756 if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {
757 bt_le_scan_cb_register(&bap_scan_cb);
758 }
759
760 cbs_registered = true;
761 }
762
763 if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {
764 err = check_start_scan();
765 if (err != 0) {
766 LOG_ERR("Unable to start scan for CAP initiators: %d", err);
767
768 return err;
769 }
770 }
771
772 return 0;
773 }
774