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

Reply via email to