OpenWrt - Przyciski
Obsługa przycisków w OpenWrt
Ostatnia zmiana: 2013-11-26 18:43

1. Nazwy przycisków
2. Skrypt do obsługi przycisków
3. Obsługa przycisków przy pomocy UCI


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 "ses" 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

(UWAGA: w moich obrazach 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:
  • button - nazwa przycisku
  • 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

UWAGA: żeby dysk można było odmontować, żaden proces nie może używać dysku - w szczególności np. Transmission, samba czy ftp.