This commit is contained in:
zxb 2023-08-04 16:40:37 +08:00
parent 8b72d7db64
commit 25321e3a7d
9 changed files with 81 additions and 108 deletions

View File

@ -301,9 +301,14 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<!-- <scope>test</scope>-->
<scope>test</scope>
</dependency>
<!-- 开发工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- lombok -->
<dependency>

View File

@ -1,7 +1,6 @@
package com.genersoft.iot.vmp.conf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
@ -19,10 +18,8 @@ import java.util.concurrent.TimeUnit;
* @author lin
*/
@Component
@Slf4j
public class DynamicTask {
private final Logger logger = LoggerFactory.getLogger(DynamicTask.class);
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
private final Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>();
@ -48,9 +45,9 @@ public class DynamicTask {
ScheduledFuture<?> future = futureMap.get(key);
if (future != null) {
if (future.isCancelled()) {
logger.debug("任务【{}】已存在但是关闭状态!!!", key);
log.debug("任务【{}】已存在但是关闭状态!!!", key);
} else {
logger.debug("任务【{}】已存在且已启动!!!", key);
log.debug("任务【{}】已存在且已启动!!!", key);
return;
}
}
@ -59,9 +56,9 @@ public class DynamicTask {
if (future != null){
futureMap.put(key, future);
runnableMap.put(key, task);
logger.debug("任务【{}】启动成功!!!", key);
log.debug("任务【{}】启动成功!!!", key);
}else {
logger.debug("任务【{}】启动失败!!!", key);
log.debug("任务【{}】启动失败!!!", key);
}
}
@ -78,12 +75,12 @@ public class DynamicTask {
// 获取执行的时刻
Instant startInstant = Instant.now().plusMillis(TimeUnit.MILLISECONDS.toMillis(delay));
ScheduledFuture future = futureMap.get(key);
ScheduledFuture<?> future = futureMap.get(key);
if (future != null) {
if (future.isCancelled()) {
logger.debug("任务【{}】已存在但是关闭状态!!!", key);
log.debug("任务【{}】已存在但是关闭状态!!!", key);
} else {
logger.debug("任务【{}】已存在且已启动!!!", key);
log.debug("任务【{}】已存在且已启动!!!", key);
return;
}
}
@ -92,9 +89,9 @@ public class DynamicTask {
if (future != null){
futureMap.put(key, future);
runnableMap.put(key, task);
logger.debug("任务【{}】启动成功!!!", key);
log.debug("任务【{}】启动成功!!!", key);
}else {
logger.debug("任务【{}】启动失败!!!", key);
log.debug("任务【{}】启动失败!!!", key);
}
}

View File

@ -26,8 +26,8 @@
package com.genersoft.iot.vmp.gb28181.auth;
import gov.nist.core.InternalErrorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import javax.sip.address.URI;
import javax.sip.header.AuthorizationHeader;
@ -46,19 +46,14 @@ import java.util.Random;
* @author M. Ranganathan
* @author Marc Bednarek
*/
@Slf4j
public class DigestServerAuthenticationHelper {
private Logger logger = LoggerFactory.getLogger(DigestServerAuthenticationHelper.class);
private MessageDigest messageDigest;
private final MessageDigest messageDigest;
public static final String DEFAULT_ALGORITHM = "MD5";
public static final String DEFAULT_SCHEME = "Digest";
/** to hex converter */
private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
@ -93,8 +88,8 @@ public class DigestServerAuthenticationHelper {
long pad = rand.nextLong();
String nonceString = Long.valueOf(time).toString()
+ Long.valueOf(pad).toString();
byte mdbytes[] = messageDigest.digest(nonceString.getBytes());
return toHexString(mdbytes);
byte[] mdBytes = messageDigest.digest(nonceString.getBytes());
return toHexString(mdBytes);
}
public Response generateChallenge(HeaderFactory headerFactory, Response response, String realm) {
@ -138,12 +133,9 @@ public class DigestServerAuthenticationHelper {
return false;
}
String A2 = request.getMethod().toUpperCase() + ":" + uri.toString();
String A2 = request.getMethod().toUpperCase() + ":" + uri;
String HA1 = hashedPassword;
byte[] mdbytes = messageDigest.digest(A2.getBytes());
String HA2 = toHexString(mdbytes);
@ -177,7 +169,7 @@ public class DigestServerAuthenticationHelper {
String realm = authHeader.getRealm().trim();
String username = authHeader.getUsername().trim();
if ( username == null || realm == null ) {
if(ObjectUtils.anyNull(username,realm)){
return false;
}
@ -196,26 +188,22 @@ public class DigestServerAuthenticationHelper {
// nonce计数器是一个16进制的数值表示同一nonce下客户端发送出请求的数量
int nc = authHeader.getNonceCount();
String ncStr = String.format("%08x", nc).toUpperCase();
// String ncStr = new DecimalFormat("00000000").format(nc);
// String ncStr = new DecimalFormat("00000000").format(Integer.parseInt(nc + "", 16));
String A1 = String.join(":",username , realm , pass);
String A2 = String.join(":",request.getMethod().toUpperCase() , uri.toString());
String A1 = username + ":" + realm + ":" + pass;
String A2 = request.getMethod().toUpperCase() + ":" + uri.toString();
byte mdbytes[] = messageDigest.digest(A1.getBytes());
byte[] mdbytes = messageDigest.digest(A1.getBytes());
String HA1 = toHexString(mdbytes);
logger.debug("A1: " + A1);
logger.debug("A2: " + A2);
log.debug("A1: " + A1);
log.debug("A2: " + A2);
mdbytes = messageDigest.digest(A2.getBytes());
String HA2 = toHexString(mdbytes);
logger.debug("HA1: " + HA1);
logger.debug("HA2: " + HA2);
log.debug("HA1: " + HA1);
log.debug("HA2: " + HA2);
// String cnonce = authHeader.getCNonce();
logger.debug("nonce: " + nonce);
logger.debug("nc: " + ncStr);
logger.debug("cnonce: " + cnonce);
logger.debug("qop: " + qop);
log.debug("nonce: " + nonce);
log.debug("nc: " + ncStr);
log.debug("cnonce: " + cnonce);
log.debug("qop: " + qop);
String KD = HA1 + ":" + nonce;
if (qop != null && qop.equalsIgnoreCase("auth") ) {
@ -228,12 +216,12 @@ public class DigestServerAuthenticationHelper {
KD += ":" + qop;
}
KD += ":" + HA2;
logger.debug("KD: " + KD);
log.debug("KD: " + KD);
mdbytes = messageDigest.digest(KD.getBytes());
String mdString = toHexString(mdbytes);
logger.debug("mdString: " + mdString);
log.debug("mdString: " + mdString);
String response = authHeader.getResponse();
logger.debug("response: " + response);
log.debug("response: " + response);
return mdString.equals(response);
}

View File

@ -20,8 +20,8 @@ import gov.nist.javax.sip.address.SipUri;
import gov.nist.javax.sip.header.SIPDateHeader;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -43,32 +43,26 @@ import java.util.Locale;
/**
* SIP命令类型 REGISTER请求
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class RegisterRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
public static final String METHOD = "REGISTER";
private final SipConfig sipConfig;
private final Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class);
private final SIPProcessorObserver sipProcessorObserver;
public final String method = "REGISTER";
private final IDeviceService deviceService;
@Autowired
private SipConfig sipConfig;
private final SIPSender sipSender;
@Autowired
private SIPProcessorObserver sipProcessorObserver;
@Autowired
private IDeviceService deviceService;
@Autowired
private SIPSender sipSender;
@Autowired
private UserSetting userSetting;
private final UserSetting userSetting;
@Override
public void afterPropertiesSet() throws Exception {
// 添加消息处理的订阅
sipProcessorObserver.addRequestProcessor(method, this);
sipProcessorObserver.addRequestProcessor(METHOD, this);
}
/**
@ -82,8 +76,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
RequestEventExt evtExt = (RequestEventExt) evt;
SIPRequest request = (SIPRequest)evt.getRequest();
Response response = null;
boolean passwordCorrect = false;
Response response;
boolean passwordCorrect;
// 注册标志
boolean registerFlag;
FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);
@ -96,11 +90,11 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request,
userSetting.getSipUseSourceIpAsRemoteAddress());
String requestAddress = remoteAddressInfo.getIp() + ":" + remoteAddressInfo.getPort();
logger.info("[注册请求] 设备:{}, 开始处理: {}", deviceId, requestAddress);
log.info("[注册请求] 设备:{}, 开始处理: {}", deviceId, requestAddress);
if (device != null &&
device.getSipTransactionInfo() != null &&
request.getCallIdHeader().getCallId().equals(device.getSipTransactionInfo().getCallId())) {
logger.info("[注册请求] 设备:{}, 注册续订: {}",device.getDeviceId(), device.getDeviceId());
log.info("[注册请求] 设备:{}, 注册续订: {}",device.getDeviceId(), device.getDeviceId());
device.setExpires(request.getExpires().getExpires());
device.setIp(remoteAddressInfo.getIp());
device.setPort(remoteAddressInfo.getPort());
@ -120,7 +114,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword();
AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
if (authHead == null && !ObjectUtils.isEmpty(password)) {
logger.info("[注册请求] 设备:{}, 回复401: {}",deviceId, requestAddress);
log.info("[注册请求] 设备:{}, 回复401: {}",deviceId, requestAddress);
response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain());
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
@ -135,7 +129,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
// 注册失败
response = getMessageFactory().createResponse(Response.FORBIDDEN, request);
response.setReasonPhrase("wrong password");
logger.info("[注册请求] 设备:{}, 密码/SIP服务器ID错误, 回复403: {}", deviceId, requestAddress);
log.info("[注册请求] 设备:{}, 密码/SIP服务器ID错误, 回复403: {}", deviceId, requestAddress);
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
return;
}
@ -199,16 +193,16 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
// 注册成功
// 保存到redis
if (registerFlag) {
logger.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress);
log.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress);
device.setRegisterTime(DateUtil.getNow());
SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response);
deviceService.online(device, sipTransactionInfo);
} else {
logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress);
log.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress);
deviceService.offline(deviceId, "主动注销");
}
} catch (SipException | NoSuchAlgorithmException | ParseException e) {
logger.error("未处理的异常 ", e);
log.error("未处理的异常 ", e);
}
}

View File

@ -86,6 +86,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract {
Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response);
logger.info("[回复ack] {}-> {}:{} ", sdp.getOrigin().getUsername(), event.getRemoteIpAddress(), event.getRemotePort());
logger.debug("{}",reqAck);
sipSender.transmitRequest( response.getLocalAddress().getHostAddress(), reqAck);
}
} catch (InvalidArgumentException | ParseException | SipException | SdpParseException e) {

View File

@ -424,10 +424,8 @@ public class PlatformController {
@PostMapping("/catalog/add")
@ResponseBody
public void addCatalog(@RequestBody PlatformCatalog platformCatalog) {
logger.debug("添加目录,{}", JSON.toJSONString(platformCatalog));
if (logger.isDebugEnabled()) {
logger.debug("添加目录,{}", JSON.toJSONString(platformCatalog));
}
PlatformCatalog platformCatalogInStore = storager.getCatalog(platformCatalog.getPlatformId(), platformCatalog.getId());
if (platformCatalogInStore != null) {

View File

@ -5,9 +5,8 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@ -22,15 +21,13 @@ import java.text.ParseException;
@RestController
@RequestMapping(value = "/api/v1/control")
@RequiredArgsConstructor
@Slf4j
public class ApiControlController {
private final static Logger logger = LoggerFactory.getLogger(ApiControlController.class);
private final SIPCommander cmder;
@Autowired
private SIPCommander cmder;
@Autowired
private IVideoManagerStorage storager;
private final IVideoManagerStorage storager;
/**
* 设备控制 - 云台控制
@ -47,8 +44,8 @@ public class ApiControlController {
@RequestParam(required = false)String code,
@RequestParam(required = false)Integer speed){
if (logger.isDebugEnabled()) {
logger.debug("模拟接口> 设备云台控制 API调用deviceId{} channelId{} command{} speed{} ",
if (log.isDebugEnabled()) {
log.debug("模拟接口> 设备云台控制 API调用deviceId{} channelId{} command{} speed{} ",
serial, code, command, speed);
}
if (channel == null) {channel = 0;}
@ -99,7 +96,7 @@ public class ApiControlController {
try {
cmder.frontEndCmd(device, code, cmdCode, speed, speed, speed);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 云台控制: {}", e.getMessage());
log.error("[命令发送失败] 云台控制: {}", e.getMessage());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
}
}
@ -121,8 +118,8 @@ public class ApiControlController {
@RequestParam(required = false)String name,
@RequestParam(required = false)Integer preset){
if (logger.isDebugEnabled()) {
logger.debug("模拟接口> 预置位控制 API调用deviceId{} channelId{} command{} name{} preset{} ",
if (log.isDebugEnabled()) {
log.debug("模拟接口> 预置位控制 API调用deviceId{} channelId{} command{} name{} preset{} ",
serial, code, command, name, preset);
}
@ -148,7 +145,7 @@ public class ApiControlController {
try {
cmder.frontEndCmd(device, code, cmdCode, 0, preset, 0);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 预置位控制: {}", e.getMessage());
log.error("[命令发送失败] 预置位控制: {}", e.getMessage());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
}
}

View File

@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.vmanager.bean.DeferredResultEx;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -28,27 +29,19 @@ import javax.sip.SipException;
import java.text.ParseException;
import java.util.*;
/**
* API兼容设备信息
*/
@SuppressWarnings("unchecked")
@RestController
@RequestMapping(value = "/api/v1/device")
@RequiredArgsConstructor
public class ApiDeviceController {
private final static Logger logger = LoggerFactory.getLogger(ApiDeviceController.class);
private final IVideoManagerStorage storager;
private final SIPCommander cmder;
@Autowired
private IVideoManagerStorage storager;
private final IDeviceService deviceService;
@Autowired
private SIPCommander cmder;
@Autowired
private IDeviceService deviceService;
@Autowired
private DeferredResultHolder resultHolder;
private final DeferredResultHolder resultHolder;
/**

View File

@ -90,7 +90,7 @@
<appender-ref ref="STDOUT" />
</root>
<logger name="com.genersoft.iot.vmp" level="info" additivity="true">
<logger name="com.genersoft.iot.vmp" level="debug" additivity="true">
<appender-ref ref="RollingFileError"/>
<appender-ref ref="RollingFile"/>
</logger>