realtimenetprots/sipfw/ProfileAgent/IETF_Agent/src/Sipietfconnectioncontext.cpp
changeset 0 307788aac0a8
child 12 c2e8c8b73582
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/ProfileAgent/IETF_Agent/src/Sipietfconnectioncontext.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,697 @@
+// Copyright (c) 2003-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        : sipietfconnectioncontext.cpp
+// Part of     : sip ietf connection context
+// implementation
+// Version     : 1.0
+// INCLUDE FILES
+//
+
+
+
+#include    "sipietfconnectioncontext.h"
+#include	"sipmessageelements.h"
+#include	"sipregistrationbinding.h"
+#include	"sipconnection.h"
+#include	"sipclienttransaction.h"
+#include	"siprefresh.h"
+#include	"sipietfprofilecontext.h"
+#include	"sipprofileagent.h"
+#include	"sipconcreteprofile.h"
+#include	"SipProfileLog.h"
+#include	"CSIPProxyResolver.h"
+#include    "siperr.h"
+#include    "sipresponseelements.h"
+#include    <sip.h>
+#include    <siphttpdigest.h>
+#include    <sipprofile.h>
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::CSIPIetfConnectionContext
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CSIPIetfConnectionContext::CSIPIetfConnectionContext()
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::~CSIPIetfConnectionContext
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CSIPIetfConnectionContext::~CSIPIetfConnectionContext()
+	{
+	iContexts.ResetAndDestroy();
+
+	delete iProxyResolver;
+	delete iConnection;
+	
+	iUsers.Reset();
+	iUsers.Close();
+
+    delete iSipHttpDigest;
+    delete iSip;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::NewLC
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CSIPIetfConnectionContext* CSIPIetfConnectionContext::NewLC()
+	{
+	CSIPIetfConnectionContext* self =
+		new (ELeave) CSIPIetfConnectionContext();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::NewL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CSIPIetfConnectionContext* CSIPIetfConnectionContext::NewL()
+	{
+	CSIPIetfConnectionContext* self = 
+		CSIPIetfConnectionContext::NewLC();
+	CleanupStack::Pop();
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::SetConnection
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::SetConnection(CSIPConnection* aConnection)
+	{
+	delete iConnection;
+	iConnection = aConnection;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::Connection
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CSIPConnection* CSIPIetfConnectionContext::Connection()
+	{
+	return iConnection;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::IsIdle
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CSIPIetfConnectionContext::IsIdle() const
+	{
+	return (iContexts.Count()==0);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::FindContext
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CSIPIetfProfileContext* 
+	CSIPIetfConnectionContext::FindContext(TUint32 aProfileId)
+	{
+	CSIPIetfProfileContext* context = 0;
+	TBool found = EFalse;
+	for (TInt i=0; i<iContexts.Count() && !found; i++)
+		{
+		if (iContexts[i]->Profile() && iContexts[i]->Profile()->Id() == aProfileId)
+			{
+			context = iContexts[i];
+			found = ETrue;
+			}
+		}
+	return context;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::AddProfileContextL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void 
+CSIPIetfConnectionContext::AddProfileContextL(CSIPIetfProfileContext* aContext)
+	{
+	__ASSERT_DEBUG(aContext->Connection().IapId()==iConnection->IapId(),
+															 User::Invariant());
+	User::LeaveIfError(iContexts.Append(aContext));
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::CleanIdleContexts
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::CleanIdleContexts()
+	{
+	PROFILE_DEBUG1("CSIPIetfConnectionContext::CleanIdleContexts")
+	CSIPIetfProfileContext* context = 0;
+	for (TInt i= iContexts.Count()-1; i >= 0;i--)
+		{
+		PROFILE_DEBUG3("CSIPIetfConnectionContext::CleanIdleContexts iContexts.Count() > 0 i=",i)
+		if (iContexts[i]->CurrentState() == MSIPProfileContext::EInit &&
+			iContexts[i]->IsIdle())
+			{
+			PROFILE_DEBUG1("CSIPIetfConnectionContext::CleanIdleContexts, ProfileContext removed")
+			context = iContexts[i];
+			iContexts.Remove(i);
+			delete context;
+			context = NULL;	
+			}
+		}
+	iContexts.Compress();
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::SetCredentials
+// -----------------------------------------------------------------------------
+//
+TBool CSIPIetfConnectionContext::SetCredentials(
+    const CSIPClientTransaction& aTransaction,
+    CSIPHttpDigest& aDigest)
+    {
+	TBool found = EFalse;
+	for (TInt i=0; i < iContexts.Count() && !found; i++)
+		{
+		if (iSipHttpDigest)
+		    {
+		    found = iContexts[i]->SetCredentials(aTransaction,*iSipHttpDigest);
+		    }
+		else
+		    {
+		    found = iContexts[i]->SetCredentials(aTransaction,aDigest);
+		    }
+		}
+    return found;   
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::SetCredentials
+// -----------------------------------------------------------------------------
+//
+TBool CSIPIetfConnectionContext::SetCredentials(
+    const CSIPRefresh& aRefresh,
+    CSIPHttpDigest& aDigest)
+    {
+	TBool found = EFalse;
+	for (TInt i=0; i < iContexts.Count() && !found; i++)
+		{
+		if (iSipHttpDigest)
+		    {
+		    found = iContexts[i]->SetCredentials(aRefresh,*iSipHttpDigest);
+		    }
+		else
+		    {
+		    found = iContexts[i]->SetCredentials(aRefresh,aDigest);
+		    }
+		}
+    return found;    
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ConnectionUser
+// -----------------------------------------------------------------------------
+//
+TBool CSIPIetfConnectionContext::ConnectionUser( CSIPConcreteProfile& aProfile )
+    {
+    TBool connectionUser( EFalse );
+    if ( aProfile.IapId() == iConnection->IapId() )
+        {
+        connectionUser = ( iUsers.Find( &aProfile ) != KErrNotFound );
+        }
+    return connectionUser;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::SetConnectionUserL
+// -----------------------------------------------------------------------------
+//    
+void CSIPIetfConnectionContext::SetConnectionUserL( 
+    CSIPConcreteProfile& aProfile )
+    {
+    __ASSERT_ALWAYS( iConnection, User::Leave( KErrNotReady ) );
+    
+    iUsers.AppendL( &aProfile );
+
+    SetConnectionParameters();
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::CreateSipL
+// -----------------------------------------------------------------------------
+//
+CSIP& CSIPIetfConnectionContext::CreateSipL( 
+    MSIPObserver& aSipObserver,
+    MSIPHttpDigestChallengeObserver2& aSipHttpDigestObserver )
+    {
+    __ASSERT_ALWAYS( !iSip, User::Leave( KErrAlreadyExists ) );
+    __ASSERT_ALWAYS( !iSipHttpDigest, User::Leave( KErrAlreadyExists ) );
+    
+	iSip = CSIP::NewL( TUid::Null(), aSipObserver );
+	iSipHttpDigest = CSIPHttpDigest::NewL( *iSip, aSipHttpDigestObserver );
+    return *iSip;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ResolveL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ResolveL()
+	{
+	CleanProxyResolving();
+	ResolveProxyL();
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ResolveProxyL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ResolveProxyL()
+	{
+	PROFILE_DEBUG1("CSIPIetfConnectionContext::ResolveProxyL")
+	if (iProxyResolveRequestId == 0)
+		{
+		if (iProxyResolver == 0)
+			{
+			iProxyResolver = CSIPProxyResolver::NewL();
+			}
+
+		if (iConnection->State() == CSIPConnection::EActive)
+			{
+			PROFILE_DEBUG1("CSIPIetfConnectionContext::ResolveProxyL, resolving")
+			iProxyResolver->ResolveProxyL(
+				iProxyResolveRequestId, iConnection->IapId(), *this);
+			}
+		}
+	PROFILE_DEBUG1("CSIPIetfConnectionContext::ResolveProxyL, exit")
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::CleanProxyResolving
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::CleanProxyResolving()
+	{
+	PROFILE_DEBUG1("CSIPIetfConnectionContext::CleanProxyResolving")
+	if(iProxyResolveRequestId)
+		{
+		iProxyResolver->Cancel(iProxyResolveRequestId);
+		iProxyResolveRequestId = 0;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ConnectionStateChanged
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ConnectionStateChanged(
+	CSIPConnection::TState aState)
+	{
+	PROFILE_DEBUG1("CSIPIetfConnectionContext::ConnectionStateChanged")
+	if (aState == CSIPConnection::EActive)
+		{
+		PROFILE_DEBUG1("ConnectionStateChanged, Active")
+		}
+	else if (aState == CSIPConnection::EInactive
+			|| aState == CSIPConnection::EUnavailable)
+		{
+		PROFILE_DEBUG3("ConnectionStateChanged, state: ", aState)
+		CleanProxyResolving();
+		}
+	else
+		{
+		PROFILE_DEBUG3("ConnectionStateChanged, state: ", aState)
+		//makes pclint happy
+		}
+
+	CleanIdleContexts();
+
+	for (TInt i=0; i<iContexts.Count(); i++)
+		{
+		iContexts[i]->ConnectionStateChanged(aState);
+		}
+	} 
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::IncomingResponse
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::IncomingResponse(
+	CSIPClientTransaction& aTransaction,
+	CSIPRegistrationBinding& aRegistration)
+	{
+	PROFILE_DEBUG1("CSIPIetfConnectionContext::IncomingResponse")
+	TBool handled = EFalse;
+
+	CleanIdleContexts();
+
+	for (TInt i=0; i<iContexts.Count() && !handled; i++)
+		{
+		const CSIPResponseElements* response = aTransaction.ResponseElements();
+		if (response)
+		    {
+    		TBool isErrorResponse = (response->StatusCode() >= 300);
+    		TInt contextCountBefore = iContexts.Count();
+    		
+    		iContexts[i]->IncomingResponse(aTransaction, aRegistration, handled);
+    		
+    		TBool contextRemoved = (iContexts.Count() != contextCountBefore);	
+    		if (handled && !contextRemoved && isErrorResponse)
+    			{
+                iContexts[i]->RetryRegistration();
+    			}
+		    }
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ErrorOccured
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ErrorOccured(
+	TInt aError,
+	CSIPClientTransaction& aTransaction,
+	CSIPRegistrationBinding& aRegistration)
+	{
+	PROFILE_DEBUG3("CSIPIetfConnectionContext::ErrorOccured", aError)
+	TBool handled = EFalse;
+
+	CleanIdleContexts();
+
+	for (TInt i=0; i<iContexts.Count() && !handled; i++)
+		{
+		iContexts[i]->ErrorOccured(aError, aTransaction, aRegistration, handled);
+		if (handled && (iProxyResolveRequestId == 0))
+			{
+			if ( iContexts[i]->RetryTimerInUse() )
+				{
+				iContexts[i]->RetryDeltaTimer( iContexts[i]->DelayTime(), aError );
+				}
+			else
+				{
+				iContexts[i]->RetryRegistration();
+				}
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ErrorOccured
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ErrorOccured(
+	TInt aError,
+	CSIPRegistrationBinding& aRegistration)
+	{
+	PROFILE_DEBUG3("CSIPIetfConnectionContext::ErrorOccured", aError)
+	TBool handled = EFalse;
+
+	CleanIdleContexts();
+
+	for (TInt i=0; i<iContexts.Count() && !handled; i++)
+		{
+		if (aError == KErrSIPTerminatedWithResponse)
+			{
+			const CSIPClientTransaction* transaction = 
+            iContexts[i]->Registration()->SIPRefresh()->SIPTransaction();
+    		if (transaction)
+            	{
+            	aError = transaction->ResponseElements()->StatusCode();
+            	iContexts[i]->CSIPProfileContextBase::ErrorOccured(aError,
+		                           const_cast<CSIPClientTransaction&> (*transaction),
+		                           aRegistration,
+		                           handled);
+            	}
+            else
+            	{
+            	iContexts[i]->ErrorOccured(aError, aRegistration, handled);
+            	}
+			}
+		else
+			{
+			iContexts[i]->ErrorOccured(aError, aRegistration, handled);
+			}
+			
+		if (handled && (iProxyResolveRequestId == 0))
+			{
+			if ( iContexts[i]->RetryTimerInUse() )
+				{
+				iContexts[i]->RetryDeltaTimer( iContexts[i]->DelayTime(), aError );
+				}
+			else
+				{
+				iContexts[i]->RetryRegistration();
+				}
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ProxyResolvingRequestComplete
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ProxyResolvingRequestComplete(
+	TUint /*aRequestId*/, MDesC8Array* aProxies)
+	{
+	PROFILE_DEBUG1("CSIPIetfConnectionContext::ProxyResolvingRequestComplete")
+	iProxyResolveRequestId = 0;
+
+	CleanIdleContexts();
+
+	TInt err = KErrNone;
+	for (TInt i=0; i<iContexts.Count(); i++)
+		{
+		TRAP(err, iContexts[i]->ProxyResolvingRequestCompleteL(*aProxies));
+		if (err != KErrNone)
+			{
+			iContexts[i]->HandleProxyResolvingError(err);	
+			}
+		}
+	delete aProxies;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ProxyResolvingRequestFailed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ProxyResolvingRequestFailed(
+	TUint /*aRequestId*/, TInt aError)
+	{
+	PROFILE_DEBUG3("CSIPIetfConnectionContext::\
+		ProxyResolvingRequestFailed", aError)
+	CleanIdleContexts();
+	iProxyResolveRequestId = 0;
+
+	for (TInt i=0; i<iContexts.Count(); i++)
+		{
+		iContexts[i]->ProxyResolvingRequestFailed(aError);
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ConstructL()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ErrorOccured
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ErrorOccured(
+	TInt /*aError*/,
+	CSIPTransactionBase& /*aTransaction*/)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::IncomingRequest
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::IncomingRequest(
+	CSIPServerTransaction* /*aTransaction*/)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::IncomingRequest
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::IncomingRequest(
+	CSIPServerTransaction* /*aTransaction*/,
+	CSIPDialog& /*aDialog*/)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::IncomingResponse
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::IncomingResponse(
+	CSIPClientTransaction& /*aTransaction*/)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::IncomingResponse
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::IncomingResponse(
+	CSIPClientTransaction& /*aTransaction*/,
+	CSIPDialogAssocBase& /*aDialogAssoc*/)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::IncomingResponse
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::IncomingResponse(
+	CSIPClientTransaction& /*aTransaction*/,
+	CSIPInviteDialogAssoc* /*aDialogAssoc*/)
+	{
+	}
+
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ErrorOccured
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ErrorOccured(
+	TInt /*aError*/,
+	CSIPDialogAssocBase& /*aDialogAssoc*/)
+	{
+	}
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ErrorOccured
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ErrorOccured(
+	TInt /*aError*/,
+	CSIPTransactionBase& /*aTransaction*/,
+	CSIPDialogAssocBase& /*aDialogAssoc*/)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::ErrorOccured
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::ErrorOccured(
+	TInt /*aError*/,
+	CSIPRefresh& /*aRefresh*/)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::InviteCompleted
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::InviteCompleted(
+	CSIPClientTransaction& /*aTransaction*/)
+	{
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::InviteCanceled
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::InviteCanceled(
+    CSIPServerTransaction& /*aTransaction*/)
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::AddIntoQueue
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CSIPIetfConnectionContext::AddIntoQueue( const TDesC8& aValue )
+	{
+	PROFILE_DEBUG1("CSIPIetfConnectionContext::AddIntoQue")
+    TBool result = EFalse;
+	for (TInt i=0; i<iContexts.Count() && !result; i++)
+		{
+		result = iContexts[i]->AddIntoQueue( aValue );
+		}
+	return result;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPIetfConnectionContext::SetConnectionParameters
+// -----------------------------------------------------------------------------
+//
+void CSIPIetfConnectionContext::SetConnectionParameters()
+    {
+    PROFILE_DEBUG1("CSIPIetfConnectionContext::SetConnectionParameters")
+    
+    // Params are taken from first user
+    if ( iUsers.Count() > 0 && 
+         !iConnectionParamsSet && 
+         iConnection )
+        {
+        TUint32 signallingQosValue( 0 );
+        if ( iUsers[ 0 ]->ExtensionParameter( 
+                KSIPSoIpTOS, signallingQosValue ) != KErrNotFound )
+            {
+            PROFILE_DEBUG3(
+                "CSIPIetfConnectionContext::SetConnectionParametersL, val:", 
+                signallingQosValue)
+            
+            // Errors can be ignored as they are not preventing registration    
+            TRAP_IGNORE( iConnection->SetOptL( KSoIpTOS, 
+                                               KProtocolInetIp, 
+                                               signallingQosValue ) )
+            iConnectionParamsSet = ETrue;
+            }
+        }
+        
+    PROFILE_DEBUG1("CSIPIetfConnectionContext::SetConnectionParameters, exit")
+    }