Home | History | Annotate | Download | only in stack
      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  */
     26 package gov.nist.javax.sip.stack;
     27 
     28 import gov.nist.core.InternalErrorHandler;
     29 import gov.nist.javax.sip.SIPConstants;
     30 import gov.nist.javax.sip.ServerTransactionExt;
     31 import gov.nist.javax.sip.SipProviderImpl;
     32 import gov.nist.javax.sip.Utils;
     33 import gov.nist.javax.sip.header.Expires;
     34 import gov.nist.javax.sip.header.ParameterNames;
     35 import gov.nist.javax.sip.header.RSeq;
     36 import gov.nist.javax.sip.header.Via;
     37 import gov.nist.javax.sip.header.ViaList;
     38 import gov.nist.javax.sip.message.SIPMessage;
     39 import gov.nist.javax.sip.message.SIPRequest;
     40 import gov.nist.javax.sip.message.SIPResponse;
     41 
     42 import java.io.IOException;
     43 import java.text.ParseException;
     44 import java.util.TimerTask;
     45 import java.util.concurrent.Semaphore;
     46 import java.util.concurrent.TimeUnit;
     47 
     48 import javax.sip.Dialog;
     49 import javax.sip.DialogState;
     50 import javax.sip.DialogTerminatedEvent;
     51 import javax.sip.ObjectInUseException;
     52 import javax.sip.SipException;
     53 import javax.sip.Timeout;
     54 import javax.sip.TimeoutEvent;
     55 import javax.sip.TransactionState;
     56 import javax.sip.address.Hop;
     57 import javax.sip.header.ContactHeader;
     58 import javax.sip.header.ExpiresHeader;
     59 import javax.sip.header.RSeqHeader;
     60 import javax.sip.message.Request;
     61 import javax.sip.message.Response;
     62 
     63 /*
     64  * Bug fixes / enhancements:Emil Ivov, Antonis Karydas, Daniel J. Martinez Manzano, Daniel, Hagai
     65  * Sela, Vazques-Illa, Bill Roome, Thomas Froment and Pierre De Rop, Christophe Anzille and Jeroen
     66  * van Bemmel, Frank Reif.
     67  * Carolyn Beeton ( Avaya ).
     68  *
     69  */
     70 
     71 /**
     72  * Represents a server transaction. Implements the following state machines.
     73  *
     74  * <pre>
     75  *
     76  *
     77  *
     78  *                                                                      |INVITE
     79  *                                                                      |pass INV to TU
     80  *                                                   INVITE             V send 100 if TU won't in 200ms
     81  *                                                   send response+-----------+
     82  *                                                       +--------|           |--------+101-199 from TU
     83  *                                                       |        | Proceeding|        |send response
     84  *                                                       +-------&gt;|           |&lt;-------+
     85  *                                                                |           |          Transport Err.
     86  *                                                                |           |          Inform TU
     87  *                                                                |           |---------------&gt;+
     88  *                                                                +-----------+                |
     89  *                                                   300-699 from TU |     |2xx from TU        |
     90  *                                                   send response   |     |send response      |
     91  *                                                                   |     +------------------&gt;+
     92  *                                                                   |                         |
     93  *                                                   INVITE          V          Timer G fires  |
     94  *                                                   send response+-----------+ send response  |
     95  *                                                       +--------|           |--------+       |
     96  *                                                       |        | Completed |        |       |
     97  *                                                       +-------&gt;|           |&lt;-------+       |
     98  *                                                                +-----------+                |
     99  *                                                                   |     |                   |
    100  *                                                               ACK |     |                   |
    101  *                                                               -   |     +------------------&gt;+
    102  *                                                                   |        Timer H fires    |
    103  *                                                                   V        or Transport Err.|
    104  *                                                                +-----------+  Inform TU     |
    105  *                                                                |           |                |
    106  *                                                                | Confirmed |                |
    107  *                                                                |           |                |
    108  *                                                                +-----------+                |
    109  *                                                                      |                      |
    110  *                                                                      |Timer I fires         |
    111  *                                                                      |-                     |
    112  *                                                                      |                      |
    113  *                                                                      V                      |
    114  *                                                                +-----------+                |
    115  *                                                                |           |                |
    116  *                                                                | Terminated|&lt;---------------+
    117  *                                                                |           |
    118  *                                                                +-----------+
    119  *
    120  *                                                     Figure 7: INVITE server transaction
    121  *                                                         Request received
    122  *                                                                         |pass to TU
    123  *
    124  *                                                                         V
    125  *                                                                   +-----------+
    126  *                                                                   |           |
    127  *                                                                   | Trying    |-------------+
    128  *                                                                   |           |             |
    129  *                                                                   +-----------+             |200-699 from TU
    130  *                                                                         |                   |send response
    131  *                                                                         |1xx from TU        |
    132  *                                                                         |send response      |
    133  *                                                                         |                   |
    134  *                                                      Request            V      1xx from TU  |
    135  *                                                      send response+-----------+send response|
    136  *                                                          +--------|           |--------+    |
    137  *                                                          |        | Proceeding|        |    |
    138  *                                                          +-------&gt;|           |&lt;-------+    |
    139  *                                                   +&lt;--------------|           |             |
    140  *                                                   |Trnsprt Err    +-----------+             |
    141  *                                                   |Inform TU            |                   |
    142  *                                                   |                     |                   |
    143  *                                                   |                     |200-699 from TU    |
    144  *                                                   |                     |send response      |
    145  *                                                   |  Request            V                   |
    146  *                                                   |  send response+-----------+             |
    147  *                                                   |      +--------|           |             |
    148  *                                                   |      |        | Completed |&lt;------------+
    149  *                                                   |      +-------&gt;|           |
    150  *                                                   +&lt;--------------|           |
    151  *                                                   |Trnsprt Err    +-----------+
    152  *                                                   |Inform TU            |
    153  *                                                   |                     |Timer J fires
    154  *                                                   |                     |-
    155  *                                                   |                     |
    156  *                                                   |                     V
    157  *                                                   |               +-----------+
    158  *                                                   |               |           |
    159  *                                                   +--------------&gt;| Terminated|
    160  *                                                                   |           |
    161  *                                                                   +-----------+
    162  *
    163  *
    164  *
    165  *
    166  *
    167  * </pre>
    168  *
    169  * @version 1.2 $Revision: 1.118 $ $Date: 2010/01/10 00:13:14 $
    170  * @author M. Ranganathan
    171  *
    172  */
    173 public class SIPServerTransaction extends SIPTransaction implements ServerRequestInterface,
    174         javax.sip.ServerTransaction, ServerTransactionExt {
    175 
    176     // force the listener to see transaction
    177 
    178     private int rseqNumber;
    179 
    180     // private LinkedList pendingRequests;
    181 
    182     // Real RequestInterface to pass messages to
    183     private transient ServerRequestInterface requestOf;
    184 
    185     private SIPDialog dialog;
    186 
    187     // the unacknowledged SIPResponse
    188 
    189     private SIPResponse pendingReliableResponse;
    190 
    191     // The pending reliable Response Timer
    192     private ProvisionalResponseTask provisionalResponseTask;
    193 
    194     private boolean retransmissionAlertEnabled;
    195 
    196     private RetransmissionAlertTimerTask retransmissionAlertTimerTask;
    197 
    198     protected boolean isAckSeen;
    199 
    200     private SIPClientTransaction pendingSubscribeTransaction;
    201 
    202     private SIPServerTransaction inviteTransaction;
    203 
    204     private Semaphore provisionalResponseSem = new Semaphore(1);
    205 
    206     /**
    207      * This timer task is used for alerting the application to send retransmission alerts.
    208      *
    209      *
    210      */
    211     class RetransmissionAlertTimerTask extends SIPStackTimerTask {
    212 
    213         String dialogId;
    214 
    215         int ticks;
    216 
    217         int ticksLeft;
    218 
    219         public RetransmissionAlertTimerTask(String dialogId) {
    220 
    221             this.ticks = SIPTransaction.T1;
    222             this.ticksLeft = this.ticks;
    223         }
    224 
    225         protected void runTask() {
    226             SIPServerTransaction serverTransaction = SIPServerTransaction.this;
    227             ticksLeft--;
    228             if (ticksLeft == -1) {
    229                 serverTransaction.fireRetransmissionTimer();
    230                 this.ticksLeft = 2 * ticks;
    231             }
    232 
    233         }
    234 
    235     }
    236 
    237     class ProvisionalResponseTask extends SIPStackTimerTask {
    238 
    239         int ticks;
    240 
    241         int ticksLeft;
    242 
    243         public ProvisionalResponseTask() {
    244             this.ticks = SIPTransaction.T1;
    245             this.ticksLeft = this.ticks;
    246         }
    247 
    248         protected void runTask() {
    249             SIPServerTransaction serverTransaction = SIPServerTransaction.this;
    250             /*
    251              * The reliable provisional response is passed to the transaction layer periodically
    252              * with an interval that starts at T1 seconds and doubles for each retransmission (T1
    253              * is defined in Section 17 of RFC 3261). Once passed to the server transaction, it is
    254              * added to an internal list of unacknowledged reliable provisional responses. The
    255              * transaction layer will forward each retransmission passed from the UAS core.
    256              *
    257              * This differs from retransmissions of 2xx responses, whose intervals cap at T2
    258              * seconds. This is because retransmissions of ACK are triggered on receipt of a 2xx,
    259              * but retransmissions of PRACK take place independently of reception of 1xx.
    260              */
    261             // If the transaction has terminated,
    262             if (serverTransaction.isTerminated()) {
    263 
    264                 this.cancel();
    265 
    266             } else {
    267                 ticksLeft--;
    268                 if (ticksLeft == -1) {
    269                     serverTransaction.fireReliableResponseRetransmissionTimer();
    270                     this.ticksLeft = 2 * ticks;
    271                     this.ticks = this.ticksLeft;
    272                     // timer H MUST be set to fire in 64*T1 seconds for all transports. Timer H
    273                     // determines when the server
    274                     // transaction abandons retransmitting the response
    275                     if (this.ticksLeft >= SIPTransaction.TIMER_H) {
    276                         this.cancel();
    277                         setState(TERMINATED_STATE);
    278                         fireTimeoutTimer();
    279                     }
    280                 }
    281 
    282             }
    283 
    284         }
    285 
    286     }
    287 
    288     /**
    289      * This timer task will terminate the transaction if the listener does not respond in a
    290      * pre-determined time period. This helps prevent buggy listeners (who fail to respond) from
    291      * causing memory leaks. This allows a container to protect itself from buggy code ( that
    292      * fails to respond to a server transaction).
    293      *
    294      */
    295     class ListenerExecutionMaxTimer extends SIPStackTimerTask {
    296         SIPServerTransaction serverTransaction = SIPServerTransaction.this;
    297 
    298         ListenerExecutionMaxTimer() {
    299         }
    300 
    301         protected void runTask() {
    302             try {
    303                 if (serverTransaction.getState() == null) {
    304                     serverTransaction.terminate();
    305                     SIPTransactionStack sipStack = serverTransaction.getSIPStack();
    306                     sipStack.removePendingTransaction(serverTransaction);
    307                     sipStack.removeTransaction(serverTransaction);
    308 
    309                 }
    310             } catch (Exception ex) {
    311                 sipStack.getStackLogger().logError("unexpected exception", ex);
    312             }
    313         }
    314     }
    315 
    316     /**
    317      * This timer task is for INVITE server transactions. It will send a trying in 200 ms. if the
    318      * TU does not do so.
    319      *
    320      */
    321     class SendTrying extends SIPStackTimerTask {
    322 
    323         protected SendTrying() {
    324             if (sipStack.isLoggingEnabled())
    325                 sipStack.getStackLogger().logDebug("scheduled timer for " + SIPServerTransaction.this);
    326 
    327         }
    328 
    329         protected void runTask() {
    330             SIPServerTransaction serverTransaction = SIPServerTransaction.this;
    331 
    332             TransactionState realState = serverTransaction.getRealState();
    333 
    334             if (realState == null || TransactionState.TRYING == realState) {
    335                 if (sipStack.isLoggingEnabled())
    336                     sipStack.getStackLogger().logDebug(" sending Trying current state = "
    337                             + serverTransaction.getRealState());
    338                 try {
    339                     serverTransaction.sendMessage(serverTransaction.getOriginalRequest()
    340                             .createResponse(100, "Trying"));
    341                     if (sipStack.isLoggingEnabled())
    342                         sipStack.getStackLogger().logDebug(" trying sent "
    343                                 + serverTransaction.getRealState());
    344                 } catch (IOException ex) {
    345                     if (sipStack.isLoggingEnabled())
    346                         sipStack.getStackLogger().logError("IO error sending  TRYING");
    347                 }
    348             }
    349 
    350         }
    351     }
    352 
    353     class TransactionTimer extends SIPStackTimerTask {
    354 
    355         public TransactionTimer() {
    356             if (sipStack.isLoggingEnabled()) {
    357                 sipStack.getStackLogger().logDebug("TransactionTimer() : " + getTransactionId());
    358             }
    359 
    360         }
    361 
    362         protected void runTask() {
    363             // If the transaction has terminated,
    364             if (isTerminated()) {
    365                 // Keep the transaction hanging around in the transaction table
    366                 // to catch the incoming ACK -- this is needed for tcp only.
    367                 // Note that the transaction record is actually removed in
    368                 // the connection linger timer.
    369                 try {
    370                     this.cancel();
    371                 } catch (IllegalStateException ex) {
    372                     if (!sipStack.isAlive())
    373                         return;
    374                 }
    375 
    376                 // Oneshot timer that garbage collects the SeverTransaction
    377                 // after a scheduled amount of time. The linger timer allows
    378                 // the client side of the tx to use the same connection to
    379                 // send an ACK and prevents a race condition for creation
    380                 // of new server tx
    381                 TimerTask myTimer = new LingerTimer();
    382 
    383                 sipStack.getTimer().schedule(myTimer,
    384                         SIPTransactionStack.CONNECTION_LINGER_TIME * 1000);
    385 
    386             } else {
    387                 // Add to the fire list -- needs to be moved
    388                 // outside the synchronized block to prevent
    389                 // deadlock.
    390                 fireTimer();
    391 
    392             }
    393         }
    394 
    395     }
    396 
    397     /**
    398      * Send a response.
    399      *
    400      * @param transactionResponse -- the response to send
    401      *
    402      */
    403 
    404     private void sendResponse(SIPResponse transactionResponse) throws IOException {
    405 
    406         try {
    407             // RFC18.2.2. Sending Responses
    408             // The server transport uses the value of the top Via header field
    409             // in
    410             // order
    411             // to determine where to send a response.
    412             // It MUST follow the following process:
    413             // If the "sent-protocol" is a reliable transport
    414             // protocol such as TCP or SCTP,
    415             // or TLS over those, the response MUST be
    416             // sent using the existing connection
    417             // to the source of the original request
    418             // that created the transaction, if that connection is still open.
    419             if (isReliable()) {
    420 
    421                 getMessageChannel().sendMessage(transactionResponse);
    422 
    423                 // TODO If that connection attempt fails, the server SHOULD
    424                 // use SRV 3263 procedures
    425                 // for servers in order to determine the IP address
    426                 // and port to open the connection and send the response to.
    427 
    428             } else {
    429                 Via via = transactionResponse.getTopmostVia();
    430                 String transport = via.getTransport();
    431                 if (transport == null)
    432                     throw new IOException("missing transport!");
    433                 // @@@ hagai Symmetric NAT support
    434                 int port = via.getRPort();
    435                 if (port == -1)
    436                     port = via.getPort();
    437                 if (port == -1) {
    438                     if (transport.equalsIgnoreCase("TLS"))
    439                         port = 5061;
    440                     else
    441                         port = 5060;
    442                 }
    443 
    444                 // Otherwise, if the Via header field value contains a
    445                 // "maddr" parameter, the response MUST be forwarded to
    446                 // the address listed there, using the port indicated in
    447                 // "sent-by",
    448                 // or port 5060 if none is present. If the address is a
    449                 // multicast
    450                 // address, the response SHOULD be sent using
    451                 // the TTL indicated in the "ttl" parameter, or with a
    452                 // TTL of 1 if that parameter is not present.
    453                 String host = null;
    454                 if (via.getMAddr() != null) {
    455                     host = via.getMAddr();
    456                 } else {
    457                     // Otherwise (for unreliable unicast transports),
    458                     // if the top Via has a "received" parameter, the response
    459                     // MUST
    460                     // be sent to the
    461                     // address in the "received" parameter, using the port
    462                     // indicated
    463                     // in the
    464                     // "sent-by" value, or using port 5060 if none is specified
    465                     // explicitly.
    466                     host = via.getParameter(Via.RECEIVED);
    467                     if (host == null) {
    468                         // Otherwise, if it is not receiver-tagged, the response
    469                         // MUST be
    470                         // sent to the address indicated by the "sent-by" value,
    471                         // using the procedures in Section 5
    472                         // RFC 3263 PROCEDURE TO BE DONE HERE
    473                         host = via.getHost();
    474                     }
    475                 }
    476 
    477                 Hop hop = sipStack.addressResolver.resolveAddress(new HopImpl(host, port,
    478                         transport));
    479 
    480                 MessageChannel messageChannel = ((SIPTransactionStack) getSIPStack())
    481                         .createRawMessageChannel(this.getSipProvider().getListeningPoint(
    482                                 hop.getTransport()).getIPAddress(), this.getPort(), hop);
    483                 if (messageChannel != null)
    484                     messageChannel.sendMessage(transactionResponse);
    485                 else
    486                     throw new IOException("Could not create a message channel for " + hop);
    487 
    488             }
    489         } finally {
    490             this.startTransactionTimer();
    491         }
    492     }
    493 
    494     /**
    495      * Creates a new server transaction.
    496      *
    497      * @param sipStack Transaction stack this transaction belongs to.
    498      * @param newChannelToUse Channel to encapsulate.
    499      */
    500     protected SIPServerTransaction(SIPTransactionStack sipStack, MessageChannel newChannelToUse) {
    501 
    502         super(sipStack, newChannelToUse);
    503 
    504         if (sipStack.maxListenerResponseTime != -1) {
    505             sipStack.getTimer().schedule(new ListenerExecutionMaxTimer(),
    506                     sipStack.maxListenerResponseTime * 1000);
    507         }
    508 
    509         this.rseqNumber = (int) (Math.random() * 1000);
    510         // Only one outstanding request for a given server tx.
    511 
    512         if (sipStack.isLoggingEnabled()) {
    513             sipStack.getStackLogger().logDebug("Creating Server Transaction" + this.getBranchId());
    514             sipStack.getStackLogger().logStackTrace();
    515         }
    516 
    517     }
    518 
    519     /**
    520      * Sets the real RequestInterface this transaction encapsulates.
    521      *
    522      * @param newRequestOf RequestInterface to send messages to.
    523      */
    524     public void setRequestInterface(ServerRequestInterface newRequestOf) {
    525 
    526         requestOf = newRequestOf;
    527 
    528     }
    529 
    530     /**
    531      * Returns this transaction.
    532      */
    533     public MessageChannel getResponseChannel() {
    534 
    535         return this;
    536 
    537     }
    538 
    539 
    540 
    541     /**
    542      * Determines if the message is a part of this transaction.
    543      *
    544      * @param messageToTest Message to check if it is part of this transaction.
    545      *
    546      * @return True if the message is part of this transaction, false if not.
    547      */
    548     public boolean isMessagePartOfTransaction(SIPMessage messageToTest) {
    549 
    550         // List of Via headers in the message to test
    551         ViaList viaHeaders;
    552         // Topmost Via header in the list
    553         Via topViaHeader;
    554         // Branch code in the topmost Via header
    555         String messageBranch;
    556         // Flags whether the select message is part of this transaction
    557         boolean transactionMatches;
    558 
    559         transactionMatches = false;
    560 
    561         String method = messageToTest.getCSeq().getMethod();
    562         // Invite Server transactions linger in the terminated state in the
    563         // transaction
    564         // table and are matched to compensate for
    565         // http://bugs.sipit.net/show_bug.cgi?id=769
    566         if ((method.equals(Request.INVITE) || !isTerminated())) {
    567 
    568             // Get the topmost Via header and its branch parameter
    569             viaHeaders = messageToTest.getViaHeaders();
    570             if (viaHeaders != null) {
    571 
    572                 topViaHeader = (Via) viaHeaders.getFirst();
    573                 messageBranch = topViaHeader.getBranch();
    574                 if (messageBranch != null) {
    575 
    576                     // If the branch parameter exists but
    577                     // does not start with the magic cookie,
    578                     if (!messageBranch.toLowerCase().startsWith(
    579                             SIPConstants.BRANCH_MAGIC_COOKIE_LOWER_CASE)) {
    580 
    581                         // Flags this as old
    582                         // (RFC2543-compatible) client
    583                         // version
    584                         messageBranch = null;
    585 
    586                     }
    587 
    588                 }
    589 
    590                 // If a new branch parameter exists,
    591                 if (messageBranch != null && this.getBranch() != null) {
    592                     if (method.equals(Request.CANCEL)) {
    593                         // Cancel is handled as a special case because it
    594                         // shares the same same branch id of the invite
    595                         // that it is trying to cancel.
    596                         transactionMatches = this.getMethod().equals(Request.CANCEL)
    597                                 && getBranch().equalsIgnoreCase(messageBranch)
    598                                 && topViaHeader.getSentBy().equals(
    599                                         ((Via) getOriginalRequest().getViaHeaders().getFirst())
    600                                                 .getSentBy());
    601 
    602                     } else {
    603                         // Matching server side transaction with only the
    604                         // branch parameter.
    605                         transactionMatches = getBranch().equalsIgnoreCase(messageBranch)
    606                                 && topViaHeader.getSentBy().equals(
    607                                         ((Via) getOriginalRequest().getViaHeaders().getFirst())
    608                                                 .getSentBy());
    609 
    610                     }
    611 
    612                 } else {
    613                     // This is an RFC2543-compliant message; this code is here
    614                     // for backwards compatibility.
    615                     // It is a weak check.
    616                     // If RequestURI, To tag, From tag, CallID, CSeq number, and
    617                     // top Via headers are the same, the
    618                     // SIPMessage matches this transaction. An exception is for
    619                     // a CANCEL request, which is not deemed
    620                     // to be part of an otherwise-matching INVITE transaction.
    621                     String originalFromTag = super.fromTag;
    622 
    623                     String thisFromTag = messageToTest.getFrom().getTag();
    624 
    625                     boolean skipFrom = (originalFromTag == null || thisFromTag == null);
    626 
    627                     String originalToTag = super.toTag;
    628 
    629                     String thisToTag = messageToTest.getTo().getTag();
    630 
    631                     boolean skipTo = (originalToTag == null || thisToTag == null);
    632                     boolean isResponse = (messageToTest instanceof SIPResponse);
    633                     // Issue #96: special case handling for a CANCEL request -
    634                     // the CSeq method of the original request must
    635                     // be CANCEL for it to have a chance at matching.
    636                     if (messageToTest.getCSeq().getMethod().equalsIgnoreCase(Request.CANCEL)
    637                             && !getOriginalRequest().getCSeq().getMethod().equalsIgnoreCase(
    638                                     Request.CANCEL)) {
    639                         transactionMatches = false;
    640                     } else if ((isResponse || getOriginalRequest().getRequestURI().equals(
    641                             ((SIPRequest) messageToTest).getRequestURI()))
    642                             && (skipFrom || originalFromTag != null && originalFromTag.equalsIgnoreCase(thisFromTag))
    643                             && (skipTo || originalToTag != null && originalToTag.equalsIgnoreCase(thisToTag))
    644                             && getOriginalRequest().getCallId().getCallId().equalsIgnoreCase(
    645                                     messageToTest.getCallId().getCallId())
    646                             && getOriginalRequest().getCSeq().getSeqNumber() == messageToTest
    647                                     .getCSeq().getSeqNumber()
    648                             && ((!messageToTest.getCSeq().getMethod().equals(Request.CANCEL)) || getOriginalRequest()
    649                                     .getMethod().equals(messageToTest.getCSeq().getMethod()))
    650                             && topViaHeader.equals(getOriginalRequest().getViaHeaders()
    651                                     .getFirst())) {
    652 
    653                         transactionMatches = true;
    654                     }
    655 
    656                 }
    657 
    658             }
    659 
    660         }
    661         return transactionMatches;
    662 
    663     }
    664 
    665     /**
    666      * Send out a trying response (only happens when the transaction is mapped). Otherwise the
    667      * transaction is not known to the stack.
    668      */
    669     protected void map() {
    670         // note that TRYING is a pseudo-state for invite transactions
    671 
    672         TransactionState realState = getRealState();
    673 
    674         if (realState == null || realState == TransactionState.TRYING) {
    675             // JvB: Removed the condition 'dialog!=null'. Trying should also
    676             // be
    677             // sent by intermediate proxies. This fixes some TCK tests
    678             // null check added as the stack may be stopped.
    679             if (isInviteTransaction() && !this.isMapped && sipStack.getTimer() != null) {
    680                 this.isMapped = true;
    681                 // Schedule a timer to fire in 200 ms if the
    682                 // TU did not send a trying in that time.
    683                 sipStack.getTimer().schedule(new SendTrying(), 200);
    684 
    685             } else {
    686                 isMapped = true;
    687             }
    688         }
    689 
    690         // Pull it out of the pending transactions list.
    691         sipStack.removePendingTransaction(this);
    692     }
    693 
    694     /**
    695      * Return true if the transaction is known to stack.
    696      */
    697     public boolean isTransactionMapped() {
    698         return this.isMapped;
    699     }
    700 
    701     /**
    702      * Process a new request message through this transaction. If necessary, this message will
    703      * also be passed onto the TU.
    704      *
    705      * @param transactionRequest Request to process.
    706      * @param sourceChannel Channel that received this message.
    707      */
    708     public void processRequest(SIPRequest transactionRequest, MessageChannel sourceChannel) {
    709         boolean toTu = false;
    710 
    711         // Can only process a single request directed to the
    712         // transaction at a time. For a given server transaction
    713         // the listener sees only one event at a time.
    714 
    715         if (sipStack.isLoggingEnabled()) {
    716             sipStack.getStackLogger().logDebug("processRequest: " + transactionRequest.getFirstLine());
    717             sipStack.getStackLogger().logDebug("tx state = " + this.getRealState());
    718         }
    719 
    720         try {
    721 
    722             // If this is the first request for this transaction,
    723             if (getRealState() == null) {
    724                 // Save this request as the one this
    725                 // transaction is handling
    726                 setOriginalRequest(transactionRequest);
    727                 this.setState(TransactionState.TRYING);
    728                 toTu = true;
    729                 this.setPassToListener();
    730 
    731                 // Rsends the TRYING on retransmission of the request.
    732                 if (isInviteTransaction() && this.isMapped) {
    733                     // JvB: also
    734                     // proxies need
    735                     // to do this
    736 
    737                     // Has side-effect of setting
    738                     // state to "Proceeding"
    739                     sendMessage(transactionRequest.createResponse(100, "Trying"));
    740 
    741                 }
    742                 // If an invite transaction is ACK'ed while in
    743                 // the completed state,
    744             } else if (isInviteTransaction() && TransactionState.COMPLETED == getRealState()
    745                     && transactionRequest.getMethod().equals(Request.ACK)) {
    746 
    747                 // @jvB bug fix
    748                 this.setState(TransactionState.CONFIRMED);
    749                 disableRetransmissionTimer();
    750                 if (!isReliable()) {
    751                     enableTimeoutTimer(TIMER_I);
    752 
    753                 } else {
    754 
    755                     this.setState(TransactionState.TERMINATED);
    756 
    757                 }
    758 
    759                 // JvB: For the purpose of testing a TI, added a property to
    760                 // pass it anyway
    761                 if (sipStack.isNon2XXAckPassedToListener()) {
    762                     // This is useful for test applications that want to see
    763                     // all messages.
    764                     requestOf.processRequest(transactionRequest, this);
    765                 } else {
    766                     // According to RFC3261 Application should not Ack in
    767                     // CONFIRMED state
    768                     if (sipStack.isLoggingEnabled()) {
    769                         sipStack.getStackLogger().logDebug("ACK received for server Tx "
    770                                 + this.getTransactionId() + " not delivering to application!");
    771 
    772                     }
    773 
    774                     this.semRelease();
    775                 }
    776                 return;
    777 
    778                 // If we receive a retransmission of the original
    779                 // request,
    780             } else if (transactionRequest.getMethod().equals(getOriginalRequest().getMethod())) {
    781 
    782                 if (TransactionState.PROCEEDING == getRealState()
    783                         || TransactionState.COMPLETED == getRealState()) {
    784                     this.semRelease();
    785                     // Resend the last response to
    786                     // the client
    787                     if (lastResponse != null) {
    788 
    789                         // Send the message to the client
    790                         super.sendMessage(lastResponse);
    791 
    792                     }
    793                 } else if (transactionRequest.getMethod().equals(Request.ACK)) {
    794                     // This is passed up to the TU to suppress
    795                     // retransmission of OK
    796                     if (requestOf != null)
    797                         requestOf.processRequest(transactionRequest, this);
    798                     else
    799                         this.semRelease();
    800                 }
    801                 if (sipStack.isLoggingEnabled())
    802                 	sipStack.getStackLogger().logDebug("completed processing retransmitted request : "
    803                         + transactionRequest.getFirstLine() + this + " txState = "
    804                         + this.getState() + " lastResponse = " + this.getLastResponse());
    805                 return;
    806 
    807             }
    808 
    809             // Pass message to the TU
    810             if (TransactionState.COMPLETED != getRealState()
    811                     && TransactionState.TERMINATED != getRealState() && requestOf != null) {
    812                 if (getOriginalRequest().getMethod().equals(transactionRequest.getMethod())) {
    813                     // Only send original request to TU once!
    814                     if (toTu) {
    815                         requestOf.processRequest(transactionRequest, this);
    816                     } else
    817                         this.semRelease();
    818                 } else {
    819                     if (requestOf != null)
    820                         requestOf.processRequest(transactionRequest, this);
    821                     else
    822                         this.semRelease();
    823                 }
    824             } else {
    825                 // This seems like a common bug so I am allowing it through!
    826                 if (((SIPTransactionStack) getSIPStack()).isDialogCreated(getOriginalRequest()
    827                         .getMethod())
    828                         && getRealState() == TransactionState.TERMINATED
    829                         && transactionRequest.getMethod().equals(Request.ACK)
    830                         && requestOf != null) {
    831                     SIPDialog thisDialog = (SIPDialog) this.dialog;
    832 
    833                     if (thisDialog == null || !thisDialog.ackProcessed) {
    834                         // Filter out duplicate acks
    835                         if (thisDialog != null) {
    836                             thisDialog.ackReceived(transactionRequest);
    837                             thisDialog.ackProcessed = true;
    838                         }
    839                         requestOf.processRequest(transactionRequest, this);
    840                     } else {
    841                         this.semRelease();
    842                     }
    843 
    844                 } else if (transactionRequest.getMethod().equals(Request.CANCEL)) {
    845                     if (sipStack.isLoggingEnabled())
    846                         sipStack.getStackLogger().logDebug("Too late to cancel Transaction");
    847                     this.semRelease();
    848                     // send OK and just ignore the CANCEL.
    849                     try {
    850                         this.sendMessage(transactionRequest.createResponse(Response.OK));
    851                     } catch (IOException ex) {
    852                         // Transaction is already terminated
    853                         // just ignore the IOException.
    854                     }
    855                 }
    856                 if (sipStack.isLoggingEnabled())
    857                 	sipStack.getStackLogger().logDebug("Dropping request " + getRealState());
    858             }
    859 
    860         } catch (IOException e) {
    861         	if (sipStack.isLoggingEnabled())
    862         		sipStack.getStackLogger().logError("IOException " ,e);
    863             this.semRelease();
    864             this.raiseIOExceptionEvent();
    865         }
    866 
    867     }
    868 
    869     /**
    870      * Send a response message through this transactionand onto the client. The response drives
    871      * the state machine.
    872      *
    873      * @param messageToSend Response to process and send.
    874      */
    875     public void sendMessage(SIPMessage messageToSend) throws IOException {
    876         try {
    877             // Message typecast as a response
    878             SIPResponse transactionResponse;
    879             // Status code of the response being sent to the client
    880             int statusCode;
    881 
    882             // Get the status code from the response
    883             transactionResponse = (SIPResponse) messageToSend;
    884             statusCode = transactionResponse.getStatusCode();
    885 
    886             try {
    887                 // Provided we have set the banch id for this we set the BID for
    888                 // the
    889                 // outgoing via.
    890                 if (this.getOriginalRequest().getTopmostVia().getBranch() != null)
    891                     transactionResponse.getTopmostVia().setBranch(this.getBranch());
    892                 else
    893                     transactionResponse.getTopmostVia().removeParameter(ParameterNames.BRANCH);
    894 
    895                 // Make the topmost via headers match identically for the
    896                 // transaction rsponse.
    897                 if (!this.getOriginalRequest().getTopmostVia().hasPort())
    898                     transactionResponse.getTopmostVia().removePort();
    899             } catch (ParseException ex) {
    900                 ex.printStackTrace();
    901             }
    902 
    903             // Method of the response does not match the request used to
    904             // create the transaction - transaction state does not change.
    905             if (!transactionResponse.getCSeq().getMethod().equals(
    906                     getOriginalRequest().getMethod())) {
    907                 sendResponse(transactionResponse);
    908                 return;
    909             }
    910 
    911             // If the TU sends a provisional response while in the
    912             // trying state,
    913 
    914             if (getRealState() == TransactionState.TRYING) {
    915                 if (statusCode / 100 == 1) {
    916                     this.setState(TransactionState.PROCEEDING);
    917                 } else if (200 <= statusCode && statusCode <= 699) {
    918                     // INVITE ST has TRYING as a Pseudo state
    919                     // (See issue 76). We are using the TRYING
    920                     // pseudo state invite Transactions
    921                     // to signal if the application
    922                     // has sent trying or not and hence this
    923                     // check is necessary.
    924                     if (!isInviteTransaction()) {
    925                         if (!isReliable()) {
    926                             // Linger in the completed state to catch
    927                             // retransmissions if the transport is not
    928                             // reliable.
    929                             this.setState(TransactionState.COMPLETED);
    930                             // Note that Timer J is only set for Unreliable
    931                             // transports -- see Issue 75.
    932                             /*
    933                              * From RFC 3261 Section 17.2.2 (non-invite server transaction)
    934                              *
    935                              * When the server transaction enters the "Completed" state, it MUST
    936                              * set Timer J to fire in 64*T1 seconds for unreliable transports, and
    937                              * zero seconds for reliable transports. While in the "Completed"
    938                              * state, the server transaction MUST pass the final response to the
    939                              * transport layer for retransmission whenever a retransmission of the
    940                              * request is received. Any other final responses passed by the TU to
    941                              * the server transaction MUST be discarded while in the "Completed"
    942                              * state. The server transaction remains in this state until Timer J
    943                              * fires, at which point it MUST transition to the "Terminated" state.
    944                              */
    945                             enableTimeoutTimer(TIMER_J);
    946                         } else {
    947                             this.setState(TransactionState.TERMINATED);
    948                         }
    949                     } else {
    950                         // This is the case for INVITE server transactions.
    951                         // essentially, it duplicates the code in the
    952                         // PROCEEDING case below. There is no TRYING state for INVITE
    953                         // transactions in the RFC. We are using it to signal whether the
    954                         // application has sent a provisional response or not. Hence
    955                         // this is treated the same as as Proceeding.
    956                         if (statusCode / 100 == 2) {
    957                             // Status code is 2xx means that the
    958                             // transaction transitions to TERMINATED
    959                             // for both Reliable as well as unreliable
    960                             // transports. Note that the dialog layer
    961                             // takes care of retransmitting 2xx final
    962                             // responses.
    963                             /*
    964                              * RFC 3261 Section 13.3.1.4 Note, however, that the INVITE server
    965                              * transaction will be destroyed as soon as it receives this final
    966                              * response and passes it to the transport. Therefore, it is necessary
    967                              * to periodically pass the response directly to the transport until
    968                              * the ACK arrives. The 2xx response is passed to the transport with
    969                              * an interval that starts at T1 seconds and doubles for each
    970                              * retransmission until it reaches T2 seconds (T1 and T2 are defined
    971                              * in Section 17). Response retransmissions cease when an ACK request
    972                              * for the response is received. This is independent of whatever
    973                              * transport protocols are used to send the response.
    974                              */
    975                             this.disableRetransmissionTimer();
    976                             this.disableTimeoutTimer();
    977                             this.collectionTime = TIMER_J;
    978                             this.setState(TransactionState.TERMINATED);
    979                             if (this.dialog != null)
    980                                 this.dialog.setRetransmissionTicks();
    981                         } else {
    982                             // This an error final response.
    983                             this.setState(TransactionState.COMPLETED);
    984                             if (!isReliable()) {
    985                                 /*
    986                                  * RFC 3261
    987                                  *
    988                                  * While in the "Proceeding" state, if the TU passes a response
    989                                  * with status code from 300 to 699 to the server transaction, the
    990                                  * response MUST be passed to the transport layer for
    991                                  * transmission, and the state machine MUST enter the "Completed"
    992                                  * state. For unreliable transports, timer G is set to fire in T1
    993                                  * seconds, and is not set to fire for reliable transports.
    994                                  */
    995 
    996                                 enableRetransmissionTimer();
    997 
    998                             }
    999                             enableTimeoutTimer(TIMER_H);
   1000                         }
   1001                     }
   1002 
   1003                 }
   1004 
   1005                 // If the transaction is in the proceeding state,
   1006             } else if (getRealState() == TransactionState.PROCEEDING) {
   1007 
   1008                 if (isInviteTransaction()) {
   1009 
   1010                     // If the response is a failure message,
   1011                     if (statusCode / 100 == 2) {
   1012                         // Set up to catch returning ACKs
   1013                         // The transaction lingers in the
   1014                         // terminated state for some time
   1015                         // to catch retransmitted INVITEs
   1016                         this.disableRetransmissionTimer();
   1017                         this.disableTimeoutTimer();
   1018                         this.collectionTime = TIMER_J;
   1019                         this.setState(TransactionState.TERMINATED);
   1020                         if (this.dialog != null)
   1021                             this.dialog.setRetransmissionTicks();
   1022 
   1023                     } else if (300 <= statusCode && statusCode <= 699) {
   1024 
   1025                         // Set up to catch returning ACKs
   1026                         this.setState(TransactionState.COMPLETED);
   1027                         if (!isReliable()) {
   1028                             /*
   1029                              * While in the "Proceeding" state, if the TU passes a response with
   1030                              * status code from 300 to 699 to the server transaction, the response
   1031                              * MUST be passed to the transport layer for transmission, and the
   1032                              * state machine MUST enter the "Completed" state. For unreliable
   1033                              * transports, timer G is set to fire in T1 seconds, and is not set to
   1034                              * fire for reliable transports.
   1035                              */
   1036 
   1037                             enableRetransmissionTimer();
   1038 
   1039                         }
   1040                         enableTimeoutTimer(TIMER_H);
   1041 
   1042                     }
   1043 
   1044                     // If the transaction is not an invite transaction
   1045                     // and this is a final response,
   1046                 } else if (200 <= statusCode && statusCode <= 699) {
   1047                     // This is for Non-invite server transactions.
   1048 
   1049                     // Set up to retransmit this response,
   1050                     // or terminate the transaction
   1051                     this.setState(TransactionState.COMPLETED);
   1052                     if (!isReliable()) {
   1053 
   1054                         disableRetransmissionTimer();
   1055                         enableTimeoutTimer(TIMER_J);
   1056 
   1057                     } else {
   1058 
   1059                         this.setState(TransactionState.TERMINATED);
   1060 
   1061                     }
   1062 
   1063                 }
   1064 
   1065                 // If the transaction has already completed,
   1066             } else if (TransactionState.COMPLETED == this.getRealState()) {
   1067 
   1068                 return;
   1069             }
   1070 
   1071             try {
   1072                 // Send the message to the client.
   1073                 // Record the last message sent out.
   1074                 if (sipStack.isLoggingEnabled()) {
   1075                     sipStack.getStackLogger().logDebug(
   1076                             "sendMessage : tx = " + this + " getState = " + this.getState());
   1077                 }
   1078                 lastResponse = transactionResponse;
   1079                 this.sendResponse(transactionResponse);
   1080 
   1081             } catch (IOException e) {
   1082 
   1083                 this.setState(TransactionState.TERMINATED);
   1084                 this.collectionTime = 0;
   1085                 throw e;
   1086 
   1087             }
   1088         } finally {
   1089             this.startTransactionTimer();
   1090         }
   1091 
   1092     }
   1093 
   1094     public String getViaHost() {
   1095 
   1096         return getMessageChannel().getViaHost();
   1097 
   1098     }
   1099 
   1100     public int getViaPort() {
   1101 
   1102         return getMessageChannel().getViaPort();
   1103 
   1104     }
   1105 
   1106     /**
   1107      * Called by the transaction stack when a retransmission timer fires. This retransmits the
   1108      * last response when the retransmission filter is enabled.
   1109      */
   1110     protected void fireRetransmissionTimer() {
   1111 
   1112         try {
   1113             if (sipStack.isLoggingEnabled()) {
   1114                 sipStack.getStackLogger().logDebug("fireRetransmissionTimer() -- ");
   1115             }
   1116             // Resend the last response sent by this transaction
   1117             if (isInviteTransaction() && lastResponse != null) {
   1118                 // null can happen if this is terminating when the timer fires.
   1119                 if (!this.retransmissionAlertEnabled || sipStack.isTransactionPendingAck(this) ) {
   1120                     // Retransmit last response until ack.
   1121                     if (lastResponse.getStatusCode() / 100 > 2 && !this.isAckSeen)
   1122                         super.sendMessage(lastResponse);
   1123                 } else {
   1124                     // alert the application to retransmit the last response
   1125                     SipProviderImpl sipProvider = (SipProviderImpl) this.getSipProvider();
   1126                     TimeoutEvent txTimeout = new TimeoutEvent(sipProvider, this,
   1127                             Timeout.RETRANSMIT);
   1128                     sipProvider.handleEvent(txTimeout, this);
   1129                 }
   1130 
   1131             }
   1132         } catch (IOException e) {
   1133             if (sipStack.isLoggingEnabled())
   1134                 sipStack.getStackLogger().logException(e);
   1135             raiseErrorEvent(SIPTransactionErrorEvent.TRANSPORT_ERROR);
   1136 
   1137         }
   1138 
   1139     }
   1140 
   1141     private void fireReliableResponseRetransmissionTimer() {
   1142         try {
   1143 
   1144             super.sendMessage(this.pendingReliableResponse);
   1145 
   1146         } catch (IOException e) {
   1147             if (sipStack.isLoggingEnabled())
   1148                 sipStack.getStackLogger().logException(e);
   1149             this.setState(TransactionState.TERMINATED);
   1150             raiseErrorEvent(SIPTransactionErrorEvent.TRANSPORT_ERROR);
   1151 
   1152         }
   1153     }
   1154 
   1155     /**
   1156      * Called by the transaction stack when a timeout timer fires.
   1157      */
   1158     protected void fireTimeoutTimer() {
   1159 
   1160         if (sipStack.isLoggingEnabled())
   1161             sipStack.getStackLogger().logDebug("SIPServerTransaction.fireTimeoutTimer this = " + this
   1162                     + " current state = " + this.getRealState() + " method = "
   1163                     + this.getOriginalRequest().getMethod());
   1164 
   1165         if ( this.getMethod().equals(Request.INVITE) && sipStack.removeTransactionPendingAck(this) ) {
   1166             if ( sipStack.isLoggingEnabled() ) {
   1167                 sipStack.getStackLogger().logDebug("Found tx pending ACK - returning");
   1168             }
   1169             return;
   1170 
   1171         }
   1172         SIPDialog dialog = (SIPDialog) this.dialog;
   1173         if (((SIPTransactionStack) getSIPStack()).isDialogCreated(this.getOriginalRequest()
   1174                 .getMethod())
   1175                 && (TransactionState.CALLING == this.getRealState() || TransactionState.TRYING == this
   1176                         .getRealState())) {
   1177             dialog.setState(SIPDialog.TERMINATED_STATE);
   1178         } else if (getOriginalRequest().getMethod().equals(Request.BYE)) {
   1179             if (dialog != null && dialog.isTerminatedOnBye())
   1180                 dialog.setState(SIPDialog.TERMINATED_STATE);
   1181         }
   1182 
   1183         if (TransactionState.COMPLETED == this.getRealState() && isInviteTransaction()) {
   1184             raiseErrorEvent(SIPTransactionErrorEvent.TIMEOUT_ERROR);
   1185             this.setState(TransactionState.TERMINATED);
   1186             sipStack.removeTransaction(this);
   1187 
   1188         } else if (TransactionState.COMPLETED == this.getRealState() && !isInviteTransaction()) {
   1189             this.setState(TransactionState.TERMINATED);
   1190             sipStack.removeTransaction(this);
   1191 
   1192         } else if (TransactionState.CONFIRMED == this.getRealState() && isInviteTransaction()) {
   1193             // TIMER_I should not generate a timeout
   1194             // exception to the application when the
   1195             // Invite transaction is in Confirmed state.
   1196             // Just transition to Terminated state.
   1197             this.setState(TransactionState.TERMINATED);
   1198             sipStack.removeTransaction(this);
   1199         } else if (!isInviteTransaction()
   1200                 && (TransactionState.COMPLETED == this.getRealState() || TransactionState.CONFIRMED == this
   1201                         .getRealState())) {
   1202             this.setState(TransactionState.TERMINATED);
   1203         } else if (isInviteTransaction() && TransactionState.TERMINATED == this.getRealState()) {
   1204             // This state could be reached when retransmitting
   1205 
   1206             raiseErrorEvent(SIPTransactionErrorEvent.TIMEOUT_ERROR);
   1207             if (dialog != null)
   1208                 dialog.setState(SIPDialog.TERMINATED_STATE);
   1209         }
   1210 
   1211     }
   1212 
   1213     /**
   1214      * Get the last response.
   1215      */
   1216     public SIPResponse getLastResponse() {
   1217         return this.lastResponse;
   1218     }
   1219 
   1220     /**
   1221      * Set the original request.
   1222      */
   1223     public void setOriginalRequest(SIPRequest originalRequest) {
   1224         super.setOriginalRequest(originalRequest);
   1225 
   1226     }
   1227 
   1228     /*
   1229      * (non-Javadoc)
   1230      *
   1231      * @see javax.sip.ServerTransaction#sendResponse(javax.sip.message.Response)
   1232      */
   1233     public void sendResponse(Response response) throws SipException {
   1234         SIPResponse sipResponse = (SIPResponse) response;
   1235 
   1236         SIPDialog dialog = this.dialog;
   1237         if (response == null)
   1238             throw new NullPointerException("null response");
   1239 
   1240         try {
   1241             sipResponse.checkHeaders();
   1242         } catch (ParseException ex) {
   1243             throw new SipException(ex.getMessage());
   1244         }
   1245 
   1246         // check for meaningful response.
   1247         if (!sipResponse.getCSeq().getMethod().equals(this.getMethod())) {
   1248             throw new SipException(
   1249                     "CSeq method does not match Request method of request that created the tx.");
   1250         }
   1251 
   1252         /*
   1253          * 200-class responses to SUBSCRIBE requests also MUST contain an "Expires" header. The
   1254          * period of time in the response MAY be shorter but MUST NOT be longer than specified in
   1255          * the request.
   1256          */
   1257         if (this.getMethod().equals(Request.SUBSCRIBE) && response.getStatusCode() / 100 == 2) {
   1258 
   1259             if (response.getHeader(ExpiresHeader.NAME) == null) {
   1260                 throw new SipException("Expires header is mandatory in 2xx response of SUBSCRIBE");
   1261             } else {
   1262                 Expires requestExpires = (Expires) this.getOriginalRequest().getExpires();
   1263                 Expires responseExpires = (Expires) response.getExpires();
   1264                 /*
   1265                  * If no "Expires" header is present in a SUBSCRIBE request, the implied default
   1266                  * is defined by the event package being used.
   1267                  */
   1268                 if (requestExpires != null
   1269                         && responseExpires.getExpires() > requestExpires.getExpires()) {
   1270                     throw new SipException(
   1271                             "Response Expires time exceeds request Expires time : See RFC 3265 3.1.1");
   1272                 }
   1273             }
   1274 
   1275         }
   1276 
   1277         // Check for mandatory header.
   1278         if (sipResponse.getStatusCode() == 200
   1279                 && sipResponse.getCSeq().getMethod().equals(Request.INVITE)
   1280                 && sipResponse.getHeader(ContactHeader.NAME) == null)
   1281             throw new SipException("Contact Header is mandatory for the OK to the INVITE");
   1282 
   1283         if (!this.isMessagePartOfTransaction((SIPMessage) response)) {
   1284             throw new SipException("Response does not belong to this transaction.");
   1285         }
   1286 
   1287         // Fix up the response if the dialog has already been established.
   1288         try {
   1289             /*
   1290              * The UAS MAY send a final response to the initial request before
   1291              * having received PRACKs for all unacknowledged reliable provisional responses,
   1292              * unless the final response is 2xx and any of the unacknowledged reliable provisional
   1293              * responses contained a session description. In that case, it MUST NOT send a final
   1294              * response until those provisional responses are acknowledged.
   1295              */
   1296             if (this.pendingReliableResponse != null
   1297                     && this.getDialog() != null
   1298                     && this.getState() != TransactionState.TERMINATED
   1299                     && ((SIPResponse)response).getContentTypeHeader() != null
   1300                     && response.getStatusCode() / 100 == 2
   1301                     && ((SIPResponse)response).getContentTypeHeader().getContentType()
   1302                             .equalsIgnoreCase("application")
   1303                     && ((SIPResponse)response).getContentTypeHeader().getContentSubType()
   1304                             .equalsIgnoreCase("sdp")) {
   1305                 try {
   1306                     boolean acquired = this.provisionalResponseSem.tryAcquire(1,TimeUnit.SECONDS);
   1307                     if (!acquired ) {
   1308                         throw new SipException("cannot send response -- unacked povisional");
   1309                     }
   1310                 } catch (Exception ex) {
   1311                     this.sipStack.getStackLogger().logError("Could not acquire PRACK sem ", ex);
   1312                 }
   1313             } else {
   1314                 // Sending the final response cancels the
   1315                 // pending response task.
   1316                 if (this.pendingReliableResponse != null && sipResponse.isFinalResponse()) {
   1317                     this.provisionalResponseTask.cancel();
   1318                     this.provisionalResponseTask = null;
   1319                 }
   1320             }
   1321 
   1322             // Dialog checks. These make sure that the response
   1323             // being sent makes sense.
   1324             if (dialog != null) {
   1325                 if (sipResponse.getStatusCode() / 100 == 2
   1326                         && sipStack.isDialogCreated(sipResponse.getCSeq().getMethod())) {
   1327                     if (dialog.getLocalTag() == null && sipResponse.getTo().getTag() == null) {
   1328                         // Trying to send final response and user forgot to set
   1329                         // to
   1330                         // tag on the response -- be nice and assign the tag for
   1331                         // the user.
   1332                         sipResponse.getTo().setTag(Utils.getInstance().generateTag());
   1333                     } else if (dialog.getLocalTag() != null && sipResponse.getToTag() == null) {
   1334                         sipResponse.setToTag(dialog.getLocalTag());
   1335                     } else if (dialog.getLocalTag() != null && sipResponse.getToTag() != null
   1336                             && !dialog.getLocalTag().equals(sipResponse.getToTag())) {
   1337                         throw new SipException("Tag mismatch dialogTag is "
   1338                                 + dialog.getLocalTag() + " responseTag is "
   1339                                 + sipResponse.getToTag());
   1340                     }
   1341                 }
   1342 
   1343                 if (!sipResponse.getCallId().getCallId().equals(dialog.getCallId().getCallId())) {
   1344                     throw new SipException("Dialog mismatch!");
   1345                 }
   1346             }
   1347 
   1348 
   1349 
   1350             // Backward compatibility slippery slope....
   1351             // Only set the from tag in the response when the
   1352             // incoming request has a from tag.
   1353             String fromTag = ((SIPRequest) this.getRequest()).getFrom().getTag();
   1354             if (fromTag != null && sipResponse.getFromTag() != null
   1355                     && !sipResponse.getFromTag().equals(fromTag)) {
   1356                 throw new SipException("From tag of request does not match response from tag");
   1357             } else if (fromTag != null) {
   1358                 sipResponse.getFrom().setTag(fromTag);
   1359             } else {
   1360                 if (sipStack.isLoggingEnabled())
   1361                     sipStack.getStackLogger().logDebug("WARNING -- Null From tag in request!!");
   1362             }
   1363 
   1364 
   1365 
   1366             // See if the dialog needs to be inserted into the dialog table
   1367             // or if the state of the dialog needs to be changed.
   1368             if (dialog != null && response.getStatusCode() != 100) {
   1369                 dialog.setResponseTags(sipResponse);
   1370                 DialogState oldState = dialog.getState();
   1371                 dialog.setLastResponse(this, (SIPResponse) response);
   1372                 if (oldState == null && dialog.getState() == DialogState.TERMINATED) {
   1373                     DialogTerminatedEvent event = new DialogTerminatedEvent(dialog
   1374                             .getSipProvider(), dialog);
   1375 
   1376                     // Provide notification to the listener that the dialog has
   1377                     // ended.
   1378                     dialog.getSipProvider().handleEvent(event, this);
   1379 
   1380                 }
   1381 
   1382             } else if (dialog == null && this.getMethod().equals(Request.INVITE)
   1383                     && this.retransmissionAlertEnabled
   1384                     && this.retransmissionAlertTimerTask == null
   1385                     && response.getStatusCode() / 100 == 2) {
   1386                 String dialogId = ((SIPResponse) response).getDialogId(true);
   1387 
   1388                 this.retransmissionAlertTimerTask = new RetransmissionAlertTimerTask(dialogId);
   1389                 sipStack.retransmissionAlertTransactions.put(dialogId, this);
   1390                 sipStack.getTimer().schedule(this.retransmissionAlertTimerTask, 0,
   1391                         SIPTransactionStack.BASE_TIMER_INTERVAL);
   1392 
   1393             }
   1394 
   1395             // Send message after possibly inserting the Dialog
   1396             // into the dialog table to avoid a possible race condition.
   1397 
   1398             this.sendMessage((SIPResponse) response);
   1399 
   1400             if ( dialog != null ) {
   1401                 dialog.startRetransmitTimer(this, (SIPResponse)response);
   1402             }
   1403 
   1404         } catch (IOException ex) {
   1405             if (sipStack.isLoggingEnabled())
   1406                 sipStack.getStackLogger().logException(ex);
   1407             this.setState(TransactionState.TERMINATED);
   1408             raiseErrorEvent(SIPTransactionErrorEvent.TRANSPORT_ERROR);
   1409             throw new SipException(ex.getMessage());
   1410         } catch (java.text.ParseException ex1) {
   1411             if (sipStack.isLoggingEnabled())
   1412                 sipStack.getStackLogger().logException(ex1);
   1413             this.setState(TransactionState.TERMINATED);
   1414             throw new SipException(ex1.getMessage());
   1415         }
   1416     }
   1417 
   1418     /**
   1419      * Return the book-keeping information that we actually use.
   1420      */
   1421     private TransactionState getRealState() {
   1422         return super.getState();
   1423     }
   1424 
   1425     /**
   1426      * Return the current transaction state according to the RFC 3261 transaction state machine.
   1427      * Invite transactions do not have a trying state. We just use this as a pseudo state for
   1428      * processing requests.
   1429      *
   1430      * @return the state of the transaction.
   1431      */
   1432     public TransactionState getState() {
   1433         // Trying is a pseudo state for INVITE transactions.
   1434         if (this.isInviteTransaction() && TransactionState.TRYING == super.getState())
   1435             return TransactionState.PROCEEDING;
   1436         else
   1437             return super.getState();
   1438     }
   1439 
   1440     /**
   1441      * Sets a timeout after which the connection is closed (provided the server does not use the
   1442      * connection for outgoing requests in this time period) and calls the superclass to set
   1443      * state.
   1444      */
   1445     public void setState(TransactionState newState) {
   1446         // Set this timer for connection caching
   1447         // of incoming connections.
   1448         if (newState == TransactionState.TERMINATED && this.isReliable()
   1449                 && (!getSIPStack().cacheServerConnections)) {
   1450             // Set a time after which the connection
   1451             // is closed.
   1452             this.collectionTime = TIMER_J;
   1453         }
   1454 
   1455         super.setState(newState);
   1456 
   1457     }
   1458 
   1459     /**
   1460      * Start the timer task.
   1461      */
   1462     protected void startTransactionTimer() {
   1463         if (this.transactionTimerStarted.compareAndSet(false, true)) {
   1464         	if (sipStack.getTimer() != null) {
   1465                 // The timer is set to null when the Stack is
   1466                 // shutting down.
   1467                 TimerTask myTimer = new TransactionTimer();
   1468                 sipStack.getTimer().schedule(myTimer, BASE_TIMER_INTERVAL, BASE_TIMER_INTERVAL);
   1469             }
   1470         }
   1471     }
   1472 
   1473     public boolean equals(Object other) {
   1474         if (!other.getClass().equals(this.getClass())) {
   1475             return false;
   1476         }
   1477         SIPServerTransaction sst = (SIPServerTransaction) other;
   1478         return this.getBranch().equalsIgnoreCase(sst.getBranch());
   1479     }
   1480 
   1481     /*
   1482      * (non-Javadoc)
   1483      *
   1484      * @see gov.nist.javax.sip.stack.SIPTransaction#getDialog()
   1485      */
   1486     public Dialog getDialog() {
   1487 
   1488         return this.dialog;
   1489     }
   1490 
   1491     /*
   1492      * (non-Javadoc)
   1493      *
   1494      * @see gov.nist.javax.sip.stack.SIPTransaction#setDialog(gov.nist.javax.sip.stack.SIPDialog,
   1495      *      gov.nist.javax.sip.message.SIPMessage)
   1496      */
   1497     public void setDialog(SIPDialog sipDialog, String dialogId) {
   1498         if (sipStack.isLoggingEnabled())
   1499             sipStack.getStackLogger().logDebug("setDialog " + this + " dialog = " + sipDialog);
   1500         this.dialog = sipDialog;
   1501         if (dialogId != null)
   1502             this.dialog.setAssigned();
   1503         if (this.retransmissionAlertEnabled && this.retransmissionAlertTimerTask != null) {
   1504             this.retransmissionAlertTimerTask.cancel();
   1505             if (this.retransmissionAlertTimerTask.dialogId != null) {
   1506                 sipStack.retransmissionAlertTransactions
   1507                         .remove(this.retransmissionAlertTimerTask.dialogId);
   1508             }
   1509             this.retransmissionAlertTimerTask = null;
   1510         }
   1511 
   1512         this.retransmissionAlertEnabled = false;
   1513 
   1514     }
   1515 
   1516     /*
   1517      * (non-Javadoc)
   1518      *
   1519      * @see javax.sip.Transaction#terminate()
   1520      */
   1521     public void terminate() throws ObjectInUseException {
   1522         this.setState(TransactionState.TERMINATED);
   1523         if (this.retransmissionAlertTimerTask != null) {
   1524             this.retransmissionAlertTimerTask.cancel();
   1525             if (retransmissionAlertTimerTask.dialogId != null) {
   1526                 this.sipStack.retransmissionAlertTransactions
   1527                         .remove(retransmissionAlertTimerTask.dialogId);
   1528             }
   1529             this.retransmissionAlertTimerTask = null;
   1530 
   1531         }
   1532 
   1533     }
   1534 
   1535     protected void sendReliableProvisionalResponse(Response relResponse) throws SipException {
   1536 
   1537         /*
   1538          * After the first reliable provisional response for a request has been acknowledged, the
   1539          * UAS MAY send additional reliable provisional responses. The UAS MUST NOT send a second
   1540          * reliable provisional response until the first is acknowledged.
   1541          */
   1542         if (this.pendingReliableResponse != null) {
   1543             throw new SipException("Unacknowledged response");
   1544 
   1545         } else
   1546             this.pendingReliableResponse = (SIPResponse) relResponse;
   1547         /*
   1548          * In addition, it MUST contain a Require header field containing the option tag 100rel,
   1549          * and MUST include an RSeq header field.
   1550          */
   1551         RSeq rseq = (RSeq) relResponse.getHeader(RSeqHeader.NAME);
   1552         if (relResponse.getHeader(RSeqHeader.NAME) == null) {
   1553             rseq = new RSeq();
   1554             relResponse.setHeader(rseq);
   1555         }
   1556 
   1557         try {
   1558             this.rseqNumber++;
   1559             rseq.setSeqNumber(this.rseqNumber);
   1560 
   1561             // start the timer task which will retransmit the reliable response
   1562             // until the PRACK is received
   1563             this.lastResponse = (SIPResponse) relResponse;
   1564             if ( this.getDialog() != null ) {
   1565                 boolean acquired = this.provisionalResponseSem.tryAcquire(1, TimeUnit.SECONDS);
   1566                 if (!acquired) {
   1567                     throw new SipException("Unacknowledged response");
   1568                 }
   1569             }
   1570             this.sendMessage((SIPMessage) relResponse);
   1571             this.provisionalResponseTask = new ProvisionalResponseTask();
   1572             this.sipStack.getTimer().schedule(provisionalResponseTask, 0,
   1573                     SIPTransactionStack.BASE_TIMER_INTERVAL);
   1574 
   1575 
   1576         } catch (Exception ex) {
   1577             InternalErrorHandler.handleException(ex);
   1578         }
   1579 
   1580     }
   1581 
   1582     public SIPResponse getReliableProvisionalResponse() {
   1583 
   1584         return this.pendingReliableResponse;
   1585     }
   1586 
   1587     /**
   1588      * Cancel the retransmit timer for the provisional response task.
   1589      *
   1590      * @return true if the tx has seen the prack for the first time and false otherwise.
   1591      *
   1592      */
   1593     public boolean prackRecieved() {
   1594 
   1595         if (this.pendingReliableResponse == null)
   1596             return false;
   1597         if(provisionalResponseTask != null)
   1598         	this.provisionalResponseTask.cancel();
   1599         this.pendingReliableResponse = null;
   1600         this.provisionalResponseSem.release();
   1601         return true;
   1602     }
   1603 
   1604     /*
   1605      * (non-Javadoc)
   1606      *
   1607      * @see javax.sip.ServerTransaction#enableRetransmissionAlerts()
   1608      */
   1609 
   1610     public void enableRetransmissionAlerts() throws SipException {
   1611         if (this.getDialog() != null)
   1612             throw new SipException("Dialog associated with tx");
   1613 
   1614         else if (!this.getMethod().equals(Request.INVITE))
   1615             throw new SipException("Request Method must be INVITE");
   1616 
   1617         this.retransmissionAlertEnabled = true;
   1618 
   1619     }
   1620 
   1621     public boolean isRetransmissionAlertEnabled() {
   1622         return this.retransmissionAlertEnabled;
   1623     }
   1624 
   1625     /**
   1626      * Disable retransmission Alerts and cancel associated timers.
   1627      *
   1628      */
   1629     public void disableRetransmissionAlerts() {
   1630         if (this.retransmissionAlertTimerTask != null && this.retransmissionAlertEnabled) {
   1631             this.retransmissionAlertTimerTask.cancel();
   1632             this.retransmissionAlertEnabled = false;
   1633 
   1634             String dialogId = this.retransmissionAlertTimerTask.dialogId;
   1635             if (dialogId != null) {
   1636                 sipStack.retransmissionAlertTransactions.remove(dialogId);
   1637             }
   1638             this.retransmissionAlertTimerTask = null;
   1639         }
   1640     }
   1641 
   1642     /**
   1643      * This is book-keeping for retransmission filter management.
   1644      */
   1645     public void setAckSeen() {
   1646         this.isAckSeen = true;
   1647     }
   1648 
   1649     /**
   1650      * This is book-keeping for retransmission filter management.
   1651      */
   1652     public boolean ackSeen() {
   1653         return this.isAckSeen;
   1654     }
   1655 
   1656     public void setMapped(boolean b) {
   1657         this.isMapped = true;
   1658 
   1659     }
   1660 
   1661     public void setPendingSubscribe(SIPClientTransaction pendingSubscribeClientTx) {
   1662         this.pendingSubscribeTransaction = pendingSubscribeClientTx;
   1663 
   1664     }
   1665 
   1666     public void releaseSem() {
   1667         if (this.pendingSubscribeTransaction != null) {
   1668             /*
   1669              * When a notify is being processed we take a lock on the subscribe to avoid racing
   1670              * with the OK of the subscribe.
   1671              */
   1672             pendingSubscribeTransaction.releaseSem();
   1673         } else if (this.inviteTransaction != null && this.getMethod().equals(Request.CANCEL)) {
   1674             /*
   1675              * When a CANCEL is being processed we take a nested lock on the associated INVITE
   1676              * server tx.
   1677              */
   1678             this.inviteTransaction.releaseSem();
   1679         }
   1680         super.releaseSem();
   1681     }
   1682 
   1683     /**
   1684      * The INVITE Server Transaction corresponding to a CANCEL Server Transaction.
   1685      *
   1686      * @param st -- the invite server tx corresponding to the cancel server transaction.
   1687      */
   1688     public void setInviteTransaction(SIPServerTransaction st) {
   1689         this.inviteTransaction = st;
   1690 
   1691     }
   1692 
   1693     /**
   1694      * TODO -- this method has to be added to the api.
   1695      *
   1696      * @return
   1697      */
   1698     public SIPServerTransaction getCanceledInviteTransaction() {
   1699         return this.inviteTransaction;
   1700     }
   1701 
   1702     public void scheduleAckRemoval() throws IllegalStateException {
   1703         if (this.getMethod() == null || !this.getMethod().equals(Request.ACK)) {
   1704             throw new IllegalStateException("Method is null[" + (getMethod() == null)
   1705                     + "] or method is not ACK[" + this.getMethod() + "]");
   1706         }
   1707 
   1708         this.startTransactionTimer();
   1709     }
   1710 
   1711 }
   1712