expect: { '': {} }
});
-var _cache = {},
- _flush = true,
+var _init = null,
_state = null,
- _protocols = {};
-
-function getWifiState(flush) {
- if (_cache.wifi == null || flush)
- return callNetworkWirelessStatus().then(function(state) {
- if (!L.isObject(state))
- throw !1;
- return (_cache.wifi = state);
- }).catch(function() {
- return (_cache.wifi = {});
- });
-
- return Promise.resolve(_cache.wifi);
+ _protocols = {},
+ _protospecs = {};
+
+function getWifiState(cache) {
+ return callNetworkWirelessStatus().then(function(state) {
+ if (!L.isObject(state))
+ throw !1;
+ return state;
+ }).catch(function() {
+ return {};
+ });
}
-function getInterfaceState(flush) {
- if (_cache.interfacedump == null || flush)
- return callNetworkInterfaceStatus().then(function(state) {
- if (!Array.isArray(state))
- throw !1;
- return (_cache.interfacedump = state);
- }).catch(function() {
- return (_cache.interfacedump = []);
- });
-
- return Promise.resolve(_cache.interfacedump);
+function getInterfaceState(cache) {
+ return callNetworkInterfaceStatus().then(function(state) {
+ if (!Array.isArray(state))
+ throw !1;
+ return state;
+ }).catch(function() {
+ return [];
+ });
}
-function getDeviceState(flush) {
- if (_cache.devicedump == null || flush)
- return callNetworkDeviceStatus().then(function(state) {
- if (!L.isObject(state))
- throw !1;
- return (_cache.devicedump = state);
- }).catch(function() {
- return (_cache.devicedump = {});
- });
-
- return Promise.resolve(_cache.devicedump);
+function getDeviceState(cache) {
+ return callNetworkDeviceStatus().then(function(state) {
+ if (!L.isObject(state))
+ throw !1;
+ return state;
+ }).catch(function() {
+ return {};
+ });
}
-function getIfaddrState(flush) {
- if (_cache.ifaddrs == null || flush)
- return callLuciIfaddrs().then(function(addrs) {
- if (!Array.isArray(addrs))
- throw !1;
- return (_cache.ifaddrs = addrs);
- }).catch(function() {
- return (_cache.ifaddrs = []);
- });
-
- return Promise.resolve(_cache.ifaddrs);
+function getIfaddrState(cache) {
+ return callLuciIfaddrs().then(function(addrs) {
+ if (!Array.isArray(addrs))
+ throw !1;
+ return addrs;
+ }).catch(function() {
+ return [];
+ });
}
-function getNetdevState(flush) {
- if (_cache.devices == null || flush)
- return callLuciNetdevs().then(function(state) {
- if (!L.isObject(state))
- throw !1;
- return (_cache.devices = state);
- }).catch(function() {
- return (_cache.devices = {});
- });
-
- return Promise.resolve(_cache.devices);
+function getNetdevState(cache) {
+ return callLuciNetdevs().then(function(state) {
+ if (!L.isObject(state))
+ throw !1;
+ return state;
+ }).catch(function() {
+ return {};
+ });
}
-function getBoardState(flush) {
- if (_cache.board == null || flush)
- return callLuciBoardjson().then(function(state) {
- if (!L.isObject(state))
- throw !1;
- return (_cache.board = state);
- }).catch(function() {
- return (_cache.board = {});
- });
-
- return Promise.resolve(_cache.board);
+function getBoardState(cache) {
+ return callLuciBoardjson().then(function(state) {
+ if (!L.isObject(state))
+ throw !1;
+ return state;
+ }).catch(function() {
+ return {};
+ });
}
-function getProtocolHandlers(flush) {
- if (_cache.protocols == null || flush)
- return callGetProtoHandlers().then(function(protos) {
- if (!L.isObject(protos))
- throw !1;
+function getProtocolHandlers(cache) {
+ return callGetProtoHandlers().then(function(protos) {
+ if (!L.isObject(protos))
+ throw !1;
- _cache.protocols = protos;
+ Object.assign(_protospecs, protos);
- return Promise.all(Object.keys(protos).map(function(p) {
- return Promise.resolve(L.require('protocol.%s'.format(p))).catch(function(err) {
- if (L.isObject(err) && err.name != 'NetworkError')
- L.error(err);
- });
- })).then(function() {
- return _cache.protocols;
+ return Promise.all(Object.keys(protos).map(function(p) {
+ return Promise.resolve(L.require('protocol.%s'.format(p))).catch(function(err) {
+ if (L.isObject(err) && err.name != 'NetworkError')
+ L.error(err);
});
- }).catch(function() {
- return (_cache.protocols = {});
+ })).then(function() {
+ return protos;
});
-
- return Promise.resolve(_cache.protocols);
+ }).catch(function() {
+ return {};
+ });
}
function getWifiStateBySid(sid) {
var s = uci.get('wireless', sid);
if (s != null && s['.type'] == 'wifi-iface') {
- for (var radioname in _cache.wifi) {
- for (var i = 0; i < _cache.wifi[radioname].interfaces.length; i++) {
- var netstate = _cache.wifi[radioname].interfaces[i];
+ for (var radioname in _state.radios) {
+ for (var i = 0; i < _state.radios[radioname].interfaces.length; i++) {
+ var netstate = _state.radios[radioname].interfaces[i];
if (typeof(netstate.section) != 'string')
continue;
var s2 = uci.get('wireless', netstate.section);
if (s2 != null && s['.type'] == s2['.type'] && s['.name'] == s2['.name'])
- return [ radioname, _cache.wifi[radioname], netstate ];
+ return [ radioname, _state.radios[radioname], netstate ];
}
}
}
}
function getWifiStateByIfname(ifname) {
- for (var radioname in _cache.wifi) {
- for (var i = 0; i < _cache.wifi[radioname].interfaces.length; i++) {
- var netstate = _cache.wifi[radioname].interfaces[i];
+ for (var radioname in _state.radios) {
+ for (var i = 0; i < _state.radios[radioname].interfaces.length; i++) {
+ var netstate = _state.radios[radioname].interfaces[i];
if (typeof(netstate.ifname) != 'string')
continue;
if (netstate.ifname == ifname)
- return [ radioname, _cache.wifi[radioname], netstate ];
+ return [ radioname, _state.radios[radioname], netstate ];
}
}
rv = false;
if (isArray == false)
- values = String(values || '').split(/\s+/);
+ values = L.toArray(values);
if (values.indexOf(value) == -1) {
values.push(value);
rv = false;
if (isArray == false)
- values = String(values || '').split(/\s+/);
+ values = L.toArray(values);
for (var i = values.length - 1; i >= 0; i--) {
if (values[i] == value) {
return bits;
}
-function initNetworkState() {
- var flush = _flush;
-
- _flush = false;
-
- if (_state != null && !flush)
- return Promise.resolve(_state);
-
- if (_cache.pendingInit != null)
- return Promise.resolve(_cache.pendingInit);
-
- return (_cache.pendingInit = Promise.all([
- getInterfaceState(flush), getDeviceState(flush), getBoardState(flush),
- getWifiState(flush), getIfaddrState(flush), getNetdevState(flush), getProtocolHandlers(flush),
- uci.load('network'), uci.load('wireless'), uci.load('luci')
- ]).finally(function() {
- var ifaddrs = _cache.ifaddrs,
- devices = _cache.devices,
- board = _cache.board,
- s = { isTunnel: {}, isBridge: {}, isSwitch: {}, isWifi: {}, interfaces: {}, bridges: {}, switches: {} };
-
- for (var i = 0, a; (a = ifaddrs[i]) != null; i++) {
- var name = a.name.replace(/:.+$/, '');
-
- if (isVirtualIfname(name))
- s.isTunnel[name] = true;
-
- if (s.isTunnel[name] || !(isIgnoredIfname(name) || isVirtualIfname(name))) {
- s.interfaces[name] = s.interfaces[name] || {
- idx: a.ifindex || i,
- name: name,
- rawname: a.name,
- flags: [],
- ipaddrs: [],
- ip6addrs: []
- };
-
- if (a.family == 'packet') {
- s.interfaces[name].flags = a.flags;
- s.interfaces[name].stats = a.data;
- s.interfaces[name].macaddr = a.addr;
- }
- else if (a.family == 'inet') {
- s.interfaces[name].ipaddrs.push(a.addr + '/' + a.netmask);
- }
- else if (a.family == 'inet6') {
- s.interfaces[name].ip6addrs.push(a.addr + '/' + a.netmask);
+function initNetworkState(refresh) {
+ if (_state == null || refresh) {
+ _init = _init || Promise.all([
+ getInterfaceState(), getDeviceState(), getBoardState(),
+ getWifiState(), getIfaddrState(), getNetdevState(), getProtocolHandlers(),
+ uci.load('network'), uci.load('wireless'), uci.load('luci')
+ ]).then(function(data) {
+ var board = data[2], ifaddrs = data[4], devices = data[5];
+ var s = {
+ isTunnel: {}, isBridge: {}, isSwitch: {}, isWifi: {},
+ ifaces: data[0], devices: data[1], radios: data[3],
+ netdevs: {}, bridges: {}, switches: {}
+ };
+
+ for (var i = 0, a; (a = ifaddrs[i]) != null; i++) {
+ var name = a.name.replace(/:.+$/, '');
+
+ if (isVirtualIfname(name))
+ s.isTunnel[name] = true;
+
+ if (s.isTunnel[name] || !(isIgnoredIfname(name) || isVirtualIfname(name))) {
+ s.netdevs[name] = s.netdevs[name] || {
+ idx: a.ifindex || i,
+ name: name,
+ rawname: a.name,
+ flags: [],
+ ipaddrs: [],
+ ip6addrs: []
+ };
+
+ if (a.family == 'packet') {
+ s.netdevs[name].flags = a.flags;
+ s.netdevs[name].stats = a.data;
+ s.netdevs[name].macaddr = a.addr;
+ }
+ else if (a.family == 'inet') {
+ s.netdevs[name].ipaddrs.push(a.addr + '/' + a.netmask);
+ }
+ else if (a.family == 'inet6') {
+ s.netdevs[name].ip6addrs.push(a.addr + '/' + a.netmask);
+ }
}
}
- }
- for (var devname in devices) {
- var dev = devices[devname];
+ for (var devname in devices) {
+ var dev = devices[devname];
+
+ if (dev.bridge) {
+ var b = {
+ name: devname,
+ id: dev.id,
+ stp: dev.stp,
+ ifnames: []
+ };
- if (dev.bridge) {
- var b = {
- name: devname,
- id: dev.id,
- stp: dev.stp,
- ifnames: []
- };
+ for (var i = 0; dev.ports && i < dev.ports.length; i++) {
+ var subdev = s.netdevs[dev.ports[i]];
- for (var i = 0; dev.ports && i < dev.ports.length; i++) {
- var subdev = s.interfaces[dev.ports[i]];
+ if (subdev == null)
+ continue;
- if (subdev == null)
- continue;
+ b.ifnames.push(subdev);
+ subdev.bridge = b;
+ }
- b.ifnames.push(subdev);
- subdev.bridge = b;
+ s.bridges[devname] = b;
+ s.isBridge[devname] = true;
}
- s.bridges[devname] = b;
- }
-
- if (s.interfaces.hasOwnProperty(devname)) {
- Object.assign(s.interfaces[devname], {
- macaddr: dev.mac,
- type: dev.type,
- mtu: dev.mtu,
- qlen: dev.qlen
- });
+ if (s.netdevs.hasOwnProperty(devname)) {
+ Object.assign(s.netdevs[devname], {
+ macaddr: dev.mac,
+ type: dev.type,
+ mtu: dev.mtu,
+ qlen: dev.qlen
+ });
+ }
}
- }
- if (L.isObject(board.switch)) {
- for (var switchname in board.switch) {
- var layout = board.switch[switchname],
- netdevs = {},
- nports = {},
- ports = [],
- pnum = null,
- role = null;
-
- if (L.isObject(layout) && Array.isArray(layout.ports)) {
- for (var i = 0, port; (port = layout.ports[i]) != null; i++) {
- if (typeof(port) == 'object' && typeof(port.num) == 'number' &&
- (typeof(port.role) == 'string' || typeof(port.device) == 'string')) {
- var spec = {
- num: port.num,
- role: port.role || 'cpu',
- index: (port.index != null) ? port.index : port.num
- };
-
- if (port.device != null) {
- spec.device = port.device;
- spec.tagged = spec.need_tag;
- netdevs[port.num] = port.device;
+ if (L.isObject(board.switch)) {
+ for (var switchname in board.switch) {
+ var layout = board.switch[switchname],
+ netdevs = {},
+ nports = {},
+ ports = [],
+ pnum = null,
+ role = null;
+
+ if (L.isObject(layout) && Array.isArray(layout.ports)) {
+ for (var i = 0, port; (port = layout.ports[i]) != null; i++) {
+ if (typeof(port) == 'object' && typeof(port.num) == 'number' &&
+ (typeof(port.role) == 'string' || typeof(port.device) == 'string')) {
+ var spec = {
+ num: port.num,
+ role: port.role || 'cpu',
+ index: (port.index != null) ? port.index : port.num
+ };
+
+ if (port.device != null) {
+ spec.device = port.device;
+ spec.tagged = spec.need_tag;
+ netdevs[port.num] = port.device;
+ }
+
+ ports.push(spec);
+
+ if (port.role != null)
+ nports[port.role] = (nports[port.role] || 0) + 1;
}
+ }
- ports.push(spec);
+ ports.sort(function(a, b) {
+ if (a.role != b.role)
+ return (a.role < b.role) ? -1 : 1;
- if (port.role != null)
- nports[port.role] = (nports[port.role] || 0) + 1;
- }
- }
+ return (a.index - b.index);
+ });
- ports.sort(function(a, b) {
- if (a.role != b.role)
- return (a.role < b.role) ? -1 : 1;
+ for (var i = 0, port; (port = ports[i]) != null; i++) {
+ if (port.role != role) {
+ role = port.role;
+ pnum = 1;
+ }
- return (a.index - b.index);
- });
+ if (role == 'cpu')
+ port.label = 'CPU (%s)'.format(port.device);
+ else if (nports[role] > 1)
+ port.label = '%s %d'.format(role.toUpperCase(), pnum++);
+ else
+ port.label = role.toUpperCase();
- for (var i = 0, port; (port = ports[i]) != null; i++) {
- if (port.role != role) {
- role = port.role;
- pnum = 1;
+ delete port.role;
+ delete port.index;
}
- if (role == 'cpu')
- port.label = 'CPU (%s)'.format(port.device);
- else if (nports[role] > 1)
- port.label = '%s %d'.format(role.toUpperCase(), pnum++);
- else
- port.label = role.toUpperCase();
-
- delete port.role;
- delete port.index;
+ s.switches[switchname] = {
+ ports: ports,
+ netdevs: netdevs
+ };
}
-
- s.switches[switchname] = {
- ports: ports,
- netdevs: netdevs
- };
}
}
- }
- delete _cache.pendingInit;
+ if (L.isObject(board.dsl) && L.isObject(board.dsl.modem)) {
+ s.hasDSLModem = board.dsl.modem;
+ }
- return (_state = s);
- }));
+ _init = null;
+
+ return (_state = s);
+ });
+ }
+
+ return (_state != null ? Promise.resolve(_state) : _init);
}
function ifnameOf(obj) {
maskToPrefix: maskToPrefix,
flushCache: function() {
- return Promise.resolve(_state).then(function() {
- _flush = true;
- });
+ initNetworkState(true);
+ return _init;
},
getProtocol: function(protoname, netname) {
},
registerProtocol: function(protoname, methods) {
- var spec = L.isObject(_cache.protocols) ? _cache.protocols[protoname] : null;
+ var spec = L.isObject(_protospecs) ? _protospecs[protoname] : null;
var proto = Protocol.extend(Object.assign({
getI18n: function() {
return protoname;
return this.instantiateNetwork(name);
}
else if (name != null) {
- for (var i = 0; i < _cache.interfacedump.length; i++)
- if (_cache.interfacedump[i].interface == name)
- return this.instantiateNetwork(name, _cache.interfacedump[i].proto);
+ for (var i = 0; i < _state.ifaces.length; i++)
+ if (_state.ifaces[i].interface == name)
+ return this.instantiateNetwork(name, _state.ifaces[i].proto);
}
return null;
for (var i = 0; i < uciInterfaces.length; i++)
networks[uciInterfaces[i]['.name']] = this.instantiateNetwork(uciInterfaces[i]['.name']);
- for (var i = 0; i < _cache.interfacedump.length; i++)
- if (networks[_cache.interfacedump[i].interface] == null)
- networks[_cache.interfacedump[i].interface] =
- this.instantiateNetwork(_cache.interfacedump[i].interface, _cache.interfacedump[i].proto);
+ for (var i = 0; i < _state.ifaces.length; i++)
+ if (networks[_state.ifaces[i].interface] == null)
+ networks[_state.ifaces[i].interface] =
+ this.instantiateNetwork(_state.ifaces[i].interface, _state.ifaces[i].proto);
var rv = [];
if (name == null)
return null;
- if (_state.interfaces.hasOwnProperty(name) || isWifiIfname(name))
+ if (_state.netdevs.hasOwnProperty(name) || isWifiIfname(name))
return this.instantiateDevice(name);
var netid = getWifiNetidBySid(name);
}
}
- for (var ifname in _state.interfaces) {
+ for (var ifname in _state.netdevs) {
if (devices.hasOwnProperty(ifname))
continue;
var radioname = existingDevice['.name'],
netid = getWifiNetidBySid(sid) || [];
- return this.instantiateWifiNetwork(sid, radioname, _cache.wifi[radioname], netid[0], null, { ifname: netid });
+ return this.instantiateWifiNetwork(sid, radioname, _state.radios[radioname], netid[0], null, { ifname: netid });
}, this));
},
return initNetworkState().then(L.bind(function() {
var rv = [];
- for (var i = 0; i < _state.interfacedump.length; i++) {
- if (!Array.isArray(_state.interfacedump[i].route))
+ for (var i = 0; i < _state.ifaces.length; i++) {
+ if (!Array.isArray(_state.ifaces[i].route))
continue;
- for (var j = 0; j < _state.interfacedump[i].route.length; j++) {
- if (typeof(_state.interfacedump[i].route[j]) != 'object' ||
- typeof(_state.interfacedump[i].route[j].target) != 'string' ||
- typeof(_state.interfacedump[i].route[j].mask) != 'number')
+ for (var j = 0; j < _state.ifaces[i].route.length; j++) {
+ if (typeof(_state.ifaces[i].route[j]) != 'object' ||
+ typeof(_state.ifaces[i].route[j].target) != 'string' ||
+ typeof(_state.ifaces[i].route[j].mask) != 'number')
continue;
- if (_state.interfacedump[i].route[j].table)
+ if (_state.ifaces[i].route[j].table)
continue;
- rv.push(_state.interfacedump[i]);
+ if (_state.ifaces[i].route[j].target != addr ||
+ _state.ifaces[i].route[j].mask != mask)
+ continue;
+
+ rv.push(_state.ifaces[i]);
}
}
return initNetworkState().then(L.bind(function() {
var rv = [];
- for (var i = 0; i < _state.interfacedump.length; i++) {
- if (Array.isArray(_state.interfacedump[i]['ipv4-address']))
- for (var j = 0; j < _state.interfacedump[i]['ipv4-address'].length; j++)
- if (typeof(_state.interfacedump[i]['ipv4-address'][j]) == 'object' &&
- _state.interfacedump[i]['ipv4-address'][j].address == addr)
- return _state.interfacedump[i];
-
- if (Array.isArray(_state.interfacedump[i]['ipv6-address']))
- for (var j = 0; j < _state.interfacedump[i]['ipv6-address'].length; j++)
- if (typeof(_state.interfacedump[i]['ipv6-address'][j]) == 'object' &&
- _state.interfacedump[i]['ipv6-address'][j].address == addr)
- return _state.interfacedump[i];
-
- if (Array.isArray(_state.interfacedump[i]['ipv6-prefix-assignment']))
- for (var j = 0; j < _state.interfacedump[i]['ipv6-prefix-assignment'].length; j++)
- if (typeof(_state.interfacedump[i]['ipv6-prefix-assignment'][j]) == 'object' &&
- typeof(_state.interfacedump[i]['ipv6-prefix-assignment'][j]['local-address']) == 'object' &&
- _state.interfacedump[i]['ipv6-prefix-assignment'][j]['local-address'].address == addr)
- return _state.interfacedump[i];
+ for (var i = 0; i < _state.ifaces.length; i++) {
+ if (Array.isArray(_state.ifaces[i]['ipv4-address']))
+ for (var j = 0; j < _state.ifaces[i]['ipv4-address'].length; j++)
+ if (typeof(_state.ifaces[i]['ipv4-address'][j]) == 'object' &&
+ _state.ifaces[i]['ipv4-address'][j].address == addr)
+ return _state.ifaces[i];
+
+ if (Array.isArray(_state.ifaces[i]['ipv6-address']))
+ for (var j = 0; j < _state.ifaces[i]['ipv6-address'].length; j++)
+ if (typeof(_state.ifaces[i]['ipv6-address'][j]) == 'object' &&
+ _state.ifaces[i]['ipv6-address'][j].address == addr)
+ return _state.ifaces[i];
+
+ if (Array.isArray(_state.ifaces[i]['ipv6-prefix-assignment']))
+ for (var j = 0; j < _state.ifaces[i]['ipv6-prefix-assignment'].length; j++)
+ if (typeof(_state.ifaces[i]['ipv6-prefix-assignment'][j]) == 'object' &&
+ typeof(_state.ifaces[i]['ipv6-prefix-assignment'][j]['local-address']) == 'object' &&
+ _state.ifaces[i]['ipv6-prefix-assignment'][j]['local-address'].address == addr)
+ return _state.ifaces[i];
}
return null;
getIfnameOf: function(obj) {
return ifnameOf(obj);
+ },
+
+ getDSLModemType: function() {
+ return initNetworkState().then(function() {
+ return _state.hasDSLModem ? _state.hasDSLModem.type : null;
+ });
}
});
},
_ubus: function(field) {
- for (var i = 0; i < _cache.interfacedump.length; i++) {
- if (_cache.interfacedump[i].interface != this.sid)
+ for (var i = 0; i < _state.ifaces.length; i++) {
+ if (_state.ifaces[i].interface != this.sid)
continue;
- return (field != null ? _cache.interfacedump[i][field] : _cache.interfacedump[i]);
+ return (field != null ? _state.ifaces[i][field] : _state.ifaces[i]);
}
},
return new Device(ifname, this);
}
else {
- var ifname = this._ubus('l3_device') || this._ubus('device');
-
- if (ifname != null)
- return L.network.instantiateDevice(ifname, this);
-
var ifnames = L.toArray(uci.get('network', this.sid, 'ifname'));
for (var i = 0; i < ifnames.length; i++) {
return (ifname != null ? L.network.instantiateDevice(ifname, this) : null);
},
+ getL3Device: function() {
+ var ifname = this._ubus('l3_device');
+ return (ifname != null ? L.network.instantiateDevice(ifname, this) : null);
+ },
+
getDevices: function() {
var rv = [];
}
this.ifname = this.ifname || ifname;
- this.dev = _state.interfaces[this.ifname];
+ this.dev = _state.netdevs[this.ifname];
this.network = network;
},
_ubus: function(field) {
- var dump = _cache.devicedump[this.ifname] || {};
+ var dump = _state.devices[this.ifname] || {};
return (field != null ? dump[field] : dump);
},
return null;
for (var i = 0; i < br.ifnames.length; i++)
- rv.push(L.network.instantiateDevice(br.ifnames[i]));
+ rv.push(L.network.instantiateDevice(br.ifnames[i].name));
+
+ rv.sort(deviceSort);
return rv;
},
},
isUp: function() {
- if (L.isObject(_cache.wifi[this.sid]))
- return (_cache.wifi[this.sid].up == true);
+ if (L.isObject(_state.radios[this.sid]))
+ return (_state.radios[this.sid].up == true);
return false;
},