Selaa lähdekoodia

Merge branch 'wvp-28181-2.0'

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
648540858 3 vuotta sitten
vanhempi
commit
ab74d1cff9
42 muutettua tiedostoa jossa 865 lisäystä ja 743 poistoa
  1. 4 2
      pom.xml
  2. 340 444
      sql/mysql.sql
  3. 13 0
      src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
  4. 6 0
      src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
  5. 5 10
      src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
  6. 5 3
      src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
  7. 3 0
      src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
  8. 2 2
      src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
  9. 17 52
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
  10. 31 18
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
  11. 67 91
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
  12. 41 28
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
  13. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
  14. 19 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
  15. 20 0
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
  16. 6 8
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
  17. 12 6
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/impl/TimeoutProcessorImpl.java
  18. 0 22
      src/main/java/com/genersoft/iot/vmp/gb28181/utils/HeaderUtils.java
  19. 32 0
      src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
  20. 9 6
      src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
  21. 1 0
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
  22. 2 0
      src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
  23. 3 1
      src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
  24. 2 0
      src/main/java/com/genersoft/iot/vmp/service/bean/MessageForPushChannel.java
  25. 71 0
      src/main/java/com/genersoft/iot/vmp/service/bean/MessageForPushChannelResponse.java
  26. 1 1
      src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
  27. 43 1
      src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
  28. 11 9
      src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
  29. 8 6
      src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
  30. 62 0
      src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamResponseListener.java
  31. 2 3
      src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamListMsgListener.java
  32. 0 1
      src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
  33. 2 2
      src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
  34. 6 0
      src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
  35. 1 1
      src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
  36. 1 2
      src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
  37. 15 0
      src/main/java/com/genersoft/iot/vmp/utils/GitUtil.java
  38. 0 6
      src/main/resources/all-application.yml
  39. 0 6
      src/main/resources/application-dev.yml
  40. 0 7
      src/main/resources/application-docker.yml
  41. 0 2
      src/main/resources/banner.txt
  42. 1 0
      web_src/src/components/channelList.vue

+ 4 - 2
pom.xml

@@ -263,14 +263,16 @@
 				</configuration>
 			</plugin>
 
-	<!--		<plugin>
+			<plugin>
 				<groupId>pl.project13.maven</groupId>
 				<artifactId>git-commit-id-plugin</artifactId>
 				<version>3.0.1</version>
 				<configuration>
 					<offline>true</offline>
+					<failOnNoGitDirectory>false</failOnNoGitDirectory>
+					<dateFormat>yyyyMMdd</dateFormat>
 				</configuration>
-			</plugin>-->
+			</plugin>
 
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 340 - 444
sql/mysql.sql


+ 13 - 0
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java

@@ -3,6 +3,12 @@ package com.genersoft.iot.vmp;
 import java.util.logging.LogManager;
 
 import com.genersoft.iot.vmp.conf.druid.EnableDruidSupport;
+import com.genersoft.iot.vmp.storager.impl.RedisCatchStorageImpl;
+import com.genersoft.iot.vmp.utils.GitUtil;
+import com.genersoft.iot.vmp.utils.SpringBeanFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.web.servlet.ServletComponentScan;
@@ -17,11 +23,18 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @EnableScheduling
 @EnableDruidSupport
 public class VManageBootstrap extends LogManager {
+
+	private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class);
+
 	private static String[] args;
 	private static ConfigurableApplicationContext context;
 	public static void main(String[] args) {
 		VManageBootstrap.args = args;
 		VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args);
+		GitUtil gitUtil1 = SpringBeanFactory.getBean("gitUtil");
+		logger.info("构建版本: {}", gitUtil1.getBuildVersion());
+		logger.info("构建时间: {}", gitUtil1.getBuildDate());
+		logger.info("GIT最后提交时间: {}", gitUtil1.getCommitTime());
 	}
 	// 项目重启
 	public static void restart() {

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

@@ -99,6 +99,12 @@ public class VideoManagerConstants {
 	 */
 	public static final String VM_MSG_STREAM_PUSH_REQUESTED = "VM_MSG_STREAM_PUSH_REQUESTED";
 
+
+	/**
+	 * redis 消息通知平台通知设备推流结果
+	 */
+	public static final String VM_MSG_STREAM_PUSH_RESPONSE = "VM_MSG_STREAM_PUSH_RESPONSE";
+
 	/**
 	 * redis 消息请求所有的在线通道
 	 */

+ 5 - 10
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java

@@ -46,17 +46,12 @@ public class SipPlatformRunner implements CommandLineRunner {
             parentPlatformCatch.setParentPlatform(parentPlatform);
             parentPlatformCatch.setId(parentPlatform.getServerGBId());
             redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
-            if (parentPlatform.isStatus()) {
-                // 设置所有平台离线
-                platformService.offline(parentPlatform);
-                // 取消订阅
-                sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{
-                    platformService.login(parentPlatform);
-                });
-            }else {
+            // 设置所有平台离线
+            platformService.offline(parentPlatform);
+            // 取消订阅
+            sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{
                 platformService.login(parentPlatform);
-            }
-
+            });
         }
     }
 }

+ 5 - 3
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java

@@ -12,7 +12,6 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.listener.PatternTopic;
 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
-import org.springframework.data.redis.serializer.RedisSerializer;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
 
 import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
@@ -43,7 +42,10 @@ public class RedisConfig extends CachingConfigurerSupport {
 	private RedisPushStreamStatusMsgListener redisPushStreamStatusMsgListener;
 
 	@Autowired
-	private RedisPushStreamListMsgListener redisPushStreamListMsgListener;
+	private RedisPushStreamStatusListMsgListener redisPushStreamListMsgListener;
+
+	@Autowired
+	private RedisPushStreamResponseListener redisPushStreamResponseListener;
 
 	@Bean
 	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
@@ -81,7 +83,7 @@ public class RedisConfig extends CachingConfigurerSupport {
 		container.addMessageListener(redisGbPlayMsgListener, new PatternTopic(RedisGbPlayMsgListener.WVP_PUSH_STREAM_KEY));
 		container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE));
 		container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE));
+		container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE));
         return container;
     }
-
 }

+ 3 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java

