[Fixed] Wps to trigger power-led:orange to blink

I have wndr4700.
Recently I have installed wpad and hostapd-utils and removed wpad-min, So my WPS-Button is working. But when press WPS-Button theres WPS LED (wndr4700:orange:power or wndr4700:white:logo) is not blink.

So I want my WPS LED to blink when this WPS-Button is pressed for 2min (or as defined by system).

Can anyone help me.

Sure, you could do something like that. just replace the /etc/rc.button/wps script:

#!/bin/sh

if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then
    cd /var/run/hostapd
    for socket in *; do
            [ -S "$socket" ] || continue
            hostapd_cli -i "$socket" wps_pbc
    done
    (
            LOGO="/sys/class/leds/wndr4700:white:logo/brightness"
            PWR="/sys/class/leds/wndr4700:orange:power/brightness"

            for i in $(seq 0 59); do
                    echo 1 > $LOGO
                    echo 0 > $PWR
                    sleep 1
                    echo 0 > $LOGO
                    echo 1 > $PWR
                    sleep 1
            done

            echo 0 > $LOGO
            echo 0 > $PWR
    ) &
fi

return 0

Just make sure the script file is still set as a executeable. You can do a lot more too, the backup button is user-programmable as well (The button is mapped to btn_0). If you are not familiar with (b[a])sh, http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html is a great place to start. If you are just new to rc.button. Take a look at: https://wiki.openwrt.org/doc/howto/hardware.button and you are ready to go!

Here is list of my buttons

root@WNDR47XX:/etc/rc.button# ls -l
-rwxr-xr-x    1 root     root           211 Mar 25 06:43 BTN_1
-rwxr-xr-x    1 root     root            87 Feb 20 22:43 failsafe
-rwxr-xr-x    1 root     root            81 Feb 20 22:43 power
-rwxr-xr-x    1 root     root           419 Feb 20 22:43 reset
-rwxr-xr-x    1 root     root           526 Feb 20 22:43 rfkill
-rwxr-xr-x    1 root     root           194 Mar  2 22:34 wps
root@WNDR47XX:/etc/rc.button# 

as you can see theres no btn_0 but BTN_1

root@WNDR47XX:/etc/rc.button# cat BTN_1

#!/bin/sh

. /lib/functions.sh
. /lib/apm821xx.sh

BOARD=$(apm821xx_board_name)

if [ $BOARD == "wndr4700" ]; then
	case "$ACTION" in
	released)
		rmmod dwc2
	;;
	pressed)
		modprobe dwc2
	;;
	esac
fi

return 0

root@WNDR47XX:/etc/rc.button#

Is this my backup/save-to-hdd button? I am using

root@WNDR47XX:/etc/rc.button# uname -a
Linux WNDR47XX 4.4.50 #0 Mon Feb 20 17:13:44 2017 ppc GNU/Linux

Thanks for your help
Thanks for the wps script, I was wondering how "$ACTION" will be evaluated without passing argument to wps.sh. Now I know it ubiquitous by LEDE itself as system environment variable.

No, BTN_1 is a different thing. The BTN_1 is mapped to the SD-Card Reader's insertion pin.
This logic was added by the following patch:

If you want to

that's procd doing. See: https://wiki.openwrt.org/doc/techref/procd

