4 Copyright 2009-2010 Jo-Philipp Wich <xm@subsignal.org>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
20 local type, next, pairs, ipairs, loadfile, table, tonumber, math, i18n
21 = type, next, pairs, ipairs, loadfile, table, tonumber, math, luci.i18n
23 local nxo = require "nixio"
24 local ipc = require "luci.ip"
25 local sys = require "luci.sys"
26 local utl = require "luci.util"
27 local dsp = require "luci.dispatcher"
28 local uci = require "luci.model.uci"
30 module "luci.model.network"
33 local ifs, brs, sws, uci_r, uci_s
35 function _list_del(c, s, o, r)
36 local val = uci_r:get(c, s, o)
39 if type(val) == "string" then
40 for val in val:gmatch("%S+") do
46 uci_r:set(c, s, o, table.concat(l, " "))
50 elseif type(val) == "table" then
51 for _, val in ipairs(val) do
65 function _list_add(c, s, o, a)
66 local val = uci_r:get(c, s, o) or ""
67 if type(val) == "string" then
69 for val in val:gmatch("%S+") do
75 uci_r:set(c, s, o, table.concat(l, " "))
76 elseif type(val) == "table" then
78 for _, val in ipairs(val) do
88 function _stror(s1, s2)
89 if not s1 or #s1 == 0 then
90 return s2 and #s2 > 0 and s2
96 function _get(c, s, o)
97 return uci_r:get(c, s, o)
100 function _set(c, s, o, v)
102 if type(v) == "boolean" then v = v and "1" or "0" end
103 return uci_r:set(c, s, o, v)
105 return uci_r:delete(c, s, o)
109 function _wifi_iface(x)
111 x:match("^wlan%d") or x:match("^wl%d") or x:match("^ath%d") or
112 x:match("^%w+%.network%d")
116 function _wifi_lookup(ifn)
117 -- got a radio#.network# pseudo iface, locate the corresponding section
118 local radio, ifnidx = ifn:match("^(%w+)%.network(%d+)$")
119 if radio and ifnidx then
123 ifnidx = tonumber(ifnidx)
124 uci_r:foreach("wireless", "wifi-iface",
126 if s.device == radio then
128 if num == ifnidx then
137 -- looks like wifi, try to locate the section via state vars
138 elseif _wifi_iface(ifn) then
141 uci_s:foreach("wireless", "wifi-iface",
143 if s.ifname == ifn then
153 function _iface_virtual(x)
155 x:match("^6in4-%w") or x:match("^6to4-%w") or x:match("^3g-%w") or
156 x:match("^ppp-%w") or x:match("^pppoe-%w") or x:match("^pppoa-%w") or
161 function _iface_ignore(x)
163 x:match("^wmaster%d") or x:match("^wifi%d") or x:match("^hwsim%d") or
164 x:match("^imq%d") or x:match("^mon.wlan%d") or
165 x == "sit0" or x == "lo" or _iface_virtual(x)
170 function init(cursor)
171 uci_r = cursor or uci_r or uci.cursor()
172 uci_s = uci_r:substate()
178 -- read interface information
180 for n, i in ipairs(nxo.getifaddrs()) do
181 local name = i.name:match("[^:]+")
182 local prnt = name:match("^([^%.]+)%.")
184 if _iface_virtual(name) or not _iface_ignore(name) then
185 ifs[name] = ifs[name] or {
186 idx = i.ifindex or n,
199 if i.family == "packet" then
200 ifs[name].flags = i.flags
201 ifs[name].stats = i.data
202 ifs[name].macaddr = i.addr
203 elseif i.family == "inet" then
204 ifs[name].ipaddrs[#ifs[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask)
205 elseif i.family == "inet6" then
206 ifs[name].ip6addrs[#ifs[name].ip6addrs+1] = ipc.IPv6(i.addr, i.netmask)
211 -- read bridge informaton
213 for l in utl.execi("brctl show") do
214 if not l:match("STP") then
215 local r = utl.split(l, "%s+", nil, true)
221 ifnames = { ifs[r[4]] }
224 b.ifnames[1].bridge = b
228 b.ifnames[#b.ifnames+1] = ifs[r[2]]
229 b.ifnames[#b.ifnames].bridge = b
237 function save(self, ...)
242 function commit(self, ...)
247 function has_ipv6(self)
248 return nfs.access("/proc/net/ipv6_route")
251 function add_network(self, n, options)
252 local oldnet = self:get_network(n)
253 if n and #n > 0 and n:match("^[a-zA-Z0-9_]+$") and not oldnet then
254 if uci_r:section("network", "interface", n, options) then
257 elseif oldnet and oldnet:is_empty() then
260 for k, v in pairs(options) do
268 function get_network(self, n)
269 if n and uci_r:get("network", n) == "interface" then
274 function get_networks(self)
278 uci_r:foreach("network", "interface",
280 nls[s['.name']] = network(s['.name'])
284 for n in utl.kspairs(nls) do
285 nets[#nets+1] = nls[n]
291 function del_network(self, n)
292 local r = uci_r:delete("network", n)
294 uci_r:delete_all("network", "alias",
295 function(s) return (s.interface == n) end)
297 uci_r:delete_all("network", "route",
298 function(s) return (s.interface == n) end)
300 uci_r:delete_all("network", "route6",
301 function(s) return (s.interface == n) end)
303 uci_r:foreach("wireless", "wifi-iface",
305 if s.network == n then
306 uci_r:delete("wireless", s['.name'], "network")
313 function rename_network(self, old, new)
315 if new and #new > 0 and new:match("^[a-zA-Z0-9_]+$") and not self:get_network(new) then
316 r = uci_r:section("network", "interface", new, uci_r:get_all("network", old))
319 uci_r:foreach("network", "alias",
321 if s.interface == old then
322 uci_r:set("network", s['.name'], "interface", new)
326 uci_r:foreach("network", "route",
328 if s.interface == old then
329 uci_r:set("network", s['.name'], "interface", new)
333 uci_r:foreach("network", "route6",
335 if s.interface == old then
336 uci_r:set("network", s['.name'], "interface", new)
340 uci_r:foreach("wireless", "wifi-iface",
342 if s.network == old then
343 uci_r:set("wireless", s['.name'], "network", new)
347 uci_r:delete("network", old)
353 function get_interface(self, i)
354 if ifs[i] or _wifi_iface(i) then
359 uci_r:foreach("wireless", "wifi-iface",
362 num[s.device] = num[s.device] and num[s.device] + 1 or 1
363 if s['.name'] == i then
365 "%s.network%d" %{s.device, num[s.device] })
374 function get_interfaces(self)
380 -- find normal interfaces
381 uci_r:foreach("network", "interface",
383 for iface in utl.imatch(s.ifname) do
384 if not _iface_ignore(iface) and not _wifi_iface(iface) then
386 nfs[iface] = interface(iface)
391 for iface in utl.kspairs(ifs) do
392 if not (seen[iface] or _iface_ignore(iface) or _wifi_iface(iface)) then
393 nfs[iface] = interface(iface)
397 -- find vlan interfaces
398 uci_r:foreach("network", "switch_vlan",
400 local base = s.device or "-"
401 if not base:match("^eth%d") then
405 local vid = tonumber(s.vid or s.vlan)
406 if vid ~= nil and vid >= 0 and vid <= 4095 then
407 local iface = "%s.%d" %{ base, vid }
408 if not seen[iface] then
410 nfs[iface] = interface(iface)
415 for iface in utl.kspairs(nfs) do
416 ifaces[#ifaces+1] = nfs[iface]
419 -- find wifi interfaces
422 uci_r:foreach("wireless", "wifi-iface",
425 num[s.device] = num[s.device] and num[s.device] + 1 or 1
426 local i = "%s.network%d" %{ s.device, num[s.device] }
427 wfs[i] = interface(i)
431 for iface in utl.kspairs(wfs) do
432 ifaces[#ifaces+1] = wfs[iface]
438 function ignore_interface(self, x)
439 return _iface_ignore(x)
442 function get_wifidev(self, dev)
443 if uci_r:get("wireless", dev) == "wifi-device" then
448 function get_wifidevs(self)
452 uci_r:foreach("wireless", "wifi-device",
453 function(s) wfd[#wfd+1] = s['.name'] end)
456 for _, dev in utl.vspairs(wfd) do
457 devs[#devs+1] = wifidev(dev)
463 function get_wifinet(self, net)
464 local wnet = _wifi_lookup(net)
470 function add_wifinet(self, net, options)
471 if type(options) == "table" and options.device and
472 uci_r:get("wireless", options.device) == "wifi-device"
474 local wnet = uci_r:section("wireless", "wifi-iface", nil, options)
479 function del_wifinet(self, net)
480 local wnet = _wifi_lookup(net)
482 uci_r:delete("wireless", wnet)
489 network = utl.class()
491 function network.__init__(self, name)
495 function network._get(self, opt)
496 local v = uci_r:get("network", self.sid, opt)
497 if type(v) == "table" then
498 return table.concat(v, " ")
503 function network._ip(self, opt, family, list)
504 local ip = uci_s:get("network", self.sid, opt)
505 local fc = (family == 6) and ipc.IPv6 or ipc.IPv4
509 for ip in utl.imatch(ip) do
511 if ip then l[#l+1] = ip:string() end
516 return ip and ip:string()
521 function network.get(self, opt)
522 return _get("network", self.sid, opt)
525 function network.set(self, opt, val)
526 return _set("network", self.sid, opt, val)
529 function network.ifname(self)
530 local p = self:proto()
531 if self:is_bridge() then
532 return "br-" .. self.sid
533 elseif self:proto() == "relay" then
534 return uci_s:get("network", self.sid, "up") == "1" and "lo" or nil
535 elseif self:is_virtual() then
536 return p .. "-" .. self.sid
539 local dev = uci_r:get("network", self.sid, "ifname") or
540 uci_s:get("network", self.sid, "ifname")
542 dev = (type(dev) == "table") and dev[1] or dev
543 dev = (dev ~= nil) and dev:match("%S+")
546 uci_r:foreach("wireless", "wifi-iface",
549 num[s.device] = num[s.device]
550 and num[s.device] + 1 or 1
552 if s.network == self.sid then
553 dev = "%s.network%d" %{ s.device, num[s.device] }
564 function network.device(self)
565 local dev = uci_r:get("network", self.sid, "device") or
566 uci_s:get("network", self.sid, "device")
568 dev = (type(dev) == "table") and dev[1] or dev
570 if not dev or dev:match("[^%w%-%.%s]") then
571 dev = uci_r:get("network", self.sid, "ifname") or
572 uci_s:get("network", self.sid, "ifname")
574 dev = (type(dev) == "table") and dev[1] or dev
577 for dev in utl.imatch(dev) do
582 function network.proto(self)
583 return self:_get("proto") or "none"
586 function network.type(self)
587 return self:_get("type")
590 function network.name(self)
594 function network.uptime(self)
595 local cnt = tonumber(uci_s:get("network", self.sid, "connect_time"))
597 return nxo.sysinfo().uptime - cnt
603 function network.expires(self)
604 local a = tonumber(uci_s:get("network", self.sid, "lease_acquired"))
605 local l = tonumber(uci_s:get("network", self.sid, "lease_lifetime"))
607 l = l - (nxo.sysinfo().uptime - a)
608 return l > 0 and l or 0
613 function network.metric(self)
614 return tonumber(uci_s:get("network", self.sid, "metric")) or 0
617 function network.ipaddr(self)
618 return self:_ip("ipaddr", 4)
621 function network.netmask(self)
622 return self:_ip("netmask", 4)
625 function network.gwaddr(self)
626 return self:_ip("gateway", 4)
629 function network.dnsaddrs(self)
630 return self:_ip("dns", 4, true)
633 function network.ip6addr(self)
634 local ip6 = self:_ip("ip6addr", 6)
636 local ifc = ifs[self:ifname()]
637 if ifc and ifc.ip6addrs then
639 for _, a in ipairs(ifc.ip6addrs) do
640 if not a:is6linklocal() then
650 function network.gw6addr(self)
651 local ip6 = self:_ip("ip6gw", 6)
653 local dr6 = sys.net.defaultroute6()
654 if dr6 and dr6.device == self:ifname() then
655 return dr6.nexthop:string()
661 function network.dns6addrs(self)
662 return self:_ip("dns", 6, true)
665 function network.is_bridge(self)
666 return (self:type() == "bridge")
669 function network.is_virtual(self)
670 local p = self:proto()
672 p == "3g" or p == "6in4" or p == "6to4" or p == "ppp" or
673 p == "pppoe" or p == "pppoa" or p == "relay"
677 function network.is_floating(self)
678 return (self:is_virtual() and self:proto() ~= "pppoe")
681 function network.is_empty(self)
682 if self:is_virtual() then
687 if (self:_get("ifname") or ""):match("%S+") then
691 uci_r:foreach("wireless", "wifi-iface",
693 if s.network == self.sid then
703 function network.add_interface(self, ifname)
704 if not self:is_floating() then
705 if type(ifname) ~= "string" then
706 ifname = ifname:name()
708 ifname = ifname:match("[^%s:]+")
711 -- remove the interface from all ifaces
712 uci_r:foreach("network", "interface",
714 _list_del("network", s['.name'], "ifname", ifname)
717 -- if its a wifi interface, change its network option
718 local wif = _wifi_lookup(ifname)
720 uci_r:set("wireless", wif, "network", self.sid)
722 -- add iface to our iface list
724 _list_add("network", self.sid, "ifname", ifname)
729 function network.del_interface(self, ifname)
730 if not self:is_floating() then
731 if utl.instanceof(ifname, interface) then
732 ifname = ifname:name()
734 ifname = ifname:match("[^%s:]+")
737 -- if its a wireless interface, clear its network option
738 local wif = _wifi_lookup(ifname)
739 if wif then uci_r:delete("wireless", wif, "network") end
741 -- remove the interface
742 _list_del("network", self.sid, "ifname", ifname)
746 function network.get_interface(self)
747 if self:is_virtual() then
748 return interface(self:proto() .. "-" .. self.sid)
749 elseif self:is_bridge() then
750 return interface("br-" .. self.sid)
754 for ifn in utl.imatch(uci_s:get("network", self.sid, "ifname")) do
755 ifn = ifn:match("^[^:/]+")
756 return ifn and interface(ifn)
759 uci_s:foreach("wireless", "wifi-iface",
762 num[s.device] = num[s.device] and num[s.device] + 1 or 1
763 if s.network == self.sid then
764 ifn = s.ifname or "%s.network%d" %{ s.device, num[s.device] }
769 return ifn and interface(ifn)
773 function network.get_interfaces(self)
778 for ifn in utl.imatch(self:get("ifname")) do
779 ifn = ifn:match("^[^:/]+")
780 nfs[ifn] = interface(ifn)
783 for ifn in utl.kspairs(nfs) do
784 ifaces[#ifaces+1] = nfs[ifn]
789 uci_r:foreach("wireless", "wifi-iface",
792 num[s.device] = num[s.device] and num[s.device] + 1 or 1
793 if s.network == self.sid then
794 ifn = "%s.network%d" %{ s.device, num[s.device] }
795 wfs[ifn] = interface(ifn)
800 for ifn in utl.kspairs(wfs) do
801 ifaces[#ifaces+1] = wfs[ifn]
803 -- only bridges may cover more than one interface
804 --if not self:is_bridge() then
812 function network.contains_interface(self, ifname)
813 if type(ifname) ~= "string" then
814 ifname = ifname:name()
816 ifname = ifname:match("[^%s:]+")
819 if self:is_virtual() and self:proto() .. "-" .. self.sid == ifname then
821 elseif self:is_bridge() and "br-" .. self.sid == ifname then
825 for ifn in utl.imatch(self:get("ifname")) do
826 ifn = ifn:match("[^:]+")
827 if ifn == ifname then
832 local wif = _wifi_lookup(ifname)
834 return (uci_r:get("wireless", wif, "network") == self.sid)
841 function network.adminlink(self)
842 return dsp.build_url("admin", "network", "network", self.sid)
846 interface = utl.class()
847 function interface.__init__(self, ifname)
848 local wif = _wifi_lookup(ifname)
849 if wif then self.wif = wifinet(wif) end
851 self.ifname = self.ifname or ifname
852 self.dev = ifs[self.ifname]
855 function interface.name(self)
856 return self.wif and self.wif:ifname() or self.ifname
859 function interface.mac(self)
860 return self.dev and self.dev.macaddr or "00:00:00:00:00:00"
863 function interface.ipaddrs(self)
864 return self.dev and self.dev.ipaddrs or { }
867 function interface.ip6addrs(self)
868 return self.dev and self.dev.ip6addrs or { }
871 function interface.type(self)
872 if self.wif or _wifi_iface(self.ifname) then
874 elseif brs[self.ifname] then
876 elseif self.ifname:match("%.") then
878 elseif sws[self.ifname] then
885 function interface.shortname(self)
888 self.wif:active_mode(),
889 self.wif:active_ssid() or self.wif:active_bssid()
896 function interface.get_i18n(self)
898 return "%s: %s %q" %{
899 i18n.translate("Wireless Network"),
900 self.wif:active_mode(),
901 self.wif:active_ssid() or self.wif:active_bssid()
904 return "%s: %q" %{ self:get_type_i18n(), self:name() }
908 function interface.get_type_i18n(self)
909 local x = self:type()
911 return i18n.translate("Wireless Adapter")
912 elseif x == "bridge" then
913 return i18n.translate("Bridge")
914 elseif x == "switch" then
915 return i18n.translate("Ethernet Switch")
916 elseif x == "vlan" then
917 return i18n.translate("VLAN Interface")
919 return i18n.translate("Ethernet Adapter")
923 function interface.adminlink(self)
925 return self.wif:adminlink()
929 function interface.ports(self)
933 for _, iface in ipairs(self.br.ifnames) do
934 ifaces[#ifaces+1] = interface(iface.name)
940 function interface.bridge_id(self)
948 function interface.bridge_stp(self)
956 function interface.is_up(self)
958 return self.wif:is_up()
960 return self.dev and self.dev.flags and self.dev.flags.up or false
964 function interface.is_bridge(self)
965 return (self:type() == "bridge")
968 function interface.is_bridgeport(self)
969 return self.dev and self.dev.bridge and true or false
972 function interface.tx_bytes(self)
973 return self.dev and self.dev.stats
974 and self.dev.stats.tx_bytes or 0
977 function interface.rx_bytes(self)
978 return self.dev and self.dev.stats
979 and self.dev.stats.rx_bytes or 0
982 function interface.tx_packets(self)
983 return self.dev and self.dev.stats
984 and self.dev.stats.tx_packets or 0
987 function interface.rx_packets(self)
988 return self.dev and self.dev.stats
989 and self.dev.stats.rx_packets or 0
992 function interface.get_network(self)
993 if self.dev and self.dev.network then
994 self.network = _M:get_network(self.dev.network)
997 if not self.network then
999 for _, net in ipairs(_M:get_networks()) do
1000 if net:contains_interface(self.ifname) or
1001 net:ifname() == self.ifname
1012 function interface.get_wifinet(self)
1017 wifidev = utl.class()
1018 function wifidev.__init__(self, dev)
1020 self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
1023 function wifidev.get(self, opt)
1024 return _get("wireless", self.sid, opt)
1027 function wifidev.set(self, opt, val)
1028 return _set("wireless", self.sid, opt, val)
1031 function wifidev.name(self)
1035 function wifidev.hwmodes(self)
1036 local l = self.iwinfo.hwmodelist
1037 if l and next(l) then
1040 return { b = true, g = true }
1044 function wifidev.get_i18n(self)
1046 if self.iwinfo.type == "wl" then
1048 elseif self.iwinfo.type == "madwifi" then
1053 local l = self:hwmodes()
1054 if l.a then m = m .. "a" end
1055 if l.b then m = m .. "b" end
1056 if l.g then m = m .. "g" end
1057 if l.n then m = m .. "n" end
1059 return "%s 802.11%s Wireless Controller (%s)" %{ t, m, self:name() }
1062 function wifidev.is_up(self)
1065 uci_s:foreach("wireless", "wifi-iface",
1067 if s.device == self.sid then
1078 function wifidev.get_wifinet(self, net)
1079 if uci_r:get("wireless", net) == "wifi-iface" then
1082 local wnet = _wifi_lookup(net)
1084 return wifinet(wnet)
1089 function wifidev.get_wifinets(self)
1092 uci_r:foreach("wireless", "wifi-iface",
1094 if s.device == self.sid then
1095 nets[#nets+1] = wifinet(s['.name'])
1102 function wifidev.add_wifinet(self, options)
1103 options = options or { }
1104 options.device = self.sid
1106 local wnet = uci_r:section("wireless", "wifi-iface", nil, options)
1108 return wifinet(wnet, options)
1112 function wifidev.del_wifinet(self, net)
1113 if utl.instanceof(net, wifinet) then
1115 elseif uci_r:get("wireless", net) ~= "wifi-iface" then
1116 net = _wifi_lookup(net)
1119 if net and uci_r:get("wireless", net, "device") == self.sid then
1120 uci_r:delete("wireless", net)
1128 wifinet = utl.class()
1129 function wifinet.__init__(self, net, data)
1134 uci_r:foreach("wireless", "wifi-iface",
1137 num[s.device] = num[s.device] and num[s.device] + 1 or 1
1138 if s['.name'] == self.sid then
1139 netid = "%s.network%d" %{ s.device, num[s.device] }
1145 local dev = uci_s:get("wireless", self.sid, "ifname") or netid
1149 self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
1150 self.iwdata = data or uci_s:get_all("wireless", self.sid) or
1151 uci_r:get_all("wireless", self.sid) or { }
1154 function wifinet.get(self, opt)
1155 return _get("wireless", self.sid, opt)
1158 function wifinet.set(self, opt, val)
1159 return _set("wireless", self.sid, opt, val)
1162 function wifinet.mode(self)
1163 return uci_s:get("wireless", self.sid, "mode") or "ap"
1166 function wifinet.ssid(self)
1167 return uci_s:get("wireless", self.sid, "ssid")
1170 function wifinet.bssid(self)
1171 return uci_s:get("wireless", self.sid, "bssid")
1174 function wifinet.network(self)
1175 return uci_s:get("wifinet", self.sid, "network")
1178 function wifinet.id(self)
1182 function wifinet.name(self)
1186 function wifinet.ifname(self)
1187 local ifname = self.iwinfo.ifname
1188 if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
1194 function wifinet.get_device(self)
1195 if self.iwdata.device then
1196 return wifidev(self.iwdata.device)
1200 function wifinet.is_up(self)
1201 return (self.iwdata.up == "1")
1204 function wifinet.active_mode(self)
1205 local m = _stror(self.iwinfo.mode, self.iwdata.mode) or "ap"
1207 if m == "ap" then m = "Master"
1208 elseif m == "sta" then m = "Client"
1209 elseif m == "adhoc" then m = "Ad-Hoc"
1210 elseif m == "mesh" then m = "Mesh"
1211 elseif m == "monitor" then m = "Monitor"
1217 function wifinet.active_mode_i18n(self)
1218 return i18n.translate(self:active_mode())
1221 function wifinet.active_ssid(self)
1222 return _stror(self.iwinfo.ssid, self.iwdata.ssid)
1225 function wifinet.active_bssid(self)
1226 return _stror(self.iwinfo.bssid, self.iwdata.bssid) or "00:00:00:00:00:00"
1229 function wifinet.active_encryption(self)
1230 local enc = self.iwinfo and self.iwinfo.encryption
1231 return enc and enc.description or "-"
1234 function wifinet.assoclist(self)
1235 return self.iwinfo.assoclist or { }
1238 function wifinet.frequency(self)
1239 local freq = self.iwinfo.frequency
1240 if freq and freq > 0 then
1241 return "%.03f" % (freq / 1000)
1245 function wifinet.bitrate(self)
1246 local rate = self.iwinfo.bitrate
1247 if rate and rate > 0 then
1248 return (rate / 1000)
1252 function wifinet.channel(self)
1253 return self.iwinfo.channel or
1254 tonumber(uci_s:get("wireless", self.iwdata.device, "channel"))
1257 function wifinet.signal(self)
1258 return self.iwinfo.signal or 0
1261 function wifinet.noise(self)
1262 return self.iwinfo.noise or 0
1265 function wifinet.country(self)
1266 return self.iwinfo.country or "00"
1269 function wifinet.txpower(self)
1270 return self.iwinfo.txpower or 0
1273 function wifinet.signal_level(self, s, n)
1274 if self:active_bssid() ~= "00:00:00:00:00:00" then
1275 local signal = s or self:signal()
1276 local noise = n or self:noise()
1278 if signal < 0 and noise < 0 then
1279 local snr = -1 * (noise - signal)
1280 return math.floor(snr / 5)
1289 function wifinet.signal_percent(self)
1290 local qc = self.iwinfo.quality or 0
1291 local qm = self.iwinfo.quality_max or 0
1293 if qc > 0 and qm > 0 then
1294 return math.floor((100 / qm) * qc)
1300 function wifinet.shortname(self)
1302 i18n.translate(self:active_mode()),
1303 self:active_ssid() or self:active_bssid()
1307 function wifinet.get_i18n(self)
1308 return "%s: %s %q (%s)" %{
1309 i18n.translate("Wireless Network"),
1310 i18n.translate(self:active_mode()),
1311 self:active_ssid() or self:active_bssid(),
1316 function wifinet.adminlink(self)
1317 return dsp.build_url("admin", "network", "wireless", self.netid)
1320 function wifinet.get_network(self)
1321 if uci_r:get("network", self.iwdata.network) == "interface" then
1322 return network(self.iwdata.network)
1326 function wifinet.get_interface(self)
1327 return interface(self:ifname())