Search in sources :

Example 11 with SIPRequest

use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.

the class SIPDialog method createAck.

/*
     * (non-Javadoc) The UAC core MUST generate an ACK request for each 2xx received from the
     * transaction layer. The header fields of the ACK are constructed in the same way as for any
     * request sent within a dialog (see Section 12) with the exception of the CSeq and the header
     * fields related to authentication. The sequence number of the CSeq header field MUST be the
     * same as the INVITE being acknowledged, but the CSeq method MUST be ACK. The ACK MUST
     * contain the same credentials as the INVITE. If the 2xx contains an offer (based on the
     * rules above), the ACK MUST carry an answer in its body. If the offer in the 2xx response is
     * not acceptable, the UAC core MUST generate a valid answer in the ACK and then send a BYE
     * immediately.
     * 
     * Note that for the case of forked requests, you can create multiple outgoing invites each
     * with a different cseq and hence you need to supply the invite.
     * 
     * @see javax.sip.Dialog#createAck(long)
     */
public Request createAck(long cseqno) throws InvalidArgumentException, SipException {
    // then send INVITE+ACK later on
    if (!method.equals(Request.INVITE))
        throw new SipException("Dialog was not created with an INVITE" + method);
    if (cseqno <= 0)
        throw new InvalidArgumentException("bad cseq <= 0 ");
    else if (cseqno > ((((long) 1) << 32) - 1))
        throw new InvalidArgumentException("bad cseq > " + ((((long) 1) << 32) - 1));
    if (this.remoteTarget == null) {
        throw new SipException("Cannot create ACK - no remote Target!");
    }
    if (this.sipStack.isLoggingEnabled()) {
        this.sipStack.getStackLogger().logDebug("createAck " + this + " cseqno " + cseqno);
    }
    // out of order ACK sending. Old ACKs seqno's can always be ACKed.
    if (lastInviteOkReceived < cseqno) {
        if (sipStack.isLoggingEnabled()) {
            this.sipStack.getStackLogger().logDebug("WARNING : Attempt to crete ACK without OK " + this);
            this.sipStack.getStackLogger().logDebug("LAST RESPONSE = " + this.lastResponse);
        }
        throw new SipException("Dialog not yet established -- no OK response!");
    }
    try {
        // JvB: Transport from first entry in route set, or remote Contact
        // if none
        // Only used to find correct LP & create correct Via
        SipURI uri4transport = null;
        if (this.routeList != null && !this.routeList.isEmpty()) {
            Route r = (Route) this.routeList.getFirst();
            uri4transport = ((SipURI) r.getAddress().getURI());
        } else {
            // should be !=null, checked above
            uri4transport = ((SipURI) this.remoteTarget.getURI());
        }
        String transport = uri4transport.getTransportParam();
        if (transport == null) {
            // JvB fix: also support TLS
            transport = uri4transport.isSecure() ? ListeningPoint.TLS : ListeningPoint.UDP;
        }
        ListeningPointImpl lp = (ListeningPointImpl) sipProvider.getListeningPoint(transport);
        if (lp == null) {
            if (sipStack.isLoggingEnabled()) {
                sipStack.getStackLogger().logError("remoteTargetURI " + this.remoteTarget.getURI());
                sipStack.getStackLogger().logError("uri4transport = " + uri4transport);
                sipStack.getStackLogger().logError("No LP found for transport=" + transport);
            }
            throw new SipException("Cannot create ACK - no ListeningPoint for transport towards next hop found:" + transport);
        }
        SIPRequest sipRequest = new SIPRequest();
        sipRequest.setMethod(Request.ACK);
        sipRequest.setRequestURI((SipUri) getRemoteTarget().getURI().clone());
        sipRequest.setCallId(this.callIdHeader);
        sipRequest.setCSeq(new CSeq(cseqno, Request.ACK));
        List<Via> vias = new ArrayList<Via>();
        // Via via = lp.getViaHeader();
        // The user may have touched the sentby for the response.
        // so use the via header extracted from the response for the ACK =>
        // https://jain-sip.dev.java.net/issues/show_bug.cgi?id=205
        // strip the params from the via of the response and use the params from the
        // original request
        Via via = this.lastResponse.getTopmostVia();
        via.removeParameters();
        if (originalRequest != null && originalRequest.getTopmostVia() != null) {
            NameValueList originalRequestParameters = originalRequest.getTopmostVia().getParameters();
            if (originalRequestParameters != null && originalRequestParameters.size() > 0) {
                via.setParameters((NameValueList) originalRequestParameters.clone());
            }
        }
        // new branch
        via.setBranch(Utils.getInstance().generateBranchId());
        vias.add(via);
        sipRequest.setVia(vias);
        From from = new From();
        from.setAddress(this.localParty);
        from.setTag(this.myTag);
        sipRequest.setFrom(from);
        To to = new To();
        to.setAddress(this.remoteParty);
        if (hisTag != null)
            to.setTag(this.hisTag);
        sipRequest.setTo(to);
        sipRequest.setMaxForwards(new MaxForwards(70));
        if (this.originalRequest != null) {
            Authorization authorization = this.originalRequest.getAuthorization();
            if (authorization != null)
                sipRequest.setHeader(authorization);
        }
        // ACKs for 2xx responses
        // use the Route values learned from the Record-Route of the 2xx
        // responses.
        this.updateRequest(sipRequest);
        return sipRequest;
    } catch (Exception ex) {
        InternalErrorHandler.handleException(ex);
        throw new SipException("unexpected exception ", ex);
    }
}
Also used : ListeningPointImpl(gov.nist.javax.sip.ListeningPointImpl) CSeq(gov.nist.javax.sip.header.CSeq) NameValueList(gov.nist.core.NameValueList) ArrayList(java.util.ArrayList) MaxForwards(gov.nist.javax.sip.header.MaxForwards) From(gov.nist.javax.sip.header.From) SipURI(javax.sip.address.SipURI) SIPRequest(gov.nist.javax.sip.message.SIPRequest) DialogDoesNotExistException(javax.sip.DialogDoesNotExistException) InvalidArgumentException(javax.sip.InvalidArgumentException) ParseException(java.text.ParseException) ObjectInUseException(javax.sip.ObjectInUseException) SipException(javax.sip.SipException) IOException(java.io.IOException) TransactionDoesNotExistException(javax.sip.TransactionDoesNotExistException) Via(gov.nist.javax.sip.header.Via) Authorization(gov.nist.javax.sip.header.Authorization) InvalidArgumentException(javax.sip.InvalidArgumentException) To(gov.nist.javax.sip.header.To) SipException(javax.sip.SipException) RecordRoute(gov.nist.javax.sip.header.RecordRoute) Route(gov.nist.javax.sip.header.Route)

