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