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