travelmate: update 0.3.5
[feed/packages.git] / net / travelmate / files / travelmate.sh
1 #!/bin/sh
2 # travelmate, a wlan connection manager for travel router
3 # written by Dirk Brenken (dev@brenken.org)
4
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/>.
8
9 # prepare environment
10 #
11 LC_ALL=C
12 PATH="/usr/sbin:/usr/bin:/sbin:/bin"
13 trm_ver="0.3.5"
14 trm_enabled=1
15 trm_debug=0
16 trm_maxwait=20
17 trm_maxretry=3
18 trm_radio="*"
19 trm_iw=1
20
21 f_envload()
22 {
23 # source required system libraries
24 #
25 if [ -r "/lib/functions.sh" ]
26 then
27 . "/lib/functions.sh"
28 else
29 f_log "error" "required system library not found"
30 fi
31
32 # load uci config and check 'enabled' option
33 #
34 option_cb()
35 {
36 local option="${1}"
37 local value="${2}"
38 eval "${option}=\"${value}\""
39 }
40 config_load travelmate
41
42 if [ ${trm_enabled} -ne 1 ]
43 then
44 f_log "info " "travelmate is currently disabled, please set 'trm_enabled' to '1' to use this service"
45 exit 0
46 fi
47
48 # check for preferred wireless tool
49 #
50 if [ ${trm_iw} -eq 1 ]
51 then
52 trm_scanner="$(which iw)"
53 else
54 trm_scanner="$(which iwinfo)"
55 fi
56 if [ -z "${trm_scanner}" ]
57 then
58 f_log "error" "no wireless tool for wlan scanning found, please install 'iw' or 'iwinfo'"
59 fi
60 }
61
62 # function to bring down all STA interfaces
63 #
64 f_prepare()
65 {
66 local config="${1}"
67 local mode="$(uci -q get wireless."${config}".mode)"
68 local network="$(uci -q get wireless."${config}".network)"
69 local disabled="$(uci -q get wireless."${config}".disabled)"
70
71 if [ "${mode}" = "sta" ] && [ -n "${network}" ]
72 then
73 trm_stalist="${trm_stalist} ${config}_${network}"
74 if [ -z "${disabled}" ] || [ "${disabled}" = "0" ]
75 then
76 uci -q set wireless."${config}".disabled=1
77 f_log "debug" "config: ${config}, interface: ${network}"
78 fi
79 fi
80 }
81
82 f_check()
83 {
84 local ifname cnt=1 mode="${1}"
85 trm_ifstatus="false"
86
87 while [ ${cnt} -le ${trm_maxwait} ]
88 do
89 if [ "${mode}" = "ap" ]
90 then
91 ifname="$(ubus -S call network.wireless status | jsonfilter -l1 -e "@.${trm_radio}.interfaces[@.config.mode=\"ap\"].ifname")"
92 if [ -n "${ifname}" ]
93 then
94 trm_ifstatus="$(ubus -S call network.wireless status | jsonfilter -l1 -e "@.${trm_radio}.up")"
95 fi
96 else
97 ifname="$(ubus -S call network.wireless status | jsonfilter -l1 -e '@.*.interfaces[@.config.mode="sta"].ifname')"
98 if [ -n "${ifname}" ]
99 then
100 trm_ifstatus="$(ubus -S call network.interface dump | jsonfilter -e "@.interface[@.device=\"${ifname}\"].up")"
101 fi
102 fi
103 if [ "${mode}" = "initial" ] || [ "${trm_ifstatus}" = "true" ]
104 then
105 break
106 fi
107 cnt=$((cnt+1))
108 sleep 1
109 done
110 f_log "debug" "mode: ${mode}, radio: ${trm_radio}, name: ${ifname}, status: ${trm_ifstatus}, count: ${cnt}, max-wait: ${trm_maxwait}"
111 }
112
113 # function to write to syslog
114 #
115 f_log()
116 {
117 local class="${1}"
118 local log_msg="${2}"
119
120 if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${trm_debug} -eq 1 ])
121 then
122 logger -t "travelmate-[${trm_ver}] ${class}" "${log_msg}"
123 if [ "${class}" = "error" ]
124 then
125 logger -t "travelmate-[${trm_ver}] ${class}" "Please check the online documentation 'https://github.com/openwrt/packages/blob/master/net/travelmate/files/README.md'"
126 exit 255
127 fi
128 fi
129 }
130
131 f_main()
132 {
133 local ap_list ssid_list config network ssid cnt=1
134 local sysver="$(ubus -S call system board | jsonfilter -e '@.release.description')"
135
136 f_log "info " "start travelmate scanning ..."
137 f_check "initial"
138 if [ "${trm_ifstatus}" != "true" ]
139 then
140 config_load wireless
141 config_foreach f_prepare wifi-iface
142 if [ -n "$(uci -q changes wireless)" ]
143 then
144 uci -q commit wireless
145 ubus call network reload
146 fi
147 f_check "ap"
148 ap_list="$(ubus -S call network.wireless status | jsonfilter -e "@.${trm_radio}.interfaces[@.config.mode=\"ap\"].ifname" | awk '{ORS=" "; print $0}')"
149 f_log "debug" "ap-list: ${ap_list}, sta-list: ${trm_stalist}"
150 if [ -z "${ap_list}" ] || [ -z "${trm_stalist}" ]
151 then
152 f_log "error" "no usable AP/STA configuration found"
153 fi
154 for ap in ${ap_list}
155 do
156 cnt=1
157 while [ ${cnt} -le ${trm_maxretry} ]
158 do
159 if [ ${trm_iw} -eq 1 ]
160 then
161 ssid_list="$(${trm_scanner} dev "${ap}" scan 2>/dev/null | \
162 awk '/SSID: /{if(!seen[$0]++){printf "\"";for(i=2; i<=NF; i++)if(i==2)printf $i;else printf " "$i;printf "\" "}}')"
163 else
164 ssid_list="$(${trm_scanner} "${ap}" scan | \
165 awk '/ESSID: ".*"/{ORS=" ";if (!seen[$0]++) for(i=2; i<=NF; i++) print $i}')"
166 fi
167 f_log "debug" "scanner: ${trm_scanner}, ap: ${ap}, ssids: ${ssid_list}"
168 if [ -n "${ssid_list}" ]
169 then
170 for sta in ${trm_stalist}
171 do
172 config="${sta%%_*}"
173 network="${sta##*_}"
174 ssid="\"$(uci -q get wireless."${config}".ssid)\""
175 if [ -n "$(printf "${ssid_list}" | grep -Fo "${ssid}")" ]
176 then
177 uci -q set wireless."${config}".disabled=0
178 uci -q commit wireless
179 ubus call network reload
180 f_check "sta"
181 if [ "${trm_ifstatus}" = "true" ]
182 then
183 f_log "info " "wwan interface connected to uplink ${ssid} (${cnt}/${trm_maxretry}, ${sysver})"
184 sleep 5
185 return 0
186 else
187 uci -q set wireless."${config}".disabled=1
188 uci -q commit wireless
189 ubus call network reload
190 f_log "info " "wwan interface can't connect to uplink ${ssid} (${cnt}/${trm_maxretry}, ${sysver})"
191 fi
192 fi
193 done
194 else
195 f_log "info " "empty uplink list (${cnt}/${trm_maxretry}, ${sysver})"
196 fi
197 cnt=$((cnt+1))
198 sleep 5
199 done
200 done
201 f_log "info " "no wwan uplink found (${sysver})"
202 else
203 f_log "info " "wwan uplink still connected (${sysver})"
204 fi
205 }
206
207 if [ "${trm_procd}" = "true" ]
208 then
209 f_envload
210 f_main
211 fi
212 exit 0