【腳本】WifiToggle - 以 Reset/WPS/QSS 按鈕當作無線開關



贊助商連結


FYI
2011-04-26, 11:51 PM
曾經有網友詢問支援硬體無線開關的無線分享器, 小弟約略在網購找了一下, EDIMAX & SMC & ZyXEL & LevelOne 等把硬體無線開關設計成On/Off, Buffalo 則是On/Off/Auto, 此外還有某些品牌支援定時 (排程) 功能, 雖然軟體開關或定時也可以達到控制無線訊號的目的, 但有時還是不如硬體開關來得方便, 然而並非每台分享器都有此設計, 於是小弟參考OpenWrt 的教學文章, 提供網友以利用率較低的Reset/WPS/QSS 等按鈕當作無線開關, 並且根據按下的時間長短產生不同的作用

首先, 請準備一台OpenWrt/X-Wrt/Gargoyle 所支援的無線分享器, 並將韌體更換成Kamikaze 8.09.2 (Gargoyle 1.2) 或Backfire 10.03.1 (Gargoyle 1.3), 若是安裝Trunk 版, 則請先檢查是否已安裝kmod-button-hotplug 套件:

root@OpenWrt:~# opkg list_installed | grep button
kmod-button-hotplug
若未安裝, 則請執行:

root@OpenWrt:~# opkg update
root@OpenWrt:~# opkg install kmod-button-hotplug
以上透過LuCI/X-Wrt 等WebGUI 操作較為簡便

接著找出Reset/WPS/QSS 等按鈕的內部代碼, 請編輯 /etc/hotplug.d/button/01-log-button-actions:

#!/bin/sh
logger "'$BUTTON' was '$ACTION' for $SEEN seconds"
執行 "logread -f", 再按各個按鈕並觀察結果:

root@OpenWrt:~# logread -f
Mar 15 21:39:37 OpenWrt user.notice root: 'reset' was 'pressed' for 0 seconds
Mar 15 21:39:38 OpenWrt user.notice root: 'reset' was 'released' for 1 seconds
Mar 15 21:39:40 OpenWrt user.notice root: 'reset' was 'pressed' for 0 seconds
Mar 15 21:39:42 OpenWrt user.notice root: 'reset' was 'released' for 2 seconds
由以上可知 '$SEEN' 只和 'released' 有關, 和 'pressed' 無關, 撰寫Hotplug 腳本和修改 /etc/config/system 時請留意這點

$BUTTON = [reset|wps|QSS] (僅供參考)
$ACTION = [pressed|released]
$SEEN = 單位為秒, 小數以下不計
找出按鈕代碼之後, 請編輯 /etc/hotplug.d/button/00-button:

. /etc/functions.sh
do_button () {
local button
local action
local handler
local min
local max

config_get button "$1" button
config_get action "$1" action
config_get handler "$1" handler
config_get min "$1" min
config_get max "$1" max

[ "$ACTION" = "$action" -a "$BUTTON" = "$button" -a -n "$handler" ] && {
if [ -z "$min" ]; then
[ -z "$max" -o "$max" -ge $SEEN ] && eval $handler
elif [ -z "$max" ]; then
[ $min -le $SEEN ] && eval $handler
else
[ $min -le $SEEN -a $max -ge $SEEN ] && eval $handler
fi
}
}

#logger "'$BUTTON' was '$ACTION' for $SEEN seconds"
config_load system
config_foreach do_button button
編輯 /etc/config/system: (定義按鈕作用)

config 'button' 'woggle'
option 'button' 'reset'
option 'action' 'released'
option 'handler' '/sbin/woggle'
option 'min' '0'
option 'max' '1'

config 'button' 'reset'
option 'button' 'reset'
option 'action' 'released'
option 'handler' 'firstboot && reboot'
option 'min' '30'
option 'max' '60'
以上作用為:

按下 reset 0-1 秒, 則開啟或關閉無線 (執行 /sbin/woggle)
按下 reset 30-60 秒, 則恢復OpenWrt 預設值 (執行 firstboot && reboot)
請特別留意, 若以 "按下 (pressed)" 按鈕為條件, 則只有當 "min = 0" 之時才會執行 "handler" 的內容

雖然開關無線只需執行 "wifi up" 或 "wifi down", 然而針對不同硬體, 有時可能還需要其他特殊處置, 或者以燈號顯示無線狀態, 所以以下將適用於FON2201 (Kamikaze/Atheros) 和ASUS WL-HDD2.5 (Backfire/brcm47xx) 的腳本分開處理, 另請留意不同韌體版本 (Backfire/Kamikaze, ar71xx/atheros/brcm-2.4/brcm47xx) 可能需要採用不同語法, 請自行研究

FON2201 (Kamikaze/atheros):


啟用無線, 則WLAN LED 顯示綠色 (GPIO 2)
關閉無線, 則WLAN LED 顯示橙色 (GPIO 1, FON2100 & FON2200 不適用)
編輯 [B]/sbin/woggle:

