umbim: drop IP configuration parsing using 'eval'
[openwrt/staging/jow.git] / package / network / utils / umbim / files / lib / netifd / proto / mbim.sh
1 #!/bin/sh
2
3 [ -n "$INCLUDE_ONLY" ] || {
4 . /lib/functions.sh
5 . ../netifd-proto.sh
6 init_proto "$@"
7 }
8 #DBG=-v
9
10 proto_mbim_init_config() {
11 available=1
12 no_device=1
13 proto_config_add_string "device:device"
14 proto_config_add_string apn
15 proto_config_add_string pincode
16 proto_config_add_string delay
17 proto_config_add_boolean allow_roaming
18 proto_config_add_boolean allow_partner
19 proto_config_add_string auth
20 proto_config_add_string username
21 proto_config_add_string password
22 [ -e /proc/sys/net/ipv6 ] && proto_config_add_string ipv6
23 proto_config_add_boolean dhcp
24 proto_config_add_boolean dhcpv6
25 proto_config_add_string pdptype
26 proto_config_add_defaults
27 }
28
29 _proto_mbim_get_field() {
30 local field="$1"
31 shift
32 local mbimconfig="$@"
33 echo "$mbimconfig" | while read -r line; do
34 variable=${line%%:*}
35 [ "$variable" = "$field" ] || continue;
36 value=${line##* }
37 echo -n "$value "
38 done
39 }
40
41 _proto_mbim_setup() {
42 local interface="$1"
43 local tid=2
44 local ret
45
46 local device apn pincode delay auth username password allow_roaming allow_partner
47 local dhcp dhcpv6 pdptype ip4table ip6table $PROTO_DEFAULT_OPTIONS
48 json_get_vars device apn pincode delay auth username password allow_roaming allow_partner
49 json_get_vars dhcp dhcpv6 pdptype ip4table ip6table $PROTO_DEFAULT_OPTIONS
50
51 [ ! -e /proc/sys/net/ipv6 ] && ipv6=0 || json_get_var ipv6 ipv6
52
53 [ -n "$ctl_device" ] && device=$ctl_device
54
55 [ -n "$device" ] || {
56 echo "mbim[$$]" "No control device specified"
57 proto_notify_error "$interface" NO_DEVICE
58 proto_set_available "$interface" 0
59 return 1
60 }
61 [ -c "$device" ] || {
62 echo "mbim[$$]" "The specified control device does not exist"
63 proto_notify_error "$interface" NO_DEVICE
64 proto_set_available "$interface" 0
65 return 1
66 }
67
68 devname="$(basename "$device")"
69 devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
70 ifname="$( ls "$devpath"/net )"
71
72 [ -n "$ifname" ] || {
73 echo "mbim[$$]" "Failed to find matching interface"
74 proto_notify_error "$interface" NO_IFNAME
75 proto_set_available "$interface" 0
76 return 1
77 }
78
79 [ -n "$apn" ] || {
80 echo "mbim[$$]" "No APN specified"
81 proto_notify_error "$interface" NO_APN
82 return 1
83 }
84
85 [ -n "$delay" ] && sleep "$delay"
86
87 echo "mbim[$$]" "Reading capabilities"
88 umbim $DBG -n -d $device caps || {
89 echo "mbim[$$]" "Failed to read modem caps"
90 tid=$((tid + 1))
91 umbim $DBG -t $tid -d "$device" disconnect
92 proto_notify_error "$interface" PIN_FAILED
93 return 1
94 }
95 tid=$((tid + 1))
96
97 [ "$pincode" ] && {
98 echo "mbim[$$]" "Sending pin"
99 umbim $DBG -n -t $tid -d $device unlock "$pincode" || {
100 echo "mbim[$$]" "Unable to verify PIN"
101 tid=$((tid + 1))
102 umbim $DBG -t $tid -d "$device" disconnect
103 proto_notify_error "$interface" PIN_FAILED
104 proto_block_restart "$interface"
105 return 1
106 }
107 }
108 tid=$((tid + 1))
109
110 echo "mbim[$$]" "Checking pin"
111 umbim $DBG -n -t $tid -d $device pinstate
112 [ $? -eq 2 ] && {
113 echo "mbim[$$]" "PIN required"
114 tid=$((tid + 1))
115 umbim $DBG -t $tid -d "$device" disconnect
116 proto_notify_error "$interface" PIN_FAILED
117 proto_block_restart "$interface"
118 return 1
119 }
120 tid=$((tid + 1))
121
122 echo "mbim[$$]" "Checking subscriber"
123 umbim $DBG -n -t $tid -d $device subscriber || {
124 echo "mbim[$$]" "Subscriber init failed"
125 tid=$((tid + 1))
126 umbim $DBG -t $tid -d "$device" disconnect
127 proto_notify_error "$interface" NO_SUBSCRIBER
128 return 1
129 }
130 tid=$((tid + 1))
131
132 echo "mbim[$$]" "Register with network"
133 connected=0
134 umbim $DBG -n -t $tid -d $device registration
135 reg_status=$?
136 case $reg_status in
137 0) echo "mbim[$$]" "Registered in home mode"
138 tid=$((tid + 1))
139 connected=1;;
140 4) if [ "$allow_roaming" = "1" ]; then
141 echo "mbim[$$]" "Registered in roaming mode"
142 tid=$((tid + 1))
143 connected=1
144 fi;;
145 5) if [ "$allow_partner" = "1" ]; then
146 echo "mbim[$$]" "Registered in partner mode"
147 tid=$((tid + 1))
148 connected=1
149 fi;;
150 esac
151 if [ $connected -ne 1 ]; then
152 echo "mbim[$$]" "Subscriber registration failed (code $reg_status)"
153 tid=$((tid + 1))
154 umbim $DBG -t $tid -d "$device" disconnect
155 proto_notify_error "$interface" NO_REGISTRATION
156 return 1
157 fi
158
159 echo "mbim[$$]" "Attach to network"
160 umbim $DBG -n -t $tid -d $device attach || {
161 echo "mbim[$$]" "Failed to attach to network"
162 tid=$((tid + 1))
163 umbim $DBG -t $tid -d "$device" disconnect
164 proto_notify_error "$interface" ATTACH_FAILED
165 return 1
166 }
167 tid=$((tid + 1))
168
169 pdptype=$(echo "$pdptype" | awk '{print tolower($0)}')
170 [ "$ipv6" = 0 ] && pdptype="ipv4"
171
172 local req_pdptype="" # Pass "default" PDP type to umbim if unconfigured
173 [ "$pdptype" = "ipv4" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && req_pdptype="$pdptype:"
174
175 local connect_state
176 echo "mbim[$$]" "Connect to network"
177 connect_state=$(umbim $DBG -n -t $tid -d $device connect "$req_pdptype$apn" "$auth" "$username" "$password") || {
178 echo "mbim[$$]" "Failed to connect bearer"
179 tid=$((tid + 1))
180 umbim $DBG -t $tid -d "$device" disconnect
181 proto_notify_error "$interface" CONNECT_FAILED
182 return 1
183 }
184 tid=$((tid + 1))
185
186 echo "$connect_state"
187 local iptype="$(echo "$connect_state" | grep iptype: | awk '{print $4}')"
188
189 echo "mbim[$$]" "Connected"
190
191 local zone="$(fw3 -q network "$interface" 2>/dev/null)"
192
193 echo "mbim[$$]" "Setting up $ifname"
194 local mbimconfig="$(umbim $DBG -n -t $tid -d $device config)"
195 echo "$mbimconfig"
196 tid=$((tid + 1))
197
198 proto_init_update "$ifname" 1
199 proto_send_update "$interface"
200
201 [ -z "$dhcp" ] && dhcp=1
202 [ -z "$dhcpv6" ] && dhcpv6=1
203
204 [ "$iptype" != "ipv6" ] && {
205 ipv4address=$(_proto_mbim_get_field ipv4address "$mbimconfig")
206 if [ -n "$ipv4address" ]; then
207 json_init
208 json_add_string name "${interface}_4"
209 json_add_string ifname "@$interface"
210 json_add_string proto "static"
211
212 json_add_array ipaddr
213 for address in $ipv4address; do
214 json_add_string "" "$address"
215 done
216 json_close_array
217
218 json_add_string gateway $(_proto_mbim_get_field ipv4gateway "$mbimconfig")
219
220 [ "$peerdns" = 0 ] || {
221 json_add_array dns
222 for server in $(_proto_mbim_get_field ipv4dnsserver "$mbimconfig"); do
223 json_add_string "" "$server"
224 done
225 json_close_array
226 }
227
228 proto_add_dynamic_defaults
229 [ -n "$zone" ] && json_add_string zone "$zone"
230 [ -n "$ip4table" ] && json_add_string ip4table "$ip4table"
231 json_close_object
232 ubus call network add_dynamic "$(json_dump)"
233 elif [ "$dhcp" != 0 ]; then
234 echo "mbim[$$]" "Starting DHCP on $ifname"
235 json_init
236 json_add_string name "${interface}_4"
237 json_add_string ifname "@$interface"
238 json_add_string proto "dhcp"
239 proto_add_dynamic_defaults
240 [ -n "$zone" ] && json_add_string zone "$zone"
241 [ -n "$ip4table" ] && json_add_string ip4table "$ip4table"
242 json_close_object
243 ubus call network add_dynamic "$(json_dump)"
244 fi
245 }
246
247 [ "$iptype" != "ipv4" ] && {
248 ipv6address=$(_proto_mbim_get_field ipv6address "$mbimconfig")
249 if [ -n "$ipv6address" ]; then
250 json_init
251 json_add_string name "${interface}_6"
252 json_add_string ifname "@$interface"
253 json_add_string proto "static"
254
255 json_add_array ip6addr
256 for address in $ipv6address; do
257 json_add_string "" "$address"
258 done
259 json_close_array
260
261 json_add_string ip6gw $(_proto_mbim_get_field ipv6gateway "$mbimconfig")
262
263 [ "$peerdns" = 0 ] || {
264 json_add_array dns
265 for server in $(_proto_mbim_get_field ipv6dnsserver "$mbimconfig"); do
266 json_add_string "" "$server"
267 done
268 json_close_array
269 }
270
271 proto_add_dynamic_defaults
272 [ -n "$zone" ] && json_add_string zone "$zone"
273 [ -n "$ip6table" ] && json_add_string ip6table "$ip6table"
274 json_close_object
275 ubus call network add_dynamic "$(json_dump)"
276 elif [ "$dhcpv6" != 0 ]; then
277 echo "mbim[$$]" "Starting DHCPv6 on $ifname"
278 json_init
279 json_add_string name "${interface}_6"
280 json_add_string ifname "@$interface"
281 json_add_string proto "dhcpv6"
282 json_add_string extendprefix 1
283 proto_add_dynamic_defaults
284 [ -n "$zone" ] && json_add_string zone "$zone"
285 [ -n "$ip6table" ] && json_add_string ip6table "$ip6table"
286 json_close_object
287 ubus call network add_dynamic "$(json_dump)"
288 fi
289 }
290
291 uci_set_state network $interface tid "$tid"
292 }
293
294 proto_mbim_setup() {
295 local ret
296
297 _proto_mbim_setup $@
298 ret=$?
299
300 [ "$ret" = 0 ] || {
301 logger "mbim bringup failed, retry in 15s"
302 sleep 15
303 }
304
305 return $ret
306 }
307
308 proto_mbim_teardown() {
309 local interface="$1"
310
311 local device
312 json_get_vars device
313 local tid=$(uci_get_state network $interface tid)
314
315 [ -n "$ctl_device" ] && device=$ctl_device
316
317 echo "mbim[$$]" "Stopping network"
318 [ -n "$tid" ] && {
319 umbim $DBG -t $tid -d "$device" disconnect
320 uci_revert_state network $interface tid
321 }
322
323 proto_init_update "*" 0
324 proto_send_update "$interface"
325 }
326
327 [ -n "$INCLUDE_ONLY" ] || add_protocol mbim