Bluetooth: Mesh: Encapsulate feature config

Moves mesh feature configuration to a separate module, deprecating the
bt_mesh_cfg_srv structure. The initial values for the features should
now be enabled through KConfig, where new config entries have been added
for each feature.

This removes the upward dependency on the config server from the core
stack, and makes the config server a pure frontend for the configuration
states, as all spec mandated behavior around the feature states is now
encapsulated.

Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
This commit is contained in:
Trond Einar Snekvik 2020-08-18 13:36:38 +02:00 committed by Johan Hedberg
commit ad2fd44d7a
36 changed files with 645 additions and 634 deletions

View file

@ -19,4 +19,5 @@ Read more about Bluetooth Mesh on the
mesh/provisioning.rst
mesh/proxy.rst
mesh/heartbeat.rst
mesh/cfg.rst
mesh/shell.rst

View file

@ -0,0 +1,23 @@
.. _bluetooth_mesh_cfg:
Runtime configuration
#####################
The Bluetooth Mesh runtime configuration API allows applications to change
their runtime configuration directly, without going through the Configuration
models.
Bluetooth Mesh nodes should generally be configured by a central network
configurator device with a :ref:`bluetooth_mesh_models_cfg_cli` model. Each
mesh node instantiates a :ref:`bluetooth_mesh_models_cfg_srv` model that the
Config Client can communicate with to change the node configuration. In some
cases, the mesh node can't rely on the Config Client to detect or determine
local constraints, such as low battery power or changes in topology. For these
scenarios, this API can be used to change the configuration locally.
API reference
*************
.. doxygengroup:: bt_mesh_cfg
:project: Zephyr
:members:

View file

@ -8,11 +8,11 @@ specification. The Configuration Server model controls most parameters of the
mesh node. It does not have an API of its own, but relies on a
:ref:`bluetooth_mesh_models_cfg_cli` to control it.
The application can configure the initial parameters of the Configuration
Server model through the :c:struct:`bt_mesh_cfg_srv` instance passed to
:c:macro:`BT_MESH_MODEL_CFG_SRV`. Note that if the mesh node stored changes to
this configuration in the settings subsystem, the initial values may be
overwritten upon loading.
..note::
The :c:struct:`bt_mesh_cfg_srv` structure has been deprecated. The initial
values of the Relay, Beacon, Friend, Network transmit and Relay retransmit
should be set through Kconfig, and the Heartbeat feature should be
controlled through the :ref:`bluetooth_mesh_heartbeat` API.
The Configuration Server model is mandatory on all Bluetooth Mesh nodes, and
should be instantiated in the first element.

View file

@ -188,6 +188,10 @@ Bluetooth
* Mesh
* The ``bt_mesh_cfg_srv`` structure has been deprecated in favor of a
standalone Heartbeat API and Kconfig entries for default state values.
* BLE split software Controller
* HCI Driver

View file

@ -16,6 +16,7 @@
#include <bluetooth/mesh/access.h>
#include <bluetooth/mesh/main.h>
#include <bluetooth/mesh/cfg.h>
#include <bluetooth/mesh/cfg_srv.h>
#include <bluetooth/mesh/health_srv.h>
#include <bluetooth/mesh/cfg_cli.h>

View file

