From 3a25c8344195efb042476b916e6322fa77d9dc9d Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 4 Apr 2025 11:27:39 +0200 Subject: [PATCH 1/2] Bluetooth: ISO: Shell: Fix bcode for big_create The broadcast code was attempting to read from argv[1] instead of argv[2] that actually contains the broadcast code. Signed-off-by: Emil Gydesen --- subsys/bluetooth/host/shell/iso.c | 90 +++++++++++++------------------ 1 file changed, 37 insertions(+), 53 deletions(-) diff --git a/subsys/bluetooth/host/shell/iso.c b/subsys/bluetooth/host/shell/iso.c index cc2adda15cd5..17f2839b0349 100644 --- a/subsys/bluetooth/host/shell/iso.c +++ b/subsys/bluetooth/host/shell/iso.c @@ -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) @@ -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; @@ -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 */ @@ -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; @@ -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; @@ -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); @@ -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) { @@ -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"); @@ -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; @@ -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); @@ -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; @@ -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; @@ -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; @@ -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); @@ -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; @@ -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; @@ -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); @@ -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"); @@ -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, @@ -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, " [security level]", cmd_listen, 2, 1), -#else /* !CONFIG_BT_SMP */ +#else /* !CONFIG_BT_SMP */ SHELL_CMD_ARG(listen, NULL, "", cmd_listen, 2, 0), #endif /* CONFIG_BT_SMP */ #endif /* CONFIG_BT_ISO_PERIPHERAL */ @@ -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 ]", + SHELL_CMD_ARG(create - big, NULL, "Create a BIG as a broadcaster [enc ]", 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 [mse] " "[timeout] [enc ]", 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) { @@ -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); From 5ec764b98e0868fecd5d0ffa1efff01021300141 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 4 Apr 2025 11:35:19 +0200 Subject: [PATCH 2/2] doc: Bluetooth: ISO: Add broadcast to ISO shell docs Add examples of how to use the ISO shell with broadcast. Signed-off-by: Emil Gydesen --- doc/connectivity/bluetooth/shell/host/iso.rst | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/doc/connectivity/bluetooth/shell/host/iso.rst b/doc/connectivity/bluetooth/shell/host/iso.rst index f79b1374123c..96200001583f 100644 --- a/doc/connectivity/bluetooth/shell/host/iso.rst +++ b/doc/connectivity/bluetooth/shell/host/iso.rst @@ -23,6 +23,8 @@ Commands term-big :Terminate a BIG +Unicast examples +**************** 1. [Central] Create CIG: Requires to be connected: @@ -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