modules/admin-full: bssid is valid in mac80211 sta mode too
[project/luci.git] / modules / admin-full / luasrc / model / cbi / admin_network / wifi.lua
index d0ebba2155f563f539f5031ab5ee3f5886c4a6ef..503455a97c5c6921690c72a8ecc838cfb954a87c 100644 (file)
@@ -25,6 +25,7 @@ m = Map("wireless", "",
                "like encryption or operation mode are grouped in the <em>Interface Configuration</em>."))
 
 m:chain("network")
+m:chain("firewall")
 
 local ifsection
 
@@ -48,19 +49,22 @@ if not wnet or not wdev then
 end
 
 -- wireless toggle was requested, commit and reload page
-if m:formvalue("cbid.wireless.%s.__toggle" % wdev:name()) then
-       if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then
-               wnet:set("disabled", nil)
-       else
-               wnet:set("disabled", "1")
-       end
-       wdev:set("disabled", nil)
+function m.parse(map)
+       if m:formvalue("cbid.wireless.%s.__toggle" % wdev:name()) then
+               if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then
+                       wnet:set("disabled", nil)
+               else
+                       wnet:set("disabled", "1")
+               end
+               wdev:set("disabled", nil)
 
-       nw:commit("wireless")
-       luci.sys.call("(env -i /sbin/wifi down; env -i /sbin/wifi up) >/dev/null 2>/dev/null")
+               nw:commit("wireless")
+               luci.sys.call("(env -i /sbin/wifi down; env -i /sbin/wifi up) >/dev/null 2>/dev/null")
 
-       luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1]))
-       return
+               luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1]))
+               return
+       end
+       Map.parse(map)
 end
 
 m.title = luci.util.pcdata(wnet:get_i18n())
