Search in sources :

Example 1 with DialogState

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");
        }
    }
}
Also used : DialogState(javax.sip.DialogState) ReplicationStrategy(org.mobicents.ha.javax.sip.ReplicationStrategy) ClusteredSipStack(org.mobicents.ha.javax.sip.ClusteredSipStack)

Example 2 with DialogState

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);
        }
    }
}
Also used : DialogState(javax.sip.DialogState) ReplicationStrategy(org.mobicents.ha.javax.sip.ReplicationStrategy) ClusteredSipStack(org.mobicents.ha.javax.sip.ClusteredSipStack) SipCacheException(org.mobicents.ha.javax.sip.cache.SipCacheException)

Example 3 with DialogState

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());
    }
}
Also used : DialogState(javax.sip.DialogState) IOException(java.io.IOException) ParseException(java.text.ParseException) SipException(javax.sip.SipException) IOException(java.io.IOException) ObjectInUseException(javax.sip.ObjectInUseException) SIPResponse(gov.nist.javax.sip.message.SIPResponse) DialogTerminatedEvent(javax.sip.DialogTerminatedEvent) SIPMessage(gov.nist.javax.sip.message.SIPMessage) ParseException(java.text.ParseException) Expires(gov.nist.javax.sip.header.Expires) SipException(javax.sip.SipException) ParseException(java.text.ParseException)

Example 4 with DialogState

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;
}
Also used : DialogState(javax.sip.DialogState) Iterator(java.util.Iterator) CallIdHeader(javax.sip.header.CallIdHeader) LinkedList(java.util.LinkedList)

Example 5 with DialogState

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();
    }
}
Also used : ContactHeader(javax.sip.header.ContactHeader) RouteHeader(javax.sip.header.RouteHeader) RecordRouteHeader(javax.sip.header.RecordRouteHeader) DialogState(javax.sip.DialogState) FromHeader(javax.sip.header.FromHeader) ClientTransaction(javax.sip.ClientTransaction) Request(javax.sip.message.Request) SipURI(javax.sip.address.SipURI) InvalidArgumentException(javax.sip.InvalidArgumentException) ParseException(java.text.ParseException) SipException(javax.sip.SipException) ListeningPointExt(gov.nist.javax.sip.ListeningPointExt) Random(java.util.Random) ViaHeader(javax.sip.header.ViaHeader) Dialog(javax.sip.Dialog) ServerTransaction(javax.sip.ServerTransaction)

Aggregations

DialogState (javax.sip.DialogState)5 ParseException (java.text.ParseException)2 SipException (javax.sip.SipException)2 ClusteredSipStack (org.mobicents.ha.javax.sip.ClusteredSipStack)2 ReplicationStrategy (org.mobicents.ha.javax.sip.ReplicationStrategy)2 ListeningPointExt (gov.nist.javax.sip.ListeningPointExt)1 Expires (gov.nist.javax.sip.header.Expires)1 SIPMessage (gov.nist.javax.sip.message.SIPMessage)1 SIPResponse (gov.nist.javax.sip.message.SIPResponse)1 IOException (java.io.IOException)1 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1 Random (java.util.Random)1 ClientTransaction (javax.sip.ClientTransaction)1 Dialog (javax.sip.Dialog)1 DialogTerminatedEvent (javax.sip.DialogTerminatedEvent)1 InvalidArgumentException (javax.sip.InvalidArgumentException)1 ObjectInUseException (javax.sip.ObjectInUseException)1 ServerTransaction (javax.sip.ServerTransaction)1 SipURI (javax.sip.address.SipURI)1