1 /* Bluetooth Audio Broadcast Sink */
2
3 /*
4 * Copyright (c) 2021-2025 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <stddef.h>
12 #include <stdint.h>
13 #include <string.h>
14
15 #include <zephyr/autoconf.h>
16 #include <zephyr/bluetooth/addr.h>
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/bluetooth/conn.h>
19 #include <zephyr/bluetooth/gap.h>
20 #include <zephyr/bluetooth/gatt.h>
21 #include <zephyr/bluetooth/audio/audio.h>
22 #include <zephyr/bluetooth/audio/bap.h>
23 #include <zephyr/bluetooth/audio/pacs.h>
24 #include <zephyr/bluetooth/audio/bap.h>
25 #include <zephyr/bluetooth/hci_types.h>
26 #include <zephyr/bluetooth/iso.h>
27 #include <zephyr/bluetooth/uuid.h>
28 #include <zephyr/init.h>
29 #include <zephyr/kernel.h>
30 #include <zephyr/logging/log.h>
31 #include <zephyr/net_buf.h>
32 #include <zephyr/sys/__assert.h>
33 #include <zephyr/sys/atomic.h>
34 #include <zephyr/sys/byteorder.h>
35 #include <zephyr/sys/check.h>
36 #include <zephyr/sys/slist.h>
37 #include <zephyr/sys/util.h>
38 #include <zephyr/sys/util_macro.h>
39
40 #include "../host/conn_internal.h"
41 #include "../host/iso_internal.h"
42
43 #include "audio_internal.h"
44 #include "bap_iso.h"
45 #include "bap_endpoint.h"
46 #include "pacs_internal.h"
47
48 LOG_MODULE_REGISTER(bt_bap_broadcast_sink, CONFIG_BT_BAP_BROADCAST_SINK_LOG_LEVEL);
49
50 #include "common/bt_str.h"
51
52 #define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */
53 #define BROADCAST_SYNC_MIN_INDEX (BIT(1))
54
55 static struct bt_bap_ep broadcast_sink_eps[CONFIG_BT_BAP_BROADCAST_SNK_COUNT]
56 [CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
57 static struct bt_bap_broadcast_sink broadcast_sinks[CONFIG_BT_BAP_BROADCAST_SNK_COUNT];
58
59 struct codec_cap_lookup_id_data {
60 uint8_t id;
61 const struct bt_audio_codec_cap *codec_cap;
62 };
63
64 static sys_slist_t sink_cbs = SYS_SLIST_STATIC_INIT(&sink_cbs);
65
66 /* The mod_src_param is and shall only be used by the BT RX thread. It is statically defined due to
67 * the size of it, and that it's configurable in size, and can cause stack overflow issues otherwise
68 */
69 static struct bt_bap_scan_delegator_mod_src_param mod_src_param;
70
71 static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink);
72
find_recv_state_by_sink_cb(const struct bt_bap_scan_delegator_recv_state * recv_state,void * user_data)73 static bool find_recv_state_by_sink_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
74 void *user_data)
75 {
76 const struct bt_bap_broadcast_sink *sink = user_data;
77
78 if (atomic_test_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID) &&
79 sink->bass_src_id == recv_state->src_id) {
80 return true;
81 }
82
83 return false;
84 }
85
find_recv_state_by_pa_sync_cb(const struct bt_bap_scan_delegator_recv_state * recv_state,void * user_data)86 static bool find_recv_state_by_pa_sync_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
87 void *user_data)
88 {
89 struct bt_le_per_adv_sync *sync = user_data;
90 struct bt_le_per_adv_sync_info sync_info;
91 int err;
92
93 err = bt_le_per_adv_sync_get_info(sync, &sync_info);
94 if (err != 0) {
95 LOG_DBG("Failed to get sync info: %d", err);
96
97 return false;
98 }
99
100 if (bt_addr_le_eq(&recv_state->addr, &sync_info.addr) &&
101 recv_state->adv_sid == sync_info.sid) {
102 return true;
103 }
104
105 return false;
106 };
107
update_recv_state_big_synced(const struct bt_bap_broadcast_sink * sink)108 static void update_recv_state_big_synced(const struct bt_bap_broadcast_sink *sink)
109 {
110 const struct bt_bap_scan_delegator_recv_state *recv_state;
111 int err;
112
113 recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
114 if (recv_state == NULL) {
115 LOG_WRN("Failed to find receive state for sink %p", sink);
116
117 return;
118 }
119
120 (void)memset(&mod_src_param, 0, sizeof(mod_src_param));
121
122 mod_src_param.num_subgroups = sink->subgroup_count;
123 for (uint8_t i = 0U; i < sink->subgroup_count; i++) {
124 struct bt_bap_bass_subgroup *subgroup_param = &mod_src_param.subgroups[i];
125 const struct bt_bap_broadcast_sink_subgroup *sink_subgroup = &sink->subgroups[i];
126
127 /* Set the bis_sync value to the indexes available per subgroup */
128 subgroup_param->bis_sync = sink_subgroup->bis_indexes & sink->indexes_bitfield;
129 }
130
131 if (recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BCODE_REQ ||
132 recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
133 mod_src_param.encrypt_state = BT_BAP_BIG_ENC_STATE_DEC;
134 } else {
135 mod_src_param.encrypt_state = recv_state->encrypt_state;
136 }
137
138 /* Since the mod_src_param struct is 0-initialized the metadata won't
139 * be modified by this
140 */
141
142 /* Copy existing unchanged data */
143 mod_src_param.src_id = recv_state->src_id;
144 mod_src_param.broadcast_id = recv_state->broadcast_id;
145
146 err = bt_bap_scan_delegator_mod_src(&mod_src_param);
147 if (err != 0) {
148 LOG_WRN("Failed to modify Receive State for sink %p: %d", sink, err);
149 }
150 }
151
update_recv_state_big_cleared(const struct bt_bap_broadcast_sink * sink,uint8_t reason)152 static void update_recv_state_big_cleared(const struct bt_bap_broadcast_sink *sink,
153 uint8_t reason)
154 {
155 const struct bt_bap_scan_delegator_recv_state *recv_state;
156 bool sink_is_streaming = false;
157 int err;
158
159 recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
160 if (recv_state == NULL) {
161 /* This is likely due to the receive state being removed while we are BIG synced */
162 LOG_DBG("Could not find receive state for sink %p", sink);
163
164 return;
165 }
166
167 (void)memset(&mod_src_param, 0, sizeof(mod_src_param));
168
169 if ((recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BCODE_REQ ||
170 recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_DEC) &&
171 reason == BT_HCI_ERR_TERM_DUE_TO_MIC_FAIL) {
172 /* Sync failed due to bad broadcast code */
173 mod_src_param.encrypt_state = BT_BAP_BIG_ENC_STATE_BAD_CODE;
174 } else {
175 mod_src_param.encrypt_state = BT_BAP_BIG_ENC_STATE_NO_ENC;
176 }
177
178 /* Determine if the previous receive state reported that streaming was active
179 * If it was previously active, then we need to set the BIS_sync state to 0
180 * (not streaming), and if not then we consider this a BIG Sync failure and
181 * set BT_BAP_BIS_SYNC_FAILED
182 */
183 for (uint8_t i = 0U; i < recv_state->num_subgroups && !sink_is_streaming; i++) {
184 sink_is_streaming = recv_state->subgroups[i].bis_sync != 0 &&
185 recv_state->subgroups[i].bis_sync != BT_BAP_BIS_SYNC_FAILED;
186 }
187
188 if (!sink_is_streaming) {
189 /* BASS spec 3.1.1.5: Set Sync Failed when the server fails to sync to the BIG */
190 for (uint8_t i = 0U; i < recv_state->num_subgroups; i++) {
191 mod_src_param.subgroups[i].bis_sync = BT_BAP_BIS_SYNC_FAILED;
192 }
193 }
194
195 /* Since the metadata_len is 0 then the metadata won't be modified by the operation either*/
196
197 /* Copy existing unchanged data */
198 mod_src_param.num_subgroups = recv_state->num_subgroups;
199 mod_src_param.src_id = recv_state->src_id;
200 mod_src_param.broadcast_id = recv_state->broadcast_id;
201
202 err = bt_bap_scan_delegator_mod_src(&mod_src_param);
203 if (err != 0) {
204 LOG_WRN("Failed to modify Receive State for sink %p: %d",
205 sink, err);
206 }
207 }
208
broadcast_sink_clear_big(struct bt_bap_broadcast_sink * sink,uint8_t reason)209 static void broadcast_sink_clear_big(struct bt_bap_broadcast_sink *sink,
210 uint8_t reason)
211 {
212 sink->big = NULL;
213
214 update_recv_state_big_cleared(sink, reason);
215 }
216
broadcast_sink_lookup_iso_chan(const struct bt_iso_chan * chan)217 static struct bt_bap_broadcast_sink *broadcast_sink_lookup_iso_chan(
218 const struct bt_iso_chan *chan)
219 {
220 for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sinks); i++) {
221 for (uint8_t j = 0U; j < broadcast_sinks[i].stream_count; j++) {
222 if (broadcast_sinks[i].bis[j].chan == chan) {
223 return &broadcast_sinks[i];
224 }
225 }
226 }
227
228 return NULL;
229 }
230
broadcast_sink_set_ep_state(struct bt_bap_ep * ep,uint8_t state)231 static void broadcast_sink_set_ep_state(struct bt_bap_ep *ep, uint8_t state)
232 {
233 uint8_t old_state;
234
235 old_state = ep->status.state;
236
237 LOG_DBG("ep %p id 0x%02x %s -> %s", ep, ep->status.id, bt_bap_ep_state_str(old_state),
238 bt_bap_ep_state_str(state));
239
240 switch (old_state) {
241 case BT_BAP_EP_STATE_IDLE:
242 if (state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
243 LOG_DBG("Invalid broadcast sync endpoint state transition");
244 return;
245 }
246 break;
247 case BT_BAP_EP_STATE_QOS_CONFIGURED:
248 if (state != BT_BAP_EP_STATE_IDLE && state != BT_BAP_EP_STATE_STREAMING) {
249 LOG_DBG("Invalid broadcast sync endpoint state transition");
250 return;
251 }
252 break;
253 case BT_BAP_EP_STATE_STREAMING:
254 if (state != BT_BAP_EP_STATE_IDLE) {
255 LOG_DBG("Invalid broadcast sync endpoint state transition");
256 return;
257 }
258 break;
259 default:
260 LOG_ERR("Invalid broadcast sync endpoint state: %s",
261 bt_bap_ep_state_str(old_state));
262 return;
263 }
264
265 ep->status.state = state;
266
267 if (state == BT_BAP_EP_STATE_IDLE) {
268 struct bt_bap_stream *stream = ep->stream;
269
270 if (stream != NULL) {
271 bt_bap_iso_unbind_ep(ep->iso, ep);
272 stream->iso = NULL;
273 stream->ep = NULL;
274 stream->codec_cfg = NULL;
275 stream->group = NULL;
276 ep->stream = NULL;
277 ep->broadcast_sink = NULL;
278 }
279 }
280 }
281
broadcast_sink_iso_recv(struct bt_iso_chan * chan,const struct bt_iso_recv_info * info,struct net_buf * buf)282 static void broadcast_sink_iso_recv(struct bt_iso_chan *chan,
283 const struct bt_iso_recv_info *info,
284 struct net_buf *buf)
285 {
286 struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
287 const struct bt_bap_stream_ops *ops;
288 struct bt_bap_stream *stream;
289 struct bt_bap_ep *ep = iso->rx.ep;
290 size_t buf_len;
291
292 if (ep == NULL) {
293 LOG_ERR("iso %p not bound with ep", chan);
294 return;
295 }
296
297 stream = ep->stream;
298 if (stream == NULL) {
299 LOG_ERR("No stream for ep %p", ep);
300 return;
301 }
302
303 ops = stream->ops;
304
305 buf_len = net_buf_frags_len(buf);
306 if (IS_ENABLED(CONFIG_BT_BAP_DEBUG_STREAM_DATA)) {
307 LOG_DBG("stream %p ep %p len %zu", stream, stream->ep, buf_len);
308 }
309
310 if (buf_len > stream->qos->sdu) {
311 LOG_WRN("Received %u octets but stream %p was only configured for %u", buf_len,
312 stream, stream->qos->sdu);
313 }
314
315 if (ops != NULL && ops->recv != NULL) {
316 ops->recv(stream, info, buf);
317 } else {
318 LOG_WRN("No callback for recv set");
319 }
320 }
321
broadcast_sink_is_in_state(struct bt_bap_broadcast_sink * sink,enum bt_bap_ep_state state)322 static bool broadcast_sink_is_in_state(struct bt_bap_broadcast_sink *sink,
323 enum bt_bap_ep_state state)
324 {
325 struct bt_bap_stream *stream;
326
327 if (sink == NULL) {
328 LOG_DBG("sink is NULL");
329
330 return state == BT_BAP_EP_STATE_IDLE;
331 }
332
333 if (sys_slist_is_empty(&sink->streams)) {
334 LOG_DBG("Sink does not have any streams");
335
336 return state == BT_BAP_EP_STATE_IDLE;
337 }
338
339 SYS_SLIST_FOR_EACH_CONTAINER(&sink->streams, stream, _node) {
340 if (stream->ep != NULL && stream->ep->status.state != state) {
341 return false;
342 }
343 }
344
345 return true;
346 }
347
broadcast_sink_iso_connected(struct bt_iso_chan * chan)348 static void broadcast_sink_iso_connected(struct bt_iso_chan *chan)
349 {
350 struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
351 const struct bt_bap_stream_ops *ops;
352 struct bt_bap_broadcast_sink *sink;
353 struct bt_bap_stream *stream;
354 struct bt_bap_ep *ep = iso->rx.ep;
355
356 if (ep == NULL) {
357 LOG_ERR("iso %p not bound with ep", chan);
358 return;
359 }
360
361 stream = ep->stream;
362 if (stream == NULL) {
363 LOG_ERR("No stream for ep %p", ep);
364 return;
365 }
366
367 LOG_DBG("stream %p", stream);
368
369 ops = stream->ops;
370 if (ops != NULL && ops->connected != NULL) {
371 ops->connected(stream);
372 }
373
374 sink = broadcast_sink_lookup_iso_chan(chan);
375 if (sink == NULL) {
376 LOG_ERR("Could not lookup sink by iso %p", chan);
377 return;
378 }
379
380 broadcast_sink_set_ep_state(ep, BT_BAP_EP_STATE_STREAMING);
381
382 /* Setup the ISO data path */
383 bt_bap_setup_iso_data_path(stream);
384
385 if (ops != NULL && ops->started != NULL) {
386 ops->started(stream);
387 }
388
389 if (broadcast_sink_is_in_state(sink, BT_BAP_EP_STATE_STREAMING)) {
390 update_recv_state_big_synced(sink);
391 }
392 }
393
broadcast_sink_iso_disconnected(struct bt_iso_chan * chan,uint8_t reason)394 static void broadcast_sink_iso_disconnected(struct bt_iso_chan *chan,
395 uint8_t reason)
396 {
397 struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
398 const struct bt_bap_stream_ops *ops;
399 struct bt_bap_stream *stream;
400 struct bt_bap_ep *ep = iso->rx.ep;
401 struct bt_bap_broadcast_sink *sink;
402
403 if (ep == NULL) {
404 LOG_ERR("iso %p not bound with ep", chan);
405 return;
406 }
407
408 stream = ep->stream;
409 if (stream == NULL) {
410 LOG_ERR("No stream for ep %p", ep);
411 return;
412 }
413
414 LOG_DBG("stream %p ep %p reason 0x%02x", stream, ep, reason);
415
416 ops = stream->ops;
417 if (ops != NULL && ops->disconnected != NULL) {
418 ops->disconnected(stream, reason);
419 }
420
421 broadcast_sink_set_ep_state(ep, BT_BAP_EP_STATE_IDLE);
422
423 sink = broadcast_sink_lookup_iso_chan(chan);
424 if (sink == NULL) {
425 LOG_ERR("Could not lookup sink by iso %p", chan);
426 } else {
427 if (!sys_slist_find_and_remove(&sink->streams, &stream->_node)) {
428 LOG_DBG("Could not find and remove stream %p from sink %p", stream, sink);
429 }
430 }
431
432 if (ops != NULL && ops->stopped != NULL) {
433 ops->stopped(stream, reason);
434 }
435 }
436
437 static struct bt_iso_chan_ops broadcast_sink_iso_ops = {
438 .recv = broadcast_sink_iso_recv,
439 .connected = broadcast_sink_iso_connected,
440 .disconnected = broadcast_sink_iso_disconnected,
441 };
442
broadcast_sink_free_get(void)443 static struct bt_bap_broadcast_sink *broadcast_sink_free_get(void)
444 {
445 /* Find free entry */
446 for (int i = 0; i < ARRAY_SIZE(broadcast_sinks); i++) {
447 if (!atomic_test_bit(broadcast_sinks[i].flags,
448 BT_BAP_BROADCAST_SINK_FLAG_INITIALIZED)) {
449 broadcast_sinks[i].index = i;
450 broadcast_sinks[i].broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
451
452 return &broadcast_sinks[i];
453 }
454 }
455
456 return NULL;
457 }
458
broadcast_sink_get_by_pa(struct bt_le_per_adv_sync * sync)459 static struct bt_bap_broadcast_sink *broadcast_sink_get_by_pa(struct bt_le_per_adv_sync *sync)
460 {
461 for (int i = 0; i < ARRAY_SIZE(broadcast_sinks); i++) {
462 if (broadcast_sinks[i].pa_sync == sync) {
463 return &broadcast_sinks[i];
464 }
465 }
466
467 return NULL;
468 }
469
broadcast_sink_get_by_big(const struct bt_iso_big * big)470 static struct bt_bap_broadcast_sink *broadcast_sink_get_by_big(const struct bt_iso_big *big)
471 {
472 for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sinks); i++) {
473 if (broadcast_sinks[i].big == big) {
474 return &broadcast_sinks[i];
475 }
476 }
477
478 return NULL;
479 }
480
broadcast_sink_add_src(struct bt_bap_broadcast_sink * sink)481 static void broadcast_sink_add_src(struct bt_bap_broadcast_sink *sink)
482 {
483 struct bt_bap_scan_delegator_add_src_param add_src_param;
484 struct bt_le_per_adv_sync_info sync_info;
485 int err;
486
487 err = bt_le_per_adv_sync_get_info(sink->pa_sync, &sync_info);
488 __ASSERT_NO_MSG(err == 0);
489
490 bt_addr_le_copy(&add_src_param.addr, &sync_info.addr);
491 add_src_param.sid = sync_info.sid;
492 add_src_param.broadcast_id = sink->broadcast_id;
493 /* Will be updated when we receive the BASE */
494 add_src_param.encrypt_state = BT_BAP_BIG_ENC_STATE_NO_ENC;
495 add_src_param.num_subgroups = 0U;
496
497 err = bt_bap_scan_delegator_add_src(&add_src_param);
498 if (err < 0) {
499 LOG_WRN("Failed to add sync as Receive State for sink %p: %d",
500 sink, err);
501 } else {
502 sink->bass_src_id = (uint8_t)err;
503 atomic_set_bit(sink->flags,
504 BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID);
505 }
506 }
507
base_subgroup_meta_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)508 static bool base_subgroup_meta_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
509 {
510 struct bt_bap_bass_subgroup *subgroup_param;
511 uint8_t *meta;
512 int ret;
513
514 ret = bt_bap_base_get_subgroup_codec_meta(subgroup, &meta);
515 if (ret < 0) {
516 return false;
517 }
518
519 subgroup_param = &mod_src_param.subgroups[mod_src_param.num_subgroups++];
520 subgroup_param->metadata_len = (uint8_t)ret;
521 memcpy(subgroup_param->metadata, meta, subgroup_param->metadata_len);
522
523 return true;
524 }
525
update_recv_state_base_copy_meta(const struct bt_bap_base * base)526 static int update_recv_state_base_copy_meta(const struct bt_bap_base *base)
527 {
528 int err;
529
530 err = bt_bap_base_foreach_subgroup(base, base_subgroup_meta_cb, NULL);
531 if (err != 0) {
532 LOG_DBG("Failed to parse subgroups: %d", err);
533 return err;
534 }
535
536 return 0;
537 }
538
update_recv_state_base(const struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base)539 static void update_recv_state_base(const struct bt_bap_broadcast_sink *sink,
540 const struct bt_bap_base *base)
541 {
542 const struct bt_bap_scan_delegator_recv_state *recv_state;
543 int err;
544
545 recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
546 if (recv_state == NULL) {
547 LOG_WRN("Failed to find receive state for sink %p", sink);
548
549 return;
550 }
551
552 (void)memset(&mod_src_param, 0, sizeof(mod_src_param));
553
554 err = update_recv_state_base_copy_meta(base);
555 if (err != 0) {
556 LOG_WRN("Failed to modify Receive State for sink %p: %d", sink, err);
557 return;
558 }
559
560 /* Copy existing unchanged data */
561 mod_src_param.src_id = recv_state->src_id;
562 mod_src_param.encrypt_state = recv_state->encrypt_state;
563 mod_src_param.broadcast_id = recv_state->broadcast_id;
564 mod_src_param.num_subgroups = sink->subgroup_count;
565 for (uint8_t i = 0U; i < sink->subgroup_count; i++) {
566 struct bt_bap_bass_subgroup *subgroup_param = &mod_src_param.subgroups[i];
567
568 /* Leave the bis_sync unchanged */
569 subgroup_param->bis_sync = recv_state->subgroups[i].bis_sync;
570 }
571
572 err = bt_bap_scan_delegator_mod_src(&mod_src_param);
573 if (err != 0) {
574 LOG_WRN("Failed to modify Receive State for sink %p: %d", sink, err);
575 }
576 }
577
base_subgroup_bis_count_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)578 static bool base_subgroup_bis_count_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
579 {
580 uint8_t *bis_cnt = user_data;
581 int ret;
582
583 ret = bt_bap_base_get_subgroup_bis_count(subgroup);
584 if (ret < 0) {
585 return false;
586 }
587
588 *bis_cnt += (uint8_t)ret;
589
590 return true;
591 }
592
base_get_bis_count(const struct bt_bap_base * base)593 static int base_get_bis_count(const struct bt_bap_base *base)
594 {
595 uint8_t bis_cnt = 0U;
596 int err;
597
598 err = bt_bap_base_foreach_subgroup(base, base_subgroup_bis_count_cb, &bis_cnt);
599 if (err != 0) {
600 LOG_DBG("Failed to parse subgroups: %d", err);
601 return err;
602 }
603
604 return bis_cnt;
605 }
606
base_decode_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis * bis,void * user_data)607 static bool base_decode_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis *bis, void *user_data)
608 {
609 uint32_t *base_bis_index_bitfield = user_data;
610
611 *base_bis_index_bitfield |= BT_ISO_BIS_INDEX_BIT(bis->index);
612
613 return true;
614 }
615
base_decode_subgroup_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)616 static bool base_decode_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
617 {
618 struct bt_bap_broadcast_sink *sink = (struct bt_bap_broadcast_sink *)user_data;
619 const struct bt_audio_codec_cap *codec_cap;
620 struct bt_audio_codec_cfg codec_cfg;
621 struct bt_pac_codec codec_id;
622 int ret;
623
624 if (sink->subgroup_count == ARRAY_SIZE(sink->subgroups)) {
625 /* We've parsed as many subgroups as we support */
626 LOG_DBG("Could only store %u subgroups", sink->subgroup_count);
627 return false;
628 }
629
630 uint32_t *subgroup_bis_indexes = &sink->subgroups[sink->subgroup_count].bis_indexes;
631
632 *subgroup_bis_indexes = 0;
633
634 ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &codec_cfg);
635 if (ret < 0) {
636 LOG_DBG("Could not store codec_cfg: %d", ret);
637 return false;
638 }
639
640 /* Lookup and assign path_id based on capabilities */
641 codec_id.id = codec_cfg.id;
642 codec_id.cid = codec_cfg.cid;
643 codec_id.vid = codec_cfg.vid;
644
645 codec_cap = bt_pacs_get_codec_cap(BT_AUDIO_DIR_SINK, &codec_id);
646 if (codec_cap == NULL) {
647 LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x is not supported by our "
648 "capabilities",
649 codec_id.id, codec_id.cid, codec_id.vid);
650 } else {
651 ret = bt_bap_base_subgroup_foreach_bis(subgroup, base_decode_subgroup_bis_cb,
652 subgroup_bis_indexes);
653
654 if (ret != 0) {
655 LOG_DBG("Could not parse BISes: %d", ret);
656 return false;
657 }
658
659 sink->valid_indexes_bitfield |= *subgroup_bis_indexes;
660 }
661
662 sink->subgroup_count++;
663
664 return true;
665 }
666
pa_decode_base(struct bt_data * data,void * user_data)667 static bool pa_decode_base(struct bt_data *data, void *user_data)
668 {
669 struct bt_bap_broadcast_sink *sink = (struct bt_bap_broadcast_sink *)user_data;
670 const struct bt_bap_base *base = bt_bap_base_get_base_from_ad(data);
671 struct bt_bap_broadcast_sink_cb *listener;
672 int base_size;
673
674 /* Base is NULL if the data does not contain a valid BASE */
675 if (base == NULL) {
676 return true;
677 }
678
679 /* We provide the BASE without the service data UUID */
680 base_size = bt_bap_base_get_size(base);
681 if (base_size != sink->base_size || memcmp(base, sink->base, base_size) != 0) {
682 /* New BASE, parse */
683
684 if (atomic_test_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_BIGINFO_RECEIVED)) {
685 int ret;
686
687 ret = base_get_bis_count(base);
688
689 if (ret < 0) {
690 LOG_DBG("Invalid BASE: %d", ret);
691 return false;
692 } else if (ret != sink->biginfo_num_bis) {
693 LOG_DBG("BASE contains different amount of BIS (%u) than reported "
694 "by BIGInfo (%u)",
695 ret, sink->biginfo_num_bis);
696 return false;
697 }
698 }
699
700 /* Store newest BASE info until we are BIG synced */
701 if (sink->big == NULL) {
702 sink->qos_cfg.pd = bt_bap_base_get_pres_delay(base);
703
704 sink->subgroup_count = 0;
705 sink->valid_indexes_bitfield = 0;
706 bt_bap_base_foreach_subgroup(base, base_decode_subgroup_cb, sink);
707
708 LOG_DBG("Updating BASE for sink %p with %d subgroups\n", sink,
709 sink->subgroup_count);
710
711 memcpy(sink->base, base, base_size);
712 sink->base_size = base_size;
713 }
714
715 if (atomic_test_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID)) {
716 update_recv_state_base(sink, base);
717 }
718 }
719
720 SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, _node) {
721 if (listener->base_recv != NULL) {
722 listener->base_recv(sink, base, (size_t)base_size);
723 }
724 }
725
726 return false;
727 }
728
pa_recv(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_recv_info * info,struct net_buf_simple * buf)729 static void pa_recv(struct bt_le_per_adv_sync *sync,
730 const struct bt_le_per_adv_sync_recv_info *info,
731 struct net_buf_simple *buf)
732 {
733 struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_pa(sync);
734
735 if (sink == NULL) {
736 /* Not a PA sync that we control */
737 return;
738 }
739
740 if (sys_slist_is_empty(&sink_cbs)) {
741 /* Terminate early if we do not have any broadcast sink listeners */
742 return;
743 }
744
745 bt_data_parse(buf, pa_decode_base, (void *)sink);
746 }
747
pa_term_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)748 static void pa_term_cb(struct bt_le_per_adv_sync *sync,
749 const struct bt_le_per_adv_sync_term_info *info)
750 {
751 struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_pa(sync);
752
753 if (sink != NULL) {
754 sink->pa_sync = NULL;
755 sink->base_size = 0U;
756 }
757 }
758
update_recv_state_encryption(const struct bt_bap_broadcast_sink * sink)759 static void update_recv_state_encryption(const struct bt_bap_broadcast_sink *sink)
760 {
761 const struct bt_bap_scan_delegator_recv_state *recv_state;
762 int err;
763
764 __ASSERT(sink->big == NULL, "Encryption state shall not be updated while synced");
765
766 recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
767 if (recv_state == NULL) {
768 LOG_WRN("Failed to find receive state for sink %p", sink);
769
770 return;
771 }
772
773 (void)memset(&mod_src_param, 0, sizeof(mod_src_param));
774
775 /* Only change the encrypt state, and leave the rest as is */
776 if (atomic_test_bit(sink->flags,
777 BT_BAP_BROADCAST_SINK_FLAG_BIG_ENCRYPTED)) {
778 mod_src_param.encrypt_state = BT_BAP_BIG_ENC_STATE_BCODE_REQ;
779 } else {
780 mod_src_param.encrypt_state = BT_BAP_BIG_ENC_STATE_NO_ENC;
781 }
782
783 if (mod_src_param.encrypt_state == recv_state->encrypt_state) {
784 /* No change, abort*/
785 return;
786 }
787
788 /* Copy existing data */
789 /* TODO: Maybe we need more refined functions to set only specific fields? */
790 mod_src_param.src_id = recv_state->src_id;
791 mod_src_param.broadcast_id = recv_state->broadcast_id;
792 mod_src_param.num_subgroups = recv_state->num_subgroups;
793 (void)memcpy(mod_src_param.subgroups,
794 recv_state->subgroups,
795 sizeof(recv_state->num_subgroups));
796
797 err = bt_bap_scan_delegator_mod_src(&mod_src_param);
798 if (err != 0) {
799 LOG_WRN("Failed to modify Receive State for sink %p: %d", sink, err);
800 }
801 }
802
biginfo_recv(struct bt_le_per_adv_sync * sync,const struct bt_iso_biginfo * biginfo)803 static void biginfo_recv(struct bt_le_per_adv_sync *sync,
804 const struct bt_iso_biginfo *biginfo)
805 {
806 struct bt_bap_broadcast_sink_cb *listener;
807 struct bt_bap_broadcast_sink *sink;
808
809 sink = broadcast_sink_get_by_pa(sync);
810 if (sink == NULL) {
811 /* Not ours */
812 return;
813 }
814
815 if (sink->big != NULL) {
816 /* Already synced - ignore */
817 return;
818 }
819
820 atomic_set_bit(sink->flags,
821 BT_BAP_BROADCAST_SINK_FLAG_BIGINFO_RECEIVED);
822 sink->iso_interval = biginfo->iso_interval;
823 sink->biginfo_num_bis = biginfo->num_bis;
824 if (biginfo->encryption != atomic_test_bit(sink->flags,
825 BT_BAP_BROADCAST_SINK_FLAG_BIG_ENCRYPTED)) {
826 atomic_set_bit_to(sink->flags,
827 BT_BAP_BROADCAST_SINK_FLAG_BIG_ENCRYPTED,
828 biginfo->encryption);
829
830 if (atomic_test_bit(sink->flags,
831 BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID)) {
832 update_recv_state_encryption(sink);
833 }
834 }
835
836 sink->qos_cfg.framing = biginfo->framing;
837 sink->qos_cfg.phy = biginfo->phy;
838 sink->qos_cfg.sdu = biginfo->max_sdu;
839 sink->qos_cfg.interval = biginfo->sdu_interval;
840
841 SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, _node) {
842 if (listener->syncable != NULL) {
843 listener->syncable(sink, biginfo);
844 }
845 }
846 }
847
interval_to_sync_timeout(uint16_t interval)848 static uint16_t interval_to_sync_timeout(uint16_t interval)
849 {
850 uint32_t interval_us;
851 uint32_t timeout;
852
853 /* Add retries and convert to unit in 10's of ms */
854 interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(interval);
855 timeout =
856 BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
857
858 /* Enforce restraints */
859 timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
860
861 return (uint16_t)timeout;
862 }
863
big_started_cb(struct bt_iso_big * big)864 static void big_started_cb(struct bt_iso_big *big)
865 {
866 struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_big(big);
867 struct bt_bap_broadcast_sink_cb *listener;
868
869 if (sink == NULL) {
870 /* Not one of ours */
871 return;
872 }
873
874 SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, _node) {
875 if (listener->started != NULL) {
876 listener->started(sink);
877 }
878 }
879 }
880
big_stopped_cb(struct bt_iso_big * big,uint8_t reason)881 static void big_stopped_cb(struct bt_iso_big *big, uint8_t reason)
882 {
883 struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_big(big);
884 struct bt_bap_broadcast_sink_cb *listener;
885
886 if (sink == NULL) {
887 /* Not one of ours */
888 return;
889 }
890
891 broadcast_sink_clear_big(sink, reason);
892
893 SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, _node) {
894 if (listener->stopped != NULL) {
895 listener->stopped(sink, reason);
896 }
897 }
898 }
899
bt_bap_broadcast_sink_register_cb(struct bt_bap_broadcast_sink_cb * cb)900 int bt_bap_broadcast_sink_register_cb(struct bt_bap_broadcast_sink_cb *cb)
901 {
902 static bool iso_big_cb_registered;
903
904 CHECKIF(cb == NULL) {
905 LOG_DBG("cb is NULL");
906
907 return -EINVAL;
908 }
909
910 if (sys_slist_find(&sink_cbs, &cb->_node, NULL)) {
911 LOG_DBG("cb %p is already registered", cb);
912
913 return -EEXIST;
914 }
915
916 if (!iso_big_cb_registered) {
917 static struct bt_iso_big_cb big_cb = {
918 .started = big_started_cb,
919 .stopped = big_stopped_cb,
920 };
921 const int err = bt_iso_big_register_cb(&big_cb);
922
923 if (err != 0) {
924 __ASSERT(false, "Failed to register ISO BIG callbacks: %d", err);
925 }
926
927 iso_big_cb_registered = true;
928 }
929
930 sys_slist_append(&sink_cbs, &cb->_node);
931
932 return 0;
933 }
934
bt_bap_ep_is_broadcast_snk(const struct bt_bap_ep * ep)935 bool bt_bap_ep_is_broadcast_snk(const struct bt_bap_ep *ep)
936 {
937 for (int i = 0; i < ARRAY_SIZE(broadcast_sink_eps); i++) {
938 if (PART_OF_ARRAY(broadcast_sink_eps[i], ep)) {
939 return true;
940 }
941 }
942
943 return false;
944 }
945
broadcast_sink_ep_init(struct bt_bap_ep * ep)946 static void broadcast_sink_ep_init(struct bt_bap_ep *ep)
947 {
948 LOG_DBG("ep %p", ep);
949
950 (void)memset(ep, 0, sizeof(*ep));
951 ep->dir = BT_AUDIO_DIR_SINK;
952 ep->iso = NULL;
953 }
954
broadcast_sink_new_ep(uint8_t index)955 static struct bt_bap_ep *broadcast_sink_new_ep(uint8_t index)
956 {
957 for (size_t i = 0; i < ARRAY_SIZE(broadcast_sink_eps[index]); i++) {
958 struct bt_bap_ep *ep = &broadcast_sink_eps[index][i];
959
960 /* If ep->stream is NULL the endpoint is unallocated */
961 if (ep->stream == NULL) {
962 broadcast_sink_ep_init(ep);
963 return ep;
964 }
965 }
966
967 return NULL;
968 }
969
bt_bap_broadcast_sink_setup_stream(struct bt_bap_broadcast_sink * sink,struct bt_bap_stream * stream,struct bt_audio_codec_cfg * codec_cfg)970 static int bt_bap_broadcast_sink_setup_stream(struct bt_bap_broadcast_sink *sink,
971 struct bt_bap_stream *stream,
972 struct bt_audio_codec_cfg *codec_cfg)
973 {
974 struct bt_bap_iso *iso;
975 struct bt_bap_ep *ep;
976
977 if (stream->group != NULL) {
978 LOG_DBG("Stream %p already in group %p", stream, stream->group);
979 return -EALREADY;
980 }
981
982 ep = broadcast_sink_new_ep(sink->index);
983 if (ep == NULL) {
984 LOG_DBG("Could not allocate new broadcast endpoint");
985 return -ENOMEM;
986 }
987
988 iso = bt_bap_iso_new();
989 if (iso == NULL) {
990 LOG_DBG("Could not allocate iso");
991 return -ENOMEM;
992 }
993
994 bt_bap_iso_init(iso, &broadcast_sink_iso_ops);
995 bt_bap_iso_bind_ep(iso, ep);
996 stream->iso = &iso->chan;
997
998 bt_bap_qos_cfg_to_iso_qos(iso->chan.qos->rx, &sink->qos_cfg);
999
1000 bt_bap_iso_unref(iso);
1001
1002 bt_bap_stream_attach(NULL, stream, ep, codec_cfg);
1003 stream->qos = &sink->qos_cfg;
1004 stream->group = sink;
1005
1006 return 0;
1007 }
1008
broadcast_sink_cleanup_streams(struct bt_bap_broadcast_sink * sink)1009 static void broadcast_sink_cleanup_streams(struct bt_bap_broadcast_sink *sink)
1010 {
1011 struct bt_bap_stream *stream, *next;
1012
1013 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sink->streams, stream, next, _node) {
1014 if (stream->ep != NULL) {
1015 bt_bap_iso_unbind_ep(stream->ep->iso, stream->ep);
1016 stream->iso = NULL;
1017 stream->ep->stream = NULL;
1018 stream->ep->broadcast_sink = NULL;
1019 stream->ep = NULL;
1020 }
1021
1022 stream->qos = NULL;
1023 stream->codec_cfg = NULL;
1024 stream->group = NULL;
1025
1026 sys_slist_remove(&sink->streams, NULL, &stream->_node);
1027 }
1028
1029 sink->stream_count = 0;
1030 sink->indexes_bitfield = 0U;
1031 }
1032
broadcast_sink_cleanup(struct bt_bap_broadcast_sink * sink)1033 static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink)
1034 {
1035 if (sink->stream_count > 0U) {
1036 broadcast_sink_cleanup_streams(sink);
1037 }
1038
1039 (void)memset(sink, 0, sizeof(*sink)); /* also clears flags */
1040 }
1041
bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync * pa_sync,uint32_t broadcast_id,struct bt_bap_broadcast_sink ** out_sink)1042 int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t broadcast_id,
1043 struct bt_bap_broadcast_sink **out_sink)
1044 {
1045 const struct bt_bap_scan_delegator_recv_state *recv_state;
1046 struct bt_bap_broadcast_sink *sink;
1047
1048 CHECKIF(pa_sync == NULL) {
1049 LOG_DBG("pa_sync is NULL");
1050
1051 return -EINVAL;
1052 }
1053
1054 CHECKIF(broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) {
1055 LOG_DBG("Invalid broadcast_id: 0x%X", broadcast_id);
1056
1057 return -EINVAL;
1058 }
1059
1060 CHECKIF(out_sink == NULL) {
1061 LOG_DBG("sink was NULL");
1062
1063 return -EINVAL;
1064 }
1065
1066 sink = broadcast_sink_free_get();
1067 if (sink == NULL) {
1068 LOG_DBG("No more free broadcast sinks");
1069
1070 return -ENOMEM;
1071 }
1072
1073 sink->broadcast_id = broadcast_id;
1074 sink->pa_sync = pa_sync;
1075
1076 recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_pa_sync_cb,
1077 (void *)pa_sync);
1078 if (recv_state == NULL) {
1079 broadcast_sink_add_src(sink);
1080 } else {
1081 /* The PA sync is known by the Scan Delegator */
1082 if (recv_state->broadcast_id != broadcast_id) {
1083 LOG_DBG("Broadcast ID mismatch: 0x%X != 0x%X",
1084 recv_state->broadcast_id, broadcast_id);
1085
1086 broadcast_sink_cleanup(sink);
1087 return -EINVAL;
1088 }
1089
1090 sink->bass_src_id = recv_state->src_id;
1091 atomic_set_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID);
1092 }
1093 atomic_set_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_INITIALIZED);
1094
1095 *out_sink = sink;
1096 return 0;
1097 }
1098
bit_count(uint32_t bitfield)1099 static uint8_t bit_count(uint32_t bitfield)
1100 {
1101 #ifdef POPCOUNT
1102 return POPCOUNT(bitfield);
1103 #else
1104 uint8_t cnt = 0U;
1105
1106 while (bitfield != 0U) {
1107 cnt += bitfield & 1U;
1108 bitfield >>= 1U;
1109 }
1110
1111 return cnt;
1112 #endif
1113 }
1114
1115 struct sync_base_info_data {
1116 struct bt_audio_codec_cfg codec_cfgs[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
1117 struct bt_audio_codec_cfg *subgroup_codec_cfg;
1118 uint32_t sync_indexes_bitfield;
1119 uint8_t subgroup_count;
1120 uint8_t stream_count;
1121 };
1122
merge_bis_and_subgroup_data_cb(struct bt_data * data,void * user_data)1123 static bool merge_bis_and_subgroup_data_cb(struct bt_data *data, void *user_data)
1124 {
1125 struct bt_audio_codec_cfg *codec_cfg = user_data;
1126 int err;
1127
1128 err = bt_audio_codec_cfg_set_val(codec_cfg, data->type, data->data, data->data_len);
1129 if (err < 0) {
1130 LOG_DBG("Failed to set type %u with len %u in codec_cfg: %d", data->type,
1131 data->data_len, err);
1132
1133 return false;
1134 }
1135
1136 return true;
1137 }
1138
sync_base_subgroup_bis_index_cb(const struct bt_bap_base_subgroup_bis * bis,void * user_data)1139 static bool sync_base_subgroup_bis_index_cb(const struct bt_bap_base_subgroup_bis *bis,
1140 void *user_data)
1141 {
1142 struct sync_base_info_data *data = user_data;
1143 struct bt_audio_codec_cfg *codec_cfg;
1144
1145 /* Only process selected BISes */
1146 if ((data->sync_indexes_bitfield & BT_ISO_BIS_INDEX_BIT(bis->index)) == 0) {
1147 return true;
1148 }
1149
1150 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
1151
1152 codec_cfg = &data->codec_cfgs[data->stream_count];
1153
1154 memcpy(codec_cfg, data->subgroup_codec_cfg, sizeof(struct bt_audio_codec_cfg));
1155
1156 if (bis->data_len > 0) {
1157 /* Merge subgroup codec configuration with the BIS configuration
1158 * As per the BAP spec, if a value exist at level 2 (subgroup) and 3 (BIS), then it
1159 * is the value at level 3 that shall be used
1160 */
1161 if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
1162 int err;
1163
1164 memcpy(codec_cfg, data->subgroup_codec_cfg,
1165 sizeof(struct bt_audio_codec_cfg));
1166
1167 err = bt_audio_data_parse(bis->data, bis->data_len,
1168 merge_bis_and_subgroup_data_cb, codec_cfg);
1169 if (err != 0) {
1170 LOG_DBG("Could not merge BIS and subgroup config in codec_cfg: %d",
1171 err);
1172
1173 return false;
1174 }
1175 } else {
1176 /* If it is not LC3, then we don't know how to merge the subgroup and BIS
1177 * codecs, so we just append them
1178 */
1179 if (codec_cfg->data_len + bis->data_len > sizeof(codec_cfg->data)) {
1180 LOG_DBG("Could not store BIS and subgroup config in codec_cfg (%u "
1181 "> %u)",
1182 codec_cfg->data_len + bis->data_len,
1183 sizeof(codec_cfg->data));
1184
1185 return false;
1186 }
1187
1188 memcpy(&codec_cfg->data[codec_cfg->data_len], bis->data, bis->data_len);
1189 codec_cfg->data_len += bis->data_len;
1190 }
1191 }
1192 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
1193
1194 data->stream_count++;
1195
1196 return true;
1197 }
1198
sync_base_subgroup_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)1199 static bool sync_base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
1200 {
1201 struct sync_base_info_data *data = user_data;
1202 const struct bt_audio_codec_cap *codec_cap;
1203 struct bt_audio_codec_cfg codec_cfg;
1204 struct bt_pac_codec codec_id;
1205 int ret;
1206
1207 if (data->subgroup_count == CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT) {
1208 /* We've parsed as many subgroups as we support */
1209 LOG_DBG("Could only store %u subgroups", data->subgroup_count);
1210 return false;
1211 }
1212
1213 ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &codec_cfg);
1214 if (ret < 0) {
1215 LOG_DBG("Could not store codec_cfg: %d", ret);
1216 return false;
1217 }
1218
1219 /* Lookup and assign path_id based on capabilities */
1220 codec_id.id = codec_cfg.id;
1221 codec_id.cid = codec_cfg.cid;
1222 codec_id.vid = codec_cfg.vid;
1223
1224 codec_cap = bt_pacs_get_codec_cap(BT_AUDIO_DIR_SINK, &codec_id);
1225 if (codec_cap == NULL) {
1226 LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x is not supported by our "
1227 "capabilities",
1228 codec_id.id, codec_id.cid, codec_id.vid);
1229 } else {
1230 codec_cfg.path_id = codec_cap->path_id;
1231 codec_cfg.ctlr_transcode = codec_cap->ctlr_transcode;
1232
1233 data->subgroup_codec_cfg = &codec_cfg;
1234
1235 ret = bt_bap_base_subgroup_foreach_bis(subgroup, sync_base_subgroup_bis_index_cb,
1236 data);
1237 if (ret < 0) {
1238 LOG_DBG("Could not parse BISes: %d", ret);
1239 return false;
1240 }
1241
1242 data->subgroup_count++;
1243 }
1244
1245 return true;
1246 }
1247
bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink * sink,uint32_t indexes_bitfield,struct bt_bap_stream * streams[],const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])1248 int bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink *sink, uint32_t indexes_bitfield,
1249 struct bt_bap_stream *streams[],
1250 const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
1251 {
1252 static struct sync_base_info_data data;
1253 struct bt_iso_big_sync_param param;
1254 struct bt_iso_chan *bis_channels[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
1255 uint8_t bis_count;
1256 uint8_t stream_count;
1257 int err;
1258 int ret;
1259
1260 CHECKIF(sink == NULL) {
1261 LOG_DBG("sink is NULL");
1262 return -EINVAL;
1263 }
1264
1265 CHECKIF(indexes_bitfield == 0U || indexes_bitfield > BIT_MASK(BT_ISO_BIS_INDEX_MAX)) {
1266 LOG_DBG("Invalid indexes_bitfield: 0x%08X", indexes_bitfield);
1267 return -EINVAL;
1268 }
1269
1270 CHECKIF(streams == NULL) {
1271 LOG_DBG("streams is NULL");
1272 return -EINVAL;
1273 }
1274
1275 if (sink->pa_sync == NULL) {
1276 LOG_DBG("Sink is not PA synced");
1277 return -EINVAL;
1278 }
1279
1280 if (!atomic_test_bit(sink->flags,
1281 BT_BAP_BROADCAST_SINK_FLAG_BIGINFO_RECEIVED)) {
1282 /* TODO: We could store the request to sync and start the sync
1283 * once the BIGInfo has been received, and then do the sync
1284 * then. This would be similar how LE Create Connection works.
1285 */
1286 LOG_DBG("BIGInfo not received, cannot sync yet");
1287 return -EAGAIN;
1288 }
1289
1290 if (atomic_test_bit(sink->flags,
1291 BT_BAP_BROADCAST_SINK_FLAG_BIG_ENCRYPTED) &&
1292 broadcast_code == NULL) {
1293 LOG_DBG("Broadcast code required");
1294
1295 return -EINVAL;
1296 }
1297
1298 /* Validate that number of bits set is within supported range */
1299 bis_count = bit_count(indexes_bitfield);
1300 if (bis_count > CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT) {
1301 LOG_DBG("Cannot sync to more than %d streams (%u was requested)",
1302 CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT, bis_count);
1303 return -EINVAL;
1304 }
1305
1306 /* Validate that the bits set are present in BASE */
1307 if ((indexes_bitfield & sink->valid_indexes_bitfield) != indexes_bitfield) {
1308 LOG_DBG("Request BIS indexes (0x%08X) contains bits not present in BASE (0x%08X)",
1309 indexes_bitfield, sink->valid_indexes_bitfield);
1310 return -EINVAL;
1311 }
1312
1313 memset(&data, 0, sizeof(data));
1314
1315 data.sync_indexes_bitfield = indexes_bitfield;
1316
1317 ret = bt_bap_base_foreach_subgroup((const struct bt_bap_base *)sink->base,
1318 sync_base_subgroup_cb, &data);
1319 if (ret != 0) {
1320 LOG_DBG("Failed to parse all subgroups: %d", ret);
1321 return ret;
1322 }
1323
1324 stream_count = data.stream_count;
1325
1326 for (size_t i = 0; i < stream_count; i++) {
1327 CHECKIF(streams[i] == NULL) {
1328 LOG_DBG("streams[%zu] is NULL", i);
1329 return -EINVAL;
1330 }
1331 }
1332
1333 sink->stream_count = 0U;
1334 for (size_t i = 0; i < stream_count; i++) {
1335 struct bt_bap_stream *stream;
1336 struct bt_audio_codec_cfg *codec_cfg;
1337
1338 stream = streams[i];
1339 codec_cfg = &data.codec_cfgs[i];
1340
1341 err = bt_bap_broadcast_sink_setup_stream(sink, stream, codec_cfg);
1342 if (err != 0) {
1343 LOG_DBG("Failed to setup streams[%zu]: %d", i, err);
1344 broadcast_sink_cleanup_streams(sink);
1345 return err;
1346 }
1347
1348 sink->bis[i].chan = bt_bap_stream_iso_chan_get(stream);
1349 sys_slist_append(&sink->streams, &stream->_node);
1350 sink->stream_count++;
1351
1352 bis_channels[i] = sink->bis[i].chan;
1353 }
1354
1355 param.bis_channels = bis_channels;
1356 param.num_bis = sink->stream_count;
1357 param.bis_bitfield = indexes_bitfield;
1358 param.mse = 0; /* Let controller decide */
1359 param.sync_timeout = interval_to_sync_timeout(sink->iso_interval);
1360 param.encryption = atomic_test_bit(sink->flags,
1361 BT_BAP_BROADCAST_SINK_FLAG_BIG_ENCRYPTED);
1362 if (param.encryption) {
1363 memcpy(param.bcode, broadcast_code, sizeof(param.bcode));
1364 } else {
1365 memset(param.bcode, 0, sizeof(param.bcode));
1366 }
1367
1368 err = bt_iso_big_sync(sink->pa_sync, ¶m, &sink->big);
1369 if (err != 0) {
1370 broadcast_sink_cleanup_streams(sink);
1371 return err;
1372 }
1373
1374 sink->indexes_bitfield = indexes_bitfield;
1375 for (size_t i = 0; i < stream_count; i++) {
1376 struct bt_bap_ep *ep = streams[i]->ep;
1377
1378 ep->broadcast_sink = sink;
1379 broadcast_sink_set_ep_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
1380 }
1381
1382 return 0;
1383 }
1384
bt_bap_broadcast_sink_stop(struct bt_bap_broadcast_sink * sink)1385 int bt_bap_broadcast_sink_stop(struct bt_bap_broadcast_sink *sink)
1386 {
1387 int err;
1388
1389 CHECKIF(sink == NULL) {
1390 LOG_DBG("sink is NULL");
1391 return -EINVAL;
1392 }
1393
1394 if (sys_slist_is_empty(&sink->streams)) {
1395 LOG_DBG("Source does not have any streams (already stopped)");
1396 return -EALREADY;
1397 }
1398
1399 if (broadcast_sink_is_in_state(sink, BT_BAP_EP_STATE_IDLE)) {
1400 LOG_DBG("Broadcast sink %p in idle state", sink);
1401 return -EBADMSG;
1402 }
1403
1404 err = bt_iso_big_terminate(sink->big);
1405 if (err) {
1406 LOG_DBG("Failed to terminate BIG (err %d)", err);
1407 return err;
1408 }
1409
1410 return 0;
1411 }
1412
bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink * sink)1413 int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink)
1414 {
1415
1416 CHECKIF(sink == NULL) {
1417 LOG_DBG("sink is NULL");
1418 return -EINVAL;
1419 }
1420
1421 if (!broadcast_sink_is_in_state(sink, BT_BAP_EP_STATE_IDLE)) {
1422 LOG_DBG("Broadcast sink %p not in idle state", sink);
1423 return -EBADMSG;
1424 }
1425
1426 /* Reset the broadcast sink */
1427 broadcast_sink_cleanup(sink);
1428
1429 return 0;
1430 }
1431
broadcast_sink_init(void)1432 static int broadcast_sink_init(void)
1433 {
1434 static struct bt_le_per_adv_sync_cb cb = {
1435 .recv = pa_recv,
1436 .biginfo = biginfo_recv,
1437 .term = pa_term_cb,
1438 };
1439
1440 bt_le_per_adv_sync_cb_register(&cb);
1441
1442 return 0;
1443 }
1444
1445 SYS_INIT(broadcast_sink_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
1446