Commit 4fe5672623212f5f6ac50009c4dc88d5c517dbb4

Authored by 648540858
1 parent 470aa479

处理获取消息体内容为空时造成的空指针异常

Showing 13 changed files with 127 additions and 113 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
@@ -231,6 +231,9 @@ public abstract class SIPRequestProcessorParent { @@ -231,6 +231,9 @@ public abstract class SIPRequestProcessorParent {
231 byte destBye = (byte) despChar; 231 byte destBye = (byte) despChar;
232 List<Byte> result = new ArrayList<>(); 232 List<Byte> result = new ArrayList<>();
233 byte[] rawContent = request.getRawContent(); 233 byte[] rawContent = request.getRawContent();
  234 + if (rawContent == null) {
  235 + return null;
  236 + }
234 for (int i = 0; i < rawContent.length; i++) { 237 for (int i = 0; i < rawContent.length; i++) {
235 if (rawContent[i] == destBye) { 238 if (rawContent[i] == destBye) {
236 boolean resul = false; 239 boolean resul = false;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
@@ -41,7 +41,7 @@ import java.util.Iterator; @@ -41,7 +41,7 @@ import java.util.Iterator;
41 import java.util.concurrent.ConcurrentLinkedQueue; 41 import java.util.concurrent.ConcurrentLinkedQueue;
42 42
43 /** 43 /**
44 - * SIP命令类型: NOTIFY请求 44 + * SIP命令类型: NOTIFY请求,这是作为上级发送订阅请求后,设备才会响应的
45 */ 45 */
46 @Component 46 @Component
47 public class NotifyRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor { 47 public class NotifyRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
@@ -198,6 +198,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -198,6 +198,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
198 } 198 }
199 199
200 storager.updateChannelPosition(deviceChannel); 200 storager.updateChannelPosition(deviceChannel);
  201 +
201 // 发送redis消息。 通知位置信息的变化 202 // 发送redis消息。 通知位置信息的变化
202 JSONObject jsonObject = new JSONObject(); 203 JSONObject jsonObject = new JSONObject();
203 jsonObject.put("time", time); 204 jsonObject.put("time", time);
@@ -237,6 +238,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -237,6 +238,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
237 return; 238 return;
238 } 239 }
239 rootElement = getRootElement(evt, device.getCharset()); 240 rootElement = getRootElement(evt, device.getCharset());
  241 + if (rootElement == null) {
  242 + logger.warn("[ NotifyAlarm ] content cannot be null");
  243 + return;
  244 + }
240 DeviceAlarm deviceAlarm = new DeviceAlarm(); 245 DeviceAlarm deviceAlarm = new DeviceAlarm();
241 deviceAlarm.setDeviceId(deviceId); 246 deviceAlarm.setDeviceId(deviceId);
242 deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority")); 247 deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
@@ -272,8 +277,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -272,8 +277,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
272 mobilePosition.setLatitude(deviceAlarm.getLatitude()); 277 mobilePosition.setLatitude(deviceAlarm.getLatitude());
273 mobilePosition.setReportSource("GPS Alarm"); 278 mobilePosition.setReportSource("GPS Alarm");
274 279
275 -  
276 -  
277 // 更新device channel 的经纬度 280 // 更新device channel 的经纬度
278 DeviceChannel deviceChannel = new DeviceChannel(); 281 DeviceChannel deviceChannel = new DeviceChannel();
279 deviceChannel.setDeviceId(device.getDeviceId()); 282 deviceChannel.setDeviceId(device.getDeviceId());
@@ -294,6 +297,18 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -294,6 +297,18 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
294 } 297 }
295 298
296 storager.updateChannelPosition(deviceChannel); 299 storager.updateChannelPosition(deviceChannel);
  300 + // 发送redis消息。 通知位置信息的变化
  301 + JSONObject jsonObject = new JSONObject();
  302 + jsonObject.put("time", mobilePosition.getTime());
  303 + jsonObject.put("serial", deviceChannel.getDeviceId());
  304 + jsonObject.put("code", deviceChannel.getChannelId());
  305 + jsonObject.put("longitude", mobilePosition.getLongitude());
  306 + jsonObject.put("latitude", mobilePosition.getLatitude());
  307 + jsonObject.put("altitude", mobilePosition.getAltitude());
  308 + jsonObject.put("direction", mobilePosition.getDirection());
  309 + jsonObject.put("speed", mobilePosition.getSpeed());
  310 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
  311 +
297 } 312 }
298 // TODO: 需要实现存储报警信息、报警分类 313 // TODO: 需要实现存储报警信息、报警分类
299 314
@@ -322,6 +337,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -322,6 +337,10 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
322 return; 337 return;
323 } 338 }
324 Element rootElement = getRootElement(evt, device.getCharset()); 339 Element rootElement = getRootElement(evt, device.getCharset());
  340 + if (rootElement == null) {
  341 + logger.warn("[ 收到目录订阅 ] content cannot be null");
  342 + return;
  343 + }
