sipp是一个针对SIP协议进行测试的免费开源工具,可运行于windows/mac/linux,官方地址:http://sipp.sourceforge.net/

一、安装

本文只介绍mac上的安装方式,其它平台(windows/linux)的安装,可参考官方文档 (注:感谢黄龙舟做的中文翻译)

brew install sipp

mac上,直接用brew 一行命令搞定安装,完成后,可用sipp -v查看版本号,参见下图,目前的版本号是SIPp v3.6.0-PCAP-RTPSTREAM

二、uac/uas初体验

安装好以后,相信大家已经等不及要体验一把,既然是打电话,就得有“主叫方(uac)”和“被叫方(uas)” (注:对uac、uas第1次接触的同学,建议先移步 SIP协议学习笔记 )

2.1 启动内置的uas场景

sipp -sn uas

如上图所示,启动uas后,会在本机开1个端口5061,然后下面会一些SIP信令的实时统计,INVITE文字在“右方向箭头”右侧,表示当前收到的INVITE请求数,180左侧的“左方向箭头”表示回应的振铃消息数。现在只有被叫,并没有主叫来电,所以Messages这一栏全是0

2.2 启动内置的uac场景

sipp -sn uac 127.0.0.1:5061

注:最后的“ip:端口”,即为上一步uas启动的ip地址和端口号,必须匹配。

此时,再回到uas的界面,Messages栏,就不再全是0了

这样,主叫方(uac)打电话,被叫方(uas)接电话,基本的呼叫流程就通了。

三、理解配置文件

流程虽然跑通了,可能有同学会好奇,uas/uac这2个内置场景,具体逻辑长啥样?为什么uac的界面,会有100/180/183这些响应码,没有其它4xx或5xx之类的码?除uac/uas,还有其它内置场景吗?

如上图,直接输入sipp,会看到有很多参数说明,其中-sn 表示加载默认的场景,除了uas/uac,还有regexp/branchc/branchs...等其它场景,有兴趣的同学可以每种场景都试一下。

另外,还有一个很有用的-sd参数,可以把默认的场景配置,直接导出来,参考下面的命令:

这样,就把默认的uac/uas这2个场景,导出成xml文件,方便后续研究。打开这2个文件看一下:

3.1 uac.xml

 1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2 <!DOCTYPE scenario SYSTEM "sipp.dtd">
3
4 <scenario name="Basic Sipstone UAC">
5 <send retrans="500">
6 <![CDATA[
7
8 INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
9 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
10 From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
11 To: [service] <sip:[service]@[remote_ip]:[remote_port]>
12 Call-ID: [call_id]
13 CSeq: 1 INVITE
14 Contact: sip:sipp@[local_ip]:[local_port]
15 Max-Forwards: 70
16 Subject: Performance Test
17 Content-Type: application/sdp
18 Content-Length: [len]
19
20 v=0
21 o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
22 s=-
23 c=IN IP[media_ip_type] [media_ip]
24 t=0 0
25 m=audio [media_port] RTP/AVP 0
26 a=rtpmap:0 PCMU/8000
27
28 ]]>
29 </send>
30
31 <recv response="100"
32 optional="true">
33 </recv>
34
35 <recv response="180" optional="true">
36 </recv>
37
38 <recv response="183" optional="true">
39 </recv>
40
41 <recv response="200" rtd="true">
42 </recv>
43
44 <!-- Packet lost can be simulated in any send/recv message by -->
45 <!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
46 <send>
47 <![CDATA[
48
49 ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
50 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
51 From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
52 To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
53 Call-ID: [call_id]
54 CSeq: 1 ACK
55 Contact: sip:sipp@[local_ip]:[local_port]
56 Max-Forwards: 70
57 Subject: Performance Test
58 Content-Length: 0
59
60 ]]>
61 </send>
62
63 <!-- This delay can be customized by the -d command-line option -->
64 <pause/>
65
66 <send retrans="500">
67 <![CDATA[
68
69 BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
70 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
71 From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
72 To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
73 Call-ID: [call_id]
74 CSeq: 2 BYE
75 Contact: sip:sipp@[local_ip]:[local_port]
76 Max-Forwards: 70
77 Subject: Performance Test
78 Content-Length: 0
79
80 ]]>
81 </send>
82
83 <recv response="200" crlf="true">
84 </recv>
85
86 <!-- definition of the response time repartition table (unit is ms) -->
87 <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
88
89 <!-- definition of the call length repartition table (unit is ms) -->
90 <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
91
92 </scenario>

