15b9c547cSRui Paulo /* 25b9c547cSRui Paulo * Generic XML helper functions 35b9c547cSRui Paulo * Copyright (c) 2012-2013, Qualcomm Atheros, Inc. 45b9c547cSRui Paulo * 55b9c547cSRui Paulo * This software may be distributed under the terms of the BSD license. 65b9c547cSRui Paulo * See README for more details. 75b9c547cSRui Paulo */ 85b9c547cSRui Paulo 95b9c547cSRui Paulo #include "includes.h" 105b9c547cSRui Paulo 115b9c547cSRui Paulo #include "common.h" 125b9c547cSRui Paulo #include "xml-utils.h" 135b9c547cSRui Paulo 145b9c547cSRui Paulo 155b9c547cSRui Paulo static xml_node_t * get_node_uri_iter(struct xml_node_ctx *ctx, 165b9c547cSRui Paulo xml_node_t *root, char *uri) 175b9c547cSRui Paulo { 185b9c547cSRui Paulo char *end; 195b9c547cSRui Paulo xml_node_t *node; 205b9c547cSRui Paulo const char *name; 215b9c547cSRui Paulo 225b9c547cSRui Paulo end = strchr(uri, '/'); 235b9c547cSRui Paulo if (end) 245b9c547cSRui Paulo *end++ = '\0'; 255b9c547cSRui Paulo 265b9c547cSRui Paulo node = root; 275b9c547cSRui Paulo xml_node_for_each_sibling(ctx, node) { 285b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 295b9c547cSRui Paulo name = xml_node_get_localname(ctx, node); 305b9c547cSRui Paulo if (strcasecmp(name, uri) == 0) 315b9c547cSRui Paulo break; 325b9c547cSRui Paulo } 335b9c547cSRui Paulo 345b9c547cSRui Paulo if (node == NULL) 355b9c547cSRui Paulo return NULL; 365b9c547cSRui Paulo 375b9c547cSRui Paulo if (end) { 385b9c547cSRui Paulo return get_node_uri_iter(ctx, xml_node_first_child(ctx, node), 395b9c547cSRui Paulo end); 405b9c547cSRui Paulo } 415b9c547cSRui Paulo 425b9c547cSRui Paulo return node; 435b9c547cSRui Paulo } 445b9c547cSRui Paulo 455b9c547cSRui Paulo 465b9c547cSRui Paulo xml_node_t * get_node_uri(struct xml_node_ctx *ctx, xml_node_t *root, 475b9c547cSRui Paulo const char *uri) 485b9c547cSRui Paulo { 495b9c547cSRui Paulo char *search; 505b9c547cSRui Paulo xml_node_t *node; 515b9c547cSRui Paulo 525b9c547cSRui Paulo search = os_strdup(uri); 535b9c547cSRui Paulo if (search == NULL) 545b9c547cSRui Paulo return NULL; 555b9c547cSRui Paulo 565b9c547cSRui Paulo node = get_node_uri_iter(ctx, root, search); 575b9c547cSRui Paulo 585b9c547cSRui Paulo os_free(search); 595b9c547cSRui Paulo return node; 605b9c547cSRui Paulo } 615b9c547cSRui Paulo 625b9c547cSRui Paulo 635b9c547cSRui Paulo static xml_node_t * get_node_iter(struct xml_node_ctx *ctx, 645b9c547cSRui Paulo xml_node_t *root, const char *path) 655b9c547cSRui Paulo { 665b9c547cSRui Paulo char *end; 675b9c547cSRui Paulo xml_node_t *node; 685b9c547cSRui Paulo const char *name; 695b9c547cSRui Paulo 705b9c547cSRui Paulo end = os_strchr(path, '/'); 715b9c547cSRui Paulo if (end) 725b9c547cSRui Paulo *end++ = '\0'; 735b9c547cSRui Paulo 745b9c547cSRui Paulo xml_node_for_each_child(ctx, node, root) { 755b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 765b9c547cSRui Paulo name = xml_node_get_localname(ctx, node); 775b9c547cSRui Paulo if (os_strcasecmp(name, path) == 0) 785b9c547cSRui Paulo break; 795b9c547cSRui Paulo } 805b9c547cSRui Paulo 815b9c547cSRui Paulo if (node == NULL) 825b9c547cSRui Paulo return NULL; 835b9c547cSRui Paulo if (end) 845b9c547cSRui Paulo return get_node_iter(ctx, node, end); 855b9c547cSRui Paulo return node; 865b9c547cSRui Paulo } 875b9c547cSRui Paulo 885b9c547cSRui Paulo 895b9c547cSRui Paulo xml_node_t * get_node(struct xml_node_ctx *ctx, xml_node_t *root, 905b9c547cSRui Paulo const char *path) 915b9c547cSRui Paulo { 925b9c547cSRui Paulo char *search; 935b9c547cSRui Paulo xml_node_t *node; 945b9c547cSRui Paulo 955b9c547cSRui Paulo search = os_strdup(path); 965b9c547cSRui Paulo if (search == NULL) 975b9c547cSRui Paulo return NULL; 985b9c547cSRui Paulo 995b9c547cSRui Paulo node = get_node_iter(ctx, root, search); 1005b9c547cSRui Paulo 1015b9c547cSRui Paulo os_free(search); 1025b9c547cSRui Paulo return node; 1035b9c547cSRui Paulo } 1045b9c547cSRui Paulo 1055b9c547cSRui Paulo 1065b9c547cSRui Paulo xml_node_t * get_child_node(struct xml_node_ctx *ctx, xml_node_t *root, 1075b9c547cSRui Paulo const char *path) 1085b9c547cSRui Paulo { 1095b9c547cSRui Paulo xml_node_t *node; 1105b9c547cSRui Paulo xml_node_t *match; 1115b9c547cSRui Paulo 1125b9c547cSRui Paulo xml_node_for_each_child(ctx, node, root) { 1135b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 1145b9c547cSRui Paulo match = get_node(ctx, node, path); 1155b9c547cSRui Paulo if (match) 1165b9c547cSRui Paulo return match; 1175b9c547cSRui Paulo } 1185b9c547cSRui Paulo 1195b9c547cSRui Paulo return NULL; 1205b9c547cSRui Paulo } 1215b9c547cSRui Paulo 1225b9c547cSRui Paulo 1235b9c547cSRui Paulo xml_node_t * node_from_file(struct xml_node_ctx *ctx, const char *name) 1245b9c547cSRui Paulo { 1255b9c547cSRui Paulo xml_node_t *node; 1265b9c547cSRui Paulo char *buf, *buf2, *start; 1275b9c547cSRui Paulo size_t len; 1285b9c547cSRui Paulo 1295b9c547cSRui Paulo buf = os_readfile(name, &len); 1305b9c547cSRui Paulo if (buf == NULL) 1315b9c547cSRui Paulo return NULL; 1325b9c547cSRui Paulo buf2 = os_realloc(buf, len + 1); 1335b9c547cSRui Paulo if (buf2 == NULL) { 1345b9c547cSRui Paulo os_free(buf); 1355b9c547cSRui Paulo return NULL; 1365b9c547cSRui Paulo } 1375b9c547cSRui Paulo buf = buf2; 1385b9c547cSRui Paulo buf[len] = '\0'; 1395b9c547cSRui Paulo 1405b9c547cSRui Paulo start = os_strstr(buf, "<!DOCTYPE "); 1415b9c547cSRui Paulo if (start) { 1425b9c547cSRui Paulo char *pos = start + 1; 1435b9c547cSRui Paulo int count = 1; 1445b9c547cSRui Paulo while (*pos) { 1455b9c547cSRui Paulo if (*pos == '<') 1465b9c547cSRui Paulo count++; 1475b9c547cSRui Paulo else if (*pos == '>') { 1485b9c547cSRui Paulo count--; 1495b9c547cSRui Paulo if (count == 0) { 1505b9c547cSRui Paulo pos++; 1515b9c547cSRui Paulo break; 1525b9c547cSRui Paulo } 1535b9c547cSRui Paulo } 1545b9c547cSRui Paulo pos++; 1555b9c547cSRui Paulo } 1565b9c547cSRui Paulo if (count == 0) { 1575b9c547cSRui Paulo /* Remove DOCTYPE to allow the file to be parsed */ 1585b9c547cSRui Paulo os_memset(start, ' ', pos - start); 1595b9c547cSRui Paulo } 1605b9c547cSRui Paulo } 1615b9c547cSRui Paulo 1625b9c547cSRui Paulo node = xml_node_from_buf(ctx, buf); 1635b9c547cSRui Paulo os_free(buf); 1645b9c547cSRui Paulo 1655b9c547cSRui Paulo return node; 1665b9c547cSRui Paulo } 1675b9c547cSRui Paulo 1685b9c547cSRui Paulo 1695b9c547cSRui Paulo int node_to_file(struct xml_node_ctx *ctx, const char *fname, xml_node_t *node) 1705b9c547cSRui Paulo { 1715b9c547cSRui Paulo FILE *f; 1725b9c547cSRui Paulo char *str; 1735b9c547cSRui Paulo 1745b9c547cSRui Paulo str = xml_node_to_str(ctx, node); 1755b9c547cSRui Paulo if (str == NULL) 1765b9c547cSRui Paulo return -1; 1775b9c547cSRui Paulo 1785b9c547cSRui Paulo f = fopen(fname, "w"); 1795b9c547cSRui Paulo if (!f) { 1805b9c547cSRui Paulo os_free(str); 1815b9c547cSRui Paulo return -1; 1825b9c547cSRui Paulo } 1835b9c547cSRui Paulo 1845b9c547cSRui Paulo fprintf(f, "%s\n", str); 1855b9c547cSRui Paulo os_free(str); 1865b9c547cSRui Paulo fclose(f); 1875b9c547cSRui Paulo 1885b9c547cSRui Paulo return 0; 1895b9c547cSRui Paulo } 1905b9c547cSRui Paulo 1915b9c547cSRui Paulo 1925b9c547cSRui Paulo static char * get_val(struct xml_node_ctx *ctx, xml_node_t *node) 1935b9c547cSRui Paulo { 1945b9c547cSRui Paulo char *val, *pos; 1955b9c547cSRui Paulo 1965b9c547cSRui Paulo val = xml_node_get_text(ctx, node); 1975b9c547cSRui Paulo if (val == NULL) 1985b9c547cSRui Paulo return NULL; 1995b9c547cSRui Paulo pos = val; 2005b9c547cSRui Paulo while (*pos) { 2015b9c547cSRui Paulo if (*pos != ' ' && *pos != '\t' && *pos != '\r' && *pos != '\n') 2025b9c547cSRui Paulo return val; 2035b9c547cSRui Paulo pos++; 2045b9c547cSRui Paulo } 2055b9c547cSRui Paulo 2065b9c547cSRui Paulo return NULL; 2075b9c547cSRui Paulo } 2085b9c547cSRui Paulo 2095b9c547cSRui Paulo 2105b9c547cSRui Paulo static char * add_path(const char *prev, const char *leaf) 2115b9c547cSRui Paulo { 2125b9c547cSRui Paulo size_t len; 2135b9c547cSRui Paulo char *new_uri; 2145b9c547cSRui Paulo 2155b9c547cSRui Paulo if (prev == NULL) 2165b9c547cSRui Paulo return NULL; 2175b9c547cSRui Paulo 2185b9c547cSRui Paulo len = os_strlen(prev) + 1 + os_strlen(leaf) + 1; 2195b9c547cSRui Paulo new_uri = os_malloc(len); 2205b9c547cSRui Paulo if (new_uri) 2215b9c547cSRui Paulo os_snprintf(new_uri, len, "%s/%s", prev, leaf); 2225b9c547cSRui Paulo 2235b9c547cSRui Paulo return new_uri; 2245b9c547cSRui Paulo } 2255b9c547cSRui Paulo 2265b9c547cSRui Paulo 2275b9c547cSRui Paulo static void node_to_tnds(struct xml_node_ctx *ctx, xml_node_t *out, 2285b9c547cSRui Paulo xml_node_t *in, const char *uri) 2295b9c547cSRui Paulo { 2305b9c547cSRui Paulo xml_node_t *node; 2315b9c547cSRui Paulo xml_node_t *tnds; 2325b9c547cSRui Paulo const char *name; 2335b9c547cSRui Paulo char *val; 2345b9c547cSRui Paulo char *new_uri; 2355b9c547cSRui Paulo 2365b9c547cSRui Paulo xml_node_for_each_child(ctx, node, in) { 2375b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 2385b9c547cSRui Paulo name = xml_node_get_localname(ctx, node); 2395b9c547cSRui Paulo 2405b9c547cSRui Paulo tnds = xml_node_create(ctx, out, NULL, "Node"); 2415b9c547cSRui Paulo if (tnds == NULL) 2425b9c547cSRui Paulo return; 2435b9c547cSRui Paulo xml_node_create_text(ctx, tnds, NULL, "NodeName", name); 2445b9c547cSRui Paulo 2455b9c547cSRui Paulo if (uri) 2465b9c547cSRui Paulo xml_node_create_text(ctx, tnds, NULL, "Path", uri); 2475b9c547cSRui Paulo 2485b9c547cSRui Paulo val = get_val(ctx, node); 249*85732ac8SCy Schubert if (val || !xml_node_first_child(ctx, node)) 250*85732ac8SCy Schubert xml_node_create_text(ctx, tnds, NULL, "Value", 251*85732ac8SCy Schubert val ? val : ""); 2525b9c547cSRui Paulo xml_node_get_text_free(ctx, val); 2535b9c547cSRui Paulo 2545b9c547cSRui Paulo new_uri = add_path(uri, name); 2555b9c547cSRui Paulo node_to_tnds(ctx, new_uri ? out : tnds, node, new_uri); 2565b9c547cSRui Paulo os_free(new_uri); 2575b9c547cSRui Paulo } 2585b9c547cSRui Paulo } 2595b9c547cSRui Paulo 2605b9c547cSRui Paulo 2615b9c547cSRui Paulo static int add_ddfname(struct xml_node_ctx *ctx, xml_node_t *parent, 2625b9c547cSRui Paulo const char *urn) 2635b9c547cSRui Paulo { 2645b9c547cSRui Paulo xml_node_t *node; 2655b9c547cSRui Paulo 2665b9c547cSRui Paulo node = xml_node_create(ctx, parent, NULL, "RTProperties"); 2675b9c547cSRui Paulo if (node == NULL) 2685b9c547cSRui Paulo return -1; 2695b9c547cSRui Paulo node = xml_node_create(ctx, node, NULL, "Type"); 2705b9c547cSRui Paulo if (node == NULL) 2715b9c547cSRui Paulo return -1; 2725b9c547cSRui Paulo xml_node_create_text(ctx, node, NULL, "DDFName", urn); 2735b9c547cSRui Paulo return 0; 2745b9c547cSRui Paulo } 2755b9c547cSRui Paulo 2765b9c547cSRui Paulo 2775b9c547cSRui Paulo xml_node_t * mo_to_tnds(struct xml_node_ctx *ctx, xml_node_t *mo, 2785b9c547cSRui Paulo int use_path, const char *urn, const char *ns_uri) 2795b9c547cSRui Paulo { 2805b9c547cSRui Paulo xml_node_t *root; 2815b9c547cSRui Paulo xml_node_t *node; 2825b9c547cSRui Paulo const char *name; 2835b9c547cSRui Paulo 2845b9c547cSRui Paulo root = xml_node_create_root(ctx, ns_uri, NULL, NULL, "MgmtTree"); 2855b9c547cSRui Paulo if (root == NULL) 2865b9c547cSRui Paulo return NULL; 2875b9c547cSRui Paulo 2885b9c547cSRui Paulo xml_node_create_text(ctx, root, NULL, "VerDTD", "1.2"); 2895b9c547cSRui Paulo 2905b9c547cSRui Paulo name = xml_node_get_localname(ctx, mo); 2915b9c547cSRui Paulo 2925b9c547cSRui Paulo node = xml_node_create(ctx, root, NULL, "Node"); 2935b9c547cSRui Paulo if (node == NULL) 2945b9c547cSRui Paulo goto fail; 2955b9c547cSRui Paulo xml_node_create_text(ctx, node, NULL, "NodeName", name); 2965b9c547cSRui Paulo if (urn) 2975b9c547cSRui Paulo add_ddfname(ctx, node, urn); 2985b9c547cSRui Paulo 2995b9c547cSRui Paulo node_to_tnds(ctx, use_path ? root : node, mo, use_path ? name : NULL); 3005b9c547cSRui Paulo 3015b9c547cSRui Paulo return root; 3025b9c547cSRui Paulo 3035b9c547cSRui Paulo fail: 3045b9c547cSRui Paulo xml_node_free(ctx, root); 3055b9c547cSRui Paulo return NULL; 3065b9c547cSRui Paulo } 3075b9c547cSRui Paulo 3085b9c547cSRui Paulo 3095b9c547cSRui Paulo static xml_node_t * get_first_child_node(struct xml_node_ctx *ctx, 3105b9c547cSRui Paulo xml_node_t *node, 3115b9c547cSRui Paulo const char *name) 3125b9c547cSRui Paulo { 3135b9c547cSRui Paulo const char *lname; 3145b9c547cSRui Paulo xml_node_t *child; 3155b9c547cSRui Paulo 3165b9c547cSRui Paulo xml_node_for_each_child(ctx, child, node) { 3175b9c547cSRui Paulo xml_node_for_each_check(ctx, child); 3185b9c547cSRui Paulo lname = xml_node_get_localname(ctx, child); 3195b9c547cSRui Paulo if (os_strcasecmp(lname, name) == 0) 3205b9c547cSRui Paulo return child; 3215b9c547cSRui Paulo } 3225b9c547cSRui Paulo 3235b9c547cSRui Paulo return NULL; 3245b9c547cSRui Paulo } 3255b9c547cSRui Paulo 3265b9c547cSRui Paulo 3275b9c547cSRui Paulo static char * get_node_text(struct xml_node_ctx *ctx, xml_node_t *node, 3285b9c547cSRui Paulo const char *node_name) 3295b9c547cSRui Paulo { 3305b9c547cSRui Paulo node = get_first_child_node(ctx, node, node_name); 3315b9c547cSRui Paulo if (node == NULL) 3325b9c547cSRui Paulo return NULL; 3335b9c547cSRui Paulo return xml_node_get_text(ctx, node); 3345b9c547cSRui Paulo } 3355b9c547cSRui Paulo 3365b9c547cSRui Paulo 3375b9c547cSRui Paulo static xml_node_t * add_mo_node(struct xml_node_ctx *ctx, xml_node_t *root, 3385b9c547cSRui Paulo xml_node_t *node, const char *uri) 3395b9c547cSRui Paulo { 3405b9c547cSRui Paulo char *nodename, *value, *path; 3415b9c547cSRui Paulo xml_node_t *parent; 3425b9c547cSRui Paulo 3435b9c547cSRui Paulo nodename = get_node_text(ctx, node, "NodeName"); 3445b9c547cSRui Paulo if (nodename == NULL) 3455b9c547cSRui Paulo return NULL; 3465b9c547cSRui Paulo value = get_node_text(ctx, node, "Value"); 3475b9c547cSRui Paulo 3485b9c547cSRui Paulo if (root == NULL) { 3495b9c547cSRui Paulo root = xml_node_create_root(ctx, NULL, NULL, NULL, 3505b9c547cSRui Paulo nodename); 3515b9c547cSRui Paulo if (root && value) 3525b9c547cSRui Paulo xml_node_set_text(ctx, root, value); 3535b9c547cSRui Paulo } else { 3545b9c547cSRui Paulo if (uri == NULL) { 3555b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 3565b9c547cSRui Paulo xml_node_get_text_free(ctx, value); 3575b9c547cSRui Paulo return NULL; 3585b9c547cSRui Paulo } 3595b9c547cSRui Paulo path = get_node_text(ctx, node, "Path"); 3605b9c547cSRui Paulo if (path) 3615b9c547cSRui Paulo uri = path; 3625b9c547cSRui Paulo parent = get_node_uri(ctx, root, uri); 3635b9c547cSRui Paulo xml_node_get_text_free(ctx, path); 3645b9c547cSRui Paulo if (parent == NULL) { 3655b9c547cSRui Paulo printf("Could not find URI '%s'\n", uri); 3665b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 3675b9c547cSRui Paulo xml_node_get_text_free(ctx, value); 3685b9c547cSRui Paulo return NULL; 3695b9c547cSRui Paulo } 3705b9c547cSRui Paulo if (value) 3715b9c547cSRui Paulo xml_node_create_text(ctx, parent, NULL, nodename, 3725b9c547cSRui Paulo value); 3735b9c547cSRui Paulo else 3745b9c547cSRui Paulo xml_node_create(ctx, parent, NULL, nodename); 3755b9c547cSRui Paulo } 3765b9c547cSRui Paulo 3775b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 3785b9c547cSRui Paulo xml_node_get_text_free(ctx, value); 3795b9c547cSRui Paulo 3805b9c547cSRui Paulo return root; 3815b9c547cSRui Paulo } 3825b9c547cSRui Paulo 3835b9c547cSRui Paulo 3845b9c547cSRui Paulo static xml_node_t * tnds_to_mo_iter(struct xml_node_ctx *ctx, xml_node_t *root, 3855b9c547cSRui Paulo xml_node_t *node, const char *uri) 3865b9c547cSRui Paulo { 3875b9c547cSRui Paulo xml_node_t *child; 3885b9c547cSRui Paulo const char *name; 3895b9c547cSRui Paulo char *nodename; 3905b9c547cSRui Paulo 3915b9c547cSRui Paulo xml_node_for_each_sibling(ctx, node) { 3925b9c547cSRui Paulo xml_node_for_each_check(ctx, node); 3935b9c547cSRui Paulo 3945b9c547cSRui Paulo nodename = get_node_text(ctx, node, "NodeName"); 3955b9c547cSRui Paulo if (nodename == NULL) 3965b9c547cSRui Paulo return NULL; 3975b9c547cSRui Paulo 3985b9c547cSRui Paulo name = xml_node_get_localname(ctx, node); 3995b9c547cSRui Paulo if (strcmp(name, "Node") == 0) { 4005b9c547cSRui Paulo if (root && !uri) { 4015b9c547cSRui Paulo printf("Invalid TNDS tree structure - " 4025b9c547cSRui Paulo "multiple top level nodes\n"); 4035b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 4045b9c547cSRui Paulo return NULL; 4055b9c547cSRui Paulo } 4065b9c547cSRui Paulo root = add_mo_node(ctx, root, node, uri); 4075b9c547cSRui Paulo } 4085b9c547cSRui Paulo 4095b9c547cSRui Paulo child = get_first_child_node(ctx, node, "Node"); 4105b9c547cSRui Paulo if (child) { 4115b9c547cSRui Paulo if (uri == NULL) 4125b9c547cSRui Paulo tnds_to_mo_iter(ctx, root, child, nodename); 4135b9c547cSRui Paulo else { 4145b9c547cSRui Paulo char *new_uri; 4155b9c547cSRui Paulo new_uri = add_path(uri, nodename); 4165b9c547cSRui Paulo tnds_to_mo_iter(ctx, root, child, new_uri); 4175b9c547cSRui Paulo os_free(new_uri); 4185b9c547cSRui Paulo } 4195b9c547cSRui Paulo } 4205b9c547cSRui Paulo xml_node_get_text_free(ctx, nodename); 4215b9c547cSRui Paulo } 4225b9c547cSRui Paulo 4235b9c547cSRui Paulo return root; 4245b9c547cSRui Paulo } 4255b9c547cSRui Paulo 4265b9c547cSRui Paulo 4275b9c547cSRui Paulo xml_node_t * tnds_to_mo(struct xml_node_ctx *ctx, xml_node_t *tnds) 4285b9c547cSRui Paulo { 4295b9c547cSRui Paulo const char *name; 4305b9c547cSRui Paulo xml_node_t *node; 4315b9c547cSRui Paulo 4325b9c547cSRui Paulo name = xml_node_get_localname(ctx, tnds); 4335b9c547cSRui Paulo if (name == NULL || os_strcmp(name, "MgmtTree") != 0) 4345b9c547cSRui Paulo return NULL; 4355b9c547cSRui Paulo 4365b9c547cSRui Paulo node = get_first_child_node(ctx, tnds, "Node"); 4375b9c547cSRui Paulo if (!node) 4385b9c547cSRui Paulo return NULL; 4395b9c547cSRui Paulo return tnds_to_mo_iter(ctx, NULL, node, NULL); 4405b9c547cSRui Paulo } 4415b9c547cSRui Paulo 4425b9c547cSRui Paulo 4435b9c547cSRui Paulo xml_node_t * soap_build_envelope(struct xml_node_ctx *ctx, xml_node_t *node) 4445b9c547cSRui Paulo { 4455b9c547cSRui Paulo xml_node_t *envelope, *body; 4465b9c547cSRui Paulo xml_namespace_t *ns; 4475b9c547cSRui Paulo 4485b9c547cSRui Paulo envelope = xml_node_create_root( 4495b9c547cSRui Paulo ctx, "http://www.w3.org/2003/05/soap-envelope", "soap12", &ns, 4505b9c547cSRui Paulo "Envelope"); 4515b9c547cSRui Paulo if (envelope == NULL) 4525b9c547cSRui Paulo return NULL; 4535b9c547cSRui Paulo body = xml_node_create(ctx, envelope, ns, "Body"); 4545b9c547cSRui Paulo xml_node_add_child(ctx, body, node); 4555b9c547cSRui Paulo return envelope; 4565b9c547cSRui Paulo } 4575b9c547cSRui Paulo 4585b9c547cSRui Paulo 4595b9c547cSRui Paulo xml_node_t * soap_get_body(struct xml_node_ctx *ctx, xml_node_t *soap) 4605b9c547cSRui Paulo { 4615b9c547cSRui Paulo xml_node_t *body, *child; 4625b9c547cSRui Paulo 4635b9c547cSRui Paulo body = get_node_uri(ctx, soap, "Envelope/Body"); 4645b9c547cSRui Paulo if (body == NULL) 4655b9c547cSRui Paulo return NULL; 4665b9c547cSRui Paulo xml_node_for_each_child(ctx, child, body) { 4675b9c547cSRui Paulo xml_node_for_each_check(ctx, child); 4685b9c547cSRui Paulo return child; 4695b9c547cSRui Paulo } 4705b9c547cSRui Paulo return NULL; 4715b9c547cSRui Paulo } 472