This commit is contained in:
ling 2023-05-22 22:08:29 +08:00
parent 050e1102f2
commit 7d0cb41fb3
537 changed files with 14866 additions and 50619 deletions

View File

@ -1,49 +0,0 @@
-- Copyright 2018 Florian Eckert <fe@dev.tdt.de>
-- Licensed to the public under the Apache License 2.0.
local netmod = luci.model.network
local interface = luci.model.network.interface
local proto = netmod:register_protocol("3x")
function proto.get_i18n(self)
return luci.i18n.translate("UMTS/GPRS/EV-DO")
end
function proto.ifname(self)
return "3x-" .. self.sid
end
function proto.get_interface(self)
return interface(self:ifname(), self)
end
function proto.is_installed(self)
return nixio.fs.access("/lib/netifd/proto/3x.sh")
end
function proto.opkg_package(self)
return "comgt"
end
function proto.is_floating(self)
return true
end
function proto.is_virtual(self)
return true
end
function proto.get_interfaces(self)
return nil
end
function proto.contains_interface(self, ifc)
if self:is_floating() then
return (netmod:ifnameof(ifc) == self:ifname())
else
return netmod.protocol.contains_interface(self, ifc)
end
end
netmod:register_pattern_virtual("^3x%-%w")

View File

@ -1,11 +0,0 @@
'use strict';'require rpc';'require uci';'require form';'require network';var callFileList=rpc.declare({object:'file',method:'list',params:['path'],expect:{entries:[]},filter:function(list,params){var rv=[];for(var i=0;i<list.length;i++)
if(list[i].name.match(/^tty[A-Z]/)||list[i].name.match(/^cdc-wdm/)||list[i].name.match(/^[0-9]+$/))
rv.push(params.path+list[i].name);return rv.sort();}});network.registerPatternVirtual(/^3x-.+$/);function write_keepalive(section_id,value){var f_opt=this.map.lookupOption('_keepalive_failure',section_id),i_opt=this.map.lookupOption('_keepalive_interval',section_id),f=(f_opt!=null)?+f_opt[0].formvalue(section_id):null,i=(i_opt!=null)?+i_opt[0].formvalue(section_id):null;if(f==null||f==''||isNaN(f))
f=0;if(i==null||i==''||isNaN(i)||i<1)
i=1;if(f>0)
uci.set('network',section_id,'keepalive','%d %d'.format(f,i));else
uci.unset('network',section_id,'keepalive');}
return network.registerProtocol('3x',{getI18n:function(){return _('UMTS/GPRS/EV-DO');},getIfname:function(){return this._ubus('l3_device')||'3x-%s'.format(this.sid);},getOpkgPackage:function(){return'comgt';},isFloating:function(){return true;},isVirtual:function(){return true;},getDevices:function(){return null;},containsDevice:function(ifname){return(network.getIfnameOf(ifname)==this.getIfname());},renderFormOptions:function(s){var o;o=s.taboption('general',form.Value,'device',_('Modem device'));o.rmempty=false;o.load=function(section_id){return callFileList('/dev/').then(L.bind(function(devices){for(var i=0;i<devices.length;i++)
this.value(devices[i]);return callFileList('/dev/tts/');},this)).then(L.bind(function(devices){for(var i=0;i<devices.length;i++)
this.value(devices[i]);return form.Value.prototype.load.apply(this,[section_id]);},this));};o=s.taboption('general',form.Value,'service',_('Service Type'));o.value('',_('-- Please choose --'));o.value('umts','UMTS/GPRS');o.value('umts_only',_('UMTS only'));o.value('gprs_only',_('GPRS only'));o.value('evdo','CDMA/EV-DO');s.taboption('general',form.Value,'apn',_('APN'));s.taboption('general',form.Value,'pincode',_('PIN'));s.taboption('general',form.Value,'username',_('PAP/CHAP username'));o=s.taboption('general',form.Value,'password',_('PAP/CHAP password'));o.password=true;o=s.taboption('general',form.Value,'dialnumber',_('Dial number'));o.placeholder='*99***1#';if(L.hasSystemFeature('ipv6')){o=s.taboption('advanced',form.ListValue,'ipv6',_('Obtain IPv6-Address'));o.value('auto',_('Automatic'));o.value('0',_('Disabled'));o.value('1',_('Manual'));o.default='auto';}
o=s.taboption('advanced',form.Value,'delay',_('Modem init timeout'),_('Maximum amount of seconds to wait for the modem to become ready'));o.placeholder='10';o.datatype='min(1)';o=s.taboption('advanced',form.Flag,'defaultroute',_('Use default gateway'),_('If unchecked, no default route is configured'));o.default=o.enabled;o=s.taboption('advanced',form.Value,'metric',_('Use gateway metric'));o.placeholder='0';o.datatype='uinteger';o.depends('defaultroute','1');o=s.taboption('advanced',form.Flag,'peerdns',_('Use DNS servers advertised by peer'),_('If unchecked, the advertised DNS server addresses are ignored'));o.default=o.enabled;o=s.taboption('advanced',form.DynamicList,'dns',_('Use custom DNS servers'));o.depends('peerdns','0');o.datatype='ipaddr';o=s.taboption('advanced',form.Value,'_keepalive_failure',_('LCP echo failure threshold'),_('Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures'));o.placeholder='0';o.datatype='uinteger';o.write=write_keepalive;o.remove=write_keepalive;o.cfgvalue=function(section_id){var v=uci.get('network',section_id,'keepalive');if(typeof(v)=='string'&&v!=''){var m=v.match(/^(\d+)[ ,]\d+$/);return m?m[1]:v;}};o=s.taboption('advanced',form.Value,'_keepalive_interval',_('LCP echo interval'),_('Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold'));o.placeholder='5';o.datatype='min(1)';o.write=write_keepalive;o.remove=write_keepalive;o.cfgvalue=function(section_id){var v=uci.get('network',section_id,'keepalive');if(typeof(v)=='string'&&v!=''){var m=v.match(/^\d+[ ,](\d+)$/);return m?m[1]:v;}};o=s.taboption('advanced',form.Value,'demand',_('Inactivity timeout'),_('Close inactive connection after the given amount of seconds, use 0 to persist connection'));o.placeholder='0';o.datatype='uinteger';}});

View File

@ -1,107 +0,0 @@
'use strict';
'require rpc';
'require form';
'require network';
var callFileList = rpc.declare({
object: 'file',
method: 'list',
params: [ 'path' ],
expect: { entries: [] },
filter: function(list, params) {
var rv = [];
for (var i = 0; i < list.length; i++)
if (list[i].name.match(/^cdc-wdm/))
rv.push(params.path + list[i].name);
return rv.sort();
}
});
network.registerPatternVirtual(/^mbim-.+$/);
network.registerErrorCode('CALL_FAILED', _('Call failed'));
network.registerErrorCode('NO_CID', _('Unable to obtain client ID'));
network.registerErrorCode('PLMN_FAILED', _('Setting PLMN failed'));
return network.registerProtocol('mbim', {
getI18n: function() {
return _('MBIM Cellular');
},
getIfname: function() {
return this._ubus('l3_device') || 'mbim-%s'.format(this.sid);
},
getOpkgPackage: function() {
return 'rmbim';
},
isFloating: function() {
return true;
},
isVirtual: function() {
return true;
},
getDevices: function() {
return null;
},
containsDevice: function(ifname) {
return (network.getIfnameOf(ifname) == this.getIfname());
},
renderFormOptions: function(s) {
var dev = this.getL3Device() || this.getDevice(), o;
o = s.taboption('general', form.Value, 'device', _('Modem device'));
o.rmempty = false;
o.load = function(section_id) {
return callFileList('/dev/').then(L.bind(function(devices) {
for (var i = 0; i < devices.length; i++)
this.value(devices[i]);
return form.Value.prototype.load.apply(this, [section_id]);
}, this));
};
s.taboption('general', form.Value, 'apn', _('APN'));
s.taboption('general', form.Value, 'pincode', _('PIN'));
o = s.taboption('general', form.ListValue, 'auth', _('Authentication Type'));
o.value('both', 'PAP/CHAP');
o.value('pap', 'PAP');
o.value('chap', 'CHAP');
o.value('none', 'NONE');
o.default = 'none';
o = s.taboption('general', form.Value, 'username', _('PAP/CHAP username'));
o.depends('auth', 'pap');
o.depends('auth', 'chap');
o.depends('auth', 'both');
o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password'));
o.depends('auth', 'pap');
o.depends('auth', 'chap');
o.depends('auth', 'both');
o.password = true;
if (L.hasSystemFeature('ipv6')) {
o = s.taboption('advanced', form.Flag, 'ipv6', _('Enable IPv6 negotiation'));
o.default = o.disabled;
}
o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'), _('Maximum amount of seconds to wait for the modem to become ready'));
o.placeholder = '10';
o.datatype = 'min(1)';
o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU'));
o.placeholder = dev ? (dev.getMTU() || '1500') : '1500';
o.datatype = 'max(9200)';
o = s.taboption('general', form.ListValue, 'pdptype', _('PDP Type'));
o.value('ipv4v6', 'IPv4/IPv6');
o.value('ipv4', 'IPv4');
o.value('ipv6', 'IPv6');
o.default = 'ipv4v6';
}
});

View File

@ -1,43 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-huasifei
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-huasifei
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+luci +ext-rooter-basic +pingtest +ext-blacklist +ext-blockport \
+extramenu +ext-domain \
+luci-app-ddns +ddns-scripts \
+luci-app-rootervpn +ext-wireguard \
+webconsole +bwmon +464xlat \
+iptables-mod-hashlimit \
+ca-bundle +ca-certificates +libustream-wolfssl \
+luci-app-ksmbd +usb-storage \
+ext-p910nd +kmod-sched-cake +luci-app-nft-qos \
+ext-command +ext-speedtest +luci-app-guestwifi \
+openvpn-easy-rsa +openvpn-openssl \
+ext-extra +luci-app-hotspot +luci-app-wol \
+usbmuxd +libusbmuxd-utils +libimobiledevice-utils +kmod-usb-net-ipheth \
+qlog +luci-ssl +usbutils +openssl-util +irqbalance +ext-splashconfig \
+nano +picocom +wpad +wget +qfirehose
TITLE:=ROOter support w/o MWan3 for Huasifei
PKGARCH:=all
endef
define Package/ext-huasifei/description
Helper scripts to enable ROOter support for Huasifei
endef
define Build/Compile
endef
$(eval $(call BuildPackage,ext-huasifei))

View File

@ -1,30 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-huasifei16
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-huasifei16
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+ext-huasifei \
+luci-app-mwan3 +luci-app-dnsmasq-ipset
TITLE:=ROOter support w/o MWan3 for Huasifei
PKGARCH:=all
endef
define Package/ext-huasifei16/description
Helper scripts to enable ROOter support for Huasifei
endef
define Build/Compile
endef
$(eval $(call BuildPackage,ext-huasifei16))

View File

@ -1,37 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-rbsxtr
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-rbsxtr
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+luci +luci-compat +ext-rooter-basic \
+luci-app-rootervpn +ext-wireguard \
+bwmon +464xlat \
+ca-bundle +ca-certificates +libustream-wolfssl \
+luci-app-sqm +kmod-sched-cake \
+ext-command +ext-speedtest \
+openvpn-easy-rsa +openvpn-openssl \
+ext-extra \
+nano +picocom +wget +webconsole
TITLE:=ROOter support for RBSXTR routers
PKGARCH:=all
endef
define Package/ext-rbsxtr/description
Helper scripts to enable ROOter support for RBSXTR routers
endef
define Build/Compile
endef
$(eval $(call BuildPackage,ext-rbsxtr))

View File

@ -1,37 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-rbsxtr
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-rbsxtr
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+luci +luci-compat +ext-rooter-basic \
+luci-app-rootervpn +ext-wireguard \
+bwmon +464xlat \
+ca-bundle +ca-certificates +libustream-wolfssl \
+luci-app-sqm +kmod-sched-cake \
+ext-command +ext-speedtest \
+openvpn-easy-rsa +openvpn-openssl \
+ext-extra \
+nano +picocom +wget +webconsole
TITLE:=ROOter support for RBSXTR routers
PKGARCH:=all
endef
define Package/ext-rbsxtr/description
Helper scripts to enable ROOter support for RBSXTR routers
endef
define Build/Compile
endef
$(eval $(call BuildPackage,ext-rbsxtr))

View File

@ -1,43 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-rooter-lite
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-rooter-lite
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+luci +ext-rooter-basic +pingtest +ext-logo \
+luci-app-ddns +ddns-scripts \
+luci-app-rootervpn +ext-wireguard \
+bwmon +464xlat +webconsole \
+ext-theme +luci-theme-argon +luci-theme-argondark +ext-login \
+luci-theme-tomato \
+ca-bundle +ca-certificates +libustream-wolfssl \
+luci-app-ksmbd +usb-storage \
+ext-p910nd +luci-app-sqm +kmod-sched-cake +luci-app-nft-qos \
+ext-command +ext-speedtest \
+openvpn-easy-rsa +openvpn-openssl \
+ext-extra +luci-app-hotspot +luci-app-wol +luci-app-guestwifi \
+usbmuxd +libusbmuxd-utils +libimobiledevice-utils +kmod-usb-net-ipheth \
+qlog +luci-ssl +usbutils +openssl-util +irqbalance +ext-splashconfig \
+nano +picocom +wpad-openssl +wget +qfirehose +luci-app-vpnbypass +ext-simplegps
TITLE:=ROOter support w/o MWan3 for 16meg and larger routers
PKGARCH:=all
endef
define Package/ext-rooter-lite/description
Helper scripts to enable ROOter w/o MWan3 on 16meg and larger routers
endef
define Build/Compile
endef
$(eval $(call BuildPackage,ext-rooter-lite))

View File

@ -1,44 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-rooter16
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-rooter16
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+luci +ext-rooter-basic +pingtest +ext-logo \
+luci-app-mwan3 +luci-app-dnsmasq-ipset \
+luci-app-ddns +ddns-scripts \
+luci-app-rootervpn +ext-wireguard \
+bwmon +464xlat +webconsole \
+ext-theme +luci-theme-argon +luci-theme-argondark \
+luci-theme-tomato +ext-login \
+ca-bundle +ca-certificates +libustream-wolfssl \
+luci-app-ksmbd +usb-storage \
+ext-p910nd +luci-app-sqm +kmod-sched-cake +luci-app-nft-qos \
+ext-command +ext-speedtest +luci-app-guestwifi \
+openvpn-easy-rsa +openvpn-openssl \
+ext-extra +luci-app-hotspot +luci-app-wol \
+usbmuxd +libusbmuxd-utils +libimobiledevice-utils +kmod-usb-net-ipheth \
+qlog +luci-ssl +usbutils +openssl-util +irqbalance +ext-splashconfig \
+nano +picocom +wpad-openssl +wget +qfirehose +luci-app-vpnbypass +ext-simplegps
TITLE:=ROOter support for 16meg and larger routers
PKGARCH:=all
endef
define Package/ext-rooter16/description
Helper scripts to enable ROOter on 16meg and larger routers
endef
define Build/Compile
endef
$(eval $(call BuildPackage,ext-rooter16))

View File

@ -1,38 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-rooter4
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-rooter4
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+luci +ext-rooter-basic +ext-logo \
+ca-bundle +ca-certificates \
+luci-app-sqm +kmod-sched-cake \
+luci-app-ddns +ddns-scripts \
+ext-command +ext-p910nd +luci-app-guestwifi \
+luci-app-hotspot +ext-extra \
+picocom +wget +nano +464xlat
TITLE:=install basic ROOter routers
PKGARCH:=all
endef
define Package/ext-rooter4/description
Helper scripts to install basic ROOter routers
endef
define Build/Compile
endef
define Package/ext-rooter4/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,ext-rooter4))

View File

@ -1,15 +0,0 @@
config policy 'faillist'
config tracker 'failover'
option reliability '1'
option count '1'
option pingtime '5'
option pingwait '7'
option down '2'
option up '2'
list trackip '8.8.8.8'
config enabled 'enabled'
option enabled '0'

View File

@ -1 +0,0 @@
FLASH="4"

View File

@ -1,39 +0,0 @@
module("luci.controller.failover", package.seeall)
function index()
local page
if not nixio.fs.access("/etc/config/failover") then
return
end
page = entry({"admin", "network", "failover"}, cbi("rooter/failover"), "Internet Failover", 600)
page.dependent = true
entry({"admin", "network", "get_fstatus"}, call("action_get_fstatus"))
end
function action_get_fstatus()
local file
mArray = {}
file = io.open("/tmp/wanstatus", "r")
if file == nil then
mArray["wan"] = " "
else
mArray["wan"] = file:read("*line")
mArray["winter"] = file:read("*line")
mArray["wstatus"] = file:read("*line")
file:close()
end
file = io.open("/tmp/modemstatus", "r")
if file == nil then
mArray["modem"] = " "
else
mArray["modem"] = file:read("*line")
mArray["minter"] = file:read("*line")
mArray["mstatus"] = file:read("*line")
file:close()
end
luci.http.prepare_content("application/json")
luci.http.write_json(mArray)
end

View File

@ -1,140 +0,0 @@
local utl = require "luci.util"
local uci = require "luci.model.uci".cursor()
function cbiAddWan(field)
i = 0
uci.cursor():foreach("failover", "member",
function (section)
line = section[".name"]
s, e = line:find("Modem")
if s == nil then
field:value(section[".name"])
if i == 0 then
field.default = section[".name"]
end
i = 1
end
end
)
end
function cbiAddModem(field)
i = 0
uci.cursor():foreach("failover", "member",
function (section)
line = section[".name"]
s, e = line:find("Modem")
if s ~= nil then
field:value(section[".name"])
if i == 0 then
field.default = section[".name"]
end
i = 1
end
end
)
end
m = Map("failover", translate("Internet Connection Failover"), translate("Enable a connection failover system between two Internet sources."))
m.on_after_commit = function(self)
luci.sys.call("/usr/lib/rooter/luci/failchk.sh")
end
enabl = m:section(NamedSection, "enabled", "enabled", "")
enabl.addremove = false
enabl.dynamic = false
e = enabl:option(Flag, "enabled", translate("Failover Enabled"))
e.rmempty = false
policy = m:section(NamedSection, "faillist", "policy", "")
policy.addremove = false
policy.dynamic = false
use_wan = policy:option(ListValue, "use_wan", translate("Primary Internet Source"),
translate("Select Primary Internet source."))
cbiAddWan(use_wan)
use_modem = policy:option(ListValue, "use_modem", translate("Secondary Internet Source"),
translate("Select Secondary (Backup) Internet source."))
cbiAddModem(use_modem)
tracker = m:section(NamedSection, "failover", "tracker", "")
tracker.addremove = false
tracker.dynamic = false
reliability = tracker:option(Value, "reliability", translate("Tracking reliability"),
translate("Acceptable values: 1-100. This many Tracking IP addresses must respond for the source to be deemed up"))
reliability.datatype = "range(1, 100)"
reliability.default = "1"
count = tracker:option(ListValue, "count", translate("Ping count"))
count.default = "1"
count:value("1")
count:value("2")
count:value("3")
count:value("4")
count:value("5")
interval = tracker:option(ListValue, "pingtime", translate("Ping interval"),
translate("Amount of time between tracking tests"))
interval.default = "5"
interval:value("5", translate("5 seconds"))
interval:value("10", translate("10 seconds"))
interval:value("20", translate("20 seconds"))
interval:value("30", translate("30 seconds"))
interval:value("60", translate("1 minute"))
interval:value("300", translate("5 minutes"))
interval:value("600", translate("10 minutes"))
interval:value("900", translate("15 minutes"))
interval:value("1800", translate("30 minutes"))
interval:value("3600", translate("1 hour"))
timeout = tracker:option(ListValue, "pingwait", translate("Ping timeout"))
timeout.default = "2"
timeout:value("1", translate("1 second"))
timeout:value("2", translate("2 seconds"))
timeout:value("3", translate("3 seconds"))
timeout:value("4", translate("4 seconds"))
timeout:value("5", translate("5 seconds"))
timeout:value("6", translate("6 seconds"))
timeout:value("7", translate("7 seconds"))
timeout:value("8", translate("8 seconds"))
timeout:value("9", translate("9 seconds"))
timeout:value("10", translate("10 seconds"))
down = tracker:option(ListValue, "down", translate("Interface down"),
translate("Interface will be deemed down after this many failed ping tests in a row"))
down.default = "2"
down:value("1")
down:value("2")
down:value("3")
down:value("4")
down:value("5")
down:value("6")
down:value("7")
down:value("8")
down:value("9")
down:value("10")
up = tracker:option(ListValue, "up", translate("Interface up"),
translate("Downed interface will be deemed up after this many successful ping tests in a row"))
up.default = "2"
up:value("1")
up:value("2")
up:value("3")
up:value("4")
up:value("5")
up:value("6")
up:value("7")
up:value("8")
up:value("9")
up:value("10")
cb2 = tracker:option(DynamicList, "trackip", translate("Tracking IP"),
translate("This IP address will be pinged to dermine if the link is up or down."))
cb2.datatype = "ipaddr"
return m

View File

@ -1,188 +0,0 @@
#!/bin/sh
. /lib/functions.sh
ROOTER=/usr/lib/rooter
log() {
logger -t "Failover System" "$@"
}
log "Failover System is Started"
ifname1="ifname"
if [ -e /etc/newstyle ]; then
ifname1="device"
fi
i=1
STAT="0"
track_ips=
WAN_STATUS="0"
MODEM_STATUS="0"
MODEM_IFUP=true
rm -f /tmp/wanstatus
rm -f /tmp/modemstatus
rm -f /tmp/mdown$CURRMODEM
get_interface() {
OX=$1
case $OX in
"Wan" )
inter="wan"
;;
"Hotspot" )
inter="wwan"
;;
* )
inter="wan${OX:5}"
;;
esac
uci set failover.$OX.interface=$inter
}
ping_interface() {
interf=$(uci get failover.$1.interface)
if [ $interf = "wwan" ]; then
IFN="$(ubus -S call network.wireless status | jsonfilter -e '@.*.interfaces[@.config.mode="sta"].${ifname1}')"
else
IFN=$(uci get network.$interf.${ifname1})
fi
if [ ! -z $IFN ]; then
STAT="1"
host_up_count=0
score_up=$UP
score_dwn=$DOWN
lost=0
while true; do
if [ ! -z "$track_ips" ]; then
for track_ip in $track_ips; do
ping -I $IFN -c $COUNT -W $TIMEOUT -s 4 -q $track_ip &> /dev/null
if [ $? -eq 0 ]; then
let host_up_count++
else
let lost++
fi
done
if [ $host_up_count -lt $RELIAB ]; then
let score_dwn--
score_up=$UP
if [ $score_dwn -eq 0 ]; then
STAT="1"
break
fi
else
let score_up--
score_dwn=$DOWN
if [ $score_up -eq 0 ]; then
STAT="2"
break
fi
fi
else
log "No Tracking IP, stopping Failover"
exit
fi
host_up_count=0
sleep $INTERVAL
done
else
STAT="0"
fi
}
make_status() {
name=$2
status=$3
interface=$(uci get failover.$name.interface)
echo "$name" > /tmp/$1"status"
echo "$interface" >> /tmp/$1"status"
case $status in
"0" )
echo "disabled" >> /tmp/$1"status"
;;
"1" )
echo "offline" >> /tmp/$1"status"
;;
"2" )
echo "online" >> /tmp/$1"status"
;;
"3" )
echo "onlinedwn" >> /tmp/$1"status"
;;
esac
}
list_track_ips() {
track_ips="$1 $track_ips"
}
rm -f /tmp/wanstatus
rm -f /tmp/modemstatus
config_load failover
config_list_foreach "failover" "trackip" list_track_ips
use_wan=$(uci get failover.faillist.use_wan)
get_interface $use_wan
use_modem=$(uci get failover.faillist.use_modem)
get_interface $use_modem
uci commit failover
interf=$(uci get failover.$use_wan.interface)
uci set network.$interf.metric="99"
uci commit network
ifup $interf
TIMEOUT=$(uci get failover.failover.pingwait)
INTERVAL=$(uci get failover.failover.pingtime)
RELIAB=$(uci get failover.failover.reliability)
DOWN=$(uci get failover.failover.down)
UP=$(uci get failover.failover.up)
COUNT=$(uci get failover.failover.count)
while true; do
use_wan=$(uci get failover.faillist.use_wan)
use_modem=$(uci get failover.faillist.use_modem)
ping_interface $use_wan
make_status "wan" $use_wan $STAT
WAN_STATUS=$STAT
if [ $WAN_STATUS = "2" ];then
if [ $MODEM_IFUP = true -a $MODEM_STATUS == "2" ]; then
MODEM_IFUP=false
MODEM_STATUS="3"
ifdown $(uci get failover.$use_modem.interface)
fi
else
if [ $MODEM_IFUP = false -a $MODEM_STATUS != "0" ]; then
MODEM_IFUP=true
MODEM_STATUS="2"
ifup $(uci get failover.$use_modem.interface)
sleep 10
fi
fi
if [ $MODEM_STATUS != "3" ]; then
ping_interface $use_modem
make_status "modem" $use_modem $STAT
MODEM_STATUS=$STAT
MODEM_IFUP=true
if [ $STAT = "1" ]; then
echo "0" > /tmp/mdown$CURRMODEM
else
rm -f /tmp/mdown$CURRMODEM
fi
else
interf=$(uci get failover.$use_modem.interface)
IFN=$(uci get network.$interf.${ifname1})
if [ -z $IFN ]; then
MODEM_IFUP=false
make_status "modem" $use_modem "0"
MODEM_STATUS="0"
else
make_status "modem" $use_modem "3"
MODEM_STATUS="3"
MODEM_IFUP=false
fi
fi
sleep 10
done

View File

@ -1,16 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
log() {
logger -t "Failover Check" "$@"
}
jkillall failover.sh
ENB=$(uci get failover.enabled.enabled)
if [ $ENB = "1" ]; then
if [ -e $ROOTER/connect/failover.sh ]; then
log "Restarting Failover System"
$ROOTER/connect/failover.sh &
fi
fi

View File

@ -1,36 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-rooter8-vpn
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-rooter8-vpn
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+luci +ext-rooter4 +bwmon \
+luci-app-rootervpn +ext-wireguard
TITLE:=basic ROOter support for 8meg routers
PKGARCH:=all
endef
define Package/ext-rooter8-vpn/description
basic ROOter support for 8meg routers
endef
define Build/Compile
endef
define Package/ext-rooter8-vpn/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,ext-rooter8-vpn))

View File

@ -1 +0,0 @@
FLASH="8"

View File

@ -1,44 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-rooterbcm16
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-rooterbcm16
SECTION:=utils
CATEGORY:=ROOter
DEPENDS:=+luci +ext-rooter-basic +ext-logo \
+luci-app-mwan3 +luci-app-dnsmasq-ipset \
+luci-app-ddns +ddns-scripts \
+luci-app-rootervpn +ext-wireguard \
+webconsole +bwmon +464xlat \
+ext-theme +luci-theme-argon +luci-theme-argondark \
+luci-theme-tomato +ext-login \
+ca-bundle +ca-certificates +libustream-wolfssl \
+luci-app-ksmbd +usb-storage \
+ext-p910nd +luci-app-sqm +kmod-sched-cake +luci-app-nft-qos \
+ext-command +ext-speedtest +luci-app-guestwifi \
+openvpn-easy-rsa +openvpn-openssl \
+ext-extra +luci-app-wol \
+usbmuxd +libusbmuxd-utils +libimobiledevice-utils +kmod-usb-net-ipheth \
+qlog +luci-ssl +usbutils +openssl-util +irqbalance +ext-splashconfig \
+nano +picocom +wpad +wget +qfirehose +luci-app-vpnbypass
TITLE:=ROOter support for 16meg and larger Broadcom routers w/o Hotspot Manager
PKGARCH:=all
endef
define Package/ext-rooterbcm16/description
Helper scripts to enable ROOter on 16meg and larger Broadcom routers w/o Hotspot Manager
endef
define Build/Compile
endef
$(eval $(call BuildPackage,ext-rooterbcm16))

View File

@ -1,33 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-netselect
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-netselect
SECTION:=utils
CATEGORY:=ROOter
SUBMENU:=Optional Applications
TITLE:=support for Network Selection
PKGARCH:=all
endef
define Package/ext-netselect/description
Helper scripts to enable Network Selection
endef
define Build/Compile
endef
define Package/ext-netselect/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,ext-netselect))

View File