uac.xml

看着貌似一大堆,有点吓人,但并不难理解:

a) 5-29行,第一段send,发送INVITE信令,即:准备打电话

b) 接下来的31-39行,表示期待收到被叫方回过来的100/180/183响应,注意这3小段,都是optional=true,表示预期的响应是可选的,即:对方可以发100/180/183,也可以不发。通俗点讲,打一通电话过去,对方可能振铃或不振铃(比如:对方已经在通话中,或者话机有问题)

c) 41行,期待对方回200过来,这里没有optional=true,表示不是可选的,如果收不到,就无法继续。

d) 46-61行,表示上一步收到200后,主叫方发送ACK确认

e) 64行,pause暂停,但是并没有指定暂停多久,看注释,可以在启动uac时,传入“-d 暂停时间”指定,这一行相当于电话接起来,模拟双方在通话,让电话先不要断。

f) 66-81行,表示uac发出bye挂断信令,结束通话,注 retrans="500",表示如果发送失败,500ms后,会重发。

3.2 uas.xml

 1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2 <!DOCTYPE scenario SYSTEM "sipp.dtd">
3
4 <scenario name="Basic UAS responder">
5
6 <recv request="INVITE" crlf="true">
7 </recv>
8
9 <send>
10 <![CDATA[
11
12 SIP/2.0 180 Ringing
13 [last_Via:]
14 [last_From:]
15 [last_To:];tag=[pid]SIPpTag01[call_number]
16 [last_Call-ID:]
17 [last_CSeq:]
18 Contact: <sip:[local_ip]:[local_port];transport=[transport]>
19 Content-Length: 0
20
21 ]]>
22 </send>
23
24 <send retrans="500">
25 <![CDATA[
26
27 SIP/2.0 200 OK
28 [last_Via:]
29 [last_From:]
30 [last_To:];tag=[pid]SIPpTag01[call_number]
31 [last_Call-ID:]
32 [last_CSeq:]
33 Contact: <sip:[local_ip]:[local_port];transport=[transport]>
34 Content-Type: application/sdp
35 Content-Length: [len]
36
37 v=0
38 o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
39 s=-
40 c=IN IP[media_ip_type] [media_ip]
41 t=0 0
42 m=audio [media_port] RTP/AVP 0
43 a=rtpmap:0 PCMU/8000
44
45 ]]>
46 </send>
47
48 <recv request="ACK"
49 optional="true"
50 rtd="true"
51 crlf="true">
52 </recv>
53
54 <recv request="BYE">
55 </recv>
56
57 <send>
58 <![CDATA[
59
60 SIP/2.0 200 OK
61 [last_Via:]
62 [last_From:]
63 [last_To:]
64 [last_Call-ID:]
65 [last_CSeq:]
66 Contact: <sip:[local_ip]:[local_port];transport=[transport]>
67 Content-Length: 0
68
69 ]]>
70 </send>
71
72 <!-- Keep the call open for a while in case the 200 is lost to be -->
73 <!-- able to retransmit it if we receive the BYE again. -->
74 <timewait milliseconds="4000"/>
75
76 <!-- definition of the response time repartition table (unit is ms) -->
77 <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
78
79 <!-- definition of the call length repartition table (unit is ms) -->
80 <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
81
82 </scenario>

uas.xml

a) 6-7行,等待主叫方发送INVITE信令。

b) 9-22行收到主叫方的INVITE请求后,先send 180响应,表示振铃。

c) 24-46行,发送200 响应,表示被叫方已经ready.

d) 48-52行,期待对应发过来ACK确认(注:optional=true,表示可选),至此,通话已经建立。

e) 54-55行,等待被叫方发送挂断信令BYE

f) 57-70行,发送200,通知主叫方挂断完成。

g) 74行,等4秒,防止上一步的200响应由于网络原因丢失,留4秒余量,让对方重发BYE信令。

3.3 自定义scenario配置

除了内置的几种场景,我们也可以自定义xml配置文件,比如:我们把内置的uas.xml/uac.xml简化一下,让主叫方发起呼叫后,被叫方直接挂断(即:模拟被挂方拒接)

