luci-mod-admin-full: fix displaying of VHT rates (#533)
[project/luci.git] / modules / luci-mod-admin-full / luasrc / view / admin_network / wifi_overview.htm
index b7c44f9..1df6b28 100644 (file)
                end
        end
 
-       local devices  = ntm:get_wifidevs()
-       local arpcache = { }
-       ip.neighbors({ family = 4 }, function(n)
-               if n.mac and n.dest then arpcache[n.mac:upper()] = n.dest:string() end
-       end)
-
+       local devices = ntm:get_wifidevs()
        local netlist = { }
        local netdevs = { }
 
 <script type="text/javascript" src="<%=resource%>/cbi.js"></script>
 <script type="text/javascript">//<![CDATA[
        var wifidevs = <%=luci.http.write_json(netdevs)%>;
-       var arptable = <%=luci.http.write_json(arpcache)%>;
 
        var is_reconnecting = false;
 
                return s.replace(/ /g, '&#160;');
        }
 
+       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');
 
                                st.innerHTML = '<em><%:Wireless is restarting...%></em>';
                }
 
-               XHR.get('<%=luci.dispatcher.build_url("admin", "network")%>/wireless_' + (reconnect ? 'reconnect' : 'shutdown') + '/' + id, null,
+               (new XHR()).post('<%=url('admin/network')%>/wireless_' + (reconnect ? 'reconnect' : 'shutdown') + '/' + id, { token: '<%=token%>' },
                        function(x)
                        {
                                if (s)
                );
        }
 
-       XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "wireless_status", table.concat(netlist, ","))%>', null,
+       function wifi_delete(id) {
+               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.%>'))
+                       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)
                                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');
+                                       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 sig = document.getElementById(iw.id + '-iw-signal');
                                        if (sig)
                                                sig.innerHTML = String.format(
-                                                       '<img src="%s" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%>" /><br />' +
-                                                       '<small>%d%%</small>', icon, iw.signal, iw.noise, p
+                                                       '<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');
                                                                icon = "<%=resource%>/icons/signal-75-100.png";
 
                                                        tr.insertCell(-1).innerHTML = String.format(
-                                                               '<img src="%s" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%>" />',
-                                                               icon, assoclist[j].signal, assoclist[j].noise
+                                                               '<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> %h</span>',
+                                                               iw.device.name, iw.ifname
                                                        );
 
                                                        tr.insertCell(-1).innerHTML = nowrap(String.format('%h', iw.ssid ? iw.ssid : '?'));
                                                        tr.insertCell(-1).innerHTML = assoclist[j].bssid;
 
-                                                       tr.insertCell(-1).innerHTML = arptable[assoclist[j].bssid]
-                                                               ? arptable[assoclist[j].bssid] : '?';
-
-                                                       tr.insertCell(-1).innerHTML = nowrap(String.format('%d <%:dBm%>', assoclist[j].signal));
-                                                       tr.insertCell(-1).innerHTML = nowrap(String.format('%d <%:dBm%>', assoclist[j].noise));
+                                                       var host = hosts[assoclist[j].bssid];
+                                                       if (host)
+                                                               tr.insertCell(-1).innerHTML = String.format(
+                                                                       '<div style="max-width:200px;overflow:hidden;text-overflow:ellipsis">%s</div>',
+                                                                       ((host.name && (host.ipv4 || host.ipv6))
+                                                                               ? '%h (%s)'.format(host.name, host.ipv4 || host.ipv6)
+                                                                               : '%h'.format(host.name || host.ipv4 || host.ipv6)).nobr()
+                                                               );
+                                                       else
+                                                               tr.insertCell(-1).innerHTML = '?';
 
-                                                       tr.insertCell(-1).innerHTML = nowrap((assoclist[j].rx_mcs > -1)
-                                                               ? 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)
+                                                       tr.insertCell(-1).innerHTML = String.format(
+                                                               '<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>',
+                                                               assoclist[j].signal, assoclist[j].noise, assoclist[j].signal - assoclist[j].noise,
+                                                               icon,
+                                                               assoclist[j].signal, assoclist[j].noise
                                                        );
 
