Skip to content

Commit 770a9c4

Browse files
committed
Bluetooth: ISO: Make setting ISO data explicit
The stack will no longer implicitly set the data path for ISO channel, and the responsibility for doing that is now for the upper layers/applications. This provides additional flexibility for the higher layers as they can better control the values and timing of the data path, as well as support removing and even reconfiguring the data path at will. This also removes some complexity from the stack. This commit also fixed a inconsistency in the disconnected handler. CIS for centrals as well as BIS were still valid bt_iso_chan channels in the disconnected callback, but CIS for peripherals were completely cleaned up at this point. This issue is fixed by moving the disconnected callback handling to before the code to cleanup the channel for peripherals. Since there is a difference in how you remove data paths depending on the GAP role (central/peripheral), the iso_info struct type has been expanded to be more concise of which type of CIS it is. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 10e12ba commit 770a9c4

File tree

29 files changed

+775
-303
lines changed

29 files changed

+775
-303
lines changed

doc/releases/migration-guide-4.1.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,10 @@ Bluetooth Host
588588
* The prompt for :kconfig:option:`CONFIG_BT_ECC` has been removed, since it only offers an internal
589589
API, meaning internal users should explicitly select it in their respective Kconfig options.
590590

591+
* The ISO data paths are not longer setup automatically, and shall explicitly be setup and removd
592+
by the application by calling :c:func:`bt_iso_setup_data_path` and
593+
:c:func:`bt_iso_remove_data_path` respectively. (:github:`75549`)
594+
591595
Bluetooth Crypto
592596
================
593597

include/zephyr/bluetooth/iso.h

