b416da6bc82caa2b41227508afc05ecbe69ec940
[openwrt/openwrt.git] / package / network / utils / uqmi / files / lib / netifd / proto / qmi.sh
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_string delay
19 proto_config_add_string modes
20 }
21
22 qmi_disconnect() {
23 # disable previous autoconnect state using the global handle
24 # do not reuse previous wds client id to prevent hangs caused by stale data
25 uqmi -s -d "$device" \
26 --stop-network 0xffffffff \
27 --autoconnect > /dev/null
28 }
29
30 qmi_wds_release() {
31 [ -n "$cid" ] || return 0
32
33 uqmi -s -d "$device" --set-client-id wds,"$cid" --release-client-id wds
34 uci_revert_state network $interface cid
35 }
36
37 _proto_qmi_setup() {
38 local interface="$1"
39
40 local device apn auth username password pincode delay modes cid pdh
41 json_get_vars device apn auth username password pincode delay modes
42
43 [ -n "$ctl_device" ] && device=$ctl_device
44
45 [ -n "$device" ] || {
46 echo "No control device specified"
47 proto_notify_error "$interface" NO_DEVICE
48 proto_set_available "$interface" 0
49 return 1
50 }
51 [ -c "$device" ] || {
52 echo "The specified control device does not exist"
53 proto_notify_error "$interface" NO_DEVICE
54 proto_set_available "$interface" 0
55 return 1
56 }
57
58 devname="$(basename "$device")"
59 devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
60 ifname="$( ls "$devpath"/net )"
61 [ -n "$ifname" ] || {
62 echo "The interface could not be found."
63 proto_notify_error "$interface" NO_IFACE
64 proto_set_available "$interface" 0
65 return 1
66 }
67
68 [ -n "$delay" ] && sleep "$delay"
69
70 while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
71 sleep 1;
72 done
73
74 [ -n "$pincode" ] && {
75 uqmi -s -d "$device" --verify-pin1 "$pincode" || {
76 echo "Unable to verify PIN"
77 proto_notify_error "$interface" PIN_FAILED
78 proto_block_restart "$interface"
79 return 1
80 }
81 }
82
83 [ -n "$apn" ] || {
84 echo "No APN specified"
85 proto_notify_error "$interface" NO_APN
86 return 1
87 }
88
89 qmi_disconnect
90
91 uqmi -s -d "$device" --set-data-format 802.3
92 uqmi -s -d "$device" --wda-set-data-format 802.3
93
94 echo "Waiting for network registration"
95 while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do
96 sleep 5;
97 done
98
99 [ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes"
100
101 echo "Starting network $apn"
102 cid=`uqmi -s -d "$device" --get-client-id wds`
103 [ $? -ne 0 ] && {
104 echo "Unable to obtain client ID"
105 proto_notify_error "$interface" NO_CID
106 return 1
107 }
108
109 uqmi -s -d "$device" --set-client-id wds,"$cid" \
110 --start-network "$apn" \
111 ${auth:+--auth-type $auth} \
112 ${username:+--username $username} \
113 ${password:+--password $password} \
114 --autoconnect > /dev/null
115
116 echo "Starting DHCP"
117 proto_init_update "$ifname" 1
118 proto_send_update "$interface"
119
120 json_init
121 json_add_string name "${interface}_4"
122 json_add_string ifname "@$interface"
123 json_add_string proto "dhcp"
124 json_close_object
125 ubus call network add_dynamic "$(json_dump)"
126
127 json_init
128 json_add_string name "${interface}_6"
129 json_add_string ifname "@$interface"
130 json_add_string proto "dhcpv6"
131 json_add_string extendprefix 1
132 json_close_object
133 ubus call network add_dynamic "$(json_dump)"
134 }
135
136 proto_qmi_setup() {
137 local ret
138
139 _proto_qmi_setup $@
140 ret=$?
141
142 [ "$ret" = 0 ] || {
143 logger "qmi bringup failed, retry in 15s"
144 sleep 15
145 }
146
147 return $rt
148 }
149
150 proto_qmi_teardown() {
151 local interface="$1"
152
153 local device
154 json_get_vars device
155
156 [ -n "$ctl_device" ] && device=$ctl_device
157
158 local cid=$(uci_get_state network $interface cid)
159
160 echo "Stopping network"
161 qmi_disconnect
162 qmi_wds_release
163
164 proto_init_update "*" 0
165 proto_send_update "$interface"
166 }
167
168 [ -n "$INCLUDE_ONLY" ] || {
169 add_protocol qmi
170 }