4 Copyright (C) 2006-2009 Jonathan Zarate
9 #include <sys/reboot.h>
14 #include <linux_gpio.h>
15 #include <sys/socket.h>
16 #include <sys/ioctl.h>
24 static uint32_t _gpio_read(void)
30 return (read(gf
, &v
, sizeof(v
)) == sizeof(v
)) ? v
: ~0;
34 static int get_btn(const char *name
, uint32_t *bit
, uint32_t *pushed
)
39 if (nvget_gpio(name
, &gpio
, &inv
)) {
41 *pushed
= inv
? 0 : *bit
;
47 int buttons_main(int argc
, char *argv
[])
55 uint32_t reset_pushed
;
64 ses_mask
= ses_pushed
= 0;
71 switch (nvram_get_int("btn_override") ? MODEL_UNKNOWN
: get_model()) {
89 case MODEL_WHR2A54G54
:
92 reset_mask
= reset_pushed
= 1 << 4;
97 reset_mask
= reset_pushed
= 1 << 4;
100 reset_mask
= reset_pushed
= 1 << 7;
101 ses_mask
= ses_pushed
= 1 << 4;
107 case MODEL_WZRRSG54HP
:
109 reset_mask
= reset_pushed
= 1 << 4;
114 reset_mask
= reset_pushed
= 1 << 7;
126 reset_mask
= reset_pushed
= 1 << 0;
127 ses_mask
= ses_pushed
= 1 << 4;
134 //? reset_mask = reset_pushed = 1 << 7;
137 reset_mask
= reset_pushed
= 1 << 7;
140 get_btn("btn_ses", &ses_mask
, &ses_pushed
);
141 if (!get_btn("btn_reset", &reset_mask
, &reset_pushed
)) {
142 // fprintf(stderr, "Not supported.\n");
147 mask
= reset_mask
| ses_mask
| brau_mask
;
150 cprintf("reset_mask=0x%X reset_pushed=0x%X\n", reset_mask
, reset_pushed
);
151 cprintf("ses_mask=0x%X\n", ses_mask
);
152 cprintf("brau_mask=0x%X\n", brau_mask
);
153 cprintf("ses_led=%d\n", ses_led
);
155 if (fork() != 0) return 0;
159 signal(SIGCHLD
, handle_reap
);
164 if ((gf
= open("/dev/gpio/in", O_RDONLY
|O_SYNC
)) < 0) return 1;
169 if (((gpio
= _gpio_read()) == ~0) || (last
== (gpio
&= mask
)) || (check_action() != ACT_IDLE
)) {
171 cprintf("gpio = %X\n", gpio
);
177 if ((gpio
& reset_mask
) == reset_pushed
) {
179 cprintf("reset down\n");
187 if (++count
== 3) led(LED_DIAG
, 1);
188 } while (((gpio
= _gpio_read()) != ~0) && ((gpio
& reset_mask
) == reset_pushed
));
191 cprintf("reset count = %d\n", count
);
194 nvram_set("restore_defaults", "1");
201 set_action(ACT_REBOOT
);
208 if ((ses_mask
) && ((gpio
& ses_mask
) == ses_pushed
)) {
211 // syslog(LOG_DEBUG, "ses-pushed: gpio=x%X, pushed=x%X, mask=x%X, count=%d", gpio, ses_pushed, ses_mask, count);
213 led(ses_led
, LED_ON
);
215 led(ses_led
, LED_OFF
);
218 } while (((gpio
= _gpio_read()) != ~0) && ((gpio
& ses_mask
) == ses_pushed
));
221 if ((ses_led
== LED_DMZ
) && (nvram_get_int("dmz_enable") > 0)) led(LED_DMZ
, 1);
223 // syslog(LOG_DEBUG, "ses-released: gpio=x%X, pushed=x%X, mask=x%X, count=%d", gpio, ses_pushed, ses_mask, count);
224 syslog(LOG_INFO
, "SES pushed. Count was %d.", count
);
226 if ((count
!= 3) && (count
!= 7) && (count
!= 11)) {
237 cprintf("ses func=%d\n", n
);
239 sprintf(s
, "sesx_b%d", n
);
240 // syslog(LOG_DEBUG, "ses-func: count=%d %s='%s'", count, s, nvram_safe_get(s));
241 if ((p
= nvram_get(s
)) != NULL
) {
243 case '1': // toggle wl
244 nvram_set("rrules_radio", "-1");
245 eval("radio", "toggle");
250 case '3': // shutdown
253 case '4': // run a script
254 sprintf(s
, "%d", count
);
255 run_nvscript("sesx_script", s
, 2);
265 last
= (gpio
& brau_mask
);
266 if (brau_state
!= last
) {
268 p
= brau_state
? "auto" : "bridge";
269 nvram_set("brau_state", p
);
271 cprintf("bridge/auto state = %s\n", p
);
273 run_nvscript("script_brau", p
, 2);