Enhance notification functions update_notify_file and check_value_change & add the function cwmp_get_single_parameter_value to call Inform parameters instead

This commit is contained in:
Omar Kallel 2021-03-25 23:22:16 +01:00
parent cad3ea4dd8
commit 62cdbebd70
5 changed files with 147 additions and 74 deletions

View file

@ -11,6 +11,7 @@
#include "datamodel_interface.h"
#include "log.h"
#include "ubus.h"
#include "notifications.h"
bool transaction_started = false;
int transaction_id = 0;
@ -201,6 +202,52 @@ bool cwmp_transaction_status()
CWMP_LOG(INFO, "Transaction with id: %d is not available anymore\n", transaction_id);
return status;
}
/*
* Get single _parameter value
*/
void ubus_get_single_parameter_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
struct blob_attr *parameters = get_parameters_array(msg);
struct cwmp_dm_parameter *result = (struct cwmp_dm_parameter *)req->priv;
if (parameters == NULL) {
int fault_code = get_fault(msg);
result->name = NULL;
result->type = NULL;
cwmp_asprintf(&result->value, "%d", fault_code);
return;
}
const struct blobmsg_policy p[3] = { { "parameter", BLOBMSG_TYPE_STRING }, { "value", BLOBMSG_TYPE_STRING }, { "type", BLOBMSG_TYPE_STRING } };
struct blob_attr *cur;
int rem;
blobmsg_for_each_attr(cur, parameters, rem)
{
struct blob_attr *tb[3] = { NULL, NULL, NULL };
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
if (!tb[0])
continue;
result->name = strdup(blobmsg_get_string(tb[0]));
result->value = strdup(tb[1] ? blobmsg_get_string(tb[1]) : "");
result->type = strdup(tb[2] ? blobmsg_get_string(tb[2]) : "");
break;
}
}
char *cwmp_get_single_parameter_value(char *parameter_name, struct cwmp_dm_parameter *dm_parameter)
{
int e;
e = cwmp_ubus_call("usp.raw", "get", CWMP_UBUS_ARGS{ { "path", {.str_val = !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name }, UBUS_String } }, 1, ubus_get_single_parameter_callback, dm_parameter);
if (e < 0) {
CWMP_LOG(INFO, "get ubus method failed: Ubus err code: %d", e);
return strdup("9002");
}
if (dm_parameter->name == NULL) {
CWMP_LOG(INFO, "Get parameter_values failed: fault_code: %s", dm_parameter->value); // the value is the fault
return dm_parameter->value;
}
return NULL;
}
/*
* Get parameter Values/Names/Notify
@ -252,16 +299,6 @@ char *cwmp_get_parameter_names(char *object_name, bool next_level, struct list_h
return NULL;
}
int cwmp_update_enabled_list_notify(int instance_mode, struct list_head *parameters_list)
{
int e;
struct list_params_result list_notify_result = {.parameters_list = parameters_list };
e = cwmp_ubus_call("usp.raw", "list_notify", CWMP_UBUS_ARGS{ { "instance_mode", {.int_val = instance_mode }, UBUS_Integer } }, 1, ubus_get_parameter_callback, &list_notify_result);
if (e < 0)
CWMP_LOG(INFO, "list_notify ubus method failed: Ubus err code: %d", e);
return e;
}
/*
* Set multiple parameter values
*/
@ -438,3 +475,24 @@ char *cwmp_set_parameter_attributes(char *parameter_name, char *notification)
return NULL;
}
/*
* Notifications functions
*/
int cwmp_update_enabled_notify_file(void)
{
int e, fault;
struct cwmp *cwmp = &cwmp_main;
e = cwmp_ubus_call("usp.raw", "list_notify", CWMP_UBUS_ARGS{ { "instance_mode", {.int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 1, cwmp_update_enabled_notify_file_callback, &fault);
if (e || fault)
return 0;
return 1;
}
int check_value_change(void)
{
struct cwmp *cwmp = &cwmp_main;
int ret = 0;
cwmp_ubus_call("usp.raw", "list_notify", CWMP_UBUS_ARGS{ { "instance_mode", {.int_val = cwmp->conf.instance_mode }, UBUS_Integer } }, 1, ubus_check_value_change_callback, &ret);
return ret;
}

View file

@ -7,17 +7,21 @@
extern bool transaction_started;
extern int transaction_id;
struct blob_attr *get_parameters_array(struct blob_attr *msg);
int get_fault(struct blob_attr *msg);
bool cwmp_transaction_start(char *app);
bool cwmp_transaction_commit();
bool cwmp_transaction_abort();
bool cwmp_transaction_status();
char *cwmp_get_parameter_values(char *parameter_name, struct list_head *parameters_list);
char *cwmp_get_single_parameter_value(char *parameter_name, struct cwmp_dm_parameter *dm_parameter);
int cwmp_set_multiple_parameters_values(struct list_head parameters_values_list, char *parameter_key, int *flag, struct list_head *faults_list);
char *cwmp_add_object(char *object_name, char *key, char **instance);
char *cwmp_delete_object(char *object_name, char *key);
char *cwmp_get_parameter_names(char *object_name, bool next_level, struct list_head *parameters_list);
char *cwmp_get_parameter_attributes(char *parameter_name, struct list_head *parameters_list);
char *cwmp_set_parameter_attributes(char *parameter_name, char *notification);
int cwmp_update_enabled_list_notify(int instance_moden, struct list_head *parameters_list);
int cwmp_update_enabled_notify_file();
int check_value_change(void);
#endif /* SRC_DATAMODELIFACE_H_ */

View file

@ -13,6 +13,9 @@
#define NOTIFICATIONS_H_
#include <sys/socket.h>
#include <pthread.h>
#include <libubox/blobmsg_json.h>
#include <libubus.h>
#include "common.h"
#include "event.h"
#include "datamodel_interface.h"
@ -32,9 +35,8 @@ extern struct list_head list_value_change;
extern pthread_mutex_t mutex_value_change;
#define DM_ENABLED_NOTIFY "/etc/icwmpd/.dm_enabled_notify"
int cwmp_update_enabled_notify_file();
int check_value_change(void);
void ubus_check_value_change_callback(struct ubus_request *req, int type, struct blob_attr *msg);
void cwmp_update_enabled_notify_file_callback(struct ubus_request *req, int type, struct blob_attr *msg);
void sotfware_version_value_change(struct cwmp *cwmp, struct transfer_complete *p);
void *thread_periodic_check_notify(void *v);
void send_active_value_change(void);

View file

@ -13,98 +13,114 @@
#include <openssl/evp.h>
#include <netdb.h>
#include <libubox/list.h>
#include "notifications.h"
#include "ubus.h"
LIST_HEAD(list_value_change);
LIST_HEAD(list_lw_value_change);
pthread_mutex_t mutex_value_change = PTHREAD_MUTEX_INITIALIZER;
int cwmp_update_enabled_notify_file()
void cwmp_update_enabled_notify_file_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
struct cwmp *cwmp = &cwmp_main;
FILE *fp;
LIST_HEAD(list_notify);
int e = cwmp_update_enabled_list_notify(cwmp->conf.instance_mode, &list_notify);
if (e)
return 0;
remove(DM_ENABLED_NOTIFY);
int *int_ret = (int *)req->priv;
*int_ret = get_fault(msg);
if (*int_ret) {
*int_ret = 0;
return;
}
remove(DM_ENABLED_NOTIFY);
fp = fopen(DM_ENABLED_NOTIFY, "a");
if (fp == NULL) {
cwmp_free_all_dm_parameter_list(&list_notify);
return 0;
*int_ret = 0;
return;
}
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &list_notify, list) {
struct blob_attr *parameters = get_parameters_array(msg);
const struct blobmsg_policy p[5] = { { "parameter", BLOBMSG_TYPE_STRING }, { "value", BLOBMSG_TYPE_STRING }, { "type", BLOBMSG_TYPE_STRING }, { "notification", BLOBMSG_TYPE_STRING } };
struct blob_attr *cur;
int rem;
blobmsg_for_each_attr(cur, parameters, rem)
{
struct blob_attr *tb[4] = { NULL, NULL, NULL, NULL };
blobmsg_parse(p, 4, tb, blobmsg_data(cur), blobmsg_len(cur));
if (!tb[0])
continue;
char *notif_line = NULL;
cwmp_asprintf(&notif_line, "parameter:%s notifcation:%d type:%s value:%s", param_value->name, param_value->notification, param_value->type, param_value->value);
cwmp_asprintf(&notif_line, "parameter:%s notifcation:%s type:%s value:%s", blobmsg_get_string(tb[0]), tb[3] ? blobmsg_get_string(tb[3]) : "", tb[2] ? blobmsg_get_string(tb[2]) : "", tb[1] ? blobmsg_get_string(tb[1]) : "");
fprintf(fp, "%s\n", notif_line);
FREE(notif_line);
}
fclose(fp);
cwmp_free_all_dm_parameter_list(&list_notify);
return 1;
}
void get_parameter_value_from_parameters_list(struct list_head *list_notif, char *parameter_name, struct cwmp_dm_parameter **ret_dm_param)
void get_parameter_value_from_parameters_list(struct blob_attr *list_notif, char *parameter_name, char **value, char **type)
{
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, list_notif, list) {
if (param_value->name && strcmp(param_value->name, parameter_name) != 0) {
const struct blobmsg_policy p[5] = { { "parameter", BLOBMSG_TYPE_STRING }, { "value", BLOBMSG_TYPE_STRING }, { "type", BLOBMSG_TYPE_STRING } };
struct blob_attr *cur;
int rem;
blobmsg_for_each_attr(cur, list_notif, rem)
{
struct blob_attr *tb[3] = { NULL, NULL, NULL };
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
if (!tb[0])
continue;
}
*ret_dm_param = (struct cwmp_dm_parameter *)calloc(1, sizeof(struct cwmp_dm_parameter));
(*ret_dm_param)->name = strdup(param_value->name);
(*ret_dm_param)->value = strdup(param_value->value);
(*ret_dm_param)->type = strdup(param_value->type);
if (strcmp(parameter_name, blobmsg_get_string(tb[0])) != 0)
continue;
*value = strdup(tb[1] ? blobmsg_get_string(tb[1]) : "");
*type = strdup(tb[2] ? blobmsg_get_string(tb[2]) : "");
break;
}
}
int check_value_change(void)
void ubus_check_value_change_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
FILE *fp;
char buf[1280];
char *dm_value = NULL, *dm_type = NULL;
int *int_ret = (int *)req->priv;
*int_ret = get_fault(msg);
if (*int_ret) {
*int_ret = 0;
return;
}
struct cwmp *cwmp = &cwmp_main;
struct cwmp_dm_parameter *dm_parameter = NULL;
int is_notify = 0;
fp = fopen(DM_ENABLED_NOTIFY, "r");
if (fp == NULL)
return false;
LIST_HEAD(list_notify);
cwmp_update_enabled_list_notify(cwmp->conf.instance_mode, &list_notify);
if (fp == NULL) {
*int_ret = 0;
return;
}
struct blob_attr *list_notify = get_parameters_array(msg);
while (fgets(buf, 1280, fp) != NULL) {
int len = strlen(buf);
if (len)
buf[len - 1] = '\0';
char parameter[128] = { 0 }, notification[2] = { 0 }, value[1024] = { 0 }, type[32] = { 0 };
sscanf(buf, "parameter:%s notifcation:%s type:%s value:%s\n", parameter, notification, type, value);
get_parameter_value_from_parameters_list(&list_notify, parameter, &dm_parameter);
if (dm_parameter == NULL)
get_parameter_value_from_parameters_list(list_notify, parameter, &dm_value, &dm_type);
if (dm_value == NULL && dm_type == NULL)
continue;
if ((strlen(notification) > 0) && (notification[0] >= '1') && (dm_parameter->value != NULL) && (strcmp(dm_parameter->value, value) != 0)) {
if ((strlen(notification) > 0) && (notification[0] >= '1') && (dm_value != NULL) && (strcmp(dm_value, value) != 0)) {
if (notification[0] == '1' || notification[0] == '2')
add_list_value_change(parameter, dm_parameter->value, dm_parameter->type);
add_list_value_change(parameter, dm_value, dm_type);
if (notification[0] >= '3')
add_lw_list_value_change(parameter, dm_parameter->value, dm_parameter->type);
add_lw_list_value_change(parameter, dm_value, dm_type);
if (notification[0] == '1')
is_notify |= NOTIF_PASSIVE;
*int_ret |= NOTIF_PASSIVE;
if (notification[0] == '2')
is_notify |= NOTIF_ACTIVE;
*int_ret |= NOTIF_ACTIVE;
if (notification[0] == '5' || notification[0] == '6')
is_notify |= NOTIF_LW_ACTIVE;
*int_ret |= NOTIF_LW_ACTIVE;
}
FREE(dm_parameter->name);
FREE(dm_parameter->value);
FREE(dm_parameter->type);
FREE(dm_parameter);
FREE(dm_value);
FREE(dm_type);
}
fclose(fp);
cwmp_free_all_dm_parameter_list(&list_notify);
return is_notify;
}
void sotfware_version_value_change(struct cwmp *cwmp, struct transfer_complete *p)

23
xml.c
View file

@ -561,15 +561,8 @@ static int xml_prepare_parameters_inform(struct cwmp_dm_parameter *dm_parameter,
(*size)--;
goto create_value;
} else if (b && dm_parameter->value == NULL) {
} else if (dm_parameter->value == NULL)
return 0;
} else if (!b && dm_parameter->value == NULL) {
LIST_HEAD(list_specific_inform);
char *err = cwmp_get_parameter_values(dm_parameter->name, &list_specific_inform);
cwmp_free_all_dm_parameter_list(&list_specific_inform);
FREE(err);
return 0;
}
node = mxmlNewElement(parameter_list, "ParameterValueStruct");
if (!node)
return -1;
@ -841,19 +834,19 @@ int cwmp_rpc_acs_prepare_message_inform(struct cwmp *cwmp, struct session *sessi
size_t inform_parameters_nbre = sizeof(forced_inform_parameters) / sizeof(forced_inform_parameters[0]);
size_t i;
struct cwmp_dm_parameter *cwmp_dm_param = NULL;
struct cwmp_dm_parameter cwmp_dm_param = { 0 };
LIST_HEAD(list_inform);
for (i = 0; i < inform_parameters_nbre; i++) {
char *fault = cwmp_get_parameter_values(forced_inform_parameters[i], &list_inform);
char *fault = cwmp_get_single_parameter_value(forced_inform_parameters[i], &cwmp_dm_param);
if (fault != NULL) {
FREE(fault);
continue;
}
list_for_each_entry (cwmp_dm_param, &list_inform, list) {
if (xml_prepare_parameters_inform(cwmp_dm_param, parameter_list, &size))
goto error;
}
cwmp_free_all_dm_parameter_list(&list_inform);
if (xml_prepare_parameters_inform(&cwmp_dm_param, parameter_list, &size))
goto error;
FREE(cwmp_dm_param.name);
FREE(cwmp_dm_param.value);
FREE(cwmp_dm_param.type);
}
if (cwmp_asprintf(&c, "cwmp:ParameterValueStruct[%d]", size) == -1)
goto error;