The publication period is defined by Steps and Resolution. At BLE Mesh protocol level, the period is encoded in a byte where first LSB 6 bits correspond to PerSteps and the last two to PerRes. There is an issue on how the code at `subsys/bluetooth/mesh/shell/cfg.c:model_pub_set` is encoding these two values into the publication period byte. This is commit fixes issue #87780 Signed-off-by: Raúl Gotor <raulgotor@gmail.com>
1896 lines
49 KiB
C
1896 lines
49 KiB
C
/*
|
|
* Copyright (c) 2022 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <zephyr/shell/shell.h>
|
|
#include <zephyr/bluetooth/mesh.h>
|
|
|
|
#include "mesh/net.h"
|
|
#include "mesh/access.h"
|
|
#include "utils.h"
|
|
#include <zephyr/bluetooth/mesh/shell.h>
|
|
|
|
#define CID_NVAL 0xffff
|
|
|
|
/* Default net & app key values, unless otherwise specified */
|
|
extern const uint8_t bt_mesh_shell_default_key[16];
|
|
|
|
static int cmd_reset(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
int err;
|
|
bool reset = false;
|
|
|
|
err = bt_mesh_cfg_cli_node_reset(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &reset);
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Remote Node Reset (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
|
|
struct bt_mesh_cdb_node *node = bt_mesh_cdb_node_get(bt_mesh_shell_target_ctx.dst);
|
|
|
|
if (node) {
|
|
bt_mesh_cdb_node_del(node, true);
|
|
}
|
|
}
|
|
|
|
shell_print(sh, "Remote node reset complete");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_timeout(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
int32_t timeout_ms;
|
|
int err = 0;
|
|
|
|
if (argc == 2) {
|
|
int32_t timeout_s = shell_strtol(argv[1], 0, &err);
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (timeout_s < 0 || timeout_s > (INT32_MAX / 1000)) {
|
|
timeout_ms = SYS_FOREVER_MS;
|
|
} else {
|
|
timeout_ms = timeout_s * MSEC_PER_SEC;
|
|
}
|
|
|
|
bt_mesh_cfg_cli_timeout_set(timeout_ms);
|
|
}
|
|
|
|
timeout_ms = bt_mesh_cfg_cli_timeout_get();
|
|
if (timeout_ms == SYS_FOREVER_MS) {
|
|
shell_print(sh, "Message timeout: forever");
|
|
} else {
|
|
shell_print(sh, "Message timeout: %u seconds", timeout_ms / 1000);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_RX_SDU_MAX);
|
|
struct bt_mesh_comp_p0_elem elem;
|
|
struct bt_mesh_comp_p0 comp;
|
|
uint8_t page = 0x00;
|
|
int err = 0;
|
|
|
|
if (argc > 1) {
|
|
page = shell_strtoul(argv[1], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_comp_data_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, page, &page, &buf);
|
|
if (err) {
|
|
shell_error(sh, "Getting composition failed (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (page != 0 && page != 128 &&
|
|
((page != 1 && page != 129) || !IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) &&
|
|
((page != 2 && page != 130) || !IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2))) {
|
|
shell_print(sh, "Got page %d. No parser available.", page);
|
|
return 0;
|
|
}
|
|
|
|
if (page == 0 || page == 128) {
|
|
err = bt_mesh_comp_p0_get(&comp, &buf);
|
|
|
|
if (err) {
|
|
shell_error(sh, "Couldn't parse Composition data (err %d)",
|
|
err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "Got Composition Data for 0x%04x, page: %d:",
|
|
bt_mesh_shell_target_ctx.dst, page);
|
|
shell_print(sh, "\tCID 0x%04x", comp.cid);
|
|
shell_print(sh, "\tPID 0x%04x", comp.pid);
|
|
shell_print(sh, "\tVID 0x%04x", comp.vid);
|
|
shell_print(sh, "\tCRPL 0x%04x", comp.crpl);
|
|
shell_print(sh, "\tFeatures 0x%04x", comp.feat);
|
|
|
|
while (bt_mesh_comp_p0_elem_pull(&comp, &elem)) {
|
|
int i;
|
|
|
|
shell_print(sh, "\tElement @ 0x%04x:", elem.loc);
|
|
|
|
if (elem.nsig) {
|
|
shell_print(sh, "\t\tSIG Models:");
|
|
} else {
|
|
shell_print(sh, "\t\tNo SIG Models");
|
|
}
|
|
|
|
for (i = 0; i < elem.nsig; i++) {
|
|
uint16_t mod_id = bt_mesh_comp_p0_elem_mod(&elem, i);
|
|
|
|
shell_print(sh, "\t\t\t0x%04x", mod_id);
|
|
}
|
|
|
|
if (elem.nvnd) {
|
|
shell_print(sh, "\t\tVendor Models:");
|
|
} else {
|
|
shell_print(sh, "\t\tNo Vendor Models");
|
|
}
|
|
|
|
for (i = 0; i < elem.nvnd; i++) {
|
|
struct bt_mesh_mod_id_vnd mod =
|
|
bt_mesh_comp_p0_elem_mod_vnd(&elem, i);
|
|
|
|
shell_print(sh, "\t\t\tCompany 0x%04x: 0x%04x",
|
|
mod.company, mod.id);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) {
|
|
/* size of 32 is chosen arbitrary, as sufficient for testing purposes */
|
|
NET_BUF_SIMPLE_DEFINE(p1_buf, 32);
|
|
NET_BUF_SIMPLE_DEFINE(p1_item_buf, 32);
|
|
struct bt_mesh_comp_p1_elem p1_elem = { ._buf = &p1_buf };
|
|
struct bt_mesh_comp_p1_model_item mod_item = { ._buf = &p1_item_buf };
|
|
struct bt_mesh_comp_p1_ext_item ext_item = { 0 };
|
|
int mod_idx = 1;
|
|
|
|
if (!buf.len) {
|
|
shell_error(sh, "Composition data empty");
|
|
return 0;
|
|
}
|
|
shell_print(sh,
|
|
"Got Composition Data for 0x%04x, page: %d:",
|
|
bt_mesh_shell_target_ctx.dst, page);
|
|
|
|
while (bt_mesh_comp_p1_elem_pull(&buf, &p1_elem)) {
|
|
int i, j;
|
|
|
|
shell_print(sh, "\tElement #%d description", mod_idx);
|
|
|
|
for (i = 0; i < p1_elem.nsig; i++) {
|
|
if (bt_mesh_comp_p1_item_pull(&p1_elem, &mod_item)) {
|
|
shell_print(sh, "\t\tSIG Model Item #%d:", i+1);
|
|
if (mod_item.cor_present) {
|
|
shell_print(sh,
|
|
"\t\t\tWith Corresponding ID %u",
|
|
mod_item.cor_id);
|
|
} else {
|
|
shell_print(sh,
|
|
"\t\t\tWithout Corresponding ID");
|
|
}
|
|
shell_print(sh,
|
|
"\t\t\tWith %u Extended Model Item(s)",
|
|
mod_item.ext_item_cnt);
|
|
}
|
|
for (j = 0; j < mod_item.ext_item_cnt; j++) {
|
|
bt_mesh_comp_p1_pull_ext_item(&mod_item,
|
|
&ext_item);
|
|
shell_print(sh,
|
|
"\t\t\t\tExtended Item #%d:", j+1);
|
|
if (ext_item.type == SHORT) {
|
|
shell_print(sh,
|
|
"\t\t\t\t\toffset: %u",
|
|
ext_item.short_item.elem_offset);
|
|
shell_print(sh,
|
|
"\t\t\t\t\tindex: %u",
|
|
ext_item.short_item.mod_item_idx);
|
|
} else {
|
|
shell_print(sh,
|
|
"\t\t\t\t\toffset: %u",
|
|
ext_item.long_item.elem_offset);
|
|
shell_print(sh,
|
|
"\t\t\t\t\tindex: %u",
|
|
ext_item.long_item.mod_item_idx);
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < p1_elem.nvnd; i++) {
|
|
if (bt_mesh_comp_p1_item_pull(&p1_elem, &mod_item)) {
|
|
shell_print(sh, "\t\tVendor Model Item #%d:", i+1);
|
|
if (mod_item.cor_present) {
|
|
shell_print(sh,
|
|
"\t\t\tWith Corresponding ID %u",
|
|
mod_item.cor_id);
|
|
} else {
|
|
shell_print(sh,
|
|
"\t\t\tWithout Corresponding ID");
|
|
}
|
|
shell_print(sh,
|
|
"\t\t\tWith %u Extended Model Item(s)",
|
|
mod_item.ext_item_cnt);
|
|
}
|
|
for (j = 0; j < mod_item.ext_item_cnt; j++) {
|
|
bt_mesh_comp_p1_pull_ext_item(&mod_item,
|
|
&ext_item);
|
|
shell_print(sh,
|
|
"\t\t\t\tExtended Item #%d:", j+1);
|
|
if (ext_item.type == SHORT) {
|
|
shell_print(sh,
|
|
"\t\t\t\t\toffset: %u",
|
|
ext_item.short_item.elem_offset);
|
|
shell_print(sh,
|
|
"\t\t\t\t\tindex: %u",
|
|
ext_item.short_item.mod_item_idx);
|
|
} else {
|
|
shell_print(sh,
|
|
"\t\t\t\t\toffset: %u",
|
|
ext_item.long_item.elem_offset);
|
|
shell_print(sh,
|
|
"\t\t\t\t\tindex: %u",
|
|
ext_item.long_item.mod_item_idx);
|
|
}
|
|
}
|
|
}
|
|
mod_idx++;
|
|
}
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) {
|
|
/* size of 32 is chosen arbitrary, as sufficient for testing purposes */
|
|
NET_BUF_SIMPLE_DEFINE(p2_elem_offset_buf, 32);
|
|
NET_BUF_SIMPLE_DEFINE(p2_data_buf, 32);
|
|
struct bt_mesh_comp_p2_record p2_elem = {
|
|
.elem_buf = &p2_elem_offset_buf,
|
|
.data_buf = &p2_data_buf
|
|
};
|
|
|
|
if (!buf.len) {
|
|
shell_error(sh, "Composition data empty");
|
|
return 0;
|
|
}
|
|
shell_print(sh, "Got Composition Data for 0x%04x, page: %d:",
|
|
bt_mesh_shell_target_ctx.dst, page);
|
|
|
|
while (bt_mesh_comp_p2_record_pull(&buf, &p2_elem)) {
|
|
|
|
shell_print(sh, "\tMesh Profile id: %04x ", p2_elem.id);
|
|
shell_print(sh, "\t\tVersion: %d.%d.%d ", p2_elem.version.x,
|
|
p2_elem.version.y, p2_elem.version.z);
|
|
shell_print(sh, "\t\tElement offsets:");
|
|
|
|
while (p2_elem.elem_buf->len) {
|
|
shell_print(sh, "\t\t\t%d ",
|
|
net_buf_simple_pull_u8(p2_elem.elem_buf));
|
|
}
|
|
|
|
if (p2_elem.data_buf->len) {
|
|
shell_print(sh, "\t\t%d bytes of additional data is available",
|
|
p2_elem.data_buf->len);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (buf.len) {
|
|
shell_print(sh, "\t\t...truncated data!");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_beacon(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
if (argc < 2) {
|
|
err = bt_mesh_cfg_cli_beacon_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &status);
|
|
} else {
|
|
uint8_t val = shell_strtobool(argv[1], 0, &err);
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_beacon_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, val, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Beacon Get/Set message (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "Beacon state is 0x%02x", status);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_ttl(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t ttl;
|
|
int err = 0;
|
|
|
|
if (argc < 2) {
|
|
err = bt_mesh_cfg_cli_ttl_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &ttl);
|
|
} else {
|
|
uint8_t val = shell_strtoul(argv[1], 0, &err);
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_ttl_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, val, &ttl);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Default TTL Get/Set (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "Default TTL is 0x%02x", ttl);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_friend(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t frnd;
|
|
int err = 0;
|
|
|
|
if (argc < 2) {
|
|
err = bt_mesh_cfg_cli_friend_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &frnd);
|
|
} else {
|
|
uint8_t val = shell_strtobool(argv[1], 0, &err);
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_friend_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, val, &frnd);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Friend Get/Set (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "Friend is set to 0x%02x", frnd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_gatt_proxy(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t proxy;
|
|
int err = 0;
|
|
|
|
if (argc < 2) {
|
|
err = bt_mesh_cfg_cli_gatt_proxy_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &proxy);
|
|
} else {
|
|
uint8_t val = shell_strtobool(argv[1], 0, &err);
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_gatt_proxy_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, val, &proxy);
|
|
}
|
|
|
|
if (err) {
|
|
shell_print(sh, "Unable to send GATT Proxy Get/Set (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "GATT Proxy is set to 0x%02x", proxy);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_polltimeout_get(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t lpn_address;
|
|
int32_t poll_timeout;
|
|
int err = 0;
|
|
|
|
lpn_address = shell_strtoul(argv[1], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_lpn_timeout_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, lpn_address, &poll_timeout);
|
|
if (err) {
|
|
shell_error(sh, "Unable to send LPN PollTimeout Get (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "PollTimeout value %d", poll_timeout);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_net_transmit(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t transmit;
|
|
int err = 0;
|
|
|
|
if (argc < 2) {
|
|
err = bt_mesh_cfg_cli_net_transmit_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &transmit);
|
|
} else {
|
|
if (argc != 3) {
|
|
shell_warn(sh, "Wrong number of input arguments"
|
|
"(2 arguments are required)");
|
|
return -EINVAL;
|
|
}
|
|
|
|
uint8_t count, interval, new_transmit;
|
|
|
|
count = shell_strtoul(argv[1], 0, &err);
|
|
interval = shell_strtoul(argv[2], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
new_transmit = BT_MESH_TRANSMIT(count, interval);
|
|
|
|
err = bt_mesh_cfg_cli_net_transmit_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, new_transmit,
|
|
&transmit);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send network transmit Get/Set (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "Transmit 0x%02x (count %u interval %ums)", transmit,
|
|
BT_MESH_TRANSMIT_COUNT(transmit), BT_MESH_TRANSMIT_INT(transmit));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_relay(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t relay, transmit;
|
|
int err = 0;
|
|
|
|
if (argc < 2) {
|
|
err = bt_mesh_cfg_cli_relay_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &relay, &transmit);
|
|
} else {
|
|
uint8_t count, interval, new_transmit;
|
|
uint8_t val = shell_strtobool(argv[1], 0, &err);
|
|
|
|
if (val) {
|
|
if (argc > 2) {
|
|
count = shell_strtoul(argv[2], 0, &err);
|
|
} else {
|
|
count = 2U;
|
|
}
|
|
|
|
if (argc > 3) {
|
|
interval = shell_strtoul(argv[3], 0, &err);
|
|
} else {
|
|
interval = 20U;
|
|
}
|
|
|
|
new_transmit = BT_MESH_TRANSMIT(count, interval);
|
|
} else {
|
|
new_transmit = 0U;
|
|
}
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_relay_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, val, new_transmit, &relay,
|
|
&transmit);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Relay Get/Set (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "Relay is 0x%02x, Transmit 0x%02x (count %u interval %ums)", relay,
|
|
transmit, BT_MESH_TRANSMIT_COUNT(transmit), BT_MESH_TRANSMIT_INT(transmit));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_net_key_add(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
bool has_key_val = (argc > 2);
|
|
uint8_t key_val[16];
|
|
uint16_t key_net_idx;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
key_net_idx = shell_strtoul(argv[1], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (has_key_val) {
|
|
size_t len;
|
|
|
|
len = hex2bin(argv[2], strlen(argv[2]), key_val, sizeof(key_val));
|
|
(void)memset(key_val + len, 0, sizeof(key_val) - len);
|
|
} else {
|
|
memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
|
|
struct bt_mesh_cdb_subnet *subnet;
|
|
|
|
subnet = bt_mesh_cdb_subnet_get(key_net_idx);
|
|
if (subnet) {
|
|
if (has_key_val) {
|
|
shell_error(sh, "Subnet 0x%03x already has a value", key_net_idx);
|
|
return 0;
|
|
}
|
|
|
|
if (bt_mesh_cdb_subnet_key_export(subnet, 0, key_val)) {
|
|
shell_error(sh, "Unable to export subnet key from cdb 0x%03x",
|
|
key_net_idx);
|
|
return 0;
|
|
}
|
|
} else {
|
|
subnet = bt_mesh_cdb_subnet_alloc(key_net_idx);
|
|
if (!subnet) {
|
|
shell_error(sh, "No space for subnet in cdb");
|
|
return 0;
|
|
}
|
|
|
|
if (bt_mesh_cdb_subnet_key_import(subnet, 0, key_val)) {
|
|
shell_error(sh, "Unable to import subnet key into cdb 0x%03x",
|
|
key_net_idx);
|
|
return 0;
|
|
}
|
|
bt_mesh_cdb_subnet_store(subnet);
|
|
}
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_net_key_add(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, key_net_idx, key_val, &status);
|
|
if (err) {
|
|
shell_print(sh, "Unable to send NetKey Add (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "NetKeyAdd failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "NetKey added with NetKey Index 0x%03x", key_net_idx);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_net_key_update(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
bool has_key_val = (argc > 2);
|
|
uint8_t key_val[16];
|
|
uint16_t key_net_idx;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
key_net_idx = shell_strtoul(argv[1], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (has_key_val) {
|
|
size_t len;
|
|
|
|
len = hex2bin(argv[2], strlen(argv[2]), key_val, sizeof(key_val));
|
|
(void)memset(key_val + len, 0, sizeof(key_val) - len);
|
|
} else {
|
|
memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_net_key_update(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, key_net_idx, key_val,
|
|
&status);
|
|
if (err) {
|
|
shell_print(sh, "Unable to send NetKey Update (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "NetKeyUpdate failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "NetKey updated with NetKey Index 0x%03x", key_net_idx);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_net_key_get(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t keys[16];
|
|
size_t cnt;
|
|
int err, i;
|
|
|
|
cnt = ARRAY_SIZE(keys);
|
|
|
|
err = bt_mesh_cfg_cli_net_key_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, keys, &cnt);
|
|
if (err) {
|
|
shell_print(sh, "Unable to send NetKeyGet (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "NetKeys known by 0x%04x:", bt_mesh_shell_target_ctx.dst);
|
|
for (i = 0; i < cnt; i++) {
|
|
shell_print(sh, "\t0x%03x", keys[i]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_net_key_del(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t key_net_idx;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
key_net_idx = shell_strtoul(argv[1], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_net_key_del(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, key_net_idx, &status);
|
|
if (err) {
|
|
shell_print(sh, "Unable to send NetKeyDel (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "NetKeyDel failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "NetKey 0x%03x deleted", key_net_idx);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_app_key_add(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t key_val[16];
|
|
uint16_t key_net_idx, key_app_idx;
|
|
bool has_key_val = (argc > 3);
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
key_net_idx = shell_strtoul(argv[1], 0, &err);
|
|
key_app_idx = shell_strtoul(argv[2], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (has_key_val) {
|
|
size_t len;
|
|
|
|
len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
|
|
(void)memset(key_val + len, 0, sizeof(key_val) - len);
|
|
} else {
|
|
memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
|
|
struct bt_mesh_cdb_app_key *app_key;
|
|
|
|
app_key = bt_mesh_cdb_app_key_get(key_app_idx);
|
|
if (app_key) {
|
|
if (has_key_val) {
|
|
shell_error(sh, "App key 0x%03x already has a value", key_app_idx);
|
|
return 0;
|
|
}
|
|
|
|
if (bt_mesh_cdb_app_key_export(app_key, 0, key_val)) {
|
|
shell_error(sh, "Unable to export app key 0x%03x from cdb",
|
|
key_app_idx);
|
|
return 0;
|
|
}
|
|
} else {
|
|
app_key = bt_mesh_cdb_app_key_alloc(key_net_idx, key_app_idx);
|
|
if (!app_key) {
|
|
shell_error(sh, "No space for app key in cdb");
|
|
return 0;
|
|
}
|
|
|
|
if (bt_mesh_cdb_app_key_import(app_key, 0, key_val)) {
|
|
shell_error(sh, "Unable to import app key 0x%03x into cdb",
|
|
key_app_idx);
|
|
return 0;
|
|
}
|
|
bt_mesh_cdb_app_key_store(app_key);
|
|
}
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_app_key_add(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
|
|
key_val, &status);
|
|
if (err) {
|
|
shell_error(sh, "Unable to send App Key Add (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "AppKeyAdd failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "AppKey added, NetKeyIndex 0x%04x AppKeyIndex 0x%04x", key_net_idx,
|
|
key_app_idx);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_app_key_upd(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t key_val[16];
|
|
uint16_t key_net_idx, key_app_idx;
|
|
bool has_key_val = (argc > 3);
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
key_net_idx = shell_strtoul(argv[1], 0, &err);
|
|
key_app_idx = shell_strtoul(argv[2], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (has_key_val) {
|
|
size_t len;
|
|
|
|
len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
|
|
(void)memset(key_val + len, 0, sizeof(key_val) - len);
|
|
} else {
|
|
memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_app_key_update(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
|
|
key_val, &status);
|
|
if (err) {
|
|
shell_error(sh, "Unable to send App Key Update (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "AppKey update failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "AppKey updated, NetKeyIndex 0x%04x AppKeyIndex 0x%04x",
|
|
key_net_idx, key_app_idx);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_app_key_get(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t net_idx;
|
|
uint16_t keys[16];
|
|
size_t cnt;
|
|
uint8_t status;
|
|
int err = 0;
|
|
int i;
|
|
|
|
cnt = ARRAY_SIZE(keys);
|
|
net_idx = shell_strtoul(argv[1], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_app_key_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, net_idx, &status, keys, &cnt);
|
|
if (err) {
|
|
shell_print(sh, "Unable to send AppKeyGet (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "AppKeyGet failed with status 0x%02x", status);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "AppKeys for NetKey 0x%03x known by 0x%04x:", net_idx,
|
|
bt_mesh_shell_target_ctx.dst);
|
|
for (i = 0; i < cnt; i++) {
|
|
shell_print(sh, "\t0x%03x", keys[i]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_node_id(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t net_idx;
|
|
uint8_t status, identify;
|
|
int err = 0;
|
|
|
|
net_idx = shell_strtoul(argv[1], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc <= 2) {
|
|
err = bt_mesh_cfg_cli_node_identity_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, net_idx, &status,
|
|
&identify);
|
|
if (err) {
|
|
shell_print(sh, "Unable to send Node Identify Get (err %d)", err);
|
|
return 0;
|
|
}
|
|
} else {
|
|
uint8_t new_identify = shell_strtoul(argv[2], 0, &err);
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_node_identity_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, net_idx,
|
|
new_identify, &status, &identify);
|
|
if (err) {
|
|
shell_print(sh, "Unable to send Node Identify Set (err %d)", err);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Node Identify Get/Set failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "Node Identify Get/Set successful with identify 0x%02x", identify);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_app_key_del(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t key_net_idx, key_app_idx;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
key_net_idx = shell_strtoul(argv[1], 0, &err);
|
|
key_app_idx = shell_strtoul(argv[2], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_app_key_del(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
|
|
&status);
|
|
if (err) {
|
|
shell_error(sh, "Unable to send App Key del(err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "AppKeyDel failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "AppKey deleted, NetKeyIndex 0x%04x AppKeyIndex 0x%04x",
|
|
key_net_idx, key_app_idx);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_app_bind(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, mod_app_idx, mod_id, cid;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
mod_app_idx = shell_strtoul(argv[2], 0, &err);
|
|
mod_id = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 4) {
|
|
cid = shell_strtoul(argv[4], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_app_bind_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr,
|
|
mod_app_idx, mod_id, cid, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_app_bind(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, mod_app_idx,
|
|
mod_id, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model App Bind (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model App Bind failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "AppKey successfully bound");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_app_unbind(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, mod_app_idx, mod_id, cid;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
mod_app_idx = shell_strtoul(argv[2], 0, &err);
|
|
mod_id = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 4) {
|
|
cid = shell_strtoul(argv[4], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_app_unbind_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr,
|
|
mod_app_idx, mod_id, cid, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_app_unbind(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr,
|
|
mod_app_idx, mod_id, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model App Unbind (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model App Unbind failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "AppKey successfully unbound");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_app_get(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, mod_id, cid;
|
|
uint16_t apps[16];
|
|
uint8_t status;
|
|
size_t cnt;
|
|
int err = 0;
|
|
int i;
|
|
|
|
cnt = ARRAY_SIZE(apps);
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
mod_id = shell_strtoul(argv[2], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 3) {
|
|
cid = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_app_get_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
|
|
cid, &status, apps, &cnt);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_app_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
|
|
&status, apps, &cnt);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model App Get (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model App Get failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "Apps bound to Element 0x%04x, Model 0x%04x %s:", elem_addr, mod_id,
|
|
argc > 3 ? argv[3] : "(SIG)");
|
|
|
|
if (!cnt) {
|
|
shell_print(sh, "\tNone.");
|
|
}
|
|
|
|
for (i = 0; i < cnt; i++) {
|
|
shell_print(sh, "\t0x%04x", apps[i]);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_sub_add(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, sub_addr, mod_id, cid;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
sub_addr = shell_strtoul(argv[2], 0, &err);
|
|
mod_id = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 4) {
|
|
cid = shell_strtoul(argv[4], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_sub_add_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
|
|
mod_id, cid, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_sub_add(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
|
|
mod_id, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model Subscription Add (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model Subscription Add failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "Model subscription was successful");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_sub_del(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, sub_addr, mod_id, cid;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
sub_addr = shell_strtoul(argv[2], 0, &err);
|
|
mod_id = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 4) {
|
|
cid = shell_strtoul(argv[4], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_sub_del_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
|
|
mod_id, cid, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_sub_del(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
|
|
mod_id, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model Subscription Delete (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model Subscription Delete failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "Model subscription deletion was successful");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_sub_add_va(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, sub_addr, mod_id, cid;
|
|
uint8_t label[16];
|
|
uint8_t status;
|
|
size_t len;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
|
|
len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
|
|
(void)memset(label + len, 0, sizeof(label) - len);
|
|
|
|
mod_id = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 4) {
|
|
cid = shell_strtoul(argv[4], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_sub_va_add_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, label,
|
|
mod_id, cid, &sub_addr, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_sub_va_add(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, label,
|
|
mod_id, &sub_addr, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Mod Sub VA Add (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Mod Sub VA Add failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "0x%04x subscribed to Label UUID %s (va 0x%04x)", elem_addr,
|
|
argv[2], sub_addr);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_sub_del_va(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, sub_addr, mod_id, cid;
|
|
uint8_t label[16];
|
|
uint8_t status;
|
|
size_t len;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
|
|
len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
|
|
(void)memset(label + len, 0, sizeof(label) - len);
|
|
|
|
mod_id = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 4) {
|
|
cid = shell_strtoul(argv[4], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_sub_va_del_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, label,
|
|
mod_id, cid, &sub_addr, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_sub_va_del(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, label,
|
|
mod_id, &sub_addr, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model Subscription Delete (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model Subscription Delete failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "0x%04x unsubscribed from Label UUID %s (va 0x%04x)", elem_addr,
|
|
argv[2], sub_addr);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_sub_ow(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, sub_addr, mod_id, cid;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
sub_addr = shell_strtoul(argv[2], 0, &err);
|
|
mod_id = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 4) {
|
|
cid = shell_strtoul(argv[4], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_sub_overwrite_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr,
|
|
sub_addr, mod_id, cid, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_sub_overwrite(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr,
|
|
sub_addr, mod_id, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model Subscription Overwrite (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model Subscription Overwrite failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "Model subscription overwrite was successful");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_sub_ow_va(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, sub_addr, mod_id, cid;
|
|
uint8_t label[16];
|
|
uint8_t status;
|
|
size_t len;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
|
|
len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
|
|
(void)memset(label + len, 0, sizeof(label) - len);
|
|
|
|
mod_id = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 4) {
|
|
cid = shell_strtoul(argv[4], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_sub_va_overwrite_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr,
|
|
label, mod_id, cid, &sub_addr, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_sub_va_overwrite(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr,
|
|
label, mod_id, &sub_addr, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Mod Sub VA Overwrite (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Mod Sub VA Overwrite failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "0x%04x overwrite to Label UUID %s (va 0x%04x)", elem_addr, argv[2],
|
|
sub_addr);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_sub_del_all(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, mod_id, cid;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
mod_id = shell_strtoul(argv[2], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 3) {
|
|
cid = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_sub_del_all_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr,
|
|
mod_id, cid, &status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_sub_del_all(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
|
|
&status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model Subscription Delete All (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model Subscription Delete All failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh, "Model subscription deletion all was successful");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_sub_get(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint16_t elem_addr, mod_id, cid;
|
|
uint16_t subs[16];
|
|
uint8_t status;
|
|
size_t cnt;
|
|
int err = 0;
|
|
int i;
|
|
|
|
cnt = ARRAY_SIZE(subs);
|
|
elem_addr = shell_strtoul(argv[1], 0, &err);
|
|
mod_id = shell_strtoul(argv[2], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 3) {
|
|
cid = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_mod_sub_get_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
|
|
cid, &status, subs, &cnt);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_sub_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
|
|
&status, subs, &cnt);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send Model Subscription Get (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model Subscription Get failed with status 0x%02x", status);
|
|
} else {
|
|
shell_print(sh,
|
|
"Model Subscriptions for Element 0x%04x, Model 0x%04x %s:", elem_addr,
|
|
mod_id, argc > 3 ? argv[3] : "(SIG)");
|
|
|
|
if (!cnt) {
|
|
shell_print(sh, "\tNone.");
|
|
}
|
|
|
|
for (i = 0; i < cnt; i++) {
|
|
shell_print(sh, "\t0x%04x", subs[i]);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_krp(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
uint8_t status, phase;
|
|
uint16_t key_net_idx;
|
|
int err = 0;
|
|
|
|
key_net_idx = shell_strtoul(argv[1], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc < 3) {
|
|
err = bt_mesh_cfg_cli_krp_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, key_net_idx, &status,
|
|
&phase);
|
|
} else {
|
|
uint16_t trans = shell_strtoul(argv[2], 0, &err);
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_krp_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, key_net_idx, trans, &status,
|
|
&phase);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Unable to send key refresh phase Get/Set (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "Key refresh phase Get/Set with status 0x%02x and phase 0x%02x", status,
|
|
phase);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mod_pub_get(const struct shell *sh, uint16_t addr, uint16_t mod_id, uint16_t cid)
|
|
{
|
|
struct bt_mesh_cfg_cli_mod_pub pub;
|
|
uint8_t status;
|
|
int err;
|
|
|
|
if (cid == CID_NVAL) {
|
|
err = bt_mesh_cfg_cli_mod_pub_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, addr, mod_id, &pub,
|
|
&status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_pub_get_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, addr, mod_id, cid,
|
|
&pub, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Model Publication Get failed (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model Publication Get failed (status 0x%02x)", status);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh,
|
|
"Model Publication for Element 0x%04x, Model 0x%04x:\n"
|
|
"\tPublish Address: 0x%04x\n"
|
|
"\tAppKeyIndex: 0x%04x\n"
|
|
"\tCredential Flag: %u\n"
|
|
"\tPublishTTL: %u\n"
|
|
"\tPublishPeriod: 0x%02x\n"
|
|
"\tPublishRetransmitCount: %u\n"
|
|
"\tPublishRetransmitInterval: %ums",
|
|
addr, mod_id, pub.addr, pub.app_idx, pub.cred_flag, pub.ttl, pub.period,
|
|
BT_MESH_PUB_TRANSMIT_COUNT(pub.transmit),
|
|
BT_MESH_PUB_TRANSMIT_INT(pub.transmit));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mod_pub_set(const struct shell *sh, uint16_t addr, bool is_va, uint16_t mod_id,
|
|
uint16_t cid, char *argv[])
|
|
{
|
|
struct bt_mesh_cfg_cli_mod_pub pub;
|
|
uint8_t status, count, res_step, steps;
|
|
uint16_t interval;
|
|
uint8_t uuid[16];
|
|
uint8_t len;
|
|
int err = 0;
|
|
|
|
if (!is_va) {
|
|
pub.addr = shell_strtoul(argv[0], 0, &err);
|
|
pub.uuid = NULL;
|
|
} else {
|
|
len = hex2bin(argv[0], strlen(argv[0]), uuid, sizeof(uuid));
|
|
memset(uuid + len, 0, sizeof(uuid) - len);
|
|
pub.uuid = (const uint8_t *)&uuid;
|
|
}
|
|
|
|
pub.app_idx = shell_strtoul(argv[1], 0, &err);
|
|
pub.cred_flag = shell_strtobool(argv[2], 0, &err);
|
|
pub.ttl = shell_strtoul(argv[3], 0, &err);
|
|
res_step = shell_strtoul(argv[4], 0, &err);
|
|
steps = shell_strtoul(argv[5], 0, &err);
|
|
if ((res_step > 3) || (steps > 0x3F)) {
|
|
shell_print(sh, "Invalid period");
|
|
return -EINVAL;
|
|
}
|
|
|
|
pub.period = steps + (res_step << 6);
|
|
count = shell_strtoul(argv[6], 0, &err);
|
|
if (count > 7) {
|
|
shell_print(sh, "Invalid retransmit count");
|
|
return -EINVAL;
|
|
}
|
|
|
|
interval = shell_strtoul(argv[7], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (interval > (31 * 50) || (interval % 50)) {
|
|
shell_print(sh, "Invalid retransmit interval %u", interval);
|
|
return -EINVAL;
|
|
}
|
|
|
|
pub.transmit = BT_MESH_PUB_TRANSMIT(count, interval);
|
|
|
|
if (cid == CID_NVAL) {
|
|
err = bt_mesh_cfg_cli_mod_pub_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, addr, mod_id, &pub,
|
|
&status);
|
|
} else {
|
|
err = bt_mesh_cfg_cli_mod_pub_set_vnd(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, addr, mod_id, cid,
|
|
&pub, &status);
|
|
}
|
|
|
|
if (err) {
|
|
shell_error(sh, "Model Publication Set failed (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Model Publication Set failed (status 0x%02x)", status);
|
|
} else {
|
|
shell_print(sh, "Model Publication successfully set");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_mod_pub(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
int err = 0;
|
|
uint16_t addr, mod_id, cid;
|
|
|
|
addr = shell_strtoul(argv[1], 0, &err);
|
|
mod_id = shell_strtoul(argv[2], 0, &err);
|
|
|
|
argc -= 3;
|
|
argv += 3;
|
|
|
|
if (argc == 1 || argc == 9) {
|
|
cid = shell_strtoul(argv[0], 0, &err);
|
|
argc--;
|
|
argv++;
|
|
} else {
|
|
cid = CID_NVAL;
|
|
}
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
if (argc > 0) {
|
|
if (argc < 7) {
|
|
shell_warn(sh, "Invalid number of argument");
|
|
return -EINVAL;
|
|
}
|
|
|
|
return mod_pub_set(sh, addr, false, mod_id, cid, argv);
|
|
} else {
|
|
return mod_pub_get(sh, addr, mod_id, cid);
|
|
}
|
|
}
|
|
|
|
static int cmd_mod_pub_va(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
int err = 0;
|
|
uint16_t addr, mod_id, cid = CID_NVAL;
|
|
|
|
addr = shell_strtoul(argv[1], 0, &err);
|
|
mod_id = shell_strtoul(argv[9], 0, &err);
|
|
|
|
if (argc > 10) {
|
|
cid = shell_strtoul(argv[10], 0, &err);
|
|
}
|
|
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
argv += 2;
|
|
|
|
return mod_pub_set(sh, addr, true, mod_id, cid, argv);
|
|
}
|
|
|
|
static void hb_sub_print(const struct shell *sh, struct bt_mesh_cfg_cli_hb_sub *sub)
|
|
{
|
|
shell_print(sh,
|
|
"Heartbeat Subscription:\n"
|
|
"\tSource: 0x%04x\n"
|
|
"\tDestination: 0x%04x\n"
|
|
"\tPeriodLog: 0x%02x\n"
|
|
"\tCountLog: 0x%02x\n"
|
|
"\tMinHops: %u\n"
|
|
"\tMaxHops: %u",
|
|
sub->src, sub->dst, sub->period, sub->count, sub->min, sub->max);
|
|
}
|
|
|
|
static int hb_sub_get(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
struct bt_mesh_cfg_cli_hb_sub sub;
|
|
uint8_t status;
|
|
int err;
|
|
|
|
err = bt_mesh_cfg_cli_hb_sub_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &sub, &status);
|
|
if (err) {
|
|
shell_error(sh, "Heartbeat Subscription Get failed (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Heartbeat Subscription Get failed (status 0x%02x)", status);
|
|
} else {
|
|
hb_sub_print(sh, &sub);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int hb_sub_set(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
struct bt_mesh_cfg_cli_hb_sub sub;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
sub.src = shell_strtoul(argv[1], 0, &err);
|
|
sub.dst = shell_strtoul(argv[2], 0, &err);
|
|
sub.period = shell_strtoul(argv[3], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_hb_sub_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &sub, &status);
|
|
if (err) {
|
|
shell_error(sh, "Heartbeat Subscription Set failed (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Heartbeat Subscription Set failed (status 0x%02x)", status);
|
|
} else {
|
|
hb_sub_print(sh, &sub);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_hb_sub(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
if (argc > 1) {
|
|
if (argc < 4) {
|
|
shell_warn(sh, "Invalid number of argument");
|
|
return -EINVAL;
|
|
}
|
|
|
|
return hb_sub_set(sh, argc, argv);
|
|
} else {
|
|
return hb_sub_get(sh, argc, argv);
|
|
}
|
|
}
|
|
|
|
static int hb_pub_get(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
struct bt_mesh_cfg_cli_hb_pub pub;
|
|
uint8_t status;
|
|
int err;
|
|
|
|
err = bt_mesh_cfg_cli_hb_pub_get(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &pub, &status);
|
|
if (err) {
|
|
shell_error(sh, "Heartbeat Publication Get failed (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Heartbeat Publication Get failed (status 0x%02x)", status);
|
|
return 0;
|
|
}
|
|
|
|
shell_print(sh, "Heartbeat publication:");
|
|
shell_print(sh, "\tdst 0x%04x count 0x%02x period 0x%02x", pub.dst, pub.count, pub.period);
|
|
shell_print(sh, "\tttl 0x%02x feat 0x%04x net_idx 0x%04x", pub.ttl, pub.feat, pub.net_idx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int hb_pub_set(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
struct bt_mesh_cfg_cli_hb_pub pub;
|
|
uint8_t status;
|
|
int err = 0;
|
|
|
|
pub.dst = shell_strtoul(argv[1], 0, &err);
|
|
pub.count = shell_strtoul(argv[2], 0, &err);
|
|
pub.period = shell_strtoul(argv[3], 0, &err);
|
|
pub.ttl = shell_strtoul(argv[4], 0, &err);
|
|
pub.feat = shell_strtoul(argv[5], 0, &err);
|
|
pub.net_idx = shell_strtoul(argv[6], 0, &err);
|
|
if (err) {
|
|
shell_warn(sh, "Unable to parse input string argument");
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_cfg_cli_hb_pub_set(bt_mesh_shell_target_ctx.net_idx,
|
|
bt_mesh_shell_target_ctx.dst, &pub, &status);
|
|
if (err) {
|
|
shell_error(sh, "Heartbeat Publication Set failed (err %d)", err);
|
|
return 0;
|
|
}
|
|
|
|
if (status) {
|
|
shell_print(sh, "Heartbeat Publication Set failed (status 0x%02x)", status);
|
|
} else {
|
|
shell_print(sh, "Heartbeat publication successfully set");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_hb_pub(const struct shell *sh, size_t argc, char *argv[])
|
|
{
|
|
if (argc > 1) {
|
|
if (argc < 7) {
|
|
shell_warn(sh, "Invalid number of argument");
|
|
return -EINVAL;
|
|
}
|
|
|
|
return hb_pub_set(sh, argc, argv);
|
|
} else {
|
|
return hb_pub_get(sh, argc, argv);
|
|
}
|
|
}
|
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(model_cmds,
|
|
SHELL_CMD_ARG(app-bind, NULL, "<Addr> <AppKeyIdx> <MID> [CID]",
|
|
cmd_mod_app_bind, 4, 1),
|
|
SHELL_CMD_ARG(app-get, NULL, "<ElemAddr> <MID> [CID]", cmd_mod_app_get,
|
|
3, 1),
|
|
SHELL_CMD_ARG(app-unbind, NULL, "<Addr> <AppKeyIdx> <MID> [CID]",
|
|
cmd_mod_app_unbind, 4, 1),
|
|
SHELL_CMD_ARG(pub, NULL,
|
|
"<Addr> <MID> [CID] [<PubAddr> "
|
|
"<AppKeyIdx> <Cred(off, on)> <TTL> <PerRes> <PerSteps> <Count> "
|
|
"<Int(ms)>]",
|
|
cmd_mod_pub, 3, 1 + 8),
|
|
SHELL_CMD_ARG(pub-va, NULL,
|
|
"<Addr> <UUID(1-16 hex)> "
|
|
"<AppKeyIdx> <Cred(off, on)> <TTL> <PerRes> <PerSteps> <Count> "
|
|
"<Int(ms)> <MID> [CID]",
|
|
cmd_mod_pub_va, 11, 1),
|
|
SHELL_CMD_ARG(sub-add, NULL, "<ElemAddr> <SubAddr> <MID> [CID]",
|
|
cmd_mod_sub_add, 4, 1),
|
|
SHELL_CMD_ARG(sub-del, NULL, "<ElemAddr> <SubAddr> <MID> [CID]",
|
|
cmd_mod_sub_del, 4, 1),
|
|
SHELL_CMD_ARG(sub-add-va, NULL,
|
|
"<ElemAddr> <LabelUUID(1-16 hex)> <MID> [CID]", cmd_mod_sub_add_va, 4, 1),
|
|
SHELL_CMD_ARG(sub-del-va, NULL,
|
|
"<ElemAddr> <LabelUUID(1-16 hex)> <MID> [CID]", cmd_mod_sub_del_va, 4, 1),
|
|
SHELL_CMD_ARG(sub-ow, NULL, "<ElemAddr> <SubAddr> <MID> [CID]",
|
|
cmd_mod_sub_ow, 4, 1),
|
|
SHELL_CMD_ARG(sub-ow-va, NULL, "<ElemAddr> <LabelUUID(1-16 hex)> <MID> [CID]",
|
|
cmd_mod_sub_ow_va, 4, 1),
|
|
SHELL_CMD_ARG(sub-del-all, NULL, "<ElemAddr> <MID> [CID]",
|
|
cmd_mod_sub_del_all, 3, 1),
|
|
SHELL_CMD_ARG(sub-get, NULL, "<ElemAddr> <MID> [CID]", cmd_mod_sub_get,
|
|
3, 1),
|
|
SHELL_SUBCMD_SET_END);
|
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(netkey_cmds,
|
|
SHELL_CMD_ARG(add, NULL, "<NetKeyIdx> [Key(1-16 hex)]", cmd_net_key_add, 2, 1),
|
|
SHELL_CMD_ARG(upd, NULL, "<NetKeyIdx> [Key(1-16 hex)]", cmd_net_key_update, 2, 1),
|
|
SHELL_CMD_ARG(get, NULL, NULL, cmd_net_key_get, 1, 0),
|
|
SHELL_CMD_ARG(del, NULL, "<NetKeyIdx>", cmd_net_key_del, 2, 0),
|
|
SHELL_SUBCMD_SET_END);
|
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(appkey_cmds,
|
|
SHELL_CMD_ARG(add, NULL, "<NetKeyIdx> <AppKeyIdx> [Key(1-16 hex)]", cmd_app_key_add,
|
|
3, 1),
|
|
SHELL_CMD_ARG(upd, NULL, "<NetKeyIdx> <AppKeyIdx> [Key(1-16 hex)]", cmd_app_key_upd,
|
|
3, 1),
|
|
SHELL_CMD_ARG(del, NULL, "<NetKeyIdx> <AppKeyIdx>", cmd_app_key_del, 3, 0),
|
|
SHELL_CMD_ARG(get, NULL, "<NetKeyIdx>", cmd_app_key_get, 2, 0),
|
|
SHELL_SUBCMD_SET_END);
|
|
|
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(
|
|
cfg_cli_cmds,
|
|
/* Configuration Client Model operations */
|
|
SHELL_CMD_ARG(reset, NULL, NULL, cmd_reset, 1, 0),
|
|
SHELL_CMD_ARG(timeout, NULL, "[Timeout(s)]", cmd_timeout, 1, 1),
|
|
SHELL_CMD_ARG(get-comp, NULL, "[Page]", cmd_get_comp, 1, 1),
|
|
SHELL_CMD_ARG(beacon, NULL, "[Val(off, on)]", cmd_beacon, 1, 1),
|
|
SHELL_CMD_ARG(ttl, NULL, "[TTL]", cmd_ttl, 1, 1),
|
|
SHELL_CMD_ARG(friend, NULL, "[Val(off, on)]", cmd_friend, 1, 1),
|
|
SHELL_CMD_ARG(gatt-proxy, NULL, "[Val(off, on)]", cmd_gatt_proxy, 1, 1),
|
|
SHELL_CMD_ARG(relay, NULL, "[<Val(off, on)> [<Count> [Int(ms)]]]", cmd_relay,
|
|
1, 3),
|
|
SHELL_CMD_ARG(node-id, NULL, "<NetKeyIdx> [Identify]", cmd_node_id, 2, 1),
|
|
SHELL_CMD_ARG(polltimeout-get, NULL, "<LPNAddr>", cmd_polltimeout_get, 2, 0),
|
|
SHELL_CMD_ARG(net-transmit-param, NULL, "[<Count> <Int(ms)>]",
|
|
cmd_net_transmit, 1, 2),
|
|
SHELL_CMD_ARG(krp, NULL, "<NetKeyIdx> [Phase]", cmd_krp, 2, 1),
|
|
SHELL_CMD_ARG(hb-sub, NULL, "[<Src> <Dst> <Per>]", cmd_hb_sub, 1, 3),
|
|
SHELL_CMD_ARG(hb-pub, NULL, "[<Dst> <Count> <Per> <TTL> <Features> <NetKeyIdx>]",
|
|
cmd_hb_pub, 1, 6),
|
|
SHELL_CMD(appkey, &appkey_cmds, "Appkey config commands", bt_mesh_shell_mdl_cmds_help),
|
|
SHELL_CMD(netkey, &netkey_cmds, "Netkey config commands", bt_mesh_shell_mdl_cmds_help),
|
|
SHELL_CMD(model, &model_cmds, "Model config commands", bt_mesh_shell_mdl_cmds_help),
|
|
SHELL_SUBCMD_SET_END);
|
|
|
|
SHELL_SUBCMD_ADD((mesh, models), cfg, &cfg_cli_cmds, "Config Cli commands",
|
|
bt_mesh_shell_mdl_cmds_help, 1, 1);
|