use of javax.sip.DialogState in project jain-sip.ha by RestComm.
the class AbstractHASipDialog method setState.
@Override
public void setState(int state) {
DialogState oldState = this.getState();
super.setState(state);
final ReplicationStrategy replicationStrategy = ((ClusteredSipStack) getStack()).getReplicationStrategy();
if (replicationStrategy == ReplicationStrategy.EarlyDialog && (oldState == null || oldState.getValue() != state)) {
dialogStateChanged = true;
if (logger.isLoggingEnabled(StackLogger.TRACE_DEBUG)) {
logger.logDebug("dialogStateChanged");
}
}
}
use of javax.sip.DialogState in project jain-sip.ha by RestComm.
the class ConfirmedNoAppDataReplicationSipDialog method replicateState.
/*
*
*/
protected void replicateState() {
final DialogState dialogState = getState();
final ReplicationStrategy replicationStrategy = ((ClusteredSipStack) getStack()).getReplicationStrategy();
boolean replicationStateVsDialogStateOK = false;
if (logger.isLoggingEnabled(StackLogger.TRACE_DEBUG)) {
logger.logDebug("dialogState = " + dialogState + ", replicationStrategy = " + replicationStrategy);
}
if (dialogState == DialogState.CONFIRMED && (replicationStrategy == ReplicationStrategy.ConfirmedDialog || replicationStrategy == ReplicationStrategy.ConfirmedDialogNoApplicationData)) {
replicationStateVsDialogStateOK = true;
}
if ((dialogState == DialogState.EARLY || dialogState == DialogState.CONFIRMED || // Added as part of https://github.com/Mobicents/jain-sip.ha/pull/1
dialogState == DialogState.TERMINATED) && replicationStrategy == ReplicationStrategy.EarlyDialog) {
replicationStateVsDialogStateOK = true;
}
if (replicationStateVsDialogStateOK && isCreated && super.dialogId != null && isRemoteTagSet() && isLocalTagSet() && getStack().getDialog(getDialogIdToReplicate()) != null) {
try {
((ClusteredSipStack) getStack()).getSipCache().putDialog(this);
} catch (SipCacheException e) {
logger.logError("problem storing dialog " + getDialogId() + " into the distributed cache", e);
}
}
}
use of javax.sip.DialogState 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 javax.sip.DialogState in project XobotOS by xamarin.
the class SIPTransactionStack method auditDialogs.
/**
* Audits SIP dialogs for leaks - Compares the dialogs in the dialogTable with a list of Call
* IDs passed by the application. - Dialogs that are not known by the application are leak
* suspects. - Kill the dialogs that are still around after the timer specified.
*
* @return Audit report, null if no dialog leaks were found
*/
private String auditDialogs(Set activeCallIDs, long leakedDialogTimer) {
String auditReport = " Leaked dialogs:\n";
int leakedDialogs = 0;
long currentTime = System.currentTimeMillis();
// Make a shallow copy of the dialog list.
// This copy will remain intact as leaked dialogs are removed by the
// stack.
LinkedList dialogs;
synchronized (dialogTable) {
dialogs = new LinkedList(dialogTable.values());
}
// Iterate through the dialogDialog, get the callID of each dialog and
// check if it's in the
// list of active calls passed by the application. If it isn't, start
// the timer on it.
// If the timer has expired, kill the dialog.
Iterator it = dialogs.iterator();
while (it.hasNext()) {
// Get the next dialog
SIPDialog itDialog = (SIPDialog) it.next();
// Get the call id associated with this dialog
CallIdHeader callIdHeader = (itDialog != null ? itDialog.getCallId() : null);
String callID = (callIdHeader != null ? callIdHeader.getCallId() : null);
// Check if the application knows about this call id
if (itDialog != null && callID != null && !activeCallIDs.contains(callID)) {
// Application doesn't know anything about this dialog...
if (itDialog.auditTag == 0) {
// Mark this dialog as suspect
itDialog.auditTag = currentTime;
} else {
// time's up.
if (currentTime - itDialog.auditTag >= leakedDialogTimer) {
// Leaked dialog found
leakedDialogs++;
// Generate report
DialogState dialogState = itDialog.getState();
String dialogReport = "dialog id: " + itDialog.getDialogId() + ", dialog state: " + (dialogState != null ? dialogState.toString() : "null");
auditReport += " " + dialogReport + "\n";
// Kill it
itDialog.setState(SIPDialog.TERMINATED_STATE);
if (stackLogger.isLoggingEnabled())
stackLogger.logDebug("auditDialogs: leaked " + dialogReport);
}
}
}
}
// Return final report
if (leakedDialogs > 0) {
auditReport += " Total: " + Integer.toString(leakedDialogs) + " leaked dialogs detected and removed.\n";
} else {
auditReport = null;
}
return auditReport;
}
use of javax.sip.DialogState in project load-balancer by RestComm.
the class BackToBackUserAgent method processRequest.
public void processRequest(RequestEvent requestEvent) {
try {
Request request = requestEvent.getRequest();
if (request.getMethod().equals(Request.INVITE)) {
ServerTransaction st = sp.getNewServerTransaction(requestEvent.getRequest());
incomingDialog = st.getDialog();
try {
replyToRequestEvent(requestEvent.getRequest(), st, Response.TRYING);
Request newRequest = (Request) request.clone();
newRequest.removeHeader(RouteHeader.NAME);
newRequest.removeHeader(RecordRouteHeader.NAME);
FromHeader fromHeader = (FromHeader) newRequest.getHeader(FromHeader.NAME);
fromHeader.setTag(Long.toString(Math.abs(new Random().nextLong())));
ViaHeader viaHeader = ((ListeningPointExt) sp.getListeningPoint(transport)).createViaHeader();
newRequest.setHeader(viaHeader);
ContactHeader contactHeader = ((ListeningPointExt) sp.getListeningPoint(transport)).createContactHeader();
newRequest.setHeader(contactHeader);
SipURI route = this.protocolObjects.addressFactory.createSipURI("lbint", lbAddress + ":" + lbPort);
route.setParameter("node_host", "127.0.0.1");
route.setParameter("node_port", "" + port);
route.setLrParam();
RouteHeader routeHeader = (RouteHeader) this.protocolObjects.headerFactory.createRouteHeader(this.protocolObjects.addressFactory.createAddress(route));
newRequest.setHeader(routeHeader);
clientTransaction = sp.getNewClientTransaction(newRequest);
outgoingDialog = clientTransaction.getDialog();
clientTransaction.setApplicationData(st);
clientTransaction.sendRequest();
} catch (Throwable e) {
e.printStackTrace();
replyToRequestEvent(request, st, Response.SERVICE_UNAVAILABLE);
}
} else if (request.getMethod().equals(Request.BYE)) {
ServerTransaction st = requestEvent.getServerTransaction();
replyToRequestEvent(requestEvent.getRequest(), st, Response.OK);
Dialog peerDialog = getPeerDialog(requestEvent.getDialog());
Request outgoingRequest = peerDialog.createRequest(requestEvent.getRequest().getMethod());
final ClientTransaction ct = sp.getNewClientTransaction(outgoingRequest);
peerDialog.sendRequest(ct);
} else if (request.getMethod().equals(Request.CANCEL)) {
try {
final Dialog peerDialog = outgoingDialog;
final DialogState peerDialogState = peerDialog.getState();
if (peerDialogState == null || peerDialogState == DialogState.EARLY) {
Request cancelRequest = clientTransaction.createCancel();
sp.sendRequest(cancelRequest);
} else {
clientTransaction = sp.getNewClientTransaction(peerDialog.createRequest(Request.BYE));
clientTransaction.sendRequest();
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
Aggregations