use of gov.nist.javax.sip.header.RSeq in project XobotOS by xamarin.
the class SIPServerTransaction method sendReliableProvisionalResponse.
protected void sendReliableProvisionalResponse(Response relResponse) throws SipException {
/*
* After the first reliable provisional response for a request has been acknowledged, the
* UAS MAY send additional reliable provisional responses. The UAS MUST NOT send a second
* reliable provisional response until the first is acknowledged.
*/
if (this.pendingReliableResponse != null) {
throw new SipException("Unacknowledged response");
} else
this.pendingReliableResponse = (SIPResponse) relResponse;
/*
* In addition, it MUST contain a Require header field containing the option tag 100rel,
* and MUST include an RSeq header field.
*/
RSeq rseq = (RSeq) relResponse.getHeader(RSeqHeader.NAME);
if (relResponse.getHeader(RSeqHeader.NAME) == null) {
rseq = new RSeq();
relResponse.setHeader(rseq);
}
try {
this.rseqNumber++;
rseq.setSeqNumber(this.rseqNumber);
// start the timer task which will retransmit the reliable response
// until the PRACK is received
this.lastResponse = (SIPResponse) relResponse;
if (this.getDialog() != null) {
boolean acquired = this.provisionalResponseSem.tryAcquire(1, TimeUnit.SECONDS);
if (!acquired) {
throw new SipException("Unacknowledged response");
}
}
this.sendMessage((SIPMessage) relResponse);
this.provisionalResponseTask = new ProvisionalResponseTask();
this.sipStack.getTimer().schedule(provisionalResponseTask, 0, SIPTransactionStack.BASE_TIMER_INTERVAL);
} catch (Exception ex) {
InternalErrorHandler.handleException(ex);
}
}
use of gov.nist.javax.sip.header.RSeq in project XobotOS by xamarin.
the class SIPDialog method createPrack.
/*
* (non-Javadoc) Retransmissions of the reliable provisional response cease when a matching
* PRACK is received by the UA core. PRACK is like any other request within a dialog, and the
* UAS core processes it according to the procedures of Sections 8.2 and 12.2.2 of RFC 3261. A
* matching PRACK is defined as one within the same dialog as the response, and whose method,
* CSeq-num, and response-num in the RAck header field match, respectively, the method from
* the CSeq, the sequence number from the CSeq, and the sequence number from the RSeq of the
* reliable provisional response.
*
* @see javax.sip.Dialog#createPrack(javax.sip.message.Response)
*/
public Request createPrack(Response relResponse) throws DialogDoesNotExistException, SipException {
if (this.getState() == null || this.getState().equals(DialogState.TERMINATED))
throw new DialogDoesNotExistException("Dialog not initialized or terminated");
if ((RSeq) relResponse.getHeader(RSeqHeader.NAME) == null) {
throw new SipException("Missing RSeq Header");
}
try {
SIPResponse sipResponse = (SIPResponse) relResponse;
SIPRequest sipRequest = (SIPRequest) this.createRequest(Request.PRACK, (SIPResponse) relResponse);
String toHeaderTag = sipResponse.getTo().getTag();
sipRequest.setToTag(toHeaderTag);
RAck rack = new RAck();
RSeq rseq = (RSeq) relResponse.getHeader(RSeqHeader.NAME);
rack.setMethod(sipResponse.getCSeq().getMethod());
rack.setCSequenceNumber((int) sipResponse.getCSeq().getSeqNumber());
rack.setRSequenceNumber(rseq.getSeqNumber());
sipRequest.setHeader(rack);
return (Request) sipRequest;
} catch (Exception ex) {
InternalErrorHandler.handleException(ex);
return null;
}
}
use of gov.nist.javax.sip.header.RSeq in project XobotOS by xamarin.
the class SIPDialog method handlePrack.
/**
* Do the processing necessary for the PRACK
*
* @param prackRequest
* @return true if this is the first time the tx has seen the prack ( and hence needs to be
* passed up to the TU)
*/
public boolean handlePrack(SIPRequest prackRequest) {
/*
* The RAck header is sent in a PRACK request to support reliability of provisional
* responses. It contains two numbers and a method tag. The first number is the value from
* the RSeq header in the provisional response that is being acknowledged. The next
* number, and the method, are copied from the CSeq in the response that is being
* acknowledged. The method name in the RAck header is case sensitive.
*/
if (!this.isServer()) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Dropping Prack -- not a server Dialog");
return false;
}
SIPServerTransaction sipServerTransaction = (SIPServerTransaction) this.getFirstTransaction();
SIPResponse sipResponse = sipServerTransaction.getReliableProvisionalResponse();
if (sipResponse == null) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Dropping Prack -- ReliableResponse not found");
return false;
}
RAck rack = (RAck) prackRequest.getHeader(RAckHeader.NAME);
if (rack == null) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Dropping Prack -- rack header not found");
return false;
}
CSeq cseq = (CSeq) sipResponse.getCSeq();
if (!rack.getMethod().equals(cseq.getMethod())) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Dropping Prack -- CSeq Header does not match PRACK");
return false;
}
if (rack.getCSeqNumberLong() != cseq.getSeqNumber()) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Dropping Prack -- CSeq Header does not match PRACK");
return false;
}
RSeq rseq = (RSeq) sipResponse.getHeader(RSeqHeader.NAME);
if (rack.getRSequenceNumber() != rseq.getSeqNumber()) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Dropping Prack -- RSeq Header does not match PRACK");
return false;
}
return sipServerTransaction.prackRecieved();
}
use of gov.nist.javax.sip.header.RSeq in project XobotOS by xamarin.
the class SIPDialog method createReliableProvisionalResponse.
/*
* (non-Javadoc)
*
* @see javax.sip.Dialog#createReliableProvisionalResponse(int)
*/
public Response createReliableProvisionalResponse(int statusCode) throws InvalidArgumentException, SipException {
if (!(firstTransactionIsServerTransaction)) {
throw new SipException("Not a Server Dialog!");
}
/*
* A UAS MUST NOT attempt to send a 100 (Trying) response reliably. Only provisional
* responses numbered 101 to 199 may be sent reliably. If the request did not include
* either a Supported or Require header field indicating this feature, the UAS MUST NOT
* send the provisional response reliably.
*/
if (statusCode <= 100 || statusCode > 199)
throw new InvalidArgumentException("Bad status code ");
SIPRequest request = this.originalRequest;
if (!request.getMethod().equals(Request.INVITE))
throw new SipException("Bad method");
ListIterator<SIPHeader> list = request.getHeaders(SupportedHeader.NAME);
if (list == null || !optionPresent(list, "100rel")) {
list = request.getHeaders(RequireHeader.NAME);
if (list == null || !optionPresent(list, "100rel")) {
throw new SipException("No Supported/Require 100rel header in the request");
}
}
SIPResponse response = request.createResponse(statusCode);
/*
* The provisional response to be sent reliably is constructed by the UAS core according
* to the procedures of Section 8.2.6 of RFC 3261. In addition, it MUST contain a Require
* header field containing the option tag 100rel, and MUST include an RSeq header field.
* The value of the header field for the first reliable provisional response in a
* transaction MUST be between 1 and 2**31 - 1. It is RECOMMENDED that it be chosen
* uniformly in this range. The RSeq numbering space is within a single transaction. This
* means that provisional responses for different requests MAY use the same values for the
* RSeq number.
*/
Require require = new Require();
try {
require.setOptionTag("100rel");
} catch (Exception ex) {
InternalErrorHandler.handleException(ex);
}
response.addHeader(require);
RSeq rseq = new RSeq();
/*
* set an arbitrary sequence number. This is actually set when the response is sent out
*/
rseq.setSeqNumber(1L);
/*
* Copy the record route headers from the request to the response ( Issue 160 ). Note that
* other 1xx headers do not get their Record Route headers copied over but reliable
* provisional responses do. See RFC 3262 Table 2.
*/
RecordRouteList rrl = request.getRecordRouteHeaders();
if (rrl != null) {
RecordRouteList rrlclone = (RecordRouteList) rrl.clone();
response.setHeader(rrlclone);
}
return response;
}
Aggregations