reSIProcate/stack  9694
TransactionState.hxx
Go to the documentation of this file.
00001 #if !defined(RESIP_TRANSACTIONSTATE_HXX)
00002 #define RESIP_TRANSACTIONSTATE_HXX
00003 
00004 #include <iosfwd>
00005 #include <memory>
00006 #include "rutil/dns/DnsHandler.hxx"
00007 #include "resip/stack/MethodTypes.hxx"
00008 #include "resip/stack/SipMessage.hxx"
00009 #include "resip/stack/Transport.hxx"
00010 #include "rutil/HeapInstanceCounter.hxx"
00011 
00012 namespace resip
00013 {
00014 
00015 class DnsResult;
00016 class TransactionMessage;
00017 class TimerMessage;
00018 class SendData;
00019 class TransactionMap;
00020 class TransactionController;
00021 class TransactionUser;
00022 class NameAddr;
00023 class Via;
00024 class MessageDecorator;
00025 
00029 class TransactionState : public DnsHandler
00030 {
00031    public:
00032       RESIP_HeapCount(TransactionState);
00033       static void process(TransactionController& controller,
00034                            TransactionMessage* message); 
00035       static void processTimer(TransactionController& controller,
00036                                  TimerMessage* timer); 
00037       ~TransactionState();
00038      
00039    private:
00040       typedef enum 
00041       {
00042          ClientNonInvite,
00043          ClientInvite,
00044          ServerNonInvite,
00045          ServerInvite,
00046          ClientStale,
00047          ServerStale,
00048          Stateless  // may not be needed
00049       } Machine;
00050       
00051       typedef enum 
00052       {
00053          Calling,
00054          Trying,
00055          Proceeding,
00056          Completed,
00057          Confirmed,
00058          Terminated,
00059          Bogus
00060       } State;
00061 
00062       TransactionState(TransactionController& controller, 
00063                        Machine m, 
00064                        State s, 
00065                        const Data& tid, 
00066                        MethodTypes method,
00067                        const Data& methodText,
00068                        TransactionUser* tu=0);
00069       
00070       void rewriteRequest(const Uri& rewrite);
00071       void handle(DnsResult*);
00072       void handleSync(DnsResult*);
00073       
00074       void processStateless(TransactionMessage* msg);
00075       void processClientNonInvite(TransactionMessage* msg);
00076       void processClientInvite(TransactionMessage* msg);
00077       void processServerNonInvite(TransactionMessage* msg);
00078       void processServerInvite(TransactionMessage* msg);
00079       void processClientStale(TransactionMessage* msg);
00080       void processServerStale(TransactionMessage* msg);
00081       void processTransportFailure(TransactionMessage* failure);
00082       void processNoDnsResults();
00083       void processReliability(TransportType type);
00084       
00085       void add(const Data& tid);
00086       void erase(const Data& tid);
00087       
00088       bool isClient() const;
00089    private:
00090       bool isRequest(TransactionMessage* msg) const;
00091       bool isInvite(TransactionMessage* msg) const;
00092       bool isTimer(TransactionMessage* msg) const;
00093       bool isResponse(TransactionMessage* msg, int lower=100, int upper=699) const;
00094       bool isFromTU(TransactionMessage* msg) const;
00095       bool isFromWire(TransactionMessage* msg) const;
00096       bool isTransportError(TransactionMessage* msg) const;
00097       bool isSentReliable(TransactionMessage* msg) const;
00098       bool isSentUnreliable(TransactionMessage* msg) const;
00099       bool isReliabilityIndication(TransactionMessage* msg) const;
00100       bool isSentIndication(TransactionMessage* msg) const;
00101       bool isAbandonServerTransaction(TransactionMessage* msg) const;
00102       bool isCancelClientTransaction(TransactionMessage* msg) const;
00103       void sendToTU(TransactionMessage* msg);
00104       static void sendToTU(TransactionUser* tu, TransactionController& controller, TransactionMessage* msg);
00105       void sendCurrentToWire();
00106       SipMessage* make100(SipMessage* request) const;
00107       void terminateClientTransaction(const Data& tid); 
00108       void terminateServerTransaction(const Data& tid); 
00109       const Data& tid(SipMessage* sip) const;
00110 
00111       void startServerNonInviteTimerTrying(SipMessage& sip, const Data& tid);
00112 
00113       static TransactionState* makeCancelTransaction(TransactionState* tran, Machine machine, const Data& tid);
00114       static void handleInternalCancel(SipMessage* cancel,
00115                                        TransactionState& clientInvite);
00122       static bool handleBadRequest(const resip::SipMessage& badReq,TransactionController& controller);
00123 
00124       void saveOriginalContactAndVia(const SipMessage& msg);
00125       void restoreOriginalContactAndVia();
00126       void resetNextTransmission(SipMessage* msg)
00127       {
00128          delete mNextTransmission;
00129          mNextTransmission=msg;
00130          mMsgToRetransmit.clear();
00131       }
00132 
00133       static bool processSipMessageAsNew(resip::SipMessage* sip, 
00134                                          resip::TransactionController& controller,
00135                                          const resip::Data& tid);
00136 
00137       TransactionController& mController;
00138       
00139       Machine mMachine;
00140       State mState;
00141       bool mIsAbandoned; // TU doesn't care about this transaction anymore.
00142       
00143       // Indicates that the message has been sent with a reliable protocol. Set
00144       // by the TransportSelector
00145       bool mIsReliable;
00146 
00147       // !bwc! sendCurrentToWire() uses these to determine what it should put on
00148       // the wire. If mMsgToRetransmit is non-empty, it goes on the wire 
00149       // _regardless_ of what mNextTransmission is. If mMsgToRetransmit is 
00150       // empty, but mNextTransmission is non-null, sendCurrentToWire() will try 
00151       // to send it.
00152       SipMessage* mNextTransmission;
00153       SendData mMsgToRetransmit;
00154 
00155       // Handle to the dns results queried by the TransportSelector
00156       DnsResult* mDnsResult;
00157 
00158       // current selection from the DnsResult. e.g. it is important to send the
00159       // CANCEL to exactly the same tuple as the original INVITE went to. 
00160       Tuple mTarget; 
00161       Tuple mResponseTarget; // used to reply to requests
00162 
00163       // used when the DnsResult moves to another transport on failure. Only
00164       // used for outgoing stateful, so auto_ptr for space efficiency.
00165       std::auto_ptr<NameAddr> mOriginalContact;
00166       std::auto_ptr<Via> mOriginalVia;
00167 
00168       const Data mId;
00169       const MethodTypes mMethod;
00170       Data* mMethodText;
00171 
00172       // These two apply to the message we're currently retransmitting.
00173       MethodTypes mCurrentMethodType;
00174       unsigned int mCurrentResponseCode;
00175 
00176       bool mAckIsValid;
00177       bool mWaitingForDnsResult;
00178       TransactionUser* mTransactionUser;
00179       TransportFailure::FailureReason mFailureReason;      
00180       int mFailureSubCode;
00181 
00182       static unsigned long StatelessIdCounter;
00183       
00184       friend EncodeStream& operator<<(EncodeStream& strm, const TransactionState& state);
00185       friend class TransactionController;
00186 };
00187 
00188 
00189 }
00190 
00191 #endif
00192 
00193 /* ====================================================================
00194  * The Vovida Software License, Version 1.0 
00195  * 
00196  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00197  * 
00198  * Redistribution and use in source and binary forms, with or without
00199  * modification, are permitted provided that the following conditions
00200  * are met:
00201  * 
00202  * 1. Redistributions of source code must retain the above copyright
00203  *    notice, this list of conditions and the following disclaimer.
00204  * 
00205  * 2. Redistributions in binary form must reproduce the above copyright
00206  *    notice, this list of conditions and the following disclaimer in
00207  *    the documentation and/or other materials provided with the
00208  *    distribution.
00209  * 
00210  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00211  *    and "Vovida Open Communication Application Library (VOCAL)" must
00212  *    not be used to endorse or promote products derived from this
00213  *    software without prior written permission. For written
00214  *    permission, please contact vocal@vovida.org.
00215  *
00216  * 4. Products derived from this software may not be called "VOCAL", nor
00217  *    may "VOCAL" appear in their name, without prior written
00218  *    permission of Vovida Networks, Inc.
00219  * 
00220  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00221  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00222  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00223  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00224  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00225  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00226  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00227  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00228  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00229  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00230  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00231  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00232  * DAMAGE.
00233  * 
00234  * ====================================================================
00235  * 
00236  * This software consists of voluntary contributions made by Vovida
00237  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00238  * Inc.  For more information on Vovida Networks, Inc., please see
00239  * <http://www.vovida.org/>.
00240  *
00241  */