@@ -110,14 +114,30 @@ local htcaps = wdev:get("ht_capab") and true or false
 -- NanoFoo
 local nsantenna = wdev:get("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
-       if not f.restricted then
-               ch:value(f.channel, "%i (%.3f GHz)" %{ f.channel, f.mhz / 1000 })
+-- Check whether there is a client interface on the same radio,
+-- if yes, lock the channel choice as the station will dicatate the freq
+local has_sta = nil
+local _, net
+for _, net in ipairs(wdev:get_wifinets()) do
+       if net:mode() == "sta" and net:id() ~= wnet:id() then
+               has_sta = net
+               break
        end
 end
 
+if has_sta then
+       ch = s:taboption("general", DummyValue, "choice", translate("Channel"))
+       ch.value = translatef("Locked to channel %d used by %s",
+               has_sta:channel(), has_sta:shortname())
+else
+       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
+               if not f.restricted then
+                       ch:value(f.channel, "%i (%.3f GHz)" %{ f.channel, f.mhz / 1000 })
+               end
+       end
+end
 
 ------------------- MAC80211 Device ------------------
 
@@ -167,6 +187,9 @@ if hwtype == "mac80211" then
 
        s:taboption("advanced", Value, "distance", translate("Distance Optimization"),
                translate("Distance to farthest network member in meters."))
+
+       s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
+       s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
 end
 
 
@@ -350,11 +373,11 @@ if hwtype == "mac80211" then
        mode:value("ahdemo", translate("Pseudo Ad-Hoc (ahdemo)"))
        mode:value("monitor", translate("Monitor"))
        bssid:depends({mode="adhoc"})
+       bssid:depends({mode="sta"})
 
-       s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
-       s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
-       
        mp = s:taboption("macfilter", ListValue, "macfilter", translate("MAC-Address Filter"))
+       mp:depends({mode="ap"})
+       mp:depends({mode="ap-wds"})
        mp:value("", translate("disable"))
        mp:value("allow", translate("Allow listed only"))
        mp:value("deny", translate("Allow all except listed"))
@@ -555,6 +578,58 @@ encr:depends({mode="ap-wds"})
 encr:depends({mode="sta-wds"})
 encr:depends({mode="mesh"})
 
+cipher = s:taboption("encryption", ListValue, "cipher", translate("Cipher"))
+cipher:depends({encryption="wpa"})
+cipher:depends({encryption="wpa2"})
+cipher:depends({encryption="psk"})
+cipher:depends({encryption="psk2"})
+cipher:depends({encryption="wpa-mixed"})
+cipher:depends({encryption="psk-mixed"})
+cipher:value("auto", translate("auto"))
+cipher:value("ccmp", translate("Force CCMP (AES)"))
+cipher:value("tkip", translate("Force TKIP"))
+cipher:value("tkip+ccmp", translate("Force TKIP and CCMP (AES)"))
+
+function encr.cfgvalue(self, section)
+       local v = tostring(ListValue.cfgvalue(self, section))
+       if v == "wep" then
+               return "wep-open"
+       elseif v and v:match("%+") then
+               return (v:gsub("%+.+$", ""))
+       end
+       return v
+end
+
+function encr.write(self, section, value)
+       local e = tostring(encr:formvalue(section))
+       local c = tostring(cipher:formvalue(section))
+       if value == "wpa" or value == "wpa2"  then
+               self.map.uci:delete("wireless", section, "key")
+       end
+       if e and (c == "tkip" or c == "ccmp" or c == "tkip+ccmp") then
+               e = e .. "+" .. c
+       end
+       self.map:set(section, "encryption", e)
+end
+
+function cipher.cfgvalue(self, section)
+       local v = tostring(ListValue.cfgvalue(encr, section))
+       if v and v:match("%+") then
+               v = v:gsub("^[^%+]+%+", "")
+               if v == "aes" then v = "ccmp"
+               elseif v == "tkip+aes" then v = "tkip+ccmp"
+               elseif v == "aes+tkip" then v = "tkip+ccmp"
+               elseif v == "ccmp+tkip" then v = "tkip+ccmp"
+               end
+       end
+       return v
+end
+
+function cipher.write(self, section)
+       return encr:write(section)
+end
+
+
 encr:value("none", "No Encryption")
 encr:value("wep-open",   translate("WEP Open System"), {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
 encr:value("wep-shared", translate("WEP Shared Key"),  {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
@@ -601,35 +676,59 @@ elseif hwtype == "broadcom" then
        encr:value("psk+psk2", "WPA-PSK/WPA2-PSK Mixed Mode")
 end
 
-encr:depends("mode", "ap")
-encr:depends("mode", "sta")
-encr:depends("mode", "ap-wds")
-encr:depends("mode", "sta-wds")
-encr:depends("mode", "wds")
-
-server = s:taboption("encryption", Value, "server", translate("Radius-Server"))
-server:depends({mode="ap", encryption="wpa"})
-server:depends({mode="ap", encryption="wpa2"})
-server:depends({mode="ap-wds", encryption="wpa"})
-server:depends({mode="ap-wds", encryption="wpa2"})
-server.rmempty = true
-
-port = s:taboption("encryption", Value, "port", translate("Radius-Port"))
-port:depends({mode="ap", encryption="wpa"})
-port:depends({mode="ap", encryption="wpa2"})
-port:depends({mode="ap-wds", encryption="wpa"})
-port:depends({mode="ap-wds", encryption="wpa2"})
-port.rmempty = true
+auth_server = s:taboption("encryption", Value, "auth_server", translate("Radius-Authentication-Server"))
+auth_server:depends({mode="ap", encryption="wpa"})
+auth_server:depends({mode="ap", encryption="wpa2"})
+auth_server:depends({mode="ap-wds", encryption="wpa"})
+auth_server:depends({mode="ap-wds", encryption="wpa2"})
+auth_server.rmempty = true
+auth_server.datatype = "host"
+
+auth_port = s:taboption("encryption", Value, "auth_port", translate("Radius-Authentication-Port"), translatef("Default %d", 1812))
+auth_port:depends({mode="ap", encryption="wpa"})
+auth_port:depends({mode="ap", encryption="wpa2"})
+auth_port:depends({mode="ap-wds", encryption="wpa"})
+auth_port:depends({mode="ap-wds", encryption="wpa2"})
+auth_port.rmempty = true
+auth_port.datatype = "port"
+
+auth_secret = s:taboption("encryption", Value, "auth_secret", translate("Radius-Authentication-Secret"))
+auth_secret:depends({mode="ap", encryption="wpa"})
+auth_secret:depends({mode="ap", encryption="wpa2"})
+auth_secret:depends({mode="ap-wds", encryption="wpa"})
+auth_secret:depends({mode="ap-wds", encryption="wpa2"})
+auth_secret.rmempty = true
+auth_secret.password = true
+
+acct_server = s:taboption("encryption", Value, "acct_server", translate("Radius-Accounting-Server"))
+acct_server:depends({mode="ap", encryption="wpa"})
+acct_server:depends({mode="ap", encryption="wpa2"})
+acct_server:depends({mode="ap-wds", encryption="wpa"})
+acct_server:depends({mode="ap-wds", encryption="wpa2"})
+acct_server.rmempty = true
+acct_server.datatype = "host"
+
+acct_port = s:taboption("encryption", Value, "acct_port", translate("Radius-Accounting-Port"), translatef("Default %d", 1813))
+acct_port:depends({mode="ap", encryption="wpa"})
+acct_port:depends({mode="ap", encryption="wpa2"})
+acct_port:depends({mode="ap-wds", encryption="wpa"})
+acct_port:depends({mode="ap-wds", encryption="wpa2"})
+acct_port.rmempty = true
+acct_port.datatype = "port"
+
+acct_secret = s:taboption("encryption", Value, "acct_secret", translate("Radius-Accounting-Secret"))
+acct_secret:depends({mode="ap", encryption="wpa"})
+acct_secret:depends({mode="ap", encryption="wpa2"})
+acct_secret:depends({mode="ap-wds", encryption="wpa"})
+acct_secret:depends({mode="ap-wds", encryption="wpa2"})
+acct_secret.rmempty = true
+acct_secret.password = true
 
 wpakey = s:taboption("encryption", Value, "_wpa_key", translate("Key"))
 wpakey:depends("encryption", "psk")
 wpakey:depends("encryption", "psk2")
 wpakey:depends("encryption", "psk+psk2")
 wpakey:depends("encryption", "psk-mixed")
-wpakey:depends({mode="ap", encryption="wpa"})
-wpakey:depends({mode="ap", encryption="wpa2"})
-wpakey:depends({mode="ap-wds", encryption="wpa"})
-wpakey:depends({mode="ap-wds", encryption="wpa2"})
 wpakey.datatype = "wpakey"
 wpakey.rmempty = true
 wpakey.password = true