Parcourir la source

重构28181信令结构,解决循环依赖导致的无法直接注入

648540858 il y a 4 ans
Parent
commit
f1217682a9
62 fichiers modifiés avec 345 ajouts et 3589 suppressions
  1. 1 1
      src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
  2. 1 1
      src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
  3. 2 0
      src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java
  4. 1 1
      src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java
  5. 17 165
      src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
  6. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
  7. 13 0
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
  8. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/MobilePosition.java
  9. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
  10. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java
  11. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java
  12. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
  13. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java
  14. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java
  15. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java
  16. 5 2
      src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java
  17. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java
  18. 3 4
      src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java
  19. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java
  20. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
  21. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
  22. 0 243
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
  23. 113 0
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
  24. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/CheckForAllRecordsThread.java
  25. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
  26. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java
  27. 8 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
  28. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
  29. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
  30. 45 28
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
  31. 8 0
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/SIPResponseProcessorAbstract.java
  32. 7 0
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/ITimeoutProcessor.java
  33. 36 0
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/impl/TimeoutProcessorImpl.java
  34. 0 12
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java
  35. 0 131
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java
  36. 0 142
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
  37. 0 150
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
  38. 0 28
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java
  39. 0 478
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
  40. 0 1177
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
  41. 0 394
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/NotifyRequestProcessor.java
  42. 0 31
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
  43. 0 201
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
  44. 0 62
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java
  45. 0 19
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java
  46. 0 31
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java
  47. 0 33
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java
  48. 0 75
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
  49. 0 32
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java
  50. 0 100
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
  51. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java
  52. 7 2
      src/main/java/com/genersoft/iot/vmp/utils/SipUtils.java
  53. 25 8
      src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
  54. 1 1
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
  55. 1 1
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
  56. 1 1
      src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
  57. 1 1
      src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
  58. 1 1
      src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
  59. 1 1
      src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java
  60. 1 1
      src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java
  61. 1 1
      src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
  62. 26 10
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java

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

@@ -1,7 +1,7 @@
 package com.genersoft.iot.vmp.common;
 
 /**    
- * @Description: 定义常量   
+ * @description: 定义常量   
  * @author: swwheihei
  * @date:   2019年5月30日 下午3:04:04   
  *   

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

@@ -16,7 +16,7 @@ import redis.clients.jedis.JedisPool;
 import redis.clients.jedis.JedisPoolConfig;
 
 /**
- * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
+ * @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
  * @author: swwheihei
  * @date: 2019年5月30日 上午10:58:25
  * 

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java

@@ -32,5 +32,7 @@ public class SipDeviceRunner implements CommandLineRunner {
         for (String deviceId : onlineForAll) {
             storager.online(deviceId);
         }
+
+        // TODO 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
     }
 }

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

@@ -4,7 +4,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
 
 /**    
- * @Description: 获取数据库配置   
+ * @description: 获取数据库配置   
  * @author: swwheihei
  * @date:   2020年5月6日 下午2:46:00     
  */

+ 17 - 165
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java

@@ -1,19 +1,10 @@
 package com.genersoft.iot.vmp.gb28181;
 
-import java.text.ParseException;
-import java.util.Properties;
-import java.util.TooManyListenersException;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import javax.sip.*;
-import javax.sip.header.CallIdHeader;
-import javax.sip.header.Header;
-import javax.sip.message.Response;
-
+import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
 import gov.nist.javax.sip.SipProviderImpl;
+import gov.nist.javax.sip.SipStackImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,14 +12,15 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.DependsOn;
 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.response.ISIPResponseProcessor;
-
-import gov.nist.javax.sip.SipStackImpl;
+import javax.sip.*;
+import java.util.Properties;
+import java.util.TooManyListenersException;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 @Component
-public class SipLayer implements SipListener {
+public class SipLayer{
 
 	private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
 
@@ -36,7 +28,7 @@ public class SipLayer implements SipListener {
 	private SipConfig sipConfig;
 
 	@Autowired
-	private SIPProcessorFactory processorFactory;
+	private SIPProcessorObserver sipProcessorObserver;
 
 	@Autowired
 	private SipSubscribe sipSubscribe;
@@ -50,19 +42,16 @@ public class SipLayer implements SipListener {
 	 */
 	private ThreadPoolExecutor processThreadPool;
 
-	@Bean("initSipServer")
-	private ThreadPoolExecutor initSipServer() {
-		
+	public SipLayer() {
 		int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
 		LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000);
 		processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
 				0L,TimeUnit.MILLISECONDS,processQueue,
 				new ThreadPoolExecutor.CallerRunsPolicy());
-		return processThreadPool;
 	}
-	
+
+
 	@Bean("sipFactory")
-	@DependsOn("initSipServer")
 	private SipFactory createSipFactory() {
 		sipFactory = SipFactory.getInstance();
 		sipFactory.setPathName("gov.nist");
@@ -70,7 +59,7 @@ public class SipLayer implements SipListener {
 	}
 	
 	@Bean("sipStack")
-	@DependsOn({"initSipServer", "sipFactory"})
+	@DependsOn({"sipFactory"})
 	private SipStack createSipStack() throws PeerUnavailableException {
 		Properties properties = new Properties();
 		properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
@@ -96,7 +85,7 @@ public class SipLayer implements SipListener {
 		try {
 			tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "TCP");
 			tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint);
-			tcpSipProvider.addSipListener(this);
+			tcpSipProvider.addSipListener(sipProcessorObserver);
 			logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "}");
 		} catch (TransportNotSupportedException e) {
 			e.printStackTrace();
@@ -119,8 +108,7 @@ public class SipLayer implements SipListener {
 		try {
 			udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "UDP");
 			udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint);
-			udpSipProvider.addSipListener(this);
-//			udpSipProvider.setAutomaticDialogSupportEnabled(false);
+			udpSipProvider.addSipListener(sipProcessorObserver);
 		} catch (TransportNotSupportedException e) {
 			e.printStackTrace();
 		} catch (InvalidArgumentException e) {
@@ -135,140 +123,4 @@ public class SipLayer implements SipListener {
 		return udpSipProvider;
 	}
 
-	/**
-	 * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
-	 * new request arrives.
-	 */
-	@Override
-	public void processRequest(RequestEvent evt) {
-		logger.debug(evt.getRequest().toString());
-		// 由于jainsip是单线程程序,为提高性能并发处理
-		processThreadPool.execute(() -> {
-			if (processorFactory != null) {
-				processorFactory.createRequestProcessor(evt).process();
-			}
-		});
-	}
-
-	@Override
-	public void processResponse(ResponseEvent evt) {
-		Response response = evt.getResponse();
-		logger.debug(evt.getResponse().toString());
-		int status = response.getStatusCode();
-		if (((status >= 200) && (status < 300)) || status == 401) { // Success!
-			ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
-			try {
-				processor.process(evt, this, sipConfig);
-			} catch (ParseException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-
-			if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) {
-				CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
-				if (callIdHeader != null) {
-					SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId());
-					if (subscribe != null) {
-						SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(evt);
-						subscribe.response(eventResult);
-					}
-				}
-			}
-		} else if ((status >= 100) && (status < 200)) {
-			// 增加其它无需回复的响应,如101、180等
-		} else {
-			logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
-			if (evt.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) {
-				CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
-				if (callIdHeader != null) {
-					SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId());
-					if (subscribe != null) {
-						SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(evt);
-						subscribe.response(eventResult);
-					}
-				}
-			}
-		}
-
-
-
-	}
-
-	/**
-	 * <p>
-	 * Title: processTimeout
-	 * </p>
-	 * <p>
-	 * Description:
-	 * </p>
-	 * 
-	 * @param timeoutEvent
-	 */
-	@Override
-	public void processTimeout(TimeoutEvent timeoutEvent) {
-		// TODO Auto-generated method stub
-		CallIdHeader callIdHeader = timeoutEvent.getClientTransaction().getDialog().getCallId();
-		String callId = callIdHeader.getCallId();
-		SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
-		SipSubscribe.EventResult<TimeoutEvent> timeoutEventEventResult = new SipSubscribe.EventResult<>(timeoutEvent);
-		errorSubscribe.response(timeoutEventEventResult);
-	}
-
-	/**
-	 * <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
-//		CallIdHeader callIdHeader = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId();
-//		String callId = callIdHeader.getCallId();
-//		SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
-//		SipSubscribe.EventResult<TransactionTerminatedEvent> eventResult = new SipSubscribe.EventResult<>(transactionTerminatedEvent);
-//		errorSubscribe.response(eventResult);
-	}
-
-	/**
-	 * <p>
-	 * Title: processDialogTerminated
-	 * </p>
-	 * <p>
-	 * Description:
-	 * </p>
-	 * 
-	 * @param dialogTerminatedEvent
-	 */
-	@Override
-	public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
-		// TODO Auto-generated method stub
-//		CallIdHeader callIdHeader = dialogTerminatedEvent.getDialog().getCallId();
-//		String callId = callIdHeader.getCallId();
-//		SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
-//		SipSubscribe.EventResult<DialogTerminatedEvent> eventResult = new SipSubscribe.EventResult<>(dialogTerminatedEvent);
-//		errorSubscribe.response(eventResult);
-
-	}
-
 }

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

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

+ 13 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java

