OpenWrt Forum Archive

Topic: Script to read a number using the reset button

The content of this topic has been archived on 10 Mar 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi!

I've written a nice script which can read a number using input from reset button ;-). I think it can be useful for someone, so I post it here.

To see how it works, run the script, press your reset button for about 1-2 seconds and release it after DMZ led switches on. Then power led should start to blink. Now you have to enter the number - simply by pushing the button - watch DMZ led to be sure it "gets" your input. After your done, wait for about 5 seconds and watch the script output on your console. Simply magic ;-).

Hope somebody else finds it useful tongue.

I was wondering about this, but the script seems to be lost.  Could you possibly repost it? 

Thanks.

* there is a button demon software in original linksys firmware.
* it could be nice to have a script or deamon that handle that to,
* LED feedback shoud be good to help in counting resets,
* in script mode, busybox usleep should help.

I have also writen a similar script. A init.d script could wait like this :

reset_count=$(reset_count_script)

switch($reset_count){

case 1 :
    # do something (reconfigure network for example)
    break;

case 2 :
    # do something
    reboot;
    break;

case 3:
    reconfigure ...

case 4:
    rerun telnetd

case 5:
    # reset nvram

case 6:
    # force boot_wait flag
    nvram set boot_wait=on ; nvram commit

case 7:
    # configure lan to default 192.168.1.1
    ifconfig ...

  ...
}

(Last edited by _marc_ on 13 Jun 2005, 13:45)

I have a wrt54gs with the front button, which uses gpio pin 4.  Since its not available in /proc/sys, I was wondering if there is another way to read the pin status.  I tried gpio, but it only reads in a polling loop...

I could modify gpio I suppose...

(ludicrous) suggestion:

Make the script to accept a morse-like code so you can enter shell commands into the wrt without
using a serial terminal or computer ...

To carry this idea further, OpenWRT in his default configuration could come with some filter scripts, that filter the stdout output of common commands (like ifconfig, route, and so on), to make
them shorter and suitable for morse transmission using a LED at the front.

Now no one will complain about bricked routers any longer smile

netprince mentioned that there was no /proc/sys entry for the front button on the new WRT54GS v2.1... so I modded the kernel module to include support for this new button and LEDs... you can grab a copy of my diag_led.c from http://www.intherack.com/random-stuff/diag_led.c or if you're lazy and don't want to compile it yourself, you can pick up a prebuilt replacement to install into /lib/modules/2.4.30/ on the current WhiteRussian RC2 build from http://www.intherack.com/random-stuff/diag.o .... This will create a /proc/sys/ciscobutton that works just like the ./reset one, and adds 0x02 and 0x08 to /proc/sys/diag to turn the button orange or white respectively.

we need polling reset button to read it's walue. Is this polling really needed , because it' time consuming ?

I installed the module codepoet82 modified, and it works well.  I can now turn on and off my wireless radio by pressing the cisco button on the front panel.

Thanks codepoet82.

(Last edited by netprince on 8 Aug 2005, 13:46)

netprince wrote:

I was wondering about this, but the script seems to be lost.  Could you possibly repost it?

Sure, it must have been lost when OpenWRT project website moved to new forum engine (I suppose).

Here it is:

--- setnr - can be run as a daemon (&) ---
#!/bin/sh

while [ true ]; do
  if [ `cat /proc/sys/reset` = "1" ]; then
    echo "0x01" > /proc/sys/diag
    while true; do
      [ `cat /proc/sys/reset` = "0" ] && break
    done
    echo "0x00" > /proc/sys/diag

    /bin/setnr-actions
  fi

  sleep 1
done
---

--- setnr-actions ---
#!/bin/sh

. /bin/setnr-functions

case "`get_nr_1`" in
  1) save_and_reboot ;;
  2) router_number ;;
  3) peer_number ;;
  4) channel_number ;;
  5) pppoe_enable ;;
  6) /etc/init.d/S45firewall stop ;;
  7) /etc/init.d/S53olsrd restart ;;
  8) ping_test ;;
esac
---

--- setnr-functions ---
#!/bin/sh

### FUNCTIONS
get_nr_1() {
  /bin/getnr
}

get_nr_2() {
  num1="`get_nr_1`"
  num2="`get_nr_1`"
  echo $(($num1 * 10 + $num2))
}

