sip

sip:的缺省传输协议是 UDP;sips:的缺省传输协议是TCP。tcp默认5060,tcp+tls5061;tcps5061.

会话发起协议(SIP),即有一个或多个参与者的用于创建、修改和终止会话的应用层控制(信令)协议。

用户代理UA:用户代理能向代理服务器发送注册信息、会话邀请以及其它请求。

事务:在事务中,当请求是一个INVITE(叫做INVITE事务),当终结应答不是一个2xx应答的时候,事务还包括一个ACK。如果应答是一个2xx应答,那么ACK并不认为是事务的一部分。

会话描述协议(SDP):会议细节协商,如编解码,采样率等

事务由5个必要部分组成:from、to、Via头的branch参数、call-id和cseq。分支参数是唯一的事务标识符。

对话Call-ID、from-tag以及to-tag三个值的组合能够唯一标识一次对话。对话至少包含一个事务。

会话:只有当媒体协商成功后,会话才能被建立起来.

对话和事务处于信令层,而会话处于媒体传输层。

同一会话(对话)窗口Call-ID不变,但不一定是一个对话,因to-tag可能会变;180时to-tag填充,100为空。

sip协议栈 java sip协议 udp_java

INVITE是SIP中建立对话的唯一方法

sip协议栈 java sip协议 udp_开发语言_02

头字段简要描述如下:

Via(v) 包含地址信息(pc33.atlanta.com),Alice 希望从该地址接收请求的响应。Via 也包含一个标识事务的分支参数。同一个事务的branch相同。   recived参数是发送响应的对端地址

Max-Forwards 限制请求在达到其目的地过程中的跳跃点数。它包含一个整数,该整数在每一个跳跃点增加。若Max-Forwards 头字段为 0将直接响应请求。

To(t) 包含一个显示名称(Bob)和 SIP 或 SIPS URI(sip:bob@biloxi.com),它是请求的目的地址。显示名称在 RFC2822[3]中描述。

From(f) 也包含一个显示名称(Alice)和 SIP 或 SIPS URI(sip:alice@atlanta.com),它是请求的源地址。本头字段有个标签(tag)参数,它包含一个随机串,软电话将该串加到URI 中。它用于身份鉴别。

Call-ID(I) 包含呼叫的全球唯一标识符,由随机串、软电话主机名或 IP 地址连接而成。To 标签、From 标签和 Call-ID 一起定义 Alice 和 Bob 间对等的 SIP 关系,称为对话。

CSeq 或命令序列包含一个整数和一个方法名。在一个对话内,CSeq 号随着新请求增加,传统上它是一个序列号。

Contact(m) 包含一个 SIP 或 SIPS URI,它表示联系 Alice 的直接路由,它由绝对域名称(FQDN)中的用户名组成。选用 FQDN 的时候,许多终端系统没有注册域名,因此允许 IP地址。Via 头字段告诉其它元素向哪里发送响应,而 Contact 头字段告诉其它元素以后向哪里发送请求。

Content-Type(c) 包含消息体的描述。

Content-Length(l) 包含计算消息体长度的八位位组(字节)。

To、From、Cseq、Call-ID、Max-Forwards 和 Via。在所有的 SIP 请求中,这些头字段都是必需的

附:

Record-Route:代理始终留在SIP信令路径,知道会话的所有信令交互。不加,invite后就不再经过代理。

Content-Encoding:编解码

Allow:允许的方法集合

Require:UAC(self)希望 UAS 支持的 SIP扩展

Unsupported:UAS不支持的Require选项

Accept:self支持的消息体类型

Accept-Encoding:self支持的编码

Accept-Language:self支持的语言

Supported:支持的Require选项

Route:路由集合   lr 参数表示元素实现了指定的路由机制,不加lr表示严格路由(16.12.1 实例)

Alert-Info:替换响铃音

Retry-After:禁止请求持续时间,如30s后再试

