--- /dev/null
+--[[
+LuCI - Wireless model
+
+Copyright 2009 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
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+]]--
+
+local pairs, i18n, uci, math = pairs, luci.i18n, luci.model.uci, math
+
+local iwi = require "iwinfo"
+local utl = require "luci.util"
+local uct = require "luci.model.uci.bind"
+
+module "luci.model.network.wireless"
+
+local ub = uct.bind("wireless")
+local st, ifs
+
+function init(self, cursor)
+ cursor:unload("wireless")
+ cursor:load("wireless")
+ ub:init(cursor)
+
+ st = uci.cursor_state()
+ ifs = { }
+
+ local count = 0
+
+ ub.uci:foreach("wireless", "wifi-iface",
+ function(s)
+ count = count + 1
+
+ local id = "%s.network%d" %{ self.device, count }
+
+ ifs[id] = {
+ id = id,
+ sid = s['.name'],
+ count = count
+ }
+
+ local dev = st:get("wireless", s['.name'], "ifname")
+ or st:get("wireless", s['.name'], "device")
+
+ local wtype = dev and iwi.type(dev)
+
+ if dev and wtype then
+ ifs[id].winfo = iwi[wtype]
+ ifs[id].wdev = dev
+ end
+ end)
+end
+
+function get_device(self, dev)
+ return device(dev)
+end
+
+function get_network(self, id)
+ if ifs[id] then
+ return network(ifs[id].sid)
+ else
+ local n
+ for n, _ in pairs(ifs) do
+ if ifs[n].sid == id then
+ return network(id)
+ end
+ end
+ end
+end
+
+function shortname(self, iface)
+ if iface.dev and iface.dev.wifi then
+ return "%s %q" %{
+ i18n.translate("a_s_if_iwmode_" .. (iface.dev.wifi.mode or "ap")),
+ iface.dev.wifi.ssid or iface.dev.wifi.bssid or "(hidden)"
+ }
+ else
+ return iface:name()
+ end
+end
+
+function get_i18n(self, iface)
+ if iface.dev and iface.dev.wifi then
+ return "%s: %s %q" %{
+ i18n.translate("a_s_if_wifinet", "Wireless Network"),
+ i18n.translate("a_s_if_iwmode_" .. (iface.dev.wifi.mode or "ap"), iface.dev.wifi.mode or "AP"),
+ iface.dev.wifi.ssid or iface.dev.wifi.bssid or "(hidden)"
+ }
+ else
+ return "%s: %q" %{ i18n.translate("a_s_if_wifinet", "Wireless Network"), iface:name() }
+ end
+end
+
+function rename_network(self, old, new)
+ local i
+ for i, _ in pairs(ifs) do
+ if ifs[i].network == old then
+ ifs[i].network = new
+ end
+ end
+
+ ub.uci:foreach("wireless", "wifi-iface",
+ function(s)
+ if s.network == old then
+ if new then
+ ub.uci:set("wireless", s['.name'], "network", new)
+ else
+ ub.uci:delete("wireless", s['.name'], "network")
+ end
+ end
+ end)
+end
+
+function del_network(self, old)
+ return self:rename_network(old, nil)
+end
+
+function find_interfaces(self, iflist, brlist)
+ local iface
+ for iface, _ in pairs(ifs) do
+ iflist[iface] = ifs[iface]
+ end
+end
+
+function ignore_interface(self, iface)
+ if ifs and ifs[iface] then
+ return false
+ else
+ return iwi.type(iface) and true or false
+ end
+end
+
+function add_interface(self, net, iface)
+ if ifs and ifs[iface] and ifs[iface].sid then
+ ub.uci:set("wireless", ifs[iface].sid, "network", net:name())
+ ifs[iface].network = net:name()
+ return true
+ end
+
+ return false
+end
+
+function del_interface(self, net, iface)
+ if ifs and ifs[iface] and ifs[iface].sid then
+ ub.uci:delete("wireless", ifs[iface].sid, "network")
+ --return true
+ end
+
+ return false
+end
+
+
+device = ub:section("wifi-device")
+device:property("type")
+device:property("channel")
+device:property("disabled")
+
+function device.name(self)
+ return self.sid
+end
+
+function device.get_networks(self)
+ local nets = { }
+
+ ub.uci:foreach("wireless", "wifi-iface",
+ function(s)
+ if s.device == self:name() then
+ nets[#nets+1] = network(s['.name'])
+ end
+ end)
+
+ return nets
+end
+
+
+network = ub:section("wifi-iface")
+network:property("mode")
+network:property("ssid")
+network:property("bssid")
+network:property("network")
+
+function network._init(self, sid)
+ local count = 0
+
+ ub.uci:foreach("wireless", "wifi-iface",
+ function(s)
+ count = count + 1
+ return s['.name'] ~= sid
+ end)
+
+ self.id = "%s.network%d" %{ self.device, count }
+
+ local dev = st:get("wireless", sid, "ifname")
+ or st:get("wireless", sid, "device")
+
+ local wtype = dev and iwi.type(dev)
+
+ if dev and wtype then
+ self.winfo = iwi[wtype]
+ self.wdev = dev
+ end
+end
+
+function network.name(self)
+ return self.id
+end
+
+function network.ifname(self)
+ return self.wdev
+end
+
+function network.get_device(self)
+ if self.device then
+ return device(self.device)
+ end
+end
+
+function network.active_mode(self)
+ local m = self.winfo and self.winfo.mode(self.wdev)
+ if m == "Master" or m == "Auto" then
+ m = "ap"
+ elseif m == "Ad-Hoc" then
+ m = "adhoc"
+ elseif m == "Client" then
+ m = "sta"
+ elseif m then
+ m = m:lower()
+ else
+ m = self:mode()
+ end
+ return m or "ap"
+end
+
+function network.active_mode_i18n(self)
+ return i18n.translate("a_s_if_iwmode_" .. self:active_mode())
+end
+
+function network.active_ssid(self)
+ return self.winfo and self.winfo.ssid(self.wdev) or
+ self:ssid()
+end
+
+function network.active_bssid(self)
+ return self.winfo and self.winfo.bssid(self.wdev) or
+ self:bssid() or "00:00:00:00:00:00"
+end
+
+function network.signal(self)
+ return self.winfo and self.winfo.signal(self.wdev) or 0
+end
+
+function network.noise(self)
+ return self.winfo and self.winfo.noise(self.wdev) or 0
+end
+
+function network.signal_level(self)
+ if self:active_bssid() ~= "00:00:00:00:00:00" then
+ local signal = self:signal()
+ local noise = 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 network.signal_percent(self)
+ local qc = self.winfo and
+ self.winfo.quality(self.wdev) or 0
+
+ local qm = self.winfo and
+ self.winfo.quality_max(self.wdev) or 0
+
+ if qc > 0 and qm > 0 then
+ return math.floor((100 / qm) * qc)
+ else
+ return 0
+ end
+end
+