settings: Generic function to call set handler

This commit implements generic function to decide
witch functions to call for selected value name with given
loading parameters.

Signed-off-by: Radoslaw Koppel <radoslaw.koppel@nordicsemi.no>
This commit is contained in:
Radoslaw Koppel 2019-09-18 16:07:01 +02:00 committed by Ioannis Glaropoulos
commit c68ff8b99c
9 changed files with 128 additions and 106 deletions

View file

@ -342,7 +342,6 @@ int settings_commit_subtree(const char *subtree);
struct settings_store_itf; struct settings_store_itf;
/** /**
* @struct settings_store
* Backend handler node for storage handling. * Backend handler node for storage handling.
*/ */
struct settings_store { struct settings_store {
@ -354,23 +353,43 @@ struct settings_store {
}; };
/** /**
* @struct settings_store_itf * Arguments for data loading.
* Holds all parameters that changes the way data should be loaded from backend.
*/
struct settings_load_arg {
/**
* @brief Name of the subtree to be loaded
*
* If NULL, all values would be loaded.
*/
const char *subtree;
/**
* @brief Pointer to the callback function.
*
* If NULL then matching registered function would be used.
*/
settings_load_direct_cb cb;
/**
* @brief Parameter for callback function
*
* Parameter to be passed to the callback function.
*/
void *param;
};
/**
* Backend handler functions. * Backend handler functions.
* Sources are registered using a call to @ref settings_src_register. * Sources are registered using a call to @ref settings_src_register.
* Destinations are registered using a call to @ref settings_dst_register. * Destinations are registered using a call to @ref settings_dst_register.
*/ */
struct settings_store_itf { struct settings_store_itf {
int (*csi_load)(struct settings_store *cs, const char *subtree, int (*csi_load)(struct settings_store *cs,
settings_load_direct_cb cb, void *param); const struct settings_load_arg *arg);
/**< Loads values from storage limited to subtree defined by subtree. /**< Loads values from storage limited to subtree defined by subtree.
* *
* Parameters: * Parameters:
* - cs - Corresponding backend handler node * - cs - Corresponding backend handler node,
* - subtree - subtree name of the subtree to be loaded, * - arg - Structure that holds additional data for data loading.
* if NULL loads all values.
* - cb - pointer to the callback function,
* if NULL then matching registered function would be used.
* - param - parameter to be passed when callback function is called.
*/ */
int (*csi_save_start)(struct settings_store *cs); int (*csi_save_start)(struct settings_store *cs);
@ -429,9 +448,26 @@ void settings_dst_register(struct settings_store *cs);
* @return settings_handler_static on success, NULL on failure. * @return settings_handler_static on success, NULL on failure.
*/ */
struct settings_handler_static *settings_parse_and_lookup(const char *name, struct settings_handler_static *settings_parse_and_lookup(const char *name,
const char **next); const char **next);
/**
* Calls settings handler.
*
* @param[in] name The name of the data found in the backend.
* @param[in] len The size of the data found in the backend.
* @param[in] read_cb Function provided to read the data from
* the backend.
* @param[in,out] read_cb_arg Arguments for the read function provided by
* the backend.
* @param[in,out] load_arg Arguments for data loading.
*
* @return 0 or negative error code
*/
int settings_call_set_handler(const char *name,
size_t len,
settings_read_cb read_cb,
void *read_cb_arg,
const struct settings_load_arg *load_arg);
/* /*
* API for const name processing * API for const name processing
*/ */

View file

@ -46,9 +46,7 @@ static struct bt_conn_cb conn_callbacks = {
}; };
static int zephyr_settings_fw_load(struct settings_store *cs, static int zephyr_settings_fw_load(struct settings_store *cs,
const char *subtree, const struct settings_load_arg *arg);
settings_load_direct_cb cb,
void *param);
static const struct settings_store_itf zephyr_settings_fw_itf = { static const struct settings_store_itf zephyr_settings_fw_itf = {
.csi_load = zephyr_settings_fw_load, .csi_load = zephyr_settings_fw_load,
@ -59,12 +57,10 @@ static struct settings_store zephyr_settings_fw_store = {
}; };
static int zephyr_settings_fw_load(struct settings_store *cs, static int zephyr_settings_fw_load(struct settings_store *cs,
const char *subtree, const struct settings_load_arg *arg)
settings_load_direct_cb cb,
void *param)
{ {
/* Ignore subtree and direct loading */ /* Ignore subtree and direct loading */
if (subtree || cb) if (arg && (arg->subtree || arg->cb))
return 0; return 0;
#if defined(CONFIG_BT_GATT_DIS_SETTINGS) #if defined(CONFIG_BT_GATT_DIS_SETTINGS)
settings_runtime_set("bt/dis/model", settings_runtime_set("bt/dis/model",

View file

@ -190,6 +190,46 @@ struct settings_handler_static *settings_parse_and_lookup(const char *name,
return bestmatch; return bestmatch;
} }
int settings_call_set_handler(const char *name,
size_t len,
settings_read_cb read_cb,
void *read_cb_arg,
const struct settings_load_arg *load_arg)
{
int rc;
const char *name_key;
if (load_arg && load_arg->subtree &&
!settings_name_steq(name, load_arg->subtree, &name_key)) {
return 0;
}
if (load_arg && load_arg->cb) {
rc = load_arg->cb(name_key, len, read_cb, read_cb_arg,
load_arg->param);
} else {
struct settings_handler_static *ch;
ch = settings_parse_and_lookup(name, &name_key);
if (!ch) {
return 0;
}
rc = ch->h_set(name_key, len, read_cb, read_cb_arg);
if (rc != 0) {
LOG_ERR("set-value failure. key: %s error(%d)",
log_strdup(name), rc);
/* Ignoring the error */
rc = 0;
} else {
LOG_DBG("set-value OK. key: %s",
log_strdup(name));
}
}
return rc;
}
int settings_commit(void) int settings_commit(void)
{ {
return settings_commit_subtree(NULL); return settings_commit_subtree(NULL);

View file

@ -23,8 +23,8 @@ struct settings_fcb_load_cb_arg {
void *cb_arg; void *cb_arg;
}; };
static int settings_fcb_load(struct settings_store *cs, const char *subtree, static int settings_fcb_load(struct settings_store *cs,
settings_load_direct_cb cb, void *param); const struct settings_load_arg *arg);
static int settings_fcb_save(struct settings_store *cs, const char *name, static int settings_fcb_save(struct settings_store *cs, const char *name,
const char *value, size_t val_len); const char *value, size_t val_len);
@ -118,15 +118,10 @@ static int settings_fcb_load_priv(struct settings_store *cs, line_load_cb cb,
return 0; return 0;
} }
static int settings_fcb_load(struct settings_store *cs, const char *subtree, static int settings_fcb_load(struct settings_store *cs,
settings_load_direct_cb cb, void *param) const struct settings_load_arg *arg)
{ {
struct settings_line_load_arg arg = { return settings_fcb_load_priv(cs, settings_line_load_cb, (void *)arg);
.subtree = subtree,
.direct_cb = cb,
.param = param
};
return settings_fcb_load_priv(cs, settings_line_load_cb, &arg);
} }

View file

@ -14,8 +14,8 @@
#include "settings/settings_file.h" #include "settings/settings_file.h"
#include "settings_priv.h" #include "settings_priv.h"
static int settings_file_load(struct settings_store *cs, const char *subtree, static int settings_file_load(struct settings_store *cs,
settings_load_direct_cb cb, void *param); const struct settings_load_arg *arg);
static int settings_file_save(struct settings_store *cs, const char *name, static int settings_file_save(struct settings_store *cs, const char *name,
const char *value, size_t val_len); const char *value, size_t val_len);
@ -110,15 +110,10 @@ static int settings_file_load_priv(struct settings_store *cs, line_load_cb cb,
/* /*
* Called to load configuration items. * Called to load configuration items.
*/ */
static int settings_file_load(struct settings_store *cs, const char *subtree, static int settings_file_load(struct settings_store *cs,
settings_load_direct_cb cb, void *param) const struct settings_load_arg *arg)
{ {
struct settings_line_load_arg arg = { return settings_file_load_priv(cs, settings_line_load_cb, (void *)arg);
.subtree = subtree,
.direct_cb = cb,
.param = param
};
return settings_file_load_priv(cs, settings_line_load_cb, &arg);
} }
static void settings_tmpfile(char *dst, const char *src, char *pfx) static void settings_tmpfile(char *dst, const char *src, char *pfx)

View file

@ -542,43 +542,15 @@ static ssize_t settings_line_read_cb(void *cb_arg, void *data, size_t len)
} }
int settings_line_load_cb(const char *name, void *val_read_cb_ctx, off_t off, int settings_line_load_cb(const char *name, void *val_read_cb_ctx, off_t off,
void *cb_arg) void *cb_arg)
{ {
const char *name_key;
struct settings_handler_static *ch;
struct settings_line_read_value_cb_ctx value_ctx;
struct settings_line_load_arg *arg = cb_arg;
int rc;
size_t len; size_t len;
struct settings_line_read_value_cb_ctx value_ctx;
if (arg && arg->subtree && struct settings_load_arg *arg = cb_arg;
!settings_name_steq(name, arg->subtree, &name_key)) {
return 0;
}
value_ctx.read_cb_ctx = val_read_cb_ctx; value_ctx.read_cb_ctx = val_read_cb_ctx;
value_ctx.off = off; value_ctx.off = off;
len = settings_line_val_get_len(off, val_read_cb_ctx); len = settings_line_val_get_len(off, val_read_cb_ctx);
if (arg && arg->direct_cb) { return settings_call_set_handler(name, len, settings_line_read_cb,
rc = arg->direct_cb(name_key, len, settings_line_read_cb, &value_ctx, arg);
(void *)&value_ctx, arg->param);
} else {
ch = settings_parse_and_lookup(name, &name_key);
if (!ch) {
return 0;
}
rc = ch->h_set(name_key, 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));
}
}
return rc;
} }

View file

@ -20,8 +20,8 @@ struct settings_nvs_read_fn_arg {
u16_t id; u16_t id;
}; };
static int settings_nvs_load(struct settings_store *cs, const char *subtree, static int settings_nvs_load(struct settings_store *cs,
settings_load_direct_cb cb, void *param); const struct settings_load_arg *arg);
static int settings_nvs_save(struct settings_store *cs, const char *name, static int settings_nvs_save(struct settings_store *cs, const char *name,
const char *value, size_t val_len); const char *value, size_t val_len);
@ -63,15 +63,14 @@ int settings_nvs_dst(struct settings_nvs *cf)
return 0; return 0;
} }
static int settings_nvs_load(struct settings_store *cs, const char *subtree, static int settings_nvs_load(struct settings_store *cs,
settings_load_direct_cb cb, void *param) const struct settings_load_arg *arg)
{ {
int ret = 0;
struct settings_nvs *cf = (struct settings_nvs *)cs; struct settings_nvs *cf = (struct settings_nvs *)cs;
struct settings_nvs_read_fn_arg read_fn_arg; struct settings_nvs_read_fn_arg read_fn_arg;
struct settings_handler_static *ch;
char name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1]; char name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
char buf; char buf;
const char *name_argv;
ssize_t rc1, rc2; ssize_t rc1, rc2;
u16_t name_id = NVS_NAMECNT_ID; u16_t name_id = NVS_NAMECNT_ID;
@ -114,31 +113,18 @@ static int settings_nvs_load(struct settings_store *cs, const char *subtree,
/* Found a name, this might not include a trailing \0 */ /* Found a name, this might not include a trailing \0 */
name[rc1] = '\0'; name[rc1] = '\0';
if (subtree && !settings_name_steq(name, subtree, &name_argv)) {
continue;
}
read_fn_arg.fs = &cf->cf_nvs; read_fn_arg.fs = &cf->cf_nvs;
read_fn_arg.id = name_id + NVS_NAME_ID_OFFSET; read_fn_arg.id = name_id + NVS_NAME_ID_OFFSET;
if (cb) {
int ret;
ret = cb(name_argv, rc2, settings_nvs_read_fn, ret = settings_call_set_handler(
(void *) &read_fn_arg, param); name, rc2,
if (ret) settings_nvs_read_fn, &read_fn_arg,
return ret; (void *)arg);
} else { if (ret) {
ch = settings_parse_and_lookup(name, &name_argv); break;
if (!ch) {
continue;
}
ch->h_set(name_argv, rc2, settings_nvs_read_fn,
(void *) &read_fn_arg);
} }
} }
return 0; return ret;
} }
static int settings_nvs_save(struct settings_store *cs, const char *name, static int settings_nvs_save(struct settings_store *cs, const char *name,

View file

@ -46,12 +46,6 @@ int settings_line_load_cb(const char *name, void *val_read_cb_ctx,
typedef int (*line_load_cb)(const char *name, void *val_read_cb_ctx, typedef int (*line_load_cb)(const char *name, void *val_read_cb_ctx,
off_t off, void *cb_arg); off_t off, void *cb_arg);
struct settings_line_load_arg {
const char *subtree;
settings_load_direct_cb direct_cb;
void *param;
};
struct settings_line_read_value_cb_ctx { struct settings_line_read_value_cb_ctx {
void *read_cb_ctx; void *read_cb_ctx;
off_t off; off_t off;

View file

@ -51,6 +51,9 @@ int settings_load_subtree(const char *subtree)
{ {
struct settings_store *cs; struct settings_store *cs;
int rc; int rc;
const struct settings_load_arg arg = {
.subtree = subtree
};
/* /*
* for every config store * for every config store
@ -60,7 +63,7 @@ int settings_load_subtree(const char *subtree)
*/ */
k_mutex_lock(&settings_lock, K_FOREVER); k_mutex_lock(&settings_lock, K_FOREVER);
SYS_SLIST_FOR_EACH_CONTAINER(&settings_load_srcs, cs, cs_next) { SYS_SLIST_FOR_EACH_CONTAINER(&settings_load_srcs, cs, cs_next) {
cs->cs_itf->csi_load(cs, subtree, NULL, NULL); cs->cs_itf->csi_load(cs, &arg);
} }
rc = settings_commit_subtree(subtree); rc = settings_commit_subtree(subtree);
k_mutex_unlock(&settings_lock); k_mutex_unlock(&settings_lock);
@ -74,6 +77,11 @@ int settings_load_subtree_direct(
{ {
struct settings_store *cs; struct settings_store *cs;
const struct settings_load_arg arg = {
.subtree = subtree,
.cb = cb,
.param = param
};
/* /*
* for every config store * for every config store
* load config * load config
@ -82,7 +90,7 @@ int settings_load_subtree_direct(
*/ */
k_mutex_lock(&settings_lock, K_FOREVER); k_mutex_lock(&settings_lock, K_FOREVER);
SYS_SLIST_FOR_EACH_CONTAINER(&settings_load_srcs, cs, cs_next) { SYS_SLIST_FOR_EACH_CONTAINER(&settings_load_srcs, cs, cs_next) {
cs->cs_itf->csi_load(cs, subtree, cb, param); cs->cs_itf->csi_load(cs, &arg);
} }
k_mutex_unlock(&settings_lock); k_mutex_unlock(&settings_lock);
return 0; return 0;