From ae88b29aa635a48d4903622384a336232a86a3fe Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 28 May 2014 19:45:20 +0000 Subject: 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 git-svn-id: svn://svn.openwrt.org/openwrt/trunk@40868 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../utils/uqmi/files/lib/netifd/proto/qmi.sh | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100755 package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh (limited to 'package/network/utils/uqmi/files/lib/netifd/proto') 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 + -- cgit v1.2.3