虚拟设备历史录像记录
This commit is contained in:
parent
5b7ee3996b
commit
bfc5db85ae
@ -11,12 +11,14 @@ import cn.skcks.docking.gb28181.core.sip.message.sender.SipMessageSender;
|
|||||||
import cn.skcks.docking.gb28181.core.sip.utils.SipUtil;
|
import cn.skcks.docking.gb28181.core.sip.utils.SipUtil;
|
||||||
import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.catalog.CatalogCmdProcessor;
|
import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.catalog.CatalogCmdProcessor;
|
||||||
import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.deviceinfo.DeviceInfoRequestProcessor;
|
import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.deviceinfo.DeviceInfoRequestProcessor;
|
||||||
|
import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.RecordInfoRequestProcessor;
|
||||||
import cn.skcks.docking.gb28181.mocking.core.sip.message.subscribe.SipSubscribe;
|
import cn.skcks.docking.gb28181.mocking.core.sip.message.subscribe.SipSubscribe;
|
||||||
import cn.skcks.docking.gb28181.mocking.core.sip.response.SipResponseBuilder;
|
import cn.skcks.docking.gb28181.mocking.core.sip.response.SipResponseBuilder;
|
||||||
import gov.nist.javax.sip.message.SIPRequest;
|
import gov.nist.javax.sip.message.SIPRequest;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.sip.RequestEvent;
|
import javax.sip.RequestEvent;
|
||||||
@ -38,6 +40,8 @@ public class MessageRequestProcessor implements MessageProcessor {
|
|||||||
private final CatalogCmdProcessor catalogCmdProcessor;
|
private final CatalogCmdProcessor catalogCmdProcessor;
|
||||||
private final DeviceInfoRequestProcessor deviceInfoRequestProcessor;
|
private final DeviceInfoRequestProcessor deviceInfoRequestProcessor;
|
||||||
|
|
||||||
|
private final RecordInfoRequestProcessor recordInfoRequestProcessor;
|
||||||
|
|
||||||
private Response okResponse(SIPRequest request){
|
private Response okResponse(SIPRequest request){
|
||||||
return SipResponseBuilder.response(request, Response.OK, "OK");
|
return SipResponseBuilder.response(request, Response.OK, "OK");
|
||||||
}
|
}
|
||||||
@ -59,12 +63,15 @@ public class MessageRequestProcessor implements MessageProcessor {
|
|||||||
MessageDTO messageDto = XmlUtils.parse(content, MessageDTO.class, GB28181Constant.CHARSET);
|
MessageDTO messageDto = XmlUtils.parse(content, MessageDTO.class, GB28181Constant.CHARSET);
|
||||||
log.debug("deviceId:{}, 接收到的消息 => {}", deviceId, messageDto);
|
log.debug("deviceId:{}, 接收到的消息 => {}", deviceId, messageDto);
|
||||||
|
|
||||||
if(messageDto.getCmdType().equalsIgnoreCase(CmdType.CATALOG)) {
|
String cmdType = messageDto.getCmdType();
|
||||||
|
if(cmdType.equalsIgnoreCase(CmdType.CATALOG)) {
|
||||||
sender.send(senderIp, okResponse(request));
|
sender.send(senderIp, okResponse(request));
|
||||||
catalogCmdProcessor.process(request, content);
|
catalogCmdProcessor.process(request, content);
|
||||||
} else if(messageDto.getCmdType().equalsIgnoreCase("DeviceInfo")){
|
} else if(cmdType.equalsIgnoreCase("DeviceInfo")){
|
||||||
sender.send(senderIp, okResponse(request));
|
sender.send(senderIp, okResponse(request));
|
||||||
deviceInfoRequestProcessor.process(request, content);
|
deviceInfoRequestProcessor.process(request, content);
|
||||||
|
} else if(StringUtils.equalsIgnoreCase(cmdType,CmdType.RECORD_INFO)){
|
||||||
|
recordInfoRequestProcessor.process(request, content);
|
||||||
} else {
|
} else {
|
||||||
Response response = SipResponseBuilder.response(request, Response.NOT_IMPLEMENTED, ResponseStatus.NOT_IMPLEMENTED.getMessage());
|
Response response = SipResponseBuilder.response(request, Response.NOT_IMPLEMENTED, ResponseStatus.NOT_IMPLEMENTED.getMessage());
|
||||||
sender.send(senderIp, response);
|
sender.send(senderIp, response);
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
package cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.skcks.docking.gb28181.common.xml.XmlUtils;
|
||||||
|
import cn.skcks.docking.gb28181.core.sip.message.processor.message.types.recordinfo.query.dto.RecordInfoRequestDTO;
|
||||||
|
import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.dto.RecordInfoItemDTO;
|
||||||
|
import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.dto.RecordInfoResponseDTO;
|
||||||
|
import cn.skcks.docking.gb28181.mocking.core.sip.request.SipRequestBuilder;
|
||||||
|
import cn.skcks.docking.gb28181.mocking.core.sip.response.SipResponseBuilder;
|
||||||
|
import cn.skcks.docking.gb28181.mocking.core.sip.sender.SipSender;
|
||||||
|
import cn.skcks.docking.gb28181.mocking.orm.mybatis.dynamic.model.MockingDevice;
|
||||||
|
import cn.skcks.docking.gb28181.mocking.service.device.DeviceService;
|
||||||
|
import gov.nist.javax.sip.message.SIPRequest;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.header.CallIdHeader;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Component
|
||||||
|
public class RecordInfoRequestProcessor {
|
||||||
|
private final SipSender sender;
|
||||||
|
private final DeviceService deviceService;
|
||||||
|
|
||||||
|
public void process(SIPRequest request, byte[] content) {
|
||||||
|
String senderIp = request.getLocalAddress().getHostAddress();
|
||||||
|
String transport = request.getTopmostViaHeader().getTransport();
|
||||||
|
RecordInfoRequestDTO recordInfoRequestDTO = XmlUtils.parse(content, RecordInfoRequestDTO.class);
|
||||||
|
String id = recordInfoRequestDTO.getDeviceId();
|
||||||
|
deviceService.getDeviceByGbChannelId(id).ifPresentOrElse((device) -> {
|
||||||
|
sendRecordInfo(device, recordInfoRequestDTO, request, senderIp, transport);
|
||||||
|
}, () -> {
|
||||||
|
deviceService.getDeviceByGbChannelId(id).ifPresentOrElse((device) -> {
|
||||||
|
sendRecordInfo(device, recordInfoRequestDTO, request, senderIp, transport);
|
||||||
|
}, () -> {
|
||||||
|
log.error("未能找到 deviceId: {} 的相关信息", id);
|
||||||
|
sender.sendResponse(senderIp, transport, notFound(request));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendRecordInfo(MockingDevice device, RecordInfoRequestDTO recordInfoRequestDTO, SIPRequest request, String senderIp, String transport) {
|
||||||
|
sender.sendResponse(senderIp, transport, ok(request));
|
||||||
|
Date startTime = recordInfoRequestDTO.getStartTime();
|
||||||
|
Date endTime = recordInfoRequestDTO.getEndTime();
|
||||||
|
String name = StringUtils.joinWith(" - ",
|
||||||
|
DateUtil.format(startTime, DatePattern.NORM_DATETIME_FORMATTER),
|
||||||
|
DateUtil.format(endTime, DatePattern.NORM_DATETIME_FORMATTER));
|
||||||
|
|
||||||
|
RecordInfoItemDTO recordInfoItemDTO = new RecordInfoItemDTO();
|
||||||
|
recordInfoItemDTO.setName(name);
|
||||||
|
recordInfoItemDTO.setStartTime(startTime);
|
||||||
|
recordInfoItemDTO.setEndTime(endTime);
|
||||||
|
recordInfoItemDTO.setSecrecy(recordInfoRequestDTO.getSecrecy());
|
||||||
|
recordInfoItemDTO.setDeviceId(device.getGbDeviceId());
|
||||||
|
|
||||||
|
List<RecordInfoItemDTO> recordInfoItemDTOList = Collections.singletonList(recordInfoItemDTO);
|
||||||
|
RecordInfoResponseDTO recordInfoResponseDTO = new RecordInfoResponseDTO();
|
||||||
|
recordInfoResponseDTO.setSn(recordInfoRequestDTO.getSn());
|
||||||
|
recordInfoResponseDTO.setDeviceId(device.getGbDeviceId());
|
||||||
|
recordInfoResponseDTO.setName(device.getName());
|
||||||
|
recordInfoResponseDTO.setSumNum((long) recordInfoItemDTOList.size());
|
||||||
|
recordInfoResponseDTO.setRecordList(recordInfoItemDTOList);
|
||||||
|
|
||||||
|
FromHeader fromHeader = request.getFromHeader();
|
||||||
|
sender.sendRequest((provider, ip, port) -> {
|
||||||
|
CallIdHeader callIdHeader = provider.getNewCallId();
|
||||||
|
return SipRequestBuilder.createMessageRequest(device,
|
||||||
|
ip, port, 1, XmlUtils.toXml(recordInfoResponseDTO), fromHeader.getTag(), callIdHeader);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private SipSender.SendResponse ok(SIPRequest request) {
|
||||||
|
return (provider, ip, port) -> SipResponseBuilder.response(request, Response.OK,
|
||||||
|
"OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
private SipSender.SendResponse notFound(SIPRequest request) {
|
||||||
|
return (provider, ip, port) -> SipResponseBuilder.response(request, Response.NOT_FOUND,
|
||||||
|
"Not Found");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.dto;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import cn.skcks.docking.gb28181.core.sip.gb28181.constant.GB28181Constant;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JacksonXmlRootElement(localName = "Item")
|
||||||
|
public class RecordInfoItemDTO {
|
||||||
|
/**
|
||||||
|
* 目标设备的设备编码(必选)
|
||||||
|
*/
|
||||||
|
@JacksonXmlProperty(localName = "DeviceID")
|
||||||
|
private String deviceId;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = DatePattern.UTC_SIMPLE_PATTERN, timezone = GB28181Constant.TIME_ZONE)
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = DatePattern.UTC_SIMPLE_PATTERN, timezone = GB28181Constant.TIME_ZONE)
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
@Min(value = 0)
|
||||||
|
private Integer secrecy = 0;
|
||||||
|
|
||||||
|
private String type = "all";
|
||||||
|
|
||||||
|
private Long fileSize;
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.recordinfo.dto;
|
||||||
|
|
||||||
|
import cn.skcks.docking.gb28181.core.sip.gb28181.constant.CmdType;
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JacksonXmlRootElement(localName = "Response")
|
||||||
|
public class RecordInfoResponseDTO {
|
||||||
|
/**
|
||||||
|
* 命令类型:设备信息查询(必选)
|
||||||
|
*/
|
||||||
|
private String cmdType = CmdType.RECORD_INFO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命令序列号(必选)
|
||||||
|
*/
|
||||||
|
@JacksonXmlProperty(localName = "SN")
|
||||||
|
private String sn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 目标设备的设备编码(必选)
|
||||||
|
*/
|
||||||
|
@JacksonXmlProperty(localName = "DeviceID")
|
||||||
|
private String deviceId;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Long sumNum;
|
||||||
|
|
||||||
|
@JacksonXmlElementWrapper(localName = "RecordList")
|
||||||
|
@JacksonXmlProperty(localName = "Item")
|
||||||
|
private List<RecordInfoItemDTO> recordList;
|
||||||
|
}
|
@ -1,13 +1,14 @@
|
|||||||
package cn.skcks.docking.gb28181.mocking.core.sip.response;
|
package cn.skcks.docking.gb28181.mocking.core.sip.response;
|
||||||
|
|
||||||
|
import cn.skcks.docking.gb28181.core.sip.gb28181.constant.GB28181Constant;
|
||||||
import cn.skcks.docking.gb28181.core.sip.message.MessageHelper;
|
import cn.skcks.docking.gb28181.core.sip.message.MessageHelper;
|
||||||
import cn.skcks.docking.gb28181.core.sip.utils.SipUtil;
|
import cn.skcks.docking.gb28181.core.sip.utils.SipUtil;
|
||||||
|
import gov.nist.javax.sip.message.MessageFactoryImpl;
|
||||||
import gov.nist.javax.sip.message.SIPRequest;
|
import gov.nist.javax.sip.message.SIPRequest;
|
||||||
import gov.nist.javax.sip.message.SIPResponse;
|
import gov.nist.javax.sip.message.SIPResponse;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.sip.message.MessageFactory;
|
|
||||||
import javax.sip.message.Response;
|
import javax.sip.message.Response;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -18,7 +19,9 @@ public class SipResponseBuilder {
|
|||||||
request.getToHeader().setTag(SipUtil.generateTag());
|
request.getToHeader().setTag(SipUtil.generateTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageFactory messageFactory = MessageHelper.getSipFactory().createMessageFactory();
|
MessageFactoryImpl messageFactory = (MessageFactoryImpl)MessageHelper.getSipFactory().createMessageFactory();
|
||||||
|
// 使用 GB28181 默认编码 否则中文将会乱码
|
||||||
|
messageFactory.setDefaultContentEncodingCharset(GB28181Constant.CHARSET);
|
||||||
SIPResponse response = (SIPResponse)messageFactory.createResponse(status, request);
|
SIPResponse response = (SIPResponse)messageFactory.createResponse(status, request);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
response.setReasonPhrase(message);
|
response.setReasonPhrase(message);
|
||||||
|
@ -47,6 +47,11 @@ public class DeviceService {
|
|||||||
.and(MockingDeviceDynamicSqlSupport.gbChannelId,isEqualTo(channel)));
|
.and(MockingDeviceDynamicSqlSupport.gbChannelId,isEqualTo(channel)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<MockingDevice> getDeviceByGbChannelId(String channel){
|
||||||
|
return deviceMapper.selectOne(s->
|
||||||
|
s.where(MockingDeviceDynamicSqlSupport.gbChannelId,isEqualTo(channel)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加设备
|
* 添加设备
|
||||||
* @param device 设备
|
* @param device 设备
|
||||||
@ -78,6 +83,13 @@ public class DeviceService {
|
|||||||
throw new JsonException(MessageFormat.format("国标编码 {0}, 通道 {1} 已存在" ,gbDeviceId, channel));
|
throw new JsonException(MessageFormat.format("国标编码 {0}, 通道 {1} 已存在" ,gbDeviceId, channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(getDeviceByGbChannelId(channel).isPresent()){
|
||||||
|
throw new JsonException(MessageFormat.format("通道 {0} 已存在", channel));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getDeviceByGbDeviceId(gbDeviceId).isPresent()){
|
||||||
|
throw new JsonException(MessageFormat.format("国标编码 {0} 已存在", gbDeviceId));
|
||||||
|
}
|
||||||
return deviceMapper.insert(device) > 0;
|
return deviceMapper.insert(device) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user