Setup & Context
Introduction
These methods in from TestSipLuaAgent Lua API are methods called prior to performing the SIP Test actions, for the purpose of setting up the endpoints and the context in preperation for an INVITE or non-INVITE transaction, including registration for inbound transactions.
Setup & Context API
.default_endpoints [Synchronous]
An “endpoints” object is a representation of the IP address and port numbers which will be used for the a SIP message flow test, either outcall (we send SIP INVITE) or incall (we receive SIP INVITE). This structure is also required for non-INVITE test scripts.
The default_endpoints
method is the standard way to initialize the endpoints object. It will simply
set the required SIP and RTP IP address and UDP/TCP port numbers into a single table by taking them
from the LogicApp
global defaults, with optional overrides.
The method takes a single, optional custom
argument which allows for the explicit override of the
individual default values. The most common parameter to override is the RTP port number, which is
dynamically assigned by the TestRtpApp
and which is unique to the call for the lifetime of that
RTP stream.
Argument | Type | Description |
---|---|---|
custom
|
Object |
Container for override values. (Default = use default global values for all endpoints). |
.local_sip_ip
|
IPv4 Address |
Override the local SIP IP address (the address of our near SIP endpoint). (Default = the value of the LOCAL_SIP_IP Lua global).
|
.local_sip_port
|
Integer |
Override the local SIP UDP port (the port of our near SIP endpoint). (Default = the value of the LOCAL_SIP_PORT Lua global).
|
.remote_sip_ip
|
IPv4 Address |
Override the remote SIP IP address (the address of the far SIP endpoint). (Default = the value of the REMOTE_SIP_IP Lua global).
|
.remote_sip_ip
|
Integer |
Override the remote SIP UDP port (the port of the far SIP endpoint). (Default = the value of the REMOTE_SIP_PORT Lua global).
|
.local_rtp_ip
|
IPv4 Address |
Override the local RTP IP address (the address of the local RTP endpoint). (Default = the value of the LOCAL_RTP_IP Lua global).
|
.local_rtp_port
|
Integer |
Specify the local RTP UDP port (the UDP port of the local RTP stream endpoint). (Default = no RTP port is assigned, and we cannot construct an SDP Offer or SDP Answer). |
The method returns an endpoints object.
Argument | Type | Description |
---|---|---|
endpoints
|
Object | The local SIP IP address (the address of our near SIP endpoint) from default or custom. |
.local_sip_ip
|
Object | The local SIP IP address (the address of our near SIP endpoint) from default or custom. |
.local_sip_port
|
Object | The local SIP UDP port (the port of our near SIP endpoint) from default or custom. |
.remote_sip_ip
|
Object | The remote SIP IP address (the address of the far SIP endpoint) from default or custom. |
.remote_sip_ip
|
Object | The remote SIP UDP port (the port of the far SIP endpoint) from default or custom. |
.local_rtp_port
|
Object | The local RTP IP address (the address of the local RTP endpoint) from default or custom. |
.local_rtp_ip
|
Object | The local RTP UDP port (the port of the local RTP endpoint) as specified (no default value applies). |
This table will subsequently become part of the overall “context” of the test call, and will be passed through as part of that table, the script will no longer need to refer to it explicitly.
Example getting endpoints with override:
-- Ask the TestRtpApp to assign us an RTP port.
local result = truo.register ()
local rtp_listener_port = result.local_port
...
-- Initialise endpoints from global variables, but with our private RTP port.
local endpoints = tsuo.default_endpoints ({ local_rtp_port = rtp_listener_port })
...
-- Create a new outcall SIP INVITE Context for our endpoints and calling/called parties.
local context = tsuo.invite_context (endpoints, "7000", "048989777")
...
.non_invite_context [Synchronous]
The “context” object for a non-INVITE transaction is a simple container of a Call-ID plus associated To/From/Contact URI values, counters, and other state variables.
The non_invite_context
method on the TestSipAgent API is the method used to construct a
context which is ready to send out a non-INVITE SIP Request. The test script will act as
a User Agent Client.
The non_invite_context
method takes the following arguments:
Argument | Type | Description |
---|---|---|
endpoints
|
Object |
[Required] The endpoints object defining the IP address and ports which will be used for
sending and receiving messages for this UAC transaction. This object is typically constructed using the default_endpoints method.
|
calling_party
|
Hex Digits |
[Required] The user part of the local URI which will be placed in the From header for the initial SIP Request.
|
called_party
|
Hex Digits |
[Required] The user part of the remote URI which will be placed in the To header for the initial SIP Request.
|
options
|
Object |
Additional override/customisation behavior for this test transaction. (Default = see defaults for individual options). |
.compact_headers
|
Boolean |
Should we use the "Compact" header names for messages we send within this non-INVITE transaction. (Default = use full-length header names). |
.from_domain
|
String |
Override the default domain for the local URI in the "From" header local URI sent by us. (Default = the from domain is the local SIP address from the endpoints). |
.contact_sip_instance
|
String |
Add this value as a ;+sip_instance= parameter on the "Contact" header for the SIP Request.(Default = do not include a " ;+sip_instance= parameter on our "Contact" header).
|
.contact_expires
|
Integer |
Add this value as a ;expires= parameter on the "Contact" header for the SIP Request.(Default = do not include a ;expires= parameter on our "Contact" header).
|
The method returns a single argument which is the “context” object. This object should be passed in to subsequent SIP Test API methods related to this non-INVITE transaction.
The “context” object is nominally opaque, but it is documented here for completeness.
Argument | Type | Description |
---|---|---|
context
|
Object | Container for the context which aggregates the information for this non-INVITE transaction. |
.compact_headers
|
Boolean |
Should we use the "Compact" header names for messages we send within this transaction. (Default = use full-length header names). |
.call_id
|
String |
The allocated Call-ID we will use for this transaction.
|
.local_tag
|
String |
The local ;tag= value which will be added to our local URI in the "From" header.
|
.request_uri
|
String | The URI which will be placed into all SIP Requests sent by us for this transaction. |
.local_uri
|
String | The local URI used as the "From" header, complete including the local "tag" parameter. |
.local_uri_notag
|
String |
The local URI but without the ;tag= parameter.
|
.remote_uri
|
String |
The remote URI used as the "To" header. There is no ;tag= parameter, and will not be one for a non-INVITE context.
|
.contact
|
String |
The "Contact" header URI which we will send for the non-INVITE SIP Request. This is relevant for the REGISTER request, but is not sent for OPTIONS or other methods.
|
.local_seq
|
Integer |
The CSeq value which will be used for the first (and only) SIP Request in this non-INVITE transaction.
|
.endpoints
|
Object |
A stored reference to the endpoints object supplied in the method.
|
The standard sequence for testing a non-INVITE outbound request is:
- Create the endpoints object with
default_endpoints
. - Create the non-INVITE context with
non_invite_context
. - Send the outbound request, e.g. with
register_send_request
. - Wait for responses.
Example of constructing and using a context for an outbound non-INVITE SIP Request test sequence:
-- Get a SIP outbound non-INVITE request context from our helper library.
local context = tsuo.non_invite_context (endpoints, calling_party, called_party, { contact_expires = '3600' })
-- Switch the authentication mode to DIGEST.
n2svcd.management_configuration_scalar ('LHO', 'sip_auth_schema', 'digest')
-- Attempt to register again this time expecting an unauthorized response.
tsuo.register_send_request (context)
-- Expect REGISTER response (401 Unauthorized).
local response = tsuo.register_expect_response (context, 401, "Unauthorized")
-- Generate the authorization header for our request.
local www_auth_header = tsuo.header_fetch (response.headers, "WWW-Authenticate")
local authorization_header = tsuo.auth_header_value (context, 'REGISTER', www_auth_header, username, password)
-- Attempt to register again this time expecting a successful auth response.
tsuo.register_send_request (context, { { name = "Authorization", value = authorization_header } })
-- Expect REGISTER response 200 OK.
tsuo.register_expect_response (context, 200, "OK")
-- Switch the authentication mode back to OPEN.
n2svcd.management_configuration_scalar ('LHO', 'sip_auth_schema', 'open')
.invite_context [Synchronous]
The “context” object for an INVITE transaction/dialog is very similar to the non-INVITE context, but contains some additional fields related to the ongoing dialog and the secondary transactions.
The invite_context
method on the TestSipAgent API is the method used to construct a
context which is ready to send out a non-INVITE SIP Request. The test script will act as
a User Agent Client.
Note: For inbound calls, the INVITE context object is returned from the invite_expect_request
method
as documented for the Inbound INVITE methods.
The invite_context
method takes the following arguments:
Argument | Type | Description |
---|---|---|
endpoints
|
Object |
[Required] The endpoints object defining the IP address and ports which will be used for
sending and receiving messages for this UAC transaction. This object is typically constructed using the default_endpoints method.
|
calling_party
|
Hex Digits |
[Required] The user part of the local URI which will be placed in the From header for the initial SIP Request.
|
called_party
|
Hex Digits |
[Required] The user part of the remote URI which will be placed in the To header for the initial SIP Request.
|
options
|
Object |
Additional override/customisation behavior for this test transaction. Note the difference in supported options from the non-INVITE case. (Default = see defaults for individual options). |
.prack_supported
|
Boolean |
Do we include 100rel in a Supported header for INVITE Requests we send within this dialog.(Default = do not advertise support for 100rel ).
|
.compact_headers
|
Boolean |
Should we use the "Compact" header names for messages we send within this transaction. (Default = use full-length header names). |
.from_otg
|
String |
Value to include as the ;otg= parameter in the "From" header local URI value.(Default = do not include ;otg= parameter in the "From" header local URI value).
|
.from_isup_oli
|
String |
Value to include as the ;isup-oli= parameter in the "From" header local URI value.(Default = do not include ;isup-oli= parameter in the "From" header local URI value).
|
.from_domain
|
String |
Override the default domain for the local URI in the "From" header sent by us. (Default = the from domain is the local SIP address from the endpoints). |
.from_display_name
|
String |
Include the indicated display name when constructing the "From" header local URI value. (Default = do not include any display name part in the "From" header local URI value). |
.contact_sip_instance
|
String |
Add this value as a ;+sip_instance= parameter on the "Contact" header for the SIP Request.(Default = do not include a " ;+sip_instance= parameter on our "Contact" header).
|
.contact_expires
|
Integer |
Add this value as a ;expires= parameter on the "Contact" header for the SIP Request.(Default = do not include a ;expires= parameter on our "Contact" header).
|
The method returns a single argument which is the “context” object. This object should be passed in to subsequent SIP Test API methods related to this INVITE transaction/dialog.
The “context” object is nominally opaque, but it is documented here for completeness. Note the additional attributes related to the ongoing dialog which are not present for the non-INVITE context equivalent.
Argument | Type | Description |
---|---|---|
context
|
Object | Container for the context which aggregates the information for this INVITE transaction. |
.prack_supported
|
Boolean |
Do we include 100rel in a Supported header for INVITE Requests we send within this dialog.(Default = do not advertise support for 100rel ).
|
.compact_headers
|
Boolean |
Should we use the "Compact" header names for messages we send within this INVITE transaction. (Default = use full-length header names). |
.call_id
|
String |
The allocated Call-ID we will use for this transaction/dialog.
|
.local_tag
|
String |
The local ;tag= value which will be added to our local URI in the "From" header.
|
.request_uri
|
String | The URI which will be placed into all SIP Requests sent by us for this transaction. |
.local_uri
|
String |
The local URI used as the "From" header (or "To" header for incall scenarios). This is complete including the local "tag" parameter. |
.local_uri_notag
|
String |
The local URI used as the "From" header (or "To" header for incall scenarios). This version does not have the ;tag= parameter.
|
.remote_uri
|
String |
The remote URI used as the "To" header in the initial INVITE (or "From" header for incall scenarios). At the time of construction this will not have the ;tag= as it is not yet known.However, the ;tag= will be added to this attribute as soon as the tag is received from the far end.
|
.remote_uri_notag
|
String |
The remote URI used as the "To" header (or "From" header for incall scenarios). This version will never have the ;tag= parameter.
|
.contact
|
String | The "Contact" header URI which we will send for any outbound SIP INVITE or re-INVITE Request within this dialog. |
.local_seq
|
Integer |
The CSeq value which will be used for the first SIP Request transaction in this INVITE dialog.Any subsequent outbound transactions within the dialog will increment this value by one. |
.invite_pcv
|
String |
This value is not initialized when the context is created. It will subsequently be given the value of the P-Charging-Vector (if present) from the sent or received SIP INVITE Request.
|
.endpoints
|
Object |
A stored reference to the endpoints object supplied in the method.
|
The standard sequence for testing an INVITE outbound request is:
- Create the endpoints object with
default_endpoints
. - Create the INVITE context with
invite_context
. - Create the SDP Offer with
sdp_offer
- Send the outbound request with
invite_send_request
. - Wait for responses.
Example fragment showing creating a new INVITE context from existing endpoints object:
-- Get a SIP outcall context from our helper library.
local context = tsuo.invite_context (endpoints, calling_party, called_party, {
contact_sip_instance = '"<urn:uuid:27b843f9-d300-49fb-b108-fff03a6369e3>"',
contact_expires = '3600'
})
-- Construct the SDP
local sdp_offer = tsuo.sdp_offer (context, tsuo.SDP_LINPHONE)
-- Construct and Send INVITE Request.
tsuo.invite_send_request (context, sdp_offer, { { name = 'Prefer-EM', value = '1' }, { name = 'Scenario', value = '533' } })
-- Expect Trying (no Ringing) from the IVR.
tsuo.invite_expect_response (context, 100, "Trying")
.register_incall [Asynchronous]
The register_incall
method informs the TestSipApp
that we are expecting to receive an new SIP Dialog
from an uncorrelated inbound SIP INVITE Request on one of the ports/connections on which it is listening.
We do not know what the Call-ID
will be, so we instead specify another match attribute which can be used
to identify that this test is indeed the owner of that call when it arrives.
Argument | Type | Description |
---|---|---|
match
|
Object | Container for the possible match fields used to claim ownership of the new Call/Dialog. |
.calling_party
|
Hex&String |
Calling Party address digits to match. If present, this address must be a full-length, case-insensitive match on the "user" part of the From
header URI of the new-dialog SIP INVITE Request.
|
.called_party
|
Hex&String |
Called Party address digits to match. If present, this address must be a full-length, case-insensitive match on the "user" part of the To
header URI of the new-dialog SIP INVITE Request.
|
The register_incall
is asynchronous, it waits until the TestSipApp
confirms the registration.
The registration lifetime is determined by the TestSipApp
, currently an inbound registration is valid
for 5 seconds, and this value is not configurable or controllable.
The register_incall
method returns nil
.
The standard sequence for testing an INVITE incall is:
- Create the endpoints object with
default_endpoints
. - Register for an incall with
register_incall
. - Perform an action that initiates the inbound call (e.g. REST request).
- Wait for the incall with
invite_expect_request
(which returns the context).
Example incall registration and REST request:
-- Register to claim the next call for this called party.
tsuo.register_incall ({ called_party = called_party })
-- Start timer for elapsed checking.
local tv = match.elapsed ()
-- Open a rest client request to start the call.
local result = rest_agent.send_request (nil, {
path = '/outcall_pa_internal',
query = 'calling_party=' .. calling_party ..
'&called_party=' .. called_party ..
'&scenario=' .. scenario
})
local rest_response = rest_agent.expect_response ()
tv = match.elapsed ("Received REST Response (immediate)", tv, 0.0)
local context = tsuo.invite_expect_request (endpoints, { ['User-Agent'] = "N-Squared LHO", Scenario = scenario })
local call_pcv = context.invite_pcv
tv = match.elapsed ("Received SIP INVITE (immediate)", tv, 0)