2018-01-23 14:36:03 +00:00
< %#
Copyright 2008-2009 Steven Barth < steven @ midlink . org >
Copyright 2008-2015 Jo-Philipp Wich < jow @ openwrt . org >
Licensed to the public under the Apache License 2.0.
-%>
< %-
local ip = require "luci.ip"
local fs = require "nixio.fs"
local utl = require "luci.util"
local uci = require "luci.model.uci".cursor()
local ntm = require "luci.model.network"
local has_iwinfo = pcall(require, "iwinfo")
ntm.init(uci)
function guess_wifi_hw(dev)
local bands = ""
local ifname = dev:name()
local name, idx = ifname:match("^([a-z]+)(%d+)")
idx = tonumber(idx)
if has_iwinfo then
local bl = dev.iwinfo.hwmodelist
if bl and next(bl) then
if bl.a then bands = bands .. "a" end
if bl.b then bands = bands .. "b" end
if bl.g then bands = bands .. "g" end
if bl.n then bands = bands .. "n" end
if bl.ac then bands = bands .. "ac" end
end
local hw = dev.iwinfo.hardware_name
if hw then
return "%s 802.11%s" %{ hw, bands }
end
end
-- wl.o
if name == "wl" then
local name = translatef("Broadcom 802.11%s Wireless Controller", bands)
local nm = 0
local fd = nixio.open("/proc/bus/pci/devices", "r")
if fd then
local ln
for ln in fd:linesource() do
if ln:match("wl$") then
if nm == idx then
local version = ln:match("^%S+%s+%S%S%S%S([0-9a-f]+)")
name = translatef(
"Broadcom BCM%04x 802.11 Wireless Controller",
tonumber(version, 16)
)
break
else
nm = nm + 1
end
end
end
fd:close()
end
return name
-- ralink
elseif name == "ra" then
return translatef("RaLink 802.11%s Wireless Controller", bands)
-- hermes
elseif name == "eth" then
return translate("Hermes 802.11b Wireless Controller")
-- hostap
elseif name == "wlan" and fs.stat("/proc/net/hostap/" .. ifname, "type") == "dir" then
return translate("Prism2/2.5/3 802.11b Wireless Controller")
-- dunno yet
else
return translatef("Generic 802.11%s Wireless Controller", bands)
end
end
local devices = ntm:get_wifidevs()
local netlist = { }
local netdevs = { }
local dev
for _, dev in ipairs(devices) do
local net
for _, net in ipairs(dev:get_wifinets()) do
netlist[#netlist+1] = net:id()
netdevs[net:id()] = dev:name()
end
end
-%>
< %+header%>
< % if not has_iwinfo then %>
2018-06-04 20:13:57 +00:00
< div class = "alert-message warning" >
< h4 > < %:Package libiwinfo required!%>< / h4 >
< p > < %_The < em > libiwinfo-lua< / em > package is not installed. You must install this component for working wireless configuration!%>< / p >
2018-01-23 14:36:03 +00:00
< / div >
< % end %>
< script type = "text/javascript" src = "<%=resource%>/cbi.js" > < / script >
< script type = "text/javascript" > / / < ! [ C D A T A [
var wifidevs = < %=luci.http.write_json(netdevs)%>;
var is_reconnecting = false;
function wifi_shutdown(id, toggle) {
var reconnect = (toggle.getAttribute('active') == 'false');
2018-07-03 14:03:20 +00:00
if (!reconnect & & !confirm(< %=luci.http.write_json(translate('Really shut down network? You might lose access to this device if you are connected via this interface'))%>))
2018-01-23 14:36:03 +00:00
return;
is_reconnecting = true;
var s = document.getElementById('iw-rc-status');
if (s)
{
s.parentNode.style.display = 'block';
s.innerHTML = '< %:Waiting for changes to be applied...%>';
}
for (var net in wifidevs)
{
var st = document.getElementById(net + '-iw-status');
if (st)
st.innerHTML = '< em > < %:Wireless is restarting...%>< / em > ';
}
(new XHR()).post('< %=url('admin/network')%>/wireless_' + (reconnect ? 'reconnect' : 'shutdown') + '/' + id, { token: '< %=token%>' },
function(x)
{
if (s)
{
s.innerHTML = reconnect
? '< %:Wireless restarted%>'
: '< %:Wireless shut down%>';
window.setTimeout(function() {
s.parentNode.style.display = 'none';
is_reconnecting = false;
}, 1000);
}
}
);
}
function wifi_delete(id) {
2018-07-03 14:03:20 +00:00
if (!confirm(< %=luci.http.write_json(translate('Really delete this wireless network? The deletion cannot be undone! You might lose access to this device if you are connected via this network.'))%>))
2018-01-23 14:36:03 +00:00
return;
(new XHR()).post('< %=url('admin/network/wireless_delete')%>/' + id, { token: '< %=token%>' },
function(x) {
location.href = '< %=url('admin/network/wireless')%>';
}
);
}
var hosts = < %=luci.http.write_json(luci.sys.net.host_hints())%>;
XHR.poll(5, '< %=url('admin/network/wireless_status', table.concat(netlist, ","))%>', null,
function(x, st)
{
if (st)
{
var rowstyle = 1;
2018-07-03 14:03:20 +00:00
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;
});
2018-01-23 14:36:03 +00:00
for( var i = 0; i < st.length ; i + + )
{
var iw = st[i];
var p = iw.quality;
2018-07-03 14:03:20 +00:00
var q = iw.is_assoc ? p : -1;
2018-01-23 14:36:03 +00:00
var icon;
if (q < 0 )
icon = "< %=resource%>/icons/signal-none.png";
else if (q == 0)
icon = "< %=resource%>/icons/signal-0.png";
else if (q < 25 )
icon = "< %=resource%>/icons/signal-0-25.png";
else if (q < 50 )
icon = "< %=resource%>/icons/signal-25-50.png";
else if (q < 75 )
icon = "< %=resource%>/icons/signal-50-75.png";
else
icon = "< %=resource%>/icons/signal-75-100.png";
var sig = document.getElementById(iw.id + '-iw-signal');
if (sig)
sig.innerHTML = String.format(
'< span class = "ifacebadge" title = "<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%>" > < img src = "%s" / > %d%%< / span > ',
iw.signal, iw.noise, icon, p
);
var toggle = document.getElementById(iw.id + '-iw-toggle');
if (toggle)
{
if (!iw.disabled)
{
2018-07-03 14:03:20 +00:00
toggle.className = 'cbi-button cbi-button-neutral';
2018-01-23 14:36:03 +00:00
toggle.value = '< %:Disable%>';
toggle.title = '< %:Shutdown this network%>';
}
else
{
2018-07-03 14:03:20 +00:00
toggle.className = 'cbi-button cbi-button-neutral';
2018-01-23 14:36:03 +00:00
toggle.value = '< %:Enable%>';
toggle.title = '< %:Activate this network%>';
}
toggle.setAttribute('active', !iw.disabled);
}
var info = document.getElementById(iw.id + '-iw-status');
if (info)
{
2018-07-03 14:03:20 +00:00
if (iw.is_assoc)
2018-01-23 14:36:03 +00:00
info.innerHTML = String.format(
'< strong > < %:SSID%>:< / strong > %h | ' +
'< strong > < %:Mode%>:< / strong > %s< br / > ' +
'< strong > < %:BSSID%>:< / strong > %s | ' +
'< strong > < %:Encryption%>:< / strong > %s',
iw.ssid, iw.mode, iw.bssid,
iw.encryption ? iw.encryption : '< %:None%>'
);
else
info.innerHTML = String.format(
'< strong > < %:SSID%>:< / strong > %h | ' +
'< strong > < %:Mode%>:< / strong > %s< br / > ' +
'< em > %s< / em > ',
iw.ssid || '?', iw.mode,
is_reconnecting
? '< em > < %:Wireless is restarting...%>< / em > '
: '< em > < %:Wireless is disabled or not associated%>< / em > '
);
}
}
2018-07-03 14:03:20 +00:00
for (var dev in radiostate)
2018-01-23 14:36:03 +00:00
{
var img = document.getElementById(dev + '-iw-upstate');
if (img)
2018-07-03 14:03:20 +00:00
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 : '?'
);
2018-01-23 14:36:03 +00:00
}
}
}
);
//]]>< / script >
< h2 name = "content" > < %:Wireless Overview%>< / h2 >
2018-07-03 14:03:20 +00:00
< div class = "cbi-section" style = "display:none" >
2018-01-23 14:36:03 +00:00
< legend > < %:Reconnecting interface%>< / legend >
< img src = "<%=resource%>/icons/loading.gif" alt = "<%:Loading%>" style = "vertical-align:middle" / >
< span id = "iw-rc-status" > < %:Waiting for changes to be applied...%>< / span >
2018-07-03 14:03:20 +00:00
< / div >
2018-01-23 14:36:03 +00:00
2018-07-03 14:03:20 +00:00
< div id = "cbi-wireless-overview" class = "cbi-map" >
2018-01-23 14:36:03 +00:00
< % for _, dev in ipairs(devices) do local nets = dev:get_wifinets() %>
<!-- device <%=dev:name()%> -->
2018-07-03 14:03:20 +00:00
< div class = "cbi-section-node" >
< div class = "table" >
2018-01-23 14:36:03 +00:00
<!-- physical device -->
2018-05-31 13:44:12 +00:00
< div class = "tr" >
2018-07-03 14:03:20 +00:00
< div class = "td col-2 center" >
< span class = "ifacebadge" > < img src = "<%=resource%>/icons/wifi_disabled.png" id = "<%=dev:name()%>-iw-upstate" / > < %=dev:name()%>< / span >
2018-05-31 13:44:12 +00:00
< / div >
2018-07-03 14:03:20 +00:00
< div class = "td col-7 left" >
< big > < strong > < %=guess_wifi_hw(dev)%>< / strong > < / big > < br / >
2018-01-23 14:36:03 +00:00
< span id = "<%=dev:name()%>-iw-devinfo" > < / span >
2018-05-31 13:44:12 +00:00
< / div >
2018-07-03 14:03:20 +00:00
< div class = "td cbi-section-actions" >
2018-01-23 14:36:03 +00:00
< form action = "<%=url('admin/network/wireless_join')%>" method = "post" class = "inline" >
< input type = "hidden" name = "device" value = "<%=dev:name()%>" / >
< input type = "hidden" name = "token" value = "<%=token%>" / >
2018-07-03 14:03:20 +00:00
< input type = "submit" class = "cbi-button cbi-button-action" title = "<%:Find and join network%>" value = "<%:Scan%>" / >
2018-01-23 14:36:03 +00:00
< / form >
< form action = "<%=url('admin/network/wireless_add')%>" method = "post" class = "inline" >
< input type = "hidden" name = "device" value = "<%=dev:name()%>" / >
< input type = "hidden" name = "token" value = "<%=token%>" / >
2018-07-03 14:03:20 +00:00
< input type = "submit" class = "cbi-button cbi-button-add" title = "<%:Provide new network%>" value = "<%:Add%>" / >
2018-01-23 14:36:03 +00:00
< / form >
2018-05-31 13:44:12 +00:00
< / div >
< / div >
2018-01-23 14:36:03 +00:00
<!-- /physical device -->
<!-- network list -->
< % if #nets > 0 then %>
< % for i, net in ipairs(nets) do %>
2018-07-03 14:03:20 +00:00
< div class = "tr cbi-rowstyle-<%=1 + ((i-1) % 2)%>" >
< div class = "td col-2 center" id = "<%=net:id()%>-iw-signal" >
2018-01-23 14:36:03 +00:00
< span class = "ifacebadge" title = "<%:Not associated%>" > < img src = "<%=resource%>/icons/signal-none.png" / > 0%< / span >
2018-05-31 13:44:12 +00:00
< / div >
2018-07-03 14:03:20 +00:00
< div class = "td col-7 left" id = "<%=net:id()%>-iw-status" >
2018-01-23 14:36:03 +00:00
< em > < %:Collecting data...%>< / em >
2018-05-31 13:44:12 +00:00
< / div >
2018-07-03 14:03:20 +00:00
< div class = "td cbi-section-actions" >
< input id = "<%=net:id()%>-iw-toggle" type = "button" class = "cbi-button cbi-button-neutral" onclick = "wifi_shutdown('<%=net:id()%>', this)" title = "<%:Enable this network%>" value = "<%:Enable%>" / >
< input type = "button" class = "cbi-button cbi-button-action important" onclick = "location.href='<%=net:adminlink()%>'" title = "<%:Edit this network%>" value = "<%:Edit%>" / >
< input type = "button" class = "cbi-button cbi-button-negative" onclick = "wifi_delete('<%=net:id()%>')" title = "<%:Delete this network%>" value = "<%:Remove%>" / >
2018-05-31 13:44:12 +00:00
< / div >
< / div >
2018-01-23 14:36:03 +00:00
< % end %>
< % else %>
2018-07-03 14:03:20 +00:00
< div class = "tr cbi-rowstyle-2" >
2018-05-31 13:44:12 +00:00
< div class = "td left" >
2018-01-23 14:36:03 +00:00
< em > < %:No network configured on this device%>< / em >
2018-05-31 13:44:12 +00:00
< / div >
< / div >
2018-01-23 14:36:03 +00:00
< % end %>
<!-- /network list -->
2018-05-31 13:44:12 +00:00
< / div >
2018-07-03 14:03:20 +00:00
< / div >
2018-01-23 14:36:03 +00:00
<!-- /device <%=dev:name()%> -->
< % end %>
< h2 > < %:Associated Stations%>< / h2 >
2018-07-03 14:03:20 +00:00
< %+admin_network/wifi_assoclist%>
2018-01-23 14:36:03 +00:00
< / div >
< %+footer%>