I wanted to get an LTE dongle which uses the QMI protocol working in my router, but didn't have enough space for libqmi. Luckily, Felix had developed uqmi [1], which turned out to work nicely. I made a protocol script for netifd, and some other changes, which you see below.
Now my questions: - Is there a reason why uqmi has not been packaged yet? - Is the QMI protocol documentation available somewhere (except the JSON files at [1])? I'm particularly confused about when to get, set, keep, and release client ID's. My dongle doesn't seem to require a client ID except for starting and stopping the connection. Is this different for other dongles? - What is the best way to include IPv6 support? Can I just use wan6 with ifname @wan and proto dhcpv6, or do I need to somehow tell wan6 to wait until wan is up? - Comments on the patch below? Here's an example config: network.wan=interface network.wan.device=/dev/cdc-wdm0 network.wan.pincode=0000 network.wan.apn=internet network.wan.proto=qmi network.wan.ifname=wwan0 [1] http://nbd.name/gitweb.cgi?p=uqmi.git;a=summary -- Index: trunk/package/network/utils/uqmi/Makefile =================================================================== --- trunk/package/network/utils/uqmi/Makefile (revision 0) +++ trunk/package/network/utils/uqmi/Makefile (working copy) @@ -0,0 +1,43 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=uqmi +PKG_VERSION:=2013-06-23 +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://nbd.name/uqmi.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=35201737484008ac802649cbe9fb5f7ab38a4ad2 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MAINTAINER:=Felix Fietkau <n...@openwrt.org> +# PKG_MIRROR_MD5SUM:= +# CMAKE_INSTALL:=1 + +PKG_LICENSE:=GPLv2 +PKG_LICENSE_FILES:= + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/uqmi + SECTION:=base + CATEGORY:=Base system + DEPENDS:=+libuci +libubus +ubus +ubusd +jshn +libubox + TITLE:=uQMI +endef + +TARGET_CFLAGS += \ + -I$(STAGING_DIR)/usr/include + +CMAKE_OPTIONS += \ + -DDEBUG=1 + +define Package/uqmi/install + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/uqmi $(1)/sbin/ + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,uqmi)) Index: trunk/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh =================================================================== --- trunk/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh (revision 0) +++ trunk/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh (working copy) @@ -0,0 +1,98 @@ +#!/bin/sh +INCLUDE_ONLY=1 + +. /lib/functions.sh +. ../netifd-proto.sh +. ./dhcp.sh +init_proto "$@" + +proto_qmi_init_config() { + proto_dhcp_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_qmi_setup() { + local interface="$1" + + local device apn auth username password pincode cid pdh + json_get_vars device apn auth username password pincode + + [ -n "$device" ] || { + proto_notify_error "$interface" NO_DEVICE + proto_block_restart "$interface" + return 1 + } + [ -c "$device" ] || { + proto_notify_error "$interface" NO_DEVICE + proto_block_restart "$interface" + return 1 + } + + 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" || { + proto_notify_error "$interface" PIN_FAILED + proto_block_restart "$interface" + return 1 + } + } + + [ -n "$apn" ] || { + proto_notify_error "$interface" NO_APN + proto_block_restart "$interface" + return 1 + } + + while ! uqmi -s -d "$device" --get-serving-system | grep '"registered"' > /dev/null; do + sleep 1; + done + + cid=`uqmi -s -d "$device" --get-client-id wds` + pdh=`uqmi -s -d "$device" --set-client-id wds,"$cid" --start-network "$apn" \ + ${auth:+--auth-type $auth} \ + ${username:+--username $username} \ + ${password:+--password $password}` + + uci_set_state network $interface cid "$cid" + uci_set_state network $interface pdh "$pdh" + + while ! uqmi -s -d "$device" --get-data-status | grep '"connected"' > /dev/null; do + sleep 1; + done + + proto_dhcp_setup "$@" +} + +proto_qmi_renew() { + proto_dhcp_renew "$@" +} + +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) + + [ -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_kill_command "$interface" +} + +add_protocol qmi + Index: trunk/package/network/utils/uqmi/patches/001-stop-network.patch =================================================================== --- trunk/package/network/utils/uqmi/patches/001-stop-network.patch (revision 0) +++ trunk/package/network/utils/uqmi/patches/001-stop-network.patch (working copy) @@ -0,0 +1,46 @@ +--- a/commands-wds.c ++++ b/commands-wds.c +@@ -1,3 +1,5 @@ ++#include <stdlib.h> ++ + #include "qmi-message.h" + + static struct qmi_wds_start_network_request wds_sn_req = { +@@ -74,6 +76,20 @@ cmd_wds_start_network_prepare(struct qmi + return QMI_CMD_REQUEST; + } + ++#define cmd_wds_stop_network_cb no_cb ++static enum qmi_cmd_result ++cmd_wds_stop_network_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) ++{ ++ int pdh = strtoul(arg, NULL, 0); ++ ++ static struct qmi_wds_stop_network_request sreq = { ++ QMI_INIT(packet_data_handle, 0), ++ }; ++ qmi_set(&sreq, packet_data_handle, pdh); ++ qmi_set_wds_stop_network_request(msg, &sreq); ++ return QMI_CMD_REQUEST; ++} ++ + static void + cmd_wds_get_packet_service_status_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) + { +--- a/commands-wds.h ++++ b/commands-wds.h +@@ -4,6 +4,7 @@ + __uqmi_command(wds_set_username, username, required, CMD_TYPE_OPTION), \ + __uqmi_command(wds_set_password, password, required, CMD_TYPE_OPTION), \ + __uqmi_command(wds_set_autoconnect, autoconnect, no, CMD_TYPE_OPTION), \ ++ __uqmi_command(wds_stop_network, stop-network, required, QMI_SERVICE_WDS), \ + __uqmi_command(wds_get_packet_service_status, get-data-status, no, QMI_SERVICE_WDS), \ + __uqmi_command(wds_reset, reset-wds, no, QMI_SERVICE_WDS) \ + +@@ -14,5 +15,6 @@ + " --username <name>: Use network username\n" \ + " --password <password>: Use network password\n" \ + " --autconnect: Enable automatic connect/reconnect\n" \ ++ " --stop-network <pdh>: Stop network connection\n" \ + " --get-data-status: Get current data access status\n" \ + Index: trunk/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh =================================================================== --- trunk/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh (revision 40526) +++ trunk/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh (working copy) @@ -1,8 +1,10 @@ #!/bin/sh -. /lib/functions.sh -. ../netifd-proto.sh -init_proto "$@" +[ -n "$INCLUDE_ONLY" ] || { + . /lib/functions.sh + . ../netifd-proto.sh + init_proto "$@" +} proto_dhcp_init_config() { renew_handler=1 @@ -65,5 +67,7 @@ proto_kill_command "$interface" } -add_protocol dhcp +[ -n "$INCLUDE_ONLY" ] || { + add_protocol dhcp +} _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel