1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * Generic XML helper functions 3e5b75505Sopenharmony_ci * Copyright (c) 2012-2013, Qualcomm Atheros, Inc. 4e5b75505Sopenharmony_ci * 5e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 6e5b75505Sopenharmony_ci * See README for more details. 7e5b75505Sopenharmony_ci */ 8e5b75505Sopenharmony_ci 9e5b75505Sopenharmony_ci#include "includes.h" 10e5b75505Sopenharmony_ci 11e5b75505Sopenharmony_ci#include "common.h" 12e5b75505Sopenharmony_ci#include "xml-utils.h" 13e5b75505Sopenharmony_ci 14e5b75505Sopenharmony_ci 15e5b75505Sopenharmony_cistatic xml_node_t * get_node_uri_iter(struct xml_node_ctx *ctx, 16e5b75505Sopenharmony_ci xml_node_t *root, char *uri) 17e5b75505Sopenharmony_ci{ 18e5b75505Sopenharmony_ci char *end; 19e5b75505Sopenharmony_ci xml_node_t *node; 20e5b75505Sopenharmony_ci const char *name; 21e5b75505Sopenharmony_ci 22e5b75505Sopenharmony_ci end = strchr(uri, '/'); 23e5b75505Sopenharmony_ci if (end) 24e5b75505Sopenharmony_ci *end++ = '\0'; 25e5b75505Sopenharmony_ci 26e5b75505Sopenharmony_ci node = root; 27e5b75505Sopenharmony_ci xml_node_for_each_sibling(ctx, node) { 28e5b75505Sopenharmony_ci xml_node_for_each_check(ctx, node); 29e5b75505Sopenharmony_ci name = xml_node_get_localname(ctx, node); 30e5b75505Sopenharmony_ci if (strcasecmp(name, uri) == 0) 31e5b75505Sopenharmony_ci break; 32e5b75505Sopenharmony_ci } 33e5b75505Sopenharmony_ci 34e5b75505Sopenharmony_ci if (node == NULL) 35e5b75505Sopenharmony_ci return NULL; 36e5b75505Sopenharmony_ci 37e5b75505Sopenharmony_ci if (end) { 38e5b75505Sopenharmony_ci return get_node_uri_iter(ctx, xml_node_first_child(ctx, node), 39e5b75505Sopenharmony_ci end); 40e5b75505Sopenharmony_ci } 41e5b75505Sopenharmony_ci 42e5b75505Sopenharmony_ci return node; 43e5b75505Sopenharmony_ci} 44e5b75505Sopenharmony_ci 45e5b75505Sopenharmony_ci 46e5b75505Sopenharmony_cixml_node_t * get_node_uri(struct xml_node_ctx *ctx, xml_node_t *root, 47e5b75505Sopenharmony_ci const char *uri) 48e5b75505Sopenharmony_ci{ 49e5b75505Sopenharmony_ci char *search; 50e5b75505Sopenharmony_ci xml_node_t *node; 51e5b75505Sopenharmony_ci 52e5b75505Sopenharmony_ci search = os_strdup(uri); 53e5b75505Sopenharmony_ci if (search == NULL) 54e5b75505Sopenharmony_ci return NULL; 55e5b75505Sopenharmony_ci 56e5b75505Sopenharmony_ci node = get_node_uri_iter(ctx, root, search); 57e5b75505Sopenharmony_ci 58e5b75505Sopenharmony_ci os_free(search); 59e5b75505Sopenharmony_ci return node; 60e5b75505Sopenharmony_ci} 61e5b75505Sopenharmony_ci 62e5b75505Sopenharmony_ci 63e5b75505Sopenharmony_cistatic xml_node_t * get_node_iter(struct xml_node_ctx *ctx, 64e5b75505Sopenharmony_ci xml_node_t *root, const char *path) 65e5b75505Sopenharmony_ci{ 66e5b75505Sopenharmony_ci char *end; 67e5b75505Sopenharmony_ci xml_node_t *node; 68e5b75505Sopenharmony_ci const char *name; 69e5b75505Sopenharmony_ci 70e5b75505Sopenharmony_ci end = os_strchr(path, '/'); 71e5b75505Sopenharmony_ci if (end) 72e5b75505Sopenharmony_ci *end++ = '\0'; 73e5b75505Sopenharmony_ci 74e5b75505Sopenharmony_ci xml_node_for_each_child(ctx, node, root) { 75e5b75505Sopenharmony_ci xml_node_for_each_check(ctx, node); 76e5b75505Sopenharmony_ci name = xml_node_get_localname(ctx, node); 77e5b75505Sopenharmony_ci if (os_strcasecmp(name, path) == 0) 78e5b75505Sopenharmony_ci break; 79e5b75505Sopenharmony_ci } 80e5b75505Sopenharmony_ci 81e5b75505Sopenharmony_ci if (node == NULL) 82e5b75505Sopenharmony_ci return NULL; 83e5b75505Sopenharmony_ci if (end) 84e5b75505Sopenharmony_ci return get_node_iter(ctx, node, end); 85e5b75505Sopenharmony_ci return node; 86e5b75505Sopenharmony_ci} 87e5b75505Sopenharmony_ci 88e5b75505Sopenharmony_ci 89e5b75505Sopenharmony_cixml_node_t * get_node(struct xml_node_ctx *ctx, xml_node_t *root, 90e5b75505Sopenharmony_ci const char *path) 91e5b75505Sopenharmony_ci{ 92e5b75505Sopenharmony_ci char *search; 93e5b75505Sopenharmony_ci xml_node_t *node; 94e5b75505Sopenharmony_ci 95e5b75505Sopenharmony_ci search = os_strdup(path); 96e5b75505Sopenharmony_ci if (search == NULL) 97e5b75505Sopenharmony_ci return NULL; 98e5b75505Sopenharmony_ci 99e5b75505Sopenharmony_ci node = get_node_iter(ctx, root, search); 100e5b75505Sopenharmony_ci 101e5b75505Sopenharmony_ci os_free(search); 102e5b75505Sopenharmony_ci return node; 103e5b75505Sopenharmony_ci} 104e5b75505Sopenharmony_ci 105e5b75505Sopenharmony_ci 106e5b75505Sopenharmony_cixml_node_t * get_child_node(struct xml_node_ctx *ctx, xml_node_t *root, 107e5b75505Sopenharmony_ci const char *path) 108e5b75505Sopenharmony_ci{ 109e5b75505Sopenharmony_ci xml_node_t *node; 110e5b75505Sopenharmony_ci xml_node_t *match; 111e5b75505Sopenharmony_ci 112e5b75505Sopenharmony_ci xml_node_for_each_child(ctx, node, root) { 113e5b75505Sopenharmony_ci xml_node_for_each_check(ctx, node); 114e5b75505Sopenharmony_ci match = get_node(ctx, node, path); 115e5b75505Sopenharmony_ci if (match) 116e5b75505Sopenharmony_ci return match; 117e5b75505Sopenharmony_ci } 118e5b75505Sopenharmony_ci 119e5b75505Sopenharmony_ci return NULL; 120e5b75505Sopenharmony_ci} 121e5b75505Sopenharmony_ci 122e5b75505Sopenharmony_ci 123e5b75505Sopenharmony_cixml_node_t * node_from_file(struct xml_node_ctx *ctx, const char *name) 124e5b75505Sopenharmony_ci{ 125e5b75505Sopenharmony_ci xml_node_t *node; 126e5b75505Sopenharmony_ci char *buf, *buf2, *start; 127e5b75505Sopenharmony_ci size_t len; 128e5b75505Sopenharmony_ci 129e5b75505Sopenharmony_ci buf = os_readfile(name, &len); 130e5b75505Sopenharmony_ci if (buf == NULL) 131e5b75505Sopenharmony_ci return NULL; 132e5b75505Sopenharmony_ci buf2 = os_realloc(buf, len + 1); 133e5b75505Sopenharmony_ci if (buf2 == NULL) { 134e5b75505Sopenharmony_ci os_free(buf); 135e5b75505Sopenharmony_ci return NULL; 136e5b75505Sopenharmony_ci } 137e5b75505Sopenharmony_ci buf = buf2; 138e5b75505Sopenharmony_ci buf[len] = '\0'; 139e5b75505Sopenharmony_ci 140e5b75505Sopenharmony_ci start = os_strstr(buf, "<!DOCTYPE "); 141e5b75505Sopenharmony_ci if (start) { 142e5b75505Sopenharmony_ci char *pos = start + 1; 143e5b75505Sopenharmony_ci int count = 1; 144e5b75505Sopenharmony_ci while (*pos) { 145e5b75505Sopenharmony_ci if (*pos == '<') 146e5b75505Sopenharmony_ci count++; 147e5b75505Sopenharmony_ci else if (*pos == '>') { 148e5b75505Sopenharmony_ci count--; 149e5b75505Sopenharmony_ci if (count == 0) { 150e5b75505Sopenharmony_ci pos++; 151e5b75505Sopenharmony_ci break; 152e5b75505Sopenharmony_ci } 153e5b75505Sopenharmony_ci } 154e5b75505Sopenharmony_ci pos++; 155e5b75505Sopenharmony_ci } 156e5b75505Sopenharmony_ci if (count == 0) { 157e5b75505Sopenharmony_ci /* Remove DOCTYPE to allow the file to be parsed */ 158e5b75505Sopenharmony_ci os_memset(start, ' ', pos - start); 159e5b75505Sopenharmony_ci } 160e5b75505Sopenharmony_ci } 161e5b75505Sopenharmony_ci 162e5b75505Sopenharmony_ci node = xml_node_from_buf(ctx, buf); 163e5b75505Sopenharmony_ci os_free(buf); 164e5b75505Sopenharmony_ci 165e5b75505Sopenharmony_ci return node; 166e5b75505Sopenharmony_ci} 167e5b75505Sopenharmony_ci 168e5b75505Sopenharmony_ci 169e5b75505Sopenharmony_ciint node_to_file(struct xml_node_ctx *ctx, const char *fname, xml_node_t *node) 170e5b75505Sopenharmony_ci{ 171e5b75505Sopenharmony_ci FILE *f; 172e5b75505Sopenharmony_ci char *str; 173e5b75505Sopenharmony_ci 174e5b75505Sopenharmony_ci str = xml_node_to_str(ctx, node); 175e5b75505Sopenharmony_ci if (str == NULL) 176e5b75505Sopenharmony_ci return -1; 177e5b75505Sopenharmony_ci 178e5b75505Sopenharmony_ci f = fopen(fname, "w"); 179e5b75505Sopenharmony_ci if (!f) { 180e5b75505Sopenharmony_ci os_free(str); 181e5b75505Sopenharmony_ci return -1; 182e5b75505Sopenharmony_ci } 183e5b75505Sopenharmony_ci 184e5b75505Sopenharmony_ci fprintf(f, "%s\n", str); 185e5b75505Sopenharmony_ci os_free(str); 186e5b75505Sopenharmony_ci fclose(f); 187e5b75505Sopenharmony_ci 188e5b75505Sopenharmony_ci return 0; 189e5b75505Sopenharmony_ci} 190e5b75505Sopenharmony_ci 191e5b75505Sopenharmony_ci 192e5b75505Sopenharmony_cistatic char * get_val(struct xml_node_ctx *ctx, xml_node_t *node) 193e5b75505Sopenharmony_ci{ 194e5b75505Sopenharmony_ci char *val, *pos; 195e5b75505Sopenharmony_ci 196e5b75505Sopenharmony_ci val = xml_node_get_text(ctx, node); 197e5b75505Sopenharmony_ci if (val == NULL) 198e5b75505Sopenharmony_ci return NULL; 199e5b75505Sopenharmony_ci pos = val; 200e5b75505Sopenharmony_ci while (*pos) { 201e5b75505Sopenharmony_ci if (*pos != ' ' && *pos != '\t' && *pos != '\r' && *pos != '\n') 202e5b75505Sopenharmony_ci return val; 203e5b75505Sopenharmony_ci pos++; 204e5b75505Sopenharmony_ci } 205e5b75505Sopenharmony_ci 206e5b75505Sopenharmony_ci return NULL; 207e5b75505Sopenharmony_ci} 208e5b75505Sopenharmony_ci 209e5b75505Sopenharmony_ci 210e5b75505Sopenharmony_cistatic char * add_path(const char *prev, const char *leaf) 211e5b75505Sopenharmony_ci{ 212e5b75505Sopenharmony_ci size_t len; 213e5b75505Sopenharmony_ci char *new_uri; 214e5b75505Sopenharmony_ci 215e5b75505Sopenharmony_ci if (prev == NULL) 216e5b75505Sopenharmony_ci return NULL; 217e5b75505Sopenharmony_ci 218e5b75505Sopenharmony_ci len = os_strlen(prev) + 1 + os_strlen(leaf) + 1; 219e5b75505Sopenharmony_ci new_uri = os_malloc(len); 220e5b75505Sopenharmony_ci if (new_uri) 221e5b75505Sopenharmony_ci os_snprintf(new_uri, len, "%s/%s", prev, leaf); 222e5b75505Sopenharmony_ci 223e5b75505Sopenharmony_ci return new_uri; 224e5b75505Sopenharmony_ci} 225e5b75505Sopenharmony_ci 226e5b75505Sopenharmony_ci 227e5b75505Sopenharmony_cistatic void node_to_tnds(struct xml_node_ctx *ctx, xml_node_t *out, 228e5b75505Sopenharmony_ci xml_node_t *in, const char *uri) 229e5b75505Sopenharmony_ci{ 230e5b75505Sopenharmony_ci xml_node_t *node; 231e5b75505Sopenharmony_ci xml_node_t *tnds; 232e5b75505Sopenharmony_ci const char *name; 233e5b75505Sopenharmony_ci char *val; 234e5b75505Sopenharmony_ci char *new_uri; 235e5b75505Sopenharmony_ci 236e5b75505Sopenharmony_ci xml_node_for_each_child(ctx, node, in) { 237e5b75505Sopenharmony_ci xml_node_for_each_check(ctx, node); 238e5b75505Sopenharmony_ci name = xml_node_get_localname(ctx, node); 239e5b75505Sopenharmony_ci 240e5b75505Sopenharmony_ci tnds = xml_node_create(ctx, out, NULL, "Node"); 241e5b75505Sopenharmony_ci if (tnds == NULL) 242e5b75505Sopenharmony_ci return; 243e5b75505Sopenharmony_ci xml_node_create_text(ctx, tnds, NULL, "NodeName", name); 244e5b75505Sopenharmony_ci 245e5b75505Sopenharmony_ci if (uri) 246e5b75505Sopenharmony_ci xml_node_create_text(ctx, tnds, NULL, "Path", uri); 247e5b75505Sopenharmony_ci 248e5b75505Sopenharmony_ci val = get_val(ctx, node); 249e5b75505Sopenharmony_ci if (val || !xml_node_first_child(ctx, node)) 250e5b75505Sopenharmony_ci xml_node_create_text(ctx, tnds, NULL, "Value", 251e5b75505Sopenharmony_ci val ? val : ""); 252e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, val); 253e5b75505Sopenharmony_ci 254e5b75505Sopenharmony_ci new_uri = add_path(uri, name); 255e5b75505Sopenharmony_ci node_to_tnds(ctx, new_uri ? out : tnds, node, new_uri); 256e5b75505Sopenharmony_ci os_free(new_uri); 257e5b75505Sopenharmony_ci } 258e5b75505Sopenharmony_ci} 259e5b75505Sopenharmony_ci 260e5b75505Sopenharmony_ci 261e5b75505Sopenharmony_cistatic int add_ddfname(struct xml_node_ctx *ctx, xml_node_t *parent, 262e5b75505Sopenharmony_ci const char *urn) 263e5b75505Sopenharmony_ci{ 264e5b75505Sopenharmony_ci xml_node_t *node; 265e5b75505Sopenharmony_ci 266e5b75505Sopenharmony_ci node = xml_node_create(ctx, parent, NULL, "RTProperties"); 267e5b75505Sopenharmony_ci if (node == NULL) 268e5b75505Sopenharmony_ci return -1; 269e5b75505Sopenharmony_ci node = xml_node_create(ctx, node, NULL, "Type"); 270e5b75505Sopenharmony_ci if (node == NULL) 271e5b75505Sopenharmony_ci return -1; 272e5b75505Sopenharmony_ci xml_node_create_text(ctx, node, NULL, "DDFName", urn); 273e5b75505Sopenharmony_ci return 0; 274e5b75505Sopenharmony_ci} 275e5b75505Sopenharmony_ci 276e5b75505Sopenharmony_ci 277e5b75505Sopenharmony_cixml_node_t * mo_to_tnds(struct xml_node_ctx *ctx, xml_node_t *mo, 278e5b75505Sopenharmony_ci int use_path, const char *urn, const char *ns_uri) 279e5b75505Sopenharmony_ci{ 280e5b75505Sopenharmony_ci xml_node_t *root; 281e5b75505Sopenharmony_ci xml_node_t *node; 282e5b75505Sopenharmony_ci const char *name; 283e5b75505Sopenharmony_ci 284e5b75505Sopenharmony_ci root = xml_node_create_root(ctx, ns_uri, NULL, NULL, "MgmtTree"); 285e5b75505Sopenharmony_ci if (root == NULL) 286e5b75505Sopenharmony_ci return NULL; 287e5b75505Sopenharmony_ci 288e5b75505Sopenharmony_ci xml_node_create_text(ctx, root, NULL, "VerDTD", "1.2"); 289e5b75505Sopenharmony_ci 290e5b75505Sopenharmony_ci name = xml_node_get_localname(ctx, mo); 291e5b75505Sopenharmony_ci 292e5b75505Sopenharmony_ci node = xml_node_create(ctx, root, NULL, "Node"); 293e5b75505Sopenharmony_ci if (node == NULL) 294e5b75505Sopenharmony_ci goto fail; 295e5b75505Sopenharmony_ci xml_node_create_text(ctx, node, NULL, "NodeName", name); 296e5b75505Sopenharmony_ci if (urn) 297e5b75505Sopenharmony_ci add_ddfname(ctx, node, urn); 298e5b75505Sopenharmony_ci 299e5b75505Sopenharmony_ci node_to_tnds(ctx, use_path ? root : node, mo, use_path ? name : NULL); 300e5b75505Sopenharmony_ci 301e5b75505Sopenharmony_ci return root; 302e5b75505Sopenharmony_ci 303e5b75505Sopenharmony_cifail: 304e5b75505Sopenharmony_ci xml_node_free(ctx, root); 305e5b75505Sopenharmony_ci return NULL; 306e5b75505Sopenharmony_ci} 307e5b75505Sopenharmony_ci 308e5b75505Sopenharmony_ci 309e5b75505Sopenharmony_cistatic xml_node_t * get_first_child_node(struct xml_node_ctx *ctx, 310e5b75505Sopenharmony_ci xml_node_t *node, 311e5b75505Sopenharmony_ci const char *name) 312e5b75505Sopenharmony_ci{ 313e5b75505Sopenharmony_ci const char *lname; 314e5b75505Sopenharmony_ci xml_node_t *child; 315e5b75505Sopenharmony_ci 316e5b75505Sopenharmony_ci xml_node_for_each_child(ctx, child, node) { 317e5b75505Sopenharmony_ci xml_node_for_each_check(ctx, child); 318e5b75505Sopenharmony_ci lname = xml_node_get_localname(ctx, child); 319e5b75505Sopenharmony_ci if (os_strcasecmp(lname, name) == 0) 320e5b75505Sopenharmony_ci return child; 321e5b75505Sopenharmony_ci } 322e5b75505Sopenharmony_ci 323e5b75505Sopenharmony_ci return NULL; 324e5b75505Sopenharmony_ci} 325e5b75505Sopenharmony_ci 326e5b75505Sopenharmony_ci 327e5b75505Sopenharmony_cistatic char * get_node_text(struct xml_node_ctx *ctx, xml_node_t *node, 328e5b75505Sopenharmony_ci const char *node_name) 329e5b75505Sopenharmony_ci{ 330e5b75505Sopenharmony_ci node = get_first_child_node(ctx, node, node_name); 331e5b75505Sopenharmony_ci if (node == NULL) 332e5b75505Sopenharmony_ci return NULL; 333e5b75505Sopenharmony_ci return xml_node_get_text(ctx, node); 334e5b75505Sopenharmony_ci} 335e5b75505Sopenharmony_ci 336e5b75505Sopenharmony_ci 337e5b75505Sopenharmony_cistatic xml_node_t * add_mo_node(struct xml_node_ctx *ctx, xml_node_t *root, 338e5b75505Sopenharmony_ci xml_node_t *node, const char *uri) 339e5b75505Sopenharmony_ci{ 340e5b75505Sopenharmony_ci char *nodename, *value, *path; 341e5b75505Sopenharmony_ci xml_node_t *parent; 342e5b75505Sopenharmony_ci 343e5b75505Sopenharmony_ci nodename = get_node_text(ctx, node, "NodeName"); 344e5b75505Sopenharmony_ci if (nodename == NULL) 345e5b75505Sopenharmony_ci return NULL; 346e5b75505Sopenharmony_ci value = get_node_text(ctx, node, "Value"); 347e5b75505Sopenharmony_ci 348e5b75505Sopenharmony_ci if (root == NULL) { 349e5b75505Sopenharmony_ci root = xml_node_create_root(ctx, NULL, NULL, NULL, 350e5b75505Sopenharmony_ci nodename); 351e5b75505Sopenharmony_ci if (root && value) 352e5b75505Sopenharmony_ci xml_node_set_text(ctx, root, value); 353e5b75505Sopenharmony_ci } else { 354e5b75505Sopenharmony_ci if (uri == NULL) { 355e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, nodename); 356e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, value); 357e5b75505Sopenharmony_ci return NULL; 358e5b75505Sopenharmony_ci } 359e5b75505Sopenharmony_ci path = get_node_text(ctx, node, "Path"); 360e5b75505Sopenharmony_ci if (path) 361e5b75505Sopenharmony_ci uri = path; 362e5b75505Sopenharmony_ci parent = get_node_uri(ctx, root, uri); 363e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, path); 364e5b75505Sopenharmony_ci if (parent == NULL) { 365e5b75505Sopenharmony_ci printf("Could not find URI '%s'\n", uri); 366e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, nodename); 367e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, value); 368e5b75505Sopenharmony_ci return NULL; 369e5b75505Sopenharmony_ci } 370e5b75505Sopenharmony_ci if (value) 371e5b75505Sopenharmony_ci xml_node_create_text(ctx, parent, NULL, nodename, 372e5b75505Sopenharmony_ci value); 373e5b75505Sopenharmony_ci else 374e5b75505Sopenharmony_ci xml_node_create(ctx, parent, NULL, nodename); 375e5b75505Sopenharmony_ci } 376e5b75505Sopenharmony_ci 377e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, nodename); 378e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, value); 379e5b75505Sopenharmony_ci 380e5b75505Sopenharmony_ci return root; 381e5b75505Sopenharmony_ci} 382e5b75505Sopenharmony_ci 383e5b75505Sopenharmony_ci 384e5b75505Sopenharmony_cistatic xml_node_t * tnds_to_mo_iter(struct xml_node_ctx *ctx, xml_node_t *root, 385e5b75505Sopenharmony_ci xml_node_t *node, const char *uri) 386e5b75505Sopenharmony_ci{ 387e5b75505Sopenharmony_ci xml_node_t *child; 388e5b75505Sopenharmony_ci const char *name; 389e5b75505Sopenharmony_ci char *nodename; 390e5b75505Sopenharmony_ci 391e5b75505Sopenharmony_ci xml_node_for_each_sibling(ctx, node) { 392e5b75505Sopenharmony_ci xml_node_for_each_check(ctx, node); 393e5b75505Sopenharmony_ci 394e5b75505Sopenharmony_ci nodename = get_node_text(ctx, node, "NodeName"); 395e5b75505Sopenharmony_ci if (nodename == NULL) 396e5b75505Sopenharmony_ci return NULL; 397e5b75505Sopenharmony_ci 398e5b75505Sopenharmony_ci name = xml_node_get_localname(ctx, node); 399e5b75505Sopenharmony_ci if (strcmp(name, "Node") == 0) { 400e5b75505Sopenharmony_ci if (root && !uri) { 401e5b75505Sopenharmony_ci printf("Invalid TNDS tree structure - " 402e5b75505Sopenharmony_ci "multiple top level nodes\n"); 403e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, nodename); 404e5b75505Sopenharmony_ci return NULL; 405e5b75505Sopenharmony_ci } 406e5b75505Sopenharmony_ci root = add_mo_node(ctx, root, node, uri); 407e5b75505Sopenharmony_ci } 408e5b75505Sopenharmony_ci 409e5b75505Sopenharmony_ci child = get_first_child_node(ctx, node, "Node"); 410e5b75505Sopenharmony_ci if (child) { 411e5b75505Sopenharmony_ci if (uri == NULL) 412e5b75505Sopenharmony_ci tnds_to_mo_iter(ctx, root, child, nodename); 413e5b75505Sopenharmony_ci else { 414e5b75505Sopenharmony_ci char *new_uri; 415e5b75505Sopenharmony_ci new_uri = add_path(uri, nodename); 416e5b75505Sopenharmony_ci tnds_to_mo_iter(ctx, root, child, new_uri); 417e5b75505Sopenharmony_ci os_free(new_uri); 418e5b75505Sopenharmony_ci } 419e5b75505Sopenharmony_ci } 420e5b75505Sopenharmony_ci xml_node_get_text_free(ctx, nodename); 421e5b75505Sopenharmony_ci } 422e5b75505Sopenharmony_ci 423e5b75505Sopenharmony_ci return root; 424e5b75505Sopenharmony_ci} 425e5b75505Sopenharmony_ci 426e5b75505Sopenharmony_ci 427e5b75505Sopenharmony_cixml_node_t * tnds_to_mo(struct xml_node_ctx *ctx, xml_node_t *tnds) 428e5b75505Sopenharmony_ci{ 429e5b75505Sopenharmony_ci const char *name; 430e5b75505Sopenharmony_ci xml_node_t *node; 431e5b75505Sopenharmony_ci 432e5b75505Sopenharmony_ci name = xml_node_get_localname(ctx, tnds); 433e5b75505Sopenharmony_ci if (name == NULL || os_strcmp(name, "MgmtTree") != 0) 434e5b75505Sopenharmony_ci return NULL; 435e5b75505Sopenharmony_ci 436e5b75505Sopenharmony_ci node = get_first_child_node(ctx, tnds, "Node"); 437e5b75505Sopenharmony_ci if (!node) 438e5b75505Sopenharmony_ci return NULL; 439e5b75505Sopenharmony_ci return tnds_to_mo_iter(ctx, NULL, node, NULL); 440e5b75505Sopenharmony_ci} 441e5b75505Sopenharmony_ci 442e5b75505Sopenharmony_ci 443e5b75505Sopenharmony_cixml_node_t * soap_build_envelope(struct xml_node_ctx *ctx, xml_node_t *node) 444e5b75505Sopenharmony_ci{ 445e5b75505Sopenharmony_ci xml_node_t *envelope, *body; 446e5b75505Sopenharmony_ci xml_namespace_t *ns; 447e5b75505Sopenharmony_ci 448e5b75505Sopenharmony_ci envelope = xml_node_create_root( 449e5b75505Sopenharmony_ci ctx, "http://www.w3.org/2003/05/soap-envelope", "soap12", &ns, 450e5b75505Sopenharmony_ci "Envelope"); 451e5b75505Sopenharmony_ci if (envelope == NULL) 452e5b75505Sopenharmony_ci return NULL; 453e5b75505Sopenharmony_ci body = xml_node_create(ctx, envelope, ns, "Body"); 454e5b75505Sopenharmony_ci xml_node_add_child(ctx, body, node); 455e5b75505Sopenharmony_ci return envelope; 456e5b75505Sopenharmony_ci} 457e5b75505Sopenharmony_ci 458e5b75505Sopenharmony_ci 459e5b75505Sopenharmony_cixml_node_t * soap_get_body(struct xml_node_ctx *ctx, xml_node_t *soap) 460e5b75505Sopenharmony_ci{ 461e5b75505Sopenharmony_ci xml_node_t *body, *child; 462e5b75505Sopenharmony_ci 463e5b75505Sopenharmony_ci body = get_node_uri(ctx, soap, "Envelope/Body"); 464e5b75505Sopenharmony_ci if (body == NULL) 465e5b75505Sopenharmony_ci return NULL; 466e5b75505Sopenharmony_ci xml_node_for_each_child(ctx, child, body) { 467e5b75505Sopenharmony_ci xml_node_for_each_check(ctx, child); 468e5b75505Sopenharmony_ci return child; 469e5b75505Sopenharmony_ci } 470e5b75505Sopenharmony_ci return NULL; 471e5b75505Sopenharmony_ci} 472