规范解读
GB/T28181-2016规范里面,9.10.1章节,关于校时基本要求:
联网内设备支持基于SIP方式或 NTP方式的网络校时功能,标准时间为北京时间。
SIP方式校时见本节具体描述;NTP(见IETFRFC2030)协议的网络统一校时服务,网络校时设备分为时钟源和客户端,支持客户/服务器的工作模式,时钟源应支持 TCP/IP、UDP及 NTP协议,将输入的或是自身产生的时间信号以标准的 NTP信息包格式输出。
系统运行时可根据配置使用具体校时方式。SIP校时在注册过程中完成。
具体流程如下:
在注册成功情况下,注册流程的最后一个 SIP应答消息200 OK中的 Date头-域中携带时间信息。
采用的格式为 XML标准格式:Date:yyyy-MM-dd'T'HH:mm:ss.SSS。
若SIP代理通过注册方式校时,其注册过期时间宜设置为小于SIP代理与 SIP服务器出现1s误差所经过的运行时间。
例如:SIP代理与SIP服务器校时后,SIP代理运行10h后设备时间与SIP服务器时间相差大于1s,则宜将注册过期时间设置为10h(36000s),以保证SIP代理与SIP服务器之间时 间误差小于1s。
技术实现
以大牛直播SDK的Android平台GB28181设备接入模块为例:
点击页面“启动GB28181”按钮,启动GB28181服务,完成注册和catalog交互:
classButtonGB28181AgentListenerimplementsView.OnClickListener { publicvoidonClick(Viewv) { record_executor_.cancel_tasks(); stopRecordDownloads(true); stopAudioPlayer(); destoryRTPReceiver(); gb_broadcast_source_id_=null; gb_broadcast_target_id_=null; btnGB28181AudioBroadcast.setText("GB28181语音广播"); btnGB28181AudioBroadcast.setEnabled(false); stopGB28181Stream(); destoryRTPSender(); if (null==gb28181_agent_ ) { if( !initGB28181Agent() ) return; } if (gb28181_agent_.isRunning()) { gb28181_agent_.terminateAllAudioBroadcasts(true); gb28181_agent_.terminateAllPlays(true);// 目前测试下来,发送BYE之后,有些服务器会立即发送INVITE,是否发送BYE根据实际情况看gb28181_agent_.stop(); btnGB28181Agent.setText("启动GB28181"); } else { record_executor_.cancel_tasks(); initRecordDownloads(null); if ( gb28181_agent_.start() ) { btnGB28181Agent.setText("停止GB28181"); } } } }
其中,initGb28181Agent()实现如下:
/** MainActivity.java* initGB28181Agent* Author: daniusdk.com*/privatebooleaninitGB28181Agent() { if ( gb28181_agent_!=null ) returntrue; getLocation(context_); Stringlocal_ip_addr=IPAddrUtils.getIpAddress(context_); Log.i(TAG, "initGB28181Agent local ip addr: "+local_ip_addr); if ( local_ip_addr==null||local_ip_addr.isEmpty() ) { Log.e(TAG, "initGB28181Agent local ip is empty"); returnfalse; } gb28181_agent_=GBSIPAgentFactory.getInstance().create(); if ( gb28181_agent_==null ) { Log.e(TAG, "initGB28181Agent create agent failed"); returnfalse; } gb28181_agent_.addListener(this); gb28181_agent_.addPlayListener(this); gb28181_agent_.addAudioBroadcastListener(this); gb28181_agent_.addDeviceControlListener(this); gb28181_agent_.addQueryCommandListener(this); gb28181_agent_.addQueryRecordInfoListener(this); // 必填信息gb28181_agent_.setLocalAddress(local_ip_addr); gb28181_agent_.setServerParameter(gb28181_sip_server_addr_, gb28181_sip_server_port_, gb28181_sip_server_id_, gb28181_sip_domain_); gb28181_agent_.setUserInfo(gb28181_sip_username_, gb28181_sip_password_); //gb28181_agent_.setUserInfo(gb28181_sip_username_, gb28181_sip_username_, gb28181_sip_password_);// 可选参数gb28181_agent_.setUserAgent(gb28181_sip_user_agent_filed_); gb28181_agent_.setTransportProtocol(gb28181_sip_trans_protocol_==0?"UDP":"TCP"); // GB28181配置gb28181_agent_.config(gb28181_reg_expired_, gb28181_heartbeat_interval_, gb28181_heartbeat_count_); com.gb.ntsignalling.Devicegb_device=newcom.gb.ntsignalling.Device("34020000001380000001", "安卓测试设备", Build.MANUFACTURER, Build.MODEL, "宇宙","火星1","火星", true); if (mLongitude!=null&&mLatitude!=null) { com.gb.ntsignalling.DevicePositiondevice_pos=newcom.gb.ntsignalling.DevicePosition(); device_pos.setTime(mLocationTime); device_pos.setLongitude(mLongitude); device_pos.setLatitude(mLatitude); gb_device.setPosition(device_pos); gb_device.setSupportMobilePosition(true); // 设置支持移动位置上报 } gb28181_agent_.addDevice(gb_device); if (!gb28181_agent_.createSipStack()) { gb28181_agent_=null; Log.e(TAG, "initGB28181Agent gb28181_agent_.createSipStack failed."); returnfalse; } booleanis_bind_local_port_ok=false; // 最多尝试5000个端口inttry_end_port=gb28181_sip_local_port_base_+5000; try_end_port=try_end_port>65536?65536: try_end_port; for (inti=gb28181_sip_local_port_base_; i<try_end_port; ++i) { if (gb28181_agent_.bindLocalPort(i)) { is_bind_local_port_ok=true; break; } } if (!is_bind_local_port_ok) { gb28181_agent_.releaseSipStack(); gb28181_agent_=null; Log.e(TAG, "initGB28181Agent gb28181_agent_.bindLocalPort failed."); returnfalse; } if (!gb28181_agent_.initialize()) { gb28181_agent_.unBindLocalPort(); gb28181_agent_.releaseSipStack(); gb28181_agent_=null; Log.e(TAG, "initGB28181Agent gb28181_agent_.initialize failed."); returnfalse; } returntrue; }
注册成功的话,返回校时信息:
publicvoidntsRegisterOK(StringdateString) { Log.i(TAG, "ntsRegisterOK Date: "+ (dateString!=null?dateString : "")); } publicvoidntsRegisterTimeout() { Log.e(TAG, "ntsRegisterTimeout"); } publicvoidntsRegisterTransportError(StringerrorInfo) { Log.e(TAG, "ntsRegisterTransportError error:"+ (errorInfo!=null?errorInfo :"")); }
logcat示例日志如下:
2023-10-07 11:53:33.163 12889-13101/com.daniulive.smartpublisher I/NTGB28181: ntsRegisterOK Date: 2023-10-07T11:53:32.439
Android评估GB28181设备接入侧可以根据返回的时间,做响应的校时处理。以上就是GB28181国标设备接入端校时协议规范和相关实现。