4 Copyright 2009 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 pairs, i18n, uci, math = pairs, luci.i18n, luci.model.uci, math
22 local iwi = require "iwinfo"
23 local utl = require "luci.util"
24 local uct = require "luci.model.uci.bind"
26 module "luci.model.wireless"
28 local ub = uct.bind("wireless")
32 cursor:unload("wireless")
33 cursor:load("wireless")
36 st = uci.cursor_state()
41 ub.uci:foreach("wireless", "wifi-iface",
45 local id = "%s.network%d" %{ s.device, count }
53 local dev = st:get("wireless", s['.name'], "ifname")
54 or st:get("wireless", s['.name'], "device")
56 local wtype = dev and iwi.type(dev)
59 ifs[id].winfo = iwi[wtype]
65 function get_device(self, dev)
69 function get_devices(self)
71 ub.uci:foreach("wireless", "wifi-device",
72 function(s) devs[#devs+1] = device(s['.name']) end)
76 function get_network(self, id)
78 return network(ifs[id].sid)
81 for n, _ in pairs(ifs) do
82 if ifs[n].sid == id then
89 function shortname(self, iface)
90 if iface.wdev and iface.winfo then
92 i18n.translate("a_s_if_iwmode_" .. iface:active_mode(), iface.winfo.mode(iface.wdev)),
93 iface:active_ssid() or "(hidden)"
100 function get_i18n(self, iface)
101 if iface.wdev and iface.winfo then
102 return "%s: %s %q (%s)" %{
103 i18n.translate("a_s_if_wifinet", "Wireless Network"),
104 i18n.translate("a_s_if_iwmode_" .. iface:active_mode(), iface.winfo.mode(iface.wdev)),
105 iface:active_ssid() or "(hidden)", iface.wdev
108 return "%s: %q" %{ i18n.translate("a_s_if_wifinet", "Wireless Network"), iface:name() }
112 function del_network(self, id)
114 ub.uci:delete("wireless", ifs[id].sid)
118 for n, _ in pairs(ifs) do
119 if ifs[n].sid == id then
120 ub.uci:delete("wireless", id)
127 function find_interfaces(self, iflist, brlist)
129 for iface, _ in pairs(ifs) do
130 iflist[iface] = ifs[iface]
134 function ignore_interface(self, iface)
135 if ifs and ifs[iface] then
138 return iwi.type(iface) and true or false
142 function add_interface(self, net, iface)
143 if ifs and ifs[iface] and ifs[iface].sid then
144 ub.uci:set("wireless", ifs[iface].sid, "network", net:name())
145 ifs[iface].network = net:name()
152 function del_interface(self, net, iface)
153 if ifs and ifs[iface] and ifs[iface].sid then
154 ub.uci:delete("wireless", ifs[iface].sid, "network")
162 device = ub:section("wifi-device")
163 device:property("type")
164 device:property("channel")
165 device:property_bool("disabled")
167 function device.name(self)
171 function device.is_up(self)
174 if not self:disabled() then
175 st:foreach("wireless", "wifi-iface",
177 if s.device == self:name() and s.up == "1" then
187 function device.get_networks(self)
190 ub.uci:foreach("wireless", "wifi-iface",
192 if s.device == self:name() then
193 nets[#nets+1] = network(s['.name'])
201 network = ub:section("wifi-iface")
202 network:property("mode")
203 network:property("ssid")
204 network:property("bssid")
205 network:property("network")
207 function network._init(self, sid)
210 ub.uci:foreach("wireless", "wifi-iface",
213 return s['.name'] ~= sid
216 local dev = st:get("wireless", sid, "ifname")
217 or st:get("wireless", sid, "device")
220 self.id = "%s.network%d" %{ dev, count }
222 local wtype = iwi.type(dev)
223 if dev and wtype then
224 self.winfo = iwi[wtype]
230 function network.name(self)
234 function network.ifname(self)
238 function network.get_device(self)
240 return device(self.device)
244 function network.is_up(self)
245 return (st:get("wireless", self.sid, "up") == "1")
248 function network.active_mode(self)
249 local m = self.winfo and self.winfo.mode(self.wdev)
250 if m == "Master" or m == "Auto" then
252 elseif m == "Ad-Hoc" then
254 elseif m == "Client" then
264 function network.active_mode_i18n(self)
265 return i18n.translate("a_s_if_iwmode_" .. self:active_mode())
268 function network.active_ssid(self)
269 return self.winfo and self.winfo.ssid(self.wdev) or
273 function network.active_bssid(self)
274 return self.winfo and self.winfo.bssid(self.wdev) or
275 self:bssid() or "00:00:00:00:00:00"
278 function network.active_encryption(self)
279 return self.winfo and self.winfo.enctype(self.wdev) or "-"
282 function network.assoclist(self)
283 return self.winfo and self.winfo.assoclist(self.wdev) or { }
286 function network.frequency(self)
287 local freq = self.winfo and self.winfo.frequency(self.wdev)
288 return freq and freq > 0 and "%.03f" % (freq / 1000)
291 function network.bitrate(self)
292 local rate = self.winfo and self.winfo.bitrate(self.wdev)
293 return rate and rate > 0 and (rate / 1000)
296 function network.channel(self)
297 return self.winfo and self.winfo.channel(self.wdef)
300 function network.signal(self)
301 return self.winfo and self.winfo.signal(self.wdev) or 0
304 function network.noise(self)
305 return self.winfo and self.winfo.noise(self.wdev) or 0
308 function network.signal_level(self, s, n)
309 if self:active_bssid() ~= "00:00:00:00:00:00" then
310 local signal = s or self:signal()
311 local noise = n or self:noise()
313 if signal < 0 and noise < 0 then
314 local snr = -1 * (noise - signal)
315 return math.floor(snr / 5)
324 function network.signal_percent(self)
325 local qc = self.winfo and
326 self.winfo.quality(self.wdev) or 0
328 local qm = self.winfo and
329 self.winfo.quality_max(self.wdev) or 0
331 if qc > 0 and qm > 0 then
332 return math.floor((100 / qm) * qc)