修复WVP作为下级平台接收上级平台DeviceControl信令不做处理的问题。

pull/741/head
gaofw189 2023-02-02 18:21:25 +08:00
parent bdf799fb64
commit 7a9f001dcb
6 changed files with 319 additions and 48 deletions

View File

@ -57,6 +57,11 @@
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>

View File

@ -0,0 +1,69 @@
package com.genersoft.iot.vmp.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.dom4j.Element;
import org.springframework.util.ObjectUtils;
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
/**
* @author gaofuwang
* @date 2023/01/18/ 10:09:00
* @since 1.0
*/
@Getter
@AllArgsConstructor
public enum DeviceControlType {
/**
*
*
*/
PTZ("PTZCmd","云台控制"),
/**
*
*/
TELE_BOOT("TeleBoot","远程启动"),
/**
*
*/
RECORD("RecordCmd","录像控制"),
/**
*
*/
GUARD("GuardCmd","布防撤防"),
/**
*
*/
ALARM("AlarmCmd","告警控制"),
/**
*
*/
I_FRAME("IFameCmd","强制关键帧"),
/**
*
*/
DRAG_ZOOM_IN("DragZoomIn","拉框放大"),
/**
*
*/
DRAG_ZOOM_OUT("DragZoomOut","拉框缩小"),
/**
*
*/
HOME_POSITION("HomePosition","看守位");
private final String val;
private final String desc;
public static DeviceControlType typeOf(Element rootElement) {
for (DeviceControlType item : DeviceControlType.values()) {
if (!ObjectUtils.isEmpty(getText(rootElement,item.val))) {
return item;
}
}
return null;
}
}

View File

