diff --git a/app/calls/app_languages.php b/app/calls/app_languages.php index 9829a26cee..9f41a6f14c 100644 --- a/app/calls/app_languages.php +++ b/app/calls/app_languages.php @@ -11,7 +11,7 @@ $text['description']['fr-fr'] = "Rediriger les appels entrant pour l'extension:"; $text['description-2']['en-us'] = "Use the links to configure call forward follow me, or do not disturb."; - $text['descriptionA-2']['es-cl'] = "Utilice los links para configurar reenvio de llamada, sígueme o no Molestar."; + $text['description-2']['es-cl'] = "Utilice los links para configurar reenvio de llamada, sígueme o no Molestar."; $text['description-2']['pt-pt'] = "Utilizar os links para definir as funcinalidades de encaminhamento de chamada, seguimento ou de não perturbar."; $text['description-2']['fr-fr'] = "Utiliser les liens afin de configurer le renvoi \"follow me\", ou ne pas déranger."; @@ -25,6 +25,9 @@ $text['label-call-forward']['pt-pt'] = "Encaminhamento de Chamadas"; $text['label-call-forward']['fr-fr'] = "Renvoi d'appel"; + $text['label-forward-busy']['en-us'] = "Forward on busy"; + $text['label-forward-busy']['it-it'] = "Rinvio su occupato"; + $text['label-enabled']['en-us'] = "Enabled"; $text['label-enabled']['es-cl'] = "Activo"; $text['label-enabled']['pt-pt'] = "Activo"; diff --git a/app/calls/call_edit.php b/app/calls/call_edit.php index 50fd52acec..df67500ee4 100644 --- a/app/calls/call_edit.php +++ b/app/calls/call_edit.php @@ -116,6 +116,8 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { if (count($_POST)>0) { $forward_all_enabled = check_str($_POST["forward_all_enabled"]); $forward_all_destination = check_str($_POST["forward_all_destination"]); + $forward_busy_enabled = check_str($_POST["forward_busy_enabled"]); + $forward_busy_destination = check_str($_POST["forward_busy_destination"]); $cid_name_prefix = check_str($_POST["cid_name_prefix"]); $cid_number_prefix = check_str($_POST["cid_number_prefix"]); $follow_me_enabled = check_str($_POST["follow_me_enabled"]); @@ -150,6 +152,9 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { if (strlen($forward_all_destination) > 0) { // $forward_all_destination = preg_replace("~[^0-9]~", "",$forward_all_destination); } + if (strlen($forward_busy_destination) > 0) { + // $forward_busy_destination = preg_replace("~[^0-9*]~", "",$forward_busy_destination); + } if (strlen($destination_data_1) > 0) { // $destination_data_1 = preg_replace("~[^0-9]~", "",$destination_data_1); } @@ -345,6 +350,15 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { unset($ext); } + // Forward on busy is stored in table and will be used by lua scripts + $sql = "update v_extensions set "; + $sql .= "forward_busy_destination = '$forward_busy_destination', "; + $sql .= "forward_busy_enabled = '$forward_busy_enabled' "; + $sql .= "where domain_uuid = '$domain_uuid' "; + $sql .= "and extension_uuid = '$extension_uuid'"; + $db->exec(check_sql($sql)); + unset($sql); + //delete extension from memcache $fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']); if ($fp) { @@ -531,6 +545,47 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { echo "\n"; echo "\n"; + /* BUSY handling */ + echo "\n"; + echo "\n"; + echo " ".$text['label-forward-busy'].":\n"; + echo "\n"; + echo "\n"; + $on_click = "document.getElementById('dnd_enabled').checked=false;"; + $on_click .= "document.getElementById('dnd_disabled').checked=true;"; + if ($forward_busy_enabled == "true") { + echo " ".$text['label-enabled']." \n"; + } + else { + echo " ".$text['label-enable']." \n"; + } + if ($forward_busy_enabled == "false" || $forward_busy_enabled == "") { + echo " ".$text['label-disabled']." \n"; + } + else { + echo " ".$text['label-disable']." \n"; + } + unset($on_click); + echo "
\n"; + echo "\n"; + echo "\n"; + + echo "\n"; + echo "\n"; + echo " ".$text['label-number'].":\n"; + echo "\n"; + echo "\n"; + echo " \n"; + echo "
\n"; + echo "\n"; + echo "\n"; + + echo "\n"; + echo "\n"; + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; echo "\n"; echo " ".$text['label-follow-me'].":\n"; @@ -719,6 +774,8 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { $on_click .= "document.getElementById('forward_all_disabled').checked=true;"; $on_click .= "document.getElementById('follow_me_enabled').checked=true;"; $on_click .= "document.getElementById('follow_me_disabled').checked=true;"; + $on_click .= "document.getElementById('forward_busy_enabled').checked=true;"; + $on_click .= "document.getElementById('forward_busy_disabled').checked=true;"; if ($dnd_enabled == "true") { echo " ".$text['label-enabled']." \n"; } diff --git a/app/calls/calls.php b/app/calls/calls.php index f8777e1b84..c575e0d37e 100644 --- a/app/calls/calls.php +++ b/app/calls/calls.php @@ -155,6 +155,7 @@ else { echo " ".$row['extension']."\n"; echo " \n"; if (permission_exists('call_forward')) { echo "".$text['label-call-forward']."   "; } + if (permission_exists('call_forward')) { echo "".$text['label-forward-busy']."   "; } if (permission_exists('follow_me')) { echo "".$text['label-follow-me']."   "; } if (permission_exists('do_not_disturb')) { echo "".$text['label-dnd'].""; } echo " \n"; diff --git a/app/calls/resources/classes/follow_me.php b/app/calls/resources/classes/follow_me.php index 690e2440a9..b84d397523 100644 --- a/app/calls/resources/classes/follow_me.php +++ b/app/calls/resources/classes/follow_me.php @@ -23,6 +23,8 @@ Contributor(s): Mark J Crane Luis Daniel Lucio Quiroz + Salvatore Caruso + Riccardo Granchi */ include "root.php"; @@ -312,7 +314,8 @@ include "root.php"; $prep_statement_2 = $db->prepare(check_sql($sql)); $prep_statement_2->execute(); $result = $prep_statement_2->fetchAll(PDO::FETCH_NAMED); - $dial_string = "{instant_ringback=true"; + $dial_string = "{fail_on_single_reject=USER_BUSY"; + $dial_string .= ",instant_ringback=true"; $dial_string .= ",ignore_early_media=true,"; $dial_string .= ",domain_uuid=".$_SESSION['domain_uuid']; $dial_string .= ",sip_invite_domain=".$_SESSION['domain_name']; diff --git a/app/dialplan/resources/switch/conf/dialplan/001_extension_queue.xml b/app/dialplan/resources/switch/conf/dialplan/001_extension_queue.xml new file mode 100644 index 0000000000..a1cab5d5fb --- /dev/null +++ b/app/dialplan/resources/switch/conf/dialplan/001_extension_queue.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/resources/install/scripts/app.lua b/resources/install/scripts/app.lua index 39dd56308d..a1cd6f336f 100644 --- a/resources/install/scripts/app.lua +++ b/resources/install/scripts/app.lua @@ -22,17 +22,25 @@ -- 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. - +-- +-- Contributor(s): +-- Salvatore Caruso +-- Riccardo Granchi --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/functions/config.lua"); + dofile(scripts_dir.."/resources/functions/explode.lua"); dofile(config()); --get the argv values script_name = argv[0]; app_name = argv[1]; +-- variables + forward_on_busy = false; + send_to_voicemail = false; + --example use command --luarun app.lua app_name 'a' 'b 123' 'c' @@ -45,7 +53,38 @@ end end ---route the request to the application - --freeswitch.consoleLog("notice", "["..app_name.."]".. scripts_dir .. "/app/" .. app_name .. "/index.lua\n"); - loadfile(scripts_dir .. "/app/" .. app_name .. "/index.lua")(argv); + if (session ~= nil) then + originate_disposition = session:getVariable("originate_disposition"); + originate_causes = session:getVariable("originate_causes"); + if (originate_causes ~= nil) then + array = explode("|",originate_causes); + if string.find(array[1], "USER_BUSY") then + originate_disposition = "USER_BUSY"; + session:setVariable("originate_disposition", originate_disposition); + end + end + + if( originate_disposition ~= nil ) then + + send_to_voicemail = session:getVariable("send_to_voicemail"); + + if( originate_disposition=='USER_BUSY' and not send_to_voicemail ) then + freeswitch.consoleLog("notice", "[app] forward on busy: ".. scripts_dir .. "/app/forward_on_busy/index.lua" .. arguments .."\n"); + + forward_on_busy = loadfile(scripts_dir .. "/app/forward_on_busy/index.lua")(argv); + + freeswitch.consoleLog("notice", "[app] forward on busy: ".. tostring(forward_on_busy) .. "\n"); + end + end + end + + if( originate_disposition == "SUBSCRIBER_ABSENT" ) then + --return 404 UNALLOCATED_NUMBER if extension doesn't exist + freeswitch.consoleLog("notice", "[app] lua route: ".. scripts_dir .. "/app/" .. app_name .. "/index.lua" .. arguments ..". HANGUP.\n"); + session:hangup("UNALLOCATED_NUMBER"); + elseif( not forward_on_busy and originate_disposition ~= "CALL_REJECTED" ) then + --route the request to the application + freeswitch.consoleLog("notice", "[app] lua route: ".. scripts_dir .. "/app/" .. app_name .. "/index.lua" .. arguments .."\n"); + loadfile(scripts_dir .. "/app/" .. app_name .. "/index.lua")(argv); + end diff --git a/resources/install/scripts/app/forward_on_busy/index.lua b/resources/install/scripts/app/forward_on_busy/index.lua new file mode 100644 index 0000000000..cfc5f28063 --- /dev/null +++ b/resources/install/scripts/app/forward_on_busy/index.lua @@ -0,0 +1,108 @@ +-- +-- 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-2014 +-- the Initial Developer. All Rights Reserved. +-- +-- Contributor(s): +-- Salvatore Caruso +-- Riccardo Granchi + +--set default values + forward = false; + +--debug + debug["info"] = false; + debug["sql"] = false; + +--connect to the database + dofile(scripts_dir.."/resources/functions/database_handle.lua"); + dbh = database_handle('system'); + + if (session ~= nil) then + originate_disposition = session:getVariable("originate_disposition"); + + if( originate_disposition=='USER_BUSY' ) then + + dialed_extension = session:getVariable("dialed_extension"); + context = session:getVariable("context"); + domain_name = session:getVariable("domain_name"); + uuid = session:getVariable("uuid"); + + --get the domain_uuid + domain_uuid = session:getVariable("domain_uuid"); + if (domain_uuid == nil) then + --get the domain_uuid using the domain name required for multi-tenant + 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", "[forward_on_busy] SQL: " .. sql .. "\n"); + end + status = dbh:query(sql, function(rows) + domain_uuid = rows["domain_uuid"]; + end); + end + end + domain_uuid = string.lower(domain_uuid); + + if( debug["info"] ) then + freeswitch.consoleLog("info", "[forward_on_busy] originate_disposition: " .. originate_disposition .. "\n"); + freeswitch.consoleLog("info", "[forward_on_busy] dialed_extension : " .. dialed_extension .. "\n"); + end + + if (dialed_extension ~= nil) then + if (session:ready()) then + + --get the information from the database + sql = [[SELECT * FROM v_extensions + WHERE domain_uuid = ']] .. domain_uuid ..[[' + AND extension = ']] .. dialed_extension ..[[' + AND forward_busy_enabled = 'true' ]]; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[forward_on_busy] SQL: " .. sql .. "\n"); + end + status = dbh:query(sql, function(row) + forward_busy_destination = string.lower(row["forward_busy_destination"]); + end); + + --set default values + if (forward_busy_destination ~= nil and string.len(forward_busy_destination)>0 ) then + if( debug["info"] ) then + freeswitch.consoleLog("notice", "[forward_on_busy] forward_busy_destination: " .. forward_busy_destination .. "\n"); + end + + session:transfer(forward_busy_destination, "XML", context); + forward = true; + else + if( debug["info"] ) then + freeswitch.consoleLog("notice", "[forward_on_busy] forward on busy disabled or destination unsetted - HANGUP WITH USER BUSY \n"); + end + + session:hangup("USER_BUSY"); + forward = false; + end + end + end + end + end + + --close the database connection + dbh:release(); + + return forward; diff --git a/resources/install/scripts/extension_queue.lua b/resources/install/scripts/extension_queue.lua new file mode 100644 index 0000000000..db83c14017 --- /dev/null +++ b/resources/install/scripts/extension_queue.lua @@ -0,0 +1,77 @@ +-- +-- 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-2014 +-- the Initial Developer. All Rights Reserved. +-- +-- Contributor(s): +-- Salvatore Caruso +-- Riccardo Granchi + +--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/functions/config.lua"); + dofile(config()); + +--connect to the database + dofile(scripts_dir.."/resources/functions/database_handle.lua"); + dbh = database_handle('system'); + +if (session:ready()) then + fifo_simo = session:getVariable("fifo_simo"); + if (not fifo_simo) then fifo_simo = '1'; end + fifo_timeout = session:getVariable("fifo_timeout"); + if (not fifo_timeout) then fifo_timeout = '10'; end + fifo_lag = session:getVariable("fifo_lag"); + if (not fifo_lag) then fifo_lag = '10'; end + + extension_queue = session:getVariable("extension_queue"); + extension = string.sub(extension_queue, string.len("queue_") + 1 ); + + -- freeswitch.consoleLog("notice", "Extension Queue [" .. extension_queue .. "]\n"); + + api = freeswitch.API(); + fifo_count = api:executeString("fifo count " .. extension_queue); + + -- freeswitch.consoleLog("notice", "fifo count " .. fifo_count .. "]\n"); + + -- Parsing queue info + i = 0; + v = {}; + for w in string.gmatch(fifo_count,"[^:]+") do + v[i] = w; + i = i + 1; + end + + fifo_name = v[0]; + consumer_count = v[1]; + caller_count = v[2]; + member_count = v[3]; + ring_consumer_count = v[4]; + idle_consumer_count = v[5]; + + if( not (member_count == "0") ) then + freeswitch.consoleLog("notice", "Adding member [" .. extension .. "] to fifo " .. extension_queue .. " \n"); + + session:execute("set", "fifo_member_add_result=${fifo_member(add " .. extension_queue .." {fifo_member_wait=nowait}user/" .. extension .. " " ..fifo_simo .. " " ..fifo_timeout .. " " .. fifo_lag .. "} )"); --simo timeout lag + end; + + -- Answerinf the call + session:answer(); + session:execute( "fifo", extension_queue .. " in" ); +end