分离 gb28181-sip 模块
重新封装 sdp 解析部分
This commit is contained in:
parent
dc030c6844
commit
f3ae4156d1
@ -28,7 +28,7 @@ public class XmlUtils {
|
||||
// 大驼峰 (首字母大写)
|
||||
mapper.setPropertyNamingStrategy(new PropertyNamingStrategies.UpperCamelCaseStrategy());
|
||||
// 添加 xml 头部声明
|
||||
mapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
|
||||
mapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, false);
|
||||
}
|
||||
|
||||
public static String toXml(Object obj) {
|
||||
|
@ -46,13 +46,6 @@
|
||||
<version>1.3.0-91</version>
|
||||
</dependency>
|
||||
|
||||
<!-- xml解析库 -->
|
||||
<dependency>
|
||||
<groupId>org.dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
<version>2.1.4</version>
|
||||
</dependency>
|
||||
|
||||
<!--MapStruct-->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
|
38
gb28181-sip/.gitignore
vendored
Normal file
38
gb28181-sip/.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
44
gb28181-sip/pom.xml
Normal file
44
gb28181-sip/pom.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>cn.skcks.docking</groupId>
|
||||
<artifactId>gb28181</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>cn.skcks.docking.gb28181</groupId>
|
||||
<artifactId>gb28181-sip</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.skcks.docking.gb28181</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sip协议栈 -->
|
||||
<dependency>
|
||||
<groupId>javax.sip</groupId>
|
||||
<artifactId>jain-sip-ri</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,39 @@
|
||||
package cn.skcks.docking.gb28181.sdp;
|
||||
|
||||
import gov.nist.javax.sdp.SessionDescriptionImpl;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.sdp.SdpException;
|
||||
import javax.sdp.SessionDescription;
|
||||
|
||||
@Slf4j
|
||||
@Setter
|
||||
@Getter
|
||||
public class GB28181Description extends SessionDescriptionImpl implements SessionDescription {
|
||||
private SsrcField ssrcField;
|
||||
private SessionDescriptionImpl sessionDescription;
|
||||
|
||||
public GB28181Description(){
|
||||
super();
|
||||
}
|
||||
|
||||
public GB28181Description(SessionDescription sessionDescription) throws SdpException {
|
||||
super(sessionDescription);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static GB28181Description build(SessionDescription sessionDescription){
|
||||
return new GB28181Description(sessionDescription);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(super.toString());
|
||||
sb.append(getSsrcField() == null ? "" : getSsrcField().toString());
|
||||
// return "+";
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package cn.skcks.docking.gb28181.sdp;
|
||||
|
||||
import gov.nist.core.ParserCore;
|
||||
import gov.nist.javax.sdp.SessionDescriptionImpl;
|
||||
import gov.nist.javax.sdp.fields.SDPField;
|
||||
import gov.nist.javax.sdp.parser.Lexer;
|
||||
import gov.nist.javax.sdp.parser.SDPParser;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Vector;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public class GB28181DescriptionParser extends ParserCore {
|
||||
protected Lexer lexer;
|
||||
protected Vector sdpMessage;
|
||||
|
||||
public GB28181DescriptionParser(Vector sdpMessage) {
|
||||
this.sdpMessage = sdpMessage;
|
||||
}
|
||||
|
||||
public GB28181DescriptionParser(String message) {
|
||||
int start = 0;
|
||||
String line = null;
|
||||
// Return trivially if there is no sdp announce message
|
||||
// to be parsed. Bruno Konik noticed this bug.
|
||||
if (message == null) return;
|
||||
sdpMessage = new Vector();
|
||||
// Strip off leading and trailing junk.
|
||||
String sdpAnnounce = message.trim() + "\r\n";
|
||||
// Bug fix by Andreas Bystrom.
|
||||
while (start < sdpAnnounce.length()) {
|
||||
// Major re-write by Ricardo Borba.
|
||||
int lfPos = sdpAnnounce.indexOf("\n", start);
|
||||
int crPos = sdpAnnounce.indexOf("\r", start);
|
||||
|
||||
if (lfPos >= 0 && crPos < 0) {
|
||||
// there are only "\n" separators
|
||||
line = sdpAnnounce.substring(start, lfPos);
|
||||
start = lfPos + 1;
|
||||
} else if (lfPos < 0 && crPos >= 0) {
|
||||
//bug fix: there are only "\r" separators
|
||||
line = sdpAnnounce.substring(start, crPos);
|
||||
start = crPos + 1;
|
||||
} else if (lfPos >= 0 && crPos >= 0) {
|
||||
// there are "\r\n" or "\n\r" (if exists) separators
|
||||
if (lfPos > crPos) {
|
||||
// assume "\r\n" for now
|
||||
line = sdpAnnounce.substring(start, crPos);
|
||||
// Check if the "\r" and "\n" are close together
|
||||
if (lfPos == crPos + 1) {
|
||||
start = lfPos + 1; // "\r\n"
|
||||
} else {
|
||||
start = crPos + 1; // "\r" followed by the next record and a "\n" further away
|
||||
}
|
||||
} else {
|
||||
// assume "\n\r" for now
|
||||
line = sdpAnnounce.substring(start, lfPos);
|
||||
// Check if the "\n" and "\r" are close together
|
||||
if (crPos == lfPos + 1) {
|
||||
start = crPos + 1; // "\n\r"
|
||||
} else {
|
||||
start = lfPos + 1; // "\n" followed by the next record and a "\r" further away
|
||||
}
|
||||
}
|
||||
} else if (lfPos < 0 && crPos < 0) { // end
|
||||
break;
|
||||
}
|
||||
sdpMessage.addElement(line);
|
||||
}
|
||||
}
|
||||
|
||||
public GB28181Description parse() throws ParseException {
|
||||
GB28181Description retval = new GB28181Description();
|
||||
for (int i = 0; i < sdpMessage.size(); i++) {
|
||||
String field = (String) sdpMessage.elementAt(i);
|
||||
SDPParser sdpParser = GB28181DescriptionParserFactory.createParser(field);
|
||||
SDPField sdpField = null;
|
||||
if (sdpParser != null) {
|
||||
sdpField = sdpParser.parse();
|
||||
}
|
||||
retval.addField(sdpField);
|
||||
if (sdpField instanceof SsrcField ssrc) {
|
||||
retval.setSsrcField(ssrc);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package cn.skcks.docking.gb28181.sdp;
|
||||
|
||||
import gov.nist.javax.sdp.parser.Lexer;
|
||||
import gov.nist.javax.sdp.parser.ParserFactory;
|
||||
import gov.nist.javax.sdp.parser.SDPParser;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
public class GB28181DescriptionParserFactory {
|
||||
public static SDPParser createParser(String field) throws ParseException {
|
||||
String fieldName = Lexer.getFieldName(field);
|
||||
if(fieldName.equalsIgnoreCase("y")){
|
||||
return new SsrcFieldParser(field);
|
||||
}
|
||||
return ParserFactory.createParser(field);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cn.skcks.docking.gb28181.sdp;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.sdp.SessionDescription;
|
||||
|
||||
@Builder
|
||||
@Data
|
||||
public class Gb28181Sdp {
|
||||
private SessionDescription baseSdb;
|
||||
private String ssrc;
|
||||
private String mediaDescription;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package cn.skcks.docking.gb28181.sdp;
|
||||
|
||||
import gov.nist.core.Separators;
|
||||
import gov.nist.javax.sdp.fields.SDPField;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class SsrcField extends SDPField {
|
||||
private static final String SSRC_FIELD = "y=";
|
||||
public SsrcField() {
|
||||
super(SSRC_FIELD);
|
||||
}
|
||||
|
||||
private String ssrc;
|
||||
|
||||
@Override
|
||||
public String encode() {
|
||||
return SSRC_FIELD + ssrc + Separators.NEWLINE;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return encode();
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package cn.skcks.docking.gb28181.sdp;
|
||||
|
||||
import gov.nist.javax.sdp.fields.SDPField;
|
||||
import gov.nist.javax.sdp.parser.Lexer;
|
||||
import gov.nist.javax.sdp.parser.SDPParser;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
public class SsrcFieldParser extends SDPParser {
|
||||
public SsrcFieldParser(String ssrcField) {
|
||||
this.lexer = new Lexer("charLexer", ssrcField);
|
||||
}
|
||||
|
||||
public SsrcField ssrcField() throws ParseException {
|
||||
try {
|
||||
this.lexer.match('y');
|
||||
this.lexer.SPorHT();
|
||||
this.lexer.match('=');
|
||||
this.lexer.SPorHT();
|
||||
|
||||
SsrcField ssrcField = new SsrcField();
|
||||
String rest = lexer.getRest().trim();
|
||||
ssrcField.setSsrc(rest);
|
||||
return ssrcField;
|
||||
} catch (Exception e) {
|
||||
throw lexer.createParseException();
|
||||
}
|
||||
}
|
||||
|
||||
public SDPField parse() throws ParseException {
|
||||
return this.ssrcField();
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package cn.skcks.docking.gb28181.sip.generic;
|
||||
|
||||
import cn.skcks.docking.gb28181.sip.header.XGBVerHeader;
|
||||
import cn.skcks.docking.gb28181.sip.header.impl.XGBVerHeaderImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.sip.SipFactory;
|
||||
import javax.sip.address.Address;
|
||||
import javax.sip.address.AddressFactory;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.header.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class SipBuilder {
|
||||
public static SipFactory getSipFactory(){
|
||||
return SipFactory.getInstance();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static AddressFactory createAddressFactory() {
|
||||
return getSipFactory().createAddressFactory();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static HeaderFactory createHeaderFactory() {
|
||||
return getSipFactory().createHeaderFactory();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String createHostAddress(String ip, int port) {
|
||||
return StringUtils.joinWith(":", ip, port);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static SipURI createSipURI(String id, String address) {
|
||||
return createAddressFactory().createSipURI(id, address);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static Address createAddress(SipURI uri) {
|
||||
return createAddressFactory().createAddress(uri);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static ToHeader createToHeader(Address toAddress, String toTag) {
|
||||
return createHeaderFactory().createToHeader(toAddress, toTag);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static FromHeader createFromHeader(Address fromAddress, String fromTag) {
|
||||
return createHeaderFactory().createFromHeader(fromAddress, fromTag);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static CSeqHeader createCSeqHeader(long cSeq, String method){
|
||||
return createHeaderFactory().createCSeqHeader(cSeq, method);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public static MaxForwardsHeader createMaxForwardsHeader(int maxForwards) {
|
||||
return createHeaderFactory().createMaxForwardsHeader(maxForwards);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static ViaHeader createViaHeader(String ip, int port, String transport, String viaTag){
|
||||
ViaHeader viaHeader = createHeaderFactory().createViaHeader(ip, port, transport, viaTag);
|
||||
viaHeader.setRPort();
|
||||
return viaHeader;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static List<ViaHeader> createViaHeaders(String ip, int port, String transport, String viaTag) {
|
||||
return Collections.singletonList(createViaHeader(ip, port, transport, viaTag));
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public static ContactHeader createContactHeader(Address address){
|
||||
return createHeaderFactory().createContactHeader(address);
|
||||
};
|
||||
|
||||
@SneakyThrows
|
||||
public static ContentTypeHeader createContentTypeHeader(String contentType, String subType){
|
||||
return createHeaderFactory().createContentTypeHeader(contentType, subType);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static ContentTypeHeader createSDPContentTypeHeader(){
|
||||
return createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
|
||||
}
|
||||
|
||||
public static UserAgentHeader createUserAgentHeader(String userAgent){
|
||||
return createUserAgentHeader(Arrays.stream(StringUtils.split(userAgent, StringUtils.SPACE)).toList());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static UserAgentHeader createUserAgentHeader(List<String> product){
|
||||
return createHeaderFactory().createUserAgentHeader(product);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static XGBVerHeader createUserAgentHeader(int m,int n){
|
||||
return new XGBVerHeaderImpl(m,n);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package cn.skcks.docking.gb28181.sip.header;
|
||||
|
||||
import javax.sip.header.Header;
|
||||
|
||||
public interface XGBVerHeader extends Header {
|
||||
public void setVersion(int m, int n);
|
||||
|
||||
public String getVersion();
|
||||
|
||||
public final static String NAME = "X-GB-Ver";
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package cn.skcks.docking.gb28181.sip.header.impl;
|
||||
|
||||
import cn.skcks.docking.gb28181.sip.header.XGBVerHeader;
|
||||
import gov.nist.javax.sip.header.SIPHeader;
|
||||
|
||||
public class XGBVerHeaderImpl extends SIPHeader implements XGBVerHeader {
|
||||
private String version;
|
||||
|
||||
@Override
|
||||
public void setVersion(int m, int n) {
|
||||
this.version = String.format("%d.%d", m, n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public XGBVerHeaderImpl(int m, int n) {
|
||||
super(NAME);
|
||||
setVersion(m, n);
|
||||
}
|
||||
|
||||
public XGBVerHeaderImpl() {
|
||||
super(NAME);
|
||||
}
|
||||
|
||||
protected StringBuilder encodeBody(StringBuilder buffer) {
|
||||
return buffer.append(version);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package cn.skcks.docking.gb28181.sip.request;
|
||||
|
||||
import javax.sip.SipFactory;
|
||||
|
||||
public class SipRequestBuilder {
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package cn.skcks.docking.gb28181.sip.response;
|
||||
|
||||
import javax.sip.SipFactory;
|
||||
|
||||
public class SipResponseBuilder {
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package cn.skcks.docking.gb28181.sdp;
|
||||
|
||||
import gov.nist.javax.sdp.SessionDescriptionImpl;
|
||||
import gov.nist.javax.sdp.fields.TimeField;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.sdp.SdpFactory;
|
||||
import javax.sdp.TimeDescription;
|
||||
import java.util.Vector;
|
||||
|
||||
@Slf4j
|
||||
public class SdpTest {
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void test(){
|
||||
String domain = "4405010000";
|
||||
TimeField timeField = new TimeField();
|
||||
timeField.setZero();
|
||||
TimeDescription timeDescription = SdpFactory.getInstance().createTimeDescription(timeField);
|
||||
GB28181Description gb28181Description = new GB28181Description();
|
||||
gb28181Description.setTimeDescriptions(new Vector<>() {{
|
||||
add(timeDescription);
|
||||
}});
|
||||
gb28181Description.setSsrcField(new SsrcField(String.format("%s%04d", domain.substring(3, 8), 1)));
|
||||
log.info("gb28181 sdp \n{}", gb28181Description);
|
||||
|
||||
GB28181DescriptionParser gb28181DescriptionParser = new GB28181DescriptionParser(gb28181Description.toString());
|
||||
GB28181Description parse = gb28181DescriptionParser.parse();
|
||||
log.info("gb28181 sdp 解析\n{}",parse);
|
||||
|
||||
SessionDescriptionImpl sessionDescription = gb28181Description;
|
||||
sessionDescription.setTimeDescriptions(new Vector<>() {{
|
||||
add(timeDescription);
|
||||
}});
|
||||
gb28181Description = new GB28181Description(sessionDescription);
|
||||
gb28181Description.setTimeDescriptions(new Vector<>() {{
|
||||
add(timeDescription);
|
||||
}});
|
||||
log.info("从 SessionDescriptionImpl 转换为 gb28181 sdp \n{}", gb28181Description);
|
||||
gb28181DescriptionParser = new GB28181DescriptionParser(gb28181Description.toString());
|
||||
parse = gb28181DescriptionParser.parse();
|
||||
log.info("从 SessionDescriptionImpl 转换为 gb28181 sdp 解析\n{}",parse);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package cn.skcks.docking.gb28181.sip;
|
||||
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipBuilder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.sip.address.Address;
|
||||
import javax.sip.address.SipURI;
|
||||
|
||||
@Slf4j
|
||||
public class SipTest {
|
||||
@Test
|
||||
public void test(){
|
||||
String localIp = "127.0.0.1";
|
||||
int localPort = 5060;
|
||||
String localId = "12345678901234567890";
|
||||
String localHostAddress = SipBuilder.createHostAddress(localIp,localPort);
|
||||
SipURI localSipUri = SipBuilder.createSipURI(localId, localHostAddress);
|
||||
|
||||
Address localAddress = SipBuilder.createAddress(localSipUri);
|
||||
log.info("{}", localAddress);
|
||||
}
|
||||
}
|
16
pom.xml
16
pom.xml
@ -22,6 +22,7 @@
|
||||
<module>gb28181-service</module>
|
||||
<module>orm</module>
|
||||
<module>zlmediakit-service</module>
|
||||
<module>gb28181-sip</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
@ -59,6 +60,8 @@
|
||||
<!-- <docker.registry.username>XXX</docker.registry.username>-->
|
||||
<!-- <docker.registry.password>XXX</docker.registry.password>-->
|
||||
<docker.maven.plugin.version>1.4.13</docker.maven.plugin.version>
|
||||
|
||||
<jain-sip.version>1.3.0-91</jain-sip.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
@ -97,6 +100,12 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.skcks.docking.gb28181</groupId>
|
||||
<artifactId>gb28181-sip</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.skcks.docking.gb28181</groupId>
|
||||
<artifactId>annotation</artifactId>
|
||||
@ -121,6 +130,13 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sip协议栈 -->
|
||||
<dependency>
|
||||
<groupId>javax.sip</groupId>
|
||||
<artifactId>jain-sip-ri</artifactId>
|
||||
<version>${jain-sip.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--MapStruct-->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
|
Loading…
Reference in New Issue
Block a user