WWW-Authenticate:未授权  401用于注册register认证

Proxy-Authenticate::代理认证 407 invite请求时认证

Content-Disposition 的描述:

alert
icon
render
session

消息体是提醒用户的自定义铃声
消息体是显示给用户的图标
消息体应显示给用户
消息体描述一个通信会话

SIP的响应由三位数字编码+描述短语组成。

invite每经过一个代理服务器,就在invite增加一个via路由地址。响应时,每个代理使用 Via 头字段决定向哪里发送响应,并从顶端移除其地址。(这里有三个 Via 头字段值——一个是 Alice 的 SIP 电话增加的,一个是代理服务器增加的,一个是 biloxi.com 代理增加的。)

sip协议栈 java sip协议 udp_字段_03

有两个阶段的 SDP 消息交换: Alice 向 Bob 发送一个invite请求消息, Bob 向 Alice返回一个响应消息(183或200)。这两个阶段的交换提供了基本的协商能力.

sip协议栈 java sip协议 udp_servlet_04

200(OK)通过两个代理服务器路由返回,ACK 直接从 Alice 的软电话发送到Bob 的 SIP 电话,而旁路两个代理。这是因为两个端点已从 INVITE 200(OK)交换的 Contact头字段获知相互的地址,因而不再需要两个代理执行查询,两个代理退出呼叫流程。这样就结束了用于建立 SIP 会话的 INVITE/200/ACK 三方握手。

会话过程中更改媒体会话特征 -- re-INVITE

Alice 和 Bob 都可以在会话过程中更改媒体会话特征。更改可通过发送报告新媒体描述的 re-INVITE 实现。Re-INVITE 需要提及已建立的对话,以让另一方知道是修改现有的会话,而不是建立新会话。另一方发送 200(OK)接受改变。请求者用 ACK 响应 200(OK)。如果另一方不接受此改变,他就会发送一个错误响应,如 488(这里不接受),此时接收到的也是 ACK。但是,re-INVITE 的失败不会导致现有会话失败——使用先前协商的特征继续会话。

如:建立会话后,新的请求re-INVITE,BYE等都是直接点到点发送,而不通过代理。

Record-Route代理服务器始终留在SIP信令路径 -- 一般会话开始后不再经过代理服务器

向INVITE 添加一个所需路由选择头字段即 Record-Route, 其包含解析代理主机名或 IP 地址的URI。

Call Stateful:如果一个代理从初始 INVITE 到终止 BYE 请求都保留了对话的状态,那么该代理有呼叫状态。

REGISTER 请求和响应中的 Record-Route 头字段没有意义。

SIP消息

消息都由一个起始行、一个或多个头字段、一个标识头字段结束的空行和一个可选消息体组成。

generic-message = start-line

*message-header

CRLF

[ message-body ]

起始行、每个消息头行和空行必须以回车换行序列(CRLF)终止。注意:即使没有消息体,也必须有空行。

请求 -- Request-Line

Request-Line 包含一个方法名、一个 Request-URI 和由空格(SP)字符分开的协议版本。

Request-Line = Method SP Request-URI SP SIP-Version CRLF

Method:用于注册 Contact 信息的 REGISTER;

用于建立会话的 INVITE、ACK 和 CANCEL;

用于终止会话的 BYE 和用于查询服务器能力的 OPTIONS。

响应 -- Status-Line

Status-Line 依次由协议版本号、数字 Status-Code 和以及相关的文本分析(textual phrase)组成。

Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF

1xx: informational - 临时响应 已经收到请求、继续处理请求。
2xx: success       - 成功响应 已经成功收到,理解和介绍行动。
3xx: Redirection   - 重定向 为完成呼叫请求,还须采取进一步地动作。
4xx: Client Error - 客户端错误  请求有语法错误或服务器不能执行请求。
5xx: Server Error - 服务端错误  不能执行合法请求。
6xx: GLOBAL FAILURE - 任何服务器都不能执行请求。