@@ -109,6 +109,11 @@ public class Device {
 	 */
 	private String charset ;
 
+	/**
+	 * 目录订阅周期,0为不订阅
+	 */
+	private int subscribeCycleForCatalog ;
+
 
 
 	public String getDeviceId() {
@@ -270,4 +275,12 @@ public class Device {
 	public void setCharset(String charset) {
 		this.charset = charset;
 	}
+
+	public int getSubscribeCycleForCatalog() {
+		return subscribeCycleForCatalog;
+	}
+
+	public void setSubscribeCycleForCatalog(int subscribeCycleForCatalog) {
+		this.subscribeCycleForCatalog = subscribeCycleForCatalog;
+	}
 }

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

@@ -1,7 +1,7 @@
 package com.genersoft.iot.vmp.gb28181.bean;
 
 /**
- * @Description: 移动位置bean
+ * @description: 移动位置bean
  * @author: lawrencehj
  * @date: 2021年1月23日
  */

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

@@ -6,7 +6,7 @@ package com.genersoft.iot.vmp.gb28181.bean;
 import java.util.List;
 
 /**    
- * @Description:设备录像信息bean 
+ * @description:设备录像信息bean 
  * @author: swwheihei
  * @date:   2020年5月8日 下午2:05:56     
  */

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

@@ -8,7 +8,7 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 
 /**
- * @Description:设备录像bean 
+ * @description:设备录像bean 
  * @author: swwheihei
  * @date:   2020年5月8日 下午2:06:54     
  */

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

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

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

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

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

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

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

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

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

@@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.gb28181.event.offline;
 import org.springframework.context.ApplicationEvent;
 
 /**    
- * @Description: 离线事件类   
+ * @description: 离线事件类   
  * @author: swwheihei
  * @date:   2020年5月6日 上午11:33:13     
  */

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

@@ -11,8 +11,8 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
 
 /**
- * @Description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
- *               1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
+ * @description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
+ *               1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor}
  *               2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
  * @author: swwheihei
  * @date: 2020年5月6日 下午1:51:23
@@ -54,5 +54,8 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> {
 
 		// 处理离线监听
 		storager.outline(event.getDeviceId());
+
+		// TODO 离线取消订阅
+
 	}
 }

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

@@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
 import org.springframework.context.ApplicationEvent;
 
 /**    
- * @Description: 在线事件类   
+ * @description: 在线事件类   
  * @author: swwheihei
  * @date:   2020年5月6日 上午11:32:56     
  */

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

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

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

@@ -18,7 +18,7 @@ import javax.sip.ResponseEvent;
 import javax.sip.message.Response;
 
 /**
- * @Description: 平台心跳超时事件
+ * @description: 平台心跳超时事件
  * @author: panll
  * @date: 2020年11月5日 10:00
  */

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

@@ -19,7 +19,7 @@ import org.springframework.stereotype.Component;
 import java.util.*;
 
 /**
- * @Description: 平台未注册事件,来源有二:
+ * @description: 平台未注册事件,来源有二:
  *               1、平台新添加
  *               2、平台心跳超时
  * @author: panll

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

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

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

@@ -1,243 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit;
-
-import javax.sip.RequestEvent;
-import javax.sip.ResponseEvent;
-import javax.sip.SipProvider;
-import javax.sip.header.CSeqHeader;
-import javax.sip.message.Request;
-import javax.sip.message.Response;
-
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
-import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
-import com.genersoft.iot.vmp.service.IDeviceAlarmService;
-import com.genersoft.iot.vmp.service.IMediaServerService;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
-import com.genersoft.iot.vmp.service.IPlayService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Component;
-
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;
-import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
-import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
-import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.AckRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.ByeRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.CancelRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.InviteRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.NotifyRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.response.impl.ByeResponseProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.response.impl.CancelResponseProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.response.impl.InviteResponseProcessor;
-import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcessor;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-import com.genersoft.iot.vmp.utils.SpringBeanFactory;
-import com.genersoft.iot.vmp.utils.redis.RedisUtil;
-
-/**    
- * @Description: SIP信令处理分配
- * @author: swwheihei
- * @date:   2020年5月3日 下午4:24:37     
- */
-@Component
-public class SIPProcessorFactory {
-	
-	// private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
-	
-	@Autowired
-	private SipConfig sipConfig;
-	
-	@Autowired
-	private RegisterLogicHandler handler;
-	
-	@Autowired
-	private IVideoManagerStorager storager;
-
-	@Autowired
-	private IRedisCatchStorage redisCatchStorage;
-
-	@Autowired
-	private EventPublisher publisher;
-	
-	@Autowired
-	private SIPCommander cmder;
-
-	@Autowired
-	private SIPCommanderFroPlatform cmderFroPlatform;
-
-	@Autowired
-	private IDeviceAlarmService deviceAlarmService;
-
-	@Autowired
-	private RedisUtil redis;
-	
-	@Autowired
-	private DeferredResultHolder deferredResultHolder;
-	
-	@Autowired
-	private DeviceOffLineDetector offLineDetector;
-	
-	@Autowired
-	private InviteResponseProcessor inviteResponseProcessor;
-	
-	@Autowired
-	private ByeResponseProcessor byeResponseProcessor;
-	
-	@Autowired
-	private CancelResponseProcessor cancelResponseProcessor;
-
-	@Autowired
-	@Lazy
-	private RegisterResponseProcessor registerResponseProcessor;
-
-
-	@Autowired
-	private OtherResponseProcessor otherResponseProcessor;
-
-	@Autowired
-	private IPlayService playService;
-
-	@Autowired
-	private ZLMRTPServerFactory zlmrtpServerFactory;
-
-	@Autowired
-	private IMediaServerService mediaServerService;
-
-	// 注:这里使用注解会导致循环依赖注入,暂用springBean
-	private SipProvider tcpSipProvider;
-		
-	// 注:这里使用注解会导致循环依赖注入,暂用springBean
-	private SipProvider udpSipProvider;
-	
-	public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) {
-		Request request = evt.getRequest();
-		String method = request.getMethod();
-//		logger.info("接收到消息:"+request.getMethod());
-//		sipSubscribe.getSubscribe(evt.getServerTransaction().getBranchId()).response(evt);
-		if (Request.INVITE.equals(method)) {
-			InviteRequestProcessor processor = new InviteRequestProcessor();
-			processor.setRequestEvent(evt);
-			processor.setTcpSipProvider(getTcpSipProvider());
-			processor.setUdpSipProvider(getUdpSipProvider());
-
-			processor.setCmder(cmder);
-			processor.setCmderFroPlatform(cmderFroPlatform);
-			processor.setPlayService(playService);
-			processor.setStorager(storager);
-			processor.setRedisCatchStorage(redisCatchStorage);
-			processor.setZlmrtpServerFactory(zlmrtpServerFactory);
-			processor.setMediaServerService(mediaServerService);
-			return processor;
-		} else if (Request.REGISTER.equals(method)) {
-			RegisterRequestProcessor processor = new RegisterRequestProcessor();
-			processor.setRequestEvent(evt);
-			processor.setTcpSipProvider(getTcpSipProvider());
-			processor.setUdpSipProvider(getUdpSipProvider());
-			processor.setHandler(handler);
-			processor.setPublisher(publisher);
-			processor.setSipConfig(sipConfig);
-			processor.setVideoManagerStorager(storager);
-			return processor;
-		} else if (Request.SUBSCRIBE.equals(method)) {
-			SubscribeRequestProcessor processor = new SubscribeRequestProcessor();
-			processor.setTcpSipProvider(getTcpSipProvider());
-			processor.setUdpSipProvider(getUdpSipProvider());
-			processor.setRequestEvent(evt);
-			return processor;
-		} else if (Request.ACK.equals(method)) {
-			AckRequestProcessor processor = new AckRequestProcessor();
-			processor.setRequestEvent(evt);
-			processor.setRedisCatchStorage(redisCatchStorage);
-			processor.setZlmrtpServerFactory(zlmrtpServerFactory);
-			processor.setMediaServerService(mediaServerService);
-			return processor;
-		} else if (Request.BYE.equals(method)) {
-			ByeRequestProcessor processor = new ByeRequestProcessor();
-			processor.setRequestEvent(evt);
-			processor.setRedisCatchStorage(redisCatchStorage);
-			processor.setStorager(storager);
-			processor.setZlmrtpServerFactory(zlmrtpServerFactory);
-			processor.setSIPCommander(cmder);
-			processor.setMediaServerService(mediaServerService);
-			return processor;
-		} else if (Request.CANCEL.equals(method)) {
-			CancelRequestProcessor processor = new CancelRequestProcessor();
-			processor.setRequestEvent(evt);
-			return processor;
-		} else if (Request.MESSAGE.equals(method)) {
-			MessageRequestProcessor processor = new MessageRequestProcessor();
-			processor.setRequestEvent(evt);
-			processor.setTcpSipProvider(getTcpSipProvider());
-			processor.setUdpSipProvider(getUdpSipProvider());
-			processor.setPublisher(publisher);
-			processor.setRedis(redis);
-			processor.setDeferredResultHolder(deferredResultHolder);
-			processor.setOffLineDetector(offLineDetector);
-			processor.setCmder(cmder);
-			processor.setCmderFroPlatform(cmderFroPlatform);
-			processor.setDeviceAlarmService(deviceAlarmService);
-			processor.setStorager(storager);
-			processor.setRedisCatchStorage(redisCatchStorage);
-			return processor;
-		} else if (Request.NOTIFY.equalsIgnoreCase(method)) {
-			NotifyRequestProcessor processor = new NotifyRequestProcessor();
-			processor.setRequestEvent(evt);
-			processor.setTcpSipProvider(getTcpSipProvider());
-			processor.setUdpSipProvider(getUdpSipProvider());
-			processor.setPublisher(publisher);
-			processor.setRedis(redis);
-			processor.setDeferredResultHolder(deferredResultHolder);
-			processor.setOffLineDetector(offLineDetector);
-			processor.setCmder(cmder);
-			processor.setStorager(storager);
-			processor.setRedisCatchStorage(redisCatchStorage);
-			return processor;
-		} else {
-			OtherRequestProcessor processor = new OtherRequestProcessor();
-			processor.setRequestEvent(evt);
-			return processor;
-		}
-	}
-	
-	public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) {
-
-		Response response = evt.getResponse();
-		CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
-		String method = cseqHeader.getMethod();
-		if(Request.INVITE.equals(method)){
-			return inviteResponseProcessor;
-		} else if (Request.BYE.equals(method)) {
-			return byeResponseProcessor;
-		} else if (Request.CANCEL.equals(method)) {
-			return cancelResponseProcessor;
-		}else if (Request.REGISTER.equals(method)) {
-			return registerResponseProcessor;
-		} else {
-			return otherResponseProcessor;
-		}
-	}
-	
-	private SipProvider getTcpSipProvider() {
-		if (tcpSipProvider == null) {
-			tcpSipProvider = (SipProvider) SpringBeanFactory.getBean("tcpSipProvider");
-		}
-		return tcpSipProvider;
-	}
-	
-	private SipProvider getUdpSipProvider() {
-		if (udpSipProvider == null) {
-			udpSipProvider = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
-		}
-		return udpSipProvider;
-	}
-	
-}

+ 113 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java

@@ -0,0 +1,113 @@
+package com.genersoft.iot.vmp.gb28181.transmit;
+
+import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
+import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor;
+import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.sip.*;
+import javax.sip.header.CSeqHeader;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @description: SIP信令处理类观察者
+ * @author: panlinlin
+ * @date:   2021年11月5日 下午15:32
+ */
+@Component
+public class SIPProcessorObserver implements SipListener {
+
+    private final static Logger logger = LoggerFactory.getLogger(SIPProcessorObserver.class);
+
+    private static Map<String, ISIPRequestProcessor> requestProcessorMap = new ConcurrentHashMap<>();
+    private static Map<String, ISIPResponseProcessor> responseProcessorMap = new ConcurrentHashMap<>();
+    private static ITimeoutProcessor timeoutProcessor;
+
+    /**
+     * 添加 request订阅
+     * @param method 方法名
+     * @param processor 处理程序
+     */
+    public void addRequestProcessor(String method, ISIPRequestProcessor processor) {
+        requestProcessorMap.put(method, processor);
+    }
+
+    /**
+     * 添加 response订阅
+     * @param method 方法名
+     * @param processor 处理程序
+     */
+    public void addResponseProcessor(String method, ISIPResponseProcessor processor) {
+        responseProcessorMap.put(method, processor);
+    }
+
+    /**
+     * 添加 超时事件订阅
+     * @param processor 处理程序
+     */
+    public void addTimeoutProcessor(ITimeoutProcessor processor) {
+        this.timeoutProcessor = processor;
+    }
+
+    /**
+     * 分发RequestEvent事件
+     * @param requestEvent RequestEvent事件
+     */
+    @Override
+    public void processRequest(RequestEvent requestEvent) {
+        String method = requestEvent.getRequest().getMethod();
+        ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method);
+        if (sipRequestProcessor == null) {
+            logger.warn("不支持方法{}的request", method);
+            return;
+        }
+        requestProcessorMap.get(requestEvent.getRequest().getMethod()).process(requestEvent);
+    }
+
+    /**
+     * 分发ResponseEvent事件
+     * @param responseEvent responseEvent事件
+     */
+    @Override
+    public void processResponse(ResponseEvent responseEvent) {
+        CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
+        String method = cseqHeader.getMethod();
+        ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method);
+        if (sipRequestProcessor == null) {
+            logger.warn("不支持方法{}的response", method);
+            return;
+        }
+        sipRequestProcessor.process(responseEvent);
+    }
+
+    /**
+     * 向超时订阅发送消息
+     * @param timeoutEvent timeoutEvent事件
+     */
+    @Override
+    public void processTimeout(TimeoutEvent timeoutEvent) {
+        if(timeoutProcessor != null) {
+            timeoutProcessor.process(timeoutEvent);
+        }
+    }
+
+    @Override
+    public void processIOException(IOExceptionEvent exceptionEvent) {
+
+    }
+
+    @Override
+    public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
+
+    }
+
+    @Override
+    public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
+
+    }
+
+
+}

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

