realtimenetprots/sipfw/SIP/sipapi/src/SipConnectionImplementation.h
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/sipapi/src/SipConnectionImplementation.h	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,468 @@
+/*
+* Copyright (c) 2005-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        : SipConnectionImplementation.h
+* Part of     : SIP Client
+* Interface   : SDK API, SIP API
+* Version     : 1.0
+*
+*/
+
+
+
+
+/**
+ @internalComponent
+*/
+
+#ifndef CSIPCONNECTIONIMPLEMENTATION_H
+#define CSIPCONNECTIONIMPLEMENTATION_H
+
+// INCLUDES
+#include "sipconnection.h"
+#include "sipclientconnectionobserver.h"
+#include "transactionassociation.h"
+#include "siprefreshassociation.h"
+#include "_sipcodecdefs.h"
+
+// FORWARD DECLARATIONS
+class CSIP;
+class MSIPConnectionObserver;
+class CSIPTransactionBase;
+class CSIPClientTransaction;
+class CSIPServerTransaction;
+class CRegBindingImplementation;
+class CRegistrationState;
+class CSIPDialogImplementation;
+class CDialogState;
+class CSIPRefresh;
+class CSIPMessageElements;
+class CSIPRequestElements;
+class CSIPResponseElements;
+class CConnectionCallback;
+
+//CONSTANTS
+
+// CLASS DECLARATION
+
+/**
+* Implementation class for managing a connection.
+*/
+class CSIPConnectionImplementation :
+    public CBase,
+    public MSIPClientConnectionObserver,
+    public MTransactionAssociation,
+    public MSIPRefreshAssociation
+	{    
+    public: //Constructors and destructor
+
+	    /**
+        * Two-phased constructor.
+		* @param aSIP Handle to the SIP server
+	    * @param aConnection Associated CSIPConnection
+		* @param aIapId IAP-id
+		* @param aObserver a observer for receiving asynchonous events on this
+        *   connection
+        * @return New object, ownership is transferred
+        */
+		static CSIPConnectionImplementation*
+			NewL(CSIP& aSIP,
+				 CSIPConnection& aConnection,
+				 TUint32 aIapId,
+				 MSIPConnectionObserver& aObserver);
+
+		/**
+		* Destructor
+		*/
+		~CSIPConnectionImplementation();
+
+	public: //From MSIPClientConnectionObserver:
+		void IncomingRequestL(CSIPRequestElements* aElements,
+							  TUint32 aRequestId);
+
+		void IncomingDialogRequestL(CSIPRequestElements* aElements,
+			                  		TUint32 aRequestId,
+							  		TUint32 aDialogId);
+
+		void IncomingResponseL(CSIPResponseElements* aElements,
+							   TUint32 aRequestId);
+
+		void IncomingDialogResponseL(CSIPResponseElements* aElements,
+			                   		 TUint32 aRequestId,
+							   		 TUint32 aDialogId);
+
+		void IncomingDialogResponseL(CSIPResponseElements* aElements,
+			                   		 TUint32 aRequestId,
+	                           		 TUint32 aRefreshId,
+							   		 TUint32 aDialogId);
+
+		void IncomingRegistrationResponseL(CSIPResponseElements* aElements,
+										   TUint32 aRequestId,
+		                                   TUint32 aRefreshId,
+								           TUint32 aRegistrationId);		
+	 
+		void IncomingRefreshResponseL(CSIPResponseElements* aElements,
+			                   		  TUint32 aRequestId,
+					           		  TUint32 aRefreshId);
+
+		void ErrorOccured(TInt aError, TUint32 aRequestId);
+		
+		void RefreshErrorOccured(TInt aError, TUint32 aRefreshId); 
+
+		void RegistrationErrorOccured(TInt aError,
+	                      			  TUint32 aRegistrationId,
+	                      			  TUint32 aRequestId);
+		
+		void DialogErrorOccured(TInt aError,
+	                      		TUint32 aDialogId,
+	                      		TUint32 aRequestId);
+
+		void DialogErrorOccured(TInt aError,
+	                      		TUint32 aDialogId,
+	                      		TUint32 aRefreshId,
+	                      		TUint32 aRequestId);
+	    
+	    void InviteCompleted(TUint32 aRequestId);
+
+	    void ConnectionStateChanged(CSIPConnection::TState aState);
+
+    public: //From MTransactionAssociation:
+
+        CSIPClientConnection& ClientConnectionL();
+        
+        CSIPClientConnection* ClientConnection();
+	
+        CSIPConnection& SIPConnectionL();
+
+        void AddTransactionL(CSIPTransactionBase& aTransaction);
+
+        void RemoveTransaction(const CSIPTransactionBase& aTransaction);
+
+    public: //From MSIPRefreshAssociation:
+        CSIPClientTransaction*
+            UpdateRefreshL(CSIPRefresh& aRefresh,
+                           CSIPMessageElements* aElements,
+                           TBool aTerminate);        
+
+        void DeletingRefresh(CSIPRefresh& aRefresh, TUint32 aRefreshId);
+        
+        MTransactionAssociation& TransactionAssociation();
+        
+        TInt CheckIfStandAlone();
+
+    public: // New functions
+        /**
+		* Gets current state of the connection        
+        * @return current state of the connection
+        */
+		CSIPConnection::TState State() const;
+
+		/**
+        * Send a SIP request.
+        *
+		* @param aElements SIP headers. Ownership is transferred.
+        * @param aRegistrationId If non-NULL, request will use the outbound
+        *   proxy and some SIP headers from the registration identified by
+        *   aRegistrationId. Ownership is not transferred.
+        * @param aRefresh If non-NULL, the request will be refreshed. Otherwise
+        *   NULL. Ownership is not transferred.
+		* @return New transaction. Ownership is transferred.
+        */
+        CSIPClientTransaction*
+            SendRequestL(CSIPRequestElements* aElements,
+                         TUint32* aRegistrationId,
+						 CSIPRefresh* aRefresh);
+
+		/**
+		* Creates SIP REGISTER request and sends it to the given destination.
+		* User must no define any Contact or Expires-headers
+		* in the provided elements.
+		* @pre State() == EActive
+        * @pre aElements != 0
+        * @pre aElements->Method().DesC().Length()==0
+		* @param aElements contains local and remote addresses, optional SIP
+        *        message headers and body. User must not set any expires values
+        *        to aElements. The ownership is transferred.
+        * @return SIP REGISTER client transaction, ownership is transferred
+        */        
+		CSIPClientTransaction*
+            FetchRegistrationsL(CSIPRequestElements* aElements);
+
+		/**
+		* Gets Iap-id used for this connection
+		* @return Iap-id
+		*/
+        TUint32 IapId() const;
+
+		/**
+        * Gets SIP server handle
+        * @return handle to SIP server, or 0-pointer if SIP server does not
+        *	exist any more
+        */        
+        CSIP* SIP();
+        
+        /**
+        * Gets SIP server handle
+        * @return handle to SIP server, or 0-pointer if SIP server does not
+        *	exist any more
+        */        
+        const CSIP* SIP() const;
+        
+	    void SetOptL(TUint aOptionName,
+	                 TUint aOptionLevel,
+	                 const TDesC8& aOption);
+		
+	    void SetOptL(TUint aOptionName, TUint aOptionLevel, TInt aOption);
+
+		/**
+        * Searches for a transaction with the matching aRequestId.
+		* @param aRequestId RequestId associated with the transaction
+		* @return Found transaction or NULL if not found. Ownership is not
+        *   transferred.
+        */
+        CSIPTransactionBase* FindTransaction(TUint32 aRequestId) const;
+
+        void AddRegistrationL(CRegBindingImplementation& aRegistration);
+
+        /**
+        * Removes a registration from the array, but doesn't delete it.
+		* @param aRegistration Registration binding to be removed
+        */
+        void RemoveRegistration(const CRegBindingImplementation& aRegistration);
+
+        void AddDialogL(CSIPDialogImplementation& aDialog);
+        void RemoveDialog(const CSIPDialogImplementation& aDialog);
+
+        /**
+        * Searches for a dialog, using aRequestId as a key.
+        * @param aRequestId RequestId of a transaction associated with the
+        *   dialog
+		* @return Found dialog or NULL if not found. Ownership is not
+        *   transferred.
+        */
+        CSIPDialogImplementation*
+        	FindDialogByRequestId(TUint32 aRequestId) const;
+
+        /**
+		* Informs CSIPConnection that the associated CSIP instance has been
+        * deleted. After this the CSIPConnection object can't be used anymore.
+		*/
+        void CSIPDeleted();
+
+        /**
+		* Obtains the initial state for registration state machine.
+        *
+        * @return Initial registration state, ownership is not transferred
+		*/
+        CRegistrationState* InitialRegisterStateL() const;
+
+        /**
+		* Obtains the initial state for dialog state machine.
+        *
+        * @return Initial dialog state, ownership is not transferred
+		*/
+        CDialogState* InitialDialogStateL() const;
+
+        /**
+        * Response related to a dialog has been received.
+		*
+        * @param aElements SIP response elements. Ownership is transferred.
+        * @param aRequestId Identifies the transaction
+        * @param aDialogId DialogId
+        * @param aRefreshId NULL if the response is not related to a refresh,
+        *   otherwise the RefreshId. Ownership is not transferred.
+		*/
+
+        void IncomingResponseToDialogL(CSIPResponseElements* aElements,
+		                               TUint32 aRequestId,
+                                       TUint32 aDialogId,
+                                       TUint32* aRefreshId);
+
+        /**
+		* Finds a client transaction by its ID. 
+		* All connection, registration and dialog related transactions 
+		* are searched through.
+        *
+        * @param aRequestId request ID of the client transaction
+        * 
+        * @return transaction or NULL if not found, ownership not transferred.
+		*/
+        CSIPClientTransaction* FindClientTransaction(TUint32 aRequestId) const;
+
+        /**
+		* Finds a refresh by its id. 
+		* All connection, registration and dialog related refreshes 
+		* are searched through.
+        *
+        * @param aRequestId RequestId associated with the refresh instance
+        * @param aRefreshId RefreshId associated with the refresh instance
+        * 
+        * @return refresh or NULL if not found, ownership is not transferred.
+		*/
+        CSIPRefresh* FindRefresh(TUint32 aRequestId, TUint32 aRefreshId) const;
+
+    private:
+        CSIPConnectionImplementation(CSIP& aSIP,
+        							 CSIPConnection& aConnection,
+                       				 TUint32 aIapId,
+                       				 MSIPConnectionObserver& aObserver);
+
+        void ConstructL();        
+
+        /**
+        * Searches for a refresh and transaction, using aRequestId and
+        * aRefreshId as keys.        
+		* @param aRequestId RequestId associated with the refreshed transaction
+        * @param aRefreshId RefreshId associated with the refresh instance
+        * @param aRefresh OUT: if refresh was found, this pointer is set to the
+        *   refresh instance. Ownership is not transferred.
+        * @param aTransaction OUT: if transaction was found, this pointer is
+        *   set to the refreshed client transaction. Ownership is not
+        *   transferred.
+		* @return ETrue if found, EFalse otherwise
+        */
+        TBool FindRefresh(TUint32 aRequestId,
+                          TUint32 aRefreshId,
+                          CSIPRefresh** aRefresh,
+                          CSIPClientTransaction** aTransaction) const;
+
+  		/**
+        * Searches for a registration, using aRegistrationId and aRequestId as
+        * keys. Registration might not yet have received RegistrationId from
+        * SIP client, so the aRequestId may be needed for searching.
+        * @param aRegistrationId RegistrationId of the registration
+		* @param aRequestId RequestId of a transaction associated with the
+        *   registration
+		* @return Found registration binding implementation, or NULL if not
+		*	found. Ownership is not transferred.
+        */
+        CRegBindingImplementation* FindRegistration(TUint32 aRegistrationId,
+                             			   		    TUint32 aRequestId) const;
+                             			   		  
+        /**
+        * Searches for a registration, using aRequestId as a key.
+        * @param aRequestId RequestId of a transaction associated with the
+        *   registration
+		* @return Found registration binding implementation, or NULL if not
+		*	found. Ownership is not transferred.
+        */
+        CRegBindingImplementation* FindRegistration(TUint32 aRequestId) const;
+        
+        /**
+        * Searches for a dialog, using aDialogId as a key.        
+        * @param aDialogId DialogId of the dialog.
+		* @return Found dialog or NULL if not found. Ownership is not
+        *   transferred.
+        */
+        CSIPDialogImplementation* FindDialog(TUint32 aDialogId) const;
+
+        /**
+        * A request has been received with a dialogId, but no matching dialog
+        * exists.
+		* If the request is NOTIFY, it is stored until a response with the same
+        * dialogId is received. Then the response is passed to dialog and after
+        * that all the stored NOTIFY are passed to the same dialog.
+        * This is needed since NOTIFY can be received before a sent SUBSCRIBE
+        * receives a response with dialogId.
+		*
+        * @param aTransaction Server transaction, ownership is transferred
+        * @param aDialogId DialogId
+		*/
+        void IncomingRequestBeforeDialogExistsL(
+                                    CSIPServerTransaction* aTransaction,
+                                    TUint32 aDialogId);
+
+        /**
+		* Extracts the oldest stored transaction for the dialog identified by
+        * aDialogId.
+        * @param aDialogId DialogId
+        * @return Server transaction or NULL if no transaction is stored for
+        *   the dialog. Ownership is transferred.
+		*/
+        CSIPServerTransaction* GetStoredTransaction(TUint32 aDialogId);
+
+        /**
+		* Checks that CSIP is available for use (not NULL). If iSIP is NULL,
+        * it means user has deleted a resource needed by
+        * CSIPConnectionImplementation, and this function leaves.
+		*/
+        void CheckCSipL() const;
+
+        /**
+		* Connection is no longer available. All registrations, dialogs,
+        * transactions and refreshes using this connection are terminated, but
+        * not deleted.
+		*/
+        void ConnectionLost() const;
+
+	private: // Data
+	
+        //The used CSIP instance. CSIPConnectionImplementation doesn't own it.
+        //If this is NULL, it means application has deleted the CSIP instance,
+        //and the CSIPConnectionImplementation is now useless.
+        CSIP* iSIP;
+
+        //Associated CSIPConnection of this instance
+        CSIPConnection& iConnection;
+
+        //IAP-id of this connection
+        TUint32 iIapId;
+
+        //Callback to upper layer (to application)
+        MSIPConnectionObserver& iObserver;
+
+        //Client connection, owned by CSIPConnectionImplementation.
+        CSIPClientConnection* iClientConnection;
+
+        //CSIPConnection doesn't own CRegBindingImplementation
+		RPointerArray<CRegBindingImplementation> iRegistrations;
+
+        //CSIPConnectionImplementation doesn't own the CSIPDialogImplementation
+        //objects. CSIPDialogImplementation is deleted when the last dialog
+        //association is deleted.
+        //NOTE: When CSIPDialogImplementation has just been created and has no
+        //dialog associations yet, it must be stored in CleanupStack, otherwise
+        //it wouldn't be freed if leave occurs.
+        RPointerArray<CSIPDialogImplementation> iDialogs;
+
+        //CSIPConnectionImplementation has to know which transactions are
+        //attached to it, but application still owns the transactions.
+        RPointerArray<CSIPTransactionBase> iTransactions;        
+
+        //Standalone refreshes, application owns these
+        RPointerArray<CSIPRefresh> iRefreshes;
+
+        //To avoid calling MSIPConnectionObserver from within CSIPDialog and
+        //CSIPRegistrationBinding, the CConnectionCallback is passed to the
+        //functions which would need to call MSIPConnectionObserver.
+        //CSIPRegistrationBinding and CSIPDialog fill CConnectionCallback with
+        //the selected callback function and its parameters, and return ETrue
+        //to tell to CSIPConnectionImplementation that a callback must be done.
+		//CSIPConnectionImplementation owns this.        
+        CConnectionCallback* iCallbackInfo;
+
+	private: // For testing purposes
+	    UNIT_TEST(CSIP_Test)
+        UNIT_TEST(CSIPConnection_Test)
+        UNIT_TEST(CSIPSubscribeDialogAssoc_Test)
+        UNIT_TEST(CSIPInviteDialogAssoc_Test)
+        UNIT_TEST(CSIPReferDialogAssoc_Test)
+        UNIT_TEST(CSIPDialogTrying_Test)
+        UNIT_TEST(CSIPRegistrationBinding_Test)
+        
+		void __DbgTestInvariant() const;
+
+	};
+
+#endif