本章开始要一步步深入对28181协议中具体的交互协议信令的剖析,请大家耐下心来,一起搞懂他。
本章以及后续章节描述的协议内容将主要参考GB/T 28181最新在行的2022版本,在描述中将会标注出是否是2022版本特有,且核心协议基本是向下兼容的,大家可以放心食用。
1. 基本的注册以及注销
注册
指的是设备或系统进入联网系统时向SIP服务器
(SIP UAS)进行注册登记的工作模式,其中SIP代理
(SIP UAC)意味着支持28181协议的摄像头或者系统;注销
流程与注册流程类似,在信令中有特殊字段进行区分识别,在下述中我们会单独说明。
1.1 注册/注销整体流程
基本注册/注销流程描述如下:
- SIP代理向SIP服务器发送
REGISTER
请求,其中Expires字段的值为0,表示SIP代理要注销,否则为注册流程; - SIP服务器向SIP代理发送响应
401
,并在响应的消息头WWW_Authenticate
字段中给出适合SIP代理的认证体制和参数; - SIP代理重新向SIP服务器发送
REGISTER
请求,在请求的Authorization
字段给出信任书,包含认证信息,注销流程时,Expires字段的值为0; - SIP服务器对请求进行验证,如果检查出SIP代理身份合法,向SIP代理发送成功响应
200OK
,如果SIP代理身份不合法则发送拒绝服务应答。
当然sip服务器也可关闭鉴权,只需要上述1、4两步即可。
当sip代理获取到2步骤拿到的认证参数后,接下来的注册也可以只进行3、4步骤,比较灵活。
接下来我们将上述四个步骤一一拆解开分析一下。
1.2 sip代理注册第一次
信令总览
REGISTER sip:51000000002000000001@5100000000 SIP/2.0
Via: SIP/2.0/UDP 10.18.34.1:5060;rport;branch=z9hG4bK1193130769
From: <sip:62010001001187000003@5100000000>;tag=1692749618
To: <sip:62010001001187000003@5100000000>
Call-ID: 331103435
CSeq: 75 REGISTER
Contact: <sip:62010001001187000003@10.18.34.1:5060>
Max-Forwards: 70
User-Agent: Embedded Net DVR/NVR/DVS
Expires: 180
Content-Length: 0
重要信令解析
REGISTER sip:51000000002000000001@5100000000 SIP/2.0
- REGISTER:SIP消息的方法(Method)是REGISTER,注册流程下,此为固定值
- sip:51000000002000000001@5100000000: 即Request-URI,说明如下:
-
51000000002000000001:是SIP服务器的国标ID,编码由中心编码(8位)、行业编码(2位)、类型编码(3位)、网络标识(1位)和序号(6位)5个码段共20位十进制数字字符构成,即系统编码=中心编码+行业编码+类型编码+网络标识+序号。
-
5100000000: 指的是SIP服务器的域国标ID
-
SIP/2.0:SIP/2.0指的是SIP协议版本
Via: SIP/2.0/UDP 10.18.34.1:5060;rport;branch=z9hG4bK1193130769
Via头中包含了发送请求方的相关信息,后续需要使用这些信息进行回复。
- SIP/2.0/UDP: 表示使用的是2.0版本的SIP协议,使用的传输协议是UDP,也可以使用TCP协议。
- 10.18.34.1:5060: 为请求发送方的IP地址和端口号。
- branch: Via头中必须包含branch参数,具体值是一个在整个SIP通信过程中不重复的数值。branch是一个事务ID(Transaction ID),用于区分同一个UA所发起的不同Transaction,它不会对未来的request或者是response造成影响,对于遵循RFC3261规范的实现,这个branch参数的值必须用”z9hG4bK”打头. 其它部分是对To, From, Call-ID头域和Request-URI按一定的算法加密后得到。
- rport: 字段表示使用rport机制路由响应,即发送的响应时,按照rport中的端口发送SIP响应,也就是说IP和端口均完全遵照从哪里来的,发回哪里去的原则,如果没有rport字段时,服务端的策略是IP使用UDP包中的地址,即从哪里来回哪里去,但是端口使用的是via中的端口,详情见RFC3581。所以这里在互联网环境下需要考虑via中ip端口是否可达。
From: <sip:62010001001187000003@5100000000>;tag=1692749618
- From头:中包含了请求发送方的逻辑标识,在GB28181协议中是发送请求的设备国标ID和域国标ID信息。
- tag:参数是为了身份认证的,值为随机数字字符。
To: <sip:62010001001187000003@5100000000>
- To头: 在SIP协议中是为了标明请求接收方的逻辑标识的,在GB28181协议中填写的是发送请求的设备国标ID和域国标ID信息。
Call-ID: 331103435
- Call-ID头:是全局唯一的,在同一个session中保持一致,在不同session中不同。
CSeq: 75 REGISTER
- CSeq头: 又叫Command Seqence(命令队列),用于标识命令顺序,值为序号+Method,序号部分为无符号整数,最大值为2^31。序号起始值是随机的,后续在同一个session中依次递增,比如发1 REGISTER没返回--->再发2 REGISTER--->没返回--->再发3 REGISTER--->这时返回了2 REGISTER就知道是第2个请求得到了响应。对于ACK和CANCLE中的CSeq与INVITE中的Cseq保持一致。
Contact: <sip:62010001001187000003@10.18.34.1:5060>
- Contact头: 包含源的URI信息,用来给响应消息直接和源建立连接用。在GB28181协议中为SIP设备编码@源IP地址端口。
Max-Forwards: 70
- Max-Forwards头:用于设置包最大中转次数,默认是70。
User-Agent: Embedded Net DVR/NVR/DVS
- User-Agent头: 用于设置关于UA的信息,用户可以自定义。
Expires: 180
- Expires头:表示超时时间,值为0时表示当前为注销流程。
Content-Length: 0
- Content-Length头:Content-Length报头字段指示发送给消息体的大小,以十进制八位字节为单位,消息体的大小不包括分隔报头字段和正文的CRLF。无论实体的媒体类型如何,应用程序都应该使用此字段来指示要传输的消息体的大小。如果使用基于流的协议(如TCP)作为传输,则必须使用报头字段。因为REGISTER消息不需要SDP,因此为0。如果消息中不存在消息体,则Content-Length报头字段值必须设置为零。
1.3 sip服务器回复第一次
信令总览
SIP/2.0 401 Unauthorized
To: <sip:62010001001187000003@5100000000>;tag=1198202625
From: <sip:62010001001187000003@5100000000>;tag=1692749618
Call-ID: 331103435
CSeq: 75 REGISTER
Max-Forwards: 70
Via: SIP/2.0/UDP 10.18.34.1:5060;rport;branch=z9hG4bK1193130769
User-Agent: zdww sip server
WWW-Authenticate: Digest realm="51000000",nonce="a8afe6fcbee6331d89d3eb0d3d19ce39",opaque="a853e4f25298413f9bf3a9aa6767857d",algorithm=MD5
Expires: 180
Content-Length: 0
重要信令解析
- SIP/2.0 401 Unauthorized
- 401 Unauthorized:请求需要用户验证,对应的每次指令后都会有对端去回应消息,会有成功、失败,具体描述可查看后续条目。
WWW-Authenticate: Digest realm="51000000",nonce="a8afe6fcbee6331d89d3eb0d3d19ce39",opaque="a853e4f25298413f9bf3a9aa6767857d",algorithm=MD5
- WWW-Authenticate头:WWW-Authenticate头用于配置服务端支持的认证方式及认证参数,这里认证方式为digest。
- nonce:为数字摘要经 过 BASE64编码后的值。
- algorithm :为数字摘要的算法名称。
1.4 sip代理携带认证信息注册第二次
信令总览
REGISTER sip:51000000002000000001@5100000000 SIP/2.0
Via: SIP/2.0/UDP 10.18.34.1:5060;rport;branch=z9hG4bK1242248676
From: <sip:62010001001187000003@5100000000>;tag=1692749618
To: <sip:62010001001187000003@5100000000>
Call-ID: 331103435
CSeq: 76 REGISTER
Contact: <sip:62010001001187000003@10.18.34.1:5060>
Authorization: Digest username="62010001001187000003", realm="51000000", nonce="a8afe6fcbee6331d89d3eb0d3d19ce39", uri="sip:51000000002000000001@5100000000", response="85d8f290f0050ad9ba84d44ebad695ac", algorit
=MD5, opaque="a853e4f25298413f9bf3a9aa6767857d"
Max-Forwards: 70
User-Agent: Embedded Net DVR/NVR/DVS
Expires: 180
Content-Length: 0
重要信令解析
Authorization: Digest username="62010001001187000003", realm="51000000", nonce="a8afe6fcbee6331d89d3eb0d3d19ce39", uri="sip:51000000002000000001@5100000000", response="85d8f290f0050ad9ba84d44ebad695ac", algorit =MD5, opaque="a853e4f25298413f9bf3a9aa6767857d"
- 应对SIP信令做数字摘要认证,宜支持 MD5、SHA-1、SHA-256等数字摘要算法。在 SIP消息头域中,启用 Date域,增加Note域。Note=(Digestnonce="",algorithm=)。
- nonce:为数字摘要经 过 BASE64编码后的值。
- algorithm :为数字摘要的算法名称。
- 当跨域访问时,若该信令是由本域的用户发起,则信令安全路由网关宜将发送到外域的信令添加 Monitor-User-Identity头域,其取值为信令安全路由网关ID 和用户的身份信息;若该信令不是由本域 的用户发起,则只在原有 Monitor-User-Identity域值前添加信令安全路由网关ID;各段分隔符为“-”。
1.5 sip服务器验证sip代理身份回复第二次
信令总览
SIP/2.0 200 OK
To: <sip:62010001001187000003@5100000000>;tag=1198202654
From: <sip:62010001001187000003@5100000000>;tag=1692749618
Call-ID: 331103435
CSeq: 76 REGISTER
Max-Forwards: 70
Via: SIP/2.0/UDP 10.18.34.1:5060;rport;branch=z9hG4bK1242248676
Contact: <sip:62010001001187000003@5100000000>;tag=1198202654
User-Agent: zdww sip server
Expires: 180
Date: 2024-08-29T14:55:29
Content-Length: 0
重要信令解析
SIP/2.0 200 OK
- 200 OK:验证成功。
Date: 2024-08-29T14:55:29
- 时间信息,用于设备同步时间,采用的格式为 XML标准格式:Date:yyyy-MM-dd'T'HH:mm:ss.SSS。
2. 保活
当UAC发现工作异常时, 应立即向本SIP监控域的SIP服务器发送状态信息; 无异常时,应定时向本SIP监控域的SIP服务器发送状态信息。状态信息报送采用RFC3427定义的方法MESSAGE实现。通过周期性的状态信息报送,实现注册服务器与源设备之间的状态检测即心跳机制。
心跳发送方、接收方需统一配置“心跳间隔”参数,按照“心跳间隔”定时发送心跳消息,默认心跳间隔60s。心跳发送方、接收方需统一配置“心跳超时次数”参数,心跳消息连续超时达到“心跳超时次数”则认为对方下线,默认心跳超时次数3次。心跳接收方在心跳发送方上线状态下检测到心跳消息连续超时达到商定次数则认为心跳发送方离线; 心跳发送方在心跳接收方上线状态下检测到心跳消息响应消息连续超时达到商定次数则认为心跳接收方离线。
2.1 心跳信令
信令总览
MESSAGE sip:34020000002000000001@3402000000 SIP/2.0
Via: SIP/2.0/UDP 192.168.137.11:5060;rport;branch=z9hG4bK1066375804
From: sip:34020000001320000003@3402000000;tag=1925919231
To: sip:34020000002000000001@3402000000
Call-ID: 1185236415
CSeq: 20 MESSAGE
Content-Type: Application/MANSCDP+xml
Max-Forwards: 70
User-Agent: IP Camera
Content-Length: 175
<?xml version="1.0" encoding="UTF-8"?>
<Notify>
<CmdType>Keepalive<CmdType>
<SN>1</SN>
<DeviceID>34020000001320000003</DeviceID>
<Status>OK</Status>
<Info>
</Info>
</Notify>
重要信令解析
MESSAGE sip:34020000002000000001@3402000000 SIP/2.0
- MESSAGE: SIP消息的方法(Method)是MESSAGE,在收到 Message消息后,应立即返回应答,应答均无消息体。
Content-Type: Application/MANSCDP+xml
- Application/MANSCDP+xml: 设备控制命令采用 MANSCDP协议格式定义。设备控制命令应包括命令类型(CmdType)、命令序列号(SN)、设备编码(DeviceID)、子命令等,采用 Message方法的消息体携带。
xml消息体
<?xml version="1.0" encoding="UTF-8"?>
<Notify>
<CmdType>Keepalive</CmdType> // 心跳控制字段
<SN>1</SN> //SN 值用于与请求命令的匹配处理,响应命令中的SN 值应使用请求命令中的SN值
<DeviceID>34020000001320000003</DeviceID> // 设备编码
<Status>OK</Status> // 是否正常工作
<Info>
</Info>
</Notify>
其中 Notify为Messagee,简要说明如下:
心跳信令xml格式要求
<! -- 命令类型:设备状态信息报送(必选)-->
<elementname="CmdType"fixed="Keepalive"/>
<! -- 命令序列号(必选)-->
<elementname="SN" type="integer"minInclusivevalue= "1"/>
<! -- 源设备的设备/系统编码(必选)-->
<elementname="DeviceID" type="tg:deviceIDType"/>
<! -- 是否正常工作(必选)-->
<elementname="Status"type="tg:resultType"/>
<! --故障设备列表-->
<elementname="Info">
<complexType>
<sequence>
<elementname="DeviceID"type="tg:deviceIDType" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
2.2 心跳信令的回复
信令总览
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.137.11:5060;rport;branch=z9hG4bK1066375804
From: sip:34020000001320000003@3402000000;tag=1925919231
To: sip:34020000002000000001@3402000000
CSeq: 20 MESSAGE
Call-ID: 1185236415
User-Agent: test
Content-Length: 0
- Call-ID:同心跳call id值,表明是同一个session。
3. 信令格式说明整理
3.1 错误码整理
SIP以及28181协议中包含了一系列错误码,用于指示系统在通信和交互过程中可能遇到的各种问题和状态,用在部署、对接、调试中。
- 1xx 信息性响应
- 100 Trying:呼叫方正在呼叫,但尚未联系到被呼叫方。
- 180 Ringing:被呼叫方已被联系到,其铃声正在响。收到此信息后,通常等待200 OK。
- 181 Call is being forwarded:呼叫正在被转发到另一个目的地。
- 182 Queued:被呼叫方当前不可用,但不想直接拒绝呼叫,而是选择将其放入呼叫队列中。
- 183 Session progress:用于警告呼叫方频段(inband)错误。当从PSTN收到一个ISDN消息时,SIP网关会产生此响应。
- 2xx 成功响应
- 200 OK:请求已成功处理。
- 3xx 重定向响应
- 300 Multiple Choices:有多个选项可用于处理请求。
- 301 Moved Permanently:请求的资源已永久移动到新的URI。
- 302 Moved Temporarily:请求的资源临时移动到新的URI。
- 4xx 请求失败
- 400 Bad Request:请求无法理解,因为语法有误。
- 401 Unauthorized:请求需要用户验证。
- 404 Not Found:服务器上未找到请求的资源。
- 5xx 服务器内部错误
- 500 Server Internal Error:服务器遇到意外情况,导致其无法完成请求。
- 503 Service Unavailable:由于临时的服务器维护或过载,服务器当前无法处理请求。
3.2 请求类型
Method | 说明 |
---|---|
INVITE | 发起会话请求,用于邀请用户加入会话,SDP中包含会话描述。 |
ACK | 证实已经收到对于INVITE请求的最终响应 |
BYE | 结束会话 |
CANCEL | 取消尚未完成的请求,对已经完成的请求没有影响 |
REGISTER | 注册 |
OPTIONS | 查询服务器能力 |
SUBSCRIBE | 类似于无线电协议上的信息请求,要求另一方报告任何特定状态或者事件 |
NOTIFY | 类似于协议上的测量报告或者信息响应。传递subscribe消息请求的信息 |