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 fs = require "nixio.fs"
20 m = Map("wireless", translate("networks"), translate("a_w_networks1"))
26 m.uci:foreach("wireless", "wifi-iface",
28 if s.device == arg[1] and not iw then
29 iw = luci.sys.wifi.getiwinfo(s.ifname or s.device)
30 tx_powers = iw.txpwrlist or { }
34 s = m:section(NamedSection, arg[1], "wifi-device", translate("device") .. " " .. arg[1])
37 s:tab("general", translate("a_w_general", "General Setup"))
38 s:tab("macfilter", translate("a_w_macfilter", "MAC-Filter"))
39 s:tab("advanced", translate("a_w_advanced", "Advanced Settings"))
42 back = s:option(DummyValue, "_overview", translate("overview"))
44 back.titleref = luci.dispatcher.build_url("admin", "network", "wireless")
47 en = s:taboption("general", Flag, "disabled", translate("enable"))
52 function en.cfgvalue(self, section)
53 return Flag.cfgvalue(self, section) or "0"
56 s:taboption("general", DummyValue, "type", translate("type"))
58 local hwtype = m:get(arg[1], "type")
60 local nsantenna = m:get(arg[1], "antenna")
62 ch = s:taboption("general", Value, "channel", translate("a_w_channel"))
63 ch:value("auto", translate("wifi_auto"))
64 for c, f in luci.util.kspairs(luci.sys.wifi.channels()) do
65 ch:value(c, "%i (%.3f GHz)" %{ c, f })
69 ------------------- MAC80211 Device ------------------
71 if hwtype == "mac80211" then
72 tp = s:taboption("general",
73 (tx_powers and #tx_powers > 0) and ListValue or Value,
74 "txpower", translate("a_w_txpwr"), "dBm")
77 for _, p in ipairs(iw and iw.txpwrlist or {}) do
78 tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
83 ------------------- Madwifi Device ------------------
85 if hwtype == "atheros" then
86 tp = s:taboption("general",
87 (#tx_powers > 0) and ListValue or Value,
88 "txpower", translate("a_w_txpwr"), "dBm")
91 for _, p in ipairs(iw.txpwrlist) do
92 tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
95 mode = s:taboption("advanced", ListValue, "hwmode", translate("mode"))
96 mode:value("", translate("wifi_auto"))
97 mode:value("11b", "802.11b")
98 mode:value("11g", "802.11g")
99 mode:value("11a", "802.11a")
100 mode:value("11bg", "802.11b+g")
101 mode:value("11gst", "802.11g + Turbo")
102 mode:value("11ast", "802.11a + Turbo")
103 mode:value("fh", translate("wifi_fh"))
105 s:taboption("advanced", Flag, "diversity", translate("wifi_diversity")).rmempty = false
107 if not nsantenna then
108 ant1 = s:taboption("advanced", ListValue, "txantenna", translate("wifi_txantenna"))
109 ant1.widget = "radio"
110 ant1.orientation = "horizontal"
111 ant1:depends("diversity", "")
112 ant1:value("0", translate("wifi_auto"))
113 ant1:value("1", translate("wifi_ant1", "Antenna 1"))
114 ant1:value("2", translate("wifi_ant2", "Antenna 2"))
116 ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("wifi_rxantenna"))
117 ant2.widget = "radio"
118 ant2.orientation = "horizontal"
119 ant2:depends("diversity", "")
120 ant2:value("0", translate("wifi_auto"))
121 ant2:value("1", translate("wifi_ant1", "Antenna 1"))
122 ant2:value("2", translate("wifi_ant2", "Antenna 2"))
125 local ant = s:taboption("advanced", ListValue, "antenna", translate("wifi_txantenna"))
127 ant:value("vertical")
128 ant:value("horizontal")
129 ant:value("external")
132 s:taboption("advanced", Value, "distance", translate("wifi_distance"),
133 translate("wifi_distance_desc"))
134 s:taboption("advanced", Value, "regdomain", translate("wifi_regdomain"))
135 s:taboption("advanced", Value, "country", translate("wifi_country"))
136 s:taboption("advanced", Flag, "outdoor", translate("wifi_outdoor"))
138 --s:option(Flag, "nosbeacon", translate("wifi_nosbeacon"))
143 ------------------- Broadcom Device ------------------
145 if hwtype == "broadcom" then
146 tp = s:taboption("general",
147 (#tx_powers > 0) and ListValue or Value,
148 "txpower", translate("a_w_txpwr"), "dBm")
151 for _, p in ipairs(iw.txpwrlist) do
152 tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
155 mp = s:taboption("macfilter", ListValue, "macfilter", translate("wifi_macpolicy"))
156 mp:value("", translate("disable"))
157 mp:value("allow", translate("wifi_whitelist"))
158 mp:value("deny", translate("wifi_blacklist"))
159 ml = s:taboption("macfilter", DynamicList, "maclist", translate("wifi_maclist"))
160 ml:depends({macfilter="allow"})
161 ml:depends({macfilter="deny"})
163 ant1 = s:taboption("advanced", ListValue, "txantenna", translate("wifi_txantenna"))
164 ant1.widget = "radio"
165 ant1:depends("diversity", "")
166 ant1:value("3", translate("wifi_auto"))
167 ant1:value("0", translate("wifi_ant1", "Antenna 1"))
168 ant1:value("1", translate("wifi_ant2", "Antenna 2"))
170 ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("wifi_rxantenna"))
171 ant2.widget = "radio"
172 ant2:depends("diversity", "")
173 ant2:value("3", translate("wifi_auto"))
174 ant2:value("0", translate("wifi_ant1", "Antenna 1"))
175 ant2:value("1", translate("wifi_ant2", "Antenna 2"))
177 s:taboption("advanced", Flag, "frameburst", translate("wifi_bursting"))
179 s:taboption("advanced", Value, "distance", translate("wifi_distance"))
180 --s:option(Value, "slottime", translate("wifi_slottime"))
182 s:taboption("advanced", Value, "country", translate("wifi_country"))
183 s:taboption("advanced", Value, "maxassoc", translate("wifi_maxassoc"))
187 --------------------- HostAP Device ---------------------
189 if hwtype == "prism2" then
190 s:taboption("advanced", Value, "txpower", translate("a_w_txpwr"), "att units").rmempty = true
192 s:taboption("advanced", Flag, "diversity", translate("wifi_diversity")).rmempty = false
194 s:taboption("advanced", Value, "txantenna", translate("wifi_txantenna"))
195 s:taboption("advanced", Value, "rxantenna", translate("wifi_rxantenna"))
199 ----------------------- Interface -----------------------
201 s = m:section(TypedSection, "wifi-iface", translate("interfaces"))
202 s.addremove = (iw and iw.mbssid_support) and true or false
204 s:depends("device", arg[1])
205 s.defaults.device = arg[1]
207 s:tab("general", translate("a_w_general", "General Setup"))
208 s:tab("encryption", translate("a_w_security", "Wireless Security"))
209 s:tab("macfilter", translate("a_w_macfilter", "MAC-Filter"))
210 s:tab("advanced", translate("a_w_advanced", "Advanced Settings"))
212 s:taboption("general", Value, "ssid", translate("wifi_essid"))
214 mode = s:taboption("general", ListValue, "mode", translate("mode"))
215 mode.override_values = true
216 mode:value("ap", translate("a_w_ap"))
217 mode:value("sta", translate("a_w_client"))
218 mode:value("adhoc", translate("a_w_adhoc"))
220 bssid = s:taboption("general", Value, "bssid", translate("wifi_bssid"))
222 network = s:taboption("general", Value, "network", translate("network"), translate("a_w_network1"))
223 network.rmempty = true
225 network.combobox_manual = translate("a_w_netmanual")
226 wa.cbi_add_networks(network)
228 function network.write(self, section, value)
229 if not m.uci:get("network", value) then
230 -- avoid "value not defined in enum" because network is not known yet
231 s.override_scheme = true
234 m.uci:set("network", value, "interface")
235 Value.write(self, section, value)
237 if m.uci:get("network", value) == "interface" then
238 Value.write(self, section, value)
244 -------------------- MAC80211 Interface ----------------------
246 if hwtype == "mac80211" then
247 if fs.access("/usr/sbin/iw") then
248 mode:value("mesh", "802.11s")
251 mode:value("ahdemo", translate("a_w_ahdemo"))
252 mode:value("monitor", translate("a_w_monitor"))
253 bssid:depends({mode="adhoc"})
255 s:taboption("advanced", Value, "frag", translate("wifi_frag"))
256 s:taboption("advanced", Value, "rts", translate("wifi_rts"))
261 -------------------- Madwifi Interface ----------------------
263 if hwtype == "atheros" then
264 mode:value("ahdemo", translate("a_w_ahdemo"))
265 mode:value("monitor", translate("a_w_monitor"))
266 mode:value("ap-wds", "%s (%s)" % {translate("a_w_ap"), translate("a_w_wds")})
267 mode:value("sta-wds", "%s (%s)" % {translate("a_w_client"), translate("a_w_wds")})
269 function mode.write(self, section, value)
270 if value == "ap-wds" then
271 ListValue.write(self, section, "ap")
272 m.uci:set("wireless", section, "wds", 1)
273 elseif value == "sta-wds" then
274 ListValue.write(self, section, "sta")
275 m.uci:set("wireless", section, "wds", 1)
277 ListValue.write(self, section, value)
278 m.uci:delete("wireless", section, "wds")
282 function mode.cfgvalue(self, section)
283 local mode = ListValue.cfgvalue(self, section)
284 local wds = m.uci:get("wireless", section, "wds") == "1"
286 if mode == "ap" and wds then
288 elseif mode == "sta" and wds then
295 bssid:depends({mode="adhoc"})
296 bssid:depends({mode="ahdemo"})
298 wdssep = s:taboption("advanced", Flag, "wdssep", translate("wifi_wdssep"))
299 wdssep:depends({mode="ap-wds"})
301 s:taboption("advanced", Flag, "doth", "802.11h")
302 hidden = s:taboption("general", Flag, "hidden", translate("wifi_hidden"))
303 hidden:depends({mode="ap"})
304 hidden:depends({mode="adhoc"})
305 hidden:depends({mode="ap-wds"})
306 hidden:depends({mode="sta-wds"})
307 isolate = s:taboption("advanced", Flag, "isolate", translate("wifi_isolate"),
308 translate("wifi_isolate_desc"))
309 isolate:depends({mode="ap"})
310 s:taboption("advanced", Flag, "bgscan", translate("wifi_bgscan"))
312 mp = s:taboption("macfilter", ListValue, "macpolicy", translate("wifi_macpolicy"))
313 mp:value("", translate("disable"))
314 mp:value("deny", translate("wifi_whitelist"))
315 mp:value("allow", translate("wifi_blacklist"))
316 ml = s:taboption("macfilter", DynamicList, "maclist", translate("wifi_maclist"))
317 ml:depends({macpolicy="allow"})
318 ml:depends({macpolicy="deny"})
320 s:taboption("advanced", Value, "rate", translate("wifi_rate"))
321 s:taboption("advanced", Value, "mcast_rate", translate("wifi_mcast_rate"))
322 s:taboption("advanced", Value, "frag", translate("wifi_frag"))
323 s:taboption("advanced", Value, "rts", translate("wifi_rts"))
324 s:taboption("advanced", Value, "minrate", translate("wifi_minrate"))
325 s:taboption("advanced", Value, "maxrate", translate("wifi_maxrate"))
326 s:taboption("advanced", Flag, "compression", translate("wifi_compression"))
328 s:taboption("advanced", Flag, "bursting", translate("wifi_bursting"))
329 s:taboption("advanced", Flag, "turbo", translate("wifi_turbo"))
330 s:taboption("advanced", Flag, "ff", translate("wifi_ff"))
332 s:taboption("advanced", Flag, "wmm", translate("wifi_wmm"))
333 s:taboption("advanced", Flag, "xr", translate("wifi_xr"))
334 s:taboption("advanced", Flag, "ar", translate("wifi_ar"))
336 local swm = s:taboption("advanced", Flag, "sw_merge", translate("wifi_nosbeacon"))
337 swm:depends({mode="adhoc"})
339 local nos = s:taboption("advanced", Flag, "nosbeacon", translate("wifi_nosbeacon"))
340 nos:depends({mode="sta"})
341 nos:depends({mode="sta-wds"})
343 local probereq = s:taboption("advanced", Flag, "probereq", translate("wifi_noprobereq"))
344 probereq.enabled = "0"
345 probereq.disabled = "1"
349 -------------------- Broadcom Interface ----------------------
351 if hwtype == "broadcom" then
352 mode:value("wds", translate("a_w_wds"))
353 mode:value("monitor", translate("a_w_monitor"))
355 hidden = s:taboption("general", Flag, "hidden", translate("wifi_hidden"))
356 hidden:depends({mode="ap"})
357 hidden:depends({mode="adhoc"})
358 hidden:depends({mode="wds"})
360 isolate = s:taboption("advanced", Flag, "isolate", translate("wifi_isolate"),
361 translate("wifi_isolate_desc"))
362 isolate:depends({mode="ap"})
364 s:taboption("advanced", Flag, "doth", "802.11h")
365 s:taboption("advanced", Flag, "wmm", translate("wifi_wmm"))
367 bssid:depends({mode="wds"})
368 bssid:depends({mode="adhoc"})
372 ----------------------- HostAP Interface ---------------------
374 if hwtype == "prism2" then
375 mode:value("wds", translate("a_w_wds"))
376 mode:value("monitor", translate("a_w_monitor"))
378 hidden = s:taboption("general", Flag, "hidden", translate("wifi_hidden"))
379 hidden:depends({mode="ap"})
380 hidden:depends({mode="adhoc"})
381 hidden:depends({mode="wds"})
383 bssid:depends({mode="sta"})
385 mp = s:taboption("macfilter", ListValue, "macpolicy", translate("wifi_macpolicy"))
386 mp:value("", translate("disable"))
387 mp:value("deny", translate("wifi_whitelist"))
388 mp:value("allow", translate("wifi_blacklist"))
389 ml = s:taboption("macfilter", DynamicList, "maclist", translate("wifi_maclist"))
390 ml:depends({macpolicy="allow"})
391 ml:depends({macpolicy="deny"})
393 s:taboption("advanced", Value, "rate", translate("wifi_rate"))
394 s:taboption("advanced", Value, "frag", translate("wifi_frag"))
395 s:taboption("advanced", Value, "rts", translate("wifi_rts"))
399 ------------------- WiFI-Encryption -------------------
401 encr = s:taboption("encryption", ListValue, "encryption", translate("encryption"))
402 encr.override_values = true
403 encr:depends({mode="ap"})
404 encr:depends({mode="sta"})
405 encr:depends({mode="adhoc"})
406 encr:depends({mode="ahdemo"})
407 encr:depends({mode="ap-wds"})
408 encr:depends({mode="sta-wds"})
409 encr:depends({mode="mesh"})
411 encr:value("none", "No Encryption")
412 encr:value("wep", "WEP")
414 if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
415 local supplicant = fs.access("/usr/sbin/wpa_supplicant")
416 local hostapd = fs.access("/usr/sbin/hostapd")
418 if hostapd and supplicant then
419 encr:value("psk", "WPA-PSK")
420 encr:value("psk2", "WPA2-PSK")
421 encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode")
422 encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
423 encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="sta"})
424 elseif hostapd and not supplicant then
425 encr:value("psk", "WPA-PSK", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
426 encr:value("psk2", "WPA2-PSK", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
427 encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
428 encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="ap-wds"})
429 encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="ap-wds"})
430 encr.description = translate("wifi_wpareq")
431 elseif not hostapd and supplicant then
432 encr:value("psk", "WPA-PSK", {mode="sta"}, {mode="sta-wds"})
433 encr:value("psk2", "WPA2-PSK", {mode="sta"}, {mode="sta-wds"})
434 encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="sta"}, {mode="sta-wds"})
435 encr:value("wpa", "WPA-EAP", {mode="sta"}, {mode="sta-wds"})
436 encr:value("wpa2", "WPA2-EAP", {mode="sta"}, {mode="sta-wds"})
437 encr.description = translate("wifi_wpareq")
439 encr.description = translate("wifi_wpareq")
441 elseif hwtype == "broadcom" then
442 encr:value("psk", "WPA-PSK")
443 encr:value("psk2", "WPA2-PSK")
444 encr:value("psk+psk2", "WPA-PSK/WPA2-PSK Mixed Mode")
447 encr:depends("mode", "ap")
448 encr:depends("mode", "sta")
449 encr:depends("mode", "ap-wds")
450 encr:depends("mode", "sta-wds")
451 encr:depends("mode", "wds")
453 server = s:taboption("encryption", Value, "server", translate("a_w_radiussrv"))
454 server:depends({mode="ap", encryption="wpa"})
455 server:depends({mode="ap", encryption="wpa2"})
456 server.rmempty = true
458 port = s:taboption("encryption", Value, "port", translate("a_w_radiusport"))
459 port:depends({mode="ap", encryption="wpa"})
460 port:depends({mode="ap", encryption="wpa2"})
463 key = s:taboption("encryption", Value, "key", translate("key"))
464 key:depends("encryption", "wep")
465 key:depends("encryption", "psk")
466 key:depends("encryption", "psk2")
467 key:depends("encryption", "psk+psk2")
468 key:depends("encryption", "psk-mixed")
469 key:depends({mode="ap", encryption="wpa"})
470 key:depends({mode="ap", encryption="wpa2"})
474 if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
475 nasid = s:taboption("encryption", Value, "nasid", translate("a_w_nasid"))
476 nasid:depends({mode="ap", encryption="wpa"})
477 nasid:depends({mode="ap", encryption="wpa2"})
480 eaptype = s:taboption("encryption", ListValue, "eap_type", translate("a_w_eaptype"))
482 eaptype:value("TTLS")
483 eaptype:value("PEAP")
484 eaptype:depends({mode="sta", encryption="wpa"})
485 eaptype:depends({mode="sta", encryption="wpa2"})
487 cacert = s:taboption("encryption", FileUpload, "ca_cert", translate("a_w_cacert"))
488 cacert:depends({mode="sta", encryption="wpa"})
489 cacert:depends({mode="sta", encryption="wpa2"})
491 privkey = s:taboption("encryption", FileUpload, "priv_key", translate("a_w_tlsprivkey"))
492 privkey:depends({mode="sta", eap_type="TLS", encryption="wpa2"})
493 privkey:depends({mode="sta", eap_type="TLS", encryption="wpa"})
495 privkeypwd = s:taboption("encryption", Value, "priv_key_pwd", translate("a_w_tlsprivkeypwd"))
496 privkeypwd:depends({mode="sta", eap_type="TLS", encryption="wpa2"})
497 privkeypwd:depends({mode="sta", eap_type="TLS", encryption="wpa"})
500 auth = s:taboption("encryption", Value, "auth", translate("a_w_peapauth"))
504 auth:value("MSCHAPV2")
505 auth:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
506 auth:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
507 auth:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
508 auth:depends({mode="sta", eap_type="TTLS", encryption="wpa"})
511 identity = s:taboption("encryption", Value, "identity", translate("a_w_peapidentity"))
512 identity:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
513 identity:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
514 identity:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
515 identity:depends({mode="sta", eap_type="TTLS", encryption="wpa"})
517 password = s:taboption("encryption", Value, "password", translate("a_w_peappassword"))
518 password:depends({mode="sta", eap_type="PEAP", encryption="wpa2"})
519 password:depends({mode="sta", eap_type="PEAP", encryption="wpa"})
520 password:depends({mode="sta", eap_type="TTLS", encryption="wpa2"})
521 password:depends({mode="sta", eap_type="TTLS", encryption="wpa"})