Browse Source

Merge pull request #9862 from dibdot/travelmate

travelmate: update 1.4.12
lilik-openwrt-22.03
Dirk Brenken 5 years ago
committed by GitHub
parent
commit
f385415110
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 59 deletions
  1. +1
    -1
      net/travelmate/Makefile
  2. +4
    -2
      net/travelmate/files/README.md
  3. +1
    -0
      net/travelmate/files/travelmate.conf
  4. +83
    -56
      net/travelmate/files/travelmate.sh

+ 1
- 1
net/travelmate/Makefile View File

@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=travelmate
PKG_VERSION:=1.4.11
PKG_VERSION:=1.4.12
PKG_RELEASE:=1
PKG_LICENSE:=GPL-3.0+
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>


+ 4
- 2
net/travelmate/files/README.md View File

@ -12,6 +12,7 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
* fast uplink connections
* support all kinds of uplinks, incl. hidden and enterprise uplinks
* continuously checks the existing uplink connection (quality), e.g. for conditional uplink (dis-) connections
* automatically add open uplinks to your wireless config, e.g. hotel captive portals
* captive portal detection with internet online check and a 'heartbeat' function to keep the uplink connection up & running
* captive portal auto-login hook (configured via uci/LuCI), you could reference an external script for captive portal auto-logins (see example below)
* proactively scan and switch to a higher prioritized uplink, despite of an already existing connection
@ -47,6 +48,7 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
* trm\_debug => enable/disable debug logging (bool/default: '0', disabled)
* trm\_captive => enable/disable the captive portal detection (bool/default: '1', enabled)
* trm\_proactive => enable/disable the proactive uplink switch (bool/default: '1', enabled)
* trm\_autoadd => automatically add open uplinks to your wireless config (bool/default: '0', disabled)
* trm\_minquality => minimum signal quality threshold as percent for conditional uplink (dis-) connections (int/default: '35', valid range: 20-80)
* trm\_maxwait => how long (in seconds) should travelmate wait for a successful wlan interface reload action (int/default: '30', valid range: 20-40)
* trm\_maxretry => how many times should travelmate try to connect to an uplink (int/default: '3', valid range: 1-10)
@ -56,9 +58,9 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
* trm\_triggerdelay => additional trigger delay in seconds before travelmate processing begins (int/default: '2')
## Captive Portal auto-logins
For automated captive portal logins you could reference external shell scripts. All login scripts should be executable and located in '/etc/travelmate' with the extension '.login'. The provided 'wifionice.login' script example requires curl and automates the login to german ICE hotspots, it also explains the principle approach to extract runtime data like security tokens for a succesful login. Hopefully more scripts for different captive portals will be provided by the community ...
For automated captive portal logins you could reference external shell scripts. All login scripts should be executable and located in '/etc/travelmate' with the extension '.login'. The provided 'wifionice.login' script example requires curl and automates the login to german ICE hotspots, it also explains the principle approach to extract runtime data like security tokens for a successful login. Hopefully more scripts for different captive portals will be provided by the community ...
A typical/succesful captive portal login looks like this:
A typical/successful captive portal login looks like this:
<pre><code>
[...]
Mon Aug 5 10:15:48 2019 user.info travelmate-1.4.10[1481]: travelmate instance started ::: action: start, pid: 1481


+ 1
- 0
net/travelmate/files/travelmate.conf View File

@ -6,6 +6,7 @@ config travelmate 'global'
option trm_captive '1'
option trm_proactive '1'
option trm_netcheck '0'
option trm_autoadd '0'
option trm_iface 'trm_wwan'
option trm_triggerdelay '2'
option trm_debug '0'


+ 83
- 56
net/travelmate/files/travelmate.sh View File

