diff --git a/include/bluetooth/mesh/access.h b/include/bluetooth/mesh/access.h index 64f47dc6066..90a75da02f3 100644 --- a/include/bluetooth/mesh/access.h +++ b/include/bluetooth/mesh/access.h @@ -10,6 +10,8 @@ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_ACCESS_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_ACCESS_H_ +#include + /** * @brief Bluetooth Mesh Access Layer * @defgroup bt_mesh_access Bluetooth Mesh Access Layer @@ -382,6 +384,35 @@ struct bt_mesh_model_pub { /** Model callback functions. */ struct bt_mesh_model_cb { + /** @brief Set value handler of user data tied to the model. + * + * @sa settings_handler::h_set + * + * @param model Model to set the persistent data of. + * @param len_rd The size of the data found in the backend. + * @param read_cb Function provided to read the data from the backend. + * @param cb_arg Arguments for the read function provided by the + * backend. + * + * @return 0 on success, error otherwise. + */ + int (*const settings_set)(struct bt_mesh_model *model, + size_t len_rd, settings_read_cb read_cb, + void *cb_arg); + + /** @brief Callback called when all settings have been loaded. + * + * This handler gets called after the settings have been loaded in + * full. + * + * @sa settings_handler::h_commit + * + * @param model Model this callback belongs to. + * + * @return 0 on success, error otherwise. + */ + int (*const settings_commit)(struct bt_mesh_model *model); + /** @brief Model init callback. * * Called on every model instance during mesh initialization. @@ -515,6 +546,18 @@ static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod) return (mod->elem_idx == 0); } +/** @brief Immediately store the model's user data in persistent storage. + * + * @param mod Mesh model. + * @param vnd This is a vendor model. + * @param data Model data to store, or NULL to delete any model data. + * @param data_len Length of the model data. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, + const void *data, size_t data_len); + /** Node Composition */ struct bt_mesh_comp { u16_t cid; diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 1ac2b85bff8..a1583491030 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -660,6 +660,10 @@ static int mod_set(bool vnd, const char *name, size_t len_rd, return mod_set_pub(mod, len_rd, read_cb, cb_arg); } + if (!strncmp(next, "data", len) && mod->cb && mod->cb->settings_set) { + return mod->cb->settings_set(mod, len_rd, read_cb, cb_arg); + } + BT_WARN("Unknown module key %s", next); return -ENOENT; } @@ -759,6 +763,10 @@ static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, k_delayed_work_submit(&mod->pub->timer, ms); } } + + if (mod->cb && mod->cb->settings_commit) { + mod->cb->settings_commit(mod); + } } static int mesh_commit(void) @@ -1574,6 +1582,28 @@ void bt_mesh_store_mod_pub(struct bt_mesh_model *mod) schedule_store(BT_MESH_MOD_PENDING); } +int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, + const void *data, size_t data_len) +{ + char path[20]; + int err; + + encode_mod_path(mod, vnd, "data", path, sizeof(path)); + + if (data_len) { + err = settings_save_one(path, data, data_len); + } else { + err = settings_delete(path); + } + + if (err) { + BT_ERR("Failed to store %s value", log_strdup(path)); + } else { + BT_DBG("Stored %s value", log_strdup(path)); + } + return err; +} + void bt_mesh_settings_init(void) { k_delayed_work_init(&pending_store, store_pending);