Config¶
Config subsystem is meant for persisting per-device configuration and runtime state for packages.
Configuration items are stored as key-value pairs, where both the key and
the value are expected to be strings. Keys are divided into component
elements, where packages register their subtree using the first element.
E.g key id/serial
consists of 2 components, id
and serial
.
Package sys/id registered it’s subtree of configuration elements to be
under id
.
There are convenience routines for converting value back and forth from string.
Handlers¶
Config handlers for subtree implement a set of handler functions.
These are registered using a call to conf_register()
.
- ch_get
This gets called when somebody asks for a config element value by it’s name using
conf_get_value()
.
- ch_set
This is called when value is being set using
conf_set_value()
, and also when configuration is loaded from persisted storage withconf_load()
.
- ch_commit
This gets called after configuration has been loaded in full. Sometimes you don’t want individual configuration value to take effect right away, for example if there are multiple settings which are interdependent.
- ch_export
This gets called to dump all current configuration. This happens when
conf_save()
tries to save the settings, or when CLI is dumping current system configuration to console.
Persistence¶
Backend storage for the config can be either FCB, a file in filesystem, or both.
You can declare multiple sources for configuration; settings from
all of these are restored when conf_load()
is called.
There can be only one target for writing configuration; this is where
data is stored when you call conf_save()
, or conf_save_one().
FCB read target is registered using conf_fcb_src()
, and write target
using conf_fcb_dst()
. conf_fcb_src()
as side-effect initializes the
FCB area, so it must be called when calling conf_fcb_dst()
.
File read target is registered using conf_file_src()
, and write target
conf_file_dst()
.
Convenience initialization of one config area can be enabled by setting either syscfg variable CONFIG_FCB or CONFIG_NFFS. These use other syscfg variables to figure which flash_map entry of BSP defines flash area, or which file to use. Check the syscfg.yml in sys/config package for more detailed description.
CLI¶
This can be enabled when shell package is enabled by setting syscfg variable CONFIG_CLI to 1.
Here you can set config variables, inspect their values and print both saved configuration as well as running configuration.
- config dump
Dump the current running configuration
- config dump saved
Dump the saved configuration. The values are printed in the ordered they’re restored.
- config <key>
Print the value of config variable identified by <key>
- config <key> <value>
Set the value of config variable <key> to be <value>
Example: Device Configuration¶
This is a simple example, config handler only implements ch_set
and
ch_export
. ch_set
is called when value is restored from storage (or
when set initially), and ch_export
is used to write the value to
storage (or dump to console).
static int8 foo_val;
struct conf_handler my_conf = {
.ch_name = "foo",
.ch_set = foo_conf_set,
.ch_export = foo_conf_export
}
static int
foo_conf_set(int argc, char **argv, char *val)
{
if (argc == 1) {
if (!strcmp(argv[0], "bar")) {
return CONF_VALUE_SET(val, CONF_INT8, foo_val);
}
}
return OS_ENOENT;
}
static int
foo_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt)
{
char buf[4];
conf_str_from_value(CONF_INT8, &foo_val, buf, sizeof(buf));
func("foo/bar", buf)
return 0;
}
Example: Persist Runtime State¶
This is a simple example showing how to persist runtime state. Here
there is only ch_set
defined, which is used when restoring value from
persisted storage.
There’s a os_callout function which increments foo_val, and then
persists the latest number. When system restarts, and calls conf_load()
,
foo_val will continue counting up from where it was before restart.
static int8 foo_val;
struct conf_handler my_conf = {
.ch_name = "foo",
.ch_set = foo_conf_set
}
static int
foo_conf_set(int argc, char **argv, char *val)
{
if (argc == 1) {
if (!strcmp(argv[0], "bar")) {
return CONF_VALUE_SET(val, CONF_INT8, foo_val);
}
}
return OS_ENOENT;
}
static void
foo_callout(struct os_event *ev)
{
struct os_callout *c = (struct os_callout *)ev;
char buf[4];
foo_val++;
conf_str_from_value(CONF_INT8, &foo_val, buf, sizeof(buf));
conf_save_one("foo/bar", bar);
callout_reset(c, OS_TICKS_PER_SEC * 120);
}
API¶
-
enum
conf_type
¶ Type of configuration value.
Values:
-
enum
conf_export_tgt
¶ Parameter to commit handler describing where data is going to.
Values:
-
enumerator
CONF_EXPORT_PERSIST
¶ Value is to be persisted.
-
enumerator
CONF_EXPORT_SHOW
¶ Value is to be display.
-
enumerator
-
typedef enum conf_export_tgt
conf_export_tgt_t
¶
-
typedef char *(*
conf_get_handler_t
)(int argc, char **argv, char *val, int val_len_max)¶ Handler for getting configuration items, this handler is called per-configuration section.
Configuration sections are delimited by ‘/’, for example:
section/name/value
Would be passed as:
argc = 3
argv[0] = section
argv[1] = name
argv[2] = value
The handler returns the value into val, null terminated, up to val_len_max.
- Return
A pointer to val or NULL if error.
- Parameters
argc
: The number of sections in the configuration variableargv
: The array of configuration sectionsval
: A pointer to the buffer to return the configuration value into.val_len_max
: The maximum length of the val buffer to copy into.
-
typedef char *(*
conf_get_handler_ext_t
)(int argc, char **argv, char *val, int val_len_max, void *arg)¶
-
typedef int (*
conf_set_handler_t
)(int argc, char **argv, char *val)¶ Set the configuration variable pointed to by argc and argv.
See description of ch_get_handler_t for format of these variables. This sets the configuration variable to the shadow value, but does not apply the configuration change. In order to apply the change, call the ch_commit() handler.
- Return
0 on success, non-zero error code on failure.
- Parameters
argc
: The number of sections in the configuration variable.argv
: The array of configuration sectionsval
: The value to configure that variable to
-
typedef int (*
conf_set_handler_ext_t
)(int argc, char **argv, char *val, void *arg)¶
-
typedef int (*
conf_commit_handler_t
)(void)¶ Commit shadow configuration state to the active configuration.
- Return
0 on success, non-zero error code on failure.
-
typedef int (*
conf_commit_handler_ext_t
)(void *arg)¶
-
typedef void (*
conf_export_func_t
)(char *name, char *val)¶ Called per-configuration variable being exported.
- Parameters
name
: The name of the variable to exportval
: The value of the variable to export
-
typedef int (*
conf_export_handler_t
)(conf_export_func_t export_func, conf_export_tgt_t tgt)¶ Export all of the configuration variables, calling the export_func per variable being exported.
- Return
0 on success, non-zero error code on failure.
- Parameters
export_func
: The export function to call.tgt
: The target of the export, either for persistence or display.
-
typedef int (*
conf_export_handler_ext_t
)(conf_export_func_t export_func, conf_export_tgt_t tgt, void *arg)¶
-
typedef void (*
conf_store_load_cb
)(char *name, char *val, void *cb_arg)¶
-
void
conf_init
(void)¶
-
void
conf_store_init
(void)¶
-
int
conf_register
(struct conf_handler *cf)¶ Register a handler for configurations items.
- Return
0 on success, non-zero on failure.
- Parameters
cf
: Structure containing registration info.
-
int
conf_load
(void)¶ Load configuration from registered persistence sources.
Handlers for configuration subtrees registered earlier will be called for encountered values.
- Return
0 on success, non-zero on failure.
-
int
conf_load_one
(char *name)¶ Load configuration from a specific registered persistence source.
Handlers will be called for configuration subtree for encountered values.
- Return
0 on success, non-zero on failure.
- Parameters
name
: of the configuration subtree.
-
int
conf_ensure_loaded
(void)¶ Loads the configuration if it hasn’t been loaded since reboot.
- Return
0 on success, non-zero on failure.
-
int
conf_set_from_storage
(void)¶ Config setting comes as a result of conf_load().
- Return
1 if yes, 0 if not.
-
int
conf_save
(void)¶ Save currently running configuration.
All configuration which is different from currently persisted values will be saved.
- Return
0 on success, non-zero on failure.
-
int
conf_save_tree
(char *name)¶ Save currently running configuration for configuration subtree.
- Return
0 on success, non-zero on failure.
- Parameters
name
: Name of the configuration subtree.
-
int
conf_save_one
(const char *name, char *var)¶ Write a single configuration value to persisted storage (if it has changed value).
- Return
0 on success, non-zero on failure.
- Parameters
name
: Name/key of the configuration item.var
: Value of the configuration item.
-
int
conf_set_value
(char *name, char *val_str)¶ Set configuration item identified by
name
to be valueval_str
.This finds the configuration handler for this subtree and calls it’s set handler.
- Return
0 on success, non-zero on failure.
- Parameters
name
: Name/key of the configuration item.val_str
: Value of the configuration item.
-
char *
conf_get_value
(char *name, char *buf, int buf_len)¶ Get value of configuration item identified by
name
.This calls the configuration handler ch_get for the subtree.
Configuration handler can copy the string to
buf
, the maximum number of bytes it will copy is limited bybuf_len
.Return value will be pointer to beginning of the value. Note that this might, or might not be the same as buf.
- Return
pointer to value on success, NULL on failure.
- Parameters
name
: Name/key of the configuration item.val_str
: Value of the configuration item.
-
int
conf_get_stored_value
(char *name, char *buf, int buf_len)¶ Get stored value of configuration item identified by
name
.This traverses the configuration area(s), and copies the value of the latest value.
Value is copied to
buf
, the maximum number of bytes it will copy is limited bybuf_len
.- Return
0 on success, non-zero on failure.
- Parameters
name
: Name/key of the configuration item.val_str
: Value of the configuration item.
-
int
conf_commit
(char *name)¶ Call commit for all configuration handler.
This should apply all configuration which has been set, but not applied yet.
- Return
0 on success, non-zero on failure.
- Parameters
name
: Name of the configuration subtree, or NULL to commit everything.
-
int
conf_value_from_str
(char *val_str, enum conf_type type, void *vp, int maxlen)¶ Convenience routine for converting value passed as a string to native data type.
- Return
0 on success, non-zero on failure.
- Parameters
val_str
: Value of the configuration item as string.type
: Type of the value to convert to.vp
: Pointer to variable to fill with the decoded value.vp
: Size of that variable.
-
int
conf_bytes_from_str
(char *val_str, void *vp, int *len)¶ Convenience routine for converting byte array passed as a base64 encoded string.
- Return
0 on success, non-zero on failure.
- Parameters
val_str
: Value of the configuration item as string.vp
: Pointer to variable to fill with the decoded value.len
: Size of that variable. On return the number of bytes in the array.
-
char *
conf_str_from_value
(enum conf_type type, void *vp, char *buf, int buf_len)¶ Convenience routine for converting native data type to a string.
- Return
0 on success, non-zero on failure.
- Parameters
type
: Type of the value to convert from.vp
: Pointer to variable to convert.buf
: Buffer where string value will be stored.buf_len
: Size of the buffer.
-
char *
conf_str_from_bytes
(void *vp, int vp_len, char *buf, int buf_len)¶ Convenience routine for converting byte array into a base64 encoded string.
- Return
0 on success, non-zero on failure.
- Parameters
vp
: Pointer to variable to convert.vp_len
: Number of bytes to convert.buf
: Buffer where string value will be stored.buf_len
: Size of the buffer.
-
void
conf_lock
(void)¶ Locks the config package.
If another task tries to read or write a setting while the config package is locked, the operation will block until the package is unlocked. The locking task is permitted to read and write settings as usual. A call to
conf_lock()
should always be followed byconf_unlock()
.Typical usage of the config API does not require manual locking. This function is only needed for unusual use cases such as temporarily changing the destination medium for an isolated series of writes.
-
void
conf_unlock
(void)¶ Unlocks the config package.
This function reverts the effects of the
conf_lock()
function. Typical usage of the config API does not require manual locking.
-
void
conf_src_register
(struct conf_store *cs)¶
-
void
conf_dst_register
(struct conf_store *cs)¶
-
CONF_STR_FROM_BYTES_LEN
(len)¶ Return the length of a configuration string from buffer length.
-
CONF_VALUE_SET
(str, type, val)¶ Convert a string into a value of type.
-
struct
conf_handler
¶ - #include <config.h>
Configuration handler, used to register a config item/subtree.
Public Members
-
char *
ch_name
¶ The name of the conifguration item/subtree.
-
bool
ch_ext
¶ Whether to use the extended callbacks.
false: standard true: extended
-
union conf_handler.[anonymous] [anonymous]¶
Get configuration value.
-
union conf_handler.[anonymous] [anonymous]¶
Set configuration value.
-
union conf_handler.[anonymous] [anonymous]¶
Commit configuration value.
-
union conf_handler.[anonymous] [anonymous]¶
Export configuration value.
-
void *
ch_arg
¶ Custom argument that gets passed to the extended callbacks.
-
char *
-
struct
conf_store_itf
¶ - #include <config_store.h>
-
struct
conf_store
¶ - #include <config_store.h>