diff --git a/subsys/bluetooth/shell/iso.c b/subsys/bluetooth/shell/iso.c index aa7cd47bfd..565755625c 100644 --- a/subsys/bluetooth/shell/iso.c +++ b/subsys/bluetooth/shell/iso.c @@ -160,58 +160,174 @@ static int cmd_cig_create(const struct shell *sh, size_t argc, char *argv[]) } } + err = 0; if (argc > 2) { - param.interval = strtol(argv[2], NULL, 0); + unsigned long interval; + + interval = shell_strtoul(argv[2], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse interval: %d", err); + + return -ENOEXEC; + } + + if (!IN_RANGE(interval, + BT_ISO_SDU_INTERVAL_MIN, + BT_ISO_SDU_INTERVAL_MAX)) { + shell_error(sh, "Invalid interval %lu", interval); + + return -ENOEXEC; + } + + param.interval = interval; } else { param.interval = 10000; } cis_sdu_interval_us = param.interval; if (argc > 3) { - param.packing = strtol(argv[3], NULL, 0); + unsigned long packing; + + packing = shell_strtoul(argv[3], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse packing: %d", err); + + return -ENOEXEC; + } + + if (!IN_RANGE(packing, + BT_ISO_PACKING_SEQUENTIAL, + BT_ISO_PACKING_INTERLEAVED)) { + shell_error(sh, "Invalid packing %lu", packing); + + return -ENOEXEC; + } + + param.packing = packing; } else { param.packing = 0; } if (argc > 4) { - param.framing = strtol(argv[4], NULL, 0); + unsigned long framing; + + framing = shell_strtoul(argv[4], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse framing: %d", err); + + return -ENOEXEC; + } + + if (!IN_RANGE(framing, + BT_ISO_FRAMING_UNFRAMED, + BT_ISO_FRAMING_FRAMED)) { + shell_error(sh, "Invalid framing %lu", framing); + + return -ENOEXEC; + } + + param.framing = framing; } else { param.framing = 0; } if (argc > 5) { - param.latency = strtol(argv[5], NULL, 0); + unsigned long latency; + + latency = shell_strtoul(argv[5], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse latency: %d", err); + + return -ENOEXEC; + } + + if (!IN_RANGE(latency, + BT_ISO_LATENCY_MIN, + BT_ISO_LATENCY_MAX)) { + shell_error(sh, "Invalid latency %lu", latency); + + return -ENOEXEC; + } + + param.latency = latency; } else { param.latency = 10; } if (argc > 6) { + unsigned long sdu; + + sdu = shell_strtoul(argv[6], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse sdu: %d", err); + + return -ENOEXEC; + } + + if (sdu > BT_ISO_MAX_SDU) { + shell_error(sh, "Invalid sdu %lu", sdu); + + return -ENOEXEC; + } + if (chans[0]->qos->tx) { - chans[0]->qos->tx->sdu = strtol(argv[6], NULL, 0); + chans[0]->qos->tx->sdu = sdu; } if (chans[0]->qos->rx) { - chans[0]->qos->rx->sdu = strtol(argv[6], NULL, 0); + chans[0]->qos->rx->sdu = sdu; } } if (argc > 7) { + unsigned long phy; + + phy = shell_strtoul(argv[7], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse phy: %d", err); + + return -ENOEXEC; + } + + 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); + + return -ENOEXEC; + } + if (chans[0]->qos->tx) { - chans[0]->qos->tx->phy = strtol(argv[7], NULL, 0); + chans[0]->qos->tx->phy = phy; } if (chans[0]->qos->rx) { - chans[0]->qos->rx->phy = strtol(argv[7], NULL, 0); + chans[0]->qos->rx->phy = phy; } } if (argc > 8) { + unsigned long rtn; + + rtn = shell_strtoul(argv[8], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse rtn: %d", err); + + return -ENOEXEC; + } + + if (rtn > BT_ISO_CONNECTED_RTN_MAX) { + shell_error(sh, "Invalid rtn %lu", rtn); + + return -ENOEXEC; + } + if (chans[0]->qos->tx) { - chans[0]->qos->tx->rtn = strtol(argv[8], NULL, 0); + chans[0]->qos->tx->rtn = rtn; } if (chans[0]->qos->rx) { - chans[0]->qos->rx->rtn = strtol(argv[8], NULL, 0); + chans[0]->qos->rx->rtn = rtn; } } @@ -361,11 +477,18 @@ 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 }; - int ret, len, count = 1; + unsigned long count = 1; struct net_buf *buf; + int ret = 0; + int len; if (argc > 1) { - count = strtoul(argv[1], NULL, 10); + count = shell_strtoul(argv[1], 0, &ret); + if (ret != 0) { + shell_error(sh, "Could not parse count: %d", ret); + + return -ENOEXEC; + } } if (!iso_chan.iso) { @@ -465,11 +588,18 @@ 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 }; - int ret, len, count = 1; + unsigned long count = 1; struct net_buf *buf; + int ret = 0; + int len; if (argc > 1) { - count = strtoul(argv[1], NULL, 10); + count = shell_strtoul(argv[1], 0, &ret); + if (ret != 0) { + shell_error(sh, "Could not parse count: %d", ret); + + return -ENOEXEC; + } } if (!bis_iso_chan.iso) { @@ -591,28 +721,38 @@ static int cmd_big_sync(const struct shell *sh, size_t argc, char *argv[]) /* TODO: Add support to select which PA sync to BIG sync to */ struct bt_le_per_adv_sync *pa_sync = per_adv_syncs[0]; struct bt_iso_big_sync_param param; + unsigned long bis_bitfield; if (!pa_sync) { shell_error(sh, "No PA sync selected"); return -ENOEXEC; } + bis_bitfield = shell_strtoul(argv[1], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse bis_bitfield: %d", err); + + return -ENOEXEC; + } + + if (bis_bitfield > BIT_MASK(BT_ISO_BIS_INDEX_MAX)) { + shell_error(sh, "Invalid bis_bitfield: %lu", bis_bitfield); + + return -ENOEXEC; + } + bis_iso_qos.tx = NULL; param.bis_channels = bis_channels; param.num_bis = BIS_ISO_CHAN_COUNT; param.encryption = false; - param.bis_bitfield = strtoul(argv[1], NULL, 16); + param.bis_bitfield = bis_bitfield; param.mse = 0; param.sync_timeout = 0xFF; - for (int i = 2; i < argc; i++) { + for (size_t i = 2U; i < argc; i++) { if (!strcmp(argv[i], "mse")) { - param.mse = strtoul(argv[i], NULL, 16); - } else if (!strcmp(argv[i], "timeout")) { - param.sync_timeout = strtoul(argv[i], NULL, 16); - } else if (!strcmp(argv[i], "enc")) { - uint8_t bcode_len; + unsigned long mse; i++; if (i == argc) { @@ -620,13 +760,69 @@ static int cmd_big_sync(const struct shell *sh, size_t argc, char *argv[]) return SHELL_CMD_HELP_PRINTED; } + mse = shell_strtoul(argv[i], 0, &err); + if (err != 0) { + shell_error(sh, "Could not parse mse: %d", err); + + return -ENOEXEC; + } + + if (!IN_RANGE(mse, + BT_ISO_SYNC_MSE_MIN, + BT_ISO_SYNC_MSE_MAX)) { + shell_error(sh, "Invalid mse %lu", mse); + + return -ENOEXEC; + } + + param.mse = mse; + } else if (!strcmp(argv[i], "timeout")) { + unsigned long sync_timeout; + + i++; + if (i == argc) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + sync_timeout = shell_strtoul(argv[i], 0, &err); + if (err != 0) { + shell_error(sh, + "Could not parse sync_timeout: %d", + err); + + return -ENOEXEC; + } + + if (!IN_RANGE(sync_timeout, + BT_ISO_SYNC_MSE_MIN, + BT_ISO_SYNC_MSE_MAX)) { + shell_error(sh, "Invalid sync_timeout %lu", + sync_timeout); + + return -ENOEXEC; + } + + param.sync_timeout = sync_timeout; + } else if (!strcmp(argv[i], "enc")) { + size_t bcode_len; + + i++; + if (i == argc) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + memset(param.bcode, 0, sizeof(param.bcode)); bcode_len = hex2bin(argv[i], strlen(argv[i]), param.bcode, sizeof(param.bcode)); - if (!bcode_len || bcode_len != sizeof(param.bcode)) { - shell_error(sh, "Invalid Broadcast Code Length"); + if (bcode_len == 0) { + shell_error(sh, "Invalid Broadcast Code"); + return -ENOEXEC; } + param.encryption = true; } else { shell_help(sh);