Serialize uci usages

This commit is contained in:
Vivek Kumar Dutta 2023-12-26 08:05:13 +00:00
parent a1df16afca
commit cf89728b92
31 changed files with 1189 additions and 1663 deletions

2
.gitignore vendored
View file

@ -44,3 +44,5 @@ cmake_install.cmake
install_manifest.txt install_manifest.txt
/report /report
docs/index.md docs/index.md
/src/icwmpd
/build

View file

@ -1019,7 +1019,8 @@ static int set_inform_parameter_parameter_name(char *refparam, struct dmctx *ctx
static int get_inform_parameter_event_list(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) static int get_inform_parameter_event_list(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{ {
struct dmmap_dup *inform_param_args = (struct dmmap_dup *)data; struct dmmap_dup *inform_param_args = (struct dmmap_dup *)data;
dmuci_get_value_by_section_string(inform_param_args->config_section, "events_list", value); return 0; dmuci_get_value_by_section_string(inform_param_args->config_section, "events_list", value);
return 0;
} }
static int set_inform_parameter_event_list(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) static int set_inform_parameter_event_list(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)

View file

@ -11,7 +11,6 @@
*/ */
#include "autonomous_complpolicy.h" #include "autonomous_complpolicy.h"
#include "cwmp_uci.h"
#include "cwmp_du_state.h" #include "cwmp_du_state.h"
#include "log.h" #include "log.h"
#include <libubox/blobmsg_json.h> #include <libubox/blobmsg_json.h>

View file

@ -22,7 +22,7 @@
#include "common.h" #include "common.h"
#include "cwmp_cli.h" #include "cwmp_cli.h"
#include "cwmp_uci.h" #include "uci_utils.h"
#include "ubus_utils.h" #include "ubus_utils.h"
#include "log.h" #include "log.h"
@ -241,12 +241,6 @@ size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
return written; return written;
} }
int get_firewall_restart_state(char **state)
{
cwmp_uci_reinit();
return uci_get_state_value("icwmp.cpe.firewall_restart", state);
}
// wait till firewall restart is not complete or 5 sec, whichever is less // wait till firewall restart is not complete or 5 sec, whichever is less
void check_firewall_restart_state() void check_firewall_restart_state()
{ {
@ -254,19 +248,15 @@ void check_firewall_restart_state()
bool init = false; bool init = false;
do { do {
char *state = NULL; char state[BUF_SIZE_32] = {0};
if (get_firewall_restart_state(&state) != CWMP_OK)
break;
get_uci_path_value(VARSTATE_CONFIG, "icwmp.cpe.firewall_restart", state, BUF_SIZE_32);
if (CWMP_STRCMP(state, "init") == 0) { if (CWMP_STRCMP(state, "init") == 0) {
init = true; init = true;
FREE(state);
break; break;
} }
sleep(1); sleep(1);
FREE(state);
count++; count++;
} while(count < 10); } while(count < 10);
@ -274,15 +264,13 @@ void check_firewall_restart_state()
g_firewall_restart = false; g_firewall_restart = false;
if (init == false) { // In case of timeout reset the firewall_restart flag if (init == false) { // In case of timeout reset the firewall_restart flag
CWMP_LOG(ERROR, "Firewall restart took longer than usual"); CWMP_LOG(ERROR, "Firewall restart took longer than usual");
cwmp_uci_set_varstate_value("icwmp", "cpe", "firewall_restart", "init"); set_uci_path_value(VARSTATE_CONFIG, "icwmp.cpe.firewall_restart", "init");
cwmp_commit_package("icwmp", UCI_VARSTATE_CONFIG);
} }
} }
void set_rpc_parameter_key(char *param_key) void set_rpc_parameter_key(char *param_key)
{ {
cwmp_uci_set_value("cwmp", "cpe", "ParameterKey", param_key ? param_key : ""); set_uci_path_value(NULL, "cwmp.cpe.ParameterKey", param_key ? param_key : "");
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
} }
/* /*
@ -613,8 +601,7 @@ void icwmp_restart_services()
} }
if (g_firewall_restart) { if (g_firewall_restart) {
CWMP_LOG(INFO, "Initiating Firewall restart"); CWMP_LOG(INFO, "Initiating Firewall restart");
cwmp_uci_set_varstate_value("icwmp", "cpe", "firewall_restart", "in_progress"); set_uci_path_value(VARSTATE_CONFIG, "icwmp.cpe.firewall_restart", "in_progress");
cwmp_commit_package("icwmp", UCI_VARSTATE_CONFIG);
} }
icwmp_free_list_services(); icwmp_free_list_services();
sleep(5); // wait for services to get restarted sleep(5); // wait for services to get restarted
@ -864,7 +851,7 @@ time_t convert_datetime_to_timestamp(char *value)
return mktime(&tm); return mktime(&tm);
} }
bool uci_str_to_bool(char *value) bool str_to_bool(char *value)
{ {
if (!value) if (!value)
return false; return false;

View file

@ -74,7 +74,6 @@
#define ICWMP_TMP_PATH "/tmp/icwmp" #define ICWMP_TMP_PATH "/tmp/icwmp"
#define FIREWALL_CWMP "/etc/firewall.cwmp" #define FIREWALL_CWMP "/etc/firewall.cwmp"
#define CWMP_VARSTATE_UCI_PACKAGE "/var/state/icwmp"
#define DM_PPP_INTERFACE_PATH "Device\\.PPP\\.Interface\\." #define DM_PPP_INTERFACE_PATH "Device\\.PPP\\.Interface\\."
#define DM_IP_INTERFACE_PATH "Device\\.IP\\.Interface\\." #define DM_IP_INTERFACE_PATH "Device\\.IP\\.Interface\\."
#define DEFAULT_CR_TIMEOUT 5 /* In Seconds */ #define DEFAULT_CR_TIMEOUT 5 /* In Seconds */
@ -656,7 +655,7 @@ bool is_reload_parameter(const char *object_name);
time_t convert_datetime_to_timestamp(char *value); time_t convert_datetime_to_timestamp(char *value);
int run_session_end_func(void); int run_session_end_func(void);
void set_interface_reset_request(char *param_name, char *value); void set_interface_reset_request(char *param_name, char *value);
bool uci_str_to_bool(char *value); bool str_to_bool(char *value);
bool match_reg_exp(char *reg_exp, char *param_name); bool match_reg_exp(char *reg_exp, char *param_name);
void cwmp_invoke_intf_reset(char *path); void cwmp_invoke_intf_reset(char *path);
void check_firewall_restart_state(); void check_firewall_restart_state();

View file