nvram() {
  /usr/sbin/nvram $*
}

### OPTIONS
# *** put your implementations here ***
# (...)

# some samples:
save_and_reboot() {
  nvram commit
  /sbin/reboot
}

channel_number() {
  num="`get_nr_1`"
  [ "$num" = "0" ] && return
  nvram set wl0_channel=$num
}

ping_test() {
  for i in 1 2 3 4 5 6 7 8 9 10; do
    ping -c 1 #IP# >/dev/null 2>&1
    if [ $? -eq 0 ]; then
      echo "0x01" > /proc/sys/diag
      sleep 1
      echo "0x00" > /proc/sys/diag
    fi
  done
}
---

--- getnr (finally) ---
#!/bin/sh

  empty=0
  last=0
  number=0

  # notify that we're ready to get the number
  echo "0x04" > /proc/sys/diag

  while true; do
    if [ `cat /proc/sys/reset` = "1" ]; then
      # hey, it's one push - power on DMZ led
      echo "0x01" > /proc/sys/diag

      empty=0

      if [ "$last" = "0" ]; then
        # increase number
        number=$(($number+1))
      fi

      # user pressed the button
      last=1
    else
      # power off DMZ led
      echo "0x04" > /proc/sys/diag

      empty=$(($empty+1))

      # end after 15 "empty" inputs
      if [ $empty -gt 15 ]; then
        break
      fi

      # user released the button
      last=0
    fi
  done

  # notify that we're end
  echo "0x01" > /proc/sys/diag
  sleep 1
  echo "0x00" > /proc/sys/diag

  echo $number
---

netprince wrote:

I tried gpio, but it only reads in a polling loop...

That's the ideal way to do it - then your script only responds when there's some action - not reliant on that 1 second delay...

Something like:

gpio poll 4 | while read value; do
   if [ "$value" = "00" ];then
      echo "Cisco button pressed!"
   fi
done

The current gpio tool won't work like this though, as its polling loop uses printf(), but no fflush(), so it won't work correctly in a pipe like it is above. I've fixed this, and compiled a new binary and packaged it, available here. (there's also a 'cisco-button' package there that will monitor the front panel button and take the wifi interface up and down as needed)

Mike.

Hi all!

This is a very interesting thread!

I have implemented a script that uses the Cisco button in front of myh WRT54G V4 to flip between 2 modes of operation:
1- Automatic Bridge Client that looks for access points, try to associate and verify it an internet connection is present
2- Regular access point.

This is done by changing an nvram variable that my other startup script is reading.  Here is the code:

#!/bin/sh

# fp_mon.sh

gpio poll 4 | while read value; do
   if [ "$value" = "00" ];then
     ST=$(/usr/sbin/nvram get autoinet)
     echo "Status : $ST"
     echo  "0x00" > /proc/sys/diag
     sleep 2
     if [ "$(nvram get autoinet)" = "1" ]; then
       /usr/sbin/nvram set autoinet=0
       echo "Client mode deactivated";
       echo  "0x04" > /proc/sys/diag
     else
       /usr/sbin/nvram set autoinet=1
       echo "Client mode activated";
       echo  "0x05" > /proc/sys/diag
     fi
     nvram commit
     reboot
   fi
  sleep 1
done

The problem is that the gpio module uses more than 90% of the CPU when polling for the cisco button:

Mem: 9364K used, 5012K free, 0K shrd, 860K buff, 3636K cached
Load average: 1.01, 0.95, 0.56    (State: S=sleeping R=running, W=waiting)

  PID USER     STATUS   RSS  PPID %CPU %MEM COMMAND
  295 root     R        232   293 99.9  1.6 gpio
  945 root     R        408   492  2.8  2.8 top
  487 root     S        640   288  0.0  4.4 dropbear
  492 root     S        468   487  0.0  3.2 ash
  294 root     S        428   289  0.0  2.9 sh
   41 root     S        424     1  0.0  2.9 rcS
  296 root     S        420   293  0.0  2.9 fp_mon.sh
  288 root     S        420     1  0.0  2.9 dropbear

