From c80a52a1e31eaf74d83c1d4e2a47f82936ce4bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 6 Sep 2023 13:06:40 +0200 Subject: [PATCH] Bluetooth: Mesh: Store priv beacon in sep entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stores persistent private beacon state in separate settings entry. This is implemented to avoid issues related to backwards compatibility between device firmware updates. Signed-off-by: Anders Storrø --- subsys/bluetooth/mesh/cfg.c | 27 ++------- subsys/bluetooth/mesh/priv_beacon.h | 7 +++ subsys/bluetooth/mesh/priv_beacon_srv.c | 74 +++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 21 deletions(-) create mode 100644 subsys/bluetooth/mesh/priv_beacon.h diff --git a/subsys/bluetooth/mesh/cfg.c b/subsys/bluetooth/mesh/cfg.c index 287023afa68..4a59f76bbbd 100644 --- a/subsys/bluetooth/mesh/cfg.c +++ b/subsys/bluetooth/mesh/cfg.c @@ -16,6 +16,7 @@ #include "friend.h" #include "adv.h" #include "cfg.h" +#include "priv_beacon.h" #define LOG_LEVEL CONFIG_BT_MESH_CFG_LOG_LEVEL #include @@ -30,11 +31,6 @@ struct cfg_val { uint8_t gatt_proxy; uint8_t frnd; uint8_t default_ttl; -#if defined(CONFIG_BT_MESH_PRIV_BEACONS) - uint8_t priv_beacon; - uint8_t priv_beacon_int; - uint8_t priv_gatt_proxy; -#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) uint8_t on_demand_state; #endif @@ -109,9 +105,9 @@ int bt_mesh_priv_beacon_set(enum bt_mesh_feat_state priv_beacon) /* Beacon timer will stop automatically when all beacons are disabled. */ } - if (IS_ENABLED(CONFIG_BT_SETTINGS) && + if (IS_ENABLED(CONFIG_BT_SETTINGS) && IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACON_SRV) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); + bt_mesh_priv_beacon_srv_store_schedule(); } return 0; @@ -244,9 +240,9 @@ int bt_mesh_priv_gatt_proxy_set(enum bt_mesh_feat_state priv_gatt_proxy) bt_mesh_adv_gatt_update(); } - if (IS_ENABLED(CONFIG_BT_SETTINGS) && + if (IS_ENABLED(CONFIG_BT_SETTINGS) && IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACON_SRV) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); + bt_mesh_priv_beacon_srv_store_schedule(); } return 0; @@ -261,7 +257,6 @@ enum bt_mesh_feat_state bt_mesh_priv_gatt_proxy_get(void) return feature_get(BT_MESH_PRIV_GATT_PROXY); } - int bt_mesh_default_ttl_set(uint8_t default_ttl) { if (default_ttl == 1 || default_ttl > BT_MESH_TTL_MAX) { @@ -454,11 +449,6 @@ static int cfg_set(const char *name, size_t len_rd, bt_mesh_gatt_proxy_set(cfg.gatt_proxy); bt_mesh_friend_set(cfg.frnd); bt_mesh_default_ttl_set(cfg.default_ttl); -#if defined(CONFIG_BT_MESH_PRIV_BEACONS) - bt_mesh_priv_beacon_set(cfg.priv_beacon); - bt_mesh_priv_beacon_update_interval_set(cfg.priv_beacon_int); - bt_mesh_priv_gatt_proxy_set(cfg.priv_gatt_proxy); -#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) bt_mesh_od_priv_proxy_set(cfg.on_demand_state); #endif @@ -476,7 +466,7 @@ static void clear_cfg(void) err = settings_delete("bt/mesh/Cfg"); if (err) { - LOG_ERR("Failed to clear configuration"); + LOG_ERR("Failed to clear configuration (err: %d)", err); } else { LOG_DBG("Cleared configuration"); } @@ -494,11 +484,6 @@ static void store_pending_cfg(void) val.gatt_proxy = bt_mesh_gatt_proxy_get(); val.frnd = bt_mesh_friend_get(); val.default_ttl = bt_mesh_default_ttl_get(); -#if defined(CONFIG_BT_MESH_PRIV_BEACONS) - val.priv_beacon = bt_mesh_priv_beacon_get(); - val.priv_beacon_int = bt_mesh_priv_beacon_update_interval_get(); - val.priv_gatt_proxy = bt_mesh_priv_gatt_proxy_get(); -#endif #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) val.on_demand_state = bt_mesh_od_priv_proxy_get(); #endif diff --git a/subsys/bluetooth/mesh/priv_beacon.h b/subsys/bluetooth/mesh/priv_beacon.h new file mode 100644 index 00000000000..0cbbdafd0b1 --- /dev/null +++ b/subsys/bluetooth/mesh/priv_beacon.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void bt_mesh_priv_beacon_srv_store_schedule(void); diff --git a/subsys/bluetooth/mesh/priv_beacon_srv.c b/subsys/bluetooth/mesh/priv_beacon_srv.c index a1478efff80..377703e8352 100644 --- a/subsys/bluetooth/mesh/priv_beacon_srv.c +++ b/subsys/bluetooth/mesh/priv_beacon_srv.c @@ -11,11 +11,33 @@ #include "foundation.h" #include "beacon.h" #include "cfg.h" +#include "settings.h" #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_mesh_priv_beacon_srv); +static struct bt_mesh_model *priv_beacon_srv; + +/* Private Beacon configuration server model states */ +struct { + uint8_t state; + uint8_t interval; + uint8_t proxy_state; +} priv_beacon_state; + +static int priv_beacon_store(bool delete) +{ + if (!IS_ENABLED(CONFIG_BT_SETTINGS)) { + return 0; + } + + const void *data = delete ? NULL : &priv_beacon_state; + size_t len = delete ? 0 : sizeof(priv_beacon_state); + + return bt_mesh_model_data_store(priv_beacon_srv, false, "pb", data, len); +} + static int beacon_status_rsp(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx) { @@ -179,11 +201,63 @@ static int priv_beacon_srv_init(struct bt_mesh_model *mod) return -EINVAL; } + priv_beacon_srv = mod; mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; return 0; } +static void priv_beacon_srv_reset(struct bt_mesh_model *model) +{ + (void)memset(&priv_beacon_state, 0, sizeof(priv_beacon_state)); + priv_beacon_store(true); +} + +#ifdef CONFIG_BT_SETTINGS +static int priv_beacon_srv_settings_set(struct bt_mesh_model *model, const char *name, + size_t len_rd, settings_read_cb read_cb, void *cb_data) +{ + int err; + + if (len_rd == 0) { + LOG_DBG("Cleared configuration state"); + return 0; + } + + err = bt_mesh_settings_set(read_cb, cb_data, &priv_beacon_state, sizeof(priv_beacon_state)); + if (err) { + LOG_ERR("Failed to set Private Beacon state"); + return err; + } + + bt_mesh_priv_beacon_set(priv_beacon_state.state); + bt_mesh_priv_beacon_update_interval_set(priv_beacon_state.interval); + bt_mesh_priv_gatt_proxy_set(priv_beacon_state.proxy_state); + return 0; +} + +static void priv_beacon_srv_pending_store(struct bt_mesh_model *model) +{ + priv_beacon_state.state = bt_mesh_priv_beacon_get(); + priv_beacon_state.interval = bt_mesh_priv_beacon_update_interval_get(); + priv_beacon_state.proxy_state = bt_mesh_priv_gatt_proxy_get(); + + priv_beacon_store(false); +} +#endif + const struct bt_mesh_model_cb bt_mesh_priv_beacon_srv_cb = { .init = priv_beacon_srv_init, + .reset = priv_beacon_srv_reset, +#ifdef CONFIG_BT_SETTINGS + .settings_set = priv_beacon_srv_settings_set, + .pending_store = priv_beacon_srv_pending_store, +#endif }; + +void bt_mesh_priv_beacon_srv_store_schedule(void) +{ + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_model_data_store_schedule(priv_beacon_srv); + } +}