소스 검색

Merge branch 'master' of https://github.com/swwheihei/wvp.git

Conflicts:
	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
swwheihei 5 년 전
부모
커밋
29710b7cc1
49개의 변경된 파일461개의 추가작업 그리고 343개의 파일을 삭제
  1. 21 0
      LICENSE
  2. 2 2
      pom.xml
  3. 1 1
      src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
  4. 1 1
      src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
  5. 1 1
      src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java
  6. 262 250
      src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
  7. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
  8. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
  9. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java
  10. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java
  11. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
  12. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java
  13. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java
  14. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java
  15. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java
  16. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java
  17. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java
  18. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
  19. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
  20. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
  21. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java
  22. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
  23. 7 3
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
  24. 61 3
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
  25. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java
  26. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
  27. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
  28. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java
  29. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
  30. 3 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
  31. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
  32. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
  33. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java
  34. 4 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java
  35. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java
  36. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java
  37. 56 38
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
  38. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java
  39. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java
  40. 2 2
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
  41. 1 1
      src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
  42. 1 1
      src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java
  43. 1 1
      src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
  44. 1 1
      src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
  45. 1 1
      src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
  46. 1 1
      src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java
  47. 1 1
      src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
  48. 5 3
      src/main/resources/application.yml
  49. BIN
      wikis/images/核心流程.png

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 swwhaha
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 2 - 2
pom.xml

@@ -39,7 +39,7 @@
 		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-undertow</artifactId>
+			<artifactId>spring-boot-starter-tomcat</artifactId>
 		</dependency>
 		<dependency>
 	        <groupId>org.springframework.boot</groupId>
@@ -127,7 +127,7 @@
 		<dependency>
 			<groupId>org.dom4j</groupId>
 			<artifactId>dom4j</artifactId>
-			<version>2.1.1</version>
+			<version>2.1.3</version>
 		</dependency>
 		<dependency>
 			<groupId>com.google.code.gson</groupId>

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java

@@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.common;
 
 /**    
  * @Description:TODO(这里用一句话描述这个类的作用)   
- * @author: swwheihei
+ * @author: songww
  * @date:   2019年5月30日 下午3:04:04   
  *   
  */

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java

@@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
 
 /**
  * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
- * @author: swwheihei
+ * @author: songww
  * @date: 2019年5月30日 上午10:58:25
  * 
  */

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java

@@ -5,7 +5,7 @@ import org.springframework.context.annotation.Configuration;
 
 /**    
  * @Description:TODO(这里用一句话描述这个类的作用)   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 下午2:46:00     
  */
 @Configuration("vmConfig")

+ 262 - 250
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java