@ -35,6 +35,171 @@ enum bt_mesh_feat_state {
BT_MESH_FEATURE_NOT_SUPPORTED,
};
/* Legacy feature defines */
#define BT_MESH_RELAY_DISABLED BT_MESH_FEATURE_DISABLED
#define BT_MESH_RELAY_ENABLED BT_MESH_FEATURE_ENABLED
#define BT_MESH_RELAY_NOT_SUPPORTED BT_MESH_FEATURE_NOT_SUPPORTED
#define BT_MESH_BEACON_DISABLED BT_MESH_FEATURE_DISABLED
#define BT_MESH_BEACON_ENABLED BT_MESH_FEATURE_ENABLED
#define BT_MESH_GATT_PROXY_DISABLED BT_MESH_FEATURE_DISABLED
#define BT_MESH_GATT_PROXY_ENABLED BT_MESH_FEATURE_ENABLED
#define BT_MESH_GATT_PROXY_NOT_SUPPORTED BT_MESH_FEATURE_NOT_SUPPORTED
#define BT_MESH_FRIEND_DISABLED BT_MESH_FEATURE_DISABLED
#define BT_MESH_FRIEND_ENABLED BT_MESH_FEATURE_ENABLED
#define BT_MESH_FRIEND_NOT_SUPPORTED BT_MESH_FEATURE_NOT_SUPPORTED
#define BT_MESH_NODE_IDENTITY_STOPPED BT_MESH_FEATURE_DISABLED
#define BT_MESH_NODE_IDENTITY_RUNNING BT_MESH_FEATURE_ENABLED
#define BT_MESH_NODE_IDENTITY_NOT_SUPPORTED BT_MESH_FEATURE_NOT_SUPPORTED
/** @brief Enable or disable sending of the Secure Network Beacon.
*
* @param beacon New Secure Network Beacon state.
*/
void bt_mesh_beacon_set(bool beacon);
/** @brief Get the current Secure Network Beacon state.
*
* @returns Whether the Secure Network Beacon feature is enabled.
*/
bool bt_mesh_beacon_enabled(void);
/** @brief Set the default TTL value.
*
* The default TTL value is used when no explicit TTL value is set. Models will
* use the default TTL value when @ref bt_mesh_msg_ctx::send_ttl is
* @ref BT_MESH_TTL_DEFAULT.
*
* @param default_ttl The new default TTL value. Valid values are 0x00 and 0x02
* to @ref BT_MESH_TTL_MAX.
*
* @retval 0 Successfully set the default TTL value.
* @retval -EINVAL Invalid TTL value.
*/
int bt_mesh_default_ttl_set(uint8_t default_ttl);
/** @brief Get the current default TTL value.
*
* @return The current default TTL value.
*/
uint8_t bt_mesh_default_ttl_get(void);
/** @brief Set the Network Transmit parameters.
*
* The Network Transmit parameters determine the parameters local messages are
* transmitted with.
*
* @see BT_MESH_TRANSMIT
*
* @param xmit New Network Transmit parameters. Use @ref BT_MESH_TRANSMIT for
* encoding.
*/
void bt_mesh_net_transmit_set(uint8_t xmit);
/** @brief Get the current Network Transmit parameters.
*
* The @ref BT_MESH_TRANSMIT_COUNT and @ref BT_MESH_TRANSMIT_INT macros can be
* used to decode the Network Transmit parameters.
*
* @return The current Network Transmit parameters.
*/
uint8_t bt_mesh_net_transmit_get(void);
/** @brief Configure the Relay feature.
*
* Enable or disable the Relay feature, and configure the parameters to
* transmit relayed messages with.
*
* Support for the Relay feature must be enabled through the
* @c CONFIG_BT_MESH_RELAY configuration option.
*
* @see BT_MESH_TRANSMIT
*
* @param relay New Relay feature state. Must be one of
* @ref BT_MESH_FEATURE_ENABLED and
* @ref BT_MESH_FEATURE_DISABLED.
* @param xmit New Relay retransmit parameters. Use @ref BT_MESH_TRANSMIT for
* encoding.
*
* @retval 0 Successfully changed the Relay configuration.
* @retval -ENOTSUP The Relay feature is not supported.
* @retval -EINVAL Invalid parameter.
* @retval -EALREADY Already using the given parameters.
*/
int bt_mesh_relay_set(enum bt_mesh_feat_state relay, uint8_t xmit);
/** @brief Get the current Relay feature state.
*
* @returns The Relay feature state.
*/
enum bt_mesh_feat_state bt_mesh_relay_get(void);
/** @brief Get the current Relay Retransmit parameters.
*
* The @ref BT_MESH_TRANSMIT_COUNT and @ref BT_MESH_TRANSMIT_INT macros can be
* used to decode the Relay Retransmit parameters.
*
* @return The current Relay Retransmit parameters, or 0 if relay is not
* supported.
*/
uint8_t bt_mesh_relay_retransmit_get(void);
/** @brief Enable or disable the GATT Proxy feature.
*
* Support for the GATT Proxy feature must be enabled through the
* @c CONFIG_BT_MESH_GATT_PROXY configuration option.
*
* @note The GATT Proxy feature only controls a Proxy node's ability to relay
* messages to the mesh network. A node that supports GATT Proxy will
* still advertise Connectable Proxy beacons, even if the feature is
* disabled. The Proxy feature can only be fully disabled through compile
* time configuration.
*
* @param gatt_proxy New GATT Proxy state. Must be one of
* @ref BT_MESH_FEATURE_ENABLED and
* @ref BT_MESH_FEATURE_DISABLED.
*
* @retval 0 Successfully changed the GATT Proxy feature state.
* @retval -ENOTSUP The GATT Proxy feature is not supported.
* @retval -EINVAL Invalid parameter.
* @retval -EALREADY Already in the given state.
*/
int bt_mesh_gatt_proxy_set(enum bt_mesh_feat_state gatt_proxy);
/** @brief Get the current GATT Proxy state.
*
* @returns The GATT Proxy feature state.
*/
enum bt_mesh_feat_state bt_mesh_gatt_proxy_get(void);
/** @brief Enable or disable the Friend feature.
*
* Any active friendships will be terminated immediately if the Friend feature
* is disabled.
*
* Support for the Friend feature must be enabled through the
* @c CONFIG_BT_MESH_FRIEND configuration option.
*
* @param friendship New Friend feature state. Must be one of
* @ref BT_MESH_FEATURE_ENABLED and
* @ref BT_MESH_FEATURE_DISABLED.
*
* @retval 0 Successfully changed the Friend feature state.
* @retval -ENOTSUP The Friend feature is not supported.
* @retval -EINVAL Invalid parameter.
* @retval -EALREADY Already in the given state.
*/
int bt_mesh_friend_set(enum bt_mesh_feat_state friendship);
/** @brief Get the current Friend state.
*
* @returns The Friend feature state.
*/
enum bt_mesh_feat_state bt_mesh_friend_get(void);
/**
* @brief Bluetooth Mesh Subnet Configuration
* @defgroup bt_mesh_cfg_subnet Bluetooth Mesh Subnet Configuration

View file

@ -21,101 +21,13 @@
extern "C" {
#endif
/** Mesh Configuration Server Model Context */
struct bt_mesh_cfg_srv {
/** Composition data model entry pointer. */
struct bt_mesh_model *model;
uint8_t net_transmit; /**< Network Transmit state */
uint8_t relay; /**< Relay Mode state */
uint8_t relay_retransmit; /**< Relay Retransmit state */
uint8_t beacon; /**< Secure Network Beacon state */
uint8_t gatt_proxy; /**< GATT Proxy state */
uint8_t frnd; /**< Friend state */
uint8_t default_ttl; /**< Default TTL */
/** Heartbeat Publication parameters.
*
* @deprecated in favor of standalone API in bluetooth/mesh/heartbeat.h.
*/
struct {
struct k_delayed_work timer;
/** Destination address. */
uint16_t dst;
/** Remaining publish count. */
uint16_t count;
/** Logarithmic publish interval in seconds. */
uint8_t period;
/** Time To Live value. */
uint8_t ttl;
/**
* Bitmap of features that trigger a Heartbeat publication if
* they change. Legal values are
* @ref BT_MESH_FEAT_RELAY, @ref BT_MESH_FEAT_PROXY,
* @ref BT_MESH_FEAT_FRIEND and @ref BT_MESH_FEAT_LOW_POWER.
*/
uint16_t feat;
/** Network index used for publishing. */
uint16_t net_idx;
} hb_pub __deprecated;
/** Heartbeat Subscription parameters.
*
* @deprecated in favor of standalone API in bluetooth/mesh/heartbeat.h.
*/
struct {
/** Subscription period exipration timestamp. */
int64_t expiry;
/** Source address to receive Heartbeats from. */
uint16_t src;
/** Destination address to received Heartbeats on. */
uint16_t dst;
/** The number of received Heartbeat messages so far. */
uint16_t count;
/**
* Minimum hops in received messages, ie the shortest registered
* path from the publishing node to the subscribing node. A
* Heartbeat received from an immediate neighbor has hop
* count = 1.
*/
uint8_t min_hops;
/**
* Maximum hops in received messages, ie the longest registered
* path from the publishing node to the subscribing node. A
* Heartbeat received from an immediate neighbor has hop
* count = 1.
*/
uint8_t max_hops;
/** @brief Optional Heartbeat subscription tracking callback.
*
* Gets called on every received Heartbeat.
*
* @param hops The number of hops the Heartbeat was received
* with.
* @param feat The feature set of the publishing node. The
* value is a bitmap of @ref BT_MESH_FEAT_RELAY,
* @ref BT_MESH_FEAT_PROXY,
* @ref BT_MESH_FEAT_FRIEND and
* @ref BT_MESH_FEAT_LOW_POWER.
*
* @deprecated Please use the @ref bt_mesh_hb_cb registration
* function.
*/
void (*func)(uint8_t hops, uint16_t feat);
} hb_sub __deprecated;
};
/** @def BT_MESH_MODEL_CFG_SRV
*
* @brief Generic Configuration Server model composition data entry.
*
* @param srv_data Pointer to a @ref bt_mesh_cfg_srv instance.
*/
#define BT_MESH_MODEL_CFG_SRV(srv_data) \
#define BT_MESH_MODEL_CFG_SRV \
BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_CFG_SRV, bt_mesh_cfg_srv_op, NULL, \
srv_data, &bt_mesh_cfg_srv_cb)
NULL, &bt_mesh_cfg_srv_cb)
/** @cond INTERNAL_HIDDEN */
extern const struct bt_mesh_model_op bt_mesh_cfg_srv_op[];

