diff options
Diffstat (limited to 'misc/freeswitch')
20 files changed, 341 insertions, 83 deletions
diff --git a/misc/freeswitch/conf/freeswitch.xml b/misc/freeswitch/conf/freeswitch.xml index 0a6538e..82da873 100644 --- a/misc/freeswitch/conf/freeswitch.xml +++ b/misc/freeswitch/conf/freeswitch.xml @@ -670,7 +670,7 @@ <action function="play-file" data="voicemail/vm-message_number.wav"/> <action function="say" data="$1" method="pronounced" type="items"/> <action function="play-file" data="voicemail/vm-received.wav"/> - <action function="say" data="$2" method="pronounced" type="short_date_time"/> + <action function="say" data="$2" method="pronounced" type="current_date_time"/> <action function="play-file" data="$3"/> </match> </input> diff --git a/misc/freeswitch/scripts/common/array.lua b/misc/freeswitch/scripts/common/array.lua index c3cabec..58a6798 100644 --- a/misc/freeswitch/scripts/common/array.lua +++ b/misc/freeswitch/scripts/common/array.lua @@ -41,10 +41,11 @@ end function expand_variable(variable_path, variable_sets) for index=1, #variable_sets do local result = try(variable_sets[index], variable_path); - if result then + if result ~= nil then return result; end end + return nil; end -- replace variables in a string by array values diff --git a/misc/freeswitch/scripts/common/call_history.lua b/misc/freeswitch/scripts/common/call_history.lua index 7e1e22b..ee73e84 100644 --- a/misc/freeswitch/scripts/common/call_history.lua +++ b/misc/freeswitch/scripts/common/call_history.lua @@ -76,6 +76,7 @@ function CallHistory.insert_event(self, uuid, account_type, account_id, entry_ty call_history.callee_account_id = common.str.to_sql(event:getHeader('variable_gs_destination_id')); call_history.destination_number = common.str.to_sql(event:getHeader('variable_gs_destination_number')); call_history.forwarding_service = common.str.to_sql(event:getHeader('variable_gs_forwarding_service')); + call_history.clir = common.str.to_sql(common.str.to_b(event:getHeader('variable_gs_clir'))); if not common.str.to_b(event:getHeader('variable_gs_clir')) then call_history.caller_account_type = common.str.to_sql(camelize_type(event:getHeader('variable_gs_caller_account_type') or event:getHeader('variable_gs_account_type'))); diff --git a/misc/freeswitch/scripts/common/conference.lua b/misc/freeswitch/scripts/common/conference.lua index 5694f62..423d564 100644 --- a/misc/freeswitch/scripts/common/conference.lua +++ b/misc/freeswitch/scripts/common/conference.lua @@ -52,8 +52,7 @@ function Conference.settings_get(self) end -function Conference.find_by_id(self, id) - local sql_query = 'SELECT *, (NOW() >= `start` AND NOW() <= `end`) AS `open_now` FROM `conferences` WHERE `id`= ' .. tonumber(id) .. ' LIMIT 1'; +function Conference.find_sql(self, sql_query) local conference = nil; self.database:query(sql_query, function(conference_entry) @@ -82,6 +81,16 @@ function Conference.find_by_id(self, id) end +function Conference.find_by_id(self, id) + return self:find_sql('SELECT *, (NOW() >= `start` AND NOW() <= `end`) AS `open_now` FROM `conferences` WHERE `id`= ' .. tonumber(id) .. ' LIMIT 1'); +end + + +function Conference.find_by_uuid(self, uuid) + return self:find_sql('SELECT *, (NOW() >= `start` AND NOW() <= `end`) AS `open_now` FROM `conferences` WHERE `uuid`= ' .. self.database:escape(uuid, '"') .. ' LIMIT 1'); +end + + function Conference.find_invitee_by_numbers(self, phone_numbers) if not self.record then return false; diff --git a/misc/freeswitch/scripts/common/gateway.lua b/misc/freeswitch/scripts/common/gateway.lua index 09e8c4b..8ea6b04 100644 --- a/misc/freeswitch/scripts/common/gateway.lua +++ b/misc/freeswitch/scripts/common/gateway.lua @@ -274,3 +274,97 @@ function Gateway.parameters_build(self, gateway_id, technology) return parameters; end + + +function Gateway.headers_get(self, header_type, gateway_id) + gateway_id = gateway_id or self.id; + + local sql_query = 'SELECT * FROM `gateway_headers` WHERE `gateway_id` = ' .. tonumber(gateway_id) .. ' AND `header_type` = ' .. self.database:escape(header_type, '"'); + + local headers = {}; + self.database:query(sql_query, function(entry) + table.insert(headers, entry); + end) + + return headers; +end + + +function Gateway.constraint_match(self, constraints_str, variable_sets) + if common.str.blank(constraints_str) then + entry_match = true; + else + local constraints = common.str.strip_to_a(constraints_str, ',') + for constraint_index=1, #constraints do + local variable_name, pattern = common.str.partition(constraints[constraint_index], '!=') + local invert = variable_name ~= nil; + if not variable_name then + variable_name, pattern = common.str.partition(constraints[constraint_index], '=') + end + + if not common.str.blank(variable_name) and not common.str.blank(pattern) then + local search_string = common.array.expand_variable(variable_name, variable_sets); + if search_string ~= nil then + local success, result = pcall(string.find, tostring(search_string), pattern); + + entry_match = common.str.to_b(result); + + if invert then + entry_match = not entry_match; + end + + if entry_match == false then + break; + end + end + end + end + end + + return entry_match; +end + + +function Gateway.origination_variables(self, header_type, origination_variables, ...) + local dtmf = tostring(self.settings.dtmf_type):lower(); + if dtmf == 'inband' then + table.insert(origination_variables, "dtmf_type=none"); + elseif dtmf == 'none' or dtmf == 'info' then + table.insert(origination_variables, "dtmf_type=" .. dtmf); + else + table.insert(origination_variables, "dtmf_type=rfc2833"); + end + + local header_to_variable = { + default = { + default = 'sip_h_', + from = 'sip_full_from', + to = 'sip_full_to', + invite = 'sip_req_uri', + }, + invite = { + default = 'sip_h_', + from = 'sip_invite_full_from', + to = 'sip_invite_full_to', + invite = 'sip_invite_req_uri', + route = 'sip_invite_route_uri', + ['Record-Route'] = 'sip_invite_record_route', + } + } + + local variable_sets = {...}; + local headers = self:headers_get('default'); + for index, header in ipairs(self:headers_get(header_type)) do + table.insert(headers, header); + end + + for index, header in ipairs(headers) do + local search_string = common.array.expand_variable(header.constraint_source, variable_sets); + if common.str.blank(header.constraint_value) or self:constraint_match(header.constraint_value, variable_sets) then + if header_to_variable[header.header_type] then + local origination_variable = header_to_variable[header.header_type][header.name:lower()] or header_to_variable[header.header_type].default .. header.name; + table.insert(origination_variables, origination_variable .. "='" .. common.array.expand_variables(header.value, unpack(variable_sets)) .. "'"); + end + end + end +end diff --git a/misc/freeswitch/scripts/common/object.lua b/misc/freeswitch/scripts/common/object.lua index 68e1361..5482168 100644 --- a/misc/freeswitch/scripts/common/object.lua +++ b/misc/freeswitch/scripts/common/object.lua @@ -116,3 +116,16 @@ function Object.find(self, attributes) return object; end + +-- local class from module +function Object.load_one(self, module_path) + result, module_data = pcall(require, module_path); + if not result or not module_data then + return nil, module_data; + end + for object_name in pairs(module_data) do + if tostring(object_name[1]) ~= '_' then + return module_data[object_name]; + end + end +end diff --git a/misc/freeswitch/scripts/configuration.lua b/misc/freeswitch/scripts/configuration.lua index 2486565..5874752 100644 --- a/misc/freeswitch/scripts/configuration.lua +++ b/misc/freeswitch/scripts/configuration.lua @@ -189,10 +189,10 @@ function conf_conference(database) local config = common.configuration_table.get(database, 'conferences'); local profiles = nil; - local event_name = params:getHeader("Event-Name") + local event_name = params:getHeader("Event-Name") or ''; if event_name == 'COMMAND' then - local conf_name = params:getHeader('conf_name'); - local profile_name = params:getHeader('profile_name'); + local conf_name = params:getHeader('conf_name') or ''; + local profile_name = params:getHeader('profile_name') or ''; if conf_name:find('^conference%d+') then require 'common.conference'; diff --git a/misc/freeswitch/scripts/dialplan/acd.lua b/misc/freeswitch/scripts/dialplan/acd.lua index 5ed8979..1e6e2ef 100644 --- a/misc/freeswitch/scripts/dialplan/acd.lua +++ b/misc/freeswitch/scripts/dialplan/acd.lua @@ -482,3 +482,23 @@ function AutomaticCallDistributor.run(self, dialplan_object, caller, destination return result; end + +function AutomaticCallDistributor.call_forwarding_on(self, service, destination, destination_type, timeout, source) + + if not self.call_forwarding then + require 'common.call_forwarding'; + self.call_forwarding = common.call_forwarding.CallForwarding:new{ log = self.log, database = self.database, parent = self, domain = self.domain }; + end + + return self.call_forwarding:call_forwarding_on(service, destination, destination_type, timeout, source) +end + + +function AutomaticCallDistributor.call_forwarding_off(self, service, source, delete) + if not self.call_forwarding then + require 'common.call_forwarding'; + self.call_forwarding = common.call_forwarding.CallForwarding:new{ log = self.log, database = self.database, parent = self, domain = self.domain }; + end + + return self.call_forwarding:call_forwarding_off(service, source, delete) +end diff --git a/misc/freeswitch/scripts/dialplan/callthrough.lua b/misc/freeswitch/scripts/dialplan/callthrough.lua index 69a0611..59f170a 100644 --- a/misc/freeswitch/scripts/dialplan/callthrough.lua +++ b/misc/freeswitch/scripts/dialplan/callthrough.lua @@ -52,8 +52,8 @@ function Callthrough.authenticate(self, caller) end self.log:debug('CALLTHROUGH_AUTHENTICATE - access_authorizations: ', #self.access_authorizations); - for index, authorization in ipairs(self.access_authorizations) do - if authorization.phone_number then + for index, authorization in ipairs(self.access_authorizations) do + if not common.str.blank(authorization.phone_number) then if authorization.phone_number == caller.caller_phone_number then if authorization.pin and authorization.pin ~= "" then if caller.session:read(authorization.pin:len(), authorization.pin:len(), "ivr/ivr-please_enter_pin_followed_by_pound.wav", 3000, "#") ~= authorization.pin then diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index 913d7a5..1133f58 100644 --- a/misc/freeswitch/scripts/dialplan/dialplan.lua +++ b/misc/freeswitch/scripts/dialplan/dialplan.lua @@ -124,16 +124,19 @@ function Dialplan.auth_node(self) end -function Dialplan.auth_sip_account(self) +function Dialplan.auth_account(self) if not common.str.blank(self.caller.auth_account_type) then - self.log:info('AUTH_SIP_ACCOUNT - ', self.caller.auth_account_type, '=', self.caller.account_id, '/', self.caller.account_uuid); + self.log:info('AUTH auth_account - ', self.caller.auth_account_type, '=', self.caller.account_id, '/', self.caller.account_uuid); + return true; + elseif not common.str.blank(self.caller.previous_destination_type) and not common.str.blank(self.caller.previous_destination_uuid) then + self.log:info('AUTH previous_destination - ', self.caller.previous_destination_type, '=', self.caller.previous_destination_id, '/', self.caller.previous_destination_uuid); return true; end end function Dialplan.auth_gateway(self) - require 'common.gateway' + require 'common.gateway'; local gateway_class = common.gateway.Gateway:new{ log = self.log, database = self.database}; local gateway = false; @@ -143,14 +146,14 @@ function Dialplan.auth_gateway(self) name = self.caller:to_s('gs_gateway_name'), id = self.caller:to_i('gs_gateway_id'), } - log:info('AUTH_GATEWAY - authenticaded by password and username: ', self.caller:to_s('username'), ', gateway=', gateway.id, '|', gateway.name, ', ip: ', self.caller.sip_contact_host); + log:info('AUTH gateway - authenticaded by password and username: ', self.caller:to_s('username'), ', gateway=', gateway.id, '|', gateway.name, ', ip: ', self.caller.sip_contact_host); return gateway_class:find_by_id(gateway.id); else gateway = gateway_class:authenticate(self.caller); end if gateway then - log:info('AUTH_GATEWAY - ', gateway.auth_source, ' ~ ', gateway.auth_pattern, ', gateway=', gateway.id, '|', gateway.name, ', ip: ', self.caller.sip_contact_host); + log:info('AUTH gateway - ', gateway.auth_source, ' ~ ', gateway.auth_pattern, ', gateway=', gateway.id, '|', gateway.name, ', ip: ', self.caller.sip_contact_host); return gateway_class:find_by_id(gateway.id); end end @@ -349,7 +352,7 @@ function Dialplan.dial(self, destination) self.log:debug('RINGTONE - phonebookentry=', self.caller.phone_book_entry.id, ', ringtone: ', self.caller.phone_book_entry.bellcore_id); self.caller:export_variable('alert_info', 'http://amooma.de;info=Ringer' .. self.caller.phone_book_entry.bellcore_id .. ';x-line-id=0'); end - if self.caller.phone_book_entry.image then + if not common.str.blank(self.caller.phone_book_entry.image) then self:set_caller_picture(self.caller.phone_book_entry.id, 'phonebookentry', self.caller.phone_book_entry.image); elseif self.caller.account and self.caller.account.owner then self:set_caller_picture(self.caller.account.owner.id, self.caller.account.owner.class); @@ -726,14 +729,6 @@ function Dialplan.switch(self, destination) destination.callee_id_number = destination.number; destination.callee_id_name = nil; - require 'dialplan.router' - local routes = dialplan.router.Router:new{ log = self.log, database = self.database, caller = self.caller, variables = self.caller }:route_run('outbound'); - - if not routes or #routes == 0 then - self.log:notice('SWITCH - no route - number: ', destination.number); - return { continue = false, code = 404, phrase = 'No route' } - end - if self.phonebook_number_lookup then local user_id = common.array.try(self.caller, 'account.owner.id'); local tenant_id = common.array.try(self.caller, 'account.owner.record.current_tenant_id'); @@ -763,7 +758,16 @@ function Dialplan.switch(self, destination) self.caller:set_callee_id(destination.callee_id_number, destination.callee_id_name); + require 'dialplan.router' + local routes = dialplan.router.Router:new{ log = self.log, database = self.database, caller = self.caller, variables = self.caller }:route_run('outbound'); + + if not routes or #routes == 0 then + self.log:notice('SWITCH - no route - number: ', destination.number); + return { continue = false, code = 404, phrase = 'No route' } + end + for index, route in ipairs(routes) do + self.caller:set_callee_id(route.callee_id_number or destination.callee_id_number, route.callee_id_name or destination.callee_id_name); 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 } @@ -893,9 +897,10 @@ function Dialplan.run(self, destination) self.caller:set_variable('sound_prefix', common.array.try(self.config, 'sounds.' .. tostring(self.caller.language))); self.log:info('DIALPLAN start - caller_id: ',self.caller.caller_id_number, ' "', self.caller.caller_id_name, '" , number: ', destination.number, ', language: ', self.caller.language); - self.caller.static_caller_id_number = self.caller.caller_id_number; self.caller.static_caller_id_name = self.caller.caller_id_name; + self.caller:set_variable('gs_caller_id_number', self.caller.caller_id_number); + self.caller:set_variable('gs_caller_id_name', self.caller.caller_id_name); local result = { continue = false }; local loop = self.caller.loop_count; @@ -965,6 +970,14 @@ function Dialplan.run(self, destination) destination, result ); + local forwarding_path = self.caller:to_s('gs_forwarding_path'); + if forwarding_path ~= '' then + forwarding_path = forwarding_path .. ','; + end + + forwarding_path = forwarding_path .. auth_account.class:sub(1,1) .. ':' .. auth_account.id; + self.caller:set_variable('gs_forwarding_path', forwarding_path); + self.log:debug('FORWARDING_PATH: ', forwarding_path); end end diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua index efd1f05..89f101d 100644 --- a/misc/freeswitch/scripts/dialplan/functions.lua +++ b/misc/freeswitch/scripts/dialplan/functions.lua @@ -98,6 +98,10 @@ function Functions.dialplan_function(self, caller, dialed_number) result = self:call_forwarding_off(caller, 'busy'); elseif fid == "cfbdel" then result = self:call_forwarding_off(caller, 'busy', true); + elseif fid == "cfun" then + result = self:call_forwarding_by_number(caller, parameters[3], false, 'always'); + elseif fid == "cfunoff" then + result = self:call_forwarding_by_number(caller, parameters[3], true, 'always'); elseif fid == "vmleave" then result = self:voicemail_message_leave(caller, parameters[3]); elseif fid == "vmcheck" then @@ -742,6 +746,70 @@ function Functions.call_forwarding_toggle(self, caller, call_forwarding_service, end +function Functions.call_forwarding_by_number(self, caller, number, call_forwarding_off, call_forwarding_service, delete) + -- Find caller's SipAccount + local caller_sip_account = self:ensure_caller_sip_account(caller); + if not caller_sip_account then + return { continue = false, code = 403, phrase = 'Incompatible caller', no_cdr = true } + end + + if common.str.blank(number) then + self.log:notice('FUNCTION_CALL_FORWARDING_BY_NUMBER - no phone number specified'); + return { continue = false, code = 500, phrase = 'No number specified', no_cdr = true } + end + + require 'common.phone_number'; + local phone_number = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database, domain = caller_sip_account.domain }:find_by_number(number); + + if not phone_number then + self.log:notice('FUNCTION_CALL_FORWARDING_BY_NUMBER - no phone number found: ', number); + return { continue = false, code = 500, phrase = 'Number not found', no_cdr = true } + end + + require 'common.object'; + parent = common.object.Object:new{ log = self.log, database = self.database}:find{class = phone_number.record.phone_numberable_type, id = phone_number.record.phone_numberable_id}; + parent.domain = parent.domain or self.domain; + + if not parent then + self.log:notice('FUNCTION_CALL_FORWARDING_BY_NUMBER - no parent found: ', phone_number.record.phone_numberable_type, '=', phone_number.record.phone_numberable_id); + return { continue = false, code = 500, phrase = 'Parent not found', no_cdr = true } + end + + self.log:info('FUNCTION_CALL_FORWARDING_BY_NUMBER - account: ', parent.class, '=', parent.id, '/', parent.uuid); + + if parent.class == 'automaticcalldistributor' then + if not parent:agent_find_by_acd_and_destination(parent.id, caller_sip_account.class, caller_sip_account.id) then + self.log:notice('FUNCTION_CALL_FORWARDING_BY_NUMBER - caller not allowed to set call forwarding for: ', phone_number.record.phone_numberable_type, '=', phone_number.record.phone_numberable_id); + return { continue = false, code = 500, phrase = 'Permission denied', no_cdr = true } + end + else + self.log:notice('FUNCTION_CALL_FORWARDING_BY_NUMBER - parent type not forwardable by caller: ', phone_number.record.phone_numberable_type); + return { continue = false, code = 500, phrase = 'Permission denied', no_cdr = true } + end + + if call_forwarding_off then + if not parent:call_forwarding_off(call_forwarding_service, nil, delete) then + self.log:notice('FUNCTION_CALL_FORWARDING_BY_NUMBER - call forwarding could not be deactivated'); + return { continue = false, code = 500, phrase = 'Call Forwarding could not be deactivated', no_cdr = true } + end + else + if not parent:call_forwarding_on(call_forwarding_service, nil, delete) then + self.log:notice('FUNCTION_CALL_FORWARDING_BY_NUMBER - call forwarding could not be activated'); + return { continue = false, code = 500, phrase = 'Call Forwarding could not be activated', no_cdr = true } + end + end + + caller:answer(); + if call_forwarding_off then + caller:send_display('Call forwarding off'); + else + caller:send_display('Call forwarding on'); + end + caller:sleep(1000); + return { continue = false, code = 200, phrase = 'OK', no_cdr = true } +end + + function Functions.voicemail_message_leave(self, caller, phone_number) require 'dialplan.voicemail' local voicemail_account = dialplan.voicemail.Voicemail:new{ log = self.log, database = self.database }:find_by_number(phone_number); diff --git a/misc/freeswitch/scripts/dialplan/hunt_group.lua b/misc/freeswitch/scripts/dialplan/hunt_group.lua index e87c6b2..f12182c 100644 --- a/misc/freeswitch/scripts/dialplan/hunt_group.lua +++ b/misc/freeswitch/scripts/dialplan/hunt_group.lua @@ -165,7 +165,11 @@ function HuntGroup.run(self, dialplan_object, caller, destination) table.insert(recursive_destinations, forwarding_destination); end require 'dialplan.sip_call' - result = dialplan.sip_call.SipCall:new{ log = self.log, database = self.database, caller = caller }:fork( recursive_destinations, { callee_id_number = hunt_group_destination.number, timeout = member_timeout }); + result = dialplan.sip_call.SipCall:new{ log = self.log, database = self.database, caller = caller }:fork( recursive_destinations, + { callee_id_number = hunt_group_destination.number, + timeout = member_timeout, + send_ringing = ( dialplan_object.send_ringing_to_gateways and caller.from_gateway ), + }); if result.disposition == 'SUCCESS' then if result.fork_index then result.destination = recursive_destinations[result.fork_index]; diff --git a/misc/freeswitch/scripts/dialplan/session.lua b/misc/freeswitch/scripts/dialplan/session.lua index 1d907c5..7023c5e 100644 --- a/misc/freeswitch/scripts/dialplan/session.lua +++ b/misc/freeswitch/scripts/dialplan/session.lua @@ -8,6 +8,8 @@ Session = {} -- create session object function Session.new(self, arg) + require 'common.str'; + arg = arg or {} object = arg.object or {} setmetatable(object, self); @@ -29,8 +31,8 @@ function Session.init_channel_variables(self) self.destination_number = self:expand_variables(self:to_s('destination_number')); self.called_number = self.destination_number; - self.caller_id_number = self:to_s('caller_id_number'); - self.caller_id_name = self:to_s('caller_id_name'); + self.caller_id_number = self.session:getVariable('gs_caller_id_number') or self:to_s('caller_id_number'); + self.caller_id_name = self.session:getVariable('gs_caller_id_name') or self:to_s('caller_id_name'); self.caller_phone_number = self.caller_id_number; self.caller_phone_numbers = {self.caller_id_number}; @@ -93,25 +95,21 @@ end -- Cast channel variable to string function Session.to_s(self, variable_name) - require 'common.str' return common.str.to_s(self.session:getVariable(variable_name)); end -- Cast channel variable to integer function Session.to_i(self, variable_name) - require 'common.str' return common.str.to_i(self.session:getVariable(variable_name)); end -- Cast channel variable to boolean function Session.to_b(self, variable_name) - require 'common.str' return common.str.to_b(self.session:getVariable(variable_name)); end -- Split channel variable to table function Session.to_a(self, variable_name) - require 'common.str' return common.str.to_a(self.session:getVariable(variable_name)); end diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua index 1966a41..1b5ee5d 100644 --- a/misc/freeswitch/scripts/dialplan/sip_call.lua +++ b/misc/freeswitch/scripts/dialplan/sip_call.lua @@ -175,49 +175,7 @@ function SipCall.fork(self, destinations, arg ) local gateway = common.gateway.Gateway:new{ log = self.log, database = self.database}:find_by_id(destination.id); if gateway and gateway.outbound then - local asserted_identity = tostring(gateway.settings.asserted_identity); - local asserted_identity_clir = tostring(gateway.settings.asserted_identity); - local caller_id_number = destination.caller_id_number or self.caller.caller_id_number; - local caller_id_name = destination.caller_id_name or self.caller.caller_id_name; - local from_uri = common.array.expand_variables(gateway.settings.from or '', destination, self.caller, { gateway = gateway }); - - if gateway.settings.asserted_identity then - local identity = common.array.expand_variables(gateway.settings.asserted_identity or '', destination, self.caller, { gateway = gateway }) - - if self.caller.clir then - caller_id_number = self.caller.anonymous_number or 'anonymous'; - caller_id_name = self.caller.anonymous_name or 'Anonymous'; - from_uri = common.array.expand_variables(gateway.settings.from_clir or '', destination, self.caller, { gateway = gateway }) or from_uri; - identity = common.array.expand_variables(gateway.settings.asserted_identity_clir or '', destination, self.caller, { gateway = gateway }) or identity; - table.insert(origination_variables, "origination_caller_id_number='" .. caller_id_number .. "'"); - table.insert(origination_variables, "origination_caller_id_name='" .. caller_id_name .. "'"); - table.insert(origination_variables, "sip_h_Privacy='id'"); - else - if destination.caller_id_number then - table.insert(origination_variables, "origination_caller_id_number='" .. destination.caller_id_number .. "'"); - end - if destination.caller_id_name then - table.insert(origination_variables, "origination_caller_id_name='" .. destination.caller_id_name .. "'"); - end - end - - if from_uri then - table.insert(origination_variables, "sip_from_uri='" .. from_uri .. "'"); - end - - if identity then - table.insert(origination_variables, "sip_h_P-Asserted-Identity='" .. identity .. "'"); - end - - self.log:info('FORK ', index, '/', #destinations, ' - from: ', from_uri, ', identity: ', identity, ', privacy: ', self.caller.clir); - else - if destination.caller_id_number then - table.insert(origination_variables, "origination_caller_id_number='" .. destination.caller_id_number .. "'"); - end - if destination.caller_id_name then - table.insert(origination_variables, "origination_caller_id_name='" .. destination.caller_id_name .. "'"); - end - end + gateway:origination_variables('invite', origination_variables, gateway.settings, destination, self.caller); if destination.channel_variables then for key, value in pairs(destination.channel_variables) do @@ -226,6 +184,10 @@ function SipCall.fork(self, destinations, arg ) end table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']' .. gateway:call_url(destination.number)); + + if tostring(gateway.settings.dtmf_type):lower() == 'inband' then + self.caller:execute('start_dtmf_generate'); + end else self.log:notice('FORK - gateway not found - gateway=', destination.id); end diff --git a/misc/freeswitch/scripts/dialplan/voicemail.lua b/misc/freeswitch/scripts/dialplan/voicemail.lua index 3358d2b..f436720 100644 --- a/misc/freeswitch/scripts/dialplan/voicemail.lua +++ b/misc/freeswitch/scripts/dialplan/voicemail.lua @@ -349,7 +349,10 @@ function Voicemail.leave(self, caller, greeting, number) end os.remove(record_file_name); caller:send_display('Goodbye'); - caller.session:sayPhrase('voicemail_goodbye'); + + if common.str.blank(greeting_file) then + caller.session:sayPhrase('voicemail_goodbye'); + end end diff --git a/misc/freeswitch/scripts/dialplan_default.lua b/misc/freeswitch/scripts/dialplan_default.lua index 32789cb..eeeb5c2 100644 --- a/misc/freeswitch/scripts/dialplan_default.lua +++ b/misc/freeswitch/scripts/dialplan_default.lua @@ -74,7 +74,7 @@ if start_caller.from_node and not start_dialplan:auth_node() then log:debug('DIALPLAN_DEFAULT - node unauthorized - node_id: ', start_caller.node_id, ', domain: ', start_dialplan.domain); start_dialplan:hangup(401, start_dialplan.domain); else - if not start_dialplan:auth_sip_account() then + if not start_dialplan:auth_account() then local gateway = start_dialplan:auth_gateway() if gateway then diff --git a/misc/freeswitch/scripts/event/cdr_save.lua b/misc/freeswitch/scripts/event/cdr_save.lua index e7ac64a..03eccf7 100644 --- a/misc/freeswitch/scripts/event/cdr_save.lua +++ b/misc/freeswitch/scripts/event/cdr_save.lua @@ -81,6 +81,7 @@ function CdrSave.channel_destroy(self, event) cdr.forwarding_service = common.str.to_sql(event:getHeader('variable_gs_forwarding_service')); cdr.forwarding_account_id = common.str.to_sql(event:getHeader('variable_gs_auth_account_id')); cdr.forwarding_account_type = common.str.to_sql(camelize_type(event:getHeader('variable_gs_auth_account_type'))); + cdr.forwarding_path = common.str.to_sql(event:getHeader('variable_gs_forwarding_path')); cdr.account_id = common.str.to_sql(event:getHeader('variable_gs_account_id')); cdr.account_type = common.str.to_sql(camelize_type(event:getHeader('variable_gs_account_type'))); cdr.bleg_account_id = common.str.to_sql(event:getHeader('variable_gs_destination_id')); diff --git a/misc/freeswitch/scripts/event/presence_update.lua b/misc/freeswitch/scripts/event/presence_update.lua index fd85f03..cf29ca9 100644 --- a/misc/freeswitch/scripts/event/presence_update.lua +++ b/misc/freeswitch/scripts/event/presence_update.lua @@ -134,6 +134,9 @@ function PresenceUpdate.presence_in(self, event) self.log:info('[', uuid,'] PRESENCE_CONFERENCE_', call_direction:upper(), ' ', common.str.to_i(account), ' - identifier: ', account, ', state: ', state); self:conference(direction, account, domain, state, uuid); elseif protocol == 'sip' or protocol == 'any' then + if common.str.blank(state) then + state = event:getHeader('answer-state'); + end if protocol == 'sip' and common.str.blank(state) then self.log:debug('[', uuid,'] PRESENCE_', call_direction:upper(),' no state - protocol: ', protocol, ', account: ', account); return; diff --git a/misc/freeswitch/scripts/phones/phone.lua b/misc/freeswitch/scripts/phones/phone.lua index 57997ba..6219eb1 100644 --- a/misc/freeswitch/scripts/phones/phone.lua +++ b/misc/freeswitch/scripts/phones/phone.lua @@ -114,15 +114,43 @@ function Phone.login(self, account_id, owner_id, owner_type) end function Phone.resync(self, arg) - if not self.model then + local result = nil; + + if self.record then + arg.ip_address = arg.ip_address or self.record.ip_address; + arg.http_user = arg.http_user or self.record.http_user; + arg.http_password = arg.http_password or self.record.http_password; + end + + if self.model then + result = self.model:resync(arg); + else 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); + require 'phones.snom'; + result = phones.snom.Snom:new{ log = self.log }:resync(arg); + end + + if self.record and self.record.id then + self:resync_extension_modules(arg); end - arg.ip_address = arg.ip_address or self.record.ip_address; - arg.http_user = arg.http_user or self.record.http_user; - arg.http_password = arg.http_password or self.record.http_password; + return result; +end + + +function Phone.resync_extension_modules(self, arg) + require('common.object'); + local object_class = common.object.Object:new{ log = self.log }; + + local sql_query = 'SELECT * FROM `extension_modules` WHERE `active` IS TRUE AND `phone_id` = ' .. common.str.to_i(self.record.id); + self.database:query(sql_query, function(extension_module) + local extension_module_class, error_message = object_class:load_one('phones.' .. extension_module.model); + if not extension_module_class then + self.log:error('RESYNC_EXTENSION_MODULE - unsupported model: ', extension_module.model, ', error: ', error_message); + end - return self.model:resync(arg); + arg.ip_address = extension_module.ip_address; + local result = extension_module_class:new{log = self.log}:resync(arg); + self.log:debug('RESYNC_EXTENSION_MODULE - ', extension_module_class.class, '=', extension_module.id, ', mac_address: ', extension_module.mac_address, ', ip_address: ', extension_module.ip_address, ', executed: ', tostring(result)); + end); end diff --git a/misc/freeswitch/scripts/phones/snom_vision.lua b/misc/freeswitch/scripts/phones/snom_vision.lua new file mode 100644 index 0000000..7adace4 --- /dev/null +++ b/misc/freeswitch/scripts/phones/snom_vision.lua @@ -0,0 +1,40 @@ +-- Gemeinschaft 5 module: snom vision extension module model class +-- (c) AMOOMA GmbH 2012-2013 +-- + +module(...,package.seeall) + +SnomVision = {} + +-- Create SnomVision object +function SnomVision.new(self, arg) + arg = arg or {} + object = arg.object or {} + setmetatable(object, self); + self.__index = self; + self.log = arg.log; + self.reboot = arg.reboot or true; + self.class = 'snomvision'; + return object; +end + +-- send reload message to module +function SnomVision.resync(self, arg) + if arg.ip_address then + return self:resync_http(arg.ip_address, arg.http_user, arg.http_password, arg.http_port); + end + + return false; +end + + +function SnomVision.resync_http(self, ip_address, http_user, http_password, http_port) + local port_str = ''; + if tonumber(http_port) then + port_str = ':' .. http_port; + end + + local command = 'http_request.lua snom_vision_resync http://' .. tostring(ip_address):gsub('[^0-9%.]', '') .. port_str .. '/ConfigurationModule/restart ' .. (http_user or '') .. ' ' .. (http_password or ''); + require 'common.fapi' + return common.fapi.FApi:new():execute('luarun', command); +end |