@@ -1,250 +1,262 @@
-package com.genersoft.iot.vmp.gb28181;
-
-import java.util.Properties;
-
-import javax.annotation.PostConstruct;
-import javax.sip.DialogTerminatedEvent;
-import javax.sip.IOExceptionEvent;
-import javax.sip.ListeningPoint;
-import javax.sip.RequestEvent;
-import javax.sip.ResponseEvent;
-import javax.sip.ServerTransaction;
-import javax.sip.SipFactory;
-import javax.sip.SipListener;
-import javax.sip.SipProvider;
-import javax.sip.SipStack;
-import javax.sip.TimeoutEvent;
-import javax.sip.TransactionAlreadyExistsException;
-import javax.sip.TransactionTerminatedEvent;
-import javax.sip.TransactionUnavailableException;
-import javax.sip.address.AddressFactory;
-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 org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
-import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
-
-import gov.nist.javax.sip.SipStackImpl;
-
-@Component
-public class SipLayer implements SipListener, Runnable {
-
-	private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
-
-	@Autowired
-	private SipConfig sipConfig;
-
-	private SipProvider tcpSipProvider;
-
-	private SipProvider udpSipProvider;
-
-	@Autowired
-	private SIPProcessorFactory processorFactory;
-
-	private SipStack sipStack;
-
-	private AddressFactory addressFactory;
-	private HeaderFactory headerFactory;
-	private MessageFactory messageFactory;
-
-	@PostConstruct
-	private void initSipServer() {
-		Thread thread=new Thread(this);
-        thread.setDaemon(true);
-        thread.setName("sip server thread start");
-        thread.start();
-	}
-
-	@Override
-	public void run() {
-		SipFactory sipFactory = SipFactory.getInstance();
-		sipFactory.setPathName("gov.nist");
-		try {
-			headerFactory = sipFactory.createHeaderFactory();
-
-			addressFactory = sipFactory.createAddressFactory();
-			messageFactory = sipFactory.createMessageFactory();
-
-			Properties properties = new Properties();
-			properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
-			properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp());
-			properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
-			/**
-			 * 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 = (SipStackImpl) sipFactory.createSipStack(properties);
-
-			startTcpListener();
-			startUdpListener();
-		} catch (Exception e) {
-			logger.error("Sip Server 启动失败! port {" + sipConfig.getSipPort() + "}");
-			e.printStackTrace();
-		}
-		logger.info("Sip Server 启动成功 port {" + sipConfig.getSipPort() + "}");
-	}
-
-	private void startTcpListener() throws Exception {
-		ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "TCP");
-		tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
-		tcpSipProvider.addSipListener(this);
-	}
-
-	private void startUdpListener() throws Exception {
-		ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP");
-		udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
-		udpSipProvider.addSipListener(this);
-	}
-
-	/**
-	 * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
-	 * new request arrives.
-	 */
-	@Override
-	public void processRequest(RequestEvent evt) {
-		ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt);
-		processor.process(evt, this);
-	}
-
-	@Override
-	public void processResponse(ResponseEvent evt) {
-		Response response = evt.getResponse();
-		int status = response.getStatusCode();
-		if ((status >= 200) && (status < 300)) { // Success!
-			ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
-			processor.process(evt, this, sipConfig);
-		} else {
-			logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getContent().toString());
-		}
-		// trying不会回复
-		if (status == Response.TRYING) {
-
-		}
-	}
-
-	/**
-	 * <p>
-	 * Title: processTimeout
-	 * </p>
-	 * <p>
-	 * Description:
-	 * </p>
-	 * 
-	 * @param timeoutEvent
-	 */
-	@Override
-	public void processTimeout(TimeoutEvent timeoutEvent) {
-		// TODO Auto-generated method stub
-
-	}
-
-	/**
-	 * <p>
-	 * Title: processIOException
-	 * </p>
-	 * <p>
-	 * Description:
-	 * </p>
-	 * 
-	 * @param exceptionEvent
-	 */
-	@Override
-	public void processIOException(IOExceptionEvent exceptionEvent) {
-		// TODO Auto-generated method stub
-
-	}
-
-	/**
-	 * <p>
-	 * Title: processTransactionTerminated
-	 * </p>
-	 * <p>
-	 * Description:
-	 * </p>
-	 * 
-	 * @param transactionTerminatedEvent
-	 */
-	@Override
-	public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
-		// TODO Auto-generated method stub
-
-	}
-
-	/**
-	 * <p>
-	 * Title: processDialogTerminated
-	 * </p>
-	 * <p>
-	 * Description:
-	 * </p>
-	 * 
-	 * @param dialogTerminatedEvent
-	 */
-	@Override
-	public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
-		// TODO Auto-generated method stub
-
-	}
-
-	public ServerTransaction getServerTransaction(RequestEvent evt) {
-		Request request = evt.getRequest();
-		ServerTransaction serverTransaction = evt.getServerTransaction();
-		// 判断TCP还是UDP
-		boolean isTcp = false;
-		ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
-		String transport = reqViaHeader.getTransport();
-		if (transport.equals("TCP")) {
-			isTcp = true;
-		}
-
-		if (serverTransaction == null) {
-			try {
-				if (isTcp) {
-					serverTransaction = tcpSipProvider.getNewServerTransaction(request);
-				} else {
-					serverTransaction = udpSipProvider.getNewServerTransaction(request);
-				}
-			} catch (TransactionAlreadyExistsException e) {
-				e.printStackTrace();
-			} catch (TransactionUnavailableException e) {
-				e.printStackTrace();
-			}
-		}
-		return serverTransaction;
-	}
-
-	public AddressFactory getAddressFactory() {
-		return addressFactory;
-	}
-
-	public HeaderFactory getHeaderFactory() {
-		return headerFactory;
-	}
-
-	public MessageFactory getMessageFactory() {
-		return messageFactory;
-	}
-
-	public SipProvider getTcpSipProvider() {
-		return tcpSipProvider;
-	}
-
-	public SipProvider getUdpSipProvider() {
-		return udpSipProvider;
-	}
-
-}
+package com.genersoft.iot.vmp.gb28181;
+
+import java.text.ParseException;
+import java.util.Properties;
+
+import javax.annotation.PostConstruct;
+import javax.sip.DialogTerminatedEvent;
+import javax.sip.IOExceptionEvent;
+import javax.sip.ListeningPoint;
+import javax.sip.RequestEvent;
+import javax.sip.ResponseEvent;
+import javax.sip.ServerTransaction;
+import javax.sip.SipFactory;
+import javax.sip.SipListener;
+import javax.sip.SipProvider;
+import javax.sip.SipStack;
+import javax.sip.TimeoutEvent;
+import javax.sip.TransactionAlreadyExistsException;
+import javax.sip.TransactionTerminatedEvent;
+import javax.sip.TransactionUnavailableException;
+import javax.sip.address.AddressFactory;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.genersoft.iot.vmp.conf.SipConfig;
+import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
+import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
+import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
+
+import gov.nist.javax.sip.SipStackImpl;
+
+@Component
+public class SipLayer implements SipListener, Runnable {
+
+	private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
+
+	@Autowired
+	private SipConfig sipConfig;
+
+	private SipProvider tcpSipProvider;
+
+	private SipProvider udpSipProvider;
+
+	@Autowired
+	private SIPProcessorFactory processorFactory;
+
+	private SipStack sipStack;
+
+	private AddressFactory addressFactory;
+	private HeaderFactory headerFactory;
+	private MessageFactory messageFactory;
+
+	@PostConstruct
+	private void initSipServer() {
+		Thread thread = new Thread(this);
+		thread.setDaemon(true);
+		thread.setName("sip server thread start");
+		thread.start();
+	}
+
+	@Override
+	public void run() {
+		SipFactory sipFactory = SipFactory.getInstance();
+		sipFactory.setPathName("gov.nist");
+		try {
+			headerFactory = sipFactory.createHeaderFactory();
+
+			addressFactory = sipFactory.createAddressFactory();
+			messageFactory = sipFactory.createMessageFactory();
+
+			Properties properties = new Properties();
+			properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
+			properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp());
+			properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
+			/**
+			 * 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", "32");
+			properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
+			properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");
+			sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
+
+			startTcpListener();
+			startUdpListener();
+		} catch (Exception e) {
+			logger.error("Sip Server 启动失败! port {" + sipConfig.getSipPort() + "}");
+			e.printStackTrace();
+		}
+		logger.info("Sip Server 启动成功 port {" + sipConfig.getSipPort() + "}");
+	}
+
+	private void startTcpListener() throws Exception {
+		ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(),
+				"TCP");
+		tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
+		tcpSipProvider.addSipListener(this);
+	}
+
+	private void startUdpListener() throws Exception {
+		ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(),
+				"UDP");
+		udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
+		udpSipProvider.addSipListener(this);
+	}
+
+	/**
+	 * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
+	 * new request arrives.
+	 */
+	@Override
+	public void processRequest(RequestEvent evt) {
+		ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt);
+		processor.process(evt, this);
+	}
+
+	@Override
+	public void processResponse(ResponseEvent evt) {
+		Response response = evt.getResponse();
+		int status = response.getStatusCode();
+		if ((status >= 200) && (status < 300)) { // Success!
+			ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
+			try {
+				processor.process(evt, this, sipConfig);
+			} catch (ParseException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		// } else if (status == Response.TRYING) {
+			// trying不会回复
+		} else if ((status >= 100) && (status < 200)) {
+			// 增加其它无需回复的响应,如101、180等
+		} else {
+			logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
+		}
+		// trying不会回复
+		// if (status == Response.TRYING) {
+
+		// }
+	}
+
+	/**
+	 * <p>
+	 * Title: processTimeout
+	 * </p>
+	 * <p>
+	 * Description:
+	 * </p>
+	 * 
+	 * @param timeoutEvent
+	 */
+	@Override
+	public void processTimeout(TimeoutEvent timeoutEvent) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * <p>
+	 * Title: processIOException
+	 * </p>
+	 * <p>
+	 * Description:
+	 * </p>
+	 * 
+	 * @param exceptionEvent
+	 */
+	@Override
+	public void processIOException(IOExceptionEvent exceptionEvent) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * <p>
+	 * Title: processTransactionTerminated
+	 * </p>
+	 * <p>
+	 * Description:
+	 * </p>
+	 * 
+	 * @param transactionTerminatedEvent
+	 */
+	@Override
+	public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * <p>
+	 * Title: processDialogTerminated
+	 * </p>
+	 * <p>
+	 * Description:
+	 * </p>
+	 * 
+	 * @param dialogTerminatedEvent
+	 */
+	@Override
+	public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
+		// TODO Auto-generated method stub
+
+	}
+
+	public ServerTransaction getServerTransaction(RequestEvent evt) {
+		Request request = evt.getRequest();
+		ServerTransaction serverTransaction = evt.getServerTransaction();
+		// 判断TCP还是UDP
+		boolean isTcp = false;
+		ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
+		String transport = reqViaHeader.getTransport();
+		if (transport.equals("TCP")) {
+			isTcp = true;
+		}
+
+		if (serverTransaction == null) {
+			try {
+				if (isTcp) {
+					serverTransaction = tcpSipProvider.getNewServerTransaction(request);
+				} else {
+					serverTransaction = udpSipProvider.getNewServerTransaction(request);
+				}
+			} catch (TransactionAlreadyExistsException e) {
+				e.printStackTrace();
+			} catch (TransactionUnavailableException e) {
+				e.printStackTrace();
+			}
+		}
+		return serverTransaction;
+	}
+
+	public AddressFactory getAddressFactory() {
+		return addressFactory;
+	}
+
+	public HeaderFactory getHeaderFactory() {
+		return headerFactory;
+	}
+
+	public MessageFactory getMessageFactory() {
+		return messageFactory;
+	}
+
+	public SipProvider getTcpSipProvider() {
+		return tcpSipProvider;
+	}
+
+	public SipProvider getUdpSipProvider() {
+		return udpSipProvider;
+	}
+
+}

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java

