SIP Outcall Lua Agent
LhoSipOutcallLuaAgent Module
Introduction
The LhoSipOutcallLuaAgent is an asynchronous helper for Lua scripts running within the
LogicApp. It is used for initiating an outbound SIP call A-Leg. This agent will send
an outbound SIP INVITE Request to open an A-Leg and then will allow interaction and
B-Leg termination in the same manner as supported for inbound A-Legs.
For handling inbound SIP A-Leg calls you need to use the LhoSipIncallLuaService
The LhoSipOutcallLuaAgent communicates with one or more instances of the LhoSipApp which can be used to perform outcalls to external SIP UAC or SIP Gateways.
The LhoSipOutcallLuaAgent communicates with the LhoSipApp using the
SCC-… messages.
The LhoSipOutcallLuaAgent is tied to the outcall action key.
Configuring LhoSipOutcallLuaAgent
The LhoSipOutcallLuaAgent is configured within a LogicApp.
<?xml version="1.0" encoding="utf-8"?>
<n2svcd>
...
<applications>
...
<application name="Logic" module="LogicApp">
<include>
<lib>../apps/logic/lib</lib>
</include>
<parameters>
...
<parameter name="default_sip_outcall_app_name" value="LHO-SIP"/>
</parameters>
<config>
<services>
...
</services>
<agents>
<agent module="LhoSipApp::LhoSipOutcallLuaAgent" libs="../../n2sip/apps/lho_sip/lib"/>
</agents>
</config>
</application>
...
</applications>
...
</n2svcd>
Under normal installation, following agent attributes apply:
| Attribute | Type | XML Type | Description |
|---|---|---|---|
module
|
LhoSipApp::LhoSipOutcallLuaAgent
|
Attribute | [Required] The module name containing the Lua Agent code. |
libs
|
../../n2sip/apps/lho_sip/lib
|
Element |
Location of the module for LhoSipOutcallLuaAgent.
|
default_no_answer_secs
|
Positive Integer | Attribute |
The default number of seconds to wait for No Answer on the A-Leg outcall attempt,
when the service logic does not explicitly specify a no-answer timeout value. (Default = 60 seconds).
|
default_pa_wait_secs
|
1 - 600
|
Attribute |
The number of seconds to wait for a non-prompt Interaction
action to complete when the service logic does not specify a duration.(Default = 120 seconds).
|
default_pacui_wait_secs
|
1 - 600
|
Attribute |
The number of seconds to wait for a prompt Interaction
action to complete when the service logic does not specify a duration.(Default = 300 seconds).
|
wait_margin_secs
|
1 - 15
|
Attribute |
The number of seconds to add to the wait time for all SIP call control actions to account for round-trip latency. (Default = 5 seconds).
|
In addition, the LhoSipOutcallLuaAgent must be configured with the name of the LhoSipApp with which
it will communicate. This is configured within the parameters of the containing LogicApp.
| Attribute | Type | Description |
|---|---|---|
parameters
|
Array |
Array of name = value Parameters for this Application instance.
|
.default_sip_outcall_app_name
|
String |
Default name for the LhoSipApp to which LhoSipOutcallLuaAgent will send the request for initiating the outbound A-Leg SIP INVITE Request.
|
Invoking LhoSipOutcallLuaAgent
A Lua Script can access the LhoSipOutcallLuaAgent outcall action with code such as the following.
In this example, the Lua script performing the outcall has been started as the result of receiving an inbound REST Request (via the RestLuaService). In practice, any Lua Script may use the outcall agent, independent of how the Lua script itself was initiated.
local n2svcd = require "n2.n2svcd"
local rest_service = require "n2.n2svcd.rest_service"
local sip_outcall_agent = require "n2.n2svcd.sip_outcall_agent"
local rest = ...
if (type (rest.query_args) ~= 'table') then
error ("Missing REST Query Args for SIP Outcall")
end
local calling_party = rest.query_args.calling_party
local called_party = rest.query_args.called_party
local result = sip_outcall_agent.outcall (calling_party, called_party)
if (not result.controlled) then
return result.reason
end
-- We're going to return now, before the REST Server gives up on us.
rest_service.response ("ANSWERED")
result = sip_outcall_agent.rtp_interaction ({ message_id = 25046, variables = { { number_digits = "1234" } } })
if (not result.controlled) then
return nil
end
sip_outcall_agent.hangup ()
return
This is standard Lua-style library usage. The n2/n2svcd/sip_outcall_agent.lua library is loaded
with require "n2.n2svcd.sip_outcall_agent". Then methods are invoked on the returned library object.
The LhoSipOutcallLuaAgent API
All methods may raise a Lua Error in the case of exception, including:
- Invalid input parameters supplied by Lua script.
- Unexpected results structure returned from
LhoSipApp. - Processing error occurred at
LhoSipApp. - Timeout occurred when waiting for the
LhoSipAppresponse.
.establish_new_call [Asynchronous]
The establish_new_call method initiates an outbound A-Leg SIP INVITE Request. The method parameters are:
| Field | Type | Description |
|---|---|---|
details
|
Table | [Required] The detailed SIP parameters for the message. |
.calling_party
|
(+)Hex String |
[Required] The userinfo part of the calling party for the INVITE Request.The protocol and domain parts of the address will be determined automatically. The applicable configured calling_party denormalisation on the LhoSipApp will be applied.The calling party will be placed in either the P-Asserted-Identity or
From header, depending on whether presentation of the calling party is
restricted or not.
|
.presented_calling_party
|
(+)Hex String |
The userinfo part of the INVITE Request From header address.The protocol and domain parts of the address will be determined automatically. The applicable configured calling_party denormalisation on the LhoSipApp will be applied.This parameter will have no effect if .is_calling_restricted is true.(Default = .calling_party).
|
.is_calling_restricted
|
Boolean |
Specify whether presentation of the calling party should be restricted. When restricted, the outbound INVITE Request From and Contact headers will
be anonymous, and a Privacy header containing the id flag will be
included.When not restricted, the outbound INVITE Request From and Contact headers
will not be anonymous, and a Privacy header will not be included.(Default = false, not restricted).
|
.called_party
|
(+)Hex String |
[Required] The userinfo part of the INVITE Request URI addressThe protocol and domain parts of the address will be determined automatically. The applicable configured called_party denormalisation on the LhoSipApp will be applied.This parameter value will also be used as the userinfo part of the INVITE
Request To header address if the .original_called_party parameter is not specified.
|
.original_called_party
|
(+)Hex String |
The userinfo part of the INVITE Request To header address.The protocol and domain parts of the address will be determined automatically. The applicable configured called_party denormalisation on the LhoSipApp will be applied.(Default = .called_party).
|
.no_answer_timeout
|
Positive Integer |
Specifies the desired time limit for INVITE Request processing in seconds. The LhoSipApp will enforce a maximum bound for this value.A CANCEL Request will be sent if a Final Response is not received within this time. (Default = use the default_no_answer_secs configured on the LhoSipOutcallLuaAgent).
|
.extra_headers
|
Table |
Additional user headers to include in the SIP INVITE Request. The table keys are header names. The table values are tables of header values. (Default = do not add extra user headers). |
The establish_new_call method returns a Lua table with the following attributes.
The outcall attempt will return to the Lua service logic only when one of the following conditions is met:
- The outcall attempt is unacceptable and cannot be processed.
- No SIP Route is available towards the indicated called party.
- A SIP INVITE Final Response with code
300-699(not answered) is received. - A SIP INVITE Final Response with code
200-299(answered) is received. - An unacceptable SIP INVITE Provisional or Final Response is received.
- The No Answer time expires before a SIP INVITE Final Response is received.
| Attribute | Type | Description |
|---|---|---|
.controlled
|
Boolean |
[Required] Is this call still controlled right now? This value will be true if and only if the answered field is
true, and indicates that (at least some) telephony API actions can be performed
by service logic.Note that in some cases the available control actions may be limited. |
.answered
|
Boolean |
[Required] Was this call answered. This value being true indicates that the A-Leg outcall attempt received a SIP INVITE Final Response
that indicated success, i.e. typically 200 OK.Receipt of a Provisional Response is never considered an "answered" call, even if it results in early media. |
.reason
|
No Route / Declined / No Answer / Answered
|
[Required] The reason why the outcall attempt ended. |
.code
|
Integer |
A SIP Final Response code (in the range 200-699) associated with the A-Leg outcall attempt.This value is present only when the A-Leg outcall attempt received a SIP INVITE Final Response. |
.call_id
|
String |
The Call-ID header value from the sent SIP INVITE Request.This value is present only when .answered is true.(Default = not present, .answered is false).
|
.privacy
|
Table |
This value is present only when .answered is true and
one or more Privacy headers are present in one of the received SIP INVITE Responses.This table will have entries with keys matching each of the Privacy flags which are present in the headers from the first Response that contains one or more headers. Table values will be 1.For example if a Privacy header has value user;id then this table will
be { user = 1, id = 1 }.(Default = not present, .answered is false or the header was not present in any Response).
|
.p_preferred_identities
|
Table |
Table of P-Preferred-Identity header values from one of the received SIP INVITE Responses.This value is present only when .answered is true and the first Response containing one or more P-Preferred-Identity
or P-Asserted-Identity headers contains one or more P-Preferred-Identity headers.(Default = not present, .answered is false, or the header was not present in any Response, or the header was not present in the first Response containing P-Asserted-Identity headers).
|
.p_asserted_identities
|
Table |
Table of P-Asserted-Identity header values from one of the received SIP INVITE Responses.This value is present only when .answered is true and the first Response containing one or more P-Preferred-Identity
or P-Asserted-Identity headers contains one or more P-Asserted-Identity headers.(Default = not present, .answered is false, or the header was not present in any Response, or the header was not present in the first Response containing P-Preferred-Identity headers).
|
.p_charging_vector
|
String |
The P-Charging-Vector header value from the sent SIP INVITE Request or the most recently received Response containing a P-Charging-Vector header.This value is present only when .answered is true and a P-Charging-Vector header is present in the Request or one of the Responses.(Default = not present, .answered is false or the header was not present in the Request or any Response).
|
.calling_party
|
(+)Hex String |
This is the establish_new_call .calling_party parameter value,
sent in the userinfo part of the SIP INVITE Request P-Asserted-Identity or From header Address.It is guaranteed to contain only 0-9A-F digits.This value is present only when .answered is true.(Default = not present, .answered is false).
|
.is_calling_restricted
|
Boolean |
[Required] Is presentation of the Calling Party restricted? This value will be true if presentation restriction was applied to the calling party in the sent SIP INVITE Request.
|
.presented_calling_party
|
(+)Hex String |
This is the userinfo part of the SIP INVITE Request From header Address.It is guaranteed to contain only 0-9A-F digits.This value is present only when:
|
.called_party
|
(+)Hex String |
In most cases this is the establish_new_call .called_party parameter value,
sent in the userinfo part of the SIP INVITE Request URI Address.The specified .called_party will be overridden if an INVITE Response containing a parseable P-Asserted-Identity header that includes an Address userinfo part is received.It is guaranteed to contain only 0-9A-F digits.This value is present only when .answered is true.(Default = not present, .answered is false).
|
.presented_called_party
|
(+)Hex String |
This is the userinfo part of the SIP INVITE Request To header Address.It is guaranteed to contain only 0-9A-F digits.This value is present only when:
|
.is_called_restricted
|
Boolean |
Is presentation of the Called Party restricted? This value will be true if .privacy contains the id or user flags.This value is present only when .answered is true.(Default = not present, .answered is false).
|
.original_called_party
|
(+)Hex String |
This is the establish_new_call .original_called_party parameter value,
sent in the userinfo part of the SIP INVITE Request To header Address.It is guaranteed to contain only 0-9A-F digits.This value is present only when:
|
Example:
local result = sip_outcall.establish_new_call ({ calling_party = "7000", called_party = "100123", is_calling_restricted = true })
if (not result.answered) then
return "NOT ANSWERED .. " . result.reason
end
.outcall [Asynchronous]
This helper method provides a simplified flattened-argument version of the establish_new_call method.
The outcall method takes the following arguments:
| Field | Type | Description |
|---|---|---|
calling_party
|
(+)Hex String |
[Required] The userinfo part of the INVITE Request From header address.The protocol and domain parts of the address will be determined automatically. The applicable configured calling_party denormalisation on the LhoSipApp will be applied.
|
called_party
|
(+)Hex String |
[Required] The userinfo part of the INVITE Request To header address.The protocol and domain parts of the address will be determined automatically. The applicable configured called_party denormalisation on the LhoSipApp will be applied.
|
no_answer_timeout
|
Positive Integer |
Specifies the desired time limit for INVITE Request processing in seconds. The LhoSipApp will enforce a maximum bound for this value.A CANCEL Request will be sent if a Final Response is not received within this time. (Default = use the default_no_answer_secs configured on the LhoSipOutcallLuaAgent).
|
The outcall method returns the same table structure as establish_new_call.
Example:
local result = sip_outcall.outcall ("7000", "100123")
if (not result.answered) then
return "NOT ANSWERED .. " . result.reason
end
Hangup
Once the outcall is connected to the A-Party, Hangup can be performed as described for the SIP Incall Lua Service / Hangup.
Note that hangup of an outcall A-Leg is always performed using BYE.
Interaction (Internal RTP)
Once the outcall is connected to the A-Party, Internal RTP Interaction can be performed as described for the SIP Incall Lua Service / Interaction RTP.
Internal RTP Interaction refers to interaction which is performed using a co-located, on-platform RTP media server via the RtpApp.
Interaction (External INAP)
Once the outcall is connected to the A-Party, External INAP Interaction can be performed as described for the SIP Incall Lua Service / Interaction INAP.
External INAP Interaction refers to interaction which is performed by opening a B-Leg to an off-platform, independent INAP-Controlled IVR platform.
Termination (Attempt)
Once the outcall is connected to the A-Party, Termination (Attempt) can be performed as described for the SIP Incall Lua Service / Termination (Attempt).
Charged and Monitored Terminations are fully supported.