头字段

格式:field-name: field-value

相同头字段可合成一个:依次将每个字段值添加到第一个后。因此顺序很重要。

头字段值可扩展为多行,方法是在每个附加行前添加一个空格(SP)或横向制表(HT)。

UA行为

UAC行为:生成请求,发送请求,处理响应

UAC行为:方法检查:Allow头字段提示支持的方法

                     头检查:不理解的头字段,忽略并继续处理后续内容

      

重定向服务器

当重定向服务器给请求返回 3xx 响应,它在 Contact 头字段填充(一个或多个)可选的地址。Contact 头字段值的 expires 参数也可以指出 Contact 数字的生命周期。

可以修改:传输URI,tcp、udp传输方式相互转换

取消请求CANCEL -- 占用服务器很长时间才能响应的请求

取消客户端发送的前一请求。它要求UAS 停止处理请求,并为请求生成错误响应。

接收到 INVITE的 CANCEL 请求,但是没有发送最终响应的 UAS,可能会“停止响铃”,然后给 INVITE 发送特定的错误代码(a 487)。

CANCEL 请求也不包含 Require 头字段。

注意:收到INVITE 的 ACK 后,才能发送呼叫的 BYE。获取请求的临时响应1xx后,才能向事务发送 CANCEL。

注册REGISTER

定位服务:注册服务器(建立映射—定位服务前端),重定向服务器(查询映射—定位服务后端)

域中的注册服务器必须能够在定位服务中读和写数据,域中的代理和重定向服务必须能够读取相同的数据。

如果 Record-Route 包含在 REGISTER 请求中, 那么,注册服务器必须忽略 Record-Route头字段。

sip协议栈 java sip协议 udp_servlet_05

REGISTER 请求 必有头字段:Request-URI、To、From、Call-ID、CSeq、Contact

删除绑定:Expires 头字段 用值“0”表示,立即删除绑定。未配置时,默认3600s

更细绑定:在Expires结束之前,为其每个绑定发布 REGISTER 请求,更新Expires。

提取绑定:注册服务器的 200(OK)响应包含一系列的 Contact 头,列举了所有的当前绑定。

Min-Expires 头字段——说明注册服务器想要的最小逾时间隔,防止过于频繁的注册更新

查询能力OPTIONS

OPTIONS 允许 UA 查询其它 UA 和代理服务器的能力。      返回Supported 头字段

Accept 头字段,说明在响应中 UAC 想要接收到的消息体的类型。默认值为 application/sdp。

sip协议栈 java sip协议 udp_servlet_06

Allow、Accept、Accept-Encoding、Accept-Language 和 Supported 头字段应该出现在 OPTIONS 请求的 200 (OK)响应中。

对话(Dialogs)

对话,表现为两个用户代理(UA)之间的持续一段时间的点对点的SIP关系。对话使得用户代理之间的消息顺序传递和两个用户代理之间的请求正确路由更加容易。对话可以认为是对SIP消息解释的上下文关系。一个对话在参与对话的UA中都有一个dialog ID作为标记,这个dialog ID由Call-ID,和一个本地tag和远程tag组成,即Call-ID、from-tag以及to-tag三个值的组合能够唯一标识一次对话。

1)对于UAC来说,dialog ID中的Call-ID的值会填写到消息中的Call-ID域中,远程tag放在消息中的To的tag参数中,本地tag放在From的tag参数中。

2)对于UAS来说,dialog ID的Call-ID值放在消息的Call-ID头域中,远程tag放在From头域的tag中,本地tag放在To头域的tag参数中

对话 ID 由 Call-ID 值、本地标签和远程标签组成。


UAC

UAS

本地序列号

响应的 CSeq 头字段的序列号值

NULL

远程序列号

NULL

请求的 CSeq 头字段

dialog ID

请求的 Call-ID

请求的 Call-ID 值

