自定义 GB28181 SDP 解析器

GB28181DescriptionParser
GB28181DescriptionParserFactory
SsrcFieldParser
This commit is contained in:
shikong 2023-09-14 11:49:56 +08:00
parent 2e8d5fc3f7
commit 16657efe0e
4 changed files with 194 additions and 0 deletions

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}