325 Element deviceListElement = rootElement.element("DeviceList"); 344 Element deviceListElement = rootElement.element("DeviceList");
326 if (deviceListElement == null) { 345 if (deviceListElement == null) {
327 return; 346 return;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/NotifyMessageHandler.java
@@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
8 8
9 /** 9 /**
10 - * 命令类型: 通知命令 10 + * 命令类型: 通知命令, 参看 A.2.5 通知命令
11 * 命令类型: 状态信息(心跳)报送, 报警通知, 媒体通知, 移动设备位置数据,语音广播通知(TODO), 设备预置位(TODO) 11 * 命令类型: 状态信息(心跳)报送, 报警通知, 媒体通知, 移动设备位置数据,语音广播通知(TODO), 设备预置位(TODO)
12 * @author lin 12 * @author lin
13 */ 13 */
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
2 2
  3 +import com.alibaba.fastjson.JSONObject;
3 import com.genersoft.iot.vmp.conf.SipConfig; 4 import com.genersoft.iot.vmp.conf.SipConfig;
4 import com.genersoft.iot.vmp.conf.UserSetting; 5 import com.genersoft.iot.vmp.conf.UserSetting;
5 import com.genersoft.iot.vmp.gb28181.bean.*; 6 import com.genersoft.iot.vmp.gb28181.bean.*;
@@ -32,6 +33,9 @@ import java.text.ParseException; @@ -32,6 +33,9 @@ import java.text.ParseException;
32 33
33 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*; 34 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*;
34 35
  36 +/**
  37 + * 报警事件的处理,参考:9.4
  38 + */
35 @Component 39 @Component
36 public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 40 public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
37 41
@@ -73,12 +77,8 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -73,12 +77,8 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
73 // 回复200 OK 77 // 回复200 OK
74 try { 78 try {
75 responseAck(evt, Response.OK); 79 responseAck(evt, Response.OK);
76 - } catch (SipException e) {  
77 - throw new RuntimeException(e);  
78 - } catch (InvalidArgumentException e) {  
79 - throw new RuntimeException(e);  
80 - } catch (ParseException e) {  
81 - throw new RuntimeException(e); 80 + } catch (SipException | InvalidArgumentException | ParseException e) {
  81 + logger.error("[收到报警通知], 回复200OK失败", e);
82 } 82 }
83 83
84 Element deviceIdElement = rootElement.element("DeviceID"); 84 Element deviceIdElement = rootElement.element("DeviceID");
@@ -124,7 +124,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -124,7 +124,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
124 mobilePosition.setLatitude(deviceAlarm.getLatitude()); 124 mobilePosition.setLatitude(deviceAlarm.getLatitude());
125 mobilePosition.setReportSource("GPS Alarm"); 125 mobilePosition.setReportSource("GPS Alarm");
126 126
127 -  
128 // 更新device channel 的经纬度 127 // 更新device channel 的经纬度
129 DeviceChannel deviceChannel = new DeviceChannel(); 128 DeviceChannel deviceChannel = new DeviceChannel();
130 deviceChannel.setDeviceId(device.getDeviceId()); 129 deviceChannel.setDeviceId(device.getDeviceId());
@@ -144,6 +143,18 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -144,6 +143,18 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
144 storager.insertMobilePosition(mobilePosition); 143 storager.insertMobilePosition(mobilePosition);
145 } 144 }
146 storager.updateChannelPosition(deviceChannel); 145 storager.updateChannelPosition(deviceChannel);
  146 +
  147 + // 发送redis消息。 通知位置信息的变化
  148 + JSONObject jsonObject = new JSONObject();
  149 + jsonObject.put("time", mobilePosition.getTime());
  150 + jsonObject.put("serial", deviceChannel.getDeviceId());
  151 + jsonObject.put("code", deviceChannel.getChannelId());
  152 + jsonObject.put("longitude", mobilePosition.getLongitude());
  153 + jsonObject.put("latitude", mobilePosition.getLatitude());
  154 + jsonObject.put("altitude", mobilePosition.getAltitude());
  155 + jsonObject.put("direction", mobilePosition.getDirection());
  156 + jsonObject.put("speed", mobilePosition.getSpeed());
  157 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
