wifi.lua 26.3 KB
Newer Older
S
Steven Barth 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
--[[
LuCI - Lua Configuration Interface

Copyright 2008 Steven Barth <steven@midlink.org>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

$Id$
]]--
14 15

local wa = require "luci.tools.webadmin"
16
local nw = require "luci.model.network"
17 18
local fs = require "nixio.fs"

19 20
arg[1] = arg[1] or ""

21 22 23 24 25 26
m = Map("wireless", "",
	translate("The <em>Device Configuration</em> section covers physical settings of the radio " ..
		"hardware such as channel, transmit power or antenna selection which is shared among all " ..
		"defined wireless networks (if the radio hardware is multi-SSID capable). Per network settings " ..
		"like encryption or operation mode are grouped in the <em>Interface Configuration</em>."))

27
m:chain("network")
28 29 30 31

local ifsection

function m.on_commit(map)
32
	local wnet = nw:get_wifinet(arg[1])
33 34
	if ifsection and wnet then
		ifsection.section = wnet.sid
35
		m.title = luci.util.pcdata(wnet:get_i18n())
36 37 38
	end
end

39
nw.init(m.uci)
40

41 42
local wnet = nw:get_wifinet(arg[1])
local wdev = wnet and wnet:get_device()
43 44

-- redirect to overview page if network does not exist anymore (e.g. after a revert)
45
if not wnet or not wdev then
46 47 48 49
	luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
	return
end

50
m.title = luci.util.pcdata(wnet:get_i18n())
51

52

53
local iw = luci.sys.wifi.getiwinfo(arg[1])
54
local hw_modes  = iw.hwmodelist or { }
55 56 57 58 59
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)
)
60

61
s = m:section(NamedSection, wdev:name(), "wifi-device", translate("Device Configuration"))
62
s.addremove = false
63

64 65 66
s:tab("general", translate("General Setup"))
s:tab("macfilter", translate("MAC-Filter"))
s:tab("advanced", translate("Advanced Settings"))
67 68

--[[
69
back = s:option(DummyValue, "_overview", translate("Overview"))
70 71
back.value = ""
back.titleref = luci.dispatcher.build_url("admin", "network", "wireless")
72
]]
73

74 75
st = s:taboption("general", DummyValue, "__status", translate("Status"))
st.template = "admin_network/wifi_status"
76
st.ifname   = arg[1]
77 78

en = s:taboption("general", Flag, "disabled", translate("Enable device"))
79 80
en.enabled = "0"
en.disabled = "1"
S
Steven Barth 已提交
81
en.rmempty = false
82 83 84 85 86

function en.cfgvalue(self, section)
	return Flag.cfgvalue(self, section) or "0"
end

87

88 89
local hwtype = wdev:get("type")
local htcaps = wdev:get("ht_capab") and true or false
90

91
-- NanoFoo
92
local nsantenna = wdev:get("antenna")
93

94 95
ch = s:taboption("general", Value, "channel", translate("Channel"))
ch:value("auto", translate("auto"))
96
for _, f in ipairs(iw and iw.freqlist or luci.sys.wifi.channels()) do
97 98 99
	if not f.restricted then
		ch:value(f.channel, "%i (%.3f GHz)" %{ f.channel, f.mhz / 1000 })
	end
100
end
101

102

103
------------------- MAC80211 Device ------------------
104

