f4478f61cc9e373c0892ecaa69ecc81739a4e3d3
[project/luci.git] / applications / luci-meshwizard / luasrc / model / cbi / freifunk / meshwizard.lua
1 -- wizard rewrite wip
2
3 local uci = require "luci.model.uci".cursor()
4 local sys = require "luci.sys"
5 local util = require "luci.util"
6 local ip = require "luci.ip"
7
8 local community = "profile_" .. (uci:get("freifunk", "community", "name") or "Freifunk")
9 local mesh_network = ip.IPv4(uci:get_first(community, "community", "mesh_network") or "10.0.0.0/8")
10 local community_ipv6 = uci:get_first(community, "community", "ipv6") or 0
11 local community_ipv6mode = uci:get_first(community, "community", "ipv6_config") or "static"
12 local meshkit_ipv6 = uci:get("meshwizard", "ipv6", "enabled") or 0
13
14 m = Map("meshwizard", translate("Wizard"), translate("This wizard will assist you in setting up your router for Freifunk " ..
15 "or another similar wireless community network."))
16
17 n = m:section(NamedSection, "netconfig", nil, translate("Interfaces"))
18 n.anonymous = true
19
20 -- common functions
21
22 function cbi_configure(device)
23 local configure = n:taboption(device, Flag, device .. "_config", translate("Configure this interface"),
24 translate("Note: this will setup this interface for mesh operation, i.e. add to zone 'freifunk' and enable olsr."))
25 end
26
27 function cbi_ip4addr(device)
28 local ip4addr = n:taboption(device, Value, device .. "_ip4addr", translate("Mesh IP address"),
29 translate("This is a unique address in the mesh (e.g. 10.1.1.1) and has to be registered at your local community."))
30 ip4addr:depends(device .. "_config", 1)
31 ip4addr.datatype = "ip4addr"
32 function ip4addr.validate(self, value)
33 local x = ip.IPv4(value)
34 if mesh_network:contains(x) then
35 return value
36 else
37 return nil, translate("The given IP address is not inside the mesh network range ") ..
38 "(" .. mesh_network:string() .. ")."
39 end
40 end
41 end
42
43 function cbi_ip6addr(device)
44 local ip6addr = n:taboption(device, Value, device .. "_ip6addr", translate("Mesh IPv6 address"),
45 translate("This is a unique IPv6 address in CIDR notation (e.g. 2001:1:2:3::1/64) and has to be registered at your local community."))
46 ip6addr:depends(device .. "_config", 1)
47 ip6addr.datatype = "ip6addr"
48 end
49
50
51 function cbi_dhcp(device)
52 local dhcp = n:taboption(device, Flag, device .. "_dhcp", translate("Enable DHCP"),
53 translate("DHCP will automatically assign ip addresses to clients"))
54 dhcp:depends(device .. "_config", 1)
55 dhcp.rmempty = true
56 end
57
58 function cbi_ra(device)
59 local ra = n:taboption(device, Flag, device .. "_ipv6ra", translate("Enable RA"),
60 translate("Send router advertisements on this device."))
61 ra:depends(device .. "_config", 1)
62 ra.rmempty = true
63 end
64
65 function cbi_dhcprange(device)
66 local dhcprange = n:taboption(device, Value, device .. "_dhcprange", translate("DHCP IP range"),
67 translate("The IP range from which clients are assigned ip addresses (e.g. 10.1.2.1/28). " ..
68 "If this is a range inside your mesh network range, then it will be announced as HNA. Any other range will use NAT. " ..
69 "If left empty then the defaults from the community profile will be used."))
70 dhcprange:depends(device .. "_dhcp", "1")
71 dhcprange.rmempty = true
72 dhcprange.datatype = "ip4addr"
73 end
74 -- create tabs and config for wireless
75 local nets={}
76 uci:foreach("wireless", "wifi-device", function(section)
77 local device = section[".name"]
78 table.insert(nets, device)
79 end)
80
81 local wired_nets = {}
82 uci:foreach("network", "interface", function(section)
83 local device = section[".name"]
84 if not util.contains(nets, device) and device ~= "loopback" and not device:find("wireless") then
85 table.insert(nets, device)
86 table.insert(wired_nets, device)
87 end
88 end)
89
90 for _, net in util.spairs(nets, function(a,b) return (nets[a] < nets[b]) end) do
91 n:tab(net, net)
92 end
93
94 -- create cbi config for wireless
95 uci:foreach("wireless", "wifi-device", function(section)
96 local device = section[".name"]
97 local hwtype = section.type
98 local syscc = section.country or uci:get(community, "wifi_device", "country") or
99 uci:get("freifunk", "wifi_device", "country")
100
101 cbi_configure(device)
102
103 -- Channel selection
104
105 if hwtype == "atheros" then
106 local cc = util.trim(sys.exec("grep -i '" .. syscc .. "' /lib/wifi/cc_translate.txt |cut -d ' ' -f 2")) or 0
107 sys.exec('"echo " .. cc .. " > /proc/sys/dev/" .. device .. "/countrycode"')
108 elseif hwtype == "mac80211" then
109 sys.exec("iw reg set " .. syscc)
110 elseif hwtype == "broadcom" then
111 sys.exec ("wlc country " .. syscc)
112 end
113
114 local chan = n:taboption(device, ListValue, device .. "_channel", translate("Channel"),
115 translate("Your device and neighbouring nodes have to use the same channel."))
116 chan:depends(device .. "_config", 1)
117 chan:value('default')
118
119 local iwinfo = sys.wifi.getiwinfo(device)
120 if iwinfo then
121 for _, f in ipairs(iwinfo.freqlist) do
122 if not f.restricted then
123 chan:value(f.channel)
124 end
125 end
126 end
127 -- IPv4 address
128 cbi_ip4addr(device)
129
130 -- DHCP enable
131 cbi_dhcp(device)
132
133 -- DHCP range
134 cbi_dhcprange(device)
135
136 -- IPv6 addr and RA
137 if community_ipv6 == "1" then
138 if community_ipv6mode == "static" then
139 cbi_ip6addr(device)
140 end
141 cbi_ra(device)
142 end
143
144 -- Enable VAP
145 if hwtype == "atheros" then
146 local vap = n:taboption(device, Flag, device .. "_vap", translate("Virtual Access Point (VAP)"),
147 translate("This will setup a new virtual wireless interface in Access Point mode."))
148 vap:depends(device .. "_dhcp", "1")
149 vap.rmempty = true
150 end
151 end)
152
153 for _, device in pairs(wired_nets) do
154 cbi_configure(device)
155 cbi_ip4addr(device)
156 cbi_dhcp(device)
157 cbi_dhcprange(device)
158 -- IPv6 addr and RA
159 if community_ipv6 == "1" then
160 if community_ipv6mode == "static" then
161 cbi_ip6addr(device)
162 end
163 cbi_ra(device)
164 end
165 end
166
167 -- General settings
168 g = m:section(TypedSection, "general", translate("General Settings"))
169 g.anonymous = true
170
171 local cleanup = g:option(Flag, "cleanup", translate("Cleanup config"),
172 translate("If this is selected then config is cleaned before setting new config options."))
173 cleanup.default = "1"
174
175 local restrict = g:option(Flag, "local_restrict", translate("Protect LAN"),
176 translate("Check this to protect your LAN from other nodes or clients") .. " (" .. translate("recommended") .. ").")
177
178 local share = g:option(Flag, "sharenet", translate("Share your internet connection"),
179 translate("Select this to allow others to use your connection to access the internet."))
180 share.rmempty = true
181
182 -- IPv6 config
183 if community_ipv6 == "1" then
184 v6 = m:section(NamedSection, "ipv6", nil, translate("IPv6 Settings"))
185 local enabled = v6:option(Flag, "enabled", translate("Enabled"),
186 translate("Activate or deactivate IPv6 config globally."))
187 enabled.default = meshkit_ipv6
188 enabled.rmempty = false
189 end
190
191 return m