wifi.lua 24.8 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)
J
Jo-Philipp Wich 已提交
32
	local wnet = nw:get_wifinet(arg[1])
33 34
	if ifsection and wnet then
		ifsection.section = wnet.sid
J
Jo-Philipp Wich 已提交
35
		m.title = luci.util.pcdata(wnet:get_i18n())
36 37 38
	end
end

39
nw.init(m.uci)
40

J
Jo-Philipp Wich 已提交
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)
J
Jo-Philipp Wich 已提交
45
if not wnet or not wdev then
46 47 48 49
	luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
	return
end

J
Jo-Philipp Wich 已提交
50
m.title = luci.util.pcdata(wnet:get_i18n())
51

52

53
local iw = luci.sys.wifi.getiwinfo(arg[1])
54 55
local tx_powers = iw.txpwrlist  or { }
local hw_modes  = iw.hwmodelist or { }
56

57

J
Jo-Philipp Wich 已提交
58
s = m:section(NamedSection, wdev:name(), "wifi-device", translate("Device Configuration"))
59
s.addremove = false
60

61 62 63
s:tab("general", translate("General Setup"))
s:tab("macfilter", translate("MAC-Filter"))
s:tab("advanced", translate("Advanced Settings"))
64 65

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

71 72
st = s:taboption("general", DummyValue, "__status", translate("Status"))
st.template = "admin_network/wifi_status"
J
Jo-Philipp Wich 已提交
73
st.ifname   = arg[1]
74 75

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

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

84

J
Jo-Philipp Wich 已提交
85 86
local hwtype = wdev:get("type")
local htcaps = wdev:get("ht_capab") and true or false
87

88
-- NanoFoo
J
Jo-Philipp Wich 已提交
89
local nsantenna = wdev:get("antenna")
90

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

99

100
------------------- MAC80211 Device ------------------
101

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

	tp.rmempty = true
