OpenWrt – Blame information for rev 3
?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_defaults |
||
26 | } |
||
27 | |||
28 | proto_qmi_setup() { |
||
29 | local interface="$1" |
||
30 | local dataformat connstat |
||
3 | office | 31 | local device apn auth username password pincode delay modes pdptype profile dhcpv6 autoconnect plmn $PROTO_DEFAULT_OPTIONS |
1 | office | 32 | local cid_4 pdh_4 cid_6 pdh_6 |
33 | local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6 |
||
3 | office | 34 | json_get_vars device apn auth username password pincode delay modes pdptype profile dhcpv6 autoconnect plmn $PROTO_DEFAULT_OPTIONS |
1 | office | 35 | |
36 | [ "$metric" = "" ] && metric="0" |
||
37 | |||
38 | [ -n "$ctl_device" ] && device=$ctl_device |
||
39 | |||
40 | [ -n "$device" ] || { |
||
41 | echo "No control device specified" |
||
42 | proto_notify_error "$interface" NO_DEVICE |
||
43 | proto_set_available "$interface" 0 |
||
44 | return 1 |
||
45 | } |
||
46 | |||
47 | device="$(readlink -f $device)" |
||
48 | [ -c "$device" ] || { |
||
49 | echo "The specified control device does not exist" |
||
50 | proto_notify_error "$interface" NO_DEVICE |
||
51 | proto_set_available "$interface" 0 |
||
52 | return 1 |
||
53 | } |
||
54 | |||
55 | devname="$(basename "$device")" |
||
56 | devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)" |
||
57 | ifname="$( ls "$devpath"/net )" |
||
58 | [ -n "$ifname" ] || { |
||
59 | echo "The interface could not be found." |
||
60 | proto_notify_error "$interface" NO_IFACE |
||
61 | proto_set_available "$interface" 0 |
||
62 | return 1 |
||
63 | } |
||
64 | |||
3 | office | 65 | [ -n "$delay" ] && sleep "$delay" |
66 | |||
1 | office | 67 | while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do |
68 | [ -e "$device" ] || return 1 |
||
3 | office | 69 | sleep 1; |
70 | done |
||
71 | |||
72 | [ -n "$pincode" ] && { |
||
73 | uqmi -s -d "$device" --verify-pin1 "$pincode" > /dev/null || uqmi -s -d "$device" --uim-verify-pin1 "$pincode" > /dev/null || { |
||
74 | echo "Unable to verify PIN" |
||
75 | proto_notify_error "$interface" PIN_FAILED |
||
1 | office | 76 | proto_block_restart "$interface" |
77 | return 1 |
||
78 | } |
||
3 | office | 79 | } |
1 | office | 80 | |
81 | [ -n "$plmn" ] && { |
||
82 | local mcc mnc |
||
83 | if [ "$plmn" = 0 ]; then |
||
84 | mcc=0 |
||
85 | mnc=0 |
||
86 | echo "Setting PLMN to auto" |
||
87 | else |
||
88 | mcc=${plmn:0:3} |
||
89 | mnc=${plmn:3} |
||
90 | echo "Setting PLMN to $plmn" |
||
91 | fi |
||
3 | office | 92 | uqmi -s -d "$device" --set-plmn --mcc "$mcc" --mnc "$mnc" || { |
1 | office | 93 | echo "Unable to set PLMN" |
94 | proto_notify_error "$interface" PLMN_FAILED |
||
95 | proto_block_restart "$interface" |
||
96 | return 1 |
||
97 | } |
||
98 | } |
||
99 | |||
100 | # Cleanup current state if any |
||
3 | office | 101 | uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect |
1 | office | 102 | |
103 | # Set IP format |
||
3 | office | 104 | uqmi -s -d "$device" --set-data-format 802.3 |
105 | uqmi -s -d "$device" --wda-set-data-format 802.3 |
||
1 | office | 106 | dataformat="$(uqmi -s -d "$device" --wda-get-data-format)" |
107 | |||
108 | if [ "$dataformat" = '"raw-ip"' ]; then |
||
109 | |||
110 | [ -f /sys/class/net/$ifname/qmi/raw_ip ] || { |
||
111 | echo "Device only supports raw-ip mode but is missing this required driver attribute: /sys/class/net/$ifname/qmi/raw_ip" |
||
112 | return 1 |
||
113 | } |
||
114 | |||
115 | echo "Device does not support 802.3 mode. Informing driver of raw-ip only for $ifname .." |
||
116 | echo "Y" > /sys/class/net/$ifname/qmi/raw_ip |
||
117 | fi |
||
118 | |||
3 | office | 119 | uqmi -s -d "$device" --sync |
1 | office | 120 | |
121 | echo "Waiting for network registration" |
||
122 | while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do |
||
123 | [ -e "$device" ] || return 1 |
||
3 | office | 124 | sleep 5; |
1 | office | 125 | done |
126 | |||
3 | office | 127 | [ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes" |
1 | office | 128 | |
129 | echo "Starting network $interface" |
||
130 | |||
131 | pdptype=$(echo "$pdptype" | awk '{print tolower($0)}') |
||
132 | [ "$pdptype" = "ip" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] || pdptype="ip" |
||
133 | |||
134 | if [ "$pdptype" = "ip" ]; then |
||
135 | [ -z "$autoconnect" ] && autoconnect=1 |
||
136 | [ "$autoconnect" = 0 ] && autoconnect="" |
||
137 | else |
||
138 | [ "$autoconnect" = 1 ] || autoconnect="" |
||
139 | fi |
||
140 | |||
141 | [ "$pdptype" = "ip" -o "$pdptype" = "ipv4v6" ] && { |
||
142 | cid_4=$(uqmi -s -d "$device" --get-client-id wds) |
||
143 | if ! [ "$cid_4" -eq "$cid_4" ] 2> /dev/null; then |
||
144 | echo "Unable to obtain client ID" |
||
145 | proto_notify_error "$interface" NO_CID |
||
146 | return 1 |
||
147 | fi |
||
148 | |||
3 | office | 149 | uqmi -s -d "$device" --set-client-id wds,"$cid_4" --set-ip-family ipv4 > /dev/null |
1 | office | 150 | |
151 | pdh_4=$(uqmi -s -d "$device" --set-client-id wds,"$cid_4" \ |
||
152 | --start-network \ |
||
153 | ${apn:+--apn $apn} \ |
||
154 | ${profile:+--profile $profile} \ |
||
155 | ${auth:+--auth-type $auth} \ |
||
156 | ${username:+--username $username} \ |
||
157 | ${password:+--password $password} \ |
||
158 | ${autoconnect:+--autoconnect}) |
||
159 | |||
3 | office | 160 | # pdh_4 is a numeric value on success |
1 | office | 161 | if ! [ "$pdh_4" -eq "$pdh_4" ] 2> /dev/null; then |
162 | echo "Unable to connect IPv4" |
||
3 | office | 163 | uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds |
1 | office | 164 | proto_notify_error "$interface" CALL_FAILED |
165 | return 1 |
||
166 | fi |
||
167 | |||
3 | office | 168 | # Check data connection state |
1 | office | 169 | connstat=$(uqmi -s -d "$device" --get-data-status) |
3 | office | 170 | [ "$connstat" == '"connected"' ] || { |
171 | echo "No data link!" |
||
172 | uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds |
||
173 | proto_notify_error "$interface" CALL_FAILED |
||
174 | return 1 |
||
175 | } |
||
1 | office | 176 | } |
177 | |||
178 | [ "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && { |
||
179 | cid_6=$(uqmi -s -d "$device" --get-client-id wds) |
||
180 | if ! [ "$cid_6" -eq "$cid_6" ] 2> /dev/null; then |
||
181 | echo "Unable to obtain client ID" |
||
182 | proto_notify_error "$interface" NO_CID |
||
183 | return 1 |
||
184 | fi |
||
185 | |||
3 | office | 186 | uqmi -s -d "$device" --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null |
1 | office | 187 | |
188 | pdh_6=$(uqmi -s -d "$device" --set-client-id wds,"$cid_6" \ |
||
189 | --start-network \ |
||
190 | ${apn:+--apn $apn} \ |
||
191 | ${profile:+--profile $profile} \ |
||
192 | ${auth:+--auth-type $auth} \ |
||
193 | ${username:+--username $username} \ |
||
194 | ${password:+--password $password} \ |
||
195 | ${autoconnect:+--autoconnect}) |
||
196 | |||
3 | office | 197 | # pdh_6 is a numeric value on success |
1 | office | 198 | if ! [ "$pdh_6" -eq "$pdh_6" ] 2> /dev/null; then |
199 | echo "Unable to connect IPv6" |
||
3 | office | 200 | uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds |
1 | office | 201 | proto_notify_error "$interface" CALL_FAILED |
202 | return 1 |
||
203 | fi |
||
204 | |||
3 | office | 205 | # Check data connection state |
1 | office | 206 | connstat=$(uqmi -s -d "$device" --get-data-status) |
3 | office | 207 | [ "$connstat" == '"connected"' ] || { |
208 | echo "No data link!" |
||
209 | uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds |
||
210 | proto_notify_error "$interface" CALL_FAILED |
||
211 | return 1 |
||
212 | } |
||
1 | office | 213 | } |
214 | |||
215 | echo "Setting up $ifname" |
||
216 | proto_init_update "$ifname" 1 |
||
217 | proto_set_keep 1 |
||
218 | proto_add_data |
||
219 | [ -n "$pdh_4" ] && { |
||
220 | json_add_string "cid_4" "$cid_4" |
||
221 | json_add_string "pdh_4" "$pdh_4" |
||
222 | } |
||
223 | [ -n "$pdh_6" ] && { |
||
224 | json_add_string "cid_6" "$cid_6" |
||
225 | json_add_string "pdh_6" "$pdh_6" |
||
226 | } |
||
227 | proto_close_data |
||
228 | proto_send_update "$interface" |
||
229 | [ -n "$pdh_6" ] && { |
||
230 | if [ -z "$dhcpv6" -o "$dhcpv6" = 0 ]; then |
||
231 | json_load "$(uqmi -s -d $device --set-client-id wds,$cid_6 --get-current-settings)" |
||
232 | json_select ipv6 |
||
233 | json_get_var ip_6 ip |
||
234 | json_get_var gateway_6 gateway |
||
235 | json_get_var dns1_6 dns1 |
||
236 | json_get_var dns2_6 dns2 |
||
237 | json_get_var ip_prefix_length ip-prefix-length |
||
238 | |||
239 | proto_init_update "$ifname" 1 |
||
240 | proto_set_keep 1 |
||
241 | proto_add_ipv6_address "$ip_6" "128" |
||
242 | proto_add_ipv6_prefix "${ip_6}/${ip_prefix_length}" |
||
243 | proto_add_ipv6_route "$gateway_6" "128" |
||
244 | [ "$defaultroute" = 0 ] || proto_add_ipv6_route "::0" 0 "$gateway_6" "" "" "${ip_6}/${ip_prefix_length}" |
||
245 | [ "$peerdns" = 0 ] || { |
||
246 | proto_add_dns_server "$dns1_6" |
||
247 | proto_add_dns_server "$dns2_6" |
||
248 | } |
||
249 | proto_send_update "$interface" |
||
250 | else |
||
251 | json_init |
||
252 | json_add_string name "${interface}_6" |
||
253 | json_add_string ifname "@$interface" |
||
254 | json_add_string proto "dhcpv6" |
||
255 | proto_add_dynamic_defaults |
||
256 | # RFC 7278: Extend an IPv6 /64 Prefix to LAN |
||
257 | json_add_string extendprefix 1 |
||
258 | json_close_object |
||
259 | ubus call network add_dynamic "$(json_dump)" |
||
260 | fi |
||
261 | } |
||
262 | |||
263 | [ -n "$pdh_4" ] && { |
||
264 | json_init |
||
265 | json_add_string name "${interface}_4" |
||
266 | json_add_string ifname "@$interface" |
||
267 | json_add_string proto "dhcp" |
||
268 | proto_add_dynamic_defaults |
||
269 | json_close_object |
||
270 | ubus call network add_dynamic "$(json_dump)" |
||
271 | } |
||
272 | } |
||
273 | |||
274 | qmi_wds_stop() { |
||
275 | local cid="$1" |
||
276 | local pdh="$2" |
||
277 | |||
278 | [ -n "$cid" ] || return |
||
279 | |||
280 | uqmi -s -d "$device" --set-client-id wds,"$cid" \ |
||
281 | --stop-network 0xffffffff \ |
||
282 | --autoconnect > /dev/null 2>&1 |
||
283 | |||
284 | [ -n "$pdh" ] && { |
||
285 | uqmi -s -d "$device" --set-client-id wds,"$cid" \ |
||
286 | --stop-network "$pdh" > /dev/null 2>&1 |
||
287 | } |
||
288 | |||
289 | uqmi -s -d "$device" --set-client-id wds,"$cid" \ |
||
290 | --release-client-id wds > /dev/null 2>&1 |
||
291 | } |
||
292 | |||
293 | proto_qmi_teardown() { |
||
294 | local interface="$1" |
||
295 | |||
296 | local device cid_4 pdh_4 cid_6 pdh_6 |
||
297 | json_get_vars device |
||
298 | |||
299 | [ -n "$ctl_device" ] && device=$ctl_device |
||
300 | |||
301 | echo "Stopping network $interface" |
||
302 | |||
303 | json_load "$(ubus call network.interface.$interface status)" |
||
304 | json_select data |
||
305 | json_get_vars cid_4 pdh_4 cid_6 pdh_6 |
||
306 | |||
307 | qmi_wds_stop "$cid_4" "$pdh_4" |
||
308 | qmi_wds_stop "$cid_6" "$pdh_6" |
||
309 | |||
310 | proto_init_update "*" 0 |
||
311 | proto_send_update "$interface" |
||
312 | } |
||
313 | |||
314 | [ -n "$INCLUDE_ONLY" ] || { |
||
315 | add_protocol qmi |
||
316 | } |