105
if hwtype == "mac80211" then
106
	tp = s:taboption("general",
107
		(tx_powers and #tx_powers > 0) and ListValue or Value,
108
		"txpower", translate("Transmit Power"), "dBm")
109 110

	tp.rmempty = true
111
	tp.default = tx_power
112
	for _, p in ipairs(tx_powers or {}) do
113 114
		tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
	end
115

116 117
	mode = s:taboption("advanced", ListValue, "hwmode", translate("Mode"))
	mode:value("", translate("auto"))
118 119 120
	if hw_modes.b then mode:value("11b", "802.11b") end
	if hw_modes.g then mode:value("11g", "802.11g") end
	if hw_modes.a then mode:value("11a", "802.11a") end
121

122
	if htcaps then
123 124
		if hw_modes.g and hw_modes.n then mode:value("11ng", "802.11g+n") end
		if hw_modes.a and hw_modes.n then mode:value("11na", "802.11a+n") end
125

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
		htmode = s:taboption("advanced", ListValue, "htmode", translate("HT mode"))
		htmode:depends("hwmode", "11na")
		htmode:depends("hwmode", "11ng")
		htmode:value("HT20", "20MHz")
		htmode:value("HT40-", translate("40MHz 2nd channel below"))
		htmode:value("HT40+", translate("40MHz 2nd channel above"))

		--htcapab = s:taboption("advanced", DynamicList, "ht_capab", translate("HT capabilities"))
		--htcapab:depends("hwmode", "11na")
		--htcapab:depends("hwmode", "11ng")
	end

	local cl = iw and iw.countrylist
	if cl and #cl > 0 then
		cc = s:taboption("advanced", ListValue, "country", translate("Country Code"), translate("Use ISO/IEC 3166 alpha2 country codes."))
		cc.default = tostring(iw and iw.country or "00")
		for _, c in ipairs(cl) do
			cc:value(c.alpha2, "%s - %s" %{ c.alpha2, c.name })
		end
	else
		s:taboption("advanced", Value, "country", translate("Country Code"), translate("Use ISO/IEC 3166 alpha2 country codes."))
	end
148

149
	s:taboption("advanced", Value, "distance", translate("Distance Optimization"),
150
		translate("Distance to farthest network member in meters."))
151
end
152

153 154 155 156

------------------- Madwifi Device ------------------

if hwtype == "atheros" then
157 158
	tp = s:taboption("general",
		(#tx_powers > 0) and ListValue or Value,
159
		"txpower", translate("Transmit Power"), "dBm")
160 161

	tp.rmempty = true
162 163
	tp.default = tx_power
	for _, p in ipairs(tx_powers or {}) do
164 165
		tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
	end
166

167 168
	mode = s:taboption("advanced", ListValue, "hwmode", translate("Mode"))
	mode:value("", translate("auto"))
169 170 171 172 173 174
	if hw_modes.b then mode:value("11b", "802.11b") end
	if hw_modes.g then mode:value("11g", "802.11g") end
	if hw_modes.a then mode:value("11a", "802.11a") end
	if hw_modes.g then mode:value("11bg", "802.11b+g") end
	if hw_modes.g then mode:value("11gst", "802.11g + Turbo") end
	if hw_modes.a then mode:value("11ast", "802.11a + Turbo") end
175
	mode:value("fh", translate("Frequency Hopping"))
J
Jo-Philipp Wich 已提交
176

177
	s:taboption("advanced", Flag, "diversity", translate("Diversity")).rmempty = false
178 179

	if not nsantenna then
180
		ant1 = s:taboption("advanced", ListValue, "txantenna", translate("Transmitter Antenna"))
181
		ant1.widget = "radio"
182
		ant1.orientation = "horizontal"
183
		ant1:depends("diversity", "")
184 185 186
		ant1:value("0", translate("auto"))
		ant1:value("1", translate("Antenna 1"))
		ant1:value("2", translate("Antenna 2"))
187

188
		ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("Receiver Antenna"))
189
		ant2.widget = "radio"
190
		ant2.orientation = "horizontal"
191
		ant2:depends("diversity", "")
192 193 194
		ant2:value("0", translate("auto"))
		ant2:value("1", translate("Antenna 1"))
		ant2:value("2", translate("Antenna 2"))
195

196
	else -- NanoFoo
197
		local ant = s:taboption("advanced", ListValue, "antenna", translate("Transmitter Antenna"))
198 199 200 201 202
		ant:value("auto")
		ant:value("vertical")
		ant:value("horizontal")
		ant:value("external")
	end
203

204 205 206 207 208
	s:taboption("advanced", Value, "distance", translate("Distance Optimization"),
		translate("Distance to farthest network member in meters."))
	s:taboption("advanced", Value, "regdomain", translate("Regulatory Domain"))
	s:taboption("advanced", Value, "country", translate("Country Code"))
	s:taboption("advanced", Flag, "outdoor", translate("Outdoor Channels"))
J
Jo-Philipp Wich 已提交
209

210
	--s:option(Flag, "nosbeacon", translate("Disable HW-Beacon timer"))
211
end
212 213 214



215 216 217
------------------- Broadcom Device ------------------

if hwtype == "broadcom" then
218 219
	tp = s:taboption("general",
		(#tx_powers > 0) and ListValue or Value,
220
		"txpower", translate("Transmit Power"), "dBm")
221 222

	tp.rmempty = true
223 224
	tp.default = tx_power
	for _, p in ipairs(tx_powers or {}) do
225
		tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
226
	end
227

228 229 230 231 232 233
	mode = s:taboption("advanced", ListValue, "hwmode", translate("Mode"))
	mode:value("11bg", "802.11b+g")
	mode:value("11b", "802.11b")
	mode:value("11g", "802.11g")
	mode:value("11gst", "802.11g + Turbo")

234
	ant1 = s:taboption("advanced", ListValue, "txantenna", translate("Transmitter Antenna"))
235 236
	ant1.widget = "radio"
	ant1:depends("diversity", "")
237 238 239
	ant1:value("3", translate("auto"))
	ant1:value("0", translate("Antenna 1"))
	ant1:value("1", translate("Antenna 2"))
240

241
	ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("Receiver Antenna"))
242 243
	ant2.widget = "radio"
	ant2:depends("diversity", "")
244 245 246
	ant2:value("3", translate("auto"))
	ant2:value("0", translate("Antenna 1"))
	ant2:value("1", translate("Antenna 2"))
J
Jo-Philipp Wich 已提交
247

248
	s:taboption("advanced", Flag, "frameburst", translate("Frame Bursting"))
J
Jo-Philipp Wich 已提交
249

250
	s:taboption("advanced", Value, "distance", translate("Distance Optimization"))
251
	--s:option(Value, "slottime", translate("Slot time"))
J
Jo-Philipp Wich 已提交
252

253 254
	s:taboption("advanced", Value, "country", translate("Country Code"))
	s:taboption("advanced", Value, "maxassoc", translate("Connection Limit"))
255 256
end

257

258 259 260
--------------------- HostAP Device ---------------------

if hwtype == "prism2" then
261
	s:taboption("advanced", Value, "txpower", translate("Transmit Power"), "att units").rmempty = true
262

263
	s:taboption("advanced", Flag, "diversity", translate("Diversity")).rmempty = false
264

265 266
	s:taboption("advanced", Value, "txantenna", translate("Transmitter Antenna"))
	s:taboption("advanced", Value, "rxantenna", translate("Receiver Antenna"))
267 268 269
end


S
Steven Barth 已提交
270 271
----------------------- Interface -----------------------

272 273 274 275
s = m:section(NamedSection, wnet.sid, "wifi-iface", translate("Interface Configuration"))
ifsection = s
s.addremove = false
s.anonymous = true
276
s.defaults.device = wdev:name()
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309

s:tab("general", translate("General Setup"))
s:tab("encryption", translate("Wireless Security"))
s:tab("macfilter", translate("MAC-Filter"))
s:tab("advanced", translate("Advanced Settings"))

s:taboption("general", Value, "ssid", translate("<abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))

mode = s:taboption("general", ListValue, "mode", translate("Mode"))
mode.override_values = true
mode:value("ap", translate("Access Point"))
mode:value("sta", translate("Client"))
mode:value("adhoc", translate("Ad-Hoc"))

bssid = s:taboption("general", Value, "bssid", translate("<abbr title=\"Basic Service Set Identifier\">BSSID</abbr>"))

network = s:taboption("general", Value, "network", translate("Network"),
	translate("Choose the network you want to attach to this wireless interface. " ..
		"Select <em>unspecified</em> to not attach any network or fill out the " ..
		"<em>create</em> field to define a new network."))

network.rmempty = true
network.template = "cbi/network_netlist"
network.widget = "radio"

function network.write(self, section, value)
	local i = nw:get_interface(section)
	if i then
		if value == '-' then
			value = m:formvalue(self:cbid(section) .. ".newnet")
			if value and #value > 0 then
				local n = nw:add_network(value, {proto="none"})
				if n then n:add_interface(i) end
310
			else
311 312 313 314 315 316
				local n = i:get_network()
				if n then n:del_interface(i) end
			end
		else
			local n = nw:get_network(value)
			if n then
317
				n:set("type", "bridge")
318
				n:add_interface(i)
319
			end
S
Steven Barth 已提交
320 321
		end
	end
322
end
S
Steven Barth 已提交
323

324
-------------------- MAC80211 Interface ----------------------
325

326 327 328 329
if hwtype == "mac80211" then
	if fs.access("/usr/sbin/iw") then
		mode:value("mesh", "802.11s")
	end
330

331 332 333
	mode:value("ahdemo", translate("Pseudo Ad-Hoc (ahdemo)"))
	mode:value("monitor", translate("Monitor"))
	bssid:depends({mode="adhoc"})
334

335 336
	s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
	s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
J
Jo-Philipp Wich 已提交
337 338 339 340 341 342 343 344 345 346
	
	mp = s:taboption("macfilter", ListValue, "macfilter", translate("MAC-Address Filter"))
	mp:value("", translate("disable"))
	mp:value("allow", translate("Allow listed only"))
	mp:value("deny", translate("Allow all except listed"))

	ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List"))
	ml.datatype = "macaddr"
	ml:depends({macfilter="allow"})
	ml:depends({macfilter="deny"})
347

348 349
	mode:value("ap-wds", "%s (%s)" % {translate("Access Point"), translate("WDS")})
	mode:value("sta-wds", "%s (%s)" % {translate("Client"), translate("WDS")})
350

351 352 353 354 355 356 357 358 359 360
	function mode.write(self, section, value)
		if value == "ap-wds" then
			ListValue.write(self, section, "ap")
			m.uci:set("wireless", section, "wds", 1)
		elseif value == "sta-wds" then
			ListValue.write(self, section, "sta")
			m.uci:set("wireless", section, "wds", 1)
		else
			ListValue.write(self, section, value)
			m.uci:delete("wireless", section, "wds")
361
		end
362
	end
363

364 365 366
	function mode.cfgvalue(self, section)
		local mode = ListValue.cfgvalue(self, section)
		local wds  = m.uci:get("wireless", section, "wds") == "1"
367

368 369 370 371 372 373
		if mode == "ap" and wds then
			return "ap-wds"
		elseif mode == "sta" and wds then
			return "sta-wds"
		else
			return mode
374
		end
375
	end
J
Jo-Philipp Wich 已提交
376

377 378 379 380
	hidden = s:taboption("general", Flag, "hidden", translate("Hide <abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
	hidden:depends({mode="ap"})
	hidden:depends({mode="ap-wds"})
end
J
Jo-Philipp Wich 已提交
381 382 383



384
-------------------- Madwifi Interface ----------------------
S
Steven Barth 已提交
385

386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
if hwtype == "atheros" then
	mode:value("ahdemo", translate("Pseudo Ad-Hoc (ahdemo)"))
	mode:value("monitor", translate("Monitor"))
	mode:value("ap-wds", "%s (%s)" % {translate("Access Point"), translate("WDS")})
	mode:value("sta-wds", "%s (%s)" % {translate("Client"), translate("WDS")})
	mode:value("wds", translate("Static WDS"))

	function mode.write(self, section, value)
		if value == "ap-wds" then
			ListValue.write(self, section, "ap")
			m.uci:set("wireless", section, "wds", 1)
		elseif value == "sta-wds" then
			ListValue.write(self, section, "sta")
			m.uci:set("wireless", section, "wds", 1)
		else
			ListValue.write(self, section, value)
			m.uci:delete("wireless", section, "wds")
403
		end
404
	end
S
Steven Barth 已提交
405

406 407 408
	function mode.cfgvalue(self, section)
		local mode = ListValue.cfgvalue(self, section)
		local wds  = m.uci:get("wireless", section, "wds") == "1"
409

410 411 412 413 414 415
		if mode == "ap" and wds then
			return "ap-wds"
		elseif mode == "sta" and wds then
			return "sta-wds"
		else
			return mode
416 417
		end
	end
J
Jo-Philipp Wich 已提交
418

419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
	bssid:depends({mode="adhoc"})
	bssid:depends({mode="ahdemo"})
	bssid:depends({mode="wds"})

	wdssep = s:taboption("advanced", Flag, "wdssep", translate("Separate WDS"))
	wdssep:depends({mode="ap-wds"})

	s:taboption("advanced", Flag, "doth", "802.11h")
	hidden = s:taboption("general", Flag, "hidden", translate("Hide <abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
	hidden:depends({mode="ap"})
	hidden:depends({mode="adhoc"})
	hidden:depends({mode="ap-wds"})
	hidden:depends({mode="sta-wds"})
	isolate = s:taboption("advanced", Flag, "isolate", translate("Separate Clients"),
	 translate("Prevents client-to-client communication"))
	isolate:depends({mode="ap"})
	s:taboption("advanced", Flag, "bgscan", translate("Background Scan"))

	mp = s:taboption("macfilter", ListValue, "macpolicy", translate("MAC-Address Filter"))
	mp:value("", translate("disable"))
	mp:value("deny", translate("Allow listed only"))
	mp:value("allow", translate("Allow all except listed"))
441

442
	ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List"))
443
	ml.datatype = "macaddr"
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
	ml:depends({macpolicy="allow"})
	ml:depends({macpolicy="deny"})

	s:taboption("advanced", Value, "rate", translate("Transmission Rate"))
	s:taboption("advanced", Value, "mcast_rate", translate("Multicast Rate"))
	s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
	s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
	s:taboption("advanced", Value, "minrate", translate("Minimum Rate"))
	s:taboption("advanced", Value, "maxrate", translate("Maximum Rate"))
	s:taboption("advanced", Flag, "compression", translate("Compression"))

	s:taboption("advanced", Flag, "bursting", translate("Frame Bursting"))
	s:taboption("advanced", Flag, "turbo", translate("Turbo Mode"))
	s:taboption("advanced", Flag, "ff", translate("Fast Frames"))

	s:taboption("advanced", Flag, "wmm", translate("WMM Mode"))
	s:taboption("advanced", Flag, "xr", translate("XR Support"))
	s:taboption("advanced", Flag, "ar", translate("AR Support"))

	local swm = s:taboption("advanced", Flag, "sw_merge", translate("Disable HW-Beacon timer"))
	swm:depends({mode="adhoc"})

	local nos = s:taboption("advanced", Flag, "nosbeacon", translate("Disable HW-Beacon timer"))
	nos:depends({mode="sta"})
	nos:depends({mode="sta-wds"})

	local probereq = s:taboption("advanced", Flag, "probereq", translate("Do not send probe responses"))
	probereq.enabled  = "0"
	probereq.disabled = "1"
end
J
Jo-Philipp Wich 已提交
474

475

476
-------------------- Broadcom Interface ----------------------
S
Steven Barth 已提交
477

478 479 480
if hwtype == "broadcom" then
	mode:value("wds", translate("WDS"))
	mode:value("monitor", translate("Monitor"))
S
Steven Barth 已提交
481

482 483 484 485
	hidden = s:taboption("general", Flag, "hidden", translate("Hide <abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
	hidden:depends({mode="ap"})
	hidden:depends({mode="adhoc"})
	hidden:depends({mode="wds"})
486

487 488 489
	isolate = s:taboption("advanced", Flag, "isolate", translate("Separate Clients"),
	 translate("Prevents client-to-client communication"))
	isolate:depends({mode="ap"})
490

491 492
	s:taboption("advanced", Flag, "doth", "802.11h")
	s:taboption("advanced", Flag, "wmm", translate("WMM Mode"))
493

494 495 496
	bssid:depends({mode="wds"})
	bssid:depends({mode="adhoc"})
end
497

498

499
----------------------- HostAP Interface ---------------------
500

501 502 503
if hwtype == "prism2" then
	mode:value("wds", translate("WDS"))
	mode:value("monitor", translate("Monitor"))
S
Steven Barth 已提交
504

505 506 507 508
	hidden = s:taboption("general", Flag, "hidden", translate("Hide <abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
	hidden:depends({mode="ap"})
	hidden:depends({mode="adhoc"})
	hidden:depends({mode="wds"})
509

510
	bssid:depends({mode="sta"})
511

512 513 514 515 516 517 518
	mp = s:taboption("macfilter", ListValue, "macpolicy", translate("MAC-Address Filter"))
	mp:value("", translate("disable"))
	mp:value("deny", translate("Allow listed only"))
	mp:value("allow", translate("Allow all except listed"))
	ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List"))
	ml:depends({macpolicy="allow"})
	ml:depends({macpolicy="deny"})
519

520 521 522 523
	s:taboption("advanced", Value, "rate", translate("Transmission Rate"))
	s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
	s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
end
J
Jo-Philipp Wich 已提交
524

525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547

------------------- WiFI-Encryption -------------------

encr = s:taboption("encryption", ListValue, "encryption", translate("Encryption"))
encr.override_values = true
encr.override_depends = true
encr:depends({mode="ap"})
encr:depends({mode="sta"})
encr:depends({mode="adhoc"})
encr:depends({mode="ahdemo"})
encr:depends({mode="ap-wds"})
encr:depends({mode="sta-wds"})
encr:depends({mode="mesh"})

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"})

if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
	local supplicant = fs.access("/usr/sbin/wpa_supplicant")
	local hostapd = fs.access("/usr/sbin/hostapd")

	if hostapd and supplicant then
548 549
		encr:value("psk", "WPA-PSK")
		encr:value("psk2", "WPA2-PSK")
550 551
		encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode")
		encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
J
Jo-Philipp Wich 已提交
552
		encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
	elseif hostapd and not supplicant then
		encr:value("psk", "WPA-PSK", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
		encr:value("psk2", "WPA2-PSK", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
		encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="ap"}, {mode="ap-wds"}, {mode="adhoc"}, {mode="ahdemo"})
		encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="ap-wds"})
		encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="ap-wds"})
		encr.description = translate(
			"WPA-Encryption requires wpa_supplicant (for client mode) or hostapd (for AP " ..
			"and ad-hoc mode) to be installed."
		)
	elseif not hostapd and supplicant then
		encr:value("psk", "WPA-PSK", {mode="sta"}, {mode="sta-wds"})
		encr:value("psk2", "WPA2-PSK", {mode="sta"}, {mode="sta-wds"})
		encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="sta"}, {mode="sta-wds"})
		encr:value("wpa", "WPA-EAP", {mode="sta"}, {mode="sta-wds"})
		encr:value("wpa2", "WPA2-EAP", {mode="sta"}, {mode="sta-wds"})
		encr.description = translate(
			"WPA-Encryption requires wpa_supplicant (for client mode) or hostapd (for AP " ..
			"and ad-hoc mode) to be installed."
		)
	else
		encr.description = translate(
			"WPA-Encryption requires wpa_supplicant (for client mode) or hostapd (for AP " ..
			"and ad-hoc mode) to be installed."
		)
578
	end
579 580 581 582 583
elseif hwtype == "broadcom" then
	encr:value("psk", "WPA-PSK")
	encr:value("psk2", "WPA2-PSK")
	encr:value("psk+psk2", "WPA-PSK/WPA2-PSK Mixed Mode")
end
584

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
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

605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
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

wpakey.cfgvalue = function(self, section, value)
	local key = m.uci:get("wireless", section, "key")
	if key == "1" or key == "2" or key == "3" or key == "4" then
		return nil
	end
	return key
end

wpakey.write = function(self, section, value)
	self.map.uci:set("wireless", section, "key", value)
	self.map.uci:delete("wireless", section, "key1")
end


wepslot = s:taboption("encryption", ListValue, "_wep_key", translate("Used Key Slot"))
wepslot:depends("encryption", "wep-open")
wepslot:depends("encryption", "wep-shared")
wepslot:value("1", translatef("Key #%d", 1))
wepslot:value("2", translatef("Key #%d", 2))
wepslot:value("3", translatef("Key #%d", 3))
wepslot:value("4", translatef("Key #%d", 4))

wepslot.cfgvalue = function(self, section)
	local slot = tonumber(m.uci:get("wireless", section, "key"))
	if not slot or slot < 1 or slot > 4 then
		return 1
	end
645
	return slot
646 647 648 649 650 651 652 653 654 655 656 657 658 659
end

wepslot.write = function(self, section, value)
	self.map.uci:set("wireless", section, "key", value)
end

local slot
for slot=1,4 do
	wepkey = s:taboption("encryption", Value, "key" .. slot, translatef("Key #%d", slot))
	wepkey:depends("encryption", "wep-open")
	wepkey:depends("encryption", "wep-shared")
	wepkey.datatype = "wepkey"
	wepkey.rmempty = true
	wepkey.password = true
660

661 662 663 664 665 666 667 668
	function wepkey.write(self, section, value)
		if value and (#value == 5 or #value == 13) then
			value = "s:" .. value
		end
		return Value.write(self, section, value)
	end
end

669 670 671 672 673 674 675 676 677 678 679 680 681 682 683

if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
	nasid = s:taboption("encryption", Value, "nasid", translate("NAS ID"))
	nasid:depends({mode="ap", encryption="wpa"})
	nasid:depends({mode="ap", encryption="wpa2"})
	nasid:depends({mode="ap-wds", encryption="wpa"})
	nasid:depends({mode="ap-wds", encryption="wpa2"})
	nasid.rmempty = true

	eaptype = s:taboption("encryption", ListValue, "eap_type", translate("EAP-Method"))
	eaptype:value("tls",  "TLS")
	eaptype:value("ttls", "TTLS")
	eaptype:value("peap", "PEAP")
	eaptype:depends({mode="sta", encryption="wpa"})
	eaptype:depends({mode="sta", encryption="wpa2"})
J
Jo-Philipp Wich 已提交
684 685
	eaptype:depends({mode="sta-wds", encryption="wpa"})
	eaptype:depends({mode="sta-wds", encryption="wpa2"})
686 687 688 689

	cacert = s:taboption("encryption", FileUpload, "ca_cert", translate("Path to CA-Certificate"))
	cacert:depends({mode="sta", encryption="wpa"})
	cacert:depends({mode="sta", encryption="wpa2"})
J
Jo-Philipp Wich 已提交
690 691
	cacert:depends({mode="sta-wds", encryption="wpa"})
	cacert:depends({mode="sta-wds", encryption="wpa2"})
692 693 694 695

	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"})
J
Jo-Philipp Wich 已提交
696 697
	privkey:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"})
	privkey:depends({mode="sta-wds", eap_type="tls", encryption="wpa"})
698 699 700 701

	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"})
J
Jo-Philipp Wich 已提交
702 703
	privkeypwd:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"})
	privkeypwd:depends({mode="sta-wds", eap_type="tls", encryption="wpa"})
704 705 706 707 708 709 710 711 712 713 714


	auth = s:taboption("encryption", Value, "auth", translate("Authentication"))
	auth:value("PAP")
	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"})
J
Jo-Philipp Wich 已提交
715 716 717 718
	auth:depends({mode="sta-wds", eap_type="peap", encryption="wpa2"})
	auth:depends({mode="sta-wds", eap_type="peap", encryption="wpa"})
	auth:depends({mode="sta-wds", eap_type="ttls", encryption="wpa2"})
	auth:depends({mode="sta-wds", eap_type="ttls", encryption="wpa"})
719 720 721 722 723 724 725


	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"})
J
Jo-Philipp Wich 已提交
726 727 728 729
	identity:depends({mode="sta-wds", eap_type="peap", encryption="wpa2"})
	identity:depends({mode="sta-wds", eap_type="peap", encryption="wpa"})
	identity:depends({mode="sta-wds", eap_type="ttls", encryption="wpa2"})
	identity:depends({mode="sta-wds", eap_type="ttls", encryption="wpa"})
730 731 732 733 734 735

	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"})
J
Jo-Philipp Wich 已提交
736 737 738 739
	password:depends({mode="sta-wds", eap_type="peap", encryption="wpa2"})
	password:depends({mode="sta-wds", eap_type="peap", encryption="wpa"})
	password:depends({mode="sta-wds", eap_type="ttls", encryption="wpa2"})
	password:depends({mode="sta-wds", eap_type="ttls", encryption="wpa"})
740
end
S
Steven Barth 已提交
741

742
return m