@@ -7,7 +7,7 @@ import java.util.concurrent.TimeUnit;
 
 import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
 import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
-import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor;
+import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.MessageRequestProcessor;
 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
 
 import org.slf4j.Logger;

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

@@ -11,7 +11,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.async.DeferredResult;
 
 /**    
- * @Description: 异步请求处理
+ * @description: 异步请求处理
  * @author: swwheihei
  * @date:   2020年5月8日 下午7:59:05     
  */

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

@@ -1,7 +1,7 @@
 package com.genersoft.iot.vmp.gb28181.transmit.callback;
 
 /**    
- * @Description: 请求信息定义   
+ * @description: 请求信息定义   
  * @author: swwheihei
  * @date:   2020年5月8日 下午1:09:18     
  */

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

@@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 
 /**    
- * @Description:设备能力接口,用于定义设备的控制、查询能力   
+ * @description:设备能力接口,用于定义设备的控制、查询能力   
  * @author: swwheihei
  * @date:   2020年5月3日 下午9:16:34     
  */
@@ -299,4 +299,11 @@ public interface ISIPCommander {
 	 * @return				true = 命令发送成功
 	 */
 	boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
+
+	/**
+	 * 订阅、取消订阅目录信息
+	 * @param device		视频设备
+	 * @return				true = 命令发送成功
+	 */
+	boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent);
 }

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

@@ -19,7 +19,7 @@ import java.util.List;
 import java.util.UUID;
 
 /**
- * @Description: 平台命令request创造器 TODO 冗余代码太多待优化
+ * @description: 平台命令request创造器 TODO 冗余代码太多待优化
  * @author: panll
  * @date: 2020年5月6日 上午9:29:02
  */

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

@@ -18,7 +18,7 @@ import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 
 /**
- * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化
+ * @description:摄像头命令request创造器 TODO 冗余代码太多待优化
  * @author: swwheihei
  * @date: 2020年5月6日 上午9:29:02
  */

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

@@ -1,20 +1,17 @@
 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
 
-import java.lang.reflect.Field;
-import java.text.ParseException;
-import java.util.HashSet;
-
-import javax.sip.*;
-import javax.sip.address.SipURI;
-import javax.sip.header.CallIdHeader;
-import javax.sip.header.ViaHeader;
-import javax.sip.message.Request;
-
 import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.conf.UserSetup;
+import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
-import com.genersoft.iot.vmp.media.zlm.*;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
+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 com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
+import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.IMediaServerService;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -29,20 +26,20 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.DependsOn;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Component;
-
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
-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 com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
 import org.springframework.util.StringUtils;
 
+import javax.sip.*;
+import javax.sip.address.SipURI;
+import javax.sip.header.CallIdHeader;
+import javax.sip.header.ViaHeader;
+import javax.sip.message.Request;
+import java.lang.reflect.Field;
+import java.text.ParseException;
+import java.util.HashSet;
+
 /**    
- * @Description:设备能力接口,用于定义设备的控制、查询能力   
+ * @description:设备能力接口,用于定义设备的控制、查询能力   
  * @author: swwheihei
  * @date:   2020年5月3日 下午9:22:48     
  */
@@ -55,12 +52,10 @@ public class SIPCommander implements ISIPCommander {
 	@Autowired
 	private SipConfig sipConfig;
 
-	@Lazy
 	@Autowired
 	@Qualifier(value="tcpSipProvider")
 	private SipProviderImpl tcpSipProvider;
 
-	@Lazy
 	@Autowired
 	@Qualifier(value="udpSipProvider")
 	private SipProviderImpl udpSipProvider;
@@ -89,11 +84,6 @@ public class SIPCommander implements ISIPCommander {
 	@Autowired
 	private IMediaServerService mediaServerService;
 
-	private SIPDialog dialog;
-
-	public SipConfig getSipConfig() {
-		return sipConfig;
-	}
 
 	/**
 	 * 云台方向放控制,使用配置文件中的默认镜头移动速度
@@ -1490,6 +1480,33 @@ public class SIPCommander implements ISIPCommander {
 		}
 	}
 
+	@Override
+	public boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
+		try {
+			StringBuffer cmdXml = new StringBuffer(200);
+			cmdXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
+			cmdXml.append("<Query>\r\n");
+			cmdXml.append("<CmdType>CataLog</CmdType>\r\n");
+			cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
+			cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
+			cmdXml.append("</Query>\r\n");
+
+			String tm = Long.toString(System.currentTimeMillis());
+
+			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
+					: udpSipProvider.getNewCallId();
+
+			Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, device.getSubscribeCycleForCatalog(), "presence" , callIdHeader);
+			transmitRequest(device, request, errorEvent, okEvent);
+
+			return true;
+
+		} catch ( NumberFormatException | ParseException | InvalidArgumentException	| SipException e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
 
 	private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
 		return transmitRequest(device, request, null, null);

+ 8 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/SIPResponseProcessorAbstract.java

@@ -0,0 +1,8 @@
+package com.genersoft.iot.vmp.gb28181.transmit.event.response;
+
+import org.springframework.beans.factory.InitializingBean;
+
+public abstract class SIPResponseProcessorAbstract implements InitializingBean, ISIPResponseProcessor {
+
+
+}

+ 7 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/ITimeoutProcessor.java

@@ -0,0 +1,7 @@
+package com.genersoft.iot.vmp.gb28181.transmit.event.timeout;
+
+import javax.sip.TimeoutEvent;
+
+public interface ITimeoutProcessor {
+    void process(TimeoutEvent event);
+}

+ 36 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/impl/TimeoutProcessorImpl.java

@@ -0,0 +1,36 @@
+package com.genersoft.iot.vmp.gb28181.transmit.event.timeout.impl;
+
+import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
+import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.sip.TimeoutEvent;
+import javax.sip.header.CallIdHeader;
+
+@Component
+public class TimeoutProcessorImpl implements InitializingBean, ITimeoutProcessor {
+
+    @Autowired
+    private SIPProcessorObserver processorObserver;
+
+    @Autowired
+    private SipSubscribe sipSubscribe;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        processorObserver.addTimeoutProcessor(this);
+    }
+
+    @Override
+    public void process(TimeoutEvent event) {
+        // TODO Auto-generated method stub
+        CallIdHeader callIdHeader = event.getClientTransaction().getDialog().getCallId();
+        String callId = callIdHeader.getCallId();
+        SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
+        SipSubscribe.EventResult<TimeoutEvent> timeoutEventEventResult = new SipSubscribe.EventResult<>(event);
+        errorSubscribe.response(timeoutEventEventResult);
+    }
+}

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

@@ -1,12 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request;
-
-/**    
- * @Description:处理接收IPCamera发来的SIP协议请求消息
- * @author: swwheihei
- * @date:   2020年5月3日 下午4:42:22     
- */
-public interface ISIPRequestProcessor {
-
-	public void process();
-
-}

+ 0 - 131
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java

@@ -1,131 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request;
-
-import javax.sip.PeerUnavailableException;
-import javax.sip.RequestEvent;
-import javax.sip.ServerTransaction;
-import javax.sip.SipFactory;
-import javax.sip.SipProvider;
-import javax.sip.TransactionAlreadyExistsException;
-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 gov.nist.javax.sip.SipStackImpl;
-import gov.nist.javax.sip.message.SIPRequest;
-import gov.nist.javax.sip.stack.SIPServerTransaction;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**    
- * @Description:处理接收IPCamera发来的SIP协议请求消息
- * @author: songww
- * @date:   2020年5月3日 下午4:42:22     
- */
-public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcessor {
-
-	private final static Logger logger = LoggerFactory.getLogger(SIPRequestAbstractProcessor.class);
-
-	protected RequestEvent evt;
-	
-	private SipProvider tcpSipProvider;
-	
-	private SipProvider udpSipProvider;
-	
-	@Override
-	public void process() {
-		this.process(evt);
-	}
-	
-	public abstract void process(RequestEvent evt);
-	
-	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) {
-					SipStackImpl stack = (SipStackImpl)tcpSipProvider.getSipStack();
-					serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
-					if (serverTransaction == null) {
-						serverTransaction = tcpSipProvider.getNewServerTransaction(request);
-					}
-				} else {
-					SipStackImpl stack = (SipStackImpl)udpSipProvider.getSipStack();
-					serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
-					if (serverTransaction == null) {
-						serverTransaction = udpSipProvider.getNewServerTransaction(request);
-					}
-				}
-			} catch (TransactionAlreadyExistsException e) {
-				logger.error(e.getMessage());
-			} catch (TransactionUnavailableException e) {
-				logger.error(e.getMessage());
-			}
-		}
-		return serverTransaction;
-	}
-	
-	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;
-	}
-
-	public RequestEvent getRequestEvent() {
-		return evt;
-	}
-
-	public void setRequestEvent(RequestEvent evt) {
-		this.evt = evt;
-	}
-
-	public SipProvider getTcpSipProvider() {
-		return tcpSipProvider;
-	}
-
-	public void setTcpSipProvider(SipProvider tcpSipProvider) {
-		this.tcpSipProvider = tcpSipProvider;
-	}
-
-	public SipProvider getUdpSipProvider() {
-		return udpSipProvider;
-	}
-
-	public void setUdpSipProvider(SipProvider udpSipProvider) {
-		this.udpSipProvider = udpSipProvider;
-	}
-	
-	
-}

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

