diff options
author | Felix Fietkau <nbd@openwrt.org> | 2014-05-28 19:45:20 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2014-05-28 19:45:20 +0000 |
commit | ae88b29aa635a48d4903622384a336232a86a3fe (patch) | |
tree | 6d72e67105925fb32927d956c31f58336191934b /package/network/utils/uqmi/files | |
parent | ece9382c46e80f0a7a497aecfb61ea6935fc76e5 (diff) | |
download | master-187ad058-ae88b29aa635a48d4903622384a336232a86a3fe.tar.gz master-187ad058-ae88b29aa635a48d4903622384a336232a86a3fe.tar.bz2 master-187ad058-ae88b29aa635a48d4903622384a336232a86a3fe.zip |
uqmi: Add support for QMI-based mobile broadband modems
Many of the 4G/LTE and 3G modems utilize the QMI-protocol to control the
modem. At the moment there is no support for them in OpenWrt. This
patch adds support for them in the form of a netifd script and a
control utility. Tested with Huawei E398 and ZTE MF820D (which requires
a delay of ~30 s before responding to QMI commands). I put myself up as
the maintainer, feel free to change this if you desire.
Signed-off-by: Matti Laakso <malaakso@elisanet.fi>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@40868 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/network/utils/uqmi/files')
-rwxr-xr-x | package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh new file mode 100755 index 0000000000..693fd6c115 --- /dev/null +++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh @@ -0,0 +1,137 @@ +#!/bin/sh + +. /lib/functions.sh +. ../netifd-proto.sh +init_proto "$@" + +proto_qmi_init_config() { + proto_config_add_string "device:device" + proto_config_add_string apn + proto_config_add_string auth + proto_config_add_string username + proto_config_add_string password + proto_config_add_string pincode + proto_config_add_string delay + proto_config_add_string modes +} + +proto_qmi_setup() { + local interface="$1" + + local device apn auth username password pincode delay modes cid pdh + json_get_vars device apn auth username password pincode delay modes + + [ -n "$device" ] || { + logger -p daemon.err -t "qmi[$$]" "No control device specified" + proto_notify_error "$interface" NO_DEVICE + proto_block_restart "$interface" + return 1 + } + [ -c "$device" ] || { + logger -p daemon.err -t "qmi[$$]" "The specified control device does not exist" + proto_notify_error "$interface" NO_DEVICE + proto_block_restart "$interface" + return 1 + } + + [ -n "$delay" ] && sleep "$delay" + + while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do + sleep 1; + done + + [ -n "$pincode" ] && { + uqmi -s -d "$device" --verify-pin1 "$pincode" || { + logger -p daemon.err -t "qmi[$$]" "Unable to verify PIN" + proto_notify_error "$interface" PIN_FAILED + proto_block_restart "$interface" + return 1 + } + } + + [ -n "$apn" ] || { + logger -p daemon.err -t "qmi[$$]" "No APN specified" + proto_notify_error "$interface" NO_APN + proto_block_restart "$interface" + return 1 + } + + logger -p daemon.info -t "qmi[$$]" "Waiting for network registration" + while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do + sleep 5; + done + + [ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes" + + logger -p daemon.info -t "qmi[$$]" "Starting network $apn" + cid=`uqmi -s -d "$device" --get-client-id wds` + [ $? -ne 0 ] && { + logger -p daemon.err -t "qmi[$$]" "Unable to obtain client ID" + proto_notify_error "$interface" NO_CID + proto_block_restart "$interface" + return 1 + } + uci_set_state network $interface cid "$cid" + + pdh=`uqmi -s -d "$device" --set-client-id wds,"$cid" --start-network "$apn" \ + ${auth:+--auth-type $auth} \ + ${username:+--username $username} \ + ${password:+--password $password}` + [ $? -ne 0 ] && { + logger -p daemon.err -t "qmi[$$]" "Unable to connect, check APN and authentication" + proto_notify_error "$interface" NO_PDH + proto_block_restart "$interface" + return 1 + } + uci_set_state network $interface pdh "$pdh" + + if ! uqmi -s -d "$device" --get-data-status | grep '"connected"' > /dev/null; then + logger -p daemon.err -t "qmi[$$]" "Connection lost" + proto_notify_error "$interface" NOT_CONNECTED + proto_block_restart "$interface" + return 1 + fi + + logger -p daemon.info -t "qmi[$$]" "Connected, starting DHCP" + proto_init_update "*" 1 + proto_send_update "$interface" + + json_init + json_add_string name "${interface}_dhcp" + json_add_string ifname "@$interface" + json_add_string proto "dhcp" + json_close_object + ubus call network add_dynamic "$(json_dump)" + + json_init + json_add_string name "${interface}_dhcpv6" + json_add_string ifname "@$interface" + json_add_string proto "dhcpv6" + json_close_object + ubus call network add_dynamic "$(json_dump)" +} + +proto_qmi_teardown() { + local interface="$1" + + local device + json_get_vars device + local cid=$(uci_get_state network $interface cid) + local pdh=$(uci_get_state network $interface pdh) + + logger -p daemon.info -t "qmi[$$]" "Stopping network" + [ -n "$cid" ] && { + [ -n "$pdh" ] && { + uqmi -s -d "$device" --set-client-id wds,"$cid" --stop-network "$pdh" + uci_revert_state network $interface pdh + } + uqmi -s -d "$device" --set-client-id wds,"$cid" --release-client-id wds + uci_revert_state network $interface cid + } + + proto_init_update "*" 0 + proto_send_update "$interface" +} + +add_protocol qmi + |