uac2.xml

 1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2 <!DOCTYPE scenario SYSTEM "sipp.dtd">
3
4 <scenario name="Basic Sipstone UAC">
5
6 <send retrans="500">
7 <![CDATA[
8
9 INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
10 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
11 From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
12 To: [service] <sip:[service]@[remote_ip]:[remote_port]>
13 Call-ID: [call_id]
14 CSeq: 1 INVITE
15 Contact: sip:sipp@[local_ip]:[local_port]
16 Max-Forwards: 70
17 Subject: Performance Test
18 Content-Type: application/sdp
19 Content-Length: [len]
20
21 v=0
22 o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
23 s=-
24 c=IN IP[media_ip_type] [media_ip]
25 t=0 0
26 m=audio [media_port] RTP/AVP 0
27 a=rtpmap:0 PCMU/8000
28
29 ]]>
30 </send>
31
32 <recv response="200" rtd="true">
33 </recv>
34
35 <send retrans="500">
36 <![CDATA[
37
38 BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
39 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
40 From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
41 To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
42 Call-ID: [call_id]
43 CSeq: 2 BYE
44 Contact: sip:sipp@[local_ip]:[local_port]
45 Max-Forwards: 70
46 Subject: Performance Test
47 Content-Length: 0
48
49 ]]>
50 </send>
51
52 <!-- definition of the response time repartition table (unit is ms) -->
53 <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
54
55 <!-- definition of the call length repartition table (unit is ms) -->
56 <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
57
58 </scenario>

uac2.xml

uas2.xml

 1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2 <!DOCTYPE scenario SYSTEM "sipp.dtd">
3
4 <scenario name="Basic UAS responder">
5
6 <recv request="INVITE" crlf="true">
7 </recv>
8
9 <send retrans="500">
10 <![CDATA[
11
12 SIP/2.0 200 OK
13 [last_Via:]
14 [last_From:]
15 [last_To:];tag=[pid]SIPpTag01[call_number]
16 [last_Call-ID:]
17 [last_CSeq:]
18 Contact: <sip:[local_ip]:[local_port];transport=[transport]>
19 Content-Type: application/sdp
20 Content-Length: [len]
21
22 v=0
23 o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
24 s=-
25 c=IN IP[media_ip_type] [media_ip]
26 t=0 0
27 m=audio [media_port] RTP/AVP 0
28 a=rtpmap:0 PCMU/8000
29
30 ]]>
31 </send>
32
33 <recv request="BYE">
34 </recv>
35
36 <!-- definition of the response time repartition table (unit is ms) -->
37 <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
38
39 <!-- definition of the call length repartition table (unit is ms) -->
40 <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
41
42 </scenario>

uas2.xml

使用时,可以用参数-sf加载xml文件

三、使用数据文件

3.1 简单数据文件

测试时,通常需要模拟不同的主被叫号码,前面的测试中,可能有同学注意到了uac.xml中,From/To是写死的用户sipp,能否动态替换用户名呢?当然可以!

SEQUENTIAL
#This line will be ignored
1001;1019
1002;1018
1003;1017
1004;1016

创建一个uac_data.csv的文件,内容参考上面。第1行的SEQUENTIAL表示顺序读取,#行表示注释,第3行开始,定义数据行,每行2列,在uac.xml配置文件中,可以用[field0]、[field1]来占位替换,即:

重新跑一下uac场景,这次要新加参数 -inf uac_data.csv,同时为了方便验证SIP报文内容,加上-trace_msg

sipp -sf uac.xml -inf uac_data.csv 127.0.0.1:5060  -trace_msg

跑起来后,应该在当前目录生成类似uac_xxx_messages.log的日志文件,打开看看占位符[field0]/[field1]是否被替换了。

3.2 动态数据文件

如果模拟的主/被号很多,一行行手动写有点麻烦,可以用下面的方式自动生成

SEQUENTIAL,PRINTF=999
1%03d;2%03d

其中PRINTF=N,表示生成多少行,而下面的%03d为占位符,真正运行时,会生成

SEQUENTIAL,PRINTF=999
1000;2000
1001;2001
1002;2002
1003;2003
...

  

四、与freeswitch交互

