|  |  | 
 |  |  | 
 | 
 |  |  | import javax.sip.InvalidArgumentException;
 | 
 |  |  | import javax.sip.RequestEvent;
 | 
 |  |  | import javax.sip.ServerTransaction;
 | 
 |  |  | import javax.sip.SipException;
 | 
 |  |  | import javax.sip.message.Request;
 | 
 |  |  | import javax.sip.message.Response;
 | 
 |  |  | 
 |  |  | import org.slf4j.Logger;
 | 
 |  |  | import org.slf4j.LoggerFactory;
 | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired;
 | 
 |  |  | import org.springframework.stereotype.Component;
 | 
 |  |  | 
 | 
 |  |  | import com.genersoft.iot.vmp.common.VideoManagerConstants;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.SipLayer;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.bean.Device;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
 | 
 |  |  | 
 |  |  | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
 | 
 |  |  | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
 | 
 |  |  | import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 | 
 |  |  | import com.genersoft.iot.vmp.utils.redis.RedisUtil;
 | 
 |  |  | import org.springframework.util.StringUtils;
 | 
 |  |  | 
 | 
 |  |  | /**    
 | 
 |  |  |  * @Description:MESSAGE请求处理器
 | 
 |  |  |  * @author: songww
 | 
 |  |  |  * @author: swwheihei
 | 
 |  |  |  * @date:   2020年5月3日 下午5:32:41     
 | 
 |  |  |  */
 | 
 |  |  | @Component
 | 
 |  |  | public class MessageRequestProcessor implements ISIPRequestProcessor {
 | 
 |  |  | public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 | 
 |  |  |    
 | 
 |  |  |    private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
 | 
 |  |  |    
 | 
 |  |  |    private ServerTransaction transaction;
 | 
 |  |  | 	 | 
 |  |  |    private SipLayer layer;
 | 
 |  |  | 	 | 
 |  |  |    @Autowired
 | 
 |  |  |    private SIPCommander cmder;
 | 
 |  |  |    
 | 
 |  |  |    @Autowired
 | 
 |  |  |    private IVideoManagerStorager storager;
 | 
 |  |  |    
 | 
 |  |  |    @Autowired
 | 
 |  |  |    private EventPublisher publisher;
 | 
 |  |  |    
 | 
 |  |  |    @Autowired
 | 
 |  |  |    private RedisUtil redis;
 | 
 |  |  |    
 | 
 |  |  |    @Autowired
 | 
 |  |  |    private DeferredResultHolder deferredResultHolder;
 | 
 |  |  |    
 | 
 |  |  |    @Autowired
 | 
 |  |  |    private DeviceOffLineDetector offLineDetector;
 | 
 |  |  |    
 | 
 |  |  |    private final static String CACHE_RECORDINFO_KEY = "CACHE_RECORDINFO_";
 | 
 |  |  |    
 | 
 |  |  |    private static final String MESSAGE_KEEP_ALIVE = "Keepalive";
 | 
 |  |  |    private static final String MESSAGE_CONFIG_DOWNLOAD = "ConfigDownload";
 | 
 |  |  |    private static final String MESSAGE_CATALOG = "Catalog";
 | 
 |  |  |    private static final String MESSAGE_DEVICE_INFO = "DeviceInfo";
 | 
 |  |  |    private static final String MESSAGE_KEEP_ALIVE = "Keepalive";
 | 
 |  |  |    private static final String MESSAGE_ALARM = "Alarm";
 | 
 |  |  |    private static final String MESSAGE_RECORD_INFO = "RecordInfo";
 | 
 |  |  | //   private static final String MESSAGE_BROADCAST = "Broadcast";
 | 
 |  |  | 
 |  |  |     * 处理MESSAGE请求
 | 
 |  |  |     *  
 | 
 |  |  |     * @param evt
 | 
 |  |  |     * @param layer
 | 
 |  |  |     * @param transaction   | 
 |  |  |     */  
 | 
 |  |  |    @Override
 | 
 |  |  |    public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
 | 
 |  |  | 		 | 
 |  |  |       this.layer = layer;
 | 
 |  |  |       this.transaction = transaction;
 | 
 |  |  | 		 | 
 |  |  |       Request request = evt.getRequest();
 | 
 |  |  |       SAXReader reader = new SAXReader();
 | 
 |  |  |       Document xml;
 | 
 |  |  |    public void process(RequestEvent evt) {
 | 
 |  |  | 
 | 
 |  |  |       try {
 | 
 |  |  |          xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
 | 
 |  |  |          Element rootElement = xml.getRootElement();
 | 
 |  |  |          String cmd = rootElement.element("CmdType").getStringValue();
 | 
 |  |  | 			 | 
 |  |  |          Element rootElement = getRootElement(evt);
 | 
 |  |  |          String cmd = XmlUtil.getText(rootElement,"CmdType");
 | 
 |  |  | 
 | 
 |  |  |          if (MESSAGE_KEEP_ALIVE.equals(cmd)) {
 | 
 |  |  |             logger.info("接收到KeepAlive消息");
 | 
 |  |  |             processMessageKeepAlive(evt);
 | 
 |  |  |          } else if (MESSAGE_CONFIG_DOWNLOAD.equals(cmd)) {
 | 
 |  |  |             logger.info("接收到ConfigDownload消息");
 | 
 |  |  |          } else if (MESSAGE_CATALOG.equals(cmd)) {
 | 
 |  |  |             logger.info("接收到Catalog消息");
 | 
 |  |  |             processMessageCatalogList(evt);
 | 
 |  |  | 
 |  |  |       } catch (DocumentException e) {
 | 
 |  |  |          e.printStackTrace();
 | 
 |  |  |       }
 | 
 |  |  | 		 | 
 |  |  |    }
 | 
 |  |  |    
 | 
 |  |  |    /**
 | 
 |  |  | 
 |  |  |          device.setManufacturer(XmlUtil.getText(rootElement,"Manufacturer"));
 | 
 |  |  |          device.setModel(XmlUtil.getText(rootElement,"Model"));
 | 
 |  |  |          device.setFirmware(XmlUtil.getText(rootElement,"Firmware"));
 | 
 |  |  |          storager.update(device);
 | 
 |  |  |          if (StringUtils.isEmpty(device.getStreamMode())){
 | 
 |  |  |             device.setStreamMode("UDP");
 | 
 |  |  |          }
 | 
 |  |  |          storager.updateDevice(device);
 | 
 |  |  |          
 | 
 |  |  |          RequestMessage msg = new RequestMessage();
 | 
 |  |  |          msg.setDeviceId(deviceId);
 | 
 |  |  | 
 |  |  |       try {
 | 
 |  |  |          Element rootElement = getRootElement(evt);
 | 
 |  |  |          Element deviceIdElement = rootElement.element("DeviceID");
 | 
 |  |  |          String deviceId = deviceIdElement.getText().toString();
 | 
 |  |  |          String deviceId = deviceIdElement.getText();
 | 
 |  |  |          Element deviceListElement = rootElement.element("DeviceList");
 | 
 |  |  |          if (deviceListElement == null) {
 | 
 |  |  |             return;
 | 
 |  |  | 
 |  |  |             if (device == null) {
 | 
 |  |  |                return;
 | 
 |  |  |             }
 | 
 |  |  |             Map<String, DeviceChannel> channelMap = device.getChannelMap();
 | 
 |  |  |             if (channelMap == null) {
 | 
 |  |  |                channelMap = new HashMap<String, DeviceChannel>(5);
 | 
 |  |  |                device.setChannelMap(channelMap);
 | 
 |  |  |             }
 | 
 |  |  |             // 遍历DeviceList
 | 
 |  |  |             while (deviceListIterator.hasNext()) {
 | 
 |  |  |                Element itemDevice = deviceListIterator.next();
 | 
 |  |  | 
 |  |  |                if (channelDeviceElement == null) {
 | 
 |  |  |                   continue;
 | 
 |  |  |                }
 | 
 |  |  |                String channelDeviceId = channelDeviceElement.getText().toString();
 | 
 |  |  |                String channelDeviceId = channelDeviceElement.getText();
 | 
 |  |  |                Element channdelNameElement = itemDevice.element("Name");
 | 
 |  |  |                String channelName = channdelNameElement != null ? channdelNameElement.getText().toString() : "";
 | 
 |  |  |                String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
 | 
 |  |  |                Element statusElement = itemDevice.element("Status");
 | 
 |  |  |                String status = statusElement != null ? statusElement.getText().toString() : "ON";
 | 
 |  |  |                DeviceChannel deviceChannel = channelMap.containsKey(channelDeviceId) ? channelMap.get(channelDeviceId) : new DeviceChannel();
 | 
 |  |  |                DeviceChannel deviceChannel = new DeviceChannel();
 | 
 |  |  |                deviceChannel.setName(channelName);
 | 
 |  |  |                deviceChannel.setChannelId(channelDeviceId);
 | 
 |  |  |                if(status.equals("ON")) {
 | 
 |  |  |                if(status.equals("ON") || status.equals("On")) {
 | 
 |  |  |                   deviceChannel.setStatus(1);
 | 
 |  |  |                }
 | 
 |  |  |                if(status.equals("OFF")) {
 | 
 |  |  |                if(status.equals("OFF") || status.equals("Off")) {
 | 
 |  |  |                   deviceChannel.setStatus(0);
 | 
 |  |  |                }
 | 
 |  |  | 
 | 
 |  |  | 
 |  |  |                deviceChannel.setBlock(XmlUtil.getText(itemDevice,"Block"));
 | 
 |  |  |                deviceChannel.setAddress(XmlUtil.getText(itemDevice,"Address"));
 | 
 |  |  |                deviceChannel.setParental(itemDevice.element("Parental") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"Parental")));
 | 
 |  |  |                deviceChannel.setParentId(XmlUtil.getText(itemDevice,"ParentId"));
 | 
 |  |  |                deviceChannel.setParentId(XmlUtil.getText(itemDevice,"ParentID"));
 | 
 |  |  |                deviceChannel.setSafetyWay(itemDevice.element("SafetyWay") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"SafetyWay")));
 | 
 |  |  |                deviceChannel.setRegisterWay(itemDevice.element("RegisterWay") == null? 1:Integer.parseInt(XmlUtil.getText(itemDevice,"RegisterWay")));
 | 
 |  |  |                deviceChannel.setCertNum(XmlUtil.getText(itemDevice,"CertNum"));
 | 
 |  |  | 
 |  |  |                deviceChannel.setPassword(XmlUtil.getText(itemDevice,"Password"));
 | 
 |  |  |                deviceChannel.setLongitude(itemDevice.element("Longitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Longitude")));
 | 
 |  |  |                deviceChannel.setLatitude(itemDevice.element("Latitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Latitude")));
 | 
 |  |  |                channelMap.put(channelDeviceId, deviceChannel);
 | 
 |  |  |                deviceChannel.setPTZType(itemDevice.element("PTZType") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"PTZType")));
 | 
 |  |  |                deviceChannel.setHasAudio(false); // 默认含有音频为false
 | 
 |  |  |                storager.updateChannel(device.getDeviceId(), deviceChannel);
 | 
 |  |  |             }
 | 
 |  |  |             // 更新
 | 
 |  |  |             storager.update(device);
 | 
 |  |  | 
 | 
 |  |  |             RequestMessage msg = new RequestMessage();
 | 
 |  |  |             msg.setDeviceId(deviceId);
 | 
 |  |  |             msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
 | 
 |  |  |             msg.setData(device);
 | 
 |  |  |             deferredResultHolder.invokeResult(msg);
 | 
 |  |  | 
 | 
 |  |  |             // 回复200
 | 
 |  |  |             if (offLineDetector.isOnline(deviceId)) {
 | 
 |  |  |                responseAck(evt);
 | 
 |  |  |                publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
 | 
 |  |  |             }
 | 
 |  |  | 
 | 
 |  |  |          }
 | 
 |  |  |       } catch (DocumentException e) {
 | 
 |  |  |       } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
 | 
 |  |  |          e.printStackTrace();
 | 
 |  |  |       }
 | 
 |  |  |    }
 | 
 |  |  | 
 |  |  |          
 | 
 |  |  |          Device device = storager.queryVideoDevice(deviceId);
 | 
 |  |  |          if (device == null) {
 | 
 |  |  |             // TODO 也可能是通道
 | 
 |  |  | //            storager.queryChannel(deviceId)
 | 
 |  |  |             return;
 | 
 |  |  |          }
 | 
 |  |  |          device.setName(XmlUtil.getText(rootElement,"DeviceName"));
 | 
 |  |  |          device.setManufacturer(XmlUtil.getText(rootElement,"Manufacturer"));
 | 
 |  |  |          device.setModel(XmlUtil.getText(rootElement,"Model"));
 | 
 |  |  |          device.setFirmware(XmlUtil.getText(rootElement,"Firmware"));
 | 
 |  |  |          storager.update(device);
 | 
 |  |  |          if (StringUtils.isEmpty(device.getStreamMode())){
 | 
 |  |  |             device.setStreamMode("UDP");
 | 
 |  |  |          }
 | 
 |  |  |          storager.updateDevice(device);
 | 
 |  |  |          cmder.catalogQuery(device);
 | 
 |  |  |       } catch (DocumentException e) {
 | 
 |  |  |          e.printStackTrace();
 | 
 |  |  | 
 |  |  |       try {
 | 
 |  |  |          Element rootElement = getRootElement(evt);
 | 
 |  |  |          String deviceId = XmlUtil.getText(rootElement,"DeviceID");
 | 
 |  |  |          Request request = evt.getRequest();
 | 
 |  |  |          Response response = null;
 | 
 |  |  |          if (offLineDetector.isOnline(deviceId)) {
 | 
 |  |  |             response = layer.getMessageFactory().createResponse(Response.OK,request);
 | 
 |  |  |             responseAck(evt);
 | 
 |  |  |             publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
 | 
 |  |  |          } else {
 | 
 |  |  |             response = layer.getMessageFactory().createResponse(Response.BAD_REQUEST,request);
 | 
 |  |  |          }
 | 
 |  |  |          transaction.sendResponse(response);
 | 
 |  |  |       } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
 | 
 |  |  |          e.printStackTrace();
 | 
 |  |  |       }
 | 
 |  |  | 
 |  |  |                record.setEndTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(XmlUtil.getText(itemRecord,"EndTime")));
 | 
 |  |  |                record.setSecrecy(itemRecord.element("Secrecy") == null? 0:Integer.parseInt(XmlUtil.getText(itemRecord,"Secrecy")));
 | 
 |  |  |                record.setType(XmlUtil.getText(itemRecord,"Type"));
 | 
 |  |  |                record.setRecordId(XmlUtil.getText(itemRecord,"RecorderID"));
 | 
 |  |  |                record.setRecorderId(XmlUtil.getText(itemRecord,"RecorderID"));
 | 
 |  |  |                recordList.add(record);
 | 
 |  |  |             }
 | 
 |  |  |             recordInfo.setRecordList(recordList);
 | 
 |  |  | 
 |  |  |       }
 | 
 |  |  |    }
 | 
 |  |  |    
 | 
 |  |  |    private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
 | 
 |  |  |       Response response = getMessageFactory().createResponse(Response.OK,evt.getRequest());
 | 
 |  |  |       getServerTransaction(evt).sendResponse(response);
 | 
 |  |  |    }
 | 
 |  |  | 	 | 
 |  |  |    private Element getRootElement(RequestEvent evt) throws DocumentException {
 | 
 |  |  |       Request request = evt.getRequest();
 | 
 |  |  |       SAXReader reader = new SAXReader();
 | 
 |  |  |       reader.setEncoding("GB2312");
 | 
 |  |  |       reader.setEncoding("gbk");
 | 
 |  |  |       Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
 | 
 |  |  |       return xml.getRootElement();
 | 
 |  |  |    }
 | 
 |  |  | 
 | 
 |  |  |    public void setCmder(SIPCommander cmder) {
 | 
 |  |  |       this.cmder = cmder;
 | 
 |  |  |    }
 | 
 |  |  | 
 | 
 |  |  |    public void setStorager(IVideoManagerStorager storager) {
 | 
 |  |  |       this.storager = storager;
 | 
 |  |  |    }
 | 
 |  |  | 
 | 
 |  |  |    public void setPublisher(EventPublisher publisher) {
 | 
 |  |  |       this.publisher = publisher;
 | 
 |  |  |    }
 | 
 |  |  | 
 | 
 |  |  |    public void setRedis(RedisUtil redis) {
 | 
 |  |  |       this.redis = redis;
 | 
 |  |  |    }
 | 
 |  |  | 
 | 
 |  |  |    public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) {
 | 
 |  |  |       this.deferredResultHolder = deferredResultHolder;
 | 
 |  |  |    }
 | 
 |  |  | 
 | 
 |  |  |    public void setOffLineDetector(DeviceOffLineDetector offLineDetector) {
 | 
 |  |  |       this.offLineDetector = offLineDetector;
 | 
 |  |  |    }
 | 
 |  |  | 
 | 
 |  |  | }
 |