Lines Matching full:iso

1 /*  Bluetooth ISO */
17 #include <zephyr/bluetooth/iso.h>
35 #define iso_chan(_iso) ((_iso)->iso.chan);
64 static void bt_iso_remove_data_path(struct bt_conn *iso);
83 static void bt_iso_send_cb(struct bt_conn *iso, void *user_data, int err) in bt_iso_send_cb() argument
85 struct bt_iso_chan *chan = iso->iso.chan; in bt_iso_send_cb()
88 __ASSERT(chan != NULL, "NULL chan for iso %p", iso); in bt_iso_send_cb()
103 struct bt_conn *iso; in hci_iso() local
109 LOG_ERR("Invalid HCI ISO packet size (%u)", buf->len); in hci_iso()
119 iso(buf)->handle = bt_iso_handle(handle); in hci_iso()
120 iso(buf)->index = BT_CONN_INDEX_INVALID; in hci_iso()
123 iso(buf)->handle, len, flags); in hci_iso()
126 LOG_ERR("ISO data length mismatch (%u != %u)", buf->len, len); in hci_iso()
131 iso = bt_conn_lookup_handle(iso(buf)->handle, BT_CONN_TYPE_ISO); in hci_iso()
132 if (iso == NULL) { in hci_iso()
133 LOG_ERR("Unable to find conn for handle %u", iso(buf)->handle); in hci_iso()
138 iso(buf)->index = bt_conn_index(iso); in hci_iso()
140 bt_conn_recv(iso, buf, flags); in hci_iso()
141 bt_conn_unref(iso); in hci_iso()
146 struct bt_conn *iso = bt_conn_new(iso_conns, ARRAY_SIZE(iso_conns)); in iso_new() local
148 if (iso) { in iso_new()
149 iso->type = BT_CONN_TYPE_ISO; in iso_new()
151 LOG_DBG("Could not create new ISO"); in iso_new()
154 return iso; in iso_new()
203 static int hci_le_setup_iso_data_path(const struct bt_conn *iso, uint8_t dir, in hci_le_setup_iso_data_path() argument
214 "invalid ISO data path dir: %u", dir); in hci_le_setup_iso_data_path()
217 LOG_DBG("Invalid ISO data path CC: %p %u", path->cc, path->cc_len); in hci_le_setup_iso_data_path()
228 cp->handle = sys_cpu_to_le16(iso->handle); in hci_le_setup_iso_data_path()
245 if (rp->status || (sys_le16_to_cpu(rp->handle) != iso->handle)) { in hci_le_setup_iso_data_path()
254 static void bt_iso_chan_add(struct bt_conn *iso, struct bt_iso_chan *chan) in bt_iso_chan_add() argument
256 /* Attach ISO channel to the connection */ in bt_iso_chan_add()
257 chan->iso = iso; in bt_iso_chan_add()
258 iso->iso.chan = chan; in bt_iso_chan_add()
260 LOG_DBG("iso %p chan %p", iso, chan); in bt_iso_chan_add()
273 struct bt_conn *iso; in bt_iso_setup_data_path() local
276 iso = chan->iso; in bt_iso_setup_data_path()
281 /* The following code sets the in and out paths for ISO data. in bt_iso_setup_data_path()
290 if (tx_qos != NULL && iso->iso.info.can_send) { in bt_iso_setup_data_path()
298 if (rx_qos != NULL && iso->iso.info.can_recv) { in bt_iso_setup_data_path()
311 iso->iso.info.type == BT_ISO_CHAN_TYPE_BROADCASTER && in_path) { in bt_iso_setup_data_path()
313 err = hci_le_setup_iso_data_path(iso, dir, in_path); in bt_iso_setup_data_path()
320 iso->iso.info.type == BT_ISO_CHAN_TYPE_SYNC_RECEIVER && in bt_iso_setup_data_path()
323 err = hci_le_setup_iso_data_path(iso, dir, out_path); in bt_iso_setup_data_path()
330 iso->iso.info.type == BT_ISO_CHAN_TYPE_CONNECTED) { in bt_iso_setup_data_path()
334 err = hci_le_setup_iso_data_path(iso, dir, in_path); in bt_iso_setup_data_path()
344 err = hci_le_setup_iso_data_path(iso, dir, out_path); in bt_iso_setup_data_path()
353 __ASSERT(false, "Invalid iso.info.type: %u", in bt_iso_setup_data_path()
354 iso->iso.info.type); in bt_iso_setup_data_path()
359 void bt_iso_connected(struct bt_conn *iso) in bt_iso_connected() argument
364 if (iso == NULL || iso->type != BT_CONN_TYPE_ISO) { in bt_iso_connected()
365 LOG_DBG("Invalid parameters: iso %p iso->type %u", iso, iso ? iso->type : 0); in bt_iso_connected()
369 LOG_DBG("%p", iso); in bt_iso_connected()
371 chan = iso_chan(iso); in bt_iso_connected()
373 LOG_ERR("Could not lookup chan from connected ISO"); in bt_iso_connected()
382 } else if (iso->iso.info.type == BT_ISO_CHAN_TYPE_BROADCASTER || in bt_iso_connected()
383 iso->iso.info.type == BT_ISO_CHAN_TYPE_SYNC_RECEIVER) { in bt_iso_connected()
386 big = lookup_big_by_handle(iso->iso.big_handle); in bt_iso_connected()
395 iso->iso.info.type == BT_ISO_CHAN_TYPE_CONNECTED) { in bt_iso_connected()
396 bt_conn_disconnect(iso, in bt_iso_connected()
399 __ASSERT(false, "Invalid iso.info.type: %u", in bt_iso_connected()
400 iso->iso.info.type); in bt_iso_connected()
416 __ASSERT(chan->iso != NULL, "NULL conn for iso chan %p", chan); in bt_iso_chan_disconnected()
424 chan->iso->iso.info.type == BT_ISO_CHAN_TYPE_CONNECTED) { in bt_iso_chan_disconnected()
425 bt_iso_cleanup_acl(chan->iso); in bt_iso_chan_disconnected()
427 if (chan->iso->role == BT_HCI_ROLE_PERIPHERAL) { in bt_iso_chan_disconnected()
428 bt_conn_unref(chan->iso); in bt_iso_chan_disconnected()
429 chan->iso = NULL; in bt_iso_chan_disconnected()
432 /* ISO data paths are automatically removed when the in bt_iso_chan_disconnected()
436 bt_iso_remove_data_path(chan->iso); in bt_iso_chan_disconnected()
466 void bt_iso_disconnected(struct bt_conn *iso) in bt_iso_disconnected() argument
470 if (iso == NULL || iso->type != BT_CONN_TYPE_ISO) { in bt_iso_disconnected()
471 LOG_DBG("Invalid parameters: iso %p iso->type %u", iso, iso ? iso->type : 0); in bt_iso_disconnected()
475 LOG_DBG("%p", iso); in bt_iso_disconnected()
477 chan = iso_chan(iso); in bt_iso_disconnected()
479 LOG_ERR("Could not lookup chan from disconnected ISO"); in bt_iso_disconnected()
483 bt_iso_chan_disconnected(chan, iso->err); in bt_iso_disconnected()
509 LOG_DBG("chan %p iso %p %s -> %s", chan, chan->iso, bt_iso_chan_state_str(chan->state), in bt_iso_chan_set_state_debug()
557 CHECKIF(chan->iso == NULL) { in bt_iso_chan_get_info()
558 LOG_DBG("chan->iso is NULL"); in bt_iso_chan_get_info()
567 (void)memcpy(info, &chan->iso->iso.info, sizeof(*info)); in bt_iso_chan_get_info()
585 void bt_iso_recv(struct bt_conn *iso, struct net_buf *buf, uint8_t flags) in bt_iso_recv() argument
596 iso->handle, buf->len, flags, pb, ts); in bt_iso_recv()
600 * and ISO_SDU_Length are omitted from the HCI ISO Data packet. in bt_iso_recv()
636 LOG_WRN("Invalid ISO packet status flag: %u", flags); in bt_iso_recv()
644 if (iso->rx) { in bt_iso_recv()
645 LOG_ERR("Unexpected ISO %s fragment", in bt_iso_recv()
647 bt_conn_reset_rx_state(iso); in bt_iso_recv()
650 iso->rx = buf; in bt_iso_recv()
651 iso->rx_len = len - buf->len; in bt_iso_recv()
652 if (iso->rx_len) { in bt_iso_recv()
653 /* if iso->rx_len then package is longer than the in bt_iso_recv()
657 LOG_ERR("Unexpected ISO single fragment"); in bt_iso_recv()
658 bt_conn_reset_rx_state(iso); in bt_iso_recv()
668 if (!iso->rx) { in bt_iso_recv()
669 LOG_ERR("Unexpected ISO continuation fragment"); in bt_iso_recv()
675 buf->len, iso->rx_len); in bt_iso_recv()
677 if (buf->len > net_buf_tailroom(iso->rx)) { in bt_iso_recv()
678 LOG_ERR("Not enough buffer space for ISO data"); in bt_iso_recv()
679 bt_conn_reset_rx_state(iso); in bt_iso_recv()
684 net_buf_add_mem(iso->rx, buf->data, buf->len); in bt_iso_recv()
685 iso->rx_len -= buf->len; in bt_iso_recv()
693 BT_ISO_DATA_DBG("End, len %u rx_len %u", buf->len, iso->rx_len); in bt_iso_recv()
695 if (iso->rx == NULL) { in bt_iso_recv()
696 LOG_ERR("Unexpected ISO end fragment"); in bt_iso_recv()
701 if (buf->len > net_buf_tailroom(iso->rx)) { in bt_iso_recv()
702 LOG_ERR("Not enough buffer space for ISO data"); in bt_iso_recv()
703 bt_conn_reset_rx_state(iso); in bt_iso_recv()
708 (void)net_buf_add_mem(iso->rx, buf->data, buf->len); in bt_iso_recv()
709 iso->rx_len -= buf->len; in bt_iso_recv()
714 LOG_ERR("Unexpected ISO pb flags (0x%02x)", pb); in bt_iso_recv()
715 bt_conn_reset_rx_state(iso); in bt_iso_recv()
720 chan = iso_chan(iso); in bt_iso_recv()
722 LOG_ERR("Could not lookup chan from receiving ISO"); in bt_iso_recv()
724 chan->ops->recv(chan, iso_info(iso->rx), iso->rx); in bt_iso_recv()
727 bt_conn_reset_rx_state(iso); in bt_iso_recv()
771 iso_conn = chan->iso; in bt_iso_chan_send()
772 if (!iso_conn->iso.info.can_send) { in bt_iso_chan_send()
779 LOG_DBG("Cannot send ISO packet with buffer size %u", buf->size); in bt_iso_chan_send()
783 LOG_DBG("Cannot send ISO packet with timestamp with buffer size %u", buf->size); in bt_iso_chan_send()
895 CHECKIF(chan->iso == NULL) { in bt_iso_chan_get_tx_sync()
896 LOG_DBG("chan->iso is NULL"); in bt_iso_chan_get_tx_sync()
915 cp->handle = sys_cpu_to_le16(chan->iso->handle); in bt_iso_chan_get_tx_sync()
948 CHECKIF(chan->iso == NULL) { in bt_iso_chan_disconnect()
953 if (chan->iso->iso.acl == NULL || in bt_iso_chan_disconnect()
977 if (IS_ENABLED(CONFIG_BT_ISO_PERIPHERAL) && chan->iso->role == BT_HCI_ROLE_PERIPHERAL && in bt_iso_chan_disconnect()
985 err = bt_conn_disconnect(chan->iso, BT_HCI_ERR_REMOTE_USER_TERM_CONN); in bt_iso_chan_disconnect()
993 void bt_iso_cleanup_acl(struct bt_conn *iso) in bt_iso_cleanup_acl() argument
995 LOG_DBG("%p", iso); in bt_iso_cleanup_acl()
997 if (iso->iso.acl) { in bt_iso_cleanup_acl()
998 bt_conn_unref(iso->iso.acl); in bt_iso_cleanup_acl()
999 iso->iso.acl = NULL; in bt_iso_cleanup_acl()
1035 struct bt_conn *iso; in hci_le_cis_established() local
1039 /* ISO connection handles are already assigned at this point */ in hci_le_cis_established()
1040 iso = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ISO); in hci_le_cis_established()
1041 if (!iso) { in hci_le_cis_established()
1059 iso_conn = &iso->iso; in hci_le_cis_established()
1062 __ASSERT(chan != NULL && chan->qos != NULL, "Invalid ISO chan"); in hci_le_cis_established()
1069 if (iso->role == BT_HCI_ROLE_PERIPHERAL) { in hci_le_cis_established()
1095 if (iso->role == BT_HCI_ROLE_PERIPHERAL && in hci_le_cis_established()
1098 } else if (iso->role == BT_HCI_ROLE_CENTRAL && in hci_le_cis_established()
1107 if (iso->role == BT_HCI_ROLE_PERIPHERAL && in hci_le_cis_established()
1110 } else if (iso->role == BT_HCI_ROLE_CENTRAL && in hci_le_cis_established()
1117 bt_conn_set_state(iso, BT_CONN_CONNECTED); in hci_le_cis_established()
1118 bt_conn_unref(iso); in hci_le_cis_established()
1121 iso->err = evt->status; in hci_le_cis_established()
1122 bt_iso_disconnected(iso); in hci_le_cis_established()
1125 bt_conn_unref(iso); in hci_le_cis_established()
1136 /* Check if controller is ISO capable */ in bt_iso_server_register()
1181 static int iso_accept(struct bt_conn *acl, struct bt_conn *iso) in iso_accept() argument
1187 CHECKIF(!iso || iso->type != BT_CONN_TYPE_ISO) { in iso_accept()
1188 LOG_DBG("Invalid parameters: iso %p iso->type %u", iso, iso ? iso->type : 0); in iso_accept()
1192 LOG_DBG("%p", iso); in iso_accept()
1195 accept_info.cig_id = iso->iso.cig_id; in iso_accept()
1196 accept_info.cis_id = iso->iso.cis_id; in iso_accept()
1208 bt_iso_chan_add(iso, chan); in iso_accept()
1281 struct bt_conn *acl, *iso; in hci_le_cis_req() local
1289 LOG_DBG("No ISO server registered"); in hci_le_cis_req()
1295 iso = bt_conn_lookup_handle(cis_handle, BT_CONN_TYPE_ISO); in hci_le_cis_req()
1296 if (iso) { in hci_le_cis_req()
1297 LOG_ERR("Invalid ISO handle %u", cis_handle); in hci_le_cis_req()
1299 bt_conn_unref(iso); in hci_le_cis_req()
1323 /* Add ISO connection */ in hci_le_cis_req()
1324 iso = bt_conn_add_iso(acl); in hci_le_cis_req()
1328 if (!iso) { in hci_le_cis_req()
1329 LOG_ERR("Could not create and add ISO to ACL %u", acl_handle); in hci_le_cis_req()
1335 iso->iso.info.type = BT_ISO_CHAN_TYPE_CONNECTED; in hci_le_cis_req()
1336 iso->iso.cig_id = evt->cig_id; in hci_le_cis_req()
1337 iso->iso.cis_id = evt->cis_id; in hci_le_cis_req()
1340 err = iso_accept(acl, iso); in hci_le_cis_req()
1342 LOG_DBG("App rejected ISO %d", err); in hci_le_cis_req()
1343 bt_iso_cleanup_acl(iso); in hci_le_cis_req()
1344 bt_conn_unref(iso); in hci_le_cis_req()
1350 iso->handle = cis_handle; in hci_le_cis_req()
1351 iso->role = BT_HCI_ROLE_PERIPHERAL; in hci_le_cis_req()
1352 bt_conn_set_state(iso, BT_CONN_CONNECTING); in hci_le_cis_req()
1356 bt_iso_cleanup_acl(iso); in hci_le_cis_req()
1357 bt_conn_unref(iso); in hci_le_cis_req()
1366 struct bt_conn *iso = iso_new(); in bt_conn_add_iso() local
1368 if (iso == NULL) { in bt_conn_add_iso()
1369 LOG_ERR("Unable to allocate ISO connection"); in bt_conn_add_iso()
1373 iso->iso.acl = bt_conn_ref(acl); in bt_conn_add_iso()
1375 return iso; in bt_conn_add_iso()
1380 static int hci_le_remove_iso_data_path(struct bt_conn *iso, uint8_t dir) in hci_le_remove_iso_data_path() argument
1393 cp->handle = sys_cpu_to_le16(iso->handle); in hci_le_remove_iso_data_path()
1402 if (rp->status || (sys_le16_to_cpu(rp->handle) != iso->handle)) { in hci_le_remove_iso_data_path()
1411 static void bt_iso_remove_data_path(struct bt_conn *iso) in bt_iso_remove_data_path() argument
1413 enum bt_iso_chan_type type = iso->iso.info.type; in bt_iso_remove_data_path()
1415 LOG_DBG("%p", iso); in bt_iso_remove_data_path()
1417 /* TODO: Removing the ISO data path is never used for broadcast: in bt_iso_remove_data_path()
1428 chan = iso_chan(iso); in bt_iso_remove_data_path()
1442 (void)hci_le_remove_iso_data_path(iso, dir); in bt_iso_remove_data_path()
1450 (void)hci_le_remove_iso_data_path(iso, BIT(BT_HCI_DATAPATH_DIR_HOST_TO_CTLR)); in bt_iso_remove_data_path()
1451 (void)hci_le_remove_iso_data_path(iso, BIT(BT_HCI_DATAPATH_DIR_CTLR_TO_HOST)); in bt_iso_remove_data_path()
1453 __ASSERT(false, "Invalid iso.type: %u", type); in bt_iso_remove_data_path()
1550 cis_param->cis_id = cis->iso->iso.cis_id; in hci_le_set_cig_params()
1640 cis_param->cis_id = cis->iso->iso.cis_id; in hci_le_set_cig_test_params()
1727 if (iso_chan == NULL || iso_chan->iso == NULL) { in get_cig()
1731 __ASSERT(iso_chan->iso->iso.cig_id < ARRAY_SIZE(cigs), in get_cig()
1732 "Invalid cig_id %u", iso_chan->iso->iso.cig_id); in get_cig()
1734 return &cigs[iso_chan->iso->iso.cig_id]; in get_cig()
1758 if (cig == NULL || cis == NULL || cis->iso == NULL) { in cis_is_in_cig()
1762 return cig->id == cis->iso->iso.cig_id; in cis_is_in_cig()
1771 if (cis->iso == NULL) { in cig_init_cis()
1774 cis->iso = iso_new(); in cig_init_cis()
1775 if (cis->iso == NULL) { in cig_init_cis()
1779 iso_conn = &cis->iso->iso; in cig_init_cis()
1785 bt_iso_chan_add(cis->iso, cis); in cig_init_cis()
1799 if (cis->iso != NULL) { in cleanup_cig()
1800 bt_conn_unref(cis->iso); in cleanup_cig()
1801 cis->iso = NULL; in cleanup_cig()
1825 if (cis->iso != NULL && !cis_is_in_cig(cig, cis)) { in valid_cig_param()
1837 LOG_DBG("ISO %p duplicated at index %u and %u", cis, i, j); in valid_cig_param()
1894 LOG_DBG("Invalid ISO interval %u", param->iso_interval); in valid_cig_param()
1922 /* Check if controller is ISO capable as a central */ in bt_iso_cig_create()
1991 cis->iso->handle = sys_le16_to_cpu(handle); in bt_iso_cig_create()
2010 if (cis->iso != NULL && in restore_cig()
2011 cis->iso->iso.cis_id >= existing_num_cis) { in restore_cig()
2012 bt_conn_unref(cis->iso); in restore_cig()
2013 cis->iso = NULL; in restore_cig()
2100 cis->iso->handle = sys_le16_to_cpu(handle); in bt_iso_cig_reconfigure()
2140 /* The peripheral does not accept any ISO requests if security is in bt_iso_security_changed()
2151 struct bt_conn *iso = &iso_conns[i]; in bt_iso_security_changed() local
2154 if (iso == NULL || iso->iso.acl != acl) { in bt_iso_security_changed()
2158 iso_chan = iso_chan(iso); in bt_iso_security_changed()
2170 LOG_DBG("Failed to encrypt ACL %p for ISO %p: %u", acl, iso, hci_status); in bt_iso_security_changed()
2183 /* Nothing to do for ISO. This happens if security is changed, in bt_iso_security_changed()
2184 * but no ISO channels were pending encryption. in bt_iso_security_changed()
2216 bt_conn_set_state(iso_chan->iso, BT_CONN_CONNECTING); in bt_iso_security_changed()
2250 cis->cis_handle = sys_cpu_to_le16(param[i].iso_chan->iso->handle); in hci_le_create_cis()
2297 bt_iso_cleanup_acl(iso_chan->iso); in iso_chan_connect_security()
2308 iso_chan->iso->iso.acl = bt_conn_ref(acl); in iso_chan_connect_security()
2320 const struct bt_conn *iso = &iso_conns[i]; in iso_chans_connecting() local
2323 if (iso == NULL || in iso_chans_connecting()
2324 iso->iso.info.type != BT_ISO_CHAN_TYPE_CONNECTED) { in iso_chans_connecting()
2328 iso_chan = iso_chan(iso); in iso_chans_connecting()
2359 LOG_DBG("[%zu]: Invalid iso (%p)", i, param[i].iso_chan); in bt_iso_chan_connect()
2374 if (param[i].iso_chan->iso == NULL) { in bt_iso_chan_connect()
2375 LOG_DBG("[%zu]: ISO has not been initialized in a CIG", i); in bt_iso_chan_connect()
2380 LOG_DBG("[%zu]: ISO is not in the BT_ISO_STATE_DISCONNECTED state: %u", i, in bt_iso_chan_connect()
2387 LOG_DBG("There are pending ISO connections"); in bt_iso_chan_connect()
2422 iso_chan->iso->iso.acl = bt_conn_ref(param[i].acl); in bt_iso_chan_connect()
2423 bt_conn_set_state(iso_chan->iso, BT_CONN_CONNECTING); in bt_iso_chan_connect()
2479 if (bis->iso != NULL) { in cleanup_big()
2480 bt_conn_unref(bis->iso); in cleanup_big()
2481 bis->iso = NULL; in cleanup_big()
2495 bis->iso->err = reason; in big_disconnect()
2497 bt_iso_disconnected(bis->iso); in big_disconnect()
2510 bis->iso = iso_new(); in big_init_bis()
2512 if (!bis->iso) { in big_init_bis()
2516 iso_conn = &bis->iso->iso; in big_init_bis()
2521 iso_conn->bis_id = bt_conn_index(bis->iso); in big_init_bis()
2523 bt_iso_chan_add(bis->iso, bis); in big_init_bis()
2633 "ISO interval %u, NSE %u, SDU %u, PDU %u, PHY %u, packing %u, " in hci_le_create_big_test()
2704 if (bis->iso) { in valid_big_param()
2781 LOG_DBG("Invalid ISO interval %u", param->iso_interval); in valid_big_param()
2904 struct bt_conn *iso_conn = bis->iso; in hci_le_big_complete()
2907 store_bis_broadcaster_info(evt, &iso_conn->iso.info); in hci_le_big_complete()
2992 bis->iso->iso.info.type == BT_ISO_CHAN_TYPE_BROADCASTER) { in bt_iso_big_terminate()
3004 bis->iso->iso.info.type == BT_ISO_CHAN_TYPE_SYNC_RECEIVER) { in bt_iso_big_terminate()
3078 struct bt_conn *iso_conn = bis->iso; in hci_le_big_sync_established()
3081 store_bis_sync_receiver_info(evt, &iso_conn->iso.info); in hci_le_big_sync_established()
3199 if (param_bis->iso) { in bt_iso_big_sync()