Ticket refs #14516: TR-069 Notification support

This commit is contained in:
Amin Ben Ramdhane 2018-05-31 10:29:39 +01:00
parent 3320a62344
commit 70a8338cba
11 changed files with 312 additions and 77 deletions

View file

@ -1354,6 +1354,6 @@ int cwmp_config_reload(struct cwmp *cwmp)
if (conf->xmpp_enable && conf->xmpp_connection_id != 0)
cwmp_get_xmpp_param(cwmp);
#endif
dm_entry_load_enabled_notify(DM_CWMP, cwmp->conf.amd_version, cwmp->conf.instance_mode);
dm_entry_reload_enabled_notify(DM_CWMP, cwmp->conf.amd_version, cwmp->conf.instance_mode);
return CWMP_OK;
}

4
cwmp.c
View file

@ -679,12 +679,12 @@ int main(int argc, char **argv)
error = pthread_create(&periodic_event_thread, NULL, &thread_event_periodic, (void *)cwmp);
if (error<0)
{
CWMP_LOG(ERROR,"Error error when creating the periodic event thread!");
CWMP_LOG(ERROR,"Error when creating the periodic event thread!");
}
error = pthread_create(&handle_notify_thread, NULL, &thread_handle_notify, (void *)cwmp);
if (error<0)
{
CWMP_LOG(ERROR,"Error error when creating the handle notify thread!");
CWMP_LOG(ERROR,"Error when creating the handle notify thread!");
}
error = pthread_create(&scheduleInform_thread, NULL, &thread_cwmp_rpc_cpe_scheduleInform, (void *)cwmp);
if (error<0)

View file