@@ -49,6 +49,7 @@ public class SipLayer{
 		 * gov/nist/javax/sip/SipStackImpl.class
 		 * sip消息的解析在 gov.nist.javax.sip.stack.UDPMessageChannel的processIncomingDataPacket方法
 		 */
+
 //		 * gov/nist/javax/sip/SipStackImpl.class
 		if (logger.isDebugEnabled()) {
 			properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
@@ -63,6 +64,8 @@ public class SipLayer{
 		properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal");
 		// 处理由该服务器处理的基于底层TCP的保持生存超时
 		properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
+		// 获取实际内容长度,不使用header中的长度信息
+		properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
 
 		/**
 		 * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE

+ 2 - 2
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java

@@ -132,7 +132,7 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
                     if (event.getGbStreams() != null && event.getGbStreams().size() > 0){
                         for (GbStream gbStream : event.getGbStreams()) {
                             deviceChannelList.add(
-                                    gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), parentPlatform));
+                                    gbStreamService.getDeviceChannelListByStreamWithStatus(gbStream, gbStream.getCatalogId(), parentPlatform));
                         }
                     }
                     if (deviceChannelList.size() > 0) {
@@ -154,7 +154,7 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
                                 deviceChannelList.add(deviceChannel);
                                 GbStream gbStream = storager.queryStreamInParentPlatform(platform.getServerGBId(), gbId);
                                 if(gbStream != null){
-                                    DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStream(gbStream, gbStream.getCatalogId(), platform);
+                                    DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStreamWithStatus(gbStream, gbStream.getCatalogId(), platform);
                                     deviceChannelList.add(deviceChannelByStream);
                                 }
                                 sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), platform, deviceChannelList, subscribeInfo, null);

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

@@ -2,9 +2,9 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd;
 
 import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
-import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
-import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils;
+import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.utils.GitUtil;
 import gov.nist.javax.sip.message.MessageFactoryImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -36,45 +36,10 @@ public class SIPRequestHeaderPlarformProvider {
 	private SipFactory sipFactory;
 
 	@Autowired
-	private IRedisCatchStorage redisCatchStorage;
-
-
-	public Request createKeetpaliveMessageRequest(ParentPlatform parentPlatform, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
-		Request request = null;
-		// sipuri
-		SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
-		// via
-		ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
-		ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(),
-				parentPlatform.getTransport(), viaTag);
-		viaHeader.setRPort();
-		viaHeaders.add(viaHeader);
-		// from
-		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(),
-				sipConfig.getIp() + ":" + sipConfig.getPort());
-		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
-		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
-		// to
-		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort() );
-		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
-		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
-
-
-		// Forwards
-		MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
-		// ceq
-		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE);
-
-		request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
-				toHeader, viaHeaders, maxForwards);
-
-		List<String> agentParam = new ArrayList<>();
-
-		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
-		request.setContent(content, contentTypeHeader);
-		return request;
-	}
+	private GitUtil gitUtil;
 
+	@Autowired
+	private IRedisCatchStorage redisCatchStorage;
 
 	public Request createRegisterRequest(@NotNull ParentPlatform platform, long CSeq, String fromTag, String viaTag, CallIdHeader callIdHeader, boolean isRegister) throws ParseException, InvalidArgumentException, PeerUnavailableException {
 		Request request = null;
@@ -88,16 +53,14 @@ public class SIPRequestHeaderPlarformProvider {
 		viaHeader.setRPort();
 		viaHeaders.add(viaHeader);
 		//from
-		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),sipAddress);
+		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(), sipConfig.getDomain());
 		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
 		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
 		//to
-		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(),sipAddress);
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(platform.getDeviceGBId(), sipConfig.getDomain());
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
 		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,null);
 
-
-
 		//Forwards
 		MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
 
@@ -113,8 +76,7 @@ public class SIPRequestHeaderPlarformProvider {
 		ExpiresHeader expires = sipFactory.createHeaderFactory().createExpiresHeader(isRegister ? platform.getExpires() : 0);
 		request.addHeader(expires);
 
-		UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory);
-		request.addHeader(userAgentHeader);
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
 
 		return request;
 	}
@@ -193,23 +155,24 @@ public class SIPRequestHeaderPlarformProvider {
 	}
 
 
-	public Request createMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
+	public Request createMessageRequest(ParentPlatform parentPlatform, String content, String fromTag, String viaTag, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
 		Request request = null;
+		String serverAddress = parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort();
 		// sipuri
-		SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort());
+		SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress);
 		// via
 		ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
 		ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), Integer.parseInt(parentPlatform.getDevicePort()),
-				parentPlatform.getTransport(), null);
+				parentPlatform.getTransport(), viaTag);
 		viaHeader.setRPort();
 		viaHeaders.add(viaHeader);
 		// from
-		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(),
-				parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort());
+		// SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), parentPlatform.getDeviceIp() + ":" + parentPlatform.getDeviceIp());
+		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain());
 		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
 		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
 		// to
-		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerGBDomain());
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), serverAddress);
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
 		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, null);
 
@@ -223,6 +186,8 @@ public class SIPRequestHeaderPlarformProvider {
 		request = messageFactory.createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
 				toHeader, viaHeaders, maxForwards);
 
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
+
 		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
 		request.setContent(content, contentTypeHeader);
 		return request;

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

@@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd;
 
 import java.text.ParseException;
 import java.util.ArrayList;
-import java.util.List;
 
 import javax.sip.*;
 import javax.sip.address.Address;
@@ -12,8 +11,9 @@ import javax.sip.message.Request;
 
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
-import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils;
+import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.utils.GitUtil;
 import gov.nist.javax.sip.SipProviderImpl;
 import gov.nist.javax.sip.SipStackImpl;
 import gov.nist.javax.sip.stack.SIPDialog;
@@ -38,6 +38,9 @@ public class SIPRequestHeaderProvider {
 	@Autowired
 	private SipFactory sipFactory;
 
+	@Autowired
+	private GitUtil gitUtil;
+
 	@Autowired
 	private IRedisCatchStorage redisCatchStorage;
 
@@ -62,22 +65,24 @@ public class SIPRequestHeaderProvider {
 		viaHeader.setRPort();
 		viaHeaders.add(viaHeader);
 		// from
-		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(),
-				sipConfig.getIp() + ":" + sipConfig.getPort());
+		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
 		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
 		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
 		// to
-		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), sipConfig.getDomain());
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
 		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
 
 		// Forwards
 		MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
 		// ceq
-		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE);
+		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE);
 
 		request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
 				toHeader, viaHeaders, maxForwards);
+
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
+
 		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
 		request.setContent(content, contentTypeHeader);
 		return request;
@@ -94,11 +99,11 @@ public class SIPRequestHeaderProvider {
 		viaHeaders.add(viaHeader);
 
 		//from
-		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain());
+		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
 		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
 		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack
 		//to
-		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId,sipConfig.getDomain()); 
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId, device.getHostAddress());
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
 		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,null);
 		
@@ -108,7 +113,9 @@ public class SIPRequestHeaderProvider {
 		//ceq
 		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INVITE);
 		request = sipFactory.createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
-		
+
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
+
 		Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
 		// Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), device.getHost().getIp()+":"+device.getHost().getPort()));
 		request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
@@ -130,11 +137,11 @@ public class SIPRequestHeaderProvider {
 		viaHeader.setRPort();
 		viaHeaders.add(viaHeader);
 		//from
-		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain());
+		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
 		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
 		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack
 		//to
-		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId, sipConfig.getDomain());
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId, device.getHostAddress());
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
 		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,null);
 		
@@ -148,6 +155,9 @@ public class SIPRequestHeaderProvider {
 		Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
 		// Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), device.getHost().getIp()+":"+device.getHost().getPort()));
 		request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
+
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
+
 		// Subject
 		SubjectHeader subjectHeader = sipFactory.createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0));
 		request.addHeader(subjectHeader);
@@ -170,7 +180,7 @@ public class SIPRequestHeaderProvider {
 		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
 		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack
 		//to
-		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId,sipConfig.getDomain());
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId,device.getHostAddress());
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
 		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,toTag);
 
@@ -178,10 +188,12 @@ public class SIPRequestHeaderProvider {
 		MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
 
 		//ceq
-		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.BYE);
+		CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE);
 		CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(callId);
 		request = sipFactory.createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
 
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
+
 		Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
 
 		return request;
@@ -198,12 +210,11 @@ public class SIPRequestHeaderProvider {
 		viaHeader.setRPort();
 		viaHeaders.add(viaHeader);
 		// from
-		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(),
-				sipConfig.getIp() + ":" + sipConfig.getPort());
+		SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
 		Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
 		FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
 		// to
-		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), sipConfig.getDomain());
+		SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
 		Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
 		ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, toTag);
 
@@ -233,6 +244,9 @@ public class SIPRequestHeaderProvider {
 
 		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
 		request.setContent(content, contentTypeHeader);
+
+		request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
+
 		return request;
 	}
 
@@ -267,8 +281,7 @@ public class SIPRequestHeaderProvider {
 		Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory()
 				.createSipURI(sipConfig.getId(), sipConfig.getIp() + ":" + sipConfig.getPort()));
 		infoRequest.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
-		UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory);
-		infoRequest.addHeader(userAgentHeader);
+		infoRequest.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
 
 		ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application",
 				"MANSRTSP");

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

@@ -10,7 +10,7 @@ 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.HeaderUtils;
+import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
 import com.genersoft.iot.vmp.utils.DateUtil;
@@ -21,6 +21,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
+import com.genersoft.iot.vmp.utils.GitUtil;
 import gov.nist.javax.sip.SipProviderImpl;
 import gov.nist.javax.sip.SipStackImpl;
 import gov.nist.javax.sip.message.MessageFactoryImpl;
@@ -62,6 +63,9 @@ public class SIPCommander implements ISIPCommander {
 	@Autowired
 	private SipFactory sipFactory;
 
+	@Autowired
+	private GitUtil gitUtil;
+
 	@Autowired
 	@Qualifier(value="tcpSipProvider")
 	private SipProviderImpl tcpSipProvider;
@@ -246,13 +250,11 @@ public class SIPCommander implements ISIPCommander {
 			ptzXml.append("<ControlPriority>5</ControlPriority>\r\n");
 			ptzXml.append("</Info>\r\n");
 			ptzXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
 			
 			transmitRequest(device, request);
 			return true;
@@ -289,13 +291,12 @@ public class SIPCommander implements ISIPCommander {
 			ptzXml.append("<ControlPriority>5</ControlPriority>\r\n");
 			ptzXml.append("</Info>\r\n");
 			ptzXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
+
 
 			CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -325,13 +326,12 @@ public class SIPCommander implements ISIPCommander {
 			ptzXml.append("<ControlPriority>5</ControlPriority>\r\n");
 			ptzXml.append("</Info>\r\n");
 			ptzXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
+
 
 			CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent, okEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -423,12 +423,10 @@ public class SIPCommander implements ISIPCommander {
 			// f字段:f= v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率
 //			content.append("f=v/2/5/25/1/4000a/1/8/1" + "\r\n"); // 未发现支持此特性的设备
 
-			String tm = Long.toString(System.currentTimeMillis());
-
 			CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader);
+			Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(), callIdHeader);
 
 			transmitRequest(device, request, (e -> {
 				streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
@@ -521,8 +519,6 @@ public class SIPCommander implements ISIPCommander {
 			}
 
 	        content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
-	        
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
@@ -535,7 +531,7 @@ public class SIPCommander implements ISIPCommander {
 						}
 						subscribe.removeSubscribe(hookSubscribe);
 					});
-	        Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
+	        Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader, ssrcInfo.getSsrc());
 
 	        transmitRequest(device, request, errorEvent, event -> {
 				ResponseEvent responseEvent = (ResponseEvent) event.event;
@@ -627,8 +623,6 @@ public class SIPCommander implements ISIPCommander {
 			content.append("a=downloadspeed:" + downloadSpeed + "\r\n");
 
 	        content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
-	        
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
@@ -651,7 +645,7 @@ public class SIPCommander implements ISIPCommander {
 								});
 					});
 
-	        Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
+	        Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader, ssrcInfo.getSsrc());
 			if (inviteStreamCallback != null) {
 				inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));
 			}
@@ -734,7 +728,7 @@ public class SIPCommander implements ISIPCommander {
 				dialog = streamSession.getDialogByStream(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
 			}
 			mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
-			mediaServerService.closeRTPServer(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
+			mediaServerService.closeRTPServer(ssrcTransaction.getMediaServerId(), ssrcTransaction.getStream());
 			streamSession.remove(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
 
 			if (dialog == null) {
@@ -771,7 +765,7 @@ public class SIPCommander implements ISIPCommander {
 			// 增加Contact header
 			Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
 			byeRequest.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
-			UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory);
+			UserAgentHeader userAgentHeader = SipUtils.createUserAgentHeader(sipFactory, gitUtil);
 			byeRequest.addHeader(userAgentHeader);
 			ClientTransaction clientTransaction = null;
 			if("TCP".equals(protocol)) {
@@ -812,20 +806,41 @@ public class SIPCommander implements ISIPCommander {
 			broadcastXml.append("<SourceID>" + sipConfig.getId() + "</SourceID>\r\n");
 			broadcastXml.append("<TargetID>" + channelId + "</TargetID>\r\n");
 			broadcastXml.append("</Notify>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
-			
+
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 								
-			Request request = headerProvider.createMessageRequest(device, broadcastXml.toString(), "z9hG4bK-ViaBcst-" + tm, "FromBcst" + tm, null, callIdHeader);
-			transmitRequest(device, request, errorEvent, okEvent);
+			Request request = headerProvider.createMessageRequest(device, broadcastXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
+			transmitRequest(device, request);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
 		} 
 		return false;
 	}
+	@Override
+	public void audioBroadcastCmd(Device device, SipSubscribe.Event errorEvent) {
+		try {
+			StringBuffer broadcastXml = new StringBuffer(200);
+			String charset = device.getCharset();
+			broadcastXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
+			broadcastXml.append("<Notify>\r\n");
+			broadcastXml.append("<CmdType>Broadcast</CmdType>\r\n");
+			broadcastXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
+			broadcastXml.append("<SourceID>" + sipConfig.getId() + "</SourceID>\r\n");
+			broadcastXml.append("<TargetID>" + device.getDeviceId() + "</TargetID>\r\n");
+			broadcastXml.append("</Notify>\r\n");
+
+			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
+					: udpSipProvider.getNewCallId();
+
+			Request request = headerProvider.createMessageRequest(device, broadcastXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
+			transmitRequest(device, request, errorEvent);
+		} catch (SipException | ParseException | InvalidArgumentException e) {
+			e.printStackTrace();
+		}
+	}
+
 
 	/**
 	 * 音视频录像控制
@@ -850,13 +865,11 @@ public class SIPCommander implements ISIPCommander {
 			}
 			cmdXml.append("<RecordCmd>" + recordCmdStr + "</RecordCmd>\r\n");
 			cmdXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromRecord" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -882,13 +895,11 @@ public class SIPCommander implements ISIPCommander {
 			cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			cmdXml.append("<TeleBoot>Boot</TeleBoot>\r\n");
 			cmdXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromBoot" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -915,13 +926,11 @@ public class SIPCommander implements ISIPCommander {
 			cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n");
 			cmdXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromGuard" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -959,13 +968,11 @@ public class SIPCommander implements ISIPCommander {
 				cmdXml.append("</Info>\r\n");
 			}
 			cmdXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromAlarm" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -996,13 +1003,11 @@ public class SIPCommander implements ISIPCommander {
 			}
 			cmdXml.append("<IFameCmd>Send</IFameCmd>\r\n");
 			cmdXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromBoot" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -1051,13 +1056,11 @@ public class SIPCommander implements ISIPCommander {
 			}
 			cmdXml.append("</HomePosition>\r\n");
 			cmdXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromGuard" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -1123,13 +1126,11 @@ public class SIPCommander implements ISIPCommander {
 			}
 			cmdXml.append("</BasicParam>\r\n");
 			cmdXml.append("</Control>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -1154,13 +1155,11 @@ public class SIPCommander implements ISIPCommander {
 			catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
 			catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			catalogXml.append("</Query>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, "FromStatus" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 
 			transmitRequest(device, request, errorEvent);
 			return true;
@@ -1187,13 +1186,11 @@ public class SIPCommander implements ISIPCommander {
 			catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
 			catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			catalogXml.append("</Query>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "z9hG4bK-ViaDeviceInfo-" + tm, "FromDev" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
 
 			transmitRequest(device, request);
 			
@@ -1216,17 +1213,15 @@ public class SIPCommander implements ISIPCommander {
 			String charset = device.getCharset();
 			catalogXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
 			catalogXml.append("<Query>\r\n");
-			catalogXml.append("<CmdType>Catalog</CmdType>\r\n");
-			catalogXml.append("<SN>" + sn + "</SN>\r\n");
-			catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
+			catalogXml.append("  <CmdType>Catalog</CmdType>\r\n");
+			catalogXml.append("  <SN>" + sn + "</SN>\r\n");
+			catalogXml.append("  <DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			catalogXml.append("</Query>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "z9hG4bK-ViaCatalog-" + tm, "FromCat" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), SipUtils.getNewViaTag(),  SipUtils.getNewFromTag(), null, callIdHeader);
 
 			transmitRequest(device, request, errorEvent);
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -1273,14 +1268,12 @@ public class SIPCommander implements ISIPCommander {
 				recordInfoXml.append("<Type>" + type+"</Type>\r\n");
 			}
 			recordInfoXml.append("</Query>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
 			Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(),
-					"z9hG4bK-ViaRecordInfo-" + tm, "fromRec" + tm, null, callIdHeader);
+					SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
 
 			transmitRequest(device, request, errorEvent, okEvent);
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -1332,13 +1325,11 @@ public class SIPCommander implements ISIPCommander {
 				cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\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.createMessageRequest(device, cmdXml.toString(), null, "FromAlarm" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -1370,13 +1361,11 @@ public class SIPCommander implements ISIPCommander {
 			}
 			cmdXml.append("<ConfigType>" + configType + "</ConfigType>\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.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -1405,13 +1394,11 @@ public class SIPCommander implements ISIPCommander {
 				cmdXml.append("<DeviceID>" + channelId + "</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.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request, errorEvent);
 			return true;
 		} catch (SipException | ParseException | InvalidArgumentException e) {
@@ -1437,13 +1424,11 @@ public class SIPCommander implements ISIPCommander {
 			mobilePostitionXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
 			mobilePostitionXml.append("<Interval>60</Interval>\r\n");
 			mobilePostitionXml.append("</Query>\r\n");
-			
-			String tm = Long.toString(System.currentTimeMillis());
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
 
-			Request request = headerProvider.createMessageRequest(device, mobilePostitionXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, mobilePostitionXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
 
 			transmitRequest(device, request, errorEvent);
 			
@@ -1492,10 +1477,9 @@ public class SIPCommander implements ISIPCommander {
 				request.removeHeader(CSeqHeader.NAME);
 				request.addHeader(cSeqHeader);
 			}else {
-				String tm = Long.toString(System.currentTimeMillis());
 				CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 						: udpSipProvider.getNewCallId();
-				request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, device.getSubscribeCycleForMobilePosition(), "presence" ,callIdHeader); //Position;id=" + tm.substring(tm.length() - 4));
+				request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, device.getSubscribeCycleForMobilePosition(), "presence" ,callIdHeader); //Position;id=" + tm.substring(tm.length() - 4));
 			}
 			transmitRequest(device, request, errorEvent, okEvent);
 
@@ -1550,12 +1534,10 @@ public class SIPCommander implements ISIPCommander {
 			}
 			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, expires, "presence" , callIdHeader);
+			Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, expires, "presence" , callIdHeader);
 			transmitRequest(device, request);
 
 			return true;
@@ -1597,14 +1579,12 @@ public class SIPCommander implements ISIPCommander {
 				request.addHeader(cSeqHeader);
 
 			}else {
-				String tm = Long.toString(System.currentTimeMillis());
-
 				CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 						: udpSipProvider.getNewCallId();
 
 				// 有效时间默认为60秒以上
-				request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "z9hG4bK-viaPos-" + tm,
-						"fromTagPos" + tm, null, device.getSubscribeCycleForCatalog(), "Catalog" ,
+				request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), SipUtils.getNewViaTag(),
+						SipUtils.getNewFromTag(), null, device.getSubscribeCycleForCatalog(), "Catalog" ,
 						callIdHeader);
 
 			}
@@ -1633,10 +1613,9 @@ public class SIPCommander implements ISIPCommander {
 			}
 			dragXml.append(cmdString);
 			dragXml.append("</Control>\r\n");
-			String tm = Long.toString(System.currentTimeMillis());
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
-			Request request = headerProvider.createMessageRequest(device, dragXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, dragXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
 			logger.debug("拉框信令: " + request.toString());
 			transmitRequest(device, request);
 			return true;
@@ -1663,13 +1642,11 @@ public class SIPCommander implements ISIPCommander {
 			clientTransaction = udpSipProvider.getNewClientTransaction(request);
 		}
 		if (request.getHeader(UserAgentHeader.NAME) == null) {
-			UserAgentHeader userAgentHeader = null;
 			try {
-				userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory);
+				request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
 			} catch (ParseException e) {
 				logger.error("添加UserAgentHeader失败", e);
 			}
-			request.addHeader(userAgentHeader);
 		}
 		CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
 		// 添加错误订阅
@@ -1880,8 +1857,7 @@ public class SIPCommander implements ISIPCommander {
 
 			CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
 					: udpSipProvider.getNewCallId();
-			String tm = Long.toString(System.currentTimeMillis());
-			Request request = headerProvider.createMessageRequest(device, deviceStatusXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
+			Request request = headerProvider.createMessageRequest(device, deviceStatusXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, callIdHeader);
 			transmitRequest(device, request);
 
 
@@ -1896,7 +1872,7 @@ public class SIPCommander implements ISIPCommander {
 
 	private void sendNotify(Device device, String catalogXmlContent,
 							SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent,  SipSubscribe.Event okEvent )
-			throws NoSuchFieldException, IllegalAccessException, SipException, ParseException {
+			throws SipException, ParseException {
 		MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
 		String characterSet = device.getCharset();
 		// 设置编码, 防止中文乱码

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

@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider;
+import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
 import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
 import com.genersoft.iot.vmp.utils.DateUtil;
 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
@@ -26,7 +27,6 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
 
 
 import com.genersoft.iot.vmp.utils.DateUtil;
@@ -39,7 +39,6 @@ import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
-import java.util.UUID;
 
 @Component
 @DependsOn("sipLayer")
@@ -90,7 +89,6 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
                             SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) {
         try {
             Request request;
-            String tm = Long.toString(System.currentTimeMillis());
             if (!registerAgain ) {
                 CallIdHeader callIdHeader = null;
                 if(parentPlatform.getTransport().equalsIgnoreCase("TCP")) {
@@ -101,8 +99,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
                 }
 
                 request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform,
-                        redisCatchStorage.getCSEQ(), "FromRegister" + tm,
-                        "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), callIdHeader, isRegister);
+                        redisCatchStorage.getCSEQ(), SipUtils.getNewFromTag(),
+                        SipUtils.getNewViaTag(), callIdHeader, isRegister);
                 // 将 callid 写入缓存, 等注册成功可以更新状态
                 String callIdFromHeader = callIdHeader.getCallId();
                 redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister));
@@ -122,7 +120,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             }else {
                 CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                         : udpSipProvider.getNewCallId();
-                request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, "FromRegister" + tm, null, callId, www, callIdHeader, isRegister);
+                request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, SipUtils.getNewFromTag(), null, callId, www, callIdHeader, isRegister);
             }
 
             transmitRequest(parentPlatform, request, null, okEvent);
@@ -156,12 +154,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createKeetpaliveMessageRequest(
+            Request request = headerProviderPlarformProvider.createMessageRequest(
                     parentPlatform,
                     keepaliveXml.toString(),
-                    "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""),
-                    UUID.randomUUID().toString().replace("-", ""),
-                    null,
+                    SipUtils.getNewFromTag(),
+                    SipUtils.getNewViaTag(),
                     callIdHeader);
             transmitRequest(parentPlatform, request, errorEvent, okEvent);
             callId = callIdHeader.getCallId();
@@ -223,7 +220,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag, callIdHeader);
+            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -263,26 +260,34 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
                 if (channel.getParentId() != null) {
                     // 业务分组加上这一项即可,提高兼容性,
                     catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n");
+//                    catalogXml.append("<ParentID>" + parentPlatform.getDeviceGBId() + "/" + channel.getParentId() + "</ParentID>\r\n");
                 }
                 if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) {
                     // 虚拟组织增加BusinessGroupID字段
                     catalogXml.append("<BusinessGroupID>" + channel.getParentId() + "</BusinessGroupID>\r\n");
                 }
-                catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
+                if (!channel.getChannelId().equals(parentPlatform.getDeviceGBId())) {
+                    catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
+                    if (channel.getParental() == 0) {
+                        catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
+                    }
+                }
                 if (channel.getParental() == 0) {
                     // 通道项
                     catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
                     catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
                     catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
-                    catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
-
+                    String civilCode = channel.getCivilCode() == null?parentPlatform.getAdministrativeDivision() : channel.getCivilCode();
                     if (channel.getChannelType() != 2) {  // 业务分组/虚拟组织/行政区划 不设置以下属性
                         catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
-                        catalogXml.append("<Owner> " + channel.getOwner()+ "</Owner>\r\n");
-                        catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
-                        catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
+                        catalogXml.append("<Owner>" + parentPlatform.getDeviceGBId()+ "</Owner>\r\n");
+                        catalogXml.append("<CivilCode>" + civilCode + "</CivilCode>\r\n");
+                        if (channel.getAddress() == null) {
+                            catalogXml.append("<Address></Address>\r\n");
+                        }else {
+                            catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
+                        }
                     }
-
                 }
                 catalogXml.append("</Item>\r\n");
             }
@@ -309,7 +314,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, callIdHeader);
+            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request, null, eventResult -> {
                 int indexNext = index + parentPlatform.getCatalogGroup();
                 sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext);
@@ -349,7 +354,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag, callIdHeader);
+            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -387,7 +392,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, callIdHeader);
+            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -437,6 +442,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             e.printStackTrace();
         } catch (IllegalAccessException e) {
             e.printStackTrace();
+        } catch (InvalidArgumentException e) {
+            e.printStackTrace();
         }
         return true;
     }
@@ -470,15 +477,14 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
 
-            String tm = Long.toString(System.currentTimeMillis());
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), "FromPtz" + tm, callIdHeader);
+            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), SipUtils.getNewFromTag(), SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException  e) {
             e.printStackTrace();
             return false;
         } catch (InvalidArgumentException e) {
-            throw new RuntimeException(e);
+            e.printStackTrace();
         }
         return true;
     }
@@ -517,13 +523,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             e.printStackTrace();
         } catch (IllegalAccessException e) {
             e.printStackTrace();
+        } catch (InvalidArgumentException e) {
+            e.printStackTrace();
         }
         return true;
     }
 
     private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent,
                                    SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent,  SipSubscribe.Event okEvent )
-            throws NoSuchFieldException, IllegalAccessException, SipException, ParseException {
+            throws NoSuchFieldException, IllegalAccessException, SipException, ParseException, InvalidArgumentException {
 		MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
         String characterSet = parentPlatform.getCharacterSet();
  		// 设置编码, 防止中文乱码
@@ -533,6 +541,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             return;
         }
         SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY);
+
+        notifyRequest.getCSeqHeader().setSeqNumber(redisCatchStorage.getCSEQ());
+        
         ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
         notifyRequest.setContent(catalogXmlContent, contentTypeHeader);
 
@@ -665,6 +676,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             e.printStackTrace();
         } catch (IllegalAccessException e) {
             e.printStackTrace();
+        } catch (InvalidArgumentException e) {
+            e.printStackTrace();
         }
 
         return true;
@@ -742,7 +755,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             // callid
             CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
-            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, callIdHeader);
+            Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
             transmitRequest(parentPlatform, request);
 
         } catch (SipException | ParseException | InvalidArgumentException e) {
@@ -819,9 +832,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
             e.printStackTrace();
             return false;
         } catch (NoSuchFieldException e) {
-            throw new RuntimeException(e);
+            e.printStackTrace();
         } catch (IllegalAccessException e) {
-            throw new RuntimeException(e);
+            e.printStackTrace();
         }
         return true;
 

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

@@ -130,7 +130,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
 					StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
 					if (streamInfo != null) {
 						redisCatchStorage.stopPlay(streamInfo);
-						mediaServerService.closeRTPServer(device.getDeviceId(), channelId, streamInfo.getStream());
+						mediaServerService.closeRTPServer(streamInfo.getMediaServerId(), streamInfo.getStream());
 					}
 					SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
 					if (ssrcTransactionForPlay != null){

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

@@ -32,6 +32,7 @@ import com.genersoft.iot.vmp.service.IStreamPushService;
 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener;
+import com.genersoft.iot.vmp.service.impl.RedisPushStreamResponseListener;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import com.genersoft.iot.vmp.utils.DateUtil;
@@ -87,7 +88,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
     private DynamicTask dynamicTask;
 
     @Autowired
-    private SIPCommander cmder;
+    private RedisPushStreamResponseListener redisPushStreamResponseListener;
 
     @Autowired
     private IPlayService playService;
@@ -588,7 +589,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
             otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                     mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
         }
-
     }
     /**
      * 通知流上线
@@ -671,6 +671,23 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
                             mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                 }
             });
+
+            // 添加回复的拒绝或者错误的通知
+            redisPushStreamResponseListener.addEvent(gbStream.getApp(), gbStream.getStream(), response -> {
+                if (response.getCode() != 0) {
+                    dynamicTask.stop(callIdHeader.getCallId());
+                    mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
+                    try {
+                        responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
+                    } catch (SipException e) {
+                        throw new RuntimeException(e);
+                    } catch (InvalidArgumentException e) {
+                        throw new RuntimeException(e);
+                    } catch (ParseException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            });
         }
     }
 

+ 20 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java

@@ -78,6 +78,11 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
 
             List<DeviceChannel> allChannels = new ArrayList<>();
 
+            // 回复平台
+//            DeviceChannel deviceChannel = getChannelForPlatform(parentPlatform);
+//            allChannels.add(deviceChannel);
+
+            // 回复目录
             if (catalogs.size() > 0) {
                 allChannels.addAll(catalogs);
             }
@@ -104,4 +109,19 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
         }
 
     }
+
+    private DeviceChannel getChannelForPlatform(ParentPlatform platform) {
+        DeviceChannel deviceChannel = new DeviceChannel();
+
+        deviceChannel.setChannelId(platform.getDeviceGBId());
+        deviceChannel.setName(platform.getName());
+        deviceChannel.setManufacture("wvp-pro");
+        deviceChannel.setOwner("wvp-pro");
+        deviceChannel.setCivilCode(platform.getAdministrativeDivision());
+        deviceChannel.setAddress("wvp-pro");
+        deviceChannel.setRegisterWay(0);
+        deviceChannel.setSecrecy("0");
+
+        return deviceChannel;
+    }
 }

+ 6 - 8
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java

@@ -1,14 +1,12 @@
 package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
 
 import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.gb28181.SipLayer;
-import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
 import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
-import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils;
+import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
+import com.genersoft.iot.vmp.utils.GitUtil;
 import gov.nist.javax.sip.ResponseEventExt;
-import gov.nist.javax.sip.message.SIPResponse;
 import gov.nist.javax.sip.stack.SIPDialog;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -22,13 +20,10 @@ import javax.sip.*;
 import javax.sip.address.Address;
 import javax.sip.address.SipURI;
 import javax.sip.header.CSeqHeader;
-import javax.sip.header.CallIdHeader;
 import javax.sip.header.UserAgentHeader;
 import javax.sip.message.Request;
 import javax.sip.message.Response;
 import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.List;
 
 
 /**
@@ -54,6 +49,9 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
 	@Autowired
 	private SipFactory sipFactory;
 
+	@Autowired
+	private GitUtil gitUtil;
+
 	@Override
 	public void afterPropertiesSet() throws Exception {
 		// 添加消息处理的订阅
@@ -104,7 +102,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
 				}
 				requestURI.setPort(event.getRemotePort());
 				reqAck.setRequestURI(requestURI);
-				UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory);
+				UserAgentHeader userAgentHeader = SipUtils.createUserAgentHeader(sipFactory, gitUtil);
 				reqAck.addHeader(userAgentHeader);
 				Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
 				reqAck.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));

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

@@ -26,11 +26,17 @@ public class TimeoutProcessorImpl implements InitializingBean, ITimeoutProcessor
 
     @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);
+        try {
+            // 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);
+            sipSubscribe.removeErrorSubscribe(callId);
+            sipSubscribe.removeOkSubscribe(callId);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 }

+ 0 - 22
src/main/java/com/genersoft/iot/vmp/gb28181/utils/HeaderUtils.java

@@ -1,22 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.utils;
-
-import javax.sip.PeerUnavailableException;
-import javax.sip.SipFactory;
-import javax.sip.header.UserAgentHeader;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 生成header的工具类
- * @author lin
- */
-public class HeaderUtils {
-
-    public static UserAgentHeader createUserAgentHeader(SipFactory sipFactory) throws PeerUnavailableException, ParseException {
-        List<String> agentParam = new ArrayList<>();
-        agentParam.add("WVP PRO");
-        // TODO 添加版本信息以及日期
-        return sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
-    }
-}

+ 32 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java

@@ -1,12 +1,20 @@
 package com.genersoft.iot.vmp.gb28181.utils;
 
+import com.genersoft.iot.vmp.utils.GitUtil;
 import gov.nist.javax.sip.address.AddressImpl;
 import gov.nist.javax.sip.address.SipUri;
 import gov.nist.javax.sip.header.Subject;
 
+import javax.sip.PeerUnavailableException;
+import javax.sip.SipFactory;
 import javax.sip.header.FromHeader;
 import javax.sip.header.Header;
+import javax.sip.header.UserAgentHeader;
 import javax.sip.message.Request;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
 
 /**
  * @author panlinlin
@@ -38,4 +46,28 @@ public class SipUtils {
         return uri.getUser();
     }
 
+    public static  String getNewViaTag() {
+        return "z9hG4bK" + System.currentTimeMillis();
+    }
+
+    public static UserAgentHeader createUserAgentHeader(SipFactory sipFactory, GitUtil gitUtil) throws PeerUnavailableException, ParseException {
+        List<String> agentParam = new ArrayList<>();
+        agentParam.add("WVP-Pro v");
+        if (gitUtil != null && gitUtil.getCommitTime() != null) {
+            agentParam.add(gitUtil.getBuildVersion() + ".");
+            agentParam.add(gitUtil.getCommitTime());
+        }
+        return sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
+    }
+
+    public static String getNewFromTag(){
+        return UUID.randomUUID().toString().replace("-", "");
+
+//        return getNewTag();
+    }
+
+    public static String getNewTag(){
+        return String.valueOf(System.currentTimeMillis());
+    }
+
 }

+ 9 - 6
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java

@@ -203,12 +203,6 @@ public class XmlUtil {
             return null;
         }
         deviceChannel.setChannelId(channelId);
-        int channelTypeCode = Integer.parseInt(channelId.substring(10, 13));
-        if (channelTypeCode == 136 || channelTypeCode == 137 || channelTypeCode == 138) {
-            deviceChannel.setHasAudio(true);
-        }else {
-            deviceChannel.setHasAudio(false);
-        }
         if (event != null && !event.equals(CatalogEvent.ADD) && !event.equals(CatalogEvent.UPDATE)) {
             // 除了ADD和update情况下需要识别全部内容,
             return deviceChannel;
@@ -217,17 +211,26 @@ public class XmlUtil {
         ChannelType channelType = ChannelType.Other;
         if (channelId.length() <= 8) {
             channelType = ChannelType.CivilCode;
+            deviceChannel.setHasAudio(false);
         }else {
             if (channelId.length() == 20) {
                 int code = Integer.parseInt(channelId.substring(10, 13));
                 switch (code){
                     case 215:
                         channelType = ChannelType.BusinessGroup;
+                        deviceChannel.setHasAudio(false);
                         break;
                     case 216:
                         channelType = ChannelType.VirtualOrganization;
+                        deviceChannel.setHasAudio(false);
+                        break;
+                    case 136:
+                    case 137:
+                    case 138:
+                        deviceChannel.setHasAudio(true);
                         break;
                     default:
+                        deviceChannel.setHasAudio(false);
                         break;
 
                 }

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

@@ -139,6 +139,7 @@ public class ZLMRTPServerFactory {
             param.put("stream_id", streamId);
             JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(serverItem, param);
             if (jsonObject != null ) {
+                System.out.println(jsonObject);
                 if (jsonObject.getInteger("code") == 0) {
                     result = jsonObject.getInteger("hit") == 1;
                 }else {

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java

@@ -53,4 +53,6 @@ public interface IGbStreamService {
      * @return
      */
     int updateGbIdOrName(List<StreamPushItem> streamPushItemForUpdate);
+
+    DeviceChannel getDeviceChannelListByStreamWithStatus(GbStream gbStream, String catalogId, ParentPlatform platform);
 }

+ 3 - 1
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java

@@ -49,7 +49,9 @@ public interface IMediaServerService {
 
     SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port);
 
-    void closeRTPServer(String deviceId, String channelId, String ssrc);
+    void closeRTPServer(MediaServerItem mediaServerItem, String streamId);
+
+    void closeRTPServer(String mediaServerId, String streamId);
 
     void clearRTPServer(MediaServerItem mediaServerItem);
 

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/service/bean/MessageForPushChannel.java

@@ -48,6 +48,8 @@ public class MessageForPushChannel {
      */
     private String mediaServerId;
 
+
+
     public static MessageForPushChannel getInstance(int type, String app, String stream, String gbId,
                                                     String platFormId, String platFormName, String serverId,
                                                     String mediaServerId){

+ 71 - 0
src/main/java/com/genersoft/iot/vmp/service/bean/MessageForPushChannelResponse.java

@@ -0,0 +1,71 @@
+package com.genersoft.iot.vmp.service.bean;
+
+/**
+ * 当redis回复推流结果上级平台
+ * @author lin
+ */
+public class MessageForPushChannelResponse {
+    /**
+     * 错误玛
+     * 0 成功 1 失败
+     */
+    private int code;
+    /**
+     * 错误内容
+     */
+    private String msg;
+
+    /**
+     * 流应用名
+     */
+    private String app;
+
+    /**
+     * 流Id
+     */
+    private String stream;
+
+
+
+    public static MessageForPushChannelResponse getInstance(int code, String msg, String app, String stream){
+        MessageForPushChannelResponse messageForPushChannel = new MessageForPushChannelResponse();
+        messageForPushChannel.setCode(code);
+        messageForPushChannel.setMsg(msg);
+        messageForPushChannel.setApp(app);
+        messageForPushChannel.setStream(stream);
+        return messageForPushChannel;
+    }
+
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getApp() {
+        return app;
+    }
+
+    public void setApp(String app) {
+        this.app = app;
+    }
+
+    public String getStream() {
+        return stream;
+    }
+
+    public void setStream(String stream) {
+        this.stream = stream;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java

@@ -145,7 +145,7 @@ public class DeviceServiceImpl implements IDeviceService {
         if (ssrcTransactions != null && ssrcTransactions.size() > 0) {
             for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
                 mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
-                mediaServerService.closeRTPServer(deviceId, ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
+                mediaServerService.closeRTPServer(ssrcTransaction.getMediaServerId(), ssrcTransaction.getStream());
                 streamSession.remove(deviceId, ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
             }
         }

+ 43 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java

@@ -79,7 +79,7 @@ public class GbStreamServiceImpl implements IGbStreamService {
                 gbStream.setPlatformId(platformId);
                 // TODO 修改为批量提交
                 platformGbStreamMapper.add(gbStream);
-                DeviceChannel deviceChannelListByStream = getDeviceChannelListByStream(gbStream, catalogId, parentPlatform);
+                DeviceChannel deviceChannelListByStream = getDeviceChannelListByStreamWithStatus(gbStream, catalogId, parentPlatform);
                 deviceChannelList.add(deviceChannelListByStream);
             }
             dataSourceTransactionManager.commit(transactionStatus);     //手动提交
@@ -188,4 +188,46 @@ public class GbStreamServiceImpl implements IGbStreamService {
     public int updateGbIdOrName(List<StreamPushItem> streamPushItemForUpdate) {
         return gbStreamMapper.updateGbIdOrName(streamPushItemForUpdate);
     }
+
+    @Override
+    public DeviceChannel getDeviceChannelListByStreamWithStatus(GbStream gbStream, String catalogId, ParentPlatform platform) {
+        DeviceChannel deviceChannel = new DeviceChannel();
+        deviceChannel.setChannelId(gbStream.getGbId());
+        deviceChannel.setName(gbStream.getName());
+        deviceChannel.setLongitude(gbStream.getLongitude());
+        deviceChannel.setLatitude(gbStream.getLatitude());
+        deviceChannel.setDeviceId(platform.getDeviceGBId());
+        deviceChannel.setManufacture("wvp-pro");
+        // todo 目前是每一条查询一次,需要优化
+        Boolean status = null;
+        if ("proxy".equals(gbStream.getStreamType())) {
+            status = gbStreamMapper.selectStatusForProxy(gbStream.getApp(), gbStream.getStream());
+        }else {
+            status = gbStreamMapper.selectStatusForPush(gbStream.getApp(), gbStream.getStream());
+        }
+        deviceChannel.setStatus((status != null && status )?1:0);
+
+        deviceChannel.setRegisterWay(1);
+        deviceChannel.setCivilCode(platform.getAdministrativeDivision());
+
+        if (platform.getTreeType().equals(TreeType.CIVIL_CODE)){
+            deviceChannel.setCivilCode(catalogId);
+        }else if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)){
+            PlatformCatalog catalog = catalogMapper.select(catalogId);
+            if (catalog == null) {
+                deviceChannel.setParentId(platform.getDeviceGBId());
+                deviceChannel.setBusinessGroupId(null);
+            }else {
+                deviceChannel.setParentId(catalog.getId());
+                deviceChannel.setBusinessGroupId(catalog.getBusinessGroupId());
+            }
+
+        }
+
+        deviceChannel.setModel("live");
+        deviceChannel.setOwner("wvp-pro");
+        deviceChannel.setParental(0);
+        deviceChannel.setSecrecy("0");
+        return deviceChannel;
+    }
 }

+ 11 - 9
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java

@@ -169,16 +169,18 @@ public class MediaServerServiceImpl implements IMediaServerService {
     }
 
     @Override
-    public void closeRTPServer(String deviceId, String channelId, String stream) {
-        String mediaServerId = streamSession.getMediaServerId(deviceId, channelId, stream);
-        String ssrc = streamSession.getSSRC(deviceId, channelId, stream);
-        MediaServerItem mediaServerItem = this.getOne(mediaServerId);
-        if (mediaServerItem != null) {
-            String streamId = String.format("%s_%s", deviceId, channelId);
-            zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
-            releaseSsrc(mediaServerItem.getId(), ssrc);
+    public void closeRTPServer(MediaServerItem mediaServerItem, String streamId) {
+        if (mediaServerItem == null) {
+            return;
         }
-        streamSession.remove(deviceId, channelId, stream);
+        zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
+        releaseSsrc(mediaServerItem.getId(), streamId);
+    }
+
+    @Override
+    public void closeRTPServer(String mediaServerId, String streamId) {
+        MediaServerItem mediaServerItem = this.getOne(mediaServerId);
+        closeRTPServer(mediaServerItem, streamId);
     }
 
     @Override

+ 8 - 6
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java

@@ -285,6 +285,7 @@ public class PlayServiceImpl implements IPlayService {
         // 超时处理
         String timeOutTaskKey = UUID.randomUUID().toString();
         SSRCInfo finalSsrcInfo = ssrcInfo;
+        System.out.println("设置超时任务: " + timeOutTaskKey);
         dynamicTask.startDelay( timeOutTaskKey,()->{
 
             SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
@@ -297,7 +298,7 @@ public class PlayServiceImpl implements IPlayService {
                 logger.info("[点播超时] 消息未响应 deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
                 timeoutCallback.run(0, "点播超时");
                 mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
-                mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
+                mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
                 streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
             }
         }, userSetting.getPlayTimeout());
@@ -310,6 +311,7 @@ public class PlayServiceImpl implements IPlayService {
         }
         cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
             logger.info("收到订阅消息: " + response.toJSONString());
+            System.out.println("停止超时任务: " + timeOutTaskKey);
             dynamicTask.stop(timeOutTaskKey);
             // hook响应
             onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid);
@@ -359,7 +361,7 @@ public class PlayServiceImpl implements IPlayService {
                                 });
                     }
                     // 关闭rtp server
-                    mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
+                    mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
                     // 重新开启ssrc server
                     mediaServerService.openRTPServer(mediaServerItem, finalSsrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, finalSsrcInfo.getPort());
 
@@ -367,7 +369,7 @@ public class PlayServiceImpl implements IPlayService {
             }
         }, (event) -> {
             dynamicTask.stop(timeOutTaskKey);
-            mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
+            mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
             // 释放ssrc
             mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
 
@@ -471,7 +473,7 @@ public class PlayServiceImpl implements IPlayService {
                 cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
             }else {
                 mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
-                mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream());
+                mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
                 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
             }
             cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
@@ -559,7 +561,7 @@ public class PlayServiceImpl implements IPlayService {
                                     });
                                 }
                                 // 关闭rtp server
-                                mediaServerService.closeRTPServer(device.getDeviceId(), channelId, ssrcInfo.getStream());
+                                mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
                                 // 重新开启ssrc server
                                 mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
                             }
@@ -619,7 +621,7 @@ public class PlayServiceImpl implements IPlayService {
                 cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
             }else {
                 mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
-                mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream());
+                mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
                 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
             }
             cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);

+ 62 - 0
src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamResponseListener.java

@@ -0,0 +1,62 @@
+package com.genersoft.iot.vmp.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.media.zlm.dto.ChannelOnlineEvent;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
+import com.genersoft.iot.vmp.service.IGbStreamService;
+import com.genersoft.iot.vmp.service.IMediaServerService;
+import com.genersoft.iot.vmp.service.IStreamPushService;
+import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse;
+import com.genersoft.iot.vmp.utils.DateUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.connection.MessageListener;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 接收redis返回的推流结果
+ * @author lin
+ */
+@Component
+public class RedisPushStreamResponseListener implements MessageListener {
+
+    private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamResponseListener.class);
+
+    private Map<String, PushStreamResponseEvent> responseEvents = new ConcurrentHashMap<>();
+
+    public interface PushStreamResponseEvent{
+        void run(MessageForPushChannelResponse response);
+    }
+
+    @Override
+    public void onMessage(Message message, byte[] bytes) {
+        //
+        logger.warn("[REDIS消息-请求推流结果]: {}", new String(message.getBody()));
+        MessageForPushChannelResponse response = JSON.parseObject(new String(message.getBody()), MessageForPushChannelResponse.class);
+        if (response == null || ObjectUtils.isEmpty(response.getApp()) || ObjectUtils.isEmpty(response.getStream())){
+            logger.info("[REDIS消息-请求推流结果]:参数不全");
+            return;
+        }
+        // 查看正在等待的invite消息
+        if (responseEvents.get(response.getApp() + response.getStream()) != null) {
+            responseEvents.get(response.getApp() + response.getStream()).run(response);
+        }
+    }
+
+    public void addEvent(String app, String stream, PushStreamResponseEvent callback) {
+        responseEvents.put(app + stream, callback);
+    }
+
+    public void removeEvent(String app, String stream) {
+        responseEvents.remove(app + stream);
+    }
+}

