mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-09-05 16:50:01 +00:00
Merge pull request #142 from michal-narajowski/mesh-storage-port
Mesh sync with Zephyr (persistent storage)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "net.h"
|
||||
#include "foundation.h"
|
||||
|
||||
#define CID_NVAL 0xffff
|
||||
|
||||
+302
-57
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user