这次测试的过程中,出现困扰最多的问题是网关在呼叫过程中,没有收到Alerting事件,导致状态机的紊乱。实际上,SIP协议已经定义了临时响应的可靠性。
在SIP标准中规定,规定了在呼叫建立过程中对临时消息可靠传输的定义,在其他过程中,可以借鉴这种机制,但是不是作为标准制定。如果呼叫建立需要支持临时消息的可靠性,需要加上SIP头——supported或者require,该头部任选参数为100rel。require表明需要对端支持,supported表明本次呼叫不要求可靠传输,但本端支持,由UAS决定。如果对断不支持,需要回420消息,并且在头部中加上Unsupported字段,并且该字段的参数为100rel。
举例说明,如果Invite消息中包含require或者supported字段,并且为100rel,则对端在100 Trying后,发送后续101-199事件需要设定指数类型的定时器。此时钟和invite应答的重传时钟应该相互独立。
当收到PRACK后,需要对进行匹配,如果匹配的话,重传时钟就可以中止了。所谓匹配就是指PRACK和临时响应处于同一个会话,且RAck中的方法,CSeq-num,response-num在此一对消息中都是吻合的。所谓吻合,咋一看不容易理解,通过以下的例子说明。
C->S: INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP saturn.bell-tel.com
Supported: 100rel
From: sip:[email protected]
To: sip:[email protected]
Call-ID: [email protected]
CSeq: 1 INVITE
Subject: Come here Watson
S->C: SIP/2.0 100 Trying
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected]
Call-ID: [email protected]
CSeq: 1 INVITE
S->C: SIP/2.0 183 Proceeding
Require: 100rel
Via: SIP/2.0/UDP saturn.bell-tel.com
RSeq: 776655
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 1 INVITE
Content-Type: application/sdp
v=0
s=Let's talk
b=CT:128
c=IN IP4 north.east.isi.edu
m=audio 3456 RTP/AVP 5 0 7
m=video 2232 RTP/AVP 31
C->S: PRACK sip:[email protected] SIP/2.0
RAck: 776655 1 INVITE
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 2 PRACK
Content-Type: application/sdp
v=0
s=Let's talk
b=CT:128
c=IN IP4 machine.bell-tel.com
m=audio 3456 RTP/AVP 5 0 7
m=video 2232 RTP/AVP 31
S->C: SIP/2.0 200 OK
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 2 PRACK
S->C: SIP/2.0 182 Two in the Queue
Via: SIP/2.0/UDP saturn.bell-tel.com
Require: 100rel
RSeq: 776656
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 1 INVITE
S->C: SIP/2.0 182 One in the Queue
Via: SIP/2.0/UDP saturn.bell-tel.com
Require: 100rel
RSeq: 776657
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 1 INVITE
C->S: PRACK sip:[email protected] SIP/2.0
RAck: 776656 1 INVITE
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 3 PRACK
C->S: PRACK sip:[email protected] SIP/2.0
RAck: 776657 1 INVITE
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 4 PRACK
S->C: SIP/2.0 200 OK
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 3 PRACK
S->C: SIP/2.0 200 OK
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 4 PRACK
S->C: SIP/2.0 200 OK
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 1 INVITE
Content-Type: application/sdp
v=0
s=Let's talk
b=CT:128
c=IN IP4 north.east.isi.edu
m=audio 3456 RTP/AVP 5 0 7
m=video 2232 RTP/AVP 31
C->S: ACK sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP saturn.bell-tel.com
From: sip:[email protected]
To: sip:[email protected];tag=11
Call-ID: [email protected]
CSeq: 1 INVITE
以上的例子摘自draft-ietf-sip-100rel-02.txt,从这个例子中可以看到PRACK发送的原理和参数要求。PRACK首先是作为一个请求,并以200 OK作为响应。PRACK发送的所针对的是一个临时响应。
以183为例,参数为
Require: 100rel
RSeq: 776655
那么对应的PRACK的参数为
RAck: 776655 1 INVITE
CSeq: 2 PRACK
对应的200 OK的参数是
CSeq: 2 PRACK
如果收到的PRACK得不到任何的匹配,需要发送481作为响应。如果得到正确的响应,应该从响应列表中删除该响应。