+ 2 - 3
src/main/java/com/genersoft/iot/vmp/service/impl/RedisPushStreamListMsgListener.java

@@ -9,7 +9,6 @@ import com.genersoft.iot.vmp.service.IStreamPushService;
 import com.genersoft.iot.vmp.utils.DateUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.connection.Message;
 import org.springframework.data.redis.connection.MessageListener;
 import org.springframework.stereotype.Component;
@@ -23,9 +22,9 @@ import java.util.*;
  * @Description: 接收redis发送的推流设备列表更新通知
  */
 @Component
-public class RedisPushStreamListMsgListener implements MessageListener {
+public class RedisPushStreamStatusListMsgListener implements MessageListener {
 
-    private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamListMsgListener.class);
+    private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamStatusListMsgListener.class);
     @Resource
     private IMediaServerService mediaServerService;
 

+ 0 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java

@@ -428,7 +428,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
                             platformId, platformForEvent.get(platformId), CatalogEvent.ADD);
                 }
             }
-
         }
     }
 

+ 2 - 2
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java

@@ -19,11 +19,11 @@ public interface DeviceChannelMapper {
     @Insert("INSERT INTO device_channel (channelId, deviceId, name, manufacture, model, owner, civilCode, block, " +
             "address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " +
             "ipAddress, port, password, PTZType, status, streamId, longitude, latitude, longitudeGcj02, latitudeGcj02, " +
-            "longitudeWgs84, latitudeWgs84, createTime, updateTime, businessGroupId, gpsTime) " +
+            "longitudeWgs84, latitudeWgs84, hasAudio, createTime, updateTime, businessGroupId, gpsTime) " +
             "VALUES ('${channelId}', '${deviceId}', '${name}', '${manufacture}', '${model}', '${owner}', '${civilCode}', '${block}'," +
             "'${address}', ${parental}, '${parentId}', ${safetyWay}, ${registerWay}, '${certNum}', ${certifiable}, ${errCode}, '${secrecy}', " +
             "'${ipAddress}', ${port}, '${password}', ${PTZType}, ${status}, '${streamId}', ${longitude}, ${latitude}, ${longitudeGcj02}, " +
-            "${latitudeGcj02}, ${longitudeWgs84}, ${latitudeWgs84},'${createTime}', '${updateTime}', '${businessGroupId}', '${gpsTime}')")
+            "${latitudeGcj02}, ${longitudeWgs84}, ${latitudeWgs84}, ${hasAudio}, '${createTime}', '${updateTime}', '${businessGroupId}', '${gpsTime}')")
     int add(DeviceChannel channel);
 
     @Update(value = {" <script>" +

+ 6 - 0
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java

@@ -158,4 +158,10 @@ public interface GbStreamMapper {
                 "</foreach>"+
             "</script>")
     int updateGbIdOrName(List<StreamPushItem> streamPushItemForUpdate);
+
+    @Select("SELECT status FROM stream_proxy WHERE app=#{app} AND stream=#{stream}")
+    Boolean selectStatusForProxy(String app, String stream);
+
+    @Select("SELECT status FROM stream_push WHERE app=#{app} AND stream=#{stream}")
+    Boolean selectStatusForPush(String app, String stream);
 }

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

@@ -77,7 +77,7 @@ public interface StreamPushMapper {
             "1=1 " +
             " <if test='query != null'> AND (st.app LIKE '%${query}%' OR st.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " +
             " <if test='pushing == true' > AND (gs.gbId is null OR st.pushIng=1)</if>" +
-            " <if test='pushing == false' > AND (gs.pushIng is null OR st.pushIng=0) </if>" +
+            " <if test='pushing == false' > AND (st.pushIng is null OR st.pushIng=0) </if>" +
             " <if test='mediaServerId != null' > AND st.mediaServerId=#{mediaServerId} </if>" +
             "order by st.createTime desc" +
             " </script>"})

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