View file

@ -432,25 +432,6 @@ bool bt_mesh_is_provisioned(void);
/* Primary Network Key index */
#define BT_MESH_NET_PRIMARY 0x000
#define BT_MESH_RELAY_DISABLED 0x00
#define BT_MESH_RELAY_ENABLED 0x01
#define BT_MESH_RELAY_NOT_SUPPORTED 0x02
#define BT_MESH_BEACON_DISABLED 0x00
#define BT_MESH_BEACON_ENABLED 0x01
#define BT_MESH_GATT_PROXY_DISABLED 0x00
#define BT_MESH_GATT_PROXY_ENABLED 0x01
#define BT_MESH_GATT_PROXY_NOT_SUPPORTED 0x02
#define BT_MESH_FRIEND_DISABLED 0x00
#define BT_MESH_FRIEND_ENABLED 0x01
#define BT_MESH_FRIEND_NOT_SUPPORTED 0x02
#define BT_MESH_NODE_IDENTITY_STOPPED 0x00
#define BT_MESH_NODE_IDENTITY_RUNNING 0x01
#define BT_MESH_NODE_IDENTITY_NOT_SUPPORTED 0x02
/** Relay feature */
#define BT_MESH_FEAT_RELAY BIT(0)
/** GATT Proxy feature */

View file

@ -15,26 +15,6 @@
#include "board.h"
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_RELAY_DISABLED,
.beacon = BT_MESH_BEACON_ENABLED,
#if defined(CONFIG_BT_MESH_FRIEND)
.frnd = BT_MESH_FRIEND_ENABLED,
#else
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BT_MESH_GATT_PROXY)
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
#endif
.default_ttl = 7,
/* 3 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
};
static struct bt_mesh_health_srv health_srv = {
};
@ -122,7 +102,7 @@ static const struct bt_mesh_model_op gen_level_op[] = {
};
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_op,
&gen_onoff_pub, NULL),

View file

@ -25,6 +25,7 @@ CONFIG_BT_MESH_ADV_BUF_COUNT=3
CONFIG_BT_MESH_LOOPBACK_BUFS=1
CONFIG_BT_MESH_PB_ADV=n
CONFIG_BT_MESH_CFG_CLI=y
CONFIG_BT_MESH_BEACON_ENABLED=n
CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y

View file

@ -40,30 +40,13 @@ static const uint32_t iv_index;
static uint8_t flags;
static uint16_t addr = NODE_ADDR;
static void heartbeat(uint8_t hops, uint16_t feat)
static void heartbeat(const struct bt_mesh_hb_sub *sub, uint8_t hops,
uint16_t feat)
{
board_heartbeat(hops, feat);
board_play("100H");
}
static struct bt_mesh_cfg_srv cfg_srv = {
#if defined(CONFIG_BOARD_BBC_MICROBIT)
.relay = BT_MESH_RELAY_ENABLED,
.beacon = BT_MESH_BEACON_DISABLED,
#else
.relay = BT_MESH_RELAY_ENABLED,
.beacon = BT_MESH_BEACON_ENABLED,
#endif
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
.default_ttl = 7,
/* 3 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
.relay_retransmit = BT_MESH_TRANSMIT(3, 20),
.hb_sub.func = heartbeat,
};
static struct bt_mesh_cfg_cli cfg_cli = {
};
@ -92,7 +75,7 @@ static struct bt_mesh_health_srv health_srv = {
BT_MESH_HEALTH_PUB_DEFINE(health_pub, 0);
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
};
@ -175,6 +158,10 @@ static const struct bt_mesh_prov prov = {
.uuid = dev_uuid,
};
BT_MESH_HB_CB_DEFINE(hb_cb) = {
.recv = heartbeat,
};
static void bt_ready(int err)
{
if (err) {

View file

@ -17,6 +17,9 @@ CONFIG_BT_MESH_MODEL_GROUP_COUNT=2
CONFIG_BT_MESH_LABEL_COUNT=0
CONFIG_BT_MESH_CFG_CLI=y
CONFIG_BT_MESH_HEALTH_CLI=y
CONFIG_BT_MESH_BEACON_ENABLED=n
CONFIG_BT_MESH_RELAY=y
CONFIG_BT_MESH_RELAY_RETRANSMIT_COUNT=3
CONFIG_BT_MESH_PROVISIONER=y
CONFIG_BT_MESH_PROV_DEVICE=n

View file

@ -20,17 +20,6 @@ static uint8_t node_uuid[16];
K_SEM_DEFINE(sem_unprov_beacon, 0, 1);
K_SEM_DEFINE(sem_node_added, 0, 1);
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_RELAY_ENABLED,
.beacon = BT_MESH_BEACON_DISABLED,
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
.default_ttl = 7,
/* 3 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
.relay_retransmit = BT_MESH_TRANSMIT(3, 20),
};
static struct bt_mesh_cfg_cli cfg_cli = {
};
@ -61,7 +50,7 @@ static struct bt_mesh_health_cli health_cli = {
};
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
BT_MESH_MODEL_HEALTH_CLI(&health_cli),
};

View file

@ -36,6 +36,8 @@ CONFIG_BT_L2CAP_TX_BUF_COUNT=8
CONFIG_BT_MESH=y
CONFIG_BT_MESH_RELAY=y
CONFIG_BT_MESH_RELAY_ENABLED=n
CONFIG_BT_MESH_BEACON_ENABLED=n
CONFIG_BT_MESH_LOW_POWER=n
CONFIG_BT_MESH_FRIEND=n
CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=16

View file

@ -70,30 +70,6 @@ static void gen_onoff_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
/*
* Server Configuration Declaration
*/
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_RELAY_DISABLED,
.beacon = BT_MESH_BEACON_ENABLED,
#if defined(CONFIG_BT_MESH_FRIEND)
.frnd = BT_MESH_FRIEND_ENABLED,
#else
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BT_MESH_GATT_PROXY)
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
#endif
.default_ttl = 7,
/* 3 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
};
/*
* Client Configuration Declaration
*/
@ -193,7 +169,7 @@ static struct onoff_state onoff_state[] = {
*/
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op,

View file

@ -32,6 +32,7 @@ CONFIG_BT_L2CAP_TX_BUF_COUNT=8
CONFIG_BT_MESH=y
CONFIG_BT_MESH_RELAY=y
CONFIG_BT_MESH_RELAY_RETRANSMIT_COUNT=3
CONFIG_BT_MESH_LOW_POWER=n
CONFIG_BT_MESH_FRIEND=n
CONFIG_BT_MESH_FRIEND_QUEUE_SIZE=16

View file

@ -14,31 +14,6 @@
#include "transition.h"
#include "storage.h"
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_RELAY_ENABLED,
.beacon = BT_MESH_BEACON_ENABLED,
#if defined(CONFIG_BT_MESH_FRIEND)
.frnd = BT_MESH_FRIEND_ENABLED,
#else
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BT_MESH_GATT_PROXY)
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
#endif
.default_ttl = 7,
/* 2 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
/* 3 transmissions with 20ms interval */
.relay_retransmit = BT_MESH_TRANSMIT(3, 20),
};
static struct bt_mesh_health_srv health_srv = {
};
@ -3010,7 +2985,7 @@ static const struct bt_mesh_model_op gen_level_cli_op_temp[] = {
};
struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV,