假设要自动测试1个场景:主叫方拨打1开头的内线号码 ,被叫方自动应答。可以在freeswitch的diaplan里,加这么一段:(注:mac上默认的配置文件为/usr/local/freeswitch/conf/dialplan/default.xml)

1 <extension name="auto-answer-sample">
2 <condition field="destination_number" expression="^10\d+$">
3 <action application="log" data="******** auto-answer-and-echo **********"/>
4 <action application="answer"/>
5 <action application="echo"/>
6 </condition>
7 </extension>

然后用软电话工具,测试一下:

如上图,用zoiper终端,以1000身份注册到freeswitch后,拨打1010号码 ,在freeswitch的控制台,看到已经自动接听,然后echo,说明diaplan确实生效了。

用sipp如何来自动测试这一场景呢?显然对于sipp来说,这是一个uac场景,我们写一段uac_auto_answer.xml

 1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2 <!DOCTYPE scenario SYSTEM "sipp.dtd">
3
4 <scenario name="uac_auto_answer_test">
5
6 <!-- 发起呼叫 -->
7 <send retrans="500">
8 <![CDATA[
9
10 INVITE sip:[field1]@[remote_ip]:[remote_port] SIP/2.0
11 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
12 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
13 To: [field1] <sip:[field1]@[remote_ip]:[remote_port]>
14 Call-ID: [call_id]
15 CSeq: 1 INVITE
16 Contact: sip:[field0]@[local_ip]:[local_port]
17 Max-Forwards: 70
18 Subject: Performance Test
19 Content-Type: application/sdp
20 Content-Length: [len]
21
22 v=0
23 o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
24 s=-
25 c=IN IP[media_ip_type] [media_ip]
26 t=0 0
27 m=audio [media_port] RTP/AVP 0
28 a=rtpmap:0 PCMU/8000
29
30 ]]>
31 </send>
32
33 <!-- 期待freeswitch回200 -->
34 <recv response="200" rtd="true">
35 </recv>
36
37 <!-- 期望电话接通后,暂停,由-d参数控制通话时长 -->
38 <pause/>
39
40 <!-- 通话结束后,自动挂断 -->
41 <send retrans="500">
42 <![CDATA[
43
44 BYE sip:[field1]@[remote_ip]:[remote_port] SIP/2.0
45 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
46 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
47 To: [field1] <sip:[field1]@[remote_ip]:[remote_port]>[peer_tag_param]
48 Call-ID: [call_id]
49 CSeq: 2 BYE
50 Contact: sip:[field0]@[local_ip]:[local_port]
51 Max-Forwards: 70
52 Subject: Performance Test
53 Content-Length: 0
54
55 ]]>
56 </send>
57
58 <!-- definition of the response time repartition table (unit is ms) -->
59 <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
60
61 <!-- definition of the call length repartition table (unit is ms) -->
62 <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
63
64 </scenario>

uac_auto_answer.xml

看上去,貌似没啥问题,定义相应的数据文件uac_auto_answer_data.csv

SEQUENTIAL
#callerNumber,destNumber
1000;1010
1001;1011

跑一把:

sipp -sf uac_auto_answer.xml -inf uac_auto_answer_data.csv 192.168.7.101:5070 -l 1 -d 10000 -trace_msg -trace_err

其中192.168.7.101:5070 为本机freeswitch的ip和端口号

可以看到,并没有预期的200响应,freeswitch的控制台上,也没看到预期的answer, echo响应

查看sipp生成的error日志,可以看到

'2021-05-16 15:12:01.801909 1621149121.801909: Aborting call on unexpected message for Call-Id '14-90540@192.168.7.101': while expecting '200' (index 1), received 'SIP/2.0 407 Proxy Authentication Required 

很多这种错误:received 'SIP/2.0 407 Proxy Authentication Required,凭经验,但凡跟Authentication相关的,多半跟验证有关。

先关闭freeswitch的auth验证,方法如下:

a) /usr/local/freeswitch/conf/vars.xml中,把 internal_auth_calls改成false

<X-PRE-PROCESS cmd="set" data="internal_auth_calls=false"/>

b) /usr/local/freeswitch/conf/autoload_configs/acl.conf.xml