Lines changed: 123 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ extern "C" {
7070

7171
/** Unknown SDU interval */
7272
#define BT_ISO_SDU_INTERVAL_UNKNOWN 0x000000U
73+
/** The minimum value for vendor specific data path ID */
74+
#define BT_ISO_DATA_PATH_VS_ID_MIN 0x01
75+
/** The maximum value for vendor specific data path ID */
76+
#define BT_ISO_DATA_PATH_VS_ID_MAX 0xFE
77+
/** Minimum controller delay in microseconds (0 s) */
78+
#define BT_ISO_CONTROLLER_DELAY_MIN 0x000000
79+
/** Maximum controller delay in microseconds (4 s) */
80+
#define BT_ISO_CONTROLLER_DELAY_MAX 0x3D0900
7381
/** Minimum interval value in microseconds */
7482
#define BT_ISO_SDU_INTERVAL_MIN 0x0000FFU
7583
/** Maximum interval value in microseconds */
@@ -178,7 +186,8 @@ enum bt_iso_state {
178186
*/
179187
enum bt_iso_chan_type {
180188
BT_ISO_CHAN_TYPE_NONE, /**< No channel type */
181-
BT_ISO_CHAN_TYPE_CONNECTED, /**< Connected */
189+
BT_ISO_CHAN_TYPE_CENTRAL, /**< Connected as central */
190+
BT_ISO_CHAN_TYPE_PERIPHERAL, /**< Connected as peripheral */
182191
BT_ISO_CHAN_TYPE_BROADCASTER, /**< Isochronous broadcaster */
183192
BT_ISO_CHAN_TYPE_SYNC_RECEIVER /**< Synchronized receiver */
184193
};
@@ -230,13 +239,6 @@ struct bt_iso_chan_io_qos {
230239
* This value is ignored if any advanced ISO parameters are set.
231240
*/
232241
uint8_t rtn;
233-
/**
234-
* @brief Channel data path reference
235-
*
236-
* Setting to NULL default to HCI data path (same as setting path.pid
237-
* to @ref BT_ISO_DATA_PATH_HCI).
238-
*/
239-
struct bt_iso_chan_path *path;
240242

241243
#if defined(CONFIG_BT_ISO_TEST_PARAMS) || defined(__DOXYGEN__)
242244
/**
@@ -293,20 +295,37 @@ struct bt_iso_chan_qos {
293295

294296
/** @brief ISO Channel Data Path structure. */
295297
struct bt_iso_chan_path {
296-
/** Default path ID */
297-
uint8_t pid;
298-
/** Coding Format */
299-
uint8_t format;
298+
/**
299+
* @brief Default path ID
300+
*
301+
* @ref BT_ISO_DATA_PATH_HCI to use ISO over HCI or between @ref BT_ISO_DATA_PATH_VS_ID_MIN
302+
* and @ref BT_ISO_DATA_PATH_VS_ID_MAX for vendor specific data paths.
303+
*/
304+
uint8_t pid;
305+
/**
306+
* @brief Coding Format
307+
*
308+
* See the BT_HCI_CODING_FORMAT_* values for valid values.
309+
*/
310+
uint8_t format;
300311
/** Company ID */
301-
uint16_t cid;
312+
uint16_t cid;
302313
/** Vendor-defined Codec ID */
303-
uint16_t vid;
304-
/** Controller Delay */
305-
uint32_t delay;
306-
/** Codec Configuration length*/
307-
uint8_t cc_len;
308-
/** Pointer to an array containing the Codec Configuration */
309-
uint8_t *cc;
314+
uint16_t vid;
315+
/**
316+
* @brief Controller Delay in microseconds
317+
*
318+
* Value range from @ref BT_ISO_CONTROLLER_DELAY_MIN to @ref BT_ISO_CONTROLLER_DELAY_MAX.
319+
*/
320+
uint32_t delay;
321+
/** Codec Configuration length */
322+
uint8_t cc_len;
323+
/**
324+
* @brief Pointer to an array containing the Codec Configuration
325+
*
326+
* Shall not be NULL if bt_iso_chan_path.cc_len is non-zero.
327+
*/
328+
uint8_t *cc;
310329
};
311330

312331
/** ISO packet status flag bits */
@@ -691,6 +710,14 @@ struct bt_iso_chan_ops {
691710
* channel is disconnected, including when a connection gets
692711
* rejected or when setting security fails.
693712
*
713+
* If the channel was established then it still contain references to the BIS/CIS handles
714+
* and is not completely free'd at this point. The memory of the channel shall not be
715+
* memset to 0 or free'd.
716+
* To avoid any issue it is recommended to use a @ref k_work_submit or similar to not
717+
* overwrite any data while in the callback.
718+
*
719+
* For the above reason it is still possible to use bt_iso_chan_get_info() on the @p chan.
720+
*
694721
* @param chan The channel that has been Disconnected
695722
* @param reason BT_HCI_ERR_* reason for the disconnection.
696723
*/
@@ -957,6 +984,69 @@ int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq
957984
int bt_iso_chan_send_ts(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq_num,
958985
uint32_t ts);
959986

987+
/**
988+
* @brief Sets up the ISO data path for a ISO channel
989+
*
990+
* The channel must be associated with a BIS or CIS handle first which it is when the
991+
* bt_iso_chan_ops.connected() callback is called.
992+
*
993+
* @param chan The channel to setup the ISO data path for
994+
* @param dir The direction to setup, either @ref BT_HCI_DATAPATH_DIR_CTLR_TO_HOST or
995+
* @ref BT_HCI_DATAPATH_DIR_HOST_TO_CTLR. For ISO broadcast channels this can only be
996+
* @ref BT_HCI_DATAPATH_DIR_HOST_TO_CTLR, and for ISO sync receiver channels this can
997+
* only be @ref BT_HCI_DATAPATH_DIR_CTLR_TO_HOST.
998+
* @param path The data path
999+
*
1000+
* @retval 0 Success
1001+
* @retval -EINVAL Invalid parameters
1002+
* @retval -ENOBUFS No HCI command buffer could be allocated
1003+
* @retval -EIO The controller rejected the request or response contains invalid data
1004+
* @retval -ENODEV @p chan is not associated with a CIS or BIS handle
1005+
* @retval -EACCES The controller rejected the request as disallowed
1006+
* @retval -ENOEXEC Unexpected error occurred
1007+
*/
1008+
int bt_iso_setup_data_path(const struct bt_iso_chan *chan, uint8_t dir,
1009+
const struct bt_iso_chan_path *path);
1010+
1011+
/**
1012+
* @brief Removes the ISO data path for a ISO channel
1013+
*
1014+
* Removes the ISO data path configured by bt_iso_setup_data_path() for the provided @p dir.
1015+
*
1016+
* As per Bluetooth Core specification 5.4, Vol 4, Part E, Section 7.7.5, the data paths of CIS for
1017+
* Peripherals are deleted by the controller, and thus it is not necessary (or possible) to remove
1018+
* data paths of CIS after they have disconnected for a Peripheral.
1019+
* The data paths for CIS for a Central remain valid, even after a disconnection, and thus a Central
1020+
* device should call bt_iso_remove_data_path() on disconnect if it no longer wants to use that CIS.
1021+
* All data paths created by a Central are removed when the CIG is removed with
1022+
* bt_iso_cig_terminate().
1023+
*
1024+
* As per Bluetooth Core specification 5.4, Vol 4, Part E, Section 7.7.65.30 any data paths
1025+
* associated with an ISO Sync Receiver BIG are removed by the controller when the BIG sync is lost
1026+
* or terminated, and thus it is not necessary (or possible) to remove data paths of ISO channels
1027+
* associated with a BIG for a Sync Receiver.
1028+
*
1029+
* As per Bluetooth Core specification 5.4, Vol 4, Part E, Section 7.8.105 all data paths associated
1030+
* with an ISO Broadcaster BIG are removed when the BIG is terminated by bt_iso_big_terminate(),
1031+
* and thus it is not necessary (or possible) to remove data paths of ISO channels
1032+
* associated with a BIG for a Broadcaster.
1033+
*
1034+
* @param chan The channel to setup the ISO data path for
1035+
* @param dir The direction to setup, either @ref BT_HCI_DATAPATH_DIR_CTLR_TO_HOST or
1036+
* @ref BT_HCI_DATAPATH_DIR_HOST_TO_CTLR. For ISO broadcast channels this can only be
1037+
* @ref BT_HCI_DATAPATH_DIR_HOST_TO_CTLR, and for ISO sync receiver channels this can
1038+
* only be @ref BT_HCI_DATAPATH_DIR_CTLR_TO_HOST.
1039+
1040+
* @retval 0 Success
1041+
* @retval -EINVAL Invalid parameters
1042+
* @retval -ENOBUFS No HCI command buffer could be allocated
1043+
* @retval -EIO The controller rejected the request or response contains invalid data
1044+
* @retval -ENODEV @p chan is not associated with a CIS or BIS handle
1045+
* @retval -EACCES The controller rejected the request as disallowed
1046+
* @retval -ENOEXEC Unexpected error occurred
1047+
*/
1048+
int bt_iso_remove_data_path(const struct bt_iso_chan *chan, uint8_t dir);
1049+
9601050
/** @brief ISO Unicast TX Info Structure */
9611051
struct bt_iso_unicast_tx_info {
9621052
/** The transport latency in us */
@@ -1082,20 +1172,30 @@ struct bt_iso_info {
10821172
/** Connection Type specific Info.*/
10831173
union {
10841174
#if defined(CONFIG_BT_ISO_UNICAST) || defined(__DOXYGEN__)
1085-
/** Unicast specific Info.
1175+
/**
1176+
* @brief Unicast specific Info.
1177+
*
10861178
* Only available when @kconfig{CONFIG_BT_ISO_UNICAST} is enabled.
1179+
* Use this when the @ref bt_iso_info.type is @ref BT_ISO_CHAN_TYPE_CENTRAL or
1180+
* @ref BT_ISO_CHAN_TYPE_PERIPHERAL.
10871181
*/
10881182
struct bt_iso_unicast_info unicast;
10891183
#endif /* CONFIG_BT_ISO_UNICAST */
10901184
#if defined(CONFIG_BT_ISO_BROADCASTER) || defined(__DOXYGEN__)
1091-
/** Broadcaster specific Info.
1185+
/**
1186+
* @brief Broadcaster specific Info.
1187+
*
10921188
* Only available when @kconfig{CONFIG_BT_ISO_BROADCASTER} is enabled.
1189+
* Use this when the @ref bt_iso_info.type is @ref BT_ISO_CHAN_TYPE_BROADCASTER.
10931190
*/
10941191
struct bt_iso_broadcaster_info broadcaster;
10951192
#endif /* CONFIG_BT_ISO_BROADCASTER */
10961193
#if defined(CONFIG_BT_ISO_SYNC_RECEIVER) || defined(__DOXYGEN__)
1097-
/** Sync receiver specific Info.
1194+
/**
1195+
* @brief Sync receiver specific Info.
1196+
*
10981197
* Only available when @kconfig{CONFIG_BT_ISO_SYNC_RECEIVER} is enabled.
1198+
* Use this when the @ref bt_iso_info.type is @ref BT_ISO_CHAN_TYPE_SYNC_RECEIVER.
10991199
*/
11001200
struct bt_iso_sync_receiver_info sync_receiver;
11011201
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */

samples/bluetooth/iso_broadcast/src/main.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <zephyr/bluetooth/bluetooth.h>
1010
#include <zephyr/bluetooth/gap.h>
11+
#include <zephyr/bluetooth/hci_types.h>
1112
#include <zephyr/bluetooth/iso.h>
1213
#include <zephyr/sys/byteorder.h>
1314

@@ -31,10 +32,21 @@ static uint16_t seq_num;
3132

3233
static void iso_connected(struct bt_iso_chan *chan)
3334
{
35+
const struct bt_iso_chan_path hci_path = {
36+
.pid = BT_ISO_DATA_PATH_HCI,
37+
.format = BT_HCI_CODING_FORMAT_TRANSPARENT,
38+
};
39+
int err;
40+
3441
printk("ISO Channel %p connected\n", chan);
3542

3643
seq_num = 0U;
3744

45+
err = bt_iso_setup_data_path(chan, BT_HCI_DATAPATH_DIR_HOST_TO_CTLR, &hci_path);
46+
if (err != 0) {
47+
printk("Failed to setup ISO TX data path: %d\n", err);
48+
}
49+
3850
k_sem_give(&sem_big_cmplt);
3951
}
4052

samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <stdint.h>
1010

1111
#include <zephyr/bluetooth/gap.h>
12+
#include <zephyr/bluetooth/hci_types.h>
1213
#include <zephyr/console/console.h>
1314
#include <zephyr/bluetooth/bluetooth.h>
1415
#include <zephyr/bluetooth/iso.h>
@@ -72,8 +73,19 @@ static const struct bt_data ad[] = {
7273

7374
static void iso_connected(struct bt_iso_chan *chan)
7475
{
76+
const struct bt_iso_chan_path hci_path = {
77+
.pid = BT_ISO_DATA_PATH_HCI,
78+
.format = BT_HCI_CODING_FORMAT_TRANSPARENT,
79+
};
80+
int err;
81+
7582
LOG_INF("ISO Channel %p connected", chan);
7683

84+
err = bt_iso_setup_data_path(chan, BT_HCI_DATAPATH_DIR_HOST_TO_CTLR, &hci_path);
85+
if (err != 0) {
86+
printk("Failed to setup ISO TX data path: %d\n", err);
87+
}
88+
7789
connected_bis++;
7890
if (connected_bis == big_create_param.num_bis) {
7991
seq_num = 0U;

samples/bluetooth/iso_broadcast_benchmark/src/receiver.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/*
2-
* Copyright (c) 2021 Nordic Semiconductor ASA
2+
* Copyright (c) 2021-2024 Nordic Semiconductor ASA
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

77
#include <ctype.h>
88
#include <zephyr/bluetooth/bluetooth.h>
99
#include <zephyr/bluetooth/conn.h>
10+
#include <zephyr/bluetooth/hci_types.h>
1011
#include <zephyr/bluetooth/iso.h>
1112
#include <zephyr/sys/byteorder.h>
1213
#include <zephyr/console/console.h>
@@ -229,10 +230,21 @@ static void iso_recv(struct bt_iso_chan *chan,
229230

230231
static void iso_connected(struct bt_iso_chan *chan)
231232
{
233+
const struct bt_iso_chan_path hci_path = {
234+
.pid = BT_ISO_DATA_PATH_HCI,
235+
.format = BT_HCI_CODING_FORMAT_TRANSPARENT,
236+
};
237+
int err;
238+
232239
LOG_INF("ISO Channel %p connected", chan);
233240

234241
big_sync_start_time = k_uptime_get();
235242

243+
err = bt_iso_setup_data_path(chan, BT_HCI_DATAPATH_DIR_CTLR_TO_HOST, &hci_path);
244+
if (err != 0) {
245+
printk("Failed to setup ISO RX data path: %d\n", err);
246+
}
247+
236248
k_sem_give(&sem_big_sync);
237249
}
238250

samples/bluetooth/iso_central/src/main.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <zephyr/bluetooth/conn.h>
1717
#include <zephyr/bluetooth/uuid.h>
1818
#include <zephyr/bluetooth/gatt.h>
19+
#include <zephyr/bluetooth/hci_types.h>
1920
#include <zephyr/bluetooth/iso.h>
2021
#include <zephyr/settings/settings.h>
2122
#include <zephyr/sys/byteorder.h>
@@ -142,18 +143,36 @@ static void start_scan(void)
142143

143144
static void iso_connected(struct bt_iso_chan *chan)
144145
{
146+
const struct bt_iso_chan_path hci_path = {
147+
.pid = BT_ISO_DATA_PATH_HCI,
148+
.format = BT_HCI_CODING_FORMAT_TRANSPARENT,
149+
};
150+
int err;
151+
145152
printk("ISO Channel %p connected\n", chan);
146153

147154
seq_num = 0U;
148155

149-
/* Start send timer */
150-
k_work_schedule(&iso_send_work, K_MSEC(0));
156+
err = bt_iso_setup_data_path(chan, BT_HCI_DATAPATH_DIR_HOST_TO_CTLR, &hci_path);
157+
if (err != 0) {
158+
printk("Failed to setup ISO TX data path: %d\n", err);
159+
} else {
160+
/* Start send timer */
161+
k_work_schedule(&iso_send_work, K_NO_WAIT);
162+
}
151163
}
152164

153165
static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
154166
{
167+
int err;
168+
155169
printk("ISO Channel %p disconnected (reason 0x%02x)\n", chan, reason);
156170
k_work_cancel_delayable(&iso_send_work);
171+
172+
err = bt_iso_remove_data_path(chan, BT_HCI_DATAPATH_DIR_HOST_TO_CTLR);
173+
if (err != 0) {
174+
printk("Failed to setup ISO TX data path: %d\n", err);
175+
}
157176
}
158177

159178
static struct bt_iso_chan_ops iso_ops = {
@@ -165,7 +184,6 @@ static struct bt_iso_chan_io_qos iso_tx = {
165184
.sdu = CONFIG_BT_ISO_TX_MTU,
166185
.phy = BT_GAP_LE_PHY_2M,
167186
.rtn = 1,
168-
.path = NULL,
169187
};
170188

171189
static struct bt_iso_chan_qos iso_qos = {

0 commit comments

Comments
 (0)