Skip to content

Commit

Permalink
Bluetooth: Mesh: Add brg_cfg_cli commands to shell
Browse files Browse the repository at this point in the history
Adds the Bridge Configuration Client commands to Mesh shell.

Unifies documentation for shell Kconfig options.

Signed-off-by: Håvard Reierstad <haavard.reierstad@nordicsemi.no>
  • Loading branch information
HaavardRei authored and nashif committed Sep 17, 2024
1 parent d49068e commit 50a4c2d
Show file tree
Hide file tree
Showing 5 changed files with 334 additions and 3 deletions.
74 changes: 74 additions & 0 deletions doc/connectivity/bluetooth/api/mesh/shell.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,80 @@ a Config Composition Data Status message, and reading the metadata of the model
* ``Offset``: Offset within the page.


Bridge Configuration Client
---------------------------

The Bridge Configuration Client model is an optional Bluetooth Mesh model that can be enabled through the
:kconfig:option:`CONFIG_BT_MESH_BRG_CFG_CLI` configuration option. The model provides functionality
for configuring the subnet bridge functionality of a mesh node.

``mesh models brg_cfg bridge-get``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get the current Subnet Bridge state.

``mesh models brg_cfg bridge-set <State(disable, enable)>``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Set the Subnet Bridge state.

* ``State``: Disable or enable the Subnet Bridge functionality.

``mesh models brg_cfg table-size-get``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get the current size of the Bridging Table.

``mesh models brg_cfg table-add <Directions> <NetIdx1> <NetIdx2> <Addr1> <Addr2>``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Add an entry to the Bridging Table.

* ``Directions``: Allowed directions for the bridged traffic. Valid values are:

* ``0x01``: Bridging is allowed only for messages with ``Addr1`` as the source address and ``Addr2`` as the destination address.
* ``0x02``: Bridging is allowed in both directions.

* ``NetIdx1``: NetKey index of the first subnet.
* ``NetIdx2``: NetKey index of the second subnet.
* ``Addr1``: Address of the node in the first subnet.
* ``Addr2``: Address of the node in the second subnet.

``mesh models brg_cfg table-remove <NetIdx1> <NetIdx2> <Addr1> <Addr2>``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Remove an entry from the Bridging Table.

* ``NetIdx1``: NetKey index of the first subnet.
* ``NetIdx2``: NetKey index of the second subnet.
* ``Addr1``: Address of the node in the first subnet.
* ``Addr2``: Address of the node in the second subnet.

``mesh models brg_cfg subnets-get <Filter> <NetIdx> <StartIdx>``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get a filtered set of NetKey index pairs extracted from the Bridging Table.

* ``Filter``: Filter to be applied when reporting pairs of NetKey indexes extracted from the Bridging Table. Allowed values:

* ``0x00``: Report all pairs.
* ``0x01``: Report pairs in which the NetKey index of the first subnet matches ``NetIdx``.
* ``0x02``: Report pairs in which the NetKey index of the second subnet matches ``NetIdx``.
* ``0x03``: Report pairs in which one of the NetKey indexes matches ``NetIdx``.

* ``NetIdx``: NetKey index of any of the subnets.
* ``StartIdx``: Start offset in units of pairs of NetKey indexes to read.

``mesh models brg_cfg table-get <NetIdx1> <NetIdx2> <StartIdx>``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get a list of addresses and allowed traffic directions of the Bridging Table entries.

* ``NetIdx1``: NetKey index of the first subnet.
* ``NetIdx2``: NetKey index of the second subnet.
* ``StartIdx``: Start offset to read in units of Bridging Table state entries.


Configuration database
======================

Expand Down
2 changes: 2 additions & 0 deletions subsys/bluetooth/mesh/shell/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_SHELL_DFD_SRV dfd.c)
zephyr_library_sources_ifdef(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI od_priv_proxy.c)

zephyr_library_sources_ifdef(CONFIG_BT_MESH_SOL_PDU_RPL_CLI sol_pdu_rpl.c)

