diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/sipapi/src/SipConnectionImplementation.h --- /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 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 iDialogs; + + //CSIPConnectionImplementation has to know which transactions are + //attached to it, but application still owns the transactions. + RPointerArray iTransactions; + + //Standalone refreshes, application owns these + RPointerArray 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