Commit f1217682a9d1726b5b5673343dfe9b035e1180d4
1 parent
341ea711
重构28181信令结构,解决循环依赖导致的无法直接注入
Showing
62 changed files
with
345 additions
and
3589 deletions
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
| @@ -16,7 +16,7 @@ import redis.clients.jedis.JedisPool; | @@ -16,7 +16,7 @@ import redis.clients.jedis.JedisPool; | ||
| 16 | import redis.clients.jedis.JedisPoolConfig; | 16 | import redis.clients.jedis.JedisPoolConfig; |
| 17 | 17 | ||
| 18 | /** | 18 | /** |
| 19 | - * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置 | 19 | + * @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置 |
| 20 | * @author: swwheihei | 20 | * @author: swwheihei |
| 21 | * @date: 2019年5月30日 上午10:58:25 | 21 | * @date: 2019年5月30日 上午10:58:25 |
| 22 | * | 22 | * |
src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java
| @@ -32,5 +32,7 @@ public class SipDeviceRunner implements CommandLineRunner { | @@ -32,5 +32,7 @@ public class SipDeviceRunner implements CommandLineRunner { | ||
| 32 | for (String deviceId : onlineForAll) { | 32 | for (String deviceId : onlineForAll) { |
| 33 | storager.online(deviceId); | 33 | storager.online(deviceId); |
| 34 | } | 34 | } |
| 35 | + | ||
| 36 | + // TODO 查询在线设备那些开启了订阅,为设备开启定时的目录订阅 | ||
| 35 | } | 37 | } |
| 36 | } | 38 | } |
src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java
| @@ -4,7 +4,7 @@ import org.springframework.beans.factory.annotation.Value; | @@ -4,7 +4,7 @@ import org.springframework.beans.factory.annotation.Value; | ||
| 4 | import org.springframework.context.annotation.Configuration; | 4 | import org.springframework.context.annotation.Configuration; |
| 5 | 5 | ||
| 6 | /** | 6 | /** |
| 7 | - * @Description: 获取数据库配置 | 7 | + * @description: 获取数据库配置 |
| 8 | * @author: swwheihei | 8 | * @author: swwheihei |
| 9 | * @date: 2020年5月6日 下午2:46:00 | 9 | * @date: 2020年5月6日 下午2:46:00 |
| 10 | */ | 10 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| 1 | package com.genersoft.iot.vmp.gb28181; | 1 | package com.genersoft.iot.vmp.gb28181; |
| 2 | 2 | ||
| 3 | -import java.text.ParseException; | ||
| 4 | -import java.util.Properties; | ||
| 5 | -import java.util.TooManyListenersException; | ||
| 6 | -import java.util.concurrent.LinkedBlockingQueue; | ||
| 7 | -import java.util.concurrent.ThreadPoolExecutor; | ||
| 8 | -import java.util.concurrent.TimeUnit; | ||
| 9 | - | ||
| 10 | -import javax.sip.*; | ||
| 11 | -import javax.sip.header.CallIdHeader; | ||
| 12 | -import javax.sip.header.Header; | ||
| 13 | -import javax.sip.message.Response; | ||
| 14 | - | 3 | +import com.genersoft.iot.vmp.conf.SipConfig; |
| 15 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 4 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 5 | +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | ||
| 16 | import gov.nist.javax.sip.SipProviderImpl; | 6 | import gov.nist.javax.sip.SipProviderImpl; |
| 7 | +import gov.nist.javax.sip.SipStackImpl; | ||
| 17 | import org.slf4j.Logger; | 8 | import org.slf4j.Logger; |
| 18 | import org.slf4j.LoggerFactory; | 9 | import org.slf4j.LoggerFactory; |
| 19 | import org.springframework.beans.factory.annotation.Autowired; | 10 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -21,14 +12,15 @@ import org.springframework.context.annotation.Bean; | @@ -21,14 +12,15 @@ import org.springframework.context.annotation.Bean; | ||
| 21 | import org.springframework.context.annotation.DependsOn; | 12 | import org.springframework.context.annotation.DependsOn; |
| 22 | import org.springframework.stereotype.Component; | 13 | import org.springframework.stereotype.Component; |
| 23 | 14 | ||
| 24 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 25 | -import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; | ||
| 26 | -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | ||
| 27 | - | ||
| 28 | -import gov.nist.javax.sip.SipStackImpl; | 15 | +import javax.sip.*; |
| 16 | +import java.util.Properties; | ||
| 17 | +import java.util.TooManyListenersException; | ||
| 18 | +import java.util.concurrent.LinkedBlockingQueue; | ||
| 19 | +import java.util.concurrent.ThreadPoolExecutor; | ||
| 20 | +import java.util.concurrent.TimeUnit; | ||
| 29 | 21 | ||
| 30 | @Component | 22 | @Component |
| 31 | -public class SipLayer implements SipListener { | 23 | +public class SipLayer{ |
| 32 | 24 | ||
| 33 | private final static Logger logger = LoggerFactory.getLogger(SipLayer.class); | 25 | private final static Logger logger = LoggerFactory.getLogger(SipLayer.class); |
| 34 | 26 | ||
| @@ -36,7 +28,7 @@ public class SipLayer implements SipListener { | @@ -36,7 +28,7 @@ public class SipLayer implements SipListener { | ||
| 36 | private SipConfig sipConfig; | 28 | private SipConfig sipConfig; |
| 37 | 29 | ||
| 38 | @Autowired | 30 | @Autowired |
| 39 | - private SIPProcessorFactory processorFactory; | 31 | + private SIPProcessorObserver sipProcessorObserver; |
| 40 | 32 | ||
| 41 | @Autowired | 33 | @Autowired |
| 42 | private SipSubscribe sipSubscribe; | 34 | private SipSubscribe sipSubscribe; |
| @@ -50,19 +42,16 @@ public class SipLayer implements SipListener { | @@ -50,19 +42,16 @@ public class SipLayer implements SipListener { | ||
| 50 | */ | 42 | */ |
| 51 | private ThreadPoolExecutor processThreadPool; | 43 | private ThreadPoolExecutor processThreadPool; |
| 52 | 44 | ||
| 53 | - @Bean("initSipServer") | ||
| 54 | - private ThreadPoolExecutor initSipServer() { | ||
| 55 | - | 45 | + public SipLayer() { |
| 56 | int processThreadNum = Runtime.getRuntime().availableProcessors() * 10; | 46 | int processThreadNum = Runtime.getRuntime().availableProcessors() * 10; |
| 57 | LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000); | 47 | LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000); |
| 58 | processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum, | 48 | processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum, |
| 59 | 0L,TimeUnit.MILLISECONDS,processQueue, | 49 | 0L,TimeUnit.MILLISECONDS,processQueue, |
| 60 | new ThreadPoolExecutor.CallerRunsPolicy()); | 50 | new ThreadPoolExecutor.CallerRunsPolicy()); |
| 61 | - return processThreadPool; | ||
| 62 | } | 51 | } |
| 63 | - | 52 | + |
| 53 | + | ||
| 64 | @Bean("sipFactory") | 54 | @Bean("sipFactory") |
| 65 | - @DependsOn("initSipServer") | ||
| 66 | private SipFactory createSipFactory() { | 55 | private SipFactory createSipFactory() { |
| 67 | sipFactory = SipFactory.getInstance(); | 56 | sipFactory = SipFactory.getInstance(); |
| 68 | sipFactory.setPathName("gov.nist"); | 57 | sipFactory.setPathName("gov.nist"); |
| @@ -70,7 +59,7 @@ public class SipLayer implements SipListener { | @@ -70,7 +59,7 @@ public class SipLayer implements SipListener { | ||
| 70 | } | 59 | } |
| 71 | 60 | ||
| 72 | @Bean("sipStack") | 61 | @Bean("sipStack") |
| 73 | - @DependsOn({"initSipServer", "sipFactory"}) | 62 | + @DependsOn({"sipFactory"}) |
| 74 | private SipStack createSipStack() throws PeerUnavailableException { | 63 | private SipStack createSipStack() throws PeerUnavailableException { |
| 75 | Properties properties = new Properties(); | 64 | Properties properties = new Properties(); |
| 76 | properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); | 65 | properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); |
| @@ -96,7 +85,7 @@ public class SipLayer implements SipListener { | @@ -96,7 +85,7 @@ public class SipLayer implements SipListener { | ||
| 96 | try { | 85 | try { |
| 97 | tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "TCP"); | 86 | tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "TCP"); |
| 98 | tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint); | 87 | tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint); |
| 99 | - tcpSipProvider.addSipListener(this); | 88 | + tcpSipProvider.addSipListener(sipProcessorObserver); |
| 100 | logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "}"); | 89 | logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "}"); |
| 101 | } catch (TransportNotSupportedException e) { | 90 | } catch (TransportNotSupportedException e) { |
| 102 | e.printStackTrace(); | 91 | e.printStackTrace(); |
| @@ -119,8 +108,7 @@ public class SipLayer implements SipListener { | @@ -119,8 +108,7 @@ public class SipLayer implements SipListener { | ||
| 119 | try { | 108 | try { |
| 120 | udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "UDP"); | 109 | udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "UDP"); |
| 121 | udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint); | 110 | udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint); |
| 122 | - udpSipProvider.addSipListener(this); | ||
| 123 | -// udpSipProvider.setAutomaticDialogSupportEnabled(false); | 111 | + udpSipProvider.addSipListener(sipProcessorObserver); |
| 124 | } catch (TransportNotSupportedException e) { | 112 | } catch (TransportNotSupportedException e) { |
| 125 | e.printStackTrace(); | 113 | e.printStackTrace(); |
| 126 | } catch (InvalidArgumentException e) { | 114 | } catch (InvalidArgumentException e) { |
| @@ -135,140 +123,4 @@ public class SipLayer implements SipListener { | @@ -135,140 +123,4 @@ public class SipLayer implements SipListener { | ||
| 135 | return udpSipProvider; | 123 | return udpSipProvider; |
| 136 | } | 124 | } |
| 137 | 125 | ||
| 138 | - /** | ||
| 139 | - * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a | ||
| 140 | - * new request arrives. | ||
| 141 | - */ | ||
| 142 | - @Override | ||
| 143 | - public void processRequest(RequestEvent evt) { | ||
| 144 | - logger.debug(evt.getRequest().toString()); | ||
| 145 | - // 由于jainsip是单线程程序,为提高性能并发处理 | ||
| 146 | - processThreadPool.execute(() -> { | ||
| 147 | - if (processorFactory != null) { | ||
| 148 | - processorFactory.createRequestProcessor(evt).process(); | ||
| 149 | - } | ||
| 150 | - }); | ||
| 151 | - } | ||
| 152 | - | ||
| 153 | - @Override | ||
| 154 | - public void processResponse(ResponseEvent evt) { | ||
| 155 | - Response response = evt.getResponse(); | ||
| 156 | - logger.debug(evt.getResponse().toString()); | ||
| 157 | - int status = response.getStatusCode(); | ||
| 158 | - if (((status >= 200) && (status < 300)) || status == 401) { // Success! | ||
| 159 | - ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); | ||
| 160 | - try { | ||
| 161 | - processor.process(evt, this, sipConfig); | ||
| 162 | - } catch (ParseException e) { | ||
| 163 | - // TODO Auto-generated catch block | ||
| 164 | - e.printStackTrace(); | ||
| 165 | - } | ||
| 166 | - | ||
| 167 | - if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { | ||
| 168 | - CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); | ||
| 169 | - if (callIdHeader != null) { | ||
| 170 | - SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId()); | ||
| 171 | - if (subscribe != null) { | ||
| 172 | - SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(evt); | ||
| 173 | - subscribe.response(eventResult); | ||
| 174 | - } | ||
| 175 | - } | ||
| 176 | - } | ||
| 177 | - } else if ((status >= 100) && (status < 200)) { | ||
| 178 | - // 增加其它无需回复的响应,如101、180等 | ||
| 179 | - } else { | ||
| 180 | - logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/); | ||
| 181 | - if (evt.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) { | ||
| 182 | - CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); | ||
| 183 | - if (callIdHeader != null) { | ||
| 184 | - SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()); | ||
| 185 | - if (subscribe != null) { | ||
| 186 | - SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(evt); | ||
| 187 | - subscribe.response(eventResult); | ||
| 188 | - } | ||
| 189 | - } | ||
| 190 | - } | ||
| 191 | - } | ||
| 192 | - | ||
| 193 | - | ||
| 194 | - | ||
| 195 | - } | ||
| 196 | - | ||
| 197 | - /** | ||
| 198 | - * <p> | ||
| 199 | - * Title: processTimeout | ||
| 200 | - * </p> | ||
| 201 | - * <p> | ||
| 202 | - * Description: | ||
| 203 | - * </p> | ||
| 204 | - * | ||
| 205 | - * @param timeoutEvent | ||
| 206 | - */ | ||
| 207 | - @Override | ||
| 208 | - public void processTimeout(TimeoutEvent timeoutEvent) { | ||
| 209 | - // TODO Auto-generated method stub | ||
| 210 | - CallIdHeader callIdHeader = timeoutEvent.getClientTransaction().getDialog().getCallId(); | ||
| 211 | - String callId = callIdHeader.getCallId(); | ||
| 212 | - SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId); | ||
| 213 | - SipSubscribe.EventResult<TimeoutEvent> timeoutEventEventResult = new SipSubscribe.EventResult<>(timeoutEvent); | ||
| 214 | - errorSubscribe.response(timeoutEventEventResult); | ||
| 215 | - } | ||
| 216 | - | ||
| 217 | - /** | ||
| 218 | - * <p> | ||
| 219 | - * Title: processIOException | ||
| 220 | - * </p> | ||
| 221 | - * <p> | ||
| 222 | - * Description: | ||
| 223 | - * </p> | ||
| 224 | - * | ||
| 225 | - * @param exceptionEvent | ||
| 226 | - */ | ||
| 227 | - @Override | ||
| 228 | - public void processIOException(IOExceptionEvent exceptionEvent) { | ||
| 229 | - // TODO Auto-generated method stub | ||
| 230 | - | ||
| 231 | - } | ||
| 232 | - | ||
| 233 | - /** | ||
| 234 | - * <p> | ||
| 235 | - * Title: processTransactionTerminated | ||
| 236 | - * </p> | ||
| 237 | - * <p> | ||
| 238 | - * Description: | ||
| 239 | - * </p> | ||
| 240 | - * | ||
| 241 | - * @param transactionTerminatedEvent | ||
| 242 | - */ | ||
| 243 | - @Override | ||
| 244 | - public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { | ||
| 245 | - // TODO Auto-generated method stub | ||
| 246 | -// CallIdHeader callIdHeader = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId(); | ||
| 247 | -// String callId = callIdHeader.getCallId(); | ||
| 248 | -// SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId); | ||
| 249 | -// SipSubscribe.EventResult<TransactionTerminatedEvent> eventResult = new SipSubscribe.EventResult<>(transactionTerminatedEvent); | ||
| 250 | -// errorSubscribe.response(eventResult); | ||
| 251 | - } | ||
| 252 | - | ||
| 253 | - /** | ||
| 254 | - * <p> | ||
| 255 | - * Title: processDialogTerminated | ||
| 256 | - * </p> | ||
| 257 | - * <p> | ||
| 258 | - * Description: | ||
| 259 | - * </p> | ||
| 260 | - * | ||
| 261 | - * @param dialogTerminatedEvent | ||
| 262 | - */ | ||
| 263 | - @Override | ||
| 264 | - public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) { | ||
| 265 | - // TODO Auto-generated method stub | ||
| 266 | -// CallIdHeader callIdHeader = dialogTerminatedEvent.getDialog().getCallId(); | ||
| 267 | -// String callId = callIdHeader.getCallId(); | ||
| 268 | -// SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId); | ||
| 269 | -// SipSubscribe.EventResult<DialogTerminatedEvent> eventResult = new SipSubscribe.EventResult<>(dialogTerminatedEvent); | ||
| 270 | -// errorSubscribe.response(eventResult); | ||
| 271 | - | ||
| 272 | - } | ||
| 273 | - | ||
| 274 | } | 126 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
| @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; | @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 10 | 10 | ||
| 11 | /** | 11 | /** |
| 12 | - * @Description:注册逻辑处理,当设备注册后触发逻辑。 | 12 | + * @description:注册逻辑处理,当设备注册后触发逻辑。 |
| 13 | * @author: swwheihei | 13 | * @author: swwheihei |
| 14 | * @date: 2020年5月8日 下午9:41:46 | 14 | * @date: 2020年5月8日 下午9:41:46 |
| 15 | */ | 15 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
| @@ -109,6 +109,11 @@ public class Device { | @@ -109,6 +109,11 @@ public class Device { | ||
| 109 | */ | 109 | */ |
| 110 | private String charset ; | 110 | private String charset ; |
| 111 | 111 | ||
| 112 | + /** | ||
| 113 | + * 目录订阅周期,0为不订阅 | ||
| 114 | + */ | ||
| 115 | + private int subscribeCycleForCatalog ; | ||
| 116 | + | ||
| 112 | 117 | ||
| 113 | 118 | ||
| 114 | public String getDeviceId() { | 119 | public String getDeviceId() { |
| @@ -270,4 +275,12 @@ public class Device { | @@ -270,4 +275,12 @@ public class Device { | ||
| 270 | public void setCharset(String charset) { | 275 | public void setCharset(String charset) { |
| 271 | this.charset = charset; | 276 | this.charset = charset; |
| 272 | } | 277 | } |
| 278 | + | ||
| 279 | + public int getSubscribeCycleForCatalog() { | ||
| 280 | + return subscribeCycleForCatalog; | ||
| 281 | + } | ||
| 282 | + | ||
| 283 | + public void setSubscribeCycleForCatalog(int subscribeCycleForCatalog) { | ||
| 284 | + this.subscribeCycleForCatalog = subscribeCycleForCatalog; | ||
| 285 | + } | ||
| 273 | } | 286 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/MobilePosition.java
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
| @@ -6,7 +6,7 @@ package com.genersoft.iot.vmp.gb28181.bean; | @@ -6,7 +6,7 @@ package com.genersoft.iot.vmp.gb28181.bean; | ||
| 6 | import java.util.List; | 6 | import java.util.List; |
| 7 | 7 | ||
| 8 | /** | 8 | /** |
| 9 | - * @Description:设备录像信息bean | 9 | + * @description:设备录像信息bean |
| 10 | * @author: swwheihei | 10 | * @author: swwheihei |
| 11 | * @date: 2020年5月8日 下午2:05:56 | 11 | * @date: 2020年5月8日 下午2:05:56 |
| 12 | */ | 12 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java
| @@ -8,7 +8,7 @@ import java.text.SimpleDateFormat; | @@ -8,7 +8,7 @@ import java.text.SimpleDateFormat; | ||
| 8 | import java.util.Date; | 8 | import java.util.Date; |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | - * @Description:设备录像bean | 11 | + * @description:设备录像bean |
| 12 | * @author: swwheihei | 12 | * @author: swwheihei |
| 13 | * @date: 2020年5月8日 下午2:06:54 | 13 | * @date: 2020年5月8日 下午2:06:54 |
| 14 | */ | 14 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java
| @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; | @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 7 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 7 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | - * @Description:设备离在线状态检测器,用于检测设备状态 | 10 | + * @description:设备离在线状态检测器,用于检测设备状态 |
| 11 | * @author: swwheihei | 11 | * @author: swwheihei |
| 12 | * @date: 2020年5月13日 下午2:40:29 | 12 | * @date: 2020年5月13日 下午2:40:29 |
| 13 | */ | 13 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
| @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent; | @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent; | ||
| 13 | import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent; | 13 | import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent; |
| 14 | 14 | ||
| 15 | /** | 15 | /** |
| 16 | - * @Description:Event事件通知推送器,支持推送在线事件、离线事件 | 16 | + * @description:Event事件通知推送器,支持推送在线事件、离线事件 |
| 17 | * @author: swwheihei | 17 | * @author: swwheihei |
| 18 | * @date: 2020年5月6日 上午11:30:50 | 18 | * @date: 2020年5月6日 上午11:30:50 |
| 19 | */ | 19 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java
| @@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; | @@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 12 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | 12 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | - * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 | 15 | + * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 |
| 16 | * @author: swwheihei | 16 | * @author: swwheihei |
| 17 | * @date: 2020年5月6日 上午11:35:46 | 17 | * @date: 2020年5月6日 上午11:35:46 |
| 18 | */ | 18 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java
| @@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; | @@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 12 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | 12 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | - * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 | 15 | + * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件 |
| 16 | * @author: swwheihei | 16 | * @author: swwheihei |
| 17 | * @date: 2020年5月6日 上午11:35:46 | 17 | * @date: 2020年5月6日 上午11:35:46 |
| 18 | */ | 18 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java
| @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.gb28181.event.offline; | @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.gb28181.event.offline; | ||
| 3 | import org.springframework.context.ApplicationEvent; | 3 | import org.springframework.context.ApplicationEvent; |
| 4 | 4 | ||
| 5 | /** | 5 | /** |
| 6 | - * @Description: 离线事件类 | 6 | + * @description: 离线事件类 |
| 7 | * @author: swwheihei | 7 | * @author: swwheihei |
| 8 | * @date: 2020年5月6日 上午11:33:13 | 8 | * @date: 2020年5月6日 上午11:33:13 |
| 9 | */ | 9 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java
| @@ -11,8 +11,8 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | @@ -11,8 +11,8 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 11 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 11 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | - * @Description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源: | ||
| 15 | - * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor} | 14 | + * @description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源: |
| 15 | + * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor} | ||
| 16 | * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener} | 16 | * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener} |
| 17 | * @author: swwheihei | 17 | * @author: swwheihei |
| 18 | * @date: 2020年5月6日 下午1:51:23 | 18 | * @date: 2020年5月6日 下午1:51:23 |
| @@ -54,5 +54,8 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> { | @@ -54,5 +54,8 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> { | ||
| 54 | 54 | ||
| 55 | // 处理离线监听 | 55 | // 处理离线监听 |
| 56 | storager.outline(event.getDeviceId()); | 56 | storager.outline(event.getDeviceId()); |
| 57 | + | ||
| 58 | + // TODO 离线取消订阅 | ||
| 59 | + | ||
| 57 | } | 60 | } |
| 58 | } | 61 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java
| @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; | @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 4 | import org.springframework.context.ApplicationEvent; | 4 | import org.springframework.context.ApplicationEvent; |
| 5 | 5 | ||
| 6 | /** | 6 | /** |
| 7 | - * @Description: 在线事件类 | 7 | + * @description: 在线事件类 |
| 8 | * @author: swwheihei | 8 | * @author: swwheihei |
| 9 | * @date: 2020年5月6日 上午11:32:56 | 9 | * @date: 2020年5月6日 上午11:32:56 |
| 10 | */ | 10 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java
| @@ -13,12 +13,11 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | @@ -13,12 +13,11 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 13 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 13 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 14 | 14 | ||
| 15 | import java.text.SimpleDateFormat; | 15 | import java.text.SimpleDateFormat; |
| 16 | -import java.util.Date; | ||
| 17 | 16 | ||
| 18 | /** | 17 | /** |
| 19 | - * @Description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源: | ||
| 20 | - * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor} | ||
| 21 | - * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor} | 18 | + * @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源: |
| 19 | + * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor} | ||
| 20 | + * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.MessageRequestProcessor} | ||
| 22 | * @author: swwheihei | 21 | * @author: swwheihei |
| 23 | * @date: 2020年5月6日 下午1:51:23 | 22 | * @date: 2020年5月6日 下午1:51:23 |
| 24 | */ | 23 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java
| @@ -18,7 +18,7 @@ import javax.sip.ResponseEvent; | @@ -18,7 +18,7 @@ import javax.sip.ResponseEvent; | ||
| 18 | import javax.sip.message.Response; | 18 | import javax.sip.message.Response; |
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | - * @Description: 平台心跳超时事件 | 21 | + * @description: 平台心跳超时事件 |
| 22 | * @author: panll | 22 | * @author: panll |
| 23 | * @date: 2020年11月5日 10:00 | 23 | * @date: 2020年11月5日 10:00 |
| 24 | */ | 24 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
| @@ -19,7 +19,7 @@ import org.springframework.stereotype.Component; | @@ -19,7 +19,7 @@ import org.springframework.stereotype.Component; | ||
| 19 | import java.util.*; | 19 | import java.util.*; |
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | - * @Description: 平台未注册事件,来源有二: | 22 | + * @description: 平台未注册事件,来源有二: |
| 23 | * 1、平台新添加 | 23 | * 1、平台新添加 |
| 24 | * 2、平台心跳超时 | 24 | * 2、平台心跳超时 |
| 25 | * @author: panll | 25 | * @author: panll |
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
| @@ -15,7 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; | @@ -15,7 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; | ||
| 15 | import org.springframework.stereotype.Component; | 15 | import org.springframework.stereotype.Component; |
| 16 | 16 | ||
| 17 | /** | 17 | /** |
| 18 | - * @Description:视频流session管理器,管理视频预览、预览回放的通信句柄 | 18 | + * @description:视频流session管理器,管理视频预览、预览回放的通信句柄 |
| 19 | * @author: swwheihei | 19 | * @author: swwheihei |
| 20 | * @date: 2020年5月13日 下午4:03:02 | 20 | * @date: 2020年5月13日 下午4:03:02 |
| 21 | */ | 21 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit; | ||
| 2 | - | ||
| 3 | -import javax.sip.RequestEvent; | ||
| 4 | -import javax.sip.ResponseEvent; | ||
| 5 | -import javax.sip.SipProvider; | ||
| 6 | -import javax.sip.header.CSeqHeader; | ||
| 7 | -import javax.sip.message.Request; | ||
| 8 | -import javax.sip.message.Response; | ||
| 9 | - | ||
| 10 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | ||
| 11 | -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | ||
| 12 | -import com.genersoft.iot.vmp.service.IDeviceAlarmService; | ||
| 13 | -import com.genersoft.iot.vmp.service.IMediaServerService; | ||
| 14 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 15 | -import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; | ||
| 16 | -import com.genersoft.iot.vmp.service.IPlayService; | ||
| 17 | -import org.springframework.beans.factory.annotation.Autowired; | ||
| 18 | -import org.springframework.context.annotation.Lazy; | ||
| 19 | -import org.springframework.stereotype.Component; | ||
| 20 | - | ||
| 21 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 22 | -import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler; | ||
| 23 | -import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; | ||
| 24 | -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | ||
| 25 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 26 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 27 | -import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; | ||
| 28 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.AckRequestProcessor; | ||
| 29 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.ByeRequestProcessor; | ||
| 30 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.CancelRequestProcessor; | ||
| 31 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.InviteRequestProcessor; | ||
| 32 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor; | ||
| 33 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.NotifyRequestProcessor; | ||
| 34 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor; | ||
| 35 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; | ||
| 36 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor; | ||
| 37 | -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | ||
| 38 | -import com.genersoft.iot.vmp.gb28181.transmit.response.impl.ByeResponseProcessor; | ||
| 39 | -import com.genersoft.iot.vmp.gb28181.transmit.response.impl.CancelResponseProcessor; | ||
| 40 | -import com.genersoft.iot.vmp.gb28181.transmit.response.impl.InviteResponseProcessor; | ||
| 41 | -import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcessor; | ||
| 42 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 43 | -import com.genersoft.iot.vmp.utils.SpringBeanFactory; | ||
| 44 | -import com.genersoft.iot.vmp.utils.redis.RedisUtil; | ||
| 45 | - | ||
| 46 | -/** | ||
| 47 | - * @Description: SIP信令处理分配 | ||
| 48 | - * @author: swwheihei | ||
| 49 | - * @date: 2020年5月3日 下午4:24:37 | ||
| 50 | - */ | ||
| 51 | -@Component | ||
| 52 | -public class SIPProcessorFactory { | ||
| 53 | - | ||
| 54 | - // private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class); | ||
| 55 | - | ||
| 56 | - @Autowired | ||
| 57 | - private SipConfig sipConfig; | ||
| 58 | - | ||
| 59 | - @Autowired | ||
| 60 | - private RegisterLogicHandler handler; | ||
| 61 | - | ||
| 62 | - @Autowired | ||
| 63 | - private IVideoManagerStorager storager; | ||
| 64 | - | ||
| 65 | - @Autowired | ||
| 66 | - private IRedisCatchStorage redisCatchStorage; | ||
| 67 | - | ||
| 68 | - @Autowired | ||
| 69 | - private EventPublisher publisher; | ||
| 70 | - | ||
| 71 | - @Autowired | ||
| 72 | - private SIPCommander cmder; | ||
| 73 | - | ||
| 74 | - @Autowired | ||
| 75 | - private SIPCommanderFroPlatform cmderFroPlatform; | ||
| 76 | - | ||
| 77 | - @Autowired | ||
| 78 | - private IDeviceAlarmService deviceAlarmService; | ||
| 79 | - | ||
| 80 | - @Autowired | ||
| 81 | - private RedisUtil redis; | ||
| 82 | - | ||
| 83 | - @Autowired | ||
| 84 | - private DeferredResultHolder deferredResultHolder; | ||
| 85 | - | ||
| 86 | - @Autowired | ||
| 87 | - private DeviceOffLineDetector offLineDetector; | ||
| 88 | - | ||
| 89 | - @Autowired | ||
| 90 | - private InviteResponseProcessor inviteResponseProcessor; | ||
| 91 | - | ||
| 92 | - @Autowired | ||
| 93 | - private ByeResponseProcessor byeResponseProcessor; | ||
| 94 | - | ||
| 95 | - @Autowired | ||
| 96 | - private CancelResponseProcessor cancelResponseProcessor; | ||
| 97 | - | ||
| 98 | - @Autowired | ||
| 99 | - @Lazy | ||
| 100 | - private RegisterResponseProcessor registerResponseProcessor; | ||
| 101 | - | ||
| 102 | - | ||
| 103 | - @Autowired | ||
| 104 | - private OtherResponseProcessor otherResponseProcessor; | ||
| 105 | - | ||
| 106 | - @Autowired | ||
| 107 | - private IPlayService playService; | ||
| 108 | - | ||
| 109 | - @Autowired | ||
| 110 | - private ZLMRTPServerFactory zlmrtpServerFactory; | ||
| 111 | - | ||
| 112 | - @Autowired | ||
| 113 | - private IMediaServerService mediaServerService; | ||
| 114 | - | ||
| 115 | - // 注:这里使用注解会导致循环依赖注入,暂用springBean | ||
| 116 | - private SipProvider tcpSipProvider; | ||
| 117 | - | ||
| 118 | - // 注:这里使用注解会导致循环依赖注入,暂用springBean | ||
| 119 | - private SipProvider udpSipProvider; | ||
| 120 | - | ||
| 121 | - public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) { | ||
| 122 | - Request request = evt.getRequest(); | ||
| 123 | - String method = request.getMethod(); | ||
| 124 | -// logger.info("接收到消息:"+request.getMethod()); | ||
| 125 | -// sipSubscribe.getSubscribe(evt.getServerTransaction().getBranchId()).response(evt); | ||
| 126 | - if (Request.INVITE.equals(method)) { | ||
| 127 | - InviteRequestProcessor processor = new InviteRequestProcessor(); | ||
| 128 | - processor.setRequestEvent(evt); | ||
| 129 | - processor.setTcpSipProvider(getTcpSipProvider()); | ||
| 130 | - processor.setUdpSipProvider(getUdpSipProvider()); | ||
| 131 | - | ||
| 132 | - processor.setCmder(cmder); | ||
| 133 | - processor.setCmderFroPlatform(cmderFroPlatform); | ||
| 134 | - processor.setPlayService(playService); | ||
| 135 | - processor.setStorager(storager); | ||
| 136 | - processor.setRedisCatchStorage(redisCatchStorage); | ||
| 137 | - processor.setZlmrtpServerFactory(zlmrtpServerFactory); | ||
| 138 | - processor.setMediaServerService(mediaServerService); | ||
| 139 | - return processor; | ||
| 140 | - } else if (Request.REGISTER.equals(method)) { | ||
| 141 | - RegisterRequestProcessor processor = new RegisterRequestProcessor(); | ||
| 142 | - processor.setRequestEvent(evt); | ||
| 143 | - processor.setTcpSipProvider(getTcpSipProvider()); | ||
| 144 | - processor.setUdpSipProvider(getUdpSipProvider()); | ||
| 145 | - processor.setHandler(handler); | ||
| 146 | - processor.setPublisher(publisher); | ||
| 147 | - processor.setSipConfig(sipConfig); | ||
| 148 | - processor.setVideoManagerStorager(storager); | ||
| 149 | - return processor; | ||
| 150 | - } else if (Request.SUBSCRIBE.equals(method)) { | ||
| 151 | - SubscribeRequestProcessor processor = new SubscribeRequestProcessor(); | ||
| 152 | - processor.setTcpSipProvider(getTcpSipProvider()); | ||
| 153 | - processor.setUdpSipProvider(getUdpSipProvider()); | ||
| 154 | - processor.setRequestEvent(evt); | ||
| 155 | - return processor; | ||
| 156 | - } else if (Request.ACK.equals(method)) { | ||
| 157 | - AckRequestProcessor processor = new AckRequestProcessor(); | ||
| 158 | - processor.setRequestEvent(evt); | ||
| 159 | - processor.setRedisCatchStorage(redisCatchStorage); | ||
| 160 | - processor.setZlmrtpServerFactory(zlmrtpServerFactory); | ||
| 161 | - processor.setMediaServerService(mediaServerService); | ||
| 162 | - return processor; | ||
| 163 | - } else if (Request.BYE.equals(method)) { | ||
| 164 | - ByeRequestProcessor processor = new ByeRequestProcessor(); | ||
| 165 | - processor.setRequestEvent(evt); | ||
| 166 | - processor.setRedisCatchStorage(redisCatchStorage); | ||
| 167 | - processor.setStorager(storager); | ||
| 168 | - processor.setZlmrtpServerFactory(zlmrtpServerFactory); | ||
| 169 | - processor.setSIPCommander(cmder); | ||
| 170 | - processor.setMediaServerService(mediaServerService); | ||
| 171 | - return processor; | ||
| 172 | - } else if (Request.CANCEL.equals(method)) { | ||
| 173 | - CancelRequestProcessor processor = new CancelRequestProcessor(); | ||
| 174 | - processor.setRequestEvent(evt); | ||
| 175 | - return processor; | ||
| 176 | - } else if (Request.MESSAGE.equals(method)) { | ||
| 177 | - MessageRequestProcessor processor = new MessageRequestProcessor(); | ||
| 178 | - processor.setRequestEvent(evt); | ||
| 179 | - processor.setTcpSipProvider(getTcpSipProvider()); | ||
| 180 | - processor.setUdpSipProvider(getUdpSipProvider()); | ||
| 181 | - processor.setPublisher(publisher); | ||
| 182 | - processor.setRedis(redis); | ||
| 183 | - processor.setDeferredResultHolder(deferredResultHolder); | ||
| 184 | - processor.setOffLineDetector(offLineDetector); | ||
| 185 | - processor.setCmder(cmder); | ||
| 186 | - processor.setCmderFroPlatform(cmderFroPlatform); | ||
| 187 | - processor.setDeviceAlarmService(deviceAlarmService); | ||
| 188 | - processor.setStorager(storager); | ||
| 189 | - processor.setRedisCatchStorage(redisCatchStorage); | ||
| 190 | - return processor; | ||
| 191 | - } else if (Request.NOTIFY.equalsIgnoreCase(method)) { | ||
| 192 | - NotifyRequestProcessor processor = new NotifyRequestProcessor(); | ||
| 193 | - processor.setRequestEvent(evt); | ||
| 194 | - processor.setTcpSipProvider(getTcpSipProvider()); | ||
| 195 | - processor.setUdpSipProvider(getUdpSipProvider()); | ||
| 196 | - processor.setPublisher(publisher); | ||
| 197 | - processor.setRedis(redis); | ||
| 198 | - processor.setDeferredResultHolder(deferredResultHolder); | ||
| 199 | - processor.setOffLineDetector(offLineDetector); | ||
| 200 | - processor.setCmder(cmder); | ||
| 201 | - processor.setStorager(storager); | ||
| 202 | - processor.setRedisCatchStorage(redisCatchStorage); | ||
| 203 | - return processor; | ||
| 204 | - } else { | ||
| 205 | - OtherRequestProcessor processor = new OtherRequestProcessor(); | ||
| 206 | - processor.setRequestEvent(evt); | ||
| 207 | - return processor; | ||
| 208 | - } | ||
| 209 | - } | ||
| 210 | - | ||
| 211 | - public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) { | ||
| 212 | - | ||
| 213 | - Response response = evt.getResponse(); | ||
| 214 | - CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | ||
| 215 | - String method = cseqHeader.getMethod(); | ||
| 216 | - if(Request.INVITE.equals(method)){ | ||
| 217 | - return inviteResponseProcessor; | ||
| 218 | - } else if (Request.BYE.equals(method)) { | ||
| 219 | - return byeResponseProcessor; | ||
| 220 | - } else if (Request.CANCEL.equals(method)) { | ||
| 221 | - return cancelResponseProcessor; | ||
| 222 | - }else if (Request.REGISTER.equals(method)) { | ||
| 223 | - return registerResponseProcessor; | ||
| 224 | - } else { | ||
| 225 | - return otherResponseProcessor; | ||
| 226 | - } | ||
| 227 | - } | ||
| 228 | - | ||
| 229 | - private SipProvider getTcpSipProvider() { | ||
| 230 | - if (tcpSipProvider == null) { | ||
| 231 | - tcpSipProvider = (SipProvider) SpringBeanFactory.getBean("tcpSipProvider"); | ||
| 232 | - } | ||
| 233 | - return tcpSipProvider; | ||
| 234 | - } | ||
| 235 | - | ||
| 236 | - private SipProvider getUdpSipProvider() { | ||
| 237 | - if (udpSipProvider == null) { | ||
| 238 | - udpSipProvider = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); | ||
| 239 | - } | ||
| 240 | - return udpSipProvider; | ||
| 241 | - } | ||
| 242 | - | ||
| 243 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.transmit; | ||
| 2 | + | ||
| 3 | +import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; | ||
| 4 | +import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor; | ||
| 5 | +import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor; | ||
| 6 | +import org.slf4j.Logger; | ||
| 7 | +import org.slf4j.LoggerFactory; | ||
| 8 | +import org.springframework.stereotype.Component; | ||
| 9 | + | ||
| 10 | +import javax.sip.*; | ||
| 11 | +import javax.sip.header.CSeqHeader; | ||
| 12 | +import java.util.Map; | ||
| 13 | +import java.util.concurrent.ConcurrentHashMap; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * @description: SIP信令处理类观察者 | ||
| 17 | + * @author: panlinlin | ||
| 18 | + * @date: 2021年11月5日 下午15:32 | ||
| 19 | + */ | ||
| 20 | +@Component | ||
| 21 | +public class SIPProcessorObserver implements SipListener { | ||
| 22 | + | ||
| 23 | + private final static Logger logger = LoggerFactory.getLogger(SIPProcessorObserver.class); | ||
| 24 | + | ||
| 25 | + private static Map<String, ISIPRequestProcessor> requestProcessorMap = new ConcurrentHashMap<>(); | ||
| 26 | + private static Map<String, ISIPResponseProcessor> responseProcessorMap = new ConcurrentHashMap<>(); | ||
| 27 | + private static ITimeoutProcessor timeoutProcessor; | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * 添加 request订阅 | ||
| 31 | + * @param method 方法名 | ||
| 32 | + * @param processor 处理程序 | ||
| 33 | + */ | ||
| 34 | + public void addRequestProcessor(String method, ISIPRequestProcessor processor) { | ||
| 35 | + requestProcessorMap.put(method, processor); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 添加 response订阅 | ||
| 40 | + * @param method 方法名 | ||
| 41 | + * @param processor 处理程序 | ||
| 42 | + */ | ||
| 43 | + public void addResponseProcessor(String method, ISIPResponseProcessor processor) { | ||
| 44 | + responseProcessorMap.put(method, processor); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * 添加 超时事件订阅 | ||
| 49 | + * @param processor 处理程序 | ||
| 50 | + */ | ||
| 51 | + public void addTimeoutProcessor(ITimeoutProcessor processor) { | ||
| 52 | + this.timeoutProcessor = processor; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * 分发RequestEvent事件 | ||
| 57 | + * @param requestEvent RequestEvent事件 | ||
| 58 | + */ | ||
| 59 | + @Override | ||
| 60 | + public void processRequest(RequestEvent requestEvent) { | ||
| 61 | + String method = requestEvent.getRequest().getMethod(); | ||
| 62 | + ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method); | ||
| 63 | + if (sipRequestProcessor == null) { | ||
| 64 | + logger.warn("不支持方法{}的request", method); | ||
| 65 | + return; | ||
| 66 | + } | ||
| 67 | + requestProcessorMap.get(requestEvent.getRequest().getMethod()).process(requestEvent); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * 分发ResponseEvent事件 | ||
| 72 | + * @param responseEvent responseEvent事件 | ||
| 73 | + */ | ||
| 74 | + @Override | ||
| 75 | + public void processResponse(ResponseEvent responseEvent) { | ||
| 76 | + CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME); | ||
| 77 | + String method = cseqHeader.getMethod(); | ||
| 78 | + ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method); | ||
| 79 | + if (sipRequestProcessor == null) { | ||
| 80 | + logger.warn("不支持方法{}的response", method); | ||
| 81 | + return; | ||
| 82 | + } | ||
| 83 | + sipRequestProcessor.process(responseEvent); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + /** | ||
| 87 | + * 向超时订阅发送消息 | ||
| 88 | + * @param timeoutEvent timeoutEvent事件 | ||
| 89 | + */ | ||
| 90 | + @Override | ||
| 91 | + public void processTimeout(TimeoutEvent timeoutEvent) { | ||
| 92 | + if(timeoutProcessor != null) { | ||
| 93 | + timeoutProcessor.process(timeoutEvent); | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + @Override | ||
| 98 | + public void processIOException(IOExceptionEvent exceptionEvent) { | ||
| 99 | + | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + @Override | ||
| 103 | + public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { | ||
| 104 | + | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + @Override | ||
| 108 | + public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) { | ||
| 109 | + | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + | ||
| 113 | +} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/CheckForAllRecordsThread.java
| @@ -7,7 +7,7 @@ import java.util.concurrent.TimeUnit; | @@ -7,7 +7,7 @@ import java.util.concurrent.TimeUnit; | ||
| 7 | 7 | ||
| 8 | import com.genersoft.iot.vmp.gb28181.bean.RecordInfo; | 8 | import com.genersoft.iot.vmp.gb28181.bean.RecordInfo; |
| 9 | import com.genersoft.iot.vmp.gb28181.bean.RecordItem; | 9 | import com.genersoft.iot.vmp.gb28181.bean.RecordItem; |
| 10 | -import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor; | 10 | +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.MessageRequestProcessor; |
| 11 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 11 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| 12 | 12 | ||
| 13 | import org.slf4j.Logger; | 13 | import org.slf4j.Logger; |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
| @@ -11,7 +11,7 @@ import org.springframework.stereotype.Component; | @@ -11,7 +11,7 @@ import org.springframework.stereotype.Component; | ||
| 11 | import org.springframework.web.context.request.async.DeferredResult; | 11 | import org.springframework.web.context.request.async.DeferredResult; |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | - * @Description: 异步请求处理 | 14 | + * @description: 异步请求处理 |
| 15 | * @author: swwheihei | 15 | * @author: swwheihei |
| 16 | * @date: 2020年5月8日 下午7:59:05 | 16 | * @date: 2020年5月8日 下午7:59:05 |
| 17 | */ | 17 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java
| 1 | package com.genersoft.iot.vmp.gb28181.transmit.callback; | 1 | package com.genersoft.iot.vmp.gb28181.transmit.callback; |
| 2 | 2 | ||
| 3 | /** | 3 | /** |
| 4 | - * @Description: 请求信息定义 | 4 | + * @description: 请求信息定义 |
| 5 | * @author: swwheihei | 5 | * @author: swwheihei |
| 6 | * @date: 2020年5月8日 下午1:09:18 | 6 | * @date: 2020年5月8日 下午1:09:18 |
| 7 | */ | 7 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | ||
| 7 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; | 7 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | - * @Description:设备能力接口,用于定义设备的控制、查询能力 | 10 | + * @description:设备能力接口,用于定义设备的控制、查询能力 |
| 11 | * @author: swwheihei | 11 | * @author: swwheihei |
| 12 | * @date: 2020年5月3日 下午9:16:34 | 12 | * @date: 2020年5月3日 下午9:16:34 |
| 13 | */ | 13 | */ |
| @@ -299,4 +299,11 @@ public interface ISIPCommander { | @@ -299,4 +299,11 @@ public interface ISIPCommander { | ||
| 299 | * @return true = 命令发送成功 | 299 | * @return true = 命令发送成功 |
| 300 | */ | 300 | */ |
| 301 | boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime); | 301 | boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime); |
| 302 | + | ||
| 303 | + /** | ||
| 304 | + * 订阅、取消订阅目录信息 | ||
| 305 | + * @param device 视频设备 | ||
| 306 | + * @return true = 命令发送成功 | ||
| 307 | + */ | ||
| 308 | + boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent); | ||
| 302 | } | 309 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
| @@ -19,7 +19,7 @@ import java.util.List; | @@ -19,7 +19,7 @@ import java.util.List; | ||
| 19 | import java.util.UUID; | 19 | import java.util.UUID; |
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | - * @Description: 平台命令request创造器 TODO 冗余代码太多待优化 | 22 | + * @description: 平台命令request创造器 TODO 冗余代码太多待优化 |
| 23 | * @author: panll | 23 | * @author: panll |
| 24 | * @date: 2020年5月6日 上午9:29:02 | 24 | * @date: 2020年5月6日 上午9:29:02 |
| 25 | */ | 25 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
| @@ -18,7 +18,7 @@ import com.genersoft.iot.vmp.conf.SipConfig; | @@ -18,7 +18,7 @@ import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 18 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 18 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | - * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化 | 21 | + * @description:摄像头命令request创造器 TODO 冗余代码太多待优化 |
| 22 | * @author: swwheihei | 22 | * @author: swwheihei |
| 23 | * @date: 2020年5月6日 上午9:29:02 | 23 | * @date: 2020年5月6日 上午9:29:02 |
| 24 | */ | 24 | */ |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| 1 | package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; | 1 | package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; |
| 2 | 2 | ||
| 3 | -import java.lang.reflect.Field; | ||
| 4 | -import java.text.ParseException; | ||
| 5 | -import java.util.HashSet; | ||
| 6 | - | ||
| 7 | -import javax.sip.*; | ||
| 8 | -import javax.sip.address.SipURI; | ||
| 9 | -import javax.sip.header.CallIdHeader; | ||
| 10 | -import javax.sip.header.ViaHeader; | ||
| 11 | -import javax.sip.message.Request; | ||
| 12 | - | ||
| 13 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | +import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 14 | import com.genersoft.iot.vmp.conf.UserSetup; | 5 | import com.genersoft.iot.vmp.conf.UserSetup; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 15 | import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | 7 | import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; |
| 16 | -import com.genersoft.iot.vmp.media.zlm.*; | ||
| 17 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 8 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 9 | +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | ||
| 10 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | ||
| 11 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; | ||
| 12 | +import com.genersoft.iot.vmp.gb28181.utils.DateUtil; | ||
| 13 | +import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; | ||
| 14 | +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | ||
| 18 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 15 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 19 | import com.genersoft.iot.vmp.service.IMediaServerService; | 16 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 20 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; | 17 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| @@ -29,20 +26,20 @@ import org.slf4j.LoggerFactory; | @@ -29,20 +26,20 @@ import org.slf4j.LoggerFactory; | ||
| 29 | import org.springframework.beans.factory.annotation.Autowired; | 26 | import org.springframework.beans.factory.annotation.Autowired; |
| 30 | import org.springframework.beans.factory.annotation.Qualifier; | 27 | import org.springframework.beans.factory.annotation.Qualifier; |
| 31 | import org.springframework.context.annotation.DependsOn; | 28 | import org.springframework.context.annotation.DependsOn; |
| 32 | -import org.springframework.context.annotation.Lazy; | ||
| 33 | import org.springframework.stereotype.Component; | 29 | import org.springframework.stereotype.Component; |
| 34 | - | ||
| 35 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 36 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 37 | -import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | ||
| 38 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | ||
| 39 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; | ||
| 40 | -import com.genersoft.iot.vmp.gb28181.utils.DateUtil; | ||
| 41 | -import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; | ||
| 42 | import org.springframework.util.StringUtils; | 30 | import org.springframework.util.StringUtils; |
| 43 | 31 | ||
| 32 | +import javax.sip.*; | ||
| 33 | +import javax.sip.address.SipURI; | ||
| 34 | +import javax.sip.header.CallIdHeader; | ||
| 35 | +import javax.sip.header.ViaHeader; | ||
| 36 | +import javax.sip.message.Request; | ||
| 37 | +import java.lang.reflect.Field; | ||
| 38 | +import java.text.ParseException; | ||
| 39 | +import java.util.HashSet; | ||
| 40 | + | ||
| 44 | /** | 41 | /** |
| 45 | - * @Description:设备能力接口,用于定义设备的控制、查询能力 | 42 | + * @description:设备能力接口,用于定义设备的控制、查询能力 |
| 46 | * @author: swwheihei | 43 | * @author: swwheihei |
| 47 | * @date: 2020年5月3日 下午9:22:48 | 44 | * @date: 2020年5月3日 下午9:22:48 |
| 48 | */ | 45 | */ |
| @@ -55,12 +52,10 @@ public class SIPCommander implements ISIPCommander { | @@ -55,12 +52,10 @@ public class SIPCommander implements ISIPCommander { | ||
| 55 | @Autowired | 52 | @Autowired |
| 56 | private SipConfig sipConfig; | 53 | private SipConfig sipConfig; |
| 57 | 54 | ||
| 58 | - @Lazy | ||
| 59 | @Autowired | 55 | @Autowired |
| 60 | @Qualifier(value="tcpSipProvider") | 56 | @Qualifier(value="tcpSipProvider") |
| 61 | private SipProviderImpl tcpSipProvider; | 57 | private SipProviderImpl tcpSipProvider; |
| 62 | 58 | ||
| 63 | - @Lazy | ||
| 64 | @Autowired | 59 | @Autowired |
| 65 | @Qualifier(value="udpSipProvider") | 60 | @Qualifier(value="udpSipProvider") |
| 66 | private SipProviderImpl udpSipProvider; | 61 | private SipProviderImpl udpSipProvider; |
| @@ -89,11 +84,6 @@ public class SIPCommander implements ISIPCommander { | @@ -89,11 +84,6 @@ public class SIPCommander implements ISIPCommander { | ||
| 89 | @Autowired | 84 | @Autowired |
| 90 | private IMediaServerService mediaServerService; | 85 | private IMediaServerService mediaServerService; |
| 91 | 86 | ||
| 92 | - private SIPDialog dialog; | ||
| 93 | - | ||
| 94 | - public SipConfig getSipConfig() { | ||
| 95 | - return sipConfig; | ||
| 96 | - } | ||
| 97 | 87 | ||
| 98 | /** | 88 | /** |
| 99 | * 云台方向放控制,使用配置文件中的默认镜头移动速度 | 89 | * 云台方向放控制,使用配置文件中的默认镜头移动速度 |
| @@ -1490,6 +1480,33 @@ public class SIPCommander implements ISIPCommander { | @@ -1490,6 +1480,33 @@ public class SIPCommander implements ISIPCommander { | ||
| 1490 | } | 1480 | } |
| 1491 | } | 1481 | } |
| 1492 | 1482 | ||
| 1483 | + @Override | ||
| 1484 | + public boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) { | ||
| 1485 | + try { | ||
| 1486 | + StringBuffer cmdXml = new StringBuffer(200); | ||
| 1487 | + cmdXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n"); | ||
| 1488 | + cmdXml.append("<Query>\r\n"); | ||
| 1489 | + cmdXml.append("<CmdType>CataLog</CmdType>\r\n"); | ||
| 1490 | + cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); | ||
| 1491 | + cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); | ||
| 1492 | + cmdXml.append("</Query>\r\n"); | ||
| 1493 | + | ||
| 1494 | + String tm = Long.toString(System.currentTimeMillis()); | ||
| 1495 | + | ||
| 1496 | + CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() | ||
| 1497 | + : udpSipProvider.getNewCallId(); | ||
| 1498 | + | ||
| 1499 | + Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, device.getSubscribeCycleForCatalog(), "presence" , callIdHeader); | ||
| 1500 | + transmitRequest(device, request, errorEvent, okEvent); | ||
| 1501 | + | ||
| 1502 | + return true; | ||
| 1503 | + | ||
| 1504 | + } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) { | ||
| 1505 | + e.printStackTrace(); | ||
| 1506 | + return false; | ||
| 1507 | + } | ||
| 1508 | + } | ||
| 1509 | + | ||
| 1493 | 1510 | ||
| 1494 | private ClientTransaction transmitRequest(Device device, Request request) throws SipException { | 1511 | private ClientTransaction transmitRequest(Device device, Request request) throws SipException { |
| 1495 | return transmitRequest(device, request, null, null); | 1512 | return transmitRequest(device, request, null, null); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/SIPResponseProcessorAbstract.java
0 → 100644
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/ITimeoutProcessor.java
0 → 100644
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/impl/TimeoutProcessorImpl.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.transmit.event.timeout.impl; | ||
| 2 | + | ||
| 3 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | ||
| 4 | +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | ||
| 5 | +import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor; | ||
| 6 | +import org.springframework.beans.factory.InitializingBean; | ||
| 7 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 8 | +import org.springframework.stereotype.Component; | ||
| 9 | + | ||
| 10 | +import javax.sip.TimeoutEvent; | ||
| 11 | +import javax.sip.header.CallIdHeader; | ||
| 12 | + | ||
| 13 | +@Component | ||
| 14 | +public class TimeoutProcessorImpl implements InitializingBean, ITimeoutProcessor { | ||
| 15 | + | ||
| 16 | + @Autowired | ||
| 17 | + private SIPProcessorObserver processorObserver; | ||
| 18 | + | ||
| 19 | + @Autowired | ||
| 20 | + private SipSubscribe sipSubscribe; | ||
| 21 | + | ||
| 22 | + @Override | ||
| 23 | + public void afterPropertiesSet() throws Exception { | ||
| 24 | + processorObserver.addTimeoutProcessor(this); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + @Override | ||
| 28 | + public void process(TimeoutEvent event) { | ||
| 29 | + // TODO Auto-generated method stub | ||
| 30 | + CallIdHeader callIdHeader = event.getClientTransaction().getDialog().getCallId(); | ||
| 31 | + String callId = callIdHeader.getCallId(); | ||
| 32 | + SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId); | ||
| 33 | + SipSubscribe.EventResult<TimeoutEvent> timeoutEventEventResult = new SipSubscribe.EventResult<>(event); | ||
| 34 | + errorSubscribe.response(timeoutEventEventResult); | ||
| 35 | + } | ||
| 36 | +} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java deleted
100644 → 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request; | ||
| 2 | - | ||
| 3 | -import javax.sip.PeerUnavailableException; | ||
| 4 | -import javax.sip.RequestEvent; | ||
| 5 | -import javax.sip.ServerTransaction; | ||
| 6 | -import javax.sip.SipFactory; | ||
| 7 | -import javax.sip.SipProvider; | ||
| 8 | -import javax.sip.TransactionAlreadyExistsException; | ||
| 9 | -import javax.sip.TransactionUnavailableException; | ||
| 10 | -import javax.sip.address.AddressFactory; | ||
| 11 | -import javax.sip.header.HeaderFactory; | ||
| 12 | -import javax.sip.header.ViaHeader; | ||
| 13 | -import javax.sip.message.MessageFactory; | ||
| 14 | -import javax.sip.message.Request; | ||
| 15 | - | ||
| 16 | -import gov.nist.javax.sip.SipStackImpl; | ||
| 17 | -import gov.nist.javax.sip.message.SIPRequest; | ||
| 18 | -import gov.nist.javax.sip.stack.SIPServerTransaction; | ||
| 19 | -import org.slf4j.Logger; | ||
| 20 | -import org.slf4j.LoggerFactory; | ||
| 21 | - | ||
| 22 | -/** | ||
| 23 | - * @Description:处理接收IPCamera发来的SIP协议请求消息 | ||
| 24 | - * @author: songww | ||
| 25 | - * @date: 2020年5月3日 下午4:42:22 | ||
| 26 | - */ | ||
| 27 | -public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcessor { | ||
| 28 | - | ||
| 29 | - private final static Logger logger = LoggerFactory.getLogger(SIPRequestAbstractProcessor.class); | ||
| 30 | - | ||
| 31 | - protected RequestEvent evt; | ||
| 32 | - | ||
| 33 | - private SipProvider tcpSipProvider; | ||
| 34 | - | ||
| 35 | - private SipProvider udpSipProvider; | ||
| 36 | - | ||
| 37 | - @Override | ||
| 38 | - public void process() { | ||
| 39 | - this.process(evt); | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | - public abstract void process(RequestEvent evt); | ||
| 43 | - | ||
| 44 | - public ServerTransaction getServerTransaction(RequestEvent evt) { | ||
| 45 | - Request request = evt.getRequest(); | ||
| 46 | - ServerTransaction serverTransaction = evt.getServerTransaction(); | ||
| 47 | - // 判断TCP还是UDP | ||
| 48 | - boolean isTcp = false; | ||
| 49 | - ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | ||
| 50 | - String transport = reqViaHeader.getTransport(); | ||
| 51 | - if (transport.equals("TCP")) { | ||
| 52 | - isTcp = true; | ||
| 53 | - } | ||
| 54 | - | ||
| 55 | - if (serverTransaction == null) { | ||
| 56 | - try { | ||
| 57 | - if (isTcp) { | ||
| 58 | - SipStackImpl stack = (SipStackImpl)tcpSipProvider.getSipStack(); | ||
| 59 | - serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true); | ||
| 60 | - if (serverTransaction == null) { | ||
| 61 | - serverTransaction = tcpSipProvider.getNewServerTransaction(request); | ||
| 62 | - } | ||
| 63 | - } else { | ||
| 64 | - SipStackImpl stack = (SipStackImpl)udpSipProvider.getSipStack(); | ||
| 65 | - serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true); | ||
| 66 | - if (serverTransaction == null) { | ||
| 67 | - serverTransaction = udpSipProvider.getNewServerTransaction(request); | ||
| 68 | - } | ||
| 69 | - } | ||
| 70 | - } catch (TransactionAlreadyExistsException e) { | ||
| 71 | - logger.error(e.getMessage()); | ||
| 72 | - } catch (TransactionUnavailableException e) { | ||
| 73 | - logger.error(e.getMessage()); | ||
| 74 | - } | ||
| 75 | - } | ||
| 76 | - return serverTransaction; | ||
| 77 | - } | ||
| 78 | - | ||
| 79 | - public AddressFactory getAddressFactory() { | ||
| 80 | - try { | ||
| 81 | - return SipFactory.getInstance().createAddressFactory(); | ||
| 82 | - } catch (PeerUnavailableException e) { | ||
| 83 | - e.printStackTrace(); | ||
| 84 | - } | ||
| 85 | - return null; | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | - public HeaderFactory getHeaderFactory() { | ||
| 89 | - try { | ||
| 90 | - return SipFactory.getInstance().createHeaderFactory(); | ||
| 91 | - } catch (PeerUnavailableException e) { | ||
| 92 | - e.printStackTrace(); | ||
| 93 | - } | ||
| 94 | - return null; | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - public MessageFactory getMessageFactory() { | ||
| 98 | - try { | ||
| 99 | - return SipFactory.getInstance().createMessageFactory(); | ||
| 100 | - } catch (PeerUnavailableException e) { | ||
| 101 | - e.printStackTrace(); | ||
| 102 | - } | ||
| 103 | - return null; | ||
| 104 | - } | ||
| 105 | - | ||
| 106 | - public RequestEvent getRequestEvent() { | ||
| 107 | - return evt; | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | - public void setRequestEvent(RequestEvent evt) { | ||
| 111 | - this.evt = evt; | ||
| 112 | - } | ||
| 113 | - | ||
| 114 | - public SipProvider getTcpSipProvider() { | ||
| 115 | - return tcpSipProvider; | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - public void setTcpSipProvider(SipProvider tcpSipProvider) { | ||
| 119 | - this.tcpSipProvider = tcpSipProvider; | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - public SipProvider getUdpSipProvider() { | ||
| 123 | - return udpSipProvider; | ||
| 124 | - } | ||
| 125 | - | ||
| 126 | - public void setUdpSipProvider(SipProvider udpSipProvider) { | ||
| 127 | - this.udpSipProvider = udpSipProvider; | ||
| 128 | - } | ||
| 129 | - | ||
| 130 | - | ||
| 131 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import java.util.HashMap; | ||
| 4 | -import java.util.Map; | ||
| 5 | - | ||
| 6 | -import javax.sip.*; | ||
| 7 | -import javax.sip.address.SipURI; | ||
| 8 | -import javax.sip.header.FromHeader; | ||
| 9 | -import javax.sip.header.HeaderAddress; | ||
| 10 | -import javax.sip.header.ToHeader; | ||
| 11 | - | ||
| 12 | -import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 13 | -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | ||
| 14 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 15 | -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | ||
| 16 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | ||
| 17 | -import com.genersoft.iot.vmp.service.IMediaServerService; | ||
| 18 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 19 | -import org.slf4j.Logger; | ||
| 20 | -import org.slf4j.LoggerFactory; | ||
| 21 | - | ||
| 22 | -/** | ||
| 23 | - * @Description:ACK请求处理器 | ||
| 24 | - * @author: swwheihei | ||
| 25 | - * @date: 2020年5月3日 下午5:31:45 | ||
| 26 | - */ | ||
| 27 | -public class AckRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 28 | - | ||
| 29 | - private Logger logger = LoggerFactory.getLogger(AckRequestProcessor.class); | ||
| 30 | - | ||
| 31 | - private IRedisCatchStorage redisCatchStorage; | ||
| 32 | - | ||
| 33 | - private ZLMRTPServerFactory zlmrtpServerFactory; | ||
| 34 | - | ||
| 35 | - private IMediaServerService mediaServerService; | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * 处理 ACK请求 | ||
| 39 | - * | ||
| 40 | - * @param evt | ||
| 41 | - */ | ||
| 42 | - @Override | ||
| 43 | - public void process(RequestEvent evt) { | ||
| 44 | - //Request request = evt.getRequest(); | ||
| 45 | - Dialog dialog = evt.getDialog(); | ||
| 46 | - if (dialog == null) return; | ||
| 47 | - //DialogState state = dialog.getState(); | ||
| 48 | - if (/*request.getMecodewwthod().equals(Request.INVITE) &&*/ dialog.getState()== DialogState.CONFIRMED) { | ||
| 49 | - String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 50 | - String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 51 | - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); | ||
| 52 | - String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; | ||
| 53 | - String deviceId = sendRtpItem.getDeviceId(); | ||
| 54 | - StreamInfo streamInfo = null; | ||
| 55 | - if (deviceId == null) { | ||
| 56 | - streamInfo = new StreamInfo(); | ||
| 57 | - streamInfo.setApp(sendRtpItem.getApp()); | ||
| 58 | - streamInfo.setStreamId(sendRtpItem.getStreamId()); | ||
| 59 | - }else { | ||
| 60 | - streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); | ||
| 61 | - sendRtpItem.setStreamId(streamInfo.getStreamId()); | ||
| 62 | - streamInfo.setApp("rtp"); | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - redisCatchStorage.updateSendRTPSever(sendRtpItem); | ||
| 66 | - logger.info(platformGbId); | ||
| 67 | - logger.info(channelId); | ||
| 68 | - Map<String, Object> param = new HashMap<>(); | ||
| 69 | - param.put("vhost","__defaultVhost__"); | ||
| 70 | - param.put("app",streamInfo.getApp()); | ||
| 71 | - param.put("stream",streamInfo.getStreamId()); | ||
| 72 | - param.put("ssrc", sendRtpItem.getSsrc()); | ||
| 73 | - param.put("dst_url",sendRtpItem.getIp()); | ||
| 74 | - param.put("dst_port", sendRtpItem.getPort()); | ||
| 75 | - param.put("is_udp", is_Udp); | ||
| 76 | - //param.put ("src_port", sendRtpItem.getLocalPort()); | ||
| 77 | - // 设备推流查询,成功后才能转推 | ||
| 78 | - boolean rtpPushed = false; | ||
| 79 | - long startTime = System.currentTimeMillis(); | ||
| 80 | - while (!rtpPushed) { | ||
| 81 | - try { | ||
| 82 | - if (System.currentTimeMillis() - startTime < 30 * 1000) { | ||
| 83 | - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | ||
| 84 | - if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) { | ||
| 85 | - rtpPushed = true; | ||
| 86 | - logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]", | ||
| 87 | - streamInfo.getApp() ,streamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort()); | ||
| 88 | - zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); | ||
| 89 | - } else { | ||
| 90 | - logger.info("等待设备推流[{}/{}].......", | ||
| 91 | - streamInfo.getApp() ,streamInfo.getStreamId()); | ||
| 92 | - Thread.sleep(1000); | ||
| 93 | - continue; | ||
| 94 | - } | ||
| 95 | - } else { | ||
| 96 | - rtpPushed = true; | ||
| 97 | - logger.info("设备推流[{}/{}]超时,终止向上级推流", | ||
| 98 | - streamInfo.getApp() ,streamInfo.getStreamId()); | ||
| 99 | - } | ||
| 100 | - } catch (InterruptedException e) { | ||
| 101 | - e.printStackTrace(); | ||
| 102 | - } | ||
| 103 | - } | ||
| 104 | - } | ||
| 105 | - // try { | ||
| 106 | - // Request ackRequest = null; | ||
| 107 | - // CSeq csReq = (CSeq) request.getHeader(CSeq.NAME); | ||
| 108 | - // ackRequest = dialog.createAck(csReq.getSeqNumber()); | ||
| 109 | - // dialog.sendAck(ackRequest); | ||
| 110 | - // logger.info("send ack to callee:" + ackRequest.toString()); | ||
| 111 | - // } catch (SipException e) { | ||
| 112 | - // e.printStackTrace(); | ||
| 113 | - // } catch (InvalidArgumentException e) { | ||
| 114 | - // e.printStackTrace(); | ||
| 115 | - // } | ||
| 116 | - | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - public IRedisCatchStorage getRedisCatchStorage() { | ||
| 120 | - return redisCatchStorage; | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { | ||
| 124 | - this.redisCatchStorage = redisCatchStorage; | ||
| 125 | - } | ||
| 126 | - | ||
| 127 | - public ZLMRTPServerFactory getZlmrtpServerFactory() { | ||
| 128 | - return zlmrtpServerFactory; | ||
| 129 | - } | ||
| 130 | - | ||
| 131 | - public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { | ||
| 132 | - this.zlmrtpServerFactory = zlmrtpServerFactory; | ||
| 133 | - } | ||
| 134 | - | ||
| 135 | - public IMediaServerService getMediaServerService() { | ||
| 136 | - return mediaServerService; | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | - public void setMediaServerService(IMediaServerService mediaServerService) { | ||
| 140 | - this.mediaServerService = mediaServerService; | ||
| 141 | - } | ||
| 142 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import javax.sip.*; | ||
| 4 | -import javax.sip.address.SipURI; | ||
| 5 | -import javax.sip.header.FromHeader; | ||
| 6 | -import javax.sip.header.HeaderAddress; | ||
| 7 | -import javax.sip.header.ToHeader; | ||
| 8 | -import javax.sip.message.Response; | ||
| 9 | - | ||
| 10 | -import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 11 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 12 | -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | ||
| 13 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | ||
| 14 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 15 | -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | ||
| 16 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | ||
| 17 | -import com.genersoft.iot.vmp.service.IMediaServerService; | ||
| 18 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 19 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 20 | -import org.slf4j.Logger; | ||
| 21 | -import org.slf4j.LoggerFactory; | ||
| 22 | - | ||
| 23 | -import java.text.ParseException; | ||
| 24 | -import java.util.HashMap; | ||
| 25 | -import java.util.Map; | ||
| 26 | - | ||
| 27 | -/** | ||
| 28 | - * @Description: BYE请求处理器 | ||
| 29 | - * @author: lawrencehj | ||
| 30 | - * @date: 2021年3月9日 | ||
| 31 | - */ | ||
| 32 | -public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 33 | - | ||
| 34 | - private Logger logger = LoggerFactory.getLogger(ByeRequestProcessor.class); | ||
| 35 | - | ||
| 36 | - private ISIPCommander cmder; | ||
| 37 | - | ||
| 38 | - private IRedisCatchStorage redisCatchStorage; | ||
| 39 | - | ||
| 40 | - private IVideoManagerStorager storager; | ||
| 41 | - | ||
| 42 | - private ZLMRTPServerFactory zlmrtpServerFactory; | ||
| 43 | - | ||
| 44 | - private IMediaServerService mediaServerService; | ||
| 45 | - | ||
| 46 | - /** | ||
| 47 | - * 处理BYE请求 | ||
| 48 | - * @param evt | ||
| 49 | - */ | ||
| 50 | - @Override | ||
| 51 | - public void process(RequestEvent evt) { | ||
| 52 | - try { | ||
| 53 | - responseAck(evt); | ||
| 54 | - Dialog dialog = evt.getDialog(); | ||
| 55 | - if (dialog == null) return; | ||
| 56 | - if (dialog.getState().equals(DialogState.TERMINATED)) { | ||
| 57 | - String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 58 | - String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 59 | - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); | ||
| 60 | - logger.info("收到bye, [{}/{}]", platformGbId, channelId); | ||
| 61 | - if (sendRtpItem != null){ | ||
| 62 | - String streamId = sendRtpItem.getStreamId(); | ||
| 63 | - Map<String, Object> param = new HashMap<>(); | ||
| 64 | - param.put("vhost","__defaultVhost__"); | ||
| 65 | - param.put("app",sendRtpItem.getApp()); | ||
| 66 | - param.put("stream",streamId); | ||
| 67 | - param.put("ssrc",sendRtpItem.getSsrc()); | ||
| 68 | - logger.info("停止向上级推流:" + streamId); | ||
| 69 | - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | ||
| 70 | - zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | ||
| 71 | - redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); | ||
| 72 | - if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) { | ||
| 73 | - logger.info(streamId + "无其它观看者,通知设备停止推流"); | ||
| 74 | - cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId); | ||
| 75 | - } | ||
| 76 | - } | ||
| 77 | - // 可能是设备主动停止 | ||
| 78 | - Device device = storager.queryVideoDeviceByChannelId(platformGbId); | ||
| 79 | - if (device != null) { | ||
| 80 | - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); | ||
| 81 | - if (streamInfo != null) { | ||
| 82 | - redisCatchStorage.stopPlay(streamInfo); | ||
| 83 | - } | ||
| 84 | - storager.stopPlay(device.getDeviceId(), channelId); | ||
| 85 | - mediaServerService.closeRTPServer(device, channelId); | ||
| 86 | - } | ||
| 87 | - } | ||
| 88 | - } catch (SipException e) { | ||
| 89 | - e.printStackTrace(); | ||
| 90 | - } catch (InvalidArgumentException e) { | ||
| 91 | - e.printStackTrace(); | ||
| 92 | - } catch (ParseException e) { | ||
| 93 | - e.printStackTrace(); | ||
| 94 | - } | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - /*** | ||
| 98 | - * 回复200 OK | ||
| 99 | - * @param evt | ||
| 100 | - * @throws SipException | ||
| 101 | - * @throws InvalidArgumentException | ||
| 102 | - * @throws ParseException | ||
| 103 | - */ | ||
| 104 | - private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { | ||
| 105 | - Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); | ||
| 106 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 107 | - serverTransaction.sendResponse(response); | ||
| 108 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | ||
| 109 | - } | ||
| 110 | - | ||
| 111 | - public IRedisCatchStorage getRedisCatchStorage() { | ||
| 112 | - return redisCatchStorage; | ||
| 113 | - } | ||
| 114 | - | ||
| 115 | - public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { | ||
| 116 | - this.redisCatchStorage = redisCatchStorage; | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - public ZLMRTPServerFactory getZlmrtpServerFactory() { | ||
| 120 | - return zlmrtpServerFactory; | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { | ||
| 124 | - this.zlmrtpServerFactory = zlmrtpServerFactory; | ||
| 125 | - } | ||
| 126 | - | ||
| 127 | - public ISIPCommander getSIPCommander() { | ||
| 128 | - return cmder; | ||
| 129 | - } | ||
| 130 | - | ||
| 131 | - public void setSIPCommander(ISIPCommander cmder) { | ||
| 132 | - this.cmder = cmder; | ||
| 133 | - } | ||
| 134 | - | ||
| 135 | - public IMediaServerService getMediaServerService() { | ||
| 136 | - return mediaServerService; | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | - public void setMediaServerService(IMediaServerService mediaServerService) { | ||
| 140 | - this.mediaServerService = mediaServerService; | ||
| 141 | - } | ||
| 142 | - | ||
| 143 | - public IVideoManagerStorager getStorager() { | ||
| 144 | - return storager; | ||
| 145 | - } | ||
| 146 | - | ||
| 147 | - public void setStorager(IVideoManagerStorager storager) { | ||
| 148 | - this.storager = storager; | ||
| 149 | - } | ||
| 150 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import javax.sip.RequestEvent; | ||
| 4 | - | ||
| 5 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 6 | - | ||
| 7 | -/** | ||
| 8 | - * @Description:CANCEL请求处理器 | ||
| 9 | - * @author: swwheihei | ||
| 10 | - * @date: 2020年5月3日 下午5:32:23 | ||
| 11 | - */ | ||
| 12 | -public class CancelRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 13 | - | ||
| 14 | - /** | ||
| 15 | - * 处理CANCEL请求 | ||
| 16 | - * | ||
| 17 | - * @param evt | ||
| 18 | - * @param layer | ||
| 19 | - * @param transaction | ||
| 20 | - * @param config | ||
| 21 | - */ | ||
| 22 | - @Override | ||
| 23 | - public void process(RequestEvent evt) { | ||
| 24 | - // TODO 优先级99 Cancel Request消息实现,此消息一般为级联消息,上级给下级发送请求取消指令 | ||
| 25 | - | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import javax.sdp.*; | ||
| 4 | -import javax.sip.*; | ||
| 5 | -import javax.sip.address.Address; | ||
| 6 | -import javax.sip.address.SipURI; | ||
| 7 | -import javax.sip.header.*; | ||
| 8 | -import javax.sip.message.Request; | ||
| 9 | -import javax.sip.message.Response; | ||
| 10 | - | ||
| 11 | -import com.genersoft.iot.vmp.gb28181.bean.*; | ||
| 12 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 13 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | ||
| 14 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 15 | -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | ||
| 16 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | ||
| 17 | -import com.genersoft.iot.vmp.service.IMediaServerService; | ||
| 18 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 19 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 20 | -import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; | ||
| 21 | -import com.genersoft.iot.vmp.service.IPlayService; | ||
| 22 | -import gov.nist.javax.sip.address.AddressImpl; | ||
| 23 | -import gov.nist.javax.sip.address.SipUri; | ||
| 24 | -import org.slf4j.Logger; | ||
| 25 | -import org.slf4j.LoggerFactory; | ||
| 26 | - | ||
| 27 | -import java.text.ParseException; | ||
| 28 | -import java.util.Vector; | ||
| 29 | - | ||
| 30 | -/** | ||
| 31 | - * @Description:处理INVITE请求 | ||
| 32 | - * @author: panll | ||
| 33 | - * @date: 2021年1月14日 | ||
| 34 | - */ | ||
| 35 | -@SuppressWarnings("rawtypes") | ||
| 36 | -public class InviteRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 37 | - | ||
| 38 | - private final static Logger logger = LoggerFactory.getLogger(InviteRequestProcessor.class); | ||
| 39 | - | ||
| 40 | - private SIPCommanderFroPlatform cmderFroPlatform; | ||
| 41 | - | ||
| 42 | - private IVideoManagerStorager storager; | ||
| 43 | - | ||
| 44 | - private IRedisCatchStorage redisCatchStorage; | ||
| 45 | - | ||
| 46 | - private SIPCommander cmder; | ||
| 47 | - | ||
| 48 | - private IPlayService playService; | ||
| 49 | - | ||
| 50 | - private ZLMRTPServerFactory zlmrtpServerFactory; | ||
| 51 | - | ||
| 52 | - private IMediaServerService mediaServerService; | ||
| 53 | - | ||
| 54 | - public ZLMRTPServerFactory getZlmrtpServerFactory() { | ||
| 55 | - return zlmrtpServerFactory; | ||
| 56 | - } | ||
| 57 | - | ||
| 58 | - public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { | ||
| 59 | - this.zlmrtpServerFactory = zlmrtpServerFactory; | ||
| 60 | - } | ||
| 61 | - | ||
| 62 | - /** | ||
| 63 | - * 处理invite请求 | ||
| 64 | - * | ||
| 65 | - * @param evt | ||
| 66 | - * 请求消息 | ||
| 67 | - */ | ||
| 68 | - @Override | ||
| 69 | - public void process(RequestEvent evt) { | ||
| 70 | - // Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令 | ||
| 71 | - try { | ||
| 72 | - Request request = evt.getRequest(); | ||
| 73 | - SipURI sipURI = (SipURI) request.getRequestURI(); | ||
| 74 | - String channelId = sipURI.getUser(); | ||
| 75 | - String requesterId = null; | ||
| 76 | - | ||
| 77 | - FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); | ||
| 78 | - AddressImpl address = (AddressImpl) fromHeader.getAddress(); | ||
| 79 | - SipUri uri = (SipUri) address.getURI(); | ||
| 80 | - requesterId = uri.getUser(); | ||
| 81 | - | ||
| 82 | - if (requesterId == null || channelId == null) { | ||
| 83 | - logger.info("无法从FromHeader的Address中获取到平台id,返回400"); | ||
| 84 | - responseAck(evt, Response.BAD_REQUEST); // 参数不全, 发400,请求错误 | ||
| 85 | - return; | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | - // 查询请求方是否上级平台 | ||
| 89 | - ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId); | ||
| 90 | - if (platform != null) { | ||
| 91 | - // 查询平台下是否有该通道 | ||
| 92 | - DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); | ||
| 93 | - GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); | ||
| 94 | - MediaServerItem mediaServerItem = null; | ||
| 95 | - // 不是通道可能是直播流 | ||
| 96 | - if (channel != null && gbStream == null ) { | ||
| 97 | - if (channel.getStatus() == 0) { | ||
| 98 | - logger.info("通道离线,返回400"); | ||
| 99 | - responseAck(evt, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline"); | ||
| 100 | - return; | ||
| 101 | - } | ||
| 102 | - responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中 | ||
| 103 | - }else if(channel == null && gbStream != null){ | ||
| 104 | - String mediaServerId = gbStream.getMediaServerId(); | ||
| 105 | - mediaServerItem = mediaServerService.getOne(mediaServerId); | ||
| 106 | - if (mediaServerItem == null) { | ||
| 107 | - logger.info("[ app={}, stream={} ]找不到zlm {},返回410",gbStream.getApp(), gbStream.getStream(), mediaServerId); | ||
| 108 | - responseAck(evt, Response.GONE, "media server not found"); | ||
| 109 | - return; | ||
| 110 | - } | ||
| 111 | - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); | ||
| 112 | - if (!streamReady ) { | ||
| 113 | - logger.info("[ app={}, stream={} ]通道离线,返回400",gbStream.getApp(), gbStream.getStream()); | ||
| 114 | - responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline"); | ||
| 115 | - return; | ||
| 116 | - } | ||
| 117 | - responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中 | ||
| 118 | - }else { | ||
| 119 | - logger.info("通道不存在,返回404"); | ||
| 120 | - responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在 | ||
| 121 | - return; | ||
| 122 | - } | ||
| 123 | - // 解析sdp消息, 使用jainsip 自带的sdp解析方式 | ||
| 124 | - String contentString = new String(request.getRawContent()); | ||
| 125 | - | ||
| 126 | - // jainSip不支持y=字段, 移除移除以解析。 | ||
| 127 | - int ssrcIndex = contentString.indexOf("y="); | ||
| 128 | - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 | ||
| 129 | - String ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | ||
| 130 | - String substring = contentString.substring(0, contentString.indexOf("y=")); | ||
| 131 | - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); | ||
| 132 | - | ||
| 133 | - // 获取支持的格式 | ||
| 134 | - Vector mediaDescriptions = sdp.getMediaDescriptions(true); | ||
| 135 | - // 查看是否支持PS 负载96 | ||
| 136 | - //String ip = null; | ||
| 137 | - int port = -1; | ||
| 138 | - //boolean recvonly = false; | ||
| 139 | - boolean mediaTransmissionTCP = false; | ||
| 140 | - Boolean tcpActive = null; | ||
| 141 | - for (Object description : mediaDescriptions) { | ||
| 142 | - MediaDescription mediaDescription = (MediaDescription) description; | ||
| 143 | - Media media = mediaDescription.getMedia(); | ||
| 144 | - | ||
| 145 | - Vector mediaFormats = media.getMediaFormats(false); | ||
| 146 | - if (mediaFormats.contains("96")) { | ||
| 147 | - port = media.getMediaPort(); | ||
| 148 | - //String mediaType = media.getMediaType(); | ||
| 149 | - String protocol = media.getProtocol(); | ||
| 150 | - | ||
| 151 | - // 区分TCP发流还是udp, 当前默认udp | ||
| 152 | - if ("TCP/RTP/AVP".equals(protocol)) { | ||
| 153 | - String setup = mediaDescription.getAttribute("setup"); | ||
| 154 | - if (setup != null) { | ||
| 155 | - mediaTransmissionTCP = true; | ||
| 156 | - if ("active".equals(setup)) { | ||
| 157 | - tcpActive = true; | ||
| 158 | - } else if ("passive".equals(setup)) { | ||
| 159 | - tcpActive = false; | ||
| 160 | - } | ||
| 161 | - } | ||
| 162 | - } | ||
| 163 | - break; | ||
| 164 | - } | ||
| 165 | - } | ||
| 166 | - if (port == -1) { | ||
| 167 | - logger.info("不支持的媒体格式,返回415"); | ||
| 168 | - // 回复不支持的格式 | ||
| 169 | - responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415 | ||
| 170 | - return; | ||
| 171 | - } | ||
| 172 | - String username = sdp.getOrigin().getUsername(); | ||
| 173 | - String addressStr = sdp.getOrigin().getAddress(); | ||
| 174 | - //String sessionName = sdp.getSessionName().getValue(); | ||
| 175 | - logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc); | ||
| 176 | - Device device = null; | ||
| 177 | - // 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标 | ||
| 178 | - if (channel != null) { | ||
| 179 | - device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId); | ||
| 180 | - if (device == null) { | ||
| 181 | - logger.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel); | ||
| 182 | - responseAck(evt, Response.SERVER_INTERNAL_ERROR); | ||
| 183 | - return; | ||
| 184 | - } | ||
| 185 | - mediaServerItem = playService.getNewMediaServerItem(device); | ||
| 186 | - if (mediaServerItem == null) { | ||
| 187 | - logger.warn("未找到可用的zlm"); | ||
| 188 | - responseAck(evt, Response.BUSY_HERE); | ||
| 189 | - return; | ||
| 190 | - } | ||
| 191 | - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, | ||
| 192 | - device.getDeviceId(), channelId, | ||
| 193 | - mediaTransmissionTCP); | ||
| 194 | - if (tcpActive != null) { | ||
| 195 | - sendRtpItem.setTcpActive(tcpActive); | ||
| 196 | - } | ||
| 197 | - if (sendRtpItem == null) { | ||
| 198 | - logger.warn("服务器端口资源不足"); | ||
| 199 | - responseAck(evt, Response.BUSY_HERE); | ||
| 200 | - return; | ||
| 201 | - } | ||
| 202 | - | ||
| 203 | - // 写入redis, 超时时回复 | ||
| 204 | - redisCatchStorage.updateSendRTPSever(sendRtpItem); | ||
| 205 | - // 通知下级推流, | ||
| 206 | - PlayResult playResult = playService.play(mediaServerItem,device.getDeviceId(), channelId, (mediaServerItemInUSe, responseJSON)->{ | ||
| 207 | - // 收到推流, 回复200OK, 等待ack | ||
| 208 | - // if (sendRtpItem == null) return; | ||
| 209 | - sendRtpItem.setStatus(1); | ||
| 210 | - redisCatchStorage.updateSendRTPSever(sendRtpItem); | ||
| 211 | - // TODO 添加对tcp的支持 | ||
| 212 | - | ||
| 213 | - StringBuffer content = new StringBuffer(200); | ||
| 214 | - content.append("v=0\r\n"); | ||
| 215 | - content.append("o="+ channelId +" 0 0 IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n"); | ||
| 216 | - content.append("s=Play\r\n"); | ||
| 217 | - content.append("c=IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n"); | ||
| 218 | - content.append("t=0 0\r\n"); | ||
| 219 | - content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n"); | ||
| 220 | - content.append("a=sendonly\r\n"); | ||
| 221 | - content.append("a=rtpmap:96 PS/90000\r\n"); | ||
| 222 | - content.append("y="+ ssrc + "\r\n"); | ||
| 223 | - content.append("f=\r\n"); | ||
| 224 | - | ||
| 225 | - try { | ||
| 226 | - responseAck(evt, content.toString()); | ||
| 227 | - } catch (SipException e) { | ||
| 228 | - e.printStackTrace(); | ||
| 229 | - } catch (InvalidArgumentException e) { | ||
| 230 | - e.printStackTrace(); | ||
| 231 | - } catch (ParseException e) { | ||
| 232 | - e.printStackTrace(); | ||
| 233 | - } | ||
| 234 | - } ,((event) -> { | ||
| 235 | - // 未知错误。直接转发设备点播的错误 | ||
| 236 | - Response response = null; | ||
| 237 | - try { | ||
| 238 | - response = getMessageFactory().createResponse(event.statusCode, evt.getRequest()); | ||
| 239 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 240 | - serverTransaction.sendResponse(response); | ||
| 241 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | ||
| 242 | - } catch (ParseException | SipException | InvalidArgumentException e) { | ||
| 243 | - e.printStackTrace(); | ||
| 244 | - } | ||
| 245 | - })); | ||
| 246 | - if (logger.isDebugEnabled()) { | ||
| 247 | - logger.debug(playResult.getResult().toString()); | ||
| 248 | - } | ||
| 249 | - | ||
| 250 | - }else if (gbStream != null) { | ||
| 251 | - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, | ||
| 252 | - gbStream.getApp(), gbStream.getStream(), channelId, | ||
| 253 | - mediaTransmissionTCP); | ||
| 254 | - | ||
| 255 | - if (tcpActive != null) { | ||
| 256 | - sendRtpItem.setTcpActive(tcpActive); | ||
| 257 | - } | ||
| 258 | - if (sendRtpItem == null) { | ||
| 259 | - logger.warn("服务器端口资源不足"); | ||
| 260 | - responseAck(evt, Response.BUSY_HERE); | ||
| 261 | - return; | ||
| 262 | - } | ||
| 263 | - | ||
| 264 | - // 写入redis, 超时时回复 | ||
| 265 | - redisCatchStorage.updateSendRTPSever(sendRtpItem); | ||
| 266 | - | ||
| 267 | - sendRtpItem.setStatus(1); | ||
| 268 | - redisCatchStorage.updateSendRTPSever(sendRtpItem); | ||
| 269 | - // TODO 添加对tcp的支持 | ||
| 270 | - StringBuffer content = new StringBuffer(200); | ||
| 271 | - content.append("v=0\r\n"); | ||
| 272 | - content.append("o="+ channelId +" 0 0 IN IP4 "+mediaServerItem.getSdpIp()+"\r\n"); | ||
| 273 | - content.append("s=Play\r\n"); | ||
| 274 | - content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n"); | ||
| 275 | - content.append("t=0 0\r\n"); | ||
| 276 | - content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n"); | ||
| 277 | - content.append("a=sendonly\r\n"); | ||
| 278 | - content.append("a=rtpmap:96 PS/90000\r\n"); | ||
| 279 | - content.append("y="+ ssrc + "\r\n"); | ||
| 280 | - content.append("f=\r\n"); | ||
| 281 | - | ||
| 282 | - try { | ||
| 283 | - responseAck(evt, content.toString()); | ||
| 284 | - } catch (SipException e) { | ||
| 285 | - e.printStackTrace(); | ||
| 286 | - } catch (InvalidArgumentException e) { | ||
| 287 | - e.printStackTrace(); | ||
| 288 | - } catch (ParseException e) { | ||
| 289 | - e.printStackTrace(); | ||
| 290 | - } | ||
| 291 | - } | ||
| 292 | - | ||
| 293 | - } else { | ||
| 294 | - // 非上级平台请求,查询是否设备请求(通常为接收语音广播的设备) | ||
| 295 | - Device device = storager.queryVideoDevice(requesterId); | ||
| 296 | - if (device != null) { | ||
| 297 | - logger.info("收到设备" + requesterId + "的语音广播Invite请求"); | ||
| 298 | - responseAck(evt, Response.TRYING); | ||
| 299 | - | ||
| 300 | - String contentString = new String(request.getRawContent()); | ||
| 301 | - // jainSip不支持y=字段, 移除移除以解析。 | ||
| 302 | - String substring = contentString; | ||
| 303 | - String ssrc = "0000000404"; | ||
| 304 | - int ssrcIndex = contentString.indexOf("y="); | ||
| 305 | - if (ssrcIndex > 0) { | ||
| 306 | - substring = contentString.substring(0, ssrcIndex); | ||
| 307 | - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | ||
| 308 | - } | ||
| 309 | - ssrcIndex = substring.indexOf("f="); | ||
| 310 | - if (ssrcIndex > 0) { | ||
| 311 | - substring = contentString.substring(0, ssrcIndex); | ||
| 312 | - } | ||
| 313 | - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); | ||
| 314 | - | ||
| 315 | - // 获取支持的格式 | ||
| 316 | - Vector mediaDescriptions = sdp.getMediaDescriptions(true); | ||
| 317 | - // 查看是否支持PS 负载96 | ||
| 318 | - int port = -1; | ||
| 319 | - //boolean recvonly = false; | ||
| 320 | - boolean mediaTransmissionTCP = false; | ||
| 321 | - Boolean tcpActive = null; | ||
| 322 | - for (int i = 0; i < mediaDescriptions.size(); i++) { | ||
| 323 | - MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i); | ||
| 324 | - Media media = mediaDescription.getMedia(); | ||
| 325 | - | ||
| 326 | - Vector mediaFormats = media.getMediaFormats(false); | ||
| 327 | - if (mediaFormats.contains("8")) { | ||
| 328 | - port = media.getMediaPort(); | ||
| 329 | - String protocol = media.getProtocol(); | ||
| 330 | - // 区分TCP发流还是udp, 当前默认udp | ||
| 331 | - if ("TCP/RTP/AVP".equals(protocol)) { | ||
| 332 | - String setup = mediaDescription.getAttribute("setup"); | ||
| 333 | - if (setup != null) { | ||
| 334 | - mediaTransmissionTCP = true; | ||
| 335 | - if ("active".equals(setup)) { | ||
| 336 | - tcpActive = true; | ||
| 337 | - } else if ("passive".equals(setup)) { | ||
| 338 | - tcpActive = false; | ||
| 339 | - } | ||
| 340 | - } | ||
| 341 | - } | ||
| 342 | - break; | ||
| 343 | - } | ||
| 344 | - } | ||
| 345 | - if (port == -1) { | ||
| 346 | - logger.info("不支持的媒体格式,返回415"); | ||
| 347 | - // 回复不支持的格式 | ||
| 348 | - responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415 | ||
| 349 | - return; | ||
| 350 | - } | ||
| 351 | - String username = sdp.getOrigin().getUsername(); | ||
| 352 | - String addressStr = sdp.getOrigin().getAddress(); | ||
| 353 | - logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}", username, addressStr, port, ssrc); | ||
| 354 | - | ||
| 355 | - } else { | ||
| 356 | - logger.warn("来自无效设备/平台的请求"); | ||
| 357 | - responseAck(evt, Response.BAD_REQUEST); | ||
| 358 | - } | ||
| 359 | - } | ||
| 360 | - | ||
| 361 | - } catch (SipException | InvalidArgumentException | ParseException e) { | ||
| 362 | - e.printStackTrace(); | ||
| 363 | - logger.warn("sdp解析错误"); | ||
| 364 | - e.printStackTrace(); | ||
| 365 | - } catch (SdpParseException e) { | ||
| 366 | - e.printStackTrace(); | ||
| 367 | - } catch (SdpException e) { | ||
| 368 | - e.printStackTrace(); | ||
| 369 | - } | ||
| 370 | - } | ||
| 371 | - | ||
| 372 | - | ||
| 373 | - /*** | ||
| 374 | - * 回复状态码 | ||
| 375 | - * 100 trying | ||
| 376 | - * 200 OK | ||
| 377 | - * 400 | ||
| 378 | - * 404 | ||
| 379 | - * @param evt | ||
| 380 | - * @throws SipException | ||
| 381 | - * @throws InvalidArgumentException | ||
| 382 | - * @throws ParseException | ||
| 383 | - */ | ||
| 384 | - private void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException { | ||
| 385 | - Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); | ||
| 386 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 387 | - serverTransaction.sendResponse(response); | ||
| 388 | - if (statusCode >= 200) { | ||
| 389 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | ||
| 390 | - } | ||
| 391 | - } | ||
| 392 | - | ||
| 393 | - private void responseAck(RequestEvent evt, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException { | ||
| 394 | - Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); | ||
| 395 | - response.setReasonPhrase(msg); | ||
| 396 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 397 | - serverTransaction.sendResponse(response); | ||
| 398 | - if (statusCode >= 200) { | ||
| 399 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | ||
| 400 | - } | ||
| 401 | - } | ||
| 402 | - | ||
| 403 | - /** | ||
| 404 | - * 回复带sdp的200 | ||
| 405 | - * @param evt | ||
| 406 | - * @param sdp | ||
| 407 | - * @throws SipException | ||
| 408 | - * @throws InvalidArgumentException | ||
| 409 | - * @throws ParseException | ||
| 410 | - */ | ||
| 411 | - private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException { | ||
| 412 | - Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); | ||
| 413 | - SipFactory sipFactory = SipFactory.getInstance(); | ||
| 414 | - ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); | ||
| 415 | - response.setContent(sdp, contentTypeHeader); | ||
| 416 | - | ||
| 417 | - SipURI sipURI = (SipURI)evt.getRequest().getRequestURI(); | ||
| 418 | - | ||
| 419 | - Address concatAddress = sipFactory.createAddressFactory().createAddress( | ||
| 420 | - sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort() | ||
| 421 | - )); | ||
| 422 | - response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); | ||
| 423 | - getServerTransaction(evt).sendResponse(response); | ||
| 424 | - } | ||
| 425 | - | ||
| 426 | - | ||
| 427 | - | ||
| 428 | - | ||
| 429 | - | ||
| 430 | - | ||
| 431 | - public SIPCommanderFroPlatform getCmderFroPlatform() { | ||
| 432 | - return cmderFroPlatform; | ||
| 433 | - } | ||
| 434 | - | ||
| 435 | - public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) { | ||
| 436 | - this.cmderFroPlatform = cmderFroPlatform; | ||
| 437 | - } | ||
| 438 | - | ||
| 439 | - public IVideoManagerStorager getStorager() { | ||
| 440 | - return storager; | ||
| 441 | - } | ||
| 442 | - | ||
| 443 | - public void setStorager(IVideoManagerStorager storager) { | ||
| 444 | - this.storager = storager; | ||
| 445 | - } | ||
| 446 | - | ||
| 447 | - public SIPCommander getCmder() { | ||
| 448 | - return cmder; | ||
| 449 | - } | ||
| 450 | - | ||
| 451 | - public void setCmder(SIPCommander cmder) { | ||
| 452 | - this.cmder = cmder; | ||
| 453 | - } | ||
| 454 | - | ||
| 455 | - public IPlayService getPlayService() { | ||
| 456 | - return playService; | ||
| 457 | - } | ||
| 458 | - | ||
| 459 | - public void setPlayService(IPlayService playService) { | ||
| 460 | - this.playService = playService; | ||
| 461 | - } | ||
| 462 | - | ||
| 463 | - public IRedisCatchStorage getRedisCatchStorage() { | ||
| 464 | - return redisCatchStorage; | ||
| 465 | - } | ||
| 466 | - | ||
| 467 | - public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { | ||
| 468 | - this.redisCatchStorage = redisCatchStorage; | ||
| 469 | - } | ||
| 470 | - | ||
| 471 | - public IMediaServerService getMediaServerService() { | ||
| 472 | - return mediaServerService; | ||
| 473 | - } | ||
| 474 | - | ||
| 475 | - public void setMediaServerService(IMediaServerService mediaServerService) { | ||
| 476 | - this.mediaServerService = mediaServerService; | ||
| 477 | - } | ||
| 478 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import java.io.ByteArrayInputStream; | ||
| 4 | -import java.text.ParseException; | ||
| 5 | -import java.util.*; | ||
| 6 | - | ||
| 7 | -import javax.sip.*; | ||
| 8 | -import javax.sip.address.Address; | ||
| 9 | -import javax.sip.address.SipURI; | ||
| 10 | - | ||
| 11 | -import javax.sip.header.FromHeader; | ||
| 12 | -import javax.sip.header.Header; | ||
| 13 | -import javax.sip.header.HeaderAddress; | ||
| 14 | -import javax.sip.header.ToHeader; | ||
| 15 | -import javax.sip.message.Request; | ||
| 16 | -import javax.sip.message.Response; | ||
| 17 | - | ||
| 18 | -import com.alibaba.fastjson.JSONObject; | ||
| 19 | -import com.genersoft.iot.vmp.VManageBootstrap; | ||
| 20 | -import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 21 | -import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 22 | -import com.genersoft.iot.vmp.conf.UserSetup; | ||
| 23 | -import com.genersoft.iot.vmp.gb28181.bean.*; | ||
| 24 | -import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; | ||
| 25 | -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | ||
| 26 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.CheckForAllRecordsThread; | ||
| 27 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 28 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | ||
| 29 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 30 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | ||
| 31 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 32 | -import com.genersoft.iot.vmp.gb28181.utils.DateUtil; | ||
| 33 | -import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; | ||
| 34 | -import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; | ||
| 35 | -import com.genersoft.iot.vmp.service.IDeviceAlarmService; | ||
| 36 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 37 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 38 | -import com.genersoft.iot.vmp.utils.GpsUtil; | ||
| 39 | -import com.genersoft.iot.vmp.utils.SipUtils; | ||
| 40 | -import com.genersoft.iot.vmp.utils.SpringBeanFactory; | ||
| 41 | -import com.genersoft.iot.vmp.utils.redis.RedisUtil; | ||
| 42 | -import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; | ||
| 43 | - | ||
| 44 | -import gov.nist.javax.sip.SipStackImpl; | ||
| 45 | -import gov.nist.javax.sip.address.AddressImpl; | ||
| 46 | -import gov.nist.javax.sip.address.SipUri; | ||
| 47 | - | ||
| 48 | -import org.dom4j.Document; | ||
| 49 | -import org.dom4j.DocumentException; | ||
| 50 | -import org.dom4j.Element; | ||
| 51 | -import org.dom4j.io.SAXReader; | ||
| 52 | -import org.slf4j.Logger; | ||
| 53 | -import org.slf4j.LoggerFactory; | ||
| 54 | -import org.springframework.util.StringUtils; | ||
| 55 | - | ||
| 56 | -/** | ||
| 57 | - * @Description:MESSAGE请求处理器 | ||
| 58 | - * @author: swwheihei | ||
| 59 | - * @date: 2020年5月3日 下午5:32:41 | ||
| 60 | - */ | ||
| 61 | -@SuppressWarnings(value={"unchecked", "rawtypes"}) | ||
| 62 | -public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 63 | - | ||
| 64 | - public static volatile List<String> threadNameList = new ArrayList(); | ||
| 65 | - | ||
| 66 | - private UserSetup userSetup = (UserSetup) SpringBeanFactory.getBean("userSetup"); | ||
| 67 | - | ||
| 68 | - private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class); | ||
| 69 | - | ||
| 70 | - private SIPCommander cmder; | ||
| 71 | - | ||
| 72 | - private SIPCommanderFroPlatform cmderFroPlatform; | ||
| 73 | - | ||
| 74 | - private IVideoManagerStorager storager; | ||
| 75 | - | ||
| 76 | - private IRedisCatchStorage redisCatchStorage; | ||
| 77 | - | ||
| 78 | - private EventPublisher publisher; | ||
| 79 | - | ||
| 80 | - private RedisUtil redis; | ||
| 81 | - | ||
| 82 | - private DeferredResultHolder deferredResultHolder; | ||
| 83 | - | ||
| 84 | - private DeviceOffLineDetector offLineDetector; | ||
| 85 | - | ||
| 86 | - private IDeviceAlarmService deviceAlarmService; | ||
| 87 | - | ||
| 88 | - private final static String CACHE_RECORDINFO_KEY = "CACHE_RECORDINFO_"; | ||
| 89 | - | ||
| 90 | - private static final String MESSAGE_KEEP_ALIVE = "Keepalive"; | ||
| 91 | - private static final String MESSAGE_CONFIG_DOWNLOAD = "ConfigDownload"; | ||
| 92 | - private static final String MESSAGE_CATALOG = "Catalog"; | ||
| 93 | - private static final String MESSAGE_DEVICE_INFO = "DeviceInfo"; | ||
| 94 | - private static final String MESSAGE_ALARM = "Alarm"; | ||
| 95 | - private static final String MESSAGE_RECORD_INFO = "RecordInfo"; | ||
| 96 | - private static final String MESSAGE_MEDIA_STATUS = "MediaStatus"; | ||
| 97 | - private static final String MESSAGE_BROADCAST = "Broadcast"; | ||
| 98 | - private static final String MESSAGE_DEVICE_STATUS = "DeviceStatus"; | ||
| 99 | - private static final String MESSAGE_DEVICE_CONTROL = "DeviceControl"; | ||
| 100 | - private static final String MESSAGE_DEVICE_CONFIG = "DeviceConfig"; | ||
| 101 | - private static final String MESSAGE_MOBILE_POSITION = "MobilePosition"; | ||
| 102 | - // private static final String MESSAGE_MOBILE_POSITION_INTERVAL = "Interval"; | ||
| 103 | - private static final String MESSAGE_PRESET_QUERY = "PresetQuery"; | ||
| 104 | - | ||
| 105 | - /** | ||
| 106 | - * 处理MESSAGE请求 | ||
| 107 | - * | ||
| 108 | - * @param evt | ||
| 109 | - */ | ||
| 110 | - @Override | ||
| 111 | - public void process(RequestEvent evt) { | ||
| 112 | - | ||
| 113 | - try { | ||
| 114 | - Element rootElement = getRootElement(evt); | ||
| 115 | - String cmd = XmlUtil.getText(rootElement, "CmdType"); | ||
| 116 | - | ||
| 117 | - if (MESSAGE_KEEP_ALIVE.equals(cmd)) { | ||
| 118 | - logger.debug("接收到KeepAlive消息"); | ||
| 119 | - processMessageKeepAlive(evt); | ||
| 120 | - } else if (MESSAGE_CONFIG_DOWNLOAD.equals(cmd)) { | ||
| 121 | - logger.debug("接收到ConfigDownload消息"); | ||
| 122 | - processMessageConfigDownload(evt); | ||
| 123 | - } else if (MESSAGE_CATALOG.equals(cmd)) { | ||
| 124 | - logger.debug("接收到Catalog消息"); | ||
| 125 | - processMessageCatalogList(evt); | ||
| 126 | - } else if (MESSAGE_DEVICE_INFO.equals(cmd)) { | ||
| 127 | - // DeviceInfo消息处理 | ||
| 128 | - processMessageDeviceInfo(evt); | ||
| 129 | - } else if (MESSAGE_DEVICE_STATUS.equals(cmd)) { | ||
| 130 | - // DeviceStatus消息处理 | ||
| 131 | - processMessageDeviceStatus(evt); | ||
| 132 | - } else if (MESSAGE_DEVICE_CONTROL.equals(cmd)) { | ||
| 133 | - logger.debug("接收到DeviceControl消息"); | ||
| 134 | - processMessageDeviceControl(evt); | ||
| 135 | - } else if (MESSAGE_DEVICE_CONFIG.equals(cmd)) { | ||
| 136 | - logger.info("接收到DeviceConfig消息"); | ||
| 137 | - processMessageDeviceConfig(evt); | ||
| 138 | - } else if (MESSAGE_ALARM.equals(cmd)) { | ||
| 139 | - logger.debug("接收到Alarm消息"); | ||
| 140 | - processMessageAlarm(evt); | ||
| 141 | - } else if (MESSAGE_RECORD_INFO.equals(cmd)) { | ||
| 142 | - logger.debug("接收到RecordInfo消息"); | ||
| 143 | - processMessageRecordInfo(evt); | ||
| 144 | - }else if (MESSAGE_MEDIA_STATUS.equals(cmd)) { | ||
| 145 | - logger.debug("接收到MediaStatus消息"); | ||
| 146 | - processMessageMediaStatus(evt); | ||
| 147 | - } else if (MESSAGE_MOBILE_POSITION.equals(cmd)) { | ||
| 148 | - logger.debug("接收到MobilePosition消息"); | ||
| 149 | - processMessageMobilePosition(evt); | ||
| 150 | - } else if (MESSAGE_PRESET_QUERY.equals(cmd)) { | ||
| 151 | - logger.debug("接收到PresetQuery消息"); | ||
| 152 | - processMessagePresetQuery(evt); | ||
| 153 | - } else if (MESSAGE_BROADCAST.equals(cmd)) { | ||
| 154 | - // Broadcast消息处理 | ||
| 155 | - processMessageBroadcast(evt); | ||
| 156 | - } else { | ||
| 157 | - logger.debug("接收到消息:" + cmd); | ||
| 158 | - responseAck(evt); | ||
| 159 | - } | ||
| 160 | - } catch (DocumentException | SipException |InvalidArgumentException | ParseException e) { | ||
| 161 | - e.printStackTrace(); | ||
| 162 | - } | ||
| 163 | - } | ||
| 164 | - | ||
| 165 | - /** | ||
| 166 | - * 处理MobilePosition移动位置消息 | ||
| 167 | - * | ||
| 168 | - * @param evt | ||
| 169 | - */ | ||
| 170 | - private void processMessageMobilePosition(RequestEvent evt) { | ||
| 171 | - try { | ||
| 172 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 173 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 174 | - if (device == null) { | ||
| 175 | - logger.warn("处理MobilePosition移动位置消息时未找到设备信息"); | ||
| 176 | - response404Ack(evt); | ||
| 177 | - return; | ||
| 178 | - } | ||
| 179 | - Element rootElement = getRootElement(evt, device.getCharset()); | ||
| 180 | - | ||
| 181 | - MobilePosition mobilePosition = new MobilePosition(); | ||
| 182 | - if (!StringUtils.isEmpty(device.getName())) { | ||
| 183 | - mobilePosition.setDeviceName(device.getName()); | ||
| 184 | - } | ||
| 185 | - mobilePosition.setDeviceId(deviceId); | ||
| 186 | - mobilePosition.setChannelId(XmlUtil.getText(rootElement, "DeviceID")); | ||
| 187 | - mobilePosition.setTime(XmlUtil.getText(rootElement, "Time")); | ||
| 188 | - mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); | ||
| 189 | - mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); | ||
| 190 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) { | ||
| 191 | - mobilePosition.setSpeed(Double.parseDouble(XmlUtil.getText(rootElement, "Speed"))); | ||
| 192 | - } else { | ||
| 193 | - mobilePosition.setSpeed(0.0); | ||
| 194 | - } | ||
| 195 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Direction"))) { | ||
| 196 | - mobilePosition.setDirection(Double.parseDouble(XmlUtil.getText(rootElement, "Direction"))); | ||
| 197 | - } else { | ||
| 198 | - mobilePosition.setDirection(0.0); | ||
| 199 | - } | ||
| 200 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Altitude"))) { | ||
| 201 | - mobilePosition.setAltitude(Double.parseDouble(XmlUtil.getText(rootElement, "Altitude"))); | ||
| 202 | - } else { | ||
| 203 | - mobilePosition.setAltitude(0.0); | ||
| 204 | - } | ||
| 205 | - mobilePosition.setReportSource("Mobile Position"); | ||
| 206 | - BaiduPoint bp = new BaiduPoint(); | ||
| 207 | - bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude())); | ||
| 208 | - logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat()); | ||
| 209 | - mobilePosition.setGeodeticSystem("BD-09"); | ||
| 210 | - mobilePosition.setCnLng(bp.getBdLng()); | ||
| 211 | - mobilePosition.setCnLat(bp.getBdLat()); | ||
| 212 | - if (!userSetup.getSavePositionHistory()) { | ||
| 213 | - storager.clearMobilePositionsByDeviceId(deviceId); | ||
| 214 | - } | ||
| 215 | - storager.insertMobilePosition(mobilePosition); | ||
| 216 | - //回复 200 OK | ||
| 217 | - responseAck(evt); | ||
| 218 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 219 | - e.printStackTrace(); | ||
| 220 | - } | ||
| 221 | - } | ||
| 222 | - | ||
| 223 | - /** | ||
| 224 | - * 处理DeviceStatus设备状态Message | ||
| 225 | - * | ||
| 226 | - * @param evt | ||
| 227 | - */ | ||
| 228 | - private void processMessageDeviceStatus(RequestEvent evt) { | ||
| 229 | - try { | ||
| 230 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 231 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 232 | - if (device == null) { | ||
| 233 | - logger.warn("处理DeviceStatus设备状态Message时未找到设备信息"); | ||
| 234 | - response404Ack(evt); | ||
| 235 | - return; | ||
| 236 | - } | ||
| 237 | - Element rootElement = getRootElement(evt); | ||
| 238 | - String name = rootElement.getName(); | ||
| 239 | - Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 240 | - String channelId = deviceIdElement.getText(); | ||
| 241 | - if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求 | ||
| 242 | - logger.info("接收到DeviceStatus查询消息"); | ||
| 243 | - FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); | ||
| 244 | - String platformId = ((SipUri) fromHeader.getAddress().getURI()).getUser(); | ||
| 245 | - if (platformId == null) { | ||
| 246 | - response404Ack(evt); | ||
| 247 | - return; | ||
| 248 | - } else { | ||
| 249 | - // 回复200 OK | ||
| 250 | - responseAck(evt); | ||
| 251 | - String sn = rootElement.element("SN").getText(); | ||
| 252 | - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); | ||
| 253 | - cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag()); | ||
| 254 | - } | ||
| 255 | - } else { | ||
| 256 | - logger.info("接收到DeviceStatus应答消息"); | ||
| 257 | - // 检查设备是否存在, 不存在则不回复 | ||
| 258 | - if (storager.exists(deviceId)) { | ||
| 259 | - // 回复200 OK | ||
| 260 | - responseAck(evt); | ||
| 261 | - JSONObject json = new JSONObject(); | ||
| 262 | - XmlUtil.node2Json(rootElement, json); | ||
| 263 | - if (logger.isDebugEnabled()) { | ||
| 264 | - logger.debug(json.toJSONString()); | ||
| 265 | - } | ||
| 266 | - RequestMessage msg = new RequestMessage(); | ||
| 267 | - msg.setKey(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId + channelId); | ||
| 268 | - msg.setData(json); | ||
| 269 | - deferredResultHolder.invokeAllResult(msg); | ||
| 270 | - | ||
| 271 | - if (offLineDetector.isOnline(deviceId)) { | ||
| 272 | - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); | ||
| 273 | - } else { | ||
| 274 | - } | ||
| 275 | - } | ||
| 276 | - } | ||
| 277 | - | ||
| 278 | - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | ||
| 279 | - e.printStackTrace(); | ||
| 280 | - } | ||
| 281 | - } | ||
| 282 | - | ||
| 283 | - /** | ||
| 284 | - * 处理DeviceControl设备状态Message | ||
| 285 | - * | ||
| 286 | - * @param evt | ||
| 287 | - */ | ||
| 288 | - private void processMessageDeviceControl(RequestEvent evt) { | ||
| 289 | - try { | ||
| 290 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 291 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 292 | - if (device == null) { | ||
| 293 | - logger.warn("处理DeviceControl设备状态Message未找到设备信息"); | ||
| 294 | - response404Ack(evt); | ||
| 295 | - return; | ||
| 296 | - } | ||
| 297 | - Element rootElement = getRootElement(evt); | ||
| 298 | - String channelId = XmlUtil.getText(rootElement, "DeviceID"); | ||
| 299 | - //String result = XmlUtil.getText(rootElement, "Result"); | ||
| 300 | - // 回复200 OK | ||
| 301 | - responseAck(evt); | ||
| 302 | - if (rootElement.getName().equals("Response")) {//} !StringUtils.isEmpty(result)) { | ||
| 303 | - // 此处是对本平台发出DeviceControl指令的应答 | ||
| 304 | - JSONObject json = new JSONObject(); | ||
| 305 | - XmlUtil.node2Json(rootElement, json); | ||
| 306 | - if (logger.isDebugEnabled()) { | ||
| 307 | - logger.debug(json.toJSONString()); | ||
| 308 | - } | ||
| 309 | - RequestMessage msg = new RequestMessage(); | ||
| 310 | - String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId; | ||
| 311 | - msg.setKey(key); | ||
| 312 | - msg.setData(json); | ||
| 313 | - deferredResultHolder.invokeAllResult(msg); | ||
| 314 | - } else { | ||
| 315 | - // 此处是上级发出的DeviceControl指令 | ||
| 316 | - String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 317 | - String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); | ||
| 318 | - // 远程启动功能 | ||
| 319 | - if (!StringUtils.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) { | ||
| 320 | - if (deviceId.equals(targetGBId)) { | ||
| 321 | - // 远程启动本平台:需要在重新启动程序后先对SipStack解绑 | ||
| 322 | - logger.info("执行远程启动本平台命令"); | ||
| 323 | - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); | ||
| 324 | - cmderFroPlatform.unregister(parentPlatform, null, null); | ||
| 325 | - | ||
| 326 | - Thread restartThread = new Thread(new Runnable() { | ||
| 327 | - @Override | ||
| 328 | - public void run() { | ||
| 329 | - try { | ||
| 330 | - Thread.sleep(3000); | ||
| 331 | - SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); | ||
| 332 | - SipStackImpl stack = (SipStackImpl)up.getSipStack(); | ||
| 333 | - stack.stop(); | ||
| 334 | - Iterator listener = stack.getListeningPoints(); | ||
| 335 | - while (listener.hasNext()) { | ||
| 336 | - stack.deleteListeningPoint((ListeningPoint) listener.next()); | ||
| 337 | - } | ||
| 338 | - Iterator providers = stack.getSipProviders(); | ||
| 339 | - while (providers.hasNext()) { | ||
| 340 | - stack.deleteSipProvider((SipProvider) providers.next()); | ||
| 341 | - } | ||
| 342 | - VManageBootstrap.restart(); | ||
| 343 | - } catch (InterruptedException ignored) { | ||
| 344 | - } catch (ObjectInUseException e) { | ||
| 345 | - e.printStackTrace(); | ||
| 346 | - } | ||
| 347 | - } | ||
| 348 | - }); | ||
| 349 | - | ||
| 350 | - restartThread.setDaemon(false); | ||
| 351 | - restartThread.start(); | ||
| 352 | - } else { | ||
| 353 | - // 远程启动指定设备 | ||
| 354 | - } | ||
| 355 | - } | ||
| 356 | - // 云台/前端控制命令 | ||
| 357 | - if (!StringUtils.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) { | ||
| 358 | - String cmdString = XmlUtil.getText(rootElement,"PTZCmd"); | ||
| 359 | - Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId); | ||
| 360 | - cmder.fronEndCmd(deviceForPlatform, deviceId, cmdString); | ||
| 361 | - } | ||
| 362 | - } | ||
| 363 | - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | ||
| 364 | - e.printStackTrace(); | ||
| 365 | - } | ||
| 366 | - } | ||
| 367 | - | ||
| 368 | - /** | ||
| 369 | - * 处理DeviceConfig设备状态Message | ||
| 370 | - * | ||
| 371 | - * @param evt | ||
| 372 | - */ | ||
| 373 | - private void processMessageDeviceConfig(RequestEvent evt) { | ||
| 374 | - try { | ||
| 375 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 376 | - // 查询设备是否存在 | ||
| 377 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 378 | - if (device == null) { | ||
| 379 | - logger.warn("处理DeviceConfig设备状态Message消息时未找到设备信息"); | ||
| 380 | - response404Ack(evt); | ||
| 381 | - return; | ||
| 382 | - } | ||
| 383 | - Element rootElement = getRootElement(evt); | ||
| 384 | - String channelId = XmlUtil.getText(rootElement, "DeviceID"); | ||
| 385 | - // 回复200 OK | ||
| 386 | - responseAck(evt); | ||
| 387 | - if (rootElement.getName().equals("Response")) { | ||
| 388 | - // 此处是对本平台发出DeviceControl指令的应答 | ||
| 389 | - JSONObject json = new JSONObject(); | ||
| 390 | - XmlUtil.node2Json(rootElement, json); | ||
| 391 | - if (logger.isDebugEnabled()) { | ||
| 392 | - logger.debug(json.toJSONString()); | ||
| 393 | - } | ||
| 394 | - String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + deviceId + channelId; | ||
| 395 | - RequestMessage msg = new RequestMessage(); | ||
| 396 | - msg.setKey(key); | ||
| 397 | - msg.setData(json); | ||
| 398 | - deferredResultHolder.invokeAllResult(msg); | ||
| 399 | - } else { | ||
| 400 | - // 此处是上级发出的DeviceConfig指令 | ||
| 401 | - } | ||
| 402 | - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | ||
| 403 | - e.printStackTrace(); | ||
| 404 | - } | ||
| 405 | - } | ||
| 406 | - | ||
| 407 | - /** | ||
| 408 | - * 处理ConfigDownload设备状态Message | ||
| 409 | - * | ||
| 410 | - * @param evt | ||
| 411 | - */ | ||
| 412 | - private void processMessageConfigDownload(RequestEvent evt) { | ||
| 413 | - try { | ||
| 414 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 415 | - // 查询设备是否存在 | ||
| 416 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 417 | - if (device == null) { | ||
| 418 | - logger.warn("处理ConfigDownload设备状态Message时未找到设备信息"); | ||
| 419 | - response404Ack(evt); | ||
| 420 | - return; | ||
| 421 | - } | ||
| 422 | - Element rootElement = getRootElement(evt); | ||
| 423 | - String channelId = XmlUtil.getText(rootElement, "DeviceID"); | ||
| 424 | - String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + deviceId + channelId; | ||
| 425 | - // 回复200 OK | ||
| 426 | - responseAck(evt); | ||
| 427 | - if (rootElement.getName().equals("Response")) { | ||
| 428 | - // 此处是对本平台发出DeviceControl指令的应答 | ||
| 429 | - JSONObject json = new JSONObject(); | ||
| 430 | - XmlUtil.node2Json(rootElement, json); | ||
| 431 | - if (logger.isDebugEnabled()) { | ||
| 432 | - logger.debug(json.toJSONString()); | ||
| 433 | - } | ||
| 434 | - RequestMessage msg = new RequestMessage(); | ||
| 435 | - msg.setKey(key); | ||
| 436 | - msg.setData(json); | ||
| 437 | - deferredResultHolder.invokeAllResult(msg); | ||
| 438 | - } else { | ||
| 439 | - // 此处是上级发出的DeviceConfig指令 | ||
| 440 | - } | ||
| 441 | - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | ||
| 442 | - e.printStackTrace(); | ||
| 443 | - } | ||
| 444 | - } | ||
| 445 | - | ||
| 446 | - /** | ||
| 447 | - * 处理PresetQuery预置位列表Message | ||
| 448 | - * | ||
| 449 | - * @param evt | ||
| 450 | - */ | ||
| 451 | - private void processMessagePresetQuery(RequestEvent evt) { | ||
| 452 | - try { | ||
| 453 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 454 | - // 查询设备是否存在 | ||
| 455 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 456 | - if (device == null) { | ||
| 457 | - logger.warn("处理PresetQuery预置位列表Message时未找到设备信息"); | ||
| 458 | - response404Ack(evt); | ||
| 459 | - return; | ||
| 460 | - } | ||
| 461 | - Element rootElement = getRootElement(evt); | ||
| 462 | - String channelId = XmlUtil.getText(rootElement, "DeviceID"); | ||
| 463 | - String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId + channelId; | ||
| 464 | - // 回复200 OK | ||
| 465 | - responseAck(evt); | ||
| 466 | - if (rootElement.getName().equals("Response")) {// !StringUtils.isEmpty(result)) { | ||
| 467 | - // 此处是对本平台发出DeviceControl指令的应答 | ||
| 468 | - JSONObject json = new JSONObject(); | ||
| 469 | - XmlUtil.node2Json(rootElement, json); | ||
| 470 | - if (logger.isDebugEnabled()) { | ||
| 471 | - logger.debug(json.toJSONString()); | ||
| 472 | - } | ||
| 473 | - RequestMessage msg = new RequestMessage(); | ||
| 474 | - msg.setKey(key); | ||
| 475 | - msg.setData(json); | ||
| 476 | - deferredResultHolder.invokeAllResult(msg); | ||
| 477 | - } else { | ||
| 478 | - // 此处是上级发出的DeviceControl指令 | ||
| 479 | - } | ||
| 480 | - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | ||
| 481 | - e.printStackTrace(); | ||
| 482 | - } | ||
| 483 | - } | ||
| 484 | - | ||
| 485 | - /** | ||
| 486 | - * 处理DeviceInfo设备信息Message | ||
| 487 | - * | ||
| 488 | - * @param evt | ||
| 489 | - */ | ||
| 490 | - private void processMessageDeviceInfo(RequestEvent evt) { | ||
| 491 | - try { | ||
| 492 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 493 | - // 查询设备是否存在 | ||
| 494 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 495 | - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(deviceId); | ||
| 496 | - | ||
| 497 | - Element rootElement = getRootElement(evt); | ||
| 498 | - String requestName = rootElement.getName(); | ||
| 499 | - Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 500 | - String channelId = deviceIdElement.getTextTrim(); | ||
| 501 | - String key = DeferredResultHolder.CALLBACK_CMD_DEVICEINFO + deviceId + channelId; | ||
| 502 | - if (device != null ) { | ||
| 503 | - rootElement = getRootElement(evt, device.getCharset()); | ||
| 504 | - } | ||
| 505 | - if (requestName.equals("Query")) { | ||
| 506 | - logger.info("接收到DeviceInfo查询消息"); | ||
| 507 | - FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); | ||
| 508 | - if (parentPlatform == null) { | ||
| 509 | - response404Ack(evt); | ||
| 510 | - return; | ||
| 511 | - } else { | ||
| 512 | - // 回复200 OK | ||
| 513 | - responseAck(evt); | ||
| 514 | - String sn = rootElement.element("SN").getText(); | ||
| 515 | - cmderFroPlatform.deviceInfoResponse(parentPlatform, sn, fromHeader.getTag()); | ||
| 516 | - } | ||
| 517 | - } else { | ||
| 518 | - logger.debug("接收到DeviceInfo应答消息"); | ||
| 519 | - if (device == null) { | ||
| 520 | - logger.warn("处理DeviceInfo设备信息Message时未找到设备信息"); | ||
| 521 | - response404Ack(evt); | ||
| 522 | - return; | ||
| 523 | - } | ||
| 524 | - | ||
| 525 | - device.setName(XmlUtil.getText(rootElement, "DeviceName")); | ||
| 526 | - | ||
| 527 | - device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer")); | ||
| 528 | - device.setModel(XmlUtil.getText(rootElement, "Model")); | ||
| 529 | - device.setFirmware(XmlUtil.getText(rootElement, "Firmware")); | ||
| 530 | - if (StringUtils.isEmpty(device.getStreamMode())) { | ||
| 531 | - device.setStreamMode("UDP"); | ||
| 532 | - } | ||
| 533 | - storager.updateDevice(device); | ||
| 534 | - | ||
| 535 | - RequestMessage msg = new RequestMessage(); | ||
| 536 | - msg.setKey(key); | ||
| 537 | - msg.setData(device); | ||
| 538 | - deferredResultHolder.invokeAllResult(msg); | ||
| 539 | - // 回复200 OK | ||
| 540 | - responseAck(evt); | ||
| 541 | - if (offLineDetector.isOnline(deviceId)) { | ||
| 542 | - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); | ||
| 543 | - } | ||
| 544 | - } | ||
| 545 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 546 | - e.printStackTrace(); | ||
| 547 | - } | ||
| 548 | - } | ||
| 549 | - | ||
| 550 | - /*** | ||
| 551 | - * 收到catalog设备目录列表请求 处理 | ||
| 552 | - * | ||
| 553 | - * @param evt | ||
| 554 | - */ | ||
| 555 | - private void processMessageCatalogList(RequestEvent evt) { | ||
| 556 | - try { | ||
| 557 | - | ||
| 558 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 559 | - // 查询设备是否存在 | ||
| 560 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 561 | - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(deviceId); | ||
| 562 | - | ||
| 563 | - | ||
| 564 | - Element rootElement = getRootElement(evt); | ||
| 565 | - String name = rootElement.getName(); | ||
| 566 | - Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 567 | - String channelId = deviceIdElement.getText(); | ||
| 568 | - Element deviceListElement = rootElement.element("DeviceList"); | ||
| 569 | - String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + deviceId; | ||
| 570 | - FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); | ||
| 571 | - if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求 | ||
| 572 | - // TODO 后续将代码拆分 | ||
| 573 | - if (parentPlatform == null) { | ||
| 574 | - response404Ack(evt); | ||
| 575 | - return; | ||
| 576 | - } else { | ||
| 577 | - // 回复200 OK | ||
| 578 | - responseAck(evt); | ||
| 579 | - | ||
| 580 | - Element snElement = rootElement.element("SN"); | ||
| 581 | - String sn = snElement.getText(); | ||
| 582 | - // 准备回复通道信息 | ||
| 583 | - List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId()); | ||
| 584 | - // 查询关联的直播通道 | ||
| 585 | - List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId()); | ||
| 586 | - int size = channelReduces.size() + gbStreams.size(); | ||
| 587 | - // 回复级联的通道 | ||
| 588 | - if (channelReduces.size() > 0) { | ||
| 589 | - for (ChannelReduce channelReduce : channelReduces) { | ||
| 590 | - DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); | ||
| 591 | - cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); | ||
| 592 | - } | ||
| 593 | - } | ||
| 594 | - // 回复直播的通道 | ||
| 595 | - if (gbStreams.size() > 0) { | ||
| 596 | - for (GbStream gbStream : gbStreams) { | ||
| 597 | - DeviceChannel deviceChannel = new DeviceChannel(); | ||
| 598 | - deviceChannel.setChannelId(gbStream.getGbId()); | ||
| 599 | - deviceChannel.setName(gbStream.getName()); | ||
| 600 | - deviceChannel.setLongitude(gbStream.getLongitude()); | ||
| 601 | - deviceChannel.setLatitude(gbStream.getLatitude()); | ||
| 602 | - deviceChannel.setDeviceId(parentPlatform.getDeviceGBId()); | ||
| 603 | - deviceChannel.setManufacture("wvp-pro"); | ||
| 604 | - deviceChannel.setStatus(gbStream.isStatus()?1:0); | ||
| 605 | -// deviceChannel.setParentId(parentPlatform.getDeviceGBId()); | ||
| 606 | - deviceChannel.setRegisterWay(1); | ||
| 607 | - deviceChannel.setCivilCode(cmder.getSipConfig().getDomain()); | ||
| 608 | - deviceChannel.setModel("live"); | ||
| 609 | - deviceChannel.setOwner("wvp-pro"); | ||
| 610 | -// deviceChannel.setAddress("test"); | ||
| 611 | - deviceChannel.setParental(0); | ||
| 612 | - deviceChannel.setSecrecy("0"); | ||
| 613 | - deviceChannel.setSecrecy("0"); | ||
| 614 | - | ||
| 615 | - cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size); | ||
| 616 | - } | ||
| 617 | - } | ||
| 618 | - if (size == 0) { | ||
| 619 | - // 回复无通道 | ||
| 620 | - cmderFroPlatform.catalogQuery(null, parentPlatform, sn, fromHeader.getTag(), size); | ||
| 621 | - } | ||
| 622 | - } | ||
| 623 | - | ||
| 624 | - | ||
| 625 | - } else { | ||
| 626 | - if (device == null) { | ||
| 627 | - logger.warn("收到catalog设备目录列表请求时未找到设备信息"); | ||
| 628 | - response404Ack(evt); | ||
| 629 | - return; | ||
| 630 | - } | ||
| 631 | - deviceListElement = getRootElement(evt, device.getCharset()).element("DeviceList"); | ||
| 632 | - Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); | ||
| 633 | - if (deviceListIterator != null) { | ||
| 634 | - | ||
| 635 | - // 遍历DeviceList | ||
| 636 | - while (deviceListIterator.hasNext()) { | ||
| 637 | - Element itemDevice = deviceListIterator.next(); | ||
| 638 | - Element channelDeviceElement = itemDevice.element("DeviceID"); | ||
| 639 | - if (channelDeviceElement == null) { | ||
| 640 | - continue; | ||
| 641 | - } | ||
| 642 | - String channelDeviceId = channelDeviceElement.getText(); | ||
| 643 | - Element channdelNameElement = itemDevice.element("Name"); | ||
| 644 | - String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : ""; | ||
| 645 | - Element statusElement = itemDevice.element("Status"); | ||
| 646 | - String status = statusElement != null ? statusElement.getText().toString() : "ON"; | ||
| 647 | - DeviceChannel deviceChannel = new DeviceChannel(); | ||
| 648 | - deviceChannel.setName(channelName); | ||
| 649 | - deviceChannel.setChannelId(channelDeviceId); | ||
| 650 | - // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理 | ||
| 651 | - if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) { | ||
| 652 | - deviceChannel.setStatus(1); | ||
| 653 | - } | ||
| 654 | - if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { | ||
| 655 | - deviceChannel.setStatus(0); | ||
| 656 | - } | ||
| 657 | - | ||
| 658 | - deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer")); | ||
| 659 | - deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model")); | ||
| 660 | - deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner")); | ||
| 661 | - deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode")); | ||
| 662 | - deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block")); | ||
| 663 | - deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address")); | ||
| 664 | - if (XmlUtil.getText(itemDevice, "Parental") == null || XmlUtil.getText(itemDevice, "Parental") == "") { | ||
| 665 | - deviceChannel.setParental(0); | ||
| 666 | - } else { | ||
| 667 | - deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental"))); | ||
| 668 | - } | ||
| 669 | - deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID")); | ||
| 670 | - if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay") == "") { | ||
| 671 | - deviceChannel.setSafetyWay(0); | ||
| 672 | - } else { | ||
| 673 | - deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay"))); | ||
| 674 | - } | ||
| 675 | - if (XmlUtil.getText(itemDevice, "RegisterWay") == null || XmlUtil.getText(itemDevice, "RegisterWay") == "") { | ||
| 676 | - deviceChannel.setRegisterWay(1); | ||
| 677 | - } else { | ||
| 678 | - deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay"))); | ||
| 679 | - } | ||
| 680 | - deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum")); | ||
| 681 | - if (XmlUtil.getText(itemDevice, "Certifiable") == null || XmlUtil.getText(itemDevice, "Certifiable") == "") { | ||
| 682 | - deviceChannel.setCertifiable(0); | ||
| 683 | - } else { | ||
| 684 | - deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable"))); | ||
| 685 | - } | ||
| 686 | - if (XmlUtil.getText(itemDevice, "ErrCode") == null || XmlUtil.getText(itemDevice, "ErrCode") == "") { | ||
| 687 | - deviceChannel.setErrCode(0); | ||
| 688 | - } else { | ||
| 689 | - deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode"))); | ||
| 690 | - } | ||
| 691 | - deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime")); | ||
| 692 | - deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy")); | ||
| 693 | - deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress")); | ||
| 694 | - if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") { | ||
| 695 | - deviceChannel.setPort(0); | ||
| 696 | - } else { | ||
| 697 | - deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port"))); | ||
| 698 | - } | ||
| 699 | - deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password")); | ||
| 700 | - if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) { | ||
| 701 | - deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude"))); | ||
| 702 | - } else { | ||
| 703 | - deviceChannel.setLongitude(0.00); | ||
| 704 | - } | ||
| 705 | - if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) { | ||
| 706 | - deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude"))); | ||
| 707 | - } else { | ||
| 708 | - deviceChannel.setLatitude(0.00); | ||
| 709 | - } | ||
| 710 | - if (XmlUtil.getText(itemDevice, "PTZType") == null || XmlUtil.getText(itemDevice, "PTZType") == "") { | ||
| 711 | - deviceChannel.setPTZType(0); | ||
| 712 | - } else { | ||
| 713 | - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); | ||
| 714 | - } | ||
| 715 | - deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC | ||
| 716 | - storager.updateChannel(device.getDeviceId(), deviceChannel); | ||
| 717 | - } | ||
| 718 | - | ||
| 719 | - RequestMessage msg = new RequestMessage(); | ||
| 720 | - msg.setKey(key); | ||
| 721 | - msg.setData(device); | ||
| 722 | - deferredResultHolder.invokeAllResult(msg); | ||
| 723 | - // 回复200 OK | ||
| 724 | - responseAck(evt); | ||
| 725 | - if (offLineDetector.isOnline(deviceId)) { | ||
| 726 | - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); | ||
| 727 | - } | ||
| 728 | - } | ||
| 729 | - } | ||
| 730 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 731 | - e.printStackTrace(); | ||
| 732 | - } | ||
| 733 | - } | ||
| 734 | - | ||
| 735 | - /*** | ||
| 736 | - * 收到alarm设备报警信息 处理 | ||
| 737 | - * | ||
| 738 | - * @param evt | ||
| 739 | - */ | ||
| 740 | - private void processMessageAlarm(RequestEvent evt) { | ||
| 741 | - try { | ||
| 742 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 743 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 744 | - if (device == null) { | ||
| 745 | - logger.warn("处理alarm设备报警信息未找到设备信息"); | ||
| 746 | - response404Ack(evt); | ||
| 747 | - return; | ||
| 748 | - } | ||
| 749 | - Element rootElement = getRootElement(evt, device.getCharset()); | ||
| 750 | - Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 751 | - String channelId = deviceIdElement.getText().toString(); | ||
| 752 | - String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId + channelId; | ||
| 753 | - // 回复200 OK | ||
| 754 | - responseAck(evt); | ||
| 755 | - | ||
| 756 | - if (device.getCharset() != null) { | ||
| 757 | - rootElement = getRootElement(evt, device.getCharset()); | ||
| 758 | - } | ||
| 759 | - | ||
| 760 | - if (rootElement.getName().equals("Notify")) { // 处理报警通知 | ||
| 761 | - DeviceAlarm deviceAlarm = new DeviceAlarm(); | ||
| 762 | - deviceAlarm.setDeviceId(deviceId); | ||
| 763 | - deviceAlarm.setChannelId(channelId); | ||
| 764 | - deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority")); | ||
| 765 | - deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod")); | ||
| 766 | - deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime")); | ||
| 767 | - if (XmlUtil.getText(rootElement, "AlarmDescription") == null) { | ||
| 768 | - deviceAlarm.setAlarmDescription(""); | ||
| 769 | - } else { | ||
| 770 | - deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription")); | ||
| 771 | - } | ||
| 772 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) { | ||
| 773 | - deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); | ||
| 774 | - } else { | ||
| 775 | - deviceAlarm.setLongitude(0.00); | ||
| 776 | - } | ||
| 777 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) { | ||
| 778 | - deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); | ||
| 779 | - } else { | ||
| 780 | - deviceAlarm.setLatitude(0.00); | ||
| 781 | - } | ||
| 782 | - | ||
| 783 | - if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) { | ||
| 784 | - if ( deviceAlarm.getAlarmMethod().equals("4")) { | ||
| 785 | - MobilePosition mobilePosition = new MobilePosition(); | ||
| 786 | - mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); | ||
| 787 | - mobilePosition.setTime(deviceAlarm.getAlarmTime()); | ||
| 788 | - mobilePosition.setLongitude(deviceAlarm.getLongitude()); | ||
| 789 | - mobilePosition.setLatitude(deviceAlarm.getLatitude()); | ||
| 790 | - mobilePosition.setReportSource("GPS Alarm"); | ||
| 791 | - BaiduPoint bp = new BaiduPoint(); | ||
| 792 | - bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude())); | ||
| 793 | - logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat()); | ||
| 794 | - mobilePosition.setGeodeticSystem("BD-09"); | ||
| 795 | - mobilePosition.setCnLng(bp.getBdLng()); | ||
| 796 | - mobilePosition.setCnLat(bp.getBdLat()); | ||
| 797 | - if (!userSetup.getSavePositionHistory()) { | ||
| 798 | - storager.clearMobilePositionsByDeviceId(deviceId); | ||
| 799 | - } | ||
| 800 | - storager.insertMobilePosition(mobilePosition); | ||
| 801 | - } | ||
| 802 | - } | ||
| 803 | - logger.debug("存储报警信息、报警分类"); | ||
| 804 | - // 存储报警信息、报警分类 | ||
| 805 | - deviceAlarmService.add(deviceAlarm); | ||
| 806 | - | ||
| 807 | - if (offLineDetector.isOnline(deviceId)) { | ||
| 808 | - publisher.deviceAlarmEventPublish(deviceAlarm); | ||
| 809 | - } | ||
| 810 | - } else if (rootElement.getName().equals("Response")) { // 处理报警查询响应 | ||
| 811 | - JSONObject json = new JSONObject(); | ||
| 812 | - XmlUtil.node2Json(rootElement, json); | ||
| 813 | - if (logger.isDebugEnabled()) { | ||
| 814 | - logger.debug(json.toJSONString()); | ||
| 815 | - } | ||
| 816 | - RequestMessage msg = new RequestMessage(); | ||
| 817 | - msg.setKey(key); | ||
| 818 | - msg.setData(json); | ||
| 819 | - deferredResultHolder.invokeAllResult(msg); | ||
| 820 | - } | ||
| 821 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 822 | - e.printStackTrace(); | ||
| 823 | - } | ||
| 824 | - } | ||
| 825 | - | ||
| 826 | - /*** | ||
| 827 | - * 收到keepalive请求 处理 | ||
| 828 | - * | ||
| 829 | - * @param evt | ||
| 830 | - */ | ||
| 831 | - private void processMessageKeepAlive(RequestEvent evt) { | ||
| 832 | - try { | ||
| 833 | - | ||
| 834 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 835 | - // 查询设备是否存在 | ||
| 836 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 837 | - | ||
| 838 | - Element rootElement = getRootElement(evt); | ||
| 839 | - String channelId = XmlUtil.getText(rootElement, "DeviceID"); | ||
| 840 | - | ||
| 841 | - // 检查设备是否存在并在线, 不在线则设置为在线 | ||
| 842 | - if (device != null ) { | ||
| 843 | - // 回复200 OK | ||
| 844 | - responseAck(evt); | ||
| 845 | - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); | ||
| 846 | - }else{ | ||
| 847 | - logger.warn("收到[ "+deviceId+" ]心跳信息, 但是设备不存在, 回复404"); | ||
| 848 | - Response response = getMessageFactory().createResponse(Response.NOT_FOUND, evt.getRequest()); | ||
| 849 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 850 | - serverTransaction.sendResponse(response); | ||
| 851 | - if (serverTransaction.getDialog() != null) { | ||
| 852 | - serverTransaction.getDialog().delete(); | ||
| 853 | - } | ||
| 854 | - } | ||
| 855 | - | ||
| 856 | -// if (device != null && device.getOnline() == 1) { | ||
| 857 | -// | ||
| 858 | -// if (offLineDetector.isOnline(deviceId)) { | ||
| 859 | -// publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); | ||
| 860 | -// } else { | ||
| 861 | -// } | ||
| 862 | -// }else { | ||
| 863 | -//// logger.warn("收到[ "+deviceId+" ]心跳信息, 但是设备" + (device == null? "不存在":"离线") + ", 回复401"); | ||
| 864 | -//// Response response = getMessageFactory().createResponse(Response.UNAUTHORIZED, evt.getRequest()); | ||
| 865 | -//// getServerTransaction(evt).sendResponse(response); | ||
| 866 | -// publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); | ||
| 867 | -// | ||
| 868 | -// } | ||
| 869 | - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | ||
| 870 | - e.printStackTrace(); | ||
| 871 | - } | ||
| 872 | - } | ||
| 873 | - | ||
| 874 | - /*** | ||
| 875 | - * 处理RecordInfo设备录像列表Message请求 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致 | ||
| 876 | - * | ||
| 877 | - * @param evt | ||
| 878 | - */ | ||
| 879 | - private void processMessageRecordInfo(RequestEvent evt) { | ||
| 880 | - try { | ||
| 881 | - | ||
| 882 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 883 | - // 查询设备是否存在 | ||
| 884 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 885 | - if (device == null) { | ||
| 886 | - logger.warn("处理DeviceInfo设备信息Message时未找到设备信息"); | ||
| 887 | - response404Ack(evt); | ||
| 888 | - return; | ||
| 889 | - } | ||
| 890 | - | ||
| 891 | - // 回复200 OK | ||
| 892 | - responseAck(evt); | ||
| 893 | - String uuid = UUID.randomUUID().toString().replace("-", ""); | ||
| 894 | - RecordInfo recordInfo = new RecordInfo(); | ||
| 895 | - Element rootElement = getRootElement(evt); | ||
| 896 | - Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 897 | - String channelId = deviceIdElement.getText().toString(); | ||
| 898 | - String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + channelId; | ||
| 899 | - if (device != null ) { | ||
| 900 | - rootElement = getRootElement(evt, device.getCharset()); | ||
| 901 | - } | ||
| 902 | - recordInfo.setDeviceId(deviceId); | ||
| 903 | - recordInfo.setChannelId(channelId); | ||
| 904 | - recordInfo.setName(XmlUtil.getText(rootElement, "Name")); | ||
| 905 | - if (XmlUtil.getText(rootElement, "SumNum")== null || XmlUtil.getText(rootElement, "SumNum") =="") { | ||
| 906 | - recordInfo.setSumNum(0); | ||
| 907 | - } else { | ||
| 908 | - recordInfo.setSumNum(Integer.parseInt(XmlUtil.getText(rootElement, "SumNum"))); | ||
| 909 | - } | ||
| 910 | - String sn = XmlUtil.getText(rootElement, "SN"); | ||
| 911 | - Element recordListElement = rootElement.element("RecordList"); | ||
| 912 | - if (recordListElement == null || recordInfo.getSumNum() == 0) { | ||
| 913 | - logger.info("无录像数据"); | ||
| 914 | - RequestMessage msg = new RequestMessage(); | ||
| 915 | - msg.setKey(key); | ||
| 916 | - msg.setData(recordInfo); | ||
| 917 | - deferredResultHolder.invokeAllResult(msg); | ||
| 918 | - } else { | ||
| 919 | - Iterator<Element> recordListIterator = recordListElement.elementIterator(); | ||
| 920 | - List<RecordItem> recordList = new ArrayList<RecordItem>(); | ||
| 921 | - if (recordListIterator != null) { | ||
| 922 | - RecordItem record = new RecordItem(); | ||
| 923 | - logger.info("处理录像列表数据..."); | ||
| 924 | - // 遍历DeviceList | ||
| 925 | - while (recordListIterator.hasNext()) { | ||
| 926 | - Element itemRecord = recordListIterator.next(); | ||
| 927 | - Element recordElement = itemRecord.element("DeviceID"); | ||
| 928 | - if (recordElement == null) { | ||
| 929 | - logger.info("记录为空,下一个..."); | ||
| 930 | - continue; | ||
| 931 | - } | ||
| 932 | - record = new RecordItem(); | ||
| 933 | - record.setDeviceId(XmlUtil.getText(itemRecord, "DeviceID")); | ||
| 934 | - record.setName(XmlUtil.getText(itemRecord, "Name")); | ||
| 935 | - record.setFilePath(XmlUtil.getText(itemRecord, "FilePath")); | ||
| 936 | - record.setAddress(XmlUtil.getText(itemRecord, "Address")); | ||
| 937 | - record.setStartTime( | ||
| 938 | - DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(XmlUtil.getText(itemRecord, "StartTime"))); | ||
| 939 | - record.setEndTime( | ||
| 940 | - DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(XmlUtil.getText(itemRecord, "EndTime"))); | ||
| 941 | - record.setSecrecy(itemRecord.element("Secrecy") == null ? 0 | ||
| 942 | - : Integer.parseInt(XmlUtil.getText(itemRecord, "Secrecy"))); | ||
| 943 | - record.setType(XmlUtil.getText(itemRecord, "Type")); | ||
| 944 | - record.setRecorderId(XmlUtil.getText(itemRecord, "RecorderID")); | ||
| 945 | - recordList.add(record); | ||
| 946 | - } | ||
| 947 | - recordInfo.setRecordList(recordList); | ||
| 948 | - } | ||
| 949 | - | ||
| 950 | - // 改用单独线程统计已获取录像文件数量,避免多包并行分别统计不完整的问题 | ||
| 951 | - String cacheKey = CACHE_RECORDINFO_KEY + deviceId + sn; | ||
| 952 | - redis.set(cacheKey + "_" + uuid, recordList, 90); | ||
| 953 | - if (!threadNameList.contains(cacheKey)) { | ||
| 954 | - threadNameList.add(cacheKey); | ||
| 955 | - CheckForAllRecordsThread chk = new CheckForAllRecordsThread(cacheKey, recordInfo); | ||
| 956 | - chk.setName(cacheKey); | ||
| 957 | - chk.setDeferredResultHolder(deferredResultHolder); | ||
| 958 | - chk.setRedis(redis); | ||
| 959 | - chk.setLogger(logger); | ||
| 960 | - chk.start(); | ||
| 961 | - if (logger.isDebugEnabled()) { | ||
| 962 | - logger.debug("Start Thread " + cacheKey + "."); | ||
| 963 | - } | ||
| 964 | - } else { | ||
| 965 | - if (logger.isDebugEnabled()) { | ||
| 966 | - logger.debug("Thread " + cacheKey + " already started."); | ||
| 967 | - } | ||
| 968 | - } | ||
| 969 | - | ||
| 970 | - // 存在录像且如果当前录像明细个数小于总条数,说明拆包返回,需要组装,暂不返回 | ||
| 971 | - // if (recordInfo.getSumNum() > 0 && recordList.size() > 0 && recordList.size() < recordInfo.getSumNum()) { | ||
| 972 | - // // 为防止连续请求该设备的录像数据,返回数据错乱,特增加sn进行区分 | ||
| 973 | - // String cacheKey = CACHE_RECORDINFO_KEY + deviceId + sn; | ||
| 974 | - | ||
| 975 | - // redis.set(cacheKey + "_" + uuid, recordList, 90); | ||
| 976 | - // List<Object> cacheKeys = redis.scan(cacheKey + "_*"); | ||
| 977 | - // List<RecordItem> totalRecordList = new ArrayList<RecordItem>(); | ||
| 978 | - // for (int i = 0; i < cacheKeys.size(); i++) { | ||
| 979 | - // totalRecordList.addAll((List<RecordItem>) redis.get(cacheKeys.get(i).toString())); | ||
| 980 | - // } | ||
| 981 | - // if (totalRecordList.size() < recordInfo.getSumNum()) { | ||
| 982 | - // logger.info("已获取" + totalRecordList.size() + "项录像数据,共" + recordInfo.getSumNum() + "项"); | ||
| 983 | - // return; | ||
| 984 | - // } | ||
| 985 | - // logger.info("录像数据已全部获取,共" + recordInfo.getSumNum() + "项"); | ||
| 986 | - // recordInfo.setRecordList(totalRecordList); | ||
| 987 | - // for (int i = 0; i < cacheKeys.size(); i++) { | ||
| 988 | - // redis.del(cacheKeys.get(i).toString()); | ||
| 989 | - // } | ||
| 990 | - // } | ||
| 991 | - // // 自然顺序排序, 元素进行升序排列 | ||
| 992 | - // recordInfo.getRecordList().sort(Comparator.naturalOrder()); | ||
| 993 | - } | ||
| 994 | - // 走到这里,有以下可能:1、没有录像信息,第一次收到recordinfo的消息即返回响应数据,无redis操作 | ||
| 995 | - // 2、有录像数据,且第一次即收到完整数据,返回响应数据,无redis操作 | ||
| 996 | - // 3、有录像数据,在超时时间内收到多次包组装后数量足够,返回数据 | ||
| 997 | - | ||
| 998 | - // RequestMessage msg = new RequestMessage(); | ||
| 999 | - // msg.setDeviceId(deviceId); | ||
| 1000 | - // msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO); | ||
| 1001 | - // msg.setData(recordInfo); | ||
| 1002 | - // deferredResultHolder.invokeResult(msg); | ||
| 1003 | - // logger.info("处理完成,返回结果"); | ||
| 1004 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 1005 | - e.printStackTrace(); | ||
| 1006 | - } | ||
| 1007 | - } | ||
| 1008 | - | ||
| 1009 | - /** | ||
| 1010 | - * 收到MediaStatus消息处理 | ||
| 1011 | - * | ||
| 1012 | - * @param evt | ||
| 1013 | - */ | ||
| 1014 | - private void processMessageMediaStatus(RequestEvent evt){ | ||
| 1015 | - try { | ||
| 1016 | - | ||
| 1017 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 1018 | - // 查询设备是否存在 | ||
| 1019 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 1020 | - if (device == null) { | ||
| 1021 | - logger.warn("处理DeviceInfo设备信息Message时未找到设备信息"); | ||
| 1022 | - response404Ack(evt); | ||
| 1023 | - return; | ||
| 1024 | - } | ||
| 1025 | - | ||
| 1026 | - // 回复200 OK | ||
| 1027 | - responseAck(evt); | ||
| 1028 | - Element rootElement = getRootElement(evt); | ||
| 1029 | - String channelId = XmlUtil.getText(rootElement, "DeviceID"); | ||
| 1030 | - String NotifyType =XmlUtil.getText(rootElement, "NotifyType"); | ||
| 1031 | - if (NotifyType.equals("121")){ | ||
| 1032 | - logger.info("媒体播放完毕,通知关流"); | ||
| 1033 | - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, "*"); | ||
| 1034 | - if (streamInfo != null) { | ||
| 1035 | - redisCatchStorage.stopPlayback(streamInfo); | ||
| 1036 | - cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId()); | ||
| 1037 | - } | ||
| 1038 | - } | ||
| 1039 | - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | ||
| 1040 | - e.printStackTrace(); | ||
| 1041 | - } | ||
| 1042 | - } | ||
| 1043 | - | ||
| 1044 | - /** | ||
| 1045 | - * 处理AudioBroadcast语音广播Message | ||
| 1046 | - * | ||
| 1047 | - * @param evt | ||
| 1048 | - */ | ||
| 1049 | - private void processMessageBroadcast(RequestEvent evt) { | ||
| 1050 | - try { | ||
| 1051 | - | ||
| 1052 | - String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); | ||
| 1053 | - // 查询设备是否存在 | ||
| 1054 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 1055 | - if (device == null) { | ||
| 1056 | - logger.warn("处理DeviceInfo设备信息Message时未找到设备信息"); | ||
| 1057 | - response404Ack(evt); | ||
| 1058 | - return; | ||
| 1059 | - } | ||
| 1060 | - | ||
| 1061 | - Element rootElement = getRootElement(evt); | ||
| 1062 | - String channelId = XmlUtil.getText(rootElement, "DeviceID"); | ||
| 1063 | - String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId + channelId; | ||
| 1064 | - // 回复200 OK | ||
| 1065 | - responseAck(evt); | ||
| 1066 | - if (rootElement.getName().equals("Response")) { | ||
| 1067 | - // 此处是对本平台发出Broadcast指令的应答 | ||
| 1068 | - JSONObject json = new JSONObject(); | ||
| 1069 | - XmlUtil.node2Json(rootElement, json); | ||
| 1070 | - if (logger.isDebugEnabled()) { | ||
| 1071 | - logger.debug(json.toJSONString()); | ||
| 1072 | - } | ||
| 1073 | - RequestMessage msg = new RequestMessage(); | ||
| 1074 | - msg.setKey(key); | ||
| 1075 | - msg.setData(json); | ||
| 1076 | - deferredResultHolder.invokeAllResult(msg); | ||
| 1077 | - } else { | ||
| 1078 | - // 此处是上级发出的Broadcast指令 | ||
| 1079 | - } | ||
| 1080 | - } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | ||
| 1081 | - e.printStackTrace(); | ||
| 1082 | - } | ||
| 1083 | - } | ||
| 1084 | - | ||
| 1085 | - | ||
| 1086 | - /*** | ||
| 1087 | - * 回复200 OK | ||
| 1088 | - * @param evt | ||
| 1089 | - * @throws SipException | ||
| 1090 | - * @throws InvalidArgumentException | ||
| 1091 | - * @throws ParseException | ||
| 1092 | - */ | ||
| 1093 | - private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { | ||
| 1094 | - Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); | ||
| 1095 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 1096 | - serverTransaction.sendResponse(response); | ||
| 1097 | - if (serverTransaction.getDialog() != null) { | ||
| 1098 | - serverTransaction.getDialog().delete(); | ||
| 1099 | - } | ||
| 1100 | - } | ||
| 1101 | - | ||
| 1102 | - /*** | ||
| 1103 | - * 回复404 | ||
| 1104 | - * @param evt | ||
| 1105 | - * @throws SipException | ||
| 1106 | - * @throws InvalidArgumentException | ||
| 1107 | - * @throws ParseException | ||
| 1108 | - */ | ||
| 1109 | - private void response404Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { | ||
| 1110 | - Response response = getMessageFactory().createResponse(Response.NOT_FOUND, evt.getRequest()); | ||
| 1111 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 1112 | - serverTransaction.sendResponse(response); | ||
| 1113 | - if (serverTransaction.getDialog() != null) { | ||
| 1114 | - serverTransaction.getDialog().delete(); | ||
| 1115 | - } | ||
| 1116 | - } | ||
| 1117 | - | ||
| 1118 | - private Element getRootElement(RequestEvent evt) throws DocumentException { | ||
| 1119 | - | ||
| 1120 | - return getRootElement(evt, "gb2312"); | ||
| 1121 | - } | ||
| 1122 | - | ||
| 1123 | - private Element getRootElement(RequestEvent evt, String charset) throws DocumentException { | ||
| 1124 | - if (charset == null) { | ||
| 1125 | - charset = "gb2312"; | ||
| 1126 | - } | ||
| 1127 | - Request request = evt.getRequest(); | ||
| 1128 | - SAXReader reader = new SAXReader(); | ||
| 1129 | - reader.setEncoding(charset); | ||
| 1130 | - Document xml = reader.read(new ByteArrayInputStream(request.getRawContent())); | ||
| 1131 | - return xml.getRootElement(); | ||
| 1132 | - } | ||
| 1133 | - | ||
| 1134 | - public void setCmder(SIPCommander cmder) { | ||
| 1135 | - this.cmder = cmder; | ||
| 1136 | - } | ||
| 1137 | - | ||
| 1138 | - public void setStorager(IVideoManagerStorager storager) { | ||
| 1139 | - this.storager = storager; | ||
| 1140 | - } | ||
| 1141 | - | ||
| 1142 | - public void setPublisher(EventPublisher publisher) { | ||
| 1143 | - this.publisher = publisher; | ||
| 1144 | - } | ||
| 1145 | - | ||
| 1146 | - public void setRedis(RedisUtil redis) { | ||
| 1147 | - this.redis = redis; | ||
| 1148 | - } | ||
| 1149 | - | ||
| 1150 | - public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) { | ||
| 1151 | - this.deferredResultHolder = deferredResultHolder; | ||
| 1152 | - } | ||
| 1153 | - | ||
| 1154 | - public void setOffLineDetector(DeviceOffLineDetector offLineDetector) { | ||
| 1155 | - this.offLineDetector = offLineDetector; | ||
| 1156 | - } | ||
| 1157 | - | ||
| 1158 | - public IRedisCatchStorage getRedisCatchStorage() { | ||
| 1159 | - return redisCatchStorage; | ||
| 1160 | - } | ||
| 1161 | - | ||
| 1162 | - public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { | ||
| 1163 | - this.redisCatchStorage = redisCatchStorage; | ||
| 1164 | - } | ||
| 1165 | - | ||
| 1166 | - public SIPCommanderFroPlatform getCmderFroPlatform() { | ||
| 1167 | - return cmderFroPlatform; | ||
| 1168 | - } | ||
| 1169 | - | ||
| 1170 | - public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) { | ||
| 1171 | - this.cmderFroPlatform = cmderFroPlatform; | ||
| 1172 | - } | ||
| 1173 | - | ||
| 1174 | - public void setDeviceAlarmService(IDeviceAlarmService deviceAlarmService) { | ||
| 1175 | - this.deviceAlarmService = deviceAlarmService; | ||
| 1176 | - } | ||
| 1177 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/NotifyRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import java.io.ByteArrayInputStream; | ||
| 4 | -import java.text.ParseException; | ||
| 5 | -import java.util.Iterator; | ||
| 6 | - | ||
| 7 | -import javax.sip.InvalidArgumentException; | ||
| 8 | -import javax.sip.RequestEvent; | ||
| 9 | -import javax.sip.ServerTransaction; | ||
| 10 | -import javax.sip.SipException; | ||
| 11 | -import javax.sip.message.Request; | ||
| 12 | -import javax.sip.message.Response; | ||
| 13 | - | ||
| 14 | -import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 15 | -import com.genersoft.iot.vmp.conf.UserSetup; | ||
| 16 | -import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint; | ||
| 17 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 18 | -import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; | ||
| 19 | -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | ||
| 20 | -import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; | ||
| 21 | -import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; | ||
| 22 | -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | ||
| 23 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 24 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 25 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 26 | -import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; | ||
| 27 | -import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; | ||
| 28 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 29 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 30 | -import com.genersoft.iot.vmp.utils.GpsUtil; | ||
| 31 | -import com.genersoft.iot.vmp.utils.SpringBeanFactory; | ||
| 32 | -import com.genersoft.iot.vmp.utils.redis.RedisUtil; | ||
| 33 | - | ||
| 34 | -import org.dom4j.Document; | ||
| 35 | -import org.dom4j.DocumentException; | ||
| 36 | -import org.dom4j.Element; | ||
| 37 | -import org.dom4j.io.SAXReader; | ||
| 38 | -import org.slf4j.Logger; | ||
| 39 | -import org.slf4j.LoggerFactory; | ||
| 40 | -import org.springframework.util.StringUtils; | ||
| 41 | - | ||
| 42 | -/** | ||
| 43 | - * @Description: Notify请求处理器 | ||
| 44 | - * @author: lawrencehj | ||
| 45 | - * @date: 2021年1月27日 | ||
| 46 | - */ | ||
| 47 | - | ||
| 48 | -public class NotifyRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 49 | - | ||
| 50 | - private UserSetup userSetup = (UserSetup) SpringBeanFactory.getBean("userSetup"); | ||
| 51 | - | ||
| 52 | - private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class); | ||
| 53 | - | ||
| 54 | - private IVideoManagerStorager storager; | ||
| 55 | - | ||
| 56 | - private IRedisCatchStorage redisCatchStorage; | ||
| 57 | - | ||
| 58 | - private EventPublisher publisher; | ||
| 59 | - | ||
| 60 | - private DeviceOffLineDetector offLineDetector; | ||
| 61 | - | ||
| 62 | - private static final String NOTIFY_CATALOG = "Catalog"; | ||
| 63 | - private static final String NOTIFY_ALARM = "Alarm"; | ||
| 64 | - private static final String NOTIFY_MOBILE_POSITION = "MobilePosition"; | ||
| 65 | - | ||
| 66 | - @Override | ||
| 67 | - public void process(RequestEvent evt) { | ||
| 68 | - try { | ||
| 69 | - Element rootElement = getRootElement(evt); | ||
| 70 | - String cmd = XmlUtil.getText(rootElement, "CmdType"); | ||
| 71 | - | ||
| 72 | - if (NOTIFY_CATALOG.equals(cmd)) { | ||
| 73 | - logger.info("接收到Catalog通知"); | ||
| 74 | - processNotifyCatalogList(evt); | ||
| 75 | - } else if (NOTIFY_ALARM.equals(cmd)) { | ||
| 76 | - logger.info("接收到Alarm通知"); | ||
| 77 | - processNotifyAlarm(evt); | ||
| 78 | - } else if (NOTIFY_MOBILE_POSITION.equals(cmd)) { | ||
| 79 | - logger.info("接收到MobilePosition通知"); | ||
| 80 | - processNotifyMobilePosition(evt); | ||
| 81 | - } else { | ||
| 82 | - logger.info("接收到消息:" + cmd); | ||
| 83 | - response200Ok(evt); | ||
| 84 | - } | ||
| 85 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 86 | - e.printStackTrace(); | ||
| 87 | - } | ||
| 88 | - } | ||
| 89 | - | ||
| 90 | - /** | ||
| 91 | - * 处理MobilePosition移动位置Notify | ||
| 92 | - * | ||
| 93 | - * @param evt | ||
| 94 | - */ | ||
| 95 | - private void processNotifyMobilePosition(RequestEvent evt) { | ||
| 96 | - try { | ||
| 97 | - // 回复 200 OK | ||
| 98 | - Element rootElement = getRootElement(evt); | ||
| 99 | - MobilePosition mobilePosition = new MobilePosition(); | ||
| 100 | - Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 101 | - String deviceId = deviceIdElement.getTextTrim().toString(); | ||
| 102 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 103 | - if (device != null) { | ||
| 104 | - if (!StringUtils.isEmpty(device.getName())) { | ||
| 105 | - mobilePosition.setDeviceName(device.getName()); | ||
| 106 | - } | ||
| 107 | - } | ||
| 108 | - mobilePosition.setDeviceId(XmlUtil.getText(rootElement, "DeviceID")); | ||
| 109 | - mobilePosition.setTime(XmlUtil.getText(rootElement, "Time")); | ||
| 110 | - mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); | ||
| 111 | - mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); | ||
| 112 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) { | ||
| 113 | - mobilePosition.setSpeed(Double.parseDouble(XmlUtil.getText(rootElement, "Speed"))); | ||
| 114 | - } else { | ||
| 115 | - mobilePosition.setSpeed(0.0); | ||
| 116 | - } | ||
| 117 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Direction"))) { | ||
| 118 | - mobilePosition.setDirection(Double.parseDouble(XmlUtil.getText(rootElement, "Direction"))); | ||
| 119 | - } else { | ||
| 120 | - mobilePosition.setDirection(0.0); | ||
| 121 | - } | ||
| 122 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Altitude"))) { | ||
| 123 | - mobilePosition.setAltitude(Double.parseDouble(XmlUtil.getText(rootElement, "Altitude"))); | ||
| 124 | - } else { | ||
| 125 | - mobilePosition.setAltitude(0.0); | ||
| 126 | - } | ||
| 127 | - mobilePosition.setReportSource("Mobile Position"); | ||
| 128 | - BaiduPoint bp = new BaiduPoint(); | ||
| 129 | - bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude())); | ||
| 130 | - logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat()); | ||
| 131 | - mobilePosition.setGeodeticSystem("BD-09"); | ||
| 132 | - mobilePosition.setCnLng(bp.getBdLng()); | ||
| 133 | - mobilePosition.setCnLat(bp.getBdLat()); | ||
| 134 | - if (!userSetup.getSavePositionHistory()) { | ||
| 135 | - storager.clearMobilePositionsByDeviceId(deviceId); | ||
| 136 | - } | ||
| 137 | - storager.insertMobilePosition(mobilePosition); | ||
| 138 | - response200Ok(evt); | ||
| 139 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 140 | - e.printStackTrace(); | ||
| 141 | - } | ||
| 142 | - } | ||
| 143 | - | ||
| 144 | - /*** | ||
| 145 | - * 处理alarm设备报警Notify | ||
| 146 | - * | ||
| 147 | - * @param evt | ||
| 148 | - */ | ||
| 149 | - private void processNotifyAlarm(RequestEvent evt) { | ||
| 150 | - try { | ||
| 151 | - Element rootElement = getRootElement(evt); | ||
| 152 | - Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 153 | - String deviceId = deviceIdElement.getText().toString(); | ||
| 154 | - | ||
| 155 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 156 | - if (device == null) { | ||
| 157 | - return; | ||
| 158 | - } | ||
| 159 | - rootElement = getRootElement(evt, device.getCharset()); | ||
| 160 | - DeviceAlarm deviceAlarm = new DeviceAlarm(); | ||
| 161 | - deviceAlarm.setDeviceId(deviceId); | ||
| 162 | - deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority")); | ||
| 163 | - deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod")); | ||
| 164 | - deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime")); | ||
| 165 | - if (XmlUtil.getText(rootElement, "AlarmDescription") == null) { | ||
| 166 | - deviceAlarm.setAlarmDescription(""); | ||
| 167 | - } else { | ||
| 168 | - deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription")); | ||
| 169 | - } | ||
| 170 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) { | ||
| 171 | - deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); | ||
| 172 | - } else { | ||
| 173 | - deviceAlarm.setLongitude(0.00); | ||
| 174 | - } | ||
| 175 | - if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) { | ||
| 176 | - deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); | ||
| 177 | - } else { | ||
| 178 | - deviceAlarm.setLatitude(0.00); | ||
| 179 | - } | ||
| 180 | - | ||
| 181 | - if (deviceAlarm.getAlarmMethod().equals("4")) { | ||
| 182 | - MobilePosition mobilePosition = new MobilePosition(); | ||
| 183 | - mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); | ||
| 184 | - mobilePosition.setTime(deviceAlarm.getAlarmTime()); | ||
| 185 | - mobilePosition.setLongitude(deviceAlarm.getLongitude()); | ||
| 186 | - mobilePosition.setLatitude(deviceAlarm.getLatitude()); | ||
| 187 | - mobilePosition.setReportSource("GPS Alarm"); | ||
| 188 | - BaiduPoint bp = new BaiduPoint(); | ||
| 189 | - bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude())); | ||
| 190 | - logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat()); | ||
| 191 | - mobilePosition.setGeodeticSystem("BD-09"); | ||
| 192 | - mobilePosition.setCnLng(bp.getBdLng()); | ||
| 193 | - mobilePosition.setCnLat(bp.getBdLat()); | ||
| 194 | - if (!userSetup.getSavePositionHistory()) { | ||
| 195 | - storager.clearMobilePositionsByDeviceId(deviceId); | ||
| 196 | - } | ||
| 197 | - storager.insertMobilePosition(mobilePosition); | ||
| 198 | - } | ||
| 199 | - // TODO: 需要实现存储报警信息、报警分类 | ||
| 200 | - | ||
| 201 | - // 回复200 OK | ||
| 202 | - response200Ok(evt); | ||
| 203 | - if (offLineDetector.isOnline(deviceId)) { | ||
| 204 | - publisher.deviceAlarmEventPublish(deviceAlarm); | ||
| 205 | - } | ||
| 206 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 207 | - e.printStackTrace(); | ||
| 208 | - } | ||
| 209 | - } | ||
| 210 | - | ||
| 211 | - /*** | ||
| 212 | - * 处理catalog设备目录列表Notify | ||
| 213 | - * | ||
| 214 | - * @param evt | ||
| 215 | - */ | ||
| 216 | - private void processNotifyCatalogList(RequestEvent evt) { | ||
| 217 | - try { | ||
| 218 | - Element rootElement = getRootElement(evt); | ||
| 219 | - Element deviceIdElement = rootElement.element("DeviceID"); | ||
| 220 | - String deviceId = deviceIdElement.getText(); | ||
| 221 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 222 | - if (device != null ) { | ||
| 223 | - rootElement = getRootElement(evt, device.getCharset()); | ||
| 224 | - } | ||
| 225 | - Element deviceListElement = rootElement.element("DeviceList"); | ||
| 226 | - if (deviceListElement == null) { | ||
| 227 | - return; | ||
| 228 | - } | ||
| 229 | - Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); | ||
| 230 | - if (deviceListIterator != null) { | ||
| 231 | - if (device == null) { | ||
| 232 | - return; | ||
| 233 | - } | ||
| 234 | - // 遍历DeviceList | ||
| 235 | - while (deviceListIterator.hasNext()) { | ||
| 236 | - Element itemDevice = deviceListIterator.next(); | ||
| 237 | - Element channelDeviceElement = itemDevice.element("DeviceID"); | ||
| 238 | - if (channelDeviceElement == null) { | ||
| 239 | - continue; | ||
| 240 | - } | ||
| 241 | - String channelDeviceId = channelDeviceElement.getTextTrim(); | ||
| 242 | - Element channdelNameElement = itemDevice.element("Name"); | ||
| 243 | - String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : ""; | ||
| 244 | - Element statusElement = itemDevice.element("Status"); | ||
| 245 | - String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON"; | ||
| 246 | - DeviceChannel deviceChannel = new DeviceChannel(); | ||
| 247 | - deviceChannel.setName(channelName); | ||
| 248 | - deviceChannel.setChannelId(channelDeviceId); | ||
| 249 | - // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理 | ||
| 250 | - if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) { | ||
| 251 | - deviceChannel.setStatus(1); | ||
| 252 | - } | ||
| 253 | - if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { | ||
| 254 | - deviceChannel.setStatus(0); | ||
| 255 | - } | ||
| 256 | - | ||
| 257 | - deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer")); | ||
| 258 | - deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model")); | ||
| 259 | - deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner")); | ||
| 260 | - deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode")); | ||
| 261 | - deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block")); | ||
| 262 | - deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address")); | ||
| 263 | - if (XmlUtil.getText(itemDevice, "Parental") == null | ||
| 264 | - || XmlUtil.getText(itemDevice, "Parental") == "") { | ||
| 265 | - deviceChannel.setParental(0); | ||
| 266 | - } else { | ||
| 267 | - deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental"))); | ||
| 268 | - } | ||
| 269 | - deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID")); | ||
| 270 | - if (XmlUtil.getText(itemDevice, "SafetyWay") == null | ||
| 271 | - || XmlUtil.getText(itemDevice, "SafetyWay") == "") { | ||
| 272 | - deviceChannel.setSafetyWay(0); | ||
| 273 | - } else { | ||
| 274 | - deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay"))); | ||
| 275 | - } | ||
| 276 | - if (XmlUtil.getText(itemDevice, "RegisterWay") == null | ||
| 277 | - || XmlUtil.getText(itemDevice, "RegisterWay") == "") { | ||
| 278 | - deviceChannel.setRegisterWay(1); | ||
| 279 | - } else { | ||
| 280 | - deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay"))); | ||
| 281 | - } | ||
| 282 | - deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum")); | ||
| 283 | - if (XmlUtil.getText(itemDevice, "Certifiable") == null | ||
| 284 | - || XmlUtil.getText(itemDevice, "Certifiable") == "") { | ||
| 285 | - deviceChannel.setCertifiable(0); | ||
| 286 | - } else { | ||
| 287 | - deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable"))); | ||
| 288 | - } | ||
| 289 | - if (XmlUtil.getText(itemDevice, "ErrCode") == null | ||
| 290 | - || XmlUtil.getText(itemDevice, "ErrCode") == "") { | ||
| 291 | - deviceChannel.setErrCode(0); | ||
| 292 | - } else { | ||
| 293 | - deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode"))); | ||
| 294 | - } | ||
| 295 | - deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime")); | ||
| 296 | - deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy")); | ||
| 297 | - deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress")); | ||
| 298 | - if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") { | ||
| 299 | - deviceChannel.setPort(0); | ||
| 300 | - } else { | ||
| 301 | - deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port"))); | ||
| 302 | - } | ||
| 303 | - deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password")); | ||
| 304 | - if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) { | ||
| 305 | - deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude"))); | ||
| 306 | - } else { | ||
| 307 | - deviceChannel.setLongitude(0.00); | ||
| 308 | - } | ||
| 309 | - if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) { | ||
| 310 | - deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude"))); | ||
| 311 | - } else { | ||
| 312 | - deviceChannel.setLatitude(0.00); | ||
| 313 | - } | ||
| 314 | - if (XmlUtil.getText(itemDevice, "PTZType") == null | ||
| 315 | - || XmlUtil.getText(itemDevice, "PTZType") == "") { | ||
| 316 | - deviceChannel.setPTZType(0); | ||
| 317 | - } else { | ||
| 318 | - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); | ||
| 319 | - } | ||
| 320 | - deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC | ||
| 321 | - storager.updateChannel(device.getDeviceId(), deviceChannel); | ||
| 322 | - } | ||
| 323 | - | ||
| 324 | - // RequestMessage msg = new RequestMessage(); | ||
| 325 | - // msg.setDeviceId(deviceId); | ||
| 326 | - // msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG); | ||
| 327 | - // msg.setData(device); | ||
| 328 | - // deferredResultHolder.invokeResult(msg); | ||
| 329 | - // 回复200 OK | ||
| 330 | - response200Ok(evt); | ||
| 331 | - if (offLineDetector.isOnline(deviceId)) { | ||
| 332 | - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); | ||
| 333 | - } | ||
| 334 | - } | ||
| 335 | - } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { | ||
| 336 | - e.printStackTrace(); | ||
| 337 | - } | ||
| 338 | - } | ||
| 339 | - | ||
| 340 | - /*** | ||
| 341 | - * 回复200 OK | ||
| 342 | - * | ||
| 343 | - * @param evt | ||
| 344 | - * @throws SipException | ||
| 345 | - * @throws InvalidArgumentException | ||
| 346 | - * @throws ParseException | ||
| 347 | - */ | ||
| 348 | - private void response200Ok(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { | ||
| 349 | - Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); | ||
| 350 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 351 | - serverTransaction.sendResponse(response); | ||
| 352 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | ||
| 353 | - } | ||
| 354 | - private Element getRootElement(RequestEvent evt) throws DocumentException { | ||
| 355 | - return getRootElement(evt, "gb2312"); | ||
| 356 | - } | ||
| 357 | - private Element getRootElement(RequestEvent evt, String charset) throws DocumentException { | ||
| 358 | - if (charset == null) charset = "gb2312"; | ||
| 359 | - Request request = evt.getRequest(); | ||
| 360 | - SAXReader reader = new SAXReader(); | ||
| 361 | - reader.setEncoding(charset); | ||
| 362 | - Document xml = reader.read(new ByteArrayInputStream(request.getRawContent())); | ||
| 363 | - return xml.getRootElement(); | ||
| 364 | - } | ||
| 365 | - | ||
| 366 | - public void setCmder(SIPCommander cmder) { | ||
| 367 | - } | ||
| 368 | - | ||
| 369 | - public void setStorager(IVideoManagerStorager storager) { | ||
| 370 | - this.storager = storager; | ||
| 371 | - } | ||
| 372 | - | ||
| 373 | - public void setPublisher(EventPublisher publisher) { | ||
| 374 | - this.publisher = publisher; | ||
| 375 | - } | ||
| 376 | - | ||
| 377 | - public void setRedis(RedisUtil redis) { | ||
| 378 | - } | ||
| 379 | - | ||
| 380 | - public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) { | ||
| 381 | - } | ||
| 382 | - | ||
| 383 | - public void setOffLineDetector(DeviceOffLineDetector offLineDetector) { | ||
| 384 | - this.offLineDetector = offLineDetector; | ||
| 385 | - } | ||
| 386 | - | ||
| 387 | - public IRedisCatchStorage getRedisCatchStorage() { | ||
| 388 | - return redisCatchStorage; | ||
| 389 | - } | ||
| 390 | - | ||
| 391 | - public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { | ||
| 392 | - this.redisCatchStorage = redisCatchStorage; | ||
| 393 | - } | ||
| 394 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import javax.sip.RequestEvent; | ||
| 4 | - | ||
| 5 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 6 | -import org.slf4j.Logger; | ||
| 7 | -import org.slf4j.LoggerFactory; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * @Description:暂不支持的消息请求处理器 | ||
| 11 | - * @author: swwheihei | ||
| 12 | - * @date: 2020年5月3日 下午5:32:59 | ||
| 13 | - */ | ||
| 14 | -public class OtherRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 15 | - | ||
| 16 | - private Logger logger = LoggerFactory.getLogger(OtherRequestProcessor.class); | ||
| 17 | - | ||
| 18 | - /** | ||
| 19 | - * <p>Title: process</p> | ||
| 20 | - * <p>Description: </p> | ||
| 21 | - * @param evt | ||
| 22 | - * @param layer | ||
| 23 | - * @param transaction | ||
| 24 | - * @param config | ||
| 25 | - */ | ||
| 26 | - @Override | ||
| 27 | - public void process(RequestEvent evt) { | ||
| 28 | - logger.info("Unsupported the method: " + evt.getRequest().getMethod()); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import java.security.NoSuchAlgorithmException; | ||
| 4 | -import java.text.ParseException; | ||
| 5 | -import java.util.Calendar; | ||
| 6 | -import java.util.Locale; | ||
| 7 | - | ||
| 8 | -import javax.sip.InvalidArgumentException; | ||
| 9 | -import javax.sip.RequestEvent; | ||
| 10 | -import javax.sip.ServerTransaction; | ||
| 11 | -import javax.sip.SipException; | ||
| 12 | -import javax.sip.header.AuthorizationHeader; | ||
| 13 | -import javax.sip.header.ContactHeader; | ||
| 14 | -import javax.sip.header.ExpiresHeader; | ||
| 15 | -import javax.sip.header.FromHeader; | ||
| 16 | -import javax.sip.header.ViaHeader; | ||
| 17 | -import javax.sip.message.Request; | ||
| 18 | -import javax.sip.message.Response; | ||
| 19 | - | ||
| 20 | -import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; | ||
| 21 | -import gov.nist.javax.sip.RequestEventExt; | ||
| 22 | -import gov.nist.javax.sip.header.SIPDateHeader; | ||
| 23 | -import org.slf4j.Logger; | ||
| 24 | -import org.slf4j.LoggerFactory; | ||
| 25 | -import org.springframework.util.StringUtils; | ||
| 26 | - | ||
| 27 | -import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 28 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 29 | -import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; | ||
| 30 | -import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler; | ||
| 31 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 32 | -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | ||
| 33 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 34 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 35 | - | ||
| 36 | -import gov.nist.javax.sip.address.AddressImpl; | ||
| 37 | -import gov.nist.javax.sip.address.SipUri; | ||
| 38 | -import gov.nist.javax.sip.header.Expires; | ||
| 39 | - | ||
| 40 | -/** | ||
| 41 | - * @Description:收到注册请求 处理 | ||
| 42 | - * @author: swwheihei | ||
| 43 | - * @date: 2020年5月3日 下午4:47:25 | ||
| 44 | - */ | ||
| 45 | -public class RegisterRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 46 | - | ||
| 47 | - private Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class); | ||
| 48 | - | ||
| 49 | - private SipConfig sipConfig; | ||
| 50 | - | ||
| 51 | - private RegisterLogicHandler handler; | ||
| 52 | - | ||
| 53 | - private IVideoManagerStorager storager; | ||
| 54 | - | ||
| 55 | - private EventPublisher publisher; | ||
| 56 | - | ||
| 57 | - /** | ||
| 58 | - * 收到注册请求 处理 | ||
| 59 | - * @param evt | ||
| 60 | - */ | ||
| 61 | - @Override | ||
| 62 | - public void process(RequestEvent evt) { | ||
| 63 | - try { | ||
| 64 | - RequestEventExt evtExt = (RequestEventExt)evt; | ||
| 65 | - String requestAddress = evtExt.getRemoteIpAddress() + ":" + evtExt.getRemotePort(); | ||
| 66 | - logger.info("[{}] 收到注册请求,开始处理", requestAddress); | ||
| 67 | - Request request = evt.getRequest(); | ||
| 68 | - | ||
| 69 | - Response response = null; | ||
| 70 | - boolean passwordCorrect = false; | ||
| 71 | - // 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功 | ||
| 72 | - int registerFlag = 0; | ||
| 73 | - FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); | ||
| 74 | - AddressImpl address = (AddressImpl) fromHeader.getAddress(); | ||
| 75 | - SipUri uri = (SipUri) address.getURI(); | ||
| 76 | - String deviceId = uri.getUser(); | ||
| 77 | - Device device = storager.queryVideoDevice(deviceId); | ||
| 78 | - AuthorizationHeader authorhead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | ||
| 79 | - // 校验密码是否正确 | ||
| 80 | - if (authorhead != null) { | ||
| 81 | - passwordCorrect = new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, | ||
| 82 | - sipConfig.getPassword()); | ||
| 83 | - } | ||
| 84 | - if (StringUtils.isEmpty(sipConfig.getPassword())){ | ||
| 85 | - passwordCorrect = true; | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | - // 未携带授权头或者密码错误 回复401 | ||
| 89 | - if (authorhead == null ) { | ||
| 90 | - | ||
| 91 | - logger.info("[{}] 未携带授权头 回复401", requestAddress); | ||
| 92 | - response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request); | ||
| 93 | - new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain()); | ||
| 94 | - }else { | ||
| 95 | - if (!passwordCorrect){ | ||
| 96 | - // 注册失败 | ||
| 97 | - response = getMessageFactory().createResponse(Response.FORBIDDEN, request); | ||
| 98 | - response.setReasonPhrase("wrong password"); | ||
| 99 | - logger.info("[{}] 密码/SIP服务器ID错误, 回复403", requestAddress); | ||
| 100 | - }else { | ||
| 101 | - // 携带授权头并且密码正确 | ||
| 102 | - response = getMessageFactory().createResponse(Response.OK, request); | ||
| 103 | - // 添加date头 | ||
| 104 | - SIPDateHeader dateHeader = new SIPDateHeader(); | ||
| 105 | - // 使用自己修改的 | ||
| 106 | - WvpSipDate wvpSipDate = new WvpSipDate(Calendar.getInstance(Locale.ENGLISH).getTimeInMillis()); | ||
| 107 | - dateHeader.setDate(wvpSipDate); | ||
| 108 | - response.addHeader(dateHeader); | ||
| 109 | - | ||
| 110 | - ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME); | ||
| 111 | - if (expiresHeader == null) { | ||
| 112 | - response = getMessageFactory().createResponse(Response.BAD_REQUEST, request); | ||
| 113 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 114 | - serverTransaction.sendResponse(response); | ||
| 115 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | ||
| 116 | - return; | ||
| 117 | - } | ||
| 118 | - // 添加Contact头 | ||
| 119 | - response.addHeader(request.getHeader(ContactHeader.NAME)); | ||
| 120 | - // 添加Expires头 | ||
| 121 | - response.addHeader(request.getExpires()); | ||
| 122 | - | ||
| 123 | - // 获取到通信地址等信息 | ||
| 124 | - ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | ||
| 125 | - String received = viaHeader.getReceived(); | ||
| 126 | - int rPort = viaHeader.getRPort(); | ||
| 127 | - // 解析本地地址替代 | ||
| 128 | - if (StringUtils.isEmpty(received) || rPort == -1) { | ||
| 129 | - received = viaHeader.getHost(); | ||
| 130 | - rPort = viaHeader.getPort(); | ||
| 131 | - } | ||
| 132 | - // | ||
| 133 | - | ||
| 134 | - if (device == null) { | ||
| 135 | - device = new Device(); | ||
| 136 | - device.setStreamMode("UDP"); | ||
| 137 | - device.setCharset("gb2312"); | ||
| 138 | - device.setDeviceId(deviceId); | ||
| 139 | - device.setFirsRegister(true); | ||
| 140 | - } | ||
| 141 | - device.setIp(received); | ||
| 142 | - device.setPort(rPort); | ||
| 143 | - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); | ||
| 144 | - // 注销成功 | ||
| 145 | - if (expiresHeader.getExpires() == 0) { | ||
| 146 | - registerFlag = 2; | ||
| 147 | - } | ||
| 148 | - // 注册成功 | ||
| 149 | - else { | ||
| 150 | - device.setExpires(expiresHeader.getExpires()); | ||
| 151 | - registerFlag = 1; | ||
| 152 | - // 判断TCP还是UDP | ||
| 153 | - boolean isTcp = false; | ||
| 154 | - ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | ||
| 155 | - String transport = reqViaHeader.getTransport(); | ||
| 156 | - if (transport.equals("TCP")) { | ||
| 157 | - isTcp = true; | ||
| 158 | - } | ||
| 159 | - device.setTransport(isTcp ? "TCP" : "UDP"); | ||
| 160 | - } | ||
| 161 | - } | ||
| 162 | - } | ||
| 163 | - | ||
| 164 | - ServerTransaction serverTransaction = getServerTransaction(evt); | ||
| 165 | - serverTransaction.sendResponse(response); | ||
| 166 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | ||
| 167 | - // 注册成功 | ||
| 168 | - // 保存到redis | ||
| 169 | - // 下发catelog查询目录 | ||
| 170 | - if (registerFlag == 1 ) { | ||
| 171 | - logger.info("[{}] 注册成功! deviceId:" + device.getDeviceId(), requestAddress); | ||
| 172 | - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER); | ||
| 173 | - // 重新注册更新设备和通道,以免设备替换或更新后信息无法更新 | ||
| 174 | - handler.onRegister(device); | ||
| 175 | - } else if (registerFlag == 2) { | ||
| 176 | - logger.info("[{}] 注销成功! deviceId:" + device.getDeviceId(), requestAddress); | ||
| 177 | - publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER); | ||
| 178 | - } | ||
| 179 | - } catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) { | ||
| 180 | - e.printStackTrace(); | ||
| 181 | - } | ||
| 182 | - | ||
| 183 | - } | ||
| 184 | - | ||
| 185 | - public void setSipConfig(SipConfig sipConfig) { | ||
| 186 | - this.sipConfig = sipConfig; | ||
| 187 | - } | ||
| 188 | - | ||
| 189 | - public void setHandler(RegisterLogicHandler handler) { | ||
| 190 | - this.handler = handler; | ||
| 191 | - } | ||
| 192 | - | ||
| 193 | - public void setVideoManagerStorager(IVideoManagerStorager storager) { | ||
| 194 | - this.storager = storager; | ||
| 195 | - } | ||
| 196 | - | ||
| 197 | - public void setPublisher(EventPublisher publisher) { | ||
| 198 | - this.publisher = publisher; | ||
| 199 | - } | ||
| 200 | - | ||
| 201 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.request.impl; | ||
| 2 | - | ||
| 3 | -import java.text.ParseException; | ||
| 4 | - | ||
| 5 | -import javax.sip.InvalidArgumentException; | ||
| 6 | -import javax.sip.RequestEvent; | ||
| 7 | -import javax.sip.ServerTransaction; | ||
| 8 | -import javax.sip.SipException; | ||
| 9 | -import javax.sip.header.ExpiresHeader; | ||
| 10 | -import javax.sip.message.Request; | ||
| 11 | -import javax.sip.message.Response; | ||
| 12 | - | ||
| 13 | -import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | ||
| 14 | -import org.slf4j.Logger; | ||
| 15 | -import org.slf4j.LoggerFactory; | ||
| 16 | - | ||
| 17 | -/** | ||
| 18 | - * @Description:SUBSCRIBE请求处理器 | ||
| 19 | - * @author: swwheihei | ||
| 20 | - * @date: 2020年5月3日 下午5:31:20 | ||
| 21 | - */ | ||
| 22 | -public class SubscribeRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 23 | - | ||
| 24 | - private Logger logger = LoggerFactory.getLogger(SubscribeRequestProcessor.class); | ||
| 25 | - | ||
| 26 | - /** | ||
| 27 | - * 处理SUBSCRIBE请求 | ||
| 28 | - * | ||
| 29 | - * @param evt | ||
| 30 | - */ | ||
| 31 | - @Override | ||
| 32 | - public void process(RequestEvent evt) { | ||
| 33 | - Request request = evt.getRequest(); | ||
| 34 | - | ||
| 35 | - try { | ||
| 36 | - Response response = null; | ||
| 37 | - response = getMessageFactory().createResponse(200, request); | ||
| 38 | - if (response != null) { | ||
| 39 | - ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30); | ||
| 40 | - response.setExpires(expireHeader); | ||
| 41 | - } | ||
| 42 | - logger.info("response : " + response.toString()); | ||
| 43 | - ServerTransaction transaction = getServerTransaction(evt); | ||
| 44 | - if (transaction != null) { | ||
| 45 | - transaction.sendResponse(response); | ||
| 46 | - transaction.getDialog().delete(); | ||
| 47 | - transaction.terminate(); | ||
| 48 | - } else { | ||
| 49 | - logger.info("processRequest serverTransactionId is null."); | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - } catch (ParseException e) { | ||
| 53 | - e.printStackTrace(); | ||
| 54 | - } catch (SipException e) { | ||
| 55 | - e.printStackTrace(); | ||
| 56 | - } catch (InvalidArgumentException e) { | ||
| 57 | - e.printStackTrace(); | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | - } | ||
| 61 | - | ||
| 62 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.response; | ||
| 2 | - | ||
| 3 | -import java.text.ParseException; | ||
| 4 | - | ||
| 5 | -import javax.sip.ResponseEvent; | ||
| 6 | - | ||
| 7 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 8 | -import com.genersoft.iot.vmp.gb28181.SipLayer; | ||
| 9 | - | ||
| 10 | -/** | ||
| 11 | - * @Description:处理接收IPCamera发来的SIP协议响应消息 | ||
| 12 | - * @author: swwheihei | ||
| 13 | - * @date: 2020年5月3日 下午4:42:22 | ||
| 14 | - */ | ||
| 15 | -public interface ISIPResponseProcessor { | ||
| 16 | - | ||
| 17 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException; | ||
| 18 | - | ||
| 19 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.response.impl; | ||
| 2 | - | ||
| 3 | -import javax.sip.ResponseEvent; | ||
| 4 | - | ||
| 5 | -import org.springframework.stereotype.Component; | ||
| 6 | - | ||
| 7 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 8 | -import com.genersoft.iot.vmp.gb28181.SipLayer; | ||
| 9 | -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * @Description: BYE请求响应器 | ||
| 13 | - * @author: swwheihei | ||
| 14 | - * @date: 2020年5月3日 下午5:32:05 | ||
| 15 | - */ | ||
| 16 | -@Component | ||
| 17 | -public class ByeResponseProcessor implements ISIPResponseProcessor { | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * 处理BYE响应 | ||
| 21 | - * | ||
| 22 | - * @param evt | ||
| 23 | - * @param layer | ||
| 24 | - * @param config | ||
| 25 | - */ | ||
| 26 | - @Override | ||
| 27 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) { | ||
| 28 | - // TODO Auto-generated method stub | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.response.impl; | ||
| 2 | - | ||
| 3 | -import javax.sip.ResponseEvent; | ||
| 4 | - | ||
| 5 | -import org.springframework.stereotype.Component; | ||
| 6 | - | ||
| 7 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 8 | -import com.genersoft.iot.vmp.gb28181.SipLayer; | ||
| 9 | -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * @Description:CANCEL响应处理器 | ||
| 13 | - * @author: swwheihei | ||
| 14 | - * @date: 2020年5月3日 下午5:32:23 | ||
| 15 | - */ | ||
| 16 | -@Component | ||
| 17 | -public class CancelResponseProcessor implements ISIPResponseProcessor { | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * 处理CANCEL响应 | ||
| 21 | - * | ||
| 22 | - * @param evt | ||
| 23 | - * @param layer | ||
| 24 | - * @param transaction | ||
| 25 | - * @param config | ||
| 26 | - */ | ||
| 27 | - @Override | ||
| 28 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) { | ||
| 29 | - // TODO Auto-generated method stub | ||
| 30 | - | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.response.impl; | ||
| 2 | - | ||
| 3 | -import java.text.ParseException; | ||
| 4 | - | ||
| 5 | -import javax.sip.*; | ||
| 6 | -import javax.sip.address.SipURI; | ||
| 7 | -import javax.sip.header.CSeqHeader; | ||
| 8 | -import javax.sip.message.Request; | ||
| 9 | -import javax.sip.message.Response; | ||
| 10 | - | ||
| 11 | -import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | ||
| 12 | -import gov.nist.javax.sip.ResponseEventExt; | ||
| 13 | -import gov.nist.javax.sip.stack.SIPDialog; | ||
| 14 | -import org.slf4j.Logger; | ||
| 15 | -import org.slf4j.LoggerFactory; | ||
| 16 | -import org.springframework.beans.factory.annotation.Autowired; | ||
| 17 | -import org.springframework.stereotype.Component; | ||
| 18 | - | ||
| 19 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 20 | -import com.genersoft.iot.vmp.gb28181.SipLayer; | ||
| 21 | -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | ||
| 22 | - | ||
| 23 | - | ||
| 24 | -/** | ||
| 25 | - * @Description:处理INVITE响应 | ||
| 26 | - * @author: swwheihei | ||
| 27 | - * @date: 2020年5月3日 下午4:43:52 | ||
| 28 | - */ | ||
| 29 | -@Component | ||
| 30 | -public class InviteResponseProcessor implements ISIPResponseProcessor { | ||
| 31 | - | ||
| 32 | - private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class); | ||
| 33 | - | ||
| 34 | - @Autowired | ||
| 35 | - private VideoStreamSessionManager streamSession; | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * 处理invite响应 | ||
| 39 | - * | ||
| 40 | - * @param evt 响应消息 | ||
| 41 | - * @throws ParseException | ||
| 42 | - */ | ||
| 43 | - @Override | ||
| 44 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException { | ||
| 45 | - try { | ||
| 46 | - Response response = evt.getResponse(); | ||
| 47 | - int statusCode = response.getStatusCode(); | ||
| 48 | - // trying不会回复 | ||
| 49 | - if (statusCode == Response.TRYING) { | ||
| 50 | - } | ||
| 51 | - // 成功响应 | ||
| 52 | - // 下发ack | ||
| 53 | - if (statusCode == Response.OK) { | ||
| 54 | - ResponseEventExt event = (ResponseEventExt)evt; | ||
| 55 | - SIPDialog dialog = (SIPDialog)evt.getDialog(); | ||
| 56 | - CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | ||
| 57 | - Request reqAck = dialog.createAck(cseq.getSeqNumber()); | ||
| 58 | - SipURI requestURI = (SipURI) reqAck.getRequestURI(); | ||
| 59 | - requestURI.setHost(event.getRemoteIpAddress()); | ||
| 60 | - requestURI.setPort(event.getRemotePort()); | ||
| 61 | - reqAck.setRequestURI(requestURI); | ||
| 62 | - logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack"); | ||
| 63 | - SipURI sipURI = (SipURI)dialog.getRemoteParty().getURI(); | ||
| 64 | - String deviceId = requestURI.getUser(); | ||
| 65 | - String channelId = sipURI.getUser(); | ||
| 66 | - | ||
| 67 | - dialog.sendAck(reqAck); | ||
| 68 | - | ||
| 69 | - } | ||
| 70 | - } catch (InvalidArgumentException | SipException e) { | ||
| 71 | - e.printStackTrace(); | ||
| 72 | - } | ||
| 73 | - } | ||
| 74 | - | ||
| 75 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.response.impl; | ||
| 2 | - | ||
| 3 | -import javax.sip.ResponseEvent; | ||
| 4 | - | ||
| 5 | -import org.springframework.stereotype.Component; | ||
| 6 | - | ||
| 7 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 8 | -import com.genersoft.iot.vmp.gb28181.SipLayer; | ||
| 9 | -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * @Description:暂不支持的消息响应处理器 | ||
| 13 | - * @author: swwheihei | ||
| 14 | - * @date: 2020年5月3日 下午5:32:59 | ||
| 15 | - */ | ||
| 16 | -@Component | ||
| 17 | -public class OtherResponseProcessor implements ISIPResponseProcessor { | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * <p>Title: process</p> | ||
| 21 | - * <p>Description: </p> | ||
| 22 | - * @param evt | ||
| 23 | - * @param layer | ||
| 24 | - * @param config | ||
| 25 | - */ | ||
| 26 | - @Override | ||
| 27 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) { | ||
| 28 | - // TODO Auto-generated method stub | ||
| 29 | - | ||
| 30 | - } | ||
| 31 | - | ||
| 32 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.gb28181.transmit.response.impl; | ||
| 2 | - | ||
| 3 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 4 | -import com.genersoft.iot.vmp.gb28181.SipLayer; | ||
| 5 | -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | ||
| 6 | -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | ||
| 7 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | ||
| 8 | -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | ||
| 9 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 10 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 11 | -import org.slf4j.Logger; | ||
| 12 | -import org.slf4j.LoggerFactory; | ||
| 13 | -import org.springframework.beans.factory.annotation.Autowired; | ||
| 14 | -import org.springframework.stereotype.Component; | ||
| 15 | - | ||
| 16 | -import javax.sip.ResponseEvent; | ||
| 17 | -import javax.sip.header.CallIdHeader; | ||
| 18 | -import javax.sip.header.WWWAuthenticateHeader; | ||
| 19 | -import javax.sip.message.Response; | ||
| 20 | - | ||
| 21 | -/** | ||
| 22 | - * @Description:Register响应处理器 | ||
| 23 | - * @author: swwheihei | ||
| 24 | - * @date: 2020年5月3日 下午5:32:23 | ||
| 25 | - */ | ||
| 26 | -@Component | ||
| 27 | -public class RegisterResponseProcessor implements ISIPResponseProcessor { | ||
| 28 | - | ||
| 29 | - private Logger logger = LoggerFactory.getLogger(RegisterResponseProcessor.class); | ||
| 30 | - | ||
| 31 | - @Autowired | ||
| 32 | - private ISIPCommanderForPlatform sipCommanderForPlatform; | ||
| 33 | - | ||
| 34 | - @Autowired | ||
| 35 | - private IVideoManagerStorager storager; | ||
| 36 | - | ||
| 37 | - @Autowired | ||
| 38 | - private IRedisCatchStorage redisCatchStorage; | ||
| 39 | - | ||
| 40 | - public RegisterResponseProcessor() { | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - /** | ||
| 44 | - * 处理Register响应 | ||
| 45 | - * | ||
| 46 | - * @param evt | ||
| 47 | - * @param layer | ||
| 48 | - * @param config | ||
| 49 | - */ | ||
| 50 | - @Override | ||
| 51 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) { | ||
| 52 | - Response response = evt.getResponse(); | ||
| 53 | - CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME); | ||
| 54 | - String callId = callIdHeader.getCallId(); | ||
| 55 | - | ||
| 56 | - String platformGBId = redisCatchStorage.queryPlatformRegisterInfo(callId); | ||
| 57 | - if (platformGBId == null) { | ||
| 58 | - logger.info(String.format("未找到callId: %s 的注册/注销平台id", callId )); | ||
| 59 | - return; | ||
| 60 | - } | ||
| 61 | - | ||
| 62 | - ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(platformGBId); | ||
| 63 | - if (parentPlatformCatch == null) { | ||
| 64 | - logger.warn(String.format("收到 %s 的注册/注销%S请求, 但是平台缓存信息未查询到!!!", platformGBId, response.getStatusCode())); | ||
| 65 | - return; | ||
| 66 | - } | ||
| 67 | - String action = parentPlatformCatch.getParentPlatform().getExpires().equals("0") ? "注销" : "注册"; | ||
| 68 | - logger.info(String.format("收到 %s %s的%S响应", platformGBId, action, response.getStatusCode() )); | ||
| 69 | - ParentPlatform parentPlatform = parentPlatformCatch.getParentPlatform(); | ||
| 70 | - if (parentPlatform == null) { | ||
| 71 | - logger.warn(String.format("收到 %s %s的%S请求, 但是平台信息未查询到!!!", platformGBId, action, response.getStatusCode())); | ||
| 72 | - return; | ||
| 73 | - } | ||
| 74 | - | ||
| 75 | - if (response.getStatusCode() == 401) { | ||
| 76 | - WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); | ||
| 77 | - sipCommanderForPlatform.register(parentPlatform, callId, www, null, null); | ||
| 78 | - }else if (response.getStatusCode() == 200){ | ||
| 79 | - // 注册/注销成功 | ||
| 80 | - logger.info(String.format("%s %s成功", platformGBId, action)); | ||
| 81 | - redisCatchStorage.delPlatformRegisterInfo(callId); | ||
| 82 | - parentPlatform.setStatus("注册".equals(action)); | ||
| 83 | - // 取回Expires设置,避免注销过程中被置为0 | ||
| 84 | - ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId); | ||
| 85 | - String expires = parentPlatformTmp.getExpires(); | ||
| 86 | - parentPlatform.setExpires(expires); | ||
| 87 | - parentPlatform.setId(parentPlatformTmp.getId()); | ||
| 88 | - storager.updateParentPlatformStatus(platformGBId, "注册".equals(action)); | ||
| 89 | - | ||
| 90 | - redisCatchStorage.updatePlatformRegister(parentPlatform); | ||
| 91 | - | ||
| 92 | - redisCatchStorage.updatePlatformKeepalive(parentPlatform); | ||
| 93 | - | ||
| 94 | - parentPlatformCatch.setParentPlatform(parentPlatform); | ||
| 95 | - | ||
| 96 | - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | ||
| 97 | - } | ||
| 98 | - } | ||
| 99 | - | ||
| 100 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java
| @@ -6,7 +6,7 @@ import java.util.Date; | @@ -6,7 +6,7 @@ import java.util.Date; | ||
| 6 | import java.util.Locale; | 6 | import java.util.Locale; |
| 7 | 7 | ||
| 8 | /** | 8 | /** |
| 9 | - * @Description:时间工具类,主要处理ISO 8601格式转换 | 9 | + * @description:时间工具类,主要处理ISO 8601格式转换 |
| 10 | * @author: swwheihei | 10 | * @author: swwheihei |
| 11 | * @date: 2020年5月8日 下午3:24:42 | 11 | * @date: 2020年5月8日 下午3:24:42 |
| 12 | */ | 12 | */ |
src/main/java/com/genersoft/iot/vmp/utils/SipUtils.java renamed to src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
| 1 | -package com.genersoft.iot.vmp.utils; | 1 | +package com.genersoft.iot.vmp.gb28181.utils; |
| 2 | 2 | ||
| 3 | import gov.nist.javax.sip.address.AddressImpl; | 3 | import gov.nist.javax.sip.address.AddressImpl; |
| 4 | import gov.nist.javax.sip.address.SipUri; | 4 | import gov.nist.javax.sip.address.SipUri; |
| @@ -9,15 +9,20 @@ import javax.sip.message.Request; | @@ -9,15 +9,20 @@ import javax.sip.message.Request; | ||
| 9 | /** | 9 | /** |
| 10 | * @author panlinlin | 10 | * @author panlinlin |
| 11 | * @version 1.0.0 | 11 | * @version 1.0.0 |
| 12 | - * @Description JAIN SIP的工具类 | 12 | + * @description JAIN SIP的工具类 |
| 13 | * @createTime 2021年09月27日 15:12:00 | 13 | * @createTime 2021年09月27日 15:12:00 |
| 14 | */ | 14 | */ |
| 15 | public class SipUtils { | 15 | public class SipUtils { |
| 16 | 16 | ||
| 17 | public static String getUserIdFromFromHeader(Request request) { | 17 | public static String getUserIdFromFromHeader(Request request) { |
| 18 | FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); | 18 | FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); |
| 19 | + return getUserIdFromFromHeader(fromHeader); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + public static String getUserIdFromFromHeader(FromHeader fromHeader) { | ||
| 19 | AddressImpl address = (AddressImpl)fromHeader.getAddress(); | 23 | AddressImpl address = (AddressImpl)fromHeader.getAddress(); |
| 20 | SipUri uri = (SipUri) address.getURI(); | 24 | SipUri uri = (SipUri) address.getURI(); |
| 21 | return uri.getUser(); | 25 | return uri.getUser(); |
| 22 | } | 26 | } |
| 27 | + | ||
| 23 | } | 28 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
| 1 | package com.genersoft.iot.vmp.gb28181.utils; | 1 | package com.genersoft.iot.vmp.gb28181.utils; |
| 2 | 2 | ||
| 3 | -import java.io.StringReader; | ||
| 4 | -import java.util.ArrayList; | ||
| 5 | -import java.util.HashMap; | ||
| 6 | -import java.util.Iterator; | ||
| 7 | -import java.util.List; | ||
| 8 | -import java.util.Map; | ||
| 9 | - | ||
| 10 | import com.alibaba.fastjson.JSONArray; | 3 | import com.alibaba.fastjson.JSONArray; |
| 11 | import com.alibaba.fastjson.JSONObject; | 4 | import com.alibaba.fastjson.JSONObject; |
| 12 | - | ||
| 13 | import org.dom4j.Attribute; | 5 | import org.dom4j.Attribute; |
| 14 | import org.dom4j.Document; | 6 | import org.dom4j.Document; |
| 15 | import org.dom4j.DocumentException; | 7 | import org.dom4j.DocumentException; |
| @@ -19,6 +11,12 @@ import org.slf4j.Logger; | @@ -19,6 +11,12 @@ import org.slf4j.Logger; | ||
| 19 | import org.slf4j.LoggerFactory; | 11 | import org.slf4j.LoggerFactory; |
| 20 | import org.springframework.util.StringUtils; | 12 | import org.springframework.util.StringUtils; |
| 21 | 13 | ||
| 14 | +import javax.sip.RequestEvent; | ||
| 15 | +import javax.sip.message.Request; | ||
| 16 | +import java.io.ByteArrayInputStream; | ||
| 17 | +import java.io.StringReader; | ||
| 18 | +import java.util.*; | ||
| 19 | + | ||
| 22 | /** | 20 | /** |
| 23 | * 基于dom4j的工具包 | 21 | * 基于dom4j的工具包 |
| 24 | * | 22 | * |
| @@ -161,4 +159,23 @@ public class XmlUtil { | @@ -161,4 +159,23 @@ public class XmlUtil { | ||
| 161 | } | 159 | } |
| 162 | } | 160 | } |
| 163 | } | 161 | } |
| 162 | + public static Element getRootElement(RequestEvent evt) throws DocumentException { | ||
| 163 | + | ||
| 164 | + return getRootElement(evt, "gb2312"); | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + public static Element getRootElement(RequestEvent evt, String charset) throws DocumentException { | ||
| 168 | + Request request = evt.getRequest(); | ||
| 169 | + return getRootElement(request.getRawContent(), charset); | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + public static Element getRootElement(byte[] content, String charset) throws DocumentException { | ||
| 173 | + if (charset == null) { | ||
| 174 | + charset = "gb2312"; | ||
| 175 | + } | ||
| 176 | + SAXReader reader = new SAXReader(); | ||
| 177 | + reader.setEncoding(charset); | ||
| 178 | + Document xml = reader.read(new ByteArrayInputStream(content)); | ||
| 179 | + return xml.getRootElement(); | ||
| 180 | + } | ||
| 164 | } | 181 | } |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| @@ -31,7 +31,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | @@ -31,7 +31,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 31 | import javax.servlet.http.HttpServletRequest; | 31 | import javax.servlet.http.HttpServletRequest; |
| 32 | 32 | ||
| 33 | /** | 33 | /** |
| 34 | - * @Description:针对 ZLMediaServer的hook事件监听 | 34 | + * @description:针对 ZLMediaServer的hook事件监听 |
| 35 | * @author: swwheihei | 35 | * @author: swwheihei |
| 36 | * @date: 2020年5月8日 上午10:46:48 | 36 | * @date: 2020年5月8日 上午10:46:48 |
| 37 | */ | 37 | */ |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
| @@ -8,7 +8,7 @@ import java.util.*; | @@ -8,7 +8,7 @@ import java.util.*; | ||
| 8 | import java.util.concurrent.ConcurrentHashMap; | 8 | import java.util.concurrent.ConcurrentHashMap; |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | - * @Description:针对 ZLMediaServer的hook事件订阅 | 11 | + * @description:针对 ZLMediaServer的hook事件订阅 |
| 12 | * @author: pan | 12 | * @author: pan |
| 13 | * @date: 2020年12月2日 21:17:32 | 13 | * @date: 2020年12月2日 21:17:32 |
| 14 | */ | 14 | */ |
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
| @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; | @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; | ||
| 10 | import com.github.pagehelper.PageInfo; | 10 | import com.github.pagehelper.PageInfo; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| 13 | - * @Description:视频设备数据存储接口 | 13 | + * @description:视频设备数据存储接口 |
| 14 | * @author: swwheihei | 14 | * @author: swwheihei |
| 15 | * @date: 2020年5月6日 下午2:14:31 | 15 | * @date: 2020年5月6日 下午2:14:31 |
| 16 | */ | 16 | */ |
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
| @@ -25,7 +25,7 @@ import org.springframework.transaction.TransactionStatus; | @@ -25,7 +25,7 @@ import org.springframework.transaction.TransactionStatus; | ||
| 25 | import org.springframework.transaction.annotation.Transactional; | 25 | import org.springframework.transaction.annotation.Transactional; |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | - * @Description:视频设备数据存储-jdbc实现 | 28 | + * @description:视频设备数据存储-jdbc实现 |
| 29 | * @author: swwheihei | 29 | * @author: swwheihei |
| 30 | * @date: 2020年5月6日 下午2:31:42 | 30 | * @date: 2020年5月6日 下午2:31:42 |
| 31 | */ | 31 | */ |
src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
| @@ -6,7 +6,7 @@ import org.springframework.context.ApplicationContextAware; | @@ -6,7 +6,7 @@ import org.springframework.context.ApplicationContextAware; | ||
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 | ||
| 8 | /** | 8 | /** |
| 9 | - * @Description:spring bean获取工厂,获取spring中的已初始化的bean | 9 | + * @description:spring bean获取工厂,获取spring中的已初始化的bean |
| 10 | * @author: swwheihei | 10 | * @author: swwheihei |
| 11 | * @date: 2019年6月25日 下午4:51:52 | 11 | * @date: 2019年6月25日 下午4:51:52 |
| 12 | * | 12 | * |
src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java
| @@ -9,7 +9,7 @@ import com.alibaba.fastjson.JSON; | @@ -9,7 +9,7 @@ import com.alibaba.fastjson.JSON; | ||
| 9 | import com.alibaba.fastjson.serializer.SerializerFeature; | 9 | import com.alibaba.fastjson.serializer.SerializerFeature; |
| 10 | 10 | ||
| 11 | /** | 11 | /** |
| 12 | - * @Description:使用fastjson实现redis的序列化 | 12 | + * @description:使用fastjson实现redis的序列化 |
| 13 | * @author: swwheihei | 13 | * @author: swwheihei |
| 14 | * @date: 2020年5月6日 下午8:40:11 | 14 | * @date: 2020年5月6日 下午8:40:11 |
| 15 | */ | 15 | */ |
src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java
| @@ -8,7 +8,7 @@ import redis.clients.jedis.JedisPool; | @@ -8,7 +8,7 @@ import redis.clients.jedis.JedisPool; | ||
| 8 | import java.util.Set; | 8 | import java.util.Set; |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | - * @Description:Jedis工具类 | 11 | + * @description:Jedis工具类 |
| 12 | * @author: wangshaopeng@sunnybs.com | 12 | * @author: wangshaopeng@sunnybs.com |
| 13 | * @date: 2021年03月22日 下午8:27:29 | 13 | * @date: 2021年03月22日 下午8:27:29 |
| 14 | */ | 14 | */ |
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
| @@ -9,7 +9,7 @@ import org.springframework.stereotype.Component; | @@ -9,7 +9,7 @@ import org.springframework.stereotype.Component; | ||
| 9 | import org.springframework.util.CollectionUtils; | 9 | import org.springframework.util.CollectionUtils; |
| 10 | 10 | ||
| 11 | /** | 11 | /** |
| 12 | - * @Description:Redis工具类 | 12 | + * @description:Redis工具类 |
| 13 | * @author: swwheihei | 13 | * @author: swwheihei |
| 14 | * @date: 2020年5月6日 下午8:27:29 | 14 | * @date: 2020年5月6日 下午8:27:29 |
| 15 | */ | 15 | */ |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
| 1 | package com.genersoft.iot.vmp.vmanager.gb28181.device; | 1 | package com.genersoft.iot.vmp.vmanager.gb28181.device; |
| 2 | 2 | ||
| 3 | +import com.alibaba.fastjson.JSONObject; | ||
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 5 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 6 | +import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; | ||
| 7 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 4 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 8 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 9 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 10 | +import com.genersoft.iot.vmp.service.IDeviceService; | ||
| 5 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 11 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 12 | +import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 6 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | 13 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| 7 | import com.github.pagehelper.PageInfo; | 14 | import com.github.pagehelper.PageInfo; |
| 8 | -import io.swagger.annotations.*; | 15 | +import io.swagger.annotations.Api; |
| 16 | +import io.swagger.annotations.ApiImplicitParam; | ||
| 17 | +import io.swagger.annotations.ApiImplicitParams; | ||
| 18 | +import io.swagger.annotations.ApiOperation; | ||
| 9 | import org.slf4j.Logger; | 19 | import org.slf4j.Logger; |
| 10 | import org.slf4j.LoggerFactory; | 20 | import org.slf4j.LoggerFactory; |
| 11 | import org.springframework.beans.factory.annotation.Autowired; | 21 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -15,15 +25,6 @@ import org.springframework.util.StringUtils; | @@ -15,15 +25,6 @@ import org.springframework.util.StringUtils; | ||
| 15 | import org.springframework.web.bind.annotation.*; | 25 | import org.springframework.web.bind.annotation.*; |
| 16 | import org.springframework.web.context.request.async.DeferredResult; | 26 | import org.springframework.web.context.request.async.DeferredResult; |
| 17 | 27 | ||
| 18 | -import com.alibaba.fastjson.JSONObject; | ||
| 19 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 20 | -import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; | ||
| 21 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 22 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 23 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 24 | - | ||
| 25 | -import javax.sip.message.Response; | ||
| 26 | -import java.io.UnsupportedEncodingException; | ||
| 27 | import java.util.UUID; | 28 | import java.util.UUID; |
| 28 | 29 | ||
| 29 | @Api(tags = "国标设备查询", value = "国标设备查询") | 30 | @Api(tags = "国标设备查询", value = "国标设备查询") |
| @@ -50,6 +51,9 @@ public class DeviceQuery { | @@ -50,6 +51,9 @@ public class DeviceQuery { | ||
| 50 | @Autowired | 51 | @Autowired |
| 51 | private DeviceOffLineDetector offLineDetector; | 52 | private DeviceOffLineDetector offLineDetector; |
| 52 | 53 | ||
| 54 | + @Autowired | ||
| 55 | + private IDeviceService deviceService; | ||
| 56 | + | ||
| 53 | /** | 57 | /** |
| 54 | * 使用ID查询国标设备 | 58 | * 使用ID查询国标设备 |
| 55 | * @param deviceId 国标ID | 59 | * @param deviceId 国标ID |
| @@ -301,6 +305,18 @@ public class DeviceQuery { | @@ -301,6 +305,18 @@ public class DeviceQuery { | ||
| 301 | if (!StringUtils.isEmpty(device.getName())) deviceInStore.setName(device.getName()); | 305 | if (!StringUtils.isEmpty(device.getName())) deviceInStore.setName(device.getName()); |
| 302 | if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset()); | 306 | if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset()); |
| 303 | if (!StringUtils.isEmpty(device.getMediaServerId())) deviceInStore.setMediaServerId(device.getMediaServerId()); | 307 | if (!StringUtils.isEmpty(device.getMediaServerId())) deviceInStore.setMediaServerId(device.getMediaServerId()); |
| 308 | + | ||
| 309 | + if (deviceInStore.getSubscribeCycleForCatalog() <=0 && device.getSubscribeCycleForCatalog() > 0) { | ||
| 310 | + deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog()); | ||
| 311 | + // 开启订阅 | ||
| 312 | + deviceService.addCatalogSubscribe(deviceInStore); | ||
| 313 | + } | ||
| 314 | + if (deviceInStore.getSubscribeCycleForCatalog() > 0 && device.getSubscribeCycleForCatalog() <= 0) { | ||
| 315 | + deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog()); | ||
| 316 | + // 取消订阅 | ||
| 317 | + deviceService.removeCatalogSubscribe(deviceInStore); | ||
| 318 | + } | ||
| 319 | + | ||
| 304 | storager.updateDevice(deviceInStore); | 320 | storager.updateDevice(deviceInStore); |
| 305 | cmder.deviceInfoQuery(deviceInStore); | 321 | cmder.deviceInfoQuery(deviceInStore); |
| 306 | } | 322 | } |