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