From b4b7418a85ad30f59f1f0e53eeaecb59cd90bc31 Mon Sep 17 00:00:00 2001 From: Mark Crane Date: Sat, 20 Apr 2013 23:28:45 +0000 Subject: [PATCH] Add the new XML handler. --- .../install/scripts/app/xml_handler/index.lua | 126 ++ .../scripts/configuration/conference.conf.lua | 103 ++ .../scripts/configuration/sofia.conf.lua | 265 ++++ .../resources/scripts/dialplan/dialplan.lua | 264 ++++ .../scripts/directory/action/group_call.lua | 124 ++ .../directory/action/message-count.lua | 8 + .../resources/scripts/directory/directory.lua | 374 ++++++ includes/install/scripts/xml_handler.lua | 1133 ----------------- 8 files changed, 1264 insertions(+), 1133 deletions(-) create mode 100644 includes/install/scripts/app/xml_handler/index.lua create mode 100644 includes/install/scripts/app/xml_handler/resources/scripts/configuration/conference.conf.lua create mode 100644 includes/install/scripts/app/xml_handler/resources/scripts/configuration/sofia.conf.lua create mode 100644 includes/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua create mode 100644 includes/install/scripts/app/xml_handler/resources/scripts/directory/action/group_call.lua create mode 100644 includes/install/scripts/app/xml_handler/resources/scripts/directory/action/message-count.lua create mode 100644 includes/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua delete mode 100644 includes/install/scripts/xml_handler.lua diff --git a/includes/install/scripts/app/xml_handler/index.lua b/includes/install/scripts/app/xml_handler/index.lua new file mode 100644 index 0000000000..809793b449 --- /dev/null +++ b/includes/install/scripts/app/xml_handler/index.lua @@ -0,0 +1,126 @@ +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--set defaults + expire = {} + expire["directory"] = "3600"; + expire["dialplan"] = "300"; + expire["sofia.conf"] = "3600"; + +--set the debug options + debug["params"] = true; + debug["sql"] = false; + debug["xml_request"] = true; + debug["xml_string"] = false; + debug["cache"] = false; + +--general functions + dofile(scripts_dir.."/resources/functions/trim.lua"); + dofile(scripts_dir.."/resources/functions/file_exists.lua"); + dofile(scripts_dir.."/resources/functions/explode.lua"); + +--connect to the database + dbh = freeswitch.Dbh(database["system"]); + +--if the params class and methods do not exist then add them to prevent errors + if (not params) then + params = {} + function params:getHeader(name) + self.name = name + end + function params:serialize(name) + self.name = name + end + end + +--show the params in the console + if (debug["params"]) then + freeswitch.consoleLog("notice", "[xml_handler] Params:\n" .. params:serialize() .. "\n"); + end + +--show the xml request in the console + if (debug["xml_request"]) then + freeswitch.consoleLog("notice", "[xml_handler] Section: " .. XML_REQUEST["section"] .. "\n"); + freeswitch.consoleLog("notice", "[xml_handler] Tag Name: " .. XML_REQUEST["tag_name"] .. "\n"); + freeswitch.consoleLog("notice", "[xml_handler] Key Name: " .. XML_REQUEST["key_name"] .. "\n"); + freeswitch.consoleLog("notice", "[xml_handler] Key Value: " .. XML_REQUEST["key_value"] .. "\n"); + end + +--get the params and set them as variables + domain_name = params:getHeader("sip_from_host"); + if (domain_uuid == nil) then + domain_uuid = params:getHeader("domain_uuid"); + end + domain_name = params:getHeader("domain"); + if (domain_name == nil) then + domain_name = params:getHeader("domain_name"); + end + if (domain_name == nil) then + domain_name = params:getHeader("variable_domain_name"); + end + purpose = params:getHeader("purpose"); + profile = params:getHeader("profile"); + key = params:getHeader("key"); + user = params:getHeader("user"); + user_context = params:getHeader("variable_user_context"); + call_context = params:getHeader("Caller-Context"); + destination_number = params:getHeader("Caller-Destination-Number"); + caller_id_number = params:getHeader("Caller-Caller-ID-Number"); + hunt_context = params:getHeader("Hunt-Context"); + if (hunt_context ~= nil) then + call_context = hunt_context; + end + +--prepare the api object + api = freeswitch.API(); + +--get the domain_uuid + if (domain_uuid == nil) then + --get the domain_uuid + if (domain_name ~= nil) then + sql = "SELECT domain_uuid FROM v_domains "; + sql = sql .. "WHERE domain_name = '" .. domain_name .."' "; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); + end + status = dbh:query(sql, function(rows) + domain_uuid = rows["domain_uuid"]; + end); + end + end + +--process the sections + if (XML_REQUEST["section"] == "configuration") then + dofile(scripts_dir.."/app/xml_handler/resources/scripts/configuration/"..XML_REQUEST["key_value"]..".lua"); + end + if (XML_REQUEST["section"] == "directory") then + dofile(scripts_dir.."/app/xml_handler/resources/scripts/directory/directory.lua"); + end + if (XML_REQUEST["section"] == "dialplan") then + dofile(scripts_dir.."/app/xml_handler/resources/scripts/dialplan/dialplan.lua"); + end + +--close the database connection + dbh:release(); \ No newline at end of file diff --git a/includes/install/scripts/app/xml_handler/resources/scripts/configuration/conference.conf.lua b/includes/install/scripts/app/xml_handler/resources/scripts/configuration/conference.conf.lua new file mode 100644 index 0000000000..d8003c73f3 --- /dev/null +++ b/includes/install/scripts/app/xml_handler/resources/scripts/configuration/conference.conf.lua @@ -0,0 +1,103 @@ +-- xml_handler.lua +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--set the xml array + local xml = {} + table.insert(xml, [[]]); + table.insert(xml, [[]]); + table.insert(xml, [[
]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, ""); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + +--set the xml array and then concatenate the array to a string + table.insert(xml, [[ ]]); + table.insert(xml, [[
]]); + table.insert(xml, [[
]]); + XML_STRING = table.concat(xml, "\n"); + +--send the xml to the console + if (debug["xml_string"]) then + local file = assert(io.open("/tmp/conference.conf.xml", "w")); + file:write(XML_STRING); + file:close(); + end \ No newline at end of file diff --git a/includes/install/scripts/app/xml_handler/resources/scripts/configuration/sofia.conf.lua b/includes/install/scripts/app/xml_handler/resources/scripts/configuration/sofia.conf.lua new file mode 100644 index 0000000000..ae3a55b4df --- /dev/null +++ b/includes/install/scripts/app/xml_handler/resources/scripts/configuration/sofia.conf.lua @@ -0,0 +1,265 @@ +-- xml_handler.lua +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--get the cache + if (trim(api:execute("module_exists", "mod_memcache")) == "true") then + XML_STRING = trim(api:execute("memcache", "get configuration:sofia.conf")); + else + XML_STRING = "-ERR NOT FOUND"; + end + +--set the cache + if (XML_STRING == "-ERR NOT FOUND") then + + --get the variables + vars = trim(api:execute("global_getvar", "")); + + --start the xml array + local xml = {} + table.insert(xml, [[]]); + table.insert(xml, [[]]); + table.insert(xml, [[
]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + --table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + --table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + + --set defaults + previous_sip_profile_name = ""; + profile_tag_status = "closed"; + + --run the query + sql = "select p.sip_profile_name, p.sip_profile_description, s.sip_profile_setting_name, s.sip_profile_setting_value "; + sql = sql .. "from v_sip_profiles as p, v_sip_profile_settings as s "; + sql = sql .. "where p.sip_profile_uuid = s.sip_profile_uuid "; + sql = sql .. "and s.sip_profile_setting_enabled = 'true' "; + sql = sql .. "order by p.sip_profile_name asc "; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); + end + x = 0; + dbh:query(sql, function(row) + --set as variables + sip_profile_name = row.sip_profile_name; + --sip_profile_description = row.sip_profile_description; + sip_profile_setting_name = row.sip_profile_setting_name; + sip_profile_setting_value = row.sip_profile_setting_value; + + --open xml tag + if (sip_profile_name ~= previous_sip_profile_name) then + if (x > 1) then + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + end + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + --table.insert(xml, [[ ]]); + + --get the gateways + if (domain_count > 1) then + sql = "select * from v_gateways as g, v_domains as d "; + sql = sql .. "where g.profile = '"..sip_profile_name.."' "; + sql = sql .. "and g.enabled = 'true' "; + sql = sql .. "and g.domain_uuid = d.domain_uuid "; + else + sql = "select * from v_gateways "; + sql = sql .. "where profile = '"..sip_profile_name.."' and enabled = 'true' "; + end + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); + end + x = 0; + dbh:query(sql, function(field) + --set as variables + gateway = field.gateway; + gateway = gateway:gsub(" ", "_"); + + if (domain_count > 1) then + table.insert(xml, [[ ]]); + else + table.insert(xml, [[ ]]); + end + + if (string.len(field.username) > 0) then + table.insert(xml, [[ ]]); + else + table.insert(xml, [[ ]]); + end + if (string.len(field.distinct_to) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.auth_username) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.password) > 0) then + table.insert(xml, [[ ]]); + else + table.insert(xml, [[ ]]); + end + if (string.len(field.realm) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.from_user) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.from_domain) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.proxy) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.register_proxy) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.outbound_proxy) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.expire_seconds) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.register) > 0) then + table.insert(xml, [[ ]]); + end + + if (field.register_transport) then + if (field.register_transport == "udp") then + table.insert(xml, [[ ]]); + elseif (field.register_transport == "tcp") then + table.insert(xml, [[ ]]); + elseif (field.register_transport == "tls") then + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + else + table.insert(xml, [[ ]]); + end + end + + if (string.len(field.retry_seconds) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.extension) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.ping) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.context) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.caller_id_in_from) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.supress_cng) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.sip_cid_type) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(field.extension_in_contact) > 0) then + table.insert(xml, [[ ]]); + end + table.insert(xml, [[ ]]); + end) + + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + profile_tag_status = "open"; + end + + --loop through the var array + for line in (vars.."\n"):gmatch"(.-)\n" do + if (line) then + pos = string.find(line, "=", 0, true); + --name = string.sub( line, 0, pos-1); + --value = string.sub( line, pos+1); + sip_profile_setting_value = sip_profile_setting_value:gsub("%$%${"..string.sub( line, 0, pos-1).."}", string.sub( line, pos+1)); + end + end + + --remove $ and replace with "" + --if (sip_profile_setting_value) then + -- sip_profile_setting_value = sip_profile_setting_value:gsub("%$", ""); + --end + + --set the parameters + if (sip_profile_setting_name) then + table.insert(xml, [[ ]]); + end + + --set the previous value + previous_sip_profile_name = sip_profile_name; + + --increment the value of x + x = x + 1; + end) + + --close the extension tag if it was left open + if (profile_tag_status == "open") then + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + profile_tag_status = "close"; + end + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[
]]); + table.insert(xml, [[
]]); + XML_STRING = table.concat(xml, "\n"); + if (debug["xml_string"]) then + freeswitch.consoleLog("notice", "[xml_handler] XML_STRING: " .. XML_STRING .. "\n"); + end + + --set the cache + result = trim(api:execute("memcache", "set configuration:sofia.conf '"..XML_STRING:gsub("'", "'").."' "..expire["sofia.conf"])); + + --send the xml to the console + if (debug["xml_string"]) then + local file = assert(io.open("/tmp/sofia.conf.xml", "w")); + file:write(XML_STRING); + file:close(); + end + + --send to the console + if (debug["cache"]) then + freeswitch.consoleLog("notice", "[xml_handler] configuration:sofia.conf source: database\n"); + end + else + --replace the ' back to a single quote + XML_STRING = XML_STRING:gsub("'", "'"); + + --send to the console + if (debug["cache"]) then + freeswitch.consoleLog("notice", "[xml_handler] configuration:sofia.conf source: memcache\n"); + end + end --if XML_STRING \ No newline at end of file diff --git a/includes/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua b/includes/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua new file mode 100644 index 0000000000..fb1df7952f --- /dev/null +++ b/includes/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua @@ -0,0 +1,264 @@ +-- xml_handler.lua +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--get the cache + if (trim(api:execute("module_exists", "mod_memcache")) == "true") then + XML_STRING = trim(api:execute("memcache", "get dialplan:" .. call_context)); + else + XML_STRING = "-ERR NOT FOUND"; + end + +--set the cache + if (XML_STRING == "-ERR NOT FOUND") then + --set the xml array and then concatenate the array to a string + local xml = {} + table.insert(xml, [[]]); + table.insert(xml, [[]]); + table.insert(xml, [[
]]); + table.insert(xml, [[ ]]); + + --set defaults + previous_dialplan_uuid = ""; + previous_dialplan_detail_group = ""; + previous_dialplan_detail_tag = ""; + previous_dialplan_detail_type = ""; + previous_dialplan_detail_data = ""; + dialplan_tag_status = "closed"; + condition_tag_status = "closed"; + + --get the dialplan and related details + sql = "select * from v_dialplans as d, v_dialplan_details as s "; + sql = sql .. "where d.dialplan_context = '" .. call_context .. "' "; + sql = sql .. "and d.dialplan_enabled = 'true' "; + sql = sql .. "and d.dialplan_uuid = s.dialplan_uuid "; + --if (call_context ~= "public") then + -- sql = sql .. "and d.domain_uuid = '" .. domain_uuid .. "' "; + --end + sql = sql .. "order by "; + sql = sql .. "d.dialplan_order asc, "; + sql = sql .. "d.dialplan_name asc, "; + sql = sql .. "d.dialplan_uuid asc, "; + sql = sql .. "s.dialplan_detail_group asc, "; + sql = sql .. "CASE s.dialplan_detail_tag "; + sql = sql .. "WHEN 'condition' THEN 1 "; + sql = sql .. "WHEN 'action' THEN 2 "; + sql = sql .. "WHEN 'anti-action' THEN 3 "; + sql = sql .. "ELSE 100 END, "; + sql = sql .. "s.dialplan_detail_order asc "; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); + end + x = 0; + dbh:query(sql, function(row) + --get the dialplan + --domain_uuid = row.domain_uuid; + dialplan_uuid = row.dialplan_uuid; + --app_uuid = row.app_uuid; + --dialplan_context = row.dialplan_context; + dialplan_name = row.dialplan_name; + --dialplan_number = row.dialplan_number; + dialplan_continue = row.dialplan_continue; + --dialplan_order = row.dialplan_order; + --dialplan_enabled = row.dialplan_enabled; + --dialplan_description = row.dialplan_description; + --get the dialplan details + --dialplan_detail_uuid = row.dialplan_detail_uuid; + dialplan_detail_tag = row.dialplan_detail_tag; + dialplan_detail_type = row.dialplan_detail_type; + dialplan_detail_data = row.dialplan_detail_data; + dialplan_detail_break = row.dialplan_detail_break; + dialplan_detail_inline = row.dialplan_detail_inline; + dialplan_detail_group = row.dialplan_detail_group; + --dialplan_detail_order = row.dialplan_detail_order; + + --remove $$ and replace with $ + dialplan_detail_data = dialplan_detail_data:gsub("%$%$", "$"); + + --get the dialplan detail inline + detail_inline = ""; + if (dialplan_detail_inline) then + if (string.len(dialplan_detail_inline) > 0) then + detail_inline = [[ inline="]] .. dialplan_detail_inline .. [["]]; + end + end + + --close the tags + if (condition_tag_status ~= "closed") then + if (previous_dialplan_uuid ~= dialplan_uuid) then + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + dialplan_tag_status = "closed"; + condition_tag_status = "closed"; + else + if (previous_dialplan_detail_group ~= dialplan_detail_group and previous_dialplan_detail_tag == "condition") then + table.insert(xml, [[ ]]); + condition_tag_status = "closed"; + end + end + end + + --open the tags + if (dialplan_tag_status == "closed") then + table.insert(xml, [[ ]]); + dialplan_tag_status = "open"; + end + if (dialplan_detail_tag == "condition") then + --determine the type of condition + if (dialplan_detail_type == "hour") then + condition_type = 'time'; + elseif (dialplan_detail_type == "minute") then + condition_type = 'time'; + elseif (dialplan_detail_type == "minute-of-day") then + condition_type = 'time'; + elseif (dialplan_detail_type == "mday") then + condition_type = 'time'; + elseif (dialplan_detail_type == "mweek") then + condition_type = 'time'; + elseif (dialplan_detail_type == "mon") then + condition_type = 'time'; + elseif (dialplan_detail_type == "yday") then + condition_type = 'time'; + elseif (dialplan_detail_type == "year") then + condition_type = 'time'; + elseif (dialplan_detail_type == "wday") then + condition_type = 'time'; + elseif (dialplan_detail_type == "week") then + condition_type = 'time'; + else + condition_type = 'default'; + end + + --get the condition break attribute + condition_break = ""; + if (dialplan_detail_break) then + if (string.len(dialplan_detail_break) > 0) then + condition_break = [[ break="]] .. dialplan_detail_break .. [["]]; + end + end + + if (condition_tag_status == "open") then + if (previous_dialplan_detail_tag == "condition") then + --add the condition self closing tag + if (condition) then + if (string.len(condition) > 0) then + table.insert(xml, condition .. [[/>]]); + end + end + end + if (previous_dialplan_detail_tag == "action" or previous_dialplan_detail_tag == "anti-action") then + table.insert(xml, [[ ]]); + condition_tag_status = "closed"; + condition_type = ""; + condition_attribute = ""; + condition_expression = ""; + end + end + + --condition tag but leave off the ending + if (condition_type == "default") then + condition = [[ ]]); + condition = ""; --prevents duplicate time conditions + end + end + if (dialplan_detail_tag == "action") then + table.insert(xml, [[ ]]); + end + if (dialplan_detail_tag == "anti-action") then + table.insert(xml, [[ ]]); + end + + --save the previous values + previous_dialplan_uuid = dialplan_uuid; + previous_dialplan_detail_group = dialplan_detail_group; + previous_dialplan_detail_tag = dialplan_detail_tag; + previous_dialplan_detail_type = dialplan_detail_type; + previous_dialplan_detail_data = dialplan_detail_data; + + --increment the x + x = x + 1; + end); + + --close the extension tag if it was left open + if (dialplan_tag_status == "open") then + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + end + + --set the xml array and then concatenate the array to a string + table.insert(xml, [[ ]]); + table.insert(xml, [[
]]); + table.insert(xml, [[
]]); + XML_STRING = table.concat(xml, "\n"); + + --set the cache + tmp = XML_STRING:gsub("\\", "\\\\"); + result = trim(api:execute("memcache", "set dialplan:" .. call_context .. " '"..tmp:gsub("'", "'").."' "..expire["dialplan"])); + + --send the xml to the console + if (debug["xml_string"]) then + local file = assert(io.open("/tmp/dialplan-" .. call_context .. ".xml", "w")); + file:write(XML_STRING); + file:close(); + end + + --send to the console + if (debug["cache"]) then + freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: database\n"); + end + else + --replace the ' back to a single quote + XML_STRING = XML_STRING:gsub("'", "'"); + + --send to the console + if (debug["cache"]) then + freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: memcache\n"); + end + end diff --git a/includes/install/scripts/app/xml_handler/resources/scripts/directory/action/group_call.lua b/includes/install/scripts/app/xml_handler/resources/scripts/directory/action/group_call.lua new file mode 100644 index 0000000000..c1479cdcda --- /dev/null +++ b/includes/install/scripts/app/xml_handler/resources/scripts/directory/action/group_call.lua @@ -0,0 +1,124 @@ +-- xml_handler.lua +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--get the cache + if (trim(api:execute("module_exists", "mod_memcache")) == "true") then + XML_STRING = trim(api:execute("memcache", "get directory:groups:"..domain_name)); + else + XML_STRING = "-ERR NOT FOUND"; + end + +--set the cache + if (XML_STRING == "-ERR NOT FOUND") then + --build the call group array + sql = [[ + select * from v_extensions + where domain_uuid = ']]..domain_uuid..[[' + order by call_group asc + ]]; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); + end + call_group_array = {}; + status = dbh:query(sql, function(row) + call_group = row['call_group']; + --call_group = str_replace(";", ",", call_group); + tmp_array = explode(",", call_group); + for key,value in pairs(tmp_array) do + value = trim(value); + --freeswitch.consoleLog("notice", "[directory] Key: " .. key .. " Value: " .. value .. " " ..row['extension'] .."\n"); + if (string.len(value) == 0) then + --do nothing + else + if (call_group_array[value] == nil) then + call_group_array[value] = row['extension']; + else + call_group_array[value] = call_group_array[value]..','..row['extension']; + end + end + end + end); + --for key,value in pairs(call_group_array) do + -- freeswitch.consoleLog("notice", "[directory] Key: " .. key .. " Value: " .. value .. "\n"); + --end + + --build the xml array + local xml = {} + table.insert(xml, [[]]); + table.insert(xml, [[]]); + table.insert(xml, [[
]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + previous_call_group = ""; + for key, value in pairs(call_group_array) do + call_group = trim(key); + extension_list = trim(value); + if (string.len(call_group) > 0) then + freeswitch.consoleLog("notice", "[directory] call_group: " .. call_group .. "\n"); + freeswitch.consoleLog("notice", "[directory] extension_list: " .. extension_list .. "\n"); + if (previous_call_group ~= call_group) then + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + extension_array = explode(",", extension_list); + for index,tmp_extension in pairs(extension_array) do + table.insert(xml, [[ ]]); + end + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + end + previous_call_group = call_group; + end + end + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[
]]); + table.insert(xml, [[
]]); + XML_STRING = table.concat(xml, "\n"); + + --set the cache + result = trim(api:execute("memcache", "set directory:groups:"..domain_name.." '"..XML_STRING:gsub("'", "'").."' "..expire["directory"])); + + --send to the console + if (debug["cache"]) then + freeswitch.consoleLog("notice", "[xml_handler] directory:groups:"..domain_name.." source: database\n"); + end + + else + --replace the ' back to a single quote + XML_STRING = XML_STRING:gsub("'", "'"); + + --send to the console + if (debug["cache"]) then + if (XML_STRING) then + freeswitch.consoleLog("notice", "[xml_handler] directory:groups:"..domain_name.." source: memcache\n"); + end + end + end + +--send the xml to the console + if (debug["xml_string"]) then + freeswitch.consoleLog("notice", "[xml_handler] directory:groups:"..domain_name.." XML_STRING: \n" .. XML_STRING .. "\n"); + end \ No newline at end of file diff --git a/includes/install/scripts/app/xml_handler/resources/scripts/directory/action/message-count.lua b/includes/install/scripts/app/xml_handler/resources/scripts/directory/action/message-count.lua new file mode 100644 index 0000000000..c2c5455391 --- /dev/null +++ b/includes/install/scripts/app/xml_handler/resources/scripts/directory/action/message-count.lua @@ -0,0 +1,8 @@ + +--params + --Event-Calling-Line-Number: 102 + --Event-Sequence: 4173 + --action: message-count + --key: id + --user: *98 + --domain: example.com \ No newline at end of file diff --git a/includes/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua b/includes/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua new file mode 100644 index 0000000000..8d57f35472 --- /dev/null +++ b/includes/install/scripts/app/xml_handler/resources/scripts/directory/directory.lua @@ -0,0 +1,374 @@ +-- xml_handler.lua +-- Part of FusionPBX +-- Copyright (C) 2013 Mark J Crane +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. + +--set the default + continue = true; + +--get the action + action = params:getHeader("action"); + purpose = params:getHeader("purpose"); + --sip_auth - registration + --group_call - call group has been called + --user_call - user has been called + +--additional information + --event_calling_function = params:getHeader("Event-Calling-Function"); + +--determine the correction action to perform + if (purpose == "gateways") then + if (params:getHeader("profile") == "internal") then + --process when the sip profile is rescanned or sofia is reloaded + local xml = {} + table.insert(xml, [[]]); + table.insert(xml, [[]]); + table.insert(xml, [[
]]); + sql = "SELECT * FROM v_domains "; + dbh:query(sql, function(row) + table.insert(xml, [[ ]]); + end); + table.insert(xml, [[
]]); + table.insert(xml, [[
]]); + XML_STRING = table.concat(xml, "\n"); + end + elseif (action == "message-count") then + dofile(scripts_dir.."/app/xml_handler/resources/scripts/directory/action/message-count"); + elseif (action == "group_call") then + dofile(scripts_dir.."/app/xml_handler/resources/scripts/directory/action/group_call.lua"); + else + --handle action + --all other directory actions: sip_auth, user_call + --except for the action: group_call + + --get the cache + if (trim(api:execute("module_exists", "mod_memcache")) == "true") then + if (user == nil) then + user = ""; + end + if (domain_name) then + XML_STRING = trim(api:execute("memcache", "get directory:" .. user .. "@" .. domain_name)); + end + if (XML_STRING == "-ERR NOT FOUND") then + continue = true; + else + continue = false; + end + else + XML_STRING = ""; + continue = true; + end + + --prevent processing for invalid user + if (user == "*97") then + continue = false; + end + + --get the extension from the database + if (continue) then + sql = "SELECT * FROM v_extensions WHERE domain_uuid = '" .. domain_uuid .. "' and extension = '" .. user .. "' and enabled = 'true' "; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); + end + dbh:query(sql, function(row) + --general + domain_uuid = row.domain_uuid; + extension_uuid = row.extension_uuid; + extension = row.extension; + cidr = ""; + if (string.len(row.cidr) > 0) then + cidr = [[ cidr="]] .. row.cidr .. [["]]; + end + number_alias = ""; + if (string.len(row.number_alias) > 0) then + number_alias = [[ number-alias="]] .. row.number_alias .. [["]]; + end + --params + password = row.password; + vm_enabled = "true"; + if (string.len(row.vm_enabled) > 0) then + vm_enabled = row.vm_enabled; + end + vm_password = row.vm_password; + vm_attach_file = "true"; + if (string.len(row.vm_attach_file) > 0) then + vm_attach_file = row.vm_attach_file; + end + vm_keep_local_after_email = "true"; + if (string.len(row.vm_keep_local_after_email) > 0) then + vm_keep_local_after_email = row.vm_keep_local_after_email; + end + if (string.len(row.vm_mailto) > 0) then + vm_mailto = row.vm_mailto; + else + vm_mailto = ""; + end + mwi_account = row.mwi_account; + auth_acl = row.auth_acl; + --variables + sip_from_user = row.extension; + call_group = row.call_group; + hold_music = row.hold_music; + toll_allow = row.toll_allow; + accountcode = row.accountcode; + user_context = row.user_context; + effective_caller_id_name = row.effective_caller_id_name; + effective_caller_id_number = row.effective_caller_id_number; + outbound_caller_id_name = row.outbound_caller_id_name; + outbound_caller_id_number = row.outbound_caller_id_number; + emergency_caller_id_number = row.emergency_caller_id_number; + directory_full_name = row.directory_full_name; + directory_visible = row.directory_visible; + directory_exten_visible = row.directory_exten_visible; + limit_max = row.limit_max; + call_timeout = row.call_timeout; + limit_destination = row.limit_destination; + sip_force_contact = row.sip_force_contact; + sip_force_expires = row.sip_force_expires; + nibble_account = row.nibble_account; + sip_bypass_media = row.sip_bypass_media; + + --set the dial_string + if (string.len(row.dial_string) > 0) then + dial_string = row.dial_string; + else + dial_string = "{sip_invite_domain=" .. domain_name .. ",leg_timeout=" .. call_timeout .. ",presence_id=" .. user .. "@" .. domain_name .. "}${sofia_contact(" .. user .. "@" .. domain_name .. ")}"; + end + end); + end + + --if the extension does not exist set continue to false; + if (extension_uuid == nil) then + continue = false; + end + + --outbound hot desking - get the extension variables + if (continue) then + sql = "SELECT * FROM v_extensions WHERE dial_domain = '" .. domain_name .. "' and dial_user = '" .. user .. "' and enabled = 'true' "; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); + end + dbh:query(sql, function(row) + --get the values from the database + extension_uuid = row.extension_uuid; + domain_uuid = row.domain_uuid; + sip_from_user = row.extension; + call_group = row.call_group; + hold_music = row.hold_music; + toll_allow = row.toll_allow; + accountcode = row.accountcode; + user_context = row.user_context; + effective_caller_id_name = row.effective_caller_id_name; + effective_caller_id_number = row.effective_caller_id_number; + outbound_caller_id_name = row.outbound_caller_id_name; + outbound_caller_id_number = row.outbound_caller_id_number; + emergency_caller_id_number = row.emergency_caller_id_number; + directory_full_name = row.directory_full_name; + directory_visible = row.directory_visible; + directory_exten_visible = row.directory_exten_visible; + limit_max = row.limit_max; + --call_timeout = row.call_timeout; + limit_destination = row.limit_destination; + sip_force_contact = row.sip_force_contact; + sip_force_expires = row.sip_force_expires; + nibble_account = row.nibble_account; + sip_bypass_media = row.sip_bypass_media; + end); + end + + --set the xml array and then concatenate the array to a string + if (continue and password) then + --build the xml + local xml = {} + table.insert(xml, [[]]); + table.insert(xml, [[]]); + table.insert(xml, [[
]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + if (number_alias) then + if (cidr) then + table.insert(xml, [[ ]]); + else + table.insert(xml, [[ ]]); + end + else + if (cidr) then + table.insert(xml, [[ ]]); + else + table.insert(xml, [[ ]]); + end + end + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + if (string.len(vm_mailto) > 0) then + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + end + if (string.len(mwi_account) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(auth_acl) > 0) then + table.insert(xml, [[ ]]); + end + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + --table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + if (string.len(call_group) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(hold_music) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(toll_allow) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(accountcode) > 0) then + table.insert(xml, [[ ]]); + end + table.insert(xml, [[ ]]); + if (string.len(effective_caller_id_name) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(effective_caller_id_number) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(outbound_caller_id_name) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(outbound_caller_id_number) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(emergency_caller_id_number) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(directory_full_name) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(directory_visible) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(directory_exten_visible) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(limit_max) > 0) then + table.insert(xml, [[ ]]); + else + table.insert(xml, [[ ]]); + end + if (string.len(limit_destination) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(sip_force_contact) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(sip_force_expires) > 0) then + table.insert(xml, [[ ]]); + end + if (string.len(nibble_account) > 0) then + table.insert(xml, [[ ]]); + end + if (sip_bypass_media == "bypass-media") then + table.insert(xml, [[ ]]); + end + if (sip_bypass_media == "bypass-media-after-bridge") then + table.insert(xml, [[ ]]); + end + if (sip_bypass_media == "proxy-media") then + table.insert(xml, [[ ]]); + end + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[ ]]); + table.insert(xml, [[
]]); + table.insert(xml, [[
]]); + XML_STRING = table.concat(xml, "\n"); + + --set the cache + if (user and domain_name) then + result = trim(api:execute("memcache", "set directory:" .. user .. "@" .. domain_name .. " '"..XML_STRING:gsub("'", "'").."' "..expire["directory"])); + end + + --send the xml to the console + if (debug["xml_string"]) then + local file = assert(io.open("/tmp/" .. user .. "@" .. domain_name .. ".xml", "w")); + file:write(XML_STRING); + file:close(); + end + + --send to the console + if (debug["cache"]) then + freeswitch.consoleLog("notice", "[xml_handler] directory:" .. user .. "@" .. domain_name .. " source: database\n"); + end + else + --replace the ' back to a single quote + if (XML_STRING) then + XML_STRING = XML_STRING:gsub("'", "'"); + end + + --send to the console + if (debug["cache"]) then + if (XML_STRING) then + freeswitch.consoleLog("notice", "[xml_handler] directory:" .. user .. "@" .. domain_name .. " source: memcache \n"); + end + end + end + end --if action + +--if the extension does not exist send "not found" + if (trim(XML_STRING) == "-ERR NOT FOUND" or XML_STRING == nil) then + --send not found + XML_STRING = [[ + +
+ +
+
]]; + --set the cache + if (user and domain_name) then + result = trim(api:execute("memcache", "set directory:" .. user .. "@" .. domain_name .. " '"..XML_STRING:gsub("'", "'").."' "..expire["directory"])); + end + end + +--send the xml to the console + if (debug["xml_string"]) then + freeswitch.consoleLog("notice", "[xml_handler] XML_STRING: \n" .. XML_STRING .. "\n"); + end \ No newline at end of file diff --git a/includes/install/scripts/xml_handler.lua b/includes/install/scripts/xml_handler.lua deleted file mode 100644 index 06ec5b44ab..0000000000 --- a/includes/install/scripts/xml_handler.lua +++ /dev/null @@ -1,1133 +0,0 @@ --- xml_handler.lua --- Part of FusionPBX --- Copyright (C) 2013 Mark J Crane --- All rights reserved. --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- 1. Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- 2. Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, --- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY --- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE --- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, --- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. - ---set defaults - expire = {} - expire["directory"] = "3600"; - expire["dialplan"] = "300"; - expire["sofia.conf"] = "3600"; - ---set the debug options - debug["params"] = false; - debug["sql"] = false; - debug["xml_request"] = false; - debug["xml_string"] = false; - debug["cache"] = false; - ---include config.lua - scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1)); - dofile(scripts_dir.."/resources/config.lua"); - ---connect to the database - dbh = freeswitch.Dbh(database["system"]); - ---add the trim function - function trim(s) - if (s == nil) then s = ''; end - return s:gsub("^%s+", ""):gsub("%s+$", "") - end - ---add the explode function - function explode ( seperator, str ) - local pos, arr = 0, {} - for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found - table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider - pos = sp + 1 -- jump past current divider - end - table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider - return arr - end - ---if the params class and methods do not exist then add them to prevent errors - if (not params) then - params = {} - function params:getHeader(name) - self.name = name - end - function params:serialize(name) - self.name = name - end - end - ---show param debug info - if (debug["params"]) then - freeswitch.consoleLog("notice", "[xml_handler] Params:\n" .. params:serialize() .. "\n"); - end - ---get the params and set them as variables - local domain_name = params:getHeader("sip_from_host"); - if (domain_uuid == nil) then - local domain_uuid = params:getHeader("domain_uuid"); - end - local domain_name = params:getHeader("domain"); - if (domain_name == nil) then - local domain_name = params:getHeader("domain_name"); - end - if (domain_name == nil) then - local domain_name = params:getHeader("variable_domain_name"); - end - local purpose = params:getHeader("purpose"); - local profile = params:getHeader("profile"); - local key = params:getHeader("key"); - local user = params:getHeader("user"); - local user_context = params:getHeader("variable_user_context"); - local call_context = params:getHeader("Caller-Context"); - local destination_number = params:getHeader("Caller-Destination-Number"); - local caller_id_number = params:getHeader("Caller-Caller-ID-Number"); - local hunt_context = params:getHeader("Hunt-Context"); - if (hunt_context ~= nil) then - call_context = hunt_context; - end - ---prepare the api object - api = freeswitch.API(); - ---get the domain_uuid - if (domain_uuid == nil) then - --get the domain_uuid - if (domain_name ~= nil) then - sql = "SELECT domain_uuid FROM v_domains "; - sql = sql .. "WHERE domain_name = '" .. domain_name .."' "; - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); - end - status = dbh:query(sql, function(rows) - domain_uuid = rows["domain_uuid"]; - end); - end - end - ---handle the configuration - if (XML_REQUEST["section"] == "configuration") then - --sofia.conf - profiles and gateways - if (XML_REQUEST["key_value"] == "sofia.conf") then - - --get the cache - if (trim(api:execute("module_exists", "mod_memcache")) == "true") then - XML_STRING = trim(api:execute("memcache", "get configuration:sofia.conf")); - else - XML_STRING = "-ERR NOT FOUND"; - end - - if (XML_STRING == "-ERR NOT FOUND") then - - --get the variables - vars = trim(api:execute("global_getvar", "")); - - --start the xml array - local xml = {} - table.insert(xml, [[]]); - table.insert(xml, [[]]); - table.insert(xml, [[
]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - --table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - --table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - - --set defaults - previous_sip_profile_name = ""; - profile_tag_status = "closed"; - - --run the query - sql = "select p.sip_profile_name, p.sip_profile_description, s.sip_profile_setting_name, s.sip_profile_setting_value "; - sql = sql .. "from v_sip_profiles as p, v_sip_profile_settings as s "; - sql = sql .. "where p.sip_profile_uuid = s.sip_profile_uuid "; - sql = sql .. "and s.sip_profile_setting_enabled = 'true' "; - sql = sql .. "order by p.sip_profile_name asc "; - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); - end - x = 0; - dbh:query(sql, function(row) - --set as variables - sip_profile_name = row.sip_profile_name; - --sip_profile_description = row.sip_profile_description; - sip_profile_setting_name = row.sip_profile_setting_name; - sip_profile_setting_value = row.sip_profile_setting_value; - - --open xml tag - if (sip_profile_name ~= previous_sip_profile_name) then - if (x > 1) then - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - --table.insert(xml, [[ ]]); - - --get the gateways - if (domain_count > 1) then - sql = "select * from v_gateways as g, v_domains as d "; - sql = sql .. "where g.profile = '"..sip_profile_name.."' "; - sql = sql .. "and g.enabled = 'true' "; - sql = sql .. "and g.domain_uuid = d.domain_uuid "; - else - sql = "select * from v_gateways "; - sql = sql .. "where profile = '"..sip_profile_name.."' and enabled = 'true' "; - end - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); - end - x = 0; - dbh:query(sql, function(field) - --set as variables - gateway = field.gateway; - gateway = gateway:gsub(" ", "_"); - - if (domain_count > 1) then - table.insert(xml, [[ ]]); - else - table.insert(xml, [[ ]]); - end - - if (string.len(field.username) > 0) then - table.insert(xml, [[ ]]); - else - table.insert(xml, [[ ]]); - end - if (string.len(field.distinct_to) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.auth_username) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.password) > 0) then - table.insert(xml, [[ ]]); - else - table.insert(xml, [[ ]]); - end - if (string.len(field.realm) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.from_user) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.from_domain) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.proxy) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.register_proxy) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.outbound_proxy) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.expire_seconds) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.register) > 0) then - table.insert(xml, [[ ]]); - end - - if (field.register_transport) then - if (field.register_transport == "udp") then - table.insert(xml, [[ ]]); - elseif (field.register_transport == "tcp") then - table.insert(xml, [[ ]]); - elseif (field.register_transport == "tls") then - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - else - table.insert(xml, [[ ]]); - end - end - - if (string.len(field.retry_seconds) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.extension) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.ping) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.context) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.caller_id_in_from) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.supress_cng) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.sip_cid_type) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(field.extension_in_contact) > 0) then - table.insert(xml, [[ ]]); - end - table.insert(xml, [[ ]]); - end) - - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - profile_tag_status = "open"; - end - - --loop through the var array - for line in (vars.."\n"):gmatch"(.-)\n" do - if (line) then - pos = string.find(line, "=", 0, true); - --name = string.sub( line, 0, pos-1); - --value = string.sub( line, pos+1); - sip_profile_setting_value = sip_profile_setting_value:gsub("%$%${"..string.sub( line, 0, pos-1).."}", string.sub( line, pos+1)); - end - end - - --remove $ and replace with "" - --if (sip_profile_setting_value) then - -- sip_profile_setting_value = sip_profile_setting_value:gsub("%$", ""); - --end - - --set the parameters - if (sip_profile_setting_name) then - table.insert(xml, [[ ]]); - end - - --set the previous value - previous_sip_profile_name = sip_profile_name; - - --increment the value of x - x = x + 1; - end) - - --close the extension tag if it was left open - if (profile_tag_status == "open") then - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - profile_tag_status = "close"; - end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[
]]); - table.insert(xml, [[
]]); - XML_STRING = table.concat(xml, "\n"); - if (debug["xml_string"]) then - freeswitch.consoleLog("notice", "[xml_handler] XML_STRING: " .. XML_STRING .. "\n"); - end - - --set the cache - result = trim(api:execute("memcache", "set configuration:sofia.conf '"..XML_STRING:gsub("'", "'").."' "..expire["sofia.conf"])); - - --send the xml to the console - if (debug["xml_string"]) then - local file = assert(io.open("/tmp/sofia.conf.xml", "w")); - file:write(XML_STRING); - file:close(); - end - - --send to the console - if (debug["cache"]) then - freeswitch.consoleLog("notice", "[xml_handler] configuration:sofia.conf source: database\n"); - end - else - --replace the ' back to a single quote - XML_STRING = XML_STRING:gsub("'", "'"); - - --send to the console - if (debug["cache"]) then - freeswitch.consoleLog("notice", "[xml_handler] configuration:sofia.conf source: memcache\n"); - end - end --if XML_STRING - end --sofia.conf - - --conference.conf - conference controls, and conference profiles - if (XML_REQUEST["key_value"] == "conference.conf") then - - --start the xml array - local xml = {} - table.insert(xml, [[]]); - table.insert(xml, [[]]); - table.insert(xml, [[
]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, ""); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - - --set the xml array and then concatenate the array to a string - table.insert(xml, [[ ]]); - table.insert(xml, [[
]]); - table.insert(xml, [[
]]); - XML_STRING = table.concat(xml, "\n"); - - --send the xml to the console - if (debug["xml_string"]) then - local file = assert(io.open("/tmp/conference.conf.xml", "w")); - file:write(XML_STRING); - file:close(); - end - end --conference.conf - end --section configuration - ---handle the directory - if (XML_REQUEST["section"] == "directory") then - - --set the default - continue = true; - - --get the action - action = params:getHeader("action"); - --sip_auth - registration - --group_call - call group has been called - --user_call - user has been called - - --additional information - --event_calling_function = params:getHeader("Event-Calling-Function"); - - --determine the correction action to perform - if (action == "message-count") then - --Event-Calling-Line-Number: 102 - --Event-Sequence: 4173 - --action: message-count - --key: id - --user: *98 - --domain: example.com - elseif (action == "group_call") then - --handles action - --group_call - - --attempt to use the cache - if (trim(api:execute("module_exists", "mod_memcache")) == "true") then - XML_STRING = trim(api:execute("memcache", "get directory:groups")); - else - XML_STRING = "-ERR NOT FOUND"; - end - if (XML_STRING == "-ERR NOT FOUND") then - --build the call group array - sql = [[ - select * from v_extensions - where domain_uuid = ']]..domain_uuid..[[' - order by call_group asc - ]]; - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); - end - call_group_array = {}; - status = dbh:query(sql, function(row) - call_group = row['call_group']; - --call_group = str_replace(";", ",", call_group); - tmp_array = explode(",", call_group); - for key,value in pairs(tmp_array) do - value = trim(value); - --freeswitch.consoleLog("notice", "[directory] Key: " .. key .. " Value: " .. value .. " " ..row['extension'] .."\n"); - if (string.len(value) == 0) then - --do nothing - else - if (call_group_array[value] == nil) then - call_group_array[value] = row['extension']; - else - call_group_array[value] = call_group_array[value]..','..row['extension']; - end - end - end - end); - --for key,value in pairs(call_group_array) do - -- freeswitch.consoleLog("notice", "[directory] Key: " .. key .. " Value: " .. value .. "\n"); - --end - - --build the xml array - local xml = {} - table.insert(xml, [[]]); - table.insert(xml, [[]]); - table.insert(xml, [[
]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - previous_call_group = ""; - for key, value in pairs(call_group_array) do - call_group = trim(key); - extension_list = trim(value); - if (string.len(call_group) > 0) then - freeswitch.consoleLog("notice", "[directory] call_group: " .. call_group .. "\n"); - freeswitch.consoleLog("notice", "[directory] extension_list: " .. extension_list .. "\n"); - if (previous_call_group ~= call_group) then - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - extension_array = explode(",", extension_list); - for index,tmp_extension in pairs(extension_array) do - table.insert(xml, [[ ]]); - end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - end - previous_call_group = call_group; - end - end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[
]]); - table.insert(xml, [[
]]); - XML_STRING = table.concat(xml, "\n"); - - --set the cache - result = trim(api:execute("memcache", "set directory:groups '"..XML_STRING:gsub("'", "'").."' "..expire["directory"])); - - --send to the console - if (debug["cache"]) then - freeswitch.consoleLog("notice", "[xml_handler] directory:groups source: database\n"); - end - - else - --replace the ' back to a single quote - XML_STRING = XML_STRING:gsub("'", "'"); - - --send to the console - if (debug["cache"]) then - if (XML_STRING) then - freeswitch.consoleLog("notice", "[xml_handler] directory:groups source: memcache\n"); - end - end - end - - --send the xml to the console - if (debug["xml_string"]) then - freeswitch.consoleLog("notice", "[directory] Groups XML_STRING: \n" .. XML_STRING .. "\n"); - end - else - --handle action - --all other directory actions: sip_auth, user_call - --except for the action: group_call - - --get the cache - if (trim(api:execute("module_exists", "mod_memcache")) == "true") then - if (user == nil) then - user = ""; - end - XML_STRING = trim(api:execute("memcache", "get directory:" .. user .. "@" .. domain_name)); - if (XML_STRING == "-ERR NOT FOUND") then - continue = true; - else - continue = false; - end - else - XML_STRING = ""; - continue = true; - end - - --prevent processing for invalid user - if (user == "*97") then - continue = false; - end - - --get the extension from the database - if (continue) then - sql = "SELECT * FROM v_extensions WHERE domain_uuid = '" .. domain_uuid .. "' and extension = '" .. user .. "' and enabled = 'true' "; - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); - end - dbh:query(sql, function(row) - --general - domain_uuid = row.domain_uuid; - extension_uuid = row.extension_uuid; - extension = row.extension; - cidr = ""; - if (string.len(row.cidr) > 0) then - cidr = [[ cidr="]] .. row.cidr .. [["]]; - end - number_alias = ""; - if (string.len(row.number_alias) > 0) then - number_alias = [[ number-alias="]] .. row.number_alias .. [["]]; - end - --params - password = row.password; - vm_enabled = "true"; - if (string.len(row.vm_enabled) > 0) then - vm_enabled = row.vm_enabled; - end - vm_password = row.vm_password; - vm_attach_file = "true"; - if (string.len(row.vm_attach_file) > 0) then - vm_attach_file = row.vm_attach_file; - end - vm_keep_local_after_email = "true"; - if (string.len(row.vm_keep_local_after_email) > 0) then - vm_keep_local_after_email = row.vm_keep_local_after_email; - end - if (string.len(row.vm_mailto) > 0) then - vm_mailto = row.vm_mailto; - else - vm_mailto = ""; - end - mwi_account = row.mwi_account; - auth_acl = row.auth_acl; - --variables - sip_from_user = row.extension; - call_group = row.call_group; - hold_music = row.hold_music; - toll_allow = row.toll_allow; - accountcode = row.accountcode; - user_context = row.user_context; - effective_caller_id_name = row.effective_caller_id_name; - effective_caller_id_number = row.effective_caller_id_number; - outbound_caller_id_name = row.outbound_caller_id_name; - outbound_caller_id_number = row.outbound_caller_id_number; - emergency_caller_id_number = row.emergency_caller_id_number; - directory_full_name = row.directory_full_name; - directory_visible = row.directory_visible; - directory_exten_visible = row.directory_exten_visible; - limit_max = row.limit_max; - limit_destination = row.limit_destination; - sip_force_contact = row.sip_force_contact; - sip_force_expires = row.sip_force_expires; - nibble_account = row.nibble_account; - sip_bypass_media = row.sip_bypass_media; - - --set the dial_string - if (string.len(row.dial_string) > 0) then - dial_string = row.dial_string; - else - dial_string = "{sip_invite_domain=" .. domain_name .. ",presence_id=" .. user .. "@" .. domain_name .. "}${sofia_contact(" .. user .. "@" .. domain_name .. ")}"; - end - end); - end - - --if the extension does not exist set continue to false; - if (extension_uuid == nil) then - continue = false; - end - - --outbound hot desking - get the extension variables - if (continue) then - sql = "SELECT * FROM v_extensions WHERE dial_domain = '" .. domain_name .. "' and dial_user = '" .. user .. "' and enabled = 'true' "; - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); - end - dbh:query(sql, function(row) - --get the values from the database - extension_uuid = row.extension_uuid; - domain_uuid = row.domain_uuid; - sip_from_user = row.extension; - call_group = row.call_group; - hold_music = row.hold_music; - toll_allow = row.toll_allow; - accountcode = row.accountcode; - user_context = row.user_context; - effective_caller_id_name = row.effective_caller_id_name; - effective_caller_id_number = row.effective_caller_id_number; - outbound_caller_id_name = row.outbound_caller_id_name; - outbound_caller_id_number = row.outbound_caller_id_number; - emergency_caller_id_number = row.emergency_caller_id_number; - directory_full_name = row.directory_full_name; - directory_visible = row.directory_visible; - directory_exten_visible = row.directory_exten_visible; - limit_max = row.limit_max; - limit_destination = row.limit_destination; - sip_force_contact = row.sip_force_contact; - sip_force_expires = row.sip_force_expires; - nibble_account = row.nibble_account; - sip_bypass_media = row.sip_bypass_media; - end); - end - - --set the xml array and then concatenate the array to a string - if (continue and password) then - --build the xml - local xml = {} - table.insert(xml, [[]]); - table.insert(xml, [[]]); - table.insert(xml, [[
]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - if (number_alias) then - if (cidr) then - table.insert(xml, [[ ]]); - else - table.insert(xml, [[ ]]); - end - else - if (cidr) then - table.insert(xml, [[ ]]); - else - table.insert(xml, [[ ]]); - end - end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - if (string.len(vm_mailto) > 0) then - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - end - if (string.len(mwi_account) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(auth_acl) > 0) then - table.insert(xml, [[ ]]); - end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - if (string.len(call_group) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(hold_music) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(toll_allow) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(accountcode) > 0) then - table.insert(xml, [[ ]]); - end - table.insert(xml, [[ ]]); - if (string.len(effective_caller_id_name) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(effective_caller_id_number) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(outbound_caller_id_name) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(outbound_caller_id_number) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(emergency_caller_id_number) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(directory_full_name) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(directory_visible) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(directory_exten_visible) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(limit_max) > 0) then - table.insert(xml, [[ ]]); - else - table.insert(xml, [[ ]]); - end - if (string.len(limit_destination) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(sip_force_contact) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(sip_force_expires) > 0) then - table.insert(xml, [[ ]]); - end - if (string.len(nibble_account) > 0) then - table.insert(xml, [[ ]]); - end - if (sip_bypass_media == "bypass-media") then - table.insert(xml, [[ ]]); - end - if (sip_bypass_media == "bypass-media-after-bridge") then - table.insert(xml, [[ ]]); - end - if (sip_bypass_media == "proxy-media") then - table.insert(xml, [[ ]]); - end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[
]]); - table.insert(xml, [[
]]); - XML_STRING = table.concat(xml, "\n"); - - --set the cache - result = trim(api:execute("memcache", "set directory:" .. user .. "@" .. domain_name .. " '"..XML_STRING:gsub("'", "'").."' "..expire["directory"])); - - --send the xml to the console - if (debug["xml_string"]) then - local file = assert(io.open("/tmp/" .. user .. "@" .. domain_name .. ".xml", "w")); - file:write(XML_STRING); - file:close(); - end - - --send to the console - if (debug["cache"]) then - freeswitch.consoleLog("notice", "[xml_handler] directory:" .. user .. "@" .. domain_name .. " source: database\n"); - end - else - --replace the ' back to a single quote - XML_STRING = XML_STRING:gsub("'", "'"); - - --send to the console - if (debug["cache"]) then - if (XML_STRING) then - freeswitch.consoleLog("notice", "[xml_handler] directory:" .. user .. "@" .. domain_name .. " source: memcache \n"); - end - end - end - end --if action - - --if the extension does not exist send "not found" - if (trim(XML_STRING) == "-ERR NOT FOUND" or XML_STRING == nil) then - --send not found - XML_STRING = [[ - -
- -
-
]]; - --set the cache - result = trim(api:execute("memcache", "set directory:" .. user .. "@" .. domain_name .. " '"..XML_STRING:gsub("'", "'").."' "..expire["directory"])); - end - - --send the xml to the console - if (debug["xml_string"]) then - freeswitch.consoleLog("notice", "[xml_handler] XML_STRING: \n" .. XML_STRING .. "\n"); - end - end - ---handle the dialplan - if (XML_REQUEST["section"] == "dialplan") then - if (debug["params"]) then - freeswitch.consoleLog("notice", "[xml_handler] Params:\n" .. params:serialize() .. "\n"); - end - - --get the cache - if (trim(api:execute("module_exists", "mod_memcache")) == "true") then - XML_STRING = trim(api:execute("memcache", "get dialplan:" .. call_context)); - else - XML_STRING = "-ERR NOT FOUND"; - end - if (XML_STRING == "-ERR NOT FOUND") then - --set the xml array and then concatenate the array to a string - local xml = {} - table.insert(xml, [[]]); - table.insert(xml, [[]]); - table.insert(xml, [[
]]); - table.insert(xml, [[ ]]); - - --set defaults - previous_dialplan_uuid = ""; - previous_dialplan_detail_group = ""; - previous_dialplan_detail_tag = ""; - previous_dialplan_detail_type = ""; - previous_dialplan_detail_data = ""; - dialplan_tag_status = "closed"; - condition_tag_status = "closed"; - - --get the dialplan and related details - sql = "select * from v_dialplans as d, v_dialplan_details as s "; - sql = sql .. "where d.dialplan_context = '" .. call_context .. "' "; - sql = sql .. "and d.dialplan_enabled = 'true' "; - sql = sql .. "and d.dialplan_uuid = s.dialplan_uuid "; - --if (call_context ~= "public") then - -- sql = sql .. "and d.domain_uuid = '" .. domain_uuid .. "' "; - --end - sql = sql .. "order by "; - sql = sql .. "d.dialplan_order asc, "; - sql = sql .. "d.dialplan_name asc, "; - sql = sql .. "d.dialplan_uuid asc, "; - sql = sql .. "s.dialplan_detail_group asc, "; - sql = sql .. "CASE s.dialplan_detail_tag "; - sql = sql .. "WHEN 'condition' THEN 1 "; - sql = sql .. "WHEN 'action' THEN 2 "; - sql = sql .. "WHEN 'anti-action' THEN 3 "; - sql = sql .. "ELSE 100 END, "; - sql = sql .. "s.dialplan_detail_order asc "; - if (debug["sql"]) then - freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); - end - x = 0; - dbh:query(sql, function(row) - --get the dialplan - --domain_uuid = row.domain_uuid; - dialplan_uuid = row.dialplan_uuid; - --app_uuid = row.app_uuid; - --dialplan_context = row.dialplan_context; - dialplan_name = row.dialplan_name; - --dialplan_number = row.dialplan_number; - dialplan_continue = row.dialplan_continue; - --dialplan_order = row.dialplan_order; - --dialplan_enabled = row.dialplan_enabled; - --dialplan_description = row.dialplan_description; - --get the dialplan details - --dialplan_detail_uuid = row.dialplan_detail_uuid; - dialplan_detail_tag = row.dialplan_detail_tag; - dialplan_detail_type = row.dialplan_detail_type; - dialplan_detail_data = row.dialplan_detail_data; - dialplan_detail_break = row.dialplan_detail_break; - dialplan_detail_inline = row.dialplan_detail_inline; - dialplan_detail_group = row.dialplan_detail_group; - --dialplan_detail_order = row.dialplan_detail_order; - - --remove $$ and replace with $ - dialplan_detail_data = dialplan_detail_data:gsub("%$%$", "$"); - - --get the dialplan detail inline - detail_inline = ""; - if (dialplan_detail_inline) then - if (string.len(dialplan_detail_inline) > 0) then - detail_inline = [[ inline="]] .. dialplan_detail_inline .. [["]]; - end - end - - --close the tags - if (condition_tag_status ~= "closed") then - if (previous_dialplan_uuid ~= dialplan_uuid) then - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - dialplan_tag_status = "closed"; - condition_tag_status = "closed"; - else - if (previous_dialplan_detail_group ~= dialplan_detail_group and previous_dialplan_detail_tag == "condition") then - table.insert(xml, [[ ]]); - condition_tag_status = "closed"; - end - end - end - - --open the tags - if (dialplan_tag_status == "closed") then - table.insert(xml, [[ ]]); - dialplan_tag_status = "open"; - end - if (dialplan_detail_tag == "condition") then - --determine the type of condition - if (dialplan_detail_type == "hour") then - condition_type = 'time'; - elseif (dialplan_detail_type == "minute") then - condition_type = 'time'; - elseif (dialplan_detail_type == "minute-of-day") then - condition_type = 'time'; - elseif (dialplan_detail_type == "mday") then - condition_type = 'time'; - elseif (dialplan_detail_type == "mweek") then - condition_type = 'time'; - elseif (dialplan_detail_type == "mon") then - condition_type = 'time'; - elseif (dialplan_detail_type == "yday") then - condition_type = 'time'; - elseif (dialplan_detail_type == "year") then - condition_type = 'time'; - elseif (dialplan_detail_type == "wday") then - condition_type = 'time'; - elseif (dialplan_detail_type == "week") then - condition_type = 'time'; - else - condition_type = 'default'; - end - - --get the condition break attribute - condition_break = ""; - if (dialplan_detail_break) then - if (string.len(dialplan_detail_break) > 0) then - condition_break = [[ break="]] .. dialplan_detail_break .. [["]]; - end - end - - if (condition_tag_status == "open") then - if (previous_dialplan_detail_tag == "condition") then - --add the condition self closing tag - if (condition) then - if (string.len(condition) > 0) then - table.insert(xml, condition .. [[/>]]); - end - end - end - if (previous_dialplan_detail_tag == "action" or previous_dialplan_detail_tag == "anti-action") then - table.insert(xml, [[ ]]); - condition_tag_status = "closed"; - condition_type = ""; - condition_attribute = ""; - condition_expression = ""; - end - end - - --condition tag but leave off the ending - if (condition_type == "default") then - condition = [[ ]]); - condition = ""; --prevents duplicate time conditions - end - end - if (dialplan_detail_tag == "action") then - table.insert(xml, [[ ]]); - end - if (dialplan_detail_tag == "anti-action") then - table.insert(xml, [[ ]]); - end - - --save the previous values - previous_dialplan_uuid = dialplan_uuid; - previous_dialplan_detail_group = dialplan_detail_group; - previous_dialplan_detail_tag = dialplan_detail_tag; - previous_dialplan_detail_type = dialplan_detail_type; - previous_dialplan_detail_data = dialplan_detail_data; - - --increment the x - x = x + 1; - end); - - --close the extension tag if it was left open - if (dialplan_tag_status == "open") then - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - end - - --set the xml array and then concatenate the array to a string - table.insert(xml, [[ ]]); - table.insert(xml, [[
]]); - table.insert(xml, [[
]]); - XML_STRING = table.concat(xml, "\n"); - - --set the cache - tmp = XML_STRING:gsub("\\", "\\\\"); - result = trim(api:execute("memcache", "set dialplan:" .. call_context .. " '"..tmp:gsub("'", "'").."' "..expire["dialplan"])); - - --send the xml to the console - if (debug["xml_string"]) then - local file = assert(io.open("/tmp/dialplan-" .. call_context .. ".xml", "w")); - file:write(XML_STRING); - file:close(); - end - - --send to the console - if (debug["cache"]) then - freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: database\n"); - end - else - --replace the ' back to a single quote - XML_STRING = XML_STRING:gsub("'", "'"); - - --send to the console - if (debug["cache"]) then - freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: memcache\n"); - end - end - end - ---send debug info to the console - if (debug["xml_request"]) then - freeswitch.consoleLog("notice", "[xml_handler] Section: " .. XML_REQUEST["section"] .. "\n"); - freeswitch.consoleLog("notice", "[xml_handler] Tag Name: " .. XML_REQUEST["tag_name"] .. "\n"); - freeswitch.consoleLog("notice", "[xml_handler] Key Name: " .. XML_REQUEST["key_name"] .. "\n"); - freeswitch.consoleLog("notice", "[xml_handler] Key Value: " .. XML_REQUEST["key_value"] .. "\n"); - end - ---close the database connection - dbh:release();