#!/bin/sh
wlanled_off () {
/usr/bin/gpioctl dirout 2 > /dev/null
/usr/bin/gpioctl clear 2 > /dev/null
/usr/bin/gpioctl dirout 1 > /dev/null #for FON2201/FON2202
/usr/bin/gpioctl set 1 > /dev/null #for FON2201/FON2202
}

if [ -d /var/run/hostapd-ath0 -o -d /var/run/hostapd-ath1 ]; then
if [ -z "$1" ]; then
/usr/bin/logger "WifiToggle: WiFi down"
/sbin/wifi down
wlanled_off
fi
elif [ "$1" = led ]; then
wlanled_off
else
/usr/bin/logger "WifiToggle: WiFi up"
/usr/bin/gpioctl dirout 1 > /dev/null #for FON2201/FON2202
/usr/bin/gpioctl clear 1 > /dev/null #for FON2201/FON2202
/sbin/uci set wireless.wifi0.disabled=0
/sbin/wifi up
/sbin/uci revert wireless.wifi0.disabled
fi
ASUS WL-HDD2.5 (Backfire/brcm47xx):


啟用無線, 則PWR LED (/proc/diag/led/power) 恆亮 (1)
關閉無線, 則PWR LED (/proc/diag/led/power) 閃爍 (f)
編輯 /sbin/woggle:

#!/bin/sh
. /etc/diag.sh
if [ -d /var/run/hostapd-phy0 -o -d /var/run/hostapd-phy1 ]; then
if [ -z "$1" ]; then
/usr/bin/logger "WifiToggle: WiFi down"
/sbin/wifi down
set_led power f
fi
elif [ "$1" = led ]; then
set_led power f
else
/usr/bin/logger "WifiToggle: WiFi up"
set_led power 1
/sbin/uci set wireless.radio0.disabled=0
/sbin/wifi up
/sbin/uci set wireless.radio0.disabled=1
fi
儲存後再把 /sbin/woggle 設定為可執行:

root@OpenWrt:~# chmod +x /sbin/woggle
以上除了可以透過按鈕開關無線之外, 直接執行 "woggle" 也可以開關無線

如果網友和小弟一樣, AP 開機時預設不啟用無線, 那麼還需於AP 開機之後以燈號反映正確的無線狀態, 請編輯 /etc/init.d/custom-user-startup:

#!/bin/sh /etc/rc.common
START=98
start() {
/sbin/woggle led
}
儲存並執行:

root@OpenWrt:~# chmod +x /etc/init.d/custom-user-startup
root@OpenWrt:~# /etc/init.d/custom-user-startup enable
由於以上腳本牽涉設定LED, 而OpenWrt 原本會在/etc/rc.d/S95done (/etc/init.d/done) 之中, 於處理/etc/rc.local 之後設定LED, 以Power LED 恆亮代表init 階段完成, 如此則會和小弟的腳本衝突, 所以必須把以上腳本設定於S95done 之後才執行 (START=98)

最後, 由於Backfire 之下可透過LuCI 或 /etc/config/system 控制LED, 所以還需留意是否會和 /proc/diag/led 衝突, 請只控制其中之一, 以ASUS WL-HDD2.5 (Backfire/brcm47xx) 為例:

root@OpenWrt:~# ls /proc/diag/led
power usb
/etc/config/system:

config 'led'
option 'name' 'radio'
option 'sysfs' 'b43-phy0::radio'
option 'default' '1'
option 'trigger' 'netdev'
option 'dev' 'wlan0'
option 'mode' 'tx rx'
參考連結:
Hardware Button - OpenWrt Wiki (http://wiki.openwrt.org/doc/howto/hardware.button)
System configuration - OpenWrt Wiki (http://wiki.openwrt.org/doc/uci/system)
LED System Load Monitor - OpenWrt Wiki (http://wiki.openwrt.org/oldwiki/mod.led.sysloadled)
Wifi Toggle - OpenWrt Wiki (http://wiki.openwrt.org/doc/howto/wifitoggle)
Netgear WNDR3700 - OpenWrt Wiki (http://wiki.openwrt.org/toh/netgear/wndr3700#monitor.button.actions) - Monitor button actions

相關連結:
【韌體】ASUS WL-HDD2.5 改刷 OpenWrt Kamikaze with X-Wrt Webif² - PCZONE 討論區 (http://www.pczone.com.tw/thread/44/150740/)
【腳本】WifiToggle for DD-WRT - 以Reset 按鈕當作無線開關, 無線閒置則自動關閉訊號 - PCZONE 討論區 (http://www.pczone.com.tw/thread/29/150684/)
【韌體】Gargoyle Router Management Utility - PCZONE 討論區 (http://www.pczone.com.tw/thread/16/151818/)

贊助商連結


rushoun
2011-04-27, 01:29 PM
感謝!
先收起來.....
寫韌體真的是很好玩。