--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/TransactionUser/src/CTransactionStore.h Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,466 @@
+/*
+* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Name : CTransactionStore.h
+* Part of : TransactionUser
+* Version : SIP/6.0
+*
+*/
+
+
+
+
+/**
+ @internalComponent
+*/
+
+#ifndef CTRANSACTIONSTORE_H
+#define CTRANSACTIONSTORE_H
+
+// INCLUDES
+#include "SipStackServerDefs.h"
+
+#include "MTransactionStore.h"
+#include "MTransactionFinder.h"
+#include "TransactionInfo.h"
+
+#include <e32base.h>
+#include <stringpool.h>
+
+// FORWARD DECLARATIONS
+class CTransactionBase;
+
+class MTransactionOwner;
+class CUserAgent;
+class CUserAgentServer;
+class MTransactionHeaders;
+
+// CLASS DECLARATION
+
+/**
+ * CTransactionStore contains the information of all existing transactions.
+ * This information is used for e.g. routing the incoming SIP messages to the
+ * correct transaction or UA.
+ */
+class CTransactionStore :
+ public CBase,
+ public MTransactionStore,
+ public MTransactionFinder
+ {
+public: // Constructors and destructor
+
+ /**
+ * Creates a new object.
+ * @return New CTransactionStore object, ownership is transferred.
+ */
+ static CTransactionStore* NewL();
+
+ ~CTransactionStore();
+
+public: // From MTransactionStore
+
+ TInt UpdateTransactionId(TTransactionId aOldTransactionId,
+ TTransactionId aNewTransactionId);
+
+ void Remove(TTransactionId aTransactionId);
+
+public: // From MTransactionFinder
+
+ MReceiverObserver* Search(CSIPMessage& aMsg);
+
+ void IcmpErrorL(const TInetAddr& aAddress,
+ CSipConnectionMgr::TICMPError aError);
+
+public: // New functions
+
+ /**
+ * Generates a new unique value to be used as a TransactionId.
+ * @return value New TransactionId value
+ */
+ TTransactionId NewTransactionId();
+
+ /**
+ * Stores information of a transaction.
+ * @pre aUserAgent != NULL
+ * @param aTransactionId transaction identifier
+ * @param aUserAgent UA, ownership is transferred
+ * @param aTransaction Transaction object, can be NULL. Ownership is not
+ * transferred,. as UA owns aTransaction.
+ * @param aMsg SIP message which initiated the transaction, can be NULL.
+ * Ownership is not transferred.
+ * @param aType Identifies which kind of transaction this is
+ * (client, server, etc.)
+ */
+ void AddL(TTransactionId aTransactionId,
+ CUserAgent* aUserAgent,
+ CTransactionBase* aTransaction,
+ CSIPMessage* aMsg,
+ CTransactionBase::TTransactionType aType);
+
+ /**
+ * Updates the information of the transaction identified by aTransactionId.
+ * @pre Transaction must exist in the CTransactionStore
+ * @param aTransactionId transaction identifier
+ * @param aTransaction New value for the transaction pointer, can be NULL.
+ * Ownership is not transferred.
+ * @param aMsg The transaction related headers which are present in the
+ * aMsg are copied to CTransactionStore. The possibly existing previously
+ * stored headers discarded. This parameter can be NULL. Ownership is not
+ * transferred.
+ * @leave KErrNotFound If no such transaction is found
+ */
+ void UpdateL(TTransactionId aTransactionId,
+ CTransactionBase* aTransaction,
+ CSIPMessage* aMsg);
+
+ /**
+ * Updates the To tag of the transaction identified by the aTransactionId.
+ * @pre Transaction must exists in the CTransactionStore
+ * @param aTransactionId transaction identifier
+ * @param aTag To tag
+ * @leave KErrNotFound If no such transaction is found
+ */
+ void UpdateToTagL(TTransactionId aTransactionId, RStringF aTag);
+
+ /**
+ * Clears the pointer to UA by setting it NULL.
+ * The UA is identified by aTransactionId.
+ * @param aTransactionId Identifies the UA
+ */
+ void ClearUserAgent(TTransactionId aTransactionId);
+
+ /**
+ * Clears the pointer to transaction by setting it NULL. Transaction is
+ * identified by aTransactionId.
+ * @param aTransactionId Identifies the transaction
+ */
+ void ClearTransaction(TTransactionId aTransactionId);
+
+ /**
+ * Searches the store for an UAS to match the CANCEL.
+ * @param aCancel IN: CANCEL request
+ * @param aCancelUAS IN: UA that is searching for an UAS to be canceled.
+ * TransactionStore checks aCancelUAS to avoid returning the same UAS
+ * that is handling the CANCEL request.
+ * @return UAS to be canceled, NULL if not found. Ownership isn't
+ * transferred.
+ */
+ CUserAgentServer* SearchUasToCancel(CSIPRequest& aCancel,
+ const CUserAgent& aCancelUAS);
+
+ /**
+ * Searches the store for an UA having the specified aTransactionId.
+ * @param aTransactionId Identifies the UA
+ * @return The found UA or NULL if not found. Ownership is not transferred.
+ */
+ CUserAgent* SearchById(TTransactionId aTransactionId);
+
+ /**
+ * Checks if the SIP request is a merged request.
+ * Searches through the stored transactions for a transaction with a
+ * matching From tag, Call-ID and CSeq. Skips the specified UA which is
+ * aUserAgent requesting this search.
+ * @param aUserAgent UA asking if the request is merged
+ * @param aReq SIP request
+ * @return ETrue if the request is merged, EFalse otherwise
+ */
+ TBool IsMergedRequest(const CUserAgent& aUserAgent, CSIPRequest& aReq);
+
+ /**
+ * Copies any Record-Route headers possibly present in aReq, to the
+ * specified transaction's stored information.
+ *
+ * @pre The transaction identified by aTransactionId must not already have
+ * stored Record-Route headers.
+ * @post
+ *
+ * @param aTransactionId Transaction id used for identifying the
+ * transaction, which will store the Record-Route headers.
+ * @param aReq SIP request from which the headers are copied from.
+ */
+ void StoreRecordRouteHeadersL(TTransactionId aTransactionId,
+ CSIPRequest& aReq);
+
+ /**
+ * Frees the stored Record-Route headers from the specified transaction.
+ * @param aTransactionId Transaction id used for identifying the
+ * transaction which the Record-Route headers are freed.
+ */
+ void FreeRecordRouteHeaders(TTransactionId aTransactionId);
+
+ /**
+ * Copies any Contact headers possibly present in aReq, to the specified
+ * transaction's stored information.
+ * @pre The transaction identified by aTransactionId must not already have
+ * stored Contact headers.
+ * @param aTransactionId Transaction id used for identifying the
+ * transaction which will store the Contact headers.
+ * @param aReq SIP request from which the headers are copied from.
+ */
+ void StoreContactHeadersL(TTransactionId aTransactionId,
+ CSIPRequest& aReq);
+
+ /**
+ * Frees the stored Contact headers from the specified transaction.
+ * @param aTransactionId Transaction id used for identifying the
+ * transaction which the Contact headers are freed.
+ */
+ void FreeContactHeaders(TTransactionId aTransactionId);
+
+ /**
+ * Copies certain headers from the CTransactionInfo item, identified by the
+ * aTransactionId, to the response message (aResp).
+ * @param aTransactionId Transaction id used for locating the correct
+ * CTransactionInfo object
+ * @param aResp IN/OUT: SIP response message which will be filled.
+ */
+ void CopyHeadersToResponseL(TTransactionId aTransactionId,
+ CSIPResponse& aResp);
+
+ /**
+ * Copies certain headers from the CTransactionInfo item, identified by the
+ * aTransactionId, to the aReq.
+ * @param aTransactionId Transaction id used for locating the
+ * CTransactionInfo object from which the headers are copied from.
+ * @param aReq SIP request into which the headers are copied
+ * @param aCopyRequestURI ETrue: Request-URI is copied, EFalse: otherwise
+ * @param aCopyViaHeaders ETrue: Via headers are copied, EFalse: otherwise
+ */
+ void CopyHeadersToRequestL(TTransactionId aTransactionId,
+ CSIPRequest& aReq,
+ TBool aCopyRequestURI,
+ TBool aCopyViaHeaders);
+
+ /**
+ * Retrieve the transaction related headers of the SIP message that created
+ * the transaction.
+ * @param aTransactionId Identifies the transaction whose SIP headers are
+ * requested.
+ * @return MTransactionHeaders* Object containing the SIP headers.
+ * Ownership is transferred. NULL if the transaction was not found.
+ */
+ MTransactionHeaders* TransactionHeadersL(TTransactionId aTransactionId);
+
+ /**
+ * Obtains information from one transaction (not from any specific
+ * transaction). This information will be as a input to generate random
+ * tags.
+ * @param aTransactionId Will be filled by a transactionId value, unless
+ * there are no stored transactions.
+ * @param aUserAgent OUT: Will be set to point to a UA object.
+ * If there are no stored UAs, this pointer isn't set.
+ * Ownership isn't transferred.
+ * @param aMsg OUT: Pointer to a SIP Message, might be zero if no SIP
+ * message was available. Ownership is transferred.
+ */
+ void RandomTaInfoL(TTransactionId& aTaId,
+ CUserAgent** aUserAgent,
+ CSIPMessage** aMsg);
+
+ /**
+ * Returns the request method of the transaction identified by
+ * aTransactionId.
+ * @pre A transaction identified by aTransactionId must exist in the store.
+ * @param aTransactionId TransactionId
+ * @return Request method
+ */
+ RStringF RequestMethod(TTransactionId aTransactionId);
+
+ /**
+ * Clears the MTransactionOwner pointers from the stored UA objects, which
+ * have a matching MTransactionOwner callback.
+ * @pre aObserver != NULL
+ * @param aObserver pointer to the MTransactionOwner callback. Ownership
+ * isn't transferred.
+ * @return KErrNone if successful, KErrNotFound if no UA used the specified
+ * aObserver callback.
+ */
+ TInt ClearTransactionOwner(const MTransactionOwner* aObserver);
+
+ /**
+ * Goes through all stored transactions using the given IAP-id and those
+ * which are currently resolving the remote address, are stopped.
+ * @param aIapId IAP-id
+ * @param aReason Reason why transaction is stopped
+ */
+ void EndResolvingTransactions(TUint32 aIapId, TInt aReason);
+
+ /**
+ * Delete any transactions matching the IAP-id.
+ * @param aIapId IAP-id
+ */
+ void RemoveItemsByIapId(TUint32 aIapId);
+
+ /**
+ * Check if there is space for a new server transaction.
+ * @return ETrue New server transaction can be created
+ * EFalse otherwise
+ */
+ TBool AllowMoreServerTransactions() const;
+private: // New functions, for internal use
+ void ConstructL();
+ CTransactionStore();
+
+ /**
+ * Removes aItem from the list, deletes aItem's contents and the aItem.
+ * @pre aItem != NULL
+ * @param aItem Item to delete.
+ */
+ void DeleteItem(CTransactionInfo* aItem);
+
+ /**
+ * Searches the store for a CTransactionInfo item of the transaction with
+ * the given aTransactionId.
+ * @param aTransactionId identifies the transaction whose information is
+ * searched for
+ * @return Pointer to the object containing transaction's information,
+ * NULL if no such transaction is found. Ownership isn't transferred.
+ */
+ CTransactionInfo* FindTransactionInfo(TTransactionId aTransactionId);
+
+ /**
+ * Searches the store for an object which should receive a SIP message
+ * with the Branch-ID, Sent-by value and method given as parameters.
+ * Transaction type has to also match.
+ * @param aMsg SIP message received from remote endpoint
+ * @param aType identifies which kind of transaction this is
+ * (client, server, etc.)
+ * @param aUserAgent IN: If non-zero: this is the UA that searches for an
+ * UAS to be canceled. If NULL: the search is done to find a transaction
+ * to receive an incoming SIP message. Ownership isn't transferred.
+ * @return Pointer to the receiving interface of the object which should
+ * receive the SIP message (the actual object can UA or transaction).
+ * NULL if not found. Ownership is not transferred.
+ */
+ MReceiverObserver* SearchByBranch(CSIPMessage& aMsg,
+ CTransactionBase::TTransactionType aType,
+ const CUserAgent* aUserAgent);
+
+ /**
+ * Searches the store for an object which should receive the SIP request,
+ * using the To, From, CallID, CSeq, topmost Via, Request-URI.
+ * Transaction type has to also match. Via Branch is not used for matching.
+ * @param aReq SIP request received from remote endpoint
+ * @param aType identifies which kind of transaction this is
+ * @param aUserAgent IN: If non-NULL: the UA which is searching for an UAS
+ * to be canceled. If NULL: the search is done to find a transaction to
+ * receive an incoming SIP message. Ownership isn't transferred.
+ * @return Receiving interface of the object which should receive the
+ * request (the actual object can UA or transaction). NULL if no matching
+ * object was found. Ownership isn't transferred.
+ */
+ MReceiverObserver*
+ SearchServerByHeaders(CSIPRequest& aReq,
+ CTransactionBase::TTransactionType aType,
+ const CUserAgent* aUserAgent);
+
+ /**
+ * Check if all of the required headers for Transaction matching are
+ * present in the SIP message.
+ * @param aMsg SIP message
+ * @return ETrue if all required headers exist, EFalse otherwise.
+ */
+ TBool RequiredHeadersPresent(CSIPMessage& aMsg) const;
+
+ /**
+ * Compares the TTransactionType stored in aInfo with aType.
+ * @param aInfo Transaction information
+ * @param aType Transaction type
+ * @param aSearchCanceledUas Indicates whether the comparison is performed
+ * for searching an UAS to be canceled.
+ * @return ETrue if transaction types match, EFalse otherwise
+ */
+ TBool CompareTransactionTypes(const CTransactionInfo& aInfo,
+ CTransactionBase::TTransactionType aType,
+ TBool aSearchCanceledUas) const;
+
+ /**
+ * This function is used to return the receiver interface of the
+ * transaction/UA that should be given the SIP message received from the
+ * network.
+ * If the SIP message is ACK and the UA, pointed by aInfo, has sent a 2xx
+ * response, the transaction/UA is ignored as Via Branch must not be used
+ * to find the transaction in case of ACK to a 2xx.
+ * @param aMsg SIP message received from network.
+ * @param aInfo Information of the transaction that should receive a
+ * SIP message received from network. aInfo has been determined by an
+ * earlier search among the existing transactions.
+ * @param aUserAgent If NULL, this parameter is ignored. If UA is not NULL,
+ * it is the UA that is searching for an UAS to be canceled. Used to the
+ * avoid returning the MReceiverObserver interface of the same UAS that
+ * initiated the search. Ownership isn't transferred.
+ * @return Object where the SIP message received from network should be
+ * passed next or NULL if there is no suitable object. Ownership is not
+ * transferred.
+ */
+ MReceiverObserver* IgnoreAckTo2xx(const CSIPMessage& aMsg,
+ CTransactionInfo& aInfo,
+ const CUserAgent* aUserAgent) const;
+
+ /**
+ * This function is used to return the receiver interface of the
+ * transaction/UA that should be given the SIP message received from the
+ * network.
+ * @param aInfo Information of the transaction that should receive a
+ * SIP message received from network. aInfo has been determined by an
+ * earlier search among the existing transactions.
+ * @param aUserAgent If NULL, this parameter is ignored. If UA is not NULL,
+ * it is the UA that is searching for an UAS to be canceled. Used to the
+ * avoid returning the MReceiverObserver interface of the same UAS that
+ * initiated the search. Ownership isn't transferred.
+ * @return Object where the SIP message received from network should be
+ * passed next or NULL if there is no suitable object. Ownership is not
+ * transferred.
+ */
+ MReceiverObserver* CheckResult(CTransactionInfo& aInfo,
+ const CUserAgent* aUserAgent) const;
+
+ /**
+ * Remove item from list of transactions.
+ * @param aItem Item to remove
+ */
+ void RemoveListItem(CTransactionInfo& aItem);
+private: // Data
+
+ // Information of all existing UAs and transactions
+ TSglQue<CTransactionInfo> iList;
+
+ // Counter for generating unique numbers to be used as TransactionIds.
+ // This will eventually wrap around, but by the time that happens, it is
+ // expected the old transactions using the same TransactionId values have
+ // been terminated.
+ TTransactionId iTransactionIdCounter;
+ // Amount of UAS / server transactions in iList
+ TInt iServerTransactionCount;
+ // Maximum amount of UAS / server transactions in iList
+ TInt iMaxServerTransactions;
+
+ // We don't use __DECLARE_TEST because we don't want to export this function.
+ void __DbgTestInvariant() const;
+
+
+
+#ifdef CPPUNIT_TEST
+ friend class CTransactionStore_Test;
+ friend class CTransactionUser_Test;
+ friend class CNormalUAC_ResolveAddress_Test;
+ friend class CNormalUAC_WaitResponse_Test;
+ friend class CUserAgentServer_Test;
+ friend class CUserAgentClient_Test;
+#endif
+ };
+
+#endif // end of CTRANSACTIONSTORE_H
+
+// End of File