@ -1,73 +0,0 @@
module("luci.controller.netroam", package.seeall)
I18N = require "luci.i18n"
translate = I18N.translate
function index()
entry({"admin", "modem", "netroam"}, template("netroam/netroam"), translate("Network Selection"), 39)
entry({"admin", "netroam", "getconnect"}, call("action_getconnect"))
entry({"admin", "netroam", "getscan"}, call("action_getscan"))
entry({"admin", "netroam", "connect"}, call("action_connect"))
end
function action_getconnect()
local rv ={}
connect = luci.model.uci.cursor():get("modem", "modem1", "connected")
rv['connected'] = connect
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
end
function action_getscan()
local netw = {}
local netmc = {}
local netlong = {}
local netavail = {}
local rv ={}
os.execute("/usr/lib/netroam/getcops.sh")
file = io.open("/tmp/copseqxx", "r")
mfile = io.open("/tmp/copseqmc", "r")
lfile = io.open("/tmp/copseqlg", "r")
afile = io.open("/tmp/copseqav", "r")
if file ~= nil then
rv["data"] = "1"
indx = 0
repeat
line = file:read("*line")
if line == nil then
break
end
mline = mfile:read("*line")
netw[indx] = line
netmc[indx] = mline
lline = lfile:read("*line")
netlong[indx] = lline
aline = afile:read("*line")
netavail[indx] = aline
indx = indx +1
until 1 == 0
rv['network'] = netw
rv['mccmnc'] = netmc
rv['long'] = netlong
rv['avail'] = netavail
rv['indx'] = tostring(indx)
file:close()
mfile:close()
lfile:close()
afile:close()
else
rv["data"] = "0"
end
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
end
function action_connect()
local set = luci.http.formvalue("set")
os.execute("/usr/lib/netroam/doconnect.sh " .. set)
end

View File

@ -1,261 +0,0 @@
<%+header%>
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<script type="text/javascript">//<![CDATA[
var gotdata = "0";
var netdata = new Array();
var netmcc = new Array();
var netlong = new Array();
var netavail = new Array();
var ulselect = -1;
XHR.poll(2, '<%=luci.dispatcher.build_url("admin", "netroam", "getconnect")%>', null,
function(x, rv)
{
connected = rv.connected;
if ( connected == "1" )
{
document.getElementById("noconnect").style.visibility="hidden";
document.getElementById("noconnect").style.display="none";
document.getElementById("scansec").style.visibility="visible";
document.getElementById("scansec").style.display="";
document.getElementById("scan").style.visibility="visible";
document.getElementById("scan").style.display="";
}
else
{
document.getElementById("noconnect").style.visibility="visible";
document.getElementById("noconnect").style.display="";
document.getElementById("scan").style.visibility="hidden";
document.getElementById("scan").style.display="none";
document.getElementById("results").style.visibility="hidden";
document.getElementById("results").style.display="none";
}
}
);
function clearListul(listboxID)
{
var mylistbox = document.getElementById(listboxID);
if(mylistbox == null)
{
return 1;
}
mylistbox.innerHTML = '';
}
function scannet(btn)
{
document.getElementById("results").style.visibility="hidden";
document.getElementById("results").style.display="none";
document.getElementById("scan").disabled=true;
document.getElementById("getinfo").style.visibility="visible";
document.getElementById("getinfo").style.display="";
XHR.get('<%=luci.dispatcher.build_url("admin", "netroam", "getscan")%>',
null,
function(x, rv)
{
document.getElementById("results").style.visibility="visible";
document.getElementById("results").style.display="";
document.getElementById("scan").disabled=false;
document.getElementById("getinfo").style.visibility="hidden";
document.getElementById("getinfo").style.display="none";
gotdata = rv.data;
if ( gotdata == "1" )
{
document.getElementById("noresults").style.visibility="hidden";
document.getElementById("noresults").style.display="none";
document.getElementById("selected").style.visibility="visible";
document.getElementById("selected").style.display="";
clearListul("hotList1");
netdata = rv.network;
netmcc = rv.mccmnc;
netlong = rv.long;
netavail = rv.avail;
hotv = 0;
indx = parseInt(rv.indx);
indxx = 0;
for (i = 0; i < indx; i++) {
txtline = netdata[i];
if (netlong[i] == "2")
{
hotv = i;
}
txtline = txtline.replace(/ /g,"\240");
var ul = document.getElementById("hotList1");
var li = document.createElement('li');
lix = indxx + 1;
li.id = 'li' + lix;
li.setAttribute('onclick', "testclk(" + lix + ")");
li.appendChild(document.createTextNode(txtline));
ul.appendChild(li);
indxx = indxx + 1;
}
ulselect = hotv + 1;
id = "li" + ulselect;
document.getElementById(id).style.backgroundColor = '#4686fe';
document.getElementById(id).style.color = 'white';
document.getElementById("selnet").innerHTML=netavail[hotv];
if ( netlong[hotv] == "2" )
{
document.getElementById("change").disabled=true;
}
else
{
document.getElementById("change").disabled=false;
}
}
else
{
document.getElementById("noresults").style.visibility="visible";
document.getElementById("noresults").style.display="";
document.getElementById("selected").style.visibility="hidden";
document.getElementById("selected").style.display="none";
}
}
);
}
function testclk(row)
{
var num = indx+1;
for (i = 1; i <= num; i++) {
id = "li" + i;
if ( document.getElementById(id) != null )
{
document.getElementById(id).style.backgroundColor = 'inherit';
document.getElementById(id).style.color = 'inherit';
}
}
id = "li" + row;
ulselect = row;
document.getElementById(id).style.backgroundColor = '#4686fe';
document.getElementById(id).style.color = 'white';
s = ulselect-1;
selectline = s;
document.getElementById('selnet').innerHTML=netavail[s];
if ( netlong[s] == "2" )
{
document.getElementById("change").disabled=true;
}
else
{
document.getElementById("change").disabled=false;
}
}
function changenet(btn)
{
var s = ulselect-1;
mmc = netmcc[s];
if ( confirm("<%:Modem will be restarted to change to new network. Continue?%>") )
{
XHR.get('<%=luci.dispatcher.build_url("admin", "netroam", "connect")%>',
{ set: mmc },
function(x, rv)
{
}
);
}
}
//]]></script>
<form method="post" action="<%=REQUEST_URI%>">
<div class="cbi-map" id="cbi-modem">
<h2><a id="content" name="content"><%:Network Selection%></a></h2>
<div class="cbi-map-descr"> </div>
<head>
<style>
ul.select {
list-style: none;
margin: 0;
padding: 2px;
border: 1px solid grey;
}
ul.select li {
padding: 2px 6px;
}
ul.select li:hover {
background-color: #ccc;
cursor: pointer;
}
ul.select li.selected {
background-color: blue;
color: white;
}
</style>
</head>
<fieldset class="cbi-section" id="scanning">
<legend><%:Scanning%></legend>
<table border="0" id="noconnect" style="visibility:hidden;">
<tr>
<td width="5%"></td>
<td width="35%"><div align="center" style="font-size : 17px" id="backbw"><strong><%:Modem must be connected to scan for networks%></strong></div></td>
<td width="60%"></td>
</tr>
</table>
<table border="0" id="scansec" style="visibility:hidden;">
<tr>
<td width="5%"></td>
<td width="15%"><input type="button" id="scan" class="cbi-button cbi-button-apply" value="<%:Scan for Networks%>" onclick="return scannet(this)" /></td>
<td width="80%"></td>
</tr>
</table>
<table width="900" id="getinfo" border="0" style="visibility:hidden;" >
<tr>
<tr>
<td width="5%"></td>
<td width="25%" id="gps_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /><strong><%:Scanning for Networks ... Please wait.%></strong>
</td>
<td width="70%"></td>
</tr>
</tr>
</table>
</fieldset>
<fieldset class="cbi-section" id="results" style="visibility:hidden;">
<legend><%:Networks Found%></legend>
<table border="0" id="noresults" style="visibility:hidden;">
<tr>
<td width="5%"></td>
<td width="35%"><div align="center" style="font-size : 17px" ><strong><%:No Networks Found, Retry Scan%></strong></div></td>
<td width="60%"></td>
</tr>
</table>
<ul class="select" id="hotList1" style="width:800px; font-size: 20px; font-family:monospace;">
</ul>
<table width="550" border="0">
<tr>
<td width="100%">&nbsp;</td>
</tr>
</table>
<table border="0" id="selected" style="visibility:hidden;">
<tr>
<td width="10%"><div align="left" style="font-size : 17px" ><strong><%:Selected Network%></strong></div></td>
<td width="10%"><div align="left" style="font-size : 17px"id="selnet" ></div></td>
<td width="15%"><input type="button" id="change" class="cbi-button cbi-button-apply" value="<%:Change to Network%>" onclick="return changenet(this)" /></td>
<td width="45%"></td>
</tr>
</table>
</fieldset>
</form>
<%+footer%>

View File

@ -1,136 +0,0 @@
#!/usr/bin/lua
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
lang = trim(arg[1])
copseq = "/tmp/copseq"
netw = {}
netwa = {}
long = {}
mccmnc = {}
freq = {}
germ = 0
file = io.open(copseq, "r")
i = 0
repeat
line = file:read("*line")
if line == nil then
break
end
if line == "2" then
if lang == "de" then
netw[i] = "( Aktuelles Netzwerk )"
else
netw[i] = "( Current Network )"
end
end
if line == "1" then
if lang == "de" then
netw[i] = "( Verfügbares Netzwerk )"
else
netw[i] = "( Availible Network )"
end
end
if line == "3" then
if lang == "de" then
netw[i] = "( Verbotenes Netzwerk )"
else
netw[i] = "( Forbidden Network )"
end
end
if line == "0" then
if lang == "de" then
netw[i] = "( Unbekanntes Netzwerk )"
else
netw[i] = "( Unknown Network )"
end
end
netwa[i] = line
line = file:read("*line")
long[i] = line
line = file:read("*line")
line = file:read("*line")
mccmnc[i] = line
line = file:read("*line")
freq[i] = line
i = i + 1
until 1==0
file:close()
maxlen = 0
for j = 0, i-1 do
nlen = string.len(long[j])
if nlen > maxlen then
maxlen = nlen
end
end
for j = 0, i-1 do
name = long[j] .. " "
long[j] = string.sub(name, 1, maxlen + 1)
end
list = 0
netfnd = {}
netmcc = {}
netfreq = {}
netavail = {}
netlong = {}
for j = 0, i-1 do
if list == 0 then
netfnd[list] = long[j] .. netw[j] .. " "
netmcc[list] = mccmnc[j]
netfreq[list] = freq[j]
netavail[list] = netwa[j]
netlong[list] = long[j]
list = list + 1
else
match = 0
for k = 0, list-1 do
if mccmnc[j] == netmcc[k] then
match = 1
indx = k
break
end
end
if match == 1 then
k = indx
if netfreq[k] == "7" and freq[j] == "2" then
netfreq[k] = "9"
end
if netfreq[k] == "2" and freq[j] == "7" then
netfreq[k] = "9"
end
else
netfnd[list] = long[j] .. netw[j] .. " "
netmcc[list] = mccmnc[j]
netfreq[list] = freq[j]
netavail[list] = netwa[j]
netlong[list] = long[j]
list = list + 1
end
end
end
tfile = io.open(copseq .. "xx", "w")
file = io.open(copseq .. "mc", "w")
lfile = io.open(copseq .. "lg", "w")
afile = io.open(copseq .. "av", "w")
for k = 0, list-1 do
if netfreq[k] == "9" then
netfnd[k] = netfnd[k] .. "3G/LTE MCC/MNC - " .. string.sub(netmcc[k], 1, 3) .. " " .. string.sub(netmcc[k], 4)
end
if netfreq[k] == "2" then
netfnd[k] = netfnd[k] .. "3G MCC/MNC - " .. string.sub(netmcc[k], 1, 3) .. " " .. string.sub(netmcc[k], 4)
end
if netfreq[k] == "7" then
netfnd[k] = netfnd[k] .. "LTE MCC/MNC - " .. string.sub(netmcc[k], 1, 3) .. " " .. string.sub(netmcc[k], 4)
end
tfile:write(netfnd[k], "\n")
file:write(netmcc[k], "\n")
lfile:write(netavail[k], "\n")
afile:write(netlong[k], "\n")
end
tfile:close()
file:close()
lfile:close()
afile:close()

View File

@ -1,53 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
logger -t "ROAM" "$@"
}
mccmnc=$1
log "Disconnect modem"
CURRMODEM=1
uci set modem.modem$CURRMODEM.connected=0
uci commit modem
INTER=$(uci get modem.modeminfo$CURRMODEM.inter)
jkillall getsignal$CURRMODEM
rm -f $ROOTER_LINK/getsignal$CURRMODEM
jkillall con_monitor$CURRMODEM
rm -f $ROOTER_LINK/con_monitor$CURRMODEM
ifdown wan$INTER
PROT=$(uci get modem.modem$CURRMODEM.proto)
CPORT=$(uci get modem.modem$CURRMODEM.commport)
case $PROT in
"30" )
ATCMDD="AT+CFUN=0"
$ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD"
;;
"3" )
WDMNX=$(uci get modem.modem$CURRMODEM.wdm)
umbim -n -t 3 -d /dev/cdc-wdm$WDMNX disconnect
;;
* )
$ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "reset.gcom" "$CURRMODEM"
;;
esac
log "Lock to network"
mcc=${mccmnc:0:3}
mnc=${mccmnc:3}
ATCMDD="AT+COPS=1,2,\"$mccmnc\",7"
echo "ATCMDD=\"$ATCMDD\"" > /tmp/rlock
log "Reconnect Modem"
$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM 1 &

View File

@ -1,62 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
logger -t "ROAM" "$@"
}
CURRMODEM=1
CPORT=$(uci get modem.modem$CURRMODEM.commport)
connect=$(uci get modem.modem$CURRMODEM.connected)
if [ "$connect" != "1" ]; then
exit 0
fi
ATCMDD="AT+COPS=?"
#export TIMEOUT="120"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
#export TIMEOUT="5"
OX=$(echo "$OX " | sed -e "s!+COPS: !+COPS:,!g")
OX=$(echo "$OX" | grep "+COPS:")
if [ -z "$OX" ]; then
rm -f /tmp/copseq
exit 0
fi
CNT=2
rm -f /tmp/copseq
while [ true ]; do
CCNT=$CNT
AVAIL=$(echo $OX | cut -d, -f$CCNT)
NXT=$(echo "$AVAIL" | grep "(")
if [ ! -z "$NXT" ]; then
AVAIL="${AVAIL#(}"
let "CCNT=$CCNT+1"
LONG=$(echo $OX | cut -d, -f$CCNT)
temp="${LONG%\"}"
LONG="${temp#\"}"
let "CCNT=$CCNT+1"
SHORT=$(echo $OX | cut -d, -f$CCNT)
temp="${SHORT%\"}"
SHORT="${temp#\"}"
let "CCNT=$CCNT+1"
NUMER=$(echo $OX | cut -d, -f$CCNT)
temp="${NUMER%\"}"
NUMER="${temp#\"}"
let "CCNT=$CCNT+1"
ACT=$(echo $OX | cut -d, -f$CCNT)
ACT="${ACT%)}"
echo "$AVAIL" >> /tmp/copseq
echo "$LONG" >> /tmp/copseq
echo "$SHORT" >> /tmp/copseq
echo "$NUMER" >> /tmp/copseq
echo "$ACT" >> /tmp/copseq
let "CNT=$CCNT+1"
else
break
fi
done
lang=$(uci -q get luci.main.lang)
/usr/lib/netroam/compress.lua $lang

View File

@ -1,18 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
logger -t "ROAM" "$@"
}
CURRMODEM=$1
CPORT=$(uci get modem.modem$CURRMODEM.commport)
if [ -e /tmp/rlock ]; then
source /tmp/rlock
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
log "$OX"
rm -f /tmp/rlock
fi

View File

@ -1,34 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=ext-simplegps
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/ext-simplegps
SECTION:=utils
CATEGORY:=ROOter
SUBMENU:=Optional Applications
DEPENDS:=+msmtp
TITLE:=support for gps
PKGARCH:=all
endef
define Package/ext-simplegps/description
Helper scripts to enable gps
endef
define Build/Compile
endef
define Package/ext-simplegps/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,ext-simplegps))

View File

@ -1 +0,0 @@
0

View File

@ -1,26 +0,0 @@
#!/usr/bin/lua
ldeg = arg[1]
lmin = arg[2]
lsecd = arg[3]
lhemi = arg[4]
sect = arg[5]
lmin = lmin / 60
if sect == nil then
lsecd = (lsecd * 6) /1000
end
lsec = lsecd / 3600
ldegree = ldeg + lmin + lsec
if lhemi == "S" then
ldegree = -ldegree
end
if lhemi == "W" then
ldegree = -ldegree
end
sdeg = string.format("%.4f",ldegree)
local tfile = io.open("/tmp/latlon", "w")
tfile:write("CONVERT=\"", sdeg, "\"")
tfile:close()

View File

@ -1,75 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
logger -t "GPS" "$@"
}
ifname1="ifname"
if [ -e /etc/newstyle ]; then
ifname1="device"
fi
chksierra() {
SIERRAID=0
if [ $idV = 1199 ]; then
case $idP in
"68aa"|"68a2"|"68a3"|"68a9"|"68b0"|"68b1" )
SIERRAID=1
;;
"68c0"|"9040"|"9041"|"9051"|"9054"|"9056"|"90d3" )
SIERRAID=1
;;
"9070"|"907b"|"9071"|"9079"|"901c"|"9091"|"901f"|"90b1" )
SIERRAID=1
;;
esac
elif [ $idV = 114f -a $idP = 68a2 ]; then
SIERRAID=1
elif [ $idV = 413c -a $idP = 81a8 ]; then
SIERRAID=1
elif [ $idV = 413c -a $idP = 81b6 ]; then
SIERRAID=1
fi
}
CURRMODEM=$1
idV=$(uci -q get modem.modem$CURRMODEM.idV)
idP=$(uci -q get modem.modem$CURRMODEM.idP)
CPORT=$(uci get modem.modem$CURRMODEM.commport)
log "Running GPS script"
QUECTEL=false
if [ "$idV" = "2c7c" ]; then
QUECTEL=true
elif [ "$idV" = "05c6" ]; then
QUELST="9090,9003,9215"
if [[ $(echo "$QUELST" | grep -o "$idP") ]]; then
QUECTEL=true
fi
fi
if $QUECTEL; then
if [ -e /usr/lib/gps/quectel.sh ]; then
result=`ps | grep -i "quectel.sh" | grep -v "grep" | wc -l`
if [ $result -lt 1 ]; then
/usr/lib/gps/quectel.sh $CURRMODEM &
fi
fi
return
fi
chksierra
if [ $SIERRAID -eq 1 ]; then
if [ -e /usr/lib/gps/sierra.sh ]; then
result=`ps | grep -i "sierra.sh" | grep -v "grep" | wc -l`
if [ $result -lt 1 ]; then
/usr/lib/gps/sierra.sh $CURRMODEM &
fi
fi
return
fi

View File

@ -1,23 +0,0 @@
#!/bin/sh
CURRMODEM=$1
ROOTER=/usr/lib/rooter
CPORT=$(uci get modem.modem$CURRMODEM.commport)
PID=$(ps | grep "[q]uectel.sh $CURRMODEM" | awk '{print $1}')
if [ -n "$PID" ]; then
kill -9 $PID
ATCMDD="AT+QGPSEND"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
rm -f /tmp/gps
rm -f /tmp/gpsdata
rm -f /tmp/gpsdata1
fi
PID=$(ps | grep "[s]ierra.sh $CURRMODEM" | awk '{print $1}')
if [ -n "$PID" ]; then
kill -9 $PID
ATCMDD="AT!GPSEND=0"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
rm -f /tmp/gps
rm -f /tmp/gpsdata
rm -f /tmp/gpsdata1
fi

View File

@ -1,92 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
logger -t "Quectel GPS" "$@"
}
OX=$1
if [ -z "$OX" ]; then
if [ -e /tmp/lastgps ]; then
OX=$(cat /tmp/lastgps)
else
exit 0
fi
else
OX=$(cat /tmp/gpsox)
echo "$OX" > /tmp/lastgps
fi
O=$(echo "$OX" | grep "+QGPSLOC:")
if [ -z "$O" ]; then
exit 0
fi
OX=$(echo $O" " | tr ":" ",")
LAT=$(echo $OX | cut -d, -f3)
LON=$(echo $OX | cut -d, -f4)
llen=$(expr length "$LAT")
if [ $llen -eq 10 ]; then
LAT="0"$LAT
fi
if [ $llen -eq 9 ]; then
LAT="00"$LAT
fi
llen=$(expr length "$LON")
if [ $llen -eq 10 ]; then
LON="0"$LON
fi
if [ $llen -eq 9 ]; then
LON="00"$LON
fi
latdeg=${LAT:0:3}
latmin=${LAT:3:2}
latsec=${LAT:6:4}
lathemi=${LAT:10:1}
londeg=${LON:0:3}
lonmin=${LON:3:2}
lonsec=${LON:6:4}
lonhemi=${LON:10:1}
lathemid=$lathemi
lonhemid=$lonhemi
let "latsecd=$latsec*6/1000"
let "lonsecd=$lonsec*6/1000"
latdeg="${latdeg#"${latdeg%%[!0]*}"}"
latmin="${latmin#"${latmin%%[!0]*}"}"
if [ $lathemi = "S" ]; then
lathemi="South"
else
lathemi="North"
fi
delatitude=$latdeg" Deg "$latmin" Min "$latsecd" Sec "$lathemi
if [ $lonhemi = "E" ]; then
lonhemi="East"
else
lonhemi="West"
fi
londeg="${londeg#"${londeg%%[!0]*}"}"
lonmin="${lonmin#"${lonmin%%[!0]*}"}"
delongitude=$londeg" Deg "$lonmin" Min "$lonsecd" Sec "$lonhemi
/usr/lib/gps/convert.lua $latdeg $latmin $latsec $lathemid
source /tmp/latlon
dlatitude=$CONVERT
/usr/lib/gps/convert.lua $londeg $lonmin $lonsec $lonhemid
source /tmp/latlon
dlongitude=$CONVERT
lat="$delatitude ( $dlatitude )"
long="$delongitude ( $dlongitude )"
echo 'LATITUDE="'"$lat"'"' >> /tmp/gpsdata
echo 'LONGITUDE="'"$long"'"' >> /tmp/gpsdata
echo "$lat" > /tmp/gpsdata1
echo "$long" >> /tmp/gpsdata1
echo "0" > /tmp/gps

View File

@ -1,77 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
logger -t "Quectel GPS" "$@"
}
OX=$1
if [ -z "$OX" ]; then
if [ -e /tmp/lastgps ]; then
OX=$(cat /tmp/lastgps)
else
exit 0
fi
else
OX=$(cat /tmp/gpsox)
echo "$OX" > /tmp/lastgps
fi
O=$(echo "$OX" | grep "at!gpsloc?")
if [ -z "$O" ]; then
exit 0
fi
CURRMODEM=1
CPORT=$(uci get modem.modem$CURRMODEM.commport)
ATCMDD="at!gpssatinfo?"
OY=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
echo "$OY" > /tmp/satgps
Y=$(cat /tmp/satgps)
OY=$(echo $Y" " | tr " " ",")
OX=$(echo $OX" " | tr " " ",")
LATD=$(echo $OX | cut -d, -f3)
LATM=$(echo $OX | cut -d, -f5)
LATS=$(echo $OX | cut -d, -f7)
LATH=$(echo $OX | cut -d, -f9)
LOND=$(echo $OX | cut -d, -f12)
LONM=$(echo $OX | cut -d, -f14)
LONS=$(echo $OX | cut -d, -f16)
LONH=$(echo $OX | cut -d, -f18)
lathemid=$LATH
lonhemid=$LONH
if [ $LATH = "S" ]; then
LATH="South"
else
LATH="North"
fi
if [ $LONH = "E" ]; then
LONH="East"
else
LONH="West"
fi
delatitude=$LATD" Deg "$LATM" Min "$LATS" Sec "$LATH
delongitude=$LOND" Deg "$LONM" Min "$LONS" Sec "$LONH
/usr/lib/gps/convert.lua $LATD $LATM $LATS $lathemid 1
source /tmp/latlon
dlatitude=$CONVERT
/usr/lib/gps/convert.lua $LOND $LONM $LONS $lonhemid 1
source /tmp/latlon
dlongitude=$CONVERT
lat="$delatitude ( $dlatitude )"
long="$delongitude ( $dlongitude )"
echo 'LATITUDE="'"$lat"'"' >> /tmp/gpsdata
echo 'LONGITUDE="'"$long"'"' >> /tmp/gpsdata
echo "$lat" > /tmp/gpsdata1
echo "$long" >> /tmp/gpsdata1
echo "0" > /tmp/gps

View File

@ -1,61 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
logger -t "Quectel GPS" "$@"
}
ifname1="ifname"
if [ -e /etc/newstyle ]; then
ifname1="device"
fi
CURRMODEM=$1
if [ $CURRMODEM = "2" ]; then
exit 0
fi
CPORT=$(uci get modem.modem$CURRMODEM.commport)
rm -f /tmp/gps
rm -f /tmp/lastgps
if [ -z "$CPORT" ]; then
exit 0
fi
ATCMDD="AT+QGPS?"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
err=$(echo "$OX" | grep "+QGPS: 1")
if [ -z "$err" ]; then
ATCMDD="AT+QGPS=1"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
fi
log "GPS setup and waiting"
ATCMDD="AT+QCFG=\"gpsdrx\""
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
err=$(echo "$OX" | grep "0")
if [ -n "$err" ]; then
ATCMDD="AT+QCFG=\"gpsdrx\",1"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
fi
ATCMDD="AT+QGPSCFG=\"outport\",\"none\""
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
while true; do
refresh=30
ATCMDD="AT+QGPSLOC=0"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
err=$(echo "$OX" | grep "ERROR")
if [ -z "$err" ]; then
echo "$OX" > /tmp/gpsox
result=`ps | grep -i "processq.sh" | grep -v "grep" | wc -l`
if [ $result -lt 1 ]; then
/usr/lib/gps/processq.sh 1
fi
sleep $refresh
else
sleep 5
fi
done

View File

@ -1,64 +0,0 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
logger -t "Sierra GPS" "$@"
}
ifname1="ifname"
if [ -e /etc/newstyle ]; then
ifname1="device"
fi
CURRMODEM=$1
CPORT=$(uci get modem.modem$CURRMODEM.commport)
rm -f /tmp/gps
rm -f /tmp/lastgps
if [ -z "$CPORT" ]; then
exit 0
fi
ATCMDD="AT!CUSTOM?"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
GPSsel=$(echo $OX | grep "GPSSEL")
GPSenable=$(echo $OX | grep "GPSENABLE")
if [ -z "$GPSsel" -o -z "$GPSenable" ]; then
ATCMDD="AT!ENTERCND=\"A710\""
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
if [ -z "$GPSsel" ]; then
ATCMDD="at!custom=\"GPSSEL\",1"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
fi
if [ -z "$GPSenable" ]; then
ATCMDD="at!custom=\"GPSENABLE\",1"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
ATCMDD="AT+CFUN=0;+CFUN=1,1"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
exit
fi
ATCMDD="AT!ENTERCND=\"AWRONG\""
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
fi
ATCMDD="AT!GPSTRACK=1,240,30,1000,5"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
while true; do
refresh=30
ATCMDD="at!gpsloc?"
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
err=$(echo "$OX" | grep "Not Available")
if [ -z "$err" ]; then
echo "$OX" > /tmp/gpsox
result=`ps | grep -i "processs.sh" | grep -v "grep" | wc -l`
if [ $result -lt 1 ]; then
/usr/lib/gps/processs.sh 1
fi
sleep $refresh
else
sleep 5
fi
done

View File

