Bluetooth: Mesh: Moved composition data out of mesh shell

The mesh shell module owns the composition data for the shell
application, which makes it impossible to use it outside of the
application itself. To support the shell as a generic debugging
component that can be added to any application, we have moved the
composition data out of shell.c, and into the application.

Signed-off-by: Ingar Kulbrandstad <ingar.kulbrandstad@nordicsemi.no>
This commit is contained in:
Ingar Kulbrandstad 2021-05-14 10:37:32 +02:00 committed by Christopher Friedt
commit 59d5ef1e24
5 changed files with 227 additions and 121 deletions

View file

@ -11,7 +11,7 @@ The Bluetooth mesh shell interface provides access to most Bluetooth mesh featur
Prerequisites Prerequisites
************* *************
The Bluetooth mesh shell subsystem depends on the :ref:`bluetooth_mesh_models_cfg_cli` and :ref:`bluetooth_mesh_models_health_cli` models. The Bluetooth mesh shell subsystem depends on the application to create the composition data and do the mesh initialization.
Application Application
*********** ***********
@ -125,7 +125,7 @@ General configuration
``mesh init`` ``mesh init``
------------- -------------
Initialize the mesh. This command must be run before any other mesh command. Initialize the mesh shell. This command must be run before any other mesh command.
``mesh reset <addr>`` ``mesh reset <addr>``
@ -298,7 +298,7 @@ Provisioning
Configuration Client model Configuration Client model
========================== ==========================
The Bluetooth mesh shell module instantiates a Configuration Client model for configuring itself and other nodes in the mesh network. The Configuration Client model is an optional mesh subsystem that can be enabled through the :kconfig:`CONFIG_BT_MESH_CFG_CLI` configuration option. If included, the Bluetooth mesh shell module instantiates a Configuration Client model for configuring itself and other nodes in the mesh network.
The Configuration Client uses the general messages parameters set by ``mesh dst`` and ``mesh netidx`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, the Configuration Client model targets itself by default. When another node has been provisioned by the Bluetooth mesh shell, the Configuration Client model targets the new node. The Configuration Client always sends messages using the Device key bound to the destination address, so it will only be able to configure itself and mesh nodes it provisioned. The Configuration Client uses the general messages parameters set by ``mesh dst`` and ``mesh netidx`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, the Configuration Client model targets itself by default. When another node has been provisioned by the Bluetooth mesh shell, the Configuration Client model targets the new node. The Configuration Client always sends messages using the Device key bound to the destination address, so it will only be able to configure itself and mesh nodes it provisioned.
@ -583,7 +583,7 @@ The Configuration Client uses the general messages parameters set by ``mesh dst`
Health Client model Health Client model
=================== ===================
The Bluetooth mesh shell module instantiates a Health Client model for configuring itself and other nodes in the mesh network. The Health Client model is an optional mesh subsystem that can be enabled through the :kconfig:`CONFIG_BT_MESH_HEALTH_CLI` configuration option. If included, the Bluetooth mesh shell module instantiates a Health Client model for configuring itself and other nodes in the mesh network.
The Health Client uses the general messages parameters set by ``mesh dst`` and ``mesh netidx`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, the Health Client model targets itself by default. When another node has been provisioned by the Bluetooth mesh shell, the Health Client model targets the new node. The Health Client always sends messages using the Device key bound to the destination address, so it will only be able to configure itself and mesh nodes it provisioned. The Health Client uses the general messages parameters set by ``mesh dst`` and ``mesh netidx`` to target specific nodes. When the Bluetooth mesh shell node is provisioned, the Health Client model targets itself by default. When another node has been provisioned by the Bluetooth mesh shell, the Health Client model targets the new node. The Health Client always sends messages using the Device key bound to the destination address, so it will only be able to configure itself and mesh nodes it provisioned.

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_SHELL_H_
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_SHELL_H_
#include <bluetooth/mesh.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Maximum number of faults the health server can have. */
#define BT_MESH_SHELL_CUR_FAULTS_MAX 4
/** @def BT_MESH_SHELL_HEALTH_PUB_DEFINE
*
* A helper to define a health publication context for shell with the shell's
* maximum number of faults the element can have.
*
* @param _name Name given to the publication context variable.
*/
#define BT_MESH_SHELL_HEALTH_PUB_DEFINE(_name) \
BT_MESH_HEALTH_PUB_DEFINE(_name, \
BT_MESH_SHELL_CUR_FAULTS_MAX);
/** @brief External reference to health server */
extern struct bt_mesh_health_srv bt_mesh_shell_health_srv;
/** @brief External reference to health client */
extern struct bt_mesh_health_cli bt_mesh_shell_health_cli;
/** @brief External reference to provisioning handler. */
extern struct bt_mesh_prov bt_mesh_shell_prov;
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_SHELL_H_ */

