summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-base
diff options
context:
space:
mode:
Diffstat (limited to 'modules/luci-base')
-rw-r--r--modules/luci-base/luasrc/controller/admin/index.lua40
-rw-r--r--modules/luci-base/luasrc/view/cbi/wireless_modefreq.htm168
-rw-r--r--modules/luci-base/luasrc/view/lease_status.htm95
-rw-r--r--modules/luci-base/luasrc/view/wifi_assoclist.htm82
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>&#160;(%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>