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