SIP协议的概念:
SIP 协议,即 会话初始协议(Session Initiation Protocol),是一个应用层的 点对点协议,用于初始、管理和终止网络中的语音和视频会话,是 GB28181 的核心之一。
SIP是一个基于文本的应用层控制协议,独立于底层传输协议 TCP/UDP/SCTP,用于建立、修改和终止IP网上的双方或多方多媒体会话。 SIP 协议虽然属于应用层协议,然而 SIP 本身并不提供任何服务。但是 SIP 是通信的基础,在 SIP 这个通信的基础上可以用来构建不同的服务。
国标协议是基于sip协议开发的,国标的信令传递都依靠sip协议;在国标的实现中主要使用sip的register、 message、 invite、info、bye、subscribe、notify等消息,消息中重要的几个id:call-id、dialog-id、reg-id 。
sip消息:
• SIP消息分为请求和响应两类
• 消息中可以携带任意类型的消息体
• 用头域表示消息,实体或者消息体的相关属性
SIP消息格式:
• 这两种消息类型都由一个起始行,一个或者多个包头域,一个或多个可选的消息正文组成。
• 起始行、每一个包头行,空行、都必须由回车换行组成(CRLF)。即使消息 正文没有,也必须有一个空行跟随。
• 通用格式
SIP-Message = start-line
*message-header
CRLF
[message-body]
start-line是请求行(起始行)或者状态行:
请求行(起始行) : INVITE sip:bob@biloxi.com SIP/2.0
Request-Line : Method Request-URI SIP-Version CRLF
Method : 请求UAS处理的方法
Request-URI: 处理请求的用户或服务器的地址,并不是目的地址,是下一跳地址
SIP-Version : SIP协议版本号,供应用程序采用相应的兼容策略
状态行: SIP/2.0 200 OK
status-line:SIP-VERSION STATUS-CODE Reason-Phrase CRLF
SIP-VERSION : SIP协议版本号,供应用程序采用相应的兼容策略
STATUS-CODE :是一个3位的数字result code,用来标志处理请求的一个结果
Reason-Phrase :一个简短的Status-Code的说明
Sip消息举例:
-
请求报文REGISTER
-
请求报文INVITE
SIP消息的分类:
请求消息
REGISTER 注册请求,上报用户信息,完成号码绑定
INVITE 发起会话请求
CANCEL 取消一个尚未完成的请求,特别针对INVITE
ACK 为INVITE请求提供三次握手
BYE 结束会话请求
SUBSCRIBE 预定某个用户、资源或者呼叫的状态改变情况
NOTIFY 当被预定资源或者用户状态发生改变时向定制者发出通知
INFO 通话建立后,中间信息传输
OPTION 查询服务器或者是UA的能力
… 可扩展,体现SIP协议的灵活性
应答消息
1XX - 临时响应。表示请求正在处理中
2XX - 成功。表示请求处理成功
3XX - 重定向。提供重定向呼叫的号码
4XX - 客户端错误。错误来源于UAC
5XX - 服务端错误。错误来源于UAS
6XX - 全局错误。Server已知受到制约的条件
INVITE 请求的例子:
INVITE sip:bob@biloxi.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob sip:bob@biloxi.com
From: Alice sip:alice@atlanta.com;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: sip:alice@pc33.atlanta.com
Content-Type: application/sdp
Content-Length: 142
(Alice’s SDP not shown)
SIP头域介绍:
头域分类
- 通用头域
描述消息基本属性的头域 - 请求头域
仅在请求中有效,在应答中应该被忽略 - 应答头域
仅在应答中有效,在请求中应该被忽略 - 实体头域
用于描述消息体内容的长度、格式和编码类型等属性
头域格式:
头域遵循在RFC2822的2.2节定义的通用头域格式。每一个头域都由一个域名加上冒号(”:”)和域值组成。
field-name:field-value
任何SIP消息都必须携带的头域:
– From
– To
– Callid
– Max-Forwards
– Via
– Cseq
任何SIP消息缺少必选头域都是一个不完整的消息
这六个头域决定了消息的传送、响应的路径、事务的匹配、多个事务关联关系
SIP请求消息中常见头域介绍:
Via:
Via头域是用来描述请求当前经历的路径,并且标志了应答所应当经过的路径;
当UAC创建一个请求,它必须在头域中添加一个Via域;转发请求报文的Proxy在Via头域顶端添加自己的地址,并携带branch ID参数(提供了事务的标志,是Request-URI、To-Tag、From-Tag、Call-ID和CSeq的哈希值)
包含协议名、版本号、以及传输层协议(SIP/2.0/UDP, SIP/2.0/TCP, etc.)
Via头域必须包含一个分支(branch)参数,用于区分请求创建的事务。根据RFC3261产生的branch ID必须用”z9hG4bK”开头
TO
To头域定义了逻辑上请求的接收者
允许有一个显示用的姓名,由< >封装
FROM
From头域表示了请求的来源地
允许有一个显示用的姓名,由< >封装
UAC发起的请求必须包含Tag字段,用于标识一个特定的呼叫
CALL-ID
Call-ID是一个在一系列消息中,区分一组消息的唯一标志。在对话中的任一UA的所 有请求和所有应答的Call-ID必须一致
在UA的每次注册中,都应该是一样的
所有的SIP UA都必须保证自己产生的Call-ID不会和其他UA产生的Call-ID重复。注意,如果是请求的重传,则不被当作一个新的请求,所以不需要新的Call-ID。
CSeq
由一个方法(method)和一系列的顺序号码组成。方法(method)必须和请求的方法一致
CSeq 头域是用来区分事务的顺序,随着事务递增
UAS据此来判断该请求是一个新请求,还是一个重传的请求
Contact
在INVITE请求和200 OK响应里面必须存在
当UA处于防火墙后,该字段内容为防火墙URI,From字段为UA的URI地址
允许有一个显示用的姓名,由< >封装
Expires
Expires头域给定了消息(或者内容)过期的相关时间
出现在INVITE消息中,表示UAC的请求有效时间
出现在REGISTER消息中,表示Contact中URI地址的注册有效时间
Supported 和 Require
如果UAC支持服务端响应请求的SIP扩展,UAC应该在请求的时候包含一个Supported头域说明options tags描述那些SIP扩展
如果UAC要求UAS能够支持扩展,以便UAS能够处理UAC的特定请求,那么它必须在请求头中增加一个Require头域来说明处理本特定请求需要什么样的一个扩展option tags
Option tags是一个唯一标志,用来指明SIP中的新options(扩展)的。
Max-Forwards
限制请求到他的目的地中间的跳转。经过一次跳转就自动减一。如果Max-Forwards在到达目的之前就减到0,他会报告一个483(太多的路由)错误回应。
一个UAC必须为每一个请求填写一个Max-Forwards头域,这个字段的缺省值应该是70。
Route
Route头域用于强制一个请求经过一个proxy路由列表。
例如UA发出一个BYE请求,强制其经过PS
Record-Route
Record-Route头域是proxy在请求中增加的,用来强制会话中的后续请求经过本proxy的 。
后续消息路由选择策略:
Form、Contact、Via、Record-Route/Route,这几个字段均可作为路由选择依据,总的来说:协议栈中响应消息根据via携带url回复响应,后续请求消息根据上述字段中有Record-Route/Route就选Record-Route/Route,没有就根据contact字段、如果contact都没有就按照From字段携带url。
Sip消息包体:
• 请求信息都可以包含一个消息正文体
• 消息中的internet媒体类别必须在Content-Type头域中指明。
• 如果消息正文(body)通过某种形式的编码(encoding),比如压缩等等,都必须在Content-Encoding 头域中指明,否则Content-Encoding域必须忽略
• Content-Length头域中存放了包体的字节长度
例如:SDP
例如:DDCP
SIP应答消息:
应答消息分类
– 临时应答
提示进度,如果UAS不能马上接受或者拒绝邀请,那么它可以提示进度给UAC。这是通过一个101到199的临时应答实现的。
– 终结应答
很多情况下,在与方法无关的应答规范中,在非INVITE请求的情况下,我们都要求UAS不应该发送临时应答给请求者。在这种情况下,UAS应该尽快发送一个终结应答给非INVITE请求 。
请求的转发3xx
请求的接受2xx
请求的拒绝4xx/5xx/6xx
SIP应答消息中常见头域说明:
• 应答中的From头域必须和请求中的From头域相等。
• 应答中的Call-ID头域必须和请求中的Call-ID头域相等。
• 应答中的Cseq头域必须和请求中的Cseq头域相等。
• 应答中的Via头域必须和请求中的Via头域相等,而且顺序也必须相等。
• 如果请求中包含了To tag,那么应答中的To头域必须和请求中的To头域相等。
• 如果请求中的To头域并不包含Tag,那么应答中的To头域的URI必须和请求中的TO头域的URI相等;此外,UAS还必须增加一个Tag到To头域上(100(trying)应答是一个例外,在100中可能已经存在了一个tag)。这就提供了一个UAS正在应答的标志,也许就是对话ID的一部分。对同一个请求来说,它的应答必须有相同的tag标志,包括终结应答和临时应答(同样100(trying)除外)。
SIP响应消息举例:
应答报文200OK