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