@@ -1,142 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.sip.*;
-import javax.sip.address.SipURI;
-import javax.sip.header.FromHeader;
-import javax.sip.header.HeaderAddress;
-import javax.sip.header.ToHeader;
-
-import com.genersoft.iot.vmp.common.StreamInfo;
-import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
-import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
-import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
-import com.genersoft.iot.vmp.service.IMediaServerService;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**    
- * @Description:ACK请求处理器  
- * @author: swwheihei
- * @date:   2020年5月3日 下午5:31:45     
- */
-public class AckRequestProcessor extends SIPRequestAbstractProcessor {
-
-	private Logger logger = LoggerFactory.getLogger(AckRequestProcessor.class);
-
-    private IRedisCatchStorage redisCatchStorage;
-
-	private ZLMRTPServerFactory zlmrtpServerFactory;
-
-	private IMediaServerService mediaServerService;
-
-	/**   
-	 * 处理  ACK请求
-	 * 
-	 * @param evt
-	 */
-	@Override
-	public void process(RequestEvent evt) {
-		//Request request = evt.getRequest();
-		Dialog dialog = evt.getDialog();
-		if (dialog == null) return;
-		//DialogState state = dialog.getState();
-		if (/*request.getMecodewwthod().equals(Request.INVITE) &&*/ dialog.getState()== DialogState.CONFIRMED) {
-			String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
-			String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
-			SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(platformGbId, channelId);
-			String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
-			String deviceId = sendRtpItem.getDeviceId();
-			StreamInfo streamInfo = null;
-			if (deviceId == null) {
-				streamInfo = new StreamInfo();
-				streamInfo.setApp(sendRtpItem.getApp());
-				streamInfo.setStreamId(sendRtpItem.getStreamId());
-			}else {
-				streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
-				sendRtpItem.setStreamId(streamInfo.getStreamId());
-				streamInfo.setApp("rtp");
-			}
-
-			redisCatchStorage.updateSendRTPSever(sendRtpItem);
-			logger.info(platformGbId);
-			logger.info(channelId);
-			Map<String, Object> param = new HashMap<>();
-			param.put("vhost","__defaultVhost__");
-			param.put("app",streamInfo.getApp());
-			param.put("stream",streamInfo.getStreamId());
-			param.put("ssrc", sendRtpItem.getSsrc());
-			param.put("dst_url",sendRtpItem.getIp());
-			param.put("dst_port", sendRtpItem.getPort());
-			param.put("is_udp", is_Udp);
-			//param.put ("src_port", sendRtpItem.getLocalPort());
-			// 设备推流查询,成功后才能转推
-			boolean rtpPushed = false;
-			long startTime = System.currentTimeMillis();
-			while (!rtpPushed) {
-				try {
-					if (System.currentTimeMillis() - startTime < 30 * 1000) {
-						MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
-						if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) {
-							rtpPushed = true;
-							logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",
-									streamInfo.getApp() ,streamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort());
-							zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
-						} else {
-							logger.info("等待设备推流[{}/{}].......",
-									streamInfo.getApp() ,streamInfo.getStreamId());
-							Thread.sleep(1000);
-							continue;
-						}
-					} else {
-						rtpPushed = true;
-						logger.info("设备推流[{}/{}]超时,终止向上级推流",
-								streamInfo.getApp() ,streamInfo.getStreamId());
-					}
-				} catch (InterruptedException e) {
-					e.printStackTrace();
-				}
-			}
-		}
-		// try {
-		// 	Request ackRequest = null;
-		// 	CSeq csReq = (CSeq) request.getHeader(CSeq.NAME);
-		// 	ackRequest = dialog.createAck(csReq.getSeqNumber());
-		// 	dialog.sendAck(ackRequest);
-		// 	logger.info("send ack to callee:" + ackRequest.toString());
-		// } catch (SipException e) {
-		// 	e.printStackTrace();
-		// } catch (InvalidArgumentException e) {
-		// 	e.printStackTrace();
-		// }
-		
-	}
-
-	public IRedisCatchStorage getRedisCatchStorage() {
-		return redisCatchStorage;
-	}
-
-	public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
-		this.redisCatchStorage = redisCatchStorage;
-	}
-
-	public ZLMRTPServerFactory getZlmrtpServerFactory() {
-		return zlmrtpServerFactory;
-	}
-
-	public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
-		this.zlmrtpServerFactory = zlmrtpServerFactory;
-	}
-
-	public IMediaServerService getMediaServerService() {
-		return mediaServerService;
-	}
-
-	public void setMediaServerService(IMediaServerService mediaServerService) {
-		this.mediaServerService = mediaServerService;
-	}
-}

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

@@ -1,150 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
-
-import javax.sip.*;
-import javax.sip.address.SipURI;
-import javax.sip.header.FromHeader;
-import javax.sip.header.HeaderAddress;
-import javax.sip.header.ToHeader;
-import javax.sip.message.Response;
-
-import com.genersoft.iot.vmp.common.StreamInfo;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
-import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
-import com.genersoft.iot.vmp.service.IMediaServerService;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.text.ParseException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**    
- * @Description: BYE请求处理器
- * @author: lawrencehj
- * @date:   2021年3月9日     
- */
-public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
-
-	private Logger logger = LoggerFactory.getLogger(ByeRequestProcessor.class);
-
-	private ISIPCommander cmder;
-
-	private IRedisCatchStorage redisCatchStorage;
-
-	private IVideoManagerStorager storager;
-
-	private ZLMRTPServerFactory zlmrtpServerFactory;
-
-	private IMediaServerService mediaServerService;
-
-	/**
-	 * 处理BYE请求
-	 * @param evt
-	 */
-	@Override
-	public void process(RequestEvent evt) {
-		try {
-			responseAck(evt);
-			Dialog dialog = evt.getDialog();
-			if (dialog == null) return;
-			if (dialog.getState().equals(DialogState.TERMINATED)) {
-				String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
-				String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
-				SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(platformGbId, channelId);
-				logger.info("收到bye, [{}/{}]", platformGbId, channelId);
-				if (sendRtpItem != null){
-					String streamId = sendRtpItem.getStreamId();
-					Map<String, Object> param = new HashMap<>();
-					param.put("vhost","__defaultVhost__");
-					param.put("app",sendRtpItem.getApp());
-					param.put("stream",streamId);
-					param.put("ssrc",sendRtpItem.getSsrc());
-					logger.info("停止向上级推流:" + streamId);
-					MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
-					zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
-					redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
-					if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) {
-						logger.info(streamId + "无其它观看者,通知设备停止推流");
-						cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId);
-					}
-				}
-				// 可能是设备主动停止
-				Device device = storager.queryVideoDeviceByChannelId(platformGbId);
-				if (device != null) {
-					StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
-					if (streamInfo != null) {
-						redisCatchStorage.stopPlay(streamInfo);
-					}
-					storager.stopPlay(device.getDeviceId(), channelId);
-					mediaServerService.closeRTPServer(device, channelId);
-				}
-			}
-		} catch (SipException e) {
-			e.printStackTrace();
-		} catch (InvalidArgumentException e) {
-			e.printStackTrace();
-		} catch (ParseException e) {
-			e.printStackTrace();
-		}
-	}
-
-	/***
-	 * 回复200 OK
-	 * @param evt
-	 * @throws SipException
-	 * @throws InvalidArgumentException
-	 * @throws ParseException
-	 */
-	private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
-		Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
-		ServerTransaction serverTransaction = getServerTransaction(evt);
-		serverTransaction.sendResponse(response);
-		if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
-	}
-
-	public IRedisCatchStorage getRedisCatchStorage() {
-		return redisCatchStorage;
-	}
-
-	public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
-		this.redisCatchStorage = redisCatchStorage;
-	}
-
-	public ZLMRTPServerFactory getZlmrtpServerFactory() {
-		return zlmrtpServerFactory;
-	}
-
-	public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
-		this.zlmrtpServerFactory = zlmrtpServerFactory;
-	}
-
-	public ISIPCommander getSIPCommander() {
-		return cmder;
-	}
-
-	public void setSIPCommander(ISIPCommander cmder) {
-		this.cmder = cmder;
-	}
-
-	public IMediaServerService getMediaServerService() {
-		return mediaServerService;
-	}
-
-	public void setMediaServerService(IMediaServerService mediaServerService) {
-		this.mediaServerService = mediaServerService;
-	}
-
-	public IVideoManagerStorager getStorager() {
-		return storager;
-	}
-
-	public void setStorager(IVideoManagerStorager storager) {
-		this.storager = storager;
-	}
-}

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

@@ -1,28 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
-
-import javax.sip.RequestEvent;
-
-import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
-
-/**    
- * @Description:CANCEL请求处理器
- * @author: swwheihei
- * @date:   2020年5月3日 下午5:32:23     
- */
-public class CancelRequestProcessor extends SIPRequestAbstractProcessor {
-
-	/**   
-	 * 处理CANCEL请求
-	 *  
-	 * @param evt
-	 * @param layer
-	 * @param transaction
-	 * @param config    
-	 */  
-	@Override
-	public void process(RequestEvent evt) {
-		// TODO 优先级99 Cancel Request消息实现,此消息一般为级联消息,上级给下级发送请求取消指令
-		
-	}
-
-}

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

