1 /* @file
2  * @brief Bluetooth ASCS
3  */
4 /*
5  * Copyright (c) 2020 Intel Corporation
6  * Copyright (c) 2022-2023 Nordic Semiconductor ASA
7  * Copyright (c) 2024 Demant A/S
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 #include <errno.h>
12 #include <stdbool.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 #include <string.h>
16 #include <sys/types.h>
17 
18 #include <zephyr/autoconf.h>
19 #include <zephyr/bluetooth/att.h>
20 #include <zephyr/bluetooth/audio/audio.h>
21 #include <zephyr/bluetooth/audio/bap.h>
22 #include <zephyr/bluetooth/audio/pacs.h>
23 #include <zephyr/bluetooth/bluetooth.h>
24 #include <zephyr/bluetooth/conn.h>
25 #include <zephyr/bluetooth/gatt.h>
26 #include <zephyr/bluetooth/hci_types.h>
27 #include <zephyr/bluetooth/iso.h>
28 #include <zephyr/bluetooth/uuid.h>
29 #include <zephyr/kernel.h>
30 #include <zephyr/logging/log.h>
31 #include <zephyr/net_buf.h>
32 #include <zephyr/sys/__assert.h>
33 #include <zephyr/sys/byteorder.h>
34 #include <zephyr/sys/check.h>
35 #include <zephyr/sys/util.h>
36 #include <zephyr/sys/util_macro.h>
37 #include <zephyr/toolchain.h>
38 
39 LOG_MODULE_REGISTER(bt_ascs, CONFIG_BT_ASCS_LOG_LEVEL);
40 
41 #include "common/bt_str.h"
42 #include "common/assert.h"
43 
44 #include "../host/att_internal.h"
45 
46 #include "ascs_internal.h"
47 #include "audio_internal.h"
48 #include "bap_endpoint.h"
49 #include "bap_iso.h"
50 #include "bap_stream.h"
51 #include "bap_unicast_server.h"
52 #include "pacs_internal.h"
53 #include "cap_internal.h"
54 
55 #define ASE_BUF_SEM_TIMEOUT K_MSEC(CONFIG_BT_ASCS_ASE_BUF_TIMEOUT)
56 
57 #define MAX_ASES_SESSIONS CONFIG_BT_MAX_CONN * \
58 				(CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + \
59 				 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT)
60 
61 #define NTF_HEADER_SIZE (3) /* opcode (1) + handle (2) */
62 
63 BUILD_ASSERT(CONFIG_BT_ASCS_MAX_ACTIVE_ASES <= MAX(MAX_ASES_SESSIONS,
64 						   CONFIG_BT_ISO_MAX_CHAN),
65 	     "Max active ASEs are set to more than actual number of ASEs or ISOs");
66 
67 #if defined(CONFIG_BT_BAP_UNICAST_SERVER)
68 
69 #define ASE_ID(_ase) ase->ep.status.id
70 #define ASE_DIR(_id) \
71 	(_id > CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT ? BT_AUDIO_DIR_SOURCE : BT_AUDIO_DIR_SINK)
72 #define ASE_UUID(_id) \
73 	(_id > CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT ? BT_UUID_ASCS_ASE_SRC : BT_UUID_ASCS_ASE_SNK)
74 #define ASE_COUNT (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT)
75 #define BT_BAP_ASCS_RSP_NULL ((struct bt_bap_ascs_rsp[]) { BT_BAP_ASCS_RSP(0, 0) })
76 
77 struct bt_ascs_ase {
78 	struct bt_conn *conn;
79 	struct bt_bap_ep ep;
80 	const struct bt_gatt_attr *attr;
81 	struct k_work_delayable disconnect_work;
82 	struct k_work_delayable state_transition_work;
83 	enum bt_bap_ep_state state_pending;
84 	bool unexpected_iso_link_loss;
85 };
86 
87 struct bt_ascs {
88 	/* Whether the service has been registered or not */
89 	bool registered;
90 
91 	struct bt_ascs_ase ase_pool[CONFIG_BT_ASCS_MAX_ACTIVE_ASES];
92 } ascs;
93 
94 /* Minimum state size when in the codec configured state */
95 #define MIN_CONFIG_STATE_SIZE (1 + 1 + 1 + 1 + 1 + 2 + 3 + 3 + 3 + 3 + 5 + 1)
96 /* Minimum state size when in the QoS configured state */
97 #define MIN_QOS_STATE_SIZE    (1 + 1 + 1 + 1 + 3 + 1 + 1 + 2 + 1 + 2 + 3 + 1 + 1 + 1)
98 
99 /* Calculate the size requirement of the ASE BUF, based on the maximum possible
100  * size of the Codec Configured state or the QoS Configured state, as either
101  * of them can be the largest state
102  */
103 #define ASE_BUF_SIZE                                                                               \
104 	MIN(BT_ATT_MAX_ATTRIBUTE_LEN,                                                              \
105 	    MAX(MIN_CONFIG_STATE_SIZE + CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE,                   \
106 		MIN_QOS_STATE_SIZE + CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE))
107 
108 /* Verify that the prepare count is large enough to cover the maximum value we support a client
109  * writing
110  */
111 BUILD_ASSERT(
112 	(BT_ATT_BUF_SIZE - NTF_HEADER_SIZE) >= ASE_BUF_SIZE ||
113 		DIV_ROUND_UP(ASE_BUF_SIZE, (BT_ATT_BUF_SIZE - NTF_HEADER_SIZE)) <=
114 			CONFIG_BT_ATT_PREPARE_COUNT,
115 	"CONFIG_BT_ATT_PREPARE_COUNT not large enough to cover the maximum supported ASCS value");
116 
117 /* It is mandatory to support long writes in ASCS unconditionally, and thus
118  * CONFIG_BT_ATT_PREPARE_COUNT must be at least 1 to support the feature
119  */
120 BUILD_ASSERT(CONFIG_BT_ATT_PREPARE_COUNT > 0, "CONFIG_BT_ATT_PREPARE_COUNT shall be at least 1");
121 
122 static const struct bt_bap_unicast_server_cb *unicast_server_cb;
123 
124 static K_SEM_DEFINE(ase_buf_sem, 1, 1);
125 NET_BUF_SIMPLE_DEFINE_STATIC(ase_buf, ASE_BUF_SIZE);
126 
127 static int control_point_notify(struct bt_conn *conn, const void *data, uint16_t len);
128 static int ascs_ep_get_status(struct bt_bap_ep *ep, struct net_buf_simple *buf);
129 
ascs_app_rsp_warn_valid(const struct bt_bap_ascs_rsp * rsp)130 static void ascs_app_rsp_warn_valid(const struct bt_bap_ascs_rsp *rsp)
131 {
132 	/* Validate application error code */
133 	switch (rsp->code) {
134 	case BT_BAP_ASCS_RSP_CODE_SUCCESS:
135 	case BT_BAP_ASCS_RSP_CODE_CAP_UNSUPPORTED:
136 	case BT_BAP_ASCS_RSP_CODE_NO_MEM:
137 	case BT_BAP_ASCS_RSP_CODE_UNSPECIFIED:
138 	case BT_BAP_ASCS_RSP_CODE_CONF_UNSUPPORTED:
139 	case BT_BAP_ASCS_RSP_CODE_CONF_REJECTED:
140 	case BT_BAP_ASCS_RSP_CODE_METADATA_UNSUPPORTED:
141 	case BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED:
142 		break;
143 	default:
144 		LOG_WRN("Invalid application error code: %u", rsp->code);
145 		return;
146 	}
147 
148 	/* Validate application error code and reason combinations */
149 	switch (rsp->code) {
150 	case BT_BAP_ASCS_RSP_CODE_SUCCESS:
151 	case BT_BAP_ASCS_RSP_CODE_CAP_UNSUPPORTED:
152 	case BT_BAP_ASCS_RSP_CODE_NO_MEM:
153 	case BT_BAP_ASCS_RSP_CODE_UNSPECIFIED:
154 		if (rsp->reason != BT_BAP_ASCS_REASON_NONE) {
155 			LOG_WRN("Invalid reason %u for code %u", rsp->reason, rsp->code);
156 		}
157 		break;
158 	case BT_BAP_ASCS_RSP_CODE_CONF_UNSUPPORTED:
159 	case BT_BAP_ASCS_RSP_CODE_CONF_REJECTED:
160 		if (!IN_RANGE(rsp->reason, BT_BAP_ASCS_REASON_NONE, BT_BAP_ASCS_REASON_CIS)) {
161 			LOG_WRN("Invalid reason %u for code %u", rsp->reason, rsp->code);
162 		}
163 		break;
164 	case BT_BAP_ASCS_RSP_CODE_METADATA_UNSUPPORTED:
165 	case BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED:
166 		if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(rsp->metadata_type)) {
167 			LOG_WRN("Invalid metadata type %u for code %u", rsp->metadata_type,
168 				rsp->code);
169 		}
170 		break;
171 	default:
172 		break;
173 	}
174 }
175 
is_valid_ase_id(uint8_t ase_id)176 static bool is_valid_ase_id(uint8_t ase_id)
177 {
178 	return IN_RANGE(ase_id, 1, ASE_COUNT);
179 }
180 
ascs_ep_get_state(struct bt_bap_ep * ep)181 static enum bt_bap_ep_state ascs_ep_get_state(struct bt_bap_ep *ep)
182 {
183 	return ep->status.state;
184 }
185 
ase_free(struct bt_ascs_ase * ase)186 static void ase_free(struct bt_ascs_ase *ase)
187 {
188 	__ASSERT(ase && ase->conn, "Non-existing ASE");
189 
190 	LOG_DBG("conn %p ase %p id 0x%02x", (void *)ase->conn, ase, ase->ep.status.id);
191 
192 	if (ase->ep.iso != NULL) {
193 		bt_bap_iso_unbind_ep(ase->ep.iso, &ase->ep);
194 	}
195 
196 	bt_conn_unref(ase->conn);
197 	ase->conn = NULL;
198 
199 	(void)k_work_cancel_delayable(&ase->disconnect_work);
200 	(void)k_work_cancel_delayable(&ase->state_transition_work);
201 }
202 
ase_state_notify(struct bt_ascs_ase * ase)203 static int ase_state_notify(struct bt_ascs_ase *ase)
204 {
205 	struct bt_conn *conn = ase->conn;
206 	struct bt_conn_info conn_info;
207 	uint16_t max_ntf_size;
208 	uint16_t ntf_size;
209 	int err;
210 
211 	__ASSERT_NO_MSG(conn != NULL);
212 
213 	err = bt_conn_get_info(conn, &conn_info);
214 	__ASSERT_NO_MSG(err == 0);
215 
216 	if (conn_info.state != BT_CONN_STATE_CONNECTED ||
217 	    !bt_gatt_is_subscribed(conn, ase->attr, BT_GATT_CCC_NOTIFY)) {
218 		return 0;
219 	}
220 
221 	err = k_sem_take(&ase_buf_sem, ASE_BUF_SEM_TIMEOUT);
222 	if (err != 0) {
223 		LOG_WRN("Failed to take ase_buf_sem: %d", err);
224 
225 		return err;
226 	}
227 
228 	ascs_ep_get_status(&ase->ep, &ase_buf);
229 
230 	max_ntf_size = bt_audio_get_max_ntf_size(conn);
231 
232 	ntf_size = MIN(max_ntf_size, ase_buf.len);
233 	if (ntf_size < ase_buf.len) {
234 		LOG_DBG("Sending truncated notification (%u / %u)",
235 			ntf_size, ase_buf.len);
236 	}
237 
238 	err = bt_gatt_notify(conn, ase->attr, ase_buf.data, ntf_size);
239 
240 	k_sem_give(&ase_buf_sem);
241 
242 	return err;
243 }
244 
ascs_disconnect_stream_work_handler(struct k_work * work)245 static void ascs_disconnect_stream_work_handler(struct k_work *work)
246 {
247 	struct k_work_delayable *d_work = k_work_delayable_from_work(work);
248 	struct bt_ascs_ase *ase = CONTAINER_OF(d_work, struct bt_ascs_ase,
249 					       disconnect_work);
250 	struct bt_bap_ep *ep = &ase->ep;
251 	struct bt_bap_stream *stream = ep->stream;
252 	struct bt_bap_stream *pair_stream;
253 
254 	__ASSERT(ep != NULL && ep->iso && stream != NULL,
255 		 "Invalid endpoint %p, iso %p or stream %p",
256 		 ep, ep == NULL ? NULL : ep->iso, stream);
257 
258 	if (ep->dir == BT_AUDIO_DIR_SINK) {
259 		pair_stream = ep->iso->tx.stream;
260 	} else {
261 		pair_stream = ep->iso->rx.stream;
262 	}
263 
264 	LOG_DBG("ase %p ep %p stream %p pair_stream %p",
265 		ase, ep, stream, pair_stream);
266 
267 	if (pair_stream != NULL) {
268 		struct bt_ascs_ase *pair_ase;
269 
270 		__ASSERT(pair_stream->ep != NULL, "Invalid pair_stream %p",
271 			 pair_stream);
272 
273 		if (pair_stream->ep->status.state == BT_BAP_EP_STATE_STREAMING) {
274 			/* Should not disconnect ISO if the stream is paired
275 			 * with another one in the streaming state
276 			 */
277 
278 			return;
279 		}
280 
281 		pair_ase = CONTAINER_OF(pair_stream->ep, struct bt_ascs_ase,
282 					ep);
283 
284 		/* Cancel pair ASE disconnect work if pending */
285 		(void)k_work_cancel_delayable(&pair_ase->disconnect_work);
286 	}
287 
288 	if (stream != NULL &&
289 	    ep->iso != NULL &&
290 	    (ep->iso->chan.state == BT_ISO_STATE_CONNECTED ||
291 	     ep->iso->chan.state == BT_ISO_STATE_CONNECTING)) {
292 		const int err = bt_bap_stream_disconnect(stream);
293 
294 		if (err != 0) {
295 			LOG_ERR("Failed to disconnect CIS %p: %d",
296 				stream, err);
297 		}
298 	}
299 }
300 
ascs_disconnect_stream(struct bt_bap_stream * stream)301 static int ascs_disconnect_stream(struct bt_bap_stream *stream)
302 {
303 	struct bt_ascs_ase *ase = CONTAINER_OF(stream->ep, struct bt_ascs_ase,
304 					       ep);
305 
306 	LOG_DBG("%p", stream);
307 
308 	return k_work_reschedule(&ase->disconnect_work,
309 				 K_MSEC(CONFIG_BT_ASCS_ISO_DISCONNECT_DELAY));
310 }
311 
ase_enter_state_idle(struct bt_ascs_ase * ase)312 static void ase_enter_state_idle(struct bt_ascs_ase *ase)
313 {
314 	struct bt_bap_stream *stream = ase->ep.stream;
315 	struct bt_bap_stream_ops *ops;
316 
317 	__ASSERT_NO_MSG(stream != NULL);
318 
319 	ase->ep.receiver_ready = false;
320 
321 	bt_bap_stream_detach(stream);
322 
323 	ops = stream->ops;
324 	if (ops != NULL && ops->released != NULL) {
325 		ops->released(stream);
326 	}
327 
328 	ase_free(ase);
329 }
330 
ase_enter_state_codec_configured(struct bt_ascs_ase * ase)331 static void ase_enter_state_codec_configured(struct bt_ascs_ase *ase)
332 {
333 	struct bt_bap_stream *stream = ase->ep.stream;
334 	struct bt_bap_stream_ops *ops;
335 
336 	__ASSERT_NO_MSG(stream != NULL);
337 
338 	ase->ep.receiver_ready = false;
339 
340 	ops = stream->ops;
341 	if (ops != NULL && ops->configured != NULL) {
342 		ops->configured(stream, &ase->ep.qos_pref);
343 	}
344 }
345 
ase_enter_state_qos_configured(struct bt_ascs_ase * ase)346 static void ase_enter_state_qos_configured(struct bt_ascs_ase *ase)
347 {
348 	struct bt_bap_stream *stream = ase->ep.stream;
349 	struct bt_bap_stream_ops *ops;
350 
351 	__ASSERT_NO_MSG(stream != NULL);
352 
353 	ase->ep.receiver_ready = false;
354 
355 	ops = stream->ops;
356 	if (ops != NULL && ops->qos_set != NULL) {
357 		ops->qos_set(stream);
358 	}
359 }
360 
ase_enter_state_enabling(struct bt_ascs_ase * ase)361 static void ase_enter_state_enabling(struct bt_ascs_ase *ase)
362 {
363 	struct bt_bap_stream *stream = ase->ep.stream;
364 	struct bt_bap_stream_ops *ops;
365 
366 	__ASSERT_NO_MSG(stream != NULL);
367 
368 	ops = stream->ops;
369 	if (ops != NULL && ops->enabled != NULL) {
370 		ops->enabled(stream);
371 	}
372 
373 	/* SINK ASEs can autonomously go into the streaming state if the CIS is connected */
374 	if (ase->ep.dir == BT_AUDIO_DIR_SINK && ase->ep.receiver_ready && ase->ep.iso != NULL &&
375 	    ase->ep.iso->chan.state == BT_ISO_STATE_CONNECTED) {
376 		ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_STREAMING);
377 	}
378 }
379 
ase_enter_state_streaming(struct bt_ascs_ase * ase)380 static void ase_enter_state_streaming(struct bt_ascs_ase *ase)
381 {
382 	struct bt_bap_stream *stream = ase->ep.stream;
383 	struct bt_bap_stream_ops *ops;
384 
385 	__ASSERT_NO_MSG(stream != NULL);
386 
387 	ops = stream->ops;
388 	if (ops != NULL && ops->started != NULL) {
389 		ops->started(stream);
390 	}
391 }
392 
ase_metadata_updated(struct bt_ascs_ase * ase)393 static void ase_metadata_updated(struct bt_ascs_ase *ase)
394 {
395 	struct bt_bap_stream *stream = ase->ep.stream;
396 	struct bt_bap_stream_ops *ops;
397 
398 	__ASSERT_NO_MSG(stream != NULL);
399 
400 	ops = stream->ops;
401 	if (ops != NULL && ops->metadata_updated != NULL) {
402 		ops->metadata_updated(stream);
403 	}
404 }
405 
ase_exit_state_streaming(struct bt_ascs_ase * ase)406 static void ase_exit_state_streaming(struct bt_ascs_ase *ase)
407 {
408 	struct bt_bap_stream *stream = ase->ep.stream;
409 	struct bt_bap_stream_ops *ops;
410 	const enum bt_bap_ep_state next_state = ascs_ep_get_state(&ase->ep);
411 	uint8_t reason = ase->ep.reason;
412 
413 	__ASSERT_NO_MSG(stream != NULL);
414 
415 	if (reason == BT_HCI_ERR_SUCCESS) {
416 		/* Default to BT_HCI_ERR_UNSPECIFIED if no other reason is set */
417 		reason = BT_HCI_ERR_UNSPECIFIED;
418 	}
419 
420 	ops = stream->ops;
421 
422 	/*
423 	 * On link-loss we go from streaming state to QOS configured state,
424 	 * and it makes sense to do the disabled callback before entering the
425 	 * QOS configured state
426 	 */
427 	if (next_state == BT_BAP_EP_STATE_QOS_CONFIGURED) {
428 		if (ops != NULL && ops->disabled != NULL) {
429 			ops->disabled(stream);
430 		} else {
431 			LOG_WRN("No callback for disabled set");
432 		}
433 	}
434 
435 	if (ops != NULL && ops->stopped != NULL) {
436 		ops->stopped(stream, reason);
437 	} else {
438 		LOG_WRN("No callback for stopped set");
439 	}
440 }
441 
ase_exit_state_enabling(struct bt_ascs_ase * ase)442 static void ase_exit_state_enabling(struct bt_ascs_ase *ase)
443 {
444 	struct bt_bap_stream *stream = ase->ep.stream;
445 	struct bt_bap_stream_ops *ops;
446 	const enum bt_bap_ep_state next_state = ascs_ep_get_state(&ase->ep);
447 
448 	ops = stream->ops;
449 
450 	/*
451 	 * When the EP direction is BT_AUDIO_DIR_SOURCE the state machine goes from
452 	 * enabled to disabled where the disabled callback will be called,
453 	 * for BT_AUDIO_DIR_SINK we go from enabled to qos_configured,
454 	 * and logically we have to do the disabled callback first
455 	 */
456 	if (next_state == BT_BAP_EP_STATE_QOS_CONFIGURED && ase->ep.dir == BT_AUDIO_DIR_SINK) {
457 		if (ops != NULL && ops->disabled != NULL) {
458 			ops->disabled(stream);
459 		} else {
460 			LOG_WRN("No callback for disabled set");
461 		}
462 	}
463 }
464 
ase_enter_state_disabling(struct bt_ascs_ase * ase)465 static void ase_enter_state_disabling(struct bt_ascs_ase *ase)
466 {
467 	struct bt_bap_stream *stream = ase->ep.stream;
468 	struct bt_bap_stream_ops *ops;
469 
470 	__ASSERT_NO_MSG(stream != NULL);
471 
472 	ase->ep.receiver_ready = false;
473 
474 	ops = stream->ops;
475 	if (ops != NULL && ops->disabled != NULL) {
476 		ops->disabled(stream);
477 	}
478 }
479 
ase_enter_state_releasing(struct bt_ascs_ase * ase)480 static void ase_enter_state_releasing(struct bt_ascs_ase *ase)
481 {
482 	struct bt_bap_stream *stream = ase->ep.stream;
483 
484 	__ASSERT_NO_MSG(stream != NULL);
485 
486 	ase->ep.receiver_ready = false;
487 
488 	/* Either the client or the server may disconnect the CISes when entering the releasing
489 	 * state.
490 	 */
491 	if (bt_bap_stream_can_disconnect(stream)) {
492 		int err;
493 
494 		err = ascs_disconnect_stream(stream);
495 		if (err < 0) {
496 			LOG_ERR("Failed to disconnect stream %p: %d", stream, err);
497 		}
498 	} else {
499 		ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_IDLE);
500 	}
501 }
502 
state_transition_work_handler(struct k_work * work)503 static void state_transition_work_handler(struct k_work *work)
504 {
505 	struct k_work_delayable *d_work = k_work_delayable_from_work(work);
506 	struct bt_ascs_ase *ase = CONTAINER_OF(d_work, struct bt_ascs_ase, state_transition_work);
507 	const enum bt_bap_ep_state old_state = ascs_ep_get_state(&ase->ep);
508 	const enum bt_bap_ep_state new_state = ase->state_pending;
509 	int err;
510 
511 	ase->ep.status.state = new_state;
512 
513 	/* Notify ASE state */
514 	if (ase->conn != NULL) {
515 		err = ase_state_notify(ase);
516 		if (err == -ENOMEM) {
517 			struct bt_conn_info info;
518 			uint32_t retry_delay_ms;
519 
520 			/* Revert back to old state */
521 			ase->ep.status.state = old_state;
522 
523 			err = bt_conn_get_info(ase->conn, &info);
524 			__ASSERT_NO_MSG(err == 0);
525 
526 			retry_delay_ms = BT_CONN_INTERVAL_TO_MS(info.le.interval);
527 
528 			/* Reschedule the state transition */
529 			err = k_work_reschedule(d_work, K_MSEC(retry_delay_ms));
530 			if (err >= 0) {
531 				LOG_WRN("Out of buffers for ase state notification. "
532 					"Will retry in %dms", retry_delay_ms);
533 				return;
534 			}
535 		}
536 
537 		if (err < 0) {
538 			LOG_ERR("Failed to notify ASE state (err %d)", err);
539 		}
540 	}
541 
542 	LOG_DBG("ase %p ep %p id 0x%02x %s -> %s", ase, &ase->ep, ase->ep.status.id,
543 		bt_bap_ep_state_str(old_state), bt_bap_ep_state_str(new_state));
544 
545 	if (old_state == new_state) {
546 		switch (new_state) {
547 		case BT_BAP_EP_STATE_ENABLING:
548 		case BT_BAP_EP_STATE_STREAMING:
549 			ase_metadata_updated(ase);
550 			return;
551 		default:
552 			break;
553 		}
554 	}
555 
556 	/* Actions needed for exiting the old state */
557 	switch (old_state) {
558 	case BT_BAP_EP_STATE_STREAMING:
559 		ase_exit_state_streaming(ase);
560 		break;
561 	case BT_BAP_EP_STATE_ENABLING:
562 		ase_exit_state_enabling(ase);
563 		break;
564 	default:
565 		break;
566 	}
567 
568 	/* Actions needed for entering the new state */
569 	switch (new_state) {
570 	case BT_BAP_EP_STATE_IDLE:
571 		ase_enter_state_idle(ase);
572 		break;
573 	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
574 		ase_enter_state_codec_configured(ase);
575 		break;
576 	case BT_BAP_EP_STATE_QOS_CONFIGURED:
577 		ase_enter_state_qos_configured(ase);
578 		break;
579 	case BT_BAP_EP_STATE_ENABLING:
580 		ase_enter_state_enabling(ase);
581 		break;
582 	case BT_BAP_EP_STATE_STREAMING:
583 		ase_enter_state_streaming(ase);
584 		break;
585 	case BT_BAP_EP_STATE_DISABLING:
586 		ase_enter_state_disabling(ase);
587 		break;
588 	case BT_BAP_EP_STATE_RELEASING:
589 		ase_enter_state_releasing(ase);
590 		break;
591 	default:
592 		__ASSERT_PRINT("Invalid state %d", new_state);
593 	}
594 }
595 
ascs_ep_set_state(struct bt_bap_ep * ep,uint8_t state)596 int ascs_ep_set_state(struct bt_bap_ep *ep, uint8_t state)
597 {
598 	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
599 	const enum bt_bap_ep_state old_state = ascs_ep_get_state(&ase->ep);
600 	bool valid_state_transition = false;
601 	int err;
602 
603 	switch (state) {
604 	case BT_BAP_EP_STATE_IDLE:
605 		valid_state_transition = true;
606 		break;
607 	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
608 		switch (old_state) {
609 		case BT_BAP_EP_STATE_IDLE:
610 		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
611 		case BT_BAP_EP_STATE_QOS_CONFIGURED:
612 		case BT_BAP_EP_STATE_RELEASING:
613 			valid_state_transition = true;
614 			break;
615 		default:
616 			break;
617 		} break;
618 	case BT_BAP_EP_STATE_QOS_CONFIGURED:
619 		switch (old_state) {
620 		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
621 		case BT_BAP_EP_STATE_QOS_CONFIGURED:
622 			valid_state_transition = true;
623 			break;
624 		case BT_BAP_EP_STATE_DISABLING:
625 			valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SOURCE;
626 			break;
627 		case BT_BAP_EP_STATE_ENABLING:
628 		case BT_BAP_EP_STATE_STREAMING:
629 			/* Source ASE transition Streaming->QoS configured is valid on case of CIS
630 			 * link-loss.
631 			 */
632 			valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SINK ||
633 						 ase->unexpected_iso_link_loss;
634 			break;
635 		default:
636 			break;
637 		} break;
638 	case BT_BAP_EP_STATE_ENABLING:
639 		switch (old_state) {
640 		case BT_BAP_EP_STATE_QOS_CONFIGURED:
641 		case BT_BAP_EP_STATE_ENABLING:
642 			valid_state_transition = true;
643 			break;
644 		default:
645 			break;
646 		} break;
647 	case BT_BAP_EP_STATE_STREAMING:
648 		switch (old_state) {
649 		case BT_BAP_EP_STATE_ENABLING:
650 		case BT_BAP_EP_STATE_STREAMING:
651 			valid_state_transition = true;
652 			break;
653 		default:
654 			break;
655 		} break;
656 	case BT_BAP_EP_STATE_DISABLING:
657 		switch (old_state) {
658 		case BT_BAP_EP_STATE_ENABLING:
659 		case BT_BAP_EP_STATE_STREAMING:
660 			valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SOURCE;
661 			break;
662 		default:
663 			break;
664 		} break;
665 	case BT_BAP_EP_STATE_RELEASING:
666 		switch (old_state) {
667 		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
668 		case BT_BAP_EP_STATE_QOS_CONFIGURED:
669 		case BT_BAP_EP_STATE_ENABLING:
670 		case BT_BAP_EP_STATE_STREAMING:
671 			valid_state_transition = true;
672 			break;
673 		case BT_BAP_EP_STATE_DISABLING:
674 			valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SOURCE;
675 			break;
676 		default:
677 			break;
678 		} break;
679 	}
680 
681 	if (!valid_state_transition) {
682 		BT_ASSERT_MSG(false, "Invalid state transition: %s -> %s",
683 			      bt_bap_ep_state_str(old_state), bt_bap_ep_state_str(state));
684 
685 		return -EBADMSG;
686 	}
687 
688 	ase->state_pending = state;
689 
690 	err = k_work_schedule(&ase->state_transition_work, K_NO_WAIT);
691 	if (err < 0) {
692 		LOG_ERR("Failed to schedule state transition work err %d", err);
693 		return err;
694 	}
695 
696 	return 0;
697 }
698 
ascs_ep_get_status_config(struct bt_bap_ep * ep,struct net_buf_simple * buf)699 static void ascs_ep_get_status_config(struct bt_bap_ep *ep, struct net_buf_simple *buf)
700 {
701 	struct bt_ascs_ase_status_config *cfg;
702 	struct bt_bap_qos_cfg_pref *pref = &ep->qos_pref;
703 
704 	cfg = net_buf_simple_add(buf, sizeof(*cfg));
705 	cfg->framing = pref->unframed_supported ? BT_ASCS_QOS_FRAMING_UNFRAMED
706 						: BT_ASCS_QOS_FRAMING_FRAMED;
707 	cfg->phy = pref->phy;
708 	cfg->rtn = pref->rtn;
709 	cfg->latency = sys_cpu_to_le16(pref->latency);
710 	sys_put_le24(pref->pd_min, cfg->pd_min);
711 	sys_put_le24(pref->pd_max, cfg->pd_max);
712 	sys_put_le24(pref->pref_pd_min, cfg->prefer_pd_min);
713 	sys_put_le24(pref->pref_pd_max, cfg->prefer_pd_max);
714 	cfg->codec.id = ep->codec_cfg.id;
715 	cfg->codec.cid = sys_cpu_to_le16(ep->codec_cfg.cid);
716 	cfg->codec.vid = sys_cpu_to_le16(ep->codec_cfg.vid);
717 
718 	LOG_DBG("dir %s unframed_supported 0x%02x phy 0x%02x rtn %u "
719 		"latency %u pd_min %u pd_max %u pref_pd_min %u pref_pd_max %u codec id 0x%02x",
720 		bt_audio_dir_str(ep->dir), pref->unframed_supported, pref->phy, pref->rtn,
721 		pref->latency, pref->pd_min, pref->pd_max, pref->pref_pd_min, pref->pref_pd_max,
722 		ep->stream->codec_cfg->id);
723 
724 	cfg->cc_len = ep->codec_cfg.data_len;
725 	net_buf_simple_add_mem(buf, ep->codec_cfg.data, ep->codec_cfg.data_len);
726 }
727 
ascs_ep_get_status_qos(struct bt_bap_ep * ep,struct net_buf_simple * buf)728 static void ascs_ep_get_status_qos(struct bt_bap_ep *ep, struct net_buf_simple *buf)
729 {
730 	struct bt_ascs_ase_status_qos *qos;
731 
732 	qos = net_buf_simple_add(buf, sizeof(*qos));
733 	qos->cig_id = ep->cig_id;
734 	qos->cis_id = ep->cis_id;
735 	sys_put_le24(ep->stream->qos->interval, qos->interval);
736 	qos->framing = ep->stream->qos->framing;
737 	qos->phy = ep->stream->qos->phy;
738 	qos->sdu = sys_cpu_to_le16(ep->stream->qos->sdu);
739 	qos->rtn = ep->stream->qos->rtn;
740 	qos->latency = sys_cpu_to_le16(ep->stream->qos->latency);
741 	sys_put_le24(ep->stream->qos->pd, qos->pd);
742 
743 	LOG_DBG("dir %s codec id 0x%02x interval %u framing 0x%02x phy 0x%02x "
744 		"rtn %u latency %u pd %u",
745 		bt_audio_dir_str(ep->dir), ep->stream->codec_cfg->id, ep->stream->qos->interval,
746 		ep->stream->qos->framing, ep->stream->qos->phy, ep->stream->qos->rtn,
747 		ep->stream->qos->latency, ep->stream->qos->pd);
748 }
749 
ascs_ep_get_status_enable(struct bt_bap_ep * ep,struct net_buf_simple * buf)750 static void ascs_ep_get_status_enable(struct bt_bap_ep *ep, struct net_buf_simple *buf)
751 {
752 	struct bt_ascs_ase_status_enable *enable;
753 
754 	enable = net_buf_simple_add(buf, sizeof(*enable));
755 	enable->cig_id = ep->cig_id;
756 	enable->cis_id = ep->cis_id;
757 
758 	enable->metadata_len = ep->codec_cfg.meta_len;
759 	net_buf_simple_add_mem(buf, ep->codec_cfg.meta, ep->codec_cfg.meta_len);
760 
761 	LOG_DBG("dir %s cig 0x%02x cis 0x%02x",
762 		bt_audio_dir_str(ep->dir), ep->cig_id, ep->cis_id);
763 }
764 
ascs_ase_read_status_idle(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)765 static ssize_t ascs_ase_read_status_idle(struct bt_conn *conn, const struct bt_gatt_attr *attr,
766 					 void *buf, uint16_t len, uint16_t offset)
767 {
768 	struct bt_ascs_ase_status status = {
769 		.id = POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr)),
770 		.state = BT_BAP_EP_STATE_IDLE,
771 	};
772 
773 	LOG_DBG("conn %p id 0x%02x", (void *)conn, status.id);
774 
775 	return bt_gatt_attr_read(conn, attr, buf, len, offset, &status, sizeof(status));
776 }
777 
ascs_ep_get_status(struct bt_bap_ep * ep,struct net_buf_simple * buf)778 static int ascs_ep_get_status(struct bt_bap_ep *ep, struct net_buf_simple *buf)
779 {
780 	if (!ep || !buf) {
781 		return -EINVAL;
782 	}
783 
784 	LOG_DBG("ep %p id 0x%02x state %s", ep, ep->status.id,
785 		bt_bap_ep_state_str(ep->status.state));
786 
787 	/* Reset if buffer before using */
788 	net_buf_simple_reset(buf);
789 
790 	(void)net_buf_simple_add_mem(buf, &ep->status, sizeof(ep->status));
791 
792 	switch (ep->status.state) {
793 	case BT_BAP_EP_STATE_IDLE:
794 	/* Fallthrough */
795 	case BT_BAP_EP_STATE_RELEASING:
796 		break;
797 	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
798 		ascs_ep_get_status_config(ep, buf);
799 		break;
800 	case BT_BAP_EP_STATE_QOS_CONFIGURED:
801 		ascs_ep_get_status_qos(ep, buf);
802 		break;
803 	case BT_BAP_EP_STATE_ENABLING:
804 	/* Fallthrough */
805 	case BT_BAP_EP_STATE_STREAMING:
806 	/* Fallthrough */
807 	case BT_BAP_EP_STATE_DISABLING:
808 		ascs_ep_get_status_enable(ep, buf);
809 		break;
810 	default:
811 		LOG_ERR("Invalid Endpoint state");
812 		break;
813 	}
814 
815 	return 0;
816 }
817 
ascs_iso_accept(const struct bt_iso_accept_info * info,struct bt_iso_chan ** iso_chan)818 static int ascs_iso_accept(const struct bt_iso_accept_info *info, struct bt_iso_chan **iso_chan)
819 {
820 	LOG_DBG("conn %p", (void *)info->acl);
821 
822 	for (size_t i = 0; i < ARRAY_SIZE(ascs.ase_pool); i++) {
823 		struct bt_ascs_ase *ase = &ascs.ase_pool[i];
824 		enum bt_bap_ep_state state;
825 		struct bt_iso_chan *chan;
826 
827 		if (ase->conn != info->acl ||
828 		    ase->ep.cig_id != info->cig_id ||
829 		    ase->ep.cis_id != info->cis_id) {
830 			continue;
831 		}
832 
833 		state = ascs_ep_get_state(&ase->ep);
834 		if (state != BT_BAP_EP_STATE_ENABLING && state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
835 			LOG_WRN("ase %p cannot accept ISO connection", ase);
836 			break;
837 		}
838 
839 		__ASSERT(ase->ep.iso != NULL, "ep %p not bound with ISO", &ase->ep);
840 
841 		chan = &ase->ep.iso->chan;
842 		if (chan->iso != NULL) {
843 			LOG_WRN("ase %p chan %p already connected", ase, chan);
844 			return -EALREADY;
845 		}
846 
847 		*iso_chan = chan;
848 
849 		LOG_DBG("iso_chan %p", *iso_chan);
850 
851 		return 0;
852 	}
853 
854 	return -EACCES;
855 }
856 
857 #if defined(CONFIG_BT_AUDIO_RX)
ascs_iso_recv(struct bt_iso_chan * chan,const struct bt_iso_recv_info * info,struct net_buf * buf)858 static void ascs_iso_recv(struct bt_iso_chan *chan,
859 			  const struct bt_iso_recv_info *info,
860 			  struct net_buf *buf)
861 {
862 	struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
863 	const struct bt_bap_stream_ops *ops;
864 	struct bt_bap_stream *stream;
865 	struct bt_bap_ep *ep;
866 
867 	ep = iso->rx.ep;
868 	if (ep == NULL) {
869 		/* In the case that the CIS has been setup as bidirectional, and
870 		 * only one of the directions have an ASE configured yet,
871 		 * we should only care about valid ISO packets when doing this
872 		 * check. The reason is that some controllers send HCI ISO data
873 		 * packets to the host, even if no SDU was sent on the remote
874 		 * side. This basically means that empty PDUs are sent to the
875 		 * host as HCI ISO data packets, which we should just ignore
876 		 */
877 		if ((info->flags & BT_ISO_FLAGS_VALID) != 0) {
878 			LOG_DBG("Valid ISO packet of len %zu received for iso %p not bound with ep",
879 				net_buf_frags_len(buf), chan);
880 		}
881 
882 		return;
883 	}
884 
885 	if (ep->status.state != BT_BAP_EP_STATE_STREAMING) {
886 		if (IS_ENABLED(CONFIG_BT_BAP_DEBUG_STREAM_DATA)) {
887 			LOG_DBG("ep %p is not in the streaming state: %s", ep,
888 				bt_bap_ep_state_str(ep->status.state));
889 		}
890 
891 		return;
892 	}
893 
894 	stream = ep->stream;
895 	if (stream == NULL) {
896 		LOG_ERR("No stream for ep %p", ep);
897 		return;
898 	}
899 
900 	ops = stream->ops;
901 
902 	if (IS_ENABLED(CONFIG_BT_BAP_DEBUG_STREAM_DATA)) {
903 		LOG_DBG("stream %p ep %p len %zu", stream, stream->ep, net_buf_frags_len(buf));
904 	}
905 
906 	if (ops != NULL && ops->recv != NULL) {
907 		ops->recv(stream, info, buf);
908 	} else {
909 		LOG_WRN("No callback for recv set");
910 	}
911 }
912 #endif /* CONFIG_BT_AUDIO_RX */
913 
914 #if defined(CONFIG_BT_AUDIO_TX)
ascs_iso_sent(struct bt_iso_chan * chan)915 static void ascs_iso_sent(struct bt_iso_chan *chan)
916 {
917 	struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
918 	const struct bt_bap_stream_ops *ops;
919 	struct bt_bap_stream *stream;
920 	struct bt_bap_ep *ep;
921 
922 	ep = iso->tx.ep;
923 	if (ep == NULL) {
924 		LOG_ERR("iso %p not bound with ep", chan);
925 		return;
926 	}
927 
928 	stream = ep->stream;
929 	if (stream == NULL) {
930 		LOG_ERR("No stream for ep %p", ep);
931 		return;
932 	}
933 
934 	ops = stream->ops;
935 
936 	if (IS_ENABLED(CONFIG_BT_BAP_DEBUG_STREAM_DATA)) {
937 		LOG_DBG("stream %p ep %p", stream, stream->ep);
938 	}
939 
940 	if (ops != NULL && ops->sent != NULL) {
941 		ops->sent(stream);
942 	}
943 }
944 #endif /* CONFIG_BT_AUDIO_TX */
945 
ascs_update_sdu_size(struct bt_bap_ep * ep)946 static void ascs_update_sdu_size(struct bt_bap_ep *ep)
947 {
948 	struct bt_iso_chan_io_qos *io_qos;
949 	struct bt_bap_qos_cfg *qos_cfg = &ep->qos;
950 
951 	if (ep->dir == BT_AUDIO_DIR_SINK) {
952 		io_qos = ep->iso->chan.qos->rx;
953 	} else if (ep->dir == BT_AUDIO_DIR_SOURCE) {
954 		io_qos = ep->iso->chan.qos->tx;
955 	} else {
956 		return;
957 	}
958 
959 	io_qos->sdu = qos_cfg->sdu;
960 	io_qos->rtn = qos_cfg->rtn;
961 }
962 
ascs_ep_iso_connected(struct bt_bap_ep * ep)963 static void ascs_ep_iso_connected(struct bt_bap_ep *ep)
964 {
965 	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
966 	const struct bt_bap_stream_ops *stream_ops;
967 	struct bt_bap_stream *stream;
968 
969 	if (ep->status.state != BT_BAP_EP_STATE_ENABLING) {
970 		LOG_DBG("ep %p not in enabling state: %s", ep,
971 			bt_bap_ep_state_str(ep->status.state));
972 		return;
973 	}
974 
975 	stream = ep->stream;
976 	if (stream == NULL) {
977 		LOG_ERR("No stream for ep %p", ep);
978 		return;
979 	}
980 
981 	/* Reset reason */
982 	ep->reason = BT_HCI_ERR_SUCCESS;
983 	ase->unexpected_iso_link_loss = false;
984 
985 	/* Some values are not provided by the HCI events when the CIS is established for the
986 	 * peripheral, so we update them here based on the parameters provided by the BAP Unicast
987 	 * Client
988 	 */
989 	ascs_update_sdu_size(ep);
990 
991 	LOG_DBG("stream %p ep %p dir %s", stream, ep, bt_audio_dir_str(ep->dir));
992 
993 #if defined(CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM)
994 	/* reset sequence number */
995 	stream->_prev_seq_num = 0U;
996 #endif /* CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM */
997 
998 	stream_ops = stream->ops;
999 	if (stream_ops != NULL && stream_ops->connected != NULL) {
1000 		stream_ops->connected(stream);
1001 	}
1002 
1003 	if (ep->dir == BT_AUDIO_DIR_SINK && ep->receiver_ready) {
1004 		/* Source ASEs shall be ISO connected first, and then receive
1005 		 * the receiver start ready command to enter the streaming
1006 		 * state
1007 		 */
1008 		ascs_ep_set_state(ep, BT_BAP_EP_STATE_STREAMING);
1009 	}
1010 }
1011 
ascs_iso_connected(struct bt_iso_chan * chan)1012 static void ascs_iso_connected(struct bt_iso_chan *chan)
1013 {
1014 	struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
1015 
1016 	if (iso->rx.ep == NULL && iso->tx.ep == NULL) {
1017 		LOG_ERR("iso %p not bound with ep", chan);
1018 		return;
1019 	}
1020 
1021 	if (iso->rx.ep != NULL) {
1022 		ascs_ep_iso_connected(iso->rx.ep);
1023 	}
1024 
1025 	if (iso->tx.ep != NULL) {
1026 		ascs_ep_iso_connected(iso->tx.ep);
1027 	}
1028 }
1029 
ascs_ep_iso_disconnected(struct bt_bap_ep * ep,uint8_t reason)1030 static void ascs_ep_iso_disconnected(struct bt_bap_ep *ep, uint8_t reason)
1031 {
1032 	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
1033 	const struct bt_bap_stream_ops *stream_ops;
1034 	struct bt_bap_stream *stream;
1035 
1036 	stream = ep->stream;
1037 	if (stream == NULL) {
1038 		LOG_ERR("No stream for ep %p", ep);
1039 		return;
1040 	}
1041 
1042 	LOG_DBG("stream %p ep %p state %s reason 0x%02x", stream, stream->ep,
1043 		bt_bap_ep_state_str(ep->status.state), reason);
1044 
1045 	stream_ops = stream->ops;
1046 	if (stream_ops != NULL && stream_ops->disconnected != NULL) {
1047 		stream_ops->disconnected(stream, reason);
1048 	}
1049 
1050 	/* Cancel ASE disconnect work if pending */
1051 	(void)k_work_cancel_delayable(&ase->disconnect_work);
1052 	ep->reason = reason;
1053 
1054 	if (ep->status.state == BT_BAP_EP_STATE_RELEASING) {
1055 		ascs_ep_set_state(ep, BT_BAP_EP_STATE_IDLE);
1056 	} else if (ep->status.state == BT_BAP_EP_STATE_STREAMING ||
1057 		   ep->status.state == BT_BAP_EP_STATE_DISABLING) {
1058 		/* ASCS_v1.0 3.2 ASE state machine transitions
1059 		 *
1060 		 * If the server detects link loss of a CIS for an ASE in the Streaming
1061 		 * state or the Disabling state, the server shall immediately transition
1062 		 * that ASE to the QoS Configured state.
1063 		 */
1064 		ase->unexpected_iso_link_loss = true;
1065 
1066 		ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
1067 	}
1068 }
1069 
ascs_iso_disconnected(struct bt_iso_chan * chan,uint8_t reason)1070 static void ascs_iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
1071 {
1072 	struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
1073 
1074 	if (iso->rx.ep == NULL && iso->tx.ep == NULL) {
1075 		return;
1076 	}
1077 
1078 	if (iso->rx.ep != NULL) {
1079 		ascs_ep_iso_disconnected(iso->rx.ep, reason);
1080 	}
1081 
1082 	if (iso->tx.ep != NULL) {
1083 		ascs_ep_iso_disconnected(iso->tx.ep, reason);
1084 	}
1085 }
1086 
1087 static struct bt_iso_chan_ops ascs_iso_ops = {
1088 #if defined(CONFIG_BT_AUDIO_RX)
1089 	.recv = ascs_iso_recv,
1090 #endif /* CONFIG_BT_AUDIO_RX */
1091 #if defined(CONFIG_BT_AUDIO_TX)
1092 	.sent = ascs_iso_sent,
1093 #endif /* CONFIG_BT_AUDIO_TX */
1094 	.connected = ascs_iso_connected,
1095 	.disconnected = ascs_iso_disconnected,
1096 };
1097 
ascs_ase_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1098 static void ascs_ase_cfg_changed(const struct bt_gatt_attr *attr,
1099 				 uint16_t value)
1100 {
1101 	LOG_DBG("attr %p value 0x%04x", attr, value);
1102 }
1103 
1104 #define CP_RSP_BUF_SIZE                                                                            \
1105 	(sizeof(struct bt_ascs_cp_rsp) + (ASE_COUNT * sizeof(struct bt_ascs_cp_ase_rsp)))
1106 
1107 /* Ensure that the cp_rsp_buf can fit in any notification
1108  * (sizeof buffer - header for notification)
1109  */
1110 BUILD_ASSERT(BT_ATT_BUF_SIZE - NTF_HEADER_SIZE >= CP_RSP_BUF_SIZE,
1111 	     "BT_ATT_BUF_SIZE not large enough to hold responses for all ASEs");
1112 NET_BUF_SIMPLE_DEFINE_STATIC(cp_rsp_buf, CP_RSP_BUF_SIZE);
1113 
ascs_cp_rsp_init(uint8_t op)1114 static void ascs_cp_rsp_init(uint8_t op)
1115 {
1116 	struct bt_ascs_cp_rsp *rsp;
1117 
1118 	net_buf_simple_reset(&cp_rsp_buf);
1119 
1120 	rsp = net_buf_simple_add(&cp_rsp_buf, sizeof(*rsp));
1121 	rsp->op = op;
1122 	rsp->num_ase = 0;
1123 }
1124 
1125 /* Add response to an opcode/ASE ID */
ascs_cp_rsp_add(uint8_t id,uint8_t code,uint8_t reason)1126 static void ascs_cp_rsp_add(uint8_t id, uint8_t code, uint8_t reason)
1127 {
1128 	struct bt_ascs_cp_rsp *rsp = (void *)cp_rsp_buf.__buf;
1129 	struct bt_ascs_cp_ase_rsp *ase_rsp;
1130 
1131 	LOG_DBG("id 0x%02x code %s (0x%02x) reason %s (0x%02x)", id,
1132 		bt_ascs_rsp_str(code), code, bt_ascs_reason_str(reason), reason);
1133 
1134 	if (rsp->num_ase == BT_ASCS_UNSUPP_OR_LENGTH_ERR_NUM_ASE) {
1135 		return;
1136 	}
1137 
1138 	switch (code) {
1139 	/* If the Response_Code value is 0x01 or 0x02, Number_of_ASEs shall be
1140 	 * set to 0xFF.
1141 	 */
1142 	case BT_BAP_ASCS_RSP_CODE_NOT_SUPPORTED:
1143 	case BT_BAP_ASCS_RSP_CODE_INVALID_LENGTH:
1144 		rsp->num_ase = BT_ASCS_UNSUPP_OR_LENGTH_ERR_NUM_ASE;
1145 		break;
1146 	default:
1147 		rsp->num_ase++;
1148 		break;
1149 	}
1150 
1151 	ase_rsp = net_buf_simple_add(&cp_rsp_buf, sizeof(*ase_rsp));
1152 	ase_rsp->id = id;
1153 	ase_rsp->code = code;
1154 	ase_rsp->reason = reason;
1155 }
1156 
ascs_cp_rsp_success(uint8_t id)1157 static void ascs_cp_rsp_success(uint8_t id)
1158 {
1159 	ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
1160 }
1161 
ase_release(struct bt_ascs_ase * ase,uint8_t reason,struct bt_bap_ascs_rsp * rsp)1162 static int ase_release(struct bt_ascs_ase *ase, uint8_t reason, struct bt_bap_ascs_rsp *rsp)
1163 {
1164 	enum bt_bap_ep_state state = ascs_ep_get_state(&ase->ep);
1165 	int err;
1166 
1167 	if (state == BT_BAP_EP_STATE_IDLE || state == BT_BAP_EP_STATE_RELEASING) {
1168 		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(state));
1169 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
1170 				       BT_BAP_ASCS_REASON_NONE);
1171 		return -EBADMSG;
1172 	}
1173 
1174 	if (unicast_server_cb == NULL || unicast_server_cb->release == NULL) {
1175 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
1176 				       BT_BAP_ASCS_REASON_NONE);
1177 		return -ENOTSUP;
1178 	}
1179 
1180 	err = unicast_server_cb->release(ase->ep.stream, rsp);
1181 	if (err) {
1182 		if (rsp->code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
1183 			*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
1184 					       BT_BAP_ASCS_REASON_NONE);
1185 		}
1186 
1187 		LOG_ERR("Release failed: err %d, code %u, reason %u", err, rsp->code, rsp->reason);
1188 		return err;
1189 	}
1190 
1191 	/* Set reason in case this exits the streaming state */
1192 	ase->ep.reason = reason;
1193 
1194 	ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_RELEASING);
1195 
1196 	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
1197 	return 0;
1198 }
1199 
bt_ascs_release_ase(struct bt_bap_ep * ep)1200 int bt_ascs_release_ase(struct bt_bap_ep *ep)
1201 {
1202 	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
1203 	const enum bt_bap_ep_state state = ascs_ep_get_state(&ase->ep);
1204 
1205 	if (state == BT_BAP_EP_STATE_IDLE) {
1206 		ase_free(ase);
1207 		return 0;
1208 	}
1209 
1210 	return ase_release(ase, BT_HCI_ERR_LOCALHOST_TERM_CONN, BT_BAP_ASCS_RSP_NULL);
1211 }
1212 
ase_disable(struct bt_ascs_ase * ase,uint8_t reason,struct bt_bap_ascs_rsp * rsp)1213 static int ase_disable(struct bt_ascs_ase *ase, uint8_t reason, struct bt_bap_ascs_rsp *rsp)
1214 {
1215 	struct bt_bap_stream *stream;
1216 	struct bt_bap_ep *ep;
1217 	int err;
1218 
1219 	LOG_DBG("ase %p", ase);
1220 
1221 	ep = &ase->ep;
1222 
1223 	switch (ep->status.state) {
1224 	/* Valid only if ASE_State field = 0x03 (Enabling) */
1225 	case BT_BAP_EP_STATE_ENABLING:
1226 		/* or 0x04 (Streaming) */
1227 	case BT_BAP_EP_STATE_STREAMING:
1228 		break;
1229 	default:
1230 		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
1231 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
1232 				       BT_BAP_ASCS_REASON_NONE);
1233 		return -EBADMSG;
1234 	}
1235 
1236 	stream = ep->stream;
1237 
1238 	if (unicast_server_cb == NULL || unicast_server_cb->disable == NULL) {
1239 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED, BT_BAP_ASCS_REASON_NONE);
1240 		return -ENOTSUP;
1241 	}
1242 
1243 	err = unicast_server_cb->disable(stream, rsp);
1244 	if (err) {
1245 		if (rsp->code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
1246 			*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
1247 					       BT_BAP_ASCS_REASON_NONE);
1248 		}
1249 
1250 		LOG_ERR("Disable failed: err %d, code %u, reason %u", err, rsp->code, rsp->reason);
1251 		return err;
1252 	}
1253 
1254 	/* Set reason in case this exits the streaming state */
1255 	ep->reason = reason;
1256 
1257 	/* The ASE state machine goes into different states from this operation
1258 	 * based on whether it is a source or a sink ASE.
1259 	 */
1260 	if (ep->dir == BT_AUDIO_DIR_SOURCE) {
1261 		ascs_ep_set_state(ep, BT_BAP_EP_STATE_DISABLING);
1262 	} else {
1263 		ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
1264 	}
1265 
1266 	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
1267 	return 0;
1268 }
1269 
bt_ascs_disable_ase(struct bt_bap_ep * ep)1270 int bt_ascs_disable_ase(struct bt_bap_ep *ep)
1271 {
1272 	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
1273 
1274 	return ase_disable(ase, BT_HCI_ERR_LOCALHOST_TERM_CONN, BT_BAP_ASCS_RSP_NULL);
1275 }
1276 
disconnected(struct bt_conn * conn,uint8_t reason)1277 static void disconnected(struct bt_conn *conn, uint8_t reason)
1278 {
1279 	for (size_t i = 0; i < ARRAY_SIZE(ascs.ase_pool); i++) {
1280 		struct bt_ascs_ase *ase = &ascs.ase_pool[i];
1281 
1282 		if (ase->conn != conn) {
1283 			continue;
1284 		}
1285 
1286 		if (ase->ep.status.state != BT_BAP_EP_STATE_IDLE) {
1287 			/* We must set the state to idle when the ACL is disconnected immediately,
1288 			 * as when the ACL disconnect callbacks have been called, the application
1289 			 * should expect there to be only a single reference to the bt_conn pointer
1290 			 * from the stack.
1291 			 * We trigger the work handler directly rather than e.g. calling
1292 			 * ase_enter_state_idle to trigger "regular" state change behavior (such) as
1293 			 * calling stream->stopped when leaving the streaming state.
1294 			 */
1295 			ase->ep.reason = reason;
1296 			ase->state_pending = BT_BAP_EP_STATE_IDLE;
1297 			state_transition_work_handler(&ase->state_transition_work.work);
1298 			/* At this point, `ase` object have been free'd */
1299 		}
1300 	}
1301 }
1302 
1303 BT_CONN_CB_DEFINE(conn_cb) = {
1304 	.disconnected = disconnected,
1305 };
1306 
1307 struct bap_iso_find_params {
1308 	struct bt_conn *acl;
1309 	uint8_t cig_id;
1310 	uint8_t cis_id;
1311 };
1312 
bap_iso_find_func(struct bt_bap_iso * iso,void * user_data)1313 static bool bap_iso_find_func(struct bt_bap_iso *iso, void *user_data)
1314 {
1315 	struct bap_iso_find_params *params = user_data;
1316 	const struct bt_bap_ep *ep;
1317 
1318 	if (iso->rx.ep != NULL) {
1319 		ep = iso->rx.ep;
1320 	} else if (iso->tx.ep != NULL) {
1321 		ep = iso->tx.ep;
1322 	} else {
1323 		return false;
1324 	}
1325 
1326 	return ep->stream->conn == params->acl &&
1327 	       ep->cig_id == params->cig_id &&
1328 	       ep->cis_id == params->cis_id;
1329 }
1330 
bap_iso_get_or_new(struct bt_conn * conn,uint8_t cig_id,uint8_t cis_id)1331 static struct bt_bap_iso *bap_iso_get_or_new(struct bt_conn *conn, uint8_t cig_id, uint8_t cis_id)
1332 {
1333 	struct bt_bap_iso *iso;
1334 	struct bap_iso_find_params params = {
1335 		.acl = bt_conn_ref(conn),
1336 		.cig_id = cig_id,
1337 		.cis_id = cis_id,
1338 	};
1339 
1340 	iso = bt_bap_iso_find(bap_iso_find_func, &params);
1341 	bt_conn_unref(conn);
1342 
1343 	if (iso) {
1344 		return iso;
1345 	}
1346 
1347 	iso = bt_bap_iso_new();
1348 	if (!iso) {
1349 		return NULL;
1350 	}
1351 
1352 	bt_bap_iso_init(iso, &ascs_iso_ops);
1353 
1354 	return iso;
1355 }
1356 
ase_attr_cb(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)1357 static uint8_t ase_attr_cb(const struct bt_gatt_attr *attr, uint16_t handle,
1358 			   void *user_data)
1359 {
1360 	struct bt_ascs_ase *ase = user_data;
1361 
1362 	if (ase->ep.status.id == POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr))) {
1363 		ase->attr = attr;
1364 
1365 		return BT_GATT_ITER_STOP;
1366 	}
1367 
1368 	return BT_GATT_ITER_CONTINUE;
1369 }
1370 
ascs_ep_init(struct bt_bap_ep * ep,uint8_t id)1371 void ascs_ep_init(struct bt_bap_ep *ep, uint8_t id)
1372 {
1373 	LOG_DBG("ep %p id 0x%02x", ep, id);
1374 
1375 	(void)memset(ep, 0, sizeof(*ep));
1376 	ep->status.id = id;
1377 	ep->dir = ASE_DIR(id);
1378 	ep->reason = BT_HCI_ERR_SUCCESS;
1379 }
1380 
ase_init(struct bt_ascs_ase * ase,struct bt_conn * conn,uint8_t id)1381 static void ase_init(struct bt_ascs_ase *ase, struct bt_conn *conn, uint8_t id)
1382 {
1383 	memset(ase, 0, sizeof(*ase));
1384 
1385 	ascs_ep_init(&ase->ep, id);
1386 
1387 	ase->conn = bt_conn_ref(conn);
1388 
1389 	/* Lookup ASE characteristic */
1390 	bt_gatt_foreach_attr_type(0x0001, 0xffff, ASE_UUID(id), NULL, 0, ase_attr_cb, ase);
1391 
1392 	__ASSERT(ase->attr, "ASE characteristic not found\n");
1393 
1394 	k_work_init_delayable(&ase->disconnect_work, ascs_disconnect_stream_work_handler);
1395 	k_work_init_delayable(&ase->state_transition_work, state_transition_work_handler);
1396 }
1397 
ase_new(struct bt_conn * conn,uint8_t id)1398 static struct bt_ascs_ase *ase_new(struct bt_conn *conn, uint8_t id)
1399 {
1400 	struct bt_ascs_ase *ase = NULL;
1401 
1402 	__ASSERT(id > 0 && id <= ASE_COUNT, "invalid ASE_ID 0x%02x", id);
1403 
1404 	for (size_t i = 0; i < ARRAY_SIZE(ascs.ase_pool); i++) {
1405 		if (ascs.ase_pool[i].conn == NULL) {
1406 			ase = &ascs.ase_pool[i];
1407 			break;
1408 		}
1409 	}
1410 
1411 	if (ase == NULL) {
1412 		return NULL;
1413 	}
1414 
1415 	ase_init(ase, conn, id);
1416 
1417 	LOG_DBG("conn %p new ase %p id 0x%02x", (void *)conn, ase, id);
1418 
1419 	return ase;
1420 }
1421 
ase_find(struct bt_conn * conn,uint8_t id)1422 static struct bt_ascs_ase *ase_find(struct bt_conn *conn, uint8_t id)
1423 {
1424 	for (size_t i = 0; i < ARRAY_SIZE(ascs.ase_pool); i++) {
1425 		struct bt_ascs_ase *ase = &ascs.ase_pool[i];
1426 
1427 		if (ase->conn == conn && ase->ep.status.id == id) {
1428 			return ase;
1429 		}
1430 	}
1431 
1432 	return NULL;
1433 }
1434 
ascs_ase_read(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1435 static ssize_t ascs_ase_read(struct bt_conn *conn,
1436 			     const struct bt_gatt_attr *attr, void *buf,
1437 			     uint16_t len, uint16_t offset)
1438 {
1439 	uint8_t ase_id = POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr));
1440 	struct bt_ascs_ase *ase = NULL;
1441 	ssize_t ret_val;
1442 	int err;
1443 
1444 	LOG_DBG("conn %p attr %p buf %p len %u offset %u", (void *)conn, attr, buf, len, offset);
1445 
1446 	/* The callback can be used locally to read the ASE_ID in which case conn won't be set. */
1447 	if (conn != NULL) {
1448 		ase = ase_find(conn, ase_id);
1449 	}
1450 
1451 	/* If NULL, we haven't assigned an ASE, this also means that we are currently in IDLE */
1452 	if (ase == NULL) {
1453 		return ascs_ase_read_status_idle(conn, attr, buf, len, offset);
1454 	}
1455 
1456 	err = k_sem_take(&ase_buf_sem, ASE_BUF_SEM_TIMEOUT);
1457 	if (err != 0) {
1458 		LOG_DBG("Failed to take ase_buf_sem: %d", err);
1459 
1460 		return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
1461 	}
1462 
1463 	ascs_ep_get_status(&ase->ep, &ase_buf);
1464 
1465 	ret_val = bt_gatt_attr_read(conn, attr, buf, len, offset, ase_buf.data, ase_buf.len);
1466 
1467 	k_sem_give(&ase_buf_sem);
1468 
1469 	return ret_val;
1470 }
1471 
ascs_cp_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1472 static void ascs_cp_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
1473 {
1474 	LOG_DBG("attr %p value 0x%04x", attr, value);
1475 }
1476 
ascs_ep_set_codec(struct bt_bap_ep * ep,uint8_t id,uint16_t cid,uint16_t vid,uint8_t * cc,uint8_t len,struct bt_bap_ascs_rsp * rsp)1477 static int ascs_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, uint16_t vid,
1478 			     uint8_t *cc, uint8_t len, struct bt_bap_ascs_rsp *rsp)
1479 {
1480 	const struct bt_audio_codec_cap *codec_cap;
1481 	struct bt_audio_codec_cfg *codec_cfg;
1482 	const struct bt_pac_codec codec_id = {
1483 		.id = id,
1484 		.cid = cid,
1485 		.vid = vid,
1486 	};
1487 
1488 	if (ep == NULL) {
1489 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
1490 				       BT_BAP_ASCS_REASON_CODEC_DATA);
1491 		return -EINVAL;
1492 	}
1493 
1494 	codec_cfg = &ep->codec_cfg;
1495 
1496 	LOG_DBG("ep %p dir %s codec id 0x%02x cid 0x%04x vid 0x%04x len %u",
1497 		ep, bt_audio_dir_str(ep->dir), id, cid, vid, len);
1498 
1499 	codec_cap = bt_pacs_get_codec_cap(ep->dir, &codec_id);
1500 	if (codec_cap == NULL) {
1501 		LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x for dir %s is not "
1502 			"supported by our capabilities",
1503 			codec_id.id, codec_id.cid, codec_id.vid, bt_audio_dir_str(ep->dir));
1504 
1505 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
1506 				       BT_BAP_ASCS_REASON_CODEC);
1507 		return -ENOENT;
1508 	}
1509 
1510 	codec_cfg->id = id;
1511 	codec_cfg->cid = cid;
1512 	codec_cfg->vid = vid;
1513 	codec_cfg->data_len = len;
1514 	memcpy(codec_cfg->data, cc, len);
1515 	codec_cfg->path_id = codec_cap->path_id;
1516 
1517 	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
1518 
1519 	return 0;
1520 }
1521 
ase_config(struct bt_ascs_ase * ase,const struct bt_ascs_config * cfg)1522 static int ase_config(struct bt_ascs_ase *ase, const struct bt_ascs_config *cfg)
1523 {
1524 	struct bt_bap_stream *stream;
1525 	struct bt_audio_codec_cfg codec_cfg;
1526 	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
1527 						     BT_BAP_ASCS_REASON_NONE);
1528 	int err;
1529 
1530 	LOG_DBG("ase %p latency 0x%02x phy 0x%02x codec 0x%02x "
1531 		"cid 0x%04x vid 0x%04x codec config len 0x%02x",
1532 		ase, cfg->latency, cfg->phy, cfg->codec.id, cfg->codec.cid, cfg->codec.vid,
1533 		cfg->cc_len);
1534 
1535 	if (cfg->latency < BT_ASCS_CONFIG_LATENCY_LOW ||
1536 	    cfg->latency > BT_ASCS_CONFIG_LATENCY_HIGH) {
1537 		LOG_WRN("Invalid latency: 0x%02x", cfg->latency);
1538 		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
1539 				BT_BAP_ASCS_REASON_LATENCY);
1540 		return -EINVAL;
1541 	}
1542 
1543 	if (cfg->phy < BT_ASCS_CONFIG_PHY_LE_1M ||
1544 	    cfg->phy > BT_ASCS_CONFIG_PHY_LE_CODED) {
1545 		LOG_WRN("Invalid PHY: 0x%02x", cfg->phy);
1546 		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
1547 				BT_BAP_ASCS_REASON_PHY);
1548 		return -EINVAL;
1549 	}
1550 
1551 	if (cfg->cc_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE) {
1552 		LOG_DBG("Can not store %u codec configuration data", cfg->cc_len);
1553 
1554 		return -ENOMEM;
1555 	}
1556 
1557 	switch (ase->ep.status.state) {
1558 	/* Valid only if ASE_State field = 0x00 (Idle) */
1559 	case BT_BAP_EP_STATE_IDLE:
1560 		/* or 0x01 (Codec Configured) */
1561 	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
1562 		/* or 0x02 (QoS Configured) */
1563 	case BT_BAP_EP_STATE_QOS_CONFIGURED:
1564 		break;
1565 	default:
1566 		LOG_WRN("Invalid operation in state: %s",
1567 			bt_bap_ep_state_str(ase->ep.status.state));
1568 		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
1569 				BT_BAP_ASCS_REASON_NONE);
1570 		return -EINVAL;
1571 	}
1572 
1573 	/* Store current codec configuration to be able to restore it
1574 	 * in case of error.
1575 	 */
1576 	(void)memcpy(&codec_cfg, &ase->ep.codec_cfg, sizeof(codec_cfg));
1577 
1578 	err = ascs_ep_set_codec(&ase->ep, cfg->codec.id, sys_le16_to_cpu(cfg->codec.cid),
1579 				sys_le16_to_cpu(cfg->codec.vid), (uint8_t *)cfg->cc, cfg->cc_len,
1580 				&rsp);
1581 	if (err) {
1582 		ascs_app_rsp_warn_valid(&rsp);
1583 		(void)memcpy(&ase->ep.codec_cfg, &codec_cfg, sizeof(codec_cfg));
1584 		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
1585 		return err;
1586 	}
1587 
1588 	if (ase->ep.stream != NULL) {
1589 		if (unicast_server_cb != NULL &&
1590 		    unicast_server_cb->reconfig != NULL) {
1591 			err = unicast_server_cb->reconfig(ase->ep.stream, ase->ep.dir,
1592 							  &ase->ep.codec_cfg, &ase->ep.qos_pref,
1593 							  &rsp);
1594 		} else {
1595 			err = -ENOTSUP;
1596 			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
1597 					      BT_BAP_ASCS_REASON_NONE);
1598 		}
1599 
1600 		if (err == 0 && !bt_bap_valid_qos_pref(&ase->ep.qos_pref)) {
1601 			LOG_ERR("Invalid QoS preferences");
1602 
1603 			/* If the upper layers provide an invalid QoS preferences we reject the
1604 			 * request from the client, as it would not be able to parse the result
1605 			 * as valid anyways
1606 			 */
1607 			err = -EINVAL;
1608 		}
1609 
1610 		if (err) {
1611 			ascs_app_rsp_warn_valid(&rsp);
1612 
1613 			if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
1614 				rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
1615 						      BT_BAP_ASCS_REASON_NONE);
1616 			}
1617 
1618 			LOG_ERR("Reconfig failed: err %d, code %u, reason %u",
1619 				err, rsp.code, rsp.reason);
1620 
1621 			(void)memcpy(&ase->ep.codec_cfg, &codec_cfg, sizeof(codec_cfg));
1622 			ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
1623 
1624 			return err;
1625 		}
1626 
1627 		stream = ase->ep.stream;
1628 	} else {
1629 		stream = NULL;
1630 		if (unicast_server_cb != NULL &&
1631 		    unicast_server_cb->config != NULL) {
1632 			err = unicast_server_cb->config(ase->conn, &ase->ep, ase->ep.dir,
1633 							&ase->ep.codec_cfg, &stream,
1634 							&ase->ep.qos_pref, &rsp);
1635 		} else {
1636 			err = -ENOTSUP;
1637 			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
1638 					      BT_BAP_ASCS_REASON_NONE);
1639 		}
1640 
1641 		if (err == 0 && !bt_bap_valid_qos_pref(&ase->ep.qos_pref)) {
1642 			LOG_ERR("Invalid QoS preferences");
1643 
1644 			/* If the upper layers provide an invalid QoS preferences we reject the
1645 			 * request from the client, as it would not be able to parse the result
1646 			 * as valid anyways
1647 			 */
1648 			err = -EINVAL;
1649 		}
1650 
1651 		if (err || stream == NULL) {
1652 			ascs_app_rsp_warn_valid(&rsp);
1653 
1654 			if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
1655 				rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
1656 						      BT_BAP_ASCS_REASON_NONE);
1657 			}
1658 
1659 			LOG_ERR("Config failed: err %d, stream %p, code %u, reason %u",
1660 				err, stream, rsp.code, rsp.reason);
1661 
1662 			(void)memcpy(&ase->ep.codec_cfg, &codec_cfg, sizeof(codec_cfg));
1663 			ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
1664 
1665 			return err ? err : -ENOMEM;
1666 		}
1667 
1668 		bt_bap_stream_init(stream);
1669 	}
1670 
1671 	ascs_cp_rsp_success(ASE_ID(ase));
1672 
1673 	bt_bap_stream_attach(ase->conn, stream, &ase->ep, &ase->ep.codec_cfg);
1674 
1675 	ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_CODEC_CONFIGURED);
1676 
1677 	return 0;
1678 }
1679 
ep_lookup_stream(struct bt_conn * conn,struct bt_bap_stream * stream)1680 static struct bt_bap_ep *ep_lookup_stream(struct bt_conn *conn, struct bt_bap_stream *stream)
1681 {
1682 	for (size_t i = 0; i < ARRAY_SIZE(ascs.ase_pool); i++) {
1683 		struct bt_ascs_ase *ase = &ascs.ase_pool[i];
1684 
1685 		if (ase->conn == conn && ase->ep.stream == stream) {
1686 			return &ase->ep;
1687 		}
1688 	}
1689 
1690 	return NULL;
1691 }
1692 
bt_ascs_config_ase(struct bt_conn * conn,struct bt_bap_stream * stream,struct bt_audio_codec_cfg * codec_cfg,const struct bt_bap_qos_cfg_pref * qos_pref)1693 int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream,
1694 		       struct bt_audio_codec_cfg *codec_cfg,
1695 		       const struct bt_bap_qos_cfg_pref *qos_pref)
1696 {
1697 	const struct bt_audio_codec_cap *codec_cap;
1698 	struct bt_ascs_ase *ase = NULL;
1699 	struct bt_pac_codec codec_id;
1700 	struct bt_bap_ep *ep;
1701 	int err;
1702 
1703 	CHECKIF(conn == NULL || stream == NULL || codec_cfg == NULL || qos_pref == NULL) {
1704 		LOG_DBG("NULL value(s) supplied)");
1705 		return -EINVAL;
1706 	}
1707 
1708 	ep = ep_lookup_stream(conn, stream);
1709 	if (ep != NULL) {
1710 		LOG_DBG("Stream already configured for conn %p", (void *)stream->conn);
1711 		return -EALREADY;
1712 	}
1713 
1714 	/* Get a free ASE or NULL if all ASE instances are already in use */
1715 	for (int i = 1; i <= ASE_COUNT; i++) {
1716 		if (ase_find(conn, i) == NULL) {
1717 			ase = ase_new(conn, i);
1718 			break;
1719 		}
1720 	}
1721 
1722 	if (ase == NULL) {
1723 		LOG_WRN("No free ASE found.");
1724 		return -ENOTSUP;
1725 	}
1726 
1727 	ep = &ase->ep;
1728 
1729 	if (ep == NULL) {
1730 		return -EINVAL;
1731 	}
1732 
1733 	codec_id.id = codec_cfg->id;
1734 	codec_id.cid = codec_cfg->cid;
1735 	codec_id.vid = codec_cfg->vid;
1736 
1737 	codec_cap = bt_pacs_get_codec_cap(ep->dir, &codec_id);
1738 	if (codec_cap == NULL) {
1739 		LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x for dir %s is not "
1740 			"supported by our capabilities",
1741 			codec_id.id, codec_id.cid, codec_id.vid, bt_audio_dir_str(ep->dir));
1742 		return -ENOENT;
1743 	}
1744 
1745 	(void)memcpy(&ep->codec_cfg, codec_cfg, sizeof(ep->codec_cfg));
1746 
1747 	ep->qos_pref = *qos_pref;
1748 
1749 	bt_bap_stream_attach(conn, stream, ep, &ep->codec_cfg);
1750 
1751 	err = ascs_ep_set_state(ep, BT_BAP_EP_STATE_CODEC_CONFIGURED);
1752 	if (err != 0) {
1753 		bt_bap_stream_detach(stream);
1754 		ase_free(ase);
1755 		return err;
1756 	}
1757 
1758 	return 0;
1759 }
1760 
get_max_ase_rsp_for_conn(struct bt_conn * conn)1761 static uint16_t get_max_ase_rsp_for_conn(struct bt_conn *conn)
1762 {
1763 	const uint16_t max_ntf_size = bt_audio_get_max_ntf_size(conn);
1764 	const size_t rsp_hdr_size = sizeof(struct bt_ascs_cp_rsp);
1765 
1766 	if (max_ntf_size > rsp_hdr_size) {
1767 		return (max_ntf_size - rsp_hdr_size) / sizeof(struct bt_ascs_cp_ase_rsp);
1768 	}
1769 
1770 	return 0U;
1771 }
1772 
is_valid_num_ases(struct bt_conn * conn,uint8_t num_ases)1773 static bool is_valid_num_ases(struct bt_conn *conn, uint8_t num_ases)
1774 {
1775 	const uint16_t max_ase_rsp = get_max_ase_rsp_for_conn(conn);
1776 
1777 	if (num_ases < 1U) {
1778 		LOG_WRN("Number_of_ASEs parameter value is less than 1");
1779 		return false;
1780 	} else if (num_ases > ASE_COUNT) {
1781 		/* If the request is for more ASEs than we have, we just reject the request */
1782 		LOG_DBG("Number_of_ASEs parameter value (%u) is greater than %d", num_ases,
1783 			ASE_COUNT);
1784 		return false;
1785 	} else if (num_ases > max_ase_rsp) {
1786 		/* If the request is for more ASEs than we can respond to, we reject the request */
1787 		LOG_DBG("Number_of_ASEs parameter value (%u) is greater than what we can respond "
1788 			"to (%u) based on the MTU",
1789 			num_ases, max_ase_rsp);
1790 		return false;
1791 	}
1792 
1793 	return true;
1794 }
1795 
is_valid_config_len(struct bt_conn * conn,struct net_buf_simple * buf)1796 static bool is_valid_config_len(struct bt_conn *conn, struct net_buf_simple *buf)
1797 {
1798 	const struct bt_ascs_config_op *op;
1799 	struct net_buf_simple_state state;
1800 
1801 	net_buf_simple_save(buf, &state);
1802 
1803 	if (buf->len < sizeof(*op)) {
1804 		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
1805 		return false;
1806 	}
1807 
1808 	op = net_buf_simple_pull_mem(buf, sizeof(*op));
1809 	if (!is_valid_num_ases(conn, op->num_ases)) {
1810 		return false;
1811 	}
1812 
1813 	for (uint8_t i = 0U; i < op->num_ases; i++) {
1814 		const struct bt_ascs_config *config;
1815 
1816 		if (buf->len < sizeof(*config)) {
1817 			LOG_WRN("Malformed params array");
1818 			return false;
1819 		}
1820 
1821 		config = net_buf_simple_pull_mem(buf, sizeof(*config));
1822 		if (buf->len < config->cc_len) {
1823 			LOG_WRN("Malformed codec specific config");
1824 			return false;
1825 		}
1826 
1827 		(void)net_buf_simple_pull_mem(buf, config->cc_len);
1828 	}
1829 
1830 	if (buf->len > 0) {
1831 		LOG_WRN("Unexpected data");
1832 		return false;
1833 	}
1834 
1835 	net_buf_simple_restore(buf, &state);
1836 
1837 	return true;
1838 }
1839 
ascs_config(struct bt_conn * conn,struct net_buf_simple * buf)1840 static ssize_t ascs_config(struct bt_conn *conn, struct net_buf_simple *buf)
1841 {
1842 	const struct bt_ascs_config_op *req;
1843 	const struct bt_ascs_config *cfg;
1844 
1845 	if (!is_valid_config_len(conn, buf)) {
1846 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1847 	}
1848 
1849 	req = net_buf_simple_pull_mem(buf, sizeof(*req));
1850 
1851 	LOG_DBG("num_ases %u", req->num_ases);
1852 
1853 	for (uint8_t i = 0; i < req->num_ases; i++) {
1854 		struct bt_ascs_ase *ase;
1855 		int err;
1856 
1857 		cfg = net_buf_simple_pull_mem(buf, sizeof(*cfg));
1858 		(void)net_buf_simple_pull(buf, cfg->cc_len);
1859 
1860 		LOG_DBG("ase 0x%02x cc_len %u", cfg->ase, cfg->cc_len);
1861 
1862 		if (!cfg->ase || cfg->ase > ASE_COUNT) {
1863 			LOG_WRN("Invalid ASE ID: %u", cfg->ase);
1864 			ascs_cp_rsp_add(cfg->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
1865 					BT_BAP_ASCS_REASON_NONE);
1866 			continue;
1867 		}
1868 
1869 		ase = ase_find(conn, cfg->ase);
1870 		if (ase != NULL) {
1871 			ase_config(ase, cfg);
1872 			continue;
1873 		}
1874 
1875 		ase = ase_new(conn, cfg->ase);
1876 		if (!ase) {
1877 			ascs_cp_rsp_add(cfg->ase, BT_BAP_ASCS_RSP_CODE_NO_MEM,
1878 					BT_BAP_ASCS_REASON_NONE);
1879 			LOG_WRN("No free ASE found for config ASE ID 0x%02x", cfg->ase);
1880 			continue;
1881 		}
1882 
1883 		err = ase_config(ase, cfg);
1884 		if (err != 0) {
1885 			ase_free(ase);
1886 		}
1887 	}
1888 
1889 	return buf->size;
1890 }
1891 
bt_ascs_foreach_ep(struct bt_conn * conn,bt_bap_ep_func_t func,void * user_data)1892 void bt_ascs_foreach_ep(struct bt_conn *conn, bt_bap_ep_func_t func, void *user_data)
1893 {
1894 	for (size_t i = 0; i < ARRAY_SIZE(ascs.ase_pool); i++) {
1895 		struct bt_ascs_ase *ase = &ascs.ase_pool[i];
1896 
1897 		if (ase->conn == conn) {
1898 			func(&ase->ep, user_data);
1899 		}
1900 	}
1901 }
1902 
ase_qos(struct bt_ascs_ase * ase,uint8_t cig_id,uint8_t cis_id,struct bt_bap_qos_cfg * qos,struct bt_bap_ascs_rsp * rsp)1903 static void ase_qos(struct bt_ascs_ase *ase, uint8_t cig_id, uint8_t cis_id,
1904 		    struct bt_bap_qos_cfg *qos, struct bt_bap_ascs_rsp *rsp)
1905 {
1906 	struct bt_bap_ep *ep = &ase->ep;
1907 	struct bt_bap_stream *stream;
1908 
1909 	LOG_DBG("ase %p cig 0x%02x cis 0x%02x interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u "
1910 		"latency %u pd %u", ase, cig_id, cis_id, qos->interval, qos->framing, qos->phy,
1911 		qos->sdu, qos->rtn, qos->latency, qos->pd);
1912 
1913 	switch (ep->status.state) {
1914 	/* Valid only if ASE_State field = 0x01 (Codec Configured) */
1915 	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
1916 	/* or 0x02 (QoS Configured) */
1917 	case BT_BAP_EP_STATE_QOS_CONFIGURED:
1918 		break;
1919 	default:
1920 		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
1921 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
1922 				       BT_BAP_ASCS_REASON_NONE);
1923 		return;
1924 	}
1925 
1926 	stream = ep->stream;
1927 	if (stream == NULL) {
1928 		LOG_ERR("NULL stream");
1929 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED, BT_BAP_ASCS_REASON_NONE);
1930 		return;
1931 	}
1932 
1933 	if (stream->ep == NULL) {
1934 		LOG_ERR("NULL stream->ep");
1935 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED, BT_BAP_ASCS_REASON_NONE);
1936 		return;
1937 	}
1938 
1939 	rsp->reason = bt_audio_verify_qos(qos);
1940 	if (rsp->reason != BT_BAP_ASCS_REASON_NONE) {
1941 		rsp->code = BT_BAP_ASCS_RSP_CODE_CONF_INVALID;
1942 		return;
1943 	}
1944 
1945 	rsp->reason = bt_bap_stream_verify_qos(stream, qos);
1946 	if (rsp->reason != BT_BAP_ASCS_REASON_NONE) {
1947 		rsp->code = BT_BAP_ASCS_RSP_CODE_CONF_INVALID;
1948 		return;
1949 	}
1950 
1951 	if (unicast_server_cb != NULL && unicast_server_cb->qos != NULL) {
1952 		int err = unicast_server_cb->qos(stream, qos, rsp);
1953 
1954 		if (err) {
1955 			if (rsp->code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
1956 				*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
1957 						       BT_BAP_ASCS_REASON_NONE);
1958 			}
1959 
1960 			LOG_DBG("Application returned error: err %d status %u reason %u",
1961 				err, rsp->code, rsp->reason);
1962 			return;
1963 		}
1964 	}
1965 
1966 	/* QoS->QoS transition. Unbind ISO if CIG/CIS changed. */
1967 	if (ep->iso != NULL && (ep->cig_id != cig_id || ep->cis_id != cis_id)) {
1968 		bt_bap_iso_unbind_ep(ep->iso, ep);
1969 	}
1970 
1971 	if (ep->iso == NULL) {
1972 		struct bt_bap_iso *iso;
1973 
1974 		iso = bap_iso_get_or_new(ase->conn, cig_id, cis_id);
1975 		if (iso == NULL) {
1976 			LOG_ERR("Could not allocate bap_iso");
1977 			*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM,
1978 					       BT_BAP_ASCS_REASON_NONE);
1979 			return;
1980 		}
1981 
1982 		if (bt_bap_iso_get_ep(false, iso, ep->dir) != NULL) {
1983 			LOG_ERR("iso %p already in use in dir %s",
1984 			       &iso->chan, bt_audio_dir_str(ep->dir));
1985 			bt_bap_iso_unref(iso);
1986 			*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
1987 					       BT_BAP_ASCS_REASON_CIS);
1988 			return;
1989 		}
1990 
1991 		bt_bap_iso_bind_ep(iso, ep);
1992 		bt_bap_iso_unref(iso);
1993 	}
1994 
1995 	/* Store the QoS once accepted */
1996 	ep->qos = *qos;
1997 	stream->qos = &ep->qos;
1998 
1999 	/* We setup the data path here, as this is the earliest where
2000 	 * we have the ISO <-> EP coupling completed (due to setting
2001 	 * the CIS ID in the QoS procedure).
2002 	 */
2003 	bt_bap_iso_configure_data_path(ep, stream->codec_cfg);
2004 
2005 	ep->cig_id = cig_id;
2006 	ep->cis_id = cis_id;
2007 
2008 	ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
2009 
2010 	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
2011 }
2012 
is_valid_qos_len(struct bt_conn * conn,struct net_buf_simple * buf)2013 static bool is_valid_qos_len(struct bt_conn *conn, struct net_buf_simple *buf)
2014 {
2015 	const struct bt_ascs_qos_op *op;
2016 	struct net_buf_simple_state state;
2017 	size_t params_size;
2018 
2019 	net_buf_simple_save(buf, &state);
2020 
2021 	if (buf->len < sizeof(*op)) {
2022 		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
2023 		return false;
2024 	}
2025 
2026 	op = net_buf_simple_pull_mem(buf, sizeof(*op));
2027 	if (!is_valid_num_ases(conn, op->num_ases)) {
2028 		return false;
2029 	}
2030 
2031 	params_size = sizeof(struct bt_ascs_qos) * op->num_ases;
2032 	if (buf->len < params_size) {
2033 		LOG_WRN("Malformed params array");
2034 		return false;
2035 	}
2036 
2037 	(void)net_buf_simple_pull_mem(buf, params_size);
2038 
2039 	if (buf->len > 0) {
2040 		LOG_WRN("Unexpected data");
2041 		return false;
2042 	}
2043 
2044 	net_buf_simple_restore(buf, &state);
2045 
2046 	return true;
2047 }
2048 
ascs_qos(struct bt_conn * conn,struct net_buf_simple * buf)2049 static ssize_t ascs_qos(struct bt_conn *conn, struct net_buf_simple *buf)
2050 {
2051 	const struct bt_ascs_qos_op *req;
2052 
2053 	if (!is_valid_qos_len(conn, buf)) {
2054 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
2055 	}
2056 
2057 	req = net_buf_simple_pull_mem(buf, sizeof(*req));
2058 
2059 	LOG_DBG("num_ases %u", req->num_ases);
2060 
2061 	for (uint8_t i = 0; i < req->num_ases; i++) {
2062 		struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2063 							     BT_BAP_ASCS_REASON_NONE);
2064 		struct bt_bap_qos_cfg cqos;
2065 		const struct bt_ascs_qos *qos;
2066 		struct bt_ascs_ase *ase;
2067 
2068 		qos = net_buf_simple_pull_mem(buf, sizeof(*qos));
2069 
2070 		LOG_DBG("ase 0x%02x", qos->ase);
2071 
2072 		if (!is_valid_ase_id(qos->ase)) {
2073 			ascs_cp_rsp_add(qos->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
2074 					BT_BAP_ASCS_REASON_NONE);
2075 			LOG_WRN("Unknown ase 0x%02x", qos->ase);
2076 			continue;
2077 		}
2078 
2079 		ase = ase_find(conn, qos->ase);
2080 		if (!ase) {
2081 			LOG_DBG("Invalid operation for idle ASE");
2082 			ascs_cp_rsp_add(qos->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2083 					BT_BAP_ASCS_REASON_NONE);
2084 			continue;
2085 		}
2086 
2087 		cqos.interval = sys_get_le24(qos->interval);
2088 		cqos.framing = qos->framing;
2089 		cqos.phy = qos->phy;
2090 		cqos.sdu = sys_le16_to_cpu(qos->sdu);
2091 		cqos.rtn = qos->rtn;
2092 		cqos.latency = sys_le16_to_cpu(qos->latency);
2093 		cqos.pd = sys_get_le24(qos->pd);
2094 
2095 		ase_qos(ase, qos->cig, qos->cis, &cqos, &rsp);
2096 		ascs_cp_rsp_add(qos->ase, rsp.code, rsp.reason);
2097 	}
2098 
2099 	return buf->size;
2100 }
2101 
2102 struct ascs_parse_result {
2103 	int err;
2104 	struct bt_conn *conn;
2105 	struct bt_bap_ascs_rsp *rsp;
2106 	const struct bt_bap_ep *ep;
2107 };
2108 
is_context_available(struct bt_conn * conn,enum bt_audio_dir dir,uint16_t context)2109 static bool is_context_available(struct bt_conn *conn, enum bt_audio_dir dir, uint16_t context)
2110 {
2111 	return (context & bt_pacs_get_available_contexts_for_conn(conn, dir)) == context;
2112 }
2113 
ascs_parse_metadata(struct bt_data * data,void * user_data)2114 static bool ascs_parse_metadata(struct bt_data *data, void *user_data)
2115 {
2116 	struct ascs_parse_result *result = user_data;
2117 	const struct bt_bap_ep *ep = result->ep;
2118 	const uint8_t data_len = data->data_len;
2119 	const uint8_t data_type = data->type;
2120 	const uint8_t *data_value = data->data;
2121 
2122 	LOG_DBG("type 0x%02x len %u", data_type, data_len);
2123 
2124 	if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(data_type)) {
2125 		LOG_WRN("Unknown metadata type 0x%02x", data_type);
2126 		return true;
2127 	}
2128 
2129 	switch (data_type) {
2130 	/* TODO: Consider rejecting BT_AUDIO_METADATA_TYPE_PREF_CONTEXT type */
2131 	case BT_AUDIO_METADATA_TYPE_PREF_CONTEXT:
2132 	case BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT: {
2133 		uint16_t context;
2134 
2135 		if (data_len != sizeof(context)) {
2136 			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
2137 						       data_type);
2138 			result->err = -EBADMSG;
2139 			return false;
2140 		}
2141 
2142 		context = sys_get_le16(data_value);
2143 		if (context == BT_AUDIO_CONTEXT_TYPE_PROHIBITED) {
2144 			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
2145 						       data_type);
2146 			result->err = -EINVAL;
2147 			return false;
2148 		}
2149 
2150 		/* The CAP acceptor shall not accept metadata with unsupported stream context. */
2151 		if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR) &&
2152 		    data_type == BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT) {
2153 			if (!is_context_available(result->conn, ep->dir, context)) {
2154 				LOG_WRN("Context 0x%04x is unavailable", context);
2155 				*result->rsp = BT_BAP_ASCS_RSP(
2156 					BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED, data_type);
2157 				result->err = -EACCES;
2158 				return false;
2159 			}
2160 		}
2161 
2162 		break;
2163 	}
2164 	case BT_AUDIO_METADATA_TYPE_LANG:
2165 		if (data_len != BT_AUDIO_LANG_SIZE) {
2166 			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
2167 						       data_type);
2168 			result->err = -EBADMSG;
2169 			return false;
2170 		}
2171 
2172 		break;
2173 	case BT_AUDIO_METADATA_TYPE_CCID_LIST: {
2174 		/* Verify that the CCID is a known CCID on the writing device */
2175 		if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR)) {
2176 			for (uint8_t i = 0; i < data_len; i++) {
2177 				const uint8_t ccid = data_value[i];
2178 
2179 				if (!bt_cap_acceptor_ccid_exist(ep->stream->conn, ccid)) {
2180 					LOG_WRN("CCID %u is unknown", ccid);
2181 
2182 					/* TBD:
2183 					 * Should we reject the Metadata?
2184 					 *
2185 					 * Should unknown CCIDs trigger a
2186 					 * discovery procedure for TBS or MCS?
2187 					 *
2188 					 * Or should we just accept as is, and
2189 					 * then let the application decide?
2190 					 */
2191 				}
2192 			}
2193 		}
2194 
2195 		break;
2196 	}
2197 	case BT_AUDIO_METADATA_TYPE_PARENTAL_RATING:
2198 		if (data_len != 1) {
2199 			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
2200 						       data_type);
2201 			result->err = -EBADMSG;
2202 			return false;
2203 		}
2204 
2205 		break;
2206 	case BT_AUDIO_METADATA_TYPE_AUDIO_STATE: {
2207 		uint8_t state;
2208 
2209 		if (data_len != sizeof(state)) {
2210 			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
2211 						       data_type);
2212 			result->err = -EBADMSG;
2213 			return false;
2214 		}
2215 
2216 		break;
2217 	}
2218 	/* TODO: Consider rejecting BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE type */
2219 	case BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE:
2220 		if (data_len != 0) {
2221 			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
2222 						       data_type);
2223 			result->err = -EBADMSG;
2224 			return false;
2225 		}
2226 
2227 		break;
2228 	default:
2229 		break;
2230 	}
2231 
2232 	return true;
2233 }
2234 
ascs_verify_metadata(struct bt_bap_ep * ep,const struct bt_ascs_metadata * meta,struct bt_bap_ascs_rsp * rsp)2235 static int ascs_verify_metadata(struct bt_bap_ep *ep, const struct bt_ascs_metadata *meta,
2236 				struct bt_bap_ascs_rsp *rsp)
2237 {
2238 	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
2239 	struct ascs_parse_result result = {
2240 		.conn = ase->conn,
2241 		.rsp = rsp,
2242 		.err = 0,
2243 		.ep = ep,
2244 	};
2245 	int err;
2246 
2247 	if (meta->len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
2248 		LOG_WRN("Not enough space for Codec Config Metadata: %u > %d", meta->len,
2249 			CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
2250 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM, BT_BAP_ASCS_REASON_NONE);
2251 
2252 		return -ENOMEM;
2253 	}
2254 
2255 	/* Parse LTV entries */
2256 	err = bt_audio_data_parse(meta->data, meta->len, ascs_parse_metadata, &result);
2257 	if (err != 0 && err != -ECANCELED) {
2258 		/* ECANCELED is called if the callback stops the parsing prematurely, in which case
2259 		 * result.err will be set
2260 		 */
2261 		LOG_DBG("Failed to parse metadata: %d", err);
2262 		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
2263 				       BT_BAP_ASCS_REASON_NONE);
2264 
2265 		return err;
2266 	}
2267 
2268 	return result.err;
2269 }
2270 
ase_metadata(struct bt_ascs_ase * ase,struct bt_ascs_metadata * meta)2271 static void ase_metadata(struct bt_ascs_ase *ase, struct bt_ascs_metadata *meta)
2272 {
2273 	struct bt_bap_stream *stream;
2274 	struct bt_bap_ep *ep;
2275 	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
2276 						     BT_BAP_ASCS_REASON_NONE);
2277 	uint8_t state;
2278 	int err;
2279 
2280 	LOG_DBG("ase %p meta->len %u", ase, meta->len);
2281 
2282 	ep = &ase->ep;
2283 	state = ep->status.state;
2284 
2285 	switch (state) {
2286 	/* Valid for an ASE only if ASE_State field = 0x03 (Enabling) */
2287 	case BT_BAP_EP_STATE_ENABLING:
2288 	/* or 0x04 (Streaming) */
2289 	case BT_BAP_EP_STATE_STREAMING:
2290 		break;
2291 	default:
2292 		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(state));
2293 		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2294 				BT_BAP_ASCS_REASON_NONE);
2295 		return;
2296 	}
2297 
2298 	stream = ep->stream;
2299 
2300 	err = ascs_verify_metadata(ep, meta, &rsp);
2301 	if (err != 0) {
2302 		LOG_DBG("Invalid metadata from client: %d", err);
2303 
2304 		/* rsp will be set by ascs_verify_metadata*/
2305 	} else if (unicast_server_cb != NULL && unicast_server_cb->metadata != NULL) {
2306 		err = unicast_server_cb->metadata(stream, meta->data, meta->len, &rsp);
2307 	} else {
2308 		err = -ENOTSUP;
2309 		rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2310 				      BT_BAP_ASCS_REASON_NONE);
2311 	}
2312 
2313 	if (err) {
2314 		ascs_app_rsp_warn_valid(&rsp);
2315 
2316 		if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
2317 			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2318 					      BT_BAP_ASCS_REASON_NONE);
2319 		}
2320 
2321 		LOG_ERR("Metadata failed: err %d, code %u, reason %u", err, rsp.code, rsp.reason);
2322 		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
2323 		return;
2324 	}
2325 
2326 	ep->codec_cfg.meta_len = meta->len;
2327 	(void)memcpy(ep->codec_cfg.meta, meta->data, meta->len);
2328 
2329 	/* Set the state to the same state to trigger the notifications */
2330 	ascs_ep_set_state(ep, ep->status.state);
2331 	ascs_cp_rsp_success(ASE_ID(ase));
2332 }
2333 
ase_enable(struct bt_ascs_ase * ase,struct bt_ascs_metadata * meta)2334 static int ase_enable(struct bt_ascs_ase *ase, struct bt_ascs_metadata *meta)
2335 {
2336 	struct bt_bap_stream *stream;
2337 	struct bt_bap_ep *ep;
2338 	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
2339 						     BT_BAP_ASCS_REASON_NONE);
2340 	int err;
2341 
2342 	LOG_DBG("ase %p meta->len %u", ase, meta->len);
2343 
2344 	ep = &ase->ep;
2345 
2346 	/* Valid for an ASE only if ASE_State field = 0x02 (QoS Configured) */
2347 	if (ep->status.state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
2348 		err = -EBADMSG;
2349 		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
2350 		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2351 				BT_BAP_ASCS_REASON_NONE);
2352 		return err;
2353 	}
2354 
2355 	stream = ep->stream;
2356 
2357 	err = ascs_verify_metadata(ep, meta, &rsp);
2358 	if (err != 0) {
2359 		LOG_DBG("Invalid metadata from client: %d", err);
2360 
2361 		/* rsp will be set by ascs_verify_metadata*/
2362 	} else if (unicast_server_cb != NULL && unicast_server_cb->enable != NULL) {
2363 		err = unicast_server_cb->enable(stream, meta->data, meta->len, &rsp);
2364 	} else {
2365 		err = -ENOTSUP;
2366 		rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2367 				      BT_BAP_ASCS_REASON_NONE);
2368 	}
2369 
2370 	if (err) {
2371 		ascs_app_rsp_warn_valid(&rsp);
2372 
2373 		if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
2374 			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2375 					      BT_BAP_ASCS_REASON_NONE);
2376 		}
2377 
2378 		LOG_ERR("Enable rejected: err %d, code %u, reason %u", err, rsp.code, rsp.reason);
2379 		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
2380 
2381 		return -EFAULT;
2382 	}
2383 
2384 	ep->codec_cfg.meta_len = meta->len;
2385 	(void)memcpy(ep->codec_cfg.meta, meta->data, meta->len);
2386 
2387 	ascs_ep_set_state(ep, BT_BAP_EP_STATE_ENABLING);
2388 
2389 	ascs_cp_rsp_success(ASE_ID(ase));
2390 
2391 	return 0;
2392 }
2393 
is_valid_enable_len(struct bt_conn * conn,struct net_buf_simple * buf)2394 static bool is_valid_enable_len(struct bt_conn *conn, struct net_buf_simple *buf)
2395 {
2396 	const struct bt_ascs_enable_op *op;
2397 	struct net_buf_simple_state state;
2398 
2399 	net_buf_simple_save(buf, &state);
2400 
2401 	if (buf->len < sizeof(*op)) {
2402 		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
2403 		return false;
2404 	}
2405 
2406 	op = net_buf_simple_pull_mem(buf, sizeof(*op));
2407 	if (!is_valid_num_ases(conn, op->num_ases)) {
2408 		return false;
2409 	}
2410 
2411 	for (uint8_t i = 0U; i < op->num_ases; i++) {
2412 		const struct bt_ascs_metadata *metadata;
2413 
2414 		if (buf->len < sizeof(*metadata)) {
2415 			LOG_WRN("Malformed params array");
2416 			return false;
2417 		}
2418 
2419 		metadata = net_buf_simple_pull_mem(buf, sizeof(*metadata));
2420 		if (buf->len < metadata->len) {
2421 			LOG_WRN("Malformed metadata");
2422 			return false;
2423 		}
2424 
2425 		(void)net_buf_simple_pull_mem(buf, metadata->len);
2426 	}
2427 
2428 	if (buf->len > 0) {
2429 		LOG_WRN("Unexpected data");
2430 		return false;
2431 	}
2432 
2433 	net_buf_simple_restore(buf, &state);
2434 
2435 	return true;
2436 }
2437 
ascs_enable(struct bt_conn * conn,struct net_buf_simple * buf)2438 static ssize_t ascs_enable(struct bt_conn *conn, struct net_buf_simple *buf)
2439 {
2440 	const struct bt_ascs_enable_op *req;
2441 	struct bt_ascs_metadata *meta;
2442 	int i;
2443 
2444 	if (!is_valid_enable_len(conn, buf)) {
2445 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
2446 	}
2447 
2448 	req = net_buf_simple_pull_mem(buf, sizeof(*req));
2449 
2450 	LOG_DBG("num_ases %u", req->num_ases);
2451 
2452 	for (i = 0; i < req->num_ases; i++) {
2453 		struct bt_ascs_ase *ase;
2454 
2455 		meta = net_buf_simple_pull_mem(buf, sizeof(*meta));
2456 		(void)net_buf_simple_pull(buf, meta->len);
2457 
2458 		if (!is_valid_ase_id(meta->ase)) {
2459 			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
2460 					BT_BAP_ASCS_REASON_NONE);
2461 			LOG_WRN("Unknown ase 0x%02x", meta->ase);
2462 			continue;
2463 		}
2464 
2465 		ase = ase_find(conn, meta->ase);
2466 		if (!ase) {
2467 			LOG_DBG("Invalid operation for idle ase 0x%02x", meta->ase);
2468 			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2469 					BT_BAP_ASCS_REASON_NONE);
2470 			continue;
2471 		}
2472 
2473 		ase_enable(ase, meta);
2474 	}
2475 
2476 	return buf->size;
2477 }
2478 
ase_start(struct bt_ascs_ase * ase)2479 static void ase_start(struct bt_ascs_ase *ase)
2480 {
2481 	struct bt_bap_ep *ep;
2482 	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
2483 						     BT_BAP_ASCS_REASON_NONE);
2484 	int err;
2485 
2486 	LOG_DBG("ase %p", ase);
2487 
2488 	ep = &ase->ep;
2489 
2490 	/* Valid for an ASE only if ASE_State field = 0x02 (QoS Configured) */
2491 	if (ep->status.state != BT_BAP_EP_STATE_ENABLING) {
2492 		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
2493 		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2494 				BT_BAP_ASCS_REASON_NONE);
2495 		return;
2496 	}
2497 
2498 	if (ep->iso->chan.state != BT_ISO_STATE_CONNECTED) {
2499 		/* An ASE may not go into the streaming state unless the CIS
2500 		 * is connected
2501 		 */
2502 		LOG_WRN("Start failed: CIS not connected: %u",
2503 			ep->iso->chan.state);
2504 		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2505 				BT_BAP_ASCS_REASON_NONE);
2506 		return;
2507 	}
2508 
2509 	if (unicast_server_cb != NULL && unicast_server_cb->start != NULL) {
2510 		err = unicast_server_cb->start(ep->stream, &rsp);
2511 	} else {
2512 		err = -ENOTSUP;
2513 		rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2514 				      BT_BAP_ASCS_REASON_NONE);
2515 	}
2516 
2517 	if (err) {
2518 		ascs_app_rsp_warn_valid(&rsp);
2519 
2520 		if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
2521 			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2522 					      BT_BAP_ASCS_REASON_NONE);
2523 		}
2524 
2525 		LOG_ERR("Start failed: err %d, code %u, reason %u", err, rsp.code, rsp.reason);
2526 		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
2527 
2528 		return;
2529 	}
2530 
2531 	ep->receiver_ready = true;
2532 
2533 	ascs_ep_set_state(ep, BT_BAP_EP_STATE_STREAMING);
2534 
2535 	ascs_cp_rsp_success(ASE_ID(ase));
2536 }
2537 
is_valid_start_len(struct bt_conn * conn,struct net_buf_simple * buf)2538 static bool is_valid_start_len(struct bt_conn *conn, struct net_buf_simple *buf)
2539 {
2540 	const struct bt_ascs_start_op *op;
2541 	struct net_buf_simple_state state;
2542 
2543 	net_buf_simple_save(buf, &state);
2544 
2545 	if (buf->len < sizeof(*op)) {
2546 		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
2547 		return false;
2548 	}
2549 
2550 	op = net_buf_simple_pull_mem(buf, sizeof(*op));
2551 	if (!is_valid_num_ases(conn, op->num_ases)) {
2552 		return false;
2553 	}
2554 
2555 	if (buf->len != op->num_ases) {
2556 		LOG_WRN("Number_of_ASEs mismatch");
2557 		return false;
2558 	}
2559 
2560 	net_buf_simple_restore(buf, &state);
2561 
2562 	return true;
2563 }
2564 
ascs_start(struct bt_conn * conn,struct net_buf_simple * buf)2565 static ssize_t ascs_start(struct bt_conn *conn, struct net_buf_simple *buf)
2566 {
2567 	const struct bt_ascs_start_op *req;
2568 	int i;
2569 
2570 	if (!is_valid_start_len(conn, buf)) {
2571 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
2572 	}
2573 
2574 	req = net_buf_simple_pull_mem(buf, sizeof(*req));
2575 
2576 	LOG_DBG("num_ases %u", req->num_ases);
2577 
2578 	for (i = 0; i < req->num_ases; i++) {
2579 		struct bt_ascs_ase *ase;
2580 		uint8_t id;
2581 
2582 		id = net_buf_simple_pull_u8(buf);
2583 
2584 		LOG_DBG("ase 0x%02x", id);
2585 
2586 		if (!is_valid_ase_id(id)) {
2587 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
2588 					BT_BAP_ASCS_REASON_NONE);
2589 			LOG_WRN("Unknown ase 0x%02x", id);
2590 			continue;
2591 		}
2592 
2593 		/* If the ASE_ID  written by the client represents a Sink ASE, the
2594 		 * server shall not accept the Receiver Start Ready operation for that
2595 		 * ASE. The server shall send a notification of the ASE Control Point
2596 		 * characteristic to the client, and the server shall set the
2597 		 * Response_Code value for that ASE to 0x05 (Invalid ASE direction).
2598 		 */
2599 		if (ASE_DIR(id) == BT_AUDIO_DIR_SINK) {
2600 			LOG_WRN("Start failed: invalid operation for Sink");
2601 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_DIR,
2602 					BT_BAP_ASCS_REASON_NONE);
2603 			continue;
2604 		}
2605 
2606 		ase = ase_find(conn, id);
2607 		if (!ase) {
2608 			LOG_DBG("Invalid operation for idle ASE");
2609 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2610 					BT_BAP_ASCS_REASON_NONE);
2611 			continue;
2612 		}
2613 
2614 		ase_start(ase);
2615 	}
2616 
2617 	return buf->size;
2618 }
2619 
is_valid_disable_len(struct bt_conn * conn,struct net_buf_simple * buf)2620 static bool is_valid_disable_len(struct bt_conn *conn, struct net_buf_simple *buf)
2621 {
2622 	const struct bt_ascs_disable_op *op;
2623 	struct net_buf_simple_state state;
2624 
2625 	net_buf_simple_save(buf, &state);
2626 
2627 	if (buf->len < sizeof(*op)) {
2628 		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
2629 		return false;
2630 	}
2631 
2632 	op = net_buf_simple_pull_mem(buf, sizeof(*op));
2633 	if (!is_valid_num_ases(conn, op->num_ases)) {
2634 		return false;
2635 	}
2636 
2637 	if (buf->len != op->num_ases) {
2638 		LOG_WRN("Number_of_ASEs mismatch");
2639 		return false;
2640 	}
2641 
2642 	net_buf_simple_restore(buf, &state);
2643 
2644 	return true;
2645 }
2646 
ascs_disable(struct bt_conn * conn,struct net_buf_simple * buf)2647 static ssize_t ascs_disable(struct bt_conn *conn, struct net_buf_simple *buf)
2648 {
2649 	const struct bt_ascs_disable_op *req;
2650 
2651 	if (!is_valid_disable_len(conn, buf)) {
2652 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
2653 	}
2654 
2655 	req = net_buf_simple_pull_mem(buf, sizeof(*req));
2656 
2657 	LOG_DBG("num_ases %u", req->num_ases);
2658 
2659 	for (uint8_t i = 0; i < req->num_ases; i++) {
2660 		struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2661 							     BT_BAP_ASCS_REASON_NONE);
2662 		struct bt_ascs_ase *ase;
2663 		uint8_t id;
2664 
2665 		id = net_buf_simple_pull_u8(buf);
2666 
2667 		LOG_DBG("ase 0x%02x", id);
2668 
2669 		if (!is_valid_ase_id(id)) {
2670 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
2671 					BT_BAP_ASCS_REASON_NONE);
2672 			LOG_WRN("Unknown ase 0x%02x", id);
2673 			continue;
2674 		}
2675 
2676 		ase = ase_find(conn, id);
2677 		if (!ase) {
2678 			LOG_DBG("Invalid operation for idle ASE");
2679 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2680 					BT_BAP_ASCS_REASON_NONE);
2681 			continue;
2682 		}
2683 
2684 		ase_disable(ase, BT_HCI_ERR_REMOTE_USER_TERM_CONN, &rsp);
2685 		ascs_cp_rsp_add(id, rsp.code, rsp.reason);
2686 	}
2687 
2688 	return buf->size;
2689 }
2690 
ase_stop(struct bt_ascs_ase * ase)2691 static void ase_stop(struct bt_ascs_ase *ase)
2692 {
2693 	struct bt_bap_stream *stream;
2694 	struct bt_bap_ep *ep;
2695 	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
2696 						     BT_BAP_ASCS_REASON_NONE);
2697 	int err;
2698 
2699 	LOG_DBG("ase %p", ase);
2700 
2701 	ep = &ase->ep;
2702 
2703 	if (ep->status.state != BT_BAP_EP_STATE_DISABLING) {
2704 		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
2705 		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2706 				BT_BAP_ASCS_REASON_NONE);
2707 		return;
2708 	}
2709 
2710 	stream = ep->stream;
2711 	if (unicast_server_cb != NULL && unicast_server_cb->stop != NULL) {
2712 		err = unicast_server_cb->stop(stream, &rsp);
2713 	} else {
2714 		err = -ENOTSUP;
2715 		rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2716 				      BT_BAP_ASCS_REASON_NONE);
2717 	}
2718 
2719 	if (err) {
2720 		ascs_app_rsp_warn_valid(&rsp);
2721 
2722 		if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
2723 			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2724 					      BT_BAP_ASCS_REASON_NONE);
2725 		}
2726 
2727 		LOG_ERR("Stop failed: err %d, code %u, reason %u", err, rsp.code, rsp.reason);
2728 		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
2729 		return;
2730 	}
2731 
2732 	/* If the Receiver Stop Ready operation has completed successfully the
2733 	 * Unicast Client or the Unicast Server may terminate a CIS established
2734 	 * for that ASE by following the Connected Isochronous Stream Terminate
2735 	 * procedure defined in Volume 3, Part C, Section 9.3.15.
2736 	 */
2737 	if (bt_bap_stream_can_disconnect(stream)) {
2738 		err = ascs_disconnect_stream(stream);
2739 		if (err < 0) {
2740 			LOG_ERR("Failed to disconnect stream %p: %d", stream, err);
2741 		}
2742 	}
2743 
2744 	ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
2745 
2746 	ascs_cp_rsp_success(ASE_ID(ase));
2747 }
2748 
is_valid_stop_len(struct bt_conn * conn,struct net_buf_simple * buf)2749 static bool is_valid_stop_len(struct bt_conn *conn, struct net_buf_simple *buf)
2750 {
2751 	const struct bt_ascs_stop_op *op;
2752 	struct net_buf_simple_state state;
2753 
2754 	net_buf_simple_save(buf, &state);
2755 
2756 	if (buf->len < sizeof(*op)) {
2757 		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
2758 		return false;
2759 	}
2760 
2761 	op = net_buf_simple_pull_mem(buf, sizeof(*op));
2762 	if (op->num_ases < 1U) {
2763 		LOG_WRN("Number_of_ASEs parameter value is less than 1");
2764 		return false;
2765 	}
2766 
2767 	if (buf->len != op->num_ases) {
2768 		LOG_WRN("Number_of_ASEs mismatch");
2769 		return false;
2770 	}
2771 
2772 	net_buf_simple_restore(buf, &state);
2773 
2774 	return true;
2775 }
2776 
ascs_stop(struct bt_conn * conn,struct net_buf_simple * buf)2777 static ssize_t ascs_stop(struct bt_conn *conn, struct net_buf_simple *buf)
2778 {
2779 	const struct bt_ascs_start_op *req;
2780 	int i;
2781 
2782 	if (!is_valid_stop_len(conn, buf)) {
2783 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
2784 	}
2785 
2786 	req = net_buf_simple_pull_mem(buf, sizeof(*req));
2787 
2788 	LOG_DBG("num_ases %u", req->num_ases);
2789 
2790 	for (i = 0; i < req->num_ases; i++) {
2791 		struct bt_ascs_ase *ase;
2792 		uint8_t id;
2793 
2794 		id = net_buf_simple_pull_u8(buf);
2795 
2796 		LOG_DBG("ase 0x%02x", id);
2797 
2798 		if (!is_valid_ase_id(id)) {
2799 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
2800 					BT_BAP_ASCS_REASON_NONE);
2801 			LOG_WRN("Unknown ase 0x%02x", id);
2802 			continue;
2803 		}
2804 
2805 		/* If the ASE_ID  written by the client represents a Sink ASE, the
2806 		 * server shall not accept the Receiver Stop Ready operation for that
2807 		 * ASE. The server shall send a notification of the ASE Control Point
2808 		 * characteristic to the client, and the server shall set the
2809 		 * Response_Code value for that ASE to 0x05 (Invalid ASE direction).
2810 		 */
2811 		if (ASE_DIR(id) == BT_AUDIO_DIR_SINK) {
2812 			LOG_WRN("Stop failed: invalid operation for Sink");
2813 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_DIR,
2814 					BT_BAP_ASCS_REASON_NONE);
2815 			continue;
2816 		}
2817 
2818 		ase = ase_find(conn, id);
2819 		if (!ase) {
2820 			LOG_DBG("Invalid operation for idle ASE");
2821 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2822 					BT_BAP_ASCS_REASON_NONE);
2823 			continue;
2824 		}
2825 
2826 		ase_stop(ase);
2827 	}
2828 
2829 	return buf->size;
2830 }
2831 
is_valid_metadata_len(struct bt_conn * conn,struct net_buf_simple * buf)2832 static bool is_valid_metadata_len(struct bt_conn *conn, struct net_buf_simple *buf)
2833 {
2834 	const struct bt_ascs_metadata_op *op;
2835 	struct net_buf_simple_state state;
2836 
2837 	net_buf_simple_save(buf, &state);
2838 
2839 	if (buf->len < sizeof(*op)) {
2840 		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
2841 		return false;
2842 	}
2843 
2844 	op = net_buf_simple_pull_mem(buf, sizeof(*op));
2845 	if (!is_valid_num_ases(conn, op->num_ases)) {
2846 		return false;
2847 	}
2848 
2849 	for (uint8_t i = 0U; i < op->num_ases; i++) {
2850 		const struct bt_ascs_metadata *metadata;
2851 
2852 		if (buf->len < sizeof(*metadata)) {
2853 			LOG_WRN("Malformed params array");
2854 			return false;
2855 		}
2856 
2857 		metadata = net_buf_simple_pull_mem(buf, sizeof(*metadata));
2858 		if (buf->len < metadata->len) {
2859 			LOG_WRN("Malformed metadata");
2860 			return false;
2861 		}
2862 
2863 		(void)net_buf_simple_pull_mem(buf, metadata->len);
2864 	}
2865 
2866 	if (buf->len > 0) {
2867 		LOG_WRN("Unexpected data");
2868 		return false;
2869 	}
2870 
2871 	net_buf_simple_restore(buf, &state);
2872 
2873 	return true;
2874 }
2875 
ascs_metadata(struct bt_conn * conn,struct net_buf_simple * buf)2876 static ssize_t ascs_metadata(struct bt_conn *conn, struct net_buf_simple *buf)
2877 {
2878 	const struct bt_ascs_metadata_op *req;
2879 	struct bt_ascs_metadata *meta;
2880 	int i;
2881 
2882 	if (!is_valid_metadata_len(conn, buf)) {
2883 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
2884 	}
2885 
2886 	req = net_buf_simple_pull_mem(buf, sizeof(*req));
2887 
2888 	LOG_DBG("num_ases %u", req->num_ases);
2889 
2890 	for (i = 0; i < req->num_ases; i++) {
2891 		struct bt_ascs_ase *ase;
2892 
2893 		meta = net_buf_simple_pull_mem(buf, sizeof(*meta));
2894 		(void)net_buf_simple_pull(buf, meta->len);
2895 
2896 		if (meta->len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
2897 			LOG_DBG("Cannot store %u octets of metadata", meta->len);
2898 
2899 			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_NO_MEM,
2900 					BT_BAP_ASCS_REASON_NONE);
2901 			continue;
2902 		}
2903 
2904 		if (!is_valid_ase_id(meta->ase)) {
2905 			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
2906 					BT_BAP_ASCS_REASON_NONE);
2907 			LOG_WRN("Unknown ase 0x%02x", meta->ase);
2908 			continue;
2909 		}
2910 
2911 		ase = ase_find(conn, meta->ase);
2912 		if (!ase) {
2913 			LOG_DBG("Invalid operation for idle ase 0x%02x", meta->ase);
2914 			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2915 					BT_BAP_ASCS_REASON_NONE);
2916 			continue;
2917 		}
2918 
2919 		ase_metadata(ase, meta);
2920 	}
2921 
2922 	return buf->size;
2923 }
2924 
is_valid_release_len(struct bt_conn * conn,struct net_buf_simple * buf)2925 static bool is_valid_release_len(struct bt_conn *conn, struct net_buf_simple *buf)
2926 {
2927 	const struct bt_ascs_release_op *op;
2928 	struct net_buf_simple_state state;
2929 
2930 	net_buf_simple_save(buf, &state);
2931 
2932 	if (buf->len < sizeof(*op)) {
2933 		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
2934 		return false;
2935 	}
2936 
2937 	op = net_buf_simple_pull_mem(buf, sizeof(*op));
2938 	if (!is_valid_num_ases(conn, op->num_ases)) {
2939 		return false;
2940 	}
2941 
2942 	if (buf->len != op->num_ases) {
2943 		LOG_WRN("Number_of_ASEs mismatch");
2944 		return false;
2945 	}
2946 
2947 	net_buf_simple_restore(buf, &state);
2948 
2949 	return true;
2950 }
2951 
ascs_release(struct bt_conn * conn,struct net_buf_simple * buf)2952 static ssize_t ascs_release(struct bt_conn *conn, struct net_buf_simple *buf)
2953 {
2954 	const struct bt_ascs_release_op *req;
2955 	int i;
2956 
2957 	if (!is_valid_release_len(conn, buf)) {
2958 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
2959 	}
2960 
2961 	req = net_buf_simple_pull_mem(buf, sizeof(*req));
2962 
2963 	LOG_DBG("num_ases %u", req->num_ases);
2964 
2965 	for (i = 0; i < req->num_ases; i++) {
2966 		struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
2967 							     BT_BAP_ASCS_REASON_NONE);
2968 		struct bt_ascs_ase *ase;
2969 		uint8_t id;
2970 
2971 		id = net_buf_simple_pull_u8(buf);
2972 
2973 		LOG_DBG("ase 0x%02x", id);
2974 
2975 		if (!is_valid_ase_id(id)) {
2976 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
2977 					BT_BAP_ASCS_REASON_NONE);
2978 			LOG_WRN("Unknown ase 0x%02x", id);
2979 			continue;
2980 		}
2981 
2982 		ase = ase_find(conn, id);
2983 		if (!ase) {
2984 			LOG_DBG("Invalid operation for idle ASE");
2985 			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
2986 					BT_BAP_ASCS_REASON_NONE);
2987 			continue;
2988 		}
2989 
2990 		ase_release(ase, BT_HCI_ERR_REMOTE_USER_TERM_CONN, &rsp);
2991 		ascs_cp_rsp_add(id, rsp.code, rsp.reason);
2992 	}
2993 
2994 	return buf->size;
2995 }
2996 
ascs_cp_write(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * data,uint16_t len,uint16_t offset,uint8_t flags)2997 static ssize_t ascs_cp_write(struct bt_conn *conn,
2998 			     const struct bt_gatt_attr *attr, const void *data,
2999 			     uint16_t len, uint16_t offset, uint8_t flags)
3000 {
3001 	const struct bt_ascs_ase_cp *req;
3002 	struct net_buf_simple buf;
3003 	ssize_t ret;
3004 
3005 	if (flags & BT_GATT_WRITE_FLAG_PREPARE) {
3006 		/* Return 0 to allow long writes */
3007 		return 0;
3008 	}
3009 
3010 	if (offset != 0 && (flags & BT_GATT_WRITE_FLAG_EXECUTE) == 0) {
3011 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
3012 	}
3013 
3014 	if (len < sizeof(*req)) {
3015 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
3016 	}
3017 
3018 	net_buf_simple_init_with_data(&buf, (void *) data, len);
3019 
3020 	req = net_buf_simple_pull_mem(&buf, sizeof(*req));
3021 
3022 	LOG_DBG("conn %p attr %p buf %p len %u op %s (0x%02x)",
3023 		(void *)conn, attr, data, len, bt_ascs_op_str(req->op), req->op);
3024 
3025 	ascs_cp_rsp_init(req->op);
3026 
3027 	switch (req->op) {
3028 	case BT_ASCS_CONFIG_OP:
3029 		ret = ascs_config(conn, &buf);
3030 		break;
3031 	case BT_ASCS_QOS_OP:
3032 		ret = ascs_qos(conn, &buf);
3033 		break;
3034 	case BT_ASCS_ENABLE_OP:
3035 		ret = ascs_enable(conn, &buf);
3036 		break;
3037 	case BT_ASCS_START_OP:
3038 		ret = ascs_start(conn, &buf);
3039 		break;
3040 	case BT_ASCS_DISABLE_OP:
3041 		ret = ascs_disable(conn, &buf);
3042 		break;
3043 	case BT_ASCS_STOP_OP:
3044 		ret = ascs_stop(conn, &buf);
3045 		break;
3046 	case BT_ASCS_METADATA_OP:
3047 		ret = ascs_metadata(conn, &buf);
3048 		break;
3049 	case BT_ASCS_RELEASE_OP:
3050 		ret = ascs_release(conn, &buf);
3051 		break;
3052 	default:
3053 		ascs_cp_rsp_add(BT_ASCS_ASE_ID_NONE, BT_BAP_ASCS_RSP_CODE_NOT_SUPPORTED,
3054 				BT_BAP_ASCS_REASON_NONE);
3055 		LOG_DBG("Unknown opcode");
3056 		goto respond;
3057 	}
3058 
3059 	if (ret == BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN)) {
3060 		ascs_cp_rsp_add(BT_ASCS_ASE_ID_NONE, BT_BAP_ASCS_RSP_CODE_INVALID_LENGTH,
3061 				BT_BAP_ASCS_REASON_NONE);
3062 	}
3063 
3064 respond:
3065 	control_point_notify(conn, cp_rsp_buf.data, cp_rsp_buf.len);
3066 
3067 	return len;
3068 }
3069 
3070 #define BT_ASCS_ASE_DEFINE(_uuid, _id) \
3071 	BT_AUDIO_CHRC(_uuid, \
3072 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
3073 		      BT_GATT_PERM_READ_ENCRYPT, \
3074 		      ascs_ase_read, NULL, UINT_TO_POINTER(_id)), \
3075 	BT_AUDIO_CCC(ascs_ase_cfg_changed)
3076 #define BT_ASCS_ASE_SNK_DEFINE(_n, ...) BT_ASCS_ASE_DEFINE(BT_UUID_ASCS_ASE_SNK, (_n) + 1)
3077 #define BT_ASCS_ASE_SRC_DEFINE(_n, ...) BT_ASCS_ASE_DEFINE(BT_UUID_ASCS_ASE_SRC, (_n) + 1 + \
3078 							   CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT)
3079 
3080 #define BT_ASCS_CHR_ASE_CONTROL_POINT \
3081 	BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_CP, \
3082 		      BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \
3083 		      BT_GATT_PERM_WRITE_ENCRYPT | BT_GATT_PERM_PREPARE_WRITE, \
3084 		      NULL, ascs_cp_write, NULL), \
3085 	BT_AUDIO_CCC(ascs_cp_cfg_changed)
3086 
3087 #if CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT > 0
3088 #define BT_ASCS_ASE_SINKS \
3089 	LISTIFY(CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, BT_ASCS_ASE_SNK_DEFINE, (,)),
3090 #else
3091 #define BT_ASCS_ASE_SINKS
3092 #endif /* CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT > 0 */
3093 
3094 #if CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 0
3095 #define BT_ASCS_ASE_SOURCES \
3096 	LISTIFY(CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, BT_ASCS_ASE_SRC_DEFINE, (,)),
3097 #else
3098 #define BT_ASCS_ASE_SOURCES
3099 #endif /* CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT > 0 */
3100 
3101 #define BT_ASCS_SERVICE_DEFINITION() { \
3102 	BT_GATT_PRIMARY_SERVICE(BT_UUID_ASCS), \
3103 	BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_CP, \
3104 		      BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY, \
3105 		      BT_GATT_PERM_WRITE_ENCRYPT | BT_GATT_PERM_PREPARE_WRITE, \
3106 		      NULL, ascs_cp_write, NULL), \
3107 	BT_AUDIO_CCC(ascs_cp_cfg_changed), \
3108 	BT_ASCS_ASE_SINKS \
3109 	BT_ASCS_ASE_SOURCES \
3110 	}
3111 
3112 #define ASCS_ASE_CHAR_ATTR_COUNT 3 /* declaration + value + cccd */
3113 
3114 static struct bt_gatt_attr ascs_attrs[] = BT_ASCS_SERVICE_DEFINITION();
3115 static struct bt_gatt_service ascs_svc = (struct bt_gatt_service)BT_GATT_SERVICE(ascs_attrs);
3116 
configure_ase_char(uint8_t snk_cnt,uint8_t src_cnt)3117 static void configure_ase_char(uint8_t snk_cnt, uint8_t src_cnt)
3118 {
3119 	uint8_t snk_ases_to_rem = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT - snk_cnt;
3120 	uint8_t src_ases_to_rem = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT - src_cnt;
3121 	size_t attrs_to_rem;
3122 
3123 	/* Remove the Source ASEs. The ones to remove will always be at the very tail of the
3124 	 * attributes, so we just decrease the count withe the amount of sources we want to remove.
3125 	 */
3126 	attrs_to_rem = src_ases_to_rem * ASCS_ASE_CHAR_ATTR_COUNT;
3127 	ascs_svc.attr_count -= attrs_to_rem;
3128 
3129 	/* Remove the Sink ASEs.
3130 	 */
3131 	attrs_to_rem = snk_ases_to_rem * ASCS_ASE_CHAR_ATTR_COUNT;
3132 	if (CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT == 0 || CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
3133 	    == src_ases_to_rem) {
3134 		/* If there are no Source ASEs present, then we can just decrease the
3135 		 * attribute count
3136 		 */
3137 		ascs_svc.attr_count -= attrs_to_rem;
3138 	} else {
3139 		/* As Source ASEs are present, we need to iterate backwards (as this will likely be
3140 		 * the shortest distance). Find the first Sink to save, and move all Sources
3141 		 * backwards to it.
3142 		 */
3143 		size_t src_start_idx = ascs_svc.attr_count - (src_cnt * ASCS_ASE_CHAR_ATTR_COUNT);
3144 		size_t new_src_start_idx = src_start_idx - (snk_ases_to_rem *
3145 							    ASCS_ASE_CHAR_ATTR_COUNT);
3146 
3147 		for (size_t i = 0; i < src_cnt * ASCS_ASE_CHAR_ATTR_COUNT; i++) {
3148 			ascs_svc.attrs[new_src_start_idx + i] = ascs_svc.attrs[src_start_idx + i];
3149 		}
3150 
3151 		ascs_svc.attr_count -= attrs_to_rem;
3152 	}
3153 }
3154 
bt_ascs_register(uint8_t snk_cnt,uint8_t src_cnt)3155 int bt_ascs_register(uint8_t snk_cnt, uint8_t src_cnt)
3156 {
3157 	int err = 0;
3158 
3159 	if (ascs.registered) {
3160 		LOG_DBG("ASCS already registered");
3161 
3162 		return -EALREADY;
3163 	}
3164 
3165 	if (snk_cnt > CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT ||
3166 	    src_cnt > CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT) {
3167 		LOG_DBG("Provided ASE count above maximum");
3168 
3169 		return -EINVAL;
3170 	}
3171 
3172 	/* At least one ASE has been registered */
3173 	if (snk_cnt == 0 && src_cnt == 0) {
3174 		LOG_DBG("Can't register ASCS with zero ASEs");
3175 
3176 		return -EINVAL;
3177 	}
3178 
3179 	configure_ase_char(snk_cnt, src_cnt);
3180 
3181 	err = bt_gatt_service_register(&ascs_svc);
3182 	if (err != 0) {
3183 		LOG_DBG("Failed to register ASCS in gatt DB");
3184 
3185 		return err;
3186 	}
3187 
3188 	ascs.registered = true;
3189 
3190 	return err;
3191 }
3192 
control_point_notify(struct bt_conn * conn,const void * data,uint16_t len)3193 static int control_point_notify(struct bt_conn *conn, const void *data, uint16_t len)
3194 {
3195 	return bt_gatt_notify_uuid(conn, BT_UUID_ASCS_ASE_CP, ascs_svc.attrs, data, len);
3196 }
3197 
3198 static struct bt_iso_server iso_server = {
3199 	.sec_level = BT_SECURITY_L2,
3200 	.accept = ascs_iso_accept,
3201 };
3202 
bt_ascs_init(const struct bt_bap_unicast_server_cb * cb)3203 int bt_ascs_init(const struct bt_bap_unicast_server_cb *cb)
3204 {
3205 	int err;
3206 
3207 	if (!ascs.registered) {
3208 		return -ENOTSUP;
3209 	}
3210 
3211 	if (unicast_server_cb != NULL) {
3212 		return -EALREADY;
3213 	}
3214 
3215 	err = bt_iso_server_register(&iso_server);
3216 	if (err) {
3217 		LOG_ERR("Failed to register ISO server %d", err);
3218 		return err;
3219 	}
3220 
3221 	unicast_server_cb = cb;
3222 
3223 	return 0;
3224 }
3225 
bt_ascs_cleanup(void)3226 void bt_ascs_cleanup(void)
3227 {
3228 	for (size_t i = 0; i < ARRAY_SIZE(ascs.ase_pool); i++) {
3229 		struct bt_ascs_ase *ase = &ascs.ase_pool[i];
3230 
3231 		if (ase->conn != NULL) {
3232 			bt_ascs_release_ase(&ase->ep);
3233 		}
3234 	}
3235 	if (unicast_server_cb != NULL) {
3236 		bt_iso_server_unregister(&iso_server);
3237 		unicast_server_cb = NULL;
3238 	}
3239 }
3240 
bt_ascs_unregister(void)3241 int bt_ascs_unregister(void)
3242 {
3243 	int err;
3244 	struct bt_gatt_attr _ascs_attrs[] = BT_ASCS_SERVICE_DEFINITION();
3245 
3246 	if (!ascs.registered) {
3247 		LOG_DBG("No ascs instance registered");
3248 		return -EALREADY;
3249 	}
3250 
3251 	for (size_t i = 0; i < ARRAY_SIZE(ascs.ase_pool); i++) {
3252 		if (ascs.ase_pool[i].ep.status.state != BT_BAP_EP_STATE_IDLE) {
3253 			LOG_DBG("[%zu] ase %p not in idle state: %s", i, &ascs.ase_pool[i].ep,
3254 				bt_bap_ep_state_str(ascs.ase_pool[i].ep.status.state));
3255 			return -EBUSY;
3256 		}
3257 	}
3258 
3259 	err = bt_gatt_service_unregister(&ascs_svc);
3260 	/* If unregistration was successful, make sure to reset ascs_attrs so it can be used for
3261 	 * new registrations
3262 	 */
3263 	if (err != 0) {
3264 		LOG_DBG("Failed to unregister ASCS");
3265 		return err;
3266 	}
3267 
3268 	memcpy(&ascs_attrs, &_ascs_attrs, sizeof(struct bt_gatt_attr));
3269 	ascs.registered = false;
3270 
3271 	return err;
3272 }
3273 #endif /* BT_BAP_UNICAST_SERVER */
3274