I would like to poll the value of the button and then sleep for 1 second. I installed the new diag.o by CodePoet82 (from http://www.intherack.com/random-stuff/diag.o). The only thing found under /proc/sys is:

root@OpenWrt:/proc/sys# ls
abi     debug   dev     diag    fs      kernel  net     proc    reset   vm

How can I poll the button without taking so much CPU bandwith?

Thanks!

Actually, isn't it possible to trigger an interrupt when a gpio pin changes? This would remove the rather ugly polling loop.

Sure!  This would be the best approach!  Anyone to implement this? Is it possible to trigger some code when the button is pressed without having to use the GPIO and 90% of the CPU?

Here's my code thus far...
I'm using CodePoet82's modified diag module...

#!/bin/sh

delay=1
toggle=0
timer=0
while sleep $delay; do
#      if [ `cat /proc/sys/reset` -eq 1 ]; then
        if [ `cat /proc/sys/ciscobutton` -eq 1 ]; then
                if [ $timer -eq 1 ]; then
                        timer=2
                else
                        timer=1
                fi
        fi
        if [ $timer -eq 2 ]; then
                if [ $toggle -eq 1 ]; then
                        gpio enable 2
                        toggle=0
                else
                        gpio disable 2
                        toggle=1
                fi
                timer=0
        fi
done

nothing super special, and all it does is turn on and off a light!  Definately could do other things though.

(Last edited by neeko on 9 Dec 2005, 18:06)

hey, i tried installing codepoet's diag.o file by overwriting the symlink already in the directory specified,... is there anything else im supposed to do? Because it does not immediatley work, and if i reboot my router, it still dosen't work. I got it to work by running

rmmod diag
insmod diag

but i soon discovered that it dosen't recognize when i press my reset button anymore. Also, i tried putting it into /etc/init.d/S60ciscobutton as

#!/bin/sh

rmmod diag
insmod diag

but that hangs my router's boot so the DMZ never goes off.

Eventually, i want to be able to backup my router when i press the cisco button...
this is what i have now to do that (dosen't work unless i get the above fixed)

#!/bin/sh

while [ true ]; do
        if [ `cat /proc/sys/ciscobutton` -eq 1 ]; then
                killall S52loadled
                /sbin/gpio enable 3
                /sbin/gpio enable 2
                sleep 3
                mount -o remount,ro /dev/mtdblock/4 /
                dd if=/dev/mtdblock/1 > /tmp/wrt-linux.trx
                mount -o remount,rw /dev/mtdblock/4 /
                dd if=/dev/mtdblock/3 > /tmp/wrt-nvram.bin
                mkdir /tmp/smb
                mount -t cifs //server/share /tmp/smb -o unc=//server\\share,ip=x.x.x.x,user=username,pass=pass
                mv /tmp/smb/wrt-linux.trx /tmp/smb/wrt-linux.trx.bak
                mv /tmp/smb/wrt-nvram.bin /tmp/smb/wrt-nvram.bin.bak
                mv /tmp/wrt-linux.trx /tmp/smb
                mv /tmp/wrt-nvram.bin /tmp/smb
                umount /tmp/smb
                rm -rf /tmp/smb
                /etc/init.d/S52loadled
        fi
done &

(Last edited by eatnumber1 on 19 Feb 2006, 10:32)

Hi mjb,

could you maybe modify the gpio module in that way, that you add another mode? I think of something like a "once" command. Using this command (gpio once 4), the command will not poll in a loop button 4, instead it will get the button 4 status and returns. Code could be like this (please forgive me but I'm not a shell expert...):

while [ true ]; do
   if [ 'gpio once 4' -eq 1 ]; then
      echo "Cisco button pressed!"
   fi
   sleep 1
done

I'm using the cisco-button module and I have still a cpu usage of >95% with your modified gpio.

Regards

Andreas

any help on installing the module (read my above post)?

Hi eatnumber1,

could you fix your problem in the meantime? What version of openwrt are you using?

I'm still looking for solution with little cpu consumption...

Andreas

ALuedtke wrote:

Hi eatnumber1,

could you fix your problem in the meantime? What version of openwrt are you using?

I'm still looking for solution with little cpu consumption...

Andreas

sort of gave up on it... i was running RC4, but now i'm running nbd's pre-RC5. Haven't tried it on this yet

The discussion might have continued from here.