Example 12 with SIPRequest

use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.

the class SIPDialog method sendAck.

/**
     * Sends ACK Request to the remote party of this Dialogue.
     * 
     * 
     * @param request the new ACK Request message to send.
     * @param throwIOExceptionAsSipException - throws SipException if IOEx encountered. Otherwise,
     *        no exception is propagated.
     * @param releaseAckSem - release ack semaphore.
     * @throws SipException if implementation cannot send the ACK Request for any other reason
     * 
     */
private void sendAck(Request request, boolean throwIOExceptionAsSipException) throws SipException {
    SIPRequest ackRequest = (SIPRequest) request;
    if (sipStack.isLoggingEnabled())
        sipStack.getStackLogger().logDebug("sendAck" + this);
    if (!ackRequest.getMethod().equals(Request.ACK))
        throw new SipException("Bad request method -- should be ACK");
    if (this.getState() == null || this.getState().getValue() == EARLY_STATE) {
        if (sipStack.isLoggingEnabled()) {
            sipStack.getStackLogger().logError("Bad Dialog State for " + this + " dialogID = " + this.getDialogId());
        }
        throw new SipException("Bad dialog state " + this.getState());
    }
    if (!this.getCallId().getCallId().equals(((SIPRequest) request).getCallId().getCallId())) {
        if (sipStack.isLoggingEnabled()) {
            sipStack.getStackLogger().logError("CallID " + this.getCallId());
            sipStack.getStackLogger().logError("RequestCallID = " + ackRequest.getCallId().getCallId());
            sipStack.getStackLogger().logError("dialog =  " + this);
        }
        throw new SipException("Bad call ID in request");
    }
    try {
        if (sipStack.isLoggingEnabled()) {
            sipStack.getStackLogger().logDebug("setting from tag For outgoing ACK= " + this.getLocalTag());
            sipStack.getStackLogger().logDebug("setting To tag for outgoing ACK = " + this.getRemoteTag());
            sipStack.getStackLogger().logDebug("ack = " + ackRequest);
        }
        if (this.getLocalTag() != null)
            ackRequest.getFrom().setTag(this.getLocalTag());
        if (this.getRemoteTag() != null)
            ackRequest.getTo().setTag(this.getRemoteTag());
    } catch (ParseException ex) {
        throw new SipException(ex.getMessage());
    }
    Hop hop = sipStack.getNextHop(ackRequest);
    // Hop hop = defaultRouter.getNextHop(ackRequest);
    if (hop == null)
        throw new SipException("No route!");
    try {
        if (sipStack.isLoggingEnabled())
            sipStack.getStackLogger().logDebug("hop = " + hop);
        ListeningPointImpl lp = (ListeningPointImpl) this.sipProvider.getListeningPoint(hop.getTransport());
        if (lp == null)
            throw new SipException("No listening point for this provider registered at " + hop);
        InetAddress inetAddress = InetAddress.getByName(hop.getHost());
        MessageChannel messageChannel = lp.getMessageProcessor().createMessageChannel(inetAddress, hop.getPort());
        boolean releaseAckSem = false;
        long cseqNo = ((SIPRequest) request).getCSeq().getSeqNumber();
        if (!this.isAckSent(cseqNo)) {
            releaseAckSem = true;
        }
        this.setLastAckSent(ackRequest);
        messageChannel.sendMessage(ackRequest);
        // Sent atleast one ACK.
        this.isAcknowledged = true;
        this.highestSequenceNumberAcknowledged = Math.max(this.highestSequenceNumberAcknowledged, ((SIPRequest) ackRequest).getCSeq().getSeqNumber());
        if (releaseAckSem && this.isBackToBackUserAgent) {
            this.releaseAckSem();
        } else {
            if (sipStack.isLoggingEnabled()) {
                sipStack.getStackLogger().logDebug("Not releasing ack sem for " + this + " isAckSent " + releaseAckSem);
            }
        }
    } catch (IOException ex) {
        if (throwIOExceptionAsSipException)
            throw new SipException("Could not send ack", ex);
        this.raiseIOException(hop.getHost(), hop.getPort(), hop.getTransport());
    } catch (SipException ex) {
        if (sipStack.isLoggingEnabled())
            sipStack.getStackLogger().logException(ex);
        throw ex;
    } catch (Exception ex) {
        if (sipStack.isLoggingEnabled())
            sipStack.getStackLogger().logException(ex);
        throw new SipException("Could not create message channel", ex);
    }
    if (this.dialogDeleteTask != null) {
        this.dialogDeleteTask.cancel();
        this.dialogDeleteTask = null;
    }
    this.ackSeen = true;
}
Also used : ListeningPointImpl(gov.nist.javax.sip.ListeningPointImpl) Hop(javax.sip.address.Hop) ParseException(java.text.ParseException) IOException(java.io.IOException) SipException(javax.sip.SipException) SIPRequest(gov.nist.javax.sip.message.SIPRequest) InetAddress(java.net.InetAddress) DialogDoesNotExistException(javax.sip.DialogDoesNotExistException) InvalidArgumentException(javax.sip.InvalidArgumentException) ParseException(java.text.ParseException) ObjectInUseException(javax.sip.ObjectInUseException) SipException(javax.sip.SipException) IOException(java.io.IOException) TransactionDoesNotExistException(javax.sip.TransactionDoesNotExistException)

