use of gov.nist.javax.sip.message.SIPMessage in project XobotOS by xamarin.
the class SipProviderImpl method sendResponse.
/*
* (non-Javadoc)
*
* @see javax.sip.SipProvider#sendResponse(javax.sip.message.Response)
*/
public void sendResponse(Response response) throws SipException {
if (!sipStack.isAlive())
throw new SipException("Stack is stopped");
SIPResponse sipResponse = (SIPResponse) response;
Via via = sipResponse.getTopmostVia();
if (via == null)
throw new SipException("No via header in response!");
SIPServerTransaction st = (SIPServerTransaction) sipStack.findTransaction((SIPMessage) response, true);
if (st != null && st.getState() != TransactionState.TERMINATED && this.isAutomaticDialogSupportEnabled()) {
throw new SipException("Transaction exists -- cannot send response statelessly");
}
String transport = via.getTransport();
// check to see if Via has "received paramaeter". If so
// set the host to the via parameter. Else set it to the
// Via host.
String host = via.getReceived();
if (host == null)
host = via.getHost();
// Symmetric nat support
int port = via.getRPort();
if (port == -1) {
port = via.getPort();
if (port == -1) {
if (transport.equalsIgnoreCase("TLS"))
port = 5061;
else
port = 5060;
}
}
// for correct management of IPv6 addresses.
if (host.indexOf(":") > 0)
if (host.indexOf("[") < 0)
host = "[" + host + "]";
Hop hop = sipStack.getAddressResolver().resolveAddress(new HopImpl(host, port, transport));
try {
ListeningPointImpl listeningPoint = (ListeningPointImpl) this.getListeningPoint(transport);
if (listeningPoint == null)
throw new SipException("whoopsa daisy! no listening point found for transport " + transport);
MessageChannel messageChannel = sipStack.createRawMessageChannel(this.getListeningPoint(hop.getTransport()).getIPAddress(), listeningPoint.port, hop);
messageChannel.sendMessage(sipResponse);
} catch (IOException ex) {
throw new SipException(ex.getMessage());
}
}
use of gov.nist.javax.sip.message.SIPMessage in project XobotOS by xamarin.
the class UDPMessageChannel method processIncomingDataPacket.
/**
* Process an incoming datagram
*
* @param packet
* is the incoming datagram packet.
*/
private void processIncomingDataPacket(DatagramPacket packet) throws Exception {
this.peerAddress = packet.getAddress();
int packetLength = packet.getLength();
// Read bytes and put it in a eueue.
byte[] bytes = packet.getData();
byte[] msgBytes = new byte[packetLength];
System.arraycopy(bytes, 0, msgBytes, 0, packetLength);
// Do debug logging.
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("UDPMessageChannel: processIncomingDataPacket : peerAddress = " + peerAddress.getHostAddress() + "/" + packet.getPort() + " Length = " + packetLength);
}
SIPMessage sipMessage = null;
try {
this.receptionTime = System.currentTimeMillis();
sipMessage = myParser.parseSIPMessage(msgBytes);
myParser = null;
} catch (ParseException ex) {
// let go of the parser reference.
myParser = null;
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("Rejecting message ! " + new String(msgBytes));
this.sipStack.getStackLogger().logDebug("error message " + ex.getMessage());
this.sipStack.getStackLogger().logException(ex);
}
// JvB: send a 400 response for requests (except ACK)
// Currently only UDP, @todo also other transports
String msgString = new String(msgBytes, 0, packetLength);
if (!msgString.startsWith("SIP/") && !msgString.startsWith("ACK ")) {
String badReqRes = createBadReqRes(msgString, ex);
if (badReqRes != null) {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("Sending automatic 400 Bad Request:");
sipStack.getStackLogger().logDebug(badReqRes);
}
try {
this.sendMessage(badReqRes.getBytes(), peerAddress, packet.getPort(), "UDP", false);
} catch (IOException e) {
this.sipStack.getStackLogger().logException(e);
}
} else {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("Could not formulate automatic 400 Bad Request");
}
}
}
return;
}
if (sipMessage == null) {
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("Rejecting message ! + Null message parsed.");
}
if (pingBackRecord.get(packet.getAddress().getHostAddress() + ":" + packet.getPort()) == null) {
byte[] retval = "\r\n\r\n".getBytes();
DatagramPacket keepalive = new DatagramPacket(retval, 0, retval.length, packet.getAddress(), packet.getPort());
((UDPMessageProcessor) this.messageProcessor).sock.send(keepalive);
this.sipStack.getTimer().schedule(new PingBackTimerTask(packet.getAddress().getHostAddress(), packet.getPort()), 1000);
}
return;
}
ViaList viaList = sipMessage.getViaHeaders();
// Check for the required headers.
if (sipMessage.getFrom() == null || sipMessage.getTo() == null || sipMessage.getCallId() == null || sipMessage.getCSeq() == null || sipMessage.getViaHeaders() == null) {
String badmsg = new String(msgBytes);
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logError("bad message " + badmsg);
this.sipStack.getStackLogger().logError(">>> Dropped Bad Msg " + "From = " + sipMessage.getFrom() + "To = " + sipMessage.getTo() + "CallId = " + sipMessage.getCallId() + "CSeq = " + sipMessage.getCSeq() + "Via = " + sipMessage.getViaHeaders());
}
return;
}
// For response, just get the port from the packet.
if (sipMessage instanceof SIPRequest) {
Via v = (Via) viaList.getFirst();
Hop hop = sipStack.addressResolver.resolveAddress(v.getHop());
this.peerPort = hop.getPort();
this.peerProtocol = v.getTransport();
this.peerPacketSourceAddress = packet.getAddress();
this.peerPacketSourcePort = packet.getPort();
try {
this.peerAddress = packet.getAddress();
// Check to see if the received parameter matches
// the peer address and tag it appropriately.
boolean hasRPort = v.hasParameter(Via.RPORT);
if (hasRPort || !hop.getHost().equals(this.peerAddress.getHostAddress())) {
v.setParameter(Via.RECEIVED, this.peerAddress.getHostAddress());
}
if (hasRPort) {
v.setParameter(Via.RPORT, Integer.toString(this.peerPacketSourcePort));
}
} catch (java.text.ParseException ex1) {
InternalErrorHandler.handleException(ex1);
}
} else {
this.peerPacketSourceAddress = packet.getAddress();
this.peerPacketSourcePort = packet.getPort();
this.peerAddress = packet.getAddress();
this.peerPort = packet.getPort();
this.peerProtocol = ((Via) viaList.getFirst()).getTransport();
}
this.processMessage(sipMessage);
}
use of gov.nist.javax.sip.message.SIPMessage in project XobotOS by xamarin.
the class StringMsgParser method parseSIPMessage.
/**
* Parse a buffer containing one or more SIP Messages and return an array of
* SIPMessage parsed structures.
*
* @param msgString
* a String 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(String msgString) throws ParseException {
if (msgString == null || msgString.length() == 0)
return null;
rawStringMessage = msgString;
int i = 0;
// Squeeze out any leading control character.
try {
while (msgString.charAt(i) < 0x20) i++;
} catch (ArrayIndexOutOfBoundsException e) {
// Array contains only control char, return null.
return null;
} catch (StringIndexOutOfBoundsException ex) {
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 {
char c = msgString.charAt(i);
while (c != '\r' && c != '\n') c = msgString.charAt(++i);
} catch (ArrayIndexOutOfBoundsException e) {
// End of the message.
break;
} catch (StringIndexOutOfBoundsException ex) {
break;
}
// Make it a String.
currentLine = msgString.substring(lineStart, i);
currentLine = trimEndOfLine(currentLine);
if (currentLine.length() == 0) {
// Last header line, process the previous buffered header.
if (currentHeader != null) {
processHeader(currentHeader, message);
}
} else {
if (isFirstLine) {
message = processFirstLine(currentLine);
} 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) {
processHeader(currentHeader, message);
}
currentHeader = currentLine;
}
}
}
if (msgString.charAt(i) == '\r' && msgString.length() > i + 1 && msgString.charAt(i + 1) == '\n')
i++;
i++;
isFirstLine = false;
} while (currentLine.length() > 0);
message.setSize(i);
// Check for content legth header
if (readBody && message.getContentLength() != null) {
if (message.getContentLength().getContentLength() != 0) {
String body = msgString.substring(i);
message.setMessageContent(body, this.strict, computeContentLengthFromMessage, message.getContentLength().getContentLength());
} else if (!computeContentLengthFromMessage && message.getContentLength().getContentLength() == 0 && !msgString.endsWith("\r\n\r\n")) {
if (strict) {
throw new ParseException("Extraneous characters at the end of the message ", i);
}
}
}
return message;
}
use of gov.nist.javax.sip.message.SIPMessage in project XobotOS by xamarin.
the class StringMsgParser method processFirstLine.
private SIPMessage processFirstLine(String firstLine) 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 (this.parseExceptionListener != null)
this.parseExceptionListener.handleException(ex, message, RequestLine.class, firstLine, rawStringMessage);
else
throw ex;
}
} else {
message = new SIPResponse();
try {
StatusLine sl = new StatusLineParser(firstLine + "\n").parse();
((SIPResponse) message).setStatusLine(sl);
} catch (ParseException ex) {
if (this.parseExceptionListener != null) {
this.parseExceptionListener.handleException(ex, message, StatusLine.class, firstLine, rawStringMessage);
} else
throw ex;
}
}
return message;
}
use of gov.nist.javax.sip.message.SIPMessage in project XobotOS by xamarin.
the class StringMsgParser method main.
/**
* Test code.
*/
public static void main(String[] args) throws ParseException {
String[] messages = { "SIP/2.0 200 OK\r\n" + "To: \"The Little Blister\" <sip:LittleGuy@there.com>;tag=469bc066\r\n" + "From: \"The Master Blaster\" <sip:BigGuy@here.com>;tag=11\r\n" + "Via: SIP/2.0/UDP 139.10.134.246:5060;branch=z9hG4bK8b0a86f6_1030c7d18e0_17;received=139.10.134.246\r\n" + "Call-ID: 1030c7d18ae_a97b0b_b@8b0a86f6\r\n" + "CSeq: 1 SUBSCRIBE\r\n" + "Contact: <sip:172.16.11.162:5070>\r\n" + "Content-Length: 0\r\n\r\n", "SIP/2.0 180 Ringing\r\n" + "Via: SIP/2.0/UDP 172.18.1.29:5060;branch=z9hG4bK43fc10fb4446d55fc5c8f969607991f4\r\n" + "To: \"0440\" <sip:0440@212.209.220.131>;tag=2600\r\n" + "From: \"Andreas\" <sip:andreas@e-horizon.se>;tag=8524\r\n" + "Call-ID: f51a1851c5f570606140f14c8eb64fd3@172.18.1.29\r\n" + "CSeq: 1 INVITE\r\n" + "Max-Forwards: 70\r\n" + "Record-Route: <sip:212.209.220.131:5060>\r\n" + "Content-Length: 0\r\n\r\n", "REGISTER sip:nist.gov SIP/2.0\r\n" + "Via: SIP/2.0/UDP 129.6.55.182:14826\r\n" + "Max-Forwards: 70\r\n" + "From: <sip:mranga@nist.gov>;tag=6fcd5c7ace8b4a45acf0f0cd539b168b;epid=0d4c418ddf\r\n" + "To: <sip:mranga@nist.gov>\r\n" + "Call-ID: c5679907eb954a8da9f9dceb282d7230@129.6.55.182\r\n" + "CSeq: 1 REGISTER\r\n" + "Contact: <sip:129.6.55.182:14826>;methods=\"INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER\"\r\n" + "User-Agent: RTC/(Microsoft RTC)\r\n" + "Event: registration\r\n" + "Allow-Events: presence\r\n" + "Content-Length: 0\r\n\r\n" + "INVITE sip:littleguy@there.com:5060 SIP/2.0\r\n" + "Via: SIP/2.0/UDP 65.243.118.100:5050\r\n" + "From: M. Ranganathan <sip:M.Ranganathan@sipbakeoff.com>;tag=1234\r\n" + "To: \"littleguy@there.com\" <sip:littleguy@there.com:5060> \r\n" + "Call-ID: Q2AboBsaGn9!?x6@sipbakeoff.com \r\n" + "CSeq: 1 INVITE \r\n" + "Content-Length: 247\r\n\r\n" + "v=0\r\n" + "o=4855 13760799956958020 13760799956958020 IN IP4 129.6.55.78\r\n" + "s=mysession session\r\n" + "p=+46 8 52018010\r\n" + "c=IN IP4 129.6.55.78\r\n" + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n" };
class ParserThread implements Runnable {
String[] messages;
public ParserThread(String[] messagesToParse) {
this.messages = messagesToParse;
}
public void run() {
for (int i = 0; i < messages.length; i++) {
StringMsgParser smp = new StringMsgParser();
try {
SIPMessage sipMessage = smp.parseSIPMessage(messages[i]);
System.out.println(" i = " + i + " branchId = " + sipMessage.getTopmostVia().getBranch());
// System.out.println("encoded " +
// sipMessage.toString());
} catch (ParseException ex) {
}
// System.out.println("dialog id = " +
// sipMessage.getDialogId(false));
}
}
}
for (int i = 0; i < 20; i++) {
new Thread(new ParserThread(messages)).start();
}
}
Aggregations