国标GB28181学习路程-part1

 GB/T28181-2011 《安全防范视频监控联网系统信息传输、交换、控制技术要求》是由公安部科技信息化局提出,由全国安全防范报警系统标准化技术委员会(SAC/TC100)归口,公安部一所等多家单位共同起草的一部国家标准。
http://www.gb688.cn/bzgk/gb/newGbInfo?hcno=469659DC56B9B8187671FF08748CEC89
        通过仔细学习《GBT 28181-2016 公共安全视频监控联网系统信息传输、交换、控制技术要求》技术规范文档。整篇主要是基于SIP协议对视频监控系统互联中涉及的消息内容格式进行了规范,由于GB28181是适用于各个领域各种情况下的视频监控系统信令交互,涉及的信令太多,在实际应用中往往只使用其中一部份信令,今天我主要讲几个最常用的信令应用。

设备注册

当有新的监控设备要接入视频监控平台时,首先要在服务端进行注册操作,其中涉及用户注册时身份认证是本信令的难点。

 1、SIP代理终端(视频监控设备)向 SIP服务器发送 Register请求并携带设备信息,表明有新设备要接入监控平台。

2、SIP服务器向SIP代理终端回401,增加响应消息头域 WWW-Authenticate信息,要求终端进行身份验证。

3、SIP代理终端收到401响应后,取出nonce字段,根据服务端身份认证要求对设备信息进行加密处理(一般是MD5),携带认证信息重新发起Register请求。

 4、SIP服务器对请求进行验证,如果检查新注册终端身份合法,向终端发送200成功响应。

@Slf4j
public class SipServerLayer implements SipListener {
    public SipSrymyMessageProcessor getMessageProcessor() {
        return messageProcessor;
    }

    public void setMessageProcessor(SipSrymyMessageProcessor messageProcessor) {
        this.messageProcessor = messageProcessor;
    }

    private SipSrymyMessageProcessor messageProcessor;

    private SipStack sipStack;

    private SipFactory sipFactory;

    private AddressFactory addressFactory;

    private HeaderFactory headerFactory;

    private MessageFactory messageFactory;

    private SipProvider sipProvider;

    private ListeningPoint tcp;

    private ListeningPoint udp;

    /**
     * Here we initialize the SIP stack.
     */
    @SuppressWarnings("deprecation")
    public SipServerLayer(String ip, int port) throws PeerUnavailableException,
            TransportNotSupportedException, InvalidArgumentException, ObjectInUseException, TooManyListenersException {
        sipFactory = SipFactory.getInstance();
        sipFactory.setPathName("gov.nist");
        Properties properties = new Properties();
        properties.setProperty("javax.sip.STACK_NAME", "srymy-GB28181");
        properties.setProperty("javax.sip.IP_ADDRESS", ip);

        /**
         * sip_server_log.log 和 sip_debug_log.log
         * 	public static final int TRACE_NONE = 0;
         public static final int TRACE_MESSAGES = 16;
         public static final int TRACE_EXCEPTION = 17;
         public static final int TRACE_DEBUG = 32;
         */
        properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0");
        properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
        properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");

        sipStack = sipFactory.createSipStack(properties);
        headerFactory = sipFactory.createHeaderFactory();
        addressFactory = sipFactory.createAddressFactory();
        messageFactory = sipFactory.createMessageFactory();

        tcp = sipStack.createListeningPoint(ip,  port, "tcp");
        udp = sipStack.createListeningPoint(ip, port, "udp");
        createListeningPoint(ip,port);
    }

    /**
     * 停止监听
     * @throws ObjectInUseException
     */
    public void deleteListeningPoint() throws ObjectInUseException {
        if (tcp != null) {
            sipStack.deleteListeningPoint(tcp);
            sipStack.deleteListeningPoint(udp);
        }
    }

