Bluetooth: Mesh: Store priv beacon in sep entry

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ø <anders.storro@nordicsemi.no>
This commit is contained in:
Anders Storrø 2023-09-06 13:06:40 +02:00 committed by Carles Cufí
commit c80a52a1e3
3 changed files with 87 additions and 21 deletions

View file

@ -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 <zephyr/logging/log.h>
@ -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

View file

@ -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);

View file

@ -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 <zephyr/logging/log.h>
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);
}
}