Commit 29710b7cc154191ae56acf6af32ec70241886e78
Merge branch 'master' of https://github.com/swwheihei/wvp.git
Conflicts: src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
Showing
49 changed files
with
461 additions
and
343 deletions
LICENSE
0 → 100644
| 1 | +MIT License | |
| 2 | + | |
| 3 | +Copyright (c) 2020 swwhaha | |
| 4 | + | |
| 5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 6 | +of this software and associated documentation files (the "Software"), to deal | |
| 7 | +in the Software without restriction, including without limitation the rights | |
| 8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 9 | +copies of the Software, and to permit persons to whom the Software is | |
| 10 | +furnished to do so, subject to the following conditions: | |
| 11 | + | |
| 12 | +The above copyright notice and this permission notice shall be included in all | |
| 13 | +copies or substantial portions of the Software. | |
| 14 | + | |
| 15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| 21 | +SOFTWARE. | ... | ... |
pom.xml
| ... | ... | @@ -39,7 +39,7 @@ |
| 39 | 39 | </dependency> |
| 40 | 40 | <dependency> |
| 41 | 41 | <groupId>org.springframework.boot</groupId> |
| 42 | - <artifactId>spring-boot-starter-undertow</artifactId> | |
| 42 | + <artifactId>spring-boot-starter-tomcat</artifactId> | |
| 43 | 43 | </dependency> |
| 44 | 44 | <dependency> |
| 45 | 45 | <groupId>org.springframework.boot</groupId> |
| ... | ... | @@ -127,7 +127,7 @@ |
| 127 | 127 | <dependency> |
| 128 | 128 | <groupId>org.dom4j</groupId> |
| 129 | 129 | <artifactId>dom4j</artifactId> |
| 130 | - <version>2.1.1</version> | |
| 130 | + <version>2.1.3</version> | |
| 131 | 131 | </dependency> |
| 132 | 132 | <dependency> |
| 133 | 133 | <groupId>com.google.code.gson</groupId> | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
| ... | ... | @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; |
| 13 | 13 | |
| 14 | 14 | /** |
| 15 | 15 | * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置 |
| 16 | - * @author: swwheihei | |
| 16 | + * @author: songww | |
| 17 | 17 | * @date: 2019年5月30日 上午10:58:25 |
| 18 | 18 | * |
| 19 | 19 | */ | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| 1 | -package com.genersoft.iot.vmp.gb28181; | |
| 2 | - | |
| 3 | -import java.util.Properties; | |
| 4 | - | |
| 5 | -import javax.annotation.PostConstruct; | |
| 6 | -import javax.sip.DialogTerminatedEvent; | |
| 7 | -import javax.sip.IOExceptionEvent; | |
| 8 | -import javax.sip.ListeningPoint; | |
| 9 | -import javax.sip.RequestEvent; | |
| 10 | -import javax.sip.ResponseEvent; | |
| 11 | -import javax.sip.ServerTransaction; | |
| 12 | -import javax.sip.SipFactory; | |
| 13 | -import javax.sip.SipListener; | |
| 14 | -import javax.sip.SipProvider; | |
| 15 | -import javax.sip.SipStack; | |
| 16 | -import javax.sip.TimeoutEvent; | |
| 17 | -import javax.sip.TransactionAlreadyExistsException; | |
| 18 | -import javax.sip.TransactionTerminatedEvent; | |
| 19 | -import javax.sip.TransactionUnavailableException; | |
| 20 | -import javax.sip.address.AddressFactory; | |
| 21 | -import javax.sip.header.HeaderFactory; | |
| 22 | -import javax.sip.header.ViaHeader; | |
| 23 | -import javax.sip.message.MessageFactory; | |
| 24 | -import javax.sip.message.Request; | |
| 25 | -import javax.sip.message.Response; | |
| 26 | - | |
| 27 | -import org.slf4j.Logger; | |
| 28 | -import org.slf4j.LoggerFactory; | |
| 29 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 30 | -import org.springframework.stereotype.Component; | |
| 31 | - | |
| 32 | -import com.genersoft.iot.vmp.conf.SipConfig; | |
| 33 | -import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; | |
| 34 | -import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; | |
| 35 | -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | |
| 36 | - | |
| 37 | -import gov.nist.javax.sip.SipStackImpl; | |
| 38 | - | |
| 39 | -@Component | |
| 40 | -public class SipLayer implements SipListener, Runnable { | |
| 41 | - | |
| 42 | - private final static Logger logger = LoggerFactory.getLogger(SipLayer.class); | |
| 43 | - | |
| 44 | - @Autowired | |
| 45 | - private SipConfig sipConfig; | |
| 46 | - | |
| 47 | - private SipProvider tcpSipProvider; | |
| 48 | - | |
| 49 | - private SipProvider udpSipProvider; | |
| 50 | - | |
| 51 | - @Autowired | |
| 52 | - private SIPProcessorFactory processorFactory; | |
| 53 | - | |
| 54 | - private SipStack sipStack; | |
| 55 | - | |
| 56 | - private AddressFactory addressFactory; | |
| 57 | - private HeaderFactory headerFactory; | |
| 58 | - private MessageFactory messageFactory; | |
| 59 | - | |
| 60 | - @PostConstruct | |
| 61 | - private void initSipServer() { | |
| 62 | - Thread thread=new Thread(this); | |
| 63 | - thread.setDaemon(true); | |
| 64 | - thread.setName("sip server thread start"); | |
| 65 | - thread.start(); | |
| 66 | - } | |
| 67 | - | |
| 68 | - @Override | |
| 69 | - public void run() { | |
| 70 | - SipFactory sipFactory = SipFactory.getInstance(); | |
| 71 | - sipFactory.setPathName("gov.nist"); | |
| 72 | - try { | |
| 73 | - headerFactory = sipFactory.createHeaderFactory(); | |
| 74 | - | |
| 75 | - addressFactory = sipFactory.createAddressFactory(); | |
| 76 | - messageFactory = sipFactory.createMessageFactory(); | |
| 77 | - | |
| 78 | - Properties properties = new Properties(); | |
| 79 | - properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); | |
| 80 | - properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp()); | |
| 81 | - properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false"); | |
| 82 | - /** | |
| 83 | - * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE = | |
| 84 | - * 0; public static final int TRACE_MESSAGES = 16; public static final int | |
| 85 | - * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32; | |
| 86 | - */ | |
| 87 | - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0"); | |
| 88 | - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log"); | |
| 89 | - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log"); | |
| 90 | - sipStack = (SipStackImpl) sipFactory.createSipStack(properties); | |
| 91 | - | |
| 92 | - startTcpListener(); | |
| 93 | - startUdpListener(); | |
| 94 | - } catch (Exception e) { | |
| 95 | - logger.error("Sip Server 启动失败! port {" + sipConfig.getSipPort() + "}"); | |
| 96 | - e.printStackTrace(); | |
| 97 | - } | |
| 98 | - logger.info("Sip Server 启动成功 port {" + sipConfig.getSipPort() + "}"); | |
| 99 | - } | |
| 100 | - | |
| 101 | - private void startTcpListener() throws Exception { | |
| 102 | - ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "TCP"); | |
| 103 | - tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); | |
| 104 | - tcpSipProvider.addSipListener(this); | |
| 105 | - } | |
| 106 | - | |
| 107 | - private void startUdpListener() throws Exception { | |
| 108 | - ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP"); | |
| 109 | - udpSipProvider = sipStack.createSipProvider(udpListeningPoint); | |
| 110 | - udpSipProvider.addSipListener(this); | |
| 111 | - } | |
| 112 | - | |
| 113 | - /** | |
| 114 | - * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a | |
| 115 | - * new request arrives. | |
| 116 | - */ | |
| 117 | - @Override | |
| 118 | - public void processRequest(RequestEvent evt) { | |
| 119 | - ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt); | |
| 120 | - processor.process(evt, this); | |
| 121 | - } | |
| 122 | - | |
| 123 | - @Override | |
| 124 | - public void processResponse(ResponseEvent evt) { | |
| 125 | - Response response = evt.getResponse(); | |
| 126 | - int status = response.getStatusCode(); | |
| 127 | - if ((status >= 200) && (status < 300)) { // Success! | |
| 128 | - ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); | |
| 129 | - processor.process(evt, this, sipConfig); | |
| 130 | - } else { | |
| 131 | - logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getContent().toString()); | |
| 132 | - } | |
| 133 | - // trying不会回复 | |
| 134 | - if (status == Response.TRYING) { | |
| 135 | - | |
| 136 | - } | |
| 137 | - } | |
| 138 | - | |
| 139 | - /** | |
| 140 | - * <p> | |
| 141 | - * Title: processTimeout | |
| 142 | - * </p> | |
| 143 | - * <p> | |
| 144 | - * Description: | |
| 145 | - * </p> | |
| 146 | - * | |
| 147 | - * @param timeoutEvent | |
| 148 | - */ | |
| 149 | - @Override | |
| 150 | - public void processTimeout(TimeoutEvent timeoutEvent) { | |
| 151 | - // TODO Auto-generated method stub | |
| 152 | - | |
| 153 | - } | |
| 154 | - | |
| 155 | - /** | |
| 156 | - * <p> | |
| 157 | - * Title: processIOException | |
| 158 | - * </p> | |
| 159 | - * <p> | |
| 160 | - * Description: | |
| 161 | - * </p> | |
| 162 | - * | |
| 163 | - * @param exceptionEvent | |
| 164 | - */ | |
| 165 | - @Override | |
| 166 | - public void processIOException(IOExceptionEvent exceptionEvent) { | |
| 167 | - // TODO Auto-generated method stub | |
| 168 | - | |
| 169 | - } | |
| 170 | - | |
| 171 | - /** | |
| 172 | - * <p> | |
| 173 | - * Title: processTransactionTerminated | |
| 174 | - * </p> | |
| 175 | - * <p> | |
| 176 | - * Description: | |
| 177 | - * </p> | |
| 178 | - * | |
| 179 | - * @param transactionTerminatedEvent | |
| 180 | - */ | |
| 181 | - @Override | |
| 182 | - public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { | |
| 183 | - // TODO Auto-generated method stub | |
| 184 | - | |
| 185 | - } | |
| 186 | - | |
| 187 | - /** | |
| 188 | - * <p> | |
| 189 | - * Title: processDialogTerminated | |
| 190 | - * </p> | |
| 191 | - * <p> | |
| 192 | - * Description: | |
| 193 | - * </p> | |
| 194 | - * | |
| 195 | - * @param dialogTerminatedEvent | |
| 196 | - */ | |
| 197 | - @Override | |
| 198 | - public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) { | |
| 199 | - // TODO Auto-generated method stub | |
| 200 | - | |
| 201 | - } | |
| 202 | - | |
| 203 | - public ServerTransaction getServerTransaction(RequestEvent evt) { | |
| 204 | - Request request = evt.getRequest(); | |
| 205 | - ServerTransaction serverTransaction = evt.getServerTransaction(); | |
| 206 | - // 判断TCP还是UDP | |
| 207 | - boolean isTcp = false; | |
| 208 | - ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | |
| 209 | - String transport = reqViaHeader.getTransport(); | |
| 210 | - if (transport.equals("TCP")) { | |
| 211 | - isTcp = true; | |
| 212 | - } | |
| 213 | - | |
| 214 | - if (serverTransaction == null) { | |
| 215 | - try { | |
| 216 | - if (isTcp) { | |
| 217 | - serverTransaction = tcpSipProvider.getNewServerTransaction(request); | |
| 218 | - } else { | |
| 219 | - serverTransaction = udpSipProvider.getNewServerTransaction(request); | |
| 220 | - } | |
| 221 | - } catch (TransactionAlreadyExistsException e) { | |
| 222 | - e.printStackTrace(); | |
| 223 | - } catch (TransactionUnavailableException e) { | |
| 224 | - e.printStackTrace(); | |
| 225 | - } | |
| 226 | - } | |
| 227 | - return serverTransaction; | |
| 228 | - } | |
| 229 | - | |
| 230 | - public AddressFactory getAddressFactory() { | |
| 231 | - return addressFactory; | |
| 232 | - } | |
| 233 | - | |
| 234 | - public HeaderFactory getHeaderFactory() { | |
| 235 | - return headerFactory; | |
| 236 | - } | |
| 237 | - | |
| 238 | - public MessageFactory getMessageFactory() { | |
| 239 | - return messageFactory; | |
| 240 | - } | |
| 241 | - | |
| 242 | - public SipProvider getTcpSipProvider() { | |
| 243 | - return tcpSipProvider; | |
| 244 | - } | |
| 245 | - | |
| 246 | - public SipProvider getUdpSipProvider() { | |
| 247 | - return udpSipProvider; | |
| 248 | - } | |
| 249 | - | |
| 250 | -} | |
| 1 | +package com.genersoft.iot.vmp.gb28181; | |
| 2 | + | |
| 3 | +import java.text.ParseException; | |
| 4 | +import java.util.Properties; | |
| 5 | + | |
| 6 | +import javax.annotation.PostConstruct; | |
| 7 | +import javax.sip.DialogTerminatedEvent; | |
| 8 | +import javax.sip.IOExceptionEvent; | |
| 9 | +import javax.sip.ListeningPoint; | |
| 10 | +import javax.sip.RequestEvent; | |
| 11 | +import javax.sip.ResponseEvent; | |
| 12 | +import javax.sip.ServerTransaction; | |
| 13 | +import javax.sip.SipFactory; | |
| 14 | +import javax.sip.SipListener; | |
| 15 | +import javax.sip.SipProvider; | |
| 16 | +import javax.sip.SipStack; | |
| 17 | +import javax.sip.TimeoutEvent; | |
| 18 | +import javax.sip.TransactionAlreadyExistsException; | |
| 19 | +import javax.sip.TransactionTerminatedEvent; | |
| 20 | +import javax.sip.TransactionUnavailableException; | |
| 21 | +import javax.sip.address.AddressFactory; | |
| 22 | +import javax.sip.header.HeaderFactory; | |
| 23 | +import javax.sip.header.ViaHeader; | |
| 24 | +import javax.sip.message.MessageFactory; | |
| 25 | +import javax.sip.message.Request; | |
| 26 | +import javax.sip.message.Response; | |
| 27 | + | |
| 28 | +import org.slf4j.Logger; | |
| 29 | +import org.slf4j.LoggerFactory; | |
| 30 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 31 | +import org.springframework.stereotype.Component; | |
| 32 | + | |
| 33 | +import com.genersoft.iot.vmp.conf.SipConfig; | |
| 34 | +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; | |
| 35 | +import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; | |
| 36 | +import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | |
| 37 | + | |
| 38 | +import gov.nist.javax.sip.SipStackImpl; | |
| 39 | + | |
| 40 | +@Component | |
| 41 | +public class SipLayer implements SipListener, Runnable { | |
| 42 | + | |
| 43 | + private final static Logger logger = LoggerFactory.getLogger(SipLayer.class); | |
| 44 | + | |
| 45 | + @Autowired | |
| 46 | + private SipConfig sipConfig; | |
| 47 | + | |
| 48 | + private SipProvider tcpSipProvider; | |
| 49 | + | |
| 50 | + private SipProvider udpSipProvider; | |
| 51 | + | |
| 52 | + @Autowired | |
| 53 | + private SIPProcessorFactory processorFactory; | |
| 54 | + | |
| 55 | + private SipStack sipStack; | |
| 56 | + | |
| 57 | + private AddressFactory addressFactory; | |
| 58 | + private HeaderFactory headerFactory; | |
| 59 | + private MessageFactory messageFactory; | |
| 60 | + | |
| 61 | + @PostConstruct | |
| 62 | + private void initSipServer() { | |
| 63 | + Thread thread = new Thread(this); | |
| 64 | + thread.setDaemon(true); | |
| 65 | + thread.setName("sip server thread start"); | |
| 66 | + thread.start(); | |
| 67 | + } | |
| 68 | + | |
| 69 | + @Override | |
| 70 | + public void run() { | |
| 71 | + SipFactory sipFactory = SipFactory.getInstance(); | |
| 72 | + sipFactory.setPathName("gov.nist"); | |
| 73 | + try { | |
| 74 | + headerFactory = sipFactory.createHeaderFactory(); | |
| 75 | + | |
| 76 | + addressFactory = sipFactory.createAddressFactory(); | |
| 77 | + messageFactory = sipFactory.createMessageFactory(); | |
| 78 | + | |
| 79 | + Properties properties = new Properties(); | |
| 80 | + properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); | |
| 81 | + properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp()); | |
| 82 | + properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false"); | |
| 83 | + /** | |
| 84 | + * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE = | |
| 85 | + * 0; public static final int TRACE_MESSAGES = 16; public static final int | |
| 86 | + * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32; | |
| 87 | + */ | |
| 88 | + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); | |
| 89 | + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log"); | |
| 90 | + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log"); | |
| 91 | + sipStack = (SipStackImpl) sipFactory.createSipStack(properties); | |
| 92 | + | |
| 93 | + startTcpListener(); | |
| 94 | + startUdpListener(); | |
| 95 | + } catch (Exception e) { | |
| 96 | + logger.error("Sip Server 启动失败! port {" + sipConfig.getSipPort() + "}"); | |
| 97 | + e.printStackTrace(); | |
| 98 | + } | |
| 99 | + logger.info("Sip Server 启动成功 port {" + sipConfig.getSipPort() + "}"); | |
| 100 | + } | |
| 101 | + | |
| 102 | + private void startTcpListener() throws Exception { | |
| 103 | + ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), | |
| 104 | + "TCP"); | |
| 105 | + tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); | |
| 106 | + tcpSipProvider.addSipListener(this); | |
| 107 | + } | |
| 108 | + | |
| 109 | + private void startUdpListener() throws Exception { | |
| 110 | + ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), | |
| 111 | + "UDP"); | |
| 112 | + udpSipProvider = sipStack.createSipProvider(udpListeningPoint); | |
| 113 | + udpSipProvider.addSipListener(this); | |
| 114 | + } | |
| 115 | + | |
| 116 | + /** | |
| 117 | + * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a | |
| 118 | + * new request arrives. | |
| 119 | + */ | |
| 120 | + @Override | |
| 121 | + public void processRequest(RequestEvent evt) { | |
| 122 | + ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt); | |
| 123 | + processor.process(evt, this); | |
| 124 | + } | |
| 125 | + | |
| 126 | + @Override | |
| 127 | + public void processResponse(ResponseEvent evt) { | |
| 128 | + Response response = evt.getResponse(); | |
| 129 | + int status = response.getStatusCode(); | |
| 130 | + if ((status >= 200) && (status < 300)) { // Success! | |
| 131 | + ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); | |
| 132 | + try { | |
| 133 | + processor.process(evt, this, sipConfig); | |
| 134 | + } catch (ParseException e) { | |
| 135 | + // TODO Auto-generated catch block | |
| 136 | + e.printStackTrace(); | |
| 137 | + } | |
| 138 | + // } else if (status == Response.TRYING) { | |
| 139 | + // trying不会回复 | |
| 140 | + } else if ((status >= 100) && (status < 200)) { | |
| 141 | + // 增加其它无需回复的响应,如101、180等 | |
| 142 | + } else { | |
| 143 | + logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/); | |
| 144 | + } | |
| 145 | + // trying不会回复 | |
| 146 | + // if (status == Response.TRYING) { | |
| 147 | + | |
| 148 | + // } | |
| 149 | + } | |
| 150 | + | |
| 151 | + /** | |
| 152 | + * <p> | |
| 153 | + * Title: processTimeout | |
| 154 | + * </p> | |
| 155 | + * <p> | |
| 156 | + * Description: | |
| 157 | + * </p> | |
| 158 | + * | |
| 159 | + * @param timeoutEvent | |
| 160 | + */ | |
| 161 | + @Override | |
| 162 | + public void processTimeout(TimeoutEvent timeoutEvent) { | |
| 163 | + // TODO Auto-generated method stub | |
| 164 | + | |
| 165 | + } | |
| 166 | + | |
| 167 | + /** | |
| 168 | + * <p> | |
| 169 | + * Title: processIOException | |
| 170 | + * </p> | |
| 171 | + * <p> | |
| 172 | + * Description: | |
| 173 | + * </p> | |
| 174 | + * | |
| 175 | + * @param exceptionEvent | |
| 176 | + */ | |
| 177 | + @Override | |
| 178 | + public void processIOException(IOExceptionEvent exceptionEvent) { | |
| 179 | + // TODO Auto-generated method stub | |
| 180 | + | |
| 181 | + } | |
| 182 | + | |
| 183 | + /** | |
| 184 | + * <p> | |
| 185 | + * Title: processTransactionTerminated | |
| 186 | + * </p> | |
| 187 | + * <p> | |
| 188 | + * Description: | |
| 189 | + * </p> | |
| 190 | + * | |
| 191 | + * @param transactionTerminatedEvent | |
| 192 | + */ | |
| 193 | + @Override | |
| 194 | + public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { | |
| 195 | + // TODO Auto-generated method stub | |
| 196 | + | |
| 197 | + } | |
| 198 | + | |
| 199 | + /** | |
| 200 | + * <p> | |
| 201 | + * Title: processDialogTerminated | |
| 202 | + * </p> | |
| 203 | + * <p> | |
| 204 | + * Description: | |
| 205 | + * </p> | |
| 206 | + * | |
| 207 | + * @param dialogTerminatedEvent | |
| 208 | + */ | |
| 209 | + @Override | |
| 210 | + public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) { | |
| 211 | + // TODO Auto-generated method stub | |
| 212 | + | |
| 213 | + } | |
| 214 | + | |
| 215 | + public ServerTransaction getServerTransaction(RequestEvent evt) { | |
| 216 | + Request request = evt.getRequest(); | |
| 217 | + ServerTransaction serverTransaction = evt.getServerTransaction(); | |
| 218 | + // 判断TCP还是UDP | |
| 219 | + boolean isTcp = false; | |
| 220 | + ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | |
| 221 | + String transport = reqViaHeader.getTransport(); | |
| 222 | + if (transport.equals("TCP")) { | |
| 223 | + isTcp = true; | |
| 224 | + } | |
| 225 | + | |
| 226 | + if (serverTransaction == null) { | |
| 227 | + try { | |
| 228 | + if (isTcp) { | |
| 229 | + serverTransaction = tcpSipProvider.getNewServerTransaction(request); | |
| 230 | + } else { | |
| 231 | + serverTransaction = udpSipProvider.getNewServerTransaction(request); | |
| 232 | + } | |
| 233 | + } catch (TransactionAlreadyExistsException e) { | |
| 234 | + e.printStackTrace(); | |
| 235 | + } catch (TransactionUnavailableException e) { | |
| 236 | + e.printStackTrace(); | |
| 237 | + } | |
| 238 | + } | |
| 239 | + return serverTransaction; | |
| 240 | + } | |
| 241 | + | |
| 242 | + public AddressFactory getAddressFactory() { | |
| 243 | + return addressFactory; | |
| 244 | + } | |
| 245 | + | |
| 246 | + public HeaderFactory getHeaderFactory() { | |
| 247 | + return headerFactory; | |
| 248 | + } | |
| 249 | + | |
| 250 | + public MessageFactory getMessageFactory() { | |
| 251 | + return messageFactory; | |
| 252 | + } | |
| 253 | + | |
| 254 | + public SipProvider getTcpSipProvider() { | |
| 255 | + return tcpSipProvider; | |
| 256 | + } | |
| 257 | + | |
| 258 | + public SipProvider getUdpSipProvider() { | |
| 259 | + return udpSipProvider; | |
| 260 | + } | |
| 261 | + | |
| 262 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java
src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java
| ... | ... | @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 14 | 14 | * @Description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源: |
| 15 | 15 | * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor} |
| 16 | 16 | * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener} |
| 17 | - * @author: swwheihei | |
| 17 | + * @author: songww | |
| 18 | 18 | * @date: 2020年5月6日 下午1:51:23 |
| 19 | 19 | */ |
| 20 | 20 | @Component | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java
| ... | ... | @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 14 | 14 | * @Description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源: |
| 15 | 15 | * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor} |
| 16 | 16 | * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor} |
| 17 | - * @author: swwheihei | |
| 17 | + * @author: songww | |
| 18 | 18 | * @date: 2020年5月6日 下午1:51:23 |
| 19 | 19 | */ |
| 20 | 20 | @Component | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java
| ... | ... | @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
| 9 | 9 | |
| 10 | 10 | /** |
| 11 | 11 | * @Description:SIP信令中的SSRC工具类。SSRC值由10位十进制整数组成的字符串,第一位为0代表实况,为1则代表回放;第二位至第六位由监控域ID的第4位到第8位组成;最后4位为不重复的4个整数 |
| 12 | - * @author: swwheihei | |
| 12 | + * @author: songww | |
| 13 | 13 | * @date: 2020年5月10日 上午11:57:57 |
| 14 | 14 | */ |
| 15 | 15 | public class SsrcUtil { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
| ... | ... | @@ -25,7 +25,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Host; |
| 25 | 25 | |
| 26 | 26 | /** |
| 27 | 27 | * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化 |
| 28 | - * @author: swwheihei | |
| 28 | + * @author: songww | |
| 29 | 29 | * @date: 2020年5月6日 上午9:29:02 |
| 30 | 30 | */ |
| 31 | 31 | @Component |
| ... | ... | @@ -79,7 +79,8 @@ public class SIPRequestHeaderProvider { |
| 79 | 79 | SipURI requestLine = layer.getAddressFactory().createSipURI(channelId, host.getAddress()); |
| 80 | 80 | //via |
| 81 | 81 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 82 | - ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); | |
| 82 | + // ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); | |
| 83 | + ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag); | |
| 83 | 84 | viaHeader.setRPort(); |
| 84 | 85 | viaHeaders.add(viaHeader); |
| 85 | 86 | //from |
| ... | ... | @@ -108,6 +109,7 @@ public class SIPRequestHeaderProvider { |
| 108 | 109 | request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); |
| 109 | 110 | |
| 110 | 111 | Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort())); |
| 112 | + // Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort())); | |
| 111 | 113 | request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress)); |
| 112 | 114 | |
| 113 | 115 | ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP"); |
| ... | ... | @@ -122,7 +124,8 @@ public class SIPRequestHeaderProvider { |
| 122 | 124 | SipURI requestLine = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress()); |
| 123 | 125 | //via |
| 124 | 126 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 125 | - ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); | |
| 127 | + // ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); | |
| 128 | + ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag); | |
| 126 | 129 | viaHeader.setRPort(); |
| 127 | 130 | viaHeaders.add(viaHeader); |
| 128 | 131 | //from |
| ... | ... | @@ -151,6 +154,7 @@ public class SIPRequestHeaderProvider { |
| 151 | 154 | request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); |
| 152 | 155 | |
| 153 | 156 | Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort())); |
| 157 | + // Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort())); | |
| 154 | 158 | request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress)); |
| 155 | 159 | |
| 156 | 160 | ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP"); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| ... | ... | @@ -7,10 +7,13 @@ import javax.sip.Dialog; |
| 7 | 7 | import javax.sip.InvalidArgumentException; |
| 8 | 8 | import javax.sip.SipException; |
| 9 | 9 | import javax.sip.TransactionDoesNotExistException; |
| 10 | +import javax.sip.address.Address; | |
| 11 | +import javax.sip.address.SipURI; | |
| 10 | 12 | import javax.sip.header.ViaHeader; |
| 11 | 13 | import javax.sip.message.Request; |
| 12 | 14 | |
| 13 | 15 | import org.springframework.beans.factory.annotation.Autowired; |
| 16 | +import org.springframework.boot.autoconfigure.security.SecurityProperties.Headers; | |
| 14 | 17 | import org.springframework.stereotype.Component; |
| 15 | 18 | |
| 16 | 19 | import com.genersoft.iot.vmp.conf.SipConfig; |
| ... | ... | @@ -21,9 +24,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 21 | 24 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; |
| 22 | 25 | import com.genersoft.iot.vmp.gb28181.utils.DateUtil; |
| 23 | 26 | |
| 27 | +import java.util.regex.Pattern; | |
| 28 | +import java.util.regex.Matcher; | |
| 29 | + | |
| 24 | 30 | /** |
| 25 | 31 | * @Description:设备能力接口,用于定义设备的控制、查询能力 |
| 26 | - * @author: swwheihei | |
| 32 | + * @author: songww | |
| 27 | 33 | * @date: 2020年5月3日 下午9:22:48 |
| 28 | 34 | */ |
| 29 | 35 | @Component |
| ... | ... | @@ -94,6 +100,49 @@ public class SIPCommander implements ISIPCommander { |
| 94 | 100 | return ptzCmd(device, channelId, 0, 0, inOut, 0, zoomSpeed); |
| 95 | 101 | } |
| 96 | 102 | |
| 103 | + /** | |
| 104 | + * 云台指令码计算 | |
| 105 | + * | |
| 106 | + * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 | |
| 107 | + * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 | |
| 108 | + * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 | |
| 109 | + * @param moveSpeed 镜头移动速度 默认 0XFF (0-255) | |
| 110 | + * @param zoomSpeed 镜头缩放速度 默认 0X1 (0-255) | |
| 111 | + */ | |
| 112 | + public static String cmdString(int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) { | |
| 113 | + int cmdCode = 0; | |
| 114 | + if (leftRight == 2) { | |
| 115 | + cmdCode|=0x01; // 右移 | |
| 116 | + } else if(leftRight == 1) { | |
| 117 | + cmdCode|=0x02; // 左移 | |
| 118 | + } | |
| 119 | + if (upDown == 2) { | |
| 120 | + cmdCode|=0x04; // 下移 | |
| 121 | + } else if(upDown == 1) { | |
| 122 | + cmdCode|=0x08; // 上移 | |
| 123 | + } | |
| 124 | + if (inOut == 2) { | |
| 125 | + cmdCode |= 0x10; // 放大 | |
| 126 | + } else if(inOut == 1) { | |
| 127 | + cmdCode |= 0x20; // 缩小 | |
| 128 | + } | |
| 129 | + StringBuilder builder = new StringBuilder("A50F01"); | |
| 130 | + String strTmp; | |
| 131 | + strTmp = String.format("%02X", cmdCode); | |
| 132 | + builder.append(strTmp, 0, 2); | |
| 133 | + strTmp = String.format("%02X", moveSpeed); | |
| 134 | + builder.append(strTmp, 0, 2); | |
| 135 | + builder.append(strTmp, 0, 2); | |
| 136 | + strTmp = String.format("%X", zoomSpeed); | |
| 137 | + builder.append(strTmp, 0, 1).append("0"); | |
| 138 | + //计算校验码 | |
| 139 | + int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + moveSpeed + moveSpeed + (zoomSpeed /*<< 4*/ & 0XF0)) % 0X100; | |
| 140 | + strTmp = String.format("%02X", checkCode); | |
| 141 | + builder.append(strTmp, 0, 2); | |
| 142 | + return builder.toString(); | |
| 143 | +} | |
| 144 | + | |
| 145 | + | |
| 97 | 146 | /** |
| 98 | 147 | * 云台控制,支持方向与缩放控制 |
| 99 | 148 | * |
| ... | ... | @@ -109,13 +158,14 @@ public class SIPCommander implements ISIPCommander { |
| 109 | 158 | public boolean ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed, |
| 110 | 159 | int zoomSpeed) { |
| 111 | 160 | try { |
| 161 | + String cmdStr= cmdString(leftRight, upDown, inOut, moveSpeed, zoomSpeed); | |
| 112 | 162 | StringBuffer ptzXml = new StringBuffer(200); |
| 113 | 163 | ptzXml.append("<?xml version=\"1.0\" ?>"); |
| 114 | 164 | ptzXml.append("<Control>"); |
| 115 | 165 | ptzXml.append("<CmdType>DeviceControl</CmdType>"); |
| 116 | 166 | ptzXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>"); |
| 117 | 167 | ptzXml.append("<DeviceID>" + channelId + "</DeviceID>"); |
| 118 | - ptzXml.append("<PTZCmd>" + "</PTZCmd>"); | |
| 168 | + ptzXml.append("<PTZCmd>" + cmdStr + "</PTZCmd>"); | |
| 119 | 169 | ptzXml.append("<Info>"); |
| 120 | 170 | ptzXml.append("</Info>"); |
| 121 | 171 | ptzXml.append("</Control>"); |
| ... | ... | @@ -123,7 +173,6 @@ public class SIPCommander implements ISIPCommander { |
| 123 | 173 | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); |
| 124 | 174 | |
| 125 | 175 | transmitRequest(device, request); |
| 126 | - | |
| 127 | 176 | return true; |
| 128 | 177 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| 129 | 178 | e.printStackTrace(); |
| ... | ... | @@ -245,6 +294,13 @@ public class SIPCommander implements ISIPCommander { |
| 245 | 294 | return; |
| 246 | 295 | } |
| 247 | 296 | Request byeRequest = dialog.createRequest(Request.BYE); |
| 297 | + SipURI byeURI = (SipURI) byeRequest.getRequestURI(); | |
| 298 | + String vh = transaction.getRequest().getHeader(ViaHeader.NAME).toString(); | |
| 299 | + Pattern p = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)"); | |
| 300 | + Matcher matcher = p.matcher(vh); | |
| 301 | + if (matcher.find()) { | |
| 302 | + byeURI.setHost(matcher.group(1)); | |
| 303 | + } | |
| 248 | 304 | ViaHeader viaHeader = (ViaHeader) byeRequest.getHeader(ViaHeader.NAME); |
| 249 | 305 | String protocol = viaHeader.getTransport().toUpperCase(); |
| 250 | 306 | ClientTransaction clientTransaction = null; |
| ... | ... | @@ -258,6 +314,8 @@ public class SIPCommander implements ISIPCommander { |
| 258 | 314 | e.printStackTrace(); |
| 259 | 315 | } catch (SipException e) { |
| 260 | 316 | e.printStackTrace(); |
| 317 | + } catch (ParseException e) { | |
| 318 | + e.printStackTrace(); | |
| 261 | 319 | } |
| 262 | 320 | } |
| 263 | 321 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
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; |
| 43 | 43 | |
| 44 | 44 | /** |
| 45 | 45 | * @Description:MESSAGE请求处理器 |
| 46 | - * @author: swwheihei | |
| 46 | + * @author: songww | |
| 47 | 47 | * @date: 2020年5月3日 下午5:32:41 |
| 48 | 48 | */ |
| 49 | 49 | @Component |
| ... | ... | @@ -100,6 +100,7 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { |
| 100 | 100 | |
| 101 | 101 | Request request = evt.getRequest(); |
| 102 | 102 | SAXReader reader = new SAXReader(); |
| 103 | + reader.setEncoding("gbk"); | |
| 103 | 104 | Document xml; |
| 104 | 105 | try { |
| 105 | 106 | xml = reader.read(new ByteArrayInputStream(request.getRawContent())); |
| ... | ... | @@ -375,7 +376,7 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { |
| 375 | 376 | private Element getRootElement(RequestEvent evt) throws DocumentException { |
| 376 | 377 | Request request = evt.getRequest(); |
| 377 | 378 | SAXReader reader = new SAXReader(); |
| 378 | - reader.setEncoding("GB2312"); | |
| 379 | + reader.setEncoding("gbk"); | |
| 379 | 380 | Document xml = reader.read(new ByteArrayInputStream(request.getRawContent())); |
| 380 | 381 | return xml.getRootElement(); |
| 381 | 382 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.response; |
| 2 | 2 | |
| 3 | +import java.text.ParseException; | |
| 4 | + | |
| 3 | 5 | import javax.sip.ResponseEvent; |
| 4 | 6 | |
| 5 | 7 | import com.genersoft.iot.vmp.conf.SipConfig; |
| ... | ... | @@ -7,11 +9,11 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 7 | 9 | |
| 8 | 10 | /** |
| 9 | 11 | * @Description:处理接收IPCamera发来的SIP协议响应消息 |
| 10 | - * @author: swwheihei | |
| 12 | + * @author: songww | |
| 11 | 13 | * @date: 2020年5月3日 下午4:42:22 |
| 12 | 14 | */ |
| 13 | 15 | public interface ISIPResponseProcessor { |
| 14 | 16 | |
| 15 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config); | |
| 17 | + public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException; | |
| 16 | 18 | |
| 17 | 19 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java
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; |
| 2 | 2 | |
| 3 | 3 | import java.text.ParseException; |
| 4 | 4 | |
| 5 | -import javax.sip.ClientTransaction; | |
| 6 | 5 | import javax.sip.Dialog; |
| 7 | 6 | import javax.sip.InvalidArgumentException; |
| 8 | 7 | import javax.sip.ResponseEvent; |
| ... | ... | @@ -22,57 +21,76 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 22 | 21 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; |
| 23 | 22 | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; |
| 24 | 23 | |
| 25 | -/** | |
| 26 | - * @Description:处理INVITE响应 | |
| 27 | - * @author: swwheihei | |
| 28 | - * @date: 2020年5月3日 下午4:43:52 | |
| 24 | + | |
| 25 | +/** | |
| 26 | + * @Description:处理INVITE响应 | |
| 27 | + * @author: songww | |
| 28 | + * @date: 2020年5月3日 下午4:43:52 | |
| 29 | 29 | */ |
| 30 | 30 | @Component |
| 31 | 31 | public class InviteResponseProcessor implements ISIPResponseProcessor { |
| 32 | 32 | |
| 33 | 33 | private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class); |
| 34 | - | |
| 34 | + | |
| 35 | 35 | /** |
| 36 | 36 | * 处理invite响应 |
| 37 | 37 | * |
| 38 | - * @param evt | |
| 39 | - * 响应消息 | |
| 40 | - */ | |
| 38 | + * @param evt 响应消息 | |
| 39 | + * @throws ParseException | |
| 40 | + */ | |
| 41 | 41 | @Override |
| 42 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) { | |
| 42 | + public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException { | |
| 43 | 43 | try { |
| 44 | 44 | Response response = evt.getResponse(); |
| 45 | 45 | int statusCode = response.getStatusCode(); |
| 46 | - //trying不会回复 | |
| 47 | - if(statusCode == Response.TRYING){ | |
| 48 | - | |
| 46 | + // trying不会回复 | |
| 47 | + if (statusCode == Response.TRYING) { | |
| 49 | 48 | } |
| 50 | - //成功响应 | |
| 51 | - //下发ack | |
| 52 | - if(statusCode == Response.OK){ | |
| 53 | -// ClientTransaction clientTransaction = evt.getClientTransaction(); | |
| 54 | -// if(clientTransaction == null){ | |
| 55 | -// logger.error("回复ACK时,clientTransaction为null >>> {}",response); | |
| 56 | -// return; | |
| 57 | -// } | |
| 58 | -// Dialog clientDialog = clientTransaction.getDialog(); | |
| 59 | -// | |
| 60 | -// CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | |
| 61 | -// long cseqId = clientCSeqHeader.getSeqNumber(); | |
| 62 | -// /* | |
| 63 | -// createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 | |
| 64 | -// 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 | |
| 65 | -// 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 | |
| 66 | -// */ | |
| 67 | -// Request ackRequest = clientDialog.createAck(cseqId); | |
| 68 | -// SipURI requestURI = (SipURI) ackRequest.getRequestURI(); | |
| 69 | -// ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); | |
| 70 | -// requestURI.setHost(viaHeader.getHost()); | |
| 71 | -// requestURI.setPort(viaHeader.getPort()); | |
| 72 | -// clientDialog.sendAck(ackRequest); | |
| 73 | - | |
| 49 | + // 成功响应 | |
| 50 | + // 下发ack | |
| 51 | + if (statusCode == Response.OK) { | |
| 52 | + // ClientTransaction clientTransaction = evt.getClientTransaction(); | |
| 53 | + // if(clientTransaction == null){ | |
| 54 | + // logger.error("回复ACK时,clientTransaction为null >>> {}",response); | |
| 55 | + // return; | |
| 56 | + // } | |
| 57 | + // Dialog clientDialog = clientTransaction.getDialog(); | |
| 58 | + | |
| 59 | + // CSeqHeader clientCSeqHeader = (CSeqHeader) | |
| 60 | + // response.getHeader(CSeqHeader.NAME); | |
| 61 | + // long cseqId = clientCSeqHeader.getSeqNumber(); | |
| 62 | + // /* | |
| 63 | + // createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 | |
| 64 | + // 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 | |
| 65 | + // 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 | |
| 66 | + // */ | |
| 67 | + // Request ackRequest = clientDialog.createAck(cseqId); | |
| 68 | + // SipURI requestURI = (SipURI) ackRequest.getRequestURI(); | |
| 69 | + // ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); | |
| 70 | + // try { | |
| 71 | + // requestURI.setHost(viaHeader.getHost()); | |
| 72 | + // } catch (Exception e) { | |
| 73 | + // e.printStackTrace(); | |
| 74 | + // } | |
| 75 | + // requestURI.setPort(viaHeader.getPort()); | |
| 76 | + // clientDialog.sendAck(ackRequest); | |
| 77 | + | |
| 74 | 78 | Dialog dialog = evt.getDialog(); |
| 75 | - Request reqAck =dialog.createAck(1L); | |
| 79 | + CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | |
| 80 | + Request reqAck = dialog.createAck(cseq.getSeqNumber()); | |
| 81 | + | |
| 82 | + SipURI requestURI = (SipURI) reqAck.getRequestURI(); | |
| 83 | + ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); | |
| 84 | + // String viaHost =viaHeader.getHost(); | |
| 85 | + //getHost()函数取回的IP地址是“[xxx.xxx.xxx.xxx:yyyy]”的格式,需用正则表达式截取为“xxx.xxx.xxx.xxx"格式 | |
| 86 | + // Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+"); | |
| 87 | + // Matcher matcher = p.matcher(viaHeader.getHost()); | |
| 88 | + // if (matcher.find()) { | |
| 89 | + // requestURI.setHost(matcher.group()); | |
| 90 | + // } | |
| 91 | + requestURI.setHost(viaHeader.getHost()); | |
| 92 | + requestURI.setPort(viaHeader.getPort()); | |
| 93 | + reqAck.setRequestURI(requestURI); | |
| 76 | 94 | dialog.sendAck(reqAck); |
| 77 | 95 | } |
| 78 | 96 | } catch (InvalidArgumentException | SipException e) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java
src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java
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; |
| 18 | 18 | |
| 19 | 19 | /** |
| 20 | 20 | * @Description:针对 ZLMediaServer的hook事件监听 |
| 21 | - * @author: swwheihei | |
| 21 | + * @author: songww | |
| 22 | 22 | * @date: 2020年5月8日 上午10:46:48 |
| 23 | 23 | */ |
| 24 | 24 | @RestController |
| 25 | -@RequestMapping("/hook/zlm") | |
| 25 | +@RequestMapping("/index/hook") | |
| 26 | 26 | public class ZLMHttpHookListener { |
| 27 | 27 | |
| 28 | 28 | private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java
src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java
| ... | ... | @@ -10,7 +10,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature; |
| 10 | 10 | |
| 11 | 11 | /** |
| 12 | 12 | * @Description:使用fastjson实现redis的序列化 |
| 13 | - * @author: swwheihei | |
| 13 | + * @author: songww | |
| 14 | 14 | * @date: 2020年5月6日 下午8:40:11 |
| 15 | 15 | */ |
| 16 | 16 | public class FastJsonRedisSerializer<T> implements RedisSerializer<T> { | ... | ... |
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
src/main/resources/application.yml
| ... | ... | @@ -26,7 +26,8 @@ spring: |
| 26 | 26 | server: |
| 27 | 27 | port: 8080 |
| 28 | 28 | sip: |
| 29 | - ip: 10.200.64.63 | |
| 29 | +# ip: 10.200.64.63 | |
| 30 | + ip: 192.168.0.102 | |
| 30 | 31 | port: 5060 |
| 31 | 32 | # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) |
| 32 | 33 | # 后两位为行业编码,定义参照附录D.3 |
| ... | ... | @@ -34,7 +35,8 @@ sip: |
| 34 | 35 | domain: 3701020049 |
| 35 | 36 | id: 37010200492000000001 |
| 36 | 37 | # 默认设备认证密码,后续扩展使用设备单独密码 |
| 37 | - password: admin | |
| 38 | + password: admin123 | |
| 38 | 39 | media: |
| 39 | - ip: 10.200.64.88 | |
| 40 | +# ip: 10.200.64.88 | |
| 41 | + ip: 192.168.0.102 | |
| 40 | 42 | port: 10000 |
| 41 | 43 | \ No newline at end of file | ... | ... |
wikis/images/核心流程.png