Package javax.sip

Examples of javax.sip.SipException


     */
    public void sendRequest() throws SipException {
        SIPRequest sipRequest = this.getOriginalRequest();

        if (this.getInternalState() >= 0)
            throw new SipException("Request already sent");

        if (sipStack.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
            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.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.getInternalState() < 0) {
                    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.getMethod().equals(Request.BYE)
                    || this.getMethod().equals(Request.NOTIFY)) {
                SIPDialog dialog = sipStack.getDialog(this.getOriginalRequest()
                        .getDialogId(false));
                // I want to behave like a user agent so send the BYE using the
                // 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;
         // Time extracted from the Expires header.
            int expiresTime = -1;

           if ( sipRequest.getHeader(ExpiresHeader.NAME) != null ) {
                Expires expires = (Expires) sipRequest.getHeader(ExpiresHeader.NAME);
                expiresTime = expires.getExpires();
            }
            // This is a User Agent. The user has specified an Expires time. Start a timer
            // which will check if the tx is terminated by that time.
            if ( this.getDefaultDialog() != null  &&  getMethod().equals(Request.INVITE) &&
                    expiresTime != -1 && expiresTimerTask == null ) {
                this.expiresTimerTask = new ExpiresTimerTask();
                sipStack.getTimer().schedule(expiresTimerTask, expiresTime * 1000);
               
            }
            this.sendMessage(sipRequest);
           

        } catch (IOException ex) {
            this.setState(TransactionState._TERMINATED);
            if ( this.expiresTimerTask != null ) {
                sipStack.getTimer().cancel(this.expiresTimerTask);
            }
            throw new SipException(
                    ex.getMessage() == null ? "IO Error sending request" : ex.getMessage(),
                    ex);
        }

    }
View Full Code Here


     * @see javax.sip.ClientTransaction#createCancel()
     */
    public Request createCancel() throws SipException {
        SIPRequest originalRequest = this.getOriginalRequest();
        if (originalRequest == null)
            throw new SipException("Bad state " + getState());
        if (!originalRequest.getMethod().equals(Request.INVITE))
            throw new SipException("Only INIVTE may be cancelled");

        if (originalRequest.getMethod().equalsIgnoreCase(Request.ACK))
            throw new SipException("Cannot Cancel ACK!");
        else {
            SIPRequest cancelRequest = originalRequest.createCancelRequest();
            cancelRequest.setInviteTransaction(this);
            return cancelRequest;
        }
View Full Code Here

     * Note that this is different from an ACK for 2xx
     */
    private final Request createErrorAck() throws SipException, ParseException {
        SIPRequest originalRequest = this.getOriginalRequest();
        if (originalRequest == null)
            throw new SipException("bad state " + getState());
        if (!getMethod().equals(Request.INVITE)) {
            throw new SipException("Can only ACK an INVITE!");
        } else if (lastResponse == null) {
            throw new SipException("bad Transaction state");
        } else if (lastResponse.getStatusCode() < 200) {
            if (sipStack.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
                sipStack.getStackLogger().logDebug("lastResponse = " + lastResponse);
            }
            throw new SipException("Cannot ACK a provisional response!");
        }
        return originalRequest.createErrorAck((To) lastResponse.getTo());
    }
View Full Code Here

            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")) {
                if (!interlockProvisionalResponses ) {
                    throw new SipException("cannot send response -- unacked povisional");
                } else {           
                    try {
                       boolean acquired = this.provisionalResponseSem.tryAcquire(1,TimeUnit.SECONDS);
                       if (!acquired ) {
                           throw new SipException("cannot send response -- unacked povisional");
                       }
                    } catch (InterruptedException ex) {
                        sipStack.getStackLogger().logError ("Interrupted acuqiring PRACK sem");
                        throw new SipException("Cannot aquire PRACK sem");
                    }
                 
                }
            } else {
                // Sending the final response cancels the
                // pending response task.
                if (this.pendingReliableResponse != null && sipResponse.isFinalResponse()) {
                    this.provisionalResponseTask.cancel();
                    this.provisionalResponseTask = null;
                }
            }

            // Dialog checks. These make sure that the response
            // 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) {
                      if ( sipStack.getStackLogger().isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
                        sipStack.getStackLogger().logDebug("assigning toTag : serverTransaction = " + this + " dialog "
                            + dialog + " tag = " + dialog.getLocalTag());
                      }
                        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(LogWriter.TRACE_DEBUG))
                    sipStack.getStackLogger().logDebug("WARNING -- Null From tag in request!!");
            }



            // See if the dialog needs to be inserted into the dialog table
            // 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());
        }
    }