Example 13 with SIPRequest

use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.

the class SIPDialog method createPrack.

/*
     * (non-Javadoc) Retransmissions of the reliable provisional response cease when a matching
     * PRACK is received by the UA core. PRACK is like any other request within a dialog, and the
     * UAS core processes it according to the procedures of Sections 8.2 and 12.2.2 of RFC 3261. A
     * matching PRACK is defined as one within the same dialog as the response, and whose method,
     * CSeq-num, and response-num in the RAck header field match, respectively, the method from
     * the CSeq, the sequence number from the CSeq, and the sequence number from the RSeq of the
     * reliable provisional response.
     * 
     * @see javax.sip.Dialog#createPrack(javax.sip.message.Response)
     */
public Request createPrack(Response relResponse) throws DialogDoesNotExistException, SipException {
    if (this.getState() == null || this.getState().equals(DialogState.TERMINATED))
        throw new DialogDoesNotExistException("Dialog not initialized or terminated");
    if ((RSeq) relResponse.getHeader(RSeqHeader.NAME) == null) {
        throw new SipException("Missing RSeq Header");
    }
    try {
        SIPResponse sipResponse = (SIPResponse) relResponse;
        SIPRequest sipRequest = (SIPRequest) this.createRequest(Request.PRACK, (SIPResponse) relResponse);
        String toHeaderTag = sipResponse.getTo().getTag();
        sipRequest.setToTag(toHeaderTag);
        RAck rack = new RAck();
        RSeq rseq = (RSeq) relResponse.getHeader(RSeqHeader.NAME);
        rack.setMethod(sipResponse.getCSeq().getMethod());
        rack.setCSequenceNumber((int) sipResponse.getCSeq().getSeqNumber());
        rack.setRSequenceNumber(rseq.getSeqNumber());
        sipRequest.setHeader(rack);
        return (Request) sipRequest;
    } catch (Exception ex) {
        InternalErrorHandler.handleException(ex);
        return null;
    }
}
Also used : SIPResponse(gov.nist.javax.sip.message.SIPResponse) RAck(gov.nist.javax.sip.header.RAck) Request(javax.sip.message.Request) SIPRequest(gov.nist.javax.sip.message.SIPRequest) DialogDoesNotExistException(javax.sip.DialogDoesNotExistException) RSeq(gov.nist.javax.sip.header.RSeq) SipException(javax.sip.SipException) SIPRequest(gov.nist.javax.sip.message.SIPRequest) DialogDoesNotExistException(javax.sip.DialogDoesNotExistException) InvalidArgumentException(javax.sip.InvalidArgumentException) ParseException(java.text.ParseException) ObjectInUseException(javax.sip.ObjectInUseException) SipException(javax.sip.SipException) IOException(java.io.IOException) TransactionDoesNotExistException(javax.sip.TransactionDoesNotExistException)

