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/call_parking.lua16
-rw-r--r--misc/freeswitch/scripts/dialplan/dialplan.lua136
-rw-r--r--misc/freeswitch/scripts/dialplan/dtmf.lua8
-rw-r--r--misc/freeswitch/scripts/dialplan/fax.lua8
-rw-r--r--misc/freeswitch/scripts/dialplan/functions.lua141
-rw-r--r--misc/freeswitch/scripts/dialplan/sip_call.lua26
-rw-r--r--misc/freeswitch/scripts/dialplan/user.lua17
-rw-r--r--misc/freeswitch/scripts/dialplan/voicemail.lua2
8 files changed, 206 insertions, 148 deletions
diff --git a/misc/freeswitch/scripts/dialplan/call_parking.lua b/misc/freeswitch/scripts/dialplan/call_parking.lua
index cc2cf4b..e51eb16 100644
--- a/misc/freeswitch/scripts/dialplan/call_parking.lua
+++ b/misc/freeswitch/scripts/dialplan/call_parking.lua
@@ -39,6 +39,22 @@ function CallParking.find_by_name(self, name)
end
+function CallParking.find_by_owner(self, owner_id, owner_type)
+ local sql_query = 'SELECT * FROM `parking_stalls` WHERE `parking_stallable_id` = '.. owner_id .. ' AND `parking_stallable_type` = "' .. owner_type .. '" ORDER BY `name`';
+ local parking_stalls = {};
+
+ self.database:query(sql_query, function(entry)
+ local parking_stall = CallParking:new(self);
+ parking_stall.record = entry;
+ parking_stall.id = tonumber(entry.id);
+ parking_stall.name = entry.name;
+ table.insert(parking_stalls, parking_stall)
+ end)
+
+ return parking_stalls;
+end
+
+
function CallParking.list_occupied(self, lot)
lot = lot or self.lot;
diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua
index b27bb9d..7d9ac58 100644
--- a/misc/freeswitch/scripts/dialplan/dialplan.lua
+++ b/misc/freeswitch/scripts/dialplan/dialplan.lua
@@ -148,6 +148,9 @@ function Dialplan.object_find(self, class, identifier, auth_name)
require 'common.str'
class = common.str.downcase(class);
+ require 'common.group';
+ local group_class = common.group.Group:new{ log = self.log, database = self.database };
+
if class == 'user' then
require 'dialplan.user'
local user = nil;
@@ -158,7 +161,8 @@ function Dialplan.object_find(self, class, identifier, auth_name)
end
if user then
- user.groups = user:list_groups();
+ user.user_groups = user:list_groups();
+ user.groups = group_class:name_id_by_member(user.id, user.class);
end
return user;
@@ -171,6 +175,10 @@ function Dialplan.object_find(self, class, identifier, auth_name)
tenant = dialplan.tenant.Tenant:new{ log = self.log, database = self.database }:find_by_uuid(identifier);
end
+ if tenant then
+ tenant.groups = group_class:name_id_by_member(tenant.id, tenant.class);
+ end
+
return tenant;
elseif class == 'sipaccount' then
require 'common.sip_account'
@@ -184,6 +192,7 @@ function Dialplan.object_find(self, class, identifier, auth_name)
end
if sip_account then
sip_account.owner = self:object_find(sip_account.record.sip_accountable_type, tonumber(sip_account.record.sip_accountable_id));
+ sip_account.groups = group_class:name_id_by_member(sip_account.id, sip_account.class);
end
return sip_account;
elseif class == 'huntgroup' then
@@ -198,6 +207,7 @@ function Dialplan.object_find(self, class, identifier, auth_name)
if hunt_group then
hunt_group.owner = self:object_find('tenant', tonumber(hunt_group.record.tenant_id));
+ hunt_group.groups = group_class:name_id_by_member(hunt_group.id, hunt_group.class);
end
return hunt_group;
@@ -213,6 +223,7 @@ function Dialplan.object_find(self, class, identifier, auth_name)
if acd then
acd.owner = self:object_find(acd.record.automatic_call_distributorable_type, tonumber(acd.record.automatic_call_distributorable_id));
+ acd.groups = group_class:name_id_by_member(acd.id, acd.class);
end
return acd;
@@ -226,6 +237,7 @@ function Dialplan.object_find(self, class, identifier, auth_name)
end
if fax_account then
fax_account.owner = self:object_find(fax_account.record.fax_accountable_type, tonumber(fax_account.record.fax_accountable_id));
+ fax_account.groups = group_class:name_id_by_member(fax_account.id, fax_account.class);
end
return fax_account;
@@ -235,7 +247,6 @@ end
function Dialplan.retrieve_caller_data(self)
require 'common.str'
-
self.caller.caller_phone_numbers_hash = {}
-- TODO: Set auth_account on transfer initiated by calling party
@@ -252,9 +263,9 @@ function Dialplan.retrieve_caller_data(self)
end
if self.caller.auth_account then
- self.log:info('CALLER_DATA - auth account: ', self.caller.auth_account.class, '=', self.caller.auth_account.id, '/', self.caller.auth_account.uuid);
+ self.log:info('CALLER_DATA - auth account: ', self.caller.auth_account.class, '=', self.caller.auth_account.id, '/', self.caller.auth_account.uuid, ', groups: ', table.concat(self.caller.auth_account.groups, ','));
if self.caller.auth_account.owner then
- self.log:info('CALLER_DATA - auth owner: ', self.caller.auth_account.owner.class, '=', self.caller.auth_account.owner.id, '/', self.caller.auth_account.owner.uuid);
+ self.log:info('CALLER_DATA - auth owner: ', self.caller.auth_account.owner.class, '=', self.caller.auth_account.owner.id, '/', self.caller.auth_account.owner.uuid, ', groups: ', table.concat(self.caller.auth_account.owner.groups, ','));
else
self.log:error('CALLER_DATA - auth owner not found');
end
@@ -273,9 +284,9 @@ function Dialplan.retrieve_caller_data(self)
if not common.str.blank(self.caller.account.record.language_code) then
self.caller.language = self.caller.account.record.language_code;
end
- self.log:info('CALLER_DATA - caller account: ', self.caller.account.class, '=', self.caller.account.id, '/', self.caller.account.uuid, ', phone_numbers: ', #self.caller.caller_phone_numbers, ', language: ', self.caller.language);
+ self.log:info('CALLER_DATA - caller account: ', self.caller.account.class, '=', self.caller.account.id, '/', self.caller.account.uuid, ', phone_numbers: ', #self.caller.caller_phone_numbers, ', language: ', self.caller.language, ', groups: ', table.concat(self.caller.account.groups, ','));
if self.caller.account.owner then
- self.log:info('CALLER_DATA - caller owner: ', self.caller.account.owner.class, '=', self.caller.account.owner.id, '/', self.caller.account.owner.uuid);
+ self.log:info('CALLER_DATA - caller owner: ', self.caller.account.owner.class, '=', self.caller.account.owner.id, '/', self.caller.account.owner.uuid, ', groups: ', table.concat(self.caller.account.owner.groups, ','));
else
self.log:error('CALLER_DATA - caller owner not found');
end
@@ -319,7 +330,13 @@ function Dialplan.destination_new(self, arg)
destination.uuid = common.str.to_s(destination.phone_number.record.phone_numberable_uuid);
destination.node_id = common.str.to_i(destination.phone_number.record.gs_node_id);
if self.caller then
- destination.call_forwarding = destination.phone_number:call_forwarding(self.caller.caller_phone_numbers);
+ require 'common.call_forwarding';
+ local call_forwarding_class = common.call_forwarding.CallForwarding:new{ log = self.log, database = self.database }
+ destination.call_forwarding = call_forwarding_class:list_by_owner(destination.id, destination.type, self.caller.caller_phone_numbers);
+ for service, call_forwarding_entry in pairs(call_forwarding_class:list_by_owner(destination.phone_number.id, destination.phone_number.class, self.caller.caller_phone_numbers)) do
+ destination.call_forwarding[service] = call_forwarding_entry;
+ end
+ -- destination.call_forwarding = destination.phone_number:call_forwarding(self.caller.caller_phone_numbers);
end
elseif destination.type == 'unknown' then
require 'common.sip_account'
@@ -362,64 +379,74 @@ end
function Dialplan.dial(self, destination)
+ local user_id = nil;
+ local tenant_id = nil;
+
require 'common.str'
destination.caller_id_number = destination.caller_id_number or self.caller.caller_phone_numbers[1];
- if not self.caller.clir then
- if destination.node_local and destination.type == 'sipaccount' then
- local user_id = nil;
- local tenant_id = nil;
-
- destination.account = self:object_find(destination.type, destination.id);
- if destination.account then
- if destination.account.class == 'sipaccount' then
- destination.callee_id_name = destination.account.record.caller_name;
- self.caller:set_callee_id(destination.number, destination.account.record.caller_name);
- end
+ if destination.node_local and destination.type == 'sipaccount' then
+ destination.pickup_groups = {};
+
+ destination.account = self:object_find(destination.type, destination.id);
+ if destination.account then
+ if destination.account.class == 'sipaccount' then
+ destination.callee_id_name = destination.account.record.caller_name;
+ self.caller:set_callee_id(destination.number, destination.account.record.caller_name);
+ table.insert(destination.pickup_groups, 's' .. destination.account.id );
end
+ require 'common.group';
+ local group_names, group_ids = common.group.Group:new{ log = self.log, database = self.database }:name_id_by_permission(destination.id, destination.type, 'pickup');
+ self.log:debug('DESTINATION_GROUPS - pickup_groups: ', table.concat(group_names, ','));
+ for index=1, #group_ids do
+ table.insert(destination.pickup_groups, 'g' .. group_ids[index]);
+ end
+ end
- if destination.account and destination.account.owner then
- if destination.account.owner.class == 'user' then
- user_id = destination.account.owner.id;
- tenant_id = tonumber(destination.account.owner.record.current_tenant_id);
- elseif destination.account.owner.class == 'tenant' then
- tenant_id = destination.account.owner.id;
- end
+ if destination.account and destination.account.owner then
+ if destination.account.owner.class == 'user' then
+ user_id = destination.account.owner.id;
+ tenant_id = tonumber(destination.account.owner.record.current_tenant_id);
+ local user = self:object_find(destination.account.owner.class, tonumber(user_id));
+ elseif destination.account.owner.class == 'tenant' then
+ tenant_id = destination.account.owner.id;
end
+ end
+ end
- if user_id or tenant_id then
- require 'common.str'
- local phone_book_entry = nil;
+ if not self.caller.clir then
+ if user_id or tenant_id then
+ require 'common.str'
+ local phone_book_entry = nil;
- if self.phonebook_number_lookup then
- require 'dialplan.phone_book'
- phone_book_entry = dialplan.phone_book.PhoneBook:new{ log = self.log, database = self.database }:find_entry_by_number_user_tenant(self.caller.caller_phone_numbers, user_id, tenant_id);
- end
+ if self.phonebook_number_lookup then
+ require 'dialplan.phone_book'
+ phone_book_entry = dialplan.phone_book.PhoneBook:new{ log = self.log, database = self.database }:find_entry_by_number_user_tenant(self.caller.caller_phone_numbers, user_id, tenant_id);
+ end
- if phone_book_entry then
- self.log:info('PHONE_BOOK_ENTRY - phone_book=', phone_book_entry.phone_book_id, ' (', phone_book_entry.phone_book_name, '), caller_id_name: ', phone_book_entry.caller_id_name, ', ringtone: ', phone_book_entry.bellcore_id);
- destination.caller_id_name = common.str.to_ascii(phone_book_entry.caller_id_name);
- if tonumber(phone_book_entry.bellcore_id) then
- self.log:debug('RINGTONE - phonebookentry, index: ', phone_book_entry.bellcore_id);
- self.caller:export_variable('alert_info', 'http://amooma.de;info=Ringer' .. phone_book_entry.bellcore_id .. ';x-line-id=0');
- end
- if phone_book_entry.image then
- self:set_caller_picture(phone_book_entry.id, 'phonebookentry', 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);
- end
+ if phone_book_entry then
+ self.log:info('PHONE_BOOK_ENTRY - phone_book=', phone_book_entry.phone_book_id, ' (', phone_book_entry.phone_book_name, '), caller_id_name: ', phone_book_entry.caller_id_name, ', ringtone: ', phone_book_entry.bellcore_id);
+ destination.caller_id_name = common.str.to_ascii(phone_book_entry.caller_id_name);
+ if tonumber(phone_book_entry.bellcore_id) then
+ self.log:debug('RINGTONE - phonebookentry, index: ', phone_book_entry.bellcore_id);
+ self.caller:export_variable('alert_info', 'http://amooma.de;info=Ringer' .. phone_book_entry.bellcore_id .. ';x-line-id=0');
+ end
+ if phone_book_entry.image then
+ self:set_caller_picture(phone_book_entry.id, 'phonebookentry', 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);
- elseif self.geo_number_lookup then
- require 'dialplan.geo_number'
- local geo_number = dialplan.geo_number.GeoNumber:new{ log = self.log, database = self.database }:find(destination.caller_id_number);
- if geo_number then
- self.log:info('GEO_NUMBER - found: ', geo_number.name, ', ', geo_number.country);
- if geo_number.name then
- destination.caller_id_name = common.str.to_ascii(geo_number.name) .. ', ' .. common.str.to_ascii(geo_number.country);
- else
- destination.caller_id_name = common.str.to_ascii(geo_number.country);
- end
+ end
+ elseif self.caller.account and self.caller.account.owner then
+ self:set_caller_picture(self.caller.account.owner.id, self.caller.account.owner.class);
+ elseif self.geo_number_lookup then
+ require 'dialplan.geo_number'
+ local geo_number = dialplan.geo_number.GeoNumber:new{ log = self.log, database = self.database }:find(destination.caller_id_number);
+ if geo_number then
+ self.log:info('GEO_NUMBER - found: ', geo_number.name, ', ', geo_number.country);
+ if geo_number.name then
+ destination.caller_id_name = common.str.to_ascii(geo_number.name) .. ', ' .. common.str.to_ascii(geo_number.country);
+ else
+ destination.caller_id_name = common.str.to_ascii(geo_number.country);
end
end
end
@@ -997,6 +1024,7 @@ function Dialplan.run(self, destination)
destination = self:destination_new(result.call_forwarding);
self.caller.destination = destination;
+ self.caller.destination_number = destination.number;
if not result.no_cdr and auth_account then
require 'common.call_history'
diff --git a/misc/freeswitch/scripts/dialplan/dtmf.lua b/misc/freeswitch/scripts/dialplan/dtmf.lua
index 4dbd35f..64f538e 100644
--- a/misc/freeswitch/scripts/dialplan/dtmf.lua
+++ b/misc/freeswitch/scripts/dialplan/dtmf.lua
@@ -17,12 +17,17 @@ function Dtmf.new(self, arg)
self.bleg = arg.bleg
self.digit_timeout = arg.digit_timeout or 5;
self.router = arg.router;
+ self.digit_duration_min = arg.digit_duration_min or 500;
return object;
end
function Dtmf.detect(self, caller, sequence, digit, duration, calee)
+ if not tonumber(duration) or duration < self.digit_duration_min then
+ return;
+ end
+
local timestamp = os.time();
if timestamp - sequence.updated > self.digit_timeout then
sequence.digits = digit;
@@ -63,6 +68,9 @@ function Dtmf.transfer(self, caller, destination, calee)
caller:execute('transfer', destination);
fapi:execute('uuid_kill', callee_uuid);
else
+ if caller.account then
+ fapi:execute('uuid_setvar_multi', callee_uuid .. ' gs_auth_account_type=' .. caller.account.class .. ';gs_auth_account_uuid=' .. caller.account.uuid);
+ end
fapi:execute('uuid_transfer', callee_uuid .. ' ' .. destination);
caller.session:hangup();
end
diff --git a/misc/freeswitch/scripts/dialplan/fax.lua b/misc/freeswitch/scripts/dialplan/fax.lua
index 49a45d9..6dce0a9 100644
--- a/misc/freeswitch/scripts/dialplan/fax.lua
+++ b/misc/freeswitch/scripts/dialplan/fax.lua
@@ -4,7 +4,7 @@
module(...,package.seeall)
-FAX_DOCUMENTS_DIRECTORY = '/tmp/'
+FAX_SPOOL_DIRECTORY = '/var/spool/freeswitch/'
FAX_PARALLEL_MAX = 8;
Fax = {}
@@ -18,7 +18,7 @@ function Fax.new(self, arg)
self.log = arg.log;
self.database = arg.database;
self.record = arg.record;
- self.fax_directory = arg.fax_directory or FAX_DOCUMENTS_DIRECTORY;
+ self.fax_spool_directory = arg.fax_spool_directory or FAX_SPOOL_DIRECTORY;
return object;
end
@@ -79,7 +79,7 @@ end
-- List waiting fax documents
function Fax.queued_for_sending(self, limit)
limit = limit or FAX_PARALLEL_MAX;
- local sql_query = 'SELECT * FROM `fax_documents` WHERE `state` IN ("queued_for_sending","unsuccessful") AND `retry_counter` > 0 ORDER BY `sent_at` ASC LIMIT ' .. limit;
+ local sql_query = 'SELECT * FROM `fax_documents` WHERE `state` IN ("queued_for_sending","unsuccessful") AND `retry_counter` > 0 AND `tiff` IS NOT NULL AND `tiff` != "" ORDER BY `sent_at` ASC LIMIT ' .. limit;
local fax_documents = {}
self.database:query(sql_query, function(fax_entry)
fax_entry['destination_numbers'] = Fax:destination_numbers(fax_entry.id)
@@ -136,7 +136,7 @@ end
-- Receive Fax
function Fax.receive(self, caller, file_name)
- file_name = file_name or self.fax_directory .. 'fax_in_' .. caller.uuid .. '.tiff';
+ file_name = file_name or self.fax_spool_directory .. 'fax_in_' .. caller.uuid .. '.tiff';
caller:set_variable('fax_ident', self.record.station_id)
caller:set_variable('fax_verbose', 'false')
diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua
index acfa336..3706872 100644
--- a/misc/freeswitch/scripts/dialplan/functions.lua
+++ b/misc/freeswitch/scripts/dialplan/functions.lua
@@ -35,10 +35,8 @@ function Functions.dialplan_function(self, caller, dialed_number)
if fid == "ta" then
result = self:transfer_all(caller, parameters[3]);
- elseif fid == "in" then
- result = self:intercept_extensions(caller, parameters[3]);
elseif fid == "ia" then
- result = self:intercept_any_extension(caller, parameters[3]);
+ result = self:intercept_any_number(caller, parameters[3]);
elseif fid == "anc" then
result = self:account_node_change(caller);
elseif fid == "li" then
@@ -113,9 +111,11 @@ function Functions.dialplan_function(self, caller, dialed_number)
result = self:hangup(caller, parameters[3], parameters[4]);
elseif fid == "cpa" then
result = self:call_parking_inout(caller, parameters[3], parameters[4]);
+ elseif fid == "cpai" then
+ result = self:call_parking_inout_index(caller, parameters[3]);
end
- return result;
+ return result or { continue = false, code = 505, phrase = 'Error executing function', no_cdr = true };
end
-- Transfer all calls to a conference
@@ -149,94 +149,27 @@ function Functions.transfer_all(self, caller, destination_number)
return destination_number;
end
--- Intercept Extensions
-function Functions.intercept_extensions(self, caller, destination_numbers)
- if type(destination_numbers) == "string" then
- destination_numbers = "\"" .. destination_numbers .. "\"";
- else
- destination_numbers = "\"" .. table.concat(destination_numbers, "\",\"") .. "\"";
- end
-
- self.log:debug("Intercept call to number(s): " .. destination_numbers);
-
- if caller.account_type ~= "SipAccount" then
- self.log:error("caller is not a SipAccount");
- return { continue = false, code = 403, phrase = 'Incompatible caller' }
- end
- local sql_query = 'SELECT * FROM `channels` WHERE `callstate` IN ("EARLY", "ACTIVE") AND `dest` IN (' .. destination_numbers .. ') LIMIT 1';
-
- self.database:query(sql_query, function(call_entry)
- self.log:debug("intercepting call with uid: " .. call_entry.uuid);
- caller:intercept(call_entry.uuid);
- end)
-
- return nil;
-end
+function Functions.intercept_any_number(self, caller, destination_number)
+ require 'common.phone_number'
+ local phone_number = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database }:find_by_number(destination_number);
--- intercept call to destination (e.g. sip_account)
-function Functions.intercept_destination(self, caller, destination)
- self.log:debug("Intercept call to destination " .. destination);
- local result = false;
- local sql_query = 'SELECT `call_uuid`, `uuid` FROM `channels` WHERE `callstate` = "RINGING" AND `dest` = "' .. destination .. '" LIMIT 1';
+ if not phone_number or not phone_number.record then
+ self.log:notice('FUNCTION_INTERCEPT_ANY_NUMBER - number not found: ', destination_number);
+ return { continue = false, code = 404, phrase = 'Number not found', no_cdr = true };
+ end
- caller:set_caller_id(caller.caller_phone_numbers[1] ,caller.caller_id_name);
- self.database:query(sql_query, function(call_entry)
- if call_entry.call_uuid and tostring(call_entry.call_uuid) then
- self.log:debug("intercepting call - uuid: " .. call_entry.call_uuid);
- caller:intercept(call_entry.call_uuid);
- result = { continue = false, code = 200, call_service = 'pickup' }
- require 'common.str'
- require 'common.fapi'
- local fapi = common.fapi.FApi:new{ log = self.log, uuid = call_entry.call_uuid }
- if fapi:channel_exists() then
- caller:set_caller_id(
- common.str.to_s(fapi:get_variable('effective_caller_id_number')),
- common.str.to_s(fapi:get_variable('effective_caller_id_name'))
- );
- caller:set_callee_id(
- common.str.to_s(fapi:get_variable('effective_callee_id_number')),
- common.str.to_s(fapi:get_variable('effective_callee_id_name'))
- );
-
- caller:set_variable('gs_destination_type', fapi:get_variable('gs_destination_type'));
- caller:set_variable('gs_destination_id', fapi:get_variable('gs_destination_id'));
- caller:set_variable('gs_destination_uuid', fapi:get_variable('gs_destination_uuid'));
-
- caller:set_variable('gs_caller_account_type', fapi:get_variable('gs_account_type'));
- caller:set_variable('gs_caller_account_id', fapi:get_variable('gs_account_id'));
- caller:set_variable('gs_caller_account_uuid', fapi:get_variable('gs_account_uuid'));
-
- caller:set_variable('gs_auth_account_type', fapi:get_variable('gs_auth_account_type'));
- caller:set_variable('gs_auth_account_id', fapi:get_variable('gs_auth_account_id'));
- caller:set_variable('gs_auth_account_uuid', fapi:get_variable('gs_auth_account_uuid'));
- end
- else
- self.log:error('FUNCTION - failed to intercept call - no caller uuid for callee uuid: ', call_entry.uuid);
- end
- end)
+ if not phone_number.record.phone_numberable_type:lower() == 'sipaccount' or not tonumber(phone_number.record.phone_numberable_id) then
+ self.log:notice('FUNCTION_INTERCEPT_ANY_NUMBER - destination: ', phone_number.record.phone_numberable_type:lower(), '=', phone_number.record.phone_numberable_id, ', number: ', destination_number);
+ return { continue = false, code = 505, phrase = 'Incompatible destination', no_cdr = true };
+ end
- return result;
-end
+ self.log:info('FUNCTION_INTERCEPT_ANY_NUMBER intercepting call - to: ', phone_number.record.phone_numberable_type:lower(), '=', phone_number.record.phone_numberable_id, ', number: ', destination_number);
--- intercept call to owner of destination_number
-function Functions.intercept_any_extension(self, caller, destination_number)
- require 'common.phone_number'
- local phone_number_object = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database }:find_by_number(destination_number);
+ caller:set_variable('gs_pickup_group_pick', 's' .. phone_number.record.phone_numberable_id);
+ caller:execute('pickup', 's' .. phone_number.record.phone_numberable_id);
- if not phone_number_object or not phone_number_object.record then
- self.log:notice("unallocated number: " .. tostring(destination_number));
- return false;
- end
-
- if phone_number_object.record.phone_numberable_type == 'SipAccount' then
- require "common.sip_account"
- local sip_account_class = common.sip_account.SipAccount:new{ log = self.log, database = self.database }
- local sip_account = sip_account_class:find_by_id(phone_number_object.record.phone_numberable_id)
- if sip_account then
- return self:intercept_destination(caller, sip_account.record.auth_name);
- end
- end
+ return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
end
@@ -932,3 +865,39 @@ function Functions.call_parking_inout(self, caller, stall_name, lot_name)
return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
end
+
+
+function Functions.call_parking_inout_index(self, caller, stall_index)
+ if not tonumber(stall_index) then
+ self.log:notice('FUNCTION_CALL_PARKING_INOUT_INDEX - malformed index: ', stall_index);
+ return { continue = false, code = 404, phrase = 'No parkings stall specified', no_cdr = true }
+ end
+
+ require 'common.str';
+ local owner = common.str.try(caller, 'auth_account.owner');
+
+ if not owner then
+ self.log:notice('FUNCTION_CALL_PARKING_INOUT_INDEX - stall owner not specified');
+ return { continue = false, code = 404, phrase = 'No parkings stalls owner' , no_cdr = true }
+ end
+
+ require 'dialplan.call_parking';
+ local parking_stalls = dialplan.call_parking.CallParking:new{ log = self.log, database = self.database, caller = caller }:find_by_owner(owner.id, owner.class);
+
+ if not parking_stalls or #parking_stalls < 1 then
+ self.log:notice('FUNCTION_CALL_PARKING_INOUT_INDEX - no parkings stalls found');
+ return { continue = false, code = 404, phrase = 'No parkings stalls', no_cdr = true }
+ end
+
+ local parking_stall = parking_stalls[tonumber(stall_index)];
+
+ if not parking_stall then
+ self.log:notice('FUNCTION_CALL_PARKING_INOUT_INDEX - no parkings stall found with index: ', stall_index);
+ return { continue = false, code = 404, phrase = 'Parking stall not found', no_cdr = true }
+ end
+
+ self.log:info('FUNCTION_CALL_PARKING_INOUT_INDEX parking/retrieving call - parkingstall=', parking_stall.id, '/', parking_stall.name, ', index: ', stall_index);
+ parking_stall:park_retrieve();
+
+ return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
+end
diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua
index b56f1b2..5c98792 100644
--- a/misc/freeswitch/scripts/dialplan/sip_call.lua
+++ b/misc/freeswitch/scripts/dialplan/sip_call.lua
@@ -76,7 +76,8 @@ end
function SipCall.fork(self, destinations, arg )
- local dial_strings = {}
+ local dial_strings = {};
+ local pickup_groups = {};
require 'common.sip_account'
require 'common.str'
@@ -135,6 +136,11 @@ function SipCall.fork(self, destinations, arg )
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);
+ if destination.pickup_groups and #destination.pickup_groups > 0 then
+ for key=1, #destination.pickup_groups do
+ pickup_groups[destination.pickup_groups[key]] = true;
+ end
+ end
else
some_destinations_busy = true;
call_result = { code = 486, phrase = 'User busy', disposition = 'USER_BUSY' };
@@ -184,6 +190,10 @@ function SipCall.fork(self, destinations, arg )
self.caller:set_variable('call_timeout', arg.timeout );
self.log:info('FORK DIAL - destinations: ', #dial_strings, ', timeout: ', arg.timeout);
+ for pickup_group, value in pairs(pickup_groups) do
+ table.insert(dial_strings, 'pickup/' .. pickup_group);
+ end
+
if arg.send_ringing then
self.caller:execute('ring_ready');
end
@@ -201,10 +211,20 @@ 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
+ if not destination then
+ destination = {
+ ['type'] = session_callee:getVariable('gs_account_type');
+ id = session_callee:getVariable('gs_account_id');
+ uuid = session_callee:getVariable('gs_account_uuid');
+ pickup_group_pick = session_callee:getVariable('gs_pickup_group_pick');
+ }
+ self.log:notice('FORK - call picked off by: ', destination.type, '=', destination.id, '/', destination.uuid, ', pickup_group: ', destination.pickup_group_pick);
+ end
+
+ if arg.detect_dtmf_after_bridge_caller and self.caller.auth_account then
session:execute('start_dtmf');
end
- if arg.detect_dtmf_after_bridge_callee then
+ if arg.detect_dtmf_after_bridge_callee and destination.type == 'sipaccount' then
session_callee:execute('start_dtmf');
end
if arg.bypass_media_network then
diff --git a/misc/freeswitch/scripts/dialplan/user.lua b/misc/freeswitch/scripts/dialplan/user.lua
index b536600..b6928b4 100644
--- a/misc/freeswitch/scripts/dialplan/user.lua
+++ b/misc/freeswitch/scripts/dialplan/user.lua
@@ -69,6 +69,23 @@ function User.list_groups(self, id)
end
+function User.list_group_ids(self, id)
+ require 'common.str'
+ id = id or self.id;
+ local sql_query = 'SELECT `b`.`id` FROM `user_group_memberships` `a` \
+ JOIN `user_groups` `b` ON `a`.`user_group_id` = `b`.`id` \
+ WHERE `a`.`state` = "active" AND `a`.`user_id`= ' .. tonumber(id) .. ' ORDER BY `b`.`position` LIMIT ' .. MAX_GROUP_MEMBERSHIPS;
+
+ local groups = {};
+
+ self.database:query(sql_query, function(entry)
+ table.insert(groups, common.str.downcase(entry.id));
+ end);
+
+ return groups;
+end
+
+
function User.check_pin(self, pin_to_check)
if not self.record then
return nil
diff --git a/misc/freeswitch/scripts/dialplan/voicemail.lua b/misc/freeswitch/scripts/dialplan/voicemail.lua
index 4c96fbe..ae7d0a1 100644
--- a/misc/freeswitch/scripts/dialplan/voicemail.lua
+++ b/misc/freeswitch/scripts/dialplan/voicemail.lua
@@ -11,7 +11,7 @@ MESSAGE_LENGTH_MAX = 120;
SILENCE_LENGTH_ABORT = 5;
SILENCE_LEVEL = 500;
BEEP = 'tone_stream://%(1000,0,500)';
-RECORD_FILE_PREFIX = '/tmp/voicemail_';
+RECORD_FILE_PREFIX = '/var/spool/freeswitch/voicemail_';
-- create voicemail object
function Voicemail.new(self, arg)