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