@ -1,63 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
# Copyright (C) 2022 BlueWave Projects and Services <licence@blue-wave.net>
#
include $(TOPDIR)/rules.mk
PKG_NAME:=mesh11sd
PKG_VERSION:=1.2.0
PKG_RELEASE:=$(AUTORELEASE)
PKG_MAINTAINER:=Rob White <rob@blue-wave.net>
PKG_LICENSE:=GPL-2.0-or-later
PKG_LICENSE_FILES:=LICENSE
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/opennds/mesh11sd/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=b719eaacf63eb3684d0cd6a026f4357a4f400f2339f5d5a6cf74ba3744fe30d8
PKG_BUILD_DIR:=$(BUILD_DIR)/mesh11sd-$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
define Package/mesh11sd
SUBMENU:=Captive Portals
SECTION:=net
CATEGORY:=Network
TITLE:=Dynamic 802.11s Mesh Configuration Daemon
PKGARCH:=all
URL:=https://github.com/opennds/mesh11sd
endef
define Package/mesh11sd/description
Mesh11sd is a dynamic parameter configuration daemon for 802.11s mesh networks.
It was originally designed to leverage 802.11s mesh networking at Captive Portal venues.
This is the open source version and it enables easy and automated mesh network operation with multiple mesh nodes.
It allows all mesh parameters supported by the wireless driver to be set in the uci config file.
Settings take effect immediately without having to restart the wireless network.
Default settings give rapid and reliable layer 2 mesh convergence.
Without mesh11sd, many mesh parameters cannot be set in the uci wireless config file as the mesh interface must be up before the parameters can be set.
Some of those that are supported, would fail to be implemented when the network is (re)started resulting in errors or dropped nodes.
The mesh11sd daemon dynamically checks configured parameters and sets them as required.
This version does not require a Captive Portal to be running.
endef
define Package/mesh11sd/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/mesh11sd $(1)/usr/sbin
$(INSTALL_CONF) $(PKG_BUILD_DIR)/linux_openwrt/mesh11sd/files/etc/config/mesh11sd $(1)/etc/config/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/linux_openwrt/mesh11sd/files/etc/init.d/mesh11sd $(1)/etc/init.d/
endef
define Package/mesh11sd/conffiles
/etc/config/mesh11sd
endef
define Build/Compile
endef
$(eval $(call BuildPackage,mesh11sd))

View File

@ -1,42 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=speedtestpp
PKG_VERSION:=1.14
PKG_RELEASE:=$(AUTORELEASE)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/taganaka/SpeedTest.git
PKG_SOURCE_DATE:=2021-12-06
PKG_SOURCE_VERSION:=0f63cfbf7ce8d64ea803bf143b957eae76323405
PKG_MIRROR_HASH:=4221584dc3e1e31f2560ef347298a2bcca3ac2331049970b7bd7d742e4e1825f
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
PKG_LICENSE:=MIT
CMAKE_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
include $(INCLUDE_DIR)/cmake.mk
CMAKE_OPTIONS += -DCMAKE_BUILD_TYPE=Release .
define Package/speedtestpp
SECTION:=net
CATEGORY:=Network
TITLE:=speedtest++
DEPENDS:=+libcurl +libxml2 +libopenssl +libstdcpp $(ICONV_DEPENDS)
CONFLICTS:=python3-speedtest-cli
URL:=https://github.com/taganaka/SpeedTest
endef
define Package/speedtestpp/description
Yet another unofficial speedtest.net client cli interface
endef
define Package/speedtestpp/install
$(INSTALL_DIR) $(1)/usr/bin
$(CP) $(PKG_INSTALL_DIR)/usr/bin/SpeedTest $(1)/usr/bin/speedtest
endef
$(eval $(call BuildPackage,speedtestpp))

View File

@ -2,12 +2,8 @@
module("luci.controller.schedule", package.seeall) module("luci.controller.schedule", package.seeall)
I18N = require "luci.i18n"
translate = I18N.translate
function index() function index()
local page local page
page = entry({"admin", "services", "schedule"}, cbi("schedule"), _("Scheduled Reboot"), 61)
page = entry({"admin", "services", "schedule"}, cbi("schedule"), _(translate("Scheduled Reboot")), 61)
page.dependent = true page.dependent = true
end end

View File

