use of gov.nist.javax.sip.message.SIPResponse in project XobotOS by xamarin.
the class DialogFilter method sendBadRequestResponse.
/**
* Send a BAD REQUEST response.
*
* @param sipRequest
* @param transaction
* @param reasonPhrase
*/
private void sendBadRequestResponse(SIPRequest sipRequest, SIPServerTransaction transaction, String reasonPhrase) {
SIPResponse sipResponse = sipRequest.createResponse(Response.BAD_REQUEST);
if (reasonPhrase != null)
sipResponse.setReasonPhrase(reasonPhrase);
ServerHeader serverHeader = MessageFactoryImpl.getDefaultServerHeader();
if (serverHeader != null) {
sipResponse.setHeader(serverHeader);
}
try {
if (sipRequest.getMethod().equals(Request.INVITE)) {
sipStack.addTransactionPendingAck(transaction);
}
transaction.sendResponse(sipResponse);
transaction.releaseSem();
} catch (Exception ex) {
sipStack.getStackLogger().logError("Problem sending error response", ex);
transaction.releaseSem();
sipStack.removeTransaction(transaction);
}
}
use of gov.nist.javax.sip.message.SIPResponse in project XobotOS by xamarin.
the class DialogFilter method sendServerInternalErrorResponse.
/**
* Send back an error Response.
*
* @param sipRequest
* @param transaction
*/
private void sendServerInternalErrorResponse(SIPRequest sipRequest, SIPServerTransaction transaction) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Sending 500 response for out of sequence message");
SIPResponse sipResponse = sipRequest.createResponse(Response.SERVER_INTERNAL_ERROR);
sipResponse.setReasonPhrase("Request out of order");
if (MessageFactoryImpl.getDefaultServerHeader() != null) {
ServerHeader serverHeader = MessageFactoryImpl.getDefaultServerHeader();
sipResponse.setHeader(serverHeader);
}
try {
RetryAfter retryAfter = new RetryAfter();
retryAfter.setRetryAfter(10);
sipResponse.setHeader(retryAfter);
sipStack.addTransactionPendingAck(transaction);
transaction.sendResponse(sipResponse);
transaction.releaseSem();
} catch (Exception ex) {
sipStack.getStackLogger().logError("Problem sending response", ex);
transaction.releaseSem();
sipStack.removeTransaction(transaction);
}
}
use of gov.nist.javax.sip.message.SIPResponse 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.message.SIPResponse in project XobotOS by xamarin.
the class SIPServerTransaction method sendResponse.
/*
* (non-Javadoc)
*
* @see javax.sip.ServerTransaction#sendResponse(javax.sip.message.Response)
*/
public void sendResponse(Response response) throws SipException {
SIPResponse sipResponse = (SIPResponse) response;
SIPDialog dialog = this.dialog;
if (response == null)
throw new NullPointerException("null response");
try {
sipResponse.checkHeaders();
} catch (ParseException ex) {
throw new SipException(ex.getMessage());
}
// check for meaningful response.
if (!sipResponse.getCSeq().getMethod().equals(this.getMethod())) {
throw new SipException("CSeq method does not match Request method of request that created the tx.");
}
/*
* 200-class responses to SUBSCRIBE requests also MUST contain an "Expires" header. The
* period of time in the response MAY be shorter but MUST NOT be longer than specified in
* the request.
*/
if (this.getMethod().equals(Request.SUBSCRIBE) && response.getStatusCode() / 100 == 2) {
if (response.getHeader(ExpiresHeader.NAME) == null) {
throw new SipException("Expires header is mandatory in 2xx response of SUBSCRIBE");
} else {
Expires requestExpires = (Expires) this.getOriginalRequest().getExpires();
Expires responseExpires = (Expires) response.getExpires();
/*
* If no "Expires" header is present in a SUBSCRIBE request, the implied default
* is defined by the event package being used.
*/
if (requestExpires != null && responseExpires.getExpires() > requestExpires.getExpires()) {
throw new SipException("Response Expires time exceeds request Expires time : See RFC 3265 3.1.1");
}
}
}
// Check for mandatory header.
if (sipResponse.getStatusCode() == 200 && sipResponse.getCSeq().getMethod().equals(Request.INVITE) && sipResponse.getHeader(ContactHeader.NAME) == null)
throw new SipException("Contact Header is mandatory for the OK to the INVITE");
if (!this.isMessagePartOfTransaction((SIPMessage) response)) {
throw new SipException("Response does not belong to this transaction.");
}
// Fix up the response if the dialog has already been established.
try {
/*
* The UAS MAY send a final response to the initial request before
* having received PRACKs for all unacknowledged reliable provisional responses,
* unless the final response is 2xx and any of the unacknowledged reliable provisional
* responses contained a session description. In that case, it MUST NOT send a final
* response until those provisional responses are acknowledged.
*/
if (this.pendingReliableResponse != null && this.getDialog() != null && this.getState() != TransactionState.TERMINATED && ((SIPResponse) response).getContentTypeHeader() != null && response.getStatusCode() / 100 == 2 && ((SIPResponse) response).getContentTypeHeader().getContentType().equalsIgnoreCase("application") && ((SIPResponse) response).getContentTypeHeader().getContentSubType().equalsIgnoreCase("sdp")) {
try {
boolean acquired = this.provisionalResponseSem.tryAcquire(1, TimeUnit.SECONDS);
if (!acquired) {
throw new SipException("cannot send response -- unacked povisional");
}
} catch (Exception ex) {
this.sipStack.getStackLogger().logError("Could not acquire PRACK sem ", ex);
}
} else {
// pending response task.
if (this.pendingReliableResponse != null && sipResponse.isFinalResponse()) {
this.provisionalResponseTask.cancel();
this.provisionalResponseTask = null;
}
}
// being sent makes sense.
if (dialog != null) {
if (sipResponse.getStatusCode() / 100 == 2 && sipStack.isDialogCreated(sipResponse.getCSeq().getMethod())) {
if (dialog.getLocalTag() == null && sipResponse.getTo().getTag() == null) {
// Trying to send final response and user forgot to set
// to
// tag on the response -- be nice and assign the tag for
// the user.
sipResponse.getTo().setTag(Utils.getInstance().generateTag());
} else if (dialog.getLocalTag() != null && sipResponse.getToTag() == null) {
sipResponse.setToTag(dialog.getLocalTag());
} else if (dialog.getLocalTag() != null && sipResponse.getToTag() != null && !dialog.getLocalTag().equals(sipResponse.getToTag())) {
throw new SipException("Tag mismatch dialogTag is " + dialog.getLocalTag() + " responseTag is " + sipResponse.getToTag());
}
}
if (!sipResponse.getCallId().getCallId().equals(dialog.getCallId().getCallId())) {
throw new SipException("Dialog mismatch!");
}
}
// Backward compatibility slippery slope....
// Only set the from tag in the response when the
// incoming request has a from tag.
String fromTag = ((SIPRequest) this.getRequest()).getFrom().getTag();
if (fromTag != null && sipResponse.getFromTag() != null && !sipResponse.getFromTag().equals(fromTag)) {
throw new SipException("From tag of request does not match response from tag");
} else if (fromTag != null) {
sipResponse.getFrom().setTag(fromTag);
} else {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("WARNING -- Null From tag in request!!");
}
// or if the state of the dialog needs to be changed.
if (dialog != null && response.getStatusCode() != 100) {
dialog.setResponseTags(sipResponse);
DialogState oldState = dialog.getState();
dialog.setLastResponse(this, (SIPResponse) response);
if (oldState == null && dialog.getState() == DialogState.TERMINATED) {
DialogTerminatedEvent event = new DialogTerminatedEvent(dialog.getSipProvider(), dialog);
// Provide notification to the listener that the dialog has
// ended.
dialog.getSipProvider().handleEvent(event, this);
}
} else if (dialog == null && this.getMethod().equals(Request.INVITE) && this.retransmissionAlertEnabled && this.retransmissionAlertTimerTask == null && response.getStatusCode() / 100 == 2) {
String dialogId = ((SIPResponse) response).getDialogId(true);
this.retransmissionAlertTimerTask = new RetransmissionAlertTimerTask(dialogId);
sipStack.retransmissionAlertTransactions.put(dialogId, this);
sipStack.getTimer().schedule(this.retransmissionAlertTimerTask, 0, SIPTransactionStack.BASE_TIMER_INTERVAL);
}
// Send message after possibly inserting the Dialog
// into the dialog table to avoid a possible race condition.
this.sendMessage((SIPResponse) response);
if (dialog != null) {
dialog.startRetransmitTimer(this, (SIPResponse) response);
}
} catch (IOException ex) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logException(ex);
this.setState(TransactionState.TERMINATED);
raiseErrorEvent(SIPTransactionErrorEvent.TRANSPORT_ERROR);
throw new SipException(ex.getMessage());
} catch (java.text.ParseException ex1) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logException(ex1);
this.setState(TransactionState.TERMINATED);
throw new SipException(ex1.getMessage());
}
}
use of gov.nist.javax.sip.message.SIPResponse in project XobotOS by xamarin.
the class UDPMessageChannel method processMessage.
/**
* Actually proces the parsed message.
*
* @param sipMessage
*/
public void processMessage(SIPMessage sipMessage) {
if (sipMessage instanceof SIPRequest) {
SIPRequest sipRequest = (SIPRequest) sipMessage;
// all processing is OK.
if (sipStack.getStackLogger().isLoggingEnabled(ServerLogger.TRACE_MESSAGES)) {
this.sipStack.serverLogger.logMessage(sipMessage, this.getPeerHostPort().toString(), this.getHost() + ":" + this.myPort, false, receptionTime);
}
ServerRequestInterface sipServerRequest = sipStack.newSIPServerRequest(sipRequest, this);
// Drop it if there is no request returned
if (sipServerRequest == null) {
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logWarning("Null request interface returned -- dropping request");
}
return;
}
if (sipStack.isLoggingEnabled())
this.sipStack.getStackLogger().logDebug("About to process " + sipRequest.getFirstLine() + "/" + sipServerRequest);
try {
sipServerRequest.processRequest(sipRequest, this);
} finally {
if (sipServerRequest instanceof SIPTransaction) {
SIPServerTransaction sipServerTx = (SIPServerTransaction) sipServerRequest;
if (!sipServerTx.passToListener()) {
((SIPTransaction) sipServerRequest).releaseSem();
}
}
}
if (sipStack.isLoggingEnabled())
this.sipStack.getStackLogger().logDebug("Done processing " + sipRequest.getFirstLine() + "/" + sipServerRequest);
// So far so good -- we will commit this message if
// all processing is OK.
} else {
// Handle a SIP Reply message.
SIPResponse sipResponse = (SIPResponse) sipMessage;
try {
sipResponse.checkHeaders();
} catch (ParseException ex) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logError("Dropping Badly formatted response message >>> " + sipResponse);
return;
}
ServerResponseInterface sipServerResponse = sipStack.newSIPServerResponse(sipResponse, this);
if (sipServerResponse != null) {
try {
if (sipServerResponse instanceof SIPClientTransaction && !((SIPClientTransaction) sipServerResponse).checkFromTag(sipResponse)) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logError("Dropping response message with invalid tag >>> " + sipResponse);
return;
}
sipServerResponse.processResponse(sipResponse, this);
} finally {
if (sipServerResponse instanceof SIPTransaction && !((SIPTransaction) sipServerResponse).passToListener())
((SIPTransaction) sipServerResponse).releaseSem();
}
// Normal processing of message.
} else {
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("null sipServerResponse!");
}
}
}
}
Aggregations