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, type, i18n, uci, math = pairs, type, 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",
44 count[s.device] = count[s.device] and count[s.device] + 1 or 1
46 local id = "%s.network%d" %{ s.device, count[s.device] }
54 local dev = st:get("wireless", s['.name'], "ifname")
55 or st:get("wireless", s['.name'], "device")
57 local wtype = dev and iwi.type(dev)
59 ifs[id].winfo = iwi[wtype]
66 function get_device(self, dev)
70 function get_devices(self)
72 ub.uci:foreach("wireless", "wifi-device",
73 function(s) devs[#devs+1] = device(s['.name']) end)
77 function get_network(self, id)
79 return network(ifs[id].sid)
82 for n, _ in pairs(ifs) do
83 if ifs[n].sid == id then
90 function add_network(self, options)
91 if type(options) == "table" and options.device and
92 ub.uci:get("wireless", options.device) == "wifi-device"
94 local s = ub.uci:section("wireless", "wifi-iface", nil, options)
96 ub.uci:foreach("wireless", "wifi-iface", function(s) c = c + 1 end)
98 local id = "%s.network%d" %{ options.device, c }
105 local wtype = iwi.type(options.device)
107 ifs[id].winfo = iwi[wtype]
108 ifs[id].wdev = options.device
115 function del_network(self, id)
117 ub.uci:delete("wireless", ifs[id].sid)
121 for n, _ in pairs(ifs) do
122 if ifs[n].sid == id then
123 ub.uci:delete("wireless", id)
130 function shortname(self, iface)
131 if iface.wdev and iface.winfo then
133 i18n.translate(iface:active_mode()),
134 iface:active_ssid() or i18n.translate("(hidden)")
141 function get_i18n(self, iface)
142 if iface.wdev and iface.winfo then
143 return "%s: %s %q (%s)" %{
144 i18n.translate("Wireless Network"),
145 i18n.translate(iface:active_mode()),
146 iface:active_ssid() or i18n.translate("(hidden)"), iface.wdev
149 return "%s: %q" %{ i18n.translate("Wireless Network"), iface:name() }
153 function find_interfaces(self, iflist, brlist)
155 for iface, _ in pairs(ifs) do
156 iflist[iface] = ifs[iface]
160 function ignore_interface(self, iface)
161 if ifs and ifs[iface] then
164 return iwi.type(iface) and true or false
168 function add_interface(self, net, iface)
169 if ifs and ifs[iface] and ifs[iface].sid then
170 ub.uci:set("wireless", ifs[iface].sid, "network", net:name())
171 ifs[iface].network = net:name()
178 function del_interface(self, net, iface)
179 if ifs and ifs[iface] and ifs[iface].sid then
180 ub.uci:delete("wireless", ifs[iface].sid, "network")
188 device = ub:section("wifi-device")
189 device:property("type")
190 device:property("channel")
191 device:property_bool("disabled")
193 function device.name(self)
197 function device.is_up(self)
200 if not self:disabled() then
201 st:foreach("wireless", "wifi-iface",
203 if s.device == self:name() and s.up == "1" then
213 function device.get_networks(self)
216 ub.uci:foreach("wireless", "wifi-iface",
218 if s.device == self:name() then
219 nets[#nets+1] = network(s['.name'])
227 network = ub:section("wifi-iface")
228 network:property("mode")
229 network:property("ssid")
230 network:property("bssid")
231 network:property("network")
233 function network._init(self, sid)
236 local parent_dev = st:get("wireless", sid, "device")
237 or ub.uci:get("wireless", sid, "device")
239 local dev = st:get("wireless", sid, "ifname")
243 ub.uci:foreach("wireless", "wifi-iface",
246 count[s.device] = count[s.device]
247 and count[s.device] + 1 or 1
248 if s['.name'] == sid then
249 self.id = "%s.network%d" %{ parent_dev, count[s.device] }
251 local wtype = iwi.type(dev)
252 if dev and wtype then
253 self.winfo = iwi[wtype]
262 function network.name(self)
266 function network.ifname(self)
270 function network.get_device(self)
272 return device(self.device)
276 function network.is_up(self)
277 return (st:get("wireless", self.sid, "up") == "1")
280 function network.active_mode(self)
281 local m = self.winfo and self.winfo.mode(self.wdev)
284 if m == "ap" then m = "AP"
285 elseif m == "sta" then m = "Client"
286 elseif m == "adhoc" then m = "Ad-Hoc"
287 elseif m == "mesh" then m = "Mesh"
288 elseif m == "monitor" then m = "Monitor"
294 function network.active_mode_i18n(self)
295 return i18n.translate(self:active_mode())
298 function network.active_ssid(self)
299 return self.winfo and self.winfo.ssid(self.wdev) or
303 function network.active_bssid(self)
304 return self.winfo and self.winfo.bssid(self.wdev) or
305 self:bssid() or "00:00:00:00:00:00"
308 function network.active_encryption(self)
309 local enc = self.winfo and self.winfo.encryption(self.wdev)
310 return enc and enc.description or "-"
313 function network.assoclist(self)
314 return self.winfo and self.winfo.assoclist(self.wdev) or { }
317 function network.frequency(self)
318 local freq = self.winfo and self.winfo.frequency(self.wdev)
319 return freq and freq > 0 and "%.03f" % (freq / 1000)
322 function network.bitrate(self)
323 local rate = self.winfo and self.winfo.bitrate(self.wdev)
324 return rate and rate > 0 and (rate / 1000)
327 function network.channel(self)
328 return self.winfo and self.winfo.channel(self.wdev)
331 function network.signal(self)
332 return self.winfo and self.winfo.signal(self.wdev) or 0
335 function network.noise(self)
336 return self.winfo and self.winfo.noise(self.wdev) or 0
339 function network.signal_level(self, s, n)
340 if self:active_bssid() ~= "00:00:00:00:00:00" then
341 local signal = s or self:signal()
342 local noise = n or self:noise()
344 if signal < 0 and noise < 0 then
345 local snr = -1 * (noise - signal)
346 return math.floor(snr / 5)
355 function network.signal_percent(self)
356 local qc = self.winfo and
357 self.winfo.quality(self.wdev) or 0
359 local qm = self.winfo and
360 self.winfo.quality_max(self.wdev) or 0
362 if qc > 0 and qm > 0 then
363 return math.floor((100 / qm) * qc)