GB28181设备接入端如何实现校时?

2022-09-19 23:57:32 浏览数 (4)

​在探讨这个问题之前,我们先看看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。

废话不多说,以我们Android平台GB28181设备接入模块为例,先启动GB28181服务:

代码语言:javascript复制
    class ButtonGB28181AgentListener implements View.OnClickListener {
        public void onClick(View v) {
            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_.terminateAllPlays(true);// 目前测试下来,发送BYE之后,有些服务器会立即发送INVITE,是否发送BYE根据实际情况看
                gb28181_agent_.stop();
                btnGB28181Agent.setText("启动GB28181");
            }
            else {
                if ( gb28181_agent_.start() ) {
                    btnGB28181Agent.setText("停止GB28181");
                }
            }
        }
    }

调用initGb28181Agent()实现如下:

代码语言:javascript复制
    /*
     * MainActivity.java
     * initGB28181Agent
     * Github: https://github.com/daniulive/SmarterStreaming
     */
    private boolean initGB28181Agent() {
        if ( gb28181_agent_ != null )
            return  true;

        getLocation(context_);

        String local_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");
            return  false;
        }

        gb28181_agent_ = GBSIPAgentFactory.getInstance().create();
        if ( gb28181_agent_ == null ) {
            Log.e(TAG, "initGB28181Agent create agent failed");
            return false;
        }

        gb28181_agent_.addListener(this);
        gb28181_agent_.addPlayListener(this);
        gb28181_agent_.addAudioBroadcastListener(this);
        gb28181_agent_.addDeviceControlListener(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_.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.Device gb_device = new com.gb.ntsignalling.Device("34020000001380000001", "安卓测试设备", Build.MANUFACTURER, Build.MODEL,
                    "宇宙","火星1","火星", true);

        if (mLongitude != null && mLatitude != null) {
            com.gb.ntsignalling.DevicePosition device_pos = new com.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);

/*
        com.gb28181.ntsignalling.Device gb_device1 = new com.gb28181.ntsignalling.Device("34020000001380000002", "安卓测试设备2", Build.MANUFACTURER, Build.MODEL,
                "宇宙","火星1","火星", true);

        if (mLongitude != null && mLatitude != null) {
            com.gb28181.ntsignalling.DevicePosition device_pos = new com.gb28181.ntsignalling.DevicePosition();

            device_pos.setTime(mLocationTime);
            device_pos.setLongitude(mLongitude);
            device_pos.setLatitude(mLatitude);
            gb_device1.setPosition(device_pos);

            gb_device1.setSupportMobilePosition(true);
        }

        gb28181_agent_.addDevice(gb_device1);


 */

        if (!gb28181_agent_.createSipStack()) {
            gb28181_agent_ = null;
            Log.e(TAG, "initGB28181Agent gb28181_agent_.createSipStack failed.");
            return  false;
        }

        boolean is_bind_local_port_ok = false;

        // 最多尝试5000个端口
        int try_end_port = gb28181_sip_local_port_base_   5000;
        try_end_port = try_end_port > 65536 ?65536: try_end_port;

        for (int i = 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.");
            return  false;
        }

        if (!gb28181_agent_.initialize()) {
            gb28181_agent_.unBindLocalPort();
            gb28181_agent_.releaseSipStack();
            gb28181_agent_ = null;
            Log.e(TAG, "initGB28181Agent gb28181_agent_.initialize failed.");
            return  false;
        }

        return true;
    }

注册成功后,回调如下:

代码语言:javascript复制
    @Override
    public void ntsRegisterOK(String dateString) {
        Log.i(TAG, "ntsRegisterOK Date: "   (dateString!= null? dateString : ""));
    }

回上来的日志如下:

2022-09-13 11:53:33.163 12889-13101/com.daniulive.smartpublisher I/NTGB28181: ntsRegisterOK Date: 2022-09-13T11:53:32.439

以上就是GB28181国标设备接入端校时协议规范和相关实现流程,感兴趣的开发者可酌情参考。

0 人点赞