本地标签

请求中 From 字段

响应中 To 字段

远程标签

响应中的 To 字段

请求中 From 字段

UAS收到的请求的序列号值比远程序列号值低,则请求无序,必须拒绝,返回 500(服务器内部错误)响应。

UAS收到的请求的序列号值比远程序列号值高,请求有序。UAS将远程序列号设置成请求的 CSeq 头字段值。

会话

INVITE 。。。 1XX 。。。2XX 。。。ACK

2XX响应时,建立会话及对话。

会话是一次通信过程中所有参与者之间的关联关系以及他们之间的媒体流的集合。只有当媒体协商成功后,会话才能被建立起来。

INVITE发起会话

Allow:对话内可以调用的方法

Supported:支持的扩展

Accept:接受的消息类型,如text,json,xml等

Expires:有效期   超时生成cancel请求

sip协议栈 java sip协议 udp_java_07

成功的 INVITE 请求(见第 13 章)同时建立两个用户代理之间的 对话 和 呼叫-应答模式的会话。

呼叫/应答模式:呼叫指出想要的通信方式(音频、视频、游戏)、这些方式的参数(如,编码类型)和接收应答器媒体的地址。“应答”,它指出接受哪种通信方式、使用于这些方式的参数和接受呼叫者的媒体类型。如SDP会话描述。INVITE 。。。2XX(或183)

1xx Responses,INVITE 请求的临时响应,可以创建“早期对话”。 2XX响应时,建立对话及会话。2XX的To字段后面的bag是对话的唯一标识,有多个invite时以此区分。1xx 和 2xx 响应都创建对话,如果此响应完成呼叫/应答交换,那么,它也创建会话。

3xx 响应可以包含一个或者多个 Contact 头字段——提供可以到达被呼叫者的新地址。

sip协议栈 java sip协议 udp_servlet_08

re-INVITE修改会话 – ip port 媒体流

呼叫保持

会话保持就是正在通话的用户,可以暂时中断数据原来的电话,而打出新的电话,同时与原来的电话保持联系;当需要回复原来的通话时,则使新打出的电话处于保持状态,再继续与原来的通话方通话,即可以通过操作按键选择及切换这两个通话,还可以分别或同时结束与他们的通话。会话保持业务与基本通话的不同之处在于,它使得我们可以有两个处于连接中的会话,而且可以在这两个会话之间进行任意次的来回切换。

保持,媒体流的方向为sendonly.  正常通话为 sendrecv

BYE结束会话

对话中,主叫方INVITE 的非 2xx 最终响应的效果是主叫使用了 CANCEL。如呼叫不通的603,487等。

挂断:对于呼叫者UA,如果初始的 INVITE 没有创建最终响应(仅1xx),那么挂断意味着 CANCEL 请求;对于在最终响应后所有确认的对话,挂断意味着 BYE。     对于被呼叫者 UA,一般来说,挂断意味着 BYE。

代理

对新的请求的处理过程:

  1. 确认请求
  2. 预处理路由信息
  3. 确定请求目标
  4. 向每个目标转发请求
  5. 处理所有响应

具体看   RFC3261的16.12.1 实例

*** 事务 ***

SIP 是一个事务协议:组件间的交互发生在一系列独立的消息交换中。具体来说,SIP事务由一个单一的请求和对这个请求的任何响应(包括零或多个临时响应以及一个或多个最终响应)组成。

事务匹配:唯一标识:Via 头字段中的分支参数。或Cseq的方法相同,如CANCEL的分支参数不同。

特别地,事务中的请求是 INVITE(称为 INVITE 事务)时,只有最终响应不是 2xx 响应时这个事务才包括 ACK。如果最终响应是 2xx,那么不应将 ACK 视为事务的一部分。

