src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -17,7 +17,15 @@ @Component public class DeferredResultHolder { public static final String CALLBACK_CMD_DEVICESTATUS = "CALLBACK_DEVICESTATUS"; public static final String CALLBACK_CMD_DEVICEINFO = "CALLBACK_DEVICEINFO"; public static final String CALLBACK_CMD_DEVICECONTROL = "CALLBACK_DEVICECONTROL"; public static final String CALLBACK_CMD_DEVICECONFIG = "CALLBACK_DEVICECONFIG"; public static final String CALLBACK_CMD_CONFIGDOWNLOAD = "CALLBACK_CONFIGDOWNLOAD"; public static final String CALLBACK_CMD_CATALOG = "CALLBACK_CATALOG"; @@ -29,6 +37,10 @@ public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION"; public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY"; public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM"; private Map<String, DeferredResult> map = new ConcurrentHashMap<String, DeferredResult>(); public void put(String key, DeferredResult result) { src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -115,24 +115,35 @@ /** * 音视频录像控制 * * @param device 视频设备 * @param channelId 预览通道 * @param device 视频设备 * @param channelId 预览通道 * @param recordCmdStr 录像命令:Record / StopRecord */ boolean recordCmd(Device device,String channelId); boolean recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent); /** * 远程启动控制命令 * * @param device 视频设备 */ boolean teleBootCmd(Device device); /** * 报警布防/撤防命令 * * @param device 视频设备 * @param device 视频设备 * @param setGuard true: SetGuard, false: ResetGuard */ boolean guardCmd(Device device); boolean guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent); /** * 报警复位命令 * * @param device 视频设备 * @param device 视频设备 * @param alarmMethod 报警方式(可选) * @param alarmType 报警类型(可选) */ boolean alarmCmd(Device device); boolean alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent); /** * 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧 @@ -140,14 +151,17 @@ * @param device 视频设备 * @param channelId 预览通道 */ boolean iFameCmd(Device device,String channelId); boolean iFrameCmd(Device device, String channelId); /** * 看守位控制命令 * * @param device 视频设备 * @param device 视频设备 * @param enabled 看守位使能:1 = 开启,0 = 关闭 * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s) * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255 */ boolean homePositionCmd(Device device); boolean homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent); /** * 设备配置命令 @@ -156,13 +170,24 @@ */ boolean deviceConfigCmd(Device device); /** * 设备配置命令:basicParam * * @param device 视频设备 * @param channelId 通道编码(可选) * @param name 设备/通道名称(可选) * @param expiration 注册过期时间(可选) * @param heartBeatInterval 心跳间隔时间(可选) * @param heartBeatCount 心跳超时次数(可选) */ boolean deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent); /** * 查询设备状态 * * @param device 视频设备 */ boolean deviceStatusQuery(Device device); boolean deviceStatusQuery(Device device, SipSubscribe.Event errorEvent); /** * 查询设备信息 @@ -191,23 +216,33 @@ /** * 查询报警信息 * * @param device 视频设备 * @param device 视频设备 * @param startPriority 报警起始级别(可选) * @param endPriority 报警终止级别(可选) * @param alarmMethod 报警方式条件(可选) * @param alarmType 报警类型 * @param startTime 报警发生起始时间(可选) * @param endTime 报警发生终止时间(可选) * @return true = 命令发送成功 */ boolean alarmInfoQuery(Device device); boolean alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime, SipSubscribe.Event errorEvent); /** * 查询设备配置 * * @param device 视频设备 * @param device 视频设备 * @param channelId 通道编码(可选) * @param configType 配置类型: */ boolean configQuery(Device device); boolean deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent); /** * 查询设备预置位置 * * @param device 视频设备 */ boolean presetQuery(Device device); boolean presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent); /** * 查询移动设备位置数据 @@ -222,10 +257,26 @@ * @param device 视频设备 * @param expires 订阅超时时间(值=0时为取消订阅) * @param interval 上报时间间隔 * @return true = 命令发送成功 */ boolean mobilePositionSubscribe(Device device, int expires, int interval); /** * 订阅、取消订阅报警信息 * @param device 视频设备 * @param expires 订阅过期时间(0 = 取消订阅) * @param startPriority 报警起始级别(可选) * @param endPriority 报警终止级别(可选) * @param alarmMethods 报警方式条件(可选) * @param alarmType 报警类型 * @param startTime 报警发生起始时间(可选) * @param endTime 报警发生终止时间(可选) * @return true = 命令发送成功 */ boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime); /** * 释放rtpserver * @param device * @param channelId src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -34,6 +34,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; import com.genersoft.iot.vmp.gb28181.utils.DateUtil; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; /** * @Description:设备能力接口,用于定义设备的控制、查询能力 @@ -577,24 +579,89 @@ /** * 音视频录像控制 * * @param device 视频设备 * @param channelId 预览通道 * @param device 视频设备 * @param channelId 预览通道 * @param recordCmdStr 录像命令:Record / StopRecord */ @Override public boolean recordCmd(Device device, String channelId) { // TODO Auto-generated method stub return false; public boolean recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Control>\r\n"); cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); if (XmlUtil.isEmpty(channelId)) { cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); } else { cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); } cmdXml.append("<RecordCmd>" + recordCmdStr + "</RecordCmd>\r\n"); cmdXml.append("</Control>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromRecord" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** * 远程启动控制命令 * * @param device 视频设备 */ @Override public boolean teleBootCmd(Device device) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Control>\r\n"); cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); cmdXml.append("<TeleBoot>Boot</TeleBoot>\r\n"); cmdXml.append("</Control>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromBoot" + tm, null); transmitRequest(device, request); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** * 报警布防/撤防命令 * * @param device 视频设备 */ * @param device 视频设备 * @param guardCmdStr "SetGuard"/"ResetGuard" */ @Override public boolean guardCmd(Device device) { // TODO Auto-generated method stub return false; public boolean guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Control>\r\n"); cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n"); cmdXml.append("</Control>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromGuard" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** @@ -603,9 +670,37 @@ * @param device 视频设备 */ @Override public boolean alarmCmd(Device device) { // TODO Auto-generated method stub return false; public boolean alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Control>\r\n"); cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); cmdXml.append("<AlarmCmd>ResetAlarm</AlarmCmd>\r\n"); if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) { cmdXml.append("<Info>\r\n"); } if (!XmlUtil.isEmpty(alarmMethod)) { cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n"); } if (!XmlUtil.isEmpty(alarmType)) { cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n"); } if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) { cmdXml.append("</Info>\r\n"); } cmdXml.append("</Control>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromAlarm" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** @@ -615,20 +710,79 @@ * @param channelId 预览通道 */ @Override public boolean iFameCmd(Device device, String channelId) { // TODO Auto-generated method stub return false; public boolean iFrameCmd(Device device, String channelId) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Control>\r\n"); cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); if (XmlUtil.isEmpty(channelId)) { cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); } else { cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); } cmdXml.append("<IFameCmd>Send</IFameCmd>\r\n"); cmdXml.append("</Control>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromBoot" + tm, null); transmitRequest(device, request); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** * 看守位控制命令 * * @param device 视频设备 * @param device 视频设备 * @param enabled 看守位使能:1 = 开启,0 = 关闭 * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s) * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255 */ @Override public boolean homePositionCmd(Device device) { // TODO Auto-generated method stub return false; public boolean homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Control>\r\n"); cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); if (XmlUtil.isEmpty(channelId)) { cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); } else { cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); } cmdXml.append("<HomePosition>\r\n"); if (NumericUtil.isInteger(enabled) && (!enabled.equals("0"))) { cmdXml.append("<Enabled>1</Enabled>\r\n"); if (NumericUtil.isInteger(resetTime)) { cmdXml.append("<ResetTime>" + resetTime + "</ResetTime>\r\n"); } else { cmdXml.append("<ResetTime>0</ResetTime>\r\n"); } if (NumericUtil.isInteger(presetIndex)) { cmdXml.append("<PresetIndex>" + presetIndex + "</PresetIndex>\r\n"); } else { cmdXml.append("<PresetIndex>0</PresetIndex>\r\n"); } } else { cmdXml.append("<Enabled>0</Enabled>\r\n"); } cmdXml.append("</HomePosition>\r\n"); cmdXml.append("</Control>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromGuard" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** @@ -643,14 +797,87 @@ } /** * 设备配置命令:basicParam * * @param device 视频设备 * @param channelId 通道编码(可选) * @param name 设备/通道名称(可选) * @param expiration 注册过期时间(可选) * @param heartBeatInterval 心跳间隔时间(可选) * @param heartBeatCount 心跳超时次数(可选) */ @Override public boolean deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Control>\r\n"); cmdXml.append("<CmdType>DeviceConfig</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); if (XmlUtil.isEmpty(channelId)) { cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); } else { cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); } cmdXml.append("<BasicParam>\r\n"); if (!XmlUtil.isEmpty(name)) { cmdXml.append("<Name>" + name + "</Name>\r\n"); } if (NumericUtil.isInteger(expiration)) { if (Integer.valueOf(expiration) > 0) { cmdXml.append("<Expiration>" + expiration + "</Expiration>\r\n"); } } if (NumericUtil.isInteger(heartBeatInterval)) { if (Integer.valueOf(heartBeatInterval) > 0) { cmdXml.append("<HeartBeatInterval>" + heartBeatInterval + "</HeartBeatInterval>\r\n"); } } if (NumericUtil.isInteger(heartBeatCount)) { if (Integer.valueOf(heartBeatCount) > 0) { cmdXml.append("<HeartBeatCount>" + heartBeatCount + "</HeartBeatCount>\r\n"); } } cmdXml.append("</BasicParam>\r\n"); cmdXml.append("</Control>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** * 查询设备状态 * * @param device 视频设备 */ @Override public boolean deviceStatusQuery(Device device) { // TODO Auto-generated method stub return false; public boolean deviceStatusQuery(Device device, SipSubscribe.Event errorEvent) { try { StringBuffer catalogXml = new StringBuffer(200); catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n"); catalogXml.append("<Query>\r\n"); catalogXml.append("<CmdType>DeviceStatus</CmdType>\r\n"); catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); catalogXml.append("</Query>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, "FromStatus" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** @@ -748,23 +975,86 @@ /** * 查询报警信息 * * @param device 视频设备 */ * @param device 视频设备 * @param startPriority 报警起始级别(可选) * @param endPriority 报警终止级别(可选) * @param alarmMethods 报警方式条件(可选) * @param alarmType 报警类型 * @param startTime 报警发生起始时间(可选) * @param endTime 报警发生终止时间(可选) * @return true = 命令发送成功 */ @Override public boolean alarmInfoQuery(Device device) { // TODO Auto-generated method stub return false; public boolean alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Query>\r\n"); cmdXml.append("<CmdType>Alarm</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); if (!XmlUtil.isEmpty(startPriority)) { cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n"); } if (!XmlUtil.isEmpty(endPriority)) { cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n"); } if (!XmlUtil.isEmpty(alarmMethod)) { cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n"); } if (!XmlUtil.isEmpty(alarmType)) { cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n"); } if (!XmlUtil.isEmpty(startTime)) { cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n"); } if (!XmlUtil.isEmpty(endTime)) { cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n"); } cmdXml.append("</Query>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromAlarm" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** * 查询设备配置 * * @param device 视频设备 */ * @param device 视频设备 * @param channelId 通道编码(可选) * @param configType 配置类型: */ @Override public boolean configQuery(Device device) { // TODO Auto-generated method stub return false; public boolean deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Query>\r\n"); cmdXml.append("<CmdType>ConfigDownload</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); if (XmlUtil.isEmpty(channelId)) { cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); } else { cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); } cmdXml.append("<ConfigType>" + configType + "</ConfigType>\r\n"); cmdXml.append("</Query>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** @@ -773,9 +1063,28 @@ * @param device 视频设备 */ @Override public boolean presetQuery(Device device) { // TODO Auto-generated method stub return false; public boolean presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" ?>\r\n"); cmdXml.append("<Query>\r\n"); cmdXml.append("<CmdType>PresetQuery</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); if (XmlUtil.isEmpty(channelId)) { cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); } else { cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); } cmdXml.append("</Query>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, "FromConfig" + tm, null); transmitRequest(device, request, errorEvent); return true; } catch (SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); return false; } } /** @@ -813,6 +1122,7 @@ * @param device 视频设备 * @param expires 订阅超时时间 * @param interval 上报时间间隔 * @return true = 命令发送成功 */ public boolean mobilePositionSubscribe(Device device, int expires, int interval) { try { @@ -828,7 +1138,60 @@ subscribePostitionXml.append("</Query>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "Position;id=" + tm.substring(tm.length() - 4)); Request request = headerProvider.createSubscribeRequest(device, subscribePostitionXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "presence" ); //Position;id=" + tm.substring(tm.length() - 4)); transmitRequest(device, request); return true; } catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) { e.printStackTrace(); return false; } } /** * 订阅、取消订阅报警信息 * * @param device 视频设备 * @param expires 订阅过期时间(0 = 取消订阅) * @param startPriority 报警起始级别(可选) * @param endPriority 报警终止级别(可选) * @param alarmMethod 报警方式条件(可选) * @param alarmType 报警类型 * @param startTime 报警发生起始时间(可选) * @param endTime 报警发生终止时间(可选) * @return true = 命令发送成功 */ public boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime) { try { StringBuffer cmdXml = new StringBuffer(200); cmdXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n"); cmdXml.append("<Query>\r\n"); cmdXml.append("<CmdType>Alarm</CmdType>\r\n"); cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); if (!XmlUtil.isEmpty(startPriority)) { cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n"); } if (!XmlUtil.isEmpty(endPriority)) { cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n"); } if (!XmlUtil.isEmpty(alarmMethod)) { cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n"); } if (!XmlUtil.isEmpty(alarmType)) { cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n"); } if (!XmlUtil.isEmpty(startTime)) { cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n"); } if (!XmlUtil.isEmpty(endTime)) { cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n"); } cmdXml.append("</Query>\r\n"); String tm = Long.toString(System.currentTimeMillis()); Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "viaTagPos" + tm, "fromTagPos" + tm, null, expires, "presence" ); transmitRequest(device, request); return true; src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -10,6 +10,7 @@ import javax.sip.message.Request; import javax.sip.message.Response; 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; @@ -78,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_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请求 @@ -99,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); @@ -117,6 +131,9 @@ } 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); @@ -133,7 +150,6 @@ */ private void processMessageMobilePosition(RequestEvent evt) { try { //回复 200 OK Element rootElement = getRootElement(evt); MobilePosition mobilePosition = new MobilePosition(); Element deviceIdElement = rootElement.element("DeviceID"); @@ -174,12 +190,7 @@ storager.clearMobilePositionsByDeviceId(deviceId); } storager.insertMobilePosition(mobilePosition); // List<MobilePosition> all= storager.queryMobilePositions(deviceId, "2021-01-23T00:00:00", "2021-02-28T23:59:59"); // all= storager.queryMobilePositions(deviceId, null, "2021-01-24T23:59:59"); // all= storager.queryMobilePositions(deviceId, "2021-01-24T00:00:00", null); // //logger.debug(all.toString()); // MobilePosition mp = storager.queryLatestPosition(deviceId); // logger.debug("最新位置:" + mp.getLongitude() + ", " + mp.getLatitude()); //回复 200 OK responseAck(evt); } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { e.printStackTrace(); @@ -187,7 +198,169 @@ } /** * 收到deviceInfo设备信息请求 处理 * 处理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 */ @@ -354,56 +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) { 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 (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 ( 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); 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")); } storager.insertMobilePosition(mobilePosition); } // TODO: 需要实现存储报警信息、报警分类 // 回复200 OK responseAck(evt); if (offLineDetector.isOnline(deviceId)) { publisher.deviceAlarmEventPublish(deviceAlarm); 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) { @@ -435,7 +624,7 @@ } /*** * 收到catalog设备目录列表请求 处理 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致 * 处理RecordInfo设备录像列表Message请求 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致 * * @param evt */ @@ -522,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("处理完成,返回结果");