modules/admin-full: rework wifi configuration
authorJo-Philipp Wich <jow@openwrt.org>
Tue, 19 Oct 2010 04:08:15 +0000 (04:08 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Tue, 19 Oct 2010 04:08:15 +0000 (04:08 +0000)
modules/admin-full/luasrc/controller/admin/network.lua
modules/admin-full/luasrc/model/cbi/admin_network/wifi.lua
modules/admin-full/luasrc/view/admin_network/wifi_status.htm [new file with mode: 0644]

index fe60e78..14af771 100644 (file)
@@ -41,17 +41,22 @@ function index()
        end
 
        if has_wifi and has_wifi.size > 0 then
        end
 
        if has_wifi and has_wifi.size > 0 then
-               local page = entry({"admin", "network", "wireless"}, arcombine(template("admin_network/wifi_overview"), cbi("admin_network/wifi")), i18n("Wifi"), 15)
+               local page
+
+               page = entry({"admin", "network", "wireless"}, arcombine(template("admin_network/wifi_overview"), cbi("admin_network/wifi")), i18n("Wifi"), 15)
                page.leaf = true
                page.subindex = true
 
                page.leaf = true
                page.subindex = true
 
-               local page = entry({"admin", "network", "wireless_join"}, call("wifi_join"), nil, 16)
+               page = entry({"admin", "network", "wireless_join"}, call("wifi_join"), nil, 16)
+               page.leaf = true
+
+               page = entry({"admin", "network", "wireless_add"}, call("wifi_add"), nil, 16)
                page.leaf = true
 
                page.leaf = true
 
-               local page = entry({"admin", "network", "wireless_add"}, call("wifi_add"), nil, 16)
+               page = entry({"admin", "network", "wireless_delete"}, call("wifi_delete"), nil, 16)
                page.leaf = true
 
                page.leaf = true
 
-               local page = entry({"admin", "network", "wireless_delete"}, call("wifi_delete"), nil, 16)
+               page = entry({"admin", "network", "wireless_status"}, call("wifi_status"), nil, 16)
                page.leaf = true
        end
 
                page.leaf = true
        end
 
@@ -127,7 +132,7 @@ function wifi_join()
 end
 
 function wifi_add()
 end
 
 function wifi_add()
-       local dev = luci.http.formvalue("device") 
+       local dev = luci.http.formvalue("device")
        local uci = require "luci.model.uci".cursor()
        local wlm = require "luci.model.wireless"
 
        local uci = require "luci.model.uci".cursor()
        local wlm = require "luci.model.wireless"
 
@@ -156,3 +161,60 @@ function wifi_delete(network)
        uci:save("wireless")
        luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
 end
        uci:save("wireless")
        luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
 end
+
+function wifi_status()
+       local function jsondump(x)
+               if x == nil then
+                       luci.http.write("null")
+               elseif type(x) == "table" then
+                       local k, v
+                       if type(next(x)) == "number" then
+                               luci.http.write("[ ")
+                               for k, v in ipairs(x) do
+                                       jsondump(v)
+                                       if next(x, k) then
+                                               luci.http.write(", ")
+                                       end
+                               end
+                               luci.http.write(" ]")
+                       else
+                               luci.http.write("{ ")
+                               for k, v in pairs(x) do
+                               luci.http.write("%q: " % k)
+                                       jsondump(v)
+                                       if next(x, k) then
+                                               luci.http.write(", ")
+                                       end
+                               end
+                               luci.http.write(" }")
+                       end
+               elseif type(x) == "number" or type(x) == "boolean" then
+                       luci.http.write(tostring(x))
+               elseif type(x) == "string" then
+                       luci.http.write("%q" % tostring(x))
+               end
+       end
+
+
+       local path = luci.dispatcher.context.requestpath
+       local dev  = path[#path]
+       local iw   = luci.sys.wifi.getiwinfo(dev)
+
+       if iw then
+               local f
+               local j = { }
+               for _, f in ipairs({
+                       "channel", "frequency", "txpower", "bitrate", "signal", "noise",
+                       "quality", "quality_max", "mode", "ssid", "bssid", "country",
+                       "encryption", "mbssid_support", "ifname"
+               }) do
+                       j[f] = iw[f]
+               end
+
+               luci.http.prepare_content("application/json")
+               jsondump(j)
+               return
+       end
+
+       luci.http.status(404, "No such device")
+end
index adf6651..8ecfdda 100644 (file)
@@ -58,16 +58,9 @@ end
 m.title = ww:get_i18n(wnet)
 
 
 m.title = ww:get_i18n(wnet)
 
 
-local iw = nil
-local tx_powers = nil
-
-m.uci:foreach("wireless", "wifi-iface",
-       function(s)
-               if s.device == arg[1] and not iw then
-                       iw = luci.sys.wifi.getiwinfo(s.ifname or s.device)
-                       tx_powers = iw.txpwrlist or { }
-               end
-       end)
+local iw = luci.sys.wifi.getiwinfo(arg[1])
+local tx_powers = iw.txpwrlist or { }
+
 
 s = m:section(NamedSection, arg[1], "wifi-device", translate("Device Configuration"))
 s.addremove = false
 
 s = m:section(NamedSection, arg[1], "wifi-device", translate("Device Configuration"))
 s.addremove = false
@@ -82,7 +75,11 @@ back.value = ""
 back.titleref = luci.dispatcher.build_url("admin", "network", "wireless")
 ]]
 
 back.titleref = luci.dispatcher.build_url("admin", "network", "wireless")
 ]]
 
