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
533 err = bt_le_scan_stop();
534 if (err != 0) {
535 LOG_ERR("Unable to stop scanning: %d", err);
536 } else {
537 atomic_clear_bit(flags, FLAG_SCANNING);
538 }
539 }
540
541 err = create_broadcast_sink();
542 if (err != 0) {
543 LOG_ERR("Failed to create broadcast sink: %d", err);
544 } else {
545 check_sync_broadcast();
546 }
547 }
548 }
549
bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)550 static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
551 const struct bt_le_per_adv_sync_term_info *info)
552 {
553 if (sync == broadcast_sink.pa_sync) {
554 int err;
555
556 LOG_INF("PA sync %p lost with reason %u", (void *)sync, info->reason);
557
558 /* Without PA we cannot sync to any new BIG - Clear data */
559 broadcast_sink.requested_bis_sync = 0;
560 broadcast_sink.pa_sync = NULL;
561 k_work_cancel_delayable(&pa_timer);
562 atomic_clear_bit(flags, FLAG_BROADCAST_SYNCABLE);
563 atomic_clear_bit(flags, FLAG_PA_SYNCED);
564 atomic_clear_bit(flags, FLAG_PA_SYNCING);
565 atomic_clear_bit(flags, FLAG_BASE_RECEIVED);
566 atomic_clear_bit(flags, FLAG_BROADCAST_CODE_REQUIRED);
567 atomic_clear_bit(flags, FLAG_BROADCAST_CODE_RECEIVED);
568 atomic_clear_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED);
569
570 err = bt_bap_scan_delegator_set_pa_state(broadcast_sink.req_recv_state->src_id,
571 BT_BAP_PA_STATE_NOT_SYNCED);
572 if (err != 0) {
573 LOG_ERR("Failed to set PA state to BT_BAP_PA_STATE_NOT_SYNCED: %d", err);
574 }
575
576 if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {
577 (void)check_start_scan();
578 }
579 }
580 }
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)581 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
582 {
583 const struct bt_le_scan_recv_info *info = user_data;
584 struct bt_le_per_adv_sync_param param = {0};
585 char le_addr[BT_ADDR_LE_STR_LEN];
586 struct bt_uuid_16 adv_uuid;
587 uint32_t broadcast_id;
588 int err;
589
590 if (data->type != BT_DATA_SVC_DATA16) {
591 return true;
592 }
593
594 if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
595 return true;
596 }
597
598 if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
599 return true;
600 }
601
602 if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
603 return true;
604 }
605
606 broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
607
608 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
609
610 LOG_INF("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X\n", broadcast_id,
611 le_addr, info->sid);
612
613 bt_addr_le_copy(¶m.addr, info->addr);
614 param.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE;
615 param.sid = info->sid;
616 param.skip = PA_SYNC_SKIP;
617 param.timeout = interval_to_sync_timeout(info->interval);
618
619 err = bt_le_per_adv_sync_create(¶m, &broadcast_sink.pa_sync);
620 if (err != 0) {
621 LOG_ERR("Failed to create PA sync: %d", err);
622 } else {
623 LOG_INF("Syncing without PAST from scan");
624
625 broadcast_sink.broadcast_id = broadcast_id;
626 atomic_set_bit(flags, FLAG_PA_SYNCING);
627 k_work_reschedule(&pa_timer, K_MSEC(param.timeout * 10));
628
629 /* Since we are scanning ourselves, we consider this as broadcast sync has been
630 * requested
631 */
632 broadcast_sink.requested_bis_sync = BT_BAP_BIS_SYNC_NO_PREF;
633 atomic_set_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED);
634 }
635
636 /* Stop parsing */
637 return false;
638 }
639
is_substring(const char * substr,const char * str)640 static bool is_substring(const char *substr, const char *str)
641 {
642 const size_t str_len = strlen(str);
643 const size_t sub_str_len = strlen(substr);
644
645 if (sub_str_len > str_len) {
646 return false;
647 }
648
649 for (size_t pos = 0; pos < str_len; pos++) {
650 if (pos + sub_str_len > str_len) {
651 return false;
652 }
653
654 if (strncasecmp(substr, &str[pos], sub_str_len) == 0) {
655 return true;
656 }
657 }
658
659 return false;
660 }
661
data_cb(struct bt_data * data,void * user_data)662 static bool data_cb(struct bt_data *data, void *user_data)
663 {
664 char *name = user_data;
665
666 switch (data->type) {
667 case BT_DATA_NAME_SHORTENED:
668 case BT_DATA_NAME_COMPLETE:
669 case BT_DATA_BROADCAST_NAME:
670 memcpy(name, data->data, MIN(data->data_len, NAME_LEN - 1));
671 return false;
672 default:
673 return true;
674 }
675 }
676
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)677 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad)
678 {
679 if (atomic_test_bit(flags, FLAG_PA_SYNCED) || atomic_test_bit(flags, FLAG_PA_SYNCING) ||
680 atomic_test_bit(flags, FLAG_BROADCAST_SYNCED) ||
681 atomic_test_bit(flags, FLAG_BROADCAST_SYNCING)) {
682 /* If we are already synced or syncing, we do not care about scan reports */
683 return;
684 }
685
686 /* Only consider advertisers with periodic advertising */
687 if (info->interval != 0U) {
688 /* call to bt_data_parse consumes netbufs so shallow clone for verbose output */
689
690 /* If broadcast_sink.req_recv_state is NULL then we have been requested by a
691 * broadcast assistant to sync to a specific broadcast source. In that case we do
692 * not apply our own broadcast name filter.
693 */
694 if (broadcast_sink.req_recv_state != NULL &&
695 strlen(CONFIG_SAMPLE_TARGET_BROADCAST_NAME) > 0U) {
696 struct net_buf_simple buf_copy;
697 char name[NAME_LEN] = {0};
698
699 net_buf_simple_clone(ad, &buf_copy);
700 bt_data_parse(&buf_copy, data_cb, name);
701 if (!(is_substring(CONFIG_SAMPLE_TARGET_BROADCAST_NAME, name))) {
702 return;
703 }
704 }
705 bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info);
706 }
707 }
708
init_cap_acceptor_broadcast(void)709 int init_cap_acceptor_broadcast(void)
710 {
711 static bool cbs_registered;
712 int err;
713
714 if (!cbs_registered) {
715 static struct bt_bap_scan_delegator_cb scan_delegator_cbs = {
716 .pa_sync_req = pa_sync_req_cb,
717 .pa_sync_term_req = pa_sync_term_req_cb,
718 .broadcast_code = broadcast_code_cb,
719 .bis_sync_req = bis_sync_req_cb,
720 };
721 static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = {
722 .base_recv = base_recv_cb,
723 .syncable = syncable_cb,
724 };
725 static struct bt_bap_stream_ops broadcast_stream_ops = {
726 .started = broadcast_stream_started_cb,
727 .stopped = broadcast_stream_stopped_cb,
728 .recv = broadcast_stream_recv_cb,
729 };
730 static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = {
731 .synced = bap_pa_sync_synced_cb,
732 .term = bap_pa_sync_terminated_cb,
733 };
734 static struct bt_le_scan_cb bap_scan_cb = {
735 .recv = broadcast_scan_recv,
736 };
737
738 err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
739 if (err != 0) {
740 LOG_ERR("Scan delegator register failed (err %d)", err);
741
742 return err;
743 }
744
745 err = bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
746 if (err != 0) {
747 LOG_ERR("Failed to register BAP broadcast sink callbacks: %d", err);
748
749 return -ENOEXEC;
750 }
751
752 bt_cap_stream_ops_register(&broadcast_sink.broadcast_stream, &broadcast_stream_ops);
753 bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
754
755 if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {
756 bt_le_scan_cb_register(&bap_scan_cb);
757 }
758
759 cbs_registered = true;
760 }
761
762 if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {
763 err = check_start_scan();
764 if (err != 0) {
765 LOG_ERR("Unable to start scan for CAP initiators: %d", err);
766
767 return err;
768 }
769 }
770
771 return 0;
772 }
773