Commit 5d541e4ae6a5c635289d437366b20c9b2aefe741

Authored by Lawrence
1 parent dd3b8c25

增加对Notify方法的支持

src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -26,6 +26,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.impl.ByeRequestProcessor; @@ -26,6 +26,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.impl.ByeRequestProcessor;
26 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.CancelRequestProcessor; 26 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.CancelRequestProcessor;
27 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.InviteRequestProcessor; 27 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.InviteRequestProcessor;
28 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor; 28 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor;
  29 +import com.genersoft.iot.vmp.gb28181.transmit.request.impl.NotifyRequestProcessor;
29 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor; 30 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor;
30 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; 31 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor;
31 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor; 32 import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor;
@@ -144,6 +145,19 @@ public class SIPProcessorFactory { @@ -144,6 +145,19 @@ public class SIPProcessorFactory {
144 processor.setStorager(storager); 145 processor.setStorager(storager);
145 processor.setRedisCatchStorage(redisCatchStorage); 146 processor.setRedisCatchStorage(redisCatchStorage);
146 return processor; 147 return processor;
  148 + } else if (Request.NOTIFY.equalsIgnoreCase(method)) {
  149 + NotifyRequestProcessor processor = new NotifyRequestProcessor();
  150 + processor.setRequestEvent(evt);
  151 + processor.setTcpSipProvider(getTcpSipProvider());
  152 + processor.setUdpSipProvider(getUdpSipProvider());
  153 + processor.setPublisher(publisher);
  154 + processor.setRedis(redis);
  155 + processor.setDeferredResultHolder(deferredResultHolder);
  156 + processor.setOffLineDetector(offLineDetector);
  157 + processor.setCmder(cmder);
  158 + processor.setStorager(storager);
  159 + processor.setRedisCatchStorage(redisCatchStorage);
  160 + return processor;
147 } else { 161 } else {
148 OtherRequestProcessor processor = new OtherRequestProcessor(); 162 OtherRequestProcessor processor = new OtherRequestProcessor();
149 processor.setRequestEvent(evt); 163 processor.setRequestEvent(evt);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/NotifyRequestProcessor.java 0 → 100644
  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.SipException;
  10 +import javax.sip.message.Request;
  11 +import javax.sip.message.Response;
  12 +
  13 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  14 +import com.genersoft.iot.vmp.conf.UserSetup;
  15 +import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint;
  16 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  17 +import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
  18 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  19 +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
  20 +import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
  21 +import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
  22 +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
  23 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  24 +import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
  25 +import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
  26 +import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
  27 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  28 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  29 +import com.genersoft.iot.vmp.utils.GpsUtil;
  30 +import com.genersoft.iot.vmp.utils.SpringBeanFactory;
  31 +import com.genersoft.iot.vmp.utils.redis.RedisUtil;
  32 +
  33 +import org.dom4j.Document;
  34 +import org.dom4j.DocumentException;
  35 +import org.dom4j.Element;
  36 +import org.dom4j.io.SAXReader;
  37 +import org.slf4j.Logger;
  38 +import org.slf4j.LoggerFactory;
  39 +import org.springframework.util.StringUtils;
  40 +
  41 +/**
  42 + * @Description: Notify请求处理器
  43 + * @author: lawrencehj
  44 + * @date: 2021年1月27日
  45 + */
  46 +
  47 +public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
  48 +
  49 + private UserSetup userSetup = (UserSetup) SpringBeanFactory.getBean("userSetup");
  50 +
  51 + private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
  52 +
  53 + private SIPCommander cmder;
  54 +
  55 + private IVideoManagerStorager storager;
  56 +
  57 + private IRedisCatchStorage redisCatchStorage;
  58 +
  59 + private EventPublisher publisher;
  60 +
  61 + private RedisUtil redis;
  62 +
  63 + private DeferredResultHolder deferredResultHolder;
  64 +
  65 + private DeviceOffLineDetector offLineDetector;
  66 +
  67 + private static final String NOTIFY_CATALOG = "Catalog";
  68 + private static final String NOTIFY_ALARM = "Alarm";
  69 + private static final String NOTIFY_MOBILE_POSITION = "MobilePosition";
  70 +
  71 + @Override
  72 + public void process(RequestEvent evt) {
  73 + try {
  74 + Element rootElement = getRootElement(evt);
  75 + String cmd = XmlUtil.getText(rootElement, "CmdType");
  76 +
  77 + if (NOTIFY_CATALOG.equals(cmd)) {
  78 + logger.info("接收到Catalog通知");
  79 + processNotifyCatalogList(evt);
  80 + } else if (NOTIFY_ALARM.equals(cmd)) {
  81 + logger.info("接收到Alarm通知");
  82 + processNotifyAlarm(evt);
  83 + } else if (NOTIFY_MOBILE_POSITION.equals(cmd)) {
  84 + logger.info("接收到MobilePosition通知");
  85 + processNotifyMobilePosition(evt);
  86 + } else {
  87 + logger.info("接收到消息:" + cmd);
  88 + response200Ok(evt);
  89 + }
  90 + } catch (DocumentException | SipException |InvalidArgumentException | ParseException e) {
  91 + e.printStackTrace();
  92 + }
  93 + }
  94 +
  95 + /**
  96 + * 处理MobilePosition移动位置Notify
  97 + * @param evt
  98 + */
  99 + private void processNotifyMobilePosition(RequestEvent evt) {
  100 + try {
  101 + //回复 200 OK
  102 + Element rootElement = getRootElement(evt);
  103 + MobilePosition mobilePosition = new MobilePosition();
  104 + Element deviceIdElement = rootElement.element("DeviceID");
  105 + String deviceId = deviceIdElement.getTextTrim().toString();
  106 + Device device = storager.queryVideoDevice(deviceId);
  107 + if (device != null) {
  108 + if (!StringUtils.isEmpty(device.getName())) {
  109 + mobilePosition.setDeviceName(device.getName());
  110 + }
  111 + }
  112 + mobilePosition.setDeviceId(XmlUtil.getText(rootElement, "DeviceID"));
  113 + mobilePosition.setTime(XmlUtil.getText(rootElement, "Time"));
  114 + mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
  115 + mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
  116 + if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) {
  117 + mobilePosition.setSpeed(Double.parseDouble(XmlUtil.getText(rootElement, "Speed")));
  118 + } else {
  119 + mobilePosition.setSpeed(0.0);
  120 + }
  121 + if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Direction"))) {
  122 + mobilePosition.setDirection(Double.parseDouble(XmlUtil.getText(rootElement, "Direction")));
  123 + } else {
  124 + mobilePosition.setDirection(0.0);
  125 + }
  126 + if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Altitude"))) {
  127 + mobilePosition.setAltitude(Double.parseDouble(XmlUtil.getText(rootElement, "Altitude")));
  128 + } else {
  129 + mobilePosition.setAltitude(0.0);
  130 + }
  131 + mobilePosition.setReportSource("Mobile Position");
  132 + BaiduPoint bp = new BaiduPoint();
  133 + bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
  134 + logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
  135 + mobilePosition.setGeodeticSystem("BD-09");
  136 + mobilePosition.setCnLng(bp.getBdLng());
  137 + mobilePosition.setCnLat(bp.getBdLat());
  138 + if (!userSetup.getSavePositionHistory()) {
  139 + storager.clearMobilePositionsByDeviceId(deviceId);
  140 + }
  141 + storager.insertMobilePosition(mobilePosition);
  142 + response200Ok(evt);
  143 + } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
  144 + e.printStackTrace();
  145 + }
  146 + }
  147 +
  148 + /***
  149 + * 处理alarm设备报警Notify
  150 + * @param evt
  151 + */
  152 + private void processNotifyAlarm(RequestEvent evt) {
  153 + try {
  154 + Element rootElement = getRootElement(evt);
  155 + Element deviceIdElement = rootElement.element("DeviceID");
  156 + String deviceId = deviceIdElement.getText().toString();
  157 +
  158 + Device device = storager.queryVideoDevice(deviceId);
  159 + if (device == null) {
  160 + return;
  161 + }
  162 + DeviceAlarm deviceAlarm = new DeviceAlarm();
  163 + deviceAlarm.setDeviceId(deviceId);
  164 + deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
  165 + deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
  166 + deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
  167 + if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
  168 + deviceAlarm.setAlarmDescription("");
  169 + } else {
  170 + deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
  171 + }
  172 + if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) {
  173 + deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
  174 + } else {
  175 + deviceAlarm.setLongitude(0.00);
  176 + }
  177 + if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) {
  178 + deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
  179 + } else {
  180 + deviceAlarm.setLatitude(0.00);
  181 + }
  182 +
  183 + if ( deviceAlarm.getAlarmMethod().equals("4")) {
  184 + MobilePosition mobilePosition = new MobilePosition();
  185 + mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
  186 + mobilePosition.setTime(deviceAlarm.getAlarmTime());
  187 + mobilePosition.setLongitude(deviceAlarm.getLongitude());
  188 + mobilePosition.setLatitude(deviceAlarm.getLatitude());
  189 + mobilePosition.setReportSource("GPS Alarm");
  190 + BaiduPoint bp = new BaiduPoint();
  191 + bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
  192 + logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
  193 + mobilePosition.setGeodeticSystem("BD-09");
  194 + mobilePosition.setCnLng(bp.getBdLng());
  195 + mobilePosition.setCnLat(bp.getBdLat());
  196 + if (!userSetup.getSavePositionHistory()) {
  197 + storager.clearMobilePositionsByDeviceId(deviceId);
  198 + }
  199 + storager.insertMobilePosition(mobilePosition);
  200 + }
  201 + // TODO: 需要实现存储报警信息、报警分类
  202 +
  203 + // 回复200 OK
  204 + response200Ok(evt);
  205 + if (offLineDetector.isOnline(deviceId)) {
  206 + publisher.deviceAlarmEventPublish(deviceAlarm);
  207 + }
  208 + } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
  209 + e.printStackTrace();
  210 + }
  211 + }
  212 +
  213 + /***
  214 + * 处理catalog设备目录列表Notify
  215 + *
  216 + * @param evt
  217 + */
  218 + private void processNotifyCatalogList(RequestEvent evt) {
  219 + try {
  220 + Element rootElement = getRootElement(evt);
  221 + Element deviceIdElement = rootElement.element("DeviceID");
  222 + String deviceId = deviceIdElement.getText();
  223 + Element deviceListElement = rootElement.element("DeviceList");
  224 + if (deviceListElement == null) {
  225 + return;
  226 + }
  227 + Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
  228 + if (deviceListIterator != null) {
  229 + Device device = storager.queryVideoDevice(deviceId);
  230 + if (device == null) {
  231 + return;
  232 + }
  233 + // 遍历DeviceList
  234 + while (deviceListIterator.hasNext()) {
  235 + Element itemDevice = deviceListIterator.next();
  236 + Element channelDeviceElement = itemDevice.element("DeviceID");
  237 + if (channelDeviceElement == null) {
  238 + continue;
  239 + }
  240 + String channelDeviceId = channelDeviceElement.getTextTrim();
  241 + Element channdelNameElement = itemDevice.element("Name");
  242 + String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
  243 + Element statusElement = itemDevice.element("Status");
  244 + String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON";
  245 + DeviceChannel deviceChannel = new DeviceChannel();
  246 + deviceChannel.setName(channelName);
  247 + deviceChannel.setChannelId(channelDeviceId);
  248 + // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
  249 + if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) {
  250 + deviceChannel.setStatus(1);
  251 + }
  252 + if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
  253 + deviceChannel.setStatus(0);
  254 + }
  255 +
  256 + deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
  257 + deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
  258 + deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
  259 + deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
  260 + deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
  261 + deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
  262 + if (XmlUtil.getText(itemDevice, "Parental") == null || XmlUtil.getText(itemDevice, "Parental") == "") {
  263 + deviceChannel.setParental(0);
  264 + } else {
  265 + deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));
  266 + }
  267 + deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));
  268 + if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay")== "") {
  269 + deviceChannel.setSafetyWay(0);
  270 + } else {
  271 + deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
  272 + }
  273 + if (XmlUtil.getText(itemDevice, "RegisterWay") == null || XmlUtil.getText(itemDevice, "RegisterWay") =="") {
  274 + deviceChannel.setRegisterWay(1);
  275 + } else {
  276 + deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
  277 + }
  278 + deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
  279 + if (XmlUtil.getText(itemDevice, "Certifiable") == null || XmlUtil.getText(itemDevice, "Certifiable") == "") {
  280 + deviceChannel.setCertifiable(0);
  281 + } else {
  282 + deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
  283 + }
  284 + if (XmlUtil.getText(itemDevice, "ErrCode") == null || XmlUtil.getText(itemDevice, "ErrCode") == "") {
  285 + deviceChannel.setErrCode(0);
  286 + } else {
  287 + deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
  288 + }
  289 + deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
  290 + deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
  291 + deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
  292 + if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") =="") {
  293 + deviceChannel.setPort(0);
  294 + } else {
  295 + deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
  296 + }
  297 + deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
  298 + if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) {
  299 + deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
  300 + } else {
  301 + deviceChannel.setLongitude(0.00);
  302 + }
  303 + if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) {
  304 + deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
  305 + } else {
  306 + deviceChannel.setLatitude(0.00);
  307 + }
  308 + if (XmlUtil.getText(itemDevice, "PTZType") == null || XmlUtil.getText(itemDevice, "PTZType") == "") {
  309 + deviceChannel.setPTZType(0);
  310 + } else {
  311 + deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
  312 + }
  313 + deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
  314 + storager.updateChannel(device.getDeviceId(), deviceChannel);
  315 + }
  316 +
  317 + // RequestMessage msg = new RequestMessage();
  318 + // msg.setDeviceId(deviceId);
  319 + // msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
  320 + // msg.setData(device);
  321 + // deferredResultHolder.invokeResult(msg);
  322 + // 回复200 OK
  323 + response200Ok(evt);
  324 + if (offLineDetector.isOnline(deviceId)) {
  325 + publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
  326 + }
  327 + }
  328 + } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
  329 + e.printStackTrace();
  330 + }
  331 + }
  332 +
  333 +
  334 + /***
  335 + * 回复200 OK
  336 + * @param evt
  337 + * @throws SipException
  338 + * @throws InvalidArgumentException
  339 + * @throws ParseException
  340 + */
  341 + private void response200Ok(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
  342 + Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
  343 + getServerTransaction(evt).sendResponse(response);
  344 + }
  345 +
  346 + private Element getRootElement(RequestEvent evt) throws DocumentException {
  347 + Request request = evt.getRequest();
  348 + SAXReader reader = new SAXReader();
  349 + reader.setEncoding("gbk");
  350 + Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
  351 + return xml.getRootElement();
  352 + }
  353 +
  354 + public void setCmder(SIPCommander cmder) {
  355 + this.cmder = cmder;
  356 + }
  357 +
  358 + public void setStorager(IVideoManagerStorager storager) {
  359 + this.storager = storager;
  360 + }
  361 +
  362 + public void setPublisher(EventPublisher publisher) {
  363 + this.publisher = publisher;
  364 + }
  365 +
  366 + public void setRedis(RedisUtil redis) {
  367 + this.redis = redis;
  368 + }
  369 +
  370 + public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) {
  371 + this.deferredResultHolder = deferredResultHolder;
  372 + }
  373 +
  374 + public void setOffLineDetector(DeviceOffLineDetector offLineDetector) {
  375 + this.offLineDetector = offLineDetector;
  376 + }
  377 +
  378 + public IRedisCatchStorage getRedisCatchStorage() {
  379 + return redisCatchStorage;
  380 + }
  381 +
  382 + public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
  383 + this.redisCatchStorage = redisCatchStorage;
  384 + }
  385 +}