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.
208 lines
6.5 KiB
Plaintext
208 lines
6.5 KiB
Plaintext
4 years ago
|
#!/bin/sh
|
||
|
|
||
|
. /lib/config/uci.sh
|
||
|
|
||
|
IFNAME=$1
|
||
|
CMD=$2
|
||
|
|
||
|
get_conf_var() {
|
||
|
local conf="$1"
|
||
|
local var="$2"
|
||
|
# This finds the last "$2=" in the supplicant config and strips off leading
|
||
|
# and trailing quotes. Generally the quotes are there if it's a passphrase and not if its a psk hex string
|
||
|
# (passphrase is pure ascii not escaped, not even for " inside "") and for ssid
|
||
|
grep "^[$(printf " \t")]*$var=" "$conf" |
|
||
|
awk 'BEGIN{FS="="} {a=substr($0, index($0,$2))} END{print a}' |
|
||
|
sed -e 's/^"\(.*\)"$/\1/'
|
||
|
}
|
||
|
|
||
|
add_interface() {
|
||
|
local radio="$1"
|
||
|
local ssid="$2"
|
||
|
local psk="$3"
|
||
|
local encryption="$4"
|
||
|
local country="$(uci_get_state delos baptization WiFiCountryCode)"
|
||
|
uci_add wireless wifi-iface
|
||
|
uci_set wireless @wifi-iface[-1] type qcawifi
|
||
|
uci_set wireless @wifi-iface[-1] device "$radio"
|
||
|
uci_set wireless @wifi-iface[-1] mode ap
|
||
|
uci_set wireless @wifi-iface[-1] ssid "$ssid"
|
||
|
uci_set wireless @wifi-iface[-1] key "$psk"
|
||
|
uci_set wireless @wifi-iface[-1] network lan
|
||
|
uci_set wireless @wifi-iface[-1] channel auto
|
||
|
uci_set wireless @wifi-iface[-1] country "${country:-DE}"
|
||
|
uci_set wireless @wifi-iface[-1] txpower 27
|
||
|
case $encryption in
|
||
|
WPA2-PSK)
|
||
|
uci_set wireless @wifi-iface[-1] encryption psk2
|
||
|
;;
|
||
|
WPA-PSK)
|
||
|
uci_set wireless @wifi-iface[-1] encryption psk
|
||
|
;;
|
||
|
NONE)
|
||
|
uci_set wireless @wifi-iface[-1] encryption none
|
||
|
;;
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
add_interface_uci() {
|
||
|
add_interface "$1" "$2" "$3" "$4"
|
||
|
|
||
|
uci_commit wireless
|
||
|
}
|
||
|
|
||
|
# this implementation depends on having only max 4 SSIDs (2.4GHz/5GHz and normal/guest SSID)
|
||
|
overwrite_interface_uci() {
|
||
|
local radio="$1"
|
||
|
local ssid="$2"
|
||
|
local psk="$3"
|
||
|
local encryption="$4"
|
||
|
local index=-1
|
||
|
local index24=-1
|
||
|
local index5=-1
|
||
|
local radio24=wifi0 # 2.4GHz radio is normally wifi0
|
||
|
local radio5=wifi1 # 5GHz radio is normally wifi1
|
||
|
local use_common_setting=0
|
||
|
|
||
|
# check if wifi1 is 2.4GHz radio
|
||
|
if [ "$(uci_get_state wireless wifi1 hwmode)" == "11g" ]; then
|
||
|
radio24=wifi1
|
||
|
radio5=wifi0
|
||
|
fi
|
||
|
|
||
|
for id in 0 1 2 3; do
|
||
|
# skip guest wifi
|
||
|
if [ "$(uci_get_state wireless @wifi-iface[$id] dvl_guest 0)" == "0" ]; then
|
||
|
# search for 2.4GHz index
|
||
|
if [ "$(uci_get_state wireless @wifi-iface[$id] device)" == "$radio24" ]; then
|
||
|
index24=$id
|
||
|
fi
|
||
|
# search for 5GHz inedx
|
||
|
if [ "$(uci_get_state wireless @wifi-iface[$id] device)" == "$radio5" ]; then
|
||
|
index5=$id
|
||
|
fi
|
||
|
# search for matching entry
|
||
|
if [ "$(uci_get_state wireless @wifi-iface[$id] device)" == "$radio" ]; then
|
||
|
index=$id
|
||
|
fi
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
# if a SSID exist of both radios check if settings are equal and if they are equal overwrite both SSID settings
|
||
|
if [ "$index24" != "-1" ] && [ "$index5" != "-1" ]; then
|
||
|
if [ "$(uci_get_state wireless @wifi-iface[$index24] ssid)" == "$(uci_get_state wireless @wifi-iface[$index5] ssid)" ] &&
|
||
|
[ "$(uci_get_state wireless @wifi-iface[$index24] key)" == "$(uci_get_state wireless @wifi-iface[$index5] key)" ] &&
|
||
|
[ "$(uci_get_state wireless @wifi-iface[$index24] encryption)" == "$(uci_get_state wireless @wifi-iface[$index5] encryption)" ] &&
|
||
|
[ "$(uci_get_state wireless @wifi-iface[$index24] hidden)" == "$(uci_get_state wireless @wifi-iface[$index5] hidden)" ];then
|
||
|
use_common_setting=1
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
# if "use common setting" modify both radio entries
|
||
|
if [ "$use_common_setting" == "1" ]; then
|
||
|
uci_set wireless @wifi-iface[$index24] ssid "$ssid"
|
||
|
uci_set wireless @wifi-iface[$index5] ssid "$ssid"
|
||
|
uci_set wireless @wifi-iface[$index24] key "$psk"
|
||
|
uci_set wireless @wifi-iface[$index5] key "$psk"
|
||
|
case $encryption in
|
||
|
WPA2-PSK)
|
||
|
uci_set wireless @wifi-iface[$index24] encryption psk2
|
||
|
uci_set wireless @wifi-iface[$index5] encryption psk2
|
||
|
;;
|
||
|
WPA-PSK)
|
||
|
uci_set wireless @wifi-iface[$index24] encryption psk
|
||
|
uci_set wireless @wifi-iface[$index5] encryption psk
|
||
|
;;
|
||
|
NONE)
|
||
|
uci_set wireless @wifi-iface[$index24] encryption none
|
||
|
uci_set wireless @wifi-iface[$index5] encryption none
|
||
|
;;
|
||
|
esac
|
||
|
elif [ "$index" != "-1" ]; then
|
||
|
uci_set wireless @wifi-iface[$index] ssid "$ssid"
|
||
|
uci_set wireless @wifi-iface[$index] key "$psk"
|
||
|
case $encryption in
|
||
|
WPA2-PSK)
|
||
|
uci_set wireless @wifi-iface[$index] encryption psk2
|
||
|
;;
|
||
|
WPA-PSK)
|
||
|
uci_set wireless @wifi-iface[$index] encryption psk
|
||
|
;;
|
||
|
NONE)
|
||
|
uci_set wireless @wifi-iface[$index] encryption none
|
||
|
;;
|
||
|
esac
|
||
|
else
|
||
|
add_interface "$radio" "$ssid" "$psk" "$encryption"
|
||
|
fi
|
||
|
|
||
|
uci_commit wireless
|
||
|
}
|
||
|
|
||
|
remove_interface() {
|
||
|
local ifname="$1"
|
||
|
wpa_cli -g /var/run/wpa_supplicantglobal interface_remove $ifname
|
||
|
[ -f /var/run/wpa_supplicant-$ifname.pid ] && kill $(cat /var/run/wpa_supplicant-$ifname.pid)
|
||
|
rm -rf /var/run/wpa_supplicant-${ifname}*
|
||
|
wlanconfig $ifname destroy
|
||
|
}
|
||
|
|
||
|
# stop all wps cloning instances
|
||
|
remove_all_interfaces() {
|
||
|
for ifpath in $(ls -d /sys/class/net/athClone? 2>/dev/null); do
|
||
|
remove_interface $(basename $ifpath)
|
||
|
done
|
||
|
}
|
||
|
|
||
|
case "$CMD" in
|
||
|
CONNECTED)
|
||
|
# only accept first connect, if wps clone not successful yet
|
||
|
if [ "$(uci_get_state wireless wps_clone state)" != success ]; then
|
||
|
uci_set_state wireless wps_clone state success
|
||
|
uci_revert_state wireless wps_clone reason
|
||
|
|
||
|
wpa_cli -i$IFNAME -p /var/run/wpa_supplicant-$IFNAME save_config
|
||
|
radio=$(cat /sys/class/net/$IFNAME/parent)
|
||
|
# ssid/psk are strangely escaped (escaping \ " but not ' or $), don't use
|
||
|
status="$(wpa_cli -i$IFNAME -p/var/run/wpa_supplicant-$IFNAME status)"
|
||
|
encryption=$(echo "$status" | grep ^key_mgmt=)
|
||
|
encryption="${encryption#*=}"
|
||
|
# get ssid/psk from config instead
|
||
|
ssid="$(get_conf_var /var/run/wpa_supplicant-$IFNAME.conf ssid)"
|
||
|
psk="$(get_conf_var /var/run/wpa_supplicant-$IFNAME.conf psk)"
|
||
|
|
||
|
|
||
|
# Check if only one ssid is allowed
|
||
|
if [ "for now" != "only one ssid" ]; then
|
||
|
overwrite_interface_uci "$radio" "$ssid" "$psk" "$encryption"
|
||
|
else
|
||
|
add_interface_uci "$radio" "$ssid" "$psk" "$encryption"
|
||
|
fi
|
||
|
|
||
|
remove_interface $IFNAME
|
||
|
# we're done, stop all remaining wps cloning instances
|
||
|
remove_all_interfaces
|
||
|
reload_config # use procd to check for config changes
|
||
|
else
|
||
|
remove_interface $IFNAME
|
||
|
fi
|
||
|
;;
|
||
|
WPS-OVERLAP-DETECTED |\
|
||
|
WPS-FAIL |\
|
||
|
WPS-TIMEOUT)
|
||
|
if [ "$(uci_get_state wireless wps_clone state)" = running ]; then
|
||
|
uci_set_state wireless wps_clone state failed
|
||
|
uci_set_state wireless wps_clone reason $CMD
|
||
|
remove_interface $IFNAME
|
||
|
remove_all_interfaces
|
||
|
# force re-up all wifi interfaces (not done by driver/hostapd)
|
||
|
for ifname in $(ubus call uci state '{"config":"wireless","type":"wifi-iface"}'|\
|
||
|
jsonfilter -e "$.values[@.up='1'].ifname"); do
|
||
|
ip link set $ifname down
|
||
|
ip link set $ifname up
|
||
|
done
|
||
|
fi
|
||
|
;;
|
||
|
esac
|
||
|
|