UCI stands for Unified Configuration Interface.
UCI is a subsystem/module intended to centralize the configuration of OpenWrt. It manages configuration data for CPE, where the configuration information is stored in form of files in /etc/config folder on CPE.
UCI Usage
To call UCI, we can either use "uci" user-space application helper or we can directly link to UCI library to call as C routine calls.
UCI Via Shell
Get the Primary SSID:
Open a port in firewall for TR69 client:
Change the httpd bind port to 8080:
A nice example from carrierwrt:
UCI Call via Library API
Suppose we want to have UCI like below:
This requires us to create a config file name "easycwmp" and name the config section "stun_server":
The skeletal C code would be like below:
UCI Walk Through
To walk through each option entry under the config section:
As the rule, if we want UCI to return data in the format of [<filename>.<config name>.<type>], The declaration in /etc/config/<filename> is:
config <config-name> 'named section'
option <option-name> <value>
'named section' can be blank (which would make the config section unnamed)
Another example:
Requires config file /etc/config/wireless with entry like lines below:
UCI API
Function Name
|
Purpose
|
---|---|
struct uci_context *uci_alloc_context(void) | Allocate a new UCI context |
void uci_free_context(struct uci_context *ctx) | Free the allocated UCI context, including all of its data |
void uci_perror(struct uci_context *ctx, const char *str) |
Print the last uci error that occured
@ctx: uci context @str: string to print before the error message |
void uci_get_errorstr(struct uci_context *ctx, char **dest, const char *str) |
Get an error string for the last uci error
@ctx: uci context @dest: target pointer for the string @str: prefix for the error message
Note: string must be freed by the caller
|
int uci_import(struct uci_context *ctx, FILE *stream, const char *name, struct uci_package **package, bool single) |
Import uci config data from a stream
The name parameter is for config files that don't explicitly use the 'package <...>' keyword
if 'package' points to a non-null struct pointer, enable delta tracking and merge |
int uci_export(struct uci_context *ctx, FILE *stream, struct uci_package *package, bool header) |
Export one or all uci config packages
|
int uci_load(struct uci_context *ctx, const char *name, struct uci_package **package) | Parse an uci config file and store it in the uci context
|
int uci_unload(struct uci_context *ctx, struct uci_package *p) | Unload a config file from the uci context
|
int uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *str, bool extended)
| Split an uci tuple string and look up an element tree
if extended is set to true, uci_lookup_ptr supports the following extended syntax: Examples: network.@interface[0].ifname ('ifname' option of the first interface section) network.@interface[-1] (last interface section)
Note: uci_lookup_ptr will automatically load a config package if necessary
@str must not be constant, as it will be modified and used for the strings inside @ptr, thus it must also be available as long as @ptr is in use. |
int uci_add_section(struct uci_context *ctx, struct uci_package *p, const char *type, struct uci_section **res) | Add an unnamed section
|
int uci_set(struct uci_context *ctx, struct uci_ptr *ptr) | Set an element's value; create the element if necessary
The updated/created element is stored in ptr->last |
int uci_add_list(struct uci_context *ctx, struct uci_ptr *ptr)
| Append a string to an element list
Note: if the given option already contains a string value, it will be converted to an 1-element-list before appending the next element |
int uci_reorder_section(struct uci_context *ctx, struct uci_section *s, int pos)
| Reposition a section
|
int uci_rename(struct uci_context *ctx, struct uci_ptr *ptr)
| Rename an element
|
int uci_delete(struct uci_context *ctx, struct uci_ptr *ptr)
| Delete a section or option
|
int uci_save(struct uci_context *ctx, struct uci_package *p)
| save change delta for a package
|
int uci_commit(struct uci_context *ctx, struct uci_package **p, bool overwrite)
| commit changes to a package
Committing may reload the whole uci_package data, the supplied pointer is updated accordingly |
int uci_list_configs(struct uci_context *ctx, char ***list)
| List available uci config files @ctx: uci context Caller is responsible for freeing the allocated memory behind list |
int uci_set_savedir(struct uci_context *ctx, const char *dir);
| override the default delta save directory
|
int uci_add_delta_path(struct uci_context *ctx, const char *dir)
| add a directory to the search path for change delta files
|
int uci_revert(struct uci_context *ctx, struct uci_ptr *ptr)
| revert all changes to a config item
|
int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char **result)
| parse a shell-style argument, with an arbitrary quoting style
|
int uci_set_backend(struct uci_context *ctx, const char *name)
| change the default backend
The default backend is "file", which uses /etc/config for config storage |
bool uci_validate_text(const char *str)
| validate a value string for uci options @str: value this function checks whether a given string is acceptable as value for uci options |
int uci_add_hook(struct uci_context *ctx, const struct uci_hook_ops *ops)
| add a uci hook
NB: allocated and freed by the caller |
int uci_remove_hook(struct uci_context *ctx, const struct uci_hook_ops *ops)
| remove a uci hook
|
int uci_load_plugin(struct uci_context *ctx, const char *filename) | load an uci plugin
NB: plugin will be unloaded automatically when the context is freed |
int uci_load_plugins(struct uci_context *ctx, const char *pattern)
| load all uci plugins from a directory
if pattern is NULL, then uci_load_plugins will call uci_load_plugin for uci_*.so in <prefix>/lib/ |
int uci_parse_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *str)
| parse a uci string into a uci_ptr
str is modified by this function |
int uci_lookup_next(struct uci_context *ctx, struct uci_element **e, struct uci_list *list, const char *name)
| lookup a child element
if parent is NULL, the function looks up the package with the given name |
void uci_parse_section(struct uci_section *s, const struct uci_parse_option *opts,
int n_opts, struct uci_option **tb) | look up a set of options
|
uint32_t uci_hash_options(struct uci_option **tb, int n_opts)
| build a hash over a list of options
|
Examples
TO get and set value:
Walk-through each entry under a subtree/sub-path (e.g: under "easycwmp.stun_server"). This is basically to load a package and initialize our buffer with values retrieved from the options in the package.
References
(...to be continued....)