summaryrefslogtreecommitdiffhomepage
path: root/modules/admin-full
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2009-09-26 11:10:01 +0000
committerJo-Philipp Wich <jow@openwrt.org>2009-09-26 11:10:01 +0000
commit4d3ddb03a308629abc4f9c37686c5d2351ce5950 (patch)
treed3af4c63fa8d96b07d8ff9f9e934ea79985f9db0 /modules/admin-full
parent7bd891326df0eb265a9f26fadf1c5a1764a8faa4 (diff)
modules/admin-full: initial work on site survey and network join
Diffstat (limited to 'modules/admin-full')
-rw-r--r--modules/admin-full/luasrc/controller/admin/network.lua92
-rw-r--r--modules/admin-full/luasrc/view/admin_network/wifi_join.htm129
-rw-r--r--modules/admin-full/luasrc/view/admin_network/wifi_join_settings.htm112
-rw-r--r--modules/admin-full/luasrc/view/admin_network/wifi_overview.htm250
4 files changed, 582 insertions, 1 deletions
diff --git a/modules/admin-full/luasrc/controller/admin/network.lua b/modules/admin-full/luasrc/controller/admin/network.lua
index 08a5dd0ef6..12dd559bc7 100644
--- a/modules/admin-full/luasrc/controller/admin/network.lua
+++ b/modules/admin-full/luasrc/controller/admin/network.lua
@@ -29,7 +29,7 @@ function index()
page.title = i18n("a_n_switch")
page.order = 20
- local page = entry({"admin", "network", "wireless"}, arcombine(cbi("admin_network/wireless"), cbi("admin_network/wifi")), i18n("wifi"), 15)
+ local page = entry({"admin", "network", "wireless"}, arcombine(template("admin_network/wifi_overview"), cbi("admin_network/wifi")), i18n("wifi"), 15)
page.i18n = "wifi"
page.leaf = true
page.subindex = true
@@ -43,6 +43,10 @@ function index()
end
)
+ local page = entry({"admin", "network", "wireless_join"}, call("wifi_join"), nil, 16)
+ page.i18n = "wifi"
+ page.leaf = true
+
local page = entry({"admin", "network", "network"}, arcombine(cbi("admin_network/network"), cbi("admin_network/ifaces")), i18n("interfaces", "Schnittstellen"), 10)
page.leaf = true
page.subindex = true
@@ -81,3 +85,89 @@ function index()
page.order = 50
end
+
+function wifi_join()
+ local function param(x)
+ return luci.http.formvalue(x)
+ end
+
+ local function ptable(x)
+ x = param(x)
+ return x and (type(x) ~= "table" and { x } or x) or {}
+ end
+
+ local dev = param("device")
+ local ssid = param("join")
+
+ if dev and ssid then
+ local wep = (tonumber(param("wep")) == 1)
+ local wpa = tonumber(param("wpa_version")) or 0
+ local channel = tonumber(param("channel"))
+ local mode = param("mode")
+ local bssid = param("bssid")
+
+ local confirm = (param("confirm") == "1")
+ local cancel = param("cancel") and true or false
+
+ if confirm and not cancel then
+ local fixed_bssid = (param("fixed_bssid") == "1")
+ local replace_net = (param("replace_net") == "1")
+ local autoconnect = (param("autoconnect") == "1")
+ local attach_intf = param("attach_intf")
+
+ local uci = require "luci.model.uci".cursor()
+
+ if replace_net then
+ uci:delete_all("wireless", "wifi-iface")
+ end
+
+ local wificonf = {
+ device = dev,
+ mode = (mode == "Ad-Hoc" and "adhoc" or "sta"),
+ ssid = ssid
+ }
+
+ if attach_intf and uci:get("network", attach_intf, "ifname") then
+ -- target network already has a interface, make it a bridge
+ uci:set("network", attach_intf, "type", "bridge")
+ uci:save("network")
+ uci:commit("network")
+
+ if autoconnect then
+ require "luci.sys".call("/sbin/ifup " .. attach_intf)
+ end
+ end
+
+ if fixed_bssid then
+ wificonf.bssid = bssid
+ end
+
+ if wep then
+ wificonf.encryption = "wep"
+ wificonf.key = param("key")
+ elseif wpa > 0 then
+ wificonf.encryption = param("wpa_suite")
+ wificonf.key = param("key")
+ end
+
+ uci:section("wireless", "wifi-iface", nil, wificonf)
+ uci:delete("wireless", dev, "disabled")
+ uci:set("wireless", dev, "channel", channel)
+
+ uci:save("wireless")
+ uci:commit("wireless")
+
+ if autoconnect then
+ require "luci.sys".call("/sbin/wifi")
+ end
+
+ luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", dev))
+ elseif cancel then
+ luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless_join?device=" .. dev))
+ else
+ luci.template.render("admin_network/wifi_join_settings")
+ end
+ else
+ luci.template.render("admin_network/wifi_join")
+ end
+end
diff --git a/modules/admin-full/luasrc/view/admin_network/wifi_join.htm b/modules/admin-full/luasrc/view/admin_network/wifi_join.htm
new file mode 100644
index 0000000000..3963a5ae28
--- /dev/null
+++ b/modules/admin-full/luasrc/view/admin_network/wifi_join.htm
@@ -0,0 +1,129 @@
+<%#
+LuCI - Lua Configuration Interface
+Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
+
+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
+
+$Id$
+
+-%>
+
+<%-
+
+ local sys = require "luci.sys"
+ local utl = require "luci.util"
+
+ function guess_wifi_signal(info)
+ local scale = (100 / (info.quality_max or 100) * (info.quality or 0))
+ local icon
+
+ if not info.bssid or info.bssid == "00:00:00:00:00:00" then
+ icon = resource .. "/icons/signal-none.png"
+ elseif scale < 15 then
+ icon = resource .. "/icons/signal-0.png"
+ elseif scale < 35 then
+ icon = resource .. "/icons/signal-0-25.png"
+ elseif scale < 55 then
+ icon = resource .. "/icons/signal-25-50.png"
+ elseif scale < 75 then
+ icon = resource .. "/icons/signal-50-75.png"
+ else
+ icon = resource .. "/icons/signal-75-100.png"
+ end
+
+ return icon
+ end
+
+ function percent_wifi_signal(info)
+ local qc = info.quality or 0
+ local qm = info.quality_max or 0
+
+ if info.bssid and qc > 0 and qm > 0 then
+ return math.floor((100 / qm) * qc)
+ else
+ return 0
+ end
+ end
+
+ function format_wifi_encryption(info)
+ if info.wep == true and not info.wpa_version then
+ return "WEP"
+ elseif info.wpa_version then
+ return "<abbr title='Pairwise: %s / Group: %s'>%s - %s</abbr>" % {
+ table.concat(info.pair_ciphers, ", "),
+ table.concat(info.group_ciphers, ", "),
+ (info.wpa_version == 3) and "mixed WPA/WPA2"
+ or (info.wpa_version == 2 and "WPA2" or "WPA"),
+ table.concat(info.auth_suites, ", ")
+ }
+ else
+ return "<em>None</em>"
+ end
+ end
+
+ local dev = luci.http.formvalue("device")
+ local iw = luci.sys.wifi.getiwinfo(dev)
+-%>
+
+<%+header%>
+
+<h2><a id="content" name="content"><%:a_s_iw_scan Wireless Scan%></a></h2>
+
+<div class="cbi-map">
+ <fieldset class="cbi-section">
+ <table class="cbi-section-table" style="empty-cells:hide">
+ <!-- scan list -->
+ <% for i, net in ipairs(iw.scanlist) do %>
+ <tr class="cbi-section-table-row cbi-rowstyle-<%=1 + ((i-1) % 2)%>">
+ <td class="cbi-value-field" style="width:16px; padding:3px">
+ <abbr title="Signal: <%=net.signal%> dB / Quality: <%=net.quality%>/<%=net.quality_max%>">
+ <img src="<%=guess_wifi_signal(net)%>" /><br />
+ <small><%=percent_wifi_signal(net)%>%</small>
+ </abbr>
+ </td>
+ <td class="cbi-value-field" style="vertical-align:middle; text-align:left; padding:3px">
+ <big><strong><%=net.ssid and utl.pcdata(net.ssid) or "<em>hidden</em>"%></strong></big><br />
+ <strong>Channel:</strong> <%=net.channel%> |
+ <strong>Mode:</strong> <%=net.mode%> |
+ <strong>BSSID:</strong> <%=net.bssid%> |
+ <strong>Encryption:</strong> <%=format_wifi_encryption(net)%>
+ </td>
+ <td class="cbi-value-field" style="width:40px">
+ <form action="<%=REQUEST_URI%>" method="post">
+ <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>" />
+ <input type="hidden" name="join" value="<%=utl.pcdata(net.ssid)%>" />
+ <input type="hidden" name="mode" value="<%=net.mode%>" />
+ <input type="hidden" name="bssid" value="<%=net.bssid%>" />
+ <input type="hidden" name="channel" value="<%=net.channel%>" />
+ <input type="hidden" name="wep" value="<%=net.wep and 1 or 0%>" />
+ <% if net.wpa_version then %>
+ <input type="hidden" name="wpa_version" value="<%=net.wpa_version%>" />
+ <% for _, v in ipairs(net.auth_suites) do %><input type="hidden" name="wpa_suites" value="<%=v%>" />
+ <% end; for _, v in ipairs(net.group_ciphers) do %><input type="hidden" name="wpa_group" value="<%=v%>" />
+ <% end; for _, v in ipairs(net.pair_ciphers) do %><input type="hidden" name="wpa_pairwise" value="<%=v%>" />
+ <% end; end %>
+
+ <input class="cbi-button-apply" type="submit" value="Join Network" />
+ </form>
+ </td>
+ </tr>
+ <% end %>
+ <!-- /scan list -->
+ </table>
+ </fieldset>
+</div>
+<div class="cbi-page-actions right">
+ <form class="inline" action="<%=luci.dispatcher.build_url("admin/network/wireless")%>" method="get">
+ <input class="cbi-button-reset" type="submit" value="<%:a_s_iw_back_overview Back to overview%>" />
+ </form>
+ <form class="inline" action="<%=REQUEST_URI%>" method="get">
+ <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>" />
+ <input class="cbi-input-find" type="submit" value="<%:a_s_iw_scan_repeat Repeat scan%>" />
+ </form>
+</div>
+
+<%+footer%>
diff --git a/modules/admin-full/luasrc/view/admin_network/wifi_join_settings.htm b/modules/admin-full/luasrc/view/admin_network/wifi_join_settings.htm
new file mode 100644
index 0000000000..c914f3eddb
--- /dev/null
+++ b/modules/admin-full/luasrc/view/admin_network/wifi_join_settings.htm
@@ -0,0 +1,112 @@
+<%#
+LuCI - Lua Configuration Interface
+Copyright 2009 Jo-Philipp Wich <xm@subsignal.org>
+
+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
+
+$Id$
+
+-%>
+
+<%-
+
+ local sys = require "luci.sys"
+ local utl = require "luci.util"
+ local uci = require "luci.model.uci".cursor_state()
+
+ local ifaces = { }
+ uci:foreach("network", "interface", function(i)
+ if i.ifname ~= "lo" then
+ ifaces[#ifaces+1] = { i['.name'], i.ifname, i.ipaddr }
+ end
+ end)
+
+ local dev = luci.http.formvalue("device")
+ local iw = luci.sys.wifi.getiwinfo(dev)
+
+-%>
+
+<%+header%>
+
+<h2><a id="content" name="content"><%:a_s_iw_join Join Network%></a></h2>
+
+<form method="post" action="<%=REQUEST_URI%>">
+ <div class="cbi-map">
+ <div class="cbi-map-descr">
+ <%=luci.i18n.translatef("a_s_iw_join_desc", "You are about to join the wireless network <em><strong>%s</strong></em>. " ..
+ "In order to complete the process, you need to provide some additional details.",
+ utl.pcdata(luci.http.formvalue("join") or "(hidden)")
+ )%>
+ </div>
+
+ <fieldset class="cbi-section">
+ <input type="hidden" name="confirm" value="1" />
+ <input type="hidden" name="join" value="<%=utl.pcdata(luci.http.formvalue("join"))%>" />
+ <input type="hidden" name="device" value="<%=utl.pcdata(luci.http.formvalue("device"))%>" />
+ <input type="hidden" name="mode" value="<%=luci.http.formvalue("mode")%>" />
+ <input type="hidden" name="bssid" value="<%=luci.http.formvalue("bssid")%>" />
+ <input type="hidden" name="channel" value="<%=luci.http.formvalue("channel")%>" />
+ <input type="hidden" name="wep" value="<%=luci.http.formvalue("wep")%>" />
+ <input type="hidden" name="wpa_version" value="<%=luci.http.formvalue("wpa_version")%>" />
+
+ <% if luci.http.formvalue("wep") == "1" then %>
+ <label for="pw_key">WEP passphrase</label><br />
+ <input class="cbi-input-password" type="password" name="key" id="pw_key" />
+ <br /><br />
+ <% elseif tonumber(luci.http.formvalue("wpa_version") or 0) > 0 and luci.http.formvalue("wpa_suites") == "PSK" then %>
+ <label for="pw_key">WPA passphrase</label><br />
+ <input class="cbi-input-password" type="password" name="key" id="pw_key" />
+
+ <% if tonumber(luci.http.formvalue("wpa_version") or 0) == 3 then %>
+ <select name="wpa_suite">
+ <option value="psk">WPA-PSK</option>
+ <option value="psk2" selected="selected">WPA2-PSK</option>
+ <option value="psk+psk2">WPA/WPA2-PSK mixed mode</option>
+ </select>
+ <% else %>
+ <input type="hidden" name="wpa_suite" value="psk<%=tonumber(luci.http.formvalue("wpa_version") or 0) == 2 and 2%>" />
+ <% end %>
+
+ <br /><br />
+ <% end %>
+
+ <label for="sel_attach_intf">Attach wireless to</label><br />
+ <select name="attach_intf" id="sel_attach_intf">
+ <% for _, i in ipairs(ifaces) do %>
+ <option<% if i[1] == "wan" then %> selected="selected"<% end %> value="<%=i[1]%>"><%=i[1]%> (<%=i[2]%><% if i[3] then %> - <%=i[3]%><% end %>)</option>
+ <% end %>
+ <option value="">-- no interface --</option>
+ </select>
+
+ <br/><br />
+ <hr /><br />
+
+ <% if luci.http.formvalue("mode") == "Ad-Hoc" then %>
+ <input type="checkbox" name="fixed_bssid" value="1" id="cb_fixed_bssid" checked="checked" />
+ <label for="cb_fixed_bssid">Lock to BSSID <%=luci.http.formvalue("bssid")%></label>
+ <br />
+ <% end %>
+
+ <% if iw.mbssid_support then %>
+ <input type="checkbox" name="replace_net" value="1" id="cb_replace_net" checked="checked" />
+ <label for="cb_replace_net">Overwrite existing wireless configuration</label>
+ <br />
+ <% else %>
+ <input type="hidden" name="replace_net" value="1" />
+ <% end %>
+
+ <input type="checkbox" name="autoconnect" value="1" id="cb_autoconnect" checked="checked" />
+ <label for="cb_autoconnect">Automatically connect</label>
+ </fieldset>
+ </div>
+ <div class="cbi-page-actions">
+ <input class="cbi-button-apply" type="submit" value="<%:a_s_iw_join_confirm Join network%>" />
+ <input class="cbi-button-reset" type="submit" name="cancel" value="<%:a_s_iw_back_scan Back to scan results%>" />
+ </div>
+</form>
+
+<%+footer%>
diff --git a/modules/admin-full/luasrc/view/admin_network/wifi_overview.htm b/modules/admin-full/luasrc/view/admin_network/wifi_overview.htm
new file mode 100644
index 0000000000..251f767d23
--- /dev/null
+++ b/modules/admin-full/luasrc/view/admin_network/wifi_overview.htm
@@ -0,0 +1,250 @@
+<%#
+LuCI - Lua Configuration Interface
+Copyright 2008-2009 Steven Barth <steven@midlink.org>
+Copyright 2008-2009 Jo-Philipp Wich <xm@leipzig.freifunk.net>
+
+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
+
+$Id$
+
+-%>
+
+<%-
+
+ local sys = require "luci.sys"
+ local utl = require "luci.util"
+ local uci = require "luci.model.uci".cursor_state()
+
+ function guess_wifi_hw(ifname)
+ local name, idx = ifname:match("^([a-z]+)(%d+)")
+ idx = tonumber(idx)
+
+ -- wl.o
+ if name == "wl" then
+ local name = "Broadcom 802.11 Wireless Controller"
+ 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 = string.format(
+ "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
+ return "Atheros 802.11 Wireless Controller"
+
+ -- ralink
+ elseif name == "ra" then
+ return "RaLink 802.11 Wireless Controller"
+
+ -- prism?
+ elseif name == "eth" then
+ return "Prism 802.11 Wireless Controller"
+
+ -- dunno yet
+ else
+ return "Unkown 802.11 Wireless Controller"
+ end
+ end
+
+ function guess_wifi_signal(info)
+ local snr = -1 * ((info.noise or 0) - (info.signal or 0))
+ local scale = math.floor(snr / 5)
+ local icon
+
+ if not info.bssid or info.bssid == "00:00:00:00:00:00" then
+ icon = resource .. "/icons/signal-none.png"
+ elseif scale < 1 then
+ icon = resource .. "/icons/signal-0.png"
+ elseif scale < 2 then
+ icon = resource .. "/icons/signal-0-25.png"
+ elseif scale < 3 then
+ icon = resource .. "/icons/signal-25-50.png"
+ elseif scale < 4 then
+ icon = resource .. "/icons/signal-50-75.png"
+ else
+ icon = resource .. "/icons/signal-75-100.png"
+ end
+
+ return icon
+ end
+
+ function percent_wifi_signal(info)
+ local qc = info.quality or 0
+ local qm = info.quality_max or 0
+
+ if info.bssid and qc > 0 and qm > 0 then
+ return math.floor((100 / qm) * qc)
+ else
+ return 0
+ end
+ end
+
+ function find_wifi_devices()
+ local devs = { }
+ uci:foreach("wireless", "wifi-device",
+ function(s)
+ local dev = s['.name']
+ local act = 0
+ devs[dev] = { active = 0, networks = { } }
+
+ uci:foreach("wireless", "wifi-iface",
+ function(s)
+ if s.device == dev then
+ if s.up == "1" then act = act + 1 end
+ devs[dev].networks[#devs[dev].networks+1] = {
+ active = (s.up == "1"),
+ ifname = s.ifname,
+ info = sys.wifi.getiwinfo(s.ifname or s.device)
+ }
+ end
+ end)
+
+ devs[dev].hwname = guess_wifi_hw(dev)
+ devs[dev].active = (act > 0)
+ end)
+
+ return devs
+ end
+
+ function find_wifi_frequency(state)
+ if state.active then
+ return string.format("%d (%.03f GHz)",
+ state.networks[1].info.channel,
+ state.networks[1].info.frequency / 1000);
+ else
+ return "n/a"
+ end
+ end
+
+
+ local devices = find_wifi_devices()
+ local arpcache = { }
+ sys.net.arptable(function(e) arpcache[e["HW address"]] = e["IP address"] end)
+-%>
+
+<%+header%>
+
+<h2><a id="content" name="content"><%:a_s_iw_overview Wireless Overview%></a></h2>
+
+<div class="cbi-map">
+
+ <% for dev, state in utl.kspairs(devices) do %>
+ <!-- device <%=dev%> -->
+ <fieldset class="cbi-section">
+ <table class="cbi-section-table" style="margin:10px; empty-cells:hide">
+ <!-- physical device -->
+ <tr>
+ <td style="width:34px"><img src="<%=resource%>/icons/wifi<%=state.active and "" or "_disabled"%>.png" style="float:left; margin-right:10px" /></td>
+ <td colspan="2" style="text-align:left">
+ <big><strong><%=state.hwname%> (<%=dev%>)</strong></big><br />
+ <strong>Channel:</strong> <%=find_wifi_frequency(state)%> |
+ <strong>Bitrate:</strong> <%=state.active and (state.networks[1].info.bitrate / 1000) .. " Mb/s" or "n/a"%>
+ </td>
+ <td style="width:40px">
+ <a href="<%=luci.dispatcher.build_url("admin/network/wireless_join?device="..dev)%>"><img style="border:none" src="<%=resource%>/cbi/find.gif" alt="Find and join network" title="Find and join network" /></a>
+ <a href="#"><img style="border:none" src="<%=resource%>/cbi/add.gif" alt="Provide new network" title="Provide new network" /></a>
+ </td>
+ </tr>
+ <!-- /physical device -->
+
+ <!-- network list -->
+ <% if #state.networks > 0 then %>
+ <% for i, net in ipairs(state.networks) do %>
+ <tr class="cbi-section-table-row cbi-rowstyle-<%=1 + ((i-1) % 2)%>">
+ <td></td>
+ <td class="cbi-value-field" style="width:16px; padding:3px">
+ <img src="<%=guess_wifi_signal(net.info)%>" title="Signal: <%=net.info.signal%> dBm / Noise: <%=net.info.noise%> dBm" /><br />
+ <small><%=percent_wifi_signal(net.info)%>%</small>
+ </td>
+ <td class="cbi-value-field" style="vertical-align:middle; text-align:left; padding:3px">
+ <strong>SSID:</strong> <%=utl.pcdata(net.info.ssid)%> |
+ <strong>Mode:</strong> <%=net.info.mode%><br />
+ <strong>BSSID:</strong> <%=net.info.bssid%> |
+ <strong>Encryption:</strong> <%=net.info.enctype%>
+ </td>
+ <td class="cbi-value-field" style="width:40px">
+ <a href="<%=REQUEST_URI%>/<%=dev%>"><img style="border:none" src="<%=resource%>/cbi/edit.gif" alt="Edit this network" title="Edit this network" /></a>
+ <a href="#"><img style="border:none" src="<%=resource%>/cbi/remove.gif" alt="Delete this network" title="Delete this network" /></a>
+ </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">
+ <em>(No network configured on this device)</em>
+ </td>
+ </tr>
+ <% end %>
+ <!-- /network list -->
+ </table>
+ </fieldset>
+ <!-- /device <%=dev%> -->
+ <% end %>
+
+
+
+
+ <h2><a id="content" name="content"><%:a_s_iw_overview2 Associated Stations%></a></h2>
+
+ <fieldset class="cbi-section">
+ <table class="cbi-section-table" style="margin:10px; width:50%">
+ <tr class="cbi-section-table-titles">
+ <th class="cbi-section-table-cell"></th>
+ <th class="cbi-section-table-cell">SSID</th>
+ <th class="cbi-section-table-cell">MAC</th>
+ <th class="cbi-section-table-cell">Address</th>
+ <th class="cbi-section-table-cell">Signal</th>
+ <th class="cbi-section-table-cell">Noise</th>
+ </tr>
+
+ <% local count = -1 %>
+ <% for dev, state in utl.kspairs(devices) do %>
+ <% for _, net in ipairs(state.networks) do %>
+ <% for mac, info in utl.kspairs(net.info.assoclist) do info.bssid = mac; count = count + 1 %>
+ <tr class="cbi-section-table-row cbi-rowstyle-<%=1 + (count % 2)%>">
+ <td class="cbi-value-field"><img src="<%=guess_wifi_signal(info)%>" title="Signal: <%=info.signal%> dBm / Noise: <%=info.noise%> dBm" /></td>
+ <td class="cbi-value-field"><%=net.info.ssid%></td>
+ <td class="cbi-value-field"><%=mac%></td>
+ <td class="cbi-value-field"><%=arpcache[mac] or "n/a"%></td>
+ <td class="cbi-value-field"><%=info.signal%> dBm</td>
+ <td class="cbi-value-field"><%=info.noise%> dBm</td>
+ </tr>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% if count <= 0 then %>
+ <tr class="cbi-section-table-row cbi-rowstyle-2">
+ <td class="cbi-value-field" colspan="6">
+ <em>No information available</em>
+ </td>
+ </tr>
+ <% end %>
+ </table>
+ </fieldset>
+</div>
+
+<%+footer%>