1 <list name="domains" default="deny">
2 <!-- domain= is special it scans the domain from the directory to build the ACL -->
3 <node type="allow" domain="$${domain}"/>
4 <!-- use cidr= if you wish to allow ip ranges to this domains acl. -->
5 <!-- 把执行sipp机器所在网段,加入到allow列表 -->
6 <node type="allow" cidr="192.168.7.0/24"/>
7 </list>

参考第6行,把相应的网段加到allow列表里。

重启freeswitch后,再跑一把,会发现仍然没有预期的返回,sipp终端的messages列,期望的200仍然没有返回。此时freeswitch控制台,有下列输出:

同时sipp的错误日志时,有很多487的返回:

'2021-05-16 15:31:48.012115 1621150308.012115: Dead call 1-96258@192.168.7.101 (aborted at index 1), received 'SIP/2.0 487 Request Terminated

说明freeswitch的SIP返回报文,跟我们想得不一样,并不是直接返回了200,这时候就要祭出大招:tcpdump抓包工具(注:这里故意为了演示如何使用抓包工具,如果对freeswitch有经验的同学,可能一眼就能看出freeswitch会先返回100响应码)

如何抓包,也要有思路,既然用zoiper软电话工具,能正常跑通,说明freeswitch肯定是没问题的,那我们就抓zoiper与freeswitch之间的SIP包,抓包步骤:

先确认要抓哪块网卡:

tcpdump -D会列出本机所有网卡,然后用ifconfig看下各网卡的ip

本文所有测试,都是在mac笔记本上执行的,跟freeswitch相关的ip,只有127.0.0.1及192.168.7.101,也就是上图中的网卡lo0、en0

注:可能有同学会问,5070在上图中,lsof -i:5070,不就只有192.168.7.101吗?为啥还要关注127.0.0.1 ?

输入命令:

sudo tcpdump -i en0 port 5070 -vv -w sip_en0.log

即:抓取网卡en0上,端口号为5070的数据包,并将结果写入sip_en0.log中。抓包工具开启后,软电话zoiper呼叫1010,奇怪的是电话接通后,tcpdump里Got 0,也就是并未抓到数据!

然后尝试抓取127.0.0.1所在网卡lo0,同样的操作,这次有数据了!(这也就解释了前面的为什么要关注127.0.0.1所在网卡的原因)

打开抓包的数据文件sip_lo0.log,大致内容如下(已做了整理,方便阅读):