The kernel driver gpio_button_hotplug is constantly polling a set of specified GPIOs and if one changes, it will notify procd via a Button Event (Which includes the pressed/release state). Procd will look into /etc/hotplug.json file and execute the following rule:
[ "button", "/etc/rc.button/%BUTTON%" ]`

the "button" rule is an internal handler procedure in procd:
https://git.lede-project.org/?p=project/procd.git;a=blob;f=plug/hotplug.c;h=c8bea1b75b958284968fd6663a8fcb0c9a9fab2a;hb=HEAD#l329

And this will execute the right script in /etc/rc.button/ with the env variables ACTION, TIMEOUT, BUTTON set.

If you want to test your scripts, you can do sth like:
ACTION="pressed" BUTTON="wps" /etc/rc.button/wps

Note: Yes, the "Backup" Button should have been /etc/rc.button/BTN_0

This is very help full for testing.

But it's not there from the day I installed LEDE. Can you cat /etc/rc.button/BTN_0 so that I copy and test.

The hostapd_cli return OK or FAIL, I want to know its timeout, return, exit status, So that the wps_pbc can't be running for forever and on successful attachment with client it can kill the [ ($LOGO and $PWR) & ] in background.

Oh, you'll have to code your own version for this Feature. LEDE doesn't ship with it.
Writing a proper and generic "Backup to SD-Card" script is more difficult than you would think.:

First, the script would need to know which of the many devices in /dev is the sd-card.
This is because the WNDR4700 has a builtin HDD Port that might be empty, you can't
assume it's always /dev/sdb.

Second, what's the destination for the files on the SD-Card? Is it the HDD or a connected
USB-Stick, or some destination, maybe someone wants to copy it to a different NAS,
email them, ....

Then there's all the management, that goes along with it: What should the script do,
If there's a existing file with the same name but different content? When would it be OK
to overwrite it and when not? What to do if the destination ran out of space for the files?
How to handle "accidental" double, tripple, n-taps. etc...

And finally, some people will request strange "features": e.g. making it so that the "backed up"
files will be deleted from the SD-Card. Or adding some custom blinkenlight progress bars, ...

I think there's simply no way to make everyone happy. So, I just point users to the bash
programming documentation and say: Have fun with it.

Personally, I'm using the "Backup" button as a reboot button, since I do only development on the router.
I don't use it much because of the fan.

Similar problem as above. I think you would have to add the functionallity to hostapd's sources.
I think that wpa_supplicant's wpa_cli does allow to request the timeout and the state... But
wpa_supplicant is for clients (and the AP functionallity is a addon). Maybe Jouni
would be interested, you could ask him what he would do.

I think that you are aiming to higher degree of status info and LED control than is directly available from the hostapd itself.

I have written the current version of the wps button script in 2015 and these comments are mainly based on memories from that. That commit contains also useful examples: https://git.lede-project.org/?p=source.git;a=commitdiff;h=125b2ced636d35b78c0ec5a5d7e391a849beb945;hp=d9ebcce56cf191cf0c13612c62c4097be1bc087a

See also https://dev.openwrt.org/ticket/19485 and https://forum.openwrt.org/viewtopic.php?pid=272476

Key points for you:

  • hostapd itself will turn off the wps function after the 120 seconds timeout period. There is no need to separately stop wps.
  • There is no way to query the "wps active time left"
  • hostapd_cli wps_pbc returns "OK" or "FAIL" just informing about the status of activating/initiating the wps polling. But that does not give a hint about the end result. It just tells you if wps functionality exists at all and was started.
  • hostapd_cli wps_get_status wiill return "Active" while the wps polling is on, and "Timed-out" after the time expires. (I don't remember what gets returned after an ok connection.)
    • you have to query the status of each radio separately (in a router with multiple radios)

My advice:

If you want to stop blinking LED as soon as a connection is made with wps, my suggestion is that you start a 120 sec loop and query status with "wps_get_status" e.g. every 5 seconds. If "PBC Status" is still "Active", do nothing and continue loop. If it is something else (either timeout or success has happened), you can stop blinking the LED.

You need to explore getting wps status with
hostapd_cli -p /var/run/hostapd -i wlan0 wps_get_status
during the process and see how the returned status change with various actions. That way you can collect enough info to do what you want.

it can be used easily by use lock_by_file_methord

if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" -a (! -f /tmp/.bkp_lock) ] then
echo 1>/tmp/.bkp_lock
cmd1
cmd2
#make sure that you dont delete /tmp/.bkp_lock in b/w
cmd3
cmd4
fi
rm -f /tmp/.bkp_lock
return 0;

Yes, the reboot is more helpful than bakup. I am also going to use it.

Yes, I am working on this.

Today I was reading your email and I found that you had sent me proper instructions and content of BTN_0 which I did not read because I was obsessed with the WPS button

Your email was:

And Copy SDCard Button.
Well, somebody gifted me the router if I would work on a port.
I never used Netgears Firmware. I don't know what Netgear had
implemented with the "Backup HDD" button.

What I can tell you is, that the "Backup HDD" button is mapped
to BTN_0. So you'll have to write a (bash) script and place it
into /etc/rc.button/BTN_0 which does what you want. If you need
a base, please take a look at the other scripts in the directory.

--- sample ---
#!/bin/sh

. /lib/functions.sh
. /lib/apm821xx.sh

BOARD=$(apm821xx_board_name)

if [ $BOARD == "wndr4700" ]; then
        case "$ACTION" in
        pressed)
                                  echo "Copy SD to HDD"
                                  # mount SD-card
                                  # copy /mnt/sdb1/* to /mnt/sda1/sd
                                  # umount SD-card, if it wasn't mounted
        ;;
        esac
fi

return 0

As sample/example

Every thing is ok WPS button is working and blinking.

Please post your final wps script. Might be useful :wink:

I would second the request for publishing the final script as I'd love to adapt it for my WRT1900ACS.

I was unable to make dynamic wps like OEM, so I opted simple is easy

root@WHOST12:/etc/rc.button# cat wps
#!/bin/sh

if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then

	WPSLED="/sys/class/leds/wndr4700:white:logo/brightness"
	echo 1 > $WPSLED
	cd /var/run/hostapd
	for socket in *; do
		[ -S "$socket" ] || continue
		hostapd_cli -i "$socket" wps_pbc
	done
	sleep 119
	wait
	echo 0 > $WPSLED
fi

return 0

I was unable to make as OEM wps LED
However I am still working on it (generic-model)

1 Like

This what on which I am working on it

#!/bin/sh
#test ACTION="pressed" BUTTON="wps" /etc/rc.button/wps


if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" -a ! -f /tmp/wpsbuttonlock ]; then
set -C; > /tmp/wpsbuttonlock
	(
	WPSLED="/sys/class/leds/wndr4700:white:logo/brightness"
	for i in $(seq 0 59); 
	do
		sleep 1
		echo 1 > $WPSLED
		sleep 1
		echo 0 > $WPSLED
	done
	) &
	WPSLEDPID=$!

ffactiviy_check(){
	set -C; > /tmp/wpsledlock_by_$1
	if [ "$status_$1"=="FAIL" ]; then
		( rm -f /tmp/wpsledlock_by_$1; return; )
	else
		for i in $(seq 0 23); do
			if [ `hostapd_cli -p /var/run/hostapd -i $1 wps_get_status | grep "PBC Status" | cut -d' ' -f3` = "Active" ] ; 
			then 
				sleep 5; 
				wait;
			else 
				( rm -f /tmp/wpsledlock_by_$1; return; )
			fi
		done
	fi
}

	cd /var/run/hostapd
	for socket in *; do
		[ -S "$socket" ] || continue
		status_$socket=$(hostapd_cli -i "$socket" wps_pbc)
		ffactiviy_check "$socket" &		
	done

	while [ -f /tmp/wpsledlock_by_* ]
	do
		sleep 3
	done
	wait

	kill $WPSLEDPID
	
	rm -f /tmp/wpsledlock_by_*
	rm /tmp/wpsbuttonlock
	echo 0 > $WPSLED
fi
return 0

Its not working right now, lots of error and mismatch, fixing by reading bash

1 Like

Thank you very much for the "easy" option, this is the adapted and working version for the WRT1900ACS:

[details=/etc/rc.button] 1 #!/bin/sh
2
3 if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then
4
5 WPSLED="/sys/class/leds/pca963x:shelby:white:wps/brightness"
6 echo 255 > $WPSLED
7 cd /var/run/hostapd
8 for socket in *; do
9 [ -S "$socket" ] || continue
10 hostapd_cli -i "$socket" wps_pbc
11 done
12 sleep 119
13 wait
14 echo 0 > $WPSLED
15 fi
16
17 return 0
[/details]

From what I remember procd will actually serialize calls to various hotplug and button handlers scripts for you.
I'm not sure if a long sleep in a handler will block other handlers as well or not. If possible this should be
avoided. The upside of this is, that you don't really need locking to protect against the "fast double taps".
But It's a issue if the script is supposed to run for two minutes.

Anyway, If you want to package your scripts: Here's a example Makefile for it:

include $(TOPDIR)/rules.mk

PKG_NAME:=wndr4700-custom
PKG_RELEASE:=1
PKG_VERSION:=2017-04-07

include $(INCLUDE_DIR)/package.mk

define Package/wndr4700-custom
  SECTION:=firmware
  CATEGORY:=Firmware
  DEPENDS:=@TARGET_apm821xx_nand_DEVICE_WNDR4700 +hostapd-utils
  TITLE:=Special customization for the WNDR4700
endef

define Package/wndr4700-custom/description
  This package contains:various scripts to support the various buttons
  and LEDs the WNDR4700 has to offer.
endef

# For existing scripts that need to be overwritten
define Package/wndr4700-custom/install-overlay
    $(INSTALL_DIR) $(1)/etc/rc.button/
    $(INSTALL_BIN) ./wps $(1)/etc/rc.button/
endef

# For new scripts
define Package/wndr4700-custom/install
    $(INSTALL_DIR) $(1)/etc/rc.button/
    $(INSTALL_BIN) ./BTN_0 $(1)/etc/rc.button/
endef

define Build/Compile

endef

$(eval $(call BuildPackage,wndr4700-custom))

I've attached the generated package (the Backup Button is mapped to reboot! :rotating_light:) and sample package with the scripts right here:

As you can see, the main advantage is that you no longer have to worry about them if you do regular updates (i.e. to keep up with stable kernels). You can either use this version, or roll your own with even more customizations and stuff.
Have fun! :slight_smile:

Edit: Looks like the package binary confuses the github integration of discord. However, I think the package is fine if you access/download it via the github website.

Well, I crafted a WPS button script version that blinks a LED for max. 120 seconds but stops blinking if there is a successful WPS connection before that (WPS status is no more "Active").

  • The script blinks a LED for four seconds, then checks the WPS status and if still Active, continues to the next 4-sec period. If 120 seconds is reached, stop blinking.
  • The script only monitors wlan0 WPS status, so it is not yet perfect. If wlan1 gets the WPS connection, the script does not notice that
  • It logs into system log every four seconds just for debugging purposing
  • And the max. 120 second long waiting is not done in a detached process, so this might block other hotplug actions, like chunkeey says.

Script:

#!/bin/sh

if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then
        logger "WPS button pressed, looking for active radios"
        cd /var/run/hostapd
        for socket in *; do
                [ -S "$socket" ] || continue
                logger "WPS activated for: $socket"
                hostapd_cli -i "$socket" wps_pbc
        done

        LedCount=0
        while [ $LedCount -lt 120 ]
        do
                echo "255" > /sys/class/leds/r7800:amber:power/brightness
                sleep 1
                echo "0" > /sys/class/leds/r7800:amber:power/brightness
                sleep 1
                echo "255" > /sys/class/leds/r7800:amber:power/brightness
                sleep 1
                echo "0" > /sys/class/leds/r7800:amber:power/brightness
                sleep 1
                hostapd_cli -p /var/run/hostapd -i wlan0 wps_get_status | grep "PBC Status..Active"
                if [ "$?" = "0" ] ; then
                        LedCount=$((LedCount+4))
                        logger "Ledcount $LedCount"
                else
                        logger "Ledcount end"
                        LedCount=120
                fi
        done

fi

return 0

Log:

Sat Apr  8 00:00:46 2017 user.notice root: WPS button pressed, looking for active radios
Sat Apr  8 00:00:46 2017 user.notice root: WPS activated for: wlan0
Sat Apr  8 00:00:46 2017 user.notice root: WPS activated for: wlan1
Sat Apr  8 00:00:50 2017 user.notice root: Ledcount 4
Sat Apr  8 00:00:55 2017 user.notice root: Ledcount 8
Sat Apr  8 00:00:59 2017 user.notice root: Ledcount 12
Sat Apr  8 00:01:03 2017 user.notice root: Ledcount 16
Sat Apr  8 00:01:07 2017 user.notice root: Ledcount 20
Sat Apr  8 00:01:11 2017 user.notice root: Ledcount end
Sat Apr  8 00:01:12 2017 daemon.info dnsmasq-dhcp[4101]: DHCPDISCOVER(br-lan) 1c:af:f7:f6:11:dc

It does not yet monitor both wlan0 and wlan1 for WPS status and that may lead into faulty decision. Hostapd seems to act so that if one radio gets a successful WPS connection, the other radio still continues active WPS polling until the 120 seconds has gone. See below:

root@LEDE:~# hostapd_cli -p /var/run/hostapd -i wlan0 wps_get_status; hostapd_cli -p /var/run/hostapd -i wlan1 w ps_get_status
PBC Status: Active
Last WPS result: None
PBC Status: Disabled
Last WPS result: Success
Peer Address: 1c:af:f7:f6:11:dc

root@LEDE:~# hostapd_cli -p /var/run/hostapd -i wlan0 wps_get_status; hostapd_cli -p /var/run/hostapd -i wlan1 wps_get_status
PBC Status: Timed-out
Last WPS result: None
PBC Status: Disabled
Last WPS result: Success
Peer Address: 1c:af:f7:f6:11:dc

So, my script is not yet perfect, but shows the basics how the detection and stopping of the blinking can be done. It needs at least to support the second radio better.

You can just add a space before the link, and Discourse does not try to show the fancy contents box, but shows just the link...