@@ -1,478 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
-
-import javax.sdp.*;
-import javax.sip.*;
-import javax.sip.address.Address;
-import javax.sip.address.SipURI;
-import javax.sip.header.*;
-import javax.sip.message.Request;
-import javax.sip.message.Response;
-
-import com.genersoft.iot.vmp.gb28181.bean.*;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
-import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
-import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
-import com.genersoft.iot.vmp.service.IMediaServerService;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
-import com.genersoft.iot.vmp.service.IPlayService;
-import gov.nist.javax.sip.address.AddressImpl;
-import gov.nist.javax.sip.address.SipUri;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.text.ParseException;
-import java.util.Vector;
-
-/**    
- * @Description:处理INVITE请求
- * @author: panll
- * @date:   2021年1月14日
- */
-@SuppressWarnings("rawtypes")
-public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
-
-	private final static Logger logger = LoggerFactory.getLogger(InviteRequestProcessor.class);
-
-	private SIPCommanderFroPlatform cmderFroPlatform;
-
-	private IVideoManagerStorager storager;
-
-	private IRedisCatchStorage  redisCatchStorage;
-
-	private SIPCommander cmder;
-
-	private IPlayService playService;
-
-	private ZLMRTPServerFactory zlmrtpServerFactory;
-
-	private IMediaServerService mediaServerService;
-
-	public ZLMRTPServerFactory getZlmrtpServerFactory() {
-		return zlmrtpServerFactory;
-	}
-
-	public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
-		this.zlmrtpServerFactory = zlmrtpServerFactory;
-	}
-
-	/**
-	 * 处理invite请求
-	 * 
-	 * @param evt
-	 *            请求消息
-	 */ 
-	@Override
-	public void process(RequestEvent evt) {
-		//  Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令
-		try {
-			Request request = evt.getRequest();
-			SipURI sipURI = (SipURI) request.getRequestURI();
-			String channelId = sipURI.getUser();
-			String requesterId = null;
-
-			FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
-			AddressImpl address = (AddressImpl) fromHeader.getAddress();
-			SipUri uri = (SipUri) address.getURI();
-			requesterId = uri.getUser();
-
-			if (requesterId == null || channelId == null) {
-				logger.info("无法从FromHeader的Address中获取到平台id,返回400");
-				responseAck(evt, Response.BAD_REQUEST); // 参数不全, 发400,请求错误
-				return;
-			}
-
-			// 查询请求方是否上级平台
-			ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
-			if (platform != null) {
-				// 查询平台下是否有该通道
-				DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
-				GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
-				MediaServerItem mediaServerItem = null;
-				// 不是通道可能是直播流
-				if (channel != null && gbStream == null ) {
-					if (channel.getStatus() == 0) {
-						logger.info("通道离线,返回400");
-						responseAck(evt, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
-						return;
-					}
-					responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
-				}else if(channel == null && gbStream != null){
-					String mediaServerId = gbStream.getMediaServerId();
-					mediaServerItem = mediaServerService.getOne(mediaServerId);
-					if (mediaServerItem == null) {
-						logger.info("[ app={}, stream={} ]找不到zlm {},返回410",gbStream.getApp(), gbStream.getStream(), mediaServerId);
-						responseAck(evt, Response.GONE, "media server not found");
-						return;
-					}
-					Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
-					if (!streamReady ) {
-						logger.info("[ app={}, stream={} ]通道离线,返回400",gbStream.getApp(), gbStream.getStream());
-						responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
-						return;
-					}
-					responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
-				}else {
-					logger.info("通道不存在,返回404");
-					responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在
-					return;
-				}
-				// 解析sdp消息, 使用jainsip 自带的sdp解析方式
-				String contentString = new String(request.getRawContent());
-
-				// jainSip不支持y=字段, 移除移除以解析。
-				int ssrcIndex = contentString.indexOf("y=");
-				//ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段
-				String ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
-				String substring = contentString.substring(0, contentString.indexOf("y="));
-				SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
-
-				//  获取支持的格式
-				Vector mediaDescriptions = sdp.getMediaDescriptions(true);
-				// 查看是否支持PS 负载96
-				//String ip = null;
-				int port = -1;
-				//boolean recvonly = false;
-				boolean mediaTransmissionTCP = false;
-				Boolean tcpActive = null;
-				for (Object description : mediaDescriptions) {
-					MediaDescription mediaDescription = (MediaDescription) description;
-					Media media = mediaDescription.getMedia();
-
-					Vector mediaFormats = media.getMediaFormats(false);
-					if (mediaFormats.contains("96")) {
-						port = media.getMediaPort();
-						//String mediaType = media.getMediaType();
-						String protocol = media.getProtocol();
-
-						// 区分TCP发流还是udp, 当前默认udp
-						if ("TCP/RTP/AVP".equals(protocol)) {
-							String setup = mediaDescription.getAttribute("setup");
-							if (setup != null) {
-								mediaTransmissionTCP = true;
-								if ("active".equals(setup)) {
-									tcpActive = true;
-								} else if ("passive".equals(setup)) {
-									tcpActive = false;
-								}
-							}
-						}
-						break;
-					}
-				}
-				if (port == -1) {
-					logger.info("不支持的媒体格式,返回415");
-					// 回复不支持的格式
-					responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
-					return;
-				}
-				String username = sdp.getOrigin().getUsername();
-				String addressStr = sdp.getOrigin().getAddress();
-				//String sessionName = sdp.getSessionName().getValue();
-				logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc);
-				Device device  = null;
-				// 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标
-				if (channel != null) {
-					device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId);
-					if (device == null) {
-						logger.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel);
-						responseAck(evt, Response.SERVER_INTERNAL_ERROR);
-						return;
-					}
-					mediaServerItem = playService.getNewMediaServerItem(device);
-					if (mediaServerItem == null) {
-						logger.warn("未找到可用的zlm");
-						responseAck(evt, Response.BUSY_HERE);
-						return;
-					}
-					SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
-							device.getDeviceId(), channelId,
-							mediaTransmissionTCP);
-					if (tcpActive != null) {
-						sendRtpItem.setTcpActive(tcpActive);
-					}
-					if (sendRtpItem == null) {
-						logger.warn("服务器端口资源不足");
-						responseAck(evt, Response.BUSY_HERE);
-						return;
-					}
-
-					// 写入redis, 超时时回复
-					redisCatchStorage.updateSendRTPSever(sendRtpItem);
-					// 通知下级推流,
-					PlayResult playResult = playService.play(mediaServerItem,device.getDeviceId(), channelId, (mediaServerItemInUSe, responseJSON)->{
-						// 收到推流, 回复200OK, 等待ack
-						// if (sendRtpItem == null) return;
-						sendRtpItem.setStatus(1);
-						redisCatchStorage.updateSendRTPSever(sendRtpItem);
-						// TODO 添加对tcp的支持
-
-						StringBuffer content = new StringBuffer(200);
-						content.append("v=0\r\n");
-						content.append("o="+ channelId +" 0 0 IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n");
-						content.append("s=Play\r\n");
-						content.append("c=IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n");
-						content.append("t=0 0\r\n");
-						content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
-						content.append("a=sendonly\r\n");
-						content.append("a=rtpmap:96 PS/90000\r\n");
-						content.append("y="+ ssrc + "\r\n");
-						content.append("f=\r\n");
-
-						try {
-							responseAck(evt, content.toString());
-						} catch (SipException e) {
-							e.printStackTrace();
-						} catch (InvalidArgumentException e) {
-							e.printStackTrace();
-						} catch (ParseException e) {
-							e.printStackTrace();
-						}
-					} ,((event) -> {
-						// 未知错误。直接转发设备点播的错误
-						Response response = null;
-						try {
-							response = getMessageFactory().createResponse(event.statusCode, evt.getRequest());
-							ServerTransaction serverTransaction = getServerTransaction(evt);
-							serverTransaction.sendResponse(response);
-							if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
-						} catch (ParseException | SipException | InvalidArgumentException e) {
-							e.printStackTrace();
-						}
-					}));
-					if (logger.isDebugEnabled()) {
-						logger.debug(playResult.getResult().toString());
-					}
-
-				}else if (gbStream != null) {
-					SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
-							gbStream.getApp(), gbStream.getStream(), channelId,
-							mediaTransmissionTCP);
-
-					if (tcpActive != null) {
-						sendRtpItem.setTcpActive(tcpActive);
-					}
-					if (sendRtpItem == null) {
-						logger.warn("服务器端口资源不足");
-						responseAck(evt, Response.BUSY_HERE);
-						return;
-					}
-
-					// 写入redis, 超时时回复
-					redisCatchStorage.updateSendRTPSever(sendRtpItem);
-
-					sendRtpItem.setStatus(1);
-					redisCatchStorage.updateSendRTPSever(sendRtpItem);
-					// TODO 添加对tcp的支持
-					StringBuffer content = new StringBuffer(200);
-					content.append("v=0\r\n");
-					content.append("o="+ channelId +" 0 0 IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
-					content.append("s=Play\r\n");
-					content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
-					content.append("t=0 0\r\n");
-					content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
-					content.append("a=sendonly\r\n");
-					content.append("a=rtpmap:96 PS/90000\r\n");
-					content.append("y="+ ssrc + "\r\n");
-					content.append("f=\r\n");
-
-					try {
-						responseAck(evt, content.toString());
-					} catch (SipException e) {
-						e.printStackTrace();
-					} catch (InvalidArgumentException e) {
-						e.printStackTrace();
-					} catch (ParseException e) {
-						e.printStackTrace();
-					}
-				}
-
-			} else {
-				// 非上级平台请求,查询是否设备请求(通常为接收语音广播的设备)
-				Device device = storager.queryVideoDevice(requesterId);
-				if (device != null) {
-					logger.info("收到设备" + requesterId + "的语音广播Invite请求");
-					responseAck(evt, Response.TRYING);
-
-					String contentString = new String(request.getRawContent());
-					// jainSip不支持y=字段, 移除移除以解析。
-					String substring = contentString;
-					String ssrc = "0000000404";
-					int ssrcIndex = contentString.indexOf("y=");
-					if (ssrcIndex > 0) {
-						substring = contentString.substring(0, ssrcIndex);
-						ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
-					}
-					ssrcIndex = substring.indexOf("f=");
-					if (ssrcIndex > 0) {
-						substring = contentString.substring(0, ssrcIndex);
-					}
-					SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
-
-					//  获取支持的格式
-					Vector mediaDescriptions = sdp.getMediaDescriptions(true);
-					// 查看是否支持PS 负载96
-					int port = -1;
-					//boolean recvonly = false;
-					boolean mediaTransmissionTCP = false;
-					Boolean tcpActive = null;
-					for (int i = 0; i < mediaDescriptions.size(); i++) {
-						MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
-						Media media = mediaDescription.getMedia();
-
-						Vector mediaFormats = media.getMediaFormats(false);
-						if (mediaFormats.contains("8")) {
-							port = media.getMediaPort();
-							String protocol = media.getProtocol();
-							// 区分TCP发流还是udp, 当前默认udp
-							if ("TCP/RTP/AVP".equals(protocol)) {
-								String setup = mediaDescription.getAttribute("setup");
-								if (setup != null) {
-									mediaTransmissionTCP = true;
-									if ("active".equals(setup)) {
-										tcpActive = true;
-									} else if ("passive".equals(setup)) {
-										tcpActive = false;
-									}
-								}
-							}
-							break;
-						}
-					}
-					if (port == -1) {
-						logger.info("不支持的媒体格式,返回415");
-						// 回复不支持的格式
-						responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
-						return;
-					}
-					String username = sdp.getOrigin().getUsername();
-					String addressStr = sdp.getOrigin().getAddress();
-					logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}", username, addressStr, port, ssrc);
-
-				} else {
-					logger.warn("来自无效设备/平台的请求");
-					responseAck(evt, Response.BAD_REQUEST);
-				}
-			}
-
-		} catch (SipException | InvalidArgumentException | ParseException e) {
-			e.printStackTrace();
-			logger.warn("sdp解析错误");
-			e.printStackTrace();
-		} catch (SdpParseException e) {
-			e.printStackTrace();
-		} catch (SdpException e) {
-			e.printStackTrace();
-		}
-	}
-
-
-	/***
-	 * 回复状态码
-	 * 100 trying
-	 * 200 OK
-	 * 400
-	 * 404
-	 * @param evt
-	 * @throws SipException
-	 * @throws InvalidArgumentException
-	 * @throws ParseException
-	 */
-	private void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException {
-		Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
-		ServerTransaction serverTransaction = getServerTransaction(evt);
-		serverTransaction.sendResponse(response);
-		if (statusCode >= 200) {
-			if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
-		}
-	}
-
-	private void responseAck(RequestEvent evt, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
-		Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
-		response.setReasonPhrase(msg);
-		ServerTransaction serverTransaction = getServerTransaction(evt);
-		serverTransaction.sendResponse(response);
-		if (statusCode >= 200) {
-			if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
-		}
-	}
-
-	/**
-	 * 回复带sdp的200
-	 * @param evt
-	 * @param sdp
-	 * @throws SipException
-	 * @throws InvalidArgumentException
-	 * @throws ParseException
-	 */
-	private void responseAck(RequestEvent evt, String sdp) 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);
-
-		SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
-
-		Address concatAddress = sipFactory.createAddressFactory().createAddress(
-				sipFactory.createAddressFactory().createSipURI(sipURI.getUser(),  sipURI.getHost()+":"+sipURI.getPort()
-				));
-		response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
-		getServerTransaction(evt).sendResponse(response);
-	}
-
-
-
-
-
-
-	public SIPCommanderFroPlatform getCmderFroPlatform() {
-		return cmderFroPlatform;
-	}
-
-	public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) {
-		this.cmderFroPlatform = cmderFroPlatform;
-	}
-
-	public IVideoManagerStorager getStorager() {
-		return storager;
-	}
-
-	public void setStorager(IVideoManagerStorager storager) {
-		this.storager = storager;
-	}
-
-	public SIPCommander getCmder() {
-		return cmder;
-	}
-
-	public void setCmder(SIPCommander cmder) {
-		this.cmder = cmder;
-	}
-
-	public IPlayService getPlayService() {
-		return playService;
-	}
-
-	public void setPlayService(IPlayService playService) {
-		this.playService = playService;
-	}
-
-	public IRedisCatchStorage getRedisCatchStorage() {
-		return redisCatchStorage;
-	}
-
-	public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
-		this.redisCatchStorage = redisCatchStorage;
-	}
-
-	public IMediaServerService getMediaServerService() {
-		return mediaServerService;
-	}
-
-	public void setMediaServerService(IMediaServerService mediaServerService) {
-		this.mediaServerService = mediaServerService;
-	}
-}

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 1177
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java