@ -23,8 +23,8 @@ o = d1:option(DummyValue, "zonename", translate("Timezone : "), translate("Be su
d = m:section(TypedSection, "reboot", " ") d = m:section(TypedSection, "reboot", " ")
c1 = d:option(ListValue, "enable", " "); c1 = d:option(ListValue, "enable", " ");
c1:value("0", translate("Disabled")) c1:value("0", "Disabled")
c1:value("1", translate("Enabled")) c1:value("1", "Enabled")
c1.default=0 c1.default=0
sdhour = d:option(ListValue, "sdhour", translate("Reboot Time :")) sdhour = d:option(ListValue, "sdhour", translate("Reboot Time :"))

View File

@ -24,7 +24,7 @@ if [ $PARM = "1" ]; then
let "TH = $HOUR * 4" let "TH = $HOUR * 4"
let "TMP1 = $SDHOUR - $TH" let "TMP1 = $SDHOUR - $TH"
let "MIN = $TMP1 * 15" let "MIN = $TMP1 * 15"
echo "$MIN $HOUR * * * sleep 70 && touch /etc/banner && /usr/lib/rooter/luci/rebootmodem.sh" > /etc/cronbase echo "$MIN $HOUR * * * sleep 70 && touch /etc/banner && reboot -f" > /etc/cronbase
else else
rm -f /etc/cronbase rm -f /etc/cronbase
fi fi

View File

@ -3,9 +3,6 @@
module("luci.controller.p910ndx", package.seeall) module("luci.controller.p910ndx", package.seeall)
I18N = require "luci.i18n"
translate = I18N.translate
function index() function index()
if not nixio.fs.access("/etc/config/p910nd") then if not nixio.fs.access("/etc/config/p910nd") then
return return
@ -13,6 +10,6 @@ function index()
local page local page
page = entry({"admin", "services", "p910ndx"}, cbi("p910ndx"), _(translate("Print Server")), 60) page = entry({"admin", "services", "p910ndx"}, cbi("p910ndx"), _("Print Server"), 60)
page.dependent = true page.dependent = true
end end

View File

@ -3,15 +3,13 @@
module("luci.controller.hd_idle", package.seeall) module("luci.controller.hd_idle", package.seeall)
I18N = require "luci.i18n"
translate = I18N.translate
function index() function index()
if not nixio.fs.access("/etc/config/hd-idle") then if not nixio.fs.access("/etc/config/hd-idle") then
return return
end end
local page local page
page = entry({"admin", "services", "hd_idle"}, cbi("hd_idle"), _(translate("Hard Drive Idle")), 60)
page = entry({"admin", "services", "hd_idle"}, cbi("hd_idle"), _("Hard Drive Idle"), 60)
page.dependent = true page.dependent = true
end end

View File

@ -1,11 +1,8 @@
module("luci.controller.umount", package.seeall) module("luci.controller.umount", package.seeall)
I18N = require "luci.i18n"
translate = I18N.translate
function index() function index()
local page local page
page = entry({"admin", "services", "umount"}, cbi("umount", {hidesavebtn=true, hideresetbtn=true}), translate("Safely Eject Drive"), 25) page = entry({"admin", "services", "umount"}, cbi("umount", {hidesavebtn=true, hideresetbtn=true}), "Safely Eject Drive", 25)
page.dependent = true page.dependent = true
end end

View File

@ -4,7 +4,8 @@
require("nixio.fs") require("nixio.fs")
m = Map("hd-idle", "Hard Drive Idle", m = Map("hd-idle", "Hard Drive Idle",
translate("This is a utility program for spinning-down external disks after a period of idle time.")) translate("This is a utility program for spinning-down external " ..
"disks after a period of idle time."))
s = m:section(TypedSection, "hd-idle", translate("Settings")) s = m:section(TypedSection, "hd-idle", translate("Settings"))
s.anonymous = true s.anonymous = true

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
log() { log() {
modlog "sdcard" "$@" logger -t "sdcard" "$@"
} }
h721() { h721() {
@ -16,45 +16,62 @@ h721() {
fi fi
} }
ws1208() { wg1608() {
if [ $1 = "add" ]; then if [ $1 = "add" ]; then
echo none > /sys/class/leds/usb/trigger echo timer > /sys/class/leds/zbt-wg3526:green:signal/trigger
echo 1 > /sys/class/leds/usb/brightness echo 1000 > /sys/class/leds/zbt-wg3526:green:signal/delay_on
echo 0 > /sys/class/leds/zbt-wg3526:green:signal/delay_off
else else
echo none > /sys/class/leds/usb/trigger echo timer > /sys/class/leds/zbt-wg3526:green:signal/trigger
echo 0 > /sys/class/leds/usb/brightness echo 0 > /sys/class/leds/zbt-wg3526:green:signal/delay_on
echo 1000 > /sys/class/leds/zbt-wg3526:green:signal/delay_off
fi
}
ws7915() {
if [ $1 = "add" ]; then
echo timer > /sys/class/leds/sys/trigger
echo 1000 > /sys/class/leds/sys/delay_on
echo 0 > /sys/class/leds/sys/delay_off
else
echo timer > /sys/class/leds/sys/trigger
echo 0 > /sys/class/leds/sys/delay_on
echo 1000 > /sys/class/leds/sys/delay_off
fi fi
} }
ws1688() { ws1688() {
if [ $1 = "add" ]; then if [ $1 = "add" ]; then
echo none > /sys/class/leds/usb/trigger echo timer > /sys/class/leds/usb/trigger
echo 1 > /sys/class/leds/usb/brightness echo 1000 > /sys/class/leds/usb/delay_on
echo 0 > /sys/class/leds/usb/delay_off
else else
echo none > /sys/class/leds/usb/trigger echo timer > /sys/class/leds/usb/trigger
echo 0 > /sys/class/leds/usb/brightness echo 0 > /sys/class/leds/usb/delay_on
echo 1000 > /sys/class/leds/usb/delay_off
fi fi
} }
ACTION=$1 ACTION=$1
model=$(cat /tmp/sysinfo/model) model=$(cat /tmp/sysinfo/model)
case $ACTION in case $ACTION in
"add"|"remove" ) "add"|"remove" )
mod=$(echo $model | grep "H721") mod=$(echo $model | grep "H721")
if [ ! -z "$mod" ]; then if [ $mod ]; then
h721 $ACTION h721 $ACTION
fi fi
mod=$(echo $model | grep "WS1208V2") mod=$(echo $model | grep "WG1608")
if [ ! -z "$mod" ]; then if [ $mod ]; then
ws1208 $ACTION wg1608 $ACTION
fi fi
mod=$(echo $model | grep "WS1218") mod=$(echo $model | grep "WS7915")
if [ ! -z "$mod" ]; then if [ $mod ]; then
ws1208 $ACTION ws7915 $ACTION
fi fi
mod=$(echo $model | grep "WS1688") mod=$(echo $model | grep "WS1688")
if [ ! -z "$mod" ]; then if [ $mod ]; then
ws1688 $ACTION ws1688 $ACTION
fi fi
;; ;;

View File

@ -5,15 +5,13 @@ translate = I18N.translate
function index() function index()
local fs = require "nixio.fs" local fs = require "nixio.fs"
local multilock = luci.model.uci.cursor():get("custom", "multiuser", "multi") or "0"
local rootlock = luci.model.uci.cursor():get("custom", "multiuser", "root") or "0"
if (multilock == "0") or (multilock == "1" and rootlock == "1") then
if not fs.stat("/etc/nosms") then if not fs.stat("/etc/nosms") then
local page local page
page = entry({"admin", "modem", "sms"}, template("rooter/sms"), translate("SMS Messaging"), 35) page = entry({"admin", "modem", "sms"}, template("rooter/sms"), translate("短信功能"), 35)
page.dependent = true page.dependent = true
end end
end
entry({"admin", "modem", "check_read"}, call("action_check_read")) entry({"admin", "modem", "check_read"}, call("action_check_read"))
entry({"admin", "modem", "del_sms"}, call("action_del_sms")) entry({"admin", "modem", "del_sms"}, call("action_del_sms"))

View File

@ -27,7 +27,7 @@
document.getElementById('used').innerHTML=""; document.getElementById('used').innerHTML="";
document.getElementById('mslots').innerHTML=""; document.getElementById('mslots').innerHTML="";
document.getElementById('menb').checked=false; document.getElementById('menb').checked=false;
document.getElementById('supported').innerHTML="<%:SMS Not Supported/No Modem%>"; document.getElementById('supported').innerHTML="<%:模块未适配短信支持/未连接到模块%>";
} }
if ( ss == "1" ) if ( ss == "1" )
{ {
@ -37,15 +37,15 @@
document.getElementById('used').innerHTML=""; document.getElementById('used').innerHTML="";
document.getElementById('mslots').innerHTML=""; document.getElementById('mslots').innerHTML="";
document.getElementById('menb').checked=false; document.getElementById('menb').checked=false;
document.getElementById('supported').innerHTML="<%:Waiting to Read Messages%>"; document.getElementById('supported').innerHTML="<%:您有未读的短信,请前往查看%>";
} }
if ( ss == "3" ) if ( ss == "3" )
{ {
document.getElementById('supported').innerHTML="<%:Message Read Problem%>"; document.getElementById('supported').innerHTML="<%:消息读取有问题%>";
} }
if ( ss == "2" ) if ( ss == "2" )
{ {
document.getElementById('supported').innerHTML="<%:Messages Present%>"; document.getElementById('supported').innerHTML="<%:存在的短信%>";
clearListBox("smsList"); clearListBox("smsList");
document.getElementById('total').innerHTML=rv.max; document.getElementById('total').innerHTML=rv.max;
document.getElementById('used').innerHTML=rv.used; document.getElementById('used').innerHTML=rv.used;
@ -75,7 +75,7 @@
} }
if (rv.used == "0") if (rv.used == "0")
{ {
document.getElementById('supported').innerHTML="<%:No Messages Present on SIM%>"; document.getElementById('supported').innerHTML="<%:SIM卡上没有短信%>";
} }
else else
{ {
@ -180,13 +180,13 @@
//document.getElementById('rding').innerHTML=s.length; //document.getElementById('rding').innerHTML=s.length;
if ( s.length == 0 ) if ( s.length == 0 )
{ {
alert("<%:You must enter a phone number!!%>"); alert("<%:请输入电话号码!!%>");
return false; return false;
} }
s = s.trim(); s = s.trim();
if ( isNaN(s) == true ) if ( isNaN(s) == true )
{ {
alert("<%:Invalid phone number!!%>"); alert("<%:错误的电话号码!!%>");
return false; return false;
} }
var num = s.concat(" "); var num = s.concat(" ");
@ -203,7 +203,7 @@
} }
num = num.concat(t); num = num.concat(t);
alert("<%:SMS will be queued for processing.\nA status update will follow.%>"); alert("<%:SMS will be queued for processing.\nA status update will follow.%>");
document.getElementById("sstat").innerHTML="<%:Sending Message. Please Wait%>"; document.getElementById("sstat").innerHTML="<%:状态 消息正在发送%>";
XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "send_sms")%>', XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "send_sms")%>',
{ set: num }, { set: num },
function(x, rv) function(x, rv)
@ -229,15 +229,15 @@
document.getElementById('message').value=""; document.getElementById('message').value="";
document.getElementById('total').innerHTML=""; document.getElementById('total').innerHTML="";
document.getElementById('used').innerHTML=""; document.getElementById('used').innerHTML="";
document.getElementById('supported').innerHTML="<%:Waiting to Read Messages%>"; document.getElementById('supported').innerHTML="<%:您有未读的短信,请前往查看%>";
} }
if ( ss == "3" ) if ( ss == "3" )
{ {
document.getElementById('supported').innerHTML="<%:Message Read Problem%>"; document.getElementById('supported').innerHTML="<%:消息读取有问题%>";
} }
if ( ss == "2" ) if ( ss == "2" )
{ {
document.getElementById('supported').innerHTML="<%:Messages Present%>"; document.getElementById('supported').innerHTML="<%:存在短信%>";
clearListBox("smsList"); clearListBox("smsList");
document.getElementById('total').innerHTML=rv.max; document.getElementById('total').innerHTML=rv.max;
document.getElementById('used').innerHTML=rv.used; document.getElementById('used').innerHTML=rv.used;
@ -284,15 +284,15 @@
function delallsms() function delallsms()
{ {
var r=confirm("<%:Do you really want to delete all SMS?%>"); var r=confirm("<%:是否确定要删除所有短信?%>");
if (r==false) if (r==false)
{ {
return false; return false;
} }
clearListBox("smsList"); clearListBox("smsList");
document.getElementById('message').style.color = "red"; document.getElementById('message').style.color = "red";
document.getElementById('message').value="<%:All Messages will be deleted. It may take some time before the list is updated.%>"; document.getElementById('message').value="<%:将删除所有短信.更新列表可能需要一些时间.%>";
XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "delall_sms")%>', XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "删除所有短信")%>',
null, null,
function() function()
{ {
@ -307,7 +307,7 @@
{ {
return false; return false;
} }
var r=confirm("<%:Delete the selected message?%>"); var r=confirm("<%:确认删除选中消息?%>");
if (r==false) if (r==false)
{ {
return false; return false;
@ -316,7 +316,7 @@
var dx = index[s]; var dx = index[s];
clearListBox("smsList"); clearListBox("smsList");
document.getElementById('message').style.color = "red"; document.getElementById('message').style.color = "red";
document.getElementById('message').value="<%:Message will be deleted. It may take some time before the list is updated.%>"; document.getElementById('message').value="<%:短信将被删除,同步到列表可能会很久(反复提交删除申请一样很久)%>";
XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "del_sms")%>', XHR.get('<%=luci.dispatcher.build_url("admin", "modem", "del_sms")%>',
{ set: dx }, { set: dx },
function() function()
@ -373,7 +373,7 @@
function(x, rv) function(x, rv)
{ {
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Next Modem%>'; btn.value = '<%:下一个模块%>';
} }
); );
@ -416,28 +416,28 @@
<form method="post" action="<%=REQUEST_URI%>"> <form method="post" action="<%=REQUEST_URI%>">
<div class="cbi-map" id="cbi-sms"> <div class="cbi-map" id="cbi-sms">
<h2><a id="content" name="content"><%:SMS Messaging%></a></h2> <h2><a id="content" name="content"><%:短信收发页面%></a></h2>
<div class="cbi-map-descr"><%:Send and Receive Text Messages Through Your Modem%></div> <div class="cbi-map-descr"><%:通过模块发送和接收文本消息%></div>
<fieldset class="cbi-section" id="cbi-read"> <fieldset class="cbi-section" id="cbi-read">
<legend><%:Modem Information%></legend> <legend><%:通信模块信息%></legend>
<table width="550" border="0"> <table width="550" border="0">
<tr> <tr>
<td width="40%"><ul id="supported"></ul></td> <td width="40%"><ul id="supported"></ul></td>
<td width="17%"><strong id="conntype"></strong></td> <td width="17%"><strong id="conntype"></strong></td>
<td width="12%"> <td width="12%">
<input type="button" class="cbi-button cbi-button-apply" value="<%:Prev Modem%>" onclick="return modemtoggledn(this)" /> <input type="button" class="cbi-button cbi-button-apply" value="<%:上一个模块%>" onclick="return modemtoggledn(this)" />
</td> </td>
<td width="31%"> <td width="31%">
<input type="button" class="cbi-button cbi-button-apply" value="<%:Next Modem%>" onclick="return modemtoggle(this)" /> <input type="button" class="cbi-button cbi-button-apply" value="<%:下一个模块%>" onclick="return modemtoggle(this)" />
</td> </td>
</tr> </tr>
</table> </table>
<legend><%:Received Messages%></legend> <legend><%:收到的短信%></legend>
<table width="550" border="0"> <table width="550" border="0">
<tr> <tr>
<td width="18%"><div align="center"><strong><u><%:Total SIM Message Slots%></u></strong></div></td> <td width="18%"><div align="center"><strong><u><%:SIM可存放的短信空间 (条)%></u></strong></div></td>
<td width="18%"><div align="center"><strong><u><%:Used SIM Message Slots%></u></strong></div></td> <td width="18%"><div align="center"><strong><u><%:已使用的SIM短信空间 (条)%></u></strong></div></td>
<td width="34%">&nbsp;</td> <td width="34%">&nbsp;</td>
</tr> </tr>
<tr> <tr>
@ -450,11 +450,11 @@
<table width="550" border="0"> <table width="550" border="0">
<tr> <tr>
<td width="3%">&nbsp;</td> <td width="3%">&nbsp;</td>
<td width="20%"><div align="left"><%:Enable SMS transfer from modem to SIM%></div></td> <td width="20%"><div align="left"><%:启用模块到SIM卡的短信传输%></div></td>
<td width="8%"> <td width="8%">
<input type="checkbox" id="menb" onclick="memenable(this)" /> <input type="checkbox" id="menb" onclick="memenable(this)" />
</td> </td>
<td width="16%"><div align="left"><strong><u><%:Unread SMS count on modem%></u></strong></div></td> <td width="16%"><div align="left"><strong><u><%:模块上的未读信息数量%></u></strong></div></td>
<td width="34%">&nbsp;</td> <td width="34%">&nbsp;</td>
</tr> </tr>
<tr> <tr>
@ -469,18 +469,18 @@
<table width="700" border="0"> <table width="700" border="0">
<tr> <tr>
<td width="3%">&nbsp;</td> <td width="3%">&nbsp;</td>
<td width="17%"><input type="button" id="delallbtn" class="cbi-button cbi-button-remove" value="<%:Delete All Messages%>" onclick="return delallsms()" /></td> <td width="17%"><input type="button" id="delallbtn" class="cbi-button cbi-button-remove" value="<%:删除所有短信%>" onclick="return delallsms()" /></td>
<td width="80%">&nbsp;</td> <td width="80%">&nbsp;</td>
</tr> </tr>
</table> </table>
<table width="700" border="0"> <table width="700" border="0">
<tr> <tr>
<td width="4%"><div align="center"><strong><u><%:Read%></u></strong></div></td> <td width="4%"><div align="center"><strong><u><%:已读状态%></u></strong></div></td>
<td width="18%"><div align="left"><strong><u><%:Sender%></u></strong></div></td> <td width="18%"><div align="left"><strong><u><%:发件人%></u></strong></div></td>
<td width="8%"><div align="left"><strong><u><%:Date%></u></strong></div></td> <td width="8%"><div align="left"><strong><u><%:Date%></u></strong></div></td>
<td width="11%"><div align="left"><strong><u><%:Time%></u></strong></div></td> <td width="11%"><div align="left"><strong><u><%:时间%></u></strong></div></td>
<td width="35%"><div align="left"><strong><u><%:Message%></u></strong></div></td> <td width="35%"><div align="left"><strong><u><%:短信%></u></strong></div></td>
<td width="24%"><div align="left"> </div></td> <td width="24%"><div align="left"> </div></td>
</tr> </tr>
@ -497,7 +497,7 @@
<table width="550" border="0"> <table width="550" border="0">
<tr> <tr>
<td width="7%"><div align="left"><strong><%:Message :%></strong></div></td> <td width="7%"><div align="left"><strong><%:短信内容 :%></strong></div></td>
<!-- <td width="70%"><ul id="message"></ul></td> --> <!-- <td width="70%"><ul id="message"></ul></td> -->
<td width="80%"> <td width="80%">
<textarea readonly="readonly" name="message" id="message" rows="6" style="font-size : 20px;width: 600px;" maxlength="160"></textarea> <textarea readonly="readonly" name="message" id="message" rows="6" style="font-size : 20px;width: 600px;" maxlength="160"></textarea>
@ -508,18 +508,18 @@
<table width="550" border="0"> <table width="550" border="0">
<tr> <tr>
<td width="17%"><input type="button" id="delbtn" class="cbi-button cbi-button-remove" value="<%:Delete Message%>" onclick="return delsms()" /></td> <td width="17%"><input type="button" id="delbtn" class="cbi-button cbi-button-remove" value="<%:删除短信%>" onclick="return delsms()" /></td>
<td width="17%"><input type="button" id="replybtn" class="cbi-button cbi-button-apply" value="<%:Reply to Message%>" onclick="return replysms()" /></td> <td width="17%"><input type="button" id="replybtn" class="cbi-button cbi-button-apply" value="<%:回复短信%>" onclick="return replysms()" /></td>
<td width="17%"><input type="button" id="newbtn" class="cbi-button cbi-button-apply" value="<%:New Message%>" onclick="return newsms()" /></td> <td width="17%"><input type="button" id="newbtn" class="cbi-button cbi-button-apply" value="<%:新建短信%>" onclick="return newsms()" /></td>
<td width="49%">&nbsp;</td> <td width="49%">&nbsp;</td>
</tr> </tr>
</table> </table>
<legend id="sendtitle" style="display:block;"><%:Send Messages%></legend> <legend id="sendtitle" style="display:block;"><%:短信会话%></legend>
<table id="sendmsg" width="600" border="0" style="display:table;"> <table id="sendmsg" width="600" border="0" style="display:table;">
<tr> <tr>
<td width="15%"><div align="left"><strong><%:Send To :%></strong></div></td> <td width="15%"><div align="left"><strong><%:收件人 :%></strong></div></td>
<td width="70%"><input name="sendto" id="sendto" maxlength="20"></input></td> <td width="70%"><input name="sendto" id="sendto" maxlength="20"></input></td>
<td width="15%">&nbsp;</td> <td width="15%">&nbsp;</td>
</tr> </tr>
@ -543,7 +543,7 @@
<table width="550" border="0"> <table width="550" border="0">
<tr> <tr>
<td width="15%"><div align="left"><strong><%:Sending Status :%></strong></div></td> <td width="15%"><div align="left"><strong><%:短信发送状态 :%></strong></div></td>
<td width="70%"><ul style="color:red" id="sstat"></ul></td> <td width="70%"><ul style="color:red" id="sstat"></ul></td>
<td width="15%">&nbsp;</td> <td width="15%">&nbsp;</td>
</tr> </tr>

View File

@ -28,36 +28,42 @@ repeat
message['phone'] = filein:read("*line") message['phone'] = filein:read("*line")
nline = filein:read("*line") nline = filein:read("*line")
message['nline'] = nline message['nline'] = nline
nline = tonumber(nline)
nc = nline
ncntr = 1 ncntr = 1
msg="" msg=""
message['msgnum'] = "xxx" message['msgnum'] = "xxx"
message['msgord'] = "xxx" message['msgord'] = "xxx"
message['msgmax'] = "xxx" message['msgmax'] = "xxx"
lines = filein:read("*line") lines = filein:read("*line")
if lines == nil then s, e = lines:find("Msg# ")
s = nil if s ~= nil then
else bs, be = lines:find(",", e+1)
s, msgnum, msgord, msgmax = lines:match("(Msg# (%d+),(%d+)/(%d+))") msgnum = lines:sub(e+1, be-1)
end
if s == nil then
nc = nc + 1
else
message['msgnum'] = msgnum message['msgnum'] = msgnum
s, e = lines:find("/", be+1)
msgord = lines:sub(be+1, e-1)
message['msgord'] = msgord message['msgord'] = msgord
message['msgmax'] = msgmax message['msgmax'] = lines:sub(e+1)
lines = filein:read("*line") lines = filein:read("*line")
end end
msg = lines msg = lines
nc = tonumber(nline)
if nc > 2 then if nc > 2 then
for i=1,nc-2,1 for i=1,nc-2,1
do do
lines = filein:read("*line") lines = filein:read("*line")
if lines == "" then if lines ~= "" then
msg = msg .. "\n"
else
msg = msg .. "\n" .. lines msg = msg .. "\n" .. lines
else
if i == nc-2 then
if msgord == message['msgmax'] then
msg = msg .. "\n\n"
else
msg = msg .. "\n\n"
end
else
msg = msg .. "\n"
end
end end
end end
--print(nln, msg) --print(nln, msg)
@ -66,9 +72,11 @@ repeat
message['msg'] = msg message['msg'] = msg
message['numlines'] = nc - 1 message['numlines'] = nc - 1
sht = filein:read("*line") sht = filein:read("*line")
s, sht1, sht2 = sht:match("((.*)Msg# %d+,%d+/%d%s*(.*))") s, e = sht:find("Msg#")
if s ~= nil then if s ~= nil then
sht = sht1 .. sht2 shtt = sht:sub(1, s-1)
bs, be = sht:find("/", e)
sht = shtt .. sht:sub(be+2)
end end
message['short'] = sht message['short'] = sht
overall[message['slot']] = message overall[message['slot']] = message
@ -134,43 +142,8 @@ do
end end
fileout:write(msgtmp, "\n") fileout:write(msgtmp, "\n")
fileout:write(overall[tostring(i)]['phone'], "\n") fileout:write(overall[tostring(i)]['phone'], "\n")
if mflg == 0 then
s, preshort = short:match("((.* %d+%-%d+%-%d+ %d+:%d+:%d+%s+[+-]%d+h ))") if mflg ~= 0 then
if preshort ~= nil then
stxt = ''
j = 0
k = 1
ch = ''
while j < 20 do
ch = string.byte(msg:sub(k, k))
if ch == nil then
j = 20
elseif ch == 10 or ch == 13 then
stxt = stxt .. ' '
k = k + 1
elseif ch < 127 then
stxt = stxt .. string.char(ch)
k = k + 1
elseif ch < 0xE0 then
stxt = stxt .. msg:sub(k, k + 1)
k = k + 2
elseif ch < 0xF0 then
stxt = stxt .. msg:sub(k, k + 2)
k = k + 3
else
stxt = stxt .. msg:sub(k, k + 3)
k = k + 4
end
j = j + 1
end
if preshort:sub(1, 1) == ' ' then
jj = 49
else
jj = 51
end
short = (preshort .. ' '):sub(1, jj) .. stxt .. " ..."
end
else
msg = "Partial Message : " .. msg msg = "Partial Message : " .. msg
t = short:gsub("%s+", " ") t = short:gsub("%s+", " ")
short = "Partial Message " .. t short = "Partial Message " .. t
@ -188,3 +161,5 @@ do
end end
end end
fileout:close() fileout:close()

View File

@ -72,11 +72,6 @@ while true; do
SX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD") SX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
USED=$(echo "$SX" | cut -d, -f1 | grep -o "[0-9]\{1,3\}") USED=$(echo "$SX" | cut -d, -f1 | grep -o "[0-9]\{1,3\}")
MESCc="$USED" MESCc="$USED"
if [ -n "$MESCc" -a "$MESCc" != "$MESC" ]; then
MESC=$MESCc
uci set modem.sms.slots=$MESC
uci commit modem
fi
MAXED=$(echo "$SX" | cut -d, -f2 | grep -o "[0-9]\{1,3\}") MAXED=$(echo "$SX" | cut -d, -f2 | grep -o "[0-9]\{1,3\}")
fi fi
if [ $SMSLOC == "SM" ]; then if [ $SMSLOC == "SM" ]; then
@ -84,6 +79,11 @@ while true; do
SX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD") SX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
USED=$(echo "$SX" | cut -d, -f1 | grep -o "[0-9]\{1,3\}") USED=$(echo "$SX" | cut -d, -f1 | grep -o "[0-9]\{1,3\}")
MAXED=$(echo "$SX" | cut -d, -f2 | grep -o "[0-9]\{1,3\}") MAXED=$(echo "$SX" | cut -d, -f2 | grep -o "[0-9]\{1,3\}")
if [ -n "$MESCc" -a "$MESCc" != "$MESC" ]; then
MESC=$MESCc
uci set modem.sms.slots=$MESC
uci commit modem
fi
if [ $USED == $MAXED -a $MEM3 == "SM" ]; then if [ $USED == $MAXED -a $MEM3 == "SM" ]; then
ATCMDD="AT+CPMS=\"SM\",\"SM\",\"ME\"" ATCMDD="AT+CPMS=\"SM\",\"SM\",\"ME\""
OX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD") OX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
@ -101,12 +101,8 @@ while true; do
fi fi
if [ $USED -eq $(uci get modem.modem$CURRMODEM.smsnum) ] && [ $HH -eq $(date +%H) ]; then if [ $USED -eq $(uci get modem.modem$CURRMODEM.smsnum) ] && [ $HH -eq $(date +%H) ]; then
if [ $MEM3 == "SM" -a $USED -lt $MAXED -a $MESC -gt 0 -a $(uci -q get modem.sms.menable) == 1 ]; then if [ $MEM3 == "SM" -a $USED -lt $MAXED -a $MESC -gt 0 -a $(uci -q get modem.sms.menable) == 1 ]; then
ATCMDD="AT+CPMS=\"ME\"" ATCMDD="AT+CPMS=\"ME\";+CMGR=$MESLOT;+CPMS=\"SM\""
OX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD") OX=$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
ATCMDD="AT+CMGR=$MESLOT"
OX=$OX$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
ATCMDD="AT+CPMS=\"SM\""
OX=$OX$($ROOTER/gcom/gcom-locked "$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
Rstat=$(echo "$OX" | grep -o "+CMGR:[^,]\+" | grep -o "[0-3]") Rstat=$(echo "$OX" | grep -o "+CMGR:[^,]\+" | grep -o "[0-3]")
PDU=$(echo "$OX" | grep -o "[0-9A-F]\{30,\}") PDU=$(echo "$OX" | grep -o "[0-9A-F]\{30,\}")
PDUL=$(echo "$OX" | grep -o "+CMGR:.*" | grep -o ",[0-9]\{1,\}" | grep -o "[0-9]\{1,3\}") PDUL=$(echo "$OX" | grep -o "+CMGR:.*" | grep -o ",[0-9]\{1,\}" | grep -o "[0-9]\{1,3\}")

View File

@ -507,9 +507,6 @@ function parseDeliver()
if timezone:sub(-2, -1) == '.0' then if timezone:sub(-2, -1) == '.0' then
timezone = timezone:sub(1, -3) timezone = timezone:sub(1, -3)
end end
if #timezone == 2 then
timezone = ' ' .. timezone
end
m_time = str_buf .. ' ' .. timezone .. 'h' m_time = str_buf .. ' ' .. timezone .. 'h'
m_pdu_ptr = m_pdu_ptr:sub(7) m_pdu_ptr = m_pdu_ptr:sub(7)
if octet2bin_check(m_pdu_ptr) < 0 then if octet2bin_check(m_pdu_ptr) < 0 then

View File

@ -1,15 +1,12 @@
module("luci.controller.guestwifi", package.seeall) module("luci.controller.guestwifi", package.seeall)
I18N = require "luci.i18n"
translate = I18N.translate
function index() function index()
local page local page
if not nixio.fs.access("/etc/config/wireless") then if not nixio.fs.access("/etc/config/wireless") then
return return
end end
page = entry({"admin", "network", "guestwifi"}, cbi("guestwifi", {hidesavebtn=true, hideresetbtn=true}), translate("Guest Wifi"), 22) page = entry({"admin", "network", "guestwifi"}, cbi("guestwifi", {hidesavebtn=true, hideresetbtn=true}), "Guest Wifi", 22)
page.dependent = true page.dependent = true
entry( {"admin", "network", "guestwifi", "edit"}, cbi("guestwifi-edit"), nil ).leaf = true entry( {"admin", "network", "guestwifi", "edit"}, cbi("guestwifi-edit"), nil ).leaf = true

View File

@ -99,12 +99,12 @@ function auto.cfgvalue(self, section)
val = 0 val = 0
end end
if val == "1" then if val == "1" then
return translate("WPA-PSK (Medium Security)") return "WPA-PSK (Medium Security)"
else else
if val == "2" then if val == "2" then
return translate("WPA2-PSK (Strong Security)") return "WPA2-PSK (Strong Security)"
else else
return translate("None") return "None"
end end
end end
end end
@ -118,9 +118,9 @@ function qos.cfgvalue(self, section)
if val == "1" then if val == "1" then
dl_cfg = self.map:get(section, "dl") dl_cfg = self.map:get(section, "dl")
ul_cfg = self.map:get(section, "ul") ul_cfg = self.map:get(section, "ul")
return translate("Download : ") .. dl_cfg .. translate(" Mbit/s / Upload : ") .. ul_cfg .. translate(" Mbit/s") return "Download : " .. dl_cfg .. " Mbit/s / Upload : " .. ul_cfg .. " Mbit/s"
else else
return translate("Disabled") return "Disabled"
end end
end end

View File

@ -339,11 +339,11 @@ _proto_mbim_setup() {
tid=$((tid + 1)) tid=$((tid + 1))
log "Get IP config"
CONFIG=$(umbim $DBG -n -t $tid -d $device config) || { CONFIG=$(umbim $DBG -n -t $tid -d $device config) || {
log "config failed" log "config failed"
return 1 return 1
} }
log "IP config $CONFIG"
IP=$(echo -e "$CONFIG"|grep "ipv4address"|grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)") IP=$(echo -e "$CONFIG"|grep "ipv4address"|grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")
GATE=$(echo -e "$CONFIG"|grep "ipv4gateway"|grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)") GATE=$(echo -e "$CONFIG"|grep "ipv4gateway"|grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")

View File

@ -22,7 +22,7 @@ define Package/rqmi
SECTION:=net SECTION:=net
CATEGORY:=ROOter CATEGORY:=ROOter
SUBMENU:=Drivers SUBMENU:=Drivers
DEPENDS:=+libubox +libblobmsg-json +kmod-usb-net +kmod-usb-net-qmi-wwan +wwan +luci-proto-qmi DEPENDS:=+libubox +libblobmsg-json +kmod-usb-net +kmod-usb-net-qmi-wwan +wwan
TITLE:=Control utility for mobile broadband modems TITLE:=Control utility for mobile broadband modems
endef endef

View File

@ -1,596 +0,0 @@
#!/bin/sh
[ -n "$INCLUDE_ONLY" ] || {
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
}
ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"
log() {
modlog "QMI Connect $CURRMODEM" "$@"
}
log "Starting QMI"
proto_qmi_init_config() {
available=1
no_device=1
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_int delay
proto_config_add_string modes
proto_config_add_string pdptype
proto_config_add_int profile
proto_config_add_boolean dhcp
proto_config_add_boolean dhcpv6
proto_config_add_boolean autoconnect
proto_config_add_int plmn
proto_config_add_int timeout
proto_config_add_int mtu
proto_config_add_defaults
}
proto_qmi_setup() {
local interface="$1"
local dataformat connstat plmn_mode mcc mnc
local device apn auth username password pincode delay modes pdptype
local profile dhcp dhcpv6 autoconnect plmn timeout mtu $PROTO_DEFAULT_OPTIONS
local ip4table ip6table
local cid_4 pdh_4 cid_6 pdh_6
local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6
if [ ! -f /tmp/bootend.file ]; then
return 0
fi
CURRMODEM=$(uci -q get network.$interface.currmodem)
uci set modem.modem$CURRMODEM.connected=0
uci commit modem
rm -f $ROOTER_LINK/reconnect$CURRMODEM
jkillall getsignal$CURRMODEM
rm -f $ROOTER_LINK/getsignal$CURRMODEM
jkillall con_monitor$CURRMODEM
rm -f $ROOTER_LINK/con_monitor$CURRMODEM
jkillall mbim_monitor$CURRMODEM
rm -f $ROOTER_LINK/mbim_monitor$CURRMODEM
json_get_vars device apn auth username password pincode delay modes
json_get_vars pdptype profile dhcp dhcpv6 autoconnect plmn ip4table
json_get_vars ip6table timeout mtu $PROTO_DEFAULT_OPTIONS
case $auth in
"0" )
auth=
;;
"1" )
auth="pap"
;;
"2" )
auth="chap"
;;
"*" )
auth=
;;
esac
[ "$timeout" = "" ] && timeout="10"
[ "$metric" = "" ] && metric="0"
[ -n "$ctl_device" ] && device=$ctl_device
[ -n "$device" ] || {
log "No control device specified"
proto_notify_error "$interface" NO_DEVICE
proto_set_available "$interface" 0
return 1
}
[ -n "$delay" ] && sleep "$delay"
device="$(readlink -f $device)"
[ -c "$device" ] || {
log "The specified control device does not exist"
proto_notify_error "$interface" NO_DEVICE
proto_set_available "$interface" 0
return 1
}
devname="$(basename "$device")"
devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
ifname="$( ls "$devpath"/net )"
[ -n "$ifname" ] || {
log "The interface could not be found."
proto_notify_error "$interface" NO_IFACE
proto_set_available "$interface" 0
return 1
}
[ -n "$mtu" ] && {
log "Setting MTU to $mtu"
/sbin/ip link set dev $ifname mtu $mtu
}
timeout=1
# Cleanup current state if any
uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
# Go online
uqmi -s -d "$device" --set-device-operating-mode online > /dev/null 2>&1
# Set IP format
uqmi -s -d "$device" --set-data-format 802.3 > /dev/null 2>&1
uqmi -s -d "$device" --wda-set-data-format 802.3 > /dev/null 2>&1
if [ $RAW -eq 1 ]; then
dataformat='"raw-ip"'
else
if [ $idV = 1199 -a $idP = 9055 ]; then
$ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "reset.gcom" "$CURRMODEM"
dataformat='"802.3"'
uqmi -s -d "$device" --set-data-format 802.3
uqmi -s -d "$device" --wda-set-data-format 802.3
else
dataformat=$(uqmi -s -d "$device" --wda-get-data-format)
fi
fi
log "WDA-GET-DATA-FORMAT is $dataformat"
if [ "$dataformat" = '"raw-ip"' ]; then
[ -f /sys/class/net/$ifname/qmi/raw_ip ] || {
log "Device only supports raw-ip mode but is missing this required driver attribute: /sys/class/net/$ifname/qmi/raw_ip"
return 1
}
log "Device does not support 802.3 mode. Informing driver of raw-ip only for $ifname .."
echo "Y" > /sys/class/net/$ifname/qmi/raw_ip
fi
uqmi -s -d "$device" --sync > /dev/null 2>&1
uqmi -s -d "$device" --network-register > /dev/null 2>&1
log "Waiting for network registration"
sleep 1
local registration_timeout=0
local registration_state=""
while true; do
registration_state=$(uqmi -s -d "$device" --get-serving-system 2>/dev/null | jsonfilter -e "@.registration" 2>/dev/null)
log "Registration State : $registration_state"
[ "$registration_state" = "registered" ] && break
if [ "$registration_state" = "searching" ] || [ "$registration_state" = "not_registered" ]; then
if [ "$registration_timeout" -lt "$timeout" ] || [ "$timeout" = "0" ]; then
[ "$registration_state" = "searching" ] || {
log "Device stopped network registration. Restart network registration"
uqmi -s -d "$device" --network-register > /dev/null 2>&1
}
let registration_timeout++
sleep 1
continue
fi
log "Network registration failed, registration timeout reached"
else
# registration_state is 'registration_denied' or 'unknown' or ''
log "Network registration failed (reason: '$registration_state')"
fi
proto_notify_error "$interface" NETWORK_REGISTRATION_FAILED
proto_block_restart "$interface"
return 1
done
[ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes" > /dev/null 2>&1
pdptype="ipv4v6"
IPVAR=$(uci -q get modem.modem$CURRMODEM.pdptype)
case "$IPVAR" in
"IP" )
pdptype="ipv4"
;;
"IPV6" )
pdptype="ipv6"
;;
"IPV4V6" )
pdptype="ipv4v6"
;;
esac
pdptype=$(echo "$pdptype" | awk '{print tolower($0)}')
[ "$pdptype" = "ip" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] || pdptype="ip"
if [ "$pdptype" = "ip" ]; then
[ -z "$autoconnect" ] && autoconnect=1
[ "$autoconnect" = 0 ] && autoconnect=""
else
[ "$autoconnect" = 1 ] || autoconnect=""
fi
isplist=$(uci -q get modem.modeminfo$CURRMODEM.isplist)
apn2=$(uci -q get modem.modeminfo$CURRMODEM.apn2)
for isp in $isplist
do
NAPN=$(echo $isp | cut -d, -f2)
NPASS=$(echo $isp | cut -d, -f4)
CID=$(echo $isp | cut -d, -f5)
NUSER=$(echo $isp | cut -d, -f6)
NAUTH=$(echo $isp | cut -d, -f7)
if [ "$NPASS" = "nil" ]; then
NPASS="NIL"
fi
if [ "$NUSER" = "nil" ]; then
NUSER="NIL"
fi
if [ "$NAUTH" = "nil" ]; then
NAUTH="0"
fi
apn=$NAPN
username="$NUSER"
password="$NPASS"
auth=$NAUTH
case $auth in
"0" )
auth="none"
;;
"1" )
auth="pap"
;;
"2" )
auth="chap"
;;
"*" )
auth="none"
;;
esac
if [ ! -e /etc/config/isp ]; then
log "Connect to network using $NAPN"
else
log "Connect to network"
fi
if [ ! -e /etc/config/isp ]; then
log "Connection Parameters : $NAPN $auth $username $password"
fi
conn=0
[ "$pdptype" = "ip" -o "$pdptype" = "ipv4v6" ] && {
cid_4=$(uqmi -s -d "$device" --get-client-id wds)
if ! [ "$cid_4" -eq "$cid_4" ] 2> /dev/null; then
log "Unable to obtain client ID"
fi
}
uqmi -s -d "$device" --set-client-id wds,"$cid_4" --set-ip-family ipv4 > /dev/null 2>&1
v4s=0
pdh_4=$(uqmi -s -d "$device" --set-client-id wds,"$cid_4" \
--start-network \
${apn:+--apn $apn} \
${auth:+--auth-type $auth} \
${username:+--username $username} \
${password:+--password $password} \
${autoconnect:+--autoconnect})
log "IPv4 Connection returned : $pdh_4"
CONN4=$(uqmi -s -d "$device" --set-client-id wds,"$cid_4" --get-current-settings)
log "GET-CURRENT-SETTINGS is $CONN4"
# pdh_4 is a numeric value on success
if ! [ "$pdh_4" -eq "$pdh_4" ] 2> /dev/null; then
log "Unable to connect IPv4"
v4s=0
else
# Check data connection state
v4s=1
conn=1
fi
[ "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && {
cid_6=$(uqmi -s -d "$device" --get-client-id wds)
if ! [ "$cid_6" -eq "$cid_6" ] 2> /dev/null; then
log "Unable to obtain client ID"
#proto_notify_error "$interface" NO_CID
fi
}
uqmi -s -d "$device" --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null 2>&1
v6s=0
pdh_6=$(uqmi -s -d "$device" --set-client-id wds,"$cid_6" \
--start-network \
${apn:+--apn $apn} \
${auth:+--auth-type $auth} \
${username:+--username $username} \
${password:+--password $password} \
${autoconnect:+--autoconnect})
log "IPv6 Connection returned : $pdh_6"
# pdh_6 is a numeric value on success
if ! [ "$pdh_6" -eq "$pdh_6" ] 2> /dev/null; then
log "Unable to connect IPv6"
v6s=0
else
# Check data connection state
CONN6=$(uqmi -s -d "$device" --set-client-id wds,"$cid_6" --get-current-settings)
log "GET-CURRENT-SETTINGS is $CONN6"
v6s=1
conn=1
fi
if [ $conn -eq 1 ]; then
break;
fi
done
if [ $conn -eq 0 ]; then
proto_notify_error "$interface" CALL_FAILED
return 1
else
log "Setting up $ifname"
proto_init_update "$ifname" 1
proto_set_keep 1
proto_add_data
[ -n "$pdh_4" ] && {
json_add_string "cid_4" "$cid_4"
json_add_string "pdh_4" "$pdh_4"
}
[ -n "$pdh_6" ] && {
json_add_string "cid_6" "$cid_6"
json_add_string "pdh_6" "$pdh_6"
}
proto_close_data
proto_send_update "$interface"
zone="$(fw3 -q network "$interface" 2>/dev/null)"
dhcp=0
dhcpv6=0
[ "$v6s" -eq 1 ] && {
if [ -z "$dhcpv6" -o "$dhcpv6" = 0 ]; then
json_load "$(uqmi -s -d $device --set-client-id wds,$cid_6 --get-current-settings)"
json_select ipv6
json_get_var ip_6 ip
json_get_var gateway_6 gateway
json_get_var dns1_6 dns1
json_get_var dns2_6 dns2
json_get_var ip_prefix_length ip-prefix-length
proto_init_update "$ifname" 1
proto_set_keep 1
proto_add_ipv6_address "$ip_6" "128"
proto_add_ipv6_prefix "${ip_6}/${ip_prefix_length}"
proto_add_ipv6_route "$gateway_6" "128"
[ "$defaultroute" = 0 ] || proto_add_ipv6_route "::0" 0 "$gateway_6" "" "" "${ip_6}/${ip_prefix_length}"
[ "$peerdns" = 0 ] || {
proto_add_dns_server "$dns1_6"
proto_add_dns_server "$dns2_6"
}
[ -n "$zone" ] && {
proto_add_data
json_add_string zone "$zone"
proto_close_data
}
proto_send_update "$interface"
v6dns="$dns1_6 $dns2_6"
log "IPv6 address : $ip_6"
log "IPv6 DNS : $v6dns"
else
json_init
json_add_string name "${interface}_6"
json_add_string ifname "@$interface"
json_add_string proto "dhcpv6"
[ -n "$ip6table" ] && json_add_string ip6table "$ip6table"
proto_add_dynamic_defaults
# RFC 7278: Extend an IPv6 /64 Prefix to LAN
json_add_string extendprefix 1
[ -n "$zone" ] && json_add_string zone "$zone"
json_close_object
ubus call network add_dynamic "$(json_dump)"
fi
}
[ "$v4s" -eq 1 ] && {
if [ "$dhcp" = 0 ]; then
json_load "$(uqmi -s -d $device --set-client-id wds,$cid_4 --get-current-settings)"
json_select ipv4
json_get_var ip_4 ip
json_get_var gateway_4 gateway
json_get_var dns1_4 dns1
json_get_var dns2_4 dns2
json_get_var subnet_4 subnet
proto_init_update "$ifname" 1
proto_set_keep 1
proto_add_ipv4_address "$ip_4" "$subnet_4"
proto_add_ipv4_route "$gateway_4" "128"
[ "$defaultroute" = 0 ] || proto_add_ipv4_route "0.0.0.0" 0 "$gateway_4"
[ "$peerdns" = 0 ] || {
proto_add_dns_server "$dns1_4"
proto_add_dns_server "$dns2_4"
}
[ -n "$zone" ] && {
proto_add_data
json_add_string zone "$zone"
proto_close_data
}
proto_send_update "$interface"
log "IPv4 address : $ip_4"
log "IPv4 DNS : $dns1_4 $dns2_4"
else
json_init
json_add_string name "${interface}_4"
json_add_string ifname "@$interface"
json_add_string proto "dhcp"
[ -n "$ip4table" ] && json_add_string ip4table "$ip4table"
proto_add_dynamic_defaults
[ -n "$zone" ] && json_add_string zone "$zone"
json_close_object
ubus call network add_dynamic "$(json_dump)"
fi
}
if [ -n "$ip_6" -a -z "$ip_4" ]; then
log "Running IPv6-only mode"
nat46=1
fi
if [[ $(echo "$ip_6" | grep -o "^[23]") ]]; then
# Global unicast IP acquired
v6cap=1
elif
[[ $(echo "$ip_6" | grep -o "^[0-9a-fA-F]\{1,4\}:") ]]; then
# non-routable address
v6cap=2
else
v6cap=0
fi
if [ $v4s -eq 0 -a $v6s -eq 1 ]; then
INTER=$(uci get modem.modem$CURRMODEM.inter)
if [ "$v6cap" -gt 0 ]; then
zone="$(fw3 -q network "$interface" 2>/dev/null)"
fi
if [ "$v6cap" = 2 ]; then
log "Adding IPv6 dynamic interface"
json_init
json_add_string name "${interface}_6"
json_add_string ${ifname1} "@$interface"
json_add_string proto "dhcpv6"
json_add_string extendprefix 1
[ -n "$zone" ] && json_add_string zone "$zone"
[ "$nat46" = 1 ] || json_add_string iface_464xlat 0
json_add_boolean peerdns 0
json_add_array dns
for DNSV in $(echo "$v6dns"); do
json_add_string "" "$DNSV"
done
json_close_array
proto_add_dynamic_defaults
json_close_object
ubus call network add_dynamic "$(json_dump)"
elif
[ "$v6cap" = 1 -a "$nat46" = 1 ]; then
log "Adding 464XLAT (CLAT) dynamic interface"
json_init
json_add_string name "CLAT$INTER"
json_add_string proto "464xlat"
json_add_string tunlink "${interface}"
[ -n "$zone" ] && json_add_string zone "$zone"
proto_add_dynamic_defaults
json_close_object
ubus call network add_dynamic "$(json_dump)"
fi
fi
if [ -e $ROOTER/modem-led.sh ]; then
$ROOTER/modem-led.sh $CURRMODEM 3
fi
log "Modem $CURRMODEM Connected"
COMMPORT=$(uci get modem.modem$CURRMODEM.commport)
if [ ! -z $COMMPORT ]; then
$ROOTER/sms/check_sms.sh $CURRMODEM &
ln -s $ROOTER/signal/modemsignal.sh $ROOTER_LINK/getsignal$CURRMODEM
# send custom AT startup command
if [ $(uci -q get modem.modeminfo$CURRMODEM.at) -eq "1" ]; then
ATCMDD=$(uci -q get modem.modeminfo$CURRMODEM.atc)
if [ ! -z "${ATCMDD}" ]; then
OX=$($ROOTER/gcom/gcom-locked "/dev/ttyUSB$COMMPORT" "run-at.gcom" "$CURRMODEM" "$ATCMDD")
OX=$($ROOTER/common/processat.sh "$OX")
ERROR="ERROR"
if `echo ${OX} | grep "${ERROR}" 1>/dev/null 2>&1`
then
log "Error sending custom AT command: $ATCMDD with result: $OX"
else
log "Sent custom AT command: $ATCMDD with result: $OX"
fi
fi
fi
fi
ln -s $ROOTER/connect/reconnect.sh $ROOTER_LINK/reconnect$CURRMODEM
$ROOTER_LINK/getsignal$CURRMODEM $CURRMODEM $PROT &
ln -s $ROOTER/connect/conmon.sh $ROOTER_LINK/con_monitor$CURRMODEM
$ROOTER_LINK/con_monitor$CURRMODEM $CURRMODEM &
uci set modem.modem$CURRMODEM.connected=1
uci commit modem
if [ -e $ROOTER/connect/postconnect.sh ]; then
$ROOTER/connect/postconnect.sh $CURRMODEM
fi
if [ -e $ROOTER/timezone.sh ]; then
TZ=$(uci -q get modem.modeminfo$CURRMODEM.tzone)
if [ "$TZ" = "1" ]; then
$ROOTER/timezone.sh &
fi
fi
CLB=1
if [ -e /etc/config/mwan3 ]; then
INTER=$(uci get modem.modeminfo$CURRMODEM.inter)
if [ -z $INTER ]; then
INTER=0
else
if [ $INTER = 0 ]; then
INTER=$CURRMODEM
fi
fi
ENB=$(uci -q get mwan3.wan$CURRMODEM.enabled)
if [ ! -z $ENB ]; then
if [ $CLB = "1" ]; then
uci set mwan3.wan$INTER.enabled=1
else
uci set mwan3.wan$INTER.enabled=0
fi
uci commit mwan3
/usr/sbin/mwan3 restart
fi
fi
rm -f /tmp/usbwait
return 0
fi
}
qmi_wds_stop() {
local cid="$1"
local pdh="$2"
[ -n "$cid" ] || return
uqmi -s -d "$device" --set-client-id wds,"$cid" \
--stop-network 0xffffffff \
--autoconnect > /dev/null 2>&1
[ -n "$pdh" ] && {
uqmi -s -d "$device" --set-client-id wds,"$cid" \
--stop-network "$pdh" > /dev/null 2>&1
}
uqmi -s -d "$device" --set-client-id wds,"$cid" \
--release-client-id wds > /dev/null 2>&1
}
proto_qmi_teardown() {
local interface="$1"
local device cid_4 pdh_4 cid_6 pdh_6
json_get_vars device
[ -n "$ctl_device" ] && device=$ctl_device
log "Stopping network $interface"
json_load "$(ubus call network.interface.$interface status)"
json_select data
json_get_vars cid_4 pdh_4 cid_6 pdh_6
qmi_wds_stop "$cid_4" "$pdh_4"
qmi_wds_stop "$cid_6" "$pdh_6"
proto_init_update "*" 0
proto_send_update "$interface"
}
[ -n "$INCLUDE_ONLY" ] || {
add_protocol qmi
}

View File

