mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
Add uci api & fix other issues
This commit is contained in:
parent
22beb8fb06
commit
f1560b1305
13 changed files with 683 additions and 423 deletions
|
|
@ -2,6 +2,7 @@ CWMP_VERSION = 3.0.0
|
||||||
bin_PROGRAMS = icwmpd
|
bin_PROGRAMS = icwmpd
|
||||||
|
|
||||||
icwmpd_SOURCES = \
|
icwmpd_SOURCES = \
|
||||||
|
../cwmp_uci.c \
|
||||||
../backupSession.c \
|
../backupSession.c \
|
||||||
../config.c \
|
../config.c \
|
||||||
../cwmp.c \
|
../cwmp.c \
|
||||||
|
|
|
||||||
393
config.c
393
config.c
|
|
@ -4,10 +4,10 @@
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2019 iopsys Software Solutions AB
|
* Copyright (C) 2013-2020 iopsys Software Solutions AB
|
||||||
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
||||||
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
||||||
*
|
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -36,12 +36,6 @@
|
||||||
|
|
||||||
pthread_mutex_t mutex_config_load = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t mutex_config_load = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
typedef enum uci_config_action {
|
|
||||||
CMD_SET,
|
|
||||||
CMD_SET_STATE,
|
|
||||||
CMD_ADD_LIST,
|
|
||||||
CMD_DEL,
|
|
||||||
} uci_config_action;
|
|
||||||
|
|
||||||
struct option long_options[] = {
|
struct option long_options[] = {
|
||||||
{"boot-event", no_argument, NULL, 'b'},
|
{"boot-event", no_argument, NULL, 'b'},
|
||||||
|
|
@ -68,18 +62,6 @@ static void show_help(void)
|
||||||
printf("Usage: icwmpd [OPTIONS]\n");
|
printf("Usage: icwmpd [OPTIONS]\n");
|
||||||
printf(" -b, --boot-event (CWMP daemon) Start CWMP with BOOT event\n");
|
printf(" -b, --boot-event (CWMP daemon) Start CWMP with BOOT event\n");
|
||||||
printf(" -g, --get-rpc-methods (CWMP daemon) Start CWMP with GetRPCMethods request to ACS\n");
|
printf(" -g, --get-rpc-methods (CWMP daemon) Start CWMP with GetRPCMethods request to ACS\n");
|
||||||
printf(" -c, --command-input (DataModel CLI) Execute data model rpc(s) with commands input\n");
|
|
||||||
printf(" -m, --shell-cli <data model rpc> (DataModel CLI) Execute data model RPC command directly from shell.\n");
|
|
||||||
printf(" -a, --alias-based-addressing (DataModel CLI) Alias based addressing supported\n");
|
|
||||||
printf(" -N, --instance-mode-number (DataModel CLI) Instance mode is Number (Enabled by default)\n");
|
|
||||||
printf(" -A, --instance-mode-alias (DataModel CLI) Instance mode is Alias\n");
|
|
||||||
printf(" -M, --amendment <amendment version> (DataModel CLI) Amendment version (Default amendment version is 2)\n");
|
|
||||||
printf(" -U, --upnp (DataModel CLI) Use UPNP data model paths\n");
|
|
||||||
printf(" -u, --user-acl <public|basic|xxxadmin|superadmin> (DataModel CLI) user access level. Default: superadmin\n");
|
|
||||||
printf(" -t, --time-tracking (DataModel CLI) Tracking time of RPC commands\n");
|
|
||||||
printf(" -E, --evaluating-test (DataModel CLI) Evaluating test format\n");
|
|
||||||
printf(" -f, --file <file path> (DataModel CLI) Execute data model rpc(s) from file\n");
|
|
||||||
printf(" -w, --wep <strength> <passphrase> (WEP KEY GEN) Generate wep keys\n");
|
|
||||||
printf(" -h, --help Display this help text\n");
|
printf(" -h, --help Display this help text\n");
|
||||||
printf(" -v, --version Display the version\n");
|
printf(" -v, --version Display the version\n");
|
||||||
}
|
}
|
||||||
|
|
@ -93,296 +75,6 @@ void show_version()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int uci_get_list_value(char *cmd, struct list_head *list)
|
|
||||||
{
|
|
||||||
struct uci_ptr ptr;
|
|
||||||
struct uci_context *c = uci_alloc_context();
|
|
||||||
struct uci_element *e;
|
|
||||||
struct config_uci_list *uci_list_elem;
|
|
||||||
char *s,*t;
|
|
||||||
int size = 0;
|
|
||||||
|
|
||||||
if (!c)
|
|
||||||
{
|
|
||||||
CWMP_LOG(ERROR, "Out of memory");
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = strdup(cmd);
|
|
||||||
t = s;
|
|
||||||
if (uci_lookup_ptr(c, &ptr, s, true) != UCI_OK)
|
|
||||||
{
|
|
||||||
CWMP_LOG(ERROR, "Invalid uci command path: %s",cmd);
|
|
||||||
free(t);
|
|
||||||
uci_free_context(c);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ptr.o == NULL)
|
|
||||||
{
|
|
||||||
free(t);
|
|
||||||
uci_free_context(c);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ptr.o->type == UCI_TYPE_LIST)
|
|
||||||
{
|
|
||||||
uci_foreach_element(&ptr.o->v.list, e)
|
|
||||||
{
|
|
||||||
if((e != NULL)&&(e->name))
|
|
||||||
{
|
|
||||||
uci_list_elem = calloc(1,sizeof(struct config_uci_list));
|
|
||||||
if(uci_list_elem == NULL)
|
|
||||||
{
|
|
||||||
free(t);
|
|
||||||
uci_free_context(c);
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
uci_list_elem->value = strdup(e->name);
|
|
||||||
list_add_tail (&(uci_list_elem->list), list);
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free(t);
|
|
||||||
uci_free_context(c);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(t);
|
|
||||||
uci_free_context(c);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_get_value_common(char *cmd,char **value,bool state)
|
|
||||||
{
|
|
||||||
struct uci_ptr ptr;
|
|
||||||
struct uci_context *c = uci_alloc_context();
|
|
||||||
char *s,*t;
|
|
||||||
char state_path[32];
|
|
||||||
|
|
||||||
*value = NULL;
|
|
||||||
if (!c)
|
|
||||||
{
|
|
||||||
CWMP_LOG(ERROR, "Out of memory");
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
if (state)
|
|
||||||
{
|
|
||||||
strcpy(state_path,"/var/state");
|
|
||||||
uci_add_delta_path(c, c->savedir);
|
|
||||||
uci_set_savedir(c, state_path);
|
|
||||||
}
|
|
||||||
s = strdup(cmd);
|
|
||||||
t = s;
|
|
||||||
if (uci_lookup_ptr(c, &ptr, s, true) != UCI_OK)
|
|
||||||
{
|
|
||||||
CWMP_LOG(ERROR, "Error occurred in uci %s get %s",state?"state":"config",cmd);
|
|
||||||
free(t);
|
|
||||||
uci_free_context(c);
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
free(t);
|
|
||||||
if(ptr.flags & UCI_LOOKUP_COMPLETE)
|
|
||||||
{
|
|
||||||
if (ptr.o==NULL || ptr.o->v.string==NULL)
|
|
||||||
{
|
|
||||||
CWMP_LOG(INFO, "%s not found or empty value",cmd);
|
|
||||||
uci_free_context(c);
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
*value = strdup(ptr.o->v.string);
|
|
||||||
}
|
|
||||||
uci_free_context(c);
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_get_state_value(char *cmd,char **value)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
error = uci_get_value_common (cmd,value,true);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_get_value(char *cmd,char **value)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
error = uci_get_value_common (cmd,value,false);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int uci_action_value_common(char *cmd, uci_config_action action)
|
|
||||||
{
|
|
||||||
int ret = UCI_OK;
|
|
||||||
char *s,*t;
|
|
||||||
struct uci_context *c = uci_alloc_context();
|
|
||||||
struct uci_ptr ptr;
|
|
||||||
char state_path[32];
|
|
||||||
|
|
||||||
if (!c)
|
|
||||||
{
|
|
||||||
CWMP_LOG(ERROR, "Out of memory");
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action == CMD_SET_STATE)
|
|
||||||
{
|
|
||||||
strcpy(state_path,"/var/state");
|
|
||||||
uci_add_delta_path(c, c->savedir);
|
|
||||||
uci_set_savedir(c, state_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
s = strdup(cmd);
|
|
||||||
t = s;
|
|
||||||
|
|
||||||
if (uci_lookup_ptr(c, &ptr, s, true) != UCI_OK)
|
|
||||||
{
|
|
||||||
free(t);
|
|
||||||
uci_free_context(c);
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case CMD_SET:
|
|
||||||
case CMD_SET_STATE:
|
|
||||||
ret = uci_set(c, &ptr);
|
|
||||||
break;
|
|
||||||
case CMD_DEL:
|
|
||||||
ret = uci_delete(c, &ptr);
|
|
||||||
break;
|
|
||||||
case CMD_ADD_LIST:
|
|
||||||
ret = uci_add_list(c, &ptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ret == UCI_OK)
|
|
||||||
{
|
|
||||||
ret = uci_save(c, ptr.p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CWMP_LOG(ERROR, "UCI %s %s not succeed %s",action==CMD_SET_STATE?"state":"config",action==CMD_DEL?"delete":"set",cmd);
|
|
||||||
}
|
|
||||||
free(t);
|
|
||||||
uci_free_context(c);
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_delete_value(char *cmd)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
error = uci_action_value_common (cmd,CMD_DEL);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_set_value(char *cmd)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
error = uci_action_value_common (cmd,CMD_SET);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_set_state_value(char *cmd)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
error = uci_action_value_common (cmd,CMD_SET_STATE);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_add_list_value(char *cmd)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
error = uci_action_value_common (cmd,CMD_ADD_LIST);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cwmp_package_commit(struct uci_context *c,char *tuple)
|
|
||||||
{
|
|
||||||
struct uci_ptr ptr;
|
|
||||||
|
|
||||||
if (uci_lookup_ptr(c, &ptr, tuple, true) != UCI_OK) {
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uci_commit(c, &ptr.p, false) != UCI_OK)
|
|
||||||
{
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
uci_unload(c, ptr.p);
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cwmp_do_package_cmd(struct uci_context *c)
|
|
||||||
{
|
|
||||||
char **configs = NULL;
|
|
||||||
char **p;
|
|
||||||
|
|
||||||
if ((uci_list_configs(c, &configs) != UCI_OK) || !configs)
|
|
||||||
{
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (p = configs; *p; p++)
|
|
||||||
{
|
|
||||||
cwmp_package_commit(c,*p);
|
|
||||||
}
|
|
||||||
FREE(configs);
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_commit_value()
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct uci_context *c = uci_alloc_context();
|
|
||||||
|
|
||||||
if (!c)
|
|
||||||
{
|
|
||||||
CWMP_LOG(ERROR, "Out of memory");
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = cwmp_do_package_cmd(c);
|
|
||||||
if(ret == CWMP_OK)
|
|
||||||
{
|
|
||||||
uci_free_context(c);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uci_free_context(c);
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uci_revert_value ()
|
|
||||||
{
|
|
||||||
char **configs = NULL;
|
|
||||||
char **p;
|
|
||||||
struct uci_context *ctx = uci_alloc_context();
|
|
||||||
struct uci_ptr ptr;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
{
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((uci_list_configs(ctx, &configs) != UCI_OK) || !configs) {
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (p = configs; *p; p++)
|
|
||||||
{
|
|
||||||
if (uci_lookup_ptr(ctx, &ptr, *p, true) != UCI_OK)
|
|
||||||
{
|
|
||||||
return CWMP_GEN_ERR;
|
|
||||||
}
|
|
||||||
uci_revert(ctx, &ptr);
|
|
||||||
}
|
|
||||||
FREE(configs);
|
|
||||||
uci_free_context(ctx);
|
|
||||||
|
|
||||||
return CWMP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_global_config (struct config *conf)
|
int check_global_config (struct config *conf)
|
||||||
{
|
{
|
||||||
if (conf->acsurl==NULL)
|
if (conf->acsurl==NULL)
|
||||||
|
|
@ -978,6 +670,7 @@ int get_instance_mode_config()
|
||||||
}
|
}
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_lwn_config(struct config *conf)
|
int get_lwn_config(struct config *conf)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
@ -1031,90 +724,12 @@ int get_lwn_config(struct config *conf)
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool cwmp_check_section_name(const char *str, bool name)
|
|
||||||
{
|
|
||||||
if (!*str)
|
|
||||||
return false;
|
|
||||||
for (; *str; str++) {
|
|
||||||
unsigned char c = *str;
|
|
||||||
if (isalnum(c) || c == '_')
|
|
||||||
continue;
|
|
||||||
if (name || (c < 33) || (c > 126))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cwmp_uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value)
|
|
||||||
{
|
|
||||||
/*value*/
|
|
||||||
ptr->value = value;
|
|
||||||
|
|
||||||
/*package*/
|
|
||||||
if (!package)
|
|
||||||
return -1;
|
|
||||||
ptr->package = package;
|
|
||||||
|
|
||||||
/*section*/
|
|
||||||
if (!section || !section[0]) {
|
|
||||||
ptr->target = UCI_TYPE_PACKAGE;
|
|
||||||
goto lookup;
|
|
||||||
}
|
|
||||||
ptr->section = section;
|
|
||||||
if (ptr->section && !cwmp_check_section_name(ptr->section , true))
|
|
||||||
ptr->flags |= UCI_LOOKUP_EXTENDED;
|
|
||||||
|
|
||||||
/*option*/
|
|
||||||
if (!option || !option[0]) {
|
|
||||||
ptr->target = UCI_TYPE_SECTION;
|
|
||||||
goto lookup;
|
|
||||||
}
|
|
||||||
ptr->target = UCI_TYPE_OPTION;
|
|
||||||
ptr->option = option;
|
|
||||||
|
|
||||||
lookup:
|
|
||||||
if (uci_lookup_ptr(ctx, ptr, NULL, true) != UCI_OK || !UCI_LOOKUP_COMPLETE) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* cwmp_db_get_value_string(char *package, char *section, char *option)
|
|
||||||
{
|
|
||||||
struct uci_context *uci_ctx = uci_alloc_context();
|
|
||||||
|
|
||||||
struct uci_option *o = NULL;
|
|
||||||
struct uci_element *e;
|
|
||||||
struct uci_ptr ptr = {0};
|
|
||||||
|
|
||||||
uci_ctx->confdir = "/lib/db/config";
|
|
||||||
|
|
||||||
if (cwmp_uci_lookup_ptr(uci_ctx, &ptr, package, section, option, NULL))
|
|
||||||
return "";
|
|
||||||
|
|
||||||
e = ptr.last;
|
|
||||||
switch(e->type) {
|
|
||||||
case UCI_TYPE_OPTION:
|
|
||||||
o = ptr.o;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (o)
|
|
||||||
return o->v.string ? o->v.string : "";
|
|
||||||
else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int global_env_init (int argc, char** argv, struct env *env)
|
int global_env_init (int argc, char** argv, struct env *env)
|
||||||
{
|
{
|
||||||
|
|
||||||
int c, option_index = 0;
|
int c, option_index = 0;
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "bgcaNAUtEhvm:u:M:f:w:", long_options, &option_index)) != -1) {
|
while ((c = getopt_long(argc, argv, "bghv", long_options, &option_index)) != -1) {
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
9
cwmp.c
9
cwmp.c
|
|
@ -4,10 +4,10 @@
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2019 iopsys Software Solutions AB
|
* Copyright (C) 2013-2020 iopsys Software Solutions AB
|
||||||
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
||||||
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
||||||
*
|
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
@ -193,7 +193,7 @@ void cwmp_schedule_session (struct cwmp *cwmp)
|
||||||
is_notify = check_value_change();
|
is_notify = check_value_change();
|
||||||
}
|
}
|
||||||
if(is_notify>0 || access(DM_ENABLED_NOTIFY, F_OK ) < 0)
|
if(is_notify>0 || access(DM_ENABLED_NOTIFY, F_OK ) < 0)
|
||||||
cwmp_update_enabled_notify_file(cwmp->conf.amd_version, cwmp->conf.instance_mode);
|
cwmp_update_enabled_notify_file(cwmp->conf.instance_mode);
|
||||||
cwmp_prepare_value_change(cwmp);
|
cwmp_prepare_value_change(cwmp);
|
||||||
free_dm_parameter_all_fromlist(&list_value_change);
|
free_dm_parameter_all_fromlist(&list_value_change);
|
||||||
if ((error = cwmp_move_session_to_session_send (cwmp, session))) {
|
if ((error = cwmp_move_session_to_session_send (cwmp, session))) {
|
||||||
|
|
@ -592,7 +592,7 @@ int run_session_end_func ()
|
||||||
|
|
||||||
if (end_session_flag & END_SESSION_SET_NOTIFICATION_UPDATE) {
|
if (end_session_flag & END_SESSION_SET_NOTIFICATION_UPDATE) {
|
||||||
CWMP_LOG (INFO,"SetParameterAttributes end session: update enabled notify file");
|
CWMP_LOG (INFO,"SetParameterAttributes end session: update enabled notify file");
|
||||||
cwmp_update_enabled_notify_file(cwmp_main.conf.amd_version, cwmp_main.conf.instance_mode);
|
cwmp_update_enabled_notify_file(cwmp_main.conf.instance_mode);
|
||||||
}
|
}
|
||||||
if (end_session_flag & END_SESSION_TRANSACTION_COMMIT) {
|
if (end_session_flag & END_SESSION_TRANSACTION_COMMIT) {
|
||||||
cwmp_transaction_commit();
|
cwmp_transaction_commit();
|
||||||
|
|
@ -694,6 +694,7 @@ int cwmp_exit(void)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct cwmp *cwmp = &cwmp_main;
|
struct cwmp *cwmp = &cwmp_main;
|
||||||
int error;
|
int error;
|
||||||
pthread_t periodic_event_thread;
|
pthread_t periodic_event_thread;
|
||||||
|
|
|
||||||
550
cwmp_uci.c
Normal file
550
cwmp_uci.c
Normal file
|
|
@ -0,0 +1,550 @@
|
||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2020 iopsys Software Solutions AB
|
||||||
|
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cwmp_uci.h"
|
||||||
|
|
||||||
|
struct uci_paths uci_save_conf_paths[] = {
|
||||||
|
[UCI_STANDARD_CONFIG] ={"/etc/config","/tmp/.uci"},
|
||||||
|
[UCI_DB_CONFIG] = {"/lib/db/config", NULL},
|
||||||
|
[UCI_BOARD_DB_CONFIG] = {"/etc/board-db/config", NULL},
|
||||||
|
[UCI_VARSTATE_CONFIG] = {"/var/state", NULL},
|
||||||
|
[UCI_BBFDM_CONFIG] = {"/etc/bbfdm", "/tmp/.bbfdm"}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct uci_context *cwmp_uci_ctx = ((void *)0);
|
||||||
|
|
||||||
|
int cwmp_uci_init(int uci_path_type)
|
||||||
|
{
|
||||||
|
if (cwmp_uci_ctx == NULL) {
|
||||||
|
cwmp_uci_ctx = uci_alloc_context();
|
||||||
|
if (!cwmp_uci_ctx)
|
||||||
|
return -1;
|
||||||
|
if (uci_save_conf_paths[uci_path_type].save_dir) {
|
||||||
|
uci_add_delta_path(cwmp_uci_ctx, cwmp_uci_ctx->savedir);
|
||||||
|
uci_set_savedir(cwmp_uci_ctx, uci_save_conf_paths[uci_path_type].save_dir);
|
||||||
|
}
|
||||||
|
if (uci_save_conf_paths[uci_path_type].conf_dir)
|
||||||
|
uci_set_confdir(cwmp_uci_ctx, uci_save_conf_paths[uci_path_type].conf_dir);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cwmp_uci_exit(void)
|
||||||
|
{
|
||||||
|
if (cwmp_uci_ctx)
|
||||||
|
uci_free_context(cwmp_uci_ctx);
|
||||||
|
cwmp_uci_ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool cwmp_check_section_name(const char *str, bool name)
|
||||||
|
{
|
||||||
|
if (!*str)
|
||||||
|
return false;
|
||||||
|
for (; *str; str++) {
|
||||||
|
unsigned char c = *str;
|
||||||
|
if (isalnum(c) || c == '_')
|
||||||
|
continue;
|
||||||
|
if (name || (c < 33) || (c > 126))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cwmp_uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value)
|
||||||
|
{
|
||||||
|
/*value*/
|
||||||
|
ptr->value = value;
|
||||||
|
|
||||||
|
/*package*/
|
||||||
|
if (!package)
|
||||||
|
return -1;
|
||||||
|
ptr->package = package;
|
||||||
|
|
||||||
|
/*section*/
|
||||||
|
if (!section || !section[0]) {
|
||||||
|
ptr->target = UCI_TYPE_PACKAGE;
|
||||||
|
goto lookup;
|
||||||
|
}
|
||||||
|
ptr->section = section;
|
||||||
|
if (ptr->section && !cwmp_check_section_name(ptr->section , true))
|
||||||
|
ptr->flags |= UCI_LOOKUP_EXTENDED;
|
||||||
|
|
||||||
|
/*option*/
|
||||||
|
if (!option || !option[0]) {
|
||||||
|
ptr->target = UCI_TYPE_SECTION;
|
||||||
|
goto lookup;
|
||||||
|
}
|
||||||
|
ptr->target = UCI_TYPE_OPTION;
|
||||||
|
ptr->option = option;
|
||||||
|
|
||||||
|
lookup:
|
||||||
|
if (uci_lookup_ptr(ctx, ptr, NULL, true) != UCI_OK || !UCI_LOOKUP_COMPLETE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cwmp_db_get_value_string(char *package, char *section, char *option)
|
||||||
|
{
|
||||||
|
cwmp_uci_ctx = uci_alloc_context();
|
||||||
|
|
||||||
|
struct uci_option *o = NULL;
|
||||||
|
struct uci_element *e;
|
||||||
|
struct uci_ptr ptr = {0};
|
||||||
|
|
||||||
|
cwmp_uci_ctx->confdir = LIB_DB_CONFIG;
|
||||||
|
|
||||||
|
if (cwmp_uci_lookup_ptr(cwmp_uci_ctx, &ptr, package, section, option, NULL))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
e = ptr.last;
|
||||||
|
switch(e->type) {
|
||||||
|
case UCI_TYPE_OPTION:
|
||||||
|
o = ptr.o;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (o)
|
||||||
|
return o->v.string ? o->v.string : "";
|
||||||
|
else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cwmp_uci_get_option_value_list(char *package, char *section, char *option, struct list_head *list)
|
||||||
|
{
|
||||||
|
struct uci_element *e;
|
||||||
|
struct uci_ptr ptr = {0};
|
||||||
|
cwmp_uci_ctx = uci_alloc_context();
|
||||||
|
struct config_uci_list *uci_list_elem;
|
||||||
|
int size = 0;
|
||||||
|
//*value = NULL;
|
||||||
|
|
||||||
|
if (cwmp_uci_lookup_ptr(cwmp_uci_ctx, &ptr, package, section, option, NULL)) {
|
||||||
|
uci_free_context(cwmp_uci_ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr.o == NULL) {
|
||||||
|
uci_free_context(cwmp_uci_ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr.o->type == UCI_TYPE_LIST) {
|
||||||
|
uci_foreach_element(&ptr.o->v.list, e)
|
||||||
|
{
|
||||||
|
if((e != NULL)&&(e->name))
|
||||||
|
{
|
||||||
|
uci_list_elem = calloc(1,sizeof(struct config_uci_list));
|
||||||
|
if(uci_list_elem == NULL)
|
||||||
|
{
|
||||||
|
uci_free_context(cwmp_uci_ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
uci_list_elem->value = strdup(e->name);
|
||||||
|
list_add_tail (&(uci_list_elem->list), list);
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uci_free_context(cwmp_uci_ctx);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uci_free_context(cwmp_uci_ctx);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_get_list_value(char *cmd, struct list_head *list)
|
||||||
|
{
|
||||||
|
struct uci_ptr ptr;
|
||||||
|
struct uci_context *c = uci_alloc_context();
|
||||||
|
struct uci_element *e;
|
||||||
|
struct config_uci_list *uci_list_elem;
|
||||||
|
char *s,*t;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
{
|
||||||
|
CWMP_LOG(ERROR, "Out of memory");
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = strdup(cmd);
|
||||||
|
t = s;
|
||||||
|
if (uci_lookup_ptr(c, &ptr, s, true) != UCI_OK)
|
||||||
|
{
|
||||||
|
CWMP_LOG(ERROR, "Invalid uci command path: %s",cmd);
|
||||||
|
free(t);
|
||||||
|
uci_free_context(c);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ptr.o == NULL)
|
||||||
|
{
|
||||||
|
free(t);
|
||||||
|
uci_free_context(c);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ptr.o->type == UCI_TYPE_LIST)
|
||||||
|
{
|
||||||
|
uci_foreach_element(&ptr.o->v.list, e)
|
||||||
|
{
|
||||||
|
if((e != NULL)&&(e->name))
|
||||||
|
{
|
||||||
|
uci_list_elem = calloc(1,sizeof(struct config_uci_list));
|
||||||
|
if(uci_list_elem == NULL)
|
||||||
|
{
|
||||||
|
free(t);
|
||||||
|
uci_free_context(c);
|
||||||
|
return CWMP_GEN_ERR;
|
||||||
|
}
|
||||||
|
uci_list_elem->value = strdup(e->name);
|
||||||
|
list_add_tail (&(uci_list_elem->list), list);
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(t);
|
||||||
|
uci_free_context(c);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(t);
|
||||||
|
uci_free_context(c);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_get_value_common(char *cmd,char **value,bool state)
|
||||||
|
{
|
||||||
|
struct uci_ptr ptr;
|
||||||
|
struct uci_context *c = uci_alloc_context();
|
||||||
|
char *s,*t;
|
||||||
|
char state_path[32];
|
||||||
|
|
||||||
|
*value = NULL;
|
||||||
|
if (!c)
|
||||||
|
{
|
||||||
|
CWMP_LOG(ERROR, "Out of memory");
|
||||||
|
return CWMP_GEN_ERR;
|
||||||
|
}
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
strcpy(state_path,VARSTATE_CONFIG);
|
||||||
|
uci_add_delta_path(c, c->savedir);
|
||||||
|
uci_set_savedir(c, state_path);
|
||||||
|
}
|
||||||
|
s = strdup(cmd);
|
||||||
|
t = s;
|
||||||
|
if (uci_lookup_ptr(c, &ptr, s, true) != UCI_OK)
|
||||||
|
{
|
||||||
|
CWMP_LOG(ERROR, "Error occurred in uci %s get %s",state?"state":"config",cmd);
|
||||||
|
free(t);
|
||||||
|
uci_free_context(c);
|
||||||
|
return CWMP_GEN_ERR;
|
||||||
|
}
|
||||||
|
free(t);
|
||||||
|
if(ptr.flags & UCI_LOOKUP_COMPLETE)
|
||||||
|
{
|
||||||
|
if (ptr.o==NULL || ptr.o->v.string==NULL)
|
||||||
|
{
|
||||||
|
CWMP_LOG(INFO, "%s not found or empty value",cmd);
|
||||||
|
uci_free_context(c);
|
||||||
|
return CWMP_OK;
|
||||||
|
}
|
||||||
|
*value = strdup(ptr.o->v.string);
|
||||||
|
}
|
||||||
|
uci_free_context(c);
|
||||||
|
return CWMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_get_state_value(char *cmd,char **value)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
error = uci_get_value_common (cmd,value,true);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_get_value(char *cmd,char **value)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
error = uci_get_value_common (cmd,value,false);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uci_action_value_common(char *cmd, uci_config_action action)
|
||||||
|
{
|
||||||
|
int ret = UCI_OK;
|
||||||
|
char *s,*t;
|
||||||
|
struct uci_context *c = uci_alloc_context();
|
||||||
|
struct uci_ptr ptr;
|
||||||
|
char state_path[32];
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
{
|
||||||
|
CWMP_LOG(ERROR, "Out of memory");
|
||||||
|
return CWMP_GEN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == CWMP_CMD_SET_STATE)
|
||||||
|
{
|
||||||
|
strcpy(state_path,VARSTATE_CONFIG);
|
||||||
|
uci_add_delta_path(c, c->savedir);
|
||||||
|
uci_set_savedir(c, state_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = strdup(cmd);
|
||||||
|
t = s;
|
||||||
|
|
||||||
|
if (uci_lookup_ptr(c, &ptr, s, true) != UCI_OK)
|
||||||
|
{
|
||||||
|
free(t);
|
||||||
|
uci_free_context(c);
|
||||||
|
return CWMP_GEN_ERR;
|
||||||
|
}
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case CWMP_CMD_SET:
|
||||||
|
case CWMP_CMD_SET_STATE:
|
||||||
|
ret = uci_set(c, &ptr);
|
||||||
|
break;
|
||||||
|
case CWMP_CMD_DEL:
|
||||||
|
ret = uci_delete(c, &ptr);
|
||||||
|
break;
|
||||||
|
case CWMP_CMD_ADD_LIST:
|
||||||
|
ret = uci_add_list(c, &ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret == UCI_OK)
|
||||||
|
{
|
||||||
|
ret = uci_save(c, ptr.p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CWMP_LOG(ERROR, "UCI %s %s not succeed %s",action==CWMP_CMD_SET_STATE?"state":"config",action==CWMP_CMD_DEL?"delete":"set",cmd);
|
||||||
|
}
|
||||||
|
free(t);
|
||||||
|
uci_free_context(c);
|
||||||
|
return CWMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_delete_value(char *cmd)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
error = uci_action_value_common (cmd,CWMP_CMD_DEL);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_set_value(char *cmd)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
error = uci_action_value_common (cmd,CWMP_CMD_SET);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_set_state_value(char *cmd)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
error = uci_action_value_common (cmd,CWMP_CMD_SET_STATE);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_add_list_value(char *cmd)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
error = uci_action_value_common (cmd,CWMP_CMD_ADD_LIST);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cwmp_uci_list_insert(struct uci_list *list, struct uci_list *ptr)
|
||||||
|
{
|
||||||
|
list->next->prev = ptr;
|
||||||
|
ptr->prev = list;
|
||||||
|
ptr->next = list->next;
|
||||||
|
list->next = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cwmp_uci_list_add(struct uci_list *head, struct uci_list *ptr)
|
||||||
|
{
|
||||||
|
cwmp_uci_list_insert(head->prev, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *cwmp_uci_list_to_string(struct uci_list *list, char *delimitor)
|
||||||
|
{
|
||||||
|
struct uci_element *e = NULL;
|
||||||
|
char val[512] = {0};
|
||||||
|
int del_len = strlen(delimitor);
|
||||||
|
|
||||||
|
if (list) {
|
||||||
|
uci_foreach_element(list, e) {
|
||||||
|
int len = strlen(val);
|
||||||
|
if (len != 0) {
|
||||||
|
memcpy(val + len, delimitor, del_len);
|
||||||
|
strcpy(val + len + del_len, e->name);
|
||||||
|
} else
|
||||||
|
strcpy(val, e->name);
|
||||||
|
}
|
||||||
|
return (strdup(val));
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cwmp_uci_get_value_by_section_string(struct uci_section *s, char *option, char **value)
|
||||||
|
{
|
||||||
|
struct uci_element *e;
|
||||||
|
struct uci_option *o;
|
||||||
|
|
||||||
|
if (s == NULL || option == NULL)
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
|
uci_foreach_element(&s->options, e) {
|
||||||
|
o = (uci_to_option(e));
|
||||||
|
if (!strcmp(o->e.name, option)) {
|
||||||
|
if (o->type == UCI_TYPE_LIST) {
|
||||||
|
*value = cwmp_uci_list_to_string(&o->v.list, " ");
|
||||||
|
} else {
|
||||||
|
*value = o->v.string ? strdup(o->v.string) : "";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
*value = "";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void uci_list_init(struct uci_list *ptr)
|
||||||
|
{
|
||||||
|
ptr->prev = ptr;
|
||||||
|
ptr->next = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cwmp_uci_get_value_by_section_list(struct uci_section *s, char *option, struct uci_list **value)
|
||||||
|
{
|
||||||
|
struct uci_element *e;
|
||||||
|
struct uci_option *o;
|
||||||
|
struct uci_list *list;
|
||||||
|
char *pch = NULL, *spch = NULL, *dup;
|
||||||
|
|
||||||
|
*value = NULL;
|
||||||
|
|
||||||
|
if (s == NULL || option == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uci_foreach_element(&s->options, e) {
|
||||||
|
o = (uci_to_option(e));
|
||||||
|
if (strcmp(o->e.name, option) == 0) {
|
||||||
|
switch(o->type) {
|
||||||
|
case UCI_TYPE_LIST:
|
||||||
|
*value = &o->v.list;
|
||||||
|
return 0;
|
||||||
|
case UCI_TYPE_STRING:
|
||||||
|
if (!o->v.string || (o->v.string)[0] == '\0')
|
||||||
|
return 0;
|
||||||
|
list = calloc(1, sizeof(struct uci_list));
|
||||||
|
uci_list_init(list);
|
||||||
|
dup = strdup(o->v.string);
|
||||||
|
pch = strtok_r(dup, " ", &spch);
|
||||||
|
while (pch != NULL) {
|
||||||
|
e = calloc(1, sizeof(struct uci_element));
|
||||||
|
e->name = pch;
|
||||||
|
cwmp_uci_list_add(list, &e->list);
|
||||||
|
pch = strtok_r(NULL, " ", &spch);
|
||||||
|
}
|
||||||
|
*value = list;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
struct uci_section *cwmp_uci_walk_section (char *package, char *stype, void *arg1, void *arg2, int cmp , int (*filter)(struct uci_section *s, void *value), struct uci_section *prev_section, int walk)
|
||||||
|
{
|
||||||
|
struct uci_section *s = NULL;
|
||||||
|
struct uci_element *e, *m;
|
||||||
|
char *value, *dup, *pch, *spch;
|
||||||
|
struct uci_list *list_value, *list_section;
|
||||||
|
struct uci_ptr ptr = {0};
|
||||||
|
|
||||||
|
if (walk == CWMP_GET_FIRST_SECTION) {
|
||||||
|
if (cwmp_uci_lookup_ptr(cwmp_uci_ctx, &ptr, package, NULL, NULL, NULL) != UCI_OK)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
list_section = &(ptr.p)->sections;
|
||||||
|
e = list_to_element(list_section->next);
|
||||||
|
} else {
|
||||||
|
list_section = &prev_section->package->sections;
|
||||||
|
e = list_to_element(prev_section->e.list.next);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(&e->list != list_section) {
|
||||||
|
s = uci_to_section(e);
|
||||||
|
if (strcmp(s->type, stype) == 0) {
|
||||||
|
switch(cmp) {
|
||||||
|
case CWMP_CMP_SECTION:
|
||||||
|
goto end;
|
||||||
|
case CWMP_CMP_OPTION_EQUAL:
|
||||||
|
cwmp_uci_get_value_by_section_string(s, (char *)arg1, &value);
|
||||||
|
if (strcmp(value, (char *)arg2) == 0)
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
case CWMP_CMP_OPTION_CONTAINING:
|
||||||
|
cwmp_uci_get_value_by_section_string(s, (char *)arg1, &value);
|
||||||
|
if (strstr(value, (char *)arg2))
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
case CWMP_CMP_OPTION_CONT_WORD:
|
||||||
|
cwmp_uci_get_value_by_section_string(s, (char *)arg1, &value);
|
||||||
|
dup = strdup(value);
|
||||||
|
pch = strtok_r(dup, " ", &spch);
|
||||||
|
while (pch != NULL) {
|
||||||
|
if (strcmp((char *)arg2, pch) == 0) {
|
||||||
|
FREE(dup);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
pch = strtok_r(NULL, " ", &spch);
|
||||||
|
}
|
||||||
|
FREE(dup);
|
||||||
|
break;
|
||||||
|
case CWMP_CMP_LIST_CONTAINING:
|
||||||
|
cwmp_uci_get_value_by_section_list(s, (char *)arg1, &list_value);
|
||||||
|
if (list_value != NULL) {
|
||||||
|
uci_foreach_element(list_value, m) {
|
||||||
|
if (strcmp(m->name, (char *)arg2) == 0)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CWMP_CMP_FILTER_FUNC:
|
||||||
|
if (filter(s, arg1) == 0)
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e = list_to_element(e->list.next);
|
||||||
|
s = NULL;
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
FREE(value);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,13 @@
|
||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2020 iopsys Software Solutions AB
|
||||||
|
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||||
|
*/
|
||||||
|
|
||||||
#include "datamodel_interface.h"
|
#include "datamodel_interface.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
bool transaction_started = false;
|
bool transaction_started = false;
|
||||||
|
|
@ -268,8 +278,8 @@ char* cwmp_set_parameter_attributes(char* parameter_name, char* notification)
|
||||||
/*
|
/*
|
||||||
* Init Notify Function
|
* Init Notify Function
|
||||||
*/
|
*/
|
||||||
int cwmp_update_enabled_notify_file(unsigned int amd_version, int instance_mode)
|
int cwmp_update_enabled_notify_file(int instance_mode)
|
||||||
{
|
{
|
||||||
int e = cwmp_ubus_call("usp.raw", "init_notify", CWMP_UBUS_ARGS{{"instance_mode", {.int_val=instance_mode}, UBUS_Integer}, {"amd_version", {.int_val=amd_version}, UBUS_Integer}}, 2, NULL);
|
int e = cwmp_ubus_call("usp.raw", "list_notify", CWMP_UBUS_ARGS{{"instance_mode", {.int_val=instance_mode}, UBUS_Integer}}, 1, NULL);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
event.c
5
event.c
|
|
@ -4,9 +4,10 @@
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2019 iopsys Software Solutions AB
|
* Copyright (C) 2013-2020 iopsys Software Solutions AB
|
||||||
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
||||||
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
||||||
|
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -657,7 +658,7 @@ void *thread_periodic_check_notify (void *v)
|
||||||
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
pthread_mutex_lock(&(cwmp->mutex_session_send));
|
||||||
is_notify = check_value_change();
|
is_notify = check_value_change();
|
||||||
if (is_notify > 0)
|
if (is_notify > 0)
|
||||||
cwmp_update_enabled_notify_file(cwmp->conf.amd_version, cwmp->conf.instance_mode);
|
cwmp_update_enabled_notify_file(cwmp->conf.instance_mode);
|
||||||
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
pthread_mutex_unlock(&(cwmp->mutex_session_send));
|
||||||
if (is_notify & NOTIF_ACTIVE)
|
if (is_notify & NOTIF_ACTIVE)
|
||||||
send_active_value_change();
|
send_active_value_change();
|
||||||
|
|
|
||||||
3
http.c
3
http.c
|
|
@ -7,7 +7,8 @@
|
||||||
* Copyright (C) 2013-2019 iopsys Software Solutions AB
|
* Copyright (C) 2013-2019 iopsys Software Solutions AB
|
||||||
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
||||||
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
||||||
* Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
|
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||||
|
* Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
||||||
14
inc/common.h
Normal file
14
inc/common.h
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef __COMMON_H
|
||||||
|
#define __COMMON_H
|
||||||
|
|
||||||
|
enum cwmp_ret_err {
|
||||||
|
CWMP_OK, /* No Error */
|
||||||
|
CWMP_GEN_ERR, /* General Error */
|
||||||
|
CWMP_MEM_ERR, /* Memory Error */
|
||||||
|
CWMP_MUTEX_ERR,
|
||||||
|
CWMP_RETRY_SESSION
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef FREE
|
||||||
|
#define FREE(x) do { if (x) {free(x); x = NULL;} } while (0)
|
||||||
|
#endif
|
||||||
|
|
@ -15,13 +15,9 @@
|
||||||
|
|
||||||
extern pthread_mutex_t mutex_config_load;
|
extern pthread_mutex_t mutex_config_load;
|
||||||
|
|
||||||
int uci_get_state_value(char *cmd,char **value);
|
|
||||||
int uci_set_state_value(char *cmd);
|
|
||||||
int save_acs_bkp_config(struct cwmp *cwmp);
|
int save_acs_bkp_config(struct cwmp *cwmp);
|
||||||
int uci_get_value(char *cmd,char **value);
|
|
||||||
int get_amd_version_config();
|
int get_amd_version_config();
|
||||||
int get_instance_mode_config();
|
int get_instance_mode_config();
|
||||||
int get_session_timeout_config();
|
int get_session_timeout_config();
|
||||||
int uci_set_value(char *cmd);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
19
inc/cwmp.h
19
inc/cwmp.h
|
|
@ -29,6 +29,8 @@
|
||||||
#include <libbbfdm/dmdiagnostics.h>
|
#include <libbbfdm/dmdiagnostics.h>
|
||||||
extern unsigned int end_session_flag;
|
extern unsigned int end_session_flag;
|
||||||
#endif
|
#endif
|
||||||
|
#include "common.h"
|
||||||
|
#include "cwmp_uci.h"
|
||||||
|
|
||||||
#define MAX_EVENTS 64
|
#define MAX_EVENTS 64
|
||||||
#define MAX_INT32 2147483646
|
#define MAX_INT32 2147483646
|
||||||
|
|
@ -99,14 +101,6 @@ enum cwmp_start {
|
||||||
CWMP_START_PERIODIC = 2
|
CWMP_START_PERIODIC = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum cwmp_ret_err {
|
|
||||||
CWMP_OK, /* No Error */
|
|
||||||
CWMP_GEN_ERR, /* General Error */
|
|
||||||
CWMP_MEM_ERR, /* Memory Error */
|
|
||||||
CWMP_MUTEX_ERR,
|
|
||||||
CWMP_RETRY_SESSION
|
|
||||||
};
|
|
||||||
|
|
||||||
enum event_retry_after_enum {
|
enum event_retry_after_enum {
|
||||||
EVENT_RETRY_AFTER_TRANSMIT_FAIL = 0x1,
|
EVENT_RETRY_AFTER_TRANSMIT_FAIL = 0x1,
|
||||||
EVENT_RETRY_AFTER_REBOOT = 0x2,
|
EVENT_RETRY_AFTER_REBOOT = 0x2,
|
||||||
|
|
@ -225,11 +219,6 @@ typedef struct env {
|
||||||
long int max_firmware_size;
|
long int max_firmware_size;
|
||||||
} env;
|
} env;
|
||||||
|
|
||||||
typedef struct config_uci_list {
|
|
||||||
struct list_head list;
|
|
||||||
char *value;
|
|
||||||
} config_uci_list;
|
|
||||||
|
|
||||||
typedef struct session_status {
|
typedef struct session_status {
|
||||||
time_t last_start_time;
|
time_t last_start_time;
|
||||||
time_t last_end_time;
|
time_t last_end_time;
|
||||||
|
|
@ -309,9 +298,7 @@ typedef struct rpc {
|
||||||
extern int ip_version;
|
extern int ip_version;
|
||||||
extern char *commandKey;
|
extern char *commandKey;
|
||||||
#define ARRAYSIZEOF(a) (sizeof(a) / sizeof((a)[0]))
|
#define ARRAYSIZEOF(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
#ifndef FREE
|
|
||||||
#define FREE(x) do { if (x) {free(x); x = NULL;} } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern struct cwmp cwmp_main;
|
extern struct cwmp cwmp_main;
|
||||||
extern const struct EVENT_CONST_STRUCT EVENT_CONST [__EVENT_IDX_MAX];
|
extern const struct EVENT_CONST_STRUCT EVENT_CONST [__EVENT_IDX_MAX];
|
||||||
|
|
|
||||||
83
inc/cwmp_uci.h
Normal file
83
inc/cwmp_uci.h
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
#ifndef __CWMPUCI_H
|
||||||
|
#define __CWMPUCI_H
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <uci.h>
|
||||||
|
#include <libubox/list.h>
|
||||||
|
#include "common.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
//struct uci_context *cwmp_uci_ctx = ((void *)0);
|
||||||
|
#define UCI_CONFIG_DIR "/etc/config/"
|
||||||
|
#define LIB_DB_CONFIG "/lib/db/config"
|
||||||
|
#define ETC_DB_CONFIG "/etc/board-db/config"
|
||||||
|
#define VARSTATE_CONFIG "/var/state"
|
||||||
|
#define BBFDM_CONFIG "/etc/bbfdm"
|
||||||
|
#define BBFDM_SAVEDIR "/tmp/.bbfdm"
|
||||||
|
|
||||||
|
typedef enum uci_config_action {
|
||||||
|
CWMP_CMD_SET,
|
||||||
|
CWMP_CMD_SET_STATE,
|
||||||
|
CWMP_CMD_ADD_LIST,
|
||||||
|
CWMP_CMD_DEL,
|
||||||
|
} uci_config_action;
|
||||||
|
|
||||||
|
enum uci_paths_types {
|
||||||
|
UCI_STANDARD_CONFIG,
|
||||||
|
UCI_DB_CONFIG,
|
||||||
|
UCI_BOARD_DB_CONFIG,
|
||||||
|
UCI_VARSTATE_CONFIG,
|
||||||
|
UCI_BBFDM_CONFIG
|
||||||
|
};
|
||||||
|
|
||||||
|
enum cwmp_uci_cmp {
|
||||||
|
CWMP_CMP_SECTION,
|
||||||
|
CWMP_CMP_OPTION_EQUAL,
|
||||||
|
CWMP_CMP_OPTION_REGEX,
|
||||||
|
CWMP_CMP_OPTION_CONTAINING,
|
||||||
|
CWMP_CMP_OPTION_CONT_WORD,
|
||||||
|
CWMP_CMP_LIST_CONTAINING,
|
||||||
|
CWMP_CMP_FILTER_FUNC
|
||||||
|
};
|
||||||
|
|
||||||
|
enum cwmp_uci_walk {
|
||||||
|
CWMP_GET_FIRST_SECTION,
|
||||||
|
CWMP_GET_NEXT_SECTION
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct config_uci_list {
|
||||||
|
struct list_head list;
|
||||||
|
char *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct uci_paths {
|
||||||
|
char *conf_dir;
|
||||||
|
char *save_dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int cwmp_uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value);
|
||||||
|
int cwmp_uci_get_option_value_list(char *package, char *section, char *option, struct list_head *list);
|
||||||
|
int uci_get_state_value(char *cmd,char **value);
|
||||||
|
int uci_set_state_value(char *cmd);
|
||||||
|
int uci_set_value(char *cmd);
|
||||||
|
int uci_get_value(char *cmd,char **value);
|
||||||
|
char* cwmp_db_get_value_string(char *package, char *section, char *option);
|
||||||
|
struct uci_section *cwmp_uci_walk_section (char *package, char *stype, void *arg1, void *arg2, int cmp , int (*filter)(struct uci_section *s, void *value), struct uci_section *prev_section, int walk);
|
||||||
|
|
||||||
|
#define cwmp_uci_path_foreach_option_eq(package, stype, option, val, section) \
|
||||||
|
for (section = cwmp_uci_walk_section(package, stype, option, val, CWMP_CMP_OPTION_EQUAL, NULL, NULL, CWMP_GET_FIRST_SECTION); \
|
||||||
|
section != NULL; \
|
||||||
|
section = cwmp_uci_walk_section(package, stype, option, val, CWMP_CMP_OPTION_EQUAL, NULL, section, CWMP_GET_NEXT_SECTION))
|
||||||
|
|
||||||
|
#define cwmp_uci_path_foreach_sections(package, stype, section) \
|
||||||
|
for (section = cwmp_uci_walk_section(package, stype, NULL, NULL, CMP_SECTION, NULL, NULL, GET_FIRST_SECTION); \
|
||||||
|
section != NULL; \
|
||||||
|
section = cwmp_uci_walk_section(package, stype, NULL, NULL, CMP_SECTION, NULL, section, GET_NEXT_SECTION))
|
||||||
|
#endif
|
||||||
|
|
@ -20,6 +20,6 @@ char* cwmp_delete_object(char* object_name, char* key);
|
||||||
char* cwmp_get_parameter_names(char* object_name, bool next_level, json_object **parameters);
|
char* cwmp_get_parameter_names(char* object_name, bool next_level, json_object **parameters);
|
||||||
char* cwmp_get_parameter_attributes(char* parameter_name, json_object **parameters);
|
char* cwmp_get_parameter_attributes(char* parameter_name, json_object **parameters);
|
||||||
char* cwmp_set_parameter_attributes(char* parameter_name, char* notification);
|
char* cwmp_set_parameter_attributes(char* parameter_name, char* notification);
|
||||||
int cwmp_update_enabled_notify_file(unsigned int amd_version, int instance_mode);
|
int cwmp_update_enabled_notify_file(int instance_mode);
|
||||||
|
|
||||||
#endif /* SRC_DATAMODELIFACE_H_ */
|
#endif /* SRC_DATAMODELIFACE_H_ */
|
||||||
|
|
|
||||||
9
xml.c
9
xml.c
|
|
@ -4,11 +4,12 @@
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2019 iopsys Software Solutions AB
|
* Copyright (C) 2013-2020 iopsys Software Solutions AB
|
||||||
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
* Author Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
||||||
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
* Author Ahmed Zribi <ahmed.zribi@pivasoftware.com>
|
||||||
* Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
|
* Author Omar Kallel <omar.kallel@pivasoftware.com>
|
||||||
* Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
|
* Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
|
||||||
|
* Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
@ -4595,7 +4596,7 @@ int cwmp_handle_rpc_cpe_fault(struct session *session, struct rpc *rpc)
|
||||||
|
|
||||||
if (rpc->type == RPC_CPE_SET_PARAMETER_VALUES) {
|
if (rpc->type == RPC_CPE_SET_PARAMETER_VALUES) {
|
||||||
while (rpc->list_set_value_fault->next != rpc->list_set_value_fault) {
|
while (rpc->list_set_value_fault->next != rpc->list_set_value_fault) {
|
||||||
param_fault = list_entry(rpc->list_set_value_fault->next, struct param_fault, list);
|
param_fault = list_entry(rpc->list_set_value_fault->next, struct cwmp_param_fault, list);
|
||||||
|
|
||||||
if (param_fault->fault)
|
if (param_fault->fault)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue