summaryrefslogtreecommitdiff
path: root/misc/freeswitch/scripts/dialplan
diff options
context:
space:
mode:
Diffstat (limited to 'misc/freeswitch/scripts/dialplan')
-rw-r--r--misc/freeswitch/scripts/dialplan/acd.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/dialplan.lua18
-rw-r--r--misc/freeswitch/scripts/dialplan/dtmf.lua69
-rw-r--r--misc/freeswitch/scripts/dialplan/functions.lua20
-rw-r--r--misc/freeswitch/scripts/dialplan/hunt_group.lua13
-rw-r--r--misc/freeswitch/scripts/dialplan/router.lua12
-rw-r--r--misc/freeswitch/scripts/dialplan/sip_call.lua71
7 files changed, 163 insertions, 42 deletions
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);
diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua
index ff4adc6..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
@@ -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
@@ -759,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
@@ -814,11 +816,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
diff --git a/misc/freeswitch/scripts/dialplan/dtmf.lua b/misc/freeswitch/scripts/dialplan/dtmf.lua
new file mode 100644
index 0000000..4dbd35f
--- /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:debug('DTMF_RECEIVER callee - digit: [', digit, '][', duration, '], sequence: ', sequence.digits);
+ else
+ self.log:debug('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
diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua
index 2ca51c8..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;
@@ -264,7 +266,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
@@ -302,6 +304,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
@@ -374,13 +377,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
@@ -409,8 +412,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
@@ -426,7 +430,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
@@ -909,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
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
diff --git a/misc/freeswitch/scripts/dialplan/router.lua b/misc/freeswitch/scripts/dialplan/router.lua
index cdcb58b..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
@@ -143,7 +150,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
@@ -159,6 +166,7 @@ function Router.route_match(self, route)
end
if route_matches then
+ destination.number = destination.number or destination.destination_number;
return destination;
end;
diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua
index d1557e9..b56f1b2 100644
--- a/misc/freeswitch/scripts/dialplan/sip_call.lua
+++ b/misc/freeswitch/scripts/dialplan/sip_call.lua
@@ -95,39 +95,50 @@ 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
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'
@@ -169,11 +180,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);
@@ -195,6 +201,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();
@@ -226,10 +238,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