Example 14 with SIPRequest

use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.

the class SIPServerTransaction method isMessagePartOfTransaction.

/**
     * Determines if the message is a part of this transaction.
     *
     * @param messageToTest Message to check if it is part of this transaction.
     *
     * @return True if the message is part of this transaction, false if not.
     */
public boolean isMessagePartOfTransaction(SIPMessage messageToTest) {
    // List of Via headers in the message to test
    ViaList viaHeaders;
    // Topmost Via header in the list
    Via topViaHeader;
    // Branch code in the topmost Via header
    String messageBranch;
    // Flags whether the select message is part of this transaction
    boolean transactionMatches;
    transactionMatches = false;
    String method = messageToTest.getCSeq().getMethod();
    // http://bugs.sipit.net/show_bug.cgi?id=769
    if ((method.equals(Request.INVITE) || !isTerminated())) {
        // Get the topmost Via header and its branch parameter
        viaHeaders = messageToTest.getViaHeaders();
        if (viaHeaders != null) {
            topViaHeader = (Via) viaHeaders.getFirst();
            messageBranch = topViaHeader.getBranch();
            if (messageBranch != null) {
                // does not start with the magic cookie,
                if (!messageBranch.toLowerCase().startsWith(SIPConstants.BRANCH_MAGIC_COOKIE_LOWER_CASE)) {
                    // Flags this as old
                    // (RFC2543-compatible) client
                    // version
                    messageBranch = null;
                }
            }
            // If a new branch parameter exists,
            if (messageBranch != null && this.getBranch() != null) {
                if (method.equals(Request.CANCEL)) {
                    // Cancel is handled as a special case because it
                    // shares the same same branch id of the invite
                    // that it is trying to cancel.
                    transactionMatches = this.getMethod().equals(Request.CANCEL) && getBranch().equalsIgnoreCase(messageBranch) && topViaHeader.getSentBy().equals(((Via) getOriginalRequest().getViaHeaders().getFirst()).getSentBy());
                } else {
                    // Matching server side transaction with only the
                    // branch parameter.
                    transactionMatches = getBranch().equalsIgnoreCase(messageBranch) && topViaHeader.getSentBy().equals(((Via) getOriginalRequest().getViaHeaders().getFirst()).getSentBy());
                }
            } else {
                // This is an RFC2543-compliant message; this code is here
                // for backwards compatibility.
                // It is a weak check.
                // If RequestURI, To tag, From tag, CallID, CSeq number, and
                // top Via headers are the same, the
                // SIPMessage matches this transaction. An exception is for
                // a CANCEL request, which is not deemed
                // to be part of an otherwise-matching INVITE transaction.
                String originalFromTag = super.fromTag;
                String thisFromTag = messageToTest.getFrom().getTag();
                boolean skipFrom = (originalFromTag == null || thisFromTag == null);
                String originalToTag = super.toTag;
                String thisToTag = messageToTest.getTo().getTag();
                boolean skipTo = (originalToTag == null || thisToTag == null);
                boolean isResponse = (messageToTest instanceof SIPResponse);
                // be CANCEL for it to have a chance at matching.
                if (messageToTest.getCSeq().getMethod().equalsIgnoreCase(Request.CANCEL) && !getOriginalRequest().getCSeq().getMethod().equalsIgnoreCase(Request.CANCEL)) {
                    transactionMatches = false;
                } else if ((isResponse || getOriginalRequest().getRequestURI().equals(((SIPRequest) messageToTest).getRequestURI())) && (skipFrom || originalFromTag != null && originalFromTag.equalsIgnoreCase(thisFromTag)) && (skipTo || originalToTag != null && originalToTag.equalsIgnoreCase(thisToTag)) && getOriginalRequest().getCallId().getCallId().equalsIgnoreCase(messageToTest.getCallId().getCallId()) && getOriginalRequest().getCSeq().getSeqNumber() == messageToTest.getCSeq().getSeqNumber() && ((!messageToTest.getCSeq().getMethod().equals(Request.CANCEL)) || getOriginalRequest().getMethod().equals(messageToTest.getCSeq().getMethod())) && topViaHeader.equals(getOriginalRequest().getViaHeaders().getFirst())) {
                    transactionMatches = true;
                }
            }
        }
    }
    return transactionMatches;
}
Also used : SIPResponse(gov.nist.javax.sip.message.SIPResponse) ViaList(gov.nist.javax.sip.header.ViaList) SIPRequest(gov.nist.javax.sip.message.SIPRequest) Via(gov.nist.javax.sip.header.Via)

