From 94451b22fcc6a068de2a2982b202772c6bbefae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Delawarde?= Date: Tue, 2 Apr 2019 11:06:05 +0200 Subject: [PATCH] subsys/settings: Allow to register custom backends in settings subsystem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major changes are: - Expose settings backend API to enable custom backend support. - Add a new CONFIG_SETTINGS_CUSTOM backend to allow registering a custom backend. - Change api of the handlers h_set() routines to allow for backend-specific read callbacks. - Provide a customizable settings_backend_init() routine for custom backends. - Move runtime settings support to be its own backend. Signed-off-by: François Delawarde --- doc/reference/storage/settings/settings.rst | 88 +++++++-- include/settings/settings.h | 179 ++++++++++++------ .../src/storage.c | 51 +++-- subsys/bluetooth/host/gatt.c | 21 +- subsys/bluetooth/host/keys.c | 16 +- subsys/bluetooth/host/mesh/settings.c | 128 +++++++------ subsys/bluetooth/host/settings.c | 24 +-- subsys/bluetooth/host/settings.h | 3 +- subsys/settings/Kconfig | 21 +- subsys/settings/src/CMakeLists.txt | 1 + subsys/settings/src/settings.c | 129 +------------ subsys/settings/src/settings_fcb.c | 46 ++++- subsys/settings/src/settings_file.c | 56 ++++-- subsys/settings/src/settings_init.c | 48 +++-- subsys/settings/src/settings_line.c | 115 ++++++++++- subsys/settings/src/settings_priv.h | 54 +++--- subsys/settings/src/settings_runtime.c | 68 +++++++ subsys/settings/src/settings_store.c | 104 +--------- tests/subsys/settings/fcb/base64/prj.conf | 1 + tests/subsys/settings/fcb/raw/prj.conf | 1 + .../settings/fcb/src/settings_test_fcb.c | 43 +++-- tests/subsys/settings/fcb_init/prj.conf | 1 + .../fcb_init/src/settings_test_fcb_init.c | 7 +- tests/subsys/settings/nffs/base64/prj.conf | 1 + tests/subsys/settings/nffs/raw/prj.conf | 1 + .../settings/nffs/src/settings_test_nffs.c | 18 +- .../settings/src/settings_empty_lookups.c | 8 +- .../settings/src/settings_test_commit.c | 6 +- .../settings/src/settings_test_getset_int.c | 4 +- .../settings/src/settings_test_getset_int64.c | 8 +- .../src/settings_test_getset_unknown.c | 8 +- 31 files changed, 727 insertions(+), 532 deletions(-) create mode 100644 subsys/settings/src/settings_runtime.c diff --git a/doc/reference/storage/settings/settings.rst b/doc/reference/storage/settings/settings.rst index e346da5e71f7..49ea785424d3 100644 --- a/doc/reference/storage/settings/settings.rst +++ b/doc/reference/storage/settings/settings.rst @@ -21,13 +21,13 @@ Settings handlers for subtree implement a set of handler functions. These are registered using a call to ``settings_register()``. **h_get** - This gets called when asking for a settings element value - by its name using ``settings_get_value()``. + This gets called when asking for a settings element value by its name using + ``settings_runtime_get()`` from the runtime backend. **h_set** - This gets called when the value is being set using ``settings_set_value()``, - and also when setting is loaded from persisted storage with - ``settings_load()``. + This gets called when the value is loaded from persisted storage with + ``settings_load()``, or when using ``settings_runtime_set()`` from the + runtime backend. **h_commit** This gets called after the settings have been loaded in full. @@ -40,11 +40,38 @@ These are registered using a call to ``settings_register()``. when ``settings_save()`` tries to save the settings or transfer to any user-implemented back-end. -Persistence -*********** +Backends +******** + +Backends are meant to load and save data to/from setting handlers, and +implement a set of handler functions. These are registered using a call to +``settings_src_register()`` for backends that can load data, and/or +``settings_dst_register()`` for backends that can save data. The current +implementation allows for multiple source backends but only a single destination +backend. + +**csi_load** + This gets called when loading values from persistent storage using + ``settings_load()``. + +**csi_save** + This gets called when a saving a single setting to persistent storage using + ``settings_save_one()``. -Backend storage for the settings can be a Flash Circular Buffer (FCB) -or a file in the filesystem. +**csi_save_start** + This gets called when starting a save of all current settings using + ``settings_save()``. + +**csi_save_end** + This gets called after having saved of all current settings using + ``settings_save()``. + +Zephyr Storage Backends +*********************** + +Zephyr has two existing backend storages which can be a Flash Circular Buffer +(:option:`CONFIG_SETTINGS_FCB`) or a file in the filesystem +(:option:`CONFIG_SETTINGS_FS`). You can declare multiple sources for settings; settings from all of these are restored when ``settings_load()`` is called. @@ -89,12 +116,12 @@ export functionality, for example, writing to the shell console). .h_export = foo_settings_export }; - static int foo_settings_set(int argc, char **argv, void *value_ctx) + static int foo_settings_set(int argc, char **argv, settings_read_cb read_cb, + void *cb_arg) { if (argc == 1) { if (!strcmp(argv[0], "bar")) { - return settings_val_read_cb(value_ctx, &foo_val, - sizeof(foo_val)); + return read_cb(cb_arg, &foo_val, sizeof(foo_val)); } } @@ -129,12 +156,12 @@ up from where it was before restart. .h_set = foo_settings_set }; - static int foo_settings_set(int argc, char **argv, void *value_ctx) + static int foo_settings_set(int argc, char **argv, settings_read_cb read_cb, + void *cb_arg) { if (argc == 1) { if (!strcmp(argv[0], "bar")) { - return settings_val_read_cb(value_ctx, &foo_val, - sizeof(foo_val)); + return read_cb(cb_arg, &foo_val, sizeof(foo_val)); } } @@ -152,6 +179,37 @@ up from where it was before restart. sys_reboot(SYS_REBOOT_COLD); } +Example: Custom Backend Implementation +************************************** + +This is a simple example showing how to register a simple custom backend +handler (:option:`CONFIG_SETTINGS_CUSTOM`). + +.. code-block:: c + + static int settings_custom_load(struct settings_store *cs) + { + //... + } + + static int settings_custom_save(struct settings_store *cs, const char *name, + const char *value, size_t val_len) + { + //... + } + + static struct settings_store_itf settings_custom_itf = { + .csi_load = settings_custom_load, + .csi_save = settings_custom_save, + }; + + int settings_backend_init(void) + { + settings_dst_register(&settings_custom_itf); + settings_src_register(&settings_custom_itf); + return 0; + } + API Reference ************* diff --git a/include/settings/settings.h b/include/settings/settings.h index 3f96cae5b1f8..f2f4e43914af 100644 --- a/include/settings/settings.h +++ b/include/settings/settings.h @@ -33,7 +33,7 @@ extern "C" { */ #define SETTINGS_EXTRA_LEN ((SETTINGS_MAX_DIR_DEPTH - 1) + 2) -#define SETTINGS_NMGR_OP 0 +typedef ssize_t (*settings_read_cb)(void *cb_arg, void *data, size_t len); /** * @struct settings_handler @@ -57,14 +57,16 @@ struct settings_handler { * - val_len_max - size of that buffer. */ - int (*h_set)(int argc, char **argv, void *value_ctx); + int (*h_set)(int argc, char **argv, size_t len, + settings_read_cb read_cb, void *cb_arg); /**< Set value handler of settings items identified by keyword names. * * Parameters: - * - argc - count of item in argv, argv - array of pointers to keyword - * names. - * - value_ctx - pointer to the value context which is used parameter - * for data extracting routine (@ref settings_val_read_cb). + * - argc - count of item in argv. + * - argv - array of pointers to keyword names. + * - len - the size of the data found in the backend. + * - read_cb - function provided to read the data from the backend. + * - cb_arg - arguments for the read function provided by the backend. */ int (*h_commit)(void); @@ -152,86 +154,149 @@ int settings_save_one(const char *name, void *value, size_t val_len); int settings_delete(const char *name); /** - * Set settings item identified by @p name to be value @p value. - * This finds the settings handler for this subtree and calls it's - * set handler. - * - * @param name Name/key of the settings item. - * @param value Pointer to the value of the settings item. This value will - * be transferred to the @ref settings_handler::h_set handler implementation. - * @param len Length of value string. + * Call commit for all settings handler. This should apply all + * settings which has been set, but not applied yet. * * @return 0 on success, non-zero on failure. */ -int settings_set_value(char *name, void *value, size_t len); +int settings_commit(void); /** - * Get value of settings item identified by @p name. - * This calls the settings handler h_get for the subtree. - * - * Configuration handler should copy the string to @p buf, the maximum - * number of bytes it will copy is limited by @p buf_len. + * @} settings + */ + + +/* + * API for config storage + */ + +struct settings_store_itf; + +/** + * @struct settings_store + * Backend handler node for storage handling. + */ +struct settings_store { + sys_snode_t cs_next; + /**< Linked list node info for internal usage. */ + + const struct settings_store_itf *cs_itf; + /**< Backend handler structure. */ +}; + +/** + * @struct settings_store_itf + * Backend handler functions. + * Sources are registered using a call to @ref settings_src_register. + * Destinations are registered using a call to @ref settings_dst_register. + */ +struct settings_store_itf { + int (*csi_load)(struct settings_store *cs); + /**< Loads all values from storage. + * + * Parameters: + * - cs - Corresponding backend handler node + */ + + int (*csi_save_start)(struct settings_store *cs); + /**< Handler called before an export operation. + * + * Parameters: + * - cs - Corresponding backend handler node + */ + + int (*csi_save)(struct settings_store *cs, const char *name, + const char *value, size_t val_len); + /**< Save a single key-value pair to storage. + * + * Parameters: + * - cs - Corresponding backend handler node + * - name - Key in string format + * - value - Binary value + * - val_len - Length of value in bytes. + */ + + int (*csi_save_end)(struct settings_store *cs); + /**< Handler called after an export operation. + * + * Parameters: + * - cs - Corresponding backend handler node + */ +}; + +/** + * Register a backend handler acting as source. * - * @param name Name/key of the settings item. + * @param cs Backend handler node containing handler information. * - * @param buf buffer for value of the settings item. - * If value is not string, the value will be filled in *buf. + */ +void settings_src_register(struct settings_store *cs); + +/** + * Register a backend handler acting as destination. * - * @param buf_len size of buf. + * @param cs Backend handler node containing handler information. * - * @return Positive: Length of copied dat. Negative: -ERCODE */ -int settings_get_value(char *name, char *buf, int buf_len); +void settings_dst_register(struct settings_store *cs); + + +/* + * API for handler lookup + */ /** - * Call commit for all settings handler. This should apply all - * settings which has been set, but not applied yet. + * Parses a key to an array of elements and locate corresponding module handler. * - * @param name Name of the settings subtree, or NULL to commit everything. + * @param name Key in string format + * @param name_argc Parsed number of elements. + * @param name_argv Parsed array of elements. * - * @return 0 on success, non-zero on failure. + * @return settings_handler node on success, NULL on failure. + */ +struct settings_handler *settings_parse_and_lookup(char *name, int *name_argc, + char *name_argv[]); + + +/* + * API for runtime settings */ -int settings_commit(char *name); + +#ifdef CONFIG_SETTINGS_RUNTIME /** - * Persistent data extracting routine. - * - * This function read and decode data from non-volatile storage to user buffer - * This function should be used inside set handler in order to read the settings - * data from backend storage. + * Set a value with a specific key to a module handler. * - * @param[in] value_ctx Data context provided by the h_set handler. - * @param[out] buf Buffer for data read. - * @param[in] len Length of @p buf. + * @param name Key in string format. + * @param data Binary value. + * @param len Value length in bytes. * - * @retval Negative value on failure. 0 and positive: Length of data loaded to - * the @p buf. + * @return 0 on success, non-zero on failure. */ -int settings_val_read_cb(void *value_ctx, void *buf, size_t len); +int settings_runtime_set(const char *name, void *data, size_t len); /** - * This function fetch length of decode data. - * This function should be used inside set handler in order to detect the - * settings data length. + * Get a value corresponding to a key from a module handler. * - * @param[in] value_ctx Data context provided by the h_set handler. + * @param name Key in string format. + * @param data Returned binary value. + * @param len Returned value length in bytes. * - * @retval length of data. + * @return 0 on success, non-zero on failure. */ -size_t settings_val_get_len_cb(void *value_ctx); +int settings_runtime_get(const char *name, void *data, size_t len); /** - * @} settings + * Apply settings in a module handler. + * + * @param name Key in string format. + * + * @return 0 on success, non-zero on failure. */ +int settings_runtime_commit(const char *name); + +#endif /* CONFIG_SETTINGS_RUNTIME */ -/* - * Config storage - */ -struct settings_store_itf; -struct settings_store { - sys_snode_t cs_next; - const struct settings_store_itf *cs_itf; -}; #ifdef __cplusplus } diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/storage.c b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/storage.c index 3ad79012a5f4..764535f48418 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/storage.c +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/storage.c @@ -114,56 +114,51 @@ void save_on_flash(u8_t id) k_work_submit(&storage_work); } -static int ps_set(int argc, char **argv, void *val_ctx) +static int ps_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { - int len = 0; + size_t len = 0; if (argc == 1) { if (!strcmp(argv[0], "rc")) { - len = settings_val_read_cb(val_ctx, &reset_counter, - sizeof(reset_counter)); + len = read_cb(cb_arg, &reset_counter, + sizeof(reset_counter)); } if (!strcmp(argv[0], "gdtt")) { - len = settings_val_read_cb( - val_ctx, - &gen_def_trans_time_srv_user_data.tt, - sizeof(gen_def_trans_time_srv_user_data.tt)); + len = read_cb(cb_arg, + &gen_def_trans_time_srv_user_data.tt, + sizeof(gen_def_trans_time_srv_user_data.tt)); } if (!strcmp(argv[0], "gpo")) { - len = settings_val_read_cb( - val_ctx, - &gen_power_onoff_srv_user_data.onpowerup, - sizeof(gen_power_onoff_srv_user_data.onpowerup)); + len = read_cb(cb_arg, + &gen_power_onoff_srv_user_data.onpowerup, + sizeof(gen_power_onoff_srv_user_data.onpowerup)); } if (!strcmp(argv[0], "ltd")) { - len = settings_val_read_cb( - val_ctx, - &light_ctl_srv_user_data.lightness_temp_def, - sizeof(light_ctl_srv_user_data.lightness_temp_def)); + len = read_cb(cb_arg, + &light_ctl_srv_user_data.lightness_temp_def, + sizeof(light_ctl_srv_user_data.lightness_temp_def)); } if (!strcmp(argv[0], "ltl")) { - len = settings_val_read_cb( - val_ctx, - &light_ctl_srv_user_data.lightness_temp_last, - sizeof(light_ctl_srv_user_data.lightness_temp_last)); + len = read_cb(cb_arg, + &light_ctl_srv_user_data.lightness_temp_last, + sizeof(light_ctl_srv_user_data.lightness_temp_last)); } if (!strcmp(argv[0], "lr")) { - len = settings_val_read_cb( - val_ctx, - &light_lightness_srv_user_data.lightness_range, - sizeof(light_lightness_srv_user_data.lightness_range)); + len = read_cb(cb_arg, + &light_lightness_srv_user_data.lightness_range, + sizeof(light_lightness_srv_user_data.lightness_range)); } if (!strcmp(argv[0], "tr")) { - len = settings_val_read_cb( - val_ctx, - &light_ctl_srv_user_data.temperature_range, - sizeof(light_ctl_srv_user_data.temperature_range)); + len = read_cb(cb_arg, + &light_ctl_srv_user_data.temperature_range, + sizeof(light_ctl_srv_user_data.temperature_range)); } return (len < 0) ? len : 0; diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 8a49b9c06904..3b98823a645d 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -3332,7 +3332,8 @@ static u8_t ccc_load(const struct bt_gatt_attr *attr, void *user_data) return load->count ? BT_GATT_ITER_CONTINUE : BT_GATT_ITER_STOP; } -static int ccc_set(int argc, char **argv, void *val_ctx) +static int ccc_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct ccc_store ccc_store[CCC_STORE_MAX]; struct ccc_load load; @@ -3356,9 +3357,8 @@ static int ccc_set(int argc, char **argv, void *val_ctx) load.addr_with_id.addr = &addr; - if (settings_val_get_len_cb(val_ctx)) { - len = settings_val_read_cb(val_ctx, ccc_store, - sizeof(ccc_store)); + if (len_rd) { + len = read_cb(cb_arg, ccc_store, sizeof(ccc_store)); if (len < 0) { BT_ERR("Failed to decode value (err %d)", len); @@ -3388,7 +3388,8 @@ static int ccc_set(int argc, char **argv, void *val_ctx) BT_SETTINGS_DEFINE(ccc, ccc_set, NULL, NULL); #if defined(CONFIG_BT_GATT_CACHING) -static int cf_set(int argc, char **argv, void *val_ctx) +static int cf_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct gatt_cf_cfg *cfg; bt_addr_le_t addr; @@ -3414,9 +3415,8 @@ static int cf_set(int argc, char **argv, void *val_ctx) } } - if (settings_val_get_len_cb(val_ctx)) { - len = settings_val_read_cb(val_ctx, cfg->data, - sizeof(cfg->data)); + if (len_rd) { + len = read_cb(cb_arg, cfg->data, sizeof(cfg->data)); if (len < 0) { BT_ERR("Failed to decode value (err %d)", len); return len; @@ -3436,11 +3436,12 @@ BT_SETTINGS_DEFINE(cf, cf_set, NULL, NULL); static u8_t stored_hash[16]; -static int db_hash_set(int argc, char **argv, void *val_ctx) +static int db_hash_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { int len; - len = settings_val_read_cb(val_ctx, stored_hash, sizeof(stored_hash)); + len = read_cb(cb_arg, stored_hash, sizeof(stored_hash)); if (len < 0) { BT_ERR("Failed to decode value (err %d)", len); return len; diff --git a/subsys/bluetooth/host/keys.c b/subsys/bluetooth/host/keys.c index 8715a665cb90..9edbe8149b1c 100644 --- a/subsys/bluetooth/host/keys.c +++ b/subsys/bluetooth/host/keys.c @@ -271,12 +271,14 @@ int bt_keys_store(struct bt_keys *keys) return 0; } -static int keys_set(int argc, char **argv, void *value_ctx) +static int keys_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct bt_keys *keys; bt_addr_le_t addr; u8_t id; - int len, err; + size_t len; + int err; char val[BT_KEYS_STORAGE_LEN]; if (argc < 1) { @@ -284,9 +286,9 @@ static int keys_set(int argc, char **argv, void *value_ctx) return -EINVAL; } - len = settings_val_read_cb(value_ctx, val, sizeof(val)); + len = read_cb(cb_arg, val, sizeof(val)); if (len < 0) { - BT_ERR("Failed to read value (err %d)", len); + BT_ERR("Failed to read value (err %zu)", len); return -EINVAL; } @@ -323,9 +325,9 @@ static int keys_set(int argc, char **argv, void *value_ctx) return -ENOMEM; } - if (settings_val_get_len_cb(value_ctx) != BT_KEYS_STORAGE_LEN) { - BT_ERR("Invalid key length %d != %zu", len, - BT_KEYS_STORAGE_LEN); + if (len_rd != BT_KEYS_STORAGE_LEN) { + BT_ERR("Invalid key length %zu != %zu", len, + BT_KEYS_STORAGE_LEN); bt_keys_clear(keys); return -EINVAL; } else { diff --git a/subsys/bluetooth/host/mesh/settings.c b/subsys/bluetooth/host/mesh/settings.c index 66203e41d72f..ec3342e38588 100644 --- a/subsys/bluetooth/host/mesh/settings.c +++ b/subsys/bluetooth/host/mesh/settings.c @@ -125,33 +125,35 @@ static struct { struct cfg_val cfg; } stored_cfg; -static inline int mesh_x_set(void *val_ctx, void *out, size_t read_len) +static inline int mesh_x_set(settings_read_cb read_cb, void *cb_arg, void *out, + size_t read_len) { - int len; + size_t len; - len = settings_val_read_cb(val_ctx, out, read_len); + len = read_cb(cb_arg, out, read_len); if (len < 0) { - BT_ERR("Failed to read value (err %d)", len); + BT_ERR("Failed to read value (err %zu)", len); return len; } BT_HEXDUMP_DBG(out, len, "val"); if (len != read_len) { - BT_ERR("Unexpected value length (%d != %zu)", len, read_len); + BT_ERR("Unexpected value length (%zu != %zu)", len, read_len); return -EINVAL; } return 0; } -static int net_set(int argc, char **argv, void *val_ctx) +static int net_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct net_val net; int err; - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { BT_DBG("val (null)"); bt_mesh_comp_unprovision(); @@ -159,7 +161,7 @@ static int net_set(int argc, char **argv, void *val_ctx) return 0; } - err = mesh_x_set(val_ctx, &net, sizeof(net)); + err = mesh_x_set(read_cb, cb_arg, &net, sizeof(net)); if (err) { BT_ERR("Failed to set \'net\'"); return err; @@ -174,12 +176,13 @@ static int net_set(int argc, char **argv, void *val_ctx) return 0; } -static int iv_set(int argc, char **argv, void *val_ctx) +static int iv_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct iv_val iv; int err; - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { BT_DBG("IV deleted"); bt_mesh.iv_index = 0U; @@ -187,7 +190,7 @@ static int iv_set(int argc, char **argv, void *val_ctx) return 0; } - err = mesh_x_set(val_ctx, &iv, sizeof(iv)); + err = mesh_x_set(read_cb, cb_arg, &iv, sizeof(iv)); if (err) { BT_ERR("Failed to set \'iv\'"); return err; @@ -203,19 +206,20 @@ static int iv_set(int argc, char **argv, void *val_ctx) return 0; } -static int seq_set(int argc, char **argv, void *val_ctx) +static int seq_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct seq_val seq; int err; - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { BT_DBG("val (null)"); bt_mesh.seq = 0U; return 0; } - err = mesh_x_set(val_ctx, &seq, sizeof(seq)); + err = mesh_x_set(read_cb, cb_arg, &seq, sizeof(seq)); if (err) { BT_ERR("Failed to set \'seq\'"); return err; @@ -266,7 +270,8 @@ static struct bt_mesh_rpl *rpl_alloc(u16_t src) return NULL; } -static int rpl_set(int argc, char **argv, void *val_ctx) +static int rpl_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct bt_mesh_rpl *entry; struct rpl_val rpl; @@ -281,7 +286,7 @@ static int rpl_set(int argc, char **argv, void *val_ctx) src = strtol(argv[0], NULL, 16); entry = rpl_find(src); - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { BT_DBG("val (null)"); if (entry) { (void)memset(entry, 0, sizeof(*entry)); @@ -300,7 +305,7 @@ static int rpl_set(int argc, char **argv, void *val_ctx) } } - err = mesh_x_set(val_ctx, &rpl, sizeof(rpl)); + err = mesh_x_set(read_cb, cb_arg, &rpl, sizeof(rpl)); if (err) { BT_ERR("Failed to set `net`"); return err; @@ -315,7 +320,8 @@ static int rpl_set(int argc, char **argv, void *val_ctx) return 0; } -static int net_key_set(int argc, char **argv, void *val_ctx) +static int net_key_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct bt_mesh_subnet *sub; struct net_key_val key; @@ -325,7 +331,7 @@ static int net_key_set(int argc, char **argv, void *val_ctx) net_idx = strtol(argv[0], NULL, 16); sub = bt_mesh_subnet_get(net_idx); - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { BT_DBG("val (null)"); if (!sub) { BT_ERR("No subnet with NetKeyIndex 0x%03x", net_idx); @@ -337,7 +343,7 @@ static int net_key_set(int argc, char **argv, void *val_ctx) return 0; } - err = mesh_x_set(val_ctx, &key, sizeof(key)); + err = mesh_x_set(read_cb, cb_arg, &key, sizeof(key)); if (err) { BT_ERR("Failed to set \'net-key\'"); return err; @@ -377,7 +383,8 @@ static int net_key_set(int argc, char **argv, void *val_ctx) return 0; } -static int app_key_set(int argc, char **argv, void *val_ctx) +static int app_key_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct bt_mesh_app_key *app; struct app_key_val key; @@ -386,7 +393,7 @@ static int app_key_set(int argc, char **argv, void *val_ctx) app_idx = strtol(argv[0], NULL, 16); - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { BT_DBG("val (null)"); BT_DBG("Deleting AppKeyIndex 0x%03x", app_idx); @@ -398,7 +405,7 @@ static int app_key_set(int argc, char **argv, void *val_ctx) return 0; } - err = mesh_x_set(val_ctx, &key, sizeof(key)); + err = mesh_x_set(read_cb, cb_arg, &key, sizeof(key)); if (err) { BT_ERR("Failed to set \'app-key\'"); return err; @@ -428,7 +435,8 @@ static int app_key_set(int argc, char **argv, void *val_ctx) return 0; } -static int hb_pub_set(int argc, char **argv, void *val_ctx) +static int hb_pub_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct bt_mesh_hb_pub *pub = bt_mesh_hb_pub_get(); struct hb_pub_val hb_val; @@ -438,7 +446,7 @@ static int hb_pub_set(int argc, char **argv, void *val_ctx) return -ENOENT; } - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { pub->dst = BT_MESH_ADDR_UNASSIGNED; pub->count = 0U; pub->ttl = 0U; @@ -449,7 +457,7 @@ static int hb_pub_set(int argc, char **argv, void *val_ctx) return 0; } - err = mesh_x_set(val_ctx, &hb_val, sizeof(hb_val)); + err = mesh_x_set(read_cb, cb_arg, &hb_val, sizeof(hb_val)); if (err) { BT_ERR("Failed to set \'hb_val\'"); return err; @@ -472,7 +480,8 @@ static int hb_pub_set(int argc, char **argv, void *val_ctx) return 0; } -static int cfg_set(int argc, char **argv, void *val_ctx) +static int cfg_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); int err; @@ -481,14 +490,15 @@ static int cfg_set(int argc, char **argv, void *val_ctx) return -ENOENT; } - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { stored_cfg.valid = false; BT_DBG("Cleared configuration state"); return 0; } - err = mesh_x_set(val_ctx, &stored_cfg.cfg, sizeof(stored_cfg.cfg)); + err = mesh_x_set(read_cb, cb_arg, &stored_cfg.cfg, + sizeof(stored_cfg.cfg)); if (err) { BT_ERR("Failed to set \'cfg\'"); return err; @@ -500,23 +510,25 @@ static int cfg_set(int argc, char **argv, void *val_ctx) return 0; } -static int mod_set_bind(struct bt_mesh_model *mod, void *val_ctx) +static int mod_set_bind(struct bt_mesh_model *mod, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { - int len, i; + size_t len; + int i; /* Start with empty array regardless of cleared or set value */ for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { mod->keys[i] = BT_MESH_KEY_UNUSED; } - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { BT_DBG("Cleared bindings for model"); return 0; } - len = settings_val_read_cb(val_ctx, mod->keys, sizeof(mod->keys)); + len = read_cb(cb_arg, mod->keys, sizeof(mod->keys)); if (len < 0) { - BT_ERR("Failed to read value (err %d)", len); + BT_ERR("Failed to read value (err %zu)", len); return len; } @@ -525,21 +537,22 @@ static int mod_set_bind(struct bt_mesh_model *mod, void *val_ctx) return 0; } -static int mod_set_sub(struct bt_mesh_model *mod, void *val_ctx) +static int mod_set_sub(struct bt_mesh_model *mod, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { - int len; + size_t len; /* Start with empty array regardless of cleared or set value */ (void)memset(mod->groups, 0, sizeof(mod->groups)); - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { BT_DBG("Cleared subscriptions for model"); return 0; } - len = settings_val_read_cb(val_ctx, mod->groups, sizeof(mod->groups)); + len = read_cb(cb_arg, mod->groups, sizeof(mod->groups)); if (len < 0) { - BT_ERR("Failed to read value (err %d)", len); + BT_ERR("Failed to read value (err %zu)", len); return len; } @@ -548,17 +561,18 @@ static int mod_set_sub(struct bt_mesh_model *mod, void *val_ctx) return 0; } -static int mod_set_pub(struct bt_mesh_model *mod, void *val_ctx) +static int mod_set_pub(struct bt_mesh_model *mod, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct mod_pub_val pub; - int err; + int err; if (!mod->pub) { BT_WARN("Model has no publication context!"); return -EINVAL; } - if (settings_val_get_len_cb(val_ctx) == 0) { + if (len_rd == 0) { mod->pub->addr = BT_MESH_ADDR_UNASSIGNED; mod->pub->key = 0U; mod->pub->cred = 0U; @@ -571,7 +585,7 @@ static int mod_set_pub(struct bt_mesh_model *mod, void *val_ctx) return 0; } - err = mesh_x_set(val_ctx, &pub, sizeof(pub)); + err = mesh_x_set(read_cb, cb_arg, &pub, sizeof(pub)); if (err) { BT_ERR("Failed to set \'model-pub\'"); return err; @@ -591,7 +605,8 @@ static int mod_set_pub(struct bt_mesh_model *mod, void *val_ctx) return 0; } -static int mod_set(bool vnd, int argc, char **argv, void *val_ctx) +static int mod_set(bool vnd, int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { struct bt_mesh_model *mod; u8_t elem_idx, mod_idx; @@ -617,34 +632,37 @@ static int mod_set(bool vnd, int argc, char **argv, void *val_ctx) } if (!strcmp(argv[1], "bind")) { - return mod_set_bind(mod, val_ctx); + return mod_set_bind(mod, len_rd, read_cb, cb_arg); } if (!strcmp(argv[1], "sub")) { - return mod_set_sub(mod, val_ctx); + return mod_set_sub(mod, len_rd, read_cb, cb_arg); } if (!strcmp(argv[1], "pub")) { - return mod_set_pub(mod, val_ctx); + return mod_set_pub(mod, len_rd, read_cb, cb_arg); } BT_WARN("Unknown module key %s", argv[1]); return -ENOENT; } -static int sig_mod_set(int argc, char **argv, void *val_ctx) +static int sig_mod_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { - return mod_set(false, argc, argv, val_ctx); + return mod_set(false, argc, argv, len_rd, read_cb, cb_arg); } -static int vnd_mod_set(int argc, char **argv, void *val_ctx) +static int vnd_mod_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { - return mod_set(true, argc, argv, val_ctx); + return mod_set(true, argc, argv, len_rd, read_cb, cb_arg); } const struct mesh_setting { const char *name; - int (*func)(int argc, char **argv, void *val_ctx); + int (*func)(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg); } settings[] = { { "Net", net_set }, { "IV", iv_set }, @@ -658,7 +676,8 @@ const struct mesh_setting { { "v", vnd_mod_set }, }; -static int mesh_set(int argc, char **argv, void *val_ctx) +static int mesh_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *cb_arg) { int i; @@ -672,7 +691,8 @@ static int mesh_set(int argc, char **argv, void *val_ctx) argc--; argv++; - return settings[i].func(argc, argv, val_ctx); + return settings[i].func(argc, argv, len_rd, read_cb, + cb_arg); } } diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index 277aa756e212..c0fcee2520b3 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -86,9 +86,11 @@ int bt_settings_decode_key(char *key, bt_addr_le_t *addr) return 0; } -static int set(int argc, char **argv, void *value_ctx) +static int set(int argc, char **argv, size_t len_rd, settings_read_cb read_cb, + void *cb_arg) { - int len; + size_t len; + const struct bt_settings_handler *h; for (h = _bt_settings_start; h < _bt_settings_end; h++) { @@ -96,7 +98,8 @@ static int set(int argc, char **argv, void *value_ctx) argc--; argv++; - return h->set(argc, argv, value_ctx); + return h->set(argc, argv, len_rd, read_cb, + cb_arg); } } @@ -107,13 +110,12 @@ static int set(int argc, char **argv, void *value_ctx) return 0; } - len = settings_val_read_cb(value_ctx, &bt_dev.id_addr, - sizeof(bt_dev.id_addr)); + len = read_cb(cb_arg, &bt_dev.id_addr, sizeof(bt_dev.id_addr)); if (len < sizeof(bt_dev.id_addr[0])) { if (len < 0) { BT_ERR("Failed to read ID address from storage" - " (err %d)", len); + " (err %zu)", len); } else { BT_ERR("Invalid length ID address in storage"); BT_HEXDUMP_DBG(&bt_dev.id_addr, len, @@ -137,11 +139,10 @@ static int set(int argc, char **argv, void *value_ctx) #if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC) if (!strcmp(argv[0], "name")) { - len = settings_val_read_cb(value_ctx, &bt_dev.name, - sizeof(bt_dev.name) - 1); + len = read_cb(cb_arg, &bt_dev.name, sizeof(bt_dev.name) - 1); if (len < 0) { BT_ERR("Failed to read device name from storage" - " (err %d)", len); + " (err %zu)", len); } else { bt_dev.name[len] = '\0'; @@ -153,12 +154,11 @@ static int set(int argc, char **argv, void *value_ctx) #if defined(CONFIG_BT_PRIVACY) if (!strcmp(argv[0], "irk")) { - len = settings_val_read_cb(value_ctx, bt_dev.irk, - sizeof(bt_dev.irk)); + len = read_cb(cb_arg, bt_dev.irk, sizeof(bt_dev.irk)); if (len < sizeof(bt_dev.irk[0])) { if (len < 0) { BT_ERR("Failed to read IRK from storage" - " (err %d)", len); + " (err %zu)", len); } else { BT_ERR("Invalid length IRK in storage"); (void)memset(bt_dev.irk, 0, sizeof(bt_dev.irk)); diff --git a/subsys/bluetooth/host/settings.h b/subsys/bluetooth/host/settings.h index 36f110dc676d..27d3a8a6387a 100644 --- a/subsys/bluetooth/host/settings.h +++ b/subsys/bluetooth/host/settings.h @@ -6,7 +6,8 @@ struct bt_settings_handler { const char *name; - int (*set)(int argc, char **argv, void *value_ctx); + int (*set)(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg); int (*commit)(void); int (*export)(int (*func)(const char *name, void *val, size_t val_len)); diff --git a/subsys/settings/Kconfig b/subsys/settings/Kconfig index 22cf1c8276ae..dead1e764ac5 100644 --- a/subsys/settings/Kconfig +++ b/subsys/settings/Kconfig @@ -6,9 +6,6 @@ menuconfig SETTINGS bool "Enable settings subsystem with non-volatile storage" - # Only NFFS is currently supported as FS. - # The reason in that FatFs doesn't implement the fs_rename() API - depends on (FILE_SYSTEM && FILE_SYSTEM_NFFS) || (FCB && FLASH_PAGE_LAYOUT) help The settings subsystem allows its users to serialize and deserialize state in memory into and from non-volatile memory. @@ -21,6 +18,12 @@ module-str = settings source "subsys/logging/Kconfig.template.log_config" endif +config SETTINGS_RUNTIME + bool "runtime storage back-end" + depends on SETTINGS + help + Enables runtime storage back-end. + # Hidden option to enable encoding length into settings entry config SETTINGS_ENCODE_LEN depends on SETTINGS @@ -35,7 +38,9 @@ config SETTINGS_USE_BASE64 choice prompt "Storage back-end" + optional default SETTINGS_FCB if FCB + default SETTINGS_NONE depends on SETTINGS help Storage back-end to be used by the settings subsystem. @@ -52,6 +57,16 @@ config SETTINGS_FS select SETTINGS_ENCODE_LEN help Use a file system as a settings storage back-end. + +config SETTINGS_CUSTOM + bool "CUSTOM" + help + Use a custom settings storage back-end. + +config SETTINGS_NONE + bool "NONE" + help + No storage back-end. endchoice config SETTINGS_FCB_NUM_AREAS diff --git a/subsys/settings/src/CMakeLists.txt b/subsys/settings/src/CMakeLists.txt index 69088c702a1d..ecae3f965c5e 100644 --- a/subsys/settings/src/CMakeLists.txt +++ b/subsys/settings/src/CMakeLists.txt @@ -7,5 +7,6 @@ zephyr_sources( settings_line.c ) +zephyr_sources_ifdef(CONFIG_SETTINGS_RUNTIME settings_runtime.c) zephyr_sources_ifdef(CONFIG_SETTINGS_FS settings_file.c) zephyr_sources_ifdef(CONFIG_SETTINGS_FCB settings_fcb.c) diff --git a/subsys/settings/src/settings.c b/subsys/settings/src/settings.c index 2b2c63c32e14..d3bfda918715 100644 --- a/subsys/settings/src/settings.c +++ b/subsys/settings/src/settings.c @@ -89,9 +89,9 @@ int settings_parse_name(char *name, int *name_argc, char *name_argv[]) return 0; } -static struct settings_handler *settings_parse_and_lookup(char *name, - int *name_argc, - char *name_argv[]) +struct settings_handler *settings_parse_and_lookup(char *name, + int *name_argc, + char *name_argv[]) { int rc; @@ -102,129 +102,20 @@ static struct settings_handler *settings_parse_and_lookup(char *name, return settings_handler_lookup(name_argv[0]); } -int settings_set_value_priv(char *name, void *val_read_cb_ctx, off_t off, - u8_t is_runtime) +int settings_commit(void) { - int name_argc; - char *name_argv[SETTINGS_MAX_DIR_DEPTH]; - struct settings_handler *ch; - struct read_value_cb_ctx value_ctx; - - ch = settings_parse_and_lookup(name, &name_argc, name_argv); - if (!ch) { - return -EINVAL; - } - - value_ctx.read_cb_ctx = val_read_cb_ctx; - value_ctx.off = off; - value_ctx.runtime = is_runtime; - - return ch->h_set(name_argc - 1, &name_argv[1], (void *)&value_ctx); -} - -/* API */ -int settings_set_value(char *name, void *val_str, size_t len) -{ - struct runtime_value_ctx rt_ctx; - - rt_ctx.p_value = val_str; - rt_ctx.size = len; - - return settings_set_value_priv(name, &rt_ctx, 0, 1); -} - -/* API */ -int settings_val_read_cb(void *value_ctx, void *buf, size_t len) -{ - struct read_value_cb_ctx *value_context = value_ctx; - size_t len_read; - int rc; - struct runtime_value_ctx *rt_ctx; - - if (value_context->runtime) { - rt_ctx = value_context->read_cb_ctx; - len_read = MIN(len, rt_ctx->size); - memcpy(buf, rt_ctx->p_value, len_read); - return len_read; - } else { - rc = settings_line_val_read(value_context->off, 0, buf, len, - &len_read, - value_context->read_cb_ctx); - } - - if (rc == 0) { - return len_read; - } - - return rc; -} - -/* API */ -size_t settings_val_get_len_cb(void *value_ctx) -{ - struct read_value_cb_ctx *value_context = value_ctx; - struct runtime_value_ctx *rt_ctx; - - if (value_context->runtime) { - rt_ctx = value_context->read_cb_ctx; - return rt_ctx->size; - } else { - return settings_line_val_get_len(value_context->off, - value_context->read_cb_ctx); - } -} - -/* - * Get value in printable string form. If value is not string, the value - * will be filled in *buf. - * Return value will be pointer to beginning of that buffer, - * except for string it will pointer to beginning of string. - */ -int settings_get_value(char *name, char *buf, int buf_len) -{ - int name_argc; - char *name_argv[SETTINGS_MAX_DIR_DEPTH]; - struct settings_handler *ch; - - ch = settings_parse_and_lookup(name, &name_argc, name_argv); - if (!ch) { - return -EINVAL; - } - - if (!ch->h_get) { - return -EINVAL; - } - return ch->h_get(name_argc - 1, &name_argv[1], buf, buf_len); -} - -int settings_commit(char *name) -{ - int name_argc; - char *name_argv[SETTINGS_MAX_DIR_DEPTH]; struct settings_handler *ch; int rc; int rc2; - if (name) { - ch = settings_parse_and_lookup(name, &name_argc, name_argv); - if (!ch) { - return -EINVAL; - } + rc = 0; + SYS_SLIST_FOR_EACH_CONTAINER(&settings_handlers, ch, node) { if (ch->h_commit) { - return ch->h_commit(); - } else { - return 0; - } - } else { - rc = 0; - SYS_SLIST_FOR_EACH_CONTAINER(&settings_handlers, ch, node) { - if (ch->h_commit) { - rc2 = ch->h_commit(); - if (!rc) { - rc = rc2; - } + rc2 = ch->h_commit(); + if (!rc) { + rc = rc2; } } - return rc; } + return rc; } diff --git a/subsys/settings/src/settings_fcb.c b/subsys/settings/src/settings_fcb.c index 755276215c0a..0622aaf4963b 100644 --- a/subsys/settings/src/settings_fcb.c +++ b/subsys/settings/src/settings_fcb.c @@ -19,12 +19,11 @@ LOG_MODULE_DECLARE(settings, CONFIG_SETTINGS_LOG_LEVEL); #define SETTINGS_FCB_VERS 1 struct settings_fcb_load_cb_arg { - load_cb cb; + line_load_cb cb; void *cb_arg; }; -static int settings_fcb_load(struct settings_store *cs, load_cb cb, - void *cb_arg); +static int settings_fcb_load(struct settings_store *cs); static int settings_fcb_save(struct settings_store *cs, const char *name, const char *value, size_t val_len); @@ -102,8 +101,8 @@ static int settings_fcb_load_cb(struct fcb_entry_ctx *entry_ctx, void *arg) return 0; } -static int settings_fcb_load(struct settings_store *cs, load_cb cb, - void *cb_arg) +static int settings_fcb_load_priv(struct settings_store *cs, line_load_cb cb, + void *cb_arg) { struct settings_fcb *cf = (struct settings_fcb *)cs; struct settings_fcb_load_cb_arg arg; @@ -118,6 +117,12 @@ static int settings_fcb_load(struct settings_store *cs, load_cb cb, return 0; } +static int settings_fcb_load(struct settings_store *cs) +{ + return settings_fcb_load_priv(cs, settings_line_load_cb, NULL); +} + + static int read_handler(void *ctx, off_t off, char *buf, size_t *len) { struct fcb_entry_ctx *entry_ctx = ctx; @@ -208,8 +213,8 @@ static void settings_fcb_compress(struct settings_fcb *cf) continue; } - rc = settings_entry_copy(&loc2, 0, &loc1, 0, - loc1.loc.fe_data_len); + rc = settings_line_entry_copy(&loc2, 0, &loc1, 0, + loc1.loc.fe_data_len); if (rc) { continue; } @@ -243,8 +248,8 @@ static int write_handler(void *ctx, off_t off, char const *buf, size_t len) } /* ::csi_save implementation */ -static int settings_fcb_save(struct settings_store *cs, const char *name, - const char *value, size_t val_len) +static int settings_fcb_save_priv(struct settings_store *cs, const char *name, + const char *value, size_t val_len) { struct settings_fcb *cf = (struct settings_fcb *)cs; struct fcb_entry_ctx loc; @@ -284,6 +289,29 @@ static int settings_fcb_save(struct settings_store *cs, const char *name, return rc; } +static int settings_fcb_save(struct settings_store *cs, const char *name, + const char *value, size_t val_len) +{ + struct settings_line_dup_check_arg cdca; + + if (val_len > 0 && value == NULL) { + return -EINVAL; + } + + /* + * Check if we're writing the same value again. + */ + cdca.name = name; + cdca.val = (char *)value; + cdca.is_dup = 0; + cdca.val_len = val_len; + settings_fcb_load_priv(cs, settings_line_dup_check_cb, &cdca); + if (cdca.is_dup == 1) { + return 0; + } + return settings_fcb_save_priv(cs, name, (char *)value, val_len); +} + void settings_mount_fcb_backend(struct settings_fcb *cf) { u8_t rbs; diff --git a/subsys/settings/src/settings_file.c b/subsys/settings/src/settings_file.c index 47aaca1a05af..79faf4656311 100644 --- a/subsys/settings/src/settings_file.c +++ b/subsys/settings/src/settings_file.c @@ -14,8 +14,7 @@ #include "settings/settings_file.h" #include "settings_priv.h" -static int settings_file_load(struct settings_store *cs, load_cb cb, - void *cb_arg); +static int settings_file_load(struct settings_store *cs); static int settings_file_save(struct settings_store *cs, const char *name, const char *value, size_t val_len); @@ -49,12 +48,9 @@ int settings_file_dst(struct settings_file *cf) return 0; } -/* - * Called to load configuration items. cb must be called for every configuration - * item found. - */ -static int settings_file_load(struct settings_store *cs, load_cb cb, - void *cb_arg) + +static int settings_file_load_priv(struct settings_store *cs, line_load_cb cb, + void *cb_arg) { struct settings_file *cf = (struct settings_file *)cs; char buf[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1]; @@ -110,6 +106,14 @@ static int settings_file_load(struct settings_store *cs, load_cb cb, return rc; } +/* + * Called to load configuration items. + */ +static int settings_file_load(struct settings_store *cs) +{ + return settings_file_load_priv(cs, settings_line_load_cb, NULL); +} + static void settings_tmpfile(char *dst, const char *src, char *pfx) { int len; @@ -247,7 +251,7 @@ int settings_file_save_and_compress(struct settings_file *cf, const char *name, loc2 = loc1; loc2.len += 2; loc2.seek -= 2; - rc = settings_entry_copy(&loc3, 0, &loc2, 0, loc2.len); + rc = settings_line_entry_copy(&loc3, 0, &loc2, 0, loc2.len); if (rc) { /* compressed file might be corrupted */ goto end_rolback; @@ -287,11 +291,8 @@ int settings_file_save_and_compress(struct settings_file *cf, const char *name, } -/* - * Called to save configuration. - */ -static int settings_file_save(struct settings_store *cs, const char *name, - const char *value, size_t val_len) +static int settings_file_save_priv(struct settings_store *cs, const char *name, + const char *value, size_t val_len) { struct settings_file *cf = (struct settings_file *)cs; struct line_entry_ctx entry_ctx; @@ -336,6 +337,33 @@ static int settings_file_save(struct settings_store *cs, const char *name, return rc; } + +/* + * Called to save configuration. + */ +static int settings_file_save(struct settings_store *cs, const char *name, + const char *value, size_t val_len) +{ + struct settings_line_dup_check_arg cdca; + + if (val_len > 0 && value == NULL) { + return -EINVAL; + } + + /* + * Check if we're writing the same value again. + */ + cdca.name = name; + cdca.val = (char *)value; + cdca.is_dup = 0; + cdca.val_len = val_len; + settings_file_load_priv(cs, settings_line_dup_check_cb, &cdca); + if (cdca.is_dup == 1) { + return 0; + } + return settings_file_save_priv(cs, name, (char *)value, val_len); +} + static int read_handler(void *ctx, off_t off, char *buf, size_t *len) { struct line_entry_ctx *entry_ctx = ctx; diff --git a/subsys/settings/src/settings_init.c b/subsys/settings/src/settings_init.c index e71986ad08e2..ec98264273a7 100644 --- a/subsys/settings/src/settings_init.c +++ b/subsys/settings/src/settings_init.c @@ -17,6 +17,8 @@ void settings_init(void); +int settings_backend_init(void); + #ifdef CONFIG_SETTINGS_FS #include @@ -25,7 +27,7 @@ static struct settings_file config_init_settings_file = { .cf_maxlines = CONFIG_SETTINGS_FS_MAX_LINES }; -static void settings_init_fs(void) +int settings_backend_init(void) { int rc; @@ -40,6 +42,20 @@ static void settings_init_fs(void) } settings_mount_fs_backend(&config_init_settings_file); + + /* + * Must be called after root FS has been initialized. + */ + rc = fs_mkdir(CONFIG_SETTINGS_FS_DIR); + + /* + * The following lines mask the file exist error. + */ + if (rc == -EEXIST) { + rc = 0; + } + + return rc; } #elif defined(CONFIG_SETTINGS_FCB) @@ -53,7 +69,7 @@ static struct settings_fcb config_init_settings_fcb = { .cf_fcb.f_sectors = settings_fcb_area, }; -static void settings_init_fcb(void) +int settings_backend_init(void) { u32_t cnt = CONFIG_SETTINGS_FCB_NUM_AREAS + 1; int rc; @@ -95,14 +111,20 @@ static void settings_init_fcb(void) } settings_mount_fcb_backend(&config_init_settings_fcb); -} + return rc; +} +#elif defined(CONFIG_SETTINGS_NONE) +int settings_backend_init(void) +{ + return 0; +} #endif int settings_subsys_init(void) { static bool settings_initialized; - int err; + int err = 0; if (settings_initialized) { return 0; @@ -110,23 +132,7 @@ int settings_subsys_init(void) settings_init(); -#ifdef CONFIG_SETTINGS_FS - settings_init_fs(); /* func rises kernel panic once error */ - - /* - * Must be called after root FS has been initialized. - */ - err = fs_mkdir(CONFIG_SETTINGS_FS_DIR); - /* - * The following lines mask the file exist error. - */ - if (err == -EEXIST) { - err = 0; - } -#elif defined(CONFIG_SETTINGS_FCB) - settings_init_fcb(); /* func rises kernel panic once error */ - err = 0; -#endif + err = settings_backend_init(); /* func rises kernel panic once error */ if (!err) { settings_initialized = true; diff --git a/subsys/settings/src/settings_line.c b/subsys/settings/src/settings_line.c index f35915a0c999..f773fa82a030 100644 --- a/subsys/settings/src/settings_line.c +++ b/subsys/settings/src/settings_line.c @@ -411,8 +411,8 @@ int settings_line_name_read(char *out, size_t len_req, size_t *len_read, } -int settings_entry_copy(void *dst_ctx, off_t dst_off, void *src_ctx, - off_t src_off, size_t len) +int settings_line_entry_copy(void *dst_ctx, off_t dst_off, void *src_ctx, + off_t src_off, size_t len) { int rc; char buf[16]; @@ -451,3 +451,114 @@ void settings_line_io_init(int (*read_cb)(void *ctx, off_t off, char *buf, settings_io_cb.get_len_cb = get_len_cb; settings_io_cb.rwbs = io_rwbs; } + + +/* val_off - offset of value-string within line entries */ +static int settings_line_cmp(char const *val, size_t val_len, + void *val_read_cb_ctx, off_t val_off) +{ + size_t len_read, exp_len; + size_t rem; + char buf[16]; + int rc; + off_t off = 0; + + for (rem = val_len; rem > 0; rem -= len_read) { + len_read = exp_len = MIN(sizeof(buf), rem); + rc = settings_line_val_read(val_off, off, buf, len_read, + &len_read, val_read_cb_ctx); + if (rc) { + break; + } + + if (len_read != exp_len) { + rc = 1; + break; + } + + rc = memcmp(val, buf, len_read); + if (rc) { + break; + } + val += len_read; + off += len_read; + } + + return rc; +} + +void settings_line_dup_check_cb(char *name, void *val_read_cb_ctx, + off_t off, void *cb_arg) +{ + struct settings_line_dup_check_arg *cdca; + size_t len_read; + + cdca = (struct settings_line_dup_check_arg *)cb_arg; + if (strcmp(name, cdca->name)) { + return; + } + + len_read = settings_line_val_get_len(off, val_read_cb_ctx); + if (len_read != cdca->val_len) { + cdca->is_dup = 0; + } else if (len_read == 0) { + cdca->is_dup = 1; + } else { + if (!settings_line_cmp(cdca->val, cdca->val_len, + val_read_cb_ctx, off)) { + cdca->is_dup = 1; + } else { + cdca->is_dup = 0; + } + } +} + +static ssize_t settings_line_read_cb(void *cb_arg, void *data, size_t len) +{ + struct settings_line_read_value_cb_ctx *value_context = cb_arg; + size_t len_read; + int rc; + + rc = settings_line_val_read(value_context->off, 0, data, len, + &len_read, + value_context->read_cb_ctx); + + if (rc == 0) { + return len_read; + } + + return -1; +} + +void settings_line_load_cb(char *name, void *val_read_cb_ctx, off_t off, + void *cb_arg) +{ + int name_argc; + char *name_argv[SETTINGS_MAX_DIR_DEPTH]; + struct settings_handler *ch; + struct settings_line_read_value_cb_ctx value_ctx; + int rc; + size_t len; + + ch = settings_parse_and_lookup(name, &name_argc, name_argv); + if (!ch) { + return; + } + + value_ctx.read_cb_ctx = val_read_cb_ctx; + value_ctx.off = off; + + len = settings_line_val_get_len(off, val_read_cb_ctx); + + rc = ch->h_set(name_argc - 1, &name_argv[1], len, settings_line_read_cb, + (void *)&value_ctx); + + if (rc != 0) { + LOG_ERR("set-value failure. key: %s error(%d)", + log_strdup(name), rc); + } else { + LOG_DBG("set-value OK. key: %s", + log_strdup(name)); + } + (void)rc; +} diff --git a/subsys/settings/src/settings_priv.h b/subsys/settings/src/settings_priv.h index dab14fbee340..8fbe452e649f 100644 --- a/subsys/settings/src/settings_priv.h +++ b/subsys/settings/src/settings_priv.h @@ -35,6 +35,27 @@ int settings_line_write(const char *name, const char *value, size_t val_len, /* Get len of record without alignment to write-block-size */ int settings_line_len_calc(const char *name, size_t val_len); +void settings_line_dup_check_cb(char *name, void *val_read_cb_ctx, off_t off, + void *cb_arg); + +void settings_line_load_cb(char *name, void *val_read_cb_ctx, off_t off, + void *cb_arg); + +typedef void (*line_load_cb)(char *name, void *val_read_cb_ctx, off_t off, + void *cb_arg); + +struct settings_line_read_value_cb_ctx { + void *read_cb_ctx; + off_t off; +}; + +struct settings_line_dup_check_arg { + const char *name; + const char *val; + size_t val_len; + int is_dup; +}; + #ifdef CONFIG_SETTINGS_ENCODE_LEN /* in storage line contex */ struct line_entry_ctx { @@ -87,7 +108,7 @@ int settings_line_name_read(char *out, size_t len_req, size_t *len_read, size_t settings_line_val_get_len(off_t val_off, void *read_cb_ctx); -int settings_entry_copy(void *dst_ctx, off_t dst_off, void *src_ctx, +int settings_line_entry_copy(void *dst_ctx, off_t dst_off, void *src_ctx, off_t src_off, size_t len); void settings_line_io_init(int (*read_cb)(void *ctx, off_t off, char *buf, @@ -97,37 +118,6 @@ void settings_line_io_init(int (*read_cb)(void *ctx, off_t off, char *buf, size_t (*get_len_cb)(void *ctx), u8_t io_rwbs); -int settings_set_value_priv(char *name, void *val_read_cb_ctx, off_t off, - u8_t is_runtime); - -/* - * API for config storage. - */ -typedef void (*load_cb)(char *name, void *val_read_cb_ctx, off_t off, - void *cb_arg); - -struct settings_store_itf { - int (*csi_load)(struct settings_store *cs, load_cb cb, void *cb_arg); - int (*csi_save_start)(struct settings_store *cs); - int (*csi_save)(struct settings_store *cs, const char *name, - const char *value, size_t val_len); - int (*csi_save_end)(struct settings_store *cs); -}; - -struct read_value_cb_ctx { - void *read_cb_ctx; - off_t off; - u8_t runtime; -}; - -/* suports runtime settings_set_value operation */ -struct runtime_value_ctx { - void *p_value; - size_t size; -}; - -void settings_src_register(struct settings_store *cs); -void settings_dst_register(struct settings_store *cs); extern sys_slist_t settings_load_srcs; extern sys_slist_t settings_handlers; diff --git a/subsys/settings/src/settings_runtime.c b/subsys/settings/src/settings_runtime.c new file mode 100644 index 000000000000..2d28064d8515 --- /dev/null +++ b/subsys/settings/src/settings_runtime.c @@ -0,0 +1,68 @@ +/* Copyright (c) 2019 Laczen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include "settings_priv.h" + +static ssize_t settings_runtime_read_cb(void *cb_arg, void *data, size_t len) +{ + memcpy(data, cb_arg, len); + return len; +} + +int settings_runtime_set(const char *name, void *data, size_t len) +{ + struct settings_handler *ch; + char name1[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN]; + char *name_argv[SETTINGS_MAX_DIR_DEPTH]; + int name_argc; + + strcpy(name1, name); + ch = settings_parse_and_lookup(name1, &name_argc, name_argv); + if (!ch) { + return -EINVAL; + } + + return ch->h_set(name_argc - 1, &name_argv[1], len, + settings_runtime_read_cb, data); +} + +int settings_runtime_get(const char *name, void *data, size_t len) +{ + struct settings_handler *ch; + char name1[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN]; + char *name_argv[SETTINGS_MAX_DIR_DEPTH]; + int name_argc; + + strcpy(name1, name); + ch = settings_parse_and_lookup(name1, &name_argc, name_argv); + if (!ch) { + return -EINVAL; + } + + return ch->h_get(name_argc - 1, &name_argv[1], data, len); +} + +int settings_runtime_commit(const char *name) +{ + struct settings_handler *ch; + char name1[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN]; + char *name_argv[SETTINGS_MAX_DIR_DEPTH]; + int name_argc; + + strcpy(name1, name); + ch = settings_parse_and_lookup(name1, &name_argc, name_argv); + if (!ch) { + return -EINVAL; + } + if (ch->h_commit) { + return ch->h_commit(); + } else { + return 0; + } +} diff --git a/subsys/settings/src/settings_store.c b/subsys/settings/src/settings_store.c index 2b0220ea9ce2..036484dc3976 100644 --- a/subsys/settings/src/settings_store.c +++ b/subsys/settings/src/settings_store.c @@ -19,14 +19,7 @@ #include LOG_MODULE_DECLARE(settings, CONFIG_SETTINGS_LOG_LEVEL); -struct settings_dup_check_arg { - const char *name; - const char *val; - size_t val_len; - int is_dup; -}; - -sys_slist_t settings_load_srcs; +sys_slist_t settings_load_srcs; struct settings_store *settings_save_dst; void settings_src_register(struct settings_store *cs) @@ -47,21 +40,6 @@ void settings_dst_register(struct settings_store *cs) settings_save_dst = cs; } -static void settings_load_cb(char *name, void *val_read_cb_ctx, off_t off, - void *cb_arg) -{ - int rc = settings_set_value_priv(name, val_read_cb_ctx, off, 0); - - if (rc != 0) { - LOG_ERR("set-value failure. key: %s error(%d)", - log_strdup(name), rc); - } else { - LOG_DBG("set-value OK. key: %s", - log_strdup(name)); - } - (void)rc; -} - int settings_load(void) { struct settings_store *cs; @@ -74,69 +52,9 @@ int settings_load(void) */ SYS_SLIST_FOR_EACH_CONTAINER(&settings_load_srcs, cs, cs_next) { - cs->cs_itf->csi_load(cs, settings_load_cb, NULL); - } - return settings_commit(NULL); -} - -/* val_off - offset of value-string within line entries */ -static int settings_cmp(char const *val, size_t val_len, void *val_read_cb_ctx, - off_t val_off) -{ - size_t len_read, exp_len; - size_t rem; - char buf[16]; - int rc; - off_t off = 0; - - for (rem = val_len; rem > 0; rem -= len_read) { - len_read = exp_len = MIN(sizeof(buf), rem); - rc = settings_line_val_read(val_off, off, buf, len_read, - &len_read, val_read_cb_ctx); - if (rc) { - break; - } - - if (len_read != exp_len) { - rc = 1; - break; - } - - rc = memcmp(val, buf, len_read); - if (rc) { - break; - } - val += len_read; - off += len_read; - } - - return rc; -} - -static void settings_dup_check_cb(char *name, void *val_read_cb_ctx, off_t off, - void *cb_arg) -{ - struct settings_dup_check_arg *cdca = (struct settings_dup_check_arg *) - cb_arg; - size_t len_read; - - if (strcmp(name, cdca->name)) { - return; - } - - len_read = settings_line_val_get_len(off, val_read_cb_ctx); - if (len_read != cdca->val_len) { - cdca->is_dup = 0; - } else if (len_read == 0) { - cdca->is_dup = 1; - } else { - if (!settings_cmp(cdca->val, cdca->val_len, - val_read_cb_ctx, off)) { - cdca->is_dup = 1; - } else { - cdca->is_dup = 0; - } + cs->cs_itf->csi_load(cs); } + return settings_commit(); } /* @@ -145,28 +63,12 @@ static void settings_dup_check_cb(char *name, void *val_read_cb_ctx, off_t off, int settings_save_one(const char *name, void *value, size_t val_len) { struct settings_store *cs; - struct settings_dup_check_arg cdca; cs = settings_save_dst; if (!cs) { return -ENOENT; } - if (val_len > 0 && value == NULL) { - return -EINVAL; - } - - /* - * Check if we're writing the same value again. - */ - cdca.name = name; - cdca.val = (char *)value; - cdca.is_dup = 0; - cdca.val_len = val_len; - cs->cs_itf->csi_load(cs, settings_dup_check_cb, &cdca); - if (cdca.is_dup == 1) { - return 0; - } return cs->cs_itf->csi_save(cs, name, (char *)value, val_len); } diff --git a/tests/subsys/settings/fcb/base64/prj.conf b/tests/subsys/settings/fcb/base64/prj.conf index 9000a0cfbfba..c328a2a3ed23 100644 --- a/tests/subsys/settings/fcb/base64/prj.conf +++ b/tests/subsys/settings/fcb/base64/prj.conf @@ -7,5 +7,6 @@ CONFIG_ARM_MPU=n CONFIG_FCB=y CONFIG_SETTINGS=y +CONFIG_SETTINGS_RUNTIME=y CONFIG_SETTINGS_FCB=y CONFIG_SETTINGS_USE_BASE64=y diff --git a/tests/subsys/settings/fcb/raw/prj.conf b/tests/subsys/settings/fcb/raw/prj.conf index c75749ef011d..767305cd6214 100644 --- a/tests/subsys/settings/fcb/raw/prj.conf +++ b/tests/subsys/settings/fcb/raw/prj.conf @@ -7,5 +7,6 @@ CONFIG_ARM_MPU=n CONFIG_FCB=y CONFIG_SETTINGS=y +CONFIG_SETTINGS_RUNTIME=y CONFIG_SETTINGS_FCB=y CONFIG_SETTINGS_USE_BASE64=n diff --git a/tests/subsys/settings/fcb/src/settings_test_fcb.c b/tests/subsys/settings/fcb/src/settings_test_fcb.c index 241503f456f6..9e350bc681c3 100644 --- a/tests/subsys/settings/fcb/src/settings_test_fcb.c +++ b/tests/subsys/settings/fcb/src/settings_test_fcb.c @@ -24,16 +24,19 @@ int test_export_block; int c2_var_count = 1; int c1_handle_get(int argc, char **argv, char *val, int val_len_max); -int c1_handle_set(int argc, char **argv, void *value_ctx); +int c1_handle_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg); int c1_handle_commit(void); int c1_handle_export(int (*cb)(const char *name, void *value, size_t val_len)); int c2_handle_get(int argc, char **argv, char *val, int val_len_max); -int c2_handle_set(int argc, char **argv, void *value_ctx); +int c2_handle_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg); int c2_handle_export(int (*cb)(const char *name, void *value, size_t val_len)); int c3_handle_get(int argc, char **argv, char *val, int val_len_max); -int c3_handle_set(int argc, char **argv, void *value_ctx); +int c3_handle_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg); int c3_handle_export(int (*cb)(const char *name, void *value, size_t val_len)); struct settings_handler c_test_handlers[] = { @@ -82,29 +85,30 @@ int c1_handle_get(int argc, char **argv, char *val, int val_len_max) return -ENOENT; } -int c1_handle_set(int argc, char **argv, void *value_ctx) +int c1_handle_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg) { size_t val_len; int rc; test_set_called = 1; if (argc == 1 && !strcmp(argv[0], "mybar")) { - rc = settings_val_read_cb(value_ctx, &val8, sizeof(val8)); + rc = read_cb(cb_arg, &val8, sizeof(val8)); zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); return 0; } - if (argc == 1 && !strcmp(argv[0], "mybar64")) { - rc = settings_val_read_cb(value_ctx, &val64, sizeof(val64)); + if (argc == 1 && !strcmp(argv[0], "mybar64")) { + rc = read_cb(cb_arg, &val64, sizeof(val64)); zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); return 0; } if (argc == 1 && !strcmp(argv[0], "unaligned")) { - val_len = settings_val_get_len_cb(value_ctx); + val_len = len; zassert_equal(val_len, sizeof(val8_un), "value length: %d, ought equal 1", val_len); - rc = settings_val_read_cb(value_ctx, &val8_un, sizeof(val8_un)); + rc = read_cb(cb_arg, &val8_un, sizeof(val8_un)); zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); return 0; } @@ -241,7 +245,8 @@ int c2_handle_get(int argc, char **argv, char *val, int val_len_max) return -ENOENT; } -int c2_handle_set(int argc, char **argv, void *value_ctx) +int c2_handle_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg) { char *valptr; int rc; @@ -252,12 +257,11 @@ int c2_handle_set(int argc, char **argv, void *value_ctx) return -ENOENT; } - rc = settings_val_read_cb(value_ctx, valptr, - sizeof(val_string[0])); - zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); - if (rc == 0) { - (void)memset(valptr, 0, sizeof(val_string[0])); - } + rc = read_cb(cb_arg, valptr, sizeof(val_string[0])); + zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); + if (rc == 0) { + (void)memset(valptr, 0, sizeof(val_string[0])); + } return 0; } @@ -288,16 +292,17 @@ int c3_handle_get(int argc, char **argv, char *val, int val_len_max) return -EINVAL; } -int c3_handle_set(int argc, char **argv, void *value_ctx) +int c3_handle_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg) { int rc; size_t val_len; if (argc == 1 && !strcmp(argv[0], "v")) { - val_len = settings_val_get_len_cb(value_ctx); + val_len = len; zassert_true(val_len == 4, "bad set-value size"); - rc = settings_val_read_cb(value_ctx, &val32, sizeof(val32)); + rc = read_cb(cb_arg, &val32, sizeof(val32)); zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); return 0; } diff --git a/tests/subsys/settings/fcb_init/prj.conf b/tests/subsys/settings/fcb_init/prj.conf index a91787b629df..8209c44a576b 100644 --- a/tests/subsys/settings/fcb_init/prj.conf +++ b/tests/subsys/settings/fcb_init/prj.conf @@ -7,6 +7,7 @@ CONFIG_ARM_MPU=n CONFIG_FCB=y CONFIG_SETTINGS=y +CONFIG_SETTINGS_RUNTIME=y CONFIG_SETTINGS_FCB=y CONFIG_REBOOT=y diff --git a/tests/subsys/settings/fcb_init/src/settings_test_fcb_init.c b/tests/subsys/settings/fcb_init/src/settings_test_fcb_init.c index 993fef066808..ef81c269b25f 100644 --- a/tests/subsys/settings/fcb_init/src/settings_test_fcb_init.c +++ b/tests/subsys/settings/fcb_init/src/settings_test_fcb_init.c @@ -15,12 +15,13 @@ static u32_t val32; -static int c1_set(int argc, char **argv, void *value_ctx) +static int c1_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg) { int rc; - if (argc == 1 && !strcmp(argv[0], "val32")) { - rc = settings_val_read_cb(value_ctx, &val32, sizeof(val32)); + if (argc == 1 && !strcmp(argv[0], "val32")) { + rc = read_cb(cb_arg, &val32, sizeof(val32)); zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); return 0; } diff --git a/tests/subsys/settings/nffs/base64/prj.conf b/tests/subsys/settings/nffs/base64/prj.conf index 7805a98101f0..c5a2d9c7f1e3 100644 --- a/tests/subsys/settings/nffs/base64/prj.conf +++ b/tests/subsys/settings/nffs/base64/prj.conf @@ -23,5 +23,6 @@ CONFIG_FILE_SYSTEM_NFFS=y CONFIG_NFFS_FILESYSTEM_MAX_AREAS=12 CONFIG_SETTINGS=y +CONFIG_SETTINGS_RUNTIME=y CONFIG_SETTINGS_FS=y CONFIG_SETTINGS_USE_BASE64=y diff --git a/tests/subsys/settings/nffs/raw/prj.conf b/tests/subsys/settings/nffs/raw/prj.conf index a27af5c94e44..627da06fa6cb 100644 --- a/tests/subsys/settings/nffs/raw/prj.conf +++ b/tests/subsys/settings/nffs/raw/prj.conf @@ -22,5 +22,6 @@ CONFIG_FILE_SYSTEM_NFFS=y CONFIG_NFFS_FILESYSTEM_MAX_AREAS=12 CONFIG_SETTINGS=y +CONFIG_SETTINGS_RUNTIME=y CONFIG_SETTINGS_FS=y CONFIG_SETTINGS_USE_BASE64=n diff --git a/tests/subsys/settings/nffs/src/settings_test_nffs.c b/tests/subsys/settings/nffs/src/settings_test_nffs.c index f7dda2a2943c..8b31ab2e40d5 100644 --- a/tests/subsys/settings/nffs/src/settings_test_nffs.c +++ b/tests/subsys/settings/nffs/src/settings_test_nffs.c @@ -23,7 +23,8 @@ int test_export_block; int c2_var_count = 1; int c1_handle_get(int argc, char **argv, char *val, int val_len_max); -int c1_handle_set(int argc, char **argv, void *value_ctx); +int c1_handle_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg); int c1_handle_commit(void); int c1_handle_export(int (*cb)(const char *name, void *value, size_t val_len)); @@ -64,35 +65,36 @@ int c1_handle_get(int argc, char **argv, char *val, int val_len_max) return -ENOENT; } -int c1_handle_set(int argc, char **argv, void *value_ctx) +int c1_handle_set(int argc, char **argv, size_t len, settings_read_cb read_cb, + void *cb_arg) { int rc; size_t val_len; test_set_called = 1; if (argc == 1 && !strcmp(argv[0], "mybar")) { - val_len = settings_val_get_len_cb(value_ctx); + val_len = len; zassert_true(val_len == 1, "bad set-value size"); - rc = settings_val_read_cb(value_ctx, &val8, sizeof(val8)); + rc = read_cb(cb_arg, &val8, sizeof(val8)); zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); return 0; } if (argc == 1 && !strcmp(argv[0], "mybar16")) { - val_len = settings_val_get_len_cb(value_ctx); + val_len = len; zassert_true(val_len == 2, "bad set-value size"); - rc = settings_val_read_cb(value_ctx, &val16, sizeof(val16)); + rc = read_cb(cb_arg, &val16, sizeof(val16)); zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); return 0; } if (argc == 1 && !strcmp(argv[0], "mybar64")) { - val_len = settings_val_get_len_cb(value_ctx); + val_len = len; zassert_true(val_len == 8, "bad set-value size"); - rc = settings_val_read_cb(value_ctx, &val64, sizeof(val64)); + rc = read_cb(cb_arg, &val64, sizeof(val64)); zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback"); return 0; } diff --git a/tests/subsys/settings/src/settings_empty_lookups.c b/tests/subsys/settings/src/settings_empty_lookups.c index 90f783586bf4..5595194ad397 100644 --- a/tests/subsys/settings/src/settings_empty_lookups.c +++ b/tests/subsys/settings/src/settings_empty_lookups.c @@ -14,10 +14,10 @@ void config_empty_lookups(void) char tmp[64]; strcpy(name, "foo/bar"); - rc = settings_set_value(name, "tmp", 4); - zassert_true(rc != 0, "settings_set_value callback"); + rc = settings_runtime_set(name, "tmp", 4); + zassert_true(rc != 0, "settings_runtime_set callback"); strcpy(name, "foo/bar"); - rc = settings_get_value(name, tmp, sizeof(tmp)); - zassert_true(rc == -EINVAL, "settings_get_value callback"); + rc = settings_runtime_get(name, tmp, sizeof(tmp)); + zassert_true(rc == -EINVAL, "settings_runtime_get callback"); } diff --git a/tests/subsys/settings/src/settings_test_commit.c b/tests/subsys/settings/src/settings_test_commit.c index 412669d5ebff..634118ce1ec4 100644 --- a/tests/subsys/settings/src/settings_test_commit.c +++ b/tests/subsys/settings/src/settings_test_commit.c @@ -13,19 +13,19 @@ void test_config_commit(void) int rc; strcpy(name, "bar"); - rc = settings_commit(name); + rc = settings_runtime_commit(name); zassert_true(rc, "commit-nonexisting-tree call should succeed"); zassert_true(ctest_get_call_state() == 0, "a handler was called unexpectedly"); - rc = settings_commit(NULL); + rc = settings_commit(); zassert_true(rc == 0, "commit-All call should succeed"); zassert_true(test_commit_called == 1, "the COMMIT handler wasn't called"); ctest_clear_call_state(); strcpy(name, "myfoo"); - rc = settings_commit(name); + rc = settings_runtime_commit(name); zassert_true(rc == 0, "commit-a-tree call should succeed"); zassert_true(test_commit_called == 1, "the COMMIT handler wasn't called"); diff --git a/tests/subsys/settings/src/settings_test_getset_int.c b/tests/subsys/settings/src/settings_test_getset_int.c index 7d0d9f586029..60606d5f6aa5 100644 --- a/tests/subsys/settings/src/settings_test_getset_int.c +++ b/tests/subsys/settings/src/settings_test_getset_int.c @@ -16,7 +16,7 @@ void test_config_getset_int(void) small_value = 42U; strcpy(name, "myfoo/mybar"); - rc = settings_set_value(name, &small_value, sizeof(small_value)); + rc = settings_runtime_set(name, &small_value, sizeof(small_value)); zassert_true(rc == 0, "can not set key value"); zassert_true(test_set_called == 1, "the SET handler wasn't called"); zassert_true(val8 == 42, @@ -24,7 +24,7 @@ void test_config_getset_int(void) ctest_clear_call_state(); strcpy(name, "myfoo/mybar"); - rc = settings_get_value(name, tmp, sizeof(tmp)); + rc = settings_runtime_get(name, tmp, sizeof(tmp)); zassert_true(rc == 1, "the key value should been available"); zassert_true(test_get_called == 1, "the GET handler wasn't called"); zassert_equal(42, tmp[0], "unexpected value fetched"); diff --git a/tests/subsys/settings/src/settings_test_getset_int64.c b/tests/subsys/settings/src/settings_test_getset_int64.c index cffdad33bd3d..b61b99b37f10 100644 --- a/tests/subsys/settings/src/settings_test_getset_int64.c +++ b/tests/subsys/settings/src/settings_test_getset_int64.c @@ -16,7 +16,7 @@ void test_config_getset_int64(void) new_val64 = 0x8012345678901234; strcpy(name, "myfoo/mybar64"); - rc = settings_set_value(name, &new_val64, sizeof(s64_t)); + rc = settings_runtime_set(name, &new_val64, sizeof(s64_t)); zassert_true(rc == 0, "can't set value"); zassert_true(test_set_called == 1, "the SET handler wasn't called"); zassert_equal(val64, 0x8012345678901234, @@ -24,7 +24,7 @@ void test_config_getset_int64(void) ctest_clear_call_state(); strcpy(name, "myfoo/mybar64"); - rc = settings_get_value(name, tmp, sizeof(tmp)); + rc = settings_runtime_get(name, tmp, sizeof(tmp)); zassert_equal(rc, sizeof(s64_t), "the key value should been available"); zassert_true(test_get_called == 1, "the GET handler wasn't called"); memcpy(&new_val64, tmp, sizeof(s64_t)); @@ -34,7 +34,7 @@ void test_config_getset_int64(void) new_val64 = 1; strcpy(name, "myfoo/mybar64"); - rc = settings_set_value(name, &new_val64, sizeof(s64_t)); + rc = settings_runtime_set(name, &new_val64, sizeof(s64_t)); zassert_true(rc == 0, "can't set value"); zassert_true(test_set_called == 1, "the SET handler wasn't called"); zassert_equal(val64, 1, @@ -42,7 +42,7 @@ void test_config_getset_int64(void) ctest_clear_call_state(); strcpy(name, "myfoo/mybar64"); - rc = settings_get_value(name, tmp, sizeof(tmp)); + rc = settings_runtime_get(name, tmp, sizeof(tmp)); zassert_equal(rc, sizeof(s64_t), "the key value should been available"); zassert_true(test_get_called == 1, "the GET handler wasn't called"); memcpy(&new_val64, tmp, sizeof(s64_t)); diff --git a/tests/subsys/settings/src/settings_test_getset_unknown.c b/tests/subsys/settings/src/settings_test_getset_unknown.c index 09971712201d..36703acd0b33 100644 --- a/tests/subsys/settings/src/settings_test_getset_unknown.c +++ b/tests/subsys/settings/src/settings_test_getset_unknown.c @@ -15,26 +15,26 @@ void test_config_getset_unknown(void) int rc; strcpy(name, "foo/bar"); - rc = settings_set_value(name, "tmp", 4); + rc = settings_runtime_set(name, "tmp", 4); zassert_true(rc != 0, "set value should fail"); zassert_true(ctest_get_call_state() == 0, "a handler was called unexpectedly"); strcpy(name, "foo/bar"); - rc = settings_get_value(name, tmp, sizeof(tmp)); + rc = settings_runtime_get(name, tmp, sizeof(tmp)); zassert_true(rc == -EINVAL, "value should been unreachable"); zassert_true(ctest_get_call_state() == 0, "a handler was called unexpectedly"); strcpy(name, "myfoo/bar"); - rc = settings_set_value(name, "tmp", 4); + rc = settings_runtime_set(name, "tmp", 4); zassert_true(rc == -ENOENT, "unexpected failure retval\n"); zassert_true(test_set_called == 1, "the GET handler wasn't called"); ctest_clear_call_state(); strcpy(name, "myfoo/bar"); - rc = settings_get_value(name, tmp, sizeof(tmp)); + rc = settings_runtime_get(name, tmp, sizeof(tmp)); zassert_true(rc == -ENOENT, "value should been unreachable\n"); zassert_true(test_get_called == 1, "the SET handler wasn't called");