108 109
	tp.default = tostring(iw and iw.txpower or tx_powers[#tx_powers])
	for _, p in ipairs(tx_powers or {}) do
110 111
		tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
	end
112

113 114
	mode = s:taboption("advanced", ListValue, "hwmode", translate("Mode"))
	mode:value("", translate("auto"))
115 116 117
	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
118

119
	if htcaps then
120 121
		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
122

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
		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
145

146
	s:taboption("advanced", Value, "distance", translate("Distance Optimization"),
147
		translate("Distance to farthest network member in meters."))
148
end
149

150 151 152 153

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

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

	tp.rmempty = true
	for _, p in ipairs(iw.txpwrlist) do
		tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
	end
162

163 164
	mode = s:taboption("advanced", ListValue, "hwmode", translate("Mode"))
	mode:value("", translate("auto"))
165 166 167 168 169 170
	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
171
	mode:value("fh", translate("Frequency Hopping"))
J
Jo-Philipp Wich 已提交
172

173
	s:taboption("advanced", Flag, "diversity", translate("Diversity")).rmempty = false
174 175

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

184
		ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("Receiver Antenna"))
185
		ant2.widget = "radio"
186
		ant2.orientation = "horizontal"
187
		ant2:depends("diversity", "")
188 189 190
		ant2:value("0", translate("auto"))
		ant2:value("1", translate("Antenna 1"))
		ant2:value("2", translate("Antenna 2"))
191

192
	else -- NanoFoo
193
		local ant = s:taboption("advanced", ListValue, "antenna", translate("Transmitter Antenna"))
194 195 196 197 198
		ant:value("auto")
		ant:value("vertical")
		ant:value("horizontal")
		ant:value("external")
	end
199

200 201 202 203 204
	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 已提交
205

206
	--s:option(Flag, "nosbeacon", translate("Disable HW-Beacon timer"))
207
end
208 209 210



211 212 213
------------------- Broadcom Device ------------------

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

	tp.rmempty = true
	for _, p in ipairs(iw.txpwrlist) do
		tp:value(p.dbm, "%i dBm (%i mW)" %{ p.dbm, p.mw })
221
	end
222

223 224 225 226 227 228
	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")

229
	mp = s:taboption("macfilter", ListValue, "macfilter", translate("MAC-Address Filter"))
230
	mp:value("", translate("disable"))
231 232 233
	mp:value("allow", translate("Allow listed only"))
	mp:value("deny", translate("Allow all except listed"))
	ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List"))
234 235
	ml:depends({macfilter="allow"})
	ml:depends({macfilter="deny"})
J
Jo-Philipp Wich 已提交
236

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

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

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

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

256 257
	s:taboption("advanced", Value, "country", translate("Country Code"))
	s:taboption("advanced", Value, "maxassoc", translate("Connection Limit"))
258 259
end

260

261 262 263
--------------------- HostAP Device ---------------------

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

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

268 269
	s:taboption("advanced", Value, "txantenna", translate("Transmitter Antenna"))
	s:taboption("advanced", Value, "rxantenna", translate("Receiver Antenna"))
270 271 272
end


S
Steven Barth 已提交
273 274
----------------------- Interface -----------------------

275 276 277 278
s = m:section(NamedSection, wnet.sid, "wifi-iface", translate("Interface Configuration"))
ifsection = s
s.addremove = false
s.anonymous = true
J
Jo-Philipp Wich 已提交
279
s.defaults.device = wdev:name()
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 310 311 312

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
313
			else
314 315 316 317 318 319 320 321
				local n = i:get_network()
				if n then n:del_interface(i) end
			end
		else
			local n = nw:get_network(value)
			if n then
				n:type("bridge")
				n:add_interface(i)
322
			end
S
Steven Barth 已提交
323 324
		end
	end
325
end
S
Steven Barth 已提交
326

327
-------------------- MAC80211 Interface ----------------------
328

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

334 335 336
	mode:value("ahdemo", translate("Pseudo Ad-Hoc (ahdemo)"))
	mode:value("monitor", translate("Monitor"))
	bssid:depends({mode="adhoc"})
337

338 339
	s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
	s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
340

341 342
	mode:value("ap-wds", "%s (%s)" % {translate("Access Point"), translate("WDS")})
	mode:value("sta-wds", "%s (%s)" % {translate("Client"), translate("WDS")})
343

344 345 346 347 348 349 350 351 352 353
	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")
354
		end
355
	end
356

357 358 359
	function mode.cfgvalue(self, section)
		local mode = ListValue.cfgvalue(self, section)
		local wds  = m.uci:get("wireless", section, "wds") == "1"
360

361 362 363 364 365 366
		if mode == "ap" and wds then
			return "ap-wds"
		elseif mode == "sta" and wds then
			return "sta-wds"
		else
			return mode
367
		end
368
	end
J
Jo-Philipp Wich 已提交
369

370 371 372 373
	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 已提交
374 375 376



377
-------------------- Madwifi Interface ----------------------
S
Steven Barth 已提交
378

379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
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")
396
		end
397
	end
S
Steven Barth 已提交
398

399 400 401
	function mode.cfgvalue(self, section)
		local mode = ListValue.cfgvalue(self, section)
		local wds  = m.uci:get("wireless", section, "wds") == "1"
402

403 404 405 406 407 408
		if mode == "ap" and wds then
			return "ap-wds"
		elseif mode == "sta" and wds then
			return "sta-wds"
		else
			return mode
409 410
		end
	end
J
Jo-Philipp Wich 已提交
411

412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
	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"))
	ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List"))
	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 已提交
465

466

467
-------------------- Broadcom Interface ----------------------
S
Steven Barth 已提交
468

469 470 471
if hwtype == "broadcom" then
	mode:value("wds", translate("WDS"))
	mode:value("monitor", translate("Monitor"))
S
Steven Barth 已提交
472

473 474 475 476
	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"})
477

478 479 480
	isolate = s:taboption("advanced", Flag, "isolate", translate("Separate Clients"),
	 translate("Prevents client-to-client communication"))
	isolate:depends({mode="ap"})
481

482 483
	s:taboption("advanced", Flag, "doth", "802.11h")
	s:taboption("advanced", Flag, "wmm", translate("WMM Mode"))
484

485 486 487
	bssid:depends({mode="wds"})
	bssid:depends({mode="adhoc"})
end
488

489

490
----------------------- HostAP Interface ---------------------
491

492 493 494
if hwtype == "prism2" then
	mode:value("wds", translate("WDS"))
	mode:value("monitor", translate("Monitor"))
S
Steven Barth 已提交
495

496 497 498 499
	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"})
500

501
	bssid:depends({mode="sta"})
502

503 504 505 506 507 508 509
	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"})
510

511 512 513 514
	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 已提交
515

516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538

------------------- 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
539 540
		encr:value("psk", "WPA-PSK")
		encr:value("psk2", "WPA2-PSK")
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
		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"})
		encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="sta"})
	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."
		)
569
	end
570 571 572 573 574
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
575

576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
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

J
Jo-Philipp Wich 已提交
596 597 598 599 600 601 602 603 604 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
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
J
Jo-Philipp Wich 已提交
636
	return slot
J
Jo-Philipp Wich 已提交
637 638 639 640 641 642 643 644 645 646 647 648 649 650
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
J
Jo-Philipp Wich 已提交
651

J
Jo-Philipp Wich 已提交
652 653 654 655 656 657 658 659
	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

660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710

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

	cacert = s:taboption("encryption", FileUpload, "ca_cert", translate("Path to CA-Certificate"))
	cacert:depends({mode="sta", encryption="wpa"})
	cacert:depends({mode="sta", encryption="wpa2"})

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

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


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


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

	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"})
711
end
S
Steven Barth 已提交
712

713
return m