realtimenetprots/sipfw/SIP/sipapi/src/RegBindingImplementation.h
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/sipapi/src/RegBindingImplementation.h	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,436 @@
+/*
+* 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        : RegBindingImplementation.h
+* Part of     : SIP Client
+* Interface   : SDK API, SIP Client API
+* Version     : 1.0
+*
+*/
+
+
+
+
+/**
+ @internalComponent
+*/
+
+#ifndef CREGBINDINGIMPLEMENTATION_H
+#define CREGBINDINGIMPLEMENTATION_H
+
+// INCLUDES
+#include <stringpool.h>
+#include "sipregistrationcontext.h"
+#include "transactionassociation.h"
+#include "siprefreshassociation.h"
+#include "_sipcodecdefs.h"
+
+// FORWARD DECLARATIONS
+class CSIPRegistrationBinding;
+class CSIPResponseElements;
+class CSIPContactHeader;
+class CSIPRouteHeader;
+class CUri8;
+class CRegistrationState;
+class CSIPToHeader;
+class CSIPFromHeader;
+class CConnectionCallback;
+
+
+// CLASS DECLARATION
+
+/**
+*  Implementation class for managing SIP registration binding.
+*/
+class CRegBindingImplementation :
+    public CBase,
+    public MSIPRegistrationContext,
+    public MTransactionAssociation,
+    public MSIPRefreshAssociation
+	{
+    public: // Constructors and destructor
+
+        /**
+        * Two-phased constructor.
+		* @pre aAor != 0 &&		
+		*      aContact != 0
+        * @pre "Expires" parameter in aContact must be >= KSIPMinExpirationValue
+        * @param aRegistration Registration binding who creates this
+        *		 CRegBindingImplementation instance.
+		* @param aConnection The SIP connection to be used
+		* @param aAor contains user's address-of-record to register;
+		*        the ownership is transfered
+		* @param aContact contact(s) to be registered. The "expires" parameter
+		*        indicates how long the client would like the binding to be
+        *        valid.
+		*        "expires" parameter value must be >= KSIPMinExpirationValue; 
+		*		 the ownership is transfered
+ 		* @param aRefresh if set, created binding will be refreshed;
+		*        the ownership is transfered
+		* @param aOutboundProxy an outbound proxy address;
+		*        the ownership is transfered
+		* @param aRemoteUri if set, will be used in request-uri construction;
+		*        the ownership is transfered
+        * @param aFrom From header, the ownership is transferred
+        * @return New object, ownership is transferred.
+		*/
+		static CRegBindingImplementation*
+            NewL(CSIPRegistrationBinding& aRegistration,
+            	 CSIPConnection& aConnection,
+			     CSIPToHeader* aAor,
+			     CSIPContactHeader* aContact,
+ 			     CSIPRefresh* aRefresh,
+			     CSIPRouteHeader* aOutboundProxy,
+			     CUri8* aRemoteUri,
+                 CSIPFromHeader* aFrom);
+
+		/**
+		* Destructor
+		*/
+		~CRegBindingImplementation();
+
+	public: // From MSIPRegistrationContext
+
+        /**
+        * Checks if the registration context can be
+        * used for creating SIP messages/dialogs
+        * @return ETrue if the registration binding exists; EFalse
+        *         otherwise
+        */
+        TBool IsContextActive() const;
+
+        /**
+        * Gets the context id
+        * @return context id
+        * For internal use only
+        */
+        TUint32 ContextId() const;
+
+	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
+
+        /**
+		* Creates SIP REGISTER request, sends it to the given destination.
+		* Received 2xx response will create at least one registration
+		* binding.
+		* @pre Connection().State()==EActive
+		* @param aElements contains user SIP headers and content; the ownership
+		*        is taken
+        * @return SIP REGISTER transaction; the ownership is transfered
+        * @leave KErrSIPMalformedMessage if aElements contain contact or
+        *		 expires headers
+        */
+		CSIPClientTransaction* RegisterL(CSIPMessageElements* aElements=0);	
+
+        /**
+		* Creates SIP (de)REGISTER request, sends it to the given destination.
+		* This function will remove registration binding.
+		* Any SIP response (2xx - 6xx) to this request removes the binding.
+		* Note that deregistration can be done then the 2xx is received to the
+		* initial REGISTER transaction and there is no on-going registration
+		* updates.
+		* @pre Connection().State()==EActive
+		* @param aElements contains user SIP headers and content; the ownership
+		*        is transfered. If set, user SIP headers must not contain any 
+		*        Contact-header nor Expires-header
+        * @return SIP REGISTER transaction; the ownership is transfered
+        */
+		CSIPClientTransaction* DeregisterL(CSIPMessageElements* aElements=0);
+
+		CSIPClientTransaction*
+            UpdateL(CSIPMessageElements* aElements, TUint* aExpirationValue=0);
+
+        /**
+		* Gets the SIP connection used for the registration.
+		* @return SIP connection used for the registration, or 0-pointer if the
+        *   	  connection has been deleted. Ownership is not transferred.
+		*/
+        CSIPConnection* Connection();
+
+        /**
+		* Gets the SIP connection used for the registration.
+		* @return SIP connection used for the registration, or 0-pointer if the
+        *   	  connection has been deleted. Ownership is not transferred.
+		*/
+        const CSIPConnection* Connection() const;
+
+		/**
+		* Sets/resets outbound proxy.
+		* If a 0-pointer is given the outbound proxy will be reset.
+		* @param aOutboundProxy an outbound proxy. Ownership is transferred.		
+		*/
+		void SetOutboundProxyL(CSIPRouteHeader* aOutboundProxy);
+
+		/**
+		* Gets the address-of-record (AOR) used for creating binding
+		* @return address-of-record (AOR)
+		*/
+		const CSIPToHeader& Aor() const;
+
+		/**
+		* Gets Contact header associated with the registration binding
+		* @return Contact header
+		*/
+		const CSIPContactHeader& ContactHeader() const;
+
+		/**
+		* Gets Contact header associated with the registration binding
+		* @return Contact header
+		*/
+		CSIPContactHeader& ContactHeader();
+		
+        /**
+        * Gets the registered Contact-header received in the 200 OK response.
+        * @return Contact header, or NULL if IsContextActive() is EFalse.
+        *         Ownership is not transferred.
+        */
+        const CSIPContactHeader* RegisteredContact() const;
+		
+		/**
+		* Gets used outbound proxy
+		* @return outbound proxy or a 0-pointer if not set. Ownership is not
+        *   transferred.
+		*/
+		const CSIPRouteHeader* OutboundProxy() const;        
+
+        /**
+		* Gets associated refresh in case the user has requested the refresh of
+        * the registration. Note that client cannot use update or terminate
+        * functions defined in the CSIPRefresh class. 
+		* @return Associated refresh or a 0-pointer if the user has not
+        *   requested a refresh of registration binding. Ownership is not
+        *	transferred.
+		*/
+		const CSIPRefresh* SIPRefresh() const;
+
+       /**
+		* Gets associated refresh in case the user has requested the refresh of
+        * the registration. Note that client cannot use update or terminate
+        * functions defined in the CSIPRefresh class. 
+		* @return Associated refresh or a 0-pointer if the user has not
+        *  requested a refresh of registration binding. Ownership is not
+        *  transferred.
+		*/
+		CSIPRefresh* SIPRefresh();
+		
+        /**
+		* Compares this object to another object
+		* @param aRegistration CRegBindingImplementation object to compare
+		* @return ETrue if the objects are equal, otherwise EFalse
+		*/
+        TBool operator==(const CRegBindingImplementation& aRegistration) const;
+
+        CSIPClientTransaction* DoRegisterL(CSIPMessageElements* aElements);
+
+        CSIPClientTransaction* DoDeregisterL(CSIPMessageElements* aElements);
+
+        CSIPClientTransaction* DoUpdateL(CSIPMessageElements* aElements,
+                                         TUint* aExpirationValue);
+
+        TBool IncomingResponseL(CSIPResponseElements* aElements,
+		                        TUint32 aRequestId,
+					            TUint32 aRegistrationId,
+					            TUint32 aRefreshId,
+                                CConnectionCallback& aCallback);
+
+        TBool ErrorOccured(TInt aError,
+                           TUint32 aRequestId,
+                           CConnectionCallback& aCallback);
+
+        void SetRegistrationId(TUint32 aRegistrationId);        
+
+        /**
+		* Searches for a transaction matching the given aRequestId.
+		* 
+		* @param aRequestId Request id
+		* @return Transaction object, or NULL if not found. Ownership isn't
+        *   transferred.
+		*/
+        CSIPClientTransaction* FindTransaction(TUint32 aRequestId);
+
+		/**
+		* Change the registration binding state.
+		*
+		* @param aNewState State to enter, can be NULL.
+		*		 		   Ownership is not transferred.		
+		*/
+        void ChangeState(const CRegistrationState* aNewState);
+
+        void UpdateRefreshState(TUint aStatusCode) const;
+
+        void ConnectionLost();
+
+        CSIPClientTransaction* CreateClientTransactionL();
+
+        TBool HandleError(CConnectionCallback& aCallback,
+                          TInt aError,
+                          TUint32 aRequestId,
+                          const CRegistrationState& aUnregistered);
+
+        /**
+		* Informs CRegBindingImplementation that the associated CSIPConnection
+		* has been deleted. After this the CSIPRegistrationBinding object can't
+		* be used any more.
+		*/
+        void ConnectionDeleted();
+
+		CSIPRegistrationBinding& Binding() const;
+		
+		void UpdateRegisteredContactL();
+		
+		void RemoveRegisteredContact();
+		
+		/**
+		* Sets/resets properties.
+		* @pre IsContextActive()==EFalse
+		* @param aProperty. Property name
+		* @param aValue. Property value
+		* @leave KErrSIPInvalidRegistrationState if IsContextActive() is ETrue
+		* @leave KErrNotFound if property is not found
+		*/
+		void SetPropertyL(TUint32 aProperty,TBool aValue);
+		
+	private: // Constructors, for internal use
+
+		CRegBindingImplementation(CSIPRegistrationBinding& aRegistration,
+								  CSIPConnection& aConnection);
+
+        void ConstructL(CSIPToHeader* aAor,
+						CSIPContactHeader* aContacts,                        
+						CSIPRefresh* aRefresh,
+						CSIPRouteHeader* aOutboundProxy,
+						CUri8* aRemoteUri,
+                        CSIPFromHeader* aFrom);
+
+	private: // New functions, for internal use
+
+        /**
+		* Checks that CSIPConnection is available for use (not NULL). If
+        * iConnection is NULL, it means user has deleted a resource needed by
+        * CRegBindingImplementation, and this function leaves.
+		*/
+        void CheckConnectionL() const;
+
+        /**
+		* Returns the current registration state. If state handler is not
+        * available, meaning user has deleted a resource needed by
+        * CRegBindingImplementation, this function leaves.        
+		*/
+        const CRegistrationState& StateL() const;
+
+		/**
+		* Checks that aElements don't contain Contact or Expires headers.
+        * @param aElements Message elements
+        * @leave KErrSIPMalformedMessage If Contact or Expires header is
+        *		 present in aElements.
+		*/
+        void CheckElementsL(const CSIPMessageElements* aElements) const;        
+
+		/**
+		* Removes, does not delete, Contact headers from aElements.
+		* @pre aElements != NULL
+        * @param aElements Message elements. Ownership is not transferred.        
+		*/
+        static void DetachContactHeader(TAny* aElements);
+
+		/**
+		* Removes, does not delete, the headers identified by aName, from
+		* aElements.
+		* @pre aElements != NULL
+        * @param aElements Message elements. Ownership is not transferred.
+        * @param aName Header name
+		*/
+        static void DetachHeaders(TAny* aElements, RStringF aName);        
+
+	private: // Data
+
+		//Registration binding who owns this CRegBindingImplementation instance
+		CSIPRegistrationBinding& iRegistration;
+		
+        //The used connection. CRegBindingImplementation doesn't own it.
+        //If this pointer is NULL; it means application has deleted the
+        //connection before deleting the CRegBindingImplementation, and this
+        //CRegBindingImplementation is now useless.
+        CSIPConnection* iConnection;		
+
+        //Outbound proxy or NULL if no proxy is specified. Owned.
+        CSIPRouteHeader* iOutboundProxy;
+
+        CSIPToHeader* iAor; //Owned.
+        CSIPFromHeader* iFrom; //Owned, can be NULL.
+        CSIPContactHeader* iContact; //Owned
+        
+        CSIPContactHeader* iRegisteredContact; //Owned, can be NULL
+
+        CUri8* iRemoteUri; //Owned, can be NULL.
+
+
+        //CRegBindingImplementation owns the CSIPRefresh object. It is not
+        //deleted even the refresh ends since user can try to register again,
+        //using the same CRegBindingImplementation (and CSIPRefresh) instance.
+        //CRegBindingImplementation can have maximum of one refresh object
+        CSIPRefresh* iRefresh;
+
+        //Id received from SIP client        
+        TUint32 iRegistrationId;        
+
+		//Only client transactions can be bound to registration. Transactions
+		//are not owned. Application owns them.
+        RPointerArray<CSIPClientTransaction> iTransactions;
+
+        //Current state of the registration. CRegBindingImplementation doesn't
+        //own the state object. If iState is NULL, it means the CSIP owning the
+        //registration states has been deleted.
+        const CRegistrationState* iState;        
+
+        TBool iSendWithExpires;
+        TBool iCacheOutboundProxyIP;
+
+	private: // For testing purposes
+	
+	    UNIT_TEST(CSIP_Test)
+        UNIT_TEST(CSIPRegistrationBinding_Test)
+        UNIT_TEST(CSIPInviteDialogAssoc_Test)
+        UNIT_TEST(CSIPSubscribeDialogAssoc_Test)
+        UNIT_TEST(CSIPReferDialogAssoc_Test)
+        
+		void __DbgTestInvariant() const;
+
+	};
+
+#endif