reSIProcate/repro  9694
ResponseContext.hxx
Go to the documentation of this file.
00001 #if !defined(RESIP_RESPONSE_CONTEXT_HXX)
00002 #define RESIP_RESPONSE_CONTEXT_HXX 
00003 
00004 #include <iosfwd>
00005 #include <map>
00006 #include <list>
00007 
00008 #include "rutil/HashMap.hxx"
00009 #include "resip/stack/NameAddr.hxx"
00010 #include "resip/stack/SipMessage.hxx"
00011 #include "resip/stack/Via.hxx"
00012 #include "resip/stack/Uri.hxx"
00013 #include "resip/stack/MessageDecorator.hxx"
00014 
00015 #include "repro/Target.hxx"
00016 #include "rutil/resipfaststreams.hxx"
00017 
00018 namespace resip
00019 {
00020 class SipMessage;
00021 class Transport;
00022 }
00023 
00024 namespace repro
00025 {
00026 
00027 class RequestContext;
00028 
00029 class ResponseContext
00030 {
00031    public:
00032       class CompareStatus  : public std::binary_function<const resip::SipMessage&, const resip::SipMessage&, bool>  
00033       {
00034          public:
00035             bool operator()(const resip::SipMessage& lhs, const resip::SipMessage& rhs) const;
00036       };      
00037       
00038       ~ResponseContext();
00039 
00040       /**
00041          Adds this Target as a SimpleTarget to the collection of Targets.
00042          
00043          @param target The NameAdder used to form the Target to add.
00044 
00045          @param beginImmediately Whether to immediately start a transaction for this target.
00046 
00047          @returns tid of the newly added target
00048          
00049          @note Targets are not checked for duplicate uris until an attempt is made to begin them.
00050       */
00051       resip::Data addTarget(const resip::NameAddr& target, bool beginImmediately=false);
00052 
00053       /**
00054          Adds this Target to the collection of Targets.
00055          
00056          @param target The Target to add.
00057 
00058          @param beginImmediately Whether to immediately start a transaction 
00059             for this target.
00060 
00061          @returns If beginImmediately=false, true iff the Target was
00062          successfully added (could happen if a final response has already
00063          been forwarded). If beginImmediately=true, true iff a transaction
00064          was successfully started for the Target (could fail due to the 
00065          presence of a duplicate contact, or when a final response has
00066          already been forwarded.)
00067          
00068          @note Targets are not checked for duplicate uris until an attempt 
00069             is made to start them.
00070       */
00071       bool addTarget(std::auto_ptr<repro::Target> target, bool beginImmediately=false);
00072 
00073       /**
00074          Adds a batch of Targets. 
00075          
00076          @note RESPONSECONTEXT ASSUMES OWNERSHIP OF THE TARGETS POINTED
00077              TO IN THIS LIST!
00078          
00079          @param targets A list of (sorted) Target*. This list is consumed.
00080             
00081          @param highPriority Whether or not the Target ProccessorChain should 
00082             prioritize this batch above other batches of the same type.
00083             (This is primarily intended to let multiple recursive redirection
00084             work properly, but can be used for other purposes.)
00085          
00086          @returns true iff any Targets were added.
00087          
00088          @note It is assumed that all of these Targets are 
00089          the same subclass of Target, and that they are already sorted in the
00090          order of their priority. If these assumptions do not hold, things
00091          will not break per se, but oddball target processing behavior might
00092          result.
00093       */
00094       bool addTargetBatch(TargetPtrList& targets, bool highPriority=false);
00095             
00096       /**
00097          Begins all Candidate client transactions.
00098          
00099          @returns true iff any transactions were started
00100       */
00101       bool beginClientTransactions();
00102       
00103       /** 
00104          Begins a client transaction.
00105       
00106          @param serial The transaction id to start.
00107          
00108          @returns true iff the transaction was started (could fail if there was
00109          a duplicate contact)
00110       
00111       */
00112       bool beginClientTransaction(const resip::Data& serial);
00113       
00114       /**
00115          Cancels all active client transactions. Does not clear Candidate
00116          transactions.
00117          
00118          @returns true iff any transaction was placed in either the
00119          WaitingToCancel or Cancelled state.
00120       */ 
00121       bool cancelActiveClientTransactions();
00122       
00123       /**
00124          Cancels all active client transactions. Also clears Candidate
00125          transactions (they are transitioned directly to Terminated)
00126          
00127          @returns true iff any transaction was placed in either the
00128          WaitingToCancel, Cancelled, or Terminated state.
00129       */ 
00130       bool cancelAllClientTransactions();
00131       
00132       /**
00133          Removes all Candidate transactions.
00134          
00135          @returns true iff at least one Candidate transaction was removed.
00136       */
00137       bool clearCandidateTransactions();
00138       
00139       /**
00140          Cancels this client transaction if active, or Terminates it if
00141          Candidate.
00142          
00143          @returns true iff this transaction was placed in either the 
00144          WaitingToCancel, Cancelled, or Terminated state.
00145       */
00146       bool cancelClientTransaction(const resip::Data& serial);
00147             
00148       /**
00149          Self-explanatory
00150       */
00151       Target* getTarget(const resip::Data& serial) const;
00152 
00153       //Keyed by transaction id
00154       typedef std::map<resip::Data,repro::Target*> TransactionMap;
00155 
00156       /**
00157          Self-explanatory.
00158 
00159          @note Can be used to decide which targets should be processed next,
00160          although this assumes a great deal of interdependency btw
00161          the various processor chains and homogeneity in how the Targets are
00162          prioritized, and can be inefficient if there
00163          are large numbers of Candidate Targets. A more structured approach
00164          exists in the functions dealing with TransactionBatch.
00165       */
00166       const TransactionMap& getCandidateTransactionMap() const;
00167       
00168       /**
00169          @returns true iff there are Candidate targets
00170       */
00171       bool hasCandidateTransactions() const;
00172       
00173       /**
00174          @returns true iff there are active targets (in state Trying,
00175          Proceeding, WaitingForCancel or Cancelled)
00176       */
00177       bool hasActiveTransactions() const;
00178       
00179       /**
00180          @returns true iff there are Terminated targets.
00181       */
00182       bool hasTerminatedTransactions() const;
00183 
00184       bool hasTargets() const;
00185       
00186       /**
00187          @returns true iff this target is in state Candidate
00188       */
00189       bool isCandidate(const resip::Data& tid) const;
00190       
00191       /**
00192          @returns true iff this target is active (Trying, Proceeding,
00193          WaitingForCancel, or Cancelled)
00194       */
00195       bool isActive(const resip::Data& tid) const;
00196       
00197       /**
00198          @returns true iff this target is in state Terminated
00199       */
00200       bool isTerminated(const resip::Data& tid) const;
00201       
00202       /**
00203          @returns true iff all targets are in state Terminated
00204       */
00205       bool areAllTransactionsTerminated() const;
00206 
00207       
00208       int getPriority(const resip::SipMessage& msg);
00209 
00210       //!bwc! This should probably not be private, since these two classes are
00211       //tightly coupled.
00212       RequestContext& mRequestContext;
00213       
00214       std::list<std::list<resip::Data> > mTransactionQueueCollection;
00215       resip::Data mCurrentResponseTid;
00216 
00217    private:
00218       // only constructed by RequestContext
00219       ResponseContext(RequestContext& parent);
00220 
00221       // These methods are really private. These are not intended to be used
00222       // by anything other than RequestContext or ResponseContext.
00223 
00224       // call this from RequestContext when a CANCEL comes in 
00225       void processCancel(const resip::SipMessage& request);
00226 
00227       // call this from RequestContext after the lemur chain for any response 
00228       void processResponse(resip::SipMessage& response);
00229 
00230       void processTimerC();
00231 
00232       void beginClientTransaction(repro::Target* target);
00233       void cancelClientTransaction(repro::Target* target);
00234 
00235 
00236       void terminateClientTransaction(const resip::Data& tid);
00237       void removeClientTransaction(const resip::Data& transactionId); 
00238       
00239       //There is no terminateClientTransaction(Target target) since terminating
00240       //a branch is very simple. The guts can be found in the API functions.
00241       
00242       void insertRecordRoute(resip::SipMessage& outgoing,
00243                              const resip::Transport* receivedTransport,
00244                              Target* target,
00245                              bool doPathInstead=false);
00246       resip::Data getInboundFlowToken(bool doPathInstead);
00247       bool outboundFlowTokenNeeded(Target* target);
00248       bool needsFlowTokenToWork(const resip::NameAddr& contact) const;
00249       bool sendingToSelf(Target* target);
00250 
00251       void sendRequest(resip::SipMessage& request);
00252       
00253       TransactionMap mCandidateTransactionMap; //Targets with status Candidate.
00254       TransactionMap mActiveTransactionMap; //Targets with status Trying, Proceeding, or WaitingToCancel.
00255       TransactionMap mTerminatedTransactionMap; //Targets with status Terminated.
00256 
00257       //Maybe someday canonicalized Uris will go here, and checking for duplicates
00258       //will be much faster
00259       resip::ContactList mTargetList;
00260       
00261       bool isDuplicate(const repro::Target* target) const;
00262       
00263       resip::SipMessage mBestResponse;
00264       int mBestPriority;
00265       bool mSecure;
00266       bool mIsClientBehindNAT;  // Only set if InteropHelper::getClientNATDetectionEnabled() is true
00267 
00268       void forwardBestResponse();
00269 
00270       friend class RequestContext;
00271       friend EncodeStream& operator<<(EncodeStream& strm, const repro::ResponseContext& rc);
00272 };
00273 
00274 EncodeStream&
00275 operator<<(EncodeStream& strm, const repro::ResponseContext& rc);
00276 
00277 }
00278 #endif
00279 
00280 /* ====================================================================
00281  * The Vovida Software License, Version 1.0 
00282  * 
00283  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00284  * 
00285  * Redistribution and use in source and binary forms, with or without
00286  * modification, are permitted provided that the following conditions
00287  * are met:
00288  * 
00289  * 1. Redistributions of source code must retain the above copyright
00290  *    notice, this list of conditions and the following disclaimer.
00291  * 
00292  * 2. Redistributions in binary form must reproduce the above copyright
00293  *    notice, this list of conditions and the following disclaimer in
00294  *    the documentation and/or other materials provided with the
00295  *    distribution.
00296  * 
00297  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00298  *    and "Vovida Open Communication Application Library (VOCAL)" must
00299  *    not be used to endorse or promote products derived from this
00300  *    software without prior written permission. For written
00301  *    permission, please contact vocal@vovida.org.
00302  *
00303  * 4. Products derived from this software may not be called "VOCAL", nor
00304  *    may "VOCAL" appear in their name, without prior written
00305  *    permission of Vovida Networks, Inc.
00306  * 
00307  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00308  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00309  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00310  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00311  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00312  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00313  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00314  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00315  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00316  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00317  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00318  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00319  * DAMAGE.
00320  * 
00321  * ====================================================================
00322  * 
00323  * This software consists of voluntary contributions made by Vovida
00324  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00325  * Inc.  For more information on Vovida Networks, Inc., please see
00326  * <http://www.vovida.org/>.
00327  *
00328  */