luci-app-olsr: handle empty result for non-status tables
[oweals/luci.git] / modules / luci-mod-network / luasrc / model / cbi / admin_network / wifi_overview.lua
1 -- Copyright 2018 Jo-Philipp Wich <jo@mein.io>
2 -- Licensed to the public under the Apache License 2.0.
3
4 local fs = require "nixio.fs"
5 local utl = require "luci.util"
6 local tpl = require "luci.template"
7 local ntm = require "luci.model.network"
8
9 local has_iwinfo = pcall(require, "iwinfo")
10
11 function guess_wifi_hw(dev)
12         local bands = ""
13         local ifname = dev:name()
14         local name, idx = ifname:match("^([a-z]+)(%d+)")
15         idx = tonumber(idx)
16
17         if has_iwinfo then
18                 local bl = dev.iwinfo.hwmodelist
19                 if bl and next(bl) then
20                         if bl.a then bands = bands .. "a" end
21                         if bl.b then bands = bands .. "b" end
22                         if bl.g then bands = bands .. "g" end
23                         if bl.n then bands = bands .. "n" end
24                         if bl.ac then bands = bands .. "ac" end
25                 end
26
27                 local hw = dev.iwinfo.hardware_name
28                 if hw then
29                         return "%s 802.11%s" %{ hw, bands }
30                 end
31         end
32
33         -- wl.o
34         if name == "wl" then
35                 local name = translatef("Broadcom 802.11%s Wireless Controller", bands)
36                 local nm   = 0
37
38                 local fd = nixio.open("/proc/bus/pci/devices", "r")
39                 if fd then
40                         local ln
41                         for ln in fd:linesource() do
42                                 if ln:match("wl$") then
43                                         if nm == idx then
44                                                 local version = ln:match("^%S+%s+%S%S%S%S([0-9a-f]+)")
45                                                 name = translatef(
46                                                         "Broadcom BCM%04x 802.11 Wireless Controller",
47                                                         tonumber(version, 16)
48                                                 )
49
50                                                 break
51                                         else
52                                                 nm = nm + 1
53                                         end
54                                 end
55                         end
56                         fd:close()
57                 end
58
59                 return name
60
61         -- dunno yet
62         else
63                 return translatef("Generic 802.11%s Wireless Controller", bands)
64         end
65 end
66
67
68 m = Map("wireless", translate("Wireless Overview"))
69 m:chain("network")
70 m.pageaction = false
71
72 if not has_iwinfo then
73         s = m:section(NamedSection, "__warning__")
74
75         function s.render(self)
76                 tpl.render_string([[
77                         <div class="alert-message warning">
78                                 <h4><%:Package libiwinfo required!%></h4>
79                                 <p><%_The <em>libiwinfo-lua</em> package is not installed. You must install this component for working wireless configuration!%></p>
80                         </div>
81                 ]])
82         end
83 end
84
85 local _, dev, net
86 for _, dev in ipairs(ntm:get_wifidevs()) do
87         s = m:section(TypedSection)
88         s.template = "admin_network/wifi_overview"
89         s.wnets = dev:get_wifinets()
90         s.dev = dev
91         s.hw = guess_wifi_hw(dev)
92
93         function s.cfgsections(self)
94                 local _, net, sl = nil, nil, { }
95                 for _, net in ipairs(self.wnets) do
96                         sl[#sl+1] = net:name()
97                         self.wnets[net:name()] = net
98                 end
99                 return sl
100         end
101
102         o = s:option(Value, "__disable__")
103
104         function o.cfgvalue(self, sid)
105                 local wnet = self.section.wnets[sid]
106                 local wdev = wnet:get_device()
107
108                 return ((wnet and wnet:get("disabled") == "1") or
109                             (wdev and wdev:get("disabled") == "1")) and "1" or "0"
110         end
111
112         function o.write(self, sid, value)
113                 local wnet = self.section.wnets[sid]
114                 local wdev = wnet:get_device()
115
116                 if value ~= "1" then
117                         wnet:set("disabled", nil)
118                         wdev:set("disabled", nil)
119                 else
120                         wnet:set("disabled", "1")
121                 end
122         end
123
124         o.remove = o.write
125
126
127         o = s:option(Value, "__delete__")
128
129         function o.write(self, sid, value)
130                 local wnet = self.section.wnets[sid]
131                 local nets = wnet:get_networks()
132
133                 ntm:del_wifinet(wnet:id())
134
135                 local _, net
136                 for _, net in ipairs(nets) do
137                         if net:is_empty() then
138                                 ntm:del_network(net:name())
139                         end
140                 end
141         end
142 end
143
144 s = m:section(NamedSection, "__assoclist__")
145
146 function s.render(self, sid)
147         tpl.render_string([[
148                 <h2><%:Associated Stations%></h2>
149                 <%+wifi_assoclist%>
150         ]])
151 end
152
153 return m