GB28181协议--校时

article/2025/9/19 15:47:14

1、简介

根据《GB/T 28181 —2016》7.10、9.10的要求,GB28181设备网络校时功能描述如下:
联网系统内的IP 网络服务器设备宜支持 NTP(见IETF RFC2030) 协议的网络统一校时服务。 网络校时设备分为时钟源和客户端, 支持客户/服务器的工作模式; 时钟源应支持 TCP/IP、UDP 及 NTP协议, 能将输入的或自身产生的时间信号以标准的 NTP 信息包格式输出。联网系统内的IP 网络接入设备应支持SIP 信令的统一校时, 接入设备应在注册时接受来自SIP 服务器通过消息头 Date 域携带的授时。

2、基本流程

联网内设备支持基于SIP 方式或 NTP 方式的网络校时功能, 标准时间为北京时间。流程如下所示:
在这里插入图片描述
在注册成功情况下, 注册流程的最后一个 SIP 应答消息200 OK 中的 Date 头域中携带时间信息。采用的格式为 XML 标准格式:Date: yyyy-MM-dd’T’HH: mm:ss.SSS。
若SIP 代理通过注册方式校时, 其注册过期时间宜设置为小于 SIP 代理与 SIP 服务器出现1 s 误差所经过的运行时间。 例如:SIP 代理与SIP 服务器校时后,SIP 代理运行10 h 后设备时间与SIP 服务器时间相差大于1 s, 则宜将注册过期时间设置为10 h(36 000s) , 以保证SIP 代理与SIP 服务器之间时间误差小于1 s。

3、基于SIP的校时

sip信令处理:

