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