@@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 
 /**    
  * @Description:注册逻辑处理,当设备注册后触发逻辑。
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月8日 下午9:41:46     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java

@@ -4,7 +4,7 @@ import java.util.List;
 
 /**    
  * @Description:设备录像信息bean 
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月8日 下午2:05:56     
  */
 public class RecordInfo {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java

@@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.bean;
 
 /**    
  * @Description:设备录像bean 
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月8日 下午2:06:54     
  */
 public class RecordItem {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java

@@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
 
 /**    
  * @Description:设备离在线状态检测器,用于检测设备状态
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月13日 下午2:40:29     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java

@@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
 
 /**    
  * @Description:Event事件通知推送器,支持推送在线事件、离线事件
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 上午11:30:50     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java

@@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
 
 /**    
  * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 上午11:35:46     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java

@@ -4,7 +4,7 @@ import org.springframework.context.ApplicationEvent;
 
 /**    
  * @Description:TODO(这里用一句话描述这个类的作用)   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 上午11:33:13     
  */
 public class OfflineEvent extends ApplicationEvent {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java

@@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
  * @Description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
  *               1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
  *               2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
- * @author: swwheihei
+ * @author: songww
  * @date: 2020年5月6日 下午1:51:23
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java

@@ -4,7 +4,7 @@ import org.springframework.context.ApplicationEvent;
 
 /**    
  * @Description:TODO(这里用一句话描述这个类的作用)   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 上午11:32:56     
  */
 public class OnlineEvent extends ApplicationEvent {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java

@@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
  * @Description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
  *               1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
  *               2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor}
- * @author: swwheihei
+ * @author: songww
  * @date: 2020年5月6日 下午1:51:23
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java

@@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.utils.SpringBeanFactory;
 
 /**
  * @Description:SIP信令中的SSRC工具类。SSRC值由10位十进制整数组成的字符串,第一位为0代表实况,为1则代表回放;第二位至第六位由监控域ID的第4位到第8位组成;最后4位为不重复的4个整数
- * @author: swwheihei
+ * @author: songww
  * @date: 2020年5月10日 上午11:57:57
  */
 public class SsrcUtil {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java

@@ -8,7 +8,7 @@ import org.springframework.stereotype.Component;
 
 /**    
  * @Description:视频流session管理器,管理视频预览、预览回放的通信句柄 
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月13日 下午4:03:02     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java

@@ -26,7 +26,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcess
 
 /**    
  * @Description:TODO(这里用一句话描述这个类的作用)   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午4:24:37     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java

@@ -10,7 +10,7 @@ import org.springframework.web.context.request.async.DeferredResult;
 
 /**    
  * @Description:TODO(这里用一句话描述这个类的作用)   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月8日 下午7:59:05     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java

@@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.callback;
 
 /**    
  * @Description:TODO(这里用一句话描述这个类的作用)   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月8日 下午1:09:18     
  */
 public class RequestMessage {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java

@@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
 
 /**    
  * @Description:设备能力接口,用于定义设备的控制、查询能力   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午9:16:34     
  */
 public interface ISIPCommander {

+ 7 - 3
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java

@@ -25,7 +25,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Host;
 
 /**
  * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化
- * @author: swwheihei
+ * @author: songww
  * @date: 2020年5月6日 上午9:29:02
  */
 @Component
@@ -79,7 +79,8 @@ public class SIPRequestHeaderProvider {
 		SipURI requestLine = layer.getAddressFactory().createSipURI(channelId, host.getAddress());
 		//via
 		ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
-		ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
+		// ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
+		ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag);
 		viaHeader.setRPort();
 		viaHeaders.add(viaHeader);
 		//from
@@ -108,6 +109,7 @@ public class SIPRequestHeaderProvider {
 		request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
 		
 		Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort()));
+		// Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort()));
 		request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress));
 		
 		ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP");
@@ -122,7 +124,8 @@ public class SIPRequestHeaderProvider {
 		SipURI requestLine = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress());
 		//via
 		ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
-		ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
+		// ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
+		ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag);
 		viaHeader.setRPort();
 		viaHeaders.add(viaHeader);
 		//from
@@ -151,6 +154,7 @@ public class SIPRequestHeaderProvider {
 		request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
 		
 		Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort()));
+		// Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort()));
 		request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress));
 		
 		ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP");