int SipReg(GB28181Param_t *pGB28181Param, int isReg)
{int ret = 0;int len = 0;char *msg;int expires = 0 ;int regState = 0;int unAuthorized = 0;eXosip_event_t *je = NULL;osip_header_t *dest = NULL;osip_message_t *reg = NULL;long interval = GetSysSec();if (!pGB28181Param){return SIP_FAILED;}if (isReg){expires = strtoul(pGB28181Param->userParam.sipExpires, 0, 0);}while(GetSysSec() -interval <= MAX_SIP_REG_TIMEOUT_SEC){// 先进行不认证注册if (0 == unAuthorized){ret = SipRegisterUnauthorized(pGB28181Param, expires);if (ret < 0){if(je){eXosip_event_free(je);}return SIP_FAILED;}else {unAuthorized = 1;}}je = eXosip_event_wait(0, 100);  		/* 等待新消息的到来 */if(NULL == je){/* 以下语句会导致eXosip_register_send_register失败 */eXosip_automatic_action();usleep(100*1000);continue;}/* 返回注册失败 */if(EXOSIP_REGISTRATION_FAILURE == je->type){/* 未认证注册失败,那么使用认证的方式进行注册 */if((je->response!=NULL) && (401==je->response->status_code)){ret = SipRegisterAuthorized(pGB28181Param, je->rid, expires);eXosip_event_free(je);if(ret != OSIP_SUCCESS){return SIP_FAILED;}}else {eXosip_event_free(je);unAuthorized = 0;			/* 注册失败, 重新走一遍注册流程 */if (isReg){return SIP_REREG_AFTER_60S;}return SIP_FAILED;}}else if (EXOSIP_REGISTRATION_SUCCESS == je->type){regState = 1;/* 收到服务器返回的注册成功 */g_SipState.registerID = je->rid;	if (MSG_IS_REGISTER(je->request) && je->response){if (OSIP_SUCCESS == osip_message_to_str(je->response, &msg, &len)){if (osip_message_get_date(je->response, 0, &dest) > 0){SipSetSystemTime(dest->hvalue);}}}eXosip_execute();eXosip_automatic_action();eXosip_event_free(je);break;}else{eXosip_event_free(je);}}if( (GetSysSec() -interval > MAX_SIP_REG_TIMEOUT_SEC) && (regState == 0)){return SIP_FAILED;}pthread_mutex_lock(&g_SipState.mutex);// 更新sip的注册状态if (isReg){g_SipState.sipRegStatus = 1;g_SipState.keepliveAckTime = GetSysSec();}else {g_SipState.sipRegStatus = 0;}pthread_mutex_unlock(&g_SipState.mutex);return SIP_SUCCESS;
}

设置系统时间接口:

static int SipSetSystemTime(char *timeStr)
{char *beginStr = timeStr;char *endStr = NULL;char tempStr[10] = {0, };struct tm st_time = {0, };struct timeval tv = {0, };uint32_t stime = 0;if (!timeStr){return SIP_FAILED;}if ((endStr = strstr(beginStr, "-"))){memset(tempStr, 0, sizeof(tempStr));strncpy(tempStr, beginStr, endStr-beginStr);beginStr = endStr + 1;stime = strtoul(tempStr, NULL, sizeof(tempStr));st_time.tm_year = stime - 1900;}if ((endStr = strstr(beginStr, "-"))){memset(tempStr, 0, sizeof(tempStr));strncpy(tempStr, beginStr, endStr-beginStr);beginStr = endStr + 1;stime = strtoul(tempStr, NULL, sizeof(tempStr));st_time.tm_mon = stime - 1;}if ((endStr = strstr(beginStr, "T"))){memset(tempStr, 0, sizeof(tempStr));strncpy(tempStr, beginStr, endStr-beginStr);beginStr = endStr + 1;stime = strtoul(tempStr, NULL, sizeof(tempStr));st_time.tm_mday = stime;}if ((endStr = strstr(beginStr, ":"))){memset(tempStr, 0, sizeof(tempStr));strncpy(tempStr, beginStr, endStr-beginStr);beginStr = endStr + 1;stime = strtoul(tempStr, NULL, sizeof(tempStr));st_time.tm_hour = stime;}if ((endStr = strstr(beginStr, ":"))){memset(tempStr, 0, sizeof(tempStr));strncpy(tempStr, beginStr, endStr-beginStr);beginStr = endStr + 1;stime = strtoul(tempStr, NULL, sizeof(tempStr));st_time.tm_min = stime;}if ((endStr = strstr(beginStr, "."))){memset(tempStr, 0, sizeof(tempStr));strncpy(tempStr, beginStr, endStr-beginStr);beginStr = endStr + 1;stime = strtoul(tempStr, NULL, sizeof(tempStr));st_time.tm_sec = stime;}// 设置系统时间if ((tv.tv_sec = mktime(&st_time)) < 0){GB_PrintError("mktime failed\n");return SIP_FAILED;}settimeofday(&tv, NULL);// 设置RTC时间struct tm *stTime = gmtime(&tv);if (SetRtcTime(stTime) < 0){return SIP_FAILED;		}return SIP_SUCCESS;
}

参考资料:
《GBT 28181-2016 公共安全视频监控联网系统信息传输、交换、控制技术要求》
推荐阅读:GB28181协议–设备注册和注销


http://chatgpt.dhexx.cn/article/Sm1hKq7Q.shtml

相关文章

GB28181协议常见几种信令流程(一)

在监控系统中&#xff0c;常见的摄像机设备互联协议有国际标准的ONVIF、国标的GB28181和各厂商的私有连接协议&#xff0c;本章从GB28181-2016中摘抄整理常见信令流程&#xff0c;如28181的会话/媒体通道、SIP基本注册/注销流程、客户端主动发起视频点播流程、设备控制流程等。…

国标GB28181协议客户端开发(一)整体流程和技术选型

国标GB28181协议客户端开发&#xff08;一&#xff09;整体流程和技术选型 本系列文章将介绍国标GB28181协议设备端的开发过程。本文旨在探讨整体设计和技术选型方面的考虑&#xff0c;为开发人员提供指导和参考。文章将从设备端开发的整体架构、信令交互流程以及关键技术选型等…

java gb28181网关_国标GB28181协议对接网关

国标GB28181网关概述 国标GB28181《安全防范视频监控联网系统信息传输、交换、控制技术要求》最新版为2016年版&#xff0c;较2011年版更加完善&#xff0c;其是基于SIP协议的视频联网框架标准。因其核心应用于公安视频联网&#xff0c;在平安城市、雪亮工程超大规模视频监控联…

GB28181协议之录像回放

目录 一、概述 二、录像文件播放 2.1 基本要求 2.2 命令流程 2.3 抓包示例 2.3.1 Invite请求[SIP服务器---->设备] 2.3.2 Invite应答[设备---->SIP服务器] 2.3.3 ACK[SIP服务器---->设备] 2.3.4 Bye结束回放 2.3.5 Bye应答 2.3.6 播放速度控制 2.3.6 控制…

GB28181协议之实时视频

目录 一、概述 二、实时视频 2.1基本要求 2.2命令流程 2.3抓包示例 2.3.1 Invite请求[SIP服务器----->设备] 2.3.2 Invite应答[设备---->SIP服务器] 2.3.3 ACK[SIP服务器----->设备] 2.3.4 Bye 2.3.5 Bye应答 三、国标平台介绍 一、概述 近年来&#xff0c;国…

GB28181协议--实时视音频点播(预览)

1、基本要求 根据《GB/T 28181 —2016》第9章关于实时视音频点播的描述&#xff0c;其内容如下&#xff1a; 实时视音频点播的SIP 消息应通过本域或其他域的SIP 服务器进行路由、 转发, 目标设备的实时视音频流宜通过本域内的媒体服务器进行转发。实时视音频点播采用SIP 协议…

GB28181协议--心跳

1、心跳介绍&#xff1a; 根据《GBT 28181-2016 公共安全视频监控联网系统信息传输、交换、控制技术要求》9.6.1状态信息报送章节描述。 当源设备(包括网关、SIP 设备、SIP 客户端或联网系统) 发现工作异常时, 应立即向本 SIP 监控域的SIP服务器发送状态信息; 无异常时, 应定…

国标28181: 视频国标28181协议

国标的由来 GB28181国标解决平台与平台对接问题 比如A平台大连交警系统需要看B平台上海交警系统的视频。需要对接过来&#xff0c;实现调度视频。这时候需要知道他们取流的协议&#xff0c;各家厂商都自定义了一套协议&#xff0c;就很麻烦&#xff0c;因此国家就制定了GB28…

【C/C++】isalpha、islower、isupper、isalnum、isblank、isspace函数cctype / ctype.h头文件

isalpha、islower、isupper、isalnum、isblank、isspace这些函数都在<cctype>&#xff08;即C语言中的<ctype.h>&#xff09;的头文件里面&#xff0c;下图是它们所表示的范围&#xff1a; 总的来说就是&#xff1a; isalpha &#xff08;字母&#xff0c;包括大写…

细微之处见真章之StringUtils的isBlank函数细节解读

一、背景 技术群里有一个老铁分享了一段 commons-lang 的 StringUtils 工具类的代码&#xff1a; public static boolean isBlank(final CharSequence cs) {int strLen;if (cs null || (strLen cs.length()) 0) {return true;}for (int i 0; i < strLen; i) {if (Char…

字符串判空,isBlank 和 isEmpty 到底选那个?

字符串的判空&#xff0c;日常开发是经常要做的一种校验&#xff0c;common-lang包帮我们做了一些字符串判空的封装 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId> </dependency> 并对外提…

sbrk() 函数是干什么的?

brk和sbrk主要的工作是实现虚拟内存到内存的映射. 在GNU C中,内存分配是这样的: 每个进程可访问的虚拟内存空间为3G&#xff0c;但在程序编译时&#xff0c;不可能也没必要为程序分配这么大的空间&#xff0c;只分配并不大的数据段空间&#xff0c;程序中动态分配的空间就是从这…

ORACLE如何修改默认端口号

oracle在安装的的时候&#xff0c;除了可以默认端口号&#xff0c;也可以填入自定义的端口号。但是项目上会出现这样的情况&#xff0c;项目在进展时期&#xff0c;需要对数据库安全升级&#xff0c;首先要修改数据库的默认端口号。那如何来设置oracle的默认端口号&#xff0c;…

Oracle如何更改端口号

Oracle默认端口号为8080&#xff0c;因为Tomcat端口默认也是8080所以需要把Oracle端口更改一下&#xff0c;不建议更改Tomcat端口号 运行cmd命令行操作 查看Oracle版本&#xff1a; 链接Oracle数据库&#xff1a; conn system/root as sysdba&#xff0c;system/root用户名和…

Oracle 19c中默认端口

Oracle官网https://docs.oracle.com/en/database/oracle/oracle-database/19/rilin/port-numbers-and-protocols-of-oracle-components.html#GUID-D168F70C-BECE-4F9A-B616-D9103A35F1FFhttps://www.cndba.cn/hbhe0316/article/87226https://www.cndba.cn/hbhe0316/article/872…

oracle 数据库改端口

Oracle 11g修改默认端口1521为其他值 1、修改listener.ora 打开文件D:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora&#xff0c;修改PORT 后的数值&#xff0c;如下图 修改listener.ora文件 2、重启TNSListener服务 在Windows服务中重启OracleOr…

如何查看oracle的服务端口号

查看 oracle服务端口的步骤&#xff1a; 按住WinR键&#xff0c;弹出DOS命令窗口。 输入cmd命令&#xff0c;点击确定。 弹出的DOS窗口中&#xff0c;i输入 lsnrctl status 命令&#xff0c;并点击Enter键。 找到窗口中&#xff0c;以下文字‘监听端点概要 (DESCRIPTION…

JUC是什么?

JUC表示什么 JUC是java.util.concurrent包的缩写&#xff0c;其包结构如下。 JUC框架结构 JUC是包的简称&#xff0c;JUC可能也是Java核心里最难的一块儿&#xff0c;JUC指的是Java的并发工具包&#xff0c;里边提供了各种各样的控制同步和线程通信的工具类。学习JUC之前&a…

JUC总结系列篇 (二) : 对线程的理解和使用总结

文章内容&#xff1a; 一.为什么需要多线程 二.线程的创建 三.线程的方法sleep(),run(),wait(),yeid(),join(),interrupt()等方法归纳总结 四.线程的状态及其转换 五.线程的交替执行案例 六.多个线程依次执行案例 七.多线程并发带来的线程安全问题 一.为什么需要多线程&#x…

JUC源码系列-ReentrantReadWriteLock

继承关系 ReadLock和WriteLock是ReentrantReadWriteLock的两个内部类&#xff0c;Lock的上锁和释放锁都是通过AQS来实现的。 AQS定义了独占模式的acquire()和release()方法&#xff0c;共享模式的acquireShared()和releaseShared()方法。 还定义了抽象方法tryAcquire()、tryA…