1 /* Bluetooth ISO */
2
3 /*
4 * Copyright (c) 2020 Intel Corporation
5 * Copyright (c) 2021-2025 Nordic Semiconductor ASA
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #include <errno.h>
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <string.h>
15
16 #include <zephyr/arch/common/ffs.h>
17 #include <zephyr/autoconf.h>
18 #include <zephyr/bluetooth/buf.h>
19 #include <zephyr/bluetooth/gap.h>
20 #include <zephyr/bluetooth/hci.h>
21 #include <zephyr/bluetooth/bluetooth.h>
22 #include <zephyr/bluetooth/conn.h>
23 #include <zephyr/bluetooth/hci_types.h>
24 #include <zephyr/bluetooth/iso.h>
25 #include <zephyr/kernel.h>
26 #include <zephyr/logging/log.h>
27 #include <zephyr/net_buf.h>
28 #include <zephyr/sys/__assert.h>
29 #include <zephyr/sys/atomic.h>
30 #include <zephyr/sys/byteorder.h>
31 #include <zephyr/sys/check.h>
32 #include <zephyr/sys/slist.h>
33 #include <zephyr/sys/util.h>
34 #include <zephyr/sys/util_macro.h>
35 #include <zephyr/sys_clock.h>
36 #include <zephyr/toolchain.h>
37
38 #include "common/assert.h"
39 #include "host/buf_view.h"
40 #include "host/hci_core.h"
41 #include "host/conn_internal.h"
42 #include "iso_internal.h"
43
44 LOG_MODULE_REGISTER(bt_iso, CONFIG_BT_ISO_LOG_LEVEL);
45
46 #if defined(CONFIG_BT_DEBUG_ISO_DATA)
47 #define BT_ISO_DATA_DBG(fmt, ...) LOG_DBG(fmt, ##__VA_ARGS__)
48 #else
49 #define BT_ISO_DATA_DBG(fmt, ...)
50 #endif /* CONFIG_BT_DEBUG_ISO_DATA */
51
52 #define iso_chan(_iso) ((_iso)->iso.chan);
53
54 #if defined(CONFIG_BT_ISO_RX)
55 static atomic_ptr_t buf_rx_freed_cb;
56
iso_rx_buf_destroy(struct net_buf * buf)57 static void iso_rx_buf_destroy(struct net_buf *buf)
58 {
59 bt_iso_buf_rx_freed_cb_t cb;
60
61 cb = (bt_iso_buf_rx_freed_cb_t)atomic_ptr_get(&buf_rx_freed_cb);
62
63 net_buf_destroy(buf);
64
65 if (cb != NULL) {
66 cb();
67 }
68 }
69
70 NET_BUF_POOL_FIXED_DEFINE(iso_rx_pool, CONFIG_BT_ISO_RX_BUF_COUNT,
71 BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_RX_MTU), sizeof(struct bt_conn_rx),
72 iso_rx_buf_destroy);
73
74 static struct bt_iso_recv_info iso_info_data[CONFIG_BT_ISO_RX_BUF_COUNT];
75 #define iso_info(buf) (&iso_info_data[net_buf_id(buf)])
76 #endif /* CONFIG_BT_ISO_RX */
77
78 struct bt_conn iso_conns[CONFIG_BT_ISO_MAX_CHAN];
79
80 /* TODO: Allow more than one server? */
81 #if defined(CONFIG_BT_ISO_CENTRAL)
82 struct bt_iso_cig cigs[CONFIG_BT_ISO_MAX_CIG];
83
84 static struct bt_iso_cig *get_cig(const struct bt_iso_chan *iso_chan);
85 static int hci_le_create_cis(const struct bt_iso_connect_param *param, size_t count);
86
87 #endif /* CONFIG_BT_ISO_CENTRAL */
88
89 #if defined(CONFIG_BT_ISO_PERIPHERAL)
90 static struct bt_iso_server *iso_server;
91
92 static struct bt_conn *bt_conn_add_iso(struct bt_conn *acl);
93 #endif /* CONFIG_BT_ISO_PERIPHERAL */
94
95 #if defined(CONFIG_BT_ISO_BROADCAST)
96 struct bt_iso_big bigs[CONFIG_BT_ISO_MAX_BIG];
97
98 static struct bt_iso_big *lookup_big_by_handle(uint8_t big_handle);
99 #endif /* CONFIG_BT_ISO_BROADCAST */
100
bt_iso_sent_cb(struct bt_conn * iso,void * user_data,int err)101 static void bt_iso_sent_cb(struct bt_conn *iso, void *user_data, int err)
102 {
103 #if defined(CONFIG_BT_ISO_TX)
104 struct bt_iso_chan *chan = iso->iso.chan;
105 struct bt_iso_chan_ops *ops;
106
107 __ASSERT(chan != NULL, "NULL chan for iso %p", iso);
108
109 ops = chan->ops;
110
111 if (!err && ops != NULL && ops->sent != NULL) {
112 ops->sent(chan);
113 }
114 #endif /* CONFIG_BT_ISO_TX */
115 }
116
hci_iso(struct net_buf * buf)117 void hci_iso(struct net_buf *buf)
118 {
119 struct bt_hci_iso_hdr *hdr;
120 uint16_t handle, len;
121 struct bt_conn *iso;
122 uint8_t flags;
123
124 BT_ISO_DATA_DBG("buf %p", buf);
125
126 if (buf->len < sizeof(*hdr)) {
127 LOG_ERR("Invalid HCI ISO packet size (%u)", buf->len);
128 net_buf_unref(buf);
129 return;
130 }
131
132 hdr = net_buf_pull_mem(buf, sizeof(*hdr));
133 len = bt_iso_hdr_len(sys_le16_to_cpu(hdr->len));
134 handle = sys_le16_to_cpu(hdr->handle);
135 flags = bt_iso_flags(handle);
136
137 iso(buf)->handle = bt_iso_handle(handle);
138 iso(buf)->index = BT_CONN_INDEX_INVALID;
139
140 BT_ISO_DATA_DBG("handle %u len %u flags %u", iso(buf)->handle, len, flags);
141
142 if (buf->len != len) {
143 LOG_ERR("ISO data length mismatch (%u != %u)", buf->len, len);
144 net_buf_unref(buf);
145 return;
146 }
147
148 iso = bt_conn_lookup_handle(iso(buf)->handle, BT_CONN_TYPE_ISO);
149 if (iso == NULL) {
150 LOG_ERR("Unable to find conn for handle %u", iso(buf)->handle);
151 net_buf_unref(buf);
152 return;
153 }
154
155 iso(buf)->index = bt_conn_index(iso);
156
157 bt_conn_recv(iso, buf, flags);
158 bt_conn_unref(iso);
159 }
160
161 /* Pull data from the ISO layer */
162 static struct net_buf *iso_data_pull(struct bt_conn *conn, size_t amount, size_t *length);
163
164 /* Returns true if the ISO layer has data to send on this conn */
165 static bool iso_has_data(struct bt_conn *conn);
166
iso_get_and_clear_cb(struct bt_conn * conn,struct net_buf * buf,bt_conn_tx_cb_t * cb,void ** ud)167 static void iso_get_and_clear_cb(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t *cb,
168 void **ud)
169 {
170 if (IS_ENABLED(CONFIG_BT_ISO_TX)) {
171 *cb = bt_iso_sent_cb;
172 } else {
173 *cb = NULL;
174 }
175
176 *ud = NULL;
177 }
178
iso_new(void)179 static struct bt_conn *iso_new(void)
180 {
181 struct bt_conn *iso = bt_conn_new(iso_conns, ARRAY_SIZE(iso_conns));
182
183 if (iso) {
184 iso->type = BT_CONN_TYPE_ISO;
185 iso->tx_data_pull = iso_data_pull;
186 iso->get_and_clear_cb = iso_get_and_clear_cb;
187 iso->has_data = iso_has_data;
188 } else {
189 LOG_DBG("Could not create new ISO");
190 }
191
192 return iso;
193 }
194
hci_le_setup_iso_data_path(const struct bt_conn * iso,uint8_t dir,const struct bt_iso_chan_path * path)195 static int hci_le_setup_iso_data_path(const struct bt_conn *iso, uint8_t dir,
196 const struct bt_iso_chan_path *path)
197 {
198 struct bt_hci_cp_le_setup_iso_path *cp;
199 struct bt_hci_rp_le_setup_iso_path *rp;
200 struct net_buf *buf, *rsp;
201 uint8_t *cc;
202 int err;
203
204 buf = bt_hci_cmd_alloc(K_FOREVER);
205 if (!buf) {
206 return -ENOBUFS;
207 }
208
209 cp = net_buf_add(buf, sizeof(*cp));
210 cp->handle = sys_cpu_to_le16(iso->handle);
211 cp->path_dir = dir;
212 cp->path_id = path->pid;
213 cp->codec_id.coding_format = path->format;
214 cp->codec_id.company_id = sys_cpu_to_le16(path->cid);
215 cp->codec_id.vs_codec_id = sys_cpu_to_le16(path->vid);
216 sys_put_le24(path->delay, cp->controller_delay);
217 cp->codec_config_len = path->cc_len;
218 cc = net_buf_add(buf, path->cc_len);
219 if (path->cc_len) {
220 memcpy(cc, path->cc, path->cc_len);
221 }
222 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SETUP_ISO_PATH, buf, &rsp);
223 if (err) {
224 return err;
225 }
226
227 rp = (void *)rsp->data;
228 if (rp->status || (sys_le16_to_cpu(rp->handle) != iso->handle)) {
229 err = -EIO;
230 }
231
232 net_buf_unref(rsp);
233
234 return err;
235 }
236
bt_iso_chan_add(struct bt_conn * iso,struct bt_iso_chan * chan)237 static void bt_iso_chan_add(struct bt_conn *iso, struct bt_iso_chan *chan)
238 {
239 /* Attach ISO channel to the connection */
240 chan->iso = iso;
241 iso->iso.chan = chan;
242 k_fifo_init(&iso->iso.txq);
243
244 LOG_DBG("iso %p chan %p", iso, chan);
245 }
246
validate_iso_setup_data_path_parms(const struct bt_iso_chan * chan,uint8_t dir,const struct bt_iso_chan_path * path)247 static int validate_iso_setup_data_path_parms(const struct bt_iso_chan *chan, uint8_t dir,
248 const struct bt_iso_chan_path *path)
249 {
250 struct bt_conn *iso;
251
252 CHECKIF(chan == NULL) {
253 LOG_DBG("chan is NULL");
254
255 return -EINVAL;
256 }
257
258 CHECKIF(path == NULL) {
259 LOG_DBG("path is NULL");
260
261 return -EINVAL;
262 }
263
264 CHECKIF(dir != BT_HCI_DATAPATH_DIR_HOST_TO_CTLR &&
265 dir != BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) {
266 LOG_DBG("Invalid dir: %u", dir);
267
268 return -EINVAL;
269 }
270
271 iso = chan->iso;
272 if (iso == NULL) {
273 LOG_DBG("chan %p not associated with a CIS/BIS handle", chan);
274
275 return -ENODEV;
276 }
277
278 if (!iso->iso.info.can_recv && dir == BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) {
279 LOG_DBG("Invalid dir %u for chan %p that cannot receive data", dir, chan);
280
281 return -EINVAL;
282 }
283
284 if (!iso->iso.info.can_send && dir == BT_HCI_DATAPATH_DIR_HOST_TO_CTLR) {
285 LOG_DBG("Invalid dir %u for chan %p that cannot send data", dir, chan);
286
287 return -EINVAL;
288 }
289
290 CHECKIF(path->pid != BT_ISO_DATA_PATH_HCI &&
291 !IN_RANGE(path->pid, BT_ISO_DATA_PATH_VS_ID_MIN, BT_ISO_DATA_PATH_VS_ID_MAX)) {
292 LOG_DBG("Invalid pid %u", path->pid);
293
294 return -EINVAL;
295 }
296
297 CHECKIF(path->format > BT_HCI_CODING_FORMAT_G729A &&
298 path->format != BT_HCI_CODING_FORMAT_VS) {
299 LOG_DBG("Invalid format %u", path->format);
300
301 return -EINVAL;
302 }
303
304 CHECKIF(path->delay > BT_ISO_CONTROLLER_DELAY_MAX) {
305 LOG_DBG("Invalid delay: %u", path->delay);
306
307 return -EINVAL;
308 }
309
310 CHECKIF(path->cc_len > 0U && path->cc == NULL) {
311 LOG_DBG("No CC provided for CC length %u", path->cc_len);
312
313 return -EINVAL;
314 }
315
316 return 0;
317 }
318
bt_iso_setup_data_path(const struct bt_iso_chan * chan,uint8_t dir,const struct bt_iso_chan_path * path)319 int bt_iso_setup_data_path(const struct bt_iso_chan *chan, uint8_t dir,
320 const struct bt_iso_chan_path *path)
321 {
322 int err;
323
324 err = validate_iso_setup_data_path_parms(chan, dir, path);
325 if (err != 0) {
326 return err;
327 }
328
329 err = hci_le_setup_iso_data_path(chan->iso, dir, path);
330 if (err != 0) {
331 LOG_DBG("Failed to set data path: %d", err);
332
333 /* Return known possible errors */
334 if (err == -ENOBUFS || err == -EIO || err == -EACCES) {
335 return err;
336 }
337
338 LOG_DBG("Unknown error from hci_le_setup_iso_data_path: %d", err);
339
340 return -ENOEXEC;
341 }
342
343 return 0;
344 }
345
hci_le_remove_iso_data_path(struct bt_conn * iso,uint8_t dir)346 static int hci_le_remove_iso_data_path(struct bt_conn *iso, uint8_t dir)
347 {
348 struct bt_hci_cp_le_remove_iso_path *cp;
349 struct bt_hci_rp_le_remove_iso_path *rp;
350 struct net_buf *buf, *rsp;
351 int err;
352
353 buf = bt_hci_cmd_alloc(K_FOREVER);
354 if (!buf) {
355 return -ENOBUFS;
356 }
357
358 cp = net_buf_add(buf, sizeof(*cp));
359 cp->handle = sys_cpu_to_le16(iso->handle);
360 /* The path_dir is a bitfield and it's technically possible to do BIT(0) | BIT(1) but for
361 * simplicity our API only supports removing a single ISO data path at a time.
362 * We can convert from BT_HCI_DATAPATH_DIR_HOST_TO_CTLR and BT_HCI_DATAPATH_DIR_CTLR_TO_HOST
363 * to the proper values just by using `BIT`
364 */
365 cp->path_dir = BIT(dir);
366
367 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_REMOVE_ISO_PATH, buf, &rsp);
368 if (err) {
369 return err;
370 }
371
372 rp = (void *)rsp->data;
373 if (rp->status || (sys_le16_to_cpu(rp->handle) != iso->handle)) {
374 err = -EIO;
375 }
376
377 net_buf_unref(rsp);
378
379 return err;
380 }
381
validate_iso_remove_data_path(const struct bt_iso_chan * chan,uint8_t dir)382 static int validate_iso_remove_data_path(const struct bt_iso_chan *chan, uint8_t dir)
383 {
384 struct bt_conn *iso;
385
386 CHECKIF(chan == NULL) {
387 LOG_DBG("chan is NULL");
388
389 return -EINVAL;
390 }
391
392 CHECKIF(dir != BT_HCI_DATAPATH_DIR_HOST_TO_CTLR &&
393 dir != BT_HCI_DATAPATH_DIR_CTLR_TO_HOST) {
394 LOG_DBG("Invalid dir: %u", dir);
395
396 return -EINVAL;
397 }
398
399 iso = chan->iso;
400 if (iso == NULL) {
401 LOG_DBG("chan %p not associated with a CIS/BIS handle", chan);
402
403 return -ENODEV;
404 }
405
406 return 0;
407 }
408
bt_iso_remove_data_path(const struct bt_iso_chan * chan,uint8_t dir)409 int bt_iso_remove_data_path(const struct bt_iso_chan *chan, uint8_t dir)
410 {
411 int err;
412
413 err = validate_iso_remove_data_path(chan, dir);
414 if (err != 0) {
415 return err;
416 }
417
418 err = hci_le_remove_iso_data_path(chan->iso, dir);
419 if (err != 0) {
420 LOG_DBG("Failed to remove data path: %d", err);
421
422 /* Return known possible errors */
423 if (err == -ENOBUFS || err == -EIO || err == -EACCES) {
424 return err;
425 }
426
427 LOG_DBG("Unknown error from hci_le_remove_iso_data_path: %d", err);
428
429 return -ENOEXEC;
430 }
431
432 return 0;
433 }
434
bt_iso_connected(struct bt_conn * iso)435 void bt_iso_connected(struct bt_conn *iso)
436 {
437 struct bt_iso_chan *chan;
438
439 if (iso == NULL || iso->type != BT_CONN_TYPE_ISO) {
440 LOG_DBG("Invalid parameters: iso %p iso->type %u", iso, iso ? iso->type : 0);
441 return;
442 }
443
444 LOG_DBG("%p", iso);
445
446 chan = iso_chan(iso);
447 if (chan == NULL) {
448 LOG_ERR("Could not lookup chan from connected ISO");
449 return;
450 }
451
452 bt_iso_chan_set_state(chan, BT_ISO_STATE_CONNECTED);
453
454 if (chan->ops->connected) {
455 chan->ops->connected(chan);
456 }
457 }
458
bt_iso_chan_disconnected(struct bt_iso_chan * chan,uint8_t reason)459 static void bt_iso_chan_disconnected(struct bt_iso_chan *chan, uint8_t reason)
460 {
461 uint8_t conn_type;
462 struct net_buf *buf;
463
464 LOG_DBG("%p, reason 0x%02x", chan, reason);
465
466 __ASSERT(chan->iso != NULL, "NULL conn for iso chan %p", chan);
467
468 /* release buffers from tx_queue */
469 while ((buf = k_fifo_get(&chan->iso->iso.txq, K_NO_WAIT))) {
470 __ASSERT_NO_MSG(!bt_buf_has_view(buf));
471 net_buf_unref(buf);
472 }
473
474 bt_iso_chan_set_state(chan, BT_ISO_STATE_DISCONNECTED);
475 bt_conn_set_state(chan->iso, BT_CONN_DISCONNECT_COMPLETE);
476
477 /* Calling disconnected before final cleanup allows users to use bt_iso_chan_get_info in
478 * the callback and to be more similar to the ACL disconnected callback. This also means
479 * that the channel cannot be reused or memset in the callback
480 */
481 if (chan->ops->disconnected) {
482 chan->ops->disconnected(chan, reason);
483 }
484
485 conn_type = chan->iso->iso.info.type;
486
487 /* The peripheral does not have the concept of a CIG, so once a CIS
488 * disconnects it is completely freed by unref'ing it
489 */
490 if (IS_ENABLED(CONFIG_BT_ISO_UNICAST) &&
491 (conn_type == BT_ISO_CHAN_TYPE_CENTRAL || conn_type == BT_ISO_CHAN_TYPE_PERIPHERAL)) {
492 bt_iso_cleanup_acl(chan->iso);
493
494 if (conn_type == BT_ISO_CHAN_TYPE_PERIPHERAL) {
495 bt_conn_unref(chan->iso);
496 chan->iso = NULL;
497 #if defined(CONFIG_BT_ISO_CENTRAL)
498 } else {
499 bool is_chan_connected;
500 struct bt_iso_cig *cig;
501 struct bt_iso_chan *cis_chan;
502
503 /* Update CIG state */
504 cig = get_cig(chan);
505 __ASSERT(cig != NULL, "CIG was NULL");
506
507 is_chan_connected = false;
508 SYS_SLIST_FOR_EACH_CONTAINER(&cig->cis_channels, cis_chan, node) {
509 if (cis_chan->state != BT_ISO_STATE_DISCONNECTED) {
510 is_chan_connected = true;
511 break;
512 }
513 }
514
515 if (!is_chan_connected) {
516 cig->state = BT_ISO_CIG_STATE_INACTIVE;
517 }
518 #endif /* CONFIG_BT_ISO_CENTRAL */
519 }
520 } else if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) &&
521 conn_type == BT_ISO_CHAN_TYPE_BROADCASTER) {
522 /* BIS do not get a HCI Disconnected event and will not handle cleanup of pending TX
523 * complete in the same way as ACL and CIS do. Call bt_conn_tx_notify directly here
524 * to flush the chan->iso->tx_complete for each disconnected BIS
525 */
526 bt_conn_tx_notify(chan->iso, true);
527 } else {
528 /* No special handling for BT_ISO_CHAN_TYPE_SYNC_RECEIVER */
529 }
530 }
531
bt_iso_disconnected(struct bt_conn * iso)532 void bt_iso_disconnected(struct bt_conn *iso)
533 {
534 struct bt_iso_chan *chan;
535
536 if (iso == NULL || iso->type != BT_CONN_TYPE_ISO) {
537 LOG_DBG("Invalid parameters: iso %p iso->type %u", iso, iso ? iso->type : 0);
538 return;
539 }
540
541 LOG_DBG("%p", iso);
542
543 chan = iso_chan(iso);
544 if (chan == NULL) {
545 LOG_ERR("Could not lookup chan from disconnected ISO");
546 return;
547 }
548
549 bt_iso_chan_disconnected(chan, iso->err);
550 }
551
552 #if defined(CONFIG_BT_ISO_LOG_LEVEL_DBG)
bt_iso_chan_state_str(uint8_t state)553 const char *bt_iso_chan_state_str(uint8_t state)
554 {
555 switch (state) {
556 case BT_ISO_STATE_DISCONNECTED:
557 return "disconnected";
558 case BT_ISO_STATE_CONNECTING:
559 return "connecting";
560 case BT_ISO_STATE_ENCRYPT_PENDING:
561 return "encryption pending";
562 case BT_ISO_STATE_CONNECTED:
563 return "connected";
564 case BT_ISO_STATE_DISCONNECTING:
565 return "disconnecting";
566 default:
567 return "unknown";
568 }
569 }
570
bt_iso_chan_set_state_debug(struct bt_iso_chan * chan,enum bt_iso_state state,const char * func,int line)571 void bt_iso_chan_set_state_debug(struct bt_iso_chan *chan, enum bt_iso_state state,
572 const char *func, int line)
573 {
574 LOG_DBG("chan %p iso %p %s -> %s", chan, chan->iso, bt_iso_chan_state_str(chan->state),
575 bt_iso_chan_state_str(state));
576
577 /* check transitions validness */
578 switch (state) {
579 case BT_ISO_STATE_DISCONNECTED:
580 /* regardless of old state always allows this states */
581 break;
582 case BT_ISO_STATE_ENCRYPT_PENDING:
583 __fallthrough;
584 case BT_ISO_STATE_CONNECTING:
585 if (chan->state != BT_ISO_STATE_DISCONNECTED) {
586 LOG_WRN("%s()%d: invalid transition", func, line);
587 }
588 break;
589 case BT_ISO_STATE_CONNECTED:
590 if (chan->state != BT_ISO_STATE_CONNECTING) {
591 LOG_WRN("%s()%d: invalid transition", func, line);
592 }
593 break;
594 case BT_ISO_STATE_DISCONNECTING:
595 if (chan->state != BT_ISO_STATE_CONNECTING &&
596 chan->state != BT_ISO_STATE_CONNECTED) {
597 LOG_WRN("%s()%d: invalid transition", func, line);
598 }
599 break;
600 default:
601 LOG_ERR("%s()%d: unknown (%u) state was set", func, line, state);
602 return;
603 }
604
605 chan->state = state;
606 }
607 #else
bt_iso_chan_set_state(struct bt_iso_chan * chan,enum bt_iso_state state)608 void bt_iso_chan_set_state(struct bt_iso_chan *chan, enum bt_iso_state state)
609 {
610 chan->state = state;
611 }
612 #endif /* CONFIG_BT_ISO_LOG_LEVEL_DBG */
613
bt_iso_chan_get_info(const struct bt_iso_chan * chan,struct bt_iso_info * info)614 int bt_iso_chan_get_info(const struct bt_iso_chan *chan, struct bt_iso_info *info)
615 {
616 CHECKIF(chan == NULL) {
617 LOG_DBG("chan is NULL");
618 return -EINVAL;
619 }
620
621 CHECKIF(chan->iso == NULL) {
622 LOG_DBG("chan->iso is NULL");
623 return -EINVAL;
624 }
625
626 CHECKIF(info == NULL) {
627 LOG_DBG("info is NULL");
628 return -EINVAL;
629 }
630
631 (void)memcpy(info, &chan->iso->iso.info, sizeof(*info));
632
633 return 0;
634 }
635
636 #if defined(CONFIG_BT_ISO_RX)
bt_iso_get_rx(k_timeout_t timeout)637 struct net_buf *bt_iso_get_rx(k_timeout_t timeout)
638 {
639 struct net_buf *buf = net_buf_alloc(&iso_rx_pool, timeout);
640
641 if (buf) {
642 net_buf_add_u8(buf, BT_HCI_H4_ISO);
643 }
644
645 return buf;
646 }
647
bt_iso_buf_rx_freed_cb_set(bt_iso_buf_rx_freed_cb_t cb)648 void bt_iso_buf_rx_freed_cb_set(bt_iso_buf_rx_freed_cb_t cb)
649 {
650 atomic_ptr_set(&buf_rx_freed_cb, (void *)cb);
651 }
652
bt_iso_recv(struct bt_conn * iso,struct net_buf * buf,uint8_t flags)653 void bt_iso_recv(struct bt_conn *iso, struct net_buf *buf, uint8_t flags)
654 {
655 struct bt_hci_iso_sdu_hdr *hdr;
656 struct bt_iso_chan *chan;
657 uint8_t pb, ts;
658 uint16_t len, pkt_seq_no;
659
660 pb = bt_iso_flags_pb(flags);
661 ts = bt_iso_flags_ts(flags);
662
663 BT_ISO_DATA_DBG("handle %u len %u flags 0x%02x pb 0x%02x ts 0x%02x", iso->handle, buf->len,
664 flags, pb, ts);
665
666 /* When the PB_Flag does not equal BT_ISO_START or BT_ISO_SINGLE,
667 * the fields Time_Stamp, Packet_Sequence_Number, Packet_Status_Flag
668 * and ISO_SDU_Length are omitted from the HCI ISO Data packet.
669 */
670 switch (pb) {
671 case BT_ISO_START:
672 case BT_ISO_SINGLE:
673 iso_info(buf)->flags = 0;
674
675 /* The ISO_Data_Load field contains either the first fragment
676 * of an SDU or a complete SDU.
677 */
678 if (ts) {
679 struct bt_hci_iso_sdu_ts_hdr *ts_hdr;
680
681 ts_hdr = net_buf_pull_mem(buf, sizeof(*ts_hdr));
682 iso_info(buf)->ts = sys_le32_to_cpu(ts_hdr->ts);
683
684 hdr = &ts_hdr->sdu;
685 iso_info(buf)->flags |= BT_ISO_FLAGS_TS;
686 } else {
687 hdr = net_buf_pull_mem(buf, sizeof(*hdr));
688 /* TODO: Generate a timestamp? */
689 iso_info(buf)->ts = 0x00000000;
690 }
691
692 len = sys_le16_to_cpu(hdr->slen);
693 flags = bt_iso_pkt_flags(len);
694 len = bt_iso_pkt_len(len);
695 pkt_seq_no = sys_le16_to_cpu(hdr->sn);
696 iso_info(buf)->seq_num = pkt_seq_no;
697 if (flags == BT_ISO_DATA_VALID) {
698 iso_info(buf)->flags |= BT_ISO_FLAGS_VALID;
699 } else if (flags == BT_ISO_DATA_INVALID) {
700 iso_info(buf)->flags |= BT_ISO_FLAGS_ERROR;
701 } else if (flags == BT_ISO_DATA_NOP) {
702 iso_info(buf)->flags |= BT_ISO_FLAGS_LOST;
703 } else {
704 LOG_WRN("Invalid ISO packet status flag: %u", flags);
705 iso_info(buf)->flags = 0;
706 }
707
708 BT_ISO_DATA_DBG("%s, len %u total %u flags 0x%02x timestamp %u",
709 pb == BT_ISO_START ? "Start" : "Single", buf->len, len, flags,
710 iso_info(buf)->ts);
711
712 if (iso->rx) {
713 LOG_ERR("Unexpected ISO %s fragment",
714 pb == BT_ISO_START ? "Start" : "Single");
715 bt_conn_reset_rx_state(iso);
716 }
717
718 iso->rx = buf;
719 iso->rx_len = len - buf->len;
720 if (iso->rx_len) {
721 /* if iso->rx_len then package is longer than the
722 * buf->len and cannot fit in a SINGLE package
723 */
724 if (pb == BT_ISO_SINGLE) {
725 LOG_ERR("Unexpected ISO single fragment");
726 bt_conn_reset_rx_state(iso);
727 }
728 return;
729 }
730 break;
731
732 case BT_ISO_CONT:
733 /* The ISO_Data_Load field contains a continuation fragment of
734 * an SDU.
735 */
736 if (!iso->rx) {
737 LOG_ERR("Unexpected ISO continuation fragment");
738 net_buf_unref(buf);
739 return;
740 }
741
742 BT_ISO_DATA_DBG("Cont, len %u rx_len %u", buf->len, iso->rx_len);
743
744 if (buf->len > net_buf_tailroom(iso->rx)) {
745 LOG_ERR("Not enough buffer space for ISO data");
746 bt_conn_reset_rx_state(iso);
747 net_buf_unref(buf);
748 return;
749 }
750
751 net_buf_add_mem(iso->rx, buf->data, buf->len);
752 iso->rx_len -= buf->len;
753 net_buf_unref(buf);
754 return;
755
756 case BT_ISO_END:
757 /* The ISO_Data_Load field contains the last fragment of an
758 * SDU.
759 */
760 BT_ISO_DATA_DBG("End, len %u rx_len %u", buf->len, iso->rx_len);
761
762 if (iso->rx == NULL) {
763 LOG_ERR("Unexpected ISO end fragment");
764 net_buf_unref(buf);
765 return;
766 }
767
768 if (buf->len > net_buf_tailroom(iso->rx)) {
769 LOG_ERR("Not enough buffer space for ISO data");
770 bt_conn_reset_rx_state(iso);
771 net_buf_unref(buf);
772 return;
773 }
774
775 (void)net_buf_add_mem(iso->rx, buf->data, buf->len);
776 iso->rx_len -= buf->len;
777 net_buf_unref(buf);
778
779 break;
780 default:
781 LOG_ERR("Unexpected ISO pb flags (0x%02x)", pb);
782 bt_conn_reset_rx_state(iso);
783 net_buf_unref(buf);
784 return;
785 }
786
787 chan = iso_chan(iso);
788 if (chan == NULL) {
789 LOG_ERR("Could not lookup chan from receiving ISO");
790 } else if (chan->ops->recv != NULL) {
791 chan->ops->recv(chan, iso_info(iso->rx), iso->rx);
792 }
793
794 bt_conn_reset_rx_state(iso);
795 }
796 #endif /* CONFIG_BT_ISO_RX */
797
iso_has_data(struct bt_conn * conn)798 static bool iso_has_data(struct bt_conn *conn)
799 {
800 #if defined(CONFIG_BT_ISO_TX)
801 return ((conn->iso.chan->state == BT_ISO_STATE_CONNECTED) &&
802 !k_fifo_is_empty(&conn->iso.txq));
803 #else /* !CONFIG_BT_ISO_TX */
804 return false;
805 #endif /* CONFIG_BT_ISO_TX */
806 }
807
iso_data_pull(struct bt_conn * conn,size_t amount,size_t * length)808 static struct net_buf *iso_data_pull(struct bt_conn *conn, size_t amount, size_t *length)
809 {
810 #if defined(CONFIG_BT_ISO_TX)
811 BT_ISO_DATA_DBG("conn %p amount %d", conn, amount);
812
813 /* Leave the PDU buffer in the queue until we have sent all its
814 * fragments.
815 */
816 struct net_buf *q_frag = k_fifo_peek_head(&conn->iso.txq);
817
818 if (!q_frag) {
819 BT_ISO_DATA_DBG("signaled ready but no frag available");
820 /* Service other connections */
821 bt_tx_irq_raise();
822
823 return NULL;
824 }
825
826 __ASSERT_NO_MSG(conn->state == BT_CONN_CONNECTED);
827
828 if (conn->iso.chan->state != BT_ISO_STATE_CONNECTED) {
829 LOG_DBG("channel has been disconnected");
830
831 /* Service other connections */
832 bt_tx_irq_raise();
833
834 return NULL;
835 }
836
837 if (bt_buf_has_view(q_frag)) {
838 /* This should not happen. conn.c should wait until the view is
839 * destroyed before requesting more data.
840 */
841 LOG_DBG("already have view");
842 return NULL;
843 }
844
845 struct net_buf *frag = net_buf_ref(q_frag);
846 bool last_frag = amount >= frag->len;
847
848 if (last_frag) {
849 q_frag = k_fifo_get(&conn->iso.txq, K_NO_WAIT);
850
851 BT_ISO_DATA_DBG("last frag, pop buf");
852 __ASSERT_NO_MSG(q_frag == frag);
853
854 net_buf_unref(q_frag);
855 }
856
857 *length = frag->len;
858
859 return frag;
860 #else
861 return NULL;
862 #endif
863 }
864
865 #if defined(CONFIG_BT_ISO_TX)
iso_chan_max_data_len(const struct bt_iso_chan * chan)866 static uint16_t iso_chan_max_data_len(const struct bt_iso_chan *chan)
867 {
868 size_t max_controller_data_len;
869 uint16_t max_data_len;
870
871 if (chan->qos->tx == NULL) {
872 return 0;
873 }
874
875 max_data_len = chan->qos->tx->sdu;
876
877 /* Ensure that the SDU fits when using all the buffers */
878 max_controller_data_len = bt_dev.le.iso_mtu * bt_dev.le.iso_limit;
879
880 /* Update the max_data_len to take the max_controller_data_len into account */
881 max_data_len = MIN(max_data_len, max_controller_data_len);
882
883 return max_data_len;
884 }
885
conn_iso_send(struct bt_conn * conn,struct net_buf * buf,enum bt_iso_timestamp has_ts)886 int conn_iso_send(struct bt_conn *conn, struct net_buf *buf, enum bt_iso_timestamp has_ts)
887 {
888 if (buf->user_data_size < CONFIG_BT_CONN_TX_USER_DATA_SIZE) {
889 LOG_ERR("not enough room in user_data %d < %d pool %u", buf->user_data_size,
890 CONFIG_BT_CONN_TX_USER_DATA_SIZE, buf->pool_id);
891 return -EINVAL;
892 }
893
894 k_fifo_put(&conn->iso.txq, buf);
895 BT_ISO_DATA_DBG("%p put on list", buf);
896
897 /* only one ISO channel per conn-object */
898 bt_conn_data_ready(conn);
899
900 return 0;
901 }
902
validate_send(const struct bt_iso_chan * chan,const struct net_buf * buf,uint8_t hdr_size)903 static int validate_send(const struct bt_iso_chan *chan, const struct net_buf *buf,
904 uint8_t hdr_size)
905 {
906 const struct bt_conn *iso_conn;
907 uint16_t max_data_len;
908
909 CHECKIF(!chan || !buf) {
910 LOG_DBG("Invalid parameters: chan %p buf %p", chan, buf);
911 return -EINVAL;
912 }
913
914 BT_ISO_DATA_DBG("chan %p len %zu", chan, net_buf_frags_len(buf));
915
916 if (chan->state != BT_ISO_STATE_CONNECTED) {
917 LOG_DBG("Channel %p not connected", chan);
918 return -ENOTCONN;
919 }
920
921 iso_conn = chan->iso;
922 if (!iso_conn->iso.info.can_send) {
923 LOG_DBG("Channel %p not able to send", chan);
924 return -EINVAL;
925 }
926
927 if (net_buf_headroom(buf) != BT_BUF_ISO_SIZE(0)) {
928 LOG_DBG("Buffer headroom (%d) != BT_BUF_ISO_SIZE(0) (%d) bytes",
929 net_buf_headroom(buf), BT_BUF_ISO_SIZE(0));
930
931 /* DO NOT remove this check. We rely on precise headroom further
932 * below in the stack to determine if `buf` contains a timestamp
933 * field or not. See conn.c:contains_iso_timestamp.
934 */
935
936 return -EMSGSIZE;
937 }
938
939 if (buf->size < hdr_size) {
940 LOG_DBG("Channel %p cannot send ISO packet with buffer size %u", chan, buf->size);
941
942 return -EMSGSIZE;
943 }
944
945 max_data_len = iso_chan_max_data_len(chan);
946 if (buf->len > max_data_len) {
947 LOG_DBG("Channel %p cannot send %u octets, maximum %u", chan, buf->len,
948 max_data_len);
949 return -EMSGSIZE;
950 }
951
952 return 0;
953 }
954
bt_iso_chan_send(struct bt_iso_chan * chan,struct net_buf * buf,uint16_t seq_num)955 int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq_num)
956 {
957 struct bt_hci_iso_sdu_hdr *hdr;
958 struct bt_conn *iso_conn;
959 int err;
960
961 err = validate_send(chan, buf, BT_HCI_ISO_SDU_HDR_SIZE);
962 if (err != 0) {
963 return err;
964 }
965
966 BT_ISO_DATA_DBG("chan %p len %zu", chan, net_buf_frags_len(buf));
967
968 hdr = net_buf_push(buf, sizeof(*hdr));
969 hdr->sn = sys_cpu_to_le16(seq_num);
970 hdr->slen = sys_cpu_to_le16(
971 bt_iso_pkt_len_pack(net_buf_frags_len(buf) - sizeof(*hdr), BT_ISO_DATA_VALID));
972
973 iso_conn = chan->iso;
974
975 return conn_iso_send(iso_conn, buf, BT_ISO_TS_ABSENT);
976 }
977
bt_iso_chan_send_ts(struct bt_iso_chan * chan,struct net_buf * buf,uint16_t seq_num,uint32_t ts)978 int bt_iso_chan_send_ts(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq_num,
979 uint32_t ts)
980 {
981 struct bt_hci_iso_sdu_ts_hdr *hdr;
982 struct bt_conn *iso_conn;
983 int err;
984
985 err = validate_send(chan, buf, BT_HCI_ISO_SDU_TS_HDR_SIZE);
986 if (err != 0) {
987 return err;
988 }
989
990 BT_ISO_DATA_DBG("chan %p len %zu ts %u", chan, net_buf_frags_len(buf), ts);
991
992 hdr = net_buf_push(buf, sizeof(*hdr));
993 hdr->ts = sys_cpu_to_le32(ts);
994 hdr->sdu.sn = sys_cpu_to_le16(seq_num);
995 hdr->sdu.slen = sys_cpu_to_le16(
996 bt_iso_pkt_len_pack(net_buf_frags_len(buf) - sizeof(*hdr), BT_ISO_DATA_VALID));
997
998 iso_conn = chan->iso;
999
1000 return conn_iso_send(iso_conn, buf, BT_ISO_TS_PRESENT);
1001 }
1002
1003 #if defined(CONFIG_BT_ISO_CENTRAL) || defined(CONFIG_BT_ISO_BROADCASTER)
valid_chan_io_qos(const struct bt_iso_chan_io_qos * io_qos,bool is_tx,bool is_broadcast,bool advanced)1004 static bool valid_chan_io_qos(const struct bt_iso_chan_io_qos *io_qos, bool is_tx,
1005 bool is_broadcast, bool advanced)
1006 {
1007 if (!IN_RANGE(io_qos->phy, BT_GAP_LE_PHY_1M, BT_GAP_LE_PHY_CODED)) {
1008 LOG_DBG("Invalid PHY %u", io_qos->phy);
1009
1010 return false;
1011 }
1012
1013 if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) && is_broadcast &&
1014 io_qos->rtn > BT_ISO_BROADCAST_RTN_MAX) {
1015 LOG_DBG("Invalid RTN %u", io_qos->phy);
1016
1017 return false;
1018 }
1019
1020 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
1021 if (advanced) {
1022 if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) && is_broadcast) {
1023 if (!IN_RANGE(io_qos->max_pdu, BT_ISO_BROADCAST_PDU_MIN, BT_ISO_PDU_MAX)) {
1024 LOG_DBG("Invalid broadcast PDU %u", io_qos->max_pdu);
1025
1026 return false;
1027 }
1028 } else if (IS_ENABLED(CONFIG_BT_ISO_CENTRAL)) {
1029 if (!IN_RANGE(io_qos->max_pdu, BT_ISO_CONNECTED_PDU_MIN, BT_ISO_PDU_MAX)) {
1030 LOG_DBG("Invalid unicast PDU %u", io_qos->max_pdu);
1031
1032 return false;
1033 }
1034 }
1035
1036 if (!IN_RANGE(io_qos->burst_number, BT_ISO_BN_MIN, BT_ISO_BN_MAX)) {
1037 LOG_DBG("Invalid BN %u", io_qos->burst_number);
1038
1039 return false;
1040 }
1041 }
1042 #else
1043 ARG_UNUSED(advanced);
1044 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
1045
1046 return true;
1047 }
1048 #endif /* CONFIG_BT_ISO_CENTRAL || CONFIG_BT_ISO_BROADCASTER */
1049
bt_iso_chan_get_tx_sync(const struct bt_iso_chan * chan,struct bt_iso_tx_info * info)1050 int bt_iso_chan_get_tx_sync(const struct bt_iso_chan *chan, struct bt_iso_tx_info *info)
1051 {
1052 struct bt_hci_cp_le_read_iso_tx_sync *cp;
1053 struct bt_hci_rp_le_read_iso_tx_sync *rp;
1054 struct net_buf *buf;
1055 struct net_buf *rsp = NULL;
1056 int err;
1057
1058 CHECKIF(chan == NULL) {
1059 LOG_DBG("chan is NULL");
1060 return -EINVAL;
1061 }
1062
1063 CHECKIF(chan->iso == NULL) {
1064 LOG_DBG("chan->iso is NULL");
1065 return -EINVAL;
1066 }
1067
1068 CHECKIF(info == NULL) {
1069 LOG_DBG("info is NULL");
1070 return -EINVAL;
1071 }
1072
1073 CHECKIF(chan->state != BT_ISO_STATE_CONNECTED) {
1074 return -ENOTCONN;
1075 }
1076
1077 buf = bt_hci_cmd_alloc(K_FOREVER);
1078 if (!buf) {
1079 return -ENOMEM;
1080 }
1081
1082 cp = net_buf_add(buf, sizeof(*cp));
1083 cp->handle = sys_cpu_to_le16(chan->iso->handle);
1084
1085 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_ISO_TX_SYNC, buf, &rsp);
1086 if (err) {
1087 return err;
1088 }
1089
1090 if (rsp) {
1091 rp = (struct bt_hci_rp_le_read_iso_tx_sync *)rsp->data;
1092
1093 info->ts = sys_le32_to_cpu(rp->timestamp);
1094 info->seq_num = sys_le16_to_cpu(rp->seq);
1095 info->offset = sys_get_le24(rp->offset);
1096
1097 net_buf_unref(rsp);
1098 } else {
1099 return -ENOTSUP;
1100 }
1101
1102 return 0;
1103 }
1104 #endif /* CONFIG_BT_ISO_TX */
1105
1106 #if defined(CONFIG_BT_ISO_UNICAST)
bt_iso_chan_disconnect(struct bt_iso_chan * chan)1107 int bt_iso_chan_disconnect(struct bt_iso_chan *chan)
1108 {
1109 int err;
1110
1111 CHECKIF(!chan) {
1112 LOG_DBG("Invalid parameter: chan %p", chan);
1113 return -EINVAL;
1114 }
1115
1116 CHECKIF(chan->iso == NULL) {
1117 LOG_DBG("Channel has not been initialized in a CIG");
1118 return -EINVAL;
1119 }
1120
1121 if (chan->iso->iso.acl == NULL || chan->state == BT_ISO_STATE_DISCONNECTED) {
1122 LOG_DBG("Channel is not connected");
1123 return -ENOTCONN;
1124 }
1125
1126 if (chan->state == BT_ISO_STATE_ENCRYPT_PENDING) {
1127 LOG_DBG("Channel already disconnected");
1128 bt_iso_chan_set_state(chan, BT_ISO_STATE_DISCONNECTED);
1129
1130 if (chan->ops->disconnected) {
1131 chan->ops->disconnected(chan, BT_HCI_ERR_LOCALHOST_TERM_CONN);
1132 }
1133
1134 return 0;
1135 }
1136
1137 if (chan->state == BT_ISO_STATE_DISCONNECTING) {
1138 LOG_DBG("Already disconnecting");
1139
1140 return -EALREADY;
1141 }
1142
1143 if (IS_ENABLED(CONFIG_BT_ISO_PERIPHERAL) && chan->iso->role == BT_HCI_ROLE_PERIPHERAL &&
1144 chan->state == BT_ISO_STATE_CONNECTING) {
1145 /* A CIS peripheral is not allowed to disconnect a CIS in the connecting state - It
1146 * has to wait for a CIS Established event
1147 */
1148 return -EAGAIN;
1149 }
1150
1151 err = bt_conn_disconnect(chan->iso, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
1152 if (err == 0) {
1153 bt_iso_chan_set_state(chan, BT_ISO_STATE_DISCONNECTING);
1154 }
1155
1156 return err;
1157 }
1158
bt_iso_cleanup_acl(struct bt_conn * iso)1159 void bt_iso_cleanup_acl(struct bt_conn *iso)
1160 {
1161 LOG_DBG("%p", iso);
1162
1163 if (iso->iso.acl) {
1164 bt_conn_unref(iso->iso.acl);
1165 iso->iso.acl = NULL;
1166 }
1167 }
1168
store_cis_info(const struct bt_hci_evt_le_cis_established * evt,struct bt_conn * iso)1169 static void store_cis_info(const struct bt_hci_evt_le_cis_established *evt, struct bt_conn *iso)
1170 {
1171 struct bt_conn_iso *iso_conn = &iso->iso;
1172 struct bt_iso_info *info = &iso_conn->info;
1173 struct bt_iso_unicast_info *unicast_info = &info->unicast;
1174 struct bt_iso_unicast_tx_info *peripheral = &unicast_info->peripheral;
1175 struct bt_iso_unicast_tx_info *central = &unicast_info->central;
1176 const uint8_t c_phy = bt_get_phy(evt->c_phy);
1177 const uint8_t p_phy = bt_get_phy(evt->p_phy);
1178 struct bt_iso_chan_io_qos *tx;
1179 struct bt_iso_chan_io_qos *rx;
1180 struct bt_iso_chan *chan;
1181
1182 iso_conn = &iso->iso;
1183 chan = iso_conn->chan;
1184 rx = chan->qos->rx;
1185 tx = chan->qos->tx;
1186
1187 LOG_DBG("iso_chan %p tx %p rx %p", chan, tx, rx);
1188
1189 if (iso->role == BT_HCI_ROLE_PERIPHERAL) {
1190 /* As of BT Core 6.0, we can only get the SDU size if the controller
1191 * supports bt_hci_evt_le_cis_established_v2. Since this is not guaranteeds,
1192 * we fallback to using the PDU size as the SDU size.
1193 */
1194 if (rx != NULL) {
1195 rx->phy = c_phy;
1196 rx->sdu = sys_le16_to_cpu(evt->c_max_pdu);
1197 }
1198
1199 if (tx != NULL) {
1200 tx->phy = p_phy;
1201 tx->sdu = sys_le16_to_cpu(evt->p_max_pdu);
1202 }
1203
1204 iso_conn->info.type = BT_ISO_CHAN_TYPE_PERIPHERAL;
1205 } else {
1206 /* values are already set for central - Verify */
1207 if (tx != NULL && tx->phy != c_phy) {
1208 LOG_WRN("Unexpected C to P PHY: %u != %u", c_phy, tx->phy);
1209 /* We assume that tx->phy has become invalid, and will use the event from
1210 * the controller as the truth
1211 */
1212 tx->phy = c_phy;
1213 }
1214
1215 if (rx != NULL && rx->phy != p_phy) {
1216 LOG_WRN("Unexpected P to C max SDU: %u != %u", p_phy, rx->phy);
1217 /* We assume that rx->phy has become invalid, and will use the event from
1218 * the controller as the truth
1219 */
1220 rx->phy = p_phy;
1221 }
1222 }
1223
1224 /* Verify if device can send */
1225 iso_conn->info.can_send = false;
1226 if (tx != NULL) {
1227 if (iso->role == BT_HCI_ROLE_PERIPHERAL && evt->p_bn > 0) {
1228 iso_conn->info.can_send = true;
1229 } else if (iso->role == BT_HCI_ROLE_CENTRAL && evt->c_bn > 0) {
1230 iso_conn->info.can_send = true;
1231 }
1232 }
1233
1234 /* Verify if device can recv */
1235 iso_conn->info.can_recv = false;
1236 if (rx != NULL) {
1237 if (iso->role == BT_HCI_ROLE_PERIPHERAL && evt->c_bn > 0) {
1238 iso_conn->info.can_recv = true;
1239 } else if (iso->role == BT_HCI_ROLE_CENTRAL && evt->p_bn > 0) {
1240 iso_conn->info.can_recv = true;
1241 }
1242 }
1243
1244 info->iso_interval = sys_le16_to_cpu(evt->interval);
1245 info->max_subevent = evt->nse;
1246
1247 unicast_info->cig_sync_delay = sys_get_le24(evt->cig_sync_delay);
1248 unicast_info->cis_sync_delay = sys_get_le24(evt->cis_sync_delay);
1249 unicast_info->cig_id = iso_conn->info.unicast.cig_id;
1250 unicast_info->cis_id = iso_conn->info.unicast.cis_id;
1251
1252 central->bn = evt->c_bn;
1253 central->phy = bt_get_phy(evt->c_phy);
1254 central->latency = sys_get_le16(evt->c_latency);
1255 central->max_pdu = sys_le16_to_cpu(evt->c_max_pdu);
1256 /* Transform to n * 1.25ms */
1257 central->flush_timeout = info->iso_interval * evt->c_ft;
1258
1259 peripheral->bn = evt->p_bn;
1260 peripheral->phy = bt_get_phy(evt->p_phy);
1261 peripheral->latency = sys_get_le16(evt->p_latency);
1262 peripheral->max_pdu = sys_le16_to_cpu(evt->p_max_pdu);
1263 /* Transform to n * 1.25ms */
1264 peripheral->flush_timeout = info->iso_interval * evt->p_ft;
1265
1266 /* The following values are only available with bt_hci_evt_le_cis_established_v2 so
1267 * initialize them to the "unknown" values
1268 */
1269 unicast_info->subinterval = BT_ISO_SUBINTERVAL_UNKNOWN;
1270
1271 if (iso->role == BT_HCI_ROLE_PERIPHERAL) {
1272 central->max_sdu = central->max_pdu;
1273 central->sdu_interval = BT_ISO_SDU_INTERVAL_UNKNOWN;
1274
1275 peripheral->max_sdu = peripheral->max_pdu;
1276 peripheral->sdu_interval = BT_ISO_SDU_INTERVAL_UNKNOWN;
1277 } else {
1278 central->max_sdu = tx == NULL ? 0 : tx->sdu;
1279 central->sdu_interval = BT_ISO_SDU_INTERVAL_UNKNOWN;
1280
1281 peripheral->max_sdu = rx == NULL ? 0 : rx->sdu;
1282 peripheral->sdu_interval = BT_ISO_SDU_INTERVAL_UNKNOWN;
1283 }
1284 }
1285
1286 /** Only store information that is not stored by store_cis_info
1287 * Assumes that store_cis_info has been called first
1288 */
store_cis_info_v2(const struct bt_hci_evt_le_cis_established_v2 * evt,struct bt_conn * iso)1289 static void store_cis_info_v2(const struct bt_hci_evt_le_cis_established_v2 *evt,
1290 struct bt_conn *iso)
1291 {
1292 struct bt_conn_iso *iso_conn = &iso->iso;
1293 struct bt_iso_info *info = &iso_conn->info;
1294 struct bt_iso_unicast_info *unicast_info = &info->unicast;
1295 struct bt_iso_unicast_tx_info *peripheral = &unicast_info->peripheral;
1296 struct bt_iso_unicast_tx_info *central = &unicast_info->central;
1297 const uint16_t c_max_sdu = sys_le16_to_cpu(evt->c_max_sdu);
1298 const uint16_t p_max_sdu = sys_le16_to_cpu(evt->p_max_sdu);
1299 struct bt_iso_chan_io_qos *tx;
1300 struct bt_iso_chan_io_qos *rx;
1301 struct bt_iso_chan *chan;
1302
1303 /* The v1 version of the event is a subset of the v2 version - We can thus use the
1304 * store_cis_info function for the majority of the info
1305 */
1306 store_cis_info((const struct bt_hci_evt_le_cis_established *)evt, iso);
1307
1308 chan = iso_conn->chan;
1309 rx = chan->qos->rx;
1310 tx = chan->qos->tx;
1311
1312 if (iso->role == BT_HCI_ROLE_PERIPHERAL) {
1313 /* Update the SDU sizes in the IO QoS fields stored by store_cis_info */
1314 if (rx != NULL) {
1315 rx->sdu = c_max_sdu;
1316 }
1317
1318 if (tx != NULL) {
1319 tx->sdu = p_max_sdu;
1320 }
1321 } else {
1322 /* values are already set for central - Verify */
1323 if (tx != NULL && tx->sdu != c_max_sdu) {
1324 LOG_WRN("Unexpected C to P max SDU: %u != %u", c_max_sdu, tx->sdu);
1325 /* We assume that tx->sdu has become invalid, and will use the event from
1326 * the controller as the truth
1327 */
1328 tx->sdu = c_max_sdu;
1329 }
1330
1331 if (rx != NULL && rx->sdu != p_max_sdu) {
1332 LOG_WRN("Unexpected P to C max SDU: %u != %u", p_max_sdu, rx->sdu);
1333 /* We assume that rx->sdu has become invalid, and will use the event from
1334 * the controller as the truth
1335 */
1336 rx->sdu = p_max_sdu;
1337 }
1338 }
1339
1340 unicast_info->subinterval = sys_get_le24(evt->sub_interval);
1341
1342 central->max_sdu = sys_le16_to_cpu(evt->c_max_sdu);
1343 central->sdu_interval = sys_get_le24(evt->c_sdu_interval);
1344
1345 peripheral->max_sdu = sys_le16_to_cpu(evt->p_max_sdu);
1346 peripheral->sdu_interval = sys_get_le24(evt->p_sdu_interval);
1347 }
1348
hci_le_cis_established(struct net_buf * buf)1349 void hci_le_cis_established(struct net_buf *buf)
1350 {
1351 struct bt_hci_evt_le_cis_established *evt = (void *)buf->data;
1352 uint16_t handle = sys_le16_to_cpu(evt->conn_handle);
1353 struct bt_conn *iso;
1354
1355 LOG_DBG("status 0x%02x %s handle %u", evt->status, bt_hci_err_to_str(evt->status), handle);
1356
1357 /* ISO connection handles are already assigned at this point */
1358 iso = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ISO);
1359 if (!iso) {
1360 /* If it is a local disconnect, then we may have received the disconnect complete
1361 * event before this event, and in which case we do not expect to find the CIS
1362 * object
1363 */
1364 if (evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) {
1365 LOG_ERR("No connection found for handle %u", handle);
1366 }
1367
1368 return;
1369 }
1370
1371 if (evt->status == BT_HCI_ERR_SUCCESS) {
1372 store_cis_info(evt, iso);
1373 bt_conn_set_state(iso, BT_CONN_CONNECTED);
1374 } else if (iso->role == BT_HCI_ROLE_PERIPHERAL ||
1375 evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) {
1376 iso->err = evt->status;
1377 bt_iso_disconnected(iso);
1378 } /* else we wait for disconnect event */
1379
1380 bt_conn_unref(iso);
1381 }
1382
hci_le_cis_established_v2(struct net_buf * buf)1383 void hci_le_cis_established_v2(struct net_buf *buf)
1384 {
1385 struct bt_hci_evt_le_cis_established_v2 *evt = (void *)buf->data;
1386 uint16_t handle = sys_le16_to_cpu(evt->conn_handle);
1387 struct bt_conn *iso;
1388
1389 LOG_DBG("status 0x%02x %s handle %u", evt->status, bt_hci_err_to_str(evt->status), handle);
1390
1391 /* ISO connection handles are already assigned at this point */
1392 iso = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ISO);
1393 if (!iso) {
1394 /* If it is a local disconnect, then we may have received the disconnect complete
1395 * event before this event, and in which case we do not expect to find the CIS
1396 * object
1397 */
1398 if (evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) {
1399 LOG_ERR("No connection found for handle %u", handle);
1400 }
1401
1402 return;
1403 }
1404
1405 if (evt->status == BT_HCI_ERR_SUCCESS) {
1406 store_cis_info_v2(evt, iso);
1407 bt_conn_set_state(iso, BT_CONN_CONNECTED);
1408 } else if (iso->role == BT_HCI_ROLE_PERIPHERAL ||
1409 evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) {
1410 iso->err = evt->status;
1411 bt_iso_disconnected(iso);
1412 } /* else we wait for disconnect event */
1413
1414 bt_conn_unref(iso);
1415 }
1416
1417 #if defined(CONFIG_BT_ISO_PERIPHERAL)
bt_iso_server_register(struct bt_iso_server * server)1418 int bt_iso_server_register(struct bt_iso_server *server)
1419 {
1420 CHECKIF(!server) {
1421 LOG_DBG("Invalid parameter: server %p", server);
1422 return -EINVAL;
1423 }
1424
1425 /* Check if controller is ISO capable */
1426 if (!BT_FEAT_LE_CIS_PERIPHERAL(bt_dev.le.features)) {
1427 return -ENOTSUP;
1428 }
1429
1430 if (iso_server) {
1431 return -EADDRINUSE;
1432 }
1433
1434 if (!server->accept) {
1435 return -EINVAL;
1436 }
1437
1438 #if defined(CONFIG_BT_SMP)
1439 if (server->sec_level > BT_SECURITY_L3) {
1440 return -EINVAL;
1441 } else if (server->sec_level < BT_SECURITY_L1) {
1442 /* Level 0 is only applicable for BR/EDR */
1443 server->sec_level = BT_SECURITY_L1;
1444 }
1445 #endif /* CONFIG_BT_SMP */
1446
1447 LOG_DBG("%p", server);
1448
1449 iso_server = server;
1450
1451 return 0;
1452 }
1453
bt_iso_server_unregister(struct bt_iso_server * server)1454 int bt_iso_server_unregister(struct bt_iso_server *server)
1455 {
1456 CHECKIF(!server) {
1457 LOG_DBG("Invalid parameter: server %p", server);
1458 return -EINVAL;
1459 }
1460
1461 if (iso_server != server) {
1462 return -EINVAL;
1463 }
1464
1465 iso_server = NULL;
1466
1467 return 0;
1468 }
1469
iso_accept(struct bt_conn * acl,struct bt_conn * iso)1470 static int iso_accept(struct bt_conn *acl, struct bt_conn *iso)
1471 {
1472 struct bt_iso_accept_info accept_info;
1473 struct bt_iso_chan *chan;
1474 int err;
1475
1476 CHECKIF(!iso || iso->type != BT_CONN_TYPE_ISO) {
1477 LOG_DBG("Invalid parameters: iso %p iso->type %u", iso, iso ? iso->type : 0);
1478 return -EINVAL;
1479 }
1480
1481 LOG_DBG("%p", iso);
1482
1483 accept_info.acl = acl;
1484 accept_info.cig_id = iso->iso.info.unicast.cig_id;
1485 accept_info.cis_id = iso->iso.info.unicast.cis_id;
1486
1487 err = iso_server->accept(&accept_info, &chan);
1488 if (err < 0) {
1489 LOG_ERR("Server failed to accept: %d", err);
1490 return err;
1491 }
1492
1493 #if defined(CONFIG_BT_SMP)
1494 chan->required_sec_level = iso_server->sec_level;
1495 #endif /* CONFIG_BT_SMP */
1496
1497 bt_iso_chan_add(iso, chan);
1498 bt_iso_chan_set_state(chan, BT_ISO_STATE_CONNECTING);
1499
1500 return 0;
1501 }
1502
hci_le_reject_cis(uint16_t handle,uint8_t reason)1503 static int hci_le_reject_cis(uint16_t handle, uint8_t reason)
1504 {
1505 struct bt_hci_cp_le_reject_cis *cp;
1506 struct net_buf *buf;
1507 int err;
1508
1509 buf = bt_hci_cmd_alloc(K_FOREVER);
1510 if (!buf) {
1511 return -ENOBUFS;
1512 }
1513
1514 cp = net_buf_add(buf, sizeof(*cp));
1515 cp->handle = sys_cpu_to_le16(handle);
1516 cp->reason = reason;
1517
1518 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_REJECT_CIS, buf, NULL);
1519 if (err) {
1520 return err;
1521 }
1522
1523 return 0;
1524 }
1525
hci_le_accept_cis(uint16_t handle)1526 static int hci_le_accept_cis(uint16_t handle)
1527 {
1528 struct bt_hci_cp_le_accept_cis *cp;
1529 struct net_buf *buf;
1530 int err;
1531
1532 buf = bt_hci_cmd_alloc(K_FOREVER);
1533 if (!buf) {
1534 return -ENOBUFS;
1535 }
1536
1537 cp = net_buf_add(buf, sizeof(*cp));
1538 cp->handle = sys_cpu_to_le16(handle);
1539
1540 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_ACCEPT_CIS, buf, NULL);
1541 if (err) {
1542 return err;
1543 }
1544
1545 return 0;
1546 }
1547
iso_server_check_security(struct bt_conn * conn)1548 static uint8_t iso_server_check_security(struct bt_conn *conn)
1549 {
1550 if (IS_ENABLED(CONFIG_BT_CONN_DISABLE_SECURITY)) {
1551 return BT_HCI_ERR_SUCCESS;
1552 }
1553
1554 #if defined(CONFIG_BT_SMP)
1555 if (conn->sec_level >= iso_server->sec_level) {
1556 return BT_HCI_ERR_SUCCESS;
1557 }
1558
1559 return BT_HCI_ERR_INSUFFICIENT_SECURITY;
1560 #else
1561 return BT_HCI_ERR_SUCCESS;
1562 #endif /* CONFIG_BT_SMP */
1563 }
1564
hci_le_cis_req(struct net_buf * buf)1565 void hci_le_cis_req(struct net_buf *buf)
1566 {
1567 struct bt_hci_evt_le_cis_req *evt = (void *)buf->data;
1568 uint16_t acl_handle = sys_le16_to_cpu(evt->acl_handle);
1569 uint16_t cis_handle = sys_le16_to_cpu(evt->cis_handle);
1570 struct bt_conn *acl, *iso;
1571 uint8_t sec_err;
1572 int err;
1573
1574 LOG_DBG("acl_handle %u cis_handle %u cig_id %u cis %u", acl_handle, cis_handle, evt->cig_id,
1575 evt->cis_id);
1576
1577 if (iso_server == NULL) {
1578 LOG_DBG("No ISO server registered");
1579 hci_le_reject_cis(cis_handle, BT_HCI_ERR_UNSPECIFIED);
1580 return;
1581 }
1582
1583 /* Lookup existing connection with same handle */
1584 iso = bt_conn_lookup_handle(cis_handle, BT_CONN_TYPE_ISO);
1585 if (iso) {
1586 LOG_ERR("Invalid ISO handle %u", cis_handle);
1587 hci_le_reject_cis(cis_handle, BT_HCI_ERR_CONN_LIMIT_EXCEEDED);
1588 bt_conn_unref(iso);
1589 return;
1590 }
1591
1592 /* Lookup ACL connection to attach */
1593 acl = bt_conn_lookup_handle(acl_handle, BT_CONN_TYPE_LE);
1594 if (!acl) {
1595 LOG_ERR("Invalid ACL handle %u", acl_handle);
1596 hci_le_reject_cis(cis_handle, BT_HCI_ERR_UNKNOWN_CONN_ID);
1597 return;
1598 }
1599
1600 sec_err = iso_server_check_security(acl);
1601 if (sec_err != BT_HCI_ERR_SUCCESS) {
1602 LOG_DBG("Insufficient security %u", sec_err);
1603 err = hci_le_reject_cis(cis_handle, sec_err);
1604 if (err != 0) {
1605 LOG_ERR("Failed to reject CIS");
1606 }
1607
1608 bt_conn_unref(acl);
1609 return;
1610 }
1611
1612 /* Add ISO connection */
1613 iso = bt_conn_add_iso(acl);
1614
1615 bt_conn_unref(acl);
1616
1617 if (!iso) {
1618 LOG_ERR("Could not create and add ISO to ACL %u", acl_handle);
1619 hci_le_reject_cis(cis_handle, BT_HCI_ERR_INSUFFICIENT_RESOURCES);
1620 return;
1621 }
1622
1623 iso->iso.info.type = BT_ISO_CHAN_TYPE_PERIPHERAL;
1624 iso->iso.info.unicast.cig_id = evt->cig_id;
1625 iso->iso.info.unicast.cis_id = evt->cis_id;
1626
1627 /* Request application to accept */
1628 err = iso_accept(acl, iso);
1629 if (err) {
1630 LOG_DBG("App rejected ISO %d", err);
1631 bt_iso_cleanup_acl(iso);
1632 bt_conn_unref(iso);
1633 hci_le_reject_cis(cis_handle, BT_HCI_ERR_INSUFFICIENT_RESOURCES);
1634 return;
1635 }
1636
1637 iso->handle = cis_handle;
1638 iso->role = BT_HCI_ROLE_PERIPHERAL;
1639 bt_conn_set_state(iso, BT_CONN_INITIATING);
1640
1641 err = hci_le_accept_cis(cis_handle);
1642 if (err) {
1643 bt_iso_cleanup_acl(iso);
1644 bt_conn_unref(iso);
1645 hci_le_reject_cis(cis_handle, BT_HCI_ERR_INSUFFICIENT_RESOURCES);
1646 return;
1647 }
1648 }
1649
bt_conn_add_iso(struct bt_conn * acl)1650 static struct bt_conn *bt_conn_add_iso(struct bt_conn *acl)
1651 {
1652 struct bt_conn *iso = iso_new();
1653
1654 if (iso == NULL) {
1655 LOG_ERR("Unable to allocate ISO connection");
1656 return NULL;
1657 }
1658
1659 iso->iso.acl = bt_conn_ref(acl);
1660
1661 return iso;
1662 }
1663 #endif /* CONFIG_BT_ISO_PERIPHERAL */
1664
1665 #if defined(CONFIG_BT_ISO_CENTRAL)
valid_chan_qos(const struct bt_iso_chan_qos * qos,bool advanced)1666 static bool valid_chan_qos(const struct bt_iso_chan_qos *qos, bool advanced)
1667 {
1668 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
1669 if (advanced && !IN_RANGE(qos->num_subevents, BT_ISO_NSE_MIN, BT_ISO_NSE_MAX)) {
1670 LOG_DBG("Invalid NSE: %u", qos->num_subevents);
1671
1672 return false;
1673 }
1674 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
1675 if (qos->rx == NULL && qos->tx == NULL) {
1676 LOG_DBG("Both rx and tx qos are NULL");
1677 return false;
1678 }
1679
1680 if (qos->rx != NULL && !valid_chan_io_qos(qos->rx, false, false, advanced)) {
1681 LOG_DBG("Invalid rx qos");
1682 return false;
1683 }
1684
1685 if (qos->tx != NULL && !valid_chan_io_qos(qos->tx, true, false, advanced)) {
1686 LOG_DBG("Invalid tx qos");
1687 return false;
1688 }
1689
1690 return true;
1691 }
1692
hci_le_remove_cig(uint8_t cig_id)1693 static int hci_le_remove_cig(uint8_t cig_id)
1694 {
1695 struct bt_hci_cp_le_remove_cig *req;
1696 struct net_buf *buf;
1697
1698 buf = bt_hci_cmd_alloc(K_FOREVER);
1699 if (!buf) {
1700 return -ENOBUFS;
1701 }
1702
1703 req = net_buf_add(buf, sizeof(*req));
1704
1705 memset(req, 0, sizeof(*req));
1706
1707 req->cig_id = cig_id;
1708
1709 return bt_hci_cmd_send_sync(BT_HCI_OP_LE_REMOVE_CIG, buf, NULL);
1710 }
1711
hci_le_set_cig_params(const struct bt_iso_cig * cig,const struct bt_iso_cig_param * param)1712 static struct net_buf *hci_le_set_cig_params(const struct bt_iso_cig *cig,
1713 const struct bt_iso_cig_param *param)
1714 {
1715 struct bt_hci_cp_le_set_cig_params *req;
1716 struct bt_hci_cis_params *cis_param;
1717 struct net_buf *buf;
1718 struct net_buf *rsp;
1719 int i, err;
1720
1721 buf = bt_hci_cmd_alloc(K_FOREVER);
1722 if (!buf) {
1723 return NULL;
1724 }
1725
1726 req = net_buf_add(buf, sizeof(*req));
1727
1728 memset(req, 0, sizeof(*req));
1729
1730 req->cig_id = cig->id;
1731 req->c_latency = sys_cpu_to_le16(param->c_to_p_latency);
1732 req->p_latency = sys_cpu_to_le16(param->p_to_c_latency);
1733 sys_put_le24(param->c_to_p_interval, req->c_interval);
1734 sys_put_le24(param->p_to_c_interval, req->p_interval);
1735
1736 req->sca = param->sca;
1737 req->packing = param->packing;
1738 req->framing = param->framing;
1739 req->num_cis = param->num_cis;
1740
1741 LOG_DBG("id %u, latency C to P %u, latency P to C %u, "
1742 "interval C to P %u, interval P to C %u, "
1743 "sca %u, packing %u, framing %u, num_cis %u",
1744 cig->id, param->c_to_p_latency, param->p_to_c_latency, param->c_to_p_interval,
1745 param->p_to_c_interval, param->sca, param->packing, param->framing, param->num_cis);
1746
1747 /* Program the cis parameters */
1748 for (i = 0; i < param->num_cis; i++) {
1749 struct bt_iso_chan *cis = param->cis_channels[i];
1750 struct bt_iso_chan_qos *qos = cis->qos;
1751
1752 cis_param = net_buf_add(buf, sizeof(*cis_param));
1753
1754 memset(cis_param, 0, sizeof(*cis_param));
1755
1756 cis_param->cis_id = cis->iso->iso.info.unicast.cis_id;
1757
1758 if (!qos->tx && !qos->rx) {
1759 LOG_ERR("Both TX and RX QoS are disabled");
1760 net_buf_unref(buf);
1761 return NULL;
1762 }
1763
1764 if (!qos->tx) {
1765 /* Use RX PHY if TX is not set (disabled)
1766 * to avoid setting invalid values
1767 */
1768 cis_param->c_phy = qos->rx->phy;
1769 } else {
1770 cis_param->c_sdu = sys_cpu_to_le16(qos->tx->sdu);
1771 cis_param->c_phy = qos->tx->phy;
1772 cis_param->c_rtn = qos->tx->rtn;
1773 }
1774
1775 if (!qos->rx) {
1776 /* Use TX PHY if RX is not set (disabled)
1777 * to avoid setting invalid values
1778 */
1779 cis_param->p_phy = qos->tx->phy;
1780 } else {
1781 cis_param->p_sdu = sys_cpu_to_le16(qos->rx->sdu);
1782 cis_param->p_phy = qos->rx->phy;
1783 cis_param->p_rtn = qos->rx->rtn;
1784 }
1785
1786 LOG_DBG("[%d]: id %u, c_phy %u, c_sdu %u, c_rtn %u, p_phy %u, p_sdu %u, p_rtn %u",
1787 i, cis_param->cis_id, cis_param->c_phy, cis_param->c_sdu, cis_param->c_rtn,
1788 cis_param->p_phy, cis_param->p_sdu, cis_param->p_rtn);
1789 }
1790
1791 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CIG_PARAMS, buf, &rsp);
1792 if (err) {
1793 return NULL;
1794 }
1795
1796 return rsp;
1797 }
1798
1799 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
hci_le_set_cig_test_params(const struct bt_iso_cig * cig,const struct bt_iso_cig_param * param)1800 static struct net_buf *hci_le_set_cig_test_params(const struct bt_iso_cig *cig,
1801 const struct bt_iso_cig_param *param)
1802 {
1803 struct bt_hci_cp_le_set_cig_params_test *req;
1804 struct bt_hci_cis_params_test *cis_param;
1805 struct net_buf *buf;
1806 struct net_buf *rsp;
1807 int err;
1808
1809 buf = bt_hci_cmd_alloc(K_FOREVER);
1810 if (!buf) {
1811 return NULL;
1812 }
1813
1814 req = net_buf_add(buf, sizeof(*req));
1815
1816 memset(req, 0, sizeof(*req));
1817
1818 req->cig_id = cig->id;
1819 sys_put_le24(param->c_to_p_interval, req->c_interval);
1820 sys_put_le24(param->p_to_c_interval, req->p_interval);
1821
1822 req->c_ft = param->c_to_p_ft;
1823 req->p_ft = param->p_to_c_ft;
1824 req->iso_interval = sys_cpu_to_le16(param->iso_interval);
1825 req->sca = param->sca;
1826 req->packing = param->packing;
1827 req->framing = param->framing;
1828 req->num_cis = param->num_cis;
1829
1830 LOG_DBG("id %u, SDU interval C to P %u, SDU interval P to C %u, c_ft %u, p_ft %u, "
1831 "iso_interval %u, sca %u, packing %u, framing %u, num_cis %u",
1832 cig->id, param->c_to_p_interval, param->p_to_c_interval, param->c_to_p_ft,
1833 param->p_to_c_ft, param->iso_interval, param->sca, param->packing, param->framing,
1834 param->num_cis);
1835
1836 /* Program the cis parameters */
1837 for (uint8_t i = 0U; i < param->num_cis; i++) {
1838 const struct bt_iso_chan *cis = param->cis_channels[i];
1839 const struct bt_iso_chan_qos *qos = cis->qos;
1840
1841 cis_param = net_buf_add(buf, sizeof(*cis_param));
1842
1843 memset(cis_param, 0, sizeof(*cis_param));
1844
1845 cis_param->cis_id = cis->iso->iso.info.unicast.cis_id;
1846 cis_param->nse = qos->num_subevents;
1847
1848 if (!qos->tx && !qos->rx) {
1849 LOG_ERR("Both TX and RX QoS are disabled");
1850 net_buf_unref(buf);
1851 return NULL;
1852 }
1853
1854 if (!qos->tx) {
1855 /* Use RX PHY if TX is not set (disabled)
1856 * to avoid setting invalid values
1857 */
1858 cis_param->c_phy = qos->rx->phy;
1859 } else {
1860 cis_param->c_sdu = sys_cpu_to_le16(qos->tx->sdu);
1861 cis_param->c_pdu = sys_cpu_to_le16(qos->tx->max_pdu);
1862 cis_param->c_phy = qos->tx->phy;
1863 cis_param->c_bn = qos->tx->burst_number;
1864 }
1865
1866 if (!qos->rx) {
1867 /* Use TX PHY if RX is not set (disabled)
1868 * to avoid setting invalid values
1869 */
1870 cis_param->p_phy = qos->tx->phy;
1871 } else {
1872 cis_param->p_sdu = sys_cpu_to_le16(qos->rx->sdu);
1873 cis_param->p_pdu = sys_cpu_to_le16(qos->rx->max_pdu);
1874 cis_param->p_phy = qos->rx->phy;
1875 cis_param->p_bn = qos->rx->burst_number;
1876 }
1877
1878 LOG_DBG("[%d]: id %u, nse %u c_sdu %u, p_sdu %u, c_pdu %u, "
1879 "p_pdu %u, c_phy %u, p_phy %u, c_bn %u, p_bn %u",
1880 i, cis_param->cis_id, cis_param->nse, cis_param->c_sdu, cis_param->p_sdu,
1881 cis_param->c_pdu, cis_param->p_pdu, cis_param->c_phy, cis_param->p_phy,
1882 cis_param->c_bn, cis_param->p_bn);
1883 }
1884
1885 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CIG_PARAMS_TEST, buf, &rsp);
1886 if (err) {
1887 return NULL;
1888 }
1889
1890 return rsp;
1891 }
1892
is_advanced_cig_param(const struct bt_iso_cig_param * param)1893 static bool is_advanced_cig_param(const struct bt_iso_cig_param *param)
1894 {
1895 if (param->c_to_p_ft != 0U || param->p_to_c_ft != 0U || param->iso_interval != 0U) {
1896 return true;
1897 }
1898
1899 /* Check if any of the CIS contain any test-param-only values */
1900 for (uint8_t i = 0U; i < param->num_cis; i++) {
1901 const struct bt_iso_chan *cis = param->cis_channels[i];
1902 const struct bt_iso_chan_qos *qos = cis->qos;
1903
1904 if (qos->num_subevents > 0U) {
1905 return true;
1906 }
1907
1908 if (qos->tx != NULL) {
1909 if (qos->tx->max_pdu > 0U || qos->tx->burst_number > 0U) {
1910 return true;
1911 }
1912 }
1913
1914 if (qos->rx != NULL) {
1915 if (qos->rx->max_pdu > 0U || qos->rx->burst_number > 0U) {
1916 return true;
1917 }
1918 }
1919 }
1920
1921 return false;
1922 }
1923 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
1924
get_cig(const struct bt_iso_chan * iso_chan)1925 static struct bt_iso_cig *get_cig(const struct bt_iso_chan *iso_chan)
1926 {
1927 if (iso_chan == NULL || iso_chan->iso == NULL) {
1928 return NULL;
1929 }
1930
1931 __ASSERT(iso_chan->iso->iso.info.unicast.cig_id < ARRAY_SIZE(cigs), "Invalid cig_id %u",
1932 iso_chan->iso->iso.info.unicast.cig_id);
1933
1934 return &cigs[iso_chan->iso->iso.info.unicast.cig_id];
1935 }
1936
get_free_cig(void)1937 static struct bt_iso_cig *get_free_cig(void)
1938 {
1939 /* We can use the index in the `cigs` array as CIG ID */
1940
1941 for (size_t i = 0; i < ARRAY_SIZE(cigs); i++) {
1942 if (cigs[i].state == BT_ISO_CIG_STATE_IDLE) {
1943 cigs[i].state = BT_ISO_CIG_STATE_CONFIGURED;
1944 cigs[i].id = i;
1945 sys_slist_init(&cigs[i].cis_channels);
1946 return &cigs[i];
1947 }
1948 }
1949
1950 LOG_DBG("Could not allocate any more CIGs");
1951
1952 return NULL;
1953 }
1954
cis_is_in_cig(const struct bt_iso_cig * cig,const struct bt_iso_chan * cis)1955 static bool cis_is_in_cig(const struct bt_iso_cig *cig, const struct bt_iso_chan *cis)
1956 {
1957 if (cig == NULL || cis == NULL || cis->iso == NULL) {
1958 return false;
1959 }
1960
1961 return cig->id == cis->iso->iso.info.unicast.cig_id;
1962 }
1963
cig_init_cis(struct bt_iso_cig * cig,const struct bt_iso_cig_param * param)1964 static int cig_init_cis(struct bt_iso_cig *cig, const struct bt_iso_cig_param *param)
1965 {
1966 for (uint8_t i = 0; i < param->num_cis; i++) {
1967 struct bt_iso_chan *cis = param->cis_channels[i];
1968
1969 if (cis->iso == NULL) {
1970 struct bt_conn_iso *iso_conn;
1971
1972 cis->iso = iso_new();
1973 if (cis->iso == NULL) {
1974 LOG_ERR("Unable to allocate CIS connection");
1975 return -ENOMEM;
1976 }
1977 iso_conn = &cis->iso->iso;
1978
1979 iso_conn->info.unicast.cig_id = cig->id;
1980 iso_conn->info.type = BT_ISO_CHAN_TYPE_CENTRAL;
1981 iso_conn->info.unicast.cis_id = cig->num_cis++;
1982
1983 bt_iso_chan_add(cis->iso, cis);
1984
1985 sys_slist_append(&cig->cis_channels, &cis->node);
1986 } /* else already initialized */
1987 }
1988
1989 return 0;
1990 }
1991
cleanup_cig(struct bt_iso_cig * cig)1992 static void cleanup_cig(struct bt_iso_cig *cig)
1993 {
1994 struct bt_iso_chan *cis, *tmp;
1995
1996 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&cig->cis_channels, cis, tmp, node) {
1997 if (cis->iso != NULL) {
1998 bt_conn_unref(cis->iso);
1999 cis->iso = NULL;
2000 }
2001
2002 sys_slist_remove(&cig->cis_channels, NULL, &cis->node);
2003 }
2004
2005 memset(cig, 0, sizeof(*cig));
2006 }
2007
valid_cig_param(const struct bt_iso_cig_param * param,bool advanced,const struct bt_iso_cig * cig)2008 static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced,
2009 const struct bt_iso_cig *cig)
2010 {
2011 bool is_c_to_p = false;
2012 bool is_p_to_c = false;
2013
2014 if (param == NULL) {
2015 return false;
2016 }
2017
2018 for (uint8_t i = 0; i < param->num_cis; i++) {
2019 struct bt_iso_chan *cis = param->cis_channels[i];
2020
2021 if (cis == NULL) {
2022 LOG_DBG("cis_channels[%u]: NULL channel", i);
2023 return false;
2024 }
2025
2026 if (cis->qos == NULL) {
2027 LOG_DBG("cis_channels[%u]: NULL QoS", i);
2028 return false;
2029 }
2030
2031 if (cis->iso != NULL && !cis_is_in_cig(cig, cis)) {
2032 LOG_DBG("cis_channels[%u]: already allocated to CIG %p", i, get_cig(cis));
2033 return false;
2034 }
2035
2036 if (!valid_chan_qos(cis->qos, advanced)) {
2037 LOG_DBG("cis_channels[%u]: Invalid QOS", i);
2038 return false;
2039 }
2040
2041 for (uint8_t j = 0; j < i; j++) {
2042 if (cis == param->cis_channels[j]) {
2043 LOG_DBG("ISO %p duplicated at index %u and %u", cis, i, j);
2044 return false;
2045 }
2046 }
2047
2048 if (cis->qos->rx != NULL && cis->qos->rx->sdu != 0U) {
2049 is_p_to_c = true;
2050 }
2051
2052 if (cis->qos->tx != NULL && cis->qos->tx->sdu != 0U) {
2053 is_c_to_p = true;
2054 }
2055
2056 if (!is_p_to_c && !is_c_to_p) {
2057 LOG_DBG("Neither C to P nor P to C can be configured");
2058 return false;
2059 }
2060 }
2061
2062 if (param->framing != BT_ISO_FRAMING_UNFRAMED && param->framing != BT_ISO_FRAMING_FRAMED) {
2063 LOG_DBG("Invalid framing parameter: %u", param->framing);
2064 return false;
2065 }
2066
2067 if (param->packing != BT_ISO_PACKING_SEQUENTIAL &&
2068 param->packing != BT_ISO_PACKING_INTERLEAVED) {
2069 LOG_DBG("Invalid packing parameter: %u", param->packing);
2070 return false;
2071 }
2072
2073 if (param->num_cis > BT_ISO_MAX_GROUP_ISO_COUNT ||
2074 param->num_cis > CONFIG_BT_ISO_MAX_CHAN) {
2075 LOG_DBG("num_cis (%u) shall be lower than: %u", param->num_cis,
2076 MAX(CONFIG_BT_ISO_MAX_CHAN, BT_ISO_MAX_GROUP_ISO_COUNT));
2077 return false;
2078 }
2079
2080 if (is_c_to_p &&
2081 !IN_RANGE(param->c_to_p_interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) {
2082 LOG_DBG("Invalid C to P interval: %u", param->c_to_p_interval);
2083 return false;
2084 }
2085
2086 if (is_p_to_c &&
2087 !IN_RANGE(param->p_to_c_interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) {
2088 LOG_DBG("Invalid P to C interval: %u", param->p_to_c_interval);
2089 return false;
2090 }
2091
2092 if (!advanced) {
2093 if (is_c_to_p &&
2094 !IN_RANGE(param->c_to_p_latency, BT_ISO_LATENCY_MIN, BT_ISO_LATENCY_MAX)) {
2095 LOG_DBG("Invalid C to P latency: %u", param->c_to_p_latency);
2096 return false;
2097 }
2098
2099 if (is_p_to_c &&
2100 !IN_RANGE(param->p_to_c_latency, BT_ISO_LATENCY_MIN, BT_ISO_LATENCY_MAX)) {
2101 LOG_DBG("Invalid P to C latency: %u", param->p_to_c_latency);
2102 return false;
2103 }
2104 }
2105
2106 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
2107 if (advanced) {
2108 if (!IN_RANGE(param->c_to_p_ft, BT_ISO_FT_MIN, BT_ISO_FT_MAX)) {
2109 LOG_DBG("Invalid Central to Peripheral FT %u", param->c_to_p_ft);
2110
2111 return false;
2112 }
2113
2114 if (!IN_RANGE(param->p_to_c_ft, BT_ISO_FT_MIN, BT_ISO_FT_MAX)) {
2115 LOG_DBG("Invalid Peripheral to Central FT %u", param->p_to_c_ft);
2116
2117 return false;
2118 }
2119
2120 if (!IN_RANGE(param->iso_interval, BT_ISO_ISO_INTERVAL_MIN,
2121 BT_ISO_ISO_INTERVAL_MAX)) {
2122 LOG_DBG("Invalid ISO interval %u", param->iso_interval);
2123
2124 return false;
2125 }
2126 }
2127 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
2128
2129 return true;
2130 }
2131
bt_iso_cig_create(const struct bt_iso_cig_param * param,struct bt_iso_cig ** out_cig)2132 int bt_iso_cig_create(const struct bt_iso_cig_param *param, struct bt_iso_cig **out_cig)
2133 {
2134 int err;
2135 struct net_buf *rsp = NULL;
2136 struct bt_iso_cig *cig;
2137 struct bt_hci_rp_le_set_cig_params *cig_rsp;
2138 struct bt_iso_chan *cis;
2139 bool advanced = false;
2140 int i;
2141
2142 CHECKIF(param == NULL) {
2143 LOG_DBG("param is NULL");
2144 return -EINVAL;
2145 }
2146
2147 CHECKIF(out_cig == NULL) {
2148 LOG_DBG("out_cig is NULL");
2149 return -EINVAL;
2150 }
2151
2152 *out_cig = NULL;
2153
2154 /* Check if controller is ISO capable as a central */
2155 if (!BT_FEAT_LE_CIS_CENTRAL(bt_dev.le.features)) {
2156 return -ENOTSUP;
2157 }
2158
2159 /* TBD: Should we allow creating empty CIGs? */
2160 CHECKIF(param->cis_channels == NULL) {
2161 LOG_DBG("NULL CIS channels");
2162 return -EINVAL;
2163 }
2164
2165 CHECKIF(param->num_cis == 0) {
2166 LOG_DBG("Invalid number of CIS %u", param->num_cis);
2167 return -EINVAL;
2168 }
2169
2170 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
2171 advanced = is_advanced_cig_param(param);
2172 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
2173
2174 CHECKIF(!valid_cig_param(param, advanced, NULL)) {
2175 LOG_DBG("Invalid CIG params");
2176 return -EINVAL;
2177 }
2178
2179 cig = get_free_cig();
2180
2181 if (!cig) {
2182 return -ENOMEM;
2183 }
2184
2185 err = cig_init_cis(cig, param);
2186 if (err) {
2187 LOG_DBG("Could not init CIS %d", err);
2188 cleanup_cig(cig);
2189 return err;
2190 }
2191
2192 if (!advanced) {
2193 rsp = hci_le_set_cig_params(cig, param);
2194 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
2195 } else {
2196 rsp = hci_le_set_cig_test_params(cig, param);
2197 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
2198 }
2199
2200 if (rsp == NULL) {
2201 LOG_WRN("Unexpected response to hci_le_set_cig_params");
2202 err = -EIO;
2203 cleanup_cig(cig);
2204 return err;
2205 }
2206
2207 cig_rsp = (void *)rsp->data;
2208
2209 if (rsp->len < sizeof(*cig_rsp) || cig_rsp->num_handles != param->num_cis) {
2210 LOG_WRN("Unexpected response to hci_le_set_cig_params");
2211 err = -EIO;
2212 net_buf_unref(rsp);
2213 cleanup_cig(cig);
2214 return err;
2215 }
2216
2217 i = 0;
2218 SYS_SLIST_FOR_EACH_CONTAINER(&cig->cis_channels, cis, node) {
2219 const uint16_t handle = cig_rsp->handle[i++];
2220
2221 /* Assign the connection handle */
2222 cis->iso->handle = sys_le16_to_cpu(handle);
2223 }
2224
2225 net_buf_unref(rsp);
2226
2227 *out_cig = cig;
2228
2229 return err;
2230 }
2231
restore_cig(struct bt_iso_cig * cig,uint8_t existing_num_cis)2232 static void restore_cig(struct bt_iso_cig *cig, uint8_t existing_num_cis)
2233 {
2234 struct bt_iso_chan *cis, *tmp;
2235
2236 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&cig->cis_channels, cis, tmp, node) {
2237 /* Remove all newly added by comparing the cis_id to the number
2238 * of CIS that was previously added before
2239 * bt_iso_cig_reconfigure was called
2240 */
2241 if (cis->iso != NULL && cis->iso->iso.info.unicast.cis_id >= existing_num_cis) {
2242 bt_conn_unref(cis->iso);
2243 cis->iso = NULL;
2244
2245 sys_slist_remove(&cig->cis_channels, NULL, &cis->node);
2246 cig->num_cis--;
2247 }
2248 }
2249 }
2250
bt_iso_cig_reconfigure(struct bt_iso_cig * cig,const struct bt_iso_cig_param * param)2251 int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, const struct bt_iso_cig_param *param)
2252 {
2253 struct bt_hci_rp_le_set_cig_params *cig_rsp;
2254 uint8_t existing_num_cis;
2255 bool advanced = false;
2256 struct net_buf *rsp = NULL;
2257 int err;
2258
2259 CHECKIF(cig == NULL) {
2260 LOG_DBG("cig is NULL");
2261 return -EINVAL;
2262 }
2263
2264 CHECKIF(param == NULL) {
2265 LOG_DBG("param is NULL");
2266 return -EINVAL;
2267 }
2268
2269 if (cig->state != BT_ISO_CIG_STATE_CONFIGURED) {
2270 LOG_DBG("Invalid CIG state: %u", cig->state);
2271 return -EINVAL;
2272 }
2273
2274 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
2275 advanced = is_advanced_cig_param(param);
2276 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
2277
2278 CHECKIF(!valid_cig_param(param, advanced, cig)) {
2279 LOG_DBG("Invalid CIG params");
2280 return -EINVAL;
2281 }
2282
2283 /* Used to restore CIG in case of error */
2284 existing_num_cis = cig->num_cis;
2285
2286 err = cig_init_cis(cig, param);
2287 if (err != 0) {
2288 LOG_DBG("Could not init CIS %d", err);
2289 restore_cig(cig, existing_num_cis);
2290 return err;
2291 }
2292
2293 if (!advanced) {
2294 rsp = hci_le_set_cig_params(cig, param);
2295 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
2296 } else {
2297 rsp = hci_le_set_cig_test_params(cig, param);
2298 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
2299 }
2300
2301 if (rsp == NULL) {
2302 LOG_WRN("Unexpected response to hci_le_set_cig_params");
2303 err = -EIO;
2304 restore_cig(cig, existing_num_cis);
2305 return err;
2306 }
2307
2308 cig_rsp = (void *)rsp->data;
2309
2310 if (rsp->len < sizeof(*cig_rsp)) {
2311 LOG_WRN("Unexpected response len to hci_le_set_cig_params %u != %zu", rsp->len,
2312 sizeof(*cig_rsp));
2313 err = -EIO;
2314 net_buf_unref(rsp);
2315 restore_cig(cig, existing_num_cis);
2316 return err;
2317 }
2318
2319 if (cig_rsp->num_handles != param->num_cis) {
2320 LOG_WRN("Unexpected response num_handles to hci_le_set_cig_params %u != %u",
2321 cig_rsp->num_handles, param->num_cis);
2322 err = -EIO;
2323 net_buf_unref(rsp);
2324 restore_cig(cig, existing_num_cis);
2325 return err;
2326 }
2327
2328 for (uint8_t i = 0u; i < param->num_cis; i++) {
2329 const uint16_t handle = cig_rsp->handle[i];
2330 struct bt_iso_chan *cis = param->cis_channels[i];
2331
2332 /* Assign the connection handle */
2333 cis->iso->handle = sys_le16_to_cpu(handle);
2334 }
2335
2336 net_buf_unref(rsp);
2337
2338 return err;
2339 }
2340
bt_iso_cig_terminate(struct bt_iso_cig * cig)2341 int bt_iso_cig_terminate(struct bt_iso_cig *cig)
2342 {
2343 int err;
2344
2345 CHECKIF(cig == NULL) {
2346 LOG_DBG("cig is NULL");
2347 return -EINVAL;
2348 }
2349
2350 if (cig->state != BT_ISO_CIG_STATE_INACTIVE && cig->state != BT_ISO_CIG_STATE_CONFIGURED) {
2351 LOG_DBG("Invalid CIG state: %u", cig->state);
2352 return -EINVAL;
2353 }
2354
2355 err = hci_le_remove_cig(cig->id);
2356 if (err != 0) {
2357 LOG_DBG("Failed to terminate CIG: %d", err);
2358 return err;
2359 }
2360
2361 cleanup_cig(cig);
2362
2363 return 0;
2364 }
2365
bt_iso_security_changed(struct bt_conn * acl,uint8_t hci_status)2366 void bt_iso_security_changed(struct bt_conn *acl, uint8_t hci_status)
2367 {
2368 struct bt_iso_connect_param param[CONFIG_BT_ISO_MAX_CHAN];
2369 size_t param_count;
2370 int err;
2371
2372 /* The peripheral does not accept any ISO requests if security is
2373 * insufficient, so we only need to handle central here.
2374 * BT_ISO_STATE_ENCRYPT_PENDING is only set by the central.
2375 */
2376 if (!IS_ENABLED(CONFIG_BT_CENTRAL) || acl->role != BT_CONN_ROLE_CENTRAL) {
2377 return;
2378 }
2379
2380 param_count = 0;
2381 for (size_t i = 0; i < ARRAY_SIZE(iso_conns); i++) {
2382 struct bt_conn *iso = &iso_conns[i];
2383 struct bt_iso_chan *iso_chan;
2384
2385 if (iso == NULL || iso->iso.acl != acl) {
2386 continue;
2387 }
2388
2389 iso_chan = iso_chan(iso);
2390 if (iso_chan->state != BT_ISO_STATE_ENCRYPT_PENDING) {
2391 continue;
2392 }
2393
2394 /* Set state to disconnected to indicate that we are no longer waiting for
2395 * encryption.
2396 * TODO: Remove the BT_ISO_STATE_ENCRYPT_PENDING state and replace with a flag to
2397 * avoid these unnecessary state changes
2398 */
2399 bt_iso_chan_set_state(iso_chan, BT_ISO_STATE_DISCONNECTED);
2400
2401 if (hci_status == BT_HCI_ERR_SUCCESS) {
2402 param[param_count].acl = acl;
2403 param[param_count].iso_chan = iso_chan;
2404 param_count++;
2405 } else {
2406 LOG_DBG("Failed to encrypt ACL %p for ISO %p: %u %s", acl, iso, hci_status,
2407 bt_hci_err_to_str(hci_status));
2408
2409 /* We utilize the disconnected callback to make the
2410 * upper layers aware of the error
2411 */
2412 if (iso_chan->ops->disconnected) {
2413 iso_chan->ops->disconnected(iso_chan, hci_status);
2414 }
2415 }
2416 }
2417
2418 if (param_count == 0) {
2419 /* Nothing to do for ISO. This happens if security is changed,
2420 * but no ISO channels were pending encryption.
2421 */
2422 return;
2423 }
2424
2425 err = hci_le_create_cis(param, param_count);
2426 if (err != 0) {
2427 LOG_ERR("Failed to connect CISes: %d", err);
2428
2429 for (size_t i = 0; i < param_count; i++) {
2430 struct bt_iso_chan *iso_chan = param[i].iso_chan;
2431
2432 /* We utilize the disconnected callback to make the
2433 * upper layers aware of the error
2434 */
2435 if (iso_chan->ops->disconnected) {
2436 iso_chan->ops->disconnected(iso_chan, hci_status);
2437 }
2438 }
2439
2440 return;
2441 }
2442
2443 /* Set connection states */
2444 for (size_t i = 0; i < param_count; i++) {
2445 struct bt_iso_chan *iso_chan = param[i].iso_chan;
2446 struct bt_iso_cig *cig = get_cig(iso_chan);
2447
2448 __ASSERT(cig != NULL, "CIG was NULL");
2449 cig->state = BT_ISO_CIG_STATE_ACTIVE;
2450
2451 bt_conn_set_state(iso_chan->iso, BT_CONN_INITIATING);
2452 bt_iso_chan_set_state(iso_chan, BT_ISO_STATE_CONNECTING);
2453 }
2454 }
2455
hci_le_create_cis(const struct bt_iso_connect_param * param,size_t count)2456 static int hci_le_create_cis(const struct bt_iso_connect_param *param, size_t count)
2457 {
2458 struct bt_hci_cis *cis;
2459 struct bt_hci_cp_le_create_cis *req;
2460 struct net_buf *buf;
2461
2462 buf = bt_hci_cmd_alloc(K_FOREVER);
2463 if (!buf) {
2464 return -ENOBUFS;
2465 }
2466
2467 req = net_buf_add(buf, sizeof(*req));
2468
2469 memset(req, 0, sizeof(*req));
2470
2471 /* Program the cis parameters */
2472 for (size_t i = 0; i < count; i++) {
2473 struct bt_iso_chan *iso_chan = param[i].iso_chan;
2474
2475 if (iso_chan->state == BT_ISO_STATE_ENCRYPT_PENDING) {
2476 continue;
2477 }
2478
2479 cis = net_buf_add(buf, sizeof(*cis));
2480
2481 memset(cis, 0, sizeof(*cis));
2482
2483 cis->cis_handle = sys_cpu_to_le16(param[i].iso_chan->iso->handle);
2484 cis->acl_handle = sys_cpu_to_le16(param[i].acl->handle);
2485 req->num_cis++;
2486 }
2487
2488 /* If all CIS are pending for security, do nothing,
2489 * but return a recognizable return value
2490 */
2491 if (req->num_cis == 0) {
2492 net_buf_unref(buf);
2493
2494 return -ECANCELED;
2495 }
2496
2497 return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CIS, buf, NULL);
2498 }
2499
2500 #if defined(CONFIG_BT_SMP)
iso_chan_connect_security(const struct bt_iso_connect_param * param,size_t count)2501 static int iso_chan_connect_security(const struct bt_iso_connect_param *param, size_t count)
2502 {
2503 /* conn_idx_handled is an array of booleans for which conn indexes
2504 * already have been used to call bt_conn_set_security.
2505 * Using indexes avoids looping the array when checking if it has been
2506 * handled.
2507 */
2508 bool conn_idx_handled[CONFIG_BT_MAX_CONN];
2509
2510 memset(conn_idx_handled, false, sizeof(conn_idx_handled));
2511 for (size_t i = 0; i < count; i++) {
2512 struct bt_iso_chan *iso_chan = param[i].iso_chan;
2513 struct bt_conn *acl = param[i].acl;
2514 uint8_t conn_idx = bt_conn_index(acl);
2515
2516 if (acl->sec_level < iso_chan->required_sec_level) {
2517 if (!conn_idx_handled[conn_idx]) {
2518 int err;
2519
2520 err = bt_conn_set_security(acl, iso_chan->required_sec_level);
2521 if (err != 0) {
2522 LOG_DBG("[%zu]: Failed to set security: %d", i, err);
2523
2524 /* Restore states */
2525 for (size_t j = 0; j < i; j++) {
2526 iso_chan = param[j].iso_chan;
2527
2528 bt_iso_cleanup_acl(iso_chan->iso);
2529 bt_iso_chan_set_state(iso_chan,
2530 BT_ISO_STATE_DISCONNECTED);
2531 }
2532
2533 return err;
2534 }
2535
2536 conn_idx_handled[conn_idx] = true;
2537 }
2538
2539 iso_chan->iso->iso.acl = bt_conn_ref(acl);
2540 bt_iso_chan_set_state(iso_chan, BT_ISO_STATE_ENCRYPT_PENDING);
2541 }
2542 }
2543
2544 return 0;
2545 }
2546 #endif /* CONFIG_BT_SMP */
2547
iso_chans_connecting(void)2548 static bool iso_chans_connecting(void)
2549 {
2550 for (size_t i = 0U; i < ARRAY_SIZE(iso_conns); i++) {
2551 const struct bt_conn *iso = &iso_conns[i];
2552 const struct bt_iso_chan *iso_chan;
2553
2554 if (iso == NULL || !(iso->iso.info.type == BT_ISO_CHAN_TYPE_CENTRAL ||
2555 iso->iso.info.type == BT_ISO_CHAN_TYPE_PERIPHERAL)) {
2556 continue;
2557 }
2558
2559 iso_chan = iso_chan(iso);
2560 if (iso_chan->state == BT_ISO_STATE_CONNECTING ||
2561 iso_chan->state == BT_ISO_STATE_ENCRYPT_PENDING) {
2562 return true;
2563 }
2564 }
2565
2566 return false;
2567 }
2568
bt_iso_chan_connect(const struct bt_iso_connect_param * param,size_t count)2569 int bt_iso_chan_connect(const struct bt_iso_connect_param *param, size_t count)
2570 {
2571 int err;
2572
2573 CHECKIF(param == NULL) {
2574 LOG_DBG("param is NULL");
2575 return -EINVAL;
2576 }
2577
2578 CHECKIF(count == 0) {
2579 LOG_DBG("Invalid count %zu", count);
2580 return -EINVAL;
2581 }
2582
2583 CHECKIF(count > CONFIG_BT_ISO_MAX_CHAN) {
2584 return -EINVAL;
2585 }
2586
2587 /* Validate input */
2588 for (size_t i = 0; i < count; i++) {
2589 CHECKIF(param[i].iso_chan == NULL) {
2590 LOG_DBG("[%zu]: Invalid iso (%p)", i, param[i].iso_chan);
2591 return -EINVAL;
2592 }
2593
2594 CHECKIF(param[i].acl == NULL) {
2595 LOG_DBG("[%zu]: Invalid acl (%p)", i, param[i].acl);
2596 return -EINVAL;
2597 }
2598
2599 CHECKIF((param[i].acl->type & BT_CONN_TYPE_LE) == 0) {
2600 LOG_DBG("[%zu]: acl type (%u) shall be an LE connection", i,
2601 param[i].acl->type);
2602 return -EINVAL;
2603 }
2604
2605 if (param[i].iso_chan->iso == NULL) {
2606 LOG_DBG("[%zu]: ISO has not been initialized in a CIG", i);
2607 return -EINVAL;
2608 }
2609
2610 if (param[i].iso_chan->state != BT_ISO_STATE_DISCONNECTED) {
2611 LOG_DBG("[%zu]: ISO is not in the BT_ISO_STATE_DISCONNECTED state: %u", i,
2612 param[i].iso_chan->state);
2613 return -EINVAL;
2614 }
2615 }
2616
2617 if (iso_chans_connecting()) {
2618 LOG_DBG("There are pending ISO connections");
2619 return -EBUSY;
2620 }
2621
2622 #if defined(CONFIG_BT_SMP)
2623 /* Check for and initiate security for all channels that have
2624 * requested encryption if the ACL link is not already secured
2625 */
2626 err = iso_chan_connect_security(param, count);
2627 if (err != 0) {
2628 LOG_DBG("Failed to initiate security for all CIS: %d", err);
2629 return err;
2630 }
2631 #endif /* CONFIG_BT_SMP */
2632
2633 err = hci_le_create_cis(param, count);
2634 if (err == -ECANCELED) {
2635 LOG_DBG("All channels are pending on security");
2636
2637 return 0;
2638 } else if (err != 0) {
2639 LOG_DBG("Failed to connect CISes: %d", err);
2640
2641 return err;
2642 }
2643
2644 /* Set connection states */
2645 for (size_t i = 0; i < count; i++) {
2646 struct bt_iso_chan *iso_chan = param[i].iso_chan;
2647 struct bt_iso_cig *cig;
2648
2649 if (iso_chan->state == BT_ISO_STATE_ENCRYPT_PENDING) {
2650 continue;
2651 }
2652
2653 iso_chan->iso->iso.acl = bt_conn_ref(param[i].acl);
2654 bt_conn_set_state(iso_chan->iso, BT_CONN_INITIATING);
2655 bt_iso_chan_set_state(iso_chan, BT_ISO_STATE_CONNECTING);
2656
2657 cig = get_cig(iso_chan);
2658 __ASSERT(cig != NULL, "CIG was NULL");
2659 cig->state = BT_ISO_CIG_STATE_ACTIVE;
2660 }
2661
2662 return 0;
2663 }
2664 #endif /* CONFIG_BT_ISO_CENTRAL */
2665 #endif /* CONFIG_BT_ISO_UNICAST */
2666
2667 #if defined(CONFIG_BT_ISO_BROADCAST)
2668 static sys_slist_t iso_big_cbs = SYS_SLIST_STATIC_INIT(&iso_big_cbs);
2669
lookup_big_by_handle(uint8_t big_handle)2670 static struct bt_iso_big *lookup_big_by_handle(uint8_t big_handle)
2671 {
2672 return &bigs[big_handle];
2673 }
2674
get_free_big(void)2675 static struct bt_iso_big *get_free_big(void)
2676 {
2677 /* We can use the index in the `bigs` array as BIG handles, for both
2678 * broadcaster and receiver (even if the device is both!)
2679 */
2680
2681 for (size_t i = 0; i < ARRAY_SIZE(bigs); i++) {
2682 if (!atomic_test_and_set_bit(bigs[i].flags, BT_BIG_INITIALIZED)) {
2683 bigs[i].handle = i;
2684 sys_slist_init(&bigs[i].bis_channels);
2685 return &bigs[i];
2686 }
2687 }
2688
2689 LOG_DBG("Could not allocate any more BIGs");
2690
2691 return NULL;
2692 }
2693
big_lookup_flag(int bit)2694 static struct bt_iso_big *big_lookup_flag(int bit)
2695 {
2696 for (size_t i = 0; i < ARRAY_SIZE(bigs); i++) {
2697 if (atomic_test_bit(bigs[i].flags, bit)) {
2698 return &bigs[i];
2699 }
2700 }
2701
2702 LOG_DBG("No BIG with flag bit %d set", bit);
2703
2704 return NULL;
2705 }
2706
cleanup_big(struct bt_iso_big * big)2707 static void cleanup_big(struct bt_iso_big *big)
2708 {
2709 struct bt_iso_chan *bis, *tmp;
2710
2711 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&big->bis_channels, bis, tmp, node) {
2712 if (bis->iso != NULL) {
2713 bt_conn_unref(bis->iso);
2714 bis->iso = NULL;
2715 }
2716
2717 sys_slist_remove(&big->bis_channels, NULL, &bis->node);
2718 }
2719
2720 memset(big, 0, sizeof(*big));
2721 }
2722
big_disconnect(struct bt_iso_big * big,uint8_t reason)2723 static void big_disconnect(struct bt_iso_big *big, uint8_t reason)
2724 {
2725 struct bt_iso_chan *bis;
2726
2727 atomic_set_bit(big->flags, BT_BIG_BUSY);
2728
2729 SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) {
2730 bis->iso->err = reason;
2731
2732 bt_iso_chan_disconnected(bis, reason);
2733 }
2734
2735 /* Cleanup the BIG before calling the `stopped` so that the `big` pointer and the ISO
2736 * channels in the `big` can be reused in the callback
2737 */
2738 cleanup_big(big);
2739
2740 if (!sys_slist_is_empty(&iso_big_cbs)) {
2741 struct bt_iso_big_cb *listener;
2742
2743 SYS_SLIST_FOR_EACH_CONTAINER(&iso_big_cbs, listener, _node) {
2744 if (listener->stopped != NULL) {
2745 listener->stopped(big, reason);
2746 }
2747 }
2748 }
2749 }
2750
big_init_bis(struct bt_iso_big * big,struct bt_iso_chan * bis,uint8_t bis_number,bool broadcaster)2751 static int big_init_bis(struct bt_iso_big *big, struct bt_iso_chan *bis, uint8_t bis_number,
2752 bool broadcaster)
2753 {
2754 struct bt_conn_iso *iso_conn;
2755
2756 bis->iso = iso_new();
2757 if (bis->iso == NULL) {
2758 LOG_ERR("Unable to allocate BIS connection");
2759 return -ENOMEM;
2760 }
2761
2762 iso_conn = &bis->iso->iso;
2763
2764 #if defined(CONFIG_BT_ISO_BROADCASTER)
2765 if (broadcaster) {
2766 iso_conn->info.type = BT_ISO_CHAN_TYPE_BROADCASTER;
2767 iso_conn->info.broadcaster.big_handle = big->handle;
2768 iso_conn->info.broadcaster.bis_number = bis_number;
2769 }
2770 #endif /* CONFIG_BT_ISO_BROADCASTER */
2771 #if defined(CONFIG_BT_ISO_SYNC_RECEIVER)
2772 if (!broadcaster) {
2773 iso_conn->info.type = BT_ISO_CHAN_TYPE_SYNC_RECEIVER;
2774 iso_conn->info.sync_receiver.big_handle = big->handle;
2775 iso_conn->info.sync_receiver.bis_number = bis_number;
2776 }
2777 #endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
2778
2779 bt_iso_chan_add(bis->iso, bis);
2780
2781 sys_slist_append(&big->bis_channels, &bis->node);
2782
2783 return 0;
2784 }
2785
bt_iso_big_register_cb(struct bt_iso_big_cb * cb)2786 int bt_iso_big_register_cb(struct bt_iso_big_cb *cb)
2787 {
2788 CHECKIF(cb == NULL) {
2789 LOG_DBG("cb is NULL");
2790
2791 return -EINVAL;
2792 }
2793
2794 if (sys_slist_find(&iso_big_cbs, &cb->_node, NULL)) {
2795 LOG_DBG("cb %p is already registered", cb);
2796
2797 return -EEXIST;
2798 }
2799
2800 sys_slist_append(&iso_big_cbs, &cb->_node);
2801
2802 return 0;
2803 }
2804
2805 #if defined(CONFIG_BT_ISO_BROADCASTER)
hci_le_create_big(struct bt_le_ext_adv * padv,struct bt_iso_big * big,struct bt_iso_big_create_param * param)2806 static int hci_le_create_big(struct bt_le_ext_adv *padv, struct bt_iso_big *big,
2807 struct bt_iso_big_create_param *param)
2808 {
2809 const struct bt_iso_chan_io_qos *qos;
2810 struct bt_hci_cp_le_create_big *req;
2811 struct bt_hci_cmd_state_set state;
2812 struct net_buf *buf;
2813 int err;
2814 struct bt_iso_chan *bis;
2815
2816 buf = bt_hci_cmd_alloc(K_FOREVER);
2817
2818 if (!buf) {
2819 return -ENOBUFS;
2820 }
2821
2822 bis = SYS_SLIST_PEEK_HEAD_CONTAINER(&big->bis_channels, bis, node);
2823 __ASSERT(bis != NULL, "bis was NULL");
2824
2825 /* All BIS will share the same QOS */
2826 qos = bis->qos->tx;
2827
2828 req = net_buf_add(buf, sizeof(*req));
2829 req->big_handle = big->handle;
2830 req->adv_handle = padv->handle;
2831 req->num_bis = big->num_bis;
2832 sys_put_le24(param->interval, req->sdu_interval);
2833 req->max_sdu = sys_cpu_to_le16(qos->sdu);
2834 req->max_latency = sys_cpu_to_le16(param->latency);
2835 req->rtn = qos->rtn;
2836 req->phy = qos->phy;
2837 req->packing = param->packing;
2838 req->framing = param->framing;
2839 req->encryption = param->encryption;
2840 if (req->encryption) {
2841 memcpy(req->bcode, param->bcode, sizeof(req->bcode));
2842 } else {
2843 memset(req->bcode, 0, sizeof(req->bcode));
2844 }
2845
2846 LOG_DBG("BIG handle 0x%02x, adv_handle 0x%02x, num_bis %u, sdu_interval %u, max_sdu %u, "
2847 "max_latency %u, rtn %u, phy %u, packing %u, framing %u, encryption %u",
2848 big->handle, padv->handle, big->num_bis, param->interval, qos->sdu, param->latency,
2849 qos->rtn, qos->phy, param->packing, param->framing, param->encryption);
2850
2851 bt_hci_cmd_state_set_init(buf, &state, big->flags, BT_BIG_PENDING, true);
2852 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_BIG, buf, NULL);
2853
2854 if (err) {
2855 return err;
2856 }
2857
2858 SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) {
2859 bt_iso_chan_set_state(bis, BT_ISO_STATE_CONNECTING);
2860 }
2861
2862 return err;
2863 }
2864
2865 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
hci_le_create_big_test(const struct bt_le_ext_adv * padv,struct bt_iso_big * big,const struct bt_iso_big_create_param * param)2866 static int hci_le_create_big_test(const struct bt_le_ext_adv *padv, struct bt_iso_big *big,
2867 const struct bt_iso_big_create_param *param)
2868 {
2869 struct bt_hci_cp_le_create_big_test *req;
2870 struct bt_hci_cmd_state_set state;
2871 const struct bt_iso_chan_qos *qos;
2872 struct bt_iso_chan *bis;
2873 struct net_buf *buf;
2874 int err;
2875
2876 buf = bt_hci_cmd_alloc(K_FOREVER);
2877
2878 if (!buf) {
2879 return -ENOBUFS;
2880 }
2881
2882 bis = SYS_SLIST_PEEK_HEAD_CONTAINER(&big->bis_channels, bis, node);
2883 __ASSERT(bis != NULL, "bis was NULL");
2884
2885 /* All BIS will share the same QOS */
2886 qos = bis->qos;
2887
2888 req = net_buf_add(buf, sizeof(*req));
2889 req->big_handle = big->handle;
2890 req->adv_handle = padv->handle;
2891 req->num_bis = big->num_bis;
2892 sys_put_le24(param->interval, req->sdu_interval);
2893 req->iso_interval = sys_cpu_to_le16(param->iso_interval);
2894 req->nse = qos->num_subevents;
2895 req->max_sdu = sys_cpu_to_le16(qos->tx->sdu);
2896 req->max_pdu = sys_cpu_to_le16(qos->tx->max_pdu);
2897 req->phy = qos->tx->phy;
2898 req->packing = param->packing;
2899 req->framing = param->framing;
2900 req->bn = qos->tx->burst_number;
2901 req->irc = param->irc;
2902 req->pto = param->pto;
2903 req->encryption = param->encryption;
2904 if (req->encryption) {
2905 memcpy(req->bcode, param->bcode, sizeof(req->bcode));
2906 } else {
2907 memset(req->bcode, 0, sizeof(req->bcode));
2908 }
2909
2910 LOG_DBG("BIG handle %u, adv handle %u, num_bis %u, SDU interval %u, "
2911 "ISO interval %u, NSE %u, SDU %u, PDU %u, PHY %u, packing %u, "
2912 "framing %u, BN %u, IRC %u, PTO %u, encryption %u",
2913 req->big_handle, req->adv_handle, req->num_bis, param->interval,
2914 param->iso_interval, req->nse, req->max_sdu, req->max_pdu, req->phy, req->packing,
2915 req->framing, req->bn, req->irc, req->pto, req->encryption);
2916
2917 bt_hci_cmd_state_set_init(buf, &state, big->flags, BT_BIG_PENDING, true);
2918 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_BIG_TEST, buf, NULL);
2919 if (err) {
2920 return err;
2921 }
2922
2923 SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) {
2924 bt_iso_chan_set_state(bis, BT_ISO_STATE_CONNECTING);
2925 }
2926
2927 return err;
2928 }
2929
is_advanced_big_param(const struct bt_iso_big_create_param * param)2930 static bool is_advanced_big_param(const struct bt_iso_big_create_param *param)
2931 {
2932 if (param->irc != 0U || param->iso_interval != 0U) {
2933 return true;
2934 }
2935
2936 /* Check if any of the CIS contain any test-param-only values */
2937 for (uint8_t i = 0U; i < param->num_bis; i++) {
2938 const struct bt_iso_chan *bis = param->bis_channels[i];
2939 const struct bt_iso_chan_qos *qos = bis->qos;
2940
2941 if (qos->num_subevents > 0U) {
2942 return true;
2943 }
2944
2945 __ASSERT(qos->tx != NULL, "TX cannot be NULL for broadcaster");
2946
2947 if (qos->tx->max_pdu > 0U || qos->tx->burst_number > 0U) {
2948 return true;
2949 }
2950 }
2951
2952 return false;
2953 }
2954 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
2955
valid_big_param(const struct bt_iso_big_create_param * param,bool advanced)2956 static bool valid_big_param(const struct bt_iso_big_create_param *param, bool advanced)
2957 {
2958 CHECKIF(!param->bis_channels) {
2959 LOG_DBG("NULL BIS channels");
2960
2961 return false;
2962 }
2963
2964 CHECKIF(!param->num_bis) {
2965 LOG_DBG("Invalid number of BIS %u", param->num_bis);
2966
2967 return false;
2968 }
2969
2970 for (uint8_t i = 0; i < param->num_bis; i++) {
2971 struct bt_iso_chan *bis = param->bis_channels[i];
2972
2973 CHECKIF(bis == NULL) {
2974 LOG_DBG("bis_channels[%u]: NULL channel", i);
2975
2976 return false;
2977 }
2978
2979 if (bis->iso) {
2980 LOG_DBG("bis_channels[%u]: already allocated", i);
2981
2982 return false;
2983 }
2984
2985 CHECKIF(bis->qos == NULL) {
2986 LOG_DBG("bis_channels[%u]: qos is NULL", i);
2987
2988 return false;
2989 }
2990
2991 CHECKIF(bis->qos->tx == NULL ||
2992 !valid_chan_io_qos(bis->qos->tx, true, true, advanced)) {
2993 LOG_DBG("bis_channels[%u]: Invalid QOS", i);
2994
2995 return false;
2996 }
2997 }
2998
2999 CHECKIF(param->framing != BT_ISO_FRAMING_UNFRAMED &&
3000 param->framing != BT_ISO_FRAMING_FRAMED) {
3001 LOG_DBG("Invalid framing parameter: %u", param->framing);
3002
3003 return false;
3004 }
3005
3006 CHECKIF(param->packing != BT_ISO_PACKING_SEQUENTIAL &&
3007 param->packing != BT_ISO_PACKING_INTERLEAVED) {
3008 LOG_DBG("Invalid packing parameter: %u", param->packing);
3009
3010 return false;
3011 }
3012
3013 CHECKIF(param->num_bis > BT_ISO_MAX_GROUP_ISO_COUNT ||
3014 param->num_bis > CONFIG_BT_ISO_MAX_CHAN) {
3015 LOG_DBG("num_bis (%u) shall be lower than: %u", param->num_bis,
3016 MAX(CONFIG_BT_ISO_MAX_CHAN, BT_ISO_MAX_GROUP_ISO_COUNT));
3017
3018 return false;
3019 }
3020
3021 CHECKIF(!IN_RANGE(param->interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) {
3022 LOG_DBG("Invalid interval: %u", param->interval);
3023
3024 return false;
3025 }
3026
3027 CHECKIF(!advanced && !IN_RANGE(param->latency, BT_ISO_LATENCY_MIN, BT_ISO_LATENCY_MAX)) {
3028 LOG_DBG("Invalid latency: %u", param->latency);
3029
3030 return false;
3031 }
3032
3033 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
3034 if (advanced) {
3035 CHECKIF(!IN_RANGE(param->irc, BT_ISO_IRC_MIN, BT_ISO_IRC_MAX)) {
3036 LOG_DBG("Invalid IRC %u", param->irc);
3037
3038 return false;
3039 }
3040
3041 CHECKIF(!IN_RANGE(param->pto, BT_ISO_PTO_MIN, BT_ISO_PTO_MAX)) {
3042 LOG_DBG("Invalid PTO %u", param->pto);
3043
3044 return false;
3045 }
3046
3047 CHECKIF(!IN_RANGE(param->iso_interval, BT_ISO_ISO_INTERVAL_MIN,
3048 BT_ISO_ISO_INTERVAL_MAX)) {
3049 LOG_DBG("Invalid ISO interval %u", param->iso_interval);
3050
3051 return false;
3052 }
3053 }
3054 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
3055
3056 return true;
3057 }
3058
bt_iso_big_create(struct bt_le_ext_adv * padv,struct bt_iso_big_create_param * param,struct bt_iso_big ** out_big)3059 int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param *param,
3060 struct bt_iso_big **out_big)
3061 {
3062 struct bt_iso_chan **bis_channels;
3063 int err;
3064 struct bt_iso_big *big;
3065 bool advanced = false;
3066
3067 CHECKIF(padv == NULL) {
3068 LOG_DBG("padv is NULL");
3069 return -EINVAL;
3070 }
3071
3072 CHECKIF(param == NULL) {
3073 LOG_DBG("param is NULL");
3074 return -EINVAL;
3075 }
3076
3077 CHECKIF(out_big == NULL) {
3078 LOG_DBG("out_big is NULL");
3079 return -EINVAL;
3080 }
3081
3082 if (!atomic_test_bit(padv->flags, BT_PER_ADV_PARAMS_SET)) {
3083 LOG_DBG("PA params not set; invalid adv object");
3084 return -EINVAL;
3085 }
3086
3087 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
3088 advanced = is_advanced_big_param(param);
3089 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
3090
3091 if (!valid_big_param(param, advanced)) {
3092 LOG_DBG("Invalid BIG parameters");
3093
3094 return -EINVAL;
3095 }
3096
3097 big = get_free_big();
3098
3099 if (!big) {
3100 return -ENOMEM;
3101 }
3102
3103 bis_channels = param->bis_channels;
3104 for (uint8_t i = 0; i < param->num_bis; i++) {
3105 /* BIS numbers start from 1, so the first BIS will get BIS Number = 1 */
3106 const uint8_t bis_number = i + 1U;
3107
3108 err = big_init_bis(big, bis_channels[i], bis_number, true);
3109 if (err != 0) {
3110 LOG_DBG("Could not init BIS[%u]: %d", i, err);
3111 cleanup_big(big);
3112
3113 return err;
3114 }
3115 }
3116
3117 big->num_bis = param->num_bis;
3118
3119 if (!advanced) {
3120 err = hci_le_create_big(padv, big, param);
3121 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
3122 } else {
3123 err = hci_le_create_big_test(padv, big, param);
3124 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
3125 }
3126
3127 if (err) {
3128 LOG_DBG("Could not create BIG %d", err);
3129 cleanup_big(big);
3130 return err;
3131 }
3132
3133 *out_big = big;
3134
3135 return err;
3136 }
3137
store_bis_broadcaster_info(const struct bt_hci_evt_le_big_complete * evt,struct bt_conn * iso)3138 static void store_bis_broadcaster_info(const struct bt_hci_evt_le_big_complete *evt,
3139 struct bt_conn *iso)
3140 {
3141 struct bt_conn_iso *iso_conn = &iso->iso;
3142 struct bt_iso_info *info = &iso_conn->info;
3143 struct bt_iso_broadcaster_info *broadcaster_info = &info->broadcaster;
3144
3145 info->iso_interval = sys_le16_to_cpu(evt->iso_interval);
3146 info->max_subevent = evt->nse;
3147
3148 broadcaster_info->sync_delay = sys_get_le24(evt->sync_delay);
3149 broadcaster_info->latency = sys_get_le24(evt->latency);
3150 broadcaster_info->phy = bt_get_phy(evt->phy);
3151 broadcaster_info->bn = evt->bn;
3152 broadcaster_info->irc = evt->irc;
3153 /* Transform to n * 1.25ms */
3154 broadcaster_info->pto = info->iso_interval * evt->pto;
3155 broadcaster_info->max_pdu = sys_le16_to_cpu(evt->max_pdu);
3156 broadcaster_info->big_handle = iso_conn->info.broadcaster.big_handle;
3157 broadcaster_info->bis_number = iso_conn->info.broadcaster.bis_number;
3158
3159 info->can_send = true;
3160 info->can_recv = false;
3161 }
3162
hci_le_big_complete(struct net_buf * buf)3163 void hci_le_big_complete(struct net_buf *buf)
3164 {
3165 struct bt_hci_evt_le_big_complete *evt = (void *)buf->data;
3166 struct bt_iso_chan *bis;
3167 struct bt_iso_big *big;
3168 int i;
3169
3170 if (evt->big_handle >= ARRAY_SIZE(bigs)) {
3171 LOG_WRN("Invalid BIG handle");
3172
3173 big = big_lookup_flag(BT_BIG_PENDING);
3174 if (big) {
3175 big_disconnect(big, evt->status ? evt->status : BT_HCI_ERR_UNSPECIFIED);
3176 }
3177
3178 return;
3179 }
3180
3181 big = lookup_big_by_handle(evt->big_handle);
3182 atomic_clear_bit(big->flags, BT_BIG_PENDING);
3183
3184 LOG_DBG("BIG[%u] %p completed, status 0x%02x %s", big->handle, big, evt->status,
3185 bt_hci_err_to_str(evt->status));
3186
3187 if (evt->status || evt->num_bis != big->num_bis) {
3188 if (evt->status == BT_HCI_ERR_SUCCESS && evt->num_bis != big->num_bis) {
3189 LOG_ERR("Invalid number of BIS created, was %u expected %u", evt->num_bis,
3190 big->num_bis);
3191 }
3192 big_disconnect(big, evt->status ? evt->status : BT_HCI_ERR_UNSPECIFIED);
3193 return;
3194 }
3195
3196 atomic_set_bit(big->flags, BT_BIG_BUSY);
3197 i = 0;
3198 SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) {
3199 const uint16_t handle = evt->handle[i++];
3200 struct bt_conn *iso_conn = bis->iso;
3201
3202 iso_conn->handle = sys_le16_to_cpu(handle);
3203 store_bis_broadcaster_info(evt, iso_conn);
3204 bt_conn_set_state(iso_conn, BT_CONN_CONNECTED);
3205 }
3206
3207 atomic_clear_bit(big->flags, BT_BIG_BUSY);
3208
3209 if (!sys_slist_is_empty(&iso_big_cbs)) {
3210 struct bt_iso_big_cb *listener;
3211
3212 SYS_SLIST_FOR_EACH_CONTAINER(&iso_big_cbs, listener, _node) {
3213 if (listener->started != NULL) {
3214 listener->started(big);
3215 }
3216 }
3217 }
3218 }
3219
hci_le_big_terminate(struct net_buf * buf)3220 void hci_le_big_terminate(struct net_buf *buf)
3221 {
3222 struct bt_hci_evt_le_big_terminate *evt = (void *)buf->data;
3223 struct bt_iso_big *big;
3224
3225 if (evt->big_handle >= ARRAY_SIZE(bigs)) {
3226 LOG_WRN("Invalid BIG handle");
3227 return;
3228 }
3229
3230 big = lookup_big_by_handle(evt->big_handle);
3231
3232 LOG_DBG("BIG[%u] %p terminated", big->handle, big);
3233
3234 big_disconnect(big, evt->reason);
3235 }
3236 #endif /* CONFIG_BT_ISO_BROADCASTER */
3237
hci_le_terminate_big(struct bt_iso_big * big)3238 static int hci_le_terminate_big(struct bt_iso_big *big)
3239 {
3240 struct bt_hci_cp_le_terminate_big *req;
3241 struct net_buf *buf;
3242
3243 buf = bt_hci_cmd_alloc(K_FOREVER);
3244 if (!buf) {
3245 return -ENOBUFS;
3246 }
3247
3248 req = net_buf_add(buf, sizeof(*req));
3249 req->big_handle = big->handle;
3250 req->reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN;
3251
3252 return bt_hci_cmd_send_sync(BT_HCI_OP_LE_TERMINATE_BIG, buf, NULL);
3253 }
3254
hci_le_big_sync_term(struct bt_iso_big * big)3255 static int hci_le_big_sync_term(struct bt_iso_big *big)
3256 {
3257 struct bt_hci_cp_le_big_terminate_sync *req;
3258 struct bt_hci_rp_le_big_terminate_sync *evt;
3259 struct net_buf *buf;
3260 struct net_buf *rsp;
3261 int err;
3262
3263 buf = bt_hci_cmd_alloc(K_FOREVER);
3264 if (!buf) {
3265 return -ENOBUFS;
3266 }
3267
3268 req = net_buf_add(buf, sizeof(*req));
3269 req->big_handle = big->handle;
3270 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_BIG_TERMINATE_SYNC, buf, &rsp);
3271 if (err) {
3272 return err;
3273 }
3274
3275 evt = (struct bt_hci_rp_le_big_terminate_sync *)rsp->data;
3276 if (evt->status || (evt->big_handle != big->handle)) {
3277 err = -EIO;
3278 }
3279
3280 net_buf_unref(rsp);
3281
3282 return err;
3283 }
3284
bt_iso_big_terminate(struct bt_iso_big * big)3285 int bt_iso_big_terminate(struct bt_iso_big *big)
3286 {
3287 struct bt_iso_chan *bis;
3288 int err;
3289
3290 CHECKIF(big == NULL) {
3291 LOG_DBG("big is NULL");
3292 return -EINVAL;
3293 }
3294
3295 if (!atomic_test_bit(big->flags, BT_BIG_INITIALIZED) || !big->num_bis) {
3296 LOG_DBG("BIG not initialized");
3297 return -EINVAL;
3298 }
3299
3300 if (atomic_test_bit(big->flags, BT_BIG_BUSY)) {
3301 LOG_DBG("BIG %p is busy", big);
3302 return -EBUSY;
3303 }
3304
3305 bis = SYS_SLIST_PEEK_HEAD_CONTAINER(&big->bis_channels, bis, node);
3306 __ASSERT(bis != NULL, "bis was NULL");
3307
3308 if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) &&
3309 bis->iso->iso.info.type == BT_ISO_CHAN_TYPE_BROADCASTER) {
3310 err = hci_le_terminate_big(big);
3311
3312 /* Wait for BT_HCI_EVT_LE_BIG_TERMINATE before cleaning up
3313 * the BIG in hci_le_big_terminate
3314 */
3315 if (!err) {
3316 SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) {
3317 bt_iso_chan_set_state(bis, BT_ISO_STATE_DISCONNECTING);
3318 }
3319 }
3320 } else if (IS_ENABLED(CONFIG_BT_ISO_SYNC_RECEIVER) &&
3321 bis->iso->iso.info.type == BT_ISO_CHAN_TYPE_SYNC_RECEIVER) {
3322 err = hci_le_big_sync_term(big);
3323
3324 if (!err) {
3325 big_disconnect(big, BT_HCI_ERR_LOCALHOST_TERM_CONN);
3326 }
3327 } else {
3328 err = -EINVAL;
3329 }
3330
3331 if (err) {
3332 LOG_DBG("Could not terminate BIG %d", err);
3333 }
3334
3335 return err;
3336 }
3337
3338 #if defined(CONFIG_BT_ISO_SYNC_RECEIVER)
store_bis_sync_receiver_info(const struct bt_hci_evt_le_big_sync_established * evt,struct bt_conn * iso)3339 static void store_bis_sync_receiver_info(const struct bt_hci_evt_le_big_sync_established *evt,
3340 struct bt_conn *iso)
3341 {
3342 struct bt_conn_iso *iso_conn = &iso->iso;
3343 struct bt_iso_info *info = &iso_conn->info;
3344 struct bt_iso_sync_receiver_info *receiver_info = &info->sync_receiver;
3345
3346 info->max_subevent = evt->nse;
3347 info->iso_interval = sys_le16_to_cpu(evt->iso_interval);
3348
3349 receiver_info->latency = sys_get_le24(evt->latency);
3350 receiver_info->bn = evt->bn;
3351 receiver_info->irc = evt->irc;
3352 /* Transform to n * 1.25ms */
3353 receiver_info->pto = info->iso_interval * evt->pto;
3354 receiver_info->max_pdu = sys_le16_to_cpu(evt->max_pdu);
3355 receiver_info->big_handle = iso_conn->info.sync_receiver.big_handle;
3356 receiver_info->bis_number = iso_conn->info.sync_receiver.bis_number;
3357
3358 info->can_send = false;
3359 info->can_recv = true;
3360 }
3361
hci_le_big_sync_established(struct net_buf * buf)3362 void hci_le_big_sync_established(struct net_buf *buf)
3363 {
3364 struct bt_hci_evt_le_big_sync_established *evt = (void *)buf->data;
3365 struct bt_iso_chan *bis;
3366 struct bt_iso_big *big;
3367 int i;
3368
3369 if (evt->big_handle >= ARRAY_SIZE(bigs)) {
3370 LOG_WRN("Invalid BIG handle");
3371 big = big_lookup_flag(BT_BIG_SYNCING);
3372 if (big) {
3373 big_disconnect(big, evt->status ? evt->status : BT_HCI_ERR_UNSPECIFIED);
3374 }
3375
3376 return;
3377 }
3378
3379 big = lookup_big_by_handle(evt->big_handle);
3380 atomic_clear_bit(big->flags, BT_BIG_SYNCING);
3381
3382 LOG_DBG("BIG[%u] %p sync established, status 0x%02x %s", big->handle, big, evt->status,
3383 bt_hci_err_to_str(evt->status));
3384
3385 if (evt->status || evt->num_bis != big->num_bis) {
3386 if (evt->status == BT_HCI_ERR_SUCCESS && evt->num_bis != big->num_bis) {
3387 LOG_ERR("Invalid number of BIS synced, was %u expected %u", evt->num_bis,
3388 big->num_bis);
3389 }
3390 big_disconnect(big, evt->status ? evt->status : BT_HCI_ERR_UNSPECIFIED);
3391 return;
3392 }
3393
3394 atomic_set_bit(big->flags, BT_BIG_BUSY);
3395 i = 0;
3396 SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) {
3397 const uint16_t handle = evt->handle[i++];
3398 struct bt_conn *iso_conn = bis->iso;
3399
3400 iso_conn->handle = sys_le16_to_cpu(handle);
3401 store_bis_sync_receiver_info(evt, iso_conn);
3402 bt_conn_set_state(iso_conn, BT_CONN_CONNECTED);
3403 }
3404
3405 atomic_clear_bit(big->flags, BT_BIG_BUSY);
3406
3407 if (!sys_slist_is_empty(&iso_big_cbs)) {
3408 struct bt_iso_big_cb *listener;
3409
3410 SYS_SLIST_FOR_EACH_CONTAINER(&iso_big_cbs, listener, _node) {
3411 if (listener->started != NULL) {
3412 listener->started(big);
3413 }
3414 }
3415 }
3416 }
3417
hci_le_big_sync_lost(struct net_buf * buf)3418 void hci_le_big_sync_lost(struct net_buf *buf)
3419 {
3420 struct bt_hci_evt_le_big_sync_lost *evt = (void *)buf->data;
3421 struct bt_iso_big *big;
3422
3423 if (evt->big_handle >= ARRAY_SIZE(bigs)) {
3424 LOG_WRN("Invalid BIG handle");
3425 return;
3426 }
3427
3428 big = lookup_big_by_handle(evt->big_handle);
3429
3430 LOG_DBG("BIG[%u] %p sync lost", big->handle, big);
3431
3432 big_disconnect(big, evt->reason);
3433 }
3434
hci_le_big_create_sync(const struct bt_le_per_adv_sync * sync,struct bt_iso_big * big,const struct bt_iso_big_sync_param * param)3435 static int hci_le_big_create_sync(const struct bt_le_per_adv_sync *sync, struct bt_iso_big *big,
3436 const struct bt_iso_big_sync_param *param)
3437 {
3438 struct bt_hci_cp_le_big_create_sync *req;
3439 struct bt_hci_cmd_state_set state;
3440 struct net_buf *buf;
3441 int err;
3442 uint8_t bit_idx = 0;
3443
3444 buf = bt_hci_cmd_alloc(K_FOREVER);
3445 if (!buf) {
3446 return -ENOBUFS;
3447 }
3448
3449 req = net_buf_add(buf, sizeof(*req) + big->num_bis);
3450 req->big_handle = big->handle;
3451 req->sync_handle = sys_cpu_to_le16(sync->handle);
3452 req->encryption = param->encryption;
3453 if (req->encryption) {
3454 memcpy(req->bcode, param->bcode, sizeof(req->bcode));
3455 } else {
3456 memset(req->bcode, 0, sizeof(req->bcode));
3457 }
3458 req->mse = param->mse;
3459 req->sync_timeout = sys_cpu_to_le16(param->sync_timeout);
3460 req->num_bis = big->num_bis;
3461 /* Transform from bitfield to array */
3462 for (int i = 1; i <= BT_ISO_MAX_GROUP_ISO_COUNT; i++) {
3463 if (param->bis_bitfield & BT_ISO_BIS_INDEX_BIT(i)) {
3464 if (bit_idx == big->num_bis) {
3465 LOG_DBG("BIG cannot contain %u BISes", bit_idx + 1);
3466 return -EINVAL;
3467 }
3468 req->bis[bit_idx++] = i;
3469 }
3470 }
3471
3472 if (bit_idx != big->num_bis) {
3473 LOG_DBG("Number of bits in bis_bitfield (%u) doesn't match num_bis (%u)", bit_idx,
3474 big->num_bis);
3475 return -EINVAL;
3476 }
3477
3478 bt_hci_cmd_state_set_init(buf, &state, big->flags, BT_BIG_SYNCING, true);
3479 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_BIG_CREATE_SYNC, buf, NULL);
3480
3481 return err;
3482 }
3483
bt_iso_big_sync(struct bt_le_per_adv_sync * sync,struct bt_iso_big_sync_param * param,struct bt_iso_big ** out_big)3484 int bt_iso_big_sync(struct bt_le_per_adv_sync *sync, struct bt_iso_big_sync_param *param,
3485 struct bt_iso_big **out_big)
3486 {
3487 struct bt_iso_chan **bis_channels;
3488 int err;
3489 struct bt_iso_chan *bis;
3490 struct bt_iso_big *big;
3491 uint32_t bitfield_copy;
3492
3493 CHECKIF(sync == NULL) {
3494 LOG_DBG("sync is NULL");
3495 return -EINVAL;
3496 }
3497
3498 CHECKIF(param == NULL) {
3499 LOG_DBG("param is NULL");
3500 return -EINVAL;
3501 }
3502
3503 CHECKIF(out_big == NULL) {
3504 LOG_DBG("out_big is NULL");
3505 return -EINVAL;
3506 }
3507
3508 if (!atomic_test_bit(sync->flags, BT_PER_ADV_SYNC_SYNCED)) {
3509 LOG_DBG("PA sync not synced");
3510 return -EINVAL;
3511 }
3512
3513 CHECKIF(param->mse > BT_ISO_SYNC_MSE_MAX) {
3514 LOG_DBG("Invalid MSE 0x%02x", param->mse);
3515 return -EINVAL;
3516 }
3517
3518 CHECKIF(param->sync_timeout < BT_ISO_SYNC_TIMEOUT_MIN ||
3519 param->sync_timeout > BT_ISO_SYNC_TIMEOUT_MAX) {
3520 LOG_DBG("Invalid sync timeout 0x%04x", param->sync_timeout);
3521 return -EINVAL;
3522 }
3523
3524 CHECKIF(!BT_ISO_VALID_BIS_BITFIELD(param->bis_bitfield)) {
3525 LOG_DBG("Invalid BIS bitfield 0x%08x", param->bis_bitfield);
3526 return -EINVAL;
3527 }
3528
3529 CHECKIF(!param->bis_channels) {
3530 LOG_DBG("NULL BIS channels");
3531 return -EINVAL;
3532 }
3533
3534 CHECKIF(!param->num_bis) {
3535 LOG_DBG("Invalid number of BIS %u", param->num_bis);
3536 return -EINVAL;
3537 }
3538
3539 for (uint8_t i = 0; i < param->num_bis; i++) {
3540 struct bt_iso_chan *param_bis = param->bis_channels[i];
3541
3542 CHECKIF(param_bis == NULL) {
3543 LOG_DBG("bis_channels[%u]: NULL channel", i);
3544 return -EINVAL;
3545 }
3546
3547 if (param_bis->iso) {
3548 LOG_DBG("bis_channels[%u]: already allocated", i);
3549 return -EALREADY;
3550 }
3551
3552 CHECKIF(param_bis->qos == NULL) {
3553 LOG_DBG("bis_channels[%u]: qos is NULL", i);
3554 return -EINVAL;
3555 }
3556
3557 CHECKIF(param_bis->qos->rx == NULL) {
3558 LOG_DBG("bis_channels[%u]: qos->rx is NULL", i);
3559 return -EINVAL;
3560 }
3561 }
3562
3563 big = get_free_big();
3564
3565 if (!big) {
3566 return -ENOMEM;
3567 }
3568
3569 bitfield_copy = param->bis_bitfield;
3570 bis_channels = param->bis_channels;
3571 for (uint8_t i = 0; i < param->num_bis; i++) {
3572 const uint8_t bis_number = find_lsb_set(bitfield_copy);
3573
3574 /* pop the least significant bit from the bitfield */
3575 bitfield_copy &= ~BIT(bis_number - 1U);
3576
3577 /* The least significant bit will be the bis_number, so that if the bitfield is
3578 * 0b0101 then the first pop will be 1 and the bitfield_copy will be 0b0100 and
3579 * then the second pop will be 3 and the bitfield_copy will be 0b0000
3580 * Since find_lsb_set returns the index starting from 1 we can use the result
3581 * directly as the bis_numbers also start from 1.
3582 */
3583 err = big_init_bis(big, bis_channels[i], bis_number, false);
3584 if (err != 0) {
3585 LOG_DBG("Could not init BIS[%u]: %d", i, err);
3586 cleanup_big(big);
3587
3588 return err;
3589 }
3590 }
3591
3592 big->num_bis = param->num_bis;
3593
3594 err = hci_le_big_create_sync(sync, big, param);
3595 if (err) {
3596 LOG_DBG("Could not create BIG sync %d", err);
3597 cleanup_big(big);
3598 return err;
3599 }
3600
3601 SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) {
3602 bt_iso_chan_set_state(bis, BT_ISO_STATE_CONNECTING);
3603 }
3604
3605 *out_big = big;
3606
3607 return 0;
3608 }
3609 #endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
3610 #endif /* CONFIG_BT_ISO_BROADCAST */
3611
bt_iso_reset(void)3612 void bt_iso_reset(void)
3613 {
3614 #if defined(CONFIG_BT_ISO_CENTRAL)
3615 for (size_t i = 0U; i < ARRAY_SIZE(cigs); i++) {
3616 struct bt_iso_cig *cig = &cigs[i];
3617 struct bt_iso_chan *cis;
3618
3619 /* Disconnect any connected CIS and call the callback
3620 * We cannot use bt_iso_chan_disconnected directly here, as that
3621 * attempts to also remove the ISO data path, which we shouldn't attempt to
3622 * during the reset, as that sends HCI commands.
3623 */
3624 SYS_SLIST_FOR_EACH_CONTAINER(&cig->cis_channels, cis, node) {
3625 if (cis->state != BT_ISO_STATE_DISCONNECTED) {
3626 bt_iso_chan_set_state(cis, BT_ISO_STATE_DISCONNECTED);
3627 bt_iso_cleanup_acl(cis->iso);
3628 if (cis->ops != NULL && cis->ops->disconnected != NULL) {
3629 cis->ops->disconnected(cis, BT_HCI_ERR_UNSPECIFIED);
3630 }
3631 }
3632 }
3633
3634 cleanup_cig(cig);
3635 }
3636 #endif /* CONFIG_BT_ISO_CENTRAL */
3637
3638 #if defined(CONFIG_BT_ISO_BROADCAST)
3639 for (size_t i = 0U; i < ARRAY_SIZE(bigs); i++) {
3640 struct bt_iso_big *big = &bigs[i];
3641
3642 big_disconnect(big, BT_HCI_ERR_UNSPECIFIED);
3643 }
3644 #endif /* CONFIG_BT_ISO_BROADCAST */
3645 }
3646