+
+function interface.get_wifinet(self)
+ return self.wif
+end
+
+
+wifidev = utl.class()
+function wifidev.__init__(self, dev)
+ self.sid = dev
+ self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
+end
+
+function wifidev.get(self, opt)
+ return _get("wireless", self.sid, opt)
+end
+
+function wifidev.set(self, opt, val)
+ return _set("wireless", self.sid, opt, val)
+end
+
+function wifidev.name(self)
+ return self.sid
+end
+
+function wifidev.hwmodes(self)
+ local l = self.iwinfo.hwmodelist
+ if l and next(l) then
+ return l
+ else
+ return { b = true, g = true }
+ end
+end
+
+function wifidev.get_i18n(self)
+ local t = "Generic"
+ if self.iwinfo.type == "wl" then
+ t = "Broadcom"
+ elseif self.iwinfo.type == "madwifi" then
+ t = "Atheros"
+ end
+
+ local m = ""
+ local l = self:hwmodes()
+ if l.a then m = m .. "a" end
+ if l.b then m = m .. "b" end
+ if l.g then m = m .. "g" end
+ if l.n then m = m .. "n" end
+
+ return "%s 802.11%s Wireless Controller (%s)" %{ t, m, self:name() }
+end
+
+function wifidev.is_up(self)
+ local up = false
+
+ uci_s:foreach("wireless", "wifi-iface",
+ function(s)
+ if s.device == self.sid then
+ if s.up == "1" then
+ up = true
+ return false
+ end
+ end
+ end)
+
+ return up
+end
+
+function wifidev.get_wifinet(self, net)
+ if uci_r:get("wireless", net) == "wifi-iface" then
+ return wifinet(net)
+ else
+ local wnet = _wifi_lookup(net)
+ if wnet then
+ return wifinet(wnet)
+ end
+ end
+end
+
+function wifidev.get_wifinets(self)
+ local nets = { }
+
+ uci_r:foreach("wireless", "wifi-iface",
+ function(s)
+ if s.device == self.sid then
+ nets[#nets+1] = wifinet(s['.name'])
+ end
+ end)
+
+ return nets
+end
+
+function wifidev.add_wifinet(self, options)
+ options = options or { }
+ options.device = self.sid
+
+ local wnet = uci_r:section("wireless", "wifi-iface", nil, options)
+ if wnet then
+ return wifinet(wnet, options)
+ end
+end
+
+function wifidev.del_wifinet(self, net)
+ if utl.instanceof(net, wifinet) then
+ net = net.sid
+ elseif uci_r:get("wireless", net) ~= "wifi-iface" then
+ net = _wifi_lookup(net)
+ end
+
+ if net and uci_r:get("wireless", net, "device") == self.sid then
+ uci_r:delete("wireless", net)
+ return true
+ end
+
+ return false
+end
+
+
+wifinet = utl.class()
+function wifinet.__init__(self, net, data)
+ self.sid = net
+
+ local num = { }
+ local netid
+ uci_r:foreach("wireless", "wifi-iface",
+ function(s)
+ if s.device then
+ num[s.device] = num[s.device] and num[s.device] + 1 or 1
+ if s['.name'] == self.sid then
+ netid = "%s.network%d" %{ s.device, num[s.device] }
+ return false
+ end
+ end
+ end)
+
+ local dev = uci_s:get("wireless", self.sid, "ifname") or netid
+
+ self.netid = netid
+ self.wdev = dev
+ self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
+ self.iwdata = data or uci_s:get_all("wireless", self.sid) or
+ uci_r:get_all("wireless", self.sid) or { }
+end
+
+function wifinet.get(self, opt)
+ return _get("wireless", self.sid, opt)
+end
+
+function wifinet.set(self, opt, val)
+ return _set("wireless", self.sid, opt, val)
+end
+
+function wifinet.mode(self)
+ return uci_s:get("wireless", self.sid, "mode") or "ap"
+end
+
+function wifinet.ssid(self)
+ return uci_s:get("wireless", self.sid, "ssid")
+end
+
+function wifinet.bssid(self)
+ return uci_s:get("wireless", self.sid, "bssid")
+end
+
+function wifinet.network(self)
+ return uci_s:get("wifinet", self.sid, "network")
+end
+
+function wifinet.name(self)
+ return self.sid
+end
+
+function wifinet.ifname(self)
+ local ifname = self.iwinfo.ifname
+ if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
+ ifname = self.wdev
+ end
+ return ifname
+end
+
+function wifinet.get_device(self)
+ if self.iwdata.device then
+ return wifidev(self.iwdata.device)
+ end
+end
+
+function wifinet.is_up(self)
+ return (self.iwdata.up == "1")
+end
+
+function wifinet.active_mode(self)
+ local m = _stror(self.iwinfo.mode, self.iwdata.mode) or "ap"
+
+ if m == "ap" then m = "Master"
+ elseif m == "sta" then m = "Client"
+ elseif m == "adhoc" then m = "Ad-Hoc"
+ elseif m == "mesh" then m = "Mesh"
+ elseif m == "monitor" then m = "Monitor"
+ end
+
+ return m
+end
+
+function wifinet.active_mode_i18n(self)
+ return i18n.translate(self:active_mode())
+end
+
+function wifinet.active_ssid(self)
+ return _stror(self.iwinfo.ssid, self.iwdata.ssid)
+end
+
+function wifinet.active_bssid(self)
+ return _stror(self.iwinfo.bssid, self.iwdata.bssid) or "00:00:00:00:00:00"
+end
+
+function wifinet.active_encryption(self)
+ local enc = self.iwinfo and self.iwinfo.encryption
+ return enc and enc.description or "-"
+end
+
+function wifinet.assoclist(self)
+ return self.iwinfo.assoclist or { }
+end
+
+function wifinet.frequency(self)
+ local freq = self.iwinfo.frequency
+ if freq and freq > 0 then
+ return "%.03f" % (freq / 1000)
+ end
+end
+
+function wifinet.bitrate(self)
+ local rate = self.iwinfo.bitrate
+ if rate and rate > 0 then
+ return (rate / 1000)
+ end
+end
+
+function wifinet.channel(self)
+ return self.iwinfo.channel or
+ tonumber(uci_s:get("wireless", self.iwdata.device, "channel"))
+end
+
+function wifinet.signal(self)
+ return self.iwinfo.signal or 0
+end
+
+function wifinet.noise(self)
+ return self.iwinfo.noise or 0
+end
+
+function wifinet.country(self)
+ return self.iwinfo.country or "00"
+end
+
+function wifinet.txpower(self)
+ return self.iwinfo.txpower or 0
+end
+
+function wifinet.signal_level(self, s, n)
+ if self:active_bssid() ~= "00:00:00:00:00:00" then
+ local signal = s or self:signal()
+ local noise = n or self:noise()
+
+ if signal < 0 and noise < 0 then
+ local snr = -1 * (noise - signal)
+ return math.floor(snr / 5)
+ else
+ return 0
+ end
+ else
+ return -1
+ end
+end
+
+function wifinet.signal_percent(self)
+ local qc = self.iwinfo.quality or 0
+ local qm = self.iwinfo.quality_max or 0
+
+ if qc > 0 and qm > 0 then
+ return math.floor((100 / qm) * qc)
+ else
+ return 0
+ end
+end
+
+function wifinet.shortname(self)
+ return "%s %q" %{
+ i18n.translate(self:active_mode()),
+ self:active_ssid() or self:active_bssid()
+ }
+end
+
+function wifinet.get_i18n(self)
+ return "%s: %s %q (%s)" %{
+ i18n.translate("Wireless Network"),
+ i18n.translate(self:active_mode()),
+ self:active_ssid() or self:active_bssid(),
+ self:ifname()
+ }
+end
+
+function wifinet.adminlink(self)
+ return dsp.build_url("admin", "network", "wireless", self.netid)
+end
+
+function wifinet.get_network(self)
+ if uci_r:get("network", self.iwdata.network) == "interface" then
+ return network(self.iwdata.network)
+ end
+end
+
+function wifinet.get_interface(self)
+ return interface(self:ifname())
+end