虚拟设备历史录像记录

This commit is contained in:
shikong 2023-09-14 16:11:41 +08:00
parent 5b7ee3996b
commit bfc5db85ae
6 changed files with 194 additions and 4 deletions

View File

@ -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.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.recordinfo.RecordInfoRequestProcessor;
import cn.skcks.docking.gb28181.mocking.core.sip.message.subscribe.SipSubscribe;
import cn.skcks.docking.gb28181.mocking.core.sip.response.SipResponseBuilder;
import gov.nist.javax.sip.message.SIPRequest;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.sip.RequestEvent;
@ -38,6 +40,8 @@ public class MessageRequestProcessor implements MessageProcessor {
private final CatalogCmdProcessor catalogCmdProcessor;
private final DeviceInfoRequestProcessor deviceInfoRequestProcessor;
private final RecordInfoRequestProcessor recordInfoRequestProcessor;
private Response okResponse(SIPRequest request){
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);
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));
catalogCmdProcessor.process(request, content);
} else if(messageDto.getCmdType().equalsIgnoreCase("DeviceInfo")){
} else if(cmdType.equalsIgnoreCase("DeviceInfo")){
sender.send(senderIp, okResponse(request));
deviceInfoRequestProcessor.process(request, content);
} else if(StringUtils.equalsIgnoreCase(cmdType,CmdType.RECORD_INFO)){
recordInfoRequestProcessor.process(request, content);
} else {
Response response = SipResponseBuilder.response(request, Response.NOT_IMPLEMENTED, ResponseStatus.NOT_IMPLEMENTED.getMessage());
sender.send(senderIp, response);

View File

@ -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");
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,13 +1,14 @@
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.utils.SipUtil;
import gov.nist.javax.sip.message.MessageFactoryImpl;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import javax.sip.message.MessageFactory;
import javax.sip.message.Response;
@Slf4j
@ -18,7 +19,9 @@ public class SipResponseBuilder {
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);
if (message != null) {
response.setReasonPhrase(message);

View File

@ -47,6 +47,11 @@ public class DeviceService {
.and(MockingDeviceDynamicSqlSupport.gbChannelId,isEqualTo(channel)));
}
public Optional<MockingDevice> getDeviceByGbChannelId(String channel){
return deviceMapper.selectOne(s->
s.where(MockingDeviceDynamicSqlSupport.gbChannelId,isEqualTo(channel)));
}
/**
* 添加设备
* @param device 设备
@ -78,6 +83,13 @@ public class DeviceService {
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;
}