@ -0,0 +1,301 @@
#!/bin/sh
ROOTER=/usr/lib/rooter
log() {
modlog "QMI Connect $CURRMODEM" "$@"
}
. /lib/functions.sh
. /lib/netifd/netifd-proto.sh
CURRMODEM=$1
devname=$2
device=/dev/$2
auth=$3
NAPN=$4
username=$5
password=$6
RAW=$7
DHCP=$8
pincode=$9
enb=$(uci -q get custom.connect.ipv6)
if [ -z $enb ]; then
enb="1"
fi
ifname1="ifname"
if [ -e /etc/newstyle ]; then
ifname1="device"
fi
INTER=$(uci -q get modem.modem$CURRMODEM.inter)
interface="wan"$INTER
case $auth in
"0" )
auth="none"
;;
"1" )
auth="pap"
;;
"2" )
auth="chap"
;;
*)
auth="none"
;;
esac
if [ $username = NIL ]; then
username=
fi
if [ $password = NIL ]; then
password=
fi
ifname="$(ls /sys/class/usbmisc/$devname/device/net/)"
#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" || {
log "Unable to verify PIN"
ret=1
}
}
uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect > /dev/null & sleep 5 ; kill -9 $!
uqmi -s -d "$device" --set-device-operating-mode online > /dev/null 2>&1 & sleep 5 ; kill -9 $!
if [ $RAW -eq 1 ]; then
DATAFORM='"raw-ip"'
else
if [ $idV = 1199 -a $idP = 9055 ]; then
$ROOTER/gcom/gcom-locked "/dev/ttyUSB$CPORT" "reset.gcom" "$CURRMODEM"
DATAFORM='"802.3"'
uqmi -s -d "$device" --set-data-format 802.3
uqmi -s -d "$device" --wda-set-data-format 802.3
else
log "getting data format"
DATAFORM=$(uqmi -s -d "$device" --wda-get-data-format)
fi
fi
log "WDA-GET-DATA-FORMAT is $DATAFORM"
if [ "$DATAFORM" = '"raw-ip"' ]; then
[ -f /sys/class/net/$ifname/qmi/raw_ip ] || {
log "Device only supports raw-ip mode but is missing this required driver attribute: /sys/class/net/$ifname/qmi/raw_ip"
ret=1
}
echo "Y" > /sys/class/net/$ifname/qmi/raw_ip
fi
log "Query radio state"
uqmi -s -d "$device" --get-signal-info | grep -q "Information unavailable" & sleep 5 ; kill -9 $!
STATUS=$?
[ "$STATUS" -ne 0 ] || {
sleep 1
log "Setting FCC Auth"
uqmi -s -d "$device" --fcc-auth & sleep 5 ; kill -9 $!
sleep 1
}
uqmi -s -d "$device" --sync > /dev/null 2>&1 & sleep 5 ; kill -9 $!
#uqmi -s -d "$device" --network-register > /dev/null 2>&1
log "Waiting for network registration"
td=0
while uqmi -s -d "$device" --get-serving-system | grep '"searching"' > /dev/null; do
sleep 5;
tid=$((tid + 1))
if [ $tid -gt 2 ]; then
uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect > /dev/null & sleep 10 ; kill -9 $!
exit 1
fi
done
cid=`uqmi -s -d "$device" --get-client-id wds`
[ $? -ne 0 ] && {
log "Unable to obtain client ID"
ret=1
}
uqmi -s -d "$device" --set-client-id wds,"$cid" --set-ip-family ipv4 > /dev/null
isplist=$(uci -q get modem.modeminfo$CURRMODEM.isplist)
apn2=$(uci -q get modem.modeminfo$CURRMODEM.apn2)
for isp in $isplist
do
NAPN=$(echo $isp | cut -d, -f2)
NPASS=$(echo $isp | cut -d, -f4)
CID=$(echo $isp | cut -d, -f5)
NUSER=$(echo $isp | cut -d, -f6)
NAUTH=$(echo $isp | cut -d, -f7)
if [ "$NPASS" = "nil" ]; then
NPASS="NIL"
fi
if [ "$NUSER" = "nil" ]; then
NUSER="NIL"
fi
if [ "$NAUTH" = "nil" ]; then
NAUTH="0"
fi
username="$NUSER"
password="$NPASS"
auth=$NAUTH
case $auth in
"0" )
auth="none"
;;
"1" )
auth="pap"
;;
"2" )
auth="chap"
;;
"*" )
auth="none"
;;
esac
if [ ! -e /etc/config/isp ]; then
log "Connect to network using $NAPN"
else
log "Connect to network"
fi
if [ ! -e /etc/config/isp ]; then
log "$NAPN $auth $username $password"
fi
conn=0
tidd=0
tcnt=4
while true; do
ST=$(uqmi -s -d "$device" --set-client-id wds,"$cid" --start-network ${NAPN:+--apn $NAPN} ${auth:+--auth-type $auth} \
${username:+--username $username} ${password:+--password $password})
log "Connection returned : $ST"
CONN=$(uqmi -s -d "$device" --get-data-status)
log "Status is $CONN"
if [[ $(echo "$CONN" | grep -o "disconnected") ]]; then
sleep 1
tidd=$((tidd + 1))
if [ $tidd -gt $tcnt ]; then
break
fi
else
conn=1
break
fi
done
if [ $conn -eq 1 ]; then
break;
fi
done
if [[ -z $(echo "$CONN" | grep -o "disconnected") ]]; then
ret=0
uci set modem.modem$CURRMODEM.mdevice=$device
uci set modem.modem$CURRMODEM.mcid=$cid
uci set modem.modem$CURRMODEM.mapn=$NAPN
uci set modem.modem$CURRMODEM.mauth=$auth
uci set modem.modem$CURRMODEM.musername=$username
uci set modem.modem$CURRMODEM.mpassword=$password
uci commit modem
CONN4=$(uqmi -s -d "$device" --set-client-id wds,"$cid" --get-current-settings)
log "GET-CURRENT-SETTINGS is $CONN4"
if [ $enb = "1" ]; then
cid6=`uqmi -s -d "$device" --get-client-id wds`
[ $? -ne 0 ] && {
log "Unable to obtain client ID"
ret=1
}
uqmi -s -d "$device" --set-client-id wds,"$cid6" --set-ip-family ipv6 > /dev/null
ST6=$(uqmi -s -d "$device" --set-client-id wds,"$cid6" --start-network ${NAPN:+--apn $NAPN} ${auth:+--auth-type $auth} \
${username:+--username $username} ${password:+--password $password})
log "IPv6 Connection returned : $ST6"
CONN6=$(uqmi -s -d "$device" --set-client-id wds,"$cid6" --get-current-settings)
CONF6=$(jsonfilter -s $CONN6 -e '@.ipv6')
if [ -n "$CONF6" ];then
log "IPv6 settings are $CONF6"
touch /tmp/ipv6supp$INTER
else
rm -f /tmp/ipv6supp$INTER
fi
fi
if [ $DATAFORM = '"raw-ip"' ]; then
log "Handle raw-ip"
json_load "$CONN4"
json_select ipv4
json_get_vars ip subnet gateway dns1 dns2
if [ $enb = "1" ]; then
if [ -n "$CONF6" ]; then
json_load "$CONN6"
json_select ipv6
json_get_var ip_6 ip
json_get_var gateway_6 gateway
json_get_var dns1_6 dns1
json_get_var dns2_6 dns2
json_get_var ip_prefix_length ip-prefix-length
fi
fi
if [ -s /tmp/v4dns$INTER -o -s /tmp/v6dns$INTER ]; then
pdns=1
if [ -s /tmp/v4dns$INTER ]; then
v4dns=$(cat /tmp/v4dns$INTER 2>/dev/null)
fi
if [ $enb = "1" ]; then
if [ -s /tmp/v6dns$INTER ]; then
v6dns=$(cat /tmp/v6dns$INTER 2>/dev/null)
fi
fi
else
v4dns="$dns1 $dns2"
if [ $enb = "1" ]; then
v6dns="$dns1_6 $dns2_6"
echo "$v6dns" > /tmp/v6dns$INTER
fi
fi
if [ $DHCP -eq 0 ]; then
log Applying IP settings to wan$INTER
uci delete network.wan$INTER
uci set network.wan$INTER=interface
uci set network.wan$INTER.proto=static
uci set network.wan$INTER.${ifname1}=$ifname
uci set network.wan$INTER.metric=$INTER"0"
uci set network.wan$INTER.ipaddr=$ip/$subnet
uci set network.wan$INTER.gateway='0.0.0.0'
uci set network.wan$INTER.dns="$v4dns"
uci commit network
uci set modem.modem$CURRMODEM.interface=$ifname
uci commit modem
else
proto_init_update "$ifname" 1
proto_set_keep 1
proto_add_ipv4_address "$ip" "$subnet"
proto_add_ipv4_route "0.0.0.0" 0
for DNSV in $(echo "$v4dns"); do
proto_add_dns_server "$DNSV"
done
proto_send_update "$interface"
fi
fi
else
uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect > /dev/null & sleep 10 ; kill -9 $!
ret=1
fi
exit $ret

View File

@ -1,34 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=mesh-mesh
PKG_VERSION:=4.500
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/mesh-mesh
SECTION:=utils
CATEGORY:=ROOter
SUBMENU:=Mesh Support
DEPENDS:=+kmod-batman-adv +alfred +batctl +ip
TITLE:=Install scripts for Mesh Network
PKGARCH:=all
endef
define Package/mesh-mesh/description
Install scripts for Mesh Network
endef
define Build/Compile
endef
define Package/mesh-mesh/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,mesh-mesh))

View File

@ -1,16 +0,0 @@
config mesh 'bat0'
option aggregated_ogms '1'
option ap_isolation '0'
option bonding '0'
option fragmentation '0'
option gw_bandwidth '10000/2000'
option gw_mode 'client'
option gw_sel_class '20'
option log_level '2'
option orig_interval '1000'
option bridge_loop_avoidance '1'
option distributed_arp_table '1'
option multicast_mode '1'
option network_coding '0'
option hop_penalty '30'
option isolation_mark '0'

View File

@ -1,18 +0,0 @@
config radio 'radio'
option radionumber '0'
option usedfs '1'
option channelwidth '0'
option channellist '0'
option channelindex '10'
option dedicated '0'
config network 'network'
option networkid 'MeshCloud'
option netencrypted '1'
option netpassword 'MeshPassword123'
config roam 'roam'
option signalenable '1'
option signalid 'abcd'

View File

@ -1,34 +0,0 @@
#!/bin/sh
dhcp4_discover () {
ifup lan_dhcp
}
dhcp4_kill () {
ifdown lan_dhcp
}
dnsmasq_start () {
uci revert -P/var/state dhcp.@dnsmasq[0].domainneeded
uci revert -P/var/state dhcp.@dnsmasq[0].boguspriv
uci revert -P/var/state dhcp.@dnsmasq[0].rebind_protection
uci revert -P/var/state dhcp.lan.ignore
/etc/init.d/dnsmasq restart
}
dnsmasq_stop () {
uci set -P/var/state dhcp.@dnsmasq[0].domainneeded=
uci set -P/var/state dhcp.@dnsmasq[0].boguspriv=
uci set -P/var/state dhcp.@dnsmasq[0].rebind_protection=0
uci set -P/var/state dhcp.lan.ignore=1
echo no-dhcp-interface=br-lan >> /var/etc/dnsmasq.conf
/etc/init.d/dnsmasq restart
}
if [ "$BATTYPE" = "gw" ] ; then
case "$BATACTION" in
add) dnsmasq_stop ; dhcp4_discover ;;
del) dhcp4_kill ; dnsmasq_start ;;
change) dhcp4_kill ; sleep 5 ; dhcp4_discover ;;
esac
fi

View File

@ -1,9 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2006 OpenWrt.org
START=99
start() {
/usr/lib/mesh/checker.sh
}

View File