    /**
     * 创建SIP端口监听,同时监听UDP和TCP
     * @param ip
     * @param port
     * @throws InvalidArgumentException
     * @throws TransportNotSupportedException
     * @throws ObjectInUseException
     * @throws TooManyListenersException
     */
    public void createListeningPoint(String ip, int port) throws InvalidArgumentException, TransportNotSupportedException, ObjectInUseException, TooManyListenersException {
        tcp = sipStack.createListeningPoint(ip,  port, "tcp");
        udp = sipStack.createListeningPoint(ip, port, "udp");
        sipProvider = sipStack.createSipProvider(tcp);
        sipProvider.addSipListener(this);
        sipProvider = sipStack.createSipProvider(udp);
        sipProvider.addSipListener(this);
    }

    /**
     * This method is called by the SIP stack when a response arrives.
     */
    @Override
    public void processResponse(ResponseEvent responseEvent) {
        try {
            messageProcessor.processResponse(responseEvent, addressFactory, messageFactory, headerFactory, sipProvider);
        } catch (InvalidArgumentException e) {
            e.printStackTrace();
        }
    }

    /**
     * SIP服务端接收消息的方法
     * Content 里面是GBK编码
     * This method is called by the SIP stack when a new request arrives.
     */

    @Override
    public void processRequest(RequestEvent requestEvent) {
        messageProcessor.processRequest(requestEvent, addressFactory, messageFactory, headerFactory, sipProvider);
    }


    /**
     * This method is called by the SIP stack when there's no answer to a
     * message. Note that this is treated differently from an error message.
     */
    @Override
    public void processTimeout(TimeoutEvent evt) {
        messageProcessor.processError("Previous message not sent: " + "timeout");
    }

    /**
     * This method is called by the SIP stack when there's an asynchronous
     * message transmission error.
     */
    @Override
    public void processIOException(IOExceptionEvent evt) {
        messageProcessor.processError("Previous message not sent: " + "I/O Exception");
    }

    /**
     * This method is called by the SIP stack when a dialog (session) ends.
     */
    @Override
    public void processDialogTerminated(DialogTerminatedEvent evt) {
        log.info("会话结束:CallId: {}, DialogId: {}",evt.getDialog().getCallId(), evt.getDialog().getDialogId());
    }

    /**
     * This method is called by the SIP stack when a transaction ends.
     */
    @Override
    public void processTransactionTerminated(TransactionTerminatedEvent evt) {
        log.info("Transaction结束,evt: {}",evt);
    }
}

spring boot 框架搭建项目基础配置步骤:

1、pom.xml配置如下

 <!-- SPI协议相关的包 -->
        <dependency>
            <groupId>javax.sip</groupId>
            <artifactId>jain-sip-api</artifactId>
            <version>1.2.1.4</version>
        </dependency>

        <dependency>
            <groupId>javax.sip</groupId>
            <artifactId>jain-sip-ri</artifactId>
            <version>1.2.1.4</version>
        </dependency>

2、application.properties配置如下

server.port=10000
logging.level.org.springframework.boot.autoconfigure=ERROR 

gb28181.deviceId=34020000002000000001
gb28181.ip=172.16.1.65(自己本地地址)
gb28181.port=5060
gb28181.password=12345678

3、编写SIP监听实现类,并集成到springboot项目

package com.srymy.gb28181.part1.config;

import com.srymy.gb28181.part1.sip.SipSrymyMessageProcessor;
import com.srymy.gb28181.part1.sip.SipServerLayer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sip.PeerUnavailableException;

/**
 * 监听实现类
 * @Author 授人以鳗鱼
 * @Date 9/25/2019
 */
@Slf4j
@Configuration
public class SipSrymyConfig {
    @Value("${gb28181.deviceId:34020000002000000001}")
    String deviceId;
    @Value("${gb28181.ip:172.18.99.169}")
    String ip;
    @Value("${gb28181.port:5060}")
    Integer port;

    @Bean
    public SipServerLayer sipLayer(SipSrymyMessageProcessor messageProcessor) {
        try {
            SipServerLayer sipServerLayer = new SipServerLayer(ip, port);
            sipServerLayer.setMessageProcessor(messageProcessor);
            log.info("SIP服务启动完毕, 已经在[{}:{}]端口监听SIP国标消息", ip, port);
            return sipServerLayer;
        } catch (PeerUnavailableException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

4、服务启动后,你可以用设备注册到这边,并抓包看看,你会发现SIP服务已经启动。

5、抓包工具推荐使用:wireshark,过滤信令类型 SIP 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值