OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #!/bin/sh |
2 | |||
3 | [ -n "$INCLUDE_ONLY" ] || { |
||
4 | . /lib/functions.sh |
||
5 | . ../netifd-proto.sh |
||
6 | init_proto "$@" |
||
7 | } |
||
8 | |||
9 | proto_qmi_init_config() { |
||
10 | available=1 |
||
11 | no_device=1 |
||
12 | proto_config_add_string "device:device" |
||
13 | proto_config_add_string apn |
||
14 | proto_config_add_string auth |
||
15 | proto_config_add_string username |
||
16 | proto_config_add_string password |
||
17 | proto_config_add_string pincode |
||
18 | proto_config_add_int delay |
||
19 | proto_config_add_string modes |
||
20 | proto_config_add_string pdptype |
||
21 | proto_config_add_int profile |
||
22 | proto_config_add_boolean dhcpv6 |
||
23 | proto_config_add_boolean autoconnect |
||
24 | proto_config_add_int plmn |
||
25 | proto_config_add_int timeout |
||
26 | proto_config_add_defaults |
||
27 | } |
||
28 | |||
29 | proto_qmi_setup() { |
||
30 | local interface="$1" |
||
31 | local dataformat connstat |
||
32 | local device apn auth username password pincode delay modes pdptype profile dhcpv6 autoconnect plmn timeout $PROTO_DEFAULT_OPTIONS |
||
33 | local ip4table ip6table |
||
34 | local cid_4 pdh_4 cid_6 pdh_6 |
||
35 | local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6 |
||
36 | json_get_vars device apn auth username password pincode delay modes pdptype profile dhcpv6 autoconnect plmn ip4table ip6table timeout $PROTO_DEFAULT_OPTIONS |
||
37 | |||
38 | [ "$timeout" = "" ] && timeout="10" |
||
39 | |||
40 | [ "$metric" = "" ] && metric="0" |
||
41 | |||
42 | [ -n "$ctl_device" ] && device=$ctl_device |
||
43 | |||
44 | [ -n "$device" ] || { |
||
45 | echo "No control device specified" |
||
46 | proto_notify_error "$interface" NO_DEVICE |
||
47 | proto_set_available "$interface" 0 |
||
48 | return 1 |
||
49 | } |
||
50 | |||
51 | [ -n "$delay" ] && sleep "$delay" |
||
52 | |||
53 | device="$(readlink -f $device)" |
||
54 | [ -c "$device" ] || { |
||
55 | echo "The specified control device does not exist" |
||
56 | proto_notify_error "$interface" NO_DEVICE |
||
57 | proto_set_available "$interface" 0 |
||
58 | return 1 |
||
59 | } |
||
60 | |||
61 | devname="$(basename "$device")" |
||
62 | devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)" |
||
63 | ifname="$( ls "$devpath"/net )" |
||
64 | [ -n "$ifname" ] || { |
||
65 | echo "The interface could not be found." |
||
66 | proto_notify_error "$interface" NO_IFACE |
||
67 | proto_set_available "$interface" 0 |
||
68 | return 1 |
||
69 | } |
||
70 | |||
71 | echo "Waiting for SIM initialization" |
||
72 | local uninitialized_timeout=0 |
||
73 | while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do |
||
74 | [ -e "$device" ] || return 1 |
||
75 | if [ "$uninitialized_timeout" -lt "$timeout" ]; then |
||
76 | let uninitialized_timeout++ |
||
77 | sleep 1; |
||
78 | else |
||
79 | echo "SIM not initialized" |
||
80 | proto_notify_error "$interface" SIM_NOT_INITIALIZED |
||
81 | proto_block_restart "$interface" |
||
82 | return 1 |
||
83 | fi |
||
84 | done |
||
85 | |||
86 | if uqmi -s -d "$device" --get-pin-status | grep '"Not supported"\|"Invalid QMI command"' > /dev/null; then |
||
87 | [ -n "$pincode" ] && { |
||
88 | uqmi -s -d "$device" --verify-pin1 "$pincode" > /dev/null || uqmi -s -d "$device" --uim-verify-pin1 "$pincode" > /dev/null || { |
||
89 | echo "Unable to verify PIN" |
||
90 | proto_notify_error "$interface" PIN_FAILED |
||
91 | proto_block_restart "$interface" |
||
92 | return 1 |
||
93 | } |
||
94 | } |
||
95 | else |
||
96 | . /usr/share/libubox/jshn.sh |
||
97 | json_load "$(uqmi -s -d "$device" --get-pin-status)" |
||
98 | json_get_var pin1_status pin1_status |
||
99 | json_get_var pin1_verify_tries pin1_verify_tries |
||
100 | |||
101 | case "$pin1_status" in |
||
102 | disabled) |
||
103 | echo "PIN verification is disabled" |
||
104 | ;; |
||
105 | blocked) |
||
106 | echo "SIM locked PUK required" |
||
107 | proto_notify_error "$interface" PUK_NEEDED |
||
108 | proto_block_restart "$interface" |
||
109 | return 1 |
||
110 | ;; |
||
111 | not_verified) |
||
112 | [ "$pin1_verify_tries" -lt "3" ] && { |
||
113 | echo "PIN verify count value is $pin1_verify_tries this is below the limit of 3" |
||
114 | proto_notify_error "$interface" PIN_TRIES_BELOW_LIMIT |
||
115 | proto_block_restart "$interface" |
||
116 | return 1 |
||
117 | } |
||
118 | if [ -n "$pincode" ]; then |
||
119 | uqmi -s -d "$device" --verify-pin1 "$pincode" > /dev/null 2>&1 || uqmi -s -d "$device" --uim-verify-pin1 "$pincode" > /dev/null 2>&1 || { |
||
120 | echo "Unable to verify PIN" |
||
121 | proto_notify_error "$interface" PIN_FAILED |
||
122 | proto_block_restart "$interface" |
||
123 | return 1 |
||
124 | } |
||
125 | else |
||
126 | echo "PIN not specified but required" |
||
127 | proto_notify_error "$interface" PIN_NOT_SPECIFIED |
||
128 | proto_block_restart "$interface" |
||
129 | return 1 |
||
130 | fi |
||
131 | ;; |
||
132 | verified) |
||
133 | echo "PIN already verified" |
||
134 | ;; |
||
135 | *) |
||
136 | echo "PIN status failed ($pin1_status)" |
||
137 | proto_notify_error "$interface" PIN_STATUS_FAILED |
||
138 | proto_block_restart "$interface" |
||
139 | return 1 |
||
140 | ;; |
||
141 | esac |
||
142 | fi |
||
143 | |||
144 | [ -n "$plmn" ] && { |
||
145 | local mcc mnc |
||
146 | if [ "$plmn" = 0 ]; then |
||
147 | mcc=0 |
||
148 | mnc=0 |
||
149 | echo "Setting PLMN to auto" |
||
150 | else |
||
151 | mcc=${plmn:0:3} |
||
152 | mnc=${plmn:3} |
||
153 | echo "Setting PLMN to $plmn" |
||
154 | fi |
||
155 | uqmi -s -d "$device" --set-plmn --mcc "$mcc" --mnc "$mnc" > /dev/null 2>&1 || { |
||
156 | echo "Unable to set PLMN" |
||
157 | proto_notify_error "$interface" PLMN_FAILED |
||
158 | proto_block_restart "$interface" |
||
159 | return 1 |
||
160 | } |
||
161 | } |
||
162 | |||
163 | # Cleanup current state if any |
||
164 | uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect > /dev/null 2>&1 |
||
165 | |||
166 | # Set IP format |
||
167 | uqmi -s -d "$device" --set-data-format 802.3 > /dev/null 2>&1 |
||
168 | uqmi -s -d "$device" --wda-set-data-format 802.3 > /dev/null 2>&1 |
||
169 | dataformat="$(uqmi -s -d "$device" --wda-get-data-format)" |
||
170 | |||
171 | if [ "$dataformat" = '"raw-ip"' ]; then |
||
172 | |||
173 | [ -f /sys/class/net/$ifname/qmi/raw_ip ] || { |
||
174 | echo "Device only supports raw-ip mode but is missing this required driver attribute: /sys/class/net/$ifname/qmi/raw_ip" |
||
175 | return 1 |
||
176 | } |
||
177 | |||
178 | echo "Device does not support 802.3 mode. Informing driver of raw-ip only for $ifname .." |
||
179 | echo "Y" > /sys/class/net/$ifname/qmi/raw_ip |
||
180 | fi |
||
181 | |||
182 | uqmi -s -d "$device" --sync > /dev/null 2>&1 |
||
183 | |||
184 | echo "Waiting for network registration" |
||
185 | local registration_timeout=0 |
||
186 | while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do |
||
187 | [ -e "$device" ] || return 1 |
||
188 | if [ "$registration_timeout" -lt "$timeout" ]; then |
||
189 | let registration_timeout++ |
||
190 | sleep 1; |
||
191 | else |
||
192 | echo "Network registration failed" |
||
193 | proto_notify_error "$interface" NETWORK_REGISTRATION_FAILED |
||
194 | proto_block_restart "$interface" |
||
195 | return 1 |
||
196 | fi |
||
197 | done |
||
198 | |||
199 | [ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes" > /dev/null 2>&1 |
||
200 | |||
201 | echo "Starting network $interface" |
||
202 | |||
203 | pdptype=$(echo "$pdptype" | awk '{print tolower($0)}') |
||
204 | [ "$pdptype" = "ip" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] || pdptype="ip" |
||
205 | |||
206 | if [ "$pdptype" = "ip" ]; then |
||
207 | [ -z "$autoconnect" ] && autoconnect=1 |
||
208 | [ "$autoconnect" = 0 ] && autoconnect="" |
||
209 | else |
||
210 | [ "$autoconnect" = 1 ] || autoconnect="" |
||
211 | fi |
||
212 | |||
213 | [ "$pdptype" = "ip" -o "$pdptype" = "ipv4v6" ] && { |
||
214 | cid_4=$(uqmi -s -d "$device" --get-client-id wds) |
||
215 | if ! [ "$cid_4" -eq "$cid_4" ] 2> /dev/null; then |
||
216 | echo "Unable to obtain client ID" |
||
217 | proto_notify_error "$interface" NO_CID |
||
218 | return 1 |
||
219 | fi |
||
220 | |||
221 | uqmi -s -d "$device" --set-client-id wds,"$cid_4" --set-ip-family ipv4 > /dev/null 2>&1 |
||
222 | |||
223 | pdh_4=$(uqmi -s -d "$device" --set-client-id wds,"$cid_4" \ |
||
224 | --start-network \ |
||
225 | ${apn:+--apn $apn} \ |
||
226 | ${profile:+--profile $profile} \ |
||
227 | ${auth:+--auth-type $auth} \ |
||
228 | ${username:+--username $username} \ |
||
229 | ${password:+--password $password} \ |
||
230 | ${autoconnect:+--autoconnect}) |
||
231 | |||
232 | # pdh_4 is a numeric value on success |
||
233 | if ! [ "$pdh_4" -eq "$pdh_4" ] 2> /dev/null; then |
||
234 | echo "Unable to connect IPv4" |
||
235 | uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1 |
||
236 | proto_notify_error "$interface" CALL_FAILED |
||
237 | return 1 |
||
238 | fi |
||
239 | |||
240 | # Check data connection state |
||
241 | connstat=$(uqmi -s -d "$device" --get-data-status) |
||
242 | [ "$connstat" == '"connected"' ] || { |
||
243 | echo "No data link!" |
||
244 | uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1 |
||
245 | proto_notify_error "$interface" CALL_FAILED |
||
246 | return 1 |
||
247 | } |
||
248 | } |
||
249 | |||
250 | [ "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && { |
||
251 | cid_6=$(uqmi -s -d "$device" --get-client-id wds) |
||
252 | if ! [ "$cid_6" -eq "$cid_6" ] 2> /dev/null; then |
||
253 | echo "Unable to obtain client ID" |
||
254 | proto_notify_error "$interface" NO_CID |
||
255 | return 1 |
||
256 | fi |
||
257 | |||
258 | uqmi -s -d "$device" --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null 2>&1 |
||
259 | |||
260 | pdh_6=$(uqmi -s -d "$device" --set-client-id wds,"$cid_6" \ |
||
261 | --start-network \ |
||
262 | ${apn:+--apn $apn} \ |
||
263 | ${profile:+--profile $profile} \ |
||
264 | ${auth:+--auth-type $auth} \ |
||
265 | ${username:+--username $username} \ |
||
266 | ${password:+--password $password} \ |
||
267 | ${autoconnect:+--autoconnect}) |
||
268 | |||
269 | # pdh_6 is a numeric value on success |
||
270 | if ! [ "$pdh_6" -eq "$pdh_6" ] 2> /dev/null; then |
||
271 | echo "Unable to connect IPv6" |
||
272 | uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1 |
||
273 | proto_notify_error "$interface" CALL_FAILED |
||
274 | return 1 |
||
275 | fi |
||
276 | |||
277 | # Check data connection state |
||
278 | connstat=$(uqmi -s -d "$device" --get-data-status) |
||
279 | [ "$connstat" == '"connected"' ] || { |
||
280 | echo "No data link!" |
||
281 | uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1 |
||
282 | proto_notify_error "$interface" CALL_FAILED |
||
283 | return 1 |
||
284 | } |
||
285 | } |
||
286 | |||
287 | echo "Setting up $ifname" |
||
288 | proto_init_update "$ifname" 1 |
||
289 | proto_set_keep 1 |
||
290 | proto_add_data |
||
291 | [ -n "$pdh_4" ] && { |
||
292 | json_add_string "cid_4" "$cid_4" |
||
293 | json_add_string "pdh_4" "$pdh_4" |
||
294 | } |
||
295 | [ -n "$pdh_6" ] && { |
||
296 | json_add_string "cid_6" "$cid_6" |
||
297 | json_add_string "pdh_6" "$pdh_6" |
||
298 | } |
||
299 | proto_close_data |
||
300 | proto_send_update "$interface" |
||
301 | [ -n "$pdh_6" ] && { |
||
302 | if [ -z "$dhcpv6" -o "$dhcpv6" = 0 ]; then |
||
303 | json_load "$(uqmi -s -d $device --set-client-id wds,$cid_6 --get-current-settings)" |
||
304 | json_select ipv6 |
||
305 | json_get_var ip_6 ip |
||
306 | json_get_var gateway_6 gateway |
||
307 | json_get_var dns1_6 dns1 |
||
308 | json_get_var dns2_6 dns2 |
||
309 | json_get_var ip_prefix_length ip-prefix-length |
||
310 | |||
311 | proto_init_update "$ifname" 1 |
||
312 | proto_set_keep 1 |
||
313 | proto_add_ipv6_address "$ip_6" "128" |
||
314 | proto_add_ipv6_prefix "${ip_6}/${ip_prefix_length}" |
||
315 | proto_add_ipv6_route "$gateway_6" "128" |
||
316 | [ "$defaultroute" = 0 ] || proto_add_ipv6_route "::0" 0 "$gateway_6" "" "" "${ip_6}/${ip_prefix_length}" |
||
317 | [ "$peerdns" = 0 ] || { |
||
318 | proto_add_dns_server "$dns1_6" |
||
319 | proto_add_dns_server "$dns2_6" |
||
320 | } |
||
321 | proto_send_update "$interface" |
||
322 | else |
||
323 | json_init |
||
324 | json_add_string name "${interface}_6" |
||
325 | json_add_string ifname "@$interface" |
||
326 | json_add_string proto "dhcpv6" |
||
327 | [ -n "$ip6table" ] && json_add_string ip6table "$ip6table" |
||
328 | proto_add_dynamic_defaults |
||
329 | # RFC 7278: Extend an IPv6 /64 Prefix to LAN |
||
330 | json_add_string extendprefix 1 |
||
331 | json_close_object |
||
332 | ubus call network add_dynamic "$(json_dump)" |
||
333 | fi |
||
334 | } |
||
335 | |||
336 | [ -n "$pdh_4" ] && { |
||
337 | json_init |
||
338 | json_add_string name "${interface}_4" |
||
339 | json_add_string ifname "@$interface" |
||
340 | json_add_string proto "dhcp" |
||
341 | [ -n "$ip4table" ] && json_add_string ip4table "$ip4table" |
||
342 | proto_add_dynamic_defaults |
||
343 | json_close_object |
||
344 | ubus call network add_dynamic "$(json_dump)" |
||
345 | } |
||
346 | } |
||
347 | |||
348 | qmi_wds_stop() { |
||
349 | local cid="$1" |
||
350 | local pdh="$2" |
||
351 | |||
352 | [ -n "$cid" ] || return |
||
353 | |||
354 | uqmi -s -d "$device" --set-client-id wds,"$cid" \ |
||
355 | --stop-network 0xffffffff \ |
||
356 | --autoconnect > /dev/null 2>&1 |
||
357 | |||
358 | [ -n "$pdh" ] && { |
||
359 | uqmi -s -d "$device" --set-client-id wds,"$cid" \ |
||
360 | --stop-network "$pdh" > /dev/null 2>&1 |
||
361 | } |
||
362 | |||
363 | uqmi -s -d "$device" --set-client-id wds,"$cid" \ |
||
364 | --release-client-id wds > /dev/null 2>&1 |
||
365 | } |
||
366 | |||
367 | proto_qmi_teardown() { |
||
368 | local interface="$1" |
||
369 | |||
370 | local device cid_4 pdh_4 cid_6 pdh_6 |
||
371 | json_get_vars device |
||
372 | |||
373 | [ -n "$ctl_device" ] && device=$ctl_device |
||
374 | |||
375 | echo "Stopping network $interface" |
||
376 | |||
377 | json_load "$(ubus call network.interface.$interface status)" |
||
378 | json_select data |
||
379 | json_get_vars cid_4 pdh_4 cid_6 pdh_6 |
||
380 | |||
381 | qmi_wds_stop "$cid_4" "$pdh_4" |
||
382 | qmi_wds_stop "$cid_6" "$pdh_6" |
||
383 | |||
384 | proto_init_update "*" 0 |
||
385 | proto_send_update "$interface" |
||
386 | } |
||
387 | |||
388 | [ -n "$INCLUDE_ONLY" ] || { |
||
389 | add_protocol qmi |
||
390 | } |