648540858
2021-02-04 d3fa1dd2262fc311661aa675e4a30b2423c7b130
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -10,19 +10,15 @@
import javax.sip.message.Request;
import javax.sip.message.Response;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.UserSetup;
import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
@@ -32,17 +28,30 @@
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.utils.GpsUtil;
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import com.genersoft.iot.vmp.common.StreamInfo;
/**
 * @Description:MESSAGE请求处理器
 * @author: swwheihei
 * @date: 2020年5月3日 下午5:32:41
 */
public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
   private UserSetup userSetup = (UserSetup) SpringBeanFactory.getBean("userSetup");
   private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
@@ -70,9 +79,12 @@
   private static final String MESSAGE_RECORD_INFO = "RecordInfo";
   private static final String MESSAGE_MEDIA_STATUS = "MediaStatus";
   // private static final String MESSAGE_BROADCAST = "Broadcast";
   // private static final String MESSAGE_DEVICE_STATUS = "DeviceStatus";
   // private static final String MESSAGE_MOBILE_POSITION = "MobilePosition";
   private static final String MESSAGE_DEVICE_STATUS = "DeviceStatus";
   private static final String MESSAGE_DEVICE_CONTROL = "DeviceControl";
   private static final String MESSAGE_DEVICE_CONFIG = "DeviceConfig";
   private static final String MESSAGE_MOBILE_POSITION = "MobilePosition";
   // private static final String MESSAGE_MOBILE_POSITION_INTERVAL = "Interval";
   private static final String MESSAGE_PRESET_QUERY = "PresetQuery";
   /**
    * 处理MESSAGE请求
@@ -91,12 +103,22 @@
            processMessageKeepAlive(evt);
         } else if (MESSAGE_CONFIG_DOWNLOAD.equals(cmd)) {
            logger.info("接收到ConfigDownload消息");
            processMessageConfigDownload(evt);
         } else if (MESSAGE_CATALOG.equals(cmd)) {
            logger.info("接收到Catalog消息");
            processMessageCatalogList(evt);
         } else if (MESSAGE_DEVICE_INFO.equals(cmd)) {
            logger.info("接收到DeviceInfo消息");
            processMessageDeviceInfo(evt);
         } else if (MESSAGE_DEVICE_STATUS.equals(cmd)) {
            logger.info("接收到DeviceStatus消息");
            processMessageDeviceStatus(evt);
         } else if (MESSAGE_DEVICE_CONTROL.equals(cmd)) {
            logger.info("接收到DeviceControl消息");
            processMessageDeviceControl(evt);
         } else if (MESSAGE_DEVICE_CONFIG.equals(cmd)) {
            logger.info("接收到DeviceConfig消息");
            processMessageDeviceConfig(evt);
         } else if (MESSAGE_ALARM.equals(cmd)) {
            logger.info("接收到Alarm消息");
            processMessageAlarm(evt);
@@ -106,16 +128,239 @@
         }else if (MESSAGE_MEDIA_STATUS.equals(cmd)) {
            logger.info("接收到MediaStatus消息");
            processMessageMediaStatus(evt);
         } else if (MESSAGE_MOBILE_POSITION.equals(cmd)) {
            logger.info("接收到MobilePosition消息");
            processMessageMobilePosition(evt);
         } else if (MESSAGE_PRESET_QUERY.equals(cmd)) {
            logger.info("接收到PresetQuery消息");
            processMessagePresetQuery(evt);
         } else {
            logger.info("接收到消息:" + cmd);
            responseAck(evt);
         }
      } catch (DocumentException e) {
      } catch (DocumentException | SipException |InvalidArgumentException | ParseException e) {
         e.printStackTrace();
      }
   }
   /**
    * 收到deviceInfo设备信息请求 处理
    * 处理MobilePosition移动位置消息
    *
    * @param evt
    */
   private void processMessageMobilePosition(RequestEvent evt) {
      try {
         Element rootElement = getRootElement(evt);
         MobilePosition mobilePosition = new MobilePosition();
         Element deviceIdElement = rootElement.element("DeviceID");
         String deviceId = deviceIdElement.getTextTrim().toString();
         Device device = storager.queryVideoDevice(deviceId);
         if (device != null) {
            if (!StringUtils.isEmpty(device.getName())) {
               mobilePosition.setDeviceName(device.getName());
            }
         }
         mobilePosition.setDeviceId(XmlUtil.getText(rootElement, "DeviceID"));
         mobilePosition.setTime(XmlUtil.getText(rootElement, "Time"));
         mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
         mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
            if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) {
            mobilePosition.setSpeed(Double.parseDouble(XmlUtil.getText(rootElement, "Speed")));
         } else {
            mobilePosition.setSpeed(0.0);
         }
         if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Direction"))) {
            mobilePosition.setDirection(Double.parseDouble(XmlUtil.getText(rootElement, "Direction")));
         } else {
            mobilePosition.setDirection(0.0);
         }
         if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Altitude"))) {
            mobilePosition.setAltitude(Double.parseDouble(XmlUtil.getText(rootElement, "Altitude")));
         } else {
            mobilePosition.setAltitude(0.0);
         }
         mobilePosition.setReportSource("Mobile Position");
         BaiduPoint bp = new BaiduPoint();
         bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
         logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
         mobilePosition.setGeodeticSystem("BD-09");
         mobilePosition.setCnLng(bp.getBdLng());
         mobilePosition.setCnLat(bp.getBdLat());
         if (!userSetup.getSavePositionHistory()) {
            storager.clearMobilePositionsByDeviceId(deviceId);
         }
         storager.insertMobilePosition(mobilePosition);
         //回复 200 OK
         responseAck(evt);
      } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
         e.printStackTrace();
      }
   }
   /**
    * 处理DeviceStatus设备状态Message
    *
    * @param evt
    */
   private void processMessageDeviceStatus(RequestEvent evt) {
      try {
         Element rootElement = getRootElement(evt);
         String deviceId = XmlUtil.getText(rootElement, "DeviceID");
         // 检查设备是否存在, 不存在则不回复
         if (storager.exists(deviceId)) {
            // 回复200 OK
            responseAck(evt);
            JSONObject json = new JSONObject();
            XmlUtil.node2Json(rootElement, json);
            if (logger.isDebugEnabled()) {
               logger.debug(json.toJSONString());
            }
            RequestMessage msg = new RequestMessage();
            msg.setDeviceId(deviceId);
            msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS);
            msg.setData(json);
            deferredResultHolder.invokeResult(msg);
            if (offLineDetector.isOnline(deviceId)) {
               publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
            } else {
            }
         }
      } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
         e.printStackTrace();
      }
   }
   /**
    * 处理DeviceControl设备状态Message
    *
    * @param evt
    */
   private void processMessageDeviceControl(RequestEvent evt) {
      try {
         Element rootElement = getRootElement(evt);
         String deviceId = XmlUtil.getText(rootElement, "DeviceID");
         String result = XmlUtil.getText(rootElement, "Result");
         // 回复200 OK
         responseAck(evt);
         if (!XmlUtil.isEmpty(result)) {
            // 此处是对本平台发出DeviceControl指令的应答
            JSONObject json = new JSONObject();
            XmlUtil.node2Json(rootElement, json);
            if (logger.isDebugEnabled()) {
               logger.debug(json.toJSONString());
            }
            RequestMessage msg = new RequestMessage();
            msg.setDeviceId(deviceId);
            msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL);
            msg.setData(json);
            deferredResultHolder.invokeResult(msg);
         } else {
            // 此处是上级发出的DeviceControl指令
         }
      } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
         e.printStackTrace();
      }
   }
   /**
    * 处理DeviceConfig设备状态Message
    *
    * @param evt
    */
   private void processMessageDeviceConfig(RequestEvent evt) {
      try {
         Element rootElement = getRootElement(evt);
         String deviceId = XmlUtil.getText(rootElement, "DeviceID");
         String result = XmlUtil.getText(rootElement, "Result");
         // 回复200 OK
         responseAck(evt);
         //if (!XmlUtil.isEmpty(result)) {
            // 此处是对本平台发出DeviceControl指令的应答
            JSONObject json = new JSONObject();
            XmlUtil.node2Json(rootElement, json);
            if (logger.isDebugEnabled()) {
               logger.debug(json.toJSONString());
            }
            RequestMessage msg = new RequestMessage();
            msg.setDeviceId(deviceId);
            msg.setType(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG);
            msg.setData(json);
            deferredResultHolder.invokeResult(msg);
         // } else {
         //    // 此处是上级发出的DeviceConfig指令
         //}
      } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
         e.printStackTrace();
      }
   }
   /**
    * 处理ConfigDownload设备状态Message
    *
    * @param evt
    */
   private void processMessageConfigDownload(RequestEvent evt) {
      try {
         Element rootElement = getRootElement(evt);
         String deviceId = XmlUtil.getText(rootElement, "DeviceID");
         String result = XmlUtil.getText(rootElement, "Result");
         // 回复200 OK
         responseAck(evt);
         //if (!XmlUtil.isEmpty(result)) {
            // 此处是对本平台发出DeviceControl指令的应答
            JSONObject json = new JSONObject();
            XmlUtil.node2Json(rootElement, json);
            if (logger.isDebugEnabled()) {
               logger.debug(json.toJSONString());
            }
            RequestMessage msg = new RequestMessage();
            msg.setDeviceId(deviceId);
            msg.setType(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD);
            msg.setData(json);
            deferredResultHolder.invokeResult(msg);
         // } else {
         //    // 此处是上级发出的DeviceConfig指令
         //}
      } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
         e.printStackTrace();
      }
   }
   /**
    * 处理PresetQuery预置位列表Message
    *
    * @param evt
    */
   private void processMessagePresetQuery(RequestEvent evt) {
      try {
         Element rootElement = getRootElement(evt);
         String deviceId = XmlUtil.getText(rootElement, "DeviceID");
         String result = XmlUtil.getText(rootElement, "Result");
         // 回复200 OK
         responseAck(evt);
         if (rootElement.getName().equals("Response")) {//   !XmlUtil.isEmpty(result)) {
            // 此处是对本平台发出DeviceControl指令的应答
            JSONObject json = new JSONObject();
            XmlUtil.node2Json(rootElement, json);
            if (logger.isDebugEnabled()) {
               logger.debug(json.toJSONString());
            }
            RequestMessage msg = new RequestMessage();
            msg.setDeviceId(deviceId);
            msg.setType(DeferredResultHolder.CALLBACK_CMD_PRESETQUERY);
            msg.setData(json);
            deferredResultHolder.invokeResult(msg);
         } else {
            // 此处是上级发出的DeviceControl指令
         }
      } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
         e.printStackTrace();
      }
   }
   /**
    * 处理DeviceInfo设备信息Message
    * 
    * @param evt
    */
