创建 SipStack 测试
This commit is contained in:
parent
f0857df86e
commit
84cab3441f
@ -1,4 +1,4 @@
|
||||
package cn.skcks.docking.gb28181.sip.request;
|
||||
package cn.skcks.docking.gb28181.sip.generic;
|
||||
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipContentType;
|
@ -1,8 +1,5 @@
|
||||
package cn.skcks.docking.gb28181.sip.response;
|
||||
package cn.skcks.docking.gb28181.sip.generic;
|
||||
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipContentType;
|
||||
import cn.skcks.docking.gb28181.sip.utils.SipUtil;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import javax.sip.header.*;
|
@ -0,0 +1,79 @@
|
||||
package cn.skcks.docking.gb28181.sip.logger;
|
||||
|
||||
import gov.nist.core.CommonLogger;
|
||||
import gov.nist.core.ServerLogger;
|
||||
import gov.nist.core.StackLogger;
|
||||
import gov.nist.javax.sip.message.SIPMessage;
|
||||
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;
|
||||
|
||||
protected StackLogger stackLogger;
|
||||
|
||||
@Override
|
||||
public void closeLogFile() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logMessage(SIPMessage message, String from, String to, boolean sender, long time) {
|
||||
if (!showLog) {
|
||||
return;
|
||||
}
|
||||
String log = (sender ? "发送: 目标 => " + to : "接收: 来自 => " + from) + "\r\n" + message;
|
||||
this.stackLogger.logInfo(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logMessage(SIPMessage message, String from, String to, String status, boolean sender, long time) {
|
||||
if (!showLog) {
|
||||
return;
|
||||
}
|
||||
String log = (sender ? "发送: 目标 => " + to : "接收: 来自 => " + from) + "\r\n" + message;
|
||||
this.stackLogger.logInfo(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logMessage(SIPMessage message, String from, String to, String status, boolean sender) {
|
||||
if (!showLog) {
|
||||
return;
|
||||
}
|
||||
String log = (sender ? "发送: 目标 => " + to : "接收: 来自 => " + from) + "\r\n" + message;
|
||||
this.stackLogger.logInfo(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logException(Exception ex) {
|
||||
if (!showLog) {
|
||||
return;
|
||||
}
|
||||
this.stackLogger.logException(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStackProperties(Properties stackProperties) {
|
||||
if (!showLog) {
|
||||
return;
|
||||
}
|
||||
String TRACE_LEVEL = stackProperties.getProperty("gov.nist.javax.sip.TRACE_LEVEL");
|
||||
if (TRACE_LEVEL != null) {
|
||||
showLog = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSipStack(SipStack sipStack) {
|
||||
if (!showLog) {
|
||||
return;
|
||||
}
|
||||
if(sipStack instanceof SIPTransactionStack st) {
|
||||
this.stackLogger = CommonLogger.getLogger(st.getClass());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package cn.skcks.docking.gb28181.sip.logger;
|
||||
|
||||
import gov.nist.core.StackLogger;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
@Slf4j
|
||||
@SuppressWarnings("unused")
|
||||
public class StackLoggerImpl implements StackLogger {
|
||||
@Override
|
||||
public void logStackTrace() {}
|
||||
|
||||
@Override
|
||||
public void logStackTrace(int traceLevel) {
|
||||
log.info("traceLevel: " + traceLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logException(Throwable ex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logDebug(String message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logDebug(String message, Exception ex) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logTrace(String message) {
|
||||
log.trace(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logFatalError(String message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logError(String message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggingEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggingEnabled(int logLevel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logError(String message, Exception ex) {
|
||||
log.error(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logWarning(String message) {
|
||||
log.warn(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logInfo(String message) {
|
||||
log.info(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableLogging() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableLogging() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBuildTimeStamp(String buildTimeStamp) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStackProperties(Properties stackProperties) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoggerName() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,436 @@
|
||||
package cn.skcks.docking.gb28181.sip.parser;
|
||||
|
||||
import gov.nist.core.Host;
|
||||
import gov.nist.core.HostNameParser;
|
||||
import gov.nist.javax.sip.SIPConstants;
|
||||
import gov.nist.javax.sip.address.AddressImpl;
|
||||
import gov.nist.javax.sip.address.GenericURI;
|
||||
import gov.nist.javax.sip.address.SipUri;
|
||||
import gov.nist.javax.sip.address.TelephoneNumber;
|
||||
import gov.nist.javax.sip.header.*;
|
||||
import gov.nist.javax.sip.message.SIPMessage;
|
||||
import gov.nist.javax.sip.message.SIPRequest;
|
||||
import gov.nist.javax.sip.message.SIPResponse;
|
||||
import gov.nist.javax.sip.parser.*;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
|
||||
@SuppressWarnings({"unused"})
|
||||
public class GBStringMsgParser implements MessageParser {
|
||||
|
||||
protected static boolean computeContentLengthFromMessage = false;
|
||||
|
||||
/**
|
||||
* @since v0.9
|
||||
*/
|
||||
public GBStringMsgParser() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a buffer containing a single SIP Message where the body is an array
|
||||
* of un-interpreted bytes. This is intended for parsing the message from a
|
||||
* memory buffer when the buffer. Incorporates a bug fix for a bug that was
|
||||
* noted by Will Sullin of Callcast
|
||||
*
|
||||
* @param msgBuffer
|
||||
* a byte buffer containing the messages to be parsed. This can
|
||||
* consist of multiple SIP Messages concatenated together.
|
||||
* @return a SIPMessage[] structure (request or response) containing the
|
||||
* parsed SIP message.
|
||||
* @exception ParseException
|
||||
* is thrown when an illegal message has been encountered
|
||||
* (and the rest of the buffer is discarded).
|
||||
* @see ParseExceptionListener
|
||||
*/
|
||||
public SIPMessage parseSIPMessage(byte[] msgBuffer, boolean readBody, boolean strict, ParseExceptionListener parseExceptionListener) throws ParseException {
|
||||
if (msgBuffer == null || msgBuffer.length == 0)
|
||||
return null;
|
||||
|
||||
int i = 0;
|
||||
|
||||
// Squeeze out any leading control character.
|
||||
try {
|
||||
while (msgBuffer[i] < 0x20)
|
||||
i++;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
// Array contains only control char, return null.
|
||||
return null;
|
||||
}
|
||||
|
||||
// Iterate thru the request/status line and headers.
|
||||
String currentLine = null;
|
||||
String currentHeader = null;
|
||||
boolean isFirstLine = true;
|
||||
SIPMessage message = null;
|
||||
do
|
||||
{
|
||||
int lineStart = i;
|
||||
|
||||
// Find the length of the line.
|
||||
try {
|
||||
while (msgBuffer[i] != '\r' && msgBuffer[i] != '\n')
|
||||
i++;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
// End of the message.
|
||||
break;
|
||||
}
|
||||
int lineLength = i - lineStart;
|
||||
|
||||
// Make it a String.
|
||||
currentLine = new String(msgBuffer, lineStart, lineLength, StandardCharsets.UTF_8);
|
||||
|
||||
currentLine = trimEndOfLine(currentLine);
|
||||
|
||||
if (currentLine.length() == 0) {
|
||||
// Last header line, process the previous buffered header.
|
||||
if (currentHeader != null && message != null) {
|
||||
processHeader(currentHeader, message, parseExceptionListener, msgBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if (isFirstLine) {
|
||||
message = processFirstLine(currentLine, parseExceptionListener, msgBuffer);
|
||||
} else {
|
||||
char firstChar = currentLine.charAt(0);
|
||||
if (firstChar == '\t' || firstChar == ' ') {
|
||||
if (currentHeader == null)
|
||||
throw new ParseException("Bad header continuation.", 0);
|
||||
|
||||
// This is a continuation, append it to the previous line.
|
||||
currentHeader += currentLine.substring(1);
|
||||
}
|
||||
else {
|
||||
if (currentHeader != null && message != null) {
|
||||
processHeader(currentHeader, message, parseExceptionListener, msgBuffer);
|
||||
}
|
||||
currentHeader = currentLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (msgBuffer[i] == '\r' && msgBuffer.length > i+1 && msgBuffer[i+1] == '\n')
|
||||
i++;
|
||||
|
||||
i++;
|
||||
|
||||
isFirstLine = false;
|
||||
} while (currentLine.length() > 0); // End do - while
|
||||
|
||||
if (message == null) throw new ParseException("Bad message", 0);
|
||||
message.setSize(i);
|
||||
|
||||
// Check for content legth header
|
||||
if (readBody && message.getContentLength() != null ) {
|
||||
if ( message.getContentLength().getContentLength() != 0) {
|
||||
int bodyLength = msgBuffer.length - i;
|
||||
|
||||
byte[] body = new byte[bodyLength];
|
||||
System.arraycopy(msgBuffer, i, body, 0, bodyLength);
|
||||
message.setMessageContent(body,!strict,computeContentLengthFromMessage,message.getContentLength().getContentLength());
|
||||
} else if (message.getCSeqHeader().getMethod().equalsIgnoreCase("MESSAGE")) {
|
||||
int bodyLength = msgBuffer.length - i;
|
||||
|
||||
byte[] body = new byte[bodyLength];
|
||||
System.arraycopy(msgBuffer, i, body, 0, bodyLength);
|
||||
message.setMessageContent(body,!strict,computeContentLengthFromMessage,bodyLength);
|
||||
}else if (!computeContentLengthFromMessage && strict) {
|
||||
String last4Chars = new String(msgBuffer, msgBuffer.length - 4, 4);
|
||||
if(!"\r\n\r\n".equals(last4Chars)) {
|
||||
throw new ParseException("Extraneous characters at the end of the message ",i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
protected static String trimEndOfLine(String line) {
|
||||
if (line == null)
|
||||
return null;
|
||||
|
||||
int i = line.length() - 1;
|
||||
while (i >= 0 && line.charAt(i) <= 0x20)
|
||||
i--;
|
||||
|
||||
if (i == line.length() - 1)
|
||||
return line;
|
||||
|
||||
if (i == -1)
|
||||
return "";
|
||||
|
||||
return line.substring(0, i+1);
|
||||
}
|
||||
|
||||
protected SIPMessage processFirstLine(String firstLine, ParseExceptionListener parseExceptionListener, byte[] msgBuffer) throws ParseException {
|
||||
SIPMessage message;
|
||||
if (!firstLine.startsWith(SIPConstants.SIP_VERSION_STRING)) {
|
||||
message = new SIPRequest();
|
||||
try {
|
||||
RequestLine requestLine = new RequestLineParser(firstLine + "\n")
|
||||
.parse();
|
||||
((SIPRequest) message).setRequestLine(requestLine);
|
||||
} catch (ParseException ex) {
|
||||
if (parseExceptionListener != null) {
|
||||
parseExceptionListener.handleException(ex, message,
|
||||
RequestLine.class, firstLine, new String(msgBuffer, StandardCharsets.UTF_8));
|
||||
}
|
||||
else
|
||||
throw ex;
|
||||
|
||||
}
|
||||
} else {
|
||||
message = new SIPResponse();
|
||||
try {
|
||||
StatusLine sl = new StatusLineParser(firstLine + "\n").parse();
|
||||
((SIPResponse) message).setStatusLine(sl);
|
||||
} catch (ParseException ex) {
|
||||
if (parseExceptionListener != null) {
|
||||
parseExceptionListener.handleException(ex, message,
|
||||
StatusLine.class, firstLine, new String(msgBuffer, StandardCharsets.UTF_8));
|
||||
} else
|
||||
throw ex;
|
||||
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
protected void processHeader(String header, SIPMessage message, ParseExceptionListener parseExceptionListener, byte[] rawMessage) throws ParseException {
|
||||
if (header == null || header.length() == 0)
|
||||
return;
|
||||
|
||||
HeaderParser headerParser = null;
|
||||
try {
|
||||
headerParser = ParserFactory.createParser(header + "\n");
|
||||
} catch (ParseException ex) {
|
||||
// https://java.net/jira/browse/JSIP-456
|
||||
if (parseExceptionListener != null) {
|
||||
parseExceptionListener.handleException(ex, message, null,
|
||||
header, null);
|
||||
return;
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
SIPHeader sipHeader = headerParser.parse();
|
||||
message.attachHeader(sipHeader, false);
|
||||
} catch (ParseException ex) {
|
||||
if (parseExceptionListener != null) {
|
||||
String headerName = Lexer.getHeaderName(header);
|
||||
Class<?> headerClass = NameMap.getClassFromName(headerName);
|
||||
if (headerClass == null) {
|
||||
headerClass = ExtensionHeaderImpl.class;
|
||||
|
||||
}
|
||||
parseExceptionListener.handleException(ex, message,
|
||||
headerClass, header, new String(rawMessage, StandardCharsets.UTF_8));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an address (nameaddr or address spec) and return and address
|
||||
* structure.
|
||||
*
|
||||
* @param address
|
||||
* is a String containing the address to be parsed.
|
||||
* @return a parsed address structure.
|
||||
* @since v1.0
|
||||
* @exception ParseException
|
||||
* when the address is badly formatted.
|
||||
*/
|
||||
public AddressImpl parseAddress(String address) throws ParseException {
|
||||
AddressParser addressParser = new AddressParser(address);
|
||||
return addressParser.address(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a host:port and return a parsed structure.
|
||||
*
|
||||
* @param hostport
|
||||
* is a String containing the host:port to be parsed
|
||||
* @return a parsed address structure.
|
||||
* @since v1.0
|
||||
* @exception throws
|
||||
* a ParseException when the address is badly formatted.
|
||||
*
|
||||
public HostPort parseHostPort(String hostport) throws ParseException {
|
||||
Lexer lexer = new Lexer("charLexer", hostport);
|
||||
return new HostNameParser(lexer).hostPort();
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parse a host name and return a parsed structure.
|
||||
*
|
||||
* @param host
|
||||
* is a String containing the host name to be parsed
|
||||
* @return a parsed address structure.
|
||||
* @since v1.0
|
||||
* @exception ParseException
|
||||
* a ParseException when the hostname is badly formatted.
|
||||
*/
|
||||
public Host parseHost(String host) throws ParseException {
|
||||
Lexer lexer = new Lexer("charLexer", host);
|
||||
return new HostNameParser(lexer).host();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a telephone number return a parsed structure.
|
||||
*
|
||||
* @param telephone_number
|
||||
* is a String containing the telephone # to be parsed
|
||||
* @return a parsed address structure.
|
||||
* @since v1.0
|
||||
* @exception ParseException
|
||||
* a ParseException when the address is badly formatted.
|
||||
*/
|
||||
public TelephoneNumber parseTelephoneNumber(String telephone_number)
|
||||
throws ParseException {
|
||||
// Bug fix contributed by Will Scullin
|
||||
return new URLParser(telephone_number).parseTelephoneNumber(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a SIP url from a string and return a URI structure for it.
|
||||
*
|
||||
* @param url
|
||||
* a String containing the URI structure to be parsed.
|
||||
* @return A parsed URI structure
|
||||
* @exception ParseException
|
||||
* if there was an error parsing the message.
|
||||
*/
|
||||
|
||||
public SipUri parseSIPUrl(String url) throws ParseException {
|
||||
try {
|
||||
return new URLParser(url).sipURL(true);
|
||||
} catch (ClassCastException ex) {
|
||||
throw new ParseException(url + " Not a SIP URL ", 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a uri from a string and return a URI structure for it.
|
||||
*
|
||||
* @param url
|
||||
* a String containing the URI structure to be parsed.
|
||||
* @return A parsed URI structure
|
||||
* @exception ParseException
|
||||
* if there was an error parsing the message.
|
||||
*/
|
||||
|
||||
public GenericURI parseUrl(String url) throws ParseException {
|
||||
return new URLParser(url).parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an individual SIP message header from a string.
|
||||
*
|
||||
* @param header
|
||||
* String containing the SIP header.
|
||||
* @return a SIPHeader structure.
|
||||
* @exception ParseException
|
||||
* if there was an error parsing the message.
|
||||
*/
|
||||
public static SIPHeader parseSIPHeader(String header) throws ParseException {
|
||||
int start = 0;
|
||||
int end = header.length() - 1;
|
||||
try {
|
||||
// Squeeze out any leading control character.
|
||||
while (header.charAt(start) <= 0x20)
|
||||
start++;
|
||||
|
||||
// Squeeze out any trailing control character.
|
||||
while (header.charAt(end) <= 0x20)
|
||||
end--;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
// Array contains only control char.
|
||||
throw new ParseException("Empty header.", 0);
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder(end + 1);
|
||||
int i = start;
|
||||
int lineStart = start;
|
||||
boolean endOfLine = false;
|
||||
while (i <= end) {
|
||||
char c = header.charAt(i);
|
||||
if (c == '\r' || c == '\n') {
|
||||
if (!endOfLine) {
|
||||
buffer.append(header, lineStart, i);
|
||||
endOfLine = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (endOfLine) {
|
||||
endOfLine = false;
|
||||
if (c == ' ' || c == '\t') {
|
||||
buffer.append(' ');
|
||||
lineStart = i + 1;
|
||||
}
|
||||
else {
|
||||
lineStart = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
buffer.append(header, lineStart, i);
|
||||
buffer.append('\n');
|
||||
|
||||
HeaderParser hp = ParserFactory.createParser(buffer.toString());
|
||||
if (hp == null)
|
||||
throw new ParseException("could not create parser", 0);
|
||||
return hp.parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the SIP Request Line
|
||||
*
|
||||
* @param requestLine
|
||||
* a String containing the request line to be parsed.
|
||||
* @return a RequestLine structure that has the parsed RequestLine
|
||||
* @exception ParseException
|
||||
* if there was an error parsing the requestLine.
|
||||
*/
|
||||
|
||||
public RequestLine parseSIPRequestLine(String requestLine)
|
||||
throws ParseException {
|
||||
requestLine += "\n";
|
||||
return new RequestLineParser(requestLine).parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the SIP Response message status line
|
||||
*
|
||||
* @param statusLine
|
||||
* a String containing the Status line to be parsed.
|
||||
* @return StatusLine class corresponding to message
|
||||
* @exception ParseException
|
||||
* if there was an error parsing
|
||||
* @see StatusLine
|
||||
*/
|
||||
|
||||
public StatusLine parseSIPStatusLine(String statusLine)
|
||||
throws ParseException {
|
||||
statusLine += "\n";
|
||||
return new StatusLineParser(statusLine).parse();
|
||||
}
|
||||
|
||||
public static void setComputeContentLengthFromMessage(
|
||||
boolean computeContentLengthFromMessage) {
|
||||
GBStringMsgParser.computeContentLengthFromMessage = computeContentLengthFromMessage;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.skcks.docking.gb28181.sip.parser;
|
||||
|
||||
import gov.nist.javax.sip.parser.MessageParser;
|
||||
import gov.nist.javax.sip.parser.MessageParserFactory;
|
||||
import gov.nist.javax.sip.stack.SIPTransactionStack;
|
||||
|
||||
public class GbStringMsgParserFactory implements MessageParserFactory {
|
||||
|
||||
/**
|
||||
* msg parser is completely stateless, reuse instance for the whole stack
|
||||
* fixes https://github.com/RestComm/jain-sip/issues/92
|
||||
*/
|
||||
private static final GBStringMsgParser msgParser = new GBStringMsgParser();
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see gov.nist.javax.sip.parser.MessageParserFactory#createMessageParser(gov.nist.javax.sip.stack.SIPTransactionStack)
|
||||
*/
|
||||
public MessageParser createMessageParser(SIPTransactionStack stack) {
|
||||
return msgParser;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package cn.skcks.docking.gb28181.sip.property;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 获取sip默认配置
|
||||
*/
|
||||
public class DefaultProperties {
|
||||
|
||||
public static Properties getProperties(String name,String stackLoggerFQN,String serverLoggerFQN) {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("javax.sip.STACK_NAME", name);
|
||||
// properties.setProperty("javax.sip.IP_ADDRESS", ip);
|
||||
// 关闭自动会话
|
||||
properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off");
|
||||
/**
|
||||
* 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码
|
||||
* gov/nist/javax/sip/SipStackImpl.class
|
||||
* sip消息的解析在 gov.nist.javax.sip.stack.UDPMessageChannel的processIncomingDataPacket方法
|
||||
*/
|
||||
|
||||
// * gov/nist/javax/sip/SipStackImpl.class
|
||||
// 接收所有notify请求,即使没有订阅
|
||||
properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
|
||||
properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
|
||||
properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "true");
|
||||
// 为_NULL _对话框传递_终止的_事件
|
||||
properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");
|
||||
// 是否自动计算content length的实际长度,默认不计算
|
||||
properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
|
||||
// 会话清理策略
|
||||
properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal");
|
||||
// 处理由该服务器处理的基于底层TCP的保持生存超时
|
||||
properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
|
||||
// 获取实际内容长度,不使用header中的长度信息
|
||||
properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
|
||||
// 线程可重入
|
||||
properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true");
|
||||
// 定义应用程序打算多久审计一次 SIP 堆栈,了解其内部线程的健康状况(该属性指定连续审计之间的时间(以毫秒为单位))
|
||||
properties.setProperty("gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS", "30000");
|
||||
|
||||
// properties.setProperty("gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", "gov.nist.javax.sip.stack.NioMessageProcessorFactory");
|
||||
|
||||
/**
|
||||
* sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
|
||||
*/
|
||||
properties.setProperty("gov.nist.javax.sip.STACK_LOGGER", stackLoggerFQN);
|
||||
properties.setProperty("gov.nist.javax.sip.SERVER_LOGGER", serverLoggerFQN);
|
||||
properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
|
||||
return properties;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package cn.skcks.docking.gb28181.sip.request;
|
||||
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipRequestBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.utils.SipUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.sip.address.Address;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.message.Request;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class RegisterRequestBuilder {
|
||||
private static final String method = Request.REGISTER;
|
||||
private String localIp;
|
||||
private int localPort;
|
||||
private String localId;
|
||||
private String targetIp;
|
||||
private int targetPort;
|
||||
private String targetId;
|
||||
|
||||
private String transport;
|
||||
|
||||
public Request createNoAuthorizationRequest(String callId) {
|
||||
String local = SipBuilder.createHostAddress(localIp, localPort);
|
||||
Address localAddress = SipBuilder.createAddress(SipBuilder.createSipURI(localId, local));
|
||||
String target = SipBuilder.createHostAddress(targetIp, targetPort);
|
||||
SipURI targetUri = SipBuilder.createSipURI(targetId, target);
|
||||
|
||||
return SipRequestBuilder.createRequest(targetUri, method,
|
||||
SipBuilder.createCallIdHeader(callId),
|
||||
SipBuilder.createCSeqHeader(1L, method),
|
||||
SipBuilder.createFromHeader(localAddress, SipUtil.generateFromTag()),
|
||||
SipBuilder.createToHeader(localAddress),
|
||||
SipBuilder.createViaHeaders(targetIp, targetPort, transport, SipUtil.generateViaTag()),
|
||||
SipBuilder.createMaxForwardsHeader(70));
|
||||
}
|
||||
}
|
@ -4,8 +4,8 @@ import cn.skcks.docking.gb28181.constant.GB28181Constant;
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.header.XGBVerHeader;
|
||||
import cn.skcks.docking.gb28181.sip.header.impl.XGBVerHeaderImpl;
|
||||
import cn.skcks.docking.gb28181.sip.request.SipRequestBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.response.SipResponseBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipRequestBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipResponseBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.utils.SipUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -1,18 +1,51 @@
|
||||
package cn.skcks.docking.gb28181.sip.process;
|
||||
|
||||
import cn.skcks.docking.gb28181.sip.generic.SipBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.parser.GbStringMsgParserFactory;
|
||||
import cn.skcks.docking.gb28181.sip.property.DefaultProperties;
|
||||
import cn.skcks.docking.gb28181.sip.request.RegisterRequestBuilder;
|
||||
import cn.skcks.docking.gb28181.sip.utils.SipUtil;
|
||||
import gov.nist.javax.sip.SipStackImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.sip.ListeningPoint;
|
||||
import javax.sip.SipProvider;
|
||||
import javax.sip.header.UserAgentHeader;
|
||||
import javax.sip.message.Request;
|
||||
|
||||
@Slf4j
|
||||
public class RequestTest {
|
||||
String localIp = "127.0.0.1";
|
||||
int localPort = 5060;
|
||||
String localId = "00000000000000000001";
|
||||
|
||||
String remoteIp = "10.10.10.200";
|
||||
int remotePort = 5060;
|
||||
String remoteId = "00000000000000000002";
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void test(){
|
||||
SipUtil.setUserAgentVersion("0.1.0");
|
||||
UserAgentHeader userAgentHeader = SipBuilder.userAgentHeader;
|
||||
log.info("\n{}",userAgentHeader);
|
||||
|
||||
SipStackImpl sipStack = (SipStackImpl) SipBuilder.getSipFactory()
|
||||
.createSipStack(DefaultProperties.getProperties(
|
||||
SipUtil.UserAgent,
|
||||
"cn.skcks.docking.gb28181.sip.logger.StackLoggerImpl",
|
||||
"cn.skcks.docking.gb28181.sip.logger.ServerLoggerImpl"));
|
||||
sipStack.setMessageParserFactory(new GbStringMsgParserFactory());
|
||||
ListeningPoint listeningPoint = sipStack.createListeningPoint("127.0.0.1", 5060, ListeningPoint.UDP);
|
||||
SipProvider sipProvider = sipStack.createSipProvider(listeningPoint);
|
||||
String callId = sipProvider.getNewCallId().getCallId();
|
||||
|
||||
RegisterRequestBuilder registerRequestBuilder = new RegisterRequestBuilder(localIp, localPort, localId, remoteIp, remotePort, remoteId, ListeningPoint.UDP);
|
||||
Request noAuthorizationRequest = registerRequestBuilder.createNoAuthorizationRequest(callId);
|
||||
log.info("\n{}",noAuthorizationRequest);
|
||||
sipStack.deleteSipProvider(sipProvider);
|
||||
sipStack.deleteListeningPoint(listeningPoint);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user