| Option | Default | Description/Valid Values |
| :----------------- | :--------------------------------- | :---------------------------------------------------------------------------------------------------- |
| enabled | 1, enabled | enable or disable the uplink, automatically set if the retry limit was reached |
+| revive | 0, disabled | re-enable this uplink after n run cycles if the retry limit disabled it, minimum '10' |
| device | -, not set | match the 'device' in the wireless config section |
| ssid | -, not set | match the 'ssid' in the wireless config section |
| bssid | -, not set | match the 'bssid' in the wireless config section |
**Retry behaviour**
`trm_maxretry` (default 3) limits the connection attempts per uplink. When the limit is reached, the affected uplink is disabled in the travelmate config and has to be re-enabled manually - which is intentional for permanently broken credentials, but worth keeping in mind in combination with `trm_netcheck`. Set `trm_maxretry` to '0' for unlimited retries if you never want an uplink to be disabled automatically.
+Per uplink, `revive` softens that. With a value of n, an uplink disabled by the retry limit is set back to 'enabled' after n run cycles, so a network that was only temporarily unavailable comes back on its own. Values below 10 are raised to 10, since a run cycle is roughly `trm_timeout` seconds long and shorter intervals only produce needless reconnect attempts. The number of revivals is capped by the global `trm_maxretry`, which also means that `revive` has no effect with `trm_maxretry` set to '0'. The cycle and round counters are kept in the runtime file '/var/run/travelmate/travelmate.revive', they are never written to the config and are cleared when the service is stopped. The enable and disable itself is still recorded in the travelmate config, so the LuCI station list always shows the real state.
+
**Open uplinks**
`trm_autoadd` adds open networks to your wireless config on the fly, which is handy in hotels and on trains. Keep `trm_maxautoadd` at a sane value so that a busy location doesn't flood your config, and use `trm_ssidfilter` to skip the usual noise, e.g. `Chromecast*` or printer and camera SSIDs.
trm_scanfile="${trm_rundir}/travelmate.scan"
trm_tmpfile="${trm_rundir}/travelmate.tmp"
trm_rtfile="${trm_rundir}/travelmate.runtime.json"
+trm_revivefile="${trm_rundir}/travelmate.revive"
trm_captiveurl="http://detectportal.firefox.com"
trm_useragent="Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0"
-trm_action="${1}"
trm_runmode=""
trm_active="0"
done
}
+# load the revive counter of an uplink that has been disabled by the retry limit
+#
+f_reviveload() {
+ local cnt rounds radio bssid essid load_radio="${1}" load_essid="${2}" load_bssid="${3}" found="0" revive=""
+
+ revive="$(f_getval "revive" "0")"
+ revive="${revive//[!0-9]/}"
+ [ -z "${revive}" ] || [ "${revive}" = "0" ] && return 0
+ [ "${revive}" -lt "10" ] && revive="10"
+
+ : >"${trm_revivefile}.tmp"
+ if [ -s "${trm_revivefile}" ]; then
+ while IFS="|" read -r cnt rounds radio bssid essid; do
+ if [ "${radio}" = "${load_radio}" ] && [ "${essid}" = "${load_essid}" ] && [ "${bssid}" = "${load_bssid}" ]; then
+ found="1"
+ rounds="$((rounds + 1))"
+ if [ "${rounds}" -gt "${trm_maxretry}" ]; then
+ cnt="0"
+ f_log "info" "uplink stays disabled '${load_radio}/${load_essid}/${load_bssid:-"-"}', revive limit reached"
+ else
+ cnt="${revive}"
+ fi
+ fi
+ printf "%s|%s|%s|%s|%s\n" "${cnt}" "${rounds}" "${radio}" "${bssid}" "${essid}" >>"${trm_revivefile}.tmp"
+ done <"${trm_revivefile}"
+ fi
+ [ "${found}" = "0" ] && printf "%s|%s|%s|%s|%s\n" "${revive}" "1" "${load_radio}" "${load_bssid}" "${load_essid}" >>"${trm_revivefile}.tmp"
+ mv -f "${trm_revivefile}.tmp" "${trm_revivefile}"
+
+ f_log "debug" "f_reviveload ::: radio: ${load_radio}, essid: ${load_essid}, bssid: ${load_bssid:-"-"}, revive: ${revive}, max_rounds: ${trm_maxretry}"
+}
+
+# count down the loaded uplinks and re-enable them at the end of their revive cycle
+#
+f_revive() {
+ local cnt rounds radio bssid essid
+
+ [ ! -s "${trm_revivefile}" ] && return 0
+
+ : >"${trm_revivefile}.tmp"
+ while IFS="|" read -r cnt rounds radio bssid essid; do
+ if [ "${cnt}" -gt "0" ]; then
+ cnt="$((cnt - 1))"
+ if [ "${cnt}" = "0" ]; then
+ f_getcfg "${radio}" "${essid}" "${bssid}"
+ if [ -z "${trm_uplinkcfg}" ]; then
+ continue
+ fi
+ if [ "$(uci_get "travelmate" "${trm_uplinkcfg}" "enabled")" = "0" ]; then
+ uci_set "travelmate" "${trm_uplinkcfg}" "enabled" "1"
+ uci_commit "travelmate"
+ [ ! -f "${trm_refreshfile}" ] && printf "%s" "cfg_reload" >"${trm_refreshfile}"
+ f_log "info" "uplink has been re-enabled '${radio}/${essid}/${bssid:-"-"}' (${rounds}/${trm_maxretry})"
+ fi
+ fi
+ fi
+ printf "%s|%s|%s|%s|%s\n" "${cnt}" "${rounds}" "${radio}" "${bssid}" "${essid}" >>"${trm_revivefile}.tmp"
+ done <"${trm_revivefile}"
+ mv -f "${trm_revivefile}.tmp" "${trm_revivefile}"
+}
+
# get travelmate option value in 'uplink' sections
#
f_getval() {
#
f_main() {
local radio cnt retrycnt scan_list scan_essid scan_bssid scan_rsn scan_wpa scan_quality scan_open station_id retry_display
- local section sta sta_essid sta_bssid sta_radio sta_mac open_sta open_essid config_radio config_essid config_bssid
+ local section sta sta_essid sta_bssid sta_radio sta_mac open_sta open_essid esc_essid config_radio config_essid config_bssid
# mark the run cycle as active, e.g. to distinguish 'processing' from an
# idle daemon in f_genstatus
#
trm_active="1"
+ # re-enable uplinks whose revive cycle has expired
+ #
+ f_revive
+
# initial check
#
f_check "initial" "false"
section="${sta%%-*}"
sta_radio="$(uci_get "wireless" "${section}" "device")"
sta_essid="$(uci_get "wireless" "${section}" "ssid")"
+ esc_essid="\"${sta_essid//\"/\\\"}\""
sta_bssid="$(uci_get "wireless" "${section}" "bssid")"
f_normbssid "${sta_bssid}"
sta_bssid="${trm_normbssid}"
fi
open_essid="${scan_essid%?}"
open_essid="${open_essid:1}"
+ open_essid="${open_essid//\\\"/\"}"
open_sta="$(f_addsta "${radio}" "${open_essid}")"
if [ -n "${open_sta}" ]; then
section="${open_sta%%-*}"
sta_radio="$(uci_get "wireless" "${section}" "device")"
sta_essid="$(uci_get "wireless" "${section}" "ssid")"
+ esc_essid="\"${sta_essid//\"/\\\"}\""
sta_bssid=""
sta_mac=""
fi
fi
if [ -n "${sta_bssid}" ] && [ "${radio}" = "${sta_radio}" ] &&
- [ "${scan_bssid}" != "${sta_bssid}" ] && [ "${scan_essid}" = "\"${sta_essid}\"" ]; then
+ [ "${scan_bssid}" != "${sta_bssid}" ] && [ "${scan_essid}" = "${esc_essid}" ]; then
if [ -n "${trm_uplinkcfg}" ]; then
uci_set "travelmate" "${trm_uplinkcfg}" "enabled" "0"
uci_commit "travelmate"
f_log "info" "bssid mismatch (evil-twin) '${sta_radio}/${sta_essid}/${sta_bssid} => ${scan_bssid}'"
continue
fi
- if { { [ "${scan_essid}" = "\"${sta_essid}\"" ] && { [ -z "${sta_bssid}" ] || [ "${scan_bssid}" = "${sta_bssid}" ]; }; } ||
+ if { { [ "${scan_essid}" = "${esc_essid}" ] && { [ -z "${sta_bssid}" ] || [ "${scan_bssid}" = "${sta_bssid}" ]; }; } ||
{ [ "${scan_bssid}" = "${sta_bssid}" ] && [ "${scan_essid}" = "hidden" ]; }; } && [ "${radio}" = "${sta_radio}" ]; then
if [ "${trm_eviltwin}" = "1" ] && [ -z "${sta_bssid}" ] && [ "${scan_essid}" != "hidden" ]; then
if [ "$((0x${scan_bssid%%:*} & 2))" != "0" ]; then
uci_set "travelmate" "${trm_uplinkcfg}" "enabled" "0"
uci_commit "travelmate"
[ ! -f "${trm_refreshfile}" ] && printf "%s" "cfg_reload" >"${trm_refreshfile}"
+ f_reviveload "${sta_radio}" "${sta_essid}" "${sta_bssid}"
fi
f_log "info" "uplink has been disabled '${sta_radio}/${sta_essid}/${sta_bssid:-"-"}' (${retrycnt}/${retry_display})"
continue 2