zephyr_library_sources_ifdef(CONFIG_BT_MESH_SHELL_BRG_CFG_CLI brg_cfg.c)
13 changes: 10 additions & 3 deletions subsys/bluetooth/mesh/shell/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ config BT_MESH_SHELL_TEST
This option enables support for test mesh shell commands.

config BT_MESH_SHELL_HEALTH_SRV_INSTANCE
bool "Support for shell Health Server model instance"
bool "Support for shell Health Server instance"
depends on BT_MESH_SHELL_TEST
help
This option enables Health Server model instance in the
Expand All @@ -67,14 +67,21 @@ config BT_MESH_SHELL_GATT_PROXY
This option enables support for GATT Proxy shell commands.

config BT_MESH_SHELL_HEALTH_CLI
bool "Support for Health Client Model shell commands"
bool "Support for Health Client shell commands"
depends on BT_MESH_HEALTH_CLI
default y
help
This option enables support of Health Client shell commands.

config BT_MESH_SHELL_BRG_CFG_CLI
bool "Support for Bridge Configuration Client shell commands"
depends on BT_MESH_BRG_CFG_CLI
default y
help
This option enables support of Bridge Configuration Client shell commands.

config BT_MESH_SHELL_CFG_CLI
bool "Support for Configuration Client Model shell commands"
bool "Support for Configuration Client shell commands"
depends on BT_MESH_CFG_CLI
default y
help
Expand Down
241 changes: 241 additions & 0 deletions subsys/bluetooth/mesh/shell/brg_cfg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdlib.h>
#include <zephyr/shell/shell.h>
#include <zephyr/bluetooth/mesh.h>
#include <zephyr/bluetooth/mesh/shell.h>

#include "mesh/foundation.h"
#include "utils.h"

static int cmd_subnet_bridge_get(const struct shell *sh, size_t argc, char *argv[])
{
enum bt_mesh_subnet_bridge_state rsp;
int err;

err = bt_mesh_brg_cfg_cli_subnet_bridge_get(bt_mesh_shell_target_ctx.net_idx,
bt_mesh_shell_target_ctx.dst, &rsp);
if (err) {
shell_error(sh, "Failed to send Subnet Bridge Get (err %d)", err);
return -ENOEXEC;
}

shell_print(sh, "Subnet Bridge State: %s",
(rsp == BT_MESH_SUBNET_BRIDGE_ENABLED) ? "Enabled" : "Disabled");
return 0;
}

static int cmd_subnet_bridge_set(const struct shell *sh, size_t argc, char *argv[])
{
enum bt_mesh_subnet_bridge_state set, rsp;
int err = 0;

set = shell_strtobool(argv[1], 0, &err) ? BT_MESH_SUBNET_BRIDGE_ENABLED :
BT_MESH_SUBNET_BRIDGE_DISABLED;

if (err) {
shell_warn(sh, "Unable to parse input string argument");
return err;
}

err = bt_mesh_brg_cfg_cli_subnet_bridge_set(bt_mesh_shell_target_ctx.net_idx,
bt_mesh_shell_target_ctx.dst, set, &rsp);
if (err) {
shell_error(sh, "Failed to send Subnet Bridge Set (err %d)", err);
return -ENOEXEC;
}

shell_print(sh, "Subnet Bridge State: %s",
(rsp == BT_MESH_SUBNET_BRIDGE_ENABLED) ? "Enabled" : "Disabled");
return 0;
}

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

err = bt_mesh_brg_cfg_cli_bridging_table_size_get(bt_mesh_shell_target_ctx.net_idx,
bt_mesh_shell_target_ctx.dst, &rsp);
if (err) {
shell_error(sh, "Failed to send Bridging Table Size Get (err %d)", err);
return -ENOEXEC;
}

shell_print(sh, "Bridging Table Size: %u", rsp);
return 0;
}

