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