SIP概述
概念
-
sip(Session Initiation Protocol)会话初始协议是一个在IP网络上基于文本进行多媒体通信的应用层控制协议,用于创建、修改和释放一个或多个参与者的会话。
-
SIP 是一种源于互联网的IP 语音会话控制协议,具有灵活、易于实现、便于扩展等特点。
特点
-
一个重要特点是它不定义要建立的会话的类型,而只定义应该如何管理会话。
-
独立于传输层。因此SIP应用可以在TCP、UDP或其他低层网络协议上运行
-
灵活简练,可扩展,开放,兼容。
功能
SIP通过以下逻辑功能来完成通信:
-
用户定位功能:确定参与通信的终端用户位置。
-
用户通信能力协商功能:确定参与通信的媒体终端类型和具体参数。
-
用户是否参与交互功能:确定某个终端是否加入某个特定会话中。
-
建立呼叫和控制呼叫功能:包括向被叫“振铃”、确定主叫和被叫的呼叫参数、呼叫重定向、呼叫转移、终止呼叫等。
网络元素
-
用户代理(user agent)
-
代理服务器(proxy server)
-
重定向服务器(redirect server)
-
注册服务器(registor server)
-
位置服务器(location server)
消息类
SIP协议的亮点却不在于它的强大,而是在于:简单!
SIP协议是一个Client/Sever协议,因此SIP消息分两种:请求消息和响应消息。
请求消息是SIP客户端为了激活特定操作而发给服务器端的消息。常用的SIP请求消息如下:
Method | 说明 |
---|---|
REGISTER | 表示客户端向SIP服务器端注册列在To字段中的地址信息 |
INVITE | 表示主叫用户发起会话请求,邀请其他用户加入一个会话。也可以用在呼叫建立后用于更新会话(此时该INVITE又称为Re-invite) |
ACK | 客户端向服务器端证实它已经收到了对INVITE请求的最终响应 |
PRACK | 表示对1xx响应消息的确认请求消息 |
BYE | 表示终止一个已经建立的呼叫 |
CANCEL | 表示在收到对请求的最终响应之前取消该请求,对于已完成的请求则无影响 |
OPTIONS | 表示查询被叫的相关信息和功能 |
MESSAGE | RFC3428对Sip协议的扩展,增加了MESSAGE方法。采用Pager Model进行通信,传递不超过1300字节的数据。MESSAGE方法详细可参考 “SIP-RFC3428” RFC 3428: Session Initiation Protocol (SIP) Extension for Instant Messaging |
SUBSCRIBE | RFC6665对Sip协议的扩展,建立订阅关系,以获取特定事件的通知 |
NOTIFY | RFC6665对Sip协议的扩展,传递某种特定事件发生的信息,NOTIFY通常在订阅者与能和者之间建立的dialog内发送 |
INFO | - |
SIP协议中的响应消息用于对请求消息进行响应,指示呼叫的成功或失败状态。
状态代码的第一个数字定义了响应的类别,后面两位没有具体的分类
状态代码由3位数字组成,表示请求是否被理解或被满足。第一个数字有6种可能的取值:
Status-Code | 含义 |
---|---|
1xx: | 临时响应、表示请求消息正在被处理 |
2xx | 成功响应、表示请求已被成功接收完全理解并接收 |
3xx | 重定向响应、表示需采取进一步完成请求 |
4xx | 客户机错误、表示请求消息中包含语法错误信息或服务器无法完成客户机的请求 |
5xx | 服务器错误、表示服务器无法合法完成请求 |
6xx | 全局故障 、表示任何服务器都无法完成该请求 |
常用的一些响应消息:
Status-Code | msg | 含义 |
---|---|---|
100 | Trying | 试呼叫 |
180 | Ringing | 振铃 |
181 | Call is Being Forwarded | 呼叫正在前转 |
200 | OK | 成功响应 |
302 | Moved Temporarily | 临时迁移 |
400 | Bad Request | 错误请求 |
401 | Unauthorized | 未授权 |
403 | Forbidden | 禁止 |
404 | Not Found | 用户不存在 |
408 | Request Timeout | 请求超时 |
480 | Temporarily Unavailable | 暂时无人接听 |
481 | Call Leg Does Not Exist | 呼叫/事务不存在 |
486 | Busy Here | 线路忙 |
487 | Request terminated | 请求终止 |
504 | Server Time-out | 服务器超时 |
600 | Busy Everywhere | 全忙 |
消息体格式
-
请求行(request-line) or 状态行(status-line)
-
请求行格式:Method Request-URI SIP-Version CRLF
-
状态行格式: SIP-Version Status-Code Reason-Phrase CRLF
-
-
消息头(header)
Header 含义说明 举例 Call-ID 由本地设备(Client)生成,全局唯一,每次呼叫这个值唯一不变 Call-ID: asd88asd77a@1.2.3.4 From 表示请求的发起者 From: sip:user1@domain.com;tag=49583 To 表示请求的接收者 To: sip:user2@domain.com Via Via头域是被服务器插入request中,用来检查路由环的,并且可以使response根据via找到返回的路 Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse Max-Forwards 用于表示这个包最多可以传送多少跳,每经过一跳都会减一当Max-Forwards==0系统会返回483。默认为70 Max-Forwards: 70 Contact 包含源的URI信息,用来给响应方直接和源建立连接用 Contact: sip:192.168.100.1:1111 Content-Type 指明消息体的类型 (SDP会话描述协议) Content-Type: text/plain;Content-Type: application/sdp; Content-Type: application/cpim; Content-Length 指明消息体的字节大小 Content-Length: 18 -
正文(body)
基本流程
注册流程
下图显示了SIP注册流程
F1:sip代理向sip服务器发送Register请求,未包含Authorization字段
F2:sip服务器向sip代理发送响应401,并在响应的消息头WWW-Authenticate字段中给出适合sip代理的认证体制和参数
F3:sip代理向sip服务器重新发送Register请求,在请求的Authorization字段给出信任书,包含认证信息
F4:sip服务器对请求进行验证,如果检查出sip代理身份合法,向sip代理发送成功响应200OK,如果身份不合法则发送拒绝服务应答
呼叫流程
下图显示了SIP会话的基本呼叫流程
主叫方A呼叫被叫方B:
-
步骤1:主叫方A发送INVITE请求到代理服务器;
-
步骤2:代理服务器发送100 Trying 响应主叫方A;
-
步骤3~6:代理服务器搜索被叫方B的地址,获取地址后转发INVITE请求;
-
步骤7~9:被叫方B生成的180 振铃响应,返回给主叫方A;
-
步骤10~12:被叫方B生成的200 OK响应,返回给主叫方A;
-
步骤13~17:主叫方A收到被叫方B200 OK响应后,向被叫方B发送一个ACK,会话建立;
-
步骤18~20:会话结束后,任何参与者(A或B)都可以发送一个BYE请求来终止会话;
-
步骤21~23:主叫方A发送200 OK响应来确认BYE,会话终止。
注:以上的整个流程称之为一个Dialog
订阅流程
UA 使用SUBSCRIBE方法来建立订阅关系,以获取特定事件的通知(通过NOTIFY方法),SUBSCRIBE和NOTIFY都定义于RFC6665。订阅成功后在UAC和UAS间建立一个dialog。订阅请求包含一个Expires头域,它说明订阅存在的持续时间。期满之后,订阅关系自动终止。期满之前,可以再发一条SUBSCRIBE请求来刷新。服务端接受订阅时返回一条200 OK应答,它也包含一个Expires头域。限定的时间可以和请求一致,服务端可以缩短时间,不能延长时间。SIP中没有定义UNSUBSCRIBE方法,如果需要提前终止订阅,还是要通过SUBSCRIBE方法完成,Expires:0就表示终止。订阅终止时(不论是时间到期还是通过请求提前终止),都需要最后发一条NOTIFY消息来说明订阅已经终止。对SUBSCRIBE请求回应202 Accepted,并不表示订阅已经通过授权,它仅说明服务端已经了解订阅信息。
下图显示了订阅的基本流程。客户端发出SUBSCRIBE请求,收到成功应答。服务端事件触发时,客户端会收到NOTIFY。在订阅到期之前,客户端重新发SUBSCRIBE请求来展期,以便获知更多通知。
注意:客户端在收到SUBSCRIBE对应的200 OK应答之前,就应该准备好接收NOTIFY。此外,因为下游可能有分支,客户端必须准备好接收不同服务端的NOTIFY。尽管SUBSCRIBE只会收到一条对应的200 OK应答,但是,由于NOTIFY的To tag不同,因此需要建立独立的dialog。