SIPp分支场景实现

sipp分支场景实现

场景分析

当对voip设备进行sipp相关场景测试的时候,往往得先模拟注册,使得终端设备注册成功。才可以继续接下来的场景测试。
例如:需要测试INVITE呼叫正常流程。就需要先REGISTER注册,终端再进行INVITE呼叫。

  1. 先执行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>
  1. 再执行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跳转。结构大致如下:

  1. <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。
      
  2. <label id=“REGISTER”/>
    该部分就是回复200OK后需要回到起点,因为继续执行是会不符合测试逻辑的
  3. <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就懂了!

相关推荐

  1. Git实际应用场景分析

    2024-03-27 15:26:02       36 阅读
  2. golang使用sip实现语音通话

    2024-03-27 15:26:02       56 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-27 15:26:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-27 15:26:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-27 15:26:02       87 阅读
  4. Python语言-面向对象

    2024-03-27 15:26:02       96 阅读

热门阅读

  1. Facebook多个广告账户被封禁的原因及解决方法

    2024-03-27 15:26:02       39 阅读
  2. 简明 Python 教程(第7章 数据结构)

    2024-03-27 15:26:02       37 阅读
  3. 嵌入式学习笔记(四)

    2024-03-27 15:26:02       30 阅读
  4. ocs2安装

    2024-03-27 15:26:02       38 阅读
  5. LeetCode //C - 704. Binary Search

    2024-03-27 15:26:02       46 阅读
  6. 008-如何支持各种语言的项目

    2024-03-27 15:26:02       43 阅读
  7. unity中平台判断

    2024-03-27 15:26:02       40 阅读