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