Bluetooth: Mesh: Support for storing common configuration states
Add support for storing the remaining configuration server model states (all of which are one byte values). The states are stored under a single settings key bt/mesh/Cfg. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
44bd56877b
commit
59239032f6
5 changed files with 153 additions and 1 deletions
|
@ -692,6 +692,10 @@ static void beacon_set(struct bt_mesh_model *model,
|
|||
if (buf->data[0] != cfg->beacon) {
|
||||
cfg->beacon = buf->data[0];
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
bt_mesh_store_cfg();
|
||||
}
|
||||
|
||||
if (cfg->beacon) {
|
||||
bt_mesh_beacon_enable();
|
||||
} else {
|
||||
|
@ -745,7 +749,13 @@ static void default_ttl_set(struct bt_mesh_model *model,
|
|||
if (!cfg) {
|
||||
BT_WARN("No Configuration Server context available");
|
||||
} else if (buf->data[0] <= BT_MESH_TTL_MAX && buf->data[0] != 0x01) {
|
||||
cfg->default_ttl = buf->data[0];
|
||||
if (cfg->default_ttl != buf->data[0]) {
|
||||
cfg->default_ttl = buf->data[0];
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
bt_mesh_store_cfg();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BT_WARN("Prohibited Default TTL value 0x%02x", buf->data[0]);
|
||||
return;
|
||||
|
@ -817,6 +827,11 @@ static void gatt_proxy_set(struct bt_mesh_model *model,
|
|||
}
|
||||
|
||||
cfg->gatt_proxy = buf->data[0];
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
bt_mesh_store_cfg();
|
||||
}
|
||||
|
||||
if (cfg->gatt_proxy == BT_MESH_GATT_PROXY_DISABLED) {
|
||||
int i;
|
||||
|
||||
|
@ -889,6 +904,10 @@ static void net_transmit_set(struct bt_mesh_model *model,
|
|||
BT_WARN("No Configuration Server context available");
|
||||
} else {
|
||||
cfg->net_transmit = buf->data[0];
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
bt_mesh_store_cfg();
|
||||
}
|
||||
}
|
||||
|
||||
bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS);
|
||||
|
@ -943,6 +962,10 @@ static void relay_set(struct bt_mesh_model *model,
|
|||
change = (cfg->relay != buf->data[0]);
|
||||
cfg->relay = buf->data[0];
|
||||
cfg->relay_retransmit = buf->data[1];
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
bt_mesh_store_cfg();
|
||||
}
|
||||
}
|
||||
|
||||
BT_DBG("Relay 0x%02x (%s) xmit 0x%02x (count %u interval %u)",
|
||||
|
@ -2591,6 +2614,10 @@ static void friend_set(struct bt_mesh_model *model,
|
|||
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
|
||||
cfg->frnd = buf->data[0];
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
bt_mesh_store_cfg();
|
||||
}
|
||||
|
||||
if (cfg->frnd == BT_MESH_FRIEND_DISABLED) {
|
||||
bt_mesh_friend_clear_net_idx(BT_MESH_KEY_ANY);
|
||||
}
|
||||
|
@ -3351,6 +3378,11 @@ struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void)
|
|||
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)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -127,6 +127,7 @@ 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);
|
||||
|
|
|
@ -205,6 +205,7 @@ enum {
|
|||
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 */
|
||||
|
|
|
@ -68,6 +68,17 @@ struct hb_pub_val {
|
|||
indefinite:1;
|
||||
};
|
||||
|
||||
/* Miscelaneous configuration server model states */
|
||||
struct cfg_val {
|
||||
u8_t net_transmit;
|
||||
u8_t relay;
|
||||
u8_t relay_retransmit;
|
||||
u8_t beacon;
|
||||
u8_t gatt_proxy;
|
||||
u8_t frnd;
|
||||
u8_t default_ttl;
|
||||
};
|
||||
|
||||
/* IV Index & IV Update storage */
|
||||
struct iv_val {
|
||||
u32_t iv_index;
|
||||
|
@ -104,6 +115,14 @@ struct mod_pub_val {
|
|||
cred:1;
|
||||
};
|
||||
|
||||
/* We need this so we don't overwrite app-hardcoded values in case FCB
|
||||
* contains a history of changes but then has a NULL at the end.
|
||||
*/
|
||||
static struct {
|
||||
bool valid;
|
||||
struct cfg_val cfg;
|
||||
} stored_cfg;
|
||||
|
||||
static int net_set(int argc, char **argv, char *val)
|
||||
{
|
||||
struct net_val net;
|
||||
|
@ -482,6 +501,42 @@ static int hb_pub_set(int argc, char **argv, char *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cfg_set(int argc, char **argv, char *val)
|
||||
{
|
||||
struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get();
|
||||
int len, err;
|
||||
|
||||
BT_DBG("val %s", val ? val : "(null)");
|
||||
|
||||
if (!cfg) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
stored_cfg.valid = false;
|
||||
BT_DBG("Cleared configuration state");
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = sizeof(stored_cfg.cfg);
|
||||
err = settings_bytes_from_str(val, &stored_cfg.cfg, &len);
|
||||
if (err) {
|
||||
BT_ERR("Failed to decode value %s (err %d)", val, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (len != sizeof(stored_cfg.cfg)) {
|
||||
BT_ERR("Unexpected value length (%d != %zu)", len,
|
||||
sizeof(stored_cfg.cfg));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stored_cfg.valid = true;
|
||||
BT_DBG("Restored configuration state");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mod_set_bind(struct bt_mesh_model *mod, char *val)
|
||||
{
|
||||
int len, err, i;
|
||||
|
@ -642,6 +697,7 @@ const struct mesh_setting {
|
|||
{ "NetKey", net_key_set },
|
||||
{ "AppKey", app_key_set },
|
||||
{ "HBPub", hb_pub_set },
|
||||
{ "Cfg", cfg_set },
|
||||
{ "s", sig_mod_set },
|
||||
{ "v", vnd_mod_set },
|
||||
};
|
||||
|
@ -718,6 +774,7 @@ static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
|
|||
static int mesh_commit(void)
|
||||
{
|
||||
struct bt_mesh_hb_pub *hb_pub;
|
||||
struct bt_mesh_cfg_srv *cfg;
|
||||
int i;
|
||||
|
||||
BT_DBG("sub[0].net_idx 0x%03x", bt_mesh.sub[0].net_idx);
|
||||
|
@ -763,6 +820,17 @@ static int mesh_commit(void)
|
|||
k_work_submit(&hb_pub->timer.work);
|
||||
}
|
||||
|
||||
cfg = bt_mesh_cfg_get();
|
||||
if (cfg && stored_cfg.valid) {
|
||||
cfg->net_transmit = stored_cfg.cfg.net_transmit;
|
||||
cfg->relay = stored_cfg.cfg.relay;
|
||||
cfg->relay_retransmit = stored_cfg.cfg.relay_retransmit;
|
||||
cfg->beacon = stored_cfg.cfg.beacon;
|
||||
cfg->gatt_proxy = stored_cfg.cfg.gatt_proxy;
|
||||
cfg->frnd = stored_cfg.cfg.frnd;
|
||||
cfg->default_ttl = stored_cfg.cfg.default_ttl;
|
||||
}
|
||||
|
||||
bt_mesh.valid = 1;
|
||||
|
||||
bt_mesh_net_start();
|
||||
|
@ -986,6 +1054,41 @@ static void store_pending_hb_pub(void)
|
|||
settings_save_one("bt/mesh/HBPub", str);
|
||||
}
|
||||
|
||||
static void store_pending_cfg(void)
|
||||
{
|
||||
char buf[BT_SETTINGS_SIZE(sizeof(struct cfg_val))];
|
||||
struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get();
|
||||
struct cfg_val val;
|
||||
char *str;
|
||||
|
||||
if (!cfg) {
|
||||
return;
|
||||
}
|
||||
|
||||
val.net_transmit = cfg->net_transmit;
|
||||
val.relay = cfg->relay;
|
||||
val.relay_retransmit = cfg->relay_retransmit;
|
||||
val.beacon = cfg->beacon;
|
||||
val.gatt_proxy = cfg->gatt_proxy;
|
||||
val.frnd = cfg->frnd;
|
||||
val.default_ttl = cfg->default_ttl;
|
||||
|
||||
str = settings_str_from_bytes(&val, sizeof(val), buf, sizeof(buf));
|
||||
if (!str) {
|
||||
BT_ERR("Unable to encode configuration as value");
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("Saving configuration as value %s", str);
|
||||
settings_save_one("bt/mesh/Cfg", str);
|
||||
}
|
||||
|
||||
static void clear_cfg(void)
|
||||
{
|
||||
BT_DBG("Clearing configuration");
|
||||
settings_save_one("bt/mesh/Cfg", NULL);
|
||||
}
|
||||
|
||||
static void clear_app_key(u16_t app_idx)
|
||||
{
|
||||
char path[20];
|
||||
|
@ -1273,6 +1376,14 @@ static void store_pending(struct k_work *work)
|
|||
store_pending_hb_pub();
|
||||
}
|
||||
|
||||
if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_CFG_PENDING)) {
|
||||
if (bt_mesh.valid) {
|
||||
store_pending_cfg();
|
||||
} else {
|
||||
clear_cfg();
|
||||
}
|
||||
}
|
||||
|
||||
if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_MOD_PENDING)) {
|
||||
bt_mesh_model_foreach(store_pending_mod, NULL);
|
||||
}
|
||||
|
@ -1370,10 +1481,16 @@ void bt_mesh_store_hb_pub(void)
|
|||
schedule_store(BT_MESH_HB_PUB_PENDING);
|
||||
}
|
||||
|
||||
void bt_mesh_store_cfg(void)
|
||||
{
|
||||
schedule_store(BT_MESH_CFG_PENDING);
|
||||
}
|
||||
|
||||
void bt_mesh_clear_net(void)
|
||||
{
|
||||
schedule_store(BT_MESH_NET_PENDING);
|
||||
schedule_store(BT_MESH_IV_PENDING);
|
||||
schedule_store(BT_MESH_CFG_PENDING);
|
||||
}
|
||||
|
||||
void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub)
|
||||
|
|
|
@ -11,6 +11,7 @@ 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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue