1/* 2 * Broadcom Home Gateway Reference Design 3 * Broadcom WiFi Insight Webpage functions 4 * 5 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 * $Id: vis_gui.c 458674 2014-08-12 11:23:19Z $ 19 */ 20#ifdef WEBS 21#include <webs.h> 22#include <uemf.h> 23#include <ej.h> 24#else /* !WEBS */ 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28#include <ctype.h> 29#include <errno.h> 30#include <unistd.h> 31#include <fcntl.h> 32#include <limits.h> 33#include <sys/types.h> 34#include <sys/stat.h> 35#include <sys/socket.h> 36#include <netinet/in.h> 37#include <arpa/inet.h> 38#include <assert.h> 39#include <httpd.h> 40#endif /* WEBS */ 41#include <netdb.h> 42 43#include "vis_gui.h" 44#include <proto/ethernet.h> 45#include <bcmnvram.h> 46 47#ifdef __CONFIG_VISUALIZATION__ 48 49#include <signal.h> 50 51#define sys_restart() kill(1, SIGHUP) 52 53/* Indicates the level of debug message to be printed on the console */ 54static int vis_debug_level = 0; 55 56/* Header to download DB file */ 57char g_vis_download_db_hdr[] = 58"Cache-Control: no-cache\r\n" 59"Pragma: no-cache\r\n" 60"Expires: 0\r\n" 61"Content-Type: application/download\r\n" 62"Content-Disposition: attachment ; filename=visdata.db" 63; 64 65#define INVALID_SOCKET -1 66#define VIS_SOCKET_WAIT_TIMEOUT 15 67#define MAX_READ_BUFFER 1449 68#define VISUALIZATION_SERVER_PORT 8888 69#define VISUALIZATION_SERVER_ADDRESS "127.0.0.1" 70#define VIS_LEN_FIELD_SZ 4 /* Number of bytes used to specify the length */ 71#define VIS_MAX_XML_LEN 1024 72#define VIS_MAX_REQ_LEN 50 73/* MAC address from WEB has %3A for every : character so length as 30 */ 74#define VIS_MAX_MAC_LEN 30 75#define VIS_MAX_BAND_LEN 2 76#define VIS_MAX_IP_LEN 16 77 78/* Visualization error printing defines */ 79#define VIS_DEBUG_ERROR 0x0001 80#define VIS_DEBUG_WARNING 0x0002 81#define VIS_DEBUG_INFO 0x0004 82#define VIS_DEBUG_DETAIL 0x0008 83 84#define VIS_ERROR(fmt, arg...) \ 85 do { if (vis_debug_level & VIS_DEBUG_ERROR) \ 86 printf("VIS-ERROR >> %s : "fmt, __FUNCTION__, ##arg); } while (0) 87 88#define VIS_WARNING(fmt, arg...) \ 89 do { if (vis_debug_level & VIS_DEBUG_WARNING) \ 90 printf("VIS-WARNING >> %s : "fmt, __FUNCTION__, ##arg); } while (0) 91 92#define VIS_INFO(fmt, arg...) \ 93 do { if (vis_debug_level & VIS_DEBUG_INFO) \ 94 printf("VIS-INFO >> %s : "fmt, __FUNCTION__, ##arg); } while (0) 95 96#define VIS_DEBUG(fmt, arg...) \ 97 do { if (vis_debug_level & VIS_DEBUG_DETAIL) \ 98 printf("VIS-DEBUG >> %s : "fmt, __FUNCTION__, ##arg); } while (0) 99 100typedef struct vis_xml_strings_t_ { 101 int nallocated; /* Number bytes allocated */ 102 int nlength; /* Number of bytes filled */ 103 char *str; /* string to hold the xml data */ 104} vis_xml_strings_t; 105 106enum vis_enum_req_args { 107 VIS_UNKNOWN, 108 VIS_REQUEST, 109 VIS_DUTMAC, 110 VIS_STAMAC, 111 VIS_FREQBAND, 112 VIS_INTERVAL, 113 VIS_DBSIZE, 114 VIS_STARTSTOP, 115 VIS_TOTAL, 116 VIS_GRAPHNAME, 117 VIS_DCONIP, 118 VIS_ISREMOTE_ENABLE, 119 VIS_DOSCAN, 120 VIS_ISOVERWRITEDB, 121 VIS_ISAUTOSTART, 122 VIS_WEEKDAYS, 123 VIS_FROMTM, 124 VIS_TOTM, 125 }; 126 127typedef struct { 128 enum vis_enum_req_args id; /* ID of the request argument */ 129 char *req_name; /* Name of the argument */ 130} vis_req_args; 131 132vis_req_args vis_req_args_list[] = { 133 {VIS_UNKNOWN, "Unknown"}, 134 {VIS_REQUEST, "Req"}, 135 {VIS_DUTMAC, "DutMac"}, 136 {VIS_STAMAC, "StaMac"}, 137 {VIS_FREQBAND, "FreqBand"}, 138 {VIS_INTERVAL, "Interval"}, 139 {VIS_DBSIZE, "DBSize"}, 140 {VIS_STARTSTOP, "StartStop"}, 141 {VIS_TOTAL, "Total"}, 142 {VIS_GRAPHNAME, "graphname"}, 143 {VIS_DCONIP, "DCONIP"}, 144 {VIS_ISREMOTE_ENABLE, "IsRemoteDebugEnabled"}, 145 {VIS_DOSCAN, "DoScan"}, 146 {VIS_ISOVERWRITEDB, "OverWriteDB"}, 147 {VIS_ISAUTOSTART, "AutoStart"}, 148 {VIS_WEEKDAYS, "WeekDays"}, 149 {VIS_FROMTM, "FromTm"}, 150 {VIS_TOTM, "ToTm"} 151}; 152 153/* This will check whether to reallocate memory for XML buffer or not */ 154#define CHECK_XML_BUFF(xml_strings, nlenreq) if (xml_strings->str == NULL ||\ 155 (xml_strings->nallocated < (xml_strings->nlength+nlenreq))) {\ 156 if (vis_xml_allocate_buffer(xml_strings, nlenreq) != 0)\ 157 return; } 158 159static unsigned char *vis_rdata = NULL; 160 161/* Visualization WebUI handling starts here */ 162 163/* Closes the socket given the file descriptor */ 164static void 165close_socket(int *sockfd) 166{ 167 if (*sockfd == INVALID_SOCKET) 168 return; 169 170 close(*sockfd); 171 *sockfd = INVALID_SOCKET; 172} 173 174/* Sends the buffer to server */ 175static int 176send_data(int sockfd, char *data, unsigned int len) 177{ 178 int nret = 0; 179 int totalsize = len, totalsent = 0; 180 181 while (totalsent < totalsize) { 182 fd_set WriteFDs, ExceptFDs; 183 struct timeval tv; 184 185 FD_ZERO(&WriteFDs); 186 FD_ZERO(&ExceptFDs); 187 188 if (sockfd == INVALID_SOCKET) 189 return INVALID_SOCKET; 190 191 FD_SET(sockfd, &WriteFDs); 192 193 tv.tv_sec = VIS_SOCKET_WAIT_TIMEOUT; 194 tv.tv_usec = 0; 195 if (select(sockfd+1, NULL, &WriteFDs, &ExceptFDs, &tv) > 0) { 196 if (!FD_ISSET(sockfd, &WriteFDs)) { 197 VIS_WARNING("Write descriptor is not set. Not ready to write\n"); 198 return INVALID_SOCKET; 199 } 200 } 201 202 nret = send(sockfd, &(data[totalsent]), len, 0); 203 if (nret < 0) { 204 VIS_WARNING("Failed to send data error : %s\n", strerror(errno)); 205 return INVALID_SOCKET; 206 } 207 totalsent += nret; 208 len -= nret; 209 nret = 0; 210 } 211 212 return totalsent; 213} 214 215/* Adds the 4 bytes length and then data to a buffer and sends it to 216 * server 217 */ 218static int 219add_length_and_send_data(int sockfd, char *data, unsigned int len) 220{ 221 int ret = 0; 222 char *sdata = NULL; 223 int totlen = VIS_LEN_FIELD_SZ + len; 224 225 sdata = (char*)malloc(sizeof(char) * (totlen)); 226 if (sdata == NULL) { 227 VIS_DEBUG("Failed to allocate sdata buffer of size : %d\n", totlen); 228 return -1; 229 } 230 231 memcpy(sdata, &totlen, VIS_LEN_FIELD_SZ); 232 233 memcpy(sdata+VIS_LEN_FIELD_SZ, data, len); 234 235 ret = send_data(sockfd, sdata, totlen); 236 237 free(sdata); 238 239 return ret; 240} 241 242/* Recieves the 'size' number of data */ 243static int 244recv_data(int sockfd, unsigned char *read_buf, uint32 size) 245{ 246 uint32 nbytes, totalread = 0; 247 fd_set ReadFDs, ExceptFDs; 248 struct timeval tv; 249 250 FD_ZERO(&ReadFDs); 251 FD_ZERO(&ExceptFDs); 252 FD_SET(sockfd, &ReadFDs); 253 FD_SET(sockfd, &ExceptFDs); 254 tv.tv_sec = VIS_SOCKET_WAIT_TIMEOUT; 255 tv.tv_usec = 0; 256 257 while (totalread < size) { 258 if (select(sockfd+1, &ReadFDs, NULL, &ExceptFDs, &tv) > 0) { 259 if (!FD_ISSET(sockfd, &ReadFDs)) { 260 VIS_WARNING("Read descriptor is not set. Not ready to read\n"); 261 return INVALID_SOCKET; 262 } 263 } 264 nbytes = read(sockfd, &(read_buf[totalread]), size); 265 266 if (nbytes <= 0) { 267 VIS_WARNING("Failed to read data error : %s\n", strerror(errno)); 268 return INVALID_SOCKET; 269 } 270 271 totalread += nbytes; 272 } 273 274 read_buf[totalread] = '\0'; 275 276 return totalread; 277} 278 279/* Recieves the data from server 280 * return value contains the number of bytes read or -1 for error 281 * free the buffer after reading the data 282 */ 283static int 284on_receive(int sockfd, unsigned char **data) 285{ 286 uint32 sz, size = 0; 287 unsigned char szbuff[VIS_LEN_FIELD_SZ+1] = {0}; 288 unsigned char *read_buf = NULL; 289 290 sz = recv_data(sockfd, szbuff, VIS_LEN_FIELD_SZ); 291 if (sz <= 0) { 292 return INVALID_SOCKET; 293 } 294 295 if (sz >= VIS_LEN_FIELD_SZ) { 296 memcpy(&size, szbuff, sizeof(size)); 297 } else { 298 VIS_DEBUG("Failed to receive length field\n"); 299 return -1; 300 } 301 302 read_buf = (unsigned char *)malloc(sizeof(unsigned char) * ((size-VIS_LEN_FIELD_SZ) + 1)); 303 if (read_buf == NULL) { 304 VIS_DEBUG("Failed to allocate read_buf buffer of size : %d\n", 305 ((size-VIS_LEN_FIELD_SZ) + 1)); 306 return -1; 307 } 308 309 sz = recv_data(sockfd, read_buf, (size-VIS_LEN_FIELD_SZ)); 310 if (sz <= 0) { 311 if (read_buf != NULL) { 312 free(read_buf); 313 read_buf = NULL; 314 } 315 return INVALID_SOCKET; 316 } 317 318 *data = read_buf; 319 320 return sz; 321} 322 323/* Connects to server given the port and address */ 324static int 325connect_to_server(uint32 nport, char *straddrs) 326{ 327 int res, valopt, sockfd; 328 long arg; 329 socklen_t lon; 330 fd_set readfds; 331 struct timeval tv; 332 struct hostent *host; 333 struct sockaddr_in server_addr; 334 335 sockfd = INVALID_SOCKET; 336 memset(&server_addr, 0, sizeof(server_addr)); 337 338 if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { 339 VIS_DEBUG("Failed to create socket error : %s\n", strerror(errno)); 340 goto vis_connect_err; 341 } 342 343 if ((host = gethostbyname(straddrs)) == NULL) { 344 VIS_DEBUG("gethostbyname error : %s\n", strerror(errno)); 345 goto vis_connect_err; 346 } 347 348 /* Set nonblock on the socket so we can timeout */ 349 if ((arg = fcntl(sockfd, F_GETFL, NULL)) < 0 || 350 fcntl(sockfd, F_SETFL, arg | O_NONBLOCK) < 0) { 351 VIS_DEBUG("fcntl error : %s\n", strerror(errno)); 352 goto vis_connect_err; 353 } 354 355 server_addr.sin_family = AF_INET; 356 server_addr.sin_port = htons(nport); 357 server_addr.sin_addr = *((struct in_addr*)host -> h_addr); 358 res = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); 359 360 if (res < 0) { 361 if (errno == EINPROGRESS) { 362 tv.tv_sec = 30; 363 tv.tv_usec = 0; 364 FD_ZERO(&readfds); 365 FD_SET(sockfd, &readfds); 366 if (select(sockfd+1, NULL, &readfds, NULL, &tv) > 0) { 367 lon = sizeof(int); 368 getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon); 369 if (valopt) { 370 VIS_DEBUG("Error in connection() %d - %s\n", 371 valopt, strerror(valopt)); 372 goto vis_connect_err; 373 } 374 } else { 375 VIS_DEBUG("Timeout or error() %d - %s\n", valopt, strerror(valopt)); 376 goto vis_connect_err; 377 } 378 } else { 379 VIS_DEBUG("Error connecting %d - %s\n", errno, strerror(errno)); 380 goto vis_connect_err; 381 } 382 } 383 384 return sockfd; 385 386vis_connect_err: 387 close_socket(&sockfd); 388 return INVALID_SOCKET; 389} 390 391/* Sends the XML data to server */ 392static int 393send_ui_frontend_data(char *xmldata) 394{ 395 int sockfd = INVALID_SOCKET; 396 int ret = 0; 397 398 sockfd = connect_to_server(VISUALIZATION_SERVER_PORT, VISUALIZATION_SERVER_ADDRESS); 399 if (sockfd != INVALID_SOCKET) { 400 ret = add_length_and_send_data(sockfd, xmldata, strlen(xmldata)); 401 if (ret != INVALID_SOCKET) { 402 vis_rdata = NULL; 403 ret = on_receive(sockfd, &vis_rdata); 404 if (ret <= 0) { 405 VIS_DEBUG("Failed to recieve data\n"); 406 } 407 } else { 408 VIS_DEBUG("Failed to send XML data = %s\n", xmldata); 409 } 410 } else { 411 VIS_DEBUG("Failed to Connect to server : %s Port : %d\n", 412 VISUALIZATION_SERVER_ADDRESS, VISUALIZATION_SERVER_PORT); 413 } 414 415 close_socket(&sockfd); 416 417 return ret; 418} 419 420/* Write json answer to stream */ 421void 422vis_do_json_get(char *url, FILE *stream) 423{ 424 if (vis_rdata != NULL) 425 fputs((const char*)vis_rdata, stream); 426 427 if (vis_rdata != NULL) { 428 free(vis_rdata); 429 vis_rdata = NULL; 430 } 431} 432 433/* Allocates memory for XML data buffer */ 434static inline int 435vis_xml_allocate_buffer(vis_xml_strings_t *xml_strings, int nreq) 436{ 437 int nallocate = VIS_MAX_XML_LEN; 438 439 if (xml_strings->nallocated > 0) { /* realloc */ 440 if ((xml_strings->nallocated + nallocate) < (xml_strings->nlength + nreq + 1)) 441 nallocate = xml_strings->nlength + nreq + 1; 442 else 443 nallocate += xml_strings->nallocated; 444 char *tmpptr = (char*)realloc(xml_strings->str, nallocate); 445 if (tmpptr == NULL) { 446 VIS_DEBUG("Memory reallocation failed of : %d for XML buffer\n", nallocate); 447 return -1; 448 } 449 xml_strings->str = tmpptr; 450 xml_strings->nallocated = nallocate; 451 } else { 452 if (nallocate < (nreq+1)) 453 nallocate = nreq+1; 454 455 xml_strings->str = (char*)malloc(sizeof(char)*nallocate); 456 if (xml_strings->str == NULL) { 457 VIS_DEBUG("Memory allocation failed of : %d for XML buffer\n", nallocate); 458 return -1; 459 } 460 xml_strings->nallocated = nallocate; 461 } 462 463 return 0; 464} 465 466/* Frees the XML data buffer */ 467static inline void 468vis_xml_free_data_buffer(vis_xml_strings_t *xml_strings) 469{ 470 if (xml_strings->str) { 471 free(xml_strings->str); 472 xml_strings->str = NULL; 473 } 474} 475 476/* Add only start or end tag */ 477static inline void 478vis_xml_add_only_tag(vis_xml_strings_t *xml_strings, char *tag, bool isstarttag) 479{ 480 int nlenreq = 0; 481 482 /* total len required for xml tag is 1Tag's + 2open brackets */ 483 nlenreq = strlen(tag) + 2 + 1; 484 if (!isstarttag) 485 nlenreq += 1; /* For end tag need / */ 486 CHECK_XML_BUFF(xml_strings, nlenreq); 487 488 if (isstarttag) { 489 xml_strings->nlength += snprintf(xml_strings->str+xml_strings->nlength, 490 xml_strings->nallocated-xml_strings->nlength, "<%s>", tag); 491 } else { 492 xml_strings->nlength += snprintf(xml_strings->str+xml_strings->nlength, 493 xml_strings->nallocated-xml_strings->nlength, "</%s>", tag); 494 } 495} 496 497/* Add only the value into tag */ 498static inline void 499vis_xml_add_only_value(vis_xml_strings_t *xml_strings, char *value) 500{ 501 int nlenreq = 0; 502 503 /* total len required for xml tag is 1Tag's + 2open brackets */ 504 nlenreq = strlen(value) + 1; 505 CHECK_XML_BUFF(xml_strings, nlenreq); 506 507 xml_strings->nlength += snprintf(xml_strings->str+xml_strings->nlength, 508 xml_strings->nallocated-xml_strings->nlength, "%s", value); 509} 510 511/* Adds TAG and Value pair to the xml data buffer */ 512static inline void 513vis_xml_add_tag_value(vis_xml_strings_t *xml_strings, char *tag, char *value) 514{ 515 int nlenreq = 0; 516 517 /* total len required for one xml tag is 518 * 2Tag's + 2open brackets + 2closing brackets + one slash + one value 519 */ 520 nlenreq = (2 * strlen(tag)) + 5 + strlen(value) + 1; 521 CHECK_XML_BUFF(xml_strings, nlenreq); 522 523 xml_strings->nlength += snprintf(xml_strings->str+xml_strings->nlength, 524 xml_strings->nallocated-xml_strings->nlength, "<%s>%s</%s>", 525 tag, value, tag); 526} 527 528/* Adds TAG and attribute to the xml data buffer */ 529static inline void 530vis_xml_add_tag_and_attribute(vis_xml_strings_t *xml_strings, char *tag, 531 char *attribname, char *attribvalue) 532{ 533 int nlenreq = 0; 534 535 /* total len required for one xml tag is 536 * 1Tag's + 2 brackets 537 * + one space + one attribute name + one attribute value + one = 538 */ 539 nlenreq = strlen(tag) + 4 + strlen(attribname) + strlen(attribvalue) + 1; 540 CHECK_XML_BUFF(xml_strings, nlenreq); 541 542 xml_strings->nlength += snprintf(xml_strings->str+xml_strings->nlength, 543 xml_strings->nallocated-xml_strings->nlength, "<%s %s=%s>", 544 tag, attribname, attribvalue); 545} 546 547/* Read query from stream in json format treate it and create answer string 548 * The query is a list of commands and treated by 'do_json_command' 549 */ 550static void 551create_xml_string(const char *querystring, vis_xml_strings_t *xmlstring) 552{ 553 char *pch; 554 char request[VIS_MAX_REQ_LEN] = {0}; 555 char dutmac[VIS_MAX_MAC_LEN] = {0}; 556 char stamac[VIS_MAX_MAC_LEN] = {0}; 557 char band[VIS_MAX_BAND_LEN] = {0}; 558 char dcon_ip[VIS_MAX_IP_LEN] = {0}; 559 int isenabled = 0; 560 static int donvramread = 1; 561 vis_xml_strings_t configxml = {0}; 562 vis_xml_strings_t graphxml = {0}; 563 vis_xml_strings_t dutset = {0}; 564 vis_xml_strings_t pkthdr = {0}; 565 566 /* Read NVRAM variable for debug print. Read only once, that is why checking for 1 567 * From next time onwards default value 0 will be set to static var 568 */ 569 if (donvramread == 1) { 570 char *tmpdebugflag = nvram_get("vis_debug_level"); 571 if (tmpdebugflag) 572 vis_debug_level = strtoul(tmpdebugflag, NULL, 0); 573 donvramread = 0; 574 } 575 576 VIS_DEBUG("Request : %s\n", querystring); 577 578 vis_xml_add_tag_and_attribute(&pkthdr, "PacketVersion", "Name", "\"1\""); 579 vis_xml_add_only_tag(&pkthdr, "PacketHeader", TRUE); /* Open packet header tag */ 580 vis_xml_add_tag_value(&pkthdr, "PacketType", "1"); 581 vis_xml_add_tag_value(&pkthdr, "From", "2"); 582 583 vis_xml_add_only_tag(&configxml, "Config", TRUE); /* Open Config tag */ 584 vis_xml_add_only_tag(&graphxml, "EnabledGraphs", TRUE); /* Open enabled graphs tag */ 585 586 pch = strtok((char*)querystring, "?=&"); 587 while (pch != NULL) { 588 int i; 589 enum vis_enum_req_args id = VIS_UNKNOWN; 590 591 for (i = 0; i < (sizeof(vis_req_args_list)/sizeof(vis_req_args)); i++) { 592 if (strstr(pch, vis_req_args_list[i].req_name) != NULL) { 593 pch = strtok(NULL, "?=&"); 594 if (pch == NULL) 595 break; 596 id = vis_req_args_list[i].id; 597 break; 598 } 599 } 600 switch (id) { 601 case VIS_REQUEST: /* Get the request name */ 602 snprintf(request, sizeof(request), "%s", pch); 603 vis_xml_add_tag_value(&pkthdr, "ReqRespType", request); 604 break; 605 case VIS_DUTMAC: /* Get the DUTMAC */ 606 snprintf(dutmac, sizeof(dutmac), "%s", pch); 607 break; 608 case VIS_STAMAC: /* Get the STAMAC */ 609 snprintf(stamac, sizeof(stamac), "%s", pch); 610 break; 611 case VIS_FREQBAND: /* Get the FreqBand */ 612 snprintf(band, sizeof(band), "%s", pch); 613 vis_xml_add_tag_value(&pkthdr, "FreqBand", band); 614 break; 615 case VIS_INTERVAL: /* Get Interval for config settings */ 616 vis_xml_add_tag_value(&configxml, "SampleInterval", pch); 617 break; 618 case VIS_DBSIZE: /* Get Max database size for config settings */ 619 vis_xml_add_tag_value(&configxml, "dbsize", pch); 620 break; 621 case VIS_STARTSTOP: /* Tells to stop or start the data collection */ 622 vis_xml_add_tag_value(&configxml, "startstop", pch); 623 break; 624 case VIS_TOTAL: /* Get total graph names for config settings */ 625 vis_xml_add_tag_value(&graphxml, "Total", pch); 626 break; 627 case VIS_GRAPHNAME: /* Get graphname for config settings */ 628 vis_xml_add_tag_value(&graphxml, "graphname", pch); 629 break; 630 case VIS_DCONIP: /* Server IP for remote debug */ 631 snprintf(dcon_ip, sizeof(dcon_ip), "%s", pch); 632 break; 633 case VIS_ISREMOTE_ENABLE: /* Flag for remote debugging enabled */ 634 isenabled = atoi(pch); 635 break; 636 case VIS_DOSCAN: /* Flag for DO scan flag */ 637 vis_xml_add_only_tag(&dutset, "DUTSet", TRUE); 638 vis_xml_add_tag_value(&dutset, "DoScan", pch); 639 vis_xml_add_only_tag(&dutset, "DUTSet", FALSE); 640 break; 641 case VIS_ISOVERWRITEDB: /* Get Overwrite DB flag for config settings */ 642 vis_xml_add_tag_value(&configxml, "overwrtdb", pch); 643 break; 644 case VIS_ISAUTOSTART: /* Get Is Auto Start flag for config settings */ 645 vis_xml_add_tag_value(&configxml, "autost", pch); 646 break; 647 case VIS_WEEKDAYS: /* Get Weekdays for config settings */ 648 vis_xml_add_tag_value(&configxml, "wkdays", pch); 649 break; 650 case VIS_FROMTM: /* Get From Time for config settings */ 651 vis_xml_add_tag_value(&configxml, "frmtm", pch); 652 break; 653 case VIS_TOTM: /* Get To Time for config settings */ 654 vis_xml_add_tag_value(&configxml, "totm", pch); 655 break; 656 case VIS_UNKNOWN: 657 break; 658 } 659 pch = strtok(NULL, "?=&"); 660 } 661 662 if (strcmp(request, "RemoteSettings") == 0) { 663 char *tmpdcon_ip = nvram_get("vis_dcon_ipaddr"); 664 if (tmpdcon_ip == NULL) 665 goto vis_fun_end; 666 char *value = nvram_get("vis_do_remote_dcon"); 667 if (value) 668 isenabled = atoi(value); 669 vis_rdata = (unsigned char*)malloc(sizeof(char) * MAX_READ_BUFFER); 670 memset(vis_rdata, 0, MAX_READ_BUFFER); 671 snprintf(vis_rdata, MAX_READ_BUFFER, "{\"IsEnabled\":%d,\"ServerIP\":\"%s\"}", 672 isenabled, tmpdcon_ip); 673 goto vis_fun_end; 674 } else if (strcmp(request, "SetRemoteDebug") == 0) { 675 char tmpbuf[5] = {0}; 676 677 nvram_set("vis_dcon_ipaddr", dcon_ip); 678 snprintf(tmpbuf, sizeof(tmpbuf), "%d", isenabled); 679 nvram_set("vis_do_remote_dcon", tmpbuf); 680 nvram_commit(); 681 sys_restart(); 682 goto vis_fun_end; 683 } 684 vis_xml_add_only_tag(&graphxml, "EnabledGraphs", FALSE); /* Close EnabledGraphs Tag */ 685 vis_xml_add_only_value(&configxml, graphxml.str); 686 vis_xml_add_only_tag(&configxml, "Config", FALSE); /* Close Config Tag */ 687 vis_xml_add_only_tag(&pkthdr, "PacketHeader", FALSE); /* Close Packet Header Tag */ 688 689 vis_xml_add_only_tag(xmlstring, "?xml version=\"1.0\" encoding=\"utf-8\"?", TRUE); 690 vis_xml_add_only_value(&pkthdr, configxml.str); 691 vis_xml_add_only_tag(&pkthdr, "DUT", TRUE); /* Open DUT tag */ 692 vis_xml_add_tag_value(&pkthdr, "MAC", dutmac); 693 vis_xml_add_tag_value(&pkthdr, "STAMAC", stamac); 694 vis_xml_add_only_tag(&pkthdr, "DUT", FALSE); /* Close DUT Tag */ 695 if (dutset.str) 696 vis_xml_add_only_value(&pkthdr, dutset.str); 697 vis_xml_add_only_tag(&pkthdr, "PacketVersion", FALSE); /* Clsoe PacketVersion Tag */ 698 vis_xml_add_only_value(xmlstring, pkthdr.str); 699 700vis_fun_end: 701 /* Free the XML data buffers */ 702 vis_xml_free_data_buffer(&configxml); 703 vis_xml_free_data_buffer(&graphxml); 704 vis_xml_free_data_buffer(&dutset); 705 vis_xml_free_data_buffer(&pkthdr); 706} 707 708/* Read query from stream in json format treate it and create answer string 709 * The query is a list of commands and treated by 'do_json_command' 710 */ 711void 712vis_do_json_set(const char *url, FILE *stream, int len, const char *boundary) 713{ 714 vis_xml_strings_t xmlstring = {0}; 715 716 /* create the xml string out of the query string */ 717 create_xml_string(url, &xmlstring); 718 719 /* send this xml string to the backend via socket */ 720 if (xmlstring.str != NULL) { 721 send_ui_frontend_data(xmlstring.str); 722 vis_xml_free_data_buffer(&xmlstring); 723 } 724} 725 726/* 727 * Create XML and send it to dcon to get the DB file and 728 * then send it to Web UI 729 */ 730void 731vis_do_visdbdwnld_cgi(char *url, FILE *stream) 732{ 733 vis_xml_strings_t xmlstring = {0}; 734 char tmpurl[] = "json.cgi?Req=GetDBFile"; 735 int ret = 0; 736 737 /* create the xml string out of the query string */ 738 create_xml_string(tmpurl, &xmlstring); 739 if (xmlstring.str != NULL) { 740 ret = send_ui_frontend_data(xmlstring.str); 741 if ((ret > 0) && (vis_rdata != NULL)) 742 fwrite(vis_rdata, ret, 1, stream); 743 744 if (vis_rdata != NULL) { 745 free(vis_rdata); 746 vis_rdata = NULL; 747 } 748 vis_xml_free_data_buffer(&xmlstring); 749 } 750 751 websDone(stream, 200); 752} 753 754#endif /* __CONFIG_VISUALIZATION__ */ 755