uqmi: Add support for QMI-based mobile broadband modems
[openwrt/.git] / package / network / utils / uqmi / files / lib / netifd / proto / qmi.sh
1 #!/bin/sh
2
3 . /lib/functions.sh
4 . ../netifd-proto.sh
5 init_proto "$@"
6
7 proto_qmi_init_config() {
8         proto_config_add_string "device:device"
9         proto_config_add_string apn
10         proto_config_add_string auth
11         proto_config_add_string username
12         proto_config_add_string password
13         proto_config_add_string pincode
14         proto_config_add_string delay
15         proto_config_add_string modes
16 }
17
18 proto_qmi_setup() {
19         local interface="$1"
20
21         local device apn auth username password pincode delay modes cid pdh
22         json_get_vars device apn auth username password pincode delay modes
23
24         [ -n "$device" ] || {
25                 logger -p daemon.err -t "qmi[$$]" "No control device specified"
26                 proto_notify_error "$interface" NO_DEVICE
27                 proto_block_restart "$interface"
28                 return 1
29         }
30         [ -c "$device" ] || {
31                 logger -p daemon.err -t "qmi[$$]" "The specified control device does not exist"
32                 proto_notify_error "$interface" NO_DEVICE
33                 proto_block_restart "$interface"
34                 return 1
35         }
36
37         [ -n "$delay" ] && sleep "$delay"
38
39         while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
40                 sleep 1;
41         done
42
43         [ -n "$pincode" ] && {
44                 uqmi -s -d "$device" --verify-pin1 "$pincode" || {
45                         logger -p daemon.err -t "qmi[$$]" "Unable to verify PIN"
46                         proto_notify_error "$interface" PIN_FAILED
47                         proto_block_restart "$interface"
48                         return 1
49                 }
50         }
51
52         [ -n "$apn" ] || {
53                 logger -p daemon.err -t "qmi[$$]" "No APN specified"
54                 proto_notify_error "$interface" NO_APN
55                 proto_block_restart "$interface"
56                 return 1
57         }
58
59         logger -p daemon.info -t "qmi[$$]" "Waiting for network registration"
60         while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do
61                 sleep 5;
62         done
63
64         [ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes"
65
66         logger -p daemon.info -t "qmi[$$]" "Starting network $apn"
67         cid=`uqmi -s -d "$device" --get-client-id wds`
68         [ $? -ne 0 ] && {
69                 logger -p daemon.err -t "qmi[$$]" "Unable to obtain client ID"
70                 proto_notify_error "$interface" NO_CID
71                 proto_block_restart "$interface"
72                 return 1
73         }
74         uci_set_state network $interface cid "$cid"
75
76         pdh=`uqmi -s -d "$device" --set-client-id wds,"$cid" --start-network "$apn" \
77         ${auth:+--auth-type $auth} \
78         ${username:+--username $username} \
79         ${password:+--password $password}`
80         [ $? -ne 0 ] && {
81                 logger -p daemon.err -t "qmi[$$]" "Unable to connect, check APN and authentication"
82                 proto_notify_error "$interface" NO_PDH
83                 proto_block_restart "$interface"
84                 return 1
85         }
86         uci_set_state network $interface pdh "$pdh"
87
88         if ! uqmi -s -d "$device" --get-data-status | grep '"connected"' > /dev/null; then
89                 logger -p daemon.err -t "qmi[$$]" "Connection lost"
90                 proto_notify_error "$interface" NOT_CONNECTED
91                 proto_block_restart "$interface"
92                 return 1
93         fi
94
95         logger -p daemon.info -t "qmi[$$]" "Connected, starting DHCP"
96         proto_init_update "*" 1
97         proto_send_update "$interface"
98
99         json_init
100         json_add_string name "${interface}_dhcp"
101         json_add_string ifname "@$interface"
102         json_add_string proto "dhcp"
103         json_close_object
104         ubus call network add_dynamic "$(json_dump)"
105
106         json_init
107         json_add_string name "${interface}_dhcpv6"
108         json_add_string ifname "@$interface"
109         json_add_string proto "dhcpv6"
110         json_close_object
111         ubus call network add_dynamic "$(json_dump)"
112 }
113
114 proto_qmi_teardown() {
115         local interface="$1"
116
117         local device
118         json_get_vars device
119         local cid=$(uci_get_state network $interface cid)
120         local pdh=$(uci_get_state network $interface pdh)
121
122         logger -p daemon.info -t "qmi[$$]" "Stopping network"
123         [ -n "$cid" ] && {
124                 [ -n "$pdh" ] && {
125                         uqmi -s -d "$device" --set-client-id wds,"$cid" --stop-network "$pdh"
126                         uci_revert_state network $interface pdh
127                 }
128                 uqmi -s -d "$device" --set-client-id wds,"$cid" --release-client-id wds
129                 uci_revert_state network $interface cid
130         }
131
132         proto_init_update "*" 0
133         proto_send_update "$interface"
134 }
135
136 add_protocol qmi
137