--- /sbin/wifi-up.313
+++ /sbin/wifi-up.new
@@ -3,44 +3,205 @@
export PATH=/sbin:/bin
unset LD_LIBRARY_PATH
-wid="`iwgetid`"
-if [ $? -ne 0 ]; then
- echo "No wireless dongle detected."
- exit 0
-fi
+# set this to log details (including keys!)
+WLANDBG=1
-eth_check()
-{
+# some useful functions
+
+# save/restore functionality
+WLANCONF=/mod/etc/wlan.conf
+save_settings() {
+ local conf
+ [ -w "${WLANCONF%/*}" ] &&
+ # don't clobber it if it is being read as well as updated!
+ conf=$(swifi) &&
+ # don't clobber if swifi failed
+ [ 0 = "$(echo "${conf:-Failed: }" | grep -cF "Failed: ")" ] &&
+ { echo "# these settings are used if no settings are configured"
+ echo "$conf"; } > "$WLANCONF"
+}
+
+ip2x() { # a.b.c.d
+ set -- $(if [ -z "$1" ]; then cat; else echo "$*"; fi | sed 's/\./ /g')
+ printf "%02.2X%02.2X%02.2X%02.2X" "${1:-0}" "${2:-0}" "${3:-0}" "${4:-0}"
+}
+
+put_setting() { # parm value [type=Value [tag=ETHERNET_CONF_2ND]]
+ local type
+ local parm
+
+ # dbupdate command format
+ # dbname:tbl:parm:type:val -->
+ # attach '/var/lib/humaxtv/dbname.db/' as db;
+ # 'update or insert' db.TBL_tbl set itemName=parm,item<type>=val where itemName=parm; /* roughly */
+
+ # parm is prefixed with tag if not empty
+ printf "setup:MENUCONFIG:%s:%s:%s\n" "${parm:="${4:-ETHERNET_CONF_2ND}${1:+_$1}"}" "${type:=${3:-Value}}" "$2"
+ # with certain Blob parms, the Value must be set to 1 as well
+ case "${type}:${parm}" in
+ Blob:ETHERNET_CONF_*)
+ printf "setup:MENUCONFIG:%s:%s:%s\n" "$parm" Value 1
+ ;;
+ esac
+}
+
+# print a string of NULs to stdout
+nulls() { # len
+ if [ "$1" -gt 0 ]; then
+ printf "%*.*s\n" "$1" "$1" "" | sed 's/ /\d0/g'
+ fi
+}
+
+# hex-encode (len bytes or all) bytes of the input stream
+xxcode() { # [len] <stdin
+ # convert to hex-encoded bytes with no repeat elision
+ # allow for final \n in byte count, then strip its encoding
+ hexdump -v ${1:+-n "$(( $1 + 1 ))"} -e '/1 "%02X"' | sed -r 's/[[:xdigit:]]{2}$//'
+}
+
+# hex-encode a string right-padded with NULs
+xxpacks() { # sval len
+ local vlen
+ local plen
+
+ vlen=${#1}
+ [ "$vlen" -gt "$2" ] && vlen=$2
+ plen=$(( $2 - $vlen ))
+ # add a string of plen NULs
+ { printf "%*s" "$vlen" "$1"; nulls $plen; } | xxcode "$2"
+}
+
+auth_encode() { # triple
+ set -- $*
+ printf "%b\0\0\0%b\0\0\0%b\0\0\0\n" "\0$1" "\0$2" "\0$3" | xxcode
+}
+
+# save the current WLAN settings to the setup database
+# uses the dbupdate procedure, so a reboot is needed
+# undocumented hacks copied from webif/html/settings/modules/network/save.jim
+save_settings_db() {
+ # dbupdate script saved here will be executed on next reboot
+ local dbupdate="/mod/boot/dbupdate"
+
+ [ -w "$dbupdate" ] || return
+
+ local auth
+ local val
+ { case $(swifi manual) in
+ 1) # set manual and all parms
+ put_setting "" 1
+ put_setting IP "$(swifi ip | ip2x)" Blob
+ put_setting NETMASK "$(swifi mask | ip2x)" Blob
+ put_setting GATEWAY "$(swifi gw | ip2x)" Blob
+ put_setting DNS "$(swifi dns | ip2x)" Blob
+ ;;
+ 0) # set DHCP
+ put_setting "" 0
+ ;;
+ "Failed: "*) # eg empty database
+ return 1
+ ;;
+ esac
+
+ put_setting CONNECTED_AP 0 Value WLAN
+ put_setting IS_CONNECTED 1 Value WLAN
+ put_setting AUTH_TYPE "${auth:=$(swifi auth)}" Value WLAN
+
+ case $auth in
+ 8) auth="3 4 4" ;; # WPA2 PSK (AES)
+ 7) auth="3 4 2" ;; # WPA2 PSK (TKIP+AES)
+ 6) auth="2 3 4" ;; # WPA PSK (AES)
+ 5) auth="2 3 2" ;; # WPA PSK (TKIP)
+ # unconfirmed guesses? humaxtv always seems to say 'WEP 64-bit Hex'
+ 4) auth="1 1 2" ;; # WEP 128-bit ASCII # Guess
+ 3) auth="1 2 2" ;; # WEP 128-bit Hex # Guess
+ 2) auth="1 1 1" ;; # WEP 64-bit ASCII # Guess
+ 1) auth="1 0 1" ;; # WEP 64-bit Hex
+ *) auth="0 0 0" ;; # None
+ esac
+
+ # print the null padded ssid (max 104), auth (12), 4 NULs, key (max 132) as a hex-encoded 252 byte string
+ val=$(printf "%s%s%s%s" \
+ "$(xxpacks "$(swifi ssid)" 104)" "$(auth_encode $auth)" "$(xxpacks "" 4)" "$(xxpacks "$(swifi key)" 132)")
+ put_setting CONNECTED_AP "$val" Blob WLAN
+ } > "${dbupdate}/wifi_up"
+}
+
+eth_check() {
+ local eth=eth0
# If the Ethernet interface has no link, disable it.
- if ifconfig eth0 | grep -q RUNNING; then
- echo "Link found on eth0."
+ if ifconfig "$eth" | grep -q RUNNING; then
+ echo "Link found on $eth."
else
- echo "No link found on eth0, disabling."
- ifconfig eth0 down
+ echo "No link found on $eth, disabling."
+ ifconfig "$eth" down
+ ip route flush dev "$eth"
# Refresh hosts file
/sbin/modinit setup_hosts
fi
}
-wif="`echo $wid | sed 's/ .*//'`"
-essid=`echo $wid | cut -d\" -f2`
+# define a function to confirm active connection
+isConnected() { # ifname
+ [ -n "$(iwgetid --raw --ap "$1")" ]
+}
+# now start trying to connect
+wid=$(iwgetid) ||
+ { echo "No wireless dongle detected."; exit 0; }
+
+wif=${wid%% *}
+ssid=$(iwgetid --raw "$wif")
+
echo "Wireless interface: $wif"
-if [ -n "$essid" ]; then
- echo "Already connected to '$essid'"
+if [ -n "$ssid" ] && isConnected "$wif"; then
+ echo "Already connected to '$ssid'"
eth_check
+ save_settings
exit 0
fi
-wset()
-{
+# if no settings and saved settings exist, restore ...
+[ -z "$(swifi ssid)" ] && [ -r "$WLANCONF" ] &&
+ # ... by defining a replacement swifi
+ swifi() { # parm ...
+ local parm ptn
+ for parm in "${@:-..*}"; do
+ ptn="${ptn}${ptn:+|}${parm}"
+ done
+ if [ $# -eq 0 ]; then
+ grep -E "(${ptn})=" "$WLANCONF"
+ else
+ sed -nr "/(${ptn})=/ {s/^..*=//;p}" <"$WLANCONF"
+ fi
+ }
+
+if [ -n "$WLANDBG" ]; then
+ echo "== swifi"
+ swifi
+fi
+
+ssid=$(swifi ssid)
+if [ -z "$ssid" ]; then
+ echo "No SSID configured for $wif"
+ exit 1
+fi
+
+wset() { # param value
echo "Set $1=$2"
- iwpriv $wif set $1=$2
+ iwpriv "$wif" set "$1=$2"
}
-ifconfig $wif up
-wset NetworkType Infra
+ifconfig "$wif" up
+# enable all allowed channels
+# from rt2870 README_STA.txt:
+# region 31: use ch1-11:active scan, ch12-14 passive scan
+# otherwise defaults to region 7: use 5 ~ 13 Channel
+# alternatively try CountryRegion 0 (1-11) or (not in UK) 5 (1-14)
+wset CountryRegion 31
+# same as default
+# wset NetworkType Infra
# 0 None
# 1 WEP 64-bit Hex
@@ -54,7 +215,7 @@
# AuthMode {OPEN,SHARED,WEPAUTO,WPAPSK,WPA2PSK,WPANONE}
# EncrypType {NONE,WEP,TKIP,AES}
-authmode="`swifi auth`"
+authmode=$(swifi auth)
case $authmode in
0)
wset AuthMode OPEN
@@ -63,6 +224,7 @@
1|2|3|4)
wset AuthMode SHARED
wset EncrypType WEP
+ wset DefaultKeyID 1
;;
5) wset AuthMode WPAPSK
wset EncrypType TKIP
@@ -78,25 +240,80 @@
;;
esac
-ssid=`swifi ssid`
-psk=`swifi key`
-wpakey=`wpa_passphrase "$ssid" "$psk" | sed -n '4 { s/.*=//; p }'`
+psk=$(swifi key)
-wset SSID $ssid
-wset WPAPSK $wpakey
-wset SSID $ssid
+# add processing to handle WEP
+# also work around Humax failure to distinguish WEP key types
+isHex() {
+ [ -z "$(echo "${1:-Z}" | sed 's/[[:xdigit:]]*//')" ]
+}
-if [ "`swifi manual`" = 1 ]; then
+case $authmode in
+ 0) # no key
+ ;;
+
+ 1|2|3|4) # WEP, but may be confused wrt key type (see list above)
+ if [ ${#psk} -eq 10 ] && isHex "$psk"; then
+ authmode=1
+ elif [ ${#psk} -eq 26 ] && isHex "$psk"; then
+ authmode=3
+ # these will likely actually have length 5 or 13
+ elif [ ${#psk} -le 5 ]; then
+ authmode=2
+ elif [ ${#psk} -le 13 ]; then
+ authmode=4
+ fi
+
+ wset Key1 "$psk"
+ ;;
+
+ *) # apparently necessary to set SSID twice for WPA-PSK?
+ wset SSID "$ssid"
+ wset WPAPSK "$(wpa_passphrase "$ssid" "$psk" | sed -n '4 { s/.*=//; p }')"
+ ;;
+esac
+
+wset SSID "$ssid"
+
+if [ -n "$WLANDBG" ]; then
+ echo "== iwpriv show"
+ for p in NetworkType AuthMode EncrypType Key1 WPAPSK SSID; do
+ iwpriv "$wif" show "$p"
+ done
+fi
+
+if [ "$(swifi manual)" = 1 ]; then
echo "Manual config:"
set -x
- ifconfig $wif "`swifi ip`" netmask "`swifi mask`" up
- route add -net default gw "`swifi gw`"
- echo "nameserver `swifi dns`" > /etc/resolv.conf
+ # fix lost route - must eth_check before ifconfig
+ # see https://hummy.tv/forum/threads/wifi-static-manual-gateway-ip-occasionally-incorrect-on-startup.9657/post-139964
eth_check
+ ifconfig "$wif" "$(swifi ip)" netmask "$(swifi mask)" up
+ route add -net default gw "$(swifi gw)"
+ echo "nameserver $(swifi dns)" > /etc/resolv.conf
else
+ # wait for PHY connection
+ while ! isConnected "$wif"; do
+ sleep 2
+ done
eth_check
- echo "DHCP:"
- udhcpc -t 5 -T 10 -p /var/lib/humaxtv/udhcpc.$wif.pid -i $wif &
+ echo "$(date -Iseconds -u) DHCP:"
+ # file holds PID of $wif's udhcpc
+ pidf="/var/lib/humaxtv/udhcpc.$wif.pid"
+ # if udhcpc is running for $wif, renew the lease - or launch a new one
+ [ -s "$pidf" ] &&
+ pid=$(cat "$pidf") &&
+ kill -USR1 "$pid" 2>/dev/null ||
+ udhcpc -t 5 -T 10 -p "$pidf" -i "$wif" &
+ # give some time for above to work before next init routine?
sleep 7
+fi
+
+# if successful connection, save settings
+if isConnected "$wif"; then
+ # save to DB if DB was unpopulated
+ type swifi | grep -qF function && save_settings_db
+ # save safety copy to file
+ save_settings
fi