@ -1,249 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2012 Jo-Philipp Wich <xm@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
$Id$
]]--
module("luci.controller.batman", package.seeall)
local function split(str, pat)
local t = {} -- NOTE: use {n = 0} in Lua-5.0
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
function index()
local page
page = node("admin", "mesh", "batman")
page.target = template("batman/batman")
page.title = _("Mesh Status")
page.order = 1
node("batman")
page = node("batman", "json")
page.target = call("act_json")
page = node("batman", "topo")
page.target = call("act_topo")
page.leaf = true
page = node("batman", "graph")
page.target = template("batman_graph")
page.leaf = true
end
function act_topo(mode)
if not mode or mode == "dot" or mode == "json" then
local fd = io.popen("batadv-vis -f %s" %( mode or "dot" ))
if fd then
if mode == "json" then
luci.http.prepare_content("application/json")
luci.http.write("[")
local ln
repeat
ln = fd:read("*l")
if ln then
luci.http.write(ln)
luci.http.write(", ")
end
until not ln
luci.http.write("{ } ]")
else
luci.http.prepare_content("text/vnd.graphviz")
luci.http.header("Content-Disposition",
"attachment; filename=topo-%s-%s.vd"
%{ luci.sys.hostname(), os.date("%Y%m%d-%H%M%S") })
luci.http.write(fd:read("*a"))
end
fd:close()
else
luci.http.status(500, "No data")
end
else
luci.http.status(500, "Bad mode")
end
end
function act_json()
local v, l, fd
local rv = {
interfaces = { },
originators = { },
gateways = { }
}
--
-- interfaces
--
fd = io.popen("batctl if")
if fd then
repeat
l = fd:read("*l")
v = l and l:match("^(.-):")
if v then
rv.interfaces[#rv.interfaces+1] = v
end
until not l
fd:close()
end
os.execute("cat /proc/net/arp > /tmp/arp")
iplist = {}
maclist = {}
index = 0
fd = io.open("/tmp/arp")
if fd then
-- skip header line
fd:read("*l")
repeat
l = fd:read("*l")
if l then
lan = l
s1, e1 = lan:find("0x2")
if s1 ~= nil then
s, e = l:find(" ")
if s ~= nil then
ip = l:sub(0, e-1)
fc = io.popen("batctl translate " .. ip)
if fc then
mac = fc:read("*l")
fc:close()
iplist[index] = ip
maclist[index] = mac
index = index + 1
end
end
end
end
until not l
fd:close()
end
--
-- originators
--
local originators_command = (
"batctl o -H 2>/dev/null ".. -- gets originators from batctl
"| tr -d '[]()' ".. -- removes brackets and parenthesis
"| sed 's/^ / -/g' ".. -- normalizes output, adding a minus when no asterisk is outputed in each line
"| sed 's/^ //g' ".. -- removes the space from the beginning of the line
"| sed -r 's/\\s+/,/g'".. -- replaces tabs for commas
"| sed -r 's/s,/,/g'" -- removes the 's' from the last_seen field referencing seconds
)
fd = io.popen(originators_command)
if fd then
repeat
l = fd:read()
if l then
local asterisk, originator_name, last_seen, link_quality, next_hop, outgoing_if
asterisk, originator_name, last_seen, link_quality, next_hop, outgoing_if = unpack(split(l, ","))
if originator_name and last_seen and link_quality then
if originator_name == next_hop then
next_hop = "Here"
end
if index > 0 then
for j=0,index-1 do
if maclist[j] == originator_name then
originator_name = iplist[j] .. " (" .. originator_name .. ")"
end
if maclist[j] == next_hop then
next_hop = iplist[j]
end
end
end
rv.originators[#rv.originators+1] = {
originator_name,
tonumber(last_seen) * 1000,
tonumber(link_quality),
next_hop,
outgoing_if
}
end
end
until not l
fd:close()
end
--
-- gateways
--
fd = io.popen("batctl gwl")
if fd then
-- skip header line
fd:read("*l")
fd:read("*l")
repeat
l = fd:read("*l")
if l then
local a, m, q, n, i, r = l:match("^(%S*) +([^ ]+) +%( *(%d+)%) +([^ ]+) +%[ *(%S+)%]: +(%S+)")
if a and m and q and n and i and r then
c="0"
if index > 0 then
for j=0,index-1 do
if maclist[j] == m then
m = iplist[j]
end
if maclist[j] == n then
n = iplist[j]
end
end
end
rv.gateways[#rv.gateways+1] = {
#a > 0,
m,
tonumber(q),
n,
i,
tonumber(c),
r
}
end
end
until not l
fd:close()
end
-- local Gateway status
rv.status = "Client"
fd = io.popen("batctl gw")
if fd then
l = fd:read("*l")
s, e = l:find("server")
if s ~= nil then
rv.status = "Server"
end
fd:close()
end
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
end

View File

@ -1,76 +0,0 @@
module("luci.controller.mesh", package.seeall)
function index()
local page
entry({"admin", "mesh"}, firstchild(), "Mesh", 71).dependent=false
page = entry({"admin", "mesh", "mesh"}, template("mesh/mesh-setup"), "Mesh Configuration", 71)
page.dependent = true
entry({"admin", "mesh", "getstate"}, call("action_getstate"))
entry({"admin", "mesh", "sendmeshstate"}, call("action_sendmeshstate"))
entry({"admin", "mesh", "meshcfg"}, call("action_meshcfg"))
entry({"admin", "mesh", "meshstartstop"}, call("action_meshstartstop"))
end
function action_getstate()
local rv = {}
local radiolist = {}
file = io.open("/etc/meshrun", "r")
if file == nil then
rv["state"] = "0"
else
rv["state"] = "1"
file:close()
end
os.execute("/usr/lib/mesh/radio.sh ")
file = io.open("/tmp/radiolist", "r")
if file ~= nil then
j = file:read("*line")
rv['radio'] = j
if j ~=0 then
for i=0, j-1 do
radiolist[i] = file:read("*line")
end
rv['radiolist'] = radiolist
end
rv['radionumber'] = file:read("*line")
rv['channelindex'] = file:read("*line")
rv['channellist'] = file:read("*line")
rv['channelwidth'] = file:read("*line")
rv['usedfs'] = file:read("*line")
rv['dedicated'] = file:read("*line")
rv['networkid'] = file:read("*line")
rv['netencrypted'] = file:read("*line")
rv['netpassword'] = file:read("*line")
rv['signalenable'] = file:read("*line")
rv['signalid'] = file:read("*line")
file:close()
else
rv["radio"] = "0"
end
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
end
function action_sendmeshstate()
local set = luci.http.formvalue("set")
os.execute('/usr/lib/mesh/save.sh "' .. set .. '"')
end
function action_meshcfg()
local set = luci.http.formvalue("set")
os.execute('/usr/lib/mesh/savecfg.sh "' .. set .. '"')
end
function action_meshstartstop()
os.execute('/usr/lib/mesh/startstop.sh')
os.execute("reboot &")
end

View File

@ -1,300 +0,0 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2012 Jo-Philipp Wich <xm@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
$Id$
-%>
<% luci.http.prepare_content("text/html") %>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/raphael-min.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/dracula_graffle.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/dracula_graph.js"></script>
<script type="text/javascript" src="<%=resource%>/jquery/jquery-1.4.js"></script>
<script type="text/javascript">//<![CDATA[
function gw_apply(field)
{
var mode, val;
if (field.type == 'radio') {
val = '';
mode = field.value;
}
else {
val = field.value;
mode = document.getElementById('gw_gateway').checked ? 'server' : 'client';
}
document.getElementById('gw_apply').style.display = '';
document.getElementById('gw_form').style.display = 'none';
document.getElementById('gw_form_val').parentNode.style.display = (mode != 'off') ? '' : 'none';
XHR.get('<%=luci.dispatcher.build_url("batman/gw")%>/'+mode+'/'+encodeURIComponent(val), null,
function(x, info) {
document.getElementById('gw_form').style.display = '';
document.getElementById('gw_apply').style.display = 'none';
document.getElementById('gw_form_val').value = info;
});
}
XHR.poll(5, '<%=luci.dispatcher.build_url("batman/json")%>', null,
function(x, info)
{
var t;
var og = info.originators;
var gw = info.gateways;
var server = info.status;
if ( server == 'Client' )
{
document.getElementById('status').innerHTML="No local Internet access, running as Client";
}
else
{
document.getElementById('status').innerHTML="Local Internet access, running as Gateway Server";
}
if (!!(t = document.getElementById('originator_table')))
{
/* clear all rows */
while (t.rows.length > 1)
t.rows[0].parentNode.deleteRow(1);
og.sort(function(a, b) { return parseInt(b[2]) - parseInt(a[2]) });
for (var i = 0; i < og.length; i++)
{
var tr = t.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + (1 + (i % 2));
var icon;
if (og[i][2] < 64)
icon = "<%=resource%>/icons/signal-0-25.png";
else if (og[i][2] < 128)
icon = "<%=resource%>/icons/signal-25-50.png";
else if (og[i][2] < 192)
icon = "<%=resource%>/icons/signal-50-75.png";
else
icon = "<%=resource%>/icons/signal-75-100.png";
tr.insertCell(-1).innerHTML = String.format(
'<img src="%s" title="<%:Quality%>: %d / 255" style="vertical-align:middle" /> %d/255',
icon, og[i][2], og[i][2]
);
if ( og[i][3] == "Here" )
{
tr.insertCell(-1).innerHTML = '<strong>' + og[i][0] + '</strong>' ;
og[i][3] = " ";
}
else
{
tr.insertCell(-1).innerHTML = og[i][0];
}
tr.insertCell(-1).innerHTML = String.format('%dms', og[i][1]);
tr.insertCell(-1).innerHTML = og[i][4];
tr.insertCell(-1).innerHTML = og[i][3];
}
if (t.rows.length == 1)
{
var tr = t.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 3;
td.innerHTML = '<br /><em><%:There are no active neighbors%></em>';
}
}
if (!!(t = document.getElementById('gateway_table')))
{
/* clear all rows */
while (t.rows.length > 1)
t.rows[0].parentNode.deleteRow(1);
gw.sort(function(a, b) { return a[0] > b[0] });
for (var i = 0; i < gw.length; i++)
{
var tr = t.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + (1 + (i % 2));
tr.insertCell(-1).innerHTML = gw[i][0]
? String.format('<strong>%s (active)</strong>', gw[i][1])
: gw[i][1];
tr.insertCell(-1).innerHTML = gw[i][6];
tr.insertCell(-1).innerHTML = String.format('%d/255', gw[i][2]);
tr.insertCell(-1).innerHTML = gw[i][4];
tr.insertCell(-1).innerHTML = gw[i][3];
}
if (t.rows.length == 1)
{
var tr = t.rows[0].parentNode.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 3;
td.innerHTML = '<br /><em><%:There are no active mesh gateways%></em>';
}
}
}
);
XHR.get('<%=luci.dispatcher.build_url("batman/topo/json")%>', null,
function(x, data)
{
var g = new Graph();
var render = function(r, node) {
var color = Raphael.getColor();
var rect = r.rect(node.point[0]-50, node.point[1]-10, 100, 20)
.attr({"fill": color, "stroke": color, "stroke-width": 2, r : "9px"})
var set = r.set().
push(rect).
push(r.text(node.point[0], node.point[1], node.label || node.id)
.attr({"fill": "#000"}));
return set;
};
for (var i = 0; i < (data.length-1); i++)
{
// node->node
if (data[i].router && data[i].neighbor) {
g.addNode(data[i].router, { render: render });
g.addNode(data[i].neighbor, { render: render });
g.addEdge(data[i].router, data[i].neighbor,
{ label: parseFloat(data[i].label).toFixed(1),
directed: true, stroke: '#aaaaaa' });
}
else if (data[i].secondary) {
g.addNode(data[i].secondary, { render: render });
g.addNode(data[i].of, { render: render });
g.addEdge(data[i].secondary, data[i].of,
{ fill: "#000" } );
}
}
document.getElementById('canvas').innerHTML = "";
var canvas = document.getElementById('canvas');
var layouter = new Graph.Layout.Spring(g);
layouter.layout();
var renderer = new Graph.Renderer.Raphael(canvas.id, g, canvas.offsetWidth, canvas.offsetHeight);
renderer.draw();
}
);
XHR.poll(25, '<%=luci.dispatcher.build_url("batman/topo/json")%>', null,
function(x, data)
{
var g = new Graph();
var render = function(r, node) {
var color = Raphael.getColor();
var rect = r.rect(node.point[0]-50, node.point[1]-10, 100, 20)
.attr({"fill": color, "stroke": color, "stroke-width": 2, r : "9px"})
var set = r.set().
push(rect).
push(r.text(node.point[0], node.point[1], node.label || node.id)
.attr({"fill": "#000"}));
return set;
};
for (var i = 0; i < (data.length-1); i++)
{
// node->node
if (data[i].router && data[i].neighbor) {
g.addNode(data[i].router, { render: render });
g.addNode(data[i].neighbor, { render: render });
g.addEdge(data[i].router, data[i].neighbor,
{ label: parseFloat(data[i].label).toFixed(1),
directed: true, stroke: '#aaaaaa' });
}
else if (data[i].secondary) {
g.addNode(data[i].secondary, { render: render });
g.addNode(data[i].of, { render: render });
g.addEdge(data[i].secondary, data[i].of,
{ fill: "#000" } );
}
}
document.getElementById('canvas').innerHTML = "";
var canvas = document.getElementById('canvas');
var layouter = new Graph.Layout.Spring(g);
layouter.layout();
var renderer = new Graph.Renderer.Raphael(canvas.id, g, canvas.offsetWidth, canvas.offsetHeight);
renderer.draw();
}
);
//]]></script>
<h2><a id="content" name="content"><%:Mesh Status%></a></h2>
<fieldset class="cbi-section">
<table width="550" border="0">
<tr>
<td width="17%"><div align="right"><strong>Internet Status : </strong></div></td>
<td width="19%"><ul id="status"></ul></td>
<td width="65%"></td>
</tr>
</table>
</fieldset>
<fieldset class="cbi-section">
<legend><%:Active Mesh Nodes%></legend>
<table class="cbi-section-table" id="originator_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Link Quality%></th>
<th class="cbi-section-table-cell"><%:MAC-Address%></th>
<th class="cbi-section-table-cell"><%:Last Seen%></th>
<th class="cbi-section-table-cell"><%:Interface%></th>
<th class="cbi-section-table-cell"><%:Next Hop%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="3"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
<fieldset class="cbi-section">
<legend><%:Other Mesh Nodes with Internet Access%></legend>
<table class="cbi-section-table" id="gateway_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:MAC-Address%></th>
<th class="cbi-section-table-cell"><%:Speed%></th>
<th class="cbi-section-table-cell"><%:Link Quality%></th>
<th class="cbi-section-table-cell"><%:Interface%></th>
<th class="cbi-section-table-cell"><%:Next Hop%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="3"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
<fieldset class="cbi-section">
<legend><%:Visualization%></legend>
<div id="canvas" style="min-width:800px; min-height:600px"></div>
</fieldset>
<%+footer%>

View File

@ -1,912 +0,0 @@
<%+header%>
<%
local sys = require "luci.sys"
local utl = require "luci.util"
local fs = require "nixio.fs"
function showicon(lck)
if lck == 0 then
return resource .. "/icons/unlock1.png"
else
return resource .. "/icons/lock1.png"
end
end
-%>
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<script type="text/javascript">//<![CDATA[
var change=0;
var radnum = 1; // radio number option radionumber '0'
var channelindex = 0 ; // index in to list option channelindex '0'
var channellist = 0; // list number 0-2 option channellist "0"
var channelwidth = 1; // index of bw 0-3 option channelwidth '0'
var usedfs = 0; // 1 is dfs channels option usedfs "0"
var detecatedradio = 1; // 1 is dedicated radio option dedicated "0"
var networkid = "MeshCloud";
var netencrypted = 0;
var netpassword = "password";
var signalenable = 1;
var signalid = "mesh";
var radiolist = new Array() ;
var partsArray = new Array;
var channels = new Array;
var cwidth = ["20", "40", "80", "80"];
var channelnum = 0;
var chan2num = 14;
var chan5num = 10;
var chan5dfsnum = 23;
var channel2 = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14" ];
var channel5 = ["36", "40", "44", "48", "149", "153", "157", "161", "165", "169"];
var channel5dfs = ["36", "40", "44", "48", "52", "56", "60", "64", "100", "104", "104", "112", "116", "132", "136", "140", "144", "149", "153", "157", "161", "165", "169"];
function setwidth(width)
{
switch (width)
{
case "0":
num = 1;
dropname = "drop5";
break;
case "1":
num = 2;
dropname = "drop6";
break;
case "2":
num = 3;
dropname = "drop7";
break;
case "3":
num = 3;
dropname = "drop8";
break;
}
x = document.getElementById(dropname);
for (i = 0; i < num; i++)
{
option = document.createElement("option");
option.text = cwidth[i] + "Mhz";
x.add(option);
}
}
function changebw(flg)
{
partsArray = radiolist[radnum].split('|');
channelw = partsArray[2];
switch (channelw)
{
case "0":
document.getElementById("radio46").style.visibility="visible";
if ( flg == 1 )
{
document.getElementById("radio46").style.display = "";
}
document.getElementById("drop5").selectedIndex = channelwidth;
document.getElementById("radio47").style.display = "none";
document.getElementById("radio47").style.visibility="hidden";
document.getElementById("radio48").style.display = "none";
document.getElementById("radio48").style.visibility="hidden";
document.getElementById("radio49").style.display = "none";
document.getElementById("radio49").style.visibility="hidden";
break;
case "1":
document.getElementById("radio47").style.visibility="visible";
if ( flg == 1 )
{
document.getElementById("radio47").style.display = "";
}
document.getElementById("drop6").selectedIndex = channelwidth;
document.getElementById("radio46").style.display = "none";
document.getElementById("radio46").style.visibility="hidden";
document.getElementById("radio48").style.display = "none";
document.getElementById("radio48").style.visibility="hidden";
document.getElementById("radio49").style.display = "none";
document.getElementById("radio49").style.visibility="hidden";
break;
case "2":
document.getElementById("radio48").style.visibility="visible";
if ( flg == 1 )
{
document.getElementById("radio48").style.display = "";
}
document.getElementById("drop7").selectedIndex = channelwidth;
document.getElementById("radio46").style.display = "none";
document.getElementById("radio46").style.visibility="hidden";
document.getElementById("radio47").style.display = "none";
document.getElementById("radio47").style.visibility="hidden";
document.getElementById("radio49").style.display = "none";
document.getElementById("radio49").style.visibility="hidden";
break;
case "3":
document.getElementById("radio49").style.visibility="visible";
if ( flg == 1 )
{
document.getElementById("radio49").style.display = "";
}
document.getElementById("drop8").selectedIndex = channelwidth;
document.getElementById("radio46").style.display = "none";
document.getElementById("radio46").style.visibility="hidden";
document.getElementById("radio47").style.display = "none";
document.getElementById("radio47").style.visibility="hidden";
document.getElementById("radio48").style.display = "none";
document.getElementById("radio48").style.visibility="hidden";
break;
}
}
function vischannel(flg)
{
partsArray = radiolist[radnum].split('|');
if ( partsArray[0] == "1" )
{
document.getElementById("radio3").style.display = "none";
document.getElementById("radio3").style.visibility="hidden";
document.getElementById("radio33").style.display = "none";
document.getElementById("radio33").style.visibility="hidden";
document.getElementById("drop2").style.display = "none";
document.getElementById("drop2").style.visibility="hidden";
if ( usedfs == 0 )
{
document.getElementById("radio4").style.display = "block";
document.getElementById("radio4").style.visibility="visible";
document.getElementById("drop3").style.display = "block";
document.getElementById("drop3").style.visibility="visible";
document.getElementById("radio44").style.visibility="visible";
if ( flg == 1 )
{
document.getElementById("radio44").style.display = "";
}
channellist = 1;
document.getElementById("drop3").selectedIndex = channelindex;
document.getElementById("radio5").style.display = "none";
document.getElementById("radio5").style.visibility="hidden";
document.getElementById("drop4").style.display = "none";
document.getElementById("drop4").style.visibility="hidden";
document.getElementById("radio55").style.display = "none";
document.getElementById("radio55").style.visibility="hidden";
}
else
{
document.getElementById("radio5").style.display = "block";
document.getElementById("radio5").style.visibility="visible";
document.getElementById("drop4").style.display = "block";
document.getElementById("drop4").style.visibility="visible";
document.getElementById("radio55").style.visibility="visible";
if ( flg == 1 )
{
document.getElementById("radio55").style.display = "";
}
channellist = 2;
document.getElementById("drop4").selectedIndex = channelindex;
document.getElementById("radio4").style.display = "none";
document.getElementById("radio4").style.visibility="hidden";
document.getElementById("drop3").style.display = "none";
document.getElementById("drop3").style.visibility="hidden";
document.getElementById("radio44").style.display = "none";
document.getElementById("radio44").style.visibility="hidden";
}
}
else
{
document.getElementById("radio3").style.display = "block";
document.getElementById("radio3").style.visibility="visible";
document.getElementById("radio33").style.visibility="visible";
if ( flg == 1 )
{
document.getElementById("radio33").style.display = "";
}
channellist = 0;
document.getElementById("drop2").style.display = "block";
document.getElementById("drop2").style.visibility="visible";
document.getElementById("drop2").selectedIndex = channelindex;
document.getElementById("radio4").style.display = "none";
document.getElementById("radio4").style.visibility="hidden";
document.getElementById("drop3").style.display = "none";
document.getElementById("drop3").style.visibility="hidden";
document.getElementById("radio44").style.display = "none";
document.getElementById("radio44").style.visibility="hidden";
document.getElementById("radio5").style.display = "none";
document.getElementById("radio5").style.visibility="hidden";
document.getElementById("drop4").style.display = "none";
document.getElementById("drop4").style.visibility="hidden";
document.getElementById("radio55").style.display = "none";
document.getElementById("radio55").style.visibility="hidden";
}
}
function setchannels(freq)
{
switch ( freq )
{
case "0" :
channels = channel2;
chansize = chan2num;
dropname = "drop2";
break;
case "1" :
channels = channel5;
chansize = chan5num;
dropname = "drop3";
break;
case "2" :
channels = channel5dfs;
chansize = chan5dfsnum;
dropname = "drop4";
break;
default :
break;
}
x = document.getElementById(dropname);
for (i = 0; i < chansize; i++)
{
option = document.createElement("option");
option.text = "Channel " + channels[i];
x.add(option);
}
x.selectedIndex = channelnum;
}
XHR.get('<%=luci.dispatcher.build_url("admin", "mesh", "getstate")%>',
null,
function(x, rv)
{
document.getElementById("cbi-modw").style.display = "none";
document.getElementById("cbi-modw").style.visibility="hidden";
document.getElementById("cbi-mod1").style.display = "block";
document.getElementById("cbi-mod1").style.visibility="visible";
document.getElementById("cbi-mod2").style.display = "block";
document.getElementById("cbi-mod2").style.visibility="visible";
document.getElementById("cbi-mod3").style.display = "block";
document.getElementById("cbi-mod3").style.visibility="visible";
radnum = parseInt(rv.radionumber);
channelindex = parseInt(rv.channelindex);
channellist = parseInt(rv.channellist);
channelwidth = parseInt(rv.channelwidth);
usedfs = parseInt(rv.usedfs);
detecatedradio = parseInt(rv.dedicated);
networkid = rv.networkid;
netencrypted = parseInt(rv.netencrypted);
netpassword = rv.netpassword;
signalenable = parseInt(rv.signalenable);
signalid = rv.signalid;
document.getElementById("dedicated").checked = false;
if ( detecatedradio == 1 )
{
document.getElementById("dedicated").checked = true;
}
document.getElementById("dfs").checked = false;
document.getElementById("dfs3").checked = false;
if ( usedfs == 1)
{
document.getElementById("dfs").checked = true;
document.getElementById("dfs3").checked = true;
}
num_radio = parseInt(rv.radio);
if ( num_radio > 0 )
{
radiolist = rv.radiolist;
x = document.getElementById("drop1");
for (i = 0; i < num_radio; i++)
{
partsArray = radiolist[i].split('|');
dropradio = "Radio" + partsArray[1];
if ( partsArray[0] == "1" )
{
dropradio = dropradio + " (5Ghz)";
}
else
{
dropradio = dropradio + " (2.4Ghz)";
}
option = document.createElement("option");
option.text = dropradio;
x.add(option);
}
x.selectedIndex = radnum;
setchannels("0");
setchannels("1");
setchannels("2");
setwidth("0");
setwidth("1");
setwidth("2");
setwidth("3");
vischannel(0);
changebw(0);
document.getElementById("idnam").value = networkid;
document.getElementById("encr").checked = false;
document.getElementById("enc2").style.display = "none";
document.getElementById("enc2").style.visibility="hidden";
document.getElementById("netpass").style.display = "none";
document.getElementById("netpass").style.visibility="hidden";
if ( netencrypted == 1 )
{
document.getElementById("encr").checked = true;
document.getElementById("enc2").style.display = "block";
document.getElementById("enc2").style.visibility="visible";
document.getElementById("netpass").style.display = "block";
document.getElementById("netpass").style.visibility="visible";
}
document.getElementById("netpass").value = netpassword;
document.getElementById("sigenb").checked = false;
document.getElementById("roam11").style.display = "none";
document.getElementById("roam11").style.visibility="hidden";
document.getElementById("idsig").value = signalid;
if ( signalenable == 1 )
{
document.getElementById("sigenb").checked = true;
document.getElementById("roam11").style.display = "";
document.getElementById("roam11").style.visibility="visible";
}
}
}
);
function changes(value)
{
change = value;
if ( value == 0 )
{
document.getElementById("meshstat1").innerHTML = "No Changes";
document.getElementById("meshstat1").style.color = "inherit";
document.getElementById("meshstat1").style.fontWeight = "bold" ;
}
else
{
document.getElementById("meshstat1").innerHTML = "Unsaved Changes";
document.getElementById("meshstat1").style.color = "red";
document.getElementById("meshstat1").style.fontWeight = "bold" ;
}
}
function radiochange(drop)
{
radnum = document.getElementById("drop1").selectedIndex;
channelindex = 0;
vischannel(1);
channelwidth = 0;
changebw(1);
changes(1);
}
function dedicatedrad(check)
{
if ( check.checked == true )
{
detecatedradio = 1;
}
else
{
detecatedradio = 0;
}
changes(1);
}
function setdfs(check)
{
if ( check.checked == true )
{
usedfs = 1;
radiochange();
document.getElementById("dfs").checked = true;
document.getElementById("dfs3").checked = true;
}
else
{
usedfs = 0;
radiochange();
document.getElementById("dfs").checked = false;
document.getElementById("dfs3").checked = false;
}
changes(1);
}
function bwchange(bwbox)
{
bw = bwbox.selectedIndex;
channelwidth = bw;
changes(1);
}
function channelchange(chn)
{
channelindex = chn.selectedIndex;
radnum = document.getElementById("drop1").selectedIndex;
partsArray = radiolist[radnum].split('|');
if ( partsArray[0] == "1" )
{
channellist = 1;
if ( usedfs == 1 )
{
channellist = 2;
}
}
else
{
channellist = 0;
}
changes(1);
}
function setencr(check)
{
if ( check.checked == true )
{
document.getElementById("enc2").style.display = "block";
document.getElementById("enc2").style.visibility="visible";
document.getElementById("netpass").style.display = "block";
document.getElementById("netpass").style.visibility="visible";
netencrypted = 1;
}
else
{
document.getElementById("enc2").style.display = "none";
document.getElementById("enc2").style.visibility="hidden";
document.getElementById("netpass").style.display = "none";
document.getElementById("netpass").style.visibility="hidden";
netencrypted = 0;
}
changes(1);
}
function setlow(check)
{
if ( check.checked == true )
{
document.getElementById("roam11").style.display = "";
document.getElementById("roam11").style.visibility="visible";
signalenable = 1;
}
else
{
document.getElementById("roam11").style.display = "none";
document.getElementById("roam11").style.visibility="hidden";
signalenable = 0;
}
changes(1);
}
function changeid()
{
changes(1);
}
function changesigid()
{
signalid = document.getElementById("idsig").value ;
if ( !signalid )
{
document.getElementById("idsig").value = 'abcd' ;
signalid = 'abcd';
}
changes(1);
}
function configup(btn)
{
var filex = btn.files[0];
var reader = new FileReader();
reader.readAsText(filex);
reader.onload = loaded;
}
function loaded(evt)
{
var fileString = evt.target.result;
partsArray = fileString.split('|');
if ( partsArray[0] == "meshcfg" )
{
radionumber = parseInt(partsArray[0]);
channelindex = parseInt(partsArray[1]);
channellist = parseInt(partsArray[2]);
usedfs = parseInt(partsArray[3]);
channelwidth = parseInt(partsArray[4]);
detecatedradio = parseInt(partsArray[5]);
networkid=partsArray[6];
netencrypted = parseInt(partsArray[7]);
netpassword=partsArray[8];
signalenable = parseInt(partsArray[9]);
signalmeasure = parseInt(partsArray[10]);
signalinterval = parseInt(partsArray[11]);
signalcount = parseInt(partsArray[12]);
snrconnect = parseInt(partsArray[13]);
snrchange = parseInt(partsArray[14]);
sigconnect = parseInt(partsArray[15]);
sigchange = parseInt(partsArray[16]);
window.location.reload(false);
}
changes(1);
}
function buildsave()
{
netpassword = document.getElementById("netpass").value;
if ( netencrypted == 1 )
{
if ( netpassword.length < 8 )
{
alert("You must enter a password at least 8 charactets long!!");
return "1";
}
}
if ( netpassword.length < 8 )
{
netpassword="password";
}
var stat = radnum.toString() + "|" + channelindex.toString() + "|" + channellist.toString() + "|" + usedfs.toString() + "|" + channelwidth.toString() + "|" + detecatedradio.toString() + "|" + networkid + "|" + netencrypted.toString() + "|" + netpassword + "|" ;
var rom = signalenable.toString() + "|" + signalid + "|" ;
stat = stat + rom;
return stat;
}
function saveconf(btn)
{
statusm = buildsave();
if ( statusm == "1" )
{
return false;
}
statusm = "meshcfg|" + statusm;
//document.getElementById("attxt").value=statusm;
XHR.get('<%=luci.dispatcher.build_url("admin", "mesh", "meshcfg")%>',
{ set: statusm },
function()
{
window.open('http://'+window.location.hostname+'/package/meshcfg.meshcfg', '_self')
}
);
}
function savemesh(btn)
{
statusm = buildsave();
if ( statusm == "1" )
{
return false;
}
XHR.get('<%=luci.dispatcher.build_url("admin", "mesh", "sendmeshstate")%>',
{ set: statusm },
function()
{
window.location.reload(false);
}
);
}
function reloadmesh()
{
changes(0);
window.location.reload(false);
}
var tries = 0,
message = document.querySelector('p.reboot-message'),
label = message.querySelector('span');
function ok() {
window.location = '<%=url("admin")%>';
}
function check() {
window.setTimeout(ping, 5000);
}
function ping() {
var img = document.createElement('img');
img.onload = ok;
img.onerror = check;
img.src = '<%=resource%>/icons/loading.gif?' + Math.random();
if (tries++ >= 30) {
message.classList.remove('notice');
message.classList.add('warning');
label.innerHTML = '<%:Device unreachable! Still waiting for device...%>';
}
}
function startstopmesh(btn)
{
if (change == 1 )
{
savech = confirm("Unsaved changes will be lost. Save first?");
if ( savech == true )
{
statusm = buildsave();
if ( statusm !== "1" )
{
XHR.get('<%=luci.dispatcher.build_url("admin", "mesh", "sendmeshstate")%>',
{ set: statusm },
function()
{
}
);
changes(0);
}
}
}
cont = confirm("Router will reboot after applying settings. Continue?");
if ( cont == false )
{
return false;
}
document.getElementById("cbi-modw").style.display = "block";
document.getElementById("cbi-modw").style.visibility="visible";
document.getElementById("cbi-mod1").style.display = "none";
document.getElementById("cbi-mod1").style.visibility="hidden";
document.getElementById("cbi-mod2").style.display = "none";
document.getElementById("cbi-mod2").style.visibility="hidden";
document.getElementById("cbi-mod3").style.display = "none";
document.getElementById("cbi-mod3").style.visibility="hidden";
document.getElementById("fileup").disabled=true;
document.getElementById("meshconf").disabled=true;
document.getElementById("meshsave").disabled=true;
document.getElementById("meshstart").disabled=true;
document.getElementById("meshstat1").style.display = "none";
XHR.get('<%=luci.dispatcher.build_url("admin", "mesh", "meshstartstop")%>',
{ set: "1" },
function()
{
}
);
check();
}
//document.getElementById("attxt").value=partsArray[0].toString();
//]]></script>
<form method="post" action="<%=REQUEST_URI%>">
<div class="cbi-map" id="cbi-modem">
<h2><a id="content" name="content">Mesh Network Configuration</a></h2>
<div class="cbi-map-descr"> </div>
<fieldset class="cbi-section" id="cbi-mod">
<table width="100%" border="0" id="meshstatus">
<tr>
<td width="20%"><div align="center" id="meshstat2" style="font-size:1.5em"><strong>Config Status</strong></div></td>
<td width="20%"><div align="center" id="upl2" ><strong>Import Configuration File</strong></div></td>
<td width="13%"><div align="center" id="upl3" ><strong>Export Configuration File</strong></div></td>
<td width="10%"><div align="center" id="up42" ><strong>Save Settings</strong></div></td>
<td width="10%"><div align="center" id="up52" ><strong>Apply Settings</strong></div></td>
<td width="10%"><div align="center" id="up52" ><strong>Reload Settings</strong></div></td>
<td width="17%"></td>
</tr>
<tr>
<td width="20%"><div align="center" id="meshstat1" ><strong>No Changes</strong></div></td>
<td width="20%"><input type="file" accept=".meshcfg" align="center" name="fileup" id="fileup" class="cbi-button cbi-button-positive" onchange="return configup(this)" /></td>
<td width="13%"><input type="button" align="center" id="meshconf" class="cbi-button cbi-button-positive" value="<%:Save Configuration File%>" onclick="return saveconf(this)" /></td>
<td width="10%"><input type="button" align="center" id="meshsave" class="cbi-button cbi-button-positive" value="<%:Save Settings%>" onclick="return savemesh(this)" /></td>
<td width="10%"><input type="button" align="center" id="meshstart" class="cbi-button cbi-button-positive" value="<%:Apply Settings%>" onclick="return startstopmesh(this)" /></td>
<td width="10%"><input type="button" align="center" id="meshreload" class="cbi-button cbi-button-positive" value="<%:Reload Settings%>" onclick="return reloadmesh(this)" /></td>
<td width="17%"></td>
</tr>
</table>
</fieldset>
<fieldset class="cbi-section" id="cbi-modw" style="visibility:hidden">
<table width="100%" cellspacing="10" id="waiting">
<tr>
<td width="40%"></td>
<td id="waiticon"><img src="<%=resource%>/icons/loading.gif" style="vertical-align:middle" /> Waiting for Reboot...</td>
</tr>
</table>
</fieldset>
<fieldset class="cbi-section" id="cbi-mod1">
<table width="100%" border="0" id="meshradio" >
<tr>
<td width="17%"><div align="left" id="radio1" style="font-size:1.5em"><strong>Mesh Radio Settings</strong></div></td>
<td width="15%"></td>
<td width="12%"></td>
<td width="5%"></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
<tr>
<td width="17%"><div align="right" id="radio2" ><strong>Select Backhaul Radio </strong></div></td>
<td width="15%">
<select style="width:200px" name="raddrop" id="drop1" onchange="return radiochange(this)">
</select>
</td>
<td width="12%"><div align="left" id="dedicated1" style="font-size:1em"><strong>Dedicated Backhaul Radio </strong></div></td>
<td width="5%"><input type="checkbox" id="dedicated" onclick="return dedicatedrad(this)" /></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
<tr id="radio33">
<td width="17%"><div align="right" id="radio3" ><strong>Select Backhaul Channel </strong></div></td>
<td width="15%">
<select style="width:200px" name="chandrop" id="drop2" onchange="return channelchange(this)">
</select>
</td>
<td width="12%"></td>
<td width="5%"></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
<tr id="radio44">
<td width="17%"><div align="right" id="radio4" ><strong>Select Backhaul Channel </strong></div></td>
<td width="15%">
<select style="width:200px" name="chandrop1" id="drop3" onchange="return channelchange(this)">
</select>
</td>
<td width="12%"><div align="left" id="dfs1" style="font-size:1em"><strong>Use DFS Channels </strong></div></td>
<td width="5%"><input type="checkbox" id="dfs" onclick="return setdfs(this)" /></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
<tr id="radio55">
<td width="17%"><div align="right" id="radio5" ><strong>Select Backhaul Channel </strong></div></td>
<td width="15%">
<select style="width:200px" name="chandrop2" id="drop4" onchange="return channelchange(this)">
</select>
</td>
<td width="12%"><div align="left" id="dfs2" style="font-size:1em"><strong>Use DFS Channels </strong></div></td>
<td width="5%"><input type="checkbox" id="dfs3" onclick="return setdfs(this)" /></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
<tr id="radio46">
<td width="17%"><div align="right" id="radio6" ><strong>Channel Bandwidth </strong></div></td>
<td width="15%">
<select style="width:200px" name="chandrop3" id="drop5" onchange="return bwchange(this)">
</select>
</td>
<td width="12%"></td>
<td width="5%"></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
<tr id="radio47">
<td width="17%"><div align="right" id="radio7" ><strong>Channel Bandwidth </strong></div></td>
<td width="15%">
<select style="width:200px" name="chandrop3" id="drop6" onchange="return bwchange(this)">
</select>
</td>
<td width="12%"></td>
<td width="5%"></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
<tr id="radio48">
<td width="17%"><div align="right" id="radio7" ><strong>Channel Bandwidth </strong></div></td>
<td width="15%">
<select style="width:200px" name="chandrop3" id="drop7" onchange="return bwchange(this)">
</select>
</td>
<td width="12%"></td>
<td width="5%"></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
<tr id="radio49">
<td width="17%"><div align="right" id="radio7" ><strong>Channel Bandwidth </strong></div></td>
<td width="15%">
<select style="width:200px" name="chandrop3" id="drop8" onchange="return bwchange(this)">
</select>
</td>
<td width="12%"></td>
<td width="5%"></td>
<td width="20%"></td>
<td width="31%"></td>
</tr>
</table>
</fieldset>
<fieldset class="cbi-section" id="cbi-mod2" >
<table width="100%" border="0" id="meshnet" >
<tr>
<td width="17%"><div align="left" id="net1" style="font-size:1.5em"><strong>Mesh Network Settings</strong></div></td>
<td width="10%"></td>
<td width="12%"></td>
<td width="15%"></td>
<td width="15%"></td>
<td width="31%"></td>
</tr>
<tr>
<td width="17%"><div align="right" id="net2" ><strong>Mesh Network ID </strong></div></td>
<td width="10%" ><input style="width: 200px;" type="text" name="idnam" id="idnam" class="cbi-input-text" value="MeshCloud" onchange="return changeid()" ></input></td>
<td width="12%"></td>
<td width="15%"></td>
<td width="15%"></td>
<td width="31%"></td>
</tr>
<tr>
<td width="17%"><div align="right" id="enc1" style="font-size:1em"><strong>Network Encrypted </strong></div></td>
<td width="10%"><input type="checkbox" id="encr" onclick="return setencr(this)" /></td>
<td width="12%"><div align="left" id="enc2" style="font-size:1em; visibility:hidden"><strong>Network Password </strong></div></td>
<td width="15%"><input style="width: 200px; visibility:hidden" type="text" name="netpass" id="netpass" class="cbi-input-text" placeholder="password" onchange="return changeid()" ></input></td>
<td width="15%"></td>
<td width="31%"></td>
</tr>
</table>
</fieldset>
<fieldset class="cbi-section" id="cbi-mod3" >
<table width="100%" border="0" id="meshroam" >
<tr>
<td width="17%"><div align="left" id="roam1" style="font-size:1.5em"><strong>Access Point Roaming</strong></div></td>
<td width="10%"></td>
<td width="12%"></td>
<td width="15%"></td>
<td width="15%"></td>
<td width="31%"></td>
</tr>
<tr>
<td width="17%"><div align="right" id="enc1" style="font-size:1em"><strong>Enable Low Signal Roaming </strong></div></td>
<td width="10%"><input type="checkbox" id="sigenb" onclick="return setlow(this)" /></td>
<td width="12%"></td>
<td width="15%"></td>
<td width="15%"></td>
<td width="31%"></td>
</tr>
<tr id="roam11">
<td width="17%"><div align="right" id="roam1" ><strong>Roaming ID </strong></div></td>
<td width="10%" ><input style="width: 200px;" type="text" name="idsig" id="idsig" class="cbi-input-text" value="mesh" onchange="return changesigid()" ></input></td>
<td width="12%"></td>
<td width="15%"></td>
<td width="15%"></td>
<td width="31%"></td>
</tr>
</table>
<table id="cmdtxt" width="700" border="0" style="display:table;">
<tr>
<td width="100%">
<textarea readonly="readonly" name="attxt" id="attxt" rows="6" style="width: 600px;" maxlength="160"></textarea>
</td>
</tr>
</table>
</fieldset>
</div>
</form>
<%+footer%>

View File

@ -1,251 +0,0 @@
#!/bin/sh
. /lib/functions.sh
log() {
logger -t "Checker" "$@"
}
channel2="1,2,3,4,5,6,7,8,9,10,11,12,13,14"
channel5="36,40,44,48,149,153,157,161,165,169"
channel5dfs="36,40,44,48,52,56,60,64,100,104,104,112,116,132,136,140,144,149,153,157,161,165,169"
absolute() {
num=$1
if [ "$num" -lt 0 ]; then
num=$((-num))
fi
}
loadconfig() {
X=$(uci -q get wireless.wmesh.device)
uci set mesh.radio.radionumber=$(echo ${X#radio})
uci set mesh.radio.dedicated=$(uci -q get wireless.default_$X.disabled)
chanwidth=$(uci -q get wireless.$X.htmode)
case $chanwidth in
"HT20" )
chanwidth=0
;;
"HT40" )
chanwidth=1
;;
"VHT80" )
chanwidth=2
;;
"VHT160" )
chanwidth=2
;;
esac
uci set mesh.radio.channelwidth=$chanwidth
chan=$(uci -q get wireless.$X.channel)
if [ $chan -lt 15 ]; then
uci set mesh.radio.channellist=0
uci set mesh.radio.channelindex=$((${chan}-1))
else
dfs=$(uci -q get wireless.$X.usedfs)
if [ -z $dfs ]; then
dfs=1
uci set mesh.radio.usedfs=1
else
uci set mesh.radio.usedfs=$dfs
fi
if [ $dfs -eq 0 ]; then
uci set mesh.radio.channellist=1
clist=$channel5
else
uci set mesh.radio.channellist=2
clist=$channel5dfs
fi
cindex=1
while [ true ]
do
chan=$(echo "$clist" | cut -d, -f$cindex)
if [ $chan -eq $channel ]; then
uci set mesh.radio.channelindex=$((${cindex}-1))
break
fi
cindex=$((${cindex}+1))
done
fi
enc=$(uci -q get wireless.wmesh.encryption)
if [ $enc = "sae" ]; then
uci set mesh.network.netencrypted=1
uci set mesh.network.netpassword=$(uci -q get wireless.wmesh.key)
else
uci set mesh.network.netencrypted=0
uci set mesh.network.netpassword="password"
fi
uci set mesh.network.networkid=$(uci -q get wireless.wmesh.mesh_id)
snr=$(uci -q get wireless.default_$X.ieee80211r)
if [ ! -z $snr ]; then
uci set mesh.roam.signalenable=$snr
uci set mesh.roam.signalid=$(uci -q get wireless.default_$X.mobility_domain)
else
uci set mesh.roam.signalenable=0
uci set mesh.roam.signalid="abcd"
fi
uci commit mesh
}
count_radio() {
local config=$1
local channel
uci set wireless.default_radio$count.ieee80211r=$signalenable
uci set wireless.default_radio$count.mobility_domain=$signalid
uci set wireless.default_radio$count.ft_over_ds="1"
uci set wireless.default_radio$count.ft_psk_generate_local="1"
count=$((${count}+1))
}
loadmesh() {
radionum=$(uci -q get mesh.radio.radionumber)
dedicated=$(uci -q get mesh.radio.dedicated)
if [ -z $dedicated ]; then
dedicated="0"
fi
log "default_radio$radionum disabled = $dedicated"
chanwidth=$(uci -q get mesh.radio.channelwidth)
case $chanwidth in
"0" )
chanwidth=20
;;
"1" )
chanwidth=40
;;
"2" )
chanwidth=80
;;
"3" )
chanwidth=80
;;
esac
cwidth=$(uci -q get wireless.radio$radionum.htmode)
ht=$(echo "$cwidth" | grep "VHT")
if [ ! -z $ht ]; then
cwidth="VHT"$chanwidth
else
cwidth="HT"$chanwidth
fi
log "radio$radionum htmode = $cwidth"
clist=$(uci -q get mesh.radio.channellist)
cindex=$(uci -q get mesh.radio.channelindex)
cindex=$((${cindex}+1))
case $clist in
"0" )
channel=$(echo "$channel2" | cut -d, -f$cindex)
;;
"1" )
channel=$(echo "$channel5" | cut -d, -f$cindex)
;;
"2" )
channel=$(echo "$channel5dfs" | cut -d, -f$cindex)
;;
esac
log "radio$radionum channel = $channel"
networkid=$(uci -q get mesh.network.networkid)
netencrypted=$(uci -q get mesh.network.netencrypted)
netpassword=$(uci -q get mesh.network.netpassword)
log "mesh_id = $networkid"
log "encryption = $netencrypted key = $netpassword"
signalenable=$(uci -q get mesh.roam.signalenable)
signalid=$(uci -q get mesh.roam.signalid)
log "roam enable = $signalenable"
log "id = $signalid"
ipaddr=$(uci -q get network.lan.ipaddr)
uci set wireless.default_radio$radionum.disabled=$dedicated
uci set wireless.radio$radionum.htmode=$cwidth
uci set wireless.radio$radionum.channel=$channel
count=0
config_load wireless
config_foreach count_radio wifi-iface
uci set wireless.wmesh=wifi-iface
uci set wireless.wmesh.device=radio$radionum
uci set wireless.wmesh.network="mesh"
uci set wireless.wmesh.ifname="if-mesh"
uci set wireless.wmesh.mode="mesh"
uci set wireless.wmesh.mesh_fwding="0"
uci set wireless.wmesh.mesh_id=$networkid
uci set wireless.w.encryption="none"
if [ $netencrypted = "1" ]; then
uci set wireless.wmesh.encryption="sae"
uci set wireless.wmesh.key=$netpassword
fi
uci set wireless.wmesh.mesh_ttl='1'
uci set wireless.wmesh.mcast_rate='24000'
uci set wireless.wmesh.disabled='0'
uci commit wireless
uci set alfred.alfred.batmanif='bat0'
uci set alfred.alfred.disabled='0'
uci commit alfred
uci set network.bat0=interface
uci set network.bat0.proto='batadv'
uci set network.bat0.routing_algo='BATMAN_IV'
uci set network.bat0.aggregated_ogms='1'
uci set network.bat0.ap_isolation='0'
uci set network.bat0.bonding='0'
uci set network.bat0.bridge_loop_avoidance='1'
uci set network.bat0.distributed_arp_table='1'
uci set network.bat0.fragmentation='1'
uci set network.bat0.gw_mode='off'
uci set network.bat0.hop_penalty='30'
uci set network.bat0.isolation_mark='0x00000000/0x00000000'
uci set network.bat0.log_level='0'
uci set network.bat0.multicast_mode='1'
uci set network.bat0.multicast_fanout='16'
uci set network.bat0.network_coding='0'
uci set network.bat0.orig_interval='1000'
uci set network.mesh=interface
uci set network.mesh.proto='batadv_hardif'
uci set network.mesh.master='bat0'
uci set network.mesh.mtu='2304'
uci set network.mesh.throughput_override='0'
uci set network.bat0_hardif_eth0=interface
uci set network.bat0_hardif_eth0.proto='batadv_hardif'
uci set network.bat0_hardif_eth0.master='bat0'
uci set network.bat0_hardif_eth0.mtu='1536'
uci set network.bat0_hardif_eth0.device='eth0'
uci set network.bat0_lan=interface
uci set network.bat0_lan.proto='static'
uci set network.bat0_lan.ipaddr=$ipaddr
uci set network.bat0_lan.netmask='255.255.255.0'
uci set network.bat0_lan.ip6assign='60'
uci set network.bat0_lan.device='bat0'
uci commit network
}
cmd=$1
if [ -z $cmd ]; then
WW=$(uci get wireless.wmesh)
if [ -z $WW ]; then
loadmesh
reboot -f
else
loadconfig
/usr/lib/mesh/ping.sh &
fi
else
loadmesh
fi
return