@ -6,18 +6,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# (s)hellcheck exceptions
# shellcheck disable=1091 disable=2039 disable=2143 disable=2181 disable=2188
# set initial defaults
#
LC_ALL=C
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
trm_ver="1.4.11"
trm_sysver="unknown"
trm_ver="1.4.12"
trm_enabled=0
trm_debug=0
trm_iface="trm_wwan"
trm_captive=1
trm_proactive=1
trm_netcheck=0
trm_autoadd=0
trm_captiveurl="http://captive.apple.com"
trm_scanbuffer=1024
trm_minquality=35
@ -49,7 +52,7 @@ f_trim()
#
f_envload()
{
local IFS sys_call sys_desc sys_model
local IFS
# (re-)initialize global list variables
#
@ -57,17 +60,12 @@ f_envload()
# get system information
#
sys_call="$(ubus -S call system board 2>/dev/null)"
if [ -n "${sys_call}" ]
then
sys_desc="$(printf '%s' "${sys_call}" | jsonfilter -e '@.release.description')"
sys_model="$(printf '%s' "${sys_call}" | jsonfilter -e '@.model')"
trm_sysver="${sys_model}, ${sys_desc}"
fi
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)}')"
# get eap capabilities
#
trm_eap="$("${trm_wpa}" -veap >/dev/null 2>&1; printf "%u" ${?})"
trm_eap="$("${trm_wpa}" -veap >/dev/null 2>&1; printf "%u" "${?}")"
# load config and check 'enabled' option
#
@ -137,11 +135,11 @@ f_prep()
{
local IFS mode network radio disabled eaptype config="${1}" proactive="${2}"
mode="$(uci_get wireless "${config}" mode)"
network="$(uci_get wireless "${config}" network)"
radio="$(uci_get wireless "${config}" device)"
disabled="$(uci_get wireless "${config}" disabled)"
eaptype="$(uci_get wireless "${config}" eap_type)"
mode="$(uci_get "wireless" "${config}" "mode")"
network="$(uci_get "wireless" "${config}" "network")"
radio="$(uci_get "wireless" "${config}" "device")"
disabled="$(uci_get "wireless" "${config}" "disabled")"
eaptype="$(uci_get "wireless" "${config}" "eap_type")"
if [ -n "${config}" ] && [ -n "${radio}" ] && [ -n "${mode}" ] && [ -n "${network}" ]
then
@ -171,17 +169,29 @@ f_prep()
f_log "debug" "f_prep ::: config: ${config}, mode: ${mode}, network: ${network}, radio: ${radio}, trm_radio: ${trm_radio:-"-"}, trm_active_sta: ${trm_active_sta:-"-"}, proactive: ${proactive}, trm_eap: ${trm_eap:-"-"}, disabled: ${disabled}"
}
# check net status
#
f_net()
{
local IFS result
result="$(${trm_fetch} --timeout=$((trm_maxwait/6)) "${trm_captiveurl}" -O /dev/null 2>&1 | \
awk '/^Failed to redirect|^Redirected/{printf "%s" "net cp \047"$NF"\047";exit}/^Download completed/{printf "%s" "net ok";exit}/^Failed|Connection error/{printf "%s" "net nok";exit}')"
printf "%s" "${result}"
f_log "debug" "f_net ::: fetch: ${trm_fetch}, timeout: $((trm_maxwait/6)), url: ${trm_captiveurl}, result: ${result}"
}
# check interface status
#
f_check()
{
local IFS ifname radio dev_status config sta_essid sta_bssid result uci_essid uci_bssid login_command bg_pid wait_time mode="${1}" status="${2:-"false"}" cp_domain="${3:-"false"}"
local IFS ifname radio dev_status config sta_essid sta_bssid result uci_essid uci_bssid login_command wait_time mode="${1}" status="${2:-"false"}" cp_domain="${3:-"false"}"
if [ "${mode}" != "initial" ] && [ "${status}" = "false" ]
then
ubus call network reload
wait_time=$((trm_maxwait/6))
sleep ${wait_time}
sleep "${wait_time}"
fi
wait_time=1
@ -222,13 +232,12 @@ f_check()
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 ]
then
result="$(${trm_fetch} --timeout=$((trm_maxwait/6)) "${trm_captiveurl}" -O /dev/null 2>&1 | \
awk '/^Failed to redirect|^Redirected/{printf "%s" "net cp \047"$NF"\047";exit}/^Download completed/{printf "%s" "net ok";exit}/^Failed|Connection error/{printf "%s" "net nok";exit}')"
result="$(f_net)"
if [ "${cp_domain}" = "true" ]
then
cp_domain="$(printf "%s" "${result}" | awk -F "[\\'| ]" '/^net cp/{printf "%s" $4}')"
uci_essid="$(printf "%s" "${dev_status}" | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].config.ssid')"
uci_essid="$(printf "%s" "${uci_essid//[^[:alnum:]_]/_}" | awk '{print tolower($1)}')"
uci_essid="${uci_essid//[^[:alnum:]_]/_}"
uci_bssid="$(printf "%s" "${dev_status}" | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].config.bssid')"
uci_bssid="${uci_bssid//[^[:alnum:]_]/_}"
fi
@ -242,11 +251,10 @@ f_check()
then
while true
do
result="$(${trm_fetch} --timeout=$((trm_maxwait/6)) "${trm_captiveurl}" -O /dev/null 2>&1 | \
awk '/^Failed to redirect|^Redirected/{printf "%s" "net cp \047"$NF"\047";exit}/^Download completed/{printf "%s" "net ok";exit}/^Failed|Connection error/{printf "%s" "net nok";exit}')"
result="$(f_net)"
cp_domain="$(printf "%s" "${result}" | awk -F "[\\'| ]" '/^net cp/{printf "%s" $4}')"
uci_essid="$(printf "%s" "${dev_status}" | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].config.ssid')"
uci_essid="$(printf "%s" "${uci_essid//[^[:alnum:]_]/_}" | awk '{print tolower($1)}')"
uci_essid="${uci_essid//[^[:alnum:]_]/_}"
uci_bssid="$(printf "%s" "${dev_status}" | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].config.bssid')"
uci_bssid="${uci_bssid//[^[:alnum:]_]/_}"
if [ "${trm_netcheck}" -eq 1 ] && [ "${result}" = "net nok" ]
@ -255,34 +263,34 @@ f_check()
f_jsnup
break 2
fi
if [ -z "${cp_domain}" ] || [ -n "$(uci_get dhcp "@dnsmasq[0]" rebind_domain | grep -Fo "${cp_domain}")" ]
if [ -z "${cp_domain}" ] || [ -n "$(uci_get "dhcp" "@dnsmasq[0]" "rebind_domain" | grep -Fo "${cp_domain}")" ]
then
break
fi
uci -q add_list dhcp.@dnsmasq[0].rebind_domain="${cp_domain}"
f_log "info" "captive portal domain '${cp_domain}' added to to dhcp rebind whitelist"
if [ -z "$(uci_get travelmate "${uci_essid}${uci_bssid}")" ]
if [ -z "$(uci_get "travelmate" "${uci_essid}${uci_bssid}")" ]
then
uci_add travelmate "login" "${uci_essid}${uci_bssid}"
uci_set travelmate "${uci_essid}${uci_bssid}" "command" "none"
f_log "info" "captive portal login section '${uci_essid}${uci_bssid}' added to travelmate config section"
fi
done
if [ -n "$(uci -q changes dhcp)" ]
if [ -n "$(uci -q changes "dhcp")" ]
then
uci_commit dhcp
uci_commit "dhcp"
/etc/init.d/dnsmasq reload
fi
if [ -n "$(uci -q changes travelmate)" ]
if [ -n "$(uci -q changes "travelmate")" ]
then
uci_commit travelmate
uci_commit "travelmate"
fi
fi
if [ -n "${cp_domain}" ] && [ "${cp_domain}" != "false" ] && [ -n "${uci_essid}" ] && [ "${trm_captive}" -eq 1 ]
then
trm_connection="${result:-"-"}/${trm_ifquality}"
f_jsnup
login_command="$(uci_get travelmate "${uci_essid}${uci_bssid}" command)"
login_command="$(uci_get "travelmate" "${uci_essid}${uci_bssid}" "command")"
if [ -x "${login_command}" ]
then
"${login_command}" >/dev/null 2>&1
@ -290,8 +298,7 @@ f_check()
f_log "info" "captive portal login '${login_command:0:40}' for '${cp_domain}' has been executed with rc '${rc}'"
if [ "${rc}" -eq 0 ]
then
result="$(${trm_fetch} --timeout=$((trm_maxwait/6)) "${trm_captiveurl}" -O /dev/null 2>&1 | \
awk '/^Failed to redirect|^Redirected/{printf "%s" "net cp \047"$NF"\047";exit}/^Download completed/{printf "%s" "net ok";exit}/^Failed|Connection error/{printf "%s" "net nok";exit}')"
result="$(f_net)"
fi
fi
fi
@ -352,10 +359,10 @@ f_jsnup()
config="$(printf "%s" "${dev_status}" | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].section')"
if [ -n "${config}" ]
then
sta_iface="$(uci_get wireless "${config}" network)"
sta_radio="$(uci_get wireless "${config}" device)"
sta_essid="$(uci_get wireless "${config}" ssid)"
sta_bssid="$(uci_get wireless "${config}" bssid)"
sta_iface="$(uci_get "wireless" "${config}" "network")"
sta_radio="$(uci_get "wireless" "${config}" "device")"
sta_essid="$(uci_get "wireless" "${config}" "ssid")"
sta_bssid="$(uci_get "wireless" "${config}" "bssid")"
fi
fi
@ -436,7 +443,7 @@ f_log()
#
f_main()
{
local IFS cnt dev config spec scan_list scan_essid scan_bssid scan_quality faulty_list
local IFS cnt dev config spec scan_list scan_essid scan_bssid scan_open scan_quality uci_essid cfg_essid faulty_list
local station_id sta sta_essid sta_bssid sta_radio sta_iface active_essid active_bssid active_radio
f_check "initial" "false" "true"
@ -455,7 +462,7 @@ f_main()
f_check "dev" "true"
f_log "debug" "f_main ::: active_radio: ${active_radio}, active_essid: \"${active_essid}\", active_bssid: ${active_bssid:-"-"}"
else
uci_commit wireless
uci_commit "wireless"
f_check "dev"
fi
json_get_var faulty_list "faulty_stations"
@ -475,9 +482,9 @@ f_main()
do
config="${sta%%-*}"
sta_radio="${sta##*-}"
sta_essid="$(uci_get wireless "${config}" ssid)"
sta_bssid="$(uci_get wireless "${config}" bssid)"
sta_iface="$(uci_get wireless "${config}" network)"
sta_essid="$(uci_get "wireless" "${config}" "ssid")"
sta_bssid="$(uci_get "wireless" "${config}" "bssid")"
sta_iface="$(uci_get "wireless" "${config}" "network")"
json_get_var faulty_list "faulty_stations"
if [ -n "$(printf "%s" "${faulty_list}" | grep -Fo "${sta_radio}/${sta_essid}/${sta_bssid}")" ]
then
@ -493,8 +500,8 @@ f_main()
if [ -z "${scan_list}" ]
then
scan_list="$("${trm_iwinfo}" "${dev}" scan 2>/dev/null | \
awk 'BEGIN{FS="[ ]"}/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,"/");printf "%i,%s,%s\n",(var0[1]*100/var0[2]),var1,var2}' | \
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}' | \
sort -rn | awk -v buf="${trm_scanbuffer}" 'BEGIN{ORS=","}{print substr($0,1,buf)}')"
f_log "debug" "f_main ::: scan_buffer: ${trm_scanbuffer}, scan_list: ${scan_list}"
if [ -z "${scan_list}" ]
@ -517,36 +524,40 @@ f_main()
elif [ -z "${scan_essid}" ]
then
scan_essid="${spec}"
elif [ -z "${scan_open}" ]
then
scan_open="${spec}"
fi
if [ -n "${scan_quality}" ] && [ -n "${scan_bssid}" ] && [ -n "${scan_essid}" ]
if [ -n "${scan_quality}" ] && [ -n "${scan_bssid}" ] && [ -n "${scan_essid}" ] && [ -n "${scan_open}" ]
then
if [ "${scan_quality}" -ge "${trm_minquality}" ]
then
if { { [ "${scan_essid}" = "\"${sta_essid//,/.}\"" ] && { [ -z "${sta_bssid}" ] || [ "${scan_bssid}" = "${sta_bssid}" ]; } } || \
{ [ "${scan_bssid}" = "${sta_bssid}" ] && [ "${scan_essid}" = "unknown" ]; } } && [ "${dev}" = "${sta_radio}" ]
then
f_log "debug" "f_main ::: scan_quality: ${scan_quality}, scan_essid: ${scan_essid}, scan_bssid: ${scan_bssid:-"-"}"
f_log "debug" "f_main ::: scan_quality: ${scan_quality}, scan_essid: ${scan_essid}, scan_bssid: ${scan_bssid:-"-"}, scan_open: ${scan_open}"
if [ "${dev}" = "${active_radio}" ]
then
uci_set "wireless" "${trm_active_sta}" "disabled" "1"
uci_commit "wireless"
f_log "debug" "f_main ::: active uplink connection '${active_radio}/${active_essid}/${active_bssid:-"-"}' terminated"
unset trm_connection active_radio active_essid active_bssid
uci_set wireless "${trm_active_sta}" disabled 1
uci_commit wireless
fi
# retry loop
#
cnt=1
while [ "${cnt}" -le "${trm_maxretry}" ]
do
uci_set wireless "${config}" disabled 0
uci_set "wireless" "${config}" "disabled" "0"
f_check "sta"
if [ "${trm_ifstatus}" = "true" ]
then
unset IFS scan_list
uci_commit wireless
uci_commit "wireless"
f_log "info" "connected to uplink '${sta_radio}/${sta_essid}/${sta_bssid:-"-"}' (${cnt}/${trm_maxretry}, ${trm_sysver})"
return 0
else
uci -q revert wireless
uci -q revert "wireless"
f_check "rev"
if [ "${cnt}" -eq "${trm_maxretry}" ]
then
@ -562,17 +573,33 @@ f_main()
cnt=$((cnt+1))
sleep $((trm_maxwait/6))
done
else
unset scan_quality scan_bssid scan_essid
continue
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
fi
unset scan_quality scan_bssid scan_essid scan_open
continue
else
unset scan_quality scan_bssid scan_essid
unset scan_quality scan_bssid scan_essid scan_open
continue
fi
fi
done
unset IFS scan_quality scan_bssid scan_essid
unset IFS scan_quality scan_bssid scan_essid scan_open
done
unset scan_list
done


Loading…
Cancel
Save