【死磕opensips】sip协议解析
- 闲话
-
- webrtc专栏
- opensips专栏
- 开始
-
- sip历史
- 什么是sip
- sip 会话协议流程
- sip消息格式
-
- 请求行
- 状态行
- 消息头
- 结束
闲话
最近一直在跟一个关于音视频通话的项目,之前从webrtc结合coturn打洞转发思路,到现在关于opensips的思路,都是在慢慢摸索前进,当前期的研究不是没有结果的,问题是想要根据那些做成产品有点天方夜谭了;毕竟要走的路还有很远,坑还有很多,咱也不是怕折了腿的人,但是老总催的紧,咱不得不选择一个比较成熟的技术打底,毕竟无到有很难,还是要交一些学费的。
下面是我之前的笔记,有兴趣可以了解一下。
webrtc专栏
【webrtc专栏】
【java的P2P打洞通讯学习之路(一)- 整理思路】
【java的P2P打洞通讯学习之路(二)- 初识webRTC】
【java的P2P打洞通讯学习之路(三)- coturn服务器的搭建】
【海思3518ev200学习记录(1)- 根据用户手册烧录系统镜像】
【海思3518ev200学习记录(2) – 交叉编译官方webRTC】
【海思3518ev200学习记录(3) – 编译 amazon-kinesis webrtc嵌入式实现】
【海思3518ev200学习记录(4) – 基于海思源码分段录制音频文件】
【海思 3518 ev 200编译 报错 collect2: 错误: ld 返回 1】
opensips专栏
【opensips专栏】
开始
回归正题简单介绍一下sip。
sip历史
sipv1回话协议最早是在1996年由Mark Handley 和 Eve Schooler起草的,在1999年成为标准协议。后续经过多为前辈的贡献有了现在成熟sip技术。
什么是sip
SIP(Session Initiation Protocol,会话初始协议)可以支持并应用于语音、视频、数据等多媒体业务。sip提供了用户地址信息(用户终端地址),确定被叫方参与通讯的意愿,确定使用的介质和介质参数,振铃以及会话终止。sip 支持Presence(呈现)、Instant Message(即时消息)等特斯业务可以说,有IP网络的地方就有SIP协议的存在。
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,会话终止。

