上饶市公安局wvp平台
zhongrj
2023-06-27 2e98b20bea4463e4465e3c19059d0744a09aec06
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
New file
@@ -0,0 +1,265 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import gov.nist.javax.sip.SipProviderImpl;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.sip.*;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @description:处理接收IPCamera发来的SIP协议请求消息
 * @author: songww
 * @date:   2020年5月3日 下午4:42:22
 */
public abstract class SIPRequestProcessorParent {
   private final static Logger logger = LoggerFactory.getLogger(SIPRequestProcessorParent.class);
   @Autowired
   private SIPSender sipSender;
   public AddressFactory getAddressFactory() {
      try {
         return SipFactory.getInstance().createAddressFactory();
      } catch (PeerUnavailableException e) {
         e.printStackTrace();
      }
      return null;
   }
   public HeaderFactory getHeaderFactory() {
      try {
         return SipFactory.getInstance().createHeaderFactory();
      } catch (PeerUnavailableException e) {
         e.printStackTrace();
      }
      return null;
   }
   public MessageFactory getMessageFactory() {
      try {
         return SipFactory.getInstance().createMessageFactory();
      } catch (PeerUnavailableException e) {
         e.printStackTrace();
      }
      return null;
   }
   class ResponseAckExtraParam{
      String content;
      ContentTypeHeader contentTypeHeader;
      SipURI sipURI;
      int expires = -1;
   }
   /***
    * 回复状态码
    * 100 trying
    * 200 OK
    * 400
    * 404
    */
   public SIPResponse responseAck(SIPRequest sipRequest, int statusCode) throws SipException, InvalidArgumentException, ParseException {
      return responseAck(sipRequest, statusCode, null);
   }
   public SIPResponse responseAck(SIPRequest sipRequest, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
      return responseAck(sipRequest, statusCode, msg, null);
   }
//   public SIPResponse responseAck(ServerTransaction serverTransaction, int statusCode, String msg, ResponseAckExtraParam responseAckExtraParam) throws SipException, InvalidArgumentException, ParseException {
//      if (serverTransaction == null) {
//         logger.warn("[回复消息] ServerTransaction 为null");
//         return null;
//      }
//      ToHeader toHeader = (ToHeader) serverTransaction.getRequest().getHeader(ToHeader.NAME);
//      if (toHeader.getTag() == null) {
//         toHeader.setTag(SipUtils.getNewTag());
//      }
//      SIPResponse response = (SIPResponse)getMessageFactory().createResponse(statusCode, serverTransaction.getRequest());
//      if (msg != null) {
//         response.setReasonPhrase(msg);
//      }
//      if (responseAckExtraParam != null) {
//         if (responseAckExtraParam.sipURI != null && serverTransaction.getRequest().getMethod().equals(Request.INVITE)) {
//            logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort());
//            Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(
//                  SipFactory.getInstance().createAddressFactory().createSipURI(responseAckExtraParam.sipURI.getUser(),  responseAckExtraParam.sipURI.getHost()+":"+responseAckExtraParam.sipURI.getPort()
//                  ));
//            response.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress));
//         }
//         if (responseAckExtraParam.contentTypeHeader != null) {
//            response.setContent(responseAckExtraParam.content, responseAckExtraParam.contentTypeHeader);
//         }
//
//         if (serverTransaction.getRequest().getMethod().equals(Request.SUBSCRIBE)) {
//            if (responseAckExtraParam.expires == -1) {
//               logger.error("[参数不全] 2xx的SUBSCRIBE回复,必须设置Expires header");
//            }else {
//               ExpiresHeader expiresHeader = SipFactory.getInstance().createHeaderFactory().createExpiresHeader(responseAckExtraParam.expires);
//               response.addHeader(expiresHeader);
//            }
//         }
//      }else {
//         if (serverTransaction.getRequest().getMethod().equals(Request.SUBSCRIBE)) {
//            logger.error("[参数不全] 2xx的SUBSCRIBE回复,必须设置Expires header");
//         }
//      }
//      serverTransaction.sendResponse(response);
//      if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(serverTransaction.getRequest().getMethod())) {
//         if (serverTransaction.getDialog() != null) {
//            serverTransaction.getDialog().delete();
//         }
//      }
//      return response;
//   }
   public SIPResponse responseAck(SIPRequest sipRequest, int statusCode, String msg, ResponseAckExtraParam responseAckExtraParam) throws SipException, InvalidArgumentException, ParseException {
      if (sipRequest.getToHeader().getTag() == null) {
         sipRequest.getToHeader().setTag(SipUtils.getNewTag());
      }
      SIPResponse response = (SIPResponse)getMessageFactory().createResponse(statusCode, sipRequest);
      response.setStatusCode(statusCode);
      if (msg != null) {
         response.setReasonPhrase(msg);
      }
      if (responseAckExtraParam != null) {
         if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) {
            logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort());
            Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(
                  SipFactory.getInstance().createAddressFactory().createSipURI(responseAckExtraParam.sipURI.getUser(),  responseAckExtraParam.sipURI.getHost()+":"+responseAckExtraParam.sipURI.getPort()
                  ));
            response.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress));
         }
         if (responseAckExtraParam.contentTypeHeader != null) {
            response.setContent(responseAckExtraParam.content, responseAckExtraParam.contentTypeHeader);
         }
         if (sipRequest.getMethod().equals(Request.SUBSCRIBE)) {
            if (responseAckExtraParam.expires == -1) {
               logger.error("[参数不全] 2xx的SUBSCRIBE回复,必须设置Expires header");
            }else {
               ExpiresHeader expiresHeader = SipFactory.getInstance().createHeaderFactory().createExpiresHeader(responseAckExtraParam.expires);
               response.addHeader(expiresHeader);
            }
         }
      }else {
         if (sipRequest.getMethod().equals(Request.SUBSCRIBE)) {
            logger.error("[参数不全] 2xx的SUBSCRIBE回复,必须设置Expires header");
         }
      }
      // 发送response
      sipSender.transmitRequest(response);
      return response;
   }
   /**
    * 回复带sdp的200
    */
   public SIPResponse responseSdpAck(SIPRequest request, String sdp, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
      ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
      // 兼容国标中的使用编码@域名作为RequestURI的情况
      SipURI sipURI = (SipURI)request.getRequestURI();
      if (sipURI.getPort() == -1) {
         sipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getServerGBId(),  platform.getServerIP()+":"+platform.getServerPort());
      }
      ResponseAckExtraParam responseAckExtraParam = new ResponseAckExtraParam();
      responseAckExtraParam.contentTypeHeader = contentTypeHeader;
      responseAckExtraParam.content = sdp;
      responseAckExtraParam.sipURI = sipURI;
      return responseAck(request, Response.OK, null, responseAckExtraParam);
   }
   /**
    * 回复带xml的200
    */
   public SIPResponse responseXmlAck(SIPRequest request, String xml, ParentPlatform platform, Integer expires) throws SipException, InvalidArgumentException, ParseException {
      ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
      SipURI sipURI = (SipURI)request.getRequestURI();
      if (sipURI.getPort() == -1) {
         sipURI = SipFactory.getInstance().createAddressFactory().createSipURI(platform.getServerGBId(),  platform.getServerIP()+":"+platform.getServerPort());
      }
      ResponseAckExtraParam responseAckExtraParam = new ResponseAckExtraParam();
      responseAckExtraParam.contentTypeHeader = contentTypeHeader;
      responseAckExtraParam.content = xml;
      responseAckExtraParam.sipURI = sipURI;
      responseAckExtraParam.expires = expires;
      return responseAck(request, Response.OK, null, responseAckExtraParam);
   }
   public Element getRootElement(RequestEvent evt) throws DocumentException {
      return getRootElement(evt, "gb2312");
   }
   public Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
      if (charset == null) {
         charset = "gb2312";
      }
      Request request = evt.getRequest();
      SAXReader reader = new SAXReader();
      reader.setEncoding(charset);
      // 对海康出现的未转义字符做处理。
      String[] destStrArray = new String[]{"<",">","&","'","""};
      char despChar = '&'; // 或许可扩展兼容其他字符
      byte destBye = (byte) despChar;
      List<Byte> result = new ArrayList<>();
      byte[] rawContent = request.getRawContent();
      if (rawContent == null) {
         return null;
      }
      for (int i = 0; i < rawContent.length; i++) {
         if (rawContent[i] == destBye) {
            boolean resul = false;
            for (String destStr : destStrArray) {
               if (i + destStr.length() <= rawContent.length) {
                  byte[] bytes = Arrays.copyOfRange(rawContent, i, i + destStr.length());
                  resul = resul || (Arrays.equals(bytes,destStr.getBytes()));
               }
            }
            if (resul) {
               result.add(rawContent[i]);
            }
         }else {
            result.add(rawContent[i]);
         }
      }
      Byte[] bytes = new Byte[0];
      byte[] bytesResult = ArrayUtils.toPrimitive(result.toArray(bytes));
      Document xml = reader.read(new ByteArrayInputStream(bytesResult));
      return xml.getRootElement();
   }
}