@@ -133,7 +133,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 						deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId());
 						deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio());
 					}
-
 					channels.add(deviceChannel);
 					if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {
 						if (subContMap.get(deviceChannel.getParentId()) == null) {
@@ -696,7 +695,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
 			return 0;
 		}
 		if (platform.getTreeType().equals(TreeType.BUSINESS_GROUP)) {
-			if (platformCatalog.getPlatformId().equals(platformCatalog.getParentId())) {
+			if (platform.getDeviceGBId().equals(platformCatalog.getParentId())) {
 				// 第一层节点
 				platformCatalog.setBusinessGroupId(platformCatalog.getId());
 				platformCatalog.setParentId(platform.getDeviceGBId());

+ 15 - 0
src/main/java/com/genersoft/iot/vmp/utils/GitUtil.java

@@ -19,9 +19,16 @@ public class GitUtil {
     private String gitUrl;
     @Value("${git.build.time:null}")
     private String buildDate;
+
+    @Value("${git.build.version:null}")
+    private String buildVersion;
+
     @Value("${git.commit.id.abbrev:null}")
     private String commitIdShort;
 
+    @Value("${git.commit.time:null}")
+    private String commitTime;
+
     public String getGitCommitId() {
         return gitCommitId;
     }
@@ -41,4 +48,12 @@ public class GitUtil {
     public String getCommitIdShort() {
         return commitIdShort;
     }
+
+    public String getBuildVersion() {
+        return buildVersion;
+    }
+
+    public String getCommitTime() {
+        return commitTime;
+    }
 }

+ 0 - 6
src/main/resources/all-application.yml

@@ -195,9 +195,3 @@ springdoc:
         enabled: false
     swagger-ui:
         enabled: false
-
-# 版本信息, 不需修改
-version:
-    version: "@project.version@"
-    description: "@project.description@"
-    artifact-id: "@project.artifactId@"

+ 0 - 6
src/main/resources/application-dev.yml

@@ -84,9 +84,3 @@ media:
 # [可选] 日志配置, 一般不需要改
 logging:
     config: classpath:logback-spring-local.xml
-
-# 版本信息, 不需修改
-version:
-    version: "@project.version@"
-    description: "@project.description@"
-    artifact-id: "@project.artifactId@"

+ 0 - 7
src/main/resources/application-docker.yml

@@ -78,10 +78,3 @@ user-settings:
     # 推流直播是否录制
     record-push-live: true
     auto-apply-play: true
-
-
-# 版本信息, 不需修改
-version:
-    version: "@project.version@"
-    description: "@project.description@"
-    artifact-id: "@project.artifactId@"

+ 0 - 2
src/main/resources/banner.txt

@@ -5,5 +5,3 @@
   \ \  \|\__\_\  \ \    / /   \ \  \___\|____________|\ \  \___|\ \  \\  \\ \  \\\  \ 
    \ \____________\ \__/ /     \ \__\                  \ \__\    \ \__\\ _\\ \_______\
     \|____________|\|__|/       \|__|                   \|__|     \|__|\|__|\|_______|
-
-版本:${version.version}

+ 1 - 0
web_src/src/components/channelList.vue

@@ -250,6 +250,7 @@ export default {
             that.loadSnap[deviceId + channelId] = 0;
             that.getSnapErrorEvent(snapId)
           }, 5000)
+          itemData.streamId = res.data.data.stream;
           that.$refs.devicePlayer.openDialog("media", deviceId, channelId, {
             streamInfo: res.data.data,
             hasAudio: itemData.hasAudio