2 Copyright 2011 Iordan Iordanov <iiordanov (AT) gmail.com>
4 This file is part of luci-pbx.
6 luci-pbx is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 luci-pbx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with luci-pbx. If not, see <http://www.gnu.org/licenses/>.
20 if nixio.fs.access("/etc/init.d/asterisk") then
22 elseif nixio.fs.access("/etc/init.d/freeswitch") then
28 modulename = "pbx-calls"
29 voipmodulename = "pbx-voip"
30 googlemodulename = "pbx-google"
31 usersmodulename = "pbx-users"
35 -- Checks whether the entered extension is valid syntactically.
36 function is_valid_extension(exten)
37 return (exten:match("[#*+0-9NXZ]+$") ~= nil)
41 m = Map (modulename, translate("Call Routing"),
42 translate("This is where you indicate which Google/SIP accounts are used to call what \
43 country/area codes, which users can use which SIP/Google accounts, how incoming\
44 calls are routed, what numbers can get into this PBX with a password, and what\
45 numbers are blacklisted."))
47 -- Recreate the config, and restart services after changes are commited to the configuration.
48 function m.on_after_commit(self)
49 luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
50 luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
53 ----------------------------------------------------------------------------------------------------
54 s = m:section(NamedSection, "outgoing_calls", "call_routing", translate("Outgoing Calls"),
55 translate("If you have more than one account which can make outgoing calls, you\
56 should enter a list of phone numbers and prefixes in the following fields for each\
57 provider listed. Invalid prefixes are removed silently, and only 0-9, X, Z, N, #, *,\
58 and + are valid characters. The letter X matches 0-9, Z matches 1-9, and N matches 2-9.\
59 For example to make calls to Germany through a provider, you can enter 49. To make calls\
60 to North America, you can enter 1NXXNXXXXXX. If one of your providers can make \"local\"\
61 calls to an area code like New York's 646, you can enter 646NXXXXXX for that\
62 provider. You should leave one account with an empty list to make calls with\
63 it by default, if no other provider's prefixes match. The system will automatically\
64 replace an empty list with a message that the provider dials all numbers. Be as specific as\
65 possible (i.e. 1NXXNXXXXXX is better than 1). Please note all international dial codes\
66 are discarded (e.g. 00, 011, 010, 0011). Entries can be made in a\
67 space-separated list, and/or one per line by hitting enter after every one."))
70 m.uci:foreach(googlemodulename, "gtalk_jabber",
72 if s1.username ~= nil and s1.name ~= nil and
73 s1.make_outgoing_calls == "yes" then
74 patt = s:option(DynamicList, s1.name, s1.username)
76 -- Add provider to the associative array of valid accounts.
77 validoutaccounts[s1.name] = s1.username
79 -- If the saved field is empty, we return a string
80 -- telling the user that this account would dial any exten.
81 function patt.cfgvalue(self, section)
82 value = self.map:get(section, self.option)
85 return {"Dials any number"}
91 -- Write only valid extensions into the config file.
92 function patt.write(self, section, value)
95 for index, field in ipairs(value) do
96 val = luci.util.trim(value[index])
97 if is_valid_extension(val) == true then
98 newvalue[nindex] = val
102 DynamicList.write(self, section, newvalue)
107 m.uci:foreach(voipmodulename, "voip_provider",
109 if s1.defaultuser ~= nil and s1.host ~= nil and
110 s1.name ~= nil and s1.make_outgoing_calls == "yes" then
111 patt = s:option(DynamicList, s1.name, s1.defaultuser .. "@" .. s1.host)
113 -- Add provider to the associative array of valid accounts.
114 validoutaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host
116 -- If the saved field is empty, we return a string
117 -- telling the user that this account would dial any exten.
118 function patt.cfgvalue(self, section)
119 value = self.map:get(section, self.option)
122 return {"Dials any number"}
128 -- Write only valid extensions into the config file.
129 function patt.write(self, section, value)
132 for index, field in ipairs(value) do
133 val = luci.util.trim(value[index])
134 if is_valid_extension(val) == true then
135 newvalue[nindex] = val
139 DynamicList.write(self, section, newvalue)
144 ----------------------------------------------------------------------------------------------------
145 s = m:section(NamedSection, "incoming_calls", "call_routing", translate("Incoming Calls"),
146 translate("For each provider that receives calls, here you can restrict which users to ring\
147 on incoming calls. If the list is empty, the system will indicate that all users\
148 which are enabled for incoming calls will ring. Invalid usernames will be rejected\
149 silently. Also, entering a username here overrides the user's setting to not receive\
150 incoming calls, so this way, you can make users ring only for select providers.\
151 Entries can be made in a space-separated list, and/or one per\
152 line by hitting enter after every one."))
155 m.uci:foreach(googlemodulename, "gtalk_jabber",
157 if s1.username ~= nil and s1.register == "yes" then
158 field_name=string.gsub(s1.username, "%W", "_")
159 gtalkaccts = s:option(DynamicList, field_name, s1.username)
161 -- If the saved field is empty, we return a string
162 -- telling the user that this account would dial any exten.
163 function gtalkaccts.cfgvalue(self, section)
164 value = self.map:get(section, self.option)
167 return {"Rings all users"}
173 -- Write only valid user names.
174 function gtalkaccts.write(self, section, value)
177 for index, field in ipairs(value) do
178 trimuser = luci.util.trim(value[index])
179 if allvalidusers[trimuser] == true then
180 newvalue[nindex] = trimuser
184 DynamicList.write(self, section, newvalue)
190 m.uci:foreach(voipmodulename, "voip_provider",
192 if s1.defaultuser ~= nil and s1.host ~= nil and s1.register == "yes" then
193 field_name=string.gsub(s1.defaultuser .. "_" .. s1.host, "%W", "_")
194 voipaccts = s:option(DynamicList, field_name, s1.defaultuser .. "@" .. s1.host)
196 -- If the saved field is empty, we return a string
197 -- telling the user that this account would dial any exten.
198 function voipaccts.cfgvalue(self, section)
199 value = self.map:get(section, self.option)
202 return {"Rings all users"}
208 -- Write only valid user names.
209 function voipaccts.write(self, section, value)
212 for index, field in ipairs(value) do
213 trimuser = luci.util.trim(value[index])
214 if allvalidusers[trimuser] == true then
215 newvalue[nindex] = trimuser
219 DynamicList.write(self, section, newvalue)
224 ----------------------------------------------------------------------------------------------------
225 s = m:section(NamedSection, "providers_user_can_use", "call_routing",
226 translate("Providers Used for Outgoing Calls"),
227 translate("If you would like, you could restrict which providers users are allowed to use for outgoing\
228 calls. By default all users can use all providers. To show up in the list below the user should\
229 be allowed to make outgoing calls in the \"User Accounts\" page. Enter VoIP providers in the format\
230 username@some.host.name, as listed in \"Outgoing Calls\" above. It's easiest to copy and paste\
231 the providers from above. Invalid entries will be rejected silently. Entries can be made in a \
232 space-separated list, and/or one per line by hitting enter after every one."))
235 m.uci:foreach(usersmodulename, "local_user",
237 -- Add user to list of all valid users.
238 if s1.defaultuser ~= nil then allvalidusers[s1.defaultuser] = true end
240 if s1.defaultuser ~= nil and s1.can_call == "yes" then
241 providers = s:option(DynamicList, s1.defaultuser, s1.defaultuser)
243 -- If the saved field is empty, we return a string
244 -- telling the user that this account would dial any exten.
245 function providers.cfgvalue(self, section)
246 value = self.map:get(section, self.option)
249 return {"Uses all provider accounts"}
252 -- Convert internal names to user@host values.
253 for i,v in ipairs(value) do
254 newvalue[i] = validoutaccounts[v]
260 -- Cook the new values prior to entering them into the config file.
261 -- Also, enter them only if they are valid.
262 function providers.write(self, section, value)
265 for index, field in ipairs(value) do
266 cooked = string.gsub(luci.util.trim(value[index]), "%W", "_")
267 if validoutaccounts[cooked] ~= nil then
268 cookedvalue[cindex] = cooked
272 DynamicList.write(self, section, cookedvalue)
277 ----------------------------------------------------------------------------------------------------
278 s = m:section(TypedSection, "callthrough_numbers", translate("Call-through Numbers"),
279 translate("Designate numbers which will be allowed to call through this system and which user's\
280 privileges it will have."))
284 num = s:option(DynamicList, "callthrough_number_list", translate("Call-through Numbers"))
285 num.datatype = "uinteger"
287 p = s:option(ListValue, "enabled", translate("Enabled"))
288 p:value("yes", translate("Yes"))
289 p:value("no", translate("No"))
292 user = s:option(Value, "defaultuser", translate("User Name"),
293 translate("The number(s) specified above will be able to dial out with this user's providers.\
294 Invalid usernames are dropped silently, please verify that the entry was accepted."))
295 function user.write(self, section, value)
296 trimuser = luci.util.trim(value)
297 if allvalidusers[trimuser] == true then
298 Value.write(self, section, trimuser)
302 pwd = s:option(Value, "pin", translate("PIN"),
303 translate("Your PIN disappears when saved for your protection. It will be changed\
304 only when you enter a value different from the saved one. Leaving the PIN\
305 empty is possible, but please beware of the security implications."))
309 -- We skip reading off the saved value and return nothing.
310 function pwd.cfgvalue(self, section)
314 -- We check the entered value against the saved one, and only write if the entered value is
315 -- something other than the empty string, and it differes from the saved value.
316 function pwd.write(self, section, value)
317 local orig_pwd = m:get(section, self.option)
318 if value and #value > 0 and orig_pwd ~= value then
319 Value.write(self, section, value)
323 ----------------------------------------------------------------------------------------------------
324 s = m:section(NamedSection, "blacklisting", "call_routing", translate("Blacklisted Numbers"),
325 translate("Enter phone numbers that you want to decline calls from automatically.\
326 You should probably omit the country code and any leading\
327 zeroes, but please experiment to make sure you are blocking numbers from your\
328 desired area successfully."))
331 b = s:option(DynamicList, "blacklist1", translate("Dynamic List of Blacklisted Numbers"),
332 translate("Specify numbers individually here. Press enter to add more numbers."))
334 b.datatype = "uinteger"
336 b = s:option(Value, "blacklist2", translate("Space-Separated List of Blacklisted Numbers"),
337 translate("Copy-paste large lists of numbers here."))
338 b.template = "cbi/tvalue"