1) Massive whitespace reorganization (untabified, and made consistent everything).

2) Dropped some currently unneeded, commented-out, code from pbx-users.lua.
This commit is contained in:
Iordan Iordanov 2011-11-05 18:34:12 +00:00
parent f976533433
commit 5cd67479c3
8 changed files with 804 additions and 818 deletions

View file

@ -20,10 +20,10 @@
module("luci.controller.pbx", package.seeall) module("luci.controller.pbx", package.seeall)
function index() function index()
entry({"admin", "services", "pbx"}, cbi("pbx"), "PBX", 80) entry({"admin", "services", "pbx"}, cbi("pbx"), "PBX", 80)
entry({"admin", "services", "pbx", "pbx-google"}, cbi("pbx-google"), "Google Accounts", 1) entry({"admin", "services", "pbx", "pbx-google"}, cbi("pbx-google"), "Google Accounts", 1)
entry({"admin", "services", "pbx", "pbx-voip"}, cbi("pbx-voip"), "SIP Accounts", 2) entry({"admin", "services", "pbx", "pbx-voip"}, cbi("pbx-voip"), "SIP Accounts", 2)
entry({"admin", "services", "pbx", "pbx-users"}, cbi("pbx-users"), "User Accounts", 3) entry({"admin", "services", "pbx", "pbx-users"}, cbi("pbx-users"), "User Accounts", 3)
entry({"admin", "services", "pbx", "pbx-calls"}, cbi("pbx-calls"), "Call Routing", 4) entry({"admin", "services", "pbx", "pbx-calls"}, cbi("pbx-calls"), "Call Routing", 4)
entry({"admin", "services", "pbx", "pbs-advanced"}, cbi("pbx-advanced"), "Advanced Settings", 5) entry({"admin", "services", "pbx", "pbs-advanced"}, cbi("pbx-advanced"), "Advanced Settings", 5)
end end

View file

