use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class SIPClientTransaction method sendRequest.
/*
* (non-Javadoc)
*
* @see javax.sip.ClientTransaction#sendRequest()
*/
public void sendRequest() throws SipException {
SIPRequest sipRequest = this.getOriginalRequest();
if (this.getState() != null)
throw new SipException("Request already sent");
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("sendRequest() " + sipRequest);
}
try {
sipRequest.checkHeaders();
} catch (ParseException ex) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logError("missing required header");
throw new SipException(ex.getMessage());
}
if (getMethod().equals(Request.SUBSCRIBE) && sipRequest.getHeader(ExpiresHeader.NAME) == null) {
/*
* If no "Expires" header is present in a SUBSCRIBE request, the implied default is
* defined by the event package being used.
*
*/
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logWarning("Expires header missing in outgoing subscribe --" + " Notifier will assume implied value on event package");
}
try {
/*
* This check is removed because it causes problems for load balancers ( See issue
* 136) reported by Raghav Ramesh ( BT )
*
*/
if (this.getOriginalRequest().getMethod().equals(Request.CANCEL) && sipStack.isCancelClientTransactionChecked()) {
SIPClientTransaction ct = (SIPClientTransaction) sipStack.findCancelTransaction(this.getOriginalRequest(), false);
if (ct == null) {
/*
* If the original request has generated a final response, the CANCEL SHOULD
* NOT be sent, as it is an effective no-op, since CANCEL has no effect on
* requests that have already generated a final response.
*/
throw new SipException("Could not find original tx to cancel. RFC 3261 9.1");
} else if (ct.getState() == null) {
throw new SipException("State is null no provisional response yet -- cannot cancel RFC 3261 9.1");
} else if (!ct.getMethod().equals(Request.INVITE)) {
throw new SipException("Cannot cancel non-invite requests RFC 3261 9.1");
}
} else if (this.getOriginalRequest().getMethod().equals(Request.BYE) || this.getOriginalRequest().getMethod().equals(Request.NOTIFY)) {
SIPDialog dialog = sipStack.getDialog(this.getOriginalRequest().getDialogId(false));
// Dialog
if (this.getSipProvider().isAutomaticDialogSupportEnabled() && dialog != null) {
throw new SipException("Dialog is present and AutomaticDialogSupport is enabled for " + " the provider -- Send the Request using the Dialog.sendRequest(transaction)");
}
}
// Only map this after the fist request is sent out.
if (this.getMethod().equals(Request.INVITE)) {
SIPDialog dialog = this.getDefaultDialog();
if (dialog != null && dialog.isBackToBackUserAgent()) {
// Block sending re-INVITE till we see the ACK.
if (!dialog.takeAckSem()) {
throw new SipException("Failed to take ACK semaphore");
}
}
}
this.isMapped = true;
this.sendMessage(sipRequest);
} catch (IOException ex) {
this.setState(TransactionState.TERMINATED);
throw new SipException("IO Error sending request", ex);
}
}
use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class SIPDialog method addTransaction.
/**
* Add a transaction record to the dialog.
*
* @param transaction is the transaction to add to the dialog.
*/
public void addTransaction(SIPTransaction transaction) {
SIPRequest sipRequest = (SIPRequest) transaction.getOriginalRequest();
// Proessing a re-invite.
if (firstTransactionSeen && !firstTransactionId.equals(transaction.getBranchId()) && transaction.getMethod().equals(firstTransactionMethod)) {
this.reInviteFlag = true;
}
if (firstTransactionSeen == false) {
// Record the local and remote sequenc
// numbers and the from and to tags for future
// use on this dialog.
storeFirstTransactionInfo(this, transaction);
if (sipRequest.getMethod().equals(Request.SUBSCRIBE))
this.eventHeader = (EventHeader) sipRequest.getHeader(EventHeader.NAME);
this.setLocalParty(sipRequest);
this.setRemoteParty(sipRequest);
this.setCallId(sipRequest);
if (this.originalRequest == null) {
this.originalRequest = sipRequest;
}
if (this.method == null) {
this.method = sipRequest.getMethod();
}
if (transaction instanceof SIPServerTransaction) {
this.hisTag = sipRequest.getFrom().getTag();
// My tag is assigned when sending response
} else {
setLocalSequenceNumber(sipRequest.getCSeq().getSeqNumber());
this.originalLocalSequenceNumber = localSequenceNumber;
this.myTag = sipRequest.getFrom().getTag();
if (myTag == null)
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logError("The request's From header is missing the required Tag parameter.");
}
} else if (transaction.getMethod().equals(firstTransactionMethod) && firstTransactionIsServerTransaction != transaction.isServerTransaction()) {
// This case occurs when you are processing a re-invite.
// Switch from client side to server side for re-invite
// (put the other side on hold).
storeFirstTransactionInfo(this, transaction);
this.setLocalParty(sipRequest);
this.setRemoteParty(sipRequest);
this.setCallId(sipRequest);
this.originalRequest = sipRequest;
this.method = sipRequest.getMethod();
}
if (transaction instanceof SIPServerTransaction)
setRemoteSequenceNumber(sipRequest.getCSeq().getSeqNumber());
// If this is a server transaction record the remote
// sequence number to avoid re-processing of requests
// with the same sequence number directed towards this
// dialog.
this.lastTransaction = transaction;
// transaction.setDialog(this,sipRequest);
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("Transaction Added " + this + myTag + "/" + hisTag);
sipStack.getStackLogger().logDebug("TID = " + transaction.getTransactionId() + "/" + transaction.isServerTransaction());
sipStack.getStackLogger().logStackTrace();
}
}
use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class SIPDialog method handleAck.
/**
* Do the necessary processing to handle an ACK directed at this Dialog.
*
* @param ackTransaction -- the ACK transaction that was directed at this dialog.
* @return -- true if the ACK was successfully consumed by the Dialog and resulted in the
* dialog state being changed.
*/
public boolean handleAck(SIPServerTransaction ackTransaction) {
SIPRequest sipRequest = ackTransaction.getOriginalRequest();
if (isAckSeen() && getRemoteSeqNumber() == sipRequest.getCSeq().getSeqNumber()) {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("ACK already seen by dialog -- dropping Ack" + " retransmission");
}
acquireTimerTaskSem();
try {
if (this.timerTask != null) {
this.timerTask.cancel();
this.timerTask = null;
}
} finally {
releaseTimerTaskSem();
}
return false;
} else if (this.getState() == DialogState.TERMINATED) {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("Dialog is terminated -- dropping ACK");
return false;
} else {
/*
* This could be a re-invite processing. check to see if the ack matches with the last
* transaction. s
*/
SIPServerTransaction tr = getInviteTransaction();
SIPResponse sipResponse = (tr != null ? tr.getLastResponse() : null);
// Idiot check for sending ACK from the wrong side!
if (tr != null && sipResponse != null && sipResponse.getStatusCode() / 100 == 2 && sipResponse.getCSeq().getMethod().equals(Request.INVITE) && sipResponse.getCSeq().getSeqNumber() == sipRequest.getCSeq().getSeqNumber()) {
ackTransaction.setDialog(this, sipResponse.getDialogId(false));
/*
* record that we already saw an ACK for this dialog.
*/
ackReceived(sipRequest);
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("ACK for 2XX response --- sending to TU ");
return true;
} else {
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug(" INVITE transaction not found -- Discarding ACK");
return false;
}
}
}
use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.
the class SIPTransactionStack method addTransactionHash.
/**
* Hash table for quick lookup of transactions. Here we wait for room if needed.
*/
private void addTransactionHash(SIPTransaction sipTransaction) {
SIPRequest sipRequest = sipTransaction.getOriginalRequest();
if (sipTransaction instanceof SIPClientTransaction) {
if (!this.unlimitedClientTransactionTableSize) {
if (this.activeClientTransactionCount.get() > clientTransactionTableHiwaterMark) {
try {
synchronized (this.clientTransactionTable) {
this.clientTransactionTable.wait();
this.activeClientTransactionCount.incrementAndGet();
}
} catch (Exception ex) {
if (stackLogger.isLoggingEnabled()) {
stackLogger.logError("Exception occured while waiting for room", ex);
}
}
}
} else {
this.activeClientTransactionCount.incrementAndGet();
}
String key = sipRequest.getTransactionId();
clientTransactionTable.put(key, (SIPClientTransaction) sipTransaction);
if (stackLogger.isLoggingEnabled()) {
stackLogger.logDebug(" putTransactionHash : " + " key = " + key);
}
} else {
String key = sipRequest.getTransactionId();
if (stackLogger.isLoggingEnabled()) {
stackLogger.logDebug(" putTransactionHash : " + " key = " + key);
}
serverTransactionTable.put(key, (SIPServerTransaction) sipTransaction);
}
}
use of gov.nist.javax.sip.message.SIPRequest 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