@ -49,6 +49,7 @@
#include "nat.h"
#include "xmpp.h"
#include "dmcwmp.h"
#include "dmjson.h"
static char *get_parameter_notification(struct dmctx *ctx, char *param);
static int remove_parameter_notification(char *param);
@ -108,6 +109,8 @@ static int enabled_tracked_param_check_param(DMPARAM_ARGS);
#endif
static int enabled_notify_check_obj(DMOBJECT_ARGS);
static int enabled_notify_check_param(DMPARAM_ARGS);
static int enabled_notify_check_value_change_param(DMPARAM_ARGS);
static int enabled_notify_check_value_change_obj(DMOBJECT_ARGS);
static int get_linker_check_obj(DMOBJECT_ARGS);
static int get_linker_check_param(DMPARAM_ARGS);
static int get_linker_value_check_obj(DMOBJECT_ARGS);
@ -734,17 +737,6 @@ void free_all_list_fault_param(struct dmctx *ctx)
}
}
void add_list_enabled_notify(struct dmctx *dmctx, char *param, char *notification, char *value)
{
struct dm_enabled_notify *dm_enabled_notify;
dm_enabled_notify = calloc(1, sizeof(struct dm_enabled_notify)); // Should be calloc and not dmcalloc
list_add_tail(&dm_enabled_notify->list, &list_enabled_notify);
dm_enabled_notify->name = strdup(param); // Should be strdup and not dmstrdup
dm_enabled_notify->value = value ? strdup(value) : strdup(""); // Should be strdup and not dmstrdup
dm_enabled_notify->notification = strdup(notification); // Should be strdup and not dmstrdup
}
void add_list_enabled_lwnotify(struct dmctx *dmctx, char *param, char *notification, char *value)
{
struct dm_enabled_notify *dm_enabled_notify;
@ -765,15 +757,6 @@ void del_list_enabled_notify(struct dm_enabled_notify *dm_enabled_notify)
free(dm_enabled_notify);
}
void free_all_list_enabled_notify()
{
struct dm_enabled_notify *dm_enabled_notify;
while (list_enabled_notify.next != &list_enabled_notify) {
dm_enabled_notify = list_entry(list_enabled_notify.next, struct dm_enabled_notify, list);
del_list_enabled_notify(dm_enabled_notify);
}
}
void free_all_list_enabled_lwnotify()
{
struct dm_enabled_notify *dm_enabled_notify;
@ -783,6 +766,47 @@ void free_all_list_enabled_lwnotify()
}
}
int dm_update_file_enabled_notify(char *param, char *new_value)
{
FILE *fp, *ftmp;
char buf[512];
char *parameter, *notification, *value, *type, *jval;
fp = fopen(DM_ENABLED_NOTIFY, "r");
if (fp == NULL)
return 0;
ftmp = fopen(DM_ENABLED_NOTIFY_TEMPORARY, "a");
if (ftmp == NULL) {
fclose(fp);
return 0;
}
while (fgets(buf, 512, fp) != NULL) {
int len = strlen(buf);
if (len)
buf[len-1] = '\0';
dmjson_parse_init(buf);
dmjson_get_var("parameter", &jval);
parameter = dmstrdup(jval);
dmjson_get_var("value", &jval);
value = dmstrdup(jval);
dmjson_get_var("notification", &jval);
notification = dmstrdup(jval);
dmjson_get_var("type", &jval);
type = dmstrdup(jval);
dmjson_parse_fini();
if (strcmp(parameter, param) == 0)
dmjson_fprintf(ftmp, 4, DMJSON_ARGS{{"parameter", parameter}, {"notification", notification}, {"value", new_value}, {"type", type}});
else
dmjson_fprintf(ftmp, 4, DMJSON_ARGS{{"parameter", parameter}, {"notification", notification}, {"value", value}, {"type", type}});
}
fclose(fp);
fclose(ftmp);
return 0;
}
void dm_update_enabled_notify(struct dm_enabled_notify *p, char *new_value)
{
free(p->value); // Should be free and not dmfree
@ -791,12 +815,13 @@ void dm_update_enabled_notify(struct dm_enabled_notify *p, char *new_value)
void dm_update_enabled_notify_byname(char *name, char *new_value)
{
struct dm_enabled_notify *p;
int iscopy;
dm_update_file_enabled_notify(name, new_value);
remove(DM_ENABLED_NOTIFY);
iscopy = copy_temporary_file_to_original_file(DM_ENABLED_NOTIFY, DM_ENABLED_NOTIFY_TEMPORARY);
if(iscopy)
remove(DM_ENABLED_NOTIFY_TEMPORARY);
list_for_each_entry(p, &list_enabled_notify, list) {
if (strcmp(p->name, name) == 0)
dm_update_enabled_notify(p, new_value);
}
}
int update_param_instance_alias(struct dmctx *ctx, char *param, char **new_param)
@ -1638,12 +1663,12 @@ int dm_entry_enabled_notify(struct dmctx *dmctx)
int err;
DMOBJ *root = dmctx->dm_entryobj;
DMNODE node = { .current_object = "" };
//unsigned char findparam_check = 0;
dmctx->method_obj = enabled_notify_check_obj;
dmctx->method_param = enabled_notify_check_param;
dmctx->checkobj = NULL ;
dmctx->checkleaf = NULL;
remove(DM_ENABLED_NOTIFY);
err = dm_browse(dmctx, &node, root, NULL, NULL);
return err;
@ -1653,12 +1678,11 @@ static int enabled_notify_check_obj(DMOBJECT_ARGS)
{
return FAULT_9005;
}
// TO check
static int enabled_notify_check_param(DMPARAM_ARGS)
{
char *refparam;
char *value = "";
char *notif;
char *refparam, *stype, *notif, *value = "";
FILE *fp;
dmastrcat(&refparam, node->current_object, lastname);
@ -1674,9 +1698,17 @@ static int enabled_notify_check_param(DMPARAM_ARGS)
return 0;
}
(get_cmd)(refparam, dmctx, data, instance, &value);
if (notif[0] == '1' || notif[0] == '2'
|| notif[0] == '4' || notif[0] == '6')
add_list_enabled_notify(dmctx, refparam, notif, value);
fp = fopen(DM_ENABLED_NOTIFY, "a");
if (fp == NULL) {
dmfree(refparam);
return 0;
}
if (notif[0] == '1' || notif[0] == '2' || notif[0] == '4' || notif[0] == '6') {
stype = DMT_TYPE[type];
dmjson_fprintf(fp, 4, DMJSON_ARGS{{"parameter", refparam}, {"notification", notif}, {"value", value}, {"type", stype}});
}
fclose(fp);
if (notif[0] >= '3') {
add_list_enabled_lwnotify(dmctx, refparam, notif, value);
}
@ -1684,6 +1716,68 @@ static int enabled_notify_check_param(DMPARAM_ARGS)
return 0;
}
/*********************
* Check enabled notify value change
********************/
int dm_entry_enabled_notify_check_value_change(struct dmctx *dmctx)
{
DMOBJ *root = dmctx->dm_entryobj;
FILE *fp;
char buf[512];
char *jval;
fp = fopen(DM_ENABLED_NOTIFY, "r");
if (fp == NULL) {
return 0;
}
while (fgets(buf, 512, fp) != NULL) {
DMNODE node = {.current_object = ""};
int len = strlen(buf);
if (len)
buf[len-1] = '\0';
dmjson_parse_init(buf);
dmjson_get_var("parameter", &jval);
dmctx->in_param = dmstrdup(jval);
dmjson_get_var("value", &jval);
dmctx->in_value = dmstrdup(jval);
dmjson_get_var("notification", &jval);
dmctx->in_notification = dmstrdup(jval);
dmjson_parse_fini();
dmctx->checkobj = NULL ;
dmctx->checkleaf = NULL;
dmctx->method_obj = enabled_notify_check_value_change_obj;
dmctx->method_param = enabled_notify_check_value_change_param;
dm_browse(dmctx, &node, root, NULL, NULL);
}
fclose(fp);
return 0;
}
static int enabled_notify_check_value_change_obj(DMOBJECT_ARGS)
{
return FAULT_9005;
}
static int enabled_notify_check_value_change_param(DMPARAM_ARGS)
{
char *refparam, *value = "";
dmastrcat(&refparam, node->current_object, lastname);
if (strcmp(refparam, dmctx->in_param) != 0) {
dmfree(refparam);
return FAULT_9005;
}
(get_cmd)(refparam, dmctx, data, instance, &value);
if (strcmp(value, dmctx->in_value) != 0) {
add_list_value_change(refparam, value, DMT_TYPE[type]);
if(dmctx->in_notification[0] =='2')
send_active_value_change();
}
dmfree(refparam);
return 0;
}
/******************
* get linker param
*****************/

