diff --git a/bin/Makefile.am b/bin/Makefile.am index 9f1f2ec..21a9ea6 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -16,6 +16,7 @@ icwmpd_SOURCES = \ ../ubus.c \ ../xml.c \ ../diagnostic.c \ + ../datamodelIface.c \ ../zlib.c icwmpd_CFLAGS = \ diff --git a/datamodelIface.c b/datamodelIface.c new file mode 100644 index 0000000..42195ed --- /dev/null +++ b/datamodelIface.c @@ -0,0 +1,152 @@ +#include "datamodelIface.h" + +char* cwmp_get_parameter_values(char *parameter_name, json_object **parameters) +{ + json_object *params_obj = NULL; + int e = cwmp_ubus_call("usp.raw", "get", CWMP_UBUS_ARGS{{"path", {.str_val=parameter_name}, UBUS_String}}, 1, ¶ms_obj); + if (e < 0 || params_obj == NULL) { + *parameters = NULL; + return "9002"; + } + json_object *fault_code = NULL; + json_object_object_get_ex(params_obj, "fault", &fault_code); + if (fault_code != NULL) { + *parameters = NULL; + return (char*)json_object_get_string(fault_code); + } + json_object_object_get_ex(params_obj, "parameters", parameters); + return NULL; +} + +char* cwmp_set_parameter_value(char* parameter_name, char* value, char* parameter_key) +{ + json_object *set_res; + int e = cwmp_ubus_call("usp.raw", "set", CWMP_UBUS_ARGS{{"path", {.str_val=parameter_name}, UBUS_String},{"value", value, UBUS_String}, {"key", parameter_key, UBUS_String}}, 2, &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) + return (char*)json_object_get_string(fault_code); + + json_object *parameters = NULL; + json_object_object_get_ex(set_res, "parameters", ¶meters); + if (!parameters) + return "9002"; + 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); + return (char*)json_object_get_string(fault); + } + return NULL; +} + +char* cwmp_add_object(char* object_name, char* key, char **instance) +{ + json_object *add_res; + 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}}, 2, &add_res); + if (e < 0 || add_res == NULL) + return "9002"; + json_object *fault_code = NULL; + json_object_object_get_ex(add_res, "fault", &fault_code); + if (fault_code != NULL) + return (char*)json_object_get_string(fault_code); + + json_object *parameters = NULL; + json_object_object_get_ex(add_res, "parameters", ¶meters); + if (parameters == NULL) + 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) + return (char*)json_object_get_string(fault); + json_object *instance_obj = NULL; + json_object_object_get_ex(param_obj, "instance", &instance_obj); + *instance = json_object_get_string(instance_obj); + return NULL; +} + +char* cwmp_delete_object(char* object_name, char* key) +{ + json_object *del_res; + 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}}, 2, &del_res); + if (e < 0 || del_res == NULL) + return "9002"; + json_object *fault_code = NULL; + json_object_object_get_ex(del_res, "fault", &fault_code); + if (fault_code != NULL) + return (char*)json_object_get_string(fault_code); + json_object *parameters = NULL; + json_object_object_get_ex(del_res, "parameters", ¶meters); + 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); + return (char*)json_object_get_string(fault); + } + return NULL; +} + +char* cwmp_get_parameter_names(char* object_name, bool next_level, json_object **parameters) +{ + json_object *get_name_res; + 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, &get_name_res); + if (e < 0 || get_name_res == NULL) + return "9002"; + json_object *fault_code = NULL; + json_object_object_get_ex(get_name_res, "fault", &fault_code); + if (fault_code != NULL) { + *parameters = NULL; + return (char*)json_object_get_string(fault_code); + } + json_object_object_get_ex(get_name_res, "parameters", parameters); + return NULL; +} + +char* cwmp_get_parameter_attributes(char* parameter_name, json_object **parameters) +{ + json_object *get_attributes_res = NULL; + int e = cwmp_ubus_call("usp.raw", "getm_attributes", CWMP_UBUS_ARGS{{"paths", {.array_value={{.str_value=parameter_name}}}, UBUS_Array_Str}}, 1, &get_attributes_res); + if ( e < 0 || get_attributes_res == NULL) + return "9002"; + json_object *fault_code = NULL; + json_object_object_get_ex(get_attributes_res, "fault", &fault_code); + if (fault_code != NULL) { + *parameters = NULL; + return (char*)json_object_get_string(fault_code); + } + json_object_object_get_ex(get_attributes_res, "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) { + return (char*)json_object_get_string(fault); + } + } + return NULL; +} + +char* cwmp_set_parameter_attributes(char* parameter_name, char* notification) +{ + json_object *set_attribute_res; + 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}}, 1, &set_attribute_res); + if (e < 0 || set_attribute_res == NULL) + return "9002"; + json_object *parameters = NULL; + json_object_object_get_ex(set_attribute_res, "parameters", ¶meters); + 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) + return (char*)json_object_get_string(fault_code); + return NULL; +} diff --git a/inc/cwmp.h b/inc/cwmp.h index 2759f06..3b8bc70 100644 --- a/inc/cwmp.h +++ b/inc/cwmp.h @@ -348,5 +348,6 @@ void send_active_value_change(void); void cwmp_set_end_session(unsigned int flag); bool event_exist_in_list(struct cwmp *cwmp, int event); void *thread_periodic_check_notify (void *v); +void free_dm_parameter_all_fromlist(struct list_head *list); #endif #endif /* _CWMP_H__ */ diff --git a/inc/datamodelIface.h b/inc/datamodelIface.h new file mode 100644 index 0000000..3863f6c --- /dev/null +++ b/inc/datamodelIface.h @@ -0,0 +1,15 @@ +#ifndef SRC_DATAMODELIFACE_H_ +#define SRC_DATAMODELIFACE_H_ +#include +#include +#include +#include "ubus.h" +#include "jshn.h" +char* cwmp_get_parameter_values(char *parameter_name, json_object **parameters); +char* cwmp_set_parameter_value(char* parameter_name, char* value, char* parameter_key); +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_set_parameter_attributes(char* parameter_name, char* notification); +#endif /* SRC_DATAMODELIFACE_H_ */ diff --git a/inc/jshn.h b/inc/jshn.h index d7f34c6..896e3bb 100644 --- a/inc/jshn.h +++ b/inc/jshn.h @@ -25,4 +25,8 @@ int cwmp_handle_setParamAttributes(char *msg); int cwmp_handle_addObject(char *msg); int cwmp_handle_delObject(char *msg); +#define foreach_jsonobj_in_array(param_obj, parameters) \ + int k, array_length = json_object_array_length(parameters); \ + for (k=0, param_obj = json_object_array_get_idx(parameters, 0); k< array_length; k++, param_obj = json_object_array_get_idx(parameters, k)) \ + #endif /* _JSHN_H__ */ diff --git a/inc/ubus.h b/inc/ubus.h index a24ad0e..f8a75a1 100644 --- a/inc/ubus.h +++ b/inc/ubus.h @@ -1,18 +1,45 @@ -/* - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Copyright (C) 2012 Luka Perkov - */ +#ifndef UBUS_H_ +#define UBUS_H_ +#include - -#ifndef _FREECWMP_UBUS_H__ -#define _FREECWMP_UBUS_H__ +#define ARRAY_MAX 8 int ubus_init(struct cwmp *cwmp); void ubus_exit(void); -#endif +enum cwmp_ubus_arg_type { + UBUS_String, + UBUS_Integer, + UBUS_Array_Obj, + UBUS_Array_Str, + UBUS_Bool +}; +struct key_value { + char *key; + char *value; +}; + +union array_membre { + char* str_value; + struct key_value param_value; +}; + +union ubus_value { + char* str_val; + int int_val; + bool bool_val; + union array_membre array_value[ARRAY_MAX]; +}; + +struct cwmp_ubus_arg { + const char *key; + const union ubus_value val; + enum cwmp_ubus_arg_type type; +}; + +#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); + +#endif /* UBUS_H_ */ diff --git a/inc/xml.h b/inc/xml.h index 7234609..55b644a 100644 --- a/inc/xml.h +++ b/inc/xml.h @@ -114,6 +114,12 @@ enum { FAULT_CPE_TYPE_SERVER }; +struct cwmp_param_fault { + struct list_head list; + char *name; + int fault; +}; + struct rpc_cpe_method { const char *name; int (*handler)(struct session *session, struct rpc *rpc); @@ -298,6 +304,7 @@ int xml_prepare_lwnotification_message(char **msg_out); int xml_set_cwmp_id_rpc_cpe(struct session *session); int cwmp_create_fault_message(struct session *session, struct rpc *rpc_cpe, int fault_code); int cwmp_get_fault_code (int fault_code); +int cwmp_get_fault_code_by_string (char* fault_code); int cwmp_scheduleInform_remove_all(); int cwmp_scheduledDownload_remove_all(); int cwmp_scheduledUpload_remove_all(); diff --git a/ubus.c b/ubus.c index 0bd0fc7..09ca138 100644 --- a/ubus.c +++ b/ubus.c @@ -30,6 +30,7 @@ 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", @@ -349,3 +350,81 @@ ubus_exit(void) { if (ctx) ubus_free(ctx); } + +static void receive_ubus_call_result_data(struct ubus_request *req, int type, 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); //MEM should be free and not dmfree*/ +} + +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) +{ + uint32_t id; + int i = 0; + int rc = 0; + struct ubus_context *ubus_ctx = NULL; + struct blob_buf b = {0}; + + json_res = 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) + blobmsg_add_string(&b, u_args[i].key, u_args[i].val.str_val); + else if (u_args[i].type == UBUS_Integer) + blobmsg_add_u32(&b, u_args[i].key, u_args[i].val.int_val); + else if (u_args[i].type == UBUS_Array_Obj || u_args[i].type == UBUS_Array_Str){ + void *a, *t; + int j; + a = blobmsg_open_array(&b, u_args[i].key); + if (u_args[i].type == UBUS_Array_Obj) { + t = blobmsg_open_table(&b, ""); + for (j = 0; j < ARRAY_MAX; j++) { + if (u_args[i].val.array_value[j].param_value.key == NULL || strlen(u_args[i].val.array_value[j].param_value.key) <= 0) + break; + blobmsg_add_string(&b, u_args[i].val.array_value[j].param_value.key, u_args[i].val.array_value[j].param_value.value); + } + blobmsg_close_table(&b, t); + } + if (u_args[i].type == UBUS_Array_Str) { + for (j = 0; j < ARRAY_MAX; j++) { + if (u_args[i].val.array_value[j].str_value == NULL || strlen(u_args[i].val.array_value[j].str_value) <= 0) + break; + blobmsg_add_string(&b, NULL, u_args[i].val.array_value[j].str_value); + } + } + blobmsg_close_array(&b, a); + } + else if (u_args[i].type == UBUS_Bool) + blobmsg_add_u8(&b, u_args[i].key, u_args[i].val.bool_val); + } + 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, 1000); + else + rc = -1; + + *json_ret = json_res; + + if (ubus_ctx) { + ubus_free(ubus_ctx); + ubus_ctx = NULL; + } + blob_buf_free(&b); + return rc; +} diff --git a/xml.c b/xml.c index afce579..8b52f92 100644 --- a/xml.c +++ b/xml.c @@ -34,6 +34,8 @@ #include #include #endif +#include "datamodelIface.h" + LIST_HEAD(list_download); LIST_HEAD(list_upload); LIST_HEAD(list_schedule_download); @@ -95,7 +97,7 @@ struct FAULT_CPE FAULT_CPE_ARRAY [] = { [FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD] = {"9017", FAULT_9017, FAULT_CPE_TYPE_SERVER, "Download failure: unable to complete download"}, [FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED] = {"9018", FAULT_9018, FAULT_CPE_TYPE_SERVER, "Download failure: file corrupted"}, [FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION] = {"9019", FAULT_9019, FAULT_CPE_TYPE_SERVER, "Download failure: file authentication failure"}, - [FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW] = {"9020", FAULT_9020, FAULT_CPE_TYPE_SERVER, "Download failure: unable to complete download"}, + [FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW] = {"9020", FAULT_9020, FAULT_CPE_TYPE_SERVER, "Download failure: unable to complete download"}, [FAULT_CPE_DUPLICATE_DEPLOYMENT_UNIT] = {"9026", FAULT_9026, FAULT_CPE_TYPE_SERVER, "Duplicate deployment unit"}, [FAULT_CPE_SYSTEM_RESOURCES_EXCEEDED] = {"9027", FAULT_9027, FAULT_CPE_TYPE_SERVER, "System ressources exceeded"}, [FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT] = {"9028", FAULT_9028, FAULT_CPE_TYPE_SERVER, "Unknown deployment unit"}, @@ -138,6 +140,24 @@ int cwmp_launch_du_update(char *uuid, char *url, char *version, char *user, char int cwmp_launch_du_uninstall(char *package_name, char *package_env, struct opresult **pchange_du_state_complete); int cwmp_free_change_du_state_request(struct change_du_state *change_du_state); +void cwmp_add_list_fault_param(char *param, int fault, struct list_head *list_set_value_fault) +{ + struct cwmp_param_fault *param_fault; + if (param == NULL) + param = ""; + + param_fault = calloc(1, sizeof(struct cwmp_param_fault)); + list_add_tail(¶m_fault->list, list_set_value_fault); + param_fault->name = strdup(param); + param_fault->fault = fault; +} + +void cwmp_del_list_fault_param(struct cwmp_param_fault *param_fault) +{ + list_del(¶m_fault->list); + free(param_fault->name); + free(param_fault); +} static mxml_node_t * /* O - Element node or NULL */ mxmlFindElementOpaque(mxml_node_t *node, /* I - Current node */ mxml_node_t *top, /* I - Top node */ @@ -1167,29 +1187,28 @@ int cwmp_rpc_acs_destroy_data_du_state_change_complete(struct session *session, int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc *rpc) { mxml_node_t *n, *parameter_list, *b; - struct dm_parameter *dm_parameter; char *parameter_name = NULL; char *c = NULL; int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR; - struct dmctx dmctx = {0}; - - cwmp_dm_ctx_init(&cwmp_main, &dmctx); + struct json_object *parameters = NULL, *param_obj = NULL, *param_name = NULL, *param_value = NULL, *param_type = NULL; b = session->body_in; n = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); - if (!n) goto fault; + if (!n) + goto fault; n = mxmlNewElement(n, "cwmp:GetParameterValuesResponse"); - if (!n) goto fault; + if (!n) + goto fault; parameter_list = mxmlNewElement(n, "ParameterList"); - if (!parameter_list) goto fault; + if (!parameter_list) + goto fault; #ifdef ACS_MULTI mxmlElementSetAttr(parameter_list, "xsi:type", "soap_enc:Array"); #endif - while (b) { if (b && b->type == MXML_OPAQUE && b->value.opaque && @@ -1203,42 +1222,45 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc parameter_name = ""; } if (parameter_name) { - int e = dm_entry_param_method(&dmctx, CMD_GET_VALUE, parameter_name, NULL, NULL); - if (e) { - fault_code = cwmp_get_fault_code(e); + char *err = cwmp_get_parameter_values(parameter_name, ¶meters); + if (err) { + fault_code = cwmp_get_fault_code_by_string(err); goto fault; } + foreach_jsonobj_in_array(param_obj, parameters) { + n = mxmlNewElement(parameter_list, "ParameterValueStruct"); + if (!n) + goto fault; + + n = mxmlNewElement(n, "Name"); + if (!n) + goto fault; + + json_object_object_get_ex(param_obj, "parameter", ¶m_name); + n = mxmlNewOpaque(n, json_object_get_string(param_name)); + if (!n) + goto fault; + + n = n->parent->parent; + n = mxmlNewElement(n, "Value"); + if (!n) + goto fault; + +#ifdef ACS_MULTI + json_object_object_get_ex(param_obj, "type", ¶m_type); + mxmlElementSetAttr(n, "xsi:type", json_object_get_string(param_type)); +#endif + + json_object_object_get_ex(param_obj, "value", ¶m_value); + n = mxmlNewOpaque(n, param_value? json_object_get_string(param_value) : ""); + if (!n) + goto fault; + } } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); parameter_name = NULL; } - while (dmctx.list_parameter.next != &dmctx.list_parameter) { - dm_parameter = list_entry(dmctx.list_parameter.next, struct dm_parameter, list); - - n = mxmlNewElement(parameter_list, "ParameterValueStruct"); - if (!n) goto fault; - - n = mxmlNewElement(n, "Name"); - if (!n) goto fault; - - n = mxmlNewOpaque(n, dm_parameter->name); - if (!n) goto fault; - - n = n->parent->parent; - n = mxmlNewElement(n, "Value"); - if (!n) goto fault; - -#ifdef ACS_MULTI - mxmlElementSetAttr(n, "xsi:type", dm_parameter->type); -#endif - n = mxmlNewOpaque(n, dm_parameter->data? dm_parameter->data : ""); - if (!n) goto fault; - - counter++; - - del_list_parameter(dm_parameter); - } #ifdef ACS_MULTI b = mxmlFindElement(session->tree_out, session->tree_out, "ParameterList", NULL, NULL, MXML_DESCEND); @@ -1251,17 +1273,14 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc FREE(c); #endif - cwmp_dm_ctx_clean(&dmctx); return 0; fault: if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; - cwmp_dm_ctx_clean(&dmctx); return 0; error: - cwmp_dm_ctx_clean(&dmctx); return -1; } @@ -1272,24 +1291,24 @@ error: int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc *rpc) { mxml_node_t *n, *parameter_list, *b = session->body_in; - struct dm_parameter *dm_parameter; char *parameter_name = NULL; char *NextLevel = NULL; char *c; int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR; - struct dmctx dmctx = {0}; - - cwmp_dm_ctx_init(&cwmp_main, &dmctx); + struct json_object *parameters = NULL, *param_obj = NULL, *param_name = NULL, *writable = NULL; n = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); - if (!n) goto fault; + if (!n) + goto fault; n = mxmlNewElement(n, "cwmp:GetParameterNamesResponse"); - if (!n) goto fault; + if (!n) + goto fault; parameter_list = mxmlNewElement(n, "ParameterList"); - if (!parameter_list) goto fault; + if (!parameter_list) + goto fault; #ifdef ACS_MULTI mxmlElementSetAttr(parameter_list, "xsi:type", "soap_enc:Array"); @@ -1316,35 +1335,39 @@ 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) { - int e = dm_entry_param_method(&dmctx, CMD_GET_NAME, parameter_name, NextLevel, NULL); - if (e) { - fault_code = cwmp_get_fault_code(e); + char *err = cwmp_get_parameter_names(parameter_name, strcmp(NextLevel, "true") == 0 || strcmp(NextLevel, "1") == 0?true:false, ¶meters); + if (err) { + fault_code = cwmp_get_fault_code_by_string(err); goto fault; } } - while (dmctx.list_parameter.next != &dmctx.list_parameter) { - dm_parameter = list_entry(dmctx.list_parameter.next, struct dm_parameter, list); - + foreach_jsonobj_in_array(param_obj, parameters) { n = mxmlNewElement(parameter_list, "ParameterInfoStruct"); - if (!n) goto fault; + if (!n) + goto fault; n = mxmlNewElement(n, "Name"); - if (!n) goto fault; + if (!n) + goto fault; - n = mxmlNewOpaque(n, dm_parameter->name); - if (!n) goto fault; + json_object_object_get_ex(param_obj, "parameter", ¶m_name); + n = mxmlNewOpaque(n, json_object_get_string(param_name)); + if (!n) + goto fault; n = n->parent->parent; n = mxmlNewElement(n, "Writable"); - if (!n) goto fault; + if (!n) + goto fault; - n = mxmlNewOpaque(n, dm_parameter->data); - if (!n) goto fault; + json_object_object_get_ex(param_obj, "writable", &writable); + n = mxmlNewOpaque(n, json_object_get_string(writable)); + if (!n) + goto fault; counter++; - del_list_parameter(dm_parameter); } #ifdef ACS_MULTI @@ -1359,17 +1382,14 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc FREE(c); #endif - cwmp_dm_ctx_clean(&dmctx); return 0; fault: if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; - cwmp_dm_ctx_clean(&dmctx); return 0; error: - cwmp_dm_ctx_clean(&dmctx); return -1; } @@ -1380,13 +1400,10 @@ error: int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct rpc *rpc) { mxml_node_t *n, *parameter_list, *b; - struct dm_parameter *dm_parameter; char *parameter_name = NULL; char *c=NULL; int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR; - struct dmctx dmctx = {0}; - - cwmp_dm_ctx_init(&cwmp_main, &dmctx); + struct json_object *parameters = NULL, *param_obj = NULL, *param_name = NULL, *notification = NULL; b = session->body_in; n = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", @@ -1416,46 +1433,51 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct parameter_name = ""; } if (parameter_name) { - int e = dm_entry_param_method(&dmctx, CMD_GET_NOTIFICATION, parameter_name, NULL, NULL); - if (e) { - fault_code = cwmp_get_fault_code(e); + char* err = cwmp_get_parameter_attributes(parameter_name, ¶meters); + if (err) { + fault_code = cwmp_get_fault_code_by_string(err); goto fault; } + foreach_jsonobj_in_array(param_obj, parameters) { + n = mxmlNewElement(parameter_list, "ParameterAttributeStruct"); + if (!n) + goto fault; + + n = mxmlNewElement(n, "Name"); + if (!n) + goto fault; + + json_object_object_get_ex(param_obj, "parameter", ¶m_name); + n = mxmlNewOpaque(n, json_object_get_string(param_name)); + if (!n) + goto fault; + + n = n->parent->parent; + n = mxmlNewElement(n, "Notification"); + if (!n) + goto fault; + + json_object_object_get_ex(param_obj, "value", ¬ification); + n = mxmlNewOpaque(n, json_object_get_string(notification)); + if (!n) + goto fault; + + n = n->parent->parent; + n = mxmlNewElement(n, "AccessList"); + if (!n) + goto fault; + + n = mxmlNewOpaque(n, ""); + if (!n) + goto fault; + + counter++; + + } } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); parameter_name = NULL; } - - while (dmctx.list_parameter.next != &dmctx.list_parameter) { - dm_parameter = list_entry(dmctx.list_parameter.next, struct dm_parameter, list); - - n = mxmlNewElement(parameter_list, "ParameterAttributeStruct"); - if (!n) goto fault; - - n = mxmlNewElement(n, "Name"); - if (!n) goto fault; - - n = mxmlNewOpaque(n, dm_parameter->name); - if (!n) goto fault; - - n = n->parent->parent; - n = mxmlNewElement(n, "Notification"); - if (!n) goto fault; - - n = mxmlNewOpaque(n, dm_parameter->data); - if (!n) goto fault; - - n = n->parent->parent; - n = mxmlNewElement(n, "AccessList"); - if (!n) goto fault; - - n = mxmlNewOpaque(n, ""); - if (!n) goto fault; - - counter++; - - del_list_parameter(dm_parameter); - } #ifdef ACS_MULTI b = mxmlFindElement(session->tree_out, session->tree_out, "ParameterList", NULL, NULL, MXML_DESCEND); @@ -1468,17 +1490,14 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct FREE(c); #endif - cwmp_dm_ctx_clean(&dmctx); return 0; fault: if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; - cwmp_dm_ctx_clean(&dmctx); return 0; error: - cwmp_dm_ctx_clean(&dmctx); return -1; } @@ -1509,9 +1528,6 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc char *parameter_key = NULL; char *v, *c = NULL; int fault_code = FAULT_CPE_INTERNAL_ERROR; - struct dmctx dmctx = {0}; - - cwmp_dm_ctx_init(&cwmp_main, &dmctx); b = mxmlFindElement(session->body_in, session->body_in, "ParameterList", NULL, NULL, MXML_DESCEND); if(!b) { @@ -1519,6 +1535,8 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc goto fault; } + LIST_HEAD(list_fault_param); + rpc->list_set_value_fault = &list_fault_param; while (b) { if (b && b->type == MXML_OPAQUE && b->value.opaque && @@ -1554,16 +1572,15 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc } b = n->last_child; } - if (b && b->type == MXML_ELEMENT && !strcmp(b->value.element.name, "Value") && !b->child) { parameter_value = strdup(""); } if (parameter_name && parameter_value) { - int e = dm_entry_param_method(&dmctx, CMD_SET_VALUE, parameter_name, parameter_value, NULL); - cwmp_set_end_session(dmctx.end_session_flag); - if (e) { + char *err = cwmp_set_parameter_value(parameter_name, parameter_value, parameter_key); + if (err) { + cwmp_add_list_fault_param(parameter_name, atoi(err), rpc->list_set_value_fault); fault_code = FAULT_CPE_INVALID_ARGUMENTS; } parameter_name = NULL; @@ -1586,37 +1603,32 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc if (b && b->type == MXML_OPAQUE && b->value.opaque) parameter_key = b->value.opaque; - int f = dm_entry_apply(&dmctx, CMD_SET_VALUE, parameter_key ? parameter_key : "", NULL); - if (f) { - fault_code = cwmp_get_fault_code(f); - goto fault; - } - b = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); - if (!b) goto fault; + if (!b) + goto fault; b = mxmlNewElement(b, "cwmp:SetParameterValuesResponse"); - if (!b) goto fault; + if (!b) + goto fault; b = mxmlNewElement(b, "Status"); - if (!b) goto fault; + if (!b) + goto fault; b = mxmlNewOpaque(b, "1"); - if (!b) goto fault; + if (!b) + goto fault; - cwmp_dm_ctx_clean(&dmctx); + //cwmp_set_end_session(flag) return 0; fault: - rpc->list_set_value_fault = &dmctx.list_fault_param; if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; - cwmp_dm_ctx_clean(&dmctx); return 0; error: - cwmp_dm_ctx_clean(&dmctx); return -1; } @@ -1629,9 +1641,6 @@ int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct mxml_node_t *n, *b = session->body_in; char *c, *parameter_name = NULL, *parameter_notification = NULL, *attr_notification_update = NULL; int fault_code = FAULT_CPE_INTERNAL_ERROR; - struct dmctx dmctx = {0}; - - cwmp_dm_ctx_init(&cwmp_main, &dmctx); /* handle cwmp:SetParameterAttributes */ if (asprintf(&c, "%s:%s", ns.cwmp, "SetParameterAttributes") == -1) @@ -1683,45 +1692,35 @@ int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct !b->child) { parameter_notification = ""; } - if (attr_notification_update && parameter_name && parameter_notification) { - int e = dm_entry_param_method(&dmctx, CMD_SET_NOTIFICATION, parameter_name, parameter_notification, attr_notification_update); - cwmp_set_end_session(dmctx.end_session_flag); - if (e) { - fault_code = cwmp_get_fault_code(e); + + if (parameter_name && parameter_notification) { + char* err = cwmp_set_parameter_attributes(parameter_name, parameter_notification); + if (err) { + fault_code = cwmp_get_fault_code_by_string(err); goto fault; } - - attr_notification_update = NULL; + cwmp_set_end_session(END_SESSION_RELOAD); parameter_name = NULL; parameter_notification = NULL; } b = mxmlWalkNext(b, n, MXML_DESCEND); } - int f = dm_entry_apply(&dmctx, CMD_SET_NOTIFICATION, NULL, NULL); - if (f) { - fault_code = cwmp_get_fault_code(f); - goto fault; - } - b = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); if (!b) goto fault; b = mxmlNewElement(b, "cwmp:SetParameterAttributesResponse"); if (!b) goto fault; - cwmp_dm_ctx_clean(&dmctx); dmbbf_update_enabled_notify_file(DM_CWMP, cwmp_main.conf.amd_version, cwmp_main.conf.instance_mode); return 0; fault: if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; - cwmp_dm_ctx_clean(&dmctx); return 0; error: - cwmp_dm_ctx_clean(&dmctx); return -1; } @@ -1735,9 +1734,8 @@ int cwmp_handle_rpc_cpe_add_object(struct session *session, struct rpc *rpc) char *object_name = NULL; char *parameter_key = NULL; int fault_code = FAULT_CPE_INTERNAL_ERROR; - struct dmctx dmctx = {0}; + char *instance = NULL; - cwmp_dm_ctx_init(&cwmp_main, &dmctx); b = session->body_in; while (b) { @@ -1757,9 +1755,9 @@ int cwmp_handle_rpc_cpe_add_object(struct session *session, struct rpc *rpc) } if (object_name) { - int e = dm_entry_param_method(&dmctx, CMD_ADD_OBJECT, object_name, parameter_key ? parameter_key : "", NULL); - if (e) { - fault_code = cwmp_get_fault_code(e); + char *err = cwmp_add_object(object_name, parameter_key ? parameter_key : "", &instance); + if (err) { + fault_code = cwmp_get_fault_code_by_string(err); goto fault; } } else { @@ -1769,35 +1767,38 @@ int cwmp_handle_rpc_cpe_add_object(struct session *session, struct rpc *rpc) b = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); - if (!b) goto fault; + if (!b) + goto fault; b = mxmlNewElement(b, "cwmp:AddObjectResponse"); - if (!b) goto fault; + if (!b) + goto fault; b = mxmlNewElement(b, "InstanceNumber"); - if (!b) goto fault; + if (!b) + goto fault; - b = mxmlNewOpaque(b, dmctx.addobj_instance); - if (!b) goto fault; + b = mxmlNewOpaque(b, instance); + if (!b) + goto fault; b = b->parent->parent; b = mxmlNewElement(b, "Status"); - if (!b) goto fault; + if (!b) + goto fault; b = mxmlNewOpaque(b, "1"); - if (!b) goto fault; + if (!b) + goto fault; - cwmp_dm_ctx_clean(&dmctx); return 0; fault: if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; - cwmp_dm_ctx_clean(&dmctx); return 0; error: - cwmp_dm_ctx_clean(&dmctx); return -1; } @@ -1811,9 +1812,6 @@ int cwmp_handle_rpc_cpe_delete_object(struct session *session, struct rpc *rpc) char *object_name = NULL; char *parameter_key = NULL; int fault_code = FAULT_CPE_INTERNAL_ERROR; - struct dmctx dmctx = {0}; - - cwmp_dm_ctx_init(&cwmp_main, &dmctx); b = session->body_in; while (b) { @@ -1833,9 +1831,9 @@ int cwmp_handle_rpc_cpe_delete_object(struct session *session, struct rpc *rpc) } if (object_name) { - int e = dm_entry_param_method(&dmctx, CMD_DEL_OBJECT, object_name, parameter_key ? parameter_key : "", NULL); - if (e) { - fault_code = cwmp_get_fault_code(e); + char *err = cwmp_delete_object(object_name, parameter_key ? parameter_key : ""); + if (err) { + fault_code = cwmp_get_fault_code_by_string(err); goto fault; } } else { @@ -1857,17 +1855,14 @@ int cwmp_handle_rpc_cpe_delete_object(struct session *session, struct rpc *rpc) b = mxmlNewOpaque(b, "1"); if (!b) goto fault; - cwmp_dm_ctx_clean(&dmctx); return 0; fault: if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; - cwmp_dm_ctx_clean(&dmctx); return 0; error: - cwmp_dm_ctx_clean(&dmctx); return -1; } @@ -4440,45 +4435,56 @@ error: int cwmp_handle_rpc_cpe_fault(struct session *session, struct rpc *rpc) { mxml_node_t *b, *t, *u, *body; - struct param_fault *param_fault; + struct cwmp_param_fault *param_fault; int idx; body = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); b = mxmlNewElement(body, "soap_env:Fault"); - if (!b) return -1; + if (!b) + return -1; t = mxmlNewElement(b, "faultcode"); - if (!t) return -1; + if (!t) + return -1; u = mxmlNewOpaque(t, (FAULT_CPE_ARRAY[session->fault_code].TYPE == FAULT_CPE_TYPE_CLIENT) ? "Client" : "Server"); - if (!u) return -1; + if (!u) + return -1; t = mxmlNewElement(b, "faultstring"); - if (!t) return -1; + if (!t) + return -1; u = mxmlNewOpaque(t, "CWMP fault"); - if (!u) return -1; + if (!u) + return -1; b = mxmlNewElement(b, "detail"); - if (!b) return -1; + if (!b) + return -1; b = mxmlNewElement(b, "cwmp:Fault"); - if (!b) return -1; + if (!b) + return -1; t = mxmlNewElement(b, "FaultCode"); - if (!t) return -1; + if (!t) + return -1; u = mxmlNewOpaque(t, FAULT_CPE_ARRAY[session->fault_code].CODE); - if (!u) return -1; + if (!u) + return -1; t = mxmlNewElement(b, "FaultString"); - if (!b) return -1; + if (!b) + return -1; u = mxmlNewOpaque(t, FAULT_CPE_ARRAY[session->fault_code].DESCRIPTION); - if (!u) return -1; + if (!u) + return -1; if (rpc->type == RPC_CPE_SET_PARAMETER_VALUES) { while (rpc->list_set_value_fault->next != rpc->list_set_value_fault) { @@ -4489,27 +4495,34 @@ int cwmp_handle_rpc_cpe_fault(struct session *session, struct rpc *rpc) idx = cwmp_get_fault_code(param_fault->fault); t = mxmlNewElement(b, "SetParameterValuesFault"); - if (!t) return -1; + if (!t) + return -1; u = mxmlNewElement(t, "ParameterName"); - if (!u) return -1; + if (!u) + return -1; u = mxmlNewOpaque(u, param_fault->name); - if (!u) return -1; + if (!u) + return -1; u = mxmlNewElement(t, "FaultCode"); - if (!u) return -1; + if (!u) + return -1; u = mxmlNewOpaque(u, FAULT_CPE_ARRAY[idx].CODE); - if (!u) return -1; + if (!u) + return -1; u = mxmlNewElement(t, "FaultString"); - if (!u) return -1; + if (!u) + return -1; u = mxmlNewOpaque(u, FAULT_CPE_ARRAY[idx].DESCRIPTION); - if (!u) return -1; + if (!u) + return -1; } - del_list_fault_param(param_fault); + cwmp_del_list_fault_param(param_fault); } } @@ -4532,6 +4545,22 @@ int cwmp_get_fault_code (int fault_code) return i; } +int cwmp_get_fault_code_by_string (char* fault_code) +{ + int i; + + for (i=1; i<__FAULT_CPE_MAX; i++) + { + if (strcmp(FAULT_CPE_ARRAY[i].CODE, fault_code) == 0) + break; + } + + if(i == __FAULT_CPE_MAX) + i = FAULT_CPE_INTERNAL_ERROR; + + return i; +} + int cwmp_create_fault_message(struct session *session, struct rpc *rpc_cpe, int fault_code) { CWMP_LOG (INFO,"Fault detected"); @@ -4545,7 +4574,6 @@ int cwmp_create_fault_message(struct session *session, struct rpc *rpc_cpe, int CWMP_LOG (INFO,"Preparing the Fault message"); if (rpc_cpe_methods[RPC_CPE_FAULT].handler(session, rpc_cpe)) return -1; - rpc_cpe->type = RPC_CPE_FAULT; return 0;