sipp分支场景实现
场景分析
当对voip设备进行sipp相关场景测试的时候,往往得先模拟注册,使得终端设备注册成功。才可以继续接下来的场景测试。
例如:需要测试INVITE呼叫正常流程。就需要先REGISTER注册,终端再进行INVITE呼叫。
- 先执行RecvREGSend200OK.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario>
<scenario name="REGISTER">
<recv request="REGISTER">
</recv>
<send>
<![CDATA[
SIP/2.0 200 OK
[last_From:]
[last_To:];tag=asdfa3123w
[last_Call-ID:]
[last_CSeq:]
[last_Via:]
Expires:3600
]]>
</send>
</scenario>
- 再执行RecvInviteSendTryRing200OK.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario>
<scenario name="INVITE">
<recv request="INVITE">
</recv>
<send>
<![CDATA[
SIP/2.0 100 Trying
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
Content-Length: 0
]]>
</send>
<send>
<![CDATA[
SIP/2.0 180 Ringing
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
CSeq: 1 INVITE
Content-Length: 0
]]>
</send>
<send>
<![CDATA[
SIP/2.0 200 OK
[last_Via:]
[last_From:]
[last_To:]
[last_Call-ID:]
[last_CSeq:]
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Content-Type: application/sdp
Content-Length: [len]
v=0
o=sipp 123456 123456 IN IP4 [local_ip]
s=-\d+\s-\d+ SIPp\s\d+\.\d+\.\d+
c=IN IP4 [local_ip]
t=0 0
m=audio [local_port] RTP/AVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
]]>
</send>
<recv request="ACK">
</recv>
</scenario>
使用中发现:当我每次调试设备后,设备都需要先注册,然后才可以进行INVITE测试。也就是我需要再每次调试之前去切换xml文件执行(因为不可以同时运行两个xml)。过程很麻烦,要切换xml文件。
分支场景实现
于是,我使用label和next进行场景跳转,避免xml切换。这样就可以运行一次xml就不用管了,放心调试设备。如下:test.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario>
<!-- sipp> sipp -sf ./test.xml -i ${local_ip} -s ${remote_number} ${remote_ip}:${remote_port} -m 次数 -->
<scenario name="main">
<label id="main"/>
<recv request="REGISTER" optional="true" next="REGISTER">
</recv>
<recv request="INVITE" next="INVITE">
</recv>
<label id="REGISTER"/>
<send next="main">
<![CDATA[
SIP/2.0 200 OK
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
[last_Via:]
Expires:3600
]]>
</send>
<label id="INVITE"/>
<send>
<![CDATA[
SIP/2.0 100 Trying
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
Content-Length: 0
]]>
</send>
<send>
<![CDATA[
SIP/2.0 180 Ringing
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_CSeq:]
Content-Length: 0
]]>
</send>
<send>
<![CDATA[
SIP/2.0 200 OK
[last_Via:]
[last_From:]
[last_To:]
[last_Call-ID:]
[last_CSeq:]
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Content-Type: application/sdp
Content-Length: [len]
v=0
o=sipp 123456 123456 IN IP4 [local_ip]
s=-\d+\s-\d+ SIPp\s\d+\.\d+\.\d+
c=IN IP4 [local_ip]
t=0 0
m=audio [local_port] RTP/AVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
]]>
</send>
<recv request="ACK">
</recv>
</scenario>
其实就是将两个xml场景合并在了一起,使用label标识,然后用next跳转。结构大致如下:
- <label id=“main”/>
main区域主要负责请求接收的处理,是开始的锚点- <recv request=“REGISTER” optional=“true” next=“REGISTER”/>
optional="true"表示该请求可选执行,也就是可被忽略。(不写optional,默认就是false,不可忽略,必须执行) 该句逻辑:等待到了REGISTER的注册请求,就跳转到REGISTER响应的部分。即发送200OK
- <recv request=“INVITE” next=“INVITE”/>
该句逻辑:等待INVITE的通话请求,如果没有就阻塞在这里;如果有就跳转INVITE响应部分,即trying-ringing-200OK。
- <recv request=“REGISTER” optional=“true” next=“REGISTER”/>
- <label id=“REGISTER”/>
该部分就是回复200OK后需要回到起点,因为继续执行是会不符合测试逻辑的 - <label id=“INVITE”/>
该部分就是回复INVITE部分。
实现的关键思路就是:两个场景label(可选场景+必选场景),一个开始锚点label;可选场景开始并且响应必须回到开始锚点label;必选场景跟在可选场景后,起到阻塞运行的作用,避免xml执行有问题
出现的问题
' before sequence without a mandatory message. Please remove one ‘optional=true’ (element 4)
原因:两个request请求都是optional,就会导致直接发送200OK,是错误的!
180 Ringing不响铃
少写了Call-ID,暂定等待响铃5s
<send>
<![CDATA[
SIP/2.0 180 Ringing
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
Content-Length: 0
]]>
</send>
<pause milliseconds="5000"/>
补充
SIPp手册提供的:
下面这个例子,就是用正则表达式对响应进行匹配,符合条件就会赋值给变量8,然后就跳转。效果即在From中有ua25就会跳过等待5s的机制(不需要等待5s了)
<recv response="200">
<action>
<ereg regexp="ua25" search_in="hdr" header="From: " assign_to="8"/>
</action>
</recv>
<!-- set variable 8 above on 25th call, send the ACK but skip the pause for it -->
<send next="1" test="8">
<![CDATA[省略]]>
</send>
<pause milliseconds="5000"/>
<label id="1"/>
REF:branchc.xml
总结
反正说的这么文邹邹的,难免头痛。直接运行调试该test.xml就懂了!