View File

@ -1,34 +0,0 @@
#!/bin/sh
. /lib/functions.sh
pinging() {
PING=0
RETURN_CODE_1=$(curl -m 10 -s -o /dev/null -w "%{http_code}" http://www.google.com/)
RETURN_CODE_2=$(curl -m 10 -s -o /dev/null -w "%{http_code}" http://www.example.org/)
RETURN_CODE_3=$(curl -m 10 -s -o /dev/null -w "%{http_code}" https://github.com)
if [[ "$RETURN_CODE_1" != "200" && "$RETURN_CODE_2" != "200" && "$RETURN_CODE_3" != "200" ]]; then
PING=1
fi
}
gateway() {
mode=$1
# batman-adv gateway handling (DHCP mangling)
[ "$(uci -q get batman-adv.bat0.gw_mode)" == "client" ] || return
if grep -q "^=>" /sys/kernel/debug/batman_adv/bat0/gateways ; then
BATTYPE=gw BATACTION=$mode /etc/hotplug.d/net/99-batman-gw
fi
}
while true ; do
sleep 20
pinging
if [ $PING -eq 1 ]; then
gateway add
batctl gw_mode client
else
gateway del
batctl gw_mode server 10000
fi
done

View File

@ -1,78 +0,0 @@
#!/bin/sh
. /lib/functions.sh
log() {
logger -t "Radio" "$@"
}
count_radio() {
local config=$1
local channel
config_get channel $1 channel
count=$((${count}+1))
}
do_radio() {
local config=$1
local channel
config_get channel $1 channel
rn=${config#radio}
freq="1"
if [ $channel -lt 15 ]; then
freq="0"
fi
iwin=$(iw phy phy$rn info)
hw=0
hwt=$(echo "$iwin" | grep 'short GI for 40 MHz')
if [ ! -z "$hwt" ]; then
hw=1
fi
hwt=$(echo "$iwin" | grep 'short GI (80 MHz)')
if [ ! -z "$hwt" ]; then
hw=2
fi
hwt=$(echo "$iwin" | grep 'short GI (160')
if [ ! -z "$hwt" ]; then
hw=3
fi
echo "$freq|$rn|$hw" >> /tmp/radiolist
}
count=0
rm -f /tmp/radiolist
config_load wireless
config_foreach count_radio wifi-device
if [ $count -gt 0 ]; then
echo "$count" > /tmp/radiolist
config_foreach do_radio wifi-device
fi
CF1=$(uci -q get mesh.radio.radionumber)
CF2=$(uci -q get mesh.radio.channelindex)
CF3=$(uci -q get mesh.radio.channellist)
CF4=$(uci -q get mesh.radio.channelwidth)
CF5=$(uci -q get mesh.radio.usedfs)
CF6=$(uci -q get mesh.radio.dedicated)
echo "$CF1" >> /tmp/radiolist
echo "$CF2" >> /tmp/radiolist
echo "$CF3" >> /tmp/radiolist
echo "$CF4" >> /tmp/radiolist
echo "$CF5" >> /tmp/radiolist
echo "$CF6" >> /tmp/radiolist
CF1=$(uci -q get mesh.network.networkid)
CF2=$(uci -q get mesh.network.netencrypted)
CF3=$(uci -q get mesh.network.netpassword)
echo "$CF1" >> /tmp/radiolist
echo "$CF2" >> /tmp/radiolist
echo "$CF3" >> /tmp/radiolist
CF1=$(uci -q get mesh.roam.signalenable)
CF2=$(uci -q get mesh.roam.signalid)
echo "$CF1" >> /tmp/radiolist
echo "$CF2" >> /tmp/radiolist

View File

@ -1,25 +0,0 @@
#!/bin/sh
. /lib/functions.sh
log() {
logger -t "Save" "$@"
}
state=$1
state=$(echo "$state" | tr "|" ",")
uci set mesh.radio.radionumber=$(echo "$state" | cut -d, -f1)
uci set mesh.radio.channelindex=$(echo "$state" | cut -d, -f2)
uci set mesh.radio.channellist=$(echo "$state" | cut -d, -f3)
uci set mesh.radio.usedfs=$(echo "$state" | cut -d, -f4)
uci set mesh.radio.channelwidth=$(echo "$state" | cut -d, -f5)
uci set mesh.radio.dedicated=$(echo "$state" | cut -d, -f6)
uci set mesh.network.networkid=$(echo "$state" | cut -d, -f7)
uci set mesh.network.netencrypted=$(echo "$state" | cut -d, -f8)
uci set mesh.network.netpassword=$(echo "$state" | cut -d, -f9)
uci set mesh.roam.signalenable=$(echo "$state" | cut -d, -f10)
uci set mesh.roam.signalid=$(echo "$state" | cut -d, -f11)
uci commit mesh

View File

@ -1,16 +0,0 @@
#!/bin/sh
. /lib/functions.sh
log() {
logger -t "Save" "$@"
}
state=$1
PKI_DIR="/www"
cd ${PKI_DIR}
mkdir -p package
cd ..
chmod -R 0777 ${PKI_DIR}/package
echo "$state" > ${PKI_DIR}/package/meshcfg.meshcfg

View File

@ -1,8 +0,0 @@
#!/bin/sh
. /lib/functions.sh
log() {
logger -t "Start Mesh" "$@"
}
/usr/lib/mesh/checker.sh 1

View File

@ -1 +0,0 @@
Raphael.fn.connection=function(a,b,c){var d=this,e={draw:function(){for(var f=a.getBBox(),g=b.getBBox(),h=0,i=0,j=[{x:f.x+f.width/2,y:f.y-h},{x:f.x+f.width/2,y:f.y+f.height+h},{x:f.x-h,y:f.y+f.height/2},{x:f.x+f.width+h,y:f.y+f.height/2},{x:g.x+g.width/2,y:g.y-i},{x:g.x+g.width/2,y:g.y+g.height+i},{x:g.x-i,y:g.y+g.height/2},{x:g.x+g.width+i,y:g.y+g.height/2}],k={},l=[],m=0;m<4;m++)for(var n=4;n<8;n++){var o=Math.abs(j[m].x-j[n].x),p=Math.abs(j[m].y-j[n].y);(m==n-4||(3!=m&&6!=n||j[m].x<j[n].x)&&(2!=m&&7!=n||j[m].x>j[n].x)&&(0!=m&&5!=n||j[m].y>j[n].y)&&(1!=m&&4!=n||j[m].y<j[n].y))&&(l.push(o+p),k[l[l.length-1].toFixed(3)]=[m,n])}var q=0==l.length?[0,4]:k[Math.min.apply(Math,l).toFixed(3)],r=j[q[0]].x,s=j[q[0]].y,t=j[q[1]].x,u=j[q[1]].y,o=Math.max(Math.abs(r-t)/2,10),p=Math.max(Math.abs(s-u)/2,10),v=[r,r,r-o,r+o][q[0]].toFixed(3),w=[s-p,s+p,s,s][q[0]].toFixed(3),x=[0,0,0,0,t,t,t-o,t+o][q[1]].toFixed(3),y=[0,0,0,0,s+p,s-p,u,u][q[1]].toFixed(3),z=["M",r.toFixed(3),s.toFixed(3),"C",v,w,x,y,t.toFixed(3),u.toFixed(3)].join(",");if(c&&c.directed){var A=Math.sqrt((u-y)*(u-y)+(t-x)*(t-x)),B=function(a,b){return-a*(b||5)/A},C=[{x:(B(t-x)+B(u-y)+t).toFixed(3),y:(B(u-y)+B(t-x)+u).toFixed(3)},{x:(B(t-x)-B(u-y)+t).toFixed(3),y:(B(u-y)-B(t-x)+u).toFixed(3)}];z=z+",M"+C[0].x+","+C[0].y+",L"+t+","+u+",L"+C[1].x+","+C[1].y}var D="attr";e.fg&&e.fg[D]({path:z})||(e.fg=d.path(z).attr({stroke:c&&c.stroke||"#000",fill:"none"}).toBack()),e.bg&&e.bg[D]({path:z})||c&&c.fill&&(e.bg=c.fill.split&&d.path(z).attr({stroke:c.fill.split("|")[0],fill:"none","stroke-width":c.fill.split("|")[1]||3}).toBack()),c&&c.label&&(e.label&&e.label.attr({x:(r+t)/2,y:(s+u)/2})||(e.label=d.text((r+t)/2,(s+u)/2,c.label).attr({fill:"#000","font-size":c["font-size"]||"12px"}))),c&&c.label&&c["label-style"]&&e.label&&e.label.attr(c["label-style"]),c&&c.callback&&c.callback(e)}};return e.draw(),e};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,154 +0,0 @@
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);

View File

@ -1,8 +0,0 @@
'use strict';
'require network';
return network.registerProtocol('batadv', {
getI18n: function() {
return _('Batman');
}
});

View File

@ -1,8 +0,0 @@
'use strict';
'require network';
return network.registerProtocol('batadv_hardif', {
getI18n: function() {
return _('Mesh');
}
});

View File

@ -1,29 +0,0 @@
#Owned by DairyMan@Whirlpool
#
#Copyright GNU act.
include $(TOPDIR)/rules.mk
PKG_NAME:=mesh-wpad
PKG_VERSION:=1.000
PKG_RELEASE:=1
PKG_MAINTAINER:=Created by DM/makefile by Cobia@whirlpool
include $(INCLUDE_DIR)/package.mk
define Package/mesh-wpad
SECTION:=utils
CATEGORY:=ROOter
SUBMENU:=Mesh Support
DEPENDS:=+wpad-mesh-openssl
TITLE:=Support for Mesh routing
PKGARCH:=all
endef
define Package/mesh-wpad/description
Helper scripts to install Meshing
endef
define Build/Compile
endef
$(eval $(call BuildPackage,mesh-wpad))

View File

@ -4,17 +4,6 @@ config general 'general'
option backup '30' option backup '30'
option enabled '1' option enabled '1'
config bwwan 'bwwan'
option wan '1'
config backup 'backup' config bwwan 'bwwan'
option dailytotal '0' option wan '0'
option dailyrx '0'
option dailytx '0'
option montotal '0'
option monrx '0'
option montx '0'
option days '1'
option year '0'
option month '0'
option day '0'

View File

@ -9,20 +9,10 @@ start() {
uci set bwmon.general.enabled=1 uci set bwmon.general.enabled=1
uci commit bwmon uci commit bwmon
fi fi
WX=$(uci -q get bwmon.backup) /usr/lib/bwmon/wrtbwmon.sh &
if [ -z "$WX" ]; then /usr/lib/bwmon/create.sh &
uci set bwmon.backup='backup' }
uci set bwmon.backup.dailytotal='0'
uci set bwmon.backup.dailyrx='0' stop() {
uci set bwmon.backup.dailytx='0' rmdir -f /tmp/WRTbmon
uci set bwmon.backup.montotal='0'
uci set bwmon.backup.monrx='0'
uci set bwmon.backup.montx='0'
uci set bwmon.backup.days='1'
uci set bwmon.backup.year='0'
uci set bwmon.backup.month='0'
uci set bwmon.backup.day='0'
uci commit bwmon
fi
/usr/lib/bwmon/bwmon.sh &
} }

View File

@ -12,10 +12,10 @@ if [ $amount != "0" ]; then
else else
sleep 3 sleep 3
fi fi
result=`ps | grep -i "createdata.lua" | grep -v "grep" | wc -l` result=`ps | grep -i "create_data.lua" | grep -v "grep" | wc -l`
while [ $result -ge 1 ]; do while [ $result -ge 1 ]; do
sleep 2 sleep 2
result=`ps | grep -i "createdata.lua" | grep -v "grep" | wc -l` result=`ps | grep -i "create_data.lua" | grep -v "grep" | wc -l`
done done
lua /usr/lib/bwmon/createdata.lua lua /usr/lib/bwmon/create_data.lua

View File

@ -5,15 +5,15 @@ function ltrim(s)
end end
function calc(total) function calc(total)
if total < 1000000 then if total < 1000 then
tstr = string.format("%.2f", total/1000) tstr = string.format("%.2f", total)
tfm = " K" tfm = " K"
else else
if total < 1000000 then if total < 1000000 then
tstr = string.format("%.2f", total/1000000) tstr = string.format("%.2f", total/1000)
tfm = " MB" tfm = " MB"
else else
tstr = string.format("%.2f", total/1000000000) tstr = string.format("%.2f", total/1000000)
tfm = " GB" tfm = " GB"
end end
end end
@ -21,8 +21,8 @@ function calc(total)
return ltrim(str) return ltrim(str)
end end
aamt = tonumber(arg[1]) aamt = arg[1]
uamt = tonumber(arg[2]) uamt = arg[2]
if uamt > aamt then if uamt > aamt then
amt = uamt - aamt amt = uamt - aamt
amts = calc(amt) amts = calc(amt)

View File

@ -0,0 +1,61 @@
#!/usr/bin/lua
dailyUsageDB = arg[1]
bw = {}
maclist = {}
file = io.open(dailyUsageDB, "r")
i = 0
repeat
line = file:read("*line")
if line == nil then
break
end
s, e = line:find("\"mac\":\"")
bs, be = line:find("\"", e+1)
mac = line:sub(e+1, bs-1)
if bw[mac] == nil then
maclist[i] = mac
i = i + 1
bw[mac] = {}
bw[mac]['down'] = 0
bw[mac]['offdown'] = 0
bw[mac]['up'] = 0
bw[mac]['offup'] = 0
end
s, e = line:find("\"down\":\"")
bs, be = line:find("\"", e+1)
down = tonumber(line:sub(e+1, bs-1))
bw[mac]['down'] = bw[mac]['down'] + down
s, e = line:find("\"up\":\"")
bs, be = line:find("\"", e+1)
up = tonumber(line:sub(e+1, bs-1))
bw[mac]['up'] = bw[mac]['up'] + up
s, e = line:find("\"offdown\":\"")
bs, be = line:find("\"", e+1)
offdown = tonumber(line:sub(e+1, bs-1))
bw[mac]['offdown'] = bw[mac]['offdown'] + offdown
s, e = line:find("\"offup\":\"")
bs, be = line:find("\"", e+1)
offup = tonumber(line:sub(e+1, bs-1))
bw[mac]['offup'] = bw[mac]['offup'] + offup
s, e = line:find("\"ip\":\"")
bs, be = line:find("\"", e+1)
bw[mac]['ip'] = line:sub(e+1, bs-1)
s, e = line:find("\"name\":\"")
bs, be = line:find("\"", e+1)
bw[mac]['name'] = line:sub(e+1, bs-1)
until 1==0
file:close()
j=0
file = io.open(dailyUsageDB .. ".bk", "w")
while maclist[j] ~= nil do
mac = maclist[j]
dline = "\"mac\":\"" .. mac .. "\",\"down\":\"" .. bw[mac]['down'] .. "\",\"up\":\"" .. bw[mac]['up'] .. "\",\"offdown\":\"0\",\"offup\":\"0\",\"ip\":\"" .. bw[mac]['ip'] .. "\",\"name\":\"" .. bw[mac]['name'] .. "\""
file:write(dline, "\n")
j = j + 1
end
file:close()

View File

@ -0,0 +1,81 @@
#!/usr/bin/lua
monthUsageDB = arg[1]
tfile = io.open(monthUsageDB .. ".bk", "w")
tfile:close()
file = io.open(monthUsageDB, "r")
repeat
line = file:read("*line")
if line == nil then
break
end
s, e = line:find("start day")
if s ~= nil then
maclist = {}
bw = {}
i = 0
startday = line
repeat
line = file:read("*line")
if line == nil then
break
end
s, e = line:find("end day")
if s ~= nil then
endday = line
break
end
s, e = line:find("\"mac\":\"")
bs, be = line:find("\"", e+1)
mac = line:sub(e+1, bs-1)
if bw[mac] == nil then
maclist[i] = mac
i = i + 1
bw[mac] = {}
bw[mac]['down'] = 0
bw[mac]['offdown'] = 0
bw[mac]['up'] = 0
bw[mac]['offup'] = 0
end
s, e = line:find("\"down\":\"")
bs, be = line:find("\"", e+1)
down = tonumber(line:sub(e+1, bs-1))
bw[mac]['down'] = bw[mac]['down'] + down
s, e = line:find("\"up\":\"")
bs, be = line:find("\"", e+1)
up = tonumber(line:sub(e+1, bs-1))
bw[mac]['up'] = bw[mac]['up'] + up
s, e = line:find("\"offdown\":\"")
bs, be = line:find("\"", e+1)
offdown = tonumber(line:sub(e+1, bs-1))
bw[mac]['offdown'] = bw[mac]['offdown'] + offdown
s, e = line:find("\"offup\":\"")
bs, be = line:find("\"", e+1)
offup = tonumber(line:sub(e+1, bs-1))
bw[mac]['offup'] = bw[mac]['offup'] + offup
s, e = line:find("\"ip\":\"")
bs, be = line:find("\"", e+1)
bw[mac]['ip'] = line:sub(e+1, bs-1)
s, e = line:find("\"name\":\"")
bs, be = line:find("\"", e+1)
bw[mac]['name'] = line:sub(e+1, bs-1)
until 1==0
-- day data
j=0
tfile = io.open(monthUsageDB .. ".bk", "a")
tfile:write(startday, "\n")
while maclist[j] ~= nil do
mac = maclist[j]
dline = "\"mac\":\"" .. mac .. "\",\"down\":\"" .. bw[mac]['down'] .. "\",\"up\":\"" .. bw[mac]['up'] .. "\",\"offdown\":\"0\",\"offup\":\"0\",\"ip\":\"" .. bw[mac]['ip'] .. "\",\"name\":\"" .. bw[mac]['name'] .. "\""
tfile:write(dline, "\n")
j = j + 1
end
tfile:write(endday, "\n")
tfile:close()
end
until 1==0
file:close()

View File

@ -0,0 +1,51 @@
#!/bin/sh
log() {
logger -t "wrtbwmon" "$@"
}
# parameters
#
btype=$1
cDay=$2
monthlyUsageDB=$3
dailyUsageDB=$4
monthlyUsageBack=$5
dailyUsageBack=$6
pDay=$7
/usr/lib/bwmon/backup-daily.lua $dailyUsageDB
/usr/lib/bwmon/backup-mon.lua $monthlyUsageDB
cp -f $monthlyUsageDB".bk" $monthlyUsageDB
cp -f $dailyUsageDB".bk" $dailyUsageDB
echo "start day $cDay" >> $monthlyUsageDB".bk"
cat $dailyUsageDB".bk" >> $monthlyUsageDB".bk"
echo "end day $cDay" >> $monthlyUsageDB".bk"
enb=$(uci -q get bwmon.general.enabled)
if [ $btype = "backup" ]; then
if [ "$enb" = "1" ]; then
cp -f $monthlyUsageDB".bk" $monthlyUsageBack
cp -f $dailyUsageDB".bk" $dailyUsageBack
fi
else
if [ $btype = "daily" ]; then
cp -f $monthlyUsageDB".bk" $monthlyUsageDB
if [ "$enb" = "1" ]; then
cp -f $monthlyUsageDB".bk" $monthlyUsageBack
fi
fi
fi
rm -f $dailyUsageDB".bk"
bwday=$(uci -q get modem.modeminfo1.bwday)
if [ ! -z "$bwday" ]; then
if [ $bwday = $pDay -a $bwday != "0" ]; then
if [ -e /usr/lib/bwmon/sendsms ]; then
/usr/lib/bwmon/sendsms.sh
fi
fi
fi

View File

@ -1,378 +0,0 @@
#!/bin/sh
. /usr/share/libubox/jshn.sh
. /lib/functions.sh
log() {
modlog "wrtbwmon" "$@"
}
ifname1="ifname"
if [ -e /etc/newstyle ]; then
ifname1="device"
fi
networkFuncs=/lib/functions/network.sh
uci=`which uci 2>/dev/null`
nslookup=`which nslookup 2>/dev/null`
nvram=`which nvram 2>/dev/null`
binDir=/usr/sbin
setbackup() {
extn=$(uci -q get bwmon.general.external)
if [ "$extn" = "0" ]; then
backPath=/usr/lib/bwmon/bwdata/
else
if [ -e "$extn""/" ]; then
backPath=$extn"/data/"
else
backPath=/usr/lib/bwmon/bwdata/
uci set bwmon.general.external="0"
uci commit bwmon
fi
fi
if [ ! -e "$backpath" ]; then
mkdir -p $backPath
fi
}
detectIF()
{
if [ -f "$networkFuncs" ]; then
IF=`. $networkFuncs; network_get_device netdev $1; echo $netdev`
[ -n "$IF" ] && echo $IF && return
fi
if [ -n "$uci" -a -x "$uci" ]; then
IF=`$uci get network.${1}.$ifname 2>/dev/null`
[ $? -eq 0 -a -n "$IF" ] && echo $IF && return
fi
if [ -n "$nvram" -a -x "$nvram" ]; then
IF=`$nvram get ${1}_$ifname 2>/dev/null`
[ $? -eq 0 -a -n "$IF" ] && echo $IF && return
fi
}
detectWAN()
{
[ -n "$WAN_IF" ] && echo $WAN_IF && return
wan=$(detectIF wan)
[ -n "$wan" ] && echo $wan && return
wan=$(ip route show 2>/dev/null | grep default | sed -re '/^default/ s/default.*dev +([^ ]+).*/\1/')
[ -n "$wan" ] && echo $wan && return
[ -f "$networkFuncs" ] && wan=$(. $networkFuncs; network_find_wan wan; echo $wan)
[ -n "$wan" ] && echo $wan && return
}
device_get_stats() {
iface=$1
st=$(ubus -v call network.interface.$iface status)
json_init
json_load "$st"
json_get_var iface l3_device
json_get_var status up
if [ $status = "1" ]; then
js="{ \"name\": \"$iface\" }"
st=$(ubus -v call network.device status "$js")
json_init
json_load "$st"
json_select statistics &>/dev/null
json_get_var val $2
else
val="0"
fi
echo $val
}
update() {
interfaces=""
wan=$(detectWAN)
C1=$(uci -q get modem.modem1.connected)
C2=$(uci -q get modem.modem2.connected)
if [ "$C1" = "1" ]; then
interfaces="wan1"
fi
if [ "$C2" = "1" ]; then
interfaces="interfaces wan2"
fi
WW=$(uci -q get bwmon.bwwan.wan)
if [ "$WW" -eq 1 ]; then
interfaces="$interfaces wan wwan2 wwan5"
fi
val="0"
rxval="0"
txval="0"
for interface in $interfaces; do
rval=$(device_get_stats $interface "rx_bytes")
let rxval=$rxval+$rval
tval=$(device_get_stats $interface "tx_bytes")
let txval=$txval+$tval
done
#log "Offset $offsetotal $offsetrx $offsettx"
orxval=$rxval
otxval=$txval
let xval=$rxval+$txval
otot=$xval
let val=$val+$xval
#log "Update $val $rxval $txval"
let rxval=$rxval-$offsetrx
let txval=$txval-$offsettx
let val=$val-$offsetotal
rtxval=$val
# backup daily values
let ttotal=$basedailytotal+$val
let trx=$basedailyrx+$rxval
let ttx=$basedailytx+$txval
echo "$ttotal" > $dataPath"daily.js"
echo "$trx" >> $dataPath"daily.js"
echo "$ttx" >> $dataPath"daily.js"
cd=$cDay
if [ $cd -lt 10 ]; then
ct="0"$cd
fi
dt="$cYear-$cMonth-$cd"
echo "$dt" >> $dataPath"daily.js"
# backup monthly values
let mtotal=$basemontotal+$val
let mrx=$basemonrx+$rxval
let mtx=$basemontx+$txval
alloc=$(uci -q get custom.bwallocate.allocate)
if [ -z "$alloc" ]; then
alloc=1000000000
else
alloc=$alloc"000000000"
fi
/usr/lib/bwmon/excede.sh $mtotal $alloc
if [ -e /usr/lib/bwmon/period.sh ]; then
/usr/lib/bwmon/period.sh "$mtotal"
fi
}
createAmt()
{
while [ true ]; do
valid=$(cat /var/state/dnsmasqsec)
st=$(echo "$valid" | grep "ntpd says time is valid")
if [ ! -z "$st" ]; then
break
fi
sleep 10
done
cYear=$(uci -q get bwmon.backup.year)
if [ "$cYear" = '0' ]; then
cYear=$(date +%Y)
cDay=$(date +%d)
cMonth=$(date +%m)
uci set bwmon.backup.year=$cYear
uci set bwmon.backup.month=$cMonth
uci set bwmon.backup.day=$cDay
uci commit bwmon
else
cYear=$(uci -q get bwmon.backup.year)
cMonth=$(uci -q get bwmon.backup.month)
cDay=$(uci -q get bwmon.backup.day)
fi
basedailytotal=$(uci -q get bwmon.backup.dailytotal)
basedailyrx=$(uci -q get bwmon.backup.dailyrx)
basedailytx=$(uci -q get bwmon.backup.dailytx)
basemontotal=$(uci -q get bwmon.backup.montotal)
basemonrx=$(uci -q get bwmon.backup.monrx)
basemontx=$(uci -q get bwmon.backup.montx)
if [ -z "$1" ]; then
offsetotal='0'
offsetrx='0'
offsettx='0'
else
offsetotal=$otot
offsetrx=$orxval
offsettx=$otxval
fi
}
checkTime()
{
pDay=$(date +%d)
pYear=$(date +%Y)
pMonth=$(date +%m)
#pDay=$(uci -q get bwmon.backup.tday)
if [ "$cDay" -ne "$pDay" ]; then
#log "Day Changed"
# save to periodic
/usr/lib/bwmon/createdata.lua
bt=$(uci -q get custom.bwday)
if [ -z "$bt" ]; then
uci set custom.bwday='bwday'
fi
uci set custom.bwday.bwday=$(convert_bytes $mtotal)
uci commit custom
bwday=$(uci -q get modem.modeminfo1.bwday)
if [ ! -z "$bwday" ]; then
if [ $bwday = $pDay -a $bwday != "0" ]; then
if [ -e /usr/lib/bwmon/sendsms ]; then
/usr/lib/bwmon/sendsms.sh &
fi
fi
fi
# backup month
offsetotal=$rtxval
offsetrx=$rxval
offsettx=$txval
#log "Offset $offsetotal $offsetrx $offsettx"
uci set bwmon.backup.montotal=$mtotal
uci set bwmon.backup.monrx=$mrx
uci set bwmon.backup.montx=$mtx
# clear daily
basedailytotal='0'
uci set bwmon.backup.dailytotal='0'
basedailyrx='0'
uci set bwmon.backup.dailyrx='0'
basedailytx='0'
uci set bwmon.backup.dailytx='0'
# increase days
days=$(uci -q get bwmon.backup.days)
let days=$days+1
uci set bwmon.backup.days=$days
# day and date
uci set bwmon.backup.year=$pYear
uci set bwmon.backup.month=$pMonth
uci set bwmon.backup.day=$pDay
uci commit bwmon
basemontotal=$(uci -q get bwmon.backup.montotal)
basemonrx=$(uci -q get bwmon.backup.monrx)
basemontx=$(uci -q get bwmon.backup.montx)
cDay=$pDay
cMonth=$pMonth
cYear=$pYear
roll=$(uci -q get custom.bwallocate.rollover)
[ -z $roll ] && roll=1
if [ "$roll" -eq "$pDay" ]; then
#log "Month Change"
# clear monthly
basemontotal='0'
mtotal='0'
uci set bwmon.backup.montotal='0'
basemonrx='0'
mrx='0'
uci set bwmon.backup.monrx='0'
basemontx='0'
mtx='0'
uci -q get bwmon.backup.montx='0'
# reset days
uci set bwmon.backup.days='1'
uci commit bwmon
uci set custom.texting.used='0'
uci commit custom
if [ -e /usr/lib/bwmon/periodreset.sh ]; then
/usr/lib/bwmon/periodreset.sh
fi
fi
fi
}
checkBackup()
{
CURRTIME=$(date +%s)
let ELAPSE=CURRTIME-STARTIMEZ
bs=$(uci -q get bwmon.general.backup)
#bs="1"
let "bs=$bs*60"
backup_time=$bs
en=$(uci -q get bwmon.general.enabled)
if [ "$en" = '1' ]; then
if [ $ELAPSE -gt $backup_time ]; then
STARTIMEZ=$CURRTIME
# save monthly
uci set bwmon.backup.montotal=$mtotal
uci set bwmon.backup.monrx=$mrx
uci set bwmon.backup.montx=$mtx
# save daily
uci set bwmon.backup.dailytotal=$ttotal
uci set bwmon.backup.dailyrx=$trx
uci set bwmon.backup.dailytx=$ttx
# save day and date
uci set bwmon.backup.year=$cYear
uci set bwmon.backup.month=$cMonth
uci set bwmon.backup.day=$cDay
# total days
uci commit bwmon
#log "Backup $mtotal $val"
fi
fi
}
convert_bytes() {
local val=$1
rm -f /tmp/bytes
/usr/lib/bwmon/convertbytes.lua $val
source /tmp/bytes
echo "$BYTES"
}
createGUI()
{
days=$(uci -q get bwmon.backup.days)
echo "$days" > /tmp/bwdata
tb=$(convert_bytes $mtotal)
echo "$mtotal" >> /tmp/bwdata
echo "$tb" >> /tmp/bwdata
tb=$(convert_bytes $mrx)
echo "$mrx" >> /tmp/bwdata
echo "$tb" >> /tmp/bwdata
tb=$(convert_bytes $mtx)
echo "$mtx" >> /tmp/bwdata
echo "$tb" >> /tmp/bwdata
let ptotal=$mtotal/$days
let ptotal=$ptotal*30
tb=$(convert_bytes $ptotal)
echo "$ptotal" >> /tmp/bwdata
echo "$tb" >> /tmp/bwdata
alloc=$(uci -q get custom.bwallocate.allocate)
pass=$(uci -q get custom.bwallocate.password)
if [ -z "$alloc" ]; then
alloc=1000000000
pass="password"
else
alloc=$alloc"000000000"
fi
tb=$(convert_bytes $alloc)
echo "$alloc" >> /tmp/bwdata
echo "$tb" >> /tmp/bwdata
echo "$pass" >> /tmp/bwdata
echo "0" >> /tmp/bwdata
}
basePath="/tmp/bwmon/"
mkdir -p $basePath"bwdata"
dataPath=$basePath"bwdata/"
setbackup
STARTIMEX=$(date +%s)
STARTIMEY=$(date +%s)
STARTIMEZ=$(date +%s)
update_time=20
createAmt
while [ true ] ; do
update
if [ -e /tmp/bwchange ]; then
newamt=$(cat /tmp/bwchange)
rm -f /tmp/bwchange
uci set bwmon.backup.dailytotal=$newamt
uci set bwmon.backup.dailyrx=$newamt
uci set bwmon.backup.dailytx=0
uci set bwmon.backup.montotal=$newamt
uci set bwmon.backup.monrx=$newamt
uci set bwmon.backup.montx=0
uci commit bwmon
createAmt 1
mtotal=0
mrx=0
mtx=0
createGUI
fi
checkTime
checkBackup
createGUI
#log "$(convert_bytes $mtotal) $(convert_bytes $mrx) $(convert_bytes $mtx) $(convert_bytes $val) $(convert_bytes $rxval) $(convert_bytes $txval)"
sleep $update_time
done

View File

@ -0,0 +1,32 @@
#!/usr/bin/lua
filepost = "-mac_data.js"
dirname = '/usr/lib/bwmon/data'
function clean()
nummon = 0
months = {}
f = io.popen('/bin/ls ' .. dirname)
for name in f:lines() do
s, e = name:find(filepost)
if s ~= nil then
nummon = nummon + 1
months[nummon] = dirname .. "/" .. name
end
end
f:close()
count = 1
if nummon > 0 then
for i=nummon,1,-1 do
if count > 3 then
os.execute("rm -f " .. months[i])
end
count = count + 1
end
end
end
clean()
dirname = '/tmp/bwmon/data'
clean()

View File

@ -1,30 +0,0 @@
#!/usr/bin/lua
bytes=arg[1]
function ltrim(s)
return s:match'^%s*(.*)'
end
function calc(total)
if total < 1000000 then
tstr = string.format("%.2f", total)
tstr = string.format("%.2f", total/1000)
tfm = " K"
else
if total < 1000000000 then
tstr = string.format("%.2f", total/1000000)
tfm = " MB"
else
tstr = string.format("%.2f", total/1000000000)
tfm = " GB"
end
end
str = tstr .. tfm
return ltrim(str)
end
conbytes = "BYTES='" .. calc(tonumber(bytes)) .. "'"
tfile = io.open("/tmp/bytes", "w")
tfile:write(conbytes, "\n")
tfile:close()

View File

@ -0,0 +1,16 @@
#!/bin/sh
log() {
logger -t "createdata" "$@"
}
lua /usr/lib/bwmon/create_data.lua
sleep 60
while [ true ]
do
result=`ps | grep -i "create_data.lua" | grep -v "grep" | wc -l`
if [ $result -lt 1 ]; then
lua /usr/lib/bwmon/create_data.lua
fi
sleep 60
done

View File

@ -0,0 +1,193 @@
#!/usr/bin/lua
dirname = '/tmp/bwmon/data'
filepost = "-mac_data.js.bk"
bw = {}
maclist = {}
devices = {}
totaldevices = 0
totaldown = 0
totalup = 0
total = 0
printf = function(s,...)
local ss = s:format(...)
os.execute("/usr/lib/rooter/logprint.sh " .. ss)
end
function ltrim(s)
return s:match'^%s*(.*)'
end
function calc(total)
if total < 1000 then
tstr = string.format("%.2f", total)
tfm = " K"
else
if total < 1000000 then
tstr = string.format("%.2f", total/1000)
tfm = " MB"
else
tstr = string.format("%.2f", total/1000000)
tfm = " GB"
end
end
str = tstr .. tfm
return ltrim(str)
end
function monthly(datafile)
file = io.open(datafile, "r")
i = 0
dayx = 0
repeat
line = file:read("*line")
if line == nil then
break
end
s, e = line:find("start day")
if s ~= nil then
dayx = dayx + 1
repeat
line = file:read("*line")
s, e = line:find("end day")
if s ~= nil then
break
end
s, e = line:find("\"mac\":\"")
bs, be = line:find("\"", e+1)
mac = line:sub(e+1, bs-1)
if bw[mac] == nil then
maclist[i] = mac
i = i + 1
bw[mac] = {}
bw[mac]['down'] = 0
bw[mac]['offdown'] = 0
bw[mac]['up'] = 0
bw[mac]['offup'] = 0
end
s, e = line:find("\"down\":\"")
bs, be = line:find("\"", e+1)
down = tonumber(line:sub(e+1, bs-1))
bw[mac]['down'] = bw[mac]['down'] + down
s, e = line:find("\"up\":\"")
bs, be = line:find("\"", e+1)
up = tonumber(line:sub(e+1, bs-1))
bw[mac]['up'] = bw[mac]['up'] + up
s, e = line:find("\"offdown\":\"")
bs, be = line:find("\"", e+1)
offdown = tonumber(line:sub(e+1, bs-1))
bw[mac]['offdown'] = bw[mac]['offdown'] + offdown
s, e = line:find("\"offup\":\"")
bs, be = line:find("\"", e+1)
offup = tonumber(line:sub(e+1, bs-1))
bw[mac]['offup'] = bw[mac]['offup'] + offup
s, e = line:find("\"ip\":\"")
bs, be = line:find("\"", e+1)
bw[mac]['ip'] = line:sub(e+1, bs-1)
s, e = line:find("\"name\":\"")
bs, be = line:find("\"", e+1)
bw[mac]['name'] = line:sub(e+1, bs-1)
until 1==0
end
until 1==0
file:close()
return dayx
end
function totals(bw, maclist, dayz)
totaldown = 0
totalup = 0
utotaldown = 0
utotalup = 0
j=0
while maclist[j] ~= nil do
totaldown = totaldown + bw[maclist[j]]['down']
totalup = totalup + bw[maclist[j]]['up']
utotaldown = utotaldown + bw[maclist[j]]['offdown']
utotalup = utotalup + bw[maclist[j]]['offup']
j = j + 1
end
total = totalup + totaldown
ptotal = (total / dayz) * 30
end
function showdevices(bw, maclist)
k = 0
while maclist[k] ~= nil do
k = k + 1
end
if k > 0 then
j = 0
while maclist[j] ~= nil do
dtot = bw[maclist[j]]['down'] + bw[maclist[j]]['up']
devices[j] = bw[maclist[j]]['ip'] .."|" .. maclist[j]
devices[j] = devices[j] .. "|" .. calc(bw[maclist[j]]['down']) .. "|" .. calc(bw[maclist[j]]['up'])
devices[j] = devices[j] .. "|" .. calc(dtot) .. "|" .. bw[maclist[j]]['name']
j = j + 1
end
end
totaldevices = j
end
os.execute("echo 0 > /tmp/lockbw")
dataname = nil
f = io.popen('/bin/ls ' .. dirname)
for name in f:lines() do
s, e = name:find(filepost)
if s ~= nil then
dataname = dirname .. "/" .. name
end
end
f:close()
if dataname ~= nil then
days = monthly(dataname)
totals(bw, maclist, days)
tfile = io.open("/tmp/bwdata", "w")
tfile:write(days, "\n")
tfile:write(tostring(total), "\n")
tfile:write(calc(total), "\n")
tfile:write(tostring(totaldown), "\n")
tfile:write(calc(totaldown), "\n")
tfile:write(tostring(totalup), "\n")
tfile:write(calc(totalup), "\n")
tfile:write(tostring(ptotal), "\n")
tfile:write(calc(ptotal), "\n")
--
-- allocated bandwidth in K
--
bwallo='rm -f /tmp/bwallo; x=$(uci -q get custom.bwallocate.allocate); echo $x >> /tmp/bwallo; x=$(uci -q get custom.bwallocate.password); echo $x >> /tmp/bwallo'
os.execute(bwallo)
file = io.open("/tmp/bwallo", "r")
if file == nil then
allo = 1000000000
passw = "password"
else
allos = file:read("*line")
allo = tonumber(allos) * 1000000
passw = file:read("*line")
file:close()
end
tfile:write(tostring(allo), "\n")
tfile:write(calc(allo), "\n")
tfile:write(passw, "\n")
showdevices(bw, maclist)
tfile:write(tostring(totaldevices), "\n")
if totaldevices > 0 then
for i=0, totaldevices-1 do
tfile:write(devices[i], "\n")
end
end
tfile:close()
else
tfile = io.open("/tmp/bwdata", "w")
tfile:write("0\n")
tfile:write("0\n")
tfile:close()
end
os.execute("rm -f /tmp/lockbw")
os.execute("/usr/lib/bwmon/excede.sh " .. tostring(total) .. " " .. tostring(allo) .. " " .. tostring(ptotal))
os.execute("/usr/lib/bwmon/savetot.sh \"" .. calc(total) .. "\"")
os.execute("/usr/lib/bwmon/perday.lua")

View File

@ -1,127 +0,0 @@
#!/usr/bin/lua
monthly = '/usr/lib/bwmon/data/monthly.data'
datafile='/tmp/bwmon/bwdata/daily.js'
monline = {}
monlist = {}
function ltrim(s)
return s:match'^%s*(.*)'
end
function calc(total)
if total < 1000000 then
tstr = string.format("%.2f", total)
tstr = string.format("%.2f", total/1000)
tfm = " K"
else
if total < 1000000000 then
tstr = string.format("%.2f", total/1000000)
tfm = " MB"
else
tstr = string.format("%.2f", total/1000000000)
tfm = " GB"
end
end
str = tstr .. tfm
return ltrim(str)
end
local function bubblesort(a)
repeat
local swapped = false
for i = 1, table.getn(a) do
if a[i - 1] < a[i] then
a[i], a[i - 1] = a[i - 1], a[i]
swapped = true
end -- if
end -- for
until swapped == false
end
function ConBytes(line)
local s, e, bs, be
s, e = line:find(" ")
bs, be = line:find("K", e+1)
if bs == nil then
bs, be = line:find("MB", e+1)
if bs == nil then
val = tonumber(line:sub(1, e-1)) * 1000000000
else
val = tonumber(line:sub(1, e-1)) * 1000000
end
else
val = tonumber(line:sub(1, e-1)) * 1000
end
return val
end
kdwn = 0
kup = 0
ktotal = 0
file = io.open(datafile, "r")
if file ~= nil then
total = file:read("*line")
dwn = file:read("*line")
up = file:read("*line")
lin = file:read("*line")
file:close()
kdwn = tonumber(dwn)
kup = tonumber(up)
ktotal = tonumber(total)
dwn = calc(tonumber(dwn))
up = calc(tonumber(up))
total = calc(tonumber(total))
print(ktotal, kdwn, kup)
dataline = lin .. "|" .. dwn .. "|" .. up .. "|" .. total
print(dataline)
monline[lin] = dataline
monlist[0] = lin
ksize = 1
end
k = 1
tfile = io.open(monthly, "r")
if tfile ~= nil then
ksize = tfile:read("*line")
ksize = tostring(tonumber(ksize) + 1)
kdwn1 = tfile:read("*line")
kdwn1=ConBytes(kdwn1)
kdwn = (kdwn1 + kdwn)
kup1 = tfile:read("*line")
kup1=ConBytes(kup1)
kup = (kup1 + kup)
ktotal1 = tfile:read("*line")
ktotal1=ConBytes(ktotal1)
ktotal = (ktotal1 + ktotal)
repeat
line = tfile:read("*line")
if line == nil then
break
end
s, e = line:find("|")
ymd = line:sub(1, s-1)
monline[ymd] = line
monlist[k] = ymd
k = k + 1
until 1==0
tfile:close()
bubblesort(monlist)
end
if k > 30 then
k = 30
end
tfile = io.open(monthly, "w")
tfile:write(tostring(k), "\n")
tfile:write(calc(kdwn), "\n")
tfile:write(calc(kup), "\n")
tfile:write(calc(ktotal), "\n")
for j = 0,k-1
do
lin = monlist[j]
dataline = monline[lin]
print(dataline)
tfile:write(dataline, "\n")
end
tfile:close()
--os.execute("uci set custom.bwday.bwday=" .. calc(ktotal) .. ";uci commit custom")

View File

@ -4,7 +4,7 @@ prev = arg[1] -- previous increment in GB
incr = arg[2] -- fixed increment in GB incr = arg[2] -- fixed increment in GB
used = arg[3] -- amt used in Kb used = arg[3] -- amt used in Kb
used = used / 1000000000 -- used in GB used = used / 1000000 -- used in GB
current = prev + incr current = prev + incr
running = "0" running = "0"
if used >= current then if used >= current then

View File

@ -6,7 +6,7 @@ log() {
} }
getbw() { getbw() {
alloc=$(uci -q get custom.bwallocate.allocate)"000000000" alloc=$(uci -q get custom.bwallocate.allocate)"000000"
if [ -e /tmp/bwdata ]; then if [ -e /tmp/bwdata ]; then
while IFS= read -r line; do while IFS= read -r line; do
days=$line days=$line

View File

@ -22,10 +22,8 @@ do_throttle() {
fi fi
} }
bb="$(uci -q get custom.bwallocate.manual)" lock=$(uci -q get custom.bwallocate.lock)
if [ "$bb" != "1" ]; then if [ $lock = "1" ]; then
lock=$(uci -q get custom.bwallocate.lock)
if [ $lock = "1" ]; then
enb=$(uci -q get custom.bwallocate.enabled) enb=$(uci -q get custom.bwallocate.enabled)
if [ $enb = '1' ]; then if [ $enb = '1' ]; then
allocate=$2 allocate=$2
@ -38,8 +36,6 @@ if [ "$bb" != "1" ]; then
if [ ! -e /usr/lib/throttle/throttle.sh ]; then if [ ! -e /usr/lib/throttle/throttle.sh ]; then
action=0 action=0
fi fi
uci set custom.bwallocate.status='0'
uci commit custom
if [ $action != "2" ]; then if [ $action != "2" ]; then
if [ $total -gt $allocate ]; then if [ $total -gt $allocate ]; then
if [ $action = "0" ]; then if [ $action = "0" ]; then
@ -48,8 +44,6 @@ if [ "$bb" != "1" ]; then
else else
/usr/lib/bwmon/block 1 /usr/lib/bwmon/block 1
fi fi
uci set custom.bwallocate.status='1'
uci commit custom
else else
down=$(uci -q get custom.bwallocate.down) down=$(uci -q get custom.bwallocate.down)
if [ -z $down ]; then if [ -z $down ]; then
@ -60,8 +54,6 @@ if [ "$bb" != "1" ]; then
up=2 up=2
fi fi
/usr/lib/throttle/throttle.sh start $down $up /usr/lib/throttle/throttle.sh start $down $up
uci set custom.bwallocate.status='2'
uci commit custom
fi fi
else else
if [ -e /usr/lib/throttle/throttle.sh ]; then if [ -e /usr/lib/throttle/throttle.sh ]; then
@ -91,8 +83,6 @@ if [ "$bb" != "1" ]; then
source /tmp/float source /tmp/float
/usr/lib/throttle/throttle.sh start $SPEED $SPEED 1 /usr/lib/throttle/throttle.sh start $SPEED $SPEED 1
log "Throttled to $speed Mbps" log "Throttled to $speed Mbps"
uci set custom.bwallocate.status='2'
uci commit custom
else else
if [ -e /usr/lib/throttle/throttle.sh ]; then if [ -e /usr/lib/throttle/throttle.sh ]; then
/usr/lib/throttle/throttle.sh stop /usr/lib/throttle/throttle.sh stop
@ -101,5 +91,4 @@ if [ "$bb" != "1" ]; then
fi fi
fi fi
fi
fi fi

View File

@ -13,9 +13,12 @@ if [ "$ext" = "$external" ]; then
else else
uci set bwmon.general.external=$external uci set bwmon.general.external=$external
uci commit bwmon uci commit bwmon
PID=$(ps |grep "bwmon.sh" | grep -v grep |head -n 1 | awk '{print $1}') PID=$(ps |grep "wrtbwmon.sh" | grep -v grep |head -n 1 | awk '{print $1}')
PID1=$(ps |grep "create.sh" | grep -v grep |head -n 1 | awk '{print $1}')
if [ ! -z "$PID" ]; then if [ ! -z "$PID" ]; then
kill -9 $PID kill -9 $PID
kill -9 $PID1
fi fi
/usr/lib/bwmon/bwmon.sh & /usr/lib/bwmon/wrtbwmon.sh &
/usr/lib/bwmon/create.sh &
fi fi

View File

@ -1,64 +0,0 @@
#!/bin/sh
. /usr/share/libubox/jshn.sh
. /lib/functions.sh
genline() {
MONLIST=$MONLIST"<tr>"
t1="<td width=\"160px\"><div align=\"center\"><strong> $START</strong></div></td>"
t2="<td width=\"200px\"><div align=\"center\"><strong> $updata</strong></div></td>"
t3="<td width=\"150px\"><div align=\"center\"><strong> $downdata</strong></div></td>"
t4="<td width=\"150px\"><div align=\"center\"><strong> $totaldata</strong></div></td>"
t5="<td width=\"340\" ></td>"
MONLIST=$MONLIST$t1$t2$t3$t4$t5"</tr>"
}
bwdata() {
START="-"
END="-"
header=0
while IFS= read -r line; do
if [ $header -eq 0 ]; then
days=$line
read -r line
DOWN=$line
read -r line
UP=$line
read -r line
TOTAL=$line
read -r line
line=$(echo $line" " | tr "|" ",")
END=$(echo $line | cut -d, -f1)
START=$END
updata=$(echo $line | cut -d, -f2)
downdata=$(echo $line | cut -d, -f3)
totaldata=$(echo $line | cut -d, -f4)
genline
read -r line
header=1
if [ -z "$line" ]; then
break
fi
fi
line=$(echo $line" " | tr "|" ",")
START=$(echo $line | cut -d, -f1)
updata=$(echo $line | cut -d, -f2)
downdata=$(echo $line | cut -d, -f3)
totaldata=$(echo $line | cut -d, -f4)
genline
done < /usr/lib/bwmon/data/monthly.data
}
MONLIST=""
rm -f /tmp/monlist
rm -f /tmp/montot
if [ -e /usr/lib/bwmon/data/monthly.data ]; then
bwdata
echo $MONLIST > /tmp/monlist
echo $days > /tmp/montot
echo $DOWN >> /tmp/montot
echo $UP >> /tmp/montot
echo $TOTAL >> /tmp/montot
fi

View File

@ -0,0 +1,204 @@
#!/usr/bin/lua
function ltrim(s)
return s:match'^%s*(.*)'
end
function calc(total)
if total < 1000 then
tstr = string.format("%.2f", total)
tfm = " K"
else
if total < 1000000 then
tstr = string.format("%.2f", total/1000)
tfm = " MB"
else
tstr = string.format("%.2f", total/1000000)
tfm = " GB"
end
end
str = tstr .. tfm
return ltrim(str)
end
local function bubblesort(a)
repeat
local swapped = false
for i = 1, table.getn(a) do
if a[i - 1] < a[i] then
a[i], a[i - 1] = a[i - 1], a[i]
swapped = true
end -- if
end -- for
until swapped == false
end
function ConBytes(line)
local s, e, bs, be
s, e = line:find(" ")
bs, be = line:find("K", e+1)
if bs == nil then
bs, be = line:find("MB", e+1)
if bs == nil then
val = tonumber(line:sub(1, e-1)) * 1000000
else
val = tonumber(line:sub(1, e-1)) * 1000
end
else
val = tonumber(line:sub(1, e-1))
end
return val
end
dirname = '/usr/lib/bwmon/data'
filepost = "-mac_data.js"
monthly = dirname .. "/monthly.data"
daylist = {}
dayline = {}
monlist = {}
monline = {}
dataname = nil
f = io.popen('/bin/ls ' .. dirname)
for name in f:lines() do
s, e = name:find(filepost)
if s ~= nil then
dataname = name
end
end
f:close()
if dataname ~= nil then
yearmon = dataname:sub(1, 7)
datafile = dirname .. "/" .. dataname
file = io.open(datafile, "r")
i = 0
repeat
line = file:read("*line")
if line == nil then
break
end
s, e = line:find("start day")
if s ~= nil then
day = line:sub(e+1)
nday = tonumber(day)
day= tostring(nday)
if nday < 10 then
day = "0" .. day
end
yearmonday = yearmon .. "-" .. day
daydwn = 0
dayup = 0
repeat
line = file:read("*line")
s, e = line:find("end day")
if s ~= nil then
dayt = dayup + daydwn
if dayt > 0 then
daylist[i] = yearmonday
i = i + 1
dayline[yearmonday] = {}
dayline[yearmonday]['down'] = daydwn
dayline[yearmonday]['up'] = dayup
dayline[yearmonday]['total'] = dayup + daydwn
end
break
end
s, e = line:find("\"down\":\"")
bs, be = line:find("\"", e+1)
daydwn = daydwn + tonumber(line:sub(e+1, bs-1))
s, e = line:find("\"up\":\"")
bs, be = line:find("\"", e+1)
dayup = dayup + tonumber(line:sub(e+1, bs-1))
until 1==0
end
until 1==0
if i > 0 then
tfile = io.open(monthly, "r")
if tfile == nil then
for j = 0,i-1
do
lin = daylist[j]
monlist[j] = lin
monline[lin] = {}
dwn = calc(dayline[lin]['down'])
up = calc(dayline[lin]['up'])
total = calc(dayline[lin]['total'])
dataline = lin .. "|" .. dwn .. "|" .. up .. "|" .. total
monline[lin]['data'] = dataline
end
k = i
else
k = 0
ksize = tfile:read("*line")
kdwn = tfile:read("*line")
kup = tfile:read("*line")
ktotal = tfile:read("*line")
repeat
line = tfile:read("*line")
if line == nil then
break
end
ymd = line:sub(1,10)
monlist[k] = ymd
k = k + 1
monline[ymd] = {}
monline[ymd]['data'] = line
until 1==0
tfile:close()
for j = 0,i-1
do
lin = daylist[j]
if monline[lin] == nil then
monlist[k] = lin
k = k + 1
monline[lin] = {}
end
dwn = calc(dayline[lin]['down'])
up = calc(dayline[lin]['up'])
total = calc(dayline[lin]['total'])
dataline = lin .. "|" .. dwn .. "|" .. up .. "|" .. total
monline[lin]['data'] = dataline
end
end
bubblesort(monlist)
tfile = io.open(monthly, "w")
if k > 30 then
k = 30
end
tfile:write(tostring(k), "\n")
fdown = 0
fup = 0
ftotal = 0
for j = 0,k-1
do
lin = monlist[j]
dataline = monline[lin]['data']
s, e = dataline:find("|")
if s ~= nil then
bs, be = dataline:find("|", e+1)
fdown = ConBytes(dataline:sub(e+1, be-1)) + fdown
s, e = dataline:find("|", be+1)
fup = ConBytes(dataline:sub(be+1, e-1)) + fup
ftotal = ConBytes(dataline:sub(e+1)) + ftotal
end
end
tfile:write(calc(fdown), "\n")
tfile:write(calc(fup), "\n")
tfile:write(calc(ftotal), "\n")
for j = 0,k-1
do
lin = monlist[j]
dataline = monline[lin]['data']
tfile:write(dataline, "\n")
end
tfile:close()
end
file:close()
end

View File

@ -3,3 +3,18 @@
log() { log() {
logger -t "BWmon Process" "$@" logger -t "BWmon Process" "$@"
} }
running=0
if [ -e "/tmp/WRTbmon" ]; then
running=1
fi
sleep 5
if [ $running = 0 ]; then
log "Enable BandWidthMonitor"
/usr/lib/bwmon/wrtbwmon.sh &
fi

View File

@ -0,0 +1,10 @@
#!/bin/sh
log() {
logger -t "save total" "$@"
}
total=$1
uci set custom.bwday.bwday="$total"
uci commit custom

View File

@ -60,7 +60,7 @@ checktime() {
} }
getbw() { getbw() {
alloc=$(uci -q get custom.bwallocate.allocate)"000000000" alloc=$(uci -q get custom.bwallocate.allocate)"000000"
if [ -e /tmp/bwdata ]; then if [ -e /tmp/bwdata ]; then
while IFS= read -r line; do while IFS= read -r line; do
days=$line days=$line

Some files were not shown because too many files have changed in this diff Show More