2 # travelmate, a wlan connection manager for travel router
3 # written by Dirk Brenken (dev@brenken.org)
5 # This is free software, licensed under the GNU General Public License v3.
6 # You should have received a copy of the GNU General Public License
7 # along with this program. If not, see <http://www.gnu.org/licenses/>.
12 PATH
="/usr/sbin:/usr/bin:/sbin:/bin"
14 trm_sysver
="$(ubus -S call system board | jsonfilter -e '@.release.description')"
21 trm_iw
="$(command -v iw)"
22 trm_rtfile
="/tmp/trm_runtime.json"
24 # source required system library
26 if [ -r "/lib/functions.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]
29 .
"/usr/share/libubox/jshn.sh"
31 f_log
"error" "system libraries not found"
34 # f_envload: load travelmate environment
44 # load uci config and check 'enabled' option
50 eval "${option}=\"${value}\""
52 config_load travelmate
54 if [ ${trm_enabled} -ne 1 ]
56 f_log
"info " "travelmate is currently disabled, please set 'trm_enabled' to '1' to use this service"
60 # check for wireless tool
64 f_log
"error" "no wireless tool found, please install package 'iw'"
68 # f_prepare: gather radio information & bring down all STA interfaces
73 local mode
="$(uci -q get wireless."${config}".mode)"
74 local radio
="$(uci -q get wireless."${config}".device)"
75 local disabled
="$(uci -q get wireless."${config}".disabled)"
77 if [ "${mode}" = "ap" ] && ([ -z "${disabled}" ] || [ "${disabled}" = "0" ]) && \
78 ([ -z "${trm_radio}" ] || [ "${trm_radio}" = "${radio}" ])
80 trm_radiolist
="${trm_radiolist} ${radio}"
81 elif [ "${mode}" = "sta" ]
83 trm_stalist
="${trm_stalist} ${config}_${radio}"
84 if [ -z "${disabled}" ] ||
[ "${disabled}" = "0" ]
86 uci
-q set wireless.
"${config}".disabled
=1
89 f_log
"debug" "mode: ${mode}, radio: ${radio}, config: ${config}, disabled: ${disabled}"
92 # f_check: check interface status
96 local ifname radio status cnt
=1 mode
="${1}"
99 while [ ${cnt} -le ${trm_maxwait} ]
101 status
="$(ubus -S call network.wireless status 2>/dev/null)"
102 if [ -n "${status}" ]
104 if [ "${mode}" = "ap" ]
106 for radio
in ${trm_radiolist}
108 trm_ifstatus
="$(printf "%s
" "${status}" | jsonfilter -e "@.
${radio}.up
")"
109 if [ "${trm_ifstatus}" = "true" ]
111 trm_aplist
="${trm_aplist} $(printf "%s" "${status}" | jsonfilter -e "@.${radio}.interfaces[@.config.mode=\"ap\"].ifname")_${radio}"
112 ifname
="${trm_aplist}"
120 ifname
="$(printf "%s
" "${status}" | jsonfilter -e '@.*.interfaces[@.config.mode="sta
"].ifname')"
121 if [ -n "${ifname}" ]
123 trm_ifstatus
="$(ubus -S call network.interface dump 2>/dev/null | jsonfilter -e "@.interface
[@.device
=\"${ifname}\"].up
")"
127 if [ "${mode}" = "initial" ] ||
[ "${trm_ifstatus}" = "true" ]
134 f_log
"debug" "mode: ${mode}, name: ${ifname}, status: ${trm_ifstatus}, count: ${cnt}, max-wait: ${trm_maxwait}, automatic: ${trm_automatic}"
137 # f_jsnupdate: update runtime information
141 local iface
="${1}" radio="${2}" ssid="${3}"
144 json_add_object
"data"
145 json_add_string
"travelmate_version" "${trm_ver}"
146 json_add_string
"station_connection" "${trm_ifstatus}"
147 json_add_string
"station_ssid" "${ssid}"
148 json_add_string
"station_interface" "${iface}"
149 json_add_string
"station_radio" "${radio}"
150 json_add_string
"last_rundate" "$(/bin/date "+%d.
%m.
%Y
%H
:%M
:%S
")"
151 json_add_string
"system" "${trm_sysver}"
153 json_dump
> "${trm_rtfile}"
156 # f_status: output runtime information
160 local key keylist value
162 if [ -s "${trm_rtfile}" ]
164 printf "%s\n" "::: travelmate runtime information"
165 json_load
"$(cat "${trm_rtfile}" 2>/dev/null)"
167 json_get_keys keylist
168 for key
in ${keylist}
170 json_get_var value
"${key}"
171 printf " %-18s : %s\n" "${key}" "${value}"
176 # f_log: write to syslog, exit on error
183 if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${trm_debug} -eq 1 ])
185 logger -t "travelmate-
[${trm_ver}] ${class}" "${log_msg}"
186 if [ "${class}" = "error
" ]
188 logger -t "travelmate-
[${trm_ver}] ${class}" "Please check 'https://github.com/openwrt/packages/blob/master/net/travelmate/files/README.md' (${trm_sysver})"
194 # f_main: main function for connection handling
198 local config ssid_list ap ap_radio sta_ssid sta_radio sta_iface cnt=1
201 if [ "${trm_ifstatus}" != "true
" ]
204 config_foreach f_prepare wifi-iface
205 if [ -n "$
(uci
-q changes wireless
)" ]
207 uci -q commit wireless
208 ubus call network restart
211 f_log "debug
" "ap-list
: ${trm_aplist}, sta-list
: ${trm_stalist}"
212 for ap in ${trm_aplist}
217 if [ -z "$
(printf "%s" "${trm_stalist}" |
grep -Fo "_${ap_radio}")" ]
221 while [ ${cnt} -le ${trm_maxretry} ]
223 ssid_list="$
(${trm_iw} dev
"${ap}" scan
2>/dev
/null | \
224 awk '/SSID: /{if(!seen[$0]++){printf "\"";for(i=2; i<=NF; i++)if(i==2)printf $i;else printf " "$i;printf "\" "}}')"
225 f_log "debug
" "iw
: ${trm_iw}, ap: ${ap}, ssids: ${ssid_list}"
226 if [ -n "${ssid_list}" ]
228 for sta in ${trm_stalist}
231 sta_radio="${sta##*_}"
232 sta_ssid="$
(uci
-q get wireless.
"${config}".ssid
)"
233 sta_iface="$
(uci
-q get wireless.
"${config}".network
)"
234 if [ -n "$
(printf "%s" "${ssid_list}" | grep -Fo "\"${sta_ssid}\"")" ] && [ "${ap_radio}" = "${sta_radio}" ]
236 uci
-q set wireless.
"${config}".disabled
=0
237 ubus call network reload
239 if [ "${trm_ifstatus}" = "true" ]
241 uci
-q commit wireless
242 f_log
"info " "interface '${sta_iface}' on '${sta_radio}' connected to uplink '${sta_ssid}' (${trm_sysver})"
243 f_jsnupdate
"${sta_iface}" "${sta_radio}" "${sta_ssid}"
246 uci
-q revert wireless
247 ubus call network reload
248 f_log
"info " "interface '${sta_iface}' on '${sta_radio}' can't connect to uplink '${sta_ssid}' (${trm_sysver})"
249 f_jsnupdate
"${sta_iface}" "${sta_radio}" "${sta_ssid}"
259 if [ ! -s "${trm_rtfile}" ]
261 config
="$(ubus -S call network.wireless status | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta
"].section')"
262 sta_radio
="$(uci -q get wireless."${config}".device)"
263 sta_ssid
="$(uci -q get wireless."${config}".ssid)"
264 sta_iface
="$(uci -q get wireless."${config}".network)"
265 f_jsnupdate
"${sta_iface}" "${sta_radio}" "${sta_ssid}"
270 # handle different travelmate actions
279 while [ ${trm_automatic} -eq 1 ]