dialog去除以及异常情况处理优化
This commit is contained in:
parent
a574ff0944
commit
cd117ed228
@ -2,6 +2,9 @@ package com.genersoft.iot.vmp.conf;
|
|||||||
|
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||||
|
import com.genersoft.iot.vmp.vmanager.gb28181.device.DeviceQuery;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
@ -15,6 +18,8 @@ import java.util.regex.Pattern;
|
|||||||
@Configuration("mediaConfig")
|
@Configuration("mediaConfig")
|
||||||
public class MediaConfig{
|
public class MediaConfig{
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(MediaConfig.class);
|
||||||
|
|
||||||
// 修改必须配置,不再支持自动获取
|
// 修改必须配置,不再支持自动获取
|
||||||
@Value("${media.id}")
|
@Value("${media.id}")
|
||||||
private String id;
|
private String id;
|
||||||
@ -174,7 +179,7 @@ public class MediaConfig{
|
|||||||
try {
|
try {
|
||||||
hostAddress = InetAddress.getByName(sdpIp).getHostAddress();
|
hostAddress = InetAddress.getByName(sdpIp).getHostAddress();
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
throw new RuntimeException(e);
|
logger.error("[获取SDP IP]: 域名解析失败");
|
||||||
}
|
}
|
||||||
return hostAddress;
|
return hostAddress;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.genersoft.iot.vmp.conf.exception;
|
||||||
|
|
||||||
|
import com.sun.javafx.binding.StringFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lin
|
||||||
|
*/
|
||||||
|
public class SsrcTransactionNotFoundException extends Exception{
|
||||||
|
private String deviceId;
|
||||||
|
private String channelId;
|
||||||
|
private String callId;
|
||||||
|
private String stream;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public SsrcTransactionNotFoundException(String deviceId, String channelId, String callId, String stream) {
|
||||||
|
this.deviceId = deviceId;
|
||||||
|
this.channelId = channelId;
|
||||||
|
this.callId = callId;
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceId() {
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChannelId() {
|
||||||
|
return channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCallId() {
|
||||||
|
return callId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStream() {
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
StringBuffer msg = new StringBuffer();
|
||||||
|
msg.append(StringFormatter.format("缓存事务信息未找到,device:%s channel: %s ", deviceId, channelId));
|
||||||
|
if (callId != null) {
|
||||||
|
msg.append("callId: " + callId);
|
||||||
|
}
|
||||||
|
if (stream != null) {
|
||||||
|
msg.append("stream: " + stream);
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,7 @@ public class SipLayer{
|
|||||||
|
|
||||||
@Bean("sipStack")
|
@Bean("sipStack")
|
||||||
@DependsOn({"sipFactory"})
|
@DependsOn({"sipFactory"})
|
||||||
SipStack createSipStack() throws PeerUnavailableException {
|
SipStackImpl createSipStack() throws PeerUnavailableException {
|
||||||
sipStack = ( SipStackImpl )sipFactory.createSipStack(DefaultProperties.getProperties(sipConfig.getMonitorIp(), false));
|
sipStack = ( SipStackImpl )sipFactory.createSipStack(DefaultProperties.getProperties(sipConfig.getMonitorIp(), false));
|
||||||
return sipStack;
|
return sipStack;
|
||||||
}
|
}
|
||||||
@ -56,7 +56,6 @@ public class SipLayer{
|
|||||||
tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint);
|
tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint);
|
||||||
tcpSipProvider.setDialogErrorsAutomaticallyHandled();
|
tcpSipProvider.setDialogErrorsAutomaticallyHandled();
|
||||||
tcpSipProvider.addSipListener(sipProcessorObserver);
|
tcpSipProvider.addSipListener(sipProcessorObserver);
|
||||||
// tcpSipProvider.setAutomaticDialogSupportEnabled(false);
|
|
||||||
logger.info("[Sip Server] TCP 启动成功 {}:{}", sipConfig.getMonitorIp(), sipConfig.getPort());
|
logger.info("[Sip Server] TCP 启动成功 {}:{}", sipConfig.getMonitorIp(), sipConfig.getPort());
|
||||||
} catch (TransportNotSupportedException e) {
|
} catch (TransportNotSupportedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -80,7 +79,6 @@ public class SipLayer{
|
|||||||
udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "UDP");
|
udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "UDP");
|
||||||
udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint);
|
udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint);
|
||||||
udpSipProvider.addSipListener(sipProcessorObserver);
|
udpSipProvider.addSipListener(sipProcessorObserver);
|
||||||
// udpSipProvider.setAutomaticDialogSupportEnabled(false);
|
|
||||||
} catch (TransportNotSupportedException e) {
|
} catch (TransportNotSupportedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (InvalidArgumentException e) {
|
} catch (InvalidArgumentException e) {
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.bean;
|
||||||
|
|
||||||
|
import javax.sip.Dialog;
|
||||||
|
import java.util.EventObject;
|
||||||
|
|
||||||
|
public class CmdSendFailEvent extends EventObject {
|
||||||
|
|
||||||
|
private String callId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a prototypical Event.
|
||||||
|
*
|
||||||
|
* @param dialog
|
||||||
|
* @throws IllegalArgumentException if source is null.
|
||||||
|
*/
|
||||||
|
public CmdSendFailEvent(Dialog dialog) {
|
||||||
|
super(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCallId() {
|
||||||
|
return callId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCallId(String callId) {
|
||||||
|
this.callId = callId;
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,9 @@ import javax.sip.Dialog;
|
|||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
|
|
||||||
public class DeviceNotFoundEvent extends EventObject {
|
public class DeviceNotFoundEvent extends EventObject {
|
||||||
|
|
||||||
|
private String callId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a prototypical Event.
|
* Constructs a prototypical Event.
|
||||||
*
|
*
|
||||||
@ -14,8 +17,11 @@ public class DeviceNotFoundEvent extends EventObject {
|
|||||||
super(dialog);
|
super(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCallId() {
|
||||||
|
return callId;
|
||||||
|
}
|
||||||
|
|
||||||
public Dialog getDialog() {
|
public void setCallId(String callId) {
|
||||||
return (Dialog)super.getSource();
|
this.callId = callId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.bean;
|
package com.genersoft.iot.vmp.gb28181.bean;
|
||||||
|
|
||||||
import gov.nist.javax.sip.message.SIPRequest;
|
import gov.nist.javax.sip.message.SIPRequest;
|
||||||
|
import gov.nist.javax.sip.message.SIPResponse;
|
||||||
|
|
||||||
public class SipTransactionInfo {
|
public class SipTransactionInfo {
|
||||||
|
|
||||||
@ -9,11 +10,11 @@ public class SipTransactionInfo {
|
|||||||
private String toTag;
|
private String toTag;
|
||||||
private String viaBranch;
|
private String viaBranch;
|
||||||
|
|
||||||
public SipTransactionInfo(SIPRequest request) {
|
public SipTransactionInfo(SIPResponse response) {
|
||||||
this.callId = request.getCallIdHeader().getCallId();
|
this.callId = response.getCallIdHeader().getCallId();
|
||||||
this.fromTag = request.getFromTag();
|
this.fromTag = response.getFromTag();
|
||||||
this.toTag = request.getToTag();
|
this.toTag = response.getToTag();
|
||||||
this.viaBranch = request.getTopmostViaHeader().getBranch();
|
this.viaBranch = response.getTopmostViaHeader().getBranch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SipTransactionInfo() {
|
public SipTransactionInfo() {
|
||||||
|
@ -8,10 +8,11 @@ public class SsrcTransaction {
|
|||||||
private String channelId;
|
private String channelId;
|
||||||
private String callId;
|
private String callId;
|
||||||
private String stream;
|
private String stream;
|
||||||
private byte[] transaction;
|
|
||||||
private byte[] dialog;
|
|
||||||
private String mediaServerId;
|
private String mediaServerId;
|
||||||
private String ssrc;
|
private String ssrc;
|
||||||
|
|
||||||
|
private SipTransactionInfo sipTransactionInfo;
|
||||||
|
|
||||||
private VideoStreamSessionManager.SessionType type;
|
private VideoStreamSessionManager.SessionType type;
|
||||||
|
|
||||||
public String getDeviceId() {
|
public String getDeviceId() {
|
||||||
@ -46,22 +47,6 @@ public class SsrcTransaction {
|
|||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getTransaction() {
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransaction(byte[] transaction) {
|
|
||||||
this.transaction = transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getDialog() {
|
|
||||||
return dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDialog(byte[] dialog) {
|
|
||||||
this.dialog = dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMediaServerId() {
|
public String getMediaServerId() {
|
||||||
return mediaServerId;
|
return mediaServerId;
|
||||||
}
|
}
|
||||||
@ -85,4 +70,12 @@ public class SsrcTransaction {
|
|||||||
public void setType(VideoStreamSessionManager.SessionType type) {
|
public void setType(VideoStreamSessionManager.SessionType type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SipTransactionInfo getSipTransactionInfo() {
|
||||||
|
return sipTransactionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
|
||||||
|
this.sipTransactionInfo = sipTransactionInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.bean;
|
package com.genersoft.iot.vmp.gb28181.bean;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.utils.SerializeUtils;
|
|
||||||
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 javax.sip.ClientTransaction;
|
|
||||||
import javax.sip.Dialog;
|
|
||||||
import javax.sip.RequestEvent;
|
|
||||||
import javax.sip.ServerTransaction;
|
import javax.sip.ServerTransaction;
|
||||||
import javax.sip.header.*;
|
import javax.sip.header.*;
|
||||||
import javax.sip.message.Request;
|
|
||||||
|
|
||||||
public class SubscribeInfo {
|
public class SubscribeInfo {
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import org.springframework.stereotype.Component;
|
|||||||
import javax.sip.*;
|
import javax.sip.*;
|
||||||
import javax.sip.header.CallIdHeader;
|
import javax.sip.header.CallIdHeader;
|
||||||
import javax.sip.message.Response;
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -56,8 +57,7 @@ public class SipSubscribe {
|
|||||||
logger.debug("errorSubscribes.size:{}",errorSubscribes.size());
|
logger.debug("errorSubscribes.size:{}",errorSubscribes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Event {
|
public interface Event { void response(EventResult eventResult) ;
|
||||||
void response(EventResult eventResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,18 +81,13 @@ public class SipSubscribe {
|
|||||||
public EventResultType type;
|
public EventResultType type;
|
||||||
public String msg;
|
public String msg;
|
||||||
public String callId;
|
public String callId;
|
||||||
public Dialog dialog;
|
|
||||||
public EventObject event;
|
public EventObject event;
|
||||||
|
|
||||||
public EventResult() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public EventResult(EventObject event) {
|
public EventResult(EventObject event) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
if (event instanceof ResponseEvent) {
|
if (event instanceof ResponseEvent) {
|
||||||
ResponseEvent responseEvent = (ResponseEvent)event;
|
ResponseEvent responseEvent = (ResponseEvent)event;
|
||||||
Response response = responseEvent.getResponse();
|
Response response = responseEvent.getResponse();
|
||||||
this.dialog = responseEvent.getDialog();
|
|
||||||
this.type = EventResultType.response;
|
this.type = EventResultType.response;
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
this.msg = response.getReasonPhrase();
|
this.msg = response.getReasonPhrase();
|
||||||
@ -127,12 +122,10 @@ public class SipSubscribe {
|
|||||||
this.statusCode = -1024;
|
this.statusCode = -1024;
|
||||||
this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId();
|
this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId();
|
||||||
}else if (event instanceof DeviceNotFoundEvent) {
|
}else if (event instanceof DeviceNotFoundEvent) {
|
||||||
DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event;
|
|
||||||
this.type = EventResultType.deviceNotFoundEvent;
|
this.type = EventResultType.deviceNotFoundEvent;
|
||||||
this.msg = "设备未找到";
|
this.msg = "设备未找到";
|
||||||
this.statusCode = -1024;
|
this.statusCode = -1024;
|
||||||
this.dialog = deviceNotFoundEvent.getDialog();
|
this.callId = ((DeviceNotFoundEvent) event).getCallId();
|
||||||
this.callId = this.dialog != null ?deviceNotFoundEvent.getDialog().getCallId().getCallId() : null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ public class RequestTimeoutEventImpl implements ApplicationListener<RequestTimeo
|
|||||||
}
|
}
|
||||||
deviceService.offline(device.getDeviceId());
|
deviceService.offline(device.getDeviceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,7 +99,12 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
|
|||||||
}
|
}
|
||||||
if (deviceChannelList.size() > 0) {
|
if (deviceChannelList.size() > 0) {
|
||||||
logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
|
logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
|
||||||
sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
|
try {
|
||||||
|
sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
|
||||||
|
IllegalAccessException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else if (parentPlatformMap.keySet().size() > 0) {
|
}else if (parentPlatformMap.keySet().size() > 0) {
|
||||||
for (String gbId : parentPlatformMap.keySet()) {
|
for (String gbId : parentPlatformMap.keySet()) {
|
||||||
@ -112,7 +120,12 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
|
|||||||
DeviceChannel deviceChannel = new DeviceChannel();
|
DeviceChannel deviceChannel = new DeviceChannel();
|
||||||
deviceChannel.setChannelId(gbId);
|
deviceChannel.setChannelId(gbId);
|
||||||
deviceChannelList.add(deviceChannel);
|
deviceChannelList.add(deviceChannel);
|
||||||
sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), platform, deviceChannelList, subscribeInfo, null);
|
try {
|
||||||
|
sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), platform, deviceChannelList, subscribeInfo, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
|
||||||
|
IllegalAccessException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +150,12 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
|
|||||||
}
|
}
|
||||||
if (deviceChannelList.size() > 0) {
|
if (deviceChannelList.size() > 0) {
|
||||||
logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
|
logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
|
||||||
sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
|
try {
|
||||||
|
sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
|
||||||
|
IllegalAccessException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else if (parentPlatformMap.keySet().size() > 0) {
|
}else if (parentPlatformMap.keySet().size() > 0) {
|
||||||
for (String gbId : parentPlatformMap.keySet()) {
|
for (String gbId : parentPlatformMap.keySet()) {
|
||||||
@ -157,7 +175,12 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
|
|||||||
DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStreamWithStatus(gbStream, gbStream.getCatalogId(), platform);
|
DeviceChannel deviceChannelByStream = gbStreamService.getDeviceChannelListByStreamWithStatus(gbStream, gbStream.getCatalogId(), platform);
|
||||||
deviceChannelList.add(deviceChannelByStream);
|
deviceChannelList.add(deviceChannelByStream);
|
||||||
}
|
}
|
||||||
sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), platform, deviceChannelList, subscribeInfo, null);
|
try {
|
||||||
|
sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), platform, deviceChannelList, subscribeInfo, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | NoSuchFieldException |
|
||||||
|
SipException | IllegalAccessException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,13 @@ import javax.sip.Dialog;
|
|||||||
|
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SipMsgInfo;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||||
import com.genersoft.iot.vmp.utils.SerializeUtils;
|
import com.genersoft.iot.vmp.utils.SerializeUtils;
|
||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
|
import gov.nist.javax.sip.message.SIPRequest;
|
||||||
|
import gov.nist.javax.sip.message.SIPResponse;
|
||||||
import gov.nist.javax.sip.stack.SIPDialog;
|
import gov.nist.javax.sip.stack.SIPDialog;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -42,15 +46,14 @@ public class VideoStreamSessionManager {
|
|||||||
* @param callId 一次请求的CallID
|
* @param callId 一次请求的CallID
|
||||||
* @param stream 流名称
|
* @param stream 流名称
|
||||||
* @param mediaServerId 所使用的流媒体ID
|
* @param mediaServerId 所使用的流媒体ID
|
||||||
* @param transaction 事务
|
* @param response 回复
|
||||||
*/
|
*/
|
||||||
public void put(String deviceId, String channelId, String callId, String stream, String ssrc, String mediaServerId, ClientTransaction transaction, SessionType type){
|
public void put(String deviceId, String channelId, String callId, String stream, String ssrc, String mediaServerId, SIPResponse response, SessionType type){
|
||||||
SsrcTransaction ssrcTransaction = new SsrcTransaction();
|
SsrcTransaction ssrcTransaction = new SsrcTransaction();
|
||||||
ssrcTransaction.setDeviceId(deviceId);
|
ssrcTransaction.setDeviceId(deviceId);
|
||||||
ssrcTransaction.setChannelId(channelId);
|
ssrcTransaction.setChannelId(channelId);
|
||||||
ssrcTransaction.setStream(stream);
|
ssrcTransaction.setStream(stream);
|
||||||
byte[] transactionByteArray = SerializeUtils.serialize(transaction);
|
ssrcTransaction.setSipTransactionInfo(new SipTransactionInfo(response));
|
||||||
ssrcTransaction.setTransaction(transactionByteArray);
|
|
||||||
ssrcTransaction.setCallId(callId);
|
ssrcTransaction.setCallId(callId);
|
||||||
ssrcTransaction.setSsrc(ssrc);
|
ssrcTransaction.setSsrc(ssrc);
|
||||||
ssrcTransaction.setMediaServerId(mediaServerId);
|
ssrcTransaction.setMediaServerId(mediaServerId);
|
||||||
@ -62,53 +65,6 @@ public class VideoStreamSessionManager {
|
|||||||
+ "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
|
+ "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(String deviceId, String channelId, String callId, Dialog dialog){
|
|
||||||
SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, callId, null);
|
|
||||||
if (ssrcTransaction != null) {
|
|
||||||
byte[] dialogByteArray = SerializeUtils.serialize(dialog);
|
|
||||||
ssrcTransaction.setDialog(dialogByteArray);
|
|
||||||
}
|
|
||||||
RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
|
|
||||||
+ "_" + deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_"
|
|
||||||
+ ssrcTransaction.getStream(), ssrcTransaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ClientTransaction getTransaction(String deviceId, String channelId, String stream, String callId){
|
|
||||||
SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, callId, stream);
|
|
||||||
if (ssrcTransaction == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
byte[] transactionByteArray = ssrcTransaction.getTransaction();
|
|
||||||
ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray);
|
|
||||||
return clientTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SIPDialog getDialogByStream(String deviceId, String channelId, String stream){
|
|
||||||
SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
|
|
||||||
if (ssrcTransaction == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
byte[] dialogByteArray = ssrcTransaction.getDialog();
|
|
||||||
if (dialogByteArray == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
SIPDialog dialog = (SIPDialog)SerializeUtils.deSerialize(dialogByteArray);
|
|
||||||
return dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SIPDialog getDialogByCallId(String deviceId, String channelId, String callId){
|
|
||||||
SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, callId, null);
|
|
||||||
if (ssrcTransaction == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
byte[] dialogByteArray = ssrcTransaction.getDialog();
|
|
||||||
if (dialogByteArray == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (SIPDialog)SerializeUtils.deSerialize(dialogByteArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SsrcTransaction getSsrcTransaction(String deviceId, String channelId, String callId, String stream){
|
public SsrcTransaction getSsrcTransaction(String deviceId, String channelId, String callId, String stream){
|
||||||
|
|
||||||
if (ObjectUtils.isEmpty(deviceId)) {
|
if (ObjectUtils.isEmpty(deviceId)) {
|
||||||
|
@ -10,9 +10,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
|
||||||
import javax.sip.Dialog;
|
import javax.sip.*;
|
||||||
import javax.sip.DialogState;
|
|
||||||
import javax.sip.ResponseEvent;
|
|
||||||
import javax.sip.header.ToHeader;
|
import javax.sip.header.ToHeader;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
@ -44,23 +42,29 @@ public class CatalogSubscribeTask implements ISubscribeTask {
|
|||||||
if (dynamicTask.get(taskKey) != null) {
|
if (dynamicTask.get(taskKey) != null) {
|
||||||
dynamicTask.stop(taskKey);
|
dynamicTask.stop(taskKey);
|
||||||
}
|
}
|
||||||
SIPRequest sipRequest = sipCommander.catalogSubscribe(device, request, eventResult -> {
|
SIPRequest sipRequest = null;
|
||||||
ResponseEvent event = (ResponseEvent) eventResult.event;
|
try {
|
||||||
// 成功
|
sipRequest = sipCommander.catalogSubscribe(device, request, eventResult -> {
|
||||||
logger.info("[目录订阅]成功: {}", device.getDeviceId());
|
ResponseEvent event = (ResponseEvent) eventResult.event;
|
||||||
ToHeader toHeader = (ToHeader)event.getResponse().getHeader(ToHeader.NAME);
|
// 成功
|
||||||
try {
|
logger.info("[目录订阅]成功: {}", device.getDeviceId());
|
||||||
this.request.getToHeader().setTag(toHeader.getTag());
|
ToHeader toHeader = (ToHeader)event.getResponse().getHeader(ToHeader.NAME);
|
||||||
} catch (ParseException e) {
|
try {
|
||||||
logger.info("[目录订阅]成功: 但为request设置ToTag失败");
|
this.request.getToHeader().setTag(toHeader.getTag());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
logger.info("[目录订阅]成功: 但为request设置ToTag失败");
|
||||||
|
this.request = null;
|
||||||
|
}
|
||||||
|
},eventResult -> {
|
||||||
this.request = null;
|
this.request = null;
|
||||||
}
|
// 失败
|
||||||
},eventResult -> {
|
logger.warn("[目录订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
|
||||||
this.request = null;
|
dynamicTask.startDelay(taskKey, CatalogSubscribeTask.this, 2000);
|
||||||
// 失败
|
});
|
||||||
logger.warn("[目录订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
dynamicTask.startDelay(taskKey, CatalogSubscribeTask.this, 2000);
|
logger.error("[命令发送失败] 目录订阅: {}", e.getMessage());
|
||||||
});
|
|
||||||
|
}
|
||||||
if (sipRequest != null) {
|
if (sipRequest != null) {
|
||||||
this.request = sipRequest;
|
this.request = sipRequest;
|
||||||
}
|
}
|
||||||
@ -80,18 +84,22 @@ public class CatalogSubscribeTask implements ISubscribeTask {
|
|||||||
dynamicTask.stop(taskKey);
|
dynamicTask.stop(taskKey);
|
||||||
}
|
}
|
||||||
device.setSubscribeCycleForCatalog(0);
|
device.setSubscribeCycleForCatalog(0);
|
||||||
sipCommander.catalogSubscribe(device, request, eventResult -> {
|
try {
|
||||||
ResponseEvent event = (ResponseEvent) eventResult.event;
|
sipCommander.catalogSubscribe(device, request, eventResult -> {
|
||||||
if (event.getResponse().getRawContent() != null) {
|
ResponseEvent event = (ResponseEvent) eventResult.event;
|
||||||
// 成功
|
if (event.getResponse().getRawContent() != null) {
|
||||||
logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId());
|
// 成功
|
||||||
}else {
|
logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId());
|
||||||
// 成功
|
}else {
|
||||||
logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId());
|
// 成功
|
||||||
}
|
logger.info("[取消目录订阅订阅]成功: {}", device.getDeviceId());
|
||||||
},eventResult -> {
|
}
|
||||||
// 失败
|
},eventResult -> {
|
||||||
logger.warn("[取消目录订阅订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
|
// 失败
|
||||||
});
|
logger.warn("[取消目录订阅订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 取消目录订阅订阅: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
|
||||||
import javax.sip.Dialog;
|
import javax.sip.*;
|
||||||
import javax.sip.DialogState;
|
|
||||||
import javax.sip.ResponseEvent;
|
|
||||||
import javax.sip.header.ToHeader;
|
import javax.sip.header.ToHeader;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
@ -43,23 +41,28 @@ public class MobilePositionSubscribeTask implements ISubscribeTask {
|
|||||||
if (dynamicTask.get(taskKey) != null) {
|
if (dynamicTask.get(taskKey) != null) {
|
||||||
dynamicTask.stop(taskKey);
|
dynamicTask.stop(taskKey);
|
||||||
}
|
}
|
||||||
SIPRequest sipRequest = sipCommander.mobilePositionSubscribe(device, request, eventResult -> {
|
SIPRequest sipRequest = null;
|
||||||
// 成功
|
try {
|
||||||
logger.info("[移动位置订阅]成功: {}", device.getDeviceId());
|
sipRequest = sipCommander.mobilePositionSubscribe(device, request, eventResult -> {
|
||||||
ResponseEvent event = (ResponseEvent) eventResult.event;
|
// 成功
|
||||||
ToHeader toHeader = (ToHeader)event.getResponse().getHeader(ToHeader.NAME);
|
logger.info("[移动位置订阅]成功: {}", device.getDeviceId());
|
||||||
try {
|
ResponseEvent event = (ResponseEvent) eventResult.event;
|
||||||
this.request.getToHeader().setTag(toHeader.getTag());
|
ToHeader toHeader = (ToHeader)event.getResponse().getHeader(ToHeader.NAME);
|
||||||
} catch (ParseException e) {
|
try {
|
||||||
logger.info("[移动位置订阅]成功: 为request设置ToTag失败");
|
this.request.getToHeader().setTag(toHeader.getTag());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
logger.info("[移动位置订阅]成功: 为request设置ToTag失败");
|
||||||
|
this.request = null;
|
||||||
|
}
|
||||||
|
},eventResult -> {
|
||||||
this.request = null;
|
this.request = null;
|
||||||
}
|
// 失败
|
||||||
},eventResult -> {
|
logger.warn("[移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
|
||||||
this.request = null;
|
dynamicTask.startDelay(taskKey, MobilePositionSubscribeTask.this, 2000);
|
||||||
// 失败
|
});
|
||||||
logger.warn("[移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
dynamicTask.startDelay(taskKey, MobilePositionSubscribeTask.this, 2000);
|
logger.error("[命令发送失败] 移动位置订阅: {}", e.getMessage());
|
||||||
});
|
}
|
||||||
if (sipRequest != null) {
|
if (sipRequest != null) {
|
||||||
this.request = sipRequest;
|
this.request = sipRequest;
|
||||||
}
|
}
|
||||||
@ -79,18 +82,22 @@ public class MobilePositionSubscribeTask implements ISubscribeTask {
|
|||||||
dynamicTask.stop(taskKey);
|
dynamicTask.stop(taskKey);
|
||||||
}
|
}
|
||||||
device.setSubscribeCycleForMobilePosition(0);
|
device.setSubscribeCycleForMobilePosition(0);
|
||||||
sipCommander.mobilePositionSubscribe(device, request, eventResult -> {
|
try {
|
||||||
ResponseEvent event = (ResponseEvent) eventResult.event;
|
sipCommander.mobilePositionSubscribe(device, request, eventResult -> {
|
||||||
if (event.getResponse().getRawContent() != null) {
|
ResponseEvent event = (ResponseEvent) eventResult.event;
|
||||||
// 成功
|
if (event.getResponse().getRawContent() != null) {
|
||||||
logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId());
|
// 成功
|
||||||
}else {
|
logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId());
|
||||||
// 成功
|
}else {
|
||||||
logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId());
|
// 成功
|
||||||
}
|
logger.info("[取消移动位置订阅]成功: {}", device.getDeviceId());
|
||||||
},eventResult -> {
|
}
|
||||||
// 失败
|
},eventResult -> {
|
||||||
logger.warn("[取消移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
|
// 失败
|
||||||
});
|
logger.warn("[取消移动位置订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 取消移动位置订阅: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.cmd;
|
package com.genersoft.iot.vmp.gb28181.transmit.cmd;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
||||||
@ -9,6 +10,11 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
|||||||
import gov.nist.javax.sip.message.SIPRequest;
|
import gov.nist.javax.sip.message.SIPRequest;
|
||||||
|
|
||||||
import javax.sip.Dialog;
|
import javax.sip.Dialog;
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.PeerUnavailableException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Request;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description:设备能力接口,用于定义设备的控制、查询能力
|
* @description:设备能力接口,用于定义设备的控制、查询能力
|
||||||
@ -25,7 +31,7 @@ public interface ISIPCommander {
|
|||||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||||
*/
|
*/
|
||||||
boolean ptzdirectCmd(Device device,String channelId,int leftRight, int upDown);
|
void ptzdirectCmd(Device device,String channelId,int leftRight, int upDown) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 云台方向放控制
|
* 云台方向放控制
|
||||||
@ -36,7 +42,7 @@ public interface ISIPCommander {
|
|||||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||||
* @param moveSpeed 镜头移动速度
|
* @param moveSpeed 镜头移动速度
|
||||||
*/
|
*/
|
||||||
boolean ptzdirectCmd(Device device,String channelId,int leftRight, int upDown, int moveSpeed);
|
void ptzdirectCmd(Device device,String channelId,int leftRight, int upDown, int moveSpeed) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 云台缩放控制,使用配置文件中的默认镜头缩放速度
|
* 云台缩放控制,使用配置文件中的默认镜头缩放速度
|
||||||
@ -45,7 +51,7 @@ public interface ISIPCommander {
|
|||||||
* @param channelId 预览通道
|
* @param channelId 预览通道
|
||||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||||
*/
|
*/
|
||||||
boolean ptzZoomCmd(Device device,String channelId,int inOut);
|
void ptzZoomCmd(Device device,String channelId,int inOut) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 云台缩放控制
|
* 云台缩放控制
|
||||||
@ -54,7 +60,7 @@ public interface ISIPCommander {
|
|||||||
* @param channelId 预览通道
|
* @param channelId 预览通道
|
||||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||||
*/
|
*/
|
||||||
boolean ptzZoomCmd(Device device,String channelId,int inOut, int moveSpeed);
|
void ptzZoomCmd(Device device,String channelId,int inOut, int moveSpeed) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 云台控制,支持方向与缩放控制
|
* 云台控制,支持方向与缩放控制
|
||||||
@ -67,7 +73,7 @@ public interface ISIPCommander {
|
|||||||
* @param moveSpeed 镜头移动速度
|
* @param moveSpeed 镜头移动速度
|
||||||
* @param zoomSpeed 镜头缩放速度
|
* @param zoomSpeed 镜头缩放速度
|
||||||
*/
|
*/
|
||||||
boolean ptzCmd(Device device,String channelId,int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed);
|
void ptzCmd(Device device,String channelId,int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前端控制,包括PTZ指令、FI指令、预置位指令、巡航指令、扫描指令和辅助开关指令
|
* 前端控制,包括PTZ指令、FI指令、预置位指令、巡航指令、扫描指令和辅助开关指令
|
||||||
@ -79,7 +85,7 @@ public interface ISIPCommander {
|
|||||||
* @param parameter2 数据2
|
* @param parameter2 数据2
|
||||||
* @param combineCode2 组合码2
|
* @param combineCode2 组合码2
|
||||||
*/
|
*/
|
||||||
boolean frontEndCmd(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combineCode2);
|
void frontEndCmd(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combineCode2) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前端控制指令(用于转发上级指令)
|
* 前端控制指令(用于转发上级指令)
|
||||||
@ -87,14 +93,14 @@ public interface ISIPCommander {
|
|||||||
* @param channelId 预览通道
|
* @param channelId 预览通道
|
||||||
* @param cmdString 前端控制指令串
|
* @param cmdString 前端控制指令串
|
||||||
*/
|
*/
|
||||||
boolean fronEndCmd(Device device, String channelId, String cmdString, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent);
|
void fronEndCmd(Device device, String channelId, String cmdString, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求预览视频流
|
* 请求预览视频流
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
* @param channelId 预览通道
|
* @param channelId 预览通道
|
||||||
*/
|
*/
|
||||||
void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent);
|
void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求回放视频流
|
* 请求回放视频流
|
||||||
@ -104,7 +110,7 @@ public interface ISIPCommander {
|
|||||||
* @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss
|
* @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss
|
||||||
* @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
|
* @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
|
||||||
*/
|
*/
|
||||||
void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,InviteStreamCallback inviteStreamCallback, InviteStreamCallback event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent);
|
void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,InviteStreamCallback inviteStreamCallback, InviteStreamCallback event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求历史媒体下载
|
* 请求历史媒体下载
|
||||||
@ -117,33 +123,33 @@ public interface ISIPCommander {
|
|||||||
*/
|
*/
|
||||||
void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
|
void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
|
||||||
String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent,
|
String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent,
|
||||||
SipSubscribe.Event errorEvent);
|
SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 视频流停止
|
* 视频流停止
|
||||||
*/
|
*/
|
||||||
void streamByeCmd(String deviceId, String channelId, String stream, String callId, SipSubscribe.Event okEvent);
|
void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException;
|
||||||
void streamByeCmd(String deviceId, String channelId, String stream, String callId);
|
void streamByeCmd(Device device, String channelId, String stream, String callId) throws InvalidArgumentException, ParseException, SipException, SsrcTransactionNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回放暂停
|
* 回放暂停
|
||||||
*/
|
*/
|
||||||
void playPauseCmd(Device device, StreamInfo streamInfo);
|
void playPauseCmd(Device device, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回放恢复
|
* 回放恢复
|
||||||
*/
|
*/
|
||||||
void playResumeCmd(Device device, StreamInfo streamInfo);
|
void playResumeCmd(Device device, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回放拖动播放
|
* 回放拖动播放
|
||||||
*/
|
*/
|
||||||
void playSeekCmd(Device device, StreamInfo streamInfo, long seekTime);
|
void playSeekCmd(Device device, StreamInfo streamInfo, long seekTime) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回放倍速播放
|
* 回放倍速播放
|
||||||
*/
|
*/
|
||||||
void playSpeedCmd(Device device, StreamInfo streamInfo, Double speed);
|
void playSpeedCmd(Device device, StreamInfo streamInfo, Double speed) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回放控制
|
* 回放控制
|
||||||
@ -151,23 +157,24 @@ public interface ISIPCommander {
|
|||||||
* @param streamInfo
|
* @param streamInfo
|
||||||
* @param content
|
* @param content
|
||||||
*/
|
*/
|
||||||
void playbackControlCmd(Device device, StreamInfo streamInfo, String content,SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent);
|
void playbackControlCmd(Device device, StreamInfo streamInfo, String content,SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* 语音广播
|
* 语音广播
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
* @param channelId 预览通道
|
* @param channelId 预览通道
|
||||||
*/
|
*/
|
||||||
boolean audioBroadcastCmd(Device device,String channelId);
|
void audioBroadcastCmd(Device device,String channelId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 语音广播
|
* 语音广播
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
*/
|
*/
|
||||||
void audioBroadcastCmd(Device device, SipSubscribe.Event okEvent);
|
void audioBroadcastCmd(Device device, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
boolean audioBroadcastCmd(Device device);
|
void audioBroadcastCmd(Device device) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 音视频录像控制
|
* 音视频录像控制
|
||||||
@ -176,21 +183,21 @@ public interface ISIPCommander {
|
|||||||
* @param channelId 预览通道
|
* @param channelId 预览通道
|
||||||
* @param recordCmdStr 录像命令:Record / StopRecord
|
* @param recordCmdStr 录像命令:Record / StopRecord
|
||||||
*/
|
*/
|
||||||
boolean recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent);
|
void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程启动控制命令
|
* 远程启动控制命令
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
*/
|
*/
|
||||||
boolean teleBootCmd(Device device);
|
void teleBootCmd(Device device) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报警布防/撤防命令
|
* 报警布防/撤防命令
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
*/
|
*/
|
||||||
boolean guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent);
|
void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 报警复位命令
|
* 报警复位命令
|
||||||
@ -199,7 +206,7 @@ public interface ISIPCommander {
|
|||||||
* @param alarmMethod 报警方式(可选)
|
* @param alarmMethod 报警方式(可选)
|
||||||
* @param alarmType 报警类型(可选)
|
* @param alarmType 报警类型(可选)
|
||||||
*/
|
*/
|
||||||
boolean alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent);
|
void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
|
* 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
|
||||||
@ -207,7 +214,7 @@ public interface ISIPCommander {
|
|||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
* @param channelId 预览通道
|
* @param channelId 预览通道
|
||||||
*/
|
*/
|
||||||
boolean iFrameCmd(Device device, String channelId);
|
void iFrameCmd(Device device, String channelId) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 看守位控制命令
|
* 看守位控制命令
|
||||||
@ -217,14 +224,14 @@ public interface ISIPCommander {
|
|||||||
* @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
|
* @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
|
||||||
* @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
|
* @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
|
||||||
*/
|
*/
|
||||||
boolean homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent);
|
void homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设备配置命令
|
* 设备配置命令
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
*/
|
*/
|
||||||
boolean deviceConfigCmd(Device device);
|
void deviceConfigCmd(Device device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设备配置命令:basicParam
|
* 设备配置命令:basicParam
|
||||||
@ -236,14 +243,14 @@ public interface ISIPCommander {
|
|||||||
* @param heartBeatInterval 心跳间隔时间(可选)
|
* @param heartBeatInterval 心跳间隔时间(可选)
|
||||||
* @param heartBeatCount 心跳超时次数(可选)
|
* @param heartBeatCount 心跳超时次数(可选)
|
||||||
*/
|
*/
|
||||||
boolean deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent);
|
void deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询设备状态
|
* 查询设备状态
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
*/
|
*/
|
||||||
boolean deviceStatusQuery(Device device, SipSubscribe.Event errorEvent);
|
void deviceStatusQuery(Device device, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询设备信息
|
* 查询设备信息
|
||||||
@ -251,14 +258,14 @@ public interface ISIPCommander {
|
|||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean deviceInfoQuery(Device device);
|
void deviceInfoQuery(Device device) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询目录列表
|
* 查询目录列表
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
*/
|
*/
|
||||||
boolean catalogQuery(Device device, int sn, SipSubscribe.Event errorEvent);
|
void catalogQuery(Device device, int sn, SipSubscribe.Event errorEvent) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询录像信息
|
* 查询录像信息
|
||||||
@ -268,7 +275,7 @@ public interface ISIPCommander {
|
|||||||
* @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
|
* @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
|
||||||
* @param sn
|
* @param sn
|
||||||
*/
|
*/
|
||||||
boolean recordInfoQuery(Device device, String channelId, String startTime, String endTime, int sn, Integer Secrecy, String type, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent);
|
void recordInfoQuery(Device device, String channelId, String startTime, String endTime, int sn, Integer Secrecy, String type, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询报警信息
|
* 查询报警信息
|
||||||
@ -282,8 +289,8 @@ public interface ISIPCommander {
|
|||||||
* @param endTime 报警发生终止时间(可选)
|
* @param endTime 报警发生终止时间(可选)
|
||||||
* @return true = 命令发送成功
|
* @return true = 命令发送成功
|
||||||
*/
|
*/
|
||||||
boolean alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod,
|
void alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod,
|
||||||
String alarmType, String startTime, String endTime, SipSubscribe.Event errorEvent);
|
String alarmType, String startTime, String endTime, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询设备配置
|
* 查询设备配置
|
||||||
@ -292,21 +299,21 @@ public interface ISIPCommander {
|
|||||||
* @param channelId 通道编码(可选)
|
* @param channelId 通道编码(可选)
|
||||||
* @param configType 配置类型:
|
* @param configType 配置类型:
|
||||||
*/
|
*/
|
||||||
boolean deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent);
|
void deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询设备预置位置
|
* 查询设备预置位置
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
*/
|
*/
|
||||||
boolean presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent);
|
void presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询移动设备位置数据
|
* 查询移动设备位置数据
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
*/
|
*/
|
||||||
boolean mobilePostitionQuery(Device device, SipSubscribe.Event errorEvent);
|
void mobilePostitionQuery(Device device, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订阅、取消订阅移动位置
|
* 订阅、取消订阅移动位置
|
||||||
@ -314,7 +321,7 @@ public interface ISIPCommander {
|
|||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
* @return true = 命令发送成功
|
* @return true = 命令发送成功
|
||||||
*/
|
*/
|
||||||
SIPRequest mobilePositionSubscribe(Device device, SIPRequest request, SipSubscribe.Event okEvent , SipSubscribe.Event errorEvent);
|
SIPRequest mobilePositionSubscribe(Device device, SIPRequest request, SipSubscribe.Event okEvent , SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订阅、取消订阅报警信息
|
* 订阅、取消订阅报警信息
|
||||||
@ -327,14 +334,14 @@ public interface ISIPCommander {
|
|||||||
* @param endTime 报警发生终止时间(可选)
|
* @param endTime 报警发生终止时间(可选)
|
||||||
* @return true = 命令发送成功
|
* @return true = 命令发送成功
|
||||||
*/
|
*/
|
||||||
boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
|
void alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订阅、取消订阅目录信息
|
* 订阅、取消订阅目录信息
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
* @return true = 命令发送成功
|
* @return true = 命令发送成功
|
||||||
*/
|
*/
|
||||||
SIPRequest catalogSubscribe(Device device, SIPRequest request, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent);
|
SIPRequest catalogSubscribe(Device device, SIPRequest request, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拉框控制命令
|
* 拉框控制命令
|
||||||
@ -343,7 +350,7 @@ public interface ISIPCommander {
|
|||||||
* @param channelId 通道id
|
* @param channelId 通道id
|
||||||
* @param cmdString 前端控制指令串
|
* @param cmdString 前端控制指令串
|
||||||
*/
|
*/
|
||||||
boolean dragZoomCmd(Device device, String channelId, String cmdString);
|
void dragZoomCmd(Device device, String channelId, String cmdString) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -352,5 +359,11 @@ public interface ISIPCommander {
|
|||||||
* @param deviceAlarm 报警信息信息
|
* @param deviceAlarm 报警信息信息
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean sendAlarmMessage(Device device, DeviceAlarm deviceAlarm);
|
void sendAlarmMessage(Device device, DeviceAlarm deviceAlarm) throws InvalidArgumentException, SipException, ParseException;
|
||||||
|
|
||||||
|
void transmitRequest(String transport, Request request) throws SipException, ParseException ;
|
||||||
|
|
||||||
|
void transmitRequest(String transport, Request request, SipSubscribe.Event errorEvent) throws SipException, ParseException;
|
||||||
|
|
||||||
|
void transmitRequest(String transport, Request request, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException, ParseException;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,10 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
|
|||||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||||
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
|
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
import javax.sip.header.WWWAuthenticateHeader;
|
import javax.sip.header.WWWAuthenticateHeader;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface ISIPCommanderForPlatform {
|
public interface ISIPCommanderForPlatform {
|
||||||
@ -14,15 +17,15 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param parentPlatform
|
* @param parentPlatform
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent);
|
void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException;
|
||||||
boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister);
|
void register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向上级平台注销
|
* 向上级平台注销
|
||||||
* @param parentPlatform
|
* @param parentPlatform
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent);
|
void unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,7 +33,7 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param parentPlatform
|
* @param parentPlatform
|
||||||
* @return callId(作为接受回复的判定)
|
* @return callId(作为接受回复的判定)
|
||||||
*/
|
*/
|
||||||
String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent);
|
String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,8 +45,8 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param size
|
* @param size
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size);
|
void catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size) throws SipException, InvalidArgumentException, ParseException;
|
||||||
boolean catalogQuery(List<DeviceChannel> channels, ParentPlatform parentPlatform, String sn, String fromTag);
|
void catalogQuery(List<DeviceChannel> channels, ParentPlatform parentPlatform, String sn, String fromTag) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向上级回复DeviceInfo查询信息
|
* 向上级回复DeviceInfo查询信息
|
||||||
@ -52,7 +55,7 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param fromTag
|
* @param fromTag
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean deviceInfoResponse(ParentPlatform parentPlatform, String sn, String fromTag);
|
void deviceInfoResponse(ParentPlatform parentPlatform, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向上级回复DeviceStatus查询信息
|
* 向上级回复DeviceStatus查询信息
|
||||||
@ -61,7 +64,7 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param fromTag
|
* @param fromTag
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag);
|
void deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向上级回复移动位置订阅消息
|
* 向上级回复移动位置订阅消息
|
||||||
@ -70,7 +73,7 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param subscribeInfo 订阅相关的信息
|
* @param subscribeInfo 订阅相关的信息
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean sendNotifyMobilePosition(ParentPlatform parentPlatform, GPSMsgInfo gpsMsgInfo, SubscribeInfo subscribeInfo);
|
void sendNotifyMobilePosition(ParentPlatform parentPlatform, GPSMsgInfo gpsMsgInfo, SubscribeInfo subscribeInfo) throws InvalidArgumentException, ParseException, NoSuchFieldException, SipException, IllegalAccessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向上级回复报警消息
|
* 向上级回复报警消息
|
||||||
@ -78,21 +81,21 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param deviceAlarm 报警信息信息
|
* @param deviceAlarm 报警信息信息
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean sendAlarmMessage(ParentPlatform parentPlatform, DeviceAlarm deviceAlarm);
|
void sendAlarmMessage(ParentPlatform parentPlatform, DeviceAlarm deviceAlarm) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复catalog事件-增加/更新
|
* 回复catalog事件-增加/更新
|
||||||
* @param parentPlatform
|
* @param parentPlatform
|
||||||
* @param deviceChannels
|
* @param deviceChannels
|
||||||
*/
|
*/
|
||||||
boolean sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index);
|
void sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) throws InvalidArgumentException, ParseException, NoSuchFieldException, SipException, IllegalAccessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复catalog事件-删除
|
* 回复catalog事件-删除
|
||||||
* @param parentPlatform
|
* @param parentPlatform
|
||||||
* @param deviceChannels
|
* @param deviceChannels
|
||||||
*/
|
*/
|
||||||
boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index);
|
void sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) throws InvalidArgumentException, ParseException, NoSuchFieldException, SipException, IllegalAccessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回复recordInfo
|
* 回复recordInfo
|
||||||
@ -101,7 +104,7 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param fromTag fromTag
|
* @param fromTag fromTag
|
||||||
* @param recordInfo 录像信息
|
* @param recordInfo 录像信息
|
||||||
*/
|
*/
|
||||||
boolean recordInfo(DeviceChannel deviceChannel, ParentPlatform parentPlatform, String fromTag, RecordInfo recordInfo);
|
void recordInfo(DeviceChannel deviceChannel, ParentPlatform parentPlatform, String fromTag, RecordInfo recordInfo) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 录像播放推送完成时发送MediaStatus消息
|
* 录像播放推送完成时发送MediaStatus消息
|
||||||
@ -109,13 +112,13 @@ public interface ISIPCommanderForPlatform {
|
|||||||
* @param sendRtpItem
|
* @param sendRtpItem
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean sendMediaStatusNotify(ParentPlatform platform, SendRtpItem sendRtpItem);
|
void sendMediaStatusNotify(ParentPlatform platform, SendRtpItem sendRtpItem) throws SipException, InvalidArgumentException, ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向发起点播的上级回复bye
|
* 向发起点播的上级回复bye
|
||||||
* @param platform 平台信息
|
* @param platform 平台信息
|
||||||
* @param callId callId
|
* @param callId callId
|
||||||
*/
|
*/
|
||||||
void streamByeCmd(ParentPlatform platform, String callId);
|
void streamByeCmd(ParentPlatform platform, String callId) throws SipException, InvalidArgumentException, ParseException;
|
||||||
void streamByeCmd(ParentPlatform platform, SendRtpItem sendRtpItem);
|
void streamByeCmd(ParentPlatform platform, SendRtpItem sendRtpItem) throws SipException, InvalidArgumentException, ParseException;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@ import javax.sip.header.*;
|
|||||||
import javax.sip.message.Request;
|
import javax.sip.message.Request;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SipMsgInfo;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
@ -17,6 +20,7 @@ import com.genersoft.iot.vmp.utils.GitUtil;
|
|||||||
import gov.nist.javax.sip.SipProviderImpl;
|
import gov.nist.javax.sip.SipProviderImpl;
|
||||||
import gov.nist.javax.sip.SipStackImpl;
|
import gov.nist.javax.sip.SipStackImpl;
|
||||||
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.stack.SIPDialog;
|
import gov.nist.javax.sip.stack.SIPDialog;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
@ -168,34 +172,37 @@ public class SIPRequestHeaderProvider {
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Request createByteRequest(Device device, String channelId, String viaTag, String fromTag, String toTag, String callId) throws ParseException, InvalidArgumentException, PeerUnavailableException {
|
public Request createByteRequest(Device device, String channelId, SipTransactionInfo transactionInfo) throws ParseException, InvalidArgumentException, PeerUnavailableException {
|
||||||
Request request = null;
|
Request request = null;
|
||||||
//请求行
|
//请求行
|
||||||
SipURI requestLine = sipFactory.createAddressFactory().createSipURI(channelId, device.getHostAddress());
|
SipURI requestLine = sipFactory.createAddressFactory().createSipURI(channelId, device.getHostAddress());
|
||||||
// via
|
// via
|
||||||
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
||||||
ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), device.getTransport(), viaTag);
|
ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), device.getTransport(), SipUtils.getNewViaTag());
|
||||||
viaHeaders.add(viaHeader);
|
viaHeaders.add(viaHeader);
|
||||||
//from
|
//from
|
||||||
SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain());
|
SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain());
|
||||||
Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
|
Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
|
||||||
FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack
|
FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, transactionInfo.getFromTag());
|
||||||
//to
|
//to
|
||||||
SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId,device.getHostAddress());
|
SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId,device.getHostAddress());
|
||||||
Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
|
Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
|
||||||
ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress,toTag);
|
ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, transactionInfo.getToTag());
|
||||||
|
|
||||||
//Forwards
|
//Forwards
|
||||||
MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
|
MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
|
||||||
|
|
||||||
//ceq
|
//ceq
|
||||||
CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE);
|
CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE);
|
||||||
CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(callId);
|
CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(transactionInfo.getCallId());
|
||||||
request = sipFactory.createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
|
request = sipFactory.createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
|
||||||
|
|
||||||
request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
|
request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
|
||||||
|
|
||||||
Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
|
Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
|
||||||
|
request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
|
||||||
|
|
||||||
|
request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
@ -251,47 +258,72 @@ public class SIPRequestHeaderProvider {
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Request createInfoRequest(Device device, StreamInfo streamInfo, String content)
|
public SIPRequest createInfoRequest(Device device, String channelId, String content, SipTransactionInfo transactionInfo)
|
||||||
throws SipException, ParseException, InvalidArgumentException {
|
throws SipException, ParseException, InvalidArgumentException {
|
||||||
if (streamInfo == null) {
|
if (device == null || transactionInfo == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Request request = null;
|
SIPRequest request = null;
|
||||||
SIPDialog dialog = streamSession.getDialogByStream(streamInfo.getDeviceID(), streamInfo.getChannelId(), streamInfo.getStream());
|
//请求行
|
||||||
if (dialog == null) {
|
SipURI requestLine = sipFactory.createAddressFactory().createSipURI(channelId, device.getHostAddress());
|
||||||
return null;
|
// via
|
||||||
|
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
||||||
|
ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), device.getTransport(), SipUtils.getNewViaTag());
|
||||||
|
viaHeaders.add(viaHeader);
|
||||||
|
//from
|
||||||
|
SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain());
|
||||||
|
Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
|
||||||
|
FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, transactionInfo.getFromTag());
|
||||||
|
//to
|
||||||
|
SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(channelId,device.getHostAddress());
|
||||||
|
Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
|
||||||
|
ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, transactionInfo.getToTag());
|
||||||
|
|
||||||
|
//Forwards
|
||||||
|
MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
|
||||||
|
|
||||||
|
//ceq
|
||||||
|
CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.INFO);
|
||||||
|
CallIdHeader callIdHeader = sipFactory.createHeaderFactory().createCallIdHeader(transactionInfo.getCallId());
|
||||||
|
request = (SIPRequest)sipFactory.createMessageFactory().createRequest(requestLine, Request.INFO, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
|
||||||
|
|
||||||
|
request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
|
||||||
|
|
||||||
|
Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
|
||||||
|
request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
|
||||||
|
|
||||||
|
request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
|
||||||
|
|
||||||
|
if (content != null) {
|
||||||
|
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application",
|
||||||
|
"MANSRTSP");
|
||||||
|
request.setContent(content, contentTypeHeader);
|
||||||
}
|
}
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
SipStack sipStack = udpSipProvider.getSipStack();
|
public Request createAckRequest(SipURI sipURI, SIPResponse sipResponse) throws ParseException, InvalidArgumentException, PeerUnavailableException {
|
||||||
SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog);
|
|
||||||
if (dialog != sipDialog) {
|
|
||||||
dialog = sipDialog;
|
|
||||||
}else {
|
|
||||||
dialog.setSipProvider(udpSipProvider);
|
|
||||||
}
|
|
||||||
streamSession.put(streamInfo.getDeviceID(), streamInfo.getChannelId(), dialog.getCallId().getCallId(), dialog);
|
|
||||||
Request infoRequest = dialog.createRequest(Request.INFO);
|
|
||||||
SipURI sipURI = (SipURI) infoRequest.getRequestURI();
|
|
||||||
sipURI.setHost(device.getIp());
|
|
||||||
sipURI.setPort(device.getPort());
|
|
||||||
sipURI.setUser(streamInfo.getChannelId());
|
|
||||||
|
|
||||||
ViaHeader viaHeader = (ViaHeader) infoRequest.getHeader(ViaHeader.NAME);
|
// via
|
||||||
viaHeader.setRPort();
|
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
||||||
// 增加Contact header
|
ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), sipResponse.getTopmostViaHeader().getTransport(), SipUtils.getNewViaTag());
|
||||||
Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory()
|
viaHeaders.add(viaHeader);
|
||||||
.createSipURI(sipConfig.getId(), sipConfig.getIp() + ":" + sipConfig.getPort()));
|
|
||||||
infoRequest.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
|
|
||||||
infoRequest.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
|
|
||||||
|
|
||||||
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application",
|
//Forwards
|
||||||
"MANSRTSP");
|
MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
|
||||||
infoRequest.setContent(content, contentTypeHeader);
|
|
||||||
|
|
||||||
CSeqHeader cSeqHeader = (CSeqHeader)infoRequest.getHeader(CSeqHeader.NAME);
|
//ceq
|
||||||
cSeqHeader.setSeqNumber(redisCatchStorage.getCSEQ());
|
CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(sipResponse.getCSeqHeader().getSeqNumber(), Request.ACK);
|
||||||
// ceq
|
|
||||||
infoRequest.addHeader(cSeqHeader);
|
Request request = sipFactory.createMessageFactory().createRequest(sipURI, Request.ACK, sipResponse.getCallIdHeader(), cSeqHeader, sipResponse.getFromHeader(), sipResponse.getToHeader(), viaHeaders, maxForwards);
|
||||||
return infoRequest;
|
|
||||||
|
request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
|
||||||
|
|
||||||
|
Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
|
||||||
|
request.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
|
||||||
|
|
||||||
|
request.addHeader(SipUtils.createUserAgentHeader(sipFactory, gitUtil));
|
||||||
|
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -13,12 +13,13 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
|||||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
|
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
|
import com.genersoft.iot.vmp.utils.GitUtil;
|
||||||
import com.genersoft.iot.vmp.utils.SerializeUtils;
|
import com.genersoft.iot.vmp.utils.SerializeUtils;
|
||||||
|
import gov.nist.javax.sip.SIPConstants;
|
||||||
import gov.nist.javax.sip.SipProviderImpl;
|
import gov.nist.javax.sip.SipProviderImpl;
|
||||||
import gov.nist.javax.sip.SipStackImpl;
|
import gov.nist.javax.sip.SipStackImpl;
|
||||||
import gov.nist.javax.sip.message.MessageFactoryImpl;
|
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.stack.SIPDialog;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -26,17 +27,15 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
|||||||
import org.springframework.context.annotation.DependsOn;
|
import org.springframework.context.annotation.DependsOn;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import javax.sip.*;
|
import javax.sip.*;
|
||||||
import javax.sip.address.SipURI;
|
|
||||||
import javax.sip.header.*;
|
import javax.sip.header.*;
|
||||||
import javax.sip.message.Request;
|
import javax.sip.message.Request;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ -77,19 +76,18 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
private SubscribeHolder subscribeHolder;
|
private SubscribeHolder subscribeHolder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
|
public void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
|
||||||
return register(parentPlatform, null, null, errorEvent, okEvent, false, true);
|
register(parentPlatform, null, null, errorEvent, okEvent, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
|
public void unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
|
||||||
return register(parentPlatform, null, null, errorEvent, okEvent, false, false);
|
register(parentPlatform, null, null, errorEvent, okEvent, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www,
|
public void register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www,
|
||||||
SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) {
|
SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException {
|
||||||
try {
|
|
||||||
Request request;
|
Request request;
|
||||||
if (!registerAgain ) {
|
if (!registerAgain ) {
|
||||||
CallIdHeader callIdHeader = null;
|
CallIdHeader callIdHeader = null;
|
||||||
@ -126,23 +124,10 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
transmitRequest(parentPlatform, request, null, okEvent);
|
transmitRequest(parentPlatform, request, null, okEvent);
|
||||||
return true;
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (PeerUnavailableException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (SipException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
|
public String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException {
|
||||||
String callId = null;
|
|
||||||
try {
|
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
StringBuffer keepaliveXml = new StringBuffer(200);
|
StringBuffer keepaliveXml = new StringBuffer(200);
|
||||||
keepaliveXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
keepaliveXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||||
@ -163,11 +148,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
SipUtils.getNewViaTag(),
|
SipUtils.getNewViaTag(),
|
||||||
callIdHeader);
|
callIdHeader);
|
||||||
transmitRequest(parentPlatform, request, errorEvent, okEvent);
|
transmitRequest(parentPlatform, request, errorEvent, okEvent);
|
||||||
callId = callIdHeader.getCallId();
|
return callIdHeader.getCallId();
|
||||||
} catch (ParseException | InvalidArgumentException | SipException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return callId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transmitRequest(ParentPlatform parentPlatform, Request request) throws SipException {
|
private void transmitRequest(ParentPlatform parentPlatform, Request request) throws SipException {
|
||||||
@ -206,39 +187,32 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size) {
|
public void catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size) throws SipException, InvalidArgumentException, ParseException {
|
||||||
|
|
||||||
if ( parentPlatform ==null) {
|
if ( parentPlatform ==null) {
|
||||||
return false;
|
return ;
|
||||||
}
|
}
|
||||||
try {
|
List<DeviceChannel> channels = new ArrayList<>();
|
||||||
List<DeviceChannel> channels = new ArrayList<>();
|
if (channel != null) {
|
||||||
if (channel != null) {
|
channels.add(channel);
|
||||||
channels.add(channel);
|
|
||||||
}
|
|
||||||
String catalogXml = getCatalogXml(channels, sn, parentPlatform, size);
|
|
||||||
|
|
||||||
// callid
|
|
||||||
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
|
||||||
: udpSipProvider.getNewCallId();
|
|
||||||
|
|
||||||
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
|
||||||
transmitRequest(parentPlatform, request);
|
|
||||||
|
|
||||||
} catch (SipException | ParseException | InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
String catalogXml = getCatalogXml(channels, sn, parentPlatform, size);
|
||||||
|
|
||||||
|
// callid
|
||||||
|
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
||||||
|
: udpSipProvider.getNewCallId();
|
||||||
|
|
||||||
|
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
||||||
|
transmitRequest(parentPlatform, request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean catalogQuery(List<DeviceChannel> channels, ParentPlatform parentPlatform, String sn, String fromTag) {
|
public void catalogQuery(List<DeviceChannel> channels, ParentPlatform parentPlatform, String sn, String fromTag) throws InvalidArgumentException, ParseException, SipException {
|
||||||
if ( parentPlatform ==null) {
|
if ( parentPlatform ==null) {
|
||||||
return false;
|
return ;
|
||||||
}
|
}
|
||||||
sendCatalogResponse(channels, parentPlatform, sn, fromTag, 0);
|
sendCatalogResponse(channels, parentPlatform, sn, fromTag, 0);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
private String getCatalogXml(List<DeviceChannel> channels, String sn, ParentPlatform parentPlatform, int size) {
|
private String getCatalogXml(List<DeviceChannel> channels, String sn, ParentPlatform parentPlatform, int size) {
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
@ -300,30 +274,30 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
return catalogXml.toString();
|
return catalogXml.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendCatalogResponse(List<DeviceChannel> channels, ParentPlatform parentPlatform, String sn, String fromTag, int index) {
|
private void sendCatalogResponse(List<DeviceChannel> channels, ParentPlatform parentPlatform, String sn, String fromTag, int index) throws SipException, InvalidArgumentException, ParseException {
|
||||||
if (index >= channels.size()) {
|
if (index >= channels.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
List<DeviceChannel> deviceChannels;
|
||||||
List<DeviceChannel> deviceChannels;
|
if (index + parentPlatform.getCatalogGroup() < channels.size()) {
|
||||||
if (index + parentPlatform.getCatalogGroup() < channels.size()) {
|
deviceChannels = channels.subList(index, index + parentPlatform.getCatalogGroup());
|
||||||
deviceChannels = channels.subList(index, index + parentPlatform.getCatalogGroup());
|
}else {
|
||||||
}else {
|
deviceChannels = channels.subList(index, channels.size());
|
||||||
deviceChannels = channels.subList(index, channels.size());
|
|
||||||
}
|
|
||||||
String catalogXml = getCatalogXml(deviceChannels, sn, parentPlatform, channels.size());
|
|
||||||
// callid
|
|
||||||
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
|
||||||
: udpSipProvider.getNewCallId();
|
|
||||||
|
|
||||||
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
|
||||||
transmitRequest(parentPlatform, request, null, eventResult -> {
|
|
||||||
int indexNext = index + parentPlatform.getCatalogGroup();
|
|
||||||
sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext);
|
|
||||||
});
|
|
||||||
} catch (SipException | ParseException | InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
String catalogXml = getCatalogXml(deviceChannels, sn, parentPlatform, channels.size());
|
||||||
|
// callid
|
||||||
|
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
||||||
|
: udpSipProvider.getNewCallId();
|
||||||
|
|
||||||
|
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
||||||
|
transmitRequest(parentPlatform, request, null, eventResult -> {
|
||||||
|
int indexNext = index + parentPlatform.getCatalogGroup();
|
||||||
|
try {
|
||||||
|
sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 目录查询回复: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -334,36 +308,29 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean deviceInfoResponse(ParentPlatform parentPlatform, String sn, String fromTag) {
|
public void deviceInfoResponse(ParentPlatform parentPlatform, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException {
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
StringBuffer deviceInfoXml = new StringBuffer(600);
|
||||||
StringBuffer deviceInfoXml = new StringBuffer(600);
|
deviceInfoXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||||
deviceInfoXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
deviceInfoXml.append("<Response>\r\n");
|
||||||
deviceInfoXml.append("<Response>\r\n");
|
deviceInfoXml.append("<CmdType>DeviceInfo</CmdType>\r\n");
|
||||||
deviceInfoXml.append("<CmdType>DeviceInfo</CmdType>\r\n");
|
deviceInfoXml.append("<SN>" +sn + "</SN>\r\n");
|
||||||
deviceInfoXml.append("<SN>" +sn + "</SN>\r\n");
|
deviceInfoXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
||||||
deviceInfoXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
deviceInfoXml.append("<DeviceName>" + parentPlatform.getName() + "</DeviceName>\r\n");
|
||||||
deviceInfoXml.append("<DeviceName>" + parentPlatform.getName() + "</DeviceName>\r\n");
|
deviceInfoXml.append("<Manufacturer>wvp</Manufacturer>\r\n");
|
||||||
deviceInfoXml.append("<Manufacturer>wvp</Manufacturer>\r\n");
|
deviceInfoXml.append("<Model>wvp-28181-2.0</Model>\r\n");
|
||||||
deviceInfoXml.append("<Model>wvp-28181-2.0</Model>\r\n");
|
deviceInfoXml.append("<Firmware>2.0.202107</Firmware>\r\n");
|
||||||
deviceInfoXml.append("<Firmware>2.0.202107</Firmware>\r\n");
|
deviceInfoXml.append("<Result>OK</Result>\r\n");
|
||||||
deviceInfoXml.append("<Result>OK</Result>\r\n");
|
deviceInfoXml.append("</Response>\r\n");
|
||||||
deviceInfoXml.append("</Response>\r\n");
|
|
||||||
|
|
||||||
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
||||||
: udpSipProvider.getNewCallId();
|
: udpSipProvider.getNewCallId();
|
||||||
|
|
||||||
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceInfoXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
||||||
transmitRequest(parentPlatform, request);
|
transmitRequest(parentPlatform, request);
|
||||||
|
|
||||||
} catch (SipException | ParseException | InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -374,129 +341,103 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag) {
|
public void deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException {
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
return false;
|
return ;
|
||||||
}
|
}
|
||||||
try {
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
StringBuffer deviceStatusXml = new StringBuffer(600);
|
||||||
StringBuffer deviceStatusXml = new StringBuffer(600);
|
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
deviceStatusXml.append("<Response>\r\n");
|
||||||
deviceStatusXml.append("<Response>\r\n");
|
deviceStatusXml.append("<CmdType>DeviceStatus</CmdType>\r\n");
|
||||||
deviceStatusXml.append("<CmdType>DeviceStatus</CmdType>\r\n");
|
deviceStatusXml.append("<SN>" +sn + "</SN>\r\n");
|
||||||
deviceStatusXml.append("<SN>" +sn + "</SN>\r\n");
|
deviceStatusXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
||||||
deviceStatusXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
deviceStatusXml.append("<Result>OK</Result>\r\n");
|
||||||
deviceStatusXml.append("<Result>OK</Result>\r\n");
|
deviceStatusXml.append("<Online>ONLINE</Online>\r\n");
|
||||||
deviceStatusXml.append("<Online>ONLINE</Online>\r\n");
|
deviceStatusXml.append("<Status>OK</Status>\r\n");
|
||||||
deviceStatusXml.append("<Status>OK</Status>\r\n");
|
deviceStatusXml.append("</Response>\r\n");
|
||||||
deviceStatusXml.append("</Response>\r\n");
|
|
||||||
|
|
||||||
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
||||||
: udpSipProvider.getNewCallId();
|
: udpSipProvider.getNewCallId();
|
||||||
|
|
||||||
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
||||||
transmitRequest(parentPlatform, request);
|
transmitRequest(parentPlatform, request);
|
||||||
|
|
||||||
} catch (SipException | ParseException | InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendNotifyMobilePosition(ParentPlatform parentPlatform, GPSMsgInfo gpsMsgInfo, SubscribeInfo subscribeInfo) {
|
public void sendNotifyMobilePosition(ParentPlatform parentPlatform, GPSMsgInfo gpsMsgInfo, SubscribeInfo subscribeInfo) throws InvalidArgumentException, ParseException, NoSuchFieldException, SipException, IllegalAccessException {
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("[发送 移动位置订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), gpsMsgInfo.getId(), gpsMsgInfo.getLng(), gpsMsgInfo.getLat());
|
logger.debug("[发送 移动位置订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), gpsMsgInfo.getId(), gpsMsgInfo.getLng(), gpsMsgInfo.getLat());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
StringBuffer deviceStatusXml = new StringBuffer(600);
|
||||||
StringBuffer deviceStatusXml = new StringBuffer(600);
|
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
deviceStatusXml.append("<Notify>\r\n");
|
||||||
deviceStatusXml.append("<Notify>\r\n");
|
deviceStatusXml.append("<CmdType>MobilePosition</CmdType>\r\n");
|
||||||
deviceStatusXml.append("<CmdType>MobilePosition</CmdType>\r\n");
|
deviceStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
||||||
deviceStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
deviceStatusXml.append("<DeviceID>" + gpsMsgInfo.getId() + "</DeviceID>\r\n");
|
||||||
deviceStatusXml.append("<DeviceID>" + gpsMsgInfo.getId() + "</DeviceID>\r\n");
|
deviceStatusXml.append("<Time>" + gpsMsgInfo.getTime() + "</Time>\r\n");
|
||||||
deviceStatusXml.append("<Time>" + gpsMsgInfo.getTime() + "</Time>\r\n");
|
deviceStatusXml.append("<Longitude>" + gpsMsgInfo.getLng() + "</Longitude>\r\n");
|
||||||
deviceStatusXml.append("<Longitude>" + gpsMsgInfo.getLng() + "</Longitude>\r\n");
|
deviceStatusXml.append("<Latitude>" + gpsMsgInfo.getLat() + "</Latitude>\r\n");
|
||||||
deviceStatusXml.append("<Latitude>" + gpsMsgInfo.getLat() + "</Latitude>\r\n");
|
deviceStatusXml.append("<Speed>" + gpsMsgInfo.getSpeed() + "</Speed>\r\n");
|
||||||
deviceStatusXml.append("<Speed>" + gpsMsgInfo.getSpeed() + "</Speed>\r\n");
|
deviceStatusXml.append("<Direction>" + gpsMsgInfo.getDirection() + "</Direction>\r\n");
|
||||||
deviceStatusXml.append("<Direction>" + gpsMsgInfo.getDirection() + "</Direction>\r\n");
|
deviceStatusXml.append("<Altitude>" + gpsMsgInfo.getAltitude() + "</Altitude>\r\n");
|
||||||
deviceStatusXml.append("<Altitude>" + gpsMsgInfo.getAltitude() + "</Altitude>\r\n");
|
deviceStatusXml.append("</Notify>\r\n");
|
||||||
deviceStatusXml.append("</Notify>\r\n");
|
|
||||||
|
|
||||||
sendNotify(parentPlatform, deviceStatusXml.toString(), subscribeInfo, eventResult -> {
|
sendNotify(parentPlatform, deviceStatusXml.toString(), subscribeInfo, eventResult -> {
|
||||||
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
} catch (SipException | ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendAlarmMessage(ParentPlatform parentPlatform, DeviceAlarm deviceAlarm) {
|
public void sendAlarmMessage(ParentPlatform parentPlatform, DeviceAlarm deviceAlarm) throws SipException, InvalidArgumentException, ParseException {
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
logger.info("[发送报警通知] {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),
|
logger.info("[发送报警通知] {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),
|
||||||
deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSONObject.toJSON(deviceAlarm));
|
deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSONObject.toJSON(deviceAlarm));
|
||||||
try {
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
StringBuffer deviceStatusXml = new StringBuffer(600);
|
||||||
StringBuffer deviceStatusXml = new StringBuffer(600);
|
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
deviceStatusXml.append("<Notify>\r\n");
|
||||||
deviceStatusXml.append("<Notify>\r\n");
|
deviceStatusXml.append("<CmdType>Alarm</CmdType>\r\n");
|
||||||
deviceStatusXml.append("<CmdType>Alarm</CmdType>\r\n");
|
deviceStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
||||||
deviceStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
deviceStatusXml.append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n");
|
||||||
deviceStatusXml.append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n");
|
deviceStatusXml.append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n");
|
||||||
deviceStatusXml.append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n");
|
deviceStatusXml.append("<AlarmMethod>" + deviceAlarm.getAlarmMethod() + "</AlarmMethod>\r\n");
|
||||||
deviceStatusXml.append("<AlarmMethod>" + deviceAlarm.getAlarmMethod() + "</AlarmMethod>\r\n");
|
deviceStatusXml.append("<AlarmTime>" + deviceAlarm.getAlarmTime() + "</AlarmTime>\r\n");
|
||||||
deviceStatusXml.append("<AlarmTime>" + deviceAlarm.getAlarmTime() + "</AlarmTime>\r\n");
|
deviceStatusXml.append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n");
|
||||||
deviceStatusXml.append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n");
|
deviceStatusXml.append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n");
|
||||||
deviceStatusXml.append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n");
|
deviceStatusXml.append("<Latitude>" + deviceAlarm.getLatitude() + "</Latitude>\r\n");
|
||||||
deviceStatusXml.append("<Latitude>" + deviceAlarm.getLatitude() + "</Latitude>\r\n");
|
deviceStatusXml.append("<info>\r\n");
|
||||||
deviceStatusXml.append("<info>\r\n");
|
deviceStatusXml.append("<AlarmType>" + deviceAlarm.getAlarmType() + "</AlarmType>\r\n");
|
||||||
deviceStatusXml.append("<AlarmType>" + deviceAlarm.getAlarmType() + "</AlarmType>\r\n");
|
deviceStatusXml.append("</info>\r\n");
|
||||||
deviceStatusXml.append("</info>\r\n");
|
deviceStatusXml.append("</Notify>\r\n");
|
||||||
deviceStatusXml.append("</Notify>\r\n");
|
|
||||||
|
|
||||||
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
CallIdHeader callIdHeader = parentPlatform.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
|
||||||
: udpSipProvider.getNewCallId();
|
: udpSipProvider.getNewCallId();
|
||||||
|
|
||||||
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), SipUtils.getNewFromTag(), SipUtils.getNewViaTag(), callIdHeader);
|
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), SipUtils.getNewFromTag(), SipUtils.getNewViaTag(), callIdHeader);
|
||||||
transmitRequest(parentPlatform, request);
|
transmitRequest(parentPlatform, request);
|
||||||
|
|
||||||
} catch (SipException | ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) {
|
public void sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) throws InvalidArgumentException, ParseException, NoSuchFieldException, SipException, IllegalAccessException {
|
||||||
if (parentPlatform == null || deviceChannels == null || deviceChannels.size() == 0 || subscribeInfo == null) {
|
if (parentPlatform == null || deviceChannels == null || deviceChannels.size() == 0 || subscribeInfo == null) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
if (index >= deviceChannels.size()) {
|
if (index >= deviceChannels.size()) {
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
List<DeviceChannel> channels;
|
List<DeviceChannel> channels;
|
||||||
if (index + parentPlatform.getCatalogGroup() < deviceChannels.size()) {
|
if (index + parentPlatform.getCatalogGroup() < deviceChannels.size()) {
|
||||||
@ -504,32 +445,25 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
}else {
|
}else {
|
||||||
channels = deviceChannels.subList(index, deviceChannels.size());
|
channels = deviceChannels.subList(index, deviceChannels.size());
|
||||||
}
|
}
|
||||||
try {
|
Integer finalIndex = index;
|
||||||
Integer finalIndex = index;
|
String catalogXmlContent = getCatalogXmlContentForCatalogAddOrUpdate(parentPlatform, channels,
|
||||||
String catalogXmlContent = getCatalogXmlContentForCatalogAddOrUpdate(parentPlatform, channels,
|
deviceChannels.size(), type, subscribeInfo);
|
||||||
deviceChannels.size(), type, subscribeInfo);
|
sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> {
|
||||||
sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> {
|
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
||||||
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
}, (eventResult -> {
|
||||||
}, (eventResult -> {
|
try {
|
||||||
sendNotifyForCatalogAddOrUpdate(type, parentPlatform, deviceChannels, subscribeInfo,
|
sendNotifyForCatalogAddOrUpdate(type, parentPlatform, deviceChannels, subscribeInfo,
|
||||||
finalIndex + parentPlatform.getCatalogGroup());
|
finalIndex + parentPlatform.getCatalogGroup());
|
||||||
}));
|
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
|
||||||
} catch (SipException | ParseException e) {
|
IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
logger.error("[命令发送失败] 国标级联 NOTIFY通知: {}", e.getMessage());
|
||||||
return false;
|
}
|
||||||
} catch (NoSuchFieldException e) {
|
}));
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientTransaction sendNotify(ParentPlatform parentPlatform, String catalogXmlContent,
|
private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent,
|
||||||
SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent )
|
SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent )
|
||||||
throws NoSuchFieldException, IllegalAccessException, SipException, ParseException, InvalidArgumentException {
|
throws SipException, ParseException, InvalidArgumentException {
|
||||||
MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
|
MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
// 设置编码, 防止中文乱码
|
// 设置编码, 防止中文乱码
|
||||||
@ -537,50 +471,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
|
|
||||||
SIPRequest notifyRequest = headerProviderPlatformProvider.createNotifyRequest(parentPlatform, catalogXmlContent, subscribeInfo);
|
SIPRequest notifyRequest = headerProviderPlatformProvider.createNotifyRequest(parentPlatform, catalogXmlContent, subscribeInfo);
|
||||||
|
|
||||||
notifyRequest.getCSeqHeader().setSeqNumber(redisCatchStorage.getCSEQ());
|
transmitRequest(parentPlatform, notifyRequest);
|
||||||
|
|
||||||
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
|
|
||||||
notifyRequest.setContent(catalogXmlContent, contentTypeHeader);
|
|
||||||
|
|
||||||
SubscriptionStateHeader subscriptionState = sipFactory.createHeaderFactory()
|
|
||||||
.createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE);
|
|
||||||
notifyRequest.addHeader(subscriptionState);
|
|
||||||
|
|
||||||
EventHeader event = sipFactory.createHeaderFactory().createEventHeader(subscribeInfo.getEventType());
|
|
||||||
if (subscribeInfo.getEventId() != null) {
|
|
||||||
event.setEventId(subscribeInfo.getEventId());
|
|
||||||
}
|
|
||||||
notifyRequest.addHeader(event);
|
|
||||||
SipURI sipURI = (SipURI) notifyRequest.getRequestURI();
|
|
||||||
sipURI.setHost(parentPlatform.getServerIP());
|
|
||||||
sipURI.setPort(parentPlatform.getServerPort());
|
|
||||||
|
|
||||||
// ClientTransaction transaction = subscribeInfo.getClientTransaction();
|
|
||||||
// if (transaction == null || transaction.getState().equals(TransactionState.COMPLETED)) {
|
|
||||||
// if ("TCP".equals(parentPlatform.getTransport())) {
|
|
||||||
// transaction = tcpSipProvider.getNewClientTransaction(notifyRequest);
|
|
||||||
// } else if ("UDP".equals(parentPlatform.getTransport())) {
|
|
||||||
// transaction = udpSipProvider.getNewClientTransaction(notifyRequest);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
ClientTransaction transaction = null;
|
|
||||||
if ("TCP".equals(parentPlatform.getTransport())) {
|
|
||||||
transaction = tcpSipProvider.getNewClientTransaction(notifyRequest);
|
|
||||||
} else if ("UDP".equals(parentPlatform.getTransport())) {
|
|
||||||
transaction = udpSipProvider.getNewClientTransaction(notifyRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加错误订阅
|
|
||||||
if (errorEvent != null) {
|
|
||||||
sipSubscribe.addErrorSubscribe(subscribeInfo.getRequest().getCallIdHeader().getCallId(), errorEvent);
|
|
||||||
}
|
|
||||||
// 添加订阅
|
|
||||||
if (okEvent != null) {
|
|
||||||
sipSubscribe.addOkSubscribe(subscribeInfo.getRequest().getCallIdHeader().getCallId(), okEvent);
|
|
||||||
}
|
|
||||||
transaction.sendRequest();
|
|
||||||
return transaction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) {
|
private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) {
|
||||||
@ -639,20 +530,21 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels,
|
public void sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels,
|
||||||
SubscribeInfo subscribeInfo, Integer index) {
|
SubscribeInfo subscribeInfo, Integer index) throws InvalidArgumentException, ParseException, NoSuchFieldException, SipException, IllegalAccessException {
|
||||||
if (parentPlatform == null
|
if (parentPlatform == null
|
||||||
|| deviceChannels == null
|
|| deviceChannels == null
|
||||||
|| deviceChannels.size() == 0
|
|| deviceChannels.size() == 0
|
||||||
|| subscribeInfo == null) {
|
|| subscribeInfo == null) {
|
||||||
return false;
|
logger.warn("[缺少必要参数]");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
if (index >= deviceChannels.size()) {
|
if (index >= deviceChannels.size()) {
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
List<DeviceChannel> channels;
|
List<DeviceChannel> channels;
|
||||||
if (index + parentPlatform.getCatalogGroup() < deviceChannels.size()) {
|
if (index + parentPlatform.getCatalogGroup() < deviceChannels.size()) {
|
||||||
@ -660,28 +552,19 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
}else {
|
}else {
|
||||||
channels = deviceChannels.subList(index, deviceChannels.size());
|
channels = deviceChannels.subList(index, deviceChannels.size());
|
||||||
}
|
}
|
||||||
try {
|
Integer finalIndex = index;
|
||||||
Integer finalIndex = index;
|
String catalogXmlContent = getCatalogXmlContentForCatalogOther(parentPlatform, channels, type);
|
||||||
String catalogXmlContent = getCatalogXmlContentForCatalogOther(parentPlatform, channels, type);
|
sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> {
|
||||||
sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> {
|
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
||||||
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
}, eventResult -> {
|
||||||
}, (eventResult -> {
|
try {
|
||||||
sendNotifyForCatalogOther(type, parentPlatform, deviceChannels, subscribeInfo,
|
sendNotifyForCatalogOther(type, parentPlatform, deviceChannels, subscribeInfo,
|
||||||
finalIndex + parentPlatform.getCatalogGroup());
|
finalIndex + parentPlatform.getCatalogGroup());
|
||||||
}));
|
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
|
||||||
} catch (SipException e) {
|
IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
logger.error("[命令发送失败] 国标级联 NOTIFY通知: {}", e.getMessage());
|
||||||
} catch (ParseException e) {
|
}
|
||||||
e.printStackTrace();
|
});
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCatalogXmlContentForCatalogOther(ParentPlatform parentPlatform, List<DeviceChannel> channels, String type) {
|
private String getCatalogXmlContentForCatalogOther(ParentPlatform parentPlatform, List<DeviceChannel> channels, String type) {
|
||||||
@ -711,113 +594,81 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
return catalogXml.toString();
|
return catalogXml.toString();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean recordInfo(DeviceChannel deviceChannel, ParentPlatform parentPlatform, String fromTag, RecordInfo recordInfo) {
|
public void recordInfo(DeviceChannel deviceChannel, ParentPlatform parentPlatform, String fromTag, RecordInfo recordInfo) throws SipException, InvalidArgumentException, ParseException {
|
||||||
if ( parentPlatform ==null) {
|
if ( parentPlatform ==null) {
|
||||||
return false;
|
return ;
|
||||||
}
|
}
|
||||||
try {
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
StringBuffer recordXml = new StringBuffer(600);
|
||||||
StringBuffer recordXml = new StringBuffer(600);
|
recordXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||||
recordXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
recordXml.append("<Response>\r\n");
|
||||||
recordXml.append("<Response>\r\n");
|
recordXml.append("<CmdType>RecordInfo</CmdType>\r\n");
|
||||||
recordXml.append("<CmdType>RecordInfo</CmdType>\r\n");
|
recordXml.append("<SN>" +recordInfo.getSn() + "</SN>\r\n");
|
||||||
recordXml.append("<SN>" +recordInfo.getSn() + "</SN>\r\n");
|
recordXml.append("<DeviceID>" + recordInfo.getDeviceId() + "</DeviceID>\r\n");
|
||||||
recordXml.append("<DeviceID>" + recordInfo.getDeviceId() + "</DeviceID>\r\n");
|
recordXml.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n");
|
||||||
recordXml.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n");
|
if (recordInfo.getRecordList() == null ) {
|
||||||
if (recordInfo.getRecordList() == null ) {
|
recordXml.append("<RecordList Num=\"0\">\r\n");
|
||||||
recordXml.append("<RecordList Num=\"0\">\r\n");
|
}else {
|
||||||
}else {
|
recordXml.append("<RecordList Num=\"" + recordInfo.getRecordList().size()+"\">\r\n");
|
||||||
recordXml.append("<RecordList Num=\"" + recordInfo.getRecordList().size()+"\">\r\n");
|
if (recordInfo.getRecordList().size() > 0) {
|
||||||
if (recordInfo.getRecordList().size() > 0) {
|
for (RecordItem recordItem : recordInfo.getRecordList()) {
|
||||||
for (RecordItem recordItem : recordInfo.getRecordList()) {
|
recordXml.append("<Item>\r\n");
|
||||||
recordXml.append("<Item>\r\n");
|
if (deviceChannel != null) {
|
||||||
if (deviceChannel != null) {
|
recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n");
|
||||||
recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n");
|
recordXml.append("<Name>" + recordItem.getName() + "</Name>\r\n");
|
||||||
recordXml.append("<Name>" + recordItem.getName() + "</Name>\r\n");
|
recordXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\r\n");
|
||||||
recordXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\r\n");
|
recordXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n");
|
||||||
recordXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n");
|
recordXml.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n");
|
||||||
recordXml.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n");
|
recordXml.append("<Type>" + recordItem.getType() + "</Type>\r\n");
|
||||||
recordXml.append("<Type>" + recordItem.getType() + "</Type>\r\n");
|
if (!ObjectUtils.isEmpty(recordItem.getFileSize())) {
|
||||||
if (!ObjectUtils.isEmpty(recordItem.getFileSize())) {
|
recordXml.append("<FileSize>" + recordItem.getFileSize() + "</FileSize>\r\n");
|
||||||
recordXml.append("<FileSize>" + recordItem.getFileSize() + "</FileSize>\r\n");
|
}
|
||||||
}
|
if (!ObjectUtils.isEmpty(recordItem.getFilePath())) {
|
||||||
if (!ObjectUtils.isEmpty(recordItem.getFilePath())) {
|
recordXml.append("<FilePath>" + recordItem.getFilePath() + "</FilePath>\r\n");
|
||||||
recordXml.append("<FilePath>" + recordItem.getFilePath() + "</FilePath>\r\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
recordXml.append("</Item>\r\n");
|
|
||||||
}
|
}
|
||||||
|
recordXml.append("</Item>\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recordXml.append("</RecordList>\r\n");
|
|
||||||
recordXml.append("</Response>\r\n");
|
|
||||||
|
|
||||||
// callid
|
|
||||||
CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
|
|
||||||
: udpSipProvider.getNewCallId();
|
|
||||||
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
|
||||||
transmitRequest(parentPlatform, request);
|
|
||||||
|
|
||||||
} catch (SipException | ParseException | InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean sendMediaStatusNotify(ParentPlatform platform, SendRtpItem sendRtpItem) {
|
|
||||||
if (sendRtpItem == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (platform == null) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
recordXml.append("</RecordList>\r\n");
|
||||||
|
recordXml.append("</Response>\r\n");
|
||||||
String characterSet = platform.getCharacterSet();
|
|
||||||
StringBuffer mediaStatusXml = new StringBuffer(200);
|
|
||||||
mediaStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
|
||||||
mediaStatusXml.append("<Notify>\r\n");
|
|
||||||
mediaStatusXml.append("<CmdType>MediaStatus</CmdType>\r\n");
|
|
||||||
mediaStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
|
||||||
mediaStatusXml.append("<DeviceID>" + sendRtpItem.getChannelId() + "</DeviceID>\r\n");
|
|
||||||
mediaStatusXml.append("<NotifyType>121</NotifyType>\r\n");
|
|
||||||
mediaStatusXml.append("</Notify>\r\n");
|
|
||||||
|
|
||||||
SIPRequest messageRequest = (SIPRequest)headerProviderPlatformProvider.createMessageRequest(platform, mediaStatusXml.toString(),
|
|
||||||
sendRtpItem);
|
|
||||||
|
|
||||||
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
|
|
||||||
messageRequest.setContent(mediaStatusXml.toString(), contentTypeHeader);
|
|
||||||
SipURI sipURI = (SipURI) messageRequest.getRequestURI();
|
|
||||||
sipURI.setHost(platform.getServerIP());
|
|
||||||
sipURI.setPort(platform.getServerPort());
|
|
||||||
ClientTransaction clientTransaction;
|
|
||||||
if ("TCP".equals(platform.getTransport())) {
|
|
||||||
clientTransaction = tcpSipProvider.getNewClientTransaction(messageRequest);
|
|
||||||
}else {
|
|
||||||
clientTransaction = udpSipProvider.getNewClientTransaction(messageRequest);
|
|
||||||
}
|
|
||||||
clientTransaction.sendRequest();
|
|
||||||
} catch (SipException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
|
// callid
|
||||||
|
CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
|
||||||
|
: udpSipProvider.getNewCallId();
|
||||||
|
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
||||||
|
transmitRequest(parentPlatform, request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void streamByeCmd(ParentPlatform platform, String callId) {
|
public void sendMediaStatusNotify(ParentPlatform platform, SendRtpItem sendRtpItem) throws SipException, InvalidArgumentException, ParseException {
|
||||||
|
if (sendRtpItem == null || platform == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String characterSet = platform.getCharacterSet();
|
||||||
|
StringBuffer mediaStatusXml = new StringBuffer(200);
|
||||||
|
mediaStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||||
|
mediaStatusXml.append("<Notify>\r\n");
|
||||||
|
mediaStatusXml.append("<CmdType>MediaStatus</CmdType>\r\n");
|
||||||
|
mediaStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
||||||
|
mediaStatusXml.append("<DeviceID>" + sendRtpItem.getChannelId() + "</DeviceID>\r\n");
|
||||||
|
mediaStatusXml.append("<NotifyType>121</NotifyType>\r\n");
|
||||||
|
mediaStatusXml.append("</Notify>\r\n");
|
||||||
|
|
||||||
|
SIPRequest messageRequest = (SIPRequest)headerProviderPlatformProvider.createMessageRequest(platform, mediaStatusXml.toString(),
|
||||||
|
sendRtpItem);
|
||||||
|
|
||||||
|
transmitRequest(platform, messageRequest);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamByeCmd(ParentPlatform platform, String callId) throws SipException, InvalidArgumentException, ParseException {
|
||||||
if (platform == null) {
|
if (platform == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -828,7 +679,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void streamByeCmd(ParentPlatform platform, SendRtpItem sendRtpItem) {
|
public void streamByeCmd(ParentPlatform platform, SendRtpItem sendRtpItem) throws SipException, InvalidArgumentException, ParseException {
|
||||||
if (sendRtpItem == null ) {
|
if (sendRtpItem == null ) {
|
||||||
logger.info("[向上级发送BYE], sendRtpItem 为NULL");
|
logger.info("[向上级发送BYE], sendRtpItem 为NULL");
|
||||||
return;
|
return;
|
||||||
@ -844,25 +695,10 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
|
||||||
zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());
|
zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());
|
||||||
}
|
}
|
||||||
try {
|
SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem);
|
||||||
|
if (byeRequest == null) {
|
||||||
SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem);
|
logger.warn("[向上级发送bye]:无法创建 byeRequest");
|
||||||
if (byeRequest == null) {
|
|
||||||
logger.warn("[向上级发送bye]:无法创建 byeRequest");
|
|
||||||
}
|
|
||||||
ClientTransaction clientTransaction;
|
|
||||||
if ("TCP".equals(platform.getTransport())) {
|
|
||||||
clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest);
|
|
||||||
} else {
|
|
||||||
clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest);
|
|
||||||
}
|
|
||||||
clientTransaction.sendRequest();
|
|
||||||
} catch (SipException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
|
transmitRequest(platform,byeRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import gov.nist.javax.sip.SipStackImpl;
|
|||||||
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 gov.nist.javax.sip.stack.SIPServerTransaction;
|
import gov.nist.javax.sip.stack.SIPServerTransaction;
|
||||||
|
import gov.nist.javax.sip.stack.SIPServerTransactionImpl;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
import org.dom4j.DocumentException;
|
import org.dom4j.DocumentException;
|
||||||
@ -57,7 +58,7 @@ public abstract class SIPRequestProcessorParent {
|
|||||||
*/
|
*/
|
||||||
public ServerTransaction getServerTransaction(RequestEvent evt) {
|
public ServerTransaction getServerTransaction(RequestEvent evt) {
|
||||||
Request request = evt.getRequest();
|
Request request = evt.getRequest();
|
||||||
ServerTransaction serverTransaction = evt.getServerTransaction();
|
SIPServerTransactionImpl serverTransaction = (SIPServerTransactionImpl)evt.getServerTransaction();
|
||||||
// 判断TCP还是UDP
|
// 判断TCP还是UDP
|
||||||
boolean isTcp = false;
|
boolean isTcp = false;
|
||||||
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
||||||
@ -65,28 +66,28 @@ public abstract class SIPRequestProcessorParent {
|
|||||||
if (transport.equalsIgnoreCase("TCP")) {
|
if (transport.equalsIgnoreCase("TCP")) {
|
||||||
isTcp = true;
|
isTcp = true;
|
||||||
}
|
}
|
||||||
|
if (serverTransaction != null && serverTransaction.getOriginalRequest() == null) {
|
||||||
|
serverTransaction.setOriginalRequest((SIPRequest) evt.getRequest());
|
||||||
|
}
|
||||||
if (serverTransaction == null) {
|
if (serverTransaction == null) {
|
||||||
try {
|
try {
|
||||||
if (isTcp) {
|
if (isTcp) {
|
||||||
SipStackImpl stack = (SipStackImpl)tcpSipProvider.getSipStack();
|
SipStackImpl stack = (SipStackImpl)tcpSipProvider.getSipStack();
|
||||||
serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
|
serverTransaction = (SIPServerTransactionImpl) stack.findTransaction((SIPRequest)request, true);
|
||||||
if (serverTransaction == null) {
|
if (serverTransaction == null) {
|
||||||
serverTransaction = tcpSipProvider.getNewServerTransaction(request);
|
serverTransaction = (SIPServerTransactionImpl)tcpSipProvider.getNewServerTransaction(request);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SipStackImpl stack = (SipStackImpl)udpSipProvider.getSipStack();
|
SipStackImpl stack = (SipStackImpl)udpSipProvider.getSipStack();
|
||||||
serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
|
serverTransaction = (SIPServerTransactionImpl) stack.findTransaction((SIPRequest)request, true);
|
||||||
if (serverTransaction == null) {
|
if (serverTransaction == null) {
|
||||||
serverTransaction = udpSipProvider.getNewServerTransaction(request);
|
serverTransaction = (SIPServerTransactionImpl)udpSipProvider.getNewServerTransaction(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TransactionAlreadyExistsException e) {
|
} catch (TransactionAlreadyExistsException e) {
|
||||||
logger.error(e.getMessage());
|
logger.error(e.getMessage());
|
||||||
} catch (TransactionUnavailableException e) {
|
} catch (TransactionUnavailableException e) {
|
||||||
logger.error(e.getMessage());
|
logger.error(e.getMessage());
|
||||||
}finally {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return serverTransaction;
|
return serverTransaction;
|
||||||
|
@ -23,12 +23,15 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
import javax.sip.RequestEvent;
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
import javax.sip.address.SipURI;
|
import javax.sip.address.SipURI;
|
||||||
import javax.sip.header.CallIdHeader;
|
import javax.sip.header.CallIdHeader;
|
||||||
import javax.sip.header.FromHeader;
|
import javax.sip.header.FromHeader;
|
||||||
import javax.sip.header.HeaderAddress;
|
import javax.sip.header.HeaderAddress;
|
||||||
import javax.sip.header.ToHeader;
|
import javax.sip.header.ToHeader;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,8 +98,8 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
|
|||||||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
|
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
|
||||||
String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
|
String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
|
||||||
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
||||||
logger.info("收到ACK,rtp/{}开始向上级推流, 目标 {}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
|
logger.info("收到ACK,rtp/{}开始向上级推流, 目标={}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
|
||||||
Map<String, Object> param = new HashMap<>();
|
Map<String, Object> param = new HashMap<>(12);
|
||||||
param.put("vhost","__defaultVhost__");
|
param.put("vhost","__defaultVhost__");
|
||||||
param.put("app",sendRtpItem.getApp());
|
param.put("app",sendRtpItem.getApp());
|
||||||
param.put("stream",sendRtpItem.getStreamId());
|
param.put("stream",sendRtpItem.getStreamId());
|
||||||
@ -139,7 +142,11 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
|
|||||||
// TODO 可能是语音对讲
|
// TODO 可能是语音对讲
|
||||||
}else {
|
}else {
|
||||||
// 向上级平台
|
// 向上级平台
|
||||||
commanderForPlatform.streamByeCmd(parentPlatform, callIdHeader.getCallId());
|
try {
|
||||||
|
commanderForPlatform.streamByeCmd(parentPlatform, callIdHeader.getCallId());
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType;
|
import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
||||||
@ -12,12 +13,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor
|
|||||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
|
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
import com.genersoft.iot.vmp.utils.SerializeUtils;
|
|
||||||
import gov.nist.javax.sip.stack.SIPDialog;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
@ -50,6 +50,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IVideoManagerStorage storager;
|
private IVideoManagerStorage storager;
|
||||||
|
|
||||||
@ -77,9 +80,13 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void process(RequestEvent evt) {
|
public void process(RequestEvent evt) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
responseAck(getServerTransaction(evt), Response.OK);
|
responseAck(getServerTransaction(evt), Response.OK);
|
||||||
CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[回复BYE信息失败],{}", e.getMessage());
|
||||||
|
}
|
||||||
|
CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
|
||||||
String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
|
String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
|
||||||
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
|
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
|
||||||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
|
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
|
||||||
@ -99,7 +106,17 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
|
|||||||
if (totalReaderCount <= 0) {
|
if (totalReaderCount <= 0) {
|
||||||
logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId);
|
logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId);
|
||||||
if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {
|
if (sendRtpItem.getPlayType().equals(InviteStreamType.PLAY)) {
|
||||||
cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId, null);
|
Device device = deviceService.queryDevice(sendRtpItem.getDeviceId());
|
||||||
|
if (device == null) {
|
||||||
|
logger.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
logger.warn("[停止点播] {}/{}", sendRtpItem.getDeviceId(), channelId);
|
||||||
|
cmder.streamByeCmd(device, channelId, streamId, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException |
|
||||||
|
SsrcTransactionNotFoundException e) {
|
||||||
|
logger.error("[收到bye] {} 无其它观看者,通知设备停止推流, 发送BYE失败 {}",streamId, e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) {
|
if (sendRtpItem.getPlayType().equals(InviteStreamType.PUSH)) {
|
||||||
MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
|
MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
|
||||||
@ -120,8 +137,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
|
|||||||
}
|
}
|
||||||
SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
|
SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
|
||||||
if (ssrcTransactionForPlay != null){
|
if (ssrcTransactionForPlay != null){
|
||||||
SIPDialog dialogForPlay = (SIPDialog) SerializeUtils.deSerialize(ssrcTransactionForPlay.getDialog());
|
if (ssrcTransactionForPlay.getCallId().equals(callIdHeader.getCallId())){
|
||||||
if (dialogForPlay.getCallId().getCallId().equals(callIdHeader.getCallId())){
|
|
||||||
// 释放ssrc
|
// 释放ssrc
|
||||||
MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId());
|
MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransactionForPlay.getMediaServerId());
|
||||||
if (mediaServerItem != null) {
|
if (mediaServerItem != null) {
|
||||||
@ -140,12 +156,6 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
|
|||||||
streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream());
|
streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlayBack.getStream());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SipException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,7 +341,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
logger.info("Ack 等待超时");
|
logger.info("Ack 等待超时");
|
||||||
mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), ssrc);
|
mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), ssrc);
|
||||||
// 回复bye
|
// 回复bye
|
||||||
cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
|
try {
|
||||||
|
cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
}, 60 * 1000);
|
}, 60 * 1000);
|
||||||
responseSdpAck(serverTransaction, content.toString(), platform);
|
responseSdpAck(serverTransaction, content.toString(), platform);
|
||||||
|
|
||||||
|
@ -93,7 +93,9 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
|
|||||||
responseAck(serverTransaction, Response.NOT_FOUND, "device "+ deviceId +" not found");
|
responseAck(serverTransaction, Response.NOT_FOUND, "device "+ deviceId +" not found");
|
||||||
logger.warn("[设备未找到 ]: {}", deviceId);
|
logger.warn("[设备未找到 ]: {}", deviceId);
|
||||||
if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
|
if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
|
||||||
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
|
DeviceNotFoundEvent deviceNotFoundEvent = new DeviceNotFoundEvent(evt.getDialog());
|
||||||
|
deviceNotFoundEvent.setCallId(callIdHeader.getCallId());
|
||||||
|
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(deviceNotFoundEvent);
|
||||||
sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()).response(eventResult);
|
sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()).response(eventResult);
|
||||||
};
|
};
|
||||||
}else {
|
}else {
|
||||||
|
@ -89,8 +89,6 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
|
|||||||
ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(deviceId);
|
ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(deviceId);
|
||||||
try {
|
try {
|
||||||
if (device != null && parentPlatform != null) {
|
if (device != null && parentPlatform != null) {
|
||||||
|
|
||||||
logger.warn("[重复]平台与设备编号重复:{}", deviceId);
|
|
||||||
SIPRequest request = (SIPRequest) evt.getRequest();
|
SIPRequest request = (SIPRequest) evt.getRequest();
|
||||||
String hostAddress = request.getRemoteAddress().getHostAddress();
|
String hostAddress = request.getRemoteAddress().getHostAddress();
|
||||||
int remotePort = request.getRemotePort();
|
int remotePort = request.getRemotePort();
|
||||||
@ -105,7 +103,9 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
|
|||||||
responseAck(serverTransaction, Response.NOT_FOUND, "device "+ deviceId +" not found");
|
responseAck(serverTransaction, Response.NOT_FOUND, "device "+ deviceId +" not found");
|
||||||
logger.warn("[设备未找到 ]: {}", deviceId);
|
logger.warn("[设备未找到 ]: {}", deviceId);
|
||||||
if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
|
if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
|
||||||
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
|
DeviceNotFoundEvent deviceNotFoundEvent = new DeviceNotFoundEvent(evt.getDialog());
|
||||||
|
deviceNotFoundEvent.setCallId(callIdHeader.getCallId());
|
||||||
|
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(deviceNotFoundEvent);
|
||||||
sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()).response(eventResult);
|
sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()).response(eventResult);
|
||||||
};
|
};
|
||||||
}else {
|
}else {
|
||||||
|
@ -16,6 +16,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@ -48,6 +50,10 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SIPCommanderFroPlatform cmderFroPlatform;
|
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||||
|
|
||||||
|
@Qualifier("taskExecutor")
|
||||||
|
@Autowired
|
||||||
|
private ThreadPoolTaskExecutor taskExecutor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
controlMessageHandler.addHandler(cmdType, this);
|
controlMessageHandler.addHandler(cmdType, this);
|
||||||
@ -71,34 +77,30 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
|
|||||||
if (parentPlatform.getServerGBId().equals(targetGBId)) {
|
if (parentPlatform.getServerGBId().equals(targetGBId)) {
|
||||||
// 远程启动本平台:需要在重新启动程序后先对SipStack解绑
|
// 远程启动本平台:需要在重新启动程序后先对SipStack解绑
|
||||||
logger.info("执行远程启动本平台命令");
|
logger.info("执行远程启动本平台命令");
|
||||||
cmderFroPlatform.unregister(parentPlatform, null, null);
|
try {
|
||||||
|
cmderFroPlatform.unregister(parentPlatform, null, null);
|
||||||
Thread restartThread = new Thread(new Runnable() {
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
@Override
|
logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());
|
||||||
public void run() {
|
}
|
||||||
try {
|
taskExecutor.execute(()->{
|
||||||
Thread.sleep(3000);
|
try {
|
||||||
SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
|
Thread.sleep(3000);
|
||||||
SipStackImpl stack = (SipStackImpl)up.getSipStack();
|
SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
|
||||||
stack.stop();
|
SipStackImpl stack = (SipStackImpl)up.getSipStack();
|
||||||
Iterator listener = stack.getListeningPoints();
|
stack.stop();
|
||||||
while (listener.hasNext()) {
|
Iterator listener = stack.getListeningPoints();
|
||||||
stack.deleteListeningPoint((ListeningPoint) listener.next());
|
while (listener.hasNext()) {
|
||||||
}
|
stack.deleteListeningPoint((ListeningPoint) listener.next());
|
||||||
Iterator providers = stack.getSipProviders();
|
|
||||||
while (providers.hasNext()) {
|
|
||||||
stack.deleteSipProvider((SipProvider) providers.next());
|
|
||||||
}
|
|
||||||
VManageBootstrap.restart();
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
} catch (ObjectInUseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
Iterator providers = stack.getSipProviders();
|
||||||
|
while (providers.hasNext()) {
|
||||||
|
stack.deleteSipProvider((SipProvider) providers.next());
|
||||||
|
}
|
||||||
|
VManageBootstrap.restart();
|
||||||
|
} catch (InterruptedException | ObjectInUseException e) {
|
||||||
|
logger.error("[任务执行失败] 服务重启: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
restartThread.setDaemon(false);
|
|
||||||
restartThread.start();
|
|
||||||
} else {
|
} else {
|
||||||
// 远程启动指定设备
|
// 远程启动指定设备
|
||||||
}
|
}
|
||||||
@ -111,37 +113,29 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
|
|||||||
try {
|
try {
|
||||||
responseAck(serverTransaction, Response.NOT_FOUND);
|
responseAck(serverTransaction, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
} catch (SipException e) {
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
logger.error("[命令发送失败] 错误信息: {}", e.getMessage());
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmder.fronEndCmd(deviceForPlatform, channelId, cmdString, eventResult -> {
|
try {
|
||||||
// 失败的回复
|
cmder.fronEndCmd(deviceForPlatform, channelId, cmdString, eventResult -> {
|
||||||
try {
|
// 失败的回复
|
||||||
responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
|
try {
|
||||||
} catch (SipException e) {
|
responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
|
||||||
e.printStackTrace();
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
} catch (InvalidArgumentException e) {
|
logger.error("[命令发送失败] 云台/前端回复: {}", e.getMessage());
|
||||||
e.printStackTrace();
|
}
|
||||||
} catch (ParseException e) {
|
}, eventResult -> {
|
||||||
e.printStackTrace();
|
// 成功的回复
|
||||||
}
|
try {
|
||||||
}, eventResult -> {
|
responseAck(serverTransaction, eventResult.statusCode);
|
||||||
// 成功的回复
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
try {
|
logger.error("[命令发送失败] 云台/前端回复: {}", e.getMessage());
|
||||||
responseAck(serverTransaction, eventResult.statusCode);
|
}
|
||||||
} catch (SipException e) {
|
});
|
||||||
e.printStackTrace();
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
} catch (InvalidArgumentException e) {
|
logger.error("[命令发送失败] 云台/前端: {}", e.getMessage());
|
||||||
e.printStackTrace();
|
}
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
||||||
@ -89,7 +90,12 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
|
|||||||
// 先从会话内查找
|
// 先从会话内查找
|
||||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, callIdHeader.getCallId(), null);
|
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, callIdHeader.getCallId(), null);
|
||||||
if (ssrcTransaction != null) { // 兼容海康 媒体通知 消息from字段不是设备ID的问题
|
if (ssrcTransaction != null) { // 兼容海康 媒体通知 消息from字段不是设备ID的问题
|
||||||
cmder.streamByeCmd(device.getDeviceId(), ssrcTransaction.getChannelId(), null, callIdHeader.getCallId());
|
|
||||||
|
try {
|
||||||
|
cmder.streamByeCmd(device, ssrcTransaction.getChannelId(), null, callIdHeader.getCallId());
|
||||||
|
} catch (InvalidArgumentException | ParseException | SsrcTransactionNotFoundException | SipException e) {
|
||||||
|
logger.error("[录像流]推送完毕,收到关流通知, 发送BYE失败 {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
// 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题,需要将点播CallId进行上下级绑定
|
// 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题,需要将点播CallId进行上下级绑定
|
||||||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, ssrcTransaction.getChannelId(), null, null);
|
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, ssrcTransaction.getChannelId(), null, null);
|
||||||
@ -99,7 +105,11 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
|
|||||||
logger.warn("[级联消息发送]:发送MediaStatus发现上级平台{}不存在", sendRtpItem.getPlatformId());
|
logger.warn("[级联消息发送]:发送MediaStatus发现上级平台{}不存在", sendRtpItem.getPlatformId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sipCommanderFroPlatform.sendMediaStatusNotify(parentPlatform, sendRtpItem);
|
try {
|
||||||
|
sipCommanderFroPlatform.sendMediaStatusNotify(parentPlatform, sendRtpItem);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 录像播放完毕: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,14 +49,14 @@ public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent imp
|
|||||||
try {
|
try {
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(getServerTransaction(evt), Response.OK);
|
responseAck(getServerTransaction(evt), Response.OK);
|
||||||
} catch (SipException e) {
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
logger.error("[命令发送失败] DeviceInfo查询回复: {}", e.getMessage());
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
String sn = rootElement.element("SN").getText();
|
String sn = rootElement.element("SN").getText();
|
||||||
cmderFroPlatform.deviceInfoResponse(parentPlatform, sn, fromHeader.getTag());
|
try {
|
||||||
|
cmderFroPlatform.deviceInfoResponse(parentPlatform, sn, fromHeader.getTag());
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 DeviceInfo查询回复: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,14 +62,14 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i
|
|||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
try {
|
try {
|
||||||
responseAck(getServerTransaction(evt), Response.OK);
|
responseAck(getServerTransaction(evt), Response.OK);
|
||||||
} catch (SipException e) {
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复200OK: {}", e.getMessage());
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
String sn = rootElement.element("SN").getText();
|
String sn = rootElement.element("SN").getText();
|
||||||
cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag());
|
try {
|
||||||
|
cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag());
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,53 +103,45 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
|
|||||||
DeviceChannel deviceChannel = storager.queryChannelInParentPlatform(parentPlatform.getServerGBId(), channelId);
|
DeviceChannel deviceChannel = storager.queryChannelInParentPlatform(parentPlatform.getServerGBId(), channelId);
|
||||||
// 接收录像数据
|
// 接收录像数据
|
||||||
recordEndEventListener.addEndEventHandler(deviceChannel.getDeviceId(), channelId, (recordInfo)->{
|
recordEndEventListener.addEndEventHandler(deviceChannel.getDeviceId(), channelId, (recordInfo)->{
|
||||||
cmderFroPlatform.recordInfo(deviceChannel, parentPlatform, fromHeader.getTag(), recordInfo);
|
try {
|
||||||
|
cmderFroPlatform.recordInfo(deviceChannel, parentPlatform, fromHeader.getTag(), recordInfo);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 回复录像数据: {}", e.getMessage());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
commander.recordInfoQuery(device, channelId, DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(startTime),
|
try {
|
||||||
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTime), sn, secrecy, type, (eventResult -> {
|
commander.recordInfoQuery(device, channelId, DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(startTime),
|
||||||
// 回复200 OK
|
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(endTime), sn, secrecy, type, (eventResult -> {
|
||||||
try {
|
// 回复200 OK
|
||||||
responseAck(serverTransaction, Response.OK);
|
try {
|
||||||
} catch (SipException e) {
|
responseAck(serverTransaction, Response.OK);
|
||||||
e.printStackTrace();
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
} catch (InvalidArgumentException e) {
|
logger.error("[命令发送失败] 录像查询回复: {}", e.getMessage());
|
||||||
e.printStackTrace();
|
}
|
||||||
} catch (ParseException e) {
|
}),(eventResult -> {
|
||||||
e.printStackTrace();
|
// 查询失败
|
||||||
}
|
try {
|
||||||
}),(eventResult -> {
|
responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
|
||||||
// 查询失败
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
try {
|
logger.error("[命令发送失败] 录像查询回复: {}", e.getMessage());
|
||||||
responseAck(serverTransaction, eventResult.statusCode, eventResult.msg);
|
}
|
||||||
} catch (SipException e) {
|
}));
|
||||||
e.printStackTrace();
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
} catch (InvalidArgumentException e) {
|
logger.error("[命令发送失败] 录像查询: {}", e.getMessage());
|
||||||
e.printStackTrace();
|
}
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
}else if (channelSources.get(1).getCount() > 0) { // 直播流
|
}else if (channelSources.get(1).getCount() > 0) { // 直播流
|
||||||
// TODO
|
// TODO
|
||||||
try {
|
try {
|
||||||
responseAck(serverTransaction, Response.NOT_IMPLEMENTED); // 回复未实现
|
responseAck(serverTransaction, Response.NOT_IMPLEMENTED); // 回复未实现
|
||||||
} catch (SipException e) {
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
logger.error("[命令发送失败] 录像查询: {}", e.getMessage());
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}else { // 错误的请求
|
}else { // 错误的请求
|
||||||
try {
|
try {
|
||||||
responseAck(serverTransaction, Response.BAD_REQUEST);
|
responseAck(serverTransaction, Response.BAD_REQUEST);
|
||||||
} catch (SipException e) {
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
logger.error("[命令发送失败] 录像查询: {}", e.getMessage());
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,89 +87,73 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
|
|||||||
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
taskQueue.offer(new HandlerCatchData(evt, device, element));
|
taskQueue.offer(new HandlerCatchData(evt, device, element));
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
|
ServerTransaction serverTransaction = getServerTransaction(evt);
|
||||||
try {
|
try {
|
||||||
ServerTransaction serverTransaction = getServerTransaction(evt);
|
|
||||||
responseAck(serverTransaction, Response.OK);
|
responseAck(serverTransaction, Response.OK);
|
||||||
if (!taskQueueHandlerRun) {
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
taskQueueHandlerRun = true;
|
logger.error("[命令发送失败] 目录查询回复: {}", e.getMessage());
|
||||||
taskExecutor.execute(()-> {
|
}
|
||||||
while (!taskQueue.isEmpty()) {
|
if (!taskQueueHandlerRun) {
|
||||||
HandlerCatchData take = taskQueue.poll();
|
taskQueueHandlerRun = true;
|
||||||
try {
|
taskExecutor.execute(() -> {
|
||||||
Element rootElement = getRootElement(take.getEvt(), take.getDevice().getCharset());
|
while (!taskQueue.isEmpty()) {
|
||||||
if (rootElement == null) {
|
HandlerCatchData take = taskQueue.poll();
|
||||||
logger.warn("[ 收到通道 ] content cannot be null, {}", evt.getRequest());
|
Element rootElement = null;
|
||||||
continue;
|
try {
|
||||||
}
|
rootElement = getRootElement(take.getEvt(), take.getDevice().getCharset());
|
||||||
Element deviceListElement = rootElement.element("DeviceList");
|
} catch (DocumentException e) {
|
||||||
Element sumNumElement = rootElement.element("SumNum");
|
logger.error("[xml解析] 失败: ", e);
|
||||||
Element snElement = rootElement.element("SN");
|
continue;
|
||||||
if (snElement == null || sumNumElement == null || deviceListElement == null) {
|
|
||||||
responseAck(serverTransaction, Response.BAD_REQUEST, "xml error");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int sumNum = Integer.parseInt(sumNumElement.getText());
|
|
||||||
|
|
||||||
if (sumNum == 0) {
|
|
||||||
logger.info("[收到通道]设备:{}的: 0个", take.getDevice().getDeviceId());
|
|
||||||
// 数据已经完整接收
|
|
||||||
storager.cleanChannelsForDevice(take.getDevice().getDeviceId());
|
|
||||||
catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null);
|
|
||||||
}else {
|
|
||||||
Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
|
|
||||||
if (deviceListIterator != null) {
|
|
||||||
List<DeviceChannel> channelList = new ArrayList<>();
|
|
||||||
// 遍历DeviceList
|
|
||||||
while (deviceListIterator.hasNext()) {
|
|
||||||
Element itemDevice = deviceListIterator.next();
|
|
||||||
Element channelDeviceElement = itemDevice.element("DeviceID");
|
|
||||||
if (channelDeviceElement == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null);
|
|
||||||
deviceChannel.setDeviceId(take.getDevice().getDeviceId());
|
|
||||||
|
|
||||||
channelList.add(deviceChannel);
|
|
||||||
}
|
|
||||||
int sn = Integer.parseInt(snElement.getText());
|
|
||||||
catalogDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, take.getDevice(), channelList);
|
|
||||||
logger.info("[收到通道]设备: {} -> {}个,{}/{}", take.getDevice().getDeviceId(), channelList.size(), catalogDataCatch.get(take.getDevice().getDeviceId()) == null ? 0 :catalogDataCatch.get(take.getDevice().getDeviceId()).size(), sumNum);
|
|
||||||
if (catalogDataCatch.get(take.getDevice().getDeviceId()).size() == sumNum) {
|
|
||||||
// 数据已经完整接收, 此时可能存在某个设备离线变上线的情况,但是考虑到性能,此处不做处理,
|
|
||||||
// 目前支持设备通道上线通知时和设备上线时向上级通知
|
|
||||||
boolean resetChannelsResult = storager.resetChannels(take.getDevice().getDeviceId(), catalogDataCatch.get(take.getDevice().getDeviceId()));
|
|
||||||
if (!resetChannelsResult) {
|
|
||||||
String errorMsg = "接收成功,写入失败,共" + sumNum + "条,已接收" + catalogDataCatch.get(take.getDevice().getDeviceId()).size() + "条";
|
|
||||||
catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), errorMsg);
|
|
||||||
}else {
|
|
||||||
catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (DocumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (SipException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
taskQueueHandlerRun = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
if (rootElement == null) {
|
||||||
}
|
logger.warn("[ 收到通道 ] content cannot be null, {}", evt.getRequest());
|
||||||
} catch (SipException e) {
|
continue;
|
||||||
throw new RuntimeException(e);
|
}
|
||||||
} catch (InvalidArgumentException e) {
|
Element deviceListElement = rootElement.element("DeviceList");
|
||||||
throw new RuntimeException(e);
|
Element sumNumElement = rootElement.element("SumNum");
|
||||||
} catch (ParseException e) {
|
Element snElement = rootElement.element("SN");
|
||||||
throw new RuntimeException(e);
|
int sumNum = Integer.parseInt(sumNumElement.getText());
|
||||||
} finally {
|
|
||||||
taskQueueHandlerRun = false;
|
if (sumNum == 0) {
|
||||||
|
logger.info("[收到通道]设备:{}的: 0个", take.getDevice().getDeviceId());
|
||||||
|
// 数据已经完整接收
|
||||||
|
storager.cleanChannelsForDevice(take.getDevice().getDeviceId());
|
||||||
|
catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null);
|
||||||
|
} else {
|
||||||
|
Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
|
||||||
|
if (deviceListIterator != null) {
|
||||||
|
List<DeviceChannel> channelList = new ArrayList<>();
|
||||||
|
// 遍历DeviceList
|
||||||
|
while (deviceListIterator.hasNext()) {
|
||||||
|
Element itemDevice = deviceListIterator.next();
|
||||||
|
Element channelDeviceElement = itemDevice.element("DeviceID");
|
||||||
|
if (channelDeviceElement == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null);
|
||||||
|
deviceChannel.setDeviceId(take.getDevice().getDeviceId());
|
||||||
|
|
||||||
|
channelList.add(deviceChannel);
|
||||||
|
}
|
||||||
|
int sn = Integer.parseInt(snElement.getText());
|
||||||
|
catalogDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, take.getDevice(), channelList);
|
||||||
|
logger.info("[收到通道]设备: {} -> {}个,{}/{}", take.getDevice().getDeviceId(), channelList.size(), catalogDataCatch.get(take.getDevice().getDeviceId()) == null ? 0 : catalogDataCatch.get(take.getDevice().getDeviceId()).size(), sumNum);
|
||||||
|
if (catalogDataCatch.get(take.getDevice().getDeviceId()).size() == sumNum) {
|
||||||
|
// 数据已经完整接收, 此时可能存在某个设备离线变上线的情况,但是考虑到性能,此处不做处理,
|
||||||
|
// 目前支持设备通道上线通知时和设备上线时向上级通知
|
||||||
|
boolean resetChannelsResult = storager.resetChannels(take.getDevice().getDeviceId(), catalogDataCatch.get(take.getDevice().getDeviceId()));
|
||||||
|
if (!resetChannelsResult) {
|
||||||
|
String errorMsg = "接收成功,写入失败,共" + sumNum + "条,已接收" + catalogDataCatch.get(take.getDevice().getDeviceId()).size() + "条";
|
||||||
|
catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), errorMsg);
|
||||||
|
} else {
|
||||||
|
catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -182,7 +166,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
|
|||||||
public SyncStatus getChannelSyncProgress(String deviceId) {
|
public SyncStatus getChannelSyncProgress(String deviceId) {
|
||||||
if (catalogDataCatch.get(deviceId) == null) {
|
if (catalogDataCatch.get(deviceId) == null) {
|
||||||
return null;
|
return null;
|
||||||
}else {
|
} else {
|
||||||
return catalogDataCatch.getSyncStatus(deviceId);
|
return catalogDataCatch.getSyncStatus(deviceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,7 +174,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
|
|||||||
public boolean isSyncRunning(String deviceId) {
|
public boolean isSyncRunning(String deviceId) {
|
||||||
if (catalogDataCatch.get(deviceId) == null) {
|
if (catalogDataCatch.get(deviceId) == null) {
|
||||||
return false;
|
return false;
|
||||||
}else {
|
} else {
|
||||||
return catalogDataCatch.isSyncRunning(deviceId);
|
return catalogDataCatch.isSyncRunning(deviceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,12 +50,12 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
Element rootElement = null;
|
|
||||||
|
ServerTransaction serverTransaction = getServerTransaction(evt);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Element rootElement = getRootElement(evt, device.getCharset());
|
||||||
|
|
||||||
ServerTransaction serverTransaction = getServerTransaction(evt);
|
|
||||||
|
|
||||||
rootElement = getRootElement(evt, device.getCharset());
|
|
||||||
if (rootElement == null) {
|
if (rootElement == null) {
|
||||||
logger.warn("[ 设备预置位查询应答 ] content cannot be null, {}", evt.getRequest());
|
logger.warn("[ 设备预置位查询应答 ] content cannot be null, {}", evt.getRequest());
|
||||||
responseAck(serverTransaction, Response.BAD_REQUEST);
|
responseAck(serverTransaction, Response.BAD_REQUEST);
|
||||||
@ -66,32 +66,29 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
|
|||||||
//该字段可能为通道或则设备的id
|
//该字段可能为通道或则设备的id
|
||||||
String deviceId = getText(rootElement, "DeviceID");
|
String deviceId = getText(rootElement, "DeviceID");
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId;
|
String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId;
|
||||||
if (snElement == null || presetListNumElement == null) {
|
if (snElement == null || presetListNumElement == null) {
|
||||||
responseAck(serverTransaction, Response.BAD_REQUEST, "xml error");
|
responseAck(serverTransaction, Response.BAD_REQUEST, "xml error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
|
int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
|
||||||
List<PresetQuerySipReq> presetQuerySipReqList = new ArrayList<>();
|
List<PresetQuerySipReq> presetQuerySipReqList = new ArrayList<>();
|
||||||
if (sumNum > 0) {
|
if (sumNum > 0) {
|
||||||
for (Iterator<Element> presetIterator = presetListNumElement.elementIterator();presetIterator.hasNext();){
|
for (Iterator<Element> presetIterator = presetListNumElement.elementIterator(); presetIterator.hasNext(); ) {
|
||||||
Element itemListElement = presetIterator.next();
|
Element itemListElement = presetIterator.next();
|
||||||
PresetQuerySipReq presetQuerySipReq = new PresetQuerySipReq();
|
PresetQuerySipReq presetQuerySipReq = new PresetQuerySipReq();
|
||||||
for (Iterator<Element> itemListIterator = itemListElement.elementIterator();itemListIterator.hasNext();){
|
for (Iterator<Element> itemListIterator = itemListElement.elementIterator(); itemListIterator.hasNext(); ) {
|
||||||
// 遍历item
|
// 遍历item
|
||||||
Element itemOne = itemListIterator.next();
|
Element itemOne = itemListIterator.next();
|
||||||
String name = itemOne.getName();
|
String name = itemOne.getName();
|
||||||
String textTrim = itemOne.getTextTrim();
|
String textTrim = itemOne.getTextTrim();
|
||||||
if("PresetID".equalsIgnoreCase(name)){
|
if ("PresetID".equalsIgnoreCase(name)) {
|
||||||
presetQuerySipReq.setPresetId(textTrim);
|
presetQuerySipReq.setPresetId(textTrim);
|
||||||
}else {
|
} else {
|
||||||
presetQuerySipReq.setPresetName(textTrim);
|
presetQuerySipReq.setPresetName(textTrim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
presetQuerySipReqList.add(presetQuerySipReq);
|
presetQuerySipReqList.add(presetQuerySipReq);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
RequestMessage requestMessage = new RequestMessage();
|
RequestMessage requestMessage = new RequestMessage();
|
||||||
requestMessage.setKey(key);
|
requestMessage.setKey(key);
|
||||||
@ -99,13 +96,9 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
|
|||||||
deferredResultHolder.invokeAllResult(requestMessage);
|
deferredResultHolder.invokeAllResult(requestMessage);
|
||||||
responseAck(serverTransaction, Response.OK);
|
responseAck(serverTransaction, Response.OK);
|
||||||
} catch (DocumentException e) {
|
} catch (DocumentException e) {
|
||||||
e.printStackTrace();
|
logger.error("[解析xml]失败: ", e);
|
||||||
} catch (InvalidArgumentException e) {
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
e.printStackTrace();
|
logger.error("[命令发送失败] 设备预置位查询应答处理: {}", e.getMessage());
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (SipException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,27 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
|
import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
|
||||||
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
||||||
|
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||||
import com.genersoft.iot.vmp.utils.GitUtil;
|
import com.genersoft.iot.vmp.utils.GitUtil;
|
||||||
import gov.nist.javax.sip.ResponseEventExt;
|
import gov.nist.javax.sip.ResponseEventExt;
|
||||||
|
import gov.nist.javax.sip.SipProviderImpl;
|
||||||
import gov.nist.javax.sip.message.SIPResponse;
|
import gov.nist.javax.sip.message.SIPResponse;
|
||||||
import gov.nist.javax.sip.stack.SIPClientTransaction;
|
import gov.nist.javax.sip.stack.SIPClientTransaction;
|
||||||
import gov.nist.javax.sip.stack.SIPDialog;
|
import gov.nist.javax.sip.stack.SIPDialog;
|
||||||
|
import gov.nist.javax.sip.stack.SIPTransaction;
|
||||||
|
import gov.nist.javax.sip.stack.SIPTransactionImpl;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.sdp.SdpFactory;
|
import javax.sdp.SdpFactory;
|
||||||
@ -54,6 +63,20 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private GitUtil gitUtil;
|
private GitUtil gitUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISIPCommander commander;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPRequestHeaderProvider headerProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(value="udpSipProvider")
|
||||||
|
private SipProviderImpl udpSipProvider;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
// 添加消息处理的订阅
|
// 添加消息处理的订阅
|
||||||
@ -71,7 +94,8 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
|
|||||||
@Override
|
@Override
|
||||||
public void process(ResponseEvent evt ){
|
public void process(ResponseEvent evt ){
|
||||||
try {
|
try {
|
||||||
Response response = evt.getResponse();
|
|
||||||
|
SIPResponse response = (SIPResponse)evt.getResponse();
|
||||||
int statusCode = response.getStatusCode();
|
int statusCode = response.getStatusCode();
|
||||||
// trying不会回复
|
// trying不会回复
|
||||||
if (statusCode == Response.TRYING) {
|
if (statusCode == Response.TRYING) {
|
||||||
@ -80,10 +104,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
|
|||||||
// 下发ack
|
// 下发ack
|
||||||
if (statusCode == Response.OK) {
|
if (statusCode == Response.OK) {
|
||||||
ResponseEventExt event = (ResponseEventExt)evt;
|
ResponseEventExt event = (ResponseEventExt)evt;
|
||||||
SIPDialog dialog = new SIPDialog((SIPClientTransaction) event.getClientTransaction(), (SIPResponse) event.getResponse());
|
|
||||||
CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
|
|
||||||
Request reqAck = dialog.createAck(cseq.getSeqNumber());
|
|
||||||
SipURI requestURI = (SipURI) reqAck.getRequestURI();
|
|
||||||
String contentString = new String(response.getRawContent());
|
String contentString = new String(response.getRawContent());
|
||||||
// jainSip不支持y=字段, 移除以解析。
|
// jainSip不支持y=字段, 移除以解析。
|
||||||
int ssrcIndex = contentString.indexOf("y=");
|
int ssrcIndex = contentString.indexOf("y=");
|
||||||
@ -96,29 +117,15 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
|
|||||||
} else {
|
} else {
|
||||||
sdp = SdpFactory.getInstance().createSessionDescription(contentString);
|
sdp = SdpFactory.getInstance().createSessionDescription(contentString);
|
||||||
}
|
}
|
||||||
requestURI.setUser(sdp.getOrigin().getUsername());
|
SipURI requestUri = sipFactory.createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort());
|
||||||
try {
|
Request reqAck = headerProvider.createAckRequest(requestUri, response);
|
||||||
requestURI.setHost(event.getRemoteIpAddress());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
requestURI.setPort(event.getRemotePort());
|
|
||||||
reqAck.setRequestURI(requestURI);
|
|
||||||
UserAgentHeader userAgentHeader = SipUtils.createUserAgentHeader(sipFactory, gitUtil);
|
|
||||||
reqAck.addHeader(userAgentHeader);
|
|
||||||
Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
|
|
||||||
reqAck.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
|
|
||||||
logger.info("[回复ack] {}-> {}:{} ",requestURI, event.getRemoteIpAddress(), event.getRemotePort());
|
|
||||||
|
|
||||||
dialog.sendAck(reqAck);
|
logger.info("[回复ack] {}-> {}:{} ", sdp.getOrigin().getUsername(), event.getRemoteIpAddress(), event.getRemotePort());
|
||||||
|
commander.transmitRequest(response.getTopmostViaHeader().getTransport(), reqAck, null, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (InvalidArgumentException | SipException e) {
|
} catch (InvalidArgumentException | ParseException | SipException | SdpParseException e) {
|
||||||
e.printStackTrace();
|
logger.info("[点播回复ACK],异常:", e );
|
||||||
} catch (ParseException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (SdpParseException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,13 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
import javax.sip.ResponseEvent;
|
import javax.sip.ResponseEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
import javax.sip.header.CallIdHeader;
|
import javax.sip.header.CallIdHeader;
|
||||||
import javax.sip.header.WWWAuthenticateHeader;
|
import javax.sip.header.WWWAuthenticateHeader;
|
||||||
import javax.sip.message.Response;
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description:Register响应处理器
|
* @description:Register响应处理器
|
||||||
@ -87,7 +90,11 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
|
|||||||
|
|
||||||
if (response.getStatusCode() == Response.UNAUTHORIZED) {
|
if (response.getStatusCode() == Response.UNAUTHORIZED) {
|
||||||
WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
|
WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
|
||||||
sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true, platformRegisterInfo.isRegister());
|
try {
|
||||||
|
sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true, platformRegisterInfo.isRegister());
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 再次注册: {}", e.getMessage());
|
||||||
|
}
|
||||||
}else if (response.getStatusCode() == Response.OK){
|
}else if (response.getStatusCode() == Response.OK){
|
||||||
|
|
||||||
if (platformRegisterInfo.isRegister()) {
|
if (platformRegisterInfo.isRegister()) {
|
||||||
|
@ -70,4 +70,47 @@ public class SipUtils {
|
|||||||
return String.valueOf(System.currentTimeMillis());
|
return String.valueOf(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云台指令码计算
|
||||||
|
*
|
||||||
|
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||||
|
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||||
|
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||||
|
* @param moveSpeed 镜头移动速度 默认 0XFF (0-255)
|
||||||
|
* @param zoomSpeed 镜头缩放速度 默认 0X1 (0-255)
|
||||||
|
*/
|
||||||
|
public static String cmdString(int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) {
|
||||||
|
int cmdCode = 0;
|
||||||
|
if (leftRight == 2) {
|
||||||
|
cmdCode|=0x01; // 右移
|
||||||
|
} else if(leftRight == 1) {
|
||||||
|
cmdCode|=0x02; // 左移
|
||||||
|
}
|
||||||
|
if (upDown == 2) {
|
||||||
|
cmdCode|=0x04; // 下移
|
||||||
|
} else if(upDown == 1) {
|
||||||
|
cmdCode|=0x08; // 上移
|
||||||
|
}
|
||||||
|
if (inOut == 2) {
|
||||||
|
cmdCode |= 0x10; // 放大
|
||||||
|
} else if(inOut == 1) {
|
||||||
|
cmdCode |= 0x20; // 缩小
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder("A50F01");
|
||||||
|
String strTmp;
|
||||||
|
strTmp = String.format("%02X", cmdCode);
|
||||||
|
builder.append(strTmp, 0, 2);
|
||||||
|
strTmp = String.format("%02X", moveSpeed);
|
||||||
|
builder.append(strTmp, 0, 2);
|
||||||
|
builder.append(strTmp, 0, 2);
|
||||||
|
strTmp = String.format("%X", zoomSpeed);
|
||||||
|
builder.append(strTmp, 0, 1).append("0");
|
||||||
|
//计算校验码
|
||||||
|
int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + moveSpeed + moveSpeed + (zoomSpeed /*<< 4*/ & 0XF0)) % 0X100;
|
||||||
|
strTmp = String.format("%02X", checkCode);
|
||||||
|
builder.append(strTmp, 0, 2);
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.media.zlm;
|
package com.genersoft.iot.vmp.media.zlm;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -7,6 +8,7 @@ import java.util.Map;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
@ -31,6 +33,8 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description:针对 ZLMediaServer的hook事件监听
|
* @description:针对 ZLMediaServer的hook事件监听
|
||||||
@ -58,6 +62,9 @@ public class ZLMHttpHookListener {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IMediaServerService mediaServerService;
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
@ -515,7 +522,11 @@ public class ZLMHttpHookListener {
|
|||||||
String platformId = sendRtpItem.getPlatformId();
|
String platformId = sendRtpItem.getPlatformId();
|
||||||
ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
|
ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
|
||||||
|
|
||||||
commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
|
try {
|
||||||
|
commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,21 +563,41 @@ public class ZLMHttpHookListener {
|
|||||||
if (sendRtpItems.size() > 0) {
|
if (sendRtpItems.size() > 0) {
|
||||||
for (SendRtpItem sendRtpItem : sendRtpItems) {
|
for (SendRtpItem sendRtpItem : sendRtpItems) {
|
||||||
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
||||||
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
|
try {
|
||||||
|
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
|
redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
|
||||||
sendRtpItem.getCallId(), sendRtpItem.getStreamId());
|
sendRtpItem.getCallId(), sendRtpItem.getStreamId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(),
|
Device device = deviceService.queryDevice(streamInfoForPlayCatch.getDeviceID());
|
||||||
streamInfoForPlayCatch.getStream(), null);
|
if (device != null) {
|
||||||
|
try {
|
||||||
|
cmder.streamByeCmd(device, streamInfoForPlayCatch.getChannelId(),
|
||||||
|
streamInfoForPlayCatch.getStream(), null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||||
|
logger.error("[无人观看]点播, 发送BYE失败 {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
redisCatchStorage.stopPlay(streamInfoForPlayCatch);
|
redisCatchStorage.stopPlay(streamInfoForPlayCatch);
|
||||||
storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
|
storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
|
||||||
}else{
|
}else{
|
||||||
StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, streamId, null);
|
StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, streamId, null);
|
||||||
if (streamInfoForPlayBackCatch != null) {
|
if (streamInfoForPlayBackCatch != null) {
|
||||||
cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(),
|
Device device = deviceService.queryDevice(streamInfoForPlayCatch.getDeviceID());
|
||||||
streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream(), null);
|
if (device != null) {
|
||||||
|
try {
|
||||||
|
cmder.streamByeCmd(device,streamInfoForPlayBackCatch.getChannelId(),
|
||||||
|
streamInfoForPlayBackCatch.getStream(), null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException |
|
||||||
|
SsrcTransactionNotFoundException e) {
|
||||||
|
logger.error("[无人观看]回放, 发送BYE失败 {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch.getDeviceID(),
|
redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch.getDeviceID(),
|
||||||
streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream(), null);
|
streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream(), null);
|
||||||
}else {
|
}else {
|
||||||
@ -689,7 +720,11 @@ public class ZLMHttpHookListener {
|
|||||||
if (sendRtpItems.size() > 0) {
|
if (sendRtpItems.size() > 0) {
|
||||||
for (SendRtpItem sendRtpItem : sendRtpItems) {
|
for (SendRtpItem sendRtpItem : sendRtpItems) {
|
||||||
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
||||||
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
|
try {
|
||||||
|
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
|
redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
|
||||||
sendRtpItem.getCallId(), sendRtpItem.getStreamId());
|
sendRtpItem.getCallId(), sendRtpItem.getStreamId());
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,6 @@ public class ZLMMediaListManager {
|
|||||||
private Map<String, ChannelOnlineEvent> channelOnPublishEvents = new ConcurrentHashMap<>();
|
private Map<String, ChannelOnlineEvent> channelOnPublishEvents = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public StreamPushItem addPush(MediaItem mediaItem) {
|
public StreamPushItem addPush(MediaItem mediaItem) {
|
||||||
// 查找此直播流是否存在redis预设gbId
|
|
||||||
StreamPushItem transform = streamPushService.transform(mediaItem);
|
StreamPushItem transform = streamPushService.transform(mediaItem);
|
||||||
StreamPushItem pushInDb = streamPushService.getPush(mediaItem.getApp(), mediaItem.getStream());
|
StreamPushItem pushInDb = streamPushService.getPush(mediaItem.getApp(), mediaItem.getStream());
|
||||||
transform.setPushIng(mediaItem.isRegist());
|
transform.setPushIng(mediaItem.isRegist());
|
||||||
@ -82,15 +81,14 @@ public class ZLMMediaListManager {
|
|||||||
streamPushMapper.update(transform);
|
streamPushMapper.update(transform);
|
||||||
gbStreamMapper.updateMediaServer(mediaItem.getApp(), mediaItem.getStream(), mediaItem.getMediaServerId());
|
gbStreamMapper.updateMediaServer(mediaItem.getApp(), mediaItem.getStream(), mediaItem.getMediaServerId());
|
||||||
}
|
}
|
||||||
if (transform != null) {
|
ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(transform.getApp(), transform.getStream());
|
||||||
if (getChannelOnlineEventLister(transform.getApp(), transform.getStream()) != null) {
|
if ( channelOnlineEventLister != null) {
|
||||||
try {
|
try {
|
||||||
getChannelOnlineEventLister(transform.getApp(), transform.getStream()).run(transform.getApp(), transform.getStream(), transform.getServerId());
|
channelOnlineEventLister.run(transform.getApp(), transform.getStream(), transform.getServerId());;
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
throw new RuntimeException(e);
|
logger.error("addPush: ", e);
|
||||||
}
|
|
||||||
removedChannelOnlineEventLister(transform.getApp(), transform.getStream());
|
|
||||||
}
|
}
|
||||||
|
removedChannelOnlineEventLister(transform.getApp(), transform.getStream());
|
||||||
}
|
}
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
@ -99,11 +97,12 @@ public class ZLMMediaListManager {
|
|||||||
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
|
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||||
// 查看推流状态
|
// 查看推流状态
|
||||||
if (zlmrtpServerFactory.isStreamReady(mediaServerItem, app, stream)) {
|
if (zlmrtpServerFactory.isStreamReady(mediaServerItem, app, stream)) {
|
||||||
if (getChannelOnlineEventLister(app, stream) != null) {
|
ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(app, stream);
|
||||||
|
if (channelOnlineEventLister != null) {
|
||||||
try {
|
try {
|
||||||
getChannelOnlineEventLister(app, stream).run(app, stream, mediaServerId);
|
channelOnlineEventLister.run(app, stream, mediaServerId);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
throw new RuntimeException(e);
|
logger.error("sendStreamEvent: ", e);
|
||||||
}
|
}
|
||||||
removedChannelOnlineEventLister(app, stream);
|
removedChannelOnlineEventLister(app, stream);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,9 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -95,7 +98,11 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
logger.info("[设备上线,首次注册]: {},查询设备信息以及通道信息", device.getDeviceId());
|
logger.info("[设备上线,首次注册]: {},查询设备信息以及通道信息", device.getDeviceId());
|
||||||
deviceMapper.add(device);
|
deviceMapper.add(device);
|
||||||
redisCatchStorage.updateDevice(device);
|
redisCatchStorage.updateDevice(device);
|
||||||
commander.deviceInfoQuery(device);
|
try {
|
||||||
|
commander.deviceInfoQuery(device);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage());
|
||||||
|
}
|
||||||
sync(device);
|
sync(device);
|
||||||
}else {
|
}else {
|
||||||
if(device.getOnline() == 0){
|
if(device.getOnline() == 0){
|
||||||
@ -104,7 +111,11 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
logger.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId());
|
logger.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId());
|
||||||
deviceMapper.update(device);
|
deviceMapper.update(device);
|
||||||
redisCatchStorage.updateDevice(device);
|
redisCatchStorage.updateDevice(device);
|
||||||
commander.deviceInfoQuery(device);
|
try {
|
||||||
|
commander.deviceInfoQuery(device);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage());
|
||||||
|
}
|
||||||
sync(device);
|
sync(device);
|
||||||
// TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台
|
// TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台
|
||||||
}else {
|
}else {
|
||||||
@ -129,6 +140,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void offline(String deviceId) {
|
public void offline(String deviceId) {
|
||||||
|
logger.info("[设备离线], device:{}", deviceId);
|
||||||
Device device = deviceMapper.getDeviceByDeviceId(deviceId);
|
Device device = deviceMapper.getDeviceByDeviceId(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
return;
|
return;
|
||||||
@ -238,15 +250,28 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
}
|
}
|
||||||
int sn = (int)((Math.random()*9+1)*100000);
|
int sn = (int)((Math.random()*9+1)*100000);
|
||||||
catalogResponseMessageHandler.setChannelSyncReady(device, sn);
|
catalogResponseMessageHandler.setChannelSyncReady(device, sn);
|
||||||
sipCommander.catalogQuery(device, sn, event -> {
|
try {
|
||||||
String errorMsg = String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg);
|
sipCommander.catalogQuery(device, sn, event -> {
|
||||||
|
String errorMsg = String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg);
|
||||||
|
catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
|
||||||
|
});
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[同步通道], 信令发送失败:{}", e.getMessage() );
|
||||||
|
String errorMsg = String.format("同步通道失败,信令发送失败: %s", e.getMessage());
|
||||||
catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
|
catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Device queryDevice(String deviceId) {
|
public Device queryDevice(String deviceId) {
|
||||||
return deviceMapper.getDeviceByDeviceId(deviceId);
|
Device device = redisCatchStorage.getDevice(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
device = deviceMapper.getDeviceByDeviceId(deviceId);
|
||||||
|
if (device != null) {
|
||||||
|
redisCatchStorage.updateDevice(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -266,7 +291,11 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
if (device == null || device.getOnline() == 0) {
|
if (device == null || device.getOnline() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sipCommander.deviceStatusQuery(device, null);
|
try {
|
||||||
|
sipCommander.deviceStatusQuery(device, null);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 设备状态查询: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,10 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
import javax.sip.TimeoutEvent;
|
import javax.sip.TimeoutEvent;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -99,9 +102,13 @@ public class PlatformServiceImpl implements IPlatformService {
|
|||||||
if (parentPlatform.isEnable()) {
|
if (parentPlatform.isEnable()) {
|
||||||
// 保存时启用就发送注册
|
// 保存时启用就发送注册
|
||||||
// 注册成功时由程序直接调用了online方法
|
// 注册成功时由程序直接调用了online方法
|
||||||
commanderForPlatform.register(parentPlatform, eventResult -> {
|
try {
|
||||||
logger.info("[国标级联] {},添加向上级注册失败,请确定上级平台可用时重新保存", parentPlatform.getServerGBId());
|
commanderForPlatform.register(parentPlatform, eventResult -> {
|
||||||
}, null);
|
logger.info("[国标级联] {},添加向上级注册失败,请确定上级平台可用时重新保存", parentPlatform.getServerGBId());
|
||||||
|
}, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result > 0;
|
return result > 0;
|
||||||
}
|
}
|
||||||
@ -130,46 +137,62 @@ public class PlatformServiceImpl implements IPlatformService {
|
|||||||
// 添加注册任务
|
// 添加注册任务
|
||||||
dynamicTask.startDelay(registerTaskKey,
|
dynamicTask.startDelay(registerTaskKey,
|
||||||
// 注册失败(注册成功时由程序直接调用了online方法)
|
// 注册失败(注册成功时由程序直接调用了online方法)
|
||||||
()->commanderForPlatform.register(parentPlatform, eventResult -> offline(parentPlatform),null),
|
()-> {
|
||||||
|
try {
|
||||||
|
commanderForPlatform.register(parentPlatform, eventResult -> offline(parentPlatform),null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
},
|
||||||
(parentPlatform.getExpires() - 10) *1000);
|
(parentPlatform.getExpires() - 10) *1000);
|
||||||
|
|
||||||
final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId();
|
final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId();
|
||||||
if (!dynamicTask.contains(keepaliveTaskKey)) {
|
if (!dynamicTask.contains(keepaliveTaskKey)) {
|
||||||
// 添加心跳任务
|
// 添加心跳任务
|
||||||
dynamicTask.startCron(keepaliveTaskKey,
|
dynamicTask.startCron(keepaliveTaskKey,
|
||||||
()-> commanderForPlatform.keepalive(parentPlatform, eventResult -> {
|
()-> {
|
||||||
// 心跳失败
|
try {
|
||||||
if (eventResult.type == SipSubscribe.EventResultType.timeout) {
|
commanderForPlatform.keepalive(parentPlatform, eventResult -> {
|
||||||
// 心跳超时
|
// 心跳失败
|
||||||
ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
|
if (eventResult.type == SipSubscribe.EventResultType.timeout) {
|
||||||
// 此时是第三次心跳超时, 平台离线
|
// 心跳超时
|
||||||
if (platformCatch.getKeepAliveReply() == 2) {
|
ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
|
||||||
// 设置平台离线,并重新注册
|
// 此时是第三次心跳超时, 平台离线
|
||||||
offline(parentPlatform);
|
if (platformCatch.getKeepAliveReply() == 2) {
|
||||||
logger.info("[国标级联] {},三次心跳超时后再次发起注册", parentPlatform.getServerGBId());
|
// 设置平台离线,并重新注册
|
||||||
commanderForPlatform.register(parentPlatform, eventResult1 -> {
|
offline(parentPlatform);
|
||||||
logger.info("[国标级联] {},三次心跳超时后再次发起注册仍然失败,开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId());
|
logger.info("[国标级联] {},三次心跳超时后再次发起注册", parentPlatform.getServerGBId());
|
||||||
// 添加注册任务
|
try {
|
||||||
dynamicTask.startCron(registerTaskKey,
|
commanderForPlatform.register(parentPlatform, eventResult1 -> {
|
||||||
// 注册失败(注册成功时由程序直接调用了online方法)
|
logger.info("[国标级联] {},三次心跳超时后再次发起注册仍然失败,开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId());
|
||||||
()->logger.info("[国标级联] {},平台离线后持续发起注册,失败", parentPlatform.getServerGBId()),
|
// 添加注册任务
|
||||||
60*1000);
|
dynamicTask.startCron(registerTaskKey,
|
||||||
}, null);
|
// 注册失败(注册成功时由程序直接调用了online方法)
|
||||||
}
|
()->logger.info("[国标级联] {},平台离线后持续发起注册,失败", parentPlatform.getServerGBId()),
|
||||||
|
60*1000);
|
||||||
|
}, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 注册: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
logger.warn("[国标级联]发送心跳收到错误,code: {}, msg: {}", eventResult.statusCode, eventResult.msg);
|
logger.warn("[国标级联]发送心跳收到错误,code: {}, msg: {}", eventResult.statusCode, eventResult.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, eventResult -> {
|
}, eventResult -> {
|
||||||
// 心跳成功
|
// 心跳成功
|
||||||
// 清空之前的心跳超时计数
|
// 清空之前的心跳超时计数
|
||||||
ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
|
ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
|
||||||
if (platformCatch.getKeepAliveReply() > 0) {
|
if (platformCatch.getKeepAliveReply() > 0) {
|
||||||
platformCatch.setKeepAliveReply(0);
|
platformCatch.setKeepAliveReply(0);
|
||||||
redisCatchStorage.updatePlatformCatchInfo(platformCatch);
|
redisCatchStorage.updatePlatformCatchInfo(platformCatch);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送心跳: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
(parentPlatform.getKeepTimeout() - 10)*1000);
|
(parentPlatform.getKeepTimeout() - 10)*1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,14 +248,18 @@ public class PlatformServiceImpl implements IPlatformService {
|
|||||||
@Override
|
@Override
|
||||||
public void login(ParentPlatform parentPlatform) {
|
public void login(ParentPlatform parentPlatform) {
|
||||||
final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId();
|
final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId();
|
||||||
commanderForPlatform.register(parentPlatform, eventResult1 -> {
|
try {
|
||||||
logger.info("[国标级联] {},开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId());
|
commanderForPlatform.register(parentPlatform, eventResult1 -> {
|
||||||
// 添加注册任务
|
logger.info("[国标级联] {},开始定时发起注册,间隔为1分钟", parentPlatform.getServerGBId());
|
||||||
dynamicTask.startCron(registerTaskKey,
|
// 添加注册任务
|
||||||
// 注册失败(注册成功时由程序直接调用了online方法)
|
dynamicTask.startCron(registerTaskKey,
|
||||||
()->logger.info("[国标级联] {},平台离线后持续发起注册,失败", parentPlatform.getServerGBId()),
|
// 注册失败(注册成功时由程序直接调用了online方法)
|
||||||
60*1000);
|
()->logger.info("[国标级联] {},平台离线后持续发起注册,失败", parentPlatform.getServerGBId()),
|
||||||
}, null);
|
60*1000);
|
||||||
|
}, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联注册: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -259,7 +286,12 @@ public class PlatformServiceImpl implements IPlatformService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 发送GPS消息
|
// 发送GPS消息
|
||||||
commanderForPlatform.sendNotifyMobilePosition(platform, gpsMsgInfo, subscribe);
|
try {
|
||||||
|
commanderForPlatform.sendNotifyMobilePosition(platform, gpsMsgInfo, subscribe);
|
||||||
|
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
|
||||||
|
IllegalAccessException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 移动位置通知: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,17 @@ package com.genersoft.iot.vmp.service.impl;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
import javax.sip.ResponseEvent;
|
import javax.sip.ResponseEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
|
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -22,13 +28,6 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||||
@ -92,6 +91,10 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private VideoStreamSessionManager streamSession;
|
private VideoStreamSessionManager streamSession;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserSetting userSetting;
|
private UserSetting userSetting;
|
||||||
|
|
||||||
@ -261,14 +264,14 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
System.out.println("设置超时任务: " + timeOutTaskKey);
|
System.out.println("设置超时任务: " + timeOutTaskKey);
|
||||||
dynamicTask.startDelay( timeOutTaskKey,()->{
|
dynamicTask.startDelay( timeOutTaskKey,()->{
|
||||||
|
|
||||||
SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc());
|
||||||
if (dialog != null) {
|
timeoutCallback.run(1, "收流超时");
|
||||||
logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc());
|
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
||||||
timeoutCallback.run(1, "收流超时");
|
try {
|
||||||
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
cmder.streamByeCmd(device, channelId, finalSsrcInfo.getStream(), null);
|
||||||
cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null);
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
}else {
|
logger.error("[点播超时], 发送BYE失败 {}", e.getMessage());
|
||||||
logger.info("[点播超时] 消息未响应 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc());
|
} catch (SsrcTransactionNotFoundException e) {
|
||||||
timeoutCallback.run(0, "点播超时");
|
timeoutCallback.run(0, "点播超时");
|
||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
||||||
mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
|
mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
|
||||||
@ -282,73 +285,87 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
logger.info("[点播端口分配异常],deviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channelId, ssrcInfo);
|
logger.info("[点播端口分配异常],deviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channelId, ssrcInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
|
try {
|
||||||
logger.info("收到订阅消息: " + response.toJSONString());
|
cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
|
||||||
System.out.println("停止超时任务: " + timeOutTaskKey);
|
logger.info("收到订阅消息: " + response.toJSONString());
|
||||||
dynamicTask.stop(timeOutTaskKey);
|
System.out.println("停止超时任务: " + timeOutTaskKey);
|
||||||
// hook响应
|
dynamicTask.stop(timeOutTaskKey);
|
||||||
onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid);
|
// hook响应
|
||||||
hookEvent.response(mediaServerItemInuse, response);
|
onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid);
|
||||||
logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
|
hookEvent.response(mediaServerItemInuse, response);
|
||||||
|
logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
|
||||||
|
|
||||||
}, (event) -> {
|
}, (event) -> {
|
||||||
ResponseEvent responseEvent = (ResponseEvent)event.event;
|
ResponseEvent responseEvent = (ResponseEvent)event.event;
|
||||||
String contentString = new String(responseEvent.getResponse().getRawContent());
|
String contentString = new String(responseEvent.getResponse().getRawContent());
|
||||||
// 获取ssrc
|
// 获取ssrc
|
||||||
int ssrcIndex = contentString.indexOf("y=");
|
int ssrcIndex = contentString.indexOf("y=");
|
||||||
// 检查是否有y字段
|
// 检查是否有y字段
|
||||||
if (ssrcIndex >= 0) {
|
if (ssrcIndex >= 0) {
|
||||||
//ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
|
//ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
|
||||||
String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
|
String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
|
||||||
// 查询到ssrc不一致且开启了ssrc校验则需要针对处理
|
// 查询到ssrc不一致且开启了ssrc校验则需要针对处理
|
||||||
if (ssrc.equals(ssrcInResponse)) {
|
if (ssrc.equals(ssrcInResponse)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
logger.info("[点播消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse );
|
|
||||||
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
|
|
||||||
logger.info("[点播消息] SSRC修正 {}->{}", ssrc, ssrcInResponse);
|
|
||||||
|
|
||||||
if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
|
|
||||||
// ssrc 不可用
|
|
||||||
// 释放ssrc
|
|
||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
|
||||||
streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
|
||||||
event.msg = "下级自定义了ssrc,但是此ssrc不可用";
|
|
||||||
event.statusCode = 400;
|
|
||||||
errorEvent.response(event);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
logger.info("[点播消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse );
|
||||||
|
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
|
||||||
|
logger.info("[点播消息] SSRC修正 {}->{}", ssrc, ssrcInResponse);
|
||||||
|
|
||||||
|
if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
|
||||||
|
// ssrc 不可用
|
||||||
|
// 释放ssrc
|
||||||
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
||||||
|
streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
||||||
|
event.msg = "下级自定义了ssrc,但是此ssrc不可用";
|
||||||
|
event.statusCode = 400;
|
||||||
|
errorEvent.response(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单端口模式streamId也有变化,需要重新设置监听
|
||||||
|
if (!mediaServerItem.isRtpEnable()) {
|
||||||
|
// 添加订阅
|
||||||
|
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
|
||||||
|
subscribe.removeSubscribe(hookSubscribe);
|
||||||
|
hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
|
||||||
|
subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response)->{
|
||||||
|
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
|
||||||
|
dynamicTask.stop(timeOutTaskKey);
|
||||||
|
// hook响应
|
||||||
|
onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid);
|
||||||
|
hookEvent.response(mediaServerItemInUse, response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 关闭rtp server
|
||||||
|
mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
|
||||||
|
// 重新开启ssrc server
|
||||||
|
mediaServerService.openRTPServer(mediaServerItem, finalSsrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, finalSsrcInfo.getPort());
|
||||||
|
|
||||||
// 单端口模式streamId也有变化,需要重新设置监听
|
|
||||||
if (!mediaServerItem.isRtpEnable()) {
|
|
||||||
// 添加订阅
|
|
||||||
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
|
|
||||||
subscribe.removeSubscribe(hookSubscribe);
|
|
||||||
hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
|
|
||||||
subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response)->{
|
|
||||||
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
|
|
||||||
dynamicTask.stop(timeOutTaskKey);
|
|
||||||
// hook响应
|
|
||||||
onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid);
|
|
||||||
hookEvent.response(mediaServerItemInUse, response);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// 关闭rtp server
|
|
||||||
mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
|
|
||||||
// 重新开启ssrc server
|
|
||||||
mediaServerService.openRTPServer(mediaServerItem, finalSsrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, finalSsrcInfo.getPort());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}, (event) -> {
|
||||||
}, (event) -> {
|
dynamicTask.stop(timeOutTaskKey);
|
||||||
|
mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
|
||||||
|
// 释放ssrc
|
||||||
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
||||||
|
|
||||||
|
streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
||||||
|
errorEvent.response(event);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
|
||||||
|
logger.error("[命令发送失败] 点播消息: {}", e.getMessage());
|
||||||
dynamicTask.stop(timeOutTaskKey);
|
dynamicTask.stop(timeOutTaskKey);
|
||||||
mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
|
mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
|
||||||
// 释放ssrc
|
// 释放ssrc
|
||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
|
||||||
|
|
||||||
streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
|
||||||
errorEvent.response(event);
|
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
|
||||||
});
|
eventResult.msg = "命令发送失败";
|
||||||
|
errorEvent.response(eventResult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -439,17 +456,18 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
playBackResult.setCode(ErrorCode.ERROR100.getCode());
|
playBackResult.setCode(ErrorCode.ERROR100.getCode());
|
||||||
playBackResult.setMsg("回放超时");
|
playBackResult.setMsg("回放超时");
|
||||||
playBackResult.setData(requestMessage);
|
playBackResult.setData(requestMessage);
|
||||||
SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());
|
|
||||||
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
try {
|
||||||
if (dialog != null) {
|
cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[录像流]回放超时 发送BYE失败 {}", e.getMessage());
|
||||||
|
} catch (SsrcTransactionNotFoundException e) {
|
||||||
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
||||||
cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
|
|
||||||
}else {
|
|
||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||||
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
||||||
streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
|
streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
|
||||||
}
|
}
|
||||||
cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
|
|
||||||
// 回复之前所有的点播请求
|
// 回复之前所有的点播请求
|
||||||
playBackCallback.call(playBackResult);
|
playBackCallback.call(playBackResult);
|
||||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "回放超时"));
|
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "回放超时"));
|
||||||
@ -489,59 +507,67 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
playBackCallback.call(playBackResult);
|
playBackCallback.call(playBackResult);
|
||||||
};
|
};
|
||||||
|
|
||||||
cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack,
|
try {
|
||||||
hookEvent, eventResult -> {
|
cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack,
|
||||||
if (eventResult.type == SipSubscribe.EventResultType.response) {
|
hookEvent, eventResult -> {
|
||||||
ResponseEvent responseEvent = (ResponseEvent)eventResult.event;
|
if (eventResult.type == SipSubscribe.EventResultType.response) {
|
||||||
String contentString = new String(responseEvent.getResponse().getRawContent());
|
ResponseEvent responseEvent = (ResponseEvent)eventResult.event;
|
||||||
// 获取ssrc
|
String contentString = new String(responseEvent.getResponse().getRawContent());
|
||||||
int ssrcIndex = contentString.indexOf("y=");
|
// 获取ssrc
|
||||||
// 检查是否有y字段
|
int ssrcIndex = contentString.indexOf("y=");
|
||||||
if (ssrcIndex >= 0) {
|
// 检查是否有y字段
|
||||||
//ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
|
if (ssrcIndex >= 0) {
|
||||||
String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
|
//ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
|
||||||
// 查询到ssrc不一致且开启了ssrc校验则需要针对处理
|
String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
|
||||||
if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
|
// 查询到ssrc不一致且开启了ssrc校验则需要针对处理
|
||||||
return;
|
if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
|
||||||
}
|
|
||||||
logger.info("[回放消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse );
|
|
||||||
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
|
|
||||||
logger.info("[回放消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
|
|
||||||
|
|
||||||
if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
|
|
||||||
// ssrc 不可用
|
|
||||||
// 释放ssrc
|
|
||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
|
||||||
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
|
||||||
eventResult.msg = "下级自定义了ssrc,但是此ssrc不可用";
|
|
||||||
eventResult.statusCode = 400;
|
|
||||||
errorEvent.response(eventResult);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
logger.info("[回放消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse );
|
||||||
|
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
|
||||||
|
logger.info("[回放消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
|
||||||
|
|
||||||
// 单端口模式streamId也有变化,需要重新设置监听
|
if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
|
||||||
if (!mediaServerItem.isRtpEnable()) {
|
// ssrc 不可用
|
||||||
// 添加订阅
|
// 释放ssrc
|
||||||
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||||
subscribe.removeSubscribe(hookSubscribe);
|
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
||||||
hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
|
eventResult.msg = "下级自定义了ssrc,但是此ssrc不可用";
|
||||||
subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response)->{
|
eventResult.statusCode = 400;
|
||||||
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
|
errorEvent.response(eventResult);
|
||||||
dynamicTask.stop(playBackTimeOutTaskKey);
|
return;
|
||||||
// hook响应
|
}
|
||||||
onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid);
|
|
||||||
hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
|
// 单端口模式streamId也有变化,需要重新设置监听
|
||||||
});
|
if (!mediaServerItem.isRtpEnable()) {
|
||||||
|
// 添加订阅
|
||||||
|
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
|
||||||
|
subscribe.removeSubscribe(hookSubscribe);
|
||||||
|
hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
|
||||||
|
subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response)->{
|
||||||
|
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
|
||||||
|
dynamicTask.stop(playBackTimeOutTaskKey);
|
||||||
|
// hook响应
|
||||||
|
onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid);
|
||||||
|
hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 关闭rtp server
|
||||||
|
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
||||||
|
// 重新开启ssrc server
|
||||||
|
mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
|
||||||
}
|
}
|
||||||
// 关闭rtp server
|
|
||||||
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
|
||||||
// 重新开启ssrc server
|
|
||||||
mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}, errorEvent);
|
}, errorEvent);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 回放: {}", e.getMessage());
|
||||||
|
|
||||||
|
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
|
||||||
|
eventResult.msg = "命令发送失败";
|
||||||
|
errorEvent.response(eventResult);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,46 +613,57 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
downloadResult.setCode(ErrorCode.ERROR100.getCode());
|
downloadResult.setCode(ErrorCode.ERROR100.getCode());
|
||||||
downloadResult.setMsg("录像下载请求超时");
|
downloadResult.setMsg("录像下载请求超时");
|
||||||
hookCallBack.call(downloadResult);
|
hookCallBack.call(downloadResult);
|
||||||
SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());
|
|
||||||
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
||||||
if (dialog != null) {
|
try {
|
||||||
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null);
|
||||||
cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
}else {
|
logger.error("[录像流]录像下载请求超时, 发送BYE失败 {}", e.getMessage());
|
||||||
|
} catch (SsrcTransactionNotFoundException e) {
|
||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||||
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
||||||
streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
|
streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
|
||||||
}
|
}
|
||||||
cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
|
|
||||||
// 回复之前所有的点播请求
|
// 回复之前所有的点播请求
|
||||||
hookCallBack.call(downloadResult);
|
hookCallBack.call(downloadResult);
|
||||||
}, userSetting.getPlayTimeout());
|
}, userSetting.getPlayTimeout());
|
||||||
cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack,
|
|
||||||
inviteStreamInfo -> {
|
SipSubscribe.Event errorEvent = event -> {
|
||||||
logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString());
|
dynamicTask.stop(downLoadTimeOutTaskKey);
|
||||||
dynamicTask.stop(downLoadTimeOutTaskKey);
|
downloadResult.setCode(ErrorCode.ERROR100.getCode());
|
||||||
StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId);
|
downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
|
||||||
streamInfo.setStartTime(startTime);
|
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
||||||
streamInfo.setEndTime(endTime);
|
wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
|
||||||
redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId());
|
downloadResult.setEvent(event);
|
||||||
wvpResult.setCode(ErrorCode.SUCCESS.getCode());
|
hookCallBack.call(downloadResult);
|
||||||
wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
|
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
||||||
wvpResult.setData(streamInfo);
|
};
|
||||||
downloadResult.setCode(ErrorCode.SUCCESS.getCode());
|
|
||||||
downloadResult.setMsg(ErrorCode.SUCCESS.getMsg());
|
try {
|
||||||
downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
|
cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack,
|
||||||
downloadResult.setResponse(inviteStreamInfo.getResponse());
|
inviteStreamInfo -> {
|
||||||
hookCallBack.call(downloadResult);
|
logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString());
|
||||||
}, event -> {
|
dynamicTask.stop(downLoadTimeOutTaskKey);
|
||||||
dynamicTask.stop(downLoadTimeOutTaskKey);
|
StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId);
|
||||||
downloadResult.setCode(ErrorCode.ERROR100.getCode());
|
streamInfo.setStartTime(startTime);
|
||||||
downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
|
streamInfo.setEndTime(endTime);
|
||||||
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId());
|
||||||
wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
|
wvpResult.setCode(ErrorCode.SUCCESS.getCode());
|
||||||
downloadResult.setEvent(event);
|
wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
|
||||||
hookCallBack.call(downloadResult);
|
wvpResult.setData(streamInfo);
|
||||||
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
downloadResult.setCode(ErrorCode.SUCCESS.getCode());
|
||||||
});
|
downloadResult.setMsg(ErrorCode.SUCCESS.getMsg());
|
||||||
|
downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
|
||||||
|
downloadResult.setResponse(inviteStreamInfo.getResponse());
|
||||||
|
hookCallBack.call(downloadResult);
|
||||||
|
}, errorEvent);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 录像下载: {}", e.getMessage());
|
||||||
|
|
||||||
|
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
|
||||||
|
eventResult.msg = "命令发送失败";
|
||||||
|
errorEvent.response(eventResult);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,7 +742,11 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
for (SendRtpItem sendRtpItem : sendRtpItems) {
|
for (SendRtpItem sendRtpItem : sendRtpItems) {
|
||||||
if (sendRtpItem.getMediaServerId().equals(mediaServerId)) {
|
if (sendRtpItem.getMediaServerId().equals(mediaServerId)) {
|
||||||
ParentPlatform platform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
ParentPlatform platform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
||||||
sipCommanderFroPlatform.streamByeCmd(platform, sendRtpItem.getCallId());
|
try {
|
||||||
|
sipCommanderFroPlatform.streamByeCmd(platform, sendRtpItem.getCallId());
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -714,8 +755,17 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
if (allSsrc.size() > 0) {
|
if (allSsrc.size() > 0) {
|
||||||
for (SsrcTransaction ssrcTransaction : allSsrc) {
|
for (SsrcTransaction ssrcTransaction : allSsrc) {
|
||||||
if(ssrcTransaction.getMediaServerId().equals(mediaServerId)) {
|
if(ssrcTransaction.getMediaServerId().equals(mediaServerId)) {
|
||||||
cmder.streamByeCmd(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(),
|
Device device = deviceService.queryDevice(ssrcTransaction.getDeviceId());
|
||||||
ssrcTransaction.getStream(), null);
|
if (device == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cmder.streamByeCmd(device, ssrcTransaction.getChannelId(),
|
||||||
|
ssrcTransaction.getStream(), null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException |
|
||||||
|
SsrcTransactionNotFoundException e) {
|
||||||
|
logger.error("[zlm离线]为正在使用此zlm的设备, 发送BYE失败 {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
@ -78,16 +80,28 @@ public class RedisAlarmMsgListener implements MessageListener {
|
|||||||
List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true);
|
List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true);
|
||||||
if (parentPlatforms.size() > 0) {
|
if (parentPlatforms.size() > 0) {
|
||||||
for (ParentPlatform parentPlatform : parentPlatforms) {
|
for (ParentPlatform parentPlatform : parentPlatforms) {
|
||||||
commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm);
|
try {
|
||||||
|
commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
Device device = storage.queryVideoDevice(gbId);
|
Device device = storage.queryVideoDevice(gbId);
|
||||||
ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);
|
ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);
|
||||||
if (device != null && platform == null) {
|
if (device != null && platform == null) {
|
||||||
commander.sendAlarmMessage(device, deviceAlarm);
|
try {
|
||||||
|
commander.sendAlarmMessage(device, deviceAlarm);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 发送报警: {}", e.getMessage());
|
||||||
|
}
|
||||||
}else if (device == null && platform != null){
|
}else if (device == null && platform != null){
|
||||||
commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
|
try {
|
||||||
|
commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 发送报警: {}", e.getMessage());
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
logger.warn("无法确定" + gbId + "是平台还是设备");
|
logger.warn("无法确定" + gbId + "是平台还是设备");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.vmanager.gb28181.MobilePosition;
|
package com.genersoft.iot.vmp.vmanager.gb28181.MobilePosition;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -31,6 +32,9 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.context.request.async.DeferredResult;
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 位置信息管理
|
* 位置信息管理
|
||||||
*/
|
*/
|
||||||
@ -105,13 +109,18 @@ public class MobilePositionController {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId;
|
String key = DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId;
|
||||||
cmder.mobilePostitionQuery(device, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.mobilePostitionQuery(device, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("获取移动位置信息失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("获取移动位置信息失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 获取移动位置信息: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
DeferredResult<MobilePosition> result = new DeferredResult<MobilePosition>(5*1000L);
|
DeferredResult<MobilePosition> result = new DeferredResult<MobilePosition>(5*1000L);
|
||||||
result.onTimeout(()->{
|
result.onTimeout(()->{
|
||||||
logger.warn(String.format("获取移动位置信息超时"));
|
logger.warn(String.format("获取移动位置信息超时"));
|
||||||
|
@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
|||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener;
|
||||||
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||||
@ -16,6 +17,8 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -23,6 +26,9 @@ import org.springframework.util.ObjectUtils;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -33,6 +39,8 @@ import java.util.List;
|
|||||||
@RequestMapping("/api/alarm")
|
@RequestMapping("/api/alarm")
|
||||||
public class AlarmController {
|
public class AlarmController {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(AlarmController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IDeviceAlarmService deviceAlarmService;
|
private IDeviceAlarmService deviceAlarmService;
|
||||||
|
|
||||||
@ -108,9 +116,19 @@ public class AlarmController {
|
|||||||
deviceAlarm.setLatitude(39.33333);
|
deviceAlarm.setLatitude(39.33333);
|
||||||
|
|
||||||
if (device != null && platform == null) {
|
if (device != null && platform == null) {
|
||||||
commander.sendAlarmMessage(device, deviceAlarm);
|
|
||||||
|
try {
|
||||||
|
commander.sendAlarmMessage(device, deviceAlarm);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
|
||||||
|
}
|
||||||
}else if (device == null && platform != null){
|
}else if (device == null && platform != null){
|
||||||
commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
|
try {
|
||||||
|
commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(),"无法确定" + deviceId + "是平台还是设备");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(),"无法确定" + deviceId + "是平台还是设备");
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
package com.genersoft.iot.vmp.vmanager.gb28181.device;
|
package com.genersoft.iot.vmp.vmanager.gb28181.device;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@ -26,6 +28,9 @@ import org.springframework.util.StringUtils;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.context.request.async.DeferredResult;
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Tag(name = "国标设备配置")
|
@Tag(name = "国标设备配置")
|
||||||
@ -75,14 +80,19 @@ public class DeviceConfig {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + deviceId + channelId;
|
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + deviceId + channelId;
|
||||||
cmder.deviceBasicConfigCmd(device, channelId, name, expiration, heartBeatInterval, heartBeatCount, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.deviceBasicConfigCmd(device, channelId, name, expiration, heartBeatInterval, heartBeatCount, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("设备配置操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("设备配置操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
DeferredResult<String> result = new DeferredResult<String>(3 * 1000L);
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 设备配置: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
DeferredResult<String> result = new DeferredResult<String>(3 * 1000L);
|
||||||
result.onTimeout(() -> {
|
result.onTimeout(() -> {
|
||||||
logger.warn(String.format("设备配置操作超时, 设备未返回应答指令"));
|
logger.warn(String.format("设备配置操作超时, 设备未返回应答指令"));
|
||||||
// 释放rtpserver
|
// 释放rtpserver
|
||||||
@ -121,14 +131,19 @@ public class DeviceConfig {
|
|||||||
String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (ObjectUtils.isEmpty(channelId) ? deviceId : channelId);
|
String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (ObjectUtils.isEmpty(channelId) ? deviceId : channelId);
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
cmder.deviceConfigQuery(device, channelId, configType, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.deviceConfigQuery(device, channelId, configType, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("获取设备配置失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("获取设备配置失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
DeferredResult<String> result = new DeferredResult<String > (3 * 1000L);
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 获取设备配置: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
DeferredResult<String> result = new DeferredResult<String > (3 * 1000L);
|
||||||
result.onTimeout(()->{
|
result.onTimeout(()->{
|
||||||
logger.warn(String.format("获取设备配置超时"));
|
logger.warn(String.format("获取设备配置超时"));
|
||||||
// 释放rtpserver
|
// 释放rtpserver
|
||||||
|
@ -29,6 +29,9 @@ import org.springframework.util.StringUtils;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.context.request.async.DeferredResult;
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Tag(name = "国标设备控制")
|
@Tag(name = "国标设备控制")
|
||||||
@ -61,10 +64,12 @@ public class DeviceControl {
|
|||||||
logger.debug("设备远程启动API调用");
|
logger.debug("设备远程启动API调用");
|
||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (!cmder.teleBootCmd(device)) {
|
try {
|
||||||
logger.warn("设备远程启动API调用失败!");
|
cmder.teleBootCmd(device);
|
||||||
throw new ControllerException(ErrorCode.ERROR100);
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
}
|
logger.error("[命令发送失败] 远程启动: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,13 +106,18 @@ public class DeviceControl {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
resultHolder.put(key, uuid, result);
|
resultHolder.put(key, uuid, result);
|
||||||
cmder.recordCmd(device, channelId, recordCmdStr, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.recordCmd(device, channelId, recordCmdStr, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("开始/停止录像操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeAllResult(msg);
|
msg.setData(String.format("开始/停止录像操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeAllResult(msg);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 开始/停止录像: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -123,21 +133,26 @@ public class DeviceControl {
|
|||||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||||
@Parameter(name = "guardCmdStr", description = "命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true)
|
@Parameter(name = "guardCmdStr", description = "命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true)
|
||||||
@GetMapping("/guard/{deviceId}/{guardCmdStr}")
|
@GetMapping("/guard/{deviceId}/{guardCmdStr}")
|
||||||
public DeferredResult<ResponseEntity<String>> guardApi(@PathVariable String deviceId, String channelId, @PathVariable String guardCmdStr) {
|
public DeferredResult<String> guardApi(@PathVariable String deviceId, String channelId, @PathVariable String guardCmdStr) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("布防/撤防API调用");
|
logger.debug("布防/撤防API调用");
|
||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
|
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
|
||||||
String uuid =UUID.randomUUID().toString();
|
String uuid =UUID.randomUUID().toString();
|
||||||
cmder.guardCmd(device, guardCmdStr, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.guardCmd(device, guardCmdStr, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("布防/撤防操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("布防/撤防操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 布防/撤防操作: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||||
|
}
|
||||||
|
DeferredResult<String> result = new DeferredResult<>(3 * 1000L);
|
||||||
resultHolder.put(key, uuid, result);
|
resultHolder.put(key, uuid, result);
|
||||||
result.onTimeout(() -> {
|
result.onTimeout(() -> {
|
||||||
logger.warn(String.format("布防/撤防操作超时, 设备未返回应答指令"));
|
logger.warn(String.format("布防/撤防操作超时, 设备未返回应答指令"));
|
||||||
@ -174,14 +189,19 @@ public class DeviceControl {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
|
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
|
||||||
cmder.alarmCmd(device, alarmMethod, alarmType, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.alarmCmd(device, alarmMethod, alarmType, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("报警复位操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("报警复位操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 报警复位: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
|
||||||
result.onTimeout(() -> {
|
result.onTimeout(() -> {
|
||||||
logger.warn(String.format("报警复位操作超时, 设备未返回应答指令"));
|
logger.warn(String.format("报警复位操作超时, 设备未返回应答指令"));
|
||||||
// 释放rtpserver
|
// 释放rtpserver
|
||||||
@ -205,23 +225,23 @@ public class DeviceControl {
|
|||||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||||
@Parameter(name = "channelId", description = "通道国标编号")
|
@Parameter(name = "channelId", description = "通道国标编号")
|
||||||
@GetMapping("/i_frame/{deviceId}")
|
@GetMapping("/i_frame/{deviceId}")
|
||||||
public ResponseEntity<String> iFrame(@PathVariable String deviceId,
|
public JSONObject iFrame(@PathVariable String deviceId,
|
||||||
@RequestParam(required = false) String channelId) {
|
@RequestParam(required = false) String channelId) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("强制关键帧API调用");
|
logger.debug("强制关键帧API调用");
|
||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
boolean sucsess = cmder.iFrameCmd(device, channelId);
|
try {
|
||||||
if (sucsess) {
|
cmder.iFrameCmd(device, channelId);
|
||||||
JSONObject json = new JSONObject();
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
json.put("DeviceID", deviceId);
|
logger.error("[命令发送失败] 强制关键帧: {}", e.getMessage());
|
||||||
json.put("ChannelID", channelId);
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
json.put("Result", "OK");
|
|
||||||
return new ResponseEntity<>(json.toJSONString(), HttpStatus.OK);
|
|
||||||
} else {
|
|
||||||
logger.warn("强制关键帧API调用失败!");
|
|
||||||
return new ResponseEntity<String>("强制关键帧API调用失败!", HttpStatus.INTERNAL_SERVER_ERROR);
|
|
||||||
}
|
}
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("DeviceID", deviceId);
|
||||||
|
json.put("ChannelID", channelId);
|
||||||
|
json.put("Result", "OK");
|
||||||
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -240,7 +260,7 @@ public class DeviceControl {
|
|||||||
@Parameter(name = "presetIndex", description = "调用预置位编号")
|
@Parameter(name = "presetIndex", description = "调用预置位编号")
|
||||||
@Parameter(name = "resetTime", description = "自动归位时间间隔")
|
@Parameter(name = "resetTime", description = "自动归位时间间隔")
|
||||||
@GetMapping("/home_position/{deviceId}/{enabled}")
|
@GetMapping("/home_position/{deviceId}/{enabled}")
|
||||||
public DeferredResult<ResponseEntity<String>> homePositionApi(@PathVariable String deviceId,
|
public DeferredResult<String> homePositionApi(@PathVariable String deviceId,
|
||||||
@PathVariable String enabled,
|
@PathVariable String enabled,
|
||||||
@RequestParam(required = false) String resetTime,
|
@RequestParam(required = false) String resetTime,
|
||||||
@RequestParam(required = false) String presetIndex,
|
@RequestParam(required = false) String presetIndex,
|
||||||
@ -251,14 +271,19 @@ public class DeviceControl {
|
|||||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (ObjectUtils.isEmpty(channelId) ? deviceId : channelId);
|
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (ObjectUtils.isEmpty(channelId) ? deviceId : channelId);
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
cmder.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("看守位控制操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("看守位控制操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 看守位控制: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
DeferredResult<String> result = new DeferredResult<>(3 * 1000L);
|
||||||
result.onTimeout(() -> {
|
result.onTimeout(() -> {
|
||||||
logger.warn(String.format("看守位控制操作超时, 设备未返回应答指令"));
|
logger.warn(String.format("看守位控制操作超时, 设备未返回应答指令"));
|
||||||
// 释放rtpserver
|
// 释放rtpserver
|
||||||
@ -297,14 +322,14 @@ public class DeviceControl {
|
|||||||
@Parameter(name = "lengthx", description = "拉框长度像素值", required = true)
|
@Parameter(name = "lengthx", description = "拉框长度像素值", required = true)
|
||||||
@Parameter(name = "lengthy", description = "lengthy", required = true)
|
@Parameter(name = "lengthy", description = "lengthy", required = true)
|
||||||
@GetMapping("drag_zoom/zoom_in")
|
@GetMapping("drag_zoom/zoom_in")
|
||||||
public ResponseEntity<String> dragZoomIn(@RequestParam String deviceId,
|
public void dragZoomIn(@RequestParam String deviceId,
|
||||||
@RequestParam(required = false) String channelId,
|
@RequestParam(required = false) String channelId,
|
||||||
@RequestParam int length,
|
@RequestParam int length,
|
||||||
@RequestParam int width,
|
@RequestParam int width,
|
||||||
@RequestParam int midpointx,
|
@RequestParam int midpointx,
|
||||||
@RequestParam int midpointy,
|
@RequestParam int midpointy,
|
||||||
@RequestParam int lengthx,
|
@RequestParam int lengthx,
|
||||||
@RequestParam int lengthy){
|
@RequestParam int lengthy) throws RuntimeException {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("设备拉框放大 API调用,deviceId:%s ,channelId:%s ,length:%d ,width:%d ,midpointx:%d ,midpointy:%d ,lengthx:%d ,lengthy:%d",deviceId, channelId, length, width, midpointx, midpointy,lengthx, lengthy));
|
logger.debug(String.format("设备拉框放大 API调用,deviceId:%s ,channelId:%s ,length:%d ,width:%d ,midpointx:%d ,midpointy:%d ,lengthx:%d ,lengthy:%d",deviceId, channelId, length, width, midpointx, midpointy,lengthx, lengthy));
|
||||||
}
|
}
|
||||||
@ -318,8 +343,12 @@ public class DeviceControl {
|
|||||||
cmdXml.append("<LengthX>" + lengthx+ "</LengthX>\r\n");
|
cmdXml.append("<LengthX>" + lengthx+ "</LengthX>\r\n");
|
||||||
cmdXml.append("<LengthY>" + lengthy+ "</LengthY>\r\n");
|
cmdXml.append("<LengthY>" + lengthy+ "</LengthY>\r\n");
|
||||||
cmdXml.append("</DragZoomIn>\r\n");
|
cmdXml.append("</DragZoomIn>\r\n");
|
||||||
cmder.dragZoomCmd(device, channelId, cmdXml.toString());
|
try {
|
||||||
return new ResponseEntity<String>("success", HttpStatus.OK);
|
cmder.dragZoomCmd(device, channelId, cmdXml.toString());
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 拉框放大: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -344,7 +373,7 @@ public class DeviceControl {
|
|||||||
@Parameter(name = "lengthx", description = "拉框长度像素值", required = true)
|
@Parameter(name = "lengthx", description = "拉框长度像素值", required = true)
|
||||||
@Parameter(name = "lengthy", description = "拉框宽度像素值", required = true)
|
@Parameter(name = "lengthy", description = "拉框宽度像素值", required = true)
|
||||||
@GetMapping("/drag_zoom/zoom_out")
|
@GetMapping("/drag_zoom/zoom_out")
|
||||||
public ResponseEntity<String> dragZoomOut(@RequestParam String deviceId,
|
public void dragZoomOut(@RequestParam String deviceId,
|
||||||
@RequestParam(required = false) String channelId,
|
@RequestParam(required = false) String channelId,
|
||||||
@RequestParam int length,
|
@RequestParam int length,
|
||||||
@RequestParam int width,
|
@RequestParam int width,
|
||||||
@ -366,7 +395,11 @@ public class DeviceControl {
|
|||||||
cmdXml.append("<LengthX>" + lengthx+ "</LengthX>\r\n");
|
cmdXml.append("<LengthX>" + lengthx+ "</LengthX>\r\n");
|
||||||
cmdXml.append("<LengthY>" + lengthy+ "</LengthY>\r\n");
|
cmdXml.append("<LengthY>" + lengthy+ "</LengthY>\r\n");
|
||||||
cmdXml.append("</DragZoomOut>\r\n");
|
cmdXml.append("</DragZoomOut>\r\n");
|
||||||
cmder.dragZoomCmd(device, channelId, cmdXml.toString());
|
try {
|
||||||
return new ResponseEntity<String>("success",HttpStatus.OK);
|
cmder.dragZoomCmd(device, channelId, cmdXml.toString());
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 拉框缩小: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,11 @@ import org.springframework.web.context.request.async.DeferredResult;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.sip.DialogState;
|
import javax.sip.DialogState;
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@Tag(name = "国标设备查询", description = "国标设备查询")
|
@Tag(name = "国标设备查询", description = "国标设备查询")
|
||||||
@ -315,13 +318,18 @@ public class DeviceQuery {
|
|||||||
result.setResult(new ResponseEntity(String.format("设备%s不存在", deviceId),HttpStatus.OK));
|
result.setResult(new ResponseEntity(String.format("设备%s不存在", deviceId),HttpStatus.OK));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
cmder.deviceStatusQuery(device, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.deviceStatusQuery(device, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("获取设备状态失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("获取设备状态失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 获取设备状态: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
result.onTimeout(()->{
|
result.onTimeout(()->{
|
||||||
logger.warn(String.format("获取设备状态超时"));
|
logger.warn(String.format("获取设备状态超时"));
|
||||||
// 释放rtpserver
|
// 释放rtpserver
|
||||||
@ -368,14 +376,19 @@ public class DeviceQuery {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId;
|
String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId;
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
cmder.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("设备报警查询失败,错误码: %s, %s",event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("设备报警查询失败,错误码: %s, %s",event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L);
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 设备报警查询: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L);
|
||||||
result.onTimeout(()->{
|
result.onTimeout(()->{
|
||||||
logger.warn(String.format("设备报警查询超时"));
|
logger.warn(String.format("设备报警查询超时"));
|
||||||
// 释放rtpserver
|
// 释放rtpserver
|
||||||
|
@ -29,6 +29,9 @@ import org.springframework.util.ObjectUtils;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,20 +215,37 @@ public class PlatformController {
|
|||||||
// 保存时启用就发送注册
|
// 保存时启用就发送注册
|
||||||
if (parentPlatform.isEnable()) {
|
if (parentPlatform.isEnable()) {
|
||||||
if (parentPlatformOld != null && parentPlatformOld.isStatus()) {
|
if (parentPlatformOld != null && parentPlatformOld.isStatus()) {
|
||||||
commanderForPlatform.unregister(parentPlatformOld, null, null);
|
try {
|
||||||
|
commanderForPlatform.unregister(parentPlatformOld, null, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
logger.error("[线程休眠失败] : {}", e.getMessage());
|
||||||
}
|
}
|
||||||
// 只要保存就发送注册
|
// 只要保存就发送注册
|
||||||
commanderForPlatform.register(parentPlatform, null, null);
|
try {
|
||||||
|
commanderForPlatform.register(parentPlatform, null, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 注册: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 只要保存就发送注册
|
// 只要保存就发送注册
|
||||||
commanderForPlatform.register(parentPlatform, null, null);
|
try {
|
||||||
|
commanderForPlatform.register(parentPlatform, null, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 注册: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()) { // 关闭启用时注销
|
} else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()) { // 关闭启用时注销
|
||||||
commanderForPlatform.unregister(parentPlatformOld, null, null);
|
try {
|
||||||
|
commanderForPlatform.unregister(parentPlatformOld, null, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());
|
||||||
|
}
|
||||||
// 停止订阅相关的定时任务
|
// 停止订阅相关的定时任务
|
||||||
subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId());
|
subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId());
|
||||||
}
|
}
|
||||||
@ -258,17 +278,21 @@ public class PlatformController {
|
|||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在");
|
||||||
}
|
}
|
||||||
// 发送离线消息,无论是否成功都删除缓存
|
// 发送离线消息,无论是否成功都删除缓存
|
||||||
commanderForPlatform.unregister(parentPlatform, (event -> {
|
try {
|
||||||
// 清空redis缓存
|
commanderForPlatform.unregister(parentPlatform, (event -> {
|
||||||
redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId());
|
// 清空redis缓存
|
||||||
redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId());
|
redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId());
|
||||||
redisCatchStorage.delPlatformRegister(parentPlatform.getServerGBId());
|
redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId());
|
||||||
}), (event -> {
|
redisCatchStorage.delPlatformRegister(parentPlatform.getServerGBId());
|
||||||
// 清空redis缓存
|
}), (event -> {
|
||||||
redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId());
|
// 清空redis缓存
|
||||||
redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId());
|
redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId());
|
||||||
redisCatchStorage.delPlatformRegister(parentPlatform.getServerGBId());
|
redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId());
|
||||||
}));
|
redisCatchStorage.delPlatformRegister(parentPlatform.getServerGBId());
|
||||||
|
}));
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
boolean deleteResult = storager.deleteParentPlatform(parentPlatform);
|
boolean deleteResult = storager.deleteParentPlatform(parentPlatform);
|
||||||
storager.delCatalogByPlatformId(parentPlatform.getServerGBId());
|
storager.delCatalogByPlatformId(parentPlatform.getServerGBId());
|
||||||
|
@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.vmanager.gb28181.play;
|
|||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
@ -36,6 +37,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
|||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
import org.springframework.web.context.request.async.DeferredResult;
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -102,12 +106,23 @@ public class PlayController {
|
|||||||
throw new ControllerException(ErrorCode.ERROR400);
|
throw new ControllerException(ErrorCode.ERROR400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备[" + deviceId + "]不存在");
|
||||||
|
}
|
||||||
|
|
||||||
StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
|
StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
|
||||||
if (streamInfo == null) {
|
if (streamInfo == null) {
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "点播未找到");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "点播未找到");
|
||||||
}
|
}
|
||||||
|
|
||||||
cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), null, null);
|
try {
|
||||||
|
logger.warn("[停止点播] {}/{}", device.getDeviceId(), channelId);
|
||||||
|
cmder.streamByeCmd(device, channelId, streamInfo.getStream(), null, null);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||||
|
logger.error("[命令发送失败] 停止点播, 发送BYE: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
redisCatchStorage.stopPlay(streamInfo);
|
redisCatchStorage.stopPlay(streamInfo);
|
||||||
|
|
||||||
storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
||||||
@ -221,18 +236,23 @@ public class PlayController {
|
|||||||
resultHolder.invokeResult(msg);
|
resultHolder.invokeResult(msg);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
cmder.audioBroadcastCmd(device, (event) -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.audioBroadcastCmd(device, (event) -> {
|
||||||
msg.setKey(key);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setId(uuid);
|
msg.setKey(key);
|
||||||
JSONObject json = new JSONObject();
|
msg.setId(uuid);
|
||||||
json.put("DeviceID", deviceId);
|
JSONObject json = new JSONObject();
|
||||||
json.put("CmdType", "Broadcast");
|
json.put("DeviceID", deviceId);
|
||||||
json.put("Result", "Failed");
|
json.put("CmdType", "Broadcast");
|
||||||
json.put("Description", String.format("语音广播操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
json.put("Result", "Failed");
|
||||||
msg.setData(json);
|
json.put("Description", String.format("语音广播操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(json);
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 语音广播: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
result.onTimeout(() -> {
|
result.onTimeout(() -> {
|
||||||
logger.warn("语音广播操作超时, 设备未返回应答指令");
|
logger.warn("语音广播操作超时, 设备未返回应答指令");
|
||||||
|
@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.vmanager.gb28181.playback;
|
|||||||
|
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
@ -21,12 +22,15 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
import org.springframework.web.context.request.async.DeferredResult;
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lin
|
* @author lin
|
||||||
*/
|
*/
|
||||||
@ -92,7 +96,15 @@ public class PlaybackController {
|
|||||||
if (ObjectUtils.isEmpty(deviceId) || ObjectUtils.isEmpty(channelId) || ObjectUtils.isEmpty(stream)) {
|
if (ObjectUtils.isEmpty(deviceId) || ObjectUtils.isEmpty(channelId) || ObjectUtils.isEmpty(stream)) {
|
||||||
throw new ControllerException(ErrorCode.ERROR400);
|
throw new ControllerException(ErrorCode.ERROR400);
|
||||||
}
|
}
|
||||||
cmder.streamByeCmd(deviceId, channelId, stream, null);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + " 未找到");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cmder.streamByeCmd(device, channelId, stream, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "发送bye失败: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -107,7 +119,11 @@ public class PlaybackController {
|
|||||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "streamId不存在");
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "streamId不存在");
|
||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(streamInfo.getDeviceID());
|
Device device = storager.queryVideoDevice(streamInfo.getDeviceID());
|
||||||
cmder.playPauseCmd(device, streamInfo);
|
try {
|
||||||
|
cmder.playPauseCmd(device, streamInfo);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,7 +138,11 @@ public class PlaybackController {
|
|||||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "streamId不存在");
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "streamId不存在");
|
||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(streamInfo.getDeviceID());
|
Device device = storager.queryVideoDevice(streamInfo.getDeviceID());
|
||||||
cmder.playResumeCmd(device, streamInfo);
|
try {
|
||||||
|
cmder.playResumeCmd(device, streamInfo);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -138,7 +158,11 @@ public class PlaybackController {
|
|||||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "streamId不存在");
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "streamId不存在");
|
||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(streamInfo.getDeviceID());
|
Device device = storager.queryVideoDevice(streamInfo.getDeviceID());
|
||||||
cmder.playSeekCmd(device, streamInfo, seekTime);
|
try {
|
||||||
|
cmder.playSeekCmd(device, streamInfo, seekTime);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "回放倍速播放")
|
@Operation(summary = "回放倍速播放")
|
||||||
@ -157,6 +181,10 @@ public class PlaybackController {
|
|||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "不支持的speed(0.25 0.5 1、2、4)");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "不支持的speed(0.25 0.5 1、2、4)");
|
||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(streamInfo.getDeviceID());
|
Device device = storager.queryVideoDevice(streamInfo.getDeviceID());
|
||||||
cmder.playSpeedCmd(device, streamInfo, speed);
|
try {
|
||||||
|
cmder.playSpeedCmd(device, streamInfo, speed);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.genersoft.iot.vmp.vmanager.gb28181.ptz;
|
package com.genersoft.iot.vmp.vmanager.gb28181.ptz;
|
||||||
|
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@ -18,6 +20,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
|||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Tag(name = "云台控制")
|
@Tag(name = "云台控制")
|
||||||
@ -98,7 +103,12 @@ public class PtzController {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cmder.frontEndCmd(device, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed);
|
try {
|
||||||
|
cmder.frontEndCmd(device, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 云台控制: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -117,7 +127,12 @@ public class PtzController {
|
|||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
|
|
||||||
cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2);
|
try {
|
||||||
|
cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 前端控制: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -146,13 +161,18 @@ public class PtzController {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
resultHolder.put(key, uuid, result);
|
resultHolder.put(key, uuid, result);
|
||||||
cmder.presetQuery(device, channelId, event -> {
|
try {
|
||||||
RequestMessage msg = new RequestMessage();
|
cmder.presetQuery(device, channelId, event -> {
|
||||||
msg.setId(uuid);
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setKey(key);
|
msg.setId(uuid);
|
||||||
msg.setData(String.format("获取设备预置位失败,错误码: %s, %s", event.statusCode, event.msg));
|
msg.setKey(key);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(String.format("获取设备预置位失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||||
});
|
resultHolder.invokeResult(msg);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 获取设备预置位: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.record;
|
|||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||||
|
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
import com.genersoft.iot.vmp.service.IPlayService;
|
import com.genersoft.iot.vmp.service.IPlayService;
|
||||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||||
@ -31,6 +33,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
|||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -54,6 +59,12 @@ public class GBRecordController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IPlayService playService;
|
private IPlayService playService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Operation(summary = "录像查询")
|
@Operation(summary = "录像查询")
|
||||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||||
@ -81,13 +92,18 @@ public class GBRecordController {
|
|||||||
RequestMessage msg = new RequestMessage();
|
RequestMessage msg = new RequestMessage();
|
||||||
msg.setId(uuid);
|
msg.setId(uuid);
|
||||||
msg.setKey(key);
|
msg.setKey(key);
|
||||||
cmder.recordInfoQuery(device, channelId, startTime, endTime, sn, null, null, null, (eventResult -> {
|
try {
|
||||||
WVPResult<RecordInfo> wvpResult = new WVPResult<>();
|
cmder.recordInfoQuery(device, channelId, startTime, endTime, sn, null, null, null, (eventResult -> {
|
||||||
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
WVPResult<RecordInfo> wvpResult = new WVPResult<>();
|
||||||
wvpResult.setMsg("查询录像失败, status: " + eventResult.statusCode + ", message: " + eventResult.msg);
|
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
||||||
msg.setData(wvpResult);
|
wvpResult.setMsg("查询录像失败, status: " + eventResult.statusCode + ", message: " + eventResult.msg);
|
||||||
resultHolder.invokeResult(msg);
|
msg.setData(wvpResult);
|
||||||
}));
|
resultHolder.invokeResult(msg);
|
||||||
|
}));
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 查询录像: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
// 录像查询以channelId作为deviceId查询
|
// 录像查询以channelId作为deviceId查询
|
||||||
resultHolder.put(key, uuid, result);
|
resultHolder.put(key, uuid, result);
|
||||||
@ -131,14 +147,24 @@ public class GBRecordController {
|
|||||||
@GetMapping("/download/stop/{deviceId}/{channelId}/{stream}")
|
@GetMapping("/download/stop/{deviceId}/{channelId}/{stream}")
|
||||||
public void playStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
|
public void playStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
|
||||||
|
|
||||||
cmder.streamByeCmd(deviceId, channelId, stream, null);
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId));
|
logger.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceId == null || channelId == null) {
|
if (deviceId == null || channelId == null) {
|
||||||
throw new ControllerException(ErrorCode.ERROR100);
|
throw new ControllerException(ErrorCode.ERROR400);
|
||||||
|
}
|
||||||
|
|
||||||
|
Device device = deviceService.queryDevice(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + "未找到");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
cmder.streamByeCmd(device, channelId, stream, null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||||
|
logger.error("[停止历史媒体下载]停止历史媒体下载,发送BYE失败 {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
package com.genersoft.iot.vmp.web.gb28181;
|
package com.genersoft.iot.vmp.web.gb28181;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API兼容:设备控制
|
* API兼容:设备控制
|
||||||
*/
|
*/
|
||||||
@ -35,7 +41,7 @@ public class ApiControlController {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/ptz")
|
@RequestMapping(value = "/ptz")
|
||||||
private JSONObject list(String serial,String command,
|
private void list(String serial,String command,
|
||||||
@RequestParam(required = false)Integer channel,
|
@RequestParam(required = false)Integer channel,
|
||||||
@RequestParam(required = false)String code,
|
@RequestParam(required = false)String code,
|
||||||
@RequestParam(required = false)Integer speed){
|
@RequestParam(required = false)Integer speed){
|
||||||
@ -48,9 +54,7 @@ public class ApiControlController {
|
|||||||
if (speed == null) {speed = 0;}
|
if (speed == null) {speed = 0;}
|
||||||
Device device = storager.queryVideoDevice(serial);
|
Device device = storager.queryVideoDevice(serial);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
JSONObject result = new JSONObject();
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "device[ " + serial + " ]未找到");
|
||||||
result.put("error","device[ " + serial + " ]未找到");
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
int cmdCode = 0;
|
int cmdCode = 0;
|
||||||
switch (command){
|
switch (command){
|
||||||
@ -91,7 +95,11 @@ public class ApiControlController {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 默认值 50
|
// 默认值 50
|
||||||
cmder.frontEndCmd(device, code, cmdCode, speed, speed, speed);
|
try {
|
||||||
return null;
|
cmder.frontEndCmd(device, code, cmdCode, speed, speed, speed);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 云台控制: {}", e.getMessage());
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@ package com.genersoft.iot.vmp.web.gb28181;
|
|||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||||
import com.genersoft.iot.vmp.service.IPlayService;
|
import com.genersoft.iot.vmp.service.IPlayService;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
@ -17,6 +19,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.context.request.async.DeferredResult;
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API兼容:实时直播
|
* API兼容:实时直播
|
||||||
*/
|
*/
|
||||||
@ -40,6 +46,9 @@ public class ApiStreamController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IPlayService playService;
|
private IPlayService playService;
|
||||||
|
|
||||||
@ -177,7 +186,19 @@ public class ApiStreamController {
|
|||||||
result.put("error","未找到流信息");
|
result.put("error","未找到流信息");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
cmder.streamByeCmd(serial, code, streamInfo.getStream(), null);
|
Device device = deviceService.queryDevice(serial);
|
||||||
|
if (device == null) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("error","未找到设备");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cmder.streamByeCmd(device, code, streamInfo.getStream(), null);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("error","发送BYE失败:" + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
redisCatchStorage.stopPlay(streamInfo);
|
redisCatchStorage.stopPlay(streamInfo);
|
||||||
storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
Reference in New Issue
Block a user