@ -19,25 +19,13 @@
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
#include "reboot.h" #include "reboot.h"
#include "uci_utils.h"
#include "ubus_utils.h" #include "ubus_utils.h"
#include "ssl_utils.h" #include "ssl_utils.h"
#include "datamodel_interface.h" #include "datamodel_interface.h"
#include "heartbeat.h" #include "heartbeat.h"
#include "cwmp_http.h" #include "cwmp_http.h"
pthread_mutex_t mutex_config_load = PTHREAD_MUTEX_INITIALIZER;
static char *get_value_from_uci_option(struct uci_option *tb)
{
if (tb == NULL)
return "";
if (tb->type == UCI_TYPE_STRING)
return tb->v.string;
return "";
}
static void set_cr_incoming_rule(const char *rule) static void set_cr_incoming_rule(const char *rule)
{ {
if (CWMP_LSTRCASECMP(rule, "ip_only") == 0) { if (CWMP_LSTRCASECMP(rule, "ip_only") == 0) {
@ -49,480 +37,45 @@ static void set_cr_incoming_rule(const char *rule)
} }
} }
static void config_get_cpe_elements(struct uci_section *s)
{
enum {
UCI_CPE_CON_REQ_TIMEOUT,
UCI_CPE_USER_ID,
UCI_CPE_PASSWD,
UCI_CPE_PORT,
UCI_CPE_CRPATH,
UCI_CPE_NOTIFY_PERIODIC_ENABLE,
UCI_CPE_NOTIFY_PERIOD,
UCI_CPE_SCHEDULE_REBOOT,
UCI_CPE_DELAY_REBOOT,
UCI_CPE_ACTIVE_NOTIF_THROTTLE,
UCI_CPE_MANAGEABLE_DEVICES_NOTIF_LIMIT,
UCI_CPE_SESSION_TIMEOUT,
UCI_CPE_INSTANCE_MODE,
UCI_CPE_JSON_CUSTOM_NOTIFY_FILE,
UCI_CPE_JSON_FORCED_INFORM_FILE,
UCI_CPE_FORCE_IPV4,
UCI_CPE_KEEP_SETTINGS,
__MAX_NUM_UCI_CPE_ATTRS,
};
const struct uci_parse_option cpe_opts[] = {
[UCI_CPE_USER_ID] = { .name = "userid", .type = UCI_TYPE_STRING },
[UCI_CPE_PASSWD] = { .name = "passwd", .type = UCI_TYPE_STRING },
[UCI_CPE_PORT] = { .name = "port", .type = UCI_TYPE_STRING },
[UCI_CPE_CRPATH] = { .name = "path", .type = UCI_TYPE_STRING },
[UCI_CPE_NOTIFY_PERIODIC_ENABLE] = { .name = "periodic_notify_enable", .type = UCI_TYPE_STRING },
[UCI_CPE_NOTIFY_PERIOD] = { .name = "periodic_notify_interval", .type = UCI_TYPE_STRING },
[UCI_CPE_SCHEDULE_REBOOT] = { .name = "schedule_reboot", .type = UCI_TYPE_STRING },
[UCI_CPE_DELAY_REBOOT] = { .name = "delay_reboot", .type = UCI_TYPE_STRING },
[UCI_CPE_ACTIVE_NOTIF_THROTTLE] = { .name = "active_notif_throttle", .type = UCI_TYPE_STRING },
[UCI_CPE_MANAGEABLE_DEVICES_NOTIF_LIMIT] = { .name = "md_notif_limit", .type = UCI_TYPE_STRING },
[UCI_CPE_SESSION_TIMEOUT] = { .name = "session_timeout", .type = UCI_TYPE_STRING },
[UCI_CPE_INSTANCE_MODE] = { .name = "instance_mode", .type = UCI_TYPE_STRING },
[UCI_CPE_JSON_CUSTOM_NOTIFY_FILE] = { .name = "custom_notify_json", .type = UCI_TYPE_STRING },
[UCI_CPE_JSON_FORCED_INFORM_FILE] = { .name = "forced_inform_json", .type = UCI_TYPE_STRING },
[UCI_CPE_CON_REQ_TIMEOUT] = { .name = "cr_timeout", .type = UCI_TYPE_STRING },
[UCI_CPE_FORCE_IPV4] = { .name = "force_ipv4", .type = UCI_TYPE_STRING },
[UCI_CPE_KEEP_SETTINGS] = { .name = "fw_upgrade_keep_settings", .type = UCI_TYPE_STRING }
};
struct uci_option *cpe_tb[__MAX_NUM_UCI_CPE_ATTRS];
CWMP_MEMSET(cpe_tb, 0, sizeof(cpe_tb));
uci_parse_section(s, cpe_opts, __MAX_NUM_UCI_CPE_ATTRS, cpe_tb);
snprintf(cwmp_main->conf.cpe_userid, sizeof(cwmp_main->conf.cpe_userid), "%s", get_value_from_uci_option(cpe_tb[UCI_CPE_USER_ID]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe username: %s", cwmp_main->conf.cpe_userid);
snprintf(cwmp_main->conf.cpe_passwd, sizeof(cwmp_main->conf.cpe_passwd), "%s", get_value_from_uci_option(cpe_tb[UCI_CPE_PASSWD]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe password: %s", cwmp_main->conf.cpe_passwd);
cwmp_main->conf.cr_timeout = DEFAULT_CR_TIMEOUT;
char *tm_out = get_value_from_uci_option(cpe_tb[UCI_CPE_CON_REQ_TIMEOUT]);
if (strlen(tm_out) != 0) {
int a = strtod(tm_out, NULL);
if (a > 0) {
cwmp_main->conf.cr_timeout = a;
}
}
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe connection request timeout: %d", cwmp_main->conf.cr_timeout);
cwmp_main->conf.connection_request_port = DEFAULT_CONNECTION_REQUEST_PORT;
char *port = get_value_from_uci_option(cpe_tb[UCI_CPE_PORT]);
if (strlen(port) != 0) {
int a = atoi(port);
cwmp_main->conf.connection_request_port = (a != 0) ? a : DEFAULT_CONNECTION_REQUEST_PORT;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe connection request port: %d", cwmp_main->conf.connection_request_port);
char *crpath = get_value_from_uci_option(cpe_tb[UCI_CPE_CRPATH]);
snprintf(cwmp_main->conf.connection_request_path, sizeof(cwmp_main->conf.connection_request_path), "%s", strlen(crpath) ? (*crpath == '/') ? crpath + 1 : crpath : "/");
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe connection request path: %s", cwmp_main->conf.connection_request_path);
cwmp_main->conf.periodic_notify_enable = uci_str_to_bool(get_value_from_uci_option(cpe_tb[UCI_CPE_NOTIFY_PERIODIC_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe periodic notify enable: %d", cwmp_main->conf.periodic_notify_enable);
cwmp_main->conf.periodic_notify_interval = DEFAULT_NOTIFY_PERIOD;
char *notify_period = get_value_from_uci_option(cpe_tb[UCI_CPE_NOTIFY_PERIOD]);
if (strlen(notify_period) != 0) {
int a = atoi(notify_period);
cwmp_main->conf.periodic_notify_interval = (a != 0) ? a : DEFAULT_NOTIFY_PERIOD;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe periodic notify interval: %d", cwmp_main->conf.periodic_notify_interval);
cwmp_main->conf.schedule_reboot = 0;
char *schedule_reboot = get_value_from_uci_option(cpe_tb[UCI_CPE_SCHEDULE_REBOOT]);
if (strlen(schedule_reboot) != 0) {
cwmp_main->conf.schedule_reboot = convert_datetime_to_timestamp(schedule_reboot);
}
cwmp_main->conf.delay_reboot = -1;
char *delay_reboot = get_value_from_uci_option(cpe_tb[UCI_CPE_DELAY_REBOOT]);
if (strlen(delay_reboot) != 0) {
int a = atoi(delay_reboot);
cwmp_main->conf.delay_reboot = (a > 0) ? a : -1;
}
cwmp_main->conf.active_notif_throttle = 0;
char *notify_thottle = get_value_from_uci_option(cpe_tb[UCI_CPE_ACTIVE_NOTIF_THROTTLE]);
if (strlen(notify_thottle) != 0) {
int a = atoi(notify_thottle);
cwmp_main->conf.active_notif_throttle = (a > 0) ? a : 0;
}
cwmp_main->conf.md_notif_limit = 0;
char *notify_limit = get_value_from_uci_option(cpe_tb[UCI_CPE_MANAGEABLE_DEVICES_NOTIF_LIMIT]);
if (strlen(notify_limit) != 0) {
int a = atoi(notify_limit);
cwmp_main->conf.md_notif_limit = (a > 0) ? a : 0;
}
cwmp_main->conf.session_timeout = DEFAULT_SESSION_TIMEOUT;
char *session_timeout = get_value_from_uci_option(cpe_tb[UCI_CPE_SESSION_TIMEOUT]);
if (strlen(session_timeout) != 0) {
int a = atoi(session_timeout);
cwmp_main->conf.session_timeout = (a >= 1) ? a : DEFAULT_SESSION_TIMEOUT;
}
cwmp_main->conf.instance_mode = DEFAULT_INSTANCE_MODE;
char *instance_mode = get_value_from_uci_option(cpe_tb[UCI_CPE_INSTANCE_MODE]);
if (strlen(instance_mode) != 0) {
if (CWMP_STRCMP(instance_mode, "InstanceNumber") == 0) {
cwmp_main->conf.instance_mode = INSTANCE_MODE_NUMBER;
} else {
cwmp_main->conf.instance_mode = INSTANCE_MODE_ALIAS;
}
}
snprintf(cwmp_main->conf.custom_notify_json, sizeof(cwmp_main->conf.custom_notify_json), "%s", get_value_from_uci_option(cpe_tb[UCI_CPE_JSON_CUSTOM_NOTIFY_FILE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe custom notify json path: %s", cwmp_main->conf.custom_notify_json);
snprintf(cwmp_main->conf.forced_inform_json, sizeof(cwmp_main->conf.forced_inform_json), "%s", get_value_from_uci_option(cpe_tb[UCI_CPE_JSON_FORCED_INFORM_FILE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe forced inform json path: %s", cwmp_main->conf.forced_inform_json);
cwmp_main->conf.force_ipv4 = uci_str_to_bool(get_value_from_uci_option(cpe_tb[UCI_CPE_FORCE_IPV4]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe force ipv4 enable: %d", cwmp_main->conf.force_ipv4);
cwmp_main->conf.fw_upgrade_keep_settings = cpe_tb[UCI_CPE_KEEP_SETTINGS] ? uci_str_to_bool(get_value_from_uci_option(cpe_tb[UCI_CPE_KEEP_SETTINGS])) : true;
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe keep settings enable: %d", cwmp_main->conf.fw_upgrade_keep_settings);
}
static void config_get_acs_elements(struct uci_section *s)
{
enum {
UCI_ACS_SSL_CAPATH,
UCI_ACS_HTTP_DISABLE_100CONTINUE,
UCI_ACS_INSECURE_ENABLE,
UCI_ACS_DHCP_DISCOVERY,
UCI_ACS_URL,
UCI_ACS_DHCP_URL,
UCI_ACS_USERID,
UCI_ACS_PASSWR,
UCI_ACS_RETRY_MIN_WAIT_INTERVAL,
UCI_ACS_DHCP_RETRY_MIN_WAIT_INTERVAL,
UCI_ACS_RETRY_INTERVAL_MULTIPLIER,
UCI_ACS_DHCP_RETRY_INTERVAL_MULTIPLIER,
UCI_ACS_COMPRESSION,
UCI_ACS_GETRPC,
UCI_ACS_PERIODIC_INFORM_TIME,
UCI_ACS_PERIODIC_INFORM_INTERVAL,
UCI_ACS_PERIODIC_INFORM_ENABLE,
UCI_ACS_HEARTBEAT_ENABLE,
UCI_ACS_HEARTBEAT_INTERVAL,
UCI_ACS_HEARTBEAT_TIME,
__MAX_NUM_UCI_ACS_ATTRS,
};
const struct uci_parse_option acs_opts[] = {
[UCI_ACS_SSL_CAPATH] = { .name = "ssl_capath", .type = UCI_TYPE_STRING },
[UCI_ACS_HTTP_DISABLE_100CONTINUE] = { .name = "http_disable_100continue", .type = UCI_TYPE_STRING },
[UCI_ACS_INSECURE_ENABLE] = { .name = "insecure_enable", .type = UCI_TYPE_STRING },
[UCI_ACS_DHCP_DISCOVERY] = { .name = "dhcp_discovery", .type = UCI_TYPE_STRING },
[UCI_ACS_URL] = { .name = "url", .type = UCI_TYPE_STRING },
[UCI_ACS_DHCP_URL] = { .name = "dhcp_url", .type = UCI_TYPE_STRING },
[UCI_ACS_USERID] = { .name = "userid", .type = UCI_TYPE_STRING },
[UCI_ACS_PASSWR] = { .name = "passwd", .type = UCI_TYPE_STRING },
[UCI_ACS_RETRY_MIN_WAIT_INTERVAL] = { .name = "retry_min_wait_interval", .type = UCI_TYPE_STRING },
[UCI_ACS_DHCP_RETRY_MIN_WAIT_INTERVAL] = { .name = "dhcp_retry_min_wait_interval", .type = UCI_TYPE_STRING },
[UCI_ACS_RETRY_INTERVAL_MULTIPLIER] = { .name = "retry_interval_multiplier", .type = UCI_TYPE_STRING },
[UCI_ACS_DHCP_RETRY_INTERVAL_MULTIPLIER] = { .name = "dhcp_retry_interval_multiplier", .type = UCI_TYPE_STRING },
[UCI_ACS_COMPRESSION] = { .name = "compression", .type = UCI_TYPE_STRING },
[UCI_ACS_GETRPC] = { .name = "get_rpc_methods", .type = UCI_TYPE_STRING },
[UCI_ACS_PERIODIC_INFORM_TIME] = { .name = "periodic_inform_time", .type = UCI_TYPE_STRING },
[UCI_ACS_PERIODIC_INFORM_INTERVAL] = { .name = "periodic_inform_interval", .type = UCI_TYPE_STRING },
[UCI_ACS_PERIODIC_INFORM_ENABLE] = { .name = "periodic_inform_enable", .type = UCI_TYPE_STRING },
[UCI_ACS_HEARTBEAT_ENABLE] = { .name = "heartbeat_enable", .type = UCI_TYPE_STRING },
[UCI_ACS_HEARTBEAT_INTERVAL] = { .name = "heartbeat_interval", .type = UCI_TYPE_STRING },
[UCI_ACS_HEARTBEAT_TIME] = { .name = "heartbeat_time", .type = UCI_TYPE_STRING },
};
struct uci_option *acs_tb[__MAX_NUM_UCI_ACS_ATTRS];
CWMP_MEMSET(acs_tb, 0, sizeof(acs_tb));
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_ACS_ATTRS, acs_tb);
cwmp_main->conf.http_disable_100continue = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_HTTP_DISABLE_100CONTINUE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs http disable 100continue: %d", cwmp_main->conf.http_disable_100continue);
cwmp_main->conf.insecure_enable = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_INSECURE_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs insecure enable: %d", cwmp_main->conf.insecure_enable);
cwmp_main->conf.dhcp_discovery = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_DHCP_DISCOVERY]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs dhcp discovery: %d", cwmp_main->conf.dhcp_discovery);
char *get_rpc = get_value_from_uci_option(acs_tb[UCI_ACS_GETRPC]);
cwmp_main->conf.acs_getrpc = CWMP_STRLEN(get_rpc) ? uci_str_to_bool(get_rpc) : true;
CWMP_LOG(DEBUG, "CWMP CONFIG - acs get rpc: %d", cwmp_main->conf.acs_getrpc);
char *url = get_value_from_uci_option(acs_tb[UCI_ACS_URL]);
char *dhcp_url = get_value_from_uci_option(acs_tb[UCI_ACS_DHCP_URL]);
snprintf(cwmp_main->conf.acs_url, sizeof(cwmp_main->conf.acs_url), "%s", cwmp_main->conf.dhcp_discovery ? (strlen(dhcp_url) ? dhcp_url : url) : url);
CWMP_LOG(DEBUG, "CWMP CONFIG - acs url: %s", cwmp_main->conf.acs_url);
snprintf(cwmp_main->conf.acs_userid, sizeof(cwmp_main->conf.acs_userid), "%s", get_value_from_uci_option(acs_tb[UCI_ACS_USERID]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs username: %s", cwmp_main->conf.acs_userid);
snprintf(cwmp_main->conf.acs_passwd, sizeof(cwmp_main->conf.acs_passwd), "%s", get_value_from_uci_option(acs_tb[UCI_ACS_PASSWR]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs password: %s", cwmp_main->conf.acs_passwd);
snprintf(cwmp_main->conf.acs_ssl_capath, sizeof(cwmp_main->conf.acs_ssl_capath), "%s", get_value_from_uci_option(acs_tb[UCI_ACS_SSL_CAPATH]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs ssl capath: %s", cwmp_main->conf.acs_ssl_capath);
cwmp_main->conf.retry_min_wait_interval = DEFAULT_RETRY_MINIMUM_WAIT_INTERVAL;
char *acs_retry_min_wait_interval = get_value_from_uci_option(acs_tb[UCI_ACS_RETRY_MIN_WAIT_INTERVAL]);
char *acs_dhcp_retry_min_wait_interval = get_value_from_uci_option(acs_tb[UCI_ACS_DHCP_RETRY_MIN_WAIT_INTERVAL]);
char *op_interval = cwmp_main->conf.dhcp_discovery ? acs_dhcp_retry_min_wait_interval : acs_retry_min_wait_interval;
if (strlen(op_interval) != 0) {
if (cwmp_main->conf.amd_version >= AMD_3) {
int a = atoi(op_interval);
cwmp_main->conf.retry_min_wait_interval = (a <= 65535 && a >= 1) ? a : DEFAULT_RETRY_MINIMUM_WAIT_INTERVAL;
}
}
CWMP_LOG(DEBUG, "CWMP CONFIG - acs retry minimum wait interval: %d", cwmp_main->conf.retry_min_wait_interval);
cwmp_main->conf.retry_interval_multiplier = DEFAULT_RETRY_INTERVAL_MULTIPLIER;
char *acs_retry_interval_multiplier = get_value_from_uci_option(acs_tb[UCI_ACS_RETRY_INTERVAL_MULTIPLIER]);
char *acs_dhcp_retry_interval_multiplier = get_value_from_uci_option(acs_tb[UCI_ACS_DHCP_RETRY_INTERVAL_MULTIPLIER]);
char *op_multi = cwmp_main->conf.dhcp_discovery ? acs_dhcp_retry_interval_multiplier : acs_retry_interval_multiplier;
if (strlen(op_multi) != 0) {
if (cwmp_main->conf.amd_version >= AMD_3) {
int a = atoi(op_multi);
cwmp_main->conf.retry_interval_multiplier = (a <= 65535 && a >= 1000) ? a : DEFAULT_RETRY_INTERVAL_MULTIPLIER;
}
}
CWMP_LOG(DEBUG, "CWMP CONFIG - acs retry interval multiplier: %d", cwmp_main->conf.retry_interval_multiplier);
cwmp_main->conf.compression = COMP_NONE;
char *acs_comp = get_value_from_uci_option(acs_tb[UCI_ACS_COMPRESSION]);
if (cwmp_main->conf.amd_version >= AMD_5 && strlen(acs_comp) != 0) {
if (strcasecmp(acs_comp, "gzip") == 0) {
cwmp_main->conf.compression = COMP_GZIP;
} else if (strcasecmp(acs_comp, "deflate") == 0) {
cwmp_main->conf.compression = COMP_DEFLATE;
} else {
cwmp_main->conf.compression = COMP_NONE;
}
}
cwmp_main->conf.time = 0;
char *time = get_value_from_uci_option(acs_tb[UCI_ACS_PERIODIC_INFORM_TIME]);
if (strlen(time) != 0) {
cwmp_main->conf.time = convert_datetime_to_timestamp(time);
}
cwmp_main->conf.period = PERIOD_INFORM_DEFAULT;
char *inform_interval = get_value_from_uci_option(acs_tb[UCI_ACS_PERIODIC_INFORM_INTERVAL]);
if (strlen(inform_interval) != 0) {
int a = atoi(inform_interval);
cwmp_main->conf.period = (a >= PERIOD_INFORM_MIN) ? a : PERIOD_INFORM_DEFAULT;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - acs periodic inform: %d", cwmp_main->conf.period);
cwmp_main->conf.periodic_enable = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_PERIODIC_INFORM_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs periodic enable: %d", cwmp_main->conf.periodic_enable);
cwmp_main->conf.heart_beat_enable = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_HEARTBEAT_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs heart beat enable: %d", cwmp_main->conf.heart_beat_enable);
cwmp_main->conf.heartbeat_interval = 30;
char *heartbeat_interval = get_value_from_uci_option(acs_tb[UCI_ACS_HEARTBEAT_INTERVAL]);
if (strlen(heartbeat_interval) != 0) {
int a = atoi(heartbeat_interval);
cwmp_main->conf.heartbeat_interval = a;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - acs heartbeat interval: %d", cwmp_main->conf.heartbeat_interval);
cwmp_main->conf.heart_time = 0;
char *heartbeat_time = get_value_from_uci_option(acs_tb[UCI_ACS_HEARTBEAT_TIME]);
if (strlen(heartbeat_time) != 0) {
cwmp_main->conf.heart_time = convert_datetime_to_timestamp(heartbeat_time);
}
}
static void config_get_lwn_elements(struct uci_section *s)
{
enum {
UCI_LWN_ENABLE,
UCI_LWN_HOSTNAME,
UCI_LWN_PORT,
__MAX_NUM_UCI_LWN_ATTRS,
};
const struct uci_parse_option acs_opts[] = {
[UCI_LWN_ENABLE] = { .name = "enable", .type = UCI_TYPE_STRING },
[UCI_LWN_HOSTNAME] = { .name = "hostname", .type = UCI_TYPE_STRING },
[UCI_LWN_PORT] = { .name = "port", .type = UCI_TYPE_STRING },
};
struct uci_option *lwn_tb[__MAX_NUM_UCI_LWN_ATTRS];
CWMP_MEMSET(lwn_tb, 0, sizeof(lwn_tb));
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_LWN_ATTRS, lwn_tb);
cwmp_main->conf.lwn_enable = uci_str_to_bool(get_value_from_uci_option(lwn_tb[UCI_LWN_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - lwn enable: %d", cwmp_main->conf.lwn_enable);
snprintf(cwmp_main->conf.lwn_hostname, sizeof(cwmp_main->conf.lwn_hostname), "%s", get_value_from_uci_option(lwn_tb[UCI_LWN_HOSTNAME]));
CWMP_LOG(DEBUG, "CWMP CONFIG - lwn hostname: %s", cwmp_main->conf.lwn_hostname);
cwmp_main->conf.lwn_port = DEFAULT_LWN_PORT;
char *port = get_value_from_uci_option(lwn_tb[UCI_LWN_PORT]);
if (strlen(port) != 0) {
int a = atoi(port);
cwmp_main->conf.lwn_port = a;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - lwn port: %d", cwmp_main->conf.lwn_port);
}
static void config_get_tc_elements(struct uci_section *s)
{
enum {
UCI_TC_ENABLE,
UCI_TC_TRANSFERTYPE,
UCI_TC_RESULTTYPE,
UCI_TC_FILETYPE,
__MAX_NUM_UCI_TC_ATTRS,
};
const struct uci_parse_option acs_opts[] = {
[UCI_TC_ENABLE] = { .name = "enable", .type = UCI_TYPE_STRING },
[UCI_TC_TRANSFERTYPE] = { .name = "transfer_type", .type = UCI_TYPE_STRING },
[UCI_TC_RESULTTYPE] = { .name = "result_type", .type = UCI_TYPE_STRING },
[UCI_TC_FILETYPE] = { .name = "file_type", .type = UCI_TYPE_STRING },
};
struct uci_option *tc_tb[__MAX_NUM_UCI_TC_ATTRS];
CWMP_MEMSET(tc_tb, 0, sizeof(tc_tb));
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_TC_ATTRS, tc_tb);
cwmp_main->conf.auto_tc_enable = uci_str_to_bool(get_value_from_uci_option(tc_tb[UCI_TC_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - tc enable: %d", cwmp_main->conf.auto_tc_enable);
snprintf(cwmp_main->conf.auto_tc_transfer_type, sizeof(cwmp_main->conf.auto_tc_transfer_type), "%s", get_value_from_uci_option(tc_tb[UCI_TC_TRANSFERTYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - tc transfer type: %s", cwmp_main->conf.auto_tc_transfer_type);
snprintf(cwmp_main->conf.auto_tc_result_type, sizeof(cwmp_main->conf.auto_tc_result_type), "%s", get_value_from_uci_option(tc_tb[UCI_TC_RESULTTYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - tc result type: %s", cwmp_main->conf.auto_tc_result_type);
snprintf(cwmp_main->conf.auto_tc_file_type, sizeof(cwmp_main->conf.auto_tc_file_type), "%s", get_value_from_uci_option(tc_tb[UCI_TC_FILETYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - tc file type: %s", cwmp_main->conf.auto_tc_file_type);
}
static void config_get_cds_elements(struct uci_section *s)
{
enum {
UCI_CDS_ENABLE,
UCI_CDS_OPTYPE,
UCI_CDS_RESULTYPE,
UCI_CDS_FAULTCODE,
__MAX_NUM_UCI_CDS_ATTRS,
};
const struct uci_parse_option cdu_opts[] = {
[UCI_CDS_ENABLE] = { .name = "enable", .type = UCI_TYPE_STRING },
[UCI_CDS_OPTYPE] = { .name = "operation_type", .type = UCI_TYPE_STRING },
[UCI_CDS_RESULTYPE] = { .name = "result_type", .type = UCI_TYPE_STRING },
[UCI_CDS_FAULTCODE] = { .name = "fault_code", .type = UCI_TYPE_STRING },
};
struct uci_option *cds_tb[__MAX_NUM_UCI_CDS_ATTRS];
CWMP_MEMSET(cds_tb, 0, sizeof(cds_tb));
uci_parse_section(s, cdu_opts, __MAX_NUM_UCI_CDS_ATTRS, cds_tb);
cwmp_main->conf.auto_cdu_enable = uci_str_to_bool(get_value_from_uci_option(cds_tb[UCI_CDS_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cds enable: %d", cwmp_main->conf.auto_cdu_enable);
snprintf(cwmp_main->conf.auto_cdu_oprt_type, sizeof(cwmp_main->conf.auto_cdu_oprt_type), "%s", get_value_from_uci_option(cds_tb[UCI_CDS_OPTYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cds operation type: %s", cwmp_main->conf.auto_cdu_oprt_type);
snprintf(cwmp_main->conf.auto_cdu_result_type, sizeof(cwmp_main->conf.auto_cdu_result_type), "%s", get_value_from_uci_option(cds_tb[UCI_CDS_RESULTYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cds result type: %s", cwmp_main->conf.auto_cdu_result_type);
snprintf(cwmp_main->conf.auto_cdu_fault_code, sizeof(cwmp_main->conf.auto_cdu_fault_code), "%s", get_value_from_uci_option(cds_tb[UCI_CDS_FAULTCODE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cds fault type: %s", cwmp_main->conf.auto_cdu_fault_code);
}
static void configure_var_state(void)
{
if (!file_exists(VARSTATE_CONFIG"/icwmp"))
creat(VARSTATE_CONFIG"/icwmp", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
cwmp_uci_add_section_with_specific_name("icwmp", "acs", "acs", UCI_VARSTATE_CONFIG);
cwmp_uci_add_section_with_specific_name("icwmp", "cpe", "cpe", UCI_VARSTATE_CONFIG);
cwmp_commit_package("icwmp", UCI_VARSTATE_CONFIG);
}
int get_preinit_config() int get_preinit_config()
{ {
#define UCI_CPE_LOG_FILE_NAME "cwmp.cpe.log_file_name" char value[BUF_SIZE_256] = {0};
#define UCI_CPE_LOG_MAX_SIZE "cwmp.cpe.log_max_size"
#define UCI_CPE_ENABLE_STDOUT_LOG "cwmp.cpe.log_to_console"
#define UCI_CPE_ENABLE_FILE_LOG "cwmp.cpe.log_to_file"
#define UCI_LOG_SEVERITY_PATH "cwmp.cpe.log_severity"
#define UCI_CPE_ENABLE_SYSLOG "cwmp.cpe.log_to_syslog"
#define UCI_CPE_DEFAULT_WAN_IFACE "cwmp.cpe.default_wan_interface"
#define UCI_CPE_INCOMING_RULE "cwmp.cpe.incoming_rule"
#define UCI_CPE_AMD_VERSION "cwmp.cpe.amd_version"
char *value = NULL; get_uci_path_value(NULL, UCI_LOG_SEVERITY_PATH, value, BUF_SIZE_256);
cwmp_uci_init();
uci_get_value(UCI_LOG_SEVERITY_PATH, &value);
log_set_severity_idx(value); log_set_severity_idx(value);
FREE(value);
uci_get_value(UCI_CPE_LOG_FILE_NAME, &value); get_uci_path_value(NULL, UCI_CPE_LOG_FILE_NAME, value, BUF_SIZE_256);
log_set_log_file_name(value); log_set_log_file_name(value);
FREE(value);
uci_get_value(UCI_CPE_LOG_MAX_SIZE, &value); get_uci_path_value(NULL, UCI_CPE_LOG_MAX_SIZE, value, BUF_SIZE_256);
log_set_file_max_size(value); log_set_file_max_size(value);
FREE(value);
uci_get_value(UCI_CPE_ENABLE_STDOUT_LOG, &value); get_uci_path_value(NULL, UCI_CPE_ENABLE_STDOUT_LOG, value, BUF_SIZE_256);
log_set_on_console(value); log_set_on_console(value);
FREE(value);
uci_get_value(UCI_CPE_ENABLE_FILE_LOG, &value); get_uci_path_value(NULL, UCI_CPE_ENABLE_FILE_LOG, value, BUF_SIZE_256);
log_set_on_file(value); log_set_on_file(value);
FREE(value);
uci_get_value(UCI_CPE_ENABLE_SYSLOG, &value); get_uci_path_value(NULL, UCI_CPE_ENABLE_SYSLOG, value, BUF_SIZE_256);
log_set_on_syslog(value); log_set_on_syslog(value);
FREE(value);
uci_get_value(UCI_CPE_DEFAULT_WAN_IFACE, &value); get_uci_path_value(NULL, UCI_CPE_DEFAULT_WAN_IFACE, cwmp_main->conf.default_wan_iface, BUF_SIZE_32);
snprintf(cwmp_main->conf.default_wan_iface, sizeof(cwmp_main->conf.default_wan_iface), "%s", value ? value : "wan"); if (CWMP_STRLEN(cwmp_main->conf.default_wan_iface) == 0) {
FREE(value); CWMP_STRNCMP(cwmp_main->conf.default_wan_iface, "wan", sizeof(cwmp_main->conf.default_wan_iface));
}
uci_get_value(UCI_CPE_INCOMING_RULE, &value); get_uci_path_value(NULL, UCI_CPE_INCOMING_RULE, value, BUF_SIZE_256);
set_cr_incoming_rule(value); set_cr_incoming_rule(value);
FREE(value);
cwmp_main->conf.amd_version = DEFAULT_AMD_VERSION; cwmp_main->conf.amd_version = DEFAULT_AMD_VERSION;
uci_get_value(UCI_CPE_AMD_VERSION, &value); get_uci_path_value(NULL, UCI_CPE_AMD_VERSION, value, BUF_SIZE_256);
if (CWMP_STRLEN(value) != 0) { if (CWMP_STRLEN(value) != 0) {
int a = atoi(value); int a = atoi(value);
cwmp_main->conf.amd_version = (a >= 1 && a <= 6) ? a : DEFAULT_AMD_VERSION; cwmp_main->conf.amd_version = (a >= 1 && a <= 6) ? a : DEFAULT_AMD_VERSION;
FREE(value);
} }
cwmp_main->conf.supported_amd_version = cwmp_main->conf.amd_version; cwmp_main->conf.supported_amd_version = cwmp_main->conf.amd_version;
configure_var_state();
cwmp_uci_exit();
CWMP_LOG(DEBUG, "CWMP CONFIG - default wan interface: %s", cwmp_main->conf.default_wan_iface); CWMP_LOG(DEBUG, "CWMP CONFIG - default wan interface: %s", cwmp_main->conf.default_wan_iface);
CWMP_LOG(DEBUG, "CWMP CONFIG - amendement version: %d", cwmp_main->conf.amd_version); CWMP_LOG(DEBUG, "CWMP CONFIG - amendement version: %d", cwmp_main->conf.amd_version);
@ -530,49 +83,10 @@ int get_preinit_config()
} }
int get_global_config() static int global_conf_init()
{
struct uci_context *ctx;
struct uci_package *pkg;
struct uci_element *e;
ctx = uci_alloc_context();
if (!ctx)
return CWMP_GEN_ERR;
if (uci_load(ctx, "cwmp", &pkg)) {
uci_free_context(ctx);
return CWMP_GEN_ERR;
}
uci_foreach_element(&pkg->sections, e) {
struct uci_section *s = uci_to_section(e);
if (s == NULL || s->type == NULL)
continue;
if (CWMP_STRCMP(s->type, "acs") == 0) {
config_get_acs_elements(s);
} else if (CWMP_STRCMP(s->type, "cpe") == 0) {
config_get_cpe_elements(s);
} else if (CWMP_STRCMP(s->type, "lwn") == 0) {
config_get_lwn_elements(s);
} else if (CWMP_STRCMP(s->type, "transfer_complete") == 0) {
config_get_tc_elements(s);
} else if (CWMP_STRCMP(s->type, "du_state_change") == 0) {
config_get_cds_elements(s);
}
}
uci_free_context(ctx);
return CWMP_OK;
}
int global_conf_init()
{ {
int error = CWMP_OK; int error = CWMP_OK;
pthread_mutex_lock(&mutex_config_load);
if ((error = get_global_config())) { if ((error = get_global_config())) {
cwmp_main->init_complete = false; cwmp_main->init_complete = false;
goto end; goto end;
@ -583,8 +97,6 @@ int global_conf_init()
launch_reboot_methods(); launch_reboot_methods();
end: end:
pthread_mutex_unlock(&mutex_config_load);
return error; return error;
} }
@ -611,7 +123,6 @@ void cwmp_config_load()
} }
sleep(UCI_OPTION_READ_INTERVAL); sleep(UCI_OPTION_READ_INTERVAL);
cwmp_uci_reinit();
ret = global_conf_init(); ret = global_conf_init();
if (ret == CWMP_OK) { if (ret == CWMP_OK) {
cwmp_main->net.ipv6_status = is_ipv6_enabled(); cwmp_main->net.ipv6_status = is_ipv6_enabled();

View file

@ -13,12 +13,16 @@
#ifndef _CONFIG_H__ #ifndef _CONFIG_H__
#define _CONFIG_H__ #define _CONFIG_H__
#include "cwmp_uci.h" #define UCI_CPE_LOG_FILE_NAME "cwmp.cpe.log_file_name"
#define UCI_CPE_LOG_MAX_SIZE "cwmp.cpe.log_max_size"
#define UCI_CPE_ENABLE_STDOUT_LOG "cwmp.cpe.log_to_console"
#define UCI_CPE_ENABLE_FILE_LOG "cwmp.cpe.log_to_file"
#define UCI_LOG_SEVERITY_PATH "cwmp.cpe.log_severity"
#define UCI_CPE_ENABLE_SYSLOG "cwmp.cpe.log_to_syslog"
#define UCI_CPE_DEFAULT_WAN_IFACE "cwmp.cpe.default_wan_interface"
#define UCI_CPE_INCOMING_RULE "cwmp.cpe.incoming_rule"
#define UCI_CPE_AMD_VERSION "cwmp.cpe.amd_version"
extern pthread_mutex_t mutex_config_load;
int global_conf_init();
int get_global_config();
int cwmp_get_deviceid(); int cwmp_get_deviceid();
int cwmp_config_reload(); int cwmp_config_reload();
int get_preinit_config(); int get_preinit_config();

View file

@ -23,7 +23,7 @@
#include "xml.h" #include "xml.h"
#include "notifications.h" #include "notifications.h"
#include "event.h" #include "event.h"
#include "cwmp_uci.h" #include "uci_utils.h"
#include "log.h" #include "log.h"
#include "session.h" #include "session.h"
#include "diagnostic.h" #include "diagnostic.h"
@ -96,17 +96,19 @@ void set_interface_reset_request(char *param_name, char *value)
static int create_cwmp_temporary_files(void) static int create_cwmp_temporary_files(void)
{ {
/* if (!file_exists(VARSTATE_CONFIG"/icwmp")) {
* Create Notifications empty uci package creat(VARSTATE_CONFIG"/icwmp", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
*/
if (!file_exists(CWMP_VARSTATE_UCI_PACKAGE)) {
FILE *fptr = fopen(CWMP_VARSTATE_UCI_PACKAGE, "w+");
if (fptr)
fclose(fptr);
else
return CWMP_GEN_ERR;
} }
set_uci_path_value(VARSTATE_CONFIG, "icwmp.acs", "acs");
set_uci_path_value(VARSTATE_CONFIG, "icwmp.cpe", "cpe");
if (!file_exists(CWMP_NOTIFICATIONS_PACKAGE)) {
creat(CWMP_NOTIFICATIONS_PACKAGE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
}
set_uci_path_value("/etc/icwmpd", "cwmp_notifications.notifications", "notifications");
if (!folder_exists("/var/run/icwmpd")) { if (!folder_exists("/var/run/icwmpd")) {
if (mkdir("/var/run/icwmpd", S_IRWXU | S_IRWXG | S_IRWXO) == -1) { if (mkdir("/var/run/icwmpd", S_IRWXU | S_IRWXG | S_IRWXO) == -1) {
CWMP_LOG(INFO, "Not able to create the folder /var/run/icwmpd"); CWMP_LOG(INFO, "Not able to create the folder /var/run/icwmpd");
@ -201,8 +203,6 @@ end:
static int cwmp_init(void) static int cwmp_init(void)
{ {
int error = 0;
openlog("cwmp", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); openlog("cwmp", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
cwmp_main = (struct cwmp *)calloc(1, sizeof(struct cwmp)); cwmp_main = (struct cwmp *)calloc(1, sizeof(struct cwmp));
@ -232,12 +232,6 @@ static int cwmp_init(void)
if (cwmp_main->pid_file) if (cwmp_main->pid_file)
fclose(cwmp_main->pid_file); fclose(cwmp_main->pid_file);
if ((error = create_cwmp_temporary_files()))
return error;
if ((error = create_cwmp_notifications_package()))
return error;
CWMP_LOG(DEBUG, "Loading icwmpd configuration"); CWMP_LOG(DEBUG, "Loading icwmpd configuration");
cwmp_config_load(); cwmp_config_load();
CWMP_LOG(DEBUG, "Successfully load icwmpd configuration"); CWMP_LOG(DEBUG, "Successfully load icwmpd configuration");
@ -254,8 +248,6 @@ static int cwmp_init(void)
cwmp_get_deviceid(); cwmp_get_deviceid();
cwmp_uci_init();
/* Load default force inform parameters */ /* Load default force inform parameters */
CWMP_MEMSET(&force_inform_list, 0, sizeof(struct list_head)); CWMP_MEMSET(&force_inform_list, 0, sizeof(struct list_head));
INIT_LIST_HEAD(&force_inform_list); INIT_LIST_HEAD(&force_inform_list);
@ -266,7 +258,6 @@ static int cwmp_init(void)
load_custom_notify_json(); load_custom_notify_json();
set_default_forced_active_parameters_notifications(); set_default_forced_active_parameters_notifications();
init_list_param_notify(); init_list_param_notify();
cwmp_uci_exit();
create_cwmp_session_structure(); create_cwmp_session_structure();
get_nonce_key(); get_nonce_key();
@ -290,7 +281,6 @@ static void cwmp_free()
bkp_tree_clean(); bkp_tree_clean();
icwmp_uloop_ubus_exit(); icwmp_uloop_ubus_exit();
icwmp_cleanmem(); icwmp_cleanmem();
cwmp_uci_exit();
rpc_exit(); rpc_exit();
clean_cwmp_session_structure(); clean_cwmp_session_structure();
FREE(cwmp_main); FREE(cwmp_main);
@ -336,6 +326,9 @@ int main(int argc, char **argv)
if ((error = global_env_init(argc, argv, &env))) if ((error = global_env_init(argc, argv, &env)))
return error; return error;
if ((error = create_cwmp_temporary_files()))
return error;
if ((error = cwmp_init())) if ((error = cwmp_init()))
return error; return error;

View file

@ -13,7 +13,6 @@
#include "common.h" #include "common.h"
#include "cwmp_cli.h" #include "cwmp_cli.h"
#include "cwmp_uci.h"
#include "notifications.h" #include "notifications.h"
LIST_HEAD(parameters_list); LIST_HEAD(parameters_list);

View file

@ -13,7 +13,7 @@
#include "cwmp_http.h" #include "cwmp_http.h"
#include "http.h" #include "http.h"
#include "log.h" #include "log.h"
#include "cwmp_uci.h" #include "uci_utils.h"
struct uloop_fd http_event6; struct uloop_fd http_event6;
@ -54,9 +54,7 @@ void http_server_stop(void)
static void set_http_ip_resolve(long ip_resolve) static void set_http_ip_resolve(long ip_resolve)
{ {
cwmp_main->net.ip_resolve = ip_resolve; cwmp_main->net.ip_resolve = ip_resolve;
set_uci_path_value(VARSTATE_CONFIG, "icwmp.acs.ip_version", (ip_resolve == CURL_IPRESOLVE_V6) ? "6" : "4");
cwmp_uci_set_varstate_value("icwmp", "acs", "ip_version", (ip_resolve == CURL_IPRESOLVE_V6) ? "6" : "4");
cwmp_commit_package("icwmp", UCI_VARSTATE_CONFIG);
} }
int icwmp_check_http_connection(void) int icwmp_check_http_connection(void)

View file

@ -1,742 +0,0 @@
/*
* cwmp_uci.c - API to manage UCI packages/sections/options
*
* Copyright (C) 2021-2022, IOPSYS Software Solutions AB.
*
* Author Omar Kallel <omar.kallel@pivasoftware.com>
*
* See LICENSE file for license related information.
*
*/
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
#include "cwmp_uci.h"
#include "log.h"
static struct uci_paths uci_save_conf_paths[] = {
[UCI_STANDARD_CONFIG] = { "/etc/config", "/tmp/.uci", NULL },
[UCI_VARSTATE_CONFIG] = { "/var/state", NULL, NULL },
[UCI_ETCICWMPD_CONFIG] = {"/etc/icwmpd", NULL, NULL}
};
/*
* UCI LOOKUP
*/
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;
}
static 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 UCI_ERR_IO;
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) {
return UCI_ERR_PARSE;
}
return UCI_OK;
}
static int cwmp_uci_lookup_ptr_by_section(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *s, char *option, char *value)
{
if (s == NULL || s->package == NULL)
return -1;
/*value*/
ptr->value = value;
/*package*/
ptr->package = s->package->e.name;
ptr->p = s->package;
/* section */
ptr->section = s->e.name;
ptr->s = s;
/*option*/
if (!option || !option[0]) {
ptr->target = UCI_TYPE_SECTION;
goto lookup;
}
ptr->target = UCI_TYPE_OPTION;
ptr->option = option;
ptr->flags |= UCI_LOOKUP_EXTENDED;
lookup:
if (uci_lookup_ptr(ctx, ptr, NULL, false) != UCI_OK || !UCI_LOOKUP_COMPLETE)
return -1;
return 0;
}
static char *cwmp_uci_list_to_string(struct uci_list *list, char *delimitor)
{
if (delimitor == NULL)
return NULL;
if (list && !uci_list_empty(list)) {
struct uci_element *e = NULL;
char list_val[512] = { 0 };
unsigned pos = 0;
list_val[0] = 0;
uci_foreach_element(list, e)
{
if (e->name)
pos += snprintf(&list_val[pos], sizeof(list_val) - pos, "%s%s", e->name, delimitor);
}
if (pos)
list_val[pos - 1] = 0;
return icwmp_strdup(list_val);
}
return NULL;
}
/*
* UCI Lists
*/
static void cwmp_uci_list_init(struct uci_list *ptr)
{
ptr->prev = ptr;
ptr->next = ptr;
}
static 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 void cwmp_uci_list_add(struct uci_list *head, struct uci_list *ptr)
{
cwmp_uci_list_insert(head->prev, ptr);
}
static void cwmp_uci_list_del(struct uci_element *e)
{
struct uci_list *ptr = e->list.prev;
ptr->next = e->list.next;
}
static void cwmp_delete_uci_element_from_list(struct uci_element *e)
{
cwmp_uci_list_del(e);
free(e->name);
free(e);
}
void cwmp_free_uci_list(struct uci_list *list)
{
struct uci_element *e = NULL, *tmp = NULL;
if (list == NULL)
return;
// cppcheck-suppress unknownMacro
uci_foreach_element_safe(list, e, tmp)
cwmp_delete_uci_element_from_list(e);
}
/*
* UCI INIT EXIT
*/
void cwmp_uci_init_by_config(int config)
{
if(uci_save_conf_paths[config].uci_ctx != NULL)
return;
uci_save_conf_paths[config].uci_ctx = uci_alloc_context();
if ( uci_save_conf_paths[config].uci_ctx == NULL)
return;
uci_add_delta_path(uci_save_conf_paths[config].uci_ctx, uci_save_conf_paths[config].uci_ctx->savedir);
uci_set_savedir(uci_save_conf_paths[config].uci_ctx, uci_save_conf_paths[config].save_dir);
uci_set_confdir(uci_save_conf_paths[config].uci_ctx, uci_save_conf_paths[config].conf_dir);
}
void cwmp_uci_exit_by_config(int config)
{
if (uci_save_conf_paths[config].uci_ctx) {
uci_free_context(uci_save_conf_paths[config].uci_ctx);
uci_save_conf_paths[config].uci_ctx = NULL;
}
}
int cwmp_uci_init(void)
{
unsigned int i = 0;
for (i = 0; i < ARRAY_SIZE(uci_save_conf_paths); i++) {
cwmp_uci_init_by_config(i);
}
return 0;
}
void cwmp_uci_exit(void)
{
unsigned int i = 0;
for (i = 0; i < ARRAY_SIZE(uci_save_conf_paths); i++) {
cwmp_uci_exit_by_config(i);
}
}
void cwmp_uci_reinit(void)
{
cwmp_uci_exit();
cwmp_uci_init();
}
/*
* UCI GET option value
*/
int cwmp_uci_get_value_by_path(char *path, uci_config_paths uci_type, char **value)
{
struct uci_ptr ptr;
char *s;
*value = NULL;
if (path == NULL)
return UCI_ERR_NOTFOUND;
s = strdup(path);
if (uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, s, true) != UCI_OK) {
CWMP_LOG(ERROR, "Error occurred in uci get %s", path);
free(s);
return UCI_ERR_PARSE;
}
free(s);
if (ptr.flags & UCI_LOOKUP_COMPLETE) {
if (ptr.o == NULL || ptr.o->v.string == NULL) {
CWMP_LOG(INFO, "%s not found or empty value", path);
return UCI_OK;
}
*value = strdup(ptr.o->v.string);
return UCI_OK;
}
return UCI_ERR_NOTFOUND;
}
int uci_get_state_value(char *path, char **value)
{
return cwmp_uci_get_value_by_path(path, UCI_VARSTATE_CONFIG, value);
}
int uci_get_value(char *path, char **value)
{
return cwmp_uci_get_value_by_path(path, UCI_STANDARD_CONFIG, value);
}
int cwmp_uci_get_value_by_section_string(struct uci_section *s, char *option, char **value)
{
struct uci_element *e;
struct uci_option *o;
*value = NULL;
if (s == NULL || option == NULL)
goto not_found;
uci_foreach_element(&s->options, e)
{
o = (uci_to_option(e));
if (o && !CWMP_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 ? icwmp_strdup(o->v.string) : NULL;
}
return UCI_OK;
}
}
not_found:
*value = NULL;
return UCI_ERR_NOTFOUND;
}
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;
char dup[256];
*value = NULL;
if (s == NULL || option == NULL)
return -1;
uci_foreach_element(&s->options, e)
{
o = (uci_to_option(e));
if (o && CWMP_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 = icwmp_calloc(1, sizeof(struct uci_list));
cwmp_uci_list_init(list);
snprintf(dup, sizeof(dup), "%s", o->v.string);
pch = strtok_r(dup, " ", &spch);
while (pch != NULL) {
e = icwmp_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;
}
/*
* UCI Set option value
*/
int cwmp_uci_set_value_string(char *package, char *section, char *option, char *value, uci_config_paths uci_type)
{
struct uci_ptr ptr = {0};
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || package == NULL || section == NULL)
return UCI_ERR_NOTFOUND;
if (cwmp_uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, package, section, option, value))
return UCI_ERR_PARSE;
if (uci_set(uci_save_conf_paths[uci_type].uci_ctx, &ptr) != UCI_OK)
return UCI_ERR_NOTFOUND;
if (ptr.o)
return UCI_OK;
return UCI_ERR_NOTFOUND;
}
int cwmp_uci_set_value(char *package, char *section, char *option, char *value)
{
return cwmp_uci_set_value_string(package, section, option, value, UCI_STANDARD_CONFIG);
}
int cwmp_uci_set_varstate_value(char *package, char *section, char *option, char *value)
{
return cwmp_uci_set_value_string(package, section, option, value, UCI_VARSTATE_CONFIG);
}
int uci_set_value_by_path(char *path, char *value, uci_config_paths uci_type)
{
struct uci_ptr ptr;
int ret = UCI_OK;
char cmd[256];
if (path == NULL || value == NULL)
return UCI_ERR_NOTFOUND;
snprintf(cmd, sizeof(cmd), "%s=%s", path, value);
if (uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, cmd, true) != UCI_OK) {
return UCI_ERR_PARSE;
}
ret = uci_set(uci_save_conf_paths[uci_type].uci_ctx, &ptr);
if (ret == UCI_OK) {
ret = uci_save(uci_save_conf_paths[uci_type].uci_ctx, ptr.p);
} else {
CWMP_LOG(ERROR, "UCI delete not succeed %s", path);
return UCI_ERR_NOTFOUND;
}
return ret;
}
int cwmp_uci_get_option_value_list(char *package, char *section, char *option, uci_config_paths uci_type, struct uci_list **value)
{
struct uci_element *e = NULL;
struct uci_ptr ptr = {0};
struct uci_list *list;
char *pch = NULL, *spch = NULL, *dup = NULL;
int option_type;
*value = NULL;
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || package == NULL || section ==NULL || option ==NULL)
return UCI_ERR_NOTFOUND;
if (cwmp_uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, package, section, option, NULL))
return UCI_ERR_PARSE;
if (ptr.o) {
switch(ptr.o->type) {
case UCI_TYPE_LIST:
*value = &ptr.o->v.list;
option_type = UCI_TYPE_LIST;
break;
case UCI_TYPE_STRING:
if (!ptr.o->v.string || (ptr.o->v.string)[0] == '\0') {
return UCI_TYPE_STRING;
}
list = calloc(1, sizeof(struct uci_list));
cwmp_uci_list_init(list);
dup = strdup(ptr.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;
option_type = UCI_TYPE_STRING;
break;
default:
return UCI_ERR_NOTFOUND;
}
} else {
return UCI_ERR_NOTFOUND;
}
return option_type;
}
int cwmp_uci_add_list_value(char *package, char *section, char *option, char *value, uci_config_paths uci_type)
{
struct uci_ptr ptr = {0};
int error = UCI_OK;
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || package == NULL || section ==NULL || option ==NULL)
return UCI_ERR_NOTFOUND;
if (cwmp_uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, package, section, option, value))
return UCI_ERR_PARSE;
error = uci_add_list(uci_save_conf_paths[uci_type].uci_ctx, &ptr);
if (error != UCI_OK)
return error;
return UCI_OK;
}
int cwmp_uci_del_list_value(char *package, char *section, char *option, char *value, uci_config_paths uci_type)
{
struct uci_ptr ptr = {0};
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || package == NULL || section ==NULL || option ==NULL)
return UCI_ERR_NOTFOUND;
if (cwmp_uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, package, section, option, value))
return -1;
if (uci_del_list(uci_save_conf_paths[uci_type].uci_ctx, &ptr) != UCI_OK)
return -1;
return 0;
}
int uci_add_list_value(char *cmd, uci_config_paths uci_type)
{
struct uci_ptr ptr;
int ret = UCI_OK;
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || cmd == NULL)
return UCI_ERR_NOTFOUND;
if (uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, cmd, true) != UCI_OK) {
return UCI_ERR_PARSE;
}
ret = uci_add_list(uci_save_conf_paths[uci_type].uci_ctx, &ptr);
if (ret == UCI_OK) {
ret = uci_save(uci_save_conf_paths[uci_type].uci_ctx, ptr.p);
} else {
CWMP_LOG(ERROR, "UCI delete not succeed %s", cmd);
return UCI_ERR_NOTFOUND;
}
return ret;
}
/*
* UCI ADD Section
*/
int cwmp_uci_add_section(char *package, char *stype, uci_config_paths uci_type , struct uci_section **s)
{
struct uci_ptr ptr = {0};
char fname[128];
*s = NULL;
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || package == NULL || stype == NULL)
return UCI_ERR_NOTFOUND;
snprintf(fname, sizeof(fname), "%s/%s", uci_save_conf_paths[uci_type].conf_dir, package);
if (!file_exists(fname)) {
FILE *fptr = fopen(fname, "w");
if (fptr)
fclose(fptr);
else
return UCI_ERR_UNKNOWN;
}
if (cwmp_uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, package, NULL, NULL, NULL) == 0
&& uci_add_section(uci_save_conf_paths[uci_type].uci_ctx, ptr.p, stype, s) == UCI_OK) {
CWMP_LOG(INFO, "New uci section %s added successfully", stype);
}
else
return UCI_ERR_NOTFOUND;
return UCI_OK;
}
static struct uci_section* get_section_by_section_name(char *package, char *stype, char* sname, uci_config_paths uci_type)
{
struct uci_section *s;
if (package == NULL || stype == NULL || sname == NULL)
return NULL;
cwmp_uci_foreach_sections(package, stype, uci_type, s) {
if (strcmp(section_name(s), sname) == 0)
return s;
}
return NULL;
}
int cwmp_uci_rename_section_by_section(struct uci_section *s, char *value, uci_config_paths uci_type)
{
struct uci_ptr up = {0};
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || s == NULL || value == NULL)
return UCI_ERR_NOTFOUND;
if (cwmp_uci_lookup_ptr_by_section(uci_save_conf_paths[uci_type].uci_ctx, &up, s, NULL, value) == -1)
return UCI_ERR_PARSE;
if (uci_rename(uci_save_conf_paths[uci_type].uci_ctx, &up) != UCI_OK)
return UCI_ERR_NOTFOUND;
return UCI_OK;
}
int cwmp_uci_add_section_with_specific_name(char *package, char *stype, char *section_name, uci_config_paths uci_type)
{
struct uci_section *s = NULL;
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || package == NULL || stype == NULL)
return UCI_ERR_NOTFOUND;
if (get_section_by_section_name(package, stype, section_name, uci_type) != NULL)
return UCI_ERR_DUPLICATE;
if (cwmp_uci_add_section(package, stype, uci_type, &s) != UCI_OK)
return UCI_ERR_UNKNOWN;
return cwmp_uci_rename_section_by_section(s, section_name, uci_type);
}
/*
* UCI Delete Value
*/
int uci_delete_value(char *path, int uci_type)
{
struct uci_ptr ptr;
int ret = UCI_OK;
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || path == NULL)
return UCI_ERR_NOTFOUND;
if (uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, path, true) != UCI_OK)
return CWMP_GEN_ERR;
ret = uci_delete(uci_save_conf_paths[uci_type].uci_ctx, &ptr);
if (ret == UCI_OK) {
ret = uci_save(uci_save_conf_paths[uci_type].uci_ctx, ptr.p);
} else {
CWMP_LOG(ERROR, "UCI delete not succeed %s", path);
return CWMP_GEN_ERR;
}
return ret;
}
int cwmp_uci_get_section_type(char *package, char *section, uci_config_paths uci_type, char **value)
{
struct uci_ptr ptr = {0};
if (uci_save_conf_paths[uci_type].uci_ctx == NULL || package == NULL || section == NULL)
return UCI_ERR_NOTFOUND;
if (cwmp_uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, package, section, NULL, NULL)) {
*value = "";
return -1;
}
if (ptr.s) {
*value = icwmp_strdup(ptr.s->type);
} else {
*value = "";
}
return UCI_OK;
}
struct uci_section *cwmp_uci_walk_section(char *package, char *stype, struct uci_section *prev_section, uci_config_paths uci_type, int walk)
{
struct uci_section *s = NULL;
struct uci_element *e = NULL;
struct uci_list *list_section = NULL;
struct uci_ptr ptr = {0};
if (package == NULL || stype == NULL)
goto end;
if (walk == CWMP_GET_FIRST_SECTION) {
if (cwmp_uci_lookup_ptr(uci_save_conf_paths[uci_type].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 (s && CWMP_STRCMP(s->type, stype) == 0)
goto end;
e = list_to_element(e->list.next);
s = NULL;
}
end:
return s;
}
int cwmp_commit_package(char *package, uci_config_paths uci_type)
{
struct uci_ptr ptr = { 0 };
if (uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, package, true) != UCI_OK) {
return -1;
}
if (uci_commit(uci_save_conf_paths[uci_type].uci_ctx, &ptr.p, false) != UCI_OK) {
return -1;
}
return 0;
}
int cwmp_uci_import(char *package_name, const char *input_path, uci_config_paths uci_type)
{
struct uci_package *package = NULL;
struct uci_element *e = NULL;
int ret = CWMP_OK;
if (input_path == NULL)
return -1;
FILE *input = fopen(input_path, "r");
if (!input)
return -1;
if (uci_save_conf_paths[uci_type].uci_ctx == NULL) {
ret = -1;
goto end;
}
if (uci_import(uci_save_conf_paths[uci_type].uci_ctx, input, package_name, &package, (package_name != NULL)) != UCI_OK) {
ret = -1;
goto end;
}
if (uci_save_conf_paths[uci_type].uci_ctx == NULL) {
ret = -1;
goto end;
}
uci_foreach_element(&uci_save_conf_paths[uci_type].uci_ctx->root, e)
{
struct uci_package *p = uci_to_package(e);
if (uci_commit(uci_save_conf_paths[uci_type].uci_ctx, &p, true) != UCI_OK)
ret = CWMP_GEN_ERR;
}
end:
fclose(input);
return ret;
}
int cwmp_uci_export_package(char *package, const char *output_path, uci_config_paths uci_type)
{
struct uci_ptr ptr = { 0 };
int ret = 0;
if (output_path == NULL)
return -1;
FILE *out = fopen(output_path, "a");
if (!out)
return -1;
if (uci_save_conf_paths[uci_type].uci_ctx == NULL) {
ret = -1;
goto end;
}
if (uci_lookup_ptr(uci_save_conf_paths[uci_type].uci_ctx, &ptr, package, true) != UCI_OK) {
ret = -1;
goto end;
}
if (uci_export(uci_save_conf_paths[uci_type].uci_ctx, out, ptr.p, true) != UCI_OK)
ret = -1;
end:
fclose(out);
return ret;
}
int cwmp_uci_export(const char *output_path, uci_config_paths uci_type)
{
char **configs = NULL;
char **p;
if (uci_list_configs(uci_save_conf_paths[uci_type].uci_ctx, &configs) != UCI_OK)
return -1;
if (configs == NULL)
return -1;
for (p = configs; *p; p++)
cwmp_uci_export_package(*p, output_path, uci_type);
FREE(configs);
return 0;
}

View file

@ -1,87 +0,0 @@
/*
* cwmp_uci.h - API to manage UCI packages/sections/options
*
* Copyright (C) 2021-2022, IOPSYS Software Solutions AB.
*
* Author Omar Kallel <omar.kallel@pivasoftware.com>
*
* See LICENSE file for license related information.
*
*/
#ifndef __CWMPUCI_H
#define __CWMPUCI_H
#include <uci.h>
#include <libubox/list.h>
#define UCI_CONFIG_DIR "/etc/config/"
#define ETC_DB_CONFIG "/etc/board-db/config"
#define VARSTATE_CONFIG "/var/state"
#define DHCP_OPTION_READ_MAX_RETRY 5
#define UCI_OPTION_READ_INTERVAL 5
#define section_name(s) s ? (s)->e.name : ""
typedef enum uci_config_paths
{
UCI_STANDARD_CONFIG,
UCI_VARSTATE_CONFIG,
UCI_ETCICWMPD_CONFIG,
} uci_config_paths;
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;
struct uci_context *uci_ctx;
};
int cwmp_uci_init();
void cwmp_uci_exit(void);
void cwmp_uci_reinit(void);
int cwmp_uci_get_option_value_list(char *package, char *section, char *option, uci_config_paths uci_type, struct uci_list **value);
int uci_get_state_value(char *cmd, char **value);
int uci_set_value_by_path(char *cmd, char *value, uci_config_paths uci_type);
int uci_get_value(char *cmd, char **value);
struct uci_section *cwmp_uci_walk_section(char *package, char *stype, struct uci_section *prev_section, uci_config_paths uci_type, int walk);
int cwmp_uci_get_value_by_section_string(struct uci_section *s, char *option, char **value);
int cwmp_commit_package(char *package, uci_config_paths uci_type);
int cwmp_uci_import(char *package_name, const char *input_path, uci_config_paths uci_type);
int cwmp_uci_export_package(char *package, const char *output_path, uci_config_paths uci_type);
int cwmp_uci_export(const char *output_path, uci_config_paths uci_type);
void cwmp_free_uci_list(struct uci_list *list);
int cwmp_uci_add_list_value(char *package, char *section, char *option, char *value, uci_config_paths uci_type);
int cwmp_uci_del_list_value(char *package, char *section, char *option, char *value, uci_config_paths uci_type);
int cwmp_uci_get_section_type(char *package, char *section, uci_config_paths uci_type, char **value);
int cwmp_uci_add_section(char *package, char *stype, uci_config_paths uci_type, struct uci_section **s);
int cwmp_uci_set_value(char *package, char *section, char *option, char *value);
int cwmp_uci_set_varstate_value(char *package, char*section, char *option, char *value);
int cwmp_uci_add_section_with_specific_name(char *package, char *stype, char *section, uci_config_paths uci_type);
#define cwmp_uci_foreach_sections(package, stype, uci_type, section) \
for (section = cwmp_uci_walk_section(package, stype, NULL, uci_type, CWMP_GET_FIRST_SECTION); \
section != NULL; \
section = cwmp_uci_walk_section(package, stype, section, uci_type, CWMP_GET_NEXT_SECTION))
#endif

View file

@ -14,13 +14,13 @@
#include "download.h" #include "download.h"
#include "ubus_utils.h" #include "ubus_utils.h"
#include "cwmp_uci.h"
#include "backupSession.h" #include "backupSession.h"
#include "log.h" #include "log.h"
#include "event.h" #include "event.h"
#include "common.h" #include "common.h"
#include "subprocess.h" #include "subprocess.h"
#include "session.h" #include "session.h"
#include "uci_utils.h"
LIST_HEAD(list_download); LIST_HEAD(list_download);
LIST_HEAD(list_schedule_download); LIST_HEAD(list_schedule_download);
@ -558,8 +558,7 @@ int apply_downloaded_file(struct download *pdownload, char *download_file_name,
bkp_session_insert_transfer_complete(ptransfer_complete); bkp_session_insert_transfer_complete(ptransfer_complete);
bkp_session_save(); bkp_session_save();
if (CWMP_STRCMP(pdownload->file_type, FIRMWARE_UPGRADE_IMAGE_FILE_TYPE) == 0) { if (CWMP_STRCMP(pdownload->file_type, FIRMWARE_UPGRADE_IMAGE_FILE_TYPE) == 0) {
cwmp_uci_set_value("cwmp", "cpe", "exec_download", "1"); set_uci_path_value(NULL, "cwmp.cpe.exec_download", "1");
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
if (cwmp_apply_firmware() != 0) { if (cwmp_apply_firmware() != 0) {
error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED; error = FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED;
snprintf(err_msg, sizeof(err_msg), "Failed in applying the downloaded firmware image, may be corrupted file"); snprintf(err_msg, sizeof(err_msg), "Failed in applying the downloaded firmware image, may be corrupted file");
@ -588,24 +587,22 @@ int apply_downloaded_file(struct download *pdownload, char *download_file_name,
remove(file_path); remove(file_path);
} else if (CWMP_STRCMP(pdownload->file_type, VENDOR_CONFIG_FILE_TYPE) == 0) { } else if (CWMP_STRCMP(pdownload->file_type, VENDOR_CONFIG_FILE_TYPE) == 0) {
cwmp_uci_init();
int err = CWMP_OK; int err = CWMP_OK;
if (download_file_name != NULL) { if (download_file_name != NULL) {
char file_path[512]; char file_path[512];
snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name); snprintf(file_path, sizeof(file_path), "/tmp/%s", download_file_name);
if (strstr(download_file_name, ".uci.conf") != NULL) { if (strstr(download_file_name, ".uci.conf") != NULL) {
err = cwmp_uci_import(NULL, file_path, UCI_STANDARD_CONFIG); err = import_uci_package(NULL, file_path);
} else { } else {
err = cwmp_uci_import(download_file_name, file_path, UCI_STANDARD_CONFIG); err = import_uci_package(download_file_name, file_path);
} }
remove(file_path); remove(file_path);
} else { } else {
err = cwmp_uci_import("vendor_conf_file", VENDOR_CONFIG_FILE, UCI_STANDARD_CONFIG); err = import_uci_package("vendor_conf_file", VENDOR_CONFIG_FILE);
remove(VENDOR_CONFIG_FILE); remove(VENDOR_CONFIG_FILE);
} }
cwmp_uci_exit();
if (err == CWMP_OK) if (err == CWMP_OK)
error = FAULT_CPE_NO_FAULT; error = FAULT_CPE_NO_FAULT;
else if (err == CWMP_GEN_ERR) { else if (err == CWMP_GEN_ERR) {

View file

@ -16,7 +16,6 @@
#include "common.h" #include "common.h"
#include "config.h" #include "config.h"
#include "session.h" #include "session.h"
#include "cwmp_uci.h"
#include "backupSession.h" #include "backupSession.h"
#include "log.h" #include "log.h"
#include "event.h" #include "event.h"

View file

@ -16,19 +16,20 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include "http.h" #include "http.h"
#include "cwmp_uci.h"
#include "log.h" #include "log.h"
#include "event.h" #include "event.h"
#include "ubus_utils.h" #include "ubus_utils.h"
#include "config.h" #include "config.h"
#include "digauth.h" #include "digauth.h"
#include "session.h" #include "session.h"
#include "uci_utils.h"
#define REALM "authenticate@cwmp" #define REALM "authenticate@cwmp"
#define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4" #define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
#define HTTP_GET_HDR_LEN 512 #define HTTP_GET_HDR_LEN 512
#define HTTP_FD_FEEDS_COUNT 10 /* Maximum number of lines to be read from HTTP header */ #define HTTP_FD_FEEDS_COUNT 10 /* Maximum number of lines to be read from HTTP header */
extern pthread_mutex_t mutex_config_load;
static struct curl_slist *header_list = NULL; static struct curl_slist *header_list = NULL;
static CURL *curl = NULL; static CURL *curl = NULL;
@ -310,13 +311,17 @@ int icwmp_http_send_message(char *msg_out, int msg_out_len, char **msg_in)
if (ip_acs[0] == '\0' || strcmp(ip_acs, ip) != 0) { if (ip_acs[0] == '\0' || strcmp(ip_acs, ip) != 0) {
CWMP_STRNCPY(ip_acs, ip, sizeof(ip_acs)); CWMP_STRNCPY(ip_acs, ip, sizeof(ip_acs));
tmp = inet_pton(AF_INET, ip, buf); tmp = inet_pton(AF_INET, ip, buf);
if (tmp == 1) if (tmp == 1) {
tmp = 0; tmp = 0;
else } else {
tmp = inet_pton(AF_INET6, ip, buf); tmp = inet_pton(AF_INET6, ip, buf);
}
cwmp_uci_set_varstate_value("icwmp", "acs", tmp ? "ip6" : "ip", ip_acs); if (tmp) {
cwmp_commit_package("icwmp", UCI_VARSTATE_CONFIG); set_uci_path_value(VARSTATE_CONFIG, "icwmp.acs.ip6", ip_acs);
} else {
set_uci_path_value(VARSTATE_CONFIG, "icwmp.acs.ip", ip_acs);
}
// Trigger firewall to reload firewall.cwmp // Trigger firewall to reload firewall.cwmp
if (cwmp_main->cr_policy != CR_POLICY_Port_Only) { if (cwmp_main->cr_policy != CR_POLICY_Port_Only) {
@ -662,12 +667,9 @@ void icwmp_http_server_init(void)
char cr_port_str[6]; char cr_port_str[6];
snprintf(cr_port_str, 6, "%hu", cr_port); snprintf(cr_port_str, 6, "%hu", cr_port);
cr_port_str[5] = '\0'; cr_port_str[5] = '\0';
cwmp_uci_init(); set_uci_path_value(NULL, "cwmp.cpe.port", cr_port_str);
cwmp_uci_set_value("cwmp", "cpe", "port", cr_port_str);
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
system(FIREWALL_CWMP); system(FIREWALL_CWMP);
connection_request_port_value_change(cr_port); connection_request_port_value_change(cr_port);
cwmp_uci_exit();
} }
CWMP_LOG(INFO, "Connection Request server initiated with the port: %d", cr_port); CWMP_LOG(INFO, "Connection Request server initiated with the port: %d", cr_port);

View file

@ -69,7 +69,7 @@ int log_set_on_console(char *value)
if (value == NULL) if (value == NULL)
return 1; return 1;
enable_log_stdout = uci_str_to_bool(value); enable_log_stdout = str_to_bool(value);
return 1; return 1;
} }
@ -78,7 +78,7 @@ int log_set_on_file(char *value)
if (value == NULL) if (value == NULL)
return 1; return 1;
enable_log_file = uci_str_to_bool(value); enable_log_file = str_to_bool(value);
return 1; return 1;
} }
@ -87,7 +87,7 @@ int log_set_on_syslog(char *value)
if (value == NULL) if (value == NULL)
return 1; return 1;
enable_log_syslog = uci_str_to_bool(value); enable_log_syslog = str_to_bool(value);
return 1; return 1;
} }

View file

@ -13,7 +13,7 @@
#include <fcntl.h> #include <fcntl.h>
#include "notifications.h" #include "notifications.h"
#include "cwmp_uci.h" #include "uci_utils.h"
#include "datamodel_interface.h" #include "datamodel_interface.h"
#include "ssl_utils.h" #include "ssl_utils.h"
#include "log.h" #include "log.h"
@ -30,7 +30,7 @@ LIST_HEAD(list_param_obj_notify);
struct uloop_timeout check_notify_timer = { .cb = periodic_check_notifiy }; struct uloop_timeout check_notify_timer = { .cb = periodic_check_notifiy };
char *notifications[7] = {"disabled" , "passive", "active", "passive_lw", "passive_passive_lw", "active_lw", "passive_active_lw"}; char *supported_notification_types[7] = {"disabled" , "passive", "active", "passive_lw", "passive_passive_lw", "active_lw", "passive_active_lw"};
char *default_active_notifications_parameters[] = { char *default_active_notifications_parameters[] = {
"Device.ManagementServer.ConnectionRequestURL", "Device.ManagementServer.ConnectionRequestURL",
@ -49,18 +49,6 @@ char *forced_notifications_parameters[] = {
/* /*
* Common functions * Common functions
*/ */
int create_cwmp_notifications_package()
{
if (!file_exists(CWMP_NOTIFICATIONS_PACKAGE)) {
FILE *fptr = fopen(CWMP_NOTIFICATIONS_PACKAGE, "w+");
if (fptr)
fclose(fptr);
else
return CWMP_GEN_ERR;
}
return CWMP_OK;
}
static bool parameter_is_subobject_of_parameter(char *parent, char *child) static bool parameter_is_subobject_of_parameter(char *parent, char *child)
{ {
if (child == NULL) { if (child == NULL) {
@ -115,83 +103,76 @@ char *check_valid_parameter_path(char *parameter_name)
*/ */
// Add parameter_name to the suitable notifications list // Add parameter_name to the suitable notifications list
int add_uci_option_notification(char *parameter_name, int notification) int add_uci_option_notification(char *parameter_name, int type)
{ {
char *notification_type = NULL; char notif_path[BUF_SIZE_256] = {0};
struct uci_section *s = NULL; int ret;
int ret = 0;
ret = cwmp_uci_get_section_type("cwmp_notifications", "@notifications[0]", UCI_ETCICWMPD_CONFIG, &notification_type); set_uci_path_value(ICWMPD_CONFIG, "cwmp_notifications.notifications", "notifications");
snprintf(notif_path, BUF_SIZE_256, "cwmp_notifications.notifications.%s", supported_notification_types[type]);
ret = set_uci_list_value(ICWMPD_CONFIG, notif_path, parameter_name);
if (ret != UCI_OK) if (ret != UCI_OK)
return -1; return -1;
if (notification_type == NULL || notification_type[0] == '\0') {
cwmp_uci_add_section("cwmp_notifications", "notifications", UCI_ETCICWMPD_CONFIG, &s);
}
ret = cwmp_uci_add_list_value("cwmp_notifications", "@notifications[0]", notifications[notification], parameter_name, UCI_ETCICWMPD_CONFIG);
if (ret != UCI_OK)
return -1;
ret = cwmp_commit_package("cwmp_notifications", UCI_ETCICWMPD_CONFIG);
return ret; return ret;
} }
bool check_parent_with_different_notification(char *parameter_name, int notification) bool check_parent_with_different_notification(char *parameter_name, int notification)
{ {
struct uci_list *list_notif = NULL;
struct uci_element *e = NULL;
int i; int i;
for (i = 0; i < 7; i++) { bool ret = false;
int option_type;
if (i == notification) for (i = 0; i < 7; i++) {
continue; char notif_path[BUF_SIZE_256] = {0};
option_type = cwmp_uci_get_option_value_list("cwmp_notifications", "@notifications[0]", notifications[i], UCI_ETCICWMPD_CONFIG, &list_notif); struct cwmp_dm_parameter *param_iter = NULL;
if (list_notif) { LIST_HEAD(local_notify_list);
uci_foreach_element(list_notif, e) {
if (parameter_is_subobject_of_parameter(e->name, parameter_name)) snprintf(notif_path, BUF_SIZE_256, "cwmp_notifications.notifications.%s", supported_notification_types[i]);
return true; get_uci_dm_list(ICWMPD_CONFIG, notif_path, &local_notify_list, i);
list_for_each_entry(param_iter, &local_notify_list, list) {
if (CWMP_STRLEN(param_iter->name) == 0)
continue;
if (parameter_is_subobject_of_parameter(param_iter->name, parameter_name)) {
ret = true;
break;
} }
} }
if (option_type == UCI_TYPE_STRING) cwmp_free_all_dm_parameter_list(&local_notify_list);
cwmp_free_uci_list(list_notif); if (ret == true) {
break;
}
} }
return false; return ret;
} }
bool update_notifications_list(char *parameter_name, int notification) bool update_notifications_list(char *parameter_name, int notification)
{ {
struct uci_list *list_notif;
struct uci_element *e = NULL, *tmp = NULL;
int i; int i;
char *ename = NULL;
bool update_ret = true; bool update_ret = true;
if (parameter_name == NULL) if (parameter_name == NULL)
parameter_name = "Device."; parameter_name = "Device.";
/*
* Parse all possible lists of of notifications one by one
*/ // Parse all possible lists of notifications one by one
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
int option_type; char notif_path[BUF_SIZE_256] = {0};
struct cwmp_dm_parameter *param_iter = NULL;
LIST_HEAD(local_notify_list);
option_type = cwmp_uci_get_option_value_list("cwmp_notifications", "@notifications[0]", notifications[i], UCI_ETCICWMPD_CONFIG, &list_notif); snprintf(notif_path, BUF_SIZE_256, "cwmp_notifications.notifications.%s", supported_notification_types[i]);
if (list_notif) { get_uci_dm_list(ICWMPD_CONFIG, notif_path, &local_notify_list, i);
uci_foreach_element_safe(list_notif, tmp, e) { list_for_each_entry(param_iter, &local_notify_list, list) {
if (e->name == NULL) if (CWMP_STRLEN(param_iter->name) == 0)
continue; continue;
ename = strdup(e->name);
if ((strcmp(parameter_name, e->name) == 0 && (i != notification)) || parameter_is_subobject_of_parameter(parameter_name, e->name)) if ((CWMP_STRCMP(parameter_name, param_iter->name) == 0 && (i != notification)) || parameter_is_subobject_of_parameter(parameter_name, param_iter->name))
cwmp_uci_del_list_value("cwmp_notifications", "@notifications[0]", notifications[i], e->name, UCI_ETCICWMPD_CONFIG); del_uci_list_value(ICWMPD_CONFIG, notif_path, param_iter->name);
if (ename && (strcmp(parameter_name, ename) == 0 || parameter_is_subobject_of_parameter(ename, parameter_name) ) && (i == notification)) if ((CWMP_STRCMP(parameter_name, param_iter->name) == 0 || parameter_is_subobject_of_parameter(param_iter->name, parameter_name) ) && (i == notification))
update_ret = false; update_ret = false;
FREE(ename);
}
cwmp_commit_package("cwmp_notifications", UCI_ETCICWMPD_CONFIG);
} }
if (option_type == UCI_TYPE_STRING) cwmp_free_all_dm_parameter_list(&local_notify_list);
cwmp_free_uci_list(list_notif);
} }
if (update_ret && notification == 0 && !check_parent_with_different_notification(parameter_name, 0)) if (update_ret && notification == 0 && !check_parent_with_different_notification(parameter_name, 0))
@ -201,25 +182,45 @@ bool update_notifications_list(char *parameter_name, int notification)
char *cwmp_set_parameter_attributes(char *parameter_name, int notification) char *cwmp_set_parameter_attributes(char *parameter_name, int notification)
{ {
char *error = NULL; char *error = NULL;
if (parameter_name == NULL) if (parameter_name == NULL)
parameter_name = "Device."; parameter_name = "Device.";
/*Check if the parameter name is present in TR-181 datamodel*/ /*Check if the parameter name is present in TR-181 datamodel*/
error = check_valid_parameter_path(parameter_name); error = check_valid_parameter_path(parameter_name);
if (error != NULL) if (error != NULL)
return error; return error;
/*Mustn't set notifications for forced notifications parameter*/ /*Mustn't set notifications for forced notifications parameter*/
if (check_parameter_forced_notification(parameter_name)) if (check_parameter_forced_notification(parameter_name))
return "9009"; return "9009";
/*checks if the notifications lists need to be updated*/ /*checks if the notifications lists need to be updated*/
if (update_notifications_list(parameter_name, notification) == true) if (update_notifications_list(parameter_name, notification) == true)
add_uci_option_notification(parameter_name, notification); add_uci_option_notification(parameter_name, notification);
return NULL; return NULL;
}
int cwmp_set_parameter_attributes_list(struct list_head *parameters_list)
{
struct cwmp_dm_parameter *param_iter = NULL;
int ret = CWMP_OK;
list_for_each_entry (param_iter, parameters_list, list) {
char *parameter_name = param_iter->name;
int notif_type = param_iter->notification;
char *error = NULL;
error = cwmp_set_parameter_attributes(parameter_name, notif_type);
if (error != NULL) {
CWMP_LOG(ERROR, "Invalid/forced parameter %s, skipped %s", parameter_name, error);
continue;
}
}
return ret;
} }
/* /*
@ -227,33 +228,40 @@ char *cwmp_set_parameter_attributes(char *parameter_name, int notification)
*/ */
int get_parameter_family_notifications(char *parameter_name, struct list_head *childs_notifications) { int get_parameter_family_notifications(char *parameter_name, struct list_head *childs_notifications) {
struct uci_list *list_notif;
struct uci_element *e = NULL;
int i, notif_ret = 0; int i, notif_ret = 0;
char *parent_param = NULL;
if (parameter_name == NULL) if (parameter_name == NULL)
parameter_name = "Device."; parameter_name = "Device.";
for (i = 0; i < 7; i++) {
int option_type;
option_type = cwmp_uci_get_option_value_list("cwmp_notifications", "@notifications[0]", notifications[i], UCI_ETCICWMPD_CONFIG, &list_notif); for (i = 0; i < 7; i++) {
if (list_notif) { char *parent_param = NULL;
uci_foreach_element(list_notif, e) { char notif_path[BUF_SIZE_256] = {0};
if (parameter_is_subobject_of_parameter(parameter_name, e->name)) { LIST_HEAD(local_notify_list);
add_dm_parameter_to_list(childs_notifications, e->name, "", "", i, false); struct cwmp_dm_parameter *param_iter = NULL;
}
if (parameter_is_subobject_of_parameter(e->name, parameter_name) && (parent_param == NULL || parameter_is_subobject_of_parameter(parent_param, e->name))) { snprintf(notif_path, BUF_SIZE_256, "cwmp_notifications.notifications.%s", supported_notification_types[i]);
parent_param = e->name; get_uci_dm_list(ICWMPD_CONFIG, notif_path, &local_notify_list, i);
notif_ret = i; list_for_each_entry(param_iter, &local_notify_list, list) {
} if (CWMP_STRLEN(param_iter->name) == 0)
if (CWMP_STRCMP(parameter_name, e->name) == 0) continue;
notif_ret = i;
if (parameter_is_subobject_of_parameter(parameter_name, param_iter->name)) {
add_dm_parameter_to_list(childs_notifications, param_iter->name, "", "", i, false);
} }
// cppcheck-suppress knownConditionTrueFalse
if (parameter_is_subobject_of_parameter(param_iter->name, parameter_name) && (parent_param == NULL || parameter_is_subobject_of_parameter(parent_param, param_iter->name))) {
parent_param = CWMP_STRDUP(param_iter->name);
notif_ret = i;
}
if (CWMP_STRCMP(parameter_name, param_iter->name) == 0)
notif_ret = i;
} }
if (option_type == UCI_TYPE_STRING) FREE(parent_param);
cwmp_free_uci_list(list_notif); cwmp_free_all_dm_parameter_list(&local_notify_list);
} }
return notif_ret; return notif_ret;
} }
@ -351,25 +359,6 @@ bool parameter_is_other_notif_object_child(char *parent, char *parameter)
return false; return false;
} }
void create_list_param_obj_notify()
{
struct uci_list *list_notif = NULL;
struct uci_element *e = NULL;
int i;
for (i = 0; i < 7; i++) {
int option_type;
option_type = cwmp_uci_get_option_value_list("cwmp_notifications", "@notifications[0]", notifications[i], UCI_ETCICWMPD_CONFIG, &list_notif);
if (list_notif) {
uci_foreach_element(list_notif, e) {
add_dm_parameter_to_list(&list_param_obj_notify, e->name, "", "", i, false);
}
if (option_type == UCI_TYPE_STRING)
cwmp_free_uci_list(list_notif);
}
}
}
char* update_list_param_leaf_notify_with_sub_parameter_list(struct list_head *list_param_leaf_notify, char* parent_parameter, int parent_notification, bool parent_forced_notif, void (*update_notify_file_line_arg)(FILE *notify_file, char *param_name, char *param_type, char *param_value, int notification), FILE* notify_file_arg) char* update_list_param_leaf_notify_with_sub_parameter_list(struct list_head *list_param_leaf_notify, char* parent_parameter, int parent_notification, bool parent_forced_notif, void (*update_notify_file_line_arg)(FILE *notify_file, char *param_name, char *param_type, char *param_value, int notification), FILE* notify_file_arg)
{ {
struct cwmp_dm_parameter *param_iter = NULL; struct cwmp_dm_parameter *param_iter = NULL;
@ -406,7 +395,14 @@ void create_list_param_leaf_notify(struct list_head *list_param_leaf_notify, voi
void init_list_param_notify() void init_list_param_notify()
{ {
create_list_param_obj_notify(); int i;
for (i = 0; i < 7; i++) {
char notif_path[BUF_SIZE_256] = {0};
snprintf(notif_path, BUF_SIZE_256, "cwmp_notifications.notifications.%s", supported_notification_types[i]);
get_uci_dm_list(ICWMPD_CONFIG, notif_path, &list_param_obj_notify, i);
}
} }
void clean_list_param_notify() void clean_list_param_notify()
@ -416,7 +412,6 @@ void clean_list_param_notify()
void reinit_list_param_notify() void reinit_list_param_notify()
{ {
cwmp_uci_reinit();
clean_list_param_notify(); clean_list_param_notify();
init_list_param_notify(); init_list_param_notify();
} }
@ -505,6 +500,7 @@ void load_custom_notify_json(void)
{ "notify_type", BLOBMSG_TYPE_STRING } { "notify_type", BLOBMSG_TYPE_STRING }
}; };
LIST_HEAD(notification_list_head);
blobmsg_for_each_attr(cur, custom_notify_list, rem) { blobmsg_for_each_attr(cur, custom_notify_list, rem) {
struct blob_attr *tb[2] = { 0, 0 }; struct blob_attr *tb[2] = { 0, 0 };
@ -517,41 +513,24 @@ void load_custom_notify_json(void)
continue; continue;
} }
char *fault = cwmp_set_parameter_attributes(blobmsg_get_string(tb[0]), atoi(blobmsg_get_string(tb[1]))); add_dm_parameter_to_list(&notification_list_head, blobmsg_get_string(tb[0]), "", "", atoi(blobmsg_get_string(tb[1])), false);
if (fault == NULL)
continue;
if (strcmp(fault, "9005") == 0) {
CWMP_LOG(WARNING, "The parameter %s is wrong path", blobmsg_get_string(tb[0]));
continue;
}
if (strcmp(fault, "9009") == 0) {
CWMP_LOG(WARNING, "This parameter %s is forced notification parameter, can't be changed", blobmsg_get_string(tb[0]));
continue;
}
} }
blob_buf_free(&bbuf); blob_buf_free(&bbuf);
cwmp_set_parameter_attributes_list(&notification_list_head);
cwmp_free_all_dm_parameter_list(&notification_list_head);
creat(RUN_NOTIFY_MARKER, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); creat(RUN_NOTIFY_MARKER, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
cwmp_main->custom_notify_active = true; cwmp_main->custom_notify_active = true;
} }
void set_default_forced_active_parameters_notifications() void set_default_forced_active_parameters_notifications()
{ {
LIST_HEAD(forced_list_head);
for (size_t i = 0; i < ARRAY_SIZE(default_active_notifications_parameters); i++) { for (size_t i = 0; i < ARRAY_SIZE(default_active_notifications_parameters); i++) {
char *fault = cwmp_set_parameter_attributes(default_active_notifications_parameters[i], 2); add_dm_parameter_to_list(&forced_list_head, default_active_notifications_parameters[i], "", "", 2, false);
if (fault == NULL)
continue;
if (strcmp(fault, "9005") == 0) {
continue;
}
if (strcmp(fault, "9009") == 0) {
CWMP_LOG(WARNING, "This parameter %s is forced notification parameter, can't be changed", default_active_notifications_parameters[i]);
continue;
}
} }
cwmp_set_parameter_attributes_list(&forced_list_head);
cwmp_free_all_dm_parameter_list(&forced_list_head);
} }
/* /*

View file

@ -11,9 +11,9 @@
#include <unistd.h> #include <unistd.h>
#include "session.h" #include "session.h"
#include "cwmp_uci.h"
#include "log.h" #include "log.h"
#include "reboot.h" #include "reboot.h"
#include "uci_utils.h"
void cwmp_schedule_reboot(struct uloop_timeout *timeout __attribute__((unused))); void cwmp_schedule_reboot(struct uloop_timeout *timeout __attribute__((unused)));
void cwmp_delay_reboot(struct uloop_timeout *timeout __attribute__((unused))); void cwmp_delay_reboot(struct uloop_timeout *timeout __attribute__((unused)));
@ -23,8 +23,7 @@ struct uloop_timeout delay_reboot_timer = { .cb = cwmp_delay_reboot };
void cwmp_schedule_reboot(struct uloop_timeout *timeout __attribute__((unused))) void cwmp_schedule_reboot(struct uloop_timeout *timeout __attribute__((unused)))
{ {
cwmp_uci_set_value("cwmp", "cpe", "schedule_reboot", "0001-01-01T00:00:00Z"); set_uci_path_value(NULL, "cwmp.cpe.schedule_reboot", "0001-01-01T00:00:00Z");
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
if (time(NULL) > cwmp_main->conf.schedule_reboot) if (time(NULL) > cwmp_main->conf.schedule_reboot)
return; return;
cwmp_reboot("schedule_reboot"); cwmp_reboot("schedule_reboot");
@ -32,8 +31,7 @@ void cwmp_schedule_reboot(struct uloop_timeout *timeout __attribute__((unused))
void cwmp_delay_reboot(struct uloop_timeout *timeout __attribute__((unused))) void cwmp_delay_reboot(struct uloop_timeout *timeout __attribute__((unused)))
{ {
cwmp_uci_set_value("cwmp", "cpe", "delay_reboot", "-1"); set_uci_path_value(NULL, "cwmp.cpe.delay_reboot", "-1");
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
if (cwmp_main->session->session_status.last_status == SESSION_RUNNING) { if (cwmp_main->session->session_status.last_status == SESSION_RUNNING) {
cwmp_set_end_session(END_SESSION_REBOOT); cwmp_set_end_session(END_SESSION_REBOOT);
} else { } else {

View file

@ -25,7 +25,7 @@
#include "upload.h" #include "upload.h"
#include "sched_inform.h" #include "sched_inform.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "cwmp_uci.h" #include "uci_utils.h"
#include "cwmp_event.h" #include "cwmp_event.h"
#include "autonomous_complpolicy.h" #include "autonomous_complpolicy.h"
@ -362,18 +362,18 @@ static void load_inform_xml_schema(mxml_node_t **tree)
if (cwmp_main->session->session_status.is_heartbeat) if (cwmp_main->session->session_status.is_heartbeat)
goto end; goto end;
struct uci_section *s = NULL;
cwmp_uci_foreach_sections("cwmp", "inform_parameter", UCI_STANDARD_CONFIG, s)
{
char *enable = NULL;
cwmp_uci_get_value_by_section_string(s, "enable", &enable);
if (uci_str_to_bool(enable) == false) LIST_HEAD(local_inform_list);
struct cwmp_dm_parameter *param_iter = NULL;
get_inform_parameters_uci(&local_inform_list);
list_for_each_entry(param_iter, &list_param_obj_notify, list) {
bool enable = param_iter->writable;
if (enable == false)
continue; continue;
char *parameter_name = NULL; char *parameter_name = param_iter->name;
cwmp_uci_get_value_by_section_string(s, "parameter_name", &parameter_name);
if (CWMP_STRLEN(parameter_name) == 0) if (CWMP_STRLEN(parameter_name) == 0)
continue; continue;
@ -382,9 +382,7 @@ static void load_inform_xml_schema(mxml_node_t **tree)
if (err || list_empty(&parameters_list)) if (err || list_empty(&parameters_list))
continue; continue;
char *events_str_list = NULL; char *events_str_list = param_iter->value;
cwmp_uci_get_value_by_section_string(s, "events_list", &events_str_list);
if (!check_inform_parameter_events_list_corresponding(events_str_list, &(cwmp_main->session->events))) if (!check_inform_parameter_events_list_corresponding(events_str_list, &(cwmp_main->session->events)))
continue; continue;

View file

@ -33,6 +33,7 @@
#include "sched_inform.h" #include "sched_inform.h"
#include "cwmp_du_state.h" #include "cwmp_du_state.h"
#include "cwmp_http.h" #include "cwmp_http.h"
#include "uci_utils.h"
static void cwmp_periodic_session_timer(struct uloop_timeout *timeout); static void cwmp_periodic_session_timer(struct uloop_timeout *timeout);
@ -63,7 +64,6 @@ int cwmp_session_init()
cwmp_main->cwmp_cr_event = 0; cwmp_main->cwmp_cr_event = 0;
cwmp_uci_init();
/* /*
* Set Required methods as initial value of * Set Required methods as initial value of
*/ */
@ -101,7 +101,6 @@ int cwmp_session_rpc_destructor(struct rpc *rpc)
int cwmp_session_exit() int cwmp_session_exit()
{ {
rpc_exit(); rpc_exit();
cwmp_uci_exit();
icwmp_cleanmem(); icwmp_cleanmem();
return CWMP_OK; return CWMP_OK;
} }
@ -253,10 +252,8 @@ static void set_cwmp_session_status_state(int status)
{ {
char *state = NULL; char *state = NULL;
if (!file_exists(VARSTATE_CONFIG"/icwmp")) // Create sess_status config section
creat(VARSTATE_CONFIG"/icwmp", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); set_uci_path_value(VARSTATE_CONFIG, "icwmp.sess_status", "sess_status");
cwmp_uci_add_section_with_specific_name("icwmp", "sess_status", "sess_status", UCI_VARSTATE_CONFIG);
switch (status) { switch (status) {
case SESSION_WAITING: case SESSION_WAITING:
@ -273,9 +270,7 @@ static void set_cwmp_session_status_state(int status)
break; break;
} }
cwmp_uci_set_varstate_value("icwmp", "sess_status", "current_status", state ? state : "N/A"); set_uci_path_value(VARSTATE_CONFIG, "icwmp.sess_status.current_status", state ? state : "N/A");
cwmp_commit_package("icwmp", UCI_VARSTATE_CONFIG);
} }
void set_cwmp_session_status(int status, int retry_time) void set_cwmp_session_status(int status, int retry_time)
@ -334,7 +329,7 @@ static void schedule_session_retry(void)
void start_cwmp_session(void) void start_cwmp_session(void)
{ {
int error; int error;
char *exec_download = NULL; char exec_download[BUF_SIZE_256] = {0};
uloop_timeout_cancel(&check_notify_timer); uloop_timeout_cancel(&check_notify_timer);
if (cwmp_session_init() != CWMP_OK) { if (cwmp_session_init() != CWMP_OK) {
@ -378,13 +373,11 @@ void start_cwmp_session(void)
CWMP_LOG(INFO, "Start session"); CWMP_LOG(INFO, "Start session");
uci_get_value("cwmp.cpe.exec_download", &exec_download); get_uci_path_value(NULL, "cwmp.cpe.exec_download", exec_download, BUF_SIZE_256);
if (CWMP_STRCMP(exec_download, "1") == 0) { if (CWMP_STRCMP(exec_download, "1") == 0) {
CWMP_LOG(INFO, "Firmware downloaded and applied successfully"); CWMP_LOG(INFO, "Firmware downloaded and applied successfully");
cwmp_uci_set_value("cwmp", "cpe", "exec_download", "0"); set_uci_path_value(NULL, "cwmp.cpe.exec_download", "0");
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
} }
FREE(exec_download);
error = cwmp_schedule_rpc(); error = cwmp_schedule_rpc();
if (error != CWMP_OK) { if (error != CWMP_OK) {
@ -603,8 +596,6 @@ int cwmp_apply_acs_changes(void)
{ {
int error; int error;
cwmp_uci_reinit();
if ((error = cwmp_config_reload())) if ((error = cwmp_config_reload()))
return error; return error;

View file

@ -13,7 +13,6 @@
#include "log.h" #include "log.h"
#include "sched_inform.h" #include "sched_inform.h"
#include "event.h" #include "event.h"
#include "cwmp_uci.h"
#include "session.h" #include "session.h"
#include "cwmp_event.h" #include "cwmp_event.h"
#include "autonomous_complpolicy.h" #include "autonomous_complpolicy.h"

884
src/uci_utils.c Normal file
View file

@ -0,0 +1,884 @@
/*
* uci_utils.c - API to manage UCI packages/sections/options
*
* Copyright (C) 2021-2022, IOPSYS Software Solutions AB.
*
* See LICENSE file for license related information.
*
*/
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
#include "uci_utils.h"
#include "log.h"
pthread_mutex_t mutex_config_load = PTHREAD_MUTEX_INITIALIZER;
// STATIC functions
static int _uci_get_value_by_section_string(struct uci_section *s, char *option, char *value, int len)
{
struct uci_element *e;
if (s == NULL || option == NULL)
return UCI_ERR_NOTFOUND;
uci_foreach_element(&s->options, e)
{
struct uci_option *o;
o = (uci_to_option(e));
if (o && !CWMP_STRCMP(o->e.name, option)) {
if (o->type == UCI_TYPE_STRING) {
CWMP_STRNCPY(value, o->v.string, len);
}
break;
}
}
return 0;
}
static char *get_value_from_uci_option(struct uci_option *tb)
{
if (tb == NULL)
return "";
if (tb->type == UCI_TYPE_STRING)
return tb->v.string;
return "";
}
static void config_get_acs_elements(struct uci_section *s)
{
enum {
UCI_ACS_SSL_CAPATH,
UCI_ACS_HTTP_DISABLE_100CONTINUE,
UCI_ACS_INSECURE_ENABLE,
UCI_ACS_DHCP_DISCOVERY,
UCI_ACS_URL,
UCI_ACS_DHCP_URL,
UCI_ACS_USERID,
UCI_ACS_PASSWR,
UCI_ACS_RETRY_MIN_WAIT_INTERVAL,
UCI_ACS_DHCP_RETRY_MIN_WAIT_INTERVAL,
UCI_ACS_RETRY_INTERVAL_MULTIPLIER,
UCI_ACS_DHCP_RETRY_INTERVAL_MULTIPLIER,
UCI_ACS_COMPRESSION,
UCI_ACS_GETRPC,
UCI_ACS_PERIODIC_INFORM_TIME,
UCI_ACS_PERIODIC_INFORM_INTERVAL,
UCI_ACS_PERIODIC_INFORM_ENABLE,
UCI_ACS_HEARTBEAT_ENABLE,
UCI_ACS_HEARTBEAT_INTERVAL,
UCI_ACS_HEARTBEAT_TIME,
__MAX_NUM_UCI_ACS_ATTRS,
};
const struct uci_parse_option acs_opts[] = {
[UCI_ACS_SSL_CAPATH] = { .name = "ssl_capath", .type = UCI_TYPE_STRING },
[UCI_ACS_HTTP_DISABLE_100CONTINUE] = { .name = "http_disable_100continue", .type = UCI_TYPE_STRING },
[UCI_ACS_INSECURE_ENABLE] = { .name = "insecure_enable", .type = UCI_TYPE_STRING },
[UCI_ACS_DHCP_DISCOVERY] = { .name = "dhcp_discovery", .type = UCI_TYPE_STRING },
[UCI_ACS_URL] = { .name = "url", .type = UCI_TYPE_STRING },
[UCI_ACS_DHCP_URL] = { .name = "dhcp_url", .type = UCI_TYPE_STRING },
[UCI_ACS_USERID] = { .name = "userid", .type = UCI_TYPE_STRING },
[UCI_ACS_PASSWR] = { .name = "passwd", .type = UCI_TYPE_STRING },
[UCI_ACS_RETRY_MIN_WAIT_INTERVAL] = { .name = "retry_min_wait_interval", .type = UCI_TYPE_STRING },
[UCI_ACS_DHCP_RETRY_MIN_WAIT_INTERVAL] = { .name = "dhcp_retry_min_wait_interval", .type = UCI_TYPE_STRING },
[UCI_ACS_RETRY_INTERVAL_MULTIPLIER] = { .name = "retry_interval_multiplier", .type = UCI_TYPE_STRING },
[UCI_ACS_DHCP_RETRY_INTERVAL_MULTIPLIER] = { .name = "dhcp_retry_interval_multiplier", .type = UCI_TYPE_STRING },
[UCI_ACS_COMPRESSION] = { .name = "compression", .type = UCI_TYPE_STRING },
[UCI_ACS_GETRPC] = { .name = "get_rpc_methods", .type = UCI_TYPE_STRING },
[UCI_ACS_PERIODIC_INFORM_TIME] = { .name = "periodic_inform_time", .type = UCI_TYPE_STRING },
[UCI_ACS_PERIODIC_INFORM_INTERVAL] = { .name = "periodic_inform_interval", .type = UCI_TYPE_STRING },
[UCI_ACS_PERIODIC_INFORM_ENABLE] = { .name = "periodic_inform_enable", .type = UCI_TYPE_STRING },
[UCI_ACS_HEARTBEAT_ENABLE] = { .name = "heartbeat_enable", .type = UCI_TYPE_STRING },
[UCI_ACS_HEARTBEAT_INTERVAL] = { .name = "heartbeat_interval", .type = UCI_TYPE_STRING },
[UCI_ACS_HEARTBEAT_TIME] = { .name = "heartbeat_time", .type = UCI_TYPE_STRING },
};
struct uci_option *acs_tb[__MAX_NUM_UCI_ACS_ATTRS];
CWMP_MEMSET(acs_tb, 0, sizeof(acs_tb));
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_ACS_ATTRS, acs_tb);
cwmp_main->conf.http_disable_100continue = str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_HTTP_DISABLE_100CONTINUE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs http disable 100continue: %d", cwmp_main->conf.http_disable_100continue);
cwmp_main->conf.insecure_enable = str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_INSECURE_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs insecure enable: %d", cwmp_main->conf.insecure_enable);
cwmp_main->conf.dhcp_discovery = str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_DHCP_DISCOVERY]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs dhcp discovery: %d", cwmp_main->conf.dhcp_discovery);
char *get_rpc = get_value_from_uci_option(acs_tb[UCI_ACS_GETRPC]);
cwmp_main->conf.acs_getrpc = CWMP_STRLEN(get_rpc) ? str_to_bool(get_rpc) : true;
CWMP_LOG(DEBUG, "CWMP CONFIG - acs get rpc: %d", cwmp_main->conf.acs_getrpc);
char *url = get_value_from_uci_option(acs_tb[UCI_ACS_URL]);
char *dhcp_url = get_value_from_uci_option(acs_tb[UCI_ACS_DHCP_URL]);
snprintf(cwmp_main->conf.acs_url, sizeof(cwmp_main->conf.acs_url), "%s", cwmp_main->conf.dhcp_discovery ? (strlen(dhcp_url) ? dhcp_url : url) : url);
CWMP_LOG(DEBUG, "CWMP CONFIG - acs url: %s", cwmp_main->conf.acs_url);
snprintf(cwmp_main->conf.acs_userid, sizeof(cwmp_main->conf.acs_userid), "%s", get_value_from_uci_option(acs_tb[UCI_ACS_USERID]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs username: %s", cwmp_main->conf.acs_userid);
snprintf(cwmp_main->conf.acs_passwd, sizeof(cwmp_main->conf.acs_passwd), "%s", get_value_from_uci_option(acs_tb[UCI_ACS_PASSWR]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs password: %s", cwmp_main->conf.acs_passwd);
snprintf(cwmp_main->conf.acs_ssl_capath, sizeof(cwmp_main->conf.acs_ssl_capath), "%s", get_value_from_uci_option(acs_tb[UCI_ACS_SSL_CAPATH]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs ssl capath: %s", cwmp_main->conf.acs_ssl_capath);
cwmp_main->conf.retry_min_wait_interval = DEFAULT_RETRY_MINIMUM_WAIT_INTERVAL;
char *acs_retry_min_wait_interval = get_value_from_uci_option(acs_tb[UCI_ACS_RETRY_MIN_WAIT_INTERVAL]);
char *acs_dhcp_retry_min_wait_interval = get_value_from_uci_option(acs_tb[UCI_ACS_DHCP_RETRY_MIN_WAIT_INTERVAL]);
char *op_interval = cwmp_main->conf.dhcp_discovery ? acs_dhcp_retry_min_wait_interval : acs_retry_min_wait_interval;
if (strlen(op_interval) != 0) {
if (cwmp_main->conf.amd_version >= AMD_3) {
int a = atoi(op_interval);
cwmp_main->conf.retry_min_wait_interval = (a <= 65535 && a >= 1) ? a : DEFAULT_RETRY_MINIMUM_WAIT_INTERVAL;
}
}
CWMP_LOG(DEBUG, "CWMP CONFIG - acs retry minimum wait interval: %d", cwmp_main->conf.retry_min_wait_interval);
cwmp_main->conf.retry_interval_multiplier = DEFAULT_RETRY_INTERVAL_MULTIPLIER;
char *acs_retry_interval_multiplier = get_value_from_uci_option(acs_tb[UCI_ACS_RETRY_INTERVAL_MULTIPLIER]);
char *acs_dhcp_retry_interval_multiplier = get_value_from_uci_option(acs_tb[UCI_ACS_DHCP_RETRY_INTERVAL_MULTIPLIER]);
char *op_multi = cwmp_main->conf.dhcp_discovery ? acs_dhcp_retry_interval_multiplier : acs_retry_interval_multiplier;
if (strlen(op_multi) != 0) {
if (cwmp_main->conf.amd_version >= AMD_3) {
int a = atoi(op_multi);
cwmp_main->conf.retry_interval_multiplier = (a <= 65535 && a >= 1000) ? a : DEFAULT_RETRY_INTERVAL_MULTIPLIER;
}
}
CWMP_LOG(DEBUG, "CWMP CONFIG - acs retry interval multiplier: %d", cwmp_main->conf.retry_interval_multiplier);
cwmp_main->conf.compression = COMP_NONE;
char *acs_comp = get_value_from_uci_option(acs_tb[UCI_ACS_COMPRESSION]);
if (cwmp_main->conf.amd_version >= AMD_5 && strlen(acs_comp) != 0) {
if (strcasecmp(acs_comp, "gzip") == 0) {
cwmp_main->conf.compression = COMP_GZIP;
} else if (strcasecmp(acs_comp, "deflate") == 0) {
cwmp_main->conf.compression = COMP_DEFLATE;
} else {
cwmp_main->conf.compression = COMP_NONE;
}
}
cwmp_main->conf.time = 0;
char *time = get_value_from_uci_option(acs_tb[UCI_ACS_PERIODIC_INFORM_TIME]);
if (strlen(time) != 0) {
cwmp_main->conf.time = convert_datetime_to_timestamp(time);
}
cwmp_main->conf.period = PERIOD_INFORM_DEFAULT;
char *inform_interval = get_value_from_uci_option(acs_tb[UCI_ACS_PERIODIC_INFORM_INTERVAL]);
if (strlen(inform_interval) != 0) {
int a = atoi(inform_interval);
cwmp_main->conf.period = (a >= PERIOD_INFORM_MIN) ? a : PERIOD_INFORM_DEFAULT;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - acs periodic inform: %d", cwmp_main->conf.period);
cwmp_main->conf.periodic_enable = str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_PERIODIC_INFORM_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs periodic enable: %d", cwmp_main->conf.periodic_enable);
cwmp_main->conf.heart_beat_enable = str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_HEARTBEAT_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - acs heart beat enable: %d", cwmp_main->conf.heart_beat_enable);
cwmp_main->conf.heartbeat_interval = 30;
char *heartbeat_interval = get_value_from_uci_option(acs_tb[UCI_ACS_HEARTBEAT_INTERVAL]);
if (strlen(heartbeat_interval) != 0) {
int a = atoi(heartbeat_interval);
cwmp_main->conf.heartbeat_interval = a;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - acs heartbeat interval: %d", cwmp_main->conf.heartbeat_interval);
cwmp_main->conf.heart_time = 0;
char *heartbeat_time = get_value_from_uci_option(acs_tb[UCI_ACS_HEARTBEAT_TIME]);
if (strlen(heartbeat_time) != 0) {
cwmp_main->conf.heart_time = convert_datetime_to_timestamp(heartbeat_time);
}
}
static void config_get_cpe_elements(struct uci_section *s)
{
enum {
UCI_CPE_CON_REQ_TIMEOUT,
UCI_CPE_USER_ID,
UCI_CPE_PASSWD,
UCI_CPE_PORT,
UCI_CPE_CRPATH,
UCI_CPE_NOTIFY_PERIODIC_ENABLE,
UCI_CPE_NOTIFY_PERIOD,
UCI_CPE_SCHEDULE_REBOOT,
UCI_CPE_DELAY_REBOOT,
UCI_CPE_ACTIVE_NOTIF_THROTTLE,
UCI_CPE_MANAGEABLE_DEVICES_NOTIF_LIMIT,
UCI_CPE_SESSION_TIMEOUT,
UCI_CPE_INSTANCE_MODE,
UCI_CPE_JSON_CUSTOM_NOTIFY_FILE,
UCI_CPE_JSON_FORCED_INFORM_FILE,
UCI_CPE_FORCE_IPV4,
UCI_CPE_KEEP_SETTINGS,
__MAX_NUM_UCI_CPE_ATTRS,
};
const struct uci_parse_option cpe_opts[] = {
[UCI_CPE_USER_ID] = { .name = "userid", .type = UCI_TYPE_STRING },
[UCI_CPE_PASSWD] = { .name = "passwd", .type = UCI_TYPE_STRING },
[UCI_CPE_PORT] = { .name = "port", .type = UCI_TYPE_STRING },
[UCI_CPE_CRPATH] = { .name = "path", .type = UCI_TYPE_STRING },
[UCI_CPE_NOTIFY_PERIODIC_ENABLE] = { .name = "periodic_notify_enable", .type = UCI_TYPE_STRING },
[UCI_CPE_NOTIFY_PERIOD] = { .name = "periodic_notify_interval", .type = UCI_TYPE_STRING },
[UCI_CPE_SCHEDULE_REBOOT] = { .name = "schedule_reboot", .type = UCI_TYPE_STRING },
[UCI_CPE_DELAY_REBOOT] = { .name = "delay_reboot", .type = UCI_TYPE_STRING },
[UCI_CPE_ACTIVE_NOTIF_THROTTLE] = { .name = "active_notif_throttle", .type = UCI_TYPE_STRING },
[UCI_CPE_MANAGEABLE_DEVICES_NOTIF_LIMIT] = { .name = "md_notif_limit", .type = UCI_TYPE_STRING },
[UCI_CPE_SESSION_TIMEOUT] = { .name = "session_timeout", .type = UCI_TYPE_STRING },
[UCI_CPE_INSTANCE_MODE] = { .name = "instance_mode", .type = UCI_TYPE_STRING },
[UCI_CPE_JSON_CUSTOM_NOTIFY_FILE] = { .name = "custom_notify_json", .type = UCI_TYPE_STRING },
[UCI_CPE_JSON_FORCED_INFORM_FILE] = { .name = "forced_inform_json", .type = UCI_TYPE_STRING },
[UCI_CPE_CON_REQ_TIMEOUT] = { .name = "cr_timeout", .type = UCI_TYPE_STRING },
[UCI_CPE_FORCE_IPV4] = { .name = "force_ipv4", .type = UCI_TYPE_STRING },
[UCI_CPE_KEEP_SETTINGS] = { .name = "fw_upgrade_keep_settings", .type = UCI_TYPE_STRING }
};
struct uci_option *cpe_tb[__MAX_NUM_UCI_CPE_ATTRS];
CWMP_MEMSET(cpe_tb, 0, sizeof(cpe_tb));
uci_parse_section(s, cpe_opts, __MAX_NUM_UCI_CPE_ATTRS, cpe_tb);
snprintf(cwmp_main->conf.cpe_userid, sizeof(cwmp_main->conf.cpe_userid), "%s", get_value_from_uci_option(cpe_tb[UCI_CPE_USER_ID]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe username: %s", cwmp_main->conf.cpe_userid);
snprintf(cwmp_main->conf.cpe_passwd, sizeof(cwmp_main->conf.cpe_passwd), "%s", get_value_from_uci_option(cpe_tb[UCI_CPE_PASSWD]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe password: %s", cwmp_main->conf.cpe_passwd);
cwmp_main->conf.cr_timeout = DEFAULT_CR_TIMEOUT;
char *tm_out = get_value_from_uci_option(cpe_tb[UCI_CPE_CON_REQ_TIMEOUT]);
if (strlen(tm_out) != 0) {
int a = strtod(tm_out, NULL);
if (a > 0) {
cwmp_main->conf.cr_timeout = a;
}
}
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe connection request timeout: %d", cwmp_main->conf.cr_timeout);
cwmp_main->conf.connection_request_port = DEFAULT_CONNECTION_REQUEST_PORT;
char *port = get_value_from_uci_option(cpe_tb[UCI_CPE_PORT]);
if (strlen(port) != 0) {
int a = atoi(port);
cwmp_main->conf.connection_request_port = (a != 0) ? a : DEFAULT_CONNECTION_REQUEST_PORT;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe connection request port: %d", cwmp_main->conf.connection_request_port);
char *crpath = get_value_from_uci_option(cpe_tb[UCI_CPE_CRPATH]);
snprintf(cwmp_main->conf.connection_request_path, sizeof(cwmp_main->conf.connection_request_path), "%s", strlen(crpath) ? (*crpath == '/') ? crpath + 1 : crpath : "/");
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe connection request path: %s", cwmp_main->conf.connection_request_path);
cwmp_main->conf.periodic_notify_enable = str_to_bool(get_value_from_uci_option(cpe_tb[UCI_CPE_NOTIFY_PERIODIC_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe periodic notify enable: %d", cwmp_main->conf.periodic_notify_enable);
cwmp_main->conf.periodic_notify_interval = DEFAULT_NOTIFY_PERIOD;
char *notify_period = get_value_from_uci_option(cpe_tb[UCI_CPE_NOTIFY_PERIOD]);
if (strlen(notify_period) != 0) {
int a = atoi(notify_period);
cwmp_main->conf.periodic_notify_interval = (a != 0) ? a : DEFAULT_NOTIFY_PERIOD;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe periodic notify interval: %d", cwmp_main->conf.periodic_notify_interval);
cwmp_main->conf.schedule_reboot = 0;
char *schedule_reboot = get_value_from_uci_option(cpe_tb[UCI_CPE_SCHEDULE_REBOOT]);
if (strlen(schedule_reboot) != 0) {
cwmp_main->conf.schedule_reboot = convert_datetime_to_timestamp(schedule_reboot);
}
cwmp_main->conf.delay_reboot = -1;
char *delay_reboot = get_value_from_uci_option(cpe_tb[UCI_CPE_DELAY_REBOOT]);
if (strlen(delay_reboot) != 0) {
int a = atoi(delay_reboot);
cwmp_main->conf.delay_reboot = (a > 0) ? a : -1;
}
cwmp_main->conf.active_notif_throttle = 0;
char *notify_thottle = get_value_from_uci_option(cpe_tb[UCI_CPE_ACTIVE_NOTIF_THROTTLE]);
if (strlen(notify_thottle) != 0) {
int a = atoi(notify_thottle);
cwmp_main->conf.active_notif_throttle = (a > 0) ? a : 0;
}
cwmp_main->conf.md_notif_limit = 0;
char *notify_limit = get_value_from_uci_option(cpe_tb[UCI_CPE_MANAGEABLE_DEVICES_NOTIF_LIMIT]);
if (strlen(notify_limit) != 0) {
int a = atoi(notify_limit);
cwmp_main->conf.md_notif_limit = (a > 0) ? a : 0;
}
cwmp_main->conf.session_timeout = DEFAULT_SESSION_TIMEOUT;
char *session_timeout = get_value_from_uci_option(cpe_tb[UCI_CPE_SESSION_TIMEOUT]);
if (strlen(session_timeout) != 0) {
int a = atoi(session_timeout);
cwmp_main->conf.session_timeout = (a >= 1) ? a : DEFAULT_SESSION_TIMEOUT;
}
cwmp_main->conf.instance_mode = DEFAULT_INSTANCE_MODE;
char *instance_mode = get_value_from_uci_option(cpe_tb[UCI_CPE_INSTANCE_MODE]);
if (strlen(instance_mode) != 0) {
if (CWMP_STRCMP(instance_mode, "InstanceNumber") == 0) {
cwmp_main->conf.instance_mode = INSTANCE_MODE_NUMBER;
} else {
cwmp_main->conf.instance_mode = INSTANCE_MODE_ALIAS;
}
}
snprintf(cwmp_main->conf.custom_notify_json, sizeof(cwmp_main->conf.custom_notify_json), "%s", get_value_from_uci_option(cpe_tb[UCI_CPE_JSON_CUSTOM_NOTIFY_FILE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe custom notify json path: %s", cwmp_main->conf.custom_notify_json);
snprintf(cwmp_main->conf.forced_inform_json, sizeof(cwmp_main->conf.forced_inform_json), "%s", get_value_from_uci_option(cpe_tb[UCI_CPE_JSON_FORCED_INFORM_FILE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe forced inform json path: %s", cwmp_main->conf.forced_inform_json);
cwmp_main->conf.force_ipv4 = str_to_bool(get_value_from_uci_option(cpe_tb[UCI_CPE_FORCE_IPV4]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe force ipv4 enable: %d", cwmp_main->conf.force_ipv4);
cwmp_main->conf.fw_upgrade_keep_settings = cpe_tb[UCI_CPE_KEEP_SETTINGS] ? str_to_bool(get_value_from_uci_option(cpe_tb[UCI_CPE_KEEP_SETTINGS])) : true;
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe keep settings enable: %d", cwmp_main->conf.fw_upgrade_keep_settings);
}
static void config_get_lwn_elements(struct uci_section *s)
{
enum {
UCI_LWN_ENABLE,
UCI_LWN_HOSTNAME,
UCI_LWN_PORT,
__MAX_NUM_UCI_LWN_ATTRS,
};
const struct uci_parse_option acs_opts[] = {
[UCI_LWN_ENABLE] = { .name = "enable", .type = UCI_TYPE_STRING },
[UCI_LWN_HOSTNAME] = { .name = "hostname", .type = UCI_TYPE_STRING },
[UCI_LWN_PORT] = { .name = "port", .type = UCI_TYPE_STRING },
};
struct uci_option *lwn_tb[__MAX_NUM_UCI_LWN_ATTRS];
CWMP_MEMSET(lwn_tb, 0, sizeof(lwn_tb));
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_LWN_ATTRS, lwn_tb);
cwmp_main->conf.lwn_enable = str_to_bool(get_value_from_uci_option(lwn_tb[UCI_LWN_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - lwn enable: %d", cwmp_main->conf.lwn_enable);
snprintf(cwmp_main->conf.lwn_hostname, sizeof(cwmp_main->conf.lwn_hostname), "%s", get_value_from_uci_option(lwn_tb[UCI_LWN_HOSTNAME]));
CWMP_LOG(DEBUG, "CWMP CONFIG - lwn hostname: %s", cwmp_main->conf.lwn_hostname);
cwmp_main->conf.lwn_port = DEFAULT_LWN_PORT;
char *port = get_value_from_uci_option(lwn_tb[UCI_LWN_PORT]);
if (strlen(port) != 0) {
int a = atoi(port);
cwmp_main->conf.lwn_port = a;
}
CWMP_LOG(DEBUG, "CWMP CONFIG - lwn port: %d", cwmp_main->conf.lwn_port);
}
static void config_get_tc_elements(struct uci_section *s)
{
enum {
UCI_TC_ENABLE,
UCI_TC_TRANSFERTYPE,
UCI_TC_RESULTTYPE,
UCI_TC_FILETYPE,
__MAX_NUM_UCI_TC_ATTRS,
};
const struct uci_parse_option acs_opts[] = {
[UCI_TC_ENABLE] = { .name = "enable", .type = UCI_TYPE_STRING },
[UCI_TC_TRANSFERTYPE] = { .name = "transfer_type", .type = UCI_TYPE_STRING },
[UCI_TC_RESULTTYPE] = { .name = "result_type", .type = UCI_TYPE_STRING },
[UCI_TC_FILETYPE] = { .name = "file_type", .type = UCI_TYPE_STRING },
};
struct uci_option *tc_tb[__MAX_NUM_UCI_TC_ATTRS];
CWMP_MEMSET(tc_tb, 0, sizeof(tc_tb));
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_TC_ATTRS, tc_tb);
cwmp_main->conf.auto_tc_enable = str_to_bool(get_value_from_uci_option(tc_tb[UCI_TC_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - tc enable: %d", cwmp_main->conf.auto_tc_enable);
snprintf(cwmp_main->conf.auto_tc_transfer_type, sizeof(cwmp_main->conf.auto_tc_transfer_type), "%s", get_value_from_uci_option(tc_tb[UCI_TC_TRANSFERTYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - tc transfer type: %s", cwmp_main->conf.auto_tc_transfer_type);
snprintf(cwmp_main->conf.auto_tc_result_type, sizeof(cwmp_main->conf.auto_tc_result_type), "%s", get_value_from_uci_option(tc_tb[UCI_TC_RESULTTYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - tc result type: %s", cwmp_main->conf.auto_tc_result_type);
snprintf(cwmp_main->conf.auto_tc_file_type, sizeof(cwmp_main->conf.auto_tc_file_type), "%s", get_value_from_uci_option(tc_tb[UCI_TC_FILETYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - tc file type: %s", cwmp_main->conf.auto_tc_file_type);
}
static void config_get_cds_elements(struct uci_section *s)
{
enum {
UCI_CDS_ENABLE,
UCI_CDS_OPTYPE,
UCI_CDS_RESULTYPE,
UCI_CDS_FAULTCODE,
__MAX_NUM_UCI_CDS_ATTRS,
};
const struct uci_parse_option cdu_opts[] = {
[UCI_CDS_ENABLE] = { .name = "enable", .type = UCI_TYPE_STRING },
[UCI_CDS_OPTYPE] = { .name = "operation_type", .type = UCI_TYPE_STRING },
[UCI_CDS_RESULTYPE] = { .name = "result_type", .type = UCI_TYPE_STRING },
[UCI_CDS_FAULTCODE] = { .name = "fault_code", .type = UCI_TYPE_STRING },
};
struct uci_option *cds_tb[__MAX_NUM_UCI_CDS_ATTRS];
CWMP_MEMSET(cds_tb, 0, sizeof(cds_tb));
uci_parse_section(s, cdu_opts, __MAX_NUM_UCI_CDS_ATTRS, cds_tb);
cwmp_main->conf.auto_cdu_enable = str_to_bool(get_value_from_uci_option(cds_tb[UCI_CDS_ENABLE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cds enable: %d", cwmp_main->conf.auto_cdu_enable);
snprintf(cwmp_main->conf.auto_cdu_oprt_type, sizeof(cwmp_main->conf.auto_cdu_oprt_type), "%s", get_value_from_uci_option(cds_tb[UCI_CDS_OPTYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cds operation type: %s", cwmp_main->conf.auto_cdu_oprt_type);
snprintf(cwmp_main->conf.auto_cdu_result_type, sizeof(cwmp_main->conf.auto_cdu_result_type), "%s", get_value_from_uci_option(cds_tb[UCI_CDS_RESULTYPE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cds result type: %s", cwmp_main->conf.auto_cdu_result_type);
snprintf(cwmp_main->conf.auto_cdu_fault_code, sizeof(cwmp_main->conf.auto_cdu_fault_code), "%s", get_value_from_uci_option(cds_tb[UCI_CDS_FAULTCODE]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cds fault type: %s", cwmp_main->conf.auto_cdu_fault_code);
}
static int _export_uci_package(struct uci_context *uci_ctx, char *package, const char *output_path)
{
struct uci_ptr ptr = { 0 };
int ret = 0;
if (output_path == NULL)
return -1;
FILE *out = fopen(output_path, "a");
if (!out)
return -1;
if (uci_ctx == NULL) {
ret = -1;
goto end;
}
if (uci_lookup_ptr(uci_ctx, &ptr, package, true) != UCI_OK) {
ret = -1;
goto end;
}
if (uci_export(uci_ctx, out, ptr.p, true) != UCI_OK)
ret = -1;
end:
fclose(out);
return ret;
}
// PUBLIC ##
int export_uci_package(char *package, const char *output_path)
{
struct uci_context *uci_ctx = NULL;
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
goto end;
}
_export_uci_package(uci_ctx, package, output_path);
end:
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return 0;
}
int export_std_uci(const char *output_path)
{
struct uci_context *uci_ctx = NULL;
char **configs = NULL;
char **p;
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
goto end;
}
if (uci_list_configs(uci_ctx, &configs) != UCI_OK) {
goto end;
}
if (configs == NULL) {
goto end;
}
for (p = configs; *p; p++) {
_export_uci_package(uci_ctx, *p, output_path);
}
end:
FREE(configs);
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return 0;
}
int import_uci_package(char *package_name, const char *input_path)
{
struct uci_context *uci_ctx = NULL;
struct uci_package *package = NULL;
struct uci_element *e = NULL;
int ret = CWMP_OK;
FILE *input;
if (CWMP_STRLEN(input_path) == 0) {
return -1;
}
input = fopen(input_path, "r");
if (!input)
return -1;
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
goto end;
}
if (uci_import(uci_ctx, input, package_name, &package, (package_name != NULL)) != UCI_OK) {
ret = -1;
goto end;
}
uci_foreach_element(&uci_ctx->root, e)
{
struct uci_package *p = uci_to_package(e);
if (uci_commit(uci_ctx, &p, true) != UCI_OK) {
ret |= CWMP_GEN_ERR;
}
}
end:
if (uci_ctx) {
uci_free_context(uci_ctx);
}
fclose(input);
pthread_mutex_unlock(&mutex_config_load);
return ret;
}
int get_uci_path_value(const char *conf_dir, char *path, char *value, size_t max_value_len)
{
struct uci_context *uci_ctx = NULL;
struct uci_ptr ptr;
int ret = UCI_ERR_NOTFOUND;
char *str = NULL;
if (!path || !value || max_value_len == 0) {
CWMP_LOG(ERROR, "Invalid input options");
return -1;
}
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
CWMP_LOG(ERROR, "Failed to get uci context");
ret = -1;
goto exit;
}
if (conf_dir) {
uci_set_confdir(uci_ctx, conf_dir);
}
str = CWMP_STRDUP(path);
if (uci_lookup_ptr(uci_ctx, &ptr, str, true) != UCI_OK) {
CWMP_LOG(INFO, "Failed to loopup uci [%s]", path);
ret = UCI_ERR_NOTFOUND;
goto exit;
}
if ((ptr.flags & UCI_LOOKUP_COMPLETE)
&& (ptr.o != NULL)
&& (ptr.o->v.string!=NULL)) {
ret = 0;
CWMP_STRNCPY(value, ptr.o->v.string, max_value_len);
}
exit:
FREE(str);
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return ret;
}
int get_uci_dm_list(const char *conf_dir, char *path, struct list_head *head, int notif_type)
{
struct uci_context *uci_ctx = NULL;
struct uci_ptr ptr;
int ret = 0;
char *str = NULL;
if (!path) {
return -1;
}
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
CWMP_LOG(ERROR, "Failed to get uci context");
goto exit;
}
if (conf_dir) {
uci_set_confdir(uci_ctx, conf_dir);
}
str = CWMP_STRDUP(path);
if (uci_lookup_ptr(uci_ctx, &ptr, str, true) != UCI_OK) {
ret = -1;
goto exit;
}
if ((ptr.flags & UCI_LOOKUP_COMPLETE) && (ptr.o != NULL) && (ptr.o->type == UCI_TYPE_LIST)) {
struct uci_element *e;
uci_foreach_element(&ptr.o->v.list, e) {
add_dm_parameter_to_list(head, e->name, "", "", notif_type, false);
}
ret = 0;
}
exit:
FREE(str);
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return ret;
}
int set_uci_path_value(const char *conf_dir, char *path, char *value)
{
struct uci_context *uci_ctx = NULL;
struct uci_ptr ptr;
int ret = -1;
char str[BUF_SIZE_256] = {0};
if ((CWMP_STRLEN(path) == 0) || (CWMP_STRLEN(value) == 0)) {
CWMP_LOG(ERROR, "Invalid input options");
return -1;
}
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
CWMP_LOG(ERROR, "Failed to get uci context");
goto exit;
}
if (conf_dir) {
uci_set_confdir(uci_ctx, conf_dir);
}
snprintf(str, BUF_SIZE_256, "%s=%s", path, value);
if (uci_lookup_ptr(uci_ctx, &ptr, str, true) != UCI_OK) {
ret = -1;
goto exit;
}
ret = uci_set(uci_ctx, &ptr);
if (ret == UCI_OK) {
ret = uci_save(uci_ctx, ptr.p);
}
if (ret == UCI_OK) {
ret = uci_commit(uci_ctx, &ptr.p, false);
}
exit:
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return ret;
}
int del_uci_list_value(const char *conf_dir, char *path, char *value)
{
struct uci_context *uci_ctx = NULL;
struct uci_ptr ptr;
int ret = 0;
char str[BUF_SIZE_256] = {0};
if ((CWMP_STRLEN(path) == 0) || (CWMP_STRLEN(value) == 0))
return -1;
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
goto exit;
}
if (conf_dir) {
uci_set_confdir(uci_ctx, conf_dir);
}
snprintf(str, BUF_SIZE_256, "%s=%s", path, value);
if (uci_lookup_ptr(uci_ctx, &ptr, str, true) != UCI_OK) {
ret = -1;
goto exit;
}
ret = uci_del_list(uci_ctx, &ptr);
if (ret == UCI_OK) {
ret = uci_save(uci_ctx, ptr.p);
}
if (ret == UCI_OK) {
ret = uci_commit(uci_ctx, &ptr.p, false);
}
exit:
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return ret;
}
int set_uci_list_value(const char *conf_dir, char *path, char *value)
{
struct uci_context *uci_ctx = NULL;
struct uci_ptr ptr;
int ret = 0;
char str[BUF_SIZE_256] = {0};
if ((CWMP_STRLEN(path) == 0) || (CWMP_STRLEN(value) == 0))
return -1;
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
goto exit;
}
if (conf_dir) {
uci_set_confdir(uci_ctx, conf_dir);
}
snprintf(str, BUF_SIZE_256, "%s=%s", path, value);
if (uci_lookup_ptr(uci_ctx, &ptr, str, true) != UCI_OK) {
ret = -1;
goto exit;
}
ret = uci_add_list(uci_ctx, &ptr);
if (ret == UCI_OK) {
ret = uci_save(uci_ctx, ptr.p);
}
if (ret == UCI_OK) {
ret = uci_commit(uci_ctx, &ptr.p, false);
}
exit:
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return ret;
}
int get_global_config()
{
struct uci_context *uci_ctx = NULL;
struct uci_package *pkg;
struct uci_element *e;
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (uci_ctx == NULL) {
goto exit;
}
if (uci_load(uci_ctx, "cwmp", &pkg)) {
goto exit;
}
uci_foreach_element(&pkg->sections, e) {
struct uci_section *s = uci_to_section(e);
if (s == NULL || s->type == NULL)
continue;
if (CWMP_STRCMP(s->type, "acs") == 0) {
config_get_acs_elements(s);
} else if (CWMP_STRCMP(s->type, "cpe") == 0) {
config_get_cpe_elements(s);
} else if (CWMP_STRCMP(s->type, "lwn") == 0) {
config_get_lwn_elements(s);
} else if (CWMP_STRCMP(s->type, "transfer_complete") == 0) {
config_get_tc_elements(s);
} else if (CWMP_STRCMP(s->type, "du_state_change") == 0) {
config_get_cds_elements(s);
}
}
exit:
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return CWMP_OK;
}
int get_inform_parameters_uci(struct list_head *inform_head)
{
struct uci_context *uci_ctx = NULL;
struct uci_package *pkg;
int ret = 0;
pthread_mutex_lock(&mutex_config_load);
uci_ctx = uci_alloc_context();
if (!uci_ctx) {
ret = -1;
goto exit;
}
if (uci_load(uci_ctx, "cwmp", &pkg)) {
ret = -1;
goto exit;
}
struct uci_element *e;
uci_foreach_element(&pkg->sections, e) {
char enable[BUF_SIZE_8] = {0};
char parameter_name[BUF_SIZE_256] = {0};
char events_str_list[BUF_SIZE_256] = {0};
struct uci_section *s = uci_to_section(e);
if (CWMP_STRCMP(s->type, "inform_parameter") != 0) {
continue;
}
_uci_get_value_by_section_string(s, "enable", enable, BUF_SIZE_8);
_uci_get_value_by_section_string(s, "parameter_name", parameter_name, BUF_SIZE_256);
_uci_get_value_by_section_string(s, "events_list", events_str_list, BUF_SIZE_256);
add_dm_parameter_to_list(inform_head, parameter_name, events_str_list, "", 0, str_to_bool(enable));
}
exit:
if (uci_ctx) {
uci_free_context(uci_ctx);
}
pthread_mutex_unlock(&mutex_config_load);
return ret;
}

45
src/uci_utils.h Normal file
View file

@ -0,0 +1,45 @@
/*
* uci_utils.h - API to manage UCI packages/sections/options
*
* Copyright (C) 2021-2022, IOPSYS Software Solutions AB.
*
* See LICENSE file for license related information.
*
*/
#ifndef __UCI_UTILS_H
#define __UCI_UTILS_H
#include <uci.h>
#include <libubox/list.h>
#define ETC_DB_CONFIG "/etc/board-db/config"
#define UCI_CONFIG_DIR "/etc/config/"
#define VARSTATE_CONFIG "/var/state"
#define ICWMPD_CONFIG "/etc/icwmpd"
#define DHCP_OPTION_READ_MAX_RETRY 5
#define UCI_OPTION_READ_INTERVAL 5
#define section_name(s) s ? (s)->e.name : ""
struct strNode {
struct list_head list;
char path[BUF_SIZE_256];
};
void add_str_list(struct list_head *head, char *str);
void free_str_list(struct list_head *head);
int export_uci_package(char *package, const char *output_path);
int export_std_uci(const char *output_path);
int import_uci_package(char *package_name, const char *input_path);
int get_uci_path_value(const char *conf_dir, char *path, char *value, size_t max_value_len);
int get_uci_dm_list(const char *conf_dir, char *path, struct list_head *head, int notif_type);
int set_uci_path_value(const char *conf_dir, char *path, char *value);
int set_uci_list_value(const char *conf_dir, char *path, char *value);
int del_uci_list_value(const char *conf_dir, char *path, char *value);
int get_inform_parameters_uci(struct list_head *inform_head);
int get_global_config();
#endif

View file

@ -18,9 +18,9 @@
#include "log.h" #include "log.h"
#include "backupSession.h" #include "backupSession.h"
#include "event.h" #include "event.h"
#include "cwmp_uci.h"
#include "subprocess.h" #include "subprocess.h"
#include "session.h" #include "session.h"
#include "uci_utils.h"
#define CURL_TIMEOUT 30 #define CURL_TIMEOUT 30
@ -223,9 +223,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
if (pupload->file_type[0] == '1') { if (pupload->file_type[0] == '1') {
snprintf(file_path, sizeof(file_path), "%s/all_configs", ICWMP_TMP_PATH); snprintf(file_path, sizeof(file_path), "%s/all_configs", ICWMP_TMP_PATH);
cwmp_uci_init(); export_std_uci(file_path);
cwmp_uci_export(file_path, UCI_STANDARD_CONFIG);
cwmp_uci_exit();
} else if (pupload->file_type[0] == '2') { } else if (pupload->file_type[0] == '2') {
lookup_vlf_name(1, &name); lookup_vlf_name(1, &name);
if (name && strlen(name) > 0) { if (name && strlen(name) > 0) {
@ -243,9 +241,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
lookup_vcf_name(pupload->f_instance, &name); lookup_vcf_name(pupload->f_instance, &name);
if (name && strlen(name) > 0) { if (name && strlen(name) > 0) {
snprintf(file_path, sizeof(file_path), "%s/%s", ICWMP_TMP_PATH, name); snprintf(file_path, sizeof(file_path), "%s/%s", ICWMP_TMP_PATH, name);
cwmp_uci_init(); export_uci_package(name, file_path);
cwmp_uci_export_package(name, file_path, UCI_STANDARD_CONFIG);
cwmp_uci_exit();
FREE(name); FREE(name);
} else { } else {
error = FAULT_CPE_UPLOAD_FAILURE; error = FAULT_CPE_UPLOAD_FAILURE;

View file

@ -1,7 +1,7 @@
LIB_LDFLAGS:= -lmxml -luci -lblobmsg_json -lubox\ LIB_LDFLAGS:= -lmxml -luci -lblobmsg_json -lubox\
-ljson-c -lubus -lpthread -lcurl\ -ljson-c -lubus -lpthread -lcurl\
-lcrypto -luuid -lcrypto -luuid -lm
LIB_CFLAGS:= -fPIC -I../../ -DLOPENSSL -g -O0 LIB_CFLAGS:= -fPIC -I../../ -DLOPENSSL -g -O0
UNIT_TESTS:= icwmp_unit_testd UNIT_TESTS:= icwmp_unit_testd

View file

@ -22,7 +22,6 @@
#include "xml.h" #include "xml.h"
#include "config.h" #include "config.h"
#include "event.h" #include "event.h"
#include "cwmp_uci.h"
#include "cwmp_cli.h" #include "cwmp_cli.h"
static char *add_instance = NULL; static char *add_instance = NULL;

View file

@ -22,6 +22,7 @@
#include "rpc.h" #include "rpc.h"
#include "session.h" #include "session.h"
#include "log.h" #include "log.h"
#include "uci_utils.h"
static LIST_HEAD(list_set_param_value); static LIST_HEAD(list_set_param_value);
static LIST_HEAD(faults_array); static LIST_HEAD(faults_array);
@ -32,7 +33,7 @@ static int dm_iface_unit_tests_init(void **state)
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp)); cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
create_cwmp_session_structure(); create_cwmp_session_structure();
cwmp_session_init(); cwmp_session_init();
global_conf_init(); get_global_config();
return 0; return 0;
} }

View file

@ -16,7 +16,7 @@
#include "common.h" #include "common.h"
#include "notifications.h" #include "notifications.h"
#include "cwmp_uci.h" #include "uci_utils.h"
#include "session.h" #include "session.h"
/* /*
@ -101,24 +101,30 @@ static int get_parameter_notification_from_list_head(struct list_head *params_li
static int get_parameter_notification_from_notifications_uci_list(char *parameter_name) static int get_parameter_notification_from_notifications_uci_list(char *parameter_name)
{ {
int i, notification = 0; int i, notification = 0;
struct uci_list *list_notif;
struct uci_element *e;
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
int option_type; char *parent_param = NULL;
option_type = cwmp_uci_get_option_value_list("cwmp_notifications", "@notifications[0]", notifications_test[i], UCI_ETCICWMPD_CONFIG, &list_notif); char notif_path[BUF_SIZE_256] = {0};
if (list_notif) { LIST_HEAD(local_notify_list);
uci_foreach_element(list_notif, e) { struct cwmp_dm_parameter *param_iter = NULL;
if (strcmp(e->name, parameter_name) == 0) {
notification = i; snprintf(notif_path, BUF_SIZE_256, "cwmp_notifications.notifications.%s", notifications_test[i]);
break; get_uci_dm_list(ICWMPD_CONFIG, notif_path, &local_notify_list, i);
}
list_for_each_entry(param_iter, &local_notify_list, list) {
if (CWMP_STRLEN(param_iter->name) == 0)
continue;
if (strcmp(param_iter->name, parameter_name) == 0) {
notification = i;
break;
} }
} }
if (option_type == UCI_TYPE_STRING) cwmp_free_all_dm_parameter_list(&local_notify_list);
cwmp_free_uci_list(list_notif);
if(notification > 0) if(notification > 0)
break; break;
} }
return notification; return notification;
} }

View file

@ -23,8 +23,8 @@
#include "backupSession.h" #include "backupSession.h"
#include "log.h" #include "log.h"
#include "download.h" #include "download.h"
#include "cwmp_uci.h"
#include "xml.h" #include "xml.h"
#include "uci_utils.h"
#include "icwmp_soap_msg_unit_test.h" #include "icwmp_soap_msg_unit_test.h"
#include "cwmp_event.h" #include "cwmp_event.h"

View file

@ -10,109 +10,77 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <setjmp.h> #include <setjmp.h>
#include <cmocka.h> #include <cmocka.h>
#include <dirent.h>
#include "common.h" #include "common.h"
#include "cwmp_uci.h" #include "uci_utils.h"
#define UCI_WRONG_PATH "cwmp.wrong_section.wrong_option" #define UCI_WRONG_PATH "cwmp.wrong_section.wrong_option"
#define UCI_VAR_WRONG_PATH "icwmp.wrong_section.wrong_option" #define UCI_VAR_WRONG_PATH "icwmp.wrong_section.wrong_option"
static struct uci_list *list = NULL;
static int cwmp_uci_unit_tests_init(void **state) static int cwmp_uci_unit_tests_init(void **state)
{ {
cwmp_uci_init();
return 0; return 0;
} }
static int cwmp_uci_unit_tests_clean(void **state) static int cwmp_uci_unit_tests_clean(void **state)
{ {
icwmp_cleanmem(); icwmp_cleanmem();
cwmp_uci_exit();
if (list != NULL)
cwmp_free_uci_list(list);
return 0; return 0;
} }
static void cwmp_uci_get_tests(void **state) static void cwmp_uci_get_tests(void **state)
{ {
char *value = NULL; char value[BUF_SIZE_256] = {0};
int error; int error;
error = uci_get_value("cwmp.acs.userid", &value); error = get_uci_path_value(NULL, "cwmp.acs.userid", value, BUF_SIZE_256);
assert_int_equal(error, UCI_OK); assert_int_equal(error, UCI_OK);
assert_string_equal(value, "iopsys"); assert_string_equal(value, "iopsys");
error = uci_get_value(UCI_WRONG_PATH, &value); value[0] = '\0';
error = get_uci_path_value(NULL, UCI_WRONG_PATH, value, BUF_SIZE_256);
assert_int_equal(error, UCI_ERR_NOTFOUND); assert_int_equal(error, UCI_ERR_NOTFOUND);
assert_null(value); assert_string_equal(value, "");
error = uci_get_state_value("icwmp.acs.dhcp_url", &value); value[0] = '\0';
error = get_uci_path_value(VARSTATE_CONFIG, "icwmp.acs.dhcp_url", value, BUF_SIZE_256);
assert_int_equal(error, UCI_OK); assert_int_equal(error, UCI_OK);
assert_string_equal(value, "http://192.168.103.160:8080/openacs/acs"); assert_string_equal(value, "http://192.168.103.160:8080/openacs/acs");
error = uci_get_state_value(UCI_VAR_WRONG_PATH, &value); value[0] = '\0';
error = get_uci_path_value(VARSTATE_CONFIG, UCI_VAR_WRONG_PATH, value, BUF_SIZE_256);
assert_int_equal(error, UCI_ERR_NOTFOUND); assert_int_equal(error, UCI_ERR_NOTFOUND);
assert_null(value); assert_string_equal(value, "");
} }
static void cwmp_uci_add_tests(void **state) static void cwmp_uci_add_tests(void **state)
{ {
struct uci_section *s = NULL;
int error = UCI_OK; int error = UCI_OK;
char value[BUF_SIZE_256] = {0};
error = cwmp_uci_add_section("cwmp", "acs", UCI_STANDARD_CONFIG, &s); error = set_uci_path_value(NULL, "cwmp.new_acs", "acs");
assert_non_null(s);
assert_int_equal(error, UCI_OK); assert_int_equal(error, UCI_OK);
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
assert_int_equal(strncmp(section_name(s), "cfg", 3), 0);
s = NULL;
error = cwmp_uci_add_section("new_package", "new_section", UCI_STANDARD_CONFIG, &s); error = set_uci_path_value(NULL, "cwmp.new_acs.test", "abc");
assert_non_null(s);
assert_int_equal(error, UCI_OK); assert_int_equal(error, UCI_OK);
cwmp_commit_package("new_package", UCI_STANDARD_CONFIG);
assert_int_equal(strncmp(section_name(s), "cfg", 3), 0);
s = NULL;
error = cwmp_uci_add_section_with_specific_name("cwmp", "acs", "new_acs", UCI_STANDARD_CONFIG); error = get_uci_path_value(NULL, "cwmp.new_acs.test", value, BUF_SIZE_256);
assert_int_equal(error, UCI_OK); assert_int_equal(error, UCI_OK);
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG); assert_string_equal(value, "abc");
error = cwmp_uci_add_section_with_specific_name("cwmp", "acs", "new_acs", UCI_STANDARD_CONFIG); error = set_uci_path_value(NULL, "cwmp.new_acs", "acs");
assert_int_equal(error, UCI_ERR_DUPLICATE);
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
}
static void cwmp_uci_list_tests(void **state)
{
int error = UCI_OK;
error = cwmp_uci_add_list_value("cwmp", "cpe", "optionlist", "val1", UCI_STANDARD_CONFIG);
assert_int_equal(error, UCI_OK); assert_int_equal(error, UCI_OK);
error = cwmp_uci_add_list_value("cwmp", "cpe", "optionlist", "val2", UCI_STANDARD_CONFIG);
assert_int_equal(error, UCI_OK);
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
error = cwmp_uci_add_list_value("cwmp", "wrong_section", "optionlist", "val1", UCI_STANDARD_CONFIG);
assert_int_equal(error, UCI_ERR_INVAL);
error = cwmp_uci_add_list_value("cwmp", "wrong_section", "optionlist", "val2", UCI_STANDARD_CONFIG);
assert_int_equal(error, UCI_ERR_INVAL);
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
} }
int icwmp_uci_test(void) int icwmp_uci_test(void)
{ {
const struct CMUnitTest tests[] = { const struct CMUnitTest tests[] = {
cmocka_unit_test(cwmp_uci_get_tests), cmocka_unit_test(cwmp_uci_get_tests),
cmocka_unit_test(cwmp_uci_add_tests), cmocka_unit_test(cwmp_uci_add_tests)
cmocka_unit_test(cwmp_uci_list_tests)
}; };
return cmocka_run_group_tests(tests, cwmp_uci_unit_tests_init, cwmp_uci_unit_tests_clean); return cmocka_run_group_tests(tests, cwmp_uci_unit_tests_init, cwmp_uci_unit_tests_clean);

View file

@ -110,7 +110,7 @@ if [[ $notif2 == *"Device.DeviceInfo.ProvisioningCode"* ]]; then
fi fi
logfile=`cat /var/log/icwmpd.log` logfile=`cat /var/log/icwmpd.log`
if [[ $logfile != *"[WARNING] This parameter Device.DeviceInfo.ProvisioningCode is forced notification parameter, can't be changed"* ]]; then if [[ $logfile != *"[ERROR] Invalid/forced parameter Device.DeviceInfo.ProvisioningCode, skipped 9009"* ]]; then
echo "FAIL: Device.DeviceInfo.ProvisioningCode is forced notification parameter, can't be changed" echo "FAIL: Device.DeviceInfo.ProvisioningCode is forced notification parameter, can't be changed"
exit 1 exit 1
fi fi
@ -148,7 +148,7 @@ if [[ $notif2 == *"Device.WiFi.SSID.1.SD"* ]]; then
fi fi
logfile=`cat /var/log/icwmpd.log` logfile=`cat /var/log/icwmpd.log`
if [[ $logfile != *"[WARNING] The parameter Device.WiFi.SSID.1.SD is wrong path"* ]]; then if [[ $logfile != *"[ERROR] Invalid/forced parameter Device.WiFi.SSID.1.SD, skipped 9005"* ]]; then
echo "FAIL: Log file should contain WARNING that Device.WiFi.SSID.1.SD is wrong parameter path." echo "FAIL: Log file should contain WARNING that Device.WiFi.SSID.1.SD is wrong parameter path."
exit 1 exit 1
fi fi