From 6bb578d1bdbf9790f2670b43c545444478a7b17a Mon Sep 17 00:00:00 2001 From: shikong <919411476@qq.com> Date: Sat, 12 Aug 2023 04:13:38 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=B3=A8=E5=86=8C=20?= =?UTF-8?q?=E6=9C=AA=E5=AE=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/sip/dto/SipTransactionInfo.java | 22 +++++ .../sip/{ => gb28181}/sdp/Gb28181Sdp.java | 2 +- .../core/sip/gb28181/sip/GbSipDate.java | 27 ++++++ .../core/sip/logger/ServerLoggerImpl.java | 7 +- .../DigestServerAuthenticationHelper.java | 3 + .../request/RegisterRequestProcessor.java | 86 ++++++++++++++++++- .../gb28181/core/sip/utils/SipUtil.java | 2 +- 7 files changed, 142 insertions(+), 7 deletions(-) create mode 100644 gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/dto/SipTransactionInfo.java rename gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/{ => gb28181}/sdp/Gb28181Sdp.java (84%) create mode 100644 gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/gb28181/sip/GbSipDate.java diff --git a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/dto/SipTransactionInfo.java b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/dto/SipTransactionInfo.java new file mode 100644 index 0000000..34fbdc6 --- /dev/null +++ b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/dto/SipTransactionInfo.java @@ -0,0 +1,22 @@ +package cn.skcks.docking.gb28181.core.sip.dto; + +import gov.nist.javax.sip.message.SIPResponse; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class SipTransactionInfo { + + private String callId; + private String fromTag; + private String toTag; + private String viaBranch; + + public SipTransactionInfo(SIPResponse response) { + this.callId = response.getCallIdHeader().getCallId(); + this.fromTag = response.getFromTag(); + this.toTag = response.getToTag(); + this.viaBranch = response.getTopmostViaHeader().getBranch(); + } +} diff --git a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/sdp/Gb28181Sdp.java b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/gb28181/sdp/Gb28181Sdp.java similarity index 84% rename from gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/sdp/Gb28181Sdp.java rename to gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/gb28181/sdp/Gb28181Sdp.java index bae536c..feeef96 100644 --- a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/sdp/Gb28181Sdp.java +++ b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/gb28181/sdp/Gb28181Sdp.java @@ -1,4 +1,4 @@ -package cn.skcks.docking.gb28181.core.sip.sdp; +package cn.skcks.docking.gb28181.core.sip.gb28181.sdp; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/gb28181/sip/GbSipDate.java b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/gb28181/sip/GbSipDate.java new file mode 100644 index 0000000..f946c34 --- /dev/null +++ b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/gb28181/sip/GbSipDate.java @@ -0,0 +1,27 @@ +package cn.skcks.docking.gb28181.core.sip.gb28181.sip; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.format.FastDateFormat; +import gov.nist.javax.sip.header.SIPDate; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; + +/** + * GB28181 SIP 日期 + */ +public class GbSipDate extends SIPDate { + private final Calendar javaCal; + + public GbSipDate(long timeMillis) { + super(timeMillis); + this.javaCal = new GregorianCalendar(TimeZone.getDefault(), Locale.getDefault()); + } + + @Override + public StringBuilder encode(StringBuilder encoding) { + return encoding.append(FastDateFormat.getInstance(DatePattern.UTC_SIMPLE_MS_PATTERN, TimeZone.getTimeZone("Asia/Shanghai")).format(javaCal)); + } +} diff --git a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/logger/ServerLoggerImpl.java b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/logger/ServerLoggerImpl.java index 0aea692..23bc26a 100644 --- a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/logger/ServerLoggerImpl.java +++ b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/logger/ServerLoggerImpl.java @@ -9,6 +9,7 @@ import gov.nist.javax.sip.stack.SIPTransactionStack; import javax.sip.SipStack; import java.util.Properties; +@SuppressWarnings("unused") public class ServerLoggerImpl implements ServerLogger { private boolean showLog = true; @@ -25,7 +26,7 @@ public class ServerLoggerImpl implements ServerLogger { if (!showLog) { return; } - String log = (sender ? "发送: 目标 =>" + to : "接收: 来自 => " + from) + "\r\n" + message; + String log = (sender ? "发送: 目标 => " + to : "接收: 来自 => " + from) + "\r\n" + message; this.stackLogger.logInfo(log); } @@ -34,7 +35,7 @@ public class ServerLoggerImpl implements ServerLogger { if (!showLog) { return; } - String log = (sender ? "发送: 目标 =>" + to : "接收: 来自 => " + from) + "\r\n" + message; + String log = (sender ? "发送: 目标 => " + to : "接收: 来自 => " + from) + "\r\n" + message; this.stackLogger.logInfo(log); } @@ -43,7 +44,7 @@ public class ServerLoggerImpl implements ServerLogger { if (!showLog) { return; } - String log = (sender ? "发送: 目标 =>" + to : "接收: 来自 => " + from) + "\r\n" + message; + String log = (sender ? "发送: 目标 => " + to : "接收: 来自 => " + from) + "\r\n" + message; this.stackLogger.logInfo(log); } diff --git a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/message/auth/DigestServerAuthenticationHelper.java b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/message/auth/DigestServerAuthenticationHelper.java index 5d4fa72..99b3125 100644 --- a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/message/auth/DigestServerAuthenticationHelper.java +++ b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/message/auth/DigestServerAuthenticationHelper.java @@ -25,6 +25,8 @@ */ package cn.skcks.docking.gb28181.core.sip.message.auth; +import cn.hutool.core.util.HexUtil; +import cn.hutool.core.util.NumberUtil; import gov.nist.core.InternalErrorHandler; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; @@ -189,6 +191,7 @@ public class DigestServerAuthenticationHelper { // nonce计数器,是一个16进制的数值,表示同一nonce下客户端发送出请求的数量 int nc = authHeader.getNonceCount(); + String ncStr = String.format("%08x", nc).toUpperCase(); String A1 = String.join(":",username , realm , pass); String A2 = String.join(":",request.getMethod().toUpperCase() , uri.toString()); diff --git a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/message/processor/request/RegisterRequestProcessor.java b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/message/processor/request/RegisterRequestProcessor.java index 2d07711..fc50a9b 100644 --- a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/message/processor/request/RegisterRequestProcessor.java +++ b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/message/processor/request/RegisterRequestProcessor.java @@ -1,7 +1,10 @@ package cn.skcks.docking.gb28181.core.sip.message.processor.request; +import cn.hutool.core.date.DateUtil; import cn.skcks.docking.gb28181.config.sip.SipConfig; import cn.skcks.docking.gb28181.core.sip.dto.RemoteInfo; +import cn.skcks.docking.gb28181.core.sip.dto.SipTransactionInfo; +import cn.skcks.docking.gb28181.core.sip.gb28181.sip.GbSipDate; import cn.skcks.docking.gb28181.core.sip.listener.SipListener; import cn.skcks.docking.gb28181.core.sip.message.auth.DigestServerAuthenticationHelper; import cn.skcks.docking.gb28181.core.sip.message.processor.MessageProcessor; @@ -11,18 +14,30 @@ import cn.skcks.docking.gb28181.orm.mybatis.dynamic.model.DockingDevice; import cn.skcks.docking.gb28181.service.docking.DockingDeviceService; import gov.nist.javax.sip.address.SipUri; import gov.nist.javax.sip.header.Authorization; +import gov.nist.javax.sip.header.SIPDate; +import gov.nist.javax.sip.header.SIPDateHeader; import gov.nist.javax.sip.message.SIPRequest; +import gov.nist.javax.sip.message.SIPResponse; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import javax.sip.ListeningPoint; import javax.sip.RequestEvent; import javax.sip.address.Address; +import javax.sip.header.ExpiresHeader; import javax.sip.header.FromHeader; +import javax.sip.message.Request; import javax.sip.message.Response; +import java.nio.charset.StandardCharsets; +import java.util.Calendar; +import java.util.Locale; +import java.util.Optional; @Slf4j @RequiredArgsConstructor @@ -61,10 +76,11 @@ public class RegisterRequestProcessor implements MessageProcessor { String password = sipConfig.getPassword(); Authorization authorization = request.getAuthorization(); + String senderIp = request.getLocalAddress().getHostAddress(); if(authorization == null && StringUtils.isNotBlank(password)){ Response response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request); DigestServerAuthenticationHelper.generateChallenge(getHeaderFactory(),response,sipConfig.getDomain()); - sender.send(request.getLocalAddress().getHostAddress(),response); + sender.send(senderIp,response); return; } @@ -75,9 +91,75 @@ public class RegisterRequestProcessor implements MessageProcessor { Response response = getMessageFactory().createResponse(Response.FORBIDDEN, request); response.setReasonPhrase("认证失败"); log.info("设备注册信息认证失败 deviceId => {}", deviceId); - sender.send(request.getLocalAddress().getHostAddress(),response); + sender.send(senderIp,response); return; } + + log.debug("设备 deviceId => {}, 认证通过", deviceId); + Response response = generateRegisterResponse(request); + if(response.getStatusCode() != Response.OK){ + sender.send(senderIp, response); + return; + } + + + if (deviceInfo == null) { + deviceInfo = new DockingDevice(); + deviceInfo.setStreamMode(ListeningPoint.UDP); + deviceInfo.setCharset("GB2312"); + deviceInfo.setGeoCoordSys("WGS84"); + deviceInfo.setDeviceId(deviceId); + deviceInfo.setOnLine(false); + } else { + if (ObjectUtils.isEmpty(deviceInfo.getStreamMode())) { + deviceInfo.setStreamMode(ListeningPoint.UDP); + } + if (ObjectUtils.isEmpty(deviceInfo.getCharset())) { + deviceInfo.setCharset("GB2312"); + } + if (ObjectUtils.isEmpty(deviceInfo.getGeoCoordSys())) { + deviceInfo.setGeoCoordSys("WGS84"); + } + } + + deviceInfo.setIp(remoteInfo.getIp()); + deviceInfo.setPort(remoteInfo.getPort()); + deviceInfo.setHostAddress(remoteInfo.getIp().concat(":").concat(String.valueOf(remoteInfo.getPort()))); + deviceInfo.setLocalIp(senderIp); + + int expires = request.getExpires().getExpires(); + deviceInfo.setExpires(expires); + // expires == 0 时 注销 + if (expires == 0) { + log.info("设备注销 deviceId => {}", deviceId); + } else { + deviceInfo.setRegisterTime(DateUtil.now()); + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); + } + + sender.send(senderIp, response); + } + + @SneakyThrows + private Response generateRegisterResponse(Request request){ + SIPRequest sipRequest = (SIPRequest) request; + ExpiresHeader expires = sipRequest.getExpires(); + if(expires == null){ + return getMessageFactory().createResponse(Response.BAD_REQUEST, request); + } + + Response response = getMessageFactory().createResponse(Response.OK, request); + // 添加date头 + SIPDateHeader dateHeader = new SIPDateHeader(); + // GB28181 日期 + GbSipDate gbSipDate = new GbSipDate(Calendar.getInstance(Locale.ENGLISH).getTimeInMillis()); + dateHeader.setDate(gbSipDate); + + response.addHeader(dateHeader); + response.addHeader(sipRequest.getContactHeader()); + response.addHeader(expires); + + return response; } } diff --git a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/utils/SipUtil.java b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/utils/SipUtil.java index c7a33bb..9be6580 100644 --- a/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/utils/SipUtil.java +++ b/gb28181-service/src/main/java/cn/skcks/docking/gb28181/core/sip/utils/SipUtil.java @@ -5,7 +5,7 @@ import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.util.IdUtil; import cn.skcks.docking.gb28181.common.config.ProjectConfig; import cn.skcks.docking.gb28181.core.sip.dto.RemoteInfo; -import cn.skcks.docking.gb28181.core.sip.sdp.Gb28181Sdp; +import cn.skcks.docking.gb28181.core.sip.gb28181.sdp.Gb28181Sdp; import gov.nist.javax.sip.address.AddressImpl; import gov.nist.javax.sip.address.SipUri; import gov.nist.javax.sip.header.Subject;