Sample CallXML Scripts for StarTrinity SIP Tester
The scripts should be copied from this page into SIP Tester -> Outgoing calls simulation -> XML tab, into <callxml></callxml> root element, replacing previous code.
Generation of random outgoing calls
This is a script for stress testing call centers, PBX systems, outbound dialers with SIP Tester.
It generates calls with specified prefix, random caller ID (A number) and called ID (B number). Destination SIP URI is localhost:5061, it has to be replaced with actual URI.
<assign var="to" value="sip:calledIdPrefix$rand(1000,9999);@localhost:5061" />
<assign var="from" value="callerIdPrefix$rand(1000,9999);" />
<log value="calling from $from; to $to;" />
<call value="$to;" callerId="$from;"/>
<on event="answer">
<wait value="1000ms" />
<exit />
</on>
Registering range of IP PBX extensions and making calls between them
<assign var="numberOfExtensions" value="100" />
<if test="$Id; < $numberOfExtensions;">
<assign var="extensionId" mathvalue="1000 + $Id;" />
<log value="registering extension $extensionId;..." />
<register value="sip:$extensionId;@startrinity.com:5070?user=$extensionId;&password=123456" expires="36000" var="status" delayvar="delay" />
<log value="registered extension $extensionId;. response code = $status;, delay = $delay;ms" />
</if>
<else>
<assign var="srcExtensionId" mathvalue="1000 + $Id; % ($numberOfExtensions; / 2)" />
<assign var="dstExtensionId" mathvalue="1000 + ($numberOfExtensions; / 2) + $Id; % ($numberOfExtensions; / 2)" />
<log value="making call from extension $srcExtensionId; to $dstExtensionId;" />
<call value="sip:$dstExtensionId;@startrinity.com:5070?user=$srcExtensionId;&password=123456" maxringtime="30s">
<on event="answer">
<log value="call from extension $srcExtensionId; to $dstExtensionId; got connected" />
<playaudio value="music.wav" maxtime="60s" repeat="infinite" />
<exit />
</on>
</call>
</else>
Reading IP PBX extensions, registering and making calls between them
<readcsv value="c:\startrinity\extensions.csv" repeatCounterVar="csvRepeatCounter" var0="user" var1="password" var2="dst_user" repeat="infinite" />
<log value="read from CSV: user=$user; dst_user=$dst_user; csvRepeatCounter=$csvRepeatCounter;" />
<if test="$csvRepeatCounter; == 0">
<log value="registering extension $user;..." />
<register value="sip:$user;@startrinity.com:5070?user=$user;&password=$password;" expires="36000" var="status" delayvar="delay" />
<log value="registered extension $user;. response code = $status;, delay = $delay;ms" />
</if>
<else>
<log value="making call from extension $user; to $dst_user;" />
<call value="sip:$dst_user;@startrinity.com:5070?user=$user;&password=$password;" maxringtime="30s">
<on event="answer">
<log value="call from extension $user; to $dst_user; got connected" />
<playaudio value="music.wav" maxtime="60s" repeat="infinite" />
<exit />
</on>
</call>
</else>
Specifying custom SIP headers and SDP attributes
You can add custom SIP headers by setting attribute "headers", also add SDP attributes by setting attribute "sdpAttributes". This could be helpful for testing ED-137 SIP applications.
<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"
/>
<accept headers="WG67-Version=radio.01"
sdpAttributes="R2S-KeepAlivePeriod:200|R2S-KeepAliveMultiplier:10|sigtime:1" />
Test IVR menu 1
The script reads caller ID, called ID and DTMF sequence from CSV file, creates a call and sends DTMF digits to destination.
<readcsv value="e:\list.csv" var0="destinationUri" var1="pincode" />
<log value="read next row from CSV and save it into variables: destinationUri = $destinationUri;, pincode=$pincode;" />
<log value="calling (sending INVITE to) $destinationUri;" />
<call maxringtime="10000ms" value="$destinationUri;" />
<on event="answer">
<log value="destination answered (received 200 OK). making pause = 1 second (waiting for IVR message)" />
<wait value="1000ms" />
<log value="sending DTMF digit 1 (press 1 if you are existing customer)" />
<playdtmf value="1" />
<wait value="1000ms" />
<log value="sending DTMF digits $pincode; (enter your pincode)" />
<playdtmf value="$pincode;" />
<wait value="3000ms" />
<block probability="0.5" >
<log value="50% of calls: sending additional DTMF '3'" />
<playdtmf value="3" />
<wait value="10000ms" />
<log value="aborting call" />
<exit />
</block>
<block probability="0.5" >
<log value="25% of calls: sending additional DTMF '123'" />
<playdtmf value="123" />
<wait value="10000ms" />
<log value="aborting call" />
<exit />
</block>
<log value="25% of calls: sending additional DTMF '456'" />
<playdtmf value="456" />
<wait value="10000ms" />
<log value="aborting call" />
<exit />
</on>
Test IVR menu 2
Another script example simulates several DTMF keys and records audio into WAV file. Recording contains both debugging prompts with synthesised speech and audio from tested IVR.
<log value="calling..." />
<call value="sip:1001@192.168.56.1:5061?user=user1&password=pass1" />
<on event="answer">
<log value="answered" />
<recordcall value="100" />
<wait value="$rand(3,6);s" />
<assign var="dtmf" value="$rand(1,2);" />
<playdtmf value="$dtmf;" />
<log value="sent DTMF: $dtmf;" />
<say voice="Microsoft Anna" value="pressed $dtmf;" />
<wait value="$rand(10,20);s" />
<block test="$dtmf;=1">
<wait value="$rand(3,6);s" />
<assign var="dtmf" value="$rand(1,6);" />
<playdtmf value="$dtmf;" />
<log value="sent DTMF: $dtmf;" />
<say voice="Microsoft Anna" value="pressed $dtmf;" />
<wait value="$rand(10,20);s" />
</block>
<block test="$dtmf;=2">
<wait value="$rand(3,6);s" />
<assign var="dtmf" value="$rand(0,9);" />
<playdtmf value="$dtmf;" />
<log value="sent DTMF: $dtmf;" />
<say voice="Microsoft Anna" value="pressed $dtmf;" />
<wait value="$rand(10,20);s" />
</block>
<wait value="5s" />
<log value="aborting call" />
<exit />
</on>
Test IVR menu 3 (dead air + recording)
The script makes call to a number, waits for IVR playback. If there is silence (dead air), it sends an alert email (settings MailSender***).
Minimal interval between emails is 5 minutes (sending emails is limited to avoid too many emails). All calls are recorded to WAV files.
The IVR playback delays are saved to CDR in a custom field
<call maxtime="10s" callerId="9995523212" value="sip:18557771333@207.70.137.4:5060"/>
<on event="answer">
<recordcall value="100" />
<waitforsignal signaldelayvar="ivrDelay" maxtime="10s"/>
<writecdr header="IVR_delay" qualityIsAscending="false" value="$ivrDelay;" numeric="true" />
<if test="$ivrDelay; > 5000">
<block minInterval="5m">
<sendemail value="mailto:destinationemailuser@server.com?subject=IVR timeout: $ivrDelay; milliseconds&body=Timeout in IVR1. called id: $calledId;. caller ID: $callerId;. time now: $time();" />
</block>
</if>
<wait value="2s" />
<playdtmf value="9" />
<wait value="5s" />
<exit/>
</on>
Test audio quality (PESQ MOS) in a conference server
The conference server should be tested by 2 separate instances of SIP Tester. They can run on the same server on different SIP ports
("LocalSIPPort" setting). The first instance simulates call load of about 30 concurrent calls, it plays silence to the conference.
The second instance generates pairs of calls, verifies audio signal and measures PESQ MOS.
A pair of calls is generated if you set "number of calls to generate at a time" = "2"
<call value="sip:123456@1.10.10.10:5060" codec="G711A" maxringtime="30s" />
<on event="answer">
<waitforsignal value="-24dB" />
<playdtmf value="1234#" />
<wait value="60s" />
<exit />
</on>
<call value="sip:123456@1.10.10.10:5060" codec="G711A" maxringtime="30s" />
<on event="answer">
<waitforsignal value="-24dB" />
<playdtmf value="1234#" />
<wait value="2s" />
<playaudio value="speech.wav" dontwait="true" />
<verifyaudio reference="speech.wav" maxtime="12s" mosvar="mos" recognizeddelayvar="delay" />
<log value="measured PESQ MOS = $mos;, conference audio delay = $delay;ms" />
<writecdr header="CONFERENCE_MOS" value="$mos;" numeric="true" qualityIsAscending="true" />
<writecdr header="CONFERENCE_DELAY" value="$delay;" numeric="true" qualityIsAscending="false" />
<exit />
</on>
Here is a script to simulate the conference in SIP Tester:
<accept/>
<inputdigits value="music.wav" var="roomNumber" maxsilence="10s" maxdigits="10" />
<log value="entering room number $roomNumber;" />
<conference value="$roomNumber;" />
Test audio quality (PESQ MOS) in a conference server (long-duration calls)
SIP Tester should be configured to make N calls in burst, and to limit number of concurrent calls to N.
First call in burst plays audio to the conference, secondary calls listen to audio signal from the conference server and measure audio quality
<call value="sip:123456@192.168.10.1:5060" codec="G711A" maxringtime="30s" />
<on event="answer">
<log value="call is answered [callNumberInBurst = $callNumberInBurst;]" />
<assign var="measurementsPerCall" value="20" />
<if test="$callNumberInBurst; = 0">
<wait value="5s" />
<block repeat="$measurementsPerCall;">
<log value="playing sound [callNumberInBurst = $callNumberInBurst;]" />
<playaudio value="speech.wav" />
<log value="playing silence [callNumberInBurst = $callNumberInBurst;]" />
<wait value="10s" />
</block>
</if>
<else>
<recordcall value="100" />
<assign var="minMos" value="5" />
<block repeat="$measurementsPerCall;" var="loopCounter" >
<log value="waiting for signal [callNumberInBurst = $callNumberInBurst;]" />
<waitforsignal />
<log value="recognizing audio [callNumberInBurst = $callNumberInBurst;]" />
<verifyaudio reference="speech.wav" maxtime="12s" mosvar="mos" recognizeddelayvar="delay" />
<log value="measured PESQ MOS = $mos;, conference audio delay = $delay;ms [callNumberInBurst = $callNumberInBurst;]" />
<if test="$loopCounter; != 0">
<writecdr header="CONFERENCE_measurements_count" value="$loopCounter;" numeric="true" qualityIsAscending="true" />
<if test="$mos; < $minMos;">
<assign var="minMos" value="$mos;" />
<writecdr header="CONFERENCE_min_MOS" value="$minMos;" numeric="true" qualityIsAscending="true" />
</if>
</if>
</block>
</else>
</on>
Here is a script to simulate the conference in SIP Tester:
<accept/>
<conference value="01" />
Test audio quality (PESQ MOS) and DTMF capability of a VoIP route (SIP trunk) in 2 directions
The 2 scripts (incoming and outgoing) are used to make test calls via a SIP route to check its audio quality and DTMF passability in 2 ways (from A to B and from B to A)
<call value="sip:1234567890@12.34.56.78:5060" maxringtime="30s">
<on event="answer">
<playaudio value="speech.wav" repeat="infinite" maxtime="30s" />
<wait value="1s" />
<log value="(A, step 2) verifying audio" />
<verifyaudio reference="speech.wav" maxtime="12s" mosvar="pesq_mos" />
<writecdr header="PESQ_MOS_BtoA" value="$pesq_mos;" numeric="true" qualityIsAscending="true" />
<waitforsilence />
<log value="(A, step 3) receiving DTMF" />
<inputdigits var="received_digits" maxdigits="10" maxsilence="15s" />
<writecdr header="DTMF_BtoA" value="$received_digits;" />
<wait value="10s" />
<log value="(A, step 4) sending DTMF" />
<playdtmf value="1234567890" />
<wait value="10s" />
<exit />
</on>
</call>
<accept />
<verifyaudio reference="speech.wav" maxtime="12s" mosvar="pesq_mos" />
<writecdr header="PESQ_MOS_AtoB" value="$pesq_mos;" numeric="true" qualityIsAscending="true" />
<waitforsilence minTimeBelowLevel="1s" />
<log value="(B, step 2) got silence, playing audio" />
<playaudio value="speech.wav" repeat="infinite" maxtime="30s" />
<wait value="2s" />
<log value="(B, step 3) sending DTMF" />
<playdtmf value="1234567890" />
<wait value="10s" />
<log value="(B, step 4) receivingDTMF" />
<inputdigits var="received_digits" maxdigits="10" maxsilence="10s" />
<writecdr header="DTMF_AtoB" value="$received_digits;" />
<exit />
Test outbound dialer
The script processes incoming calls which are generated by dialer. It makes random delays, accepts or rejects call.
<log value="received call from '$callerId;'" />
<
block probability="0.05" >
<log value="rejecting with 500 after delay" />
<
wait value="
$rand(100000);ms" />
<
reject value="500" />
<exit />
</block>
<
wait value="
$rand(1000);ms" />
<accept value="183" />
<log value="sent 183" />
<on event="hangup">
<log value="call is disposed by remote side" />
</<on>
<block probability="0.05" >
<log value="rejecting with 486 after pause" />
<wait value="$rand(1000);ms" />
<reject value="486" />
<exit />
</block>
<block probability="0.05" >
<log value="rejecting with 486 after busy tone" />
<playaudio value="
busytone.wav" maxtime="30s" />
<reject value="486" />
</block>
<
accept />
<log value="sent 200" />
<block probability="0.5" >
<log value="simulating answer machine" />
<say voice="Microsoft Anna" value="Hello, please enter extension number" maxsilence="30s" />
<inputdigits var="enteredExtension" maxdigits="4" />
<block test="$enteredExtension; != 1234">
<log value="ERROR: expected extension '1234' but received '$enteredExtension;'" />
<say voice="Microsoft Anna" value="extension $enteredExtension; is not valid" />
<exit />
</block>
<say voice="Microsoft Anna" value="connecting to extension $enteredExtension;" />
<wait value="$rand(10000);ms" />
<exit />
</block>
<log value="simulating live call" />
<playaudio value="music" maxtime="100s" />
Text-to-speech IVR with MSSQL request
<accept />
<say voice="Microsoft Anna" value="This is text-to-speech announcement. Please enter some number and press pound key." />
<inputdigits var="enteredNumber" maxsilence="20s" maxdigits="10" />
<say voice="Microsoft Anna" value="You have entered $enteredNumber;" />
<requestdb command="select InfoMessage from Table1 where PinCode = '$enteredNumber;'"
connection="Data Source=(local)\SQLEXPRESS;User ID=sa;Password=123;Initial Catalog=DtmfTest;Asynchronous Processing=true"
var0="infoMessage" />
<say voice="Microsoft Anna" value="$infoMessage;" />
Sending custom SIP request after provisional response for outgoing calls
<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>
Sending different SDPs in 183 and 200 response for incoming calls
The script could be used to check whether SIP caller is able to adjust RTP stream according to changed SDP response in 200 OK
<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/>
Sending custom SIP INVITE without initial SDP
The script sends custom SIP message to server without creating call (only for testing SIP stack).
The message is specified by 'CDATA' content of XML element. Call-ID header is generated from CallXML session ID.
<sendsipmessage>
<![CDATA[INVITE sip:192.168.206.197:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.206.197:5060;branch=z9hG4bK18171d2b3f11
From: "2000" <sip:2000@192.168.206.197>;tag=104574~6a5c17ac-9109-44e8-b315-975d70cd1b5d-22861245
To: <sip:1000@192.168.206.197>
Date: Mon, 29 Jul 2013 20:55:20 GMT
Call-ID: SipTester$Id;
Supported: timer,resource-priority,replaces
Min-SE: 1800
User-Agent: Cisco-CUCM8.6
Allow: INVITE, OPTIONS, INFO, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY
CSeq: 101 INVITE
Expires: 180
Allow-Events: presence
Send-Info: conference, x-cisco-conference
Alert-Info: <file://Bellcore-dr1/>
Contact: <sip:2000@192.168.206.197:5060>
Remote-Party-ID: "2000" <sip:2000@192.168.206.197;x-cisco-callback-number=2000>;party=calling;screen=yes;privacy=off
Max-Forwards: 69
]]>
</sendsipmessage>
Sending custom SIP INVITE with 2 media streams in SDP
The script sends custom SIP message to server without creating call (only for testing SIP stack).
The message is specified by 'CDATA' content of XML element.
SIP Tester automatically calculates 'Content-Length' header, so only 'Content-Type' header is needed.
Call-ID header is generated from CallXML session ID.
<sendsipmessage>
<![CDATA[INVITE sip:192.168.206.197:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.206.197:5060;branch=z9hG4bK18171d2b3f11
From: "2000" <sip:2000@192.168.206.197>;tag=104574~6a5c17ac-9109-44e8-b315-975d70cd1b5d-22861245
To: <sip:1000@192.168.206.197>
Call-ID: SipTester$Id;
Supported: timer,resource-priority,replaces
User-Agent: StarTrinity SIP Tester
Allow: INVITE, OPTIONS, INFO, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY
CSeq: 101 INVITE
Expires: 180
Contact: <sip:2000@192.168.206.191:5060>
Max-Forwards: 69
Content-Type: application/sdp
v=0
o=root 342983111 342983111 IN IP4 192.168.1.188
s=Asterisk PBX 1.6.2.15
c=IN IP4 192.168.1.188
t=0 0
m=audio 11568 RTP/AVP 18 8 0
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=ptime:20
a=sendrecv
m=image 4488 udptl t38
a=T38FaxVersion:0
a=T38MaxBitRate:14400
a=T38FaxRateManagement:transferredTCF
a=T38FaxMaxDatagram:397
a=T38FaxUdpEC:t38UDPRedundancy
]]>
</sendsipmessage>
Monitoring SIP server with email notifications
This script makes a call to a SIP server and sends email alarms on success and failure.
The SIP Tester Tool could be configured execute script periodically.
Note that interval between calls has to be large enough to avoid anti-spam protection at mail server.
The sendemail element uses settings "MailSenderUserName", "MailSenderPassword", "MailSenderServer", "MailSenderFrom",
they are configured in SIP Tester on settings screen.
<call callerId="123456" value="sip:7890123@192.168.1.57:5060" />
<on event="answer">
<assign globalvar="recurringFailuresCount" value="0" />
<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">
<assign globalvar="recurringFailuresCount" mathvalue="$global.recurringFailuresCount; + 1" />
<block test="$global.recurringFailuresCount; > 3 and $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>
Simulating RE-INVITE (put SIP call on hold)
Script for call generator:
<call value="sip:2222@server.com:5060"/>
<on event="answer">
<playaudio value="music" maxtime="5s" />
<reinvite direction="SendOnly" />
<playaudio value="music" maxtime="5s" />
<reinvite direction="ReceiveOnly" />
<playaudio value="music" maxtime="5s" />
<reinvite direction="None" />
<playaudio value="music" maxtime="5s" />
<reinvite direction="Both" />
<playaudio value="music" maxtime="5s" />
<exit />
</on>
Script for call receiver:
<accept />
<playaudio value="music" />
Simulating REFER (call transfer)
Script for call generator:
<call value="sip:2222@server.com:5060"/>
<on event="answer">
<wait value="100s" />
<exit />
</on>
Script for call receiver:
<accept />
<wait value="5s" />
<block test="$calledId; != redirected">
<transfer value="sip:redirected@server.com:5060" mode="blind" />
</block>
<exit />
Identification of IVR messages
This script recognizes audio signal in RTP stream, compares it with list of predefined WAV/MP3 files.
The resuts are saved into variables and to CDR report.
Audio verification is used to test IVR menus and check performance of IVR servers.
<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;" />
PESQ MOS (mean opinion score) audio quality measurement
This script measures audio quality of IVR message which is played by destination server
<verifyaudio reference="speech.wav" maxtime="10s" mosvar="mos" />
<log value="MOS = $mos;" />
<writecdr header="MOS" value="$mos;" numeric="true" qualityIsAscending="true" />
Client-server-client audio path verification
If SIP Tester is installed on both server side and on client side, it could be configured to test IP network for ability to pass
RTP audio correctly.
- Client-side SIP Tester generates SIP calls, transmits RTP audio to the server-side SIP Tester
- Server-side SIP Tester accepts SIP calls, receives RTP audio and plays exactly same audio back to client (creates loopback connection)
<accept />
<loopbackaudio />
If there is a NAT, you should set settings "SymmetricSIP" = "1" and "SymmetricRTP" = "1" on server-side SIP Tester
- Client-side SIP Tester verifies the received audio if it equals to what it transmitted
<call value="sip:test@server.com" maxringtime="60s" />
<on event="answer">
<playaudio value="speech.wav" dontwait="true" />
<verifyaudio reference="speech.wav" maxtime="15s" confidencevar="confidence" />
<writecdr header="CONFIDENCE" value="$confidence;" numeric="true" qualityIsAscending="true" />
<exit/>
</on>
Checking availability of SIP server using command line interface (CLI)
This script makes SIP call to a server and returns SIP status code into .bat file.
CallXML file (c:\srcipt.xml)
<callxml>
<log value="calling SIP server: $serverUri;" />
<call value="$serverUri;" />
<on event="answer">
<log value="SIP server has answered to call"/>
<playaudio value="music" repeat="10000" maxtime="20s" />
<setexitcode value="200"/>
<exit />
</on>
<on event="callfailure">
<log value="call failed with status = $eventSubType;" />
<setexitcode value="$eventSubType;" />
</on>
</callxml>
test.bat file launches SIP Tester via CLI, passes server SIP URI as parameter, makes 2 calls to the server and reports status of last SIP call.
StarTrinity.SIPTester.CLI.exe TotalCalls 2 serverUri sip:100@192.168.1.1:5060 OutgoingCallXmlFile "c:\script.xml"
echo SIP status code is %ERRORLEVEL%
Verifying list of accounts using SIP REGISTER
The script is used by VoIP resellers to verify millions of SIP accounts to determine which are valid and which are not.
Users and passwords are read from CSV file c:\siptester_files\users.csv.
Results of testing are saved to users_suceeded.csv and users_failed.csv files.
You can change file names and format of files by editing the script.
For current date, SIP Tester is able to verify about 500-1000 users per second on an average i3 desktop PC.
<readcsv value="c:\siptester_files\users.csv" var0="user" var1="password" />
<register value="sip:sipserver.com:5060?user=$user;&password=$password;" var="result" delayvar="delay" />
<report value="$delay;" name="REGISTER response delay" qualityIsAscending="false" />
<report value="$result;" name="REGISTER result" qualityIsAscending="false" />
<block test="$result; = 200">
<writefile fileName="c:\siptester_files\users_suceeded.csv" newLine="true" value="$user;;$password;" />
<exit/>
</block>
<writefile fileName="c:\siptester_files\users_failed.csv" newLine="true" value="$user;;$password;;$result;" />
Verifying list of accounts using SIP INVITE
The script reads SIP URIs line by line from a text file C:\siptester_files\sipUris.txt
and sends SIP INVITE messages (generates test calls) to check accounts on one or multiple servers.
Results are saved to 2 separate files for suceeded and failed calls.
SIP tester is able to generate about 200-500 calls per second on an average desktop i3 PC
<readcsv value="C:\siptester_files\sipUris.txt" var0="sipUri" />
<call value="$sipUri;" sendSdpInInitialInvite="false" />
<on event="answer">
<writefile newLine="true" fileName="C:\siptester_files\suceeded.txt" value="$sipUri;" />
<exit />
</on>
Playing random WAV file for incoming calls
<wait value="$rand(9,50);s" />
<assign var="fn" value="$rand_from_options;">
<option value="wav\incoming01.wav" />
<option value="wav\incoming02.wav" />
<option value="wav\incoming03.wav" />
</assign>
<accept />
<playaudio value="$fn;" />
<exit />
Writing custom CDR files for incoming calls using <writefile />
<assign var="aNumber" value="$callerId;" />
<assign var="bNumber" value="$calledId;" />
<assign var="redirectedNumber" value="$redirectedNumber;" />
<assign var="callStart" value="$time();" />
<block probability="0.2">
<accept />
<assign var="callEnd" value="$time();" />
<disconnect />
<writefile newLine="true" fileName="F:\ftproot\ACCEPTED.txt" splitInterval="10m"
value="$callStart;;$callEnd;;$aNumber;;$bNumber;;$redirectedNumber;" />
<exit/>
</block>
<reject value="503"/>
<assign var="callEnd" value="$time();" />
<writefile newLine="true" fileName="F:\ftproot\REJECTED.txt" splitInterval="10m"
value="$callStart;;$callEnd;;$aNumber;;$bNumber;;$redirectedNumber;" />
<exit/>
Calling list of B numbers from CSV file with regular expression filter
The script is used to verify connectivity and billing in a customer's VoIP system. A and B numbers are read from custom CSV files:
a_numbers.csv - one column with A numbers; b_numbers.csv - 1st column with B numbers, 2nd column with number of call attempts for each B number.
CDR reports are saved into folder F:\ftproot in custom format. The CDRs files are separate for suceeded and failed SIP calls.
Additionally, SIP Tester splits the files every 10 minutes.
<readcsv value="a_numbers.csv" var0="numA" mode="random" />
<block test="$numA; matches ^509.+" >
<log value="skipping this number because it matches pattern 509xxx" />
<exit />
</block>
<block test="$numA; matches ^00509.+" >
<log value="skipping this number because it matches pattern 00509xxxx" />
<exit />
</block>
<readcsv value="b_numbers.csv" var0="numB" countsColumnIndex="1" repeat="1" mode="random" />
<log value="calling from $numA; to $numB;" />
<call value="sip:$numB;@10.10.1.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="10m" value="$callStart;;$callEnd;;$numA;;$numB;" />
<on event="hangup">
<assign var="callEnd" value="$time();" />
<writefile newLine="true" fileName="ftproot\SUCEEDED.txt" splitInterval="10m" 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="10m" 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="10m" value="$callStart;;$callEnd;;$numA;;$numB;" />
</on>
Calling list of A and B numbers from 2 CSV file (2 countries) via 2 servers
The script is used to generate test VoIP traffic to multiple countries via multiple servers (your softswitches), reading A and B numbers from
separate CSV files (one CSV file per country). CSV files contain 2 columns: B number (called ID) in 1st column and A number (caller ID) in 2nd column.
The scripts limits number of concurrent calls (channels) per country. When call is answered, a random audio is played from directory with wav files
<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>
Generating DTMF tones for incoming calls
The script answers to incoming calls and generates a DTMF tone signals
<accept />
<playdtmf value="1" />
<wait value="500ms" />
<playdtmf value="2" />
<wait value="500ms" />
<playdtmf value="3" />
<wait value="500ms" />
<exit />
Playing different IVR messages for incoming calls based on Called ID
<accept />
<if test="$calledId; startswith 44">
<log value="Called number starts with 44" />
<playaudio value="IVR1.wav" />
<exit />
</if>
<if test="$calledId; startswith 1">
<log value="Called number starts with 1" />
<playaudio value="IVR2.wav" />
<exit />
</if>
<playaudio value="IVR3.wav" />
<exit />
Randomly simulate T.38 fax CED tone to test auto-dialer fax machine detector
<log value="received incoming call" />
<accept />
<wait value="3s" />
<block probability="0.1">
<log value="simulating fax for this call" />
<writecdr header="simulated_fax" value="1" />
<receivefax />
<exit/>
</block>
<log value="playing audio for this call" />
<writecdr header="simulated_fax" value="0" />
<playaudio value="music.wav" maxtime="$rand(100);s" />
<exit/>
Specifying RTP port numbers explicitly for incoming and outgoing calls
<!-- script for outgoing calls: port numbers 7000..7990 -->
<assign globalvar="portCounter1" mathvalue="$global.portCounter1; + 2" />
<if test="$global.portCounter1; > 990"> <assign globalvar="portCounter1" value="0"/> </if>
<assign var="port" mathvalue="$global.portCounter1; + 7000" />
<log value="using RTP port $port; for outgoing call" />
<call value="sip:111@10.10.10.1:5060" callerId="1111" localRtpPort="$port;" />
<on event="answer">
<playaudio value="music.wav" maxtime="50s" />
</on>
<!-- script for incoming calls: port numbers 8000..8990 -->
<assign globalvar="portCounter2" mathvalue="$global.portCounter2; + 2" />
<if test="$global.portCounter2; > 990"> <assign globalvar="portCounter2" value="0"/> </if>
<assign var="port" mathvalue="$global.portCounter2; + 8000" />
<log value="using RTP port $port; for incoming call" />
<accept localRtpPort="$port;" />
<playaudio value="music2.wav" repeat="infinite" maxtime="20000ms" />
<exit />
Making a pause in test if destination server fails
<movingAverageGet id="callSetupRatio" var="csr" />
<log value="current call setup ratio MA100 = $csr;" />
<if test="$csr; < 0.6">
<log value="CSR is less than threshold (0.6): stopping call generator, waiting 20 seconds" />
<stopcallgenerator />
<wait value="20s" />
<log value="starting call generator after a pause" />
<movingAverageReset id="callSetupRatio" />
<startcallgenerator />
<exit />
</if>
<call value="sip:test@10.10.10.1:5060" />
<on event="answer">
<movingAveragePut id="callSetupRatio" size="100" value="1" />
<wait value="1s" />
<exit />
</on>
<on event="callfailure">
<movingAveragePut id="callSetupRatio" size="100" value="0" />
</on>
Simulating sinusoid-type variable call load
<assign var="numberOfConcurrentCalls" mathvalue="120 + 100 * sin(($timeOfDayInHours(); - 10) / 24 * 360)" />
<setcallgeneratorparams maxconcurrentcalls="$numberOfConcurrentCalls;" />
<call value="sip:test@10.10.10.1:5060" />
<on event="answer">
<wait value="100s" />
<exit />
</on>
Combining SUBSCRIBE, PUBLISH, INVITE tests in a single CallXML script
<block minInterval="142ms">
<readcsv value=".\SubscribeList.csv" var0="Device" var1="DevName" repeat="infinite" />
<sendsipmessage>
<![CDATA[SUBSCRIBE sip:$Device;@sip.domain.com:5060 SIP/2.0
Via: SIP/2.0/UDP 1.2.3.4:5060;branch=z9hG4bK13054182
From: $DevName; <sip:$Device;@sip.domain.com:5060>;tag=1641318497
To: <sip:$Device;@sip.domain.com:5060>
Call-ID: 0_2505407707@1.2.3.4
CSeq: 1 SUBSCRIBE
Contact: <sip:$Device;@1.2.3.4:5060>
Accept: application/reginfo+xml
Max-Forwards: 70
User-Agent: Yealink SIP-T21P_E2 52.80.0.95
Expires: 3630
Event: dialog
Content-Length: 0
]]>
</sendsipmessage>
<exit/>
</block>
<block minInterval="1000ms">
<readcsv value=".\PublishList.csv" var0="PubDevice" var1="PubDevName" repeat="infinite" />
<sendsipmessage>
<![CDATA[PUBLISH sip:$PubDevice;@sip.domain.com SIP/2.0
Via: SIP/2.0/UDP 1.2.3.4:5060;branch=z9hG4bK03a3d1e310f928d0
From: $PubDevName; <sip:$PubDevice;@sip.domain.com>;tag=6e52f3725c8bd4bb
To: <sip:$PubDevice;@sip.domain.com>
Supported: path
Call-ID: f477f1f9e55aa8fc@1.2.3.4
CSeq: 1 PUBLISH
User-Agent: Grandstream GXP2000 1.2.5.3
Max-Forwards: 70
Allow: INVITE,ACK,CANCEL,BYE,NOTIFY,REFER,OPTIONS,INFO,SUBSCRIBE,UPDATE,PRACK,MESSAGE
Expires: 300
Event: presence
SIP-If-Match: iK0rghih
Content-Length: 0
]]>
</sendsipmessage>
<exit/>
</block>
<block minInterval="200ms">
<readcsv value=".\InviteList.csv" var0="callerIdFromCsv" var1="calledIdFromCsv" mode="random" repeat="infinite" />
<call value="sip:$calledIdFromCsv;@sip.domain.com" callerId="$callerIdFromCsv;" />
<exit/>
</block>
Combining INVITE and REGISTER tests in a single CallXML script (#1)
<assign var="destinationHost" value="192.168.0.216" />
<assign var="password" value="test1234" />
<assign var="extensionsCount" value="100" />
<assign var="baseExtensionId" value="3010" />
<assign var="extensionId" mathvalue="$baseExtensionId; + ($Id; % $extensionsCount;)" />
<log value="testing extension $extensionId;" />
<block minInterval="100ms">
<call value="sip:07042643699@$destinationHost;?user=$extensionId;&password=$password;">
<on event="answer" > <playaudio value="music.wav" repeat="10000" maxtime="$rand(20000);ms" /> </on>
</call>
</block>
<block minInterval="200ms">
<register value="sip:$extensionId;@$destinationHost;?user=$extensionId;&password=$password;" expires="3600" var="status" delayvar="delay" />
<log value="REGISTER: received response code = $status;, delay = $delay;ms" />
</block>
Combining INVITE and REGISTER tests in a single CallXML script (#2)
<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; " />
<assign var="repeatCounter1mod5" mathvalue="$repeatCounter1; % 5" />
<if test="$repeatCounter1mod5; == 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>
Generating and receiving video+audio SIP calls
Generate call:
<call maxringtime="30s" value="sip:13108790819@192.168.10.5:5070" videoRtpmapEncodingName ="H264" videoPcapFileName ="sample_H264.pcap" videoSdpLines="a=fmtp:99 profile-level-id=42e00a; packetization-mode=1; max-br=452; max-mbps=11880" >
<on event="answer">
<playaudio value="music.wav" repeat="infinite" maxtime="30s" />
<exit />
</on>
</call>
Receive call:
<accept value="200" videoRtpmapEncodingName ="H264" videoPcapFileName ="sample_H264.pcap" videoSdpLines="a=fmtp:99 profile-level-id=42e00a; packetization-mode=1; max-br=452; max-mbps=11880" />
<playaudio value="music.wav" repeat="infinite" maxtime="30s" />
<exit />
Generate call with custom video RTP payload type:
<setsetting name="VideoSdpPayloadType" value="126" />
<call maxringtime="30s" value="sip:13108790819@192.168.10.5:5070"
videoRtpmapEncodingName ="H264"
videoPcapFileName ="sample_H264.pcap"
videoSdpLines="a=fmtp:99 profile-level-id=42e00a; packetization-mode=1; max-br=452; max-mbps=11880" >
<on event="answer">
<playaudio value="music.wav" repeat="infinite" maxtime="30s" />
<exit />
</on>
</call>
Receive call with custom video RTP payload type:
<setsetting name="VideoSdpPayloadType" value="126" />
<accept value="200" videoRtpmapEncodingName ="H264" videoPcapFileName ="sample_H264.pcap"
videoSdpLines="a=fmtp:99 profile-level-id=42e00a; packetization-mode=1; max-br=452; max-mbps=11880" />
<playaudio value="music.wav" repeat="infinite" maxtime="30s" />
<exit />
Generating and receifing audio SIP calls with custom audio codec, with playback from .pcap file
Generate call (in this example OPUS audio codec is used):
<call maxtime="10000ms" callerId="" value="sip:13108790819@192.168.10.5:5070" sdpAttributes="rtpmap:99 opus/48000" codec="99" />
<on event="answer">
<playaudio value="sample_opus_48000.pcap" repeat="10000" maxtime="20000ms" />
<exit />
</on>
Receive call (in this example OPUS audio codec is used):
<accept sdpAttributes="rtpmap:99 opus/48000" codec="99" />
<playaudio value="sample_opus_48000.pcap" repeat="infinite" maxtime="20000ms" />
<exit />
Using a custom formula to measure MOS score (different from G.107)
Please use following CallXML scripts at call generator and receiver running at 2 different servers at 2 locations, to test quality of IP network between the servers.
Script for call generator side: please change "192.168.10.50" to IP address of call receiver server. "10m" means max duration of call = 10 minutes.
<callxml>
<call value="sip:100@192.168.10.50:5070" codec="G711U">
<on event="answer">
<playaudio value="music.wav" maxtime="10m" />
<getrtpmeasurements />
<log value="MOS calculation inputs: RTT: $RTCP_RTT_Mean;ms mean jitter: $RTP_Called_MeanRfc3550Jitter;ms packet loss: $RTP_Called_LostPackets;%" />
<assign var="effectiveLatency" mathvalue="$RTCP_RTT_Mean; + $RTP_Called_MeanRfc3550Jitter; * 2 + 10" />
<if test="$effectiveLatency; < 160"> <assign var="R" mathvalue="93.2 - ($effectiveLatency; / 40)" /> </if>
<else> <assign var="R" mathvalue="93.2 - (($effectiveLatency; - 120) / 10)" /> </else>
<assign var="R" mathvalue="$R; - (2.5 * $RTP_Called_LostPackets;)" />
<assign var="MOS" mathvalue="1 + 0.035 * $R; + (0.000007) * $R; * ($R; - 60) * (100 - $R;)" />
<log value="MOS calculation results: effectiveLatency=$effectiveLatency; R=$R; MOS=$MOS;" />
<writecdr header="MOS" value="$MOS;" numeric="true" qualityIsAscending="true" />
<exit />
</on>
</call>
</callxml>
Script for call receiver:
<callxml>
<accept >
<playaudio value="music.wav" maxtime="10m" />
<getrtpmeasurements />
<log value="MOS calculation inputs: RTT: $RTCP_RTT_Mean;ms mean jitter: $RTP_Caller_MeanRfc3550Jitter;ms packet loss: $RTP_Caller_LostPackets;%" />
<assign var="effectiveLatency" mathvalue="$RTCP_RTT_Mean; + $RTP_Caller_MeanRfc3550Jitter; * 2 + 10" />
<if test="$effectiveLatency; < 160"> <assign var="R" mathvalue="93.2 - ($effectiveLatency; / 40)" /> </if>
<else> <assign var="R" mathvalue="93.2 - (($effectiveLatency; - 120) / 10)" /> </else>
<assign var="R" mathvalue="$R; - (2.5 * $RTP_Caller_LostPackets;)" />
<assign var="MOS" mathvalue="1 + 0.035 * $R; + (0.000007) * $R; * ($R; - 60) * (100 - $R;)" />
<log value="MOS calculation results: effectiveLatency=$effectiveLatency; R=$R; MOS=$MOS;" />
<writecdr header="MOS" value="$MOS;" numeric="true" qualityIsAscending="true" />
<exit />
</callxml>
SIPREC: generate SIP calls with 2 RTP streams and play stereo WAV file
The SIP Tester software simulates a SIPREC session recording client (SRC) and generates SIP calls to a session recording server (SRS), plays RTP streams from stereo WAV file.
INVITE contains a mumtipart/mixed body with SDP and "recording-session" XML. The "recording-session" XML is configured in script.
<callxml>
<call maxringtime="30s" value="sip:test@your_ip:5080?transport=tcp" callerId="acmeSrc" mode="siprec" headers="Require=siprec" direction="SendOnly" sdpAttributes="label:218110433" sdpAttributes2="label:218110434">
<on event="answer">
<playaudio value="C:\your_stereo_file_8khz_16bit.wav" mode="siprec" maxtime="50s" />
<playaudio value="C:\your_mono_file_for_RTP_stream_1.wav" mode="" maxtime="10s" />
<playaudio value="C:\your_mono_file_for_RTP_stream_2.wav" mode="siprec2" maxtime="10s" />
<exit />
</on>
<additionalMultipartContent lineBreak="\n">
<![CDATA[Content-Type: application/rs-metadata+xml
Content-Disposition: recording-session
<?xml version='1.0' encoding='UTF-8'?>
<recording xmlns='urn:ietf:params:xml:ns:recording'>
<datamode>complete</datamode>
<session id="x">
<associate-time>2021-08-10T05:33:55</associate-time>
<extensiondata xmlns:apkt=http://acmepacket.com/siprec/extensiondata>
<apkt:ucid>x3;encoding=hex</apkt:ucid>
<apkt:callerOrig>true</apkt:callerOrig>
</extensiondata>
</session>
<participant id="x" session="x">
<nameID aor=sip:x@3.3.3.3>
<name>x</name>
</nameID>
<send>x</send>
<associate-time>2021-08-10T05:33:55</associate-time>
<extensiondata xmlns:apkt=http://acmepacket.com/siprec/extensiondata>
<apkt:callingParty>true</apkt:callingParty>
<apkt:request-uri>sip:x@4.4.4.4:5060</apkt:request-uri>
<apkt:realm>x</apkt:realm>
<apkt:header label="Session-ID">
<value>x;remote=00000000000000000000000000000000</value>
</apkt:header>
</extensiondata>
</participant>
<participant id="y" session="y">
<nameID aor=sip:y@4.4.4.4>
<name>y</name>
</nameID>
<send>y</send>
<associate-time>2021-08-10T05:33:55</associate-time>
<extensiondata xmlns:apkt=http://acmepacket.com/siprec/extensiondata>
<apkt:callingParty>false</apkt:callingParty>
</extensiondata>
</participant>
<stream id="z" session="z">
<label>218110433</label>
<mode>separate</mode>
<associate-time>2021-08-10T05:33:55</associate-time>
</stream>
<stream id="FamKUgaTRE9xYVrZsj5GWQ==" session="z">
<label>218110434</label>
<mode>separate</mode>
<associate-time>2021-08-10T05:33:56</associate-time>
</stream>
</recording>
]]>
</additionalMultipartContent>
</call>
</callxml>
Check if numbers from list are dialable (ringing) or not and save report to file
Reads some specific list of numbers, check the number is dialable or not. Save report to file. If call is answered, drop the call immediately. Also drop the call when got "ringing" signal.
<callxml>
<readcsv value="c:\numbers.txt" repeat="1" skipHeaders="false" var0="numB"/>
<call maxringtime="10000ms" callerId="" value="sip:$numB;@mehedi1-5121-dev.sip.us1.twilio.com:5060">
</call>
<on event="pr:180;pr:183;answer">
<writefile newLine="true" fileName="c:\numbers_good.txt" value="$numB;" />
<exit />
</on>
</callxml>
OTT bypass, other international bypass fraud detection
Looped traffic generation
Sample CallXML Scripts for StarTrinity Softswitch
Simple IVR-based filter
Play IVR files 0.wav, 2.wav, ... 99.wav sequentially, in loop
CallXML script for originator in StarTrinity softswitch (menu - configuration - originators - originator details - set "callxml script type" = "custom" - enter the script).
Accept the call (send 200 OK) immediately, play 100 files (the number 100 is configurable in script) sequentially from folder C:\WAV\.
For every new call the counter is incremented and next audio file is played.
<callxml type="custom" >
<accept/>
<if test="'$global.originator1_counter;' == ''">
<assign globalvar="originator1_counter" value="0" />
</if>
<else>
<assign globalvar="originator1_counter" mathvalue="($global.originator1_counter;+1)%100" />
</else>
<playaudio value="C:\WAV\$global.originator1_counter;.wav" repeat="infinite" />
<exit/>
</callxml>
Record the call (B side) for 20 seconds, end call leg B in 60 seconds, infinitely play recording
CallXML script for originator in StarTrinity softswitch (menu - configuration - originators - originator details - set "callxml script type" = "custom" - enter the script).
<assign var="recordedFileName" value="C:\Recordings\$time(yyyyMMdd);\$time(HH_mm_ss_fff);_$calledId;.wav" />
<recordcall value="100" mode="tx" uri="$recordedFileName;" />
<settimeout value="20s"> <recordcall value="0" /> </settimeout>
<transfer terminators="terminator1" maxansweredtime="60s" />
<on event="maxansweredtime">
<playaudio value="$recordedFileName;" repeat="infinite" />
<exit />
</on>
Send DTMF digit some time after connection
Script for user of multi-tenant softswitch. Note that you need to set field "CallXML variables" to "send_dtmf=true" for originators where you want to enable this feature.
<callxml>
<transfer terminators="routed">
<on event="answer">
<if test="$send_dtmf;" >
<wait value="15s" />
<playdtmf value="5" />
</if>
</on>
</transfer>
<exit/>
</callxml>
Blacklist caller RTP IP addresses that do not send RTP, to increase ACD of dialer traffic
CallXML script for originator in StarTrinity softswitch (menu - configuration - originators - originator details - set "callxml script type" = "custom" - enter the script).
<callxml type="custom">
<getrtpinfo />
<dynamicblacklist id="$originatorId;_rtpip" value="$RTP_Remote_IP;" var="badCallsCountFromThisRtpIp" add="false" maxtime="1h" />
<log value="[$calledId;] RTP IP = $RTP_Remote_IP;: bad calls count = $badCallsCountFromThisRtpIp;" />
<if test="$badCallsCountFromThisRtpIp; > 0">
<log value="[$calledId;] rejected call with RTP from $RTP_Remote_IP;" />
<reject value="503" />
<exit />
</if>
<transfer terminators="routed" />
<on event="hangup;localHangup">
<getrtpinfo />
<if test="$RTP_ExpectedDuration_ms; > 500 and $RTP_AfterJbDuration_ms; < 200">
<log value="[$calledId;] added $RTP_Remote_IP; to blacklist: RTP_ExpectedDuration=$RTP_ExpectedDuration_ms;ms, RTP_AfterJbDuration=$RTP_AfterJbDuration_ms;ms" />
<dynamicblacklist id="$originatorId;_rtpip" value="$RTP_Remote_IP;" />
</if>
</on>
</callxml>
Overwrite B numbers and make sure that number B is unique
CallXML script for originator in StarTrinity softswitch (menu - configuration - originators - originator details - set "callxml script type" = "custom" - enter the script).
The number lists can be uploaded via HTTP POST API method "UploadNumberList".
<callxml type="custom">
<assign var="c" value="0" />
<readnumberlist value="01.txt" var0="b" mode="random" label="retry"/>
<ifcallexists calledId="$b;">
<assign var="c" mathvalue="$c; + 1" />
<if test="$c; > 5"> <reject value="503" /> </if>
<goto value="retry" />
</ifcallexists>
<transfer value="$b;" terminators="routed" />
</callxml>
Play ringback tone immediately when received a call, don't wait for call leg B (using "183 Session Progress" early media)
CallXML script for originator in StarTrinity softswitch (menu - configuration - originators - originator details - set "callxml script type" = "custom" - enter the script).
Answer with "183 session progress" ("alerting") to call leg A after some random waiting time (1..3 seconds) and play a ringback tone from wav file in a loop.
Also, make call to terminators according to routing configuration.
<callxml type="custom">
<settimeout value="$rand(2000,4000);ms">
<accept value="180" />
<wait value="$rand(20,50);ms" />
<accept value="183" />
<wait value="50ms" />
<playaudio value="rbt$rand(1,3);.wav" dontwait="true" repeat="infinite" leg="A" />
</settimeout>
<transfer terminators="routed" proxyPR="false" proxyRingbacktone="false"/>
<on event="answer">
<stopaudio />
</on>
</callxml>
Play ringback tone immediately when received a call, don't wait for call leg B (using "180 Ringing")
CallXML script for originator in StarTrinity softswitch (menu - configuration - originators - originator details - set "callxml script type" = "custom" - enter the script).
Answer with "180 Ringing" to call leg A after some random waiting time (1..3 seconds).
Then make call to terminators according to routing configuration.
<callxml type="custom">
<wait value="$rand(1000,3000);ms" />
<accept value="180" />
<transfer terminators="routed" />
</callxml>
Request HLR to filter VoIP traffic (reduce SIM blocking)
CallXML script for originator in StarTrinity softswitch (menu - configuration - originators - originator details - set "callxml script type" = "custom" - enter the script).
Make API requests to hlrlookup.com: 1) validate caller number (A, CLI) 2) check status of destination number (B, CLD). Reject call with 503 if HLR request fails. Note: please put valid API key and password from hlrlookup.com
<callxml type="custom">
<accept value="180" />
<sendhttprequest value="https://www.hlrlookup.com/api/validate/?apikey=aaaaaaa&password=bbbbbb&msisdn=$callerId;" statusvar="status1" contentvar="result1" />
<log value="api request#1 (validation) for msisdn=$callerId;: status=$status1; result=$result1;" />
<if test="($result1; contains "Status":"Valid") == false" >
<log value="rejecting call: number $callerId; is not valid" />
<reject value="503" />
<exit/>
</if>
<substring var="calledId2" value="$calledId;" startIndex="2" />
<sendhttprequest value="https://www.hlrlookup.com/api/hlr/?apikey=aaaaaaaa&password=bbbbb&msisdn=$calledId2;" statusvar="status2" contentvar="result2" />
<log value="api request#2 (HLR status) for msisdn=$calledId;: status=$status2; result=$result2;" />
<if test="($result2; contains "error_text":"Live") == false" >
<log value="rejecting call: number $calledId; is not live (HLR)" />
<reject value="503" />
<exit/>
</if>
<transfer terminators="routed" />
</callxml>
Caller early media filter for VoIP traffic (reduce SIM blocking)