View file

@ -717,8 +717,6 @@ config BT_MESH_HEALTH_CLI
config BT_MESH_SHELL config BT_MESH_SHELL
bool "Enable Bluetooth mesh shell" bool "Enable Bluetooth mesh shell"
select SHELL select SHELL
depends on BT_MESH_CFG_CLI
depends on BT_MESH_HEALTH_CLI
help help
Activate shell module that provides Bluetooth mesh commands to Activate shell module that provides Bluetooth mesh commands to
the console. the console.

View file

@ -15,6 +15,7 @@
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
#include <bluetooth/mesh.h> #include <bluetooth/mesh.h>
#include <bluetooth/mesh/shell.h>
/* Private includes for raw Network & Transport layer access */ /* Private includes for raw Network & Transport layer access */
#include "mesh.h" #include "mesh.h"
@ -23,11 +24,19 @@
#include "transport.h" #include "transport.h"
#include "foundation.h" #include "foundation.h"
#include "settings.h" #include "settings.h"
#include "access.h"
#define CID_NVAL 0xffff #define CID_NVAL 0xffff
static const struct shell *ctx_shell; static const struct shell *ctx_shell;
#define shell_print_ctx(_ft, ...) \
do { \
if (ctx_shell != NULL) { \
shell_print(ctx_shell, _ft, ##__VA_ARGS__); \
} \
} while (0)
/* Default net, app & dev key values, unless otherwise specified */ /* Default net, app & dev key values, unless otherwise specified */
static const uint8_t default_key[16] = { static const uint8_t default_key[16] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
@ -44,10 +53,8 @@ static struct {
.dst = BT_MESH_ADDR_UNASSIGNED, .dst = BT_MESH_ADDR_UNASSIGNED,
}; };
#define CUR_FAULTS_MAX 4 static uint8_t cur_faults[BT_MESH_SHELL_CUR_FAULTS_MAX];
static uint8_t reg_faults[BT_MESH_SHELL_CUR_FAULTS_MAX * 2];
static uint8_t cur_faults[CUR_FAULTS_MAX];
static uint8_t reg_faults[CUR_FAULTS_MAX * 2];
static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count) static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count)
{ {
@ -64,7 +71,7 @@ static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8
static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id,
uint16_t *company_id, uint8_t *faults, uint8_t *fault_count) uint16_t *company_id, uint8_t *faults, uint8_t *fault_count)
{ {
shell_print(ctx_shell, "Sending current faults"); shell_print_ctx("Sending current faults");
*test_id = 0x00; *test_id = 0x00;
*company_id = BT_COMP_ID_LF; *company_id = BT_COMP_ID_LF;
@ -77,13 +84,13 @@ static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id,
static int fault_get_reg(struct bt_mesh_model *model, uint16_t cid, static int fault_get_reg(struct bt_mesh_model *model, uint16_t cid,
uint8_t *test_id, uint8_t *faults, uint8_t *fault_count) uint8_t *test_id, uint8_t *faults, uint8_t *fault_count)
{ {
if (cid != BT_COMP_ID_LF) { if (cid != CONFIG_BT_COMPANY_ID) {
shell_print(ctx_shell, "Faults requested for unknown Company ID" shell_print_ctx("Faults requested for unknown Company ID"
" 0x%04x", cid); " 0x%04x", cid);
return -EINVAL; return -EINVAL;
} }
shell_print(ctx_shell, "Sending registered faults"); shell_print_ctx("Sending registered faults");
*test_id = 0x00; *test_id = 0x00;
@ -94,7 +101,7 @@ static int fault_get_reg(struct bt_mesh_model *model, uint16_t cid,
static int fault_clear(struct bt_mesh_model *model, uint16_t cid) static int fault_clear(struct bt_mesh_model *model, uint16_t cid)
{ {
if (cid != BT_COMP_ID_LF) { if (cid != CONFIG_BT_COMPANY_ID) {
return -EINVAL; return -EINVAL;
} }
@ -106,7 +113,7 @@ static int fault_clear(struct bt_mesh_model *model, uint16_t cid)
static int fault_test(struct bt_mesh_model *model, uint8_t test_id, static int fault_test(struct bt_mesh_model *model, uint8_t test_id,
uint16_t cid) uint16_t cid)
{ {
if (cid != BT_COMP_ID_LF) { if (cid != CONFIG_BT_COMPANY_ID) {
return -EINVAL; return -EINVAL;
} }
@ -124,30 +131,26 @@ static const struct bt_mesh_health_srv_cb health_srv_cb = {
.fault_test = fault_test, .fault_test = fault_test,
}; };
static struct bt_mesh_health_srv health_srv = { struct bt_mesh_health_srv bt_mesh_shell_health_srv = {
.cb = &health_srv_cb, .cb = &health_srv_cb,
}; };
BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX); #if defined(CONFIG_BT_MESH_HEALTH_CLI)
static struct bt_mesh_cfg_cli cfg_cli = {
};
static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count)
{ {
size_t i; size_t i;
if (!fault_count) { if (!fault_count) {
shell_print(ctx_shell, "Health Test ID 0x%02x Company ID " shell_print_ctx("Health Test ID 0x%02x Company ID "
"0x%04x: no faults", test_id, cid); "0x%04x: no faults", test_id, cid);
return; return;
} }
shell_print(ctx_shell, "Health Test ID 0x%02x Company ID 0x%04x Fault " shell_print_ctx("Health Test ID 0x%02x Company ID 0x%04x Fault "
"Count %zu:", test_id, cid, fault_count); "Count %zu:", test_id, cid, fault_count);
for (i = 0; i < fault_count; i++) { for (i = 0; i < fault_count; i++) {
shell_print(ctx_shell, "\t0x%02x", faults[i]); shell_print_ctx("\t0x%02x", faults[i]);
} }
} }
@ -155,37 +158,21 @@ static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr,
uint8_t test_id, uint16_t cid, uint8_t *faults, uint8_t test_id, uint16_t cid, uint8_t *faults,
size_t fault_count) size_t fault_count)
{ {
shell_print(ctx_shell, "Health Current Status from 0x%04x", addr); shell_print_ctx("Health Current Status from 0x%04x", addr);
show_faults(test_id, cid, faults, fault_count); show_faults(test_id, cid, faults, fault_count);
} }
static struct bt_mesh_health_cli health_cli = { struct bt_mesh_health_cli bt_mesh_shell_health_cli = {
.current_status = health_current_status, .current_status = health_current_status,
}; };
#endif /* CONFIG_BT_MESH_HEALTH_CLI */
static uint8_t dev_uuid[16] = { 0xdd, 0xdd }; static uint8_t dev_uuid[16] = { 0xdd, 0xdd };
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
BT_MESH_MODEL_HEALTH_CLI(&health_cli),
};
static struct bt_mesh_elem elements[] = {
BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE),
};
static const struct bt_mesh_comp comp = {
.cid = BT_COMP_ID_LF,
.elem = elements,
.elem_count = ARRAY_SIZE(elements),
};
static void prov_complete(uint16_t net_idx, uint16_t addr) static void prov_complete(uint16_t net_idx, uint16_t addr)
{ {
shell_print(ctx_shell, "Local node provisioned, net_idx 0x%04x address " shell_print_ctx("Local node provisioned, net_idx 0x%04x address "
"0x%04x", net_idx, addr); "0x%04x", net_idx, addr);
net.local = addr; net.local = addr;
@ -196,7 +183,7 @@ static void prov_complete(uint16_t net_idx, uint16_t addr)
static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr, static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr,
uint8_t num_elem) uint8_t num_elem)
{ {
shell_print(ctx_shell, "Node provisioned, net_idx 0x%04x address " shell_print_ctx("Node provisioned, net_idx 0x%04x address "
"0x%04x elements %d", net_idx, addr, num_elem); "0x%04x elements %d", net_idx, addr, num_elem);
net.net_idx = net_idx, net.net_idx = net_idx,
@ -205,24 +192,24 @@ static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr,
static void prov_input_complete(void) static void prov_input_complete(void)
{ {
shell_print(ctx_shell, "Input complete"); shell_print_ctx("Input complete");
} }
static void prov_reset(void) static void prov_reset(void)
{ {
shell_print(ctx_shell, "The local node has been reset and needs " shell_print_ctx("The local node has been reset and needs "
"reprovisioning"); "reprovisioning");
} }
static int output_number(bt_mesh_output_action_t action, uint32_t number) static int output_number(bt_mesh_output_action_t action, uint32_t number)
{ {
shell_print(ctx_shell, "OOB Number: %u", number); shell_print_ctx("OOB Number: %u", number);
return 0; return 0;
} }
static int output_string(const char *str) static int output_string(const char *str)
{ {
shell_print(ctx_shell, "OOB String: %s", str); shell_print_ctx("OOB String: %s", str);
return 0; return 0;
} }
@ -289,18 +276,21 @@ static int cmd_input_str(const struct shell *shell, size_t argc, char *argv[])
static int input(bt_mesh_input_action_t act, uint8_t size) static int input(bt_mesh_input_action_t act, uint8_t size)
{ {
switch (act) { switch (act) {
case BT_MESH_ENTER_NUMBER: case BT_MESH_ENTER_NUMBER:
shell_print(ctx_shell, "Enter a number (max %u digits) with: " shell_print_ctx("Enter a number (max %u digits) with: "
"input-num <num>", size); "input-num <num>", size);
break; break;
case BT_MESH_ENTER_STRING: case BT_MESH_ENTER_STRING:
shell_print(ctx_shell, "Enter a string (max %u chars) with: " shell_print_ctx("Enter a string (max %u chars) with: "
"input-str <str>", size); "input-str <str>", size);
break; break;
default: default:
if (ctx_shell != NULL) {
shell_error(ctx_shell, "Unknown input action %u (size %u) " shell_error(ctx_shell, "Unknown input action %u (size %u) "
"requested!", act, size); "requested!", act, size);
}
return -EINVAL; return -EINVAL;
} }
@ -323,19 +313,17 @@ static const char *bearer2str(bt_mesh_prov_bearer_t bearer)
static void link_open(bt_mesh_prov_bearer_t bearer) static void link_open(bt_mesh_prov_bearer_t bearer)
{ {
shell_print(ctx_shell, "Provisioning link opened on %s", shell_print_ctx("Provisioning link opened on %s", bearer2str(bearer));
bearer2str(bearer));
} }
static void link_close(bt_mesh_prov_bearer_t bearer) static void link_close(bt_mesh_prov_bearer_t bearer)
{ {
shell_print(ctx_shell, "Provisioning link closed on %s", shell_print_ctx("Provisioning link closed on %s", bearer2str(bearer));
bearer2str(bearer));
} }
static uint8_t static_val[16]; static uint8_t static_val[16];
static struct bt_mesh_prov prov = { struct bt_mesh_prov bt_mesh_shell_prov = {
.uuid = dev_uuid, .uuid = dev_uuid,
.link_open = link_open, .link_open = link_open,
.link_close = link_close, .link_close = link_close,
@ -357,21 +345,21 @@ static struct bt_mesh_prov prov = {
static int cmd_static_oob(const struct shell *shell, size_t argc, char *argv[]) static int cmd_static_oob(const struct shell *shell, size_t argc, char *argv[])
{ {
if (argc < 2) { if (argc < 2) {
prov.static_val = NULL; bt_mesh_shell_prov.static_val = NULL;
prov.static_val_len = 0U; bt_mesh_shell_prov.static_val_len = 0U;
} else { } else {
prov.static_val_len = hex2bin(argv[1], strlen(argv[1]), bt_mesh_shell_prov.static_val_len = hex2bin(argv[1], strlen(argv[1]),
static_val, 16); static_val, 16);
if (prov.static_val_len) { if (bt_mesh_shell_prov.static_val_len) {
prov.static_val = static_val; bt_mesh_shell_prov.static_val = static_val;
} else { } else {
prov.static_val = NULL; bt_mesh_shell_prov.static_val = NULL;
} }
} }
if (prov.static_val) { if (bt_mesh_shell_prov.static_val) {
shell_print(shell, "Static OOB value set (length %u)", shell_print(shell, "Static OOB value set (length %u)",
prov.static_val_len); bt_mesh_shell_prov.static_val_len);
} else { } else {
shell_print(shell, "Static OOB value cleared"); shell_print(shell, "Static OOB value cleared");
} }
@ -401,6 +389,15 @@ static int cmd_uuid(const struct shell *shell, size_t argc, char *argv[])
return 0; return 0;
} }
static int cmd_init(const struct shell *sh, size_t argc, char *argv[])
{
ctx_shell = sh;
shell_print(sh, "Mesh shell initialized");
return 0;
}
static int cmd_reset(const struct shell *shell, size_t argc, char *argv[]) static int cmd_reset(const struct shell *shell, size_t argc, char *argv[])
{ {
uint16_t addr; uint16_t addr;
@ -413,7 +410,7 @@ static int cmd_reset(const struct shell *shell, size_t argc, char *argv[])
if (addr == net.local) { if (addr == net.local) {
bt_mesh_reset(); bt_mesh_reset();
shell_print(shell, "Local node reset complete"); shell_print(shell, "Local node reset complete");
} else { } else if (IS_ENABLED(CONFIG_BT_MESH_CFG_CLI)) {
int err; int err;
bool reset = false; bool reset = false;
@ -499,14 +496,14 @@ static int cmd_poll(const struct shell *shell, size_t argc, char *argv[])
static void lpn_established(uint16_t net_idx, uint16_t friend_addr, static void lpn_established(uint16_t net_idx, uint16_t friend_addr,
uint8_t queue_size, uint8_t recv_win) uint8_t queue_size, uint8_t recv_win)
{ {
shell_print(ctx_shell, "Friendship (as LPN) established to " shell_print_ctx("Friendship (as LPN) established to "
"Friend 0x%04x Queue Size %d Receive Window %d", "Friend 0x%04x Queue Size %d Receive Window %d",
friend_addr, queue_size, recv_win); friend_addr, queue_size, recv_win);
} }
static void lpn_terminated(uint16_t net_idx, uint16_t friend_addr) static void lpn_terminated(uint16_t net_idx, uint16_t friend_addr)
{ {
shell_print(ctx_shell, "Friendship (as LPN) lost with Friend " shell_print_ctx("Friendship (as LPN) lost with Friend "
"0x%04x", friend_addr); "0x%04x", friend_addr);
} }
@ -517,41 +514,6 @@ BT_MESH_LPN_CB_DEFINE(lpn_cb) = {
#endif /* MESH_LOW_POWER */ #endif /* MESH_LOW_POWER */
static int cmd_init(const struct shell *shell, size_t argc, char *argv[])
{
int err;
err = bt_enable(NULL);
if (err && err != -EALREADY) {
shell_error(shell, "Bluetooth init failed (err %d)", err);
return 0;
} else if (!err) {
shell_print(shell, "Bluetooth initialized");
}
err = bt_mesh_init(&prov, &comp);
if (err) {
shell_error(shell, "Mesh initialization failed (err %d)", err);
}
shell_print(shell, "Mesh initialized");
ctx_shell = shell;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
settings_load();
}
if (bt_mesh_is_provisioned()) {
shell_print(shell, "Mesh network restored from flash");
} else {
shell_print(shell, "Use \"pb-adv on\" or \"pb-gatt on\" to "
"enable advertising");
}
return 0;
}
#if defined(CONFIG_BT_MESH_GATT_PROXY) #if defined(CONFIG_BT_MESH_GATT_PROXY)
static int cmd_ident(const struct shell *shell, size_t argc, char *argv[]) static int cmd_ident(const struct shell *shell, size_t argc, char *argv[])
{ {
@ -567,6 +529,7 @@ static int cmd_ident(const struct shell *shell, size_t argc, char *argv[])
} }
#endif /* MESH_GATT_PROXY */ #endif /* MESH_GATT_PROXY */
#if defined(CONFIG_BT_MESH_CFG_CLI)
static int cmd_get_comp(const struct shell *shell, size_t argc, char *argv[]) static int cmd_get_comp(const struct shell *shell, size_t argc, char *argv[])
{ {
NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_RX_SDU_MAX); NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_RX_SDU_MAX);
@ -644,6 +607,7 @@ static int cmd_get_comp(const struct shell *shell, size_t argc, char *argv[])
return 0; return 0;
} }
#endif /* CONFIG_BT_MESH_CFG_CLI */
static int cmd_dst(const struct shell *shell, size_t argc, char *argv[]) static int cmd_dst(const struct shell *shell, size_t argc, char *argv[])
{ {
@ -764,6 +728,7 @@ static int cmd_rpl_clear(const struct shell *shell, size_t argc, char *argv[])
return 0; return 0;
} }
#if defined(CONFIG_BT_MESH_CFG_CLI)
static int cmd_beacon(const struct shell *shell, size_t argc, char *argv[]) static int cmd_beacon(const struct shell *shell, size_t argc, char *argv[])
{ {
uint8_t status; uint8_t status;
@ -788,6 +753,7 @@ static int cmd_beacon(const struct shell *shell, size_t argc, char *argv[])
return 0; return 0;
} }
#endif /* CONFIG_BT_MESH_CFG_CLI */
static void print_unprovisioned_beacon(uint8_t uuid[16], static void print_unprovisioned_beacon(uint8_t uuid[16],
bt_mesh_prov_oob_info_t oob_info, bt_mesh_prov_oob_info_t oob_info,
@ -797,7 +763,7 @@ static void print_unprovisioned_beacon(uint8_t uuid[16],
bin2hex(uuid, 16, uuid_hex_str, sizeof(uuid_hex_str)); bin2hex(uuid, 16, uuid_hex_str, sizeof(uuid_hex_str));
shell_print(ctx_shell, "UUID %s, OOB Info 0x%04x, URI Hash 0x%x", shell_print_ctx("UUID %s, OOB Info 0x%04x, URI Hash 0x%x",
uuid_hex_str, oob_info, uuid_hex_str, oob_info,
(uri_hash == NULL ? 0 : *uri_hash)); (uri_hash == NULL ? 0 : *uri_hash));
} }
@ -808,14 +774,15 @@ static int cmd_beacon_listen(const struct shell *shell, size_t argc,
uint8_t val = str2u8(argv[1]); uint8_t val = str2u8(argv[1]);
if (val) { if (val) {
prov.unprovisioned_beacon = print_unprovisioned_beacon; bt_mesh_shell_prov.unprovisioned_beacon = print_unprovisioned_beacon;
} else { } else {
prov.unprovisioned_beacon = NULL; bt_mesh_shell_prov.unprovisioned_beacon = NULL;
} }
return 0; return 0;
} }
#if defined(CONFIG_BT_MESH_CFG_CLI)
static int cmd_ttl(const struct shell *shell, size_t argc, char *argv[]) static int cmd_ttl(const struct shell *shell, size_t argc, char *argv[])
{ {
uint8_t ttl; uint8_t ttl;
@ -1862,6 +1829,7 @@ static int cmd_hb_pub(const struct shell *shell, size_t argc, char *argv[])
return hb_pub_get(shell, argc, argv); return hb_pub_get(shell, argc, argv);
} }
} }
#endif /* CONFIG_BT_MESH_CFG_CLI */
#if defined(CONFIG_BT_MESH_PROV_DEVICE) #if defined(CONFIG_BT_MESH_PROV_DEVICE)
static int cmd_pb(bt_mesh_prov_bearer_t bearer, const struct shell *shell, static int cmd_pb(bt_mesh_prov_bearer_t bearer, const struct shell *shell,
@ -1979,6 +1947,7 @@ static int cmd_provision(const struct shell *shell, size_t argc, char *argv[])
return 0; return 0;
} }
#if defined(CONFIG_BT_MESH_CFG_CLI)
int cmd_timeout(const struct shell *shell, size_t argc, char *argv[]) int cmd_timeout(const struct shell *shell, size_t argc, char *argv[])
{ {
int32_t timeout_ms; int32_t timeout_ms;
@ -2006,7 +1975,9 @@ int cmd_timeout(const struct shell *shell, size_t argc, char *argv[])
return 0; return 0;
} }
#endif /* CONFIG_BT_MESH_CFG_CLI */
#if defined(CONFIG_BT_MESH_HEALTH_CLI)
static int cmd_fault_get(const struct shell *shell, size_t argc, char *argv[]) static int cmd_fault_get(const struct shell *shell, size_t argc, char *argv[])
{ {
uint8_t faults[32]; uint8_t faults[32];
@ -2257,11 +2228,30 @@ static int cmd_attention_set_unack(const struct shell *shell, size_t argc,
return 0; return 0;
} }
#endif /* CONFIG_BT_MESH_HEALTH_CLI */
static struct bt_mesh_elem *primary_element(void)
{
const struct bt_mesh_comp *comp = bt_mesh_comp_get();
if (comp) {
return &comp->elem[0];
}
return NULL;
}
static int cmd_add_fault(const struct shell *shell, size_t argc, char *argv[]) static int cmd_add_fault(const struct shell *shell, size_t argc, char *argv[])
{ {
uint8_t fault_id; uint8_t fault_id;
uint8_t i; uint8_t i;
struct bt_mesh_elem *elem;
elem = primary_element();
if (elem == NULL) {
shell_print(shell, "Element not found!");
return -EINVAL;
}
if (argc < 2) { if (argc < 2) {
return -EINVAL; return -EINVAL;
@ -2297,7 +2287,7 @@ static int cmd_add_fault(const struct shell *shell, size_t argc, char *argv[])
shell_print(shell, "No space to store more registered faults"); shell_print(shell, "No space to store more registered faults");
} }
bt_mesh_fault_update(&elements[0]); bt_mesh_fault_update(elem);
return 0; return 0;
} }
@ -2306,11 +2296,18 @@ static int cmd_del_fault(const struct shell *shell, size_t argc, char *argv[])
{ {
uint8_t fault_id; uint8_t fault_id;
uint8_t i; uint8_t i;
struct bt_mesh_elem *elem;
elem = primary_element();
if (elem == NULL) {
shell_print(shell, "Element not found!");
return -EINVAL;
}
if (argc < 2) { if (argc < 2) {
(void)memset(cur_faults, 0, sizeof(cur_faults)); (void)memset(cur_faults, 0, sizeof(cur_faults));
shell_print(shell, "All current faults cleared"); shell_print(shell, "All current faults cleared");
bt_mesh_fault_update(&elements[0]); bt_mesh_fault_update(elem);
return 0; return 0;
} }
@ -2327,7 +2324,7 @@ static int cmd_del_fault(const struct shell *shell, size_t argc, char *argv[])
} }
} }
bt_mesh_fault_update(&elements[0]); bt_mesh_fault_update(elem);
return 0; return 0;
} }
@ -2691,6 +2688,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(mesh_cmds,
SHELL_CMD_ARG(beacon-listen, NULL, "<val: off, on>", cmd_beacon_listen, SHELL_CMD_ARG(beacon-listen, NULL, "<val: off, on>", cmd_beacon_listen,
2, 0), 2, 0),
#if defined(CONFIG_BT_MESH_CFG_CLI)
/* Configuration Client Model operations */ /* Configuration Client Model operations */
SHELL_CMD_ARG(timeout, NULL, "[timeout in seconds]", cmd_timeout, 1, 1), SHELL_CMD_ARG(timeout, NULL, "[timeout in seconds]", cmd_timeout, 1, 1),
SHELL_CMD_ARG(get-comp, NULL, "[page]", cmd_get_comp, 1, 1), SHELL_CMD_ARG(get-comp, NULL, "[page]", cmd_get_comp, 1, 1),
@ -2745,7 +2743,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(mesh_cmds,
SHELL_CMD_ARG(hb-pub, NULL, SHELL_CMD_ARG(hb-pub, NULL,
"[<dst> <count> <period> <ttl> <features> <NetKeyIndex>]", "[<dst> <count> <period> <ttl> <features> <NetKeyIndex>]",
cmd_hb_pub, 1, 6), cmd_hb_pub, 1, 6),
#endif
#if defined(CONFIG_BT_MESH_HEALTH_CLI)
/* Health Client Model Operations */ /* Health Client Model Operations */
SHELL_CMD_ARG(fault-get, NULL, "<Company ID>", cmd_fault_get, 2, 0), SHELL_CMD_ARG(fault-get, NULL, "<Company ID>", cmd_fault_get, 2, 0),
SHELL_CMD_ARG(fault-clear, NULL, "<Company ID>", cmd_fault_clear, 2, 0), SHELL_CMD_ARG(fault-clear, NULL, "<Company ID>", cmd_fault_clear, 2, 0),
@ -2763,6 +2763,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(mesh_cmds,
SHELL_CMD_ARG(attention-set, NULL, "<timer>", cmd_attention_set, 2, 0), SHELL_CMD_ARG(attention-set, NULL, "<timer>", cmd_attention_set, 2, 0),
SHELL_CMD_ARG(attention-set-unack, NULL, "<timer>", SHELL_CMD_ARG(attention-set-unack, NULL, "<timer>",
cmd_attention_set_unack, 2, 0), cmd_attention_set_unack, 2, 0),
#endif
/* Health Server Model Operations */ /* Health Server Model Operations */
SHELL_CMD_ARG(add-fault, NULL, "<Fault ID>", cmd_add_fault, 2, 0), SHELL_CMD_ARG(add-fault, NULL, "<Fault ID>", cmd_add_fault, 2, 0),

View file

@ -5,12 +5,77 @@
*/ */
#include <sys/printk.h> #include <sys/printk.h>
#include <stdlib.h>
#include <zephyr.h> #include <zephyr.h>
#include <shell/shell.h> #include <shell/shell.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/mesh.h>
#include <bluetooth/mesh/shell.h>
static struct bt_mesh_cfg_cli cfg_cli;
BT_MESH_SHELL_HEALTH_PUB_DEFINE(health_pub);
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
BT_MESH_MODEL_HEALTH_SRV(&bt_mesh_shell_health_srv, &health_pub),
BT_MESH_MODEL_HEALTH_CLI(&bt_mesh_shell_health_cli),
};
static struct bt_mesh_elem elements[] = {
BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE),
};
static const struct bt_mesh_comp comp = {
.cid = CONFIG_BT_COMPANY_ID,
.elem = elements,
.elem_count = ARRAY_SIZE(elements),
};
static void bt_ready(int err)
{
if (err && err != -EALREADY) {
printk("Bluetooth init failed (err %d)\n", err);
return;
}
printk("Bluetooth initialized\n");
err = bt_mesh_init(&bt_mesh_shell_prov, &comp);
if (err) {
printk("Initializing mesh failed (err %d)\n", err);
return;
}
if (IS_ENABLED(CONFIG_SETTINGS)) {
settings_load();
}
printk("Mesh initialized\n");
if (bt_mesh_is_provisioned()) {
printk("Mesh network restored from flash\n");
} else {
printk("Use \"pb-adv on\" or \"pb-gatt on\" to "
"enable advertising\n");
}
}
void main(void) void main(void)
{ {
int err;
printk("Initializing...\n");
/* Initialize the Bluetooth Subsystem */
err = bt_enable(bt_ready);
if (err && err != -EALREADY) {
printk("Bluetooth init failed (err %d)\n", err);
}
printk("Press the <Tab> button for supported commands.\n"); printk("Press the <Tab> button for supported commands.\n");
printk("Before any Mesh commands you must run \"mesh init\"\n"); printk("Before any Mesh commands you must run \"mesh init\"\n");
} }