147 } 158 }
148 } 159 }
149 if (!StringUtils.isEmpty(deviceAlarm.getDeviceId())) { 160 if (!StringUtils.isEmpty(deviceAlarm.getDeviceId())) {
@@ -159,7 +170,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -159,7 +170,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
159 alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription()); 170 alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());
160 alarmChannelMessage.setGbId(channelId); 171 alarmChannelMessage.setGbId(channelId);
161 redisCatchStorage.sendAlarmMsg(alarmChannelMessage); 172 redisCatchStorage.sendAlarmMsg(alarmChannelMessage);
162 -  
163 return; 173 return;
164 } 174 }
165 175
@@ -169,7 +179,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @@ -169,7 +179,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
169 deviceAlarmService.add(deviceAlarm); 179 deviceAlarmService.add(deviceAlarm);
170 } 180 }
171 181
172 -  
173 if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) { 182 if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
174 publisher.deviceAlarmEventPublish(deviceAlarm); 183 publisher.deviceAlarmEventPublish(deviceAlarm);
175 } 184 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/CatalogNotifyMessageHandler.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;  
2 -  
3 -import com.genersoft.iot.vmp.gb28181.bean.*;  
4 -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;  
5 -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;  
6 -import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;  
7 -import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;  
8 -import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;  
9 -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;  
10 -import org.dom4j.Element;  
11 -import org.springframework.beans.factory.InitializingBean;  
12 -import org.springframework.beans.factory.annotation.Autowired;  
13 -import org.springframework.stereotype.Component;  
14 -  
15 -import javax.sip.InvalidArgumentException;  
16 -import javax.sip.RequestEvent;  
17 -import javax.sip.SipException;  
18 -import javax.sip.header.FromHeader;  
19 -import javax.sip.message.Response;  
20 -import java.text.ParseException;  
21 -import java.util.ArrayList;  
22 -import java.util.List;  
23 -  
24 -@Component  
25 -public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {  
26 -  
27 - private final String cmdType = "Catalog";  
28 -  
29 - @Autowired  
30 - private NotifyMessageHandler notifyMessageHandler;  
31 -  
32 - @Autowired  
33 - private IVideoManagerStorage storage;  
34 -  
35 - @Autowired  
36 - private SIPCommanderFroPlatform cmderFroPlatform;  
37 -  
38 - @Override  
39 - public void afterPropertiesSet() throws Exception {  
40 - notifyMessageHandler.addHandler(cmdType, this);  
41 - }  
42 -  
43 - @Override  
44 - public void handForDevice(RequestEvent evt, Device device, Element element) {  
45 -  
46 - }  
47 -  
48 - @Override  
49 - public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {  
50 -  
51 - String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + parentPlatform.getServerGBId();  
52 - FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);  
53 - try {  
54 - // 回复200 OK  
55 - responseAck(evt, Response.OK);  
56 - Element snElement = rootElement.element("SN");  
57 - String sn = snElement.getText();  
58 - // 准备回复通道信息  
59 - List<DeviceChannelInPlatform> deviceChannels = storage.queryChannelListInParentPlatform(parentPlatform.getServerGBId());  
60 - // 查询关联的直播通道  
61 - List<DeviceChannel> gbStreams = storage.queryGbStreamListInPlatform(parentPlatform.getServerGBId());  
62 - // 回复目录信息  
63 - List<DeviceChannel> catalogs = storage.queryCatalogInPlatform(parentPlatform.getServerGBId());  
64 -  
65 - List<DeviceChannel> allChannels = new ArrayList<>();  
66 - if (catalogs.size() > 0) {  
67 - allChannels.addAll(catalogs);  
68 - }  
69 - // 回复级联的通道  
70 - if (deviceChannels.size() > 0) {  
71 - allChannels.addAll(deviceChannels);  
72 - }  
73 - // 回复直播的通道  
74 - if (gbStreams.size() > 0) {  
75 - allChannels.addAll(gbStreams);  
76 - }  
77 - if (allChannels.size() > 0) {  
78 - cmderFroPlatform.catalogQuery(allChannels, parentPlatform, sn, fromHeader.getTag());  
79 - }else {  
80 - // 回复无通道  
81 - cmderFroPlatform.catalogQuery(null, parentPlatform, sn, fromHeader.getTag(), 0);  
82 - }  
83 - } catch (SipException | InvalidArgumentException | ParseException e) {  
84 - e.printStackTrace();  
85 - }  
86 -  
87 - }  
88 -}  
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -25,6 +25,9 @@ import javax.sip.header.ViaHeader; @@ -25,6 +25,9 @@ import javax.sip.header.ViaHeader;
25 import javax.sip.message.Response; 25 import javax.sip.message.Response;
26 import java.text.ParseException; 26 import java.text.ParseException;
27 27
  28 +/**
  29 + * 状态信息(心跳)报送
  30 + */
