all: various i18n realted fixes
[project/luci.git] / libs / core / luasrc / model / wireless.lua
1 --[[
2 LuCI - Wireless model
3
4 Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
5
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
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
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.
17
18 ]]--
19
20 local pairs, i18n, uci, math = pairs, luci.i18n, luci.model.uci, math
21
22 local iwi = require "iwinfo"
23 local utl = require "luci.util"
24 local uct = require "luci.model.uci.bind"
25
26 module "luci.model.wireless"
27
28 local ub = uct.bind("wireless")
29 local st, ifs
30
31 function init(cursor)
32 cursor:unload("wireless")
33 cursor:load("wireless")
34 ub:init(cursor)
35
36 st = uci.cursor_state()
37 ifs = { }
38
39 local count = 0
40
41 ub.uci:foreach("wireless", "wifi-iface",
42 function(s)
43 count = count + 1
44
45 local id = "%s.network%d" %{ s.device, count }
46
47 ifs[id] = {
48 id = id,
49 sid = s['.name'],
50 count = count
51 }
52
53 local dev = st:get("wireless", s['.name'], "ifname")
54 or st:get("wireless", s['.name'], "device")
55
56 local wtype = dev and iwi.type(dev)
57
58 if dev and wtype then
59 ifs[id].winfo = iwi[wtype]
60 ifs[id].wdev = dev
61 end
62 end)
63 end
64
65 function get_device(self, dev)
66 return device(dev)
67 end
68
69 function get_devices(self)
70 local devs = { }
71 ub.uci:foreach("wireless", "wifi-device",
72 function(s) devs[#devs+1] = device(s['.name']) end)
73 return devs
74 end
75
76 function get_network(self, id)
77 if ifs[id] then
78 return network(ifs[id].sid)
79 else
80 local n
81 for n, _ in pairs(ifs) do
82 if ifs[n].sid == id then
83 return network(id)
84 end
85 end
86 end
87 end
88
89 function shortname(self, iface)
90 if iface.wdev and iface.winfo then
91 return "%s %q" %{
92 i18n.translate(iface:active_mode()),
93 iface:active_ssid() or i18n.translate("(hidden)")
94 }
95 else
96 return iface:name()
97 end
98 end
99
100 function get_i18n(self, iface)
101 if iface.wdev and iface.winfo then
102 return "%s: %s %q (%s)" %{
103 i18n.translate("Wireless Network"),
104 i18n.translate(iface:active_mode()),
105 iface:active_ssid() or i18n.translate("(hidden)"), iface.wdev
106 }
107 else
108 return "%s: %q" %{ i18n.translate("Wireless Network"), iface:name() }
109 end
110 end
111
112 function del_network(self, id)
113 if ifs[id] then
114 ub.uci:delete("wireless", ifs[id].sid)
115 ifs[id] = nil
116 else
117 local n
118 for n, _ in pairs(ifs) do
119 if ifs[n].sid == id then
120 ub.uci:delete("wireless", id)
121 ifs[n] = nil
122 end
123 end
124 end
125 end
126
127 function find_interfaces(self, iflist, brlist)
128 local iface
129 for iface, _ in pairs(ifs) do
130 iflist[iface] = ifs[iface]
131 end
132 end
133
134 function ignore_interface(self, iface)
135 if ifs and ifs[iface] then
136 return false
137 else
138 return iwi.type(iface) and true or false
139 end
140 end
141
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()
146 return true
147 end
148
149 return false
150 end
151
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")
155 --return true
156 end
157
158 return false
159 end
160
161
162 device = ub:section("wifi-device")
163 device:property("type")
164 device:property("channel")
165 device:property_bool("disabled")
166
167 function device.name(self)
168 return self.sid
169 end
170
171 function device.is_up(self)
172 local rv = false
173
174 if not self:disabled() then
175 st:foreach("wireless", "wifi-iface",
176 function(s)
177 if s.device == self:name() and s.up == "1" then
178 rv = true
179 return false
180 end
181 end)
182 end
183
184 return rv
185 end
186
187 function device.get_networks(self)
188 local nets = { }
189
190 ub.uci:foreach("wireless", "wifi-iface",
191 function(s)
192 if s.device == self:name() then
193 nets[#nets+1] = network(s['.name'])
194 end
195 end)
196
197 return nets
198 end
199
200
201 network = ub:section("wifi-iface")
202 network:property("mode")
203 network:property("ssid")
204 network:property("bssid")
205 network:property("network")
206
207 function network._init(self, sid)
208 local count = 0
209
210 ub.uci:foreach("wireless", "wifi-iface",
211 function(s)
212 count = count + 1
213 return s['.name'] ~= sid
214 end)
215
216 local parent_dev = st:get("wireless", sid, "device")
217
218 local dev = st:get("wireless", sid, "ifname")
219 or parent_dev
220
221 if dev then
222 self.id = "%s.network%d" %{ parent_dev, count }
223
224 local wtype = iwi.type(dev)
225 if dev and wtype then
226 self.winfo = iwi[wtype]
227 self.wdev = dev
228 end
229 end
230 end
231
232 function network.name(self)
233 return self.id
234 end
235
236 function network.ifname(self)
237 return self.wdev
238 end
239
240 function network.get_device(self)
241 if self.device then
242 return device(self.device)
243 end
244 end
245
246 function network.is_up(self)
247 return (st:get("wireless", self.sid, "up") == "1")
248 end
249
250 function network.active_mode(self)
251 local m = self.winfo and self.winfo.mode(self.wdev)
252 if not m then
253 m = self:mode()
254 if m == "ap" then m = "AP"
255 elseif m == "sta" then m = "Client"
256 elseif m == "adhoc" then m = "Ad-Hoc"
257 elseif m == "mesh" then m = "Mesh"
258 elseif m == "monitor" then m = "Monitor"
259 end
260 end
261 return m or "Client"
262 end
263
264 function network.active_mode_i18n(self)
265 return i18n.translate(self:active_mode())
266 end
267
268 function network.active_ssid(self)
269 return self.winfo and self.winfo.ssid(self.wdev) or
270 self:ssid()
271 end
272
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"
276 end
277
278 function network.active_encryption(self)
279 return self.winfo and self.winfo.enctype(self.wdev) or "-"
280 end
281
282 function network.assoclist(self)
283 return self.winfo and self.winfo.assoclist(self.wdev) or { }
284 end
285
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)
289 end
290
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)
294 end
295
296 function network.channel(self)
297 return self.winfo and self.winfo.channel(self.wdev)
298 end
299
300 function network.signal(self)
301 return self.winfo and self.winfo.signal(self.wdev) or 0
302 end
303
304 function network.noise(self)
305 return self.winfo and self.winfo.noise(self.wdev) or 0
306 end
307
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()
312
313 if signal < 0 and noise < 0 then
314 local snr = -1 * (noise - signal)
315 return math.floor(snr / 5)
316 else
317 return 0
318 end
319 else
320 return -1
321 end
322 end
323
324 function network.signal_percent(self)
325 local qc = self.winfo and
326 self.winfo.quality(self.wdev) or 0
327
328 local qm = self.winfo and
329 self.winfo.quality_max(self.wdev) or 0
330
331 if qc > 0 and qm > 0 then
332 return math.floor((100 / qm) * qc)
333 else
334 return 0
335 end
336 end
337