Example 15 with SIPRequest

use of gov.nist.javax.sip.message.SIPRequest in project XobotOS by xamarin.

the class SIPClientTransaction method createCancel.

/*
     * (non-Javadoc)
     * 
     * @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;
    }
}
Also used : SipException(javax.sip.SipException) SIPRequest(gov.nist.javax.sip.message.SIPRequest)

Aggregations

SIPRequest (gov.nist.javax.sip.message.SIPRequest)32 IOException (java.io.IOException)17 ParseException (java.text.ParseException)17 SipException (javax.sip.SipException)16 InvalidArgumentException (javax.sip.InvalidArgumentException)10 SIPResponse (gov.nist.javax.sip.message.SIPResponse)9 Via (gov.nist.javax.sip.header.Via)8 ObjectInUseException (javax.sip.ObjectInUseException)8 SIPClientTransaction (gov.nist.javax.sip.stack.SIPClientTransaction)6 SIPDialog (gov.nist.javax.sip.stack.SIPDialog)6 DialogDoesNotExistException (javax.sip.DialogDoesNotExistException)6 TransactionDoesNotExistException (javax.sip.TransactionDoesNotExistException)6 Hop (javax.sip.address.Hop)6 SipURI (javax.sip.address.SipURI)4 ListeningPointImpl (gov.nist.javax.sip.ListeningPointImpl)3 From (gov.nist.javax.sip.header.From)3 Route (gov.nist.javax.sip.header.Route)3 To (gov.nist.javax.sip.header.To)3 SIPServerTransaction (gov.nist.javax.sip.stack.SIPServerTransaction)3 SIPTransaction (gov.nist.javax.sip.stack.SIPTransaction)3