comgt: ncm: try to detect interface for ttyACM ports
[openwrt/staging/chunkeey.git] / package / network / utils / comgt / files / ncm.sh
1 #!/bin/sh
2
3 [ -n "$INCLUDE_ONLY" ] || {
4 . /lib/functions.sh
5 . ../netifd-proto.sh
6 init_proto "$@"
7 }
8
9 proto_ncm_init_config() {
10 no_device=1
11 available=1
12 proto_config_add_string "device:device"
13 proto_config_add_string ifname
14 proto_config_add_string apn
15 proto_config_add_string auth
16 proto_config_add_string username
17 proto_config_add_string password
18 proto_config_add_string pincode
19 proto_config_add_string delay
20 proto_config_add_string mode
21 proto_config_add_string pdptype
22 proto_config_add_int profile
23 proto_config_add_defaults
24 }
25
26 proto_ncm_setup() {
27 local interface="$1"
28
29 local manufacturer initialize setmode connect finalize devname devpath ifpath
30
31 local device ifname apn auth username password pincode delay mode pdptype profile $PROTO_DEFAULT_OPTIONS
32 json_get_vars device ifname apn auth username password pincode delay mode pdptype profile $PROTO_DEFAULT_OPTIONS
33
34 [ "$metric" = "" ] && metric="0"
35
36 [ -n "$profile" ] || profile=1
37
38 pdptype=$(echo "$pdptype" | awk '{print toupper($0)}')
39 [ "$pdptype" = "IP" -o "$pdptype" = "IPV6" -o "$pdptype" = "IPV4V6" ] || pdptype="IP"
40
41 [ -n "$ctl_device" ] && device=$ctl_device
42
43 [ -n "$device" ] || {
44 echo "No control device specified"
45 proto_notify_error "$interface" NO_DEVICE
46 proto_set_available "$interface" 0
47 return 1
48 }
49
50 device="$(readlink -f $device)"
51 [ -e "$device" ] || {
52 echo "Control device not valid"
53 proto_set_available "$interface" 0
54 return 1
55 }
56
57 [ -z "$ifname" ] && {
58 devname="$(basename "$device")"
59 case "$devname" in
60 'ttyACM'*)
61 devpath="$(readlink -f /sys/class/tty/$devname/device)"
62 ifpath="$devpath/../*/net"
63 ;;
64 'tty'*)
65 devpath="$(readlink -f /sys/class/tty/$devname/device)"
66 ifpath="$devpath/../../*/net"
67 ;;
68 *)
69 devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
70 ifpath="$devpath/net"
71 ;;
72 esac
73 ifname="$(ls $(ls -1 -d $ifpath | head -n 1))"
74 }
75
76 [ -n "$ifname" ] || {
77 echo "The interface could not be found."
78 proto_notify_error "$interface" NO_IFACE
79 proto_set_available "$interface" 0
80 return 1
81 }
82
83 [ -n "$delay" ] && sleep "$delay"
84
85 manufacturer=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk 'NF && $0 !~ /AT\+CGMI/ { sub(/\+CGMI: /,""); print tolower($1); exit; }')
86 [ $? -ne 0 -o -z "$manufacturer" ] && {
87 echo "Failed to get modem information"
88 proto_notify_error "$interface" GETINFO_FAILED
89 return 1
90 }
91
92 json_load "$(cat /etc/gcom/ncm.json)"
93 json_select "$manufacturer"
94 [ $? -ne 0 ] && {
95 echo "Unsupported modem"
96 proto_notify_error "$interface" UNSUPPORTED_MODEM
97 proto_set_available "$interface" 0
98 return 1
99 }
100
101 json_get_values initialize initialize
102 for i in $initialize; do
103 eval COMMAND="$i" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
104 echo "Failed to initialize modem"
105 proto_notify_error "$interface" INITIALIZE_FAILED
106 return 1
107 }
108 done
109
110 [ -n "$pincode" ] && {
111 PINCODE="$pincode" gcom -d "$device" -s /etc/gcom/setpin.gcom || {
112 echo "Unable to verify PIN"
113 proto_notify_error "$interface" PIN_FAILED
114 proto_block_restart "$interface"
115 return 1
116 }
117 }
118
119 json_get_values configure configure
120 echo "Configuring modem"
121 for i in $configure; do
122 eval COMMAND="$i" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
123 echo "Failed to configure modem"
124 proto_notify_error "$interface" CONFIGURE_FAILED
125 return 1
126 }
127 done
128
129 [ -n "$mode" ] && {
130 json_select modes
131 json_get_var setmode "$mode"
132 [ -n "$setmode" ] && {
133 echo "Setting mode"
134 eval COMMAND="$setmode" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
135 echo "Failed to set operating mode"
136 proto_notify_error "$interface" SETMODE_FAILED
137 return 1
138 }
139 }
140 json_select ..
141 }
142
143 echo "Starting network $interface"
144 json_get_vars connect
145 [ -n "$connect" ] && {
146 echo "Connecting modem"
147 eval COMMAND="$connect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
148 echo "Failed to connect"
149 proto_notify_error "$interface" CONNECT_FAILED
150 return 1
151 }
152 }
153
154 json_get_vars finalize
155
156 echo "Setting up $ifname"
157 proto_init_update "$ifname" 1
158 proto_add_data
159 json_add_string "manufacturer" "$manufacturer"
160 proto_close_data
161 proto_send_update "$interface"
162
163 local zone="$(fw3 -q network "$interface" 2>/dev/null)"
164
165 [ "$pdptype" = "IP" -o "$pdptype" = "IPV4V6" ] && {
166 json_init
167 json_add_string name "${interface}_4"
168 json_add_string ifname "@$interface"
169 json_add_string proto "dhcp"
170 proto_add_dynamic_defaults
171 [ -n "$zone" ] && {
172 json_add_string zone "$zone"
173 }
174 json_close_object
175 ubus call network add_dynamic "$(json_dump)"
176 }
177
178 [ "$pdptype" = "IPV6" -o "$pdptype" = "IPV4V6" ] && {
179 json_init
180 json_add_string name "${interface}_6"
181 json_add_string ifname "@$interface"
182 json_add_string proto "dhcpv6"
183 json_add_string extendprefix 1
184 proto_add_dynamic_defaults
185 [ -n "$zone" ] && {
186 json_add_string zone "$zone"
187 }
188 json_close_object
189 ubus call network add_dynamic "$(json_dump)"
190 }
191
192 [ -n "$finalize" ] && {
193 eval COMMAND="$finalize" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
194 echo "Failed to configure modem"
195 proto_notify_error "$interface" FINALIZE_FAILED
196 return 1
197 }
198 }
199 }
200
201 proto_ncm_teardown() {
202 local interface="$1"
203
204 local manufacturer disconnect
205
206 local device profile
207 json_get_vars device profile
208
209 [ -n "$ctl_device" ] && device=$ctl_device
210
211 [ -n "$device" ] || {
212 echo "No control device specified"
213 proto_notify_error "$interface" NO_DEVICE
214 proto_set_available "$interface" 0
215 return 1
216 }
217
218 device="$(readlink -f $device)"
219 [ -e "$device" ] || {
220 echo "Control device not valid"
221 proto_set_available "$interface" 0
222 return 1
223 }
224
225 [ -n "$profile" ] || profile=1
226
227 echo "Stopping network $interface"
228
229 json_load "$(ubus call network.interface.$interface status)"
230 json_select data
231 json_get_vars manufacturer
232 [ $? -ne 0 -o -z "$manufacturer" ] && {
233 # Fallback to direct detect, for proper handle device replug.
234 manufacturer=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom | awk 'NF && $0 !~ /AT\+CGMI/ { sub(/\+CGMI: /,""); print tolower($1); exit; }')
235 [ $? -ne 0 -o -z "$manufacturer" ] && {
236 echo "Failed to get modem information"
237 proto_notify_error "$interface" GETINFO_FAILED
238 return 1
239 }
240 json_add_string "manufacturer" "$manufacturer"
241 }
242
243 json_load "$(cat /etc/gcom/ncm.json)"
244 json_select "$manufacturer" || {
245 echo "Unsupported modem"
246 proto_notify_error "$interface" UNSUPPORTED_MODEM
247 return 1
248 }
249
250 json_get_vars disconnect
251 [ -n "$disconnect" ] && {
252 eval COMMAND="$disconnect" gcom -d "$device" -s /etc/gcom/runcommand.gcom || {
253 echo "Failed to disconnect"
254 proto_notify_error "$interface" DISCONNECT_FAILED
255 return 1
256 }
257 }
258
259 proto_init_update "*" 0
260 proto_send_update "$interface"
261 }
262 [ -n "$INCLUDE_ONLY" ] || {
263 add_protocol ncm
264 }