Ticket refs #6359: icwmp: Reduce I/O on filesystem

This commit is contained in:
Omar Kallel 2021-11-08 17:23:53 +01:00
parent 61a71148da
commit 0aa8c57c41
18 changed files with 118 additions and 50 deletions

View file

@ -5,7 +5,6 @@ include:
stages:
- static_code_analysis
- unit_test
- api_test
- functional_test
variables:
@ -28,7 +27,7 @@ run_unit_test:
- unit-test-coverage.xml
run_api_test:
stage: api_test
stage: functional_test
image: iopsys/code-analysis:latest
allow_failure: false
script:

View file

@ -1102,10 +1102,8 @@ int bkp_session_check_file()
int cwmp_init_backup_session(struct cwmp *cwmp, char **ret, enum backup_loading load)
{
int error;
if (bkp_session_check_file())
return 0;
error = cwmp_load_saved_session(cwmp, ret, load);
return error;
}

View file

@ -297,11 +297,10 @@ void get_firewall_zone_name_by_wan_iface(char *if_wan, char **zone_name)
*/
void cwmp_reboot(char *command_key)
{
cwmp_uci_set_value("cwmp", "acs", "ParameterKey", command_key);
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
cwmp_uci_set_varstate_value("cwmp", "cpe", "ParameterKey", command_key);
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
sync();
reboot(RB_AUTOBOOT);
cwmp_ubus_call("rpc-sys", "reboot", CWMP_UBUS_ARGS{ {} }, 0, NULL, NULL);
}
/*
@ -657,3 +656,27 @@ char *generate_random_string(size_t size)
}
return str;
}
int copy_file(char *source_file, char *target_file)
{
char ch;
FILE *source, *target;
source = fopen(source_file, "r");
if (source == NULL) {
printf("Not able to open the source file: %s\n", source_file);
return -1;
}
target = fopen(target_file, "w");
if (target == NULL) {
fclose(source);
printf("Not able to open the target file: %s\n", target_file);
return -1;
}
while( (ch = fgetc(source) ) != EOF)
fputc(ch, target);
printf("File copied successfully.\n");
fclose(source);
fclose(target);
return 0;
}

36
cwmp.c
View file

@ -548,6 +548,27 @@ void clean_custom_inform_parameters()
nbre_boot_inform = 0;
}
int create_cwmp_var_state_files()
{
/*
* Create Notifications empty uci package
*/
if (!file_exists(CWMP_VARSTATE_UCI_PACKAGE)) {
FILE *fptr = fopen(CWMP_VARSTATE_UCI_PACKAGE, "w+");
if (fptr)
fclose(fptr);
else
return CWMP_GEN_ERR;
}
if (!folder_exists("/var/state/icwmpd")) {
if (mkdir("/var/state/icwmpd", S_IRWXU | S_IRWXG | S_IRWXO) == -1) {
CWMP_LOG(INFO, "Not able to create the folder /var/state/icwmpd");
return CWMP_GEN_ERR;
}
}
return CWMP_OK;
}
static int cwmp_init(int argc, char **argv, struct cwmp *cwmp)
{
int error;
@ -558,6 +579,7 @@ static int cwmp_init(int argc, char **argv, struct cwmp *cwmp)
return error;
icwmp_init_list_services();
/* Only One instance should run*/
cwmp->pid_file = fopen("/var/run/icwmpd.pid", "w+");
fcntl(fileno(cwmp->pid_file), F_SETFD, fcntl(fileno(cwmp->pid_file), F_GETFD) | FD_CLOEXEC);
@ -580,6 +602,9 @@ static int cwmp_init(int argc, char **argv, struct cwmp *cwmp)
memcpy(&(cwmp->env), &env, sizeof(struct env));
INIT_LIST_HEAD(&(cwmp->head_session_queue));
if ((error = create_cwmp_var_state_files()))
return error;
cwmp_uci_init();
if ((error = global_conf_init(cwmp)))
return error;
@ -596,6 +621,7 @@ static int cwmp_init(int argc, char **argv, struct cwmp *cwmp)
static void cwmp_free(struct cwmp *cwmp)
{
CWMP_LOG(INFO, "%s:%s line %d", __FILE__, __FUNCTION__, __LINE__);
FREE(cwmp->deviceid.manufacturer);
FREE(cwmp->deviceid.serialnumber);
FREE(cwmp->deviceid.productclass);
@ -627,6 +653,8 @@ static void cwmp_free(struct cwmp *cwmp)
static void *thread_cwmp_signal_handler_thread(void *arg)
{
CWMP_LOG(INFO, "%s:%s line %d", __FILE__, __FUNCTION__, __LINE__);
sigset_t *set = (sigset_t *)arg;
int s, signal_num;
@ -638,7 +666,8 @@ static void *thread_cwmp_signal_handler_thread(void *arg)
CWMP_LOG(INFO, "Catch of Signal(%d)", signal_num);
if (signal_num == SIGINT || signal_num == SIGTERM) {
//copy_file(CWMP_BKP_FILE, "/etc/icwmpd/.icwmpd_backup_session.xml");
CWMP_LOG(INFO, "%s:%s line %d", __FILE__, __FUNCTION__, __LINE__);
signal_exit = true;
if (!ubus_exit)
@ -675,20 +704,25 @@ int main(int argc, char **argv)
sigset_t set;
int error;
CWMP_LOG(INFO, "%s:%s line %d", __FILE__, __FUNCTION__, __LINE__);
if ((error = cwmp_init(argc, argv, cwmp)))
return error;
CWMP_LOG(INFO, "STARTING ICWMP with PID :%d", getpid());
cwmp->start_time = time(NULL);
CWMP_LOG(INFO, "%s:%s line %d", __FILE__, __FUNCTION__, __LINE__);
if ((error = cwmp_init_backup_session(cwmp, NULL, ALL)))
return error;
CWMP_LOG(INFO, "%s:%s line %d", __FILE__, __FUNCTION__, __LINE__);
if ((error = cwmp_root_cause_events(cwmp)))
return error;
CWMP_LOG(INFO, "%s:%s line %d", __FILE__, __FUNCTION__, __LINE__);
configure_var_state(cwmp);
http_server_init();
CWMP_LOG(INFO, "%s:%s line %d", __FILE__, __FUNCTION__, __LINE__);
sigemptyset(&set);
sigaddset(&set, SIGINT);

View file

@ -16,7 +16,7 @@ struct uci_paths uci_save_conf_paths[] = {
[UCI_STANDARD_CONFIG] = { "/etc/config", "/tmp/.uci", NULL },
[UCI_DB_CONFIG] = { "/lib/db/config", NULL, NULL },
[UCI_BOARD_DB_CONFIG] = { "/etc/board-db/config", NULL, NULL },
[UCI_VARSTATE_CONFIG] = { "/var/state", NULL, NULL },
[UCI_VARSTATE_CONFIG] = { "/var/state", NULL, NULL }
};
/*
@ -315,7 +315,6 @@ int cwmp_uci_set_varstate_value(char *package, char*section, char *option, char
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;
@ -413,7 +412,7 @@ char *cwmp_uci_list_to_string(struct uci_list *list, char *delimitor)
return NULL;
}
int cwmp_uci_get_option_value_list(char *package, char *section, char *option, struct uci_list **value)
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};
@ -422,7 +421,7 @@ int cwmp_uci_get_option_value_list(char *package, char *section, char *option, s
int option_type;
*value = NULL;
if (cwmp_uci_lookup_ptr(uci_save_conf_paths[UCI_STANDARD_CONFIG].uci_ctx, &ptr, package, section, option, NULL))
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) {
@ -457,6 +456,16 @@ int cwmp_uci_get_option_value_list(char *package, char *section, char *option, s
return option_type;
}
int cwmp_uci_get_cwmp_standard_option_value_list(char *package, char *section, char *option, struct uci_list **value)
{
return cwmp_uci_get_option_value_list(package, section, option, UCI_STANDARD_CONFIG, value);
}
int cwmp_uci_get_cwmp_varstate_option_value_list(char *package, char *section, char *option, struct uci_list **value)
{
return cwmp_uci_get_option_value_list(package, section, option, UCI_VARSTATE_CONFIG, value);
}
int cwmp_uci_add_list_value(char *package, char *section, char *option, char *value, uci_config_paths uci_type)
{
struct uci_ptr ptr = {0};

View file

@ -292,8 +292,8 @@ int apply_downloaded_file(struct cwmp *cwmp, struct download *pdownload, struct
error = FAULT_CPE_INVALID_ARGUMENTS;
if ((error == FAULT_CPE_NO_FAULT) && (pdownload->file_type[0] == '1' || pdownload->file_type[0] == '3')) {
cwmp_uci_set_value("cwmp", "acs", "ParameterKey", pdownload->command_key ? pdownload->command_key : "");
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
cwmp_uci_set_varstate_value("cwmp", "cpe", "ParameterKey", pdownload->command_key ? pdownload->command_key : "");
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
if (pdownload->file_type[0] == '3') {
CWMP_LOG(INFO, "Download and apply new vendor config file is done successfully");
}

View file

@ -11,6 +11,7 @@ date +%s > timestamp.log
echo "Compiling icmwp"
build_icwmp
mkdir -p /var/state/icwmpd
echo "Starting dependent services"
supervisorctl status all
supervisorctl update

View file

@ -24,6 +24,8 @@ configure_genieacs
echo "Configuring ACS URL"
configure_acs_url
mkdir -p /var/state/icwmpd
echo "Starting icwmpd deamon"
supervisorctl start icwmpd
sleep 5

View file

@ -23,6 +23,7 @@ exec_cmd cp /builds/iopsys/icwmp/test/files/etc/icwmpd/* /etc/icwmpd
exec_cmd mkdir -p /var/state
exec_cmd cp /builds/iopsys/icwmp/test/files/var/state/cwmp /var/state
mkdir -p /var/state/icwmpd
echo "Starting dependent services"
supervisorctl status all

View file

@ -21,7 +21,7 @@
#define RPC_SEND 1
#define CWMP_BACKUP_SESSION "<cwmp></cwmp>"
#define CWMP_BKP_FILE "/etc/icwmpd/.icwmpd_backup_session.xml"
#define CWMP_BKP_FILE "/var/state/icwmpd/.icwmpd_backup_session.xml"
typedef enum backup_loading
{
ALL,

View file

@ -50,6 +50,7 @@
#define DEFAULT_ACSURL "http://192.168.1.1:8080/openacs/acs"
#define MAX_NBRE_SERVICES 256
#define FIREWALL_CWMP "/etc/firewall.cwmp"
#define CWMP_VARSTATE_UCI_PACKAGE "/var/state/cwmp"
extern char *commandKey;
extern bool thread_end;
@ -483,6 +484,7 @@ bool icwmp_validate_int_in_range(char *arg, int min, int max);
void load_forced_inform_json_file(struct cwmp *cwmp);
void clean_custom_inform_parameters();
char *generate_random_string(size_t size);
int copy_file(char *source_file, char *target_file);
#ifndef FREE
#define FREE(x) \
do { \

View file

@ -72,7 +72,7 @@ typedef enum uci_config_paths
UCI_STANDARD_CONFIG,
UCI_DB_CONFIG,
UCI_BOARD_DB_CONFIG,
UCI_VARSTATE_CONFIG,
UCI_VARSTATE_CONFIG
}uci_config_paths;
enum uci_val_type
@ -125,7 +125,8 @@ int cwmp_uci_init();
void cwmp_uci_exit(void);
void cwmp_uci_reinit(void);
int cwmp_uci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value);
int cwmp_uci_get_option_value_list(char *package, char *section, char *option, struct uci_list **value);
int cwmp_uci_get_cwmp_standard_option_value_list(char *package, char *section, char *option, struct uci_list **value);
int cwmp_uci_get_cwmp_varstate_option_value_list(char *package, char *section, char *option, 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 cwmp_uci_set_value_by_path(char *path, char *value);

View file

@ -48,8 +48,7 @@ extern struct list_head list_param_obj_notify;
uci_foreach_element(list_notif, e) { \*/
#define DM_ENABLED_NOTIFY "/etc/icwmpd/.dm_enabled_notify"
#define DM_ENABLED_NOTIFY "/var/state/icwmpd/.dm_enabled_notify"
#define NOTIFY_FILE "/etc/icwmpd/.icwmpd_notify"
void ubus_check_value_change_callback(struct ubus_request *req, int type, struct blob_attr *msg);
void cwmp_update_enabled_notify_file(void);

View file

@ -81,12 +81,12 @@ int add_uci_option_notification(char *parameter_name, int notification)
struct uci_section *s = NULL;
int ret = 0;
ret = cwmp_uci_get_section_type("cwmp", "@notifications[0]", UCI_STANDARD_CONFIG, &notification_type);
ret = cwmp_uci_get_section_type("cwmp", "@notifications[0]", UCI_VARSTATE_CONFIG, &notification_type);
if (notification_type == NULL || notification_type[0] == '\0') {
cwmp_uci_add_section("cwmp", "notifications", UCI_STANDARD_CONFIG, &s);
cwmp_uci_add_section("cwmp", "notifications", UCI_VARSTATE_CONFIG, &s);
}
ret = cwmp_uci_add_list_value("cwmp", "@notifications[0]", notifications[notification], parameter_name, UCI_STANDARD_CONFIG);
ret = cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
ret = cwmp_uci_add_list_value("cwmp", "@notifications[0]", notifications[notification], parameter_name, UCI_VARSTATE_CONFIG);
ret = cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
return ret;
}
@ -99,7 +99,7 @@ bool check_parent_with_different_notification(char *parameter_name, int notifica
for (i = 0; i < 7; i++) {
if (i == notification)
continue;
option_type = cwmp_uci_get_option_value_list("cwmp", "@notifications[0]", notifications[i], &list_notif);
option_type = cwmp_uci_get_cwmp_varstate_option_value_list("cwmp", "@notifications[0]", notifications[i], &list_notif);
if (list_notif) {
uci_foreach_element(list_notif, e) {
if (parameter_is_subobject_of_parameter(e->name, parameter_name))
@ -121,19 +121,19 @@ bool update_notifications_list(char *parameter_name, int notification)
bool update_ret = true;
for (i = 0; i < 7; i++) {
option_type = cwmp_uci_get_option_value_list("cwmp", "@notifications[0]", notifications[i], &list_notif);
option_type = cwmp_uci_get_cwmp_varstate_option_value_list("cwmp", "@notifications[0]", notifications[i], &list_notif);
if (list_notif) {
uci_foreach_element_safe(list_notif, tmp, e) {
if (e->name == NULL)
continue;
ename = strdup(e->name);
if ((strcmp(parameter_name, e->name) == 0 && (i != notification)) || parameter_is_subobject_of_parameter(parameter_name, e->name))
cwmp_uci_del_list_value("cwmp", "@notifications[0]", notifications[i], e->name, UCI_STANDARD_CONFIG);
cwmp_uci_del_list_value("cwmp", "@notifications[0]", notifications[i], e->name, UCI_VARSTATE_CONFIG);
if (ename && (strcmp(parameter_name, ename) == 0 || parameter_is_subobject_of_parameter(ename, parameter_name) ) && (i == notification))
update_ret = false;
FREE(ename);
}
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
}
if (option_type == UCI_TYPE_STRING)
cwmp_free_uci_list(list_notif);
@ -173,7 +173,7 @@ int get_parameter_family_notifications(char *parameter_name, struct list_head *c
char *parent_param = NULL;
for (i = 0; i < 7; i++) {
option_type = cwmp_uci_get_option_value_list("cwmp", "@notifications[0]", notifications[i], &list_notif);
option_type = cwmp_uci_get_cwmp_varstate_option_value_list("cwmp", "@notifications[0]", notifications[i], &list_notif);
if (list_notif) {
uci_foreach_element(list_notif, e) {
if (parameter_is_subobject_of_parameter(parameter_name, e->name)) {
@ -276,7 +276,7 @@ void create_list_param_obj_notify()
struct uci_element *e = NULL;
int i, option_type;
for (i = 0; i < 7; i++) {
option_type = cwmp_uci_get_option_value_list("cwmp", "@notifications[0]", notifications[i], &list_notif);
option_type = cwmp_uci_get_cwmp_varstate_option_value_list("cwmp", "@notifications[0]", notifications[i], &list_notif);
if (list_notif) {
uci_foreach_element(list_notif, e) {
add_dm_parameter_to_list(&list_param_obj_notify, e->name, "", "", i, false);

View file

@ -96,7 +96,7 @@ int get_parameter_notification_from_notifications_uci_list(char *parameter_name)
struct uci_list *list_notif;
struct uci_element *e;
for (i = 0; i < 7; i++) {
option_type = cwmp_uci_get_option_value_list("cwmp", "@notifications[0]", notifications_test[i], &list_notif);
option_type = cwmp_uci_get_cwmp_varstate_option_value_list("cwmp", "@notifications[0]", notifications_test[i], &list_notif);
if (list_notif) {
uci_foreach_element(list_notif, e) {
if (strcmp(e->name, parameter_name) == 0) {

View file

@ -186,7 +186,7 @@ static void cwmp_uci_list_tests(void **state)
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_get_option_value_list("cwmp", "cpe", "optionlist", &list);
error = cwmp_uci_get_cwmp_standard_option_value_list("cwmp", "cpe", "optionlist", &list);
assert_int_equal(error, UCI_TYPE_LIST);
list_string = cwmp_uci_list_to_string(list, ",");
assert_non_null(list_string);
@ -200,7 +200,7 @@ static void cwmp_uci_list_tests(void **state)
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);
error = cwmp_uci_get_option_value_list("cwmp", "wrong_section", "optionlist", &list);
error = cwmp_uci_get_cwmp_standard_option_value_list("cwmp", "wrong_section", "optionlist", &list);
assert_int_equal(error, UCI_ERR_NOTFOUND);
assert_null(list);
list_string = cwmp_uci_list_to_string(list, ",");

View file

@ -5,7 +5,6 @@ config acs 'acs'
option periodic_inform_enable 'true'
option periodic_inform_interval '1800'
option periodic_inform_time '0001-01-01T00:00:00Z'
option ParameterKey ''
option dhcp_discovery 'disable'
# compression possible configs: GZIP, Deflate, Disabled
option compression 'Disabled'

View file

@ -15,8 +15,8 @@ exec_cmd cp test/files/etc/icwmpd/custom_notification* /etc/icwmpd
# Test a valid custom notification json file
#
rm /var/log/icwmpd.log
uci delete cwmp.@notifications[0]
uci commit cwmp
uci -c /var/state delete cwmp.@notifications[0]
uci -c /var/state commit cwmp
exec_cmd uci set cwmp.cpe.custom_notify_json="/etc/icwmpd/custom_notification_valid.json"
uci commit cwmp
@ -27,12 +27,12 @@ sleep 7
supervisorctl stop icwmpd
notif1=`uci get cwmp.@notifications[0].active | grep "Device.Users."`
notif1=`uci -c /var/state get cwmp.@notifications[0].active | grep "Device.Users."`
if [[ $notif1 != *"Device.Users."* ]]; then
echo "FAIL: active notifications list doesn't contain Device.Users. parameter"
exit 1
fi
notif2=`uci get cwmp.@notifications[0].passive | grep "Device.WiFi.SSID.1.SSID"`
notif2=`uci -c /var/state get cwmp.@notifications[0].passive | grep "Device.WiFi.SSID.1.SSID"`
if [[ $notif2 != *"Device.WiFi.SSID.1.SSID"* ]]; then
echo "FAIL: active notifications list doesn't contain Device.WiFi.SSID.1.SSID parameter"
exit 1
@ -46,8 +46,8 @@ echo "PASS test valid custom notification json file"
# Test custom notification invalid json file
#
rm /var/log/icwmpd.log
uci delete cwmp.@notifications[0]
uci commit cwmp
uci -c /var/state delete cwmp.@notifications[0]
uci -c /var/state commit cwmp
exec_cmd uci set cwmp.cpe.custom_notify_json="/etc/icwmpd/custom_notification_invalid_json.json"
uci commit cwmp
@ -56,12 +56,12 @@ supervisorctl start icwmpd
sleep 7
supervisorctl stop icwmpd
notif1=`uci get cwmp.@notifications[0].active | grep "Device.Users."`
notif1=`uci -c /var/state get cwmp.@notifications[0].active | grep "Device.Users."`
if [[ $notif1 == *"Device.Users."* ]]; then
echo "FAIL: the json file is invalid, the active notifcation list shouldn't contain Device.Users. parameter"
exit 1
fi
notif2=`uci get cwmp.@notifications[0].passive | grep "Device.WiFi.SSID.1.SSID"`
notif2=`uci -c /var/state get cwmp.@notifications[0].passive | grep "Device.WiFi.SSID.1.SSID"`
if [[ $notif2 == *"Device.WiFi.SSID.1.SSID"* ]]; then
echo "FAIL: the json file is invalid, the active notifcation list shouldn't contain Device.WiFi.SSID.1.SSID parameter"
exit 1
@ -81,8 +81,8 @@ rm /etc/icwmpd/.icwmpd_notify
# Test custom notification json file containing forced active notification
#
rm /var/log/icwmpd.log
uci delete cwmp.@notifications[0]
uci commit cwmp
uci -c /var/state delete cwmp.@notifications[0]
uci -c /var/state commit cwmp
exec_cmd uci set cwmp.cpe.custom_notify_json="/etc/icwmpd/custom_notification_forced.json"
uci commit cwmp
@ -91,12 +91,12 @@ supervisorctl start icwmpd
sleep 7
supervisorctl stop icwmpd
notif1=`uci get cwmp.@notifications[0].active | grep "Device.Users."`
notif1=`uci -c /var/state get cwmp.@notifications[0].active | grep "Device.Users."`
if [[ $notif1 != *"Device.Users."* ]]; then
echo "FAIL: active notifications list doesn't contain Device.Users. parameter"
exit 1
fi
notif2=`uci get cwmp.@notifications[0].passive | grep "Device.DeviceInfo.ProvisioningCode"`
notif2=`uci -c /var/state get cwmp.@notifications[0].passive | grep "Device.DeviceInfo.ProvisioningCode"`
if [[ $notif2 == *"Device.DeviceInfo.ProvisioningCode"* ]]; then
echo "FAIL: passive notifications list contains Device.DeviceInfo.ProvisioningCode while it's a forced active notification paramter"
exit 1
@ -116,8 +116,8 @@ rm /etc/icwmpd/.icwmpd_notify
# Test custom notification json file containing invalid parameter path
#
rm /var/log/icwmpd.log
uci delete cwmp.@notifications[0]
uci commit cwmp
uci -c /var/state delete cwmp.@notifications[0]
uci -c /var/state commit cwmp
exec_cmd uci set cwmp.cpe.custom_notify_json="/etc/icwmpd/custom_notification_invalid_parameter.json"
uci commit cwmp
@ -126,12 +126,12 @@ supervisorctl start icwmpd
sleep 7
supervisorctl stop icwmpd
notif1=`uci get cwmp.@notifications[0].active | grep "Device.Users."`
notif1=`uci -c /var/state get cwmp.@notifications[0].active | grep "Device.Users."`
if [[ $notif1 != *"Device.Users."* ]]; then
echo "FAIL: active notifications list doesn't contain Device.Users. parameter"
exit 1
fi
notif2=`uci get cwmp.@notifications[0].passive | grep "Device.WiFi.SSID.1.SD"`
notif2=`uci -c /var/state get cwmp.@notifications[0].passive | grep "Device.WiFi.SSID.1.SD"`
if [[ $notif2 == *"Device.WiFi.SSID.1.SD"* ]]; then
echo "FAIL: passive notifications list contains Device.WiFi.SSID.1.SD while it's a wrong parameter path"
exit 1