From c9be68532c0d19a721b95dfdc2170c321c3f1cc6 Mon Sep 17 00:00:00 2001 From: YanBiao Hao Date: Wed, 23 Sep 2020 09:47:29 +0800 Subject: [PATCH] Bluetooth: Mesh: Add Config Client API The api is used to reset a node (other than a Provisioner) and remove it from the network Signed-off-by: YanBiao Hao --- doc/reference/bluetooth/mesh/shell.rst | 7 +-- include/bluetooth/mesh/cfg_cli.h | 10 +++++ subsys/bluetooth/mesh/cfg_cli.c | 59 ++++++++++++++++++++++++++ subsys/bluetooth/mesh/shell.c | 30 +++++++++++-- 4 files changed, 99 insertions(+), 7 deletions(-) diff --git a/doc/reference/bluetooth/mesh/shell.rst b/doc/reference/bluetooth/mesh/shell.rst index 073a24d61d4..69eae58fd64 100644 --- a/doc/reference/bluetooth/mesh/shell.rst +++ b/doc/reference/bluetooth/mesh/shell.rst @@ -128,10 +128,11 @@ General configuration Initialize the mesh. This command must be run before any other mesh command. -``mesh reset`` --------------- +``mesh reset `` +--------------------- - Reset the mesh node to its initial unprovisioned state. + reset the local mesh node to its initial unprovisioned state or reset a remote node and remove it from the network. + * ``addr``: address of the node to reset. ``mesh lpn `` diff --git a/include/bluetooth/mesh/cfg_cli.h b/include/bluetooth/mesh/cfg_cli.h index 99276ac54a5..8d61526a667 100644 --- a/include/bluetooth/mesh/cfg_cli.h +++ b/include/bluetooth/mesh/cfg_cli.h @@ -42,6 +42,16 @@ struct bt_mesh_cfg_cli { BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_CFG_CLI, bt_mesh_cfg_cli_op, NULL, \ cli_data, &bt_mesh_cfg_cli_cb) +/** @brief Reset the target node and remove it from the network. + * + * @param net_idx Network index to encrypt with. + * @param addr Target node address. + * @param status Status response parameter + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_cfg_node_reset(uint16_t net_idx, uint16_t addr, bool *status); + /** @brief Get the target node's composition data. * * @param net_idx Network index to encrypt with. diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index 11978655040..656b212f703 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -216,6 +216,26 @@ static void net_key_list(struct bt_mesh_model *model, k_sem_give(&cli->op_sync); } +static void node_reset_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) +{ + bool *param = NULL; + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x", + ctx->net_idx, ctx->app_idx, ctx->addr); + + if (cli->op_pending != OP_NODE_RESET_STATUS) { + BT_WARN("Unexpected Node Reset Status message"); + return; + } + + param = cli->op_param; + + if (param) { + *param = true; + } + k_sem_give(&cli->op_sync); +} + struct app_key_param { uint8_t *status; uint16_t net_idx; @@ -692,6 +712,7 @@ const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { { OP_MOD_SUB_LIST_VND, 7, mod_sub_list_vnd}, { OP_HEARTBEAT_SUB_STATUS, 9, hb_sub_status }, { OP_HEARTBEAT_PUB_STATUS, 10, hb_pub_status }, + { OP_NODE_RESET_STATUS, 0, node_reset_status}, BT_MESH_MODEL_OP_END, }; @@ -1140,6 +1161,44 @@ int bt_mesh_cfg_app_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_id return cli_wait(); } +int bt_mesh_cfg_node_reset(uint16_t net_idx, uint16_t addr, bool *status) +{ + BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET, 0); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + + int err; + + if (status) { + *status = false; + } + + err = cli_prepare(status, OP_NODE_RESET_STATUS); + if (err) { + return err; + } + + bt_mesh_model_msg_init(&msg, OP_NODE_RESET); + + err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + return err; + } + + if (!status) { + cli_reset(); + return 0; + } + + return cli_wait(); +} + int bt_mesh_cfg_app_key_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx, uint8_t *status, uint16_t *keys, size_t *key_cnt) { diff --git a/subsys/bluetooth/mesh/shell.c b/subsys/bluetooth/mesh/shell.c index e104b15c6f2..d15e5db09a1 100644 --- a/subsys/bluetooth/mesh/shell.c +++ b/subsys/bluetooth/mesh/shell.c @@ -429,8 +429,30 @@ static int cmd_uuid(const struct shell *shell, size_t argc, char *argv[]) static int cmd_reset(const struct shell *shell, size_t argc, char *argv[]) { - bt_mesh_reset(); - shell_print(shell, "Local node reset complete"); + uint16_t addr; + if (argc < 2) { + return -EINVAL; + } + + addr = strtoul(argv[1], NULL, 0); + + if (addr == net.local) { + bt_mesh_reset(); + shell_print(shell, "Local node reset complete"); + } else { + int err; + bool reset = false; + + err = bt_mesh_cfg_node_reset(net.net_idx, net.dst, &reset); + if (err) { + shell_error(shell, "Unable to send " + "Remote Node Reset (err %d)", err); + return 0; + } + + shell_print(shell, "Remote node reset complete"); + } + return 0; } @@ -2654,7 +2676,7 @@ static int cmd_cdb_app_key_del(const struct shell *shell, size_t argc, SHELL_STATIC_SUBCMD_SET_CREATE(mesh_cmds, /* General operations */ SHELL_CMD_ARG(init, NULL, NULL, cmd_init, 1, 0), - SHELL_CMD_ARG(reset, NULL, NULL, cmd_reset, 1, 0), + SHELL_CMD_ARG(reset, NULL, "", cmd_reset, 2, 0), #if defined(CONFIG_BT_MESH_LOW_POWER) SHELL_CMD_ARG(lpn, NULL, "", cmd_lpn, 2, 0), SHELL_CMD_ARG(poll, NULL, NULL, cmd_poll, 1, 0), @@ -2808,4 +2830,4 @@ static int cmd_mesh(const struct shell *shell, size_t argc, char **argv) } SHELL_CMD_ARG_REGISTER(mesh, &mesh_cmds, "Bluetooth Mesh shell commands", - cmd_mesh, 1, 1); + cmd_mesh, 1, 1);