2016-10-16 15:54:48 +00:00
#!/bin/sh
# travelmate, a wlan connection manager for travel router
2020-04-24 06:28:16 +00:00
# Copyright (c) 2016-2020 Dirk Brenken (dev@brenken.org)
2016-10-16 15:54:48 +00:00
# This is free software, licensed under the GNU General Public License v3.
2020-04-24 06:28:16 +00:00
# set (s)hellcheck exceptions
# shellcheck disable=1091,2016,2039,2059,2086,2143,2181,2188
2019-08-29 12:03:23 +00:00
2017-03-04 19:30:04 +00:00
# set initial defaults
2016-10-16 15:54:48 +00:00
#
LC_ALL = C
PATH = "/usr/sbin:/usr/bin:/sbin:/bin"
2020-04-22 19:00:03 +00:00
trm_ver = "1.5.4"
2017-04-02 05:41:57 +00:00
trm_enabled = 0
2016-10-29 19:36:09 +00:00
trm_debug = 0
2019-03-19 14:23:11 +00:00
trm_iface = "trm_wwan"
2018-02-19 20:59:03 +00:00
trm_captive = 1
2018-10-30 14:19:58 +00:00
trm_proactive = 1
2019-04-09 14:53:24 +00:00
trm_netcheck = 0
2019-08-29 12:03:23 +00:00
trm_autoadd = 0
2018-02-19 20:59:03 +00:00
trm_captiveurl = "http://captive.apple.com"
2019-06-26 20:30:36 +00:00
trm_scanbuffer = 1024
2018-02-22 16:32:17 +00:00
trm_minquality = 35
2019-05-18 09:42:39 +00:00
trm_maxretry = 5
2017-04-20 07:22:22 +00:00
trm_maxwait = 30
2017-03-03 13:39:38 +00:00
trm_timeout = 60
2019-04-09 14:53:24 +00:00
trm_listexpiry = 0
2017-05-17 19:24:07 +00:00
trm_radio = ""
2018-02-19 20:59:03 +00:00
trm_connection = ""
2017-04-20 07:22:22 +00:00
trm_rtfile = "/tmp/trm_runtime.json"
2019-11-18 18:28:23 +00:00
trm_wifi = " $( command -v wifi) "
trm_wificmd = "reload"
2018-02-19 20:59:03 +00:00
trm_fetch = " $( command -v uclient-fetch) "
trm_iwinfo = " $( command -v iwinfo) "
2017-12-15 18:10:17 +00:00
trm_wpa = " $( command -v wpa_supplicant) "
2019-11-06 20:02:17 +00:00
trm_logger = " $( command -v logger) "
2018-04-04 12:30:30 +00:00
trm_action = " ${ 1 :- "start" } "
trm_pidfile = "/var/run/travelmate.pid"
2016-10-16 15:54:48 +00:00
2018-01-10 18:42:48 +00:00
# load travelmate environment
2017-03-04 19:30:04 +00:00
#
2019-11-18 18:28:23 +00:00
f_env( )
2016-10-16 15:54:48 +00:00
{
2019-10-18 10:37:37 +00:00
local IFS check wpa_checks
2017-12-09 07:20:29 +00:00
2019-02-22 10:59:14 +00:00
# (re-)initialize global list variables
#
unset trm_devlist trm_stalist trm_radiolist trm_active_sta
2018-09-08 20:28:04 +00:00
# get system information
#
2019-08-29 12:03:23 +00:00
trm_sysver = " $( ubus -S call system board 2>/dev/null | jsonfilter -e '@.model' -e '@.release.description' | \
awk 'BEGIN{ORS=", "}{print $0}' | awk '{print substr($0,1,length($0)-2)}' ) "
2017-12-09 07:20:29 +00:00
2018-09-08 20:28:04 +00:00
# load config and check 'enabled' option
#
2019-03-19 14:23:11 +00:00
config_cb( )
2018-09-08 20:28:04 +00:00
{
2019-03-19 14:23:11 +00:00
local name = " ${ 1 } " type = " ${ 2 } "
if [ " ${ name } " = "travelmate" ] && [ " ${ type } " = "global" ]
2019-03-07 13:24:06 +00:00
then
2019-03-19 14:23:11 +00:00
option_cb( )
{
local option = " ${ 1 } " value = " ${ 2 } "
eval " ${ option } =\" ${ value } \" "
}
else
option_cb( )
{
return 0
}
2019-03-07 13:24:06 +00:00
fi
2018-09-08 20:28:04 +00:00
}
config_load travelmate
2016-12-31 13:14:29 +00:00
2019-05-24 12:21:02 +00:00
if [ " ${ trm_enabled } " -ne 1 ]
2018-09-08 20:28:04 +00:00
then
f_log "info" "travelmate is currently disabled, please set 'trm_enabled' to '1' to use this service"
2019-11-06 20:02:17 +00:00
> " ${ trm_pidfile } "
2018-09-08 20:28:04 +00:00
exit 0
fi
2017-12-15 18:10:17 +00:00
2019-11-18 18:28:23 +00:00
# get wpa_supplicant capabilities
#
wpa_checks = "eap sae owe"
for check in ${ wpa_checks }
do
if [ -x " ${ trm_wpa } " ]
then
eval " trm_ ${ check } check=\" $( " ${ trm_wpa } " -v${ check } >/dev/null 2>& 1; printf "%u" " ${ ? } " ) \" "
else
eval " trm_ ${ check } check=\"1\" "
fi
done
# get wifi reconf capabilities
#
if [ -n " $( grep -F "reconf" " ${ trm_wifi } " 2>/dev/null) " ]
then
trm_wificmd = "reconf"
fi
# enable 'disabled' wifi devices
#
config_load wireless
config_foreach f_prepdev wifi-device
if [ -n " $( uci -q changes "wireless" ) " ]
then
uci_commit "wireless"
" ${ trm_wifi } " " ${ trm_wificmd } "
sleep $(( trm_maxwait/6))
fi
2018-09-08 20:28:04 +00:00
# validate input ranges
#
2019-05-24 12:21:02 +00:00
if [ " ${ trm_minquality } " -lt 20 ] || [ " ${ trm_minquality } " -gt 80 ]
2018-09-08 20:28:04 +00:00
then
trm_minquality = 35
fi
2019-05-24 12:21:02 +00:00
if [ " ${ trm_listexpiry } " -lt 0 ] || [ " ${ trm_listexpiry } " -gt 300 ]
2019-04-09 14:53:24 +00:00
then
trm_listexpiry = 0
fi
2019-05-24 12:21:02 +00:00
if [ " ${ trm_maxretry } " -lt 1 ] || [ " ${ trm_maxretry } " -gt 10 ]
2018-09-08 20:28:04 +00:00
then
2019-04-09 14:53:24 +00:00
trm_maxretry = 5
2018-09-08 20:28:04 +00:00
fi
2019-05-24 12:21:02 +00:00
if [ " ${ trm_maxwait } " -lt 20 ] || [ " ${ trm_maxwait } " -gt 40 ] || [ " ${ trm_maxwait } " -ge " ${ trm_timeout } " ]
2018-09-08 20:28:04 +00:00
then
trm_maxwait = 30
fi
2019-05-24 12:21:02 +00:00
if [ " ${ trm_timeout } " -lt 30 ] || [ " ${ trm_timeout } " -gt 300 ] || [ " ${ trm_timeout } " -le " ${ trm_maxwait } " ]
2018-09-08 20:28:04 +00:00
then
trm_timeout = 60
fi
2019-03-19 14:23:11 +00:00
# load json runtime file
#
json_load_file " ${ trm_rtfile } " >/dev/null 2>& 1
json_select data >/dev/null 2>& 1
2019-05-24 12:21:02 +00:00
if [ " ${ ? } " -ne 0 ]
2019-03-19 14:23:11 +00:00
then
> " ${ trm_rtfile } "
json_init
json_add_object "data"
fi
2019-11-18 18:28:23 +00:00
f_log "debug" " f_env ::: trm_eapcheck: ${ trm_eapcheck :- "-" } , trm_saecheck: ${ trm_saecheck :- "-" } , trm_owecheck: ${ trm_owecheck :- "-" } , trm_wificmd: ${ trm_wificmd } "
}
# trim leading and trailing whitespace characters
#
f_trim( )
{
local IFS trim = " ${ 1 } "
trim = " ${ trim # " ${ trim %%[![ : space : ]]* } " } "
trim = " ${ trim % " ${ trim ##*[![ : space : ]] } " } "
printf '%s' " ${ trim } "
2016-10-16 15:54:48 +00:00
}
2019-10-21 18:37:08 +00:00
# prepare the 'wifi-device' sections
2016-12-02 20:57:56 +00:00
#
2019-10-21 18:37:08 +00:00
f_prepdev( )
{
local IFS disabled config = " ${ 1 } "
disabled = " $( uci_get "wireless" " ${ config } " "disabled" ) "
if [ " ${ disabled } " = "1" ]
then
uci_set wireless " ${ config } " disabled 0
fi
2019-11-18 18:28:23 +00:00
f_log "debug" " f_prepdev ::: config: ${ config } , disabled: ${ disabled :- "-" } "
2019-10-21 18:37:08 +00:00
}
# prepare the 'wifi-iface' sections
#
f_prepif( )
2016-12-02 20:57:56 +00:00
{
2019-10-18 10:37:37 +00:00
local IFS mode network radio encryption eaptype disabled config = " ${ 1 } " proactive = " ${ 2 } "
2019-05-24 12:21:02 +00:00
2019-08-29 12:03:23 +00:00
mode = " $( uci_get "wireless" " ${ config } " "mode" ) "
network = " $( uci_get "wireless" " ${ config } " "network" ) "
radio = " $( uci_get "wireless" " ${ config } " "device" ) "
2019-10-18 10:37:37 +00:00
encryption = " $( uci_get "wireless" " ${ config } " "encryption" ) "
2019-08-29 12:03:23 +00:00
eaptype = " $( uci_get "wireless" " ${ config } " "eap_type" ) "
2019-10-18 10:37:37 +00:00
disabled = " $( uci_get "wireless" " ${ config } " "disabled" ) "
2019-02-15 08:29:58 +00:00
if [ -n " ${ config } " ] && [ -n " ${ radio } " ] && [ -n " ${ mode } " ] && [ -n " ${ network } " ]
2018-09-08 20:28:04 +00:00
then
2019-02-15 08:29:58 +00:00
if [ -z " ${ trm_radio } " ] && [ -z " $( printf "%s" " ${ trm_radiolist } " | grep -Fo " ${ radio } " ) " ]
2018-09-08 20:28:04 +00:00
then
2019-02-15 08:29:58 +00:00
trm_radiolist = " $( f_trim " ${ trm_radiolist } ${ radio } " ) "
elif [ -n " ${ trm_radio } " ] && [ -z " ${ trm_radiolist } " ]
2018-10-30 14:19:58 +00:00
then
2019-02-15 08:29:58 +00:00
trm_radiolist = " $( f_trim " $( printf "%s" " ${ trm_radio } " | \
2020-04-22 19:00:03 +00:00
awk '{while(match(tolower($0),/[a-z0-9]+/)){ORS=" ";print substr(tolower($0),RSTART,RLENGTH);$0=substr($0,RSTART+RLENGTH)}}' ) ")"
2018-09-08 20:28:04 +00:00
fi
2019-02-15 08:29:58 +00:00
if [ " ${ mode } " = "sta" ] && [ " ${ network } " = " ${ trm_iface } " ]
2018-09-08 20:28:04 +00:00
then
2019-05-24 12:21:02 +00:00
if { [ -z " ${ disabled } " ] || [ " ${ disabled } " = "0" ] ; } && { [ " ${ proactive } " -eq 0 ] || [ " ${ trm_ifstatus } " != "true" ] ; }
2019-02-15 08:29:58 +00:00
then
uci_set wireless " ${ config } " disabled 1
2019-10-21 18:37:08 +00:00
elif [ " ${ disabled } " = "0" ] && [ " ${ trm_ifstatus } " = "true" ] && [ " ${ proactive } " -eq 1 ]
2019-02-15 08:29:58 +00:00
then
2019-10-21 18:37:08 +00:00
if [ -z " ${ trm_active_sta } " ]
then
trm_active_sta = " ${ config } "
else
uci_set wireless " ${ config } " disabled 1
fi
2019-02-15 08:29:58 +00:00
fi
2019-10-18 10:37:37 +00:00
if [ -z " ${ eaptype } " ] || { [ -n " ${ eaptype } " ] && [ " ${ trm_eapcheck } " -eq 0 ] ; }
2019-02-15 08:29:58 +00:00
then
2019-10-18 10:37:37 +00:00
if { [ " ${ encryption %-* } " != "sae" ] && [ " ${ encryption %-* } " != "wpa3" ] && [ " ${ encryption } " != "owe" ] ; } || \
{ { [ " ${ encryption %-* } " = "sae" ] || [ " ${ encryption %-* } " = "wpa3" ] ; } && [ " ${ trm_saecheck } " -eq 0 ] ; } || \
{ [ " ${ encryption } " = "owe" ] && [ " ${ trm_owecheck } " -eq 0 ] ; }
then
trm_stalist = " $( f_trim " ${ trm_stalist } ${ config } - ${ radio } " ) "
fi
2019-02-15 08:29:58 +00:00
fi
2018-09-08 20:28:04 +00:00
fi
fi
2019-11-18 18:28:23 +00:00
f_log "debug" " f_prepif ::: config: ${ config } , mode: ${ mode } , network: ${ network } , radio: ${ radio } , trm_radio: ${ trm_radio :- "-" } , trm_active_sta: ${ trm_active_sta :- "-" } , proactive: ${ proactive } , disabled: ${ disabled } "
2016-12-02 20:57:56 +00:00
}
2019-08-29 12:03:23 +00:00
# check net status
#
f_net( )
{
2020-04-29 12:48:36 +00:00
local IFS raw result
2019-08-29 12:03:23 +00:00
2020-04-29 12:48:36 +00:00
raw = " $( ${ trm_fetch } --timeout= $(( trm_maxwait/6)) " ${ trm_captiveurl } " -O /dev/null 2>& 1 | tail -n 1) "
raw = " $( printf "%s" " ${ raw //[ \? \$ \% \& \+ \| \' \" \: \* \= \/ ]/ } " ) "
result = " $( printf "%s" " ${ raw } " | awk '/^Failed to redirect|^Redirected/{printf "%s","net cp";exit}/^Download completed/{printf "%s","net ok";exit}/^Failed|Connection error/{printf "%s","net nok";exit}' ) "
if [ " ${ result } " = "net cp" ]
then
result = " $( printf "%s" " ${ raw //*on / } " | awk 'match($0,/^([[:alnum:]_-]+\.)+[[:alpha:]]+/){printf "%s","net cp \047"substr(tolower($0),RSTART,RLENGTH)"\047"}' ) "
fi
2019-08-29 12:03:23 +00:00
printf "%s" " ${ result } "
2019-10-21 18:37:08 +00:00
f_log "debug" " f_net ::: fetch: ${ trm_fetch } , timeout: $(( trm_maxwait/6)) , url: ${ trm_captiveurl } , result: ${ result } "
2019-08-29 12:03:23 +00:00
}
2018-01-10 18:42:48 +00:00
# check interface status
2017-03-04 19:30:04 +00:00
#
2016-12-02 20:57:56 +00:00
f_check( )
2016-10-16 15:54:48 +00:00
{
2020-04-22 19:00:03 +00:00
local IFS ifname radio dev_status result uci_section login_command login_command_args wait_time = 1 mode = " ${ 1 } " status = " ${ 2 :- "false" } " cp_domain = " ${ 3 :- "false" } "
2016-10-16 15:54:48 +00:00
2019-11-18 18:28:23 +00:00
if [ " ${ mode } " != "initial" ] && [ " ${ mode } " != "dev" ] && [ " ${ status } " = "false" ]
2018-09-08 20:28:04 +00:00
then
2019-11-18 18:28:23 +00:00
" ${ trm_wifi } " " ${ trm_wificmd } "
sleep $(( trm_maxwait/6))
2018-09-08 20:28:04 +00:00
fi
2019-04-09 14:53:24 +00:00
2019-08-06 13:29:00 +00:00
while [ " ${ wait_time } " -le " ${ trm_maxwait } " ]
2018-09-08 20:28:04 +00:00
do
dev_status = " $( ubus -S call network.wireless status 2>/dev/null) "
if [ -n " ${ dev_status } " ]
then
if [ " ${ mode } " = "dev" ]
then
if [ " ${ trm_ifstatus } " != " ${ status } " ]
then
trm_ifstatus = " ${ status } "
f_jsnup
fi
for radio in ${ trm_radiolist }
do
result = " $( printf "%s" " ${ dev_status } " | jsonfilter -l1 -e " @. ${ radio } .up " ) "
2019-01-24 12:58:38 +00:00
if [ " ${ result } " = "true" ] && [ -z " $( printf "%s" " ${ trm_devlist } " | grep -Fo " ${ radio } " ) " ]
2018-09-08 20:28:04 +00:00
then
2018-10-30 14:19:58 +00:00
trm_devlist = " $( f_trim " ${ trm_devlist } ${ radio } " ) "
2018-09-08 20:28:04 +00:00
fi
done
2019-08-06 13:29:00 +00:00
if [ " ${ trm_devlist } " = " ${ trm_radiolist } " ] || [ " ${ wait_time } " -eq " ${ trm_maxwait } " ]
2018-09-08 20:28:04 +00:00
then
ifname = " ${ trm_devlist } "
break
else
unset trm_devlist
fi
elif [ " ${ mode } " = "rev" ]
then
break
else
ifname = " $( printf "%s" " ${ dev_status } " | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].ifname' ) "
if [ -n " ${ ifname } " ]
then
2019-05-24 12:21:02 +00:00
trm_ifquality = " $( ${ trm_iwinfo } " ${ ifname } " info 2>/dev/null | awk -F "[ ]" '/Link Quality:/{split($NF,var0,"/");printf "%i\n",(var0[1]*100/var0[2])}' ) "
if [ " ${ mode } " = "initial" ] && [ " ${ trm_captive } " -eq 1 ]
2018-09-08 20:28:04 +00:00
then
2019-08-29 12:03:23 +00:00
result = " $( f_net) "
2019-08-06 13:29:00 +00:00
if [ " ${ cp_domain } " = "true" ]
then
cp_domain = " $( printf "%s" " ${ result } " | awk -F "[\\'| ]" '/^net cp/{printf "%s" $4}' ) "
2020-04-22 19:00:03 +00:00
uci_section = " $( printf "%s" " ${ dev_status } " | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].section' ) "
2019-08-06 13:29:00 +00:00
fi
2018-09-08 20:28:04 +00:00
fi
2019-08-06 13:29:00 +00:00
if [ " ${ trm_ifquality } " -ge " ${ trm_minquality } " ] && [ " ${ result } " != "net nok" ]
2019-03-07 13:24:06 +00:00
then
2019-04-09 14:53:24 +00:00
trm_ifstatus = " $( ubus -S call network.interface dump 2>/dev/null | jsonfilter -l1 -e " @.interface[@.device=\" ${ ifname } \"].up " ) "
if [ " ${ trm_ifstatus } " = "true" ]
2019-02-22 10:59:14 +00:00
then
2019-08-06 13:29:00 +00:00
if [ " ${ mode } " = "sta" ] && [ " ${ trm_captive } " -eq 1 ]
2019-04-09 14:53:24 +00:00
then
2019-05-24 12:21:02 +00:00
while true
do
2019-08-29 12:03:23 +00:00
result = " $( f_net) "
2019-05-24 12:21:02 +00:00
cp_domain = " $( printf "%s" " ${ result } " | awk -F "[\\'| ]" '/^net cp/{printf "%s" $4}' ) "
2020-04-22 19:00:03 +00:00
uci_section = " $( printf "%s" " ${ dev_status } " | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].section' ) "
2019-08-06 13:29:00 +00:00
if [ " ${ trm_netcheck } " -eq 1 ] && [ " ${ result } " = "net nok" ]
2019-05-24 12:21:02 +00:00
then
trm_ifstatus = " ${ status } "
f_jsnup
break 2
fi
2019-08-29 12:03:23 +00:00
if [ -z " ${ cp_domain } " ] || [ -n " $( uci_get "dhcp" "@dnsmasq[0]" "rebind_domain" | grep -Fo " ${ cp_domain } " ) " ]
2019-05-24 12:21:02 +00:00
then
break
fi
uci -q add_list dhcp.@dnsmasq[ 0] .rebind_domain= " ${ cp_domain } "
2019-08-06 13:29:00 +00:00
f_log "info" " captive portal domain ' ${ cp_domain } ' added to to dhcp rebind whitelist "
2020-04-22 19:00:03 +00:00
if [ -z " $( uci_get "travelmate" " ${ uci_section } " ) " ]
2019-08-06 13:29:00 +00:00
then
2020-04-22 19:00:03 +00:00
uci_add travelmate "login" " ${ uci_section } "
uci_set travelmate " ${ uci_section } " "command" "none"
f_log "info" " captive portal login section ' ${ uci_section } ' added to travelmate config section "
2019-08-06 13:29:00 +00:00
fi
2019-05-24 12:21:02 +00:00
done
2019-08-29 12:03:23 +00:00
if [ -n " $( uci -q changes "dhcp" ) " ]
2019-04-09 14:53:24 +00:00
then
2019-08-29 12:03:23 +00:00
uci_commit "dhcp"
2019-05-24 12:21:02 +00:00
/etc/init.d/dnsmasq reload
2019-04-09 14:53:24 +00:00
fi
2019-08-29 12:03:23 +00:00
if [ -n " $( uci -q changes "travelmate" ) " ]
2019-08-06 13:29:00 +00:00
then
2019-08-29 12:03:23 +00:00
uci_commit "travelmate"
2019-08-06 13:29:00 +00:00
fi
fi
2020-04-22 19:00:03 +00:00
if [ -n " ${ cp_domain } " ] && [ " ${ cp_domain } " != "false" ] && [ -n " ${ uci_section } " ] && [ " ${ trm_captive } " -eq 1 ]
2019-08-06 13:29:00 +00:00
then
trm_connection = " ${ result :- "-" } / ${ trm_ifquality } "
f_jsnup
2020-04-22 19:00:03 +00:00
login_command = " $( uci_get "travelmate" " ${ uci_section } " "command" ) "
2019-08-06 13:29:00 +00:00
if [ -x " ${ login_command } " ]
then
2020-04-22 19:00:03 +00:00
login_command_args = " $( uci_get "travelmate" " ${ uci_section } " "command_args" ) "
2019-09-19 21:17:42 +00:00
" ${ login_command } " ${ login_command_args } >/dev/null 2>& 1
2019-08-06 13:29:00 +00:00
rc = ${ ? }
2019-10-18 10:37:37 +00:00
f_log "info" " captive portal login ' ${ login_command : 0 : 40 } ${ login_command_args : 0 : 20 } ' for ' ${ cp_domain } ' has been executed with rc ' ${ rc } ' "
2019-08-06 13:29:00 +00:00
if [ " ${ rc } " -eq 0 ]
then
2019-08-29 12:03:23 +00:00
result = " $( f_net) "
2019-08-06 13:29:00 +00:00
fi
fi
2019-04-09 14:53:24 +00:00
fi
2019-05-24 12:21:02 +00:00
trm_connection = " ${ result :- "-" } / ${ trm_ifquality } "
2019-04-09 14:53:24 +00:00
f_jsnup
break
fi
2019-05-24 12:21:02 +00:00
elif [ -n " ${ trm_connection } " ]
then
2020-04-22 19:00:03 +00:00
uci_section = " $( printf "%s" " ${ dev_status } " | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].section' ) "
2019-05-24 12:21:02 +00:00
if [ " ${ trm_ifquality } " -lt " ${ trm_minquality } " ]
2019-04-09 14:53:24 +00:00
then
2019-08-06 13:29:00 +00:00
unset trm_connection
trm_ifstatus = " ${ status } "
2020-04-22 19:00:03 +00:00
f_log "info" " uplink ' ${ uci_section } ' is out of range ( ${ trm_ifquality } / ${ trm_minquality } ) "
2019-08-06 13:29:00 +00:00
elif [ " ${ trm_netcheck } " -eq 1 ] && [ " ${ result } " = "net nok" ]
2019-05-24 12:21:02 +00:00
then
2019-08-06 13:29:00 +00:00
unset trm_connection
trm_ifstatus = " ${ status } "
2020-04-22 19:00:03 +00:00
f_log "info" " uplink ' ${ uci_section } ' has no internet ( ${ result } ) "
2019-02-22 10:59:14 +00:00
fi
2018-09-08 20:28:04 +00:00
f_jsnup
2019-04-09 14:53:24 +00:00
break
2019-05-24 12:21:02 +00:00
elif [ " ${ mode } " = "initial" ]
then
f_jsnup
break
2018-09-08 20:28:04 +00:00
fi
2019-05-24 12:21:02 +00:00
elif [ -n " ${ trm_connection } " ]
then
unset trm_connection
trm_ifstatus = " ${ status } "
f_jsnup
break
elif [ " ${ mode } " = "initial" ]
then
f_jsnup
break
2018-09-08 20:28:04 +00:00
fi
fi
fi
2019-08-06 13:29:00 +00:00
wait_time = $(( wait_time+1))
2018-09-08 20:28:04 +00:00
sleep 1
done
2019-10-21 18:37:08 +00:00
f_log "debug" " f_check ::: mode: ${ mode } , name: ${ ifname :- "-" } , status: ${ trm_ifstatus } , connection: ${ trm_connection :- "-" } , wait: ${ wait_time } , max_wait: ${ trm_maxwait } , min_quality: ${ trm_minquality } , captive: ${ trm_captive } , netcheck: ${ trm_netcheck } "
2016-10-16 15:54:48 +00:00
}
2018-01-10 18:42:48 +00:00
# update runtime information
2017-03-04 19:30:04 +00:00
#
2018-01-10 18:42:48 +00:00
f_jsnup( )
2017-03-04 19:30:04 +00:00
{
2020-04-22 19:00:03 +00:00
local IFS uci_section d1 d2 d3 last_date last_station sta_iface sta_radio sta_essid sta_bssid last_status dev_status wpa_status status = " ${ trm_ifstatus } " faulty_list faulty_station = " ${ 1 } "
2017-04-02 05:41:57 +00:00
2018-09-08 20:28:04 +00:00
dev_status = " $( ubus -S call network.wireless status 2>/dev/null) "
if [ -n " ${ dev_status } " ]
then
2020-04-22 19:00:03 +00:00
uci_section = " $( printf "%s" " ${ dev_status } " | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].section' ) "
if [ -n " ${ uci_section } " ]
2018-09-08 20:28:04 +00:00
then
2020-04-22 19:00:03 +00:00
sta_iface = " $( uci_get "wireless" " ${ uci_section } " "network" ) "
sta_radio = " $( uci_get "wireless" " ${ uci_section } " "device" ) "
sta_essid = " $( uci_get "wireless" " ${ uci_section } " "ssid" ) "
sta_bssid = " $( uci_get "wireless" " ${ uci_section } " "bssid" ) "
2018-09-08 20:28:04 +00:00
fi
fi
2018-02-27 13:26:18 +00:00
2019-04-09 14:53:24 +00:00
json_get_var last_date "last_rundate"
json_get_var last_station "station_id"
if [ " ${ status } " = "true" ]
then
status = " connected ( ${ trm_connection :- "-" } ) "
json_get_var last_status "travelmate_status"
if [ " ${ last_status } " = "running / not connected" ] || [ " ${ last_station } " != " ${ sta_radio :- "-" } / ${ sta_essid :- "-" } / ${ sta_bssid :- "-" } " ]
then
2019-10-18 10:37:37 +00:00
last_date = " $( date "+%Y.%m.%d-%H:%M:%S" ) "
2019-04-09 14:53:24 +00:00
fi
2019-05-24 12:21:02 +00:00
elif [ " ${ status } " = "error" ]
then
unset trm_connection
status = "program error"
2019-04-09 14:53:24 +00:00
else
unset trm_connection
status = "running / not connected"
fi
if [ -z " ${ last_date } " ]
then
2019-10-18 10:37:37 +00:00
last_date = " $( date "+%Y.%m.%d-%H:%M:%S" ) "
2019-04-09 14:53:24 +00:00
fi
2018-09-08 20:28:04 +00:00
json_get_var faulty_list "faulty_stations"
2019-05-24 12:21:02 +00:00
if [ -n " ${ faulty_list } " ] && [ " ${ trm_listexpiry } " -gt 0 ]
2019-04-09 14:53:24 +00:00
then
2019-10-18 10:37:37 +00:00
d1 = " $( date -d " ${ last_date } " "+%s" ) "
d2 = " $( date "+%s" ) "
2019-05-24 12:21:02 +00:00
d3 = $(( ( d2 - d1) / 60 ))
if [ " ${ d3 } " -ge " ${ trm_listexpiry } " ]
2019-04-09 14:53:24 +00:00
then
faulty_list = ""
fi
fi
2019-03-26 21:51:40 +00:00
if [ -n " ${ faulty_station } " ]
2018-09-08 20:28:04 +00:00
then
if [ -z " $( printf "%s" " ${ faulty_list } " | grep -Fo " ${ faulty_station } " ) " ]
then
2018-10-30 14:19:58 +00:00
faulty_list = " $( f_trim " ${ faulty_list } ${ faulty_station } " ) "
2019-10-18 10:37:37 +00:00
last_date = " $( date "+%Y.%m.%d-%H:%M:%S" ) "
2018-09-08 20:28:04 +00:00
fi
fi
2019-10-18 10:37:37 +00:00
if [ " ${ trm_eapcheck } " -eq 0 ]
then
wpa_status = "EAP"
else
wpa_status = "-"
fi
if [ " ${ trm_saecheck } " -eq 0 ]
then
wpa_status = " ${ wpa_status } /SAE "
else
wpa_status = " ${ wpa_status } /- "
fi
if [ " ${ trm_owecheck } " -eq 0 ]
then
wpa_status = " ${ wpa_status } /OWE "
else
wpa_status = " ${ wpa_status } /- "
fi
2018-09-08 20:28:04 +00:00
json_add_string "travelmate_status" " ${ status } "
json_add_string "travelmate_version" " ${ trm_ver } "
json_add_string "station_id" " ${ sta_radio :- "-" } / ${ sta_essid :- "-" } / ${ sta_bssid :- "-" } "
json_add_string "station_interface" " ${ sta_iface :- "-" } "
json_add_string "faulty_stations" " ${ faulty_list } "
2019-10-18 10:37:37 +00:00
json_add_string "wpa_capabilities" " ${ wpa_status :- "-" } "
2019-04-09 14:53:24 +00:00
json_add_string "last_rundate" " ${ last_date } "
2018-09-08 20:28:04 +00:00
json_add_string "system" " ${ trm_sysver } "
json_dump > " ${ trm_rtfile } "
2020-04-22 19:00:03 +00:00
f_log "debug" " f_jsnup ::: uci_section: ${ uci_section :- "-" } , status: ${ status :- "-" } , sta_iface: ${ sta_iface :- "-" } , sta_radio: ${ sta_radio :- "-" } , sta_essid: ${ sta_essid :- "-" } , sta_bssid: ${ sta_bssid :- "-" } , faulty_list: ${ faulty_list :- "-" } , list_expiry: ${ trm_listexpiry } "
2017-04-20 07:22:22 +00:00
}
2018-01-10 18:42:48 +00:00
# write to syslog
2016-10-16 15:54:48 +00:00
#
2016-12-02 20:57:56 +00:00
f_log( )
2016-10-16 15:54:48 +00:00
{
2019-03-19 14:23:11 +00:00
local IFS class = " ${ 1 } " log_msg = " ${ 2 } "
2016-10-16 15:54:48 +00:00
2019-05-24 12:21:02 +00:00
if [ -n " ${ log_msg } " ] && { [ " ${ class } " != "debug" ] || [ " ${ trm_debug } " -eq 1 ] ; }
2018-09-08 20:28:04 +00:00
then
2019-11-06 20:02:17 +00:00
if [ -x " ${ trm_logger } " ]
then
" ${ trm_logger } " -p " ${ class } " -t " travelmate- ${ trm_ver } [ ${ $} ] " " ${ log_msg } "
else
printf "%s %s %s\\n" " ${ class } " " travelmate- ${ trm_ver } [ ${ $} ] " " ${ log_msg } "
fi
2018-09-08 20:28:04 +00:00
if [ " ${ class } " = "err" ]
then
trm_ifstatus = "error"
f_jsnup
2019-11-06 20:02:17 +00:00
> " ${ trm_pidfile } "
2018-09-08 20:28:04 +00:00
exit 1
fi
fi
2016-10-16 15:54:48 +00:00
}
2018-01-10 18:42:48 +00:00
# main function for connection handling
2017-03-04 19:30:04 +00:00
#
2016-12-31 13:14:29 +00:00
f_main( )
2016-10-16 15:54:48 +00:00
{
2020-04-22 19:00:03 +00:00
local IFS cnt dev config spec scan_dev scan_list scan_essid scan_bssid scan_open scan_quality uci_essid cfg_essid faulty_list
2019-03-19 14:23:11 +00:00
local station_id sta sta_essid sta_bssid sta_radio sta_iface active_essid active_bssid active_radio
2016-10-16 15:54:48 +00:00
2019-08-06 13:29:00 +00:00
f_check "initial" "false" "true"
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: status: ${ trm_ifstatus } , proactive: ${ trm_proactive } "
2019-05-24 12:21:02 +00:00
if [ " ${ trm_ifstatus } " != "true" ] || [ " ${ trm_proactive } " -eq 1 ]
2018-09-08 20:28:04 +00:00
then
2019-11-18 18:28:23 +00:00
config_load wireless
2019-10-21 18:37:08 +00:00
config_foreach f_prepif wifi-iface ${ trm_proactive }
2019-05-24 12:21:02 +00:00
if [ " ${ trm_ifstatus } " = "true" ] && [ -n " ${ trm_active_sta } " ] && [ " ${ trm_proactive } " -eq 1 ]
2018-10-30 14:19:58 +00:00
then
json_get_var station_id "station_id"
active_radio = " ${ station_id %%/* } "
active_essid = " ${ station_id %/* } "
active_essid = " ${ active_essid #*/ } "
active_bssid = " ${ station_id ##*/ } "
f_check "dev" "true"
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: active_radio: ${ active_radio } , active_essid: \" ${ active_essid } \", active_bssid: ${ active_bssid :- "-" } "
2018-10-30 14:19:58 +00:00
else
2019-08-29 12:03:23 +00:00
uci_commit "wireless"
2018-10-30 14:19:58 +00:00
f_check "dev"
fi
2018-09-08 20:28:04 +00:00
json_get_var faulty_list "faulty_stations"
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: iwinfo: ${ trm_iwinfo :- "-" } , dev_list: ${ trm_devlist :- "-" } , sta_list: ${ trm_stalist : 0 : ${ trm_scanbuffer } } , faulty_list: ${ faulty_list :- "-" } "
2019-03-19 14:23:11 +00:00
# radio loop
#
2018-09-08 20:28:04 +00:00
for dev in ${ trm_devlist }
do
2019-05-24 12:21:02 +00:00
if [ -z " $( printf "%s" " ${ trm_stalist } " | grep -o " \\- ${ dev } " ) " ]
2018-09-08 20:28:04 +00:00
then
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: no station on ' ${ dev } ' - continue "
2018-09-08 20:28:04 +00:00
continue
fi
2019-03-19 14:23:11 +00:00
# station loop
#
for sta in ${ trm_stalist }
2018-09-08 20:28:04 +00:00
do
2019-03-19 14:23:11 +00:00
config = " ${ sta %%-* } "
sta_radio = " ${ sta ##*- } "
2019-08-29 12:03:23 +00:00
sta_essid = " $( uci_get "wireless" " ${ config } " "ssid" ) "
sta_bssid = " $( uci_get "wireless" " ${ config } " "bssid" ) "
sta_iface = " $( uci_get "wireless" " ${ config } " "network" ) "
2019-03-19 14:23:11 +00:00
json_get_var faulty_list "faulty_stations"
if [ -n " $( printf "%s" " ${ faulty_list } " | grep -Fo " ${ sta_radio } / ${ sta_essid } / ${ sta_bssid } " ) " ]
then
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: faulty station ' ${ sta_radio } / ${ sta_essid } / ${ sta_bssid :- "-" } ' - continue "
2019-03-19 14:23:11 +00:00
continue
fi
if [ " ${ dev } " = " ${ active_radio } " ] && [ " ${ sta_essid } " = " ${ active_essid } " ] && [ " ${ sta_bssid :- "-" } " = " ${ active_bssid } " ]
then
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: active station prioritized ' ${ active_radio } / ${ active_essid } / ${ active_bssid :- "-" } ' - break "
2019-03-19 14:23:11 +00:00
break 2
fi
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: sta_radio: ${ sta_radio } , sta_essid: \" ${ sta_essid } \", sta_bssid: ${ sta_bssid :- "-" } "
2019-03-19 14:23:11 +00:00
if [ -z " ${ scan_list } " ]
then
2020-04-24 06:28:16 +00:00
scan_dev = " $( ubus -S call network.wireless status 2>/dev/null | jsonfilter -l1 -e " @. ${ dev } .interfaces[@.config.mode=\"sta\"].ifname " ) "
2020-04-22 19:00:03 +00:00
scan_list = " $( " ${ trm_iwinfo } " " ${ scan_dev :- ${ dev } } " scan 2>/dev/null | \
2019-08-29 12:03:23 +00:00
awk ' BEGIN{ FS = "[[:space:]]" } /Address:/{ var1 = $NF } /ESSID:/{ var2 = "" ; for ( i = 12; i<= NF; i++) if ( var2 = = "" ) { var2 = $i } else { var2 = var2" " $i } ;
gsub( /,/,"." ,var2) } /Quality:/{ split( $NF ,var0,"/" ) } /Encryption:/{ if ( $NF = = "none" ) { var3 = "+" } else { var3 = "-" } ; printf "%i,%s,%s,%s\n" ,( var0[ 1] *100/var0[ 2] ) ,var1,var2,var3} ' | \
2019-06-26 20:30:36 +00:00
sort -rn | awk -v buf = " ${ trm_scanbuffer } " 'BEGIN{ORS=","}{print substr($0,1,buf)}' ) "
2020-04-22 19:00:03 +00:00
f_log "debug" " f_main ::: scan_radio: ${ dev } , scan_device: ${ scan_dev :- "-" } , scan_buffer: ${ trm_scanbuffer } , scan_list: ${ scan_list :- "-" } "
2019-03-19 14:23:11 +00:00
if [ -z " ${ scan_list } " ]
2018-10-30 14:19:58 +00:00
then
2020-04-24 06:28:16 +00:00
f_log "debug" " f_main ::: no scan results on ' ${ dev } / ${ scan_dev :- "-" } ' - continue "
2019-03-19 14:23:11 +00:00
continue 2
2018-10-30 14:19:58 +00:00
fi
2019-03-19 14:23:11 +00:00
fi
# scan loop
#
IFS = ","
2019-06-26 20:30:36 +00:00
for spec in ${ scan_list }
2019-03-19 14:23:11 +00:00
do
if [ -z " ${ scan_quality } " ]
2018-10-30 14:19:58 +00:00
then
2019-06-26 20:30:36 +00:00
scan_quality = " ${ spec } "
2019-03-19 14:23:11 +00:00
elif [ -z " ${ scan_bssid } " ]
2018-10-30 14:19:58 +00:00
then
2019-06-26 20:30:36 +00:00
scan_bssid = " ${ spec } "
2019-03-19 14:23:11 +00:00
elif [ -z " ${ scan_essid } " ]
then
2019-06-26 20:30:36 +00:00
scan_essid = " ${ spec } "
2019-08-29 12:03:23 +00:00
elif [ -z " ${ scan_open } " ]
then
scan_open = " ${ spec } "
2018-10-30 14:19:58 +00:00
fi
2019-08-29 12:03:23 +00:00
if [ -n " ${ scan_quality } " ] && [ -n " ${ scan_bssid } " ] && [ -n " ${ scan_essid } " ] && [ -n " ${ scan_open } " ]
2019-03-19 14:23:11 +00:00
then
2019-05-24 12:21:02 +00:00
if [ " ${ scan_quality } " -ge " ${ trm_minquality } " ]
2018-10-30 14:19:58 +00:00
then
2019-05-24 12:21:02 +00:00
if { { [ " ${ scan_essid } " = " \" ${ sta_essid //,/. } \" " ] && { [ -z " ${ sta_bssid } " ] || [ " ${ scan_bssid } " = " ${ sta_bssid } " ] ; } } || \
{ [ " ${ scan_bssid } " = " ${ sta_bssid } " ] && [ " ${ scan_essid } " = "unknown" ] ; } } && [ " ${ dev } " = " ${ sta_radio } " ]
2018-09-08 20:28:04 +00:00
then
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: scan_quality: ${ scan_quality } , scan_essid: ${ scan_essid } , scan_bssid: ${ scan_bssid :- "-" } , scan_open: ${ scan_open } "
if [ -n " ${ active_radio } " ]
2018-09-08 20:28:04 +00:00
then
2019-08-29 12:03:23 +00:00
uci_set "wireless" " ${ trm_active_sta } " "disabled" "1"
uci_commit "wireless"
2019-10-21 18:37:08 +00:00
f_log "debug" " f_main ::: active uplink connection ' ${ active_radio } / ${ active_essid } / ${ active_bssid :- "-" } ' terminated "
2019-03-19 14:23:11 +00:00
unset trm_connection active_radio active_essid active_bssid
fi
# retry loop
#
cnt = 1
2019-05-24 12:21:02 +00:00
while [ " ${ cnt } " -le " ${ trm_maxretry } " ]
2019-03-19 14:23:11 +00:00
do
2019-08-29 12:03:23 +00:00
uci_set "wireless" " ${ config } " "disabled" "0"
2019-10-21 18:37:08 +00:00
trm_radio = " ${ sta_radio } "
2018-10-30 14:19:58 +00:00
f_check "sta"
if [ " ${ trm_ifstatus } " = "true" ]
then
2019-03-19 14:23:11 +00:00
unset IFS scan_list
2019-08-29 12:03:23 +00:00
uci_commit "wireless"
2019-03-26 21:51:40 +00:00
f_log "info" " connected to uplink ' ${ sta_radio } / ${ sta_essid } / ${ sta_bssid :- "-" } ' ( ${ cnt } / ${ trm_maxretry } , ${ trm_sysver } ) "
2019-03-19 14:23:11 +00:00
return 0
2019-02-15 08:29:58 +00:00
else
2019-08-29 12:03:23 +00:00
uci -q revert "wireless"
2018-10-30 14:19:58 +00:00
f_check "rev"
2019-05-24 12:21:02 +00:00
if [ " ${ cnt } " -eq " ${ trm_maxretry } " ]
2018-09-08 20:28:04 +00:00
then
2019-02-15 08:29:58 +00:00
faulty_station = " ${ sta_radio } / ${ sta_essid } / ${ sta_bssid :- "-" } "
f_jsnup " ${ faulty_station } "
2019-03-19 14:23:11 +00:00
f_log "info" " uplink disabled ' ${ sta_radio } / ${ sta_essid } / ${ sta_bssid :- "-" } ' ( ${ cnt } / ${ trm_maxretry } , ${ trm_sysver } ) "
break 2
2019-02-15 08:29:58 +00:00
else
f_jsnup
2019-03-19 14:23:11 +00:00
f_log "info" " can't connect to uplink ' ${ sta_radio } / ${ sta_essid } / ${ sta_bssid :- "-" } ' ( ${ cnt } / ${ trm_maxretry } , ${ trm_sysver } ) "
2018-09-08 20:28:04 +00:00
fi
fi
2019-05-24 12:21:02 +00:00
cnt = $(( cnt+1))
sleep $(( trm_maxwait/6))
2019-03-19 14:23:11 +00:00
done
2019-08-29 12:03:23 +00:00
elif [ " ${ trm_autoadd } " -eq 1 ] && [ " ${ scan_open } " = "+" ] && [ " ${ scan_essid } " != "unknown" ]
then
cfg_essid = " ${ scan_essid #* \" } "
cfg_essid = " ${ cfg_essid % \" * } "
uci_essid = " ${ cfg_essid //[^[ : alnum : ]_]/_ } "
if [ -z " $( uci_get "wireless" " trm_ ${ uci_essid } " ) " ]
then
uci_add "wireless" "wifi-iface" " trm_ ${ uci_essid } "
uci_set "wireless" " trm_ ${ uci_essid } " "mode" "sta"
uci_set "wireless" " trm_ ${ uci_essid } " "network" " ${ trm_iface } "
uci_set "wireless" " trm_ ${ uci_essid } " "device" " ${ sta_radio } "
uci_set "wireless" " trm_ ${ uci_essid } " "ssid" " ${ cfg_essid } "
uci_set "wireless" " trm_ ${ uci_essid } " "encryption" "none"
uci_set "wireless" " trm_ ${ uci_essid } " "disabled" "1"
uci_commit "wireless"
f_log "info" " open uplink ' ${ sta_radio } / ${ cfg_essid } ' added to wireless config "
fi
2018-09-08 20:28:04 +00:00
fi
2019-08-29 12:03:23 +00:00
unset scan_quality scan_bssid scan_essid scan_open
continue
2019-03-19 14:23:11 +00:00
else
2019-08-29 12:03:23 +00:00
unset scan_quality scan_bssid scan_essid scan_open
2019-03-19 14:23:11 +00:00
continue
2018-10-30 14:19:58 +00:00
fi
2019-03-19 14:23:11 +00:00
fi
2018-10-30 14:19:58 +00:00
done
2019-08-29 12:03:23 +00:00
unset IFS scan_quality scan_bssid scan_essid scan_open
2018-09-08 20:28:04 +00:00
done
2019-03-19 14:23:11 +00:00
unset scan_list
2018-09-08 20:28:04 +00:00
done
fi
2016-12-31 13:14:29 +00:00
}
2017-07-07 15:02:19 +00:00
# source required system libraries
#
if [ -r "/lib/functions.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]
then
2018-09-08 20:28:04 +00:00
. "/lib/functions.sh"
. "/usr/share/libubox/jshn.sh"
2017-07-07 15:02:19 +00:00
else
2018-09-08 20:28:04 +00:00
f_log "err" "system libraries not found"
2017-07-07 15:02:19 +00:00
fi
2018-01-10 18:42:48 +00:00
# control travelmate actions
2017-04-20 07:22:22 +00:00
#
2019-11-18 18:28:23 +00:00
f_env
2018-04-04 12:30:30 +00:00
while true
2018-01-10 18:42:48 +00:00
do
2018-09-08 20:28:04 +00:00
if [ -z " ${ trm_action } " ]
then
2019-02-26 20:11:51 +00:00
rc = 0
2019-02-15 08:29:58 +00:00
while true
do
2019-05-24 12:21:02 +00:00
if [ " ${ rc } " -eq 0 ]
2019-02-26 20:11:51 +00:00
then
f_check "initial"
fi
sleep ${ trm_timeout } 0
rc = ${ ? }
2019-05-24 12:21:02 +00:00
if [ " ${ rc } " -ne 0 ]
2019-02-15 08:29:58 +00:00
then
2019-02-26 20:11:51 +00:00
f_check "initial"
2019-02-15 08:29:58 +00:00
fi
2019-05-24 12:21:02 +00:00
if [ " ${ rc } " -eq 0 ] || { [ " ${ rc } " -ne 0 ] && [ " ${ trm_ifstatus } " = "false" ] ; }
2019-02-15 08:29:58 +00:00
then
break
fi
done
2018-09-08 20:28:04 +00:00
elif [ " ${ trm_action } " = "stop" ]
then
f_log "info" " travelmate instance stopped ::: action: ${ trm_action } , pid: $( cat ${ trm_pidfile } 2>/dev/null) "
2019-11-06 20:02:17 +00:00
> " ${ trm_rtfile } "
> " ${ trm_pidfile } "
2018-09-08 20:28:04 +00:00
exit 0
else
f_log "info" " travelmate instance started ::: action: ${ trm_action } , pid: ${ $} "
unset trm_action
fi
2019-03-19 14:23:11 +00:00
json_cleanup
2019-11-18 18:28:23 +00:00
f_env
2018-09-08 20:28:04 +00:00
f_main
2018-01-10 18:42:48 +00:00
done