Obsługa przycisków w OpenWrt
Ostatnia zmiana: 2017-01-22 07:03
Większość ruterów posiada jakieś przyciski. Zwykle jest dostępny "Reset" (lub "Restore"), czasami także pojawia się przycisk oznaczony WPS, SES czy QSS. Ze względów oszczędnościowo-praktycznych, fizycznie taki przycisk zwykle jest bezpośrednio podłączony pod jedną z linii wejściowych CPU rutera (zwanych GPIO) i tym samym jest dostępny do programowego obsłużenia. Ponieważ zwykle OpenWrt zawiera obsługę przycisków dla danej platformy, możemy to wykorzystać do własnych celów np. odmontowania dysku USB, zatrzymania pracy programu do pobierania torrentów, wyłączenie/przełączenia wifi, resetu (!) czy setki innych pomysłów które chcemy zrealizować.
Nazwy przycisków
Same moduły do obsługi powinny być już zawarte w systemie (najczęściej jest to realizowane przez pakiet kmod-button-hotplug) więc nie ma już potrzeby ich instalacji. Sama obsługa jest zrealizowana przez podsystem
hotplug - czyli jeżeli naciśniemy przycisk to zostaną wykonane wszystkie programy zawarte w pewnym katalogu; w przypadku OpenWrt jest to
/etc/hotplug.d/button. Zostaną one uruchomione zarówno po naciśnięciu jak i zwolnieniu przycisków. Do skryptów przekazywane są zmienne środowiskowe zawierające informacje o nazwie wciśniętego przycisku (zmienna $BUTTON), akcji (zmienna $ACTION) oraz czasie od ostatniego naciśnięcia przycisku (zmienna $SEEN).
Ponieważ w zależności od typu rutera przyciski mogą się różnie nazywać, najpierw należy sprawdzić pod jak nazwą są widoczne. Najprościej umieścić w w/w katalogu prosty skrypt który wypisze nam to samodzielnie:
# mkdir -p /etc/hotplug.d/button
# vi /etc/hotplug.d/button/przyciski
a w nim umieścić następującą zawartość
#!/bin/sh
logger $BUTTON
logger $ACTION
Zapisujemy zmiany i po kolei należy kilkukrotnie nacisnąć wszystkie przyciski. Po wykonaniu polecania
logread powinny pojawić się komunikaty typu
Jan 1 00:01:15 OpenWrt user.notice root: BTN_1
Jan 1 00:01:15 OpenWrt user.notice root: pressed
Jan 1 00:01:16 OpenWrt user.notice root: BTN_1
Jan 1 00:01:16 OpenWrt user.notice root: released
A to oznacza że naciśnięty przycisk nazywa się BTN_1. W zależności od typu rutera możemy tam znaleźć napisy typu "reset", "wps", "ses" itp.
Skrypt do obsługi przycisków
Skoro wiemy już jak się nazywa dany przycisk - obsługa sprowadza się do napisania odpowiedniego skryptu. Czyli w katalogu
/etc/hotplug.d/button należy utworzyć plik o dowolnej nazwie, np.
00-button
# mkdir -p /etc/hotplug.d/button
# cd /etc/hotplug.d/button
# touch 00-button
a w nim umieścić np. taki kod:
if [ "$ACTION" = "pressed" ]; then
if [ "$BUTTON" = "BTN_0" ]; then
polecenia do wykonania po naciśnięciu przyciku BTN_0
elif [ "$BUTTON" = "BTN_1" ]; then
polecenia do wykonania po naciśnięciu przyciku BTN_1
fi
fi
Praktycznie zastosowanie - skrypt do włączenia/wyłączenia wifi po naciśnięciu przycisku o nazwie "wps" dostępny jest
tutaj.
Obsługa przycisków przy pomocy UCI
Każdorazowe modyfikowanie skryptu może być uciążliwe. Można zrobić uniwersalną obsługę przycisków przy pomocy standardu w OpenWrt -
UCI, definiując odpowiednią sekcję w plikach konfiguracyjnych. Taki skrypt jest gotowy i wystarczy go pobrać od deweloperów OpenWrt:
# mkdir -p /etc/hotplug.d/button
# wget -O /etc/hotplug.d/button/00-button http://dev.openwrt.org/export/21216/trunk/target/linux/atheros/base-files/etc/hotplug.d/button/00-button
(w moich obrazach AA ten skrypt jest już dodany)
Cała obsługa przycisków sprowadza się do umieszczenia odpowiedniej sekcji w pliku
/etc/config/system. W przykładzie - wyłączenie wifi (tylko wyłączenie) po naciśnięciu przycisku "WPS"
# uci add system button
# uci set system.@button[-1].button=wps
# uci set system.@button[-1].action=pressed
# uci set system.@button[-1].handler='uci set wireless.@wifi-device[0].disabled=1 && wifi'
# uci commit system
Dostępne opcje to:
- action - pressed lub released, czyli akcja będzie wykonana po wciśnięciu lub puszczeniu przycisku
- handler - nazwa skryptu/polecenie do wykonania
Ten skrypt umożliwia także zliczanie czasu naciśnięcia i tym samym wykonanie różnej akcji po przytrzymaniu przycisku np. 3s lub 10s. Aby to wykonać akcja powinna być zdefiniowana jako "released" oraz należy ustawić opcje "min" oraz "max" - to czas podany w sekundach. Czyli np.
# uci add system button
# uci set system.@button[-1].button=BTN_1
# uci set system.@button[-1].action=released
# uci set system.@button[-1].handler='logger czas nacisniecia: 0-3s'
# uci set system.@button[-1].min=0
# uci set system.@button[-1].max=3
# uci add system button
# uci set system.@button[-1].button=BTN_1
# uci set system.@button[-1].action=released
# uci set system.@button[-1].handler='logger czas nacisniecia: 8-10s'
# uci set system.@button[-1].min=8
# uci set system.@button[-1].max=10
# uci commit system
Jeżeli teraz naciśniemy przycisk BTN_1 i przytrzymamy go do 3s lub 8-10 to w logach (
logread) powinna pojawić się odpowiednia informacja o tym. Dzięki temu można zrealizować różną funkcjonalność obsługiwaną przez jednej przycisk, np. trzymamy do 2s - wyłącza się wifi, trzymamy do 10s - odmontowywuje dyski, powyżej 30s - robi reset systemu.
Przykład: odmontowanie dysków po naciśnięciu przycisku
# uci add system button
# uci set system.@button[-1].button=BTN_1
# uci set system.@button[-1].action=released
# uci set system.@button[-1].handler='for i in $(mount | awk '/dev\/sd[a-z]/ { print $1}'); do umount $i; done'
# uci set system.@button[-1].min=5
# uci set system.@button[-1].max=10
# uci commit system
Żeby dysk można było odmontować, żaden proces nie może używać dysku - w szczególności np. Transmission, samba czy ftp.
Barrier Breaker i późniejsze
Powyższe elementy są też prawdziwe dla Barrier Breaker i późniejszych wydań. Jednakże system BB zawiera już predefiniowaną obsługę przycisków, umiejscowioną w katalogu
/etc/rc.button. Zawarte tam skrypty nazywają się tak samo jak przyciski - naciśniecie np.
reset powoduje wykonanie skryptu
/etc/rc.button/reset, przekazując wszystkie zmienne - $SEEN, $BUTTON, $ACTION. Zdefiniowane są domyślnie skrypty o nazwach:
- reset: naciśnięcie do 1s powoduje restart urządzenia, powyżej 5s - przywrócenie ustawień domyślnych (firstboot)
- power: wyłączenie urządzenia
- rfkill: wyłączenie interfejsu radiowego
Po dodaniu pakietu
hostapd-utils pojawi się także obsługa przycisku
wps.
Przed wykonaniem własnych skryptów należy więc pamiętać że mogą się wykonać także skrypty z tego katalogu. Można też oczywiście w tym katalogu umieścić własne skrypty pod odpowiednimi nazwami. W przykładach znajduje się skrypt
rfkill przełączający radio. Jeżeli chcemy taką funkcjonalność podpiąć pod przycisk
wps obecny np. w niektórych routerach TP-LINK wystarczy zrobić plik
/etc/rc.button/wps i umieścić w nim odpowiedni kod. Lub prościej - zrobić dowiązanie symboliczne do
rfkill czyli:
# ln -s /etc/rc.button/rfkill /etc/rc.button/wps
Po naciśnięciu przycisku
wps zostanie przełączony interfejs radiowy. Niektóre routery mogę posiadać przycisk który jest nazwany np. wps a nie reset - więc przez zdaniem pytania "dlaczego nie działa" warto sprawdzić pod jaką nazwą widoczny jest przycisk - patrz na górze tego poradnika.