+ 0 - 394
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/NotifyRequestProcessor.java

@@ -1,394 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
-
-import java.io.ByteArrayInputStream;
-import java.text.ParseException;
-import java.util.Iterator;
-
-import javax.sip.InvalidArgumentException;
-import javax.sip.RequestEvent;
-import javax.sip.ServerTransaction;
-import javax.sip.SipException;
-import javax.sip.message.Request;
-import javax.sip.message.Response;
-
-import com.genersoft.iot.vmp.common.VideoManagerConstants;
-import com.genersoft.iot.vmp.conf.UserSetup;
-import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
-import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
-import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
-import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
-import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
-import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
-import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
-import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-import com.genersoft.iot.vmp.utils.GpsUtil;
-import com.genersoft.iot.vmp.utils.SpringBeanFactory;
-import com.genersoft.iot.vmp.utils.redis.RedisUtil;
-
-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.util.StringUtils;
-
-/**
- * @Description: Notify请求处理器
- * @author: lawrencehj
- * @date: 2021年1月27日
- */
-
-public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
-    
-	private UserSetup userSetup = (UserSetup) SpringBeanFactory.getBean("userSetup");
-
-    private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
-
-	private IVideoManagerStorager storager;
-
-	private IRedisCatchStorage redisCatchStorage;
-
-	private EventPublisher publisher;
-
-	private DeviceOffLineDetector offLineDetector;
-
-	private static final String NOTIFY_CATALOG = "Catalog";
-	private static final String NOTIFY_ALARM = "Alarm";
-	private static final String NOTIFY_MOBILE_POSITION = "MobilePosition";
-
-	@Override
-	public void process(RequestEvent evt) {
-		try {
-			Element rootElement = getRootElement(evt);
-			String cmd = XmlUtil.getText(rootElement, "CmdType");
-
-			if (NOTIFY_CATALOG.equals(cmd)) {
-				logger.info("接收到Catalog通知");
-				processNotifyCatalogList(evt);
-			} else if (NOTIFY_ALARM.equals(cmd)) {
-				logger.info("接收到Alarm通知");
-				processNotifyAlarm(evt);
-			} else if (NOTIFY_MOBILE_POSITION.equals(cmd)) {
-				logger.info("接收到MobilePosition通知");
-				processNotifyMobilePosition(evt);
-			} else {
-				logger.info("接收到消息:" + cmd);
-				response200Ok(evt);
-			}
-		} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * 处理MobilePosition移动位置Notify
-	 * 
-	 * @param evt
-	 */
-	private void processNotifyMobilePosition(RequestEvent evt) {
-		try {
-			// 回复 200 OK
-			Element rootElement = getRootElement(evt);
-			MobilePosition mobilePosition = new MobilePosition();
-			Element deviceIdElement = rootElement.element("DeviceID");
-			String deviceId = deviceIdElement.getTextTrim().toString();
-			Device device = storager.queryVideoDevice(deviceId);
-			if (device != null) {
-				if (!StringUtils.isEmpty(device.getName())) {
-					mobilePosition.setDeviceName(device.getName());
-				}
-			}
-			mobilePosition.setDeviceId(XmlUtil.getText(rootElement, "DeviceID"));
-			mobilePosition.setTime(XmlUtil.getText(rootElement, "Time"));
-			mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
-			mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
-			if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) {
-				mobilePosition.setSpeed(Double.parseDouble(XmlUtil.getText(rootElement, "Speed")));
-			} else {
-				mobilePosition.setSpeed(0.0);
-			}
-			if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Direction"))) {
-				mobilePosition.setDirection(Double.parseDouble(XmlUtil.getText(rootElement, "Direction")));
-			} else {
-				mobilePosition.setDirection(0.0);
-			}
-			if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Altitude"))) {
-				mobilePosition.setAltitude(Double.parseDouble(XmlUtil.getText(rootElement, "Altitude")));
-			} else {
-				mobilePosition.setAltitude(0.0);
-			}
-			mobilePosition.setReportSource("Mobile Position");
-			BaiduPoint bp = new BaiduPoint();
-			bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
-			logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
-			mobilePosition.setGeodeticSystem("BD-09");
-			mobilePosition.setCnLng(bp.getBdLng());
-			mobilePosition.setCnLat(bp.getBdLat());
-			if (!userSetup.getSavePositionHistory()) {
-				storager.clearMobilePositionsByDeviceId(deviceId);
-			}
-			storager.insertMobilePosition(mobilePosition);
-			response200Ok(evt);
-		} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
-			e.printStackTrace();
-		}
-	}
-
-	/***
-	 * 处理alarm设备报警Notify
-	 * 
-	 * @param evt
-	 */
-	private void processNotifyAlarm(RequestEvent evt) {
-		try {
-			Element rootElement = getRootElement(evt);
-			Element deviceIdElement = rootElement.element("DeviceID");
-			String deviceId = deviceIdElement.getText().toString();
-
-			Device device = storager.queryVideoDevice(deviceId);
-			if (device == null) {
-				return;
-			}
-			rootElement = getRootElement(evt, device.getCharset());
-			DeviceAlarm deviceAlarm = new DeviceAlarm();
-			deviceAlarm.setDeviceId(deviceId);
-			deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
-			deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
-			deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
-			if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
-				deviceAlarm.setAlarmDescription("");
-			} else {
-				deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
-			}
-			if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) {
-				deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
-			} else {
-				deviceAlarm.setLongitude(0.00);
-			}
-			if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) {
-				deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
-			} else {
-				deviceAlarm.setLatitude(0.00);
-			}
-
-			if (deviceAlarm.getAlarmMethod().equals("4")) {
-				MobilePosition mobilePosition = new MobilePosition();
-				mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
-				mobilePosition.setTime(deviceAlarm.getAlarmTime());
-				mobilePosition.setLongitude(deviceAlarm.getLongitude());
-				mobilePosition.setLatitude(deviceAlarm.getLatitude());
-				mobilePosition.setReportSource("GPS Alarm");
-				BaiduPoint bp = new BaiduPoint();
-				bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
-				logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
-				mobilePosition.setGeodeticSystem("BD-09");
-				mobilePosition.setCnLng(bp.getBdLng());
-				mobilePosition.setCnLat(bp.getBdLat());
-				if (!userSetup.getSavePositionHistory()) {
-					storager.clearMobilePositionsByDeviceId(deviceId);
-				}
-				storager.insertMobilePosition(mobilePosition);
-			}
-			// TODO: 需要实现存储报警信息、报警分类
-
-			// 回复200 OK
-			response200Ok(evt);
-			if (offLineDetector.isOnline(deviceId)) {
-				publisher.deviceAlarmEventPublish(deviceAlarm);
-			}
-		} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
-			e.printStackTrace();
-		}
-	}
-
-	/***
-	 * 处理catalog设备目录列表Notify
-	 * 
-	 * @param evt
-	 */
-	private void processNotifyCatalogList(RequestEvent evt) {
-		try {
-			Element rootElement = getRootElement(evt);
-			Element deviceIdElement = rootElement.element("DeviceID");
-			String deviceId = deviceIdElement.getText();
-			Device device = storager.queryVideoDevice(deviceId);
-			if (device != null ) {
-				rootElement = getRootElement(evt, device.getCharset());
-			}
-			Element deviceListElement = rootElement.element("DeviceList");
-			if (deviceListElement == null) {
-				return;
-			}
-			Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
-			if (deviceListIterator != null) {
-				if (device == null) {
-					return;
-				}
-				// 遍历DeviceList
-				while (deviceListIterator.hasNext()) {
-					Element itemDevice = deviceListIterator.next();
-					Element channelDeviceElement = itemDevice.element("DeviceID");
-					if (channelDeviceElement == null) {
-						continue;
-					}
-					String channelDeviceId = channelDeviceElement.getTextTrim();
-					Element channdelNameElement = itemDevice.element("Name");
-					String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
-					Element statusElement = itemDevice.element("Status");
-					String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON";
-					DeviceChannel deviceChannel = new DeviceChannel();
-					deviceChannel.setName(channelName);
-					deviceChannel.setChannelId(channelDeviceId);
-					// ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
-					if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) {
-						deviceChannel.setStatus(1);
-					}
-					if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
-						deviceChannel.setStatus(0);
-					}
-
-					deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
-					deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
-					deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
-					deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
-					deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
-					deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
-					if (XmlUtil.getText(itemDevice, "Parental") == null
-							|| XmlUtil.getText(itemDevice, "Parental") == "") {
-						deviceChannel.setParental(0);
-					} else {
-						deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));
-					}
-					deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));
-					if (XmlUtil.getText(itemDevice, "SafetyWay") == null
-							|| XmlUtil.getText(itemDevice, "SafetyWay") == "") {
-						deviceChannel.setSafetyWay(0);
-					} else {
-						deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
-					}
-					if (XmlUtil.getText(itemDevice, "RegisterWay") == null
-							|| XmlUtil.getText(itemDevice, "RegisterWay") == "") {
-						deviceChannel.setRegisterWay(1);
-					} else {
-						deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
-					}
-					deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
-					if (XmlUtil.getText(itemDevice, "Certifiable") == null
-							|| XmlUtil.getText(itemDevice, "Certifiable") == "") {
-						deviceChannel.setCertifiable(0);
-					} else {
-						deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
-					}
-					if (XmlUtil.getText(itemDevice, "ErrCode") == null
-							|| XmlUtil.getText(itemDevice, "ErrCode") == "") {
-						deviceChannel.setErrCode(0);
-					} else {
-						deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
-					}
-					deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
-					deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
-					deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
-					if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") {
-						deviceChannel.setPort(0);
-					} else {
-						deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
-					}
-					deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
-					if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) {
-						deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
-					} else {
-						deviceChannel.setLongitude(0.00);
-					}
-					if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) {
-						deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
-					} else {
-						deviceChannel.setLatitude(0.00);
-					}
-					if (XmlUtil.getText(itemDevice, "PTZType") == null
-							|| XmlUtil.getText(itemDevice, "PTZType") == "") {
-						deviceChannel.setPTZType(0);
-					} else {
-						deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
-					}
-					deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
-					storager.updateChannel(device.getDeviceId(), deviceChannel);
-				}
-
-				// RequestMessage msg = new RequestMessage();
-				// msg.setDeviceId(deviceId);
-				// msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
-				// msg.setData(device);
-				// deferredResultHolder.invokeResult(msg);
-				// 回复200 OK
-				response200Ok(evt);
-				if (offLineDetector.isOnline(deviceId)) {
-					publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
-				}
-			}
-		} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
-			e.printStackTrace();
-		}
-	}
-
-	/***
-	 * 回复200 OK
-	 * 
-	 * @param evt
-	 * @throws SipException
-	 * @throws InvalidArgumentException
-	 * @throws ParseException
-	 */
-	private void response200Ok(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
-		Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
-		ServerTransaction serverTransaction = getServerTransaction(evt);
-		serverTransaction.sendResponse(response);
-		if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
-	}
-	private Element getRootElement(RequestEvent evt) throws DocumentException {
-		return getRootElement(evt, "gb2312");
-	}
-	private Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
-		if (charset == null) charset = "gb2312";
-		Request request = evt.getRequest();
-		SAXReader reader = new SAXReader();
-		reader.setEncoding(charset);
-		Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
-		return xml.getRootElement();
-	}
-
-	public void setCmder(SIPCommander cmder) {
-	}
-
-	public void setStorager(IVideoManagerStorager storager) {
-		this.storager = storager;
-	}
-
-	public void setPublisher(EventPublisher publisher) {
-		this.publisher = publisher;
-	}
-
-	public void setRedis(RedisUtil redis) {
-	}
-
-	public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) {
-	}
-
-	public void setOffLineDetector(DeviceOffLineDetector offLineDetector) {
-		this.offLineDetector = offLineDetector;
-	}
-
-	public IRedisCatchStorage getRedisCatchStorage() {
-		return redisCatchStorage;
-	}
-
-	public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
-		this.redisCatchStorage = redisCatchStorage;
-	}
-}

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

