wwan: add a generic 3g/4g proto
[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
93 echo "Waiting for network registration"
94 while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do
95 sleep 5;
96 done
97
98 [ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes"
99
100 echo "Starting network $apn"
101 cid=`uqmi -s -d "$device" --get-client-id wds`
102 [ $? -ne 0 ] && {
103 echo "Unable to obtain client ID"
104 proto_notify_error "$interface" NO_CID
105 return 1
106 }
107
108 uqmi -s -d "$device" --set-client-id wds,"$cid" \
109 --start-network "$apn" \
110 ${auth:+--auth-type $auth} \
111 ${username:+--username $username} \
112 ${password:+--password $password} \
113 --autoconnect > /dev/null
114
115 echo "Starting DHCP"
116 proto_init_update "$ifname" 1
117 proto_send_update "$interface"
118
119 json_init
120 json_add_string name "${interface}_dhcp"
121 json_add_string ifname "@$interface"
122 json_add_string proto "dhcp"
123 json_close_object
124 ubus call network add_dynamic "$(json_dump)"
125
126 json_init
127 json_add_string name "${interface}_dhcpv6"
128 json_add_string ifname "@$interface"
129 json_add_string proto "dhcpv6"
130 json_close_object
131 ubus call network add_dynamic "$(json_dump)"
132 }
133
134 proto_qmi_teardown() {
135 local interface="$1"
136
137 local device
138 json_get_vars device
139
140 [ -n "$ctl_device" ] && device=$ctl_device
141
142 local cid=$(uci_get_state network $interface cid)
143
144 echo "Stopping network"
145 qmi_disconnect
146 qmi_wds_release
147
148 proto_init_update "*" 0
149 proto_send_update "$interface"
150 }
151
152 [ -n "$INCLUDE_ONLY" ] || {
153 add_protocol qmi
154 }