View file

@ -29,6 +29,9 @@
#define DM_PROMPT "icwmp>"
#define DM_ENABLED_NOTIFY "/etc/icwmpd/.dm_enabled_notify"
#define DM_ENABLED_NOTIFY_TEMPORARY "/tmp/.dm_enabled_notify_temporary"
#ifdef UPNP_TR064
#define UPNP_CFG "tr064"
#endif
@ -488,6 +491,7 @@ int dm_entry_delete_object(struct dmctx *ctx);
int dm_entry_set_value(struct dmctx *ctx);
int dm_entry_set_notification(struct dmctx *ctx);
int dm_entry_enabled_notify(struct dmctx *ctx);
int dm_entry_enabled_notify_check_value_change(struct dmctx *dmctx);
int dm_entry_get_linker(struct dmctx *ctx);
int dm_entry_get_linker_value(struct dmctx *ctx);
#ifdef UPNP_TR064
@ -504,6 +508,7 @@ void free_all_list_enabled_notify();
void free_all_list_upnp_param_track(struct list_head *head);
#endif
void dm_update_enabled_notify(struct dm_enabled_notify *p, char *new_value);
int dm_update_file_enabled_notify(char *param, char *new_value);
void dm_update_enabled_notify_byname(char *name, char *new_value);
char *get_last_instance(char *package, char *section, char *opt_inst);
char *get_last_instance_icwmpd(char *package, char *section, char *opt_inst);

View file

