648540858
2022-09-09 221f99c764b51c3cd284c6e5a41492c26c5c7ffc
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
@@ -1,9 +1,11 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import gov.nist.javax.sip.SipProviderImpl;
import gov.nist.javax.sip.SipStackImpl;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.stack.SIPServerTransaction;
import org.apache.commons.lang3.ArrayUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
@@ -18,13 +20,19 @@
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.ExpiresHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.ViaHeader;
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协议请求消息
@@ -51,11 +59,14 @@
   public ServerTransaction getServerTransaction(RequestEvent evt) {
      Request request = evt.getRequest();
      ServerTransaction serverTransaction = evt.getServerTransaction();
      if (serverTransaction != null) {
         System.out.println(serverTransaction.getState().toString());
      }
      // 判断TCP还是UDP
      boolean isTcp = false;
      ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
      String transport = reqViaHeader.getTransport();
      if (transport.equals("TCP")) {
      if (transport.equalsIgnoreCase("TCP")) {
         isTcp = true;
      }
@@ -78,6 +89,8 @@
            logger.error(e.getMessage());
         } catch (TransactionUnavailableException e) {
            logger.error(e.getMessage());
         }finally {
         }
      }
      return serverTransaction;
@@ -124,10 +137,16 @@
   public void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException {
      Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
      ServerTransaction serverTransaction = getServerTransaction(evt);
      if (serverTransaction == null) {
         logger.warn("回复失败:{}", response);
         return;
      }
      serverTransaction.sendResponse(response);
      if (statusCode >= 200 && !"NOTIFY".equals(evt.getRequest().getMethod())) {
      if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(evt.getRequest().getMethod())) {
         if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
         if (serverTransaction.getDialog() != null) {
            serverTransaction.getDialog().delete();
         }
      }
   }
@@ -136,8 +155,10 @@
      response.setReasonPhrase(msg);
      ServerTransaction serverTransaction = getServerTransaction(evt);
      serverTransaction.sendResponse(response);
      if (statusCode >= 200 && !"NOTIFY".equals(evt.getRequest().getMethod())) {
         if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
      if (statusCode >= 200 && !"NOTIFY".equalsIgnoreCase(evt.getRequest().getMethod())) {
         if (serverTransaction.getDialog() != null) {
            serverTransaction.getDialog().delete();
         }
      }
   }
@@ -149,30 +170,99 @@
    * @throws InvalidArgumentException
    * @throws ParseException
    */
   public void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException {
   public void responseSdpAck(RequestEvent evt, String sdp, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
      Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
      SipFactory sipFactory = SipFactory.getInstance();
      ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
      response.setContent(sdp, contentTypeHeader);
      // 兼容国标中的使用编码@域名作为RequestURI的情况
      SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
      if (sipURI.getPort() == -1) {
         sipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(),  platform.getServerIP()+":"+platform.getServerPort());
      }
      logger.debug("responseSdpAck SipURI: {}:{}", sipURI.getHost(), sipURI.getPort());
      Address concatAddress = sipFactory.createAddressFactory().createAddress(
            sipFactory.createAddressFactory().createSipURI(sipURI.getUser(),  sipURI.getHost()+":"+sipURI.getPort()
            ));
      response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
      ServerTransaction serverTransaction = getServerTransaction(evt);
      if (serverTransaction == null) {
      }
      getServerTransaction(evt).sendResponse(response);
   }
   /**
    * 回复带xml的200
    * @param evt
    * @param xml
    * @throws SipException
    * @throws InvalidArgumentException
    * @throws ParseException
    */
   public Response responseXmlAck(RequestEvent evt, String xml, ParentPlatform platform) throws SipException, InvalidArgumentException, ParseException {
      Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
      SipFactory sipFactory = SipFactory.getInstance();
      ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
      response.setContent(xml, contentTypeHeader);
      // 兼容国标中的使用编码@域名作为RequestURI的情况
      SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
      if (sipURI.getPort() == -1) {
         sipURI = sipFactory.createAddressFactory().createSipURI(platform.getServerGBId(),  platform.getServerIP()+":"+platform.getServerPort());
      }
      logger.debug("responseXmlAck SipURI: {}:{}", sipURI.getHost(), sipURI.getPort());
      Address concatAddress = sipFactory.createAddressFactory().createAddress(
            sipFactory.createAddressFactory().createSipURI(sipURI.getUser(),  sipURI.getHost()+":"+sipURI.getPort()
            ));
      response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
      response.addHeader(evt.getRequest().getHeader(ExpiresHeader.NAME));
      getServerTransaction(evt).sendResponse(response);
      return response;
   }
   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";
      if (charset == null) {
         charset = "gb2312";
      }
      Request request = evt.getRequest();
      SAXReader reader = new SAXReader();
      reader.setEncoding(charset);
      Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
      // 对海康出现的未转义字符做处理。
      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();
   }