diff --git a/app/calls/call_edit.php b/app/calls/call_edit.php index d60120e1c2..a8e8b34847 100644 --- a/app/calls/call_edit.php +++ b/app/calls/call_edit.php @@ -326,6 +326,40 @@ } } + //send feature event notify to the phone + if ($_SESSION['device']['feature_sync']['boolean'] == "true") { + $ring_count = ceil($call_timeout / 6); + $feature_event_notify = new feature_event_notify; + $feature_event_notify->domain_name = $_SESSION['domain_name']; + $feature_event_notify->extension = $extension; + $feature_event_notify->do_not_disturb = $dnd_enabled; + $feature_event_notify->ring_count = $ring_count; + $feature_event_notify->forward_all_enabled = $forward_all_enabled; + $feature_event_notify->forward_busy_enabled = $forward_busy_enabled; + $feature_event_notify->forward_no_answer_enabled = $forward_no_answer_enabled; + //workaround for freeswitch not sending NOTIFY when destination values are nil. Send 0. + if ($forward_all_destination == "") { + $feature_event_notify->forward_all_destination = "0"; + } else { + $feature_event_notify->forward_all_destination = $forward_all_destination; + } + + if ($forward_busy_destination == "") { + $feature_event_notify->forward_busy_destination = "0"; + } else { + $feature_event_notify->forward_busy_destination = $forward_busy_destination; + } + + if ($forward_no_answer_destination == "") { + $feature_event_notify->forward_no_answer_destination = "0"; + } else { + $feature_event_notify->forward_no_answer_destination = $forward_no_answer_destination; + } + + $feature_event_notify->send_notify(); + unset($feature_event_notify); + } + //synchronize configuration if (is_readable($_SESSION['switch']['extensions']['dir'])) { require_once "app/extensions/resources/classes/extension.php"; diff --git a/app/calls/resources/classes/feature_event_notify.php b/app/calls/resources/classes/feature_event_notify.php new file mode 100644 index 0000000000..28e0791011 --- /dev/null +++ b/app/calls/resources/classes/feature_event_notify.php @@ -0,0 +1,82 @@ + + Portions created by the Initial Developer are Copyright (C) 2008-2017 + the Initial Developer. All Rights Reserved. + + Contributor(s): + Mark J Crane + KonradSC +*/ +include "root.php"; + +//define the feature_event_notify class + class feature_event_notify { + + public $debug; + public $domain_name; + public $extension; + public $forward_all_destination; + public $forward_all_enabled; + public $forward_busy_destination; + public $forward_busy_enabled; + public $forward_no_answer_destination; + public $forward_no_answer_enabled; + public $do_not_disturb; + public $ring_count; + + //feature_event method + public function send_notify() { + + $fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']); + if ($fp) { + //get the sip profile name + $command = "sofia_contact */".$this->extension."@".$this->domain_name; + $contact_string = event_socket_request($fp, "api ".$command); + if (substr($contact_string, 0, 5) == "sofia") { + $contact_array = explode("/", $contact_string); + $sip_profile_name = $contact_array[1]; + } + else { + $sip_profile_name = 'internal'; + } + //send the event + $event = "sendevent SWITCH_EVENT_PHONE_FEATURE\n"; + $event .= "profile: ".$sip_profile_name."\n"; + $event .= "user: ".$this->extension."\n"; + $event .= "host: ".$this->domain_name."\n"; + $event .= "device: \n"; + $event .= "Feature-Event: init\n"; + $event .= "forward_immediate_enabled: ".$this->forward_all_enabled."\n"; + $event .= "forward_immediate: ".$this->forward_all_destination."\n"; + $event .= "forward_busy_enabled: ".$this->forward_busy_enabled."\n"; + $event .= "forward_busy: ".$this->forward_busy_destination."\n"; + $event .= "forward_no_answer_enabled: ".$this->forward_no_answer_enabled."\n"; + $event .= "forward_no_answer: ".$this->forward_no_answer_destination."\n"; + $event .= "doNotDisturbOn: ".$this->do_not_disturb."\n"; + $event .= "ringCount: ".$this->ring_count."\n"; + event_socket_request($fp, $event); + + fclose($fp); + } + } //function + + } //class + +?> diff --git a/resources/install/scripts/app/feature_event/index.lua b/resources/install/scripts/app/feature_event/index.lua new file mode 100644 index 0000000000..d0d38d3930 --- /dev/null +++ b/resources/install/scripts/app/feature_event/index.lua @@ -0,0 +1,454 @@ +-- +-- event_notify +-- 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 - event_notify +-- +-- The Initial Developer of the Original Code is +-- Mark J Crane +-- Copyright (C) 2013 - 2014 +-- the Initial Developer. All Rights Reserved. +-- +-- Contributor(s): +-- Mark J Crane +-- KonradSC + +-- Start the script + -- /etc/freeswitch/autoload_configs/lua.conf.xml + -- + -- + +--Enable Feature Sync + -- Default Settings: + -- Device -> feature_sync = true + + --Yealink + -- Web Interface -> Features -> General Information -> Feature Key Synchronization set to Enabled + -- Config Files -> bw.feature_key_sync = 1 + --Polycom + -- reg.{$row.line_number}.serverFeatureControl.cf="1" + -- reg.{$row.line_number}.serverFeatureControl.dnd="1" + -- Cisco SPA + -- Yes + +--prepare the api object + api = freeswitch.API(); + +--define the functions + require "resources.functions.trim"; + require "resources.functions.explode"; + +--connect to the database + local Database = require "resources.functions.database"; + local Settings = require "resources.functions.lazy_settings" + local route_to_bridge = require "resources.functions.route_to_bridge" + local blf = require "resources.functions.blf" + local cache = require "resources.functions.cache" + local notify = require "app.feature_event.resources.functions.feature_event_notify" + dbh = Database.new('system'); + local settings = Settings.new(dbh, domain_name, domain_uuid); + +--set debug + debug["sql"] = true; + +--include json library + local json + if (debug["sql"]) then + json = require "resources.functions.lunajson" + end + + local function empty(t) + return (not t) or (#t == 0) + end + +--get the events + --if (user == nil) then + --serialize the data for the console + --freeswitch.consoleLog("notice","[events] " .. event:serialize("xml") .. "\n"); + --freeswitch.consoleLog("notice","[evnts] " .. event:serialize("json") .. "\n"); + + --get the event variables + user = event:getHeader("user"); + host = event:getHeader("host"); + domain_name = event:getHeader("host"); + contact = event:getHeader("contact"); + feature_action = event:getHeader("Feature-Action"); + feature_enabled = event:getHeader("Feature-Enabled"); + action_name = event:getHeader("Action-Name"); + action_value = event:getHeader("Action-Value") + ring_count = event:getHeader("ringCount") + + --send to the log + --freeswitch.consoleLog("notice","[events] user: " .. user .. "\n"); + --freeswitch.consoleLog("notice","[events] host: " .. host .. "\n"); + --if (feature_action ~= nil) then freeswitch.consoleLog("notice","[events] feature_action: " .. feature_action .. "\n"); end + --if (feature_enabled ~= nil) then freeswitch.consoleLog("notice","[events] feature_enabled: " .. feature_enabled .. "\n"); end + --if (action_name ~= nil) then freeswitch.consoleLog("notice","[events] action_name: " .. action_name .. "\n"); end + --if (action_value ~= nil) then freeswitch.consoleLog("notice","[events] action_value: " .. action_value .. "\n"); end + --end + + --get the domain uuid from the host + local sql = "select * from v_domains "; + sql = sql .. "where domain_name = :domain_name "; + local params = {domain_name = domain_name}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] " .. sql .. "; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params, function(row) + domain_uuid = row.domain_uuid; + end); + + --get extension information + if (user ~= nil and domain_name ~= nil) then + do_not_disturb, forward_all_enabled, forward_all_destination, forward_busy_enabled, forward_busy_destination, forward_no_answer_enabled, forward_no_answer_destination, call_timeout = notify.get_db_values(user, domain_name) + end + + --get sip profile + if (user ~= nil and host ~= nil) then + sip_profile = notify.get_profile(user, host); + end + + --DND + + --DND enabled + if (feature_action == "SetDoNotDisturb" and feature_enabled == "true" and sip_profile ~= nil) then + --set a variable + dial_string = "error/user_busy"; + do_not_disturb = "true"; + --update the extension + sql = "update v_extensions set "; + sql = sql .. "do_not_disturb = :do_not_disturb, "; + sql = sql .. "forward_all_enabled = 'false', "; + sql = sql .. "dial_string = :dial_string "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and extension_uuid = :extension_uuid "; + local params = {domain_uuid = domain_uuid, extension_uuid = extension_uuid, do_not_disturb = do_not_disturb, dial_string = dial_string}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + + --update follow me + if (follow_me_uuid ~= nil) then + if (string.len(follow_me_uuid) > 0) then + local sql = "update v_follow_me set "; + sql = sql .. "follow_me_enabled = 'false' "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and follow_me_uuid = :follow_me_uuid "; + local params = {domain_uuid = domain_uuid, follow_me_uuid = follow_me_uuid}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + end + end + + --send notify to the phone + notify.dnd(user, host, sip_profile, do_not_disturb); + + end + + --DND disabled + if (feature_action == "SetDoNotDisturb" and feature_enabled == "false" and sip_profile ~= nil ) then + --set a variable + do_not_disturb = "false"; + --update the extension + sql = "update v_extensions set "; + sql = sql .. "do_not_disturb = :do_not_disturb, "; + sql = sql .. "forward_all_enabled = 'false', "; + sql = sql .. "dial_string = null "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and extension_uuid = :extension_uuid "; + local params = {domain_uuid = domain_uuid, extension_uuid = extension_uuid, do_not_disturb = do_not_disturb}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + + --send notify to the phone + notify.dnd(user, host, sip_profile, do_not_disturb); + + end + + --Call Forward + + --Call Formward All enabled + if (feature_action == "SetCallForward" and feature_enabled == "true" and action_name == "forward_immediate" and sip_profile ~= nil) then + --set a variable + forward_all_destination = action_value; + forward_all_enabled = "true"; + forward_immediate_destination = action_value; + forward_immediate_enabled = "true"; + + --get the caller_id for outbound call + local forward_caller_id = "" + if not empty(forward_caller_id_uuid) then + local sql = "select destination_number, destination_description,".. + "destination_caller_id_number, destination_caller_id_name " .. + "from v_destinations where domain_uuid = :domain_uuid and " .. + "destination_type = 'inbound' and destination_uuid = :destination_uuid"; + local params = {domain_uuid = domain_uuid; destination_uuid = forward_caller_id_uuid} + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + local row = dbh:first_row(sql, params) + if row then + local caller_id_number = row.destination_caller_id_number + if empty(caller_id_number) then + caller_id_number = row.destination_number + end + + local caller_id_name = row.destination_caller_id_name + if empty(caller_id_name) then + caller_id_name = row.destination_description + end + + if not empty(caller_id_number) then + forward_caller_id = forward_caller_id .. + ",outbound_caller_id_number=" .. caller_id_number .. + ",origination_caller_id_number=" .. caller_id_number + end + + if not empty(caller_id_name) then + forward_caller_id = forward_caller_id .. + ",outbound_caller_id_name=" .. caller_id_name .. + ",origination_caller_id_name=" .. caller_id_name + end + end + end + + --set the dial string + if feature_enabled == "true" then + local destination_extension, destination_number_alias + + --used for number_alias to get the correct user + local sql = "select extension, number_alias from v_extensions "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and number_alias = :number_alias "; + local params = {domain_uuid = domain_uuid; number_alias = forward_all_destination} + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params, function(row) + destination_user = row.extension; + destination_extension = row.extension; + destination_number_alias = row.number_alias or ''; + end); + + if (destination_user ~= nil) then + cmd = "user_exists id ".. destination_user .." "..domain_name; + else + cmd = "user_exists id ".. forward_all_destination .." "..domain_name; + end + local user_exists = trim(api:executeString(cmd)); + + end + + --update the extension + sql = "update v_extensions set "; + sql = sql .. "do_not_disturb = 'false', "; + sql = sql .. "forward_all_enabled = 'true', "; + sql = sql .. "forward_all_destination = :forward_all_destination, "; + sql = sql .. "dial_string = null "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and extension_uuid = :extension_uuid "; + local params = {domain_uuid = domain_uuid, extension_uuid = extension_uuid, forward_all_destination = forward_all_destination}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + + --update follow me + if (follow_me_uuid ~= nil) then + if (string.len(follow_me_uuid) > 0) then + local sql = "update v_follow_me set "; + sql = sql .. "follow_me_enabled = 'false' "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and follow_me_uuid = :follow_me_uuid "; + local params = {domain_uuid = domain_uuid, follow_me_uuid = follow_me_uuid}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + end + end + + --send notify to the phone + notify.forward_immediate(user, host, sip_profile, forward_immediate_enabled, forward_immediate_destination); + end + + --Call Formward All disable + if (feature_action == "SetCallForward" and feature_enabled == "false" and action_name == "forward_immediate" and sip_profile ~= nil) then + --set a variable + forward_all_destination = action_value; + forward_all_enabled = "false"; + forward_immediate_enabled = "false"; + forward_immediate_destination = action_value; + --update the extension + sql = "update v_extensions set "; + sql = sql .. "do_not_disturb = 'false', "; + sql = sql .. "forward_all_enabled = 'false', "; + if (forward_all_destination ~= nil) then + sql = sql .. "forward_all_destination = :forward_all_destination, "; + else + sql = sql .. "forward_all_destination = null, "; + end + sql = sql .. "dial_string = null "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and extension_uuid = :extension_uuid "; + local params = {domain_uuid = domain_uuid, extension_uuid = extension_uuid, forward_all_destination = forward_all_destination}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + + --send notify to the phone + if (forward_immediate_destination == nil) then + forward_immediate_destination = " "; + end + notify.forward_immediate(user, host, sip_profile, forward_immediate_enabled, forward_immediate_destination); + end + + --Call Formward BUSY enable + if (feature_action == "SetCallForward" and feature_enabled == "true" and action_name == "forward_busy" and sip_profile ~= nil) then + --set a variable + forward_busy_destination = action_value; + forward_busy_enabled = "true"; + --update the extension + sql = "update v_extensions set "; + sql = sql .. "do_not_disturb = 'false', "; + sql = sql .. "forward_busy_enabled = 'true', "; + sql = sql .. "forward_busy_destination = :forward_busy_destination "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and extension_uuid = :extension_uuid "; + local params = {domain_uuid = domain_uuid, extension_uuid = extension_uuid, forward_busy_destination = forward_busy_destination}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + + --send notify to the phone + notify.forward_busy(user, host, sip_profile, forward_busy_enabled, forward_busy_destination); + end + + --Call Formward BUSY disable + if (feature_action == "SetCallForward" and feature_enabled == "false" and action_name == "forward_busy" and sip_profile ~= nil) then + --set a variable + forward_busy_destination = action_value; + forward_busy_enabled = "false"; + --update the extension + sql = "update v_extensions set "; + sql = sql .. "do_not_disturb = 'false', "; + sql = sql .. "forward_busy_enabled = 'false', "; + if (forward_busy_destination ~= nil) then + sql = sql .. "forward_busy_destination = :forward_busy_destination "; + else + sql = sql .. "forward_busy_destination = null "; + end + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and extension_uuid = :extension_uuid "; + local params = {domain_uuid = domain_uuid, extension_uuid = extension_uuid, forward_busy_destination = forward_busy_destination}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + + --send notify to the phone + notify.forward_busy(user, host, sip_profile, forward_busy_enabled, forward_busy_destination); + end + + --Call Formward NO ANSWER enable + if (feature_action == "SetCallForward" and feature_enabled == "true" and action_name == "forward_no_answer" and sip_profile ~= nil) then + --set a variable + forward_no_answer_destination = action_value; + forward_no_answer_enabled = "true"; + call_timeout = ring_count * 6; + --update the extension + sql = "update v_extensions set "; + sql = sql .. "do_not_disturb = 'false', "; + sql = sql .. "call_timeout = :call_timeout, "; + sql = sql .. "forward_no_answer_enabled = 'true', "; + sql = sql .. "forward_no_answer_destination = :forward_no_answer_destination "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and extension_uuid = :extension_uuid "; + local params = {domain_uuid = domain_uuid, extension_uuid = extension_uuid, forward_no_answer_destination = forward_no_answer_destination, call_timeout = call_timeout}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + + --send notify to the phone + notify.forward_no_answer(user, host, sip_profile, forward_no_answer_enabled, forward_no_answer_destination, ring_count); + end + + --Call Formward NO ANSWER disable + if (feature_action == "SetCallForward" and feature_enabled == "false" and action_name == "forward_no_answer" and sip_profile ~= nil) then + --set a variable + forward_no_answer_destination = action_value; + forward_no_answer_enabled = "false"; + --update the extension + sql = "update v_extensions set "; + sql = sql .. "do_not_disturb = 'false', "; + sql = sql .. "forward_no_answer_enabled = 'false', "; + if (forward_no_answer_destination ~= nil) then + sql = sql .. "forward_no_answer_destination = :forward_no_answer_destination "; + else + sql = sql .. "forward_no_answer_destination = null "; + end + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and extension_uuid = :extension_uuid "; + local params = {domain_uuid = domain_uuid, extension_uuid = extension_uuid, forward_no_answer_destination = forward_no_answer_destination, call_timeout = call_timeout}; + if (debug["sql"]) then + freeswitch.consoleLog("notice", "[feature_event] "..sql.."; params:" .. json.encode(params) .. "\n"); + end + dbh:query(sql, params); + + --send notify to the phone + notify.forward_no_answer(user, host, sip_profile, forward_no_answer_enabled, forward_no_answer_destination, ring_count); + end + + --No feature event (phone boots): Send all values + if (feature_enabled == nil) then + --Do Not Disturb + --notify.dnd(user, host, sip_profile, do_not_disturb); + + --Forward all + forward_immediate_enabled = forward_all_enabled; + forward_immediate_destination = forward_all_destination; + --notify.forward_immediate(user, host, sip_profile, forward_immediate_enabled, forward_immediate_destination); + + --Forward busy + --notify.forward_busy(user, host, sip_profile, forward_busy_enabled, forward_busy_destination); + + --Forward No Answer + ring_count = math.ceil (call_timeout / 6); + --notify.forward_no_answer(user, host, sip_profile, forward_no_answer_enabled, forward_no_answer_destination, ring_count); + notify.init(user, + host, + sip_profile, + forward_immediate_enabled, + forward_immediate_destination, + forward_busy_enabled, + forward_busy_destination, + forward_no_answer_enabled, + forward_no_answer_destination, + ring_count, + do_not_disturb); + end + +-- feature_event_notify.init(user, host, sip_profile, forward_immediate_enabled, forward_immediate_destination, forward_busy_enabled, forward_busy_destination, forward_no_answer_enabled, forward_no_answer_destination, ring_count, do_not_disturb) + + --clear the cache + if (feature_enabled ~= nil) then + cache.del("directory:"..user.."@"..host) + end diff --git a/resources/install/scripts/app/feature_event/resources/functions/feature_event_notify.lua b/resources/install/scripts/app/feature_event/resources/functions/feature_event_notify.lua new file mode 100644 index 0000000000..e5769cada0 --- /dev/null +++ b/resources/install/scripts/app/feature_event/resources/functions/feature_event_notify.lua @@ -0,0 +1,149 @@ +local feature_event_notify = {} + +function feature_event_notify.get_db_values(user, domain_name) + --get the domain uuid from the host + local Database = require "resources.functions.database"; + local dbh = Database.new('system'); + + local sql = "select * from v_domains "; + sql = sql .. "where domain_name = :domain_name "; + local params = {domain_name = domain_name}; + -- if (debug["sql"]) then + -- freeswitch.consoleLog("notice", "[feature_event] " .. sql .. "; params:" .. json.encode(params) .. "\n"); + -- end + dbh:query(sql, params, function(row) + domain_uuid = row.domain_uuid; + end); + + --get extension information + local sql = "select * from v_extensions "; + sql = sql .. "where domain_uuid = :domain_uuid "; + sql = sql .. "and (extension = :extension or number_alias = :extension) "; + local params = {domain_uuid = domain_uuid, extension = user}; + -- if (debug["sql"]) then + -- freeswitch.consoleLog("notice", "[feature_event] " .. sql .. "; params:" .. json.encode(params) .. "\n"); + -- end + + dbh:query(sql, params, function(row) + extension_uuid = row.extension_uuid; + extension = row.extension; + number_alias = row.number_alias or ''; + accountcode = row.accountcode; + follow_me_uuid = row.follow_me_uuid; + do_not_disturb = row.do_not_disturb; + forward_all_enabled = row.forward_all_enabled; + forward_all_destination = row.forward_all_destination; + forward_busy_enabled = row.forward_busy_enabled; + forward_busy_destination = row.forward_busy_destination; + forward_no_answer_enabled = row.forward_no_answer_enabled; + forward_no_answer_destination = row.forward_no_answer_destination; + forward_user_not_registered_enabled = row.forward_user_not_registered_enabled; + forward_user_not_registered_destination = row.forward_user_not_registered_destination; + forward_caller_id_uuid = row.forward_caller_id_uuid; + toll_allow = row.toll_allow + call_timeout = row.call_timeout + --freeswitch.consoleLog("NOTICE", "[feature_event] extension "..row.extension.."\n"); + --freeswitch.consoleLog("NOTICE", "[feature_event] accountcode "..row.accountcode.."\n"); + end); + + --set some defaults if values in database are NULL + if (forward_all_enabled == "") then forward_all_enabled = "false"; end + --if (forward_all_destination == "") then forward_all_destination = nil; end + if (forward_busy_enabled == "") then forward_busy_enabled = "false"; end + if (forward_no_answer_enabled == "") then forward_no_answer_enabled = "false"; end + if (do_not_disturb == "") then do_not_disturb = "false"; end + if (call_timeout == "") then call_timeout = "30"; end + + return do_not_disturb, forward_all_enabled, forward_all_destination, forward_busy_enabled, forward_busy_destination, forward_no_answer_enabled, forward_no_answer_destination, call_timeout +end + +function feature_event_notify.get_profile(user, host) + --includes + require "resources.functions.explode" + require "resources.functions.trim" + + local account = user.."@"..host + --create the api object + api = freeswitch.API(); + local sofia_contact = trim(api:executeString("sofia_contact */"..account)); + local array = explode("/", sofia_contact); + local sip_profile = array[2]; + return sip_profile +end + +function feature_event_notify.dnd(user, host, sip_profile, do_not_disturb) + --set the event and send it + local event = freeswitch.Event("SWITCH_EVENT_PHONE_FEATURE") + event:addHeader("profile", sip_profile) + event:addHeader("user", user) + event:addHeader("host", host) + event:addHeader("device", "") + event:addHeader("Feature-Event", "DoNotDisturbEvent") + event:addHeader("doNotDisturbOn", do_not_disturb) + --freeswitch.consoleLog("notice","[events] " .. event:serialize("xml") .. "\n"); + event:fire() +end + +function feature_event_notify.forward_immediate(user, host, sip_profile, forward_immediate_enabled, forward_immediate_destination) + --set the event and send it + local event = freeswitch.Event("SWITCH_EVENT_PHONE_FEATURE") + event:addHeader("profile", sip_profile) + event:addHeader("user", user) + event:addHeader("host", host) + event:addHeader("device", "") + event:addHeader("Feature-Event", "ForwardingEvent") + event:addHeader("forward_immediate_enabled", forward_immediate_enabled) + event:addHeader("forward_immediate", forward_immediate_destination); + freeswitch.consoleLog("notice","[events] " .. event:serialize("xml") .. "\n"); + event:fire() +end + +function feature_event_notify.forward_busy(user, host, sip_profile, forward_busy_enabled, forward_busy_destination) + --set the event and send it + local event = freeswitch.Event("SWITCH_EVENT_PHONE_FEATURE") + event:addHeader("profile", sip_profile) + event:addHeader("user", user) + event:addHeader("host", host) + event:addHeader("device", "") + event:addHeader("Feature-Event", "ForwardingEvent") + event:addHeader("forward_busy", forward_busy_destination) + event:addHeader("forward_busy_enabled", forward_busy_enabled) + event:fire() +end + +function feature_event_notify.forward_no_answer(user, host, sip_profile, forward_no_answer_enabled, forward_no_answer_destination, ring_count) + --set the event and send it + local event = freeswitch.Event("SWITCH_EVENT_PHONE_FEATURE") + event:addHeader("profile", sip_profile) + event:addHeader("user", user) + event:addHeader("host", host) + event:addHeader("device", "") + event:addHeader("Feature-Event", "ForwardingEvent") + event:addHeader("forward_no_answer", forward_no_answer_destination) + event:addHeader("forward_no_answer_enabled", forward_no_answer_enabled) + event:addHeader("ringCount", ring_count) + event:fire() +end + +function feature_event_notify.init(user, host, sip_profile, forward_immediate_enabled, forward_immediate_destination, forward_busy_enabled, forward_busy_destination, forward_no_answer_enabled, forward_no_answer_destination, ring_count, do_not_disturb) + --set the event and send it + local event = freeswitch.Event("SWITCH_EVENT_PHONE_FEATURE") + event:addHeader("profile", sip_profile) + event:addHeader("user", user) + event:addHeader("host", host) + event:addHeader("device", "") + event:addHeader("Feature-Event", "init") + event:addHeader("forward_immediate_enabled", forward_immediate_enabled) + event:addHeader("forward_immediate", forward_immediate_destination); + event:addHeader("forward_busy", forward_busy_destination) + event:addHeader("forward_busy_enabled", forward_busy_enabled) + event:addHeader("Feature-Event", "ForwardingEvent") + event:addHeader("forward_no_answer", forward_no_answer_destination) + event:addHeader("forward_no_answer_enabled", forward_no_answer_enabled) + event:addHeader("ringCount", ring_count) + event:addHeader("Feature-Event", "DoNotDisturbEvent") + event:addHeader("doNotDisturbOn", do_not_disturb) + event:fire() +end + +return feature_event_notify diff --git a/resources/install/scripts/call_forward.lua b/resources/install/scripts/call_forward.lua index 84c8990337..bf7374f7d1 100644 --- a/resources/install/scripts/call_forward.lua +++ b/resources/install/scripts/call_forward.lua @@ -45,6 +45,7 @@ local Settings = require "resources.functions.lazy_settings" local route_to_bridge = require "resources.functions.route_to_bridge" local blf = require "resources.functions.blf" + local notify = require "app.feature_event.resources.functions.feature_event_notify" --include json library local json @@ -290,6 +291,55 @@ dbh:query(sql, params); end +--send notify to phone if feature sync is enabled + if settings:get('device', 'feature_sync', 'boolean') == 'true' then + -- Get values from the database + do_not_disturb, forward_all_enabled, forward_all_destination, forward_busy_enabled, forward_busy_destination, forward_no_answer_enabled, forward_no_answer_destination, call_timeout = notify.get_db_values(extension, domain_name) + + -- Get the sip_profile + if (extension ~= nil and domain_name ~= nil) then + sip_profile = notify.get_profile(extension, domain_name); + end + + if (sip_profile ~= nil) then + freeswitch.consoleLog("NOTICE", "[feature_event] SIP NOTIFY: CFWD set to "..forward_all_enabled.."\n"); + + --Do Not Disturb + notify.dnd(extension, domain_name, sip_profile, do_not_disturb); + + --Forward all + forward_immediate_enabled = forward_all_enabled; + forward_immediate_destination = forward_all_destination; + + --workaround for freeswitch not sending NOTIFY when destination values are nil. Send 0. + if (string.len(forward_immediate_destination) < 1) then + forward_immediate_destination = '0'; + end + + freeswitch.consoleLog("NOTICE", "[feature_event] forward_immediate_destination "..forward_immediate_destination.."\n"); + notify.forward_immediate(extension, domain_name, sip_profile, forward_immediate_enabled, forward_immediate_destination); + + --Forward busy + --workaround for freeswitch not sending NOTIFY when destination values are nil. Send 0. + if (string.len(forward_busy_destination) < 1) then + forward_busy_destination = '0'; + end + + freeswitch.consoleLog("NOTICE", "[feature_event] forward_busy_destination "..forward_busy_destination.."\n"); + notify.forward_busy(extension, domain_name, sip_profile, forward_busy_enabled, forward_busy_destination); + + --Forward No Answer + ring_count = math.ceil (call_timeout / 6); + --workaround for freeswitch not sending NOTIFY when destination values are nil. Send 0. + if (string.len(forward_no_answer_destination) < 1) then + forward_no_answer_destination = '0'; + end + + freeswitch.consoleLog("NOTICE", "[feature_event] forward_no_answer_destination "..forward_no_answer_destination.."\n"); + notify.forward_no_answer(extension, domain_name, sip_profile, forward_no_answer_enabled, forward_no_answer_destination, ring_count); + end + end + --disconnect from database dbh:release() diff --git a/resources/install/scripts/do_not_disturb.lua b/resources/install/scripts/do_not_disturb.lua index 0e13de9103..1fbdf5d5fa 100644 --- a/resources/install/scripts/do_not_disturb.lua +++ b/resources/install/scripts/do_not_disturb.lua @@ -45,6 +45,8 @@ local blf = require "resources.functions.blf" local cache = require "resources.functions.cache" + local Settings = require "resources.functions.lazy_settings" + local notify = require "app.feature_event.resources.functions.feature_event_notify" --check if the session is ready if ( session:ready() ) then @@ -77,6 +79,8 @@ local Database = require "resources.functions.database"; dbh = Database.new('system'); + local settings = Settings.new(dbh, domain_name, domain_uuid); + --include json library local json if (debug["sql"]) then @@ -203,6 +207,52 @@ dbh:query(sql, params); end); +--send notify to phone if feature sync is enabled + if settings:get('device', 'feature_sync', 'boolean') == 'true' then + -- Get values from the database + do_not_disturb, forward_all_enabled, forward_all_destination, forward_busy_enabled, forward_busy_destination, forward_no_answer_enabled, forward_no_answer_destination, call_timeout = notify.get_db_values(extension, domain_name) + + -- Get the sip_profile + if (extension ~= nil and domain_name ~= nil) then + sip_profile = notify.get_profile(extension, domain_name); + end + + if (sip_profile ~= nil) then + freeswitch.consoleLog("NOTICE", "[feature_event] SIP NOTIFY: CFWD set to "..forward_all_enabled.."\n"); + + --Do Not Disturb + notify.dnd(extension, domain_name, sip_profile, do_not_disturb); + + --Forward all + forward_immediate_enabled = forward_all_enabled; + forward_immediate_destination = forward_all_destination; + + --workaround for freeswitch not sending NOTIFY when destination values are nil. Send 0. + if (string.len(forward_immediate_destination) < 1) then + forward_immediate_destination = '0'; + end + + notify.forward_immediate(extension, domain_name, sip_profile, forward_immediate_enabled, forward_immediate_destination); + + --Forward busy + --workaround for freeswitch not sending NOTIFY when destination values are nil. Send 0. + if (string.len(forward_busy_destination) < 1) then + forward_busy_destination = '0'; + end + + notify.forward_busy(extension, domain_name, sip_profile, forward_busy_enabled, forward_busy_destination); + + --Forward No Answer + ring_count = math.ceil (call_timeout / 6); + --workaround for freeswitch not sending NOTIFY when destination values are nil. Send 0. + if (string.len(forward_no_answer_destination) < 1) then + forward_no_answer_destination = '0'; + end + + notify.forward_no_answer(extension, domain_name, sip_profile, forward_no_answer_enabled, forward_no_answer_destination, ring_count); + end + end + --clear the cache if extension and #extension > 0 and cache.support() then cache.del("directory:"..extension.."@"..domain_name); @@ -226,4 +276,8 @@ forward_all_destination, nil, domain_name ) end + + --disconnect from database + dbh:release() + end diff --git a/resources/templates/conf/autoload_configs/lua.conf.xml b/resources/templates/conf/autoload_configs/lua.conf.xml index 4225ff6d2c..5a5e894275 100644 --- a/resources/templates/conf/autoload_configs/lua.conf.xml +++ b/resources/templates/conf/autoload_configs/lua.conf.xml @@ -56,5 +56,7 @@ + +