1/* 2 * Copyright 2004, ASUSTek Inc. 3 * All Rights Reserved. 4 * 5 * THIS SOFTWARE IS OFFERED "AS IS", AND ASUS GRANTS NO WARRANTIES OF ANY 6 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 7 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 8 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 9 * 10 * $Id: watchdog.c,v 1.3 2009/03/03 02:39:54 james26_jang Exp $ 11 */ 12 13 14#include <stdio.h> 15#include <signal.h> 16#include <time.h> 17#include <sys/time.h> 18#include <unistd.h> 19#include <stdlib.h> 20#include <sys/types.h> 21#include <shutils.h> 22#include <rc.h> 23#include <stdarg.h> 24#include <wlioctl.h> 25#include <syslog.h> 26#include <bcmnvram.h> 27#include <fcntl.h> 28#include <linux_gpio.h> 29#include <sys/stat.h> 30#include <math.h> 31 32 33/* +++ Cherry Cho added in 2007/1/4. +++ */ 34#include <sys/types.h> 35#include <sys/socket.h> 36#include <time.h> 37/* --- Cherry Cho added in 2007/1/4. --- */ 38 39#define BCM47XX_SOFTWARE_RESET 0x40 /* GPIO 6 */ 40#define RESET_WAIT 3 /* seconds */ 41#define RESET_WAIT_COUNT RESET_WAIT * 10 /* 10 times a second */ 42 43#define NORMAL_PERIOD 1 /* second */ 44#define URGENT_PERIOD 100 * 1000 /* microsecond */ 45#define RUSHURGENT_PERIOD 50 * 1000 /* microsecond */ 46 /* 1/10 second */ 47#define STACHECK_PERIOD_CONNECT 60/5 /* 30 seconds */ 48#define STACHECK_PERIOD_DISCONNECT 5/5 /* 5 seconds */ 49 50#ifdef WCN 51#define QUICK_PERIOD 100 * 1000 /* microsecond */ 52int wcn_on=0; 53int wcn_led=0; 54int wcn_led_state=0; 55int wcn_timer=2; 56int reboot_WCN_count=0; 57#endif 58 59#define GPIO0 0x0001 60#define GPIO1 0x0002 61#define GPIO2 0x0004 62#define GPIO3 0x0008 63#define GPIO4 0x0010 64#define GPIO5 0x0020 65#define GPIO6 0x0040 66#define GPIO7 0x0080 67#define GPIO15 0x8000 68 69#define LED_ON 0 70#define LED_OFF 1 71 72#define LED_POWER GPIO0 73#define BTN_RESET GPIO2 74#define BTN_SETUP GPIO3 75 76#ifdef BTN_SETUP 77#define SETUP_WAIT 3 /* seconds */ 78#define SETUP_WAIT_COUNT 100 /* The real waiting time depends on the alarm timer. Cherry Cho modified in 2008/7/4. */ 79#define SETUP_TIMEOUT 60 /* seconds */ 80#define SETUP_TIMEOUT_COUNT SETUP_TIMEOUT * 10 /* 60 times a second */ 81#endif //BTN_SETUP 82 83 84/* Global containing the file descriptor of the GPIO kernel drivers */ 85static int bcmgpio_fd; 86 87/* Global containing information about each GPIO pin */ 88 89/* Static function prototypes */ 90 91/* Generic functions to read/write Chip Common core's GPIO registers on the AP */ 92int tgpio_drvinit (); 93void tgpio_drvcleanup (); 94 95int tgpio_ioctl(int gpioreg, unsigned int mask , unsigned int val); 96 97/* GPIO registers */ 98#define BCMGPIO_REG_IN 0 99#define BCMGPIO_REG_OUT 1 100#define BCMGPIO_REG_OUTEN 2 101#define BCMGPIO_REG_RESERVE 3 102#define BCMGPIO_REG_RELEASE 4 103 104 105#define LED_CONTROL(led,flag) gpio_write("/dev/gpio/out", led, flag) 106 107 108struct itimerval itv; 109int watchdog_period=0; 110static int btn_pressed=0; 111static int btn_count = 0; 112long sync_interval=-1; // every 30 seconds a unit 113int sync_flag=0; 114long timestamp_g=0; 115int stacheck_interval=-1; 116#ifdef BTN_SETUP 117int btn_pressed_setup=0; 118int btn_pressed_flag=0; 119int btn_count_setup=0; 120int btn_count_timeout=0; 121int btn_stage=0; 122#endif 123#ifdef WSC 124int btn_addER = 0; 125/* +++ Cherry Cho added in 2008/7/16. +++ */ 126int WSC_ENABLED; 127int wsc_success = 1; 128int led_count = 0; 129int led_count_timeout = 100; 130extern int start_wsc(void); 131/* --- Cherry Cho added in 2008/7/16. --- */ 132#endif 133 134#ifdef CDMA 135int cdma_down=0; 136int cdma_connect=0; 137#endif 138 139int reboot_count=0; 140static int int_nas_enable=0; 141static int nas_check_interval=0; 142 143int tgpio_fd_init (); 144void tgpio_fd_cleanup (); 145int tgpio_ioctl(int gpioreg, unsigned int mask , unsigned int val); 146void gpio_write(char *dev, int gpio, int val); 147 148void wl_led_ctrl(int ctrl);/* Cherry Cho added in 2008/7/16. */ 149 150 151int 152tgpio_fd_init () 153{ 154 bcmgpio_fd = open("/dev/gpio", O_RDWR); 155 if (bcmgpio_fd == -1) { 156 printf ("Failed to open /dev/gpio\n"); 157 return -1; 158 } 159 return 0; 160} 161 162void 163tgpio_fd_cleanup () 164{ 165 if (bcmgpio_fd!= -1) { 166 close (bcmgpio_fd); 167 bcmgpio_fd = -1; 168 } 169} 170 171int 172tgpio_ioctl(int gpioreg, unsigned int mask , unsigned int val) 173{ 174 struct gpio_ioctl gpio; 175 int type; 176 177 gpio.val = val; 178 gpio.mask = mask; 179 180 switch (gpioreg) { 181 case BCMGPIO_REG_IN: 182 type = GPIO_IOC_IN; 183 break; 184 case BCMGPIO_REG_OUT: 185 type = GPIO_IOC_OUT; 186 break; 187 case BCMGPIO_REG_OUTEN: 188 type = GPIO_IOC_OUTEN; 189 break; 190 case BCMGPIO_REG_RESERVE: 191 type = GPIO_IOC_RESERVE; 192 break; 193 case BCMGPIO_REG_RELEASE: 194 type = GPIO_IOC_RELEASE; 195 break; 196 default: 197 printf ("invalid gpioreg %d\n", gpioreg); 198 return -1; 199 } 200 if (ioctl(bcmgpio_fd, type, &gpio) < 0) { 201 printf ("invalid gpioreg %d\n", gpioreg); 202 return -1; 203 } 204 return (gpio.val); 205} 206 207void gpio_write(char *dev, int gpio, int val) 208{ 209 unsigned int gpio_type; 210 unsigned long bitmask; 211 unsigned long gpio_val; 212// int gpio_pin; 213 214 if( strcmp (dev, "/dev/gpio/in") == 0) 215 gpio_type = BCMGPIO_REG_IN; 216 else if ( strcmp (dev, "/dev/gpio/out") == 0) 217 gpio_type = BCMGPIO_REG_OUT; 218 else if ( strcmp (dev, "/dev/gpio/outen") == 0) 219 gpio_type = BCMGPIO_REG_OUTEN; 220 else 221 printf("ERROR GPIO NAME %s\n", dev); 222 223 //sscanf(argv[3], "%x", &val); 224 tgpio_fd_init(); 225 tgpio_ioctl(BCMGPIO_REG_RESERVE, gpio, gpio); 226 if (val > 0) 227 tgpio_ioctl(gpio_type, gpio, gpio); 228 else 229 tgpio_ioctl(gpio_type, gpio, 0); 230 tgpio_fd_cleanup(); 231} 232 233int gpio_read (char *dev, int gpio) 234{ 235 unsigned int gpio_type; 236 int ret; 237 unsigned long bitmask; 238 if( strcmp (dev, "/dev/gpio/in") == 0) 239 gpio_type = BCMGPIO_REG_IN; 240 else if ( strcmp (dev, "/dev/gpio/out") == 0) 241 gpio_type = BCMGPIO_REG_OUT; 242 else if ( strcmp (dev, "/dev/gpio/outen") == 0) 243 gpio_type = BCMGPIO_REG_OUTEN; 244 else 245 printf("ERROR GPIO NAME %s\n", dev); 246 247 tgpio_fd_init(); 248 249 /* read the value of GPIO*/ 250 ret = (tgpio_ioctl(gpio_type, gpio, 0)); 251 tgpio_fd_cleanup(); 252 253 return (ret&gpio); 254} 255 256/* Functions used to control led and button */ 257void gpio_init() 258{ 259 gpio_write("/dev/gpio/outen", LED_POWER, 1); 260 gpio_write("/dev/gpio/outen", BTN_RESET, 0); 261#ifdef BTN_SETUP 262 gpio_write("/dev/gpio/outen", BTN_SETUP, 0); 263#endif 264 gpio_write("/dev/gpio/out", LED_POWER, 0); 265} 266 267static void 268alarmtimer(unsigned long sec,unsigned long usec) 269{ 270 itv.it_value.tv_sec = sec; 271 itv.it_value.tv_usec = usec; 272 itv.it_interval = itv.it_value; 273 setitimer(ITIMER_REAL, &itv, NULL); 274} 275 276void btn_check(void) 277{ 278#ifdef WCN 279 if(wcn_on==1) 280 { 281 ++wcn_led; 282 wcn_led%=wcn_timer; 283 wcn_led_state=(wcn_led==0?1:0); 284 285 if(wcn_led_state) 286 LED_CONTROL(LED_POWER, LED_ON); 287 else 288 LED_CONTROL(LED_POWER, LED_OFF); 289 290 return; 291 } 292#endif 293 294#ifdef BTN_SETUP 295#if 0/* Cherry Cho marked for stoping using EZsetup in 2007/2/12. */ 296 if (btn_pressed_flag) 297 { 298 ++btn_pressed_flag; 299 300 if(btn_pressed_flag==8) 301 { 302 start_ots(); 303 } 304 else if(btn_pressed_flag==10) 305 { 306 btn_pressed_flag=0; 307 btn_pressed_setup=BTNSETUP_START; 308 btn_count_setup=0; 309 alarmtimer(0, RUSHURGENT_PERIOD); 310 } 311 } 312#endif 313 if (btn_pressed_setup==BTNSETUP_NONE) 314 { 315#endif 316 if(!gpio_read("/dev/gpio/in", BTN_RESET)){ 317 /*--------------- Add BTN_RST MFG test ------------------------*/ 318 if(!nvram_match("asus_mfg", "")){ 319 nvram_set("btn_rst", "1"); 320 } 321 else{ 322 if(!btn_pressed){ 323 btn_pressed = 1; 324 btn_count = 0; 325 alarmtimer(0, URGENT_PERIOD); /* URGENT_PERIOD = 100*1000 microseconds */ 326 } 327 else{ /* Whenever it is pushed steady */ 328 if(++btn_count > RESET_WAIT_COUNT){ 329 btn_pressed = 2; 330 } 331 332 if(btn_pressed == 2){ 333 /* 0123456789 */ 334 /* 0011100111 */ 335 if((btn_count%10) < 1 || 336 ((btn_count%10) > 4 && (btn_count%10) < 7)){ 337 LED_CONTROL(LED_POWER, LED_OFF); 338 } 339 else{ 340 LED_CONTROL(LED_POWER, LED_ON); 341 } 342 } 343 } 344 } //end BTN_RST MFG test 345 } 346 else{ 347 if(btn_pressed == 1){ 348 btn_count = 0; 349 btn_pressed = 0; 350 LED_CONTROL(LED_POWER, LED_ON); 351 alarmtimer(NORMAL_PERIOD, 0); 352 } 353 else if(btn_pressed == 2){ 354 LED_CONTROL(LED_POWER, LED_OFF); 355 alarmtimer(0, 0); 356 eval("erase", "/dev/mtd/3"); 357 kill(1, SIGTERM); 358 } 359 } 360#ifdef BTN_SETUP 361 } 362 363 if (btn_pressed!=0) return; 364 365 if (btn_pressed_setup<BTNSETUP_START) 366 { 367 if (!gpio_read("/dev/gpio/in", BTN_SETUP)) 368 { 369 /* Add BTN_EZ MFG test */ 370 if (!nvram_match("asus_mfg", "")){ 371 nvram_set("btn_ez", "1"); 372 } 373 else{ 374 if (btn_pressed_setup==BTNSETUP_NONE) 375 { 376 btn_pressed_setup=BTNSETUP_DETECT; 377 btn_count_setup=0; 378 alarmtimer(0, RUSHURGENT_PERIOD);/* RUSHURGENT_PERIOD = 50*1000 microseconds */ 379 } 380 else { /* Whenever it is pushed steady */ 381 if( ++btn_count_setup > SETUP_WAIT_COUNT )//User must press button for more than 5 seconds. 382 { 383 #ifdef WSC/* Cherry Cho modified in 2008/6/24. */ 384 if(WSC_ENABLED){ 385 if(nvram_match("wsc_waiting", "1") 386 && nvram_match("wsc_timer_start", "1") 387 && nvram_match("wsc_method", "1")){ 388 /* When PIN configuration is running, PBC can interrupt PIN.*/ 389 nvram_set("wsc_config_command", "2");//Timeout PIN process immediately 390 } 391 else{ 392 /* Run WSC Push Button to Get Configuration */ 393 if(nvram_match("wsc_waiting", "0") 394 &&nvram_match("wsc_timer_start", "0")){ 395 nvram_set("wsc_method", "2"); 396 nvram_set("wsc_pbc_force", "1"); 397 nvram_set("wsc_proc_status", "0");//Reset value of wsc_proc_status 398 if(nvram_match("wsc_config_state", "0")) 399 nvram_set("wsc_asus_mode", "1"); 400 else 401 btn_addER = 1; 402 403 btn_pressed_setup=BTNSETUP_START; 404 btn_count_setup=0; 405 alarmtimer(0, RUSHURGENT_PERIOD); 406 } 407 } 408 } 409 #endif 410 } 411 } 412 } //end BTN_EZ MFG test 413 } 414 else if(btn_pressed_setup==BTNSETUP_DETECT)/* Cherry Cho modified in 2008/6/24. */ 415 { 416 #ifdef WSC 417 if(WSC_ENABLED){/* Cherry Cho added in 2008/7/21. */ 418 if(nvram_match("wsc_waiting", "1")//The PIN process is running. 419 && nvram_match("wsc_timer_start", "1") 420 && nvram_match("wsc_method", "1")) 421 { 422 nvram_set("wsc_config_command", "2"); 423 } 424 else if(nvram_match("wsc_waiting", "0") 425 && nvram_match("wsc_timer_start", "0")) 426 { 427 nvram_set("wsc_method", "2"); 428 nvram_set("wsc_pbc_force", "1"); 429 nvram_set("wsc_proc_status", "0"); 430 btn_addER = 1; 431 btn_pressed_setup=BTNSETUP_START; 432 btn_count_setup=0; 433 alarmtimer(0, RUSHURGENT_PERIOD); 434 } 435 } 436 else/* WSC is not enabled. Cherry Cho added in 2008/7/21. */ 437 { 438 btn_pressed_setup = BTNSETUP_START; 439 btn_count_setup = 0; 440 } 441 #endif 442 } 443 } 444 else /* Cherry Cho modified in 2008/1/15. */ 445 { 446 #ifdef WSC 447 if(WSC_ENABLED){ 448 if( !btn_addER && nvram_match("wsc_method","2") 449 && nvram_match("wsc_config_state","0")) 450 { 451 ++btn_count_setup; 452 btn_count_setup = btn_count_setup%20; 453 454 /* 0123456789 */ 455 if ((btn_count_setup%2)==0&&(btn_count_setup>10)) LED_CONTROL(LED_POWER, LED_ON); 456 else LED_CONTROL(LED_POWER, LED_OFF); 457 } 458 else if( btn_addER && nvram_match("wsc_method","2") ) 459 { 460 ++btn_count_setup; 461 btn_count_setup = btn_count_setup%6; 462 463 /* RUSHURGENT_PERIOD = 0.05 seconds 464 WPS in process: LED ON 0.2 seconds LED OFF 0.1 seconds 465 LED: 0123 ON 45 OFF */ 466 if (btn_count_setup<=3) LED_CONTROL(LED_POWER, LED_ON); 467 else LED_CONTROL(LED_POWER, LED_OFF); 468 } 469 else 470 { 471 /* Cherry Cho added in 2008/7/16. */ 472 if( !wsc_success )//WPS process fails to complete. 473 { 474 if( led_count < led_count_timeout ) 475 { 476 ++btn_count_setup; 477 btn_count_setup = btn_count_setup%4; 478 if (btn_count_setup<=1) LED_CONTROL(LED_POWER, LED_ON); 479 else LED_CONTROL(LED_POWER, LED_OFF); 480 ++led_count; 481 } 482 else 483 { 484 btn_pressed_setup = BTNSETUP_NONE; 485 btn_count_setup = 0; 486 LED_CONTROL(LED_POWER, LED_ON); 487 alarmtimer(NORMAL_PERIOD, 0); 488 led_count = 0; 489 wsc_success = 1; 490 } 491 } 492 } 493 494 /* +++ Cherry Cho added for PBC overlap in 2008/2/25. +++ */ 495 if ((btn_pressed_setup==BTNSETUP_START) && !gpio_read("/dev/gpio/in", BTN_SETUP) 496 && nvram_match("wsc_timer_start", "1") 497 && nvram_match("wsc_waiting", "1")){ 498 nvram_set("pbc_overlap", "1"); 499 } 500 /* --- Cherry Cho added for PBC overlap in 2008/2/25. --- */ 501 } 502 else /* WSC is not enabled. Cherry Cho added in 2008/7/21. */ 503 { 504 if( led_count < led_count_timeout ) 505 { 506 ++btn_count_setup; 507 btn_count_setup = btn_count_setup%2; 508 if (btn_count_setup ==1) LED_CONTROL(LED_POWER, LED_ON); 509 else LED_CONTROL(LED_POWER, LED_OFF); 510 ++led_count; 511 } 512 else 513 { 514 btn_pressed_setup = BTNSETUP_NONE; 515 btn_count_setup = 0; 516 LED_CONTROL(LED_POWER, LED_ON); 517 alarmtimer(NORMAL_PERIOD, 0); 518 led_count = 0; 519 } 520 } 521 #endif 522 } 523#endif 524} 525 526void refresh_ntpc(void) 527{ 528 eval("killall","ntpclient"); 529 kill_pidfile_s("/var/run/ntp.pid", SIGUSR1); 530 //printf("Sync time %d.\n", sync_interval); 531} 532 533int ntp_timesync(void) 534{ 535 time_t now; 536 struct tm tm; 537 struct tm gm, local; 538 struct timezone tz; 539 540 //if (nvram_match("router_disable", "1")) return 0; 541 542 if (sync_interval!=-1) 543 { 544 sync_interval--; 545 546 if (sync_interval==0) 547 { 548 /* Update kernel timezone */ 549 setenv("TZ", nvram_safe_get("time_zone_x"), 1); 550 time(&now); 551 gmtime_r(&now, &gm); 552 localtime_r(&now, &local); 553 tz.tz_minuteswest = (mktime(&gm) - mktime(&local)) / 60; 554 settimeofday(NULL, &tz); 555 memcpy(&tm, localtime(&now), sizeof(struct tm)); 556 557 if (tm.tm_year>100) // More than 2000 558 { 559 sync_interval=60*60/5; 560 logmessage("ntp client", "time is synchronized to %s", nvram_safe_get("ntp_servers")); 561 stop_upnp(); 562 start_upnp(); 563 } 564 else sync_interval=1; 565 566 refresh_ntpc(); 567 } 568 } 569} 570 571enum 572{ 573 URLACTIVE=0, 574 WEBACTIVE, 575 RADIOACTIVE, 576 ACTIVEITEMS 577} ACTIVE; 578 579int svcStatus[ACTIVEITEMS] = { -1, -1, -1}; 580int extStatus[ACTIVEITEMS] = { 0, 0, 0}; 581char svcDate[ACTIVEITEMS][10]; 582char *svcTime[ACTIVEITEMS][20]; 583 584int timecheck_item(char *activeDate, char *activeTime) 585{ 586 #define DAYSTART (0) 587 #define DAYEND (60*60*23+60*59+59) //86399 588 int current, active, activeTimeStart, activeTimeEnd, i; 589 time_t now; 590 struct tm *tm; 591 592 time(&now); 593 tm = localtime(&now); 594 current = tm->tm_hour*60 + tm->tm_min; 595 596 active=0; 597 598 //printf("active: %s %s\n", activeDate, activeTime); 599 600 activeTimeStart=((activeTime[0]-'0')*10+(activeTime[1]-'0'))*60 + (activeTime[2]-'0')*10 + (activeTime[3]-'0'); 601 602 activeTimeEnd=((activeTime[4]-'0')*10+(activeTime[5]-'0'))*60 + (activeTime[6]-'0')*10 + (activeTime[7]-'0'); 603 604 if (activeDate[tm->tm_wday] == '1') 605 { 606 if (activeTimeEnd<activeTimeStart) 607 { 608 if ((current>=activeTimeStart && current<=DAYEND) || 609 (current>=DAYSTART && current<=activeTimeEnd)) 610 { 611 active = 1; 612 } 613 else 614 { 615 active = 0; 616 } 617 } 618 else 619 { 620 if (current>=activeTimeStart && 621 current<=activeTimeEnd) 622 { 623 active = 1; 624 } 625 else 626 { 627 active = 0; 628 } 629 } 630 } 631 return(active); 632} 633 634/* Check for time-dependent service */ 635/* 1. URL filter */ 636/* 2. WEB Camera Security filter */ 637int svc_timecheck(void) 638{ 639 int activeFlag, activeNow; 640 641 activeFlag = 0; 642 643 /* Initialize */ 644 if (svcStatus[URLACTIVE]==-1 && nvram_invmatch("url_enable_x", "0")) 645 { 646 strcpy(svcDate[URLACTIVE], nvram_safe_get("url_date_x")); 647 strcpy(svcTime[URLACTIVE], nvram_safe_get("url_time_x")); 648 svcStatus[URLACTIVE] = -2; 649 } 650 651 if (svcStatus[URLACTIVE]!=-1) 652 { 653 activeNow = timecheck_item(svcDate[URLACTIVE], svcTime[URLACTIVE]); 654 if (activeNow!=svcStatus[URLACTIVE]) 655 { 656 //printf("url time change: %d\n", activeNow); 657 svcStatus[URLACTIVE] = activeNow; 658 stop_dns(); 659 start_dns(); 660 } 661 } 662 663 if (svcStatus[WEBACTIVE]==-1 && 664 nvram_invmatch("usb_webenable_x", "0") && 665 nvram_invmatch("usb_websecurity_x", "0")) 666 { 667 strcpy(svcDate[WEBACTIVE], nvram_safe_get("usb_websecurity_date_x")); 668 strcpy(svcTime[WEBACTIVE], nvram_safe_get("usb_websecurity_time_x")); 669 svcStatus[WEBACTIVE] = -2; 670 } 671 672 if (svcStatus[WEBACTIVE]!=-1) 673 { 674 activeNow = timecheck_item(svcDate[WEBACTIVE], svcTime[WEBACTIVE]); 675 if (activeNow!=svcStatus[WEBACTIVE]) 676 { 677 svcStatus[WEBACTIVE] = activeNow; 678 679 if (!notice_rcamd(svcStatus[WEBACTIVE])) svcStatus[WEBACTIVE]=-1; 680 } 681 } 682 683 if (svcStatus[RADIOACTIVE]==-1 && nvram_invmatch("wl_radio_x", "0")) 684 { 685 strcpy(svcDate[RADIOACTIVE], nvram_safe_get("wl_radio_date_x")); 686 strcpy(svcTime[RADIOACTIVE], nvram_safe_get("wl_radio_time_x")); 687 svcStatus[RADIOACTIVE] = -2; 688 } 689 690 if (svcStatus[RADIOACTIVE]!=-1) 691 { 692 activeNow = timecheck_item(svcDate[RADIOACTIVE], svcTime[RADIOACTIVE]); 693 if (activeNow!=svcStatus[RADIOACTIVE]) 694 { 695 svcStatus[RADIOACTIVE] = activeNow; 696 697 if (activeNow) 698 { 699 eval("wl", "radio", "on"); 700 wl_led_ctrl(1); 701 } 702 else 703 { 704 eval("wl", "radio", "off"); 705 wl_led_ctrl(0); 706 } 707 } 708 } 709 710 return 0; 711} 712 713/* Sometimes, httpd becomes inaccessible, try to re-run it */ 714int http_processcheck(void) 715{ 716 //char http_cmd[32]; 717 char buf[256]; 718 719 //sprintf(http_cmd, "http://127.0.0.1/"); 720 if( 721#ifdef DLM 722 !nvram_match("usb_storage_busy2", "1") && 723#endif 724#ifdef ASUS_DDNS //2007.03.27 Yau add for prevent httpd die when doing hostname check 725 !nvram_match("httpd_check_ddns", "1") && 726#endif 727 //!http_check(http_cmd, buf, sizeof(buf), 0)) 728 !http_check(NULL, buf, sizeof(buf), 0)) 729 { 730 dprintf("http rerun\n"); 731 kill_pidfile("/var/run/httpd.pid"); 732 if(nvram_match("httpd_die_reboot", "1")){ 733 nvram_set("httpd_die_reboot", ""); 734 eval("reboot"); 735 736 return 0; 737 } 738 //stop_httpd(); 739 start_httpd(); 740 } 741 742 /*if(nvram_invmatch("usb_webdriver_x", "") && 743 nvram_invmatch("usb_webdriver_x", "0")) 744 { 745 //sprintf(http_cmd, "http://127.0.0.1:%s/", nvram_safe_get("usb_webhttpport_x")); 746 //logmessage("webcam", "webcam httpd die checking %s\n", http_cmd); 747 748 if( 749#ifdef DLM 750 !nvram_match("usb_storage_busy2", "1") && 751#endif 752#ifdef ASUS_DDNS //2007.03.27 Yau add for prevent httpd die when doing hostname check 753 !nvram_match("httpd_check_ddns", "1") && 754#endif 755 //!http_check(http_cmd, buf, sizeof(buf), 0)) 756 !http_check(NULL, buf, sizeof(buf), 0)) 757 { 758 dprintf("http rerun\n"); 759 sprintf(buf, "/var/run/httpd-%s.pid", nvram_safe_get("usb_webhttpport_x")); 760 kill_pidfile(buf); 761 //logmessage("webcam", "webcam httpd rerun\n"); 762 763 chdir("/tmp/webcam"); 764 eval("httpd", nvram_safe_get("wan0_ifname"), nvram_safe_get("usb_webhttpport_x")); 765 chdir("/"); 766 } 767 }*/ 768 769 return 0; 770} 771 772/* While radius auth fails, wireless is down. We need to retry the auth */ 773int nas_processcheck() 774{ 775 FILE *fp; 776 char cfgfile[64]; 777 char pidfile[64]; 778 779 snprintf(cfgfile, sizeof(cfgfile), "/tmp/nas.%s.conf", "lan"); 780 snprintf(pidfile, sizeof(pidfile), "/tmp/nas.%s.pid", "lan"); 781 782 fp = fopen(pidfile, "r"); 783 if(fp != NULL){ 784 fclose(fp); 785 return 0; 786 } 787 788 char *argv[] = {"nas", cfgfile, pidfile, "lan", NULL}; 789 pid_t pid; 790 791 syslog(LOG_NOTICE, "Radius server authentication failed."); 792 syslog(LOG_NOTICE, "Please check the settings of radius server are correct and the radius server is available."); 793 syslog(LOG_NOTICE, "Router would try to authenticate again in seconds."); 794 sleep(5); 795 _eval(argv, NULL, 0, &pid); 796 797 return 0; 798} 799 800 801#ifdef USB_SUPPORT 802char usbinterrupt[128]; 803 804int rcamd_processcheck() 805{ 806 FILE *fp; 807 char buf[128]; 808 int flag=1; 809 810 fp = fopen("/proc/interrupts", "r"); 811 812 if (fp!=NULL) 813 { 814 while(fgets(buf, sizeof(buf), fp)) 815 { 816#ifdef WL500GX 817 if (strstr(buf, "ehci")) 818#else 819 if (strstr(buf, "ohci")) 820#endif 821 { 822 //logmessage("web camera", buf); 823 824// if (strcmp(usbinterrupt, buf)==0) flag=0; 825// strcpy(usbinterrupt, buf); 826// break; 827 } 828 } 829 fclose(fp); 830 } 831 return flag; 832} 833#endif 834 835int notice_rcamd(int flag) 836{ 837 int rcamdpid=-1; 838 //printf("Send signal : %d %d\n", rcamdpid, flag); 839 if (rcamdpid==-1) 840 { 841 FILE *fp; 842 843 if ((fp=fopen("/var/run/rcamd.pid","r"))!=NULL) 844 { 845 fscanf(fp,"%d", &rcamdpid); 846 fclose(fp); 847 } 848 } 849 if (rcamdpid!=-1) 850 { 851 if (flag) 852 kill(rcamdpid, SIGUSR1); 853 else 854 kill(rcamdpid, SIGUSR2); 855 856 return 1; 857 } 858 return 0; 859} 860 861int refresh_rcamd(void) 862{ 863 FILE *fp; 864 int rcamdpid=-1; 865 866 if ((fp=fopen("/var/run/rcamd.pid","r"))!=NULL) 867 { 868 fscanf(fp,"%d", &rcamdpid); 869 fclose(fp); 870 unlink("/var/run/rcamd.pid"); 871 kill(rcamdpid, SIGUSR1); 872 } 873 else 874 { 875 eval("killall", "rcamd"); 876 } 877 878 if ((fp=fopen("/var/run/rcamdmain.pid","r"))!=NULL) 879 { 880 fscanf(fp,"%d", &rcamdpid); 881 fclose(fp); 882 kill(rcamdpid, SIGUSR1); 883 } 884 return 0; 885} 886 887int refresh_wave(void) 888{ 889 FILE *fp; 890 int wavepid=-1; 891 892 eval("killall", "waveserver"); 893 894 if ((fp=fopen("/var/run/waveservermain.pid","r"))!=NULL) 895 { 896 fscanf(fp,"%d", &wavepid); 897 fclose(fp); 898 kill(wavepid, SIGUSR1); 899 } 900 return 0; 901} 902 903static void catch_sig(int sig) 904{ 905 if (sig == SIGUSR1) 906 { 907 dprintf("Catch Reset to Default Signal\n"); 908 //sys_default(); 909 //set_pid(getpid()); 910 } 911 else if (sig == SIGUSR2) 912 { 913 FILE *fp; 914 char command[256], *cmd_ptr; 915 916 dprintf("Get Signal: %d %d %d\n", svcStatus[WEBACTIVE], extStatus[WEBACTIVE], sig); 917 918 if (!svcStatus[WEBACTIVE]) return; 919 920 if (extStatus[WEBACTIVE]==0) 921 { 922 fp = fopen("/var/tmp/runshell", "r+"); 923 if (fp!=NULL) 924 { 925 cmd_ptr = fgets(command, 256, fp); 926 927 if (cmd_ptr!=NULL) system(command); 928 } 929 fclose(fp); 930 unlink("/tmp/runshell"); 931 notice_rcamd(0); 932 extStatus[WEBACTIVE]=1; 933 } 934 else if (svcStatus[WEBACTIVE]==1) 935 { 936 notice_rcamd(1); 937 extStatus[WEBACTIVE] = 0; 938 } 939 } 940#ifdef WSC 941 else if (sig == SIGTSTP) 942 { 943 switch(atoi(nvram_safe_get("wsc_sigtstp_case"))){ 944 case 1:/* Cherry Cho added in 2008/7/2. */ 945 if( btn_pressed_setup!=BTNSETUP_START && 946 nvram_match("wsc_client_role", "enrollee") && 947 !strcmp(nvram_safe_get("wsc_method"), "2") ) 948 { 949 btn_pressed_setup=BTNSETUP_START; 950 btn_count_setup=0; 951 alarmtimer(0, RUSHURGENT_PERIOD); 952 btn_addER = 1; 953 } 954 break; 955 956 case 2:/* WPS process successfully completes. Added for stopping LED twinkle. Cherry Cho added in 2008/2/12. */ 957 if( ( btn_pressed_setup==BTNSETUP_START )/* Reset variables when WSC process terminates. */ 958 && nvram_match("wsc_proc_status","2") ) 959 { 960 btn_pressed_setup = BTNSETUP_NONE; 961 btn_count_setup = 0; 962 LED_CONTROL(LED_POWER, LED_ON); 963 alarmtimer(NORMAL_PERIOD, 0); 964 if(btn_addER) 965 btn_addER = 0; 966 wsc_success = 1; 967 } 968 break; 969 970 case 3:/* Restart nas. Cherry Cho added in 2008/7/8. */ 971 syslog(LOG_NOTICE, "WSC: send signal to watchdog and restart nas."); 972 eval("wlconf", "eth1", "up"); 973 start_wsc(); 974 start_nas("lan"); 975 break; 976 977 case 4:/* WPS process fails to complete. Cherry Cho added in 2008/7/16.*/ 978 if(( btn_pressed_setup==BTNSETUP_START )/* Reset variables when WSC process terminates. */ 979 && ( nvram_match("wsc_proc_status","3") || nvram_match("wsc_proc_status","4") )) 980 { 981 if(btn_addER) 982 btn_addER = 0; 983 wsc_success = 0; 984 } 985 break; 986 987 default: 988 break; 989 } 990 } 991#endif 992} 993 994void sta_check(void) 995{ 996 int ret; 997 char *wl_ifname=nvram_safe_get("wl0_ifname"); 998 char bssid[32]; 999 1000 if (stacheck_interval==-1) 1001 { 1002 if (nvram_invmatch("wl0_mode", "sta") && 1003 nvram_invmatch("wl0_mode", "wet")) return; 1004 1005 stacheck_interval=STACHECK_PERIOD_DISCONNECT; 1006 } 1007 1008 stacheck_interval--; 1009 1010 if (stacheck_interval) 1011 return; 1012 1013 // Get bssid 1014 ret=wl_ioctl(wl_ifname, WLC_GET_BSSID, bssid, sizeof(bssid)); 1015 if (ret==0 && !(bssid[0]==0&&bssid[1]==0&&bssid[2]==0 1016 &&bssid[3]==0&&bssid[4]==0&&bssid[5]==0)) 1017 { 1018 dprintf("connected\n"); 1019 stacheck_interval=STACHECK_PERIOD_CONNECT; 1020 } 1021 else 1022 { 1023 dprintf("disconnected\n"); 1024 stacheck_interval=STACHECK_PERIOD_DISCONNECT; 1025 dprintf("connect: [%s]\n", nvram_safe_get("wl0_join")); 1026 system(nvram_safe_get("wl0_join")); 1027 //eval("wl", "join", nvram_safe_get("wl0_ssid")); 1028 } 1029 return; 1030} 1031 1032// 2009.12 James. { 1033#ifdef WSC 1034#define MAX_PIN_INTERVAL 120 // almost 2 mins. 1035int wps_pin_interval = 0; 1036#endif 1037// 2009.12 James. } 1038 1039/* wathchdog is runned in NORMAL_PERIOD, 1 seconds 1040 * check in each NORMAL_PERIOD 1041 * 1. button 1042 * 1043 * check in each NORAML_PERIOD*5 1044 * 1045 * 1. ntptime, 1046 * 2. time-dependent service 1047 * 3. http-process 1048 * 4. usb hotplug status 1049 */ 1050void watchdog(void) 1051{ 1052 time_t now; 1053 1054 /* handle button */ 1055 btn_check(); 1056 1057// 2009.12 James. { 1058#ifdef WSC 1059 if(nvram_match("wsc_method", "1") && nvram_match("wsc_proc_status", "1")){ 1060 if(wps_pin_interval < MAX_PIN_INTERVAL) 1061 ++wps_pin_interval; 1062 else{ 1063 wps_pin_interval = 0; 1064 nvram_set("wsc_config_command", "2"); // Be timeout and turned off PIN process immediately. 1065 } 1066 } 1067#endif 1068// 2009.12 James. } 1069 1070#ifdef WCN 1071 if(nvram_match("reboot_WCN", "1")) 1072 { 1073 ++reboot_WCN_count; 1074 1075 if(reboot_WCN_count>=50) 1076 kill(1, SIGTERM); 1077 else 1078 return; 1079 } 1080 else if(nvram_match("reboot_WCN", "2")) 1081 { 1082 nvram_commit(); 1083 alarmtimer(0, QUICK_PERIOD); 1084 wcn_on=1; 1085 nvram_set("reboot_WCN", "1"); 1086 return; 1087 } 1088#endif 1089 1090 /* if timer is set to less than 1 sec, then bypass the following */ 1091 if (itv.it_value.tv_sec==0) return; 1092 1093#if 0 1094 if (nvram_match("eject_from_web", "1")) 1095 { 1096 nvram_set("eject_from_web", "0"); 1097 eval("run_ftpsamba"); 1098 } 1099#endif 1100 // reboot signal checking 1101 if(nvram_match("reboot", "1")) 1102 { 1103 ++reboot_count; 1104 if(reboot_count>=2) kill(1, SIGTERM); 1105 } 1106 else if(nvram_match("reboot", "0")) return; 1107 1108 watchdog_period = (watchdog_period+1)%10; 1109 1110 if(watchdog_period) return; 1111 1112 time(&now); 1113 1114#ifdef BTN_SETUP 1115 if (btn_pressed_setup>=BTNSETUP_START) return; 1116#endif 1117 //printf("now: %d\n", (long )now); 1118 /* sync time to ntp server if necessary */ 1119 ntp_timesync(); 1120 1121 /* check for time-dependent services */ 1122 svc_timecheck(); 1123 1124 /* http server check */ 1125#ifdef DLM 1126 if (!nvram_match("usb_storage_busy2", "1")) 1127#endif 1128 http_processcheck(); 1129 1130 /* nas check for radius fail auth */ 1131 if (int_nas_enable){ 1132 if(nas_check_interval > 7){ 1133 nas_check_interval = 0; 1134 nas_processcheck(); 1135 } 1136 else 1137 ++nas_check_interval; 1138 } 1139 1140#ifdef USB_SUPPORT 1141 1142 /* web cam process */ 1143 if (!nvram_match("usb_web_device", "")) 1144 { 1145 if (!nvram_match("usb_webdriver_x", "")) 1146 { 1147 if (!rcamd_processcheck()) 1148 { 1149 refresh_rcamd(); 1150 } 1151 } 1152 else 1153 { 1154 //hotplug_usb_webcam(nvram_safe_get("usb_web_device"), 1155 // atoi(nvram_safe_get("usb_web_flag"))); 1156 //nvram_set("usb_web_device", ""); 1157 //nvram_set("usb_web_flag", ""); 1158 // reset WEBCAM status 1159 refresh_rcamd(); 1160 svcStatus[WEBACTIVE] = -1; 1161 } 1162 } 1163 1164 /* storage process */ 1165// 2007.12 James { 1166 char *remove_disk = nvram_safe_get("usb_storage_device_remove"); 1167 char *add_disk = nvram_safe_get("usb_storage_device"); 1168 1169 if(strlen(remove_disk) > 0){ 1170printf("*** start to remove usb disk. ***\n"); 1171 nvram_set("usb_storage_busy", "1"); // 2007.12 James 1172 remove_usb_mass(remove_disk); 1173 nvram_set("usb_storage_busy", "0"); // 2007.12 James 1174printf("*** end to remove usb disk. ***\n"); 1175 } 1176 else if(strlen(add_disk) > 0){ 1177printf("*** start to add usb disk. ***\n"); 1178 nvram_set("usb_storage_busy", "1"); // 2007.12 James 1179 hotplug_usb_mass(add_disk); 1180 nvram_set("usb_storage_busy", "0"); // 2007.12 James 1181printf("*** end to add usb disk. ***\n"); 1182 } 1183// 2007.12 James } 1184 1185#endif 1186 1187 /* station or ethernet bridge handler */ 1188 sta_check(); 1189 1190#ifdef CDMA 1191 if(!nvram_match("hsdpa_product", "")){ 1192 /* 1193 * cdma_down = 99, none 1194 * cdma_down = 1, currently down 1195 * cdma_down = 2, currently up 1196 * cdma_down = 3, Stop 1197 * cdma_down = 0, currently trying to connect 1198 */ 1199 if (nvram_match("cdma_down", "1")) 1200 { 1201 logmessage("CDMA client", "USB Modem was down(%d)!", cdma_down); // HSDPA 1202 1203 ++cdma_down; 1204 cdma_connect=0; 1205 1206 //if(cdma_down==2) 1207 if(cdma_down==1) 1208 { 1209 stop_wan(); 1210 start_wan(); 1211 } 1212 else if(cdma_down >= 2) // 20 seconds timeout for retry 1213 { 1214 cdma_down=0; 1215 } 1216 } 1217 else if(nvram_match("cdma_down", "0")) 1218 { 1219 //if(cdma_connect%3==0) // HSDPA 1220 logmessage("CDMA client", "USB Modem: Try to connect(%d)!", cdma_connect+1); // HSDPA 1221 cdma_down=0; 1222 ++cdma_connect; 1223 1224 if(cdma_connect >= 2) /* 20 seconds timeout for connecting */ // HSDPA 1225 { 1226 nvram_set("cdma_down", "1"); 1227 } 1228 } 1229 else if (nvram_match("cdma_down", "3")) 1230 { 1231 //logmessage("CDMA client", "USB Modem is down(%d)!", cdma_down); // HSDPA 1232 eval("killall", "chat"); 1233 eval("killall", "pppd"); 1234 } 1235 else 1236 { 1237 cdma_down=0; 1238 cdma_connect=0; 1239 } 1240 } 1241#endif 1242} 1243 1244int 1245gpio_main(int ledin) 1246{ 1247#ifdef BTN_SETUP 1248 printf("BTN:%d,%d\n", gpio_read("/dev/gpio/in", BTN_RESET), gpio_read("/dev/gpio/in", BTN_SETUP)); 1249#else 1250 printf("BTN:%d,0\n", gpio_read("/dev/gpio/in", BTN_RESET)); 1251#endif 1252} 1253 1254int 1255watchdog_main(int argc, char *argv[]) 1256{ 1257 FILE *fp; 1258#ifdef WSC/* Cherry Cho added in 2008/7/16. */ 1259 WSC_ENABLED = nvram_match("wsc_mode", "enabled"); 1260#endif 1261 1262#ifdef REMOVE 1263 /* Run it under background */ 1264 switch (fork()) { 1265 case -1: 1266 exit(0); 1267 break; 1268 case 0: 1269 // start in a new session 1270 (void) setsid(); 1271 break; 1272 default: 1273 /* parent process should just die */ 1274 _exit(0); 1275 } 1276#endif 1277 1278 /* write pid */ 1279 if ((fp=fopen("/var/run/watchdog.pid", "w"))!=NULL) 1280 { 1281 fprintf(fp, "%d", getpid()); 1282 fclose(fp); 1283 } 1284 1285 /* set the signal handler */ 1286 signal(SIGUSR1, catch_sig); 1287 signal(SIGUSR2, catch_sig); 1288 signal(SIGTSTP, catch_sig);/* Cherry Cho added in 2008/2/12 */ 1289 signal(SIGALRM, watchdog); 1290 1291 /* Start GPIO function */ 1292 gpio_init(); 1293 1294 /* Start POWER LED */ 1295 LED_CONTROL(LED_POWER, LED_ON); 1296// MFG test LED off for MFG USB test 1297// LED_CONTROL(LED_POWER, LED_OFF); 1298//end MFG 1299 1300 /* Start sync time */ 1301 sync_interval=1; 1302 start_ntpc(); 1303 1304#ifdef BTN_SETUP 1305 if (!nvram_match("sharedkeystr", "")) 1306 { 1307 printf("Debug::sharedkeystr=%s\n", nvram_get("sharedkeystr")); 1308 ++btn_pressed_flag; 1309 btn_stage=1; 1310 } 1311 nvram_set("bs_mode", ""); 1312#endif 1313 1314 /* nas check for radius fail auth */ 1315 if(nvram_match("wl0_akm", "wpa" ) // WPA-Enterprise 1316 || nvram_match("wl0_akm", "wpa2" ) // WPA2-Enterprise 1317 || nvram_match("wl0_akm", "wpa wpa2" ) // WPA-Auto-Enterprise 1318 || nvram_match("wl0_auth_mode", "radius" ) // Radius with 802.1x 1319 ) 1320 int_nas_enable = 1; 1321 1322 /* set timer */ 1323 alarmtimer(NORMAL_PERIOD, 0); 1324 1325 /* Most of time it goes to sleep */ 1326 while(1) 1327 { 1328 pause(); 1329 } 1330 1331 return 0; 1332} 1333 1334#define LED_RADIO GPIO1 1335 1336void wl_led_ctrl(int ctrl) 1337{ 1338 int led; 1339 if (!ctrl) 1340 { 1341 gpio_write("/dev/gpio/out", LED_RADIO, !ctrl); 1342 led=0; 1343 wl_ioctl("eth2", WLC_SET_LED, &led, sizeof(led)); 1344 } 1345 else 1346 { 1347 tgpio_fd_init(); 1348 tgpio_ioctl(BCMGPIO_REG_RELEASE, LED_RADIO, LED_RADIO); 1349 tgpio_fd_cleanup(); 1350 } 1351} 1352 1353int radio_main(int ctrl) 1354{ 1355 if (ctrl) 1356 { 1357 eval("wl", "radio", "on"); 1358 wl_led_ctrl(1); 1359 } 1360 else 1361 { 1362 eval("wl", "radio", "off"); 1363 wl_led_ctrl(0); 1364 } 1365} 1366