Ticket refs #4423: icwmpd: icwmpd leaks memory

This commit is contained in:
Omar Kallel 2021-03-23 13:36:13 +01:00
parent 50c44750dd
commit 5a4e7a0cfb
13 changed files with 615 additions and 693 deletions

View file

@ -809,7 +809,7 @@ void load_queue_event(mxml_node_t *tree, struct cwmp *cwmp)
if (c && c->type == MXML_OPAQUE) {
if (c->value.opaque != NULL) {
if (event_container_save != NULL) {
add_dm_parameter_tolist(&(event_container_save->head_dm_parameter), c->value.opaque, NULL, NULL);
add_dm_parameter_to_list(&(event_container_save->head_dm_parameter), c->value.opaque, NULL, NULL, 0, false);
}
}
}

View file

@ -77,7 +77,10 @@ int global_env_init(int argc, char **argv, struct env *env)
return CWMP_OK;
}
void add_dm_parameter_tolist(struct list_head *head, char *param_name, char *param_data, char *param_type)
/*
* List dm_paramter
*/
void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_val, char *param_type, int notification, bool writable)
{
struct cwmp_dm_parameter *dm_parameter;
struct list_head *ilist;
@ -86,10 +89,11 @@ void add_dm_parameter_tolist(struct list_head *head, char *param_name, char *par
dm_parameter = list_entry(ilist, struct cwmp_dm_parameter, list);
cmp = strcmp(dm_parameter->name, param_name);
if (cmp == 0) {
if (param_data && strcmp(dm_parameter->data, param_data) != 0) {
free(dm_parameter->data);
dm_parameter->data = strdup(param_data);
if (param_val && strcmp(dm_parameter->value, param_val) != 0) {
free(dm_parameter->value);
dm_parameter->value = strdup(param_val);
}
dm_parameter->notification = notification;
return;
} else if (cmp > 0) {
break;
@ -99,30 +103,35 @@ void add_dm_parameter_tolist(struct list_head *head, char *param_name, char *par
_list_add(&dm_parameter->list, ilist->prev, ilist);
if (param_name)
dm_parameter->name = strdup(param_name);
if (param_data)
dm_parameter->data = strdup(param_data);
if (param_val)
dm_parameter->value = strdup(param_val);
if (param_type)
dm_parameter->type = strdup(param_type ? param_type : "xsd:string");
dm_parameter->notification = notification;
dm_parameter->writable = writable;
}
void delete_dm_parameter_fromlist(struct cwmp_dm_parameter *dm_parameter)
void delete_dm_parameter_from_list(struct cwmp_dm_parameter *dm_parameter)
{
list_del(&dm_parameter->list);
free(dm_parameter->name);
free(dm_parameter->data);
free(dm_parameter->value);
free(dm_parameter->type);
free(dm_parameter);
}
void free_dm_parameter_all_fromlist(struct list_head *list)
void cwmp_free_all_dm_parameter_list(struct list_head *list)
{
struct cwmp_dm_parameter *dm_parameter;
while (list->next != list) {
dm_parameter = list_entry(list->next, struct cwmp_dm_parameter, list);
delete_dm_parameter_fromlist(dm_parameter);
delete_dm_parameter_from_list(dm_parameter);
}
}
/*
* List Fault parameter
*/
void cwmp_add_list_fault_param(char *param, int fault, struct list_head *list_set_value_fault)
{
struct cwmp_param_fault *param_fault;
@ -142,55 +151,36 @@ void cwmp_del_list_fault_param(struct cwmp_param_fault *param_fault)
free(param_fault);
}
void cwmp_add_list_param_value(char *param, char *value, struct list_head *list_param_value)
void cwmp_free_all_list_param_fault(struct list_head *list_param_fault)
{
struct cwmp_param_value *param_value = NULL;
if (param == NULL)
param = "";
param_value = calloc(1, sizeof(struct cwmp_param_value));
list_add_tail(&param_value->list, list_param_value);
param_value->param = strdup(param);
param_value->value = strdup(value ? value : "");
}
void cwmp_del_list_param_value(struct cwmp_param_value *param_value)
{
list_del(&param_value->list);
free(param_value->param);
free(param_value->value);
free(param_value);
}
void cwmp_free_all_list_param_value(struct list_head *list_param_value)
{
struct cwmp_param_value *param_value;
while (list_param_value->next != list_param_value) {
param_value = list_entry(list_param_value->next, struct cwmp_param_value, list);
cwmp_del_list_param_value(param_value);
struct cwmp_param_fault *param_fault;
while (list_param_fault->next != list_param_fault) {
param_fault = list_entry(list_param_fault->next, struct cwmp_param_fault, list);
cwmp_del_list_fault_param(param_fault);
}
}
///////////////////////////////////////////////////////////
int cwmp_asprintf(char **s, const char *format, ...)
{
int size;
char *str = NULL;
va_list arg, argcopy;
int size;
char *str = NULL;
va_list arg, argcopy;
va_start(arg,format);
va_copy(argcopy, arg);
size = vsnprintf(NULL, 0, format, argcopy);
if (size < 0)
return -1;
va_end(argcopy);
str = (char *)calloc(sizeof(char), size+1);
vsnprintf(str, size+1, format, arg);
va_end(arg);
*s = strdup(str);
FREE(str);
if (*s == NULL)
return -1;
return 0;
va_start(arg, format);
va_copy(argcopy, arg);
size = vsnprintf(NULL, 0, format, argcopy);
if (size < 0)
return -1;
va_end(argcopy);
str = (char *)calloc(sizeof(char), size + 1);
vsnprintf(str, size + 1, format, arg);
va_end(arg);
*s = strdup(str);
FREE(str);
if (*s == NULL)
return -1;
return 0;
}
bool folder_exists(const char *path)

3
cwmp.c
View file

@ -335,6 +335,7 @@ int run_session_end_func()
}
end_session_flag = 0;
cwmp_free_all_dm_parameter_list(&list_value_change);
return CWMP_OK;
}
@ -368,7 +369,7 @@ void cwmp_schedule_session(struct cwmp *cwmp)
if (is_notify > 0 || access(DM_ENABLED_NOTIFY, F_OK) < 0)
cwmp_update_enabled_notify_file();
cwmp_prepare_value_change(cwmp);
free_dm_parameter_all_fromlist(&list_value_change);
cwmp_free_all_dm_parameter_list(&list_value_change);
if ((error = cwmp_move_session_to_session_send(cwmp, session))) {
CWMP_LOG(EMERG, "FATAL error in the mutex process in the session scheduler!");
exit(EXIT_FAILURE);

View file

@ -15,367 +15,426 @@
bool transaction_started = false;
int transaction_id = 0;
json_object *old_global_json_obj = NULL;
json_object *actual_global_json_obj = NULL;
json_object *old_list_notify = NULL;
json_object *actual_list_notify = NULL;
json_object *str_json_parse_object = NULL;
enum get_results_types
{
LIST,
FAULT
};
struct object_result {
char **instance;
char fault[5];
bool status;
};
struct list_params_result {
struct list_head *parameters_list;
char fault[5];
enum get_results_types type;
};
struct setm_values_res {
bool status;
int *flag;
struct list_head *faults_list;
};
/*
* Common functions
*/
struct blob_attr *get_parameters_array(struct blob_attr *msg)
{
struct blob_attr *parameters = NULL;
struct blob_attr *cur;
int rem;
blobmsg_for_each_attr(cur, msg, rem)
{
if (blobmsg_type(cur) == BLOBMSG_TYPE_ARRAY) {
parameters = cur;
break;
}
}
return parameters;
}
char *get_status(struct blob_attr *msg)
{
char *status = NULL;
const struct blobmsg_policy p[1] = { { "status", BLOBMSG_TYPE_STRING } };
struct blob_attr *tb[1] = { NULL };
blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
if (tb[0])
status = blobmsg_get_string(tb[0]);
return status;
}
int get_fault(struct blob_attr *msg)
{
int fault = FAULT_CPE_NO_FAULT;
const struct blobmsg_policy p[1] = { { "fault", BLOBMSG_TYPE_INT32 } };
struct blob_attr *tb[1] = { NULL };
blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
if (tb[0])
fault = blobmsg_get_u32(tb[0]);
return fault;
}
void get_parameters_list_from_parameters_blob_array(struct blob_attr *parameters, struct list_head *parameters_list)
{
const struct blobmsg_policy p[5] = { { "parameter", BLOBMSG_TYPE_STRING }, { "value", BLOBMSG_TYPE_STRING }, { "type", BLOBMSG_TYPE_STRING }, { "notification", BLOBMSG_TYPE_STRING }, { "writable", BLOBMSG_TYPE_STRING } };
struct blob_attr *cur;
int rem;
blobmsg_for_each_attr(cur, parameters, rem)
{
struct blob_attr *tb[5] = { NULL, NULL, NULL, NULL, NULL };
blobmsg_parse(p, 5, tb, blobmsg_data(cur), blobmsg_len(cur));
if (!tb[0])
continue;
int notification = 0;
bool writable = 0;
if (tb[3] && strncmp(blobmsg_get_string(tb[3]), "1", 1) == 0)
notification = 1;
if (tb[3] && strncmp(blobmsg_get_string(tb[3]), "2", 1) == 0)
notification = 2;
if (tb[4] && (strncmp(blobmsg_get_string(tb[4]), "1", 1) == 0 || strcasecmp(blobmsg_get_string(tb[4]), "true") == 0))
writable = true;
add_dm_parameter_to_list(parameters_list, blobmsg_get_string(tb[0]), tb[1] ? blobmsg_get_string(tb[1]) : "", tb[2] ? blobmsg_get_string(tb[2]) : "", notification, writable);
}
}
int get_single_fault_from_blob_attr(struct blob_attr *msg)
{
int fault_code = FAULT_CPE_NO_FAULT;
fault_code = get_fault(msg);
if (fault_code != FAULT_CPE_NO_FAULT)
return fault_code;
struct blob_attr *faults_array = get_parameters_array(msg);
if (faults_array == NULL)
return FAULT_CPE_NO_FAULT;
struct blob_attr *cur;
int rem;
blobmsg_for_each_attr(cur, faults_array, rem)
{
fault_code = get_fault(cur);
if (fault_code != FAULT_CPE_NO_FAULT)
break;
}
return fault_code;
}
/*
* Transaction Functions
*/
int cwmp_transaction_start(char *app)
void ubus_transaction_callback(struct ubus_request *req __attribute__((unused)), int type __attribute__((unused)), struct blob_attr *msg)
{
bool *status = (bool *)req->priv;
const struct blobmsg_policy p[2] = { { "status", BLOBMSG_TYPE_BOOL }, { "transaction_id", BLOBMSG_TYPE_INT32 } };
struct blob_attr *tb[2] = { NULL, NULL };
blobmsg_parse(p, 2, tb, blobmsg_data(msg), blobmsg_len(msg));
*status = blobmsg_get_u8(tb[0]);
if (*status == true && tb[1])
transaction_id = blobmsg_get_u32(tb[1]);
}
void ubus_transaction_status_callback(struct ubus_request *req __attribute__((unused)), int type __attribute__((unused)), struct blob_attr *msg)
{
bool *status = (bool *)req->priv;
char *status_str = NULL;
const struct blobmsg_policy p[2] = { { "status", BLOBMSG_TYPE_STRING } };
struct blob_attr *tb[2] = { NULL, NULL };
blobmsg_parse(p, 2, tb, blobmsg_data(msg), blobmsg_len(msg));
status_str = blobmsg_get_string(tb[0]);
if (strcmp(status_str, "on-going") == 0)
*status = true;
else
*status = false;
}
bool cwmp_transaction_start(char *app)
{
CWMP_LOG(INFO, "Starting transaction ...");
json_object *transaction_ret = NULL, *status_obj = NULL, *transaction_id_obj = NULL;
int e = cwmp_ubus_call("usp.raw", "transaction_start", CWMP_UBUS_ARGS{ { "app", {.str_val = app }, UBUS_String } }, 1, &transaction_ret);
bool status = false;
int e = cwmp_ubus_call("usp.raw", "transaction_start", CWMP_UBUS_ARGS{ { "app", {.str_val = app }, UBUS_String } }, 1, ubus_transaction_callback, &status);
if (e != 0) {
FREE_JSON(transaction_ret)
CWMP_LOG(INFO, "Transaction start failed: Ubus err code: %d", e);
return 0;
status = false;
}
json_object_object_get_ex(transaction_ret, "status", &status_obj);
if (strcmp((char *)json_object_get_string(status_obj), "true") != 0) {
json_object *error = NULL;
json_object_object_get_ex(transaction_ret, "error", &error);
CWMP_LOG(INFO, "Transaction start failed: %s\n", (char *)json_object_get_string(error));
FREE_JSON(transaction_ret)
return 0;
}
json_object_object_get_ex(transaction_ret, "transaction_id", &transaction_id_obj);
if (transaction_id_obj == NULL) {
FREE_JSON(transaction_ret)
return 0;
}
transaction_id = atoi((char *)json_object_get_string(transaction_id_obj));
FREE_JSON(transaction_ret)
return 1;
return status;
}
int cwmp_transaction_commit()
bool cwmp_transaction_commit()
{
CWMP_LOG(INFO, "Transaction Commit ...");
json_object *transaction_ret = NULL, *status_obj = NULL;
int e = cwmp_ubus_call("usp.raw", "transaction_commit", CWMP_UBUS_ARGS{ { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 1, &transaction_ret);
bool status = false;
int e = cwmp_ubus_call("usp.raw", "transaction_commit", CWMP_UBUS_ARGS{ { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 1, ubus_transaction_callback, &status);
if (e != 0) {
FREE_JSON(transaction_ret)
CWMP_LOG(INFO, "Transaction commit failed: Ubus err code: %d", e)
return 0;
CWMP_LOG(INFO, "Transaction commit failed: Ubus err code: %d", e);
status = false;
}
json_object_object_get_ex(transaction_ret, "status", &status_obj);
if (strcmp((char *)json_object_get_string(status_obj), "true") != 0) {
json_object *error = NULL;
json_object_object_get_ex(transaction_ret, "error", &error);
CWMP_LOG(INFO, "Transaction commit failed: %s\n", (char *)json_object_get_string(error));
transaction_id = 0;
FREE_JSON(transaction_ret)
return 0;
}
FREE_JSON(transaction_ret)
transaction_id = 0;
return 1;
return status;
}
int cwmp_transaction_abort()
bool cwmp_transaction_abort()
{
CWMP_LOG(INFO, "Transaction Abort ...");
json_object *transaction_ret = NULL, *status_obj = NULL;
int e = cwmp_ubus_call("usp.raw", "transaction_abort", CWMP_UBUS_ARGS{ { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 1, &transaction_ret);
bool status = false;
int e = cwmp_ubus_call("usp.raw", "transaction_abort", CWMP_UBUS_ARGS{ { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 1, ubus_transaction_callback, &status);
if (e != 0) {
FREE_JSON(transaction_ret)
CWMP_LOG(INFO, "Transaction abort failed: Ubus err code: %d", e);
return 0;
status = false;
}
json_object_object_get_ex(transaction_ret, "status", &status_obj);
if (strcmp((char *)json_object_get_string(status_obj), "true") != 0) {
json_object *error = NULL;
json_object_object_get_ex(transaction_ret, "error", &error);
CWMP_LOG(INFO, "Transaction abort failed: %s\n", (char *)json_object_get_string(error));
FREE_JSON(transaction_ret)
return 0;
}
return 1;
return status;
}
int cwmp_transaction_status()
bool cwmp_transaction_status()
{
CWMP_LOG(INFO, "Transaction Status");
json_object *status_obj = NULL, *transaction_ret = NULL;
int e = cwmp_ubus_call("usp.raw", "transaction_status", CWMP_UBUS_ARGS{ { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 1, &transaction_ret);
bool status = false;
int e = cwmp_ubus_call("usp.raw", "transaction_status", CWMP_UBUS_ARGS{ { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 1, ubus_transaction_status_callback, &status);
if (e != 0) {
CWMP_LOG(INFO, "Transaction status failed: Ubus err code: %d", e);
return 0;
return false;
}
json_object_object_get_ex(transaction_ret, "status", &status_obj);
if (!status_obj || strcmp((char *)json_object_get_string(status_obj), "on-going") != 0) {
if (!status)
CWMP_LOG(INFO, "Transaction with id: %d is not available anymore\n", transaction_id);
FREE_JSON(transaction_ret)
return 0;
}
return 1;
return status;
}
/*
* RPC Methods Functions
* Get parameter Values/Names/Notify
*/
char *cwmp_get_parameter_values(char *parameter_name, json_object **parameters)
void ubus_get_parameter_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
char *fault = NULL;
int 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, &str_json_parse_object);
if (e < 0 || str_json_parse_object == NULL) {
*parameters = NULL;
return "9002";
struct blob_attr *parameters = get_parameters_array(msg);
struct list_params_result *result = (struct list_params_result *)req->priv;
if (parameters == NULL) {
int fault_code = get_fault(msg);
snprintf(result->fault, 5, "%d", fault_code);
result->type = FAULT;
return;
}
json_object *fault_code = NULL;
json_object_object_get_ex(str_json_parse_object, "fault", &fault_code);
if (fault_code != NULL) {
*parameters = NULL;
fault = strdup((char *)json_object_get_string(fault_code));
return fault;
}
json_object_object_get_ex(str_json_parse_object, "parameters", parameters);
return NULL;
result->type = LIST;
get_parameters_list_from_parameters_blob_array(parameters, result->parameters_list);
}
char *cwmp_set_parameter_value(char *parameter_name, char *value, char *parameter_key, int *flag)
char *cwmp_get_parameter_values(char *parameter_name, struct list_head *parameters_list)
{
json_object *set_res;
char *fault = NULL;
int e = cwmp_ubus_call("usp.raw", "set", CWMP_UBUS_ARGS{ { "path", {.str_val = parameter_name }, UBUS_String }, { "value", {.str_val = value }, UBUS_String }, { "key", {.str_val = parameter_key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 3,
&set_res);
if (e < 0 || set_res == NULL)
return "9002";
json_object *fault_code = NULL;
json_object_object_get_ex(set_res, "fault", &fault_code);
if (fault_code != NULL) {
fault = strdup((char *)json_object_get_string(fault_code));
return fault;
}
json_object *status = NULL;
json_object_object_get_ex(set_res, "status", &status);
char *status_str = NULL;
if (status) {
status_str = (char *)json_object_get_string(status);
if (status_str && strcmp(status_str, "true") == 0) {
json_object *flag_obj = NULL;
json_object_object_get_ex(set_res, "flag", &flag_obj);
*flag = flag_obj ? atoi((char *)json_object_get_string(flag_obj)) : 0;
FREE_JSON(set_res)
return NULL;
}
}
json_object *parameters = NULL;
json_object_object_get_ex(set_res, "parameters", &parameters);
if (!parameters) {
FREE_JSON(set_res)
int e;
struct list_params_result get_result = {.parameters_list = parameters_list };
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_parameter_callback, &get_result);
if (e < 0) {
CWMP_LOG(INFO, "get ubus method failed: Ubus err code: %d", e);
return strdup("9002");
}
json_object *param_obj = json_object_array_get_idx(parameters, 0);
json_object_object_get_ex(param_obj, "status", &status);
status_str = (char *)json_object_get_string(status);
if (status_str && strcmp(status_str, "false") == 0) {
json_object *fault = NULL;
json_object_object_get_ex(param_obj, "fault", &fault);
char *fault_code = strdup(fault ? (char *)json_object_get_string(fault) : "");
FREE_JSON(set_res)
return fault_code;
}
FREE_JSON(set_res)
if (get_result.type == FAULT)
return strdup(get_result.fault);
return NULL;
}
char *cwmp_set_multiple_parameters_values(struct list_head parameters_values_list, char *parameter_key, int *flag, json_object **faults_array)
char *cwmp_get_parameter_names(char *object_name, bool next_level, struct list_head *parameters_list)
{
int e = cwmp_ubus_call("usp.raw", "setm_values", CWMP_UBUS_ARGS{ { "pv_tuple", {.param_value_list = &parameters_values_list }, UBUS_List_Param }, { "key", {.str_val = parameter_key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 3,
&str_json_parse_object);
if (e < 0 || str_json_parse_object == NULL)
return "9002";
int e;
struct list_params_result get_result = {.parameters_list = parameters_list };
e = cwmp_ubus_call("usp.raw", "object_names", CWMP_UBUS_ARGS{ { "path", {.str_val = object_name }, UBUS_String }, { "next-level", {.bool_val = next_level }, UBUS_Bool } }, 2, ubus_get_parameter_callback, &get_result);
if (e < 0) {
CWMP_LOG(INFO, "object_names ubus method failed: Ubus err code: %d", e);
return strdup("9002");
}
json_object *status = NULL;
json_object_object_get_ex(str_json_parse_object, "status", &status);
char *status_str = NULL;
if (status) {
status_str = (char *)json_object_get_string(status);
if (status_str && strcmp(status_str, "true") == 0) {
json_object *flag_obj = NULL;
json_object_object_get_ex(str_json_parse_object, "flag", &flag_obj);
*flag = flag_obj ? atoi((char *)json_object_get_string(flag_obj)) : 0;
free(status_str);
status_str = NULL;
return NULL;
}
if (status_str) {
free(status_str);
status_str = NULL;
if (get_result.type == FAULT) {
CWMP_LOG(INFO, "Get parameter_values failed: fault_code: %s", get_result.fault);
return strdup(get_result.fault);
}
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
*/
void ubus_setm_values_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
struct setm_values_res *set_result = (struct setm_values_res *)req->priv;
const struct blobmsg_policy p[2] = { { "status", BLOBMSG_TYPE_BOOL }, { "flag", BLOBMSG_TYPE_INT64 } };
struct blob_attr *tb[2] = { NULL, NULL };
blobmsg_parse(p, 2, tb, blobmsg_data(msg), blobmsg_len(msg));
if (tb[0]) {
set_result->status = blobmsg_get_u8(tb[0]);
if (set_result->status) {
int *flag = set_result->flag;
*flag = tb[1] ? blobmsg_get_u64(tb[1]) : 0;
return;
}
}
json_object_object_get_ex(str_json_parse_object, "parameters", faults_array);
return "Fault";
set_result->status = false;
struct blob_attr *faults_params = get_parameters_array(msg);
const struct blobmsg_policy pfault[3] = { { "path", BLOBMSG_TYPE_STRING }, { "fault", BLOBMSG_TYPE_INT32 }, { "status", BLOBMSG_TYPE_BOOL } };
struct blob_attr *cur;
int rem;
blobmsg_for_each_attr(cur, faults_params, rem)
{
struct blob_attr *tb[3] = { NULL, NULL, NULL };
blobmsg_parse(pfault, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
if (!tb[0] || !tb[1])
continue;
cwmp_add_list_fault_param(blobmsg_get_string(tb[0]), blobmsg_get_u32(tb[1]), set_result->faults_list);
}
}
int cwmp_set_multiple_parameters_values(struct list_head parameters_values_list, char *parameter_key, int *flag, struct list_head *faults_list)
{
int e;
struct setm_values_res set_result = {.flag = flag, .faults_list = faults_list };
e = cwmp_ubus_call("usp.raw", "setm_values", CWMP_UBUS_ARGS{ { "pv_tuple", {.param_value_list = &parameters_values_list }, UBUS_List_Param }, { "key", {.str_val = parameter_key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 3, ubus_setm_values_callback,
&set_result);
if (e < 0) {
CWMP_LOG(INFO, "setm_values ubus method failed: Ubus err code: %d", e);
return FAULT_CPE_INTERNAL_ERROR;
}
if (set_result.status == false) {
CWMP_LOG(INFO, "Set parameter_values failed");
return FAULT_CPE_INVALID_ARGUMENTS;
}
return FAULT_CPE_NO_FAULT;
}
/*
* Add Delete object
*/
void ubus_objects_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
int fault_code = get_single_fault_from_blob_attr(msg);
struct object_result *result = (struct object_result *)req->priv;
if (fault_code != FAULT_CPE_NO_FAULT) {
snprintf(result->fault, 5, "%d", fault_code);
result->status = false;
return;
}
struct blob_attr *parameters = get_parameters_array(msg);
const struct blobmsg_policy p[2] = { { "status", BLOBMSG_TYPE_BOOL }, { "instance", BLOBMSG_TYPE_STRING } };
struct blob_attr *cur;
int rem;
blobmsg_for_each_attr(cur, parameters, rem)
{
struct blob_attr *tb[2] = { NULL, NULL };
blobmsg_parse(p, 2, tb, blobmsg_data(cur), blobmsg_len(cur));
if (!tb[0])
continue;
result->status = blobmsg_get_u8(tb[0]);
if (tb[1]) {
char **instance = result->instance;
*instance = strdup(blobmsg_get_string(tb[1]));
}
break;
}
}
char *cwmp_add_object(char *object_name, char *key, char **instance)
{
json_object *add_res;
char *err = NULL;
int e;
struct object_result add_result = {.instance = instance };
e = cwmp_ubus_call("usp.raw", "add_object", CWMP_UBUS_ARGS{ { "path", {.str_val = object_name }, UBUS_String }, { "key", {.str_val = key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 3, ubus_objects_callback, &add_result);
int e = cwmp_ubus_call("usp.raw", "add_object", CWMP_UBUS_ARGS{ { "path", {.str_val = object_name }, UBUS_String }, { "key", {.str_val = key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 3, &add_res);
if (e < 0 || add_res == NULL) {
FREE_JSON(add_res)
return "9002";
if (e < 0) {
CWMP_LOG(INFO, "add_object ubus method failed: Ubus err code: %d", e);
return strdup("9002");
}
json_object *fault_code = NULL;
json_object_object_get_ex(add_res, "fault", &fault_code);
if (fault_code != NULL) {
err = strdup((char *)json_object_get_string(fault_code));
FREE_JSON(add_res)
return err;
if (add_result.status == false) {
CWMP_LOG(INFO, "AddObject failed");
return strdup(add_result.fault);
}
json_object *parameters = NULL;
json_object_object_get_ex(add_res, "parameters", &parameters);
if (parameters == NULL) {
FREE_JSON(add_res)
return "9002";
}
json_object *param_obj = json_object_array_get_idx(parameters, 0);
json_object *fault = NULL;
json_object_object_get_ex(param_obj, "fault", &fault);
if (fault) {
err = strdup((char *)json_object_get_string(fault));
FREE_JSON(add_res)
return err;
}
json_object *instance_obj = NULL;
json_object_object_get_ex(param_obj, "instance", &instance_obj);
*instance = strdup((char *)json_object_get_string(instance_obj));
FREE_JSON(add_res)
return NULL;
}
char *cwmp_delete_object(char *object_name, char *key)
{
json_object *del_res;
char *err = NULL;
int e;
struct object_result add_result = {.instance = NULL };
e = cwmp_ubus_call("usp.raw", "del_object", CWMP_UBUS_ARGS{ { "path", {.str_val = object_name }, UBUS_String }, { "key", {.str_val = key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 3, ubus_objects_callback, &add_result);
if (e < 0) {
CWMP_LOG(INFO, "del_object ubus method failed: Ubus err code: %d", e);
return strdup("9002");
}
int e = cwmp_ubus_call("usp.raw", "del_object", CWMP_UBUS_ARGS{ { "path", {.str_val = object_name }, UBUS_String }, { "key", {.str_val = key }, UBUS_String }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 3, &del_res);
if (e < 0 || del_res == NULL) {
FREE_JSON(del_res)
return "9002";
if (add_result.status == false) {
CWMP_LOG(INFO, "DeleteObject failed");
return strdup(add_result.fault);
}
json_object *fault_code = NULL;
json_object_object_get_ex(del_res, "fault", &fault_code);
if (fault_code != NULL) {
err = strdup((char *)json_object_get_string(fault_code));
FREE_JSON(del_res)
return err;
}
json_object *parameters = NULL;
json_object_object_get_ex(del_res, "parameters", &parameters);
json_object *param_obj = json_object_array_get_idx(parameters, 0);
json_object *status = NULL;
json_object_object_get_ex(param_obj, "status", &status);
char *status_str = (char *)json_object_get_string(status);
if (status_str && strcmp(status_str, "false") == 0) {
json_object *fault = NULL;
json_object_object_get_ex(param_obj, "fault", &fault);
err = strdup((char *)json_object_get_string(fault));
FREE_JSON(del_res)
return err;
}
FREE_JSON(del_res)
return NULL;
}
char *cwmp_get_parameter_names(char *object_name, bool next_level, json_object **parameters)
{
char *err = NULL;
/*
* GET SET Parameter Attributes
*/
int e = cwmp_ubus_call("usp.raw", "object_names", CWMP_UBUS_ARGS{ { "path", {.str_val = object_name }, UBUS_String }, { "next-level", {.bool_val = next_level }, UBUS_Bool } }, 2, &str_json_parse_object);
if (e < 0 || str_json_parse_object == NULL)
return "9002";
json_object *fault_code = NULL;
json_object_object_get_ex(str_json_parse_object, "fault", &fault_code);
if (fault_code != NULL) {
*parameters = NULL;
err = strdup((char *)json_object_get_string(fault_code));
return err;
void ubus_parameter_attributes_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg)
{
int fault_code = get_single_fault_from_blob_attr(msg);
struct list_params_result *result = (struct list_params_result *)req->priv;
if (fault_code != FAULT_CPE_NO_FAULT) {
snprintf(result->fault, 5, "%d", fault_code);
result->type = FAULT;
return;
}
result->type = LIST;
if (result->parameters_list != NULL) {
struct blob_attr *parameters = get_parameters_array(msg);
get_parameters_list_from_parameters_blob_array(parameters, result->parameters_list);
}
json_object_object_get_ex(str_json_parse_object, "parameters", parameters);
return NULL;
}
char *cwmp_get_parameter_attributes(char *parameter_name, json_object **parameters)
char *cwmp_get_parameter_attributes(char *parameter_name, struct list_head *parameters_list)
{
char *err = NULL;
int e;
struct list_params_result get_result = {.parameters_list = parameters_list };
e = cwmp_ubus_call("usp.raw", "getm_attributes", CWMP_UBUS_ARGS{ { "paths", {.array_value = { {.str_value = !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name } } }, UBUS_Array_Str } }, 1, ubus_parameter_attributes_callback, &get_result);
if (e < 0) {
CWMP_LOG(INFO, "getm_attributes ubus method failed: Ubus err code: %d", e);
return strdup("9002");
}
int e = cwmp_ubus_call("usp.raw", "getm_attributes", CWMP_UBUS_ARGS{ { "paths", {.array_value = { {.str_value = !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name } } }, UBUS_Array_Str } }, 1, &str_json_parse_object);
if (e < 0 || str_json_parse_object == NULL)
return "9002";
json_object *fault_code = NULL;
json_object_object_get_ex(str_json_parse_object, "fault", &fault_code);
if (fault_code != NULL) {
*parameters = NULL;
err = strdup((char *)json_object_get_string(fault_code));
return err;
if (get_result.type == FAULT) {
CWMP_LOG(INFO, "GetParameterAttributes failed");
return strdup(get_result.fault);
}
json_object_object_get_ex(str_json_parse_object, "parameters", parameters);
json_object *fault = NULL, *param_obj = NULL;
foreach_jsonobj_in_array(param_obj, *parameters)
{
json_object_object_get_ex(param_obj, "fault", &fault);
if (fault) {
err = strdup((char *)json_object_get_string(fault));
break;
}
}
return err;
return NULL;
}
char *cwmp_set_parameter_attributes(char *parameter_name, char *notification)
{
json_object *set_attribute_res;
char *err = NULL;
int e = cwmp_ubus_call("usp.raw", "setm_attributes",
CWMP_UBUS_ARGS{ { "paths", {.array_value = { {.param_value = { "path", parameter_name } }, {.param_value = { "notify-type", notification } }, {.param_value = { "notify", "1" } } } }, UBUS_Array_Obj }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } },
2, &set_attribute_res);
if (e < 0 || set_attribute_res == NULL) {
FREE_JSON(set_attribute_res)
return "9002";
}
json_object *parameters = NULL;
json_object_object_get_ex(set_attribute_res, "parameters", &parameters);
json_object *param_obj = json_object_array_get_idx(parameters, 0);
json_object *fault_code = NULL;
json_object_object_get_ex(param_obj, "fault", &fault_code);
if (fault_code != NULL)
err = strdup((char *)json_object_get_string(fault_code));
FREE_JSON(set_attribute_res)
return err;
}
/*
* Init Notify Function
*/
int cwmp_update_enabled_list_notify(int instance_mode, int notify_type)
{
int e;
CWMP_LOG(DEBUG, "Get List Notify for %s paramters values", notify_type == OLD_LIST_NOTIFY ? "old" : "actual");
if (notify_type == OLD_LIST_NOTIFY) {
FREE_JSON(old_global_json_obj)
e = cwmp_ubus_call("usp.raw", "list_notify", CWMP_UBUS_ARGS{ { "instance_mode", {.int_val = instance_mode }, UBUS_Integer } }, 1, &old_global_json_obj);
if (e)
return e;
json_object_object_get_ex(old_global_json_obj, "parameters", &old_list_notify);
} else {
FREE_JSON(actual_global_json_obj)
e = cwmp_ubus_call("usp.raw", "list_notify", CWMP_UBUS_ARGS{ { "instance_mode", {.int_val = instance_mode }, UBUS_Integer } }, 1, &actual_global_json_obj);
if (e)
return e;
json_object_object_get_ex(actual_global_json_obj, "parameters", &actual_list_notify);
struct list_params_result set_result = {.parameters_list = NULL };
e = cwmp_ubus_call("usp.raw", "setm_attributes",
CWMP_UBUS_ARGS{ { "paths", {.array_value = { {.param_value = { "path", parameter_name } }, {.param_value = { "notify-type", notification } }, {.param_value = { "notify", "1" } } } }, UBUS_Array_Obj }, { "transaction_id", {.int_val = transaction_id }, UBUS_Integer } }, 2,
ubus_parameter_attributes_callback, &set_result);
if (e < 0) {
CWMP_LOG(INFO, "setm_attributes ubus method failed: Ubus err code: %d", e);
return strdup("9002");
}
return 0;
if (set_result.type == FAULT) {
CWMP_LOG(INFO, "SetParameterAttributes failed");
return strdup(set_result.fault);
}
return NULL;
}

View file

@ -71,34 +71,28 @@ struct diagnostic_input upload_diagnostics_array[UPLOAD_NUMBER_INPUTS] = {
//{"TimeBasedTestMeasurementOffset","Device.IP.Diagnostics.UploadDiagnostics.TimeBasedTestMeasurementOffset",NULL}
};
struct diagnostic_input ipping_diagnostics_array[IPPING_NUMBER_INPUTS] = {
{ "Host", "Device.IP.Diagnostics.IPPing.Host", NULL },
{ "NumberOfRepetitions", "Device.IP.Diagnostics.IPPing.NumberOfRepetitions", NULL },
{ "Timeout", "Device.IP.Diagnostics.IPPing.Timeout", NULL },
{ "Interface", "Device.IP.Diagnostics.IPPing.Interface", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.IPPing.ProtocolVersion", NULL },
{ "DSCP", "Device.IP.Diagnostics.IPPing.DSCP", NULL },
{ "DataBlockSize", "Device.IP.Diagnostics.IPPing.DataBlockSize", NULL }
};
struct diagnostic_input seserverselection_diagnostics_array[SESERVERSELECT_NUMBER_INPUTS] = {
{ "Interface", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Interface", NULL },
{ "Protocol", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Protocol", NULL },
{ "HostList", "Device.IP.Diagnostics.ServerSelectionDiagnostics.HostList", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.ServerSelectionDiagnostics.ProtocolVersion", NULL },
{ "NumberOfRepetitions", "Device.IP.Diagnostics.ServerSelectionDiagnostics.NumberOfRepetitions", NULL },
{ "Timeout", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Timeout", NULL }
};
struct diagnostic_input ipping_diagnostics_array[IPPING_NUMBER_INPUTS] = { { "Host", "Device.IP.Diagnostics.IPPing.Host", NULL },
{ "NumberOfRepetitions", "Device.IP.Diagnostics.IPPing.NumberOfRepetitions", NULL },
{ "Timeout", "Device.IP.Diagnostics.IPPing.Timeout", NULL },
{ "Interface", "Device.IP.Diagnostics.IPPing.Interface", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.IPPing.ProtocolVersion", NULL },
{ "DSCP", "Device.IP.Diagnostics.IPPing.DSCP", NULL },
{ "DataBlockSize", "Device.IP.Diagnostics.IPPing.DataBlockSize", NULL } };
struct diagnostic_input seserverselection_diagnostics_array[SESERVERSELECT_NUMBER_INPUTS] = { { "Interface", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Interface", NULL },
{ "Protocol", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Protocol", NULL },
{ "HostList", "Device.IP.Diagnostics.ServerSelectionDiagnostics.HostList", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.ServerSelectionDiagnostics.ProtocolVersion", NULL },
{ "NumberOfRepetitions", "Device.IP.Diagnostics.ServerSelectionDiagnostics.NumberOfRepetitions", NULL },
{ "Timeout", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Timeout", NULL } };
struct diagnostic_input traceroute_diagnostics_array[TRACEROUTE_NUMBER_INPUTS] = {
{ "Interface", "Device.IP.Diagnostics.TraceRoute.Interface", NULL },
{ "Host", "Device.IP.Diagnostics.TraceRoute.Host", NULL },
{ "NumberOfTries", "Device.IP.Diagnostics.TraceRoute.NumberOfTries", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.TraceRoute.ProtocolVersion", NULL },
{ "Timeout", "Device.IP.Diagnostics.TraceRoute.Timeout", NULL },
{ "DataBlockSize", "Device.IP.Diagnostics.TraceRoute.DataBlockSize", NULL },
{ "DSCP", "Device.IP.Diagnostics.TraceRoute.DSCP", NULL },
{ "MaxHopCount", "Device.IP.Diagnostics.TraceRoute.MaxHopCount", NULL }
};
struct diagnostic_input traceroute_diagnostics_array[TRACEROUTE_NUMBER_INPUTS] = { { "Interface", "Device.IP.Diagnostics.TraceRoute.Interface", NULL },
{ "Host", "Device.IP.Diagnostics.TraceRoute.Host", NULL },
{ "NumberOfTries", "Device.IP.Diagnostics.TraceRoute.NumberOfTries", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.TraceRoute.ProtocolVersion", NULL },
{ "Timeout", "Device.IP.Diagnostics.TraceRoute.Timeout", NULL },
{ "DataBlockSize", "Device.IP.Diagnostics.TraceRoute.DataBlockSize", NULL },
{ "DSCP", "Device.IP.Diagnostics.TraceRoute.DSCP", NULL },
{ "MaxHopCount", "Device.IP.Diagnostics.TraceRoute.MaxHopCount", NULL } };
struct diagnostic_input udpecho_diagnostics_array[UDPECHO_NUMBER_INPUTS] = {
{ "Interface", "Device.IP.Diagnostics.UDPEchoDiagnostics.Interface", NULL },
@ -113,13 +107,11 @@ struct diagnostic_input udpecho_diagnostics_array[UDPECHO_NUMBER_INPUTS] = {
//{"EnableIndividualPacketResults","Device.IP.Diagnostics.UDPEchoDiagnostics.EnableIndividualPacketResults",NULL}
};
struct diagnostic_input nslookup_diagnostics_array[NSLKUP_NUMBER_INPUTS] = {
{ "Interface", "Device.DNS.Diagnostics.NSLookupDiagnostics.Interface", NULL },
{ "HostName", "Device.DNS.Diagnostics.NSLookupDiagnostics.HostName", NULL },
{ "DNSServer", "Device.DNS.Diagnostics.NSLookupDiagnostics.DNSServer", NULL },
{ "NumberOfRepetitions", "Device.DNS.Diagnostics.NSLookupDiagnostics.NumberOfRepetitions", NULL },
{ "Timeout", "Device.DNS.Diagnostics.NSLookupDiagnostics.Timeout", NULL }
};
struct diagnostic_input nslookup_diagnostics_array[NSLKUP_NUMBER_INPUTS] = { { "Interface", "Device.DNS.Diagnostics.NSLookupDiagnostics.Interface", NULL },
{ "HostName", "Device.DNS.Diagnostics.NSLookupDiagnostics.HostName", NULL },
{ "DNSServer", "Device.DNS.Diagnostics.NSLookupDiagnostics.DNSServer", NULL },
{ "NumberOfRepetitions", "Device.DNS.Diagnostics.NSLookupDiagnostics.NumberOfRepetitions", NULL },
{ "Timeout", "Device.DNS.Diagnostics.NSLookupDiagnostics.Timeout", NULL } };
static bool set_specific_diagnostic_object_parameter_structure_value(struct diagnostic_input (*diagnostics_array)[], int number_inputs, char *parameter, char *value)
{
@ -142,6 +134,7 @@ bool set_diagnostic_parameter_structure_value(char *parameter_name, char *value)
set_specific_diagnostic_object_parameter_structure_value(&seserverselection_diagnostics_array, SESERVERSELECT_NUMBER_INPUTS, parameter_name, value);
}
void empty_ubus_callback(struct ubus_request *req __attribute__((unused)), int type __attribute__((unused)), struct blob_attr *msg __attribute__((unused))) {}
static int cwmp_diagnostics_operate(char *diagnostics_object, char *action_name, struct diagnostic_input diagnostics_array[], int number_inputs)
{
int e, i;
@ -150,10 +143,9 @@ static int cwmp_diagnostics_operate(char *diagnostics_object, char *action_name,
for (i = 0; i < number_inputs; i++) {
if (diagnostics_array[i].value == NULL || diagnostics_array[i].value[0] == '\0')
continue;
cwmp_add_list_param_value(diagnostics_array[i].input_name, diagnostics_array[i].value, &diagnostics_param_value_list);
add_dm_parameter_to_list(&diagnostics_param_value_list, diagnostics_array[i].input_name, diagnostics_array[i].value, NULL, 0, false);
}
e = cwmp_ubus_call("usp.raw", "operate", CWMP_UBUS_ARGS{ { "path", {.str_val = diagnostics_object }, UBUS_String }, { "action", {.str_val = action_name }, UBUS_String }, { "input", {.param_value_list = &diagnostics_param_value_list }, UBUS_Obj_Obj } }, 3, &old_global_json_obj);
e = cwmp_ubus_call("usp.raw", "operate", CWMP_UBUS_ARGS{ { "path", {.str_val = diagnostics_object }, UBUS_String }, { "action", {.str_val = action_name }, UBUS_String }, { "input", {.param_value_list = &diagnostics_param_value_list }, UBUS_Obj_Obj } }, 3, empty_ubus_callback, NULL);
if (e)
return -1;
return 0;

View file

@ -145,7 +145,7 @@ int event_remove_all_event_container(struct session *session, int rem_from)
remove("/etc/icwmpd/.icwmpd_boot");
}
free(event_container->command_key);
free_dm_parameter_all_fromlist(&(event_container->head_dm_parameter));
cwmp_free_all_dm_parameter_list(&(event_container->head_dm_parameter));
list_del(&(event_container->list));
free(event_container);
}
@ -162,7 +162,7 @@ int event_remove_noretry_event_container(struct session *session, struct cwmp *c
event_container = list_entry(ilist, struct event_container, list);
if (EVENT_CONST[event_container->code].RETRY == 0) {
free(event_container->command_key);
free_dm_parameter_all_fromlist(&(event_container->head_dm_parameter));
cwmp_free_all_dm_parameter_list(&(event_container->head_dm_parameter));
list_del(&(event_container->list));
free(event_container);
}
@ -217,7 +217,7 @@ int cwmp_root_cause_event_bootstrap(struct cwmp *cwmp)
}
char buf[64] = "Device.ManagementServer.URL";
add_dm_parameter_tolist(&(event_container->head_dm_parameter), buf, NULL, NULL);
add_dm_parameter_to_list(&(event_container->head_dm_parameter), buf, NULL, NULL, 0, false);
cwmp_save_event_container(event_container);
save_acs_bkp_config(cwmp);
cwmp_scheduleInform_remove_all();

View file

@ -19,6 +19,7 @@
#include <libubox/list.h>
#include <sys/time.h>
#include <pthread.h>
#include <stdbool.h>
#ifndef CWMP_VERSION
#define CWMP_VERSION "3.0.0"
@ -127,7 +128,7 @@ typedef struct cwmp {
int count_handle_notify;
int retry_count_session;
struct list_head *head_event_container;
FILE* pid_file;
FILE *pid_file;
time_t start_time;
struct session_status session_status;
unsigned int cwmp_id;
@ -183,17 +184,13 @@ struct cwmp_param_fault {
int fault;
};
struct cwmp_param_value {
struct list_head list;
char *param;
char *value;
};
struct cwmp_dm_parameter {
struct list_head list;
char *name;
char *data;
char *value;
char *type;
int notification;
bool writable;
};
enum amd_version_enum
@ -440,15 +437,13 @@ typedef struct opfault {
extern struct cwmp cwmp_main;
int cwmp_exit(void);
void add_dm_parameter_tolist(struct list_head *head, char *param_name, char *param_data, char *param_type);
void delete_dm_parameter_fromlist(struct cwmp_dm_parameter *dm_parameter);
void free_dm_parameter_all_fromlist(struct list_head *list);
void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_data, char *param_type, int notification, bool writable);
void delete_dm_parameter_from_list(struct cwmp_dm_parameter *dm_parameter);
void cwmp_free_all_dm_parameter_list(struct list_head *list);
int global_env_init(int argc, char **argv, struct env *env);
void cwmp_add_list_fault_param(char *param, int fault, struct list_head *list_set_value_fault);
void cwmp_del_list_fault_param(struct cwmp_param_fault *param_fault);
void cwmp_add_list_param_value(char *param, char *value, struct list_head *list_param_value);
void cwmp_del_list_param_value(struct cwmp_param_value *param_value);
void cwmp_free_all_list_param_value(struct list_head *list_param_value);
void cwmp_free_all_list_param_fault(struct list_head *list_param_fault);
int cwmp_asprintf(char **s, const char *format, ...);
bool folder_exists(const char *path);

View file

@ -20,11 +20,6 @@ struct cwmp_json_arg {
};
#define CWMP_JSON_ARGS (struct cwmp_json_arg[])
#define FREE_JSON(jobj) \
if (jobj) { \
json_object_put(jobj); \
jobj = NULL; \
}
int cwmp_handle_download_fault(char *msg);
int cwmp_handle_upload_fault(char *msg);
int cwmp_handle_dustate_change_fault(char *msg);

View file

@ -6,30 +6,18 @@
#define DM_ROOT_OBJ "Device."
extern bool transaction_started;
extern int transaction_id;
extern json_object *old_global_json_obj;
extern json_object *actual_global_json_obj;
extern json_object *old_list_notify;
extern json_object *actual_list_notify;
extern json_object *str_json_parse_object;
enum notify_type
{
OLD_LIST_NOTIFY,
ACTUAL_LIST_NOTIFY
};
int cwmp_transaction_start(char *app);
int cwmp_transaction_commit();
int cwmp_transaction_abort();
int cwmp_transaction_status();
char *cwmp_get_parameter_values(char *parameter_name, json_object **parameters);
char *cwmp_set_parameter_value(char *parameter_name, char *value, char *parameter_key, int *flag);
char *cwmp_set_multiple_parameters_values(struct list_head parameters_values_list, char *parameter_key, int *flag, json_object **faults_array);
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);
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, json_object **parameters);
char *cwmp_get_parameter_attributes(char *parameter_name, json_object **parameters);
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, int notify_type);
int cwmp_update_enabled_list_notify(int instance_moden, struct list_head *parameters_list);
#endif /* SRC_DATAMODELIFACE_H_ */

View file

@ -12,9 +12,13 @@
#ifndef _FREECWMP_UBUS_H__
#define _FREECWMP_UBUS_H__
#include <json-c/json.h>
#include <libubox/blobmsg_json.h>
#include <libubus.h>
#include "common.h"
#define ARRAY_MAX 8
extern struct ubus_context *ubus_ctx;
int ubus_init(struct cwmp *cwmp);
void ubus_exit(void);
@ -54,7 +58,7 @@ struct cwmp_ubus_arg {
};
#define CWMP_UBUS_ARGS (struct cwmp_ubus_arg[])
int cwmp_ubus_call(const char *obj, const char *method, const struct cwmp_ubus_arg u_args[], int u_args_size, json_object **json_ret);
int cwmp_ubus_init();
void cwmp_ubus_close();
int cwmp_ubus_call(const char *obj, const char *method, const struct cwmp_ubus_arg u_args[], int u_args_size, void (*ubus_callback)(struct ubus_request *req, int type, struct blob_attr *msg), void *callback_arg);
#endif /* UBUS_H_ */

View file

@ -23,51 +23,40 @@ int cwmp_update_enabled_notify_file()
{
struct cwmp *cwmp = &cwmp_main;
FILE *fp;
json_object *param_obj = NULL, *param_name_obj = NULL, *value_obj = NULL, *type_obj = NULL, *notification_obj = NULL;
int e = cwmp_update_enabled_list_notify(cwmp->conf.instance_mode, OLD_LIST_NOTIFY);
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);
fp = fopen(DM_ENABLED_NOTIFY, "a");
if (fp == NULL) {
cwmp_free_all_dm_parameter_list(&list_notify);
return 0;
}
foreach_jsonobj_in_array(param_obj, old_list_notify)
{
json_object_object_get_ex(param_obj, "parameter", &param_name_obj);
if (!param_name_obj || strlen((char *)json_object_get_string(param_name_obj)) <= 0)
continue;
json_object_object_get_ex(param_obj, "value", &value_obj);
json_object_object_get_ex(param_obj, "type", &type_obj);
json_object_object_get_ex(param_obj, "notification", &notification_obj);
cwmp_json_fprintf(fp, 4, CWMP_JSON_ARGS{ { "parameter", (char *)json_object_get_string(param_name_obj) },
{ "notification", notification_obj ? (char *)json_object_get_string(notification_obj) : "" },
{ "value", value_obj ? (char *)json_object_get_string(value_obj) : "" },
{ "type", type_obj ? (char *)json_object_get_string(type_obj) : "" } });
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &list_notify, list) {
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);
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(json_object *list_params_obj, char *parameter_name, struct cwmp_dm_parameter **ret_dm_param)
void get_parameter_value_from_parameters_list(struct list_head *list_notif, char *parameter_name, struct cwmp_dm_parameter **ret_dm_param)
{
json_object *param_obj = NULL, *param_name_obj = NULL, *value_obj = NULL, *type_obj = NULL;
foreach_jsonobj_in_array(param_obj, list_params_obj)
{
json_object_object_get_ex(param_obj, "parameter", &param_name_obj);
if (!param_name_obj || strlen((char *)json_object_get_string(param_name_obj)) <= 0)
continue;
if (strcmp((char *)json_object_get_string(param_name_obj), parameter_name) != 0)
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) {
continue;
}
*ret_dm_param = (struct cwmp_dm_parameter *)calloc(1, sizeof(struct cwmp_dm_parameter));
json_object_object_get_ex(param_obj, "value", &value_obj);
(*ret_dm_param)->name = strdup(parameter_name);
(*ret_dm_param)->data = strdup(value_obj ? (char *)json_object_get_string(value_obj) : "");
json_object_object_get_ex(param_obj, "type", &type_obj);
(*ret_dm_param)->type = strdup(type_obj ? (char *)json_object_get_string(type_obj) : "");
(*ret_dm_param)->name = strdup(param_value->name);
(*ret_dm_param)->value = strdup(param_value->value);
(*ret_dm_param)->type = strdup(param_value->type);
break;
}
}
@ -75,44 +64,30 @@ void get_parameter_value_from_parameters_list(json_object *list_params_obj, char
int check_value_change(void)
{
FILE *fp;
char buf[512];
char *parameter, *notification = NULL, *value = NULL;
char buf[1280];
struct cwmp *cwmp = &cwmp_main;
struct cwmp_dm_parameter *dm_parameter = NULL;
json_object *buf_json_obj = NULL, *param_name_obj = NULL, *value_obj = NULL, *notification_obj = NULL;
int is_notify = 0;
fp = fopen(DM_ENABLED_NOTIFY, "r");
if (fp == NULL)
return false;
cwmp_update_enabled_list_notify(cwmp->conf.instance_mode, ACTUAL_LIST_NOTIFY);
while (fgets(buf, 512, fp) != NULL) {
LIST_HEAD(list_notify);
cwmp_update_enabled_list_notify(cwmp->conf.instance_mode, &list_notify);
while (fgets(buf, 1280, fp) != NULL) {
int len = strlen(buf);
if (len)
buf[len - 1] = '\0';
buf_json_obj = json_tokener_parse(buf);
json_object_object_get_ex(buf_json_obj, "parameter", &param_name_obj);
if (param_name_obj == NULL || strlen((char *)json_object_get_string(param_name_obj)) <= 0) {
FREE_JSON(buf_json_obj)
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)
continue;
}
parameter = strdup((char *)json_object_get_string(param_name_obj));
json_object_object_get_ex(buf_json_obj, "value", &value_obj);
json_object_object_get_ex(buf_json_obj, "notification", &notification_obj);
value = strdup(value_obj ? (char *)json_object_get_string(value_obj) : "");
notification = strdup(notification_obj ? (char *)json_object_get_string(notification_obj) : "");
FREE_JSON(buf_json_obj)
get_parameter_value_from_parameters_list(actual_list_notify, parameter, &dm_parameter);
if (dm_parameter == NULL) {
FREE(value);
FREE(notification);
FREE(parameter);
continue;
}
if (notification && (strlen(notification) > 0) && (notification[0] >= '1') && (dm_parameter->data != NULL) && (value != NULL) && (strcmp(dm_parameter->data, value) != 0)) {
if ((strlen(notification) > 0) && (notification[0] >= '1') && (dm_parameter->value != NULL) && (strcmp(dm_parameter->value, value) != 0)) {
if (notification[0] == '1' || notification[0] == '2')
add_list_value_change(parameter, dm_parameter->data, dm_parameter->type);
add_list_value_change(parameter, dm_parameter->value, dm_parameter->type);
if (notification[0] >= '3')
add_lw_list_value_change(parameter, dm_parameter->data, dm_parameter->type);
add_lw_list_value_change(parameter, dm_parameter->value, dm_parameter->type);
if (notification[0] == '1')
is_notify |= NOTIF_PASSIVE;
@ -122,15 +97,13 @@ int check_value_change(void)
if (notification[0] == '5' || notification[0] == '6')
is_notify |= NOTIF_LW_ACTIVE;
}
FREE(value);
FREE(notification);
FREE(parameter);
FREE(dm_parameter->name);
FREE(dm_parameter->data);
FREE(dm_parameter->value);
FREE(dm_parameter->type);
FREE(dm_parameter);
}
fclose(fp);
cwmp_free_all_dm_parameter_list(&list_notify);
return is_notify;
}
@ -156,7 +129,7 @@ void *thread_periodic_check_notify(void *v)
static bool periodic_enable;
static struct timespec periodic_timeout = { 0, 0 };
time_t current_time;
int is_notify;
int is_notify = 0;
periodic_interval = cwmp->conf.periodic_notify_interval;
periodic_enable = cwmp->conf.periodic_notify_enable;
@ -186,7 +159,7 @@ void *thread_periodic_check_notify(void *v)
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);
add_dm_parameter_to_list(&list_value_change, param_name, param_data, param_type, 0, false);
pthread_mutex_unlock(&(mutex_value_change));
}
@ -211,7 +184,7 @@ void send_active_value_change(void)
/*
* Light Weight Notifications
*/
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); }
void add_lw_list_value_change(char *param_name, char *param_data, char *param_type) { add_dm_parameter_to_list(&list_lw_value_change, param_name, param_data, param_type, 0, false); }
static void udplw_server_param(struct addrinfo **res)
{
struct addrinfo hints = { 0 };

42
ubus.c
View file

@ -15,8 +15,6 @@
#include <sys/file.h>
#include <pthread.h>
#include <libubus.h>
#include <libubox/blobmsg_json.h>
#include "ubus.h"
#include "session.h"
@ -30,7 +28,6 @@
static struct ubus_context *ctx = NULL;
static struct blob_buf b;
static json_object *json_res = NULL;
static const char *arr_session_status[] = {
[SESSION_WAITING] = "waiting", [SESSION_RUNNING] = "running", [SESSION_FAILURE] = "failure", [SESSION_SUCCESS] = "success",
@ -311,35 +308,21 @@ void ubus_exit(void)
ubus_free(ctx);
}
static void receive_ubus_call_result_data(struct ubus_request *req __attribute__((unused)), int type __attribute__((unused)), struct blob_attr *msg)
{
const char *str;
if (!msg)
return;
str = blobmsg_format_json_indent(msg, true, -1);
if (!str) {
json_res = NULL;
return;
}
json_res = json_tokener_parse(str);
free((char *)str);
}
int cwmp_ubus_call(const char *obj, const char *method, const struct cwmp_ubus_arg u_args[], int u_args_size, json_object **json_ret)
int cwmp_ubus_call(const char *obj, const char *method, const struct cwmp_ubus_arg u_args[], int u_args_size, void (*ubus_callback)(struct ubus_request *req, int type, struct blob_attr *msg), void *callback_arg)
{
uint32_t id;
int i = 0;
int rc = 0;
struct ubus_context *ubus_ctx = NULL;
struct blob_buf b = { 0 };
json_res = NULL;
struct ubus_context *ubus_ctx = NULL;
if (ubus_ctx == NULL) {
ubus_ctx = ubus_connect(NULL);
if (ubus_ctx == NULL)
return -1;
}
blob_buf_init(&b, 0);
for (i = 0; i < u_args_size; i++) {
if (u_args[i].type == UBUS_String)
@ -368,25 +351,25 @@ int cwmp_ubus_call(const char *obj, const char *method, const struct cwmp_ubus_a
}
blobmsg_close_array(&b, a);
} else if (u_args[i].type == UBUS_List_Param) {
struct cwmp_param_value *param_value;
struct cwmp_dm_parameter *param_value;
void *a, *t;
a = blobmsg_open_array(&b, u_args[i].key);
list_for_each_entry (param_value, u_args[i].val.param_value_list, list) {
if (!param_value->param)
if (!param_value->name)
break;
t = blobmsg_open_table(&b, "");
blobmsg_add_string(&b, "path", param_value->param);
blobmsg_add_string(&b, "path", param_value->name);
blobmsg_add_string(&b, "value", param_value->value);
blobmsg_close_table(&b, t);
}
blobmsg_close_array(&b, a);
} else if (u_args[i].type == UBUS_Obj_Obj) {
struct cwmp_param_value *param_value;
struct cwmp_dm_parameter *param_value;
json_object *input_json_obj = json_object_new_object();
list_for_each_entry (param_value, u_args[i].val.param_value_list, list) {
if (!param_value->param)
if (!param_value->name)
break;
json_object_object_add(input_json_obj, param_value->param, json_object_new_string(param_value->value));
json_object_object_add(input_json_obj, param_value->name, json_object_new_string(param_value->value));
}
blobmsg_add_json_element(&b, u_args[i].key, input_json_obj);
} else if (u_args[i].type == UBUS_Bool)
@ -394,16 +377,13 @@ int cwmp_ubus_call(const char *obj, const char *method, const struct cwmp_ubus_a
}
blobmsg_add_string(&b, "proto", "cwmp");
if (!ubus_lookup_id(ubus_ctx, obj, &id))
rc = ubus_invoke(ubus_ctx, id, method, b.head, receive_ubus_call_result_data, NULL, 10000);
rc = ubus_invoke(ubus_ctx, id, method, b.head, ubus_callback, callback_arg, 20000);
else
rc = -1;
*json_ret = json_res;
blob_buf_free(&b);
if (ubus_ctx) {
ubus_free(ubus_ctx);
ubus_ctx = NULL;
}
blob_buf_free(&b);
return rc;
}

305
xml.c
View file

@ -550,23 +550,24 @@ static int xml_prepare_parameters_inform(struct cwmp_dm_parameter *dm_parameter,
{
mxml_node_t *node, *b;
b = mxmlFindElementOpaque(parameter_list, parameter_list, dm_parameter->name, MXML_DESCEND);
if (b && dm_parameter->data != NULL) {
if (b && dm_parameter->value != NULL) {
node = b->parent->parent;
b = mxmlFindElement(node, node, "Value", NULL, NULL, MXML_DESCEND_FIRST);
if (!b)
return 0;
if (b->child && strcmp(dm_parameter->data, b->child->value.opaque) == 0)
if (b->child && strcmp(dm_parameter->value, b->child->value.opaque) == 0)
return 0;
mxmlDelete(b);
(*size)--;
goto create_value;
} else if (b && dm_parameter->data == NULL) {
} else if (b && dm_parameter->value == NULL) {
return 0;
} else if (!b && dm_parameter->data == NULL) {
json_object *parameters = NULL;
cwmp_get_parameter_values(dm_parameter->name, &parameters);
FREE_JSON(str_json_parse_object)
} 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");
@ -589,7 +590,7 @@ create_value:
#ifdef ACS_MULTI
mxmlElementSetAttr(b, "xsi:type", (dm_parameter->type && dm_parameter->type[0] != '\0') ? dm_parameter->type : "xsd:string");
#endif
b = mxmlNewOpaque(b, dm_parameter->data);
b = mxmlNewOpaque(b, dm_parameter->value);
if (!b)
return -1;
@ -624,7 +625,7 @@ static int xml_prepare_lwnotifications(mxml_node_t *parameter_list)
#ifdef ACS_MULTI
mxmlElementSetAttr(b, "xsi:type", lw_notification->type);
#endif
b = mxmlNewOpaque(b, lw_notification->data);
b = mxmlNewOpaque(b, lw_notification->value);
if (!b)
goto error;
}
@ -733,7 +734,7 @@ char *xml_get_cwmp_version(int version)
int cwmp_rpc_acs_prepare_message_inform(struct cwmp *cwmp, struct session *session, struct rpc *this)
{
struct cwmp_dm_parameter *dm_parameter, cwmp_dm_param = { 0 };
struct cwmp_dm_parameter *dm_parameter;
struct event_container *event_container;
mxml_node_t *tree, *b, *node, *parameter_list;
char *c = NULL;
@ -838,28 +839,21 @@ int cwmp_rpc_acs_prepare_message_inform(struct cwmp *cwmp, struct session *sessi
if (!b)
goto error;
json_object *parameters = NULL, *param_obj = NULL, *param_name = NULL, *param_value = NULL, *param_type = NULL;
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;
LIST_HEAD(list_inform);
for (i = 0; i < inform_parameters_nbre; i++) {
char *fault = cwmp_get_parameter_values(forced_inform_parameters[i], &parameters);
if (parameters == NULL) {
char *fault = cwmp_get_parameter_values(forced_inform_parameters[i], &list_inform);
if (fault != NULL) {
FREE(fault);
continue;
}
param_obj = json_object_array_get_idx(parameters, 0);
json_object_object_get_ex(param_obj, "parameter", &param_name);
json_object_object_get_ex(param_obj, "value", &param_value);
json_object_object_get_ex(param_obj, "type", &param_type);
cwmp_dm_param.name = strdup(param_name ? (char *)json_object_get_string(param_name) : "");
cwmp_dm_param.data = strdup(param_value ? (char *)json_object_get_string(param_value) : "");
cwmp_dm_param.type = strdup(param_type ? (char *)json_object_get_string(param_type) : "");
if (xml_prepare_parameters_inform(&cwmp_dm_param, parameter_list, &size))
goto error;
FREE(cwmp_dm_param.name);
FREE(cwmp_dm_param.data);
FREE(cwmp_dm_param.type);
FREE_JSON(str_json_parse_object)
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 (cwmp_asprintf(&c, "cwmp:ParameterValueStruct[%d]", size) == -1)
goto error;
@ -1247,10 +1241,8 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc
mxml_node_t *n, *parameter_list, *b;
char *parameter_name = NULL;
int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR;
struct json_object *parameters = NULL, *param_obj = NULL, *param_name = NULL, *param_value = NULL;
#ifdef ACS_MULTI
char *c = NULL;
struct json_object *param_type = NULL;
#endif
b = session->body_in;
@ -1269,7 +1261,7 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc
#ifdef ACS_MULTI
mxmlElementSetAttr(parameter_list, "xsi:type", "soap_enc:Array");
#endif
LIST_HEAD(parameters_list);
while (b) {
if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "string")) {
parameter_name = b->value.opaque;
@ -1279,14 +1271,14 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc
parameter_name = "";
}
if (parameter_name) {
char *err = cwmp_get_parameter_values(parameter_name, &parameters);
char *err = cwmp_get_parameter_values(parameter_name, &parameters_list);
if (err) {
fault_code = cwmp_get_fault_code_by_string(err);
FREE(err);
goto fault;
}
foreach_jsonobj_in_array(param_obj, parameters)
{
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &parameters_list, list) {
n = mxmlNewElement(parameter_list, "ParameterValueStruct");
if (!n)
goto fault;
@ -1295,8 +1287,7 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc
if (!n)
goto fault;
json_object_object_get_ex(param_obj, "parameter", &param_name);
n = mxmlNewOpaque(n, json_object_get_string(param_name));
n = mxmlNewOpaque(n, param_value->name);
if (!n)
goto fault;
@ -1306,21 +1297,19 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc
goto fault;
#ifdef ACS_MULTI
json_object_object_get_ex(param_obj, "type", &param_type);
mxmlElementSetAttr(n, "xsi:type", json_object_get_string(param_type));
mxmlElementSetAttr(n, "xsi:type", param_value->type);
#endif
json_object_object_get_ex(param_obj, "value", &param_value);
n = mxmlNewOpaque(n, param_value ? json_object_get_string(param_value) : "");
n = mxmlNewOpaque(n, param_value->value);
if (!n)
goto fault;
counter++;
}
cwmp_free_all_dm_parameter_list(&parameters_list);
}
b = mxmlWalkNext(b, session->body_in, MXML_DESCEND);
parameter_name = NULL;
FREE_JSON(str_json_parse_object)
}
#ifdef ACS_MULTI
@ -1338,7 +1327,7 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc
return 0;
fault:
FREE_JSON(str_json_parse_object)
cwmp_free_all_dm_parameter_list(&parameters_list);
if (cwmp_create_fault_message(session, rpc, fault_code))
goto error;
return 0;
@ -1356,7 +1345,7 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc
char *parameter_name = NULL;
char *NextLevel = NULL;
int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR;
struct json_object *parameters = NULL, *param_obj = NULL, *param_name = NULL, *writable = NULL;
LIST_HEAD(parameters_list);
#ifdef ACS_MULTI
char *c = NULL;
#endif
@ -1389,16 +1378,15 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc
b = mxmlWalkNext(b, session->body_in, MXML_DESCEND);
}
if (parameter_name && NextLevel) {
char *err = cwmp_get_parameter_names(parameter_name, strcmp(NextLevel, "true") == 0 || strcmp(NextLevel, "1") == 0 ? true : false, &parameters);
char *err = cwmp_get_parameter_names(parameter_name, strcmp(NextLevel, "true") == 0 || strcmp(NextLevel, "1") == 0 ? true : false, &parameters_list);
if (err) {
fault_code = cwmp_get_fault_code_by_string(err);
FREE(err);
goto fault;
}
}
foreach_jsonobj_in_array(param_obj, parameters)
{
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &parameters_list, list) {
n = mxmlNewElement(parameter_list, "ParameterInfoStruct");
if (!n)
goto fault;
@ -1407,8 +1395,7 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc
if (!n)
goto fault;
json_object_object_get_ex(param_obj, "parameter", &param_name);
n = mxmlNewOpaque(n, json_object_get_string(param_name));
n = mxmlNewOpaque(n, param_value->name);
if (!n)
goto fault;
@ -1417,14 +1404,13 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc
if (!n)
goto fault;
json_object_object_get_ex(param_obj, "writable", &writable);
n = mxmlNewOpaque(n, json_object_get_string(writable));
n = mxmlNewOpaque(n, param_value->writable ? "1" : "0");
if (!n)
goto fault;
counter++;
}
cwmp_free_all_dm_parameter_list(&parameters_list);
#ifdef ACS_MULTI
b = mxmlFindElement(session->tree_out, session->tree_out, "ParameterList", NULL, NULL, MXML_DESCEND);
if (!b)
@ -1436,11 +1422,10 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc
mxmlElementSetAttr(b, "soap_enc:arrayType", c);
FREE(c);
#endif
FREE_JSON(str_json_parse_object)
return 0;
fault:
FREE_JSON(str_json_parse_object)
cwmp_free_all_dm_parameter_list(&parameters_list);
if (cwmp_create_fault_message(session, rpc, fault_code))
goto error;
return 0;
@ -1458,7 +1443,7 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct
mxml_node_t *n, *parameter_list, *b;
char *parameter_name = NULL;
int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR;
struct json_object *parameters = NULL, *param_obj = NULL, *param_name = NULL, *notification = NULL;
LIST_HEAD(parameters_list);
#ifdef ACS_MULTI
char *c = NULL;
#endif
@ -1487,14 +1472,14 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct
parameter_name = "";
}
if (parameter_name) {
char *err = cwmp_get_parameter_attributes(parameter_name, &parameters);
char *err = cwmp_get_parameter_attributes(parameter_name, &parameters_list);
if (err) {
fault_code = cwmp_get_fault_code_by_string(err);
FREE(err);
goto fault;
}
foreach_jsonobj_in_array(param_obj, parameters)
{
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &parameters_list, list) {
n = mxmlNewElement(parameter_list, "ParameterAttributeStruct");
if (!n)
goto fault;
@ -1503,8 +1488,7 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct
if (!n)
goto fault;
json_object_object_get_ex(param_obj, "parameter", &param_name);
n = mxmlNewOpaque(n, json_object_get_string(param_name));
n = mxmlNewOpaque(n, param_value->name);
if (!n)
goto fault;
@ -1513,8 +1497,10 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct
if (!n)
goto fault;
json_object_object_get_ex(param_obj, "value", &notification);
n = mxmlNewOpaque(n, json_object_get_string(notification));
char notification[2];
sprintf(notification, "%d", param_value->notification);
notification[1] = '\0';
n = mxmlNewOpaque(n, notification);
if (!n)
goto fault;
@ -1529,6 +1515,7 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct
counter++;
}
cwmp_free_all_dm_parameter_list(&parameters_list);
}
b = mxmlWalkNext(b, session->body_in, MXML_DESCEND);
parameter_name = NULL;
@ -1544,11 +1531,10 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct
mxmlElementSetAttr(b, "soap_enc:arrayType", c);
FREE(c);
#endif
FREE_JSON(str_json_parse_object)
return 0;
fault:
FREE_JSON(str_json_parse_object)
cwmp_free_all_dm_parameter_list(&parameters_list);
if (cwmp_create_fault_message(session, rpc, fault_code))
goto error;
return 0;
@ -1616,6 +1602,7 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc
cwmp_asprintf(&c, "%s %s", parameter_value, v);
FREE(parameter_value);
parameter_value = strdup(c);
//FREE(c);
}
b = n->last_child;
}
@ -1623,7 +1610,7 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc
parameter_value = strdup("");
}
if (parameter_name && parameter_value) {
cwmp_add_list_param_value(parameter_name, parameter_value, &list_set_param_value);
add_dm_parameter_to_list(&list_set_param_value, parameter_name, parameter_value, NULL, 0, false);
FREE(parameter_name);
FREE(parameter_value);
}
@ -1638,30 +1625,21 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc
b = mxmlWalkNext(b, session->tree_in, MXML_DESCEND_FIRST);
if (b && b->type == MXML_OPAQUE && b->value.opaque)
parameter_key = b->value.opaque;
json_object *faults_array = NULL;
int flag = 0;
if (!transaction_started) {
if (!cwmp_transaction_start("cwmp"))
goto fault;
transaction_started = true;
}
cwmp_set_multiple_parameters_values(list_set_param_value, parameter_key, &flag, &faults_array);
if (faults_array != NULL) {
json_object *fault_obj = NULL, *param_name = NULL, *fault_value = NULL;
foreach_jsonobj_in_array(fault_obj, faults_array)
{
json_object_object_get_ex(fault_obj, "path", &param_name);
json_object_object_get_ex(fault_obj, "fault", &fault_value);
cwmp_add_list_fault_param((char *)json_object_get_string(param_name), atoi(json_object_get_string(fault_value)), rpc->list_set_value_fault);
}
fault_code = FAULT_CPE_INVALID_ARGUMENTS;
fault_code = cwmp_set_multiple_parameters_values(list_set_param_value, parameter_key, &flag, rpc->list_set_value_fault);
if (fault_code != FAULT_CPE_NO_FAULT)
goto fault;
}
struct cwmp_param_value *param_value;
list_for_each_entry (param_value, &list_set_param_value, list)
set_diagnostic_parameter_structure_value(param_value->param, param_value->value);
cwmp_free_all_list_param_value(&list_set_param_value);
struct cwmp_dm_parameter *param_value;
list_for_each_entry (param_value, &list_set_param_value, list)
set_diagnostic_parameter_structure_value(param_value->name, param_value->value);
cwmp_free_all_dm_parameter_list(&list_set_param_value);
b = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND);
if (!b)
@ -1680,13 +1658,12 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc
goto fault;
cwmp_set_end_session(flag | END_SESSION_TRANSACTION_COMMIT | END_SESSION_SET_NOTIFICATION_UPDATE);
//FREE_JSON(str_json_parse_object)
return 0;
fault:
//FREE_JSON(str_json_parse_object)
if (cwmp_create_fault_message(session, rpc, fault_code))
goto error;
cwmp_free_all_list_param_fault(rpc->list_set_value_fault);
if (transaction_started) {
cwmp_transaction_abort();
transaction_started = false;
@ -2476,21 +2453,21 @@ int cwmp_launch_schedule_download(struct schedule_download *pdownload, struct tr
int lookup_vcf_name(char *instance, char **value)
{
json_object *parameters = NULL, *param_obj = NULL, *value_obj = NULL;
char *vcf_name_parameter = NULL;
char *err = NULL;
LIST_HEAD(vcf_parameters);
cwmp_asprintf(&vcf_name_parameter, "Device.DeviceInfo.VendorConfigFile.%s.Name", instance);
if (cwmp_get_parameter_values(vcf_name_parameter, &parameters) != NULL) {
if ((err = cwmp_get_parameter_values(vcf_name_parameter, &vcf_parameters)) != NULL) {
FREE(vcf_name_parameter);
FREE_JSON(str_json_parse_object)
FREE(err);
return -1;
}
param_obj = json_object_array_get_idx(parameters, 0);
json_object_object_get_ex(param_obj, "value", &value_obj);
*value = (char *)json_object_get_string(value_obj);
FREE(vcf_name_parameter);
FREE_JSON(str_json_parse_object)
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &vcf_parameters, list) {
*value = strdup(param_value->value);
break;
}
cwmp_free_all_dm_parameter_list(&vcf_parameters);
return 0;
}
@ -2527,6 +2504,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
p = calloc(1, sizeof(struct transfer_complete));
if (p == NULL) {
error = FAULT_CPE_INTERNAL_ERROR;
FREE(name);
return error;
}
@ -2538,7 +2516,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
}
*ptransfer_complete = p;
FREE(name);
return error;
}
@ -3022,52 +3000,36 @@ void *thread_cwmp_rpc_cpe_apply_schedule_download(void *v)
return NULL;
}
static char *get_software_module_object_eq(char *param1, char *val1, char *param2, char *val2, json_object **parameters)
static char *get_software_module_object_eq(char *param1, char *val1, char *param2, char *val2, struct list_head *sw_parameters)
{
char *err = NULL;
char *sw_parameter_name = NULL;
json_object *swdu_get_obj = NULL;
if (!param2)
cwmp_asprintf(&sw_parameter_name, "Device.SoftwareModules.DeploymentUnit.[%s==\\\"%s\\\"].", param1, val1);
else
cwmp_asprintf(&sw_parameter_name, "Device.SoftwareModules.DeploymentUnit.[%s==\\\"%s\\\"&& %s==\\\"%s\\\"].", param1, val1, param2, val2);
err = cwmp_get_parameter_values(sw_parameter_name, &swdu_get_obj);
err = cwmp_get_parameter_values(sw_parameter_name, sw_parameters);
FREE(sw_parameter_name);
if (err) {
FREE(sw_parameter_name);
FREE(err);
FREE_JSON(str_json_parse_object)
return NULL;
}
json_object_object_get_ex(swdu_get_obj, "parameters", parameters);
json_object *param_obj = NULL;
if (*parameters)
param_obj = json_object_array_get_idx(*parameters, 0);
if (!param_obj) {
FREE(sw_parameter_name);
FREE_JSON(str_json_parse_object)
return NULL;
}
json_object *first_param = NULL;
json_object_object_get_ex(param_obj, "parameter", &first_param);
if (!first_param) {
FREE(sw_parameter_name);
FREE_JSON(str_json_parse_object)
return NULL;
}
char *first_param_name = strdup(json_object_get_string(first_param));
struct cwmp_dm_parameter *param_value = NULL;
char instance[8];
snprintf(instance, (size_t)(strchr(first_param_name + strlen("Device.SoftwareModules.DeploymentUnit."), '.') - first_param_name - strlen("Device.SoftwareModules.DeploymentUnit.") + 1), "%s", (char *)(first_param_name + strlen("Device.SoftwareModules.DeploymentUnit.")));
FREE_JSON(str_json_parse_object)
list_for_each_entry (param_value, sw_parameters, list) {
snprintf(instance, (size_t)(strchr(param_value->name + strlen("Device.SoftwareModules.DeploymentUnit."), '.') - param_value->name - strlen("Device.SoftwareModules.DeploymentUnit.") + 1), "%s", (char *)(param_value->name + strlen("Device.SoftwareModules.DeploymentUnit.")));
break;
}
return strdup(instance);
}
static int get_deployment_unit_name_version(char *uuid, char **name, char **version, char **env)
{
json_object *du_obj = NULL, *param_obj = NULL, *arrobj = NULL, *value_obj = NULL;
char *sw_by_uuid_instance = NULL, *name_param = NULL, *version_param = NULL, *environment_param = NULL;
sw_by_uuid_instance = get_software_module_object_eq("UUID", uuid, NULL, NULL, &arrobj);
LIST_HEAD(sw_parameters);
sw_by_uuid_instance = get_software_module_object_eq("UUID", uuid, NULL, NULL, &sw_parameters);
if (!sw_by_uuid_instance)
return 0;
@ -3075,89 +3037,81 @@ static int get_deployment_unit_name_version(char *uuid, char **name, char **vers
cwmp_asprintf(&version_param, "Device.SoftwareModules.DeploymentUnit.%s.Version", sw_by_uuid_instance);
cwmp_asprintf(&environment_param, "Device.SoftwareModules.DeploymentUnit.%s.ExecutionEnvRef", sw_by_uuid_instance);
foreach_jsonobj_in_array(du_obj, arrobj)
{
json_object_object_get_ex(du_obj, "parameter", &param_obj);
if (!param_obj)
continue;
json_object_object_get_ex(du_obj, "value", &value_obj);
if (strcmp(json_object_get_string(param_obj), name_param) == 0) {
*name = strdup(value_obj ? json_object_get_string(value_obj) : "");
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &sw_parameters, list) {
if (strcmp(param_value->name, name_param) == 0) {
*name = strdup(param_value->value);
continue;
}
if (strcmp(json_object_get_string(param_obj), version_param) == 0) {
*version = strdup(value_obj ? json_object_get_string(value_obj) : "");
if (strcmp(param_value->name, version_param) == 0) {
*version = strdup(param_value->value);
continue;
}
if (strcmp(json_object_get_string(param_obj), environment_param) == 0) {
*env = strdup(value_obj ? json_object_get_string(value_obj) : "");
if (strcmp(param_value->name, environment_param) == 0) {
*env = strdup(param_value->value);
continue;
}
}
cwmp_free_all_dm_parameter_list(&sw_parameters);
FREE(name_param);
FREE(version_param);
FREE(environment_param);
return 1;
}
static char *get_softwaremodules_uuid(char *url)
{
json_object *du_obj = NULL, *param_obj = NULL, *arrobj = NULL, *value_obj = NULL;
char *sw_by_url_instance = NULL, *uuid_param = NULL, *uuid = NULL;
sw_by_url_instance = get_software_module_object_eq("URL", url, NULL, NULL, &arrobj);
LIST_HEAD(sw_parameters);
sw_by_url_instance = get_software_module_object_eq("URL", url, NULL, NULL, &sw_parameters);
if (!sw_by_url_instance)
return NULL;
cwmp_asprintf(&uuid_param, "Device.SoftwareModules.DeploymentUnit.%s.UUID", sw_by_url_instance);
foreach_jsonobj_in_array(du_obj, arrobj)
{
json_object_object_get_ex(du_obj, "parameter", &param_obj);
if (!param_obj)
continue;
json_object_object_get_ex(du_obj, "value", &value_obj);
if (strcmp(json_object_get_string(param_obj), uuid_param) == 0) {
uuid = strdup(value_obj ? json_object_get_string(value_obj) : "");
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &sw_parameters, list) {
if (strcmp(param_value->name, uuid_param) == 0) {
uuid = strdup(param_value->value);
break;
}
}
cwmp_free_all_dm_parameter_list(&sw_parameters);
FREE(uuid_param);
return uuid;
}
static char *get_softwaremodules_url(char *uuid)
{
json_object *du_obj = NULL, *param_obj = NULL, *arrobj = NULL, *value_obj = NULL;
char *sw_by_uuid_instance = NULL, *url_param = NULL, *url = NULL;
sw_by_uuid_instance = get_software_module_object_eq("UUID", uuid, NULL, NULL, &arrobj);
LIST_HEAD(sw_parameters);
sw_by_uuid_instance = get_software_module_object_eq("UUID", uuid, NULL, NULL, &sw_parameters);
if (!sw_by_uuid_instance)
return NULL;
cwmp_asprintf(&url_param, "Device.SoftwareModules.DeploymentUnit.%s.URL", sw_by_uuid_instance);
foreach_jsonobj_in_array(du_obj, arrobj)
{
json_object_object_get_ex(du_obj, "parameter", &param_obj);
if (!param_obj)
continue;
json_object_object_get_ex(du_obj, "value", &value_obj);
if (strcmp(json_object_get_string(param_obj), url_param) == 0) {
url = strdup(value_obj ? json_object_get_string(value_obj) : "");
struct cwmp_dm_parameter *param_value = NULL;
list_for_each_entry (param_value, &sw_parameters, list) {
if (strcmp(param_value->name, url_param) == 0) {
url = strdup(param_value->value);
break;
}
}
cwmp_free_all_dm_parameter_list(&sw_parameters);
FREE(url_param);
return url;
}
static char *get_deployment_unit_reference(char *package_name, char *package_env)
{
json_object *arrobj = NULL;
LIST_HEAD(sw_parameters);
char *sw_by_name_env_instance = NULL, *deployment_unit_ref = NULL;
sw_by_name_env_instance = get_software_module_object_eq("Name", package_name, "ExecutionEnvRef", package_env, &arrobj);
sw_by_name_env_instance = get_software_module_object_eq("Name", package_name, "ExecutionEnvRef", package_env, &sw_parameters);
cwmp_free_all_dm_parameter_list(&sw_parameters);
if (!sw_by_name_env_instance)
return NULL;
@ -3167,10 +3121,9 @@ static char *get_deployment_unit_reference(char *package_name, char *package_env
static bool environment_exists(char *environment_path)
{
json_object *sw_env_get_obj = NULL;
char *err = cwmp_get_parameter_values(environment_path, &sw_env_get_obj);
FREE_JSON(str_json_parse_object)
LIST_HEAD(environment_list);
char *err = cwmp_get_parameter_values(environment_path, &environment_list);
cwmp_free_all_dm_parameter_list(&environment_list);
if (err) {
FREE(err);
return false;
@ -3181,32 +3134,24 @@ static bool environment_exists(char *environment_path)
static char *get_exec_env_name(char *environment_path)
{
json_object *du_obj = NULL, *param_obj = NULL, *sw_env_get_obj = NULL, *value_obj = NULL;
char *env_param = NULL, *env_name = "";
char *err = cwmp_get_parameter_values(environment_path, &sw_env_get_obj);
LIST_HEAD(environment_list);
char *err = cwmp_get_parameter_values(environment_path, &environment_list);
if (err) {
FREE(err);
FREE_JSON(str_json_parse_object)
return "";
return strdup("");
}
struct cwmp_dm_parameter *param_value = NULL;
cwmp_asprintf(&env_param, "%sName", environment_path);
foreach_jsonobj_in_array(du_obj, sw_env_get_obj)
{
json_object_object_get_ex(du_obj, "parameter", &param_obj);
if (!param_obj)
continue;
json_object_object_get_ex(du_obj, "value", &value_obj);
if (strcmp(json_object_get_string(param_obj), env_param) == 0) {
env_name = strdup(value_obj ? json_object_get_string(value_obj) : "");
list_for_each_entry (param_value, &environment_list, list) {
if (strcmp(param_value->name, env_param) == 0) {
env_name = strdup(param_value->value);
break;
}
}
FREE_JSON(str_json_parse_object)
cwmp_free_all_dm_parameter_list(&environment_list);
FREE(env_param);
return env_name;
}