You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
7.7 KiB
Bash

#!/bin/sh /etc/rc.common
START=97
USE_PROCD=1
if [ -f /lib/ar71xx.sh ]; then
PLATFORM=ar71xx
. /lib/ar71xx.sh
elif [ -f /lib/ipq806x.sh ]; then
PLATFORM=ipq806x
. /lib/ipq806x.sh
fi
board=$(${PLATFORM}_board_name)
. /lib/functions/leds.sh
. /usr/share/libubox/jshn.sh
UCI=/sbin/uci
JSON_LEDS=$(ubus call uci get '{"config":"system","type":"led"}');
ERROR_STATE=$(ubus call uci state '{"config":"delos","section":"error","option":"state"}');
WIFI_ENABLED=0
WIFI_WPS=0
if [ -d /sys/class/net/wifi0 ]; then
INTERFACE="wifi"
else
INTERFACE="radio"
fi
get_error_state() {
if [ -n "$ERROR_STATE" ]; then
local ret
json_load "$ERROR_STATE"
json_get_var ret value 0
echo "$ret"
return 0
fi
echo "0"
}
get_wps_state() {
call='hostapd_cli -i "${vap_dir#"$dir/"}" -p "$dir" wps_get_status && hostapd_cli -i "${vap_dir#"$dir/"}" -p "$dir" wps_get_pin_status'
WIFI_WPS=0
for dir in /var/run/hostapd-*; do
[ -d "$dir" ] || continue
for vap_dir in $dir/ath* $dir/wlan*; do
[ -r "$vap_dir" ] || continue
retval=$(eval $call)
if [ $(echo "$retval" | grep -c '^RUNNING\|Active') -gt 0 ]; then
WIFI_WPS=1
fi
done
done
local retval=$(uci_get_state wireless wps_clone state)
if [ "$retval" = "running" ]; then
WIFI_WPS=1
fi
}
is_wifi_disabled() {
local radio=$1
/sbin/uci -q get wireless.$radio >/dev/null || {
# nonexisting radio counts as disabled
echo 1
return
}
local disabled=$(/sbin/uci -q get wireless.$radio.disabled 2>&1)
case "$disabled" in
0)
echo 0
;;
1)
echo 1
;;
*)
echo 0 #option not set
esac
}
all_wifis_enabled() {
if [ "$(is_wifi_disabled ${INTERFACE}0)" -eq 0 ] || [ "$(is_wifi_disabled ${INTERFACE}1)" -eq 0 ]; then
WIFI_ENABLED=1
fi
}
setup_board_leds() {
#defaults
ERROR_IND_LED="led_wlan2g"
ERROR_OFF_LED="led_wlan5g"
WIFI2G_LED="led_wlan2g"
WIFI5G_LED="led_wlan5g"
WIFI_TRIGGERED_LED=
case "$board" in
dlan-1000-ac)
ERROR_IND_LED=
ERROR_OFF_LED=
WIFI2G_LED=
WIFI5G_LED=
WIFI_TRIGGERED_LED="led_wlan"
;;
dlan2-2400-ac|\
dlan-550-wifi|\
dlan-pro-1200-ac|\
dlan-pro-1200-n)
ERROR_IND_LED=
ERROR_OFF_LED=
WIFI2G_LED=
WIFI5G_LED=
WIFI_TRIGGERED_LED="led_wlan"
;;
dlan-*)
ERROR_IND_LED="led_wlan"
ERROR_OFF_LED=""
WIFI2G_LED="led_wlan"
WIFI5G_LED="led_wlan"
;;
dvl-* |\
ew7479cap)
ERROR_IND_LED="led_wlan2g"
ERROR_OFF_LED="led_wlan5g"
WIFI2G_LED="led_wlan2g"
WIFI5G_LED="led_wlan5g"
;;
ap151)
ERROR_IND_LED=
ERROR_OFF_LED=
WIFI2G_LED="ap151:green:lan2"
WIFI5G_LED="ap151:green:lan3"
WIFI_TRIGGERED_LED="led_wlan"
;;
esac
# we need the sysfs-name
ERROR_IND_LED=$(led_get_option "$ERROR_IND_LED" sysfs)
ERROR_OFF_LED=$(led_get_option "$ERROR_OFF_LED" sysfs)
WIFI2G_LED=$(led_get_option "$WIFI2G_LED" sysfs)
WIFI5G_LED=$(led_get_option "$WIFI5G_LED" sysfs)
WIFI_TRIGGERED_LED=$(led_get_option "$WIFI_TRIGGERED_LED" sysfs)
# tricky: QSDK has 2G and 5G radio swapped w.r.t. OpenWrt when both are present: swap
[ -d /sys/class/net/wifi0 ] && [ -d /sys/class/net/wifi1 ] && {
local T="$WIFI2G_LED"
WIFI2G_LED="$WIFI5G_LED"
WIFI5G_LED="$T"
}
}
led_get_option() {
local led="$1"
local option="$2"
local ret=""
[ -z "$led" ] && return
json_load "$JSON_LEDS"
# error msg printed to stdout when object doesn't exist -> /dev/null
json_select values >/dev/null &&
json_select $led >/dev/null && {
json_get_var ret $option
}
echo "$ret"
}
led_get_sysfs_value() {
local LED="$1"
local file="$2"
[ -f "/sys/class/leds/$1/$2" ] || return 0
local retval=$(cat /sys/class/leds/$LED/$file)
retval="${retval##*\[}"
retval="${retval%%]*}"
echo "$retval"
}
led_set_error_condition() {
#orange (2.4GHz) fast blinking, blue off (5GHz) [colors of dvl-1750c]
logger "Leds: set error condition"
led_timer "$ERROR_IND_LED" 100 100
led_off "$ERROR_OFF_LED"
}
led_set_radios_off_condition() {
#both wifi leds are off for 4.9 seconds and on for 0.1 seconds (except 1200 ac: wifi trigger)
logger "Leds: set radio off condition"
led_set_attr "$WIFI_TRIGGERED_LED" operation off
# The led_off is required here, to get both LEDs in the same state, otherwise they might blink asynchronously
led_off "$WIFI2G_LED"
led_off "$WIFI5G_LED"
led_timer "$WIFI2G_LED" 100 4900
led_timer "$WIFI5G_LED" 100 4900
}
led_set_normal_condition() {
#led state depends on radio state
logger "Leds: set normal condition"
local TRIGGER1=$(led_get_option "$WIFI2G_LED" trigger)
local TRIGGER2=$(led_get_option "$WIFI5G_LED" trigger)
[ -n "$TRIGGER1" ] && led_set_attr "$WIFI2G_LED" trigger "$TRIGGER1"
[ -n "$TRIGGER2" ] && led_set_attr "$WIFI5G_LED" trigger "$TRIGGER2"
op=off
if [ "$(is_wifi_disabled ${INTERFACE}1)" -eq 0 ]; then
op=on
led_on "$WIFI2G_LED"
else
led_off "$WIFI2G_LED"
fi
if [ "$(is_wifi_disabled ${INTERFACE}0)" -eq 0 ]; then
op=on
led_on "$WIFI5G_LED"
else
led_off "$WIFI5G_LED"
fi
led_set_attr "$WIFI_TRIGGERED_LED" operation $op
}
led_set_wps_condition() {
logger "Leds: set WPS condition"
local TRIGGER1=$(led_get_sysfs_value "$WIFI2G_LED" trigger)
local TRIGGER2=$(led_get_sysfs_value "$WIFI5G_LED" trigger)
local TRIGGER3=$(led_get_sysfs_value "$WIFI_TRIGGERED_LED" trigger)
if [ "$(is_wifi_disabled ${INTERFACE}1)" -eq 0 ]; then
if [ $TRIGGER1 != "timer" ]; then
led_timer "$WIFI2G_LED" 500 500
else
local DELAY_OFF=$(led_get_sysfs_value "$WIFI2G_LED" delay_off)
local DELAY_ON=$(led_get_sysfs_value "$WIFI2G_LED" delay_on)
if [ "$DELAY_ON" != "500" ] || [ "$DELAY_OFF" != 500 ]; then
led_timer "$WIFI2G_LED" 500 500
fi
fi
fi
if [ "$(is_wifi_disabled ${INTERFACE}0)" -eq 0 ]; then
if [ $TRIGGER2 != "timer" ]; then
led_timer "$WIFI5G_LED" 500 500
else
local DELAY_OFF=$(led_get_sysfs_value $WIFI5G_LED delay_off)
local DELAY_ON=$(led_get_sysfs_value $WIFI5G_LED delay_on)
if [ "$DELAY_ON" != "500" ] || [ "$DELAY_OFF" != 500 ]; then
led_timer "$WIFI5G_LED" 500 500
fi
fi
fi
if [ $TRIGGER3 != "wifi" ]; then
led_set_attr "$WIFI_TRIGGERED_LED" trigger wifi
fi
local OPERATION3=$(led_get_sysfs_value $WIFI_TRIGGERED_LED operation)
if [ "$OPERATION3" != "wps" ]; then
led_set_attr "$WIFI_TRIGGERED_LED" operation wps
fi
}
led_state_machine() {
if [ $(get_error_state) -eq 1 ]; then
#set error led behaviour and return
led_set_error_condition
return 0
fi
if [ $WIFI_ENABLED -eq 0 ]; then
#set both radios off behaviour and return
led_set_radios_off_condition
return 0
fi
get_wps_state
if [ $WIFI_WPS -eq 1 ]; then
led_set_wps_condition
# forbidden to loop in procd (procd processing blocks), do that in background:
(sleep 1; led_state_machine) &
return 0
fi
#setup normal operation
led_set_normal_condition
}
update_leds() {
all_wifis_enabled
setup_board_leds
led_state_machine
}
start_service() {
update_leds
}
reload_service() {
update_leds
}
service_triggers()
{
procd_add_reload_trigger wireless
}