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