SIP INVITE
主叫方Tesla首先发起INVITE 消息到被叫方Marconi。INVITE 消息包含会话类型和一些呼叫所必须的参数。会话类型可能是单纯的语音,也可能是网络会议所用的多媒体视频,还可能是游戏会话。下面是消息体范例,我们来详细分析各个字段的意义。
INVITE sip:marconi@radio.org SIP/2.0
<= 请求方法、请求地址(Request-URI)、SIP 版本号(目前都是 SIP/2.0)
<= 请求地址一般就是被叫方地址,跟 MSN 中好友 eMail 地址类似
Via: SIP/2.0/UDP :5060;branch=z9hG4bKfw19b
<=SIP 版本号(2.0)、传输类型(UDP)、呼叫地址、
<=branch是一随机码,它被看作传输标识
<=Via 字段中地址是消息发送方或代理转发方设备地址,一般由主机地址和端口号组成
<=传输类型可以为 UDP、TCP、TLS、SCTP
Max-Forwards: 70
<=最大跳跃数,就是经过 SIP 服务器的跳跃次数,主要是防止循环跳跃
<=每尽管一台代理服务器,该整数减一
To: G. Marconi <sip:Marconi@radio.org>
From: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341
<=表示请求消息的发送方和目标方
<=如果里面有用户名标签,地址要求用尖括号包起来
<=对于 INVITE 消息,可以在 From 字段中包含 tag,它也是个随机码
Call-ID: 123456789@
<=呼叫ID是由本地设备生成的,全局唯一值。每次呼叫该值唯一不变
<=对于用户代理发送INVITE消息,本地将生成From tag和Call-ID全局唯一码,被叫方代理则生成To tag全局唯一码。这三个随机码做为整个对话中对话标识(dialog indentifier)在通话双方使用。 CSeq: 1 SIP INVITE
<=CSeq,又叫命令队列(Command Seqence),每发送一个新的请求,该数自动加1
* 以上几个字段是所有 SIP 消息体所必须的,其它头字段有些是可选的,有些在特定请求也是必须 Subject: About That Power Outage...
Contact: <sip:n.tesla@>
<=Contact 是 INVITE 消息所必须的,它用来路由到被叫设备地址,也称为用户代理(UA) Content-Type: application/sdp
Content-Length: 158
<=最后两位附属字段说明消息体类型以及字段长度
v=0 <=SDP版本号,目前都是 0
o=Tesla 2890844526 2890844526 IN IP4 <=主叫源地址,类型等 s=Phone Call <=主题
c=IN IP4 100.101.102.103 <=连接
t=0 0 <= 时间戳
m=audio 49170 RTP/AVP 0 <=媒体
a=rtpmap:0 PCMU/8000 <=媒体属性
<=从上面 SDP 消息体我们可以得出下面信息
<=连接 IP 地址:100.101.102.103
<=媒体格式:audio
<=端口号:49170
<=媒体传输类型:RTP
<=媒体编码:PCM u Law
<=采样率:8000 Hz
180 Ringing
当被叫方接收到SIP INVITE请求消息后,将回复 180 Ringing。顾名思义,就是发回铃音,提示主叫方电话已连接上了,正等待被叫应答。被叫方接收到 INVITE 消息后也会发生响铃或者其它有呼入提示,这由被叫方设定(我们可以把它想象成我们自己设定手机铃声)。对于 180 响应又被称为“消息及时响应”,它是一种用来测试被叫状态的一种响应。因此它所包含的信息不多,具体 180 响应消息如下: SIP/2.0 180 Ringing
Via: SIP/2.0/UDP :5060;branch=z9hG4bKfw19b
;received=100.101.102.103 <=这里增加一个 received 参数,标识接收方 IP 地址
To: G. Marconi <sip:marconi@radio.org>;tag=a53e42 <=上已提到,To tag 做为被叫方标识 From: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341 <=要求很发送方 From tag 一致
Call-ID: 123456789@
CSeq: 1 INVITE
Contact: <sip:marconi@>
Content-Length: 0
<=对于 180 Ringing 响应,基本上就是将 INVITE 的 Via、To、From、Call-ID 和 CSeq 内容复制过来,对于首行标出 SIP 版本号,响应代码(180)和动作原因(reason phrase)
<=注意这里 From 和 To 地址,因为它们用来指定呼叫方向,因此这里的 200 OK 响应并没有将地址对调,仍然保持原样。一点不同的是 To 头字段添加了由被叫方 Marconi 生成的 tag 标识
200 Ok
SIP INVITE被叫响铃后,如果被叫用户 Marconi 接起电话,则发出 200 OK 响应。这个响应除了做为接通指示之外,还有一个功能是用来指定被叫允许的连接媒体格式,让主叫方确认是否可以接收该媒体。
消息体如下
SIP/2.0 200 OK
Via: SIP/2.0/UDP :5060;branch=z9hG4bKfw19b
;received=100.101.102.103
To: G. Marconi <sip:marconi@radio.org>;tag=a53e42
From: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341
Call-ID: 123456789@
CSeq: 1 INVITE
Contact: <sip:marconi@>
Content-Type: application/sdp
Content-Length: 155
<=头字段部分基本同上
v=0
o=Marconi 2890844528 2890844528 IN IP4
s=Phone Call
c=IN IP4 200.201.202.203
t=0 0
m=audio 60000 RTP/AVP 0
a=rtpmap:0 PCMU/8000
<=从上面 SDP 消息体我们可以得出下面信息
<=终端 IP 地址:200.201.202.203
<=媒体格式:audio
<=端口号:60000
<=媒体传输类型:RTP
<=媒体编码:PCM u Law
<=采样率:8000 Hz
ACK
SIP INVITE通话前最后一步是主叫方确认 200 OK响应。该项确认证明连接被允许,即将使用另一种协议开始媒体连接。这另一种协议是上面在 SDP 消息段中所协商好的 RTP 格式。该 ACK 响应内容如下: ACK sip:marconi@ SIP/2.0
Via: SIP/2.0/UDP :5060;branch=z9hG4bK321g
Max-Forwards: 70
To: G. Marconi <sip:marconi@radio.org>;tag=a53e42
From: Nikola Tesla <sip:n.tesla@high-voltage.org>;tag=76341
Call-ID: 123456789@
CSeq: 1 ACK
Content-Length: 0
第二篇:SIP RE-INVITE
SIP_Re-invite RFC
2008-10-12 10:50
RFC 3261 SIP: 会话发起协议 20xx年6月
因为2字头应答在端到端之间重发,UAS和UAC之间的转发可能通过UDP。为了
保证转发的可靠性,就算UAS使用可靠的传输层,也要周期性的重发应答。
如果服务端重发2字头应答64*T1秒还未收到一个ACK,对话状态转换为确认,但
应当终止会话。使用BYE请求来终止会话(见15章)。
14 修改一个已建立的会话
一个成功的INVITE请求(见13章)在两个用户代理间既建立了对话,又使用
“提议/回答”模型建立了会话。12章解释了如何使用一个目的地更新请求修改
一个已有对话(例如,改变对话的对方目的地URI)。本章描述如何修改一个会话。
这些修改涉及到改变地址或端口号,增加一个媒体流,删除一个媒体流,等等。
这些修改通过在建立会话的同一个对话内发送一个新的INVITE来实现。在已有的
对话中发送一个INVITE被称为re-INVITE.
注意,单个re-INVITE可以同时修改对话及会话参数。
主叫方和被叫方都可以修改已有会话。
UA对媒体流失败的检测是一个本地策略问题,但是不建议自动生成re-INVITE或
BYE来避免网络阻塞引起的失败问题。无论何种情况,如果要自动发送消息,都
应当有随机的间隔。
注意,上一段是针对自动生成re-INVITE和BYE。如果遇到媒体流失败,用户
挂机,UA应当正常地发送BYE请求。
14.1 UAC机理
Rosenberg, et. al. Standards Track [Page 86]
RFC 3261 SIP: 会话发起协议 20xx年6月
适用于INVITE会话描述的“提议/回答”模型(13.2.1节)同样适用于re-INVITE。
所以,UAC如果想增加一个媒体流,就要建立一个包含该媒体的新的提议,放入
INVITE请求并发送给对方。要注意,发送的不是会话描述的更改部分,而是
整个会话描述。这是为了支持不保持会话状态的各种构件的处理,也是为了
支持容错和恢复的能力。当然,UAC也可以发送不带会话描述的re-INVITE,
这种情况下,对re-INVITE的第一个可靠应答将包含提议(本协议是指2字头应答)。
如果会话描述格式能够区分版本号,提议应当表明会话描述的版本是否改变。
re-INVITE的To,From,Call-ID,CSeq,和Request-URI的设定遵照构建对话内
请求相同规则,见12章。
对于re-INVITE,UAC可以选择不加入一个Alert-Info域或
Content-Disposition域
为“alert"”的消息体,因为UAS通常不会基于收到的re-INVITE而警示用户。
INVITE可以分支,而re-INVITE则不能分支。因此只有一个最终应答。re-INVITE
永不分支的原因在于,其Request-URI可以确定已建立对话的目的地是一个UA实体,
而不是用户的一个地址记录。
注意,在同一个对话中,当一个INVITE事务还在处理中(不论方向如何),UAC决不
能新建一个INVITE 事务。
1. 如果有一个正在处理的INVITE客户端事务,TU在新建INVITE事务前必须
等待,直到事务完成或终止。
2. 如果有一个正在处理的INVITE服务端事务,TU在新建INVITE事务前必须
等待,直到事务完成或终止。
但是,UA可以在处理INVITE事务时新建普通的事务,也可以在处理普通事务时
新建INVITE事务。
如果UA收到re-INVITE的非2字头的最终应答,会话参数必须保持不变,就象没有
发出re-INVITE。注意如同12.2.1.2节中规定,如果非2字头的最终应答是481(对
话/事务不存在),或408(请求超时),或根本没收到re-INVITE的应答(即INVITE
客户端事务返回超时),UAC将终止对话。
Rosenberg, et. al. Standards Track [Page 87]
RFC 3261 SIP: 会话发起协议 20xx年6月
如果UAC收到re-INVITE的491应答,就应当启动一个值为T的定时器。T值选择
如下:
1. 如果UAC是对话ID中Call-ID的所有者(即该UAC产生的该值),T是在2.1
到4秒间随机数,步长为10ms.
2. 如果UAC不是对话ID中Call-ID的所有者,T是在0到2秒间的随机数,步长
为10ms.
当定时器到点,如果UAC仍然需要改变会话,就应当再次尝试发送re-INVITE,
例如,如果对话已经被BYE挂断,就不会重发re-INVITE.
重发re-INVITE,以及产生对2字头应答的确认ACK,都和初始INVITE中的处理一样
(13.2.1节)。
14.2 UAS机理
13.3.1节描述了区分re-INVITE和初始INVITE的步骤,以及如何处理re-INVITE.
同一个对话中,如果UAS在发出第一个INVITE的最终应答前收到第二个INVITE,且
第二个CSeq序列号较小,则UAS必须给第二个INVITE返回500(服务器内部错误),
并且必须包含Retry-After域,值为0-10秒的随机数。
如果UAS发出的INVITE正在被处理时,收到一个同一对话的INVITE,则必须对该
INVITE返回491(请求待定)应答。
如果UA收到一个已有对话的re-INVITE,必须检查会话描述中的任何版本标识符,
如果没有版本标识符,则检查会话描述内容,看是否有变化。如果会话描述有
变化,UAS必须相应调整会话参数,这可能需要用户的确认。
会话描述的版本可以用来提供一系列能力,如介绍新的会议参与者,增加或
删除媒体,和将点到点会话变成多点会议。
Rosenberg, et. al. Standards Track [Page 88]
RFC 3261 SIP: 会话发起协议 20xx年6月
如果不能接受新的会话描述,UAS可以拒绝re-INVITE,并返回488(这儿不接受)
应答。应答;应当包含一个Warning域。
如果UAS产生了一个2字头应答,但没有收到ACK,UAS应当产生一个BYE来终止对话。
对于re-INVITE,UAS可以选择不产生180(响铃),因为UAC通常不将该信息告诉用户。
同样的理由,UAS可以选择不使用Alert-Info域或
Content-Disposition为“alert”
的消息体。
如果UAS在2字头应答中提供提议(因为INVITE没包含提议),就应当象建立新的呼叫
一样构建提议,更新已有会话的提议必须符合相同的约束(如果是SDP,就如[13]
所述)。也就是说,提议应当包含UA所愿支持的所有媒体格式和类型。UAS必须保
证会话描述包含之前的会话描述中被对方所支持的媒体格式和类型。这是为了避免
对方拒绝会话描述。当然,如果这不被UAC接受,UAC应当生成携带合法会话描述的
回答,然后发出BYE来终止会话。