UAC核心必须为每一个2xx应答,产生一个ACK请求。除了在Cseq和身份认证相关的头域之外,ACK请求的头域的创建和在对话中的INVITE请求创建的方法一样。Cseq头域的序列号部分必须和需要确认的INVITE请求一样,但是Cseq的方法部分必须是ACK。ACK必须包含和INVITE请求相同的信任状。如果2xx包含一个媒体磋商请求(基于上述的规则),ACK必须在包体中包含一个媒体磋商应答。如果2xx应答的媒体磋商请求不能被接收,UAC核心必须产生一个有合法的应答ACK,并且立刻发送一个BYE请求。
在客户端事务中构造ACK请求的方法:不同与UAC核心为2xx应答产生ACK请求的方法;
在客户端事务中构造的ACK请求必须包括与原始请求相同的Call-ID, From, Request-URI头域值(就是说和在客户端事务发到通讯层的请求中的这些头域值相同)。在ACK请求中的To头域必须和被确认的应答的To头域值相同,因此通常和原始请求有所不同,不同点在增加了附加的tag参数。ACK必须包含一个单个的Via头域,并且必须和原始请求的最上边一个Via头域值相等。ACK的Cseq头域必须包含和原始请求的Cseq的序列号相同,但是方法参数应当是”ACK”。
如果INVITE请求的应答是有Route头域的,这些Route头域必须也在ACK中。这是确保ACK能够正确路由通过下行队列的无状态的proxy。
虽然请求可以包含一个包体,但是ACK的包体却比较特别,因为请求不能因为不能理解包体而拒绝这个请求。因此,我们不建议在给非2xx应答的ACK请求中放置包体,但是如果放置了,并且假设给INVITE的应答不是415应答,那么包体的类型应当严格和INVITE请求中定义的那样。如果是415应答,那么ACK的包体应当和415应答中的Accept列出的类型一致。
例如:有如下请求
INVITE sip:
[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
To: Bob <sip:
[email protected]>
From: Alice <sip:
[email protected]>;tag=88sja8x
Max-Forwards: 70
Call-ID: 987asjd97y7atg
Cseq: 986759 INVITE
给非2xx终结应答的ACK请求应当是:
ACK sip:
[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
To: Bob <sip:
[email protected]>;tag=99sa0xk
From: Alice <sip:
[email protected]>;tag=88sja8x
Max-Forwards: 70
Call-ID: 987asjd97y7atg
Cseq: 986759 ACK