【死磕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 | 表示服务器不支持的功能 |