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