lawrencehj 5 лет назад
Родитель
Сommit
18c3b59318

+ 12 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java

@@ -17,8 +17,16 @@ import org.springframework.web.context.request.async.DeferredResult;
 @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";
 	
 	public static final String CALLBACK_CMD_RECORDINFO = "CALLBACK_RECORDINFO";
@@ -29,6 +37,10 @@ public class DeferredResultHolder {
 
 	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) {

+ 67 - 16
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java

@@ -115,24 +115,35 @@ public interface ISIPCommander {
 	/**
 	 * 音视频录像控制
 	 * 
-	 * @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 @@ public interface ISIPCommander {
 	 * @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 @@ public interface ISIPCommander {
 	 */
 	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 @@ public interface ISIPCommander {
 	/**
 	 * 查询报警信息
 	 * 
-	 * @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,9 +257,25 @@ public interface ISIPCommander {
 	 * @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

+ 400 - 37
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java

@@ -34,6 +34,8 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
 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 @@ public class SIPCommander implements ISIPCommander {
 	/**
 	 * 音视频录像控制
 	 * 
-	 * @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 @@ public class SIPCommander implements ISIPCommander {
 	 * @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 @@ public class SIPCommander implements ISIPCommander {
 	 * @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;
+		} 
 	}
 
 	/**
@@ -642,15 +796,88 @@ public class SIPCommander implements ISIPCommander {
 		return false;
 	}
 
+	/**
+	 * 设备配置命令: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 @@ public class SIPCommander implements ISIPCommander {
 	/**
 	 * 查询报警信息
 	 * 
-	 * @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 @@ public class SIPCommander implements ISIPCommander {
 	 * @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 @@ public class SIPCommander implements ISIPCommander {
 	 * @param device	视频设备
 	 * @param expires	订阅超时时间
 	 * @param interval	上报时间间隔
+	 * @return			true = 命令发送成功
 	 */
 	public boolean mobilePositionSubscribe(Device device, int expires, int interval) {
 		try {
@@ -828,7 +1138,60 @@ public class SIPCommander implements ISIPCommander {
 			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;

+ 242 - 56
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java

@@ -10,6 +10,7 @@ import javax.sip.SipException;
 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 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 	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 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 				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 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 			} 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 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 	 */
 	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 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 				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 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 	}
 
 	/**
-	 * 收到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 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 			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 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 	}
 
 	/***
-	 * 收到catalog设备目录列表请求 处理 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致
+	 * 处理RecordInfo设备录像列表Message请求 TODO 过期时间暂时写死180秒,后续与DeferredResult超时时间保持一致
 	 * 
 	 * @param evt
 	 */
@@ -522,12 +711,9 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
 			// 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("处理完成,返回结果");