source: src/router/rc/resetbutton.c @ 7584

Last change on this file since 7584 was 7584, checked in by eko, 6 years ago

cosmetic /buffalo

File size: 13.1 KB
Line 
1
2#include <stdio.h>
3#include <signal.h>
4#include <sys/time.h>
5#include <unistd.h>
6#include <stdlib.h>
7#include <sys/types.h>
8#include <string.h>
9#include <bcmnvram.h>
10#include <shutils.h>
11#include <utils.h>
12#include <rc.h>
13#include <stdarg.h>
14#include <dirent.h>
15#include <syslog.h>
16
17
18
19#define SES_LED_CHECK_TIMES     "9999"  /* How many times to check? */
20#define SES_LED_CHECK_INTERVAL  "1"     /* Wait interval seconds */
21#define RESET_WAIT              1       /* seconds */
22#define RESET_WAIT_COUNT        RESET_WAIT * 10 /* 10 times a second */
23
24#define NORMAL_INTERVAL         1       /* second */
25#define URGENT_INTERVAL         100 * 1000      /* microsecond */
26
27#ifndef HAVE_GATEWORX           /* 1/10 second */
28#define GPIO_FILE               "/dev/gpio/in"
29#endif
30#if 0
31#define DEBUG printf
32#else
33#define DEBUG(format, args...)
34#endif
35
36
37
38#ifdef HAVE_MAGICBOX
39#include <sys/mman.h>
40
41#define GPIO0_OR   0x0700       /* rw, output */
42#define GPIO0_TCR  0x0704       /* rw, three-state control */
43#define GPIO0_ODR  0x0718       /* rw, open drain */
44#define GPIO0_IR   0x071c       /* ro, input */
45#define GPIO0_BASE 0xef600000   /* page */
46
47#define GPIO_LED    0x20000000  /* GPIO1 */
48#define GPIO_BUTTON 0x40000000  /* GPIO2 */
49
50#define REG(buf, offset) ((unsigned int *)((void *)buf + offset))
51
52static unsigned int *page;
53static int fd;
54
55void
56init_gpio ()
57{
58  void *start = 0;
59
60  fd = open ("/dev/mem", O_RDWR);
61  if (fd < 0)
62    {
63//        syslog(LOG_ERR, "Can't open /dev/mem: %s", strerror(errno));
64      exit (1);
65    }
66
67  page = mmap (start, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
68               (off_t) GPIO0_BASE);
69  if (page == MAP_FAILED)
70    {
71//        syslog(LOG_ERR, "Can't mmap GPIO memory space: %s", strerror(errno));
72      exit (1);
73    }
74
75  /* disable */
76  *REG (page, GPIO0_TCR) &= ~(GPIO_LED | GPIO_BUTTON);
77  /* enable led */
78  *REG (page, GPIO0_TCR) |= GPIO_LED | GPIO_BUTTON;
79  /* enable/disable(?) button */
80  *REG (page, GPIO0_TCR) &= ~GPIO_BUTTON;
81
82  *REG (page, GPIO0_IR) & GPIO_BUTTON;
83  *REG (page, GPIO0_IR) & GPIO_BUTTON;
84
85}
86
87int
88getbuttonstate ()
89{
90  return (*REG (page, GPIO0_IR) & GPIO_BUTTON) == 0;
91
92}
93#endif
94
95#if defined(HAVE_FONERA) || defined(HAVE_WHRAG108) || defined(HAVE_LS2) || defined(HAVE_CA8)
96int
97getbuttonstate ()
98{
99  FILE *in;
100  int ret;
101  in = fopen ("/proc/gpio/6_in", "rb");
102  if (in == NULL)
103    return 0;
104  fscanf (in, "%d", &ret);
105  fclose (in);
106  return ret;
107}
108#endif
109#if defined(HAVE_GATEWORX)
110
111#define u8 unsigned char
112#define u32 unsigned long
113
114//#include <linux/ixp425-gpio.h>
115
116#include <include/asm/hardware.h>
117#include <include/asm-arm/arch-ixp4xx/ixp4xx-regs.h>
118
119#define IXP4XX_GPIO_OUT                 0x1
120#define IXP4XX_GPIO_IN                  0x2
121
122struct gpio_bit
123{
124  unsigned char bit;
125  unsigned char state;
126};
127
128
129
130char *filename = "/dev/gpio";
131
132
133int
134read_bit (int bit)
135{
136  int file;
137  struct gpio_bit _bit;
138
139  /* open device */
140  if ((file = open (filename, O_RDONLY)) == -1)
141    {
142      /* ERROR HANDLING; you can check errno to see what went wrong */
143      return 1;
144    }
145
146  /* Config pin as input */
147  _bit.bit = bit;
148  _bit.state = IXP4XX_GPIO_IN;
149  if (ioctl (file, GPIO_SET_CONFIG, (long) &_bit) < 0)
150    {
151      /* ERROR HANDLING; you can check errno to see what went wrong */
152      return 1;
153    }
154
155  /* Read data */
156  _bit.bit = bit;
157  if (ioctl (file, GPIO_GET_BIT, (long) &_bit) < 0)
158    {
159      /* ERROR HANDLING; you can check errno to see what went wrong */
160      return 1;
161    }
162
163  close (file);
164  return _bit.state;
165}
166
167int
168getbuttonstate ()
169{
170  FILE *in;
171  int ret = read_bit (4);
172  return ret == 0 ? 1 : 0;
173}
174#endif
175
176
177static int mode = 0;            /* mode 1 : pushed */
178static int ses_mode = 0;        /* mode 1 : pushed */
179static int count = 0;
180
181static int brand;
182
183static void
184alarmtimer (unsigned long sec, unsigned long usec)
185{
186  struct itimerval itv;
187
188  itv.it_value.tv_sec = sec;
189  itv.it_value.tv_usec = usec;
190
191  itv.it_interval = itv.it_value;
192  setitimer (ITIMER_REAL, &itv, NULL);
193}
194
195int
196endswith (char *str, char *cmp)
197{
198  int cmp_len, str_len, i;
199  cmp_len = strlen (cmp);
200  str_len = strlen (str);
201  if (cmp_len > str_len)
202    return (0);
203  for (i = 0; i < cmp_len; i++)
204    {
205      if (str[(str_len - 1) - i] != cmp[(cmp_len - 1) - i])
206        return (0);
207    }
208  return (1);
209}
210
211void
212runStartup (char *folder, char *extension)
213{
214  struct dirent *entry;
215  DIR *directory;
216  unsigned char buf[128];
217  directory = opendir (folder);
218  if (directory == NULL)
219    {
220      return;
221    }
222//list all files in this directory
223  while ((entry = readdir (directory)) != NULL)
224    {
225      if (endswith (entry->d_name, extension))
226        {
227          sprintf (buf, "%s/%s&\n", folder, entry->d_name);
228          //execute script     
229          system (buf);
230        }
231    }
232  closedir (directory);
233}
234
235/*
236void system_reboot(void)
237{
238        DEBUG("resetbutton: reboot\n");
239        alarmtimer(0, 0);
240        eval("reboot");
241}
242*/
243
244void
245service_restart (void)
246{
247  DEBUG ("resetbutton: restart\n");
248  /* Stop the timer alarm */
249  alarmtimer (0, 0);
250  /* Reset the Diagnostic LED */
251  diag_led (DIAG, START_LED);   /* call from service.c */
252  /* Restart all of services */
253  eval ("rc", "restart");
254}
255
256
257void
258period_check (int sig)
259{
260  FILE *fp;
261  unsigned int val = 0;
262//      time_t t;
263
264//      time(&t);
265//      DEBUG("resetbutton: now time=%d\n", t);
266
267#if defined(HAVE_MAGICBOX) || defined(HAVE_FONERA) || defined(HAVE_WHRAG108) || defined(HAVE_GATEWORX) || defined(HAVE_LS2) || defined(HAVE_CA8)
268  val = getbuttonstate ();
269#else
270  if ((fp = fopen (GPIO_FILE, "r")))
271    {
272#ifdef HAVE_XSCALE
273      fscanf (fp, "%d", &val);
274#else
275      fread (&val, 4, 1, fp);
276#endif
277      fclose (fp);
278    }
279  else
280    perror (GPIO_FILE);
281#endif
282  DEBUG ("resetbutton: GPIO = 0x%x\n", val);
283
284  int gpio = 0;
285
286  int state = 0;
287#if defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || defined(HAVE_FONERA) || defined(HAVE_WHRAG108) || defined(HAVE_GATEWORX) || defined(HAVE_LS2) || defined(HAVE_CA8)
288  state = val;
289#else
290  if ((brand & 0x000f) != 0x000f)
291    gpio = 1 << (brand & 0x000f);       //calculate gpio value.
292
293  if ((brand & 0x0010) == 0)    //check reset button polarity: 0 normal, 1 inversed
294    state = (val & gpio);
295  else
296    state = !(val & gpio);
297
298/* 1 byte router's SES (AOSS) button gpio number and polarity; Eko 25.nov.06
299
300  R R R P N N N N   = 0xXX
301  ----- - -------
302    |   | gpio num (1111 = f = disable SES (AOSS) button)
303    |   |
304    |   |--- SES - AOSS button polarity (0: normal, 1 inversed)
305    |
306    |-------- reserved for future use
307*/
308  int push;
309  int sesgpio;
310  switch (brand)
311    {
312    case ROUTER_BUFFALO_WHRG54S:
313    case ROUTER_BUFFALO_WZRRSG54:
314    case ROUTER_BUFFALO_WLI_TX4_G54HP:
315      sesgpio = 0x10;           //gpio 0, inversed
316      break;
317    case ROUTER_BUFFALO_WLA2G54C:
318      sesgpio = 0x12;           //gpio 2, inversed
319      break;
320    case ROUTER_BUFFALO_WBR2G54S:     
321      sesgpio = 0x04;           //gpio 4, normal
322      break;     
323#ifndef HAVE_BUFFALO     
324    case ROUTER_WRT54G:
325    case ROUTER_WRT300N:
326      sesgpio = 0x14;           //gpio 4, inversed
327      break;
328    case ROUTER_ASUS_WL500G_PRE:
329    case ROUTER_WRT150N:
330      sesgpio = 0x04;           //gpio 4, normal
331      break;
332    case ROUTER_WRT350N:
333      sesgpio = 0x18;           //gpio 8, inversed
334      break;
335#endif
336    default:
337      sesgpio = 0x0f;           //gpio unknown, disabled
338    }
339
340  push = 1 << (sesgpio & 0x0f); //calculate push value from ses gpio pin no.
341
342#endif
343  /*  The value is zero during button-pushed. */
344  if (state)
345    {
346      DEBUG ("resetbutton: mode=%d, count=%d\n", mode, count);
347
348      if (mode == 0)
349        {
350          /* We detect button pushed first time */
351          alarmtimer (0, URGENT_INTERVAL);
352          mode = 1;
353        }
354      {                         /* Whenever it is pushed steady */
355        if (++count > RESET_WAIT_COUNT)
356          {
357            if (check_action () != ACT_IDLE)
358              {                 // Don't execute during upgrading
359                fprintf (stderr, "resetbutton: nothing to do...\n");
360                alarmtimer (0, 0);      /* Stop the timer alarm */
361                return;
362              }
363            if ((brand & 0x000f) != 0x000f)
364              {
365                printf ("resetbutton: factory default.\n");
366                syslog (LOG_DEBUG,
367                        "Reset button: restoring factory defaults now!\n");
368#if !defined(HAVE_XSCALE) && !defined(HAVE_MAGICBOX) && !defined(HAVE_FONERA) && !defined(HAVE_WHRAG108) && !defined(HAVE_GATEWORX) && !defined(HAVE_LS2) && !defined(HAVE_CA8)
369                led_control (LED_DIAG, LED_ON);
370#endif
371                ACTION ("ACT_HW_RESTORE");
372                alarmtimer (0, 0);      /* Stop the timer alarm */
373#ifdef HAVE_X86
374                eval ("mount", "/usr/local", "-o", "remount,rw");
375                eval ("rm", "-f", "/tmp/nvram/*");      // delete nvram database
376                eval ("rm", "-f", "/tmp/nvram/.lock");  // delete nvram database
377                eval ("rm", "-f", "/usr/local/nvram/*");        // delete nvram database
378                eval ("mount", "/usr/local", "-o", "remount,ro");
379#elif HAVE_RB500
380                eval ("rm", "-f", "/tmp/nvram/*");      // delete nvram database
381                eval ("rm", "-f", "/tmp/nvram/.lock");  // delete nvram database
382                eval ("rm", "-f", "/etc/nvram/*");      // delete nvram database
383#elif HAVE_MAGICBOX
384                eval ("rm", "-f", "/tmp/nvram/*");      // delete nvram database
385                eval ("rm", "-f", "/tmp/nvram/.lock");  // delete nvram database
386                eval ("erase", "nvram");
387#else
388                nvram_set ("sv_restore_defaults", "1");
389                nvram_commit ();
390                eval ("erase", "nvram");
391#endif
392
393
394//                nvram_set ("sv_restore_defaults", "1");
395//                nvram_commit ();
396
397
398
399                kill (1, SIGTERM);
400              }
401          }
402      }
403    }
404#if !defined(HAVE_XSCALE) && !defined(HAVE_MAGICBOX) && !defined(HAVE_FONERA) && !defined(HAVE_WHRAG108) && !defined(HAVE_GATEWORX) && !defined(HAVE_LS2) && !defined(HAVE_CA8)
405
406  else if ((sesgpio != 0x0f)
407           && (((sesgpio & 0x10) == 0 && (val & push))
408               || ((sesgpio & 0x10) == 0x10 && !(val & push))))
409    {
410      runStartup ("/etc/config", ".sesbutton");
411      runStartup ("/jffs/etc/config", ".sesbutton");    //if available
412      runStartup ("/mmc/etc/config", ".sesbutton");     //if available
413      runStartup ("/tmp/etc/config", ".sesbutton");     //if available
414
415      if (ses_mode == 1)
416        {
417#ifdef HAVE_RADIOOFF
418          if (nvram_match ("radiooff_button", "1"))
419            {
420              eval ("wl", "radio", "on");
421#ifndef HAVE_BUFFALO
422              syslog (LOG_DEBUG,
423                      "SES /AOSS /EZ-setup button: turning radio on\n");
424#else
425              syslog (LOG_DEBUG,
426                      "AOSS button: turning radio on\n");
427#endif
428            }
429#endif
430
431//              led_control (LED_SES, LED_OFF);         
432//              led_control (LED_SES2, LED_ON);         //enable orange led
433          led_control (LED_SES, LED_FLASH);     //when pressed, blink white SES (AOSS) led
434
435//      switch (brand)
436//              {
437//              case ROUTER_WRT54G:
438//              case ROUTER_WRTSL54GS:
439//                      ses_mode = 2;
440//              break;
441//              default:
442          ses_mode = 0;
443//              }
444
445        }
446      else if (ses_mode == 0)
447        {
448#ifdef HAVE_RADIOOFF
449          if (nvram_match ("radiooff_button", "1"))
450            {
451              eval ("wl", "radio", "off");
452#ifndef HAVE_BUFFALO
453              syslog (LOG_DEBUG,
454                      "SES /AOSS /EZ-setup button: turning radio off\n");
455#else
456              syslog (LOG_DEBUG,
457                      "AOSS button: turning radio off\n");
458#endif
459            }
460#endif
461//              led_control (LED_SES, LED_ON);          //enable white led
462//              led_control (LED_SES2, LED_OFF);
463          led_control (LED_SES, LED_FLASH);     //when pressed, blink white SES (AOSS) led
464
465          ses_mode = 1;
466
467        }
468/*      else if (ses_mode == 2)
469        {
470#ifdef HAVE_RADIOOFF
471          if (nvram_match ("radiooff_button", "1"))
472            eval ("wl", "radio", "on");
473#endif
474
475                led_control (LED_SES, LED_ON);          //both leds on
476                led_control (LED_SES2, LED_ON);
477
478                ses_mode = 3;
479               
480        }
481      else if (ses_mode == 3)
482        {
483#ifdef HAVE_RADIOOFF
484          if (nvram_match ("radiooff_button", "1"))
485            eval ("wl", "radio", "off");
486#endif
487                led_control (LED_SES, LED_OFF);         //both leds off
488                led_control (LED_SES2, LED_OFF);
489
490                ses_mode = 0;
491               
492        }
493*/
494
495      /*
496         char *led_argv[] = { "check_ses_led",
497         SES_LED_CHECK_TIMES,
498         SES_LED_CHECK_INTERVAL,
499         NULL
500         };
501         pid_t pid;
502
503         if(!is_exist("/tmp/EnablePushButton"))       
504         return;
505
506         ses_mode = 1;
507         eval("killall", "check_ses_led");
508         _eval(led_argv, NULL, 0, &pid); */
509
510    }
511#endif
512  else
513    {
514
515      /* Although it's unpushed now, it had ever been pushed */
516      if (mode == 1)
517        {
518          if (check_action () != ACT_IDLE)
519            {                   // Don't execute during upgrading
520              fprintf (stderr, "resetbutton: nothing to do...\n");
521              alarmtimer (0, 0);        /* Stop the timer alarm */
522              return;
523            }
524          service_restart ();
525        }
526      /*
527         if( ses_mode == 1 ){
528         cprintf("Release SES push button\n");
529         eval("sendudp", "-i", nvram_safe_get("lan_ifname"),
530         "-s", nvram_safe_get("lan_ipaddr"),
531         "-d", nvram_safe_get("http_client_ip"),
532         "-m", nvram_safe_get("lan_hwaddr"),
533         "-p", "9999",
534         "LED TEST FINISH");
535         ses_mode = 0;
536         } */
537    }
538}
539
540int
541resetbutton_main (int argc, char *argv[])
542{
543
544  brand = getRouterBrand ();
545
546  if ((brand & 0x000f) == 0x000f)
547
548    {
549      puts ("sorry, your unit does not support resetbutton feature\n");
550      return 0;
551    }
552#ifdef HAVE_MAGICBOX
553  init_gpio ();
554#endif
555  /* Run it under background */
556  switch (fork ())
557    {
558    case -1:
559      DEBUG ("can't fork\n");
560      exit (0);
561      break;
562    case 0:
563      /* child process */
564      DEBUG ("fork ok\n");
565      (void) setsid ();
566      break;
567    default:
568      /* parent process should just die */
569      _exit (0);
570    }
571
572  /* set the signal handler */
573  signal (SIGALRM, period_check);
574
575  /* set timer */
576  alarmtimer (NORMAL_INTERVAL, 0);
577
578  /* Most of time it goes to sleep */
579  while (1)
580    pause ();
581
582  return 0;
583}
Note: See TracBrowser for help on using the repository browser.