重传机制:INVITE后,不可靠传输(UDP)启动重传机制,在收到1XX后客户端就停止重传INVITE,等待进一步响应。对不可靠的传输来说,服务端的响应也主动周期性地重传,可靠传输(TCP)不要重传。相应的客户端事务对每个最终响应都发送一个ACK,用来结束响应重传。服务端TU将最新的响应,传送到传输层进行重传,不是由事务层可靠发送。

T1/T2

T1:是对服务器和客户端之间的事务往返延时(RTT)时间评估。 T1默认500ms

T2:非 INVITE 请求和 INVITE 响应的最长重新传输时间间隔。   T2默认4s,T4默认5s

重传,在总64T1=32秒后,就又会从T1开始发送注册请求,直到成功为止。共发7次重传请求,首发,0.5,1,2,4x7

场景:SIP终端发送了 200 OK以后就开始了媒体的创建,RTP语音流开始启动,事实上,SIP终端可能还没有收到ACK消息,因此在30秒左右,没有收到消息的一方就发送了一个BYE消息。

消息过长时,会使用 TCP 发送消息,而不使用 UDP。

INVITE事务

(非2XX最终响应) -- ACK 由TU - 事务– 传输层

C_TU:    INVITE(calling) -> 1XX(proceeding)->  非2XX(completed)==== >(Terminated)

C事务:  正在呼叫(发起客户端事务)       进行                       完成      终止(客户端事务被销毁)

       计时器A,B32s                          停止A,B                            计时器D

S_TU:   INVITE、1XX (proceeding)   ->  非2XX(completed)->  ACK(confirmed)  ==== >(Terminated)

S事务:                            进行                            完成                 确认              终止(服务端事务被销毁)

                                                    计时器G MIN(n*T1,T2), H32s   停G,H,启I(T4)     I触发

(2XX最终响应无定时器)--     ACK 由TU -–- - 传输层

C_TU:          INVITE      ->         1XX      ->        2XX (Terminated) 

C_事务:正在呼叫(发起客户端事务)      进行             终止(客户端事务被销毁)

S_TU:   INVITE, 1XX(proceeding)       ->   2XX(Terminated)

S_事务:                     正在呼叫(建立服务端事务)       终止(服务端事务被销毁)

非INVITE事务

C_TU : REQ(trying) ->      1XX(proceeding)->  2-6XX(completed)==== >(Terminated)

C_事务:       尝试(发起客户端事务)       进行                       完成      终止(客户端事务被销毁)

计时器E MIN(n*T1,T2),F32s   1xxE,F依然生效    EF停止,启动K(T4=5s)    K触发到终止态

S_TU:   REQ (trying)    ->   1XX(proceeding)  ->   2-6XX(completed)==== >(Terminated)       

S_事务:       尝试(建立服务端事务)         进行                            完成              终止(服务端事务被销毁)

                                                                                                   计时器J32s           J触发终止

注:INVITE、1XX     都可以直接收到     2XX

ACK 中的To 头字段必须与正在被确认的响应中的 To 头字段相等,但由于它添加了标记参数,因此它常常与原始请求中的 To 头字段不同。

非INVITE客户端事务

非 INVITE 事务不使用 ACK。它们是简单的请求--响应交互。如option,cancel,BYE

非INVITE事务,服务器事务只有在接收到重传请求时, 才会重传它发送的最后一个响应,这个响应可以是临时响应,也可以是最终响应。最终响应,停止事务重传请求。这就是即使在临时响应之后,仍需继续重传请求的原因:它们是为了确保可靠的传输最终响应。

SIP 和 SIP URI

形式:sip:user:password@host:port;uri-parameters?headers

注:字符串需转义

tcp默认5060,tcp+tls5061;tcps5061.注意:但是sip:user@host 与 sip:user@host:5060 不相等。

具体比较实例,参考  19.1.3 URI 比较

通话标记callid from-tag to-tag

invite:   callid      from-tag

180:     callid      from-tag       to-tag

sip信令实例 注册,会话建立          见 24实例

