Merge pull request #142 from michal-narajowski/mesh-storage-port

Mesh sync with Zephyr (persistent storage)
This commit is contained in:
Michał Narajowski
2018-07-18 10:35:23 +02:00
committed by GitHub
34 changed files with 2460 additions and 286 deletions
+9 -1
View File
@@ -136,7 +136,7 @@ fault_test(struct bt_mesh_model *model, uint8_t test_id, uint16_t company_id)
recent_test_id = test_id;
has_reg_fault = true;
bt_mesh_fault_update(model->elem);
bt_mesh_fault_update(bt_mesh_model_elem(model));
return 0;
}
@@ -405,6 +405,14 @@ blemesh_on_sync(void)
#endif
console_printf("Mesh initialized\n");
if (IS_ENABLED(CONFIG_SETTINGS)) {
settings_load();
}
if (bt_mesh_is_provisioned()) {
printk("Mesh network restored from flash\n");
}
}
int
+3
View File
@@ -46,3 +46,6 @@ syscfg.vals:
BLE_MESH_DEBUG_LOW_POWER: 1
BLE_MESH_DEBUG_FRIEND: 1
BLE_MESH_DEBUG_PROXY: 1
BLE_MESH_SETTINGS: 0
CONFIG_NFFS: 0
+8
View File
@@ -98,6 +98,14 @@ blemesh_on_sync(void)
console_printf("Mesh initialized\n");
if (IS_ENABLED(CONFIG_SETTINGS)) {
settings_load();
}
if (bt_mesh_is_provisioned()) {
printk("Mesh network restored from flash\n");
}
/* Hack for demo purposes */
bt_test_shell_init();
}
+3
View File
@@ -50,6 +50,9 @@ syscfg.vals:
BLE_MESH_SHELL_MODELS: 1
BLE_MESH_TESTING: 1
BLE_MESH_OOB_OUTPUT_ACTIONS: 0
BLE_MESH_SETTINGS: 0
CONFIG_NFFS: 0
USE_NEOPIXEL: 0
syscfg.vals.BLE_MESH_SHELL_MODELS:
+2
View File
@@ -50,6 +50,8 @@ syscfg.vals:
BLE_MESH_TESTING: 1
BLE_MESH_FRIEND: 1
BLE_MESH_CFG_CLI: 1
BLE_MESH_SETTINGS: 0
CONFIG_NFFS: 0
BLE_MESH_DEBUG: 0
BLE_MESH_DEBUG_NET: 0
+18 -4
View File
@@ -130,6 +130,9 @@ struct bt_mesh_msg_ctx {
/** Remote address. */
u16_t addr;
/** Destination address of a received message. Not used for sending. */
u16_t recv_dst;
/** Received TTL value. Not used for sending. */
u8_t recv_ttl:7;
@@ -194,8 +197,8 @@ struct bt_mesh_model_op {
* @brief Encode transmission count & interval steps.
*
* @param count Number of retransmissions (first transmission is excluded).
* @param int_ms Interval steps in milliseconds. Must be greater than 0
* and a multiple of 10.
* @param int_ms Interval steps in milliseconds. Must be greater than 0,
* less than or equal to 320, and a multiple of 10.
*
* @return Mesh transmit value that can be used e.g. for the default
* values of the configuration model data.
@@ -320,8 +323,10 @@ struct bt_mesh_model {
} vnd;
};
/* The Element this Model belongs to */
struct bt_mesh_elem *elem;
/* Internal information, mainly for persistent storage */
u8_t elem_idx; /* Belongs to Nth element */
u8_t mod_idx; /* Is the Nth model in the element */
u16_t flags; /* Information about what has changed */
/* Model Publication */
struct bt_mesh_model_pub * const pub;
@@ -384,6 +389,15 @@ int bt_mesh_model_send(struct bt_mesh_model *model,
*/
int bt_mesh_model_publish(struct bt_mesh_model *model);
/**
* @brief Get the element that a model belongs to.
*
* @param mod Mesh model.
*
* @return Pointer to the element that the given model belongs to.
*/
struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod);
/** Node Composition */
struct bt_mesh_comp {
u16_t cid;
+2 -2
View File
@@ -30,7 +30,7 @@ struct bt_mesh_cfg_srv {
u8_t default_ttl; /* Default TTL */
/* Heartbeat Publication */
struct {
struct bt_mesh_hb_pub {
struct k_delayed_work timer;
u16_t dst;
@@ -42,7 +42,7 @@ struct bt_mesh_cfg_srv {
} hb_pub;
/* Heartbeat Subscription */
struct {
struct bt_mesh_hb_sub {
s64_t expiry;
u16_t src;
+27 -1
View File
@@ -41,6 +41,8 @@
#include "tinycrypt/cmac_mode.h"
#include "tinycrypt/ecc_dh.h"
#include "config/config.h"
#define u8_t uint8_t
#define s8_t int8_t
#define u16_t uint16_t
@@ -334,9 +336,9 @@ static inline unsigned int find_msb_set(u32_t op)
return 32 - __builtin_clz(op);
}
#define CONFIG_BLUETOOTH_MESH_FRIEND BLE_MESH_FRIEND
#define CONFIG_BT_MESH_FRIEND BLE_MESH_FRIEND
#define CONFIG_BT_MESH_GATT_PROXY BLE_MESH_GATT_PROXY
#define CONFIG_BT_MESH_IV_UPDATE_TEST BLE_MESH_IV_UPDATE_TEST
#define CONFIG_BT_MESH_LOW_POWER BLE_MESH_LOW_POWER
#define CONFIG_BT_MESH_LPN_AUTO BLE_MESH_LPN_AUTO
#define CONFIG_BT_MESH_LPN_ESTABLISHMENT BLE_MESH_LPN_ESTABLISHMENT
@@ -344,6 +346,9 @@ static inline unsigned int find_msb_set(u32_t op)
#define CONFIG_BT_MESH_PB_GATT BLE_MESH_PB_GATT
#define CONFIG_BT_MESH_PROV BLE_MESH_PROV
#define CONFIG_BT_TESTING BLE_MESH_TESTING
#define CONFIG_BT_SETTINGS BLE_MESH_SETTINGS
#define CONFIG_SETTINGS BLE_MESH_SETTINGS
#define BT_SETTINGS BLE_MESH_SETTINGS
/* Above flags are used with IS_ENABLED macro */
#define IS_ENABLED(config) MYNEWT_VAL(config)
@@ -357,6 +362,12 @@ static inline unsigned int find_msb_set(u32_t op)
#define CONFIG_BT_MESH_MODEL_KEY_COUNT MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT)
#define CONFIG_BT_MESH_NODE_ID_TIMEOUT MYNEWT_VAL(BLE_MESH_NODE_ID_TIMEOUT)
#define CONFIG_BT_MAX_CONN MYNEWT_VAL(BLE_MAX_CONNECTIONS)
#define CONFIG_BT_MESH_SEQ_STORE_RATE MYNEWT_VAL(BLE_MESH_SEQ_STORE_RATE)
#define CONFIG_BT_MESH_RPL_STORE_TIMEOUT MYNEWT_VAL(BLE_MESH_RPL_STORE_TIMEOUT)
#define CONFIG_BT_MESH_APP_KEY_COUNT MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT)
#define CONFIG_BT_MESH_SUBNET_COUNT MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)
#define CONFIG_BT_MESH_STORE_TIMEOUT MYNEWT_VAL(BLE_MESH_STORE_TIMEOUT)
#define CONFIG_BT_MESH_IVU_DIVIDER MYNEWT_VAL(BLE_MESH_IVU_DIVIDER)
#define CONFIG_BT_DEVICE_NAME "nimble-mesh"
#define printk console_printf
@@ -419,4 +430,19 @@ void net_buf_slist_merge_slist(struct net_buf_slist_t *list,
struct net_buf_slist_t *list_to_append);
#define NET_BUF_SLIST_FOR_EACH_NODE(head, var) STAILQ_FOREACH(var, head, omp_next)
/**
* Load serialized items from registered persistence sources. Handlers for
* serialized item subtrees registered earlier will be called for encountered
* values.
*
* @return 0 on success, non-zero on failure.
*/
#define settings_load conf_load
int settings_bytes_from_str(char *val_str, void *vp, int *len);
char *settings_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len);
#define snprintk snprintf
#define BT_SETTINGS_SIZE(in_size) ((((((in_size) - 1) / 3) * 4) + 4) + 1)
#define settings_save_one conf_save_one
#endif
+13 -3
View File
@@ -287,15 +287,25 @@ void bt_mesh_reset(void);
* @param net_idx Network Key Index
* @param flags Provisioning Flags
* @param iv_index IV Index
* @param seq Sequence Number (0 if newly provisioned).
* @param addr Primary element address
* @param dev_key Device Key
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
u8_t flags, u32_t iv_index, u32_t seq,
u16_t addr, const u8_t dev_key[16]);
u8_t flags, u32_t iv_index, u16_t addr,
const u8_t dev_key[16]);
/** @brief Check if the local node has been provisioned.
*
* This API can be used to check if the local node has been provisioned
* or not. It can e.g. be helpful to determine if there was a stored
* network in flash, i.e. if the network was restored after calling
* settings_load().
*
* @return True if the node is provisioned. False otherwise.
*/
bool bt_mesh_is_provisioned(void);
/** @brief Toggle the IV Update test mode
*
-9
View File
@@ -19,17 +19,8 @@
#include "main.h"
#include "cfg_srv.h"
#include "health_srv.h"
#if MYNEWT_VAL(BLE_MESH_CFG_CLI)
#include "cfg_cli.h"
#endif
#if MYNEWT_VAL(BLE_MESH_HEALTH_CLI)
#include "health_cli.h"
#endif
#if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
#include "proxy.h"
#endif
#endif /* __BT_MESH_H */
+1 -1
View File
@@ -58,7 +58,7 @@ void bt_test_cb_register(struct bt_test_cb *cb);
void bt_test_cb_unregister(struct bt_test_cb *cb);
u8_t mod_bind(struct bt_mesh_model *model, u16_t key_idx);
u8_t mod_unbind(struct bt_mesh_model *model, u16_t key_idx);
u8_t mod_unbind(struct bt_mesh_model *model, u16_t key_idx, bool store);
int cmd_mesh_init(int argc, char *argv[]);
int bt_test_shell_init(void);
+2
View File
@@ -30,6 +30,8 @@ pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/util/mem"
- "@apache-mynewt-core/crypto/tinycrypt"
- "@apache-mynewt-core/encoding/base64"
- "@apache-mynewt-core/sys/config"
- nimble
- nimble/host
+53 -13
View File
@@ -161,7 +161,7 @@ static int publish_retransmit(struct bt_mesh_model *mod)
};
struct bt_mesh_net_tx tx = {
.ctx = &ctx,
.src = mod->elem->addr,
.src = bt_mesh_model_elem(mod)->addr,
.xmit = bt_mesh_net_transmit_get(),
.friend_cred = pub->cred,
};
@@ -242,13 +242,44 @@ static void mod_publish(struct ble_npl_event *work)
}
}
struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod)
{
return &dev_comp->elem[mod->elem_idx];
}
struct bt_mesh_model *bt_mesh_model_get(bool vnd, u8_t elem_idx, u8_t mod_idx)
{
struct bt_mesh_elem *elem;
if (elem_idx >= dev_comp->elem_count) {
BT_ERR("Invalid element index %u", elem_idx);
return NULL;
}
elem = &dev_comp->elem[elem_idx];
if (vnd) {
if (mod_idx >= elem->vnd_model_count) {
BT_ERR("Invalid vendor model index %u", mod_idx);
return NULL;
}
return &elem->vnd_models[mod_idx];
} else {
if (mod_idx >= elem->model_count) {
BT_ERR("Invalid SIG model index %u", mod_idx);
return NULL;
}
return &elem->models[mod_idx];
}
}
static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
bool vnd, bool primary, void *user_data)
{
int i;
mod->elem = elem;
if (mod->pub) {
mod->pub->mod = mod;
k_delayed_work_init(&mod->pub->timer, mod_publish);
@@ -259,6 +290,13 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
mod->keys[i] = BT_MESH_KEY_UNUSED;
}
mod->elem_idx = elem - dev_comp->elem;
if (vnd) {
mod->mod_idx = mod - elem->vnd_models;
} else {
mod->mod_idx = mod - elem->models;
}
if (vnd) {
return;
}
@@ -490,7 +528,7 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf)
int i;
BT_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx,
rx->ctx.addr, rx->dst);
rx->ctx.addr, rx->ctx.recv_dst);
BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len));
if (get_opcode(buf, &opcode) < 0) {
@@ -503,14 +541,15 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf)
for (i = 0; i < dev_comp->elem_count; i++) {
struct bt_mesh_elem *elem = &dev_comp->elem[i];
if (BT_MESH_ADDR_IS_UNICAST(rx->dst)) {
if (elem->addr != rx->dst) {
if (BT_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst)) {
if (elem->addr != rx->ctx.recv_dst) {
continue;
}
} else if (BT_MESH_ADDR_IS_GROUP(rx->dst) ||
BT_MESH_ADDR_IS_VIRTUAL(rx->dst)) {
/* find_op will find the correct model for the group */
} else if (i != 0 || !bt_mesh_fixed_group_match(rx->dst)) {
} else if (BT_MESH_ADDR_IS_GROUP(rx->ctx.recv_dst) ||
BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) {
/* find_op() will do proper model/group matching */
} else if (i != 0 ||
!bt_mesh_fixed_group_match(rx->ctx.recv_dst)) {
continue;
}
@@ -526,7 +565,8 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf)
count = elem->vnd_model_count;
}
op = find_op(models, count, rx->dst, rx->ctx.app_idx, opcode, &model);
op = find_op(models, count, rx->ctx.recv_dst, rx->ctx.app_idx,
opcode, &model);
if (op) {
struct net_buf_simple_state state;
@@ -611,7 +651,7 @@ int bt_mesh_model_send(struct bt_mesh_model *model,
struct bt_mesh_net_tx tx = {
.sub = bt_mesh_subnet_get(ctx->net_idx),
.ctx = ctx,
.src = model->elem->addr,
.src = bt_mesh_model_elem(model)->addr,
.xmit = bt_mesh_net_transmit_get(),
.friend_cred = 0,
};
@@ -628,7 +668,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model)
};
struct bt_mesh_net_tx tx = {
.ctx = &ctx,
.src = model->elem->addr,
.src = bt_mesh_model_elem(model)->addr,
.xmit = bt_mesh_net_transmit_get(),
};
int err;
+9
View File
@@ -11,6 +11,13 @@
#include "mesh/mesh.h"
/* bt_mesh_model.flags */
enum {
BT_MESH_MOD_BIND_PENDING = BIT(0),
BT_MESH_MOD_SUB_PENDING = BIT(1),
BT_MESH_MOD_PUB_PENDING = BIT(2),
};
void bt_mesh_elem_register(struct bt_mesh_elem *elem, u8_t count);
u8_t bt_mesh_elem_count(void);
@@ -42,6 +49,8 @@ u16_t bt_mesh_primary_addr(void);
const struct bt_mesh_comp *bt_mesh_comp_get(void);
struct bt_mesh_model *bt_mesh_model_get(bool vnd, u8_t elem_idx, u8_t mod_idx);
void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf);
int bt_mesh_comp_register(const struct bt_mesh_comp *comp);
+17 -14
View File
@@ -19,8 +19,8 @@
#include "mesh/porting.h"
#include "adv.h"
#include "foundation.h"
#include "net.h"
#include "foundation.h"
#include "beacon.h"
#include "prov.h"
#include "proxy.h"
@@ -99,17 +99,20 @@ static inline void adv_send(struct os_mbuf *buf)
void *cb_data = BT_MESH_ADV(buf)->cb_data;
struct ble_gap_adv_params param = { 0 };
u16_t duration, adv_int;
struct bt_mesh_adv *adv = BT_MESH_ADV(buf);
struct bt_data ad;
int err;
adv_int = max(adv_int_min, adv->adv_int);
duration = MESH_SCAN_WINDOW_MS + (adv->count + 1) * (adv_int + 10);
adv_int = max(adv_int_min,
BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit));
duration = (MESH_SCAN_WINDOW_MS +
((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) *
(adv_int + 10)));
BT_DBG("buf %p, type %u len %u:", buf, adv->type,
buf->om_len);
BT_DBG("type %u om_len %u: %s", BT_MESH_ADV(buf)->type,
buf->om_len, bt_hex(buf->om_data, buf->om_len));
BT_DBG("count %u interval %ums duration %ums",
adv->count + 1, adv_int, duration);
BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1, adv_int,
duration);
ad.type = adv_type[BT_MESH_ADV(buf)->type];
ad.data_len = buf->om_len;
@@ -199,8 +202,7 @@ void bt_mesh_adv_update(void)
struct os_mbuf *bt_mesh_adv_create_from_pool(struct os_mbuf_pool *pool,
bt_mesh_adv_alloc_t get_id,
enum bt_mesh_adv_type type,
u8_t xmit_count, u8_t xmit_int,
s32_t timeout)
u8_t xmit, s32_t timeout)
{
struct bt_mesh_adv *adv;
struct os_mbuf *buf;
@@ -216,18 +218,19 @@ struct os_mbuf *bt_mesh_adv_create_from_pool(struct os_mbuf_pool *pool,
memset(adv, 0, sizeof(*adv));
adv->type = type;
adv->count = xmit_count;
adv->adv_int = xmit_int;
adv->xmit = xmit;
adv->ref_cnt = 1;
ble_npl_event_set_arg(&adv->ev, buf);
return buf;
}
struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count,
u8_t xmit_int, s32_t timeout)
struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
s32_t timeout)
{
return bt_mesh_adv_create_from_pool(&adv_os_mbuf_pool, adv_alloc, type,
xmit_count, xmit_int, timeout);
xmit, timeout);
}
void bt_mesh_adv_send(struct os_mbuf *buf, const struct bt_mesh_send_cb *cb,
+5 -6
View File
@@ -40,8 +40,8 @@ struct bt_mesh_adv {
u8_t type:2,
busy:1;
u8_t count:3,
adv_int:5;
u8_t xmit;
union {
/* Address, used e.g. for Friend Queue messages */
u16_t addr;
@@ -59,14 +59,13 @@ struct bt_mesh_adv {
typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id);
/* xmit_count: Number of retransmissions, i.e. 0 == 1 transmission */
struct os_mbuf * bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count,
u8_t xmit_int, s32_t timeout);
struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
s32_t timeout);
struct os_mbuf *bt_mesh_adv_create_from_pool(struct os_mbuf_pool *pool,
bt_mesh_adv_alloc_t get_id,
enum bt_mesh_adv_type type,
u8_t xmit_count, u8_t xmit_int,
s32_t timeout);
u8_t xmit, s32_t timeout);
void bt_mesh_adv_send(struct os_mbuf *buf, const struct bt_mesh_send_cb *cb,
void *cb_data);
+7 -10
View File
@@ -30,12 +30,10 @@
#define BEACON_TYPE_SECURE 0x01
/* 3 transmissions, 20ms interval */
#define UNPROV_XMIT_COUNT 2
#define UNPROV_XMIT_INT 20
#define UNPROV_XMIT BT_MESH_TRANSMIT(2, 20)
/* 1 transmission, 20ms interval */
#define PROV_XMIT_COUNT 0
#define PROV_XMIT_INT 20
#define PROV_XMIT BT_MESH_TRANSMIT(0, 20)
static struct k_delayed_work beacon_timer;
@@ -131,8 +129,8 @@ static int secure_beacon_send(void)
continue;
}
buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, PROV_XMIT_COUNT,
PROV_XMIT_INT, K_NO_WAIT);
buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, PROV_XMIT,
K_NO_WAIT);
if (!buf) {
BT_ERR("Unable to allocate beacon buffer");
return -ENOBUFS;
@@ -157,8 +155,7 @@ static int unprovisioned_beacon_send(void)
BT_DBG("unprovisioned_beacon_send");
buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, UNPROV_XMIT_COUNT,
UNPROV_XMIT_INT, K_NO_WAIT);
buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, UNPROV_XMIT, K_NO_WAIT);
if (!buf) {
BT_ERR("Unable to allocate beacon buffer");
return -ENOBUFS;
@@ -184,8 +181,8 @@ static int unprovisioned_beacon_send(void)
if (prov->uri) {
size_t len;
buf = bt_mesh_adv_create(BT_MESH_ADV_URI, UNPROV_XMIT_COUNT,
UNPROV_XMIT_INT, K_NO_WAIT);
buf = bt_mesh_adv_create(BT_MESH_ADV_URI, UNPROV_XMIT,
K_NO_WAIT);
if (!buf) {
BT_ERR("Unable to allocate URI buffer");
return -ENOBUFS;
+1
View File
@@ -16,6 +16,7 @@
#include <errno.h>
#include <stdbool.h>
#include "net.h"
#include "foundation.h"
#define CID_NVAL 0xffff
+302 -57
View File
@@ -28,6 +28,7 @@
#include "foundation.h"
#include "friend.h"
#include "testing.h"
#include "settings.h"
#define DEFAULT_TTL 7
@@ -57,7 +58,7 @@ static void hb_send(struct bt_mesh_model *model)
struct bt_mesh_net_tx tx = {
.sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx),
.ctx = &ctx,
.src = model->elem->addr,
.src = bt_mesh_model_elem(model)->addr,
.xmit = bt_mesh_net_transmit_get(),
};
@@ -241,7 +242,7 @@ static bool app_key_is_valid(u16_t app_idx)
static u8_t _mod_pub_set(struct bt_mesh_model *model, u16_t pub_addr,
u16_t app_idx, u8_t cred_flag, u8_t ttl, u8_t period,
u8_t retransmit)
u8_t retransmit, bool store)
{
if (!model->pub) {
return STATUS_NVAL_PUB_PARAM;
@@ -256,6 +257,10 @@ static u8_t _mod_pub_set(struct bt_mesh_model *model, u16_t pub_addr,
}
if (pub_addr == BT_MESH_ADDR_UNASSIGNED) {
if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
return STATUS_SUCCESS;
}
model->pub->addr = BT_MESH_ADDR_UNASSIGNED;
model->pub->key = 0;
model->pub->cred = 0;
@@ -268,6 +273,10 @@ static u8_t _mod_pub_set(struct bt_mesh_model *model, u16_t pub_addr,
k_delayed_work_cancel(&model->pub->timer);
}
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
bt_mesh_store_mod_pub(model);
}
return STATUS_SUCCESS;
}
@@ -295,6 +304,10 @@ static u8_t _mod_pub_set(struct bt_mesh_model *model, u16_t pub_addr,
}
}
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
bt_mesh_store_mod_pub(model);
}
return STATUS_SUCCESS;
}
@@ -302,7 +315,7 @@ u8_t mod_bind(struct bt_mesh_model *model, u16_t key_idx)
{
int i;
BT_DBG("key_idx 0x%04x", key_idx);
BT_DBG("model %p key_idx 0x%03x", model, key_idx);
if (!app_key_is_valid(key_idx)) {
return STATUS_INVALID_APPKEY;
@@ -318,6 +331,11 @@ u8_t mod_bind(struct bt_mesh_model *model, u16_t key_idx)
for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
if (model->keys[i] == BT_MESH_KEY_UNUSED) {
model->keys[i] = key_idx;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_mod_bind(model);
}
return STATUS_SUCCESS;
}
}
@@ -325,11 +343,11 @@ u8_t mod_bind(struct bt_mesh_model *model, u16_t key_idx)
return STATUS_INSUFF_RESOURCES;
}
u8_t mod_unbind(struct bt_mesh_model *model, u16_t key_idx)
u8_t mod_unbind(struct bt_mesh_model *model, u16_t key_idx, bool store)
{
int i;
BT_DBG("model %p key_idx 0x%04x", model, key_idx);
BT_DBG("model %p key_idx 0x%03x store %u", model, key_idx, store);
if (!app_key_is_valid(key_idx)) {
return STATUS_INVALID_APPKEY;
@@ -342,16 +360,20 @@ u8_t mod_unbind(struct bt_mesh_model *model, u16_t key_idx)
model->keys[i] = BT_MESH_KEY_UNUSED;
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
bt_mesh_store_mod_bind(model);
}
if (model->pub && model->pub->key == key_idx) {
_mod_pub_set(model, BT_MESH_ADDR_UNASSIGNED,
0, 0, 0, 0, 0);
0, 0, 0, 0, 0, store);
}
}
return STATUS_SUCCESS;
}
static struct bt_mesh_app_key *app_key_alloc(u16_t app_idx)
struct bt_mesh_app_key *bt_mesh_app_key_alloc(u16_t app_idx)
{
int i;
@@ -425,7 +447,7 @@ static u8_t app_key_set(u16_t net_idx, u16_t app_idx, const u8_t val[16],
}
}
key = app_key_alloc(app_idx);
key = bt_mesh_app_key_alloc(app_idx);
if (!key) {
return STATUS_INSUFF_RESOURCES;
}
@@ -447,6 +469,11 @@ static u8_t app_key_set(u16_t net_idx, u16_t app_idx, const u8_t val[16],
key->app_idx = app_idx;
memcpy(keys->val, val, 16);
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
BT_DBG("Storing AppKey persistently");
bt_mesh_store_app_key(key);
}
return STATUS_SUCCESS;
}
@@ -504,17 +531,30 @@ static void app_key_update(struct bt_mesh_model *model,
os_mbuf_free_chain(msg);
}
struct unbind_data {
u16_t app_idx;
bool store;
};
static void _mod_unbind(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
bool vnd, bool primary, void *user_data)
{
u16_t *key_idx = user_data;
struct unbind_data *data = user_data;
mod_unbind(mod, *key_idx);
mod_unbind(mod, data->app_idx, data->store);
}
static void _app_key_del(struct bt_mesh_app_key *key)
void bt_mesh_app_key_del(struct bt_mesh_app_key *key, bool store)
{
bt_mesh_model_foreach(_mod_unbind, &key->app_idx);
struct unbind_data data = { .app_idx = key->app_idx, .store = store };
BT_DBG("AppIdx 0x%03x store %u", key->app_idx, store);
bt_mesh_model_foreach(_mod_unbind, &data);
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
bt_mesh_clear_app_key(key);
}
key->net_idx = BT_MESH_KEY_UNUSED;
memset(key->keys, 0, sizeof(key->keys));
@@ -552,7 +592,7 @@ static void app_key_del(struct bt_mesh_model *model,
goto send_status;
}
_app_key_del(key);
bt_mesh_app_key_del(key, true);
status = STATUS_SUCCESS;
send_status:
@@ -673,6 +713,10 @@ static void beacon_set(struct bt_mesh_model *model,
if (buf->om_data[0] != cfg->beacon) {
cfg->beacon = buf->om_data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
if (cfg->beacon) {
bt_mesh_beacon_enable();
} else {
@@ -732,7 +776,13 @@ static void default_ttl_set(struct bt_mesh_model *model,
if (!cfg) {
BT_WARN("No Configuration Server context available");
} else if (buf->om_data[0] <= BT_MESH_TTL_MAX && buf->om_data[0] != 0x01) {
cfg->default_ttl = buf->om_data[0];
if (cfg->default_ttl != buf->om_data[0]) {
cfg->default_ttl = buf->om_data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
}
} else {
BT_WARN("Prohibited Default TTL value 0x%02x", buf->om_data[0]);
goto done;
@@ -810,6 +860,11 @@ static void gatt_proxy_set(struct bt_mesh_model *model,
}
cfg->gatt_proxy = buf->om_data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
if (cfg->gatt_proxy == BT_MESH_GATT_PROXY_DISABLED) {
int i;
@@ -885,6 +940,10 @@ static void net_transmit_set(struct bt_mesh_model *model,
BT_WARN("No Configuration Server context available");
} else {
cfg->net_transmit = buf->om_data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
}
bt_mesh_model_msg_init(msg, OP_NET_TRANSMIT_STATUS);
@@ -944,6 +1003,10 @@ static void relay_set(struct bt_mesh_model *model,
change = (cfg->relay != buf->om_data[0]);
cfg->relay = buf->om_data[0];
cfg->relay_retransmit = buf->om_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)",
@@ -1026,6 +1089,11 @@ static void mod_pub_get(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
mod_id = buf->om_data;
BT_DBG("elem_addr 0x%04x", elem_addr);
@@ -1069,6 +1137,11 @@ static void mod_pub_set(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
pub_addr = net_buf_simple_pull_le16(buf);
pub_app_idx = net_buf_simple_pull_le16(buf);
cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1));
@@ -1107,7 +1180,7 @@ static void mod_pub_set(struct bt_mesh_model *model,
}
status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag, pub_ttl,
pub_period, retransmit);
pub_period, retransmit, true);
send_status:
send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
@@ -1207,6 +1280,11 @@ static void mod_pub_va_set(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
label_uuid = buf->om_data;
net_buf_simple_pull(buf, 16);
@@ -1250,7 +1328,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model,
status = va_add(label_uuid, &pub_addr);
if (status == STATUS_SUCCESS) {
status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag,
pub_ttl, pub_period, retransmit);
pub_ttl, pub_period, retransmit, true);
}
send_status:
@@ -1275,6 +1353,11 @@ static void mod_pub_va_set(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
net_buf_simple_pull(buf, 16);
mod_id = net_buf_simple_pull(buf, 4);
@@ -1351,6 +1434,11 @@ static void mod_sub_add(struct bt_mesh_model *model,
int i;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
sub_addr = net_buf_simple_pull_le16(buf);
BT_DBG("elem_addr 0x%04x, sub_addr 0x%04x", elem_addr, sub_addr);
@@ -1394,7 +1482,11 @@ static void mod_sub_add(struct bt_mesh_model *model,
} else {
status = STATUS_SUCCESS;
if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) {
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_mod_sub(mod);
}
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
bt_mesh_lpn_group_add(sub_addr);
}
}
@@ -1417,6 +1509,11 @@ static void mod_sub_del(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
sub_addr = net_buf_simple_pull_le16(buf);
BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr);
@@ -1454,6 +1551,10 @@ static void mod_sub_del(struct bt_mesh_model *model,
match = bt_mesh_model_find_group(mod, sub_addr);
if (match) {
*match = BT_MESH_ADDR_UNASSIGNED;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_mod_sub(mod);
}
}
send_status:
@@ -1473,6 +1574,11 @@ static void mod_sub_overwrite(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
sub_addr = net_buf_simple_pull_le16(buf);
BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr);
@@ -1508,7 +1614,11 @@ static void mod_sub_overwrite(struct bt_mesh_model *model,
mod->groups[0] = sub_addr;
status = STATUS_SUCCESS;
if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) {
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_mod_sub(mod);
}
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
bt_mesh_lpn_group_add(sub_addr);
}
} else {
@@ -1533,6 +1643,10 @@ static void mod_sub_del_all(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
BT_DBG("elem_addr 0x%04x", elem_addr);
@@ -1558,6 +1672,10 @@ static void mod_sub_del_all(struct bt_mesh_model *model,
mod_sub_list_clear(mod);
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_mod_sub(mod);
}
status = STATUS_SUCCESS;
send_status:
@@ -1578,6 +1696,11 @@ static void mod_sub_get(struct bt_mesh_model *model,
int i;
addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
BT_WARN("Prohibited element address");
return;
}
id = net_buf_simple_pull_le16(buf);
BT_DBG("addr 0x%04x id 0x%04x", addr, id);
@@ -1633,6 +1756,11 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model,
int i;
addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
BT_WARN("Prohibited element address");
return;
}
company = net_buf_simple_pull_le16(buf);
id = net_buf_simple_pull_le16(buf);
@@ -1694,6 +1822,11 @@ static void mod_sub_va_add(struct bt_mesh_model *model,
int i;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
label_uuid = buf->om_data;
net_buf_simple_pull(buf, 16);
@@ -1741,6 +1874,10 @@ static void mod_sub_va_add(struct bt_mesh_model *model,
bt_mesh_lpn_group_add(sub_addr);
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_mod_sub(mod);
}
status = STATUS_SUCCESS;
}
@@ -1763,6 +1900,11 @@ static void mod_sub_va_del(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
label_uuid = buf->om_data;
net_buf_simple_pull(buf, 16);
@@ -1798,6 +1940,11 @@ static void mod_sub_va_del(struct bt_mesh_model *model,
match = bt_mesh_model_find_group(mod, sub_addr);
if (match) {
*match = BT_MESH_ADDR_UNASSIGNED;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_mod_sub(mod);
}
status = STATUS_SUCCESS;
} else {
status = STATUS_CANNOT_REMOVE;
@@ -1821,6 +1968,11 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
label_uuid = buf->om_data;
net_buf_simple_pull(buf, 16);
mod_id = buf->om_data;
@@ -1853,7 +2005,11 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model,
if (status == STATUS_SUCCESS) {
mod->groups[0] = sub_addr;
if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) {
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_mod_sub(mod);
}
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
bt_mesh_lpn_group_add(sub_addr);
}
}
@@ -1878,6 +2034,11 @@ static void mod_sub_va_add(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
net_buf_simple_pull(buf, 16);
mod_id = buf->om_data;
@@ -1914,6 +2075,11 @@ static void mod_sub_va_del(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
net_buf_simple_pull(buf, 16);
mod_id = buf->om_data;
@@ -1948,6 +2114,11 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
net_buf_simple_pull(buf, 18);
mod_id = buf->om_data;
@@ -2011,7 +2182,7 @@ static void net_key_add(struct bt_mesh_model *model,
if (!sub) {
int i;
for (sub = NULL, i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
if (bt_mesh.sub[i].net_idx == BT_MESH_KEY_UNUSED) {
sub = &bt_mesh.sub[i];
break;
@@ -2047,6 +2218,11 @@ static void net_key_add(struct bt_mesh_model *model,
sub->net_idx = idx;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
BT_DBG("Storing NetKey persistently");
bt_mesh_store_subnet(sub);
}
/* Make sure we have valid beacon data to be sent */
bt_mesh_net_beacon_update(sub);
@@ -2120,6 +2296,11 @@ static void net_key_update(struct bt_mesh_model *model,
sub->kr_phase = BT_MESH_KR_PHASE_1;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
BT_DBG("Storing NetKey persistently");
bt_mesh_store_subnet(sub);
}
bt_mesh_net_beacon_update(sub);
send_net_key_status(model, ctx, idx, STATUS_SUCCESS);
@@ -2141,9 +2322,8 @@ static void net_key_del(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct os_mbuf *buf)
{
struct bt_mesh_cfg_srv *cfg = model->user_data;
struct bt_mesh_subnet *sub;
u16_t del_idx, i;
u16_t del_idx;
u8_t status;
del_idx = net_buf_simple_pull_le16(buf);
@@ -2171,26 +2351,7 @@ static void net_key_del(struct bt_mesh_model *model,
goto send_status;
}
if (cfg->hb_pub.net_idx == del_idx) {
hb_pub_disable(cfg);
}
/* Delete any app keys bound to this NetKey index */
for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
if (key->net_idx == del_idx) {
_app_key_del(key);
}
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
bt_mesh_friend_clear_net_idx(del_idx);
}
memset(sub, 0, sizeof(*sub));
sub->net_idx = BT_MESH_KEY_UNUSED;
bt_mesh_subnet_del(sub, true);
status = STATUS_SUCCESS;
send_status:
@@ -2371,6 +2532,11 @@ static void mod_app_bind(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
key_app_idx = net_buf_simple_pull_le16(buf);
mod_id = buf->om_data;
@@ -2426,6 +2592,11 @@ static void mod_app_unbind(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
key_app_idx = net_buf_simple_pull_le16(buf);
mod_id = buf->om_data;
@@ -2443,7 +2614,7 @@ static void mod_app_unbind(struct bt_mesh_model *model,
goto send_status;
}
status = mod_unbind(mod, key_app_idx);
status = mod_unbind(mod, key_app_idx, true);
if (IS_ENABLED(CONFIG_BT_TESTING) && status == STATUS_SUCCESS) {
bt_test_mesh_model_unbound(ctx->addr, mod, key_app_idx);
@@ -2475,6 +2646,11 @@ static void mod_app_get(struct bt_mesh_model *model,
bool vnd;
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return;
}
mod_id = buf->om_data;
BT_DBG("elem_addr 0x%04x", elem_addr);
@@ -2610,6 +2786,10 @@ static void friend_set(struct bt_mesh_model *model,
if (MYNEWT_VAL(BLE_MESH_FRIEND)) {
cfg->frnd = buf->om_data[0];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_cfg();
}
if (cfg->frnd == BT_MESH_FRIEND_DISABLED) {
bt_mesh_friend_clear_net_idx(BT_MESH_KEY_ANY);
}
@@ -2648,7 +2828,7 @@ static void lpn_timeout_get(struct bt_mesh_model *model,
bt_mesh_model_msg_init(msg, OP_LPN_TIMEOUT_STATUS);
net_buf_simple_add_le16(msg, lpn_addr);
if (!IS_ENABLED(CONFIG_BLUETOOTH_MESH_FRIEND)) {
if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
timeout = 0;
goto send_rsp;
}
@@ -2929,6 +3109,10 @@ static void heartbeat_pub_set(struct bt_mesh_model *model,
}
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_hb_pub();
}
hb_pub_send_status(model, ctx, STATUS_SUCCESS, NULL);
return;
@@ -3191,6 +3375,7 @@ int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary)
k_delayed_work_init(&cfg->hb_pub.timer, hb_publish);
k_delayed_work_add_arg(&cfg->hb_pub.timer, cfg);
cfg->hb_pub.net_idx = BT_MESH_KEY_UNUSED;
cfg->hb_sub.expiry = 0;
cfg->model = model;
@@ -3200,6 +3385,22 @@ int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary)
return 0;
}
static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
bool vnd, bool primary, void *user_data)
{
/* Clear model state that isn't otherwise cleared. E.g. AppKey
* binding and model publication is cleared as a consequence
* of removing all app keys, however model subscription clearing
* must be taken care of here.
*/
mod_sub_list_clear(mod);
if (IS_ENABLED(BT_SETTINGS)) {
bt_mesh_store_mod_sub(mod);
}
}
void bt_mesh_cfg_reset(void)
{
struct bt_mesh_cfg_srv *cfg = conf;
@@ -3215,24 +3416,19 @@ void bt_mesh_cfg_reset(void)
cfg->hb_sub.dst = BT_MESH_ADDR_UNASSIGNED;
cfg->hb_sub.expiry = 0;
hb_pub_disable(cfg);
/* Delete all app keys */
for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
if (key->net_idx != BT_MESH_KEY_UNUSED) {
_app_key_del(key);
}
}
/* Delete all net keys, which also takes care of all app keys which
* are associated with each net key.
*/
for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
memset(sub, 0, sizeof(*sub));
sub->net_idx = BT_MESH_KEY_UNUSED;
if (sub->net_idx != BT_MESH_KEY_UNUSED) {
bt_mesh_subnet_del(sub, true);
}
}
bt_mesh_model_foreach(mod_reset, NULL);
memset(labels, 0, sizeof(labels));
}
@@ -3354,3 +3550,52 @@ u8_t *bt_mesh_label_uuid_get(u16_t addr)
return NULL;
}
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void)
{
if (!conf) {
return NULL;
}
return &conf->hb_pub;
}
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void)
{
return conf;
}
void bt_mesh_subnet_del(struct bt_mesh_subnet *sub, bool store)
{
int i;
BT_DBG("NetIdx 0x%03x store %u", sub->net_idx, store);
if (conf && conf->hb_pub.net_idx == sub->net_idx) {
hb_pub_disable(conf);
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
bt_mesh_store_hb_pub();
}
}
/* Delete any app keys bound to this NetKey index */
for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
if (key->net_idx == sub->net_idx) {
bt_mesh_app_key_del(key, store);
}
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
bt_mesh_friend_clear_net_idx(sub->net_idx);
}
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
bt_mesh_clear_subnet(sub);
}
memset(sub, 0, sizeof(*sub));
sub->net_idx = BT_MESH_KEY_UNUSED;
}
+8
View File
@@ -129,6 +129,9 @@ void bt_mesh_attention(struct bt_mesh_model *model, u8_t time);
u8_t *bt_mesh_label_uuid_get(u16_t addr);
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void);
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void);
u8_t bt_mesh_net_transmit_get(void);
u8_t bt_mesh_relay_get(void);
u8_t bt_mesh_friend_get(void);
@@ -137,6 +140,11 @@ u8_t bt_mesh_beacon_get(void);
u8_t bt_mesh_gatt_proxy_get(void);
u8_t bt_mesh_default_ttl_get(void);
void bt_mesh_subnet_del(struct bt_mesh_subnet *sub, bool store);
struct bt_mesh_app_key *bt_mesh_app_key_alloc(u16_t app_idx);
void bt_mesh_app_key_del(struct bt_mesh_app_key *key, bool store);
static inline void key_idx_pack(struct os_mbuf *buf,
u16_t idx1, u16_t idx2)
{
+17 -13
View File
@@ -47,8 +47,7 @@ static struct os_mempool friend_buf_mempool;
/* PDUs from Friend to the LPN should only be transmitted once with the
* smallest possible interval (20ms).
*/
#define FRIEND_XMIT_COUNT 0
#define FRIEND_XMIT_INT 20
#define FRIEND_XMIT BT_MESH_TRANSMIT(0, 20)
struct friend_pdu_info {
u16_t src;
@@ -98,8 +97,7 @@ static struct os_mbuf *friend_buf_alloc(u16_t src)
do {
buf = bt_mesh_adv_create_from_pool(&friend_os_mbuf_pool, adv_alloc,
BT_MESH_ADV_DATA,
FRIEND_XMIT_COUNT,
FRIEND_XMIT_INT, K_NO_WAIT);
FRIEND_XMIT, K_NO_WAIT);
if (!buf) {
discard_buffer();
}
@@ -383,6 +381,7 @@ static struct os_mbuf *encode_friend_ctl(struct bt_mesh_friend *frnd,
struct os_mbuf *sdu)
{
struct friend_pdu_info info;
u32_t seq;
BT_DBG("LPN 0x%04x", frnd->lpn);
@@ -394,9 +393,10 @@ static struct os_mbuf *encode_friend_ctl(struct bt_mesh_friend *frnd,
info.ctl = 1;
info.ttl = 0;
info.seq[0] = (bt_mesh.seq >> 16);
info.seq[1] = (bt_mesh.seq >> 8);
info.seq[2] = bt_mesh.seq++;
seq = bt_mesh_next_seq();
info.seq[0] = seq >> 16;
info.seq[1] = seq >> 8;
info.seq[2] = seq;
info.iv_index = BT_MESH_NET_IVI_TX;
@@ -1120,7 +1120,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd,
}
info.src = rx->ctx.addr;
info.dst = rx->dst;
info.dst = rx->ctx.recv_dst;
if (rx->net_if == BT_MESH_NET_IF_LOCAL) {
info.ttl = rx->ctx.recv_ttl;
@@ -1159,6 +1159,7 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd,
{
struct friend_pdu_info info;
struct os_mbuf *buf;
u32_t seq;
BT_DBG("LPN 0x%04x", frnd->lpn);
@@ -1172,9 +1173,10 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd,
info.ttl = tx->ctx->send_ttl;
info.ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED);
info.seq[0] = (bt_mesh.seq >> 16);
info.seq[1] = (bt_mesh.seq >> 8);
info.seq[2] = bt_mesh.seq++;
seq = bt_mesh_next_seq();
info.seq[0] = seq >> 16;
info.seq[1] = seq >> 8;
info.seq[2] = seq;
info.iv_index = BT_MESH_NET_IVI_TX;
@@ -1255,12 +1257,14 @@ void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx,
}
BT_DBG("recv_ttl %u net_idx 0x%04x src 0x%04x dst 0x%04x",
rx->ctx.recv_ttl, rx->sub->net_idx, rx->ctx.addr, rx->dst);
rx->ctx.recv_ttl, rx->sub->net_idx, rx->ctx.addr,
rx->ctx.recv_dst);
for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
if (friend_lpn_matches(frnd, rx->sub->net_idx, rx->dst)) {
if (friend_lpn_matches(frnd, rx->sub->net_idx,
rx->ctx.recv_dst)) {
friend_lpn_enqueue_rx(frnd, rx, type, seq_auth, sbuf);
}
}
+19
View File
@@ -17,6 +17,7 @@
* under the License.
*/
#include "base64/base64.h"
#include "mesh/glue.h"
#include "adv.h"
#ifndef MYNEWT
@@ -825,3 +826,21 @@ void net_buf_slist_merge_slist(struct net_buf_slist_t *list,
STAILQ_INIT(list);
}
int settings_bytes_from_str(char *val_str, void *vp, int *len)
{
*len = base64_decode(val_str, vp);
return 0;
}
char *settings_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len)
{
if (BASE64_ENCODE_SIZE(vp_len) > buf_len) {
return NULL;
}
base64_encode(vp, vp_len, buf, 1);
return buf;
}
-1
View File
@@ -19,7 +19,6 @@
#include "adv.h"
#include "net.h"
#include "transport.h"
#include "access.h"
#include "foundation.h"
#include "mesh/health_cli.h"
+24 -39
View File
@@ -28,13 +28,13 @@
#include "proxy.h"
#include "shell.h"
#include "mesh_priv.h"
#include "settings.h"
u8_t g_mesh_addr_type;
static bool provisioned;
int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
u8_t flags, u32_t iv_index, u32_t seq,
u16_t addr, const u8_t dev_key[16])
u8_t flags, u32_t iv_index, u16_t addr,
const u8_t dev_key[16])
{
int err;
@@ -55,60 +55,39 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
return err;
}
bt_mesh.seq = seq;
bt_mesh.seq = 0;
bt_mesh_comp_provision(addr);
memcpy(bt_mesh.dev_key, dev_key, 16);
provisioned = true;
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
bt_mesh_beacon_enable();
} else {
bt_mesh_beacon_disable();
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
BT_DBG("Storing network information persistently");
bt_mesh_store_net();
bt_mesh_store_subnet(&bt_mesh.sub[0]);
bt_mesh_store_iv(false);
}
if (MYNEWT_VAL(BLE_MESH_GATT_PROXY) &&
bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) {
bt_mesh_proxy_gatt_enable();
bt_mesh_adv_update();
}
if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) {
bt_mesh_lpn_init();
} else {
bt_mesh_scan_enable();
}
if ((MYNEWT_VAL(BLE_MESH_FRIEND))) {
bt_mesh_friend_init();
}
if (MYNEWT_VAL(BLE_MESH_PROV)) {
bt_mesh_prov_complete(net_idx, addr);
}
bt_mesh_net_start();
return 0;
}
void bt_mesh_reset(void)
{
if (!provisioned) {
if (!bt_mesh.valid) {
return;
}
bt_mesh_comp_unprovision();
bt_mesh.iv_index = 0;
bt_mesh.seq = 0;
bt_mesh.iv_update = 0;
bt_mesh.pending_update = 0;
bt_mesh.valid = 0;
bt_mesh.last_update = 0;
bt_mesh.ivu_duration = 0;
bt_mesh.ivu_initiator = 0;
k_delayed_work_cancel(&bt_mesh.ivu_complete);
k_delayed_work_cancel(&bt_mesh.ivu_timer);
bt_mesh_cfg_reset();
@@ -131,15 +110,17 @@ void bt_mesh_reset(void)
bt_mesh_proxy_prov_enable();
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_clear_net();
}
memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
provisioned = false;
bt_mesh_scan_disable();
bt_mesh_beacon_disable();
bt_mesh_comp_unprovision();
if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
bt_mesh_prov_reset();
}
@@ -147,7 +128,7 @@ void bt_mesh_reset(void)
bool bt_mesh_is_provisioned(void)
{
return provisioned;
return bt_mesh.valid;
}
int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
@@ -255,5 +236,9 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov,
ble_gap_mesh_cb_register(bt_mesh_gap_event, NULL);
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_settings_init();
}
return 0;
}
+1
View File
@@ -15,6 +15,7 @@
#define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00)
#define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000)
#define BT_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb)
struct bt_mesh_net;
#define OP_GEN_ONOFF_GET BT_MESH_MODEL_OP_2(0x82, 0x01)
#define OP_GEN_ONOFF_SET BT_MESH_MODEL_OP_2(0x82, 0x02)
+104 -51
View File
@@ -28,6 +28,8 @@
#include "access.h"
#include "foundation.h"
#include "beacon.h"
#include "settings.h"
#include "prov.h"
/* Minimum valid Mesh Network PDU length. The Network headers
* themselves take up 9 bytes. After that there is a minumum of 1 byte
@@ -40,14 +42,6 @@
/* Seq limit after IV Update is triggered */
#define IV_UPDATE_SEQ_LIMIT 8000000
#if MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST)
/* Small test timeout for IV Update Procedure testing */
#define IV_UPDATE_TIMEOUT K_SECONDS(120)
#else
/* Maximum time to stay in IV Update mode (96 < time < 144) */
#define IV_UPDATE_TIMEOUT K_HOURS(120)
#endif /* MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST) */
#define IVI(pdu) ((pdu)[0] >> 7)
#define NID(pdu) ((pdu)[0] & 0x7f)
#define CTL(pdu) ((pdu)[1] >> 7)
@@ -484,8 +478,11 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
bt_mesh.iv_index = iv_index;
bt_mesh.iv_update = BT_MESH_IV_UPDATE(flags);
/* Set initial IV Update procedure state time-stamp */
bt_mesh.last_update = k_uptime_get();
/* Set minimum required hours, since the 96-hour minimum requirement
* doesn't apply straight after provisioning (since we can't know how
* long has actually passed since the network changed its state).
*/
bt_mesh.ivu_duration = BT_MESH_IVU_MIN_HOURS;
/* Make sure we have valid beacon data to be sent */
bt_mesh_net_beacon_update(sub);
@@ -581,6 +578,8 @@ void bt_mesh_rpl_reset(void)
void bt_mesh_iv_update_test(bool enable)
{
bt_mesh.ivu_test = enable;
/* Reset the duration variable - needed for some PTS tests */
bt_mesh.ivu_duration = 0;
}
bool bt_mesh_iv_update(void)
@@ -666,18 +665,10 @@ bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update)
BT_DBG("Already in Normal state");
return false;
}
if (iv_index != bt_mesh.iv_index + 1) {
BT_WARN("Wrong new IV Index: 0x%08x != 0x%08x + 1",
iv_index, bt_mesh.iv_index);
return false;
}
}
if (!MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST) || !bt_mesh.ivu_test) {
s64_t delta = k_uptime_get() - bt_mesh.last_update;
if (delta < K_HOURS(96)) {
if (!(IS_ENABLED(CONFIG_BT_MESH_IV_UPDATE_TEST) && bt_mesh.ivu_test)) {
if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) {
BT_WARN("IV Update before minimum duration");
return false;
}
@@ -692,6 +683,7 @@ bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update)
do_update:
bt_mesh.iv_update = iv_update;
bt_mesh.ivu_duration = 0;
if (bt_mesh.iv_update) {
bt_mesh.iv_index = iv_index;
@@ -699,17 +691,12 @@ do_update:
bt_mesh.iv_index);
bt_mesh_rpl_reset();
k_delayed_work_submit(&bt_mesh.ivu_complete,
IV_UPDATE_TIMEOUT);
} else {
BT_DBG("Normal mode entered");
bt_mesh.seq = 0;
k_delayed_work_cancel(&bt_mesh.ivu_complete);
}
/* Store time-stamp of the IV procedure state change */
bt_mesh.last_update = k_uptime_get();
k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT);
for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
if (bt_mesh.sub[i].net_idx != BT_MESH_KEY_UNUSED) {
@@ -717,14 +704,30 @@ do_update:
}
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_iv(false);
}
return true;
}
u32_t bt_mesh_next_seq(void)
{
u32_t seq = bt_mesh.seq++;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_seq();
}
return seq;
}
int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf,
bool new_key, const struct bt_mesh_send_cb *cb,
void *cb_data)
{
const u8_t *enc, *priv;
u32_t seq;
int err;
BT_DBG("net_idx 0x%04x new_key %u len %u", sub->net_idx, new_key,
@@ -745,10 +748,10 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf,
return err;
}
/* Update with a new sequence number */
buf->om_data[2] = (bt_mesh.seq >> 16);
buf->om_data[3] = (bt_mesh.seq >> 8);
buf->om_data[4] = bt_mesh.seq++;
seq = bt_mesh_next_seq();
buf->om_data[2] = seq >> 16;
buf->om_data[3] = seq >> 8;
buf->om_data[4] = seq;
err = bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_TX, false);
if (err) {
@@ -788,6 +791,7 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf,
bool proxy)
{
const bool ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED);
u32_t seq_val;
u8_t nid;
const u8_t *enc, *priv;
u8_t *seq;
@@ -808,9 +812,10 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf,
net_buf_simple_push_be16(buf, tx->src);
seq = net_buf_simple_push(buf, 3);
seq[0] = (bt_mesh.seq >> 16);
seq[1] = (bt_mesh.seq >> 8);
seq[2] = bt_mesh.seq++;
seq_val = bt_mesh_next_seq();
seq[0] = seq_val >> 16;
seq[1] = seq_val >> 8;
seq[2] = seq_val;
if (ctl) {
net_buf_simple_push_u8(buf, tx->ctx->send_ttl | 0x80);
@@ -1149,7 +1154,8 @@ static void bt_mesh_net_relay(struct os_mbuf *sbuf,
return;
}
BT_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, rx->ctl, rx->dst);
BT_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, rx->ctl,
rx->ctx.recv_dst);
/* The Relay Retransmit state is only applied to adv-adv relaying.
* Anything else (like GATT to adv, or locally originated packets)
@@ -1161,9 +1167,7 @@ static void bt_mesh_net_relay(struct os_mbuf *sbuf,
transmit = bt_mesh_net_transmit_get();
}
buf = bt_mesh_adv_create(BT_MESH_ADV_DATA,
BT_MESH_TRANSMIT_COUNT(transmit),
BT_MESH_TRANSMIT_INT(transmit), K_NO_WAIT);
buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, transmit, K_NO_WAIT);
if (!buf) {
BT_ERR("Out of relay buffers");
return;
@@ -1213,8 +1217,8 @@ static void bt_mesh_net_relay(struct os_mbuf *sbuf,
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) &&
(bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED ||
rx->net_if == BT_MESH_NET_IF_LOCAL)) {
if (bt_mesh_proxy_relay(buf, rx->dst) &&
BT_MESH_ADDR_IS_UNICAST(rx->dst)) {
if (bt_mesh_proxy_relay(buf, rx->ctx.recv_dst) &&
BT_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst)) {
goto done;
}
}
@@ -1265,18 +1269,18 @@ int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if,
rx->ctl = CTL(buf->om_data);
rx->seq = SEQ(buf->om_data);
rx->dst = DST(buf->om_data);
rx->ctx.recv_dst = DST(buf->om_data);
BT_DBG("Decryption successful. Payload len %u: %s", buf->om_len,
bt_hex(buf->om_data, buf->om_len));
if (net_if != BT_MESH_NET_IF_PROXY_CFG &&
rx->dst == BT_MESH_ADDR_UNASSIGNED) {
rx->ctx.recv_dst == BT_MESH_ADDR_UNASSIGNED) {
BT_ERR("Destination address is unassigned; dropping packet");
return -EBADMSG;
}
if (BT_MESH_ADDR_IS_RFU(rx->dst)) {
if (BT_MESH_ADDR_IS_RFU(rx->ctx.recv_dst)) {
BT_ERR("Destination address is RFU; dropping packet");
return -EBADMSG;
}
@@ -1286,7 +1290,7 @@ int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if,
return -EBADMSG;
}
BT_DBG("src 0x%04x dst 0x%04x ttl %u", rx->ctx.addr, rx->dst,
BT_DBG("src 0x%04x dst 0x%04x ttl %u", rx->ctx.addr, rx->ctx.recv_dst,
rx->ctx.recv_ttl);
BT_DBG("PDU: %s", bt_hex(buf->om_data, buf->om_len));
@@ -1319,15 +1323,15 @@ void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi,
bt_mesh_proxy_addr_add(data, rx.ctx.addr);
}
rx.local_match = (bt_mesh_fixed_group_match(rx.dst) ||
bt_mesh_elem_find(rx.dst));
rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) ||
bt_mesh_elem_find(rx.ctx.recv_dst));
bt_mesh_trans_recv(buf, &rx);
/* Relay if this was a group/virtual address, or if the destination
* was neither a local element nor an LPN we're Friends for.
*/
if (!BT_MESH_ADDR_IS_UNICAST(rx.dst) ||
if (!BT_MESH_ADDR_IS_UNICAST(rx.ctx.recv_dst) ||
(!rx.local_match && !rx.friend_match)) {
net_buf_simple_restore(buf, &state);
bt_mesh_net_relay(buf, &rx);
@@ -1337,17 +1341,66 @@ done:
os_mbuf_free_chain(buf);
}
static void ivu_complete(struct ble_npl_event *work)
static void ivu_refresh(struct ble_npl_event *work)
{
BT_DBG("");
bt_mesh.ivu_duration += BT_MESH_IVU_HOURS;
bt_mesh_beacon_ivu_initiator(true);
bt_mesh_net_iv_update(bt_mesh.iv_index, false);
BT_DBG("%s for %u hour%s",
bt_mesh.iv_update ? "IVU in Progress" : "IVU Normal mode",
bt_mesh.ivu_duration, bt_mesh.ivu_duration == 1 ? "" : "s");
if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) {
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_iv(true);
}
k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT);
return;
}
if (bt_mesh.iv_update) {
bt_mesh_beacon_ivu_initiator(true);
bt_mesh_net_iv_update(bt_mesh.iv_index, false);
} else if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_iv(true);
}
}
void bt_mesh_net_start(void)
{
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
bt_mesh_beacon_enable();
} else {
bt_mesh_beacon_disable();
}
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) &&
bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) {
bt_mesh_proxy_gatt_enable();
bt_mesh_adv_update();
}
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
bt_mesh_lpn_init();
} else {
bt_mesh_scan_enable();
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
bt_mesh_friend_init();
}
if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
u16_t net_idx = bt_mesh.sub[0].net_idx;
u16_t addr = bt_mesh_primary_addr();
bt_mesh_prov_complete(net_idx, addr);
}
}
void bt_mesh_net_init(void)
{
k_delayed_work_init(&bt_mesh.ivu_complete, ivu_complete);
k_delayed_work_init(&bt_mesh.ivu_timer, ivu_refresh);
k_work_init(&bt_mesh.local_work, bt_mesh_net_local);
net_buf_slist_init(&bt_mesh.local_queue);
+34 -4
View File
@@ -25,6 +25,12 @@
#include "mesh/mesh.h"
#include "mesh/glue.h"
/* How many hours in between updating IVU duration */
#define BT_MESH_IVU_MIN_HOURS 96
#define BT_MESH_IVU_HOURS (BT_MESH_IVU_MIN_HOURS / \
CONFIG_BT_MESH_IVU_DIVIDER)
#define BT_MESH_IVU_TIMEOUT K_HOURS(BT_MESH_IVU_HOURS)
struct bt_mesh_app_key {
u16_t net_idx;
u16_t app_idx;
@@ -72,6 +78,9 @@ struct bt_mesh_subnet {
struct bt_mesh_rpl {
u16_t src;
bool old_iv;
#if defined(CONFIG_BT_SETTINGS)
bool store;
#endif
u32_t seq;
};
@@ -189,6 +198,21 @@ struct bt_mesh_lpn {
ATOMIC_DEFINE(to_remove, LPN_GROUPS);
};
/* bt_mesh_net.flags, mainly used for pending storage actions */
enum {
BT_MESH_RPL_PENDING,
BT_MESH_KEYS_PENDING,
BT_MESH_NET_PENDING,
BT_MESH_IV_PENDING,
BT_MESH_SEQ_PENDING,
BT_MESH_HB_PUB_PENDING,
BT_MESH_CFG_PENDING,
BT_MESH_MOD_PENDING,
/* Don't touch - intentionally last */
BT_MESH_FLAG_COUNT,
};
struct bt_mesh_net {
u32_t iv_index; /* Current IV Index */
u32_t seq:24, /* Next outgoing sequence number */
@@ -198,7 +222,7 @@ struct bt_mesh_net {
pending_update:1, /* Update blocked by SDU in progress */
valid:1; /* 0 if unused */
s64_t last_update; /* Time since last IV Update change */
ATOMIC_DEFINE(flags, BT_MESH_FLAG_COUNT);
/* Local network interface */
struct ble_npl_callout local_work;
@@ -213,8 +237,11 @@ struct bt_mesh_net {
struct bt_mesh_lpn lpn; /* Low Power Node state */
#endif
/* Timer to transition IV Update in Progress state */
struct k_delayed_work ivu_complete;
/* Number of hours in current IV Update state */
u8_t ivu_duration;
/* Timer to track duration in current IV Update state */
struct k_delayed_work ivu_timer;
u8_t dev_key[16];
@@ -238,7 +265,6 @@ struct bt_mesh_net_rx {
struct bt_mesh_subnet *sub;
struct bt_mesh_msg_ctx ctx;
u32_t seq; /* Sequence Number */
u16_t dst; /* Destination address */
u8_t old_iv:1, /* iv_index - 1 was used */
new_key:1, /* Data was encrypted with updated key */
friend_cred:1, /* Data was encrypted with friend cred */
@@ -309,6 +335,10 @@ int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if,
void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi,
enum bt_mesh_net_if net_if);
u32_t bt_mesh_next_seq(void);
void bt_mesh_net_start(void);
void bt_mesh_net_init(void);
/* Friendship Credential Management */
+23 -8
View File
@@ -29,8 +29,7 @@
#include "testing.h"
/* 3 transmissions, 20ms interval */
#define PROV_XMIT_COUNT 2
#define PROV_XMIT_INT 20
#define PROV_XMIT BT_MESH_TRANSMIT(2, 20)
#define AUTH_METHOD_NO_OOB 0x00
#define AUTH_METHOD_STATIC 0x01
@@ -262,8 +261,7 @@ static struct os_mbuf *adv_buf_create(void)
{
struct os_mbuf *buf;
buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, PROV_XMIT_COUNT,
PROV_XMIT_INT, BUF_TIMEOUT);
buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, PROV_XMIT, BUF_TIMEOUT);
if (!buf) {
BT_ERR("Out of provisioning buffers");
assert(0);
@@ -1008,6 +1006,15 @@ done:
os_mbuf_free_chain(rnd);
}
static inline bool is_pb_gatt(void)
{
#if MYNEWT_VAL(BLE_MESH_PB_GATT)
return !!link.conn_handle;
#else
return false;
#endif
}
static void prov_data(const u8_t *data)
{
struct os_mbuf *msg = PROV_BUF(1);
@@ -1020,6 +1027,7 @@ static void prov_data(const u8_t *data)
u16_t addr;
u16_t net_idx;
int err;
bool identity_enable;
BT_DBG("");
@@ -1071,14 +1079,21 @@ static void prov_data(const u8_t *data)
/* Ignore any further PDUs on this link */
link.expect = 0;
bt_mesh_provision(pdu, net_idx, flags, iv_index, 0, addr, dev_key);
/* Store info, since bt_mesh_provision() will end up clearing it */
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
identity_enable = is_pb_gatt();
} else {
identity_enable = false;
}
bt_mesh_provision(pdu, net_idx, flags, iv_index, addr, dev_key);
#if MYNEWT_VAL(BLE_MESH_PB_GATT) && MYNEWT_VAL(BLE_MESH_GATT_PROXY)
/* After PB-GATT provisioning we should start advertising
* using Node Identity.
*/
bt_mesh_proxy_identity_enable();
#endif
if (identity_enable) {
bt_mesh_proxy_identity_enable();
}
done:
os_mbuf_free_chain(msg);
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
void bt_mesh_store_net(void);
void bt_mesh_store_iv(bool only_duration);
void bt_mesh_store_seq(void);
void bt_mesh_store_rpl(struct bt_mesh_rpl *rpl);
void bt_mesh_store_subnet(struct bt_mesh_subnet *sub);
void bt_mesh_store_app_key(struct bt_mesh_app_key *key);
void bt_mesh_store_hb_pub(void);
void bt_mesh_store_cfg(void);
void bt_mesh_store_mod_bind(struct bt_mesh_model *mod);
void bt_mesh_store_mod_sub(struct bt_mesh_model *mod);
void bt_mesh_store_mod_pub(struct bt_mesh_model *mod);
void bt_mesh_clear_net(void);
void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub);
void bt_mesh_clear_app_key(struct bt_mesh_app_key *key);
void bt_mesh_clear_rpl(void);
void bt_mesh_settings_init(void);
+18 -6
View File
@@ -27,15 +27,17 @@
#include "net.h"
#include "access.h"
#include "mesh_priv.h"
#include "lpn.h"
#include "transport.h"
#include "foundation.h"
#include "testing.h"
#include "settings.h"
#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
#include "mesh/model_srv.h"
#include "mesh/model_cli.h"
#include "light_model.h"
#endif
#include "lpn.h"
#include "transport.h"
#include "foundation.h"
#include "testing.h"
/* This should be higher priority (lower value) than main task priority */
#define BLE_MESH_SHELL_TASK_PRIO 126
@@ -656,7 +658,17 @@ int cmd_mesh_init(int argc, char *argv[])
}
printk("Mesh initialized\n");
printk("Use \"pb-adv on\" or \"pb-gatt on\" to enable advertising\n");
if (IS_ENABLED(CONFIG_SETTINGS)) {
settings_load();
}
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");
}
#if MYNEWT_VAL(BLE_MESH_LOW_POWER)
bt_mesh_lpn_set_cb(lpn_cb);
@@ -1818,7 +1830,7 @@ static int cmd_provision(int argc, char *argv[])
iv_index = 0;
}
err = bt_mesh_provision(default_key, net_idx, 0, iv_index, 0, addr,
err = bt_mesh_provision(default_key, net_idx, 0, iv_index, addr,
default_key);
if (err) {
printk("Provisioning failed (err %d)\n", err);
+1 -1
View File
@@ -164,7 +164,7 @@ int bt_test_bind_app_key_to_model(struct bt_mesh_model *model, u16_t key_idx, u1
{
struct bt_mesh_model *found_model;
found_model = bt_mesh_model_find(model->elem, id);
found_model = bt_mesh_model_find(bt_mesh_model_elem(model), id);
if (!found_model) {
return STATUS_INVALID_MODEL;
}
+62 -42
View File
@@ -24,6 +24,7 @@
#include "friend.h"
#include "access.h"
#include "foundation.h"
#include "settings.h"
#include "transport.h"
#include "testing.h"
@@ -103,9 +104,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct os_mbuf *sdu,
BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x sdu_len %u",
tx->src, tx->ctx->addr, tx->ctx->app_idx, sdu->om_len);
buf = bt_mesh_adv_create(BT_MESH_ADV_DATA,
BT_MESH_TRANSMIT_COUNT(tx->xmit),
BT_MESH_TRANSMIT_INT(tx->xmit), BUF_TIMEOUT);
buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, tx->xmit, BUF_TIMEOUT);
if (!buf) {
BT_ERR("Out of network buffers");
return -ENOBUFS;
@@ -343,9 +342,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct os_mbuf *sdu,
u16_t len;
int err;
seg = bt_mesh_adv_create(BT_MESH_ADV_DATA,
BT_MESH_TRANSMIT_COUNT(net_tx->xmit),
BT_MESH_TRANSMIT_INT(net_tx->xmit),
seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, net_tx->xmit,
BUF_TIMEOUT);
if (!seg) {
BT_ERR("Out of segment buffers");
@@ -402,7 +399,8 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct os_mbuf *sdu,
}
}
if (bt_mesh_lpn_established()) {
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) &&
bt_mesh_lpn_established()) {
bt_mesh_lpn_poll();
}
@@ -518,6 +516,11 @@ static bool is_replay(struct bt_mesh_net_rx *rx)
{
int i;
/* Don't bother checking messages from ourselves */
if (rx->net_if == BT_MESH_NET_IF_LOCAL) {
return false;
}
for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) {
struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i];
@@ -526,6 +529,11 @@ static bool is_replay(struct bt_mesh_net_rx *rx)
rpl->src = rx->ctx.addr;
rpl->seq = rx->seq;
rpl->old_iv = rx->old_iv;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_rpl(rpl);
}
return false;
}
@@ -539,6 +547,11 @@ static bool is_replay(struct bt_mesh_net_rx *rx)
rpl->seq < rx->seq) {
rpl->seq = rx->seq;
rpl->old_iv = rx->old_iv;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_store_rpl(rpl);
}
return false;
} else {
return true;
@@ -550,8 +563,8 @@ static bool is_replay(struct bt_mesh_net_rx *rx)
return true;
}
static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t aszmic,
struct os_mbuf *buf)
static int sdu_recv(struct bt_mesh_net_rx *rx, u32_t seq, u8_t hdr,
u8_t aszmic, struct os_mbuf *buf)
{
struct os_mbuf *sdu =
NET_BUF_SIMPLE(MYNEWT_VAL(BLE_MESH_RX_SDU_MAX) - 4);
@@ -569,12 +582,13 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t aszmic,
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && !rx->local_match) {
BT_DBG("Ignoring PDU for LPN 0x%04x of this Friend", rx->dst);
BT_DBG("Ignoring PDU for LPN 0x%04x of this Friend",
rx->ctx.recv_dst);
return 0;
}
if (BT_MESH_ADDR_IS_VIRTUAL(rx->dst)) {
ad = bt_mesh_label_uuid_get(rx->dst);
if (BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) {
ad = bt_mesh_label_uuid_get(rx->ctx.recv_dst);
} else {
ad = NULL;
}
@@ -585,8 +599,9 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t aszmic,
if (!AKF(&hdr)) {
net_buf_simple_init(sdu, 0);
err = bt_mesh_app_decrypt(bt_mesh.dev_key, true, aszmic, buf,
sdu, ad, rx->ctx.addr, rx->dst,
rx->seq, BT_MESH_NET_IVI_RX(rx));
sdu, ad, rx->ctx.addr,
rx->ctx.recv_dst, seq,
BT_MESH_NET_IVI_RX(rx));
if (err) {
BT_ERR("Unable to decrypt with DevKey");
err = -EINVAL;
@@ -620,8 +635,9 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u8_t hdr, u8_t aszmic,
net_buf_simple_init(sdu, 0);
err = bt_mesh_app_decrypt(keys->val, false, aszmic, buf,
sdu, ad, rx->ctx.addr, rx->dst,
rx->seq, BT_MESH_NET_IVI_RX(rx));
sdu, ad, rx->ctx.addr,
rx->ctx.recv_dst, seq,
BT_MESH_NET_IVI_RX(rx));
if (err) {
BT_WARN("Unable to decrypt with AppKey %u", i);
continue;
@@ -691,7 +707,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr,
seq_zero = (seq_zero >> 2) & 0x1fff;
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->friend_match) {
BT_DBG("Ack for LPN 0x%04x of this Friend", rx->dst);
BT_DBG("Ack for LPN 0x%04x of this Friend", rx->ctx.recv_dst);
/* Best effort - we don't have enough info for true SeqAuth */
*seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_RX(rx), seq_zero);
return 0;
@@ -754,7 +770,7 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx,
return -EINVAL;
}
if (rx->dst != hb_sub_dst) {
if (rx->ctx.recv_dst != hb_sub_dst) {
BT_WARN("Ignoring heartbeat to non-subscribed destination");
return 0;
}
@@ -768,7 +784,7 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx,
rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops,
(hops == 1) ? "" : "s", feat);
bt_mesh_heartbeat(rx->ctx.addr, rx->dst, hops, feat);
bt_mesh_heartbeat(rx->ctx.addr, rx->ctx.recv_dst, hops, feat);
return 0;
}
@@ -852,7 +868,7 @@ static int trans_unseg(struct os_mbuf *buf, struct bt_mesh_net_rx *rx,
if (rx->local_match && is_replay(rx)) {
BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x",
rx->ctx.addr, rx->dst, rx->seq);
rx->ctx.addr, rx->ctx.recv_dst, rx->seq);
return -EINVAL;
}
@@ -866,7 +882,7 @@ static int trans_unseg(struct os_mbuf *buf, struct bt_mesh_net_rx *rx,
return 0;
}
return sdu_recv(rx, hdr, 0, buf);
return sdu_recv(rx, rx->seq, hdr, 0, buf);
}
}
@@ -905,9 +921,7 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data,
tx->ctx->addr, tx->ctx->send_ttl, ctl_op);
BT_DBG("len %zu: %s", data_len, bt_hex(data, data_len));
buf = bt_mesh_adv_create(BT_MESH_ADV_DATA,
BT_MESH_TRANSMIT_COUNT(tx->xmit),
BT_MESH_TRANSMIT_INT(tx->xmit), BUF_TIMEOUT);
buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, tx->xmit, BUF_TIMEOUT);
if (!buf) {
BT_ERR("Out of transport buffers");
return -ENOBUFS;
@@ -1046,7 +1060,8 @@ static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx,
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
struct seg_rx *rx = &seg_rx[i];
if (rx->src != net_rx->ctx.addr || rx->dst != net_rx->dst) {
if (rx->src != net_rx->ctx.addr ||
rx->dst != net_rx->ctx.recv_dst) {
continue;
}
@@ -1082,7 +1097,7 @@ static bool seg_rx_is_valid(struct seg_rx *rx, struct bt_mesh_net_rx *net_rx,
return false;
}
if (rx->src != net_rx->ctx.addr || rx->dst != net_rx->dst) {
if (rx->src != net_rx->ctx.addr || rx->dst != net_rx->ctx.recv_dst) {
BT_ERR("Invalid source or destination for segment");
return false;
}
@@ -1117,7 +1132,7 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx,
rx->hdr = *hdr;
rx->ttl = net_rx->ctx.send_ttl;
rx->src = net_rx->ctx.addr;
rx->dst = net_rx->dst;
rx->dst = net_rx->ctx.recv_dst;
rx->block = 0;
BT_DBG("New RX context. Block Complete 0x%08x",
@@ -1185,9 +1200,9 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx,
if (rx->block == BLOCK_COMPLETE(rx->seg_n)) {
BT_WARN("Got segment for already complete SDU");
send_ack(net_rx->sub, net_rx->dst, net_rx->ctx.addr,
net_rx->ctx.send_ttl, seq_auth, rx->block,
rx->obo);
send_ack(net_rx->sub, net_rx->ctx.recv_dst,
net_rx->ctx.addr, net_rx->ctx.send_ttl,
seq_auth, rx->block, rx->obo);
return -EALREADY;
}
@@ -1202,7 +1217,7 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx,
/* Bail out early if we're not ready to receive such a large SDU */
if (!sdu_len_is_ok(net_rx->ctl, seg_n)) {
BT_ERR("Too big incoming SDU length");
send_ack(net_rx->sub, net_rx->dst, net_rx->ctx.addr,
send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr,
net_rx->ctx.send_ttl, seq_auth, 0,
net_rx->friend_match);
return -EMSGSIZE;
@@ -1239,8 +1254,9 @@ found_rx:
if (rx->buf->om_len > MYNEWT_VAL(BLE_MESH_RX_SDU_MAX)) {
BT_ERR("Too large SDU len");
send_ack(net_rx->sub, net_rx->dst, net_rx->ctx.addr,
net_rx->ctx.send_ttl, seq_auth, 0, rx->obo);
send_ack(net_rx->sub, net_rx->ctx.recv_dst,
net_rx->ctx.addr, net_rx->ctx.send_ttl,
seq_auth, 0, rx->obo);
seg_rx_reset(rx, true);
return -EMSGSIZE;
}
@@ -1276,7 +1292,7 @@ found_rx:
if (net_rx->local_match && is_replay(net_rx)) {
BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x",
net_rx->ctx.addr, net_rx->dst, net_rx->seq);
net_rx->ctx.addr, net_rx->ctx.recv_dst, net_rx->seq);
/* Clear the segment's bit */
rx->block &= ~BIT(seg_o);
return -EINVAL;
@@ -1284,17 +1300,15 @@ found_rx:
*pdu_type = BT_MESH_FRIEND_PDU_COMPLETE;
/* Set the correct sequence number to be used with the App Nonce */
net_rx->seq = (rx->seq_auth & 0xffffff);
k_delayed_work_cancel(&rx->ack);
send_ack(net_rx->sub, net_rx->dst, net_rx->ctx.addr,
send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr,
net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo);
if (net_rx->ctl) {
err = ctl_recv(net_rx, *hdr, rx->buf, seq_auth);
} else {
err = sdu_recv(net_rx, *hdr, ASZMIC(hdr), rx->buf);
err = sdu_recv(net_rx, (rx->seq_auth & 0xffffff), *hdr,
ASZMIC(hdr), rx->buf);
}
seg_rx_reset(rx, false);
@@ -1311,13 +1325,13 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx)
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
rx->friend_match = bt_mesh_friend_match(rx->sub->net_idx,
rx->dst);
rx->ctx.recv_dst);
} else {
rx->friend_match = false;
}
BT_DBG("src 0x%04x dst 0x%04x seq 0x%08x friend_match %u",
rx->ctx.addr, rx->dst, rx->seq, rx->friend_match);
rx->ctx.addr, rx->ctx.recv_dst, rx->seq, rx->friend_match);
/* Remove network headers */
net_buf_simple_pull(buf, BT_MESH_NET_HDR_LEN);
@@ -1326,7 +1340,7 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx)
if (IS_ENABLED(CONFIG_BT_TESTING)) {
bt_test_mesh_net_recv(rx->ctx.recv_ttl, rx->ctl, rx->ctx.addr,
rx->dst, buf->om_data, buf->om_len);
rx->ctx.recv_dst, buf->om_data, buf->om_len);
}
/* If LPN mode is enabled messages are only accepted when we've
@@ -1397,6 +1411,12 @@ void bt_mesh_rx_reset(void)
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
seg_rx_reset(&seg_rx[i], true);
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_clear_rpl();
} else {
memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
}
}
void bt_mesh_tx_reset(void)
+68
View File
@@ -126,6 +126,30 @@ syscfg.defs:
4-byte MIC and 52 bytes using an 8-byte MIC.
value: 10
BLE_MESH_IVU_DIVIDER:
description: >
When the IV Update state enters Normal operation or IV Update
in Progress, we need to keep track of how many hours has passed
in the state, since the specification requires us to remain in
the state at least for 96 hours (Update in Progress has an
additional upper limit of 144 hours).
In order to fulfil the above requirement, even if the node might
be powered off once in a while, we need to store persistently
how many hours the node has been in the state. This doesn't
necessarily need to happen every hour (thanks to the flexible
duration range). The exact cadence will depend a lot on the
ways that the node will be used and what kind of power source it
has.
Since there is no single optimal answer, this configuration
option allows specifying a divider, i.e. how many intervals
the 96 hour minimum gets split into. After each interval the
duration that the node has been in the current state gets
stored to flash. E.g. the default value of 4 means that the
state is saved every 24 hours (96 / 4).
value: 4
BLE_MESH_TX_SEG_MSG_COUNT:
description: >
Maximum number of simultaneous outgoing multi-segment and/or
@@ -366,6 +390,11 @@ syscfg.defs:
Use this option to enable Proxy protocol debug logs.
value: 0
BLE_MESH_DEBUG_SETTINGS:
description: >
Use this option to enable persistent settings debug logs.
value: 1
BLE_MESH_IV_UPDATE_TEST:
description: >
This option removes the 96 hour limit of the IV Update
@@ -418,6 +447,45 @@ syscfg.defs:
Input OOB size
value: 4
BLE_MESH_SETTINGS:
description: >
This option enables Mesh settings storage.
value: 1
BLE_MESH_STORE_TIMEOUT:
description: >
This value defines in seconds how soon any pending changes
are actually written into persistent storage (flash) after
a change occurs.
value: 2
BLE_MESH_SEQ_STORE_RATE:
description: >
This value defines how often the local sequence number gets
updated in persistent storage (i.e. flash). E.g. a value of 100
means that the sequence number will be stored to flash on every
100th increment. If the node sends messages very frequently a
higher value makes more sense, whereas if the node sends
infrequently a value as low as 0 (update storage for every
increment) can make sense. When the stack gets initialized it
will add this number to the last stored one, so that it starts
off with a value that's guaranteed to be larger than the last
one used before power off.
value: 128
BLE_MESH_RPL_STORE_TIMEOUT:
description: >
This value defines in seconds how soon the RPL gets written to
persistent storage after a change occurs. If the node receives
messages frequently it may make sense to have this set to a
large value, whereas if the RPL gets updated infrequently a
value as low as 0 (write immediately) may make sense. Note that
if the node operates a security sensitive use case, and there's
a risk of sudden power loss, it may be a security vulnerability
to set this value to anything else than 0 (a power loss before
writing to storage exposes the node to potential message
replay attacks).
value: 5
syscfg.vals.BLE_MESH_SHELL:
BLE_MESH_CFG_CLI: 1