diff options
Diffstat (limited to 'modules/luci-base')
-rw-r--r-- | modules/luci-base/luasrc/controller/admin/index.lua | 40 | ||||
-rw-r--r-- | modules/luci-base/luasrc/view/cbi/wireless_modefreq.htm | 168 | ||||
-rw-r--r-- | modules/luci-base/luasrc/view/lease_status.htm | 95 | ||||
-rw-r--r-- | modules/luci-base/luasrc/view/wifi_assoclist.htm | 82 |
4 files changed, 385 insertions, 0 deletions
diff --git a/modules/luci-base/luasrc/controller/admin/index.lua b/modules/luci-base/luasrc/controller/admin/index.lua index 39e6e573b1..360298b1cd 100644 --- a/modules/luci-base/luasrc/controller/admin/index.lua +++ b/modules/luci-base/luasrc/controller/admin/index.lua @@ -16,6 +16,8 @@ function index() end end + local uci = require("luci.model.uci").cursor() + local root = node() if not root.target then root.target = alias("admin") @@ -23,6 +25,7 @@ function index() end local page = node("admin") + page.title = _("Administration") page.order = 10 page.sysauth = "root" @@ -61,6 +64,24 @@ function index() page.index = true toplevel_page(page, false, false) + if nixio.fs.access("/etc/config/dhcp") then + page = entry({"admin", "dhcplease_status"}, call("lease_status"), nil) + page.leaf = true + end + + local has_wifi = false + + uci:foreach("wireless", "wifi-device", + function(s) + has_wifi = true + return false + end) + + if has_wifi then + page = entry({"admin", "wireless_assoclist"}, call("wifi_assoclist"), nil) + page.leaf = true + end + -- Logout is last entry({"admin", "logout"}, call("action_logout"), _("Logout"), 999) end @@ -80,3 +101,22 @@ function action_logout() luci.http.redirect(dsp.build_url()) end + + +function lease_status() + local s = require "luci.tools.status" + + luci.http.prepare_content("application/json") + luci.http.write('[') + luci.http.write_json(s.dhcp_leases()) + luci.http.write(',') + luci.http.write_json(s.dhcp6_leases()) + luci.http.write(']') +end + +function wifi_assoclist() + local s = require "luci.tools.status" + + luci.http.prepare_content("application/json") + luci.http.write_json(s.wifi_assoclist()) +end diff --git a/modules/luci-base/luasrc/view/cbi/wireless_modefreq.htm b/modules/luci-base/luasrc/view/cbi/wireless_modefreq.htm new file mode 100644 index 0000000000..ebb02e489b --- /dev/null +++ b/modules/luci-base/luasrc/view/cbi/wireless_modefreq.htm @@ -0,0 +1,168 @@ +<%+cbi/valueheader%> + +<script type="text/javascript">//<![CDATA[ + var freqlist = <%= luci.http.write_json(self.iwinfo.freqlist) %>; + var hwmodes = <%= luci.http.write_json(self.iwinfo.hwmodelist or {}) %>; + var htmodes = <%= luci.http.write_json(self.iwinfo.htmodelist) %>; + + var channels = { + '11g': [ + 'auto', 'auto', true + ], + '11a': [ + 'auto', 'auto', true + ] + }; + + for (var i = 0; i < freqlist.length; i++) + channels[(freqlist[i].mhz > 2484) ? '11a' : '11g'].push( + freqlist[i].channel, + '%d (%d MHz)'.format(freqlist[i].channel, freqlist[i].mhz), + !freqlist[i].restricted + ); + + var modes = [ + '', 'Legacy', true, + 'n', 'N', hwmodes.n, + 'ac', 'AC', hwmodes.ac + ]; + + var htmodes = { + '': [ + '', '-', true + ], + 'n': [ + 'HT20', '20 MHz', htmodes.HT20, + 'HT40', '40 MHz', htmodes.HT40 + ], + 'ac': [ + 'VHT20', '20 MHz', htmodes.VHT20, + 'VHT40', '40 MHz', htmodes.VHT40, + 'VHT80', '80 MHz', htmodes.VHT80, + 'VHT160', '160 MHz', htmodes.VHT160 + ] + }; + + var bands = { + '': [ + '11g', '2.4 GHz', (channels['11g'].length > 3), + '11a', '5 GHz', (channels['11a'].length > 3) + ], + 'n': [ + '11g', '2.4 GHz', (channels['11g'].length > 3), + '11a', '5 GHz', (channels['11a'].length > 3) + ], + 'ac': [ + '11a', '5 GHz', true + ] + }; + + function cbi_set_values(sel, vals) + { + if (sel.vals) + sel.vals.selected = sel.selectedIndex; + + while (sel.options[0]) + sel.remove(0); + + for (var i = 0; vals && i < vals.length; i += 3) + { + if (!vals[i+2]) + continue; + + var opt = document.createElement('option'); + opt.value = vals[i+0]; + opt.text = vals[i+1]; + + sel.add(opt); + } + + if (!isNaN(vals.selected)) + sel.selectedIndex = vals.selected; + + sel.parentNode.style.display = (sel.options.length <= 1) ? 'none' : ''; + sel.vals = vals; + } + + function cbi_toggle_wifi_mode(id) + { + cbi_toggle_wifi_htmode(id); + cbi_toggle_wifi_band(id); + } + + function cbi_toggle_wifi_htmode(id) + { + var mode = document.getElementById(id + '.mode'); + var bwdt = document.getElementById(id + '.htmode'); + + cbi_set_values(bwdt, htmodes[mode.value]); + } + + function cbi_toggle_wifi_band(id) + { + var mode = document.getElementById(id + '.mode'); + var band = document.getElementById(id + '.band'); + + cbi_set_values(band, bands[mode.value]); + cbi_toggle_wifi_channel(id); + } + + function cbi_toggle_wifi_channel(id) + { + var band = document.getElementById(id + '.band'); + var chan = document.getElementById(id + '.channel'); + + cbi_set_values(chan, channels[band.value]); + } + + function cbi_init_wifi(id) + { + var mode = document.getElementById(id + '.mode'); + var band = document.getElementById(id + '.band'); + var chan = document.getElementById(id + '.channel'); + var bwdt = document.getElementById(id + '.htmode'); + + cbi_set_values(mode, modes); + + if (/VHT20|VHT40|VHT80|VHT160/.test(<%= luci.http.write_json(self.map:get(section, "htmode")) %>)) + mode.value = 'ac'; + else if (/HT20|HT40/.test(<%= luci.http.write_json(self.map:get(section, "htmode")) %>)) + mode.value = 'n'; + else + mode.value = ''; + + cbi_toggle_wifi_mode(id); + + if (/a/.test(<%= luci.http.write_json(self.map:get(section, "hwmode")) %>)) + band.value = '11a'; + else + band.value = '11g'; + + cbi_toggle_wifi_band(id); + + bwdt.value = <%= luci.http.write_json(self.map:get(section, "htmode")) %>; + chan.value = <%= luci.http.write_json(self.map:get(section, "channel")) %>; + } +//]]></script> + +<label style="float:left; margin-right:3px"> + <%:Mode%><br /> + <select style="width:auto" id="<%= cbid %>.mode" name="<%= cbid %>.mode" onchange="cbi_toggle_wifi_mode('<%= cbid %>')"></select> +</label> +<label style="float:left; margin-right:3px"> + <%:Band%><br /> + <select style="width:auto" id="<%= cbid %>.band" name="<%= cbid %>.band" onchange="cbi_toggle_wifi_band('<%= cbid %>')"></select> +</label> +<label style="float:left; margin-right:3px"> + <%:Channel%><br /> + <select style="width:auto" id="<%= cbid %>.channel" name="<%= cbid %>.channel"></select> +</label> +<label style="float:left; margin-right:3px"> + <%:Width%><br /> + <select style="width:auto" id="<%= cbid %>.htmode" name="<%= cbid %>.htmode"></select> +</label> +<br style="clear:left" /> + +<script type="text/javascript">cbi_init_wifi('<%= cbid %>');</script> + +<%+cbi/valuefooter%> diff --git a/modules/luci-base/luasrc/view/lease_status.htm b/modules/luci-base/luasrc/view/lease_status.htm new file mode 100644 index 0000000000..15b6b6908e --- /dev/null +++ b/modules/luci-base/luasrc/view/lease_status.htm @@ -0,0 +1,95 @@ +<script type="text/javascript">//<![CDATA[ + XHR.poll(5, '<%=url('admin/dhcplease_status')%>', null, + function(x, st) + { + var tb = document.getElementById('lease_status_table'); + if (st && st[0] && tb) + { + var rows = []; + + for (var i = 0; i < st[0].length; i++) + { + var timestr; + + if (st[0][i].expires === false) + timestr = '<em><%:unlimited%></em>'; + else if (st[0][i].expires <= 0) + timestr = '<em><%:expired%></em>'; + else + timestr = String.format('%t', st[0][i].expires); + + rows.push([ + st[0][i].hostname || '?', + st[0][i].ipaddr, + st[0][i].macaddr, + timestr + ]); + } + + cbi_update_table(tb, rows, '<em><%:There are no active leases.%></em>'); + } + + var tb6 = document.getElementById('lease6_status_table'); + if (st && st[1] && tb6) + { + tb6.parentNode.style.display = 'block'; + + var rows = []; + + for (var i = 0; i < st[1].length; i++) + { + var timestr; + + if (st[1][i].expires === false) + timestr = '<em><%:unlimited%></em>'; + else if (st[1][i].expires <= 0) + timestr = '<em><%:expired%></em>'; + else + timestr = String.format('%t', st[1][i].expires); + + var name = st[1][i].hostname, + hint = st[1][i].host_hint; + + rows.push([ + hint ? '%h (%h)'.format(name || '?', hint) : (name || '?'), + st[1][i].ip6addr, + st[1][i].duid, + timestr + ]); + } + + cbi_update_table(tb6, rows, '<em><%:There are no active leases.%></em>'); + } + } + ); +//]]></script> + +<div class="cbi-section"> + <h3><%:Active DHCP Leases%></h3> + <div class="table" id="lease_status_table"> + <div class="tr table-titles"> + <div class="th"><%:Hostname%></div> + <div class="th"><%:IPv4-Address%></div> + <div class="th"><%:MAC-Address%></div> + <div class="th"><%:Leasetime remaining%></div> + </div> + <div class="tr placeholder"> + <div class="td"><em><%:Collecting data...%></em></div> + </div> + </div> +</div> + +<div class="cbi-section" style="display:none"> + <h3><%:Active DHCPv6 Leases%></h3> + <div class="table" id="lease6_status_table"> + <div class="tr table-titles"> + <div class="th"><%:Host%></div> + <div class="th"><%:IPv6-Address%></div> + <div class="th"><%:DUID%></div> + <div class="th"><%:Leasetime remaining%></div> + </div> + <div class="tr placeholder"> + <div class="td"><em><%:Collecting data...%></em></div> + </div> + </div> +</div> diff --git a/modules/luci-base/luasrc/view/wifi_assoclist.htm b/modules/luci-base/luasrc/view/wifi_assoclist.htm new file mode 100644 index 0000000000..700d998ad8 --- /dev/null +++ b/modules/luci-base/luasrc/view/wifi_assoclist.htm @@ -0,0 +1,82 @@ +<script type="text/javascript">//<![CDATA[ + function wifirate(bss, rx) { + var p = rx ? 'rx_' : 'tx_', + s = '%.1f <%:Mbit/s%>, %d<%:MHz%>' + .format(bss[p+'rate'] / 1000, bss[p+'mhz']), + ht = bss[p+'ht'], vht = bss[p+'vht'], + mhz = bss[p+'mhz'], nss = bss[p+'nss'], + mcs = bss[p+'mcs'], sgi = bss[p+'short_gi']; + + if (ht || vht) { + if (vht) s += ', VHT-MCS %d'.format(mcs); + if (nss) s += ', VHT-NSS %d'.format(nss); + if (ht) s += ', MCS %s'.format(mcs); + if (sgi) s += ', <%:Short GI%>'; + } + + return s; + } + + XHR.poll(5, '<%=url('admin/wireless_assoclist')%>', null, + function(x, st) + { + var tb = document.getElementById('wifi_assoclist_table'); + if (st && tb) + { + var rows = []; + + st.forEach(function(bss) { + var icon; + var q = (-1 * (bss.noise - bss.signal)) / 5; + if (q < 1) + icon = "<%=resource%>/icons/signal-0.png"; + else if (q < 2) + icon = "<%=resource%>/icons/signal-0-25.png"; + else if (q < 3) + icon = "<%=resource%>/icons/signal-25-50.png"; + else if (q < 4) + icon = "<%=resource%>/icons/signal-50-75.png"; + else + icon = "<%=resource%>/icons/signal-75-100.png"; + + rows.push([ + '<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> <a href="%s">%h</a><small> (%h)</small></span>'.format( + bss.radio, + bss.link, + bss.name, + bss.ifname), + bss.bssid, + bss.host_hint ? '%h (%h)'.format(bss.host_name || '?', bss.host_hint) : (bss.host_name || '?'), + '<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>'.format( + bss.signal, + bss.noise, + bss.signal - bss.noise, + icon, + bss.signal, + bss.noise), + E('span', {}, [ + E('span', wifirate(bss, true)), + E('br'), + E('span', wifirate(bss, false)) + ]) + ]); + }); + + cbi_update_table(tb, rows, '<em><%:No information available%></em>'); + } + } + ); +//]]></script> + +<div class="table" id="wifi_assoclist_table"> + <div class="tr table-titles"> + <div class="th nowrap"><%:Network%></div> + <div class="th hide-xs"><%:MAC-Address%></div> + <div class="th nowrap"><%:Host%></div> + <div class="th nowrap"><%:Signal%> / <%:Noise%></div> + <div class="th nowrap"><%:RX Rate%> / <%:TX Rate%></div> + </div> + <div class="tr placeholder"> + <div class="td"><em><%:Collecting data...%></em></div> + </div> +</div> |