sip消息格式
sip的消息格式与http类似,由三部分组成:
line 请求行(request-line) or 状态行(status-line)
Several Headers 消息头(header)
Message Body 消息正文(body)
请求行
- method: 确定请求的类型
- SIP URI: 确定请求的目的地
- SIP protocol version:SIP协议版本
例如:< METHOD> < Request-URI> SIP/2.0
SIP版本2.0中的六种基本方法INVITE,REGISTER,BYE,ACK,CANCEL,OPTIONS。
method的所有类型:
| Method | 类型说明 |
|---|---|
| INVITE | 启动/修改会话 |
| ACK | 确认收到对邀请的最终回复 |
| CANCEL | 取消挂起的邀请 |
| UPDATE | 更新挂起会话的参数 |
| BYE | 结束会话 |
| OPTIONS | 请求支持的功能 |
| REGISTER | 将IP地址附加到SIP URI |
| REFER | 请求UA访问URI或URL |
| SUBSCRIBE | 建立订阅以接收有关事件的通知 |
| NOTIFY | 传达特定事件发生的信息 |
| PRACK | 确认收到可靠传输的临时响应 |
| MESSAGE | 使用SIP传输即时消息 |
| INFO | 将呼叫信令信息发送到另一个与其建立了媒体会话的用户代理 |
状态行
- SIP protocol version:SIP协议版本
例如: SIP/2.0 < Status-Code> < Reason-Phrase>
- status-code:数字响应代码
相应代码中第一个数字分为六种情况
| 状态码 | 说明 |
|---|---|
| 1xx | 临时响应,表示消息正在处理 |
| 2xx | 成功响应,表示消息被成功接收 |
| 3xx | 重定向响应,表示临时转移或永久转移 |
| 4xx | 客户端错误,表示客户端请求中有服务器无法理解的信息 |
| 5xx | 服务器错误,表示服务器无法完成请求,或服务器不可用 |
| 6xx | 全局故障,表示所有服务器都无法完成请求信息 |
所有状态码示例:
| 状态码 | 说明 |
|---|---|
| 100 | 尝试呼叫 |
| 180 | 振铃 |
| 181 | 正在转接呼叫 |
| 182 | 排队 |
| 183 | 会话进度 |
| 200 | 成功响应 |
| 202 | 认可 |
| 300 | 多项选择 |
| 301 | 永久移除 |
| 302 | 临时转移 |
| 303 | 见其他 |
| 305 | 使用代理 |
| 380 | 代替服务 |
| 400 | 错误请求 |
| 401 | 未授权 |
| 402 | 需要付款 |
| 403 | 禁止 |
| 404 | 未找到服务器 |
| 405 | 方法不允许 |
| 406 | 请求不被接受 |
| 407 | 代理身份验证 |
| 408 | 请求超时 |
| 409 | 请求冲突 |
| 410 | 请求不见了 |
| 411 | 请求所需长度 |
| 413 | 请求实体过大 |
| 414 | 请求URL过长 |
| 415 | 不支持的媒体类型 |
| 420 | 错误扩展 |
| 480 | 暂时不可用 |
| 481 | 呼叫分支/事务不存在 |
| 482 | 检测到环路 |
| 483 | 跳太多了 |
| 484 | 地址不完整 |
| 485 | 请求不明确 |
| 486 | 这里很忙 |
| 487 | 请求已取消 |
| 488 | 这里不能接受 |
| 500 | 内部服务器错误 |
| 501 | 未实施 |
| 502 | 坏网关 |
| 503 | 服务不可用 |
| 504 | 网关超时 |
| 505 | 不支持SIP版本 |
| 600 | 全局故障 |
| 603 | 拒绝 |
| 604 | 在任何地方都不存在 |
| 606 | 不可接受 |
- reason phrase:理由短语
消息头
示例:
INVITE sip:barbara@b.com SIP/2.0
Via: SIP/2.0/UDP 10.43.122.3;branch=1
From: sip:alice@a.com;tag=4ad340f
To: sip:barbara@b.com
Contact: <sip:alice@10.43.122.3>
Call-ID: 1874630@10.43.122.3
Cseq: 12442 INVITE
v=0
o=user 14341433 14341433 IP4 10.43.122.3
s=.
t=0 0
c=IN IP4 10.43.122.3
m=audio 13222 RTP/AVP 0
a=rtpmap:0 PCMU/8000
Header 字段含义说明:
| Header | 说明 |
|---|---|
| Call-ID | 用于唯一标识两个用户代理之间的调用 |
| Contact | 用于传递请求的原始资源或请求发起人的URL |
| CSeq | 命令序列识别顺序错误的请求和重传 |
| From | 标识请求的发起人 |
| To | 表示请求的收件人 |
| Subject | 表示媒体会话主题的可选标题 |
| Content-Length | 消息正文中的八位字节数 |
| Content-Type | 表示Internet媒体类型。如果不存在,则假定应用程序/SDP |
| User Agent | 提供有关用户代理的附加信息,例如制造商 |
| Server | 提供有关用户代理服务器的附加信息 |
| Via | 记录请求所采用的路由,并用于路由响应 |
| Record-Route | 用于强制UAs之间的所有请求通过代理路由 |
| Route | 强制路由通过从记录路由头中提取的路径 |
| Max-forwards | 限制一个请求在到达目的地的途中可以进行的跳数(70) |
| Authorization | 将用户代理的凭据传送到服务器 |
| Encryption | 用于指定SIP消息中已加密的部分 |
| Hide | 请求下一跳代理对Via头进行加密 |
| Priority | 允许用户代理设置请求的优先级:例如紧急、紧急 |
| Supported | 列出一个或多个在用户代理或服务器中实现的选项 |
| Unsupported | 表示服务器不支持的功能 |
结束