View file

@ -25,6 +25,8 @@ CONFIG_BT_L2CAP_TX_BUF_COUNT=8
CONFIG_BT_MESH=y
CONFIG_BT_MESH_RELAY=y
CONFIG_BT_MESH_RELAY_RETRANSMIT_COUNT=3
CONFIG_BT_MESH_BEACON_ENABLED=n
#CONFIG_BT_MESH_GATT_PROXY=y
CONFIG_BT_MESH_PB_ADV=n
CONFIG_BT_MESH_PB_GATT=n

View file

@ -66,21 +66,14 @@ static struct led_onoff_state led_onoff_state[] = {
{ .dev_id = 0 },
};
static void heartbeat(uint8_t hops, uint16_t feat)
static void heartbeat(const struct bt_mesh_hb_sub *sub, uint8_t hops,
uint16_t feat)
{
board_show_text("Heartbeat Received", false, K_SECONDS(2));
}
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_RELAY_ENABLED,
.beacon = BT_MESH_BEACON_DISABLED,
.default_ttl = DEFAULT_TTL,
/* 3 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
.relay_retransmit = BT_MESH_TRANSMIT(3, 20),
.hb_sub.func = heartbeat,
BT_MESH_HB_CB_DEFINE(hb_cb) = {
.recv = heartbeat,
};
static struct bt_mesh_cfg_cli cfg_cli = {
@ -303,7 +296,7 @@ static const struct bt_mesh_model_op sensor_srv_op[] = {
};
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV,

View file

@ -5,6 +5,7 @@ zephyr_library_link_libraries(subsys__bluetooth)
zephyr_library_sources_ifdef(CONFIG_BT_MESH
main.c
cfg.c
adv.c
beacon.c
net.c

View file

@ -107,13 +107,21 @@ config BT_MESH_PB_GATT
GATT.
config BT_MESH_GATT_PROXY
bool "GATT Proxy Service"
bool "GATT Proxy Service support"
select BT_MESH_PROXY
help
This option enables support for the Mesh GATT Proxy Service,
i.e. the ability to act as a proxy between a Mesh GATT Client
and a Mesh network.
config BT_MESH_GATT_PROXY_ENABLED
bool "GATT Proxy enabled"
depends on BT_MESH_GATT_PROXY
default y
help
Controls whether the GATT Proxy feature is enabled by default.
Can be changed through runtime configuration.
config BT_MESH_NODE_ID_TIMEOUT
int "Node Identity advertising timeout"
depends on BT_MESH_GATT_PROXY
@ -325,6 +333,14 @@ config BT_MESH_TX_SEG_MAX
which leaves 56 bytes for application layer data using a
4-byte MIC and 52 bytes using an 8-byte MIC.
config BT_MESH_DEFAULT_TTL
int "Default TTL value"
default 7
range 0 128
help
Controls the default TTL value for outgoing messages. Can be changed
through runtime configuration.
config BT_MESH_LOOPBACK_BUFS
int "Number of loopback buffers"
default 3
@ -354,11 +370,65 @@ config BT_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP
help
Maximum time of retransmit segment message to group address.
config BT_MESH_RELAY
config BT_MESH_NETWORK_TRANSMIT_COUNT
int "Network Transmit Count"
default 2
range 0 7
help
Controls the initial number of retransmissions of original messages,
in addition to the first transmission. Can be changed through runtime
configuration.
config BT_MESH_NETWORK_TRANSMIT_INTERVAL
int "Network Transmit Interval"
default 20
range 10 330
help
Controls the initial interval between retransmissions of original
messages, in milliseconds. Can be changed through runtime
configuration.
menuconfig BT_MESH_RELAY
bool "Relay support"
help
Support for acting as a Mesh Relay Node.
if BT_MESH_RELAY
config BT_MESH_RELAY_ENABLED
bool "Relay enabled"
default y
help
Controls whether the Mesh Relay feature is enabled by default. Can be
changed through runtime configuration.
config BT_MESH_RELAY_RETRANSMIT_COUNT
int "Relay Retransmit Count"
default 2
range 0 7
help
Controls the initial number of retransmissions of relayed messages, in
addition to the first transmission. Can be changed through runtime
configuration.
config BT_MESH_RELAY_RETRANSMIT_INTERVAL
int "Relay Retransmit Interval"
default 20
range 10 330
help
Controls the initial interval between retransmissions of relayed
messages, in milliseconds. Can be changed through runtime
configuration.
endif
config BT_MESH_BEACON_ENABLED
bool "Secure network beacon enabled"
default y
help
Controls whether the Secure network beacon feature is enabled by
default. Can be changed through runtime configuration.
config BT_MESH_LOW_POWER
bool "Support for Low Power features"
help
@ -491,6 +561,13 @@ config BT_MESH_FRIEND
if BT_MESH_FRIEND
config BT_MESH_FRIEND_ENABLED
bool "Friend feature enabled"
default y
help
Controls whether the Friend feature is enabled by default. Can be
changed through runtime configuration.
config BT_MESH_FRIEND_RECV_WIN
int "Friend Receive Window"
range 1 255

View file

@ -478,7 +478,11 @@ static bool model_has_dst(struct bt_mesh_model *mod, uint16_t dst)
return !!bt_mesh_model_find_group(&mod, dst);
}
return (mod->elem_idx == 0 && bt_mesh_fixed_group_match(dst));
/* If a message with a fixed group address is sent to the access layer,
* the lower layers have already confirmed that we are subscribing to
* it. All models on the primary element should receive the message.
*/
return mod->elem_idx == 0;
}
static const struct bt_mesh_model_op *find_op(struct bt_mesh_model *models,
@ -541,23 +545,6 @@ static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode)
CODE_UNREACHABLE;
}
bool bt_mesh_fixed_group_match(uint16_t addr)
{
/* Check for fixed group addresses */
switch (addr) {
case BT_MESH_ADDR_ALL_NODES:
return true;
case BT_MESH_ADDR_PROXIES:
return (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED);
case BT_MESH_ADDR_FRIENDS:
return (bt_mesh_friend_get() == BT_MESH_FRIEND_ENABLED);
case BT_MESH_ADDR_RELAYS:
return (bt_mesh_relay_get() == BT_MESH_RELAY_ENABLED);
default:
return false;
}
}
void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
{
struct bt_mesh_model *models, *model;

View file

@ -36,8 +36,6 @@ void bt_mesh_model_tree_walk(struct bt_mesh_model *root,
uint16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, uint16_t addr);
bool bt_mesh_fixed_group_match(uint16_t addr);
void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod,
struct bt_mesh_elem *elem,
bool vnd, bool primary,

View file

@ -245,7 +245,7 @@ static void beacon_send(struct k_work *work)
(void)bt_mesh_subnet_find(secure_beacon_send, NULL);
/* Only resubmit if beaconing is still enabled */
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED ||
if (bt_mesh_beacon_enabled() ||
atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) {
k_delayed_work_submit(&beacon_timer,
PROVISIONED_INTERVAL);
@ -367,7 +367,7 @@ static void secure_beacon_recv(struct net_buf_simple *buf)
bt_mesh_net_iv_update(params.iv_index, BT_MESH_IV_UPDATE(params.flags));
update_stats:
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED &&
if (bt_mesh_beacon_enabled() &&
sub->beacons_cur < 0xff) {
sub->beacons_cur++;
}
@ -439,7 +439,7 @@ void bt_mesh_beacon_ivu_initiator(bool enable)
if (enable) {
k_work_submit(&beacon_timer.work);
} else if (bt_mesh_beacon_get() == BT_MESH_BEACON_DISABLED) {
} else if (!bt_mesh_beacon_enabled()) {
k_delayed_work_cancel(&beacon_timer);
}
}

266
subsys/bluetooth/mesh/cfg.c Normal file
View file

@ -0,0 +1,266 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bluetooth/mesh.h>
#include "mesh.h"
#include "net.h"
#include "rpl.h"
#include "beacon.h"
#include "settings.h"
#include "heartbeat.h"
#include "friend.h"
#include "cfg.h"
void bt_mesh_beacon_set(bool beacon)
{
if (atomic_test_bit(bt_mesh.flags, BT_MESH_BEACON) == beacon) {
return;
}
atomic_set_bit_to(bt_mesh.flags, BT_MESH_BEACON, beacon);
if (beacon) {
bt_mesh_beacon_enable();
} else {
bt_mesh_beacon_disable();
}
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
bt_mesh_store_cfg();
}
}
bool bt_mesh_beacon_enabled(void)
{
return atomic_test_bit(bt_mesh.flags, BT_MESH_BEACON);
}
static int feature_set(int feature_flag, enum bt_mesh_feat_state state)
{
if (state != BT_MESH_FEATURE_DISABLED &&
state != BT_MESH_FEATURE_ENABLED) {
return -EINVAL;
}
if (atomic_test_bit(bt_mesh.flags, feature_flag) ==
(state == BT_MESH_FEATURE_ENABLED)) {
return -EALREADY;
}
atomic_set_bit_to(bt_mesh.flags, feature_flag,
(state == BT_MESH_FEATURE_ENABLED));
return 0;
}
static enum bt_mesh_feat_state feature_get(int feature_flag)
{
return atomic_test_bit(bt_mesh.flags, feature_flag) ?
BT_MESH_FEATURE_ENABLED :
BT_MESH_FEATURE_DISABLED;
}
int bt_mesh_gatt_proxy_set(enum bt_mesh_feat_state gatt_proxy)
{
int err;
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
return -ENOTSUP;
}
err = feature_set(BT_MESH_GATT_PROXY, gatt_proxy);
if (err) {
return err;
}
bt_mesh_hb_feature_changed(BT_MESH_FEAT_PROXY);
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
bt_mesh_store_cfg();
}
return 0;
}
enum bt_mesh_feat_state bt_mesh_gatt_proxy_get(void)
{
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
return BT_MESH_FEATURE_NOT_SUPPORTED;
}
return feature_get(BT_MESH_GATT_PROXY);
}
int bt_mesh_default_ttl_set(uint8_t default_ttl)
{
if (default_ttl == 1 || default_ttl > BT_MESH_TTL_MAX) {
return -EINVAL;
}
if (default_ttl == bt_mesh.default_ttl) {
return 0;
}
bt_mesh.default_ttl = default_ttl;
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
bt_mesh_store_cfg();
}
return 0;
}
uint8_t bt_mesh_default_ttl_get(void)
{
return bt_mesh.default_ttl;
}
int bt_mesh_friend_set(enum bt_mesh_feat_state friendship)
{
int err;
if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
return -ENOTSUP;
}
err = feature_set(BT_MESH_FRIEND, friendship);
if (err) {
return err;
}
bt_mesh_hb_feature_changed(BT_MESH_FEAT_FRIEND);
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
bt_mesh_store_cfg();
}
if (friendship == BT_MESH_FEATURE_DISABLED) {
bt_mesh_friends_clear();
}
return 0;
}
enum bt_mesh_feat_state bt_mesh_friend_get(void)
{
if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
return BT_MESH_FEATURE_NOT_SUPPORTED;
}
return feature_get(BT_MESH_FRIEND);
}
void bt_mesh_net_transmit_set(uint8_t xmit)
{
if (bt_mesh.net_xmit == xmit) {
return;
}
bt_mesh.net_xmit = xmit;
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
bt_mesh_store_cfg();
}
}
uint8_t bt_mesh_net_transmit_get(void)
{
return bt_mesh.net_xmit;
}
int bt_mesh_relay_set(enum bt_mesh_feat_state relay, uint8_t xmit)
{
int err;
if (!IS_ENABLED(CONFIG_BT_MESH_RELAY)) {
return -ENOTSUP;
}
err = feature_set(BT_MESH_RELAY, relay);
if (err == -EINVAL) {
return err;
}
if (err == -EALREADY && bt_mesh.relay_xmit == xmit) {
return -EALREADY;
}
bt_mesh.relay_xmit = xmit;
bt_mesh_hb_feature_changed(BT_MESH_FEAT_RELAY);
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
bt_mesh_store_cfg();
}
return 0;
}
enum bt_mesh_feat_state bt_mesh_relay_get(void)
{
return feature_get(BT_MESH_RELAY);
}
uint8_t bt_mesh_relay_retransmit_get(void)
{
if (!IS_ENABLED(CONFIG_BT_MESH_RELAY)) {
return 0;
}
return bt_mesh.relay_xmit;
}
bool bt_mesh_fixed_group_match(uint16_t addr)
{
/* Check for fixed group addresses */
switch (addr) {
case BT_MESH_ADDR_ALL_NODES:
return true;
case BT_MESH_ADDR_PROXIES:
return (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED);
case BT_MESH_ADDR_FRIENDS:
return (bt_mesh_friend_get() == BT_MESH_FEATURE_ENABLED);
case BT_MESH_ADDR_RELAYS:
return (bt_mesh_relay_get() == BT_MESH_FEATURE_ENABLED);
default:
return false;
}
}
void bt_mesh_cfg_init(void)
{
bt_mesh.default_ttl = CONFIG_BT_MESH_DEFAULT_TTL;
bt_mesh.net_xmit =
BT_MESH_TRANSMIT(CONFIG_BT_MESH_NETWORK_TRANSMIT_COUNT,
CONFIG_BT_MESH_NETWORK_TRANSMIT_INTERVAL);
#if defined(CONFIG_BT_MESH_RELAY)
bt_mesh.relay_xmit =
BT_MESH_TRANSMIT(CONFIG_BT_MESH_RELAY_RETRANSMIT_COUNT,
CONFIG_BT_MESH_RELAY_RETRANSMIT_INTERVAL);
#endif
if (IS_ENABLED(CONFIG_BT_MESH_RELAY_ENABLED)) {
atomic_set_bit(bt_mesh.flags, BT_MESH_RELAY);
}
if (IS_ENABLED(CONFIG_BT_MESH_BEACON_ENABLED)) {
atomic_set_bit(bt_mesh.flags, BT_MESH_BEACON);
}
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY_ENABLED)) {
atomic_set_bit(bt_mesh.flags, BT_MESH_GATT_PROXY);
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND_ENABLED)) {
atomic_set_bit(bt_mesh.flags, BT_MESH_FRIEND);
}
}