static int cmd_bridging_table_add(const struct shell *sh, size_t argc, char *argv[])
{
struct bt_mesh_bridging_table_entry entry;
struct bt_mesh_bridging_table_status rsp;
int err = 0;

entry.directions = shell_strtoul(argv[1], 0, &err);
entry.net_idx1 = shell_strtoul(argv[2], 0, &err);
entry.net_idx2 = shell_strtoul(argv[3], 0, &err);
entry.addr1 = shell_strtoul(argv[4], 0, &err);
entry.addr2 = shell_strtoul(argv[5], 0, &err);
if (err) {
shell_warn(sh, "Unable to parse input string argument");
return err;
}

err = bt_mesh_brg_cfg_cli_bridging_table_add(bt_mesh_shell_target_ctx.net_idx,
bt_mesh_shell_target_ctx.dst, &entry, &rsp);
if (err) {
shell_error(sh, "Failed to send Bridging Table Add (err %d)", err);
return -ENOEXEC;
}

if (rsp.status) {
shell_print(sh, "Bridging Table Add failed with status 0x%02x", rsp.status);
} else {
shell_print(sh, "Bridging Table Add was successful.");
}
return 0;
}

static int cmd_bridging_table_remove(const struct shell *sh, size_t argc, char *argv[])
{
uint16_t net_idx1, net_idx2, addr1, addr2;
struct bt_mesh_bridging_table_status rsp;
int err = 0;

net_idx1 = shell_strtoul(argv[1], 0, &err);
net_idx2 = shell_strtoul(argv[2], 0, &err);
addr1 = shell_strtoul(argv[3], 0, &err);
addr2 = shell_strtoul(argv[4], 0, &err);
if (err) {
shell_warn(sh, "Unable to parse input string argument");
return err;
}

err = bt_mesh_brg_cfg_cli_bridging_table_remove(bt_mesh_shell_target_ctx.net_idx,
bt_mesh_shell_target_ctx.dst, net_idx1,
net_idx2, addr1, addr2, &rsp);
if (err) {
shell_error(sh, "Failed to send Bridging Table Remove (err %d)", err);
return -ENOEXEC;
}

if (rsp.status) {
shell_print(sh, "Bridging Table Remove failed with status 0x%02x", rsp.status);
} else {
shell_print(sh, "Bridging Table Remove was successful.");
}
return 0;
}

static int cmd_bridged_subnets_get(const struct shell *sh, size_t argc, char *argv[])
{
struct bt_mesh_filter_netkey filter_net_idx;
uint8_t start_idx;
struct bt_mesh_bridged_subnets_list rsp;
int err = 0;

filter_net_idx.filter = shell_strtoul(argv[1], 0, &err);
filter_net_idx.net_idx = shell_strtoul(argv[2], 0, &err);
start_idx = shell_strtoul(argv[3], 0, &err);
if (err) {
shell_warn(sh, "Unable to parse input string argument");
return err;
}

err = bt_mesh_brg_cfg_cli_bridged_subnets_get(bt_mesh_shell_target_ctx.net_idx,
bt_mesh_shell_target_ctx.dst, filter_net_idx,
start_idx, &rsp);
if (err) {
shell_error(sh, "Failed to send Bridged Subnets Get (err %d)", err);
return -ENOEXEC;
}

shell_print(sh, "Bridged Subnets List:");
shell_print(sh, "\tfilter: %02x", rsp.net_idx_filter.filter);
shell_print(sh, "\tnet_idx: %04x", rsp.net_idx_filter.net_idx);
shell_print(sh, "\tstart_idx: %u", rsp.start_idx);
if (rsp.list) {
uint16_t net_idx1, net_idx2;
int i = 0;

while (rsp.list->len) {
key_idx_unpack_pair(rsp.list, &net_idx1, &net_idx2);
shell_print(sh, "\tEntry %d:", i++);
shell_print(sh, "\t\tnet_idx1: 0x%04x, net_idx2: 0x%04x", net_idx1,
net_idx2);
}
}
return 0;
}

