Skip to content

Bluetooth: ISO Broadcast shell updates #88151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions doc/connectivity/bluetooth/shell/host/iso.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Commands
term-big :Terminate a BIG


Unicast examples
****************
1. [Central] Create CIG:

Requires to be connected:
Expand Down Expand Up @@ -62,3 +64,65 @@ Requires to be connected:
uart:~$ iso disconnect
ISO Disconnect pending...
ISO Channel 0x20000f88 disconnected with reason 0x16


Broadcast examples
******************

Setting up broadcaster
======================

.. code-block:: console

uart:~$ bt init
Bluetooth initialized
uart:~$ bt adv-create nconn-nscan ext-adv
Created adv id: 0, adv: 0x200025d0
uart:~$ bt per-adv-param
uart:~$ iso create-big
BIG created
ISO Channel 0x200008c0 connected
uart:~$
uart:~$ bt adv-start
Advertiser[0] 0x200025d0 set started
uart:~$
uart:~$ bt per-adv on
Periodic advertising started
uart:~$
uart:~$ iso broadcast
send: 247 bytes of data with PSN 4350
ISO broadcasting...

If encrypted broadcast is required, then a broadcast code can be provided as

.. code-block:: console

uart:~$ iso create-big enc 00112233445566778899aabbccddffff
BIG created

Setting up sync receiver
========================

.. code-block:: console

uart:~$ bt init
Bluetooth initialized
uart:~$ bt scan on
[DEVICE]: 42:0F:7A:40:AE:21 (random), AD evt type 5, RSSI -27 C:0 S:0 D:0 SR:0 E:1 Prim: LE 1M, Secn: LE 2M, Interval: 0x0780 (2400000 us), SID: 0x0
uart:~$ bt per-adv-sync-create 42:0F:7A:40:AE:21 (random) 0
Per adv sync pending
PER_ADV_SYNC[0]: [DEVICE]: 42:0F:7A:40:AE:21 (random) synced, Interval 0x0780 (2400000 us), PHY LE 2M, SD 0x0000, PAST peer not present
PER_ADV_SYNC[0]: [DEVICE]: 42:0F:7A:40:AE:21 (random), tx_power 127, RSSI -28, CTE 0, data length 0
BIG_INFO PER_ADV_SYNC[0]: [DEVICE]: 42:0F:7A:40:AE:21 (random), sid 0x00, num_bis 1, nse 0x04, interval 0x0008 (10000 us), bn 0x01, pto 0x01, irc 0x03, max_pdu 0x00f7, sdu_interval 0x2710, max_sdu 0x00f7, phy LE 2M, framing 0x00, not encrypted
uart:~$ iso sync-big 1
BIG syncing
ISO Channel 0x200008c0 connected


If encrypted broadcast is required, then a broadcast code can be provided as

.. code-block:: console

uart:~$ iso sync-big 1 enc 00112233445566778899aabbccddffff
BIG syncing
ISO Channel 0x200008c0 connected
90 changes: 37 additions & 53 deletions subsys/bluetooth/host/shell/iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
#if defined(CONFIG_BT_ISO_TX)
#define DEFAULT_IO_QOS \
{ \
.sdu = 40u, .phy = BT_GAP_LE_PHY_2M, .rtn = 2u, \
.sdu = 40u, \
.phy = BT_GAP_LE_PHY_2M, \
.rtn = 2u, \
}

#define TX_BUF_TIMEOUT K_SECONDS(1)
Expand All @@ -56,8 +58,7 @@ static int64_t bis_sn_last_updated_ticks;
*
* @return The next sequence number to use
*/
static uint32_t get_next_sn(uint32_t last_sn, int64_t *last_ticks,
uint32_t interval_us)
static uint32_t get_next_sn(uint32_t last_sn, int64_t *last_ticks, uint32_t interval_us)
{
int64_t uptime_ticks, delta_ticks;
uint64_t delta_us;
Expand All @@ -84,8 +85,8 @@ static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *in
struct net_buf *buf)
{
if (info->flags & BT_ISO_FLAGS_VALID) {
bt_shell_print("Incoming data channel %p len %u, seq: %d, ts: %d",
chan, buf->len, info->seq_num, info->ts);
bt_shell_print("Incoming data channel %p len %u, seq: %d, ts: %d", chan, buf->len,
info->seq_num, info->ts);
}
}
#endif /* CONFIG_BT_ISO_RX */
Expand Down Expand Up @@ -204,9 +205,7 @@ static long parse_interval(const struct shell *sh, const char *interval_str)
return -ENOEXEC;
}

