-- -- FusionPBX -- Version: MPL 1.1 -- -- The contents of this file are subject to the Mozilla Public License Version -- 1.1 (the "License"); you may not use this file except in compliance with -- the License. You may obtain a copy of the License at -- http://www.mozilla.org/MPL/ -- -- Software distributed under the License is distributed on an "AS IS" basis, -- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -- for the specific language governing rights and limitations under the -- License. -- -- The Original Code is FusionPBX -- -- The Initial Developer of the Original Code is -- Mark J Crane -- Copyright (C) 2010 -- the Initial Developer. All Rights Reserved. -- -- Contributor(s): -- Mark J Crane -- Luis Daniel Lucio Quiroz --include config.lua require "resources.functions.config"; --connect to the database local Database = require "resources.functions.database"; dbh = Database.new('system'); --include json library local json if (debug["sql"]) then json = require "resources.functions.lunajson" end api = freeswitch.API(); --other libs require "resources.functions.trim"; aleg_number = argv[1]; bleg_number = argv[2]; context = argv[3]; accountcode = argv[4]; t_started = os.time(); local sql = "SELECT domain_uuid FROM v_domains WHERE domain_name=:context"; local params = {context = context}; if (debug["sql"]) then freeswitch.consoleLog("debug", "[disa.callback] SQL: "..sql.."; params: " .. json.encode(params) .. "\n"); end dbh:query(sql, params, function(row) domain_uuid = row.domain_uuid; end); cmd = "user_exists id ".. aleg_number .." "..context; a_user_exists = trim(api:executeString(cmd)); freeswitch.consoleLog("notice", "[disa] a_user_exists "..a_user_exists.."\n"); --Lets build correct dialstring if (a_user_exists == "true") then cmd = "user_data ".. aleg_number .."@"..context.." var extension_uuid"; extension_uuid = trim(api:executeString(cmd)); a_dialstring = "[origination_caller_id_number=*3472,outbound_caller_id_number=*3472,call_timeout=30,context="..context..",sip_invite_domain="..context..",domain_name="..context..",domain="..context..",accountcode="..accountcode..",domain_uuid="..domain_uuid.."]user/"..aleg_number.."@"..context; else local sql = [[select * from v_dialplans as d, v_dialplan_details as s where (d.domain_uuid = :domain_uuid or d.domain_uuid is null) and d.app_uuid = '8c914ec3-9fc0-8ab5-4cda-6c9288bdc9a3' and d.dialplan_enabled = 'true' and d.dialplan_uuid = s.dialplan_uuid order by d.dialplan_order asc, d.dialplan_name asc, d.dialplan_uuid asc, s.dialplan_detail_group asc, CASE s.dialplan_detail_tag WHEN 'condition' THEN 1 WHEN 'action' THEN 2 WHEN 'anti-action' THEN 3 ELSE 100 END, s.dialplan_detail_order asc ]] local params = {domain_uuid = domain_uuid}; if (debug["sql"]) then freeswitch.consoleLog("notice", "[disa ] sql for dialplans:" .. sql .. "; params: " .. json.encode(params) .. "\n"); end dialplans = {}; x = 1; dbh:query(sql, params, function(row) dialplans[x] = row; x = x + 1; end); y = 0; previous_dialplan_uuid = ''; for k, r in pairs(dialplans) do if (y > 0) then if (previous_dialplan_uuid ~= r.dialplan_uuid) then regex_match = false; bridge_match = false; square = square .. "]"; y = 0; end end if (r.dialplan_detail_tag == "condition") then if (r.dialplan_detail_type == "destination_number") then if (api:execute("regex", "m:~"..aleg_number.."~"..r.dialplan_detail_data) == "true") then --get the regex result destination_result = trim(api:execute("regex", "m:~"..aleg_number.."~"..r.dialplan_detail_data.."~$1")); regex_match = true end end end if (r.dialplan_detail_tag == "action") then if (regex_match) then --replace $1 dialplan_detail_data = r.dialplan_detail_data:gsub("$1", destination_result); --if the session is set then process the actions if (y == 0) then square = "[direction=outbound,origination_caller_id_number="..bleg_number..",outbound_caller_id_number="..bleg_number..",call_timeout=30,context="..context..",sip_invite_domain="..context..",domain_name="..context..",domain="..context..",accountcode="..accountcode..",domain_uuid="..domain_uuid..","; end if (r.dialplan_detail_type == "set") then if (dialplan_detail_data == "sip_h_X-accountcode=${accountcode}") then square = square .. "sip_h_X-accountcode="..accountcode..","; elseif (dialplan_detail_data == "effective_caller_id_name=${outbound_caller_id_name}") then elseif (dialplan_detail_data == "effective_caller_id_number=${outbound_caller_id_number}") then else square = square .. dialplan_detail_data..","; end elseif (r.dialplan_detail_type == "bridge") then if (bridge_match) then dial_string = dial_string .. "," .. square .."]"..dialplan_detail_data; square = "["; else dial_string = square .."]"..dialplan_detail_data; end bridge_match = true; end y = y + 1; end end previous_dialplan_uuid = r.dialplan_uuid; end --end for a_dialstring = dial_string; end freeswitch.consoleLog("info", "[disa.callback] a_dialstring " .. a_dialstring .. "\n"); session1 = freeswitch.Session(a_dialstring); session1:execute("export", "domain_uuid="..domain_uuid); freeswitch.consoleLog("info", "[disa.callback] calling " .. aleg_number .. "\n"); freeswitch.msleep(2000); while (session1:ready() and not session1:answered()) do if os.time() > t_started + 30 then freeswitch.consoleLog("info", "[disa.callback] timed out for " .. aleg_number .. "\n"); session1:hangup(); else freeswitch.consoleLog("info", "[disa.callback] session is not yet answered for " .. aleg_number .. "\n"); freeswitch.msleep(500); end end if session1:ready() and session1:answered() then session1:answer( ); freeswitch.consoleLog("info", "[disa.callback] calling " .. bleg_number .. "\n"); t_started2 = os.date(); cmd = "user_exists id ".. bleg_number .." "..context; b_user_exists = trim(api:executeString(cmd)); freeswitch.consoleLog("notice", "[disa] b_user_exists "..b_user_exists.."\n"); --Lets build correct dialstring if (b_user_exists == "true") then cmd = "user_data ".. bleg_number .."@"..context.." var extension_uuid"; extension_uuid = trim(api:executeString(cmd)); b_dialstring = "[origination_caller_id_number=*3472,outbound_caller_id_number=*3472,call_timeout=30,context="..context..",sip_invite_domain="..context..",domain_name="..context..",domain="..context..",accountcode="..accountcode..",domain_uuid="..domain_uuid.."]user/"..bleg_number.."@"..context; else local sql = [[select * from v_dialplans as d, v_dialplan_details as s where (d.domain_uuid = :domain_uuid or d.domain_uuid is null) and d.app_uuid = '8c914ec3-9fc0-8ab5-4cda-6c9288bdc9a3' and d.dialplan_enabled = 'true' and d.dialplan_uuid = s.dialplan_uuid order by d.dialplan_order asc, d.dialplan_name asc, d.dialplan_uuid asc, s.dialplan_detail_group asc, CASE s.dialplan_detail_tag WHEN 'condition' THEN 1 WHEN 'action' THEN 2 WHEN 'anti-action' THEN 3 ELSE 100 END, s.dialplan_detail_order asc ]] local params = {domain_uuid = domain_uuid}; if (debug["sql"]) then freeswitch.consoleLog("notice", "[disa ] sql for dialplans:" .. sql .. "; params: " .. json.encode(params) .. "\n"); end dialplans = {}; x = 1; dbh:query(sql, params, function(row) dialplans[x] = row; x = x + 1; end); y = 0; previous_dialplan_uuid = ''; for k, r in pairs(dialplans) do if (y > 0) then if (previous_dialplan_uuid ~= r.dialplan_uuid) then regex_match = false; bridge_match = false; square = square .. "]"; y = 0; end end if (r.dialplan_detail_tag == "condition") then if (r.dialplan_detail_type == "destination_number") then if (api:execute("regex", "m:~"..bleg_number.."~"..r.dialplan_detail_data) == "true") then --get the regex result destination_result = trim(api:execute("regex", "m:~"..bleg_number.."~"..r.dialplan_detail_data.."~$1")); regex_match = true end end end if (r.dialplan_detail_tag == "action") then if (regex_match) then --replace $1 dialplan_detail_data = r.dialplan_detail_data:gsub("$1", destination_result); --if the session is set then process the actions if (y == 0) then square = "[direction=outbound,origination_caller_id_number="..aleg_number..",outbound_caller_id_number="..aleg_number..",call_timeout=30,context="..context..",sip_invite_domain="..context..",domain_name="..context..",domain="..context..",accountcode="..accountcode..",domain_uuid="..domain_uuid..","; end if (r.dialplan_detail_type == "set") then if (dialplan_detail_data == "sip_h_X-accountcode=${accountcode}") then square = square .. "sip_h_X-accountcode="..accountcode..","; elseif (dialplan_detail_data == "effective_caller_id_name=${outbound_caller_id_name}") then elseif (dialplan_detail_data == "effective_caller_id_number=${outbound_caller_id_number}") then else square = square .. dialplan_detail_data..","; end elseif (r.dialplan_detail_type == "bridge") then if (bridge_match) then dial_string = dial_string .. "," .. square .."]"..dialplan_detail_data; square = "["; else dial_string = square .."]"..dialplan_detail_data; end bridge_match = true; end y = y + 1; end end previous_dialplan_uuid = r.dialplan_uuid; end --end for b_dialstring = dial_string; end freeswitch.consoleLog("info", "[disa.callback] b_dialstring " .. b_dialstring .. "\n"); session2 = freeswitch.Session(b_dialstring); while (session2:ready() and not session2:answered()) do if os.time() > t_started2 + 30 then freeswitch.consoleLog("info", "[disa.callback] timed out for " .. bleg_number .. "\n"); session2:hangup(); else freeswitch.consoleLog("debug", "[disa.callback] session is not yet answered for " .. bleg_number .. "\n"); freeswitch.msleep(500); end end freeswitch.bridge(session1, session2); else freeswitch.consoleLog("info", "[disa.callback] session is not functional for " .. aleg_number .. "\n"); session1:hangup(); end