| #include "soap.h" | |
| #include "rpc.h" | |
| #include "tr069.h" | |
| extern struct tr069_obj root_obj[]; | |
| char * tr069_string_prefix = NULL; | |
| int is_partial_path(const char * string) | |
| { | |
| return (string[(strlen(string) - 1)] == '.'); | |
| } | |
| // ----- SOAP RPC Relation ----- | |
| static int envelope_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(value); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method ** pp_method = (struct tr069_rpc_method **)userdata; | |
| // Malloc new rpc method | |
| *pp_method = (struct tr069_rpc_method *)tr069_malloc(sizeof(struct tr069_rpc_method)); | |
| if (*pp_method == NULL) { | |
| TR069_ERR("Failed @%s:%d, cannot malloc memory!", __func__, __LINE__); | |
| return 0; | |
| } | |
| memset(*pp_method, 0, sizeof(struct tr069_rpc_method)); | |
| return 0; | |
| } | |
| static int id_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| if (p_method == NULL) { | |
| TR069_ERR("Failed @%s:%d, why rpc method is null?", __func__, __LINE__); | |
| return 0; | |
| } | |
| if (type == SOAP_NODE_TYPE_VALUE) { | |
| p_method->id = tr069_strdup(value); | |
| TR069_ERR("Get response with ID %s", value); | |
| } | |
| return 0; | |
| } | |
| static int fault_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("fault...type(%d),value(%s)", type, value); | |
| if (p_method == NULL) { | |
| TR069_ERR("Fault failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_FAULT; | |
| return 0; | |
| } | |
| static int inform_response_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(value); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: InformResponse"); | |
| if (p_method == NULL) { | |
| TR069_ERR("InformResponse failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_INFORM_RESPONSE; | |
| return 0; | |
| } | |
| static int get_rpc_method_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(value); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: GetRPCMethods"); | |
| if (p_method == NULL) { | |
| TR069_ERR("GetRPCMethods failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_GET_RPC_METHOD; | |
| return 0; | |
| } | |
| static int get_param_names_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(value); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: GetParameterNames"); | |
| if (p_method == NULL) { | |
| TR069_ERR("GetParameterNames failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_GET_PARAMETER_NAME; | |
| return 0; | |
| } | |
| static int parameter_path_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method description: ParameterPath"); | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) p_method->body.get_param_name.parameter_path = tr069_strdup(value); | |
| return 0; | |
| } | |
| static int next_level_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method description: NextLevel"); | |
| if (p_method == NULL) { | |
| TR069_ERR("NextLevel failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) p_method->body.get_param_name.next_level = tr069_strdup(value); | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table get_param_names_desc[] = { | |
| {NULL, "ParameterPath", parameter_path_func, NULL}, | |
| {NULL, "NextLevel", next_level_func, NULL}, | |
| {NULL} | |
| }; | |
| static int parameter_value_value_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method description: ParameterNames-string"); | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| struct method_get_param_value * p = tr069_malloc(sizeof(struct method_get_param_value)); | |
| if (p == NULL) { | |
| TR069_ERR("Malloc failed, @parameter_value_func:%d", __LINE__); | |
| return -1; | |
| } | |
| TR069_DEBUG(" ParameterNames-string: %s", value); | |
| p->string = tr069_strdup(value); | |
| p->next = p_method->body.get_param_value; | |
| p_method->body.get_param_value = p; | |
| } | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table get_param_value_desc1[] = { | |
| {NULL, "string", parameter_value_value_func, NULL}, | |
| {NULL} | |
| }; | |
| static struct soap_rpc_node_table get_param_value_desc[] = { | |
| {NULL, "ParameterNames", NULL, get_param_value_desc1}, | |
| {NULL} | |
| }; | |
| static int get_param_value_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: GetParameterValues"); | |
| if (p_method == NULL) { | |
| TR069_ERR("GetParameterNames failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_GET_PARAMETER_VALUE; | |
| return 0; | |
| } | |
| static int get_param_attr_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: GetParameterAttributes"); | |
| if (p_method == NULL) { | |
| TR069_ERR("GetParameterAttributes failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_GET_PARAMETER_ATTR; | |
| return 0; | |
| } | |
| static int parameter_attr_value_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method description: ParameterNames-string"); | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| struct method_get_attribute_value * p = tr069_malloc(sizeof(struct method_get_attribute_value)); | |
| if (p == NULL) { | |
| TR069_ERR("Malloc failed, @parameter_value_func:%d", __LINE__); | |
| return -1; | |
| } | |
| p->string = tr069_strdup(value); | |
| p->next = p_method->body.get_param_attr; | |
| p_method->body.get_param_attr = p; | |
| } | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table get_param_attr_desc1[] = { | |
| {NULL, "string", parameter_attr_value_func, NULL}, | |
| {NULL} | |
| }; | |
| static struct soap_rpc_node_table get_param_attr_desc[] = { | |
| {NULL, "ParameterNames", NULL, get_param_attr_desc1}, | |
| {NULL} | |
| }; | |
| static int set_attr_name_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method description: SetattributeValue-Name"); | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| struct method_set_attribute_value * p = p_method->body.set_param_attr; | |
| if (p == NULL) { | |
| TR069_ERR("Failed, @Not process struct??? %d", __LINE__); | |
| return -1; | |
| } | |
| p->name = tr069_strdup(value); | |
| } | |
| return 0; | |
| } | |
| static int set_attr_nc_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method description: NotificationChange"); | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| struct method_set_attribute_value * p = p_method->body.set_param_attr; | |
| if (p == NULL) { | |
| TR069_ERR("Failed, @Not process struct??? %d", __LINE__); | |
| return -1; | |
| } | |
| p->notification_change = atoi(value); | |
| } | |
| return 0; | |
| } | |
| static int set_attr_n_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method description: NotificationChange"); | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| struct method_set_attribute_value * p = p_method->body.set_param_attr; | |
| if (p == NULL) { | |
| TR069_ERR("Failed, @Not process struct??? %d", __LINE__); | |
| return -1; | |
| } | |
| p->notification = atoi(value); | |
| } | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table set_param_attr_struct_desc[] = { | |
| {NULL, "Name", set_attr_name_func, NULL}, | |
| {NULL, "NotificationChange", set_attr_nc_func, NULL}, | |
| {NULL, "Notification", set_attr_n_func, NULL}, | |
| {NULL, "AccessListChange", NULL, NULL}, | |
| {NULL, "AccessList", NULL, NULL}, | |
| {NULL} | |
| }; | |
| static int set_attr_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method description: SetParameterAttributesStruct"); | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (1) { // In this case, not have value, so we need always malloc buffer | |
| struct method_set_attribute_value * p = tr069_malloc(sizeof(struct method_set_attribute_value)); | |
| if (p == NULL) { | |
| TR069_ERR("Malloc failed, @parameter_value_func:%d", __LINE__); | |
| return -1; | |
| } | |
| memset(p, 0, sizeof(struct method_set_attribute_value)); | |
| p->next = p_method->body.set_param_attr; | |
| p_method->body.set_param_attr = p; | |
| } | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table set_param_attr_desc[] = { | |
| {NULL, "SetParameterAttributesStruct", set_attr_func, set_param_attr_struct_desc}, | |
| {NULL} | |
| }; | |
| static struct soap_rpc_node_table set_param_attr_list_desc[] = { | |
| {NULL, "ParameterList", NULL, set_param_attr_desc}, | |
| {NULL} | |
| }; | |
| static int set_param_attr_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: SetParameterAttributes"); | |
| if (p_method == NULL) { | |
| TR069_ERR("SetParameterAttributes failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_SET_PARAMETER_ATTR; | |
| return 0; | |
| } | |
| static int set_param_value_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: SetParameterValues"); | |
| if (p_method == NULL) { | |
| TR069_ERR("GetParameterNames failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_SET_PARAMETER_VALUE; | |
| return 0; | |
| } | |
| static int set_param_value_value_name_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| struct method_set_param_value_value * p = p_method->body.set_param_value.value; | |
| if (p == NULL) { | |
| TR069_ERR("Failed, @parameter_value_func:%d", __LINE__); | |
| return -1; | |
| } | |
| // Add assert here | |
| p->name = tr069_strdup(value); | |
| } | |
| return 0; | |
| } | |
| static int set_param_value_value_value_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| struct method_set_param_value_value * p = p_method->body.set_param_value.value; | |
| if (p == NULL) { | |
| TR069_ERR("Failed, @parameter_value_func:%d", __LINE__); | |
| return -1; | |
| } | |
| // Add assert here | |
| p->value = tr069_strdup(value); | |
| p->type = data_type; | |
| } | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table set_param_value_desc2[] = { | |
| {NULL, "Name", set_param_value_value_name_func, NULL}, | |
| {NULL, "Value", set_param_value_value_value_func, NULL}, | |
| {NULL} | |
| }; | |
| static int set_param_value_value_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| struct method_set_param_value_value * p = tr069_malloc(sizeof(struct method_set_param_value_value)); | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (p == NULL) { | |
| TR069_ERR("Malloc failed, @%s:%d", __func__, __LINE__); | |
| return -1; | |
| } | |
| p->name = p->value = NULL; | |
| p->type = TR069_UNKOWN; | |
| p->next = p_method->body.set_param_value.value; | |
| p_method->body.set_param_value.value = p; | |
| return 0; | |
| } | |
| static int set_param_value_param_key_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| if (p_method == NULL) { | |
| TR069_ERR("ParameterPath failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| TR069_ERR("%s: %s", __func__, value); | |
| p_method->body.set_param_value.parameter_key = tr069_strdup(value); | |
| } | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table set_param_value_desc1[] = { | |
| {NULL, "ParameterValueStruct", set_param_value_value_func, set_param_value_desc2}, | |
| {NULL} | |
| }; | |
| static struct soap_rpc_node_table set_param_value_desc[] = { | |
| {NULL, "ParameterList", NULL, set_param_value_desc1}, | |
| {NULL, "ParameterKey", set_param_value_param_key_func, NULL}, | |
| {NULL} | |
| }; | |
| static int reboot_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: Reboot"); | |
| if (p_method == NULL) { | |
| TR069_ERR("Reboot failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_REBOOT; | |
| return 0; | |
| } | |
| static int reboot_command_key_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method reboot key: %s", value); | |
| if (p_method == NULL) { | |
| TR069_ERR("Reboot failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (value) { | |
| p_method->body.reboot.command_key = tr069_strdup(value); | |
| } | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table reboot_desc[] = { | |
| {NULL, "CommandKey", reboot_command_key_func, NULL}, | |
| {NULL} | |
| }; | |
| static int factory_reset_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: FactoryReset"); | |
| if (p_method == NULL) { | |
| TR069_ERR("FactoryReset failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_FACTORY_RESET; | |
| return 0; | |
| } | |
| static int transfer_complete_response_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: TransferCompleteResponse"); | |
| if (p_method == NULL) { | |
| TR069_ERR("TransferCompleteResponse failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_TRANSFER_COMPLETE_RESPONSE; | |
| return 0; | |
| } | |
| static int download_string_dup_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| char ** p = NULL; | |
| TR069_DEBUG("Get RPC method %s with value %s", tag, value); | |
| if (p_method == NULL) { | |
| TR069_ERR("Download failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (!strcmp(tag, "CommandKey")) { | |
| p = &p_method->body.download.command_key; | |
| } else if (!strcmp(tag, "FileType")) { | |
| p = &p_method->body.download.file_type; | |
| } else if (!strcmp(tag, "URL")) { | |
| p = &p_method->body.download.url; | |
| } else if (!strcmp(tag, "Username")) { | |
| p = &p_method->body.download.username; | |
| } else if (!strcmp(tag, "Password")) { | |
| p = &p_method->body.download.password; | |
| } else if (!strcmp(tag, "TargetFileName")) { | |
| p = &p_method->body.download.target_file_name; | |
| } else if (!strcmp(tag, "SuccessURL")) { | |
| p = &p_method->body.download.success_url; | |
| } else if (!strcmp(tag, "FailureURL")) { | |
| p = &p_method->body.download.failure_url; | |
| } | |
| if (value && p) { | |
| *p = tr069_strdup(value); | |
| } | |
| return 0; | |
| } | |
| void free_download_method(struct tr069_rpc_method * method) | |
| { | |
| if (method->body.download.command_key) tr069_free(method->body.download.command_key); | |
| if (method->body.download.file_type) tr069_free(method->body.download.file_type); | |
| if (method->body.download.url) tr069_free(method->body.download.url); | |
| if (method->body.download.username) tr069_free(method->body.download.username); | |
| if (method->body.download.password) tr069_free(method->body.download.password); | |
| if (method->body.download.target_file_name) tr069_free(method->body.download.target_file_name); | |
| if (method->body.download.success_url) tr069_free(method->body.download.success_url); | |
| if (method->body.download.failure_url) tr069_free(method->body.download.failure_url); | |
| if (method->body.download.start_time) tr069_free(method->body.download.start_time); | |
| if (method->body.download.complete_time) tr069_free(method->body.download.complete_time); | |
| } | |
| static int download_delay_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method %s delay with value %s", tag, value); | |
| p_method->body.download.delay_seconds = atoi(value); | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table download_desc[] = { | |
| {NULL, "CommandKey", download_string_dup_func, NULL}, | |
| {NULL, "FileType", download_string_dup_func, NULL}, | |
| {NULL, "URL", download_string_dup_func, NULL}, | |
| {NULL, "Username", download_string_dup_func, NULL}, | |
| {NULL, "Password", download_string_dup_func, NULL}, | |
| {NULL, "FileSize", NULL, NULL}, | |
| {NULL, "TargetFileName", download_string_dup_func, NULL}, | |
| {NULL, "DelaySeconds", download_delay_func, NULL}, | |
| {NULL, "SuccessURL", download_string_dup_func, NULL}, | |
| {NULL, "FailureURL", download_string_dup_func, NULL}, | |
| {NULL} | |
| }; | |
| static int download_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: Download"); | |
| if (p_method == NULL) { | |
| TR069_ERR("Download failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_DOWNLOAD; | |
| return 0; | |
| } | |
| static int add_delete_obj_string_dup_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| char ** pp = NULL; | |
| TR069_DEBUG("Get RPC method %s with value %s", tag, value); | |
| if (p_method == NULL) { | |
| TR069_ERR("Add object failed, because userdata is null..."); | |
| return -1; | |
| } | |
| if (!strcmp(tag, "ParameterKey")) { | |
| pp = &p_method->body.add_delete.parameter_key; | |
| } else if (!strcmp(tag, "ObjectName")) { | |
| pp = &p_method->body.add_delete.object_name; | |
| } | |
| if (value && pp) { | |
| *pp = tr069_strdup(value); | |
| } | |
| return -1; | |
| } | |
| static struct soap_rpc_node_table add_delete_obj_desc[] = { | |
| {NULL, "ParameterKey", add_delete_obj_string_dup_func, NULL}, | |
| {NULL, "ObjectName", add_delete_obj_string_dup_func, NULL}, | |
| {NULL} | |
| }; | |
| static int add_obj_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: Add object"); | |
| if (p_method == NULL) { | |
| TR069_ERR("Add object failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_ADD; | |
| return 0; | |
| } | |
| static int delete_obj_func(void * userdata, const char * tag, int type, const char * value, int data_type) | |
| { | |
| UNUSED(tag); | |
| UNUSED(value); | |
| UNUSED(type); | |
| UNUSED(data_type); | |
| struct tr069_rpc_method * p_method = *(struct tr069_rpc_method **)userdata; | |
| TR069_DEBUG("Get RPC method: Delete object"); | |
| if (p_method == NULL) { | |
| TR069_ERR("Delete object failed, because userdata is null..."); | |
| return -1; | |
| } | |
| p_method->type = RPC_TYPE_DELETE; | |
| return 0; | |
| } | |
| static struct soap_rpc_node_table body[] = { | |
| {NULL, "Fault", fault_func, NULL}, | |
| {NULL, "InformResponse", inform_response_func, NULL}, // namespace: cwmp | |
| {NULL, "GetRPCMethods", get_rpc_method_func, NULL}, | |
| {NULL, "GetParameterNames", get_param_names_func, get_param_names_desc}, | |
| {NULL, "GetParameterValues", get_param_value_func, get_param_value_desc}, | |
| {NULL, "SetParameterValues", set_param_value_func, set_param_value_desc}, | |
| {NULL, "GetParameterAttributes", get_param_attr_func, get_param_attr_desc}, | |
| {NULL, "SetParameterAttributes", set_param_attr_func, set_param_attr_list_desc}, | |
| {NULL, "Reboot", reboot_func, reboot_desc}, | |
| {NULL, "FactoryReset", factory_reset_func, NULL}, | |
| {NULL, "TransferCompleteResponse", transfer_complete_response_func, NULL}, | |
| {NULL, "GetRPCMethodsResponse", NULL, NULL}, | |
| {NULL, "AddObject", add_obj_func, add_delete_obj_desc}, | |
| {NULL, "DeleteObject", delete_obj_func, add_delete_obj_desc}, | |
| {NULL, "Download", download_func, download_desc}, | |
| {NULL} | |
| }; | |
| static struct soap_rpc_node_table header[] = { | |
| {NULL, "ID", id_func, NULL}, // namespace: cwmp | |
| {NULL, "HoldRequests", NULL, NULL}, | |
| {NULL} | |
| }; | |
| static struct soap_rpc_node_table envelope[] = { | |
| {NULL, "Header", NULL, header}, // namespace: env | |
| {NULL, "Body", NULL, body}, | |
| {NULL} | |
| }; | |
| struct soap_rpc_node_table root[] = { | |
| {NULL, "Envelope", envelope_func, envelope}, // namespace: env | |
| {NULL} | |
| }; | |
| int build_get_rpc_method_response(struct tr069_rpc_method * method, struct tr069_msg * msg) | |
| { | |
| UNUSED(method); | |
| struct soap_rpc_node_table * ptr = &body[2]; | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "cwmp:GetRPCMethodsResponse", NULL); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "MethodList", NULL); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ATTR, "arrayType", "string[!^^!]"); | |
| while (ptr->tag) { | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "string", ptr->tag); | |
| pop_soap_node(&msg->body_stack); | |
| ptr++; | |
| } | |
| pop_soap_node(&msg->body_stack); | |
| pop_soap_node(&msg->body_stack); | |
| return 0; | |
| } | |
| static const char * tr069_infor_device_id[] = { | |
| "Manufacturer", | |
| "ManufacturerOUI", | |
| "ModelName", | |
| "ProductClass", | |
| "SerialNumber", | |
| NULL | |
| }; | |
| static const char * inform_paramet_list[] ={ | |
| "Device.RootDataModelVersion", | |
| "Device.DeviceInfo.HardwareVersion", | |
| "Device.DeviceInfo.SoftwareVersion", | |
| "Device.DeviceInfo.ProvisioningCode", | |
| "Device.ManagementServer.ParameterKey", | |
| "Device.ManagementServer.ConnectionRequestURL", | |
| //"Device.ManagementServer.NATDetected", | |
| //"Device.ManagementServer.UDPConnectionRequestAddress", | |
| }; | |
| struct tr069_parameter_change_list_struct * tr069_parameter_change_list = NULL; | |
| #define TR069_EVET_FLAG_BOOTSTRAP (1 << TR069_EVENT_BOOTSTRAP) | |
| #define TR069_EVET_FLAG_BOOT (1 << TR069_EVENT_BOOT) | |
| #define TR069_EVET_FLAG_PERIODIC (1 << TR069_EVENT_PERIODIC) | |
| #define TR069_EVET_FLAG_SCHEDULED (1 << TR069_EVENT_SCHEDULED) | |
| #define TR069_EVET_FLAG_VALUE_CHANGE (1 << TR069_EVENT_VALUE_CHANGE) | |
| #define TR069_EVET_FLAG_CONNECTION_REQUEST (1 << TR069_EVENT_CONNECTION_REQUEST) | |
| #define TR069_EVET_FLAG_TRANSFER_COMPLETE (1 << TR069_EVENT_TRANSFER_COMPLETE) | |
| #define TR069_EVET_FLAG_REQUEST_DOWNLOAD (1 << TR069_EVENT_REQUEST_DOWNLOAD) | |
| #define TR069_EVET_FLAG_M_REBOOT (1 << TR069_EVENT_M_REBOOT) | |
| #define TR069_EVET_FLAG_M_SCHEDULE_INFORM (1 << TR069_EVENT_M_SCHEDULE_INFORM) | |
| #define TR069_EVET_FLAG_M_DOWNLOAD (1 << TR069_EVENT_M_DOWNLOAD) | |
| #define TR069_EVET_FLAG_M_SCHEDULE_DOWNLOAD (1 << TR069_EVENT_M_SCHEDULE_DOWNLOAD) | |
| #define TR069_EVET_FLAG_M_UPLOAD (1 << TR069_EVENT_M_UPLOAD) | |
| #define TR069_EVET_FLAG_M_CHANGE_DU_STATE (1 << TR069_EVENT_M_CHANGE_DU_STATE) | |
| static const char * event_string[TR069_EVENT_MAX] = { | |
| "0 BOOTSTRAP", | |
| "1 BOOT", | |
| "2 PERIODIC", | |
| "3 SCHEDULED", | |
| "4 VALUE CHANGE", | |
| "6 CONNECTION REQUEST", | |
| "7 TRANSFER COMPLETE", | |
| "9 REQUEST DOWNLOAD", | |
| "M Reboot", | |
| "M ScheduleInform", | |
| "M Download", | |
| "M ScheduleDownload", | |
| "M Upload", | |
| "M ChangeDUState", | |
| }; | |
| static char event_command_key[TR069_EVENT_MAX][32] = { | |
| {0} | |
| }; | |
| static unsigned int tr069_event = 0; | |
| struct cpe_struct cpe = {0}; | |
| void set_tr069_event(unsigned int event, const char * command_key) | |
| { | |
| if (event < TR069_EVENT_MAX) { | |
| tr069_event |= (1 << event); | |
| snprintf(&event_command_key[event][0], 32, "%s", command_key); | |
| } | |
| } | |
| struct tr069_msg * tr069_build_msg(const char * id) | |
| { | |
| struct tr069_msg * msg = tr069_malloc(sizeof(struct tr069_msg)); | |
| if (!msg) { | |
| TR069_ERR("Can not malloc memory for tr069_build_msg"); | |
| return NULL; | |
| } | |
| // Build Header and body msg | |
| msg->root = MrvCreateRoot(); | |
| msg->env = new_soap_node(msg->root, SOAP_NODE_TYPE_ELEMENT, "SOAP-ENV:Envelope", NULL); | |
| new_soap_node(msg->env, SOAP_NODE_TYPE_ATTR, "xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"); | |
| new_soap_node(msg->env, SOAP_NODE_TYPE_ATTR, "xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"); | |
| new_soap_node(msg->env, SOAP_NODE_TYPE_ATTR, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); | |
| new_soap_node(msg->env, SOAP_NODE_TYPE_ATTR, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); | |
| new_soap_node(msg->env, SOAP_NODE_TYPE_ATTR, "xmlns:cwmp", "urn:dslforum-org:cwmp-1-0"); | |
| msg->header_node = new_soap_node(msg->env, SOAP_NODE_TYPE_ELEMENT, "SOAP-ENV:Header", NULL); | |
| msg->body_node = new_soap_node(msg->env, SOAP_NODE_TYPE_ELEMENT, "SOAP-ENV:Body", NULL); | |
| memset(&msg->header_stack, 0, sizeof(struct soap_trace_stack)); | |
| msg->header_stack.stack[0] = msg->header_node; | |
| push_new_soap_node(&msg->header_stack, SOAP_NODE_TYPE_ELEMENT, "cwmp:ID", id); | |
| push_new_soap_node(&msg->header_stack, SOAP_NODE_TYPE_ATTR, "SOAP-ENV:mustUnderstand", "1"); | |
| memset(&msg->body_stack, 0, sizeof(struct soap_trace_stack)); | |
| msg->body_stack.stack[0] = msg->body_node; | |
| return msg; | |
| } | |
| void tr069_msg_destroy(struct tr069_msg * msg) | |
| { | |
| MrvDeleteRoot(msg->root); | |
| tr069_free(msg); | |
| } | |
| int tr069_inform_acs(struct tr069_msg * msg) | |
| { | |
| const char ** pchar; | |
| char * temp_buf; | |
| int addition_list_size = 0; | |
| temp_buf = (char *)tr069_malloc(128); | |
| if (temp_buf == NULL) { | |
| TR069_ERR("Inform to acs failed@%d!", __LINE__); | |
| return -1; | |
| } | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "cwmp:Inform", NULL); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "DeviceId", NULL); | |
| // Add device info element | |
| pchar = &tr069_infor_device_id[0]; | |
| while (*pchar) { | |
| struct tr069_param * param; | |
| sprintf(temp_buf, "%s.DeviceInfo.%s", root_obj[0].name, *pchar); | |
| param = find_param(root_obj, temp_buf); | |
| if (param) { | |
| char * string = NULL; | |
| const char * temp = *pchar; | |
| if (param->get_value) { | |
| if (!strcmp(*pchar, "ManufacturerOUI")) | |
| temp = "OUI"; | |
| param->get_value(NULL, &string); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, temp, string); | |
| pop_soap_node(&msg->body_stack); | |
| if (string) tr069_free(string); | |
| } | |
| } | |
| pchar++; | |
| } | |
| pop_soap_node(&msg->body_stack); /* End of DeviceId */ | |
| if (tr069_parameter_change_list) { | |
| struct tr069_parameter_change_list_struct * temp = tr069_parameter_change_list; | |
| set_tr069_event(TR069_EVENT_VALUE_CHANGE, ""); | |
| while (temp) { | |
| addition_list_size++; | |
| temp = temp->next; | |
| } | |
| TR069_DEBUG("Additional info list size %d", addition_list_size); | |
| } | |
| // Add event code struct | |
| if (tr069_event) { | |
| unsigned int event = tr069_event; | |
| int i = 0; | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Event", NULL); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ATTR, "SOAP-ENC:arrayType", "cwmp:EventStruct[!^^!]"); | |
| while (event && (i < TR069_EVENT_MAX)) { | |
| if (event & 0x01) { | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "EventStruct", NULL); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "EventCode", event_string[i]); | |
| pop_soap_node(&msg->body_stack); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "CommandKey", &event_command_key[i][0]); | |
| pop_soap_node(&msg->body_stack); | |
| pop_soap_node(&msg->body_stack); | |
| TR069_DEBUG("add event code: %s, command key %s", event_string[i], &event_command_key[i][0]); | |
| } | |
| event >>= 1; | |
| i++; | |
| } | |
| pop_soap_node(&msg->body_stack); /* End of Event */ | |
| } | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "MaxEnvelopes", "1"); | |
| pop_soap_node(&msg->body_stack); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "CurrentTime", "1370933262"); | |
| pop_soap_node(&msg->body_stack); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "RetryCount", "2"); | |
| pop_soap_node(&msg->body_stack); | |
| //if (inform_paramet_list) { | |
| if (1) { | |
| int size = sizeof(inform_paramet_list) / sizeof(char *); | |
| int i; | |
| struct tr069_param * param; | |
| char buf[sizeof("cwmp:ParameterValueStruct[%d]") + 5]; | |
| sprintf(buf, "cwmp:ParameterValueStruct[%d]", size + addition_list_size); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "ParameterList", NULL); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ATTR, "SOAP-ENC:arrayType", buf); | |
| for (i = 0; i < size; i++) { | |
| char * string = NULL; | |
| param = find_param(root_obj, inform_paramet_list[i]); | |
| if (!param) { | |
| TR069_ERR("Failed, when try find object paramet(%s)!", inform_paramet_list[i]); | |
| continue; | |
| } | |
| if (!param->get_value) { | |
| TR069_ERR("Why parameter not have value?"); | |
| continue; | |
| } | |
| param->get_value(NULL, &string); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "ParameterValueStruct", NULL); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Name", inform_paramet_list[i]); | |
| pop_soap_node(&msg->body_stack); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Value", string); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ATTR, "xsi:stype", rpc_type2string(param->type)); | |
| pop_soap_node(&msg->body_stack); | |
| pop_soap_node(&msg->body_stack); | |
| if (string) tr069_free(string); | |
| } | |
| } | |
| while (tr069_parameter_change_list) { | |
| struct tr069_parameter_change_list_struct * temp = tr069_parameter_change_list; | |
| do { | |
| char * string = NULL; | |
| struct tr069_param * param; | |
| param = find_param(root_obj, temp->parameter_name); | |
| if (!param) { | |
| TR069_ERR("Failed, when try find object paramet(%s)!", temp->parameter_name); | |
| break; // Failed, goto free and process next parameter | |
| } | |
| if (param->notification == TR069_NOTIFICATION_OFF) { | |
| break; // This parameter not need update to ACS | |
| } | |
| if (!param->get_value) { | |
| TR069_ERR("Why parameter not have value?"); | |
| break; // Failed, goto free and process next parameter | |
| } | |
| param->get_value(top_instance(), &string); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "ParameterValueStruct", NULL); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Name", temp->parameter_name); | |
| pop_soap_node(&msg->body_stack); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Value", string); | |
| push_new_soap_node(&msg->body_stack, SOAP_NODE_TYPE_ATTR, "xsi:stype", rpc_type2string(param->type)); | |
| pop_soap_node(&msg->body_stack); | |
| pop_soap_node(&msg->body_stack); | |
| if (string) tr069_free(string); | |
| } while (0); | |
| tr069_parameter_change_list = temp->next; | |
| tr069_free(temp); | |
| temp = NULL; | |
| } | |
| pop_soap_node(&msg->body_stack); | |
| //done: | |
| // Clear event | |
| tr069_event = 0; | |
| if (temp_buf) { | |
| tr069_free(temp_buf); | |
| temp_buf = NULL; | |
| } | |
| return 0; | |
| } | |
| int parameter_attr_dup(struct tr069_obj * obj, struct tr069_param * param, | |
| struct tr069_instance * instance, struct walk_context * context, int type) | |
| { | |
| UNUSED(obj); | |
| UNUSED(instance); | |
| struct tr069_msg * tr069_msg = context->userdata; | |
| int i, end, pos; | |
| if (type != TR069_TYPE_PARAMETER) return 0; | |
| if (!param) return 0; | |
| pos = 0; | |
| end = context->index == 0 ? 0 : context->index - 1; | |
| if (tr069_string_prefix) { | |
| i = 1; | |
| pos += sprintf(&context->tempbuf[pos], "%s", tr069_string_prefix); | |
| } else { | |
| i = 0; | |
| } | |
| for (; i <= end; i++) { | |
| pos += sprintf(&context->tempbuf[pos], "%s.", context->stack[i]); | |
| } | |
| if (end != context->index) { | |
| pos += sprintf(&context->tempbuf[pos], "%s%s", context->stack[context->index], | |
| type == TR069_TYPE_OBJECT ? "." : ""); | |
| } | |
| if (pos >= 256) TR069_ERR("Failed! %s:%d", __func__, __LINE__); | |
| if (context->index >= 30) TR069_ERR("Failed! %s:%d", __func__, __LINE__); | |
| TR069_DEBUG("parameter attribute dup: %s", context->tempbuf); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "ParameterAttributeStruct", NULL); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Name", context->tempbuf); | |
| pop_soap_node(&tr069_msg->body_stack); | |
| sprintf(context->tempbuf, "%d", param->notification); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Notification", context->tempbuf); | |
| pop_soap_node(&tr069_msg->body_stack); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "AccessList", NULL); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ATTR, "SOAP-ENC:arrayType", rpc_type2string(param->type)); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "string", "Subscriber"); | |
| pop_soap_node(&tr069_msg->body_stack); | |
| pop_soap_node(&tr069_msg->body_stack); | |
| pop_soap_node(&tr069_msg->body_stack); /* End of ParameterAttributeStruct */ | |
| return 0; | |
| } | |
| int parameter_value_dup(struct tr069_obj * obj, struct tr069_param * param, | |
| struct tr069_instance * instance, struct walk_context * context, int type) | |
| { | |
| UNUSED(obj); | |
| struct tr069_msg * tr069_msg = context->userdata; | |
| int i, end, pos, ret; | |
| char * value = NULL; | |
| if (type != TR069_TYPE_PARAMETER) return 0; | |
| if (!param || !param->get_value) return 0; | |
| ret = param->get_value(instance, &value); | |
| if (ret) { | |
| TR069_ERR("Get value failed: %s", param->name); | |
| } | |
| pos = 0; | |
| end = context->index == 0 ? 0 : context->index - 1; | |
| if (tr069_string_prefix) { | |
| i = 1; | |
| pos += sprintf(&context->tempbuf[pos], "%s", tr069_string_prefix); | |
| } else { | |
| i = 0; | |
| } | |
| for (; i <= end; i++) { | |
| pos += sprintf(&context->tempbuf[pos], "%s.", context->stack[i]); | |
| } | |
| if (end != context->index) { | |
| pos += sprintf(&context->tempbuf[pos], "%s%s", context->stack[context->index], | |
| type == TR069_TYPE_OBJECT ? "." : ""); | |
| } | |
| if (pos >= 256) TR069_ERR("Failed! %s:%d", __func__, __LINE__); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "ParameterValueStruct", NULL); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Name", context->tempbuf); | |
| pop_soap_node(&tr069_msg->body_stack); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Value", value); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ATTR, "xsi:type", rpc_type2string(param->type)); | |
| pop_soap_node(&tr069_msg->body_stack); | |
| pop_soap_node(&tr069_msg->body_stack); /* End of ParameterInfoStruct */ | |
| if (value) tr069_free(value); | |
| return 0; | |
| } | |
| int parameter_name_dup(struct tr069_obj * obj, struct tr069_param * param, | |
| struct tr069_instance * instance, struct walk_context * context, int type) | |
| { | |
| UNUSED(obj); | |
| UNUSED(instance); | |
| struct tr069_msg * tr069_msg = context->userdata; | |
| int i, end, pos; | |
| if (type != TR069_TYPE_PARAMETER) return 0; | |
| pos = 0; | |
| end = context->index == 0 ? 0 : context->index - 1; | |
| if (tr069_string_prefix) { | |
| i = 1; | |
| pos += sprintf(&context->tempbuf[pos], "%s", tr069_string_prefix); | |
| } else { | |
| i = 0; | |
| } | |
| for (; i <= end; i++) { | |
| pos += sprintf(&context->tempbuf[pos], "%s.", context->stack[i]); | |
| } | |
| if (end != context->index) { | |
| pos += sprintf(&context->tempbuf[pos], "%s%s", context->stack[context->index], | |
| type == TR069_TYPE_OBJECT ? "." : ""); | |
| } | |
| if (pos >= 256) TR069_ERR("Failed! %s:%d", __func__, __LINE__); | |
| TR069_DEBUG("Parameter dup: %s", context->tempbuf); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "ParameterInfoStruct", NULL); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Name", context->tempbuf); | |
| pop_soap_node(&tr069_msg->body_stack); | |
| push_new_soap_node(&tr069_msg->body_stack, SOAP_NODE_TYPE_ELEMENT, "Writable", param->rw == TR069_R ? "0" : "1"); | |
| pop_soap_node(&tr069_msg->body_stack); | |
| pop_soap_node(&tr069_msg->body_stack); /* End of ParameterInfoStruct */ | |
| return 0; | |
| } | |
| const char * fault2string(int fault) | |
| { | |
| switch (fault) { | |
| case 9003: return "Invalid Argments"; | |
| case 9005: return "Invalid Parameter Name"; | |
| case 9006: return "Invalid Parameter Type"; | |
| case 9007: return "Invalid Parameter Value"; | |
| case 9008: return "Attempt to set a non-writable parameter"; | |
| case 9015: return "File transfer failure: unable to contact file server"; | |
| case 9017: return "File transfer failure: unable to complete download"; | |
| case 9018: return "File transfer failure: file corrupted"; | |
| case 9012: return "File transfer server authentication failure"; | |
| case 9020: return "File transfer failure: unable to complete download with specified time windows"; | |
| case 9021: return "Cancelation of file transfer not permitted in current transfer state"; | |
| default: | |
| return "Unknown"; | |
| } | |
| } | |