if (!IN_RANGE(interval,
BT_ISO_SDU_INTERVAL_MIN,
BT_ISO_SDU_INTERVAL_MAX)) {
if (!IN_RANGE(interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) {
shell_error(sh, "Invalid interval %lu", interval);

return -ENOEXEC;
Expand All @@ -228,9 +227,7 @@ static long parse_latency(const struct shell *sh, const char *latency_str)
return -ENOEXEC;
}

if (!IN_RANGE(latency,
BT_ISO_LATENCY_MIN,
BT_ISO_LATENCY_MAX)) {
if (!IN_RANGE(latency, BT_ISO_LATENCY_MIN, BT_ISO_LATENCY_MAX)) {
shell_error(sh, "Invalid latency %lu", latency);

return -ENOEXEC;
Expand Down Expand Up @@ -406,8 +403,7 @@ static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[])
return -ENOEXEC;
}

if (phy != BT_GAP_LE_PHY_1M &&
phy != BT_GAP_LE_PHY_2M &&
if (phy != BT_GAP_LE_PHY_1M && phy != BT_GAP_LE_PHY_2M &&
phy != BT_GAP_LE_PHY_CODED) {
shell_error(sh, "Invalid phy %lu", phy);

Expand Down Expand Up @@ -486,10 +482,7 @@ static int cmd_cig_term(const struct shell *sh, size_t argc, char *argv[])

static int cmd_connect(const struct shell *sh, size_t argc, char *argv[])
{
struct bt_iso_connect_param connect_param = {
.acl = default_conn,
.iso_chan = &iso_chan
};
struct bt_iso_connect_param connect_param = {.acl = default_conn, .iso_chan = &iso_chan};
int err;

if (iso_chan.iso == NULL) {
Expand Down Expand Up @@ -517,11 +510,10 @@ static int cmd_connect(const struct shell *sh, size_t argc, char *argv[])

#if defined(CONFIG_BT_ISO_PERIPHERAL)

static int iso_accept(const struct bt_iso_accept_info *info,
struct bt_iso_chan **chan)
static int iso_accept(const struct bt_iso_accept_info *info, struct bt_iso_chan **chan)
{
bt_shell_print("Incoming request from %p with CIG ID 0x%02X and CIS ID 0x%02X",
info->acl, info->cig_id, info->cis_id);
bt_shell_print("Incoming request from %p with CIG ID 0x%02X and CIS ID 0x%02X", info->acl,
info->cig_id, info->cis_id);

if (iso_chan.iso) {
bt_shell_print("No channels available");
Expand Down Expand Up @@ -590,9 +582,7 @@ static int cmd_listen(const struct shell *sh, size_t argc, char *argv[])

static int cmd_send(const struct shell *sh, size_t argc, char *argv[])
{
static uint8_t buf_data[CONFIG_BT_ISO_TX_MTU] = {
[0 ... (CONFIG_BT_ISO_TX_MTU - 1)] = 0xff
};
static uint8_t buf_data[CONFIG_BT_ISO_TX_MTU] = {[0 ...(CONFIG_BT_ISO_TX_MTU - 1)] = 0xff};
unsigned long count = 1;
struct net_buf *buf;
int ret = 0;
Expand Down Expand Up @@ -624,8 +614,7 @@ static int cmd_send(const struct shell *sh, size_t argc, char *argv[])
}

len = MIN(iso_chan.qos->tx->sdu, CONFIG_BT_ISO_TX_MTU);
cis_sn_last = get_next_sn(cis_sn_last, &cis_sn_last_updated_ticks,
cis_sdu_interval_us);
cis_sn_last = get_next_sn(cis_sn_last, &cis_sn_last_updated_ticks, cis_sdu_interval_us);

while (count--) {
buf = net_buf_alloc(&tx_pool, TX_BUF_TIMEOUT);
Expand All @@ -651,8 +640,7 @@ static int cmd_send(const struct shell *sh, size_t argc, char *argv[])
return 0;
}

static int cmd_disconnect(const struct shell *sh, size_t argc,
char *argv[])
static int cmd_disconnect(const struct shell *sh, size_t argc, char *argv[])
{
int err;

Expand Down Expand Up @@ -701,7 +689,7 @@ static struct bt_iso_chan bis_iso_chan = {
.qos = &bis_iso_qos,
};

static struct bt_iso_chan *bis_channels[BIS_ISO_CHAN_COUNT] = { &bis_iso_chan };
static struct bt_iso_chan *bis_channels[BIS_ISO_CHAN_COUNT] = {&bis_iso_chan};

#if defined(CONFIG_BT_ISO_BROADCASTER)
static uint32_t bis_sdu_interval_us;
Expand All @@ -712,9 +700,7 @@ NET_BUF_POOL_FIXED_DEFINE(bis_tx_pool, BIS_ISO_CHAN_COUNT,

static int cmd_broadcast(const struct shell *sh, size_t argc, char *argv[])
{
static uint8_t buf_data[CONFIG_BT_ISO_TX_MTU] = {
[0 ... (CONFIG_BT_ISO_TX_MTU - 1)] = 0xff
};
static uint8_t buf_data[CONFIG_BT_ISO_TX_MTU] = {[0 ...(CONFIG_BT_ISO_TX_MTU - 1)] = 0xff};
unsigned long count = 1;
struct net_buf *buf;
int ret = 0;
Expand Down Expand Up @@ -746,8 +732,7 @@ static int cmd_broadcast(const struct shell *sh, size_t argc, char *argv[])
}

len = MIN(bis_iso_chan.qos->tx->sdu, CONFIG_BT_ISO_TX_MTU);
bis_sn_last = get_next_sn(bis_sn_last, &bis_sn_last_updated_ticks,
bis_sdu_interval_us);
bis_sn_last = get_next_sn(bis_sn_last, &bis_sn_last_updated_ticks, bis_sdu_interval_us);

while (count--) {
buf = net_buf_alloc(&bis_tx_pool, TX_BUF_TIMEOUT);
Expand Down Expand Up @@ -790,8 +775,8 @@ static int cmd_big_create(const struct shell *sh, size_t argc, char *argv[])
bis_iso_qos.tx->rtn = 2;
bis_iso_qos.tx->sdu = CONFIG_BT_ISO_TX_MTU;

bis_sdu_interval_us = param.interval = 10000; /* us */
param.latency = 20; /* ms */
bis_sdu_interval_us = param.interval = 10000; /* us */
param.latency = 20; /* ms */
param.bis_channels = bis_channels;
param.num_bis = BIS_ISO_CHAN_COUNT;
param.encryption = false;
Expand All @@ -800,10 +785,11 @@ static int cmd_big_create(const struct shell *sh, size_t argc, char *argv[])

if (argc > 1) {
if (!strcmp(argv[1], "enc")) {
uint8_t bcode_len = hex2bin(argv[1], strlen(argv[1]), param.bcode,
sizeof(param.bcode));
size_t bcode_len =
hex2bin(argv[2], strlen(argv[2]), param.bcode, sizeof(param.bcode));

if (!bcode_len || bcode_len != sizeof(param.bcode)) {
shell_error(sh, "Invalid Broadcast Code Length");
shell_error(sh, "Invalid Broadcast Code Length %zu", bcode_len);
return -ENOEXEC;
}
param.encryption = true;
Expand Down Expand Up @@ -928,8 +914,7 @@ static int cmd_big_sync(const struct shell *sh, size_t argc, char *argv[])
return -ENOEXEC;
}

if (!IN_RANGE(sync_timeout,
BT_ISO_SYNC_TIMEOUT_MIN,
if (!IN_RANGE(sync_timeout, BT_ISO_SYNC_TIMEOUT_MIN,
BT_ISO_SYNC_TIMEOUT_MAX)) {
shell_error(sh, "Invalid sync_timeout %lu", sync_timeout);

Expand All @@ -947,8 +932,8 @@ static int cmd_big_sync(const struct shell *sh, size_t argc, char *argv[])
}

memset(param.bcode, 0, sizeof(param.bcode));
bcode_len = hex2bin(argv[i], strlen(argv[i]), param.bcode,
sizeof(param.bcode));
bcode_len =
hex2bin(argv[i], strlen(argv[i]), param.bcode, sizeof(param.bcode));

if (bcode_len == 0) {
shell_error(sh, "Invalid Broadcast Code");
Expand Down Expand Up @@ -991,7 +976,8 @@ static int cmd_big_term(const struct shell *sh, size_t argc, char *argv[])
}
#endif /* CONFIG_BT_ISO_BROADCAST*/

SHELL_STATIC_SUBCMD_SET_CREATE(iso_cmds,
SHELL_STATIC_SUBCMD_SET_CREATE(
iso_cmds,
#if defined(CONFIG_BT_ISO_UNICAST)
#if defined(CONFIG_BT_ISO_CENTRAL)
SHELL_CMD_ARG(cig_create, NULL,
Expand All @@ -1001,14 +987,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE(iso_cmds,
SHELL_CMD_ARG(cig_term, NULL, "Terminate the CIG", cmd_cig_term, 1, 0),
#if defined(CONFIG_BT_SMP)
SHELL_CMD_ARG(connect, NULL, "Connect ISO Channel [security level]", cmd_connect, 1, 1),
#else /* !CONFIG_BT_SMP */
#else /* !CONFIG_BT_SMP */
SHELL_CMD_ARG(connect, NULL, "Connect ISO Channel", cmd_connect, 1, 0),
#endif /* CONFIG_BT_SMP */
#endif /* CONFIG_BT_ISO_CENTRAL */
#if defined(CONFIG_BT_ISO_PERIPHERAL)
#if defined(CONFIG_BT_SMP)
SHELL_CMD_ARG(listen, NULL, "<dir=tx,rx,txrx> [security level]", cmd_listen, 2, 1),
#else /* !CONFIG_BT_SMP */
#else /* !CONFIG_BT_SMP */
SHELL_CMD_ARG(listen, NULL, "<dir=tx,rx,txrx>", cmd_listen, 2, 0),
#endif /* CONFIG_BT_SMP */
#endif /* CONFIG_BT_ISO_PERIPHERAL */
Expand All @@ -1019,22 +1005,21 @@ SHELL_STATIC_SUBCMD_SET_CREATE(iso_cmds,
SHELL_CMD_ARG(tx_sync_read_cis, NULL, "Read CIS TX sync info", cmd_tx_sync_read_cis, 1, 0),
#endif /* CONFIG_BT_ISO_UNICAST */
#if defined(CONFIG_BT_ISO_BROADCASTER)
SHELL_CMD_ARG(create-big, NULL, "Create a BIG as a broadcaster [enc <broadcast code>]",
SHELL_CMD_ARG(create - big, NULL, "Create a BIG as a broadcaster [enc <broadcast code>]",
cmd_big_create, 1, 2),
SHELL_CMD_ARG(broadcast, NULL, "Broadcast on ISO channels", cmd_broadcast, 1, 1),
SHELL_CMD_ARG(tx_sync_read_bis, NULL, "Read BIS TX sync info", cmd_tx_sync_read_bis, 1, 0),
#endif /* CONFIG_BT_ISO_BROADCASTER */
#if defined(CONFIG_BT_ISO_SYNC_RECEIVER)
SHELL_CMD_ARG(sync-big, NULL,
SHELL_CMD_ARG(sync - big, NULL,
"Synchronize to a BIG as a receiver <BIS bitfield> [mse] "
"[timeout] [enc <broadcast code>]",
cmd_big_sync, 2, 4),
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
#if defined(CONFIG_BT_ISO_BROADCAST)
SHELL_CMD_ARG(term-big, NULL, "Terminate a BIG", cmd_big_term, 1, 0),
SHELL_CMD_ARG(term - big, NULL, "Terminate a BIG", cmd_big_term, 1, 0),
#endif /* CONFIG_BT_ISO_BROADCAST */
SHELL_SUBCMD_SET_END
);
SHELL_SUBCMD_SET_END);

static int cmd_iso(const struct shell *sh, size_t argc, char **argv)
{
Expand All @@ -1049,5 +1034,4 @@ static int cmd_iso(const struct shell *sh, size_t argc, char **argv)
return -EINVAL;
}

SHELL_CMD_ARG_REGISTER(iso, &iso_cmds, "Bluetooth ISO shell commands",
cmd_iso, 1, 1);
SHELL_CMD_ARG_REGISTER(iso, &iso_cmds, "Bluetooth ISO shell commands", cmd_iso, 1, 1);