Add uci api & fix other issues

This commit is contained in:
Omar Kallel 2020-12-09 19:03:00 +01:00
parent 22beb8fb06
commit f1560b1305
13 changed files with 683 additions and 423 deletions

View file

@ -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
View file

@ -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
View file

@ -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
View 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;
}

View file

@ -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;
} }

View file

@ -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
View file

@ -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
View 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

View file

@ -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

View file

@ -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
View 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

View file

@ -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
View file

@ -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)
{ {