# 1、 Zoiper向freeswitch 发送INVITE
INVITE sip:1011@192.168.7.101:5070;transport=UDP SIP/2.0
Via: SIP/2.0/UDP 192.168.7.101:5061;branch=z9hG4bK-d8754z-37e95a74eab22936-1---d8754z-;rport
Max-Forwards: 70
Contact: <sip:1000@192.168.7.101:5061>
To: <sip:1011@192.168.7.101:5070>;transport=UDP
From: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP;tag=cfb0773d
Call-ID: ZjFmMTExZThiNGE5ZWM3YzNiZTMyNWY0ZWUxMTVkMTE.
CSeq: 1 INVITE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO
Content-Type: application/sdp
User-Agent: Zoiper rev.1809
Content-Length: 306 v=0
o=Z 0 0 IN IP4 192.168.7.101
s=Z
c=IN IP4 192.168.7.101
t=0 0
m=audio 8000 RTP/AVP 3 110 98 8 0 101
a=rtpmap:3 GSM/8000
a=rtpmap:110 speex/8000
a=rtpmap:98 iLBC/8000
a=fmtp:98 mode=30
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv # 2、 Freeswitch回应100 Trying
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.7.101:5061;branch=z9hG4bK-d8754z-37e95a74eab22936-1---d8754z-;rport=5061
From: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=cfb0773d
To: <sip:1011@192.168.7.101:5070>;transport=UDP
Call-ID: ZjFmMTExZThiNGE5ZWM3YzNiZTMyNWY0ZWUxMTVkMTE.
CSeq: 1 INVITE
User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit
Content-Length: 0 # 3、 Freeswitch回应200 OK
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.7.101:5061;branch=z9hG4bK-d8754z-37e95a74eab22936-1---d8754z-;rport=5061
From: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=cfb0773d
To: <sip:1011@192.168.7.101:5070>;transport=UDP;tag=8BZ2eg0QStH7H
Call-ID: ZjFmMTExZThiNGE5ZWM3YzNiZTMyNWY0ZWUxMTVkMTE.
CSeq: 1 INVITE
Contact: <sip:1011@192.168.7.101:5070;transport=udp>
User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit
Accept: application/sdp
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Allow-Events: talk, hold, conference, presence, as-feature-event, dialog, line-seize, call-info, sla, include-session-description, presence.winfo, message-summary, refer
Content-Type: application/sdp
Content-Disposition: session
Content-Length: 222
Remote-Party-ID: "1011" <sip:1011@192.168.7.101>;party=calling;privacy=off;screen=no v=0
o=FreeSWITCH 1621133187 1621133188 IN IP4 192.168.7.101
s=FreeSWITCH
c=IN IP4 192.168.7.101
t=0 0
m=audio 18838 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20 # 4、 Zoiper发送ACK
ACK sip:1011@192.168.7.101:5070;transport=udp SIP/2.0
Via: SIP/2.0/UDP 192.168.7.101:5061;branch=z9hG4bK-d8754z-20ff2eafb70e0d57-1---d8754z-;rport
Max-Forwards: 70
Contact: <sip:1000@192.168.7.101:5061>
To: <sip:1011@192.168.7.101:5070>;transport=UDP;tag=8BZ2eg0QStH7H
From: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP;tag=cfb0773d
Call-ID: ZjFmMTExZThiNGE5ZWM3YzNiZTMyNWY0ZWUxMTVkMTE.
CSeq: 1 ACK
User-Agent: Zoiper rev.1809
Content-Length: 0 # 5、Zoiper发送BYE
BYE sip:1011@192.168.7.101:5070;transport=udp SIP/2.0
Via: SIP/2.0/UDP 192.168.7.101:5061;branch=z9hG4bK-d8754z-f07268afb96f7be8-1---d8754z-;rport
Max-Forwards: 70
Contact: <sip:1000@192.168.7.101:5061>
To: <sip:1011@192.168.7.101:5070>;transport=UDP;tag=8BZ2eg0QStH7H
From: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP;tag=cfb0773d
Call-ID: ZjFmMTExZThiNGE5ZWM3YzNiZTMyNWY0ZWUxMTVkMTE.
CSeq: 2 BYE
User-Agent: Zoiper rev.1809
Content-Length: 0 # 6、FreeSWITCH回应200
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.7.101:5061;branch=z9hG4bK-d8754z-f07268afb96f7be8-1---d8754z-;rport=5061
From: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=cfb0773d
To: <sip:1011@192.168.7.101:5070>;transport=UDP;tag=8BZ2eg0QStH7H
Call-ID: ZjFmMTExZThiNGE5ZWM3YzNiZTMyNWY0ZWUxMTVkMTE.
CSeq: 2 BYE
User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Length: 0

可以发现,FreeSwitch收到INVITE后,并不是直接回的200,而是先回了100。所以uac的xml要调整一下:

 1 <?xml version="1.0" encoding="ISO-8859-1" ?>
2 <!DOCTYPE scenario SYSTEM "sipp.dtd">
3
4 <scenario name="Basic Sipstone UAC">
5
6 <send retrans="500">
7 <![CDATA[
8
9 INVITE sip:[field1]@[remote_ip]:[remote_port] SIP/2.0
10 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
11 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
12 To: [field1] <sip:[field1]@[remote_ip]:[remote_port]>
13 Call-ID: [call_id]
14 CSeq: 1 INVITE
15 Contact: sip:[field0]@[local_ip]:[local_port]
16 Max-Forwards: 70
17 Subject: Performance Test
18 Content-Type: application/sdp
19 Content-Length: [len]
20
21 v=0
22 o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
23 s=-
24 c=IN IP[media_ip_type] [media_ip]
25 t=0 0
26 m=audio [media_port] RTP/AVP 0
27 a=rtpmap:0 PCMU/8000
28
29 ]]>
30 </send>
31
32 <!-- 加上这个100的接收 -->
33 <recv response="100">
34 </recv>
35
36 <recv response="200">
37 </recv>
38
39 <!-- 从抓包来看,zoiper有发送了ACK,但是sipp加上后,一直发不成功,先注释掉 -->
40 <!-- <send retrans="500">
41 <![CDATA[
42
43 ACK sip:[field1]@[remote_ip]:[remote_port] SIP/2.0
44 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
45 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
46 To: [field1] <sip:[field1]@[remote_ip]:[remote_port]>[peer_tag_param]
47 Call-ID: [call_id]
48 CSeq: 1 ACK
49 Contact: sip:[field0]@[local_ip]:[local_port]
50 Max-Forwards: 70
51 Subject: Performance Test
52 Content-Length: 0
53
54 ]]>
55 </send> -->
56
57 <pause/>
58
59 <send retrans="500">
60 <![CDATA[
61 BYE sip:[field1]@[remote_ip]:[remote_port] SIP/2.0
62 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
63 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
64 To: [field1] <sip:[field1]@[remote_ip]:[remote_port]>[peer_tag_param]
65 Call-ID: [call_id]
66 CSeq: 2 BYE
67 Contact: sip:[field0]@[local_ip]:[local_port]
68 Max-Forwards: 70
69 Subject: Performance Test
70 Content-Length: 0
71 ]]>
72 </send>
73
74 <!-- freeswitch收到BYE后,会回200 -->
75 <recv response="200">
76 </recv>
77
78 <!-- definition of the response time repartition table (unit is ms) -->
79 <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
80
81 <!-- definition of the call length repartition table (unit is ms) -->
82 <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
83
84 </scenario>

