This patch adds more user friendly support for 3g/lte modems using NCM network 
interface. This work I did, can easily be ported to variants like QMI, etc..
This adds support to /etc/config/network so one can define there usage of a 
such dongle, and then WAN connection can be automaticly established without 
hacky scripts.
This patch also creates 3 other packages than just basic support for NCM:
 1) support for Huawei E3672 dongle (initially no other dongles supported)
 2) ncm protocol support for luci. Easy/simple/fast to set up in LuCI.
 3) status page for luci reporting dongles: hardware, carrier, cell and signal.

Better description and screenshots from LuCI from this forum post: 
https://forum.openwrt.org/viewtopic.php?pid=218745#p218745

Signed-off-by: Oskari Rauta <oskari.ra...@gmail.com>

Patch starts:

diff --git a/package/network/services/ncm/Makefile 
b/package/network/services/ncm/Makefile
new file mode 100644
index 0000000..a37e3ed
--- /dev/null
+++ b/package/network/services/ncm/Makefile
@@ -0,0 +1,151 @@
+#
+# 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:=+netifd +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 Package/luci-proto-ncm
+$(call Package/ncm/Default)
+  SECTION:=luci
+  CATEGORY:=LuCI
+  SUBMENU:=6. Protocols
+  TITLE:=Support for NCM
+  DEPENDS:=+ncm
+endef
+
+define Package/luci-proto-ncm/description
+ This package contains LuCI support for NCM
+endef
+
+define Package/luci-mod-ncm-status
+$(call Package/ncm/Default)
+  SECTION:=luci
+  CATEGORY:=LuCI
+  SUBMENU:=2. Modules
+  TITLE:=LuCI NCM Status Module
+  DEPENDS:=+luci-mod-admin-core +ncm +comgt +kmod-usb-serial
+endef
+
+define Package/luci-mod-ncm-status/description
+ LuCI NCM Status Module
+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
+
+define Package/luci-proto-ncm/install
+       $(INSTALL_DIR) $(1)/usr
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/usr/lib/lua
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/network
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/admin_network
+       $(INSTALL_DATA) ./files/usr/lib/lua/luci/model/network/proto_ncm.lua 
$(1)/usr/lib/lua/luci/model/network/
+       $(INSTALL_DATA) 
./files/usr/lib/lua/luci/model/cbi/admin_network/proto_ncm.lua 
$(1)/usr/lib/lua/luci/model/cbi/admin_network/
+endef
+
+define Package/luci-mod-ncm-status/install
+       $(INSTALL_DIR) $(1)/usr
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/usr/lib/lua
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/view
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/ncm
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
+       $(INSTALL_DIR) $(1)/www
+       $(INSTALL_DIR) $(1)/www/luci-static
+       $(INSTALL_DIR) $(1)/www/luci-static/resources
+       $(INSTALL_DATA) ./files/usr/lib/lua/luci/view/ncm/status.htm 
$(1)/usr/lib/lua/luci/view/ncm/
+       $(INSTALL_DATA) ./files/usr/lib/lua/luci/controller/ncmstatus.lua 
$(1)/usr/lib/lua/luci/controller/
+       $(INSTALL_DATA) ./files/www/luci-static/resources/ncm_xhr.js 
$(1)/www/luci-static/resources/
+endef
+
+$(eval $(call BuildPackage,ncm))
+$(eval $(call BuildPackage,ncm-huawei-e3276))
+$(eval $(call BuildPackage,luci-proto-ncm))
+$(eval $(call BuildPackage,luci-mod-ncm-status))
diff --git 
a/package/network/services/ncm/files/etc/gcom/ncm/carrier/huawei_e3276.gcom 
b/package/network/services/ncm/files/etc/gcom/ncm/carrier/huawei_e3276.gcom
new file mode 100644
index 0000000..58684fd
--- /dev/null
+++ b/package/network/services/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/package/network/services/ncm/files/etc/gcom/ncm/connect/huawei_e3276.gcom 
b/package/network/services/ncm/files/etc/gcom/ncm/connect/huawei_e3276.gcom
new file mode 100644
index 0000000..d7a604c
--- /dev/null
+++ b/package/network/services/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/package/network/services/ncm/files/etc/gcom/ncm/getcardinfo.gcom 
b/package/network/services/ncm/files/etc/gcom/ncm/getcardinfo.gcom
new file mode 100644
index 0000000..79bea16
--- /dev/null
+++ b/package/network/services/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/package/network/services/ncm/files/etc/gcom/ncm/initscripts/huawei_e3276.gcom 
b/package/network/services/ncm/files/etc/gcom/ncm/initscripts/huawei_e3276.gcom
new file mode 100644
index 0000000..7d60abd
--- /dev/null
+++ 
b/package/network/services/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/package/network/services/ncm/files/etc/gcom/ncm/setmode/huawei_e3276.gcom 
b/package/network/services/ncm/files/etc/gcom/ncm/setmode/huawei_e3276.gcom
new file mode 100644
index 0000000..275cca4
--- /dev/null
+++ b/package/network/services/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/package/network/services/ncm/files/etc/gcom/ncm/signal/huawei_e3276.gcom 
b/package/network/services/ncm/files/etc/gcom/ncm/signal/huawei_e3276.gcom
new file mode 100644
index 0000000..a2ddb61
--- /dev/null
+++ b/package/network/services/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/package/network/services/ncm/files/lib/netifd/proto/ncm.sh 
b/package/network/services/ncm/files/lib/netifd/proto/ncm.sh
new file mode 100755
index 0000000..62b00b8
--- /dev/null
+++ b/package/network/services/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
diff --git 
a/package/network/services/ncm/files/usr/lib/lua/luci/controller/ncmstatus.lua 
b/package/network/services/ncm/files/usr/lib/lua/luci/controller/ncmstatus.lua
new file mode 100755
index 0000000..cfb6b20
--- /dev/null
+++ 
b/package/network/services/ncm/files/usr/lib/lua/luci/controller/ncmstatus.lua
@@ -0,0 +1,8 @@
+module("luci.controller.ncmstatus", package.seeall)
+
+function index()
+       local page
+
+       page = entry({"admin", "status", "ncm"}, template("ncm/status"), _("Ncm 
status"))
+       page.dependent = true
+end
diff --git 
a/package/network/services/ncm/files/usr/lib/lua/luci/model/cbi/admin_network/proto_ncm.lua
 
b/package/network/services/ncm/files/usr/lib/lua/luci/model/cbi/admin_network/proto_ncm.lua
new file mode 100644
index 0000000..dfaa02e
--- /dev/null
+++ 
b/package/network/services/ncm/files/usr/lib/lua/luci/model/cbi/admin_network/proto_ncm.lua
@@ -0,0 +1,120 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright 2011 Jo-Philipp Wich <x...@subsignal.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+]]--
+
+local map, section, net = ...
+
+local device, apn, mode, pincode, authtype, username, password
+local delay, bcast, defaultroute, peerdns, dns, metric, clientid, vendorclass
+
+
+device = section:taboption("general", Value, "device", translate("Modem 
device"))
+device.rmempty = false
+
+local device_suggestions = nixio.fs.glob("/dev/tty[A-Z]*")
+       or nixio.fs.glob("/dev/tts/*")
+
+if device_suggestions then
+       local node
+       for node in device_suggestions do
+               device:value(node)
+       end
+end
+
+mode = section:taboption("general", ListValue, "mode", translate("Service 
mode"))
+mode:value("2g", translate("2G only"))
+mode:value("3g", translate("3G only"))
+mode:value("lte", translate("LTE only"))
+mode:value("prefer3g", translate("Prefer 3G"))
+mode:value("preferlte", translate("Prefer LTE"))
+mode:value("auto", translate("Automatic / Any"))
+mode.rmempty = false
+mode.default = "auto"
+
+
+apn = section:taboption("general", Value, "apn", translate("APN"))
+
+
+pincode = section:taboption("general", Value, "pincode", translate("PIN"))
+
+
+authtype = section:taboption("general", ListValue, "authtype", 
translate("Authentication type"))
+authtype:value("none", translate("None"))
+authtype:value("cleartext", translate("Clear text"))
+authtype:value("pap", translate("PAP"))
+authtype:value("chap", translate("CHAP"))
+authtype.rmempty = false
+authtype.default = "none"
+
+
+username = section:taboption("general", Value, "username", translate("PAP/CHAP 
username"))
+
+
+password = section:taboption("general", Value, "password", translate("PAP/CHAP 
password"))
+password.password = true
+
+
+bcast = section:taboption("advanced", Flag, "broadcast",
+       translate("Use broadcast flag"),
+       translate("Required for certain ISPs, e.g. Charter with DOCSIS 3"))
+
+bcast.default = bcast.disabled
+
+
+defaultroute = section:taboption("advanced", Flag, "defaultroute",
+       translate("Use default gateway"),
+       translate("If unchecked, no default route is configured"))
+
+defaultroute.default = defaultroute.enabled
+
+
+peerdns = section:taboption("advanced", Flag, "peerdns",
+       translate("Use DNS servers advertised by peer"),
+       translate("If unchecked, the advertised DNS server addresses are 
ignored"))
+
+peerdns.default = peerdns.enabled
+
+
+dns = section:taboption("advanced", DynamicList, "dns",
+       translate("Use custom DNS servers"))
+
+dns:depends("peerdns", "")
+dns.datatype = "ipaddr"
+dns.cast     = "string"
+
+
+delay = section:taboption("advanced", Value, "delay",
+       translate("Dongle connection delay"))
+delay.default    = "20"
+delay.placeholder = translate("seconds")
+delay.datatype   = "uinteger"
+
+
+metric = section:taboption("advanced", Value, "metric",
+       translate("Use gateway metric"))
+
+metric.placeholder = "0"
+metric.datatype           = "uinteger"
+
+clientid = section:taboption("advanced", Value, "clientid",
+       translate("Client ID to send when requesting DHCP"))
+
+
+vendorclass = section:taboption("advanced", Value, "vendorid",
+       translate("Vendor Class to send when requesting DHCP"))
+
+
+luci.tools.proto.opt_macaddr(section, ifc, translate("Override MAC address"))
+
+
+mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU"))
+mtu.placeholder = "1492"
+mtu.datatype   = "max(9200)"
diff --git 
a/package/network/services/ncm/files/usr/lib/lua/luci/model/network/proto_ncm.lua
 
b/package/network/services/ncm/files/usr/lib/lua/luci/model/network/proto_ncm.lua
new file mode 100644
index 0000000..dd8dbe4
--- /dev/null
+++ 
b/package/network/services/ncm/files/usr/lib/lua/luci/model/network/proto_ncm.lua
@@ -0,0 +1,60 @@
+--[[
+LuCI - Network model - 3G, PPP, PPtP, PPPoE and PPPoA protocol extension
+
+Copyright 2011 Jo-Philipp Wich <x...@subsignal.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+]]--
+
+local netmod = luci.model.network
+
+local _, p
+for _, p in ipairs({"ncm"}) do
+
+       local proto = netmod:register_protocol(p)
+
+       function proto.get_i18n(self)
+               return luci.i18n.translate("NCM")
+       end
+
+       function proto.ifname(self)
+               return p .. "-" .. self.sid
+       end
+
+       function proto.opkg_package(self)
+               return "kmod-usb-net-cdc-ncm"
+       end
+
+       function proto.is_installed(self)
+               return nixio.fs.access("/lib/netifd/proto/ncm.sh")
+       end
+
+       function proto.is_floating(self)
+               return false
+       end
+
+       function proto.is_virtual(self)
+               return false
+       end
+
+       function proto.get_interfaces(self)
+               return netmod.protocol.get_interfaces(self)
+       end
+
+       function proto.contains_interface(self, ifc)
+               return netmod.protocol.contains_interface(self, ifc)
+       end
+
+       netmod:register_pattern_virtual("^%s-%%w" % p)
+end
diff --git 
a/package/network/services/ncm/files/usr/lib/lua/luci/view/ncm/status.htm 
b/package/network/services/ncm/files/usr/lib/lua/luci/view/ncm/status.htm
new file mode 100644
index 0000000..5568b7f
--- /dev/null
+++ b/package/network/services/ncm/files/usr/lib/lua/luci/view/ncm/status.htm
@@ -0,0 +1,283 @@
+<%#
+LuCI - Lua Configuration Interface
+Copyright 2008 Steven Barth <ste...@midlink.org>
+Copyright 2008-2011 Jo-Philipp Wich <x...@subsignal.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+-%>
+
+<%
+       require "luci.sys"
+       require "luci.fs"
+
+       local rv = {
+               gothw           = "0",
+               gotcarrier      = "0",
+               gotsignal       = "0",
+               hwrefresh       = "0",
+               modemdev        = "",
+               driver          = "",
+               vendor          = "",
+               model           = "",
+               notification    = "",
+               firmware        = "",
+               imei            = "",
+               provider        = "",
+               mode            = "",
+               downlink        = "",
+               uplink          = "",
+               cellid          = "",
+               lac             = "",
+               network         = "",
+               signal          = "",
+               rssi            = "",
+               csq             = "",
+               rcsp            = "",
+               ecio            = ""
+       }
+
+       if luci.http.formvalue("gothw") == "1" then
+               rv["gothw"] = luci.http.formvalue("gothw") or "0"
+               rv["modemdev"] = luci.http.formvalue("modemdev")
+               rv["driver"] = luci.http.formvalue("driver")
+               rv["gotcarrier"] = luci.http.formvalue("gotcarrier") or "0"
+               rv["gotsignal"] = luci.http.formvalue("gotsignal") or "0"
+               rv["hwrefresh"] = luci.http.formvalue("hwrefresh") or "0"
+       else
+               local uci = require "luci.model.uci".cursor()
+               if uci:get("network", "wan", "proto") == "ncm" then
+                       rv["modemdev"] = uci:get("network", "wan", "device") or 
"0"
+               else
+                       if luci.http.formvalue("status") == "1" then
+
+                               rv["notification"] = "[ WAN is not using NCM 
protocol ]"
+                               rv["hwrefresh"] = "0"
+                               rv["gothw"] = "0"
+                               rv["driver"] = "-"
+
+                               luci.http.prepare_content("application/json")
+                               luci.http.write_json(rv)
+
+                               return
+                       end
+
+               end
+
+       end
+
+       if ( luci.http.formvalue("status") == "1" and rv["driver"] ~= "-" ) then
+
+               if luci.fs.access(rv["modemdev"]) then
+
+                       if rv["gothw"] == "0" then
+
+                               local modemhw = 
luci.sys.exec(table.concat({"/usr/bin/gcom -d ", rv["modemdev"], " -s 
/etc/gcom/ncm/getcardinfo.gcom"}, ""))
+
+                               for k, v in string.gmatch(modemhw, "(%w+) 
'(.-)'") do
+                                       rv[k] = v
+                               end
+
+                               if rv["driver"] == "" then
+                                       rv["driver"] = "-"
+                               end
+
+                               if ( rv["vendor"] == "" or rv["model"] == "" or 
rv["firmware"] == "" or rv["imei"] == "" or rv["driver"] == "" ) then
+                                       rv["gothw"] = "0"
+                               elseif (rv["driver"] ~= "-" and
+                                               
luci.fs.access(table.concat({"/etc/gcom/ncm/carrier/",rv["driver"], ".gcom"}, 
"")) and 
+                                               
luci.fs.access(table.concat({"/etc/gcom/ncm/signal/", rv["driver"], ".gcom"}, 
""))) then
+                                       rv['gothw'] = "1"
+                               else
+                                       rv["notification"] = " [ Unsupported 
dongle ]";
+                                       rv["driver"] = "-"
+                                       rv["gothw"] = "0"
+                                       rv["hwrefresh"] = "1"
+                               end
+
+                       elseif rv["gotcarrier"] == "0" then
+
+                               if rv["driver"] ~= "-" then
+
+                                       local modemcarrier = 
luci.sys.exec(table.concat({"/usr/bin/gcom -d ", rv["modemdev"], " -s 
/etc/gcom/ncm/carrier/", rv["driver"], ".gcom"}, ""))
+
+                                       for k, v in string.gmatch(modemcarrier, 
"(%w+) '(.-)'") do
+                                               rv[k] = v
+                                       end
+
+                                       if ( rv["provider"] == "" or 
rv["downlink"] == "" or rv["uplink"] == "" or rv["mode"] == "" ) then
+                                               rv["gotcarrier"] = "0"
+                                       else
+                                               rv["gotcarrier"] = "1"
+                                       end
+
+                               else
+                                       rv["gotcarrier"] = "1"
+                               end
+
+                       else
+
+                               if rv["driver"] ~= "-" then
+
+                                       local modemsignal = 
luci.sys.exec(table.concat({"/usr/bin/gcom -d ", rv["modemdev"], " -s 
/etc/gcom/ncm/signal/", rv["driver"], ".gcom"}, ""))
+
+                                       for k, v in string.gmatch(modemsignal, 
"(%w+) '(.-)'") do
+                                               rv[k] = v
+                                       end
+                                       rv["gotsignal"] = "1"
+                               end
+
+                       end
+               else
+
+                       rv["notification"] = table.concat({"[ ", 
rv["modemdev"], ": Device not present. ]"}, "")
+
+               end
+
+       end
+
+       if ( luci.http.formvalue("status") == "1" ) then
+
+               luci.http.prepare_content("application/json")
+               luci.http.write_json(rv)
+
+               return
+
+       end
+
+-%>
+
+<%+header%>
+
+<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
+<script type="text/javascript" src="<%=resource%>/ncm_xhr.js"></script>
+<script type="text/javascript">//<![CDATA[
+
+       function capitalize(s)
+       {
+               return s.toLowerCase().replace( /\b./g, function(a){ return 
a.toUpperCase(); } );
+       };
+
+       XHR2.poll(5, '<%=REQUEST_URI%>', { status: 1 },
+               function(x, info)
+               {
+
+                       var e;
+
+                       if (e = document.getElementById('notification'))
+                               e.innerHTML = info.notification;
+
+                       if (( gothwD == "0" && info.gothw == "1" ) || ( 
info.hwrefresh == "1" )) {
+
+                               if (e = document.getElementById('name'))
+                                       e.innerHTML = capitalize(info.vendor) + 
" " + capitalize(info.model);
+
+                               if (e = document.getElementById('firmware'))
+                                       e.innerHTML = info.firmware;
+
+                               if (e = document.getElementById('imei'))
+                                       e.innerHTML = info.imei;
+                       }
+
+                       if ( gotcarrierD == "0" && info.gotcarrier == "1" ) {
+
+                               if (e = document.getElementById('provider'))
+                                       e.innerHTML = info.provider;
+
+                               if (e = document.getElementById('linkspeed'))
+                                       if ( info.downlink != "" && info.uplink 
!= "" )
+                                               e.innerHTML = info.downlink + " 
/ " + info.uplink ;
+
+                               if (e = document.getElementById('mode'))
+                                       e.innerHTML = info.mode;
+
+                       }
+
+                       if ( info.gotsignal == "1" ) {
+
+                               if (e = document.getElementById('cellid'))
+                                       e.innerHTML = info.cellid;
+
+                               if (e = document.getElementById('lac'))
+                                       e.innerHTML = info.lac;
+
+                               if (e = document.getElementById('network'))
+                                       e.innerHTML = info.network;
+
+                               if (e = document.getElementById('signal'))
+                                       e.innerHTML = info.signal;
+
+                               if (e = document.getElementById('csq'))
+                                       e.innerHTML = info.csq;
+
+                               if (e = document.getElementById('rssi'))
+                                       e.innerHTML = info.rssi;
+
+                               if (e = document.getElementById('rcsp'))
+                                       e.innerHTML = info.rcsp;
+
+                               if (e = document.getElementById('ecio'))
+                                       e.innerHTML = info.ecio;
+
+                       }
+
+                       modemdevD = info.modemdev;
+                       driverD = info.driver;
+                       gothwD = info.gothw;
+                       gotcarrierD = info.gotcarrier;
+                       hwrefreshD = info.hwrefresh;
+                       gotsignalD = info.gotsignal;
+
+               }
+       );
+
+//]]></script>
+
+<h2><a id="content" name="content"><%:NCM Status%></a></h2>
+<small style="color: #777;" id="notification"></small>
+
+<fieldset class="cbi-section">
+       <legend id="name"><%:Detecting dongle%></legend>
+
+       <table width="100%" cellspacing="10">
+               <tr><td width="33%"><%:Firmware version%></td><td 
id="firmware"></td></tr>
+               <tr><td width="33%"><%:IMEI%></td><td id="imei"></td></tr>
+       </table>
+</fieldset>
+
+<fieldset class="cbi-section">
+       <legend><%:Network%></legend>
+
+       <table width="100%" cellspacing="10">
+               <tr><td width="33%"><%:Provider%></td><td 
id="provider"></td></tr>
+               <tr><td width="33%"><%:Downlink/Uplink%></td><td 
id="linkspeed"></td></tr>
+               <tr><td width="33%"><%:Mode%></td><td id="mode"></td></tr>
+       </table>
+</fieldset>
+
+<fieldset class="cbi-section">
+       <legend><%:Cell%></legend>
+
+       <table width="100%" cellspacing="10">
+               <tr><td width="33%"><%:Location Area Code%></td><td 
id="lac"></td></tr>
+               <tr><td width="33%"><%:Cell ID%></td><td id="cellid"></td></tr>
+       </table>
+</fieldset>
+
+<fieldset class="cbi-section">
+       <legend><%:Signal level%></legend>
+
+       <table width="100%" cellspacing="10">
+               <tr><td width="33%"><%:Network%></td><td id="network"></td></tr>
+               <tr><td width="33%"><%:Signal strength%></td><td 
id="signal"></td></tr>
+               <tr><td width="33%"><%:CSQ%></td><td id="csq"></td></tr>
+               <tr><td width="33%"><%:RSSI%></td><td id="rssi"></td></tr>
+               <tr><td width="33%"><%:RCSP%></td><td id="rcsp"></td></tr>
+               <tr><td width="33%"><%:ECIO%></td><td id="ecio"></td></tr>
+       </table>
+</fieldset>
+<%+footer%>
diff --git 
a/package/network/services/ncm/files/www/luci-static/resources/ncm_xhr.js 
b/package/network/services/ncm/files/www/luci-static/resources/ncm_xhr.js
new file mode 100644
index 0000000..c01e8ac
--- /dev/null
+++ b/package/network/services/ncm/files/www/luci-static/resources/ncm_xhr.js
@@ -0,0 +1,254 @@
+/*
+ * xhr.js - XMLHttpRequest helper class
+ * (c) 2008-2010 Jo-Philipp Wich
+ */
+
+var gothwD = "0";
+var gotcarrierD = "0";
+var gotsignalD = "0";
+var hwrefreshD = "0";
+var modemdevD = ""
+var driverD = ""
+
+XHR2 = function()
+{
+       this.reinit = function()
+       {
+               if (window.XMLHttpRequest) {
+                       this._xmlHttp = new XMLHttpRequest();
+               }
+               else if (window.ActiveXObject) {
+                       this._xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
+               }
+               else {
+                       alert("dongle_xhr.js: XMLHttpRequest is not supported 
by this browser!");
+               }
+       }
+
+       this.busy = function() {
+               if (!this._xmlHttp)
+                       return false;
+
+               switch (this._xmlHttp.readyState)
+               {
+                       case 1:
+                       case 2:
+                       case 3:
+                               return true;
+
+                       default:
+                               return false;
+               }
+       }
+
+       this.abort = function() {
+               if (this.busy())
+                       this._xmlHttp.abort();
+       }
+
+       this.get = function(url,data,callback)
+       {
+               this.reinit();
+
+               var xhr2  = this._xmlHttp;
+               var code = this._encode(data);
+
+               url = location.protocol + '//' + location.host + url;
+
+               if (code)
+                       if (url.substr(url.length-1,1) == '&')
+                               url += code;
+                       else
+                               url += '?' + code;
+
+               xhr2.open('GET', url, true);
+
+               xhr2.onreadystatechange = function()
+               {
+                       if (xhr2.readyState == 4) {
+                               var json = null;
+                               if (xhr2.getResponseHeader("Content-Type") == 
"application/json") {
+                                       try {
+                                               json = eval('(' + 
xhr2.responseText + ')');
+                                       }
+                                       catch(e) {
+                                               json = null;
+                                       }
+                               }
+
+                               callback(xhr2, json);
+                       }
+               }
+
+               xhr2.send(null);
+       }
+
+       this.post = function(url,data,callback)
+       {
+               this.reinit();
+
+               var xhr2  = this._xmlHttp;
+               var code = this._encode(data);
+
+               xhr2.onreadystatechange = function()
+               {
+                       if (xhr2.readyState == 4)
+                               callback(xhr2);
+               }
+
+               xhr2.open('POST', url, true);
+               xhr2.setRequestHeader('Content-type', 
'application/x-www-form-urlencoded');
+               xhr2.setRequestHeader('Content-length', code.length);
+               xhr2.setRequestHeader('Connection', 'close');
+               xhr2.send(code);
+       }
+
+       this.cancel = function()
+       {
+               this._xmlHttp.onreadystatechange = function(){};
+               this._xmlHttp.abort();
+       }
+
+       this.send_form = function(form,callback,extra_values)
+       {
+               var code = '';
+
+               for (var i = 0; i < form.elements.length; i++)
+               {
+                       var e = form.elements[i];
+
+                       if (e.options)
+                       {
+                               code += (code ? '&' : '') +
+                                       form.elements[i].name + '=' + 
encodeURIComponent(
+                                               e.options[e.selectedIndex].value
+                                       );
+                       }
+                       else if (e.length)
+                       {
+                               for (var j = 0; j < e.length; j++)
+                                       if (e[j].name) {
+                                               code += (code ? '&' : '') +
+                                                       e[j].name + '=' + 
encodeURIComponent(e[j].value);
+                                       }
+                       }
+                       else
+                       {
+                               code += (code ? '&' : '') +
+                                       e.name + '=' + 
encodeURIComponent(e.value);
+                       }
+               }
+
+               if (typeof extra_values == 'object')
+                       for (var key in extra_values)
+                               code += (code ? '&' : '') +
+                                       key + '=' + 
encodeURIComponent(extra_values[key]);
+
+               return(
+                       (form.method == 'get')
+                               ? this.get(form.getAttribute('action'), code, 
callback)
+                               : this.post(form.getAttribute('action'), code, 
callback)
+               );
+       }
+
+       this._encode = function(obj)
+       {
+               obj = obj ? obj : { };
+               obj['gothw'] = gothwD;
+               obj['gotcarrier'] = gotcarrierD;
+               obj['gotsignal'] = gotsignalD;
+               obj['hwrefresh'] = hwrefreshD;
+               obj['modemdev'] = modemdevD;
+               obj['driver'] = driverD;
+               obj['_'] = Math.random();
+
+               if (typeof obj == 'object')
+               {
+                       var code = '';
+                       var self = this;
+
+                       for (var k in obj)
+                               code += (code ? '&' : '') +
+                                       k + '=' + encodeURIComponent(obj[k]);
+
+                       return code;
+               }
+
+               return obj;
+       }
+}
+
+XHR2.get = function(url, data, callback)
+{
+       (new XHR2()).get(url, data, callback);
+}
+
+XHR2.poll = function(interval, url, data, callback)
+{
+       if (isNaN(interval) || interval < 1)
+               interval = 5;
+
+       if (!XHR2._q)
+       {
+               XHR2._t = 0;
+               XHR2._q = [ ];
+               XHR2._r = function() {
+                       for (var i = 0, e = XHR2._q[0]; i < XHR2._q.length; e = 
XHR2._q[++i])
+                       {
+                               if (!(XHR2._t % e.interval) && !e.xhr2.busy())
+                                       e.xhr2.get(e.url, e.data, e.callback);
+                       }
+
+                       XHR2._t++;
+               };
+       }
+
+       XHR2._q.push({
+               interval: interval,
+               callback: callback,
+               url:      url,
+               data:     data,
+               xhr2:      new XHR2()
+       });
+
+       XHR2.run();
+}
+
+XHR2.halt = function()
+{
+       if (XHR2._i)
+       {
+               /* show & set poll indicator */
+               try {
+                       
document.getElementById('xhr_poll_status').style.display = '';
+                       
document.getElementById('xhr_poll_status_on').style.display = 'none';
+                       
document.getElementById('xhr_poll_status_off').style.display = '';
+               } catch(e) { }
+
+               window.clearInterval(XHR2._i);
+               XHR2._i = null;
+       }
+}
+
+XHR2.run = function()
+{
+       if (XHR2._r && !XHR2._i)
+       {
+               /* show & set poll indicator */
+               try {
+                       
document.getElementById('xhr_poll_status').style.display = '';
+                       
document.getElementById('xhr_poll_status_on').style.display = '';
+                       
document.getElementById('xhr_poll_status_off').style.display = 'none';
+               } catch(e) { }
+
+               /* kick first round manually to prevent one second lag when 
setting up
+                * the poll interval */
+               XHR2._r();
+               XHR2._i = window.setInterval(XHR2._r, 1000);
+       }
+}
+
+XHR2.running = function()
+{
+       return !!(XHR2._r && XHR2._i);
+}
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to