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:

.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 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.
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:

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:
  • .answered is true, and
  • the establish_new_call .presented_calling_party parameter was specified, and
  • the specified .presented_calling_party differed from the specified .calling_party, and
  • .is_calling_restricted is false
(Default = not present, the described value pre-conditions are not met).
.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:
  • .answered is true, and
  • an INVITE Response containing a parseable P-Asserted-Identity header is received, and
  • the P-Asserted-Identity header includes an Address userinfo part, and
  • the userinfo differs from the specified establish_new_call .called_party parameter value
(Default = not present, the described value pre-conditions are not met).
.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:
  • .answered is true, and
  • the establish_new_call .original_called_party parameter was specified, and
  • the specified .original_called_party differed from the specified .called_party
(Default = not present, the described value pre-conditions are not met).

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.