@ -219,12 +219,14 @@ public interface ISIPCommander {
/**
*
*
* @param device
* @param enabled 使1 = 0 =
* @param resetTime 使:(s)
* @param presetIndex 使0~255
* @param device
* @param channelId id
* @param frontCmd
* @param enabled 使1 = 0 =
* @param resetTime 使:(s)
* @param presetIndex 使0~255
*/
void homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
void homePositionCmd(Device device, String channelId,String frontCmd, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
/**
*

View File

@ -29,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.sip.InvalidArgumentException;
import javax.sip.ResponseEvent;
@ -800,12 +801,14 @@ public class SIPCommander implements ISIPCommander {
*
*
* @param device
* @param channelId id
* @param frontCmd
* @param enabled 使1 = 0 =
* @param resetTime 使:(s)
* @param presetIndex 使0~255
*/
@Override
public void homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
public void homePositionCmd(Device device, String channelId,String frontCmd, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
StringBuffer cmdXml = new StringBuffer(200);
String charset = device.getCharset();
@ -819,28 +822,33 @@ public class SIPCommander implements ISIPCommander {
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");
if (StringUtils.hasText(frontCmd)){
cmdXml.append(frontCmd);
}else{
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("<ResetTime>0</ResetTime>\r\n");
cmdXml.append("<Enabled>0</Enabled>\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");
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent);
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent);
}
/**

View File

@ -1,8 +1,9 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.control.cmd;
import com.genersoft.iot.vmp.VManageBootstrap;
import com.genersoft.iot.vmp.common.enums.DeviceControlType;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
@ -28,6 +29,7 @@ import javax.sip.header.ToHeader;
import javax.sip.message.Response;
import java.text.ParseException;
import java.util.Iterator;
import java.util.Objects;
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
@ -101,13 +103,11 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
// logger.error("[任务执行失败] 服务重启: {}", e.getMessage());
// }
});
} else {
// 远程启动指定设备
}
}
// 云台/前端控制命令
if (!ObjectUtils.isEmpty(getText(rootElement,"PTZCmd")) && !parentPlatform.getServerGBId().equals(targetGBId)) {
String cmdString = getText(rootElement,"PTZCmd");
DeviceControlType deviceControlType = DeviceControlType.typeOf(rootElement);
if (!ObjectUtils.isEmpty(deviceControlType) && !parentPlatform.getServerGBId().equals(targetGBId)){
//判断是否存在该通道
Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId);
if (deviceForPlatform == null) {
try {
@ -117,25 +117,212 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
}
return;
}
try {
cmder.fronEndCmd(deviceForPlatform, channelId, cmdString, eventResult -> {
// 失败的回复
try {
responseAck(request, eventResult.statusCode, eventResult.msg);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 云台/前端回复: {}", e.getMessage());
}
}, eventResult -> {
// 成功的回复
try {
responseAck(request, eventResult.statusCode);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 云台/前端回复: {}", e.getMessage());
}
});
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 云台/前端: {}", e.getMessage());
switch (deviceControlType){
case PTZ:
handlePtzCmd(deviceForPlatform,channelId,rootElement,request,DeviceControlType.PTZ);
break;
case ALARM:
handleAlarmCmd(deviceForPlatform,rootElement,request);
break;
case GUARD:
handleGuardCmd(deviceForPlatform,rootElement,request,DeviceControlType.GUARD);
break;
case RECORD:
handleRecordCmd(deviceForPlatform,channelId,rootElement,request,DeviceControlType.RECORD);
break;
case I_FRAME:
handleIFameCmd(deviceForPlatform,channelId);
break;
case TELE_BOOT:
handleTeleBootCmd(deviceForPlatform);
break;
case DRAG_ZOOM_IN:
handleDragZoom(deviceForPlatform,channelId,rootElement,DeviceControlType.DRAG_ZOOM_IN);
break;
case DRAG_ZOOM_OUT:
handleDragZoom(deviceForPlatform,channelId,rootElement,DeviceControlType.DRAG_ZOOM_OUT);
break;
case HOME_POSITION:
handleHomePositionCmd(deviceForPlatform,channelId,rootElement,request,DeviceControlType.HOME_POSITION);
break;
default:
break;
}
}
}
/**
*
* @param device
* @param channelId id
* @param rootElement
* @param request
*/
private void handlePtzCmd(Device device,String channelId,Element rootElement,SIPRequest request,DeviceControlType type){
String cmdString = getText(rootElement,type.getVal());
try {
cmder.fronEndCmd(device, channelId, cmdString,
errorResult -> onError(request,errorResult),
okResult -> onOk(request,okResult));
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 云台/前端: {}", e.getMessage());
}
}
/**
*
* @param device
* @param channelId id
*/
private void handleIFameCmd(Device device,String channelId){
try {
cmder.iFrameCmd(device,channelId);
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 关键帧: {}", e.getMessage());
}
}
/**
*
* @param device
*/
private void handleTeleBootCmd(Device device){
try {
cmder.teleBootCmd(device);
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 重启: {}", e.getMessage());
}
}
/**
*
* @param device
* @param channelId id
* @param rootElement
* @param type
*/
private void handleDragZoom(Device device,String channelId,Element rootElement,DeviceControlType type){
String cmdString = getText(rootElement,type.getVal());
StringBuffer cmdXml = new StringBuffer(200);
cmdXml.append("<" + type.getVal() + ">\r\n");
cmdXml.append(cmdString);
cmdXml.append("</" + type.getVal() + ">\r\n");
try {
cmder.dragZoomCmd(device,channelId,cmdXml.toString());
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 拉框控制: {}", e.getMessage());
}
}
/**
*
* @param device
* @param channelId id
* @param rootElement
* @param request
* @param type
*/
private void handleHomePositionCmd(Device device,String channelId,Element rootElement,SIPRequest request,DeviceControlType type){
//获取整个消息主体,我们只需要修改请求头即可
String cmdString = getText(rootElement,type.getVal());
try {
cmder.homePositionCmd(device, channelId, cmdString,null,null,null,
errorResult -> onError(request,errorResult),
okResult -> onOk(request,okResult));
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 看守位设置: {}", e.getMessage());
}
}
/**
*
* @param device
* @param rootElement
* @param request
*/
private void handleAlarmCmd(Device device,Element rootElement,SIPRequest request){
//告警方法
String alarmMethod = "";
//告警类型
String alarmType = "";
Element info = rootElement.element("Info");
if (info !=null){
alarmMethod = getText(rootElement,"AlarmMethod");
alarmType = getText(rootElement,"AlarmType");
}
try {
cmder.alarmCmd(device, alarmMethod,alarmType,
errorResult -> onError(request,errorResult));
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 告警重置: {}", e.getMessage());
}
}
/**
*
* @param device
* @param channelId id
* @param rootElement
* @param request
* @param type
*/
private void handleRecordCmd(Device device,String channelId,Element rootElement,SIPRequest request,DeviceControlType type){
//获取整个消息主体,我们只需要修改请求头即可
String cmdString = getText(rootElement,type.getVal());
try {
cmder.recordCmd(device, channelId,cmdString,
errorResult -> onError(request,errorResult));
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 告警重置: {}", e.getMessage());
}
}
/**
* /
* @param device
* @param rootElement
* @param request
* @param type
*/
private void handleGuardCmd(Device device,Element rootElement,SIPRequest request,DeviceControlType type){
//获取整个消息主体,我们只需要修改请求头即可
String cmdString = getText(rootElement,type.getVal());
try {
cmder.guardCmd(device, cmdString,
errorResult -> onError(request,errorResult));
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 布防/撤防命令: {}", e.getMessage());
}
}
/**
*
* @param request
* @param eventResult
*/
private void onError(SIPRequest request, SipSubscribe.EventResult eventResult){
// 失败的回复
try {
responseAck(request, eventResult.statusCode, eventResult.msg);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 回复: {}", e.getMessage());
}
}
/**
*
* @param request
* @param eventResult
*/
private void onOk(SIPRequest request, SipSubscribe.EventResult eventResult){
// 成功的回复
try {
responseAck(request, eventResult.statusCode);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 回复: {}", e.getMessage());
}
}
}

View File

@ -268,13 +268,13 @@ public class DeviceControl {
String uuid = UUID.randomUUID().toString();
Device device = storager.queryVideoDevice(deviceId);
try {
cmder.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, event -> {
cmder.homePositionCmd(device, channelId,null, enabled, resetTime, presetIndex, event -> {
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
msg.setData(String.format("看守位控制操作失败,错误码: %s, %s", event.statusCode, event.msg));
resultHolder.invokeResult(msg);
});
},null);
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 看守位控制: {}", e.getMessage());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());