2 LuCI - Lua Configuration Interface
4 Copyright 2008 Steven Barth <steven@midlink.org>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
15 local wa = require "luci.tools.webadmin"
16 local nw = require "luci.model.network"
17 local fs = require "nixio.fs"
22 m = Map("wireless", translate("networks"), translate("a_w_networks1"))
29 m.uci:foreach("wireless", "wifi-iface",
31 if s.device == arg[1] and not iw then
32 iw = luci.sys.wifi.getiwinfo(s.ifname or s.device)
33 tx_powers = iw.txpwrlist or { }
37 s = m:section(NamedSection, arg[1], "wifi-device", translate("device") .. " " .. arg[1])
40 s:tab("general", translate("a_w_general", "General Setup"))
41 s:tab("macfilter", translate("a_w_macfilter", "MAC-Filter"))
42 s:tab("advanced", translate("a_w_advanced", "Advanced Settings"))
45 back = s:option(DummyValue, "_overview", translate("overview"))
47 back.titleref = luci.dispatcher.build_url("admin", "network", "wireless")
50 en = s:taboption("general", Flag, "disabled", translate("enable"))
55 function en.cfgvalue(self, section)
56 return Flag.cfgvalue(self, section) or "0"
59 s:taboption("general", DummyValue, "type", translate("type"))
61 local hwtype = m:get(arg[1], "type")
63 local nsantenna = m:get(arg[1], "antenna")
65 ch = s:taboption("general", Value, "channel", translate("a_w_channel"))
66 ch:value("auto", translate("wifi_auto"))
67 for c, f in luci.util.kspairs(luci.sys.wifi.channels()) do
68 ch:value(c, "%i (%.3f GHz)" %{ c, f })
72 ------------------- MAC80211 Device ------------------
74 if hwtype == "mac80211" then
75 tp = s:taboption("general",
76 (tx_powers and #tx_powers > 0) and ListValue or Value,
77 "txpower", translate("a_w_txpwr"), "dBm")
80 for _, p in ipairs(iw and iw.txpwrlist or {}) do
81 tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
86 ------------------- Madwifi Device ------------------
88 if hwtype == "atheros" then
89 tp = s:taboption("general",
90 (#tx_powers > 0) and ListValue or Value,
91 "txpower", translate("a_w_txpwr"), "dBm")
94 for _, p in ipairs(iw.txpwrlist) do
95 tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
98 mode = s:taboption("advanced", ListValue, "hwmode", translate("mode"))
99 mode:value("", translate("wifi_auto"))
100 mode:value("11b", "802.11b")
101 mode:value("11g", "802.11g")
102 mode:value("11a", "802.11a")
103 mode:value("11bg", "802.11b+g")
104 mode:value("11gst", "802.11g + Turbo")
105 mode:value("11ast", "802.11a + Turbo")
106 mode:value("fh", translate("wifi_fh"))
108 s:taboption("advanced", Flag, "diversity", translate("wifi_diversity")).rmempty = false
110 if not nsantenna then
111 ant1 = s:taboption("advanced", ListValue, "txantenna", translate("wifi_txantenna"))
112 ant1.widget = "radio"
113 ant1.orientation = "horizontal"
114 ant1:depends("diversity", "")
115 ant1:value("0", translate("wifi_auto"))
116 ant1:value("1", translate("wifi_ant1", "Antenna 1"))
117 ant1:value("2", translate("wifi_ant2", "Antenna 2"))
119 ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("wifi_rxantenna"))
120 ant2.widget = "radio"
121 ant2.orientation = "horizontal"
122 ant2:depends("diversity", "")
123 ant2:value("0", translate("wifi_auto"))
124 ant2:value("1", translate("wifi_ant1", "Antenna 1"))
125 ant2:value("2", translate("wifi_ant2", "Antenna 2"))
128 local ant = s:taboption("advanced", ListValue, "antenna", translate("wifi_txantenna"))
130 ant:value("vertical")
131 ant:value("horizontal")
132 ant:value("external")
135 s:taboption("advanced", Value, "distance", translate("wifi_distance"),
136 translate("wifi_distance_desc"))
137 s:taboption("advanced", Value, "regdomain", translate("wifi_regdomain"))
138 s:taboption("advanced", Value, "country", translate("wifi_country"))
139 s:taboption("advanced", Flag, "outdoor", translate("wifi_outdoor"))
141 --s:option(Flag, "nosbeacon", translate("wifi_nosbeacon"))
146 ------------------- Broadcom Device ------------------
148 if hwtype == "broadcom" then
149 tp = s:taboption("general",
150 (#tx_powers > 0) and ListValue or Value,
151 "txpower", translate("a_w_txpwr"), "dBm")
154 for _, p in ipairs(iw.txpwrlist) do
155 tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
158 mp = s:taboption("macfilter", ListValue, "macfilter", translate("wifi_macpolicy"))
159 mp:value("", translate("disable"))
160 mp:value("allow", translate("wifi_whitelist"))
161 mp:value("deny", translate("wifi_blacklist"))
162 ml = s:taboption("macfilter", DynamicList, "maclist", translate("wifi_maclist"))
163 ml:depends({macfilter="allow"})
164 ml:depends({macfilter="deny"})
166 ant1 = s:taboption("advanced", ListValue, "txantenna", translate("wifi_txantenna"))
167 ant1.widget = "radio"
168 ant1:depends("diversity", "")
169 ant1:value("3", translate("wifi_auto"))
170 ant1:value("0", translate("wifi_ant1", "Antenna 1"))
171 ant1:value("1", translate("wifi_ant2", "Antenna 2"))
173 ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("wifi_rxantenna"))
174 ant2.widget = "radio"
175 ant2:depends("diversity", "")
176 ant2:value("3", translate("wifi_auto"))
177 ant2:value("0", translate("wifi_ant1", "Antenna 1"))
178 ant2:value("1", translate("wifi_ant2", "Antenna 2"))
180 s:taboption("advanced", Flag, "frameburst", translate("wifi_bursting"))
182 s:taboption("advanced", Value, "distance", translate("wifi_distance"))
183 --s:option(Value, "slottime", translate("wifi_slottime"))
185 s:taboption("advanced", Value, "country", translate("wifi_country"))
186 s:taboption("advanced", Value, "maxassoc", translate("wifi_maxassoc"))
190 --------------------- HostAP Device ---------------------
192 if hwtype == "prism2" then
193 s:taboption("advanced", Value, "txpower", translate("a_w_txpwr"), "att units").rmempty = true
195 s:taboption("advanced", Flag, "diversity", translate("wifi_diversity")).rmempty = false
197 s:taboption("advanced", Value, "txantenna", translate("wifi_txantenna"))
198 s:taboption("advanced", Value, "rxantenna", translate("wifi_rxantenna"))
202 ----------------------- Interface -----------------------
204 s = m:section(NamedSection, arg[2], "wifi-iface", translate("interfaces"))
207 s.defaults.device = arg[1]
209 s:tab("general", translate("a_w_general", "General Setup"))
210 s:tab("encryption", translate("a_w_security", "Wireless Security"))
211 s:tab("macfilter", translate("a_w_macfilter", "MAC-Filter"))
212 s:tab("advanced", translate("a_w_advanced", "Advanced Settings"))
214 s:taboption("general", Value, "ssid", translate("wifi_essid"))
216 mode = s:taboption("general", ListValue, "mode", translate("mode"))
217 mode.override_values = true
218 mode:value("ap", translate("a_w_ap"))
219 mode:value("sta", translate("a_w_client"))
220 mode:value("adhoc", translate("a_w_adhoc"))
222 bssid = s:taboption("general", Value, "bssid", translate("wifi_bssid"))
224 network = s:taboption("general", Value, "network", translate("network"), translate("a_w_network1"))
225 network.rmempty = true
226 network.template = "cbi/network_netlist"
227 network.widget = "radio"
229 function network.write(self, section, value)
230 local i = nw:get_interface(section)
233 value = m:formvalue(self:cbid(section) .. ".newnet")
234 if value and #value > 0 then
235 local n = nw:add_network(value, {type="bridge", proto="none"})
236 if n then n:add_interface(i) end
238 local n = i:get_network()
239 if n then n:del_interface(i) end
242 local n = nw:get_network(value)
251 -------------------- MAC80211 Interface ----------------------
253 if hwtype == "mac80211" then
254 if fs.access("/usr/sbin/iw") then
255 mode:value("mesh", "802.11s")
258 mode:value("ahdemo", translate("a_w_ahdemo"))
259 mode:value("monitor", translate("a_w_monitor"))
260 bssid:depends({mode="adhoc"})
262 s:taboption("advanced", Value, "frag", translate("wifi_frag"))
263 s:taboption("advanced", Value, "rts", translate("wifi_rts"))
268 -------------------- Madwifi Interface ----------------------
270 if hwtype == "atheros" then
271 mode:value("ahdemo", translate("a_w_ahdemo"))
272 mode:value("monitor", translate("a_w_monitor"))
273 mode:value("ap-wds", "%s (%s)" % {translate("a_w_ap"), translate("a_w_wds")})
274 mode:value("sta-wds", "%s (%s)" % {translate("a_w_client"), translate("a_w_wds")})
276 function mode.write(self, section, value)
277 if value == "ap-wds" then
278 ListValue.write(self, section, "ap")
279 m.uci:set("wireless", section, "wds", 1)
280 elseif value == "sta-wds" then
281 ListValue.write(self, section, "sta")
282 m.uci:set("wireless", section, "wds", 1)
284 ListValue.write(self, section, value)
285 m.uci:delete("wireless", section, "wds")
289 function mode.cfgvalue(self, section)
290 local mode = ListValue.cfgvalue(self, section)
291 local wds = m.uci:get("wireless", section, "wds") == "1"
293 if mode == "ap" and wds then
295 elseif mode == "sta" and wds then
302 bssid:depends({mode="adhoc"})
303 bssid:depends({mode="ahdemo"})
305 wdssep = s:taboption("advanced", Flag, "wdssep", translate("wifi_wdssep"))
306 wdssep:depends({mode="ap-wds"})
308 s:taboption("advanced", Flag, "doth", "802.11h")
309 hidden = s:taboption("general", Flag, "hidden", translate("wifi_hidden"))
310 hidden:depends({mode="ap"})
311 hidden:depends({mode="adhoc"})
312 hidden:depends({mode="ap-wds"})
313 hidden:depends({mode="sta-wds"})
314 isolate = s:taboption("advanced", Flag, "isolate", translate("wifi_isolate"),
315 translate("wifi_isolate_desc"))
316 isolate:depends({mode="ap"})
317 s:taboption("advanced", Flag, "bgscan", translate("wifi_bgscan"))
319 mp = s:taboption("macfilter", ListValue, "macpolicy", translate("wifi_macpolicy"))
320 mp:value("", translate("disable"))
321 mp:value("deny", translate("wifi_whitelist"))
322 mp:value("allow", translate("wifi_blacklist"))
323 ml = s:taboption("macfilter", DynamicList, "maclist", translate("wifi_maclist"))
324 ml:depends({macpolicy="allow"})
325 ml:depends({macpolicy="deny"})
327 s:taboption("advanced", Value, "rate", translate("wifi_rate"))
328 s:taboption("advanced", Value, "mcast_rate", translate("wifi_mcast_rate"))
329 s:taboption("advanced", Value, "frag", translate("wifi_frag"))
330 s:taboption("advanced", Value, "rts", translate("wifi_rts"))
331 s:taboption("advanced", Value, "minrate", translate("wifi_minrate"))
332 s:taboption("advanced", Value, "maxrate", translate("wifi_maxrate"))
333 s:taboption("advanced", Flag, "compression", translate("wifi_compression"))
335 s:taboption("advanced", Flag, "bursting", translate("wifi_bursting"))
336 s:taboption("advanced", Flag, "turbo", translate("wifi_turbo"))
337 s:taboption("advanced", Flag, "ff", translate("wifi_ff"))
339 s:taboption("advanced", Flag, "wmm", translate("wifi_wmm"))
340 s:taboption("advanced", Flag, "xr", translate("wifi_xr"))
341 s:taboption("advanced", Flag, "ar", translate("wifi_ar"))
343 local swm = s:taboption("advanced", Flag, "sw_merge", translate("wifi_nosbeacon"))
344 swm:depends({mode="adhoc"})
346 local nos = s:taboption("advanced", Flag, "nosbeacon", translate("wifi_nosbeacon"))
347 nos:depends({mode="sta"})
348 nos:depends({mode="sta-wds"})
350 local probereq = s:taboption("advanced", Flag, "probereq", translate("wifi_noprobereq"))
351 probereq.enabled = "0"
352 probereq.disabled = "1"
356 -------------------- Broadcom Interface ----------------------
358 if hwtype == "broadcom" then
359 mode:value("wds", translate("a_w_wds"))
360 mode:value("monitor", translate("a_w_monitor"))
362 hidden = s:taboption("general", Flag, "hidden", translate("wifi_hidden"))
363 hidden:depends({mode="ap"})
364 hidden:depends({mode="adhoc"})
365 hidden:depends({mode="wds"})
367 isolate = s:taboption("advanced", Flag, "isolate", translate("wifi_isolate"),
368 translate("wifi_isolate_desc"))
369 isolate:depends({mode="ap"})
371 s:taboption("advanced", Flag, "doth", "802.11h")
372 s:taboption("advanced", Flag, "wmm", translate("wifi_wmm"))
374 bssid:depends({mode="wds"})
375 bssid:depends({mode="adhoc"})
379 ----------------------- HostAP Interface ---------------------
381 if hwtype == "prism2" then
382 mode:value("wds", translate("a_w_wds"))
383 mode:value("monitor", translate("a_w_monitor"))
385 hidden = s:taboption("general", Flag, "hidden", translate("wifi_hidden"))
386 hidden:depends({mode="ap"})
387 hidden:depends({mode="adhoc"})
388 hidden:depends({mode="wds"})
390 bssid:depends({mode="sta"})
392 mp = s:taboption("macfilter", ListValue, "macpolicy", translate("wifi_macpolicy"))
393 mp:value("", translate("disable"))
394 mp:value("deny", translate("wifi_whitelist"))
395 mp:value("allow", translate("wifi_blacklist"))
396 ml = s:taboption("macfilter", DynamicList, "maclist", translate("wifi_maclist"))
397 ml:depends({macpolicy="allow"})
398 ml:depends({macpolicy="deny"})
400 s:taboption("advanced", Value, "rate", translate("wifi_rate"))
401 s:taboption("advanced", Value, "frag", translate("wifi_frag"))
402 s:taboption("advanced", Value, "rts", translate("wifi_rts"))
406 ------------------- WiFI-Encryption -------------------
408 encr = s:taboption("encryption", ListValue, "encryption", translate("encryption"))
409 encr.override_values = true
410 encr:depends({mode="ap"})
411 encr:depends({mode="sta"})
412 encr:depends({mode="adhoc"})
413 encr:depends({mode="ahdemo"})
414 encr:depends({mode="ap-wds"})
415 encr:depends({mode="sta-wds"})
416 encr:depends({mode="mesh"})
418 encr:value("none", "No Encryption")
419 encr:value("wep", "WEP")
421 if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
422 local supplicant = fs.access("/usr/sbin/wpa_supplicant")
423 local hostapd = fs.access("/usr/sbin/hostapd")
425 if hostapd and supplicant then
426 encr:value("psk", "WPA-PSK")
427 encr:value("psk2", "WPA2-PSK")
428 encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode")
429 encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
430 encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="sta"})
431 elseif hostapd and not supplicant then
432 encr:value("psk", "WPA-PSK", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
433 encr:value("psk2", "WPA2-PSK", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
434 encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
435 encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="ap-wds"})
436 encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="ap-wds"})
437 encr.description = translate("wifi_wpareq")
438 elseif not hostapd and supplicant then
439 encr:value("psk", "WPA-PSK", {mode="sta"}, {mode="sta-wds"})
440 encr:value("psk2", "WPA2-PSK", {mode="sta"}, {mode="sta-wds"})
441 encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="sta"}, {mode="sta-wds"})
442 encr:value("wpa", "WPA-EAP", {mode="sta"}, {mode="sta-wds"})
443 encr:value("wpa2", "WPA2-EAP", {mode="sta"}, {mode="sta-wds"})
444 encr.description = translate("wifi_wpareq")
446 encr.description = translate("wifi_wpareq")
448 elseif hwtype == "broadcom" then
449 encr:value("psk", "WPA-PSK")
450 encr:value("psk2", "WPA2-PSK")
451 encr:value("psk+psk2", "WPA-PSK/WPA2-PSK Mixed Mode")
454 encr:depends("mode", "ap")
455 encr:depends("mode", "sta")
456 encr:depends("mode", "ap-wds")
457 encr:depends("mode", "sta-wds")
458 encr:depends("mode", "wds")
460 server = s:taboption("encryption", Value, "server", translate("a_w_radiussrv"))
461 server:depends({mode="ap", encryption="wpa"})
462 server:depends({mode="ap", encryption="wpa2"})
463 server.rmempty = true
465 port = s:taboption("encryption", Value, "port", translate("a_w_radiusport"))
466 port:depends({mode="ap", encryption="wpa"})
467 port:depends({mode="ap", encryption="wpa2"})
470 key = s:taboption("encryption", Value, "key", translate("key"))
471 key:depends("encryption", "wep")
472 key:depends("encryption", "psk")
473 key:depends("encryption", "psk2")
474 key:depends("encryption", "psk+psk2")
475 key:depends("encryption", "psk-mixed")
476 key:depends({mode="ap", encryption="wpa"})
477 key:depends({mode="ap", encryption="wpa2"})
481 if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
482 nasid = s:taboption("encryption", Value, "nasid", translate("a_w_nasid"))
483 nasid:depends({mode="ap", encryption="wpa"})
484 nasid:depends({mode="ap", encryption="wpa2"})
487 eaptype = s:taboption("encryption", ListValue, "eap_type", translate("a_w_eaptype"))
489 eaptype:value("TTLS")
490 eaptype:value("PEAP")
491 eaptype:depends({mode="sta", encryption="wpa"})
492 eaptype:depends({mode="sta", encryption="wpa2"})
494 cacert = s:taboption("encryption", FileUpload, "ca_cert", translate("a_w_cacert"))
495 cacert:depends({mode="sta", encryption="wpa"})
496 cacert:depends({mode="sta", encryption="wpa2"})
498 privkey = s:taboption("encryption", FileUpload, "priv_key", translate("a_w_tlsprivkey"))
499 privkey:depends({mode="sta", eap_type="TLS", encryption="wpa2"})
500 privkey:depends({mode="sta", eap_type="TLS", encryption="wpa"})
502 privkeypwd = s:taboption("encryption", Value, "priv_key_pwd", translate("a_w_tlsprivkeypwd"))
503 privkeypwd:depends({mode="sta", eap_type="TLS", encryption="wpa2"})
504 privkeypwd:depends({mode="sta", eap_type="TLS", encryption="wpa"})
507 auth = s:taboption("encryption", Value, "auth", translate("a_w_peapauth"))
511 auth:value("MSCHAPV2")
512 auth:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
513 auth:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
514 auth:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
515 auth:depends({mode="sta", eap_type="TTLS", encryption="wpa"})
518 identity = s:taboption("encryption", Value, "identity", translate("a_w_peapidentity"))
519 identity:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
520 identity:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
521 identity:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
522 identity:depends({mode="sta", eap_type="TTLS", encryption="wpa"})
524 password = s:taboption("encryption", Value, "password", translate("a_w_peappassword"))
525 password:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
526 password:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
527 password:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
528 password:depends({mode="sta", eap_type="TTLS", encryption="wpa"})