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 = &param->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 = &param->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, &param, &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