@@ -123,7 +368,7 @@
      try {
         Element rootElement = getRootElement(evt);
         Element deviceIdElement = rootElement.element("DeviceID");
         String deviceId = deviceIdElement.getText().toString();
         String deviceId = deviceIdElement.getTextTrim().toString();
         Device device = storager.queryVideoDevice(deviceId);
         if (device == null) {
@@ -180,11 +425,11 @@
               if (channelDeviceElement == null) {
                  continue;
               }
               String channelDeviceId = channelDeviceElement.getText();
               String channelDeviceId = channelDeviceElement.getTextTrim();
               Element channdelNameElement = itemDevice.element("Name");
               String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
               Element statusElement = itemDevice.element("Status");
               String status = statusElement != null ? statusElement.getText().toString() : "ON";
               String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON";
               DeviceChannel deviceChannel = new DeviceChannel();
               deviceChannel.setName(channelName);
               deviceChannel.setChannelId(channelDeviceId);
@@ -238,15 +483,15 @@
                  deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
               }
               deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
               if (XmlUtil.getText(itemDevice, "Longitude") == null || XmlUtil.getText(itemDevice, "Longitude") == "") {
                  deviceChannel.setLongitude(0.00);
               } else {
               if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) {
                  deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
               }
               if (XmlUtil.getText(itemDevice, "Latitude") == null || XmlUtil.getText(itemDevice, "Latitude") =="") {
                  deviceChannel.setLatitude(0.00);
               } else {
                  deviceChannel.setLongitude(0.00);
               }
               if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) {
                  deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
               } else {
                  deviceChannel.setLatitude(0.00);
               }
               if (XmlUtil.getText(itemDevice, "PTZType") == null || XmlUtil.getText(itemDevice, "PTZType") == "") {
                  deviceChannel.setPTZType(0);
@@ -274,8 +519,7 @@
   }
   /***
    * 收到alarm设备报警信息 处理
    *
    * alarm设备报警信息处理
    * @param evt
    */
   private void processMessageAlarm(RequestEvent evt) {
@@ -283,48 +527,72 @@
         Element rootElement = getRootElement(evt);
         Element deviceIdElement = rootElement.element("DeviceID");
         String deviceId = deviceIdElement.getText().toString();
         // 回复200 OK
         responseAck(evt);
         Device device = storager.queryVideoDevice(deviceId);
         if (device == null) {
            // TODO 也可能是通道
            // storager.queryChannel(deviceId)
            return;
         }
         DeviceAlarm deviceAlarm = new DeviceAlarm();
         deviceAlarm.setDeviceId(deviceId);
         deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
         deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
         deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
         if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
            deviceAlarm.setAlarmDescription("");
         } else {
            deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
         }
         if (XmlUtil.getText(rootElement, "Longitude") == null || XmlUtil.getText(rootElement, "Longitude") == "") {
            deviceAlarm.setLongitude(0.00);
         } else {
            deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
         }
         if (XmlUtil.getText(rootElement, "Latitude") == null || XmlUtil.getText(rootElement, "Latitude") =="") {
            deviceAlarm.setLatitude(0.00);
         } else {
            deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
         }
         // device.setName(XmlUtil.getText(rootElement, "DeviceName"));
         // device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer"));
         // device.setModel(XmlUtil.getText(rootElement, "Model"));
         // device.setFirmware(XmlUtil.getText(rootElement, "Firmware"));
         // if (StringUtils.isEmpty(device.getStreamMode())) {
         //    device.setStreamMode("UDP");
         // }
         // storager.updateDevice(device);
         //cmder.catalogQuery(device, null);
         // 回复200 OK
         responseAck(evt);
         if (offLineDetector.isOnline(deviceId)) {
            publisher.deviceAlarmEventPublish(deviceAlarm);
         if (rootElement.getName().equals("Notify")) {   // 处理报警通知
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setDeviceId(deviceId);
            deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
            deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
            deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
            if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
               deviceAlarm.setAlarmDescription("");
            } else {
               deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
            }
            if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) {
               deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
            } else {
               deviceAlarm.setLongitude(0.00);
            }
            if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) {
               deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
            } else {
               deviceAlarm.setLatitude(0.00);
            }
            if (!XmlUtil.isEmpty(deviceAlarm.getAlarmMethod())) {
               if ( deviceAlarm.getAlarmMethod().equals("4")) {
                  MobilePosition mobilePosition = new MobilePosition();
                  mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
                  mobilePosition.setTime(deviceAlarm.getAlarmTime());
                  mobilePosition.setLongitude(deviceAlarm.getLongitude());
                  mobilePosition.setLatitude(deviceAlarm.getLatitude());
                  mobilePosition.setReportSource("GPS Alarm");
                  BaiduPoint bp = new BaiduPoint();
                  bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
                  logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
                  mobilePosition.setGeodeticSystem("BD-09");
                  mobilePosition.setCnLng(bp.getBdLng());
                  mobilePosition.setCnLat(bp.getBdLat());
                  if (!userSetup.getSavePositionHistory()) {
                     storager.clearMobilePositionsByDeviceId(deviceId);
                  }
                  storager.insertMobilePosition(mobilePosition);
               }
            }
            // TODO: 需要实现存储报警信息、报警分类
            if (offLineDetector.isOnline(deviceId)) {
               publisher.deviceAlarmEventPublish(deviceAlarm);
            }
         } else if (rootElement.getName().equals("Response")) {   // 处理报警查询响应
            JSONObject json = new JSONObject();
            XmlUtil.node2Json(rootElement, json);
            if (logger.isDebugEnabled()) {
               logger.debug(json.toJSONString());
            }
            RequestMessage msg = new RequestMessage();
            msg.setDeviceId(deviceId);
            msg.setType(DeferredResultHolder.CALLBACK_CMD_ALARM);
            msg.setData(json);
            deferredResultHolder.invokeResult(msg);
         }
      } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
         // } catch (DocumentException e) {
@@ -350,14 +618,13 @@
            } else {
            }
         }
      } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
         e.printStackTrace();
      }
   }
   /***
    * 收到catalog设备目录列表请求 处理 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致
    * 处理RecordInfo设备录像列表Message请求 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致
    * 
    * @param evt
    */
@@ -444,12 +711,9 @@
         // 2、有录像数据,且第一次即收到完整数据,返回响应数据,无redis操作
         // 3、有录像数据,在超时时间内收到多次包组装后数量足够,返回数据
         // 对记录进行排序
         RequestMessage msg = new RequestMessage();
         msg.setDeviceId(deviceId);
         msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
         // // 自然顺序排序, 元素进行升序排列
         // recordInfo.getRecordList().sort(Comparator.naturalOrder());
         msg.setData(recordInfo);
         deferredResultHolder.invokeResult(msg);
         logger.info("处理完成,返回结果");
@@ -458,7 +722,11 @@
      }
   }
   /**
    * 收到MediaStatus消息处理
     *
     * @param evt
     */
   private void processMessageMediaStatus(RequestEvent evt){
      try {
         // 回复200 OK