For me this NCM protocol has been "irreplaceable". It makes the LTE connection so much faster than "traditional" PPP link. So far I am using Oskari's NCM set at cabin's data, and more importantly at Vaasa Hacklab router. So far I haven't been able to spot any errors or misworkings in today's trunk openwrt #40863. Used general instructions from https://sites.google.com/site/variousopenwrt/huawei-e3267
+1 to this! Reviewed-by: Sami Olmari <s...@olmari.fi> Tested-by: Sami Olmari <s...@olmari.fi> Acked-by: Sami Olmari <s...@olmari.fi> On Thu, Nov 28, 2013 at 7:02 PM, Oskari Rauta <oskari.ra...@gmail.com> wrote: > >> Shouldn't the patch be splitted because of different features? >> ( luci, non-luci stuff, hardware (huawai config)) > > Here is version 2 of patch, that patches against packages and does not have > LuCI packages at all.. > > diff --git a/net/ncm/Makefile b/net/ncm/Makefile > new file mode 100644 > index 0000000..e4c5a85 > --- /dev/null > +++ b/net/ncm/Makefile > @@ -0,0 +1,94 @@ > +# > +# Copyright (C) 2007-2013 OpenWrt.org > +# Copyright (C) 2010 Vertical Communications > +# > +# This is free software, licensed under the GNU General Public License v2. > +# See /LICENSE for more information. > +# > + > +include $(TOPDIR)/rules.mk > + > +PKG_NAME:=ncm > +PKG_VERSION:=1.0 > +PKG_RELEASE:=1 > +PKG_MAINTAINER:=Oskari Rauta <oskari.ra...@gmail.com> > +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE) > + > +include $(INCLUDE_DIR)/package.mk > + > +define Package/ncm/Default > + VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) > + URL:=http://openwrt.org/ > + MAINTAINER:=Oskari Rauta <oskari.ra...@gmail.com> > +endef > + > +define Package/ncm > +$(call Package/ncm/Default) > + SECTION:=net > + CATEGORY:=Network > + TITLE:=Protocol support for NCM > + DEPENDS:=+comgt +kmod-usb-net-cdc-ncm +kmod-usb-serial > +endef > + > +define Package/ncm/description > + This package contains protocol support for NCM. > +endef > + > +define Package/ncm-huawei-e3276 > +$(call Package/ncm/Default) > + SECTION:=net > + CATEGORY:=Network > + TITLE:=Huawei E3276 support for NCM protocol > + DEPENDS:=+ncm +comgt +kmod-usb-serial > +endef > + > +define Package/ncm-huawei-e3276/description > + This package contains communication scripts for Huawei E3276 > +endef > + > +define Build/Prepare > + mkdir -p $(PKG_BUILD_DIR) > +endef > + > +define Build/Configure > +endef > + > +define Build/Compile/Default > +endef > + > +Build/Compile = $(Build/Compile/Default) > + > +define Package/ncm/install > + $(INSTALL_DIR) $(1)/lib > + $(INSTALL_DIR) $(1)/lib/netifd > + $(INSTALL_DIR) $(1)/lib/netifd/proto > + $(INSTALL_DIR) $(1)/etc > + $(INSTALL_DIR) $(1)/etc/gcom > + $(INSTALL_DIR) $(1)/etc/gcom/ncm > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/signal > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/carrier > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/setmode > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/connect > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/initscripts > + $(INSTALL_BIN) ./files/lib/netifd/proto/ncm.sh $(1)/lib/netifd/proto/ > + $(INSTALL_DATA) ./files/etc/gcom/ncm/getcardinfo.gcom > $(1)/etc/gcom/ncm/ > +endef > + > +define Package/ncm-huawei-e3276/install > + $(INSTALL_DIR) $(1)/etc > + $(INSTALL_DIR) $(1)/etc/gcom > + $(INSTALL_DIR) $(1)/etc/gcom/ncm > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/signal > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/carrier > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/setmode > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/connect > + $(INSTALL_DIR) $(1)/etc/gcom/ncm/initscripts > + $(INSTALL_DATA) ./files/etc/gcom/ncm/signal/huawei_e3276.gcom > $(1)/etc/gcom/ncm/signal/ > + $(INSTALL_DATA) ./files/etc/gcom/ncm/carrier/huawei_e3276.gcom > $(1)/etc/gcom/ncm/carrier/ > + $(INSTALL_DATA) ./files/etc/gcom/ncm/setmode/huawei_e3276.gcom > $(1)/etc/gcom/ncm/setmode/ > + $(INSTALL_DATA) ./files/etc/gcom/ncm/connect/huawei_e3276.gcom > $(1)/etc/gcom/ncm/connect/ > + $(INSTALL_DATA) ./files/etc/gcom/ncm/initscripts/huawei_e3276.gcom > $(1)/etc/gcom/ncm/initscripts/ > +endef > + > +$(eval $(call BuildPackage,ncm)) > +$(eval $(call BuildPackage,ncm-huawei-e3276)) > diff --git a/net/ncm/files/etc/gcom/ncm/carrier/huawei_e3276.gcom > b/net/ncm/files/etc/gcom/ncm/carrier/huawei_e3276.gcom > new file mode 100644 > index 0000000..58684fd > --- /dev/null > +++ b/net/ncm/files/etc/gcom/ncm/carrier/huawei_e3276.gcom > @@ -0,0 +1,56 @@ > +opengt > +set com 115200n81 > +set comecho off > +set senddelay 0.02 > +waitquiet 0.2 0.2 > +flash 0.1 > + > +:getprovider > + send "AT+COPS?^m" > + let $r="+COPS:" > + gosub readresult > + system "echo \""+$x+"\" | awk -F\"[:,]\" '{print \"provider \\x27\" $4 > \"\\x27\"}'" > + > +:getmode > + send "AT^^SYSCFGEX?^m" > + let $r="^^SYSCFGEX:" > + gosub readresult > + system "echo \""+$x+"\" | awk -F\"[:,]\" '{ \\ > + if ( $2 == \"01\" ) print \"mode \\x27\" \"2G\\x27\"; \\ > + else if ( $2 == \"02\" ) print \"mode \\x27\" \"3G\\x27\"; \\ > + else if ( $2 == \"03\" ) print \"mode \\x27\" \"LTE\\x27\"; \\ > + else if ( $2 == \"0201\" ) print \"mode \\x27\" \"3G > Preferred\\x27\"; \\ > + else if ( $2 == \"030201\" ) print \"mode \\x27\" \"LTE > Preferred\\x27\"; \\ > + else if (( $2 == \"00\" ) or ( $2 == \"0\" )) print \"mode \\x27\" > \"Automatic/Any\\x27\"; \\ > + else print \"mode \\x27\" \"Unknown\\x27\";}'" > + > +:getrate > + send "AT+CGEQNEG=1^m" > + let $r="+CGEQNEG:" > + gosub readresult > + system "echo \""+$x+"\" | awk -F\"[:,]\" '{ print \"downlink \\x27\" > int($5) \"kbps\\x27\"; print \"uplink \\x27\" int($4) \"kbps\\x27\"; }'" > + goto done > + > +:readresult > + let i=5 > + let $x="" > +:loop > + get 1 "^m" $s > + let l=len($r) > + if len($s) < l goto loop1 > + if $mid($s,1,l) <> $r goto loop1 > + let $x=$mid($s,1,len($s)-1) > + return > +:loop1 > + if len($s) < 2 goto loop2 > + if $mid($s,1,2) = "ER" return > + if $mid($s,1,2) = "CO" return > +:loop2 > + if i = 0 return > + let i=i-1 > + sleep 0.25 > + goto loop > + > +:done > + exit 0 > +^@^@ > diff --git a/net/ncm/files/etc/gcom/ncm/connect/huawei_e3276.gcom > b/net/ncm/files/etc/gcom/ncm/connect/huawei_e3276.gcom > new file mode 100644 > index 0000000..d7a604c > --- /dev/null > +++ b/net/ncm/files/etc/gcom/ncm/connect/huawei_e3276.gcom > @@ -0,0 +1,63 @@ > +opengt > +set com 115200n81 > +set comecho off > +set senddelay 0.05 > +waitquiet 1 0.2 > + > +:start > + if $env("USE_DISCONNECT")="1" goto disconnect > + send "AT^^NDISDUP=1,1,\"" > + send $env("USE_APN") > + > + if $env("USE_AUTHTYPE")="-1" goto noauth > + else goto auth > + > +:noauth > + send "\"^m" > + goto result > + > +:auth > + send "\",\"" > + send $env("USE_USERID") > + send "\",\"" > + send $env("USE_PASSWORD") > + send "\"," > + send $env("USE_AUTHTYPE") > + send "^m" > + goto result > + > +:result > + waitfor 5 "OK","ERR","ERROR" > + if % = 0 goto connok > + if % = 1 goto connerr > + if % = 2 goto connerr > + > +:connok > + print "WWAN connection established.\r\n" > + goto done > + > +:connerr > + print "WWAN error. Connection failed.\r\n" > + exit 1 > + > +:disconnect > + send "AT^^NDISDUP=1,0,\"" > + send $env("USE_APN") > + send "\"^m" > + > + waitfor 5 "OK","ERR","ERROR" > + if % = 0 goto disconnok > + if % = 1 goto disconnerr > + if % = 2 goto disconnerr > + > +:disconnok > + print "WWAN connection disconnected.\r\n" > + goto done > + > +:disconnerr > + print "WWAN disconnection error.\r\n" > + exit 1 > + > +:done > + exit 0 > +^@^@ > diff --git a/net/ncm/files/etc/gcom/ncm/getcardinfo.gcom > b/net/ncm/files/etc/gcom/ncm/getcardinfo.gcom > new file mode 100644 > index 0000000..79bea16 > --- /dev/null > +++ b/net/ncm/files/etc/gcom/ncm/getcardinfo.gcom > @@ -0,0 +1,38 @@ > +opengt > + set com 115200n81 > + set comecho on > + set senddelay 0.02 > + waitquiet 0.2 0.2 > + flash 0.1 > + > +:start > + let i=0 > + > +:waitfordevice > + waitquiet 2 0.5 > + inc i > + send "AT^m" > + waitfor 4 "OK","ERR","ERROR" > + if % = 0 goto detect > + if i < 5 goto waitfordevice > + print "Error: Dongle not responding." > + exit 1 > + > +:detect > + send "ATI^m" > + waitfor 1 "ATI^m" > + get 1 "OK" $s > + > +:output > + system "echo \""+$s+"\" | grep \"Manufacturer:\" | awk '{print \"vendor > \\x27\" $2 \"\\x27\"; }'" > + system "echo \""+$s+"\" | grep \"Model:\" | awk '{print \"model \\x27\" $2 > \"\\x27\"; }'" > + system "echo \""+$s+"\" | grep \"Revision:\" | awk '{print \"firmware > \\x27\" $2 \"\\x27\"; }'" > + system "echo \""+$s+"\" | grep \"IMEI:\" | awk '{print \"imei \\x27\" $2 > \"\\x27\"; }'" > + system "echo \""+$s+"\" | egrep -i '^^Manufacturer|^^Model' | cut -d ' ' -f > 2 | tr -d '\r' | tr '\n' '_' | sed \"s/\\(.*\\)_$/\\'\\1\\'\\n/\" | awk '{ > gsub(\"\\x27\", \"\"); \\ > + if ( $1 == \"huawei_E3276\" ) print \"driver > \\x27huawei_e3276\\x27\"; \\ > + else print \"driver \\x27-\\x27\";}'" > + > + goto continue > + > +:continue > + exit 0 > diff --git a/net/ncm/files/etc/gcom/ncm/initscripts/huawei_e3276.gcom > b/net/ncm/files/etc/gcom/ncm/initscripts/huawei_e3276.gcom > new file mode 100644 > index 0000000..7d60abd > --- /dev/null > +++ b/net/ncm/files/etc/gcom/ncm/initscripts/huawei_e3276.gcom > @@ -0,0 +1,31 @@ > +opengt > +set com 115200n81 > +set comecho off > +set senddelay 0.02 > +waitquiet 0.2 0.2 > +flash 0.1 > + > +:start > + send "AT^m" > + waitfor 4 "OK","ERR","ERROR" > + if % = 1 goto initerror > + if % = 2 goto initerror > + > + send "ATZ^m" > + waitfor 4 "OK","ERR","ERROR" > + if % = 1 goto initerror > + if % = 2 goto initerror > + > + send "ATQ V1 E1 S0=0^m" > + waitfor 4 "OK","ERR","ERROR" > + if % = 0 goto continue > + if % = 1 goto initerror > + if % = 2 goto initerror > + > +:modeerror > + print "Error while initializing dongle.\n" > + exit 1 > + > +:continue > + print "Dongle initialization complete.\n" > + exit 0 > diff --git a/net/ncm/files/etc/gcom/ncm/setmode/huawei_e3276.gcom > b/net/ncm/files/etc/gcom/ncm/setmode/huawei_e3276.gcom > new file mode 100644 > index 0000000..275cca4 > --- /dev/null > +++ b/net/ncm/files/etc/gcom/ncm/setmode/huawei_e3276.gcom > @@ -0,0 +1,56 @@ > +# set wwan mode from environment > +opengt > + set com 115200n81 > + set senddelay 0.02 > + waitquiet 1 0.2 > + flash 0.1 > + > +:start > + if $env("MODE")="2g" goto 2g > + if $env("MODE")="3g" goto 3g > + if $env("MODE")="lte" goto lte > + if $env("MODE")="prefer3g" goto prefer3g > + if $env("MODE")="preferlte" goto preferlte > + goto auto > + > +:auto > + send "AT^^SYSCFGEX=\"00\",3FFFFFFF,2,4,7FFFFFFFFFFFFFFF,,^m" > + goto result > + > +:2g > + send "AT^^SYSCFGEX=\"01\",3FFFFFFF,2,4,7FFFFFFFFFFFFFFF,,^m" > + goto result > + > +:3g > + send "AT^^SYSCFGEX=\"02\",3FFFFFFF,2,4,7FFFFFFFFFFFFFFF,,^m" > + goto result > + > +:lte > + send "AT^^SYSCFGEX=\"03\",3FFFFFFF,2,4,7FFFFFFFFFFFFFFF,,^m" > + goto result > + > +:prefer3g > + send "AT^^SYSCFGEX=\"0201\",3FFFFFFF,2,4,7FFFFFFFFFFFFFFF,,^m" > + goto result > + > +:preferlte > + send "AT^^SYSCFGEX=\"030201\",3FFFFFFF,2,4,7FFFFFFFFFFFFFFF,,^m" > + goto result > + > +:result > + waitfor 8 "OK","ERR","ERROR" > + if % = 0 goto continue > + if % = 1 goto modeerror > + if % = 2 goto modeerror > + print "Timeout setting WWAN mode!\n" > + exit 1 > + > +:modeerror > + print "Error setting WWAN mode!\n" > + exit 1 > + > +:continue > + print "WWAN mode set to '" > + print $env("MODE") > + print "'\r\n" > + exit 0 > diff --git a/net/ncm/files/etc/gcom/ncm/signal/huawei_e3276.gcom > b/net/ncm/files/etc/gcom/ncm/signal/huawei_e3276.gcom > new file mode 100644 > index 0000000..a2ddb61 > --- /dev/null > +++ b/net/ncm/files/etc/gcom/ncm/signal/huawei_e3276.gcom > @@ -0,0 +1,61 @@ > +opengt > +set com 115200n81 > +set comecho off > +set senddelay 0.02 > +waitquiet 0.2 0.2 > +flash 0.1 > + > +:getcell > + send "AT+CREG=2^m" > + let $r="OK" > + gosub readresult > + if $r <> $x goto getnetwork > + > + send "AT+CREG?^m" > + let $r="+CREG:" > + gosub readresult > + system "echo \""+$x+"\" | awk -F\"[:,]\" '{print \"cellid \\x27\" \"0x\" $5 > \" (\" (\"0x\"$5)+0 \")\\x27\"; print \"lac \\x27\" \"0x\" $4 \" (\" > (\"0x\"$4)+0 \")\\x27\";}'" > + > +:getnetwork > + send "AT^^SYSINFOEX^m" > + let $r="^^SYSINFOEX:" > + gosub readresult > + system "echo \""+$x+"\" | awk -F\"[:,]\" '{print \"network \\x27\" $8 \" / > \" $10 \"\\x27\";}'" > + > +:getsignalstrength > + send "AT+CSQ^m" > + let $r="+CSQ:" > + gosub readresult > + system "echo \""+$x+"\" | awk -F\"[:,]\" '{ print \"signal \\x27\" int(($2 > * 100 / 31)+0.5) \"%\\x27\"; print \"rssi \\x27\" int(2 * $2 - 113) > \"dBm\\x27\"; print \"csq \\x27\" int($2) \"\\x27\"; }'" > + > +:getnoicelevels > + send "AT^^CSNR?^m" > + let $r="^^CSNR:" > + gosub readresult > + system "echo \""+$x+"\" | awk -F\"[:,]\" '{ print \"rcsp \\x27\" int($2) > \"dBm\\x27\"; print \"ecio \\x27\" int($3) \"dB\\x27\";}'" > + > + goto done > + > +:readresult > + let i=5 > + let $x="" > +:loop > + get 1 "^m" $s > + let l=len($r) > + if len($s) < l goto loop1 > + if $mid($s,1,l) <> $r goto loop1 > + let $x=$mid($s,1,len($s)-1) > + return > +:loop1 > + if len($s) < 2 goto loop2 > + if $mid($s,1,2) = "ER" return > + if $mid($s,1,2) = "CO" return > +:loop2 > + if i = 0 return > + let i=i-1 > + sleep 0.25 > + goto loop > + > +:done > + exit 0 > +^@^@ > diff --git a/net/ncm/files/lib/netifd/proto/ncm.sh > b/net/ncm/files/lib/netifd/proto/ncm.sh > new file mode 100755 > index 0000000..9d9f98d > --- /dev/null > +++ b/net/ncm/files/lib/netifd/proto/ncm.sh > @@ -0,0 +1,137 @@ > +#!/bin/sh > + > +. /lib/functions.sh > +. ../netifd-proto.sh > +init_proto "$@" > + > +proto_ncm_init_config() { > + proto_config_add_string "device" > + proto_config_add_string "mode" > + proto_config_add_string "apn" > + proto_config_add_string "pincode" > + proto_config_add_string "authtype" > + proto_config_add_string "delay" > + proto_config_add_string "username" > + proto_config_add_string "password" > + proto_config_add_string "ipaddr" > + proto_config_add_string "netmask" > + proto_config_add_string "hostname" > + proto_config_add_string "clientid" > + proto_config_add_string "vendorid" > + proto_config_add_boolean "broadcast" > + proto_config_add_string "reqopts" > + proto_config_add_string "iface6rd" > + proto_config_add_string "sendopts" > +} > + > +proto_ncm_setup() { > + local config="$1" > + local iface="$2" > + > + local device mode apn pincode authtype delay username password > + local ipaddr hostname clientid vendorid broadcast reqopts iface6rd > sendopts > + local cardinfo brand model driver > + local dialupscript modescript initscript > + > + json_get_vars device mode apn pincode delay authtype username password > + json_get_vars ipaddr hostname clientid vendorid broadcast reqopts > iface6rd sendopts > + > + [ -e "$device" ] || { > + proto_set_available "$interface" 0 > + return 1 > + } > + > + cardinfo=$(gcom -d "$device" -s /etc/gcom/ncm/getcardinfo.gcom) > + brand=$(echo "$cardinfo" | grep "vendor '" | awk '{ gsub("\x27", ""); > print $2; }') > + model=$(echo "$cardinfo" | grep "model '" | awk '{ gsub("\x27", ""); > print $2; }') > + driver=$(echo "$cardinfo" | grep "driver '" | awk '{ gsub("\x27", > ""); print $2; }') > + > + [ "$driver" = "-" ] && { > + logger Detected $brand $model. Device is not supported. > + proto_notify_error "$interface" UNSUPPORTED_DEVICE > + proto_block_restart "$interface" > + return 1 > + } > + > + initscript="/etc/gcom/ncm/initscripts/$driver.gcom" > + modescript="/etc/gcom/ncm/setmode/$driver.gcom" > + dialupscript="/etc/gcom/ncm/connect/$driver.gcom" > + > + logger Detected $brand $model. Using driver $driver. > + > + if [ -n "$pincode" ]; then > + PINCODE="$pincode" gcom -d "$device" -s /etc/gcom/setpin.gcom > || { > + proto_notify_error "$interface" PIN_FAILED > + proto_block_restart "$interface" > + return 1 > + } > + fi > + > + [ -e "$initscript" ] && > + gcom -d "$device" -s "$initscript" > + > + [ "$authtype" = "pap" ] && authtype=1 || { > + [ "$authtype" = "chap" ] && authtype=2 || { > + [ "$authtype" = "cleartext" ] && authtype=0 || > + authtype=-1 > + } > + } > + > + [ -e "$modescript" ] && > + MODE="$mode" gcom -d "$device" -s "$modescript" > + > + [ -e "$dialupscript" ] || { > + logger Dial-up script for driver $driver is missing. > + proto_notify_error "$interface" SCRIPT_MISSING > + proto_block_restart "$interface" > + return 1 > + } > + > + USE_DISCONNECT="0" USE_APN="$apn" USE_AUTHTYPE="$authtype" > USE_USERID="$username" USE_PASSWORD="$password" \ > + gcom -d "$device" -s "$dialupscript" > + > + [ ! -z "${delay##*[!0-9]*}" ] && [ "$delay" != "0" ] && /bin/sleep > $delay > + > + local opt dhcpopts > + for opt in $reqopts; do > + append dhcpopts "-O $opt" > + done > + > + for opt in $sendopts; do > + append dhcpopts "-x $opt" > + done > + > + [ "$broadcast" = 1 ] && broadcast="-B" || broadcast= > + [ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}" || > clientid="-C" > + [ -n "$iface6rd" ] && proto_export "IFACE6RD=$iface6rd" > + > + proto_export "INTERFACE=$config" > + proto_run_command "$config" udhcpc \ > + -p /var/run/udhcpc-$iface.pid \ > + -s /lib/netifd/dhcp.script \ > + -f -t 0 -i "$iface" \ > + ${ipaddr:+-r $ipaddr} \ > + ${hostname:+-H $hostname} \ > + ${vendorid:+-V $vendorid} \ > + $clientid $broadcast $dhcpopts > +} > + > +proto_ncm_teardown() { > + local interface="$1" > + local device apn cardinfo driver dialupscript > + > + json_get_vars device apn > + > + cardinfo=$(gcom -d "$device" -s /etc/gcom/ncm/getcardinfo.gcom) > + driver=$(echo "$cardinfo" | grep "driver '" | awk '{ gsub("\x27", > ""); print $2; }') > + dialupscript="/etc/gcom/ncm/connect/$driver.gcom" > + > + [ "$driver" == "-" ] || > + [ -e "$device" ] && > + [ -e "$dialupscript" ] && > + USE_DISCONNECT="1" USE_APN="$apn" gcom -d > "$device" -s "$dialupscript" > + > + proto_kill_command "$interface" > +} > + > +add_protocol ncm > _______________________________________________ > openwrt-devel mailing list > openwrt-devel@lists.openwrt.org > https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel