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"
42 -- Checks whether the entered extension is valid syntactically.
43 function is_valid_extension(exten)
44 return (exten:match("[#*+0-9NXZ]+$") ~= nil)
48 m = Map (modulename, translate("Call Routing"),
49 translate("This is where you indicate which Google/SIP accounts are used to call what \
50 country/area codes, which users can use which SIP/Google accounts, how incoming \
51 calls are routed, what numbers can get into this PBX with a password, and what \
52 numbers are blacklisted."))
54 -- Recreate the config, and restart services after changes are commited to the configuration.
55 function m.on_after_commit(self)
56 luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
57 luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
60 -- Add Google accounts to all valid accounts, and accounts valid for incoming and outgoing calls.
61 m.uci:foreach(googlemodulename, "gtalk_jabber",
63 -- Add this provider to list of valid accounts.
64 if s1.username ~= nil and s1.name ~= nil then
65 allvalidaccounts[s1.name] = s1.username
66 nallvalidaccounts = nallvalidaccounts + 1
68 if s1.make_outgoing_calls == "yes" then
69 -- Add provider to the associative array of valid outgoing accounts.
70 validoutaccounts[s1.name] = s1.username
71 nvalidoutaccounts = nvalidoutaccounts + 1
74 if s1.register == "yes" then
75 -- Add provider to the associative array of valid outgoing accounts.
76 validinaccounts[s1.name] = s1.username
77 nvalidinaccounts = nvalidinaccounts + 1
82 -- Add SIP accounts to all valid accounts, and accounts valid for incoming and outgoing calls.
83 m.uci:foreach(voipmodulename, "voip_provider",
85 -- Add this provider to list of valid accounts.
86 if s1.defaultuser ~= nil and s1.host ~= nil and s1.name ~= nil then
87 allvalidaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host
88 nallvalidaccounts = nallvalidaccounts + 1
90 if s1.make_outgoing_calls == "yes" then
91 -- Add provider to the associative array of valid outgoing accounts.
92 validoutaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host
93 nvalidoutaccounts = nvalidoutaccounts + 1
96 if s1.register == "yes" then
97 -- Add provider to the associative array of valid outgoing accounts.
98 validinaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host
99 nvalidinaccounts = nvalidinaccounts + 1
104 ----------------------------------------------------------------------------------------------------
105 -- If there are no accounts configured, or no accountsenabled for outgoing calls, display a warning.
106 -- Otherwise, display the usual help text within the section.
107 if nallvalidaccounts == 0 then
108 text = "NOTE: There are no Google or SIP provider accounts configured."
109 elseif nvalidoutaccounts == 0 then
110 text = "NOTE: There are no Google or SIP provider accounts enabled for outgoing calls."
112 text = "If you have more than one account which can make outgoing calls, you \
113 should enter a list of phone numbers and prefixes in the following fields for each \
114 provider listed. Invalid prefixes are removed silently, and only 0-9, X, Z, N, #, *, \
115 and + are valid characters. The letter X matches 0-9, Z matches 1-9, and N matches 2-9. \
116 For example to make calls to Germany through a provider, you can enter 49. To make calls \
117 to North America, you can enter 1NXXNXXXXXX. If one of your providers can make \"local\" \
118 calls to an area code like New York's 646, you can enter 646NXXXXXX for that \
119 provider. You should leave one account with an empty list to make calls with \
120 it by default, if no other provider's prefixes match. The system will automatically \
121 replace an empty list with a message that the provider dials all numbers. Be as specific as \
122 possible (i.e. 1NXXNXXXXXX is better than 1). Please note all international dial codes \
123 are discarded (e.g. 00, 011, 010, 0011). Entries can be made in a space-separated \
124 list, and/or one per line by hitting enter after every one."
127 s = m:section(NamedSection, "outgoing_calls", "call_routing", translate("Outgoing Calls"),
131 m.uci:foreach(googlemodulename, "gtalk_jabber",
133 -- If this provider is valid AND is enabled for outgoing calls, add it to the section.
134 if s1.username ~= nil and s1.name ~= nil and
135 s1.make_outgoing_calls == "yes" then
136 patt = s:option(DynamicList, s1.name, s1.username)
138 -- If the saved field is empty, we return a string
139 -- telling the user that this account would dial any exten.
140 function patt.cfgvalue(self, section)
141 value = self.map:get(section, self.option)
144 return {"Dials any number"}
150 -- Write only valid extensions into the config file.
151 function patt.write(self, section, value)
154 for index, field in ipairs(value) do
155 val = luci.util.trim(value[index])
156 if is_valid_extension(val) == true then
157 newvalue[nindex] = val
161 DynamicList.write(self, section, newvalue)
166 m.uci:foreach(voipmodulename, "voip_provider",
169 -- If this provider is valid AND is enabled for outgoing calls, add it to the section.
170 if s1.defaultuser ~= nil and s1.host ~= nil and
171 s1.name ~= nil and s1.make_outgoing_calls == "yes" then
172 patt = s:option(DynamicList, s1.name, s1.defaultuser .. "@" .. s1.host)
174 -- If the saved field is empty, we return a string
175 -- telling the user that this account would dial any exten.
176 function patt.cfgvalue(self, section)
177 value = self.map:get(section, self.option)
180 return {"Dials any number"}
186 -- Write only valid extensions into the config file.
187 function patt.write(self, section, value)
190 for index, field in ipairs(value) do
191 val = luci.util.trim(value[index])
192 if is_valid_extension(val) == true then
193 newvalue[nindex] = val
197 DynamicList.write(self, section, newvalue)
202 ----------------------------------------------------------------------------------------------------
203 s = m:section(NamedSection, "incoming_calls", "call_routing", translate("Incoming Calls"),
204 translate("For each provider that receives calls, here you can restrict which users to ring \
205 on incoming calls. If the list is empty, the system will indicate that all users \
206 which are enabled for incoming calls will ring. Invalid usernames will be rejected \
207 silently. Also, entering a username here overrides the user's setting to not receive \
208 incoming calls, so this way, you can make users ring only for select providers. \
209 Entries can be made in a space-separated list, and/or one per \
210 line by hitting enter after every one."))
213 m.uci:foreach(googlemodulename, "gtalk_jabber",
215 if s1.username ~= nil and s1.register == "yes" then
216 field_name=string.gsub(s1.username, "%W", "_")
217 gtalkaccts = s:option(DynamicList, field_name, s1.username)
219 -- If the saved field is empty, we return a string
220 -- telling the user that this account would dial any exten.
221 function gtalkaccts.cfgvalue(self, section)
222 value = self.map:get(section, self.option)
225 return {"Rings all users"}
231 -- Write only valid user names.
232 function gtalkaccts.write(self, section, value)
235 for index, field in ipairs(value) do
236 trimuser = luci.util.trim(value[index])
237 if allvalidusers[trimuser] == true then
238 newvalue[nindex] = trimuser
242 DynamicList.write(self, section, newvalue)
248 m.uci:foreach(voipmodulename, "voip_provider",
250 if s1.defaultuser ~= nil and s1.host ~= nil and s1.register == "yes" then
251 field_name=string.gsub(s1.defaultuser .. "_" .. s1.host, "%W", "_")
252 voipaccts = s:option(DynamicList, field_name, s1.defaultuser .. "@" .. s1.host)
254 -- If the saved field is empty, we return a string
255 -- telling the user that this account would dial any exten.
256 function voipaccts.cfgvalue(self, section)
257 value = self.map:get(section, self.option)
260 return {"Rings all users"}
266 -- Write only valid user names.
267 function voipaccts.write(self, section, value)
270 for index, field in ipairs(value) do
271 trimuser = luci.util.trim(value[index])
272 if allvalidusers[trimuser] == true then
273 newvalue[nindex] = trimuser
277 DynamicList.write(self, section, newvalue)
283 ----------------------------------------------------------------------------------------------------
284 s = m:section(NamedSection, "providers_user_can_use", "call_routing",
285 translate("Providers Used for Outgoing Calls"),
286 translate("If you would like, you could restrict which providers users are allowed to use for outgoing \
287 calls. By default all users can use all providers. To show up in the list below the user should \
288 be allowed to make outgoing calls in the \"User Accounts\" page. Enter VoIP providers in the format \
289 username@some.host.name, as listed in \"Outgoing Calls\" above. It's easiest to copy and paste \
290 the providers from above. Invalid entries will be rejected silently. Entries can be made in a \
291 space-separated list, and/or one per line by hitting enter after every one."))
294 m.uci:foreach(usersmodulename, "local_user",
296 -- Add user to list of all valid users.
297 if s1.defaultuser ~= nil then allvalidusers[s1.defaultuser] = true end
299 if s1.defaultuser ~= nil and s1.can_call == "yes" then
300 providers = s:option(DynamicList, s1.defaultuser, s1.defaultuser)
302 -- If the saved field is empty, we return a string
303 -- telling the user that this account would dial any exten.
304 function providers.cfgvalue(self, section)
305 value = self.map:get(section, self.option)
308 return {"Uses all provider accounts"}
311 -- Convert internal names to user@host values.
312 for i,v in ipairs(value) do
313 newvalue[i] = validoutaccounts[v]
319 -- Cook the new values prior to entering them into the config file.
320 -- Also, enter them only if they are valid.
321 function providers.write(self, section, value)
324 for index, field in ipairs(value) do
325 cooked = string.gsub(luci.util.trim(value[index]), "%W", "_")
326 if validoutaccounts[cooked] ~= nil then
327 cookedvalue[cindex] = cooked
331 DynamicList.write(self, section, cookedvalue)
336 ----------------------------------------------------------------------------------------------------
337 s = m:section(TypedSection, "callthrough_numbers", translate("Call-through Numbers"),
338 translate("Designate numbers which will be allowed to call through this system and which user's \
339 privileges it will have."))
343 num = s:option(DynamicList, "callthrough_number_list", translate("Call-through Numbers"))
344 num.datatype = "uinteger"
346 p = s:option(ListValue, "enabled", translate("Enabled"))
347 p:value("yes", translate("Yes"))
348 p:value("no", translate("No"))
351 user = s:option(Value, "defaultuser", translate("User Name"),
352 translate("The number(s) specified above will be able to dial out with this user's providers. \
353 Invalid usernames are dropped silently, please verify that the entry was accepted."))
354 function user.write(self, section, value)
355 trimuser = luci.util.trim(value)
356 if allvalidusers[trimuser] == true then
357 Value.write(self, section, trimuser)
361 pwd = s:option(Value, "pin", translate("PIN"),
362 translate("Your PIN disappears when saved for your protection. It will be changed \
363 only when you enter a value different from the saved one. Leaving the PIN \
364 empty is possible, but please beware of the security implications."))
368 -- We skip reading off the saved value and return nothing.
369 function pwd.cfgvalue(self, section)
373 -- We check the entered value against the saved one, and only write if the entered value is
374 -- something other than the empty string, and it differes from the saved value.
375 function pwd.write(self, section, value)
376 local orig_pwd = m:get(section, self.option)
377 if value and #value > 0 and orig_pwd ~= value then
378 Value.write(self, section, value)
382 ----------------------------------------------------------------------------------------------------
383 s = m:section(NamedSection, "blacklisting", "call_routing", translate("Blacklisted Numbers"),
384 translate("Enter phone numbers that you want to decline calls from automatically. \
385 You should probably omit the country code and any leading \
386 zeroes, but please experiment to make sure you are blocking numbers from your \
387 desired area successfully."))
390 b = s:option(DynamicList, "blacklist1", translate("Dynamic List of Blacklisted Numbers"),
391 translate("Specify numbers individually here. Press enter to add more numbers."))
393 b.datatype = "uinteger"
395 b = s:option(Value, "blacklist2", translate("Space-Separated List of Blacklisted Numbers"),
396 translate("Copy-paste large lists of numbers here."))
397 b.template = "cbi/tvalue"