Commit f1217682a9d1726b5b5673343dfe9b035e1180d4

Authored by 648540858
1 parent 341ea711

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

Showing 62 changed files with 345 additions and 3589 deletions
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
1 1 package com.genersoft.iot.vmp.common;
2 2  
3 3 /**
4   - * @Description: 定义常量
  4 + * @description: 定义常量
5 5 * @author: swwheihei
6 6 * @date: 2019年5月30日 下午3:04:04
7 7 *
... ...
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
... ... @@ -16,7 +16,7 @@ import redis.clients.jedis.JedisPool;
16 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 20 * @author: swwheihei
21 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 32 for (String deviceId : onlineForAll) {
33 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 4 import org.springframework.context.annotation.Configuration;
5 5  
6 6 /**
7   - * @Description: 获取数据库配置
  7 + * @description: 获取数据库配置
8 8 * @author: swwheihei
9 9 * @date: 2020年5月6日 下午2:46:00
10 10 */
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
1 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 4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  5 +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
16 6 import gov.nist.javax.sip.SipProviderImpl;
  7 +import gov.nist.javax.sip.SipStackImpl;
17 8 import org.slf4j.Logger;
18 9 import org.slf4j.LoggerFactory;
19 10 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -21,14 +12,15 @@ import org.springframework.context.annotation.Bean;
21 12 import org.springframework.context.annotation.DependsOn;
22 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 22 @Component
31   -public class SipLayer implements SipListener {
  23 +public class SipLayer{
32 24  
33 25 private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
34 26  
... ... @@ -36,7 +28,7 @@ public class SipLayer implements SipListener {
36 28 private SipConfig sipConfig;
37 29  
38 30 @Autowired
39   - private SIPProcessorFactory processorFactory;
  31 + private SIPProcessorObserver sipProcessorObserver;
40 32  
41 33 @Autowired
42 34 private SipSubscribe sipSubscribe;
... ... @@ -50,19 +42,16 @@ public class SipLayer implements SipListener {
50 42 */
51 43 private ThreadPoolExecutor processThreadPool;
52 44  
53   - @Bean("initSipServer")
54   - private ThreadPoolExecutor initSipServer() {
55   -
  45 + public SipLayer() {
56 46 int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
57 47 LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000);
58 48 processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
59 49 0L,TimeUnit.MILLISECONDS,processQueue,
60 50 new ThreadPoolExecutor.CallerRunsPolicy());
61   - return processThreadPool;
62 51 }
63   -
  52 +
  53 +
64 54 @Bean("sipFactory")
65   - @DependsOn("initSipServer")
66 55 private SipFactory createSipFactory() {
67 56 sipFactory = SipFactory.getInstance();
68 57 sipFactory.setPathName("gov.nist");
... ... @@ -70,7 +59,7 @@ public class SipLayer implements SipListener {
70 59 }
71 60  
72 61 @Bean("sipStack")
73   - @DependsOn({"initSipServer", "sipFactory"})
  62 + @DependsOn({"sipFactory"})
74 63 private SipStack createSipStack() throws PeerUnavailableException {
75 64 Properties properties = new Properties();
76 65 properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
... ... @@ -96,7 +85,7 @@ public class SipLayer implements SipListener {
96 85 try {
97 86 tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "TCP");
98 87 tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint);
99   - tcpSipProvider.addSipListener(this);
  88 + tcpSipProvider.addSipListener(sipProcessorObserver);
100 89 logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "}");
101 90 } catch (TransportNotSupportedException e) {
102 91 e.printStackTrace();
... ... @@ -119,8 +108,7 @@ public class SipLayer implements SipListener {
119 108 try {
120 109 udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "UDP");
121 110 udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint);
122   - udpSipProvider.addSipListener(this);
123   -// udpSipProvider.setAutomaticDialogSupportEnabled(false);
  111 + udpSipProvider.addSipListener(sipProcessorObserver);
124 112 } catch (TransportNotSupportedException e) {
125 113 e.printStackTrace();
126 114 } catch (InvalidArgumentException e) {
... ... @@ -135,140 +123,4 @@ public class SipLayer implements SipListener {
135 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 9 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
10 10  
11 11 /**
12   - * @Description:注册逻辑处理,当设备注册后触发逻辑。
  12 + * @description:注册逻辑处理,当设备注册后触发逻辑。
13 13 * @author: swwheihei
14 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 109 */
110 110 private String charset ;
111 111  
  112 + /**
  113 + * 目录订阅周期,0为不订阅
  114 + */
  115 + private int subscribeCycleForCatalog ;
  116 +
112 117  
113 118  
114 119 public String getDeviceId() {
... ... @@ -270,4 +275,12 @@ public class Device {
270 275 public void setCharset(String charset) {
271 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
1 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
3 3 /**
4   - * @Description: 移动位置bean
  4 + * @description: 移动位置bean
5 5 * @author: lawrencehj
6 6 * @date: 2021年1月23日
7 7 */
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
... ... @@ -6,7 +6,7 @@ package com.genersoft.iot.vmp.gb28181.bean;
6 6 import java.util.List;
7 7  
8 8 /**
9   - * @Description:设备录像信息bean
  9 + * @description:设备录像信息bean
10 10 * @author: swwheihei
11 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 8 import java.util.Date;
9 9  
10 10 /**
11   - * @Description:设备录像bean
  11 + * @description:设备录像bean
12 12 * @author: swwheihei
13 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 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
8 8  
9 9 /**
10   - * @Description:设备离在线状态检测器,用于检测设备状态
  10 + * @description:设备离在线状态检测器,用于检测设备状态
11 11 * @author: swwheihei
12 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 13 import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
14 14  
15 15 /**
16   - * @Description:Event事件通知推送器,支持推送在线事件、离线事件
  16 + * @description:Event事件通知推送器,支持推送在线事件、离线事件
17 17 * @author: swwheihei
18 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 12 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
13 13  
14 14 /**
15   - * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
  15 + * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
16 16 * @author: swwheihei
17 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 12 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
13 13  
14 14 /**
15   - * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
  15 + * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
16 16 * @author: swwheihei
17 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 3 import org.springframework.context.ApplicationEvent;
4 4  
5 5 /**
6   - * @Description: 离线事件类
  6 + * @description: 离线事件类
7 7 * @author: swwheihei
8 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 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 16 * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
17 17 * @author: swwheihei
18 18 * @date: 2020年5月6日 下午1:51:23
... ... @@ -54,5 +54,8 @@ public class OfflineEventListener implements ApplicationListener&lt;OfflineEvent&gt; {
54 54  
55 55 // 处理离线监听
56 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 4 import org.springframework.context.ApplicationEvent;
5 5  
6 6 /**
7   - * @Description: 在线事件类
  7 + * @description: 在线事件类
8 8 * @author: swwheihei
9 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 13 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
14 14  
15 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 21 * @author: swwheihei
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 18 import javax.sip.message.Response;
19 19  
20 20 /**
21   - * @Description: 平台心跳超时事件
  21 + * @description: 平台心跳超时事件
22 22 * @author: panll
23 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 19 import java.util.*;
20 20  
21 21 /**
22   - * @Description: 平台未注册事件,来源有二:
  22 + * @description: 平台未注册事件,来源有二:
23 23 * 1、平台新添加
24 24 * 2、平台心跳超时
25 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 15 import org.springframework.stereotype.Component;
16 16  
17 17 /**
18   - * @Description:视频流session管理器,管理视频预览、预览回放的通信句柄
  18 + * @description:视频流session管理器,管理视频预览、预览回放的通信句柄
19 19 * @author: swwheihei
20 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  
8 8 import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
9 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 11 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
12 12  
13 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 11 import org.springframework.web.context.request.async.DeferredResult;
12 12  
13 13 /**
14   - * @Description: 异步请求处理
  14 + * @description: 异步请求处理
15 15 * @author: swwheihei
16 16 * @date: 2020年5月8日 下午7:59:05
17 17 */
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.callback;
2 2  
3 3 /**
4   - * @Description: 请求信息定义
  4 + * @description: 请求信息定义
5 5 * @author: swwheihei
6 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 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
8 8  
9 9 /**
10   - * @Description:设备能力接口,用于定义设备的控制、查询能力
  10 + * @description:设备能力接口,用于定义设备的控制、查询能力
11 11 * @author: swwheihei
12 12 * @date: 2020年5月3日 下午9:16:34
13 13 */
... ... @@ -299,4 +299,11 @@ public interface ISIPCommander {
299 299 * @return true = 命令发送成功
300 300 */
301 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 19 import java.util.UUID;
20 20  
21 21 /**
22   - * @Description: 平台命令request创造器 TODO 冗余代码太多待优化
  22 + * @description: 平台命令request创造器 TODO 冗余代码太多待优化
23 23 * @author: panll
24 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 18 import com.genersoft.iot.vmp.gb28181.bean.Device;
19 19  
20 20 /**
21   - * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化
  21 + * @description:摄像头命令request创造器 TODO 冗余代码太多待优化
22 22 * @author: swwheihei
23 23 * @date: 2020年5月6日 上午9:29:02
24 24 */
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
1 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 3 import com.alibaba.fastjson.JSONObject;
  4 +import com.genersoft.iot.vmp.conf.SipConfig;
14 5 import com.genersoft.iot.vmp.conf.UserSetup;
  6 +import com.genersoft.iot.vmp.gb28181.bean.Device;
15 7 import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
16   -import com.genersoft.iot.vmp.media.zlm.*;
17 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 15 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
19 16 import com.genersoft.iot.vmp.service.IMediaServerService;
20 17 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
... ... @@ -29,20 +26,20 @@ import org.slf4j.LoggerFactory;
29 26 import org.springframework.beans.factory.annotation.Autowired;
30 27 import org.springframework.beans.factory.annotation.Qualifier;
31 28 import org.springframework.context.annotation.DependsOn;
32   -import org.springframework.context.annotation.Lazy;
33 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 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 43 * @author: swwheihei
47 44 * @date: 2020年5月3日 下午9:22:48
48 45 */
... ... @@ -55,12 +52,10 @@ public class SIPCommander implements ISIPCommander {
55 52 @Autowired
56 53 private SipConfig sipConfig;
57 54  
58   - @Lazy
59 55 @Autowired
60 56 @Qualifier(value="tcpSipProvider")
61 57 private SipProviderImpl tcpSipProvider;
62 58  
63   - @Lazy
64 59 @Autowired
65 60 @Qualifier(value="udpSipProvider")
66 61 private SipProviderImpl udpSipProvider;
... ... @@ -89,11 +84,6 @@ public class SIPCommander implements ISIPCommander {
89 84 @Autowired
90 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 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 1511 private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
1495 1512 return transmitRequest(device, request, null, null);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/SIPResponseProcessorAbstract.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.transmit.event.response;
  2 +
  3 +import org.springframework.beans.factory.InitializingBean;
  4 +
  5 +public abstract class SIPResponseProcessorAbstract implements InitializingBean, ISIPResponseProcessor {
  6 +
  7 +
  8 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/ITimeoutProcessor.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.transmit.event.timeout;
  2 +
  3 +import javax.sip.TimeoutEvent;
  4 +
  5 +public interface ITimeoutProcessor {
  6 + void process(TimeoutEvent event);
  7 +}
... ...
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
1   -package com.genersoft.iot.vmp.gb28181.transmit.request;
2   -
3   -/**
4   - * @Description:处理接收IPCamera发来的SIP协议请求消息
5   - * @author: swwheihei
6   - * @date: 2020年5月3日 下午4:42:22
7   - */
8   -public interface ISIPRequestProcessor {
9   -
10   - public void process();
11   -
12   -}
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 6 import java.util.Locale;
7 7  
8 8 /**
9   - * @Description:时间工具类,主要处理ISO 8601格式转换
  9 + * @description:时间工具类,主要处理ISO 8601格式转换
10 10 * @author: swwheihei
11 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 3 import gov.nist.javax.sip.address.AddressImpl;
4 4 import gov.nist.javax.sip.address.SipUri;
... ... @@ -9,15 +9,20 @@ import javax.sip.message.Request;
9 9 /**
10 10 * @author panlinlin
11 11 * @version 1.0.0
12   - * @Description JAIN SIP的工具类
  12 + * @description JAIN SIP的工具类
13 13 * @createTime 2021年09月27日 15:12:00
14 14 */
15 15 public class SipUtils {
16 16  
17 17 public static String getUserIdFromFromHeader(Request request) {
18 18 FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
  19 + return getUserIdFromFromHeader(fromHeader);
  20 + }
  21 +
  22 + public static String getUserIdFromFromHeader(FromHeader fromHeader) {
19 23 AddressImpl address = (AddressImpl)fromHeader.getAddress();
20 24 SipUri uri = (SipUri) address.getURI();
21 25 return uri.getUser();
22 26 }
  27 +
23 28 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
1 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 3 import com.alibaba.fastjson.JSONArray;
11 4 import com.alibaba.fastjson.JSONObject;
12   -
13 5 import org.dom4j.Attribute;
14 6 import org.dom4j.Document;
15 7 import org.dom4j.DocumentException;
... ... @@ -19,6 +11,12 @@ import org.slf4j.Logger;
19 11 import org.slf4j.LoggerFactory;
20 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 21 * 基于dom4j的工具包
24 22 *
... ... @@ -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 31 import javax.servlet.http.HttpServletRequest;
32 32  
33 33 /**
34   - * @Description:针对 ZLMediaServer的hook事件监听
  34 + * @description:针对 ZLMediaServer的hook事件监听
35 35 * @author: swwheihei
36 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 8 import java.util.concurrent.ConcurrentHashMap;
9 9  
10 10 /**
11   - * @Description:针对 ZLMediaServer的hook事件订阅
  11 + * @description:针对 ZLMediaServer的hook事件订阅
12 12 * @author: pan
13 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 10 import com.github.pagehelper.PageInfo;
11 11  
12 12 /**
13   - * @Description:视频设备数据存储接口
  13 + * @description:视频设备数据存储接口
14 14 * @author: swwheihei
15 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 25 import org.springframework.transaction.annotation.Transactional;
26 26  
27 27 /**
28   - * @Description:视频设备数据存储-jdbc实现
  28 + * @description:视频设备数据存储-jdbc实现
29 29 * @author: swwheihei
30 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 6 import org.springframework.stereotype.Component;
7 7  
8 8 /**
9   - * @Description:spring bean获取工厂,获取spring中的已初始化的bean
  9 + * @description:spring bean获取工厂,获取spring中的已初始化的bean
10 10 * @author: swwheihei
11 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 9 import com.alibaba.fastjson.serializer.SerializerFeature;
10 10  
11 11 /**
12   - * @Description:使用fastjson实现redis的序列化
  12 + * @description:使用fastjson实现redis的序列化
13 13 * @author: swwheihei
14 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 8 import java.util.Set;
9 9  
10 10 /**
11   - * @Description:Jedis工具类
  11 + * @description:Jedis工具类
12 12 * @author: wangshaopeng@sunnybs.com
13 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 9 import org.springframework.util.CollectionUtils;
10 10  
11 11 /**
12   - * @Description:Redis工具类
  12 + * @description:Redis工具类
13 13 * @author: swwheihei
14 14 * @date: 2020年5月6日 下午8:27:29
15 15 */
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
1 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 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 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 11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  12 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
6 13 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
7 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 19 import org.slf4j.Logger;
10 20 import org.slf4j.LoggerFactory;
11 21 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -15,15 +25,6 @@ import org.springframework.util.StringUtils;
15 25 import org.springframework.web.bind.annotation.*;
16 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 28 import java.util.UUID;
28 29  
29 30 @Api(tags = "国标设备查询", value = "国标设备查询")
... ... @@ -50,6 +51,9 @@ public class DeviceQuery {
50 51 @Autowired
51 52 private DeviceOffLineDetector offLineDetector;
52 53  
  54 + @Autowired
  55 + private IDeviceService deviceService;
  56 +
53 57 /**
54 58 * 使用ID查询国标设备
55 59 * @param deviceId 国标ID
... ... @@ -301,6 +305,18 @@ public class DeviceQuery {
301 305 if (!StringUtils.isEmpty(device.getName())) deviceInStore.setName(device.getName());
302 306 if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset());
303 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 320 storager.updateDevice(deviceInStore);
305 321 cmder.deviceInfoQuery(deviceInStore);
306 322 }
... ...