"like encryption or operation mode are grouped in the <em>Interface Configuration</em>."))
m:chain("network")
+m:chain("firewall")
local ifsection
m.title = luci.util.pcdata(wnet:get_i18n())
+local function txpower_list(iw)
+ local list = iw.txpwrlist or { }
+ local off = tonumber(iw.txpower_offset) or 0
+ local new = { }
+ local prev = -1
+ local _, val
+ for _, val in ipairs(list) do
+ local dbm = val.dbm + off
+ local mw = math.floor(10 ^ (dbm / 10))
+ if mw ~= prev then
+ prev = mw
+ new[#new+1] = {
+ display_dbm = dbm,
+ display_mw = mw,
+ driver_dbm = val.dbm,
+ driver_mw = val.mw
+ }
+ end
+ end
+ return new
+end
+
+local function txpower_current(pwr, list)
+ pwr = tonumber(pwr)
+ if pwr ~= nil then
+ local _, item
+ for _, item in ipairs(list) do
+ if item.driver_dbm >= pwr then
+ return item.driver_dbm
+ end
+ end
+ end
+ return (list[#list] and list[#list].driver_dbm) or pwr or 0
+end
+
local iw = luci.sys.wifi.getiwinfo(arg[1])
-local hw_modes = iw.hwmodelist or { }
-local tx_powers = iw.txpwrlist or { }
-local tx_power = tostring(
- (iw.txpower and iw.txpower > 0 and iw.txpower) or
- (#tx_powers > 0 and tx_powers[#tx_powers].dbm)
-)
+local hw_modes = iw.hwmodelist or { }
+local tx_power_list = txpower_list(iw)
+local tx_power_cur = txpower_current(wdev:get("txpower"), tx_power_list)
s = m:section(NamedSection, wdev:name(), "wifi-device", translate("Device Configuration"))
s.addremove = 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 ------------------
if hwtype == "mac80211" then
tp = s:taboption("general",
- (tx_powers and #tx_powers > 0) and ListValue or Value,
+ (#tx_power_list > 0) and ListValue or Value,
"txpower", translate("Transmit Power"), "dBm")
tp.rmempty = true
- tp.default = tx_power
- for _, p in ipairs(tx_powers or {}) do
- tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
+ tp.default = tx_power_cur
+
+ function tp.cfgvalue(...)
+ return txpower_current(Value.cfgvalue(...), tx_power_list)
+ end
+
+ for _, p in ipairs(tx_power_list) do
+ tp:value(p.driver_dbm, "%i dBm (%i mW)"
+ %{ p.display_dbm, p.display_mw })
end
mode = s:taboption("advanced", ListValue, "hwmode", translate("Mode"))
if hwtype == "atheros" then
tp = s:taboption("general",
- (#tx_powers > 0) and ListValue or Value,
+ (#tx_power_list > 0) and ListValue or Value,
"txpower", translate("Transmit Power"), "dBm")
tp.rmempty = true
- tp.default = tx_power
- for _, p in ipairs(tx_powers or {}) do
- tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
+ tp.default = tx_power_cur
+
+ function tp.cfgvalue(...)
+ return txpower_current(Value.cfgvalue(...), tx_power_list)
+ end
+
+ for _, p in ipairs(tx_power_list) do
+ tp:value(p.driver_dbm, "%i dBm (%i mW)"
+ %{ p.display_dbm, p.display_mw })
end
mode = s:taboption("advanced", ListValue, "hwmode", translate("Mode"))
if hwtype == "broadcom" then
tp = s:taboption("general",
- (#tx_powers > 0) and ListValue or Value,
+ (#tx_power_list > 0) and ListValue or Value,
"txpower", translate("Transmit Power"), "dBm")
tp.rmempty = true
- tp.default = tx_power
- for _, p in ipairs(tx_powers or {}) do
- tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
+ tp.default = tx_power_cur
+
+ function tp.cfgvalue(...)
+ return txpower_current(Value.cfgvalue(...), tx_power_list)
+ end
+
+ for _, p in ipairs(tx_power_list) do
+ tp:value(p.driver_dbm, "%i dBm (%i mW)"
+ %{ p.display_dbm, p.display_mw })
end
mode = s:taboption("advanced", ListValue, "hwmode", translate("Mode"))
mode:value("ahdemo", translate("Pseudo Ad-Hoc (ahdemo)"))
mode:value("monitor", translate("Monitor"))
bssid:depends({mode="adhoc"})
+ bssid:depends({mode="sta"})
+ bssid:depends({mode="sta-wds"})
mp = s:taboption("macfilter", ListValue, "macfilter", translate("MAC-Address Filter"))
mp:depends({mode="ap"})
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
- self.map.uci:set("wireless", section, "encryption", value)
+ 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