CallXML documentation
Logic of processing SIP calls in StarTrinity VoIP software is defined by scripts written in high-level scripting programming language "CallXML".
Incoming and outgoing SIP calls are processed by an engine which reads and executes CallXML elements in sequence.
The CallXML elements define basic operations with the SIP call.
accept
Sends "200 OK" or "1xx" provisional response to incoming SIP call. Is not applicable for outgoing calls.
Sends a "488 Not Acceptable Here" response if codec negotiation failed.
May contain inner "additionalMultipartContent" XML element and attribute "multipartBoundary" to send "multipart/mixed" content body (see example for "call"). The "additionalMultipartContent" element may contain XML attribute "lineBreak": "\r\n" or "\n".
Attributes:
value (optional, default = "200") -
SIP status code for the response. Note: "100 Trying" response is always sent, regardless of CallXML script
headers (optional) - list of custom SIP headers to be included into the response. The separator "|" is escaped by "\0x7C".
Example1: Header1Name=Header1Value|Header2Name=Header2Value|Header3Name=Header3Value
Example2: Header1Name=Header1\0x7CValue|Header2Name=Header2\0x7CValue
sdpAttributes (optional) - list of custom SDP attributes to be included into the response.
Example: Attr1Name:Attr1Value|Attr2Name:Attr2Value|Attr3Name:Attr3Value
localRtpPort (optional) - explicitly set local RTP UDP port number. If empty or zero, a socket from RTP transport pool is used (see settings "MediaTransportPoolMinPort", "MediaTransportPoolMaxSocketsCountPerInterface")
localRtpAddress (optional) - explicitly set local RTP IP address, is used to select network interface. If empty, the network interface is selected by remote IP address using system routing table (WinAPI function GetBestInterface())
fakeSdp (optional, "true" or "false", default is "false") - if set to "true", the software does not create RTP stream (does not take system resurces for media), and creates fake SDP instead, with optional parameters "localRtpAddress" and "localRtpPort". Is used when you need to run a high-CPS test via a SIP proxy (e.g. kamailio)
noRtpIfNoOffer (optional, "true" or "false", default is "false") - if set to "true", the software does not create RTP stream and does not send SDP in "200 OK", if initial INVITE did not contain SDP offer
codec (optional) - when sending 200 OK, selects audio codec
disableRtp (optional, "true" or "false", default is "false") - disables RTP stream for the SIP call. Is used to save CPU resources by enabling RTP only for some part of generated SIP calls
rtpDscp (optional, default is "0") - sets IP ToS (DSCP) field for transmitted RTP packets. Note: this parameter turns on "WinPCAP RTP sender" operation mode for the SIP call, in this mode you can only play one WAV audio file in loop. Example: "46"
debugMediaRx (optional, "true" or "false", default is "system settings") - enables recording of received (RX) RTP audio stream to WAV file, directory path is configured by system settings "DebugMediaPath", "DebugMediaFileNamePattern"
debugMediaTx (optional, "true" or "false", default is "system settings") - enables recording of transmitted (TX) RTP audio stream to WAV file, directory path is configured by system settings "DebugMediaPath", "DebugMediaFileNamePattern"
debugMediaMixed (optional, "true" or "false", default is "system settings") - enables recording of mixed (received+transmitted, RX+TX) RTP audio stream to WAV file, directory path is configured by system settings "DebugMediaPath", "DebugMediaFileNamePattern"
videoPcapFileName (optional) - specifies pcap file to be played in loop mode for audio+video SIP calls. Any video codec is supported
videoRtpmapEncodingName (optional) - specifies video encoding name in SDP for audio+video SIP calls. Example: "H263-1998", "H264", "VP8"
videoSdpLines (optional) - additional SDP lines for video stream in SDP. Example: "b=TIAS:1920000|a=fmtp:99 profile-level-id=64001F; sar=13; packetization-mode=1"
testId (optional) - Test ID to be passed into "Test ID" CDR column
<accept value="200" />
<accept value="183" />
<accept headers="WG67-Version=radio.01" sdpAttributes="R2S-KeepAlivePeriod:200|R2S-KeepAliveMultiplier:10|sigtime:1" />
<accept value="200" headers="History-Info: <SIP URL>;index=1|History-Info: <SIP URL>; index=1.1|Diversion=<sip:1111@1.1.1.1>;abc|Diversion=<sip:2222@2.2.2.2>;def" />
addsipmalformer
Adds SIP malformer (SIP fuzzer) into current CallXML session, before "call" and "accept" elements. Both fixed and random fuzzers are available
assign
Sets new value to a variable. Variables are used to store intermediate data and to build complex logic in CallXML scripts.
Variables can be accessed later in script using
substitutions.
Valiables in CallXML are not typed, more specifically all have type "string" and are parsed dynamically if needed
Attributes:
var (optional) - name of the variable. Variables are separated for different SIP calls
globalvar (optional) - name of the global variable. Global variables are shared between different SIP calls
value (optional) - new value for the variable. If it equals to "$rand_from_options;", the value is randomly selected from one of child XML elements (see example)
pattern (optional) - one or multiple patterns for the variable. Character "?" means a random digit. Examples: "18???????", "18??????? 19???????", "20:18??????? 80:19???????"
values (optional) - list of sequential values, separated by ";" (see example)
mathvalue (optional) - mathematical expression (see example). Supported operators are: ( ) * + - / ^ %. Functions: sin(x), cos(x), tg(x), ctg(x), sh(x), ch(x), th(x), sqrt(x), exp(x), (a)log(b), ln(x), abs(x), floor(x), ceil(x), round(x)
<assign var="fileName" value="$rand_from_options;">
<option value="wav\01.wav" />
<option value="wav\02.wav" />
<option value="wav\03.wav" />
</assign>
<playaudio value="$fileName;"/>
<assign var="phone" values="101;102;103" />
<call value="sip:$phone;@server.com" />
<assign var="y" value="4" />
<assign var="x" mathvalue="-(5+5*5)/$y;+sqrt(4000000)" />
<log value="x=$x;" />
block
Groups CallXML elements into single block. Is used for many purposes: "if" statements, matching strings with regular expressions, loops, simulation of random behaviour.
Attributes:
test (optional) -
boolean expression, specifies condition of executing internal CallXML elements
repeat (optional, default is "1") - number of times to execute nested CallXML elements. If equals to "infinite", it will run until SIP call is destroyed.
The "repeat" and "minInterval" parameters can not be set at the same time.
var (optional) - name of variable to receive iteration counter value
probability (optional, default is "1") - propability of executing nested CallXML elements
minInterval (optional) - minimal interval between executions of the block. If time since last execution of the block is smaller than the "minInterval", the block is not executed.
The "minInterval" is useful when you want to do something not for every call, but for single call every minute.
The "repeat" and "minInterval" parameters can not be set at the same time
<block test="$callerId;=100">
<reject value="486">
</block>
<block probability="0.5">
<log value="this is executed with probability 0.5" />
</block>
<log value="this is executed with probability 1" />
<block test="abc = abc">
<log value="abc = abc - it is true" />
</block>
<block test="abc = def">
<log value="abc = def - it is not true" />
</block>
<log value="making call to the server. it should be configured to answer to 'test' number with no delay" />
<call value="sip:test@localhost:5060" maxtime="5s" />
<on event="answer">
<log value="call answered. aborting call" />
<exit />
</on>
<on event="maxringtime;callfailure">
<log value="call failed (5-sec timeout or error response). restarting server if did not restart already 3 minutes ago" />
<block minInterval="3m">
<sendemail value="mailto:email@gmail.com?subject=call to server failed. restarting the server" />
<log value="restarting SIP server" />
<!-- here you should set path to your SIP server -->
<restartprocess value="C:\Users\User\AppData\Roaming\StarTrinity SipTester\StarTrinity.SIPTester.exe" />
</block>
<exit />
</on>
<log value="reporting global variables: total: $global.totalcounter;, block1 (probability 0.5): $global.block1counter;, block2 (probability 0.5*(1-0.5) = 0.25): $global.block2counter;" />
<assign globalvar="totalcounter" mathvalue="$global.totalcounter;+1" />
<block probability="0.5">
<assign globalvar="block1counter" mathvalue="$global.block1counter;+1" />
<exit />
</block>
<block probability="0.5">
<assign globalvar="block2counter" mathvalue="$global.block2counter;+1" />
<exit/>
</block>
<getstringlength var="calledIdLength" value="$calledId;" />
<block repeat="$calledIdLength;" var="i">
<substring value="$calledId;" startIndex="$i;" length="1" var="digit" />
<log value="extracted called ID digit #$i;: $digit;" />
<playaudio value="C:\startrinity_siptester_latest\Wav\digit;.wav"/>
</block>
call
Initiates new outgoing call (SIP UAC session) to specified destination; optionally aborts call on time out
Raises "answer", "maxringtime", "hangup", "localHangup", "pr", "audioSignal", "reinvite", "transferred", "idleMedia" and "callfailure" events.
On "callfailure" sets variable "lastError" to SIP status code. On "transferred" event you should use "playaudio" element to send RTP to new call leg B.
Executes next CallXML element if call was aborted.
Handles "3xx (Moved Temporarily)" responses and makes another call to new destination.
Saves remote SIP headers into CallXML variables with prefix "sipHeader", when received provisional response on answer from destination; saves remote SDP attributes into CallXML variables with prefix "sdpAttribute".
May contain inner "additionalMultipartContent" XML element and attribute "multipartBoundary" to send "multipart/mixed" content body (see example). The "additionalMultipartContent" element may contain XML attribute "lineBreak": "\r\n" or "\n".
Note: one CallXML session should execute only one "call" element. If you want to make multiple calls with different parameters, you can use element "switch", or read the parameters from a CSV file, or you can put multiple "run" elements with 1 "call" element inside every "run" element.
Attributes:
value (required) - specifies
SIP URI of destination.
Destination host can be specified as IP address (e.g. 192.168.10.1), DNS A-record name (e.g. sip-anycast-1.voice.google.com), DNS SRV-record name (e.g. _sip._udp.sip.voice.google.com).
The SIP URI may contain following query parameters:
- "transport" - "udp"/"tcp"/"tls", "udp" is default
- "user", "password" - credentials for authentication
- "proxyAddress", "proxyPort" - address of proxy server
- "localSipPort" - local SIP UDP port to use for the call
- "callerId" - user ID in 'From' header
Example values:
- sip:12345@server.com
- sip:12345@server.com:5060
- sip:12345@1.2.3.4:5060
- sip:12345@1.2.3.4:5060?user=AuthUser&password=AuthPassword (here & is XML escaping syntax)
- sip:111111111;rn=D1234;npdi@1.2.3.4:5060?user=AuthUser&password=AuthPassword
If value equals to "$rand_from_options;" - call is made to one of randomly selected destinations in "option" children XML elements (see example), and it sets CallXML variable "destinationResourceId".
It is possible to limit number of concurrent calls per each "option" in list ("destination resource") and to build different call scenarios for different "destination resource".
If value equals to "$seq_sip_uri_from_csv(CSV_file_name[, optional csvLineStartIndex]);" - destination is read from CSV file, starting from specified zero-based line index (zero line index by default).
If value equals to "$random_least_busy_uac_registration();" - call is made using
UAC registrations (used when simulating calls via extensions of tested IP PBX).
If value equals to "$ext(100);" - call is made to a registered extension (UAS registration) with SIP ID = "100".
to (optional) - "To" header for SIP INVITE message. If "to" is not set, it is taken from "value" SIP URI
callerId (optional, default is "unknown") -"From" header or "SIP ID" for "From" header in INVITE message. Example: "123456", "sip:123456@domain.com"
sipCallId (optional) - SIP "Call-ID" header in INVITE message. Example: "StarTrinity$id;@yourdomain.com"
fromTag (optional) - unique "tag" parameter for "From" header in INVITE message
sendSdpInInitialInvite (optional, "true" or "false", default is "true") - specifies whether to send SDP in SIP INVITE message.
If no SDP is sent in request, and if destination also does not send SDP in response, the SIP call will be established without RTP media.
If the destination sends late SDP offer in 200 OK, the caller will respond with SDP answer in ACK.
disableRtp (optional, "true" or "false", default is "false") - disables RTP stream for the SIP call. Is used to save CPU resources by enabling RTP only for some part of generated SIP calls
rtpDscp (optional, default is "0") - sets IP ToS (DSCP) field for transmitted RTP packets. Note: this parameter turns on "WinPCAP RTP sender" operation mode for the SIP call, in this mode you can only play one WAV audio file in loop. Example: "46"
debugMediaRx (optional, "true" or "false", default is "system settings") - enables recording of received (RX) RTP audio stream to WAV file, directory path is configured by system settings "DebugMediaPath", "DebugMediaFileNamePattern"
debugMediaTx (optional, "true" or "false", default is "system settings") - enables recording of transmitted (TX) RTP audio stream to WAV file, directory path is configured by system settings "DebugMediaPath", "DebugMediaFileNamePattern"
debugMediaMixed (optional, "true" or "false", default is "system settings") - enables recording of mixed (received+transmitted, RX+TX) RTP audio stream to WAV file, directory path is configured by system settings "DebugMediaPath", "DebugMediaFileNamePattern"
direction (optional, "SendOnly"/"ReceiveOnly"/"None"/"Both", default is "Both") - RTP media direction to be declared in SDP
maxringtime (optional, default is "no timeout") - timeout of waiting for call answer in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix).
If "maxringtime" expires, call is aborted with CANCEL SIP message.
It is max time to wait for answer, not max call duration
maxansweredtime (optional, default is "no timeout") - max call duration after answering in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix).
If "maxansweredtime" expires, "maxansweredtime" event is raised. If no event handler for "maxansweredtime" exists, the call is aborted with BYE SIP message
headers (optional) - list of custom SIP headers to be included into the INVITE message.
The separator "|" is escaped by "\0x7C".
Example1: Header1Name=Header1Value|Header2Name=Header2Value|Header3Name=Header3Value
Example2: Header1Name=Header1\0x7CValue|Header2Name=Header2\0x7CValue
sdpAttributes (optional) - list of custom SDP attributes to be included into the INVITE message.
Example: Attr1Name:Attr1Value|Attr2Name:Attr2Value|Attr3Name:Attr3Value
sdpAttributes2 (optional) - custom SDP attributes for 2nd RTP stream for SIPREC testing.
see sample CallXML script
codec (optional, "G711A"/"G711U"/"G723"/"G729", default is "any of supported") - RTP media codec (SDP media stream payload type) to be used for the SIP call
localRtpPort (optional) - explicitly set local RTP UDP port number. If empty or zero, a socket from RTP transport pool is used (see settings "MediaTransportPoolMinPort", "MediaTransportPoolMaxSocketsCountPerInterface")
localRtpAddress (optional) - explicitly set local RTP IP address, is used to select network interface. If empty, the network interface is selected by remote IP address using system routing table (WinAPI function GetBestInterface())
fakeSdp (optional, "true" or "false", default is "false") - if set to "true", the software does not create RTP stream (does not take system resurces for media), and creates fake SDP instead, with optional parameters "localRtpAddress" and "localRtpPort". Is used when you need to run a high-CPS test via a SIP proxy (e.g. kamailio)
localSipPort (optional) - explicitly set local SIP/UDP transport port. Is used with global settings "LocalSipPort", "LocalSipPortRange"
localSipAddress (optional) - explicitly set local SIP IP address, is used to select network interface. Is used with global setting "LocalSipAddresses"
var (optional) - name of variable where to save SIP status code of the call
testId (optional) - Test ID to be passed into "Test ID" CDR column
terminatorId (optional) - ID of terminator to associate with the new call. Is used for complex scripts in the softswitch to manipulate A and B call legs. If "terminatorId" is set, attribute "value" means called number (CLD)
videoPcapFileName (optional) - specifies pcap file to be played in loop mode for audio+video SIP calls. Any video codec is supported
videoRtpmapEncodingName (optional) - specifies video encoding name in SDP for audio+video SIP calls. Example: "H263-1998", "H264", "VP8"
videoSdpLines (optional) - additional SDP lines for video stream in SDP. Example: "b=TIAS:1920000|a=fmtp:99 profile-level-id=64001F; sar=13; packetization-mode=1". Node: video RTP stream payload type is configured by setting "VideoSdpPayloadType"
sentContactHeaderVar (optional) - name of CallXML variable to save value of sent Contact header (from the sent SIP INVITE packet)
cseq (optional) - initial sequence number for CSeq SIP header, non-zero value
mode (optional) - if set to "siprec", the SIP call will create 2 RTP streams for SIPREC testing.
see sample CallXML script
<call maxringtime="10s" callerId="101" value="sip:100@localhost:5070" headers="Diversion=TestD|Header2=HeaderValue2" />
<call maxringtime="10000ms" callerId="$Id;" value="sip:100@localhost:5070"
headers="Diversion=<sip:+1234567890@BC05.MSCTG01;user=phone>;reason=unknown" />
<call value="sip:111@192.168.1.1" callerId="222"
headers="Subject=radio|Priority=normal|WG67-Version=radio.01"
sdpAttributes="R2S-KeepAlivePeriod:200|R2S-KeepAliveMultiplier:10|sigtime:1"
/>
<call value="sip:test@localhost" multipartBoundary="-----border----">
<additionalMultipartContent lineBreak="\r\n">
<![CDATA[
Content-ID: $id;@ng123.com
Content-Type: application/pidf+xml
Content-Transfer-Encoding: 8bit
<?xml version="1.0" encoding="ISO-8859-1"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
xmlns:gp="urn:ietf:params:xml:ns:pidf:geopriv10"
xmlns:cl=" urn:ietf:params:xml:ns:pidf:geopriv10:civicLoc"
xmlns:gml="urn:opengis:specification:gml:schema-xsd:feature:v3.0"
entity="sip:caller1@ngsos.com">
<tuple id="id56345">
<status>
<gp:geopriv>
<gp:location-info>
<gml:location>
<gml:Point>
<gml:pos>$rand(30,40);.$rand(1,99999); -$rand(67,78);.$rand(1,99999);</gml:pos>
</gml:Point>
</gml:location>
</gp:location-info>
<gp:method>Manual</gp:method>
</gp:geopriv>
</status>
<contact priority="0.8">sip:abcd@4.5.6.7:5060</contact>
<timestamp>$time();</timestamp>
</tuple>
</presence>
]]>
</additionalMultipartContent>
</call>
<on event="answer">
<playaudio value="music.wav" maxtime="10s" />
<exit />
</on>
<call value="$rand_from_options;" callerId="sipTester" maxringtime="$rand(5000);ms" sendSdpInInitialInvite="true">
<option value="sip:test@10.10.10.1:5060?transport=tcp" maxCallsPerDestinationResource="100"
destinationResourceId="server1" />
<option value="sip:test@10.10.10.2:5060?transport=tcp" maxCallsPerDestinationResource="200"
destinationResourceId="server2" />
</call>
<on event="answer">
<log value="call answered. resource ID = $destinationResourceId;" />
<wait value="5s" />
<exit />
</on>
<call maxringtime="30s" callerId="sip:test@192.168.1.10" value="sip:100@192.168.1.9:5060" />
<call callerId=""AAA" <sip:TEST@192.168.1.10>" value="sip:444@192.168.1.10:5060" />
<call maxringtime="10000ms" callerId="" value="sip:100@localhost:5070" sendSdpInInitialInvite="true"
headers="History-Info: <SIP URL>;index=1|History-Info: <SIP URL>; index=1.1|H1=<sip:1111@1.1.1.1>;abc|H1=<sip:2222@2.2.2.2>;def" />
<call value="sip:test@ims.mnc222.mcc302.abc.org" headers="Contact=sip:4087890001@ims.mnc222.mcc302.abc.org;q=0.5;+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.largemsg"|P-Asserted-Service=urn:urn-7:3gpp-service.ims.icsi.abc.cpm.largemsg|Accept-Contact=+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.abc.cpm.largemsg"" />
<call value="sip:11111@23.34.45.56" callerId=""from display name" <sip:2222@23.34.45.56>" to=""to display name" <sip:11111@23.34.45.56>" maxringtime="30s" />
<call value="sip:11111@23.34.45.56" callerId="55555" maxringtime="30s" headers="P-Charging-Vector=icid-value=1234bc9876e;icid-generated-at=192.0.6.8;orig-ioi=home1.net" />
<call value="sip:592111@startrinity.com:6060" callerId="19056089570" maxringtime="3s" var="r" codec="G711A">
<on event="callfailure">
<log value="call failed with status $eventSubType;. header WWW-Authenticate is: $sipHeaderWWW-Authenticate;"/>
</on>
</call>
callgroup
Initiates call to group of SIP phones. "parallel", "sequential", "queue" modes of calling phones are available.
Attributes:
value (required) - name of call group
ringbacktone (optional) - audio file name which is played to caller until call is answered
<callgroup value="worktime" ringbacktone="C:\wav\please_wait_for_answer.wav" />
<exit/>
<callgroups>
<callgroup name="worktime" userName="" mode="parallel" >
<callgroupitem value="sip:100@10.10.10.1" maxringtime="30s" />
<callgroupitem value="sip:101@10.10.10.1" maxringtime="30s" />
<callgroupitem value="sip:102@10.10.10.1" maxringtime="30s" />
</callgroup>
</callgroups>
case
Is used within "switch". Defines an option which can be executed
See also: "switch", "default"
Attributes:
equals (optional) - specifies a value to check equality
startswith (optional) - specifies prefix
from (optional) - specifies lower inclusive bound for the value
to (optional) - specifies upper inclusive bound for the value
probability (optional) - specifies probability for the case. Sum of "probabily" values for all "case" elements in "switch" is normalized
checktime
Checks current time, raises event if it matches to some schedule, or puts a value to a variable
Parameters of schedule are set by "span" XML elements (see example). "daystart" and "daystop" of the spans can be within same day or over midnight.
Attributes:
var (optional) - name of variable where to save "value" attribute of selected time span (see example). if not set, the "checktime" raises "time_matches" event
<checktime>
<span weekdays="mon,tue,wed,thu,fri" daystart="09:00" daystop="13:00" />
<span weekdays="mon,tue,wed,thu,fri" daystart="14:00" daystop="18:00" >
<span daystart="15:10" daystop="15:20" value="false" />
</span>
<span date="2015.01.01" value="false" priority="1" />
</checktime>
<on event="time_matches" >
<playaudio value="wav\welcome.wav" />
<transfer value="techSupport" />
<exit />
</on>
<playaudio value="wav\out_of_schedule.wav" />
<exit />
<assign var="ncalls" value="100" />
<checktime var="ncalls">
<span weekdays="mon,tue,wed,thu,fri" daystart="09:00" daystop="13:00" value="150" />
<span weekdays="mon,tue,wed,thu,fri" daystart="14:00" daystop="18:00" value="200" />
<span date="2015.11.01" value="300" />
<span date="2015.11.07" value="355" />
</checktime>
<log value="setting max concurrent calls = $ncalls;" />
<setcallgeneratorparams maxconcurrentcalls="$ncalls;" />
conference
Connects a call with other calls in conference room
Raises "callsJoinedInConference", "maxTimeToWaitForOtherCallsInConference", "callsLeftConference" events. See also "ifconferenceexists"
Attributes:
value (required) - ID of conference
direction (optional, "SendOnly"/"ReceiveOnly"/"None"/"Both", default is "Both") - audio direction between SIP call and conference room.
syncDestroy (optional, "true"/"false", default is "false") - specifies whether to destroy all other calls in conference when current call is destroyed
syncDestroyDelay (optional, default is "0ms") - specifies delay before destroying other calls in conference if "syncDestroy" is "true"
maxTimeToWaitForOtherCalls (optional, default is "infinite") - specifies a timeout of waiting for other calls to join the conference.
If calls are joined, a "callsJoinedInConference" event is raised. If the timeout expires, "maxTimeToWaitForOtherCallsInConference" event is raised.
The attribute and events are used to build a logic of billing calls only when there are 2 or more calls in conference (see example script).
<conference value="01" />
<assign var="ParentSessionID" value="$id;"/>
<assign var="NumToCall" value="sip:152@192.168.0.56" />
<run var="secondarySessionId" >
<call value="$NumToCall;" to="$NumToCall;" callerId="123" maxringtime="100s" />
<on event="answer" >
<sendevent value="answer" session="$parentSessionId;" />
<conference value="$Id;" />
</on>
<on event="callfailure">
<log value="call failed with status $lastError;" />
<sendevent value="callfailure" session="$parentSessionId;" />
</on>
</run>
<playaudio value="ringbacktone.wav" />
<on event="externalevent:answer" >
<accept />
<conference value="$eventsenderId;" />
</on>
<on event="externalevent:callfailure" >
<exit />
</on>
<accept value="183"/>
<log value="sent 183 session progress for incoming call. playing ringback tone" />
<playaudio value="music.wav" dontwait="true" />
<log value="adding to conference, setting a timer of 10 seconds to wait for other calls to join the conference" />
<conference value="conference01" maxTimeToWaitForOtherCalls="10s" />
<on event="maxTimeToWaitForOtherCallsInConference">
<log value="wait timer expired. rejecting with 503" />
<reject value="503" />
</on>
<on event="callsJoinedInConference">
<log value="2 or more calls joined in conference. sending 200 OK to start billing" />
<stopaudio />
<accept value="200" />
</on>
<conference value="01"/>
<on event="dtmf:1">
<playaudio value="you_pressed_1.wav" />
</on>
<on event="dtmf:2">
<disconnect /> <!-- this aborts the call -->
</on>
controlaudio
Controls currently played audio: moves position (forward/back), makes pause/resume
See also:
playaudio
Attributes:
action (required) - one of following:
- pauseResume - puts played audio on pause or continues playing if paused
- seekRelative - move (seek) forward or back to N milliseconds, where N is specified by "value" attribute. Negative "value" means going back (rewind), positive "value" means going fast forward
value (optional, default is "0") - depends on "action"
<playaudio value="music.wav">
<on event="dtmf:1">
<controlaudio action="pauseResume" />
</on>
<on event="dtmf:2">
<controlaudio action="seekRelative" value="30000" />
</on>
<on event="dtmf:3">
<controlaudio action="seekRelative" value="-40000" />
</on>
</playaudio>
default
Is used within "switch". Defines an option which is executed when no matching "case" element is found
See also: "switch", "case"
Attributes:
[None]
dequeue
Gets an element from a global queue and saves it to variables. If no element is found, empty values are saved
An "element" in the global queue is a raw array of values, 0..N.
Attributes:
queueId (optional) - idenfier of the global queue
var0, var1, ... (multiple) - variables where to save dequeued element's values
exceptValue0, exceptValue1, ... (multiple) - filter for dequeued element's values
onlyValue0, onlyValue1, ... (multiple) - filter for dequeued element's values
<accept value="200" />
<enqueue value0="$sipCallId;" value1="$id;" />
<dequeue label="dequeue" var0="peerCallId" var1="peerSessionId" exceptValue0="$sipCallId;" />
<if test="'$peerCallId;' = ''">
<wait value="3s" />
<if test="$movedConferenceByPeerCall; = 1"> <log value="don't dequeue: already moved to conference" /> <wait /> </if>
<goto value="dequeue" />
</if>
<dequeue onlyValue0="$sipCallId;" />
<assign var="conferenceId" value="$sipCallId;" />
<log value="connecting 2 calls: this call $sipCallId; peer call $peerCallId; session $peerSessionId;. conference ID = $conferenceId;" />
<sendevent session="$peerSessionId;" value="conference" />
<conference value="$sipCallId;" />
<on event="externalevent:conference">
<assign var="movedConferenceByPeerCall" value="1" />
<log value="joining to conference $conferenceId;" />
<conference value="$conferenceId;" />
</on>
disableuacregistration
Disables UAC registration for a specified period of time, so it will not be used for calls
Attributes:
value - SIP user ID of the UAC registration
maxtime - period to disable the item
<call value="$random_least_busy_uac_registration();" >
<on event="callfailure" >
<log value="call failed with status = $eventSubType;. temporarily disabling extension $callerId;" />
<disableuacregistration value="$callerId;" maxtime="30m" />
</on>
</call>
disconnect
Terminates SIP call if it is created and not terminated yet. Sends BYE or CANCEL SIP message.
Does not terminate execution of CallXML script.
Note: callxml element after the "disconnect" element MAY not be executed, when the SIP call is physically destroyed, so if you need additinonal processing, please do it in a new CallXML session with "run" element (see example)
Attributes:
headers (optional) - list of custom SIP headers to be included into BYE SIP message. The separator "|" is escaped by "\0x7C".
Example1: Header1Name=Header1Value|Header2Name=Header2Value|Header3Name=Header3Value
Example2: Reason=Q.850;cause=16;text="Normal call clearing"
leg (optional, "A"/"B"/"both", default is "both") - specifies call leg for disconnection: A=origination side or B=termination side
<disconnect />
<disconnect />
<run >
<wait value="5s" >
<log value="5 seconds after disconnection" >
</run >
disconnectcalls
Terminates all SIP calls, similar to "Abort all calls" button
Attributes:
<disconnectcalls />
dynamicblacklist
Adds the specified number/prefix into RAM-based blacklist, checks if number of attempts or connected minutes exceed some specified threshold.
Executes internal CallXML elements if the number gets blocked. Writes details into CallXML log, which is accessible in CDR.
Attributes:
id (required) - idenfier of the blacklist. The system may have multiple blacklists with different IDs
value (required) - the number (usually B number, called ID)
maxtime (required) - max time to store the numbers in the list. Example: 60s, 60m, 24h
maxcount (required) - max number of occurences per the specified number/prefix in the list to block the call
maxtotalminutes (required) - max number of connected minutes per the specified number/prefix in the list to block the call
removelastdigitscount (optional) - number of digits to remove at end of the number to turn it into prefix for the filtering
<dynamicblacklist id="limitCallsPerNumberRange" maxtime="24h" maxcount="2" value="$calledId;" removeLastDigitsCount="3" >
<reject value="503" />
</dynamicblacklist>
<log value="$calledId; passed the filter" />
<if test="$calledId; startswith 291">
<dynamicblacklist id="limitRanges291" value="$calledId;" maxtime="5m" maxcount="60" maxtotalminutes="5" removelastdigitscount="3">
<reject value="503" />
</dynamicblacklist>
</if>
<if test="$calledId; startswith 292">
<dynamicblacklist id="limitRanges292" value="$calledId;" maxtime="5m" maxcount="10" maxtotalminutes="10" removelastdigitscount="3">
<reject value="503" />
</dynamicblacklist>
</if>
else
Is used after "if"; is executed if the test condition is false
enablesipscanner
Enables and starts SIP scanner (for VoIP security tests)
The element allows VoIP hacking, it is a part of
SIP security testing suite.
Executes inner CallXML code within new CallXML session, passes variables "ipAddress", "port", "responsePacketData", "method", "responseFirstLine", "softwareHeader" into the new session for further processing
Attributes:
maxRPS (optional, default is 10000) - target number of SIP scan requests per second
numberOfThreads (optional, default is 4) - number of concurrent threads
enable (optional, "true"/"false", default is "true") - turns on/off the SIP scanner threads
method (optional, "OPTIONS"/"INVITE"/"REGISTER"/"RANDOM" default is "OPTIONS") - method of SIP scanning
ipSequence (optional, "random"/"linear" default is "random") - IP addresses range enumeration sequence mode
portSequence (optional, "random"/"linear" default is "random") - UDP ports range enumeration sequence mode
portRange (optional, default is "5060-5060") - UDP port range for scanning, lower and upper bound values are included. Example:
5060-5080
ipMasks (optional, default is "[all IPs]") - IP ranges for scanning. Example:
192.168.1.0/24;192.168.2.0/24;192.168.0.0/24
userAgent (optional, default is "StarTrinityFriendlyScanner") - User-Agent SIP header value
<enablesipscanner maxRPS="10000" numberOfThreads="4">
<log value="SIP scanner got response from $ipAddress;: $responsePacketData;" />
</enablesipscanner>
<enablesipscanner maxRPS="20000" numberOfThreads="4">
<log enabled="false" value="SIP scanner got OPTIONS response from $ipAddress;: $responsePacketData;" />
<sendsipmessage maxtime="2s" var="status" serverheadervar="srv">
<![CDATA[INVITE sip:100@$ipAddress;:5060 SIP/2.0
Via: SIP/2.0/UDP 195.154.173.208:5090
Max-Forwards: 70
To: sip:100@$ipAddress;
From: sip:101@195.154.173.208;tag=test$id;
Call-ID: $randdigits(10);
CSeq: $randdigits(4); INVITE
Contact: sip:101@195.154.173.208:5090
User-Agent: StarTrinityFriendlyScanner
Accept: application/sdp
Content-Length: 0
]]>
</sendsipmessage>
<log value="server $ipAddress; responded to INVITE with status=$status;. server: $srv;" />
</enablesipscanner>
<enablesipscanner maxRPS="3000" numberOfThreads="1" enable="true" method="REGISTER" portsRange="5060-5100" ipSequence="linear" ipMasks="192.168.1.0/24;192.168.10.0/24;192.168.0.0/24">
<log enabled="true" value="got response from $ipAddress; port $port; response: $responsePacketData;" />
</enablesipscanner>
enqueue
Adds an element to a global queue
Attributes:
queueId (optional) - idenfier of the global queue
value0, value1, ... (multiple) - element's values to add into the queue. An element in the queue is an array of values: "value0" .. "valueN"
<accept value="200" />
<enqueue value0="$sipCallId;" value1="$id;" />
<dequeue label="dequeue" var0="peerCallId" var1="peerSessionId" exceptValue0="$sipCallId;" />
<if test="'$peerCallId;' = ''">
<wait value="3s" />
<if test="$movedConferenceByPeerCall; = 1"> <log value="don't dequeue: already moved to conference" /> <wait /> </if>
<goto value="dequeue" />
</if>
<dequeue onlyValue0="$sipCallId;" />
<assign var="conferenceId" value="$sipCallId;" />
<log value="connecting 2 calls: this call $sipCallId; peer call $peerCallId; session $peerSessionId;. conference ID = $conferenceId;" />
<sendevent session="$peerSessionId;" value="conference" />
<conference value="$sipCallId;" />
<on event="externalevent:conference">
<assign var="movedConferenceByPeerCall" value="1" />
<log value="joining to conference $conferenceId;" />
<conference value="$conferenceId;" />
</on>
exec
Parses string as CallXML script and executes it. Is similar to "eval" in JavaScript
Attributes:
value (required) - the CallXML script as string. It can be dynamically computed
<assign var="xml" value="<log value="test" />" />
<exec value="$xml;" />
exit
Terminates SIP call if it is created and not terminated yet. Sends BYE or CANCEL SIP message.
Terminates execution of CallXML script.
Attributes:
[none]
<exit />
exitcli
Terminates current command-line-mode SIP Tester. Is used to pass result of testing to .bat script
See also: "setexitcode"
Attributes:
value (optional) - process exit code
graceful (optional, "true"/"false", default "false") - "true" to stop call generator and to wait for all current calls to complete
<exitcli value="777" />
function
Defines a function or subroutine. Is executed with "runfunction".
Session variables, global variables and
parameters are shared between
caller code and the function's code, there is no "function scope". There is only a "flat context" of variables.
Functions enable to have all of repetitive code, like initiating environment, in one place.
Attributes:
name (required) - unique name of function
[parameters] (optional, "in[;defaultValue]" or "out") - names and types of parameters. There are "in" (input) and "out" (output) types of function parameters.
Input parameters may have default values (separated by semicolon); otherwise input parameters are required when running the function. Output parameters contain name of variable
<function name="func1" param1="in" param2="in" resultvar="out" >
<log value="func1: param1 = $param1;, param2 = $param2;" />
<assign var="resultvar" value="$param1;: OK" />
</function>
<runfunction name="func1" param1="TestValue1" param2="TestValue2" resultvar="result" />
<log value="result=$result;" />
getaudiofilelength
Reads WAV or MP3 audio file, calculates its duration, saves result to variable
Attributes:
value (required) - absolute or relative path to audio file(s), separated by semicolon.
If multiple files are specified, minimal duration is saved as result
var (required) - name of CallXML variable where to save audio length in milliseconds.
<getaudiofilelength value="music.wav" var="length" />
<log value="length = $length;ms" />
getcallcenteragent
Gets available call center agent. Is used to develop a call center with CallXML.
<getcallcenteragent g="group1">
<if test="$u;!=''">
<log value="transferring to SIP phone user $u; $ext($u;);" />
<transfer value="$ext($u;);" />
</if>
<else>
<log value="transferring to number $n;, via VoIP provider, using a regular PSTN call" />
<transfer value="sip:$n;@192.168.10.50:5070" />
</else>
<exit />
</getcallcenteragent>
<log value="no free agents, rejecting call with 503" />
<reject value="503" />
getcallgeneratorparams
Saves call generator parameters into CallXML variables.
Attributes:
maxcpsvar (optional) - name of CallXML variable to save max calls per second
maxconcurrentcallsvar (optional) - name of CallXML variable to save max concurrent calls
<getcallgeneratorparams maxcpsvar="maxcps" maxconcurrentcallsvar="nchannels" />
<log value="current params of call generation: max cps = $maxcps;, num of channels = $nchannels;" />
getcallinfo
Saves RTP information into CallXML variables, for currently processed SIP call.
Attributes:
codecvar (optional) - name of CallXML variable to save name of current codec
<accept value="183"/>
<getcallinfo codecvar="codec" />
<log value="received call with codec = $codec;" />
getcdrcallscount
Queries CDR with specified query expression and saves number of returned records into a variable. Is used in StarTrinity Softswitch for advanced filtering.
The software uses "memory" CDR (limited by global setting "MaxMemoryCdrCallsCount"), for higher performance. Calls in memory (RAM) get erased when the software is restarted.
Attributes:
expression -
boolean expression to query CDR
period (optional) - identifies CDR search period. Example:
24h - query calls in recent 24 hours
var - name of CallXML variable to save the number of queried calls
<getcdrcallscount expression="CalledId = 123456" var="c" period="24h"/>
<log value="there are $c; calls in CDR with specified criteria in recent 24 hours" />
<getcdrcallscount expression="MyCustomCdrHeader = SomeValue" var="c" period="24h"/>
<log value="there are $c; calls in CDR with specified criteria in recent 24 hours" />
<writecdr header="MyCustomCdrHeader" value="SomeValue"/>
<callxml type="custom">
<log value="StarTrinity softswitch processes the call with custom callxml script. Originator ID is: $originatorId;" />
<log value="A number is $callerId;, B number is $calledId;" />
<writecdr header="blocked" value="1" />
<assign var="t1" value="$rand(15,45);" />
<getcdrcallscount expression="blocked = '1' and originatorId='$originatorId;' and Direction = in" var="c" period="$t1;m" />
<log value="$c; calls in RAM (memory) CDR with flag blocked = 1 in recent $t1; minutes. this log is accessible in CDR - call details" />
<transfer terminators="routed" />
</callxml>
getdblcallscount
Queries RAM-based dynamic black list and saves number of returned records into a variable. Is used in StarTrinity softswitch for advanced filtering.
Attributes:
value - number for the lookup
dblType - type of the dynamic blacklist for the lookup. One of following: cli_dbl1, cli_dbl2, cld_dbl1, cld_dbl2
terminatorId (optional) - specifies terminator's blacklists wor the lookup, by terminator ID. If not set, current originator's blacklists are used
var - name of CallXML variable to save the number of queried calls
<getdblcallscount value="$callerId;" var="count" dblType="cli_dbl1" />
<log value="number of items in dynamic CLI blacklist is $count; for number $callerId;" />
<if test="$count; &> 10">
<accept />
<playaudio value="ivr.wav" />
<exit />
</if>
getfilenamefrompath
Parses full file path, extracts file name
Attributes:
value (required) - input file name with path
var (required) - name of CallXML variable to save file name without path
<getfilenamefrompath var="fn" value="c:\path\file.txt" />
<log value="file name = $fn;" />
gethash
Calculates hash of a string
Attributes:
value (required) - input string
var (required) - name of CallXML variable to save hashed string
<gethash var="h" value="1231234123" />
<log value="hashed string = $h;" />
getrtpinfo
gets RTP information from media into CallXML variables
The CallXML variables are:
RTP_Remote_IP, RTP_Codec,
RTP_Remote_Port,
RTP_ExpectedDuration_ms,
RTP_AfterJbDuration_ms
. See also: "getrtpmeasurements"
Attributes:
[none]
<accept />
<wait value="6s" />
<getrtpinfo />
<log value="RTP info: RTP_Remote_IP: $RTP_Remote_IP;, RTP_Codec: $RTP_Codec;, RTP_Remote_Port: $RTP_Remote_Port;, RTP_ExpectedDuration_ms: $RTP_ExpectedDuration_ms;ms, RTP_AfterJbDuration_ms: $RTP_AfterJbDuration_ms;ms" />
<callxml type="custom">
<getrtpinfo />
<log value="before transfer to B: RTP_Remote_IP: $RTP_Remote_IP;" />
<transfer terminators="routed" />
<on event="hangup;localHangup">
<getrtpinfo />
<log value="after transfer: RTP_Remote_IP: $RTP_Remote_IP;, RTP_Remote_Port: $RTP_Remote_Port;, RTP_ExpectedDuration_ms: $RTP_ExpectedDuration_ms;ms, RTP_AfterJbDuration_ms: $RTP_AfterJbDuration_ms;ms" />
</on>
</callxml>
getrtpmeasurements
Saves measured RTP quality indicators into CallXML variables
The CallXML variables correspond to
CDR header names in CSV files:
RTP_Caller_G107R,
RTP_Caller_G107MOS,
RTP_Caller_LostPackets,
RTP_Caller_MaxRfc3550Jitter,
RTP_Caller_MeanRfc3550Jitter,
RTP_Caller_MaxDelta,
RTP_Caller_MinDelta,
RTP_Caller_PacketTime,
RTP_Caller_NonSilentDuration,
RTP_Caller_Delay,
SDP_RTP_Caller_Delay,
RTP_Called_G107R,
RTP_Called_G107MOS,
RTP_Called_LostPackets,
RTP_Called_MaxRfc3550Jitter,
RTP_Called_MeanRfc3550Jitter,
RTP_Called_MaxDelta,
RTP_Called_MinDelta,
RTP_Called_PacketTime,
RTP_Called_NonSilentDuration,
RTP_Called_Delay,
SDP_RTP_Called_Delay,
RTCP_RTT_Max,
RTCP_RTT_Mean,
RTCP_Caller_Jitter_Max
RTCP_Caller_Jitter_Mean,
RTCP_Caller_LostPackets,
RTCP_Called_Jitter_Max,
RTCP_Called_Jitter_Mean,
RTCP_Called_LostPackets,
RTP_Rx_PacketsTotal,
RTP_Rx_PacketsDiscarded,
RTP_Rx_PacketsDiscarded_Duplicated,
RTP_Rx_PacketsDiscarded_Early,
RTP_Rx_PacketsDiscarded_Late,
RTP_Rx_PacketsDiscarded_Error
Note: the RTP stream is removed from the Packet Analyser, when no RTP packets are detected for some time, and RTP measurements get erased.
Please increase global setting "DetectedRtpStreamMaxIdleTimeMs" if you want to keep the RTP stream for longer time.
See also: "resetrtpmeasurements", "getrtpinfo"
Attributes:
[none]
<accept />
<wait value="6s" />
<getrtpmeasurements />
<log value="caller-called RTP stream: sdp-rtp delay: $SDP_RTP_Caller_Delay;ms, packet loss: $RTP_Caller_LostPackets;%, max delta: $RTP_Caller_MaxDelta;ms, max rfc3550 jitter: $RTP_Caller_MaxRfc3550Jitter;ms, G.107 MOS: $RTP_Caller_G107MOS;" />
<log value="RTCP measurements: caller max jitter: $RTCP_Caller_Jitter_Max;ms; caller packet loss: $RTCP_Caller_LostPackets;%, called max jitter: $RTCP_Called_Jitter_Max;ms; called packet loss: $RTCP_Called_LostPackets;%, max round trip delay: $RTCP_RTT_Max;ms" />
getsiptrace
Saves information about previously sent or received SIP packet into a variable
Searches SIP trace of current SIP call or another call by SIP Call ID, saves SIP message into a variable. Then searches for a specific line (SIP header or SDP attribute) and saves matched line to a variable
See also: substring, sendsipmessage, sendsiprequest
Attributes:
sipCallId (optional, default is current SIP call) - SIP Call-ID header (unique identifier of SIP call) used to find the SIP trace
packetStart (required) - first bytes of searched SIP packet. Example: SIP/2.0 200
packetVar (optional) - name of variable where to save the SIP packet
lineStart (optional) - first bytes of searched line in the SIP packet. Example: m=
lineVar (optional) - name of variable where to save the line
<call value="sip:test@192.168.10.77:5060">
<on event="answer" >
<getsiptrace packetStart="SIP/2.0 200" packetVar="latest200SipPacket" />
<log value="200 OK packet: $latest200SipPacket;" />
<getsiptrace packetStart="SIP/2.0 100" packetVar="latest100SipPacket" />
<log value="100 Trying packet: $latest100SipPacket;" />
<getsiptrace packetStart="SIP/2.0 200" lineStart="Allow: " lineVar="latest200okAllowLine" />
<log value="200 OK packet Allow line: $latest200okAllowLine;" />
<getsiptrace packetStart="SIP/2.0 200" lineStart="m=" lineVar="latest200okSdpMLine" />
<log value="200 OK packet SDP m= line: $latest200okSdpMLine;" />
<exit/>
</on>
</call>
getstatistics
Gets statistics about processed SIP calls
Saves statistics into CallXML variables:
incomingCps1s, incomingCps10s, incomingCps100s - incoming calls rate per second, averaged by 1, 10 and 100-second filters
outgoingCps1s, outgoingCps10s, outgoingCps100s - outgoing calls rate per second, averaged by 1, 10 and 100-second filters
answeredCallsCount - total number of answered calls
answeredCallsAverageDuration - average answered duration (in seconds)
currentAnsweredCallsCount - number of answered calls at current time
currentCallsCount - number of concurrent calls at current time
See also: resetstatistics
Attributes:
[none]
<getstatistics />
<log value="incomingCps1s = $incomingCps1s;; incomingCps10s = $incomingCps10s;; incomingCps100s = $incomingCps100s;" />
<log value="outgoingCps1s = $outgoingCps1s;; outgoingCps10s = $outgoingCps10s;; outgoingCps100s = $outgoingCps100s;" />
<log value="answeredCallsCount = $answeredCallsCount; answeredCallsAverageDuration = $answeredCallsAverageDuration; currentAnsweredCallsCount = $currentAnsweredCallsCount; currentCallsCount = $currentCallsCount;" />
getstringlength
Calculates length of a string/number in characters/digits
Saves result into CallXML variable
Attributes:
value (required) - input string
var (required) - name of variable where to save result
<getstringlength value="$calledId;" var="calledIdLength" />
<log value="Called ID length = $calledIdLength;" />
<getstringlength value="$callerId;" var="callerIdLength" />
<log value="Caller ID length = $callerIdLength;" />
getwg67info
Saves WG-67 RTP header extension data into CallXML variables. Measures round-trip delay time if peer SIP-UA has PTT-SQU loopback connection
Attributes:
ptt2squdelayvar (optional) - name of CallXML variable to save measured round-trip delay time [in milliseconds]
ptttypevar (optional) - name of CallXML variable to save WG-67 PTT-type field from RX stream
pttidvar (optional) - name of CallXML variable to save WG-67 PTT-ID field from RX stream
squvar (optional) - name of CallXML variable to save WG-67 SQU field from RX stream
pmvar (optional) - name of CallXML variable to save WG-67 PM field from RX stream
pttsvar (optional) - name of CallXML variable to save WG-67 PTTS field from RX stream
sctvar (optional) - name of CallXML variable to save WG-67 SCT field from RX stream
<call value="sip:111@devpc:5070" callerId="1111" />
<on event="answer">
<setrtpextension wg67_pttType="1" wg67_pttId="16" />
<playaudio value="music.wav" maxtime="3s" />
<setrtpextension wg67_pttType="0" wg67_pttId="16" />
<playaudio value="music.wav" maxtime="3s" />
<getwg67info ptt2squdelayvar="ptt2squdelay" ptttypevar="ptttype" pttidvar="pttid" squvar="squ" pmvar="pm" pttsvar="ptts" sctvar="sct" />
<log value="WG67 measurements: ptt2squdelay=$ptt2squdelay;ms, ptttype=$ptttype;, pttid=$pttid;, squ=$squ;, pm=$pm;, ptts=$ptts;, sct=$sct;" />
<writecdr field="RX_WG67_PTT_ID" value="$pttid;" />
<writecdr field="RX_WG67_PTT2SQU_DELAY" value="$ptt2squdelay;" numeric="true" qualityIsAscending="false" />
<exit />
</on>
<accept />
<setrtpextension wg67_pttType="1" wg67_pttId="33" wg67_squ="rxptt" wg67_pm="0" wg67_ptts="0" wg67_sct="0" />
<playaudio value="music2.wav" repeat="infinite" maxtime="60s" />
<exit />
goto
Performs
one-way transfer of control to another CallXML element with specified "label".
Attributes:
value (required) - destination CallXML element "label" attribute
test (optional) -
boolean expression, specifies condition of transfer
<goto value="play_music1" test="$callerId; = 100" />
<goto value="play_music2" test="$callerId; = 101" />
<reject />
<block label="play_music1" >
<playaudio value="music1.wav" />
<exit />
</block>
<block label="play_music2" >
<playaudio value="music2.wav" />
<exit />
</block>
if
Executes internal CallXML elements if specified conditions are satisfied
Optionally executes internal elements of
"else",
"elseif", which should be placed after "if"
Attributes:
test (required) -
boolean expression, specifies condition of executing internal CallXML elements. Syntax of condition is following:
<if test="abc = abc">
<log value="abc = abc - it is true" />
</if>
<else>
<log value="abc != abc - it is not true" />
</else>
<if test="abc = def">
<log value="abc = def - it is not true" />
</if>
<else>
<log value="abc != def - it is true" />
</else>
<if test="abc = abc and def = def">
<log value="abc = abc AND def = def - it is true" />
</if>
<accept />
<if test="$callerId; startswith 44 or $callerId; startswith +44">
<log value="Caller ID starts with 44 or +44" />
<playaudio value="IVR1.wav" />
<exit />
</if>
<if test="$callerId; startswith 1 or $callerId; startswith +1" >
<log value="Caller ID starts with 1 or +1" />
<playaudio value="IVR2.wav" />
<exit />
</if>
<log value="some unknown Caller ID: $callerId;" />
<playaudio value="IVR3.wav" />
<exit />
<log value="start of test" />
<if test="1=2">
<log value="1=2" />
</if>
<if test="3=2">
<log value="3=2" />
</if>
<elseif test="1=1">
<log value="1=1" />
</elseif>
<else>
<log value="inside 'else' element" />
</else>
<log value="end of test" />
ifcallexists
Executes internal CallXML elements if a SIP sall with specified criteria exists in current calls or in call history
Ignores leading "+" character in the numbers.
You can check if call exists at another (remote) instance of SIP Tester by sending a HTTP API request, see in "sendhttprequest" examples
Attributes:
sipCallId (optional) - SIP Call-ID
callerId (optional) - SIP User ID in "From" header
calledId (optional) - SIP User ID in "To" header
calledId_WithoutTechPrefix (optional) - CLD (B) number (used in StarTrinity Softswitch only)
direction (optional, "in" or "out") - incoming or outgoing call
expression (optional) - CDR filter
boolean expression, when querying call history. It must be constant, for callerId and calledId filters use corresponding attributes
considerThisCall (optional, "true" or "false", default "true") - specifies whether to consider current call when searching for the matching call
foundCallSessionIdVar (optional) - name of CallXML variable where to put CallXML session ID of matched call, if call exists. Is used to send an event to the matched call.
<assign label="generate_new" var="from" value="$rand(1000,1005);" />
<ifcallexists callerId="$from;" >
<goto value="generate_new" />
</ifcallexists>
<call value="sip:test@10.10.10.10" callerId="$from;" />
<ifcallexists query="CalledId = $calledId;" >
<log value="this number has already been called" />
</ifcallexists>
ifconferenceexists
Executes internal CallXML elements if conference with specified ID currently exists
Attributes:
value (required) - ID of conference
<ifconferenceexists value="$confId;">
<accept />
<conference value="$confId;" />
</ifconferenceexists>
<reject value="503"/>
ifnumberexists
Executes internal CallXML elements if a number list contains specified number (fast number lookup by prefix)
A number list may contain millions of records. An item in list may contain concatenated A and B numbers
Attributes:
value (required) - searched number (prefix)
numberListId (required) - number list ID (number list is uploaded via softswitch web interface)
<ifnumberexists value="$calledId;" numberListId="blacklist_CLI_01">
<reject value="503" />
</ifnumberexists>
include
Reads and executes another CallXML file. Returns control to current file after the execution. Imports functions from included file.
The included file is read from disk or obtained from memory cache only when CallXML flow reaches the "include" element.
Included file name could be dynamically calculated. File must have ASCII encoding.
Note: "on" elements (event handlers) can not be placed inside included file. Please have "on" elements in main
Attributes:
value (optional) - path to included CallXML file. It can be dynamically calculated. The path can be absolute or relative to currently executed CallXML file location
httpUrl (optional) - HTTP URL of included CallXML file. It can be dynamically calculated
cache (optional, "true" or "false", default "true") - specifies whether to use previously cached included file from memory or not.
By default the "include" uses cached copy of callXML file and asynchronously starts to update the cache from disk,
so the CallXML flow is not delayed with file access operation
<include value="CustomScripts\script1.xml" />
<switch value="$callerId;">
<case startswith="198" > <include value="params198.xml" /> </case>
<case startswith="199" > <include value="params199.xml" /> </case>
</switch>
<playaudio value="$param.greeting;" />
inputdigits
Collects digits and saves them into variable
inputspeech
Recognizes voice (speech) to text and saves the text into variable. Uses
VOSK speech recognition server (based on
Kaldi).
limitcps
Limits number of calls per second (CPS) and concurrent calls (CC) in dialer scripts. Allows you to limit CPS and CC per destination IP.
If CPS/CC goes over specified limit (parameter "maxCPS" or "maxCC"), puts the CallXML session into a queue (identified by parameter "queueId"). This queue gets dequeued when CPS/CC goes back below the "maxCPS"/"maxCC".
When delay in the queue gets over "maxDelay", an error is generated.
Attributes:
queueId (required) - identifies the queue (see above)
maxDelay (required) - specifies max. delay in the queue
maxCPS (optional) - limits number of calls per second
maxCC (optional) - limits number of concurrent calls
putFirstInQueue (optional, "true"/"false", default is "false") - set to "true" if need to put this call first into the queue. For high-priority calls that need to be dialed urgently
<limitcps queueId="01" maxDelay="10s" maxCPS="40" maxCC="1000" putFirstInQueue="false" />
<call value="sip:xxx@1.2.3.4" />
log
Writes a message to GUI or CLI and to file log. Is used for debugging and reporting.
Attributes:
value (required) - text message to be written into log
level (optional, "debug"/"error", default "debug") - if "error", writes output to "stderr" stream instead of "stdout"
<log value="processing call from CLI/ANI '$callerId;'" />
<callxml type="custom">
<log value="StarTrinity softswitch processes the call with custom callxml script. Originator ID is: $originatorId;" />
<log value="A number is $callerId;, B number is $calledId;" />
<transfer terminators="routed" />
</callxml>
loopbackaudio
Plays received (RX stream) RTP audio back to SIP call (TX stream). Is used to verify audio path.
Attributes:
maxtime (optional, default is "infinite") - time of playing. Is set in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix).
<accept value="200" />
<loopbackaudio />
measuresignal
Measures min and max audio level of RX RTP stream. Saves result to variables.
Attributes:
maxtime (required) - time of measurement. Is set in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix)
maxlevelvar (optional) - name of variable to save maximal (peak) signal level in decibels
minlevelvar (optional) - name of variable to save minimal (min. of 10ms-length-frame maximums) signal level in decibels. Is used for audio verification with sine test signals
<accept />
<measuresignal maxlevelvar="max" maxtime="1s" />
<log value="measured audio level for incoming call: max=$max;dB" />
<writecdr header="maxLevelDb" value="$max;" numeric="true" qualityIsAscending="true" />
<function name="level2code" level="in" codevar="out">
<assign var="code" value="X" />
<switch value="$level;">
<case from="-35" to="-24"> <assign var="codevar" value="1" /> </case>
<case from="-24" to="-18"> <assign var="codevar" value="3" /> </case>
<case from="-18" to="-10"> <assign var="codevar" value="4" /> </case>
<case from="-10" to="-3"> <assign var="codevar" value="2" /> </case>
</switch>
</function>
<call value="sip:CP000181-14-86553@52.16.126.118:5060" />
<on event="answer">
<wait value="1s" />
<waitforsignal level="-40dB" />
<measuresignal maxlevelvar="l1" maxtime="2s" />
<runfunction name="level2code" level="$l1;" codevar="c1" />
<log value="level1=$l1;dB code1=$c1;" />
<waitforsilence level="-40dB" />
<waitforsignal level="-40dB" />
<measuresignal maxlevelvar="l2" maxtime="2s" />
<runfunction name="level2code" level="$l2;" codevar="c2" />
<log value="level2=$l2;dB code2=$c2;" />
<waitforsilence level="-40dB" />
<waitforsignal level="-40dB" />
<measuresignal maxlevelvar="l3" maxtime="2s" />
<runfunction name="level2code" level="$l3;" codevar="c3" />
<log value="level3=$l3;dB code3=$c3;" />
<waitforsilence level="-40dB" />
<waitforsignal level="-40dB" />
<measuresignal maxlevelvar="l4" maxtime="2s" />
<runfunction name="level2code" level="$l4;" codevar="c4" />
<log value="level4=$l4;dB code4=$c4;" />
<waitforsilence level="-40dB" />
<waitforsignal level="-40dB" />
<log value="measuresignal 5" />
<measuresignal maxlevelvar="l5" maxtime="2s" />
<runfunction name="level2code" level="$l5;" codevar="c5" />
<log value="level5=$l5;dB code5=$c5;" />
<waitforsilence level="-40dB" />
<writecdr header="codes" value="$c1;$c2;$c3;$c4;$c5;" />
<log value="level codes = $c1;$c2;$c3;$c4;$c5;" />
<exit />
</on>
<call maxtime="35000ms" value="sip:2222@192.168.10.4:5070" codec="G711A" callerId="+331234324234">
<on event="answer">
<wait value="1s" />
<measuresignal minlevelvar="min" maxlevelvar="max" maxtime="5s" />
<log value="measured signal: min=$min;dB max=$max;dB" />
<writecdr header="maxLevelDb" value="$max;" numeric="true" />
<writecdr header="minLevelDb" value="$min;" numeric="true" />
<exit />
</on>
</call>
movingAverageGet
Gets output of a "moving average", saves it to variable
Attributes:
id (required) - identifies the "moving average"
var (required) - name of variable where to save the output
movingAveragePut
Puts a value into a "moving average", configures number of samples to store for the calculation
Attributes:
id (required) - identifies the "moving average"
size (required) - specifies number of samples to store in the "moving average"
value (required) - input value
movingAverageReset
Resets a "moving average", i.e. removes all previously stored values from memory
Attributes:
id (required) - identifies the "moving average"
on
Handles CallXML events. Sets variable "eventType" and "eventSubType"
The "on" event handler is searched in child XML elements of current element and also in all sibling and parent XML elements.
Note: "on" event handler can not be placed inside included callxml files, please have "on" elements in main CallXML file
Attributes:
event (required) - type and optionally subtype of the handled event. Types of events are following:
- answer - answering of outgoing call
- callfailure - receiving error response for outgoing call
- dtmf - receiving DTMF signal. Warning: the call flow must not exit an element which is being used to wait for the DTMF event, otherwise it will generate a duplicate CallXML flow in the script
- error - system error
- hangup - termination of current SIP call by remote side after answer
- localHangup - termination of current SIP call by local side after answer
- cancelled - termination of current incoming SIP call by remote side before answer (when received CANCEL)
- idleMedia - detection of idle media event (not receiving RTP stream from remote side) - see global setting "IdleMediaTimeToEndSession"
- maxringtime - ringing timeout
- pr - receiving provisional response (1xx) to INVITE. Subtype of the event is SIP status code. Examples: "pr:100", "pr:180", "pr:180;pr:183"
- reinvite - receiving a RE-INVITE from remote side
- sipinfo - receiving SIP INFO
- sr - recognizing voice command
- transferred - answering of outgoing call, which was initiated by receiving REFER
The "event" may contain multiple event types separated by ";". Examples:
"maxringtime;callfailure",
"pr:180;pr:183"
<call callerId="123456" value="sip:7890123@192.168.1.57:5060" >
<on event="answer">
<block test="$global.available; != true">
<assign globalvar="available" value="true" />
<sendemail value="mailto:username@gmail.com?subject=sip testing - OK&body=received 200 OK response from server" />
</block>
<exit />
</on>
<on event="callfailure">
<block test="$global.available; != false">
<assign globalvar="available" value="false" />
<sendemail value="mailto:username@gmail.com?subject=sip testing - call failed with status $eventSubType;&body=call failed with status $eventSubType;"/>
</block>
<exit/>
</on>
</call>
<log value="making call to the server. it should be configured to answer to 'test' number with no delay" />
<call value="sip:test@localhost:5060" maxringtime="5s" />
<on event="answer">
<log value="call answered. aborting call" />
<exit />
</on>
<on event="maxringtime;callfailure">
<log value="call failed (5-sec timeout or error response). restarting server if did not restart already 3 minutes ago" />
<block minInterval="3m">
<sendemail value="mailto:email@gmail.com?subject=call to server failed. restarting the server" />
<log value="restarting SIP server" />
<!-- here you should set path to your SIP server -->
<restartprocess value="C:\Users\User\AppData\Roaming\StarTrinity SipTester\StarTrinity.SIPTester.exe" />
</block>
<exit />
</on>
<call value="$seq_sip_uri_from_csv(C:\StarTrinity\destinations.csv, 0);" maxringtime="950ms" />
<on event="pr:180;pr:183" >
<block probability="0.5">
<exit />
</block>
</on>
<on event="answer">
<playaudio value="music.wav" repeat="10000" maxtime="90s" />
<exit />
</on>
params
Declares parameters for the script
Parameters are read-only, their purpose is to have user-editable configurations for script in a separated place.
There can be multiple declarations of params in script. The params can be declared in an
included callxml file, or in parent callxml file.
Params aren't like variables. They are the one (or few) section(s) of the code, where the adjustable params are.
Attributes:
[none]
<params>
<param name="param1" value="value1" />
<param name="param2" value="value2" />
</params>
<log value="param1 = $param.param1;. param2 = $param.param2;" />
param
Is used within "params"; defines a parameter which can be used later in script
Attributes:
name (required) - name of the parameter
value (required) - value of the parameter
performAAA
Performs authentication, authorization and accounting for an incoming SIP call. Sets CallXML variables "originatorId", "tenantId", "language"
playaudio
Plays audio file from specified WAV/MP3 file/URL. Exits on end of file or end of silence (if "maxsilence" is specified), unless "dontwait" is set to "true"
The files are pre-cached into memory before playback, at startup time. If file name is dynamic and the audio file does not exist in the cache, it is cached at runtime.
The caching includes reading audio file from disk and encoding it into RTP payload using appropriate codec.
When transferring (in Softswitch), the audio is played to both call legs: A and B (if available).
See also:
controlaudio
Attributes:
value (required, if no attribute "valuePattern") - absolute or relative audio file name(s) or URL(s). Multiple file names or URLs are separated by semicolon (example:
speech.wav;music.wav). If relative file name is specified, in multitenant mode first it tries to locate a tenant-specific audio file in \[tenantId]\ subfolder, and if it is not found, it uses file from program root folder
maxtime (optional, default is "unlimited") - max time of playing. Is set in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix).
repeat (optional, default is "1") - number of times to repeat audio file
valuePattern (optional) - pattern for the file name. "?" is replaced by digit
valuePatternRandomSeed (optional) - any string data used to initialize random generator for "valuePattern"
conference (optional) - ID of conference where to play audio file. If not set, audio file is played only to current SIP call
updateCacheFromDisk (optional, "true"/"false", default is "false") - if set to "true", checks file last modification time and updates RAM cache when file is modified
dontwait (optional, "true"/"false", default is "false") - if set to "true", control is returned immediately, before ending of audio file.
In this case audio is still played during execution of next CallXML elements. It can be stopped using "stopaudio"
leg (optional, "A"/"B"/"both", default is "both") - during call transfer in StarTrinity Softswitch, specifies call leg: A=origination side or B=termination side
mode (optional) - if set to "siprec", the "playaudio" expects to open a stereo WAV file (8kHz, 16bit) to play it into the 2 RTP streams for SIPREC testing.
see sample CallXML script.
If set to "" (empty), mono WAV file is played to 1st RTP stream of a SIPREC test call. If set to "siprec2", mono WAV file is played to 2nd RTP stream of a SIPREC test call.
<playaudio value="C:\music\01.mp3" maxtime="10m" repeat="infinite" >
<log value="making call to server" />
<call callerId="test" value="sip:9999@server.com:5060" codec="G711A" />
<on event="pr:183">
<log value="received 183 Session Progress, playing early media to the server" />
<playaudio value="C:\early_media_tx.wav" dontwait="true" />
</on>
<on event="answer">
<log value="call answered" />
<exit />
</on>
<accept value="183" />
<playaudio value="ringbacktone.wav" dontwait="true" />
<stopaudio />
<accept value="200" />
playdtmf
Sends one or many DTMF digits to current SIP call. Returns control immediately.
If "UseRFC2833ToSendDTMF" setting is set to "1", sends DTMF within RTP stream (according to
RFC2833), otherwise uses SIP INFO method.
If you need to send audible DTMF signals, please use "playaudio" and pre-recorded WAV files with DTMF
See also:
sendsiprequest
Attributes:
value (required) - DTMF digits to send. If more than one digits are specified, time between digits is set by
"DtmfSendingIntervalMs" setting (default is 200ms). The value may contain 'p' character which means 1-second pause between DTMF digits
signaldelayvar (optional) - name of variable where to save audio response delay value in milliseconds.
If set, the "playdtmf" waits for audio response with signal level "DefaultSignalDetectorThresholdDb" (set in
settings).
method (optional, "sipInfo"/"rfc2833", default from global settings) - method to send the DTMF
<playdtmf value="1">
<wait value="500ms">
<playdtmf value="2">
<wait value="1000ms">
<playdtmf value="34p5">
<wait value="$rand(10,5000);ms">
<playdtmf value="#">
<playdtmf value="1">
<playaudio value="played_1.wav">
<wait value="5000ms">
<playdtmf value="2">
<playaudio value="played_2.wav">
<wait value="10000ms">
<playdtmf value="1" />
<log value="sent DTMF digit 1" />
<waitforsignal signaldelayvar="ivrDelay"/>
<log value="IVR response in RTP audio is $ivrDelay;ms" />
<playdtmf value="1" signaldelayvar="ivrDelay" />
<log value="IVR response in RTP audio is $ivrDelay;ms" />
<playaudio value="http://startrinity.com/speech.wav" repeat="infinite" >
readcsv
Reads a row from CSV file, stores fields into variables
Progress of reading the CSV file is displayed in SIP Tester's GUI on "reports/statistics" tab.
If the entire CallXML script is executed, but “readcsv" element is not executed, the CSV reader is left in current position.
CSV readers are shared between sessions, file data is cached into memory.
CSV file must have ASCII encoding. CSV fields delimiter is taken from "CsvDelimiter" global setting. See also: "readdb"
Attributes:
value (required) - absolute or relative CSV file name, or HTTP/HTTPS URL
var[columnIndex] (required) - names of variables to store fields from row. Zero-based [columnIndex] identifies column.
mode (optional, "sequential"/"random", default is "sequential") - mode of reading rows in CSV file
countsColumnIndex (optional) - zero-based index of column which contains count of reads for each row. Is used to read some rows more than one time.
skipHeaders (optional, "true"/"false", default is "false") - indicates whether to skip first row with headers
repeat (optional, default is "1") - number of times to repeat the whole CSV file. "infinite" to repeat file infinitely
repeatCounterVar (optional) - variable to save the repeat counter. The counter starts from zero and gets incremented with every pass of entire CSV file
eofMode (optional, "error" or "emptyValues", default "error") -
specifies what to do when there are no more rows to read in file (EOF) and when "repeat" counter is finished, also when "rowIndex" is out of bounds.
"error" - raises 'error' event; "emptyValues" - return empty field values
rowIndex (optional) - zero-based row index. If not set, global pointer is used. The global counter is incremented with every read.
<readcsv value="c:\list.csv" var0="resultField0" var1="resultField1" var2="resultField2" repeat="3" />
<on event="error">
<log value="CSV EOF, 3 times repeated all rows" />
</on>
<readcsv value="list.csv" var0="callerIdFromCsv" var1="calledIdFromCsv" countsColumnIndex="2" mode="random" />
<call value="sip:$calledIdFromCsv;@10.10.10.1" callerId="$callerIdFromCsv" />
<readcsv value="c:\01.csv" mode="random" var0="dialNumber" var1="cli" var2="pin" skipHeaders="true" repeat="infinite" />
<call value="sip:$dialNumber;@10.10.10.10:5060" callerId="$cli;" />
<on event="answer">
<wait value="500ms" />
<playdtmf value="$pin;#" />
<playaudio value="$randswitch(c:\01.wav,c:\02.wav,c:\03.wav);" maxtime="$rand(10,20);s" />
<exit />
</on>
<switch>
<case probability="50" >
<call maxringtime="7000ms" value="$seq_sip_uri_from_csv(C:\Users\Administrator\Desktop\Data\XXXXXXXXXXX.csv, 1);" />
</case>
<case probability="50" >
<call maxringtime="7000ms" value="$seq_sip_uri_from_csv(C:\Users\Administrator\Desktop\Data\YYYYYYYYYYY.csv, 1);" />
</case>
</switch>
<on event="answer">
<playaudio value="music.wav" maxtime="10s" />
<exit />
</on>
<readcsv value="C:\StarTrinity\CSV\Morocco160125.csv" var0="f0_1" var1="f1_1" repeat="infinite"/>
<readcsv value="C:\StarTrinity\CSV\Lybia160125.csv" var0="f0_2" var1="f1_2" repeat="infinite"/>
<call maxringtime="35000ms" value="$rand_from_options;" codec="G729" >
<option value="sip:$f0_1;@[ip1]?callerId=$f1_1;" maxCallsPerDestinationResource="100" destinationResourceId="server1" />
<option value="sip:$f0_2;@[ip2]?callerId=$f1_2;" maxCallsPerDestinationResource="200" destinationResourceId="server2" />
</call>
<on event="answer">
<playaudio value="$randfile(C:\StarTrinity\Wav Files\*.wav);" repeat="infinite" maxtime="$rand(670000);ms" />
<exit />
</on>
<readcsv value="userIds.csv" var0="userId1" repeat="infinite" repeatCounterVar="repeatCounter1" />
<readcsv value="userIds.csv" var0="userId2" repeat="infinite" repeatCounterVar="repeatCounter2" />
<log value="userId1=$userId1; repeatCounter1=$repeatCounter1; userId2=$userId2; repeatCounter2=$repeatCounter2; " />
<if test="$repeatCounter1; == 0">
<register value="sip:$userId1;@192.168.10.4:5090?user=$userId1;&password=123456" expires="3600" var="status" delayvar="delay" />
<log value="user1 ($userId1;) REGISTER response code = $status;, delay = $delay;ms" />
<register value="sip:$userId2;@192.168.10.4:5090?user=$userId2;&password=123456" expires="3600" var="status" delayvar="delay" />
<log value="user2 ($userId2;) REGISTER response code = $status;, delay = $delay;ms" />
</if>
<else>
<call value="sip:$userId2;@192.168.10.4:5090?user=$userId1;&password=123456" />
<on event="answer">
<playaudio value="music.wav" />
<exit />
</on>
</else>
readdb
Executes a database query, returns rows one by one, stores fields into variables
The database request is done via ODBC drivers to MSSQL, MySQL, PostgreSQL, other databases.
Database readers are shared between sessions, queried records are cached into memory. See also: "readcsv"
Attributes:
value (required) - SQL query to execute
odbcConnection (required) - ODBC connection string
var[columnIndex] (required) - names of variables to store data fields. Zero-based [columnIndex] identifies column.
repeat (optional, default is "1") - number of times to repeat the queried records. "infinite" to repeat file infinitely
reloadOnRepeat (optional, "true" or "false", default is "false") - need to reload data from database when queried records are repeated
<readdb value="select Number from NumbersToDial" odbcConnection="Driver={SQL Server};Server=server.com\SQLEXPRESS;Database=Test;Uid=sa;Pwd=abcxyz;" var0="number" repeat="infinite" reloadOnRepeat="false" />
<log value="read number from database: $number;" />
<call value="sip:$number;@12.34.56.67">
<on event="answer" >
<playaudio value="music.wav" />
<exit />
</on>
</call>
<readdb value="select Number, ServerIP from NumbersToDial" odbcConnection="Driver={SQL Server};Server=server.com\SQLEXPRESS;Database=Test;Uid=sa;Pwd=abcxyz;" var0="number" var1="serverIp" repeat="infinite" reloadOnRepeat="false" />
<log value="read number from database: $number;@$serverIp;" />
<call value="sip:$number@$serverIp;">
<on event="answer" >
<playaudio value="music.wav" />
<exit />
</on>
</call>
readnumberlist
Reads a row from number list file, stores fields into variables
Is used with dialer campaigns in StarTrinity softswitch and with API method "UploadNumberList" in StarTrinity SIP Tester.
The number list readers are shared between CallXML sessions, but are kept separate between softswitch tenants. File data is cached into RAM for high performance.
CSV file must have ASCII encoding. CSV fields delimiter is ";" or ",". See also: "readdb", "readcsv"
Attributes:
value (required) - identifier of number list, its file name
mode (optional, "sequential"/"random", default is "sequential") - mode of reading rows in the number list
singleRowRepeatCount (optional, default is "1") - number of times to repeat every read row
var[columnIndex] (required) - names of variables to store fields from row. Zero-based [columnIndex] identifies column.
repeatInfinitely (optional, "true"/"false" default is "false") - set to "true" to repeat the number list infinitely
<readnumberlist value="a_numbers_txt" var0="cli" />
<log value="read CLI $cli;" />
receivefax
Initiates RE-INVITE with T.38 fax SDP offer, receives T.38 fax to file.
Does not return control untile fax operation is complete. If the fax operation fails, raises an "error" event, it could be handled in CallXML script
Attributes:
value (optional) - file name where to save received fax. If not set, unique file name will be generated
<receivefax />
<receivefax value="C:\receivedfax.tiff" />
recordcall
Switches on/off recording for current SIP call or conference.
Returns control immediately. Recording is started only when RTP media session is established.
Audio is recorded from mix of RX and TX audio streams of current SIP call, and from mix of RX streams of all calls in conference.
Recorded wav file name pattern is configured with settings.
Attributes:
value (required) - percentage of SIP calls to be recorded. If "100", always starts recording; if "0" always stops recording
conference (optional) - ID of conference for recording. If not set, only current SIP call is recorded
uploadToUrls (optional) - semicolon-separated list od URLs where to upload the recorded files. The software sends HTTP POST with form fields "recorded_file" and "sip_call_id" and deletes the recorded file after successful upload. This can be used to get the recording at your custom HTTP server
basepath (optional) - folder for recorded files
mode (optional, "rx", "tx", default "mix") - source of audio data for recording. "rx" - audio received from remote side,
"tx" - audio transmitted to remote side, "mix" - mix of "rx" and "tx"
recorderId (optional, default is "") - unique identifier of the recorder, is used when multiple recorders are used for one call
<recordcall value="100" basepath="F:\recordings" />
<recordcall value="100" uri="c:\recorded_files\$time();_$callerId;.wav" />
<recordcall value="100" conference="01" />
<recordcall value="0" />
recordmessage
Records audio message e.g. for voicemail, optionally detects silence
Returns control after message is recorded. Recording is ended by pressing any DTMF key, if "finalkeys" parameter is not specified.
Recording is also ended when silence is detected (when person is no longer speaking) if "stopOnSilenceLevelDb" and "stopOnSilenceMinimalSilentDuration" parameters are specified.
Attributes:
value (required) - path to new recorded file
recorderId (optional, default is "") - unique identifier of recorder, is used when multiple recorders are used for one call
finalkeys (optional) - DTMF keys which end the recording, example: #* - both # and * digits end the recording. By default any DTMF key stops the recording
maxtime (optional) - maximal duration of the recording in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix)
stopOnSilenceLevelDb (optional) - silence detection threshold level in dB. "0" corresponds to max level, "-6" to 50%, recommended value is "-24"
stopOnSilenceMinimalSilentDuration (optional) - minimal duration of input audio below the "stopOnSilenceLevelDb" before stopping the recording. Recommended value is "3s"
<recordmessage value="d:\recordings\$time(yyyyMMdd_HH_mm_ss_fff);.wav" />
<recordmessage value="d:\recordings\$time(yyyyMMdd_HH_mm_ss_fff);.wav" maxtime="3m" stopOnSilenceLevelDb="-24" stopOnSilenceMinimalSilentDuration="3s" />
redirect
Redirects incoming SIP call to new destination. Sends "302 Moved Temporarily" response with new contact.
Attributes:
value (required) - SIP URI with new contact
<redirect value="sip:1000@10.10.10.1" />
regexsearch
Searches for patterns in strings using
regular expressions
Uses
System.Text.RegularExpressions.Regex.Match method from Microsoft .NET library
Attributes:
value (required) - input string
regex (required) - regular expression. Nnote that it should be XML-escaped, i.e. '<' and '>' should be replaced with '<' and '>'
var (required) - list of variables' names to store results
<regexsearch value="ABCD 123 456 789"
regex="ABCD\W*(?<digits1>\d+)\W*(?<digits2>\d+)\W*(?<digits3>\d+)" var="digits1;digits2;digits3" />
<log value="digits1='$digits1;', digits2='$digits2;', digits3='$digits3;'" />
<regexsearch value="$sipheadercontact;" regex="@(?<sip_contact_address>[^;]*)" var="sip_contact_address" />
<regexsearch value="asdasg s dfghdfghdfgh 777 asdf asd asf" regex="[0-9]+" var="digits" />
<log value="found digits: $digits;" />
<call value="sip:$randdigits(10);@1.2.3.4" callerId="$randdigits(7);" maxringtime="100s" var="r" codec="G711A" fromTag="TEST$randdigits(10);">
<on event="answer">
<log value="received To header '$sipHeaderTo;'" />
<regexsearch value="$sipHeaderTo;" regex=";tag=(?<toTag>\S*)" var="toTag" />
<log value="received To header tag = '$toTag;'" />
<wait value="300s" />
<exit />
</on>
</call>
register
Sends REGISTER, waits for response, saves status to a variable. Measures delay between sending "REGISTER" request and receiving "200 OK" response
Attributes:
value (required) -
SIP URI of destination.
SIP URI can contain user and password for authentication, "transport" query parameter ("udp"/"tcp"/"tls", "udp" is default), "proxyAddress" and "proxyPort" query parameters
var (optional) - name of variable to store response status code
delayvar (optional) - name of variable to store response delay in milliseconds
expires (optional) - value of "Expires" SIP header. Default is 3600 (seconds). If set to 0, the REGISTER request means un-registration
headers (optional) - list of custom SIP headers to be included into the REGISTER request.
Example: Header1Name=Header1Value|Header2Name=Header2Value|Header3Name=Header3Value
localSipPort (optional) - explicitly set local SIP/UDP transport port. Is used with global settings "LocalSipPort", "LocalSipPortRange"
localSipAddress (optional) - explicitly set local SIP IP address, is used to select network interface. Is used with global setting "LocalSipAddresses"
contactHeaderFormat (optional) - custom Contact header format. Example:
"Eran%20Younger" <sip:[userId]@[localIp]:[localPort];transport=TLS;ob>;reg-id=1;+sip.instance="<urn:uuid:2c72cde9-c1d4-321d-8727-9bb0e165519f>"
sipCallId (optional) - custom Call-ID header to put into REGISTER request packet. Is used to link unregistration REGISTER request to registration REGISTER request.
<log value="sending REGISTER..." />
<register value="sip:100@192.168.0.17?user=100&password=123456" expires="180" var="status" delayvar="delay" />
<log value="received response code = $status;, delay = $delay;ms" />
<register value="sips:$rand(100,200);@192.168.10.4:5061?transport=tls" var="status" />
<register value="sip:555@startrinity.com" contactHeaderFormat="sip:666@23.45.56.78:7895" />
<log value="sending un-REGISTER (expires = 0)..." />
<register value="sip:100@192.168.0.17?user=100&password=123456" expires="0" var="status" delayvar="delay" />
<log value="received response code = $status;, delay = $delay;ms" />
<register value="sip:+16509090910@mydomain.net?user=%2B165090909100&password=1230&proxyAddress=mydomain2.net0&proxyPort=5060" expires="3600" var="result" delayvar="delay" />
<register value="sip:$rand(400,200);@192.168.10.4:5060?user=%2B165090909100&password=1230&transport=udp" localSipAddress="192.168.10.$rand(1,4);" localSipPort="506$rand(0,9);" var="status" />
reinvite
Sends RE-INVITE. Is used to put SIP call on hold (call parking feature)
See also: "update"
Attributes:
direction (optional, "SendOnly"/"ReceiveOnly"/"None"/"Both") - RTP media stream direction.
The meaning of the direction in SDP is a little bit confusing. It is explained in
RFC3264.
If one side (A) sends "recvonly" in its SDP offer, the other side (B) should say "sendonly" (opposite) in its SDP answer.
After that (when SIP call is put on hold), A "receives only, not sends" from B, and B "sends only, not receives" to A,
in other words RTP stream flows in one direction: from B to A, microphone at A is muted
sendSdp (optional, "true"/"false", default "true") - send SDP in the RE-INVITE packet. "false" is used to test case of SDP offer in "200 OK" and SDP answer in "ACK"
localRtpAddress (optional) - a custom IP address to put into SDP. Is used for test purposes
codec (optional, "G711A"/"G711U"/"G723"/"G729", default is "current") - new RTP media codec (SDP media stream payload type) to be sent in the RE-INVITE SDP
<reinvite direction="ReceiveOnly" />
<call value="sip:test@10.10.10.10" />
<on event="answer">
<playaudio value="music.wav" maxtime="5s" />
<reinvite codec="G729" />
<playaudio value="music.wav" maxtime="5s" />
<reinvite codec="G711A" />
<playaudio value="music.wav" maxtime="5s" />
<exit />
</on>
reject
Rejects incoming SIP call before answering. Sends response with custom SIP status code.
Attributes:
value (optional, default is "603") -
SIP status code for the response
headers (optional) - list of custom SIP headers to be included into the INVITE message.
Example: Header1Name=Header1Value|Header2Name=Header2Value|Header3Name=Header3Value
<reject value="486" />
<reject value="486" headers="Reason=Q.850;cause=17" />
<reject value="302" headers="Contact=sip:152@192.168.0.56" />
replacestring
Performs text replacement
Attributes:
value (required) - input text
var (required) - name of variable where to save result
old (required) - old text to be found and replaced
new (required) - new text
<replacestring value="this is original text" old="initial" new="new" var="result" />
<log value="result of replacement is: $result;" />
report
Saves custom performance indicator to SIP Tester's GUI and HTML report
See also: "writecdr"
Attributes:
name (required) - name of the performance indicator which will be displayed in report
value (required) - numeric value of the performance indicator
qualityIsAscending (optional, "true"/"false") - indicates whether call quality increases or decreases with increasing of the indicator.
Is used to calculate percentiles and list of worst quality calls.
<playdtmf value="1" />
<waitforsignal signaldelayvar="ivrDelay"/>
<report name="IVR_delay_1" qualityIsAscending="false" value="$ivrDelay;" />
requestcsv
Makes a fast (RAM-based) lookup in a CSV file
The "requestcsv" first reads CSV file into memory cache, builds index and then for subsequent requests uses the cache. The cache can be reset with a button using web UI or desktop GUI.
System setting "CsvDelimiter" is used to parse CSV files. See also: "requestdb"
Attributes:
value (required) - file name or URL of CSV file
column0 (required) - value of first column in CSV file (index #0), key to make the lookup
column1var (required) - name of CallXML variable where to save result. If key was not found - an empty value is saved as result. If multiple values found for same key - random value is returned.
rereadAfter (optional) - max time to use cached CSV data, before re-reading the CSV file. Example: 60m
<requestcsv value="C:\CSV\myCliDictionary.csv" column0="$callerId;" column1var="result" />
<log value="query result for $callerId;: $result;" />
requestdb
Executes MSSQL command (select, insert, delete statements, stored procedures). Stores fields from the first requested row into variables. If no rows returned, saves empty values
The "requestdb" is executed even if current SIP call is disposed, independently from SIP thread. If no connection string is set by parameters, CDR connection string from settings is used. See also: "requestcsv"
Attributes:
connection (optional) - connection string to MSSQL server, contains name of server, name of database, authentication parameters. Example: Data Source=(local)\SQLEXPRESS;User ID=sa;Password=123;Initial Catalog=db1;Asynchronous Processing=true
odbcConnection (optional) - ODBC connection string to database server. Examples: Driver={SQL Server};Server=localhost\SQLEXPRESS;Database=testCDR;Uid=sa;Pwd=pass;,
command (required) - SQL command text. If not set by XML attribute, the command text is taken from inner XML text (see example)
var[columnIndex] (required) - names of variables to store results returned by MSSQL server
<requestdb command="exec SaveCallerId '$callerId;', 'Test', 'Test'"
connection="Data Source=(local);User ID=sa;Password=123456;Initial Catalog=DtmfTest;Asynchronous Processing=true"
var0="resultField0" var1="resultField1" var2="resultField2" />
<inputdigits var="enteredNumber" maxsilence="20s" maxdigits="10" />
<requestdb command="select InfoMessage from Table1 where PinCode = '$enteredNumber;'"
connection="Data Source=(local)\SQLEXPRESS;User ID=sa;Password=123;Initial Catalog=db1;Asynchronous Processing=true"
var0="infoMessage" />
<say voice="Microsoft Anna" value="$infoMessage;" />
<requestdb odbcConnection="Driver={SQL Server};Server=startrinity.com\SQLEXPRESS;Database=TestCDR;Uid=sa;Pwd=asv2015HJLK;" var0="f0" var1="f1" var2="f2">
select top 1 callerId, calledId, created from StartrinitySipTesterCdrs order by created desc
</requestdb>
<log value="result from database: callerId = $f0;, calledId = $f1;, created = $f2;" />
<requestdb odbcConnection="Driver={MySQL ODBC 5.3 ANSI Driver}; Server=91.121.146.1;Database=mor; User=usr1; Password=pass1; Option=3;" var0="f0">
SELECT `src` FROM `calls` WHERE `calldate` > DATE_SUB(NOW(), INTERVAL 48 HOUR) AND `localized_dst` LIKE '%09299802' LIMIT 1
</requestdb>
<log value="result from MySQL MOR CDR database: callerId = $f0; (empty if not found)" />
resetrtpmeasurements
Resets RTP measurement state of current SIP call. Is used to have multiple independent RTP measurements for one SIP call
See also: "getrtpmeasurements"
Attributes:
[none]
<accept />
<wait value="20s" />
<getrtpmeasurements />
<log value="measurement 1: caller-called RTP stream: sdp-rtp delay: $SDP_RTP_Caller_Delay;ms, packet loss: $RTP_Caller_LostPackets;%, max delta: $RTP_Caller_MaxDelta;ms, max rfc3550 jitter: $RTP_Caller_MaxRfc3550Jitter;ms, G.107 MOS: $RTP_Caller_G107MOS;" />
<log value="RTCP measurements 1: caller max jitter: $RTCP_Caller_Jitter_Max;ms; caller packet loss: $RTCP_Caller_LostPackets;%, called max jitter: $RTCP_Called_Jitter_Max;ms; called packet loss: $RTCP_Called_LostPackets;%, max round trip delay: $RTCP_RTT_Max;ms" />
<resetrtpmeasurements />
<wait value="20s" />
<getrtpmeasurements />
<log value="measurement 2: caller-called RTP stream: sdp-rtp delay: $SDP_RTP_Caller_Delay;ms, packet loss: $RTP_Caller_LostPackets;%, max delta: $RTP_Caller_MaxDelta;ms, max rfc3550 jitter: $RTP_Caller_MaxRfc3550Jitter;ms, G.107 MOS: $RTP_Caller_G107MOS;" />
<log value="RTCP measurements 2: caller max jitter: $RTCP_Caller_Jitter_Max;ms; caller packet loss: $RTCP_Caller_LostPackets;%, called max jitter: $RTCP_Called_Jitter_Max;ms; called packet loss: $RTCP_Called_LostPackets;%, max round trip delay: $RTCP_RTT_Max;ms" />
resetstatistics
Resets global statistics of processed SIP calls; resets all
moving averages
Attributes:
[none]
<resetstatistics />
restartprocess
Restarts a windows process
Is used to monitor availability of SIP server and restart it if test calls fail
Attributes:
value (required) - full path to executable file
<log value="making call to the server. it should be configured to answer to 'test' number with no delay" />
<call value="sip:test@localhost:5060" maxringtime="5s" />
<on event="answer">
<log value="call answered. aborting call" />
<exit />
</on>
<on event="maxringtime;callfailure">
<log value="call failed (5-sec timeout or error response). restarting server if did not restart already 3 minutes ago" />
<block minInterval="3m">
<sendemail value="mailto:email@gmail.com?subject=call to server failed. restarting the server" />
<log value="restarting SIP server" />
<!-- here you should set path to your SIP server -->
<restartprocess value="C:\Users\User\AppData\Roaming\StarTrinity SipTester\StarTrinity.SIPTester.exe" />
</block>
<exit />
</on>
run
Generates a new CallXML session. Copies all variables from current session to the new session.
The "run" XML element should contain child XML elements to be executed by new session.
Attributes:
var (optional) - name of variable to store ID of new session
<block repeat="5">
<run var="newSessionId">
<call value="sip:$Id;@192.168.0.1" />
<on event="answer">
<playaudio value="music" />
</on>
</run>
<log value="generated new session, ID = $newSessionId;" />
</block>
<assign var="ParentSessionID" value="$id;"/>
<assign var="NumToCall" value="sip:152@192.168.0.56"/>
<run var="secondarySessionId" >
<call value="$NumToCall;" to="$NumToCall;" callerId="123" maxringtime="100s" />
<on event="answer" >
<sendevent value="answer" session="$parentSessionId;" />
<conference value="$Id;" />
</on>
<on event="callfailure">
<log value="call failed with status $lastError;" />
<sendevent value="callfailure" session="$parentSessionId;" />
</on>
</run>
<playaudio value="ringbacktone.wav" />
<on event="externalevent:answer" >
<accept />
<conference value="$eventsenderId;" />
</on>
<on event="externalevent:callfailure" >
<exit />
</on>
runfunction
Executes a function
Attributes:
name (requierd) - unique name of function
[parameters] (optional) - values of input parameters, names of variables to store output parameters
<function name="func1" param1="in" param2="in" resultvar="out" >
<log value="func1: param1 = $param1;, param2 = $param2;" />
<assign var="resultvar" value="$param1;: OK" />
</function>
<runfunction name="func1" param1="TestValue1" param2="TestValue2" resultvar="result" />
<log value="result=$result;" />
runprocess
Runs an .exe or .bat file with custom command line arguments. Saves console output and process exit code into variables. Is used for integration with third party tools
Attributes:
value (required) - path to executable file
args (optional) - command line arguments
exitcode (optional) - name of variable to store
exit code. Normal exit code is "0"
user (optional) - name of Windows user in case if you need to run .exe as different user
password (optional) - password of Windows user in case if you need to run .exe as different user
workingdirectory (optional) - working directory for .exe file
<runprocess value="C:\folder\something.exe" args="plink -ssh connectremote -l testuser" stdoutput="stdoutput" exitcode="exitcode" user="xxx" password="yyy" />
<log value="executed something.exe. stdoutput = '$stdoutput;', exitcode = '$exitcode;'" />
runtenantscript
For multitenant softswitch or PBX: runs custom tenant's script
Attributes:
none
<runtenantscript />
say
Speaks text using a
Microsoft Speech API 5 engine.
Waits until the engine speaks all the text. Text is set by "value" attribute or by child XML elements
You may need to install
SAPI5 SDK. Note: default TTS engine that comes with Windows Server 2008 may cause memory leak and crash.
Attributes:
value (optional) - text to be spought
voice (optional) - identifies TTS speaker
conference (optional) - ID of conference where to speak the text. If not set, test is spought only to current SIP call
nowait (optional, "true"/"false", default is "false") - if set to "true", control is returned immediately, before end of speaking text.
In this case text is still spought during execution of next CallXML elements
<say voice="Microsoft Anna" value="Welcome to the startrinity.com SIP server with text to speech functionality" />
<say>
<voice required="NAME=Microsoft Mike">you are calling from $callerId;</voice>
</say>
<say voice="Microsoft Mike" >
you are calling from $callerId; to $calledId;
</say>
searchfile
Search for random file in a directory
Attributes:
directory (required) - absolute or relative path to directory
var (required) - name of variable where to save file name
<searchfile directory="d:\recordings" var="fn" />
<playaudio value="$fn;" />
sendemail
Sends email using SMTP server, returns control immediately. Connection to SMTP server is configured on
settings screen
Note that subject and body text have to be
escaped
Attributes:
value (required) - "mailto" URI of destination
<sendemail value="mailto:user@server.com?subject=call from $callerId;&body=test body" />
<playdtmf value="1" />
<waitforsignal signaldelayvar="ivrDelay" maxringtime="3000"/>
<if test="$ivrDelay; >= 3000">
<sendemail value="mailto:user@server.com?subject=IVR timeout: $time();&body=Timeout in IVR1" />
</if>
<inputdigits value="c:\wav\ivr.wav" var="d" maxdigits="1" maxsilence="10s" />
<if test="$d; = 1" > <sendemail value="mailto:user@server.com?subject=call from $callerId;&body=user pressed 1" /> </if>
<if test="$d; = 2" > <sendemail value="mailto:user@server.com?subject=call from $callerId;&body=user pressed 2" /> </if>
sendevent
Sends external event to another (destination) session. Sets "eventsenderId" variable to the destination session.
The external event should be handled with <on event="externalevent:[subType]"> handler or "waitforevent" element.
Optionally sends variables into destination session. The CallXML variables are set using XML attributes within the "sendevent" element.
To send events between different instances of SIP Tester|see web API method "SendCallxmlEvent" and element "sendhttprequest"
Attributes:
value (optional) - eventID, ID/subtype of the external event. The event ID is accessible using CallXML script from variable "eventSubtype", or using "value" attribute
session (optional) - ID of the destination session. If not set, sends events to all current sessions
calledId (optional) - called ID of SIP call in destination session
callerId (optional) - caller ID of SIP call in destination session
<assign var="conferenceId" value="conf_$Id;" />
<sendevent session="$generatedSessionId;" value="join_to_conference" />
<readcsv repeat="infinite" value="C:\StarTrinity\2steptest.csv" var0="from" var1="to_name" var2="sbc_ip" var3="sbc_port" var4="password" var5="reffile" var6="xferext" var7="password2" />
<assign var="to" value="sip:$to_name;@$sbc_ip;:$sbc_port;?user=$from;&password=$password;" />
<log value="calling from $from; to $to;" />
<assign var="fromTag" value="$randdigits(10);" />
<assign var="callIdC" value="$randdigits(10);" />
<call value="$to;" callerId="$from;" headers="X-Attributes=*;test=A014" testId="A014" sipCallId="$callIdC;" fromTag="$fromTag;" />
<on event="answer">
<wait value="2s" />
<run var="newSessionId">
<call value="sip:$xferext;@$sbc_ip;:$sbc_port;" sipCallId="$callIdC;" />
<on event="answer">
<log value="received To header '$sipHeaderTo;'" />
<regexsearch value="$sipHeaderTo;" regex=";tag=(?<toTag>\S*)" var="toTag" />
<log value="received To header tag = '$toTag;'" />
<sendevent value="answer" session="$parentSessionId;" toTag="$toTag;" />
<playaudio value="music.wav" />
<exit/>
</on>
</run>
<wait value="30s" />
<exit/>
<on event="externalevent:c_answered" >
<log value="main callxml session: got 'c_answered' event from secondary session. toTag = '$toTag;' -->
<transfer value="<sip:$xferext;@$sbc_ip;:$sbc_port;;user=phone?Replaces=$callIdC;%3Bto-tag%3D$toTag;%3Bfrom-tag%3D$fromTag;>" mode="blind" dontwait="true" />
<wait value="11s" />
<exit />
</on>
</on>
sendfax
Initiates RE-INVITE with T.38 fax SDP offer, sends fax from TIFF image file
Does not return control untile fax operation is complete. If the fax operation fails, raises an "error" event, it could be handled in CallXML script.
Default installation contains a file "sample_fax.tiff" for tests
Attributes:
value (required) - subtype of the external event
<sendfax value="C:\fax\01.tiff" />
sendhttprequest
Sends HTTP/HTTPS request to a web server
Is used to integrate with third-party APIs (HLR lookups, etc),
exchange data and signals between SIP Tester instances.
Note: you can analyse the API response using
regexsearch
Attributes:
value (required) - HTTP URL where to send the request
maxtime (optional) - HTTP request timeout. example:
1000ms
contentvar (optional) - name of variable where to store downloaded HTTP message body
delayvar (optional) - name of variable where to store measured delay of HTTP response (in milliseconds)
statusvar (optional) - name of variable where to store HTTP response status code
user (optional) - user name for authentication
password (optional) - password for authentication
headers (optional) - list of custom HTTP headers to be included into the HTTP request. Example: Header1Name=Header1Value|Header2Name=Header2Value|Header3Name=Header3Value
tlsversion (optional) - TLS version: "1.0", "1.1" or "1.2". Note: may require restart of the software in some cases
method (optional, "GET"/"POST", default is "GET") - HTTP method to use.
If using "POST", the software sends inner content of the "sendhttprequest" XML elements to the web server (see examples). Inner "CDATA" element can be used to send HTTP POST with JSON data.
<sendhttprequest value="http://google.com" contentvar="c" delayvar="d" statusvar="s" />
<log value="HTTP test result: delay=$d;ms, HTTP status code = $s;, content: $c;" />
<sendhttprequest value="https://yourserver.com/savetestresult.aspx?token=$token;" method="POST" contentvar="c" delayvar="d" statusvar="s">
<result>
<callxmlSessionId value="$id;" />
<status value="$status;" />
</result>
</sendhttprequest>
<log value="HTTP POST delay=$d;ms, HTTP status code = $s;, returned content: $c;" />
<sendhttprequest method="POST" value="https://api.hlrlookup.com/apiv2/hlr" contentvar="c" delayvar="d" statusvar="s">
<![CDATA[{
"api_key":"xxxx",
"api_secret":"yyyy",
"requests":
[
{"telephone_number": "$callerId;",
"cache_days_private":0,
"get_landline_status":"NO",
"get_imsi_hash":"NO"
}
]
}
]]>
</sendhttprequest>
<log value="API request delay=$d;ms, HTTP status code = $s;, returned $c; " />
<log value="sending request to another instance of SIP Tester to check if call exists there from 'test' to 'test'" />
<sendhttprequest value="http://10.10.10.10:19019/API/MainViewModel/CurrentCallExists?callerId=test&calledId=test" user="admin" password="123456" contentvar="r" />
<log value="result: $r;" />
<log value="sending request to another instance of SIP Tester to create 2 synchronous calls. the another instance will send a HTTP request to your web server to get script for the second call" />
<sendhttprequest value="http://siptester-instance-2:19019/API/MainViewModel/CreateCall?url=http://your-web0server/script.xml&user=admin01&password=passw01" user="admin" password="123456" />
<log value="sent request to the second instance. now making a call from this (first) instance" />
<call value="sip:test@192.168.10.56" callerId="test">
<on event="answer">
<playaudio value="music.wav" maxtime="20s" />
<exit />
</on>
</call>
<sendhttprequest value="http://startrinity.com" headers="Authorization=Bearer 1234567890" />
sendsipinfo
Sends SIP INFO with custom body content to current call or to other calls in conference
Attributes:
value (required) - SIP INFO message body content
contentType (optional, default is "application/dtmf-relay") - Content-Type SIP header value
<sendsipinfo value="Signal=1" />
<sendsipinfo value="the text" contentType="text/plain" />
sendsipmessage
Sends a custom SIP message. The message is set by content of XML element
Uses a common SIP parsing procedure which is used to parse normal SIP messages received from IP network.
If the message is recognized as SIP request, the "sendsipmessage" exits after receiving response.
If the message is recognized as SIP response, the "sendsipmessage" exits immediately after sending.
See also: sendsiprequest getsiptrace
Attributes:
maxtime (optional) - for SIP requests: timeout to wait for response (see example)
var (optional) - for SIP requests: variable where to save response status code (see example)
localSipPort (optional) - explicitly set local SIP/UDP transport port. Is used with global settings "LocalSipPort", "LocalSipPortRange"
localSipAddress (optional) - explicitly set local SIP IP address, is used to select network interface. Is used with global setting "LocalSipAddresses"
transport (optional) - explicitly set SIP transport: "udp", "tcp" or "tls", default is "udp"
delayvar (optional) - for SIP requests: variable where to save the response delay in milliseconds (see example)
serverheadervar (optional) - for SIP requests: variable where to save "Server" header from the response
<sendsipmessage>
<![CDATA[SIP/2.0 180 Ringing
Via: $sipHeaderVia;
Call-ID: $sipCallId;
From: $sipHeaderFrom;
To: $sipHeaderTo; ;tag=b6a1c0b8e8334ef4b89f6a4d6154bbe1
CSeq: $sipHeaderCSeq;
Contact: <sip:192.168.0.13:5070>
Allow: INFO, PRACK, SUBSCRIBE, NOTIFY, REFER, INVITE, ACK, BYE, CANCEL, UPDATE
Server: StarTrinity.SIP 2014-04-28 20:20 UTC
Content-Type: application/sdp
Content-Length: 252
v=0
o=- 3607723560 3607723560 IN IP4 192.168.0.66
s=i14.proxy.stream0
t=0 0
m=audio 6666 RTP/AVP 8 101
c=IN IP4 192.168.0.66
a=rtcp:6667 IN IP4 192.168.0.66
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
]]>
</sendsipmessage>
<wait value="3s" />
<sendsipmessage>
<![CDATA[SIP/2.0 200 OK
Via: $sipHeaderVia;
Call-ID: $sipCallId;
From: $sipHeaderFrom;
To: $sipHeaderTo; ;tag=b6a1c0b8e8334ef4b89f6a4d6154bbe1
CSeq: $sipHeaderCSeq;
Contact: <sip:192.168.0.13:5070>
Allow: INFO, PRACK, SUBSCRIBE, NOTIFY, REFER, INVITE, ACK, BYE, CANCEL, UPDATE
Server: StarTrinity.SIP 2014-04-28 20:20 UTC
Content-Type: application/sdp
Content-Length: 252
v=0
o=- 3607723560 3607723560 IN IP4 192.168.0.77
s=i14.proxy.stream0
t=0 0
m=audio 7777 RTP/AVP 8 101
c=IN IP4 192.168.0.77
a=rtcp:7778 IN IP4 192.168.0.77
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
]]>
</sendsipmessage>
<wait value="100s" />
<exit/>
<sendsipmessage>
<![CDATA[INVITE sip:88@localhost SIP/2.0
Max-Forwards: 69
Session-Expires: 3600;refresher=uac
Min-SE: 600
Supported: timer, 100rel
To: 888963217843506 <sip:888963217843506@80.239.172.171;user=phone>
From: <sip:905348591511@80.239.172.144>;tag=3621105032-66026
Remote-Party-Id: <sip:905348591511@80.239.172.144:5061;user=phone>;privacy=off;screen=yes
Call-ID: 5115009-3621105032-66020@msc1.voipdomain.com
CSeq: 1 INVITE
Allow: INVITE, BYE, OPTIONS, CANCEL, ACK, REGISTER, NOTIFY, INFO, REFER, SUBSCRIBE, PRACK, UPDATE, MESSAGE, PUBLISH
Via: SIP/2.0/UDP 80.239.172.144:5060;branch=z9hG4bK6e470d385b78ed88288a3488169f3448
Contact: <sip:905348591511@80.239.172.144:5060>
Call-Info: <sip:80.239.172.144>;method="NOTIFY;Event=telephone-event;Duration=1000"
Content-Type: application/sdp
Content-Length: 419
v=0
o=msc1 1412116227 1412116227 IN IP4 80.239.172.144
s=sip call
c=IN IP4 80.239.172.145
t=0 0
m=audio 31358 RTP/AVP 18 96 4 97 98 0 8
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:96 G729/8000
a=fmtp:96 annexb=yes
a=rtpmap:4 G723/8000
a=fmtp:4 annexa=yes
a=rtpmap:97 G729/8000
a=fmtp:97 annexb=no
a=rtpmap:98 G729/8000
a=fmtp:98 annexb=yes
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=sendrecv
]]>
</sendsipmessage>
<sendsipmessage>
<![CDATA[OPTIONS sip:test@192.168.10.6 SIP/2.0
Via: SIP/2.0/UDP 192.168.10.6
Max-Forwards: 70
To: <sip:test@192.168.10.6>
From: Alice <sip:test@192.168.10.5>;tag=test$id;
Call-ID: test$id;
CSeq: $id; OPTIONS
Contact: <sip:test@192.168.10.5>
Accept: application/sdp
Content-Length: 0
]]>
</sendsipmessage>
<log value="sending OPTIONS (SIP ping) to check availability of server. waiting for response during 3 seconds"/>
<sendsipmessage maxtime="3s" delayvar="delay" var="status">
<![CDATA[OPTIONS sip:test@192.168.10.6 SIP/2.0
Via: SIP/2.0/UDP 192.168.10.6
Max-Forwards: 70
To: <sip:test@192.168.10.6>
From: Alice <sip:test@192.168.10.5>;tag=test$id;
Call-ID: test$id;
CSeq: $id; OPTIONS
Contact: <sip:test@192.168.10.5>
Accept: application/sdp
Content-Length: 0
]]>
</sendsipmessage>
<if test="$status; = 200" > <log value="server is available. response delay is $delay;ms" /> </if>
<else> <log value="server is unavailable. status: $status;" /> </else>
<callxml>
<assign enabled="false" var="d4" mathvalue="$id; % 256" />
<assign enabled="false" var="ip" value="5.135.179.$d4;" />
<assign enabled="true" var="d1" mathvalue="$rand(1,255);" />
<if test="$d1; = 127" > <exit/> </if>
<assign enabled="true" var="ip" value="$d1;.$rand(1,255);.$rand(1,255);.$rand(1,255);" />
<assign var="port" value="5060" />
<sendsipmessage maxtime="2s" var="status">
<![CDATA[OPTIONS sip:test@$ip;:$port; SIP/2.0
Via: SIP/2.0/UDP 163.172.210.13:6000
Max-Forwards: 70
To: <sip:test@$ip;>
From: StarTrinity <sip:test@163.172.210.13>;tag=test$id;
Call-ID: $randdigits(10);
CSeq: $randdigits(4); OPTIONS
Contact: <sip:test@163.172.210.13:6000>
Accept: application/sdp
Content-Length: 0
]]>
</sendsipmessage>
<if test="$status; = 200" > <log value="server $ip;:$port; is available" /> </if>
<else> <log enabled="false" value="server $ip;:$port; is unavailable. status: $status;" /> </else>
</callxml>
<assign enabled="true" var="d1" mathvalue="$rand(1,255);" />
<if test="$d1; = 127"> <exit /> </if>
<assign enabled="true" var="ip" value="$d1;.$rand(0,255);.$rand(0,255);.$rand(0,255);" />
<assign var="port" value="5060" />
<sendsipmessage maxtime="2s" var="status" serverheadervar="srv">
<![CDATA[OPTIONS sip:test@$ip;:$port; SIP/2.0
Via: SIP/2.0/UDP 163.172.210.13:6000
Max-Forwards: 70
To: <sip:test@$ip;>
From: StarTrinity <sip:test@163.172.210.13>;tag=test$id;
Call-ID: $randdigits(10);
CSeq: $randdigits(4); OPTIONS
Contact: <sip:test@163.172.210.13:6000>
Accept: application/sdp
User-Agent: StarTrinityFriendlyScanner
Content-Length: 0
]]>
</sendsipmessage>
<if test="$status; = 200">
<log value="server $ip;:$port; responded to OPTIONS. server: $srv;" />
<sendsipmessage maxtime="2s" var="status" serverheadervar="srv">
<![CDATA[INVITE sip:100@$ip;:$port; SIP/2.0
Via: SIP/2.0/UDP 163.172.210.13:6000
Max-Forwards: 70
To: <sip:100@$ip;>
From: sip:101@163.172.210.13;tag=test$id;
Call-ID: $randdigits(10);
CSeq: $randdigits(4); INVITE
Contact: <sip:test@163.172.210.13:6000>
User-Agent: StarTrinityFriendlyScanner
Accept: application/sdp
Content-Length: 0
]]>
</sendsipmessage>
<log value="server $ip;:$port; responded to INVITE: server: $srv;" />
</if>
<else> <log enabled="false" value="server $ip;:$port; is unavailable. status: $status;" /> </else>
<exit />
sendsiprequest
Sends custom SIP request for current SIP call, within current INVITE dialog. The request is set by content of XML element.
Returns control immediately. Headers like Call-ID and request URI are overwritten, content-length is calculated automatically
Uses a common SIP parsing procedure which is used to parse normal SIP messages received from IP network
See also: sendsipmessage getsiptrace
Attributes:
none
<call callerId="" value="sip:100@localhost"/>
<on event="pr">
<sendsiprequest>
<![CDATA[
NOTIFY sip:xx.yy.zz SIP/2.0
User-Agent: XYZ
Event: message-summary
Content-Type: application/simple-message-summary
Messages-Waiting: no
Message-Account: sip:*97@10.10.10.10
Voice-Message: 0/0 (0/0)
]]>
</sendsiprequest >
</on>
<on event="answer">
<playaudio value="music" repeat="10000" maxtime="10000ms" />
<exit />
</on>
<call value="sip:123456@myserver.com:5060" callerId="19056089570" maxringtime="20s" codec="G711A">
<on event="answer">
<wait value="3s" />
<sendsiprequest><![CDATA[INFO sip:11@1.2.3.4 SIP/2.0
User-Agent: StarTrinity
Content-Type: application/dtmf-relay
Content-Length: 10
Signal=10
Duration=150
]]></sendsiprequest >
<wait value="3s" />
<exit/>
</on>
</call>
sendspoofedudppacket
Sends generic UDP packet with spoofed source IP address
The element allows VoIP hacking, it is a part of
SIP security testing suite
Attributes:
sourceIp - source/fake IP address
destinationIp - destination IP address
sourcePort - sourceUDP port
destinationPort - destination UDP port
<sendspoofedudppacket sourceIp="1.2.3.4" sourcePort="1234" destinationIp="5.6.7.8" destinationPort="5678">
<![CDATA[
TEST PACKET WITH SPOOFED (FAKE) SOURCE IP ADDRESS!!!
NOT TO BE USED BY HACKERS!!!
FOR PENETRATION SIP TESTS ONLY!!!!!
]]>
</sendspoofedudppacket>
sendudppackets
Sends generic UDP packets via current SIP/UDP socket
The element allows VoIP hacking, it is a part of
SIP security testing suite
Attributes:
repeat - number of times to repeat the packet
destinationIp - destination IP address
destinationPort - destination UDP port
<sendudppackets destinationIp="5.6.7.8" destinationPort="5678" repeat="100">
<![CDATA[TEST PACKET
some data]]>
</sendudppackets>
<sendudppackets destinationIp="$rand(1,255);.$rand(1,255);.$rand(1,255);.$rand(1,255);" destinationPort="5060">
<![CDATA[INVITE sip:100@localhost:5060 SIP/2.0
Via: SIP/2.0/UDP 195.154.173.208:6000;rport;branch=z9hG4$randdigits(10);
Route: <sip:195.154.173.208:6000;lr>
Record-Route: <sip:195.154.173.208:6000;lr>
Max-Forwards: 70
To: <sip:100@localhost>
From: <sip:101@195.154.173.208>;tag=$randdigits(10);
Call-ID: $randdigits(10);
CSeq: 5664 INVITE
Contact: <sip:101@195.154.173.208:6000>
User-Agent: StarTrinityFriendlyScanner
Accept: application/sdp
Content-Type: application/sdp
Content-Length: 419
v=0
o=msc1 1412116227 1412116227 IN IP4 195.154.173.208
s=sip call
c=IN IP4 195.154.173.208
t=0 0
m=audio 6000 RTP/AVP 18 96 4 97 98 0 8
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:96 G729/8000
a=fmtp:96 annexb=yes
a=rtpmap:4 G723/8000
a=fmtp:4 annexa=yes
a=rtpmap:97 G729/8000
a=fmtp:97 annexb=no
a=rtpmap:98 G729/8000
a=fmtp:98 annexb=yes
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=sendrecv
]]>
</sendudppackets>
setcallgeneratorparams
Changes call generation parameters
The call generator starts new CallXML session on time (clock) every N milliseconds, with fixed or random intervals.
The interval between calls is set by "maxcps", "maxcpsL", "maxcpsH", "callspertick" parameters,
maximum number of concurrent calls is set by "maxconcurrentcalls", "maxoutgoingconcurrentcalls".
If number of concurrent calls exceeds "maxconcurrentcalls", the call generator is temporary stopped, so number of calls per second will be limited also
Attributes:
maxcps (optional) - max calls per second (fixed interval betweeen calls)
maxcpsL (optional) - max calls per second, lower bound (random interval betweeen calls, linear probability distribution)
maxcpsH (optional) - max calls per second, higher bound (random interval betweeen calls, linear probability distribution)
maxconcurrentcalls (optional) - max concurrent calls (incoming + outgoing)
maxoutgoingconcurrentcalls (optional) - max concurrent calls (outgoing only)
callspertick (optional) - number of calls to create at a time (number of calls in a burst)
maxcallstoattempt (optional) - max. total number of calls to attempt
writeSettingsFileToDisk (optional, "true" or "false", default is "false") - specifies whether you need to save the call generator parameters to settings file. Note: setting this to "true" may cause too many disk writing operations
<setcallgeneratorparams maxcps="3" maxconcurrentcalls="10" />
<assign var="numberOfConcurrentCalls" mathvalue="120 + 100 * sin(($timeOfDayInHours(); - 10) / 24 * 360)" />
<setcallgeneratorparams maxconcurrentcalls="$numberOfConcurrentCalls;" />
<if test="$timeOfDayInHours(); > 10 & $timeOfDayInHours(); < 11">
<setcallgeneratorparams maxconcurrentcalls="30" />
</if>
<if test="$timeOfDayInHours(); > 11 & $timeOfDayInHours(); < 13">
<setcallgeneratorparams maxconcurrentcalls="50" />
</if>
<if test="$timeOfDayInHours(); > 13 & $timeOfDayInHours(); < 17">
<setcallgeneratorparams maxconcurrentcalls="10" />
</if>
<call maxringtime="$rand(45500);ms" value="$seq_sip_uri_from_csv(C:\StarTrinity\CSV Files\Mali Aug 26 Dialer Ready 4x 2xAST.csv);" codec="G729" />
<on event="answer">
<inputdigits var="d" maxsilence="5s" />
<if test="$d; != 7" > <exit /> </if>
<playaudio value="$randfile(C:\StarTrinity\Wav Files\*.wav);" repeat="infinite" maxtime="$rand(500000);ms" />
<exit />
</on>
setexitcode
Sets exit code for SIP Tester process. Is used to pass result from CallXML script into .bat script via using command line interface
See also: "exitcli"
Attributes:
value (required) - exit code
<setexitcode value="-1" />
setimpairmentparams
Configures simulated RTP loss, jitter and SIP packet loss parameters
See
impairments generation in SIP Tester
Attributes:
sipPacketLossProbability (optional) - simulated SIP packets loss probability
rtpPacketLossGapProbability (optional) - simulated RTP packet loss gap probability
rtpPacketLossMaxLostPacketsInGap (optional) - max. number of RTP packets in the simulated RTP packet loss gap
rtpJitterDelayProbability (optional) - probability of simulated delay in RTP thread, to generate RTP jitter
rtpJitterAverageDelay (optional) - average delay of simulated delay in RTP thread
<setimpairmentparams sipPacketLossProbability="0.01" rtpPacketLossGapProbability="0.005" rtpPacketLossMaxLostPacketsInGap="10" rtpJitterDelayProbability="0.005" rtpJitterAverageDelay="50ms" >
setinterval
Executes internal CallXML code at specified intervals, when current SIP calls is still alive
Is similar to "setInterval" in JavaScript. The internal CallXML code is executed in a separate thread. See also: "settimeout"
Attributes:
value (required) - interval between the executions of the internal CallXML code
<setinterval value="1s">
<log value="do something every 1 second during the call. e.g. request database and destroy the call if needed" />
</setinterval>
<call value="sip:test@10.10.10.10" />
<on event="answer">
<playaudio value="music.wav" repeat="infinite" />
</on>
setrtpextension
Sets or removes RTP extension data for transmitted RTP stream
Attributes:
hexData (optional) - generic RTP extension data in hexademical text format. Example: '01C04FFA'
extensionId (required if 'hexData' is set) - identifier of RTP extension data format, defined by audio/video profile
wg67_pttType (optional) - PTT-type field, defined in
INTEROPERABILITY STANDARDS FOR VOIP ATM COMPONENTS VOLUME 1: RADIO.
If
wg67_pttType is set to
"rxptt", it gets PTT-type from received RTP stream, in other words it creates PTT-type RX-TX loopback connection.
This loopback connection is used to measure round-trip RTP audio delay for ED-137 performance testing of air traffic management (ATM) VoIP networks.
wg67_pttId (optional) - PTT-ID
wg67_squ (optional, 1 or 0, default is 0) - SQU flag. If
wg67_squ is set to
"rxptt", it creates loopback connection from PTT-Type field of received RTP stream:
If RX-PTT-ID is 0 then TX-SQU is 0, otherwise TX-SQU is 1
wg67_pm (optional, 1 or 0, default is 0) - PM flag
wg67_ptts (optional, 1 or 0, default is 0) - PTTS flag
wg67_sct (optional, 1 or 0, default is 0) - SCT flag
<call value="sip:line@192.168.3.3:5062" callerId="line"></call>
<on event="answer">
<setrtpextension wg67_pttType="3" wg67_pttId="16" wg67_squ="1" wg67_pm="0" wg67_ptts="0" wg67_sct="1" />
<playaudio value="music.wav" maxtime="3s" />
<setrtpextension wg67_pttType="0" wg67_pttId="16" wg67_squ="1" wg67_pm="0" wg67_ptts="0" wg67_sct="1" />
<playaudio value="music.wav" maxtime="3s" />
<setrtpextension wg67_pttType="0" wg67_pttId="16" wg67_squ="1" wg67_pm="0" wg67_ptts="0" wg67_sct="0" />
<playaudio value="music.wav" maxtime="3s" />
<setrtpextension wg67_pttType="0" wg67_pttId="16" wg67_squ="0" wg67_pm="0" wg67_ptts="0" wg67_sct="0" />
<playaudio value="music.wav" maxtime="3s" />
<setrtpextension />
<playaudio value="music.wav" maxtime="3s" />
<exit />
</on>
<call value="sip:test@192.168.3.3:5062" callerId="test"></call>
<on event="answer">
<setrtpextension extensionId="359" hexData="01C00000" />
<playaudio value="music.wav" maxtime="3s" />
<exit />
</on>
<accept />
<setrtpextension wg67_pttType="rxptt" wg67_pttId="7" wg67_squ="0" wg67_pm="0" wg67_ptts="0" wg67_sct="0" />
<playaudio value="music2" repeat="infinite" maxtime="60000ms" />
<exit />
setrtpmalformer
Configures RTP malformer
setrtptxfields
Modifies transmitted RTP stream, fields SSRC, timestamp, sequence
Attributes:
ssrc (optional) - SSRC field, in decimal format
ts (optional) - timestamp field, in decimal format
seq (optional) - sequence field, in decimal format
<setrtptxfields ssrc="1234" />
setsetting
Sets a global setting value
The settings are described in the UI on the '
settings' screen.
Attributes:
name (required) - name of setting
value (required) - value of setting
<setsetting name="SaveSipAndRtpPacketsToDisk" value="1" />
settimeout
Executes internal CallXML code after specified timeout
Is similar to "setTimeout" in JavaScript. The internal CallXML code is executed in a separate thread. See also: "setinterval"
Attributes:
value (required) - time to delay the execution of the internal CallXML code
<assign var="receivedReinvite" value="false" />
<call maxringtime="10s" value="sip:test@localhost:5060">
<on event="answer">
<settimeout value="60s">
<log value="60 seconds passed: checking if received re-invite" />
<if test="$receivedReinvite; = false" > <log value="aborting call" /> <disconnect /> </if>
<else> <log value="received re-invite: continue the call" /> </else>
</settimeout>
<playaudio value="music.wav" repeat="infinite" /> <exit />
</on>
<on event="reinvite"> <log value="received re-invite" /> <assign var="receivedReinvite" value="true" /> </on>
</call>
setuaccredentials
Sets user name and password to handle 401 and 407 UAS responses. Is used for incoming calls, to authorize further BYE and RE-INVITE requests from SIP Tester to server
Attributes:
user (required) - user name
password (required) - password
setwebapiresult
Passes key-value result to web API "CreateCall_Post"
Attributes:
key (optional) - key
value (required) - value
srand
Initializes the CallXML engine's random generator with the specified seed value
Is used to reproduce random tests
Attributes:
value (required) - the seed value, integer
startcallgenerator
Starts generation of outgoing calls
Attributes:
[none]
<startcallgenerator />
stopaudio
Stops audio player which was started previously
Attributes:
[none]
<stopaudio />
stopcallgenerator
Stops generation of outgoing calls
Attributes:
[none]
<stopcallgenerator />
substring
Retrieves a substring from a specified value, saves result to a variable
Attributes:
value (required) - input string
startIndex (optional) - zero-based starting character position of a substring
length (optional) - number of characters in the substring
trimStartChars (optional) - characters to remove at beginning of the string
trimEndChars (optional) - characters to remove at end of the string
trimEndLength (optional) - number of characters to remove at end of the string
<substring var="result1" value="01234567890" startIndex="0" length="2" />
<log value="result1=$result1;" />
<substring var="result2" value="01234567890" startIndex="6" />
<log value="result2=$result2;" />
<substring var="result3" value="startrinity CallXML" startIndex="12" length="4" />
<log value="result3=$result3;" />
<substring var="result4" value="01234567890" trimStartChars="0" trimEndChars="0" />
<log value="result4=$result4;" />
<substring var="result5" value="01234567890" trimEndLength="3" />
<log value="result5=$result5;" />
<if test="$callerId; startswith +"> <substring var="callerId" value="$callerId;" startIndex="1" /> </if>
<getstringlength var="calledIdLength" value="$calledId;" />
<block repeat="$calledIdLength;" var="i">
<substring value="$calledId;" startIndex="$i;" length="1" var="digit" />
<log value="extracted called ID digit #$i;: $digit;" />
<playaudio value="C:\startrinity_siptester_latest\Wav\digit;.wav"/>
</block>
switch
Checks if a value matches to one of many conditions, executes an action accordingly
The conditions are defined by inner "case" XML elements. If no "case" element is found, "default" element is executed.
If "probability" attributes are defined for the conditions, a random "case" is selected.
"case" XML element may be empty. See also: "case", "default"
Attributes:
value (optional) - input value for checking
<switch value="$callerId;">
<case equals="111"> <log value="call is from 111" /> </case>
<case equals="222"> <log value="call is from 222" /> </case>
<case startsWith="2"> <log value="call is from 2xxx" /> </case>
<default> <log value="caller ID is not recognized" /> </default>
</switch>
<switch>
<case probability="10">
<log value="this has probability of 10%" />
</case>
<case probability="30">
<log value="this has probability of 30%" />
</case>
<case probability="60">
<log value="this has probability of 60%" />
</case>
</switch>
<switch value="$timeOfDayInHours();">
<case from="0" to="12"> <setcallgeneratorparams callspertick="1" maxcpsL="0.1" maxcpsH="0.22" /> </case>
<case from="13" to="24"> <setcallgeneratorparams callspertick="3" maxcpsL="0.2" maxcpsH="0.32" /> </case>
</switch>
throw
Raises an event
Attributes:
value (required) - type and (optionally) subtype of event, separated by ":"
<inputdigits value="enter_digit.wav" var="entered_digit" maxsilence="20s" maxdigits="1" />
<throw value="digit:$entered_digit;" />
<on event="digit:1">
<playaudio value="1" />
</on>
<on event="digit:2">
<playaudio value="2" />
</on>
transfer
Redirects call to another SIP URI. Is used to proxy call at server side or to send REFER
Raises "pr", "audioSignal", "maxringtime", "maxansweredtime", "callfailure" and "answer" events
Attributes:
value (required if 'terminators' attribute is not set) - specifies
SIP URI of destination.
SIP URI can contain user and password for authentication, and "transport" query parameter ("udp" or "tcp", "udp" is default).
The SIP URI may contain following query parameters:
- "transport" - "udp" or "tcp", "udp" is default
- "user", "password" - credentials for authentication
- "proxyAddress", "proxyPort" - address of proxy server
- "localSipPort" - local SIP UDP port to use for the call
- "callerId" - user ID in 'From' header
If value equals to "$ext(100);" - call is forwarded to a registered extension (UAS registration) with SIP ID = "100".
In softswitch mode the "value" overwrites destination (B) number.
terminators (required if 'value' attribute is not set) - identifiers of terminators, separated by semicolons, used for Softswitch scripts. Terminators are configured via web interface. If 'terminators' is set to 'all', all available terminators are used; if set to 'routed' - the terminators are taken from settings of originator and routing group. If attribute 'dontProxyCallfailure' is set, CallXML flow goes to next element after "transfer" in case of call failure or unavailable terminators.
gatewayId (optional) - identifies GSM gateway ID (when using the softswich with GoIP SIM management features), to select it explicitly in CallXML script
channelId (optional) - identifies GSM gateway channel ID (when using the softswich with GoIP SIM management features), to select it explicitly in CallXML script
mode (optional, default is "bridged") - list of call transfer modes, separated by semicolon. If "terminators" attribute is set, default mode is taken from the terminator.
- "blind" - if mode is "blind", sends REFER to the caller. In this mode "value" atribute goes into "Refer-To" SIP header
- "bridged" - if "mode" is "bridged",
makes another SIP call (call B) and connects RTP streams between current call (call A) and call B.
If call A is not answered yet, sends answer response to call A when call B is answered.
Optionally plays ringback tone from WAV or MP3 file.
Proxies provisional responses (180, 183) from call B to call A.
Returns control on time out or after completion of call B.
Automatically converts codecs (e.g. performs G.729-G.711 transcoding).
Raises "callfailure" and "maxringtime" events. Automatically redirects call B to new destination if receives "302 Moved Temporarily" response.
If "callfailure" event is not handled, rejects call A automatically
- "proxydtmf" - pass DTMF messages between call A and call B
- "disablehold" - disable call hold and 3-way conferencing
- "suppressAnswerBeforeRbt" - suppress FAS, start billing only if there was ringback tone before answer.
If the answer from terminator is received before ringback tone (450 Hz), it waits for the ringback tone and generates answer 5 seconds after last tone.
Stops fake ringbacktone, if it was started before the "transfer" element in the script
- "recognizeAnswerFromRtpB" - ignore answer signal from terminator, recognize it from RTP audio from call leg B - first sound after ringback tone
- "recognizeAnswerFromRtpA" - ignore answer signal from terminator, recognize it from RTP audio from call leg A - first sound above specified level (in decibels, "level" attribute, default is "-20")
For "bridged" mode only:
ringbacktone (optional) - absolute or relative path to ringback tone audio file which will be played to call A
ringbacktoneMaxtime (optional) - max time for ringback tone audio file playback. After the ringbacktoneMaxtime call leg A starts to receive early media from call leg B
to (optional) - "To" header for SIP INVITE message. If "to" is not set, it is taken from "value" SIP URI
callerId (optional, default is "unknown") - SIP ID for "From" header in INVITE message
callId (optional) - Call-ID header for call leg B
sendSdpInInitialInvite (optional, "true" or "false", default is "true") - specifies whether to send SDP in SIP INVITE message. If no SDP is sent in request, and if destination also does not send SDP in response, the SIP call will be established without RTP media.
direction (optional, "SendOnly"/"ReceiveOnly"/"None"/"Both", default is "Both") - RTP media direction to be declared in SDP
maxringtime (optional, default is "no timeout") - timeout of waiting for call answer in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix).
If "maxringtime" expires, call is leg B aborted with CANCEL SIP message and "maxringtime" event is generated
_18xTimeout (optional, default is "no timeout") - timeout of waiting for 180 or 183 response in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix).
If "_18xTimeout" expires, call leg B is aborted with CANCEL SIP message
maxansweredtime (optional, default is "no timeout") - max call duration after answering in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix).
If "maxansweredtime" expires, call leg B is aborted and "maxansweredtime" event is raised. If no event handler for "maxansweredtime" exists, the call leg A is aborted with BYE SIP message
headers (optional) - list of custom SIP headers to be included into the INVITE message.
Example: Header1Name=Header1Value|Header2Name=Header2Value|Header3Name=Header3Value
sdpAttributes (optional) - list of custom SDP attributes to be included into the INVITE message.
Example: Attr1Name:Attr1Value|Attr2Name:Attr2Value|Attr3Name:Attr3Value
codec (optional, "G711A"/"G711U"/"G723"/"G729", default is "any of supported") - RTP media codec (SDP media stream payload type) to be used for the SIP call.
rtpProxyMode (optional, "transcoding"/"open RTP"/"fast RTP proxy", default is "transcoding") - specifies the way how the softswitch connects RTP media of A and B call legs. The mode can be selected individually for every call
disconnectOnSilenceLevel (optional, default is "none") - if specified, disconnects the call if both A and B call legs are silent for a long time
disconnectOnSilenceTimeout (optional, default is "30s") - if "disconnectOnSilenceLevel" attribute is set: minimal silent time before disconnecting the call
simulateFasAfterConnection (optional, "true" or "false", default is "false") - is used in combination with element "wait" after "transfer". When the attribute is set, the "transfer" continues to next CallXML element after successful call. In this way you can simulate FAS / extra billing after connection. The attribute must be used for testing purposes only, not for live traffic to generate fraud.
proxyPR (optional, "true" or "false", default is "true") - enables unconditional proxying of 180 and 183 provisional responses from call leg B to call leg A
proxyRingbacktone (optional, "true" or "false", default is "true") - if set to "false", disables sending ringback tone from call leg B to call leg A, when playing a custom ringback tone
dontProxyRtpMedia (optional, "true" or "false", default is "false") - enables passing RTP directly from originator directly to terminator, without the softswitch (third party call control)
dontProxyCallfailure (optional, "true" or "false") - enables proxying call failure packet (4xx, 3xx, 6xx) from destination call leg to source call leg. Is set to false when additional processing is needed after call failure
localRtpPort (optional) - explicitly set local RTP UDP port number. If empty or zero, a socket from RTP transport pool is used (see settings "MediaTransportPoolMinPort", "MediaTransportPoolMaxSocketsCountPerInterface")
localRtpAddress (optional) - explicitly set local RTP IP address, is used to select network interface. If empty, the network interface is selected by remote IP address using system routing table (WinAPI function GetBestInterface())
localSipPort (optional) - explicitly set local SIP/UDP transport port. Is used with global settings "LocalSipPort", "LocalSipPortRange"
localSipAddress (optional) - explicitly set local SIP IP address, is used to select network interface. Is used with global setting "LocalSipAddresses"
antiFasConnectionDelay (optional) - technique against short-duration FAS calls. Time to delay 200 OK (connection signal) from leg B to leg A. Example: 2000ms
antiFasRingingTimePeriodsMs (optional) - time periods of ringing duration to turn on the anti-FAS technique. Example: 9500-10500,30000-60000
For "blind" mode only:
dontwait (optional, "true" or "false", default is "false") - turns off waiting for completion of REFER procedure. If set to "true", goes to next element in script immediately
referredBy (optional) - Referred-By header for the transmitted REFER request packet
<transfer value="sip:152@192.168.0.56" mode="bridged" ringbacktone="wait_for_answer.wav"
maxansweredtime="20m" maxringtime="40s" >
<on event="callfailure:486">
<playaudio value="busy.wav" />
</on>
<on event="callfailure">
<playaudio value="call_error.wav" />
</on>
<on event="maxringtime">
<playaudio value="call_does_not_answer_on_timeout.wav" />
</on>
<on event="maxansweredtime">
<playaudio value="speaking_timeout_call_again.wav" />
</on>
</transfer>
<playaudio value="thank_you_for_call.wav" />
<exit />
<assign var="transferPrefix" value="+1" />
<transfer value="sip:$transferPrefix;$calledId;@x.x.x.x:5060" callerId="$callerId;" mode="bridged" maxringtime="50s" codec="G729" />
<on event="callfailure">
<log value="call 'B' failed, status = $eventSubType;. rejecting call leg 'A' with same status code" />
<reject value="$eventSubType;" />
<exit />
</on>
<on event="maxringtime">
<playaudio value="call_does_not_answer_on_timeout.wav" />
<reject value="503" />
</on>
<accept value="183" />
<playaudio value="rbt$randswitch(1,2,3,4,5);.wav" repeat="100" dontwait="true" />
<transfer value="$rand_from_options;" callerId="$callerId;" mode="bridged;proxydtmf;suppressAnswerBeforeRbt" maxringtime="70s">
<option value="sip:$calledId;@51.254.245.55" maxCallsPerDestinationResource="5" destinationResourceId="server1" />
<option value="sip:$calledId;@51.254.245.43" maxCallsPerDestinationResource="5" destinationResourceId="server2" />
<on event="callfailure"> <reject value="$eventSubType;" /> </on>
</transfer>
<transfer value="$ext(100);" >
<on event="callfailure"> <reject value="$eventSubType;" /> </on>
</transfer>
<performAAA />
<transfer terminators="routed" />
<performAAA />
<transfer terminators="routed" mode="bridged;suppressAnswerBeforeRbt;proxydtmf" />
<performAAA />
<accept value="183" />
<transfer terminators="routed" mode="bridged;recognizeAnswerFromRtpB;proxydtmf" disconnectOnSilenceLevel="-40" disconnectOnSilenceTimeout="30s" maxringtime="60s" />
<on event="maxringtime"> <reject value="487" /> </on>
<performAAA />
<accept value="183" />
<transfer terminators="routed" mode="bridged;recognizeAnswerFromRtpA;proxydtmf" level="-20" disconnectOnSilenceLevel="-40" disconnectOnSilenceTimeout="30s" maxringtime="60s" />
<on event="maxringtime"> <reject value="487" /> </on>
<performAAA/>
<transfer terminators="routed" simulateFasAfterConnection="true">
<on event="answer"> <assign var="answeredTime" value="$timeMs();" /> </on>
</transfer>
<if test="$answeredTime;">
<assign var="connectedTime" mathvalue="$timeMs(); - $answeredTime;" />
<assign var="additionalTime" mathvalue="$connectedTime; * 0.01 * $rand(1,10);" />
<wait value="$additionalTime;ms" />
</if>
<transfer mode="blind" value="<sip:1017@xxx.com;user=phone?Replaces=75e4fb7-bdba627c-2d5c4bfd%4010.192.222.38%3Bto-tag%3D53993a5c-88b7-e51e-da9c-e8ce9f20e505%3Bfrom-tag%3DFA1A6CFB-B7991CF0&>" referredBy="sip:test@example.com" />
<readcsv repeat="infinite" value="C:\StarTrinity\2steptest.csv" var0="from" var1="to_name" var2="sbc_ip" var3="sbc_port" var4="password" var5="reffile" var6="xferext" var7="password2" />
<assign var="to" value="sip:$to_name;@$sbc_ip;:$sbc_port;?user=$from;&password=$password;" />
<log value="calling from $from; to $to;" />
<assign var="fromTag" value="$randdigits(10);" />
<assign var="callIdC" value="$randdigits(10);" />
<call value="$to;" callerId="$from;" headers="X-Attributes=*;test=A014" testId="A014" sipCallId="$callIdC;" fromTag="$fromTag;" />
<on event="answer">
<wait value="2s" />
<run var="newSessionId">
<call value="sip:$xferext;@$sbc_ip;:$sbc_port;" sipCallId="$callIdC;" />
<on event="answer">
<log value="received To header '$sipHeaderTo;'" />
<regexsearch value="$sipHeaderTo;" regex=";tag=(?<toTag>\S*)" var="toTag" />
<log value="received To header tag = '$toTag;'" />
<sendevent value="answer" session="$parentSessionId;" toTag="$toTag;" />
<playaudio value="music.wav" />
<exit/>
</on>
</run>
<wait value="30s" />
<exit/>
<on event="externalevent:c_answered" >
<log value="main callxml session: got 'c_answered' event from secondary session. toTag = '$toTag;' -->
<transfer value="<sip:$xferext;@$sbc_ip;:$sbc_port;;user=phone?Replaces=$callIdC;%3Bto-tag%3D$toTag;%3Bfrom-tag%3D$fromTag;>" mode="blind" dontwait="true" />
<wait value="11s" />
<exit />
</on>
</on>
<accept />
<assign var="fromTag" value="$randdigits(10);" />
<assign var="callIdC" value="$randdigits(10);" />
<run var="secondarySessionId">
<call value="sip:204@xxsip.com:5060" maxringtime="60s" sipCallId="$callIdC;" fromTag="$fromTag;">
<on event="answer">
<log value="received To header '$sipHeaderTo;'" />
<regexsearch value="$sipHeaderTo;" regex=";tag=(?<toTag>\S*)" var="toTag" />
<log value="received To header tag = '$toTag;'" />
<sendevent value="answered" session="$parentSessionId;" toTag="$toTag;" />
<playaudio value="C:\vm\PleaseWaitTransfer.wav" repeat="infinite" maxtime="60s" />
<exit/>
<on>
<on event="externalevent:mainSessionHangup">
<log value="received mainSessionHangup event in the second session" />
<disconnect />
</on>
</call>
<run>
<playaudio value="C:\vm\PleaseWaitTransfer.wav" repeat="infinite" maxtime="60s" />
<on event="externalevent:answered" >
<log value="main callxml session: got 'answered' event from secondary session. toTag = '$toTag;'" />
<transfer value="<sip:204@xxsip.com:5060;user=phone?Replaces=$callIdC;%3Bto-tag%3D$toTag;%3Bfrom-tag%3D$fromTag;>" mode="blind" dontwait="true" />
<wait value="11s" />
<exit />
</on>
<on event="hangup" >
<sendevent session="$secondarySessionId;" value="mainSessionHangup" />
</on>
update
Sends UPDATE with new media description.
See also: "reinvite"
Attributes:
direction (optional, "SendOnly"/"ReceiveOnly"/"None"/"Both") - RTP media stream direction.
The meaning of the direction in SDP is a little bit confusing. It is explained in
RFC3264.
If one side (A) sends "recvonly" in its SDP offer, the other side (B) should say "sendonly" (opposite) in its SDP answer.
After that (when SIP call is put on hold), A "receives only, not sends" from B, and B "sends only, not receives" to A,
in other words RTP stream flows in one direction: from B to A, microphone at A is muted
sendSdp (optional, "true"/"false", default "true") - send SDP in the UPDATE packet. "false" is used to test case of SDP offer in "200 OK" and SDP answer in "ACK"
localRtpAddress (optional) - a custom IP address to put into SDP. Is used for test purposes
codec (optional, "G711A"/"G711U"/"G723"/"G729", default is "current") - new RTP media codec (SDP media stream payload type) to be sent in the UPDATE SDP
<update direction="ReceiveOnly" />
<call value="sip:test@10.10.10.10" />
<on event="answer">
<playaudio value="music.wav" maxtime="5s" />
<update codec="G729" />
<playaudio value="music.wav" maxtime="5s" />
<update codec="G711A" />
<playaudio value="music.wav" maxtime="5s" />
<exit />
</on>
verifyaudio
Verifies RTP audio stream of current SIP call, compares it with one or many reference audio files.
Identifies matched reference file along with either a confidence score, or audio quality measurement (PESQ MOS). Also, measures the delay between the start of audio verification and the occurrence of the matched audio file.
For offline mode: records audio signal into memory during "maxtime" regardless of reference file length.
After that, passes the recording to audio verification threads and returns control after verification.
For real-time mode: verifies audio immediately, returns control when "waitConfidenceThreshold" is exceeded or when timeout is expired.
The known ("reference") audio fragment could be located in middle of a longer IVR prompt.
Note: works only in "normal" media processing mode (not "Lightweight", "Winpcap RTP sender")
See also: "waitforsignal" to measure delay of IVR response without any verification, "measuresignal" to measure min/max level in sine test audio signal
Attributes:
reference (required) - absolute or relative reference audio file names or URLs, separated by ";"
callLeg (optional, "a"/"b", "default is "a") - selects call leg (A or B) for the audio verification. Listening to "B" leg is useful when you need to analyse audio in softswitch mode coming from termination side (ringback tone or some IVR announcement)
maxtime (required) - max time of verification in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix).
For real-time audio verification mode "maxtime" is a timeout of waiting for initial match
waitConfidenceThreshold (optional, 1-100) - Setting this value enables real-time audio verification.
To enable real-time audio verification set this value to a number between 1 and 100.
In real-time audio verification mode, the audio stream is verified for a match to any portion of the audio file (or files) specified in by the "reference" parameter.
As soon as a partial match is made, the "maxtime" timer is cancelled.
The audio stream continues to be monitored until either the confidence reaches the specified value, or for number of seconds equal to the longest reference audio file has occurred, whichever comes first.
In the real-time mode audio verification is performed by media threads. It is recommended to set setting "MediaThreadsCount" greater than 64. The real-time mode works for G.711 codec only.
By default, the algorithm searches for matches by testing delays equal to multiples of RTP frame duration (N*10ms), in this way saving CPU time.
If there are partial-frame delays in your environment (e.g. if voice goes over non-RTP channels like TDM), set setting "EnablePartialFrameOffsetInRealtimeAudioVerifier" to "1"
ravParameters (optional, default is "mode=exact") - only for real-time audio verification mode, configures mode of real-time audio verification: "mode=fuzzy" or "mode=exact"
debugRecordingThreshold (optional) - for real-time audio verification: "verifyaudio" saves debug recordings of observed audio, if confidence is less than the "debugRecordingThreshold" (0-100).
for PESQ-mode audio verification (with "mosvar" attribute set) the "debugRecordingThreshold" means PESQ MOS threshold to save the recording.
Recorded file names are built from settings "DebugMediaPath" and "DebugMediaFileNamePattern".
confidencevar (optional) - name of variable to store measured confidence,
i.e. similarity rate between RTP audio stream and reference audio file = 100 * matched_duration / reference_wav_duration
mosvar (optional) - name of variable to store PESQ MOS. If "mosvar" attribute exists, PESQ algorithm is used to calculate MOS.
If recorded duration and reference duration are not equal, minimum duration is selected for PESQ.
Note: If waitConfidenceThreshold is specified, this value has no effect.
If you have low PESQ MOS scores while it is not expected, you can:
- Enable RX debug recording (set setting "DebugMedia = "1"), listen to recorded audio to check if audio quality is really bad
- Increase SIP Tester's jitter buffer size, set it according to settings of your VoIP software
- Try to use recorded RX wav file as reference file. Some implementations like SIPP make small distortions which affect work of SIP Tester's jitter buffer loss compensator
- Try to use a different audio file. The algorithm works better with speech, not music. There is a "speech.wav" in default installer
recognizedreferencevar (optional) - name of variable to store matched reference audio file. If more than one file is passed in the reference value, the file with the highest match is returned.
recognizeddelayvar (optional) - name of the variable to store delay between the start of audio verification and the occurrence of the matched audio file in milliseconds.
The delay can be negative if some part of IVR file is already played before the start of verification
probability (optional) - probability of audio verification being executed. Is used to verify audio for only part of calls, in this way reducing CPU load. Valid range is a decimal value from 0-1.
<playdtmf value="1" />
<verifyaudio reference="c:\ivr2.wav;c:\ivr3.wav" maxtime="10s" recognizeddelayvar="delay" recognizedreferencevar="ref" confidencevar="conf" />
<log value="delay = $delay;ms, reference file = $ref;, confidence = $conf;" />
<writecdr header="IVR" value="$ref;" />
<writecdr header="IVRCONF" value="$conf;" />
<call value="sip:XX@10.10.10.10" />
<on event="answer">
<verifyaudio reference="C:\reference_file_speech.wav" maxtime="10s" mosvar="pesq_mos" />
<writecdr header="PESQ_MOS" value="$pesq_mos;" numeric="true" qualityIsAscending="true" />
<exit />
</on>
<callxml>
<call value="$random_least_busy_uac_registration();" >
<on event="answer">
<playaudio value="speech.wav" dontwait="true" />
<verifyaudio reference="speech.wav" maxtime="12s" mosvar="pesq_mos" />
<writecdr header="PESQ_MOS" value="$pesq_mos;" numeric="true" qualityIsAscending="true" />
<exit />
</on>
</call>
</callxml>
<callxml>
<accept />
<loopbackaudio maxtime="60s" />
</callxml>
<call value="sip:YY@10.10.10.10" />
<on event="answer">
<verifyaudio reference="C:\reference_file_speech.wav" maxtime="14s" waitConfidenceThreshold="100" confidencevar="confidence" recognizeddelayvar="delay" />
<writecdr header="CONFIDENCE" value="$confidence;" numeric="true" qualityIsAscending="true" />
<writecdr header="DELAY" value="$delay;" numeric="true" qualityIsAscending="false" />
<exit />
</on>
wait
Introduces delay with specified amount of time
See also: "waitforsignal"
Attributes:
value (optional, default is "infinite") - timer in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix). If "value" is not specified, the "wait" sets current call into idle state
<wait value="1s" />
<wait value="$rand(10000);ms" />
waitforevent
Waits for external event, sent by other CallXML session via "sendevent" element. Is used to synchronize CallXML scripts
Attributes:
value (optional) - event subtype to wait from sender. If not set, all external events are accepted
maxtime (optional) - optional timeout
waitforringbacktone
Waits for a ringback audio tone with frequency 400..450Hz and level at least -30dB. Is used to validate SIP trunks
If there is no RTP, it does not return control. See also: "waitforsignal"
Attributes:
var (optional) - name of variable to store measured delay in milliseconds. If the "maxtime" timeout expires, it receives a value of "maxtime"
maxtime (optional) - timeout of waiting in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix)
<call value="sip:test@10.10.10.10">
<on event="pr:183">
<log value="received 183 response. waiting for ringback tone for max 6000ms..." />
<waitforringbacktone var="d" maxtime="6s" />
<log value="RBT wait time = $d;ms" />
<if test="$d; >= 6000"> <log value="RBT is not detected" /> </if>
</on>
<on event="answer">
<log value="received 200 response" />
<exit />
</on>
</call>
<assign var="rbtDetected" value="NO" />
<assign var="sipUriToDial" value="$seq_sip_uri_from_csv(C:\SipTester\destinations.csv);" />
<call value="$sipUriToDial;" maxringtime="10s" codec="G711U">
<on event="pr:183">
<log value="received 183 response. waiting for ringback tone for max 6000ms..." />
<waitforringbacktone var="rbtWaitTime" maxtime="6s" />
<log value="RBT wait time = $rbtWaitTime;ms" />
<if test="$rbtWaitTime; >= 6000"><log value="RBT is not detected" /></if>
<else> <assign var="rbtDetected" value="YES" /> </else> <
</on>
<on event="answer">
<log value="received 200 response" />
<playaudio value="music.wav" maxtime="3s" />
<assign var="statusCode" value="200" />
</on>
<on event="callfailure"> <assign var="statusCode" value="$eventSubType;" /> </on>
</call>
<writefile newLine="true" fileName="C:\SipTester\log.csv" splitInterval="1h" value="$sipUriToDial;,$statusCode;,$rbtDetected;" />
waitforringbacktoneabsence
Waits for absence of ringback audio tone with frequency 400..450Hz and level at least -30dB. Is used to skip fake SIM card answer and "welcome" announcement with GSM gateways (see sample script)
See also: "waitforringbacktone"
Attributes:
var (optional) - name of variable to store measured delay in milliseconds. If the "maxtime" timeout expires, it receives a value of "maxtime"
maxtime (optional) - timeout of waiting in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix)
minabsencetime (optional, default "5s") - minimum time without ringback tone, in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix)
<call value="sip:1234567@10.10.10.10" />
<on event="pr:183">
<log value="got early media from destination: waiting for ringback tone (RBT). we ignore the 200 OK signal, use audio signal instead" />
<waitForRingbacktone />
<log value="got ringback tone. waiting for ringback tone absence (voice answer or silence)" />
<waitForRingbacktoneAbsence />
<log value="got RBT absence. playing audio file" />
<playaudio value="music.wav" />
<exit />
</on>
waitforsilence
Waits for RTP audio signal below specified level. Is used to wait for the end of IVR prompt
If there is no RTP, it does not return control. See also: "waitforsignal"
Attributes:
maxtime (optional) - timeout of waiting in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix)
level (optional, default is "-24dB") - threshold level in dB. 0dB corresponds to max level, -6dB to 50%, -[Infinity]dB to silence
minTimeBelowLevel (optional, default is "500ms") - minimal duration of audio below the "level" before exiting the "waitforsilence"
interruptableByDtmf (optional, default is "false") - specifies presence of additional DTMF event handlers in script
<playdtmf value="1" />
<waitforsignal />
<log value="detected IVR audio prompt" />
<waitforsilence />
<log value="detected silence after prompt" />
waitforsignal
Waits for RTP audio signal above specified level, measures delay. Is used to verify response times in IVR menus
If there is no RTP, it does not detect any signal and does not return control. If you have problems when call flow hangs in the "waitforsignal",
please put "recordcall" with mode="rx" before the "waitforsignal", to record received audio into WAV file and understand what happens.
See also: "measuresignal", "waitforsilence"
Attributes:
maxtime (optional) - timeout of waiting in milliseconds ("ms" suffix), seconds ("s" suffix) or minutes ("m" suffix)
signaldelayvar (optional) - name of variable to store measured delay in milliseconds. If the "maxtime" timeout expires, it receives a value of "maxtime"
level (optional, default is "-24dB") - threshold level in dB. 0dB corresponds to max level, -6dB to 50%, -[Infinity]dB to silence
minTimeAboveLevel (optional, default is "0ms") - minimal duration of exceeding the "level" before exiting the "waitforsignal"
callLeg (optional, "A" or "B", default is "A") - identifies call leg when doing call transfer
maxlevelvar (optional) - name of variable to save maximal (peak) signal level in decibels, if the "waitforsignal" is aborted by the "maxtime" timeout
<playdtmf value="1" />
<waitforsignal signaldelayvar="ivrDelay"/>
<report name="IVR_delay_1" qualityIsAscending="false" value="$ivrDelay;" />
<waitforsignal signaldelayvar="d" level="-15dB" maxtime="3s" minTimeAboveLevel="10ms" />
<log value="delay = $d;ms" />
<log value="received call from $callerId;" />
<accept value="183" />
<waitforsignal signaldelayvar="d" level="-20dB" maxtime="3000ms" />
<log value="signal delay (-20dB) = $d;ms" />
<block test="$d; > 3000">
<log value="rejecting call: no signal is detected above -20dB within 3 seconds" />
<reject value="503" />
</block>
<log value="accepting call: signal is detected above -20dB within 3 seconds" />
<accept value="200" />
<playaudio value="music.wav" maxtime="222s" />
writecdr
Saves a variable to CDR report, optionally analyses it as numeric performance indicator
Notes:
- A CDR record represents SIP call, not CallXML session. However it is possible to execute "writecdr" before making a call
- If you use CDR CSV files, and if your code contains conditional branches (i.e. "writecdr" is not always executed),
you should put a "writecdr" with empty value in the beginning of your script, so it will be always executed.
- CSV CDR file's schema (headers) are updated only for the first call in the file. You may need to delete old CDR CSV files if you add new custom CDR headers
- If you save CDR to your a database, you need to make CDR field names compatible with SQL syntax: e.g. column name must not start with a digit
See also: "report"
Attributes:
header (required) - header in CDR file
value (required) - variable to be saved
numeric (optional, "true"/"false", default is "false") - specifies whether to analyses variable as numeric performance indicator
qualityIsAscending (optional, "true"/"false") - indicates whether call quality increases or decreases with increasing of the variable.
Is used to calculate percentiles and list of worst quality calls
<verifyaudio reference="C:\ivr.wav" maxtime="10s" mosvar="mos" />
<writecdr header="MOS" value="$mos;" numeric="true" qualityIsAscending="true" />
<writecdr header="callerCountry" value="" />
<if test="$calledId; matches ^\d{11}$">
<writecdr header="callerCountry" value="Syria" />
</if>
<call value="sip:13108790819@1.2.3.4" />
<on event="answer">
<writecdr header="call_suceeded" value="1" />
<playaudio value="music.wav" maxtime="20000ms" />
<exit />
</on>
<on event="callfailure">
<writecdr header="call_suceeded" value="0" />
</on>
writefile
Writes a text to file. Is used to write files with custom format in CallXML script. Appends text to end of file
Attributes:
value (required) - text to be written to file
fileName (required) - absolute or relative file name
newLine (optional, "true"/"false", default is "false") - specifies whether to insert line break before the text
splitInterval (optional) - enables splitting file into parts periodically, sets the period in seconds ("s" suffix),
minutes ("m" suffix) or hours ("h" suffix). Adds a suffix "_yyyyMMdd_HHmmss" to the file name
<readcsv value="b_numbers_2014mar.csv" var0="numB" repeat="5" mode="random" />
<readcsv value="a_numbers.csv" var0="numA" mode="random" />
<log value="calling from $numA; to $numB;" />
<assign var="callStart" value="$time();" />
<call value="sip:$numB;@85.110.209.50" callerId="$numA;" maxringtime="60s" />
<on event="answer">
<log value="call answered from $numA; to $numB;" />
<wait value="$rand(1000,3000);ms" />
<assign var="callEnd" value="$time();" />
<writefile newLine="true" fileName="F:\ftproot\SUCEEDED.txt" splitInterval="1m"
value="$callStart;;$callEnd;;$numA;;$numB;"
/>
<on event="hangup">
<assign var="callEnd" value="$time();" />
<writefile newLine="true" fileName="F:\ftproot\SUCEEDED.txt" splitInterval="100m"
value="$callStart;;$callEnd;;$numA;;$numB;"
/>
</on>
<exit />
</on>
<on event="callfailure">
<log value="call failed from $numA; to $numB;" />
<assign var="callEnd" value="$time();" />
<writefile newLine="true" fileName="F:\ftproot\FAILED.txt" splitInterval="1m"
value="$callStart;;$callEnd;;$numA;;$numB;"
/>
</on>
<on event="maxringtime">
<log value="call timed out from $numA; to $numB;" />
<assign var="callEnd" value="$time();" />
<writefile newLine="true" fileName="F:\ftproot\FAILED.txt" splitInterval="1m"
value="$callStart;;$callEnd;;$numA;;$numB;"
/>
</on>
All CallXML elements may contain following common attributes:
- enabled ("true"/"false", default "true") - is used to turn off a CallXML element.
Substitutions
Attributes in script may contain substitutions. A substitution starts with '$' and ends with ';'.
It is replaced in runtime with another string depending on type of substitution.
$rand(x); is replaced by random integer value which is exponentially distributed from 0 to infinity with mean of
x
$rand(x,y); is replaced by random integer value which is uniformly distributed from
x (inclusive) to
y (inclusive)
$randswitch(case1,case2,case3,...); is replaced by one of optional cases, selected randomly
$randswitch(numberAMin-numberAMax,numberBMin-numberBMax,...); is replaced by one of optional cases with number ranges, selected randomly. Example:
<assign var="num" value="$randswitch(252000000-252000999,252400000-252400999);" />
<playaudio value="music.wav" maxtime="$randswitch(1-600);s" />
$randdigits(number_of_digits); is replaced by a string of random digits from 0 to 9, with specified length = number_of_digits
$randfile(path\mask); is replaced by a random file from directory:
<playaudio value="$randfile(C:\StarTrinity\wav\*.wav);" />
The directory search is performed in main SIP thread, so large directories can slow down the software
$x; is replaced by value of variable with name
x. Variable names are not case-sensitive.
Name of variable can be computed dynamically from a prefix and another variable:
$prefix$suffixVar;; or
$arrayName[$arrayIndex;];
$global.x; is replaced by value of global variable with name
x
Name of global variable can be computed dynamically from a prefix and another variable:
$global.prefix$suffixVar;; or
$global.someCache[$key;];
$time();,
$time(format); is replaced by current date and time:
<recordmessage value="d:\recordings\$time(yyyyMMdd_HH_mm_ss_fff);.wav" />
Note: the software uses QueryPerformanceCounter() procedure inside to get accuracy of microseconds and avoid time jumps when system clock is updated (so the "$time();" always increments without interruptions).
As a drawback, there can be a small time drift between the "$time();" and system clock, it can be rset by restarting SIP Tester.
$timeMs(); is replaced by software uptime in milliseconds. Can be used to calculate delays:
<assign var="t1" value="$timeMs();"/>
<call value="sip:test@23.45.67.89:5060" />
<on event="answer">
<assign var="delay" mathvalue="$timeMs(); - $t1;"/>
<log value="delay = $delay;ms" />
<exit />
</on>
$timeOfDayInMinutes(); is replaced by number of minutes between current moment and previous midnight
$timeOfHourInMinutes(); is replaced by number of minutes between current moment and beginning of current hour
$param.x; is replaced by value of parameter which is defined in
<params> section inside the script
$env.x; is replaced by windows environment variable:
<log value="temp directory: $env.TMP;; user name: $env.USERNAME;; windows directory: $env.windir;; machine name: $env.COMPUTERNAME;" />
$ext(x); is replaced by 'Contact' header of registered extension (see UAC registrations)
<transfer value="$ext(100);"/>
XML escape characters
According to XML specifications of the W3C, there are 5 characters that must not appear in their literal form in an XML document. The characters must be replaced according to table:
Original character |
XML replacement |
" |
" |
' |
' |
& |
& |
" |
" |
< |
< |
> |
> |
Example:
<call value="sip:111@10.10.10.1?user=XXX&password=YYY" />
You can use
this tool to escape the characters automatically
Default variables
- answerDelay - for outgoing calls after answer: answer delay in milliseconds
- calledId - user ID (number) in "To" SIP header
- callerId - user ID (number) in "From" SIP header
- callerIdName - display name in "From" SIP header
- callerIpAddress - IP address of SIP call initiator. Is taken from IP protocol (layer 3)
- callNumberInBurst - number of call in burst, when generating calls in burst mode, starts from 0
- eventSubType - subtype of event which is currently handled by "on" CallXML element. Contains additional information about the event
- eventType - type of event which is currently handled by "on" CallXML element
- Id - CallXML session identifier. Starts with 0, increments sequentially. Is reset to 0 when call generator is started ("Start" button is clicked) if setting "ResetCallXmlSessionIdWhenStartedCallGenerator" is set to 1
- launcherType - identifies the way how the CallXML script is launched: "cli" - SIP Tester CLI; "gui" - SIP Tester GUI; "softswitch" - Softswitch
- originatorId - identifier of current originator. Is set by "performAAA" CallXML element
- language - language of current originator. Is set by "performAAA" CallXML element. Is used to play IVR files from corresponding folder
- redirectedNumber - user ID (number) in "Diversion" SIP header for incoming calls
- sdpAttribute[name] - prefix for variables which contain attributes of remote SDP. Example: sdpAttributeptime, sdpAttributefmtp[0], sdpAttributefmtp[1], sdpAttributertpmap[2]
- sipCallId - "Call-ID" SIP header
- sipHeader[name] - prefix for variables which contain headers of "INVITE" packet for incoming calls and "INVITE provisional response" packet for outgoing calls. For outgoing calls the variables are accessible in "pr", "answer" and "callfailure" event handlers. Example: sipHeaderVia, sipHeaderVia[0], sipHeaderVia[1]. Note: please use CallXML element "getsiptrace" to have full access to received and transmitted SIP messages, and SIP headers, SDP attributes
- tenantId - identifier of current tenant, in softswitch multi-tenant mode. Is set by "performAAA" CallXML element
Attributes which are common to all CallXML elements
- enabled ("true"/"false", default is "true") - turns off execution of a CallXML element. Is used to temporarily disable and enable some parts of the CallXML script
- label - is used to identify the destination CallXML element in "goto"
Boolean expressions
The boolean expressions are used in "if", "block" and "goto" CallXML elements and in CDR display filter. The expression contain one or many comparisons, parentheses, boolean operators, strings in single quotes.
Comparison operators are:
< | less than |
<= | less than or equal |
> | greater than |
>= | greater than or equal |
=, == | equal |
!=, <> | inequal |
startswith | left operand starts with prefix (right operand) |
matches | left operand matches to regular expression (right operand) |
contains | left operand contains right operand as a substring |
Boolean operators are:
Strings which are considered as "boolean false":
Examples of boolean expressions for CallXML script:
- $calledId; = 98764352343
- $callerId; startswith 123 or $calledId; = 345
- $callerId; = 123456 and $calledId; = 1345678
- 'a=123' = 'a=123'
Examples of boolean expressions for CDR filter:
- Answered_Duration > 1000
- Answered_Duration > 1000 and (CalledId startswith 10 or CalledId startswith 11)
- Disconnection_Status = 200
- Answer_Delay > 10000
- CalledId = 123456
- CallerId = 123456
- CallerId contains 456
- SIP_CallId = asefruyhnsdfteomhu7sngd@10.10.10.20
- MyCustomCdrField1 > 10000 and MyCustomCdrField2 != OK
List of available CDR columns (fields) is displayed in GUI (CDR - fields..)