static int cmd_bridging_table_get(const struct shell *sh, size_t argc, char *argv[])
{
uint16_t net_idx1, net_idx2, start_idx;
struct bt_mesh_bridging_table_list rsp;
int err = 0;

net_idx1 = shell_strtoul(argv[1], 0, &err);
net_idx2 = shell_strtoul(argv[2], 0, &err);
start_idx = shell_strtoul(argv[3], 0, &err);
if (err) {
shell_warn(sh, "Unable to parse input string argument");
return err;
}

err = bt_mesh_brg_cfg_cli_bridging_table_get(bt_mesh_shell_target_ctx.net_idx,
bt_mesh_shell_target_ctx.dst, net_idx1,
net_idx2, start_idx, &rsp);
if (err) {
shell_error(sh, "Failed to send Bridging Table Get (err %d)", err);
return -ENOEXEC;
}

if (rsp.status) {
shell_print(sh, "Bridging Table Get failed with status 0x%02x", rsp.status);
} else {
shell_print(sh, "Bridging Table List:");
shell_print(sh, "\tstatus: %02x", rsp.status);
shell_print(sh, "\tnet_idx1: %04x", rsp.net_idx1);
shell_print(sh, "\tnet_idx2: %04x", rsp.net_idx2);
shell_print(sh, "\tstart_idx: %u", rsp.start_idx);
if (rsp.list) {
uint16_t addr1, addr2;
uint8_t directions;
int i = 0;

while (rsp.list->len) {
addr1 = net_buf_simple_pull_le16(rsp.list);
addr2 = net_buf_simple_pull_le16(rsp.list);
directions = net_buf_simple_pull_u8(rsp.list);
shell_print(sh, "\tEntry %d:", i++);
shell_print(sh,
"\t\taddr1: 0x%04x, addr2: 0x%04x, directions: 0x%02x",
addr1, addr2, directions);
}
}
}
return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(
brg_cfg_cmds,
SHELL_CMD_ARG(bridge-get, NULL, NULL, cmd_subnet_bridge_get, 1, 0),
SHELL_CMD_ARG(bridge-set, NULL, "<State(disable, enable)>", cmd_subnet_bridge_set, 2, 0),
SHELL_CMD_ARG(table-size-get, NULL, NULL, cmd_bridging_table_size_get, 1, 0),
SHELL_CMD_ARG(table-add, NULL, "<Directions> <NetIdx1> <NetIdx2> <Addr1> <Addr2>",
cmd_bridging_table_add, 6, 0),
SHELL_CMD_ARG(table-remove, NULL, "<NetIdx1> <NetIdx2> <Addr1> <Addr2>",
cmd_bridging_table_remove, 5, 0),
SHELL_CMD_ARG(subnets-get, NULL, "<Filter> <NetIdx> <StartIdx>", cmd_bridged_subnets_get,
4, 0),
SHELL_CMD_ARG(table-get, NULL, "<NetIdx1> <NetIdx2> <StartIdx>", cmd_bridging_table_get,
4, 0),
SHELL_SUBCMD_SET_END);

SHELL_SUBCMD_ADD((mesh, models), brg, &brg_cfg_cmds, "Bridge Configuration Cli commands",
bt_mesh_shell_mdl_cmds_help, 1, 1);
7 changes: 7 additions & 0 deletions tests/bluetooth/mesh_shell/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ static struct bt_mesh_od_priv_proxy_cli od_priv_proxy_cli;
struct bt_mesh_large_comp_data_cli large_comp_data_cli;
#endif

#if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
static struct bt_mesh_brg_cfg_cli brg_cfg_cli;
#endif

BT_MESH_SHELL_HEALTH_PUB_DEFINE(health_pub);

static const struct bt_mesh_model root_models[] = {
Expand Down Expand Up @@ -106,6 +110,9 @@ static const struct bt_mesh_model root_models[] = {
#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
BT_MESH_MODEL_OD_PRIV_PROXY_SRV,
#endif
#if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
BT_MESH_MODEL_BRG_CFG_CLI(&brg_cfg_cli),
#endif
};

static const struct bt_mesh_elem elements[] = {
Expand Down

0 comments on commit 50a4c2d

Please sign in to comment.