View file

@ -0,0 +1,9 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
void bt_mesh_cfg_init(void);
bool bt_mesh_fixed_group_match(uint16_t addr);

View file

@ -38,10 +38,7 @@
#include "foundation.h"
#include "friend.h"
#include "settings.h"
#define DEFAULT_TTL 7
static struct bt_mesh_cfg_srv *conf;
#include "cfg.h"
static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
bool primary)
@ -470,7 +467,7 @@ static void beacon_get(struct bt_mesh_model *model,
bt_hex(buf->data, buf->len));
bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS);
net_buf_simple_add_u8(&msg, bt_mesh_beacon_get());
net_buf_simple_add_u8(&msg, bt_mesh_beacon_enabled());
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("Unable to send Config Beacon Status response");
@ -482,33 +479,20 @@ static void beacon_set(struct bt_mesh_model *model,
struct net_buf_simple *buf)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
struct bt_mesh_cfg_srv *cfg = model->user_data;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
if (buf->data[0] == 0x00 || buf->data[0] == 0x01) {
if (buf->data[0] != cfg->beacon) {
cfg->beacon = buf->data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
if (cfg->beacon) {
bt_mesh_beacon_enable();
} else {
bt_mesh_beacon_disable();
}
}
} else {
if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
BT_WARN("Invalid Config Beacon value 0x%02x", buf->data[0]);
return;
}
bt_mesh_beacon_set(buf->data[0]);
bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS);
net_buf_simple_add_u8(&msg, bt_mesh_beacon_get());
net_buf_simple_add_u8(&msg, buf->data[0]);
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("Unable to send Config Beacon Status response");
@ -538,27 +522,20 @@ static void default_ttl_set(struct bt_mesh_model *model,
struct net_buf_simple *buf)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
struct bt_mesh_cfg_srv *cfg = model->user_data;
int err;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
if (buf->data[0] <= BT_MESH_TTL_MAX && buf->data[0] != 0x01) {
if (cfg->default_ttl != buf->data[0]) {
cfg->default_ttl = buf->data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
}
} else {
err = bt_mesh_default_ttl_set(buf->data[0]);
if (err) {
BT_WARN("Prohibited Default TTL value 0x%02x", buf->data[0]);
return;
}
bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS);
net_buf_simple_add_u8(&msg, bt_mesh_default_ttl_get());
net_buf_simple_add_u8(&msg, buf->data[0]);
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("Unable to send Default TTL Status response");
@ -593,8 +570,6 @@ static void gatt_proxy_set(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_cfg_srv *cfg = model->user_data;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
@ -604,26 +579,8 @@ static void gatt_proxy_set(struct bt_mesh_model *model,
return;
}
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) ||
bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_NOT_SUPPORTED) {
goto send_status;
}
(void)bt_mesh_gatt_proxy_set(buf->data[0]);
BT_DBG("GATT Proxy 0x%02x -> 0x%02x", cfg->gatt_proxy, buf->data[0]);
if (cfg->gatt_proxy == buf->data[0]) {
goto send_status;
}
cfg->gatt_proxy = buf->data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
bt_mesh_hb_feature_changed(BT_MESH_FEAT_PROXY);
send_status:
send_gatt_proxy_status(model, ctx);
}
@ -650,7 +607,6 @@ static void net_transmit_set(struct bt_mesh_model *model,
struct net_buf_simple *buf)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
struct bt_mesh_cfg_srv *cfg = model->user_data;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
@ -660,14 +616,10 @@ static void net_transmit_set(struct bt_mesh_model *model,
BT_MESH_TRANSMIT_COUNT(buf->data[0]),
BT_MESH_TRANSMIT_INT(buf->data[0]));
cfg->net_transmit = buf->data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
bt_mesh_net_transmit_set(buf->data[0]);
bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS);
net_buf_simple_add_u8(&msg, bt_mesh_net_transmit_get());
net_buf_simple_add_u8(&msg, buf->data[0]);
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("Unable to send Network Transmit Status");
@ -698,39 +650,18 @@ static void relay_set(struct bt_mesh_model *model,
struct net_buf_simple *buf)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
struct bt_mesh_cfg_srv *cfg = model->user_data;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
if (buf->data[0] == 0x00 || buf->data[0] == 0x01) {
bool change;
if (cfg->relay == BT_MESH_RELAY_NOT_SUPPORTED) {
change = false;
} else {
change = (cfg->relay != buf->data[0]);
cfg->relay = buf->data[0];
cfg->relay_retransmit = buf->data[1];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
}
BT_DBG("Relay 0x%02x (%s) xmit 0x%02x (count %u interval %u)",
cfg->relay, change ? "changed" : "not changed",
cfg->relay_retransmit,
BT_MESH_TRANSMIT_COUNT(cfg->relay_retransmit),
BT_MESH_TRANSMIT_INT(cfg->relay_retransmit));
bt_mesh_hb_feature_changed(BT_MESH_FEAT_RELAY);
} else {
if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
BT_WARN("Invalid Relay value 0x%02x", buf->data[0]);
return;
}
(void)bt_mesh_relay_set(buf->data[0], buf->data[1]);
bt_mesh_model_msg_init(&msg, OP_RELAY_STATUS);
net_buf_simple_add_u8(&msg, bt_mesh_relay_get());
net_buf_simple_add_u8(&msg, bt_mesh_relay_retransmit_get());
@ -2070,10 +2001,9 @@ static void send_friend_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1);
struct bt_mesh_cfg_srv *cfg = model->user_data;
bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS);
net_buf_simple_add_u8(&msg, cfg->frnd);
net_buf_simple_add_u8(&msg, bt_mesh_friend_get());
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
BT_ERR("Unable to send Friend Status");
@ -2095,8 +2025,6 @@ static void friend_set(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_cfg_srv *cfg = model->user_data;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
@ -2106,27 +2034,8 @@ static void friend_set(struct bt_mesh_model *model,
return;
}
BT_DBG("Friend 0x%02x -> 0x%02x", cfg->frnd, buf->data[0]);
(void)bt_mesh_friend_set(buf->data[0]);
if (cfg->frnd == buf->data[0]) {
goto send_status;
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
cfg->frnd = buf->data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
if (cfg->frnd == BT_MESH_FRIEND_DISABLED) {
bt_mesh_friends_clear();
}
}
bt_mesh_hb_feature_changed(BT_MESH_FEAT_FRIEND);
send_status:
send_friend_status(model, ctx);
}
@ -2472,85 +2381,19 @@ const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = {
BT_MESH_MODEL_OP_END,
};
static bool conf_is_valid(struct bt_mesh_cfg_srv *cfg)
{
if (cfg->relay > 0x02) {
return false;
}
if (cfg->frnd > 0x02) {
return false;
}
if (cfg->gatt_proxy > 0x02) {
return false;
}
if (cfg->beacon > 0x01) {
return false;
}
if (cfg->default_ttl > BT_MESH_TTL_MAX) {
return false;
}
return true;
}
static void (*hb_sub_cb)(uint8_t hops, uint16_t features);
static struct bt_mesh_hb_cb hb_cb;
static void hb_recv_wrapper(const struct bt_mesh_hb_sub *sub, uint8_t hops, uint16_t features)
{
hb_sub_cb(hops, features);
}
static int cfg_srv_init(struct bt_mesh_model *model)
{
struct bt_mesh_cfg_srv *cfg = model->user_data;
if (!bt_mesh_model_in_primary(model)) {
BT_ERR("Configuration Server only allowed in primary element");
return -EINVAL;
}
if (!cfg) {
BT_ERR("No Configuration Server context provided");
return -EINVAL;
}
if (!conf_is_valid(cfg)) {
BT_ERR("Invalid values in configuration");
return -EINVAL;
}
if (cfg->hb_sub.func) {
hb_sub_cb = cfg->hb_sub.func;
hb_cb.recv = hb_recv_wrapper;
}
/*
* Configuration Model security is device-key based and only the local
* device-key is allowed to access this model.
*/
model->keys[0] = BT_MESH_KEY_DEV_LOCAL;
if (!IS_ENABLED(CONFIG_BT_MESH_RELAY)) {
cfg->relay = BT_MESH_RELAY_NOT_SUPPORTED;
}
if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
cfg->frnd = BT_MESH_FRIEND_NOT_SUPPORTED;
}
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
cfg->gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED;
}
cfg->model = model;
conf = cfg;
return 0;
}
@ -2586,72 +2429,3 @@ void bt_mesh_cfg_reset(void)
{
bt_mesh_model_foreach(mod_reset, NULL);
}
uint8_t bt_mesh_net_transmit_get(void)
{
if (conf) {
return conf->net_transmit;
}
return 0;
}
uint8_t bt_mesh_relay_get(void)
{
if (conf) {
return conf->relay;
}
return BT_MESH_RELAY_NOT_SUPPORTED;
}
uint8_t bt_mesh_friend_get(void)
{
if (conf) {
BT_DBG("conf %p conf->frnd 0x%02x", conf, conf->frnd);
return conf->frnd;
}
return BT_MESH_FRIEND_NOT_SUPPORTED;
}
uint8_t bt_mesh_relay_retransmit_get(void)
{
if (conf) {
return conf->relay_retransmit;
}
return 0;
}
uint8_t bt_mesh_beacon_get(void)
{
if (conf) {
return conf->beacon;
}
return BT_MESH_BEACON_DISABLED;
}
uint8_t bt_mesh_gatt_proxy_get(void)
{
if (conf) {
return conf->gatt_proxy;
}
return BT_MESH_GATT_PROXY_NOT_SUPPORTED;
}
uint8_t bt_mesh_default_ttl_get(void)
{
if (conf) {
return conf->default_ttl;
}
return DEFAULT_TTL;
}
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void)
{
return conf;
}

