2009-09-26 11:10:01 +00:00
< %#
LuCI - Lua Configuration Interface
Copyright 2008-2009 Steven Barth < steven @ midlink . org >
2013-01-04 16:25:13 +00:00
Copyright 2008-2013 Jo-Philipp Wich < xm @ subsignal . org >
2009-09-26 11:10:01 +00:00
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
-%>
< %-
local sys = require "luci.sys"
2011-02-26 22:30:58 +00:00
local fs = require "luci.fs"
2009-09-26 11:10:01 +00:00
local utl = require "luci.util"
2009-10-29 02:22:00 +00:00
local uci = require "luci.model.uci".cursor()
2010-10-30 00:44:34 +00:00
local ntm = require "luci.model.network"
2009-10-29 02:22:00 +00:00
2010-12-02 12:21:18 +00:00
local has_iwinfo = pcall(require, "iwinfo")
2010-10-30 00:44:34 +00:00
ntm.init(uci)
2009-09-26 11:10:01 +00:00
2013-01-04 16:25:13 +00:00
function guess_wifi_hw(dev)
2010-12-02 12:21:18 +00:00
local bands = ""
2013-01-04 16:25:13 +00:00
local ifname = dev:name()
2009-09-26 11:10:01 +00:00
local name, idx = ifname:match("^([a-z]+)(%d+)")
idx = tonumber(idx)
2010-12-02 12:21:18 +00:00
if has_iwinfo then
2013-01-04 16:25:13 +00:00
local bl = dev.iwinfo.hwmodelist
2010-12-02 12:21:18 +00:00
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
2014-10-04 09:38:10 +00:00
if bl.ac then bands = bands .. "ac" end
2010-12-02 12:21:18 +00:00
end
2013-01-04 16:25:13 +00:00
local hw = dev.iwinfo.hardware_name
if hw then
return "%s 802.11%s" %{ hw, bands }
end
2010-12-02 12:21:18 +00:00
end
2009-09-26 11:10:01 +00:00
-- wl.o
if name == "wl" then
2012-08-14 13:08:18 +00:00
local name = translatef("Broadcom 802.11%s Wireless Controller", bands)
2009-09-26 11:10:01 +00:00
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]+)")
2012-08-14 13:08:18 +00:00
name = translatef(
2009-09-26 11:10:01 +00:00
"Broadcom BCM%04x 802.11 Wireless Controller",
tonumber(version, 16)
)
break
else
nm = nm + 1
end
end
end
fd:close()
end
return name
-- madwifi
elseif name == "ath" or name == "wifi" then
2012-08-14 13:08:18 +00:00
return translatef("Atheros 802.11%s Wireless Controller", bands)
2009-09-26 11:10:01 +00:00
-- ralink
elseif name == "ra" then
2012-08-14 13:08:18 +00:00
return translatef("RaLink 802.11%s Wireless Controller", bands)
2009-09-26 11:10:01 +00:00
2011-02-26 22:30:58 +00:00
-- hermes
2009-09-26 11:10:01 +00:00
elseif name == "eth" then
2012-08-14 13:08:18 +00:00
return translate("Hermes 802.11b Wireless Controller")
2009-09-26 11:10:01 +00:00
2011-02-26 22:30:58 +00:00
-- hostap
elseif name == "wlan" and fs.isdirectory("/proc/net/hostap/" .. ifname) then
2012-08-14 13:08:18 +00:00
return translate("Prism2/2.5/3 802.11b Wireless Controller")
2011-02-26 22:30:58 +00:00
2009-09-26 11:10:01 +00:00
-- dunno yet
else
2012-08-14 13:08:18 +00:00
return translatef("Generic 802.11%s Wireless Controller", bands)
2009-09-26 11:10:01 +00:00
end
end
2010-10-30 00:44:34 +00:00
local devices = ntm:get_wifidevs()
2009-09-26 11:10:01 +00:00
local arpcache = { }
2010-11-08 21:51:24 +00:00
sys.net.arptable(function(e) arpcache[e["HW address"]:upper()] = e["IP address"] end)
local netlist = { }
local netdevs = { }
local dev
for _, dev in ipairs(devices) do
local net
for _, net in ipairs(dev:get_wifinets()) do
2011-03-13 17:25:54 +00:00
netlist[#netlist+1] = net:id()
netdevs[net:id()] = dev:name()
2010-11-08 21:51:24 +00:00
end
end
2009-09-26 11:10:01 +00:00
-%>
< %+header%>
2010-11-27 18:24:38 +00:00
< % if not has_iwinfo then %>
< div class = "errorbox" >
< strong > < %:Package libiwinfo required!%>< / strong > < br / >
2011-12-06 11:00:33 +00:00
< %_The < em > libiwinfo-lua< / em > package is not installed. You must install this component for working wireless configuration!%>
2010-11-27 18:24:38 +00:00
< / div >
< % end %>
2010-11-08 21:51:24 +00:00
< script type = "text/javascript" src = "<%=resource%>/cbi.js" > < / script >
2010-11-18 01:34:56 +00:00
< script type = "text/javascript" > / / < ! [ C D A T A [
2010-11-08 21:51:24 +00:00
var wifidevs = < %=luci.http.write_json(netdevs)%>;
var arptable = < %=luci.http.write_json(arpcache)%>;
2011-09-22 02:43:38 +00:00
var is_reconnecting = false;
2012-11-21 17:04:12 +00:00
function nowrap(s) {
return s.replace(/ /g, '  ');
}
2011-09-22 02:43:38 +00:00
function wifi_shutdown(id, toggle) {
var reconnect = (toggle.getAttribute('active') == 'false');
2014-08-05 10:21:03 +00:00
if (!reconnect & & !confirm(String.format('< %:Really shut down network?\nYou might lose access to this device if you are connected via this interface.%>')))
2011-09-22 02:43:38 +00:00
return;
is_reconnecting = true;
var s = document.getElementById('iw-rc-status');
if (s)
{
s.parentNode.style.display = 'block';
2012-07-01 20:05:05 +00:00
s.innerHTML = '< %:Waiting for changes to be applied...%>';
2011-09-22 02:43:38 +00:00
}
for (var net in wifidevs)
{
var st = document.getElementById(net + '-iw-status');
if (st)
st.innerHTML = '< em > < %:Wireless is restarting...%>< / em > ';
}
2011-09-26 00:24:34 +00:00
XHR.get('< %=luci.dispatcher.build_url("admin", "network")%>/wireless_' + (reconnect ? 'reconnect' : 'shutdown') + '/' + id, null,
2011-09-22 02:43:38 +00:00
function(x)
{
if (s)
{
s.innerHTML = reconnect
? '< %:Wireless restarted%>'
: '< %:Wireless shut down%>';
window.setTimeout(function() {
s.parentNode.style.display = 'none';
is_reconnecting = false;
}, 1000);
}
}
);
}
2011-09-26 00:24:34 +00:00
XHR.poll(5, '< %=luci.dispatcher.build_url("admin", "network", "wireless_status", table.concat(netlist, ","))%>', null,
function(x, st)
{
if (st)
2010-11-08 21:51:24 +00:00
{
2011-09-26 00:24:34 +00:00
var assoctable = document.getElementById('iw-assoclist');
if (assoctable)
while (assoctable.rows.length > 1)
assoctable.rows[1].parentNode.removeChild(assoctable.rows[1]);
2010-11-08 21:51:24 +00:00
2011-09-26 00:24:34 +00:00
var devup = { };
var rowstyle = 1;
2010-11-08 22:40:04 +00:00
2011-09-26 00:24:34 +00:00
for( var i = 0; i < st.length ; i + + )
{
var iw = st[i];
2014-10-03 13:34:56 +00:00
var is_assoc = (iw.bssid & & iw.bssid != '00:00:00:00:00:00' & & iw.channel & & iw.mode != 'Unknown');
2011-09-26 00:24:34 +00:00
var p = iw.quality;
var q = is_assoc ? p : -1;
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";
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(
2012-08-14 13:08:18 +00:00
'< img src = "%s" title = "<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%>" / > < br / > ' +
2011-09-26 00:24:34 +00:00
'< small > %d%%< / small > ', icon, iw.signal, iw.noise, p
);
var toggle = document.getElementById(iw.id + '-iw-toggle');
if (toggle)
2010-11-08 21:51:24 +00:00
{
2014-10-03 17:28:23 +00:00
if (!iw.disabled)
2011-09-26 00:24:34 +00:00
{
2012-02-23 17:15:50 +00:00
toggle.className = 'cbi-button cbi-button-reset';
2011-09-26 00:24:34 +00:00
toggle.value = '< %:Disable%>';
toggle.title = '< %:Shutdown this network%>';
}
2010-11-08 21:51:24 +00:00
else
2011-09-26 00:24:34 +00:00
{
2012-02-23 17:15:50 +00:00
toggle.className = 'cbi-button cbi-button-reload';
2011-09-26 00:24:34 +00:00
toggle.value = '< %:Enable%>';
toggle.title = '< %:Activate this network%>';
}
2010-11-08 21:51:24 +00:00
2011-09-26 00:24:34 +00:00
toggle.setAttribute('active', is_assoc);
}
2010-11-08 22:40:04 +00:00
2011-09-26 00:24:34 +00:00
var info = document.getElementById(iw.id + '-iw-status');
if (info)
{
if (is_assoc)
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%>'
2010-11-08 21:51:24 +00:00
);
2011-09-26 00:24:34 +00:00
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 > '
);
}
2010-11-08 21:51:24 +00:00
2011-09-26 00:24:34 +00:00
var dev = document.getElementById(wifidevs[iw.id] + '-iw-devinfo');
if (dev)
{
if (is_assoc)
dev.innerHTML = String.format(
2012-08-14 13:08:18 +00:00
'< strong > < %:Channel%>:< / strong > %s (%s < %:GHz%>) | ' +
'< strong > < %:Bitrate%>:< / strong > %s < %:Mbit/s%>',
2011-09-26 00:24:34 +00:00
iw.channel ? iw.channel : '?',
iw.frequency ? iw.frequency : '?',
iw.bitrate ? iw.bitrate : '?'
);
else
dev.innerHTML = '';
}
2011-09-22 02:43:38 +00:00
2011-09-26 00:24:34 +00:00
if (assoctable)
{
var assoclist = [ ];
for( var bssid in iw.assoclist )
2010-11-08 22:40:04 +00:00
{
2011-09-26 00:24:34 +00:00
assoclist.push(iw.assoclist[bssid]);
assoclist[assoclist.length-1].bssid = bssid;
2010-11-08 22:40:04 +00:00
}
2010-11-08 21:51:24 +00:00
2011-09-26 00:24:34 +00:00
assoclist.sort(function(a, b) { a.bssid < b.bssid } ) ;
for( var j = 0; j < assoclist.length ; j + + )
2010-11-08 22:40:04 +00:00
{
2011-09-26 00:24:34 +00:00
var tr = assoctable.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + rowstyle;
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";
2010-11-08 22:40:04 +00:00
else
2011-09-26 00:24:34 +00:00
icon = "< %=resource%>/icons/signal-75-100.png";
2010-11-08 21:51:24 +00:00
2011-09-26 00:24:34 +00:00
tr.insertCell(-1).innerHTML = String.format(
2012-08-14 13:08:18 +00:00
'< img src = "%s" title = "<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%>" / > ',
2011-09-26 00:24:34 +00:00
icon, assoclist[j].signal, assoclist[j].noise
);
2010-11-08 21:51:24 +00:00
2012-11-21 17:04:12 +00:00
tr.insertCell(-1).innerHTML = nowrap(String.format('%h', iw.ssid ? iw.ssid : '?'));
2011-09-26 00:24:34 +00:00
tr.insertCell(-1).innerHTML = assoclist[j].bssid;
2010-11-08 21:51:24 +00:00
2011-09-26 00:24:34 +00:00
tr.insertCell(-1).innerHTML = arptable[assoclist[j].bssid]
? arptable[assoclist[j].bssid] : '?';
2010-11-08 22:40:04 +00:00
2012-11-21 17:04:12 +00:00
tr.insertCell(-1).innerHTML = nowrap(String.format('%d < %:dBm%>', assoclist[j].signal));
tr.insertCell(-1).innerHTML = nowrap(String.format('%d < %:dBm%>', assoclist[j].noise));
2011-09-26 00:24:34 +00:00
2012-11-21 17:04:12 +00:00
tr.insertCell(-1).innerHTML = nowrap((assoclist[j].rx_mcs > -1)
2012-08-14 13:08:18 +00:00
? String.format('%.1f < %:Mbit/s%>, MCS %d, %d< %:MHz%>', assoclist[j].rx_rate / 1000, assoclist[j].rx_mcs, assoclist[j].rx_40mhz ? 40 : 20)
: String.format('%.1f < %:Mbit/s%>', assoclist[j].rx_rate / 1000)
2012-11-21 17:04:12 +00:00
);
2012-02-23 17:15:50 +00:00
2012-11-21 17:04:12 +00:00
tr.insertCell(-1).innerHTML = nowrap((assoclist[j].tx_mcs > -1)
2012-08-14 13:08:18 +00:00
? String.format('%.1f < %:Mbit/s%>, MCS %d, %d< %:MHz%>', assoclist[j].tx_rate / 1000, assoclist[j].tx_mcs, assoclist[j].tx_40mhz ? 40 : 20)
: String.format('%.1f < %:Mbit/s%>', assoclist[j].tx_rate / 1000)
2012-11-21 17:04:12 +00:00
);
2012-02-23 17:15:50 +00:00
2011-09-26 00:24:34 +00:00
rowstyle = (rowstyle == 1) ? 2 : 1;
}
2010-11-08 22:40:04 +00:00
}
2010-11-08 21:51:24 +00:00
}
2010-11-17 15:23:21 +00:00
2011-09-26 00:24:34 +00:00
if (assoctable & & assoctable.rows.length == 1)
{
var tr = assoctable.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
2012-02-23 17:15:50 +00:00
td.colSpan = 8;
2011-09-26 00:24:34 +00:00
td.innerHTML = '< br / > < em > < %:No information available%>< / em > ';
}
for (var dev in devup)
{
var img = document.getElementById(dev + '-iw-upstate');
if (img)
img.src = '< %=resource%>/icons/wifi_big' + (devup[dev] ? '' : '_disabled') + '.png';
}
2010-11-08 21:51:24 +00:00
}
2011-09-26 00:24:34 +00:00
}
);
2010-11-18 01:34:56 +00:00
//]]>< / script >
2010-11-08 21:51:24 +00:00
2009-10-31 15:54:11 +00:00
< h2 > < a id = "content" name = "content" > < %:Wireless Overview%>< / a > < / h2 >
2009-09-26 11:10:01 +00:00
2011-09-22 02:43:38 +00:00
< fieldset class = "cbi-section" style = "display:none" >
< legend > < %:Reconnecting interface%>< / legend >
< img src = "<%=resource%>/icons/loading.gif" alt = "<%:Loading%>" style = "vertical-align:middle" / >
2012-07-01 20:05:05 +00:00
< span id = "iw-rc-status" > < %:Waiting for changes to be applied...%>< / span >
2011-09-22 02:43:38 +00:00
< / fieldset >
2009-09-26 11:10:01 +00:00
< div class = "cbi-map" >
2010-10-30 00:44:34 +00:00
< % for _, dev in ipairs(devices) do local nets = dev:get_wifinets() %>
2009-10-29 02:22:00 +00:00
<!-- device <%=dev:name()%> -->
2009-09-26 11:10:01 +00:00
< fieldset class = "cbi-section" >
< table class = "cbi-section-table" style = "margin:10px; empty-cells:hide" >
<!-- physical device -->
< tr >
2010-11-18 03:41:13 +00:00
< td style = "width:34px" > < img src = "<%=resource%>/icons/wifi_big_disabled.png" style = "float:left; margin-right:10px" id = "<%=dev:name()%>-iw-upstate" / > < / td >
2009-09-26 11:10:01 +00:00
< td colspan = "2" style = "text-align:left" >
2013-01-04 16:25:13 +00:00
< big > < strong > < %=guess_wifi_hw(dev)%> (< %=dev:name()%>)< / strong > < / big > < br / >
2010-11-08 21:51:24 +00:00
< span id = "<%=dev:name()%>-iw-devinfo" > < / span >
2009-09-26 11:10:01 +00:00
< / td >
2011-10-02 11:37:44 +00:00
< td style = "width:310px;text-align:right" >
2012-02-23 17:15:50 +00:00
< input type = "button" class = "cbi-button cbi-button-find" style = "width:100px" onclick = "location.href='<%=luci.dispatcher.build_url(" admin / network / wireless_join " ) % > ?device=< %=dev:name()%>'" title="< %:Find and join network%>" value="< %:Scan%>" />
< input type = "button" class = "cbi-button cbi-button-add" style = "width:100px" onclick = "location.href='<%=luci.dispatcher.build_url(" admin / network / wireless_add " ) % > ?device=< %=dev:name()%>'" title="< %:Provide new network%>" value="< %:Add%>" />
2009-09-26 11:10:01 +00:00
< / td >
< / tr >
<!-- /physical device -->
<!-- network list -->
2009-10-29 02:22:00 +00:00
< % if #nets > 0 then %>
< % for i, net in ipairs(nets) do %>
2009-09-26 11:10:01 +00:00
< tr class = "cbi-section-table-row cbi-rowstyle-<%=1 + ((i-1) % 2)%>" >
< td > < / td >
2011-03-13 17:25:54 +00:00
< td class = "cbi-value-field" style = "width:16px; padding:3px" id = "<%=net:id()%>-iw-signal" >
2010-11-08 21:51:24 +00:00
< img src = "<%=resource%>/icons/signal-none.png" title = "<%:Not associated%>" / > < br / >
< small > 0%< / small >
2009-09-26 11:10:01 +00:00
< / td >
2011-03-13 17:25:54 +00:00
< td class = "cbi-value-field" style = "vertical-align:middle; text-align:left; padding:3px" id = "<%=net:id()%>-iw-status" >
2010-11-08 21:51:24 +00:00
< em > < %:Collecting data...%>< / em >
2009-09-26 11:10:01 +00:00
< / td >
2011-10-02 11:37:44 +00:00
< td class = "cbi-value-field" style = "width:310px;text-align:right" >
2012-02-23 17:15:50 +00:00
< input id = "<%=net:id()%>-iw-toggle" type = "button" class = "cbi-button cbi-button-reload" style = "width:100px" onclick = "wifi_shutdown('<%=net:id()%>', this)" title = "<%:Delete this network%>" value = "<%:Enable%>" / >
< input type = "button" class = "cbi-button cbi-button-edit" style = "width:100px" onclick = "location.href='<%=net:adminlink()%>'" title = "<%:Edit this network%>" value = "<%:Edit%>" / >
2012-07-01 20:05:05 +00:00
< input type = "button" class = "cbi-button cbi-button-remove" style = "width:100px" onclick = "if (confirm('<%:Really delete this wireless network? The deletion cannot be undone!\nYou might lose access to this device if you are connected via this network.%>')) location.href='<%=luci.dispatcher.build_url(" admin / network / wireless_delete " , net:ifname ( ) ) % > '" title="< %:Delete this network%>" value="< %:Remove%>" />
2009-09-26 11:10:01 +00:00
< / td >
< / tr >
< % end %>
< % else %>
< tr class = "cbi-section-table-row cbi-rowstyle-2" >
< td > < / td >
< td colspan = "3" class = "cbi-value-field" style = "vertical-align:middle; text-align:left; padding:3px" >
2010-11-09 19:33:09 +00:00
< em > < %:No network configured on this device%>< / em >
2009-09-26 11:10:01 +00:00
< / td >
< / tr >
< % end %>
<!-- /network list -->
< / table >
< / fieldset >
2009-10-29 02:22:00 +00:00
<!-- /device <%=dev:name()%> -->
2009-09-26 11:10:01 +00:00
< % end %>
2009-10-31 15:54:11 +00:00
< h2 > < a id = "content" name = "content" > < %:Associated Stations%>< / a > < / h2 >
2009-09-26 11:10:01 +00:00
< fieldset class = "cbi-section" >
2012-02-23 17:15:50 +00:00
< table class = "cbi-section-table" style = "margin:10px" id = "iw-assoclist" >
2009-09-26 11:10:01 +00:00
< tr class = "cbi-section-table-titles" >
< th class = "cbi-section-table-cell" > < / th >
2010-11-08 21:51:24 +00:00
< th class = "cbi-section-table-cell" > < %:SSID%>< / th >
2012-08-14 13:08:18 +00:00
< th class = "cbi-section-table-cell" > < %:MAC-Address%>< / th >
< th class = "cbi-section-table-cell" > < %:IPv4-Address%>< / th >
2010-11-08 21:51:24 +00:00
< th class = "cbi-section-table-cell" > < %:Signal%>< / th >
< th class = "cbi-section-table-cell" > < %:Noise%>< / th >
2012-02-23 17:15:50 +00:00
< th class = "cbi-section-table-cell" > < %:RX Rate%>< / th >
< th class = "cbi-section-table-cell" > < %:TX Rate%>< / th >
2009-09-26 11:10:01 +00:00
< / tr >
< tr class = "cbi-section-table-row cbi-rowstyle-2" >
2012-02-23 17:15:50 +00:00
< td class = "cbi-value-field" colspan = "8" >
2010-11-08 21:51:24 +00:00
< em > < %:Collecting data...%>< / em >
2009-09-26 11:10:01 +00:00
< / td >
< / tr >
< / table >
< / fieldset >
< / div >
< %+footer%>