1 #!/bin/sh 2 3 [ -n "$INCLUDE_ONLY" ] || { 4 . /lib/functions.sh 5 . ../netifd-proto.sh 6 init_proto "$@" 7 } 8 9 _qdebug() { 10 logger -t qmi "$@" 11 } 12 13 PROTO_OPTIONS="apn username password pin roaming" 14 proto_qmid_init_config() { 15 available=1 16 no_device=1 17 proto_config_add_string "device:device" 18 proto_config_add_string apn 19 proto_config_add_string username 20 proto_config_add_string password 21 proto_config_add_string pin 22 proto_config_add_string roaming 23 proto_config_add_defaults 24 } 25 26 # convert /dev/cdc-wdm0 -> modem0 27 _qmid_convert_devtoname() { 28 local device="$1" 29 30 if echo "${device}" | grep -q "/dev/cdc-wdm"; then 31 echo "${device/\/dev\/cdc-wdm/modem}" 32 else 33 false 34 fi 35 } 36 37 # check if uqmid already knows the device 38 _qmi_device_present() { 39 ubus list "uqmid.modem.$1" 2>/dev/null >/dev/null 40 } 41 42 _qmi_ensure_device_present() { 43 local name="$1" 44 local device="$2" 45 46 if _qmi_device_present "$name"; then 47 return 0 48 fi 49 50 ubus call uqmid add_modem "{'name':'$name','device':'$device'}" 51 _qmi_device_present "$name" 52 } 53 54 _qmi_poll_state() { 55 local name=$1 56 local timeout=$2 57 58 # in theory we should have multiple timeouts 59 # we should only have a long timeout if we reach netsearch 60 for _i in $(seq 1 "$timeout"); do 61 json_init 62 json_load "$(ubus call "uqmid.modem.$name" dump)" 63 json_get_var state_name state_name 64 case "$state_name" in 65 FAILED) 66 false 67 return 68 ;; 69 LIVE) 70 true 71 return 72 ;; 73 *) 74 # unknown state 75 sleep 1 76 ;; 77 esac 78 done 79 } 80 81 _qmi_poll_sim_state() { 82 local name=$1 83 local timeout=$2 84 85 for _i in $(seq 1 "$timeout"); do 86 json_init 87 json_load "$(ubus call "uqmid.modem.$name" dump)" 88 json_get_var sim_state_name sim_state_name 89 case "$sim_state_name" in 90 IDLE|"WAIT UIM PRESENT"|GET_INFO) 91 # normal wait 92 sleep 1 93 ;; 94 READY) 95 true 96 return 97 ;; 98 CHV_PIN|CHV_PUK|FAILED) 99 false 100 return 101 ;; 102 *) 103 # unknown state 104 sleep 1 105 ;; 106 esac 107 done 108 } 109 110 proto_qmid_setup() { 111 local interface="$1" 112 local device apn 113 local $PROTO_DEFAULT_OPTIONS 114 local ip4table ip6table 115 local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6 116 117 json_get_vars device $PROTO_OPTIONS 118 json_get_vars ip4table ip6table $PROTO_DEFAULT_OPTIONS 119 120 [ "$timeout" = "" ] && timeout="10" 121 122 [ "$metric" = "" ] && metric="0" 123 124 [ -n "$ctl_device" ] && device=$ctl_device 125 126 _qdebug "Setting up interface $interface" 127 128 [ -n "$device" ] || { 129 _qdebug "No control device specified" 130 proto_notify_error "$interface" NO_DEVICE 131 proto_set_available "$interface" 132 return 1 133 } 134 135 [ -n "$delay" ] && sleep "$delay" 136 137 device="$(readlink -f "$device")" 138 [ -c "$device" ] || { 139 _qdebug "The specified control device does not exist" 140 proto_notify_error "$interface" NO_DEVICE 141 return 1 142 } 143 144 devname="$(basename "$device")" 145 devpath="$(readlink -f "/sys/class/usbmisc/$devname/device/")" 146 ifname="$( ls "$devpath"/net )" 147 [ -n "$ifname" ] || { 148 _qdebug "The interface could not be found." 149 proto_notify_error "$interface" NO_IFACE 150 return 1 151 } 152 153 # check if uqmi already knows the device 154 [ -z "$name" ] && name=$(_qmid_convert_devtoname "$device") 155 156 if [ -z "$name" ]; then 157 _qdebug "Name not set and can't derived from device $device." 158 proto_notify_error "$interface" NO_NAME 159 return 1 160 fi 161 162 if ! _qmi_ensure_device_present "$name" "$device"; then 163 # can't create a device 164 _qdebug "Can't ensure the device" 165 proto_notify_error "$interface" NO_IFACE_CREATABLE 166 return 1 167 fi 168 169 # pass configuration to it 170 ubus call "uqmid.modem.$name" configure "{'apn':'$apn', 'username': '$username', 'password': '$password', 'pin': '$pin', 'roaming':'$roaming'}" 171 172 _qmi_poll_sim_state "$name" 30 173 174 # check if simcard is fine 175 json_init 176 json_load "$(ubus call "uqmid.modem.$name" dump)" 177 json_get_var state_name state_name 178 json_get_var sim_state_name sim_state_name 179 # use simstate as human readable to have more stable "api" 180 181 case "$sim_state_name" in 182 IDLE | "WAIT UIM PRESENT" | GET_INFO) 183 _qdebug "SIM is still not ready after 30 seconds. Failing!" 184 proto_notify_error "$interface" SIM_NOT_READY 185 return 1 186 ;; 187 CHV_PIN) 188 # TODO add support for pincode/unlock 189 _qdebug "SIM REQUIRED PIN! Failing!" 190 proto_notify_error "$interface" SIM_PIN_REQUIRED 191 proto_block_restart "$interface" 192 return 1 193 ;; 194 CHV_PUK) 195 _qdebug "SIM REQUIRED PUK! Failing!" 196 proto_notify_error "$interface" SIM_PUK_REQUIRED 197 proto_block_restart "$interface" 198 return 1 199 ;; 200 READY) 201 # continue to process 202 _qdebug "SIM is READY" 203 ;; 204 FAILED) 205 _qdebug "SIM is in FAILED state. Failing!" 206 # blocked state 207 proto_notify_error "$interface" SIM_FAILED 208 proto_block_restart "$interface" 209 return 1 210 ;; 211 *) 212 _qdebug "UNKNOWN STATE $sim_state_name" 213 ubus call "uqmid.modem.$name" dump >> /tmp/qmi.log 214 # unknown sim state 215 proto_notify_error "$interface" SIM_STATE_UNKNOWN 216 return 1 217 ;; 218 esac 219 220 # poll here again for a state 221 # TODO: until it reaches LIVE or the FSM terminates in a failure mode 222 _qmi_poll_state "$name" 30 223 224 json_init 225 json_load "$(ubus call "uqmid.modem.$name" dump)" 226 json_get_var state_name state_name 227 case "$state_name" in 228 LIVE) 229 # found our correct state 230 ;; 231 *) 232 _qdebug "Modem $interface didn't entered LIVE. Instead modem is in state $state_name" 233 proto_notify_error "$interface" NOT_READY_YET 234 return 1 235 ;; 236 esac 237 238 json_get_var ipv4_addr ipv4_addr 239 json_get_var ipv4_netmask ipv4_netmask 240 json_get_var ipv4_gateway ipv4_gateway 241 json_get_var dns1 dns1 242 json_get_var dns2 dns2 243 244 proto_init_update "$ifname" 1 245 proto_set_keep 1 246 247 proto_add_ipv4_address "$ipv4_addr" "$ipv4_netmask" 248 proto_add_ipv4_route "$ipv4_gateway" "32" 249 [ "$defaultroute" = 0 ] || proto_add_ipv4_route "0.0.0.0" 0 "$gateway_4" 250 251 [ "$peerdns" = 0 ] || { 252 [ -n "$dns1" ] && proto_add_dns_server "$dns1" 253 [ -n "$dns2" ] && proto_add_dns_server "$dns2" 254 } 255 [ -n "$zone" ] && { 256 proto_add_data 257 json_add_string zone "$zone" 258 proto_close_data 259 } 260 proto_send_update "$interface" 261 262 ## state: 263 ## - last signal strength <- last, dump from internal state, not query it 264 ## - last network state 265 ## - 266 267 # TODO: check if SIM is initialized 268 # echo "SIM not initialized" 269 # proto_notify_error "$interface" SIM_NOT_INITIALIZED 270 # proto_block_restart "$interface" 271 # return 1 272 273 # Check if UIM application is stuck in illegal state 274 # TODO: proto_notify_error "$interface" NETWORK_REGISTRATION_FAILED 275 ## proto_init_update "$ifname" 1 276 ## proto_set_keep 1 277 ## proto_add_data 278 ## [ -n "$pdh_4" ] && { 279 ## json_add_string "cid_4" "$cid_4" 280 ## json_add_string "pdh_4" "$pdh_4" 281 ## } 282 ## [ -n "$pdh_6" ] && { 283 ## json_add_string "cid_6" "$cid_6" 284 ## json_add_string "pdh_6" "$pdh_6" 285 ## } 286 ## proto_close_data 287 ## proto_send_update "$interface" 288 289 # if [ -z "$dhcpv6" -o "$dhcpv6" = 0 ]; then 290 # json_load "$(uqmi -s -d $device -t 1000 --set-client-id wds,$cid_6 --get-current-settings)" 291 # json_select ipv6 292 # json_get_var ip_6 ip 293 # json_get_var gateway_6 gateway 294 # json_get_var dns1_6 dns1 295 # json_get_var dns2_6 dns2 296 # json_get_var ip_prefix_length ip-prefix-length 297 # 298 # proto_init_update "$ifname" 1 299 # proto_set_keep 1 300 # proto_add_ipv6_address "$ip_6" "128" 301 # proto_add_ipv6_prefix "${ip_6}/${ip_prefix_length}" 302 # proto_add_ipv6_route "$gateway_6" "128" 303 # [ "$defaultroute" = 0 ] || proto_add_ipv6_route "::0" 0 "$gateway_6" "" "" "${ip_6}/${ip_prefix_length}" 304 # [ "$peerdns" = 0 ] || { 305 # proto_add_dns_server "$dns1_6" 306 # proto_add_dns_server "$dns2_6" 307 # } 308 # [ -n "$zone" ] && { 309 # proto_add_data 310 # json_add_string zone "$zone" 311 # proto_close_data 312 # } 313 # proto_send_update "$interface" 314 # else 315 # json_init 316 # json_add_string name "${interface}_6" 317 # json_add_string ifname "@$interface" 318 # [ "$pdptype" = "ipv4v6" ] && json_add_string iface_464xlat "0" 319 # json_add_string proto "dhcpv6" 320 # [ -n "$ip6table" ] && json_add_string ip6table "$ip6table" 321 # proto_add_dynamic_defaults 322 # # RFC 7278: Extend an IPv6 /64 Prefix to LAN 323 # json_add_string extendprefix 1 324 # [ -n "$zone" ] && json_add_string zone "$zone" 325 # json_close_object 326 # ubus call network add_dynamic "$(json_dump)" 327 # fi 328 } 329 330 proto_qmid_teardown() { 331 local interface="$1" 332 local device 333 334 json_get_vars device 335 336 [ -n "$ctl_device" ] && device=$ctl_device 337 [ -z "$name" ] && name=$(_qmid_convert_devtoname "$device") 338 339 echo "Stopping network $interface" 340 341 ubus call uqmid remove_modem "{ 'name': '$name' }" 342 343 proto_init_update "*" 0 344 proto_send_update "$interface" 345 } 346 347 [ -n "$INCLUDE_ONLY" ] || { 348 add_protocol qmid 349 }
This page was automatically generated by LXR 0.3.1. • OpenWrt