mirror of
https://gitee.com/pan648540858/wvp-GB28181-pro.git
synced 2026-05-27 07:27:49 +08:00
Merge remote-tracking branch 'origin/wvp-28181-2.0' into wvp-28181-2.0
This commit is contained in:
commit
d0de0c15ae
@ -1,5 +1,7 @@
|
|||||||
FROM ubuntu:20.04 AS build
|
FROM ubuntu:20.04 AS build
|
||||||
|
|
||||||
|
# DEBIAN_FRONTEND这个环境变量,告知操作系统应该从哪儿获得用户输入。
|
||||||
|
# 如果设置为”noninteractive”,你就可以直接运行命令,而无需向用户请求输入(所有操作都是非交互式的)。
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.common;
|
package com.genersoft.iot.vmp.common;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 定义常量
|
* @description: 定义常量
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2019年5月30日 下午3:04:04
|
* @date: 2019年5月30日 下午3:04:04
|
||||||
*
|
*
|
||||||
|
|||||||
42
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
Normal file
42
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package com.genersoft.iot.vmp.conf;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||||
|
import org.springframework.scheduling.support.CronTrigger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态定时任务
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DynamicTask {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
|
||||||
|
|
||||||
|
private Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
|
||||||
|
return new ThreadPoolTaskScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String startCron(String key, Runnable task, String corn) {
|
||||||
|
stopCron(key);
|
||||||
|
ScheduledFuture future = threadPoolTaskScheduler.schedule(task, new CronTrigger(corn));
|
||||||
|
futureMap.put(key, future);
|
||||||
|
return "startCron";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopCron(String key) {
|
||||||
|
if (futureMap.get(key) != null && !futureMap.get(key).isCancelled()) {
|
||||||
|
futureMap.get(key).cancel(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -16,7 +16,7 @@ import redis.clients.jedis.JedisPool;
|
|||||||
import redis.clients.jedis.JedisPoolConfig;
|
import redis.clients.jedis.JedisPoolConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
|
* @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2019年5月30日 上午10:58:25
|
* @date: 2019年5月30日 上午10:58:25
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.conf;
|
package com.genersoft.iot.vmp.conf;
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ -27,7 +25,7 @@ public class SipConfig {
|
|||||||
|
|
||||||
Integer ptzSpeed = 50;
|
Integer ptzSpeed = 50;
|
||||||
|
|
||||||
Integer keepaliveTimeOut = 180;
|
Integer keepaliveTimeOut = 255;
|
||||||
|
|
||||||
Integer registerTimeInterval = 60;
|
Integer registerTimeInterval = 60;
|
||||||
|
|
||||||
|
|||||||
@ -32,5 +32,7 @@ public class SipDeviceRunner implements CommandLineRunner {
|
|||||||
for (String deviceId : onlineForAll) {
|
for (String deviceId : onlineForAll) {
|
||||||
storager.online(deviceId);
|
storager.online(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 获取数据库配置
|
* @description: 获取数据库配置
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 下午2:46:00
|
* @date: 2020年5月6日 下午2:46:00
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,19 +1,10 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181;
|
package com.genersoft.iot.vmp.gb28181;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.TooManyListenersException;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.sip.*;
|
|
||||||
import javax.sip.header.CallIdHeader;
|
|
||||||
import javax.sip.header.Header;
|
|
||||||
import javax.sip.message.Response;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
import gov.nist.javax.sip.SipProviderImpl;
|
import gov.nist.javax.sip.SipProviderImpl;
|
||||||
|
import gov.nist.javax.sip.SipStackImpl;
|
||||||
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;
|
||||||
@ -21,14 +12,15 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.DependsOn;
|
import org.springframework.context.annotation.DependsOn;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
import javax.sip.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
|
import java.util.Properties;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
import java.util.TooManyListenersException;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import gov.nist.javax.sip.SipStackImpl;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class SipLayer implements SipListener {
|
public class SipLayer{
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
|
private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
|
||||||
|
|
||||||
@ -36,7 +28,7 @@ public class SipLayer implements SipListener {
|
|||||||
private SipConfig sipConfig;
|
private SipConfig sipConfig;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SIPProcessorFactory processorFactory;
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SipSubscribe sipSubscribe;
|
private SipSubscribe sipSubscribe;
|
||||||
@ -50,19 +42,16 @@ public class SipLayer implements SipListener {
|
|||||||
*/
|
*/
|
||||||
private ThreadPoolExecutor processThreadPool;
|
private ThreadPoolExecutor processThreadPool;
|
||||||
|
|
||||||
@Bean("initSipServer")
|
public SipLayer() {
|
||||||
private ThreadPoolExecutor initSipServer() {
|
|
||||||
|
|
||||||
int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
|
int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
|
||||||
LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000);
|
LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000);
|
||||||
processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
|
processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
|
||||||
0L,TimeUnit.MILLISECONDS,processQueue,
|
0L,TimeUnit.MILLISECONDS,processQueue,
|
||||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
return processThreadPool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean("sipFactory")
|
@Bean("sipFactory")
|
||||||
@DependsOn("initSipServer")
|
|
||||||
private SipFactory createSipFactory() {
|
private SipFactory createSipFactory() {
|
||||||
sipFactory = SipFactory.getInstance();
|
sipFactory = SipFactory.getInstance();
|
||||||
sipFactory.setPathName("gov.nist");
|
sipFactory.setPathName("gov.nist");
|
||||||
@ -70,7 +59,7 @@ public class SipLayer implements SipListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean("sipStack")
|
@Bean("sipStack")
|
||||||
@DependsOn({"initSipServer", "sipFactory"})
|
@DependsOn({"sipFactory"})
|
||||||
private SipStack createSipStack() throws PeerUnavailableException {
|
private SipStack createSipStack() throws PeerUnavailableException {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
|
properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
|
||||||
@ -88,7 +77,7 @@ public class SipLayer implements SipListener {
|
|||||||
return sipStack;
|
return sipStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean("tcpSipProvider")
|
@Bean(name = "tcpSipProvider")
|
||||||
@DependsOn("sipStack")
|
@DependsOn("sipStack")
|
||||||
private SipProviderImpl startTcpListener() {
|
private SipProviderImpl startTcpListener() {
|
||||||
ListeningPoint tcpListeningPoint = null;
|
ListeningPoint tcpListeningPoint = null;
|
||||||
@ -96,7 +85,7 @@ public class SipLayer implements SipListener {
|
|||||||
try {
|
try {
|
||||||
tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "TCP");
|
tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "TCP");
|
||||||
tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint);
|
tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint);
|
||||||
tcpSipProvider.addSipListener(this);
|
tcpSipProvider.addSipListener(sipProcessorObserver);
|
||||||
logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "}");
|
logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "}");
|
||||||
} catch (TransportNotSupportedException e) {
|
} catch (TransportNotSupportedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -111,7 +100,7 @@ public class SipLayer implements SipListener {
|
|||||||
return tcpSipProvider;
|
return tcpSipProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean("udpSipProvider")
|
@Bean(name = "udpSipProvider")
|
||||||
@DependsOn("sipStack")
|
@DependsOn("sipStack")
|
||||||
private SipProviderImpl startUdpListener() {
|
private SipProviderImpl startUdpListener() {
|
||||||
ListeningPoint udpListeningPoint = null;
|
ListeningPoint udpListeningPoint = null;
|
||||||
@ -119,8 +108,7 @@ public class SipLayer implements SipListener {
|
|||||||
try {
|
try {
|
||||||
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(this);
|
udpSipProvider.addSipListener(sipProcessorObserver);
|
||||||
// udpSipProvider.setAutomaticDialogSupportEnabled(false);
|
|
||||||
} catch (TransportNotSupportedException e) {
|
} catch (TransportNotSupportedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (InvalidArgumentException e) {
|
} catch (InvalidArgumentException e) {
|
||||||
@ -135,140 +123,4 @@ public class SipLayer implements SipListener {
|
|||||||
return udpSipProvider;
|
return udpSipProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
|
|
||||||
* new request arrives.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void processRequest(RequestEvent evt) {
|
|
||||||
logger.debug(evt.getRequest().toString());
|
|
||||||
// 由于jainsip是单线程程序,为提高性能并发处理
|
|
||||||
processThreadPool.execute(() -> {
|
|
||||||
if (processorFactory != null) {
|
|
||||||
processorFactory.createRequestProcessor(evt).process();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processResponse(ResponseEvent evt) {
|
|
||||||
Response response = evt.getResponse();
|
|
||||||
logger.debug(evt.getResponse().toString());
|
|
||||||
int status = response.getStatusCode();
|
|
||||||
if (((status >= 200) && (status < 300)) || status == 401) { // Success!
|
|
||||||
ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
|
|
||||||
try {
|
|
||||||
processor.process(evt, this, sipConfig);
|
|
||||||
} catch (ParseException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) {
|
|
||||||
CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
|
|
||||||
if (callIdHeader != null) {
|
|
||||||
SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId());
|
|
||||||
if (subscribe != null) {
|
|
||||||
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(evt);
|
|
||||||
subscribe.response(eventResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((status >= 100) && (status < 200)) {
|
|
||||||
// 增加其它无需回复的响应,如101、180等
|
|
||||||
} else {
|
|
||||||
logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
|
|
||||||
if (evt.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) {
|
|
||||||
CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
|
|
||||||
if (callIdHeader != null) {
|
|
||||||
SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId());
|
|
||||||
if (subscribe != null) {
|
|
||||||
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(evt);
|
|
||||||
subscribe.response(eventResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Title: processTimeout
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Description:
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param timeoutEvent
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void processTimeout(TimeoutEvent timeoutEvent) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
CallIdHeader callIdHeader = timeoutEvent.getClientTransaction().getDialog().getCallId();
|
|
||||||
String callId = callIdHeader.getCallId();
|
|
||||||
SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
|
|
||||||
SipSubscribe.EventResult<TimeoutEvent> timeoutEventEventResult = new SipSubscribe.EventResult<>(timeoutEvent);
|
|
||||||
errorSubscribe.response(timeoutEventEventResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Title: processIOException
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Description:
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param exceptionEvent
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void processIOException(IOExceptionEvent exceptionEvent) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Title: processTransactionTerminated
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Description:
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param transactionTerminatedEvent
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
// CallIdHeader callIdHeader = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId();
|
|
||||||
// String callId = callIdHeader.getCallId();
|
|
||||||
// SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
|
|
||||||
// SipSubscribe.EventResult<TransactionTerminatedEvent> eventResult = new SipSubscribe.EventResult<>(transactionTerminatedEvent);
|
|
||||||
// errorSubscribe.response(eventResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Title: processDialogTerminated
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Description:
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param dialogTerminatedEvent
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
// CallIdHeader callIdHeader = dialogTerminatedEvent.getDialog().getCallId();
|
|
||||||
// String callId = callIdHeader.getCallId();
|
|
||||||
// SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
|
|
||||||
// SipSubscribe.EventResult<DialogTerminatedEvent> eventResult = new SipSubscribe.EventResult<>(dialogTerminatedEvent);
|
|
||||||
// errorSubscribe.response(eventResult);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:注册逻辑处理,当设备注册后触发逻辑。
|
* @description:注册逻辑处理,当设备注册后触发逻辑。
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月8日 下午9:41:46
|
* @date: 2020年5月8日 下午9:41:46
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -109,6 +109,11 @@ public class Device {
|
|||||||
*/
|
*/
|
||||||
private String charset ;
|
private String charset ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 目录订阅周期,0为不订阅
|
||||||
|
*/
|
||||||
|
private int subscribeCycleForCatalog ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getDeviceId() {
|
public String getDeviceId() {
|
||||||
@ -270,4 +275,12 @@ public class Device {
|
|||||||
public void setCharset(String charset) {
|
public void setCharset(String charset) {
|
||||||
this.charset = charset;
|
this.charset = charset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSubscribeCycleForCatalog() {
|
||||||
|
return subscribeCycleForCatalog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubscribeCycleForCatalog(int subscribeCycleForCatalog) {
|
||||||
|
this.subscribeCycleForCatalog = subscribeCycleForCatalog;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.bean;
|
package com.genersoft.iot.vmp.gb28181.bean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 移动位置bean
|
* @description: 移动位置bean
|
||||||
* @author: lawrencehj
|
* @author: lawrencehj
|
||||||
* @date: 2021年1月23日
|
* @date: 2021年1月23日
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -6,7 +6,7 @@ package com.genersoft.iot.vmp.gb28181.bean;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:设备录像信息bean
|
* @description:设备录像信息bean
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月8日 下午2:05:56
|
* @date: 2020年5月8日 下午2:05:56
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:设备录像bean
|
* @description:设备录像bean
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月8日 下午2:06:54
|
* @date: 2020年5月8日 下午2:06:54
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
|||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:设备离在线状态检测器,用于检测设备状态
|
* @description:设备离在线状态检测器,用于检测设备状态
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月13日 下午2:40:29
|
* @date: 2020年5月13日 下午2:40:29
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent;
|
|||||||
import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
|
import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:Event事件通知推送器,支持推送在线事件、离线事件
|
* @description:Event事件通知推送器,支持推送在线事件、离线事件
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 上午11:30:50
|
* @date: 2020年5月6日 上午11:30:50
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
|||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
|
* @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 上午11:35:46
|
* @date: 2020年5月6日 上午11:35:46
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
|||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
|
* @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 上午11:35:46
|
* @date: 2020年5月6日 上午11:35:46
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.gb28181.event.offline;
|
|||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 离线事件类
|
* @description: 离线事件类
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 上午11:33:13
|
* @date: 2020年5月6日 上午11:33:13
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -11,8 +11,8 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
|||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
|
* @description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
|
||||||
* 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
|
* 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor}
|
||||||
* 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
|
* 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 下午1:51:23
|
* @date: 2020年5月6日 下午1:51:23
|
||||||
@ -54,5 +54,8 @@ public class OfflineEventListener implements ApplicationListener<OfflineEvent> {
|
|||||||
|
|
||||||
// 处理离线监听
|
// 处理离线监听
|
||||||
storager.outline(event.getDeviceId());
|
storager.outline(event.getDeviceId());
|
||||||
|
|
||||||
|
// TODO 离线取消订阅
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
|
|||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 在线事件类
|
* @description: 在线事件类
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 上午11:32:56
|
* @date: 2020年5月6日 上午11:32:56
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -13,12 +13,11 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
|||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
|
* @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
|
||||||
* 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
|
* 1、设备主动注销,发送注销指令
|
||||||
* 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor}
|
* 2、设备未知原因离线,心跳超时
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 下午1:51:23
|
* @date: 2020年5月6日 下午1:51:23
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import javax.sip.ResponseEvent;
|
|||||||
import javax.sip.message.Response;
|
import javax.sip.message.Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 平台心跳超时事件
|
* @description: 平台心跳超时事件
|
||||||
* @author: panll
|
* @author: panll
|
||||||
* @date: 2020年11月5日 10:00
|
* @date: 2020年11月5日 10:00
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import org.springframework.stereotype.Component;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 平台未注册事件,来源有二:
|
* @description: 平台未注册事件,来源有二:
|
||||||
* 1、平台新添加
|
* 1、平台新添加
|
||||||
* 2、平台心跳超时
|
* 2、平台心跳超时
|
||||||
* @author: panll
|
* @author: panll
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:视频流session管理器,管理视频预览、预览回放的通信句柄
|
* @description:视频流session管理器,管理视频预览、预览回放的通信句柄
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月13日 下午4:03:02
|
* @date: 2020年5月13日 下午4:03:02
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,243 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit;
|
|
||||||
|
|
||||||
import javax.sip.RequestEvent;
|
|
||||||
import javax.sip.ResponseEvent;
|
|
||||||
import javax.sip.SipProvider;
|
|
||||||
import javax.sip.header.CSeqHeader;
|
|
||||||
import javax.sip.message.Request;
|
|
||||||
import javax.sip.message.Response;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
|
||||||
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
|
||||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
|
|
||||||
import com.genersoft.iot.vmp.service.IPlayService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
|
||||||
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.request.ISIPRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.AckRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.ByeRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.CancelRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.InviteRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.NotifyRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.ByeResponseProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.CancelResponseProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.InviteResponseProcessor;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcessor;
|
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
|
||||||
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
|
|
||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: SIP信令处理分配
|
|
||||||
* @author: swwheihei
|
|
||||||
* @date: 2020年5月3日 下午4:24:37
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class SIPProcessorFactory {
|
|
||||||
|
|
||||||
// private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SipConfig sipConfig;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RegisterLogicHandler handler;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IVideoManagerStorager storager;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private EventPublisher publisher;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SIPCommander cmder;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SIPCommanderFroPlatform cmderFroPlatform;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IDeviceAlarmService deviceAlarmService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RedisUtil redis;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DeferredResultHolder deferredResultHolder;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DeviceOffLineDetector offLineDetector;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private InviteResponseProcessor inviteResponseProcessor;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ByeResponseProcessor byeResponseProcessor;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private CancelResponseProcessor cancelResponseProcessor;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
@Lazy
|
|
||||||
private RegisterResponseProcessor registerResponseProcessor;
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private OtherResponseProcessor otherResponseProcessor;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IPlayService playService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ZLMRTPServerFactory zlmrtpServerFactory;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IMediaServerService mediaServerService;
|
|
||||||
|
|
||||||
// 注:这里使用注解会导致循环依赖注入,暂用springBean
|
|
||||||
private SipProvider tcpSipProvider;
|
|
||||||
|
|
||||||
// 注:这里使用注解会导致循环依赖注入,暂用springBean
|
|
||||||
private SipProvider udpSipProvider;
|
|
||||||
|
|
||||||
public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) {
|
|
||||||
Request request = evt.getRequest();
|
|
||||||
String method = request.getMethod();
|
|
||||||
// logger.info("接收到消息:"+request.getMethod());
|
|
||||||
// sipSubscribe.getSubscribe(evt.getServerTransaction().getBranchId()).response(evt);
|
|
||||||
if (Request.INVITE.equals(method)) {
|
|
||||||
InviteRequestProcessor processor = new InviteRequestProcessor();
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
processor.setTcpSipProvider(getTcpSipProvider());
|
|
||||||
processor.setUdpSipProvider(getUdpSipProvider());
|
|
||||||
|
|
||||||
processor.setCmder(cmder);
|
|
||||||
processor.setCmderFroPlatform(cmderFroPlatform);
|
|
||||||
processor.setPlayService(playService);
|
|
||||||
processor.setStorager(storager);
|
|
||||||
processor.setRedisCatchStorage(redisCatchStorage);
|
|
||||||
processor.setZlmrtpServerFactory(zlmrtpServerFactory);
|
|
||||||
processor.setMediaServerService(mediaServerService);
|
|
||||||
return processor;
|
|
||||||
} else if (Request.REGISTER.equals(method)) {
|
|
||||||
RegisterRequestProcessor processor = new RegisterRequestProcessor();
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
processor.setTcpSipProvider(getTcpSipProvider());
|
|
||||||
processor.setUdpSipProvider(getUdpSipProvider());
|
|
||||||
processor.setHandler(handler);
|
|
||||||
processor.setPublisher(publisher);
|
|
||||||
processor.setSipConfig(sipConfig);
|
|
||||||
processor.setVideoManagerStorager(storager);
|
|
||||||
return processor;
|
|
||||||
} else if (Request.SUBSCRIBE.equals(method)) {
|
|
||||||
SubscribeRequestProcessor processor = new SubscribeRequestProcessor();
|
|
||||||
processor.setTcpSipProvider(getTcpSipProvider());
|
|
||||||
processor.setUdpSipProvider(getUdpSipProvider());
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
return processor;
|
|
||||||
} else if (Request.ACK.equals(method)) {
|
|
||||||
AckRequestProcessor processor = new AckRequestProcessor();
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
processor.setRedisCatchStorage(redisCatchStorage);
|
|
||||||
processor.setZlmrtpServerFactory(zlmrtpServerFactory);
|
|
||||||
processor.setMediaServerService(mediaServerService);
|
|
||||||
return processor;
|
|
||||||
} else if (Request.BYE.equals(method)) {
|
|
||||||
ByeRequestProcessor processor = new ByeRequestProcessor();
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
processor.setRedisCatchStorage(redisCatchStorage);
|
|
||||||
processor.setStorager(storager);
|
|
||||||
processor.setZlmrtpServerFactory(zlmrtpServerFactory);
|
|
||||||
processor.setSIPCommander(cmder);
|
|
||||||
processor.setMediaServerService(mediaServerService);
|
|
||||||
return processor;
|
|
||||||
} else if (Request.CANCEL.equals(method)) {
|
|
||||||
CancelRequestProcessor processor = new CancelRequestProcessor();
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
return processor;
|
|
||||||
} else if (Request.MESSAGE.equals(method)) {
|
|
||||||
MessageRequestProcessor processor = new MessageRequestProcessor();
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
processor.setTcpSipProvider(getTcpSipProvider());
|
|
||||||
processor.setUdpSipProvider(getUdpSipProvider());
|
|
||||||
processor.setPublisher(publisher);
|
|
||||||
processor.setRedis(redis);
|
|
||||||
processor.setDeferredResultHolder(deferredResultHolder);
|
|
||||||
processor.setOffLineDetector(offLineDetector);
|
|
||||||
processor.setCmder(cmder);
|
|
||||||
processor.setCmderFroPlatform(cmderFroPlatform);
|
|
||||||
processor.setDeviceAlarmService(deviceAlarmService);
|
|
||||||
processor.setStorager(storager);
|
|
||||||
processor.setRedisCatchStorage(redisCatchStorage);
|
|
||||||
return processor;
|
|
||||||
} else if (Request.NOTIFY.equalsIgnoreCase(method)) {
|
|
||||||
NotifyRequestProcessor processor = new NotifyRequestProcessor();
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
processor.setTcpSipProvider(getTcpSipProvider());
|
|
||||||
processor.setUdpSipProvider(getUdpSipProvider());
|
|
||||||
processor.setPublisher(publisher);
|
|
||||||
processor.setRedis(redis);
|
|
||||||
processor.setDeferredResultHolder(deferredResultHolder);
|
|
||||||
processor.setOffLineDetector(offLineDetector);
|
|
||||||
processor.setCmder(cmder);
|
|
||||||
processor.setStorager(storager);
|
|
||||||
processor.setRedisCatchStorage(redisCatchStorage);
|
|
||||||
return processor;
|
|
||||||
} else {
|
|
||||||
OtherRequestProcessor processor = new OtherRequestProcessor();
|
|
||||||
processor.setRequestEvent(evt);
|
|
||||||
return processor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) {
|
|
||||||
|
|
||||||
Response response = evt.getResponse();
|
|
||||||
CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
|
|
||||||
String method = cseqHeader.getMethod();
|
|
||||||
if(Request.INVITE.equals(method)){
|
|
||||||
return inviteResponseProcessor;
|
|
||||||
} else if (Request.BYE.equals(method)) {
|
|
||||||
return byeResponseProcessor;
|
|
||||||
} else if (Request.CANCEL.equals(method)) {
|
|
||||||
return cancelResponseProcessor;
|
|
||||||
}else if (Request.REGISTER.equals(method)) {
|
|
||||||
return registerResponseProcessor;
|
|
||||||
} else {
|
|
||||||
return otherResponseProcessor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private SipProvider getTcpSipProvider() {
|
|
||||||
if (tcpSipProvider == null) {
|
|
||||||
tcpSipProvider = (SipProvider) SpringBeanFactory.getBean("tcpSipProvider");
|
|
||||||
}
|
|
||||||
return tcpSipProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SipProvider getUdpSipProvider() {
|
|
||||||
if (udpSipProvider == null) {
|
|
||||||
udpSipProvider = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
|
|
||||||
}
|
|
||||||
return udpSipProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,161 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.*;
|
||||||
|
import javax.sip.header.CSeqHeader;
|
||||||
|
import javax.sip.header.CallIdHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: SIP信令处理类观察者
|
||||||
|
* @author: panlinlin
|
||||||
|
* @date: 2021年11月5日 下午15:32
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SIPProcessorObserver implements SipListener {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(SIPProcessorObserver.class);
|
||||||
|
|
||||||
|
private static Map<String, ISIPRequestProcessor> requestProcessorMap = new ConcurrentHashMap<>();
|
||||||
|
private static Map<String, ISIPResponseProcessor> responseProcessorMap = new ConcurrentHashMap<>();
|
||||||
|
private static ITimeoutProcessor timeoutProcessor;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipSubscribe sipSubscribe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加 request订阅
|
||||||
|
* @param method 方法名
|
||||||
|
* @param processor 处理程序
|
||||||
|
*/
|
||||||
|
public void addRequestProcessor(String method, ISIPRequestProcessor processor) {
|
||||||
|
requestProcessorMap.put(method, processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加 response订阅
|
||||||
|
* @param method 方法名
|
||||||
|
* @param processor 处理程序
|
||||||
|
*/
|
||||||
|
public void addResponseProcessor(String method, ISIPResponseProcessor processor) {
|
||||||
|
responseProcessorMap.put(method, processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加 超时事件订阅
|
||||||
|
* @param processor 处理程序
|
||||||
|
*/
|
||||||
|
public void addTimeoutProcessor(ITimeoutProcessor processor) {
|
||||||
|
this.timeoutProcessor = processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分发RequestEvent事件
|
||||||
|
* @param requestEvent RequestEvent事件
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void processRequest(RequestEvent requestEvent) {
|
||||||
|
String method = requestEvent.getRequest().getMethod();
|
||||||
|
ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method);
|
||||||
|
if (sipRequestProcessor == null) {
|
||||||
|
logger.warn("不支持方法{}的request", method);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
requestProcessorMap.get(method).process(requestEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分发ResponseEvent事件
|
||||||
|
* @param responseEvent responseEvent事件
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void processResponse(ResponseEvent responseEvent) {
|
||||||
|
logger.debug(responseEvent.getResponse().toString());
|
||||||
|
// CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
|
||||||
|
// String method = cseqHeader.getMethod();
|
||||||
|
// ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method);
|
||||||
|
// if (sipRequestProcessor == null) {
|
||||||
|
// logger.warn("不支持方法{}的response", method);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// sipRequestProcessor.process(responseEvent);
|
||||||
|
|
||||||
|
|
||||||
|
Response response = responseEvent.getResponse();
|
||||||
|
logger.debug(responseEvent.getResponse().toString());
|
||||||
|
int status = response.getStatusCode();
|
||||||
|
if (((status >= 200) && (status < 300)) || status == 401) { // Success!
|
||||||
|
// ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
|
||||||
|
CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
|
||||||
|
String method = cseqHeader.getMethod();
|
||||||
|
ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method);
|
||||||
|
if (sipRequestProcessor != null) {
|
||||||
|
sipRequestProcessor.process(responseEvent);
|
||||||
|
}
|
||||||
|
if (responseEvent.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) {
|
||||||
|
CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME);
|
||||||
|
if (callIdHeader != null) {
|
||||||
|
SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId());
|
||||||
|
if (subscribe != null) {
|
||||||
|
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent);
|
||||||
|
subscribe.response(eventResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((status >= 100) && (status < 200)) {
|
||||||
|
// 增加其它无需回复的响应,如101、180等
|
||||||
|
} else {
|
||||||
|
logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
|
||||||
|
if (responseEvent.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) {
|
||||||
|
CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME);
|
||||||
|
if (callIdHeader != null) {
|
||||||
|
SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId());
|
||||||
|
if (subscribe != null) {
|
||||||
|
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(responseEvent);
|
||||||
|
subscribe.response(eventResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向超时订阅发送消息
|
||||||
|
* @param timeoutEvent timeoutEvent事件
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void processTimeout(TimeoutEvent timeoutEvent) {
|
||||||
|
if(timeoutProcessor != null) {
|
||||||
|
timeoutProcessor.process(timeoutEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processIOException(IOExceptionEvent exceptionEvent) {
|
||||||
|
// System.out.println("processIOException");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
|
||||||
|
// System.out.println("processTransactionTerminated");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
|
||||||
|
CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId();
|
||||||
|
System.out.println("processDialogTerminated:::::" + callId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,17 +1,16 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.callback;
|
package com.genersoft.iot.vmp.gb28181.transmit.callback;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.RecordInfoResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor;
|
|
||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class CheckForAllRecordsThread extends Thread {
|
public class CheckForAllRecordsThread extends Thread {
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ public class CheckForAllRecordsThread extends Thread {
|
|||||||
msg.setData(recordInfo);
|
msg.setData(recordInfo);
|
||||||
deferredResultHolder.invokeAllResult(msg);
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
logger.info("处理完成,返回结果");
|
logger.info("处理完成,返回结果");
|
||||||
MessageRequestProcessor.threadNameList.remove(cacheKey);
|
RecordInfoResponseMessageHandler.threadNameList.remove(cacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRedis(RedisUtil redis) {
|
public void setRedis(RedisUtil redis) {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.web.context.request.async.DeferredResult;
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 异步请求处理
|
* @description: 异步请求处理
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月8日 下午7:59:05
|
* @date: 2020年5月8日 下午7:59:05
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.callback;
|
package com.genersoft.iot.vmp.gb28181.transmit.callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 请求信息定义
|
* @description: 请求信息定义
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月8日 下午1:09:18
|
* @date: 2020年5月8日 下午1:09:18
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
|||||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:设备能力接口,用于定义设备的控制、查询能力
|
* @description:设备能力接口,用于定义设备的控制、查询能力
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月3日 下午9:16:34
|
* @date: 2020年5月3日 下午9:16:34
|
||||||
*/
|
*/
|
||||||
@ -299,4 +299,11 @@ public interface ISIPCommander {
|
|||||||
* @return true = 命令发送成功
|
* @return true = 命令发送成功
|
||||||
*/
|
*/
|
||||||
boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
|
boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订阅、取消订阅目录信息
|
||||||
|
* @param device 视频设备
|
||||||
|
* @return true = 命令发送成功
|
||||||
|
*/
|
||||||
|
boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 平台命令request创造器 TODO 冗余代码太多待优化
|
* @description: 平台命令request创造器 TODO 冗余代码太多待优化
|
||||||
* @author: panll
|
* @author: panll
|
||||||
* @date: 2020年5月6日 上午9:29:02
|
* @date: 2020年5月6日 上午9:29:02
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import com.genersoft.iot.vmp.conf.SipConfig;
|
|||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:摄像头命令request创造器 TODO 冗余代码太多待优化
|
* @description:摄像头命令request创造器 TODO 冗余代码太多待优化
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 上午9:29:02
|
* @date: 2020年5月6日 上午9:29:02
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,20 +1,17 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import javax.sip.*;
|
|
||||||
import javax.sip.address.SipURI;
|
|
||||||
import javax.sip.header.CallIdHeader;
|
|
||||||
import javax.sip.header.ViaHeader;
|
|
||||||
import javax.sip.message.Request;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetup;
|
import com.genersoft.iot.vmp.conf.UserSetup;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||||
import com.genersoft.iot.vmp.media.zlm.*;
|
|
||||||
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.transmit.cmd.ISIPCommander;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
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.SSRCInfo;
|
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||||
@ -29,20 +26,20 @@ 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.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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.*;
|
||||||
|
import javax.sip.address.SipURI;
|
||||||
|
import javax.sip.header.CallIdHeader;
|
||||||
|
import javax.sip.header.ViaHeader;
|
||||||
|
import javax.sip.message.Request;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:设备能力接口,用于定义设备的控制、查询能力
|
* @description:设备能力接口,用于定义设备的控制、查询能力
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月3日 下午9:22:48
|
* @date: 2020年5月3日 下午9:22:48
|
||||||
*/
|
*/
|
||||||
@ -55,12 +52,10 @@ public class SIPCommander implements ISIPCommander {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SipConfig sipConfig;
|
private SipConfig sipConfig;
|
||||||
|
|
||||||
@Lazy
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier(value="tcpSipProvider")
|
@Qualifier(value="tcpSipProvider")
|
||||||
private SipProviderImpl tcpSipProvider;
|
private SipProviderImpl tcpSipProvider;
|
||||||
|
|
||||||
@Lazy
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier(value="udpSipProvider")
|
@Qualifier(value="udpSipProvider")
|
||||||
private SipProviderImpl udpSipProvider;
|
private SipProviderImpl udpSipProvider;
|
||||||
@ -89,11 +84,6 @@ public class SIPCommander implements ISIPCommander {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IMediaServerService mediaServerService;
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
private SIPDialog dialog;
|
|
||||||
|
|
||||||
public SipConfig getSipConfig() {
|
|
||||||
return sipConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 云台方向放控制,使用配置文件中的默认镜头移动速度
|
* 云台方向放控制,使用配置文件中的默认镜头移动速度
|
||||||
@ -1490,6 +1480,33 @@ public class SIPCommander implements ISIPCommander {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
|
||||||
|
try {
|
||||||
|
StringBuffer cmdXml = new StringBuffer(200);
|
||||||
|
cmdXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
|
||||||
|
cmdXml.append("<Query>\r\n");
|
||||||
|
cmdXml.append("<CmdType>CataLog</CmdType>\r\n");
|
||||||
|
cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
||||||
|
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||||
|
cmdXml.append("</Query>\r\n");
|
||||||
|
|
||||||
|
String tm = Long.toString(System.currentTimeMillis());
|
||||||
|
|
||||||
|
CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
|
||||||
|
: udpSipProvider.getNewCallId();
|
||||||
|
|
||||||
|
Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, device.getSubscribeCycleForCatalog(), "presence" , callIdHeader);
|
||||||
|
transmitRequest(device, request, errorEvent, okEvent);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch ( NumberFormatException | ParseException | InvalidArgumentException | SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
|
private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
|
||||||
return transmitRequest(device, request, null, null);
|
return transmitRequest(device, request, null, null);
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 对SIP事件进行处理,包括request, response, timeout, ioException, transactionTerminated,dialogTerminated
|
||||||
|
* @author: panlinlin
|
||||||
|
* @date: 2021年11月5日 15:47
|
||||||
|
*/
|
||||||
|
public interface ISIPRequestProcessor {
|
||||||
|
|
||||||
|
void process(RequestEvent event);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request;
|
||||||
|
|
||||||
|
import gov.nist.javax.sip.SipProviderImpl;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:处理接收IPCamera发来的SIP协议请求消息
|
||||||
|
* @author: songww
|
||||||
|
* @date: 2020年5月3日 下午4:42:22
|
||||||
|
*/
|
||||||
|
public abstract class SIPRequestProcessorAbstract {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(value="tcpSipProvider")
|
||||||
|
private SipProviderImpl tcpSipProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(value="udpSipProvider")
|
||||||
|
private SipProviderImpl udpSipProvider;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,179 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request;
|
||||||
|
|
||||||
|
import gov.nist.javax.sip.SipProviderImpl;
|
||||||
|
import gov.nist.javax.sip.SipStackImpl;
|
||||||
|
import gov.nist.javax.sip.message.SIPRequest;
|
||||||
|
import gov.nist.javax.sip.stack.SIPServerTransaction;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.dom4j.io.SAXReader;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
import javax.sip.*;
|
||||||
|
import javax.sip.address.Address;
|
||||||
|
import javax.sip.address.AddressFactory;
|
||||||
|
import javax.sip.address.SipURI;
|
||||||
|
import javax.sip.header.ContentTypeHeader;
|
||||||
|
import javax.sip.header.HeaderFactory;
|
||||||
|
import javax.sip.header.ViaHeader;
|
||||||
|
import javax.sip.message.MessageFactory;
|
||||||
|
import javax.sip.message.Request;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:处理接收IPCamera发来的SIP协议请求消息
|
||||||
|
* @author: songww
|
||||||
|
* @date: 2020年5月3日 下午4:42:22
|
||||||
|
*/
|
||||||
|
public abstract class SIPRequestProcessorParent {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(SIPRequestProcessorParent.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(value="tcpSipProvider")
|
||||||
|
private SipProviderImpl tcpSipProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(value="udpSipProvider")
|
||||||
|
private SipProviderImpl udpSipProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 RequestEvent 获取 ServerTransaction
|
||||||
|
* @param evt
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ServerTransaction getServerTransaction(RequestEvent evt) {
|
||||||
|
Request request = evt.getRequest();
|
||||||
|
ServerTransaction serverTransaction = evt.getServerTransaction();
|
||||||
|
// 判断TCP还是UDP
|
||||||
|
boolean isTcp = false;
|
||||||
|
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
||||||
|
String transport = reqViaHeader.getTransport();
|
||||||
|
if (transport.equals("TCP")) {
|
||||||
|
isTcp = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverTransaction == null) {
|
||||||
|
try {
|
||||||
|
if (isTcp) {
|
||||||
|
SipStackImpl stack = (SipStackImpl)tcpSipProvider.getSipStack();
|
||||||
|
serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
|
||||||
|
if (serverTransaction == null) {
|
||||||
|
serverTransaction = tcpSipProvider.getNewServerTransaction(request);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SipStackImpl stack = (SipStackImpl)udpSipProvider.getSipStack();
|
||||||
|
serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
|
||||||
|
if (serverTransaction == null) {
|
||||||
|
serverTransaction = udpSipProvider.getNewServerTransaction(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (TransactionAlreadyExistsException e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
} catch (TransactionUnavailableException e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return serverTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddressFactory getAddressFactory() {
|
||||||
|
try {
|
||||||
|
return SipFactory.getInstance().createAddressFactory();
|
||||||
|
} catch (PeerUnavailableException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HeaderFactory getHeaderFactory() {
|
||||||
|
try {
|
||||||
|
return SipFactory.getInstance().createHeaderFactory();
|
||||||
|
} catch (PeerUnavailableException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageFactory getMessageFactory() {
|
||||||
|
try {
|
||||||
|
return SipFactory.getInstance().createMessageFactory();
|
||||||
|
} catch (PeerUnavailableException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 回复状态码
|
||||||
|
* 100 trying
|
||||||
|
* 200 OK
|
||||||
|
* 400
|
||||||
|
* 404
|
||||||
|
* @param evt
|
||||||
|
* @throws SipException
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* @throws ParseException
|
||||||
|
*/
|
||||||
|
public void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException {
|
||||||
|
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
|
||||||
|
ServerTransaction serverTransaction = getServerTransaction(evt);
|
||||||
|
serverTransaction.sendResponse(response);
|
||||||
|
if (statusCode >= 200 && !"NOTIFY".equals(evt.getRequest().getMethod())) {
|
||||||
|
|
||||||
|
if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void responseAck(RequestEvent evt, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
|
||||||
|
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
|
||||||
|
response.setReasonPhrase(msg);
|
||||||
|
ServerTransaction serverTransaction = getServerTransaction(evt);
|
||||||
|
serverTransaction.sendResponse(response);
|
||||||
|
if (statusCode >= 200 && !"NOTIFY".equals(evt.getRequest().getMethod())) {
|
||||||
|
if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回复带sdp的200
|
||||||
|
* @param evt
|
||||||
|
* @param sdp
|
||||||
|
* @throws SipException
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* @throws ParseException
|
||||||
|
*/
|
||||||
|
public void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException {
|
||||||
|
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
|
||||||
|
SipFactory sipFactory = SipFactory.getInstance();
|
||||||
|
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
|
||||||
|
response.setContent(sdp, contentTypeHeader);
|
||||||
|
|
||||||
|
SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
|
||||||
|
|
||||||
|
Address concatAddress = sipFactory.createAddressFactory().createAddress(
|
||||||
|
sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort()
|
||||||
|
));
|
||||||
|
response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
|
||||||
|
getServerTransaction(evt).sendResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element getRootElement(RequestEvent evt) throws DocumentException {
|
||||||
|
return getRootElement(evt, "gb2312");
|
||||||
|
}
|
||||||
|
public Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
|
||||||
|
if (charset == null) charset = "gb2312";
|
||||||
|
Request request = evt.getRequest();
|
||||||
|
SAXReader reader = new SAXReader();
|
||||||
|
reader.setEncoding(charset);
|
||||||
|
Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
|
||||||
|
return xml.getRootElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,39 +1,60 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.sip.*;
|
|
||||||
import javax.sip.address.SipURI;
|
|
||||||
import javax.sip.header.FromHeader;
|
|
||||||
import javax.sip.header.HeaderAddress;
|
|
||||||
import javax.sip.header.ToHeader;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
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.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.IMediaServerService;
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
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.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.Dialog;
|
||||||
|
import javax.sip.DialogState;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.address.SipURI;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.header.HeaderAddress;
|
||||||
|
import javax.sip.header.ToHeader;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:ACK请求处理器
|
* @description:ACK请求处理器
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月3日 下午5:31:45
|
* @date: 2020年5月3日 下午5:31:45
|
||||||
*/
|
*/
|
||||||
public class AckRequestProcessor extends SIPRequestAbstractProcessor {
|
@Component
|
||||||
|
public class AckRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(AckRequestProcessor.class);
|
private Logger logger = LoggerFactory.getLogger(AckRequestProcessor.class);
|
||||||
|
private String method = "ACK";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private ZLMRTPServerFactory zlmrtpServerFactory;
|
private ZLMRTPServerFactory zlmrtpServerFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IMediaServerService mediaServerService;
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理 ACK请求
|
* 处理 ACK请求
|
||||||
*
|
*
|
||||||
@ -41,11 +62,9 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void process(RequestEvent evt) {
|
public void process(RequestEvent evt) {
|
||||||
//Request request = evt.getRequest();
|
|
||||||
Dialog dialog = evt.getDialog();
|
Dialog dialog = evt.getDialog();
|
||||||
if (dialog == null) return;
|
if (dialog == null) return;
|
||||||
//DialogState state = dialog.getState();
|
if (dialog.getState()== DialogState.CONFIRMED) {
|
||||||
if (/*request.getMecodewwthod().equals(Request.INVITE) &&*/ dialog.getState()== DialogState.CONFIRMED) {
|
|
||||||
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);
|
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId);
|
||||||
@ -102,41 +121,5 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try {
|
|
||||||
// Request ackRequest = null;
|
|
||||||
// CSeq csReq = (CSeq) request.getHeader(CSeq.NAME);
|
|
||||||
// ackRequest = dialog.createAck(csReq.getSeqNumber());
|
|
||||||
// dialog.sendAck(ackRequest);
|
|
||||||
// logger.info("send ack to callee:" + ackRequest.toString());
|
|
||||||
// } catch (SipException e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// } catch (InvalidArgumentException e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public IRedisCatchStorage getRedisCatchStorage() {
|
|
||||||
return redisCatchStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
|
|
||||||
this.redisCatchStorage = redisCatchStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZLMRTPServerFactory getZlmrtpServerFactory() {
|
|
||||||
return zlmrtpServerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
|
|
||||||
this.zlmrtpServerFactory = zlmrtpServerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMediaServerService getMediaServerService() {
|
|
||||||
return mediaServerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMediaServerService(IMediaServerService mediaServerService) {
|
|
||||||
this.mediaServerService = mediaServerService;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,17 +1,12 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
import javax.sip.*;
|
|
||||||
import javax.sip.address.SipURI;
|
|
||||||
import javax.sip.header.FromHeader;
|
|
||||||
import javax.sip.header.HeaderAddress;
|
|
||||||
import javax.sip.header.ToHeader;
|
|
||||||
import javax.sip.message.Response;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
||||||
|
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.ISIPCommander;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
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.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.IMediaServerService;
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
@ -19,30 +14,56 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
|||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
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.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.*;
|
||||||
|
import javax.sip.address.SipURI;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.header.HeaderAddress;
|
||||||
|
import javax.sip.header.ToHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: BYE请求处理器
|
* @description: BYE请求处理器
|
||||||
* @author: lawrencehj
|
* @author: lawrencehj
|
||||||
* @date: 2021年3月9日
|
* @date: 2021年3月9日
|
||||||
*/
|
*/
|
||||||
public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
|
@Component
|
||||||
|
public class ByeRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(ByeRequestProcessor.class);
|
private Logger logger = LoggerFactory.getLogger(ByeRequestProcessor.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private ISIPCommander cmder;
|
private ISIPCommander cmder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IVideoManagerStorager storager;
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private ZLMRTPServerFactory zlmrtpServerFactory;
|
private ZLMRTPServerFactory zlmrtpServerFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IMediaServerService mediaServerService;
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
|
private String method = "BYE";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理BYE请求
|
* 处理BYE请求
|
||||||
* @param evt
|
* @param evt
|
||||||
@ -50,7 +71,7 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public void process(RequestEvent evt) {
|
public void process(RequestEvent evt) {
|
||||||
try {
|
try {
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
Dialog dialog = evt.getDialog();
|
Dialog dialog = evt.getDialog();
|
||||||
if (dialog == null) return;
|
if (dialog == null) return;
|
||||||
if (dialog.getState().equals(DialogState.TERMINATED)) {
|
if (dialog.getState().equals(DialogState.TERMINATED)) {
|
||||||
@ -93,58 +114,4 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
|
||||||
* 回复200 OK
|
|
||||||
* @param evt
|
|
||||||
* @throws SipException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws ParseException
|
|
||||||
*/
|
|
||||||
private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
|
|
||||||
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
|
|
||||||
ServerTransaction serverTransaction = getServerTransaction(evt);
|
|
||||||
serverTransaction.sendResponse(response);
|
|
||||||
if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IRedisCatchStorage getRedisCatchStorage() {
|
|
||||||
return redisCatchStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
|
|
||||||
this.redisCatchStorage = redisCatchStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZLMRTPServerFactory getZlmrtpServerFactory() {
|
|
||||||
return zlmrtpServerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
|
|
||||||
this.zlmrtpServerFactory = zlmrtpServerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ISIPCommander getSIPCommander() {
|
|
||||||
return cmder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSIPCommander(ISIPCommander cmder) {
|
|
||||||
this.cmder = cmder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMediaServerService getMediaServerService() {
|
|
||||||
return mediaServerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMediaServerService(IMediaServerService mediaServerService) {
|
|
||||||
this.mediaServerService = mediaServerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IVideoManagerStorager getStorager() {
|
|
||||||
return storager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStorager(IVideoManagerStorager storager) {
|
|
||||||
this.storager = storager;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:CANCEL请求处理器
|
||||||
|
* @author: swwheihei
|
||||||
|
* @date: 2020年5月3日 下午5:32:23
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CancelRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
|
private String method = "CANCEL";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理CANCEL请求
|
||||||
|
*
|
||||||
|
* @param evt 事件
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void process(RequestEvent evt) {
|
||||||
|
// TODO 优先级99 Cancel Request消息实现,此消息一般为级联消息,上级给下级发送请求取消指令
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,62 +1,79 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
import javax.sdp.*;
|
|
||||||
import javax.sip.*;
|
|
||||||
import javax.sip.address.Address;
|
|
||||||
import javax.sip.address.SipURI;
|
|
||||||
import javax.sip.header.*;
|
|
||||||
import javax.sip.message.Request;
|
|
||||||
import javax.sip.message.Response;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
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.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
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.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.IMediaServerService;
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
|
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.IVideoManagerStorager;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
|
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
|
||||||
import com.genersoft.iot.vmp.service.IPlayService;
|
|
||||||
import gov.nist.javax.sip.address.AddressImpl;
|
import gov.nist.javax.sip.address.AddressImpl;
|
||||||
import gov.nist.javax.sip.address.SipUri;
|
import gov.nist.javax.sip.address.SipUri;
|
||||||
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.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sdp.*;
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.ServerTransaction;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.address.SipURI;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.message.Request;
|
||||||
|
import javax.sip.message.Response;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:处理INVITE请求
|
* @description:处理INVITE请求
|
||||||
* @author: panll
|
* @author: panll
|
||||||
* @date: 2021年1月14日
|
* @date: 2021年1月14日
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
|
@Component
|
||||||
|
public class InviteRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(InviteRequestProcessor.class);
|
private final static Logger logger = LoggerFactory.getLogger(InviteRequestProcessor.class);
|
||||||
|
|
||||||
|
private String method = "INVITE";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private SIPCommanderFroPlatform cmderFroPlatform;
|
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IVideoManagerStorager storager;
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private SIPCommander cmder;
|
private SIPCommander cmder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IPlayService playService;
|
private IPlayService playService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private ZLMRTPServerFactory zlmrtpServerFactory;
|
private ZLMRTPServerFactory zlmrtpServerFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IMediaServerService mediaServerService;
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
public ZLMRTPServerFactory getZlmrtpServerFactory() {
|
@Autowired
|
||||||
return zlmrtpServerFactory;
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
}
|
|
||||||
|
|
||||||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
|
@Override
|
||||||
this.zlmrtpServerFactory = zlmrtpServerFactory;
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -368,111 +385,4 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***
|
|
||||||
* 回复状态码
|
|
||||||
* 100 trying
|
|
||||||
* 200 OK
|
|
||||||
* 400
|
|
||||||
* 404
|
|
||||||
* @param evt
|
|
||||||
* @throws SipException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws ParseException
|
|
||||||
*/
|
|
||||||
private void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException {
|
|
||||||
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
|
|
||||||
ServerTransaction serverTransaction = getServerTransaction(evt);
|
|
||||||
serverTransaction.sendResponse(response);
|
|
||||||
if (statusCode >= 200) {
|
|
||||||
if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void responseAck(RequestEvent evt, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
|
|
||||||
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
|
|
||||||
response.setReasonPhrase(msg);
|
|
||||||
ServerTransaction serverTransaction = getServerTransaction(evt);
|
|
||||||
serverTransaction.sendResponse(response);
|
|
||||||
if (statusCode >= 200) {
|
|
||||||
if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回复带sdp的200
|
|
||||||
* @param evt
|
|
||||||
* @param sdp
|
|
||||||
* @throws SipException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws ParseException
|
|
||||||
*/
|
|
||||||
private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException {
|
|
||||||
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
|
|
||||||
SipFactory sipFactory = SipFactory.getInstance();
|
|
||||||
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
|
|
||||||
response.setContent(sdp, contentTypeHeader);
|
|
||||||
|
|
||||||
SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
|
|
||||||
|
|
||||||
Address concatAddress = sipFactory.createAddressFactory().createAddress(
|
|
||||||
sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort()
|
|
||||||
));
|
|
||||||
response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
|
|
||||||
getServerTransaction(evt).sendResponse(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public SIPCommanderFroPlatform getCmderFroPlatform() {
|
|
||||||
return cmderFroPlatform;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) {
|
|
||||||
this.cmderFroPlatform = cmderFroPlatform;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IVideoManagerStorager getStorager() {
|
|
||||||
return storager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStorager(IVideoManagerStorager storager) {
|
|
||||||
this.storager = storager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SIPCommander getCmder() {
|
|
||||||
return cmder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCmder(SIPCommander cmder) {
|
|
||||||
this.cmder = cmder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IPlayService getPlayService() {
|
|
||||||
return playService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayService(IPlayService playService) {
|
|
||||||
this.playService = playService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IRedisCatchStorage getRedisCatchStorage() {
|
|
||||||
return redisCatchStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
|
|
||||||
this.redisCatchStorage = redisCatchStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMediaServerService getMediaServerService() {
|
|
||||||
return mediaServerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMediaServerService(IMediaServerService mediaServerService) {
|
|
||||||
this.mediaServerService = mediaServerService;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,92 +1,71 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import javax.sip.*;
|
|
||||||
import javax.sip.address.Address;
|
|
||||||
import javax.sip.address.SipURI;
|
|
||||||
|
|
||||||
import javax.sip.header.FromHeader;
|
|
||||||
import javax.sip.header.Header;
|
|
||||||
import javax.sip.header.HeaderAddress;
|
|
||||||
import javax.sip.header.ToHeader;
|
|
||||||
import javax.sip.message.Request;
|
|
||||||
import javax.sip.message.Response;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.genersoft.iot.vmp.VManageBootstrap;
|
import com.genersoft.iot.vmp.VManageBootstrap;
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetup;
|
import com.genersoft.iot.vmp.conf.UserSetup;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.CheckForAllRecordsThread;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.CheckForAllRecordsThread;
|
||||||
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.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
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.utils.DateUtil;
|
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
||||||
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
||||||
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
import com.genersoft.iot.vmp.utils.GpsUtil;
|
import com.genersoft.iot.vmp.utils.GpsUtil;
|
||||||
import com.genersoft.iot.vmp.utils.SipUtils;
|
|
||||||
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
|
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
|
||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
||||||
|
|
||||||
import gov.nist.javax.sip.SipStackImpl;
|
import gov.nist.javax.sip.SipStackImpl;
|
||||||
import gov.nist.javax.sip.address.AddressImpl;
|
|
||||||
import gov.nist.javax.sip.address.SipUri;
|
import gov.nist.javax.sip.address.SipUri;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
|
||||||
import org.dom4j.DocumentException;
|
import org.dom4j.DocumentException;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
import org.dom4j.io.SAXReader;
|
|
||||||
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.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.*;
|
||||||
|
import javax.sip.address.SipURI;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.header.HeaderAddress;
|
||||||
|
import javax.sip.header.ToHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:MESSAGE请求处理器
|
* @description: MESSAGE请求分发处理器,
|
||||||
* @author: swwheihei
|
* @author: panlinlin
|
||||||
* @date: 2020年5月3日 下午5:32:41
|
* @date: 2021年11月8日 10:28
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings(value={"unchecked", "rawtypes"})
|
@SuppressWarnings(value={"unchecked", "rawtypes"})
|
||||||
public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
@Component
|
||||||
|
public class MessageRequestProcessor1 extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
public static volatile List<String> threadNameList = new ArrayList();
|
public static volatile List<String> threadNameList = new ArrayList();
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor1.class);
|
||||||
|
private static Map<String, ISIPRequestProcessor> messageHandlerMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private UserSetup userSetup = (UserSetup) SpringBeanFactory.getBean("userSetup");
|
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
|
|
||||||
|
|
||||||
private SIPCommander cmder;
|
|
||||||
|
|
||||||
private SIPCommanderFroPlatform cmderFroPlatform;
|
|
||||||
|
|
||||||
private IVideoManagerStorager storager;
|
|
||||||
|
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
|
||||||
|
|
||||||
private EventPublisher publisher;
|
|
||||||
|
|
||||||
private RedisUtil redis;
|
|
||||||
|
|
||||||
private DeferredResultHolder deferredResultHolder;
|
|
||||||
|
|
||||||
private DeviceOffLineDetector offLineDetector;
|
|
||||||
|
|
||||||
private IDeviceAlarmService deviceAlarmService;
|
|
||||||
|
|
||||||
private final static String CACHE_RECORDINFO_KEY = "CACHE_RECORDINFO_";
|
private final static String CACHE_RECORDINFO_KEY = "CACHE_RECORDINFO_";
|
||||||
|
|
||||||
private static final String MESSAGE_KEEP_ALIVE = "Keepalive";
|
private static final String MESSAGE_KEEP_ALIVE = "Keepalive";
|
||||||
private static final String MESSAGE_CONFIG_DOWNLOAD = "ConfigDownload";
|
private static final String MESSAGE_CONFIG_DOWNLOAD = "ConfigDownload";
|
||||||
private static final String MESSAGE_CATALOG = "Catalog";
|
private static final String MESSAGE_CATALOG = "Catalog";
|
||||||
@ -99,8 +78,50 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
private static final String MESSAGE_DEVICE_CONTROL = "DeviceControl";
|
private static final String MESSAGE_DEVICE_CONTROL = "DeviceControl";
|
||||||
private static final String MESSAGE_DEVICE_CONFIG = "DeviceConfig";
|
private static final String MESSAGE_DEVICE_CONFIG = "DeviceConfig";
|
||||||
private static final String MESSAGE_MOBILE_POSITION = "MobilePosition";
|
private static final String MESSAGE_MOBILE_POSITION = "MobilePosition";
|
||||||
// private static final String MESSAGE_MOBILE_POSITION_INTERVAL = "Interval";
|
|
||||||
private static final String MESSAGE_PRESET_QUERY = "PresetQuery";
|
private static final String MESSAGE_PRESET_QUERY = "PresetQuery";
|
||||||
|
private String method = "MESSAGE1111";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserSetup userSetup;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommander cmder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisUtil redis;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceOffLineDetector offLineDetector;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceAlarmService deviceAlarmService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理MESSAGE请求
|
* 处理MESSAGE请求
|
||||||
@ -112,7 +133,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String cmd = XmlUtil.getText(rootElement, "CmdType");
|
String cmd = getText(rootElement, "CmdType");
|
||||||
|
|
||||||
if (MESSAGE_KEEP_ALIVE.equals(cmd)) {
|
if (MESSAGE_KEEP_ALIVE.equals(cmd)) {
|
||||||
logger.debug("接收到KeepAlive消息");
|
logger.debug("接收到KeepAlive消息");
|
||||||
@ -155,7 +176,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
processMessageBroadcast(evt);
|
processMessageBroadcast(evt);
|
||||||
} else {
|
} else {
|
||||||
logger.debug("接收到消息:" + cmd);
|
logger.debug("接收到消息:" + cmd);
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
}
|
}
|
||||||
} catch (DocumentException | SipException |InvalidArgumentException | ParseException e) {
|
} catch (DocumentException | SipException |InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -173,7 +194,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理MobilePosition移动位置消息时未找到设备信息");
|
logger.warn("处理MobilePosition移动位置消息时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Element rootElement = getRootElement(evt, device.getCharset());
|
Element rootElement = getRootElement(evt, device.getCharset());
|
||||||
@ -183,22 +204,22 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
mobilePosition.setDeviceName(device.getName());
|
mobilePosition.setDeviceName(device.getName());
|
||||||
}
|
}
|
||||||
mobilePosition.setDeviceId(deviceId);
|
mobilePosition.setDeviceId(deviceId);
|
||||||
mobilePosition.setChannelId(XmlUtil.getText(rootElement, "DeviceID"));
|
mobilePosition.setChannelId(getText(rootElement, "DeviceID"));
|
||||||
mobilePosition.setTime(XmlUtil.getText(rootElement, "Time"));
|
mobilePosition.setTime(getText(rootElement, "Time"));
|
||||||
mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
|
mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
|
||||||
mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
|
mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) {
|
if (NumericUtil.isDouble(getText(rootElement, "Speed"))) {
|
||||||
mobilePosition.setSpeed(Double.parseDouble(XmlUtil.getText(rootElement, "Speed")));
|
mobilePosition.setSpeed(Double.parseDouble(getText(rootElement, "Speed")));
|
||||||
} else {
|
} else {
|
||||||
mobilePosition.setSpeed(0.0);
|
mobilePosition.setSpeed(0.0);
|
||||||
}
|
}
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Direction"))) {
|
if (NumericUtil.isDouble(getText(rootElement, "Direction"))) {
|
||||||
mobilePosition.setDirection(Double.parseDouble(XmlUtil.getText(rootElement, "Direction")));
|
mobilePosition.setDirection(Double.parseDouble(getText(rootElement, "Direction")));
|
||||||
} else {
|
} else {
|
||||||
mobilePosition.setDirection(0.0);
|
mobilePosition.setDirection(0.0);
|
||||||
}
|
}
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Altitude"))) {
|
if (NumericUtil.isDouble(getText(rootElement, "Altitude"))) {
|
||||||
mobilePosition.setAltitude(Double.parseDouble(XmlUtil.getText(rootElement, "Altitude")));
|
mobilePosition.setAltitude(Double.parseDouble(getText(rootElement, "Altitude")));
|
||||||
} else {
|
} else {
|
||||||
mobilePosition.setAltitude(0.0);
|
mobilePosition.setAltitude(0.0);
|
||||||
}
|
}
|
||||||
@ -214,7 +235,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
}
|
}
|
||||||
storager.insertMobilePosition(mobilePosition);
|
storager.insertMobilePosition(mobilePosition);
|
||||||
//回复 200 OK
|
//回复 200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -231,7 +252,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理DeviceStatus设备状态Message时未找到设备信息");
|
logger.warn("处理DeviceStatus设备状态Message时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
@ -243,11 +264,11 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||||
String platformId = ((SipUri) fromHeader.getAddress().getURI()).getUser();
|
String platformId = ((SipUri) fromHeader.getAddress().getURI()).getUser();
|
||||||
if (platformId == null) {
|
if (platformId == null) {
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
String sn = rootElement.element("SN").getText();
|
String sn = rootElement.element("SN").getText();
|
||||||
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
|
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
|
||||||
cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag());
|
cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag());
|
||||||
@ -257,7 +278,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
// 检查设备是否存在, 不存在则不回复
|
// 检查设备是否存在, 不存在则不回复
|
||||||
if (storager.exists(deviceId)) {
|
if (storager.exists(deviceId)) {
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
XmlUtil.node2Json(rootElement, json);
|
XmlUtil.node2Json(rootElement, json);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
@ -291,14 +312,14 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理DeviceControl设备状态Message未找到设备信息");
|
logger.warn("处理DeviceControl设备状态Message未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String channelId = XmlUtil.getText(rootElement, "DeviceID");
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
//String result = XmlUtil.getText(rootElement, "Result");
|
//String result = getText(rootElement, "Result");
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
if (rootElement.getName().equals("Response")) {//} !StringUtils.isEmpty(result)) {
|
if (rootElement.getName().equals("Response")) {//} !StringUtils.isEmpty(result)) {
|
||||||
// 此处是对本平台发出DeviceControl指令的应答
|
// 此处是对本平台发出DeviceControl指令的应答
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
@ -316,7 +337,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
|
String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
|
||||||
String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
|
String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
|
||||||
// 远程启动功能
|
// 远程启动功能
|
||||||
if (!StringUtils.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) {
|
if (!StringUtils.isEmpty(getText(rootElement, "TeleBoot"))) {
|
||||||
if (deviceId.equals(targetGBId)) {
|
if (deviceId.equals(targetGBId)) {
|
||||||
// 远程启动本平台:需要在重新启动程序后先对SipStack解绑
|
// 远程启动本平台:需要在重新启动程序后先对SipStack解绑
|
||||||
logger.info("执行远程启动本平台命令");
|
logger.info("执行远程启动本平台命令");
|
||||||
@ -354,8 +375,8 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 云台/前端控制命令
|
// 云台/前端控制命令
|
||||||
if (!StringUtils.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) {
|
if (!StringUtils.isEmpty(getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) {
|
||||||
String cmdString = XmlUtil.getText(rootElement,"PTZCmd");
|
String cmdString = getText(rootElement,"PTZCmd");
|
||||||
Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId);
|
Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId);
|
||||||
cmder.fronEndCmd(deviceForPlatform, deviceId, cmdString);
|
cmder.fronEndCmd(deviceForPlatform, deviceId, cmdString);
|
||||||
}
|
}
|
||||||
@ -377,13 +398,13 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理DeviceConfig设备状态Message消息时未找到设备信息");
|
logger.warn("处理DeviceConfig设备状态Message消息时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String channelId = XmlUtil.getText(rootElement, "DeviceID");
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
if (rootElement.getName().equals("Response")) {
|
if (rootElement.getName().equals("Response")) {
|
||||||
// 此处是对本平台发出DeviceControl指令的应答
|
// 此处是对本平台发出DeviceControl指令的应答
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
@ -416,14 +437,14 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理ConfigDownload设备状态Message时未找到设备信息");
|
logger.warn("处理ConfigDownload设备状态Message时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String channelId = XmlUtil.getText(rootElement, "DeviceID");
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + deviceId + channelId;
|
String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + deviceId + channelId;
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
if (rootElement.getName().equals("Response")) {
|
if (rootElement.getName().equals("Response")) {
|
||||||
// 此处是对本平台发出DeviceControl指令的应答
|
// 此处是对本平台发出DeviceControl指令的应答
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
@ -455,14 +476,14 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理PresetQuery预置位列表Message时未找到设备信息");
|
logger.warn("处理PresetQuery预置位列表Message时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String channelId = XmlUtil.getText(rootElement, "DeviceID");
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId + channelId;
|
String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + deviceId + channelId;
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
if (rootElement.getName().equals("Response")) {// !StringUtils.isEmpty(result)) {
|
if (rootElement.getName().equals("Response")) {// !StringUtils.isEmpty(result)) {
|
||||||
// 此处是对本平台发出DeviceControl指令的应答
|
// 此处是对本平台发出DeviceControl指令的应答
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
@ -506,11 +527,11 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
logger.info("接收到DeviceInfo查询消息");
|
logger.info("接收到DeviceInfo查询消息");
|
||||||
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
String sn = rootElement.element("SN").getText();
|
String sn = rootElement.element("SN").getText();
|
||||||
cmderFroPlatform.deviceInfoResponse(parentPlatform, sn, fromHeader.getTag());
|
cmderFroPlatform.deviceInfoResponse(parentPlatform, sn, fromHeader.getTag());
|
||||||
}
|
}
|
||||||
@ -518,15 +539,15 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
logger.debug("接收到DeviceInfo应答消息");
|
logger.debug("接收到DeviceInfo应答消息");
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
|
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
device.setName(XmlUtil.getText(rootElement, "DeviceName"));
|
device.setName(getText(rootElement, "DeviceName"));
|
||||||
|
|
||||||
device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer"));
|
device.setManufacturer(getText(rootElement, "Manufacturer"));
|
||||||
device.setModel(XmlUtil.getText(rootElement, "Model"));
|
device.setModel(getText(rootElement, "Model"));
|
||||||
device.setFirmware(XmlUtil.getText(rootElement, "Firmware"));
|
device.setFirmware(getText(rootElement, "Firmware"));
|
||||||
if (StringUtils.isEmpty(device.getStreamMode())) {
|
if (StringUtils.isEmpty(device.getStreamMode())) {
|
||||||
device.setStreamMode("UDP");
|
device.setStreamMode("UDP");
|
||||||
}
|
}
|
||||||
@ -537,7 +558,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
msg.setData(device);
|
msg.setData(device);
|
||||||
deferredResultHolder.invokeAllResult(msg);
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
if (offLineDetector.isOnline(deviceId)) {
|
if (offLineDetector.isOnline(deviceId)) {
|
||||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||||
}
|
}
|
||||||
@ -571,11 +592,11 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求
|
if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求
|
||||||
// TODO 后续将代码拆分
|
// TODO 后续将代码拆分
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
|
|
||||||
Element snElement = rootElement.element("SN");
|
Element snElement = rootElement.element("SN");
|
||||||
String sn = snElement.getText();
|
String sn = snElement.getText();
|
||||||
@ -604,7 +625,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
deviceChannel.setStatus(gbStream.isStatus()?1:0);
|
deviceChannel.setStatus(gbStream.isStatus()?1:0);
|
||||||
// deviceChannel.setParentId(parentPlatform.getDeviceGBId());
|
// deviceChannel.setParentId(parentPlatform.getDeviceGBId());
|
||||||
deviceChannel.setRegisterWay(1);
|
deviceChannel.setRegisterWay(1);
|
||||||
deviceChannel.setCivilCode(cmder.getSipConfig().getDomain());
|
deviceChannel.setCivilCode(config.getDomain());
|
||||||
deviceChannel.setModel("live");
|
deviceChannel.setModel("live");
|
||||||
deviceChannel.setOwner("wvp-pro");
|
deviceChannel.setOwner("wvp-pro");
|
||||||
// deviceChannel.setAddress("test");
|
// deviceChannel.setAddress("test");
|
||||||
@ -625,7 +646,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
} else {
|
} else {
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("收到catalog设备目录列表请求时未找到设备信息");
|
logger.warn("收到catalog设备目录列表请求时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
deviceListElement = getRootElement(evt, device.getCharset()).element("DeviceList");
|
deviceListElement = getRootElement(evt, device.getCharset()).element("DeviceList");
|
||||||
@ -655,62 +676,62 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
deviceChannel.setStatus(0);
|
deviceChannel.setStatus(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
|
deviceChannel.setManufacture(getText(itemDevice, "Manufacturer"));
|
||||||
deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
|
deviceChannel.setModel(getText(itemDevice, "Model"));
|
||||||
deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
|
deviceChannel.setOwner(getText(itemDevice, "Owner"));
|
||||||
deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
|
deviceChannel.setCivilCode(getText(itemDevice, "CivilCode"));
|
||||||
deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
|
deviceChannel.setBlock(getText(itemDevice, "Block"));
|
||||||
deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
|
deviceChannel.setAddress(getText(itemDevice, "Address"));
|
||||||
if (XmlUtil.getText(itemDevice, "Parental") == null || XmlUtil.getText(itemDevice, "Parental") == "") {
|
if (getText(itemDevice, "Parental") == null || getText(itemDevice, "Parental") == "") {
|
||||||
deviceChannel.setParental(0);
|
deviceChannel.setParental(0);
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));
|
deviceChannel.setParental(Integer.parseInt(getText(itemDevice, "Parental")));
|
||||||
}
|
}
|
||||||
deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));
|
deviceChannel.setParentId(getText(itemDevice, "ParentID"));
|
||||||
if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay") == "") {
|
if (getText(itemDevice, "SafetyWay") == null || getText(itemDevice, "SafetyWay") == "") {
|
||||||
deviceChannel.setSafetyWay(0);
|
deviceChannel.setSafetyWay(0);
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
|
deviceChannel.setSafetyWay(Integer.parseInt(getText(itemDevice, "SafetyWay")));
|
||||||
}
|
}
|
||||||
if (XmlUtil.getText(itemDevice, "RegisterWay") == null || XmlUtil.getText(itemDevice, "RegisterWay") == "") {
|
if (getText(itemDevice, "RegisterWay") == null || getText(itemDevice, "RegisterWay") == "") {
|
||||||
deviceChannel.setRegisterWay(1);
|
deviceChannel.setRegisterWay(1);
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
|
deviceChannel.setRegisterWay(Integer.parseInt(getText(itemDevice, "RegisterWay")));
|
||||||
}
|
}
|
||||||
deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
|
deviceChannel.setCertNum(getText(itemDevice, "CertNum"));
|
||||||
if (XmlUtil.getText(itemDevice, "Certifiable") == null || XmlUtil.getText(itemDevice, "Certifiable") == "") {
|
if (getText(itemDevice, "Certifiable") == null || getText(itemDevice, "Certifiable") == "") {
|
||||||
deviceChannel.setCertifiable(0);
|
deviceChannel.setCertifiable(0);
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
|
deviceChannel.setCertifiable(Integer.parseInt(getText(itemDevice, "Certifiable")));
|
||||||
}
|
}
|
||||||
if (XmlUtil.getText(itemDevice, "ErrCode") == null || XmlUtil.getText(itemDevice, "ErrCode") == "") {
|
if (getText(itemDevice, "ErrCode") == null || getText(itemDevice, "ErrCode") == "") {
|
||||||
deviceChannel.setErrCode(0);
|
deviceChannel.setErrCode(0);
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
|
deviceChannel.setErrCode(Integer.parseInt(getText(itemDevice, "ErrCode")));
|
||||||
}
|
}
|
||||||
deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
|
deviceChannel.setEndTime(getText(itemDevice, "EndTime"));
|
||||||
deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
|
deviceChannel.setSecrecy(getText(itemDevice, "Secrecy"));
|
||||||
deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
|
deviceChannel.setIpAddress(getText(itemDevice, "IPAddress"));
|
||||||
if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") {
|
if (getText(itemDevice, "Port") == null || getText(itemDevice, "Port") == "") {
|
||||||
deviceChannel.setPort(0);
|
deviceChannel.setPort(0);
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
|
deviceChannel.setPort(Integer.parseInt(getText(itemDevice, "Port")));
|
||||||
}
|
}
|
||||||
deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
|
deviceChannel.setPassword(getText(itemDevice, "Password"));
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) {
|
if (NumericUtil.isDouble(getText(itemDevice, "Longitude"))) {
|
||||||
deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
|
deviceChannel.setLongitude(Double.parseDouble(getText(itemDevice, "Longitude")));
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setLongitude(0.00);
|
deviceChannel.setLongitude(0.00);
|
||||||
}
|
}
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) {
|
if (NumericUtil.isDouble(getText(itemDevice, "Latitude"))) {
|
||||||
deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
|
deviceChannel.setLatitude(Double.parseDouble(getText(itemDevice, "Latitude")));
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setLatitude(0.00);
|
deviceChannel.setLatitude(0.00);
|
||||||
}
|
}
|
||||||
if (XmlUtil.getText(itemDevice, "PTZType") == null || XmlUtil.getText(itemDevice, "PTZType") == "") {
|
if (getText(itemDevice, "PTZType") == null || getText(itemDevice, "PTZType") == "") {
|
||||||
deviceChannel.setPTZType(0);
|
deviceChannel.setPTZType(0);
|
||||||
} else {
|
} else {
|
||||||
deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
|
deviceChannel.setPTZType(Integer.parseInt(getText(itemDevice, "PTZType")));
|
||||||
}
|
}
|
||||||
deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
|
deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
|
||||||
storager.updateChannel(device.getDeviceId(), deviceChannel);
|
storager.updateChannel(device.getDeviceId(), deviceChannel);
|
||||||
@ -721,7 +742,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
msg.setData(device);
|
msg.setData(device);
|
||||||
deferredResultHolder.invokeAllResult(msg);
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
if (offLineDetector.isOnline(deviceId)) {
|
if (offLineDetector.isOnline(deviceId)) {
|
||||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||||
}
|
}
|
||||||
@ -743,7 +764,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理alarm设备报警信息未找到设备信息");
|
logger.warn("处理alarm设备报警信息未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Element rootElement = getRootElement(evt, device.getCharset());
|
Element rootElement = getRootElement(evt, device.getCharset());
|
||||||
@ -751,7 +772,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
String channelId = deviceIdElement.getText().toString();
|
String channelId = deviceIdElement.getText().toString();
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId + channelId;
|
String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId + channelId;
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
|
|
||||||
if (device.getCharset() != null) {
|
if (device.getCharset() != null) {
|
||||||
rootElement = getRootElement(evt, device.getCharset());
|
rootElement = getRootElement(evt, device.getCharset());
|
||||||
@ -761,21 +782,21 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
DeviceAlarm deviceAlarm = new DeviceAlarm();
|
DeviceAlarm deviceAlarm = new DeviceAlarm();
|
||||||
deviceAlarm.setDeviceId(deviceId);
|
deviceAlarm.setDeviceId(deviceId);
|
||||||
deviceAlarm.setChannelId(channelId);
|
deviceAlarm.setChannelId(channelId);
|
||||||
deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
|
deviceAlarm.setAlarmPriority(getText(rootElement, "AlarmPriority"));
|
||||||
deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
|
deviceAlarm.setAlarmMethod(getText(rootElement, "AlarmMethod"));
|
||||||
deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
|
deviceAlarm.setAlarmTime(getText(rootElement, "AlarmTime"));
|
||||||
if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
|
if (getText(rootElement, "AlarmDescription") == null) {
|
||||||
deviceAlarm.setAlarmDescription("");
|
deviceAlarm.setAlarmDescription("");
|
||||||
} else {
|
} else {
|
||||||
deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
|
deviceAlarm.setAlarmDescription(getText(rootElement, "AlarmDescription"));
|
||||||
}
|
}
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Longitude"))) {
|
if (NumericUtil.isDouble(getText(rootElement, "Longitude"))) {
|
||||||
deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
|
deviceAlarm.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
|
||||||
} else {
|
} else {
|
||||||
deviceAlarm.setLongitude(0.00);
|
deviceAlarm.setLongitude(0.00);
|
||||||
}
|
}
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Latitude"))) {
|
if (NumericUtil.isDouble(getText(rootElement, "Latitude"))) {
|
||||||
deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
|
deviceAlarm.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
|
||||||
} else {
|
} else {
|
||||||
deviceAlarm.setLatitude(0.00);
|
deviceAlarm.setLatitude(0.00);
|
||||||
}
|
}
|
||||||
@ -836,12 +857,12 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
|
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String channelId = XmlUtil.getText(rootElement, "DeviceID");
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
|
|
||||||
// 检查设备是否存在并在线, 不在线则设置为在线
|
// 检查设备是否存在并在线, 不在线则设置为在线
|
||||||
if (device != null ) {
|
if (device != null ) {
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
||||||
}else{
|
}else{
|
||||||
logger.warn("收到[ "+deviceId+" ]心跳信息, 但是设备不存在, 回复404");
|
logger.warn("收到[ "+deviceId+" ]心跳信息, 但是设备不存在, 回复404");
|
||||||
@ -884,12 +905,12 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
|
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||||
RecordInfo recordInfo = new RecordInfo();
|
RecordInfo recordInfo = new RecordInfo();
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
@ -901,13 +922,13 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
}
|
}
|
||||||
recordInfo.setDeviceId(deviceId);
|
recordInfo.setDeviceId(deviceId);
|
||||||
recordInfo.setChannelId(channelId);
|
recordInfo.setChannelId(channelId);
|
||||||
recordInfo.setName(XmlUtil.getText(rootElement, "Name"));
|
recordInfo.setName(getText(rootElement, "Name"));
|
||||||
if (XmlUtil.getText(rootElement, "SumNum")== null || XmlUtil.getText(rootElement, "SumNum") =="") {
|
if (getText(rootElement, "SumNum")== null || getText(rootElement, "SumNum") =="") {
|
||||||
recordInfo.setSumNum(0);
|
recordInfo.setSumNum(0);
|
||||||
} else {
|
} else {
|
||||||
recordInfo.setSumNum(Integer.parseInt(XmlUtil.getText(rootElement, "SumNum")));
|
recordInfo.setSumNum(Integer.parseInt(getText(rootElement, "SumNum")));
|
||||||
}
|
}
|
||||||
String sn = XmlUtil.getText(rootElement, "SN");
|
String sn = getText(rootElement, "SN");
|
||||||
Element recordListElement = rootElement.element("RecordList");
|
Element recordListElement = rootElement.element("RecordList");
|
||||||
if (recordListElement == null || recordInfo.getSumNum() == 0) {
|
if (recordListElement == null || recordInfo.getSumNum() == 0) {
|
||||||
logger.info("无录像数据");
|
logger.info("无录像数据");
|
||||||
@ -930,18 +951,18 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
record = new RecordItem();
|
record = new RecordItem();
|
||||||
record.setDeviceId(XmlUtil.getText(itemRecord, "DeviceID"));
|
record.setDeviceId(getText(itemRecord, "DeviceID"));
|
||||||
record.setName(XmlUtil.getText(itemRecord, "Name"));
|
record.setName(getText(itemRecord, "Name"));
|
||||||
record.setFilePath(XmlUtil.getText(itemRecord, "FilePath"));
|
record.setFilePath(getText(itemRecord, "FilePath"));
|
||||||
record.setAddress(XmlUtil.getText(itemRecord, "Address"));
|
record.setAddress(getText(itemRecord, "Address"));
|
||||||
record.setStartTime(
|
record.setStartTime(
|
||||||
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(XmlUtil.getText(itemRecord, "StartTime")));
|
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(getText(itemRecord, "StartTime")));
|
||||||
record.setEndTime(
|
record.setEndTime(
|
||||||
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(XmlUtil.getText(itemRecord, "EndTime")));
|
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(getText(itemRecord, "EndTime")));
|
||||||
record.setSecrecy(itemRecord.element("Secrecy") == null ? 0
|
record.setSecrecy(itemRecord.element("Secrecy") == null ? 0
|
||||||
: Integer.parseInt(XmlUtil.getText(itemRecord, "Secrecy")));
|
: Integer.parseInt(getText(itemRecord, "Secrecy")));
|
||||||
record.setType(XmlUtil.getText(itemRecord, "Type"));
|
record.setType(getText(itemRecord, "Type"));
|
||||||
record.setRecorderId(XmlUtil.getText(itemRecord, "RecorderID"));
|
record.setRecorderId(getText(itemRecord, "RecorderID"));
|
||||||
recordList.add(record);
|
recordList.add(record);
|
||||||
}
|
}
|
||||||
recordInfo.setRecordList(recordList);
|
recordInfo.setRecordList(recordList);
|
||||||
@ -1019,15 +1040,15 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
|
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String channelId = XmlUtil.getText(rootElement, "DeviceID");
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
String NotifyType =XmlUtil.getText(rootElement, "NotifyType");
|
String NotifyType =getText(rootElement, "NotifyType");
|
||||||
if (NotifyType.equals("121")){
|
if (NotifyType.equals("121")){
|
||||||
logger.info("媒体播放完毕,通知关流");
|
logger.info("媒体播放完毕,通知关流");
|
||||||
StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, "*");
|
StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, "*");
|
||||||
@ -1054,15 +1075,15 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
|
logger.warn("处理DeviceInfo设备信息Message时未找到设备信息");
|
||||||
response404Ack(evt);
|
responseAck(evt, Response.NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
String channelId = XmlUtil.getText(rootElement, "DeviceID");
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId + channelId;
|
String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId + channelId;
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
responseAck(evt);
|
responseAck(evt, Response.OK);
|
||||||
if (rootElement.getName().equals("Response")) {
|
if (rootElement.getName().equals("Response")) {
|
||||||
// 此处是对本平台发出Broadcast指令的应答
|
// 此处是对本平台发出Broadcast指令的应答
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
@ -1081,97 +1102,4 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***
|
|
||||||
* 回复200 OK
|
|
||||||
* @param evt
|
|
||||||
* @throws SipException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws ParseException
|
|
||||||
*/
|
|
||||||
private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
|
|
||||||
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
|
|
||||||
ServerTransaction serverTransaction = getServerTransaction(evt);
|
|
||||||
serverTransaction.sendResponse(response);
|
|
||||||
if (serverTransaction.getDialog() != null) {
|
|
||||||
serverTransaction.getDialog().delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
* 回复404
|
|
||||||
* @param evt
|
|
||||||
* @throws SipException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws ParseException
|
|
||||||
*/
|
|
||||||
private void response404Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
|
|
||||||
Response response = getMessageFactory().createResponse(Response.NOT_FOUND, evt.getRequest());
|
|
||||||
ServerTransaction serverTransaction = getServerTransaction(evt);
|
|
||||||
serverTransaction.sendResponse(response);
|
|
||||||
if (serverTransaction.getDialog() != null) {
|
|
||||||
serverTransaction.getDialog().delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Element getRootElement(RequestEvent evt) throws DocumentException {
|
|
||||||
|
|
||||||
return getRootElement(evt, "gb2312");
|
|
||||||
}
|
|
||||||
|
|
||||||
private Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
|
|
||||||
if (charset == null) {
|
|
||||||
charset = "gb2312";
|
|
||||||
}
|
|
||||||
Request request = evt.getRequest();
|
|
||||||
SAXReader reader = new SAXReader();
|
|
||||||
reader.setEncoding(charset);
|
|
||||||
Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
|
|
||||||
return xml.getRootElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCmder(SIPCommander cmder) {
|
|
||||||
this.cmder = cmder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStorager(IVideoManagerStorager storager) {
|
|
||||||
this.storager = storager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPublisher(EventPublisher publisher) {
|
|
||||||
this.publisher = publisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedis(RedisUtil redis) {
|
|
||||||
this.redis = redis;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) {
|
|
||||||
this.deferredResultHolder = deferredResultHolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOffLineDetector(DeviceOffLineDetector offLineDetector) {
|
|
||||||
this.offLineDetector = offLineDetector;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IRedisCatchStorage getRedisCatchStorage() {
|
|
||||||
return redisCatchStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
|
|
||||||
this.redisCatchStorage = redisCatchStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SIPCommanderFroPlatform getCmderFroPlatform() {
|
|
||||||
return cmderFroPlatform;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) {
|
|
||||||
this.cmderFroPlatform = cmderFroPlatform;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeviceAlarmService(IDeviceAlarmService deviceAlarmService) {
|
|
||||||
this.deviceAlarmService = deviceAlarmService;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,67 +1,78 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import javax.sip.InvalidArgumentException;
|
|
||||||
import javax.sip.RequestEvent;
|
|
||||||
import javax.sip.ServerTransaction;
|
|
||||||
import javax.sip.SipException;
|
|
||||||
import javax.sip.message.Request;
|
|
||||||
import javax.sip.message.Response;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetup;
|
import com.genersoft.iot.vmp.conf.UserSetup;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
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.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
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.utils.NumericUtil;
|
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
||||||
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
import com.genersoft.iot.vmp.utils.GpsUtil;
|
import com.genersoft.iot.vmp.utils.GpsUtil;
|
||||||
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
|
|
||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
|
||||||
import org.dom4j.DocumentException;
|
import org.dom4j.DocumentException;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
import org.dom4j.io.SAXReader;
|
|
||||||
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.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: Notify请求处理器
|
* @description: Notify请求处理器
|
||||||
* @author: lawrencehj
|
* @author: lawrencehj
|
||||||
* @date: 2021年1月27日
|
* @date: 2021年1月27日
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
|
public class NotifyRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|
||||||
|
|
||||||
private UserSetup userSetup = (UserSetup) SpringBeanFactory.getBean("userSetup");
|
private final static Logger logger = LoggerFactory.getLogger(NotifyRequestProcessor.class);
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
|
@Autowired
|
||||||
|
private UserSetup userSetup;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IVideoManagerStorager storager;
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private EventPublisher publisher;
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private DeviceOffLineDetector offLineDetector;
|
private DeviceOffLineDetector offLineDetector;
|
||||||
|
|
||||||
private static final String NOTIFY_CATALOG = "Catalog";
|
private static final String NOTIFY_CATALOG = "Catalog";
|
||||||
private static final String NOTIFY_ALARM = "Alarm";
|
private static final String NOTIFY_ALARM = "Alarm";
|
||||||
private static final String NOTIFY_MOBILE_POSITION = "MobilePosition";
|
private static final String NOTIFY_MOBILE_POSITION = "MobilePosition";
|
||||||
|
private String method = "NOTIFY";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(RequestEvent evt) {
|
public void process(RequestEvent evt) {
|
||||||
@ -80,7 +91,7 @@ public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
processNotifyMobilePosition(evt);
|
processNotifyMobilePosition(evt);
|
||||||
} else {
|
} else {
|
||||||
logger.info("接收到消息:" + cmd);
|
logger.info("接收到消息:" + cmd);
|
||||||
response200Ok(evt);
|
responseAck(evt, Response.OK);
|
||||||
}
|
}
|
||||||
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -135,7 +146,7 @@ public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
storager.clearMobilePositionsByDeviceId(deviceId);
|
storager.clearMobilePositionsByDeviceId(deviceId);
|
||||||
}
|
}
|
||||||
storager.insertMobilePosition(mobilePosition);
|
storager.insertMobilePosition(mobilePosition);
|
||||||
response200Ok(evt);
|
responseAck(evt, Response.OK);
|
||||||
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -199,7 +210,7 @@ public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
// TODO: 需要实现存储报警信息、报警分类
|
// TODO: 需要实现存储报警信息、报警分类
|
||||||
|
|
||||||
// 回复200 OK
|
// 回复200 OK
|
||||||
response200Ok(evt);
|
responseAck(evt, Response.OK);
|
||||||
if (offLineDetector.isOnline(deviceId)) {
|
if (offLineDetector.isOnline(deviceId)) {
|
||||||
publisher.deviceAlarmEventPublish(deviceAlarm);
|
publisher.deviceAlarmEventPublish(deviceAlarm);
|
||||||
}
|
}
|
||||||
@ -215,10 +226,16 @@ public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
*/
|
*/
|
||||||
private void processNotifyCatalogList(RequestEvent evt) {
|
private void processNotifyCatalogList(RequestEvent evt) {
|
||||||
try {
|
try {
|
||||||
|
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||||
|
String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader);
|
||||||
|
|
||||||
Element rootElement = getRootElement(evt);
|
Element rootElement = getRootElement(evt);
|
||||||
Element deviceIdElement = rootElement.element("DeviceID");
|
Element deviceIdElement = rootElement.element("DeviceID");
|
||||||
String deviceId = deviceIdElement.getText();
|
String channelId = deviceIdElement.getText();
|
||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = storager.queryVideoDevice(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (device != null ) {
|
if (device != null ) {
|
||||||
rootElement = getRootElement(evt, device.getCharset());
|
rootElement = getRootElement(evt, device.getCharset());
|
||||||
}
|
}
|
||||||
@ -228,9 +245,7 @@ public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
}
|
}
|
||||||
Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
|
Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
|
||||||
if (deviceListIterator != null) {
|
if (deviceListIterator != null) {
|
||||||
if (device == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 遍历DeviceList
|
// 遍历DeviceList
|
||||||
while (deviceListIterator.hasNext()) {
|
while (deviceListIterator.hasNext()) {
|
||||||
Element itemDevice = deviceListIterator.next();
|
Element itemDevice = deviceListIterator.next();
|
||||||
@ -238,87 +253,52 @@ public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
if (channelDeviceElement == null) {
|
if (channelDeviceElement == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String channelDeviceId = channelDeviceElement.getTextTrim();
|
Element eventElement = itemDevice.element("Event");
|
||||||
Element channdelNameElement = itemDevice.element("Name");
|
switch (eventElement.getText().toUpperCase()) {
|
||||||
String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
|
case "ON" : // 上线
|
||||||
Element statusElement = itemDevice.element("Status");
|
logger.info("收到来自设备【{}】的通道上线【{}】通知", device.getDeviceId(), channelId);
|
||||||
String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON";
|
storager.deviceChannelOnline(deviceId, channelId);
|
||||||
DeviceChannel deviceChannel = new DeviceChannel();
|
// 回复200 OK
|
||||||
deviceChannel.setName(channelName);
|
responseAck(evt, Response.OK);
|
||||||
deviceChannel.setChannelId(channelDeviceId);
|
break;
|
||||||
// ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
|
case "OFF" : // 离线
|
||||||
if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) {
|
logger.info("收到来自设备【{}】的通道离线【{}】通知", device.getDeviceId(), channelId);
|
||||||
deviceChannel.setStatus(1);
|
storager.deviceChannelOffline(deviceId, channelId);
|
||||||
}
|
// 回复200 OK
|
||||||
if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
|
responseAck(evt, Response.OK);
|
||||||
deviceChannel.setStatus(0);
|
break;
|
||||||
|
case "VLOST" : // 视频丢失
|
||||||
|
logger.info("收到来自设备【{}】的通道视频丢失【{}】通知", device.getDeviceId(), channelId);
|
||||||
|
storager.deviceChannelOffline(deviceId, channelId);
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
break;
|
||||||
|
case "DEFECT" : // 故障
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
break;
|
||||||
|
case "ADD" : // 增加
|
||||||
|
logger.info("收到来自设备【{}】的增加通道【{}】通知", device.getDeviceId(), channelId);
|
||||||
|
DeviceChannel deviceChannel = channelContentHander(itemDevice, channelId);
|
||||||
|
storager.updateChannel(deviceId, deviceChannel);
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
break;
|
||||||
|
case "DEL" : // 删除
|
||||||
|
logger.info("收到来自设备【{}】的删除通道【{}】通知", device.getDeviceId(), channelId);
|
||||||
|
storager.delChannel(deviceId, channelId);
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
break;
|
||||||
|
case "UPDATE" : // 更新
|
||||||
|
logger.info("收到来自设备【{}】的更新通道【{}】通知", device.getDeviceId(), channelId);
|
||||||
|
DeviceChannel channel = channelContentHander(itemDevice, channelId);
|
||||||
|
storager.updateChannel(deviceId, channel);
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
responseAck(evt, Response.BAD_REQUEST, "event not found");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
|
|
||||||
deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
|
|
||||||
deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
|
|
||||||
deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
|
|
||||||
deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
|
|
||||||
deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
|
|
||||||
if (XmlUtil.getText(itemDevice, "Parental") == null
|
|
||||||
|| XmlUtil.getText(itemDevice, "Parental") == "") {
|
|
||||||
deviceChannel.setParental(0);
|
|
||||||
} else {
|
|
||||||
deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));
|
|
||||||
}
|
|
||||||
deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));
|
|
||||||
if (XmlUtil.getText(itemDevice, "SafetyWay") == null
|
|
||||||
|| XmlUtil.getText(itemDevice, "SafetyWay") == "") {
|
|
||||||
deviceChannel.setSafetyWay(0);
|
|
||||||
} else {
|
|
||||||
deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
|
|
||||||
}
|
|
||||||
if (XmlUtil.getText(itemDevice, "RegisterWay") == null
|
|
||||||
|| XmlUtil.getText(itemDevice, "RegisterWay") == "") {
|
|
||||||
deviceChannel.setRegisterWay(1);
|
|
||||||
} else {
|
|
||||||
deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
|
|
||||||
}
|
|
||||||
deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
|
|
||||||
if (XmlUtil.getText(itemDevice, "Certifiable") == null
|
|
||||||
|| XmlUtil.getText(itemDevice, "Certifiable") == "") {
|
|
||||||
deviceChannel.setCertifiable(0);
|
|
||||||
} else {
|
|
||||||
deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
|
|
||||||
}
|
|
||||||
if (XmlUtil.getText(itemDevice, "ErrCode") == null
|
|
||||||
|| XmlUtil.getText(itemDevice, "ErrCode") == "") {
|
|
||||||
deviceChannel.setErrCode(0);
|
|
||||||
} else {
|
|
||||||
deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
|
|
||||||
}
|
|
||||||
deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
|
|
||||||
deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
|
|
||||||
deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
|
|
||||||
if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") {
|
|
||||||
deviceChannel.setPort(0);
|
|
||||||
} else {
|
|
||||||
deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
|
|
||||||
}
|
|
||||||
deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
|
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) {
|
|
||||||
deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
|
|
||||||
} else {
|
|
||||||
deviceChannel.setLongitude(0.00);
|
|
||||||
}
|
|
||||||
if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) {
|
|
||||||
deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
|
|
||||||
} else {
|
|
||||||
deviceChannel.setLatitude(0.00);
|
|
||||||
}
|
|
||||||
if (XmlUtil.getText(itemDevice, "PTZType") == null
|
|
||||||
|| XmlUtil.getText(itemDevice, "PTZType") == "") {
|
|
||||||
deviceChannel.setPTZType(0);
|
|
||||||
} else {
|
|
||||||
deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
|
|
||||||
}
|
|
||||||
deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
|
|
||||||
storager.updateChannel(device.getDeviceId(), deviceChannel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestMessage msg = new RequestMessage();
|
// RequestMessage msg = new RequestMessage();
|
||||||
@ -326,8 +306,7 @@ public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
// msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
|
// msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
|
||||||
// msg.setData(device);
|
// msg.setData(device);
|
||||||
// deferredResultHolder.invokeResult(msg);
|
// deferredResultHolder.invokeResult(msg);
|
||||||
// 回复200 OK
|
|
||||||
response200Ok(evt);
|
|
||||||
if (offLineDetector.isOnline(deviceId)) {
|
if (offLineDetector.isOnline(deviceId)) {
|
||||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||||
}
|
}
|
||||||
@ -337,32 +316,91 @@ public class NotifyRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
public DeviceChannel channelContentHander(Element itemDevice, String channelId){
|
||||||
* 回复200 OK
|
Element channdelNameElement = itemDevice.element("Name");
|
||||||
*
|
String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
|
||||||
* @param evt
|
Element statusElement = itemDevice.element("Status");
|
||||||
* @throws SipException
|
String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON";
|
||||||
* @throws InvalidArgumentException
|
DeviceChannel deviceChannel = new DeviceChannel();
|
||||||
* @throws ParseException
|
deviceChannel.setName(channelName);
|
||||||
*/
|
deviceChannel.setChannelId(channelId);
|
||||||
private void response200Ok(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
|
// ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
|
||||||
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
|
if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) {
|
||||||
ServerTransaction serverTransaction = getServerTransaction(evt);
|
deviceChannel.setStatus(1);
|
||||||
serverTransaction.sendResponse(response);
|
}
|
||||||
if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
|
if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
|
||||||
}
|
deviceChannel.setStatus(0);
|
||||||
private Element getRootElement(RequestEvent evt) throws DocumentException {
|
}
|
||||||
return getRootElement(evt, "gb2312");
|
|
||||||
}
|
deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
|
||||||
private Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
|
deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
|
||||||
if (charset == null) charset = "gb2312";
|
deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
|
||||||
Request request = evt.getRequest();
|
deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
|
||||||
SAXReader reader = new SAXReader();
|
deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
|
||||||
reader.setEncoding(charset);
|
deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
|
||||||
Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
|
if (XmlUtil.getText(itemDevice, "Parental") == null
|
||||||
return xml.getRootElement();
|
|| XmlUtil.getText(itemDevice, "Parental") == "") {
|
||||||
|
deviceChannel.setParental(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));
|
||||||
|
}
|
||||||
|
deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));
|
||||||
|
if (XmlUtil.getText(itemDevice, "SafetyWay") == null
|
||||||
|
|| XmlUtil.getText(itemDevice, "SafetyWay") == "") {
|
||||||
|
deviceChannel.setSafetyWay(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
|
||||||
|
}
|
||||||
|
if (XmlUtil.getText(itemDevice, "RegisterWay") == null
|
||||||
|
|| XmlUtil.getText(itemDevice, "RegisterWay") == "") {
|
||||||
|
deviceChannel.setRegisterWay(1);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
|
||||||
|
}
|
||||||
|
deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
|
||||||
|
if (XmlUtil.getText(itemDevice, "Certifiable") == null
|
||||||
|
|| XmlUtil.getText(itemDevice, "Certifiable") == "") {
|
||||||
|
deviceChannel.setCertifiable(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
|
||||||
|
}
|
||||||
|
if (XmlUtil.getText(itemDevice, "ErrCode") == null
|
||||||
|
|| XmlUtil.getText(itemDevice, "ErrCode") == "") {
|
||||||
|
deviceChannel.setErrCode(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
|
||||||
|
}
|
||||||
|
deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
|
||||||
|
deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
|
||||||
|
deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
|
||||||
|
if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") {
|
||||||
|
deviceChannel.setPort(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
|
||||||
|
}
|
||||||
|
deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
|
||||||
|
if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) {
|
||||||
|
deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
|
||||||
|
} else {
|
||||||
|
deviceChannel.setLongitude(0.00);
|
||||||
|
}
|
||||||
|
if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) {
|
||||||
|
deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
|
||||||
|
} else {
|
||||||
|
deviceChannel.setLatitude(0.00);
|
||||||
|
}
|
||||||
|
if (XmlUtil.getText(itemDevice, "PTZType") == null
|
||||||
|
|| XmlUtil.getText(itemDevice, "PTZType") == "") {
|
||||||
|
deviceChannel.setPTZType(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
|
||||||
|
}
|
||||||
|
deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
|
||||||
|
return deviceChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void setCmder(SIPCommander cmder) {
|
public void setCmder(SIPCommander cmder) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,59 +1,73 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import javax.sip.InvalidArgumentException;
|
|
||||||
import javax.sip.RequestEvent;
|
|
||||||
import javax.sip.ServerTransaction;
|
|
||||||
import javax.sip.SipException;
|
|
||||||
import javax.sip.header.AuthorizationHeader;
|
|
||||||
import javax.sip.header.ContactHeader;
|
|
||||||
import javax.sip.header.ExpiresHeader;
|
|
||||||
import javax.sip.header.FromHeader;
|
|
||||||
import javax.sip.header.ViaHeader;
|
|
||||||
import javax.sip.message.Request;
|
|
||||||
import javax.sip.message.Response;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
|
|
||||||
import gov.nist.javax.sip.RequestEventExt;
|
|
||||||
import gov.nist.javax.sip.header.SIPDateHeader;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
|
import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
|
||||||
import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;
|
import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
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.storager.IVideoManagerStorager;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import gov.nist.javax.sip.RequestEventExt;
|
||||||
import gov.nist.javax.sip.address.AddressImpl;
|
import gov.nist.javax.sip.address.AddressImpl;
|
||||||
import gov.nist.javax.sip.address.SipUri;
|
import gov.nist.javax.sip.address.SipUri;
|
||||||
import gov.nist.javax.sip.header.Expires;
|
import gov.nist.javax.sip.header.Expires;
|
||||||
|
import gov.nist.javax.sip.header.SIPDateHeader;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.ServerTransaction;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.header.*;
|
||||||
|
import javax.sip.message.Request;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:收到注册请求 处理
|
* @description:收到注册请求 处理
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月3日 下午4:47:25
|
* @date: 2020年5月3日 下午4:47:25
|
||||||
*/
|
*/
|
||||||
public class RegisterRequestProcessor extends SIPRequestAbstractProcessor {
|
@Component
|
||||||
|
public class RegisterRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class);
|
private Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class);
|
||||||
|
|
||||||
|
public String method = "REGISTER";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private SipConfig sipConfig;
|
private SipConfig sipConfig;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private RegisterLogicHandler handler;
|
private RegisterLogicHandler handler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private IVideoManagerStorager storager;
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private EventPublisher publisher;
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 收到注册请求 处理
|
* 收到注册请求 处理
|
||||||
* @param evt
|
* @param evt
|
||||||
@ -182,20 +196,4 @@ public class RegisterRequestProcessor extends SIPRequestAbstractProcessor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSipConfig(SipConfig sipConfig) {
|
|
||||||
this.sipConfig = sipConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHandler(RegisterLogicHandler handler) {
|
|
||||||
this.handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoManagerStorager(IVideoManagerStorager storager) {
|
|
||||||
this.storager = storager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPublisher(EventPublisher publisher) {
|
|
||||||
this.publisher = publisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,6 +1,13 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.sip.InvalidArgumentException;
|
import javax.sip.InvalidArgumentException;
|
||||||
import javax.sip.RequestEvent;
|
import javax.sip.RequestEvent;
|
||||||
@ -9,19 +16,27 @@ import javax.sip.SipException;
|
|||||||
import javax.sip.header.ExpiresHeader;
|
import javax.sip.header.ExpiresHeader;
|
||||||
import javax.sip.message.Request;
|
import javax.sip.message.Request;
|
||||||
import javax.sip.message.Response;
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:SUBSCRIBE请求处理器
|
* @description:SUBSCRIBE请求处理器
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月3日 下午5:31:20
|
* @date: 2020年5月3日 下午5:31:20
|
||||||
*/
|
*/
|
||||||
public class SubscribeRequestProcessor extends SIPRequestAbstractProcessor {
|
@Component
|
||||||
|
public class SubscribeRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(SubscribeRequestProcessor.class);
|
private Logger logger = LoggerFactory.getLogger(SubscribeRequestProcessor.class);
|
||||||
|
private String method = "SUBSCRIBE";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理SUBSCRIBE请求
|
* 处理SUBSCRIBE请求
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
|
||||||
|
public interface IMessageHandler {
|
||||||
|
/**
|
||||||
|
* 处理来自设备的信息
|
||||||
|
* @param evt
|
||||||
|
* @param device
|
||||||
|
*/
|
||||||
|
void handForDevice(RequestEvent evt, Device device, Element element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理来自平台的信息
|
||||||
|
* @param evt
|
||||||
|
* @param parentPlatform
|
||||||
|
*/
|
||||||
|
void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element);
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
public abstract class MessageHandlerAbstract extends SIPRequestProcessorParent implements IMessageHandler{
|
||||||
|
|
||||||
|
public static Map<String, IMessageHandler> messageHandlerMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public MessageRequestProcessor messageRequestProcessor;
|
||||||
|
|
||||||
|
public void addHandler(String cmdType, IMessageHandler messageHandler) {
|
||||||
|
messageHandlerMap.put(cmdType, messageHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
String cmd = getText(element, "CmdType");
|
||||||
|
IMessageHandler messageHandler = messageHandlerMap.get(cmd);
|
||||||
|
if (messageHandler != null) {
|
||||||
|
messageHandler.handForDevice(evt, device, element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
String cmd = getText(element, "CmdType");
|
||||||
|
IMessageHandler messageHandler = messageHandlerMap.get(cmd);
|
||||||
|
if (messageHandler != null) {
|
||||||
|
messageHandler.handForPlatform(evt, parentPlatform, element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
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.utils.SipUtils;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MessageRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
|
||||||
|
|
||||||
|
private final String method = "MESSAGE";
|
||||||
|
|
||||||
|
private static Map<String, IMessageHandler> messageHandlerMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addRequestProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHandler(String name, IMessageHandler handler) {
|
||||||
|
messageHandlerMap.put(name, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(RequestEvent evt) {
|
||||||
|
logger.debug("接收到消息:" + evt.getRequest());
|
||||||
|
String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
|
||||||
|
// 查询设备是否存在
|
||||||
|
Device device = storage.queryVideoDevice(deviceId);
|
||||||
|
// 查询上级平台是否存在
|
||||||
|
ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(deviceId);
|
||||||
|
try {
|
||||||
|
if (device == null && parentPlatform == null) {
|
||||||
|
// 不存在则回复404
|
||||||
|
responseAck(evt, Response.NOT_FOUND, "device id not found");
|
||||||
|
}else {
|
||||||
|
Element rootElement = getRootElement(evt);
|
||||||
|
String name = rootElement.getName();
|
||||||
|
IMessageHandler messageHandler = messageHandlerMap.get(name);
|
||||||
|
if (messageHandler != null) {
|
||||||
|
if (device != null) {
|
||||||
|
messageHandler.handForDevice(evt, device, rootElement);
|
||||||
|
}else { // 由于上面已经判断都为null则直接返回,所以这里device和parentPlatform必有一个不为null
|
||||||
|
messageHandler.handForPlatform(evt, parentPlatform, rootElement);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
// 不支持的message
|
||||||
|
// 不存在则回复415
|
||||||
|
responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE, "Unsupported message type, must Control/Notify/Query/Response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SipException e) {
|
||||||
|
logger.warn("SIP 回复错误", e);
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
logger.warn("参数无效", e);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
logger.warn("SIP回复时解析异常", e);
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
logger.warn("解析XML消息内容异常", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.control;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.MessageHandlerAbstract;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.MessageRequestProcessor;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ControlMessageHandler extends MessageHandlerAbstract implements InitializingBean {
|
||||||
|
|
||||||
|
private final String messageType = "Control";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageRequestProcessor messageRequestProcessor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
messageRequestProcessor.addHandler(messageType, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.MessageHandlerAbstract;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class NotifyMessageHandler extends MessageHandlerAbstract implements InitializingBean {
|
||||||
|
|
||||||
|
private final String messageType = "Notify";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
messageRequestProcessor.addHandler(messageType, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.UserSetup;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||||
|
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import com.genersoft.iot.vmp.utils.GpsUtil;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class);
|
||||||
|
private final String cmdType = "Alarm";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NotifyMessageHandler notifyMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserSetup userSetup;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceAlarmService deviceAlarmService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceOffLineDetector offLineDetector;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
notifyMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
Element deviceIdElement = rootElement.element("DeviceID");
|
||||||
|
String channelId = deviceIdElement.getText().toString();
|
||||||
|
DeviceAlarm deviceAlarm = new DeviceAlarm();
|
||||||
|
deviceAlarm.setDeviceId(device.getDeviceId());
|
||||||
|
deviceAlarm.setChannelId(channelId);
|
||||||
|
deviceAlarm.setAlarmPriority(getText(rootElement, "AlarmPriority"));
|
||||||
|
deviceAlarm.setAlarmMethod(getText(rootElement, "AlarmMethod"));
|
||||||
|
deviceAlarm.setAlarmTime(getText(rootElement, "AlarmTime"));
|
||||||
|
if (getText(rootElement, "AlarmDescription") == null) {
|
||||||
|
deviceAlarm.setAlarmDescription("");
|
||||||
|
} else {
|
||||||
|
deviceAlarm.setAlarmDescription(getText(rootElement, "AlarmDescription"));
|
||||||
|
}
|
||||||
|
if (NumericUtil.isDouble(getText(rootElement, "Longitude"))) {
|
||||||
|
deviceAlarm.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
|
||||||
|
} else {
|
||||||
|
deviceAlarm.setLongitude(0.00);
|
||||||
|
}
|
||||||
|
if (NumericUtil.isDouble(getText(rootElement, "Latitude"))) {
|
||||||
|
deviceAlarm.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
|
||||||
|
} else {
|
||||||
|
deviceAlarm.setLatitude(0.00);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
|
||||||
|
if ( deviceAlarm.getAlarmMethod().equals("4")) {
|
||||||
|
MobilePosition mobilePosition = new MobilePosition();
|
||||||
|
mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
|
||||||
|
mobilePosition.setTime(deviceAlarm.getAlarmTime());
|
||||||
|
mobilePosition.setLongitude(deviceAlarm.getLongitude());
|
||||||
|
mobilePosition.setLatitude(deviceAlarm.getLatitude());
|
||||||
|
mobilePosition.setReportSource("GPS Alarm");
|
||||||
|
BaiduPoint bp = new BaiduPoint();
|
||||||
|
bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
|
||||||
|
logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
|
||||||
|
mobilePosition.setGeodeticSystem("BD-09");
|
||||||
|
mobilePosition.setCnLng(bp.getBdLng());
|
||||||
|
mobilePosition.setCnLat(bp.getBdLat());
|
||||||
|
if (!userSetup.getSavePositionHistory()) {
|
||||||
|
storager.clearMobilePositionsByDeviceId(device.getDeviceId());
|
||||||
|
}
|
||||||
|
storager.insertMobilePosition(mobilePosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.debug("存储报警信息、报警分类");
|
||||||
|
// 存储报警信息、报警分类
|
||||||
|
deviceAlarmService.add(deviceAlarm);
|
||||||
|
|
||||||
|
if (offLineDetector.isOnline(device.getDeviceId())) {
|
||||||
|
publisher.deviceAlarmEventPublish(deviceAlarm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(CatalogNotifyMessageHandler.class);
|
||||||
|
private final String cmdType = "Catalog";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NotifyMessageHandler notifyMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
notifyMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + parentPlatform.getServerGBId();
|
||||||
|
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||||
|
try {
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
Element snElement = rootElement.element("SN");
|
||||||
|
String sn = snElement.getText();
|
||||||
|
// 准备回复通道信息
|
||||||
|
List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
|
||||||
|
// 查询关联的直播通道
|
||||||
|
List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
|
||||||
|
int size = channelReduces.size() + gbStreams.size();
|
||||||
|
// 回复级联的通道
|
||||||
|
if (channelReduces.size() > 0) {
|
||||||
|
for (ChannelReduce channelReduce : channelReduces) {
|
||||||
|
DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
|
||||||
|
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 回复直播的通道
|
||||||
|
if (gbStreams.size() > 0) {
|
||||||
|
for (GbStream gbStream : gbStreams) {
|
||||||
|
DeviceChannel deviceChannel = new DeviceChannel();
|
||||||
|
deviceChannel.setChannelId(gbStream.getGbId());
|
||||||
|
deviceChannel.setName(gbStream.getName());
|
||||||
|
deviceChannel.setLongitude(gbStream.getLongitude());
|
||||||
|
deviceChannel.setLatitude(gbStream.getLatitude());
|
||||||
|
deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
|
||||||
|
deviceChannel.setManufacture("wvp-pro");
|
||||||
|
deviceChannel.setStatus(gbStream.isStatus()?1:0);
|
||||||
|
// deviceChannel.setParentId(parentPlatform.getDeviceGBId());
|
||||||
|
deviceChannel.setRegisterWay(1);
|
||||||
|
deviceChannel.setCivilCode(config.getDomain());
|
||||||
|
deviceChannel.setModel("live");
|
||||||
|
deviceChannel.setOwner("wvp-pro");
|
||||||
|
deviceChannel.setParental(0);
|
||||||
|
deviceChannel.setSecrecy("0");
|
||||||
|
deviceChannel.setSecrecy("0");
|
||||||
|
|
||||||
|
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size == 0) {
|
||||||
|
// 回复无通道
|
||||||
|
cmderFroPlatform.catalogQuery(null, parentPlatform, sn, fromHeader.getTag(), size);
|
||||||
|
}
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class);
|
||||||
|
private final String cmdType = "Keepalive";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NotifyMessageHandler notifyMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
notifyMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
// 检查设备是否存在并在线, 不在线则设置为在线
|
||||||
|
try {
|
||||||
|
if (device != null ) {
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
||||||
|
}
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
// 不会收到上级平台的心跳信息
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
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.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(MediaStatusNotifyMessageHandler.class);
|
||||||
|
private final String cmdType = "MediaStatus";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NotifyMessageHandler notifyMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommander cmder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
notifyMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
|
||||||
|
// 回复200 OK
|
||||||
|
try {
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String NotifyType =getText(rootElement, "NotifyType");
|
||||||
|
if (NotifyType.equals("121")){
|
||||||
|
logger.info("媒体播放完毕,通知关流");
|
||||||
|
StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), "*");
|
||||||
|
if (streamInfo != null) {
|
||||||
|
redisCatchStorage.stopPlayback(streamInfo);
|
||||||
|
cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.UserSetup;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import com.genersoft.iot.vmp.utils.GpsUtil;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(MobilePositionNotifyMessageHandler.class);
|
||||||
|
private final String cmdType = "MobilePosition";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NotifyMessageHandler notifyMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserSetup userSetup;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
notifyMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
rootElement = getRootElement(evt, device.getCharset());
|
||||||
|
|
||||||
|
MobilePosition mobilePosition = new MobilePosition();
|
||||||
|
if (!StringUtils.isEmpty(device.getName())) {
|
||||||
|
mobilePosition.setDeviceName(device.getName());
|
||||||
|
}
|
||||||
|
mobilePosition.setDeviceId(device.getDeviceId());
|
||||||
|
mobilePosition.setChannelId(getText(rootElement, "DeviceID"));
|
||||||
|
mobilePosition.setTime(getText(rootElement, "Time"));
|
||||||
|
mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
|
||||||
|
mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
|
||||||
|
if (NumericUtil.isDouble(getText(rootElement, "Speed"))) {
|
||||||
|
mobilePosition.setSpeed(Double.parseDouble(getText(rootElement, "Speed")));
|
||||||
|
} else {
|
||||||
|
mobilePosition.setSpeed(0.0);
|
||||||
|
}
|
||||||
|
if (NumericUtil.isDouble(getText(rootElement, "Direction"))) {
|
||||||
|
mobilePosition.setDirection(Double.parseDouble(getText(rootElement, "Direction")));
|
||||||
|
} else {
|
||||||
|
mobilePosition.setDirection(0.0);
|
||||||
|
}
|
||||||
|
if (NumericUtil.isDouble(getText(rootElement, "Altitude"))) {
|
||||||
|
mobilePosition.setAltitude(Double.parseDouble(getText(rootElement, "Altitude")));
|
||||||
|
} else {
|
||||||
|
mobilePosition.setAltitude(0.0);
|
||||||
|
}
|
||||||
|
mobilePosition.setReportSource("Mobile Position");
|
||||||
|
BaiduPoint bp = new BaiduPoint();
|
||||||
|
bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
|
||||||
|
logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
|
||||||
|
mobilePosition.setGeodeticSystem("BD-09");
|
||||||
|
mobilePosition.setCnLng(bp.getBdLng());
|
||||||
|
mobilePosition.setCnLat(bp.getBdLat());
|
||||||
|
if (!userSetup.getSavePositionHistory()) {
|
||||||
|
storager.clearMobilePositionsByDeviceId(device.getDeviceId());
|
||||||
|
}
|
||||||
|
storager.insertMobilePosition(mobilePosition);
|
||||||
|
//回复 200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.MessageHandlerAbstract;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.MessageRequestProcessor;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class QueryMessageHandler extends MessageHandlerAbstract implements InitializingBean {
|
||||||
|
|
||||||
|
private final String messageType = "Query";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageRequestProcessor messageRequestProcessor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
messageRequestProcessor.addHandler(messageType, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.QueryMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(CatalogQueryMessageHandler.class);
|
||||||
|
private final String cmdType = "Catalog";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QueryMessageHandler queryMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
queryMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + parentPlatform.getServerGBId();
|
||||||
|
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||||
|
try {
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
Element snElement = rootElement.element("SN");
|
||||||
|
String sn = snElement.getText();
|
||||||
|
// 准备回复通道信息
|
||||||
|
List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
|
||||||
|
// 查询关联的直播通道
|
||||||
|
List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
|
||||||
|
int size = channelReduces.size() + gbStreams.size();
|
||||||
|
// 回复级联的通道
|
||||||
|
if (channelReduces.size() > 0) {
|
||||||
|
for (ChannelReduce channelReduce : channelReduces) {
|
||||||
|
DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
|
||||||
|
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 回复直播的通道
|
||||||
|
if (gbStreams.size() > 0) {
|
||||||
|
for (GbStream gbStream : gbStreams) {
|
||||||
|
DeviceChannel deviceChannel = new DeviceChannel();
|
||||||
|
deviceChannel.setChannelId(gbStream.getGbId());
|
||||||
|
deviceChannel.setName(gbStream.getName());
|
||||||
|
deviceChannel.setLongitude(gbStream.getLongitude());
|
||||||
|
deviceChannel.setLatitude(gbStream.getLatitude());
|
||||||
|
deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
|
||||||
|
deviceChannel.setManufacture("wvp-pro");
|
||||||
|
deviceChannel.setStatus(gbStream.isStatus()?1:0);
|
||||||
|
// deviceChannel.setParentId(parentPlatform.getDeviceGBId());
|
||||||
|
deviceChannel.setRegisterWay(1);
|
||||||
|
deviceChannel.setCivilCode(config.getDomain());
|
||||||
|
deviceChannel.setModel("live");
|
||||||
|
deviceChannel.setOwner("wvp-pro");
|
||||||
|
deviceChannel.setParental(0);
|
||||||
|
deviceChannel.setSecrecy("0");
|
||||||
|
deviceChannel.setSecrecy("0");
|
||||||
|
|
||||||
|
cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size == 0) {
|
||||||
|
// 回复无通道
|
||||||
|
cmderFroPlatform.catalogQuery(null, parentPlatform, sn, fromHeader.getTag(), size);
|
||||||
|
}
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.VManageBootstrap;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.QueryMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
|
||||||
|
import gov.nist.javax.sip.SipStackImpl;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.ListeningPoint;
|
||||||
|
import javax.sip.ObjectInUseException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipProvider;
|
||||||
|
import javax.sip.address.SipURI;
|
||||||
|
import javax.sip.header.HeaderAddress;
|
||||||
|
import javax.sip.header.ToHeader;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(DeviceControlQueryMessageHandler.class);
|
||||||
|
private final String cmdType = "DeviceControl";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QueryMessageHandler queryMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommander cmder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
queryMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
|
||||||
|
// 此处是上级发出的DeviceControl指令
|
||||||
|
String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
|
||||||
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
|
// 远程启动功能
|
||||||
|
if (!StringUtils.isEmpty(getText(rootElement, "TeleBoot"))) {
|
||||||
|
if (parentPlatform.getServerGBId().equals(targetGBId)) {
|
||||||
|
// 远程启动本平台:需要在重新启动程序后先对SipStack解绑
|
||||||
|
logger.info("执行远程启动本平台命令");
|
||||||
|
cmderFroPlatform.unregister(parentPlatform, null, null);
|
||||||
|
|
||||||
|
Thread restartThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(3000);
|
||||||
|
SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
|
||||||
|
SipStackImpl stack = (SipStackImpl)up.getSipStack();
|
||||||
|
stack.stop();
|
||||||
|
Iterator listener = stack.getListeningPoints();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
restartThread.setDaemon(false);
|
||||||
|
restartThread.start();
|
||||||
|
} else {
|
||||||
|
// 远程启动指定设备
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 云台/前端控制命令
|
||||||
|
if (!StringUtils.isEmpty(getText(rootElement,"PTZCmd")) && !parentPlatform.getServerGBId().equals(targetGBId)) {
|
||||||
|
String cmdString = getText(rootElement,"PTZCmd");
|
||||||
|
Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId);
|
||||||
|
cmder.fronEndCmd(deviceForPlatform, channelId, cmdString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.QueryMessageHandler;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(DeviceInfoQueryMessageHandler.class);
|
||||||
|
private final String cmdType = "DeviceInfo";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QueryMessageHandler queryMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
queryMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
logger.info("接收到DeviceInfo查询消息");
|
||||||
|
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||||
|
try {
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String sn = rootElement.element("SN").getText();
|
||||||
|
cmderFroPlatform.deviceInfoResponse(parentPlatform, sn, fromHeader.getTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.QueryMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.header.FromHeader;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(DeviceStatusQueryMessageHandler.class);
|
||||||
|
private final String cmdType = "DeviceStatus";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QueryMessageHandler queryMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
queryMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
|
||||||
|
logger.info("接收到DeviceStatus查询消息");
|
||||||
|
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||||
|
// 回复200 OK
|
||||||
|
try {
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String sn = rootElement.element("SN").getText();
|
||||||
|
cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.MessageHandlerAbstract;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.MessageRequestProcessor;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ResponseMessageHandler extends MessageHandlerAbstract implements InitializingBean {
|
||||||
|
|
||||||
|
private final String messageType = "Response";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageRequestProcessor messageRequestProcessor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
messageRequestProcessor.addHandler(messageType, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AlarmResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(AlarmResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "Alarm";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
Element deviceIdElement = rootElement.element("DeviceID");
|
||||||
|
String channelId = deviceIdElement.getText().toString();
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_ALARM + device.getDeviceId() + channelId;
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
XmlUtil.node2Json(rootElement, json);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(json.toJSONString());
|
||||||
|
}
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
msg.setKey(key);
|
||||||
|
msg.setData(json);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(BroadcastResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "Broadcast";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
try {
|
||||||
|
String channelId = getText(rootElement, "DeviceID");
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + device.getDeviceId() + channelId;
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
// 此处是对本平台发出Broadcast指令的应答
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
XmlUtil.node2Json(rootElement, json);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(json.toJSONString());
|
||||||
|
}
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
msg.setKey(key);
|
||||||
|
msg.setData(json);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (ParseException | SipException | InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CatalogResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(CatalogResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "Catalog";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceOffLineDetector offLineDetector;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + device.getDeviceId();
|
||||||
|
Element rootElement = null;
|
||||||
|
try {
|
||||||
|
rootElement = getRootElement(evt, device.getCharset());
|
||||||
|
Element deviceListElement = rootElement.element("DeviceList");
|
||||||
|
Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
|
||||||
|
if (deviceListIterator != null) {
|
||||||
|
|
||||||
|
// 遍历DeviceList
|
||||||
|
while (deviceListIterator.hasNext()) {
|
||||||
|
Element itemDevice = deviceListIterator.next();
|
||||||
|
Element channelDeviceElement = itemDevice.element("DeviceID");
|
||||||
|
if (channelDeviceElement == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String channelDeviceId = channelDeviceElement.getText();
|
||||||
|
Element channdelNameElement = itemDevice.element("Name");
|
||||||
|
String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
|
||||||
|
Element statusElement = itemDevice.element("Status");
|
||||||
|
String status = statusElement != null ? statusElement.getText().toString() : "ON";
|
||||||
|
DeviceChannel deviceChannel = new DeviceChannel();
|
||||||
|
deviceChannel.setName(channelName);
|
||||||
|
deviceChannel.setChannelId(channelDeviceId);
|
||||||
|
// ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
|
||||||
|
if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) {
|
||||||
|
deviceChannel.setStatus(1);
|
||||||
|
}
|
||||||
|
if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
|
||||||
|
deviceChannel.setStatus(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceChannel.setManufacture(getText(itemDevice, "Manufacturer"));
|
||||||
|
deviceChannel.setModel(getText(itemDevice, "Model"));
|
||||||
|
deviceChannel.setOwner(getText(itemDevice, "Owner"));
|
||||||
|
deviceChannel.setCivilCode(getText(itemDevice, "CivilCode"));
|
||||||
|
deviceChannel.setBlock(getText(itemDevice, "Block"));
|
||||||
|
deviceChannel.setAddress(getText(itemDevice, "Address"));
|
||||||
|
if (getText(itemDevice, "Parental") == null || getText(itemDevice, "Parental") == "") {
|
||||||
|
deviceChannel.setParental(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setParental(Integer.parseInt(getText(itemDevice, "Parental")));
|
||||||
|
}
|
||||||
|
deviceChannel.setParentId(getText(itemDevice, "ParentID"));
|
||||||
|
if (getText(itemDevice, "SafetyWay") == null || getText(itemDevice, "SafetyWay") == "") {
|
||||||
|
deviceChannel.setSafetyWay(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setSafetyWay(Integer.parseInt(getText(itemDevice, "SafetyWay")));
|
||||||
|
}
|
||||||
|
if (getText(itemDevice, "RegisterWay") == null || getText(itemDevice, "RegisterWay") == "") {
|
||||||
|
deviceChannel.setRegisterWay(1);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setRegisterWay(Integer.parseInt(getText(itemDevice, "RegisterWay")));
|
||||||
|
}
|
||||||
|
deviceChannel.setCertNum(getText(itemDevice, "CertNum"));
|
||||||
|
if (getText(itemDevice, "Certifiable") == null || getText(itemDevice, "Certifiable") == "") {
|
||||||
|
deviceChannel.setCertifiable(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setCertifiable(Integer.parseInt(getText(itemDevice, "Certifiable")));
|
||||||
|
}
|
||||||
|
if (getText(itemDevice, "ErrCode") == null || getText(itemDevice, "ErrCode") == "") {
|
||||||
|
deviceChannel.setErrCode(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setErrCode(Integer.parseInt(getText(itemDevice, "ErrCode")));
|
||||||
|
}
|
||||||
|
deviceChannel.setEndTime(getText(itemDevice, "EndTime"));
|
||||||
|
deviceChannel.setSecrecy(getText(itemDevice, "Secrecy"));
|
||||||
|
deviceChannel.setIpAddress(getText(itemDevice, "IPAddress"));
|
||||||
|
if (getText(itemDevice, "Port") == null || getText(itemDevice, "Port") == "") {
|
||||||
|
deviceChannel.setPort(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setPort(Integer.parseInt(getText(itemDevice, "Port")));
|
||||||
|
}
|
||||||
|
deviceChannel.setPassword(getText(itemDevice, "Password"));
|
||||||
|
if (NumericUtil.isDouble(getText(itemDevice, "Longitude"))) {
|
||||||
|
deviceChannel.setLongitude(Double.parseDouble(getText(itemDevice, "Longitude")));
|
||||||
|
} else {
|
||||||
|
deviceChannel.setLongitude(0.00);
|
||||||
|
}
|
||||||
|
if (NumericUtil.isDouble(getText(itemDevice, "Latitude"))) {
|
||||||
|
deviceChannel.setLatitude(Double.parseDouble(getText(itemDevice, "Latitude")));
|
||||||
|
} else {
|
||||||
|
deviceChannel.setLatitude(0.00);
|
||||||
|
}
|
||||||
|
if (getText(itemDevice, "PTZType") == null || getText(itemDevice, "PTZType") == "") {
|
||||||
|
deviceChannel.setPTZType(0);
|
||||||
|
} else {
|
||||||
|
deviceChannel.setPTZType(Integer.parseInt(getText(itemDevice, "PTZType")));
|
||||||
|
}
|
||||||
|
deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
|
||||||
|
storager.updateChannel(device.getDeviceId(), deviceChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
msg.setKey(key);
|
||||||
|
msg.setData(device);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
if (offLineDetector.isOnline(device.getDeviceId())) {
|
||||||
|
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ConfigDownloadResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(ConfigDownloadResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "ConfigDownload";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
String channelId = getText(element, "DeviceID");
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + device.getDeviceId() + channelId;
|
||||||
|
try {
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
// 此处是对本平台发出DeviceControl指令的应答
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
XmlUtil.node2Json(element, json);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(json.toJSONString());
|
||||||
|
}
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
msg.setKey(key);
|
||||||
|
msg.setData(json);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
// 不会收到上级平台的心跳信息
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DeviceConfigResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(DeviceConfigResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "DeviceConfig";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
XmlUtil.node2Json(element, json);
|
||||||
|
String channelId = getText(element, "DeviceID");
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(json.toJSONString());
|
||||||
|
}
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + device.getDeviceId() + channelId;
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
msg.setKey(key);
|
||||||
|
msg.setData(json);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DeviceControlResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(DeviceControlResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "DeviceControl";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
// 此处是对本平台发出DeviceControl指令的应答
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
String channelId = getText(element, "DeviceID");
|
||||||
|
XmlUtil.node2Json(element, json);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(json.toJSONString());
|
||||||
|
}
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + device.getDeviceId() + channelId;
|
||||||
|
msg.setKey(key);
|
||||||
|
msg.setData(json);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(DeviceInfoResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "DeviceInfo";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceOffLineDetector offLineDetector;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
logger.debug("接收到DeviceInfo应答消息");
|
||||||
|
try {
|
||||||
|
rootElement = getRootElement(evt, device.getCharset());
|
||||||
|
Element deviceIdElement = rootElement.element("DeviceID");
|
||||||
|
String channelId = deviceIdElement.getTextTrim();
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_DEVICEINFO + device.getDeviceId() + channelId;
|
||||||
|
device.setName(getText(rootElement, "DeviceName"));
|
||||||
|
|
||||||
|
device.setManufacturer(getText(rootElement, "Manufacturer"));
|
||||||
|
device.setModel(getText(rootElement, "Model"));
|
||||||
|
device.setFirmware(getText(rootElement, "Firmware"));
|
||||||
|
if (StringUtils.isEmpty(device.getStreamMode())) {
|
||||||
|
device.setStreamMode("UDP");
|
||||||
|
}
|
||||||
|
storager.updateDevice(device);
|
||||||
|
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
msg.setKey(key);
|
||||||
|
msg.setData(device);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
// 回复200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
if (offLineDetector.isOnline(device.getDeviceId())) {
|
||||||
|
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||||
|
}
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(DeviceStatusResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "DeviceStatus";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceOffLineDetector offLineDetector;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventPublisher publisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||||
|
logger.info("接收到DeviceStatus应答消息");
|
||||||
|
// 检查设备是否存在, 不存在则不回复
|
||||||
|
// 回复200 OK
|
||||||
|
try {
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Element deviceIdElement = element.element("DeviceID");
|
||||||
|
String channelId = deviceIdElement.getText();
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
XmlUtil.node2Json(element, json);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(json.toJSONString());
|
||||||
|
}
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
msg.setKey(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + device.getDeviceId() + channelId);
|
||||||
|
msg.setData(json);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
|
||||||
|
if (offLineDetector.isOnline(device.getDeviceId())) {
|
||||||
|
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.UserSetup;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.BaiduPoint;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
|
import com.genersoft.iot.vmp.utils.GpsUtil;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MobilePositionResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(MobilePositionResponseMessageHandler.class);
|
||||||
|
private final String cmdType = "MobilePosition";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserSetup userSetup;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVideoManagerStorager storager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
rootElement = getRootElement(evt, device.getCharset());
|
||||||
|
|
||||||
|
MobilePosition mobilePosition = new MobilePosition();
|
||||||
|
if (!StringUtils.isEmpty(device.getName())) {
|
||||||
|
mobilePosition.setDeviceName(device.getName());
|
||||||
|
}
|
||||||
|
mobilePosition.setDeviceId(device.getDeviceId());
|
||||||
|
mobilePosition.setChannelId(getText(rootElement, "DeviceID"));
|
||||||
|
mobilePosition.setTime(getText(rootElement, "Time"));
|
||||||
|
mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude")));
|
||||||
|
mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude")));
|
||||||
|
if (NumericUtil.isDouble(getText(rootElement, "Speed"))) {
|
||||||
|
mobilePosition.setSpeed(Double.parseDouble(getText(rootElement, "Speed")));
|
||||||
|
} else {
|
||||||
|
mobilePosition.setSpeed(0.0);
|
||||||
|
}
|
||||||
|
if (NumericUtil.isDouble(getText(rootElement, "Direction"))) {
|
||||||
|
mobilePosition.setDirection(Double.parseDouble(getText(rootElement, "Direction")));
|
||||||
|
} else {
|
||||||
|
mobilePosition.setDirection(0.0);
|
||||||
|
}
|
||||||
|
if (NumericUtil.isDouble(getText(rootElement, "Altitude"))) {
|
||||||
|
mobilePosition.setAltitude(Double.parseDouble(getText(rootElement, "Altitude")));
|
||||||
|
} else {
|
||||||
|
mobilePosition.setAltitude(0.0);
|
||||||
|
}
|
||||||
|
mobilePosition.setReportSource("Mobile Position");
|
||||||
|
BaiduPoint bp = new BaiduPoint();
|
||||||
|
bp = GpsUtil.Wgs84ToBd09(String.valueOf(mobilePosition.getLongitude()), String.valueOf(mobilePosition.getLatitude()));
|
||||||
|
logger.info("百度坐标:" + bp.getBdLng() + ", " + bp.getBdLat());
|
||||||
|
mobilePosition.setGeodeticSystem("BD-09");
|
||||||
|
mobilePosition.setCnLng(bp.getBdLng());
|
||||||
|
mobilePosition.setCnLat(bp.getBdLat());
|
||||||
|
if (!userSetup.getSavePositionHistory()) {
|
||||||
|
storager.clearMobilePositionsByDeviceId(device.getDeviceId());
|
||||||
|
}
|
||||||
|
storager.insertMobilePosition(mobilePosition);
|
||||||
|
//回复 200 OK
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,153 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.CheckForAllRecordsThread;
|
||||||
|
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.event.request.SIPRequestProcessorParent;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
||||||
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.InvalidArgumentException;
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(RecordInfoResponseMessageHandler.class);
|
||||||
|
public static volatile List<String> threadNameList = new ArrayList();
|
||||||
|
private final String cmdType = "RecordInfo";
|
||||||
|
private final static String CACHE_RECORDINFO_KEY = "CACHE_RECORDINFO_";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ResponseMessageHandler responseMessageHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisUtil redis;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeferredResultHolder deferredResultHolder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
responseMessageHandler.addHandler(cmdType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||||
|
|
||||||
|
// 回复200 OK
|
||||||
|
try {
|
||||||
|
responseAck(evt, Response.OK);
|
||||||
|
|
||||||
|
rootElement = getRootElement(evt, device.getCharset());
|
||||||
|
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
RecordInfo recordInfo = new RecordInfo();
|
||||||
|
Element deviceIdElement = rootElement.element("DeviceID");
|
||||||
|
String channelId = deviceIdElement.getText();
|
||||||
|
String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + device.getDeviceId() + channelId;
|
||||||
|
recordInfo.setDeviceId(device.getDeviceId());
|
||||||
|
recordInfo.setChannelId(channelId);
|
||||||
|
recordInfo.setName(getText(rootElement, "Name"));
|
||||||
|
if (getText(rootElement, "SumNum") == null || getText(rootElement, "SumNum") == "") {
|
||||||
|
recordInfo.setSumNum(0);
|
||||||
|
} else {
|
||||||
|
recordInfo.setSumNum(Integer.parseInt(getText(rootElement, "SumNum")));
|
||||||
|
}
|
||||||
|
String sn = getText(rootElement, "SN");
|
||||||
|
Element recordListElement = rootElement.element("RecordList");
|
||||||
|
if (recordListElement == null || recordInfo.getSumNum() == 0) {
|
||||||
|
logger.info("无录像数据");
|
||||||
|
RequestMessage msg = new RequestMessage();
|
||||||
|
msg.setKey(key);
|
||||||
|
msg.setData(recordInfo);
|
||||||
|
deferredResultHolder.invokeAllResult(msg);
|
||||||
|
} else {
|
||||||
|
Iterator<Element> recordListIterator = recordListElement.elementIterator();
|
||||||
|
List<RecordItem> recordList = new ArrayList<RecordItem>();
|
||||||
|
if (recordListIterator != null) {
|
||||||
|
RecordItem record = new RecordItem();
|
||||||
|
logger.info("处理录像列表数据...");
|
||||||
|
// 遍历DeviceList
|
||||||
|
while (recordListIterator.hasNext()) {
|
||||||
|
Element itemRecord = recordListIterator.next();
|
||||||
|
Element recordElement = itemRecord.element("DeviceID");
|
||||||
|
if (recordElement == null) {
|
||||||
|
logger.info("记录为空,下一个...");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
record = new RecordItem();
|
||||||
|
record.setDeviceId(getText(itemRecord, "DeviceID"));
|
||||||
|
record.setName(getText(itemRecord, "Name"));
|
||||||
|
record.setFilePath(getText(itemRecord, "FilePath"));
|
||||||
|
record.setAddress(getText(itemRecord, "Address"));
|
||||||
|
record.setStartTime(
|
||||||
|
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(getText(itemRecord, "StartTime")));
|
||||||
|
record.setEndTime(
|
||||||
|
DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(getText(itemRecord, "EndTime")));
|
||||||
|
record.setSecrecy(itemRecord.element("Secrecy") == null ? 0
|
||||||
|
: Integer.parseInt(getText(itemRecord, "Secrecy")));
|
||||||
|
record.setType(getText(itemRecord, "Type"));
|
||||||
|
record.setRecorderId(getText(itemRecord, "RecorderID"));
|
||||||
|
recordList.add(record);
|
||||||
|
}
|
||||||
|
recordInfo.setRecordList(recordList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 改用单独线程统计已获取录像文件数量,避免多包并行分别统计不完整的问题
|
||||||
|
String cacheKey = CACHE_RECORDINFO_KEY + device.getDeviceId() + sn;
|
||||||
|
redis.set(cacheKey + "_" + uuid, recordList, 90);
|
||||||
|
if (!threadNameList.contains(cacheKey)) {
|
||||||
|
threadNameList.add(cacheKey);
|
||||||
|
CheckForAllRecordsThread chk = new CheckForAllRecordsThread(cacheKey, recordInfo);
|
||||||
|
chk.setName(cacheKey);
|
||||||
|
chk.setDeferredResultHolder(deferredResultHolder);
|
||||||
|
chk.setRedis(redis);
|
||||||
|
chk.setLogger(logger);
|
||||||
|
chk.start();
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Start Thread " + cacheKey + ".");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Thread " + cacheKey + " already started.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SipException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.response;
|
||||||
|
|
||||||
|
import javax.sip.ResponseEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:处理接收IPCamera发来的SIP协议响应消息
|
||||||
|
* @author: swwheihei
|
||||||
|
* @date: 2020年5月3日 下午4:42:22
|
||||||
|
*/
|
||||||
|
public interface ISIPResponseProcessor {
|
||||||
|
|
||||||
|
void process(ResponseEvent evt);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.response;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
public abstract class SIPResponseProcessorAbstract implements InitializingBean, ISIPResponseProcessor {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.ResponseEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: BYE请求响应器
|
||||||
|
* @author: swwheihei
|
||||||
|
* @date: 2020年5月3日 下午5:32:05
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ByeResponseProcessor extends SIPResponseProcessorAbstract {
|
||||||
|
|
||||||
|
private String method = "BYE";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipLayer sipLayer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addResponseProcessor(method, this);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 处理BYE响应
|
||||||
|
*
|
||||||
|
* @param evt
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void process(ResponseEvent evt) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
System.out.println("收到bye");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.ResponseEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: CANCEL响应处理器
|
||||||
|
* @author: panlinlin
|
||||||
|
* @date: 2021年11月5日 16:35
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CancelResponseProcessor extends SIPResponseProcessorAbstract {
|
||||||
|
|
||||||
|
private String method = "CANCEL";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipLayer sipLayer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addResponseProcessor(method, this);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 处理CANCEL响应
|
||||||
|
*
|
||||||
|
* @param evt
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void process(ResponseEvent evt) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,14 +1,10 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
|
|
||||||
import javax.sip.*;
|
|
||||||
import javax.sip.address.SipURI;
|
|
||||||
import javax.sip.header.CSeqHeader;
|
|
||||||
import javax.sip.message.Request;
|
|
||||||
import javax.sip.message.Response;
|
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||||
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.event.response.SIPResponseProcessorAbstract;
|
||||||
import gov.nist.javax.sip.ResponseEventExt;
|
import gov.nist.javax.sip.ResponseEventExt;
|
||||||
import gov.nist.javax.sip.stack.SIPDialog;
|
import gov.nist.javax.sip.stack.SIPDialog;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -16,20 +12,42 @@ 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 com.genersoft.iot.vmp.conf.SipConfig;
|
import javax.sip.InvalidArgumentException;
|
||||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
import javax.sip.ResponseEvent;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
import javax.sip.SipException;
|
||||||
|
import javax.sip.address.SipURI;
|
||||||
|
import javax.sip.header.CSeqHeader;
|
||||||
|
import javax.sip.message.Request;
|
||||||
|
import javax.sip.message.Response;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:处理INVITE响应
|
* @description: 处理INVITE响应
|
||||||
* @author: swwheihei
|
* @author: panlinlin
|
||||||
* @date: 2020年5月3日 下午4:43:52
|
* @date: 2021年11月5日 16:40
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class InviteResponseProcessor implements ISIPResponseProcessor {
|
public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class);
|
private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class);
|
||||||
|
private String method = "INVITE";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipLayer sipLayer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipConfig config;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addResponseProcessor(method, this);
|
||||||
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private VideoStreamSessionManager streamSession;
|
private VideoStreamSessionManager streamSession;
|
||||||
@ -41,7 +59,7 @@ public class InviteResponseProcessor implements ISIPResponseProcessor {
|
|||||||
* @throws ParseException
|
* @throws ParseException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException {
|
public void process(ResponseEvent evt ){
|
||||||
try {
|
try {
|
||||||
Response response = evt.getResponse();
|
Response response = evt.getResponse();
|
||||||
int statusCode = response.getStatusCode();
|
int statusCode = response.getStatusCode();
|
||||||
@ -56,7 +74,11 @@ public class InviteResponseProcessor implements ISIPResponseProcessor {
|
|||||||
CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
|
CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
|
||||||
Request reqAck = dialog.createAck(cseq.getSeqNumber());
|
Request reqAck = dialog.createAck(cseq.getSeqNumber());
|
||||||
SipURI requestURI = (SipURI) reqAck.getRequestURI();
|
SipURI requestURI = (SipURI) reqAck.getRequestURI();
|
||||||
requestURI.setHost(event.getRemoteIpAddress());
|
try {
|
||||||
|
requestURI.setHost(event.getRemoteIpAddress());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
requestURI.setPort(event.getRemotePort());
|
requestURI.setPort(event.getRemotePort());
|
||||||
reqAck.setRequestURI(requestURI);
|
reqAck.setRequestURI(requestURI);
|
||||||
logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack");
|
logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack");
|
||||||
@ -1,11 +1,10 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
|
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -19,14 +18,15 @@ import javax.sip.header.WWWAuthenticateHeader;
|
|||||||
import javax.sip.message.Response;
|
import javax.sip.message.Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:Register响应处理器
|
* @description:Register响应处理器
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月3日 下午5:32:23
|
* @date: 2020年5月3日 下午5:32:23
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class RegisterResponseProcessor implements ISIPResponseProcessor {
|
public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(RegisterResponseProcessor.class);
|
private Logger logger = LoggerFactory.getLogger(RegisterResponseProcessor.class);
|
||||||
|
private String method = "REGISTER";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISIPCommanderForPlatform sipCommanderForPlatform;
|
private ISIPCommanderForPlatform sipCommanderForPlatform;
|
||||||
@ -37,18 +37,22 @@ public class RegisterResponseProcessor implements ISIPResponseProcessor {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
public RegisterResponseProcessor() {
|
@Autowired
|
||||||
|
private SIPProcessorObserver sipProcessorObserver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
// 添加消息处理的订阅
|
||||||
|
sipProcessorObserver.addResponseProcessor(method, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理Register响应
|
* 处理Register响应
|
||||||
*
|
*
|
||||||
* @param evt
|
* @param evt 事件
|
||||||
* @param layer
|
|
||||||
* @param config
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
|
public void process(ResponseEvent evt) {
|
||||||
Response response = evt.getResponse();
|
Response response = evt.getResponse();
|
||||||
CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
|
CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
|
||||||
String callId = callIdHeader.getCallId();
|
String callId = callIdHeader.getCallId();
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.timeout;
|
||||||
|
|
||||||
|
import javax.sip.TimeoutEvent;
|
||||||
|
|
||||||
|
public interface ITimeoutProcessor {
|
||||||
|
void process(TimeoutEvent event);
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.transmit.event.timeout.impl;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sip.TimeoutEvent;
|
||||||
|
import javax.sip.header.CallIdHeader;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class TimeoutProcessorImpl implements InitializingBean, ITimeoutProcessor {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SIPProcessorObserver processorObserver;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SipSubscribe sipSubscribe;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
processorObserver.addTimeoutProcessor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(TimeoutEvent event) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
CallIdHeader callIdHeader = event.getClientTransaction().getDialog().getCallId();
|
||||||
|
String callId = callIdHeader.getCallId();
|
||||||
|
SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
|
||||||
|
SipSubscribe.EventResult<TimeoutEvent> timeoutEventEventResult = new SipSubscribe.EventResult<>(event);
|
||||||
|
errorSubscribe.response(timeoutEventEventResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,12 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description:处理接收IPCamera发来的SIP协议请求消息
|
|
||||||
* @author: swwheihei
|
|
||||||
* @date: 2020年5月3日 下午4:42:22
|
|
||||||
*/
|
|
||||||
public interface ISIPRequestProcessor {
|
|
||||||
|
|
||||||
public void process();
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request;
|
|
||||||
|
|
||||||
import javax.sip.PeerUnavailableException;
|
|
||||||
import javax.sip.RequestEvent;
|
|
||||||
import javax.sip.ServerTransaction;
|
|
||||||
import javax.sip.SipFactory;
|
|
||||||
import javax.sip.SipProvider;
|
|
||||||
import javax.sip.TransactionAlreadyExistsException;
|
|
||||||
import javax.sip.TransactionUnavailableException;
|
|
||||||
import javax.sip.address.AddressFactory;
|
|
||||||
import javax.sip.header.HeaderFactory;
|
|
||||||
import javax.sip.header.ViaHeader;
|
|
||||||
import javax.sip.message.MessageFactory;
|
|
||||||
import javax.sip.message.Request;
|
|
||||||
|
|
||||||
import gov.nist.javax.sip.SipStackImpl;
|
|
||||||
import gov.nist.javax.sip.message.SIPRequest;
|
|
||||||
import gov.nist.javax.sip.stack.SIPServerTransaction;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description:处理接收IPCamera发来的SIP协议请求消息
|
|
||||||
* @author: songww
|
|
||||||
* @date: 2020年5月3日 下午4:42:22
|
|
||||||
*/
|
|
||||||
public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcessor {
|
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(SIPRequestAbstractProcessor.class);
|
|
||||||
|
|
||||||
protected RequestEvent evt;
|
|
||||||
|
|
||||||
private SipProvider tcpSipProvider;
|
|
||||||
|
|
||||||
private SipProvider udpSipProvider;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void process() {
|
|
||||||
this.process(evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void process(RequestEvent evt);
|
|
||||||
|
|
||||||
public ServerTransaction getServerTransaction(RequestEvent evt) {
|
|
||||||
Request request = evt.getRequest();
|
|
||||||
ServerTransaction serverTransaction = evt.getServerTransaction();
|
|
||||||
// 判断TCP还是UDP
|
|
||||||
boolean isTcp = false;
|
|
||||||
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
|
||||||
String transport = reqViaHeader.getTransport();
|
|
||||||
if (transport.equals("TCP")) {
|
|
||||||
isTcp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverTransaction == null) {
|
|
||||||
try {
|
|
||||||
if (isTcp) {
|
|
||||||
SipStackImpl stack = (SipStackImpl)tcpSipProvider.getSipStack();
|
|
||||||
serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
|
|
||||||
if (serverTransaction == null) {
|
|
||||||
serverTransaction = tcpSipProvider.getNewServerTransaction(request);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SipStackImpl stack = (SipStackImpl)udpSipProvider.getSipStack();
|
|
||||||
serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
|
|
||||||
if (serverTransaction == null) {
|
|
||||||
serverTransaction = udpSipProvider.getNewServerTransaction(request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (TransactionAlreadyExistsException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
} catch (TransactionUnavailableException e) {
|
|
||||||
logger.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return serverTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AddressFactory getAddressFactory() {
|
|
||||||
try {
|
|
||||||
return SipFactory.getInstance().createAddressFactory();
|
|
||||||
} catch (PeerUnavailableException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeaderFactory getHeaderFactory() {
|
|
||||||
try {
|
|
||||||
return SipFactory.getInstance().createHeaderFactory();
|
|
||||||
} catch (PeerUnavailableException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MessageFactory getMessageFactory() {
|
|
||||||
try {
|
|
||||||
return SipFactory.getInstance().createMessageFactory();
|
|
||||||
} catch (PeerUnavailableException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RequestEvent getRequestEvent() {
|
|
||||||
return evt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequestEvent(RequestEvent evt) {
|
|
||||||
this.evt = evt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SipProvider getTcpSipProvider() {
|
|
||||||
return tcpSipProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTcpSipProvider(SipProvider tcpSipProvider) {
|
|
||||||
this.tcpSipProvider = tcpSipProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SipProvider getUdpSipProvider() {
|
|
||||||
return udpSipProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUdpSipProvider(SipProvider udpSipProvider) {
|
|
||||||
this.udpSipProvider = udpSipProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
|
||||||
|
|
||||||
import javax.sip.RequestEvent;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description:CANCEL请求处理器
|
|
||||||
* @author: swwheihei
|
|
||||||
* @date: 2020年5月3日 下午5:32:23
|
|
||||||
*/
|
|
||||||
public class CancelRequestProcessor extends SIPRequestAbstractProcessor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理CANCEL请求
|
|
||||||
*
|
|
||||||
* @param evt
|
|
||||||
* @param layer
|
|
||||||
* @param transaction
|
|
||||||
* @param config
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void process(RequestEvent evt) {
|
|
||||||
// TODO 优先级99 Cancel Request消息实现,此消息一般为级联消息,上级给下级发送请求取消指令
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
|
||||||
|
|
||||||
import javax.sip.RequestEvent;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description:暂不支持的消息请求处理器
|
|
||||||
* @author: swwheihei
|
|
||||||
* @date: 2020年5月3日 下午5:32:59
|
|
||||||
*/
|
|
||||||
public class OtherRequestProcessor extends SIPRequestAbstractProcessor {
|
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(OtherRequestProcessor.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Title: process</p>
|
|
||||||
* <p>Description: </p>
|
|
||||||
* @param evt
|
|
||||||
* @param layer
|
|
||||||
* @param transaction
|
|
||||||
* @param config
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void process(RequestEvent evt) {
|
|
||||||
logger.info("Unsupported the method: " + evt.getRequest().getMethod());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.response;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
|
|
||||||
import javax.sip.ResponseEvent;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description:处理接收IPCamera发来的SIP协议响应消息
|
|
||||||
* @author: swwheihei
|
|
||||||
* @date: 2020年5月3日 下午4:42:22
|
|
||||||
*/
|
|
||||||
public interface ISIPResponseProcessor {
|
|
||||||
|
|
||||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
|
||||||
|
|
||||||
import javax.sip.ResponseEvent;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: BYE请求响应器
|
|
||||||
* @author: swwheihei
|
|
||||||
* @date: 2020年5月3日 下午5:32:05
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class ByeResponseProcessor implements ISIPResponseProcessor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理BYE响应
|
|
||||||
*
|
|
||||||
* @param evt
|
|
||||||
* @param layer
|
|
||||||
* @param config
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
|
||||||
|
|
||||||
import javax.sip.ResponseEvent;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description:CANCEL响应处理器
|
|
||||||
* @author: swwheihei
|
|
||||||
* @date: 2020年5月3日 下午5:32:23
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class CancelResponseProcessor implements ISIPResponseProcessor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理CANCEL响应
|
|
||||||
*
|
|
||||||
* @param evt
|
|
||||||
* @param layer
|
|
||||||
* @param transaction
|
|
||||||
* @param config
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
|
||||||
|
|
||||||
import javax.sip.ResponseEvent;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description:暂不支持的消息响应处理器
|
|
||||||
* @author: swwheihei
|
|
||||||
* @date: 2020年5月3日 下午5:32:59
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class OtherResponseProcessor implements ISIPResponseProcessor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Title: process</p>
|
|
||||||
* <p>Description: </p>
|
|
||||||
* @param evt
|
|
||||||
* @param layer
|
|
||||||
* @param config
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -6,7 +6,7 @@ import java.util.Date;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:时间工具类,主要处理ISO 8601格式转换
|
* @description:时间工具类,主要处理ISO 8601格式转换
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月8日 下午3:24:42
|
* @date: 2020年5月8日 下午3:24:42
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.genersoft.iot.vmp.utils;
|
package com.genersoft.iot.vmp.gb28181.utils;
|
||||||
|
|
||||||
import gov.nist.javax.sip.address.AddressImpl;
|
import gov.nist.javax.sip.address.AddressImpl;
|
||||||
import gov.nist.javax.sip.address.SipUri;
|
import gov.nist.javax.sip.address.SipUri;
|
||||||
@ -9,15 +9,20 @@ import javax.sip.message.Request;
|
|||||||
/**
|
/**
|
||||||
* @author panlinlin
|
* @author panlinlin
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
* @Description JAIN SIP的工具类
|
* @description JAIN SIP的工具类
|
||||||
* @createTime 2021年09月27日 15:12:00
|
* @createTime 2021年09月27日 15:12:00
|
||||||
*/
|
*/
|
||||||
public class SipUtils {
|
public class SipUtils {
|
||||||
|
|
||||||
public static String getUserIdFromFromHeader(Request request) {
|
public static String getUserIdFromFromHeader(Request request) {
|
||||||
FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
|
FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
|
||||||
|
return getUserIdFromFromHeader(fromHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUserIdFromFromHeader(FromHeader fromHeader) {
|
||||||
AddressImpl address = (AddressImpl)fromHeader.getAddress();
|
AddressImpl address = (AddressImpl)fromHeader.getAddress();
|
||||||
SipUri uri = (SipUri) address.getURI();
|
SipUri uri = (SipUri) address.getURI();
|
||||||
return uri.getUser();
|
return uri.getUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,15 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.utils;
|
package com.genersoft.iot.vmp.gb28181.utils;
|
||||||
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
|
||||||
import org.dom4j.Attribute;
|
import org.dom4j.Attribute;
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
import org.dom4j.DocumentException;
|
import org.dom4j.DocumentException;
|
||||||
@ -19,6 +11,12 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.sip.RequestEvent;
|
||||||
|
import javax.sip.message.Request;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于dom4j的工具包
|
* 基于dom4j的工具包
|
||||||
*
|
*
|
||||||
@ -161,4 +159,23 @@ public class XmlUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static Element getRootElement(RequestEvent evt) throws DocumentException {
|
||||||
|
|
||||||
|
return getRootElement(evt, "gb2312");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
|
||||||
|
Request request = evt.getRequest();
|
||||||
|
return getRootElement(request.getRawContent(), charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Element getRootElement(byte[] content, String charset) throws DocumentException {
|
||||||
|
if (charset == null) {
|
||||||
|
charset = "gb2312";
|
||||||
|
}
|
||||||
|
SAXReader reader = new SAXReader();
|
||||||
|
reader.setEncoding(charset);
|
||||||
|
Document xml = reader.read(new ByteArrayInputStream(content));
|
||||||
|
return xml.getRootElement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:针对 ZLMediaServer的hook事件监听
|
* @description:针对 ZLMediaServer的hook事件监听
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月8日 上午10:46:48
|
* @date: 2020年5月8日 上午10:46:48
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import java.util.*;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:针对 ZLMediaServer的hook事件订阅
|
* @description:针对 ZLMediaServer的hook事件订阅
|
||||||
* @author: pan
|
* @author: pan
|
||||||
* @date: 2020年12月2日 21:17:32
|
* @date: 2020年12月2日 21:17:32
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -55,6 +55,9 @@ public class ZLMRESTfulUtils {
|
|||||||
if (responseStr != null) {
|
if (responseStr != null) {
|
||||||
responseJSON = JSON.parseObject(responseStr);
|
responseJSON = JSON.parseObject(responseStr);
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
response.close();
|
||||||
|
Objects.requireNonNull(response.body()).close();
|
||||||
}
|
}
|
||||||
} catch (ConnectException e) {
|
} catch (ConnectException e) {
|
||||||
logger.error(String.format("连接ZLM失败: %s, %s", e.getCause().getMessage(), e.getMessage()));
|
logger.error(String.format("连接ZLM失败: %s, %s", e.getCause().getMessage(), e.getMessage()));
|
||||||
@ -74,6 +77,10 @@ public class ZLMRESTfulUtils {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage()));
|
logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}else {
|
||||||
|
response.close();
|
||||||
|
Objects.requireNonNull(response.body()).close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.genersoft.iot.vmp.service;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备相关业务处理
|
||||||
|
*/
|
||||||
|
public interface IDeviceService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加目录订阅
|
||||||
|
* @param device 设备信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean addCatalogSubscribe(Device device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除目录订阅
|
||||||
|
* @param device 设备信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean removeCatalogSubscribe(Device device);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package com.genersoft.iot.vmp.service.bean;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.sip.ResponseEvent;
|
||||||
|
|
||||||
|
public class CatalogSubscribeTask implements Runnable{
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(CatalogSubscribeTask.class);
|
||||||
|
private Device device;
|
||||||
|
private ISIPCommander sipCommander;
|
||||||
|
|
||||||
|
public CatalogSubscribeTask(Device device, ISIPCommander sipCommander) {
|
||||||
|
this.device = device;
|
||||||
|
this.sipCommander = sipCommander;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
sipCommander.catalogSubscribe(device, eventResult -> {
|
||||||
|
ResponseEvent event = (ResponseEvent) eventResult.event;
|
||||||
|
Element rootElement = null;
|
||||||
|
try {
|
||||||
|
rootElement = XmlUtil.getRootElement(event.getResponse().getRawContent(), "gb2312");
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Element resultElement = rootElement.element("Result");
|
||||||
|
String result = resultElement.getText();
|
||||||
|
if (result.toUpperCase().equals("OK")){
|
||||||
|
// 成功
|
||||||
|
logger.info("目录订阅成功: {}", device.getDeviceId());
|
||||||
|
}else {
|
||||||
|
// 失败
|
||||||
|
logger.info("目录订阅失败: {}-{}", device.getDeviceId(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
},eventResult -> {
|
||||||
|
// 失败
|
||||||
|
logger.warn("目录订阅失败: {}-信令发送失败", device.getDeviceId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||||
|
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.CatalogSubscribeTask;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class DeviceServiceImpl implements IDeviceService {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DynamicTask dynamicTask;
|
||||||
|
;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISIPCommander sipCommander;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addCatalogSubscribe(Device device) {
|
||||||
|
if (device == null || device.getSubscribeCycleForCatalog() < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 添加目录订阅
|
||||||
|
CatalogSubscribeTask catalogSubscribeTask = new CatalogSubscribeTask(device, sipCommander);
|
||||||
|
catalogSubscribeTask.run();
|
||||||
|
// 提前开始刷新订阅
|
||||||
|
String cron = getCron(device.getSubscribeCycleForCatalog() - 60);
|
||||||
|
dynamicTask.startCron(device.getDeviceId(), catalogSubscribeTask, cron);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeCatalogSubscribe(Device device) {
|
||||||
|
if (device == null || device.getSubscribeCycleForCatalog() < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dynamicTask.stopCron(device.getDeviceId());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCron(int time) {
|
||||||
|
if (time <= 59) {
|
||||||
|
return "0/" + time +" * * * * ?";
|
||||||
|
}else if (time <= 60* 59) {
|
||||||
|
int minute = time/(60);
|
||||||
|
return "0 0/" + minute +" * * * ?";
|
||||||
|
}else if (time <= 60* 60* 59) {
|
||||||
|
int hour = time/(60*60);
|
||||||
|
return "0 0 0/" + hour +" * * ?";
|
||||||
|
}else {
|
||||||
|
return "0 0/10 * * * ?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,5 @@
|
|||||||
package com.genersoft.iot.vmp.storager;
|
package com.genersoft.iot.vmp.storager;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
||||||
@ -9,8 +7,10 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
|
|||||||
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:视频设备数据存储接口
|
* @description:视频设备数据存储接口
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 下午2:14:31
|
* @date: 2020年5月6日 下午2:14:31
|
||||||
*/
|
*/
|
||||||
@ -97,6 +97,13 @@ public interface IVideoManagerStorager {
|
|||||||
*/
|
*/
|
||||||
public DeviceChannel queryChannel(String deviceId, String channelId);
|
public DeviceChannel queryChannel(String deviceId, String channelId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除通道
|
||||||
|
* @param deviceId 设备ID
|
||||||
|
* @param channelId 通道ID
|
||||||
|
*/
|
||||||
|
public int delChannel(String deviceId, String channelId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取多个设备
|
* 获取多个设备
|
||||||
* @param page 当前页数
|
* @param page 当前页数
|
||||||
@ -373,7 +380,30 @@ public interface IVideoManagerStorager {
|
|||||||
*/
|
*/
|
||||||
void updateMediaServer(MediaServerItem mediaServerItem);
|
void updateMediaServer(MediaServerItem mediaServerItem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据媒体ID获取启用/不启用的代理列表
|
||||||
|
* @param id 媒体ID
|
||||||
|
* @param b 启用/不启用
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
List<StreamProxyItem> getStreamProxyListForEnableInMediaServer(String id, boolean b);
|
List<StreamProxyItem> getStreamProxyListForEnableInMediaServer(String id, boolean b);
|
||||||
|
|
||||||
Device queryVideoDeviceByChannelId(String platformGbId);
|
/**
|
||||||
|
* 根据通道ID获取其所在设备
|
||||||
|
* @param channelId 通道ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Device queryVideoDeviceByChannelId(String channelId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通道上线
|
||||||
|
* @param channelId 通道ID
|
||||||
|
*/
|
||||||
|
void deviceChannelOnline(String deviceId, String channelId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通道离线
|
||||||
|
* @param channelId 通道ID
|
||||||
|
*/
|
||||||
|
void deviceChannelOffline(String deviceId, String channelId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,6 +74,9 @@ public interface DeviceChannelMapper {
|
|||||||
@Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId}")
|
@Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId}")
|
||||||
int cleanChannelsByDeviceId(String deviceId);
|
int cleanChannelsByDeviceId(String deviceId);
|
||||||
|
|
||||||
|
@Delete("DELETE FROM device_channel WHERE deviceId=#{deviceId} AND channelId=#{channelId}")
|
||||||
|
int del(String deviceId, String channelId);
|
||||||
|
|
||||||
@Update(value = {"UPDATE device_channel SET streamId=null WHERE deviceId=#{deviceId} AND channelId=#{channelId}"})
|
@Update(value = {"UPDATE device_channel SET streamId=null WHERE deviceId=#{deviceId} AND channelId=#{channelId}"})
|
||||||
void stopPlay(String deviceId, String channelId);
|
void stopPlay(String deviceId, String channelId);
|
||||||
|
|
||||||
@ -104,5 +107,11 @@ public interface DeviceChannelMapper {
|
|||||||
List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, Boolean inPlatform);
|
List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, Boolean inPlatform);
|
||||||
|
|
||||||
@Select("SELECT * FROM device_channel WHERE channelId=#{channelId}")
|
@Select("SELECT * FROM device_channel WHERE channelId=#{channelId}")
|
||||||
List<DeviceChannel> queryChannelByChannelId(String channelId);
|
List<DeviceChannel> queryChannelByChannelId( String channelId);
|
||||||
|
|
||||||
|
@Update(value = {"UPDATE device_channel SET status=0 WHERE deviceId=#{deviceId} AND channelId=#{channelId}"})
|
||||||
|
void offline(String deviceId, String channelId);
|
||||||
|
|
||||||
|
@Update(value = {"UPDATE device_channel SET status=1 WHERE deviceId=#{deviceId} AND channelId=#{channelId}"})
|
||||||
|
void online(String deviceId, String channelId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ public interface DeviceMapper {
|
|||||||
"createTime," +
|
"createTime," +
|
||||||
"updateTime," +
|
"updateTime," +
|
||||||
"charset," +
|
"charset," +
|
||||||
|
"subscribeCycleForCatalog," +
|
||||||
"online" +
|
"online" +
|
||||||
") VALUES (" +
|
") VALUES (" +
|
||||||
"#{deviceId}," +
|
"#{deviceId}," +
|
||||||
@ -51,6 +52,7 @@ public interface DeviceMapper {
|
|||||||
"#{createTime}," +
|
"#{createTime}," +
|
||||||
"#{updateTime}," +
|
"#{updateTime}," +
|
||||||
"#{charset}," +
|
"#{charset}," +
|
||||||
|
"#{subscribeCycleForCatalog}," +
|
||||||
"#{online}" +
|
"#{online}" +
|
||||||
")")
|
")")
|
||||||
int add(Device device);
|
int add(Device device);
|
||||||
@ -72,6 +74,7 @@ public interface DeviceMapper {
|
|||||||
"<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" +
|
"<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" +
|
||||||
"<if test=\"expires != null\">, expires=${expires}</if>" +
|
"<if test=\"expires != null\">, expires=${expires}</if>" +
|
||||||
"<if test=\"charset != null\">, charset='${charset}'</if>" +
|
"<if test=\"charset != null\">, charset='${charset}'</if>" +
|
||||||
|
"<if test=\"subscribeCycleForCatalog != null\">, subscribeCycleForCatalog=#{subscribeCycleForCatalog}</if>" +
|
||||||
"WHERE deviceId='${deviceId}'"+
|
"WHERE deviceId='${deviceId}'"+
|
||||||
" </script>"})
|
" </script>"})
|
||||||
int update(Device device);
|
int update(Device device);
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
package com.genersoft.iot.vmp.storager.impl;
|
package com.genersoft.iot.vmp.storager.impl;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||||
import com.genersoft.iot.vmp.storager.dao.*;
|
import com.genersoft.iot.vmp.storager.dao.*;
|
||||||
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
@ -18,14 +16,18 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
|
||||||
import org.springframework.transaction.TransactionDefinition;
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:视频设备数据存储-jdbc实现
|
* @description:视频设备数据存储-jdbc实现
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2020年5月6日 下午2:31:42
|
* @date: 2020年5月6日 下午2:31:42
|
||||||
*/
|
*/
|
||||||
@ -137,6 +139,16 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deviceChannelOnline(String deviceId, String channelId) {
|
||||||
|
deviceChannelMapper.online(deviceId, channelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deviceChannelOffline(String deviceId, String channelId) {
|
||||||
|
deviceChannelMapper.offline(deviceId, channelId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startPlay(String deviceId, String channelId, String streamId) {
|
public void startPlay(String deviceId, String channelId, String streamId) {
|
||||||
deviceChannelMapper.startPlay(deviceId, channelId, streamId);
|
deviceChannelMapper.startPlay(deviceId, channelId, streamId);
|
||||||
@ -184,6 +196,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int delChannel(String deviceId, String channelId) {
|
||||||
|
return deviceChannelMapper.del(deviceId, channelId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取多个设备
|
* 获取多个设备
|
||||||
*
|
*
|
||||||
@ -624,8 +641,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
|
|||||||
return streamProxyMapper.selectForEnableInMediaServer(id, enable);
|
return streamProxyMapper.selectForEnableInMediaServer(id, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Device queryVideoDeviceByChannelId(String channelId) {
|
public Device queryVideoDeviceByChannelId( String channelId) {
|
||||||
Device result = null;
|
Device result = null;
|
||||||
List<DeviceChannel> channelList = deviceChannelMapper.queryChannelByChannelId(channelId);
|
List<DeviceChannel> channelList = deviceChannelMapper.queryChannelByChannelId(channelId);
|
||||||
if (channelList.size() == 1) {
|
if (channelList.size() == 1) {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import org.springframework.context.ApplicationContextAware;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description:spring bean获取工厂,获取spring中的已初始化的bean
|
* @description:spring bean获取工厂,获取spring中的已初始化的bean
|
||||||
* @author: swwheihei
|
* @author: swwheihei
|
||||||
* @date: 2019年6月25日 下午4:51:52
|
* @date: 2019年6月25日 下午4:51:52
|
||||||
*
|
*
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user