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_audio_codec_cfg *codec_cfg;
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 started 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_audio_codec_cfg * codec_cfg,struct bt_audio_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_audio_codec_cfg *codec_cfg,
269 					 struct bt_audio_codec_qos *qos,
270 					 struct bt_bap_broadcast_source *source)
271 {
272 	struct bt_bap_iso *iso;
273 	struct bt_bap_ep *ep;
274 
275 	ep = broadcast_source_new_ep(index);
276 	if (ep == NULL) {
277 		LOG_DBG("Could not allocate new broadcast endpoint");
278 		return -ENOMEM;
279 	}
280 
281 	iso = bt_bap_iso_new();
282 	if (iso == NULL) {
283 		LOG_DBG("Could not allocate iso");
284 		return -ENOMEM;
285 	}
286 
287 	bt_bap_iso_init(iso, &broadcast_source_iso_ops);
288 	bt_bap_iso_bind_ep(iso, ep);
289 
290 	bt_audio_codec_qos_to_iso_qos(iso->chan.qos->tx, qos);
291 	bt_audio_codec_cfg_to_iso_path(iso->chan.qos->tx->path, codec_cfg);
292 
293 	bt_bap_iso_unref(iso);
294 
295 	bt_bap_stream_attach(NULL, stream, ep, codec_cfg);
296 	stream->qos = qos;
297 	ep->broadcast_source = source;
298 
299 	return 0;
300 }
301 
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)302 static bool encode_base_subgroup(struct bt_bap_broadcast_subgroup *subgroup,
303 				 struct bt_audio_broadcast_stream_data *stream_data,
304 				 uint8_t *streams_encoded, struct net_buf_simple *buf)
305 {
306 	struct bt_bap_stream *stream;
307 	const struct bt_audio_codec_cfg *codec_cfg;
308 	uint8_t stream_count;
309 	uint8_t len;
310 
311 	stream_count = 0;
312 	SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
313 		stream_count++;
314 	}
315 
316 	codec_cfg = subgroup->codec_cfg;
317 
318 	net_buf_simple_add_u8(buf, stream_count);
319 	net_buf_simple_add_u8(buf, codec_cfg->id);
320 	net_buf_simple_add_le16(buf, codec_cfg->cid);
321 	net_buf_simple_add_le16(buf, codec_cfg->vid);
322 
323 	net_buf_simple_add_u8(buf, codec_cfg->data_len);
324 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
325 	if ((buf->size - buf->len) < codec_cfg->data_len) {
326 		LOG_DBG("No room for config data: %zu", codec_cfg->data_len);
327 
328 		return false;
329 	}
330 	net_buf_simple_add_mem(buf, codec_cfg->data, codec_cfg->data_len);
331 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
332 
333 	if ((buf->size - buf->len) < sizeof(len)) {
334 		LOG_DBG("No room for metadata length");
335 
336 		return false;
337 	}
338 
339 	net_buf_simple_add_u8(buf, codec_cfg->meta_len);
340 
341 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
342 	if ((buf->size - buf->len) < codec_cfg->meta_len) {
343 		LOG_DBG("No room for metadata data: %zu", codec_cfg->meta_len);
344 
345 		return false;
346 	}
347 
348 	net_buf_simple_add_mem(buf, codec_cfg->meta, codec_cfg->meta_len);
349 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
350 
351 	/* Create BIS index bitfield */
352 	for (uint8_t i = 0U; i < stream_count; i++) {
353 		/* Set the bis_index to *streams_encoded plus 1 as the indexes start from 1 */
354 		const uint8_t bis_index = *streams_encoded + 1;
355 
356 		if ((buf->size - buf->len) < (sizeof(bis_index) + sizeof(uint8_t))) {
357 			LOG_DBG("No room for BIS[%d] index", i);
358 
359 			return false;
360 		}
361 
362 		net_buf_simple_add_u8(buf, bis_index);
363 
364 		if ((buf->size - buf->len) < sizeof(len)) {
365 			LOG_DBG("No room for bis codec config length");
366 
367 			return false;
368 		}
369 
370 		net_buf_simple_add_u8(buf, stream_data[i].data_len);
371 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
372 		if ((buf->size - buf->len) < stream_data[i].data_len) {
373 			LOG_DBG("No room for BIS[%u] data: %zu", i, stream_data[i].data_len);
374 
375 			return false;
376 		}
377 
378 		net_buf_simple_add_mem(buf, stream_data[i].data, stream_data[i].data_len);
379 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
380 
381 		(*streams_encoded)++;
382 	}
383 
384 	return true;
385 }
386 
encode_base(struct bt_bap_broadcast_source * source,struct net_buf_simple * buf)387 static bool encode_base(struct bt_bap_broadcast_source *source, struct net_buf_simple *buf)
388 {
389 	struct bt_bap_broadcast_subgroup *subgroup;
390 	uint8_t streams_encoded;
391 	uint8_t subgroup_count;
392 
393 	/* 13 is the size of the fixed size values following this check */
394 	if ((buf->size - buf->len) < MINIMUM_BASE_SIZE) {
395 		return false;
396 	}
397 
398 	subgroup_count = 0U;
399 	SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
400 		subgroup_count++;
401 	}
402 
403 	net_buf_simple_add_le16(buf, BT_UUID_BASIC_AUDIO_VAL);
404 
405 	net_buf_simple_add_le24(buf, source->qos->pd);
406 	net_buf_simple_add_u8(buf, subgroup_count);
407 
408 	/* Since the `stream_data` is only stored in the broadcast source,
409 	 * we need to provide that information when encoding each subgroup
410 	 */
411 	streams_encoded = 0;
412 	SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
413 		if (!encode_base_subgroup(subgroup,
414 					  &source->stream_data[streams_encoded],
415 					  &streams_encoded, buf)) {
416 			return false;
417 		}
418 	}
419 
420 	return true;
421 }
422 
generate_broadcast_id(struct bt_bap_broadcast_source * source)423 static int generate_broadcast_id(struct bt_bap_broadcast_source *source)
424 {
425 	bool unique;
426 
427 	do {
428 		int err;
429 
430 		err = bt_rand(&source->broadcast_id,
431 			      BT_AUDIO_BROADCAST_ID_SIZE);
432 		if (err) {
433 			return err;
434 		}
435 
436 		/* Ensure uniqueness */
437 		unique = true;
438 		for (int i = 0; i < ARRAY_SIZE(broadcast_sources); i++) {
439 			if (&broadcast_sources[i] == source) {
440 				continue;
441 			}
442 
443 			if (broadcast_sources[i].broadcast_id == source->broadcast_id) {
444 				unique = false;
445 				break;
446 			}
447 		}
448 	} while (!unique);
449 
450 	return 0;
451 }
452 
broadcast_source_cleanup(struct bt_bap_broadcast_source * source)453 static void broadcast_source_cleanup(struct bt_bap_broadcast_source *source)
454 {
455 	struct bt_bap_broadcast_subgroup *subgroup, *next_subgroup;
456 
457 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&source->subgroups, subgroup,
458 					  next_subgroup, _node) {
459 		struct bt_bap_stream *stream, *next_stream;
460 
461 		SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&subgroup->streams, stream,
462 						  next_stream, _node) {
463 			bt_bap_iso_unbind_ep(stream->ep->iso, stream->ep);
464 			stream->ep->stream = NULL;
465 			stream->ep = NULL;
466 			stream->codec_cfg = NULL;
467 			stream->qos = NULL;
468 			stream->group = NULL;
469 
470 			sys_slist_remove(&subgroup->streams, NULL,
471 					 &stream->_node);
472 		}
473 		sys_slist_remove(&source->subgroups, NULL, &subgroup->_node);
474 	}
475 
476 	(void)memset(source, 0, sizeof(*source));
477 }
478 
valid_broadcast_source_param(const struct bt_bap_broadcast_source_param * param,const struct bt_bap_broadcast_source * source)479 static bool valid_broadcast_source_param(const struct bt_bap_broadcast_source_param *param,
480 					 const struct bt_bap_broadcast_source *source)
481 {
482 	const struct bt_audio_codec_qos *qos;
483 
484 	CHECKIF(param == NULL) {
485 		LOG_DBG("param is NULL");
486 		return false;
487 	}
488 
489 	CHECKIF(!IN_RANGE(param->params_count, 1U, CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT)) {
490 		LOG_DBG("param->params_count %zu is invalid", param->params_count);
491 		return false;
492 	}
493 
494 	CHECKIF(param->packing != BT_ISO_PACKING_SEQUENTIAL &&
495 		param->packing != BT_ISO_PACKING_INTERLEAVED) {
496 		LOG_DBG("param->packing %u is invalid", param->packing);
497 		return false;
498 	}
499 
500 	qos = param->qos;
501 	CHECKIF(qos == NULL) {
502 		LOG_DBG("param->qos is NULL");
503 		return false;
504 	}
505 
506 	CHECKIF(bt_audio_verify_qos(qos) != BT_BAP_ASCS_REASON_NONE) {
507 		LOG_DBG("param->qos is invalid");
508 		return false;
509 	}
510 
511 	CHECKIF(param->qos->rtn > BT_ISO_BROADCAST_RTN_MAX) {
512 		LOG_DBG("param->qos->rtn %u invalid", param->qos->rtn);
513 		return false;
514 	}
515 
516 	CHECKIF(param->params == NULL) {
517 		LOG_DBG("param->params is NULL");
518 		return false;
519 	}
520 
521 	CHECKIF(param->params_count == 0) {
522 		LOG_DBG("param->params_count is 0");
523 		return false;
524 	}
525 
526 	for (size_t i = 0U; i < param->params_count; i++) {
527 		const struct bt_bap_broadcast_source_subgroup_param *subgroup_param;
528 
529 		subgroup_param = &param->params[i];
530 
531 		CHECKIF(subgroup_param->params == NULL) {
532 			LOG_DBG("subgroup_params[%zu].params is NULL", i);
533 			return false;
534 		}
535 
536 		CHECKIF(!IN_RANGE(subgroup_param->params_count, 1U,
537 				  CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT)) {
538 			LOG_DBG("subgroup_params[%zu].count (%zu) is invalid", i,
539 				subgroup_param->params_count);
540 			return false;
541 		}
542 
543 		CHECKIF(!bt_audio_valid_codec_cfg(subgroup_param->codec_cfg)) {
544 			LOG_DBG("subgroup_params[%zu].codec_cfg  is invalid", i);
545 			return false;
546 		}
547 
548 		for (size_t j = 0U; j < subgroup_param->params_count; j++) {
549 			const struct bt_bap_broadcast_source_stream_param *stream_param;
550 
551 			stream_param = &subgroup_param->params[j];
552 
553 			CHECKIF(stream_param->stream == NULL) {
554 				LOG_DBG("subgroup_params[%zu].stream_params[%zu]->stream is NULL",
555 					i, j);
556 				return false;
557 			}
558 
559 			CHECKIF(stream_param->stream->group != NULL &&
560 				stream_param->stream->group != source) {
561 				LOG_DBG("subgroup_params[%zu].stream_params[%zu]->stream is "
562 					"already part of group %p",
563 					i, j, stream_param->stream->group);
564 				return false;
565 			}
566 
567 			CHECKIF(stream_param->data == NULL && stream_param->data_len != 0) {
568 				LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data is "
569 					"NULL with len %zu",
570 					i, j, stream_param->data_len);
571 				return false;
572 			}
573 
574 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
575 			CHECKIF(stream_param->data_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE) {
576 				LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data_len too "
577 					"large: %zu > %d",
578 					i, j, stream_param->data_len,
579 					CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE);
580 				return false;
581 			}
582 		}
583 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
584 	}
585 
586 	return true;
587 }
588 
broadcast_source_get_state(struct bt_bap_broadcast_source * source)589 static enum bt_bap_ep_state broadcast_source_get_state(struct bt_bap_broadcast_source *source)
590 {
591 	struct bt_bap_broadcast_subgroup *subgroup;
592 	struct bt_bap_stream *stream;
593 	sys_snode_t *head_node;
594 
595 	if (source == NULL) {
596 		LOG_DBG("source is NULL");
597 		return BT_BAP_EP_STATE_IDLE;
598 	}
599 
600 	if (sys_slist_is_empty(&source->subgroups)) {
601 		LOG_DBG("Source does not have any streams");
602 		return BT_BAP_EP_STATE_IDLE;
603 	}
604 
605 	/* Get the first stream */
606 	head_node = sys_slist_peek_head(&source->subgroups);
607 	subgroup = CONTAINER_OF(head_node, struct bt_bap_broadcast_subgroup, _node);
608 
609 	head_node = sys_slist_peek_head(&subgroup->streams);
610 	stream = CONTAINER_OF(head_node, struct bt_bap_stream, _node);
611 
612 	/* All streams in a broadcast source is in the same state,
613 	 * so we can just check the first stream
614 	 */
615 	if (stream->ep == NULL) {
616 		LOG_DBG("stream->ep is NULL");
617 		return BT_BAP_EP_STATE_IDLE;
618 	}
619 
620 	return stream->ep->status.state;
621 }
622 
bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_param * param,struct bt_bap_broadcast_source ** out_source)623 int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_param *param,
624 				   struct bt_bap_broadcast_source **out_source)
625 {
626 	struct bt_bap_broadcast_source *source;
627 	struct bt_audio_codec_qos *qos;
628 	size_t stream_count;
629 	uint8_t index;
630 	int err;
631 
632 	CHECKIF(out_source == NULL) {
633 		LOG_DBG("out_source is NULL");
634 		return -EINVAL;
635 	}
636 
637 	/* Set out_source to NULL until the source has actually been created */
638 	*out_source = NULL;
639 
640 	if (!valid_broadcast_source_param(param, NULL)) {
641 		LOG_DBG("Invalid parameters");
642 		return -EINVAL;
643 	}
644 
645 	source = NULL;
646 	for (index = 0; index < ARRAY_SIZE(broadcast_sources); index++) {
647 		if (sys_slist_is_empty(&broadcast_sources[index].subgroups)) { /* Find free entry */
648 			source = &broadcast_sources[index];
649 			break;
650 		}
651 	}
652 
653 	if (source == NULL) {
654 		LOG_DBG("Could not allocate any more broadcast sources");
655 		return -ENOMEM;
656 	}
657 
658 	stream_count = 0U;
659 
660 	qos = param->qos;
661 	/* Go through all subgroups and streams and setup each setup with an
662 	 * endpoint
663 	 */
664 	for (size_t i = 0U; i < param->params_count; i++) {
665 		const struct bt_bap_broadcast_source_subgroup_param *subgroup_param;
666 		struct bt_bap_broadcast_subgroup *subgroup;
667 
668 		subgroup_param = &param->params[i];
669 
670 		subgroup = broadcast_source_new_subgroup(index);
671 		if (subgroup == NULL) {
672 			LOG_DBG("Could not allocate new broadcast subgroup");
673 			broadcast_source_cleanup(source);
674 			return -ENOMEM;
675 		}
676 
677 		subgroup->codec_cfg = subgroup_param->codec_cfg;
678 		sys_slist_append(&source->subgroups, &subgroup->_node);
679 
680 		/* Check that we are not above the maximum BIS count */
681 		if (subgroup_param->params_count + stream_count > BROADCAST_STREAM_CNT) {
682 			LOG_DBG("Cannot create broadcaster with %zu streams", stream_count);
683 			broadcast_source_cleanup(source);
684 
685 			return -ENOMEM;
686 		}
687 
688 		for (size_t j = 0U; j < subgroup_param->params_count; j++) {
689 			const struct bt_bap_broadcast_source_stream_param *stream_param;
690 			struct bt_bap_stream *stream;
691 
692 			stream_param = &subgroup_param->params[j];
693 			stream = stream_param->stream;
694 
695 			err = broadcast_source_setup_stream(index, stream,
696 							    subgroup_param->codec_cfg, qos, source);
697 			if (err != 0) {
698 				LOG_DBG("Failed to setup streams[%zu]: %d", i, err);
699 				broadcast_source_cleanup(source);
700 				return err;
701 			}
702 
703 			/* Store the BIS specific codec configuration data in
704 			 * the broadcast source. It is stored in the broadcast
705 			 * source, instead of the stream object, as this is
706 			 * only relevant for the broadcast source, and not used
707 			 * for unicast or broadcast sink.
708 			 */
709 			(void)memcpy(source->stream_data[stream_count].data, stream_param->data,
710 				     stream_param->data_len * sizeof(*stream_param->data));
711 			source->stream_data[stream_count].data_len = stream_param->data_len;
712 
713 			sys_slist_append(&subgroup->streams, &stream->_node);
714 			stream_count++;
715 		}
716 	}
717 
718 	err = generate_broadcast_id(source);
719 	if (err != 0) {
720 		LOG_DBG("Could not generate broadcast id: %d", err);
721 		return err;
722 	}
723 
724 	/* Finalize state changes and store information */
725 	broadcast_source_set_state(source, BT_BAP_EP_STATE_QOS_CONFIGURED);
726 	source->qos = qos;
727 	source->packing = param->packing;
728 
729 	source->encryption = param->encryption;
730 	if (source->encryption) {
731 		(void)memcpy(source->broadcast_code, param->broadcast_code,
732 			     sizeof(source->broadcast_code));
733 	}
734 
735 	LOG_DBG("Broadcasting with ID 0x%6X", source->broadcast_id);
736 
737 	*out_source = source;
738 
739 	return 0;
740 }
741 
bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source * source,struct bt_bap_broadcast_source_param * param)742 int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source,
743 				     struct bt_bap_broadcast_source_param *param)
744 {
745 	struct bt_bap_broadcast_subgroup *subgroup;
746 	enum bt_bap_ep_state broadcast_state;
747 	struct bt_audio_codec_qos *qos;
748 	size_t subgroup_cnt;
749 
750 	CHECKIF(source == NULL) {
751 		LOG_DBG("source is NULL");
752 		return -EINVAL;
753 	}
754 
755 	if (!valid_broadcast_source_param(param, source)) {
756 		LOG_DBG("Invalid parameters");
757 		return -EINVAL;
758 	}
759 
760 	broadcast_state = broadcast_source_get_state(source);
761 	if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_QOS_CONFIGURED) {
762 		LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
763 		return -EBADMSG;
764 	}
765 
766 	/* Verify that the parameter counts do not exceed existing number of subgroups and streams*/
767 	subgroup_cnt = 0U;
768 	SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
769 		const struct bt_bap_broadcast_source_subgroup_param *subgroup_param =
770 			&param->params[subgroup_cnt];
771 		const size_t subgroup_stream_param_cnt = subgroup_param->params_count;
772 		struct bt_bap_stream *stream;
773 		size_t subgroup_stream_cnt = 0U;
774 
775 		SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
776 			subgroup_stream_cnt++;
777 		}
778 
779 		/* Verify that the param stream is in the subgroup */
780 		for (size_t i = 0U; i < subgroup_param->params_count; i++) {
781 			struct bt_bap_stream *subgroup_stream;
782 			struct bt_bap_stream *param_stream;
783 			bool stream_in_subgroup;
784 
785 			param_stream = subgroup_param->params[i].stream;
786 
787 			SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, subgroup_stream, _node) {
788 				if (subgroup_stream == param_stream) {
789 					stream_in_subgroup = true;
790 					break;
791 				}
792 			}
793 
794 			if (!stream_in_subgroup) {
795 				LOG_DBG("Invalid param->params[%zu]->param[%zu].stream "
796 					"not in subgroup",
797 					subgroup_cnt, i);
798 				return -EINVAL;
799 			}
800 		}
801 
802 		if (subgroup_stream_cnt < subgroup_stream_param_cnt) {
803 			LOG_DBG("Invalid param->params[%zu]->params_count: %zu "
804 				"(only %zu streams in subgroup)",
805 				subgroup_cnt, subgroup_stream_param_cnt, subgroup_stream_cnt);
806 			return -EINVAL;
807 		}
808 
809 		subgroup_cnt++;
810 	}
811 
812 	if (subgroup_cnt < param->params_count) {
813 		LOG_DBG("Invalid param->params_count: %zu (only %zu subgroups in source)",
814 			param->params_count, subgroup_cnt);
815 		return -EINVAL;
816 	}
817 
818 	qos = param->qos;
819 
820 	/* We update up to the first param->params_count subgroups */
821 	for (size_t i = 0U; i < param->params_count; i++) {
822 		const struct bt_bap_broadcast_source_subgroup_param *subgroup_param;
823 		struct bt_audio_codec_cfg *codec_cfg;
824 		struct bt_bap_stream *stream;
825 
826 		if (i == 0) {
827 			subgroup =
828 				SYS_SLIST_PEEK_HEAD_CONTAINER(&source->subgroups, subgroup, _node);
829 		} else {
830 			subgroup = SYS_SLIST_PEEK_NEXT_CONTAINER(subgroup, _node);
831 		}
832 
833 		subgroup_param = &param->params[i];
834 		codec_cfg = subgroup_param->codec_cfg;
835 		subgroup->codec_cfg = codec_cfg;
836 
837 		for (size_t j = 0U; j < subgroup_param->params_count; j++) {
838 			const struct bt_bap_broadcast_source_stream_param *stream_param;
839 			struct bt_audio_broadcast_stream_data *stream_data;
840 			struct bt_bap_stream *subgroup_stream;
841 			size_t stream_idx;
842 
843 			stream_param = &subgroup_param->params[j];
844 			stream = stream_param->stream;
845 
846 			stream_idx = 0U;
847 			SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, subgroup_stream, _node) {
848 				if (subgroup_stream == stream) {
849 					break;
850 				}
851 
852 				stream_idx++;
853 			}
854 
855 			/* Store the BIS specific codec configuration data in the broadcast source.
856 			 * It is stored in the broadcast* source, instead of the stream object,
857 			 * as this is only relevant for the broadcast source, and not used
858 			 * for unicast or broadcast sink.
859 			 */
860 			stream_data = &source->stream_data[stream_idx];
861 			(void)memcpy(stream_data->data, stream_param->data, stream_param->data_len);
862 			stream_data->data_len = stream_param->data_len;
863 		}
864 
865 		/* Apply the codec_cfg to all streams in the subgroup, and not just the ones in the
866 		 * params
867 		 */
868 		SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
869 			struct bt_iso_chan_io_qos *iso_qos;
870 
871 			iso_qos = stream->ep->iso->chan.qos->tx;
872 			bt_bap_stream_attach(NULL, stream, stream->ep, codec_cfg);
873 			bt_audio_codec_cfg_to_iso_path(iso_qos->path, codec_cfg);
874 		}
875 	}
876 
877 	/* Finally we apply the new qos and to all streams */
878 	SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
879 		struct bt_bap_stream *stream;
880 
881 		SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
882 			struct bt_iso_chan_io_qos *iso_qos;
883 
884 			iso_qos = stream->ep->iso->chan.qos->tx;
885 			bt_audio_codec_qos_to_iso_qos(iso_qos, qos);
886 			stream->qos = qos;
887 		}
888 	}
889 
890 	source->qos = qos;
891 
892 	return 0;
893 }
894 
bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source * source,const uint8_t meta[],size_t meta_len)895 int bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source *source,
896 					    const uint8_t meta[], size_t meta_len)
897 {
898 	struct bt_bap_broadcast_subgroup *subgroup;
899 	enum bt_bap_ep_state broadcast_state;
900 
901 	CHECKIF(source == NULL) {
902 		LOG_DBG("source is NULL");
903 
904 		return -EINVAL;
905 	}
906 
907 	CHECKIF((meta == NULL && meta_len != 0) || (meta != NULL && meta_len == 0)) {
908 		LOG_DBG("Invalid metadata combination: %p %zu", meta, meta_len);
909 
910 		return -EINVAL;
911 	}
912 
913 	CHECKIF(meta_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
914 		LOG_DBG("Invalid meta_len: %zu (max %d)", meta_len,
915 			CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
916 
917 		return -EINVAL;
918 	}
919 
920 	broadcast_state = broadcast_source_get_state(source);
921 	if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_STREAMING) {
922 		LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
923 
924 		return -EBADMSG;
925 	}
926 
927 	/* TODO: We should probably find a way to update the metadata
928 	 * for each subgroup individually
929 	 */
930 	SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
931 		memset(subgroup->codec_cfg->meta, 0, sizeof(subgroup->codec_cfg->meta));
932 		memcpy(subgroup->codec_cfg->meta, meta, meta_len);
933 	}
934 
935 	return 0;
936 }
937 
bt_bap_broadcast_source_start(struct bt_bap_broadcast_source * source,struct bt_le_ext_adv * adv)938 int bt_bap_broadcast_source_start(struct bt_bap_broadcast_source *source, struct bt_le_ext_adv *adv)
939 {
940 	struct bt_iso_chan *bis[BROADCAST_STREAM_CNT];
941 	struct bt_iso_big_create_param param = { 0 };
942 	struct bt_bap_broadcast_subgroup *subgroup;
943 	enum bt_bap_ep_state broadcast_state;
944 	struct bt_bap_stream *stream;
945 	size_t bis_count;
946 	int err;
947 
948 	CHECKIF(source == NULL) {
949 		LOG_DBG("source is NULL");
950 		return -EINVAL;
951 	}
952 
953 	CHECKIF(adv == NULL) {
954 		LOG_DBG("adv is NULL");
955 		return -EINVAL;
956 	}
957 
958 	broadcast_state = broadcast_source_get_state(source);
959 	if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_QOS_CONFIGURED) {
960 		LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
961 		return -EBADMSG;
962 	}
963 
964 	bis_count = 0;
965 	SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) {
966 		SYS_SLIST_FOR_EACH_CONTAINER(&subgroup->streams, stream, _node) {
967 			bis[bis_count++] = bt_bap_stream_iso_chan_get(stream);
968 		}
969 	}
970 
971 	/* Create BIG */
972 	param.num_bis = bis_count;
973 	param.bis_channels = bis;
974 	param.framing = source->qos->framing;
975 	param.packing = source->packing;
976 	param.interval = source->qos->interval;
977 	param.latency = source->qos->latency;
978 	param.encryption = source->encryption;
979 	if (param.encryption) {
980 		(void)memcpy(param.bcode, source->broadcast_code,
981 			     sizeof(param.bcode));
982 	}
983 
984 	/* Set the enabling state early in case that the BIS is connected before we can manage to
985 	 * set it afterwards
986 	 */
987 	broadcast_source_set_state(source, BT_BAP_EP_STATE_ENABLING);
988 
989 	err = bt_iso_big_create(adv, &param, &source->big);
990 	if (err != 0) {
991 		LOG_DBG("Failed to create BIG: %d", err);
992 		broadcast_source_set_state(source, BT_BAP_EP_STATE_QOS_CONFIGURED);
993 
994 		return err;
995 	}
996 
997 	return 0;
998 }
999 
bt_bap_broadcast_source_stop(struct bt_bap_broadcast_source * source)1000 int bt_bap_broadcast_source_stop(struct bt_bap_broadcast_source *source)
1001 {
1002 	enum bt_bap_ep_state broadcast_state;
1003 	int err;
1004 
1005 	CHECKIF(source == NULL) {
1006 		LOG_DBG("source is NULL");
1007 		return -EINVAL;
1008 	}
1009 
1010 	broadcast_state = broadcast_source_get_state(source);
1011 	if (broadcast_state != BT_BAP_EP_STATE_STREAMING &&
1012 	    broadcast_state != BT_BAP_EP_STATE_ENABLING) {
1013 		LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
1014 		return -EBADMSG;
1015 	}
1016 
1017 	if (source->big == NULL) {
1018 		LOG_DBG("Source is not started");
1019 		return -EALREADY;
1020 	}
1021 
1022 	err =  bt_iso_big_terminate(source->big);
1023 	if (err) {
1024 		LOG_DBG("Failed to terminate BIG (err %d)", err);
1025 		return err;
1026 	}
1027 
1028 	source->big = NULL;
1029 
1030 	return 0;
1031 }
1032 
bt_bap_broadcast_source_delete(struct bt_bap_broadcast_source * source)1033 int bt_bap_broadcast_source_delete(struct bt_bap_broadcast_source *source)
1034 {
1035 	enum bt_bap_ep_state broadcast_state;
1036 
1037 	CHECKIF(source == NULL) {
1038 		LOG_DBG("source is NULL");
1039 		return -EINVAL;
1040 	}
1041 
1042 	broadcast_state = broadcast_source_get_state(source);
1043 	if (broadcast_state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
1044 		LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
1045 		return -EBADMSG;
1046 	}
1047 
1048 	broadcast_source_set_state(source, BT_BAP_EP_STATE_IDLE);
1049 
1050 	/* Reset the broadcast source */
1051 	broadcast_source_cleanup(source);
1052 
1053 	return 0;
1054 }
1055 
bt_bap_broadcast_source_get_id(struct bt_bap_broadcast_source * source,uint32_t * const broadcast_id)1056 int bt_bap_broadcast_source_get_id(struct bt_bap_broadcast_source *source,
1057 				   uint32_t *const broadcast_id)
1058 {
1059 	enum bt_bap_ep_state broadcast_state;
1060 
1061 	CHECKIF(source == NULL) {
1062 		LOG_DBG("source is NULL");
1063 		return -EINVAL;
1064 	}
1065 
1066 	CHECKIF(broadcast_id == NULL) {
1067 		LOG_DBG("broadcast_id is NULL");
1068 		return -EINVAL;
1069 	}
1070 
1071 	broadcast_state = broadcast_source_get_state(source);
1072 	if (broadcast_state == BT_BAP_EP_STATE_IDLE) {
1073 		LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
1074 		return -EBADMSG;
1075 	}
1076 
1077 	*broadcast_id = source->broadcast_id;
1078 
1079 	return 0;
1080 }
1081 
bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source * source,struct net_buf_simple * base_buf)1082 int bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source *source,
1083 				     struct net_buf_simple *base_buf)
1084 {
1085 	enum bt_bap_ep_state broadcast_state;
1086 
1087 	CHECKIF(source == NULL) {
1088 		LOG_DBG("source is NULL");
1089 		return -EINVAL;
1090 	}
1091 
1092 	CHECKIF(base_buf == NULL) {
1093 		LOG_DBG("base_buf is NULL");
1094 		return -EINVAL;
1095 	}
1096 
1097 	broadcast_state = broadcast_source_get_state(source);
1098 	if (broadcast_state == BT_BAP_EP_STATE_IDLE) {
1099 		LOG_DBG("Broadcast source invalid state: %u", broadcast_state);
1100 		return -EBADMSG;
1101 	}
1102 
1103 	if (!encode_base(source, base_buf)) {
1104 		LOG_DBG("base_buf %p with size %u not large enough", base_buf, base_buf->size);
1105 
1106 		return -EMSGSIZE;
1107 	}
1108 
1109 	return 0;
1110 }
1111