@ -33,194 +33,194 @@ defaultrtpend = 19900
-- Returns all the network related settings, including a constructed RTP range -- Returns all the network related settings, including a constructed RTP range
function get_network_info() function get_network_info()
externhost = m.uci:get(modulename, "advanced", "externhost") externhost = m.uci:get(modulename, "advanced", "externhost")
ipaddr = m.uci:get("network", "lan", "ipaddr") ipaddr = m.uci:get("network", "lan", "ipaddr")
bindport = m.uci:get(modulename, "advanced", "bindport") bindport = m.uci:get(modulename, "advanced", "bindport")
rtpstart = m.uci:get(modulename, "advanced", "rtpstart") rtpstart = m.uci:get(modulename, "advanced", "rtpstart")
rtpend = m.uci:get(modulename, "advanced", "rtpend") rtpend = m.uci:get(modulename, "advanced", "rtpend")
if bindport == nil then bindport = defaultbindport end if bindport == nil then bindport = defaultbindport end
if rtpstart == nil then rtpstart = defaultrtpstart end if rtpstart == nil then rtpstart = defaultrtpstart end
if rtpend == nil then rtpend = defaultrtpend end if rtpend == nil then rtpend = defaultrtpend end
if rtpstart == nil or rtpend == nil then if rtpstart == nil or rtpend == nil then
rtprange = nil rtprange = nil
else else
rtprange = rtpstart .. "-" .. rtpend rtprange = rtpstart .. "-" .. rtpend
end end
return bindport, rtprange, ipaddr, externhost return bindport, rtprange, ipaddr, externhost
end end
-- If not present, insert empty rules in the given config & section named PBX-SIP and PBX-RTP -- If not present, insert empty rules in the given config & section named PBX-SIP and PBX-RTP
function insert_empty_sip_rtp_rules(config, section) function insert_empty_sip_rtp_rules(config, section)
-- Add rules named PBX-SIP and PBX-RTP if not existing -- Add rules named PBX-SIP and PBX-RTP if not existing
found_sip_rule = false found_sip_rule = false
found_rtp_rule = false found_rtp_rule = false
m.uci:foreach(config, section, m.uci:foreach(config, section,
function(s1) function(s1)
if s1._name == 'PBX-SIP' then if s1._name == 'PBX-SIP' then
found_sip_rule = true found_sip_rule = true
elseif s1._name == 'PBX-RTP' then elseif s1._name == 'PBX-RTP' then
found_rtp_rule = true found_rtp_rule = true
end end
end) end)
if found_sip_rule ~= true then if found_sip_rule ~= true then
newrule=m.uci:add(config, section) newrule=m.uci:add(config, section)
m.uci:set(config, newrule, '_name', 'PBX-SIP') m.uci:set(config, newrule, '_name', 'PBX-SIP')
end end
if found_rtp_rule ~= true then if found_rtp_rule ~= true then
newrule=m.uci:add(config, section) newrule=m.uci:add(config, section)
m.uci:set(config, newrule, '_name', 'PBX-RTP') m.uci:set(config, newrule, '_name', 'PBX-RTP')
end end
end end
-- Delete rules in the given config & section named PBX-SIP and PBX-RTP -- Delete rules in the given config & section named PBX-SIP and PBX-RTP
function delete_sip_rtp_rules(config, section) function delete_sip_rtp_rules(config, section)
-- Remove rules named PBX-SIP and PBX-RTP -- Remove rules named PBX-SIP and PBX-RTP
commit = false commit = false
m.uci:foreach(config, section, m.uci:foreach(config, section,
function(s1) function(s1)
if s1._name == 'PBX-SIP' or s1._name == 'PBX-RTP' then if s1._name == 'PBX-SIP' or s1._name == 'PBX-RTP' then
m.uci:delete(config, s1['.name']) m.uci:delete(config, s1['.name'])
commit = true commit = true
end end
end) end)
-- If something changed, then we commit the config. -- If something changed, then we commit the config.
if commit == true then m.uci:commit(config) end if commit == true then m.uci:commit(config) end
end end
-- Deletes QoS rules associated with this PBX. -- Deletes QoS rules associated with this PBX.
function delete_qos_rules() function delete_qos_rules()
delete_sip_rtp_rules ("qos", "classify") delete_sip_rtp_rules ("qos", "classify")
end end
function insert_qos_rules() function insert_qos_rules()
-- Insert empty PBX-SIP and PBX-RTP rules if not present. -- Insert empty PBX-SIP and PBX-RTP rules if not present.
insert_empty_sip_rtp_rules ("qos", "classify") insert_empty_sip_rtp_rules ("qos", "classify")
-- Get the network information -- Get the network information
bindport, rtprange, ipaddr, externhost = get_network_info() bindport, rtprange, ipaddr, externhost = get_network_info()
-- Iterate through the QoS rules, and if there is no other rule with the same port -- Iterate through the QoS rules, and if there is no other rule with the same port
-- range at the express service level, insert this rule. -- range at the express service level, insert this rule.
commit = false commit = false
m.uci:foreach("qos", "classify", m.uci:foreach("qos", "classify",
function(s1) function(s1)
if s1._name == 'PBX-SIP' then if s1._name == 'PBX-SIP' then
if s1.ports ~= bindport or s1.target ~= "Express" or s1.proto ~= "udp" then if s1.ports ~= bindport or s1.target ~= "Express" or s1.proto ~= "udp" then
m.uci:set("qos", s1['.name'], "ports", bindport) m.uci:set("qos", s1['.name'], "ports", bindport)
m.uci:set("qos", s1['.name'], "proto", "udp") m.uci:set("qos", s1['.name'], "proto", "udp")
m.uci:set("qos", s1['.name'], "target", "Express") m.uci:set("qos", s1['.name'], "target", "Express")
commit = true commit = true
end end
elseif s1._name == 'PBX-RTP' then elseif s1._name == 'PBX-RTP' then
if s1.ports ~= rtprange or s1.target ~= "Express" or s1.proto ~= "udp" then if s1.ports ~= rtprange or s1.target ~= "Express" or s1.proto ~= "udp" then
m.uci:set("qos", s1['.name'], "ports", rtprange) m.uci:set("qos", s1['.name'], "ports", rtprange)
m.uci:set("qos", s1['.name'], "proto", "udp") m.uci:set("qos", s1['.name'], "proto", "udp")
m.uci:set("qos", s1['.name'], "target", "Express") m.uci:set("qos", s1['.name'], "target", "Express")
commit = true commit = true
end end
end end
end) end)
-- If something changed, then we commit the qos config. -- If something changed, then we commit the qos config.
if commit == true then m.uci:commit("qos") end if commit == true then m.uci:commit("qos") end
end end
-- This function is a (so far) unsuccessful attempt to manipulate the firewall rules from here -- This function is a (so far) unsuccessful attempt to manipulate the firewall rules from here
-- Need to do more testing and eventually move to this mode. -- Need to do more testing and eventually move to this mode.
function maintain_firewall_rules() function maintain_firewall_rules()
-- Get the network information -- Get the network information
bindport, rtprange, ipaddr, externhost = get_network_info() bindport, rtprange, ipaddr, externhost = get_network_info()
commit = false commit = false
-- Only if externhost is set, do we control firewall rules. -- Only if externhost is set, do we control firewall rules.
if externhost ~= nil and bindport ~= nil and rtprange ~= nil then if externhost ~= nil and bindport ~= nil and rtprange ~= nil then
-- Insert empty PBX-SIP and PBX-RTP rules if not present. -- Insert empty PBX-SIP and PBX-RTP rules if not present.
insert_empty_sip_rtp_rules ("firewall", "rule") insert_empty_sip_rtp_rules ("firewall", "rule")
-- Iterate through the firewall rules, and if the dest_port and dest_ip setting of the\ -- Iterate through the firewall rules, and if the dest_port and dest_ip setting of the\
-- SIP and RTP rule do not match what we want configured, set all the entries in the rule\ -- SIP and RTP rule do not match what we want configured, set all the entries in the rule\
-- appropriately. -- appropriately.
m.uci:foreach("firewall", "rule", m.uci:foreach("firewall", "rule",
function(s1) function(s1)
if s1._name == 'PBX-SIP' then if s1._name == 'PBX-SIP' then
if s1.dest_port ~= bindport then if s1.dest_port ~= bindport then
m.uci:set("firewall", s1['.name'], "dest_port", bindport) m.uci:set("firewall", s1['.name'], "dest_port", bindport)
m.uci:set("firewall", s1['.name'], "src", "wan") m.uci:set("firewall", s1['.name'], "src", "wan")
m.uci:set("firewall", s1['.name'], "proto", "udp") m.uci:set("firewall", s1['.name'], "proto", "udp")
m.uci:set("firewall", s1['.name'], "target", "ACCEPT") m.uci:set("firewall", s1['.name'], "target", "ACCEPT")
commit = true commit = true
end end
elseif s1._name == 'PBX-RTP' then elseif s1._name == 'PBX-RTP' then
if s1.dest_port ~= rtprange then if s1.dest_port ~= rtprange then
m.uci:set("firewall", s1['.name'], "dest_port", rtprange) m.uci:set("firewall", s1['.name'], "dest_port", rtprange)
m.uci:set("firewall", s1['.name'], "src", "wan") m.uci:set("firewall", s1['.name'], "src", "wan")
m.uci:set("firewall", s1['.name'], "proto", "udp") m.uci:set("firewall", s1['.name'], "proto", "udp")
m.uci:set("firewall", s1['.name'], "target", "ACCEPT") m.uci:set("firewall", s1['.name'], "target", "ACCEPT")
commit = true commit = true
end end
end end
end) end)
else else
-- We delete the firewall rules if one or more of the necessary parameters are not set. -- We delete the firewall rules if one or more of the necessary parameters are not set.
sip_rule_name=nil sip_rule_name=nil
rtp_rule_name=nil rtp_rule_name=nil
-- First discover the configuration names of the rules. -- First discover the configuration names of the rules.
m.uci:foreach("firewall", "rule", m.uci:foreach("firewall", "rule",
function(s1) function(s1)
if s1._name == 'PBX-SIP' then if s1._name == 'PBX-SIP' then
sip_rule_name = s1['.name'] sip_rule_name = s1['.name']
elseif s1._name == 'PBX-RTP' then elseif s1._name == 'PBX-RTP' then
rtp_rule_name = s1['.name'] rtp_rule_name = s1['.name']
end end
end) end)
-- Then, using the names, actually delete the rules. -- Then, using the names, actually delete the rules.
if sip_rule_name ~= nil then if sip_rule_name ~= nil then
m.uci:delete("firewall", sip_rule_name) m.uci:delete("firewall", sip_rule_name)
commit = true commit = true
end end
if rtp_rule_name ~= nil then if rtp_rule_name ~= nil then
m.uci:delete("firewall", rtp_rule_name) m.uci:delete("firewall", rtp_rule_name)
commit = true commit = true
end end
end end
-- If something changed, then we commit the firewall config. -- If something changed, then we commit the firewall config.
if commit == true then m.uci:commit("firewall") end if commit == true then m.uci:commit("firewall") end
end end
m = Map (modulename, translate("Advanced Settings"), m = Map (modulename, translate("Advanced Settings"),
translate("This section contains settings which do not need to be changed under\ translate("This section contains settings which do not need to be changed under\
normal circumstances. In addition, here you can configure your system\ normal circumstances. In addition, here you can configure your system\
for use with remote SIP devices, and resolve call quality issues by enabling\ for use with remote SIP devices, and resolve call quality issues by enabling\
the insertion of QoS rules.")) the insertion of QoS rules."))
-- Recreate the voip server config, and restart necessary services after changes are commited -- Recreate the voip server config, and restart necessary services after changes are commited
-- to the advanced configuration. The firewall must restart because of "Remote Usage". -- to the advanced configuration. The firewall must restart because of "Remote Usage".
function m.on_after_commit(self) function m.on_after_commit(self)
-- Make sure firewall rules are in place -- Make sure firewall rules are in place
maintain_firewall_rules() maintain_firewall_rules()
-- If insertion of QoS rules is enabled -- If insertion of QoS rules is enabled
if m.uci:get(modulename, "advanced", "qos_enabled") == "yes" then if m.uci:get(modulename, "advanced", "qos_enabled") == "yes" then
insert_qos_rules() insert_qos_rules()
else else
delete_qos_rules() delete_qos_rules()
end end
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null") luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null") luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/firewall restart 1\>/dev/null 2\>/dev/null") luci.sys.call("/etc/init.d/firewall restart 1\>/dev/null 2\>/dev/null")
end end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
@ -230,45 +230,46 @@ s.anonymous = true
s:tab("general", translate("General Settings")) s:tab("general", translate("General Settings"))
s:tab("remote_usage", translate("Remote Usage"), s:tab("remote_usage", translate("Remote Usage"),
translatef("You can use your SIP devices/softphones with this system from a remote location\ translatef("You can use your SIP devices/softphones with this system from a remote location\
as well, as long as your Internet Service Provider gives you a public IP.\ as well, as long as your Internet Service Provider gives you a public IP.\
You will be able to call other local users for free (e.g. other Analog Telephone Adapters (ATAs))\ You will be able to call other local users for free (e.g. other Analog Telephone Adapters (ATAs))\
and use your VoIP providers to make calls as if you were at local to the PBX.\ and use your VoIP providers to make calls as if you were at local to the PBX.\
After configuring this tab, go back to where users are configured and see the new\ After configuring this tab, go back to where users are configured and see the new\
Server and Port setting you need to configure the SIP devices with. Please note that by default\ Server and Port setting you need to configure the SIP devices with. Please note that by default\
%s uses UDP port range %d to %d for RTP traffic (which carries voice), in case you need to configure\ %s uses UDP port range %d to %d for RTP traffic (which carries voice), in case you need to configure\
NAT or QoS on another device.", appname, defaultrtpstart, defaultrtpend)) NAT or QoS on another device.", appname, defaultrtpstart, defaultrtpend))
s:tab("qos", translate("QoS Settings"), s:tab("qos", translate("QoS Settings"),
translate("If you experience jittery or high latency audio during heavy downloads, you may want to enable QoS.\ translate("If you experience jittery or high latency audio during heavy downloads, you may want \
QoS prioritizes traffic to and from your network for specified ports and IP addresses, resulting in\ to enable QoS. QoS prioritizes traffic to and from your network for specified ports and IP \
better latency and throughput for sound in our case. If enabled below, a QoS rule for this service will\ addresses, resulting in better latency and throughput for sound in our case. If enabled below, \
be configured by the PBX automatically, but you must visit the QoS configuration page (Network->QoS) to\ a QoS rule for this service will be configured by the PBX automatically, but you must visit the \
configure other critical QoS settings like Download and Upload speed.")) QoS configuration page (Network->QoS) to configure other critical QoS settings like Download \
and Upload speed."))
ua = s:taboption("general", Value, "useragent", translate("User Agent String"), ua = s:taboption("general", Value, "useragent", translate("User Agent String"),
translate("This is the name that the VoIP server will use to identify itself when\ translate("This is the name that the VoIP server will use to identify itself when\
registering to VoIP (SIP) providers. Some providers require this to a specific\ registering to VoIP (SIP) providers. Some providers require this to a specific\
string matching a hardware SIP device.")) string matching a hardware SIP device."))
ua.default = appname ua.default = appname
h = s:taboption("remote_usage", Value, "externhost", translate("Domain Name/Dynamic Domain Name"), h = s:taboption("remote_usage", Value, "externhost", translate("Domain Name/Dynamic Domain Name"),
translate("You should either have registered a domain name and have a static IP\ translate("You should either have registered a domain name and have a static IP\
address, or have configured Dynamic DNS on this router. Enter a\ address, or have configured Dynamic DNS on this router. Enter a\
domain name which resolves to your external IP address.")) domain name which resolves to your external IP address."))
h.datatype = "hostname" h.datatype = "hostname"
p = s:taboption("remote_usage", Value, "bindport", translate("External SIP Port"), p = s:taboption("remote_usage", Value, "bindport", translate("External SIP Port"),
translate("Pick a random port number between 6500 and 9500 for the service to listen on.\ translate("Pick a random port number between 6500 and 9500 for the service to listen on.\
Do not pick the standard 5060, because it is often subject to brute-force attacks.\ Do not pick the standard 5060, because it is often subject to brute-force attacks.\
When finished, (1) click \"Save and Apply\", and (2) click the \"Restart VoIP Service\"\ When finished, (1) click \"Save and Apply\", and (2) click the \"Restart VoIP Service\"\
button above. Finally, (3) look in the \"SIP Device/Softphone Accounts\" section for\ button above. Finally, (3) look in the \"SIP Device/Softphone Accounts\" section for\
updated Server and Port settings for your SIP Devices/Softphones.")) updated Server and Port settings for your SIP Devices/Softphones."))
p.datatype = "port" p.datatype = "port"
p = s:taboption("remote_usage", Value, "rtpstart", translate("RTP Port Range Start"), p = s:taboption("remote_usage", Value, "rtpstart", translate("RTP Port Range Start"),
translate("RTP traffic carries actual voice packets. This is the start of the port range\ translate("RTP traffic carries actual voice packets. This is the start of the port range\
which will be used for setting up RTP communication. It's usually OK to leave this\ which will be used for setting up RTP communication. It's usually OK to leave this\
at the default value.")) at the default value."))
p.datatype = "port" p.datatype = "port"
p.default = defaultrtpstart p.default = defaultrtpstart

View file

@ -39,245 +39,245 @@ end
m = Map (modulename, translate("Call Routing"), m = Map (modulename, translate("Call Routing"),
translate("This is where you indicate which Google/SIP accounts are used to call what \ translate("This is where you indicate which Google/SIP accounts are used to call what \
country/area codes, which users can use which SIP/Google accounts, how incoming\ country/area codes, which users can use which SIP/Google accounts, how incoming\
calls are routed, what numbers can get into this PBX with a password, and what\ calls are routed, what numbers can get into this PBX with a password, and what\
numbers are blacklisted.")) numbers are blacklisted."))
-- Recreate the config, and restart services after changes are commited to the configuration. -- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self) function m.on_after_commit(self)
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null") luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null") luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
end end
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "outgoing_calls", "call_routing", translate("Outgoing Calls"), s = m:section(NamedSection, "outgoing_calls", "call_routing", translate("Outgoing Calls"),
translate("If you have more than one account which can make outgoing calls, you\ translate("If you have more than one account which can make outgoing calls, you\
should enter a list of phone numbers and prefixes in the following fields for each\ should enter a list of phone numbers and prefixes in the following fields for each\
provider listed. Invalid prefixes are removed silently, and only 0-9, X, Z, N, #, *,\ provider listed. Invalid prefixes are removed silently, and only 0-9, X, Z, N, #, *,\
and + are valid characters. The letter X matches 0-9, Z matches 1-9, and N matches 2-9.\ and + are valid characters. The letter X matches 0-9, Z matches 1-9, and N matches 2-9.\
For example to make calls to Germany through a provider, you can enter 49. To make calls\ For example to make calls to Germany through a provider, you can enter 49. To make calls\
to North America, you can enter 1NXXNXXXXXX. If one of your providers can make \"local\"\ to North America, you can enter 1NXXNXXXXXX. If one of your providers can make \"local\"\
calls to an area code like New York's 646, you can enter 646NXXXXXX for that\ calls to an area code like New York's 646, you can enter 646NXXXXXX for that\
provider. You should leave one account with an empty list to make calls with\ provider. You should leave one account with an empty list to make calls with\
it by default, if no other provider's prefixes match. The system will automatically\ it by default, if no other provider's prefixes match. The system will automatically\
replace an empty list with a message that the provider dials all numbers. Be as specific as\ replace an empty list with a message that the provider dials all numbers. Be as specific as\
possible (i.e. 1NXXNXXXXXX is better than 1). Please note all international dial codes\ possible (i.e. 1NXXNXXXXXX is better than 1). Please note all international dial codes\
are discarded (e.g. 00, 011, 010, 0011). Entries can be made in a\ are discarded (e.g. 00, 011, 010, 0011). Entries can be made in a space-separated\
space-separated list, and/or one per line by hitting enter after every one.")) list, and/or one per line by hitting enter after every one."))
s.anonymous = true s.anonymous = true
m.uci:foreach(googlemodulename, "gtalk_jabber", m.uci:foreach(googlemodulename, "gtalk_jabber",
function(s1) function(s1)
if s1.username ~= nil and s1.name ~= nil and if s1.username ~= nil and s1.name ~= nil and
s1.make_outgoing_calls == "yes" then s1.make_outgoing_calls == "yes" then
patt = s:option(DynamicList, s1.name, s1.username) patt = s:option(DynamicList, s1.name, s1.username)
-- Add provider to the associative array of valid accounts. -- Add provider to the associative array of valid accounts.
validoutaccounts[s1.name] = s1.username validoutaccounts[s1.name] = s1.username
-- If the saved field is empty, we return a string -- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten. -- telling the user that this account would dial any exten.
function patt.cfgvalue(self, section) function patt.cfgvalue(self, section)
value = self.map:get(section, self.option) value = self.map:get(section, self.option)
if value == nil then if value == nil then
return {"Dials any number"} return {"Dials any number"}
else else
return value return value
end end
end end
-- Write only valid extensions into the config file. -- Write only valid extensions into the config file.
function patt.write(self, section, value) function patt.write(self, section, value)
newvalue = {} newvalue = {}
nindex = 1 nindex = 1
for index, field in ipairs(value) do for index, field in ipairs(value) do
val = luci.util.trim(value[index]) val = luci.util.trim(value[index])
if is_valid_extension(val) == true then if is_valid_extension(val) == true then
newvalue[nindex] = val newvalue[nindex] = val
nindex = nindex + 1 nindex = nindex + 1
end end
end end
DynamicList.write(self, section, newvalue) DynamicList.write(self, section, newvalue)
end end
end end
end) end)
m.uci:foreach(voipmodulename, "voip_provider", m.uci:foreach(voipmodulename, "voip_provider",
function(s1) function(s1)
if s1.defaultuser ~= nil and s1.host ~= nil and if s1.defaultuser ~= nil and s1.host ~= nil and
s1.name ~= nil and s1.make_outgoing_calls == "yes" then s1.name ~= nil and s1.make_outgoing_calls == "yes" then
patt = s:option(DynamicList, s1.name, s1.defaultuser .. "@" .. s1.host) patt = s:option(DynamicList, s1.name, s1.defaultuser .. "@" .. s1.host)
-- Add provider to the associative array of valid accounts.
validoutaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host
-- Add provider to the associative array of valid accounts. -- If the saved field is empty, we return a string
validoutaccounts[s1.name] = s1.defaultuser .. "@" .. s1.host -- telling the user that this account would dial any exten.
function patt.cfgvalue(self, section)
value = self.map:get(section, self.option)
-- If the saved field is empty, we return a string if value == nil then
-- telling the user that this account would dial any exten. return {"Dials any number"}
function patt.cfgvalue(self, section) else
value = self.map:get(section, self.option) return value
end
end
if value == nil then -- Write only valid extensions into the config file.
return {"Dials any number"} function patt.write(self, section, value)
else newvalue = {}
return value nindex = 1
end for index, field in ipairs(value) do
end val = luci.util.trim(value[index])
if is_valid_extension(val) == true then
-- Write only valid extensions into the config file. newvalue[nindex] = val
function patt.write(self, section, value) nindex = nindex + 1
newvalue = {} end
nindex = 1 end
for index, field in ipairs(value) do DynamicList.write(self, section, newvalue)
val = luci.util.trim(value[index]) end
if is_valid_extension(val) == true then end
newvalue[nindex] = val end)
nindex = nindex + 1
end
end
DynamicList.write(self, section, newvalue)
end
end
end)
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "incoming_calls", "call_routing", translate("Incoming Calls"), s = m:section(NamedSection, "incoming_calls", "call_routing", translate("Incoming Calls"),
translate("For each provider that receives calls, here you can restrict which users to ring\ translate("For each provider that receives calls, here you can restrict which users to ring\
on incoming calls. If the list is empty, the system will indicate that all users\ on incoming calls. If the list is empty, the system will indicate that all users\
which are enabled for incoming calls will ring. Invalid usernames will be rejected\ which are enabled for incoming calls will ring. Invalid usernames will be rejected\
silently. Also, entering a username here overrides the user's setting to not receive\ silently. Also, entering a username here overrides the user's setting to not receive\
incoming calls, so this way, you can make users ring only for select providers.\ incoming calls, so this way, you can make users ring only for select providers.\
Entries can be made in a space-separated list, and/or one per\ Entries can be made in a space-separated list, and/or one per\
line by hitting enter after every one.")) line by hitting enter after every one."))
s.anonymous = true s.anonymous = true
m.uci:foreach(googlemodulename, "gtalk_jabber", m.uci:foreach(googlemodulename, "gtalk_jabber",
function(s1) function(s1)
if s1.username ~= nil and s1.register == "yes" then if s1.username ~= nil and s1.register == "yes" then
field_name=string.gsub(s1.username, "%W", "_") field_name=string.gsub(s1.username, "%W", "_")
gtalkaccts = s:option(DynamicList, field_name, s1.username) gtalkaccts = s:option(DynamicList, field_name, s1.username)
-- If the saved field is empty, we return a string -- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten. -- telling the user that this account would dial any exten.
function gtalkaccts.cfgvalue(self, section) function gtalkaccts.cfgvalue(self, section)
value = self.map:get(section, self.option) value = self.map:get(section, self.option)
if value == nil then if value == nil then
return {"Rings all users"} return {"Rings all users"}
else else
return value return value
end end
end end
-- Write only valid user names. -- Write only valid user names.
function gtalkaccts.write(self, section, value) function gtalkaccts.write(self, section, value)
newvalue = {} newvalue = {}
nindex = 1 nindex = 1
for index, field in ipairs(value) do for index, field in ipairs(value) do
trimuser = luci.util.trim(value[index]) trimuser = luci.util.trim(value[index])
if allvalidusers[trimuser] == true then if allvalidusers[trimuser] == true then
newvalue[nindex] = trimuser newvalue[nindex] = trimuser
nindex = nindex + 1 nindex = nindex + 1
end end
end end
DynamicList.write(self, section, newvalue) DynamicList.write(self, section, newvalue)
end end
end end
end) end)
m.uci:foreach(voipmodulename, "voip_provider", m.uci:foreach(voipmodulename, "voip_provider",
function(s1) function(s1)
if s1.defaultuser ~= nil and s1.host ~= nil and s1.register == "yes" then if s1.defaultuser ~= nil and s1.host ~= nil and s1.register == "yes" then
field_name=string.gsub(s1.defaultuser .. "_" .. s1.host, "%W", "_") field_name=string.gsub(s1.defaultuser .. "_" .. s1.host, "%W", "_")
voipaccts = s:option(DynamicList, field_name, s1.defaultuser .. "@" .. s1.host) voipaccts = s:option(DynamicList, field_name, s1.defaultuser .. "@" .. s1.host)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function voipaccts.cfgvalue(self, section)
value = self.map:get(section, self.option)
if value == nil then
return {"Rings all users"}
else
return value
end
end
-- If the saved field is empty, we return a string -- Write only valid user names.
-- telling the user that this account would dial any exten. function voipaccts.write(self, section, value)
function voipaccts.cfgvalue(self, section) newvalue = {}
value = self.map:get(section, self.option) nindex = 1
for index, field in ipairs(value) do
if value == nil then trimuser = luci.util.trim(value[index])
return {"Rings all users"} if allvalidusers[trimuser] == true then
else newvalue[nindex] = trimuser
return value nindex = nindex + 1
end end
end end
DynamicList.write(self, section, newvalue)
-- Write only valid user names. end
function voipaccts.write(self, section, value) end
newvalue = {} end)
nindex = 1
for index, field in ipairs(value) do
trimuser = luci.util.trim(value[index])
if allvalidusers[trimuser] == true then
newvalue[nindex] = trimuser
nindex = nindex + 1
end
end
DynamicList.write(self, section, newvalue)
end
end
end)
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "providers_user_can_use", "call_routing", s = m:section(NamedSection, "providers_user_can_use", "call_routing",
translate("Providers Used for Outgoing Calls"), translate("Providers Used for Outgoing Calls"),
translate("If you would like, you could restrict which providers users are allowed to use for outgoing\ translate("If you would like, you could restrict which providers users are allowed to use for outgoing\
calls. By default all users can use all providers. To show up in the list below the user should\ calls. By default all users can use all providers. To show up in the list below the user should\
be allowed to make outgoing calls in the \"User Accounts\" page. Enter VoIP providers in the format\ be allowed to make outgoing calls in the \"User Accounts\" page. Enter VoIP providers in the format\
username@some.host.name, as listed in \"Outgoing Calls\" above. It's easiest to copy and paste\ username@some.host.name, as listed in \"Outgoing Calls\" above. It's easiest to copy and paste\
the providers from above. Invalid entries will be rejected silently. Entries can be made in a \ the providers from above. Invalid entries will be rejected silently. Entries can be made in a \
space-separated list, and/or one per line by hitting enter after every one.")) space-separated list, and/or one per line by hitting enter after every one."))
s.anonymous = true s.anonymous = true
m.uci:foreach(usersmodulename, "local_user", m.uci:foreach(usersmodulename, "local_user",
function(s1) function(s1)
-- Add user to list of all valid users. -- Add user to list of all valid users.
if s1.defaultuser ~= nil then allvalidusers[s1.defaultuser] = true end if s1.defaultuser ~= nil then allvalidusers[s1.defaultuser] = true end
if s1.defaultuser ~= nil and s1.can_call == "yes" then
providers = s:option(DynamicList, s1.defaultuser, s1.defaultuser)
-- If the saved field is empty, we return a string
-- telling the user that this account would dial any exten.
function providers.cfgvalue(self, section)
value = self.map:get(section, self.option)
if s1.defaultuser ~= nil and s1.can_call == "yes" then if value == nil then
providers = s:option(DynamicList, s1.defaultuser, s1.defaultuser) return {"Uses all provider accounts"}
else
-- If the saved field is empty, we return a string newvalue = {}
-- telling the user that this account would dial any exten. -- Convert internal names to user@host values.
function providers.cfgvalue(self, section) for i,v in ipairs(value) do
value = self.map:get(section, self.option) newvalue[i] = validoutaccounts[v]
end
if value == nil then return newvalue
return {"Uses all provider accounts"} end
else end
newvalue = {}
-- Convert internal names to user@host values. -- Cook the new values prior to entering them into the config file.
for i,v in ipairs(value) do -- Also, enter them only if they are valid.
newvalue[i] = validoutaccounts[v] function providers.write(self, section, value)
end cookedvalue = {}
return newvalue cindex = 1
end for index, field in ipairs(value) do
end cooked = string.gsub(luci.util.trim(value[index]), "%W", "_")
if validoutaccounts[cooked] ~= nil then
-- Cook the new values prior to entering them into the config file. cookedvalue[cindex] = cooked
-- Also, enter them only if they are valid. cindex = cindex + 1
function providers.write(self, section, value) end
cookedvalue = {} end
cindex = 1 DynamicList.write(self, section, cookedvalue)
for index, field in ipairs(value) do end
cooked = string.gsub(luci.util.trim(value[index]), "%W", "_") end
if validoutaccounts[cooked] ~= nil then end)
cookedvalue[cindex] = cooked
cindex = cindex + 1
end
end
DynamicList.write(self, section, cookedvalue)
end
end
end)
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
s = m:section(TypedSection, "callthrough_numbers", translate("Call-through Numbers"), s = m:section(TypedSection, "callthrough_numbers", translate("Call-through Numbers"),
translate("Designate numbers which will be allowed to call through this system and which user's\ translate("Designate numbers which will be allowed to call through this system and which user's\
privileges it will have.")) privileges it will have."))
s.anonymous = true s.anonymous = true
s.addremove = true s.addremove = true
@ -290,8 +290,8 @@ p:value("no", translate("No"))
p.default = "yes" p.default = "yes"
user = s:option(Value, "defaultuser", translate("User Name"), user = s:option(Value, "defaultuser", translate("User Name"),
translate("The number(s) specified above will be able to dial out with this user's providers.\ translate("The number(s) specified above will be able to dial out with this user's providers.\
Invalid usernames are dropped silently, please verify that the entry was accepted.")) Invalid usernames are dropped silently, please verify that the entry was accepted."))
function user.write(self, section, value) function user.write(self, section, value)
trimuser = luci.util.trim(value) trimuser = luci.util.trim(value)
if allvalidusers[trimuser] == true then if allvalidusers[trimuser] == true then
@ -300,9 +300,9 @@ function user.write(self, section, value)
end end
pwd = s:option(Value, "pin", translate("PIN"), pwd = s:option(Value, "pin", translate("PIN"),
translate("Your PIN disappears when saved for your protection. It will be changed\ translate("Your PIN disappears when saved for your protection. It will be changed\
only when you enter a value different from the saved one. Leaving the PIN\ only when you enter a value different from the saved one. Leaving the PIN\
empty is possible, but please beware of the security implications.")) empty is possible, but please beware of the security implications."))
pwd.password = true pwd.password = true
pwd.rmempty = false pwd.rmempty = false
@ -322,19 +322,19 @@ end
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
s = m:section(NamedSection, "blacklisting", "call_routing", translate("Blacklisted Numbers"), s = m:section(NamedSection, "blacklisting", "call_routing", translate("Blacklisted Numbers"),
translate("Enter phone numbers that you want to decline calls from automatically.\ translate("Enter phone numbers that you want to decline calls from automatically.\
You should probably omit the country code and any leading\ You should probably omit the country code and any leading\
zeroes, but please experiment to make sure you are blocking numbers from your\ zeroes, but please experiment to make sure you are blocking numbers from your\
desired area successfully.")) desired area successfully."))
s.anonymous = true s.anonymous = true
b = s:option(DynamicList, "blacklist1", translate("Dynamic List of Blacklisted Numbers"), b = s:option(DynamicList, "blacklist1", translate("Dynamic List of Blacklisted Numbers"),
translate("Specify numbers individually here. Press enter to add more numbers.")) translate("Specify numbers individually here. Press enter to add more numbers."))
b.cast = "string" b.cast = "string"
b.datatype = "uinteger" b.datatype = "uinteger"
b = s:option(Value, "blacklist2", translate("Space-Separated List of Blacklisted Numbers"), b = s:option(Value, "blacklist2", translate("Space-Separated List of Blacklisted Numbers"),
translate("Copy-paste large lists of numbers here.")) translate("Copy-paste large lists of numbers here."))
b.template = "cbi/tvalue" b.template = "cbi/tvalue"
b.rows = 3 b.rows = 3

View file

@ -31,24 +31,24 @@ defaultstatus = "dnd"
defaultstatusmessage = "PBX online, may lose messages" defaultstatusmessage = "PBX online, may lose messages"
m = Map (modulename, translate("Google Accounts"), m = Map (modulename, translate("Google Accounts"),
translate("This is where you set up your Google (Talk and Voice) Accounts, in order to start\ translate("This is where you set up your Google (Talk and Voice) Accounts, in order to start\
using them for dialing and receiving calls (voice chat and real phone calls). Click \"Add\"\ using them for dialing and receiving calls (voice chat and real phone calls). Click \"Add\"\
to add as many accounts as you wish.")) to add as many accounts as you wish."))
-- Recreate the config, and restart services after changes are commited to the configuration. -- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self) function m.on_after_commit(self)
-- Create a field "name" for each account which identifies the account in the backend. -- Create a field "name" for each account which identifies the account in the backend.
commit = false commit = false
m.uci:foreach(modulename, "gtalk_jabber", m.uci:foreach(modulename, "gtalk_jabber",
function(s1) function(s1)
if s1.username ~= nil then if s1.username ~= nil then
name=string.gsub(s1.username, "%W", "_") name=string.gsub(s1.username, "%W", "_")
if s1.name ~= name then if s1.name ~= name then
m.uci:set(modulename, s1['.name'], "name", name) m.uci:set(modulename, s1['.name'], "name", name)
commit = true commit = true
end end
end end
end) end)
if commit == true then m.uci:commit(modulename) end if commit == true then m.uci:commit(modulename) end
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null") luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
@ -63,9 +63,9 @@ s.addremove = true
s:option(Value, "username", translate("Email")) s:option(Value, "username", translate("Email"))
pwd = s:option(Value, "secret", translate("Password"), pwd = s:option(Value, "secret", translate("Password"),
translate("When your password is saved, it disappears from this field and is not displayed\ translate("When your password is saved, it disappears from this field and is not displayed\
for your protection. The previously saved password will be changed only when you\ for your protection. The previously saved password will be changed only when you\
enter a value different from the saved one.")) enter a value different from the saved one."))
pwd.password = true pwd.password = true
pwd.rmempty = false pwd.rmempty = false
@ -85,22 +85,22 @@ end
p = s:option(ListValue, "register", p = s:option(ListValue, "register",
translate("Enable Incoming Calls (See Status, Message below)"), translate("Enable Incoming Calls (See Status, Message below)"),
translate("When somebody starts voice chat with your GTalk account or calls the GVoice,\ translate("When somebody starts voice chat with your GTalk account or calls the GVoice,\
number (if you have Google Voice), the call will be forwarded to any users\ number (if you have Google Voice), the call will be forwarded to any users\
that are online (registered using a SIP device or softphone) and permitted to\ that are online (registered using a SIP device or softphone) and permitted to\
receive the call. If you have Google Voice, you must go to your GVoice settings and\ receive the call. If you have Google Voice, you must go to your GVoice settings and\
forward calls to Google chat in order to actually receive calls made to your\ forward calls to Google chat in order to actually receive calls made to your\
GVoice number. If you have trouble receiving calls from GVoice, experiment\ GVoice number. If you have trouble receiving calls from GVoice, experiment\
with the Call Screening option in your GVoice Settings. Finally, make sure no other\ with the Call Screening option in your GVoice Settings. Finally, make sure no other\
client is online with this account (browser in gmail, mobile/desktop Google Talk\ client is online with this account (browser in gmail, mobile/desktop Google Talk\
App) as it may interfere.")) App) as it may interfere."))
p:value("yes", translate("Yes")) p:value("yes", translate("Yes"))
p:value("no", translate("No")) p:value("no", translate("No"))
p.default = "yes" p.default = "yes"
p = s:option(ListValue, "make_outgoing_calls", translate("Enable Outgoing Calls"), p = s:option(ListValue, "make_outgoing_calls", translate("Enable Outgoing Calls"),
translate("Use this account to make outgoing calls as configured in the \"Call Routing\" section.")) translate("Use this account to make outgoing calls as configured in the \"Call Routing\" section."))
p:value("yes", translate("Yes")) p:value("yes", translate("Yes"))
p:value("no", translate("No")) p:value("no", translate("No"))
p.default = "yes" p.default = "yes"
@ -113,7 +113,7 @@ st:value("available", translate("Available"))
st.default = defaultstatus st.default = defaultstatus
stm = s:option(Value, "statusmessage", translate("Account Status Message"), stm = s:option(Value, "statusmessage", translate("Account Status Message"),
translate("Avoid using anything but alpha-numeric characters, space, comma, and period.")) translate("Avoid using anything but alpha-numeric characters, space, comma, and period."))
stm:depends("register", "yes") stm:depends("register", "yes")
stm.default = defaultstatusmessage stm.default = defaultstatusmessage

View file

@ -28,35 +28,20 @@ end
modulename = "pbx-users" modulename = "pbx-users"
modulenamecalls = "pbx-calls" modulenamecalls = "pbx-calls"
modulenameadvanced = "pbx-advanced" modulenameadvanced = "pbx-advanced"
m = Map (modulename, translate("User Accounts"), m = Map (modulename, translate("User Accounts"),
translate("Here you must configure at least one SIP account, which you\ translate("Here you must configure at least one SIP account, which you\
will use to register with this service. Use this account either in an analog telephony\ will use to register with this service. Use this account either in an analog telephony\
adapter (ATA), or in a SIP softphone like CSipSimple, Linphone, or Sipdroid on your\ adapter (ATA), or in a SIP softphone like CSipSimple, Linphone, or Sipdroid on your\
Android smartphone, or X-lite or Ekiga on your computer. By default, all SIP accounts\ Android smartphone, or X-lite or Ekiga on your computer. By default, all SIP accounts\
will ring simultaneously if a call is made to one of your VoIP provider accounts or GV\ will ring simultaneously if a call is made to one of your VoIP provider accounts or GV\
numbers.")) numbers."))
-- Recreate the config, and restart services after changes are commited to the configuration. -- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self) function m.on_after_commit(self)
--allusers = "" luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
--ringusers = "" luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
--
---- Create two lists of users - one of all users and one of users enabled for incoming calls.
--m.uci:foreach(modulename, "local_user",
-- function(s1)
-- allusers = allusers .. " " .. s1.defaultuser
-- if s1.ring == "yes" then
-- ringusers = ringusers .. " " .. s1.defaultuser
-- end
-- end)
--
--m.uci:set (modulenamecalls, "valid_users", "allusers", allusers)
--m.uci:set (modulenamecalls, "valid_users", "ringusers", ringusers)
--m.uci:commit (modulenamecalls)
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
luci.sys.call("/etc/init.d/" .. server .. " restart 1\>/dev/null 2\>/dev/null")
end end
externhost = m.uci:get(modulenameadvanced, "advanced", "externhost") externhost = m.uci:get(modulenameadvanced, "advanced", "externhost")
@ -77,8 +62,8 @@ if bindport ~= nil then
end end
s:option(DummyValue, "ipaddr", translate("Server Setting for Local SIP Devices"), s:option(DummyValue, "ipaddr", translate("Server Setting for Local SIP Devices"),
translate("Enter this IP (or IP:port) in the Server/Registrar setting of SIP devices you will\ translate("Enter this IP (or IP:port) in the Server/Registrar setting of SIP devices you will\
use ONLY locally and never from a remote location.")).default = ipaddr use ONLY locally and never from a remote location.")).default = ipaddr
if externhost ~= nil then if externhost ~= nil then
if bindport ~= nil then if bindport ~= nil then
@ -86,20 +71,20 @@ if externhost ~= nil then
externhost = externhost .. ":" .. bindport externhost = externhost .. ":" .. bindport
end end
s:option(DummyValue, "externhost", translate("Server Setting for Remote SIP Devices"), s:option(DummyValue, "externhost", translate("Server Setting for Remote SIP Devices"),
translate("Enter this hostname (or hostname:port) in the Server/Registrar setting of SIP\ translate("Enter this hostname (or hostname:port) in the Server/Registrar setting of SIP\
devices you will use from a remote location (they will work locally too).") devices you will use from a remote location (they will work locally too).")
).default = externhost ).default = externhost
end end
if bindport ~= nil then if bindport ~= nil then
s:option(DummyValue, "bindport", translate("Port Setting for SIP Devices"), s:option(DummyValue, "bindport", translate("Port Setting for SIP Devices"),
translatef("If setting Server/Registrar to %s or %s does not work for you, try setting\ translatef("If setting Server/Registrar to %s or %s does not work for you, try setting\
it to %s or %s and entering this port number in a separate field which specifies the\ it to %s or %s and entering this port number in a separate field which specifies the\
Server/Registrar port number. Beware that some devices have a confusing\ Server/Registrar port number. Beware that some devices have a confusing\
setting which sets the port where SIP requests originate from on the SIP\ setting which sets the port where SIP requests originate from on the SIP\
device itself (bind port). The port specified on this page is NOT this bind port\ device itself (bind port). The port specified on this page is NOT this bind port\
but the this service listens on.", but the this service listens on.",
ipaddr, externhost, just_ipaddr, just_externhost)).default = bindport ipaddr, externhost, just_ipaddr, just_externhost)).default = bindport
end end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
@ -108,16 +93,16 @@ s.anonymous = true
s.addremove = true s.addremove = true
s:option(Value, "fullname", translate("Full Name"), s:option(Value, "fullname", translate("Full Name"),
translate("You can specify a real name to show up in the Caller ID here.")) translate("You can specify a real name to show up in the Caller ID here."))
du = s:option(Value, "defaultuser", translate("User Name"), du = s:option(Value, "defaultuser", translate("User Name"),
translate("Use (four to five digit) numeric user name if you are connecting normal telephones\ translate("Use (four to five digit) numeric user name if you are connecting normal telephones\
with ATAs to this system (so they can dial user names).")) with ATAs to this system (so they can dial user names)."))
du.datatype = "uciname" du.datatype = "uciname"
pwd = s:option(Value, "secret", translate("Password"), pwd = s:option(Value, "secret", translate("Password"),
translate("Your password disappears when saved for your protection. It will be changed\ translate("Your password disappears when saved for your protection. It will be changed\
only when you enter a value different from the saved one.")) only when you enter a value different from the saved one."))
pwd.password = true pwd.password = true
pwd.rmempty = false pwd.rmempty = false

View file

@ -28,25 +28,25 @@ end
modulename = "pbx-voip" modulename = "pbx-voip"
m = Map (modulename, translate("SIP Accounts"), m = Map (modulename, translate("SIP Accounts"),
translate("This is where you set up your SIP (VoIP) accounts ts like Sipgate, SipSorcery,\ translate("This is where you set up your SIP (VoIP) accounts ts like Sipgate, SipSorcery,\
the popular Betamax providers, and any other providers with SIP settings in order to start \ the popular Betamax providers, and any other providers with SIP settings in order to start \
using them for dialing and receiving calls (SIP uri and real phone calls). Click \"Add\" to\ using them for dialing and receiving calls (SIP uri and real phone calls). Click \"Add\" to\
add as many accounts as you wish.")) add as many accounts as you wish."))
-- Recreate the config, and restart services after changes are commited to the configuration. -- Recreate the config, and restart services after changes are commited to the configuration.
function m.on_after_commit(self) function m.on_after_commit(self)
commit = false commit = false
-- Create a field "name" for each account which identifies the account in the backend. -- Create a field "name" for each account which identifies the account in the backend.
m.uci:foreach(modulename, "voip_provider", m.uci:foreach(modulename, "voip_provider",
function(s1) function(s1)
if s1.defaultuser ~= nil and s1.host ~= nil then if s1.defaultuser ~= nil and s1.host ~= nil then
name=string.gsub(s1.defaultuser.."_"..s1.host, "%W", "_") name=string.gsub(s1.defaultuser.."_"..s1.host, "%W", "_")
if s1.name ~= name then if s1.name ~= name then
m.uci:set(modulename, s1['.name'], "name", name) m.uci:set(modulename, s1['.name'], "name", name)
commit = true commit = true
end end
end end
end) end)
if commit == true then m.uci:commit(modulename) end if commit == true then m.uci:commit(modulename) end
luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null") luci.sys.call("/etc/init.d/pbx-" .. server .. " restart 1\>/dev/null 2\>/dev/null")
@ -60,9 +60,9 @@ s.addremove = true
s:option(Value, "defaultuser", translate("User Name")) s:option(Value, "defaultuser", translate("User Name"))
pwd = s:option(Value, "secret", translate("Password"), pwd = s:option(Value, "secret", translate("Password"),
translate("When your password is saved, it disappears from this field and is not displayed\ translate("When your password is saved, it disappears from this field and is not displayed\
for your protection. The previously saved password will be changed only when you\ for your protection. The previously saved password will be changed only when you\
enter a value different from the saved one.")) enter a value different from the saved one."))
@ -87,21 +87,21 @@ h = s:option(Value, "host", translate("SIP Server/Registrar"))
h.datatype = "host" h.datatype = "host"
p = s:option(ListValue, "register", translate("Enable Incoming Calls (Register via SIP)"), p = s:option(ListValue, "register", translate("Enable Incoming Calls (Register via SIP)"),
translate("This option should be set to \"Yes\" if you have a DID \(real telephone number\)\ translate("This option should be set to \"Yes\" if you have a DID \(real telephone number\)\
associated with this SIP account or want to receive SIP uri calls through this\ associated with this SIP account or want to receive SIP uri calls through this\
provider.")) provider."))
p:value("yes", translate("Yes")) p:value("yes", translate("Yes"))
p:value("no", translate("No")) p:value("no", translate("No"))
p.default = "yes" p.default = "yes"
p = s:option(ListValue, "make_outgoing_calls", translate("Enable Outgoing Calls"), p = s:option(ListValue, "make_outgoing_calls", translate("Enable Outgoing Calls"),
translate("Use this account to make outgoing calls.")) translate("Use this account to make outgoing calls."))
p:value("yes", translate("Yes")) p:value("yes", translate("Yes"))
p:value("no", translate("No")) p:value("no", translate("No"))
p.default = "yes" p.default = "yes"
from = s:option(Value, "fromdomain", from = s:option(Value, "fromdomain",
translate("SIP Realm (needed by some providers)")) translate("SIP Realm (needed by some providers)"))
from.optional = true from.optional = true
from.datatype = "host" from.datatype = "host"

View file

@ -52,16 +52,16 @@ function format_indices(string, indices)
for lpos,splitline in ipairs(splitlines) do for lpos,splitline in ipairs(splitlines) do
loutput = "" loutput = ""
for ipos,index in ipairs(indices) do for ipos,index in ipairs(indices) do
if splitline[index] ~= nil then if splitline[index] ~= nil then
loutput = loutput .. string.format("%-50s", splitline[index]) loutput = loutput .. string.format("%-50s", splitline[index])
else else
loutput = nil loutput = nil
break break
end end
end end
if loutput ~= nil then if loutput ~= nil then
output = output .. loutput .. "\n" output = output .. loutput .. "\n"
end end
end end
return output return output
@ -69,7 +69,7 @@ end
m = Map (modulename, translate("PBX Main Page"), m = Map (modulename, translate("PBX Main Page"),
translate("This configuration page allows you to configure a phone system (PBX) service which\ translate("This configuration page allows you to configure a phone system (PBX) service which\
permits making phone calls through multiple Google and SIP (like Sipgate,\ permits making phone calls through multiple Google and SIP (like Sipgate,\
SipSorcery, and Betamax) accounts and sharing them among many SIP devices. \ SipSorcery, and Betamax) accounts and sharing them among many SIP devices. \
Note that Google accounts, SIP accounts, and local user accounts are configured in the \ Note that Google accounts, SIP accounts, and local user accounts are configured in the \
@ -84,7 +84,7 @@ m = Map (modulename, translate("PBX Main Page"),
----------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------
s = m:section(NamedSection, "connection_status", "main", s = m:section(NamedSection, "connection_status", "main",
translate("Service Control and Connection Status")) translate("Service Control and Connection Status"))
s.anonymous = true s.anonymous = true
s:option (DummyValue, "status", translate("Service Status")) s:option (DummyValue, "status", translate("Service Status"))
@ -103,7 +103,7 @@ function sts.cfgvalue(self, section)
return format_indices(regs, {1, 5}) .. return format_indices(regs, {1, 5}) ..
format_indices(jabs, {2, 4}) .. "\n" .. format_indices(jabs, {2, 4}) .. "\n" ..
format_indices(usrs, {1} ) .. "\n" .. chan format_indices(usrs, {1} ) .. "\n" .. chan
elseif server == "freeswitch" then elseif server == "freeswitch" then
return "Freeswitch is not supported yet.\n" return "Freeswitch is not supported yet.\n"

View file

@ -88,6 +88,7 @@ INCLUDED_FILES="$WORKDIR/extensions_blacklist.conf $WORKDIR/extensions_callthrou
# In this string, we concatenate all local users enabled to receive calls # In this string, we concatenate all local users enabled to receive calls
# readily formatted for the Dial command. # readily formatted for the Dial command.
localusers_to_ring="" localusers_to_ring=""
# In this string, we keep a list of all users that are enabled for outgoing # In this string, we keep a list of all users that are enabled for outgoing
# calls. It is used at the end to create the user contexts. # calls. It is used at the end to create the user contexts.
localusers_can_dial="" localusers_can_dial=""
@ -101,12 +102,12 @@ outbound_providers=""
# Copies the template files which we don't edit. # Copies the template files which we don't edit.
copy_unedited_templates_over() copy_unedited_templates_over()
{ {
cp $TMPL_ASTERISK $WORKDIR/asterisk.conf cp $TMPL_ASTERISK $WORKDIR/asterisk.conf
cp $TMPL_GTALK $WORKDIR/gtalk.conf cp $TMPL_GTALK $WORKDIR/gtalk.conf
cp $TMPL_INDICATIONS $WORKDIR/indications.conf cp $TMPL_INDICATIONS $WORKDIR/indications.conf
cp $TMPL_LOGGER $WORKDIR/logger.conf cp $TMPL_LOGGER $WORKDIR/logger.conf
cp $TMPL_MANAGER $WORKDIR/manager.conf cp $TMPL_MANAGER $WORKDIR/manager.conf
cp $TMPL_MODULES $WORKDIR/modules.conf cp $TMPL_MODULES $WORKDIR/modules.conf
} }
# Touches all the included files, to prevent asterisk from refusing to # Touches all the included files, to prevent asterisk from refusing to
@ -119,48 +120,48 @@ create_included_files()
# Puts together all the extensions.conf related configuration. # Puts together all the extensions.conf related configuration.
pbx_create_extensions_config() pbx_create_extensions_config()
{ {
sed "s/|LOCALUSERS|/$localusers_to_ring/g" $TMPL_EXTENSIONS > $WORKDIR/extensions.conf sed "s/|LOCALUSERS|/$localusers_to_ring/g" $TMPL_EXTENSIONS > $WORKDIR/extensions.conf
mv $WORKDIR/inext.TMP $WORKDIR/extensions_incoming.conf mv $WORKDIR/inext.TMP $WORKDIR/extensions_incoming.conf
cp $TMPL_EXTINCNTXTGTALKHDR $WORKDIR/extensions_incoming_gtalk.conf cp $TMPL_EXTINCNTXTGTALKHDR $WORKDIR/extensions_incoming_gtalk.conf
cat $WORKDIR/outextgtalk.TMP >> $WORKDIR/extensions_incoming_gtalk.conf 2>/dev/null cat $WORKDIR/outextgtalk.TMP >> $WORKDIR/extensions_incoming_gtalk.conf 2>/dev/null
rm -f $WORKDIR/outextgtalk.TMP rm -f $WORKDIR/outextgtalk.TMP
mv $WORKDIR/blacklist.TMP $WORKDIR/extensions_blacklist.conf mv $WORKDIR/blacklist.TMP $WORKDIR/extensions_blacklist.conf
mv $WORKDIR/userext.TMP $WORKDIR/extensions_user.conf mv $WORKDIR/userext.TMP $WORKDIR/extensions_user.conf
cp $TMPL_EXTCTHRUHDR $WORKDIR/extensions_callthrough.conf cp $TMPL_EXTCTHRUHDR $WORKDIR/extensions_callthrough.conf
cat $WORKDIR/callthrough.TMP >> $WORKDIR/extensions_callthrough.conf 2>/dev/null cat $WORKDIR/callthrough.TMP >> $WORKDIR/extensions_callthrough.conf 2>/dev/null
rm -f $WORKDIR/callthrough.TMP rm -f $WORKDIR/callthrough.TMP
cat $TMPL_EXTCTHRUCHECKHDR >> $WORKDIR/extensions_callthrough.conf 2>/dev/null cat $TMPL_EXTCTHRUCHECKHDR >> $WORKDIR/extensions_callthrough.conf 2>/dev/null
cat $WORKDIR/callthroughcheck.TMP >> $WORKDIR/extensions_callthrough.conf 2>/dev/null cat $WORKDIR/callthroughcheck.TMP >> $WORKDIR/extensions_callthrough.conf 2>/dev/null
rm -f $WORKDIR/callthroughcheck.TMP rm -f $WORKDIR/callthroughcheck.TMP
cat $TMPL_EXTCTHRUCHECKFTR >> $WORKDIR/extensions_callthrough.conf 2>/dev/null cat $TMPL_EXTCTHRUCHECKFTR >> $WORKDIR/extensions_callthrough.conf 2>/dev/null
rm -f $WORKDIR/outext-*.TMP rm -f $WORKDIR/outext-*.TMP
rm -f $WORKDIR/localext.TMP rm -f $WORKDIR/localext.TMP
} }
# Puts together all the sip.conf related configuration. # Puts together all the sip.conf related configuration.
pbx_create_sip_config() pbx_create_sip_config()
{ {
mv $WORKDIR/sip_regs.TMP $WORKDIR/sip_registrations.conf mv $WORKDIR/sip_regs.TMP $WORKDIR/sip_registrations.conf
mv $WORKDIR/sip_peers.TMP $WORKDIR/sip_peers.conf mv $WORKDIR/sip_peers.TMP $WORKDIR/sip_peers.conf
mv $WORKDIR/sip_users.TMP $WORKDIR/sip_users.conf mv $WORKDIR/sip_users.TMP $WORKDIR/sip_users.conf
} }
# Creates the jabber.conf related config # Creates the jabber.conf related config
pbx_create_jabber_config() pbx_create_jabber_config()
{ {
cp $TMPL_JABBER $WORKDIR/jabber.conf cp $TMPL_JABBER $WORKDIR/jabber.conf
mv $WORKDIR/jabber.TMP $WORKDIR/jabber_users.conf mv $WORKDIR/jabber.TMP $WORKDIR/jabber_users.conf
} }
# Gets rid of any config files from $ASTERISKDIR not found in $WORKDIR. # Gets rid of any config files from $ASTERISKDIR not found in $WORKDIR.
clean_up_asterisk_config_dir() clean_up_asterisk_config_dir()
{ {
for f in $ASTERISKDIR/* ; do for f in $ASTERISKDIR/* ; do
basef="`basename $f`" basef="`basename $f`"
if [ ! -e "$WORKDIR/$basef" ] ; then if [ ! -e "$WORKDIR/$basef" ] ; then
rm -rf "$f" rm -rf "$f"
fi fi
done done
} }
# Compares md5sums of the config files in $WORKDIR to those # Compares md5sums of the config files in $WORKDIR to those
@ -168,22 +169,22 @@ clean_up_asterisk_config_dir()
# wear on flash in embedded devices. # wear on flash in embedded devices.
compare_configs_and_copy_changed() compare_configs_and_copy_changed()
{ {
# First, compute md5sums of the config files in $WORKDIR. # First, compute md5sums of the config files in $WORKDIR.
cd $WORKDIR/ cd $WORKDIR/
md5sum * > $MD5SUMSFILE md5sum * > $MD5SUMSFILE
# Now, check the files in $ASTERISKDIR against the md5sums. # Now, check the files in $ASTERISKDIR against the md5sums.
cd $ASTERISKDIR/ cd $ASTERISKDIR/
changed_files="`md5sum -c $MD5SUMSFILE 2>/dev/null | fgrep ": FAILED" | awk -F: '{print $1}'`" changed_files="`md5sum -c $MD5SUMSFILE 2>/dev/null | fgrep ": FAILED" | awk -F: '{print $1}'`"
rm -f $MD5SUMSFILE rm -f $MD5SUMSFILE
[ -z "$changed_files" ] && return [ -z "$changed_files" ] && return
# Now copy over the changed files. # Now copy over the changed files.
for f in $changed_files ; do for f in $changed_files ; do
cp "$WORKDIR/$f" "$ASTERISKDIR/$f" cp "$WORKDIR/$f" "$ASTERISKDIR/$f"
done done
} }
# Calls the functions that create the final config files # Calls the functions that create the final config files
@ -192,72 +193,72 @@ compare_configs_and_copy_changed()
# Gets rid of $WORKDIR # Gets rid of $WORKDIR
pbx_assemble_and_copy_config() pbx_assemble_and_copy_config()
{ {
mkdir -p $ASTERISKDIR mkdir -p $ASTERISKDIR
copy_unedited_templates_over copy_unedited_templates_over
create_included_files create_included_files
pbx_create_extensions_config pbx_create_extensions_config
pbx_create_sip_config pbx_create_sip_config
pbx_create_jabber_config pbx_create_jabber_config
touch $WORKDIR/features.conf touch $WORKDIR/features.conf
# At this point, $WORKDIR should contain a complete, working config. # At this point, $WORKDIR should contain a complete, working config.
clean_up_asterisk_config_dir clean_up_asterisk_config_dir
compare_configs_and_copy_changed compare_configs_and_copy_changed
[ ! -d $ASTERISKDIR/manager.d ] && mkdir -p $ASTERISKDIR/manager.d/ [ ! -d $ASTERISKDIR/manager.d ] && mkdir -p $ASTERISKDIR/manager.d/
# Get rid of the working directory # Get rid of the working directory
rm -rf $WORKDIR/ rm -rf $WORKDIR/
} }
# Creates configuration for a user and adds it to the temporary file that holds # Creates configuration for a user and adds it to the temporary file that holds
# all users configured so far. # all users configured so far.
pbx_add_user() pbx_add_user()
{ {
local fullname local fullname
local defaultuser local defaultuser
local secret local secret
local ring local ring
local can_call local can_call
config_get fullname $1 fullname config_get fullname $1 fullname
config_get defaultuser $1 defaultuser config_get defaultuser $1 defaultuser
config_get secret $1 secret config_get secret $1 secret
config_get ring $1 ring config_get ring $1 ring
config_get can_call $1 can_call config_get can_call $1 can_call
[ -z "$defaultuser" -o -z "$secret" ] && return [ -z "$defaultuser" -o -z "$secret" ] && return
[ -z "$fullname" ] && fullname="$defaultuser" [ -z "$fullname" ] && fullname="$defaultuser"
sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_SIPUSR > $WORKDIR/sip_user.tmp sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_SIPUSR > $WORKDIR/sip_user.tmp
if [ "$can_call" = "yes" ] ; then if [ "$can_call" = "yes" ] ; then
# Add user to list of all users that are allowed to make calls. # Add user to list of all users that are allowed to make calls.
localusers_can_dial="$localusers_can_dial $defaultuser" localusers_can_dial="$localusers_can_dial $defaultuser"
sed -i "s/|CONTEXTNAME|/$defaultuser/g" $WORKDIR/sip_user.tmp sed -i "s/|CONTEXTNAME|/$defaultuser/g" $WORKDIR/sip_user.tmp
else else
sed -i "s/|CONTEXTNAME|/$HANGUPCNTXT/g" $WORKDIR/sip_user.tmp sed -i "s/|CONTEXTNAME|/$HANGUPCNTXT/g" $WORKDIR/sip_user.tmp
fi fi
# Add this user's configuration to the temp file containing all user configs. # Add this user's configuration to the temp file containing all user configs.
sed "s/|FULLNAME|/$fullname/" $WORKDIR/sip_user.tmp |\ sed "s/|FULLNAME|/$fullname/" $WORKDIR/sip_user.tmp |\
sed "s/|SECRET|/$secret/g" >> $WORKDIR/sip_users.TMP sed "s/|SECRET|/$secret/g" >> $WORKDIR/sip_users.TMP
if [ "$ring" = "yes" ] ; then if [ "$ring" = "yes" ] ; then
if [ -z "$localusers_to_ring" ] ; then if [ -z "$localusers_to_ring" ] ; then
localusers_to_ring="SIP\/$defaultuser" localusers_to_ring="SIP\/$defaultuser"
else else
localusers_to_ring="$localusers_to_ring\&SIP\/$defaultuser" localusers_to_ring="$localusers_to_ring\&SIP\/$defaultuser"
fi fi
fi fi
# Add configuration which allows local users to call each other. # Add configuration which allows local users to call each other.
sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_EXTOUTLOCAL >> $WORKDIR/localext.TMP sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_EXTOUTLOCAL >> $WORKDIR/localext.TMP
rm -f $WORKDIR/sip_user.tmp rm -f $WORKDIR/sip_user.tmp
} }
# Creates configuration for a Google account, and adds it to the temporary file that holds # Creates configuration for a Google account, and adds it to the temporary file that holds
@ -265,84 +266,84 @@ pbx_add_user()
# Also creates the outgoing extensions which are used in users' outgoing contexts. # Also creates the outgoing extensions which are used in users' outgoing contexts.
pbx_add_jabber() pbx_add_jabber()
{ {
local username local username
local secret local secret
local numprefix local numprefix
local register local register
local make_outgoing_calls local make_outgoing_calls
local name local name
local users_to_ring local users_to_ring
local status local status
local statusmessage local statusmessage
config_get username $1 username config_get username $1 username
config_get secret $1 secret config_get secret $1 secret
config_get numprefix $1 numprefix config_get numprefix $1 numprefix
config_get register $1 register config_get register $1 register
config_get make_outgoing_calls $1 make_outgoing_calls config_get make_outgoing_calls $1 make_outgoing_calls
config_get name $1 name config_get name $1 name
config_get status $1 status config_get status $1 status
config_get statusmessage $1 statusmessage config_get statusmessage $1 statusmessage
[ -z "$username" -o -z "$secret" ] && return [ -z "$username" -o -z "$secret" ] && return
# Construct a jabber entry for this provider. # Construct a jabber entry for this provider.
sed "s/|USERNAME|/$username/g" $TMPL_JABBERUSER |\ sed "s/|USERNAME|/$username/g" $TMPL_JABBERUSER |\
sed "s/|NAME|/$name/g" > $WORKDIR/jabber.tmp sed "s/|NAME|/$name/g" > $WORKDIR/jabber.tmp
if [ "$register" = yes ] ; then if [ "$register" = yes ] ; then
# If this provider is enabled for incoming calls, we need to set the # If this provider is enabled for incoming calls, we need to set the
# status of the user to something other than unavailable in order to receive calls. # status of the user to something other than unavailable in order to receive calls.
sed -i "s/|STATUS|/$status/g" $WORKDIR/jabber.tmp sed -i "s/|STATUS|/$status/g" $WORKDIR/jabber.tmp
sed -i "s/|STATUSMESSAGE|/\"$statusmessage\"/g" $WORKDIR/jabber.tmp sed -i "s/|STATUSMESSAGE|/\"$statusmessage\"/g" $WORKDIR/jabber.tmp
users_to_ring="`uci -q get ${MODULENAME}-calls.incoming_calls.$name`" users_to_ring="`uci -q get ${MODULENAME}-calls.incoming_calls.$name`"
# If no users have been specified to ring, we ring all users enabled for incoming calls. # If no users have been specified to ring, we ring all users enabled for incoming calls.
if [ -z "$users_to_ring" ] ; then if [ -z "$users_to_ring" ] ; then
users_to_ring=$localusers_to_ring users_to_ring=$localusers_to_ring
else else
# Else, we cook up a string formatted for the Dial command # Else, we cook up a string formatted for the Dial command
# with the specified users (SIP/user1&SIP/user2&...). We do it # with the specified users (SIP/user1&SIP/user2&...). We do it
# with set, shift and a loop in order to be more tolerant of ugly whitespace # with set, shift and a loop in order to be more tolerant of ugly whitespace
# messes entered by users. # messes entered by users.
set $users_to_ring set $users_to_ring
users_to_ring="SIP\/$1" && shift users_to_ring="SIP\/$1" && shift
for u in $@ ; do users_to_ring=$users_to_ring\\\&SIP\\\/$u ; done for u in $@ ; do users_to_ring=$users_to_ring\\\&SIP\\\/$u ; done
fi fi
# Now, we add this account to the gtalk incoming context. # Now, we add this account to the gtalk incoming context.
sed "s/|USERNAME|/$username/g" $TMPL_EXTINCNTXTGTALK |\ sed "s/|USERNAME|/$username/g" $TMPL_EXTINCNTXTGTALK |\
sed "s/|LOCALUSERS|/$users_to_ring/g" >> $WORKDIR/outextgtalk.TMP sed "s/|LOCALUSERS|/$users_to_ring/g" >> $WORKDIR/outextgtalk.TMP
else else
sed -i "s/|STATUS|/$GTALKUNVL/g" $WORKDIR/jabber.tmp sed -i "s/|STATUS|/$GTALKUNVL/g" $WORKDIR/jabber.tmp
sed -i "s/|STATUSMESSAGE|/\"\"/g" $WORKDIR/jabber.tmp sed -i "s/|STATUSMESSAGE|/\"\"/g" $WORKDIR/jabber.tmp
fi fi
# Add this account's configuration to the temp file containing all account configs. # Add this account's configuration to the temp file containing all account configs.
sed "s/|SECRET|/$secret/g" $WORKDIR/jabber.tmp >> $WORKDIR/jabber.TMP sed "s/|SECRET|/$secret/g" $WORKDIR/jabber.tmp >> $WORKDIR/jabber.TMP
# If this provider is enabled for outgoing calls. # If this provider is enabled for outgoing calls.
if [ "$make_outgoing_calls" = "yes" ] ; then if [ "$make_outgoing_calls" = "yes" ] ; then
numprefix="`uci -q get ${MODULENAME}-calls.outgoing_calls.$name`" numprefix="`uci -q get ${MODULENAME}-calls.outgoing_calls.$name`"
# If no prefixes are specified, then we use "X" which matches any prefix. # If no prefixes are specified, then we use "X" which matches any prefix.
[ -z "$numprefix" ] && numprefix="X" [ -z "$numprefix" ] && numprefix="X"
for p in $numprefix ; do for p in $numprefix ; do
sed "s/|NUMPREFIX|/$p/g" $TMPL_EXTOUTGTALK |\ sed "s/|NUMPREFIX|/$p/g" $TMPL_EXTOUTGTALK |\
sed "s/|NAME|/$name/g" >> $WORKDIR/outext-$name.TMP sed "s/|NAME|/$name/g" >> $WORKDIR/outext-$name.TMP
done done
# Add this provider to the list of enabled outbound providers. # Add this provider to the list of enabled outbound providers.
if [ -z "$outbound_providers" ] ; then if [ -z "$outbound_providers" ] ; then
outbound_providers="$name" outbound_providers="$name"
else else
outbound_providers="$outbound_providers $name" outbound_providers="$outbound_providers $name"
fi fi
fi fi
rm -f $WORKDIR/jabber.tmp rm -f $WORKDIR/jabber.tmp
} }
# Creates configuration for a SIP provider account, and adds it to the temporary file that holds # Creates configuration for a SIP provider account, and adds it to the temporary file that holds
@ -350,92 +351,92 @@ pbx_add_jabber()
# Also creates the outgoing extensions which are used in users' outgoing contexts. # Also creates the outgoing extensions which are used in users' outgoing contexts.
pbx_add_peer() pbx_add_peer()
{ {
local defaultuser local defaultuser
local secret local secret
local host local host
local fromdomain local fromdomain
local register local register
local numprefix local numprefix
local make_outgoing_calls local make_outgoing_calls
local name local name
local users_to_ring local users_to_ring
local port local port
local outboundproxy local outboundproxy
config_get defaultuser $1 defaultuser config_get defaultuser $1 defaultuser
config_get secret $1 secret config_get secret $1 secret
config_get host $1 host config_get host $1 host
config_get port $1 port config_get port $1 port
config_get outbountproxy $1 outboundproxy config_get outbountproxy $1 outboundproxy
config_get fromdomain $1 fromdomain config_get fromdomain $1 fromdomain
config_get register $1 register config_get register $1 register
config_get numprefix $1 numprefix config_get numprefix $1 numprefix
config_get make_outgoing_calls $1 make_outgoing_calls config_get make_outgoing_calls $1 make_outgoing_calls
config_get name $1 name config_get name $1 name
[ -z "$defaultuser" -o -z "$secret" -o -z "$host" ] && return [ -z "$defaultuser" -o -z "$secret" -o -z "$host" ] && return
[ -z "$fromdomain" ] && fromdomain=$host [ -z "$fromdomain" ] && fromdomain=$host
[ -n "$port" ] && port="port=$port" [ -n "$port" ] && port="port=$port"
[ -n "$outboundproxy" ] && outboundproxy="outboundproxy=$outboundproxy" [ -n "$outboundproxy" ] && outboundproxy="outboundproxy=$outboundproxy"
# Construct a sip peer entry for this provider. # Construct a sip peer entry for this provider.
sed "s/|DEFAULTUSER|/$defaultuser/" $TMPL_SIPPEER > $WORKDIR/sip_peer.tmp sed "s/|DEFAULTUSER|/$defaultuser/" $TMPL_SIPPEER > $WORKDIR/sip_peer.tmp
sed -i "s/|NAME|/$name/" $WORKDIR/sip_peer.tmp sed -i "s/|NAME|/$name/" $WORKDIR/sip_peer.tmp
sed -i "s/|FROMUSER|/$defaultuser/" $WORKDIR/sip_peer.tmp sed -i "s/|FROMUSER|/$defaultuser/" $WORKDIR/sip_peer.tmp
sed -i "s/|SECRET|/$secret/" $WORKDIR/sip_peer.tmp sed -i "s/|SECRET|/$secret/" $WORKDIR/sip_peer.tmp
sed -i "s/|HOST|/$host/" $WORKDIR/sip_peer.tmp sed -i "s/|HOST|/$host/" $WORKDIR/sip_peer.tmp
sed -i "s/|PORT|/$port/" $WORKDIR/sip_peer.tmp sed -i "s/|PORT|/$port/" $WORKDIR/sip_peer.tmp
sed -i "s/|OUTBOUNDPROXY|/$outboundproxy/" $WORKDIR/sip_peer.tmp sed -i "s/|OUTBOUNDPROXY|/$outboundproxy/" $WORKDIR/sip_peer.tmp
# Add this account's configuration to the temp file containing all account configs. # Add this account's configuration to the temp file containing all account configs.
sed "s/|FROMDOMAIN|/$host/" $WORKDIR/sip_peer.tmp >> $WORKDIR/sip_peers.TMP sed "s/|FROMDOMAIN|/$host/" $WORKDIR/sip_peer.tmp >> $WORKDIR/sip_peers.TMP
# If this provider is enabled for incoming calls. # If this provider is enabled for incoming calls.
if [ "$register" = "yes" ] ; then if [ "$register" = "yes" ] ; then
# Then we create a registration string for this provider. # Then we create a registration string for this provider.
sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_SIPREG > $WORKDIR/sip_reg.tmp sed "s/|DEFAULTUSER|/$defaultuser/g" $TMPL_SIPREG > $WORKDIR/sip_reg.tmp
sed -i "s/|SECRET|/$secret/g" $WORKDIR/sip_reg.tmp sed -i "s/|SECRET|/$secret/g" $WORKDIR/sip_reg.tmp
sed "s/|NAME|/$name/g" $WORKDIR/sip_reg.tmp >> $WORKDIR/sip_regs.TMP sed "s/|NAME|/$name/g" $WORKDIR/sip_reg.tmp >> $WORKDIR/sip_regs.TMP
users_to_ring="`uci -q get ${MODULENAME}-calls.incoming_calls.$name`" users_to_ring="`uci -q get ${MODULENAME}-calls.incoming_calls.$name`"
# If no users have been specified to ring, we ring all users enabled for incoming calls. # If no users have been specified to ring, we ring all users enabled for incoming calls.
if [ -z "$users_to_ring" ] ; then if [ -z "$users_to_ring" ] ; then
users_to_ring=$localusers_to_ring users_to_ring=$localusers_to_ring
else else
# Else, we cook up a string formatted for the Dial command # Else, we cook up a string formatted for the Dial command
# with the specified users (SIP/user1&SIP/user2&...). We do it # with the specified users (SIP/user1&SIP/user2&...). We do it
# with set, shift and a loop in order to be more tolerant of ugly whitespace # with set, shift and a loop in order to be more tolerant of ugly whitespace
# messes entered by users. # messes entered by users.
set $users_to_ring set $users_to_ring
users_to_ring="SIP\/$1" && shift users_to_ring="SIP\/$1" && shift
for u in $@ ; do users_to_ring=$users_to_ring\\\&SIP\\\/$u ; done for u in $@ ; do users_to_ring=$users_to_ring\\\&SIP\\\/$u ; done
fi fi
# And we create an incoming calls context for this provider. # And we create an incoming calls context for this provider.
sed "s/|NAME|/$name/g" $TMPL_EXTINCNTXTSIP |\ sed "s/|NAME|/$name/g" $TMPL_EXTINCNTXTSIP |\
sed "s/|LOCALUSERS|/$users_to_ring/g" >> $WORKDIR/inext.TMP sed "s/|LOCALUSERS|/$users_to_ring/g" >> $WORKDIR/inext.TMP
fi fi
# If this provider is enabled for outgoing calls. # If this provider is enabled for outgoing calls.
if [ "$make_outgoing_calls" = "yes" ] ; then if [ "$make_outgoing_calls" = "yes" ] ; then
numprefix="`uci -q get ${MODULENAME}-calls.outgoing_calls.$name`" numprefix="`uci -q get ${MODULENAME}-calls.outgoing_calls.$name`"
# If no prefixes are specified, then we use "X" which matches any prefix. # If no prefixes are specified, then we use "X" which matches any prefix.
[ -z "$numprefix" ] && numprefix="X" [ -z "$numprefix" ] && numprefix="X"
for p in $numprefix ; do for p in $numprefix ; do
sed "s/|NUMPREFIX|/$p/g" $TMPL_EXTOUTSIP |\ sed "s/|NUMPREFIX|/$p/g" $TMPL_EXTOUTSIP |\
sed "s/|NAME|/$name/g" >> $WORKDIR/outext-$name.TMP sed "s/|NAME|/$name/g" >> $WORKDIR/outext-$name.TMP
done done
# Add this provider to the list of enabled outbound providers. # Add this provider to the list of enabled outbound providers.
if [ -z "$outbound_providers" ] ; then if [ -z "$outbound_providers" ] ; then
outbound_providers="$name" outbound_providers="$name"
else else
outbound_providers="$outbound_providers $name" outbound_providers="$outbound_providers $name"
fi fi
fi fi
rm -f $WORKDIR/sip_peer.tmp rm -f $WORKDIR/sip_peer.tmp
rm -f $WORKDIR/sip_reg.tmp rm -f $WORKDIR/sip_reg.tmp
} }
# For all local users enabled for outbound calls, creates a context # For all local users enabled for outbound calls, creates a context
@ -443,93 +444,93 @@ pbx_add_peer()
# allowed to use. # allowed to use.
pbx_create_user_contexts() pbx_create_user_contexts()
{ {
local providers local providers
for u in $localusers_can_dial ; do for u in $localusers_can_dial ; do
sed "s/|DEFAULTUSER|/$u/g" $TMPL_EXTUSERCNTXTHDR >> $WORKDIR/userext.TMP sed "s/|DEFAULTUSER|/$u/g" $TMPL_EXTUSERCNTXTHDR >> $WORKDIR/userext.TMP
cat $WORKDIR/localext.TMP >> $WORKDIR/userext.TMP cat $WORKDIR/localext.TMP >> $WORKDIR/userext.TMP
providers="`uci -q get ${MODULENAME}-calls.providers_user_can_use.$u`" providers="`uci -q get ${MODULENAME}-calls.providers_user_can_use.$u`"
[ -z "$providers" ] && providers="$outbound_providers" [ -z "$providers" ] && providers="$outbound_providers"
# For each provider, cat the contents of outext-$name.TMP into the user's outgoing calls extension # For each provider, cat the contents of outext-$name.TMP into the user's outgoing calls extension
for p in $providers ; do for p in $providers ; do
[ -f $WORKDIR/outext-$p.TMP ] && cat $WORKDIR/outext-$p.TMP >> $WORKDIR/userext.TMP [ -f $WORKDIR/outext-$p.TMP ] && cat $WORKDIR/outext-$p.TMP >> $WORKDIR/userext.TMP
done done
cat $TMPL_EXTUSERCNTXTFTR >> $WORKDIR/userext.TMP cat $TMPL_EXTUSERCNTXTFTR >> $WORKDIR/userext.TMP
done done
} }
# Creates the blacklist context which hangs up on blacklisted numbers. # Creates the blacklist context which hangs up on blacklisted numbers.
pbx_add_blacklist() pbx_add_blacklist()
{ {
local blacklist1 local blacklist1
local blacklist2 local blacklist2
config_get blacklist1 blacklisting blacklist1 config_get blacklist1 blacklisting blacklist1
config_get blacklist2 blacklisting blacklist2 config_get blacklist2 blacklisting blacklist2
# We create the blacklist context no matter whether the blacklist # We create the blacklist context no matter whether the blacklist
# actually contains entries or not, since the PBX will send calls # actually contains entries or not, since the PBX will send calls
# to the context for a check against the list anyway. # to the context for a check against the list anyway.
cp $TMPL_EXTBLKLISTHDR $WORKDIR/blacklist.TMP cp $TMPL_EXTBLKLISTHDR $WORKDIR/blacklist.TMP
for n in $blacklist1 $blacklist2 ; do for n in $blacklist1 $blacklist2 ; do
sed "s/|BLACKLISTITEM|/$n/g" $TMPL_EXTBLKLIST >> $WORKDIR/blacklist.TMP sed "s/|BLACKLISTITEM|/$n/g" $TMPL_EXTBLKLIST >> $WORKDIR/blacklist.TMP
done done
cat $TMPL_EXTBLKLISTFTR >> $WORKDIR/blacklist.TMP cat $TMPL_EXTBLKLISTFTR >> $WORKDIR/blacklist.TMP
} }
# Creates the callthrough context which allows specified numbers to get # Creates the callthrough context which allows specified numbers to get
# into the PBX and dial out as the configured user. # into the PBX and dial out as the configured user.
pbx_add_callthrough() pbx_add_callthrough()
{ {
local callthrough_number_list local callthrough_number_list
local defaultuser local defaultuser
local pin local pin
local enabled local enabled
config_get callthrough_number_list $1 callthrough_number_list config_get callthrough_number_list $1 callthrough_number_list
config_get defaultuser $1 defaultuser config_get defaultuser $1 defaultuser
config_get pin $1 pin config_get pin $1 pin
config_get enabled $1 enabled config_get enabled $1 enabled
[ "$enabled" = "no" ] && return [ "$enabled" = "no" ] && return
[ "$defaultuser" = "" ] && return [ "$defaultuser" = "" ] && return
for callthrough_number in $callthrough_number_list ; do for callthrough_number in $callthrough_number_list ; do
sed "s/|NUMBER|/$callthrough_number/g" $TMPL_EXTCTHRUCHECK >> $WORKDIR/callthroughcheck.TMP sed "s/|NUMBER|/$callthrough_number/g" $TMPL_EXTCTHRUCHECK >> $WORKDIR/callthroughcheck.TMP
sed "s/|NUMBER|/$callthrough_number/g" $TMPL_EXTCTHRU |\ sed "s/|NUMBER|/$callthrough_number/g" $TMPL_EXTCTHRU |\
sed "s/|DEFAULTUSER|/$defaultuser/" |\ sed "s/|DEFAULTUSER|/$defaultuser/" |\
sed "s/|PIN|/$pin/" >> $WORKDIR/callthrough.TMP sed "s/|PIN|/$pin/" >> $WORKDIR/callthrough.TMP
done done
} }
# Creates sip.conf from its template. # Creates sip.conf from its template.
pbx_cook_sip_template() pbx_cook_sip_template()
{ {
local useragent local useragent
local externhost local externhost
local bindport local bindport
config_get useragent advanced useragent config_get useragent advanced useragent
config_get externhost advanced externhost config_get externhost advanced externhost
config_get bindport advanced bindport config_get bindport advanced bindport
[ -z "$useragent" ] && useragent="$USERAGENT" [ -z "$useragent" ] && useragent="$USERAGENT"
sed "s/|USERAGENT|/$useragent/g" $TMPL_SIP > $WORKDIR/sip.conf sed "s/|USERAGENT|/$useragent/g" $TMPL_SIP > $WORKDIR/sip.conf
if [ -z "$externhost" ] ; then if [ -z "$externhost" ] ; then
sed -i "s/externhost=|EXTERNHOST|//g" $WORKDIR/sip.conf sed -i "s/externhost=|EXTERNHOST|//g" $WORKDIR/sip.conf
else else
sed -i "s/|EXTERNHOST|/$externhost/g" $WORKDIR/sip.conf sed -i "s/|EXTERNHOST|/$externhost/g" $WORKDIR/sip.conf
fi fi
if [ -z "$bindport" ] ; then if [ -z "$bindport" ] ; then
sed -i "s/bindport=|BINDPORT|//g" $WORKDIR/sip.conf sed -i "s/bindport=|BINDPORT|//g" $WORKDIR/sip.conf
else else
sed -i "s/|BINDPORT|/$bindport/g" $WORKDIR/sip.conf sed -i "s/|BINDPORT|/$bindport/g" $WORKDIR/sip.conf
fi fi
} }
@ -537,58 +538,57 @@ pbx_cook_sip_template()
# Creates rtp.conf from its template. # Creates rtp.conf from its template.
pbx_cook_rtp_template() pbx_cook_rtp_template()
{ {
local rtpstart local rtpstart
local rtpend local rtpend
config_get rtpstart advanced rtpstart config_get rtpstart advanced rtpstart
config_get rtpend advanced rtpend config_get rtpend advanced rtpend
sed "s/|RTPSTART|/$rtpstart/" $TMPL_RTP |\ sed "s/|RTPSTART|/$rtpstart/" $TMPL_RTP |\
sed "s/|RTPEND|/$rtpend/" > $WORKDIR/rtp.conf sed "s/|RTPEND|/$rtpend/" > $WORKDIR/rtp.conf
} }
# Makes sure the ownership of specified directories is proper. # Makes sure the ownership of specified directories is proper.
pbx_fix_ownership() pbx_fix_ownership()
{ {
chown $ASTUSER:$ASTGROUP $ASTDIRS chown $ASTUSER:$ASTGROUP $ASTDIRS
chown $ASTUSER:$ASTGROUP -R $ASTDIRSRECURSIVE chown $ASTUSER:$ASTGROUP -R $ASTDIRSRECURSIVE
} }
start() { start() {
mkdir -p $WORKDIR mkdir -p $WORKDIR
# Create the users. # Create the users.
config_load ${MODULENAME}-users config_load ${MODULENAME}-users
config_foreach pbx_add_user local_user config_foreach pbx_add_user local_user
# Create configuration for each google account. # Create configuration for each google account.
config_unset config_unset
config_load ${MODULENAME}-google config_load ${MODULENAME}-google
config_foreach pbx_add_jabber gtalk_jabber config_foreach pbx_add_jabber gtalk_jabber
# Create configuration for each voip provider. # Create configuration for each voip provider.
config_unset config_unset
config_load ${MODULENAME}-voip config_load ${MODULENAME}-voip
config_foreach pbx_add_peer voip_provider config_foreach pbx_add_peer voip_provider
# Create the user contexts, and phone blacklist. # Create the user contexts, and phone blacklist.
config_unset config_unset
config_load ${MODULENAME}-calls config_load ${MODULENAME}-calls
pbx_create_user_contexts pbx_create_user_contexts
pbx_add_blacklist pbx_add_blacklist
config_foreach pbx_add_callthrough callthrough_numbers config_foreach pbx_add_callthrough callthrough_numbers
# Prepare sip.conf using settings from the "advanced" section. # Prepare sip.conf using settings from the "advanced" section.
config_unset config_unset
config_load ${MODULENAME}-advanced config_load ${MODULENAME}-advanced
pbx_cook_sip_template pbx_cook_sip_template
pbx_cook_rtp_template pbx_cook_rtp_template
# Assemble the configuration, and copy changed files over. # Assemble the configuration, and copy changed files over.
pbx_assemble_and_copy_config pbx_assemble_and_copy_config
# Enforce ownership of specified files and directories.
pbx_fix_ownership
}
# Enforce ownership of specified files and directories.
pbx_fix_ownership
}