@@ -1,31 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
-
-import javax.sip.RequestEvent;
-
-import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**    
- * @Description:暂不支持的消息请求处理器
- * @author: swwheihei
- * @date:   2020年5月3日 下午5:32:59     
- */
-public class OtherRequestProcessor extends SIPRequestAbstractProcessor {
-
-	private Logger logger = LoggerFactory.getLogger(OtherRequestProcessor.class);
-
-	/**   
-	 * <p>Title: process</p>   
-	 * <p>Description: </p>   
-	 * @param evt
-	 * @param layer
-	 * @param transaction
-	 * @param config    
-	 */  
-	@Override
-	public void process(RequestEvent evt) {
-		logger.info("Unsupported the method: " + evt.getRequest().getMethod());
-	}
-
-}

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

@@ -1,201 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
-
-import java.security.NoSuchAlgorithmException;
-import java.text.ParseException;
-import java.util.Calendar;
-import java.util.Locale;
-
-import javax.sip.InvalidArgumentException;
-import javax.sip.RequestEvent;
-import javax.sip.ServerTransaction;
-import javax.sip.SipException;
-import javax.sip.header.AuthorizationHeader;
-import javax.sip.header.ContactHeader;
-import javax.sip.header.ExpiresHeader;
-import javax.sip.header.FromHeader;
-import javax.sip.header.ViaHeader;
-import javax.sip.message.Request;
-import javax.sip.message.Response;
-
-import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
-import gov.nist.javax.sip.RequestEventExt;
-import gov.nist.javax.sip.header.SIPDateHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-
-import com.genersoft.iot.vmp.common.VideoManagerConstants;
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
-import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
-import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-
-import gov.nist.javax.sip.address.AddressImpl;
-import gov.nist.javax.sip.address.SipUri;
-import gov.nist.javax.sip.header.Expires;
-
-/**    
- * @Description:收到注册请求 处理 
- * @author: swwheihei
- * @date:   2020年5月3日 下午4:47:25     
- */
-public class RegisterRequestProcessor extends SIPRequestAbstractProcessor {
-
-	private Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class);
-
-	private SipConfig sipConfig;
-	
-	private RegisterLogicHandler handler;
-	
-	private IVideoManagerStorager storager;
-	
-	private EventPublisher publisher;
-
-	/**
-	 * 收到注册请求 处理
- 	 * @param evt
-	 */
-	@Override
-	public void process(RequestEvent evt) {
-		try {
-			RequestEventExt evtExt = (RequestEventExt)evt;
-			String requestAddress = evtExt.getRemoteIpAddress() + ":" + evtExt.getRemotePort();
-			logger.info("[{}] 收到注册请求,开始处理", requestAddress);
-			Request request = evt.getRequest();
-
-			Response response = null; 
-			boolean passwordCorrect = false;
-			// 注册标志  0:未携带授权头或者密码错误  1:注册成功   2:注销成功
-			int registerFlag = 0;
-			FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);
-			AddressImpl address = (AddressImpl) fromHeader.getAddress();
-			SipUri uri = (SipUri) address.getURI();
-			String deviceId = uri.getUser();
-			Device device = storager.queryVideoDevice(deviceId);
-			AuthorizationHeader authorhead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); 
-			// 校验密码是否正确
-			if (authorhead != null) {
-				passwordCorrect = new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request,
-						sipConfig.getPassword());
-			}
-			if (StringUtils.isEmpty(sipConfig.getPassword())){
-				passwordCorrect = true;
-			}
-
-			// 未携带授权头或者密码错误 回复401
-			if (authorhead == null ) {
-
-				logger.info("[{}] 未携带授权头 回复401", requestAddress);
-				response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
-				new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain());
-			}else {
-				if (!passwordCorrect){
-					// 注册失败
-					response = getMessageFactory().createResponse(Response.FORBIDDEN, request);
-					response.setReasonPhrase("wrong password");
-					logger.info("[{}] 密码/SIP服务器ID错误, 回复403", requestAddress);
-				}else {
-					// 携带授权头并且密码正确
-					response = getMessageFactory().createResponse(Response.OK, request);
-					// 添加date头
-					SIPDateHeader dateHeader = new SIPDateHeader();
-					// 使用自己修改的
-					WvpSipDate wvpSipDate = new WvpSipDate(Calendar.getInstance(Locale.ENGLISH).getTimeInMillis());
-					dateHeader.setDate(wvpSipDate);
-					response.addHeader(dateHeader);
-
-					ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME);
-					if (expiresHeader == null) {
-						response = getMessageFactory().createResponse(Response.BAD_REQUEST, request);
-						ServerTransaction serverTransaction = getServerTransaction(evt);
-						serverTransaction.sendResponse(response);
-						if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
-						return;
-					}
-					// 添加Contact头
-					response.addHeader(request.getHeader(ContactHeader.NAME));
-					// 添加Expires头
-					response.addHeader(request.getExpires());
-
-					// 获取到通信地址等信息
-					ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
-					String received = viaHeader.getReceived();
-					int rPort = viaHeader.getRPort();
-					// 解析本地地址替代
-					if (StringUtils.isEmpty(received) || rPort == -1) {
-						received = viaHeader.getHost();
-						rPort = viaHeader.getPort();
-					}
-					//
-
-					if (device == null) {
-						device = new Device();
-						device.setStreamMode("UDP");
-						device.setCharset("gb2312");
-						device.setDeviceId(deviceId);
-						device.setFirsRegister(true);
-					}
-					device.setIp(received);
-					device.setPort(rPort);
-					device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
-					// 注销成功
-					if (expiresHeader.getExpires() == 0) {
-						registerFlag = 2;
-					}
-					// 注册成功
-					else {
-						device.setExpires(expiresHeader.getExpires());
-						registerFlag = 1;
-						// 判断TCP还是UDP
-						boolean isTcp = false;
-						ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
-						String transport = reqViaHeader.getTransport();
-						if (transport.equals("TCP")) {
-							isTcp = true;
-						}
-						device.setTransport(isTcp ? "TCP" : "UDP");
-					}
-				}
-			}
-
-			ServerTransaction serverTransaction = getServerTransaction(evt);
-			serverTransaction.sendResponse(response);
-			if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
-			// 注册成功
-			// 保存到redis
-			// 下发catelog查询目录
-			if (registerFlag == 1 ) {
-				logger.info("[{}] 注册成功! deviceId:" + device.getDeviceId(), requestAddress);
-				publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER);
-				// 重新注册更新设备和通道,以免设备替换或更新后信息无法更新
-				handler.onRegister(device);
-			} else if (registerFlag == 2) {
-				logger.info("[{}] 注销成功! deviceId:" + device.getDeviceId(), requestAddress);
-				publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER);
-			}
-		} catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) {
-			e.printStackTrace();
-		}
-		
-	}
-	
-	public void setSipConfig(SipConfig sipConfig) {
-		this.sipConfig = sipConfig;
-	}
-
-	public void setHandler(RegisterLogicHandler handler) {
-		this.handler = handler;
-	}
-
-	public void setVideoManagerStorager(IVideoManagerStorager storager) {
-		this.storager = storager;
-	}
-
-	public void setPublisher(EventPublisher publisher) {
-		this.publisher = publisher;
-	}
-
-}

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

@@ -1,62 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
-
-import java.text.ParseException;
-
-import javax.sip.InvalidArgumentException;
-import javax.sip.RequestEvent;
-import javax.sip.ServerTransaction;
-import javax.sip.SipException;
-import javax.sip.header.ExpiresHeader;
-import javax.sip.message.Request;
-import javax.sip.message.Response;
-
-import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**    
- * @Description:SUBSCRIBE请求处理器
- * @author: swwheihei
- * @date:   2020年5月3日 下午5:31:20     
- */
-public class SubscribeRequestProcessor extends SIPRequestAbstractProcessor {
-
-	private Logger logger = LoggerFactory.getLogger(SubscribeRequestProcessor.class);
-
-	/**   
-	 * 处理SUBSCRIBE请求  
-	 * 
-	 * @param evt
-	 */
-	@Override
-	public void process(RequestEvent evt) {
-		Request request = evt.getRequest();
-
-		try {
-			Response response = null;
-			response = getMessageFactory().createResponse(200, request);
-			if (response != null) {
-				ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30);
-				response.setExpires(expireHeader);
-			}
-			logger.info("response : " + response.toString());
-			ServerTransaction transaction = getServerTransaction(evt);
-			if (transaction != null) {
-				transaction.sendResponse(response);
-				transaction.getDialog().delete();
-				transaction.terminate();
-			} else {
-				logger.info("processRequest serverTransactionId is null.");
-			}
-
-		} catch (ParseException e) {
-			e.printStackTrace();
-		} catch (SipException e) {
-			e.printStackTrace();
-		} catch (InvalidArgumentException e) {
-			e.printStackTrace();
-		}
-		
-	}
-
-}

+ 0 - 19
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java

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

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

@@ -1,31 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
-
-import javax.sip.ResponseEvent;
-
-import org.springframework.stereotype.Component;
-
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.SipLayer;
-import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
-
-/**    
- * @Description: BYE请求响应器
- * @author: swwheihei
- * @date:   2020年5月3日 下午5:32:05     
- */
-@Component
-public class ByeResponseProcessor implements ISIPResponseProcessor {
-
-	/**   
-	 * 处理BYE响应
-	 * 
-	 * @param evt
-	 * @param layer
-	 * @param config    
-	 */  
-	@Override
-	public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
-		// TODO Auto-generated method stub
-	}
-
-}

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

@@ -1,33 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
-
-import javax.sip.ResponseEvent;
-
-import org.springframework.stereotype.Component;
-
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.SipLayer;
-import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
-
-/**    
- * @Description:CANCEL响应处理器
- * @author: swwheihei
- * @date:   2020年5月3日 下午5:32:23     
- */
-@Component
-public class CancelResponseProcessor implements ISIPResponseProcessor {
-
-	/**   
-	 * 处理CANCEL响应
-	 *  
-	 * @param evt
-	 * @param layer
-	 * @param transaction
-	 * @param config    
-	 */  
-	@Override
-	public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
-		// TODO Auto-generated method stub
-		
-	}
-
-}

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