然后再执行,终于跑起来了!

Freeswitch的控制台,也正常输出了answer, echo等信息

相信大家看完本文后,对sipp的使用已经入门了,如果遇到复杂场景,不知道如何写sipp xml时,建议多利用日志文件及抓包工具。

sipp学习笔记的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

  10. ucos实时操作系统学习笔记——任务间通信(消息)

    ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...

随机推荐

  1. springBoot简要复习总结

    Spring Boot Spring Boot 的特点 1. 独立运行的 Spring 项目 Spring Boot 可以以 jar 包的形式独立运行,Spring Boot 项目只需通过命令&quo ...

  2. Java对象相等判断

    你是谁啊?你是不是我??(⊙_⊙)? 我们知道比较对象相等可以使用equal方法(来自Object对象的方法) 但是你打开Object的equal方法你会发现: public boolean equa ...

  3. 【记录】博客|Markdown写作常用的符号表示、公式写法合集

    文章目录 基础内容Basic 1.符号合集 2.LaTeX公式输入 附加内容Addition 1.公式左对齐 2.Markdown文档导出的PDF分页 基础内容Basic 1.符号合集 LATEX M ...

  4. 在ARM笔记本和KylinOS桌面操作系统上安装docker

    目标 手头有一台华为L420笔记本,CPU为ARM(HUAWEI Kirin 9006C),OS为Kylin桌面操作系统V10(SP1),内核5.4.96,已激活. 需要安装docker,但在软件商店 ...

  5. Linux 下搭建 Spark3 + Jupyter 环境

    最近想着来玩一玩大数据, 前段时间集中过了一遍 java, 最近又看了一些基础的 scala, 我感觉吧, 我都不想学. 还是觉得用 sql, javascript, python 这种脚本语言操作起 ...

  6. 【UEFI】DXE阶段从概念到代码

    总述 DXE(Driver Execution Environment)阶段,是执行大部分系统初始化的阶段,也就是说是BIOS发挥作用,初始化整个主板的主战场.在这个阶段我们可以进行大量的驱动工作. ...

  7. RocketMQ源码详解(消息存储、Consumer)

    消息存储 消息存储核心类 private final MessageStoreConfig messageStoreConfig; //消息配置属性 private final CommitLog c ...

  8. css样式修改-悬浮数字

    代码实现 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  9. deepseek-r1的1.5b、7b、8b、14b、32b、70b和671b有啥区别?

    DeepSeek-R1系列提供了多种参数规模的模型(1.5B.7B.8B.14B.32B.70B 和 671B),它们在模型架构.性能表现.资源需求和适用场景上有显著差异.以下是对这些版本的核心区别总 ...

  10. 使用 frp 进行内网穿透

    frp 是一个开源的内网穿透工具,可以使外网设备访问内网防火墙后的设备/服务器. 比如可以买一个 99元/年 的阿里云低配 ECS,然后把自己相对高配的旧电脑放在家里. 家里的旧电脑通过 frp 连上 ...