1#!/bin/sh 2 3[ -n "$INCLUDE_ONLY" ] || { 4 . /lib/functions.sh 5 . ../netifd-proto.sh 6 init_proto "$@" 7} 8 9proto_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 proto_config_add_boolean ipv6 21 proto_config_add_boolean dhcp 22} 23 24proto_qmi_setup() { 25 local interface="$1" 26 27 local device apn auth username password pincode delay modes ipv6 dhcp 28 local cid_4 pdh_4 cid_6 pdh_6 ipv4 29 local ip subnet gateway dns1 dns2 ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6 30 json_get_vars device apn auth username password pincode delay modes ipv6 dhcp 31 32 ipv4=1 33 34 if [ "$ipv6" = 0 ]; then 35 ipv6="" 36 else 37 ipv6=1 38 fi 39 40 [ -n "$ctl_device" ] && device=$ctl_device 41 42 [ -n "$device" ] || { 43 echo "No control device specified" 44 proto_notify_error "$interface" NO_DEVICE 45 proto_set_available "$interface" 0 46 return 1 47 } 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 65 [ -n "$delay" ] && sleep "$delay" 66 67 while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do 68 sleep 1; 69 done 70 71 [ -n "$pincode" ] && { 72 uqmi -s -d "$device" --verify-pin1 "$pincode" || { 73 echo "Unable to verify PIN" 74 proto_notify_error "$interface" PIN_FAILED 75 proto_block_restart "$interface" 76 return 1 77 } 78 } 79 80 [ -n "$apn" ] || { 81 echo "No APN specified" 82 proto_notify_error "$interface" NO_APN 83 return 1 84 } 85 86 uqmi -s -d "$device" --set-data-format 802.3 87 uqmi -s -d "$device" --wda-set-data-format 802.3 88 89 echo "Waiting for network registration" 90 while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do 91 sleep 5; 92 done 93 94 [ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes" 95 96 echo "Starting network $apn" 97 98 cid_4=`uqmi -s -d "$device" --get-client-id wds` 99 [ $? -ne 0 ] && { 100 echo "Unable to obtain client ID" 101 proto_notify_error "$interface" NO_CID 102 return 1 103 } 104 105 pdh_4=`uqmi -s -d "$device" --set-client-id wds,"$cid_4" \ 106 --start-network "$apn" \ 107 ${auth:+--auth-type $auth} \ 108 ${username:+--username $username} \ 109 ${password:+--password $password} \ 110 --ip-family ipv4` 111 [ $? -ne 0 ] && { 112 echo "Unable to connect IPv4" 113 uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds 114 ipv4="" 115 } 116 117 [ -n "$ipv6" ] && { 118 cid_6=`uqmi -s -d "$device" --get-client-id wds` 119 if [ $? = 0 ]; then 120 pdh_6=`uqmi -s -d "$device" --set-client-id wds,"$cid_6" \ 121 --start-network "$apn" \ 122 ${auth:+--auth-type $auth} \ 123 ${username:+--username $username} \ 124 ${password:+--password $password} \ 125 --ip-family ipv6` 126 [ $? -ne 0 ] && { 127 echo "Unable to connect IPv6" 128 uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds 129 ipv6="" 130 } 131 else 132 echo "Unable to connect IPv6" 133 ipv6="" 134 fi 135 } 136 137 [ -z "$ipv4" -a -z "$ipv6" ] && { 138 echo "Unable to connect" 139 proto_notify_error "$interface" CALL_FAILED 140 return 1 141 } 142 143 if [ -z "$dhcp" -o "$dhcp" = 0 ]; then 144 echo "Setting up $ifname" 145 [ -n "$ipv4" ] && { 146 json_load "$(uqmi -s -d $device --set-client-id wds,$cid_4 --get-current-settings)" 147 json_select ipv4 148 json_get_vars ip subnet gateway dns1 dns2 149 150 proto_init_update "$ifname" 1 151 proto_set_keep 1 152 proto_add_ipv4_address "$ip" "$subnet" 153 proto_add_dns_server "$dns1" 154 proto_add_dns_server "$dns2" 155 proto_add_ipv4_route "0.0.0.0" 0 "$gateway" 156 proto_add_data 157 json_add_string "cid_4" "$cid_4" 158 json_add_string "pdh_4" "$pdh_4" 159 proto_close_data 160 proto_send_update "$interface" 161 } 162 163 [ -n "$ipv6" ] && { 164 json_load "$(uqmi -s -d $device --set-client-id wds,$cid_6 --get-current-settings)" 165 json_select ipv6 166 json_get_var ip_6 ip 167 json_get_var gateway_6 gateway 168 json_get_var dns1_6 dns1 169 json_get_var dns2_6 dns2 170 json_get_var ip_prefix_length ip-prefix-length 171 172 proto_init_update "$ifname" 1 173 proto_set_keep 1 174 # RFC 7278: Extend an IPv6 /64 Prefix to LAN 175 proto_add_ipv6_address "$ip_6" "128" 176 proto_add_ipv6_prefix "${ip_6}/${ip_prefix_length}" 177 proto_add_ipv6_route "$gateway_6" "128" 178 proto_add_ipv6_route "::0" 0 "$gateway_6" "" "" "${ip_6}/${ip_prefix_length}" 179 proto_add_dns_server "$dns1_6" 180 proto_add_dns_server "$dns2_6" 181 proto_add_data 182 json_add_string "cid_6" "$cid_6" 183 json_add_string "pdh_6" "$pdh_6" 184 proto_close_data 185 proto_send_update "$interface" 186 } 187 else 188 echo "Starting DHCP on $ifname" 189 proto_init_update "$ifname" 1 190 proto_add_data 191 [ -n "$ipv4" ] && { 192 json_add_string "cid_4" "$cid_4" 193 json_add_string "pdh_4" "$pdh_4" 194 } 195 [ -n "$ipv6" ] && { 196 json_add_string "cid_6" "$cid_6" 197 json_add_string "pdh_6" "$pdh_6" 198 } 199 proto_close_data 200 proto_send_update "$interface" 201 202 [ -n "$ipv4" ] && { 203 json_init 204 json_add_string name "${interface}_4" 205 json_add_string ifname "@$interface" 206 json_add_string proto "dhcp" 207 json_close_object 208 ubus call network add_dynamic "$(json_dump)" 209 } 210 211 [ -n "$ipv6" ] && { 212 json_init 213 json_add_string name "${interface}_6" 214 json_add_string ifname "@$interface" 215 json_add_string proto "dhcpv6" 216 # RFC 7278: Extend an IPv6 /64 Prefix to LAN 217 json_add_string extendprefix 1 218 json_close_object 219 ubus call network add_dynamic "$(json_dump)" 220 } 221 fi 222} 223 224proto_qmi_teardown() { 225 local interface="$1" 226 227 local device cid_4 pdh_4 cid_6 pdh_6 228 json_get_vars device 229 230 [ -n "$ctl_device" ] && device=$ctl_device 231 232 echo "Stopping network" 233 234 json_load "$(ubus call network.interface.$interface status)" 235 json_select data 236 json_get_vars cid_4 pdh_4 cid_6 pdh_6 237 238 [ -n "$cid_4" ] && { 239 [ -n "$pdh_4" ] && { 240 uqmi -s -d "$device" --set-client-id wds,"$cid_4" --stop-network "$pdh_4" 241 uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds 242 } 243 } 244 [ -n "$cid_6" ] && { 245 [ -n "$pdh_6" ] && { 246 uqmi -s -d "$device" --set-client-id wds,"$cid_6" --stop-network "$pdh_6" 247 uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds 248 } 249 } 250 251 proto_init_update "*" 0 252 proto_send_update "$interface" 253} 254 255[ -n "$INCLUDE_ONLY" ] || { 256 add_protocol qmi 257} 258