@ -442,7 +442,21 @@ int dm_entry_load_enabled_notify(unsigned int dm_type, unsigned int amd_version,
dmctx.in_param = "";
free_all_list_enabled_lwnotify();
free_all_list_enabled_notify();
dm_entry_enabled_notify_check_value_change(&dmctx);
dm_entry_enabled_notify(&dmctx);
dm_ctx_clean(&dmctx);
return 0;
}
int dm_entry_reload_enabled_notify(unsigned int dm_type, unsigned int amd_version, int instance_mode)
{
struct dmctx dmctx = {0};
dm_ctx_init(&dmctx, dm_type, amd_version, instance_mode);
dmctx.in_param = "";
free_all_list_enabled_lwnotify();
dm_entry_enabled_notify(&dmctx);
dm_ctx_clean(&dmctx);

View file

@ -16,6 +16,7 @@ int dm_ctx_init_sub(struct dmctx *ctx, unsigned int dm_type, unsigned int amd_ve
int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, char *arg2);
int dm_entry_apply(struct dmctx *ctx, int cmd, char *arg1, char *arg2);
int dm_entry_load_enabled_notify(unsigned int dm_type, unsigned int amd_version, int instance_mode);
int dm_entry_reload_enabled_notify(unsigned int dm_type, unsigned int amd_version, int instance_mode);
int adm_entry_get_linker_param(struct dmctx *ctx, char *param, char *linker, char **value);
int adm_entry_get_linker_value(struct dmctx *ctx, char *param, char **value);
int dm_entry_restart_services(void);

View file

@ -5,6 +5,55 @@
#include "dmjson.h"
#include "dmmem.h"
static json_object *dmjson_jobj = NULL;
void dm_add_json_obj(json_object *json_obj_out, char *object, char *string)
{
json_object *json_obj_tmp = json_object_new_string(string);
json_object_object_add(json_obj_out, object, json_obj_tmp);
}
static void inline __dmjson_fprintf(FILE *fp, int argc, struct dmjson_arg dmarg[])
{
int i;
char *arg;
json_object *json_obj_out = json_object_new_object();
if (json_obj_out == NULL)
return;
if (argc) {
for (i = 0; i < argc; i++) {
dm_add_json_obj(json_obj_out, dmarg[i].key, dmarg[i].val);
}
arg = (char *)json_object_to_json_string(json_obj_out);
fprintf(fp, "%s\n", arg);
}
json_object_put(json_obj_out);
}
void dmjson_fprintf(FILE *fp, int argc, struct dmjson_arg dmarg[])
{
__dmjson_fprintf(fp, argc, dmarg);
}
void dmjson_parse_init(char *msg)
{
if (dmjson_jobj) {
json_object_put(dmjson_jobj);
dmjson_jobj = NULL;
}
dmjson_jobj = json_tokener_parse(msg);
}
void dmjson_parse_fini(void)
{
if (dmjson_jobj) {
json_object_put(dmjson_jobj);
dmjson_jobj = NULL;
}
}
static char *dmjson_print_value(json_object *jobj)
{
enum json_type type;
@ -220,3 +269,19 @@ char *__dmjson_get_value_array_all(json_object *mainjobj, char *delim, int argc,
ret = ____dmjson_get_value_array_all(mainjobj, delim, argv);
return ret;
}
void dmjson_get_var(char *jkey, char **jval)
{
enum json_type type;
*jval = "";
if (dmjson_jobj == NULL)
return;
json_object_object_foreach(dmjson_jobj, key, val) {
if (strcmp(jkey, key) == 0) {
*jval = dmjson_print_value(val);
return;
}
}
}

View file

@ -13,7 +13,11 @@ struct dmjson_arg {
#define DMJSON_ARGS (struct dmjson_arg[])
void dm_add_json_obj(json_object *json_obj_out, char *object, char *string);
void dmjson_printf(int argc, struct dmjson_arg dmarg[]);
void dmjson_fprintf(FILE *fp, int argc, struct dmjson_arg dmarg[]);
void dmjson_parse_init(char *msg);
void dmjson_parse_fini(void);
void dmjson_get_var(char *jkey, char **jval);
json_object *dmjson_select_obj(json_object * jobj, char *argv[]);
json_object *__dmjson_get_obj(json_object *mainjobj, int argc, ...);

View file

@ -34,18 +34,18 @@ DMLEAF thostsParam[] = {
/*** Hosts.Host ***/
DMLEAF thostParam[] = {
{"AssociatedDevice", &DMREAD, DMT_STRING, get_host_associateddevice, NULL, NULL, &DMNONE},
{"Layer3Interface", &DMREAD, DMT_STRING, get_host_layer3interface, NULL, NULL, &DMNONE},
{"IPAddress", &DMREAD, DMT_STRING, get_host_ipaddress, NULL, NULL, &DMNONE},
{"HostName", &DMREAD, DMT_STRING, get_host_hostname, NULL, NULL, &DMNONE},
{"Active", &DMREAD, DMT_BOOL, get_host_active, NULL, NULL, &DMNONE},
{"PhysAddress", &DMREAD, DMT_STRING, get_host_phy_address, NULL, NULL, &DMNONE},
{"X_INTENO_SE_InterfaceType", &DMREAD, DMT_STRING, get_host_interfacetype, NULL, NULL, &DMNONE},
{"AddressSource", &DMREAD, DMT_STRING, get_host_address_source, NULL, NULL, &DMNONE},
{"LeaseTimeRemaining", &DMREAD, DMT_STRING, get_host_leasetime_remaining, NULL, NULL, &DMNONE},
{"AssociatedDevice", &DMREAD, DMT_STRING, get_host_associateddevice, NULL, NULL, NULL},
{"Layer3Interface", &DMREAD, DMT_STRING, get_host_layer3interface, NULL, NULL, NULL},
{"IPAddress", &DMREAD, DMT_STRING, get_host_ipaddress, NULL, NULL, NULL},
{"HostName", &DMREAD, DMT_STRING, get_host_hostname, NULL, NULL, NULL},
{"Active", &DMREAD, DMT_BOOL, get_host_active, NULL, NULL, NULL},
{"PhysAddress", &DMREAD, DMT_STRING, get_host_phy_address, NULL, NULL, NULL},
{"X_INTENO_SE_InterfaceType", &DMREAD, DMT_STRING, get_host_interfacetype, NULL, NULL, NULL},
{"AddressSource", &DMREAD, DMT_STRING, get_host_address_source, NULL, NULL, NULL},
{"LeaseTimeRemaining", &DMREAD, DMT_STRING, get_host_leasetime_remaining, NULL, NULL, NULL},
{"DHCPClient", &DMREAD, DMT_STRING, get_host_dhcp_client, NULL, NULL, NULL},
{"X_IOPSYS_InterfaceType", &DMREAD, DMT_STRING, get_host_interface_type, NULL, NULL, &DMNONE},
{"X_IOPSYS_ifname", &DMREAD, DMT_STRING, get_host_interfacename, NULL, NULL, &DMNONE},
{"X_IOPSYS_InterfaceType", &DMREAD, DMT_STRING, get_host_interface_type, NULL, NULL, NULL},
{"X_IOPSYS_ifname", &DMREAD, DMT_STRING, get_host_interfacename, NULL, NULL, NULL},
{0}
};

View file

@ -27,9 +27,9 @@ DMOBJ tnatObj[] = {
/*** NAT.InterfaceSetting. ***/
DMLEAF tInterfaceSettingParam[] = {
{"Enable", &DMREAD, DMT_BOOL, get_nat_enable, NULL, NULL, &DMNONE},
{"Alias", &DMWRITE, DMT_STRING, get_nat_alias, set_nat_alias, NULL, &DMNONE},
{"Interface", &DMREAD, DMT_STRING, get_nat_interface, NULL, NULL, &DMNONE},
{"Enable", &DMREAD, DMT_BOOL, get_nat_enable, NULL, NULL, NULL},
{"Alias", &DMWRITE, DMT_STRING, get_nat_alias, set_nat_alias, NULL, NULL},
{"Interface", &DMREAD, DMT_STRING, get_nat_interface, NULL, NULL, NULL},
{0}
};

104
event.c
View file

@ -27,6 +27,7 @@
#include "dmentry.h"
#include "deviceinfo.h"
#include "config.h"
#include "dmjson.h"
LIST_HEAD(list_value_change);
LIST_HEAD(list_lw_value_change);
@ -166,12 +167,13 @@ void free_dm_parameter_all_fromlist(struct list_head *list)
}
}
inline void add_list_value_change(char *param_name, char *param_data, char *param_type)
void add_list_value_change(char *param_name, char *param_data, char *param_type)
{
pthread_mutex_lock(&(mutex_value_change));
add_dm_parameter_tolist(&list_value_change, param_name, param_data, param_type);
pthread_mutex_unlock(&(mutex_value_change));
}
inline void add_lw_list_value_change(char *param_name, char *param_data, char *param_type)
{
add_dm_parameter_tolist(&list_lw_value_change, param_name, param_data, param_type);
@ -277,10 +279,55 @@ void cwmp_lwnotification()
FREE(msg_out);
}
int copy_temporary_file_to_original_file(char *f1, char *f2)
{
FILE *fp, *ftmp;
char buf[512];
ftmp = fopen(f2, "r");
if (ftmp == NULL)
return 0;
fp = fopen(f1, "w");
if (fp == NULL) {
fclose(ftmp);
return 0;
}
while( fgets(buf, 512, ftmp) !=NULL )
{
fprintf(fp, "%s", buf);
}
fclose(ftmp);
fclose(fp);
return 1;
}
void send_active_value_change(void)
{
struct cwmp *cwmp = &cwmp_main;
struct event_container *event_container;
pthread_mutex_lock(&(cwmp->mutex_session_queue));
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
if (event_container == NULL)
{
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
return;
}
cwmp_save_event_container(cwmp,event_container);
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
pthread_cond_signal(&(cwmp->threshold_session_send));
return;
}
void cwmp_add_notification(void)
{
int fault;
int fault, iscopy;
int i = 0;
FILE *fp;
char buf[512];
char *parameter, *notification, *value, *jval;
struct event_container *event_container;
struct cwmp *cwmp = &cwmp_main;
struct dm_enabled_notify *p;
@ -296,26 +343,43 @@ void cwmp_add_notification(void)
pthread_mutex_lock(&(cwmp->mutex_handle_notify));
cwmp->count_handle_notify = 0;
pthread_mutex_unlock(&(cwmp->mutex_handle_notify));
cwmp_dm_ctx_init(&cwmp_main, &dmctx);
list_for_each_entry(p, &list_enabled_notify, list) {
fp = fopen(DM_ENABLED_NOTIFY, "r");
if (fp == NULL)
return 0;
while (fgets(buf, 512, fp) != NULL) {
dm_ctx_init_sub(&dmctx, DM_CWMP, cwmp_main.conf.amd_version, cwmp_main.conf.instance_mode);
initiate = true;
fault = dm_entry_param_method(&dmctx, CMD_GET_VALUE, p->name, NULL, NULL);
int len = strlen(buf);
if (len)
buf[len-1] = '\0';
dmjson_parse_init(buf);
dmjson_get_var("parameter", &jval);
parameter = dmstrdup(jval);
dmjson_get_var("value", &jval);
value = dmstrdup(jval);
dmjson_get_var("notification", &jval);
notification = dmstrdup(jval);
dmjson_parse_fini();
fault = dm_entry_param_method(&dmctx, CMD_GET_VALUE, parameter, NULL, NULL);
if (!fault && dmctx.list_parameter.next != &dmctx.list_parameter) {
dm_parameter = list_entry(dmctx.list_parameter.next, struct dm_parameter, list);
if (strcmp(dm_parameter->data, p->value) != 0) {
dm_update_enabled_notify(p, dm_parameter->data);
if (p->notification[0] == '1' || p->notification[0] == '2' || p->notification[0] == '4' || p->notification[0] == '6' )
add_list_value_change(p->name, dm_parameter->data, dm_parameter->type);
if (p->notification[0] == '2')
if (strcmp(dm_parameter->data, value) != 0) {
dm_update_file_enabled_notify(parameter, dm_parameter->data);
iscopy = copy_temporary_file_to_original_file(DM_ENABLED_NOTIFY, DM_ENABLED_NOTIFY_TEMPORARY);
if(iscopy)
remove(DM_ENABLED_NOTIFY_TEMPORARY);
if (notification[0] == '1' || notification[0] == '2' || notification[0] == '4' || notification[0] == '6' )
add_list_value_change(parameter, dm_parameter->data, dm_parameter->type);
if (notification[0] == '2')
isactive = true;
}
}
//dm_ctx_clean_sub(&dmctx);
}
//dm_ctx_clean(&dmctx);
//dm_ctx_init(&dmctx);
fclose(fp);
list_for_each_entry(p, &list_enabled_lw_notify, list) {
if (!initiate || i != 0)
dm_ctx_init_sub(&dmctx, DM_CWMP, cwmp_main.conf.amd_version, cwmp_main.conf.instance_mode);
@ -341,19 +405,7 @@ void cwmp_add_notification(void)
}
pthread_mutex_unlock(&(cwmp->mutex_session_send));
if (isactive)
{
pthread_mutex_lock(&(cwmp->mutex_session_queue));
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
if (event_container == NULL)
{
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
return;
}
cwmp_save_event_container(cwmp,event_container);
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
pthread_cond_signal(&(cwmp->threshold_session_send));
return;
}
send_active_value_change();
}
void cwmp_root_cause_event_ipdiagnostic(void)