28 @Component 31 @Component
29 public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 32 public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
30 33
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
@@ -29,6 +29,9 @@ import java.text.ParseException; @@ -29,6 +29,9 @@ import java.text.ParseException;
29 29
30 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; 30 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
31 31
  32 +/**
  33 + * 媒体通知
  34 + */
32 @Component 35 @Component
33 public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 36 public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
34 37
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
2 2
  3 +import com.alibaba.fastjson.JSONObject;
3 import com.genersoft.iot.vmp.conf.UserSetting; 4 import com.genersoft.iot.vmp.conf.UserSetting;
4 import com.genersoft.iot.vmp.gb28181.bean.*; 5 import com.genersoft.iot.vmp.gb28181.bean.*;
5 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; 7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
8 -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;  
9 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; 9 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
10 import com.genersoft.iot.vmp.service.IDeviceChannelService; 10 import com.genersoft.iot.vmp.service.IDeviceChannelService;
  11 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 12 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
12 import com.genersoft.iot.vmp.utils.DateUtil; 13 import com.genersoft.iot.vmp.utils.DateUtil;
13 -import com.genersoft.iot.vmp.utils.GpsUtil;  
14 import org.dom4j.DocumentException; 14 import org.dom4j.DocumentException;
15 import org.dom4j.Element; 15 import org.dom4j.Element;
16 import org.slf4j.Logger; 16 import org.slf4j.Logger;
@@ -28,6 +28,9 @@ import java.text.ParseException; @@ -28,6 +28,9 @@ import java.text.ParseException;
28 28
29 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; 29 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
30 30
  31 +/**
  32 + * 移动设备位置数据通知,设备主动发起,不需要上级订阅
  33 + */
31 @Component 34 @Component
32 public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 35 public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
33 36
@@ -44,6 +47,9 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @@ -44,6 +47,9 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
44 private IVideoManagerStorage storager; 47 private IVideoManagerStorage storager;
45 48
46 @Autowired 49 @Autowired
  50 + private IRedisCatchStorage redisCatchStorage;
  51 +
  52 + @Autowired