+ 61 - 3
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java

@@ -7,10 +7,13 @@ import javax.sip.Dialog;
 import javax.sip.InvalidArgumentException;
 import javax.sip.SipException;
 import javax.sip.TransactionDoesNotExistException;
+import javax.sip.address.Address;
+import javax.sip.address.SipURI;
 import javax.sip.header.ViaHeader;
 import javax.sip.message.Request;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.security.SecurityProperties.Headers;
 import org.springframework.stereotype.Component;
 
 import com.genersoft.iot.vmp.conf.SipConfig;
@@ -21,9 +24,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
 import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
 
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
 /**    
  * @Description:设备能力接口,用于定义设备的控制、查询能力   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午9:22:48     
  */
 @Component
@@ -94,6 +100,49 @@ public class SIPCommander implements ISIPCommander {
 		return ptzCmd(device, channelId, 0, 0, inOut, 0, zoomSpeed);
 	}
   
+   /**
+	* 云台指令码计算 
+	*
+    * @param leftRight  镜头左移右移 0:停止 1:左移 2:右移
+    * @param upDown     镜头上移下移 0:停止 1:上移 2:下移
+    * @param inOut      镜头放大缩小 0:停止 1:缩小 2:放大
+    * @param moveSpeed  镜头移动速度 默认 0XFF (0-255)
+    * @param zoomSpeed  镜头缩放速度 默认 0X1 (0-255)
+    */
+    public static String cmdString(int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) {
+		int cmdCode = 0;
+		if (leftRight == 2) {
+			cmdCode|=0x01;		// 右移
+		} else if(leftRight == 1) {
+			cmdCode|=0x02;		// 左移
+		}
+		if (upDown == 2) {
+			cmdCode|=0x04;		// 下移
+		} else if(upDown == 1) {
+			cmdCode|=0x08;		// 上移
+		}
+		if (inOut == 2) {
+			cmdCode |= 0x10;	// 放大
+		} else if(inOut == 1) {
+			cmdCode |= 0x20;	// 缩小
+		}
+		StringBuilder builder = new StringBuilder("A50F01");
+		String strTmp;
+		strTmp = String.format("%02X", cmdCode);
+		builder.append(strTmp, 0, 2);
+		strTmp = String.format("%02X", moveSpeed);
+		builder.append(strTmp, 0, 2);
+		builder.append(strTmp, 0, 2);
+		strTmp = String.format("%X", zoomSpeed);
+		builder.append(strTmp, 0, 1).append("0");
+		//计算校验码
+		int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + moveSpeed + moveSpeed + (zoomSpeed /*<< 4*/ & 0XF0)) % 0X100;
+		strTmp = String.format("%02X", checkCode);
+		builder.append(strTmp, 0, 2);
+		return builder.toString();
+}
+
+
 	/**
 	 * 云台控制,支持方向与缩放控制
 	 * 
@@ -109,13 +158,14 @@ public class SIPCommander implements ISIPCommander {
 	public boolean ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed,
 			int zoomSpeed) {
 		try {
+			String cmdStr= cmdString(leftRight, upDown, inOut, moveSpeed, zoomSpeed);
 			StringBuffer ptzXml = new StringBuffer(200);
 			ptzXml.append("<?xml version=\"1.0\" ?>");
 			ptzXml.append("<Control>");
 			ptzXml.append("<CmdType>DeviceControl</CmdType>");
 			ptzXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>");
 			ptzXml.append("<DeviceID>" + channelId + "</DeviceID>");
-			ptzXml.append("<PTZCmd>" + "</PTZCmd>");
+			ptzXml.append("<PTZCmd>" + cmdStr + "</PTZCmd>");
 			ptzXml.append("<Info>");
 			ptzXml.append("</Info>");
 			ptzXml.append("</Control>");
@@ -123,7 +173,6 @@ public class SIPCommander implements ISIPCommander {
 			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag");
 			
 			transmitRequest(device, request);
-			
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
@@ -245,6 +294,13 @@ public class SIPCommander implements ISIPCommander {
 				return;
 			}
 			Request byeRequest = dialog.createRequest(Request.BYE);
+			SipURI byeURI = (SipURI) byeRequest.getRequestURI();
+			String vh = transaction.getRequest().getHeader(ViaHeader.NAME).toString();
+			Pattern p = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)");
+			Matcher matcher = p.matcher(vh);
+			if (matcher.find()) {
+				byeURI.setHost(matcher.group(1));
+			}
 			ViaHeader viaHeader = (ViaHeader) byeRequest.getHeader(ViaHeader.NAME);
 			String protocol = viaHeader.getTransport().toUpperCase();
 			ClientTransaction clientTransaction = null;
@@ -258,6 +314,8 @@ public class SIPCommander implements ISIPCommander {
 			e.printStackTrace();
 		} catch (SipException e) {
 			e.printStackTrace();
+		} catch (ParseException e) {
+			e.printStackTrace();
 		}
 	}
 

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java

@@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
 
 /**    
  * @Description:处理接收IPCamera发来的SIP协议请求消息
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午4:42:22     
  */
 public interface ISIPRequestProcessor {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java

@@ -16,7 +16,7 @@ import gov.nist.javax.sip.header.CSeq;
 
 /**    
  * @Description:ACK请求处理器  
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:31:45     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java

@@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
 
 /**    
  * @Description: BYE请求处理器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:32:05     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java

@@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
 
 /**    
  * @Description:CANCEL请求处理器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:32:23     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java

@@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
 
 /**    
  * @Description:处理INVITE请求
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午4:43:52     
  */
 @Component

+ 3 - 2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java

@@ -43,7 +43,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
 
 /**    
  * @Description:MESSAGE请求处理器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:32:41     
  */
 @Component
@@ -100,6 +100,7 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
 		
 		Request request = evt.getRequest();
 		SAXReader reader = new SAXReader();
+		reader.setEncoding("gbk");
 		Document xml;
 		try {
 			xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
@@ -375,7 +376,7 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
 	private Element getRootElement(RequestEvent evt) throws DocumentException {
 		Request request = evt.getRequest();
 		SAXReader reader = new SAXReader();
-		reader.setEncoding("GB2312");
+		reader.setEncoding("gbk");
 		Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
 		return xml.getRootElement();
 	}

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java

@@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
 
 /**    
  * @Description:暂不支持的消息请求处理器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:32:59     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java

@@ -38,7 +38,7 @@ import gov.nist.javax.sip.header.Expires;
 
 /**    
  * @Description:收到注册请求 处理 
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午4:47:25     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java

@@ -17,7 +17,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
 
 /**    
  * @Description:SUBSCRIBE请求处理器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:31:20     
  */
 @Component

+ 4 - 2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java

@@ -1,5 +1,7 @@
 package com.genersoft.iot.vmp.gb28181.transmit.response;
 
+import java.text.ParseException;
+
 import javax.sip.ResponseEvent;
 
 import com.genersoft.iot.vmp.conf.SipConfig;
@@ -7,11 +9,11 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
 
 /**    
  * @Description:处理接收IPCamera发来的SIP协议响应消息
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午4:42:22     
  */
 public interface ISIPResponseProcessor {
 
-	public void process(ResponseEvent evt, SipLayer layer, SipConfig config);
+	public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException;
 
 }

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java

@@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
 
 /**    
  * @Description: BYE请求响应器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:32:05     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java

@@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
 
 /**    
  * @Description:CANCEL响应处理器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:32:23     
  */
 @Component

+ 56 - 38
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java

@@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
 
 import java.text.ParseException;
 
-import javax.sip.ClientTransaction;
 import javax.sip.Dialog;
 import javax.sip.InvalidArgumentException;
 import javax.sip.ResponseEvent;
@@ -22,57 +21,76 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
 import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
 
-/**    
- * @Description:处理INVITE响应
- * @author: swwheihei
- * @date:   2020年5月3日 下午4:43:52     
+
+/**
+ * @Description:处理INVITE响应
+ * @author: songww
+ * @date: 2020年5月3日 下午4:43:52
  */
 @Component
 public class InviteResponseProcessor implements ISIPResponseProcessor {
 
 	private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
-	
+
 	/**
 	 * 处理invite响应
 	 * 
-	 * @param evt
-	 *            响应消息
-	 */ 
+	 * @param evt 响应消息
+	 * @throws ParseException
+	 */
 	@Override
-	public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
+	public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException {
 		try {
 			Response response = evt.getResponse();
 			int statusCode = response.getStatusCode();
-			//trying不会回复
-			if(statusCode == Response.TRYING){
-
+			// trying不会回复
+			if (statusCode == Response.TRYING) {
 			}
-			//成功响应
-			//下发ack
-			if(statusCode == Response.OK){
-//				ClientTransaction clientTransaction = evt.getClientTransaction();
-//				if(clientTransaction == null){
-//					logger.error("回复ACK时,clientTransaction为null >>> {}",response);
-//					return;
-//				}
-//				Dialog clientDialog = clientTransaction.getDialog();
-//
-//				CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
-//				long cseqId = clientCSeqHeader.getSeqNumber();
-//				/*
-//				createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。
-//				有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流
-//				所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。
-//				 */
-//				Request ackRequest = clientDialog.createAck(cseqId);
-//				SipURI requestURI = (SipURI) ackRequest.getRequestURI();
-//				ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
-//				requestURI.setHost(viaHeader.getHost());
-//				requestURI.setPort(viaHeader.getPort());
-//				clientDialog.sendAck(ackRequest);
-				
+			// 成功响应
+			// 下发ack
+			if (statusCode == Response.OK) {
+				// ClientTransaction clientTransaction = evt.getClientTransaction();
+				// if(clientTransaction == null){
+				// logger.error("回复ACK时,clientTransaction为null >>> {}",response);
+				// return;
+				// }
+				// Dialog clientDialog = clientTransaction.getDialog();
+
+				// CSeqHeader clientCSeqHeader = (CSeqHeader)
+				// response.getHeader(CSeqHeader.NAME);
+				// long cseqId = clientCSeqHeader.getSeqNumber();
+				// /*
+				// createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。
+				// 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流
+				// 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。
+				// */
+				// Request ackRequest = clientDialog.createAck(cseqId);
+				// SipURI requestURI = (SipURI) ackRequest.getRequestURI();
+				// ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
+				// try {
+				// requestURI.setHost(viaHeader.getHost());
+				// } catch (Exception e) {
+				// e.printStackTrace();
+				// }
+				// requestURI.setPort(viaHeader.getPort());
+				// clientDialog.sendAck(ackRequest);
+
 				Dialog dialog = evt.getDialog();
-				Request reqAck =dialog.createAck(1L);
+				CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
+				Request reqAck = dialog.createAck(cseq.getSeqNumber());
+
+				SipURI requestURI = (SipURI) reqAck.getRequestURI();
+				ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
+				// String viaHost =viaHeader.getHost();
+				//getHost()函数取回的IP地址是“[xxx.xxx.xxx.xxx:yyyy]”的格式,需用正则表达式截取为“xxx.xxx.xxx.xxx"格式
+				// Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+");
+				// Matcher matcher = p.matcher(viaHeader.getHost());
+				// if (matcher.find()) {
+				// 	requestURI.setHost(matcher.group());
+				// }
+				requestURI.setHost(viaHeader.getHost());
+				requestURI.setPort(viaHeader.getPort());
+				reqAck.setRequestURI(requestURI);
 				dialog.sendAck(reqAck);
 			}
 		} catch (InvalidArgumentException | SipException e) {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java

@@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
 
 /**    
  * @Description:暂不支持的消息响应处理器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月3日 下午5:32:59     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java

@@ -7,7 +7,7 @@ import java.util.Locale;
 
 /**    
  * @Description:时间工具类,主要处理ISO 8601格式转换
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月8日 下午3:24:42     
  */
 public class DateUtil {

+ 2 - 2
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java

@@ -18,11 +18,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 
 /**    
  * @Description:针对 ZLMediaServer的hook事件监听
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月8日 上午10:46:48     
  */
 @RestController
-@RequestMapping("/hook/zlm")
+@RequestMapping("/index/hook")
 public class ZLMHttpHookListener {
 
 	private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class);

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java

@@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
 
 /**    
  * @Description:视频设备数据存储接口
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 下午2:14:31     
  */
 public interface IVideoManagerStorager {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java

@@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.conf.VManagerConfig;
 
 /**    
  * @Description:视频设备数据存储工厂,根据存储策略,返回对应的存储器
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 下午2:15:16     
  */
 @Component

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java

@@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 
 /**    
  * @Description:视频设备数据存储-jdbc实现  
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 下午2:28:12     
  */
 @Component("jdbcStorager")

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java

@@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
 
 /**    
  * @Description:视频设备数据存储-redis实现  
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 下午2:31:42     
  */
 @Component("redisStorager")

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java

@@ -7,7 +7,7 @@ import org.springframework.stereotype.Component;
 
 /**    
  * @Description:spring bean获取工厂,获取spring中的已初始化的bean
- * @author: swwheihei
+ * @author: songww
  * @date:   2019年6月25日 下午4:51:52   
  * 
  */

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java

@@ -10,7 +10,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
 
 /**    
  * @Description:使用fastjson实现redis的序列化   
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 下午8:40:11     
  */
 public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java

@@ -13,7 +13,7 @@ import org.springframework.util.CollectionUtils;
 
 /**    
  * @Description:Redis工具类
- * @author: swwheihei
+ * @author: songww
  * @date:   2020年5月6日 下午8:27:29     
  */
 @Component

+ 5 - 3
src/main/resources/application.yml

@@ -26,7 +26,8 @@ spring:
 server:
     port: 8080
 sip:
-    ip: 10.200.64.63
+#   ip: 10.200.64.63
+    ip: 192.168.0.102
     port: 5060
     # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
     # 后两位为行业编码,定义参照附录D.3
@@ -34,7 +35,8 @@ sip:
     domain: 3701020049
     id: 37010200492000000001
     # 默认设备认证密码,后续扩展使用设备单独密码
-    password: admin
+    password: admin123
 media:
-    ip: 10.200.64.88
+#   ip: 10.200.64.88
+    ip: 192.168.0.102
     port: 10000

BIN
wikis/images/核心流程.png