@@ -1,75 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
-
-import java.text.ParseException;
-
-import javax.sip.*;
-import javax.sip.address.SipURI;
-import javax.sip.header.CSeqHeader;
-import javax.sip.message.Request;
-import javax.sip.message.Response;
-
-import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
-import gov.nist.javax.sip.ResponseEventExt;
-import gov.nist.javax.sip.stack.SIPDialog;
-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.SipLayer;
-import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
-
-
-/**
- * @Description:处理INVITE响应
- * @author: swwheihei
- * @date: 2020年5月3日 下午4:43:52
- */
-@Component
-public class InviteResponseProcessor implements ISIPResponseProcessor {
-
-	 private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class);
-
-	@Autowired
-	private VideoStreamSessionManager streamSession;
-
-	/**
-	 * 处理invite响应
-	 * 
-	 * @param evt 响应消息
-	 * @throws ParseException
-	 */
-	@Override
-	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) {
-			}
-			// 成功响应
-			// 下发ack
-			if (statusCode == Response.OK) {
-				ResponseEventExt event = (ResponseEventExt)evt;
-				SIPDialog dialog = (SIPDialog)evt.getDialog();
-				CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
-				Request reqAck = dialog.createAck(cseq.getSeqNumber());
-				SipURI requestURI = (SipURI) reqAck.getRequestURI();
-				requestURI.setHost(event.getRemoteIpAddress());
-				requestURI.setPort(event.getRemotePort());
-				reqAck.setRequestURI(requestURI);
-				logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack");
-				SipURI sipURI = (SipURI)dialog.getRemoteParty().getURI();
-				String deviceId = requestURI.getUser();
-				String channelId = sipURI.getUser();
-
-				dialog.sendAck(reqAck);
-
-			}
-		} catch (InvalidArgumentException | SipException e) {
-			e.printStackTrace();
-		}
-	}
-
-}

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

@@ -1,32 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
-
-import javax.sip.ResponseEvent;
-
-import org.springframework.stereotype.Component;
-
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.SipLayer;
-import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
-
-/**    
- * @Description:暂不支持的消息响应处理器
- * @author: swwheihei
- * @date:   2020年5月3日 下午5:32:59     
- */
-@Component
-public class OtherResponseProcessor implements ISIPResponseProcessor {
-
-	/**   
-	 * <p>Title: process</p>   
-	 * <p>Description: </p>   
-	 * @param evt
-	 * @param layer
-	 * @param config    
-	 */  
-	@Override
-	public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
-		// TODO Auto-generated method stub
-		
-	}
-
-}

+ 0 - 100
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java

@@ -1,100 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
-
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.SipLayer;
-import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
-import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
-import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import javax.sip.ResponseEvent;
-import javax.sip.header.CallIdHeader;
-import javax.sip.header.WWWAuthenticateHeader;
-import javax.sip.message.Response;
-
-/**    
- * @Description:Register响应处理器
- * @author: swwheihei
- * @date:   2020年5月3日 下午5:32:23     
- */
-@Component
-public class RegisterResponseProcessor implements ISIPResponseProcessor {
-
-	private Logger logger = LoggerFactory.getLogger(RegisterResponseProcessor.class);
-
-	@Autowired
-	private ISIPCommanderForPlatform sipCommanderForPlatform;
-
-	@Autowired
-	private IVideoManagerStorager storager;
-
-	@Autowired
-	private IRedisCatchStorage redisCatchStorage;
-
-	public RegisterResponseProcessor() {
-	}
-
-	/**
-	 * 处理Register响应
-	 *
- 	 * @param evt
-	 * @param layer
-	 * @param config
-	 */
-	@Override
-	public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
-		Response response = evt.getResponse();
-		CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
-		String callId = callIdHeader.getCallId();
-
-		String platformGBId = redisCatchStorage.queryPlatformRegisterInfo(callId);
-		if (platformGBId == null) {
-			logger.info(String.format("未找到callId: %s 的注册/注销平台id", callId ));
-			return;
-		}
-
-		ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformGBId);
-		if (parentPlatformCatch == null) {
-			logger.warn(String.format("收到 %s 的注册/注销%S请求, 但是平台缓存信息未查询到!!!", platformGBId, response.getStatusCode()));
-			return;
-		}
-		String action = parentPlatformCatch.getParentPlatform().getExpires().equals("0") ? "注销" : "注册";
-		logger.info(String.format("收到 %s %s的%S响应", platformGBId, action, response.getStatusCode() ));
-		ParentPlatform parentPlatform = parentPlatformCatch.getParentPlatform();
-		if (parentPlatform == null) {
-			logger.warn(String.format("收到 %s %s的%S请求, 但是平台信息未查询到!!!", platformGBId, action, response.getStatusCode()));
-			return;
-		}
-
-		if (response.getStatusCode() == 401) {
-			WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
-			sipCommanderForPlatform.register(parentPlatform, callId, www, null, null);
-		}else if (response.getStatusCode() == 200){
-			// 注册/注销成功
-			logger.info(String.format("%s %s成功", platformGBId, action));
-			redisCatchStorage.delPlatformRegisterInfo(callId);
-			parentPlatform.setStatus("注册".equals(action));
-			// 取回Expires设置,避免注销过程中被置为0
-			ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId);
-			String expires = parentPlatformTmp.getExpires();
-			parentPlatform.setExpires(expires);
-			parentPlatform.setId(parentPlatformTmp.getId());
-			storager.updateParentPlatformStatus(platformGBId, "注册".equals(action));
-
-			redisCatchStorage.updatePlatformRegister(parentPlatform);
-
-			redisCatchStorage.updatePlatformKeepalive(parentPlatform);
-
-			parentPlatformCatch.setParentPlatform(parentPlatform);
-
-			redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
-		}
-	}
-
-}

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

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

+ 7 - 2
src/main/java/com/genersoft/iot/vmp/utils/SipUtils.java

@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.utils;
+package com.genersoft.iot.vmp.gb28181.utils;
 
 import gov.nist.javax.sip.address.AddressImpl;
 import gov.nist.javax.sip.address.SipUri;
@@ -9,15 +9,20 @@ import javax.sip.message.Request;
 /**
  * @author panlinlin
  * @version 1.0.0
- * @Description JAIN SIP的工具类
+ * @description JAIN SIP的工具类
  * @createTime 2021年09月27日 15:12:00
  */
 public class SipUtils {
 
     public static String getUserIdFromFromHeader(Request request) {
         FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
+        return getUserIdFromFromHeader(fromHeader);
+    }
+
+    public static String getUserIdFromFromHeader(FromHeader fromHeader) {
         AddressImpl address = (AddressImpl)fromHeader.getAddress();
         SipUri uri = (SipUri) address.getURI();
         return uri.getUser();
     }
+
 }

+ 25 - 8
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java

@@ -1,15 +1,7 @@
 package com.genersoft.iot.vmp.gb28181.utils;
 
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-
 import org.dom4j.Attribute;
 import org.dom4j.Document;
 import org.dom4j.DocumentException;
@@ -19,6 +11,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.util.StringUtils;
 
+import javax.sip.RequestEvent;
+import javax.sip.message.Request;
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.util.*;
+
 /**
  * 基于dom4j的工具包
  * 
@@ -161,4 +159,23 @@ public class XmlUtil {
             }
         }
     }
+    public static  Element getRootElement(RequestEvent evt) throws DocumentException {
+
+        return getRootElement(evt, "gb2312");
+    }
+
+    public static Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
+        Request request = evt.getRequest();
+        return getRootElement(request.getRawContent(), charset);
+    }
+
+    public static Element getRootElement(byte[] content, String charset) throws DocumentException {
+        if (charset == null) {
+            charset = "gb2312";
+        }
+        SAXReader reader = new SAXReader();
+        reader.setEncoding(charset);
+        Document xml = reader.read(new ByteArrayInputStream(content));
+        return xml.getRootElement();
+    }
 }

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

@@ -31,7 +31,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 import javax.servlet.http.HttpServletRequest;
 
 /**    
- * @Description:针对 ZLMediaServer的hook事件监听
+ * @description:针对 ZLMediaServer的hook事件监听
  * @author: swwheihei
  * @date:   2020年5月8日 上午10:46:48     
  */

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java

@@ -8,7 +8,7 @@ import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * @Description:针对 ZLMediaServer的hook事件订阅
+ * @description:针对 ZLMediaServer的hook事件订阅
  * @author: pan
  * @date:   2020年12月2日 21:17:32
  */

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

@@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
 import com.github.pagehelper.PageInfo;
 
 /**    
- * @Description:视频设备数据存储接口
+ * @description:视频设备数据存储接口
  * @author: swwheihei
  * @date:   2020年5月6日 下午2:14:31     
  */

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

@@ -25,7 +25,7 @@ import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.annotation.Transactional;
 
 /**    
- * @Description:视频设备数据存储-jdbc实现
+ * @description:视频设备数据存储-jdbc实现
  * @author: swwheihei
  * @date:   2020年5月6日 下午2:31:42
  */

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

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

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

@@ -9,7 +9,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 
 /**    
- * @Description:使用fastjson实现redis的序列化   
+ * @description:使用fastjson实现redis的序列化   
  * @author: swwheihei
  * @date:   2020年5月6日 下午8:40:11     
  */

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

@@ -8,7 +8,7 @@ import redis.clients.jedis.JedisPool;
 import java.util.Set;
 
 /**
- * @Description:Jedis工具类
+ * @description:Jedis工具类
  * @author: wangshaopeng@sunnybs.com
  * @date: 2021年03月22日 下午8:27:29
  */

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

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

+ 26 - 10
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java

@@ -1,11 +1,21 @@
 package com.genersoft.iot.vmp.vmanager.gb28181.device;
 
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
+import com.genersoft.iot.vmp.service.IDeviceService;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
 import com.github.pagehelper.PageInfo;
-import io.swagger.annotations.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -15,15 +25,6 @@ import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.context.request.async.DeferredResult;
 
-import com.alibaba.fastjson.JSONObject;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
-import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
-import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
-
-import javax.sip.message.Response;
-import java.io.UnsupportedEncodingException;
 import java.util.UUID;
 
 @Api(tags = "国标设备查询", value = "国标设备查询")
@@ -50,6 +51,9 @@ public class DeviceQuery {
 	@Autowired
 	private DeviceOffLineDetector offLineDetector;
 
+	@Autowired
+	private IDeviceService deviceService;
+
 	/**
 	 * 使用ID查询国标设备
 	 * @param deviceId 国标ID
@@ -301,6 +305,18 @@ public class DeviceQuery {
 			if (!StringUtils.isEmpty(device.getName())) deviceInStore.setName(device.getName());
 			if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset());
 			if (!StringUtils.isEmpty(device.getMediaServerId())) deviceInStore.setMediaServerId(device.getMediaServerId());
+
+			if (deviceInStore.getSubscribeCycleForCatalog() <=0 && device.getSubscribeCycleForCatalog() > 0) {
+				deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
+				// 开启订阅
+				deviceService.addCatalogSubscribe(deviceInStore);
+			}
+			if (deviceInStore.getSubscribeCycleForCatalog() > 0 && device.getSubscribeCycleForCatalog() <= 0) {
+				deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
+				// 取消订阅
+				deviceService.removeCatalogSubscribe(deviceInStore);
+			}
+
 			storager.updateDevice(deviceInStore);
 			cmder.deviceInfoQuery(deviceInStore);
 		}