wifi_assoclist.htm 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <%
  2. local supports_deauth = {}
  3. local _, v
  4. for _, v in ipairs(luci.util.ubus()) do
  5. local iface = v:match("^hostapd%.(.+)$")
  6. if iface then
  7. local funcs = luci.util.ubus(v)
  8. if type(funcs) == "table" and funcs.del_client then
  9. supports_deauth[iface] = true
  10. end
  11. end
  12. end
  13. %>
  14. <script type="text/javascript">//<![CDATA[
  15. var supports_deauth = <%= luci.http.write_json(supports_deauth) %>;
  16. function wifirate(bss, rx) {
  17. var p = rx ? 'rx_' : 'tx_',
  18. s = '%.1f <%:Mbit/s%>, %d<%:MHz%>'
  19. .format(bss[p+'rate'] / 1000, bss[p+'mhz']),
  20. ht = bss[p+'ht'], vht = bss[p+'vht'],
  21. mhz = bss[p+'mhz'], nss = bss[p+'nss'],
  22. mcs = bss[p+'mcs'], sgi = bss[p+'short_gi'];
  23. if (ht || vht) {
  24. if (vht) s += ', VHT-MCS %d'.format(mcs);
  25. if (nss) s += ', VHT-NSS %d'.format(nss);
  26. if (ht) s += ', MCS %s'.format(mcs);
  27. if (sgi) s += ', <%:Short GI%>';
  28. }
  29. return s;
  30. }
  31. function handleDeauth(ev) {
  32. (new XHR()).post('<%=url('admin/wireless_deauth')%>', {
  33. token: '<%=token%>',
  34. iface: ev.target.getAttribute('data-iface'),
  35. bssid: ev.target.getAttribute('data-bssid')
  36. }, function() {
  37. ev.target.disabled = true;
  38. });
  39. }
  40. XHR.poll(-1, '<%=url('admin/wireless_assoclist')%>', null,
  41. function(x, st)
  42. {
  43. var tb = document.getElementById('wifi_assoclist_table');
  44. if (st && tb)
  45. {
  46. var rows = [];
  47. st.forEach(function(bss) {
  48. var icon;
  49. var q = (-1 * (bss.noise - bss.signal)) / 5;
  50. if (q < 1)
  51. icon = "<%=resource%>/icons/signal-0.png";
  52. else if (q < 2)
  53. icon = "<%=resource%>/icons/signal-0-25.png";
  54. else if (q < 3)
  55. icon = "<%=resource%>/icons/signal-25-50.png";
  56. else if (q < 4)
  57. icon = "<%=resource%>/icons/signal-50-75.png";
  58. else
  59. icon = "<%=resource%>/icons/signal-75-100.png";
  60. rows.push([
  61. '<span class="ifacebadge" title="%q"><img src="<%=resource%>/icons/wifi.png" /> <a href="%s">%h</a><small>&#160;(%h)</small></span>'.format(
  62. bss.radio,
  63. bss.link,
  64. bss.name,
  65. bss.ifname),
  66. bss.bssid,
  67. bss.host_hint ? '%h (%h)'.format(bss.host_name || '?', bss.host_hint) : (bss.host_name || '?'),
  68. '<span class="ifacebadge" title="<%:Signal%>: %d <%:dBm%> / <%:Noise%>: %d <%:dBm%> / <%:SNR%>: %d"><img src="%s" /> %d / %d <%:dBm%></span>'.format(
  69. bss.signal,
  70. bss.noise,
  71. bss.signal - bss.noise,
  72. icon,
  73. bss.signal,
  74. bss.noise),
  75. E('span', {}, [
  76. E('span', wifirate(bss, true)),
  77. E('br'),
  78. E('span', wifirate(bss, false))
  79. ]),
  80. supports_deauth[bss.ifname] ? E('input', {
  81. type: 'button',
  82. class: 'cbi-button cbi-button-remove',
  83. value: '<%:Disconnect%>',
  84. 'data-bssid': bss.bssid,
  85. 'data-iface': bss.ifname,
  86. click: handleDeauth
  87. }) : '-'
  88. ]);
  89. });
  90. cbi_update_table(tb, rows, '<em><%:No information available%></em>');
  91. }
  92. }
  93. );
  94. //]]></script>
  95. <div class="table" id="wifi_assoclist_table">
  96. <div class="tr table-titles">
  97. <div class="th nowrap"><%:Network%></div>
  98. <div class="th hide-xs"><%:MAC-Address%></div>
  99. <div class="th nowrap"><%:Host%></div>
  100. <div class="th nowrap"><%:Signal%> / <%:Noise%></div>
  101. <div class="th nowrap"><%:RX Rate%> / <%:TX Rate%></div>
  102. <% if next(supports_deauth) then %>
  103. <div class="th right"><%:Disconnect%></div>
  104. <% end %>
  105. </div>
  106. <div class="tr placeholder">
  107. <div class="td"><em><%:Collecting data...%></em></div>
  108. </div>
  109. </div>