-en = s:taboption("general", Flag, "disabled", translate("enable"))
+st = s:taboption("general", DummyValue, "__status", translate("Status"))
+st.template = "admin_network/wifi_status"
+st.ifname   = arg[1]
+
+en = s:taboption("general", Flag, "disabled", translate("Enable device"))
 en.enabled = "0"
 en.disabled = "1"
 en.rmempty = false
 en.enabled = "0"
 en.disabled = "1"
 en.rmempty = false
@@ -91,7 +88,6 @@ function en.cfgvalue(self, section)
        return Flag.cfgvalue(self, section) or "0"
 end
 
        return Flag.cfgvalue(self, section) or "0"
 end
 
-s:taboption("general", DummyValue, "type", translate("Type"))
 
 local hwtype = m:get(arg[1], "type")
 local htcaps = m:get(arg[1], "ht_capab") and true or false
 
 local hwtype = m:get(arg[1], "type")
 local htcaps = m:get(arg[1], "ht_capab") and true or false
@@ -102,7 +98,9 @@ local nsantenna = m:get(arg[1], "antenna")
 ch = s:taboption("general", Value, "channel", translate("Channel"))
 ch:value("auto", translate("auto"))
 for _, f in ipairs(iw and iw.freqlist or luci.sys.wifi.channels()) do
 ch = s:taboption("general", Value, "channel", translate("Channel"))
 ch:value("auto", translate("auto"))
 for _, f in ipairs(iw and iw.freqlist or luci.sys.wifi.channels()) do
-       ch:value(f.channel, "%i (%.3f GHz)" %{ f.channel, f.mhz / 1000 })
+       if not f.restricted then
+               ch:value(f.channel, "%i (%.3f GHz)" %{ f.channel, f.mhz / 1000 })
+       end
 end
 
 
 end
 
 
@@ -626,9 +624,9 @@ if wnet then
                nasid.rmempty = true
 
                eaptype = s:taboption("encryption", ListValue, "eap_type", translate("EAP-Method"))
                nasid.rmempty = true
 
                eaptype = s:taboption("encryption", ListValue, "eap_type", translate("EAP-Method"))
-               eaptype:value("TLS")
-               eaptype:value("TTLS")
-               eaptype:value("PEAP")
+               eaptype:value("tls")
+               eaptype:value("ttls")
+               eaptype:value("peap")
                eaptype:depends({mode="sta", encryption="wpa"})
                eaptype:depends({mode="sta", encryption="wpa2"})
 
                eaptype:depends({mode="sta", encryption="wpa"})
                eaptype:depends({mode="sta", encryption="wpa2"})
 
@@ -637,12 +635,12 @@ if wnet then
                cacert:depends({mode="sta", encryption="wpa2"})
 
                privkey = s:taboption("encryption", FileUpload, "priv_key", translate("Path to Private Key"))
                cacert:depends({mode="sta", encryption="wpa2"})
 
                privkey = s:taboption("encryption", FileUpload, "priv_key", translate("Path to Private Key"))
-               privkey:depends({mode="sta", eap_type="TLS", encryption="wpa2"})
-               privkey:depends({mode="sta", eap_type="TLS", encryption="wpa"})
+               privkey:depends({mode="sta", eap_type="tls", encryption="wpa2"})
+               privkey:depends({mode="sta", eap_type="tls", encryption="wpa"})
 
                privkeypwd = s:taboption("encryption", Value, "priv_key_pwd", translate("Password of Private Key"))
 
                privkeypwd = s:taboption("encryption", Value, "priv_key_pwd", translate("Password of Private Key"))
-               privkeypwd:depends({mode="sta", eap_type="TLS", encryption="wpa2"})
-               privkeypwd:depends({mode="sta", eap_type="TLS", encryption="wpa"})
+               privkeypwd:depends({mode="sta", eap_type="tls", encryption="wpa2"})
+               privkeypwd:depends({mode="sta", eap_type="tls", encryption="wpa"})
 
 
                auth = s:taboption("encryption", Value, "auth", translate("Authentication"))
 
 
                auth = s:taboption("encryption", Value, "auth", translate("Authentication"))
@@ -650,23 +648,23 @@ if wnet then
                auth:value("CHAP")
                auth:value("MSCHAP")
                auth:value("MSCHAPV2")
                auth:value("CHAP")
                auth:value("MSCHAP")
                auth:value("MSCHAPV2")
