1 /* Bluetooth Audio Broadcast Source */
2
3 /*
4 * Copyright (c) 2021-2023 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <zephyr/sys/check.h>
12
13 #include <zephyr/bluetooth/bluetooth.h>
14 #include <zephyr/bluetooth/conn.h>
15 #include <zephyr/bluetooth/gatt.h>
16 #include <zephyr/bluetooth/audio/audio.h>
17 #include <zephyr/bluetooth/audio/bap.h>
18
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(bt_bap_broadcast_source, CONFIG_BT_BAP_BROADCAST_SOURCE_LOG_LEVEL);
21
22 #include "bap_iso.h"
23 #include "bap_endpoint.h"
24
25 struct bt_bap_broadcast_subgroup {
26 /* The streams used to create the broadcast source */
27 sys_slist_t streams;
28
29 /* The codec of the subgroup */
30 struct bt_codec *codec;
31
32 /* List node */
33 sys_snode_t _node;
34 };
35
36 static struct bt_bap_ep broadcast_source_eps[CONFIG_BT_BAP_BROADCAST_SRC_COUNT]
37 [BROADCAST_STREAM_CNT];
38 static struct bt_bap_broadcast_subgroup
39 broadcast_source_subgroups[CONFIG_BT_BAP_BROADCAST_SRC_COUNT]
40 [CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
41 static struct bt_bap_broadcast_source broadcast_sources[CONFIG_BT_BAP_BROADCAST_SRC_COUNT];
42
43 /**
44 * 2 octets UUID
45 * 3 octets presentation delay
46 * 1 octet number of subgroups
47 *
48 * Each subgroup then has
49 * 1 octet of number of BIS
50 * 5 octets of Codec_ID
51 * 1 octet codec specific configuration len
52 * 0-n octets of codec specific configuration
53 * 1 octet metadata len
54 * 0-n octets of metadata
55 *
56 * For each BIS in the subgroup there is
57 * 1 octet for the BIS index
58 * 1 octet codec specific configuration len
59 * 0-n octets of codec specific configuration
60 *
61 * For a minimal BASE with 1 subgroup and 1 BIS without and other data the
62 * total comes to 16
63 */
64 #define MINIMUM_BASE_SIZE 16
65
broadcast_source_set_ep_state(struct bt_bap_ep * ep,uint8_t state)66 static void broadcast_source_set_ep_state(struct bt_bap_ep *ep, uint8_t state)
67 {
68 uint8_t old_state;
69
70 old_state = ep->status.state;
71
72 LOG_DBG("ep %p id 0x%02x %s -> %s", ep, ep->status.id, bt_bap_ep_state_str(old_state),
73 bt_bap_ep_state_str(state));
74
75 switch (old_state) {
76 case BT_BAP_EP_STATE_IDLE:
77 if (state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
78 LOG_DBG("Invalid broadcast sync endpoint state transition");
79 return;
80 }
81 break;
82 case BT_BAP_EP_STATE_QOS_CONFIGURED:
83 if (state != BT_BAP_EP_STATE_IDLE && state != BT_BAP_EP_STATE_ENABLING) {
84 LOG_DBG("Invalid broadcast sync endpoint state transition");
85 return;
86 }
87 break;
88 case BT_BAP_EP_STATE_ENABLING:
89 if (state != BT_BAP_EP_STATE_STREAMING) {
90 LOG_DBG("Invalid broadcast sync endpoint state transition");
91 return;
92 }
93 break;
94 case BT_BAP_EP_STATE_STREAMING:
95 if (state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
96 LOG_DBG("Invalid broadcast sync endpoint state transition");
97 return;
98 }
99 break;
100 default:
101 LOG_ERR("Invalid broadcast sync endpoint state: %s",
102 bt_bap_ep_state_str(old_state));
103 return;
104 }
105
106 ep->status.state = state;
107 }
108
broadcast_source_set_state(struct bt_bap_broadcast_source * source,uint8_t state)109 static void broadcast_source_set_state(struct bt_bap_broadcast_source *source, uint8_t state)
110 {
111 struct bt_bap_broadcast_subgroup *subgroup;
112
113 SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
114 struct bt_bap_stream *stream;
115
116 SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
117 broadcast_source_set_ep_state(stream->ep, state);
118 }
119 }
120 }
121
broadcast_source_iso_sent(struct bt_iso_chan * chan)122 static void broadcast_source_iso_sent(struct bt_iso_chan *chan)
123 {
124 struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
125 const struct bt_bap_stream_ops *ops;
126 struct bt_bap_stream *stream;
127 struct bt_bap_ep *ep = iso->tx.ep;
128
129 if (ep == NULL) {
130 LOG_ERR("iso %p not bound with ep", chan);
131 return;
132 }
133
134 stream = ep->stream;
135 if (stream == NULL) {
136 LOG_ERR("No stream for ep %p", ep);
137 return;
138 }
139
140 ops = stream->ops;
141
142 if (IS_ENABLED(CONFIG_BT_BAP_DEBUG_STREAM_DATA)) {
143 LOG_DBG("stream %p ep %p", stream, stream->ep);
144 }
145
146 if (ops != NULL && ops->sent != NULL) {
147 ops->sent(stream);
148 }
149 }
150
broadcast_source_iso_connected(struct bt_iso_chan * chan)151 static void broadcast_source_iso_connected(struct bt_iso_chan *chan)
152 {
153 struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
154 const struct bt_bap_stream_ops *ops;
155 struct bt_bap_stream *stream;
156 struct bt_bap_ep *ep = iso->tx.ep;
157
158 if (ep == NULL) {
159 LOG_ERR("iso %p not bound with ep", chan);
160 return;
161 }
162
163 stream = ep->stream;
164 if (stream == NULL) {
165 LOG_ERR("No stream for ep %p", ep);
166 return;
167 }
168
169 ops = stream->ops;
170
171 LOG_DBG("stream %p ep %p", stream, ep);
172
173 broadcast_source_set_ep_state(ep, BT_BAP_EP_STATE_STREAMING);
174
175 if (ops != NULL && ops->started != NULL) {
176 ops->started(stream);
177 } else {
178 LOG_WRN("No callback for connected set");
179 }
180 }
181
broadcast_source_iso_disconnected(struct bt_iso_chan * chan,uint8_t reason)182 static void broadcast_source_iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
183 {
184 struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
185 const struct bt_bap_stream_ops *ops;
186 struct bt_bap_stream *stream;
187 struct bt_bap_ep *ep = iso->tx.ep;
188
189 if (ep == NULL) {
190 LOG_ERR("iso %p not bound with ep", chan);
191 return;
192 }
193
194 stream = ep->stream;
195 if (stream == NULL) {
196 LOG_ERR("No stream for ep %p", ep);
197 return;
198 }
199
200 ops = stream->ops;
201
202 LOG_DBG("stream %p ep %p reason 0x%02x", stream, stream->ep, reason);
203
204 broadcast_source_set_ep_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
205
206 if (ops != NULL && ops->stopped != NULL) {
207 ops->stopped(stream, reason);
208 } else {
209 LOG_WRN("No callback for stopped set");
210 }
211 }
212
213 static struct bt_iso_chan_ops broadcast_source_iso_ops = {
214 .sent = broadcast_source_iso_sent,
215 .connected = broadcast_source_iso_connected,
216 .disconnected = broadcast_source_iso_disconnected,
217 };
218
bt_bap_ep_is_broadcast_src(const struct bt_bap_ep * ep)219 bool bt_bap_ep_is_broadcast_src(const struct bt_bap_ep *ep)
220 {
221 for (int i = 0; i < ARRAY_SIZE(broadcast_source_eps); i++) {
222 if (PART_OF_ARRAY(broadcast_source_eps[i], ep)) {
223 return true;
224 }
225 }
226
227 return false;
228 }
229
broadcast_source_ep_init(struct bt_bap_ep * ep)230 static void broadcast_source_ep_init(struct bt_bap_ep *ep)
231 {
232 LOG_DBG("ep %p", ep);
233
234 (void)memset(ep, 0, sizeof(*ep));
235 ep->dir = BT_AUDIO_DIR_SOURCE;
236 ep->iso = NULL;
237 }
238
broadcast_source_new_ep(uint8_t index)239 static struct bt_bap_ep *broadcast_source_new_ep(uint8_t index)
240 {
241 for (size_t i = 0; i < ARRAY_SIZE(broadcast_source_eps[index]); i++) {
242 struct bt_bap_ep *ep = &broadcast_source_eps[index][i];
243
244 /* If ep->stream is NULL the endpoint is unallocated */
245 if (ep->stream == NULL) {
246 broadcast_source_ep_init(ep);
247 return ep;
248 }
249 }
250
251 return NULL;
252 }
253
broadcast_source_new_subgroup(uint8_t index)254 static struct bt_bap_broadcast_subgroup *broadcast_source_new_subgroup(uint8_t index)
255 {
256 for (size_t i = 0; i < ARRAY_SIZE(broadcast_source_subgroups[index]); i++) {
257 struct bt_bap_broadcast_subgroup *subgroup = &broadcast_source_subgroups[index][i];
258
259 if (sys_slist_is_empty(&subgroup->streams)) {
260 return subgroup;
261 }
262 }
263
264 return NULL;
265 }
266
broadcast_source_setup_stream(uint8_t index,struct bt_bap_stream * stream,struct bt_codec * codec,struct bt_codec_qos * qos,struct bt_bap_broadcast_source * source)267 static int broadcast_source_setup_stream(uint8_t index, struct bt_bap_stream *stream,
268 struct bt_codec *codec, struct bt_codec_qos *qos,
269 struct bt_bap_broadcast_source *source)
270 {
271 struct bt_bap_iso *iso;
272 struct bt_bap_ep *ep;
273
274 ep = broadcast_source_new_ep(index);
275 if (ep == NULL) {
276 LOG_DBG("Could not allocate new broadcast endpoint");
277 return -ENOMEM;
278 }
279
280 iso = bt_bap_iso_new();
281 if (iso == NULL) {
282 LOG_DBG("Could not allocate iso");
283 return -ENOMEM;
284 }
285
286 bt_bap_iso_init(iso, &broadcast_source_iso_ops);
287 bt_bap_iso_bind_ep(iso, ep);
288
289 bt_audio_codec_qos_to_iso_qos(iso->chan.qos->tx, qos);
290 bt_audio_codec_to_iso_path(iso->chan.qos->tx->path, codec);
291
292 bt_bap_iso_unref(iso);
293
294 bt_bap_stream_attach(NULL, stream, ep, codec);
295 stream->qos = qos;
296 ep->broadcast_source = source;
297
298 return 0;
299 }
300
encode_base_subgroup(struct bt_bap_broadcast_subgroup * subgroup,struct bt_audio_broadcast_stream_data * stream_data,uint8_t * streams_encoded,struct net_buf_simple * buf)301 static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup,
302 struct bt_audio_broadcast_stream_data *stream_data,
303 uint8_t *streams_encoded, struct net_buf_simple *buf)
304 {
305 struct bt_bap_stream *stream;
306 const struct bt_codec *codec;
307 uint8_t stream_count;
308 uint8_t bis_index;
309 uint8_t *start;
310 uint8_t len;
311
312 stream_count = 0;
313 SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
314 stream_count++;
315 }
316
317 codec = subgroup->codec;
318
319 net_buf_simple_add_u8(buf, stream_count);
320 net_buf_simple_add_u8(buf, codec->id);
321 net_buf_simple_add_le16(buf, codec->cid);
322 net_buf_simple_add_le16(buf, codec->vid);
323
324
325 /* Insert codec configuration data in LTV format */
326 start = net_buf_simple_add(buf, sizeof(len));
327
328 for (int i = 0; i < codec->data_count; i++) {
329 const struct bt_data *codec_data = &codec->data[i].data;
330
331 if ((buf->size - buf->len) < (sizeof(codec_data->data_len) +
332 sizeof(codec_data->type) +
333 codec_data->data_len)) {
334 LOG_DBG("No room for codec[%d] with len %u", i, codec_data->data_len);
335
336 return false;
337 }
338
339 net_buf_simple_add_u8(buf, codec_data->data_len + sizeof(codec_data->type));
340 net_buf_simple_add_u8(buf, codec_data->type);
341 net_buf_simple_add_mem(buf, codec_data->data, codec_data->data_len);
342
343 }
344 /* Calculate length of codec config data */
345 len = net_buf_simple_tail(buf) - start - sizeof(len);
346 /* Update the length field */
347 *start = len;
348
349 if ((buf->size - buf->len) < sizeof(len)) {
350 LOG_DBG("No room for metadata length");
351
352 return false;
353 }
354
355 /* Insert codec metadata in LTV format*/
356 start = net_buf_simple_add(buf, sizeof(len));
357 for (int i = 0; i < codec->meta_count; i++) {
358 const struct bt_data *metadata = &codec->meta[i].data;
359
360 if ((buf->size - buf->len) < (sizeof(metadata->data_len) +
361 sizeof(metadata->type) +
362 metadata->data_len)) {
363 LOG_DBG("No room for metadata[%d] with len %u", i, metadata->data_len);
364
365 return false;
366 }
367
368 net_buf_simple_add_u8(buf, metadata->data_len + sizeof(metadata->type));
369 net_buf_simple_add_u8(buf, metadata->type);
370 net_buf_simple_add_mem(buf, metadata->data, metadata->data_len);
371 }
372 /* Calculate length of codec config data */
373 len = net_buf_simple_tail(buf) - start - sizeof(len);
374 /* Update the length field */
375 *start = len;
376
377 /* Create BIS index bitfield */
378 bis_index = 0;
379 for (int i = 0; i < stream_count; i++) {
380 bis_index++;
381 if ((buf->size - buf->len) < (sizeof(bis_index) + sizeof(uint8_t))) {
382 LOG_DBG("No room for BIS[%d] index", i);
383
384 return false;
385 }
386
387 net_buf_simple_add_u8(buf, bis_index);
388
389 if ((buf->size - buf->len) < sizeof(len)) {
390 LOG_DBG("No room for bis codec config length");
391
392 return false;
393 }
394
395 /* Insert codec configuration data in LTV format */
396 start = net_buf_simple_add(buf, sizeof(len));
397
398 #if defined(CONFIG_BT_CODEC_MAX_DATA_COUNT)
399 for (size_t j = 0U; j < stream_data[i].data_count; j++) {
400 const struct bt_data *codec_data = &stream_data[i].data[j].data;
401
402 if ((buf->size - buf->len) < (sizeof(codec_data->data_len) +
403 sizeof(codec_data->type) +
404 codec_data->data_len)) {
405 LOG_DBG("No room for BIS [%u] codec[%zu] with len %u", bis_index, j,
406 codec_data->data_len);
407
408 return false;
409 }
410
411 net_buf_simple_add_u8(buf, codec_data->data_len + sizeof(codec_data->type));
412 net_buf_simple_add_u8(buf, codec_data->type);
413 net_buf_simple_add_mem(buf, codec_data->data, codec_data->data_len);
414 }
415 #endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT */
416
417 /* Calculate length of codec config data */
418 len = net_buf_simple_tail(buf) - start - sizeof(len);
419 /* Update the length field */
420 *start = len;
421
422 streams_encoded++;
423 }
424
425 return true;
426 }
427
encode_base(struct bt_bap_broadcast_source * source,struct net_buf_simple * buf)428 static bool encode_base(struct bt_bap_broadcast_source *source, struct net_buf_simple *buf)
429 {
430 struct bt_bap_broadcast_subgroup *subgroup;
431 uint8_t streams_encoded;
432 uint8_t subgroup_count;
433
434 /* 13 is the size of the fixed size values following this check */
435 if ((buf->size - buf->len) < MINIMUM_BASE_SIZE) {
436 return false;
437 }
438
439 subgroup_count = 0U;
440 SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
441 subgroup_count++;
442 }
443
444 net_buf_simple_add_le16(buf, BT_UUID_BASIC_AUDIO_VAL);
445
446 net_buf_simple_add_le24(buf, source->qos->pd);
447 net_buf_simple_add_u8(buf, subgroup_count);
448
449 /* Since the `stream_data` is only stored in the broadcast source,
450 * we need to provide that information when encoding each subgroup
451 */
452 streams_encoded = 0;
453 SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
454 if (!encode_base_subgroup(subgroup,
455 &source->stream_data[streams_encoded],
456 &streams_encoded, buf)) {
457 return false;
458 }
459 }
460
461 return true;
462 }
463
generate_broadcast_id(struct bt_bap_broadcast_source * source)464 static int generate_broadcast_id(struct bt_bap_broadcast_source *source)
465 {
466 bool unique;
467
468 do {
469 int err;
470
471 err = bt_rand(&source->broadcast_id,
472 BT_AUDIO_BROADCAST_ID_SIZE);
473 if (err) {
474 return err;
475 }
476
477 /* Ensure uniqueness */
478 unique = true;
479 for (int i = 0; i < ARRAY_SIZE(broadcast_sources); i++) {
480 if (&broadcast_sources[i] == source) {
481 continue;
482 }
483
484 if (broadcast_sources[i].broadcast_id == source->broadcast_id) {
485 unique = false;
486 break;
487 }
488 }
489 } while (!unique);
490
491 return 0;
492 }
493
broadcast_source_cleanup(struct bt_bap_broadcast_source * source)494 static void broadcast_source_cleanup(struct bt_bap_broadcast_source *source)
495 {
496 struct bt_bap_broadcast_subgroup *subgroup, *next_subgroup;
497
498 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&source->subgroups, subgroup,
499 next_subgroup, _node) {
500 struct bt_bap_stream *stream, *next_stream;
501
502 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&subgroup->streams, stream,
503 next_stream, _node) {
504 bt_bap_iso_unbind_ep(stream->ep->iso, stream->ep);
505 stream->ep->stream = NULL;
506 stream->ep = NULL;
507 stream->codec = NULL;
508 stream->qos = NULL;
509 stream->group = NULL;
510
511 sys_slist_remove(&subgroup->streams, NULL,
512 &stream->_node);
513 }
514 sys_slist_remove(&source->subgroups, NULL, &subgroup->_node);
515 }
516
517 (void)memset(source, 0, sizeof(*source));
518 }
519
valid_create_param(const struct bt_bap_broadcast_source_create_param * param)520 static bool valid_create_param(const struct bt_bap_broadcast_source_create_param *param)
521 {
522 const struct bt_codec_qos *qos;
523
524 CHECKIF(param == NULL) {
525 LOG_DBG("param is NULL");
526 return false;
527 }
528
529 CHECKIF(!IN_RANGE(param->params_count, 1U, CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT)) {
530 LOG_DBG("param->params_count %zu is invalid", param->params_count);
531 return false;
532 }
533
534 CHECKIF(param->packing != BT_ISO_PACKING_SEQUENTIAL &&
535 param->packing != BT_ISO_PACKING_INTERLEAVED) {
536 LOG_DBG("param->packing %u is invalid", param->packing);
537 return false;
538 }
539
540 qos = param->qos;
541 CHECKIF(qos == NULL) {
542 LOG_DBG("param->qos is NULL");
543 return false;
544 }
545
546 CHECKIF(bt_audio_verify_qos(qos) != BT_BAP_ASCS_REASON_NONE) {
547 LOG_DBG("param->qos is invalid");
548 return false;
549 }
550
551 CHECKIF(param->qos->rtn > BT_ISO_BROADCAST_RTN_MAX) {
552 LOG_DBG("param->qos->rtn %u invalid", param->qos->rtn);
553 return false;
554 }
555
556 CHECKIF(param->params == NULL) {
557 LOG_DBG("param->params is NULL");
558 return false;
559 }
560
561 CHECKIF(param->params_count == 0) {
562 LOG_DBG("param->params_count is 0");
563 return false;
564 }
565
566 for (size_t i = 0U; i < param->params_count; i++) {
567 const struct bt_bap_broadcast_source_subgroup_param *subgroup_param;
568
569 subgroup_param = ¶m->params[i];
570
571 CHECKIF(subgroup_param->params == NULL) {
572 LOG_DBG("subgroup_params[%zu].params is NULL", i);
573 return false;
574 }
575
576 CHECKIF(!IN_RANGE(subgroup_param->params_count, 1U,
577 CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT)) {
578 LOG_DBG("subgroup_params[%zu].count (%zu) is invalid", i,
579 subgroup_param->params_count);
580 return false;
581 }
582
583 CHECKIF(!bt_audio_valid_codec(subgroup_param->codec)) {
584 LOG_DBG("subgroup_params[%zu].codec is invalid", i);
585 return false;
586 }
587
588 for (size_t j = 0U; j < subgroup_param->params_count; j++) {
589 const struct bt_bap_broadcast_source_stream_param *stream_param;
590
591 stream_param = &subgroup_param->params[j];
592
593 CHECKIF(stream_param->stream == NULL) {
594 LOG_DBG("subgroup_params[%zu].stream_params[%zu]->stream is NULL",
595 i, j);
596 return false;
597 }
598
599 CHECKIF(stream_param->stream->group != NULL) {
600 LOG_DBG("subgroup_params[%zu].stream_params[%zu]->stream is "
601 "already part of group %p",
602 i, j, stream_param->stream->group);
603 return false;
604 }
605
606 CHECKIF(stream_param->data == NULL && stream_param->data_count != 0) {
607 LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data is "
608 "NULL with count %zu",
609 i, j, stream_param->data_count);
610 return false;
611 }
612
613 #if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0
614 CHECKIF(stream_param->data_count > CONFIG_BT_CODEC_MAX_DATA_COUNT) {
615 LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data_count too "
616 "large: %zu/%d",
617 i, j, stream_param->data_count,
618 CONFIG_BT_CODEC_MAX_DATA_COUNT);
619 return false;
620 }
621
622 for (size_t k = 0U; k < stream_param->data_count; k++) {
623 CHECKIF(!(bt_audio_valid_codec_data(&stream_param->data[k]))) {
624 LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data[%zu]"
625 " invalid",
626 i, j, k);
627
628 return false;
629 }
630 }
631 }
632 #endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */
633 }
634
635 return true;
636 }
637
broadcast_source_get_state(struct bt_bap_broadcast_source * source)638 static enum bt_bap_ep_state broadcast_source_get_state(struct bt_bap_broadcast_source *source)
639 {
640 struct bt_bap_broadcast_subgroup *subgroup;
641 struct bt_bap_stream *stream;
642 sys_snode_t *head_node;
643
644 if (source == NULL) {
645 LOG_DBG("source is NULL");
646 return BT_BAP_EP_STATE_IDLE;
647 }
648
649 if (sys_slist_is_empty(&source->subgroups)) {
650 LOG_DBG("Source does not have any streams");
651 return BT_BAP_EP_STATE_IDLE;
652 }
653
654 /* Get the first stream */
655 head_node = sys_slist_peek_head(&source->subgroups);
656 subgroup = CONTAINER_OF(head_node, struct bt_bap_broadcast_subgroup, _node);
657
658 head_node = sys_slist_peek_head(&subgroup->streams);
659 stream = CONTAINER_OF(head_node, struct bt_bap_stream, _node);
660
661 /* All streams in a broadcast source is in the same state,
662 * so we can just check the first stream
663 */
664 if (stream->ep == NULL) {
665 LOG_DBG("stream->ep is NULL");
666 return BT_BAP_EP_STATE_IDLE;
667 }
668
669 return stream->ep->status.state;
670 }
671
bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param * param,struct bt_bap_broadcast_source ** out_source)672 int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param *param,
673 struct bt_bap_broadcast_source **out_source)
674 {
675 struct bt_bap_broadcast_source *source;
676 struct bt_codec_qos *qos;
677 size_t stream_count;
678 uint8_t index;
679 int err;
680
681 CHECKIF(out_source == NULL) {
682 LOG_DBG("out_source is NULL");
683 return -EINVAL;
684 }
685
686 /* Set out_source to NULL until the source has actually been created */
687 *out_source = NULL;
688
689 if (!valid_create_param(param)) {
690 LOG_DBG("Invalid parameters");
691 return -EINVAL;
692 }
693
694 source = NULL;
695 for (index = 0; index < ARRAY_SIZE(broadcast_sources); index++) {
696 if (sys_slist_is_empty(&broadcast_sources[index].subgroups)) { /* Find free entry */
697 source = &broadcast_sources[index];
698 break;
699 }
700 }
701
702 if (source == NULL) {
703 LOG_DBG("Could not allocate any more broadcast sources");
704 return -ENOMEM;
705 }
706
707 stream_count = 0U;
708
709 qos = param->qos;
710 /* Go through all subgroups and streams and setup each setup with an
711 * endpoint
712 */
713 for (size_t i = 0U; i < param->params_count; i++) {
714 const struct bt_bap_broadcast_source_subgroup_param *subgroup_param;
715 struct bt_bap_broadcast_subgroup *subgroup;
716
717 subgroup_param = ¶m->params[i];
718
719 subgroup = broadcast_source_new_subgroup(index);
720 if (subgroup == NULL) {
721 LOG_DBG("Could not allocate new broadcast subgroup");
722 broadcast_source_cleanup(source);
723 return -ENOMEM;
724 }
725
726 subgroup->codec = subgroup_param->codec;
727 sys_slist_append(&source->subgroups, &subgroup->_node);
728
729 /* Check that we are not above the maximum BIS count */
730 if (subgroup_param->params_count + stream_count > BROADCAST_STREAM_CNT) {
731 LOG_DBG("Cannot create broadcaster with %zu streams", stream_count);
732 broadcast_source_cleanup(source);
733
734 return -ENOMEM;
735 }
736
737 for (size_t j = 0U; j < subgroup_param->params_count; j++) {
738 const struct bt_bap_broadcast_source_stream_param *stream_param;
739 struct bt_bap_stream *stream;
740
741 stream_param = &subgroup_param->params[j];
742 stream = stream_param->stream;
743
744 err = broadcast_source_setup_stream(index, stream,
745 subgroup_param->codec,
746 qos, source);
747 if (err != 0) {
748 LOG_DBG("Failed to setup streams[%zu]: %d", i, err);
749 broadcast_source_cleanup(source);
750 return err;
751 }
752
753 /* Store the BIS specific codec configuration data in
754 * the broadcast source. It is stored in the broadcast
755 * source, instead of the stream object, as this is
756 * only relevant for the broadcast source, and not used
757 * for unicast or broadcast sink.
758 */
759 (void)memcpy(source->stream_data[stream_count].data,
760 stream_param->data,
761 stream_param->data_count * sizeof(*stream_param->data));
762 source->stream_data[stream_count].data_count = stream_param->data_count;
763 for (uint8_t i = 0U; i < stream_param->data_count; i++) {
764 source->stream_data[stream_count].data[i].data.data =
765 source->stream_data[stream_count].data[i].value;
766 }
767
768 sys_slist_append(&subgroup->streams, &stream->_node);
769 stream_count++;
770 }
771 }
772
773 err = generate_broadcast_id(source);
774 if (err != 0) {
775 LOG_DBG("Could not generate broadcast id: %d", err);
776 return err;
777 }
778
779 /* Finalize state changes and store information */
780 broadcast_source_set_state(source, BT_BAP_EP_STATE_QOS_CONFIGURED);
781 source->qos = qos;
782 source->packing = param->packing;
783
784 source->encryption = param->encryption;
785 if (source->encryption) {
786 (void)memcpy(source->broadcast_code, param->broadcast_code,
787 sizeof(source->broadcast_code));
788 }
789
790 LOG_DBG("Broadcasting with ID 0x%6X", source->broadcast_id);
791
792 *out_source = source;
793
794 return 0;
795 }
796
bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source * source,struct bt_codec * codec,struct bt_codec_qos * qos)797 int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, struct bt_codec *codec,
798 struct bt_codec_qos *qos)
799 {
800 struct bt_bap_broadcast_subgroup *subgroup;
801 enum bt_bap_ep_state broadcast_state;
802 struct bt_bap_stream *stream;
803
804 CHECKIF(source == NULL) {
805 LOG_DBG("source is NULL");
806 return -EINVAL;
807 }
808
809 CHECKIF(!bt_audio_valid_codec(codec)) {
810 LOG_DBG("codec is invalid");
811 return -EINVAL;
812 }
813
814 CHECKIF(qos == NULL) {
815 LOG_DBG("qos is NULL");
816 return -EINVAL;
817 }
818
819 CHECKIF(bt_audio_verify_qos(qos) != BT_BAP_ASCS_REASON_NONE) {
820 LOG_DBG("qos is invalid");
821 return -EINVAL;
822 }
823
824 CHECKIF(qos->rtn > BT_ISO_BROADCAST_RTN_MAX) {
825 LOG_DBG("qos->rtn %u invalid", qos->rtn);
826 return -EINVAL;
827 }
828
829 broadcast_state = broadcast_source_get_state(source);
830 if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_QOS_CONFIGURED) {
831 LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
832 return -EBADMSG;
833 }
834
835 SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
836 SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
837 struct bt_iso_chan_io_qos *iso_qos;
838
839 iso_qos = stream->ep->iso->chan.qos->tx;
840
841 bt_bap_stream_attach(NULL, stream, stream->ep, codec);
842
843 bt_audio_codec_qos_to_iso_qos(iso_qos, qos);
844 bt_audio_codec_to_iso_path(iso_qos->path, codec);
845 stream->qos = qos;
846 }
847 }
848
849 source->qos = qos;
850
851 return 0;
852 }
853
broadcast_source_store_metadata(struct bt_codec * codec,const struct bt_codec_data meta[],size_t meta_count)854 static void broadcast_source_store_metadata(struct bt_codec *codec,
855 const struct bt_codec_data meta[],
856 size_t meta_count)
857 {
858 size_t old_meta_count;
859
860 old_meta_count = codec->meta_count;
861
862 /* Update metadata */
863 codec->meta_count = meta_count;
864 (void)memcpy(codec->meta, meta, meta_count * sizeof(*meta));
865 if (old_meta_count > meta_count) {
866 size_t meta_count_diff = old_meta_count - meta_count;
867
868 /* If we previously had more metadata entries we reset the
869 * data that was not overwritten by the new metadata
870 */
871 (void)memset(&codec->meta[meta_count],
872 0, meta_count_diff * sizeof(*meta));
873 }
874 }
875
bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source * source,const struct bt_codec_data meta[],size_t meta_count)876 int bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source *source,
877 const struct bt_codec_data meta[], size_t meta_count)
878 {
879 struct bt_bap_broadcast_subgroup *subgroup;
880 enum bt_bap_ep_state broadcast_state;
881
882 CHECKIF(source == NULL) {
883 LOG_DBG("source is NULL");
884
885 return -EINVAL;
886 }
887
888 CHECKIF((meta == NULL && meta_count != 0) ||
889 (meta != NULL && meta_count == 0)) {
890 LOG_DBG("Invalid metadata combination: %p %zu",
891 meta, meta_count);
892
893 return -EINVAL;
894 }
895
896 CHECKIF(meta_count > CONFIG_BT_CODEC_MAX_METADATA_COUNT) {
897 LOG_DBG("Invalid meta_count: %zu (max %d)",
898 meta_count, CONFIG_BT_CODEC_MAX_METADATA_COUNT);
899
900 return -EINVAL;
901 }
902
903 for (size_t i = 0; i < meta_count; i++) {
904 CHECKIF(meta[i].data.data_len > sizeof(meta[i].value)) {
905 LOG_DBG("Invalid meta[%zu] data_len %u",
906 i, meta[i].data.data_len);
907
908 return -EINVAL;
909 }
910 }
911 broadcast_state = broadcast_source_get_state(source);
912 if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_STREAMING) {
913 LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
914
915 return -EBADMSG;
916 }
917
918 /* TODO: We should probably find a way to update the metadata
919 * for each subgroup individually
920 */
921 SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
922 broadcast_source_store_metadata(subgroup->codec, meta, meta_count);
923 }
924
925 return 0;
926 }
927
bt_bap_broadcast_source_start(struct bt_bap_broadcast_source * source,struct bt_le_ext_adv * adv)928 int bt_bap_broadcast_source_start(struct bt_bap_broadcast_source *source, struct bt_le_ext_adv *adv)
929 {
930 struct bt_iso_chan *bis[BROADCAST_STREAM_CNT];
931 struct bt_iso_big_create_param param = { 0 };
932 struct bt_bap_broadcast_subgroup *subgroup;
933 enum bt_bap_ep_state broadcast_state;
934 struct bt_bap_stream *stream;
935 size_t bis_count;
936 int err;
937
938 CHECKIF(source == NULL) {
939 LOG_DBG("source is NULL");
940 return -EINVAL;
941 }
942
943 CHECKIF(adv == NULL) {
944 LOG_DBG("adv is NULL");
945 return -EINVAL;
946 }
947
948 broadcast_state = broadcast_source_get_state(source);
949 if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_QOS_CONFIGURED) {
950 LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
951 return -EBADMSG;
952 }
953
954 bis_count = 0;
955 SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
956 SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
957 bis[bis_count++] = bt_bap_stream_iso_chan_get(stream);
958 }
959 }
960
961 /* Create BIG */
962 param.num_bis = bis_count;
963 param.bis_channels = bis;
964 param.framing = source->qos->framing;
965 param.packing = source->packing;
966 param.interval = source->qos->interval;
967 param.latency = source->qos->latency;
968 param.encryption = source->encryption;
969 if (param.encryption) {
970 (void)memcpy(param.bcode, source->broadcast_code,
971 sizeof(param.bcode));
972 }
973
974 err = bt_iso_big_create(adv, ¶m, &source->big);
975 if (err != 0) {
976 LOG_DBG("Failed to create BIG: %d", err);
977 return err;
978 }
979
980 broadcast_source_set_state(source, BT_BAP_EP_STATE_ENABLING);
981
982 return 0;
983 }
984
bt_bap_broadcast_source_stop(struct bt_bap_broadcast_source * source)985 int bt_bap_broadcast_source_stop(struct bt_bap_broadcast_source *source)
986 {
987 enum bt_bap_ep_state broadcast_state;
988 int err;
989
990 CHECKIF(source == NULL) {
991 LOG_DBG("source is NULL");
992 return -EINVAL;
993 }
994
995 broadcast_state = broadcast_source_get_state(source);
996 if (broadcast_state != BT_BAP_EP_STATE_STREAMING &&
997 broadcast_state != BT_BAP_EP_STATE_ENABLING) {
998 LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
999 return -EBADMSG;
1000 }
1001
1002 if (source->big == NULL) {
1003 LOG_DBG("Source is not started");
1004 return -EALREADY;
1005 }
1006
1007 err = bt_iso_big_terminate(source->big);
1008 if (err) {
1009 LOG_DBG("Failed to terminate BIG (err %d)", err);
1010 return err;
1011 }
1012
1013 source->big = NULL;
1014
1015 return 0;
1016 }
1017
bt_bap_broadcast_source_delete(struct bt_bap_broadcast_source * source)1018 int bt_bap_broadcast_source_delete(struct bt_bap_broadcast_source *source)
1019 {
1020 enum bt_bap_ep_state broadcast_state;
1021
1022 CHECKIF(source == NULL) {
1023 LOG_DBG("source is NULL");
1024 return -EINVAL;
1025 }
1026
1027 broadcast_state = broadcast_source_get_state(source);
1028 if (broadcast_state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
1029 LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
1030 return -EBADMSG;
1031 }
1032
1033 broadcast_source_set_state(source, BT_BAP_EP_STATE_IDLE);
1034
1035 /* Reset the broadcast source */
1036 broadcast_source_cleanup(source);
1037
1038 return 0;
1039 }
1040
bt_bap_broadcast_source_get_id(const struct bt_bap_broadcast_source * source,uint32_t * const broadcast_id)1041 int bt_bap_broadcast_source_get_id(const struct bt_bap_broadcast_source *source,
1042 uint32_t *const broadcast_id)
1043 {
1044 CHECKIF(source == NULL) {
1045 LOG_DBG("source is NULL");
1046 return -EINVAL;
1047 }
1048
1049 CHECKIF(broadcast_id == NULL) {
1050 LOG_DBG("broadcast_id is NULL");
1051 return -EINVAL;
1052 }
1053
1054 *broadcast_id = source->broadcast_id;
1055
1056 return 0;
1057 }
1058
bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source * source,struct net_buf_simple * base_buf)1059 int bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source *source,
1060 struct net_buf_simple *base_buf)
1061 {
1062 CHECKIF(source == NULL) {
1063 LOG_DBG("source is NULL");
1064 return -EINVAL;
1065 }
1066
1067 CHECKIF(base_buf == NULL) {
1068 LOG_DBG("base_buf is NULL");
1069 return -EINVAL;
1070 }
1071
1072 if (!encode_base(source, base_buf)) {
1073 LOG_DBG("base_buf %p with size %u not large enough", base_buf, base_buf->size);
1074
1075 return -EMSGSIZE;
1076 }
1077
1078 return 0;
1079 }
1080