fusionpbx/resources/install/scripts/resources/functions/esl.lua

170 lines
3.8 KiB
Lua

local function class(base)
local t = base and setmetatable({}, base) or {}
t.__index = t
t.__class = t
t.__base = base
function t.new(...)
local o = setmetatable({}, t)
if o.__init then
if t == ... then -- we call as Class:new()
return o:__init(select(2, ...))
else -- we call as Class.new()
return o:__init(...)
end
end
return o
end
return t
end
local EventSocket = class() do
if not freeswitch then
local socket = require "socket"
local ESLParser = require "lluv.esl".ESLParser
local split_status = require "lluv.esl.utils".split_status
local Database = require "resources.functions.database"
local EOL = '\n'
local host, port, auth
function EventSocket:__init()
if not host then
local db = Database.new('system')
local settings, err = db:first_row("select event_socket_ip_address, event_socket_port, event_socket_password from v_settings")
if not settings then return nil, err end
host, port, auth = settings.event_socket_ip_address, settings.event_socket_port, settings.event_socket_password
end
return self:_connect(host, port, auth)
end
function EventSocket:_connect(host, port, password)
local err
self._cnn, err = socket.connect(host, port)
if not self._cnn then return nil, err end
self._cnn:settimeout(1)
self._parser = ESLParser.new()
local auth
while true do
local event
event, err = self:_recv_event()
if not event then break end
local ct = event:getHeader('Content-Type')
if ct == 'auth/request' then
self._cnn:send('auth ' .. password .. EOL .. EOL)
elseif ct == 'command/reply' then
local reply = event:getHeader('Reply-Text')
if reply then
local ok, status, msg = split_status(reply)
if ok then auth = true else err = msg end
else
err = 'invalid response'
end
break
end
end
if not auth then
self._cnn:close()
self._cnn = nil
return nil, err
end
return self
end
function EventSocket:_recv_event()
local event, err = self._parser:next_event()
while event == true do
local str, rst
str, err, rst = self._cnn:receive("*l")
if str then self._parser:append(str):append(EOL) end
if rst then self._parser:append(rst) end
if err and err ~= 'timeout' then
break
end
event = self._parser:next_event()
end
if (not event) or (event == true) then
return nil, err
end
return event
end
function EventSocket:_request(cmd)
if not self._cnn then return nil, 'closed' end
for str in (cmd .. '\n'):gmatch("(.-)\n") do
self._cnn:send(str .. EOL)
end
self._cnn:send(EOL)
return self:_recv_event()
end
function EventSocket:api(cmd)
local event, err = self:_request('api ' .. cmd)
if not event then return nil, err end
local body = event:getBody()
if body then
local ok, status, msg = split_status(body)
if ok == nil then return body end
return ok, status, msg
end
return event:getReply()
end
function EventSocket:close()
if self._cnn then
self._cnn:close()
self._cnn = nil
end
end
end
if freeswitch then
local api
-- [+-][OK|ERR|USAGE|...][Message]
local function split_status(str)
local ok, status, msg = string.match(str, "^%s*([-+])([^%s]+)%s*(.-)%s*$")
if not ok then return nil, str end
return ok == '+', status, msg
end
function EventSocket:__init()
self._api = api or freeswitch.API()
api = self._api
return self
end
function EventSocket:api(cmd)
local result = self._api:executeString(cmd)
local ok, status, msg = split_status(result)
if ok == nil then return result end
return ok, status, msg
end
function EventSocket:close()
self._api = nil
end
end
end
return EventSocket