SOAP_FMAC3 int SOAP_FMAC4 soap_ignore_element(struct soap *soap) { if (!soap_peek_element(soap)) { int t; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unexpected element '%s' in input (level=%u, %d)\n", soap->tag, soap->level, soap->body)); if (soap->mustUnderstand && !soap->other) return soap->error = SOAP_MUSTUNDERSTAND; if (((soap->mode & SOAP_XML_STRICT) && soap->part != SOAP_IN_HEADER) || !soap_match_tag(soap, soap->tag, "SOAP-ENV:")) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "REJECTING element '%s'\n", soap->tag)); return soap->error = SOAP_TAG_MISMATCH; } if (!*soap->id || !soap_getelement(soap, &t)) { soap->peeked = 0; if (soap->fignore) soap->error = soap->fignore(soap, soap->tag); else soap->error = SOAP_OK; DBGLOG(TEST, if (!soap->error) SOAP_MESSAGE(fdebug, "IGNORING element '%s'\n", soap->tag)); if (!soap->error && soap->body) { soap->level++; while (!soap_ignore_element(soap)) ; if (soap->error == SOAP_NO_TAG) soap->error = soap_element_end_in(soap, NULL); } }
SOAP_FMAC3 int SOAP_FMAC4 soap_getindependent(struct soap *soap) { int t; for (;;) if (!soap_getelement(soap, &t)) if (soap->error || soap_ignore_element(soap)) break; if (soap->error == SOAP_NO_TAG || soap->error == SOAP_EOF) soap->error = SOAP_OK; return soap->error; }
SOAP_FMAC2 soap_in_xsd__anyType(struct soap *soap, const char *tag, struct soap_dom_element *node, const char *type) { register struct soap_attribute *tp; register struct soap_dom_attribute **att; if (soap_peek_element(soap)) { if (soap->error != SOAP_NO_TAG) return NULL; if (!node) { if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)))) { soap->error = SOAP_EOM; return NULL; } } soap_default_xsd__anyType(soap, node); if (!(node->data = soap_string_in(soap, 1, -1, -1)) || !*node->data) return NULL; soap->error = SOAP_OK; return node; } if (!node) { if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)))) { soap->error = SOAP_EOM; return NULL; } } soap_default_xsd__anyType(soap, node); node->nstr = soap_current_namespace(soap, soap->tag); if ((soap->mode & SOAP_DOM_ASIS)) node->name = soap_strdup(soap, soap->tag); else { char *s = strchr(soap->tag, ':'); if (s) node->name = soap_strdup(soap, s+1); else node->name = soap_strdup(soap, soap->tag); } DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' parsed in namespace '%s'\n", node->name, node->nstr?node->nstr:"")); if ((soap->mode & SOAP_DOM_NODE) || (!(soap->mode & SOAP_DOM_TREE) && *soap->id)) { if ((node->node = soap_getelement(soap, &node->type))) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node contains type %d from xsi:type\n", node->type)); return node; } if (soap->error == SOAP_TAG_MISMATCH) soap->error = SOAP_OK; else return NULL; } att = &node->atts; for (tp = soap->attributes; tp; tp = tp->next) { if (tp->visible) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node attribute='%s' parsed\n", tp->name)); *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); if (!*att) { soap->error = SOAP_EOM; return NULL; } (*att)->next = NULL; (*att)->nstr = soap_current_namespace(soap, tp->name); if ((soap->mode & SOAP_DOM_ASIS) || !strncmp(tp->name, "xml", 3)) (*att)->name = soap_strdup(soap, tp->name); else { char *s = strchr(tp->name, ':'); if (s) (*att)->name = soap_strdup(soap, s+1); else (*att)->name = soap_strdup(soap, tp->name); } if (tp->visible == 2) (*att)->data = soap_strdup(soap, tp->value); else (*att)->data = NULL; (*att)->wide = NULL; (*att)->soap = soap; att = &(*att)->next; tp->visible = 0; } } soap_element_begin_in(soap, NULL, 1, NULL); DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' pulled\n", node->name)); if (soap->body) { if (!soap_peek_element(soap)) { struct soap_dom_element **elt; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has subelements\n", node->name)); elt = &node->elts; for (;;) { if (!(*elt = soap_in_xsd__anyType(soap, NULL, NULL, NULL))) { if (soap->error != SOAP_NO_TAG) return NULL; soap->error = SOAP_OK; break; } (*elt)->prnt = node; elt = &(*elt)->next; } } else if (soap->error == SOAP_NO_TAG) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has cdata\n", node->name)); if ((soap->mode & SOAP_C_UTFSTRING) || (soap->mode & SOAP_C_MBSTRING)) { if (!(node->data = soap_string_in(soap, 1, -1, -1))) return NULL; } else if (!(node->wide = soap_wstring_in(soap, 1, -1, -1))) return NULL; } else return NULL; if (soap_element_end_in(soap, node->name)) return NULL; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", node->name)); } return node; }
int soap_parser_decode(void *handle, const char *xml) { SoapParser *parser = (SoapParser *)handle; struct soap *soap; int fd[2]; if (parser == NULL) { return -1; } if (xml == NULL) { LOGE(LOG_TAG, "input xml is empty"); return -1; } soap = parser->soap; pipe(fd); /*soap_init(soap);*/ soap_init1(soap, SOAP_XML_IGNORENS); soap_set_namespaces(soap, namespaces); soap->socket = -1; soap->recvfd = fd[0]; write(fd[1], xml, strlen(xml)); close(fd[1]); if (soap_begin_recv(soap) != 0 || soap_envelope_begin_in(soap) != 0) { LOGE(LOG_TAG, "begin decode failed, error=%d", soap->error); return -1; } if (soap_recv_header(soap) != 0) { LOGE(LOG_TAG, "decode soap header failed, %d", soap->error); return -1; } _soap_header_parse(soap->header, &(parser->id), &(parser->hold_requests), &(parser->session_timeout), &(parser->supported_cwmp_versions), &(parser->use_cwmp_version)); if (soap_body_begin_in(soap) != 0) { LOGE(LOG_TAG, "decode soap body failed, %d", soap->error); return -1; } parser->_namespaces = _soap_namespaces_parse(soap); parser->namespaces = parser->_namespaces; parser->version = _soap_version_parse(xml, parser->namespaces); if (parser->version == CWMP_VERSION_1_2) { if (parser->supported_cwmp_versions != 0 && parser->use_cwmp_version != 0) { parser->version = CWMP_VERSION_1_4; } else if (parser->session_timeout > 0) { parser->version = CWMP_VERSION_1_3; } } if (soap_recv_fault(soap, 1) != 0) { parser->type = CWMP_MSG_FAULT; _soap_fault_dump(soap->fault); if (soap->fault != NULL && soap->fault->detail != NULL && soap->fault->detail->__type == SOAP_TYPE__cwmp__Fault) { struct _cwmp__Fault *cwmp_fault; cwmp_fault = (struct _cwmp__Fault *)soap->fault->detail->fault; if (cwmp_fault != NULL) { if (cwmp_fault->FaultCode != NULL) { parser->fault_code = atoi(cwmp_fault->FaultCode); } parser->fault_string = cwmp_fault->FaultString; parser->fault_body = cwmp_fault; parser->body = cwmp_fault; } } return 0; } int gsoap_type; parser->body = soap_getelement(soap, &gsoap_type); parser->type = _get_cwmp_type(gsoap_type); if (soap->error) { LOGE(LOG_TAG, "get cwmp body failed, error=%d", soap->error); return -1; } if (soap_body_end_in(soap) || soap_envelope_end_in(soap) || soap_end_recv(soap)) { LOGE(LOG_TAG, "end decode failed, %d", soap->error); return -1; } close(fd[0]); return 0; }
/** * xml -> body * @param[in] handle: parser * @param[in] xml: the xml to be decoded * @param[out] id: cpe's id? I don't know * @param[out] hold_request: hold * @param[out] type: SOAP/RPC type * @param[out] body: the result get from xml */ int soap_parser_decode(void *handle, const char *xml, int *id, int *hold_requests, int *type, void **body) { struct soap_parser *parser = (struct soap_parser *)handle; struct soap *soap = parser->soap; int fd[2]; if (xml == NULL) { return -1; } /*LOGD(parser->tag, xml);*/ pipe(fd); *id = 0; *hold_requests = 0; *type = 0; *body = NULL; soap_init(soap); soap->socket = -1; soap->recvfd = fd[0]; write(fd[1], xml, strlen(xml)); close(fd[1]); if (soap_begin_recv(soap) || soap_envelope_begin_in(soap) || soap_recv_header(soap) || soap_body_begin_in(soap)) { return -1; } if (soap->header != NULL) { if (soap->header->__HoldRequests != NULL) { *hold_requests = soap->header->__HoldRequests->__item; } if (soap->header->__ID != NULL) { if (soap->header->__ID->__item != NULL) { *id = atoi(soap->header->__ID->__item); } } } if (soap_recv_fault(soap, 1)) { LOGE(parser->tag, "FaultCode=%s, FaultString=%s", soap->fault->faultcode, soap->fault->faultstring); *type = SOAP_TYPE__ns1__Fault; if (soap->fault != NULL && soap->fault->detail != NULL) { *body = soap->fault->detail->__any; } return 0; } *body = soap_getelement(soap, type); if (soap->error) { return -1; } if (soap_body_end_in(soap) || soap_envelope_end_in(soap) || soap_end_recv(soap)) { return -1; } ////soap_end(soap); //soap_free(soap); close(fd[0]); if (soap->header != NULL) { if (soap->header->__ID != NULL) { LOGV(parser->tag, "soap header: ID=%s(%s)", soap->header->__ID->__item, soap->header->__ID->SOAP_ENV__mustUnderstand); } if (soap->header->__HoldRequests != NULL) { LOGV(parser->tag, "soap header: HoldRequests=%s(%s)", soap->header->__HoldRequests->__item, soap->header->__HoldRequests->SOAP_ENV__mustUnderstand); } } return 0; }
SOAP_FMAC2 soap_in_xsd__anyType(struct soap *soap, const char *tag, struct soap_dom_element *node, const char *type) { register struct soap_attribute *tp; register struct soap_dom_attribute **att; register struct soap_nlist *np; register char *s; if (soap_peek_element(soap)) return NULL; if (!node) if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)))) { soap->error = SOAP_EOM; return NULL; } node->next = NULL; node->prnt = NULL; node->elts = NULL; node->atts = NULL; node->nstr = NULL; node->name = NULL; node->data = NULL; node->wide = NULL; node->node = NULL; node->type = 0; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node %s\n", soap->tag)); np = soap->nlist; if (!(s = strchr(soap->tag, ':'))) { while (np && *np->id) /* find default namespace, if present */ np = np->next; s = soap->tag; } else { while (np && (strncmp(np->id, soap->tag, s - soap->tag) || np->id[s - soap->tag])) np = np->next; s++; if (!np) { soap->error = SOAP_NAMESPACE; return NULL; } } if (np) { if (np->index >= 0) node->nstr = soap->namespaces[np->index].ns; else if (np->ns) node->nstr = soap_strdup(soap, np->ns); DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node namespace='%s'\n", node->nstr?node->nstr:"")); } node->name = soap_strdup(soap, soap->tag); if ((soap->mode & SOAP_DOM_NODE) || (!(soap->mode & SOAP_DOM_TREE) && *soap->id)) { if ((node->node = soap_getelement(soap, &node->type))) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node contains type %d from xsi:type\n", node->type)); return node; } if (soap->error == SOAP_TAG_MISMATCH) soap->error = SOAP_OK; else return NULL; } att = &node->atts; for (tp = soap->attributes; tp; tp = tp->next) if (tp->visible) { np = soap->nlist; if (!(s = strchr(tp->name, ':'))) { while (np && *np->id) /* find default namespace, if present */ np = np->next; s = tp->name; } else { while (np && (strncmp(np->id, tp->name, s - tp->name) || np->id[s - tp->name])) np = np->next; s++; if (!np) { soap->error = SOAP_NAMESPACE; return NULL; } } DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node attribute='%s'\n", tp->name)); *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); if (!*att) { soap->error = SOAP_EOM; return NULL; } (*att)->next = NULL; (*att)->nstr = NULL; if (np) { if (np->index >= 0) (*att)->nstr = soap->namespaces[np->index].ns; else if (np->ns) (*att)->nstr = soap_strdup(soap, np->ns); DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM attribute namespace='%s'\n", (*att)->nstr?(*att)->nstr:"")); } (*att)->name = soap_strdup(soap, s); if (tp->visible == 2) (*att)->data = soap_strdup(soap, tp->value); else (*att)->data = NULL; (*att)->wide = NULL; att = &(*att)->next; tp->visible = 0; } soap_element_begin_in(soap, NULL, 1); DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' accepted\n", node->name)); if (soap->body) { wchar c; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has content\n", node->name)); do c = soap_getchar(soap); while (c > 0 && c <= 32); if (c == EOF) { soap->error = SOAP_EOF; return NULL; } soap_unget(soap, c); if (c == '<') { struct soap_dom_element **elt; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has subelements\n", node->name)); elt = &node->elts; for (;;) { if (!(*elt = soap_in_xsd__anyType(soap, NULL, NULL, NULL))) { if (soap->error == SOAP_NO_TAG) soap->error = SOAP_OK; else return NULL; break; } (*elt)->prnt = node; elt = &(*elt)->next; } } else { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has cdata\n", node->name)); if ((soap->mode & SOAP_C_UTFSTRING) || (soap->mode & SOAP_C_MBSTRING)) { if (!(node->data = soap_string_in(soap, 1, -1, -1))) return NULL; } else if (!(node->wide = soap_wstring_in(soap, 1, -1, -1))) return NULL; } if (soap_element_end_in(soap, node->name)) return NULL; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", node->name)); } return node; }