diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..57cc8e5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 swwhaha + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pom.xml b/pom.xml index 0788992..ec4e9c3 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ org.springframework.boot - spring-boot-starter-undertow + spring-boot-starter-tomcat org.springframework.boot @@ -127,7 +127,7 @@ org.dom4j dom4j - 2.1.1 + 2.1.3 com.google.code.gson diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index 802309d..723af70 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.common; /** * @Description:TODO(这里用一句话描述这个类的作用) - * @author: swwheihei + * @author: songww * @date: 2019年5月30日 下午3:04:04 * */ diff --git a/src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java index 47d2a02..3448a2f 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; /** * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置 - * @author: swwheihei + * @author: songww * @date: 2019年5月30日 上午10:58:25 * */ diff --git a/src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java index 6045ea2..b294e0c 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java @@ -5,7 +5,7 @@ import org.springframework.context.annotation.Configuration; /** * @Description:TODO(这里用一句话描述这个类的作用) - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午2:46:00 */ @Configuration("vmConfig") diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index cfea026..0f6a092 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -1,250 +1,262 @@ -package com.genersoft.iot.vmp.gb28181; - -import java.util.Properties; - -import javax.annotation.PostConstruct; -import javax.sip.DialogTerminatedEvent; -import javax.sip.IOExceptionEvent; -import javax.sip.ListeningPoint; -import javax.sip.RequestEvent; -import javax.sip.ResponseEvent; -import javax.sip.ServerTransaction; -import javax.sip.SipFactory; -import javax.sip.SipListener; -import javax.sip.SipProvider; -import javax.sip.SipStack; -import javax.sip.TimeoutEvent; -import javax.sip.TransactionAlreadyExistsException; -import javax.sip.TransactionTerminatedEvent; -import javax.sip.TransactionUnavailableException; -import javax.sip.address.AddressFactory; -import javax.sip.header.HeaderFactory; -import javax.sip.header.ViaHeader; -import javax.sip.message.MessageFactory; -import javax.sip.message.Request; -import javax.sip.message.Response; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.genersoft.iot.vmp.conf.SipConfig; -import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; -import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; - -import gov.nist.javax.sip.SipStackImpl; - -@Component -public class SipLayer implements SipListener, Runnable { - - private final static Logger logger = LoggerFactory.getLogger(SipLayer.class); - - @Autowired - private SipConfig sipConfig; - - private SipProvider tcpSipProvider; - - private SipProvider udpSipProvider; - - @Autowired - private SIPProcessorFactory processorFactory; - - private SipStack sipStack; - - private AddressFactory addressFactory; - private HeaderFactory headerFactory; - private MessageFactory messageFactory; - - @PostConstruct - private void initSipServer() { - Thread thread=new Thread(this); - thread.setDaemon(true); - thread.setName("sip server thread start"); - thread.start(); - } - - @Override - public void run() { - SipFactory sipFactory = SipFactory.getInstance(); - sipFactory.setPathName("gov.nist"); - try { - headerFactory = sipFactory.createHeaderFactory(); - - addressFactory = sipFactory.createAddressFactory(); - messageFactory = sipFactory.createMessageFactory(); - - Properties properties = new Properties(); - properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); - properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp()); - properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false"); - /** - * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE = - * 0; public static final int TRACE_MESSAGES = 16; public static final int - * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32; - */ - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log"); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log"); - sipStack = (SipStackImpl) sipFactory.createSipStack(properties); - - startTcpListener(); - startUdpListener(); - } catch (Exception e) { - logger.error("Sip Server 启动失败! port {" + sipConfig.getSipPort() + "}"); - e.printStackTrace(); - } - logger.info("Sip Server 启动成功 port {" + sipConfig.getSipPort() + "}"); - } - - private void startTcpListener() throws Exception { - ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "TCP"); - tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); - tcpSipProvider.addSipListener(this); - } - - private void startUdpListener() throws Exception { - ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP"); - udpSipProvider = sipStack.createSipProvider(udpListeningPoint); - udpSipProvider.addSipListener(this); - } - - /** - * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a - * new request arrives. - */ - @Override - public void processRequest(RequestEvent evt) { - ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt); - processor.process(evt, this); - } - - @Override - public void processResponse(ResponseEvent evt) { - Response response = evt.getResponse(); - int status = response.getStatusCode(); - if ((status >= 200) && (status < 300)) { // Success! - ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); - processor.process(evt, this, sipConfig); - } else { - logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getContent().toString()); - } - // trying不会回复 - if (status == Response.TRYING) { - - } - } - - /** - *

- * Title: processTimeout - *

- *

- * Description: - *

- * - * @param timeoutEvent - */ - @Override - public void processTimeout(TimeoutEvent timeoutEvent) { - // TODO Auto-generated method stub - - } - - /** - *

- * Title: processIOException - *

- *

- * Description: - *

- * - * @param exceptionEvent - */ - @Override - public void processIOException(IOExceptionEvent exceptionEvent) { - // TODO Auto-generated method stub - - } - - /** - *

- * Title: processTransactionTerminated - *

- *

- * Description: - *

- * - * @param transactionTerminatedEvent - */ - @Override - public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { - // TODO Auto-generated method stub - - } - - /** - *

- * Title: processDialogTerminated - *

- *

- * Description: - *

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

+ * Title: processTimeout + *

+ *

+ * Description: + *

+ * + * @param timeoutEvent + */ + @Override + public void processTimeout(TimeoutEvent timeoutEvent) { + // TODO Auto-generated method stub + + } + + /** + *

+ * Title: processIOException + *

+ *

+ * Description: + *

+ * + * @param exceptionEvent + */ + @Override + public void processIOException(IOExceptionEvent exceptionEvent) { + // TODO Auto-generated method stub + + } + + /** + *

+ * Title: processTransactionTerminated + *

+ *

+ * Description: + *

+ * + * @param transactionTerminatedEvent + */ + @Override + public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { + // TODO Auto-generated method stub + + } + + /** + *

+ * Title: processDialogTerminated + *

+ *

+ * Description: + *

+ * + * @param dialogTerminatedEvent + */ + @Override + public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) { + // TODO Auto-generated method stub + + } + + public ServerTransaction getServerTransaction(RequestEvent evt) { + Request request = evt.getRequest(); + ServerTransaction serverTransaction = evt.getServerTransaction(); + // 判断TCP还是UDP + boolean isTcp = false; + ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); + String transport = reqViaHeader.getTransport(); + if (transport.equals("TCP")) { + isTcp = true; + } + + if (serverTransaction == null) { + try { + if (isTcp) { + serverTransaction = tcpSipProvider.getNewServerTransaction(request); + } else { + serverTransaction = udpSipProvider.getNewServerTransaction(request); + } + } catch (TransactionAlreadyExistsException e) { + e.printStackTrace(); + } catch (TransactionUnavailableException e) { + e.printStackTrace(); + } + } + return serverTransaction; + } + + public AddressFactory getAddressFactory() { + return addressFactory; + } + + public HeaderFactory getHeaderFactory() { + return headerFactory; + } + + public MessageFactory getMessageFactory() { + return messageFactory; + } + + public SipProvider getTcpSipProvider() { + return tcpSipProvider; + } + + public SipProvider getUdpSipProvider() { + return udpSipProvider; + } + +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java index 6e4588d..5d5bf21 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; /** * @Description:注册逻辑处理,当设备注册后触发逻辑。 - * @author: swwheihei + * @author: songww * @date: 2020年5月8日 下午9:41:46 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java index 8a88c94..2d2ca1e 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java @@ -4,7 +4,7 @@ import java.util.List; /** * @Description:设备录像信息bean - * @author: swwheihei + * @author: songww * @date: 2020年5月8日 下午2:05:56 */ public class RecordInfo { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java index fbcbf96..484c25e 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.bean; /** * @Description:设备录像bean - * @author: swwheihei + * @author: songww * @date: 2020年5月8日 下午2:06:54 */ public class RecordItem { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java index 60998ea..437e7de 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; /** * @Description:设备离在线状态检测器,用于检测设备状态 - * @author: swwheihei + * @author: songww * @date: 2020年5月13日 下午2:40:29 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java index ebf0430..c6f5d44 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent; /** * @Description:Event事件通知推送器,支持推送在线事件、离线事件 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 上午11:30:50 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java index 4b5e571..9f53d64 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher; /** * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 上午11:35:46 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java index 5553106..d2f612a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java @@ -4,7 +4,7 @@ import org.springframework.context.ApplicationEvent; /** * @Description:TODO(这里用一句话描述这个类的作用) - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 上午11:33:13 */ public class OfflineEvent extends ApplicationEvent { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java index 3eeebef..faa89fa 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; * @Description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源: * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor} * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener} - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午1:51:23 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java index 86eddc1..afc6751 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java @@ -4,7 +4,7 @@ import org.springframework.context.ApplicationEvent; /** * @Description:TODO(这里用一句话描述这个类的作用) - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 上午11:32:56 */ public class OnlineEvent extends ApplicationEvent { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java index ec7ff88..4f8d6ab 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; * @Description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源: * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor} * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor} - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午1:51:23 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java index b0fb561..d524fb0 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.utils.SpringBeanFactory; /** * @Description:SIP信令中的SSRC工具类。SSRC值由10位十进制整数组成的字符串,第一位为0代表实况,为1则代表回放;第二位至第六位由监控域ID的第4位到第8位组成;最后4位为不重复的4个整数 - * @author: swwheihei + * @author: songww * @date: 2020年5月10日 上午11:57:57 */ public class SsrcUtil { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java index 4a4a538..f8b9350 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java @@ -8,7 +8,7 @@ import org.springframework.stereotype.Component; /** * @Description:视频流session管理器,管理视频预览、预览回放的通信句柄 - * @author: swwheihei + * @author: songww * @date: 2020年5月13日 下午4:03:02 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java index a211b6e..b809696 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java @@ -26,7 +26,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcess /** * @Description:TODO(这里用一句话描述这个类的作用) - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午4:24:37 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java index 7c5cbc1..f9c8d25 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java @@ -10,7 +10,7 @@ import org.springframework.web.context.request.async.DeferredResult; /** * @Description:TODO(这里用一句话描述这个类的作用) - * @author: swwheihei + * @author: songww * @date: 2020年5月8日 下午7:59:05 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java index fcf7e7a..ac95f75 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.callback; /** * @Description:TODO(这里用一句话描述这个类的作用) - * @author: swwheihei + * @author: songww * @date: 2020年5月8日 下午1:09:18 */ public class RequestMessage { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index db93230..8b190d5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; /** * @Description:设备能力接口,用于定义设备的控制、查询能力 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午9:16:34 */ public interface ISIPCommander { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index 3270c57..7a95268 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -25,7 +25,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Host; /** * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 上午9:29:02 */ @Component @@ -79,7 +79,8 @@ public class SIPRequestHeaderProvider { SipURI requestLine = layer.getAddressFactory().createSipURI(channelId, host.getAddress()); //via ArrayList viaHeaders = new ArrayList(); - ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); + // ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); + ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag); viaHeader.setRPort(); viaHeaders.add(viaHeader); //from @@ -108,6 +109,7 @@ public class SIPRequestHeaderProvider { request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort())); + // Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort())); request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress)); ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP"); @@ -122,7 +124,8 @@ public class SIPRequestHeaderProvider { SipURI requestLine = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress()); //via ArrayList viaHeaders = new ArrayList(); - ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); + // ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); + ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag); viaHeader.setRPort(); viaHeaders.add(viaHeader); //from @@ -151,6 +154,7 @@ public class SIPRequestHeaderProvider { request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort())); + // Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort())); request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress)); ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5c13162..96618d0 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -7,10 +7,13 @@ import javax.sip.Dialog; import javax.sip.InvalidArgumentException; import javax.sip.SipException; import javax.sip.TransactionDoesNotExistException; +import javax.sip.address.Address; +import javax.sip.address.SipURI; import javax.sip.header.ViaHeader; import javax.sip.message.Request; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.security.SecurityProperties.Headers; import org.springframework.stereotype.Component; import com.genersoft.iot.vmp.conf.SipConfig; @@ -21,9 +24,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; import com.genersoft.iot.vmp.gb28181.utils.DateUtil; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + /** * @Description:设备能力接口,用于定义设备的控制、查询能力 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午9:22:48 */ @Component @@ -94,6 +100,49 @@ public class SIPCommander implements ISIPCommander { return ptzCmd(device, channelId, 0, 0, inOut, 0, zoomSpeed); } + /** + * 云台指令码计算 + * + * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 + * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 + * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 + * @param moveSpeed 镜头移动速度 默认 0XFF (0-255) + * @param zoomSpeed 镜头缩放速度 默认 0X1 (0-255) + */ + public static String cmdString(int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) { + int cmdCode = 0; + if (leftRight == 2) { + cmdCode|=0x01; // 右移 + } else if(leftRight == 1) { + cmdCode|=0x02; // 左移 + } + if (upDown == 2) { + cmdCode|=0x04; // 下移 + } else if(upDown == 1) { + cmdCode|=0x08; // 上移 + } + if (inOut == 2) { + cmdCode |= 0x10; // 放大 + } else if(inOut == 1) { + cmdCode |= 0x20; // 缩小 + } + StringBuilder builder = new StringBuilder("A50F01"); + String strTmp; + strTmp = String.format("%02X", cmdCode); + builder.append(strTmp, 0, 2); + strTmp = String.format("%02X", moveSpeed); + builder.append(strTmp, 0, 2); + builder.append(strTmp, 0, 2); + strTmp = String.format("%X", zoomSpeed); + builder.append(strTmp, 0, 1).append("0"); + //计算校验码 + int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + moveSpeed + moveSpeed + (zoomSpeed /*<< 4*/ & 0XF0)) % 0X100; + strTmp = String.format("%02X", checkCode); + builder.append(strTmp, 0, 2); + return builder.toString(); +} + + /** * 云台控制,支持方向与缩放控制 * @@ -109,13 +158,14 @@ public class SIPCommander implements ISIPCommander { public boolean ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) { try { + String cmdStr= cmdString(leftRight, upDown, inOut, moveSpeed, zoomSpeed); StringBuffer ptzXml = new StringBuffer(200); ptzXml.append(""); ptzXml.append(""); ptzXml.append("DeviceControl"); ptzXml.append("" + (int)((Math.random()*9+1)*100000) + ""); ptzXml.append("" + channelId + ""); - ptzXml.append("" + ""); + ptzXml.append("" + cmdStr + ""); ptzXml.append(""); ptzXml.append(""); ptzXml.append(""); @@ -123,7 +173,6 @@ public class SIPCommander implements ISIPCommander { Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); transmitRequest(device, request); - return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); @@ -245,6 +294,13 @@ public class SIPCommander implements ISIPCommander { return; } Request byeRequest = dialog.createRequest(Request.BYE); + SipURI byeURI = (SipURI) byeRequest.getRequestURI(); + String vh = transaction.getRequest().getHeader(ViaHeader.NAME).toString(); + Pattern p = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)"); + Matcher matcher = p.matcher(vh); + if (matcher.find()) { + byeURI.setHost(matcher.group(1)); + } ViaHeader viaHeader = (ViaHeader) byeRequest.getHeader(ViaHeader.NAME); String protocol = viaHeader.getTransport().toUpperCase(); ClientTransaction clientTransaction = null; @@ -258,6 +314,8 @@ public class SIPCommander implements ISIPCommander { e.printStackTrace(); } catch (SipException e) { e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java index 8b8475c..53e0ed0 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; /** * @Description:处理接收IPCamera发来的SIP协议请求消息 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午4:42:22 */ public interface ISIPRequestProcessor { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java index 44457e8..7a5b25d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java @@ -16,7 +16,7 @@ import gov.nist.javax.sip.header.CSeq; /** * @Description:ACK请求处理器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:31:45 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java index 0c17364..716f482 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; /** * @Description: BYE请求处理器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:32:05 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java index 7b6cc31..d463af4 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; /** * @Description:CANCEL请求处理器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:32:23 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java index d3d94ee..0de32c9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; /** * @Description:处理INVITE请求 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午4:43:52 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java index 30d53bf..f5c3c8b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java @@ -43,7 +43,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; /** * @Description:MESSAGE请求处理器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:32:41 */ @Component @@ -100,6 +100,7 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { Request request = evt.getRequest(); SAXReader reader = new SAXReader(); + reader.setEncoding("gbk"); Document xml; try { xml = reader.read(new ByteArrayInputStream(request.getRawContent())); @@ -375,7 +376,7 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { private Element getRootElement(RequestEvent evt) throws DocumentException { Request request = evt.getRequest(); SAXReader reader = new SAXReader(); - reader.setEncoding("GB2312"); + reader.setEncoding("gbk"); Document xml = reader.read(new ByteArrayInputStream(request.getRawContent())); return xml.getRootElement(); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java index b27c032..e516767 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; /** * @Description:暂不支持的消息请求处理器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:32:59 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java index 7f07406..ca1ba5d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java @@ -38,7 +38,7 @@ import gov.nist.javax.sip.header.Expires; /** * @Description:收到注册请求 处理 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午4:47:25 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java index b2f1008..b0c05a8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java @@ -17,7 +17,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; /** * @Description:SUBSCRIBE请求处理器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:31:20 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java index afa1057..458158b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java @@ -1,5 +1,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.response; +import java.text.ParseException; + import javax.sip.ResponseEvent; import com.genersoft.iot.vmp.conf.SipConfig; @@ -7,11 +9,11 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; /** * @Description:处理接收IPCamera发来的SIP协议响应消息 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午4:42:22 */ public interface ISIPResponseProcessor { - public void process(ResponseEvent evt, SipLayer layer, SipConfig config); + public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java index 53bc8f7..2efa139 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; /** * @Description: BYE请求响应器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:32:05 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java index c6fd9b3..1ce6f43 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; /** * @Description:CANCEL响应处理器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:32:23 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java index 9bc67d2..669b360 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl; import java.text.ParseException; -import javax.sip.ClientTransaction; import javax.sip.Dialog; import javax.sip.InvalidArgumentException; import javax.sip.ResponseEvent; @@ -22,57 +21,76 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; -/** - * @Description:处理INVITE响应 - * @author: swwheihei - * @date: 2020年5月3日 下午4:43:52 + +/** + * @Description:处理INVITE响应 + * @author: songww + * @date: 2020年5月3日 下午4:43:52 */ @Component public class InviteResponseProcessor implements ISIPResponseProcessor { private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class); - + /** * 处理invite响应 * - * @param evt - * 响应消息 - */ + * @param evt 响应消息 + * @throws ParseException + */ @Override - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) { + public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException { try { Response response = evt.getResponse(); int statusCode = response.getStatusCode(); - //trying不会回复 - if(statusCode == Response.TRYING){ - + // trying不会回复 + if (statusCode == Response.TRYING) { } - //成功响应 - //下发ack - if(statusCode == Response.OK){ -// ClientTransaction clientTransaction = evt.getClientTransaction(); -// if(clientTransaction == null){ -// logger.error("回复ACK时,clientTransaction为null >>> {}",response); -// return; -// } -// Dialog clientDialog = clientTransaction.getDialog(); -// -// CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); -// long cseqId = clientCSeqHeader.getSeqNumber(); -// /* -// createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 -// 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 -// 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 -// */ -// Request ackRequest = clientDialog.createAck(cseqId); -// SipURI requestURI = (SipURI) ackRequest.getRequestURI(); -// ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); -// requestURI.setHost(viaHeader.getHost()); -// requestURI.setPort(viaHeader.getPort()); -// clientDialog.sendAck(ackRequest); - + // 成功响应 + // 下发ack + if (statusCode == Response.OK) { + // ClientTransaction clientTransaction = evt.getClientTransaction(); + // if(clientTransaction == null){ + // logger.error("回复ACK时,clientTransaction为null >>> {}",response); + // return; + // } + // Dialog clientDialog = clientTransaction.getDialog(); + + // CSeqHeader clientCSeqHeader = (CSeqHeader) + // response.getHeader(CSeqHeader.NAME); + // long cseqId = clientCSeqHeader.getSeqNumber(); + // /* + // createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 + // 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 + // 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 + // */ + // Request ackRequest = clientDialog.createAck(cseqId); + // SipURI requestURI = (SipURI) ackRequest.getRequestURI(); + // ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); + // try { + // requestURI.setHost(viaHeader.getHost()); + // } catch (Exception e) { + // e.printStackTrace(); + // } + // requestURI.setPort(viaHeader.getPort()); + // clientDialog.sendAck(ackRequest); + Dialog dialog = evt.getDialog(); - Request reqAck =dialog.createAck(1L); + CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); + Request reqAck = dialog.createAck(cseq.getSeqNumber()); + + SipURI requestURI = (SipURI) reqAck.getRequestURI(); + ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); + // String viaHost =viaHeader.getHost(); + //getHost()函数取回的IP地址是“[xxx.xxx.xxx.xxx:yyyy]”的格式,需用正则表达式截取为“xxx.xxx.xxx.xxx"格式 + // Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+"); + // Matcher matcher = p.matcher(viaHeader.getHost()); + // if (matcher.find()) { + // requestURI.setHost(matcher.group()); + // } + requestURI.setHost(viaHeader.getHost()); + requestURI.setPort(viaHeader.getPort()); + reqAck.setRequestURI(requestURI); dialog.sendAck(reqAck); } } catch (InvalidArgumentException | SipException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java index 1631440..a0a6fa4 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; /** * @Description:暂不支持的消息响应处理器 - * @author: swwheihei + * @author: songww * @date: 2020年5月3日 下午5:32:59 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java index 195b7e3..fb22948 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java @@ -7,7 +7,7 @@ import java.util.Locale; /** * @Description:时间工具类,主要处理ISO 8601格式转换 - * @author: swwheihei + * @author: songww * @date: 2020年5月8日 下午3:24:42 */ public class DateUtil { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 288ac36..25f000b 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -18,11 +18,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; /** * @Description:针对 ZLMediaServer的hook事件监听 - * @author: swwheihei + * @author: songww * @date: 2020年5月8日 上午10:46:48 */ @RestController -@RequestMapping("/hook/zlm") +@RequestMapping("/index/hook") public class ZLMHttpHookListener { private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java index 47aa362..d9e40e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; /** * @Description:视频设备数据存储接口 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午2:14:31 */ public interface IVideoManagerStorager { diff --git a/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java b/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java index 70bdad7..282c3e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.conf.VManagerConfig; /** * @Description:视频设备数据存储工厂,根据存储策略,返回对应的存储器 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午2:15:16 */ @Component diff --git a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java index 59ecba0..8adc73c 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; /** * @Description:视频设备数据存储-jdbc实现 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午2:28:12 */ @Component("jdbcStorager") diff --git a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java index d6e4603..54fa692 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; /** * @Description:视频设备数据存储-redis实现 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午2:31:42 */ @Component("redisStorager") diff --git a/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java b/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java index 3fe7dcc..273f5fb 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java @@ -7,7 +7,7 @@ import org.springframework.stereotype.Component; /** * @Description:spring bean获取工厂,获取spring中的已初始化的bean - * @author: swwheihei + * @author: songww * @date: 2019年6月25日 下午4:51:52 * */ diff --git a/src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java b/src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java index 411f962..590296a 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java @@ -10,7 +10,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature; /** * @Description:使用fastjson实现redis的序列化 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午8:40:11 */ public class FastJsonRedisSerializer implements RedisSerializer { diff --git a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java index f1d1673..a03f9aa 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java @@ -13,7 +13,7 @@ import org.springframework.util.CollectionUtils; /** * @Description:Redis工具类 - * @author: swwheihei + * @author: songww * @date: 2020年5月6日 下午8:27:29 */ @Component diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index bec0e00..7e6bc40 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -26,7 +26,8 @@ spring: server: port: 8080 sip: - ip: 10.200.64.63 +# ip: 10.200.64.63 + ip: 192.168.0.102 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) # 后两位为行业编码,定义参照附录D.3 @@ -34,7 +35,8 @@ sip: domain: 3701020049 id: 37010200492000000001 # 默认设备认证密码,后续扩展使用设备单独密码 - password: admin + password: admin123 media: - ip: 10.200.64.88 +# ip: 10.200.64.88 + ip: 192.168.0.102 port: 10000 \ No newline at end of file diff --git a/wikis/images/核心流程.png b/wikis/images/核心流程.png index 34eeeee..3d9f207 100644 Binary files a/wikis/images/核心流程.png and b/wikis/images/核心流程.png differ