From e1e45b9d4859099ef314dda9101d1d59d4a91917 Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 29 Jan 2013 11:07:57 +0100 Subject: profiles order --- misc/freeswitch/scripts/configuration.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/configuration.lua b/misc/freeswitch/scripts/configuration.lua index 062cf5d..18f4ef2 100644 --- a/misc/freeswitch/scripts/configuration.lua +++ b/misc/freeswitch/scripts/configuration.lua @@ -134,8 +134,15 @@ function conf_sofia(database) require 'configuration.sip' local domains = configuration.sip.Sip:new{ log = log, database = database}:domains(); - sofia_profiles_xml = ''; + local sofia_profiles = {}; for profile_name, index in pairs(sofia_ini.profiles) do + if tonumber(index) and tonumber(index) > 0 then + sofia_profiles[index] = profile_name; + end + end + + local sofia_profiles_xml = ''; + for index, profile_name in ipairs(sofia_profiles) do if tonumber(index) and tonumber(index) > 0 then sofia_profiles_xml = sofia_profiles_xml .. profile(database, sofia_ini, profile_name, tonumber(index), domains, local_node_id); end -- cgit v1.2.3 From bebf1d99a7a81ffd5cc3276acbf8b0317182a1af Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 29 Jan 2013 16:28:13 +0100 Subject: set variable function added --- misc/freeswitch/scripts/common/str.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/str.lua b/misc/freeswitch/scripts/common/str.lua index 793c191..72ff388 100644 --- a/misc/freeswitch/scripts/common/str.lua +++ b/misc/freeswitch/scripts/common/str.lua @@ -18,6 +18,23 @@ function try(array, arguments) return result; end + +function set(array, arguments, value) + local nop, arguments_count = arguments:gsub('%.', ''); + local structure = array; + arguments:gsub('([^%.]+)', function(entry) + if arguments_count <= 0 then + structure[entry] = value; + elseif type(structure[entry]) == 'table' then + structure = structure[entry]; + else + structure[entry] = {}; + structure = structure[entry]; + end + arguments_count = arguments_count - 1; + end); +end + -- to number function to_n(value) value = tostring(value):gsub('[^%d%.%+%-]', ''); -- cgit v1.2.3 From a9be92fdc62d55e6b6a8da80f0fe959ad90fa678 Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 29 Jan 2013 16:28:50 +0100 Subject: use str function set --- misc/freeswitch/scripts/dialplan/router.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/router.lua b/misc/freeswitch/scripts/dialplan/router.lua index cdcb58b..68989fa 100644 --- a/misc/freeswitch/scripts/dialplan/router.lua +++ b/misc/freeswitch/scripts/dialplan/router.lua @@ -143,7 +143,7 @@ function Router.route_match(self, route) if not common.str.blank(element.var_out) then local command, variable_name = common.str.partition(element.var_out, ':'); if not command or not variable_name or command == 'var' then - destination[element.var_out] = replacement; + common.str.set(destination, element.var_out, replacement); elseif command == 'chv' then destination.channel_variables[variable_name] = replacement; elseif command == 'hdr' then -- cgit v1.2.3 From 9928e509175ec6dbb9cd77aaeb06168c0de99d38 Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 29 Jan 2013 20:59:06 +0100 Subject: destination.number vs. destination.destination_number --- misc/freeswitch/scripts/dialplan/router.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/router.lua b/misc/freeswitch/scripts/dialplan/router.lua index 68989fa..0813a37 100644 --- a/misc/freeswitch/scripts/dialplan/router.lua +++ b/misc/freeswitch/scripts/dialplan/router.lua @@ -159,6 +159,7 @@ function Router.route_match(self, route) end if route_matches then + destination.number = destination.number or destination.destination_number; return destination; end; -- cgit v1.2.3 From 98e26f3e5b7bb7e282a25a7f7ce9af1294a3d3ed Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 30 Jan 2013 10:00:46 +0100 Subject: mysql vs. odbc driver issue --- misc/freeswitch/scripts/dialplan/acd.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/acd.lua b/misc/freeswitch/scripts/dialplan/acd.lua index f4b298e..5ed8979 100644 --- a/misc/freeswitch/scripts/dialplan/acd.lua +++ b/misc/freeswitch/scripts/dialplan/acd.lua @@ -194,7 +194,7 @@ function AutomaticCallDistributor.agents_available(self, strategy) local accounts = {} self.database:query(sql_query, function(entry) - if not entry.callstate then + if common.str.blank(entry.callstate) then table.insert(accounts, entry); end end); -- cgit v1.2.3 From 8e1b469080890f61c1dd5d20e6f4b31838e6b486 Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 30 Jan 2013 10:19:50 +0100 Subject: pass GS variables to node --- misc/freeswitch/scripts/dialplan/sip_call.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua index d1557e9..a235fb3 100644 --- a/misc/freeswitch/scripts/dialplan/sip_call.lua +++ b/misc/freeswitch/scripts/dialplan/sip_call.lua @@ -95,17 +95,22 @@ function SipCall.fork(self, destinations, arg ) table.insert(origination_variables, 'ignore_display_updates=true'); end - if not destination.node_local then + if not destination.node_local or destination.type == 'node' then require 'common.node' - local node = common.node.Node:new{ log = self.log, database = self.database }:find_by_id(destination.node_id); - if node then - table.insert(origination_variables, 'sip_h_X-GS_node_id=' .. self.caller.local_node_id); - table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/gateway/' .. node.record.name .. '/' .. destination.number); + local node = nil; + + if not destination.node_local then + node = common.node.Node:new{ log = self.log, database = self.database }:find_by_id(destination.node_id); + else + node = common.node.Node:new{ log = self.log, database = self.database }:find_by_id(destination.id); end - elseif destination.type == 'node' then - local node = common.node.Node:new{ log = self.log, database = self.database }:find_by_id(destination.id); if node then table.insert(origination_variables, 'sip_h_X-GS_node_id=' .. self.caller.local_node_id); + table.insert(origination_variables, 'sip_h_X-GS_account_uuid=' .. tostring(self.caller.account_uuid)); + table.insert(origination_variables, 'sip_h_X-GS_account_type' .. tostring(self.caller.account_type)); + table.insert(origination_variables, 'sip_h_X-GS_auth_account_type' .. tostring(self.caller.auth_account_type)); + table.insert(origination_variables, 'sip_h_X-GS_auth_account_uuid' .. tostring(self.caller.auth_account_uuid)); + table.insert(origination_variables, 'sip_h_X-GS_loop_count' .. tostring(self.caller.loop_count)); table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/gateway/' .. node.record.name .. '/' .. destination.number); end elseif destination.type == 'sipaccount' then @@ -169,11 +174,6 @@ function SipCall.fork(self, destinations, arg ) end self.caller:set_callee_id(arg.callee_id_number, arg.callee_id_name); - self.caller:set_header('X-GS_account_uuid', self.caller.account_uuid); - self.caller:set_header('X-GS_account_type', self.caller.account_type); - self.caller:set_header('X-GS_auth_account_type', self.caller.auth_account_type); - self.caller:set_header('X-GS_auth_account_uuid', self.caller.auth_account_uuid); - self.caller:set_header('X-GS_loop_count', self.caller.loop_count); self.caller:set_variable('call_timeout', arg.timeout ); self.log:info('FORK DIAL - destinations: ', #dial_strings, ', timeout: ', arg.timeout); -- cgit v1.2.3 From d959f30fbfde9d10811f04da6ab4891e2b94fdd7 Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 30 Jan 2013 10:27:40 +0100 Subject: equality sign --- misc/freeswitch/scripts/dialplan/sip_call.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua index a235fb3..806c72c 100644 --- a/misc/freeswitch/scripts/dialplan/sip_call.lua +++ b/misc/freeswitch/scripts/dialplan/sip_call.lua @@ -107,10 +107,10 @@ function SipCall.fork(self, destinations, arg ) if node then table.insert(origination_variables, 'sip_h_X-GS_node_id=' .. self.caller.local_node_id); table.insert(origination_variables, 'sip_h_X-GS_account_uuid=' .. tostring(self.caller.account_uuid)); - table.insert(origination_variables, 'sip_h_X-GS_account_type' .. tostring(self.caller.account_type)); - table.insert(origination_variables, 'sip_h_X-GS_auth_account_type' .. tostring(self.caller.auth_account_type)); - table.insert(origination_variables, 'sip_h_X-GS_auth_account_uuid' .. tostring(self.caller.auth_account_uuid)); - table.insert(origination_variables, 'sip_h_X-GS_loop_count' .. tostring(self.caller.loop_count)); + table.insert(origination_variables, 'sip_h_X-GS_account_type=' .. tostring(self.caller.account_type)); + table.insert(origination_variables, 'sip_h_X-GS_auth_account_type=' .. tostring(self.caller.auth_account_type)); + table.insert(origination_variables, 'sip_h_X-GS_auth_account_uuid=' .. tostring(self.caller.auth_account_uuid)); + table.insert(origination_variables, 'sip_h_X-GS_loop_count=' .. tostring(self.caller.loop_count)); table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/gateway/' .. node.record.name .. '/' .. destination.number); end elseif destination.type == 'sipaccount' then -- cgit v1.2.3 From 44337fb9a2bcbb8766e7c2b508cf2206afa09c05 Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 30 Jan 2013 15:57:07 +0100 Subject: route endpoints --- misc/freeswitch/scripts/dialplan/dialplan.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index ff4adc6..6e9bf68 100644 --- a/misc/freeswitch/scripts/dialplan/dialplan.lua +++ b/misc/freeswitch/scripts/dialplan/dialplan.lua @@ -814,11 +814,13 @@ function Dialplan.switch(self, destination) self.caller:set_callee_id(destination.callee_id_number, destination.callee_id_name); for index, route in ipairs(routes) do - if route.endpoint_type == 'hangup' then - return { continue = false, code = route.endpoint, phrase = route.phrase, cause = route.value } + if route.type == 'hangup' then + self.log:notice('SWITCH_HANGUP - code: ', route.code, ', phrase: ', route.phrase, ', cause: ', route.cause); + return { continue = false, code = route.code or '404', phrase = route.phrase, cause = route.cause } end - if route.endpoint_type == 'forward' then - return { continue = true, call_forwarding = { number = route.value, service = 'route', type = 'phonenumber' }} + if route.type == 'forward' then + self.log:notice('SWITCH_CALL_FORWARDING - number: ', route.number); + return { continue = true, call_forwarding = { number = route.number, service = 'route', type = 'phonenumber' }} end for key, value in pairs(route) do -- cgit v1.2.3 From a174fadb492cb2a88bd39dbc9b6d77955b878ccf Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 31 Jan 2013 11:22:13 +0100 Subject: control dtmf detection --- misc/freeswitch/scripts/dialplan/dialplan.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index 6e9bf68..a9b3a66 100644 --- a/misc/freeswitch/scripts/dialplan/dialplan.lua +++ b/misc/freeswitch/scripts/dialplan/dialplan.lua @@ -445,6 +445,8 @@ function Dialplan.dial(self, destination) send_ringing = ( self.send_ringing_to_gateways and self.caller.from_gateway ), bypass_media_network = self.config.parameters.bypass_media_network, update_callee_display = self.config.parameters.update_callee_display, + detect_dtmf_after_bridge_caller = self.detect_dtmf_after_bridge_caller, + detect_dtmf_after_bridge_callee = self.detect_dtmf_after_bridge_callee, } ); end -- cgit v1.2.3 From 09c5d6929a20bda3972c80ee62e9f4ad2f25e9cf Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 31 Jan 2013 11:26:35 +0100 Subject: clip_no_screening fixed --- misc/freeswitch/scripts/dialplan/dialplan.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index a9b3a66..55f714b 100644 --- a/misc/freeswitch/scripts/dialplan/dialplan.lua +++ b/misc/freeswitch/scripts/dialplan/dialplan.lua @@ -761,7 +761,7 @@ function Dialplan.switch(self, destination) elseif not common.str.blank(destination.number) then local result = { continue = false, code = 404, phrase = 'No route' } - local clip_no_screening = common.str.try(caller, 'account.record.clip_no_screening'); + local clip_no_screening = common.str.try(self.caller, 'account.record.clip_no_screening'); self.caller.caller_id_numbers = {} if not common.str.blank(clip_no_screening) then for index, number in ipairs(common.str.strip_to_a(clip_no_screening, ',')) do -- cgit v1.2.3 From b3e0cb6887d48374d528227230d0a5a2511f99df Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 31 Jan 2013 20:00:48 +0100 Subject: sip_copy_custom_headers affects Call-Info headers --- misc/freeswitch/scripts/dialplan/dialplan.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index 55f714b..72503e5 100644 --- a/misc/freeswitch/scripts/dialplan/dialplan.lua +++ b/misc/freeswitch/scripts/dialplan/dialplan.lua @@ -350,10 +350,10 @@ function Dialplan.set_caller_picture(self, entry_id, entry_type, image) require 'dialplan.user' local user = dialplan.user.User:new{ log = self.log, database = self.database }:find_by_id(entry_id); if user then - self.caller:set_variable('sip_h_Call-Info', '<' .. self.user_image_url .. '/' .. tonumber(entry_id) .. '/snom_caller_picture_' .. tostring(user.record.image) .. '>;purpose=icon'); + self.caller:export_variable('sip_h_Call-Info', '<' .. self.user_image_url .. '/' .. tonumber(entry_id) .. '/snom_caller_picture_' .. tostring(user.record.image) .. '>;purpose=icon'); end elseif entry_type == 'phonebookentry' and image then - self.caller:set_variable('sip_h_Call-Info', '<' .. self.phone_book_entry_image_url .. '/' .. tonumber(entry_id) .. '/snom_caller_picture_' .. tostring(image) .. '>;purpose=icon'); + self.caller:export_variable('sip_h_Call-Info', '<' .. self.phone_book_entry_image_url .. '/' .. tonumber(entry_id) .. '/snom_caller_picture_' .. tostring(image) .. '>;purpose=icon'); end end -- cgit v1.2.3 From 602c13c8d767bb0f723b66522f6b88bdbc263f81 Mon Sep 17 00:00:00 2001 From: spag Date: Sun, 3 Feb 2013 18:29:27 +0100 Subject: perimeter class added --- misc/freeswitch/scripts/common/perimeter.lua | 214 +++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 misc/freeswitch/scripts/common/perimeter.lua (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua new file mode 100644 index 0000000..d930514 --- /dev/null +++ b/misc/freeswitch/scripts/common/perimeter.lua @@ -0,0 +1,214 @@ +-- Gemeinschaft 5 module: perimeter class +-- (c) AMOOMA GmbH 2013 +-- + +module(...,package.seeall) + + +Perimeter = {} + + +function Perimeter.new(self, arg) + arg = arg or {} + object = arg.object or {} + setmetatable(object, self); + self.__index = self; + self.log = arg.log; + self.class = 'perimeter' + self.database = arg.database; + self.domain = arg.domain; + self.sources = {}; + + self.checks_available = { + check_frequency = self.check_frequency, + check_username_scan = self.check_username_scan, + check_bad_headers = self.check_bad_headers, + }; + + return object; +end + + +function Perimeter.setup(self, event) + require 'common.configuration_table'; + local config = common.configuration_table.get(self.database, 'perimeter'); + + self.contact_count_threshold = 10; + self.contact_span_threshold = 2; + self.name_changes_threshold = 2; + self.blacklist_file = '/var/opt/gemeinschaft/firewall/blacklist'; + self.blacklist_file_comment = '# PERIMETER_BAN - points: {points}, generated: {date}'; + self.blacklist_file_entry = '{received_ip} udp 5060'; + self.ban_command = 'sudo /sbin/service shorewall refresh'; + self.ban_threshold = 20; + self.ban_tries = 1; + + if config and config.general then + for key, value in pairs(config.general) do + self[key] = value; + end + end + + self.checks = config.checks; + self.bad_headers = config.bad_headers; + + self.log:info('[perimeter] PERIMETER - setup perimeter defense'); +end + + +function Perimeter.record_load(self, event) + if not self.sources[event.key] then + self.sources[event.key] = { + contact_first = event.timestamp, + contact_last = event.timestamp, + contact_count = 0, + span_contact_count = 0, + span_start = event.timestamp, + points = 0, + banned = 0, + } + end + + return self.sources[event.key]; +end + + +function Perimeter.format_date(self, value) + local epoch = tonumber(tostring(value/1000000):match('^(%d-)%.')); + return os.date('%Y-%m-%d %X', tonumber(epoch)) .. '.' .. (value-(epoch*1000000)); +end + + +function Perimeter.record_update(self, event) + event.record.contact_last = event.timestamp; + event.record.contact_count = event.record.contact_count + 1; + event.record.points = event.points or event.record.points; + event.record.span_start = event.span_start or event.record.span_start; + event.record.span_contact_count = (event.span_contact_count or event.record.span_contact_count) + 1; + event.record.users = event.users or event.record.users; +end + + +function Perimeter.check(self, event) + event.record = self:record_load(event); + -- self.log:debug('[', event.sequence, '] PERIMETER_CHECK - received: ', event.received_ip, ':', event.received_port, ', contacts: ', event.record.contact_count, ', since: ', self:format_date(event.record.contact_first), ', points: ', event.record.points); + + if event.record.banned <= self.ban_tries then + for check_name, check_points in pairs(self.checks) do + if self.checks_available[check_name] then + local result = self.checks_available[check_name](self, event); + if tonumber(result) then + event.points = (event.points or event.record.points) + result * check_points; + end + end + end + end + + if (event.points or event.record.points) > self.ban_threshold and event.record.banned <= self.ban_tries then + if event.record.banned > 0 and event.record.banned == self.ban_tries then + self.log:warning('[', event.sequence, '] PERIMETER_BAN_FUTILE - points: ', event.points,', event: ', event.class, ', ip: ', event.received_ip, ', to: ', event.to_user, '@', event.to_host); + else + self.log:notice('[', event.sequence, '] PERIMETER_BAN - threshold reached: ', event.points,', event: ', event.class, ', ip: ', event.received_ip, ', to: ', event.to_user, '@', event.to_host); + if event.record.banned == 0 then + self:append_blacklist_file(event); + end + self:execute_ban(event); + end + + event.record.banned = event.record.banned + 1; + event.span_start = event.timestamp; + event.span_contact_count = 0; + event.points = 0; + end + + self:record_update(event); +end + + +function Perimeter.check_frequency(self, event) + if event.record.span_contact_count >= self.contact_count_threshold then + self.log:info('[', event.sequence, '] PERIMETER_FREQUENCY_CHECK - contacts: ', event.record.span_contact_count, ' in < ', (event.timestamp - event.record.span_start)/1000000, ' sec, threshold: ', self.contact_count_threshold, ' in ', self.contact_span_threshold, ' sec'); + event.span_contact_count = 0; + event.span_start = event.timestamp; + return 1; + elseif (event.timestamp - event.record.span_start) > (self.contact_span_threshold * 1000000) then + event.span_contact_count = 0; + event.span_start = event.timestamp; + end +end + + +function Perimeter.check_username_scan(self, event) + if not event.to_user then + return; + end + + if not event.record.users then + event.users = { event.to_user }; + return; + end + + if #event.record.users >= self.name_changes_threshold then + self.log:info('[', event.sequence, '] PERIMETER_USER_SCAN - user names: ', #event.record.users, ', threshold: ', self.name_changes_threshold); + event.users = {}; + return 1; + else + for index=1, #event.record.users do + if event.record.users[index] == tostring(event.to_user) then + return + end + end + + if not event.users then + event.users = event.record.users or {}; + end + table.insert(event.users, tostring(event.to_user)); + end +end + + +function Perimeter.check_bad_headers(self, event) + local points = nil; + for name, pattern in pairs(self.bad_headers) do + local success, result = pcall(string.find, event[name], pattern); + if success and result then + self.log:info('[', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern); + points = (points or 0) + 1; + end + end + + return points; +end + + +function Perimeter.append_blacklist_file(self, event) + local blacklist = io.open(self.blacklist_file, 'a'); + if not blacklist then + self.log:error('[', event.sequence, '] PERIMETER_APPEND_BLACKLIST - could not open file: ', self.blacklist_file); + return false; + end + + event.date = self:format_date(event.timestamp); + + if self.blacklist_file_comment then + blacklist:write(self:expand_variables(self.blacklist_file_comment, event), '\n'); + end + + self.log:debug('[', event.sequence, '] PERIMETER_APPEND_BLACKLIST - ip: ', event.received_ip); + blacklist:write(self:expand_variables(self.blacklist_file_entry, event), '\n'); + blacklist:close(); +end + + +function Perimeter.execute_ban(self, event) + local command = self:expand_variables(self.ban_command, event); + self.log:debug('[', event.sequence, '] PERIMETER_EXECUTE_BAN - ip: ', event.received_ip, ', command: ', command); + local result = os.execute(command); +end + + +function Perimeter.expand_variables(self, line, variables) + return (line:gsub('{([%a%d%._]+)}', function(captured) + return variables[captured] or ''; + end)) +end -- cgit v1.2.3 From b7368f4471cb4be3ea81f1ade5962e039ce4ef9f Mon Sep 17 00:00:00 2001 From: spag Date: Sun, 3 Feb 2013 18:29:46 +0100 Subject: perimeter defense class added --- .../freeswitch/scripts/event/perimeter_defense.lua | 77 ++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 misc/freeswitch/scripts/event/perimeter_defense.lua (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/event/perimeter_defense.lua b/misc/freeswitch/scripts/event/perimeter_defense.lua new file mode 100644 index 0000000..c93eb13 --- /dev/null +++ b/misc/freeswitch/scripts/event/perimeter_defense.lua @@ -0,0 +1,77 @@ +-- Gemeinschaft 5 module: perimeter defense event handler class +-- (c) AMOOMA GmbH 2013 +-- + +module(...,package.seeall) + +function handler_class() + return PerimeterDefense +end + +PerimeterDefense = {} + +function PerimeterDefense.new(self, arg) + arg = arg or {} + object = arg.object or {} + setmetatable(object, self); + self.__index = self; + self.log = arg.log; + self.class = 'perimeterdefense' + self.database = arg.database; + self.domain = arg.domain; + + require 'common.perimeter'; + self.perimeter = common.perimeter.Perimeter:new(arg); + self.perimeter:setup(); + + return object; +end + + +function PerimeterDefense.event_handlers(self) + return { CUSTOM = { + ['sofia::pre_register'] = self.sofia_pre_register, + ['sofia::register_attempt'] = self.sofia_register_attempt, + ['sofia::register_failure'] = self.sofia_register_failure, + } } +end + + +function PerimeterDefense.to_record(self, event, class) + return { + class = class, + key = event:getHeader('network-ip'), + sequence = tonumber(event:getHeader('Event-Sequence')), + timestamp = tonumber(event:getHeader('Event-Date-Timestamp')), + received_ip = event:getHeader('network-ip'), + received_port = event:getHeader('network-port'), + from_user = event:getHeader('from-user'), + from_host = event:getHeader('from-host'), + to_user = event:getHeader('to-user'), + to_host = event:getHeader('to-host'), + user_agent = event:getHeader('user-agent'), + user_agent = event:getHeader('user-agent'), + username = event:getHeader('username'), + realm = event:getHeader('realm'), + auth_result = event:getHeader('auth-result'), + contact = event:getHeader('contact'), + }; +end + + +function PerimeterDefense.sofia_pre_register(self, event) + local record = self:to_record(event, 'pre_register'); + self.perimeter:check(record); +end + + +function PerimeterDefense.sofia_register_attempt(self, event) + local record = self:to_record(event, 'register_attempt'); + self.perimeter:check(record); +end + + +function PerimeterDefense.sofia_register_failure(self, event) + local record = self:to_record(event, 'register_failure'); + self.perimeter:check(record); +end -- cgit v1.2.3 From 7eaa39014d7934e8cc19001dc0da95095a73a632 Mon Sep 17 00:00:00 2001 From: spag Date: Sun, 3 Feb 2013 18:32:55 +0100 Subject: old perimeter version removed --- misc/freeswitch/scripts/event/perimeter.lua | 107 ---------------------------- 1 file changed, 107 deletions(-) delete mode 100644 misc/freeswitch/scripts/event/perimeter.lua (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/event/perimeter.lua b/misc/freeswitch/scripts/event/perimeter.lua deleted file mode 100644 index 5bbb032..0000000 --- a/misc/freeswitch/scripts/event/perimeter.lua +++ /dev/null @@ -1,107 +0,0 @@ --- Gemeinschaft 5 module: cdr event handler class --- (c) AMOOMA GmbH 2012-2013 --- - -module(...,package.seeall) - - -function handler_class() - return Perimeter -end - - - -Perimeter = {} - -MALICIOUS_CONTACT_COUNT = 20; -MALICIOUS_CONTACT_TIME_SPAN = 2; -BAN_FUTILE = 2; - -function Perimeter.new(self, arg) - arg = arg or {} - object = arg.object or {} - setmetatable(object, self); - self.__index = self; - self.log = arg.log; - self.class = 'cdrsave' - self.database = arg.database; - self.domain = arg.domain; - - self.ip_address_table = {} - self:init(); - - return object; -end - - -function Perimeter.event_handlers(self) - return { CUSTOM = { ['sofia::pre_register'] = self.sofia_pre_register } } -end - - -function Perimeter.init(self) - require 'common.configuration_table'; - local config = common.configuration_table.get(self.database, 'perimeter'); - if config and config.general then - self.malicious_contact_count = tonumber(config.general.malicious_contact_count) or MALICIOUS_CONTACT_COUNT; - self.malicious_contact_time_span = tonumber(config.general.malicious_contact_time_span) or MALICIOUS_CONTACT_TIME_SPAN; - self.ban_futile = tonumber(config.general.ban_futile) or BAN_FUTILE; - self.execute = config.general.execute; - end - - self.log:info('[perimeter] PERIMETER - setup perimeter defense - config: ', self.malicious_contact_count, '/', self.malicious_contact_time_span, ', execute: ', self.execute); -end - - -function Perimeter.sofia_pre_register(self, event) - local ip_address = event:getHeader('network-ip'); - self:check_ip(ip_address); -end - - -function Perimeter.check_ip(self, ip_address) - local event_time = os.time(); - - if not self.ip_address_table[ip_address] then - self.ip_address_table[ip_address] = { last_contact = event_time, contact_count = 0, start_stamp = event_time, banned = 0 } - end - - local ip_record = self.ip_address_table[ip_address]; - ip_record.last_contact = event_time; - ip_record.contact_count = ip_record.contact_count + 1; - - if ip_record.contact_count > MALICIOUS_CONTACT_COUNT then - if (event_time - ip_record.start_stamp) <= MALICIOUS_CONTACT_TIME_SPAN then - self.log:warning('[', ip_address, '] PERIMETER - too many registration attempts'); - ip_record.start_stamp = event_time; - ip_record.contact_count = 0; - if ip_record.banned < BAN_FUTILE then - ip_record.banned = ip_record.banned + 1; - self:ban_ip(ip_address); - else - self.log:error('[', ip_address, '] PERIMETER - ban futile'); - end - end - end -end - - -function Perimeter.ban_ip(self, ip_address) - self.ip_address = ip_address; - - if self.execute then - local command = self:expand_variables(self.execute); - self.log:debug('[', ip_address, '] PERIMETER - execute: ', command); - local result = os.execute(command); - if tostring(result) == '0' then - self.log:warning('[', ip_address, '] PERIMETER - IP banned'); - end - end -end - - -function Perimeter.expand_variables(self, line) - return (line:gsub('{([%a%d_-]+)}', function(captured) - return self[captured]; - end)) -end -- cgit v1.2.3 From 077234ab170416d8aac9bf5887aa2093b2d9c5c9 Mon Sep 17 00:00:00 2001 From: spag Date: Sun, 3 Feb 2013 19:31:18 +0100 Subject: better logging --- misc/freeswitch/scripts/common/perimeter.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua index d930514..5623b40 100644 --- a/misc/freeswitch/scripts/common/perimeter.lua +++ b/misc/freeswitch/scripts/common/perimeter.lua @@ -91,7 +91,7 @@ end function Perimeter.check(self, event) event.record = self:record_load(event); - -- self.log:debug('[', event.sequence, '] PERIMETER_CHECK - received: ', event.received_ip, ':', event.received_port, ', contacts: ', event.record.contact_count, ', since: ', self:format_date(event.record.contact_first), ', points: ', event.record.points); + -- self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_CHECK - received: ', event.received_ip, ':', event.received_port, ', contacts: ', event.record.contact_count, ', since: ', self:format_date(event.record.contact_first), ', points: ', event.record.points); if event.record.banned <= self.ban_tries then for check_name, check_points in pairs(self.checks) do @@ -106,9 +106,9 @@ function Perimeter.check(self, event) if (event.points or event.record.points) > self.ban_threshold and event.record.banned <= self.ban_tries then if event.record.banned > 0 and event.record.banned == self.ban_tries then - self.log:warning('[', event.sequence, '] PERIMETER_BAN_FUTILE - points: ', event.points,', event: ', event.class, ', ip: ', event.received_ip, ', to: ', event.to_user, '@', event.to_host); + self.log:warning('[', event.key, '/', event.sequence, '] PERIMETER_BAN_FUTILE - points: ', event.points,', event: ', event.class, ', from: ', event.from_user, '@', event.from_host, ', to: ', event.to_user, '@', event.to_host); else - self.log:notice('[', event.sequence, '] PERIMETER_BAN - threshold reached: ', event.points,', event: ', event.class, ', ip: ', event.received_ip, ', to: ', event.to_user, '@', event.to_host); + self.log:notice('[', event.key, '/', event.sequence, '] PERIMETER_BAN - threshold reached: ', event.points,', event: ', event.class, ', from: ', event.from_user, '@', event.from_host, ', to: ', event.to_user, '@', event.to_host); if event.record.banned == 0 then self:append_blacklist_file(event); end @@ -127,7 +127,7 @@ end function Perimeter.check_frequency(self, event) if event.record.span_contact_count >= self.contact_count_threshold then - self.log:info('[', event.sequence, '] PERIMETER_FREQUENCY_CHECK - contacts: ', event.record.span_contact_count, ' in < ', (event.timestamp - event.record.span_start)/1000000, ' sec, threshold: ', self.contact_count_threshold, ' in ', self.contact_span_threshold, ' sec'); + self.log:info('[', event.key, '/', event.sequence, '] PERIMETER_FREQUENCY_CHECK - contacts: ', event.record.span_contact_count, ' in < ', (event.timestamp - event.record.span_start)/1000000, ' sec, threshold: ', self.contact_count_threshold, ' in ', self.contact_span_threshold, ' sec'); event.span_contact_count = 0; event.span_start = event.timestamp; return 1; @@ -149,7 +149,7 @@ function Perimeter.check_username_scan(self, event) end if #event.record.users >= self.name_changes_threshold then - self.log:info('[', event.sequence, '] PERIMETER_USER_SCAN - user names: ', #event.record.users, ', threshold: ', self.name_changes_threshold); + self.log:info('[', event.key, '/', event.sequence, '] PERIMETER_USER_SCAN - user names: ', #event.record.users, ', threshold: ', self.name_changes_threshold); event.users = {}; return 1; else @@ -172,7 +172,7 @@ function Perimeter.check_bad_headers(self, event) for name, pattern in pairs(self.bad_headers) do local success, result = pcall(string.find, event[name], pattern); if success and result then - self.log:info('[', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern); + self.log:info('[', event.key, '/', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern); points = (points or 0) + 1; end end @@ -184,7 +184,7 @@ end function Perimeter.append_blacklist_file(self, event) local blacklist = io.open(self.blacklist_file, 'a'); if not blacklist then - self.log:error('[', event.sequence, '] PERIMETER_APPEND_BLACKLIST - could not open file: ', self.blacklist_file); + self.log:error('[', event.key, '/', event.sequence, '] PERIMETER_APPEND_BLACKLIST - could not open file: ', self.blacklist_file); return false; end @@ -194,7 +194,7 @@ function Perimeter.append_blacklist_file(self, event) blacklist:write(self:expand_variables(self.blacklist_file_comment, event), '\n'); end - self.log:debug('[', event.sequence, '] PERIMETER_APPEND_BLACKLIST - ip: ', event.received_ip); + self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_APPEND_BLACKLIST - file: ', self.blacklist_file); blacklist:write(self:expand_variables(self.blacklist_file_entry, event), '\n'); blacklist:close(); end @@ -202,7 +202,7 @@ end function Perimeter.execute_ban(self, event) local command = self:expand_variables(self.ban_command, event); - self.log:debug('[', event.sequence, '] PERIMETER_EXECUTE_BAN - ip: ', event.received_ip, ', command: ', command); + self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_EXECUTE_BAN - command: ', command); local result = os.execute(command); end -- cgit v1.2.3 From f1ccee494495e4149d0b892743b0d60612d8d790 Mon Sep 17 00:00:00 2001 From: spag Date: Sun, 3 Feb 2013 20:04:16 +0100 Subject: reset username list after successful registration --- misc/freeswitch/scripts/common/perimeter.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua index 5623b40..5de86bf 100644 --- a/misc/freeswitch/scripts/common/perimeter.lua +++ b/misc/freeswitch/scripts/common/perimeter.lua @@ -143,7 +143,7 @@ function Perimeter.check_username_scan(self, event) return; end - if not event.record.users then + if not event.record.users or tostring(event.auth_result) == 'SUCCESS' or tostring(event.auth_result) == 'RENEWED' then event.users = { event.to_user }; return; end -- cgit v1.2.3 From 0db4c7250feab288018d42cbd5c7d12657d60e3a Mon Sep 17 00:00:00 2001 From: spag Date: Mon, 4 Feb 2013 09:39:42 +0100 Subject: check calls --- misc/freeswitch/scripts/common/perimeter.lua | 23 ++++++---- .../freeswitch/scripts/event/perimeter_defense.lua | 51 +++++++++++++++++++--- 2 files changed, 59 insertions(+), 15 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua index 5de86bf..0670fee 100644 --- a/misc/freeswitch/scripts/common/perimeter.lua +++ b/misc/freeswitch/scripts/common/perimeter.lua @@ -42,6 +42,8 @@ function Perimeter.setup(self, event) self.ban_command = 'sudo /sbin/service shorewall refresh'; self.ban_threshold = 20; self.ban_tries = 1; + self.checks = { register = {}, call = {} }; + self.bad_headers = { register = {}, call = {} }; if config and config.general then for key, value in pairs(config.general) do @@ -49,8 +51,10 @@ function Perimeter.setup(self, event) end end - self.checks = config.checks; - self.bad_headers = config.bad_headers; + self.checks.register = config.checks_register or {}; + self.checks.call = config.checks_call or {}; + self.bad_headers.register = config.bad_headers_register; + self.bad_headers.call = config.bad_headers_call; self.log:info('[perimeter] PERIMETER - setup perimeter defense'); end @@ -66,7 +70,7 @@ function Perimeter.record_load(self, event) span_start = event.timestamp, points = 0, banned = 0, - } + }; end return self.sources[event.key]; @@ -90,11 +94,14 @@ end function Perimeter.check(self, event) - event.record = self:record_load(event); - -- self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_CHECK - received: ', event.received_ip, ':', event.received_port, ', contacts: ', event.record.contact_count, ', since: ', self:format_date(event.record.contact_first), ', points: ', event.record.points); - + if not event or not event.key then + self.log:warning('[perimeter] PERIMETER_CHECK - no event/key'); + return; + end + + event.record = self:record_load(event); if event.record.banned <= self.ban_tries then - for check_name, check_points in pairs(self.checks) do + for check_name, check_points in pairs(self.checks[event.action]) do if self.checks_available[check_name] then local result = self.checks_available[check_name](self, event); if tonumber(result) then @@ -169,7 +176,7 @@ end function Perimeter.check_bad_headers(self, event) local points = nil; - for name, pattern in pairs(self.bad_headers) do + for name, pattern in pairs(self.bad_headers[event.action]) do local success, result = pcall(string.find, event[name], pattern); if success and result then self.log:info('[', event.key, '/', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern); diff --git a/misc/freeswitch/scripts/event/perimeter_defense.lua b/misc/freeswitch/scripts/event/perimeter_defense.lua index c93eb13..acdfa8d 100644 --- a/misc/freeswitch/scripts/event/perimeter_defense.lua +++ b/misc/freeswitch/scripts/event/perimeter_defense.lua @@ -29,16 +29,20 @@ end function PerimeterDefense.event_handlers(self) - return { CUSTOM = { + return { + CUSTOM = { ['sofia::pre_register'] = self.sofia_pre_register, ['sofia::register_attempt'] = self.sofia_register_attempt, ['sofia::register_failure'] = self.sofia_register_failure, - } } + }, + CHANNEL_HANGUP = { [true] = self.channel_hangup }, + }; end -function PerimeterDefense.to_record(self, event, class) +function PerimeterDefense.to_register_record(self, event, class) return { + action = 'register', class = class, key = event:getHeader('network-ip'), sequence = tonumber(event:getHeader('Event-Sequence')), @@ -50,7 +54,6 @@ function PerimeterDefense.to_record(self, event, class) to_user = event:getHeader('to-user'), to_host = event:getHeader('to-host'), user_agent = event:getHeader('user-agent'), - user_agent = event:getHeader('user-agent'), username = event:getHeader('username'), realm = event:getHeader('realm'), auth_result = event:getHeader('auth-result'), @@ -59,19 +62,53 @@ function PerimeterDefense.to_record(self, event, class) end +function PerimeterDefense.to_call_record(self, event, class) + return { + action = 'call', + class = class, + key = event:getHeader('Caller-Network-Addr'), + sequence = tonumber(event:getHeader('Event-Sequence')), + timestamp = tonumber(event:getHeader('Event-Date-Timestamp')), + received_ip = event:getHeader('Caller-Network-Addr'), + received_port = event:getHeader('variable_sip_network_port'), + hangup_cause = event:getHeader('Hangup-Cause'), + endpoint_disposition = event:getHeader('variable_endpoint_disposition'), + direction = event:getHeader('Call-Direction'), + destination_number = event:getHeader('Caller-Destination-Number'); + caller_id_name = event:getHeader('Caller-Caller-ID-Name'); + caller_id_number = event:getHeader('Caller-Caller-ID-Number'); + from_user = event:getHeader('variable_sip_from_user'), + from_host = event:getHeader('variable_sip_from_host'), + to_user = event:getHeader('variable_sip_to_user'), + to_host = event:getHeader('variable_sip_to_host'), + req_user = event:getHeader('variable_sip_req_user'), + req_host = event:getHeader('variable_sip_req_host'), + user_agent = event:getHeader('variable_sip_user_agent'), + username = event:getHeader('Caller-Username'), + contact = event:getHeader('variable_sip_contact_uri'), + }; +end + + function PerimeterDefense.sofia_pre_register(self, event) - local record = self:to_record(event, 'pre_register'); + local record = self:to_register_record(event, 'pre_register'); self.perimeter:check(record); end function PerimeterDefense.sofia_register_attempt(self, event) - local record = self:to_record(event, 'register_attempt'); + local record = self:to_register_record(event, 'register_attempt'); self.perimeter:check(record); end function PerimeterDefense.sofia_register_failure(self, event) - local record = self:to_record(event, 'register_failure'); + local record = self:to_register_record(event, 'register_failure'); + self.perimeter:check(record); +end + + +function PerimeterDefense.channel_hangup(self, event) + local record = self:to_call_record(event, 'channel_hangup'); self.perimeter:check(record); end -- cgit v1.2.3 From 4594ac1559c6ecd534834b41b31d61c281d3401d Mon Sep 17 00:00:00 2001 From: spag Date: Mon, 4 Feb 2013 10:01:40 +0100 Subject: expand variables --- misc/freeswitch/scripts/common/perimeter.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua index 0670fee..d1eecd1 100644 --- a/misc/freeswitch/scripts/common/perimeter.lua +++ b/misc/freeswitch/scripts/common/perimeter.lua @@ -177,6 +177,7 @@ end function Perimeter.check_bad_headers(self, event) local points = nil; for name, pattern in pairs(self.bad_headers[event.action]) do + pattern = self:expand_variables(pattern, event); local success, result = pcall(string.find, event[name], pattern); if success and result then self.log:info('[', event.key, '/', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern); -- cgit v1.2.3 From 242470bdb4fa67780e7467c6889b7869dff05d1c Mon Sep 17 00:00:00 2001 From: spag Date: Mon, 4 Feb 2013 13:10:52 +0100 Subject: better logging --- misc/freeswitch/scripts/common/perimeter.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua index d1eecd1..de3f993 100644 --- a/misc/freeswitch/scripts/common/perimeter.lua +++ b/misc/freeswitch/scripts/common/perimeter.lua @@ -111,6 +111,14 @@ function Perimeter.check(self, event) end end + if tonumber(event.points) and event.points < 0 then + event.points = 0; + end + + if event.points then + self.log:info('[', event.key, '/', event.sequence, '] PERIMETER suspicion rising - points: ', event.points,', ', event.action, '=', event.class, ', from: ', event.from_user, '@', event.from_host, ', to: ', event.to_user, '@', event.to_host, ', user_agent: ', event.user_agent); + end + if (event.points or event.record.points) > self.ban_threshold and event.record.banned <= self.ban_tries then if event.record.banned > 0 and event.record.banned == self.ban_tries then self.log:warning('[', event.key, '/', event.sequence, '] PERIMETER_BAN_FUTILE - points: ', event.points,', event: ', event.class, ', from: ', event.from_user, '@', event.from_host, ', to: ', event.to_user, '@', event.to_host); @@ -134,7 +142,7 @@ end function Perimeter.check_frequency(self, event) if event.record.span_contact_count >= self.contact_count_threshold then - self.log:info('[', event.key, '/', event.sequence, '] PERIMETER_FREQUENCY_CHECK - contacts: ', event.record.span_contact_count, ' in < ', (event.timestamp - event.record.span_start)/1000000, ' sec, threshold: ', self.contact_count_threshold, ' in ', self.contact_span_threshold, ' sec'); + self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_FREQUENCY_CHECK - contacts: ', event.record.span_contact_count, ' in < ', (event.timestamp - event.record.span_start)/1000000, ' sec, threshold: ', self.contact_count_threshold, ' in ', self.contact_span_threshold, ' sec'); event.span_contact_count = 0; event.span_start = event.timestamp; return 1; @@ -156,7 +164,7 @@ function Perimeter.check_username_scan(self, event) end if #event.record.users >= self.name_changes_threshold then - self.log:info('[', event.key, '/', event.sequence, '] PERIMETER_USER_SCAN - user names: ', #event.record.users, ', threshold: ', self.name_changes_threshold); + self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_USER_SCAN - user names: ', #event.record.users, ', threshold: ', self.name_changes_threshold); event.users = {}; return 1; else @@ -180,7 +188,7 @@ function Perimeter.check_bad_headers(self, event) pattern = self:expand_variables(pattern, event); local success, result = pcall(string.find, event[name], pattern); if success and result then - self.log:info('[', event.key, '/', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern); + self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_BAD_HEADERS - ', name, '=', event[name], ' ~= ', pattern); points = (points or 0) + 1; end end -- cgit v1.2.3 From e13f041741fd3a44f407b623da0274d9748c5c54 Mon Sep 17 00:00:00 2001 From: spag Date: Mon, 4 Feb 2013 16:54:43 +0100 Subject: hunt group routing fixed --- misc/freeswitch/scripts/dialplan/hunt_group.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/hunt_group.lua b/misc/freeswitch/scripts/dialplan/hunt_group.lua index 2c73bf8..fa3c05b 100644 --- a/misc/freeswitch/scripts/dialplan/hunt_group.lua +++ b/misc/freeswitch/scripts/dialplan/hunt_group.lua @@ -98,6 +98,18 @@ function HuntGroup.run(self, dialplan_object, caller, destination) self.log:info('HUNTGROUP ', self.record.id, ' - name: ', self.record.name, ', strategy: ', self.record.strategy,', members: ', #hunt_group_members); + local clip_no_screening = common.str.try(caller, 'account.record.clip_no_screening'); + caller.caller_id_numbers = {} + if not common.str.blank(clip_no_screening) then + for index, number in ipairs(common.str.strip_to_a(clip_no_screening, ',')) do + table.insert(caller.caller_id_numbers, number); + end + end + for index, number in ipairs(caller.caller_phone_numbers) do + table.insert(caller.caller_id_numbers, number); + end + self.log:info('CALLER_ID_NUMBERS - clir: ', caller.clir, ', numbers: ', table.concat(caller.caller_id_numbers, ',')); + local save_destination = caller.destination; local destinations = {} @@ -172,6 +184,7 @@ function HuntGroup.run(self, dialplan_object, caller, destination) self.log:info('HUNTGROUP ', self.record.id, ' - all members busy'); run_queue = false; end + caller:sleep(500); end else if forwarding_destination then -- cgit v1.2.3 From e7968236a06c1be8c3ac23b5e63b7840659a334d Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 5 Feb 2013 11:27:14 +0100 Subject: added restart capablity --- misc/freeswitch/scripts/event_manager.lua | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/event_manager.lua b/misc/freeswitch/scripts/event_manager.lua index 1e61baf..3d558e5 100644 --- a/misc/freeswitch/scripts/event_manager.lua +++ b/misc/freeswitch/scripts/event_manager.lua @@ -7,12 +7,12 @@ require "common.log" local log = common.log.Log:new() log.prefix = "#E# " -log:info('[event] EVENT_MANAGER start'); +log:info('[event] EVENT_MANAGER_LOADER start'); require 'common.database' local database = common.database.Database:new{ log = log }:connect(); if not database:connected() then - log:error('[event] EVENT_MANAGER - cannot connect to Gemeinschaft database'); + log:error('[event] EVENT_MANAGER_LOADER - cannot connect to Gemeinschaft database'); return; end @@ -23,16 +23,21 @@ local domain = '127.0.0.1'; if domains[1] then domain = domains[1]['host']; else - log:error('[event] EVENT_MANAGER - No SIP domains found!'); + log:error('[event] EVENT_MANAGER_LOADER - No SIP domains found!'); end -require 'event.event' -local event_manager = event.event.EventManager:new{ log = log, database = database, domain = domain } -event_manager:run(); +freeswitch.setGlobalVariable('gs_event_manager', 'true'); +while freeswitch.getGlobalVariable('gs_event_manager') ~= 'false' do + package.loaded['event.event'] = nil; + local manager_class = require('event.event'); + local event_manager = manager_class.EventManager:new{ log = log, database = database, domain = domain } + freeswitch.setGlobalVariable('gs_event_manager', 'true'); + event_manager:run(); +end -- ensure database handle is released on exit if database then database:release(); end -log:info('[event] EVENT_MANAGER exit'); +log:info('[event] EVENT_MANAGER_LOADER exit'); -- cgit v1.2.3 From 676eab5ba9c2a542b9a86e1d9665cdcd7ece9cac Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 5 Feb 2013 11:28:18 +0100 Subject: reload modules from files --- misc/freeswitch/scripts/event/event.lua | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/event/event.lua b/misc/freeswitch/scripts/event/event.lua index 08d8bfe..c98b534 100644 --- a/misc/freeswitch/scripts/event/event.lua +++ b/misc/freeswitch/scripts/event/event.lua @@ -27,18 +27,26 @@ function EventManager.register(self) end -function EventManager.load_event_modules(self) - require 'common.configuration_table' - self.config = common.configuration_table.get(self.database, 'events'); +function EventManager.load_event_modules(self, modules) + local event_modules = {}; + + for module_name, index in pairs(modules) do + if tonumber(index) and index > 0 then + event_modules[index] = module_name; + self.log:debug('[event] EVENT_MANAGER - enabled handler module: ', module_name); + else + self.log:debug('[event] EVENT_MANAGER - disabled handler module: ', module_name); + end + end - return self.config.modules; + return event_modules; end function EventManager.load_event_handlers(self, event_modules) event_handlers = {} - - for event_module_name, index in pairs(event_modules) do + for index, event_module_name in ipairs(event_modules) do + package.loaded['event.' .. event_module_name] = nil; event_module = require('event.' .. event_module_name); if event_module then self.log:info('[event] EVENT_MANAGER - loading handler module: ', event_module_name); @@ -71,8 +79,12 @@ end function EventManager.run(self) + require 'common.configuration_table' + self.config = common.configuration_table.get(self.database, 'events'); + + local event_modules = self:load_event_modules(self.config.modules); + self.log:info('[event] EVENT_MANAGER_START - handler modules: ', #event_modules); - local event_modules = self:load_event_modules(); local event_handlers = self:load_event_handlers(event_modules); if not event_handlers then @@ -104,4 +116,7 @@ function EventManager.run(self) end end end + + self.consumer = nil; + self.log:info('[event] EVENT_MANAGER_EXIT - action: ', freeswitch.getGlobalVariable('gs_event_manager')); end -- cgit v1.2.3 From 11c0c5bb51d58a6d33848806a29a9a4e0d241cbd Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 5 Feb 2013 14:02:56 +0100 Subject: dump_variables event module added --- misc/freeswitch/scripts/event/dump_variables.lua | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 misc/freeswitch/scripts/event/dump_variables.lua (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/event/dump_variables.lua b/misc/freeswitch/scripts/event/dump_variables.lua new file mode 100644 index 0000000..96eb8f7 --- /dev/null +++ b/misc/freeswitch/scripts/event/dump_variables.lua @@ -0,0 +1,52 @@ +-- Gemeinschaft 5 module: dump_variables event handler class +-- (c) AMOOMA GmbH 2012-2013 +-- + +module(...,package.seeall) + + +function handler_class() + return DumpVariables +end + + +DumpVariables = {} + + +function DumpVariables.new(self, arg) + arg = arg or {} + object = arg.object or {} + setmetatable(object, self); + self.__index = self; + self.log = arg.log; + self.class = 'DumpVariables' + self.dump_file = arg.file or '/var/log/freeswitch/variables'; + + return object; +end + + +function DumpVariables.event_handlers(self) + return { CHANNEL_CREATE = { [true] = self.channel_data } } +end + + +function DumpVariables.channel_data(self, event) + local sequence = event:getHeader('Event-Sequence'); + local direction = event:getHeader('Call-Direction'); + + if not direction or direction ~= 'inbound' then + return; + end + + local file = io.open(self.dump_file, 'w'); + if not file then + self.log:error('[', event.sequence, '] DUMP_VARIABLES - could not open file for writing: ', self.dump_file); + return; + end + + self.log:debug('[', event.sequence, '] DUMP_VARIABLES - dumping channel data to: ', self.dump_file); + + file:write(event:serialize(), '\n'); + file:close(); +end -- cgit v1.2.3 From e22d3f5cb2791b70a9fcfe6befdeca233772688d Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 5 Feb 2013 14:30:30 +0100 Subject: preserve event consumer --- misc/freeswitch/scripts/event/event.lua | 6 ++++-- misc/freeswitch/scripts/event_manager.lua | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/event/event.lua b/misc/freeswitch/scripts/event/event.lua index c98b534..652fc48 100644 --- a/misc/freeswitch/scripts/event/event.lua +++ b/misc/freeswitch/scripts/event/event.lua @@ -16,13 +16,16 @@ function EventManager.new(self, arg) self.class = 'eventmanager' self.database = arg.database; self.domain = arg.domain; + self.consumer = arg.consumer; return object; end function EventManager.register(self) - self.consumer = freeswitch.EventConsumer('all'); + if not self.consumer then + self.consumer = freeswitch.EventConsumer('all'); + end return (self.consumer ~= nil); end @@ -117,6 +120,5 @@ function EventManager.run(self) end end - self.consumer = nil; self.log:info('[event] EVENT_MANAGER_EXIT - action: ', freeswitch.getGlobalVariable('gs_event_manager')); end diff --git a/misc/freeswitch/scripts/event_manager.lua b/misc/freeswitch/scripts/event_manager.lua index 3d558e5..3991f8f 100644 --- a/misc/freeswitch/scripts/event_manager.lua +++ b/misc/freeswitch/scripts/event_manager.lua @@ -26,13 +26,15 @@ else log:error('[event] EVENT_MANAGER_LOADER - No SIP domains found!'); end +local event_consumer = nil; freeswitch.setGlobalVariable('gs_event_manager', 'true'); while freeswitch.getGlobalVariable('gs_event_manager') ~= 'false' do package.loaded['event.event'] = nil; local manager_class = require('event.event'); - local event_manager = manager_class.EventManager:new{ log = log, database = database, domain = domain } + local event_manager = manager_class.EventManager:new{ log = log, database = database, domain = domain, consumer = event_consumer }; freeswitch.setGlobalVariable('gs_event_manager', 'true'); event_manager:run(); + event_consumer = event_manager.consumer; end -- ensure database handle is released on exit -- cgit v1.2.3 From 9a140ffba197b1b09350509169c229abc82ecec0 Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 6 Feb 2013 10:05:31 +0100 Subject: sip based phone resync fixed --- misc/freeswitch/scripts/dialplan/functions.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua index 2ca51c8..61c86aa 100644 --- a/misc/freeswitch/scripts/dialplan/functions.lua +++ b/misc/freeswitch/scripts/dialplan/functions.lua @@ -264,7 +264,7 @@ function Functions.account_node_change(self, caller) -- resync caller phones for index, phone_caller in ipairs(caller_phones) do - local result = phone_caller:resync{ auth_name = caller_sip_account.auth_name, domain = caller.domain }; + local result = phone_caller:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host }; self.log:info('NODE_CHANGE - resync phone - mac: ', phone_caller.record.mac_address, ', ip_address: ', phone_caller.record.ip_address, ', result: ', result); end @@ -374,13 +374,13 @@ function Functions.user_login(self, caller, number, pin) -- resync destination phones for index, phone_destination in ipairs(destination_phones) do - local result = phone_destination:resync{ auth_name = destination_sip_account.auth_name, domain = caller.domain_local }; + local result = phone_destination:resync{ auth_name = destination_sip_account.record.auth_name, domain = destination_sip_account.record.host }; self.log:info('LOGIN - resync destination phone - mac: ', phone_destination.record.mac_address, ', ip_address: ', phone_destination.record.ip_address, ', result: ', result); end -- resync caller phones for index, phone_caller in ipairs(caller_phones) do - local result = phone_caller:resync{ auth_name = caller_sip_account.auth_name, domain = caller.domain }; + local result = phone_caller:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host }; self.log:info('LOGIN - resync caller phone - mac: ', phone_caller.record.mac_address, ', ip_address: ', phone_caller.record.ip_address, ', result: ', result); end @@ -426,7 +426,7 @@ function Functions.user_logout(self, caller) -- resync caller phones for index, phone_caller in ipairs(caller_phones) do - local result = phone_caller:resync{ auth_name = caller_sip_account.auth_name, domain = caller.domain }; + local result = phone_caller:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host }; self.log:info('LOGIN - resync caller phone - mac: ', phone_caller.record.mac_address, ', ip_address: ', phone_caller.record.ip_address, ', result: ', result); end -- cgit v1.2.3 From 64912b6266ae449a2052f51e769ce59950b70da8 Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 6 Feb 2013 10:27:46 +0100 Subject: try to resync if phone not found --- misc/freeswitch/scripts/dialplan/functions.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua index 61c86aa..32fad78 100644 --- a/misc/freeswitch/scripts/dialplan/functions.lua +++ b/misc/freeswitch/scripts/dialplan/functions.lua @@ -302,6 +302,7 @@ function Functions.user_login(self, caller, number, pin) if not caller_phone then self.log:notice('LOGIN - caller phone not found or not hot-deskable'); + local result = phone_class:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host }; return { continue = false, code = 403, phrase = 'Phone not hot-deskable', no_cdr = true } end @@ -409,8 +410,9 @@ function Functions.user_logout(self, caller) local caller_phones = phone_class:find_all_hot_deskable_by_account(caller_sip_account.id); - if caller_phones == 0 then + if #caller_phones == 0 then self.log:notice('LOGOUT - caller phones not found or not hot-deskable'); + local result = phone_class:resync{ auth_name = caller_sip_account.record.auth_name, domain = caller_sip_account.record.host }; return { continue = false, code = 403, phrase = 'Phone not hot-deskable', no_cdr = true } end -- cgit v1.2.3 From 500ef315442a7fad3647f9b58ae59ab70c45c4b8 Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 6 Feb 2013 10:28:11 +0100 Subject: try to resync if phone model not found --- misc/freeswitch/scripts/phones/phone.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/phones/phone.lua b/misc/freeswitch/scripts/phones/phone.lua index 6da20f0..57997ba 100644 --- a/misc/freeswitch/scripts/phones/phone.lua +++ b/misc/freeswitch/scripts/phones/phone.lua @@ -115,8 +115,9 @@ end function Phone.resync(self, arg) if not self.model then - self.log:notice('PHONE_RESYNC - unsupported phone model'); - return false; + self.log:notice('PHONE_RESYNC phone model not found - trying Snom resync'); + require 'phones.snom' + return phones.snom.Snom:new{ log = self.log }:resync(arg); end arg.ip_address = arg.ip_address or self.record.ip_address; -- cgit v1.2.3 From 120d1ddc2b4213dd30b0a863ea65be4e0decf404 Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 6 Feb 2013 15:11:11 +0100 Subject: logging --- misc/freeswitch/scripts/send_fax.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/send_fax.lua b/misc/freeswitch/scripts/send_fax.lua index 9b6ffce..4898cb8 100644 --- a/misc/freeswitch/scripts/send_fax.lua +++ b/misc/freeswitch/scripts/send_fax.lua @@ -6,9 +6,9 @@ local FAX_FILE_PATH = "/opt/GS5/public/uploads/fax_document/tiff/"; local FAX_ANSWERING_TIMEOUT = 20; -- Set logger -require "common.log" +require 'common.log' local log = common.log.Log:new() -log.prefix = "### [sendfax] " +log.prefix = '#F# [sendfax] ' local document_id = argv[1]; @@ -16,12 +16,12 @@ require 'common.database' local database = common.database.Database:new{ log = log }:connect(); if not database:connected() then - log:error('cannot connect to Gemeinschaft database'); + log:error('FAX_SEND - cannot connect to Gemeinschaft database'); return end if not tonumber(document_id) then - log:error('document id not specified'); + log:error('FAX_SEND - document id not specified'); return end @@ -32,7 +32,7 @@ local fax_class = dialplan.fax.Fax:new(defaults); local fax_document = fax_class:find_document_by_id(document_id); if not fax_document then - log:error('document ' .. document_id .. ' not found'); + log:error('FAX_SEND - document ' .. document_id .. ' not found'); return end @@ -45,14 +45,14 @@ end local fax_account = fax_class:find_by_id(fax_document.fax_account_id); if not fax_account then - log:error('fax account ' .. fax_document.fax_account_id .. ' not found'); + log:error('FAX_SEND - fax account ' .. fax_document.fax_account_id .. ' not found'); return end local destination_number = fax_class:destination_number(document_id); if not destination_number or tostring(destination_number) == '' then - log:error('destination number not found'); + log:error('FAX_SEND - destination number not found'); return end -- cgit v1.2.3 From 98b822e2d139ad2c2779ce292f597d25ff6f936c Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 6 Feb 2013 15:12:02 +0100 Subject: persistent database connection --- misc/freeswitch/scripts/fax_daemon.lua | 43 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/fax_daemon.lua b/misc/freeswitch/scripts/fax_daemon.lua index 94d343a..0784890 100644 --- a/misc/freeswitch/scripts/fax_daemon.lua +++ b/misc/freeswitch/scripts/fax_daemon.lua @@ -5,38 +5,37 @@ local MAIN_LOOP_SLEEP_TIME = 30; -- Set logger -require "common.log" +require 'common.log' local log = common.log.Log:new() -log.prefix = "### [faxdaemon] " +log.prefix = '#F# [faxdaemon] ' -log:debug('Starting fax daemon'); +log:info('FAX_DAEMON start'); -local database = nil; -local api = freeswitch.API(); +require 'common.database' +local database = common.database.Database:new{ log = log }:connect(); +if not database:connected() then + log:error('FAX_DAEMON - cannot connect to Gemeinschaft database'); + return; +end +local api = freeswitch.API(); +require 'dialplan.fax' freeswitch.setGlobalVariable('gs_fax_daemon', 'true'); + while freeswitch.getGlobalVariable("gs_fax_daemon") == 'true' do - require 'common.database' - local database = common.database.Database:new{ log = log }:connect(); - - if not database:connected() then - log:error("connection to Gemeinschaft database lost - retry in " .. MAIN_LOOP_SLEEP_TIME .. " seconds") - else - require 'dialplan.fax' - local fax_documents = dialplan.fax.Fax:new{log=log, database=database}:queued_for_sending(); - - for key, fax_document in pairs(fax_documents) do - if table.getn(fax_document.destination_numbers) > 0 and tonumber(fax_document.retry_counter) > 0 then - log:debug('FAX_DAEMON_LOOP - fax_document=', fax_document.id, '/', fax_document.uuid, ', number: ' .. fax_document.destination_numbers[1]); - local result = api:executeString('luarun send_fax.lua ' .. fax_document.id); - end + local fax_documents = dialplan.fax.Fax:new{log=log, database=database}:queued_for_sending(); + + for key, fax_document in pairs(fax_documents) do + if table.getn(fax_document.destination_numbers) > 0 and tonumber(fax_document.retry_counter) > 0 then + log:debug('FAX_DAEMON_LOOP - fax_document=', fax_document.id, '/', fax_document.uuid, ', number: ' .. fax_document.destination_numbers[1]); + local result = api:executeString('luarun send_fax.lua ' .. fax_document.id); end end - database:release(); - + if freeswitch.getGlobalVariable("gs_fax_daemon") == 'true' then freeswitch.msleep(MAIN_LOOP_SLEEP_TIME * 1000); end end -log:debug('Exiting fax daemon'); +database:release(); +log:info('FAX_DAEMON exit'); -- cgit v1.2.3 From 87c71a3b6f33d28b03a8bde95cc3f921400dc8ae Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 6 Feb 2013 15:51:27 +0100 Subject: module-directory added --- misc/freeswitch/conf/freeswitch.xml | 1 + 1 file changed, 1 insertion(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/conf/freeswitch.xml b/misc/freeswitch/conf/freeswitch.xml index fd6ab67..2ecb618 100644 --- a/misc/freeswitch/conf/freeswitch.xml +++ b/misc/freeswitch/conf/freeswitch.xml @@ -639,6 +639,7 @@ + -- cgit v1.2.3 From 5016e204cd2026b11aef79e3a3aa10907aa9e739 Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 6 Feb 2013 18:50:50 +0100 Subject: increase verbosity when request fails --- misc/freeswitch/scripts/http_request.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/http_request.lua b/misc/freeswitch/scripts/http_request.lua index 1d6f791..a74b4d8 100644 --- a/misc/freeswitch/scripts/http_request.lua +++ b/misc/freeswitch/scripts/http_request.lua @@ -29,7 +29,7 @@ end local success, result, response_headers = http.request{url = url, headers = headers }; -if success then +if success and tostring(result) == '200' then log:debug('HTTP_REQUEST - url: ', url, ', auth: ', tostring(headers.Authorization ~= nil), ', result: ', result); else log:notice('HTTP_REQUEST - url: ', url, ', auth: ', tostring(headers.Authorization ~= nil), ', result: ', result); -- cgit v1.2.3 From df663953901e5d4192cb38e56f5b6e27d6daf3fb Mon Sep 17 00:00:00 2001 From: spag Date: Wed, 6 Feb 2013 18:53:46 +0100 Subject: inband dtmf code detection --- misc/freeswitch/scripts/dialplan/sip_call.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua index 806c72c..1b5c6e1 100644 --- a/misc/freeswitch/scripts/dialplan/sip_call.lua +++ b/misc/freeswitch/scripts/dialplan/sip_call.lua @@ -195,6 +195,12 @@ function SipCall.fork(self, destinations, arg ) fork_index = tonumber(session_callee:getVariable('gs_fork_index')) or 0; local destination = destinations[fork_index]; + if arg.detect_dtmf_after_bridge_caller then + session:execute('start_dtmf'); + end + if arg.detect_dtmf_after_bridge_callee then + session_callee:execute('start_dtmf'); + end if arg.bypass_media_network then local callee_uuid = session_callee:get_uuid(); -- cgit v1.2.3 From 9890298bbdfd909ab1fe5f35e53c9652d1371acd Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 7 Feb 2013 14:23:26 +0100 Subject: cache routing tables --- misc/freeswitch/scripts/dialplan/router.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/router.lua b/misc/freeswitch/scripts/dialplan/router.lua index 0813a37..bda80a7 100644 --- a/misc/freeswitch/scripts/dialplan/router.lua +++ b/misc/freeswitch/scripts/dialplan/router.lua @@ -18,11 +18,16 @@ function Router.new(self, arg) self.routes = arg.routes or {}; self.caller = arg.caller; self.variables = arg.variables or {}; + self.routing_tables = {}; return object; end -function Router.read_table(self, table_name) +function Router.read_table(self, table_name, force_reload) + if not force_reload and self.routing_tables[table_name] then + return self.routing_tables[table_name]; + end + local routing_table = {}; local sql_query = 'SELECT * \ @@ -48,6 +53,8 @@ function Router.read_table(self, table_name) }); end); + self.routing_tables[table_name] = routing_table; + return routing_table; end -- cgit v1.2.3 From fa243f49c53d05c8b5510cd6ba062517cbc952cf Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 7 Feb 2013 15:11:53 +0100 Subject: dtmf handling class added --- misc/freeswitch/scripts/dialplan/dtmf.lua | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 misc/freeswitch/scripts/dialplan/dtmf.lua (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/dtmf.lua b/misc/freeswitch/scripts/dialplan/dtmf.lua new file mode 100644 index 0000000..0094d05 --- /dev/null +++ b/misc/freeswitch/scripts/dialplan/dtmf.lua @@ -0,0 +1,69 @@ +-- Gemeinschaft 5 module: dtmf class +-- (c) AMOOMA GmbH 2013 +-- + +module(...,package.seeall) + +Dtmf = {} + +-- create dtmf object +function Dtmf.new(self, arg) + arg = arg or {} + object = arg.object or {} + setmetatable(object, self); + self.__index = self; + self.class = 'Dtmf'; + self.log = arg.log; + self.bleg = arg.bleg + self.digit_timeout = arg.digit_timeout or 5; + self.router = arg.router; + + return object; +end + + +function Dtmf.detect(self, caller, sequence, digit, duration, calee) + local timestamp = os.time(); + if timestamp - sequence.updated > self.digit_timeout then + sequence.digits = digit; + else + sequence.digits = sequence.digits .. digit; + end + + caller.dtmf_digits = sequence.digits; + + if calee then + self.log:info('DTMF_RECEIVER callee - digit: [', digit, '][', duration, '], sequence: ', sequence.digits); + else + self.log:info('DTMF_RECEIVER caller - digit: [', digit, '][', duration, '], sequence: ', sequence.digits); + end + + local route = self.router:route_run('dtmf', true); + sequence.updated = timestamp; + + if not route then + return; + end + + if route.type == 'dialplanfunction' or route.type == 'phonenumber' or route.type == 'unknown' then + self:transfer(caller, route.destination_number, calee) + else + self.log:notice('DTMF_RECEIVER - unhandled destination: ', route.type, '=', route.id); + end +end + + +function Dtmf.transfer(self, caller, destination, calee) + require 'common.fapi' + local fapi = common.fapi.FApi:new{ log = log }; + local callee_uuid = caller:to_s('bridge_to'); + + self.log:notice('DTMF_RECEIVER_TRANSFER - destination: ', destination, ', uuid: ', caller.uuid, ', callee_uuid: ', callee_uuid, ', callee_initiated: ', calee); + if calee then + caller:execute('transfer', destination); + fapi:execute('uuid_kill', callee_uuid); + else + fapi:execute('uuid_transfer', callee_uuid .. ' ' .. destination); + caller.session:hangup(); + end +end -- cgit v1.2.3 From 3ea1b7bf7b808a88c6d5f05ea9c5071a5fcfb082 Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 7 Feb 2013 15:12:49 +0100 Subject: rudimentary call parking added --- misc/freeswitch/scripts/dialplan/functions.lua | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua index 32fad78..4430be1 100644 --- a/misc/freeswitch/scripts/dialplan/functions.lua +++ b/misc/freeswitch/scripts/dialplan/functions.lua @@ -111,6 +111,8 @@ function Functions.dialplan_function(self, caller, dialed_number) result = "+" .. tostring(parameters[3]); elseif fid == "hangup" then result = self:hangup(caller, parameters[3], parameters[4]); + elseif fid == "park" then + result = self:park(caller, parameters[3]); end return result; @@ -911,3 +913,9 @@ function Functions.hangup(self, caller, code, phrase) self.log:info("FUNCTION_HANGUP code: ", code, ', phrase: ', phrase); return { continue = false, code = code, phrase = phrase:gsub('_', ' '), no_cdr = true } end + +function Functions.park(self, caller, lot) + self.log:info("FUNCTION_PARK lot: ", lot); + caller:execute("valet_park", 'valet_lot ' .. lot); + return { continue = false, code = 200, phrase = 'OK', no_cdr = true } +end -- cgit v1.2.3 From 5aefe7bb21d7b18f5653db439c61f7540e04e4e5 Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 7 Feb 2013 23:57:45 +0100 Subject: log level --- misc/freeswitch/scripts/dialplan/dtmf.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/dtmf.lua b/misc/freeswitch/scripts/dialplan/dtmf.lua index 0094d05..4dbd35f 100644 --- a/misc/freeswitch/scripts/dialplan/dtmf.lua +++ b/misc/freeswitch/scripts/dialplan/dtmf.lua @@ -33,9 +33,9 @@ function Dtmf.detect(self, caller, sequence, digit, duration, calee) caller.dtmf_digits = sequence.digits; if calee then - self.log:info('DTMF_RECEIVER callee - digit: [', digit, '][', duration, '], sequence: ', sequence.digits); + self.log:debug('DTMF_RECEIVER callee - digit: [', digit, '][', duration, '], sequence: ', sequence.digits); else - self.log:info('DTMF_RECEIVER caller - digit: [', digit, '][', duration, '], sequence: ', sequence.digits); + self.log:debug('DTMF_RECEIVER caller - digit: [', digit, '][', duration, '], sequence: ', sequence.digits); end local route = self.router:route_run('dtmf', true); -- cgit v1.2.3 From 5be2f0dca65491915f97e1ddd334e8d08a3603a1 Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 7 Feb 2013 23:58:24 +0100 Subject: set input callback --- misc/freeswitch/scripts/dialplan/sip_call.lua | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua index 1b5c6e1..61d4f76 100644 --- a/misc/freeswitch/scripts/dialplan/sip_call.lua +++ b/misc/freeswitch/scripts/dialplan/sip_call.lua @@ -232,10 +232,15 @@ function SipCall.fork(self, destinations, arg ) self.caller:set_variable('gs_destination_id', destination.id); self.caller:set_variable('gs_destination_uuid', destination.uuid); + if arg.detect_dtmf_after_bridge_callee then + session_callee:setInputCallback('input_call_back_callee', 'session_callee'); + end + self.log:info('FORK ', fork_index, ' BRIDGE - destination: ', destination.type, '=', destination.id, '/', destination.uuid,'@', destination.node_id, ', number: ', destination.number, ', dial_time: ', os.time() - start_time); + freeswitch.bridge(self.caller.session, session_callee); self:wait_hangup(self.caller.session, session_callee); end -- cgit v1.2.3 From ef562b407c14e9b145e500e64424ccd5bd31dbb4 Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 7 Feb 2013 23:59:27 +0100 Subject: caller input callback --- misc/freeswitch/scripts/dialplan_default.lua | 37 +++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/dialplan_default.lua b/misc/freeswitch/scripts/dialplan_default.lua index 7caff57..8fb9057 100644 --- a/misc/freeswitch/scripts/dialplan_default.lua +++ b/misc/freeswitch/scripts/dialplan_default.lua @@ -8,13 +8,28 @@ function hangup_hook_caller(s, status, arg) if tostring(status) == 'transfer' then if start_caller and start_caller.destination then log:info('CALL_TRANSFERRED - destination was: ', start_caller.destination.type, '=', start_caller.destination.id,', number: ' .. tostring(start_caller.destination.number) .. ', to: ' .. start_caller:to_s('sip_refer_to')); - start_caller.auth_account = start_dialplan:object_find(start_caller.destination.type, start_caller.destination.id); + start_caller.auth_account = start_caller.dialplan:object_find(start_caller.destination.type, start_caller.destination.id); start_caller.forwarding_number = start_caller.destination.number; start_caller.forwarding_service = 'transfer'; end end end +function input_call_back_caller(s, object_type, object_data, arg) + if object_type == 'dtmf' then + require 'dialplan.dtmf' + local dtmf = dialplan.dtmf.Dtmf:new{ log = log, router = dtmf_router }:detect(start_caller, start_caller.dtmf, object_data.digit, object_data.duration); + end +end + +function input_call_back_callee(s, object_type, object_data, arg) + if object_type == 'dtmf' then + require 'dialplan.dtmf' + local dtmf = dialplan.dtmf.Dtmf:new{ log = log, router = dtmf_router }:detect(start_caller, start_caller.dtmf_callee, object_data.digit, object_data.duration, true); + end +end + + -- initialize logging require 'common.log' log = common.log.Log:new{ prefix = '### [' .. session:get_uuid() .. '] ' }; @@ -36,8 +51,17 @@ require 'dialplan.dialplan' local start_dialplan = dialplan.dialplan.Dialplan:new{ log = log, caller = start_caller, database = database }; start_dialplan:configuration_read(); +start_caller.dialplan = start_dialplan; start_caller.local_node_id = start_dialplan.node_id; start_caller:init_channel_variables(); +start_caller.dtmf = { + updated = os.time(), + digits = ''; +}; +start_caller.dtmf_callee = { + updated = os.time(), + digits = ''; +}; if start_dialplan.config.parameters.dump_variables then start_caller:execute('info', 'notice'); @@ -72,6 +96,17 @@ if start_caller.from_node then else start_destination = { type = 'unknown' } start_caller.session:setHangupHook('hangup_hook_caller', 'destination_number'); + + require 'dialplan.router' + dtmf_router = dialplan.router.Router:new{ log = log, database = database, caller = start_caller, variables = start_caller }; + start_dialplan.dtmf_detection = #dtmf_router:read_table('dtmf') > 0; + + if start_dialplan.dtmf_detection then + start_dialplan.detect_dtmf_after_bridge_caller = true; + start_dialplan.detect_dtmf_after_bridge_callee = true; + start_caller.session:setInputCallback('input_call_back_caller', 'start_dialplan'); + end + start_dialplan:run(start_destination); end -- cgit v1.2.3 From 72e22a8aaf7ad212ed888b7d5a7c94d1c9cbd6b2 Mon Sep 17 00:00:00 2001 From: spag Date: Fri, 8 Feb 2013 23:25:20 +0100 Subject: return result --- misc/freeswitch/scripts/common/fapi.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/fapi.lua b/misc/freeswitch/scripts/common/fapi.lua index 5b96633..b749a69 100644 --- a/misc/freeswitch/scripts/common/fapi.lua +++ b/misc/freeswitch/scripts/common/fapi.lua @@ -32,8 +32,10 @@ function FApi.return_result(self, result, positive, negative, unspecified) return negative; elseif result:match('^+OK') then return positive; - else + elseif type(unspecified) ~= 'nil' then return unspecified; + else + return result; end end @@ -75,6 +77,7 @@ function FApi.create_uuid(self, uuid) end function FApi.execute(self, function_name, function_parameters) + function_parameters = function_parameters or ''; local result = self.fs_api:execute(function_name, function_parameters); return self:return_result(result, true); end -- cgit v1.2.3 From d84e7208ae138e5e85a13286739e4364e02446e9 Mon Sep 17 00:00:00 2001 From: spag Date: Sun, 10 Feb 2013 17:00:42 +0100 Subject: database update or create added --- misc/freeswitch/scripts/common/database.lua | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/database.lua b/misc/freeswitch/scripts/common/database.lua index 1f39135..345f69d 100644 --- a/misc/freeswitch/scripts/common/database.lua +++ b/misc/freeswitch/scripts/common/database.lua @@ -16,6 +16,7 @@ function Database.new(self, arg) self.class = 'database'; self.log = arg.log; self.conn = nil; + self.ignore_on_update = arg.ignore_on_update or {}; return object; end @@ -71,6 +72,45 @@ function Database.last_insert_id(self) end +function Database.insert_or_update(self, db_table, record, use_on_update) + ignore_on_update = ignore_on_update or self.ignore_on_update; + local record_sql_create = {}; + local record_sql_update = {}; + + for key, value in pairs(record) do + if ignore_on_update[key] ~= false then + table.insert(record_sql_update, self:key_value(key, value)); + end + table.insert(record_sql_create, self:key_value(key, value)); + end + + local sql_query = 'INSERT INTO `' .. db_table .. '` SET ' .. table.concat(record_sql_create, ', ') .. ' ON DUPLICATE KEY UPDATE ' .. table.concat(record_sql_update, ', '); + + return self:query(sql_query); +end + + +function Database.key_value(self, key, value) + return self:escape(key, '`') .. ' = ' .. self:escape(value, '"'); +end + + +function Database.escape(self, value, str_quotes) + str_quotes = str_quotes or ''; + if type(value) == 'boolean' then + return tostring(value):upper(); + elseif type(value) == 'number' then + return tostring(value); + elseif type(value) == 'string' then + return str_quotes .. value:gsub('"', '\\"'):gsub("'", "\\'") .. str_quotes; + elseif type(value) == 'table' and value.raw then + return tostring(value[1]); + else + return 'NULL'; + end +end + + function Database.release(self) if self.conn then self.conn:release(); -- cgit v1.2.3 From 0225c74753b20bd62e535cfcc2f7bec23266798e Mon Sep 17 00:00:00 2001 From: spag Date: Sun, 10 Feb 2013 17:02:05 +0100 Subject: intruder class added --- misc/freeswitch/scripts/common/intruder.lua | 51 +++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 misc/freeswitch/scripts/common/intruder.lua (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/intruder.lua b/misc/freeswitch/scripts/common/intruder.lua new file mode 100644 index 0000000..083ec37 --- /dev/null +++ b/misc/freeswitch/scripts/common/intruder.lua @@ -0,0 +1,51 @@ +-- Gemeinschaft 5 module: intruder class +-- (c) AMOOMA GmbH 2013 +-- + +module(...,package.seeall) + + +Intruder = {} + + +function Intruder.new(self, arg) + arg = arg or {} + object = arg.object or {} + setmetatable(object, self); + self.__index = self; + self.log = arg.log; + self.class = 'intruder' + self.database = arg.database; + + return object; +end + + +function Intruder.update_blacklist(self, event) + local intruder_record = { + list_type = 'blacklist', + key = event.key, + points = event.points, + bans = event.record.banned, + contact_ip = event.received_ip, + contact_port = event.received_port, + contact_count = event.record.contact_count + 1, + contact_last = { 'FROM_UNIXTIME(' .. tostring(math.floor(event.timestamp/1000000)) .. ')', raw = true }, + contacts_per_second = event.contacts_per_second, + contacts_per_second_max = event.contacts_per_second_max, + user_agent = event.user_agent, + to_user = event.to_user, + comment = 'Permimeter', + created_at = {'NOW()', raw = true }, + updated_at = {'NOW()', raw = true }, + }; + + if tonumber(event.ban_time) then + intruder_record.ban_last = { 'FROM_UNIXTIME(' .. event.ban_time .. ')', raw = true }; + end + if tonumber(event.ban_end) then + intruder_record.ban_end = { 'FROM_UNIXTIME(' .. event.ban_end .. ')', raw = true }; + end + + self.database:insert_or_update('intruders', intruder_record, { created_at = false, comment = false }); +end -- cgit v1.2.3 From af16d6106e5b4c81a8b167397c0fffd728762fa0 Mon Sep 17 00:00:00 2001 From: spag Date: Sun, 10 Feb 2013 17:02:55 +0100 Subject: update intruder --- misc/freeswitch/scripts/common/perimeter.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/perimeter.lua b/misc/freeswitch/scripts/common/perimeter.lua index de3f993..0815d33 100644 --- a/misc/freeswitch/scripts/common/perimeter.lua +++ b/misc/freeswitch/scripts/common/perimeter.lua @@ -128,6 +128,7 @@ function Perimeter.check(self, event) self:append_blacklist_file(event); end self:execute_ban(event); + event.ban_time = os.time(); end event.record.banned = event.record.banned + 1; @@ -136,6 +137,10 @@ function Perimeter.check(self, event) event.points = 0; end + if event.points then + self:update_intruder(event); + end + self:record_update(event); end @@ -145,6 +150,7 @@ function Perimeter.check_frequency(self, event) self.log:debug('[', event.key, '/', event.sequence, '] PERIMETER_FREQUENCY_CHECK - contacts: ', event.record.span_contact_count, ' in < ', (event.timestamp - event.record.span_start)/1000000, ' sec, threshold: ', self.contact_count_threshold, ' in ', self.contact_span_threshold, ' sec'); event.span_contact_count = 0; event.span_start = event.timestamp; + event.contacts_per_second = event.record.span_contact_count / ((event.timestamp - event.record.span_start)/1000000) return 1; elseif (event.timestamp - event.record.span_start) > (self.contact_span_threshold * 1000000) then event.span_contact_count = 0; @@ -222,6 +228,11 @@ function Perimeter.execute_ban(self, event) local result = os.execute(command); end +function Perimeter.update_intruder(self, event) + require 'common.intruder'; + local result = common.intruder.Intruder:new{ log = self.log, database = self.database }:update_blacklist(event); +end + function Perimeter.expand_variables(self, line, variables) return (line:gsub('{([%a%d%._]+)}', function(captured) -- cgit v1.2.3 From 3d817bef265f70b147455db4b0fb5e1ca3c0d379 Mon Sep 17 00:00:00 2001 From: Julian Pawlowski Date: Tue, 12 Feb 2013 00:21:15 +0100 Subject: add german language settings --- misc/freeswitch/conf/freeswitch.xml | 465 ++++++++++++++++++++++++++++++++++++ 1 file changed, 465 insertions(+) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/conf/freeswitch.xml b/misc/freeswitch/conf/freeswitch.xml index 2ecb618..a7eb44d 100644 --- a/misc/freeswitch/conf/freeswitch.xml +++ b/misc/freeswitch/conf/freeswitch.xml @@ -466,6 +466,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -632,6 +1096,7 @@ + -- cgit v1.2.3 From d1145ad9d4f495d7416ed97e0dd3c17365990323 Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 12 Feb 2013 08:19:00 +0100 Subject: create profile template --- misc/freeswitch/scripts/configuration.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/configuration.lua b/misc/freeswitch/scripts/configuration.lua index 18f4ef2..9847cc9 100644 --- a/misc/freeswitch/scripts/configuration.lua +++ b/misc/freeswitch/scripts/configuration.lua @@ -63,7 +63,12 @@ function profile(database, sofia_ini, profile_name, index, domains, node_id) require 'configuration.simple_xml' local xml = configuration.simple_xml.SimpleXml:new(); - local parameters = sofia_ini['profile:' .. profile_name]; + local profile_template = sofia_ini['profile'] or {}; + local parameters = sofia_ini['profile:' .. profile_name] or {}; + + for key, value in pairs(profile_template) do + parameters[key] = parameters[key] or value; + end if not parameters then log:error('SOFIA_PROFILE ', index,' - name: ', profile_name, ' - no parameters'); -- cgit v1.2.3 From 0ece4561627130eceb83deef4e5c2df00ec1664e Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 12 Feb 2013 09:41:55 +0100 Subject: support for registrations to non default profiles --- misc/freeswitch/scripts/common/sip_account.lua | 8 ++++-- misc/freeswitch/scripts/configuration.lua | 2 +- misc/freeswitch/scripts/dialplan/sip_call.lua | 36 +++++++++++++++----------- 3 files changed, 28 insertions(+), 18 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/scripts/common/sip_account.lua b/misc/freeswitch/scripts/common/sip_account.lua index 8dd432b..d023f20 100644 --- a/misc/freeswitch/scripts/common/sip_account.lua +++ b/misc/freeswitch/scripts/common/sip_account.lua @@ -38,8 +38,12 @@ function SipAccount.find_by_sql(self, where) `a`.`sip_accountable_id`, \ `a`.`hotdeskable`, \ `a`.`gs_node_id`, \ - `b`.`host` \ - FROM `sip_accounts` `a` JOIN `sip_domains` `b` ON `a`.`sip_domain_id` = `b`.`id` \ + `b`.`host`, \ + `c`.`sip_host`, \ + `c`.`profile_name` \ + FROM `sip_accounts` `a` \ + JOIN `sip_domains` `b` ON `a`.`sip_domain_id` = `b`.`id` \ + LEFT JOIN `sip_registrations` `c` ON `a`.`auth_name` = `c`.`sip_user` \ WHERE ' .. where .. ' LIMIT 1'; local sip_account = nil; diff --git a/misc/freeswitch/scripts/configuration.lua b/misc/freeswitch/scripts/configuration.lua index 9847cc9..75d0df3 100644 --- a/misc/freeswitch/scripts/configuration.lua +++ b/misc/freeswitch/scripts/configuration.lua @@ -415,7 +415,7 @@ function directory_sip_account(database) end else require 'common.sip_account' - local sip_account = common.sip_account.SipAccount:new{ log = log, database = database}:find_by_auth_name(auth_name, domain); + local sip_account = common.sip_account.SipAccount:new{ log = log, database = database}:find_by_auth_name(auth_name); require 'common.configuration_table' local user_parameters = common.configuration_table.get(database, 'sip_accounts', 'parameters'); diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua index 61d4f76..b56f1b2 100644 --- a/misc/freeswitch/scripts/dialplan/sip_call.lua +++ b/misc/freeswitch/scripts/dialplan/sip_call.lua @@ -116,23 +116,29 @@ function SipCall.fork(self, destinations, arg ) elseif destination.type == 'sipaccount' then local callee_id_params = ''; local sip_account = sip_account_class:find_by_id(destination.id); - local call_waiting = self:call_waiting_busy(sip_account); - if not call_waiting then - destinations[index].numbers = sip_account:phone_numbers(); + if not sip_account then + self.log:notice('FORK - sip_account not found - sip_account=', destination.id); + elseif common.str.blank(sip_account.record.profile_name) or common.str.blank(sip_account.record.sip_host) then + call_result = { code = 480, phrase = 'User offline', disposition = 'USER_NOT_REGISTERED' }; + else + local call_waiting = self:call_waiting_busy(sip_account); + if not call_waiting then + destinations[index].numbers = sip_account:phone_numbers(); - if not arg.callee_id_name then - table.insert(origination_variables, "effective_callee_id_name='" .. sip_account.record.caller_name .. "'"); - end - if not arg.callee_id_number then - table.insert(origination_variables, "effective_callee_id_number='" .. destination.number .. "'"); - end - if destination.alert_info then - table.insert(origination_variables, "alert_info='" .. destination.alert_info .. "'"); + if not arg.callee_id_name then + table.insert(origination_variables, "effective_callee_id_name='" .. sip_account.record.caller_name .. "'"); + end + if not arg.callee_id_number then + table.insert(origination_variables, "effective_callee_id_number='" .. destination.number .. "'"); + end + if destination.alert_info then + table.insert(origination_variables, "alert_info='" .. destination.alert_info .. "'"); + end + table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/' .. sip_account.record.profile_name .. '/' .. sip_account.record.auth_name .. '%' .. sip_account.record.sip_host); + else + some_destinations_busy = true; + call_result = { code = 486, phrase = 'User busy', disposition = 'USER_BUSY' }; end - table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']user/' .. sip_account.record.auth_name); - else - some_destinations_busy = true; - call_result = { code = 486, phrase = 'User busy', disposition = 'USER_BUSY' }; end elseif destination.type == 'gateway' then require 'common.gateway' -- cgit v1.2.3 From ff38cb3ad641ec8ceee26b3b287774e43fe19345 Mon Sep 17 00:00:00 2001 From: Julian Pawlowski Date: Tue, 12 Feb 2013 11:01:49 +0100 Subject: german language: gespeicherte --- misc/freeswitch/conf/freeswitch.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/conf/freeswitch.xml b/misc/freeswitch/conf/freeswitch.xml index a7eb44d..17fc53d 100644 --- a/misc/freeswitch/conf/freeswitch.xml +++ b/misc/freeswitch/conf/freeswitch.xml @@ -538,7 +538,7 @@ - + -- cgit v1.2.3 From 2ff332de8a6253a5f1e9a5914171d4f772da372c Mon Sep 17 00:00:00 2001 From: Julian Pawlowski Date: Tue, 12 Feb 2013 11:13:20 +0100 Subject: german language: gespeichert/gespeicherte --- misc/freeswitch/conf/freeswitch.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'misc/freeswitch') diff --git a/misc/freeswitch/conf/freeswitch.xml b/misc/freeswitch/conf/freeswitch.xml index 17fc53d..a5fe873 100644 --- a/misc/freeswitch/conf/freeswitch.xml +++ b/misc/freeswitch/conf/freeswitch.xml @@ -538,7 +538,7 @@ - + @@ -784,7 +784,7 @@ - + -- cgit v1.2.3