From 16657efe0e23eeab02c763ae8db992b23d44db8a Mon Sep 17 00:00:00 2001 From: shikong <919411476@qq.com> Date: Thu, 14 Sep 2023 11:49:56 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=20GB28181=20SDP=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=99=A8=20GB28181DescriptionParser=20GB2818?= =?UTF-8?q?1DescriptionParserFactory=20SsrcFieldParser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gb28181/sdp/GB28181DescriptionParser.java | 97 +++++++++++++++++++ .../sdp/GB28181DescriptionParserFactory.java | 17 ++++ .../core/sip/gb28181/sdp/SsrcFieldParser.java | 34 +++++++ .../request/InviteRequestProcessor.java | 46 +++++++++ 4 files changed, 194 insertions(+) create mode 100644 gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/GB28181DescriptionParser.java create mode 100644 gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/GB28181DescriptionParserFactory.java create mode 100644 gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/SsrcFieldParser.java create mode 100644 gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/invite/request/InviteRequestProcessor.java diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/GB28181DescriptionParser.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/GB28181DescriptionParser.java new file mode 100644 index 0000000..1fca732 --- /dev/null +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/GB28181DescriptionParser.java @@ -0,0 +1,97 @@ +package cn.skcks.docking.gb28181.mocking.core.sip.gb28181.sdp; + +import cn.skcks.docking.gb28181.core.sip.gb28181.sdp.GB28181Description; +import cn.skcks.docking.gb28181.core.sip.gb28181.sdp.SsrcField; +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; + +public class GB28181DescriptionParser extends ParserCore { + protected Lexer lexer; + protected Vector sdpMessage; + + /** Creates new SDPAnnounceParser + * @param sdpMessage Vector of messages to parse. + */ + public GB28181DescriptionParser(Vector sdpMessage) { + this.sdpMessage = sdpMessage; + } + + /** Create a new SDPAnnounceParser. + *@param message string containing the sdp announce message. + * + */ + 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 = GB28181Description.Convertor.convert(new SessionDescriptionImpl()); + 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; + } +} diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/GB28181DescriptionParserFactory.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/GB28181DescriptionParserFactory.java new file mode 100644 index 0000000..693d013 --- /dev/null +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/GB28181DescriptionParserFactory.java @@ -0,0 +1,17 @@ +package cn.skcks.docking.gb28181.mocking.core.sip.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); + } +} diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/SsrcFieldParser.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/SsrcFieldParser.java new file mode 100644 index 0000000..751a195 --- /dev/null +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/gb28181/sdp/SsrcFieldParser.java @@ -0,0 +1,34 @@ +package cn.skcks.docking.gb28181.mocking.core.sip.gb28181.sdp; + +import cn.skcks.docking.gb28181.core.sip.gb28181.sdp.SsrcField; +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(); + } +} diff --git a/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/invite/request/InviteRequestProcessor.java b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/invite/request/InviteRequestProcessor.java new file mode 100644 index 0000000..2792df1 --- /dev/null +++ b/gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/core/sip/message/processor/invite/request/InviteRequestProcessor.java @@ -0,0 +1,46 @@ +package cn.skcks.docking.gb28181.mocking.core.sip.message.processor.invite.request; + +import cn.skcks.docking.gb28181.core.sip.gb28181.sdp.GB28181Description; +import cn.skcks.docking.gb28181.core.sip.listener.SipListener; +import cn.skcks.docking.gb28181.core.sip.message.processor.MessageProcessor; +import cn.skcks.docking.gb28181.core.sip.utils.SipUtil; +import cn.skcks.docking.gb28181.mocking.core.sip.gb28181.sdp.GB28181DescriptionParser; +import gov.nist.javax.sip.message.SIPRequest; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.sip.RequestEvent; +import javax.sip.header.CallIdHeader; +import javax.sip.message.Request; +import java.util.EventObject; + +@Slf4j +@RequiredArgsConstructor +@Component +public class InviteRequestProcessor implements MessageProcessor { + private final SipListener sipListener; + @PostConstruct + @Override + public void init() { + sipListener.addRequestProcessor(Request.INVITE, this); + } + + @SuppressWarnings("Duplicates") + @SneakyThrows + @Override + public void process(EventObject eventObject) { + RequestEvent requestEvent = (RequestEvent) eventObject; + SIPRequest request = (SIPRequest)requestEvent.getRequest(); + String deviceId = SipUtil.getUserIdFromFromHeader(request); + CallIdHeader callIdHeader = request.getCallIdHeader(); + String senderIp = request.getLocalAddress().getHostAddress(); + String content = new String(request.getRawContent()); + log.info("{}", content); + + GB28181Description gb28181Description = new GB28181DescriptionParser(content).parse(); + log.info("{}", gb28181Description); + } +}