summaryrefslogtreecommitdiff
path: root/misc/freeswitch/scripts/event/presence_update.lua
diff options
context:
space:
mode:
Diffstat (limited to 'misc/freeswitch/scripts/event/presence_update.lua')
-rw-r--r--misc/freeswitch/scripts/event/presence_update.lua142
1 files changed, 106 insertions, 36 deletions
diff --git a/misc/freeswitch/scripts/event/presence_update.lua b/misc/freeswitch/scripts/event/presence_update.lua
index 01ec17b..f9d8ee7 100644
--- a/misc/freeswitch/scripts/event/presence_update.lua
+++ b/misc/freeswitch/scripts/event/presence_update.lua
@@ -10,6 +10,13 @@ ACCOUNT_RECORD_TIMEOUT = 120;
PresenceUpdate = {}
function PresenceUpdate.new(self, arg)
+ require 'common.sip_account';
+ require 'dialplan.presence';
+ require 'common.str';
+ require 'common.phone_number';
+ require 'common.fapi';
+ require 'common.configuration_table';
+
arg = arg or {}
object = arg.object or {}
setmetatable(object, self);
@@ -21,6 +28,13 @@ function PresenceUpdate.new(self, arg)
self.presence_accounts = {}
self.account_record = {}
+ self.config = common.configuration_table.get(self.database, 'presence_update');
+ self.config = self.config or {};
+ self.config.trigger = self.config.trigger or {
+ sip_account_presence = true,
+ sip_account_register = true,
+ sip_account_unregister = true,
+ };
return object;
end
@@ -34,10 +48,29 @@ function PresenceUpdate.event_handlers(self)
end
+function PresenceUpdate.retrieve_sip_account(self, account, uuid)
+ uuid = uuid or 'presence_update';
+
+ if not self.account_record[account] or ((os.time() - self.account_record[account].created_at) > ACCOUNT_RECORD_TIMEOUT) then
+ self.log:debug('[', uuid,'] PRESENCE - retrieve account data - account: ', account);
+
+ local sip_account = common.sip_account.SipAccount:new{ log = self.log, database = self.database }:find_by_auth_name(account);
+ if not sip_account then
+ return
+ end
+
+ local phone_numbers = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database }:list_by_owner(sip_account.id, sip_account.class);
+
+ self.account_record[account] = { id = sip_account.id, class = sip_account.class, phone_numbers = phone_numbers, created_at = os.time() }
+ end
+
+ return self.account_record[account];
+end
+
+
function PresenceUpdate.presence_probe(self, event)
local DIALPLAN_FUNCTION_PATTERN = '^f[_%-].*';
- require 'common.str'
local event_to = event:getHeader('to');
local event_from = event:getHeader('from');
local probe_type = event:getHeader('probe-type');
@@ -59,6 +92,13 @@ end
function PresenceUpdate.sofia_register(self, event)
local account = event:getHeader('from-user');
+ local timestamp = event:getHeader('Event-Date-Timestamp');
+
+ local sip_account = self:retrieve_sip_account(account, account);
+ if sip_account and common.str.to_b(self.config.trigger.sip_account_register) then
+ self:trigger_rails(sip_account, 'register', timestamp, account)
+ end
+
self.log:debug('[', account, '] PRESENCE_UPDATE - flushing account cache on register');
self.presence_accounts[account] = nil;
end
@@ -66,28 +106,48 @@ end
function PresenceUpdate.sofia_ungerister(self, event)
local account = event:getHeader('from-user');
+ local timestamp = event:getHeader('Event-Date-Timestamp');
+
+ local sip_account = self:retrieve_sip_account(account, account);
+ if sip_account and common.str.to_b(self.config.trigger.sip_account_unregister) then
+ self:trigger_rails(sip_account, 'unregister', timestamp, account)
+ end
+
self.log:debug('[', account, '] PRESENCE_UPDATE - flushing account cache on unregister');
self.presence_accounts[account] = nil;
end
function PresenceUpdate.presence_in(self, event)
- if not event:getHeader('status') then
- return
- end
-
local account, domain = common.str.partition(event:getHeader('from'), '@');
- local direction = tostring(event:getHeader('presence-call-direction'))
+ local call_direction = tostring(event:getHeader('presence-call-direction') or event:getHeader('call-direction'))
local state = event:getHeader('presence-call-info-state');
local uuid = event:getHeader('Unique-ID');
local caller_id = event:getHeader('Caller-Caller-ID-Number');
+ local protocol = tostring(event:getHeader('proto'));
+ local timestamp = event:getHeader('Event-Date-Timestamp');
+ local direction = nil;
+
+ if call_direction == 'inbound' then
+ direction = true;
+ elseif call_direction == 'outbound' then
+ direction = false;
+ end
- if direction == 'inbound' then
- self.log:info('[', uuid,'] PRESENCE_INBOUND: account: ', account, ', state: ', state);
- self:sip_account(true, account, domain, state, uuid);
- elseif direction == 'outbound' then
- self.log:info('[', uuid,'] PRESENCE_OUTBOUND: account: ', account, ', state: ', state, ', caller: ', caller_id);
- self:sip_account(false, account, domain, state, uuid, caller_id);
+ if protocol == 'conf' then
+ state = event:getHeader('answer-state');
+ local login = tostring(event:getHeader('proto'));
+ 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 protocol == 'sip' and common.str.blank(state) then
+ self.log:debug('[', uuid,'] PRESENCE_', call_direction:upper(),' no state - protocol: ', protocol, ', account: ', account);
+ return;
+ end
+ self.log:info('[', uuid,'] PRESENCE_', call_direction:upper(),' - protocol: ', protocol, ', account: ', account, ', state: ', state);
+ self:sip_account(direction, account, domain, state, uuid, caller_id, timestamp);
+ else
+ self.log:info('[', uuid,'] PRESENCE_', call_direction:upper(),' unhandled protocol: ', protocol, ', account: ', account, ', state: ', state);
end
end
@@ -114,10 +174,9 @@ end
function PresenceUpdate.call_forwarding(self, account, domain, call_forwarding_id)
- require 'common.call_forwarding'
- local call_forwarding = common.call_forwarding.CallForwarding:new{ log=self.log, database=self.database, domain=domain }:find_by_id(call_forwarding_id);
-
- require 'common.str'
+ require 'common.call_forwarding';
+
+ local call_forwarding = common.call_forwarding.CallForwarding:new{ log=self.log, database=self.database, domain=domain }:find_by_id(call_forwarding_id);
if call_forwarding and common.str.to_b(call_forwarding.record.active) then
local destination_type = tostring(call_forwarding.record.call_forwardable_type):lower()
@@ -138,7 +197,6 @@ function PresenceUpdate.hunt_group_membership(self, account, domain, member_id)
if status then
self.log:debug('[', account, '] PRESENCE_UPDATE - updating hunt group membership presence - id: ', member_id);
- require 'dialplan.presence'
local presence_class = dialplan.presence.Presence:new{
log = self.log,
database = self.database,
@@ -156,7 +214,6 @@ function PresenceUpdate.acd_membership(self, account, domain, member_id)
if status then
self.log:debug('[', account, '] PRESENCE_UPDATE - updating ACD membership presence - id: ', member_id);
- require 'dialplan.presence'
local presence_class = dialplan.presence.Presence:new{
log = self.log,
database = self.database,
@@ -168,32 +225,45 @@ function PresenceUpdate.acd_membership(self, account, domain, member_id)
end
-function PresenceUpdate.sip_account(self, inbound, account, domain, status, uuid, caller_id)
+function PresenceUpdate.sip_account(self, inbound, account, domain, status, uuid, caller_id, timestamp)
local status_map = { progressing = 'early', alerting = 'confirmed', active = 'confirmed' }
+
+ local sip_account = self:retrieve_sip_account(account, uuid);
+ if not sip_account then
+ return;
+ end
- if not self.account_record[account] or ((os.time() - self.account_record[account].created_at) > ACCOUNT_RECORD_TIMEOUT) then
- self.log:debug('[', uuid,'] PRESENCE - retrieve account data - account: ', account);
-
- require 'common.sip_account'
- local sip_account = common.sip_account.SipAccount:new{ log = self.log, database = self.database }:find_by_auth_name(account);
-
- if not sip_account then
- return
- end
-
- require 'common.phone_number'
- local phone_numbers = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database }:list_by_owner(sip_account.id, sip_account.class);
+ dialplan.presence.Presence:new{
+ log = self.log,
+ database = self.database,
+ inbound = inbound,
+ domain = domain,
+ accounts = sip_account.phone_numbers,
+ uuid = uuid
+ }:set(status_map[status] or 'terminated', caller_id);
- self.account_record[account] = { id = sip_account.id, class = sip_account.class, phone_numbers = phone_numbers, created_at = os.time() }
+ if common.str.to_b(self.config.trigger.sip_account_presence) then
+ self:trigger_rails(sip_account, status_map[status] or 'terminated', timestamp, uuid);
end
+end
- require 'dialplan.presence'
- local result = dialplan.presence.Presence:new{
+
+function PresenceUpdate.conference(self, inbound, account, domain, status, uuid)
+
+ dialplan.presence.Presence:new{
log = self.log,
database = self.database,
inbound = inbound,
domain = domain,
- accounts = self.account_record[account].phone_numbers,
+ accounts = { account },
uuid = uuid
- }:set(status_map[status] or 'terminated', caller_id);
+ }:set(status or 'terminated');
+end
+
+
+function PresenceUpdate.trigger_rails(self, account, status, timestamp, uuid)
+ if account.class == 'sipaccount' then
+ local command = 'http_request.lua ' .. tostring(uuid) .. ' http://127.0.0.1/trigger/sip_account_update/' .. tostring(account.id) .. '?timestamp=' .. timestamp .. '&status=' .. tostring(status);
+ common.fapi.FApi:new():execute('luarun', command);
+ end
end