47 private IDeviceChannelService deviceChannelService; 53 private IDeviceChannelService deviceChannelService;
48 54
49 @Override 55 @Override
@@ -56,7 +62,11 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @@ -56,7 +62,11 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
56 62
57 try { 63 try {
58 rootElement = getRootElement(evt, device.getCharset()); 64 rootElement = getRootElement(evt, device.getCharset());
59 - 65 + if (rootElement == null) {
  66 + logger.warn("[ 移动设备位置数据通知 ] content cannot be null");
  67 + responseAck(evt, Response.BAD_REQUEST);
  68 + return;
  69 + }
60 MobilePosition mobilePosition = new MobilePosition(); 70 MobilePosition mobilePosition = new MobilePosition();
61 mobilePosition.setCreateTime(DateUtil.getNow()); 71 mobilePosition.setCreateTime(DateUtil.getNow());
62 if (!StringUtils.isEmpty(device.getName())) { 72 if (!StringUtils.isEmpty(device.getName())) {
@@ -106,6 +116,19 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @@ -106,6 +116,19 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen
106 storager.updateChannelPosition(deviceChannel); 116 storager.updateChannelPosition(deviceChannel);
107 //回复 200 OK 117 //回复 200 OK
108 responseAck(evt, Response.OK); 118 responseAck(evt, Response.OK);
  119 +
  120 + // 发送redis消息。 通知位置信息的变化
  121 + JSONObject jsonObject = new JSONObject();
  122 + jsonObject.put("time", mobilePosition.getTime());
  123 + jsonObject.put("serial", deviceChannel.getDeviceId());
  124 + jsonObject.put("code", deviceChannel.getChannelId());
  125 + jsonObject.put("longitude", mobilePosition.getLongitude());
  126 + jsonObject.put("latitude", mobilePosition.getLatitude());
  127 + jsonObject.put("altitude", mobilePosition.getAltitude());
  128 + jsonObject.put("direction", mobilePosition.getDirection());
  129 + jsonObject.put("speed", mobilePosition.getSpeed());
  130 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
  131 +
109 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { 132 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
110 e.printStackTrace(); 133 e.printStackTrace();
111 } 134 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
@@ -95,12 +95,16 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -95,12 +95,16 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
95 HandlerCatchData take = taskQueue.poll(); 95 HandlerCatchData take = taskQueue.poll();
96 try { 96 try {
97 Element rootElement = getRootElement(take.getEvt(), take.getDevice().getCharset()); 97 Element rootElement = getRootElement(take.getEvt(), take.getDevice().getCharset());
  98 + if (rootElement == null) {
  99 + logger.warn("[ 收到通道 ] content cannot be null");
  100 + continue;
  101 + }
98 Element deviceListElement = rootElement.element("DeviceList"); 102 Element deviceListElement = rootElement.element("DeviceList");
99 Element sumNumElement = rootElement.element("SumNum"); 103 Element sumNumElement = rootElement.element("SumNum");
100 Element snElement = rootElement.element("SN"); 104 Element snElement = rootElement.element("SN");
101 if (snElement == null || sumNumElement == null || deviceListElement == null) { 105 if (snElement == null || sumNumElement == null || deviceListElement == null) {
102 responseAck(take.getEvt(), Response.BAD_REQUEST, "xml error"); 106 responseAck(take.getEvt(), Response.BAD_REQUEST, "xml error");
103 - return; 107 + continue;
104 } 108 }
105 int sumNum = Integer.parseInt(sumNumElement.getText()); 109 int sumNum = Integer.parseInt(sumNumElement.getText());
106 110
@@ -129,7 +133,8 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @@ -129,7 +133,8 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
129 catalogDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, take.getDevice(), channelList); 133 catalogDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, take.getDevice(), channelList);
130 logger.info("[收到通道]设备: {} -> {}个,{}/{}", take.getDevice().getDeviceId(), channelList.size(), catalogDataCatch.get(take.getDevice().getDeviceId()) == null ? 0 :catalogDataCatch.get(take.getDevice().getDeviceId()).size(), sumNum); 134 logger.info("[收到通道]设备: {} -> {}个,{}/{}", take.getDevice().getDeviceId(), channelList.size(), catalogDataCatch.get(take.getDevice().getDeviceId()) == null ? 0 :catalogDataCatch.get(take.getDevice().getDeviceId()).size(), sumNum);
131 if (catalogDataCatch.get(take.getDevice().getDeviceId()).size() == sumNum) { 135 if (catalogDataCatch.get(take.getDevice().getDeviceId()).size() == sumNum) {
132 - // 数据已经完整接收 136 + // 数据已经完整接收, 此时可能存在某个设备离线变上线的情况,但是考虑到性能,此处不做处理,
  137 + // 目前支持设备通道上线通知时和设备上线时向上级通知
133 boolean resetChannelsResult = storager.resetChannels(take.getDevice().getDeviceId(), catalogDataCatch.get(take.getDevice().getDeviceId())); 138 boolean resetChannelsResult = storager.resetChannels(take.getDevice().getDeviceId(), catalogDataCatch.get(take.getDevice().getDeviceId()));
134 if (!resetChannelsResult) { 139 if (!resetChannelsResult) {
135 String errorMsg = "接收成功,写入失败,共" + sumNum + "条,已接收" + catalogDataCatch.get(take.getDevice().getDeviceId()).size() + "条"; 140 String errorMsg = "接收成功,写入失败,共" + sumNum + "条,已接收" + catalogDataCatch.get(take.getDevice().getDeviceId()).size() + "条";
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java
@@ -75,6 +75,11 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -75,6 +75,11 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
75 } 75 }
76 try { 76 try {
77 rootElement = getRootElement(evt, device.getCharset()); 77 rootElement = getRootElement(evt, device.getCharset());
  78 + if (rootElement == null) {
  79 + logger.warn("[ 接收到DeviceInfo应答消息 ] content cannot be null");
  80 + responseAck(evt, Response.BAD_REQUEST);
  81 + return;
  82 + }
78 Element deviceIdElement = rootElement.element("DeviceID"); 83 Element deviceIdElement = rootElement.element("DeviceID");
79 String channelId = deviceIdElement.getTextTrim(); 84 String channelId = deviceIdElement.getTextTrim();
80 String key = DeferredResultHolder.CALLBACK_CMD_DEVICEINFO + device.getDeviceId() + channelId; 85 String key = DeferredResultHolder.CALLBACK_CMD_DEVICEINFO + device.getDeviceId() + channelId;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
2 2
  3 +import com.alibaba.fastjson.JSONObject;
3 import com.genersoft.iot.vmp.conf.UserSetting; 4 import com.genersoft.iot.vmp.conf.UserSetting;
4 import com.genersoft.iot.vmp.gb28181.bean.*; 5 import com.genersoft.iot.vmp.gb28181.bean.*;
5 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
@@ -8,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.respons @@ -8,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.respons
8 import com.genersoft.iot.vmp.gb28181.utils.Coordtransform; 9 import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
9 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; 10 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
10 import com.genersoft.iot.vmp.service.IDeviceChannelService; 11 import com.genersoft.iot.vmp.service.IDeviceChannelService;
  12 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
12 import com.genersoft.iot.vmp.utils.DateUtil; 14 import com.genersoft.iot.vmp.utils.DateUtil;
13 import com.genersoft.iot.vmp.utils.GpsUtil; 15 import com.genersoft.iot.vmp.utils.GpsUtil;
@@ -28,6 +30,10 @@ import java.text.ParseException; @@ -28,6 +30,10 @@ import java.text.ParseException;
28 30
29 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; 31 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
30 32
  33 +/**
  34 + * 移动设备位置数据查询回复
  35 + * @author lin
  36 + */
31 @Component 37 @Component
32 public class MobilePositionResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 38 public class MobilePositionResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
33 39
@@ -44,6 +50,9 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar @@ -44,6 +50,9 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
44 private IVideoManagerStorage storager; 50 private IVideoManagerStorage storager;
45 51
46 @Autowired 52 @Autowired
  53 + private IRedisCatchStorage redisCatchStorage;
  54 +
  55 + @Autowired
47 private IDeviceChannelService deviceChannelService; 56 private IDeviceChannelService deviceChannelService;
48 57
49 @Override 58 @Override
@@ -56,7 +65,11 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar @@ -56,7 +65,11 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
56 65
57 try { 66 try {
58 rootElement = getRootElement(evt, device.getCharset()); 67 rootElement = getRootElement(evt, device.getCharset());
59 - 68 + if (rootElement == null) {
  69 + logger.warn("[ 移动设备位置数据查询回复 ] content cannot be null");
  70 + responseAck(evt, Response.BAD_REQUEST);
  71 + return;
  72 + }
60 MobilePosition mobilePosition = new MobilePosition(); 73 MobilePosition mobilePosition = new MobilePosition();
61 mobilePosition.setCreateTime(DateUtil.getNow()); 74 mobilePosition.setCreateTime(DateUtil.getNow());
62 if (!StringUtils.isEmpty(device.getName())) { 75 if (!StringUtils.isEmpty(device.getName())) {
@@ -103,6 +116,18 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar @@ -103,6 +116,18 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar
103 storager.insertMobilePosition(mobilePosition); 116 storager.insertMobilePosition(mobilePosition);
104 } 117 }
105 storager.updateChannelPosition(deviceChannel); 118 storager.updateChannelPosition(deviceChannel);
  119 +
  120 + // 发送redis消息。 通知位置信息的变化
  121 + JSONObject jsonObject = new JSONObject();
  122 + jsonObject.put("time", mobilePosition.getTime());
  123 + jsonObject.put("serial", deviceChannel.getDeviceId());
  124 + jsonObject.put("code", deviceChannel.getChannelId());
  125 + jsonObject.put("longitude", mobilePosition.getLongitude());
  126 + jsonObject.put("latitude", mobilePosition.getLatitude());
  127 + jsonObject.put("altitude", mobilePosition.getAltitude());
  128 + jsonObject.put("direction", mobilePosition.getDirection());
  129 + jsonObject.put("speed", mobilePosition.getSpeed());
  130 + redisCatchStorage.sendMobilePositionMsg(jsonObject);
106 //回复 200 OK 131 //回复 200 OK
107 responseAck(evt, Response.OK); 132 responseAck(evt, Response.OK);
108 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { 133 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java
@@ -26,6 +26,9 @@ import java.util.List; @@ -26,6 +26,9 @@ import java.util.List;
26 26
27 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; 27 import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
28 28
  29 +/**
  30 + * 设备预置位查询应答
  31 + */
29 @Component 32 @Component
30 public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 33 public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
31 34
@@ -49,7 +52,11 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent @@ -49,7 +52,11 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
49 Element rootElement = null; 52 Element rootElement = null;
50 try { 53 try {
51 rootElement = getRootElement(evt, device.getCharset()); 54 rootElement = getRootElement(evt, device.getCharset());
52 - 55 + if (rootElement == null) {
  56 + logger.warn("[ 设备预置位查询应答 ] content cannot be null");
  57 + responseAck(evt, Response.BAD_REQUEST);
  58 + return;
  59 + }
53 Element presetListNumElement = rootElement.element("PresetList"); 60 Element presetListNumElement = rootElement.element("PresetList");
54 Element snElement = rootElement.element("SN"); 61 Element snElement = rootElement.element("SN");
55 //该字段可能为通道或则设备的id 62 //该字段可能为通道或则设备的id
@@ -61,11 +68,7 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent @@ -61,11 +68,7 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
61 } 68 }
62 int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num")); 69 int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
63 List<PresetQuerySipReq> presetQuerySipReqList = new ArrayList<>(); 70 List<PresetQuerySipReq> presetQuerySipReqList = new ArrayList<>();
64 - if (sumNum == 0) {  
65 - // 数据无预置位信息  
66 -  
67 -  
68 - }else { 71 + if (sumNum > 0) {
69 for (Iterator<Element> presetIterator = presetListNumElement.elementIterator();presetIterator.hasNext();){ 72 for (Iterator<Element> presetIterator = presetListNumElement.elementIterator();presetIterator.hasNext();){
70 Element itemListElement = presetIterator.next(); 73 Element itemListElement = presetIterator.next();
71 PresetQuerySipReq presetQuerySipReq = new PresetQuerySipReq(); 74 PresetQuerySipReq presetQuerySipReq = new PresetQuerySipReq();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
@@ -80,6 +80,10 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @@ -80,6 +80,10 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
80 try { 80 try {
81 HandlerCatchData take = taskQueue.poll(); 81 HandlerCatchData take = taskQueue.poll();
82 Element rootElementForCharset = getRootElement(take.getEvt(), take.getDevice().getCharset()); 82 Element rootElementForCharset = getRootElement(take.getEvt(), take.getDevice().getCharset());
  83 + if (rootElement == null) {
  84 + logger.warn("[ 国标录像 ] content cannot be null");
  85 + continue;
  86 + }
83 String sn = getText(rootElementForCharset, "SN"); 87 String sn = getText(rootElementForCharset, "SN");
84 String channelId = getText(rootElementForCharset, "DeviceID"); 88 String channelId = getText(rootElementForCharset, "DeviceID");
85 RecordInfo recordInfo = new RecordInfo(); 89 RecordInfo recordInfo = new RecordInfo();