luci-base, luci-mod-admin-full: unify wifi assoclist code
Merge the assoclist code of the status overview and wireless overview pages into a single shared partial template. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
86c6c60a0d
commit
e5ba594d77
4 changed files with 165 additions and 232 deletions
|
@ -113,6 +113,11 @@ function wifi_networks()
|
|||
|
||||
local net
|
||||
for _, net in ipairs(dev:get_wifinets()) do
|
||||
local a, an = nil, 0
|
||||
for _, a in pairs(net:assoclist() or {}) do
|
||||
an = an + 1
|
||||
end
|
||||
|
||||
rd.networks[#rd.networks+1] = {
|
||||
name = net:shortname(),
|
||||
link = net:adminlink(),
|
||||
|
@ -128,10 +133,10 @@ function wifi_networks()
|
|||
noise = net:noise(),
|
||||
bitrate = net:bitrate(),
|
||||
ifname = net:ifname(),
|
||||
assoclist = net:assoclist(),
|
||||
country = net:country(),
|
||||
txpower = net:txpower(),
|
||||
txpoweroff = net:txpower_offset(),
|
||||
num_assoc = an,
|
||||
disabled = (dev:get("disabled") == "1" or
|
||||
net:get("disabled") == "1")
|
||||
}
|
||||
|
@ -165,7 +170,6 @@ function wifi_network(id)
|
|||
noise = net:noise(),
|
||||
bitrate = net:bitrate(),
|
||||
ifname = net:ifname(),
|
||||
assoclist = net:assoclist(),
|
||||
country = net:country(),
|
||||
txpower = net:txpower(),
|
||||
txpoweroff = net:txpower_offset(),
|
||||
|
@ -182,6 +186,52 @@ function wifi_network(id)
|
|||
return { }
|
||||
end
|
||||
|
||||
function wifi_assoclist()
|
||||
local sys = require "luci.sys"
|
||||
local ntm = require "luci.model.network".init()
|
||||
local hosts = sys.net.host_hints()
|
||||
|
||||
local assoc = {}
|
||||
local _, dev, net, bss
|
||||
|
||||
for _, dev in ipairs(ntm:get_wifidevs()) do
|
||||
local radioname = dev:get_i18n()
|
||||
|
||||
for _, net in ipairs(dev:get_wifinets()) do
|
||||
local netname = net:shortname()
|
||||
local netlink = net:adminlink()
|
||||
local ifname = net:ifname()
|
||||
|
||||
for _, bss in pairs(net:assoclist() or {}) do
|
||||
local host = hosts[_]
|
||||
|
||||
bss.bssid = _
|
||||
bss.ifname = ifname
|
||||
bss.radio = radioname
|
||||
bss.name = netname
|
||||
bss.link = netlink
|
||||
|
||||
bss.host_name = (host) and (host.name or host.ipv4 or host.ipv6)
|
||||
bss.host_hint = (host and host.name and (host.ipv4 or host.ipv6)) and (host.ipv4 or host.ipv6)
|
||||
|
||||
assoc[#assoc+1] = bss
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(assoc, function(a, b)
|
||||
if a.radio ~= b.radio then
|
||||
return a.radio < b.radio
|
||||
elseif a.ifname ~= b.ifname then
|
||||
return a.ifname < b.ifname
|
||||
else
|
||||
return a.bssid < b.bssid
|
||||
end
|
||||
end)
|
||||
|
||||
return assoc
|
||||
end
|
||||
|
||||
function switch_status(devs)
|
||||
local dev
|
||||
local switches = { }
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
<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/network/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="cbi-section-node">
|
||||
<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>
|
||||
</div>
|
|
@ -113,28 +113,6 @@
|
|||
|
||||
var is_reconnecting = false;
|
||||
|
||||
function nowrap(s) {
|
||||
return s.replace(/ /g, ' ');
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function wifi_shutdown(id, toggle) {
|
||||
var reconnect = (toggle.getAttribute('active') == 'false');
|
||||
|
||||
|
@ -193,20 +171,25 @@
|
|||
{
|
||||
if (st)
|
||||
{
|
||||
var assoctable = document.getElementById('iw-assoclist');
|
||||
if (assoctable)
|
||||
while (assoctable.firstElementChild !== assoctable.lastElementChild)
|
||||
assoctable.removeChild(assoctable.lastElementChild);
|
||||
|
||||
var devup = { };
|
||||
var rowstyle = 1;
|
||||
var radiostate = { };
|
||||
|
||||
st.forEach(function(s) {
|
||||
var r = radiostate[wifidevs[s.id]] || (radiostate[wifidevs[s.id]] = {});
|
||||
|
||||
s.is_assoc = (s.bssid && s.bssid != '00:00:00:00:00:00' && s.channel && s.mode != 'Unknown' && !s.disabled);
|
||||
|
||||
r.up = r.up || s.is_assoc;
|
||||
r.channel = r.channel || s.channel;
|
||||
r.bitrate = r.bitrate || s.bitrate;
|
||||
r.frequency = r.frequency || s.frequency;
|
||||
});
|
||||
|
||||
for( var i = 0; i < st.length; i++ )
|
||||
{
|
||||
var iw = st[i];
|
||||
var is_assoc = (iw.bssid && iw.bssid != '00:00:00:00:00:00' && iw.channel && iw.mode != 'Unknown' && !iw.disabled);
|
||||
var p = iw.quality;
|
||||
var q = is_assoc ? p : -1;
|
||||
var q = iw.is_assoc ? p : -1;
|
||||
|
||||
var icon;
|
||||
if (q < 0)
|
||||
|
@ -222,9 +205,6 @@
|
|||
else
|
||||
icon = "<%=resource%>/icons/signal-75-100.png";
|
||||
|
||||
if (!devup[wifidevs[iw.id]])
|
||||
devup[wifidevs[iw.id]] = is_assoc;
|
||||
|
||||
var sig = document.getElementById(iw.id + '-iw-signal');
|
||||
if (sig)
|
||||
sig.innerHTML = String.format(
|
||||
|
@ -254,7 +234,7 @@
|
|||
var info = document.getElementById(iw.id + '-iw-status');
|
||||
if (info)
|
||||
{
|
||||
if (is_assoc)
|
||||
if (iw.is_assoc)
|
||||
info.innerHTML = String.format(
|
||||
'<strong><%:SSID%>:</strong> %h | ' +
|
||||
'<strong><%:Mode%>:</strong> %s<br />' +
|
||||
|
@ -274,83 +254,23 @@
|
|||
: '<em><%:Wireless is disabled or not associated%></em>'
|
||||
);
|
||||
}
|
||||
|
||||
var dev = document.getElementById(wifidevs[iw.id] + '-iw-devinfo');
|
||||
if (dev)
|
||||
{
|
||||
if (is_assoc)
|
||||
dev.innerHTML = String.format(
|
||||
'<strong><%:Channel%>:</strong> %s (%s <%:GHz%>) | ' +
|
||||
'<strong><%:Bitrate%>:</strong> %s <%:Mbit/s%>',
|
||||
iw.channel ? iw.channel : '?',
|
||||
iw.frequency ? iw.frequency : '?',
|
||||
iw.bitrate ? iw.bitrate : '?'
|
||||
);
|
||||
else
|
||||
dev.innerHTML = '';
|
||||
}
|
||||
|
||||
if (assoctable)
|
||||
{
|
||||
var assoclist = [ ];
|
||||
for (var bssid in iw.assoclist)
|
||||
{
|
||||
assoclist.push(iw.assoclist[bssid]);
|
||||
assoclist[assoclist.length-1].bssid = bssid;
|
||||
}
|
||||
|
||||
assoclist.sort(function(a, b) { a.bssid < b.bssid });
|
||||
|
||||
for (var j = 0; j < assoclist.length; j++)
|
||||
{
|
||||
var icon;
|
||||
var q = (-1 * (assoclist[j].noise - assoclist[j].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";
|
||||
|
||||
var host = hosts[assoclist[j].bssid],
|
||||
name = host ? (host.name || host.ipv4 || host.ipv6) : null,
|
||||
hint = (host && host.name && (host.ipv4 || host.ipv6)) ? (host.ipv4 || host.ipv6) : null;
|
||||
|
||||
assoctable.appendChild(E('<div class="tr cbi-rowstyle-%d">'.format(rowstyle), [
|
||||
E('<div class="td"><span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span></div>'
|
||||
.format(iw.device.name, iw.ifname)),
|
||||
E('<div class="td" style="white-space:nowrap">%h</div>'
|
||||
.format(iw.ssid || '?')),
|
||||
E('<div class="td">%h</div>'
|
||||
.format(assoclist[j].bssid)),
|
||||
E('<div class="td">', hint ? '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis">%h (%h)</div>'
|
||||
.format(name || '?', hint) : (name || '?')),
|
||||
E('<div class="td"><span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span></div>'
|
||||
.format(assoclist[j].signal, assoclist[j].noise, assoclist[j].signal - assoclist[j].noise, icon, assoclist[j].signal, assoclist[j].noise)),
|
||||
E('<div class="td">', [
|
||||
E('<span style="white-space:nowrap">', wifirate(assoclist[j], true)),
|
||||
E('<br />'),
|
||||
E('<span style="white-space:nowrap">', wifirate(assoclist[j], false))
|
||||
])
|
||||
]));
|
||||
|
||||
rowstyle = (rowstyle == 1) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (assoctable && assoctable.firstElementChild === assoctable.lastElementChild)
|
||||
assoctable.appendChild(E('<div class="tr cbi-section-table-row"><div class="td"><em><br /><%:No information available%></em></div></div>'));
|
||||
|
||||
for (var dev in devup)
|
||||
for (var dev in radiostate)
|
||||
{
|
||||
var img = document.getElementById(dev + '-iw-upstate');
|
||||
if (img)
|
||||
img.src = '<%=resource%>/icons/wifi' + (devup[dev] ? '' : '_disabled') + '.png';
|
||||
img.src = '<%=resource%>/icons/wifi' + (radiostate[dev].up ? '' : '_disabled') + '.png';
|
||||
|
||||
var stat = document.getElementById(dev + '-iw-devinfo');
|
||||
if (stat)
|
||||
stat.innerHTML = String.format(
|
||||
'<strong><%:Channel%>:</strong> %s (%s <%:GHz%>) | ' +
|
||||
'<strong><%:Bitrate%>:</strong> %s <%:Mbit/s%>',
|
||||
radiostate[dev].channel ? radiostate[dev].channel : '?',
|
||||
radiostate[dev].frequency ? radiostate[dev].frequency : '?',
|
||||
radiostate[dev].bitrate ? radiostate[dev].bitrate : '?'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,23 +348,7 @@
|
|||
|
||||
<h2><%:Associated Stations%></h2>
|
||||
|
||||
<div class="cbi-section-node">
|
||||
<div class="table" id="iw-assoclist">
|
||||
<div class="tr">
|
||||
<div class="th"><%:Interface%></div>
|
||||
<div class="th"><%:SSID%></div>
|
||||
<div class="th"><%:MAC-Address%></div>
|
||||
<div class="th"><%:Host%></div>
|
||||
<div class="th"><%:Signal%> / <%:Noise%></div>
|
||||
<div class="th"><%:RX Rate%> / <%:TX Rate%></div>
|
||||
</div>
|
||||
<div class="tr cbi-rowstyle-2">
|
||||
<div class="td">
|
||||
<em><%:Collecting data...%></em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%+admin_network/wifi_assoclist%>
|
||||
</div>
|
||||
|
||||
<%+footer%>
|
||||
|
|
|
@ -140,24 +140,6 @@
|
|||
);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function duid2mac(duid) {
|
||||
// DUID-LLT / Ethernet
|
||||
if (duid.length === 28 && duid.substr(0, 8) === '00010001')
|
||||
|
@ -402,8 +384,6 @@
|
|||
<% end %>
|
||||
|
||||
<% if has_wifi then %>
|
||||
var assoclist = [ ];
|
||||
|
||||
var ws = document.getElementById('wifi_status_table');
|
||||
if (ws)
|
||||
{
|
||||
|
@ -420,21 +400,6 @@
|
|||
{
|
||||
var net = dev.networks[nidx];
|
||||
var is_assoc = (net.bssid != '00:00:00:00:00:00' && net.channel && !net.disabled);
|
||||
var num_assoc = 0;
|
||||
|
||||
for (var bssid in net.assoclist)
|
||||
{
|
||||
var bss = net.assoclist[bssid];
|
||||
|
||||
bss.bssid = bssid;
|
||||
bss.link = net.link;
|
||||
bss.name = net.name;
|
||||
bss.ifname = net.ifname;
|
||||
bss.radio = dev.name;
|
||||
|
||||
assoclist.push(bss);
|
||||
num_assoc++;
|
||||
}
|
||||
|
||||
var icon;
|
||||
if (!is_assoc)
|
||||
|
@ -457,7 +422,7 @@
|
|||
'<%:Mode%>', net.mode,
|
||||
'<%:BSSID%>', is_assoc ? (net.bssid || '-') : null,
|
||||
'<%:Encryption%>', is_assoc ? net.encryption : null,
|
||||
'<%:Associations%>', is_assoc ? (num_assoc || '-') : null,
|
||||
'<%:Associations%>', is_assoc ? (net.num_assoc || '-') : null,
|
||||
null, is_assoc ? null : E('em', '<%:Wireless is disabled or not associated%>')));
|
||||
}
|
||||
|
||||
|
@ -472,63 +437,6 @@
|
|||
if (!ws.lastElementChild)
|
||||
ws.appendChild(E('<em><%:No information available%></em>'));
|
||||
}
|
||||
|
||||
var ac = document.getElementById('wifi_assoc_table');
|
||||
if (ac)
|
||||
{
|
||||
var rows = [];
|
||||
|
||||
assoclist.sort(function(a, b) {
|
||||
return (a.name == b.name)
|
||||
? (a.bssid < b.bssid)
|
||||
: (a.name > b.name )
|
||||
;
|
||||
});
|
||||
|
||||
for (var i = 0; i < assoclist.length; i++)
|
||||
{
|
||||
var icon;
|
||||
var q = (-1 * (assoclist[i].noise - assoclist[i].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";
|
||||
|
||||
var host = hosts[assoclist[i].bssid],
|
||||
name = host ? (host.name || host.ipv4 || host.ipv6) : null,
|
||||
hint = (host && host.name && (host.ipv4 || host.ipv6)) ? (host.ipv4 || host.ipv6) : null;
|
||||
|
||||
rows.push([
|
||||
'<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> <a href="%s">%h</a><small> (%h)</small></span>'.format(
|
||||
assoclist[i].radio,
|
||||
assoclist[i].link,
|
||||
assoclist[i].name,
|
||||
assoclist[i].ifname),
|
||||
assoclist[i].bssid,
|
||||
hint ? '%h (%h)'.format(name || '?', hint) : (name || '?'),
|
||||
'<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>'.format(
|
||||
assoclist[i].signal,
|
||||
assoclist[i].noise,
|
||||
assoclist[i].signal - assoclist[i].noise,
|
||||
icon,
|
||||
assoclist[i].signal,
|
||||
assoclist[i].noise),
|
||||
E('span', {}, [
|
||||
E('span', wifirate(assoclist[i], true)),
|
||||
E('br'),
|
||||
E('span', wifirate(assoclist[i], false))
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
cbi_update_table(ac, rows, '<em><%:No information available%></em>');
|
||||
}
|
||||
<% end %>
|
||||
|
||||
var e;
|
||||
|
@ -709,20 +617,7 @@
|
|||
<div class="cbi-section">
|
||||
<h3><%:Associated Stations%></h3>
|
||||
|
||||
<div class="cbi-section-node">
|
||||
<div class="table" id="wifi_assoc_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">
|
||||
<div class="td" colspan="6"><em><br /><%:Collecting data...%></em></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%+admin_network/wifi_assoclist%>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
|
Loading…
Reference in a new issue