wifi.lua 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. -- Copyright 2008 Steven Barth <steven@midlink.org>
  2. -- Licensed to the public under the Apache License 2.0.
  3. local wa = require "luci.tools.webadmin"
  4. local nw = require "luci.model.network"
  5. local ut = require "luci.util"
  6. local nt = require "luci.sys".net
  7. local fs = require "nixio.fs"
  8. arg[1] = arg[1] or ""
  9. m = Map("wireless", "",
  10. translate("The <em>Device Configuration</em> section covers physical settings of the radio " ..
  11. "hardware such as channel, transmit power or antenna selection which are shared among all " ..
  12. "defined wireless networks (if the radio hardware is multi-SSID capable). Per network settings " ..
  13. "like encryption or operation mode are grouped in the <em>Interface Configuration</em>."))
  14. m:chain("network")
  15. m:chain("firewall")
  16. m.redirect = luci.dispatcher.build_url("admin/network/wireless")
  17. local ifsection
  18. function m.on_commit(map)
  19. local wnet = nw:get_wifinet(arg[1])
  20. if ifsection and wnet then
  21. ifsection.section = wnet.sid
  22. m.title = luci.util.pcdata(wnet:get_i18n())
  23. end
  24. end
  25. nw.init(m.uci)
  26. local wnet = nw:get_wifinet(arg[1])
  27. local wdev = wnet and wnet:get_device()
  28. -- redirect to overview page if network does not exist anymore (e.g. after a revert)
  29. if not wnet or not wdev then
  30. luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
  31. return
  32. end
  33. -- wireless toggle was requested, commit and reload page
  34. function m.parse(map)
  35. if m:formvalue("cbid.wireless.%s.__toggle" % wdev:name()) then
  36. if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then
  37. wnet:set("disabled", nil)
  38. else
  39. wnet:set("disabled", "1")
  40. end
  41. wdev:set("disabled", nil)
  42. nw:commit("wireless")
  43. luci.sys.call("(env -i /bin/ubus call network reload) >/dev/null 2>/dev/null")
  44. luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1]))
  45. return
  46. end
  47. Map.parse(map)
  48. end
  49. m.title = luci.util.pcdata(wnet:get_i18n())
  50. local function txpower_list(iw)
  51. local list = iw.txpwrlist or { }
  52. local off = tonumber(iw.txpower_offset) or 0
  53. local new = { }
  54. local prev = -1
  55. local _, val
  56. for _, val in ipairs(list) do
  57. local dbm = val.dbm + off
  58. local mw = math.floor(10 ^ (dbm / 10))
  59. if mw ~= prev then
  60. prev = mw
  61. new[#new+1] = {
  62. display_dbm = dbm,
  63. display_mw = mw,
  64. driver_dbm = val.dbm,
  65. driver_mw = val.mw
  66. }
  67. end
  68. end
  69. return new
  70. end
  71. local function txpower_current(pwr, list)
  72. pwr = tonumber(pwr)
  73. if pwr ~= nil then
  74. local _, item
  75. for _, item in ipairs(list) do
  76. if item.driver_dbm >= pwr then
  77. return item.driver_dbm
  78. end
  79. end
  80. end
  81. return (list[#list] and list[#list].driver_dbm) or pwr or 0
  82. end
  83. local iw = luci.sys.wifi.getiwinfo(arg[1])
  84. local hw_modes = iw.hwmodelist or { }
  85. local tx_power_list = txpower_list(iw)
  86. local tx_power_cur = txpower_current(wdev:get("txpower"), tx_power_list)
  87. s = m:section(NamedSection, wdev:name(), "wifi-device", translate("Device Configuration"))
  88. s.addremove = false
  89. s:tab("general", translate("General Setup"))
  90. s:tab("macfilter", translate("MAC-Filter"))
  91. s:tab("advanced", translate("Advanced Settings"))
  92. --[[
  93. back = s:option(DummyValue, "_overview", translate("Overview"))
  94. back.value = ""
  95. back.titleref = luci.dispatcher.build_url("admin", "network", "wireless")
  96. ]]
  97. st = s:taboption("general", DummyValue, "__status", translate("Status"))
  98. st.template = "admin_network/wifi_status"
  99. st.ifname = arg[1]
  100. en = s:taboption("general", Button, "__toggle")
  101. if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then
  102. en.title = translate("Wireless network is disabled")
  103. en.inputtitle = translate("Enable")
  104. en.inputstyle = "apply"
  105. else
  106. en.title = translate("Wireless network is enabled")
  107. en.inputtitle = translate("Disable")
  108. en.inputstyle = "reset"
  109. end
  110. local hwtype = wdev:get("type")
  111. -- NanoFoo
  112. local nsantenna = wdev:get("antenna")
  113. -- Check whether there are client interfaces on the same radio,
  114. -- if yes, lock the channel choice as these stations will dicatate the freq
  115. local found_sta = nil
  116. local _, net
  117. if wnet:mode() ~= "sta" then
  118. for _, net in ipairs(wdev:get_wifinets()) do
  119. if net:mode() == "sta" and net:get("disabled") ~= "1" then
  120. if not found_sta then
  121. found_sta = {}
  122. found_sta.channel = net:channel()
  123. found_sta.names = {}
  124. end
  125. found_sta.names[#found_sta.names+1] = net:shortname()
  126. end
  127. end
  128. end
  129. if found_sta then
  130. ch = s:taboption("general", DummyValue, "choice", translate("Channel"))
  131. ch.value = translatef("Locked to channel %s used by: %s",
  132. found_sta.channel or "(auto)", table.concat(found_sta.names, ", "))
  133. else
  134. ch = s:taboption("general", Value, "_mode_freq", '<br />'..translate("Operating frequency"))
  135. ch.hwmodes = hw_modes
  136. ch.htmodes = iw.htmodelist
  137. ch.freqlist = iw.freqlist
  138. ch.template = "cbi/wireless_modefreq"
  139. function ch.cfgvalue(self, section)
  140. return {
  141. m:get(section, "hwmode") or "",
  142. m:get(section, "channel") or "auto",
  143. m:get(section, "htmode") or ""
  144. }
  145. end
  146. function ch.formvalue(self, section)
  147. return {
  148. m:formvalue(self:cbid(section) .. ".band") or (hw_modes.g and "11g" or "11a"),
  149. m:formvalue(self:cbid(section) .. ".channel") or "auto",
  150. m:formvalue(self:cbid(section) .. ".htmode") or ""
  151. }
  152. end
  153. function ch.write(self, section, value)
  154. m:set(section, "hwmode", value[1])
  155. m:set(section, "channel", value[2])
  156. m:set(section, "htmode", value[3])
  157. end
  158. end
  159. ------------------- MAC80211 Device ------------------
  160. if hwtype == "mac80211" then
  161. if #tx_power_list > 1 then
  162. tp = s:taboption("general", ListValue,
  163. "txpower", translate("Transmit Power"), "dBm")
  164. tp.rmempty = true
  165. tp.default = tx_power_cur
  166. function tp.cfgvalue(...)
  167. return txpower_current(Value.cfgvalue(...), tx_power_list)
  168. end
  169. for _, p in ipairs(tx_power_list) do
  170. tp:value(p.driver_dbm, "%i dBm (%i mW)"
  171. %{ p.display_dbm, p.display_mw })
  172. end
  173. end
  174. local cl = iw and iw.countrylist
  175. if cl and #cl > 0 then
  176. cc = s:taboption("advanced", ListValue, "country", translate("Country Code"), translate("Use ISO/IEC 3166 alpha2 country codes."))
  177. cc.default = tostring(iw and iw.country or "00")
  178. for _, c in ipairs(cl) do
  179. cc:value(c.alpha2, "%s - %s" %{ c.alpha2, c.name })
  180. end
  181. else
  182. s:taboption("advanced", Value, "country", translate("Country Code"), translate("Use ISO/IEC 3166 alpha2 country codes."))
  183. end
  184. s:taboption("advanced", Value, "distance", translate("Distance Optimization"),
  185. translate("Distance to farthest network member in meters."))
  186. -- external antenna profiles
  187. local eal = iw and iw.extant
  188. if eal and #eal > 0 then
  189. ea = s:taboption("advanced", ListValue, "extant", translate("Antenna Configuration"))
  190. for _, eap in ipairs(eal) do
  191. ea:value(eap.id, "%s (%s)" %{ eap.name, eap.description })
  192. if eap.selected then
  193. ea.default = eap.id
  194. end
  195. end
  196. end
  197. s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
  198. s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
  199. end
  200. ------------------- Madwifi Device ------------------
  201. if hwtype == "atheros" then
  202. tp = s:taboption("general",
  203. (#tx_power_list > 0) and ListValue or Value,
  204. "txpower", translate("Transmit Power"), "dBm")
  205. tp.rmempty = true
  206. tp.default = tx_power_cur
  207. function tp.cfgvalue(...)
  208. return txpower_current(Value.cfgvalue(...), tx_power_list)
  209. end
  210. for _, p in ipairs(tx_power_list) do
  211. tp:value(p.driver_dbm, "%i dBm (%i mW)"
  212. %{ p.display_dbm, p.display_mw })
  213. end
  214. s:taboption("advanced", Flag, "diversity", translate("Diversity")).rmempty = false
  215. if not nsantenna then
  216. ant1 = s:taboption("advanced", ListValue, "txantenna", translate("Transmitter Antenna"))
  217. ant1.widget = "radio"
  218. ant1.orientation = "horizontal"
  219. ant1:depends("diversity", "")
  220. ant1:value("0", translate("auto"))
  221. ant1:value("1", translate("Antenna 1"))
  222. ant1:value("2", translate("Antenna 2"))
  223. ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("Receiver Antenna"))
  224. ant2.widget = "radio"
  225. ant2.orientation = "horizontal"
  226. ant2:depends("diversity", "")
  227. ant2:value("0", translate("auto"))
  228. ant2:value("1", translate("Antenna 1"))
  229. ant2:value("2", translate("Antenna 2"))
  230. else -- NanoFoo
  231. local ant = s:taboption("advanced", ListValue, "antenna", translate("Transmitter Antenna"))
  232. ant:value("auto")
  233. ant:value("vertical")
  234. ant:value("horizontal")
  235. ant:value("external")
  236. end
  237. s:taboption("advanced", Value, "distance", translate("Distance Optimization"),
  238. translate("Distance to farthest network member in meters."))
  239. s:taboption("advanced", Value, "regdomain", translate("Regulatory Domain"))
  240. s:taboption("advanced", Value, "country", translate("Country Code"))
  241. s:taboption("advanced", Flag, "outdoor", translate("Outdoor Channels"))
  242. --s:option(Flag, "nosbeacon", translate("Disable HW-Beacon timer"))
  243. end
  244. ------------------- Broadcom Device ------------------
  245. if hwtype == "broadcom" then
  246. tp = s:taboption("general",
  247. (#tx_power_list > 0) and ListValue or Value,
  248. "txpower", translate("Transmit Power"), "dBm")
  249. tp.rmempty = true
  250. tp.default = tx_power_cur
  251. function tp.cfgvalue(...)
  252. return txpower_current(Value.cfgvalue(...), tx_power_list)
  253. end
  254. for _, p in ipairs(tx_power_list) do
  255. tp:value(p.driver_dbm, "%i dBm (%i mW)"
  256. %{ p.display_dbm, p.display_mw })
  257. end
  258. mode = s:taboption("advanced", ListValue, "hwmode", translate("Band"))
  259. if hw_modes.b then
  260. mode:value("11b", "2.4GHz (802.11b)")
  261. if hw_modes.g then
  262. mode:value("11bg", "2.4GHz (802.11b+g)")
  263. end
  264. end
  265. if hw_modes.g then
  266. mode:value("11g", "2.4GHz (802.11g)")
  267. mode:value("11gst", "2.4GHz (802.11g + Turbo)")
  268. mode:value("11lrs", "2.4GHz (802.11g Limited Rate Support)")
  269. end
  270. if hw_modes.a then mode:value("11a", "5GHz (802.11a)") end
  271. if hw_modes.n then
  272. if hw_modes.g then
  273. mode:value("11ng", "2.4GHz (802.11g+n)")
  274. mode:value("11n", "2.4GHz (802.11n)")
  275. end
  276. if hw_modes.a then
  277. mode:value("11na", "5GHz (802.11a+n)")
  278. mode:value("11n", "5GHz (802.11n)")
  279. end
  280. htmode = s:taboption("advanced", ListValue, "htmode", translate("HT mode (802.11n)"))
  281. htmode:depends("hwmode", "11ng")
  282. htmode:depends("hwmode", "11na")
  283. htmode:depends("hwmode", "11n")
  284. htmode:value("HT20", "20MHz")
  285. htmode:value("HT40", "40MHz")
  286. end
  287. ant1 = s:taboption("advanced", ListValue, "txantenna", translate("Transmitter Antenna"))
  288. ant1.widget = "radio"
  289. ant1:depends("diversity", "")
  290. ant1:value("3", translate("auto"))
  291. ant1:value("0", translate("Antenna 1"))
  292. ant1:value("1", translate("Antenna 2"))
  293. ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("Receiver Antenna"))
  294. ant2.widget = "radio"
  295. ant2:depends("diversity", "")
  296. ant2:value("3", translate("auto"))
  297. ant2:value("0", translate("Antenna 1"))
  298. ant2:value("1", translate("Antenna 2"))
  299. s:taboption("advanced", Flag, "frameburst", translate("Frame Bursting"))
  300. s:taboption("advanced", Value, "distance", translate("Distance Optimization"))
  301. --s:option(Value, "slottime", translate("Slot time"))
  302. s:taboption("advanced", Value, "country", translate("Country Code"))
  303. s:taboption("advanced", Value, "maxassoc", translate("Connection Limit"))
  304. end
  305. --------------------- HostAP Device ---------------------
  306. if hwtype == "prism2" then
  307. s:taboption("advanced", Value, "txpower", translate("Transmit Power"), "att units").rmempty = true
  308. s:taboption("advanced", Flag, "diversity", translate("Diversity")).rmempty = false
  309. s:taboption("advanced", Value, "txantenna", translate("Transmitter Antenna"))
  310. s:taboption("advanced", Value, "rxantenna", translate("Receiver Antenna"))
  311. end
  312. ----------------------- Interface -----------------------
  313. s = m:section(NamedSection, wnet.sid, "wifi-iface", translate("Interface Configuration"))
  314. ifsection = s
  315. s.addremove = false
  316. s.anonymous = true
  317. s.defaults.device = wdev:name()
  318. s:tab("general", translate("General Setup"))
  319. s:tab("encryption", translate("Wireless Security"))
  320. s:tab("macfilter", translate("MAC-Filter"))
  321. s:tab("advanced", translate("Advanced Settings"))
  322. ssid = s:taboption("general", Value, "ssid", translate("<abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
  323. ssid.datatype = "maxlength(32)"
  324. mode = s:taboption("general", ListValue, "mode", translate("Mode"))
  325. mode.override_values = true
  326. mode:value("ap", translate("Access Point"))
  327. mode:value("sta", translate("Client"))
  328. mode:value("adhoc", translate("Ad-Hoc"))
  329. bssid = s:taboption("general", Value, "bssid", translate("<abbr title=\"Basic Service Set Identifier\">BSSID</abbr>"))
  330. network = s:taboption("general", Value, "network", translate("Network"),
  331. translate("Choose the network(s) you want to attach to this wireless interface or " ..
  332. "fill out the <em>create</em> field to define a new network."))
  333. network.rmempty = true
  334. network.template = "cbi/network_netlist"
  335. network.widget = "checkbox"
  336. network.novirtual = true
  337. function network.write(self, section, value)
  338. local i = nw:get_interface(section)
  339. if i then
  340. if value == '-' then
  341. value = m:formvalue(self:cbid(section) .. ".newnet")
  342. if value and #value > 0 then
  343. local n = nw:add_network(value, {proto="none"})
  344. if n then n:add_interface(i) end
  345. else
  346. local n = i:get_network()
  347. if n then n:del_interface(i) end
  348. end
  349. else
  350. local v
  351. for _, v in ipairs(i:get_networks()) do
  352. v:del_interface(i)
  353. end
  354. for v in ut.imatch(value) do
  355. local n = nw:get_network(v)
  356. if n then
  357. if not n:is_empty() then
  358. n:set("type", "bridge")
  359. end
  360. n:add_interface(i)
  361. end
  362. end
  363. end
  364. end
  365. end
  366. -------------------- MAC80211 Interface ----------------------
  367. if hwtype == "mac80211" then
  368. if fs.access("/usr/sbin/iw") then
  369. mode:value("mesh", "802.11s")
  370. end
  371. mode:value("ahdemo", translate("Pseudo Ad-Hoc (ahdemo)"))
  372. mode:value("monitor", translate("Monitor"))
  373. bssid:depends({mode="adhoc"})
  374. bssid:depends({mode="sta"})
  375. bssid:depends({mode="sta-wds"})
  376. mp = s:taboption("macfilter", ListValue, "macfilter", translate("MAC-Address Filter"))
  377. mp:depends({mode="ap"})
  378. mp:depends({mode="ap-wds"})
  379. mp:value("", translate("disable"))
  380. mp:value("allow", translate("Allow listed only"))
  381. mp:value("deny", translate("Allow all except listed"))
  382. ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List"))
  383. ml.datatype = "macaddr"
  384. ml:depends({macfilter="allow"})
  385. ml:depends({macfilter="deny"})
  386. nt.mac_hints(function(mac, name) ml:value(mac, "%s (%s)" %{ mac, name }) end)
  387. mode:value("ap-wds", "%s (%s)" % {translate("Access Point"), translate("WDS")})
  388. mode:value("sta-wds", "%s (%s)" % {translate("Client"), translate("WDS")})
  389. function mode.write(self, section, value)
  390. if value == "ap-wds" then
  391. ListValue.write(self, section, "ap")
  392. m.uci:set("wireless", section, "wds", 1)
  393. elseif value == "sta-wds" then
  394. ListValue.write(self, section, "sta")
  395. m.uci:set("wireless", section, "wds", 1)
  396. else
  397. ListValue.write(self, section, value)
  398. m.uci:delete("wireless", section, "wds")
  399. end
  400. end
  401. function mode.cfgvalue(self, section)
  402. local mode = ListValue.cfgvalue(self, section)
  403. local wds = m.uci:get("wireless", section, "wds") == "1"
  404. if mode == "ap" and wds then
  405. return "ap-wds"
  406. elseif mode == "sta" and wds then
  407. return "sta-wds"
  408. else
  409. return mode
  410. end
  411. end
  412. hidden = s:taboption("general", Flag, "hidden", translate("Hide <abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
  413. hidden:depends({mode="ap"})
  414. hidden:depends({mode="ap-wds"})
  415. wmm = s:taboption("general", Flag, "wmm", translate("WMM Mode"))
  416. wmm:depends({mode="ap"})
  417. wmm:depends({mode="ap-wds"})
  418. wmm.default = wmm.enabled
  419. ifname = s:taboption("advanced", Value, "ifname", translate("Interface name"), translate("Override default interface name"))
  420. ifname.optional = true
  421. end
  422. -------------------- Madwifi Interface ----------------------
  423. if hwtype == "atheros" then
  424. mode:value("ahdemo", translate("Pseudo Ad-Hoc (ahdemo)"))
  425. mode:value("monitor", translate("Monitor"))
  426. mode:value("ap-wds", "%s (%s)" % {translate("Access Point"), translate("WDS")})
  427. mode:value("sta-wds", "%s (%s)" % {translate("Client"), translate("WDS")})
  428. mode:value("wds", translate("Static WDS"))
  429. function mode.write(self, section, value)
  430. if value == "ap-wds" then
  431. ListValue.write(self, section, "ap")
  432. m.uci:set("wireless", section, "wds", 1)
  433. elseif value == "sta-wds" then
  434. ListValue.write(self, section, "sta")
  435. m.uci:set("wireless", section, "wds", 1)
  436. else
  437. ListValue.write(self, section, value)
  438. m.uci:delete("wireless", section, "wds")
  439. end
  440. end
  441. function mode.cfgvalue(self, section)
  442. local mode = ListValue.cfgvalue(self, section)
  443. local wds = m.uci:get("wireless", section, "wds") == "1"
  444. if mode == "ap" and wds then
  445. return "ap-wds"
  446. elseif mode == "sta" and wds then
  447. return "sta-wds"
  448. else
  449. return mode
  450. end
  451. end
  452. bssid:depends({mode="adhoc"})
  453. bssid:depends({mode="ahdemo"})
  454. bssid:depends({mode="wds"})
  455. wdssep = s:taboption("advanced", Flag, "wdssep", translate("Separate WDS"))
  456. wdssep:depends({mode="ap-wds"})
  457. s:taboption("advanced", Flag, "doth", "802.11h")
  458. hidden = s:taboption("general", Flag, "hidden", translate("Hide <abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
  459. hidden:depends({mode="ap"})
  460. hidden:depends({mode="adhoc"})
  461. hidden:depends({mode="ap-wds"})
  462. hidden:depends({mode="sta-wds"})
  463. isolate = s:taboption("advanced", Flag, "isolate", translate("Separate Clients"),
  464. translate("Prevents client-to-client communication"))
  465. isolate:depends({mode="ap"})
  466. s:taboption("advanced", Flag, "bgscan", translate("Background Scan"))
  467. mp = s:taboption("macfilter", ListValue, "macpolicy", translate("MAC-Address Filter"))
  468. mp:value("", translate("disable"))
  469. mp:value("allow", translate("Allow listed only"))
  470. mp:value("deny", translate("Allow all except listed"))
  471. ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List"))
  472. ml.datatype = "macaddr"
  473. ml:depends({macpolicy="allow"})
  474. ml:depends({macpolicy="deny"})
  475. nt.mac_hints(function(mac, name) ml:value(mac, "%s (%s)" %{ mac, name }) end)
  476. s:taboption("advanced", Value, "rate", translate("Transmission Rate"))
  477. s:taboption("advanced", Value, "mcast_rate", translate("Multicast Rate"))
  478. s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
  479. s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
  480. s:taboption("advanced", Value, "minrate", translate("Minimum Rate"))
  481. s:taboption("advanced", Value, "maxrate", translate("Maximum Rate"))
  482. s:taboption("advanced", Flag, "compression", translate("Compression"))
  483. s:taboption("advanced", Flag, "bursting", translate("Frame Bursting"))
  484. s:taboption("advanced", Flag, "turbo", translate("Turbo Mode"))
  485. s:taboption("advanced", Flag, "ff", translate("Fast Frames"))
  486. s:taboption("advanced", Flag, "wmm", translate("WMM Mode"))
  487. s:taboption("advanced", Flag, "xr", translate("XR Support"))
  488. s:taboption("advanced", Flag, "ar", translate("AR Support"))
  489. local swm = s:taboption("advanced", Flag, "sw_merge", translate("Disable HW-Beacon timer"))
  490. swm:depends({mode="adhoc"})
  491. local nos = s:taboption("advanced", Flag, "nosbeacon", translate("Disable HW-Beacon timer"))
  492. nos:depends({mode="sta"})
  493. nos:depends({mode="sta-wds"})
  494. local probereq = s:taboption("advanced", Flag, "probereq", translate("Do not send probe responses"))
  495. probereq.enabled = "0"
  496. probereq.disabled = "1"
  497. end
  498. -------------------- Broadcom Interface ----------------------
  499. if hwtype == "broadcom" then
  500. mode:value("wds", translate("WDS"))
  501. mode:value("monitor", translate("Monitor"))
  502. hidden = s:taboption("general", Flag, "hidden", translate("Hide <abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
  503. hidden:depends({mode="ap"})
  504. hidden:depends({mode="adhoc"})
  505. hidden:depends({mode="wds"})
  506. isolate = s:taboption("advanced", Flag, "isolate", translate("Separate Clients"),
  507. translate("Prevents client-to-client communication"))
  508. isolate:depends({mode="ap"})
  509. s:taboption("advanced", Flag, "doth", "802.11h")
  510. s:taboption("advanced", Flag, "wmm", translate("WMM Mode"))
  511. bssid:depends({mode="wds"})
  512. bssid:depends({mode="adhoc"})
  513. end
  514. ----------------------- HostAP Interface ---------------------
  515. if hwtype == "prism2" then
  516. mode:value("wds", translate("WDS"))
  517. mode:value("monitor", translate("Monitor"))
  518. hidden = s:taboption("general", Flag, "hidden", translate("Hide <abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"))
  519. hidden:depends({mode="ap"})
  520. hidden:depends({mode="adhoc"})
  521. hidden:depends({mode="wds"})
  522. bssid:depends({mode="sta"})
  523. mp = s:taboption("macfilter", ListValue, "macpolicy", translate("MAC-Address Filter"))
  524. mp:value("", translate("disable"))
  525. mp:value("allow", translate("Allow listed only"))
  526. mp:value("deny", translate("Allow all except listed"))
  527. ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List"))
  528. ml:depends({macpolicy="allow"})
  529. ml:depends({macpolicy="deny"})
  530. nt.mac_hints(function(mac, name) ml:value(mac, "%s (%s)" %{ mac, name }) end)
  531. s:taboption("advanced", Value, "rate", translate("Transmission Rate"))
  532. s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold"))
  533. s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold"))
  534. end
  535. ------------------- WiFI-Encryption -------------------
  536. encr = s:taboption("encryption", ListValue, "encryption", translate("Encryption"))
  537. encr.override_values = true
  538. encr.override_depends = true
  539. encr:depends({mode="ap"})
  540. encr:depends({mode="sta"})
  541. encr:depends({mode="adhoc"})
  542. encr:depends({mode="ahdemo"})
  543. encr:depends({mode="ap-wds"})
  544. encr:depends({mode="sta-wds"})
  545. encr:depends({mode="mesh"})
  546. cipher = s:taboption("encryption", ListValue, "cipher", translate("Cipher"))
  547. cipher:depends({encryption="wpa"})
  548. cipher:depends({encryption="wpa2"})
  549. cipher:depends({encryption="psk"})
  550. cipher:depends({encryption="psk2"})
  551. cipher:depends({encryption="wpa-mixed"})
  552. cipher:depends({encryption="psk-mixed"})
  553. cipher:value("auto", translate("auto"))
  554. cipher:value("ccmp", translate("Force CCMP (AES)"))
  555. cipher:value("tkip", translate("Force TKIP"))
  556. cipher:value("tkip+ccmp", translate("Force TKIP and CCMP (AES)"))
  557. function encr.cfgvalue(self, section)
  558. local v = tostring(ListValue.cfgvalue(self, section))
  559. if v == "wep" then
  560. return "wep-open"
  561. elseif v and v:match("%+") then
  562. return (v:gsub("%+.+$", ""))
  563. end
  564. return v
  565. end
  566. function encr.write(self, section, value)
  567. local e = tostring(encr:formvalue(section))
  568. local c = tostring(cipher:formvalue(section))
  569. if value == "wpa" or value == "wpa2" then
  570. self.map.uci:delete("wireless", section, "key")
  571. end
  572. if e and (c == "tkip" or c == "ccmp" or c == "tkip+ccmp") then
  573. e = e .. "+" .. c
  574. end
  575. self.map:set(section, "encryption", e)
  576. end
  577. function cipher.cfgvalue(self, section)
  578. local v = tostring(ListValue.cfgvalue(encr, section))
  579. if v and v:match("%+") then
  580. v = v:gsub("^[^%+]+%+", "")
  581. if v == "aes" then v = "ccmp"
  582. elseif v == "tkip+aes" then v = "tkip+ccmp"
  583. elseif v == "aes+tkip" then v = "tkip+ccmp"
  584. elseif v == "ccmp+tkip" then v = "tkip+ccmp"
  585. end
  586. end
  587. return v
  588. end
  589. function cipher.write(self, section)
  590. return encr:write(section)
  591. end
  592. encr:value("none", "No Encryption")
  593. encr:value("wep-open", translate("WEP Open System"), {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}, {mode="adhoc"}, {mode="ahdemo"}, {mode="wds"})
  594. encr:value("wep-shared", translate("WEP Shared Key"), {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}, {mode="adhoc"}, {mode="ahdemo"}, {mode="wds"})
  595. if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
  596. local supplicant = fs.access("/usr/sbin/wpa_supplicant")
  597. local hostapd = fs.access("/usr/sbin/hostapd")
  598. -- Probe EAP support
  599. local has_ap_eap = (os.execute("hostapd -veap >/dev/null 2>/dev/null") == 0)
  600. local has_sta_eap = (os.execute("wpa_supplicant -veap >/dev/null 2>/dev/null") == 0)
  601. if hostapd and supplicant then
  602. encr:value("psk", "WPA-PSK", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
  603. encr:value("psk2", "WPA2-PSK", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
  604. encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
  605. if has_ap_eap and has_sta_eap then
  606. encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
  607. encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"})
  608. end
  609. elseif hostapd and not supplicant then
  610. encr:value("psk", "WPA-PSK", {mode="ap"}, {mode="ap-wds"})
  611. encr:value("psk2", "WPA2-PSK", {mode="ap"}, {mode="ap-wds"})
  612. encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="ap"}, {mode="ap-wds"})
  613. if has_ap_eap then
  614. encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="ap-wds"})
  615. encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="ap-wds"})
  616. end
  617. encr.description = translate(
  618. "WPA-Encryption requires wpa_supplicant (for client mode) or hostapd (for AP " ..
  619. "and ad-hoc mode) to be installed."
  620. )
  621. elseif not hostapd and supplicant then
  622. encr:value("psk", "WPA-PSK", {mode="sta"}, {mode="sta-wds"})
  623. encr:value("psk2", "WPA2-PSK", {mode="sta"}, {mode="sta-wds"})
  624. encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="sta"}, {mode="sta-wds"})
  625. if has_sta_eap then
  626. encr:value("wpa", "WPA-EAP", {mode="sta"}, {mode="sta-wds"})
  627. encr:value("wpa2", "WPA2-EAP", {mode="sta"}, {mode="sta-wds"})
  628. end
  629. encr.description = translate(
  630. "WPA-Encryption requires wpa_supplicant (for client mode) or hostapd (for AP " ..
  631. "and ad-hoc mode) to be installed."
  632. )
  633. else
  634. encr.description = translate(
  635. "WPA-Encryption requires wpa_supplicant (for client mode) or hostapd (for AP " ..
  636. "and ad-hoc mode) to be installed."
  637. )
  638. end
  639. elseif hwtype == "broadcom" then
  640. encr:value("psk", "WPA-PSK")
  641. encr:value("psk2", "WPA2-PSK")
  642. encr:value("psk+psk2", "WPA-PSK/WPA2-PSK Mixed Mode")
  643. end
  644. auth_server = s:taboption("encryption", Value, "auth_server", translate("Radius-Authentication-Server"))
  645. auth_server:depends({mode="ap", encryption="wpa"})
  646. auth_server:depends({mode="ap", encryption="wpa2"})
  647. auth_server:depends({mode="ap-wds", encryption="wpa"})
  648. auth_server:depends({mode="ap-wds", encryption="wpa2"})
  649. auth_server.rmempty = true
  650. auth_server.datatype = "host(0)"
  651. auth_port = s:taboption("encryption", Value, "auth_port", translate("Radius-Authentication-Port"), translatef("Default %d", 1812))
  652. auth_port:depends({mode="ap", encryption="wpa"})
  653. auth_port:depends({mode="ap", encryption="wpa2"})
  654. auth_port:depends({mode="ap-wds", encryption="wpa"})
  655. auth_port:depends({mode="ap-wds", encryption="wpa2"})
  656. auth_port.rmempty = true
  657. auth_port.datatype = "port"
  658. auth_secret = s:taboption("encryption", Value, "auth_secret", translate("Radius-Authentication-Secret"))
  659. auth_secret:depends({mode="ap", encryption="wpa"})
  660. auth_secret:depends({mode="ap", encryption="wpa2"})
  661. auth_secret:depends({mode="ap-wds", encryption="wpa"})
  662. auth_secret:depends({mode="ap-wds", encryption="wpa2"})
  663. auth_secret.rmempty = true
  664. auth_secret.password = true
  665. acct_server = s:taboption("encryption", Value, "acct_server", translate("Radius-Accounting-Server"))
  666. acct_server:depends({mode="ap", encryption="wpa"})
  667. acct_server:depends({mode="ap", encryption="wpa2"})
  668. acct_server:depends({mode="ap-wds", encryption="wpa"})
  669. acct_server:depends({mode="ap-wds", encryption="wpa2"})
  670. acct_server.rmempty = true
  671. acct_server.datatype = "host(0)"
  672. acct_port = s:taboption("encryption", Value, "acct_port", translate("Radius-Accounting-Port"), translatef("Default %d", 1813))
  673. acct_port:depends({mode="ap", encryption="wpa"})
  674. acct_port:depends({mode="ap", encryption="wpa2"})
  675. acct_port:depends({mode="ap-wds", encryption="wpa"})
  676. acct_port:depends({mode="ap-wds", encryption="wpa2"})
  677. acct_port.rmempty = true
  678. acct_port.datatype = "port"
  679. acct_secret = s:taboption("encryption", Value, "acct_secret", translate("Radius-Accounting-Secret"))
  680. acct_secret:depends({mode="ap", encryption="wpa"})
  681. acct_secret:depends({mode="ap", encryption="wpa2"})
  682. acct_secret:depends({mode="ap-wds", encryption="wpa"})
  683. acct_secret:depends({mode="ap-wds", encryption="wpa2"})
  684. acct_secret.rmempty = true
  685. acct_secret.password = true
  686. wpakey = s:taboption("encryption", Value, "_wpa_key", translate("Key"))
  687. wpakey:depends("encryption", "psk")
  688. wpakey:depends("encryption", "psk2")
  689. wpakey:depends("encryption", "psk+psk2")
  690. wpakey:depends("encryption", "psk-mixed")
  691. wpakey.datatype = "wpakey"
  692. wpakey.rmempty = true
  693. wpakey.password = true
  694. wpakey.cfgvalue = function(self, section, value)
  695. local key = m.uci:get("wireless", section, "key")
  696. if key == "1" or key == "2" or key == "3" or key == "4" then
  697. return nil
  698. end
  699. return key
  700. end
  701. wpakey.write = function(self, section, value)
  702. self.map.uci:set("wireless", section, "key", value)
  703. self.map.uci:delete("wireless", section, "key1")
  704. end
  705. wepslot = s:taboption("encryption", ListValue, "_wep_key", translate("Used Key Slot"))
  706. wepslot:depends("encryption", "wep-open")
  707. wepslot:depends("encryption", "wep-shared")
  708. wepslot:value("1", translatef("Key #%d", 1))
  709. wepslot:value("2", translatef("Key #%d", 2))
  710. wepslot:value("3", translatef("Key #%d", 3))
  711. wepslot:value("4", translatef("Key #%d", 4))
  712. wepslot.cfgvalue = function(self, section)
  713. local slot = tonumber(m.uci:get("wireless", section, "key"))
  714. if not slot or slot < 1 or slot > 4 then
  715. return 1
  716. end
  717. return slot
  718. end
  719. wepslot.write = function(self, section, value)
  720. self.map.uci:set("wireless", section, "key", value)
  721. end
  722. local slot
  723. for slot=1,4 do
  724. wepkey = s:taboption("encryption", Value, "key" .. slot, translatef("Key #%d", slot))
  725. wepkey:depends("encryption", "wep-open")
  726. wepkey:depends("encryption", "wep-shared")
  727. wepkey.datatype = "wepkey"
  728. wepkey.rmempty = true
  729. wepkey.password = true
  730. function wepkey.write(self, section, value)
  731. if value and (#value == 5 or #value == 13) then
  732. value = "s:" .. value
  733. end
  734. return Value.write(self, section, value)
  735. end
  736. end
  737. if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
  738. nasid = s:taboption("encryption", Value, "nasid", translate("NAS ID"))
  739. nasid:depends({mode="ap", encryption="wpa"})
  740. nasid:depends({mode="ap", encryption="wpa2"})
  741. nasid:depends({mode="ap-wds", encryption="wpa"})
  742. nasid:depends({mode="ap-wds", encryption="wpa2"})
  743. nasid.rmempty = true
  744. eaptype = s:taboption("encryption", ListValue, "eap_type", translate("EAP-Method"))
  745. eaptype:value("tls", "TLS")
  746. eaptype:value("ttls", "TTLS")
  747. eaptype:value("peap", "PEAP")
  748. eaptype:value("fast", "FAST")
  749. eaptype:depends({mode="sta", encryption="wpa"})
  750. eaptype:depends({mode="sta", encryption="wpa2"})
  751. eaptype:depends({mode="sta-wds", encryption="wpa"})
  752. eaptype:depends({mode="sta-wds", encryption="wpa2"})
  753. cacert = s:taboption("encryption", FileUpload, "ca_cert", translate("Path to CA-Certificate"))
  754. cacert:depends({mode="sta", encryption="wpa"})
  755. cacert:depends({mode="sta", encryption="wpa2"})
  756. cacert:depends({mode="sta-wds", encryption="wpa"})
  757. cacert:depends({mode="sta-wds", encryption="wpa2"})
  758. cacert.rmempty = true
  759. clientcert = s:taboption("encryption", FileUpload, "client_cert", translate("Path to Client-Certificate"))
  760. clientcert:depends({mode="sta", eap_type="tls", encryption="wpa"})
  761. clientcert:depends({mode="sta", eap_type="tls", encryption="wpa2"})
  762. clientcert:depends({mode="sta-wds", eap_type="tls", encryption="wpa"})
  763. clientcert:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"})
  764. privkey = s:taboption("encryption", FileUpload, "priv_key", translate("Path to Private Key"))
  765. privkey:depends({mode="sta", eap_type="tls", encryption="wpa2"})
  766. privkey:depends({mode="sta", eap_type="tls", encryption="wpa"})
  767. privkey:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"})
  768. privkey:depends({mode="sta-wds", eap_type="tls", encryption="wpa"})
  769. privkeypwd = s:taboption("encryption", Value, "priv_key_pwd", translate("Password of Private Key"))
  770. privkeypwd:depends({mode="sta", eap_type="tls", encryption="wpa2"})
  771. privkeypwd:depends({mode="sta", eap_type="tls", encryption="wpa"})
  772. privkeypwd:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"})
  773. privkeypwd:depends({mode="sta-wds", eap_type="tls", encryption="wpa"})
  774. privkeypwd.rmempty = true
  775. privkeypwd.password = true
  776. auth = s:taboption("encryption", ListValue, "auth", translate("Authentication"))
  777. auth:value("PAP", "PAP", {eap_type="ttls"})
  778. auth:value("CHAP", "CHAP", {eap_type="ttls"})
  779. auth:value("MSCHAP", "MSCHAP", {eap_type="ttls"})
  780. auth:value("MSCHAPV2", "MSCHAPv2", {eap_type="ttls"})
  781. auth:value("EAP-GTC")
  782. auth:value("EAP-MD5")
  783. auth:value("EAP-MSCHAPV2")
  784. auth:value("EAP-TLS")
  785. auth:depends({mode="sta", eap_type="fast", encryption="wpa2"})
  786. auth:depends({mode="sta", eap_type="fast", encryption="wpa"})
  787. auth:depends({mode="sta", eap_type="peap", encryption="wpa2"})
  788. auth:depends({mode="sta", eap_type="peap", encryption="wpa"})
  789. auth:depends({mode="sta", eap_type="ttls", encryption="wpa2"})
  790. auth:depends({mode="sta", eap_type="ttls", encryption="wpa"})
  791. auth:depends({mode="sta-wds", eap_type="fast", encryption="wpa2"})
  792. auth:depends({mode="sta-wds", eap_type="fast", encryption="wpa"})
  793. auth:depends({mode="sta-wds", eap_type="peap", encryption="wpa2"})
  794. auth:depends({mode="sta-wds", eap_type="peap", encryption="wpa"})
  795. auth:depends({mode="sta-wds", eap_type="ttls", encryption="wpa2"})
  796. auth:depends({mode="sta-wds", eap_type="ttls", encryption="wpa"})
  797. cacert2 = s:taboption("encryption", FileUpload, "ca_cert2", translate("Path to inner CA-Certificate"))
  798. cacert2:depends({mode="sta", auth="EAP-TLS", encryption="wpa"})
  799. cacert2:depends({mode="sta", auth="EAP-TLS", encryption="wpa2"})
  800. cacert2:depends({mode="sta-wds", auth="EAP-TLS", encryption="wpa"})
  801. cacert2:depends({mode="sta-wds", auth="EAP-TLS", encryption="wpa2"})
  802. clientcert2 = s:taboption("encryption", FileUpload, "client_cert2", translate("Path to inner Client-Certificate"))
  803. clientcert2:depends({mode="sta", auth="EAP-TLS", encryption="wpa"})
  804. clientcert2:depends({mode="sta", auth="EAP-TLS", encryption="wpa2"})
  805. clientcert2:depends({mode="sta-wds", auth="EAP-TLS", encryption="wpa"})
  806. clientcert2:depends({mode="sta-wds", auth="EAP-TLS", encryption="wpa2"})
  807. privkey2 = s:taboption("encryption", FileUpload, "priv_key2", translate("Path to inner Private Key"))
  808. privkey2:depends({mode="sta", auth="EAP-TLS", encryption="wpa"})
  809. privkey2:depends({mode="sta", auth="EAP-TLS", encryption="wpa2"})
  810. privkey2:depends({mode="sta-wds", auth="EAP-TLS", encryption="wpa"})
  811. privkey2:depends({mode="sta-wds", auth="EAP-TLS", encryption="wpa2"})
  812. privkeypwd2 = s:taboption("encryption", Value, "priv_key2_pwd", translate("Password of inner Private Key"))
  813. privkeypwd2:depends({mode="sta", auth="EAP-TLS", encryption="wpa"})
  814. privkeypwd2:depends({mode="sta", auth="EAP-TLS", encryption="wpa2"})
  815. privkeypwd2:depends({mode="sta-wds", auth="EAP-TLS", encryption="wpa"})
  816. privkeypwd2:depends({mode="sta-wds", auth="EAP-TLS", encryption="wpa2"})
  817. privkeypwd2.rmempty = true
  818. privkeypwd2.password = true
  819. identity = s:taboption("encryption", Value, "identity", translate("Identity"))
  820. identity:depends({mode="sta", eap_type="fast", encryption="wpa2"})
  821. identity:depends({mode="sta", eap_type="fast", encryption="wpa"})
  822. identity:depends({mode="sta", eap_type="peap", encryption="wpa2"})
  823. identity:depends({mode="sta", eap_type="peap", encryption="wpa"})
  824. identity:depends({mode="sta", eap_type="ttls", encryption="wpa2"})
  825. identity:depends({mode="sta", eap_type="ttls", encryption="wpa"})
  826. identity:depends({mode="sta-wds", eap_type="fast", encryption="wpa2"})
  827. identity:depends({mode="sta-wds", eap_type="fast", encryption="wpa"})
  828. identity:depends({mode="sta-wds", eap_type="peap", encryption="wpa2"})
  829. identity:depends({mode="sta-wds", eap_type="peap", encryption="wpa"})
  830. identity:depends({mode="sta-wds", eap_type="ttls", encryption="wpa2"})
  831. identity:depends({mode="sta-wds", eap_type="ttls", encryption="wpa"})
  832. identity:depends({mode="sta", eap_type="tls", encryption="wpa2"})
  833. identity:depends({mode="sta", eap_type="tls", encryption="wpa"})
  834. identity:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"})
  835. identity:depends({mode="sta-wds", eap_type="tls", encryption="wpa"})
  836. anonymous_identity = s:taboption("encryption", Value, "anonymous_identity", translate("Anonymous Identity"))
  837. anonymous_identity:depends({mode="sta", eap_type="fast", encryption="wpa2"})
  838. anonymous_identity:depends({mode="sta", eap_type="fast", encryption="wpa"})
  839. anonymous_identity:depends({mode="sta", eap_type="peap", encryption="wpa2"})
  840. anonymous_identity:depends({mode="sta", eap_type="peap", encryption="wpa"})
  841. anonymous_identity:depends({mode="sta", eap_type="ttls", encryption="wpa2"})
  842. anonymous_identity:depends({mode="sta", eap_type="ttls", encryption="wpa"})
  843. anonymous_identity:depends({mode="sta-wds", eap_type="fast", encryption="wpa2"})
  844. anonymous_identity:depends({mode="sta-wds", eap_type="fast", encryption="wpa"})
  845. anonymous_identity:depends({mode="sta-wds", eap_type="peap", encryption="wpa2"})
  846. anonymous_identity:depends({mode="sta-wds", eap_type="peap", encryption="wpa"})
  847. anonymous_identity:depends({mode="sta-wds", eap_type="ttls", encryption="wpa2"})
  848. anonymous_identity:depends({mode="sta-wds", eap_type="ttls", encryption="wpa"})
  849. anonymous_identity:depends({mode="sta", eap_type="tls", encryption="wpa2"})
  850. anonymous_identity:depends({mode="sta", eap_type="tls", encryption="wpa"})
  851. anonymous_identity:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"})
  852. anonymous_identity:depends({mode="sta-wds", eap_type="tls", encryption="wpa"})
  853. password = s:taboption("encryption", Value, "password", translate("Password"))
  854. password:depends({mode="sta", eap_type="fast", encryption="wpa2"})
  855. password:depends({mode="sta", eap_type="fast", encryption="wpa"})
  856. password:depends({mode="sta", eap_type="peap", encryption="wpa2"})
  857. password:depends({mode="sta", eap_type="peap", encryption="wpa"})
  858. password:depends({mode="sta", eap_type="ttls", encryption="wpa2"})
  859. password:depends({mode="sta", eap_type="ttls", encryption="wpa"})
  860. password:depends({mode="sta-wds", eap_type="fast", encryption="wpa2"})
  861. password:depends({mode="sta-wds", eap_type="fast", encryption="wpa"})
  862. password:depends({mode="sta-wds", eap_type="peap", encryption="wpa2"})
  863. password:depends({mode="sta-wds", eap_type="peap", encryption="wpa"})
  864. password:depends({mode="sta-wds", eap_type="ttls", encryption="wpa2"})
  865. password:depends({mode="sta-wds", eap_type="ttls", encryption="wpa"})
  866. password.rmempty = true
  867. password.password = true
  868. end
  869. if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
  870. local wpasupplicant = fs.access("/usr/sbin/wpa_supplicant")
  871. local hostcli = fs.access("/usr/sbin/hostapd_cli")
  872. if hostcli and wpasupplicant then
  873. wps = s:taboption("encryption", Flag, "wps_pushbutton", translate("Enable WPS pushbutton, requires WPA(2)-PSK"))
  874. wps.enabled = "1"
  875. wps.disabled = "0"
  876. wps.rmempty = false
  877. wps:depends("encryption", "psk")
  878. wps:depends("encryption", "psk2")
  879. wps:depends("encryption", "psk-mixed")
  880. end
  881. end
  882. return m