-                                                       tr.insertCell(-1).innerHTML = nowrap((assoclist[j].tx_mcs > -1)
-                                                               ? 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)
-                                                       );
+                                                       tr.insertCell(-1).innerHTML = nowrap(wifirate(assoclist[j], true)) + '<br />' + nowrap(wifirate(assoclist[j], false));
 
                                                        rowstyle = (rowstyle == 1) ? 2 : 1;
                                                }
        );
 //]]></script>
 
-<h2><a id="content" name="content"><%:Wireless Overview%></a></h2>
+<h2 name="content"><%:Wireless Overview%></h2>
 
 <fieldset class="cbi-section" style="display:none">
        <legend><%:Reconnecting interface%></legend>
                                        <span id="<%=dev:name()%>-iw-devinfo"></span>
                                </td>
                                <td style="width:310px;text-align:right">
-                                       <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%>" />
+                                       <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%>" />
+                                               <input type="submit" class="cbi-button cbi-button-find" style="width:100px" title="<%:Find and join network%>" value="<%:Scan%>" />
+                                       </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%>" />
+                                               <input type="submit" class="cbi-button cbi-button-add" style="width:100px" title="<%:Provide new network%>" value="<%:Add%>" />
+                                       </form>
                                </td>
                        </tr>
                        <!-- /physical device -->
                                <% for i, net in ipairs(nets) 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" id="<%=net:id()%>-iw-signal">
-                                               <img src="<%=resource%>/icons/signal-none.png" title="<%:Not associated%>" /><br />
-                                               <small>0%</small>
+                                       <td class="cbi-value-field" style="vertical-align:middle; padding:3px" id="<%=net:id()%>-iw-signal">
+                                               <span class="ifacebadge" title="<%:Not associated%>"><img src="<%=resource%>/icons/signal-none.png" /> 0%</span>
                                        </td>
                                        <td class="cbi-value-field" style="vertical-align:middle; text-align:left; padding:3px" id="<%=net:id()%>-iw-status">
                                                <em><%:Collecting data...%></em>
                                        <td class="cbi-value-field" style="width:310px;text-align:right">
                                                <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%>" />
-                                               <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%>" />
+                                               <input type="button" class="cbi-button cbi-button-remove" style="width:100px" onclick="wifi_delete('<%=net:ifname()%>')" title="<%:Delete this network%>" value="<%:Remove%>" />
                                        </td>
                                </tr>
                                <% end %>
        <% end %>
 
 
-       <h2><a id="content" name="content"><%:Associated Stations%></a></h2>
+       <h2><%:Associated Stations%></h2>
 
        <fieldset class="cbi-section">
-               <table class="cbi-section-table" style="margin:10px" id="iw-assoclist">
+               <table class="cbi-section-table valign-middle" style="margin:10px" id="iw-assoclist">
                        <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-Address%></th>
-                               <th class="cbi-section-table-cell"><%:IPv4-Address%></th>
-                               <th class="cbi-section-table-cell"><%:Signal%></th>
-                               <th class="cbi-section-table-cell"><%:Noise%></th>
-                               <th class="cbi-section-table-cell"><%:RX Rate%></th>
-                               <th class="cbi-section-table-cell"><%:TX Rate%></th>
+                               <th class="cbi-section-table-cell"><%:Host%></th>
+                               <th class="cbi-section-table-cell"><%:Signal%> / <%:Noise%></th>
+                               <th class="cbi-section-table-cell"><%:RX Rate%> / <%:TX Rate%></th>
                        </tr>
                        <tr class="cbi-section-table-row cbi-rowstyle-2">
-                               <td class="cbi-value-field" colspan="8">
+                               <td class="cbi-value-field" colspan="6">
                                        <em><%:Collecting data...%></em>
                                </td>
                        </tr>