View file

@ -112,31 +112,10 @@
#define STATUS_UNSPECIFIED 0x10
#define STATUS_INVALID_BINDING 0x11
enum {
BT_MESH_VA_CHANGED, /* Label information changed */
};
struct label {
uint16_t ref;
uint16_t addr;
uint8_t uuid[16];
atomic_t flags[1];
};
void bt_mesh_cfg_reset(void);
void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time);
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void);
uint8_t bt_mesh_net_transmit_get(void);
uint8_t bt_mesh_relay_get(void);
uint8_t bt_mesh_friend_get(void);
uint8_t bt_mesh_relay_retransmit_get(void);
uint8_t bt_mesh_beacon_get(void);
uint8_t bt_mesh_gatt_proxy_get(void);
uint8_t bt_mesh_default_ttl_get(void);
#include <sys/byteorder.h>
static inline void key_idx_pack(struct net_buf_simple *buf,

View file

@ -28,6 +28,7 @@
#include "subnet.h"
#include "app_keys.h"
#include "rpl.h"
#include "cfg.h"
#include "beacon.h"
#include "lpn.h"
#include "friend.h"
@ -247,7 +248,7 @@ int bt_mesh_suspend(void)
bt_mesh_hb_suspend();
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
if (bt_mesh_beacon_enabled()) {
bt_mesh_beacon_disable();
}
@ -290,7 +291,7 @@ int bt_mesh_resume(void)
bt_mesh_hb_resume();
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
if (bt_mesh_beacon_enabled()) {
bt_mesh_beacon_enable();
}
@ -325,6 +326,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov,
}
}
bt_mesh_cfg_init();
bt_mesh_net_init();
bt_mesh_trans_init();
bt_mesh_hb_init();
@ -348,7 +350,7 @@ static void model_start(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
int bt_mesh_start(void)
{
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
if (bt_mesh_beacon_enabled()) {
bt_mesh_beacon_enable();
} else {
bt_mesh_beacon_disable();

View file

@ -37,6 +37,7 @@
#include "beacon.h"
#include "settings.h"
#include "prov.h"
#include "cfg.h"
/* Minimum valid Mesh Network PDU length. The Network headers
* themselves take up 9 bytes. After that there is a minimum of 1 byte

View file

@ -174,6 +174,12 @@ enum {
BT_MESH_MOD_PENDING,
BT_MESH_VA_PENDING,
/* Feature flags */
BT_MESH_RELAY,
BT_MESH_BEACON,
BT_MESH_GATT_PROXY,
BT_MESH_FRIEND,
/* Don't touch - intentionally last */
BT_MESH_FLAG_COUNT,
};
@ -200,6 +206,10 @@ struct bt_mesh_net {
/* Number of hours in current IV Update state */
uint8_t ivu_duration;
uint8_t net_xmit;
uint8_t relay_xmit;
uint8_t default_ttl;
/* Timer to track duration in current IV Update state */
struct k_delayed_work ivu_timer;

View file

@ -37,6 +37,7 @@
#include "proxy.h"
#include "settings.h"
#include "lpn.h"
#include "cfg.h"
/* Tracking of what storage changes are pending for App and Net Keys. We
* track this in a separate array here instead of within the respective
@ -160,14 +161,6 @@ static struct node_update cdb_node_updates[0];
static struct key_update cdb_key_updates[0];
#endif
/* We need this so we don't overwrite app-hardcoded values in case FCB
* contains a history of changes but then has a NULL at the end.
*/
static struct {
bool valid;
struct cfg_val cfg;
} stored_cfg;
static inline int mesh_x_set(settings_read_cb read_cb, void *cb_arg, void *out,
size_t read_len)
{
@ -430,28 +423,27 @@ static int hb_pub_set(const char *name, size_t len_rd,
static int cfg_set(const char *name, size_t len_rd,
settings_read_cb read_cb, void *cb_arg)
{
struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get();
struct cfg_val cfg;
int err;
if (!cfg) {
return -ENOENT;
}
if (len_rd == 0) {
stored_cfg.valid = false;
BT_DBG("Cleared configuration state");
return 0;
}
err = mesh_x_set(read_cb, cb_arg, &stored_cfg.cfg,
sizeof(stored_cfg.cfg));
err = mesh_x_set(read_cb, cb_arg, &cfg, sizeof(cfg));
if (err) {
BT_ERR("Failed to set \'cfg\'");
return err;
}
stored_cfg.valid = true;
bt_mesh_net_transmit_set(cfg.net_transmit);
bt_mesh_relay_set(cfg.relay, cfg.relay_retransmit);
bt_mesh_beacon_set(cfg.beacon);
bt_mesh_gatt_proxy_set(cfg.gatt_proxy);
bt_mesh_friend_set(cfg.frnd);
bt_mesh_default_ttl_set(cfg.default_ttl);
BT_DBG("Restored configuration state");
return 0;
@ -994,8 +986,6 @@ static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
static int mesh_commit(void)
{
struct bt_mesh_cfg_srv *cfg;
if (!bt_mesh_subnet_next(NULL)) {
/* Nothing to do since we're not yet provisioned */
return 0;
@ -1011,17 +1001,6 @@ static int mesh_commit(void)
bt_mesh_model_foreach(commit_mod, NULL);
cfg = bt_mesh_cfg_get();
if (cfg && stored_cfg.valid) {
cfg->net_transmit = stored_cfg.cfg.net_transmit;
cfg->relay = stored_cfg.cfg.relay;
cfg->relay_retransmit = stored_cfg.cfg.relay_retransmit;
cfg->beacon = stored_cfg.cfg.beacon;
cfg->gatt_proxy = stored_cfg.cfg.gatt_proxy;
cfg->frnd = stored_cfg.cfg.frnd;
cfg->default_ttl = stored_cfg.cfg.default_ttl;
}
atomic_set_bit(bt_mesh.flags, BT_MESH_VALID);
bt_mesh_start();
@ -1252,21 +1231,16 @@ static void store_pending_hb_pub(void)
static void store_pending_cfg(void)
{
struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get();
struct cfg_val val;
int err;
if (!cfg) {
return;
}
val.net_transmit = cfg->net_transmit;
val.relay = cfg->relay;
val.relay_retransmit = cfg->relay_retransmit;
val.beacon = cfg->beacon;
val.gatt_proxy = cfg->gatt_proxy;
val.frnd = cfg->frnd;
val.default_ttl = cfg->default_ttl;
val.net_transmit = bt_mesh_net_transmit_get();
val.relay = bt_mesh_relay_get();
val.relay_retransmit = bt_mesh_relay_retransmit_get();
val.beacon = bt_mesh_beacon_enabled();
val.gatt_proxy = bt_mesh_gatt_proxy_get();
val.frnd = bt_mesh_friend_get();
val.default_ttl = bt_mesh_default_ttl_get();
err = settings_save_one("bt/mesh/Cfg", &val, sizeof(val));
if (err) {

View file

@ -49,27 +49,6 @@ static struct {
.dst = BT_MESH_ADDR_UNASSIGNED,
};
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_RELAY_DISABLED,
.beacon = BT_MESH_BEACON_DISABLED,
#if defined(CONFIG_BT_MESH_FRIEND)
.frnd = BT_MESH_FRIEND_DISABLED,
#else
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BT_MESH_GATT_PROXY)
.gatt_proxy = BT_MESH_GATT_PROXY_DISABLED,
#else
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
#endif
.default_ttl = 7,
/* 3 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
};
#define CUR_FAULTS_MAX 4
static uint8_t cur_faults[CUR_FAULTS_MAX];
@ -192,7 +171,7 @@ static struct bt_mesh_health_cli health_cli = {
static uint8_t dev_uuid[16] = { 0xdd, 0xdd };
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
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),

View file

@ -24,6 +24,8 @@ CONFIG_BT_L2CAP_TX_MTU=69
CONFIG_BT_MESH=y
CONFIG_BT_MESH_RELAY=y
CONFIG_BT_MESH_RELAY_ENABLED=n
CONFIG_BT_MESH_BEACON_ENABLED=n
CONFIG_BT_MESH_LOW_POWER=n
CONFIG_BT_MESH_FRIEND=n

View file

@ -17,30 +17,6 @@
static bool has_reg_fault = true;
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_RELAY_DISABLED,
.beacon = BT_MESH_BEACON_DISABLED,
#if defined(CONFIG_BT_MESH_FRIEND)
#if defined(CONFIG_BT_MESH_LOW_POWER)
.frnd = BT_MESH_FRIEND_DISABLED,
#else
.frnd = BT_MESH_FRIEND_ENABLED,
#endif
#else
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BT_MESH_GATT_PROXY)
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
#endif
.default_ttl = 7,
/* 3 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
};
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)
{
@ -117,7 +93,7 @@ static struct bt_mesh_health_srv health_srv = {
BT_MESH_HEALTH_PUB_DEFINE(health_pub, MAX_FAULT);
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
};

View file

@ -100,26 +100,6 @@ static void supported_commands(uint8_t *data, uint16_t len)
CONTROLLER_INDEX, buf->data, buf->len);
}
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_RELAY_ENABLED,
.beacon = BT_MESH_BEACON_ENABLED,
#if defined(CONFIG_BT_MESH_FRIEND)
.frnd = BT_MESH_FRIEND_ENABLED,
#else
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BT_MESH_GATT_PROXY)
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
#endif
.default_ttl = 7,
/* 3 transmissions with 20ms interval */
.net_transmit = BT_MESH_TRANSMIT(2, 20),
.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
};
static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count)
{
uint8_t i, limit = *count;
@ -233,7 +213,7 @@ static struct bt_mesh_health_cli health_cli = {
};
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
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),