安全

TLS(TCP)        -- 在网络层和传输层提供安全

HTTP 认证         -- 挑战摘要验证模式

S/MME(TCP)      -- 为消息体提供端对端的完整性和保密性,也可以提供相互认证

附:

会话邀请拓扑图

sip协议栈 java sip协议 udp_java_09

sip重定向

sip协议栈 java sip协议 udp_sip协议栈 java_10

sip事务

sip协议栈 java sip协议 udp_开发语言_11

sip对话

sip协议栈 java sip协议 udp_java_12

sip梯形

sip协议栈 java sip协议 udp_java_13

register注册消息流

sip协议栈 java sip协议 udp_java_14

invite消息流

sip协议栈 java sip协议 udp_servlet_15

bye消息流

sip协议栈 java sip协议 udp_servlet_16

事件订阅和通知subscribe,notify

subscribe成功后至少有一个notify,确保全双工,后面是推过来的通知事件.

sip协议栈 java sip协议 udp_sip协议栈 java_17

即时消息message

sip协议栈 java sip协议 udp_sip协议栈 java_18

三方会议

sip协议栈 java sip协议 udp_开发语言_19

第二次invite alice时,contact携带功能标签tag-“isfocus”,表示Bob是一个会议处理中心。

SIP网络元素

1SIP 用户代理(SIP终端)
SIP 用户代理(UA) 是终端用户设备,用于创建和管理 SIP 会话的移动电话、多媒体手持设备、PC、PDA 等。用户代理客户机发出消息,用户代理服务器对消息进行响应。

2SIP 注册服务器
SIP 注册服务器是包含域中所有用户代理的位置的数据库。在 SIP 通信中,这些服务器会检索参对方的 IP 地址和其他相关信息,并将其发送到 SIP 代理服务器。

3SIP 代理服务器
SIP 代理服务器接受 SIP UA 的会话请求并查询 SIP 注册服务器,获取收件方 UA 的地址信息。然后,它将会话邀请信息直接转发给收件方 UA(如果它位于同一域中)或代理服务器(如果 UA 位于另一域中)。

4SIP 重定向服务器

SIP 重定向服务器允许 SIP 代理服务器将 SIP 会话邀请信息定向到外部域。SIP 重定向服务器可以与 SIP 注册服务器和 SIP 代理服务器同在一个硬件上。

sip协议结构

sip协议栈 java sip协议 udp_开发语言_20

SIP的逻辑分层从低到高如下:

语法和编码层

编码使用BNF(巴科斯范式)

传输层:

规定了客户端如何发请求收响应,服务端如何收请求发响应。所有的SIP元素都包含传输层。

事务层(状态机和定时器来实现重传):

事务是SIP协议的基本组成部分。事务是一个客户端事务层使用传输层发出的请求,服务器事务层返回的所有响应。事务层处理 应用层的重传、匹配对应响应给请求 、应用层超时等。有状态代理(stateful proxies)包含一个事务层,无状态代理(Stateless proxies)不包含事务层。事务层有一个客户端组件(称为客户端事务)和服务器组件(称为服务端事务),它们都用有限状态机表示,来处理特殊请求。

事务用户(TU):

除了stateless proxy,每个SIP实体都是一个事务用户TU。当事务用户想发送请求时,它就创建一个客户端事务实例( transaction instance),并将请求与目的的IP地址、端口一起发送。创建客户端事务的TU也可以通过CANCEL请求取消事务。CANCEL请求包含自己的事务,同时也提及需要取消的事务。

SIP要素有UAC,UAS,无状态和有状态proxy,和registrar。都包含一个核心(core)来区分,除了无状态代理外其余的核心都是TU。可以理解为,一个SIP实体的UA的core就是一个TU。

对话(dialogue),是两个ua间持续一段时间的端对端的sip关系。对于2xx响应的ACK,是由TU直接交付给传输层传输的,不经过事务层。