diff --git a/app/call_centers/call_center_agent_delete.php b/app/call_centers/call_center_agent_delete.php index ecbdd74ff6..d7703ec81f 100644 --- a/app/call_centers/call_center_agent_delete.php +++ b/app/call_centers/call_center_agent_delete.php @@ -86,6 +86,7 @@ if (count($_GET)>0) { //synchronize configuration save_call_center_xml(); + remove_config_from_cache('configuration:callcenter.conf'); //redirect the browser $_SESSION["message"] = $text['message-delete']; diff --git a/app/call_centers/call_center_agent_edit.php b/app/call_centers/call_center_agent_edit.php index 5ff7915723..e72dc42c19 100644 --- a/app/call_centers/call_center_agent_edit.php +++ b/app/call_centers/call_center_agent_edit.php @@ -264,6 +264,7 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { //syncrhonize configuration save_call_center_xml(); + remove_config_from_cache('configuration:callcenter.conf'); $_SESSION["message"] = $text['message-add']; header("Location: call_center_agents.php"); @@ -291,7 +292,8 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { unset($sql); //syncrhonize configuration - save_call_center_xml(); + save_call_center_xml(); + remove_config_from_cache('configuration:callcenter.conf'); $_SESSION["message"] = $text['message-update']; header("Location: call_center_agents.php"); diff --git a/app/call_centers/call_center_queue_delete.php b/app/call_centers/call_center_queue_delete.php index bad7ad96cc..5abb84093f 100644 --- a/app/call_centers/call_center_queue_delete.php +++ b/app/call_centers/call_center_queue_delete.php @@ -87,9 +87,11 @@ if (strlen($id) > 0) { //clear the cache $cache = new cache; $cache->delete("dialplan:".$_SESSION["context"]); + remove_config_from_cache('configuration:callcenter.conf'); //synchronize configuration save_dialplan_xml(); + save_call_center_xml(); //apply settings reminder $_SESSION["reload_xml"] = true; diff --git a/app/call_centers/call_center_queue_edit.php b/app/call_centers/call_center_queue_edit.php index 05f82c1580..e37cf5f245 100644 --- a/app/call_centers/call_center_queue_edit.php +++ b/app/call_centers/call_center_queue_edit.php @@ -257,6 +257,7 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { //syncrhonize the configuration save_call_center_xml(); + remove_config_from_cache('configuration:callcenter.conf'); //delete the dialplan context from memcache $fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']); @@ -326,6 +327,7 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { //synchronize the configuration save_call_center_xml(); + remove_config_from_cache('configuration:callcenter.conf'); //clear the cache $cache = new cache; @@ -393,6 +395,7 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { //syncrhonize configuration save_call_center_xml(); + remove_config_from_cache('configuration:callcenter.conf'); } //redirect diff --git a/app/call_centers/call_center_tier_edit.php b/app/call_centers/call_center_tier_edit.php index 5f25536092..a8c5d2d4ac 100644 --- a/app/call_centers/call_center_tier_edit.php +++ b/app/call_centers/call_center_tier_edit.php @@ -111,7 +111,8 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) { unset($sql); //syncrhonize configuration - save_call_center_xml(); + save_call_center_xml(); + remove_config_from_cache('configuration:callcenter.conf'); //look up queue uuid by queue name (ugh) $sql = "select call_center_queue_uuid from v_call_center_queues where queue_name = '".$queue_name."'"; diff --git a/app/voicemails/app_defaults.php b/app/voicemails/app_defaults.php index d81acb5140..0fab2304d7 100644 --- a/app/voicemails/app_defaults.php +++ b/app/voicemails/app_defaults.php @@ -48,6 +48,13 @@ if ($domains_processed == 1) { $array[$x]['default_setting_enabled'] = 'true'; $array[$x]['default_setting_description'] = 'Define whether to keep voicemail files on the local system after sending attached via email.'; $x++; + $array[$x]['default_setting_category'] = 'voicemail'; + $array[$x]['default_setting_subcategory'] = 'storage_type'; + $array[$x]['default_setting_name'] = 'text'; + $array[$x]['default_setting_value'] = 'base64'; + $array[$x]['default_setting_enabled'] = 'false'; + $array[$x]['default_setting_description'] = 'Define which storage type (base_64 stores in the database).'; + $x++; //iterate and add each, if necessary foreach ($array as $index => $default_settings) { diff --git a/app/voicemails/resources/classes/voicemail.php b/app/voicemails/resources/classes/voicemail.php index ca5b55ba00..27f7e304af 100644 --- a/app/voicemails/resources/classes/voicemail.php +++ b/app/voicemails/resources/classes/voicemail.php @@ -161,7 +161,7 @@ if ($result_count > 0) { foreach($result as &$row) { //set the greeting directory - $path = $_SESSION['switch']['storage']['dir'].'/voicemail/default/'.$_SESSION['domain_name'].'/'.$row['voicemail_id']; + $path = $_SESSION['switch']['voicemail']['dir'].'/default/'.$_SESSION['domain_name'].'/'.$row['voicemail_id']; if (file_exists($path.'/msg_'.$row['voicemail_message_uuid'].'.wav')) { $row['file_path'] = $path.'/msg_'.$row['voicemail_message_uuid'].'.wav'; } @@ -239,7 +239,7 @@ } //delete the recording - $file_path = $_SESSION['switch']['storage']['dir']."/voicemail/default/".$_SESSION['domain_name']."/".$this->voicemail_id; + $file_path = $_SESSION['switch']['voicemail']['dir']."/default/".$_SESSION['domain_name']."/".$this->voicemail_id; foreach (glob($file_path."/msg_".$this->voicemail_message_uuid.".*") as $file_name) { unlink($file_name); } @@ -278,7 +278,7 @@ session_cache_limiter('public'); //set source folder path - $path = $_SESSION['switch']['storage']['dir'].'/voicemail/default/'.$_SESSION['domain_name'].'/'.$this->voicemail_id; + $path = $_SESSION['switch']['voicemail']['dir'].'/default/'.$_SESSION['domain_name'].'/'.$this->voicemail_id; //prepare base64 content from db, if enabled if ($_SESSION['voicemail']['storage_type']['text'] == 'base64') { diff --git a/resources/install/scripts/app/ring_groups/index.lua b/resources/install/scripts/app/ring_groups/index.lua index 553cb69ee1..25e07493f7 100644 --- a/resources/install/scripts/app/ring_groups/index.lua +++ b/resources/install/scripts/app/ring_groups/index.lua @@ -38,7 +38,7 @@ local log = require "resources.functions.log".ring_group require "resources.functions.explode"; require "resources.functions.base64"; require "resources.functions.file_exists"; - require "resources.functions.explode"; + require "resources.functions.channel_utils" --get the variables domain_name = session:getVariable("domain_name"); @@ -439,34 +439,10 @@ local log = require "resources.functions.log".ring_group extension_uuid = trim(api:executeString(cmd)); --send to user local dial_string_to_user = "[sip_invite_domain="..domain_name..","..group_confirm.."leg_timeout="..destination_timeout..","..delay_name.."="..destination_delay..",dialed_extension=" .. row.destination_number .. ",extension_uuid="..extension_uuid .. row.record_session .. "]user/" .. row.destination_number .. "@" .. domain_name; - if (ring_group_skip_active ~= nil) then - if (ring_group_skip_active == "true") then - cmd = "show channels like "..destination_number; - reply = trim(api:executeString(cmd)); - --freeswitch.consoleLog("notice", "[ring group] reply "..cmd.." " .. reply .. "\n"); - exploded_reply = {}; - exploded_reply = explode(",",reply); - - if (reply == "0 total.") then - dial_string = dial_string_to_user - else - idle_extension=true; - - if (exploded_reply ~= nil) then - for i,v in ipairs(exploded_reply) do - if(v==destination_number.."@"..domain_name) then - idle_extension=false; - end - end - end - - if(idle_extension) then - dial_string = dial_string_to_user; - end - end - else - --look inside the reply to check for the correct domain_name - dial_string = dial_string_to_user; + if (ring_group_skip_active == "true") then + local channels = channels_by_number(destination_number, domain_name) + if (not channels) or #channels == 0 then + dial_string = dial_string_to_user end else dial_string = dial_string_to_user; diff --git a/resources/install/scripts/app/xml_handler/resources/scripts/languages/languages.lua b/resources/install/scripts/app/xml_handler/resources/scripts/languages/languages.lua index 86047db948..c607d699b3 100644 --- a/resources/install/scripts/app/xml_handler/resources/scripts/languages/languages.lua +++ b/resources/install/scripts/app/xml_handler/resources/scripts/languages/languages.lua @@ -142,16 +142,25 @@ table.insert(xml, [[ ]]);; end + require "resources.functions.settings"; + settings = settings(domain_uuid); + lang_path = "/usr/local/freeswitch/conf/lang/"; + if (settings['switch']['phrases'] ~= nil) then + if (settings['switch']['phrases']['dir'] ~= nil) then + lang_path = settings['switch']['phrases']['dir']; + end + end + --read root xml language file, parse included xml files local xml_file_paths = {} - local file_handle = io.open("/usr/local/freeswitch/conf/lang/"..language.."/"..language..".xml", "r"); + local file_handle = io.open(lang_path.."/"..language.."/"..language..".xml", "r"); if (file_handle ~= nil) then for file_line in file_handle:lines() do if (string.find(file_line, 'cmd="include" data="', 0, true) ~= nil) then pos_beg = string.find(file_line, 'cmd="include" data="', 0, true) + 20; pos_end = string.find(file_line, '"/>', 0, true) - 1; xml_file_path = string.sub(file_line, pos_beg, pos_end); - table.insert(xml_file_paths, "/usr/local/freeswitch/conf/lang/"..language.."/"..xml_file_path); + table.insert(xml_file_paths, lang_path.."/"..language.."/"..xml_file_path); --freeswitch.consoleLog("notice", "file path = "..xml_file_path.."\n"); end end diff --git a/resources/install/scripts/call_flow.lua b/resources/install/scripts/call_flow.lua index a8298a067c..2b51b6d33b 100644 --- a/resources/install/scripts/call_flow.lua +++ b/resources/install/scripts/call_flow.lua @@ -35,6 +35,10 @@ require "resources.functions.database_handle"; dbh = database_handle('system'); + local log = require "resources.functions.log".call_flow + + local presence_in = require "resources.functions.presence_in" + if (session:ready()) then --get the variables domain_name = session:getVariable("domain_name"); @@ -51,11 +55,9 @@ if (session:ready()) then if (not default_voice) then default_voice = 'callie'; end --get the extension list - sql = [[SELECT * FROM v_call_flows - where call_flow_uuid = ']]..call_flow_uuid..[[']] - --and call_flow_enabled = 'true' - --freeswitch.consoleLog("notice", "SQL:" .. sql .. "\n"); - app_data = ""; + sql = "SELECT * FROM v_call_flows where call_flow_uuid = '"..call_flow_uuid.."'" + -- .. "and call_flow_enabled = 'true'" + --log.notice("SQL: %s", sql); x = 0; dbh:query(sql, function(row) @@ -68,17 +70,15 @@ if (session:ready()) then call_flow_label = row.call_flow_label; call_flow_anti_label = row.call_flow_anti_label; - if (string.len(call_flow_status) == 0) then + if #call_flow_status == 0 then + call_flow_status = "true"; + end + if (call_flow_status == "true") then app = row.call_flow_app; data = row.call_flow_data else - if (call_flow_status == "true") then - app = row.call_flow_app; - data = row.call_flow_data - else - app = row.call_flow_anti_app; - data = row.call_flow_anti_data - end + app = row.call_flow_anti_app; + data = row.call_flow_anti_data end end); @@ -99,70 +99,34 @@ if (session:ready()) then end --feature code - toggle the status - if (string.len(call_flow_status) == 0) then - toggle = "false"; - else - if (call_flow_status == "true") then - toggle = "false"; - else - toggle = "true"; - end - end - if (toggle == "true") then - --set the presence to terminated - turn the lamp off: - event = freeswitch.Event("PRESENCE_IN"); - event:addHeader("proto", "sip"); - event:addHeader("event_type", "presence"); - event:addHeader("alt_event_type", "dialog"); - event:addHeader("Presence-Call-Direction", "outbound"); - event:addHeader("state", "Active (1 waiting)"); - event:addHeader("from", call_flow_feature_code.."@"..domain_name); - event:addHeader("login", call_flow_feature_code.."@"..domain_name); - event:addHeader("unique-id", call_flow_uuid); - event:addHeader("answer-state", "terminated"); - event:fire(); - --answer and play a tone - session:answer(); - if (string.len(call_flow_label) > 0) then - api = freeswitch.API(); - reply = api:executeString("uuid_display "..session:get_uuid().." "..call_flow_label); - end - session:execute("sleep", "2000"); - session:execute("playback", "tone_stream://%(200,0,500,600,700)"); - --show in the console - freeswitch.consoleLog("notice", "Call Flow: label="..call_flow_label..",status=true,uuid="..call_flow_uuid.."\n"); - else - --set presence in - turn lamp on - event = freeswitch.Event("PRESENCE_IN"); - event:addHeader("proto", "sip"); - event:addHeader("login", call_flow_feature_code.."@"..domain_name); - event:addHeader("from", call_flow_feature_code.."@"..domain_name); - event:addHeader("status", "Active (1 waiting)"); - event:addHeader("rpid", "unknown"); - event:addHeader("event_type", "presence"); - event:addHeader("alt_event_type", "dialog"); - event:addHeader("event_count", "1"); - event:addHeader("unique-id", call_flow_uuid); - event:addHeader("Presence-Call-Direction", "outbound") - event:addHeader("answer-state", "confirmed"); - event:fire(); - --answer and play a tone - session:answer(); - if (string.len(call_flow_anti_label) > 0) then - api = freeswitch.API(); - reply = api:executeString("uuid_display "..session:get_uuid().." "..call_flow_anti_label); - end - session:execute("sleep", "2000"); - session:execute("playback", "tone_stream://%(500,0,300,200,100,50,25)"); - --show in the console - freeswitch.consoleLog("notice", "Call Flow: label="..call_flow_anti_label..",status=false,uuid="..call_flow_uuid.."\n"); + toggle = (call_flow_status == "true") and "false" or "true" + + -- turn the lamp + presence_in.turn_lamp( toggle == "false", + call_flow_feature_code.."@"..domain_name, + call_flow_uuid + ); + + local active_flow_label = (toggle == "true") and call_flow_label or call_flow_anti_label + --answer and play a tone + session:answer(); + if #active_flow_label > 0 then + api = freeswitch.API(); + reply = api:executeString("uuid_display "..session:get_uuid().." "..active_flow_label); end + session:execute("sleep", "2000"); + session:execute("playback", "tone_stream://%(200,0,500,600,700)"); + + --show in the console + log.noticef("label=%s,status=%s,uuid=%s", active_flow_label, toggle, call_flow_uuid); + + --store in database dbh:query("UPDATE v_call_flows SET call_flow_status = '"..toggle.."' WHERE call_flow_uuid = '"..call_flow_uuid.."'"); + --hangup the call session:hangup(); else - --app_data - freeswitch.consoleLog("notice", "Call Flow: " .. app .. " " .. data .. "\n"); + log.notice("execute " .. app .. " " .. data); --exucute the application session:execute(app, data); diff --git a/resources/install/scripts/call_flow_monitor.lua b/resources/install/scripts/call_flow_monitor.lua index 5db7d4f3d0..b3ddebb1dc 100644 --- a/resources/install/scripts/call_flow_monitor.lua +++ b/resources/install/scripts/call_flow_monitor.lua @@ -38,9 +38,11 @@ require "resources.functions.file_exists"; require "resources.functions.mkdir"; ---connect to the database require "resources.functions.database_handle"; - dbh = database_handle('system'); + + local log = require "resources.functions.log".call_flow_monitor + + local presence_in = require "resources.functions.presence_in" --make sure the scripts/run dir exists mkdir(scripts_dir .. "/run"); @@ -61,69 +63,52 @@ --used to stop the lua service local file = assert(io.open(run_file, "w")); file:write("remove this file to stop the script"); + file:close() + log.notice("Start") --monitor the call flows status - x = 0 + local sql = "select d.domain_name, f.call_flow_uuid, f.call_flow_extension, f.call_flow_feature_code," .. + "f.call_flow_status, f.call_flow_label, f.call_flow_anti_label ".. + "from v_call_flows as f, v_domains as d " .. + "where f.domain_uuid = d.domain_uuid " -- and call_flow_enabled = 'true' while true do - --get the extension list - sql = [[select d.domain_name, f.call_flow_uuid, f.call_flow_extension, f.call_flow_feature_code, f.call_flow_status, f.call_flow_label, f.call_flow_anti_label - from v_call_flows as f, v_domains as d - where f.domain_uuid = d.domain_uuid]] - --and call_flow_enabled = 'true' + -- debug print if (debug["sql"]) then - freeswitch.consoleLog("notice", "SQL:" .. sql .. "\n"); + log.notice("SQL:" .. sql); end - x = 0; - dbh:query(sql, function(row) - domain_name = row.domain_name; - call_flow_uuid = row.call_flow_uuid; - --call_flow_name = row.call_flow_name; - call_flow_extension = row.call_flow_extension; - call_flow_feature_code = row.call_flow_feature_code; - --call_flow_context = row.call_flow_context; - call_flow_status = row.call_flow_status; - --pin_number = row.call_flow_pin_number; - call_flow_label = row.call_flow_label; - call_flow_anti_label = row.call_flow_anti_label; - if (call_flow_status == "true") then - --set the presence to terminated - turn the lamp off: - event = freeswitch.Event("PRESENCE_IN"); - event:addHeader("proto", "sip"); - event:addHeader("event_type", "presence"); - event:addHeader("alt_event_type", "dialog"); - event:addHeader("Presence-Call-Direction", "outbound"); - event:addHeader("state", "Active (1 waiting)"); - event:addHeader("from", call_flow_feature_code.."@"..domain_name); - event:addHeader("login", call_flow_feature_code.."@"..domain_name); - event:addHeader("unique-id", call_flow_uuid); - event:addHeader("answer-state", "terminated"); - event:fire(); - --show in the console - if (debug["log"]) then - freeswitch.consoleLog("notice", "Call Flow: label="..call_flow_label..",status=true,uuid="..call_flow_uuid.."\n"); - end - else - --set presence in - turn lamp on - event = freeswitch.Event("PRESENCE_IN"); - event:addHeader("proto", "sip"); - event:addHeader("login", call_flow_feature_code.."@"..domain_name); - event:addHeader("from", call_flow_feature_code.."@"..domain_name); - event:addHeader("status", "Active (1 waiting)"); - event:addHeader("rpid", "unknown"); - event:addHeader("event_type", "presence"); - event:addHeader("alt_event_type", "dialog"); - event:addHeader("event_count", "1"); - event:addHeader("unique-id", call_flow_uuid); - event:addHeader("Presence-Call-Direction", "outbound"); - event:addHeader("answer-state", "confirmed"); - event:fire(); - --show in the console - if (debug["log"]) then - freeswitch.consoleLog("notice", "Call Flow: label="..call_flow_anti_label..",status=false,uuid="..call_flow_uuid.."\n"); - end - end - end); + --connect to the database + local dbh = database_handle('system'); + + --get the extension list + if dbh:connected() then + dbh:query(sql, function(row) + local domain_name = row.domain_name; + local call_flow_uuid = row.call_flow_uuid; + --local call_flow_name = row.call_flow_name; + --local call_flow_extension = row.call_flow_extension; + local call_flow_feature_code = row.call_flow_feature_code; + --local call_flow_context = row.call_flow_context; + local call_flow_status = row.call_flow_status; + --local pin_number = row.call_flow_pin_number; + local call_flow_label = row.call_flow_label; + local call_flow_anti_label = row.call_flow_anti_label; + + -- turn the lamp + presence_in.turn_lamp( call_flow_status == "false", + call_flow_feature_code.."@"..domain_name, + call_flow_uuid + ); + + if (debug["log"]) then + local label = (call_flow_status == "true") and call_flow_label or call_flow_anti_label + log.noticef("label=%s,status=%s,uuid=%s", label, call_flow_status, call_flow_uuid); + end + end); + end + + -- release dbh + dbh:release() --exit the loop when the file does not exist if (not file_exists(run_file)) then @@ -132,4 +117,6 @@ --sleep a moment to prevent using unecessary resources freeswitch.msleep(sleep*1000); - end \ No newline at end of file + end + + log.notice("Stop") diff --git a/resources/install/scripts/resources/functions/cache.lua b/resources/install/scripts/resources/functions/cache.lua index 974e327dd9..06548af1cd 100644 --- a/resources/install/scripts/resources/functions/cache.lua +++ b/resources/install/scripts/resources/functions/cache.lua @@ -10,6 +10,13 @@ require "resources.functions.trim"; local api = api or freeswitch.API(); +local function send_event(action, key) + local event = freeswitch.Event("MEMCACHE", action); + event:addHeader("API-Command", "memcache"); + event:addHeader("API-Command-Argument", action .. " " .. key); + event:fire() +end + local Cache = {} local function check_error(result) @@ -57,6 +64,7 @@ function Cache.set(key, value, expire) end function Cache.del(key) + send_event('delete', key) local result, err = check_error(api:execute("memcache", "delete " .. key)) if not result then if err == 'NOT FOUND' then diff --git a/resources/install/scripts/resources/functions/channel_utils.lua b/resources/install/scripts/resources/functions/channel_utils.lua index a078939d2e..5cf33c5f8f 100644 --- a/resources/install/scripts/resources/functions/channel_utils.lua +++ b/resources/install/scripts/resources/functions/channel_utils.lua @@ -1,3 +1,7 @@ +require 'resources.config' +require 'resources.functions.trim' + +local Database = require 'resources.functions.database' local api = api or freeswitch.API() @@ -18,3 +22,38 @@ function channel_evalute(uuid, cmd) return result end + +local _switchname +local function switchname() + if _switchname then return _switchname end + + local result = api:executeString("switchname") + + if result:sub(1, 4) == '-ERR' then return nil, result end + if result == '_undef_' then return false end + + _switchname = result + return result +end + +function channels_by_number(number, domain) + local hostname = assert(switchname()) + local dbh = Database.new('switch') + + local full_number = number .. '@' .. (domain or '%') + + local sql = ([[select * from channels where hostname='%s' and ( + (context = '%s' and (cid_name = '%s' or cid_num = '%s')) + or name like '%s' or presence_id like '%s' or presence_data like '%s' + ) + order by created_epoch + ]]):format(hostname, + domain, number, number, + full_number, full_number, full_number + ) + + local rows = assert(dbh:fetch_all(sql)) + + dbh:release() + return rows +end diff --git a/resources/install/scripts/resources/functions/presence_in.lua b/resources/install/scripts/resources/functions/presence_in.lua new file mode 100644 index 0000000000..b8369f9b17 --- /dev/null +++ b/resources/install/scripts/resources/functions/presence_in.lua @@ -0,0 +1,23 @@ +local function turn_lamp(on, user, uuid) + local event = freeswitch.Event("PRESENCE_IN"); + event:addHeader("proto", "sip"); + event:addHeader("event_type", "presence"); + event:addHeader("alt_event_type", "dialog"); + event:addHeader("Presence-Call-Direction", "outbound"); + event:addHeader("from", user); + event:addHeader("login", user); + event:addHeader("unique-id", uuid); + event:addHeader("status", "Active (1 waiting)"); + if on then + event:addHeader("answer-state", "confirmed"); + event:addHeader("rpid", "unknown"); + event:addHeader("event_count", "1"); + else + event:addHeader("answer-state", "terminated"); + end + event:fire(); +end + +return { + turn_lamp = turn_lamp; +} \ No newline at end of file diff --git a/resources/switch.php b/resources/switch.php index a37727a9d6..e4eb04c532 100644 --- a/resources/switch.php +++ b/resources/switch.php @@ -158,6 +158,15 @@ function byte_convert($bytes, $decimals = 2) { return $formattedbytes; } +function remove_config_from_cache($name) { + $cache = new cache; + $cache->delete($name); + $hostname = trim(event_socket_request_cmd('api switchname')); + if($hostname){ + $cache->delete($name . ':' . $hostname); + } +} + function ListFiles($dir) { if($dh = opendir($dir)) { $files = Array();