1/*
2 * Conditions Of Use
3 *
4 * This software was developed by employees of the National Institute of
5 * Standards and Technology (NIST), an agency of the Federal Government.
6 * Pursuant to title 15 Untied States Code Section 105, works of NIST
7 * employees are not subject to copyright protection in the United States
8 * and are considered to be in the public domain.  As a result, a formal
9 * license is not needed to use the software.
10 *
11 * This software is provided by NIST as a service and is expressly
12 * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
15 * AND DATA ACCURACY.  NIST does not warrant or make any representations
16 * regarding the use of the software or the results thereof, including but
17 * not limited to the correctness, accuracy, reliability or usefulness of
18 * the software.
19 *
20 * Permission to use this software is contingent upon your acceptance
21 * of the terms of this agreement
22 *
23 * .
24 *
25 */
26package gov.nist.javax.sip.stack;
27
28import gov.nist.core.InternalErrorHandler;
29import gov.nist.core.NameValueList;
30import gov.nist.javax.sip.SIPConstants;
31import gov.nist.javax.sip.Utils;
32import gov.nist.javax.sip.address.AddressImpl;
33import gov.nist.javax.sip.header.Contact;
34import gov.nist.javax.sip.header.RecordRoute;
35import gov.nist.javax.sip.header.RecordRouteList;
36import gov.nist.javax.sip.header.Route;
37import gov.nist.javax.sip.header.RouteList;
38import gov.nist.javax.sip.header.TimeStamp;
39import gov.nist.javax.sip.header.To;
40import gov.nist.javax.sip.header.Via;
41import gov.nist.javax.sip.header.ViaList;
42import gov.nist.javax.sip.message.SIPMessage;
43import gov.nist.javax.sip.message.SIPRequest;
44import gov.nist.javax.sip.message.SIPResponse;
45
46import java.io.IOException;
47import java.security.cert.X509Certificate;
48import java.text.ParseException;
49import java.util.ListIterator;
50import java.util.TimerTask;
51import java.util.concurrent.ConcurrentHashMap;
52
53import javax.net.ssl.SSLPeerUnverifiedException;
54import javax.sip.Dialog;
55import javax.sip.DialogState;
56import javax.sip.InvalidArgumentException;
57import javax.sip.ObjectInUseException;
58import javax.sip.SipException;
59import javax.sip.Timeout;
60import javax.sip.TimeoutEvent;
61import javax.sip.TransactionState;
62import javax.sip.address.Hop;
63import javax.sip.address.SipURI;
64import javax.sip.header.ExpiresHeader;
65import javax.sip.header.RouteHeader;
66import javax.sip.header.TimeStampHeader;
67import javax.sip.message.Request;
68
69/*
70 * Jeff Keyser -- initial. Daniel J. Martinez Manzano --Added support for TLS message channel.
71 * Emil Ivov -- bug fixes. Chris Beardshear -- bug fix. Andreas Bystrom -- bug fixes. Matt Keller
72 * (Motorolla) -- bug fix.
73 */
74
75/**
76 * Represents a client transaction. Implements the following state machines. (From RFC 3261)
77 *
78 * <pre>
79 *
80 *
81 *
82 *
83 *
84 *
85 *                                                     |INVITE from TU
86 *                                   Timer A fires     |INVITE sent
87 *                                   Reset A,          V                      Timer B fires
88 *                                   INVITE sent +-----------+                or Transport Err.
89 *                                     +---------|           |---------------+inform TU
90 *                                     |         |  Calling  |               |
91 *                                     +--------&gt;|           |--------------&gt;|
92 *                                               +-----------+ 2xx           |
93 *                                                  |  |       2xx to TU     |
94 *                                                  |  |1xx                  |
95 *                          300-699 +---------------+  |1xx to TU            |
96 *                         ACK sent |                  |                     |
97 *                      resp. to TU |  1xx             V                     |
98 *                                  |  1xx to TU  -----------+               |
99 *                                  |  +---------|           |               |
100 *                                  |  |         |Proceeding |--------------&gt;|
101 *                                  |  +--------&gt;|           | 2xx           |
102 *                                  |            +-----------+ 2xx to TU     |
103 *                                  |       300-699    |                     |
104 *                                  |       ACK sent,  |                     |
105 *                                  |       resp. to TU|                     |
106 *                                  |                  |                     |      NOTE:
107 *                                  |  300-699         V                     |
108 *                                  |  ACK sent  +-----------+Transport Err. |  transitions
109 *                                  |  +---------|           |Inform TU      |  labeled with
110 *                                  |  |         | Completed |--------------&gt;|  the event
111 *                                  |  +--------&gt;|           |               |  over the action
112 *                                  |            +-----------+               |  to take
113 *                                  |              &circ;   |                     |
114 *                                  |              |   | Timer D fires       |
115 *                                  +--------------+   | -                   |
116 *                                                     |                     |
117 *                                                     V                     |
118 *                                               +-----------+               |
119 *                                               |           |               |
120 *                                               | Terminated|&lt;--------------+
121 *                                               |           |
122 *                                               +-----------+
123 *
124 *                                       Figure 5: INVITE client transaction
125 *
126 *
127 *                                                         |Request from TU
128 *                                                         |send request
129 *                                     Timer E             V
130 *                                     send request  +-----------+
131 *                                         +---------|           |-------------------+
132 *                                         |         |  Trying   |  Timer F          |
133 *                                         +--------&gt;|           |  or Transport Err.|
134 *                                                   +-----------+  inform TU        |
135 *                                      200-699         |  |                         |
136 *                                      resp. to TU     |  |1xx                      |
137 *                                      +---------------+  |resp. to TU              |
138 *                                      |                  |                         |
139 *                                      |   Timer E        V       Timer F           |
140 *                                      |   send req +-----------+ or Transport Err. |
141 *                                      |  +---------|           | inform TU         |
142 *                                      |  |         |Proceeding |------------------&gt;|
143 *                                      |  +--------&gt;|           |-----+             |
144 *                                      |            +-----------+     |1xx          |
145 *                                      |              |      &circ;        |resp to TU   |
146 *                                      | 200-699      |      +--------+             |
147 *                                      | resp. to TU  |                             |
148 *                                      |              |                             |
149 *                                      |              V                             |
150 *                                      |            +-----------+                   |
151 *                                      |            |           |                   |
152 *                                      |            | Completed |                   |
153 *                                      |            |           |                   |
154 *                                      |            +-----------+                   |
155 *                                      |              &circ;   |                         |
156 *                                      |              |   | Timer K                 |
157 *                                      +--------------+   | -                       |
158 *                                                         |                         |
159 *                                                         V                         |
160 *                                   NOTE:           +-----------+                   |
161 *                                                   |           |                   |
162 *                               transitions         | Terminated|&lt;------------------+
163 *                               labeled with        |           |
164 *                               the event           +-----------+
165 *                               over the action
166 *                               to take
167 *
168 *                                       Figure 6: non-INVITE client transaction
169 *
170 *
171 *
172 *
173 *
174 *
175 * </pre>
176 *
177 *
178 * @author M. Ranganathan
179 *
180 * @version 1.2 $Revision: 1.122 $ $Date: 2009/12/17 23:33:52 $
181 */
182public class SIPClientTransaction extends SIPTransaction implements ServerResponseInterface,
183        javax.sip.ClientTransaction, gov.nist.javax.sip.ClientTransactionExt {
184
185    // a SIP Client transaction may belong simultaneously to multiple
186    // dialogs in the early state. These dialogs all have
187    // the same call ID and same From tag but different to tags.
188
189    private ConcurrentHashMap<String,SIPDialog> sipDialogs;
190
191    private SIPRequest lastRequest;
192
193    private int viaPort;
194
195    private String viaHost;
196
197    // Real ResponseInterface to pass messages to
198    private transient ServerResponseInterface respondTo;
199
200    private SIPDialog defaultDialog;
201
202    private Hop nextHop;
203
204    private boolean notifyOnRetransmit;
205
206    private boolean timeoutIfStillInCallingState;
207
208    private int callingStateTimeoutCount;
209
210    public class TransactionTimer extends SIPStackTimerTask {
211
212        public TransactionTimer() {
213
214        }
215
216        protected void runTask() {
217            SIPClientTransaction clientTransaction;
218            SIPTransactionStack sipStack;
219            clientTransaction = SIPClientTransaction.this;
220            sipStack = clientTransaction.sipStack;
221
222            // If the transaction has terminated,
223            if (clientTransaction.isTerminated()) {
224
225                if (sipStack.isLoggingEnabled()) {
226                    sipStack.getStackLogger().logDebug(
227                            "removing  = " + clientTransaction + " isReliable "
228                                    + clientTransaction.isReliable());
229                }
230
231                sipStack.removeTransaction(clientTransaction);
232
233                try {
234                    this.cancel();
235
236                } catch (IllegalStateException ex) {
237                    if (!sipStack.isAlive())
238                        return;
239                }
240
241                // Client transaction terminated. Kill connection if
242                // this is a TCP after the linger timer has expired.
243                // The linger timer is needed to allow any pending requests to
244                // return responses.
245                if ((!sipStack.cacheClientConnections) && clientTransaction.isReliable()) {
246
247                    int newUseCount = --clientTransaction.getMessageChannel().useCount;
248                    if (newUseCount <= 0) {
249                        // Let the connection linger for a while and then close
250                        // it.
251                        TimerTask myTimer = new LingerTimer();
252                        sipStack.getTimer().schedule(myTimer,
253                                SIPTransactionStack.CONNECTION_LINGER_TIME * 1000);
254                    }
255
256                } else {
257                    // Cache the client connections so dont close the
258                    // connection. This keeps the connection open permanently
259                    // until the client disconnects.
260                    if (sipStack.isLoggingEnabled() && clientTransaction.isReliable()) {
261                       	int useCount = clientTransaction.getMessageChannel().useCount;
262                       	if (sipStack.isLoggingEnabled())
263                       		sipStack.getStackLogger().logDebug("Client Use Count = " + useCount);
264                    }
265                }
266
267            } else {
268                // If this transaction has not
269                // terminated,
270                // Fire the transaction timer.
271                clientTransaction.fireTimer();
272
273            }
274
275        }
276
277    }
278
279    /**
280     * Creates a new client transaction.
281     *
282     * @param newSIPStack Transaction stack this transaction belongs to.
283     * @param newChannelToUse Channel to encapsulate.
284     * @return the created client transaction.
285     */
286    protected SIPClientTransaction(SIPTransactionStack newSIPStack, MessageChannel newChannelToUse) {
287        super(newSIPStack, newChannelToUse);
288        // Create a random branch parameter for this transaction
289        // setBranch( SIPConstants.BRANCH_MAGIC_COOKIE +
290        // Integer.toHexString( hashCode( ) ) );
291        setBranch(Utils.getInstance().generateBranchId());
292        this.messageProcessor = newChannelToUse.messageProcessor;
293        this.setEncapsulatedChannel(newChannelToUse);
294        this.notifyOnRetransmit = false;
295        this.timeoutIfStillInCallingState = false;
296
297        // This semaphore guards the listener from being
298        // re-entered for this transaction. That is
299        // for a give tx, the listener is called at most
300        // once with an outstanding request.
301
302        if (sipStack.isLoggingEnabled()) {
303            sipStack.getStackLogger().logDebug("Creating clientTransaction " + this);
304            sipStack.getStackLogger().logStackTrace();
305        }
306        // this.startTransactionTimer();
307        this.sipDialogs = new ConcurrentHashMap();
308    }
309
310    /**
311     * Sets the real ResponseInterface this transaction encapsulates.
312     *
313     * @param newRespondTo ResponseInterface to send messages to.
314     */
315    public void setResponseInterface(ServerResponseInterface newRespondTo) {
316        if (sipStack.isLoggingEnabled()) {
317            sipStack.getStackLogger().logDebug(
318                    "Setting response interface for " + this + " to " + newRespondTo);
319            if (newRespondTo == null) {
320                sipStack.getStackLogger().logStackTrace();
321                sipStack.getStackLogger().logDebug("WARNING -- setting to null!");
322            }
323        }
324
325        respondTo = newRespondTo;
326
327    }
328
329    /**
330     * Returns this transaction.
331     */
332    public MessageChannel getRequestChannel() {
333
334        return this;
335
336    }
337
338    /**
339     * Deterines if the message is a part of this transaction.
340     *
341     * @param messageToTest Message to check if it is part of this transaction.
342     *
343     * @return true if the message is part of this transaction, false if not.
344     */
345    public boolean isMessagePartOfTransaction(SIPMessage messageToTest) {
346
347        // List of Via headers in the message to test
348        ViaList viaHeaders = messageToTest.getViaHeaders();
349        // Flags whether the select message is part of this transaction
350        boolean transactionMatches;
351        String messageBranch = ((Via) viaHeaders.getFirst()).getBranch();
352        boolean rfc3261Compliant = getBranch() != null
353                && messageBranch != null
354                && getBranch().toLowerCase().startsWith(
355                        SIPConstants.BRANCH_MAGIC_COOKIE_LOWER_CASE)
356                && messageBranch.toLowerCase().startsWith(
357                        SIPConstants.BRANCH_MAGIC_COOKIE_LOWER_CASE);
358
359        transactionMatches = false;
360        if (TransactionState.COMPLETED == this.getState()) {
361            if (rfc3261Compliant) {
362                transactionMatches = getBranch().equalsIgnoreCase(
363                        ((Via) viaHeaders.getFirst()).getBranch())
364                        && getMethod().equals(messageToTest.getCSeq().getMethod());
365            } else {
366                transactionMatches = getBranch().equals(messageToTest.getTransactionId());
367            }
368        } else if (!isTerminated()) {
369            if (rfc3261Compliant) {
370                if (viaHeaders != null) {
371                    // If the branch parameter is the
372                    // same as this transaction and the method is the same,
373                    if (getBranch().equalsIgnoreCase(((Via) viaHeaders.getFirst()).getBranch())) {
374                        transactionMatches = getOriginalRequest().getCSeq().getMethod().equals(
375                                messageToTest.getCSeq().getMethod());
376
377                    }
378                }
379            } else {
380                // not RFC 3261 compliant.
381                if (getBranch() != null) {
382                    transactionMatches = getBranch().equalsIgnoreCase(
383                            messageToTest.getTransactionId());
384                } else {
385                    transactionMatches = getOriginalRequest().getTransactionId()
386                            .equalsIgnoreCase(messageToTest.getTransactionId());
387                }
388
389            }
390
391        }
392        return transactionMatches;
393
394    }
395
396    /**
397     * Send a request message through this transaction and onto the client.
398     *
399     * @param messageToSend Request to process and send.
400     */
401    public void sendMessage(SIPMessage messageToSend) throws IOException {
402
403        try {
404            // Message typecast as a request
405            SIPRequest transactionRequest;
406
407            transactionRequest = (SIPRequest) messageToSend;
408
409            // Set the branch id for the top via header.
410            Via topVia = (Via) transactionRequest.getViaHeaders().getFirst();
411            // Tack on a branch identifier to match responses.
412            try {
413                topVia.setBranch(getBranch());
414            } catch (java.text.ParseException ex) {
415            }
416
417            if (sipStack.isLoggingEnabled()) {
418                sipStack.getStackLogger().logDebug("Sending Message " + messageToSend);
419                sipStack.getStackLogger().logDebug("TransactionState " + this.getState());
420            }
421            // If this is the first request for this transaction,
422            if (TransactionState.PROCEEDING == getState()
423                    || TransactionState.CALLING == getState()) {
424
425                // If this is a TU-generated ACK request,
426                if (transactionRequest.getMethod().equals(Request.ACK)) {
427
428                    // Send directly to the underlying
429                    // transport and close this transaction
430                    if (isReliable()) {
431                        this.setState(TransactionState.TERMINATED);
432                    } else {
433                        this.setState(TransactionState.COMPLETED);
434                    }
435                    // BUGBUG -- This suppresses sending the ACK uncomment this
436                    // to
437                    // test 4xx retransmission
438                    // if (transactionRequest.getMethod() != Request.ACK)
439                    super.sendMessage(transactionRequest);
440                    return;
441
442                }
443
444            }
445            try {
446
447                // Send the message to the server
448                lastRequest = transactionRequest;
449                if (getState() == null) {
450                    // Save this request as the one this transaction
451                    // is handling
452                    setOriginalRequest(transactionRequest);
453                    // Change to trying/calling state
454                    // Set state first to avoid race condition..
455
456                    if (transactionRequest.getMethod().equals(Request.INVITE)) {
457                        this.setState(TransactionState.CALLING);
458                    } else if (transactionRequest.getMethod().equals(Request.ACK)) {
459                        // Acks are never retransmitted.
460                        this.setState(TransactionState.TERMINATED);
461                    } else {
462                        this.setState(TransactionState.TRYING);
463                    }
464                    if (!isReliable()) {
465                        enableRetransmissionTimer();
466                    }
467                    if (isInviteTransaction()) {
468                        enableTimeoutTimer(TIMER_B);
469                    } else {
470                        enableTimeoutTimer(TIMER_F);
471                    }
472                }
473                // BUGBUG This supresses sending ACKS -- uncomment to test
474                // 4xx retransmission.
475                // if (transactionRequest.getMethod() != Request.ACK)
476                super.sendMessage(transactionRequest);
477
478            } catch (IOException e) {
479
480                this.setState(TransactionState.TERMINATED);
481                throw e;
482
483            }
484        } finally {
485            this.isMapped = true;
486            this.startTransactionTimer();
487
488        }
489
490    }
491
492    /**
493     * Process a new response message through this transaction. If necessary, this message will
494     * also be passed onto the TU.
495     *
496     * @param transactionResponse Response to process.
497     * @param sourceChannel Channel that received this message.
498     */
499    public synchronized void processResponse(SIPResponse transactionResponse,
500            MessageChannel sourceChannel, SIPDialog dialog) {
501
502        // If the state has not yet been assigned then this is a
503        // spurious response.
504
505        if (getState() == null)
506            return;
507
508        // Ignore 1xx
509        if ((TransactionState.COMPLETED == this.getState() || TransactionState.TERMINATED == this
510                .getState())
511                && transactionResponse.getStatusCode() / 100 == 1) {
512            return;
513        }
514
515        if (sipStack.isLoggingEnabled()) {
516            sipStack.getStackLogger().logDebug(
517                    "processing " + transactionResponse.getFirstLine() + "current state = "
518                            + getState());
519            sipStack.getStackLogger().logDebug("dialog = " + dialog);
520        }
521
522        this.lastResponse = transactionResponse;
523
524        /*
525         * JvB: this is now duplicate with code in the other processResponse
526         *
527         * if (dialog != null && transactionResponse.getStatusCode() != 100 &&
528         * (transactionResponse.getTo().getTag() != null || sipStack .isRfc2543Supported())) { //
529         * add the route before you process the response. dialog.setLastResponse(this,
530         * transactionResponse); this.setDialog(dialog, transactionResponse.getDialogId(false)); }
531         */
532
533        try {
534            if (isInviteTransaction())
535                inviteClientTransaction(transactionResponse, sourceChannel, dialog);
536            else
537                nonInviteClientTransaction(transactionResponse, sourceChannel, dialog);
538        } catch (IOException ex) {
539            if (sipStack.isLoggingEnabled())
540                sipStack.getStackLogger().logException(ex);
541            this.setState(TransactionState.TERMINATED);
542            raiseErrorEvent(SIPTransactionErrorEvent.TRANSPORT_ERROR);
543        }
544    }
545
546    /**
547     * Implements the state machine for invite client transactions.
548     *
549     * <pre>
550     *
551     *
552     *
553     *
554     *
555     *                                                         |Request from TU
556     *                                                         |send request
557     *                                     Timer E             V
558     *                                     send request  +-----------+
559     *                                         +---------|           |-------------------+
560     *                                         |         |  Trying   |  Timer F          |
561     *                                         +--------&gt;|           |  or Transport Err.|
562     *                                                   +-----------+  inform TU        |
563     *                                      200-699         |  |                         |
564     *                                      resp. to TU     |  |1xx                      |
565     *                                      +---------------+  |resp. to TU              |
566     *                                      |                  |                         |
567     *                                      |   Timer E        V       Timer F           |
568     *                                      |   send req +-----------+ or Transport Err. |
569     *                                      |  +---------|           | inform TU         |
570     *                                      |  |         |Proceeding |------------------&gt;|
571     *                                      |  +--------&gt;|           |-----+             |
572     *                                      |            +-----------+     |1xx          |
573     *                                      |              |      &circ;        |resp to TU   |
574     *                                      | 200-699      |      +--------+             |
575     *                                      | resp. to TU  |                             |
576     *                                      |              |                             |
577     *                                      |              V                             |
578     *                                      |            +-----------+                   |
579     *                                      |            |           |                   |
580     *                                      |            | Completed |                   |
581     *                                      |            |           |                   |
582     *                                      |            +-----------+                   |
583     *                                      |              &circ;   |                         |
584     *                                      |              |   | Timer K                 |
585     *                                      +--------------+   | -                       |
586     *                                                         |                         |
587     *                                                         V                         |
588     *                                   NOTE:           +-----------+                   |
589     *                                                   |           |                   |
590     *                               transitions         | Terminated|&lt;------------------+
591     *                               labeled with        |           |
592     *                               the event           +-----------+
593     *                               over the action
594     *                               to take
595     *
596     *                                       Figure 6: non-INVITE client transaction
597     *
598     *
599     *
600     *
601     * </pre>
602     *
603     * @param transactionResponse -- transaction response received.
604     * @param sourceChannel - source channel on which the response was received.
605     */
606    private void nonInviteClientTransaction(SIPResponse transactionResponse,
607            MessageChannel sourceChannel, SIPDialog sipDialog) throws IOException {
608        int statusCode = transactionResponse.getStatusCode();
609        if (TransactionState.TRYING == this.getState()) {
610            if (statusCode / 100 == 1) {
611                this.setState(TransactionState.PROCEEDING);
612                enableRetransmissionTimer(MAXIMUM_RETRANSMISSION_TICK_COUNT);
613                enableTimeoutTimer(TIMER_F);
614                // According to RFC, the TU has to be informed on
615                // this transition.
616                if (respondTo != null) {
617                    respondTo.processResponse(transactionResponse, this, sipDialog);
618                } else {
619                    this.semRelease();
620                }
621            } else if (200 <= statusCode && statusCode <= 699) {
622                // Send the response up to the TU.
623                if (respondTo != null) {
624                    respondTo.processResponse(transactionResponse, this, sipDialog);
625                } else {
626                    this.semRelease();
627                }
628                if (!isReliable()) {
629                    this.setState(TransactionState.COMPLETED);
630                    enableTimeoutTimer(TIMER_K);
631                } else {
632                    this.setState(TransactionState.TERMINATED);
633                }
634            }
635        } else if (TransactionState.PROCEEDING == this.getState()) {
636            if (statusCode / 100 == 1) {
637                if (respondTo != null) {
638                    respondTo.processResponse(transactionResponse, this, sipDialog);
639                } else {
640                    this.semRelease();
641                }
642            } else if (200 <= statusCode && statusCode <= 699) {
643                if (respondTo != null) {
644                    respondTo.processResponse(transactionResponse, this, sipDialog);
645                } else {
646                    this.semRelease();
647                }
648                disableRetransmissionTimer();
649                disableTimeoutTimer();
650                if (!isReliable()) {
651                    this.setState(TransactionState.COMPLETED);
652                    enableTimeoutTimer(TIMER_K);
653                } else {
654                    this.setState(TransactionState.TERMINATED);
655                }
656            }
657        } else {
658            if (sipStack.isLoggingEnabled()) {
659                sipStack.getStackLogger().logDebug(
660                        " Not sending response to TU! " + getState());
661            }
662            this.semRelease();
663        }
664    }
665
666    /**
667     * Implements the state machine for invite client transactions.
668     *
669     * <pre>
670     *
671     *
672     *
673     *
674     *
675     *                                                     |INVITE from TU
676     *                                   Timer A fires     |INVITE sent
677     *                                   Reset A,          V                      Timer B fires
678     *                                   INVITE sent +-----------+                or Transport Err.
679     *                                     +---------|           |---------------+inform TU
680     *                                     |         |  Calling  |               |
681     *                                     +--------&gt;|           |--------------&gt;|
682     *                                               +-----------+ 2xx           |
683     *                                                  |  |       2xx to TU     |
684     *                                                  |  |1xx                  |
685     *                          300-699 +---------------+  |1xx to TU            |
686     *                         ACK sent |                  |                     |
687     *                      resp. to TU |  1xx             V                     |
688     *                                  |  1xx to TU  -----------+               |
689     *                                  |  +---------|           |               |
690     *                                  |  |         |Proceeding |--------------&gt;|
691     *                                  |  +--------&gt;|           | 2xx           |
692     *                                  |            +-----------+ 2xx to TU     |
693     *                                  |       300-699    |                     |
694     *                                  |       ACK sent,  |                     |
695     *                                  |       resp. to TU|                     |
696     *                                  |                  |                     |      NOTE:
697     *                                  |  300-699         V                     |
698     *                                  |  ACK sent  +-----------+Transport Err. |  transitions
699     *                                  |  +---------|           |Inform TU      |  labeled with
700     *                                  |  |         | Completed |--------------&gt;|  the event
701     *                                  |  +--------&gt;|           |               |  over the action
702     *                                  |            +-----------+               |  to take
703     *                                  |              &circ;   |                     |
704     *                                  |              |   | Timer D fires       |
705     *                                  +--------------+   | -                   |
706     *                                                     |                     |
707     *                                                     V                     |
708     *                                               +-----------+               |
709     *                                               |           |               |
710     *                                               | Terminated|&lt;--------------+
711     *                                               |           |
712     *                                               +-----------+
713     *
714     *
715     *
716     *
717     * </pre>
718     *
719     * @param transactionResponse -- transaction response received.
720     * @param sourceChannel - source channel on which the response was received.
721     */
722
723    private void inviteClientTransaction(SIPResponse transactionResponse,
724            MessageChannel sourceChannel, SIPDialog dialog) throws IOException {
725        int statusCode = transactionResponse.getStatusCode();
726
727        if (TransactionState.TERMINATED == this.getState()) {
728            boolean ackAlreadySent = false;
729            if (dialog != null && dialog.isAckSeen() && dialog.getLastAckSent() != null) {
730                if (dialog.getLastAckSent().getCSeq().getSeqNumber() == transactionResponse.getCSeq()
731                        .getSeqNumber()
732                        && transactionResponse.getFromTag().equals(
733                                dialog.getLastAckSent().getFromTag())) {
734                    // the last ack sent corresponded to this response
735                    ackAlreadySent = true;
736                }
737            }
738            // retransmit the ACK for this response.
739            if (dialog!= null && ackAlreadySent
740                    && transactionResponse.getCSeq().getMethod().equals(dialog.getMethod())) {
741                try {
742                    // Found the dialog - resend the ACK and
743                    // dont pass up the null transaction
744                    if (sipStack.isLoggingEnabled())
745                        sipStack.getStackLogger().logDebug("resending ACK");
746
747                    dialog.resendAck();
748                } catch (SipException ex) {
749                    // What to do here ?? kill the dialog?
750                }
751            }
752
753            this.semRelease();
754            return;
755        } else if (TransactionState.CALLING == this.getState()) {
756            if (statusCode / 100 == 2) {
757
758                // JvB: do this ~before~ calling the application, to avoid
759                // retransmissions
760                // of the INVITE after app sends ACK
761                disableRetransmissionTimer();
762                disableTimeoutTimer();
763                this.setState(TransactionState.TERMINATED);
764
765                // 200 responses are always seen by TU.
766                if (respondTo != null)
767                    respondTo.processResponse(transactionResponse, this, dialog);
768                else {
769                    this.semRelease();
770                }
771
772            } else if (statusCode / 100 == 1) {
773                disableRetransmissionTimer();
774                disableTimeoutTimer();
775                this.setState(TransactionState.PROCEEDING);
776
777                if (respondTo != null)
778                    respondTo.processResponse(transactionResponse, this, dialog);
779                else {
780                    this.semRelease();
781                }
782
783            } else if (300 <= statusCode && statusCode <= 699) {
784                // Send back an ACK request
785
786                try {
787                    sendMessage((SIPRequest) createErrorAck());
788
789                } catch (Exception ex) {
790                    sipStack.getStackLogger().logError(
791                            "Unexpected Exception sending ACK -- sending error AcK ", ex);
792
793                }
794
795                /*
796                 * When in either the "Calling" or "Proceeding" states, reception of response with
797                 * status code from 300-699 MUST cause the client transaction to transition to
798                 * "Completed". The client transaction MUST pass the received response up to the
799                 * TU, and the client transaction MUST generate an ACK request.
800                 */
801
802                if (respondTo != null) {
803                    respondTo.processResponse(transactionResponse, this, dialog);
804                } else {
805                    this.semRelease();
806                }
807
808                if (this.getDialog() != null &&  ((SIPDialog)this.getDialog()).isBackToBackUserAgent()) {
809                    ((SIPDialog) this.getDialog()).releaseAckSem();
810                }
811
812                if (!isReliable()) {
813                    this.setState(TransactionState.COMPLETED);
814                    enableTimeoutTimer(TIMER_D);
815                } else {
816                    // Proceed immediately to the TERMINATED state.
817                    this.setState(TransactionState.TERMINATED);
818                }
819            }
820        } else if (TransactionState.PROCEEDING == this.getState()) {
821            if (statusCode / 100 == 1) {
822                if (respondTo != null) {
823                    respondTo.processResponse(transactionResponse, this, dialog);
824                } else {
825                    this.semRelease();
826                }
827            } else if (statusCode / 100 == 2) {
828                this.setState(TransactionState.TERMINATED);
829                if (respondTo != null) {
830                    respondTo.processResponse(transactionResponse, this, dialog);
831                } else {
832                    this.semRelease();
833                }
834
835            } else if (300 <= statusCode && statusCode <= 699) {
836                // Send back an ACK request
837                try {
838                    sendMessage((SIPRequest) createErrorAck());
839                } catch (Exception ex) {
840                    InternalErrorHandler.handleException(ex);
841                }
842
843                if (this.getDialog() != null) {
844                    ((SIPDialog) this.getDialog()).releaseAckSem();
845                }
846                // JvB: update state before passing to app
847                if (!isReliable()) {
848                    this.setState(TransactionState.COMPLETED);
849                    this.enableTimeoutTimer(TIMER_D);
850                } else {
851                    this.setState(TransactionState.TERMINATED);
852                }
853
854                // Pass up to the TU for processing.
855                if (respondTo != null)
856                    respondTo.processResponse(transactionResponse, this, dialog);
857                else {
858                    this.semRelease();
859                }
860
861                // JvB: duplicate with line 874
862                // if (!isReliable()) {
863                // enableTimeoutTimer(TIMER_D);
864                // }
865            }
866        } else if (TransactionState.COMPLETED == this.getState()) {
867            if (300 <= statusCode && statusCode <= 699) {
868                // Send back an ACK request
869                try {
870                    sendMessage((SIPRequest) createErrorAck());
871                } catch (Exception ex) {
872                    InternalErrorHandler.handleException(ex);
873                } finally {
874                    this.semRelease();
875                }
876            }
877
878        }
879
880    }
881
882    /*
883     * (non-Javadoc)
884     *
885     * @see javax.sip.ClientTransaction#sendRequest()
886     */
887    public void sendRequest() throws SipException {
888        SIPRequest sipRequest = this.getOriginalRequest();
889
890        if (this.getState() != null)
891            throw new SipException("Request already sent");
892
893        if (sipStack.isLoggingEnabled()) {
894            sipStack.getStackLogger().logDebug("sendRequest() " + sipRequest);
895        }
896
897        try {
898            sipRequest.checkHeaders();
899        } catch (ParseException ex) {
900        	if (sipStack.isLoggingEnabled())
901        		sipStack.getStackLogger().logError("missing required header");
902            throw new SipException(ex.getMessage());
903        }
904
905        if (getMethod().equals(Request.SUBSCRIBE)
906                && sipRequest.getHeader(ExpiresHeader.NAME) == null) {
907            /*
908             * If no "Expires" header is present in a SUBSCRIBE request, the implied default is
909             * defined by the event package being used.
910             *
911             */
912        	if (sipStack.isLoggingEnabled())
913        		sipStack.getStackLogger().logWarning(
914                    "Expires header missing in outgoing subscribe --"
915                            + " Notifier will assume implied value on event package");
916        }
917        try {
918            /*
919             * This check is removed because it causes problems for load balancers ( See issue
920             * 136) reported by Raghav Ramesh ( BT )
921             *
922             */
923            if (this.getOriginalRequest().getMethod().equals(Request.CANCEL)
924                    && sipStack.isCancelClientTransactionChecked()) {
925                SIPClientTransaction ct = (SIPClientTransaction) sipStack.findCancelTransaction(
926                        this.getOriginalRequest(), false);
927                if (ct == null) {
928                    /*
929                     * If the original request has generated a final response, the CANCEL SHOULD
930                     * NOT be sent, as it is an effective no-op, since CANCEL has no effect on
931                     * requests that have already generated a final response.
932                     */
933                    throw new SipException("Could not find original tx to cancel. RFC 3261 9.1");
934                } else if (ct.getState() == null) {
935                    throw new SipException(
936                            "State is null no provisional response yet -- cannot cancel RFC 3261 9.1");
937                } else if (!ct.getMethod().equals(Request.INVITE)) {
938                    throw new SipException("Cannot cancel non-invite requests RFC 3261 9.1");
939                }
940            } else
941
942            if (this.getOriginalRequest().getMethod().equals(Request.BYE)
943                    || this.getOriginalRequest().getMethod().equals(Request.NOTIFY)) {
944                SIPDialog dialog = sipStack.getDialog(this.getOriginalRequest()
945                        .getDialogId(false));
946                // I want to behave like a user agent so send the BYE using the
947                // Dialog
948                if (this.getSipProvider().isAutomaticDialogSupportEnabled() && dialog != null) {
949                    throw new SipException(
950                            "Dialog is present and AutomaticDialogSupport is enabled for "
951                                    + " the provider -- Send the Request using the Dialog.sendRequest(transaction)");
952                }
953            }
954            // Only map this after the fist request is sent out.
955            if (this.getMethod().equals(Request.INVITE)) {
956                SIPDialog dialog = this.getDefaultDialog();
957
958                if (dialog != null && dialog.isBackToBackUserAgent()) {
959                    // Block sending re-INVITE till we see the ACK.
960                    if ( ! dialog.takeAckSem() ) {
961                        throw new SipException ("Failed to take ACK semaphore");
962                    }
963
964                }
965            }
966            this.isMapped = true;
967            this.sendMessage(sipRequest);
968
969        } catch (IOException ex) {
970            this.setState(TransactionState.TERMINATED);
971            throw new SipException("IO Error sending request", ex);
972
973        }
974
975    }
976
977    /**
978     * Called by the transaction stack when a retransmission timer fires.
979     */
980    protected void fireRetransmissionTimer() {
981
982        try {
983
984            // Resend the last request sent
985            if (this.getState() == null || !this.isMapped)
986                return;
987
988            boolean inv = isInviteTransaction();
989            TransactionState s = this.getState();
990
991            // JvB: INVITE CTs only retransmit in CALLING, non-INVITE in both TRYING and
992            // PROCEEDING
993            // Bug-fix for non-INVITE transactions not retransmitted when 1xx response received
994            if ((inv && TransactionState.CALLING == s)
995                    || (!inv && (TransactionState.TRYING == s || TransactionState.PROCEEDING == s))) {
996                // If the retransmission filter is disabled then
997                // retransmission of the INVITE is the application
998                // responsibility.
999
1000                if (lastRequest != null) {
1001                    if (sipStack.generateTimeStampHeader
1002                            && lastRequest.getHeader(TimeStampHeader.NAME) != null) {
1003                        long milisec = System.currentTimeMillis();
1004                        TimeStamp timeStamp = new TimeStamp();
1005                        try {
1006                            timeStamp.setTimeStamp(milisec);
1007                        } catch (InvalidArgumentException ex) {
1008                            InternalErrorHandler.handleException(ex);
1009                        }
1010                        lastRequest.setHeader(timeStamp);
1011                    }
1012                    super.sendMessage(lastRequest);
1013                    if (this.notifyOnRetransmit) {
1014                        TimeoutEvent txTimeout = new TimeoutEvent(this.getSipProvider(), this,
1015                                Timeout.RETRANSMIT);
1016                        this.getSipProvider().handleEvent(txTimeout, this);
1017                    }
1018                    if (this.timeoutIfStillInCallingState
1019                            && this.getState() == TransactionState.CALLING) {
1020                        this.callingStateTimeoutCount--;
1021                        if (callingStateTimeoutCount == 0) {
1022                            TimeoutEvent timeoutEvent = new TimeoutEvent(this.getSipProvider(),
1023                                    this, Timeout.RETRANSMIT);
1024                            this.getSipProvider().handleEvent(timeoutEvent, this);
1025                            this.timeoutIfStillInCallingState = false;
1026                        }
1027
1028                    }
1029                }
1030
1031            }
1032        } catch (IOException e) {
1033            this.raiseIOExceptionEvent();
1034            raiseErrorEvent(SIPTransactionErrorEvent.TRANSPORT_ERROR);
1035        }
1036
1037    }
1038
1039    /**
1040     * Called by the transaction stack when a timeout timer fires.
1041     */
1042    protected void fireTimeoutTimer() {
1043
1044        if (sipStack.isLoggingEnabled())
1045            sipStack.getStackLogger().logDebug("fireTimeoutTimer " + this);
1046
1047        SIPDialog dialog = (SIPDialog) this.getDialog();
1048        if (TransactionState.CALLING == this.getState()
1049                || TransactionState.TRYING == this.getState()
1050                || TransactionState.PROCEEDING == this.getState()) {
1051            // Timeout occured. If this is asociated with a transaction
1052            // creation then kill the dialog.
1053            if (dialog != null
1054                    && (dialog.getState() == null || dialog.getState() == DialogState.EARLY)) {
1055                if (((SIPTransactionStack) getSIPStack()).isDialogCreated(this
1056                        .getOriginalRequest().getMethod())) {
1057                    // If this is a re-invite we do not delete the dialog even
1058                    // if the
1059                    // reinvite times out. Else
1060                    // terminate the enclosing dialog.
1061                    dialog.delete();
1062                }
1063            } else if (dialog != null) {
1064                // Guard against the case of BYE time out.
1065
1066                if (getOriginalRequest().getMethod().equalsIgnoreCase(Request.BYE)
1067                        && dialog.isTerminatedOnBye()) {
1068                    // Terminate the associated dialog on BYE Timeout.
1069                    dialog.delete();
1070                }
1071            }
1072        }
1073        if (TransactionState.COMPLETED != this.getState()) {
1074            raiseErrorEvent(SIPTransactionErrorEvent.TIMEOUT_ERROR);
1075            // Got a timeout error on a cancel.
1076            if (this.getOriginalRequest().getMethod().equalsIgnoreCase(Request.CANCEL)) {
1077                SIPClientTransaction inviteTx = (SIPClientTransaction) this.getOriginalRequest()
1078                        .getInviteTransaction();
1079                if (inviteTx != null
1080                        && ((inviteTx.getState() == TransactionState.CALLING || inviteTx
1081                                .getState() == TransactionState.PROCEEDING))
1082                        && inviteTx.getDialog() != null) {
1083                    /*
1084                     * A proxy server should have started TIMER C and take care of the Termination
1085                     * using transaction.terminate() by itself (i.e. this is not the job of the
1086                     * stack at this point but we do it to be nice.
1087                     */
1088                    inviteTx.setState(TransactionState.TERMINATED);
1089
1090                }
1091            }
1092
1093        } else {
1094            this.setState(TransactionState.TERMINATED);
1095        }
1096
1097    }
1098
1099    /*
1100     * (non-Javadoc)
1101     *
1102     * @see javax.sip.ClientTransaction#createCancel()
1103     */
1104    public Request createCancel() throws SipException {
1105        SIPRequest originalRequest = this.getOriginalRequest();
1106        if (originalRequest == null)
1107            throw new SipException("Bad state " + getState());
1108        if (!originalRequest.getMethod().equals(Request.INVITE))
1109            throw new SipException("Only INIVTE may be cancelled");
1110
1111        if (originalRequest.getMethod().equalsIgnoreCase(Request.ACK))
1112            throw new SipException("Cannot Cancel ACK!");
1113        else {
1114            SIPRequest cancelRequest = originalRequest.createCancelRequest();
1115            cancelRequest.setInviteTransaction(this);
1116            return cancelRequest;
1117        }
1118    }
1119
1120    /*
1121     * (non-Javadoc)
1122     *
1123     * @see javax.sip.ClientTransaction#createAck()
1124     */
1125    public Request createAck() throws SipException {
1126        SIPRequest originalRequest = this.getOriginalRequest();
1127        if (originalRequest == null)
1128            throw new SipException("bad state " + getState());
1129        if (getMethod().equalsIgnoreCase(Request.ACK)) {
1130            throw new SipException("Cannot ACK an ACK!");
1131        } else if (lastResponse == null) {
1132            throw new SipException("bad Transaction state");
1133        } else if (lastResponse.getStatusCode() < 200) {
1134            if (sipStack.isLoggingEnabled()) {
1135                sipStack.getStackLogger().logDebug("lastResponse = " + lastResponse);
1136            }
1137            throw new SipException("Cannot ACK a provisional response!");
1138        }
1139        SIPRequest ackRequest = originalRequest.createAckRequest((To) lastResponse.getTo());
1140        // Pull the record route headers from the last reesponse.
1141        RecordRouteList recordRouteList = lastResponse.getRecordRouteHeaders();
1142        if (recordRouteList == null) {
1143            // If the record route list is null then we can
1144            // construct the ACK from the specified contact header.
1145            // Note the 3xx check here because 3xx is a redirect.
1146            // The contact header for the 3xx is the redirected
1147            // location so we cannot use that to construct the
1148            // request URI.
1149            if (lastResponse.getContactHeaders() != null
1150                    && lastResponse.getStatusCode() / 100 != 3) {
1151                Contact contact = (Contact) lastResponse.getContactHeaders().getFirst();
1152                javax.sip.address.URI uri = (javax.sip.address.URI) contact.getAddress().getURI()
1153                        .clone();
1154                ackRequest.setRequestURI(uri);
1155            }
1156            return ackRequest;
1157        }
1158
1159        ackRequest.removeHeader(RouteHeader.NAME);
1160        RouteList routeList = new RouteList();
1161        // start at the end of the list and walk backwards
1162        ListIterator<RecordRoute> li = recordRouteList.listIterator(recordRouteList.size());
1163        while (li.hasPrevious()) {
1164            RecordRoute rr = (RecordRoute) li.previous();
1165
1166            Route route = new Route();
1167            route.setAddress((AddressImpl) ((AddressImpl) rr.getAddress()).clone());
1168            route.setParameters((NameValueList) rr.getParameters().clone());
1169            routeList.add(route);
1170        }
1171
1172        Contact contact = null;
1173        if (lastResponse.getContactHeaders() != null) {
1174            contact = (Contact) lastResponse.getContactHeaders().getFirst();
1175        }
1176
1177        if (!((SipURI) ((Route) routeList.getFirst()).getAddress().getURI()).hasLrParam()) {
1178
1179            // Contact may not yet be there (bug reported by Andreas B).
1180
1181            Route route = null;
1182            if (contact != null) {
1183                route = new Route();
1184                route.setAddress((AddressImpl) ((AddressImpl) (contact.getAddress())).clone());
1185            }
1186
1187            Route firstRoute = (Route) routeList.getFirst();
1188            routeList.removeFirst();
1189            javax.sip.address.URI uri = firstRoute.getAddress().getURI();
1190            ackRequest.setRequestURI(uri);
1191
1192            if (route != null)
1193                routeList.add(route);
1194
1195            ackRequest.addHeader(routeList);
1196        } else {
1197            if (contact != null) {
1198                javax.sip.address.URI uri = (javax.sip.address.URI) contact.getAddress().getURI()
1199                        .clone();
1200                ackRequest.setRequestURI(uri);
1201                ackRequest.addHeader(routeList);
1202            }
1203        }
1204        return ackRequest;
1205
1206    }
1207
1208    /*
1209     * Creates an ACK for an error response, according to RFC3261 section 17.1.1.3
1210     *
1211     * Note that this is different from an ACK for 2xx
1212     */
1213    private final Request createErrorAck() throws SipException, ParseException {
1214        SIPRequest originalRequest = this.getOriginalRequest();
1215        if (originalRequest == null)
1216            throw new SipException("bad state " + getState());
1217        if (!getMethod().equals(Request.INVITE)) {
1218            throw new SipException("Can only ACK an INVITE!");
1219        } else if (lastResponse == null) {
1220            throw new SipException("bad Transaction state");
1221        } else if (lastResponse.getStatusCode() < 200) {
1222            if (sipStack.isLoggingEnabled()) {
1223                sipStack.getStackLogger().logDebug("lastResponse = " + lastResponse);
1224            }
1225            throw new SipException("Cannot ACK a provisional response!");
1226        }
1227        return originalRequest.createErrorAck((To) lastResponse.getTo());
1228    }
1229
1230    /**
1231     * Set the port of the recipient.
1232     */
1233    protected void setViaPort(int port) {
1234        this.viaPort = port;
1235    }
1236
1237    /**
1238     * Set the port of the recipient.
1239     */
1240    protected void setViaHost(String host) {
1241        this.viaHost = host;
1242    }
1243
1244    /**
1245     * Get the port of the recipient.
1246     */
1247    public int getViaPort() {
1248        return this.viaPort;
1249    }
1250
1251    /**
1252     * Get the host of the recipient.
1253     */
1254    public String getViaHost() {
1255        return this.viaHost;
1256    }
1257
1258    /**
1259     * get the via header for an outgoing request.
1260     */
1261    public Via getOutgoingViaHeader() {
1262        return this.getMessageProcessor().getViaHeader();
1263    }
1264
1265    /**
1266     * This is called by the stack after a non-invite client transaction goes to completed state.
1267     */
1268    public void clearState() {
1269        // reduce the state to minimum
1270        // This assumes that the application will not need
1271        // to access the request once the transaction is
1272        // completed.
1273        // TODO -- revisit this - results in a null pointer
1274        // occuring occasionally.
1275        // this.lastRequest = null;
1276        // this.originalRequest = null;
1277        // this.lastResponse = null;
1278    }
1279
1280    /**
1281     * Sets a timeout after which the connection is closed (provided the server does not use the
1282     * connection for outgoing requests in this time period) and calls the superclass to set
1283     * state.
1284     */
1285    public void setState(TransactionState newState) {
1286        // Set this timer for connection caching
1287        // of incoming connections.
1288        if (newState == TransactionState.TERMINATED && this.isReliable()
1289                && (!getSIPStack().cacheClientConnections)) {
1290            // Set a time after which the connection
1291            // is closed.
1292            this.collectionTime = TIMER_J;
1293
1294        }
1295        if (super.getState() != TransactionState.COMPLETED
1296                && (newState == TransactionState.COMPLETED || newState == TransactionState.TERMINATED)) {
1297            sipStack.decrementActiveClientTransactionCount();
1298        }
1299        super.setState(newState);
1300    }
1301
1302    /**
1303     * Start the timer task.
1304     */
1305    protected  void startTransactionTimer() {
1306        if (this.transactionTimerStarted.compareAndSet(false, true)) {
1307	        TimerTask myTimer = new TransactionTimer();
1308	        if ( sipStack.getTimer() != null ) {
1309	            sipStack.getTimer().schedule(myTimer, BASE_TIMER_INTERVAL, BASE_TIMER_INTERVAL);
1310	        }
1311        }
1312    }
1313
1314    /*
1315     * Terminate a transaction. This marks the tx as terminated The tx scanner will run and remove
1316     * the tx. (non-Javadoc)
1317     *
1318     * @see javax.sip.Transaction#terminate()
1319     */
1320    public void terminate() throws ObjectInUseException {
1321        this.setState(TransactionState.TERMINATED);
1322
1323    }
1324
1325    /**
1326     * Check if the From tag of the response matches the from tag of the original message. A
1327     * Response with a tag mismatch should be dropped if a Dialog has been created for the
1328     * original request.
1329     *
1330     * @param sipResponse the response to check.
1331     * @return true if the check passes.
1332     */
1333    public boolean checkFromTag(SIPResponse sipResponse) {
1334        String originalFromTag = ((SIPRequest) this.getRequest()).getFromTag();
1335        if (this.defaultDialog != null) {
1336            if (originalFromTag == null ^ sipResponse.getFrom().getTag() == null) {
1337            	if (sipStack.isLoggingEnabled())
1338            		sipStack.getStackLogger().logDebug("From tag mismatch -- dropping response");
1339                return false;
1340            }
1341            if (originalFromTag != null
1342                    && !originalFromTag.equalsIgnoreCase(sipResponse.getFrom().getTag())) {
1343            	if (sipStack.isLoggingEnabled())
1344            		sipStack.getStackLogger().logDebug("From tag mismatch -- dropping response");
1345                return false;
1346            }
1347        }
1348        return true;
1349
1350    }
1351
1352    /*
1353     * (non-Javadoc)
1354     *
1355     * @see gov.nist.javax.sip.stack.ServerResponseInterface#processResponse(gov.nist.javax.sip.message.SIPResponse,
1356     *      gov.nist.javax.sip.stack.MessageChannel)
1357     */
1358    public void processResponse(SIPResponse sipResponse, MessageChannel incomingChannel) {
1359
1360        // If a dialog has already been created for this response,
1361        // pass it up.
1362        SIPDialog dialog = null;
1363        String method = sipResponse.getCSeq().getMethod();
1364        String dialogId = sipResponse.getDialogId(false);
1365        if (method.equals(Request.CANCEL) && lastRequest != null) {
1366            // JvB for CANCEL: use invite CT in CANCEL request to get dialog
1367            // (instead of stripping tag)
1368            SIPClientTransaction ict = (SIPClientTransaction) lastRequest.getInviteTransaction();
1369            if (ict != null) {
1370                dialog = ict.defaultDialog;
1371            }
1372        } else {
1373            dialog = this.getDialog(dialogId);
1374        }
1375
1376        // JvB: Check all conditions required for creating a new Dialog
1377        if (dialog == null) {
1378            int code = sipResponse.getStatusCode();
1379            if ((code > 100 && code < 300)
1380            /* skip 100 (may have a to tag */
1381            && (sipResponse.getToTag() != null || sipStack.isRfc2543Supported())
1382                    && sipStack.isDialogCreated(method)) {
1383
1384                /*
1385                 * Dialog cannot be found for the response. This must be a forked response. no
1386                 * dialog assigned to this response but a default dialog has been assigned. Note
1387                 * that if automatic dialog support is configured then a default dialog is always
1388                 * created.
1389                 */
1390
1391                synchronized (this) {
1392                    /*
1393                     * We need synchronization here because two responses may compete for the
1394                     * default dialog simultaneously
1395                     */
1396                    if (defaultDialog != null) {
1397                        if (sipResponse.getFromTag() != null) {
1398                            SIPResponse dialogResponse = defaultDialog.getLastResponse();
1399                            String defaultDialogId = defaultDialog.getDialogId();
1400                            if (dialogResponse == null
1401                                    || (method.equals(Request.SUBSCRIBE)
1402                                            && dialogResponse.getCSeq().getMethod().equals(
1403                                                    Request.NOTIFY) && defaultDialogId
1404                                            .equals(dialogId))) {
1405                                // The default dialog has not been claimed yet.
1406                                defaultDialog.setLastResponse(this, sipResponse);
1407                                dialog = defaultDialog;
1408                            } else {
1409                                /*
1410                                 * check if we have created one previously (happens in the case of
1411                                 * REINVITE processing. JvB: should not happen, this.defaultDialog
1412                                 * should then get set in Dialog#sendRequest line 1662
1413                                 */
1414
1415                                dialog = sipStack.getDialog(dialogId);
1416                                if (dialog == null) {
1417                                    if (defaultDialog.isAssigned()) {
1418                                        /*
1419                                         * Nop we dont have one. so go ahead and allocate a new
1420                                         * one.
1421                                         */
1422                                        dialog = sipStack.createDialog(this, sipResponse);
1423
1424                                    }
1425                                }
1426
1427                            }
1428                            if ( dialog != null ) {
1429                                this.setDialog(dialog, dialog.getDialogId());
1430                            } else {
1431                                sipStack.getStackLogger().logError("dialog is unexpectedly null",new NullPointerException());
1432                            }
1433                        } else {
1434                            throw new RuntimeException("Response without from-tag");
1435                        }
1436                    } else {
1437                        // Need to create a new Dialog, this becomes default
1438                        // JvB: not sure if this ever gets executed
1439                        if (sipStack.isAutomaticDialogSupportEnabled) {
1440                            dialog = sipStack.createDialog(this, sipResponse);
1441                            this.setDialog(dialog, dialog.getDialogId());
1442                        }
1443                    }
1444                } // synchronized
1445            } else {
1446                dialog = defaultDialog;
1447            }
1448        } else {
1449            dialog.setLastResponse(this, sipResponse);
1450        }
1451        this.processResponse(sipResponse, incomingChannel, dialog);
1452    }
1453
1454    /*
1455     * (non-Javadoc)
1456     *
1457     * @see gov.nist.javax.sip.stack.SIPTransaction#getDialog()
1458     */
1459    public  Dialog getDialog() {
1460        // This is for backwards compatibility.
1461        Dialog retval = null;
1462        if (this.lastResponse != null && this.lastResponse.getFromTag() != null
1463                && this.lastResponse.getToTag() != null
1464                && this.lastResponse.getStatusCode() != 100) {
1465            String dialogId = this.lastResponse.getDialogId(false);
1466            retval = (Dialog) getDialog(dialogId);
1467        }
1468
1469        if (retval == null) {
1470            retval = (Dialog) this.defaultDialog;
1471
1472        }
1473        if (sipStack.isLoggingEnabled()) {
1474            sipStack.getStackLogger().logDebug(
1475                    " sipDialogs =  " + sipDialogs + " default dialog " + this.defaultDialog
1476                            + " retval " + retval);
1477        }
1478        return retval;
1479
1480    }
1481
1482    /*
1483     * (non-Javadoc)
1484     *
1485     * @see gov.nist.javax.sip.stack.SIPTransaction#setDialog(gov.nist.javax.sip.stack.SIPDialog,
1486     *      gov.nist.javax.sip.message.SIPMessage)
1487     */
1488    public SIPDialog getDialog(String dialogId) {
1489        SIPDialog retval = (SIPDialog) this.sipDialogs.get(dialogId);
1490        return retval;
1491
1492    }
1493
1494    /*
1495     * (non-Javadoc)
1496     *
1497     * @see gov.nist.javax.sip.stack.SIPTransaction#setDialog(gov.nist.javax.sip.stack.SIPDialog,
1498     *      gov.nist.javax.sip.message.SIPMessage)
1499     */
1500    public void setDialog(SIPDialog sipDialog, String dialogId) {
1501        if (sipStack.isLoggingEnabled())
1502            sipStack.getStackLogger().logDebug(
1503                    "setDialog: " + dialogId + "sipDialog = " + sipDialog);
1504
1505        if (sipDialog == null) {
1506        	if (sipStack.isLoggingEnabled())
1507        		sipStack.getStackLogger().logError("NULL DIALOG!!");
1508            throw new NullPointerException("bad dialog null");
1509        }
1510        if (this.defaultDialog == null) {
1511            this.defaultDialog = sipDialog;
1512            if ( this.getMethod().equals(Request.INVITE) && this.getSIPStack().maxForkTime != 0) {
1513                this.getSIPStack().addForkedClientTransaction(this);
1514            }
1515        }
1516        if (dialogId != null && sipDialog.getDialogId() != null) {
1517            this.sipDialogs.put(dialogId, sipDialog);
1518
1519        }
1520
1521    }
1522
1523    public SIPDialog getDefaultDialog() {
1524        return this.defaultDialog;
1525    }
1526
1527    /**
1528     * Set the next hop ( if it has already been computed).
1529     *
1530     * @param hop -- the hop that has been previously computed.
1531     */
1532    public void setNextHop(Hop hop) {
1533        this.nextHop = hop;
1534
1535    }
1536
1537    /**
1538     * Reeturn the previously computed next hop (avoid computing it twice).
1539     *
1540     * @return -- next hop previously computed.
1541     */
1542    public Hop getNextHop() {
1543        return nextHop;
1544    }
1545
1546    /**
1547     * Set this flag if you want your Listener to get Timeout.RETRANSMIT notifications each time a
1548     * retransmission occurs.
1549     *
1550     * @param notifyOnRetransmit the notifyOnRetransmit to set
1551     */
1552    public void setNotifyOnRetransmit(boolean notifyOnRetransmit) {
1553        this.notifyOnRetransmit = notifyOnRetransmit;
1554    }
1555
1556    /**
1557     * @return the notifyOnRetransmit
1558     */
1559    public boolean isNotifyOnRetransmit() {
1560        return notifyOnRetransmit;
1561    }
1562
1563    public void alertIfStillInCallingStateBy(int count) {
1564        this.timeoutIfStillInCallingState = true;
1565        this.callingStateTimeoutCount = count;
1566    }
1567
1568
1569
1570}
1571