View Full Code Here

         * 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. Cannot send a second provisional.
            this.lastResponse = (SIPResponse) relResponse;
            if ( this.getDialog() != null  && interlockProvisionalResponses ) {
                boolean acquired = this.provisionalResponseSem.tryAcquire(1, TimeUnit.SECONDS);
                if (!acquired) {
                    throw new SipException("Unacknowledged reliable response");
                }
            }
            //moved the task scheduling before the sending of the message to overcome
            // Issue 265 : https://jain-sip.dev.java.net/issues/show_bug.cgi?id=265
            this.provisionalResponseTask = new ProvisionalResponseTask();
View Full Code Here

     * @see javax.sip.ServerTransaction#enableRetransmissionAlerts()
     */

    public void enableRetransmissionAlerts() throws SipException {
        if (this.getDialog() != null)
            throw new SipException("Dialog associated with tx");

        else if (!this.getMethod().equals(Request.INVITE))
            throw new SipException("Request Method must be INVITE");

        this.retransmissionAlertEnabled = true;

    }
View Full Code Here

     */
    public void sendRequest() throws SipException {
        SIPRequest sipRequest = this.getOriginalRequest();

        if (this.getState() != null)
            throw new SipException("Request already sent");

        if (sipStack.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
            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));
                // I want to behave like a user agent so send the BYE using the
                // 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;
            int expiresTime = -1;
            if ( sipRequest.getHeader(ExpiresHeader.NAME) != null ) {
                Expires expires = (Expires) sipRequest.getHeader(ExpiresHeader.NAME);
                expiresTime = expires.getExpires();
            }
            // This is a User Agent. The user has specified an Expires time. Start a timer
            // which will check if the tx is terminated by that time.
            if ( this.getDefaultDialog() != null  &&  getMethod().equals(Request.INVITE) &&
                    expiresTime != -1 && expiresTimerTask == null ) {
                this.expiresTimerTask = new ExpiresTimerTask();
                sipStack.getTimer().schedule(expiresTimerTask, expiresTime * 1000);
               
            }
            this.sendMessage(sipRequest);

        } catch (IOException ex) {
            this.setState(TransactionState.TERMINATED);
            throw new SipException(
                    ex.getMessage() == null ? "IO Error sending request" : ex.getMessage(),
                    ex);
        }

    }
View Full Code Here

     * @see javax.sip.ClientTransaction#createCancel()
     */
    public Request createCancel() throws SipException {
        SIPRequest originalRequest = this.getOriginalRequest();
        if (originalRequest == null)
            throw new SipException("Bad state " + getState());
        if (!originalRequest.getMethod().equals(Request.INVITE))
            throw new SipException("Only INIVTE may be cancelled");

        if (originalRequest.getMethod().equalsIgnoreCase(Request.ACK))
            throw new SipException("Cannot Cancel ACK!");
        else {
            SIPRequest cancelRequest = originalRequest.createCancelRequest();
            cancelRequest.setInviteTransaction(this);
            return cancelRequest;
        }
View Full Code Here

     * @see javax.sip.ClientTransaction#createAck()
     */
    public Request createAck() throws SipException {
        SIPRequest originalRequest = this.getOriginalRequest();
        if (originalRequest == null)
            throw new SipException("bad state " + getState());
        if (getMethod().equalsIgnoreCase(Request.ACK)) {
            throw new SipException("Cannot ACK an ACK!");
        } else if (lastResponse == null) {
            throw new SipException("bad Transaction state");
        } else if (lastResponse.getStatusCode() < 200) {
            if (sipStack.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
                sipStack.getStackLogger().logDebug("lastResponse = " + lastResponse);
            }
            throw new SipException("Cannot ACK a provisional response!");
        }
        SIPRequest ackRequest = originalRequest.createAckRequest((To) lastResponse.getTo());
        // Pull the record route headers from the last reesponse.
        RecordRouteList recordRouteList = lastResponse.getRecordRouteHeaders();
        if (recordRouteList == null) {
View Full Code Here

     * Note that this is different from an ACK for 2xx
     */
    private final Request createErrorAck() throws SipException, ParseException {
        SIPRequest originalRequest = this.getOriginalRequest();
        if (originalRequest == null)
            throw new SipException("bad state " + getState());
        if (!getMethod().equals(Request.INVITE)) {
            throw new SipException("Can only ACK an INVITE!");
        } else if (lastResponse == null) {
            throw new SipException("bad Transaction state");
        } else if (lastResponse.getStatusCode() < 200) {
            if (sipStack.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
                sipStack.getStackLogger().logDebug("lastResponse = " + lastResponse);
            }
            throw new SipException("Cannot ACK a provisional response!");
        }
        return originalRequest.createErrorAck((To) lastResponse.getTo());
    }
View Full Code Here

TOP

Related Classes of javax.sip.SipException

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.