From 1c846651dbecdd205b926ab7c578c9ca59f24808 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 7 May 2018 12:23:37 +0300 Subject: [PATCH] Bluetooth: Mesh: Add storage APIs for core network values Add APIs for storing core network values, such as Net and App Keys, IV Index, Sequence number, RPL, etc. Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/mesh/cfg_srv.c | 16 +++ subsys/bluetooth/host/mesh/main.c | 8 ++ subsys/bluetooth/host/mesh/net.c | 17 ++- subsys/bluetooth/host/mesh/settings.c | 137 +++++++++++++++++++++++++ subsys/bluetooth/host/mesh/settings.h | 12 +++ subsys/bluetooth/host/mesh/transport.c | 11 ++ 6 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 subsys/bluetooth/host/mesh/settings.h diff --git a/subsys/bluetooth/host/mesh/cfg_srv.c b/subsys/bluetooth/host/mesh/cfg_srv.c index d3222a82b82..e8efee6ab0b 100644 --- a/subsys/bluetooth/host/mesh/cfg_srv.c +++ b/subsys/bluetooth/host/mesh/cfg_srv.c @@ -34,6 +34,7 @@ #include "proxy.h" #include "foundation.h" #include "friend.h" +#include "settings.h" #define DEFAULT_TTL 7 @@ -450,6 +451,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; } @@ -2001,6 +2007,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); @@ -2074,6 +2085,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); diff --git a/subsys/bluetooth/host/mesh/main.c b/subsys/bluetooth/host/mesh/main.c index 092d3408918..101a046b344 100644 --- a/subsys/bluetooth/host/mesh/main.c +++ b/subsys/bluetooth/host/mesh/main.c @@ -29,6 +29,7 @@ #include "access.h" #include "foundation.h" #include "proxy.h" +#include "settings.h" #include "mesh.h" static bool provisioned; @@ -64,6 +65,13 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, provisioned = true; + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + BT_DBG("Storing network information persistently"); + bt_mesh_store_net(addr, dev_key); + bt_mesh_store_subnet(&bt_mesh.sub[0]); + bt_mesh_store_iv(); + } + if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) { bt_mesh_beacon_enable(); } else { diff --git a/subsys/bluetooth/host/mesh/net.c b/subsys/bluetooth/host/mesh/net.c index 3434400d886..4559518df9c 100644 --- a/subsys/bluetooth/host/mesh/net.c +++ b/subsys/bluetooth/host/mesh/net.c @@ -33,6 +33,7 @@ #include "access.h" #include "foundation.h" #include "beacon.h" +#include "settings.h" /* Minimum valid Mesh Network PDU length. The Network headers * themselves take up 9 bytes. After that there is a minumum of 1 byte @@ -714,6 +715,10 @@ do_update: BT_DBG("Normal mode entered"); bt_mesh.seq = 0; k_delayed_work_cancel(&bt_mesh.ivu_complete); + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_seq(); + } } /* Store time-stamp of the IV procedure state change */ @@ -725,12 +730,22 @@ do_update: } } + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_iv(); + } + return true; } u32_t bt_mesh_next_seq(void) { - return bt_mesh.seq++; + 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 net_buf *buf, diff --git a/subsys/bluetooth/host/mesh/settings.c b/subsys/bluetooth/host/mesh/settings.c index cdb6f4867b8..c9fa91fc7e0 100644 --- a/subsys/bluetooth/host/mesh/settings.c +++ b/subsys/bluetooth/host/mesh/settings.c @@ -31,6 +31,7 @@ #include "access.h" #include "foundation.h" #include "proxy.h" +#include "settings.h" /* Mesh network storage information */ struct net_val { @@ -498,3 +499,139 @@ static int mesh_commit(void) } BT_SETTINGS_DEFINE(mesh, mesh_set, mesh_commit, NULL); + +void bt_mesh_store_net(u16_t primary_addr, const u8_t dev_key[16]) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct net_val))]; + struct net_val net; + char *str; + + BT_DBG("addr 0x%04x DevKey %s", primary_addr, bt_hex(dev_key, 16)); + + net.primary_addr = primary_addr; + memcpy(net.dev_key, dev_key, 16); + + str = settings_str_from_bytes(&net, sizeof(net), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Network as value"); + return; + } + + BT_DBG("Saving Network as value %s", str); + settings_save_one("bt/mesh/Net", str); +} + +void bt_mesh_store_iv(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct iv_val))]; + struct iv_val iv; + char *str; + + iv.iv_index = bt_mesh.iv_index; + iv.iv_update = bt_mesh.iv_update; + + str = settings_str_from_bytes(&iv, sizeof(iv), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode IV as value"); + return; + } + + BT_DBG("Saving IV as value %s", str); + settings_save_one("bt/mesh/IV", str); +} + +void bt_mesh_store_seq(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct seq_val))]; + struct seq_val seq; + char *str; + + seq.val[0] = bt_mesh.seq; + seq.val[1] = bt_mesh.seq >> 8; + seq.val[2] = bt_mesh.seq >> 16; + + str = settings_str_from_bytes(&seq, sizeof(seq), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Seq as value"); + return; + } + + BT_DBG("Saving Seq as value %s", str); + settings_save_one("bt/mesh/Seq", str); +} + +void bt_mesh_store_rpl(struct bt_mesh_rpl *entry) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct rpl_val))]; + struct rpl_val rpl; + char path[18]; + char *str; + + BT_DBG("src 0x%04x seq 0x%06x old_iv %u", entry->src, entry->seq, + entry->old_iv); + + rpl.seq = entry->seq; + rpl.old_iv = entry->old_iv; + + str = settings_str_from_bytes(&rpl, sizeof(rpl), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode RPL as value"); + return; + } + + snprintk(path, sizeof(path), "bt/mesh/RPL/%x", entry->src); + + BT_DBG("Saving RPL %s as value %s", path, str); + settings_save_one(path, str); +} + +void bt_mesh_store_subnet(struct bt_mesh_subnet *sub) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct net_key_val))]; + struct net_key_val key; + char path[20]; + char *str; + + BT_DBG("NetKeyIndex 0x%03x NetKey %s", sub->net_idx, + bt_hex(sub->keys[0].net, 16)); + + memcpy(&key.val[0], sub->keys[0].net, 16); + memcpy(&key.val[1], sub->keys[1].net, 16); + key.kr_flag = sub->kr_flag; + key.kr_phase = sub->kr_phase; + + str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode NetKey as value"); + return; + } + + snprintk(path, sizeof(path), "bt/mesh/NetKey/%x", sub->net_idx); + + BT_DBG("Saving NetKey %s as value %s", path, str); + settings_save_one(path, str); +} + +void bt_mesh_store_app_key(struct bt_mesh_app_key *app) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct app_key_val))]; + struct app_key_val key; + char path[20]; + char *str; + + key.net_idx = app->net_idx; + key.updated = app->updated; + memcpy(key.val[0], app->keys[0].val, 16); + memcpy(key.val[1], app->keys[1].val, 16); + + str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode AppKey as value"); + return; + } + + snprintk(path, sizeof(path), "bt/mesh/AppKey/%x", app->app_idx); + + BT_DBG("Saving AppKey %s as value %s", path, str); + settings_save_one(path, str); +} diff --git a/subsys/bluetooth/host/mesh/settings.h b/subsys/bluetooth/host/mesh/settings.h new file mode 100644 index 00000000000..8be43cff608 --- /dev/null +++ b/subsys/bluetooth/host/mesh/settings.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void bt_mesh_store_net(u16_t primary_addr, const u8_t dev_key[16]); +void bt_mesh_store_iv(void); +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); diff --git a/subsys/bluetooth/host/mesh/transport.c b/subsys/bluetooth/host/mesh/transport.c index 5b7e9fafb2b..e79ed137ac6 100644 --- a/subsys/bluetooth/host/mesh/transport.c +++ b/subsys/bluetooth/host/mesh/transport.c @@ -31,6 +31,7 @@ #include "friend.h" #include "access.h" #include "foundation.h" +#include "settings.h" #include "transport.h" #define AID_MASK ((u8_t)(BIT_MASK(6))) @@ -538,6 +539,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; } @@ -551,6 +557,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;