-               auth:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
-               auth:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
-               auth:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
-               auth:depends({mode="sta", eap_type="TTLS", encryption="wpa"})
+               auth:depends({mode="sta", eap_type="peap", encryption="wpa2"})
+               auth:depends({mode="sta", eap_type="peap", encryption="wpa"})
+               auth:depends({mode="sta", eap_type="ttls", encryption="wpa2"})
+               auth:depends({mode="sta", eap_type="ttls", encryption="wpa"})
 
 
                identity = s:taboption("encryption", Value, "identity", translate("Identity"))
 
 
                identity = s:taboption("encryption", Value, "identity", translate("Identity"))
-               identity:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
-               identity:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
-               identity:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
-               identity:depends({mode="sta", eap_type="TTLS", encryption="wpa"})
+               identity:depends({mode="sta", eap_type="peap", encryption="wpa2"})
+               identity:depends({mode="sta", eap_type="peap", encryption="wpa"})
+               identity:depends({mode="sta", eap_type="ttls", encryption="wpa2"})
+               identity:depends({mode="sta", eap_type="ttls", encryption="wpa"})
 
                password = s:taboption("encryption", Value, "password", translate("Password"))
 
                password = s:taboption("encryption", Value, "password", translate("Password"))
-               password:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
-               password:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
-               password:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
-               password:depends({mode="sta", eap_type="TTLS", encryption="wpa"})
+               password:depends({mode="sta", eap_type="peap", encryption="wpa2"})
+               password:depends({mode="sta", eap_type="peap", encryption="wpa"})
+               password:depends({mode="sta", eap_type="ttls", encryption="wpa2"})
+               password:depends({mode="sta", eap_type="ttls", encryption="wpa"})
        end
 end
 
        end
 end
 
diff --git a/modules/admin-full/luasrc/view/admin_network/wifi_status.htm b/modules/admin-full/luasrc/view/admin_network/wifi_status.htm
new file mode 100644 (file)
index 0000000..044549d
--- /dev/null
@@ -0,0 +1,77 @@
+<%+cbi/valueheader%>
+
+<script type="text/javascript"><![CDATA[
+       var iwxhr = new XHR();
+       window.setInterval(function() {
+               iwxhr.get('<%=luci.dispatcher.build_url("admin", "network", "wireless_status", self.ifname)%>', null,
+                       function(x)
+                       {
+                               var iw = x.responseText ? eval('(' + x.responseText + ')') : null;
+                               if (iw)
+                               {
+                                       var is_assoc = (iw.bssid && iw.channel);
+                                       var p = (100 / iw.quality_max * 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";
+
+                                       var s = document.getElementById('<%=self.option%>-iw-signal');
+                                       if (s)
+                                               s.innerHTML = String.format(
+                                                       '<img src="%s" title="Signal: %d dBm / Noise: %d dBm" /><br />' +
+                                                       '<small>%d%%</small>', icon, iw.signal, iw.noise, p
+                                               );
+
+                                       var d = document.getElementById('<%=self.option%>-iw-description');
+                                       if (d && is_assoc)
+                                               d.innerHTML = String.format(
+                                                       '<strong><%:Mode%>:</strong> %s |' +
+                                                       '<strong><%:SSID%>:</strong> %s<br />' +
+                                                       '<strong><%:BSSID%>:</strong> %s |' +
+                                                       '<strong><%:Encryption%>:</strong> %s<br />' +
+                                                       '<strong><%:Channel%>:</strong> %d (%.3f GHz) |' +
+                                                       '<strong><%:Tx-Power%>:</strong> %d dBm<br />' +
+                                                       '<strong><%:Signal%>:</strong> %d dBm |' +
+                                                       '<strong><%:Noise%>:</strong> %d dBm<br />' +
+                                                       '<strong><%:Bit Rate%>:</strong> %.1f MBit/s |' +
+                                                       '<strong><%:Country%>:</strong> %s',
+                                                               iw.mode, iw.ssid, iw.bssid,
+                                                               iw.encryption ? iw.encryption.description : '<%:None%>',
+                                                               iw.channel, iw.frequency ? (iw.frequency / 1000) : 0,
+                                                               iw.txpower, iw.signal, iw.noise,
+                                                               iw.bitrate ? (iw.bitrate / 1000) : 0, iw.country
+                                               );
+                                       else if (d)
+                                               d.innerHTML = '<%:Wireless is disabled or not associated%>';
+                               }
+                       }
+               )
+       }, 5000);
+]]></script>
+
+<table>
+       <tr class="cbi-section-table">
+               <td></td>
+               <td class="cbi-value-field" style="width:16px; padding:3px" id="<%=self.option%>-iw-signal">
+                       <img src="<%=resource%>/icons/signal-none.png" title="<%:Not associated%>" /><br />
+                       <small>0%</small>
+               </td>
+               <td class="cbi-value-field" style="vertical-align:middle; text-align:left; padding:3px" id="<%=self.option%>-iw-description">
+                       <em><%:Collecting data...%></em>
+               </td>
+       </tr>
+</table>
+
+<%+cbi/valuefooter%>