diff --git a/src/common.h b/src/common.h index 2c98cef..c4e233d 100644 --- a/src/common.h +++ b/src/common.h @@ -184,11 +184,9 @@ enum cwmp_start { }; enum cwmp_ret_err { - CWMP_XML_ERR = -1, CWMP_OK = 0, /* No Error */ CWMP_GEN_ERR, /* General Error */ CWMP_MEM_ERR, /* Memory Error */ - CWMP_MUTEX_ERR, CWMP_RETRY_SESSION }; @@ -570,4 +568,5 @@ bool match_reg_exp(char *reg_exp, char *param_name); void cwmp_invoke_intf_reset(char *path); void check_firewall_restart_state(); void add_day_to_time(struct tm *time); +int set_rpc_acs_to_supported(const char *rpc_name); #endif diff --git a/src/rpc.c b/src/rpc.c index 99976b1..03daf53 100755 --- a/src/rpc.c +++ b/src/rpc.c @@ -34,30 +34,33 @@ #define DM_CONN_REQ_URL "Device.ManagementServer.ConnectionRequestURL" struct cwmp_namespaces ns; -const struct rpc_cpe_method rpc_cpe_methods[] = { [RPC_CPE_GET_RPC_METHODS] = { "GetRPCMethods", cwmp_handle_rpc_cpe_get_rpc_methods, AMD_1 }, - [RPC_CPE_SET_PARAMETER_VALUES] = { "SetParameterValues", cwmp_handle_rpc_cpe_set_parameter_values, AMD_1 }, - [RPC_CPE_GET_PARAMETER_VALUES] = { "GetParameterValues", cwmp_handle_rpc_cpe_get_parameter_values, AMD_1 }, - [RPC_CPE_GET_PARAMETER_NAMES] = { "GetParameterNames", cwmp_handle_rpc_cpe_get_parameter_names, AMD_1 }, - [RPC_CPE_SET_PARAMETER_ATTRIBUTES] = { "SetParameterAttributes", cwmp_handle_rpc_cpe_set_parameter_attributes, AMD_1 }, - [RPC_CPE_GET_PARAMETER_ATTRIBUTES] = { "GetParameterAttributes", cwmp_handle_rpc_cpe_get_parameter_attributes, AMD_1 }, - [RPC_CPE_ADD_OBJECT] = { "AddObject", cwmp_handle_rpc_cpe_add_object, AMD_1 }, - [RPC_CPE_DELETE_OBJECT] = { "DeleteObject", cwmp_handle_rpc_cpe_delete_object, AMD_1 }, - [RPC_CPE_REBOOT] = { "Reboot", cwmp_handle_rpc_cpe_reboot, AMD_1 }, - [RPC_CPE_DOWNLOAD] = { "Download", cwmp_handle_rpc_cpe_download, AMD_1 }, - [RPC_CPE_UPLOAD] = { "Upload", cwmp_handle_rpc_cpe_upload, AMD_1 }, - [RPC_CPE_FACTORY_RESET] = { "FactoryReset", cwmp_handle_rpc_cpe_factory_reset, AMD_1 }, - [RPC_CPE_CANCEL_TRANSFER] = { "CancelTransfer", cwmp_handle_rpc_cpe_cancel_transfer, AMD_3 }, - [RPC_CPE_SCHEDULE_INFORM] = { "ScheduleInform", cwmp_handle_rpc_cpe_schedule_inform, AMD_1 }, - [RPC_CPE_SCHEDULE_DOWNLOAD] = { "ScheduleDownload", cwmp_handle_rpc_cpe_schedule_download, AMD_3 }, - [RPC_CPE_CHANGE_DU_STATE] = { "ChangeDUState", cwmp_handle_rpc_cpe_change_du_state, AMD_3 }, - [RPC_CPE_X_FACTORY_RESET_SOFT] = { "X_FactoryResetSoft", cwmp_handle_rpc_cpe_x_factory_reset_soft, AMD_1 }, - [RPC_CPE_FAULT] = { "Fault", cwmp_handle_rpc_cpe_fault, AMD_1 } }; +const struct rpc_cpe_method rpc_cpe_methods[] = { + [RPC_CPE_GET_RPC_METHODS] = { "GetRPCMethods", cwmp_handle_rpc_cpe_get_rpc_methods, AMD_1 }, + [RPC_CPE_SET_PARAMETER_VALUES] = { "SetParameterValues", cwmp_handle_rpc_cpe_set_parameter_values, AMD_1 }, + [RPC_CPE_GET_PARAMETER_VALUES] = { "GetParameterValues", cwmp_handle_rpc_cpe_get_parameter_values, AMD_1 }, + [RPC_CPE_GET_PARAMETER_NAMES] = { "GetParameterNames", cwmp_handle_rpc_cpe_get_parameter_names, AMD_1 }, + [RPC_CPE_SET_PARAMETER_ATTRIBUTES] = { "SetParameterAttributes", cwmp_handle_rpc_cpe_set_parameter_attributes, AMD_1 }, + [RPC_CPE_GET_PARAMETER_ATTRIBUTES] = { "GetParameterAttributes", cwmp_handle_rpc_cpe_get_parameter_attributes, AMD_1 }, + [RPC_CPE_ADD_OBJECT] = { "AddObject", cwmp_handle_rpc_cpe_add_object, AMD_1 }, + [RPC_CPE_DELETE_OBJECT] = { "DeleteObject", cwmp_handle_rpc_cpe_delete_object, AMD_1 }, + [RPC_CPE_REBOOT] = { "Reboot", cwmp_handle_rpc_cpe_reboot, AMD_1 }, + [RPC_CPE_DOWNLOAD] = { "Download", cwmp_handle_rpc_cpe_download, AMD_1 }, + [RPC_CPE_UPLOAD] = { "Upload", cwmp_handle_rpc_cpe_upload, AMD_1 }, + [RPC_CPE_FACTORY_RESET] = { "FactoryReset", cwmp_handle_rpc_cpe_factory_reset, AMD_1 }, + [RPC_CPE_CANCEL_TRANSFER] = { "CancelTransfer", cwmp_handle_rpc_cpe_cancel_transfer, AMD_3 }, + [RPC_CPE_SCHEDULE_INFORM] = { "ScheduleInform", cwmp_handle_rpc_cpe_schedule_inform, AMD_1 }, + [RPC_CPE_SCHEDULE_DOWNLOAD] = { "ScheduleDownload", cwmp_handle_rpc_cpe_schedule_download, AMD_3 }, + [RPC_CPE_CHANGE_DU_STATE] = { "ChangeDUState", cwmp_handle_rpc_cpe_change_du_state, AMD_3 }, + [RPC_CPE_X_FACTORY_RESET_SOFT] = { "X_FactoryResetSoft", cwmp_handle_rpc_cpe_x_factory_reset_soft, AMD_1 }, + [RPC_CPE_FAULT] = { "Fault", cwmp_handle_rpc_cpe_fault, AMD_1 } +}; -struct rpc_acs_method rpc_acs_methods[] = { [RPC_ACS_INFORM] = { "Inform", cwmp_rpc_acs_prepare_message_inform, cwmp_rpc_acs_parse_response_inform, NULL, NOT_KNOWN }, - [RPC_ACS_GET_RPC_METHODS] = { "GetRPCMethods", cwmp_rpc_acs_prepare_get_rpc_methods, cwmp_rpc_acs_parse_response_get_rpc_methods, NULL, NOT_KNOWN }, - [RPC_ACS_TRANSFER_COMPLETE] = { "TransferComplete", cwmp_rpc_acs_prepare_transfer_complete, NULL, cwmp_rpc_acs_destroy_data_transfer_complete, NOT_KNOWN }, - [RPC_ACS_DU_STATE_CHANGE_COMPLETE] = { "DUStateChangeComplete", cwmp_rpc_acs_prepare_du_state_change_complete, NULL, cwmp_rpc_acs_destroy_data_du_state_change_complete, NOT_KNOWN }, - [RPC_ACS_AUTONOMOUS_DU_STATE_CHANGE_COMPLETE] = { "AutonomousDUStateChangeComplete", cwmp_rpc_acs_prepare_autonomous_du_state_change_complete, NULL, cwmp_rpc_acs_destroy_data_autonomous_du_state_change_complete, NOT_KNOWN } +struct rpc_acs_method rpc_acs_methods[] = { + [RPC_ACS_INFORM] = { "Inform", cwmp_rpc_acs_prepare_message_inform, cwmp_rpc_acs_parse_response_inform, NULL, NOT_KNOWN }, + [RPC_ACS_GET_RPC_METHODS] = { "GetRPCMethods", cwmp_rpc_acs_prepare_get_rpc_methods, cwmp_rpc_acs_parse_response_get_rpc_methods, NULL, NOT_KNOWN }, + [RPC_ACS_TRANSFER_COMPLETE] = { "TransferComplete", cwmp_rpc_acs_prepare_transfer_complete, NULL, cwmp_rpc_acs_destroy_data_transfer_complete, NOT_KNOWN }, + [RPC_ACS_DU_STATE_CHANGE_COMPLETE] = { "DUStateChangeComplete", cwmp_rpc_acs_prepare_du_state_change_complete, NULL, cwmp_rpc_acs_destroy_data_du_state_change_complete, NOT_KNOWN }, + [RPC_ACS_AUTONOMOUS_DU_STATE_CHANGE_COMPLETE] = { "AutonomousDUStateChangeComplete", cwmp_rpc_acs_prepare_autonomous_du_state_change_complete, NULL, cwmp_rpc_acs_destroy_data_autonomous_du_state_change_complete, NOT_KNOWN } }; char *forced_inform_parameters[] = { @@ -516,7 +519,7 @@ error: return -1; } -int set_rpc_acs_to_supported(char *rpc_name) +int set_rpc_acs_to_supported(const char *rpc_name) { int i; @@ -549,17 +552,18 @@ int cwmp_rpc_acs_parse_response_get_rpc_methods(struct rpc *this __attribute__(( if (!b) goto error; - while (b) { - const char *node_opaque = mxmlGetOpaque(b); - mxml_node_t *parent_node = mxmlGetParent(b); - mxml_type_t node_type = mxmlGetType(b); - const char *parent_name = parent_node ? mxmlGetElement(parent_node) : NULL; + LIST_HEAD(getrpcs_acs_list); + struct xml_data_struct getrpcs_xml_attrs = {0}; + getrpcs_xml_attrs.data_list = &getrpcs_acs_list; + struct xml_tag_validation getrpcs_validation[] = {{"string", VALIDATE_STR_SIZE, 0, 256}}; + getrpcs_xml_attrs.validations = getrpcs_validation; + getrpcs_xml_attrs.nbre_validations = 1; - if (node_type == MXML_OPAQUE && mxmlGetType(parent_node) == MXML_ELEMENT && node_opaque && parent_name && strcmp((char *) mxmlGetElement(parent_node), "string") == 0) - set_rpc_acs_to_supported((char*)node_opaque); + int err = load_xml_node_data(SOAP_RESP_ACS_GETRPC, b, &getrpcs_xml_attrs); + cwmp_free_all_xml_data_list(&getrpcs_acs_list); + if (err) + goto error; - b = mxmlWalkNext(b, cwmp_main->session->body_in, MXML_DESCEND); - } set_not_known_acs_support(); return 0; error: @@ -739,10 +743,9 @@ error: */ int cwmp_handle_rpc_cpe_get_parameter_values(struct rpc *rpc) { - mxml_node_t *b, *parameter_list = NULL; + mxml_node_t *b; int fault_code = FAULT_CPE_INTERNAL_ERROR; int counter = 0; - char c[256]; if (cwmp_main->session->tree_out == NULL) goto fault; @@ -751,15 +754,6 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct rpc *rpc) if (b == NULL) goto fault; - struct xml_data_struct gpv_resp_xml_attrs = {0}; - - char *xsi_type = "soap_enc:Array"; - gpv_resp_xml_attrs.xsi_type = &xsi_type; - gpv_resp_xml_attrs.parameter_list = ¶meter_list; - - int fault = build_xml_node_data(SOAP_RESP_GPV, b, &gpv_resp_xml_attrs); - if (fault != CWMP_OK) - goto fault; LIST_HEAD(gpv_xml_data_list); @@ -769,47 +763,25 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct rpc *rpc) gpv_xml_attrs.validations = gpv_validation; gpv_xml_attrs.nbre_validations = 1; - fault = load_xml_node_data(SOAP_REQ_GPV, cwmp_main->session->body_in, &gpv_xml_attrs); - if (fault) { - fault_code = fault; + fault_code = load_xml_node_data(SOAP_REQ_GPV, cwmp_main->session->body_in, &gpv_xml_attrs); + if (fault_code) goto fault; - } - struct xml_list_data *p = NULL; - struct list_head *l = gpv_xml_data_list.next; - while (l != &gpv_xml_data_list) { - p = list_entry(l, struct xml_list_data, list); - LIST_HEAD(parameters_list); - char *err = cwmp_get_parameter_values(p->param_name, ¶meters_list); - if (err && !is_obj_excluded(p->param_name)) { - fault_code = cwmp_get_fault_code_by_string(err); - goto fault; - } - LIST_HEAD(prameters_xml_list); - dm_parameter_list_to_xml_data_list(¶meters_list, &prameters_xml_list); + gpv_xml_attrs.rpc_enum = SOAP_PARAM_STRUCT; + gpv_xml_attrs.counter = &counter; + gpv_xml_attrs.inc_counter = false; + char *xsi_type = "soap_enc:Array"; + char *soap_array_type = NULL; + gpv_xml_attrs.xsi_type = &xsi_type; + gpv_xml_attrs.soap_enc_array_type = &soap_array_type; + mxml_node_t *resp = b; + fault_code = build_xml_node_data(SOAP_RESP_GET, resp, &gpv_xml_attrs); - struct xml_data_struct prmvalstrct_resp_xml_attrs = {0}; - prmvalstrct_resp_xml_attrs.counter = &counter; - prmvalstrct_resp_xml_attrs.data_list = &prameters_xml_list; - - fault = build_xml_node_data(SOAP_PARAM_STRUCT, parameter_list, &prmvalstrct_resp_xml_attrs); - if (fault != CWMP_OK) - goto fault; - - cwmp_free_all_dm_parameter_list(¶meters_list); - cwmp_free_all_xml_data_list(&prameters_xml_list); - l = l->next; - } cwmp_free_all_xml_data_list(&gpv_xml_data_list); - b = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "ParameterList", NULL, NULL, MXML_DESCEND); - if (!b) - goto fault; - if (snprintf(c, sizeof(c), "cwmp:ParameterValueStruct[%d]", counter) == -1) + if (fault_code) goto fault; - mxmlElementSetAttr(b, "soap_enc:arrayType", c); - return 0; fault: @@ -823,12 +795,11 @@ fault: */ int cwmp_handle_rpc_cpe_get_parameter_names(struct rpc *rpc) { - mxml_node_t *n, *b, *parameter_list; + mxml_node_t *n; char *parameter_name = NULL; bool next_level = true; int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR; LIST_HEAD(parameters_list); - char c[256]; struct xml_data_struct gpn_xml_attrs = {0}; @@ -838,11 +809,10 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct rpc *rpc) gpn_xml_attrs.validations = gpn_validation; gpn_xml_attrs.nbre_validations = 2; - int fault = load_xml_node_data(SOAP_REQ_GPN, cwmp_main->session->body_in, &gpn_xml_attrs); - if (fault != CWMP_OK) { - fault_code = fault; + fault_code = load_xml_node_data(SOAP_REQ_GPN, cwmp_main->session->body_in, &gpn_xml_attrs); + if (fault_code != CWMP_OK) goto fault; - } + char *err = cwmp_get_parameter_names(parameter_name ? parameter_name : "", next_level, ¶meters_list); if (err && !is_obj_excluded(parameter_name)) { fault_code = cwmp_get_fault_code_by_string(err); @@ -860,13 +830,6 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct rpc *rpc) goto fault; } - parameter_list = mxmlNewElement(n, "ParameterList"); - if (!parameter_list) { - fault_code = FAULT_CPE_INTERNAL_ERROR; - goto fault; - } - - mxmlElementSetAttr(parameter_list, "xsi:type", "soap_enc:Array"); LIST_HEAD(prameters_xml_list); dm_parameter_list_to_xml_data_list(¶meters_list, &prameters_xml_list); @@ -874,24 +837,20 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct rpc *rpc) struct xml_data_struct gpv_resp_xml_attrs = {0}; gpv_resp_xml_attrs.data_list = &prameters_xml_list; gpv_resp_xml_attrs.counter = &counter; + gpv_resp_xml_attrs.inc_counter = true; + char *xsi_type = "soap_enc:Array"; + char *soap_array_type = NULL; + gpv_resp_xml_attrs.xsi_type = &xsi_type; + gpv_resp_xml_attrs.soap_enc_array_type = &soap_array_type; + gpv_resp_xml_attrs.rpc_enum = SOAP_RESP_GPN; - fault = build_xml_node_data(SOAP_RESP_GPN, parameter_list, &gpv_resp_xml_attrs); - if (fault != CWMP_OK) { - fault_code = fault; - goto fault; - } - + fault_code = build_xml_node_data(SOAP_RESP_GPN, n, &gpv_resp_xml_attrs); cwmp_free_all_dm_parameter_list(¶meters_list); cwmp_free_all_xml_data_list(&prameters_xml_list); - b = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "ParameterList", NULL, NULL, MXML_DESCEND); - if (!b) + if (fault_code != CWMP_OK) goto fault; - if (snprintf(c, sizeof(c), "cwmp:ParameterInfoStruct[%d]", counter) == -1) - goto fault; - - mxmlElementSetAttr(b, "soap_enc:arrayType", c); return 0; fault: @@ -906,21 +865,15 @@ fault: */ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct rpc *rpc) { - mxml_node_t *n, *parameter_list, *b; + mxml_node_t *n, *b; int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR; - char c[256]; + b = cwmp_main->session->body_in; n = build_top_body_soap_response(cwmp_main->session->tree_out, "GetParameterAttributes"); if (!n) goto fault; - parameter_list = mxmlNewElement(n, "ParameterList"); - if (!parameter_list) - goto fault; - - mxmlElementSetAttr(parameter_list, "xsi:type", "soap_enc:Array"); - LIST_HEAD(gpa_xml_data_list); @@ -935,48 +888,21 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct rpc *rpc) fault_code = fault; goto fault; } + gpa_xml_attrs.rpc_enum = SOAP_GPA_STRUCT; + gpa_xml_attrs.counter = &counter; + gpa_xml_attrs.inc_counter = false; + char *soap_array_type = NULL; + char *xsi_type = "soap_enc:Array"; + gpa_xml_attrs.xsi_type = &xsi_type; + gpa_xml_attrs.soap_enc_array_type = &soap_array_type; + mxml_node_t *resp = n; + fault_code = build_xml_node_data(SOAP_RESP_GET, resp, &gpa_xml_attrs); - struct xml_list_data *p = NULL; - struct list_head*l= gpa_xml_data_list.next; - while (l != &gpa_xml_data_list) { - p = list_entry(l, struct xml_list_data, list); - LIST_HEAD(parameters_list); - char *err = cwmp_get_parameter_attributes(p->param_name, ¶meters_list); - if (err && !is_obj_excluded(p->param_name)) { - fault_code = cwmp_get_fault_code_by_string(err); - cwmp_free_all_dm_parameter_list(¶meters_list); - cwmp_free_all_xml_data_list(&gpa_xml_data_list); - goto fault; - } - LIST_HEAD(parameters_xml_list); - dm_parameter_list_to_xml_data_list(¶meters_list, ¶meters_xml_list); - - struct xml_data_struct gpv_resp_xml_attrs = {0}; - gpv_resp_xml_attrs.counter = &counter; - gpv_resp_xml_attrs.data_list = ¶meters_xml_list; - fault = build_xml_node_data(SOAP_RESP_GPA, parameter_list, &gpv_resp_xml_attrs); - if (fault != CWMP_OK) { - fault_code = fault; - goto fault; - } - - cwmp_free_all_xml_data_list(¶meters_xml_list); - l = l->next; - } cwmp_free_all_xml_data_list(&gpa_xml_data_list); - b = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "ParameterList", NULL, NULL, MXML_DESCEND); - if (!b) { - fault_code = FAULT_CPE_INTERNAL_ERROR; + if (fault_code) goto fault; - } - if (snprintf(c, sizeof(c), "cwmp:ParameterAttributeStruct[%d]", counter) == -1) { - fault_code = FAULT_CPE_INTERNAL_ERROR; - goto fault; - } - - mxmlElementSetAttr(b, "soap_enc:arrayType", c); return 0; fault: @@ -1024,11 +950,9 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct rpc *rpc) spv_xml_attrs.validations = spv_validation; spv_xml_attrs.nbre_validations = 2; - int fault = load_xml_node_data(SOAP_REQ_SPV, cwmp_main->session->body_in, &spv_xml_attrs); - if (fault) { - fault_code = fault; + fault_code = load_xml_node_data(SOAP_REQ_SPV, cwmp_main->session->body_in, &spv_xml_attrs); + if (fault_code) goto fault; - } xml_data_list_to_dm_parameter_list(&xml_list_set_param_value, &list_set_param_value); @@ -1069,8 +993,8 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct rpc *rpc) int status = 1; struct xml_data_struct spv_resp_xml_attrs = {.status = &status}; - fault = build_xml_node_data(SOAP_RESP_SPV, b, &spv_resp_xml_attrs); - if (fault) + fault_code = build_xml_node_data(SOAP_RESP_SPV, b, &spv_resp_xml_attrs); + if (fault_code) goto fault; if (!cwmp_transaction_commit()) { @@ -1084,7 +1008,7 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct rpc *rpc) fault: cwmp_free_all_dm_parameter_list(&list_set_param_value); if (cwmp_create_fault_message(rpc, fault_code)) - ret = CWMP_XML_ERR; + ret = -1; cwmp_free_all_list_param_fault(rpc->list_set_value_fault); if (transaction_id) { @@ -1145,7 +1069,7 @@ int cwmp_handle_rpc_cpe_set_parameter_attributes(struct rpc *rpc) fault: if (cwmp_create_fault_message(rpc, fault_code)) - ret = CWMP_XML_ERR; + ret = -1; return ret; } @@ -1168,12 +1092,10 @@ int cwmp_handle_rpc_cpe_add_object(struct rpc *rpc) add_obj_xml_attrs.validations = gpn_validation; add_obj_xml_attrs.nbre_validations = 2; - int fault = load_xml_node_data(SOAP_REQ_ADDOBJ, cwmp_main->session->body_in, &add_obj_xml_attrs); + fault_code = load_xml_node_data(SOAP_REQ_ADDOBJ, cwmp_main->session->body_in, &add_obj_xml_attrs); - if (fault) { - fault_code = fault; + if (fault_code) goto fault; - } if (transaction_id == 0) { if (!cwmp_transaction_start("cwmp")) @@ -1203,11 +1125,9 @@ int cwmp_handle_rpc_cpe_add_object(struct rpc *rpc) add_resp_xml_attrs.instance = &instance_int; add_resp_xml_attrs.status = &status; - fault = build_xml_node_data(SOAP_RESP_ADDOBJ, b, &add_resp_xml_attrs); - if (fault != CWMP_OK) { - fault_code = fault; + fault_code = build_xml_node_data(SOAP_RESP_ADDOBJ, b, &add_resp_xml_attrs); + if (fault_code != CWMP_OK) goto fault; - } if (!cwmp_transaction_commit()) goto fault; @@ -1226,7 +1146,7 @@ fault: FREE(parameter_key); FREE(instance); if (cwmp_create_fault_message(rpc, fault_code)) - ret = CWMP_XML_ERR; + ret = -1; if (transaction_id) { cwmp_transaction_abort(); transaction_id = 0; @@ -1251,12 +1171,10 @@ int cwmp_handle_rpc_cpe_delete_object(struct rpc *rpc) del_obj_xml_attrs.validations = gpn_validation; del_obj_xml_attrs.nbre_validations = 2; - int fault = load_xml_node_data(SOAP_REQ_DELOBJ, cwmp_main->session->body_in, &del_obj_xml_attrs); + fault_code = load_xml_node_data(SOAP_REQ_DELOBJ, cwmp_main->session->body_in, &del_obj_xml_attrs); - if (fault) { - fault_code = fault; + if (fault_code) goto fault; - } if (transaction_id == 0) { if (!cwmp_transaction_start("cwmp")) @@ -1284,11 +1202,9 @@ int cwmp_handle_rpc_cpe_delete_object(struct rpc *rpc) struct xml_data_struct add_resp_xml_attrs = {0}; add_resp_xml_attrs.status = &status; - fault = build_xml_node_data(SOAP_RESP_DELOBJ, b, &add_resp_xml_attrs); - if (fault != CWMP_OK) { - fault_code = fault; + fault_code = build_xml_node_data(SOAP_RESP_DELOBJ, b, &add_resp_xml_attrs); + if (fault_code != CWMP_OK) goto fault; - } if (!cwmp_transaction_commit()) { fault_code = FAULT_CPE_INTERNAL_ERROR; @@ -1303,7 +1219,7 @@ fault: FREE(object_name); FREE(parameter_key); if (cwmp_create_fault_message(rpc, fault_code)) - ret = CWMP_XML_ERR; + ret = -1; if (transaction_id) { cwmp_transaction_abort(); transaction_id = 0; @@ -1316,10 +1232,8 @@ fault: */ int cwmp_handle_rpc_cpe_get_rpc_methods(struct rpc *rpc) { - mxml_node_t *n, *method_list; + mxml_node_t *n; int i, counter = 0; - mxml_node_t *b = cwmp_main->session->body_in; - char c[128]; int fault_code = FAULT_CPE_INTERNAL_ERROR; n = build_top_body_soap_response(cwmp_main->session->tree_out, "GetRPCMethods"); @@ -1339,39 +1253,29 @@ int cwmp_handle_rpc_cpe_get_rpc_methods(struct rpc *rpc) } } - method_list = mxmlNewElement(n, "MethodList"); - if (!method_list) - goto fault; - struct xml_data_struct getrpc_resp_xml_attrs = {0}; getrpc_resp_xml_attrs.data_list = &rpcs_list; + getrpc_resp_xml_attrs.counter = &counter; + getrpc_resp_xml_attrs.inc_counter = false; + char *xsi_type = "soap_enc:Array"; + char *soap_array_type = NULL; + getrpc_resp_xml_attrs.xsi_type = &xsi_type; + getrpc_resp_xml_attrs.soap_enc_array_type = &soap_array_type; + getrpc_resp_xml_attrs.rpc_enum = SOAP_RESP_GETRPC; - int fault = build_xml_node_data(SOAP_RESP_GETRPC, method_list, &getrpc_resp_xml_attrs); - if (fault != CWMP_OK) { - fault_code = fault; - goto fault; - } - + fault_code = build_xml_node_data(SOAP_RESP_GETRPC, n, &getrpc_resp_xml_attrs); cwmp_free_all_xml_data_list(&rpcs_list); - b = mxmlFindElement(cwmp_main->session->tree_out, cwmp_main->session->tree_out, "MethodList", NULL, NULL, MXML_DESCEND); - if (!b) - goto fault; - mxmlElementSetAttr(b, "xsi:type", "soap_enc:Array"); - if (snprintf(c, sizeof(c), "xsd:string[%d]", counter) == -1) + if (fault_code != CWMP_OK) goto fault; - mxmlElementSetAttr(b, "soap_enc:arrayType", c); - return 0; fault: if (cwmp_create_fault_message(rpc, fault_code)) - goto error; + return -1; return 0; -error: - return -1; } /* @@ -1732,12 +1636,10 @@ int cwmp_handle_rpc_cpe_download(struct rpc *rpc) download_xml_attrs.validations = download_validation; download_xml_attrs.nbre_validations = 7; - int fault = load_xml_node_data(SOAP_REQ_DOWNLOAD, n, &download_xml_attrs); + error = load_xml_node_data(SOAP_REQ_DOWNLOAD, n, &download_xml_attrs); - if (fault) { - error = fault; + if (error) goto fault; - } if (strcmp(download->file_type, FIRMWARE_UPGRADE_IMAGE_FILE_TYPE) && strcmp(download->file_type, WEB_CONTENT_FILE_TYPE) && strcmp(download->file_type, VENDOR_CONFIG_FILE_TYPE) && strcmp(download->file_type, TONE_FILE_TYPE) && strcmp(download->file_type, RINGER_FILE_TYPE) && strcmp(download->file_type, STORED_FIRMWARE_IMAGE_FILE_TYPE)) { error = FAULT_CPE_INVALID_ARGUMENTS; @@ -1762,11 +1664,9 @@ int cwmp_handle_rpc_cpe_download(struct rpc *rpc) download_resp_xml_attrs.status = &status; download_resp_xml_attrs.start_time = &start_time; download_resp_xml_attrs.complete_time = &complete_time; - fault = build_xml_node_data(SOAP_RESP_DOWNLOAD, t, &download_resp_xml_attrs); - if (fault != CWMP_OK) { - error = fault; + error = build_xml_node_data(SOAP_RESP_DOWNLOAD, t, &download_resp_xml_attrs); + if (error != CWMP_OK) goto fault; - } if (error == FAULT_CPE_NO_FAULT) { if (download_delay != 0) @@ -2008,11 +1908,9 @@ int cwmp_handle_rpc_cpe_upload(struct rpc *rpc) upload_resp_xml_attrs.status = &status; upload_resp_xml_attrs.start_time = &start_time; upload_resp_xml_attrs.complete_time = &complete_time; - int fault = build_xml_node_data(SOAP_RESP_UPLOAD, t, &upload_resp_xml_attrs); - if (fault != CWMP_OK) { - error = FAULT_CPE_INTERNAL_ERROR; + error = build_xml_node_data(SOAP_RESP_UPLOAD, t, &upload_resp_xml_attrs); + if (error != CWMP_OK) goto fault; - } if (error == FAULT_CPE_NO_FAULT) { if (upload_delay != 0) diff --git a/src/xml.c b/src/xml.c index d27f866..84c4f23 100644 --- a/src/xml.c +++ b/src/xml.c @@ -18,6 +18,7 @@ #include "cwmp_zlib.h" #include "common.h" #include "event.h" +#include "datamodel_interface.h" static const char *soap_env_url = "http://schemas.xmlsoap.org/soap/envelope/"; static const char *soap_enc_url = "http://schemas.xmlsoap.org/soap/encoding/"; @@ -60,30 +61,39 @@ struct xml_node_data xml_nodes_data[] = { /* * SOAP Responses */ - [SOAP_RESP_GPV] = {XML_SINGLE, 0, NULL, {{"ParameterList", XML_NODE, ATTR_PARAM_STRUCT, NULL}}}, + [SOAP_RESP_GET] = {XML_SINGLE, 0, NULL, {{"ParameterList", XML_REC, SOAP_RESP_GET_LIST, NULL}}}, + [SOAP_RESP_GET_LIST] = {XML_LIST, SOAP_RESP_GET_LIST_REF, NULL, {{NULL, XML_REC, SOAP_RESP_GET_LIST_ATTRS, NULL}}}, + [SOAP_RESP_GET_LIST_REF] = {XML_SINGLE, 0, NULL, {{NULL, XML_FUNC, 0, build_parameter_structure}}}, + [SOAP_RESP_GET_LIST_ATTRS] = {XML_SINGLE, 0, NULL, {{NULL, XML_REC, GET_RPC_ATTR, NULL}}}, [SOAP_PARAM_STRUCT] = {XML_LIST, SOAP_PARAM_STRUCT_REF, "ParameterValueStruct", {}}, [SOAP_PARAM_STRUCT_REF] = {XML_SINGLE, 0, NULL, {{"Name", XML_STRING, 0, NULL}, {"Value", XML_STRING, ATTR_PARAM_STRUCT, NULL}}}, [SOAP_VALUE_STRUCT] = {XML_SINGLE, 0, NULL, {{"Value", XML_STRING, ATTR_PARAM_STRUCT, NULL}}}, [SOAP_RESP_SPV] = {XML_SINGLE, 0, NULL, {{"Status", XML_INTEGER, 0, NULL}}}, - [SOAP_RESP_GPN] = {XML_LIST, SOAP_RESP_GPN_REF, "ParameterInfoStruct", {}}, + [SOAP_RESP_GPN] = {XML_SINGLE, 0, NULL, {{"ParameterList", XML_REC, SOAP_RESP_GPN_LIST, NULL}}}, + [SOAP_RESP_GPN_LIST] = {XML_LIST, SOAP_RESP_GPN_REF, "ParameterInfoStruct", {{NULL, XML_REC, SOAP_RESP_GET_LIST_ATTRS, NULL}}}, [SOAP_RESP_GPN_REF] = {XML_SINGLE, 0, NULL, {{"Name", XML_STRING, 0, NULL}, {"Writable", XML_BOOL, 0, NULL}}}, - [SOAP_RESP_GPA] = {XML_LIST, SOAP_RESP_GPA_REF, "ParameterAttributeStruct", {}}, - [SOAP_RESP_GPA_REF] = {XML_SINGLE, 0, NULL, {{"Name", XML_STRING, 0, NULL}, {"Notification", XML_INTEGER, 0, NULL}, {"AccessList", XML_STRING, 0, NULL}}}, + [SOAP_GPA_STRUCT] = {XML_LIST, SOAP_GPA_STRUCT_REF, "ParameterAttributeStruct", {}}, + [SOAP_GPA_STRUCT_REF] = {XML_SINGLE, 0, NULL, {{"Name", XML_STRING, 0, NULL}, {"Notification", XML_INTEGER, 0, NULL}, {"AccessList", XML_STRING, 0, NULL}}}, [SOAP_RESP_ADDOBJ] = {XML_SINGLE, 0, NULL, {{"InstanceNumber", XML_INTEGER, 0, NULL}, {"Status", XML_INTEGER, 0, NULL}}}, [SOAP_RESP_DELOBJ] = {XML_SINGLE, 0, NULL, {{"Status", XML_INTEGER, 0, NULL}}}, [SOAP_RESP_DOWNLOAD] = {XML_SINGLE, 0, NULL, {{"Status", XML_INTEGER, 0, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}}}, [SOAP_RESP_UPLOAD] = {XML_SINGLE, 0, NULL, {{"Status", XML_INTEGER, 0, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}}}, - [SOAP_RESP_GETRPC] = {XML_LIST, SOAP_RESP_GETRPC_REF, NULL, {}}, + [SOAP_RESP_GETRPC] = {XML_SINGLE, 0, NULL, {{"MethodList", XML_REC, SOAP_RESP_GETRPC_LIST, NULL}}}, + [SOAP_RESP_GETRPC_LIST] = {XML_LIST, SOAP_RESP_GETRPC_REF, NULL, {{NULL, XML_REC, SOAP_RESP_GET_LIST_ATTRS, NULL}}}, [SOAP_RESP_GETRPC_REF] = {XML_SINGLE, 0, NULL, {{"string", XML_STRING, 0, NULL}}}, - [SOAP_ACS_TRANSCOMPLETE] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"FaultStruct", XML_REC, SOAP_FAULT_STRCT_REF, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}}}, + [SOAP_RESP_ACS_GETRPC] = {XML_LIST, SOAP_RESP_ACS_GETRPC_REF, "string", {}}, + [SOAP_RESP_ACS_GETRPC_REF] = {XML_SINGLE, 0, NULL, {{"string", XML_FUNC, 0, load_get_rpc_method_acs_resp_string}}}, + [SOAP_ACS_TRANSCOMPLETE] = {XML_SINGLE, 0, NULL, {{"CommandKey", XML_STRING, 0, NULL}, {"FaultStruct", XML_REC, SOAP_CWMP_FAULT, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}}}, [SOAP_ROOT_FAULT] = {XML_SINGLE, 0, NULL, {{"soap_env:Fault", XML_REC, SOAP_RPC_FAULT, NULL}}}, [SOAP_RPC_FAULT] = {XML_SINGLE, 0, NULL, {{"faultcode", XML_STRING, 0, NULL}, {"faultstring", XML_STRING, 0, NULL}, {"detail", XML_REC, SOAP_FAULT_DETAIL, NULL}}}, [SOAP_FAULT_DETAIL] = {XML_SINGLE, 0, NULL, {{"cwmp:Fault", XML_REC, SOAP_CWMP_FAULT, NULL}}}, [SOAP_CWMP_FAULT] = {XML_SINGLE, 0, NULL, {{"FaultCode", XML_INTEGER, 0, NULL}, {"FaultString", XML_STRING, 0, NULL}}}, [SOAP_SPV_FAULT] = {XML_LIST, SOAP_SPV_FAULT_REF, "SetParameterValuesFault", {}}, [SOAP_SPV_FAULT_REF] = {XML_SINGLE, 0, NULL, {{"ParameterName", XML_STRING, 0, NULL}, {"FaultCode", XML_INTEGER, 0, NULL}, {"FaultString", XML_STRING, 0, NULL}}}, - [SOAP_FAULT_STRCT_REF] = {XML_SINGLE, 0, NULL, {{"FaultCode", XML_INTEGER, 0, NULL}, {"FaultString", XML_STRING, 0, NULL}}}, + /* + * SOAP RPC ACS + */ [SOAP_ENV] = {XML_SINGLE, 0, NULL, {{"soap_env:Envelope", XML_FUNC, 0, build_inform_env_header}}}, [SOAP_INFORM_CWMP] = {XML_SINGLE, 0, NULL, {{"DeviceId", XML_REC, SOAP_DEVID, NULL}, {"Event", XML_FUNC, 0, build_inform_events}, {"MaxEnvelopes", XML_INTEGER, 0, NULL}, {"CurrentTime", XML_STRING, 0, NULL}, {"RetryCount", XML_INTEGER, 0, NULL}}}, [SOAP_DEVID] = {XML_SINGLE, 0, NULL, {{"Manufacturer", XML_STRING, 0, NULL}, {"OUI", XML_STRING, 0, NULL}, {"ProductClass", XML_STRING, 0, NULL}, {"SerialNumber", XML_STRING, 0, NULL}}}, @@ -92,8 +102,13 @@ struct xml_node_data xml_nodes_data[] = { [SOAP_CDU_RESULTS_REF] = {XML_LIST, SOAP_CDU_OPTS_REF, "OpResultStruct", {}}, [SOAP_CDU_OPTS_REF] = {XML_SINGLE, 0, NULL, {{"UUID", XML_STRING, 0, NULL}, {"DeploymentUnitRef", XML_STRING, 0, NULL}, {"Version", XML_STRING, 0, NULL}, {"CurrentState", XML_STRING, 0, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}, {"FaultStruct", XML_REC, SOAP_CWMP_FAULT, NULL}}}, [SOAP_ACDU_OPTS_REF] = {XML_SINGLE, 0, NULL, {{"UUID", XML_STRING, 0, NULL}, {"Version", XML_STRING, 0, NULL}, {"CurrentState", XML_STRING, 0, NULL}, {"Resolved", XML_BOOL, 0, NULL}, {"StartTime", XML_STRING, 0, NULL}, {"CompleteTime", XML_STRING, 0, NULL}, {"FaultStruct", XML_REC, SOAP_CWMP_FAULT, NULL}, {"OperationPerformed", XML_STRING, 0, NULL}}}, + + /* + * XML node attributes + */ [ATTR_PARAM_STRUCT] = {XML_SINGLE, 0, NULL, {{"xsi:type", XML_STRING, 0, NULL}}}, - [ATTR_SOAP_ENV] = {XML_SINGLE, 0, NULL, {{"xmlns:soap_env", XML_STRING, 0, NULL}, {"xmlns:soap_enc", XML_STRING, 0, NULL}, {"xmlns:xsd", XML_STRING, 0, NULL}, {"xmlns:xsi", XML_STRING, 0, NULL}}} + [ATTR_SOAP_ENV] = {XML_SINGLE, 0, NULL, {{"xmlns:soap_env", XML_STRING, 0, NULL}, {"xmlns:soap_enc", XML_STRING, 0, NULL}, {"xmlns:xsd", XML_STRING, 0, NULL}, {"xmlns:xsi", XML_STRING, 0, NULL}}}, + [GET_RPC_ATTR] = {XML_SINGLE, 0, NULL, {{"xsi:type", XML_STRING, 0, NULL}, {"soap_enc:arrayType", XML_FUNC, 0, get_soap_enc_array_type}}} }; char* xml_tags_names[] = { @@ -131,6 +146,7 @@ char* xml_tags_names[] = { "CurrentTime", "ProductClass", "xsi:type", + "soap_enc:arrayType", "FileSize", "Notification", "MaxRetries", @@ -147,6 +163,16 @@ char* xml_tags_names[] = { "Writable", }; +int get_xml_tags_array_total_size(int tag_ref) +{ + int i; + for (i = 0; i < 10; i++) { + if (xml_nodes_data[tag_ref].xml_tags[i].rec_ref == 0 && xml_nodes_data[tag_ref].xml_tags[i].tag_name == NULL && xml_nodes_data[tag_ref].xml_tags[i].tag_type == 0) + return i; + } + return 0; +} + void add_xml_data_list(struct list_head *data_list, struct xml_list_data *xml_data) { list_add_tail(&xml_data->list, data_list); @@ -214,6 +240,23 @@ int load_upload_filetype(mxml_node_t *b, struct xml_data_struct *xml_attrs) return FAULT_CPE_NO_FAULT; } +int load_get_rpc_method_acs_resp_string(mxml_node_t *b, struct xml_data_struct *xml_attrs __attribute__((unused))) +{ + if (b == NULL) + return FAULT_CPE_INTERNAL_ERROR; + + mxml_node_t *t = mxmlWalkNext(b, b, MXML_DESCEND); + if (t == NULL) + return FAULT_CPE_INTERNAL_ERROR; + const char *node_opaque = mxmlGetOpaque(t); + if (node_opaque == NULL) + return FAULT_CPE_INVALID_ARGUMENTS; + + if (set_rpc_acs_to_supported(node_opaque) == -1) + return FAULT_CPE_INTERNAL_ERROR; + return FAULT_CPE_NO_FAULT; +} + int load_download_filetype(mxml_node_t *b, struct xml_data_struct *xml_attrs) { mxml_node_t *t = mxmlWalkNext(b, b, MXML_DESCEND); @@ -391,6 +434,66 @@ error: return FAULT_CPE_INTERNAL_ERROR; } + +int build_parameter_structure(mxml_node_t *param_list, struct xml_data_struct *xml_attrs) +{ + LIST_HEAD(parameters_list); + + char *err = NULL; + if (xml_attrs->parameter_name == NULL) + return CWMP_OK; + if (xml_attrs->rpc_enum == SOAP_PARAM_STRUCT) + err = cwmp_get_parameter_values(*(xml_attrs->parameter_name), ¶meters_list); + else if (xml_attrs->rpc_enum == SOAP_GPA_STRUCT) + err = cwmp_get_parameter_attributes(*(xml_attrs->parameter_name), ¶meters_list); + else + return FAULT_CPE_INTERNAL_ERROR; + if (err && !is_obj_excluded(*(xml_attrs->parameter_name))) { + int fault_code = cwmp_get_fault_code_by_string(err); + cwmp_free_all_dm_parameter_list(¶meters_list); + return fault_code; + } + LIST_HEAD(prameters_xml_list); + dm_parameter_list_to_xml_data_list(¶meters_list, &prameters_xml_list); + + struct xml_data_struct prmvalstrct_resp_xml_attrs = {0}; + prmvalstrct_resp_xml_attrs.data_list = &prameters_xml_list; + prmvalstrct_resp_xml_attrs.counter = xml_attrs->counter; + prmvalstrct_resp_xml_attrs.inc_counter = true; + int fault = build_xml_node_data(xml_attrs->rpc_enum, param_list, &prmvalstrct_resp_xml_attrs); + if (fault != CWMP_OK) + return fault; + + cwmp_free_all_dm_parameter_list(¶meters_list); + cwmp_free_all_xml_data_list(&prameters_xml_list); + return FAULT_CPE_NO_FAULT; +} + +int get_soap_enc_array_type(mxml_node_t *node __attribute__((unused)), struct xml_data_struct *xml_attrs) +{ + if (xml_attrs->soap_enc_array_type == NULL) + return FAULT_CPE_INTERNAL_ERROR; + if (xml_attrs->rpc_enum == SOAP_PARAM_STRUCT) { + if (icwmp_asprintf(xml_attrs->soap_enc_array_type, "cwmp:ParameterValueStruct[%d]", xml_attrs->counter ? *(xml_attrs->counter) : 0) == -1) + return FAULT_CPE_INTERNAL_ERROR; + return FAULT_CPE_NO_FAULT; + } else if (xml_attrs->rpc_enum == SOAP_GPA_STRUCT) { + if (icwmp_asprintf(xml_attrs->soap_enc_array_type, "cwmp:ParameterAttributeStruct[%d]", xml_attrs->counter ? *(xml_attrs->counter) : 0) == -1) + return FAULT_CPE_INTERNAL_ERROR; + return FAULT_CPE_NO_FAULT; + } else if (xml_attrs->rpc_enum == SOAP_RESP_GETRPC) { + if (icwmp_asprintf(xml_attrs->soap_enc_array_type, "xsd:string[%d]", xml_attrs->counter ? *(xml_attrs->counter) : 0) == -1) + return FAULT_CPE_INTERNAL_ERROR; + return FAULT_CPE_NO_FAULT; + } else if (xml_attrs->rpc_enum == SOAP_RESP_GPN) { + if (icwmp_asprintf(xml_attrs->soap_enc_array_type, "cwmp:ParameterInfoStruct[%d]", xml_attrs->counter ? *(xml_attrs->counter) : 0) == -1) + return FAULT_CPE_INTERNAL_ERROR; + return FAULT_CPE_NO_FAULT; + } + else + return FAULT_CPE_INTERNAL_ERROR; +} + int get_xml_type(int node_ref, int soap_idx) { return xml_nodes_data[node_ref].xml_tags[soap_idx].tag_type; @@ -432,7 +535,7 @@ int load_xml_list_node_data(int node_ref, mxml_node_t *node, struct xml_data_str while (b) { if (mxmlGetType(b) == MXML_ELEMENT) { const char *b_name = b ? mxmlGetElement(b) : NULL; - if (b_name && strcmp(xml_nodes_data[node_ref].tag_list_name, b_name) == 0) { + if (b_name && xml_nodes_data[node_ref].tag_list_name && strcmp(xml_nodes_data[node_ref].tag_list_name, b_name) == 0) { struct xml_list_data *xml_data = calloc(1, sizeof(struct xml_list_data)); struct xml_data_struct xml_attrs_args = {0}; @@ -460,7 +563,10 @@ int load_xml_list_node_data(int node_ref, mxml_node_t *node, struct xml_data_str xml_attrs_args.validations = xml_attrs->validations; xml_attrs_args.nbre_validations = xml_attrs->nbre_validations; xml_attrs_args.data_list = xml_attrs->data_list; - + if (xml_attrs->data_list == NULL) { + CWMP_LOG(WARNING, "the data list attribute of the corresponding node is null"); + return FAULT_CPE_INTERNAL_ERROR; + } list_add(&(xml_data->list), xml_attrs->data_list); int fault = load_xml_node_data(xml_nodes_data[node_ref].tag_node_ref, b, &xml_attrs_args); if (fault) @@ -595,7 +701,7 @@ int load_single_xml_node_data(int node_ref, mxml_node_t *node, struct xml_data_s int load_xml_node_data(int node_ref, mxml_node_t *node, struct xml_data_struct *xml_attrs) { if (!node || node_ref >= SOAP_MAX) - return CWMP_XML_ERR; + return FAULT_CPE_INTERNAL_ERROR; if (xml_nodes_data[node_ref].node_ms == XML_LIST) { return load_xml_list_node_data(node_ref, node, xml_attrs); } else { @@ -746,15 +852,20 @@ void get_xml_data_value_by_name(int type, int idx, struct xml_data_struct *xml_a void set_node_attributes(int attr_ref, mxml_node_t *node, struct xml_data_struct *xml_attrs) { - unsigned int i = 0; - size_t total_size = sizeof(xml_nodes_data[attr_ref].xml_tags) / sizeof(struct xml_tag); + int i = 0; + int total_size = get_xml_tags_array_total_size(attr_ref); for(i =0; i < total_size; i++) { char *attr_value = NULL; int idx = get_xml_tag_index(xml_nodes_data[attr_ref].xml_tags[i].tag_name); if (idx == -1) continue; - get_xml_data_value_by_name(xml_nodes_data[attr_ref].xml_tags[i].tag_type, idx, xml_attrs, &attr_value); + int tag_type = xml_nodes_data[attr_ref].xml_tags[i].tag_type; + if (xml_nodes_data[attr_ref].xml_tags[i].tag_type == XML_FUNC) { + xml_nodes_data[attr_ref].xml_tags[i].xml_func(node, xml_attrs); + tag_type = XML_STRING; + } + get_xml_data_value_by_name(tag_type, idx, xml_attrs, &attr_value); if (!attr_value) continue; mxmlElementSetAttr(node, xml_nodes_data[attr_ref].xml_tags[i].tag_name, attr_value); @@ -764,22 +875,27 @@ void set_node_attributes(int attr_ref, mxml_node_t *node, struct xml_data_struct int build_single_xml_node_data(int node_ref, mxml_node_t *node, struct xml_data_struct *xml_attrs) { int i = 0, idx = 0; - mxml_node_t *n; - size_t total_size = sizeof(xml_nodes_data[node_ref].xml_tags) / sizeof(struct xml_tag); - for(i =0; i < (int)total_size; i++) { - if (xml_nodes_data[node_ref].xml_tags[i].tag_name == NULL) - continue; + mxml_node_t *n = node; + int total_size = get_xml_tags_array_total_size(node_ref); + for(i =0; i < total_size; i++) { + if (xml_nodes_data[node_ref].xml_tags[i].tag_name != NULL) { + n = mxmlNewElement(node, xml_nodes_data[node_ref].xml_tags[i].tag_name); + if (!n) + return FAULT_CPE_INTERNAL_ERROR; + } - n = mxmlNewElement(node, xml_nodes_data[node_ref].xml_tags[i].tag_name); - if (!n) - return CWMP_XML_ERR; - - if (xml_nodes_data[node_ref].xml_tags[i].rec_ref >= ATTR_PARAM_STRUCT) + if (xml_nodes_data[node_ref].xml_tags[i].rec_ref >= ATTR_PARAM_STRUCT) { set_node_attributes(xml_nodes_data[node_ref].xml_tags[i].rec_ref, n, xml_attrs); + if (xml_nodes_data[node_ref].xml_tags[i].tag_type == XML_REC) + continue; + } if (xml_nodes_data[node_ref].xml_tags[i].tag_type == XML_REC) { - if (xml_nodes_data[node_ref].xml_tags[i].rec_ref > 0) - build_xml_node_data(xml_nodes_data[node_ref].xml_tags[i].rec_ref, n, xml_attrs); + if (xml_nodes_data[node_ref].xml_tags[i].rec_ref > 0){ + int error = build_xml_node_data(xml_nodes_data[node_ref].xml_tags[i].rec_ref, n, xml_attrs); + if (error) + return error; + } continue; } @@ -787,7 +903,7 @@ int build_single_xml_node_data(int node_ref, mxml_node_t *node, struct xml_data_ if (xml_nodes_data[node_ref].xml_tags[i].xml_func) { int err = xml_nodes_data[node_ref].xml_tags[i].xml_func(n, xml_attrs); if (err) - return CWMP_XML_ERR; + return err; } continue; } @@ -809,23 +925,22 @@ int build_single_xml_node_data(int node_ref, mxml_node_t *node, struct xml_data_ n = mxmlNewOpaque(n, opaque ? opaque : ""); if (!n) - return CWMP_XML_ERR; + return FAULT_CPE_INTERNAL_ERROR; } return CWMP_OK; } int build_xml_list_node_data(int node_ref, mxml_node_t *node, struct xml_data_struct *xml_attrs) { - mxml_node_t *n; + mxml_node_t *n = node; struct xml_list_data *xml_data; list_for_each_entry (xml_data, xml_attrs->data_list, list) { if (xml_nodes_data[node_ref].tag_list_name) { n = mxmlNewElement(node, xml_nodes_data[node_ref].tag_list_name); if (!n) - return CWMP_XML_ERR; - } else { + return FAULT_CPE_INTERNAL_ERROR; + } else n = node; - } if (xml_nodes_data[node_ref].tag_node_ref > 0) { struct xml_data_struct xml_ref_data = {0}; xml_ref_data.name = &xml_data->param_name; @@ -844,26 +959,37 @@ int build_xml_list_node_data(int node_ref, mxml_node_t *node, struct xml_data_st xml_ref_data.version = &xml_data->version; xml_ref_data.start_time = &xml_data->start_time; xml_ref_data.complete_time = &xml_data->complete_time; + xml_ref_data.rpc_enum = xml_attrs->rpc_enum; + xml_ref_data.counter = xml_attrs->counter; int fault = build_xml_node_data(xml_nodes_data[node_ref].tag_node_ref, n, &xml_ref_data); - if (fault != CWMP_OK) return fault; } - if (xml_attrs->counter != NULL) + if (xml_attrs->counter != NULL && xml_attrs->inc_counter) *(xml_attrs->counter)+=1; } + + int i; + int nbre_refs = get_xml_tags_array_total_size(node_ref); + for (i = 0; i < nbre_refs; i++) { + if (xml_nodes_data[node_ref].xml_tags[i].rec_ref > 0) { + int fault = build_xml_node_data(xml_nodes_data[node_ref].xml_tags[i].rec_ref, node, xml_attrs); + if (fault != CWMP_OK) + return fault; + } + } return 0; } int build_xml_node_data(int node_ref, mxml_node_t *node, struct xml_data_struct *xml_attrs) { if (node_ref >= SOAP_MAX) - return CWMP_XML_ERR; + return FAULT_CPE_INTERNAL_ERROR; - if (xml_nodes_data[node_ref].node_ms == XML_LIST ) { + if (xml_nodes_data[node_ref].node_ms == XML_LIST ) return build_xml_list_node_data(node_ref, node, xml_attrs); - } else + else return build_single_xml_node_data(node_ref, node, xml_attrs); return CWMP_OK; } diff --git a/src/xml.h b/src/xml.h index 17ea533..50fe3c0 100644 --- a/src/xml.h +++ b/src/xml.h @@ -39,21 +39,30 @@ enum soap_methods { SOAP_REQ_DU_UPDATE, SOAP_REQ_DU_UNINSTALL, - SOAP_RESP_GPV, + SOAP_RESP_GET, + SOAP_RESP_GET_LIST, + SOAP_RESP_GET_LIST_REF, + SOAP_RESP_GET_LIST_ATTRS, + SOAP_RESP_GET_LIST_REF2, + SOAP_RESP_GPV_PARAM, SOAP_PARAM_STRUCT, SOAP_PARAM_STRUCT_REF, SOAP_VALUE_STRUCT, SOAP_RESP_SPV, SOAP_RESP_GPN, + SOAP_RESP_GPN_LIST, SOAP_RESP_GPN_REF, - SOAP_RESP_GPA, - SOAP_RESP_GPA_REF, + SOAP_GPA_STRUCT, + SOAP_GPA_STRUCT_REF, SOAP_RESP_ADDOBJ, SOAP_RESP_DELOBJ, SOAP_RESP_DOWNLOAD, SOAP_RESP_UPLOAD, SOAP_RESP_GETRPC, + SOAP_RESP_GETRPC_LIST, SOAP_RESP_GETRPC_REF, + SOAP_RESP_ACS_GETRPC, + SOAP_RESP_ACS_GETRPC_REF, SOAP_ACS_TRANSCOMPLETE, SOAP_ROOT_FAULT, SOAP_RPC_FAULT, @@ -61,7 +70,6 @@ enum soap_methods { SOAP_CWMP_FAULT, SOAP_SPV_FAULT, SOAP_SPV_FAULT_REF, - SOAP_FAULT_STRCT_REF, SOAP_ENV, SOAP_HEAD, SOAP_BODY, @@ -74,6 +82,7 @@ enum soap_methods { SOAP_CDU_OPTS_REF, ATTR_PARAM_STRUCT, ATTR_SOAP_ENV, + GET_RPC_ATTR, SOAP_MAX }; @@ -143,6 +152,7 @@ struct xml_data_struct { char **current_time; char **product_class; char **xsi_type; + char **soap_enc_array_type; int *file_size; int *notification; int *scheddown_max_retries; @@ -167,6 +177,8 @@ struct xml_data_struct { int *counter; struct xml_tag_validation *validations; int nbre_validations; + int rpc_enum; + bool inc_counter; }; struct xml_list_data { @@ -251,9 +263,12 @@ void event_container_list_to_xml_data_list(struct list_head *event_container, st void cwmp_param_fault_list_to_xml_data_list(struct list_head *param_fault_list, struct list_head *xml_data_list); void cwmp_free_all_xml_data_list(struct list_head *list); int load_upload_filetype(mxml_node_t *b, struct xml_data_struct *xml_attrs); +int load_get_rpc_method_acs_resp_string(mxml_node_t *b, struct xml_data_struct *xml_attrs); int load_download_filetype(mxml_node_t *b, struct xml_data_struct *xml_attrs); int load_sched_download_window_mode(mxml_node_t *b, struct xml_data_struct *xml_attrs); int load_change_du_state_operation(mxml_node_t *b, struct xml_data_struct *xml_attrs); int build_inform_events(mxml_node_t *b, struct xml_data_struct *xml_attrs); int build_inform_env_header(mxml_node_t *b, struct xml_data_struct *xml_attrs); +int build_parameter_structure(mxml_node_t *param_list, struct xml_data_struct *xml_attrs); +int get_soap_enc_array_type(mxml_node_t *node, struct xml_data_struct *xml_attrs); #endif