1 /*
2  * Copyright (c) 2022-2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <string.h>
12 
13 #include <zephyr/autoconf.h>
14 #include <zephyr/bluetooth/audio/audio.h>
15 #include <zephyr/bluetooth/audio/bap.h>
16 #include <zephyr/bluetooth/audio/cap.h>
17 #include <zephyr/bluetooth/audio/ccid.h>
18 #include <zephyr/bluetooth/audio/csip.h>
19 #include <zephyr/bluetooth/audio/tbs.h>
20 #include <zephyr/bluetooth/bluetooth.h>
21 #include <zephyr/bluetooth/conn.h>
22 #include <zephyr/bluetooth/gatt.h>
23 #include <zephyr/bluetooth/iso.h>
24 #include <zephyr/logging/log.h>
25 #include <zephyr/net_buf.h>
26 #include <zephyr/sys/__assert.h>
27 #include <zephyr/sys/check.h>
28 #include <zephyr/sys/util.h>
29 #include <zephyr/sys/util_macro.h>
30 #include <sys/errno.h>
31 
32 #include "bap_endpoint.h"
33 #include "cap_internal.h"
34 #include "csip_internal.h"
35 
36 LOG_MODULE_REGISTER(bt_cap_initiator, CONFIG_BT_CAP_INITIATOR_LOG_LEVEL);
37 
38 #include "common/bt_str.h"
39 
40 static const struct bt_cap_initiator_cb *cap_cb;
41 
bt_cap_initiator_register_cb(const struct bt_cap_initiator_cb * cb)42 int bt_cap_initiator_register_cb(const struct bt_cap_initiator_cb *cb)
43 {
44 	CHECKIF(cb == NULL) {
45 		LOG_DBG("cb is NULL");
46 		return -EINVAL;
47 	}
48 
49 	CHECKIF(cap_cb != NULL) {
50 		LOG_DBG("callbacks already registered");
51 		return -EALREADY;
52 	}
53 
54 	cap_cb = cb;
55 
56 	return 0;
57 }
58 
bt_cap_initiator_unregister_cb(const struct bt_cap_initiator_cb * cb)59 int bt_cap_initiator_unregister_cb(const struct bt_cap_initiator_cb *cb)
60 {
61 	CHECKIF(cb == NULL) {
62 		LOG_DBG("cb is NULL");
63 		return -EINVAL;
64 	}
65 
66 	CHECKIF(cap_cb != cb) {
67 		LOG_DBG("cb is not registered");
68 		return -EINVAL;
69 	}
70 
71 	cap_cb = NULL;
72 
73 	return 0;
74 }
75 
76 struct valid_metadata_param {
77 	bool stream_context_found;
78 	bool valid;
79 };
80 
data_func_cb(struct bt_data * data,void * user_data)81 static bool data_func_cb(struct bt_data *data, void *user_data)
82 {
83 	struct valid_metadata_param *metadata_param = (struct valid_metadata_param *)user_data;
84 
85 	LOG_DBG("type %u len %u data %s", data->type, data->data_len,
86 		bt_hex(data->data, data->data_len));
87 
88 	if (data->type == BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT) {
89 		if (data->data_len != 2) { /* Stream context size */
90 			return false;
91 		}
92 
93 		metadata_param->stream_context_found = true;
94 	} else if (IS_ENABLED(CONFIG_BT_CONN) && data->type == BT_AUDIO_METADATA_TYPE_CCID_LIST) {
95 		/* If the application supplies a CCID list, we verify that the CCIDs exist on our
96 		 * device
97 		 * This is guarded by CONFIG_BT_CONN as without that we do not have a GATT DB to
98 		 * check.
99 		 */
100 		for (uint8_t i = 0U; i < data->data_len; i++) {
101 			const uint8_t ccid = data->data[i];
102 			if (bt_ccid_find_attr(ccid) == NULL) {
103 				LOG_DBG("Unknown characteristic for CCID 0x%02X", ccid);
104 				metadata_param->valid = false;
105 
106 				return false;
107 			}
108 		}
109 	}
110 
111 	return true;
112 }
113 
cap_initiator_valid_metadata(const uint8_t meta[],size_t meta_len)114 static bool cap_initiator_valid_metadata(const uint8_t meta[], size_t meta_len)
115 {
116 	struct valid_metadata_param metadata_param = {
117 		.stream_context_found = false,
118 		.valid = true,
119 	};
120 	int err;
121 
122 	LOG_DBG("meta %p len %zu", (void *)meta, meta_len);
123 
124 	err = bt_audio_data_parse(meta, meta_len, data_func_cb, &metadata_param);
125 	if (err != 0 && err != -ECANCELED) {
126 		return false;
127 	}
128 
129 	if (!metadata_param.stream_context_found) {
130 		LOG_DBG("No streaming context supplied");
131 	}
132 
133 	return metadata_param.stream_context_found && metadata_param.valid;
134 }
135 
136 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
137 static struct bt_cap_broadcast_source {
138 	struct bt_bap_broadcast_source *bap_broadcast;
139 } broadcast_sources[CONFIG_BT_BAP_BROADCAST_SRC_COUNT];
140 
cap_initiator_broadcast_audio_start_valid_param(const struct bt_cap_initiator_broadcast_create_param * param)141 static bool cap_initiator_broadcast_audio_start_valid_param(
142 	const struct bt_cap_initiator_broadcast_create_param *param)
143 {
144 
145 	for (size_t i = 0U; i < param->subgroup_count; i++) {
146 		const struct bt_cap_initiator_broadcast_subgroup_param *subgroup_param;
147 		const struct bt_audio_codec_cfg *codec_cfg;
148 		bool valid_metadata;
149 
150 		subgroup_param = &param->subgroup_params[i];
151 		codec_cfg = subgroup_param->codec_cfg;
152 
153 		/* Streaming Audio Context shall be present in CAP */
154 
155 		CHECKIF(codec_cfg == NULL) {
156 			LOG_DBG("subgroup[%zu]->codec_cfg is NULL", i);
157 			return false;
158 		}
159 
160 		valid_metadata =
161 			cap_initiator_valid_metadata(codec_cfg->meta, codec_cfg->meta_len);
162 
163 		CHECKIF(!valid_metadata) {
164 			LOG_DBG("Invalid metadata supplied for subgroup[%zu]", i);
165 			return false;
166 		}
167 	}
168 
169 	return true;
170 }
171 
cap_initiator_broadcast_to_bap_broadcast_param(const struct bt_cap_initiator_broadcast_create_param * cap_param,struct bt_bap_broadcast_source_param * bap_param,struct bt_bap_broadcast_source_subgroup_param bap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT],struct bt_bap_broadcast_source_stream_param bap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT])172 static void cap_initiator_broadcast_to_bap_broadcast_param(
173 	const struct bt_cap_initiator_broadcast_create_param *cap_param,
174 	struct bt_bap_broadcast_source_param *bap_param,
175 	struct bt_bap_broadcast_source_subgroup_param
176 		bap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT],
177 	struct bt_bap_broadcast_source_stream_param
178 		bap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT])
179 {
180 	size_t stream_cnt = 0U;
181 
182 	bap_param->params_count = cap_param->subgroup_count;
183 	bap_param->params = bap_subgroup_params;
184 	bap_param->qos = cap_param->qos;
185 	bap_param->packing = cap_param->packing;
186 	bap_param->encryption = cap_param->encryption;
187 	if (bap_param->encryption) {
188 		memcpy(bap_param->broadcast_code, cap_param->broadcast_code,
189 		       BT_ISO_BROADCAST_CODE_SIZE);
190 	} else {
191 		memset(bap_param->broadcast_code, 0, BT_ISO_BROADCAST_CODE_SIZE);
192 	}
193 
194 	for (size_t i = 0U; i < bap_param->params_count; i++) {
195 		const struct bt_cap_initiator_broadcast_subgroup_param *cap_subgroup_param =
196 			&cap_param->subgroup_params[i];
197 		struct bt_bap_broadcast_source_subgroup_param *bap_subgroup_param =
198 			&bap_param->params[i];
199 
200 		bap_subgroup_param->codec_cfg = cap_subgroup_param->codec_cfg;
201 		bap_subgroup_param->params_count = cap_subgroup_param->stream_count;
202 		bap_subgroup_param->params = &bap_stream_params[stream_cnt];
203 
204 		for (size_t j = 0U; j < bap_subgroup_param->params_count; j++, stream_cnt++) {
205 			const struct bt_cap_initiator_broadcast_stream_param *cap_stream_param =
206 				&cap_subgroup_param->stream_params[j];
207 			struct bt_bap_broadcast_source_stream_param *bap_stream_param =
208 				&bap_subgroup_param->params[j];
209 
210 			bap_stream_param->stream = &cap_stream_param->stream->bap_stream;
211 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
212 			bap_stream_param->data_len = cap_stream_param->data_len;
213 			/* We do not need to copy the data, as that is the same type of struct, so
214 			 * we can just point to the CAP parameter data
215 			 */
216 			bap_stream_param->data = cap_stream_param->data;
217 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
218 		}
219 	}
220 }
221 
bt_cap_initiator_broadcast_audio_create(const struct bt_cap_initiator_broadcast_create_param * param,struct bt_cap_broadcast_source ** broadcast_source)222 int bt_cap_initiator_broadcast_audio_create(
223 	const struct bt_cap_initiator_broadcast_create_param *param,
224 	struct bt_cap_broadcast_source **broadcast_source)
225 {
226 	struct bt_bap_broadcast_source_subgroup_param
227 		bap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
228 	struct bt_bap_broadcast_source_stream_param
229 		bap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
230 	struct bt_bap_broadcast_source_param bap_create_param = {0};
231 
232 	CHECKIF(param == NULL) {
233 		LOG_DBG("param is NULL");
234 		return -EINVAL;
235 	}
236 
237 	CHECKIF(broadcast_source == NULL) {
238 		LOG_DBG("source is NULL");
239 		return -EINVAL;
240 	}
241 
242 	if (!cap_initiator_broadcast_audio_start_valid_param(param)) {
243 		return -EINVAL;
244 	}
245 
246 	for (size_t i = 0; i < ARRAY_SIZE(broadcast_sources); i++) {
247 		if (broadcast_sources[i].bap_broadcast == NULL) {
248 			*broadcast_source = &broadcast_sources[i];
249 			break;
250 		}
251 	}
252 
253 	cap_initiator_broadcast_to_bap_broadcast_param(param, &bap_create_param,
254 						       bap_subgroup_params, bap_stream_params);
255 
256 	return bt_bap_broadcast_source_create(&bap_create_param,
257 					      &(*broadcast_source)->bap_broadcast);
258 }
259 
get_cap_broadcast_source_by_bap_broadcast_source(const struct bt_bap_broadcast_source * bap_broadcast_source)260 static struct bt_cap_broadcast_source *get_cap_broadcast_source_by_bap_broadcast_source(
261 	const struct bt_bap_broadcast_source *bap_broadcast_source)
262 {
263 	for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sources); i++) {
264 		if (broadcast_sources[i].bap_broadcast == bap_broadcast_source) {
265 			return &broadcast_sources[i];
266 		}
267 	}
268 
269 	return NULL;
270 }
271 
broadcast_source_started_cb(struct bt_bap_broadcast_source * bap_broadcast_source)272 static void broadcast_source_started_cb(struct bt_bap_broadcast_source *bap_broadcast_source)
273 {
274 	if (cap_cb && cap_cb->broadcast_started) {
275 		struct bt_cap_broadcast_source *source =
276 			get_cap_broadcast_source_by_bap_broadcast_source(bap_broadcast_source);
277 
278 		if (source == NULL) {
279 			/* Not one of ours */
280 			return;
281 		}
282 
283 		cap_cb->broadcast_started(source);
284 	}
285 }
286 
broadcast_source_stopped_cb(struct bt_bap_broadcast_source * bap_broadcast_source,uint8_t reason)287 static void broadcast_source_stopped_cb(struct bt_bap_broadcast_source *bap_broadcast_source,
288 					uint8_t reason)
289 {
290 	if (cap_cb && cap_cb->broadcast_stopped) {
291 		struct bt_cap_broadcast_source *source =
292 			get_cap_broadcast_source_by_bap_broadcast_source(bap_broadcast_source);
293 
294 		if (source == NULL) {
295 			/* Not one of ours */
296 			return;
297 		}
298 
299 		cap_cb->broadcast_stopped(source, reason);
300 	}
301 }
302 
bt_cap_initiator_broadcast_audio_start(struct bt_cap_broadcast_source * broadcast_source,struct bt_le_ext_adv * adv)303 int bt_cap_initiator_broadcast_audio_start(struct bt_cap_broadcast_source *broadcast_source,
304 					   struct bt_le_ext_adv *adv)
305 {
306 	static bool broadcast_source_cbs_registered;
307 
308 	CHECKIF(adv == NULL) {
309 		LOG_DBG("adv is NULL");
310 		return -EINVAL;
311 	}
312 
313 	CHECKIF(broadcast_source == NULL) {
314 		LOG_DBG("broadcast_source is NULL");
315 		return -EINVAL;
316 	}
317 
318 	if (!broadcast_source_cbs_registered) {
319 		static struct bt_bap_broadcast_source_cb broadcast_source_cb = {
320 			.started = broadcast_source_started_cb,
321 			.stopped = broadcast_source_stopped_cb,
322 		};
323 		const int err = bt_bap_broadcast_source_register_cb(&broadcast_source_cb);
324 
325 		if (err != 0) {
326 			__ASSERT(false, "Failed to register BAP broadcast source callbacks: %d",
327 				 err);
328 		}
329 
330 		broadcast_source_cbs_registered = true;
331 	}
332 
333 	return bt_bap_broadcast_source_start(broadcast_source->bap_broadcast, adv);
334 }
335 
bt_cap_initiator_broadcast_audio_update(struct bt_cap_broadcast_source * broadcast_source,const uint8_t meta[],size_t meta_len)336 int bt_cap_initiator_broadcast_audio_update(struct bt_cap_broadcast_source *broadcast_source,
337 					    const uint8_t meta[], size_t meta_len)
338 {
339 	CHECKIF(broadcast_source == NULL) {
340 		LOG_DBG("broadcast_source is NULL");
341 		return -EINVAL;
342 	}
343 
344 	CHECKIF(meta == NULL) {
345 		LOG_DBG("meta is NULL");
346 		return -EINVAL;
347 	}
348 
349 	if (!cap_initiator_valid_metadata(meta, meta_len)) {
350 		LOG_DBG("Invalid metadata");
351 		return -EINVAL;
352 	}
353 
354 	return bt_bap_broadcast_source_update_metadata(broadcast_source->bap_broadcast, meta,
355 						       meta_len);
356 }
357 
bt_cap_initiator_broadcast_audio_stop(struct bt_cap_broadcast_source * broadcast_source)358 int bt_cap_initiator_broadcast_audio_stop(struct bt_cap_broadcast_source *broadcast_source)
359 {
360 	CHECKIF(broadcast_source == NULL) {
361 		LOG_DBG("broadcast_source is NULL");
362 		return -EINVAL;
363 	}
364 
365 	return bt_bap_broadcast_source_stop(broadcast_source->bap_broadcast);
366 }
367 
bt_cap_initiator_broadcast_audio_delete(struct bt_cap_broadcast_source * broadcast_source)368 int bt_cap_initiator_broadcast_audio_delete(struct bt_cap_broadcast_source *broadcast_source)
369 {
370 	int err;
371 
372 	CHECKIF(broadcast_source == NULL) {
373 		LOG_DBG("broadcast_source is NULL");
374 		return -EINVAL;
375 	}
376 
377 	err = bt_bap_broadcast_source_delete(broadcast_source->bap_broadcast);
378 	if (err == 0) {
379 		broadcast_source->bap_broadcast = NULL;
380 	}
381 
382 	return err;
383 }
384 
bt_cap_initiator_broadcast_get_base(struct bt_cap_broadcast_source * broadcast_source,struct net_buf_simple * base_buf)385 int bt_cap_initiator_broadcast_get_base(struct bt_cap_broadcast_source *broadcast_source,
386 					struct net_buf_simple *base_buf)
387 {
388 	CHECKIF(broadcast_source == NULL) {
389 		LOG_DBG("broadcast_source is NULL");
390 		return -EINVAL;
391 	}
392 
393 	return bt_bap_broadcast_source_get_base(broadcast_source->bap_broadcast, base_buf);
394 }
395 
396 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
397 
398 #if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
399 
stream_get_state(const struct bt_bap_stream * bap_stream)400 static enum bt_bap_ep_state stream_get_state(const struct bt_bap_stream *bap_stream)
401 {
402 	struct bt_bap_ep_info ep_info;
403 	int err;
404 
405 	if (bap_stream->ep == NULL) {
406 		return BT_BAP_EP_STATE_IDLE;
407 	}
408 
409 	err = bt_bap_ep_get_info(bap_stream->ep, &ep_info);
410 	if (err != 0) {
411 		LOG_DBG("Failed to get endpoint info %p: %d", bap_stream, err);
412 
413 		return BT_BAP_EP_STATE_IDLE;
414 	}
415 
416 	return ep_info.state;
417 }
418 
stream_is_in_state(const struct bt_bap_stream * bap_stream,enum bt_bap_ep_state state)419 static bool stream_is_in_state(const struct bt_bap_stream *bap_stream, enum bt_bap_ep_state state)
420 {
421 	if (bap_stream->conn == NULL) {
422 		return state == BT_BAP_EP_STATE_IDLE;
423 	}
424 
425 	return stream_get_state(bap_stream) == state;
426 }
427 
stream_is_dir(const struct bt_bap_stream * bap_stream,enum bt_audio_dir dir)428 static bool stream_is_dir(const struct bt_bap_stream *bap_stream, enum bt_audio_dir dir)
429 {
430 	struct bt_bap_ep_info ep_info;
431 	int err;
432 
433 	if (bap_stream->conn == NULL) {
434 		return false;
435 	}
436 
437 	err = bt_bap_ep_get_info(bap_stream->ep, &ep_info);
438 	if (err != 0) {
439 		LOG_DBG("Failed to get endpoint info %p: %d", bap_stream, err);
440 
441 		return false;
442 	}
443 
444 	return ep_info.dir == dir;
445 }
446 
bap_stream_get_iso_state(const struct bt_bap_stream * bap_stream)447 static enum bt_iso_state bap_stream_get_iso_state(const struct bt_bap_stream *bap_stream)
448 {
449 	struct bt_bap_ep_info ep_info;
450 	int err;
451 
452 	if (bap_stream->ep == NULL) {
453 		return BT_ISO_STATE_DISCONNECTED;
454 	}
455 
456 	err = bt_bap_ep_get_info(bap_stream->ep, &ep_info);
457 	if (err != 0) {
458 		LOG_DBG("Failed to get endpoint info %p: %d", bap_stream, err);
459 
460 		return BT_ISO_STATE_DISCONNECTED;
461 	}
462 
463 	if (ep_info.iso_chan == NULL) {
464 		return BT_ISO_STATE_DISCONNECTED;
465 	}
466 
467 	return ep_info.iso_chan->state;
468 }
469 
iso_is_in_state(const struct bt_cap_stream * cap_stream,enum bt_iso_state state)470 static bool iso_is_in_state(const struct bt_cap_stream *cap_stream, enum bt_iso_state state)
471 {
472 	const struct bt_bap_stream *bap_stream = &cap_stream->bap_stream;
473 
474 	return bap_stream_get_iso_state(bap_stream) == state;
475 }
476 
set_cap_stream_in_progress(struct bt_cap_stream * cap_stream,bool value)477 static void set_cap_stream_in_progress(struct bt_cap_stream *cap_stream, bool value)
478 {
479 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
480 
481 	for (size_t i = 0U; i < active_proc->proc_cnt; i++) {
482 		if (cap_stream == active_proc->proc_param.initiator[i].stream) {
483 			active_proc->proc_param.initiator[i].in_progress = value;
484 			return;
485 		}
486 	}
487 
488 	__ASSERT(false, "CAP stream %p not in active_proc", cap_stream);
489 }
490 
491 /**
492  * @brief Gets the next stream for the active procedure.
493  *
494  * Returns NULL if all streams are in the right state for the current step
495  */
496 static struct bt_cap_initiator_proc_param *
get_proc_param_by_cap_stream(struct bt_cap_common_proc * active_proc,const struct bt_cap_stream * cap_stream)497 get_proc_param_by_cap_stream(struct bt_cap_common_proc *active_proc,
498 			     const struct bt_cap_stream *cap_stream)
499 {
500 	for (size_t i = 0U; i < active_proc->proc_cnt; i++) {
501 		if (active_proc->proc_param.initiator[i].stream == cap_stream) {
502 			return &active_proc->proc_param.initiator[i];
503 		}
504 	}
505 
506 	return NULL;
507 }
508 
update_proc_done_cnt(struct bt_cap_common_proc * active_proc)509 static void update_proc_done_cnt(struct bt_cap_common_proc *active_proc)
510 {
511 	const enum bt_cap_common_subproc_type subproc_type = active_proc->subproc_type;
512 	const enum bt_cap_common_proc_type proc_type = active_proc->proc_type;
513 	size_t proc_done_cnt = 0U;
514 
515 	if (proc_type == BT_CAP_COMMON_PROC_TYPE_START) {
516 		/* To support state changes by the server, we cannot rely simply on the number of
517 		 * BAP procedures we have initiated. For the start and stop CAP procedures we use
518 		 * the states to determine how far we are.
519 		 */
520 		for (size_t i = 0U; i < active_proc->proc_cnt; i++) {
521 			struct bt_cap_initiator_proc_param *proc_param;
522 			struct bt_cap_stream *cap_stream;
523 			struct bt_bap_stream *bap_stream;
524 			enum bt_bap_ep_state state;
525 
526 			proc_param = &active_proc->proc_param.initiator[i];
527 			cap_stream = proc_param->stream;
528 			bap_stream = &cap_stream->bap_stream;
529 
530 			state = stream_get_state(bap_stream);
531 
532 			switch (subproc_type) {
533 			case BT_CAP_COMMON_SUBPROC_TYPE_CODEC_CONFIG:
534 				if (state > BT_BAP_EP_STATE_IDLE) {
535 					proc_done_cnt++;
536 				}
537 				break;
538 			case BT_CAP_COMMON_SUBPROC_TYPE_QOS_CONFIG:
539 				if (state > BT_BAP_EP_STATE_CODEC_CONFIGURED) {
540 					proc_done_cnt++;
541 				} else if (state < BT_BAP_EP_STATE_CODEC_CONFIGURED) {
542 					/* Unexpected state - Abort */
543 					bt_cap_common_abort_proc(bap_stream->conn, -EBADMSG);
544 				}
545 				break;
546 			case BT_CAP_COMMON_SUBPROC_TYPE_ENABLE:
547 				if (state > BT_BAP_EP_STATE_QOS_CONFIGURED) {
548 					proc_done_cnt++;
549 				} else if (state < BT_BAP_EP_STATE_QOS_CONFIGURED) {
550 					/* Unexpected state - Abort */
551 					bt_cap_common_abort_proc(bap_stream->conn, -EBADMSG);
552 				}
553 				break;
554 			case BT_CAP_COMMON_SUBPROC_TYPE_CONNECT:
555 				if (state < BT_BAP_EP_STATE_ENABLING) {
556 					/* Unexpected state - Abort */
557 					bt_cap_common_abort_proc(bap_stream->conn, -EBADMSG);
558 				} else if (proc_param->start.connected) {
559 					proc_done_cnt++;
560 				}
561 				break;
562 			case BT_CAP_COMMON_SUBPROC_TYPE_START:
563 				if (state > BT_BAP_EP_STATE_ENABLING) {
564 					proc_done_cnt++;
565 				} else if (state < BT_BAP_EP_STATE_ENABLING ||
566 					   !iso_is_in_state(cap_stream, BT_ISO_STATE_CONNECTED)) {
567 					/* Unexpected state - Abort */
568 					bt_cap_common_abort_proc(bap_stream->conn, -EBADMSG);
569 				}
570 				break;
571 			default:
572 				__ASSERT(false, "Invalid subproc %d for %d", subproc_type,
573 					 proc_type);
574 			}
575 		}
576 	} else if (proc_type == BT_CAP_COMMON_PROC_TYPE_STOP) {
577 		/* To support state changes by the server, we cannot rely simply on the number of
578 		 * BAP procedures we have initiated. For the start and stop CAP procedures we use
579 		 * the states to determine how far we are.
580 		 */
581 		for (size_t i = 0U; i < active_proc->proc_cnt; i++) {
582 			struct bt_cap_initiator_proc_param *proc_param;
583 			struct bt_cap_stream *cap_stream;
584 			struct bt_bap_stream *bap_stream;
585 			enum bt_bap_ep_state state;
586 
587 			proc_param = &active_proc->proc_param.initiator[i];
588 			cap_stream = proc_param->stream;
589 			bap_stream = &cap_stream->bap_stream;
590 
591 			state = stream_get_state(bap_stream);
592 
593 			switch (subproc_type) {
594 			case BT_CAP_COMMON_SUBPROC_TYPE_DISABLE:
595 				if (state == BT_BAP_EP_STATE_QOS_CONFIGURED ||
596 				    state == BT_BAP_EP_STATE_DISABLING) {
597 					proc_done_cnt++;
598 				}
599 				break;
600 			case BT_CAP_COMMON_SUBPROC_TYPE_STOP:
601 				if (state == BT_BAP_EP_STATE_QOS_CONFIGURED) {
602 					proc_done_cnt++;
603 				}
604 				break;
605 			case BT_CAP_COMMON_SUBPROC_TYPE_RELEASE:
606 				if (state == BT_BAP_EP_STATE_IDLE ||
607 				    state == BT_BAP_EP_STATE_CODEC_CONFIGURED) {
608 					proc_done_cnt++;
609 				}
610 				break;
611 			default:
612 				__ASSERT(false, "Invalid subproc %d for %d", subproc_type,
613 					 proc_type);
614 			}
615 		}
616 	} else if (proc_type == BT_CAP_COMMON_PROC_TYPE_UPDATE) {
617 		/* For metadata we cannot check the states for all streams, as it does not trigger a
618 		 * state change
619 		 */
620 		struct bt_cap_initiator_proc_param *proc_param;
621 		struct bt_cap_stream *cap_stream;
622 		struct bt_bap_stream *bap_stream;
623 		enum bt_bap_ep_state state;
624 
625 		proc_param = &active_proc->proc_param.initiator[active_proc->proc_done_cnt];
626 		cap_stream = proc_param->stream;
627 		bap_stream = &cap_stream->bap_stream;
628 
629 		state = stream_get_state(bap_stream);
630 
631 		switch (subproc_type) {
632 		case BT_CAP_COMMON_SUBPROC_TYPE_META_UPDATE:
633 			if (state == BT_BAP_EP_STATE_ENABLING ||
634 			    state == BT_BAP_EP_STATE_STREAMING) {
635 				proc_done_cnt = active_proc->proc_done_cnt + 1U;
636 			} else {
637 				/* Unexpected state - Abort */
638 				bt_cap_common_abort_proc(bap_stream->conn, -EBADMSG);
639 			}
640 			break;
641 		default:
642 			__ASSERT(false, "Invalid subproc %d for %d", subproc_type, proc_type);
643 		}
644 	}
645 
646 	active_proc->proc_done_cnt = proc_done_cnt;
647 
648 	LOG_DBG("proc %d subproc %d: %zu/%zu", proc_type, subproc_type, active_proc->proc_done_cnt,
649 		active_proc->proc_cnt);
650 }
651 
652 /**
653  * @brief Gets the next stream for the active procedure.
654  *
655  * Returns NULL if all streams are in the right state for the current step
656  */
657 static struct bt_cap_initiator_proc_param *
get_next_proc_param(struct bt_cap_common_proc * active_proc)658 get_next_proc_param(struct bt_cap_common_proc *active_proc)
659 {
660 	const enum bt_cap_common_subproc_type subproc_type = active_proc->subproc_type;
661 
662 	for (size_t i = 0U; i < active_proc->proc_cnt; i++) {
663 		struct bt_cap_initiator_proc_param *proc_param;
664 		struct bt_cap_stream *cap_stream;
665 		struct bt_bap_stream *bap_stream;
666 		enum bt_bap_ep_state state;
667 
668 		proc_param = &active_proc->proc_param.initiator[i];
669 
670 		if (proc_param->in_progress) {
671 			continue;
672 		}
673 
674 		cap_stream = proc_param->stream;
675 		bap_stream = &cap_stream->bap_stream;
676 		state = stream_get_state(bap_stream);
677 
678 		switch (subproc_type) {
679 		case BT_CAP_COMMON_SUBPROC_TYPE_CODEC_CONFIG:
680 			if (state == BT_BAP_EP_STATE_IDLE) {
681 				return proc_param;
682 			}
683 			break;
684 		case BT_CAP_COMMON_SUBPROC_TYPE_QOS_CONFIG:
685 			if (state == BT_BAP_EP_STATE_CODEC_CONFIGURED) {
686 				return proc_param;
687 			}
688 			break;
689 		case BT_CAP_COMMON_SUBPROC_TYPE_ENABLE:
690 			if (state == BT_BAP_EP_STATE_QOS_CONFIGURED) {
691 				return proc_param;
692 			}
693 			break;
694 		case BT_CAP_COMMON_SUBPROC_TYPE_CONNECT:
695 			if (state == BT_BAP_EP_STATE_ENABLING && !proc_param->start.connected) {
696 				return proc_param;
697 			}
698 			break;
699 		case BT_CAP_COMMON_SUBPROC_TYPE_START:
700 			if (state == BT_BAP_EP_STATE_ENABLING) {
701 				/* TODO: Add check for connected */
702 				return proc_param;
703 			}
704 			break;
705 		case BT_CAP_COMMON_SUBPROC_TYPE_META_UPDATE:
706 			if (state == BT_BAP_EP_STATE_ENABLING ||
707 			    state == BT_BAP_EP_STATE_STREAMING) {
708 				return proc_param;
709 			}
710 			break;
711 		case BT_CAP_COMMON_SUBPROC_TYPE_DISABLE:
712 			if (state == BT_BAP_EP_STATE_ENABLING ||
713 			    state == BT_BAP_EP_STATE_STREAMING) {
714 				return proc_param;
715 			}
716 			break;
717 		case BT_CAP_COMMON_SUBPROC_TYPE_STOP:
718 			if (state == BT_BAP_EP_STATE_DISABLING) {
719 				return proc_param;
720 			}
721 			break;
722 		case BT_CAP_COMMON_SUBPROC_TYPE_RELEASE:
723 			if (proc_param->stop.release && state != BT_BAP_EP_STATE_IDLE &&
724 			    state != BT_BAP_EP_STATE_CODEC_CONFIGURED) {
725 				return proc_param;
726 			}
727 			break;
728 		default:
729 			break;
730 		}
731 	}
732 
733 	return NULL;
734 }
735 
736 static void
bt_cap_initiator_discover_complete(struct bt_conn * conn,int err,const struct bt_csip_set_coordinator_set_member * member,const struct bt_csip_set_coordinator_csis_inst * csis_inst)737 bt_cap_initiator_discover_complete(struct bt_conn *conn, int err,
738 				   const struct bt_csip_set_coordinator_set_member *member,
739 				   const struct bt_csip_set_coordinator_csis_inst *csis_inst)
740 {
741 	if (cap_cb && cap_cb->unicast_discovery_complete) {
742 		cap_cb->unicast_discovery_complete(conn, err, member, csis_inst);
743 	}
744 }
745 
bt_cap_initiator_unicast_discover(struct bt_conn * conn)746 int bt_cap_initiator_unicast_discover(struct bt_conn *conn)
747 {
748 	CHECKIF(conn == NULL) {
749 		LOG_DBG("NULL conn");
750 		return -EINVAL;
751 	}
752 
753 	return bt_cap_common_discover(conn, bt_cap_initiator_discover_complete);
754 }
755 
valid_unicast_audio_start_param(const struct bt_cap_unicast_audio_start_param * param)756 static bool valid_unicast_audio_start_param(const struct bt_cap_unicast_audio_start_param *param)
757 {
758 	struct bt_bap_unicast_group *unicast_group = NULL;
759 
760 	CHECKIF(param == NULL) {
761 		LOG_DBG("param is NULL");
762 		return false;
763 	}
764 
765 	CHECKIF(param->count == 0) {
766 		LOG_DBG("Invalid param->count: %u", param->count);
767 		return false;
768 	}
769 
770 	CHECKIF(param->stream_params == NULL) {
771 		LOG_DBG("param->stream_params is NULL");
772 		return false;
773 	}
774 
775 	CHECKIF(param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
776 		LOG_DBG("param->count (%zu) is larger than "
777 			"CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT (%d)",
778 			param->count,
779 			CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT);
780 		return false;
781 	}
782 
783 	for (size_t i = 0U; i < param->count; i++) {
784 		const struct bt_cap_unicast_audio_start_stream_param *stream_param =
785 									&param->stream_params[i];
786 		const union bt_cap_set_member *member = &stream_param->member;
787 		const struct bt_cap_stream *cap_stream = stream_param->stream;
788 		const struct bt_audio_codec_cfg *codec_cfg = stream_param->codec_cfg;
789 		const struct bt_bap_stream *bap_stream;
790 		const struct bt_conn *member_conn =
791 			bt_cap_common_get_member_conn(param->type, member);
792 
793 		if (member == NULL) {
794 			LOG_DBG("param->members[%zu] is NULL", i);
795 			return false;
796 		}
797 
798 		if (member_conn == NULL) {
799 			LOG_DBG("Invalid param->members[%zu]", i);
800 			return false;
801 		}
802 
803 		CHECKIF(stream_param->codec_cfg == NULL) {
804 			LOG_DBG("param->stream_params[%zu].codec_cfg  is NULL", i);
805 			return false;
806 		}
807 
808 		CHECKIF(!cap_initiator_valid_metadata(codec_cfg->meta, codec_cfg->meta_len)) {
809 			LOG_DBG("param->stream_params[%zu].codec_cfg  is invalid", i);
810 			return false;
811 		}
812 
813 		CHECKIF(stream_param->ep == NULL) {
814 			LOG_DBG("param->stream_params[%zu].ep is NULL", i);
815 			return false;
816 		}
817 
818 		CHECKIF(member == NULL) {
819 			LOG_DBG("param->stream_params[%zu].member is NULL", i);
820 			return false;
821 		}
822 
823 		CHECKIF(cap_stream == NULL) {
824 			LOG_DBG("param->streams[%zu] is NULL", i);
825 			return false;
826 		}
827 
828 		bap_stream = &cap_stream->bap_stream;
829 
830 		CHECKIF(bap_stream->group == NULL) {
831 			LOG_DBG("param->streams[%zu] is not in a unicast group", i);
832 			return false;
833 		}
834 
835 		/* Use the group of the first stream for comparison */
836 		if (unicast_group == NULL) {
837 			unicast_group = bap_stream->group;
838 		} else {
839 			CHECKIF(bap_stream->group != unicast_group) {
840 				LOG_DBG("param->streams[%zu] is not in this group %p", i,
841 					unicast_group);
842 				return false;
843 			}
844 		}
845 
846 		for (size_t j = 0U; j < i; j++) {
847 			if (param->stream_params[j].stream == cap_stream) {
848 				LOG_DBG("param->stream_params[%zu] (%p) is "
849 					"duplicated by "
850 					"param->stream_params[%zu] (%p)",
851 					j, param->stream_params[j].stream,
852 					i, cap_stream);
853 				return false;
854 			}
855 		}
856 	}
857 
858 	return true;
859 }
860 
cap_initiator_unicast_audio_proc_complete(void)861 static void cap_initiator_unicast_audio_proc_complete(void)
862 {
863 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
864 	enum bt_cap_common_proc_type proc_type;
865 	struct bt_conn *failed_conn;
866 	int err;
867 
868 	failed_conn = active_proc->failed_conn;
869 	err = active_proc->err;
870 	proc_type = active_proc->proc_type;
871 	bt_cap_common_clear_active_proc();
872 
873 	if (cap_cb == NULL) {
874 		return;
875 	}
876 
877 	switch (proc_type) {
878 	case BT_CAP_COMMON_PROC_TYPE_START:
879 		if (cap_cb->unicast_start_complete != NULL) {
880 			cap_cb->unicast_start_complete(err, failed_conn);
881 		}
882 		break;
883 	case BT_CAP_COMMON_PROC_TYPE_UPDATE:
884 		if (cap_cb->unicast_update_complete != NULL) {
885 			cap_cb->unicast_update_complete(err, failed_conn);
886 		}
887 		break;
888 	case BT_CAP_COMMON_PROC_TYPE_STOP:
889 		if (cap_cb->unicast_stop_complete != NULL) {
890 			cap_cb->unicast_stop_complete(err, failed_conn);
891 		}
892 		break;
893 	case BT_CAP_COMMON_PROC_TYPE_NONE:
894 	default:
895 		__ASSERT(false, "Invalid proc_type: %u", proc_type);
896 	}
897 }
898 
bt_cap_initiator_cp_cb(struct bt_cap_stream * cap_stream,enum bt_bap_ascs_rsp_code rsp_code,enum bt_bap_ascs_reason reason)899 void bt_cap_initiator_cp_cb(struct bt_cap_stream *cap_stream, enum bt_bap_ascs_rsp_code rsp_code,
900 			    enum bt_bap_ascs_reason reason)
901 {
902 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
903 		/* State change happened outside of a procedure; ignore */
904 		return;
905 	}
906 
907 	LOG_DBG("cap_stream %p", cap_stream);
908 
909 	set_cap_stream_in_progress(cap_stream, false);
910 
911 	if (rsp_code != BT_BAP_ASCS_RSP_CODE_SUCCESS) {
912 		struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
913 
914 		/* In the case that the control point write is rejected, we will not get a ASE state
915 		 * change notification. This is considered an error that shall abort the current
916 		 * procedure.
917 		 */
918 		active_proc->proc_done_cnt++;
919 
920 		LOG_DBG("Control point operation on stream %p failed with %d and reason %d",
921 			cap_stream, rsp_code, reason);
922 
923 		/* Unexpected callback - Abort */
924 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
925 
926 		if (bt_cap_common_proc_is_aborted()) {
927 			if (bt_cap_common_proc_all_handled()) {
928 				cap_initiator_unicast_audio_proc_complete();
929 			}
930 
931 			return;
932 		}
933 	}
934 }
935 
cap_initiator_unicast_audio_configure(const struct bt_cap_unicast_audio_start_param * param)936 static int cap_initiator_unicast_audio_configure(
937 	const struct bt_cap_unicast_audio_start_param *param)
938 {
939 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
940 	struct bt_cap_initiator_proc_param *proc_param;
941 	struct bt_audio_codec_cfg *codec_cfg;
942 	struct bt_bap_stream *bap_stream;
943 	struct bt_bap_ep *ep;
944 	struct bt_conn *conn;
945 	int err;
946 	/** TODO: If this is a CSIP set, then the order of the procedures may
947 	 * not match the order in the parameters, and the CSIP ordered access
948 	 * procedure should be used.
949 	 */
950 
951 	for (size_t i = 0U; i < param->count; i++) {
952 		struct bt_cap_unicast_audio_start_stream_param *stream_param =
953 									&param->stream_params[i];
954 		union bt_cap_set_member *member = &stream_param->member;
955 		struct bt_cap_stream *cap_stream = stream_param->stream;
956 
957 		conn = bt_cap_common_get_member_conn(param->type, member);
958 
959 		/* Ensure that ops are registered before any procedures are started */
960 		bt_cap_stream_ops_register_bap(cap_stream);
961 
962 		/* Store the necessary parameters as we cannot assume that the supplied parameters
963 		 * are kept valid
964 		 */
965 		active_proc->proc_param.initiator[i].stream = cap_stream;
966 		active_proc->proc_param.initiator[i].start.ep = stream_param->ep;
967 		active_proc->proc_param.initiator[i].start.conn = conn;
968 		active_proc->proc_param.initiator[i].start.codec_cfg = stream_param->codec_cfg;
969 	}
970 
971 	/* Store the information about the active procedure so that we can
972 	 * continue the procedure after each step
973 	 */
974 	bt_cap_common_start_proc(BT_CAP_COMMON_PROC_TYPE_START, param->count);
975 	bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_CODEC_CONFIG);
976 
977 	proc_param = get_next_proc_param(active_proc);
978 	if (proc_param == NULL) {
979 		/* If proc_param is NULL then this step is a no-op and we can skip to the next step
980 		 */
981 		bt_cap_initiator_codec_configured(active_proc->proc_param.initiator[0].stream);
982 
983 		return 0;
984 	}
985 
986 	bap_stream = &proc_param->stream->bap_stream;
987 	codec_cfg = proc_param->start.codec_cfg;
988 	conn = proc_param->start.conn;
989 	ep = proc_param->start.ep;
990 	active_proc->proc_initiated_cnt++;
991 	proc_param->in_progress = true;
992 
993 	/* Since BAP operations may require a write long or a read long on the notification,
994 	 * we cannot assume that we can do multiple streams at once, thus do it one at a time.
995 	 * TODO: We should always be able to do one per ACL, so there is room for optimization.
996 	 * This applies to all BAP calls in this file.
997 	 */
998 	err = bt_bap_stream_config(conn, bap_stream, ep, codec_cfg);
999 	if (err != 0) {
1000 		LOG_DBG("Failed to config stream %p: %d", proc_param->stream, err);
1001 
1002 		bt_cap_common_clear_active_proc();
1003 	}
1004 
1005 	return err;
1006 }
1007 
bt_cap_initiator_unicast_audio_start(const struct bt_cap_unicast_audio_start_param * param)1008 int bt_cap_initiator_unicast_audio_start(const struct bt_cap_unicast_audio_start_param *param)
1009 {
1010 	bool all_streaming = true;
1011 
1012 	if (bt_cap_common_proc_is_active()) {
1013 		LOG_DBG("A CAP procedure is already in progress");
1014 
1015 		return -EBUSY;
1016 	}
1017 
1018 	if (!valid_unicast_audio_start_param(param)) {
1019 		return -EINVAL;
1020 	}
1021 
1022 	for (size_t i = 0U; i < param->count; i++) {
1023 		const struct bt_bap_stream *bap_stream =
1024 			&param->stream_params[i].stream->bap_stream;
1025 
1026 		if (!stream_is_in_state(bap_stream, BT_BAP_EP_STATE_STREAMING)) {
1027 			all_streaming = false;
1028 		}
1029 	}
1030 
1031 	if (all_streaming) {
1032 		LOG_DBG("All streams are already in the streaming state");
1033 		return -EALREADY;
1034 	}
1035 
1036 	return cap_initiator_unicast_audio_configure(param);
1037 }
1038 
bt_cap_initiator_codec_configured(struct bt_cap_stream * cap_stream)1039 void bt_cap_initiator_codec_configured(struct bt_cap_stream *cap_stream)
1040 {
1041 	struct bt_conn
1042 		*conns[MIN(CONFIG_BT_MAX_CONN, CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT)];
1043 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
1044 	struct bt_cap_initiator_proc_param *proc_param;
1045 	struct bt_bap_unicast_group *unicast_group;
1046 
1047 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
1048 		/* State change happened outside of a procedure; ignore */
1049 		return;
1050 	}
1051 
1052 	LOG_DBG("cap_stream %p", cap_stream);
1053 
1054 	if (bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_RELEASE)) {
1055 		/* When releasing a stream, it may go into the codec configured state if
1056 		 * the unicast server caches the configuration - We treat it as a release
1057 		 */
1058 		bt_cap_initiator_released(cap_stream);
1059 		return;
1060 	} else if (!bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_CODEC_CONFIG)) {
1061 		/* Unexpected callback - Abort */
1062 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
1063 	} else {
1064 		update_proc_done_cnt(active_proc);
1065 
1066 		LOG_DBG("Stream %p configured (%zu/%zu streams done)", cap_stream,
1067 			active_proc->proc_done_cnt, active_proc->proc_cnt);
1068 	}
1069 
1070 	if (bt_cap_common_proc_is_aborted()) {
1071 		if (bt_cap_common_proc_all_handled()) {
1072 			cap_initiator_unicast_audio_proc_complete();
1073 		}
1074 
1075 		return;
1076 	}
1077 
1078 	if (!bt_cap_common_proc_is_done()) {
1079 		struct bt_cap_stream *next_cap_stream;
1080 		struct bt_bap_stream *next_bap_stream;
1081 		struct bt_audio_codec_cfg *codec_cfg;
1082 		struct bt_conn *conn;
1083 		struct bt_bap_ep *ep;
1084 		int err;
1085 
1086 		proc_param = get_next_proc_param(active_proc);
1087 		__ASSERT(proc_param != NULL, "proc is not done, but could not get next proc_param");
1088 		next_cap_stream = proc_param->stream;
1089 		conn = proc_param->start.conn;
1090 		ep = proc_param->start.ep;
1091 		codec_cfg = proc_param->start.codec_cfg;
1092 		next_bap_stream = &next_cap_stream->bap_stream;
1093 		active_proc->proc_initiated_cnt++;
1094 		proc_param->in_progress = true;
1095 
1096 		err = bt_bap_stream_config(conn, next_bap_stream, ep, codec_cfg);
1097 		if (err != 0) {
1098 			LOG_DBG("Failed to config stream %p: %d", next_cap_stream, err);
1099 
1100 			bt_cap_common_abort_proc(conn, err);
1101 			cap_initiator_unicast_audio_proc_complete();
1102 		}
1103 
1104 		return;
1105 	}
1106 
1107 	/* The QoS Configure procedure works on a set of connections and a
1108 	 * unicast group, so we generate a list of unique connection pointers
1109 	 * for the procedure
1110 	 */
1111 	(void)memset(conns, 0, sizeof(conns));
1112 	for (size_t i = 0U; i < active_proc->proc_cnt; i++) {
1113 		struct bt_conn *stream_conn =
1114 			active_proc->proc_param.initiator[i].stream->bap_stream.conn;
1115 		struct bt_conn **free_conn = NULL;
1116 		bool already_added = false;
1117 
1118 		for (size_t j = 0U; j < ARRAY_SIZE(conns); j++) {
1119 			if (stream_conn == conns[j]) {
1120 				already_added = true;
1121 				break;
1122 			} else if (conns[j] == NULL && free_conn == NULL) {
1123 				free_conn = &conns[j];
1124 			}
1125 		}
1126 
1127 		if (already_added) {
1128 			continue;
1129 		}
1130 
1131 		if (free_conn != NULL) {
1132 			*free_conn = stream_conn;
1133 		} else {
1134 			__ASSERT(false, "[%zu]: No free conns", i);
1135 			return;
1136 		}
1137 	}
1138 
1139 	/* All streams in the procedure share the same unicast group, so we just
1140 	 * use the reference from the first stream
1141 	 */
1142 	bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_QOS_CONFIG);
1143 	proc_param = get_next_proc_param(active_proc);
1144 	if (proc_param == NULL) {
1145 		/* If proc_param is NULL then this step is a no-op and we can skip to the next step
1146 		 */
1147 		bt_cap_initiator_qos_configured(active_proc->proc_param.initiator[0].stream);
1148 
1149 		return;
1150 	}
1151 
1152 	unicast_group = (struct bt_bap_unicast_group *)proc_param->stream->bap_stream.group;
1153 
1154 	for (size_t i = 0U; i < ARRAY_SIZE(conns); i++) {
1155 		int err;
1156 
1157 		/* When conns[i] is NULL, we have QoS Configured all unique connections */
1158 		if (conns[i] == NULL) {
1159 			break;
1160 		}
1161 
1162 		for (size_t j = 0U; j < active_proc->proc_cnt; j++) {
1163 			proc_param = &active_proc->proc_param.initiator[j];
1164 			if (proc_param->stream->bap_stream.conn == conns[i]) {
1165 				active_proc->proc_initiated_cnt++;
1166 				proc_param->in_progress = false;
1167 				break;
1168 			}
1169 		}
1170 
1171 		proc_param->in_progress = true;
1172 
1173 		err = bt_bap_stream_qos(conns[i], unicast_group);
1174 		if (err != 0) {
1175 			LOG_DBG("Failed to set stream QoS for conn %p and group %p: %d",
1176 				(void *)conns[i], unicast_group, err);
1177 
1178 			/* End or mark procedure as aborted.
1179 			 * If we have sent any requests over air, we will abort
1180 			 * once all sent requests has completed
1181 			 */
1182 			bt_cap_common_abort_proc(conns[i], err);
1183 			if (i == 0U) {
1184 				cap_initiator_unicast_audio_proc_complete();
1185 			}
1186 
1187 			return;
1188 		}
1189 	}
1190 }
1191 
bt_cap_initiator_qos_configured(struct bt_cap_stream * cap_stream)1192 void bt_cap_initiator_qos_configured(struct bt_cap_stream *cap_stream)
1193 {
1194 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
1195 
1196 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
1197 		/* State change happened outside of a procedure; ignore */
1198 		return;
1199 	}
1200 
1201 	LOG_DBG("cap_stream %p", cap_stream);
1202 
1203 	if (!(bt_cap_common_proc_is_type(BT_CAP_COMMON_PROC_TYPE_START) &&
1204 	      bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_QOS_CONFIG)) &&
1205 	    !(bt_cap_common_proc_is_type(BT_CAP_COMMON_PROC_TYPE_STOP))) {
1206 		/* Unexpected callback - Abort */
1207 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
1208 	} else {
1209 		update_proc_done_cnt(active_proc);
1210 
1211 		LOG_DBG("Stream %p QoS configured (%zu/%zu streams done)", cap_stream,
1212 			active_proc->proc_done_cnt, active_proc->proc_cnt);
1213 	}
1214 
1215 	if (bt_cap_common_proc_is_aborted()) {
1216 		if (bt_cap_common_proc_all_handled()) {
1217 			cap_initiator_unicast_audio_proc_complete();
1218 		}
1219 
1220 		return;
1221 	}
1222 
1223 	if (bt_cap_common_proc_is_type(BT_CAP_COMMON_PROC_TYPE_START)) {
1224 		struct bt_cap_initiator_proc_param *proc_param;
1225 		struct bt_cap_stream *next_cap_stream;
1226 		struct bt_bap_stream *bap_stream;
1227 		int err;
1228 
1229 		if (!bt_cap_common_proc_is_done()) {
1230 			/* Not yet finished, wait for all */
1231 			return;
1232 		}
1233 
1234 		bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_ENABLE);
1235 		proc_param = get_next_proc_param(active_proc);
1236 		if (proc_param == NULL) {
1237 			/* If proc_param is NULL then this step is a no-op and we can skip to the
1238 			 * next step
1239 			 */
1240 			bt_cap_initiator_enabled(active_proc->proc_param.initiator[0].stream);
1241 
1242 			return;
1243 		}
1244 
1245 		next_cap_stream = proc_param->stream;
1246 		bap_stream = &next_cap_stream->bap_stream;
1247 		active_proc->proc_initiated_cnt++;
1248 		proc_param->in_progress = true;
1249 
1250 		err = bt_bap_stream_enable(bap_stream, bap_stream->codec_cfg->meta,
1251 					   bap_stream->codec_cfg->meta_len);
1252 		if (err != 0) {
1253 			LOG_DBG("Failed to enable stream %p: %d", next_cap_stream, err);
1254 
1255 			bt_cap_common_abort_proc(bap_stream->conn, err);
1256 			cap_initiator_unicast_audio_proc_complete();
1257 		}
1258 	} else if (bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_RELEASE)) {
1259 		struct bt_cap_initiator_proc_param *proc_param;
1260 		struct bt_cap_stream *next_cap_stream;
1261 		struct bt_bap_stream *next_bap_stream;
1262 		int err;
1263 
1264 		proc_param = get_next_proc_param(active_proc);
1265 		__ASSERT(proc_param != NULL, "proc is not done, but could not get next proc_param");
1266 
1267 		next_cap_stream = proc_param->stream;
1268 		next_bap_stream = &next_cap_stream->bap_stream;
1269 		active_proc->proc_initiated_cnt++;
1270 		proc_param->in_progress = true;
1271 
1272 		err = bt_bap_stream_release(next_bap_stream);
1273 		if (err != 0) {
1274 			LOG_DBG("Failed to release stream %p: %d", next_cap_stream, err);
1275 
1276 			bt_cap_common_abort_proc(next_bap_stream->conn, err);
1277 			cap_initiator_unicast_audio_proc_complete();
1278 		}
1279 	}
1280 }
1281 
bt_cap_initiator_enabled(struct bt_cap_stream * cap_stream)1282 void bt_cap_initiator_enabled(struct bt_cap_stream *cap_stream)
1283 {
1284 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
1285 	struct bt_cap_initiator_proc_param *proc_param;
1286 	struct bt_bap_stream *bap_stream;
1287 	int err;
1288 
1289 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
1290 		/* State change happened outside of a procedure; ignore */
1291 		return;
1292 	}
1293 
1294 	LOG_DBG("cap_stream %p", cap_stream);
1295 
1296 	if (!bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_ENABLE)) {
1297 		/* Unexpected callback - Abort */
1298 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
1299 	} else {
1300 		update_proc_done_cnt(active_proc);
1301 
1302 		LOG_DBG("Stream %p enabled (%zu/%zu streams done)", cap_stream,
1303 			active_proc->proc_done_cnt, active_proc->proc_cnt);
1304 	}
1305 
1306 	if (bt_cap_common_proc_is_aborted()) {
1307 		if (bt_cap_common_proc_all_handled()) {
1308 			cap_initiator_unicast_audio_proc_complete();
1309 		}
1310 
1311 		return;
1312 	}
1313 
1314 	if (!bt_cap_common_proc_is_done()) {
1315 		struct bt_cap_stream *next_cap_stream;
1316 		struct bt_bap_stream *next_bap_stream;
1317 
1318 		proc_param = get_next_proc_param(active_proc);
1319 		__ASSERT(proc_param != NULL, "proc is not done, but could not get next proc_param");
1320 		next_cap_stream = proc_param->stream;
1321 		next_bap_stream = &next_cap_stream->bap_stream;
1322 
1323 		active_proc->proc_initiated_cnt++;
1324 		proc_param->in_progress = true;
1325 
1326 		err = bt_bap_stream_enable(next_bap_stream, next_bap_stream->codec_cfg->meta,
1327 					   next_bap_stream->codec_cfg->meta_len);
1328 		if (err != 0) {
1329 			LOG_DBG("Failed to enable stream %p: %d", next_cap_stream, err);
1330 
1331 			bt_cap_common_abort_proc(next_bap_stream->conn, err);
1332 			cap_initiator_unicast_audio_proc_complete();
1333 		}
1334 
1335 		return;
1336 	}
1337 
1338 	bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_CONNECT);
1339 	proc_param = get_next_proc_param(active_proc);
1340 	if (proc_param == NULL) {
1341 		/* If proc_param is NULL then this step is a no-op and we can skip to the next step
1342 		 */
1343 		bt_cap_initiator_connected(active_proc->proc_param.initiator[0].stream);
1344 
1345 		return;
1346 	}
1347 
1348 	bap_stream = &proc_param->stream->bap_stream;
1349 	proc_param->in_progress = true;
1350 
1351 	err = bt_bap_stream_connect(bap_stream);
1352 	if (err == -EALREADY) {
1353 		/* If the stream is already connected we can just call the callback directly
1354 		 * NOTE: It's important that we do not do any additional functionality after
1355 		 * calling this
1356 		 */
1357 		proc_param->in_progress = false;
1358 		bt_cap_initiator_connected(proc_param->stream);
1359 	} else if (err != 0) {
1360 		LOG_DBG("Failed to connect stream %p: %d", proc_param->stream, err);
1361 
1362 		/* End and mark procedure as aborted.
1363 		 * If we have sent any requests over air, we will abort
1364 		 * once all sent requests has completed
1365 		 */
1366 		bt_cap_common_abort_proc(bap_stream->conn, err);
1367 		cap_initiator_unicast_audio_proc_complete();
1368 	}
1369 }
1370 
bt_cap_initiator_connected(struct bt_cap_stream * cap_stream)1371 void bt_cap_initiator_connected(struct bt_cap_stream *cap_stream)
1372 {
1373 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
1374 	struct bt_cap_initiator_proc_param *proc_param;
1375 	struct bt_bap_stream *bap_stream;
1376 	int err;
1377 
1378 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
1379 		/* State change happened outside of a procedure; ignore */
1380 		return;
1381 	}
1382 
1383 	LOG_DBG("cap_stream %p", cap_stream);
1384 
1385 	set_cap_stream_in_progress(cap_stream, false);
1386 
1387 	if (!bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_CONNECT)) {
1388 		/* Unexpected callback - Abort */
1389 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
1390 	} else {
1391 		proc_param = get_proc_param_by_cap_stream(active_proc, cap_stream);
1392 		__ASSERT_NO_MSG(proc_param != NULL);
1393 
1394 		/* Sets connected before update_proc_done_cnt as that is the only way to can track
1395 		 * the CIS state change
1396 		 */
1397 		proc_param->start.connected = true;
1398 		update_proc_done_cnt(active_proc);
1399 
1400 		LOG_DBG("Stream %p connected (%zu/%zu streams done)", cap_stream,
1401 			active_proc->proc_done_cnt, active_proc->proc_cnt);
1402 	}
1403 
1404 	if (bt_cap_common_proc_is_aborted()) {
1405 		if (bt_cap_common_proc_all_handled()) {
1406 			cap_initiator_unicast_audio_proc_complete();
1407 		}
1408 
1409 		return;
1410 	}
1411 
1412 	if (!bt_cap_common_proc_is_done()) {
1413 		struct bt_cap_stream *next_cap_stream;
1414 		struct bt_bap_stream *next_bap_stream;
1415 
1416 		proc_param = get_next_proc_param(active_proc);
1417 		if (proc_param != NULL) {
1418 			next_cap_stream = proc_param->stream;
1419 			next_bap_stream = &next_cap_stream->bap_stream;
1420 
1421 			active_proc->proc_initiated_cnt++;
1422 			proc_param->in_progress = true;
1423 
1424 			err = bt_bap_stream_connect(next_bap_stream);
1425 			if (err == 0 || err == -EALREADY) {
1426 				if (err == -EALREADY) {
1427 					proc_param->in_progress = false;
1428 				}
1429 				/* Pending connected - wait for connected callback */
1430 			} else if (err != 0) {
1431 				LOG_DBG("Failed to connect stream %p: %d", next_cap_stream, err);
1432 
1433 				bt_cap_common_abort_proc(next_bap_stream->conn, err);
1434 				cap_initiator_unicast_audio_proc_complete();
1435 			}
1436 		} /* else pending connection - wait for connected callback */
1437 
1438 		return;
1439 	}
1440 
1441 	/* All streams connected - Start sending the receiver start ready for all source
1442 	 * ASEs. For sink ASEs it is the responsibility of the unicast server to do the
1443 	 * receiver start ready operation. If there are no source ASEs then we just wait.
1444 	 */
1445 	bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_START);
1446 	proc_param = get_next_proc_param(active_proc);
1447 	if (proc_param == NULL) {
1448 		/* If proc_param is NULL then this step is a no-op and we can skip to the next step
1449 		 */
1450 		bt_cap_initiator_started(active_proc->proc_param.initiator[0].stream);
1451 
1452 		return;
1453 	}
1454 
1455 	bap_stream = &proc_param->stream->bap_stream;
1456 	if (stream_is_dir(bap_stream, BT_AUDIO_DIR_SOURCE)) {
1457 		proc_param->in_progress = true;
1458 
1459 		err = bt_bap_stream_start(bap_stream);
1460 		if (err != 0) {
1461 			LOG_DBG("Failed to start stream %p: %d", proc_param->stream, err);
1462 
1463 			bt_cap_common_abort_proc(bap_stream->conn, err);
1464 			cap_initiator_unicast_audio_proc_complete();
1465 
1466 			return;
1467 		}
1468 	}
1469 }
1470 
bt_cap_initiator_started(struct bt_cap_stream * cap_stream)1471 void bt_cap_initiator_started(struct bt_cap_stream *cap_stream)
1472 {
1473 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
1474 
1475 	LOG_DBG("cap_stream %p", cap_stream);
1476 
1477 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
1478 		/* State change happened outside of a procedure; ignore */
1479 		return;
1480 	}
1481 
1482 	/* Streams may go into the streaming state while we are connecting or starting them */
1483 	if (bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_CONNECT)) {
1484 		/* If we are still connecting the streams, we terminate early as to not perform any
1485 		 * start operations until all streams are connected
1486 		 */
1487 		return;
1488 	} else if (!bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_START)) {
1489 		/* Unexpected callback - Abort */
1490 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
1491 	} else {
1492 		update_proc_done_cnt(active_proc);
1493 
1494 		LOG_DBG("Stream %p started (%zu/%zu streams done)", cap_stream,
1495 			active_proc->proc_done_cnt, active_proc->proc_cnt);
1496 	}
1497 
1498 	if (!bt_cap_common_proc_is_done()) {
1499 		struct bt_cap_initiator_proc_param *proc_param;
1500 		struct bt_cap_stream *next_cap_stream;
1501 		struct bt_bap_stream *next_bap_stream;
1502 
1503 		proc_param = get_next_proc_param(active_proc);
1504 		if (proc_param != NULL) {
1505 			next_cap_stream = proc_param->stream;
1506 			next_bap_stream = &next_cap_stream->bap_stream;
1507 
1508 			if (stream_is_dir(next_bap_stream, BT_AUDIO_DIR_SOURCE)) {
1509 				int err;
1510 
1511 				proc_param->in_progress = true;
1512 
1513 				err = bt_bap_stream_start(next_bap_stream);
1514 				if (err != 0) {
1515 					LOG_DBG("Failed to start stream %p: %d", next_cap_stream,
1516 						err);
1517 
1518 					/* End and mark procedure as aborted.
1519 					 * If we have sent any requests over air, we will abort
1520 					 * once all sent requests has completed
1521 					 */
1522 					bt_cap_common_abort_proc(next_bap_stream->conn, err);
1523 					cap_initiator_unicast_audio_proc_complete();
1524 
1525 					return;
1526 				}
1527 			}
1528 		} /* else await notifications from server */
1529 
1530 		/* Return to await for response from server */
1531 		return;
1532 	}
1533 
1534 	cap_initiator_unicast_audio_proc_complete();
1535 }
1536 
can_update_metadata(const struct bt_bap_stream * bap_stream)1537 static bool can_update_metadata(const struct bt_bap_stream *bap_stream)
1538 {
1539 	return stream_is_in_state(bap_stream, BT_BAP_EP_STATE_ENABLING) ||
1540 	       stream_is_in_state(bap_stream, BT_BAP_EP_STATE_STREAMING);
1541 }
1542 
valid_unicast_audio_update_param(const struct bt_cap_unicast_audio_update_param * param)1543 static bool valid_unicast_audio_update_param(const struct bt_cap_unicast_audio_update_param *param)
1544 {
1545 	struct bt_bap_unicast_group *unicast_group = NULL;
1546 
1547 	CHECKIF(param == NULL) {
1548 		LOG_DBG("param is NULL");
1549 		return false;
1550 	}
1551 
1552 	CHECKIF(param->count == 0) {
1553 		LOG_DBG("Invalid param->count: %u", param->count);
1554 		return false;
1555 	}
1556 
1557 	CHECKIF(param->stream_params == NULL) {
1558 		LOG_DBG("param->stream_params is NULL");
1559 		return false;
1560 	}
1561 
1562 	CHECKIF(param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
1563 		LOG_DBG("param->count (%zu) is larger than "
1564 			"CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT (%d)",
1565 			param->count, CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT);
1566 		return false;
1567 	}
1568 
1569 	for (size_t i = 0U; i < param->count; i++) {
1570 		const struct bt_cap_unicast_audio_update_stream_param *stream_param =
1571 			&param->stream_params[i];
1572 		const struct bt_cap_stream *cap_stream = stream_param->stream;
1573 		const struct bt_bap_stream *bap_stream;
1574 		struct bt_conn *conn;
1575 
1576 		CHECKIF(cap_stream == NULL) {
1577 			LOG_DBG("param->stream_params[%zu] is NULL", i);
1578 			return false;
1579 		}
1580 
1581 		bap_stream = &cap_stream->bap_stream;
1582 		conn = bap_stream->conn;
1583 		CHECKIF(conn == NULL) {
1584 			LOG_DBG("param->stream_params[%zu].stream->bap_stream.conn is NULL", i);
1585 
1586 			return -EINVAL;
1587 		}
1588 
1589 		CHECKIF(bap_stream->group == NULL) {
1590 			LOG_DBG("param->stream_params[%zu] is not in a unicast group", i);
1591 			return false;
1592 		}
1593 
1594 		/* Use the group of the first stream for comparison */
1595 		if (unicast_group == NULL) {
1596 			unicast_group = bap_stream->group;
1597 		} else {
1598 			CHECKIF(bap_stream->group != unicast_group) {
1599 				LOG_DBG("param->stream_params[%zu] is not in this group %p", i,
1600 					unicast_group);
1601 				return false;
1602 			}
1603 		}
1604 
1605 		if (!can_update_metadata(bap_stream)) {
1606 			LOG_DBG("param->stream_params[%zu].stream is not in right state to be "
1607 				"updated",
1608 				i);
1609 
1610 			return false;
1611 		}
1612 
1613 		if (!cap_initiator_valid_metadata(stream_param->meta, stream_param->meta_len)) {
1614 			LOG_DBG("param->stream_params[%zu] invalid metadata", i);
1615 
1616 			return false;
1617 		}
1618 
1619 		for (size_t j = 0U; j < i; j++) {
1620 			if (param->stream_params[j].stream == cap_stream) {
1621 				LOG_DBG("param->stream_params[%zu] (%p) is "
1622 					"duplicated by "
1623 					"param->stream_params[%zu] (%p)",
1624 					j, param->stream_params[j].stream, i, cap_stream);
1625 				return false;
1626 			}
1627 		}
1628 	}
1629 
1630 	return true;
1631 }
1632 
bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param * param)1633 int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param *param)
1634 {
1635 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
1636 	struct bt_cap_initiator_proc_param *proc_param;
1637 	struct bt_bap_stream *bap_stream;
1638 	const uint8_t *meta;
1639 	size_t meta_len;
1640 	int err;
1641 
1642 	if (bt_cap_common_proc_is_active()) {
1643 		LOG_DBG("A CAP procedure is already in progress");
1644 
1645 		return -EBUSY;
1646 	}
1647 
1648 	if (!valid_unicast_audio_update_param(param)) {
1649 		return -EINVAL;
1650 	}
1651 
1652 	for (size_t i = 0U; i < param->count; i++) {
1653 		const struct bt_cap_unicast_audio_update_stream_param *stream_param =
1654 			&param->stream_params[i];
1655 		struct bt_cap_stream *cap_stream = stream_param->stream;
1656 
1657 		/* Ensure that ops are registered before any procedures are started */
1658 		bt_cap_stream_ops_register_bap(cap_stream);
1659 
1660 		active_proc->proc_param.initiator[i].stream = cap_stream;
1661 		active_proc->proc_param.initiator[i].meta_update.meta_len = stream_param->meta_len;
1662 		memcpy(&active_proc->proc_param.initiator[i].meta_update.meta, stream_param->meta,
1663 		       stream_param->meta_len);
1664 	}
1665 
1666 	bt_cap_common_start_proc(BT_CAP_COMMON_PROC_TYPE_UPDATE, param->count);
1667 	bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_META_UPDATE);
1668 
1669 	proc_param = get_next_proc_param(active_proc);
1670 	__ASSERT(proc_param != NULL, "proc is not done, but could not get next proc_param");
1671 
1672 	bap_stream = &proc_param->stream->bap_stream;
1673 	meta_len = proc_param->meta_update.meta_len;
1674 	meta = proc_param->meta_update.meta;
1675 	active_proc->proc_initiated_cnt++;
1676 	proc_param->in_progress = true;
1677 
1678 	err = bt_bap_stream_metadata(bap_stream, meta, meta_len);
1679 	if (err != 0) {
1680 		LOG_DBG("Failed to update metadata for stream %p: %d", proc_param->stream, err);
1681 
1682 		bt_cap_common_clear_active_proc();
1683 	}
1684 
1685 	return err;
1686 }
1687 
bt_cap_initiator_unicast_audio_cancel(void)1688 int bt_cap_initiator_unicast_audio_cancel(void)
1689 {
1690 	if (!bt_cap_common_proc_is_active() && !bt_cap_common_proc_is_aborted()) {
1691 		LOG_DBG("No CAP procedure is in progress");
1692 
1693 		return -EALREADY;
1694 	}
1695 
1696 	bt_cap_common_abort_proc(NULL, -ECANCELED);
1697 	cap_initiator_unicast_audio_proc_complete();
1698 
1699 	return 0;
1700 }
1701 
bt_cap_initiator_metadata_updated(struct bt_cap_stream * cap_stream)1702 void bt_cap_initiator_metadata_updated(struct bt_cap_stream *cap_stream)
1703 {
1704 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
1705 
1706 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
1707 		/* State change happened outside of a procedure; ignore */
1708 		return;
1709 	}
1710 
1711 	if (!bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_META_UPDATE)) {
1712 		/* Unexpected callback - Abort */
1713 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
1714 	} else {
1715 		update_proc_done_cnt(active_proc);
1716 
1717 		LOG_DBG("Stream %p QoS metadata updated (%zu/%zu streams done)", cap_stream,
1718 			active_proc->proc_done_cnt, active_proc->proc_cnt);
1719 	}
1720 
1721 	if (bt_cap_common_proc_is_aborted()) {
1722 		if (bt_cap_common_proc_all_handled()) {
1723 			cap_initiator_unicast_audio_proc_complete();
1724 		}
1725 
1726 		return;
1727 	}
1728 
1729 	if (!bt_cap_common_proc_is_done()) {
1730 		const size_t proc_done_cnt = active_proc->proc_done_cnt;
1731 		struct bt_cap_initiator_proc_param *proc_param;
1732 		struct bt_cap_stream *next_cap_stream;
1733 		struct bt_bap_stream *bap_stream;
1734 		const uint8_t *meta;
1735 		size_t meta_len;
1736 		int err;
1737 
1738 		proc_param = &active_proc->proc_param.initiator[proc_done_cnt];
1739 		meta_len = proc_param->meta_update.meta_len;
1740 		meta = proc_param->meta_update.meta;
1741 		next_cap_stream = proc_param->stream;
1742 		bap_stream = &next_cap_stream->bap_stream;
1743 		active_proc->proc_initiated_cnt++;
1744 		proc_param->in_progress = true;
1745 
1746 		err = bt_bap_stream_metadata(bap_stream, meta, meta_len);
1747 		if (err != 0) {
1748 			LOG_DBG("Failed to update metadata for stream %p: %d", next_cap_stream,
1749 				err);
1750 
1751 			bt_cap_common_abort_proc(bap_stream->conn, err);
1752 			cap_initiator_unicast_audio_proc_complete();
1753 		}
1754 
1755 		return;
1756 	}
1757 
1758 	cap_initiator_unicast_audio_proc_complete();
1759 }
1760 
can_release_stream(const struct bt_bap_stream * bap_stream)1761 static bool can_release_stream(const struct bt_bap_stream *bap_stream)
1762 {
1763 	enum bt_bap_ep_state state;
1764 
1765 	if (bap_stream->conn == NULL) {
1766 		return false;
1767 	}
1768 
1769 	state = stream_get_state(bap_stream);
1770 
1771 	/* We cannot release idle endpoints.
1772 	 * We do not know if we can release endpoints in the Codec Configured state as servers may
1773 	 * cache it, so treat it as idle
1774 	 */
1775 	return state != BT_BAP_EP_STATE_IDLE && state != BT_BAP_EP_STATE_CODEC_CONFIGURED;
1776 }
1777 
can_disable_stream(const struct bt_bap_stream * bap_stream)1778 static bool can_disable_stream(const struct bt_bap_stream *bap_stream)
1779 {
1780 	enum bt_bap_ep_state state;
1781 
1782 	if (bap_stream->conn == NULL) {
1783 		return false;
1784 	}
1785 
1786 	state = stream_get_state(bap_stream);
1787 
1788 	return state == BT_BAP_EP_STATE_STREAMING || state == BT_BAP_EP_STATE_ENABLING;
1789 }
1790 
can_stop_stream(const struct bt_bap_stream * bap_stream)1791 static bool can_stop_stream(const struct bt_bap_stream *bap_stream)
1792 {
1793 	enum bt_iso_state iso_state;
1794 
1795 	if (bap_stream->conn == NULL) {
1796 		return false;
1797 	}
1798 
1799 	if (stream_is_dir(bap_stream, BT_AUDIO_DIR_SINK)) {
1800 		return false;
1801 	}
1802 
1803 	iso_state = bap_stream_get_iso_state(bap_stream);
1804 	if (iso_state != BT_ISO_STATE_CONNECTED && iso_state != BT_ISO_STATE_CONNECTING) {
1805 		return false;
1806 	}
1807 
1808 	return stream_is_in_state(bap_stream, BT_BAP_EP_STATE_DISABLING);
1809 }
1810 
valid_unicast_audio_stop_param(const struct bt_cap_unicast_audio_stop_param * param)1811 static bool valid_unicast_audio_stop_param(const struct bt_cap_unicast_audio_stop_param *param)
1812 {
1813 	struct bt_bap_unicast_group *unicast_group = NULL;
1814 
1815 	CHECKIF(param == NULL) {
1816 		LOG_DBG("param is NULL");
1817 		return false;
1818 	}
1819 
1820 	CHECKIF(param->count == 0) {
1821 		LOG_DBG("Invalid param->count: %u", param->count);
1822 		return false;
1823 	}
1824 
1825 	CHECKIF(param->streams == NULL) {
1826 		LOG_DBG("param->streams is NULL");
1827 		return false;
1828 	}
1829 
1830 	CHECKIF(param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
1831 		LOG_DBG("param->count (%zu) is larger than "
1832 			"CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT (%d)",
1833 			param->count, CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT);
1834 		return false;
1835 	}
1836 
1837 	for (size_t i = 0U; i < param->count; i++) {
1838 		const struct bt_cap_stream *cap_stream = param->streams[i];
1839 		const struct bt_bap_stream *bap_stream;
1840 		struct bt_conn *conn;
1841 
1842 		CHECKIF(cap_stream == NULL) {
1843 			LOG_DBG("param->streams[%zu] is NULL", i);
1844 			return false;
1845 		}
1846 
1847 		bap_stream = &cap_stream->bap_stream;
1848 		conn = bap_stream->conn;
1849 		CHECKIF(conn == NULL) {
1850 			LOG_DBG("param->streams[%zu]->bap_stream.conn is NULL", i);
1851 
1852 			return -EINVAL;
1853 		}
1854 
1855 		if (param->type == BT_CAP_SET_TYPE_CSIP) {
1856 			struct bt_cap_common_client *client = bt_cap_common_get_client_by_acl(conn);
1857 
1858 			if (client->csis_inst == NULL) {
1859 				LOG_DBG("param->streams[%zu]->bap_stream.conn not part of a "
1860 					"coordinated set",
1861 					i);
1862 
1863 				return false;
1864 			}
1865 		}
1866 
1867 		CHECKIF(bap_stream->group == NULL) {
1868 			LOG_DBG("param->streams[%zu] is not in a unicast group", i);
1869 			return false;
1870 		}
1871 
1872 		/* Use the group of the first stream for comparison */
1873 		if (unicast_group == NULL) {
1874 			unicast_group = bap_stream->group;
1875 		} else {
1876 			CHECKIF(bap_stream->group != unicast_group) {
1877 				LOG_DBG("param->streams[%zu] is not in this group %p", i,
1878 					unicast_group);
1879 				return false;
1880 			}
1881 		}
1882 
1883 		for (size_t j = 0U; j < i; j++) {
1884 			if (param->streams[j] == cap_stream) {
1885 				LOG_DBG("param->stream_params[%zu] (%p) is "
1886 					"duplicated by "
1887 					"param->stream_params[%zu] (%p)",
1888 					j, param->streams[j], i, cap_stream);
1889 				return false;
1890 			}
1891 		}
1892 	}
1893 
1894 	return true;
1895 }
1896 
bt_cap_initiator_unicast_audio_stop(const struct bt_cap_unicast_audio_stop_param * param)1897 int bt_cap_initiator_unicast_audio_stop(const struct bt_cap_unicast_audio_stop_param *param)
1898 {
1899 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
1900 	bool can_release = false;
1901 	bool can_disable = false;
1902 	bool can_stop = false;
1903 	int err;
1904 
1905 	if (bt_cap_common_proc_is_active()) {
1906 		LOG_DBG("A CAP procedure is already in progress");
1907 
1908 		return -EBUSY;
1909 	}
1910 
1911 	if (!valid_unicast_audio_stop_param(param)) {
1912 		return -EINVAL;
1913 	}
1914 
1915 	for (size_t i = 0U; i < param->count; i++) {
1916 		struct bt_cap_stream *cap_stream = param->streams[i];
1917 		struct bt_bap_stream *bap_stream = &cap_stream->bap_stream;
1918 
1919 		/* Ensure that ops are registered before any procedures are started */
1920 		bt_cap_stream_ops_register_bap(cap_stream);
1921 
1922 		active_proc->proc_param.initiator[i].stream = cap_stream;
1923 		active_proc->proc_param.initiator[i].stop.release = param->release;
1924 
1925 		if (!can_disable && can_disable_stream(bap_stream)) {
1926 			can_disable = true;
1927 		}
1928 
1929 		if (!can_stop && can_stop_stream(bap_stream)) {
1930 			can_stop = true;
1931 		}
1932 
1933 		if (!can_release && param->release && can_release_stream(bap_stream)) {
1934 			can_release = true;
1935 		}
1936 	}
1937 
1938 	if (!can_disable && !can_stop && !can_release) {
1939 		LOG_DBG("Cannot %s any streams", !can_disable ? "disable"
1940 						 : !can_stop  ? "stop"
1941 							      : "release");
1942 		return -EALREADY;
1943 	}
1944 
1945 	bt_cap_common_start_proc(BT_CAP_COMMON_PROC_TYPE_STOP, param->count);
1946 	/** TODO: If this is a CSIP set, then the order of the procedures may
1947 	 * not match the order in the parameters, and the CSIP ordered access
1948 	 * procedure should be used.
1949 	 */
1950 
1951 	if (can_disable) {
1952 		struct bt_cap_initiator_proc_param *proc_param;
1953 		struct bt_bap_stream *bap_stream;
1954 
1955 		bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_DISABLE);
1956 
1957 		proc_param = get_next_proc_param(active_proc);
1958 		__ASSERT(proc_param != NULL,
1959 			 "proc is not started, but could not get next proc_param");
1960 		bap_stream = &proc_param->stream->bap_stream;
1961 		active_proc->proc_initiated_cnt++;
1962 		proc_param->in_progress = true;
1963 
1964 		err = bt_bap_stream_disable(bap_stream);
1965 		if (err != 0) {
1966 			LOG_DBG("Failed to disable bap_stream %p: %d", proc_param->stream, err);
1967 
1968 			bt_cap_common_clear_active_proc();
1969 		}
1970 	} else if (can_stop) {
1971 		struct bt_cap_initiator_proc_param *proc_param;
1972 		struct bt_bap_stream *bap_stream;
1973 
1974 		bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_STOP);
1975 
1976 		proc_param = get_next_proc_param(active_proc);
1977 		__ASSERT(proc_param != NULL,
1978 			 "proc is not started, but could not get next proc_param");
1979 		bap_stream = &proc_param->stream->bap_stream;
1980 		active_proc->proc_initiated_cnt++;
1981 		proc_param->in_progress = true;
1982 
1983 		err = bt_bap_stream_stop(bap_stream);
1984 		if (err != 0) {
1985 			LOG_DBG("Failed to stop bap_stream %p: %d", proc_param->stream, err);
1986 
1987 			bt_cap_common_clear_active_proc();
1988 		}
1989 	} else {
1990 		struct bt_cap_initiator_proc_param *proc_param;
1991 		struct bt_bap_stream *bap_stream;
1992 
1993 		bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_RELEASE);
1994 
1995 		proc_param = get_next_proc_param(active_proc);
1996 		__ASSERT(proc_param != NULL,
1997 			 "proc is not started, but could not get next proc_param");
1998 		bap_stream = &proc_param->stream->bap_stream;
1999 		active_proc->proc_initiated_cnt++;
2000 		proc_param->in_progress = true;
2001 
2002 		err = bt_bap_stream_release(bap_stream);
2003 		if (err != 0) {
2004 			LOG_DBG("Failed to release bap_stream %p: %d", proc_param->stream, err);
2005 
2006 			bt_cap_common_clear_active_proc();
2007 		}
2008 	}
2009 
2010 	return err;
2011 }
2012 
bt_cap_initiator_disabled(struct bt_cap_stream * cap_stream)2013 void bt_cap_initiator_disabled(struct bt_cap_stream *cap_stream)
2014 {
2015 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
2016 
2017 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
2018 		/* State change happened outside of a procedure; ignore */
2019 		return;
2020 	}
2021 
2022 	if (!bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_DISABLE)) {
2023 		/* Unexpected callback - Abort */
2024 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
2025 	} else {
2026 		update_proc_done_cnt(active_proc);
2027 
2028 		LOG_DBG("Stream %p disabled (%zu/%zu streams done)", cap_stream,
2029 			active_proc->proc_done_cnt, active_proc->proc_cnt);
2030 	}
2031 
2032 	if (bt_cap_common_proc_is_aborted()) {
2033 		if (bt_cap_common_proc_all_handled()) {
2034 			cap_initiator_unicast_audio_proc_complete();
2035 		}
2036 
2037 		return;
2038 	}
2039 
2040 	if (!bt_cap_common_proc_is_done()) {
2041 		struct bt_cap_initiator_proc_param *proc_param;
2042 		struct bt_cap_stream *next_cap_stream;
2043 		struct bt_bap_stream *next_bap_stream;
2044 		int err;
2045 
2046 		proc_param = get_next_proc_param(active_proc);
2047 		__ASSERT(proc_param != NULL, "proc is not done, but could not get next proc_param");
2048 		next_cap_stream = proc_param->stream;
2049 		next_bap_stream = &next_cap_stream->bap_stream;
2050 		active_proc->proc_initiated_cnt++;
2051 		proc_param->in_progress = true;
2052 
2053 		err = bt_bap_stream_disable(next_bap_stream);
2054 		if (err != 0) {
2055 			LOG_DBG("Failed to disable stream %p: %d", next_cap_stream, err);
2056 
2057 			bt_cap_common_abort_proc(next_bap_stream->conn, err);
2058 			cap_initiator_unicast_audio_proc_complete();
2059 		}
2060 	} else {
2061 		struct bt_cap_initiator_proc_param *proc_param;
2062 		struct bt_cap_stream *next_cap_stream;
2063 		struct bt_bap_stream *next_bap_stream;
2064 		int err;
2065 
2066 		bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_STOP);
2067 
2068 		proc_param = get_next_proc_param(active_proc);
2069 		if (proc_param == NULL) {
2070 			/* If proc_param is NULL then this step is a no-op and we can skip to the
2071 			 * next step
2072 			 */
2073 			bt_cap_initiator_stopped(active_proc->proc_param.initiator[0].stream);
2074 
2075 			return;
2076 		}
2077 
2078 		next_cap_stream = proc_param->stream;
2079 		next_bap_stream = &next_cap_stream->bap_stream;
2080 		active_proc->proc_initiated_cnt++;
2081 		proc_param->in_progress = true;
2082 
2083 		err = bt_bap_stream_stop(next_bap_stream);
2084 		if (err != 0 && err != -EALREADY) {
2085 			LOG_DBG("Failed to stop stream %p: %d", next_cap_stream, err);
2086 
2087 			bt_cap_common_abort_proc(next_bap_stream->conn, err);
2088 			cap_initiator_unicast_audio_proc_complete();
2089 		} else if (err == -EALREADY) {
2090 			proc_param->in_progress = false;
2091 		} /* else wait for server notification*/
2092 	}
2093 }
2094 
bt_cap_initiator_stopped(struct bt_cap_stream * cap_stream)2095 void bt_cap_initiator_stopped(struct bt_cap_stream *cap_stream)
2096 {
2097 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
2098 
2099 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
2100 		/* State change happened outside of a procedure; ignore */
2101 		return;
2102 	}
2103 
2104 	if (!bt_cap_common_proc_is_type(BT_CAP_COMMON_PROC_TYPE_STOP)) {
2105 		/* Unexpected callback - Abort */
2106 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
2107 	} else {
2108 		if (bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_STOP)) {
2109 			update_proc_done_cnt(active_proc);
2110 
2111 			LOG_DBG("Stream %p stopped (%zu/%zu streams done)", cap_stream,
2112 				active_proc->proc_done_cnt, active_proc->proc_cnt);
2113 		} else {
2114 			/* We are still doing disable - Wait for those to be done, as stopped may
2115 			 * also be called when we are disabling sink ASEs
2116 			 */
2117 			return;
2118 		}
2119 	}
2120 
2121 	if (bt_cap_common_proc_is_aborted()) {
2122 		if (bt_cap_common_proc_all_handled()) {
2123 			cap_initiator_unicast_audio_proc_complete();
2124 		}
2125 
2126 		return;
2127 	}
2128 
2129 	if (!bt_cap_common_proc_is_done()) {
2130 		struct bt_cap_initiator_proc_param *proc_param;
2131 		struct bt_cap_stream *next_cap_stream;
2132 		struct bt_bap_stream *next_bap_stream;
2133 		int err;
2134 
2135 		proc_param = get_next_proc_param(active_proc);
2136 		if (proc_param != NULL) {
2137 			next_cap_stream = proc_param->stream;
2138 			next_bap_stream = &next_cap_stream->bap_stream;
2139 
2140 			active_proc->proc_initiated_cnt++;
2141 			proc_param->in_progress = true;
2142 
2143 			err = bt_bap_stream_stop(next_bap_stream);
2144 			if (err != 0 && err != -EALREADY) {
2145 				LOG_DBG("Failed to stop stream %p: %d", next_cap_stream, err);
2146 
2147 				bt_cap_common_abort_proc(next_bap_stream->conn, err);
2148 				cap_initiator_unicast_audio_proc_complete();
2149 			} else if (err == -EALREADY) {
2150 				proc_param->in_progress = false;
2151 			}
2152 		} /* else await notification from server */
2153 	} else {
2154 		/* We are done stopping streams now - We mark the next subproc. If
2155 		 * get_next_proc_param returns a NULL value it means that we are complete done. If
2156 		 * it returns a non-NULL value, it means that we need to start releasing streams.
2157 		 * However, since the QoS Configured state is better suited to trigger this, we
2158 		 * simply wait until bt_cap_initiator_qos_configured is called.
2159 		 */
2160 		struct bt_cap_initiator_proc_param *proc_param;
2161 
2162 		if (!bt_cap_common_proc_is_done()) {
2163 			/* We are still disabling or stopping some */
2164 			return;
2165 		}
2166 
2167 		bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_RELEASE);
2168 
2169 		proc_param = get_next_proc_param(active_proc);
2170 		if (proc_param == NULL) {
2171 			/* If proc_param is NULL then this step is a no-op and we can finish the
2172 			 * procedure
2173 			 */
2174 			cap_initiator_unicast_audio_proc_complete();
2175 
2176 			return;
2177 		} /* wait for bt_cap_initiator_qos_configured */
2178 	}
2179 }
2180 
bt_cap_initiator_released(struct bt_cap_stream * cap_stream)2181 void bt_cap_initiator_released(struct bt_cap_stream *cap_stream)
2182 {
2183 	struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
2184 
2185 	if (!bt_cap_common_stream_in_active_proc(cap_stream)) {
2186 		/* State change happened outside of a procedure; ignore */
2187 		return;
2188 	}
2189 
2190 	if (!bt_cap_common_subproc_is_type(BT_CAP_COMMON_SUBPROC_TYPE_RELEASE)) {
2191 		/* Unexpected callback - Abort */
2192 		bt_cap_common_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
2193 	} else {
2194 		update_proc_done_cnt(active_proc);
2195 
2196 		LOG_DBG("Stream %p released (%zu/%zu streams done)", cap_stream,
2197 			active_proc->proc_done_cnt, active_proc->proc_cnt);
2198 	}
2199 
2200 	if (bt_cap_common_proc_is_aborted()) {
2201 		if (bt_cap_common_proc_all_handled()) {
2202 			cap_initiator_unicast_audio_proc_complete();
2203 		}
2204 
2205 		return;
2206 	}
2207 
2208 	if (!bt_cap_common_proc_is_done()) {
2209 		struct bt_cap_initiator_proc_param *proc_param;
2210 		struct bt_cap_stream *next_cap_stream;
2211 		struct bt_bap_stream *next_bap_stream;
2212 		int err;
2213 
2214 		proc_param = get_next_proc_param(active_proc);
2215 		__ASSERT(proc_param != NULL, "proc is not done, but could not get next proc_param");
2216 		next_cap_stream = proc_param->stream;
2217 		next_bap_stream = &next_cap_stream->bap_stream;
2218 		active_proc->proc_initiated_cnt++;
2219 		proc_param->in_progress = true;
2220 
2221 		err = bt_bap_stream_release(next_bap_stream);
2222 		if (err != 0) {
2223 			LOG_DBG("Failed to release stream %p: %d", next_cap_stream, err);
2224 
2225 			bt_cap_common_abort_proc(next_bap_stream->conn, err);
2226 			cap_initiator_unicast_audio_proc_complete();
2227 		}
2228 	} else {
2229 		cap_initiator_unicast_audio_proc_complete();
2230 	}
2231 }
2232 
2233 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
2234 
2235 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) && defined(CONFIG_BT_BAP_UNICAST_CLIENT)
2236 
bt_cap_initiator_unicast_to_broadcast(const struct bt_cap_unicast_to_broadcast_param * param,struct bt_cap_broadcast_source ** source)2237 int bt_cap_initiator_unicast_to_broadcast(
2238 	const struct bt_cap_unicast_to_broadcast_param *param,
2239 	struct bt_cap_broadcast_source **source)
2240 {
2241 	return -ENOSYS;
2242 }
2243 
bt_cap_initiator_broadcast_to_unicast(const struct bt_cap_broadcast_to_unicast_param * param,struct bt_bap_unicast_group ** unicast_group)2244 int bt_cap_initiator_broadcast_to_unicast(const struct bt_cap_broadcast_to_unicast_param *param,
2245 					  struct bt_bap_unicast_group **unicast_group)
2246 {
2247 	return -ENOSYS;
2248 }
2249 
2250 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE && CONFIG_BT_BAP_UNICAST_CLIENT */
2251