realtimenetprots/sipfw/ProfileAgent/profile_fsm/src/Sipprofilecontextbase.cpp
changeset 0 307788aac0a8
child 51 8134400f8f89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/ProfileAgent/profile_fsm/src/Sipprofilecontextbase.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,1071 @@
+// Copyright (c) 2007-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        : sipprofilecontextbase.cpp
+// Part of     : sip profile fsm
+// implementation
+// Version     : %version: 3.1.1 %
+//
+
+
+
+// INCLUDE FILES
+#include <bamdesca.h>
+#include "sipprofilecontextbase.h"
+#include "sipgendefs.h"
+#include "SipProfileLog.h"
+#include "sipprflstatebase.h"
+#include "sipconcreteprofile.h"
+#include "sipprofileagentobserver.h"
+#include "siperr.h"
+#include "siphttpdigest.h"
+#include "sipconnection.h"
+#include "sipregistrationbinding.h"
+#include "siprefresh.h"
+#include "sipclienttransaction.h"
+#include "sipresponseelements.h"
+#include "sipmessageelements.h"
+#include "sipwwwauthenticateheader.h"
+#include "sipproxyauthenticateheader.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "sipmanagedprofile.h"
+#include "sip.h"
+#include <uri8.h>
+
+const TInt KMicroSecsInSec = 1000000;
+_LIT8(KTmpSipUri, "sip:tmp");
+_LIT8(KDynamicProxy, "0.0.0.0");
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::CSIPProfileContextBase
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPProfileContextBase::CSIPProfileContextBase(
+	CSIP& aSIP,
+	CSIPConnection& aConnection,
+	MSIPProfileAgentObserver& aObserver,
+	CSIPPrflStateBase& aInitState,
+	CSIPConcreteProfile& aProfile,
+	CDeltaTimer& aDeltaTimer)
+	: iSIP(aSIP),
+	  iConnection(aConnection),
+	  iObserver(aObserver),
+	  iCurrentState(&aInitState),
+	  iInitState(&aInitState),
+	  iProfile(&aProfile),
+	  iProfileId(aProfile.Id()),
+	  iDeltaTimer(aDeltaTimer),
+	  iErrorForDeltaTimer(KErrNone),
+	  iDynamicProxyCount(0),
+	  iDeltaTimerCallBack(RetryDeltaTimerExpired, this), 
+	  iRetryPossible(EFalse),
+	  iResolvingCompleted(EFalse),
+	  iUseBackupProxy(EFalse)
+	{
+	iDeltaTimerEntry.Set(iDeltaTimerCallBack);
+    iWwwAuthenticateHeaderName = 
+        SIPStrings::StringF(SipStrConsts::EWWWAuthenticateHeader);
+    iProxyAuthenticateHeaderName =
+        SIPStrings::StringF(SipStrConsts::EProxyAuthenticateHeader);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RetryDeltaTimer()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::RetryDeltaTimer( TUint aTime, TInt aError )
+	{
+	iErrorForDeltaTimer = aError;
+    iDeltaTimer.Remove(iDeltaTimerEntry);
+    TTimeIntervalMicroSeconds32 interval(aTime*KMicroSecsInSec);
+    iDeltaTimer.Queue(interval,iDeltaTimerEntry);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RetryDeltaTimerExpired()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CSIPProfileContextBase::RetryDeltaTimerExpired( TAny* aPtr )
+	{
+    CSIPProfileContextBase* self = reinterpret_cast<CSIPProfileContextBase*>(aPtr);
+    self->InitializeRetryTimerValue();
+    if (self->AgentObserver().ProceedRegistration( *(self->Profile()), self->iErrorForDeltaTimer) )
+    	{
+		TRAP_IGNORE(self->ContinueRegistrationL())
+    	}
+    return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ContinueRegistrationL()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPProfileContextBase::ContinueRegistrationL()
+	{
+    iCurrentState->ChangeRegistrationStateL(*this);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetNegotiatedSecurityMechanismL()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::SetNegotiatedSecurityMechanismL()
+    {
+    if (iProfile)
+        {
+        TPtrC8 proxyHost(ExtractProxyHost());
+        if (proxyHost.Length() > 0)
+            {
+            HBufC8* secMech = iSIP.NegotiatedSecurityMechanismL(proxyHost);
+            if (secMech)
+                {
+                CleanupStack::PushL(secMech);
+                iProfile->SetNegotiatedSecurityMechanismL(*secMech);
+                CleanupStack::PopAndDestroy(secMech);
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ResetNegotiatedSecurityMechanismL()
+// -----------------------------------------------------------------------------
+//		
+EXPORT_C void CSIPProfileContextBase::ResetNegotiatedSecurityMechanismL()
+    {
+    if (iProfile)
+        {
+        iProfile->SetNegotiatedSecurityMechanismL(KNullDesC8);
+        }
+    }
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RemoveDeltaTimerEntry
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::RemoveDeltaTimerEntry()
+	{
+	iDeltaTimer.Remove(iDeltaTimerEntry);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::~CSIPProfileContextBase
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPProfileContextBase::~CSIPProfileContextBase()
+	{
+    delete iClientTx;
+	delete iRegistration;
+	delete iProxies;
+	iDeltaTimer.Remove(iDeltaTimerEntry);
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::Connection()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const CSIPConnection& CSIPProfileContextBase::Connection() const
+	{
+	return iConnection;
+	}	
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::Registration()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPRegistrationBinding* CSIPProfileContextBase::Registration()
+	{
+	return iRegistration;
+	}	
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetNextState()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::SetNextState(CSIPPrflStateBase& aState)
+	{
+	iCurrentState = &aState;
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ForgetProfile
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::ForgetProfile()
+	{
+	PROFILE_DEBUG3("CSIPProfileContextBase::ForgetProfile", ProfileId())
+
+    TRAP_IGNORE(ResetRegisteredAORsL())
+	
+	if (!iRetryPossible) 
+		{
+	    delete iClientTx;
+	    iClientTx = 0;
+	    iProfile = 0;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetTransaction()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::SetTransaction(
+    CSIPClientTransaction* aTransaction)
+	{
+	delete iClientTx;
+	iClientTx = aTransaction;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::Profile()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPConcreteProfile* CSIPProfileContextBase::Profile()
+	{
+	return iProfile;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::AgentObserver()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C MSIPProfileAgentObserver& CSIPProfileContextBase::AgentObserver() const
+	{
+	return iObserver;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetProfile()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::SetProfile(CSIPConcreteProfile* aProfile)
+	{
+	iProfile = aProfile;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetRegisteredAORs()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//	
+EXPORT_C TInt CSIPProfileContextBase::SetRegisteredAORs()
+    {
+    TRAPD(err, SetRegisteredAORsL());
+    return err;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::CurrentState
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C MSIPProfileContext::TSIPProfileState 
+CSIPProfileContextBase::CurrentState() const
+	{
+    PROFILE_DEBUG4("CSIPProfileContextBase::CurrentState"\
+        ,ProfileId(), iCurrentState->Name())
+    return iCurrentState->Name();
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::CurrentMappedState
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//	
+EXPORT_C CSIPConcreteProfile::TStatus 
+CSIPProfileContextBase::CurrentMappedState() const
+    {
+    PROFILE_DEBUG4("CSIPProfileContextBase::CurrentMappedState"\
+        ,ProfileId(), iCurrentState->ConcreteProfileState())
+    return iCurrentState->ConcreteProfileState();
+    }	
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RegisterL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::RegisterL()
+	{
+	PROFILE_DEBUG4("CSIPProfileContextBase::RegisterL", ProfileId()\
+		,iCurrentState->Name())
+	
+    iCurrentState->RegisterL(*this);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::IsRegisterPending()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+// 		
+EXPORT_C TBool CSIPProfileContextBase::IsRegisterPending() const
+    {
+    return iCurrentState->IsRegisterPending();
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RetryRegistration
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::RetryRegistration()
+	{
+	PROFILE_DEBUG3("CSIPProfileContextBase::RetryRegistration", ProfileId())
+	if (iRetryPossible)
+		{
+		PROFILE_DEBUG1("RetryRegistration, retry possible")
+		SetNextState(*iInitState);
+		TInt err = KErrNone;
+		if (iProxies && iProxies->MdcaCount() > iDynamicProxyCount)
+			{
+			PROFILE_DEBUG1("RetryRegistration, register dynamic")
+			TRAP(err, RegisterDynamicL(*iProxies));
+			}
+		else
+			{			
+			iResolvingCompleted = EFalse;
+			TRAP(err, iCurrentState->RegisterL(*this));
+			}
+	    if (err)
+	        {
+	        HandleProxyResolvingError(err);
+	        }
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ProxyResolvingRequestCompleteL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::ProxyResolvingRequestCompleteL(
+	MDesC8Array& aProxies)
+	{
+	PROFILE_DEBUG3("CSIPProfileContextBase::ProxyResolvingRequestCompleteL"\
+		,ProfileId())
+    iCurrentState->ProxyResolvingRequestCompleteL(*this,aProxies);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ProxyResolvingRequestFailed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::ProxyResolvingRequestFailed(TInt aError)
+	{
+	PROFILE_DEBUG4("CSIPProfileContextBase::ProxyResolvingRequestFailed"\
+		,ProfileId(), aError)
+	iCurrentState->ProxyResolvingRequestFailed(*this,aError);
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::HandleProxyResolvingError()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::HandleProxyResolvingError(TInt aError)
+    {
+	PROFILE_DEBUG4("CSIPProfileContextBase::HandleProxyResolvingError"\
+		,ProfileId(), aError)
+	//If backup proxy is configured fall back to the backup proxy
+	//if its not previously tried(i.e, when iUseBackupProxy is false)
+	if(!iUseBackupProxy && !iRetryPossible && iProfile)
+		{
+		if(iProfile->Server(KSIPOutboundProxy).Length() > 0)
+			{
+			TUriParser8 parser;
+			if (KErrNone == parser.Parse(iProfile->Server(KSIPOutboundProxy)))
+				{
+				iUseBackupProxy = (parser.Extract(EUriHost).CompareF(KDynamicProxy) != 0);
+				}
+			}
+		if(iUseBackupProxy)
+			{
+			SetNextState(*iInitState);
+			TRAPD(err, iCurrentState->RegisterL(*this));
+			if(err == KErrNone)
+				{
+				return;
+				}
+			}
+		}
+	iUseBackupProxy = EFalse;
+	iRetryPossible = EFalse;
+	delete iProxies;
+	iProxies = 0;
+	iResolvingCompleted = ETrue;
+	iDynamicProxyCount = 0;
+	CSIPConcreteProfile* profile = iProfile;
+	ForgetProfile();
+	DestroyRegistration();
+	iObserver.SIPProfileErrorEvent(*profile,aError);
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::IgnoreErrorEvent
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::IgnoreErrorEvent()
+	{
+	PROFILE_DEBUG4("CSIPProfileContextBase::IgnoreErrorEvent", ProfileId()\
+		, iRetryPossible)
+	return iRetryPossible;
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::TerminateHandling
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::TerminateHandling()
+	{
+	PROFILE_DEBUG1("CSIPProfileContextBase::TerminateHandling")
+	ForgetProfile();
+	DestroyRegistration();
+	}	
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ErrorOccured()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::ErrorOccured(
+	TInt aError,
+	CSIPRegistrationBinding& aRegistration,
+	TBool& aHandled)
+	{
+	if (iRegistration && aRegistration==*iRegistration)
+		{
+		PROFILE_DEBUG3("CSIPProfileContextBase::ErrorOccured", ProfileId())
+		if ( !RetryRegister( NULL,  aError) )
+			{
+			RetryPossible(aError);
+			}
+		aHandled = ETrue;
+		iCurrentState->ErrorOccured(*this, aError);
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ErrorOccured()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::ErrorOccured(
+	TInt aError,
+	CSIPClientTransaction& aTransaction,
+	CSIPRegistrationBinding& aRegistration,
+	TBool& aHandled)
+	{
+	if (iRegistration && 
+		aRegistration==*iRegistration)
+		{
+		PROFILE_DEBUG3("CSIPProfileContextBase::ErrorOccured", ProfileId())
+		if ( !RetryRegister( &aTransaction,  aError) )
+			{
+			RetryPossible(aError);
+			}
+		aHandled = ETrue;
+		iCurrentState->ErrorOccured(*this, aError);
+		}
+	}	
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ConnectionStateChanged
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::ConnectionStateChanged(
+	CSIPConnection::TState aState)
+	{
+	PROFILE_DEBUG4("CSIPProfileContextBase::ConnectionStateChanged"
+		,ProfileId(), aState)
+	PROFILE_DEBUG3("ConnectionStateChanged, current state"
+		,iCurrentState->Name())
+
+    ConnectionStateChangedImpl(aState);
+
+    iCurrentState->ConnectionStateChanged(*this, aState);
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RequireProxyResolving
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::RequireProxyResolving()
+	{
+	PROFILE_DEBUG1("CSIPProfileContextBase::RequireProxyResolving")
+	return (iProfile != 0 && IsProxyResolvingEnabled() && !iResolvingCompleted);
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ProxyAddressL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CSIPProfileContextBase::ProxyAddressL()
+	{
+	if (iProfile)
+		{
+		return ProxyAddressL(*iProfile);
+		}
+	else
+		{
+		return KNullDesC8;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ProxyAddressL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CSIPProfileContextBase::ProxyAddressL(
+	CSIPConcreteProfile& aProfile)
+	{
+	if (iProfile && IsProxyResolvingEnabled())
+		{
+		return iProfile->DynamicProxy();
+		}
+	else
+		{
+		return aProfile.Server(KSIPOutboundProxy);
+		}
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::Received2XXRegisterResponse
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPProfileContextBase::Received2XXRegisterResponse()
+	{
+	PROFILE_DEBUG1("CSIPProfileContextBase::Received2XXRegisterResponse")
+	iRetryPossible = EFalse;
+	iResolvingCompleted = ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RetryPossible
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::RetryPossible(TInt aError)
+	{
+	PROFILE_DEBUG4("CSIPProfileContextBase::RetryPossible", ProfileId(), aError)
+	if (iProfile && IsProxyResolvingEnabled())
+		{
+		iDynamicProxyCount++;
+		PROFILE_DEBUG3("RetryPossible, resolving enabled, count",\
+			iDynamicProxyCount)
+		if (ShouldRetryRegistration(aError))
+			{
+			if (iResolvingCompleted)
+				{
+				PROFILE_DEBUG1("RetryPossible = ETrue, re-registration")
+				SetRetryPossible(ETrue);
+				}
+			else if ((iProxies && iDynamicProxyCount < iProxies->MdcaCount()) ||
+			          (iProxies == NULL))
+				{
+				PROFILE_DEBUG1("RetryPossible = ETrue, initial-registration")
+				iRetryPossible = ETrue;
+				}
+			else
+				{
+				PROFILE_DEBUG1("RetryPossible = EFalse, initial-registration")
+				iRetryPossible = EFalse;
+				}
+			}
+		else
+			{
+			PROFILE_DEBUG1("RetryPossible = EFalse, cleaning")
+			iDynamicProxyCount = 0;
+			iRetryPossible = EFalse;
+			iResolvingCompleted = EFalse;
+			}
+		}
+    else
+        {
+        iRetryPossible = EFalse;
+        }
+	return iRetryPossible;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetRetryPossible
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//	
+EXPORT_C void CSIPProfileContextBase::SetRetryPossible(TBool aRetryPossible)
+    {
+    iRetryPossible = aRetryPossible;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ProfileId
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//   
+EXPORT_C TUint32 CSIPProfileContextBase::ProfileId() const
+	{
+	if (iProfile)
+		{
+		return iProfile->Id();
+		}
+	else
+		{
+		return 0;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::IsProxyResolvingEnabled()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::IsProxyResolvingEnabled() const
+	{	
+	TBool enabled = EFalse; 
+	if(!iUseBackupProxy && iProfile)
+		{
+		iProfile->ExtensionParameter(KSIPResolveProxy,enabled);
+		if (!enabled && iProfile->Server(KSIPOutboundProxy).Length() > 0)
+			{
+			TUriParser8 parser;
+			if (KErrNone == parser.Parse(iProfile->Server(KSIPOutboundProxy)))
+				{
+				enabled = (parser.Extract(EUriHost).CompareF(KDynamicProxy) == 0);
+				}
+			}
+		}
+    return enabled;
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::AddIntoQueue()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::AddIntoQueue( const TDesC8& aRegistrar )
+	{
+	TBool result = EFalse;
+	if ( iCurrentState->IsRegisterPending() )
+		{
+		result = (Profile()->Server(KSIPRegistrar).Compare( aRegistrar ) == 0);
+		}
+	return result;
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::AddDeregisterIntoQueue()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::AddDeregisterIntoQueue()
+	{
+	return iCurrentState->IsRegisterPending();
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::IsIdle
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::IsIdle()
+    {
+	PROFILE_DEBUG1("CSIPProfileContextBase::IsIdle")    
+    return iCurrentState->IsIdle( *this );
+    } 
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetCredentials
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::SetCredentials(
+    const CSIPClientTransaction& aTransaction,
+    CSIPHttpDigest& aDigest)
+    {
+    TBool handled = EFalse;
+    const CSIPResponseElements* response = aTransaction.ResponseElements();
+    
+    if (HasTransaction(aTransaction) && response)
+        {
+        handled = ETrue;
+        SetCredentialsImplementation(aTransaction,*response,aDigest);
+        }
+    return handled;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetCredentials
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::SetCredentials(
+    const CSIPRefresh& aRefresh,
+    CSIPHttpDigest& aDigest)
+    {
+    TBool handled = EFalse;
+    const CSIPClientTransaction* ta = aRefresh.SIPTransaction();
+    
+    if (HasRefresh(aRefresh) && ta && ta->ResponseElements())
+        {
+        handled = ETrue;
+        const CSIPResponseElements* response = ta->ResponseElements();
+        SetCredentialsImplementation(aRefresh,*response,aDigest);
+        }
+    return handled;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ProxiesAlreadyResolved()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::ProxiesAlreadyResolved()
+    {
+    return (iProxies && iProxies->MdcaCount() > 0);
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetProxiesL()
+// -----------------------------------------------------------------------------
+//	
+EXPORT_C void CSIPProfileContextBase::SetProxiesL(MDesC8Array& aProxies)
+    {
+    __ASSERT_ALWAYS(aProxies.MdcaCount() > 0, User::Leave(KErrArgument));
+
+    CDesC8ArrayFlat* tmpArray = new (ELeave) CDesC8ArrayFlat(1);
+    CleanupStack::PushL(tmpArray);
+
+    for (TInt i = 0; i < aProxies.MdcaCount(); i++)
+        {
+        tmpArray->AppendL(aProxies.MdcaPoint(i));
+        }
+
+    CleanupStack::Pop(tmpArray);
+    
+    delete iProxies;
+	iProxies = tmpArray;
+	
+	ConstructDynamicProxyL(iProxies->MdcaPoint(0));
+	
+	iDynamicProxyCount = 0;   
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::HasTransaction
+// The default base class implementation
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSIPProfileContextBase::HasTransaction(
+    const CSIPClientTransaction& aTransaction) const
+    {
+    if (iClientTx && 
+        aTransaction == *iClientTx)
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::HasRefresh
+// The default base class implementation
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C TBool CSIPProfileContextBase::HasRefresh(
+    const CSIPRefresh& aRefresh) const
+    {
+    if (iRegistration && 
+        iRegistration->SIPRefresh() &&
+        aRefresh == *(iRegistration->SIPRefresh()))
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RegistrarUsername
+// The default base class implementation
+// -----------------------------------------------------------------------------
+//   
+EXPORT_C const TDesC8& CSIPProfileContextBase::RegistrarUsername() const
+    {
+    if (iProfile)
+        {
+        return iProfile->ServerParameter(KSIPRegistrar,KSIPDigestUserName);
+        }
+    return KNullDesC8;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::RegisterDynamicL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPProfileContextBase::RegisterDynamicL(MDesC8Array& aProxies)
+	{
+	__ASSERT_ALWAYS(IsProxyResolvingEnabled(),
+		User::Leave(KErrArgument));
+	__ASSERT_ALWAYS(aProxies.MdcaCount() > iDynamicProxyCount, 
+		User::Leave(KErrArgument));
+
+	ConstructDynamicProxyL(aProxies.MdcaPoint(iDynamicProxyCount));
+	iCurrentState->RegisterL(*this);
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ConstructDynamicProxyL()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPProfileContextBase::ConstructDynamicProxyL(const TDesC8& aProxy)
+	{
+	__ASSERT_ALWAYS(iProfile, User::Leave(KErrNotReady));
+	
+	TPtrC8 uriDesPtr;
+	if (iProfile->Server(KSIPOutboundProxy).Length() > 0)
+		{
+		uriDesPtr.Set(iProfile->Server(KSIPOutboundProxy));
+		}
+	else
+		{
+		uriDesPtr.Set(KTmpSipUri);
+		}
+    TUriParser8 uriParser;
+    User::LeaveIfError(uriParser.Parse(uriDesPtr));
+    CUri8* uri = CUri8::NewLC(uriParser);
+    uri->SetComponentL(aProxy,EUriHost);
+	iProfile->SetDynamicProxyL(uri->Uri().UriDes());
+	CleanupStack::PopAndDestroy(uri);	
+		
+	PROFILE_DEBUG6("CSIPProfileContextBase::ConstructDynamicProxyL", 
+	               iProfile->DynamicProxy())
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ClearProxyResolving()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSIPProfileContextBase::ClearProxyResolving()
+	{
+	PROFILE_DEBUG1("CSIPProfileContextBase::ClearProxyResolving")
+	iDynamicProxyCount = 0;
+	iRetryPossible = ETrue;
+	iResolvingCompleted = EFalse;
+	delete iProxies;
+	iProxies = 0;
+	}
+	
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ResetRegisteredAORsL()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//  
+void CSIPProfileContextBase::ResetRegisteredAORsL()
+    {
+    if (iProfile)
+        {
+        CDesC8ArrayFlat* array = new(ELeave)CDesC8ArrayFlat(1);
+	    CleanupStack::PushL(array);
+	    iProfile->SetRegisteredAORsL(*array);
+	    CleanupStack::PopAndDestroy(array);
+	    iProfile->SetExtensionParameterL(KSIPRegisteredContact,KNullDesC8);   
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::SetCredentialsImplementation 
+// -----------------------------------------------------------------------------
+//
+template<class T> void CSIPProfileContextBase::SetCredentialsImplementation(
+    const T& aChallengeTarget,
+    const CSIPResponseElements& aResponse,
+    CSIPHttpDigest& aDigest)
+    {
+    const RPointerArray<CSIPHeaderBase>& headers = 
+        aResponse.MessageElements().UserHeaders();
+        
+    for (TInt i=0; i < headers.Count(); i++)
+        {
+        const CSIPHeaderBase* header = headers[i];
+        if (header->Name() == iWwwAuthenticateHeaderName)
+            {
+            const CSIPWWWAuthenticateHeader* wwwAuthHeader =
+                static_cast<const CSIPWWWAuthenticateHeader*>(header);
+            TPtrC8 realm(wwwAuthHeader->DesParamValue(
+                SIPStrings::StringF(SipStrConsts::ERealm)));
+            TPtrC8 username(KNullDesC8);
+            TPtrC8 password(KNullDesC8);
+            if (GetRegistrarCredentials(username,password))
+                {
+                TRAPD(err, aDigest.SetCredentialsL(aChallengeTarget,
+                                                   KNullDesC8,
+                                                   realm,
+                                                   username,
+                                                   password));
+                if (err)
+                    {
+                    aDigest.IgnoreChallenge(aChallengeTarget,realm);
+                    }
+                }
+            else
+                {
+                aDigest.IgnoreChallenge(aChallengeTarget,realm);
+                }
+            }
+        else if (header->Name() == iProxyAuthenticateHeaderName)
+            {
+            const CSIPProxyAuthenticateHeader* proxyAuthHeader =
+                static_cast<const CSIPProxyAuthenticateHeader*>(header);
+            TPtrC8 realm = proxyAuthHeader->DesParamValue(
+                SIPStrings::StringF(SipStrConsts::ERealm));
+            TPtrC8 proxyHost(KNullDesC8);
+            TPtrC8 username(KNullDesC8);
+            TPtrC8 password(KNullDesC8);
+            if (GetProxyCredentials(proxyHost,username,password))
+                {
+                TRAPD(err, aDigest.SetCredentialsL(aChallengeTarget,
+                                                   proxyHost,
+                                                   realm,
+                                                   username,
+                                                   password));
+                if (err)
+                    {
+                    aDigest.IgnoreChallenge(aChallengeTarget,realm);
+                    }
+                }
+            else
+                {
+                aDigest.IgnoreChallenge(aChallengeTarget,realm);
+                }
+            }
+        else
+            {
+            // Not WWW-/Proxy-Authenticate-header: Do nothing.
+            }
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::GetRegistrarCredentials
+// -----------------------------------------------------------------------------
+//
+TBool CSIPProfileContextBase::GetRegistrarCredentials(
+    TPtrC8& aUsername,
+    TPtrC8& aPassword) const
+    {
+    aUsername.Set(KNullDesC8);
+    aPassword.Set(KNullDesC8);
+    if (iProfile)
+        {    
+        aUsername.Set(RegistrarUsername()); 
+        
+        if (aUsername.Length() == 0)
+            {
+            // To be backwards compatible, 
+            // check also proxy settings if registrar settings not found
+            aUsername.Set(
+                iProfile->ServerParameter(KSIPOutboundProxy,KSIPDigestUserName));
+            aPassword.Set(
+                iProfile->ServerParameter(KSIPOutboundProxy,KSIPDigestPassword));
+            }
+        else
+            {
+            aPassword.Set(
+                iProfile->ServerParameter(KSIPRegistrar,KSIPDigestPassword));
+            }        
+        }
+    return (aUsername.Length() && aPassword.Length());
+    }
+ 
+ // -----------------------------------------------------------------------------
+// CSIPProfileContextBase::GetProxyCredentials
+// -----------------------------------------------------------------------------
+//
+TBool CSIPProfileContextBase::GetProxyCredentials(
+    TPtrC8& aProxyHost,
+    TPtrC8& aUsername,
+    TPtrC8& aPassword) const
+    {
+    aProxyHost.Set(KNullDesC8);
+    aUsername.Set(KNullDesC8);
+    aPassword.Set(KNullDesC8);
+    if (iProfile)
+        {
+        aProxyHost.Set(ExtractProxyHost());
+                
+        aUsername.Set(
+            iProfile->ServerParameter(KSIPOutboundProxy,KSIPDigestUserName));
+    
+        if (aUsername.Length() == 0)
+            {
+            // To be backwards compatible, 
+            // check also registrar settings if proxy settings not found
+            aUsername.Set(RegistrarUsername());          
+            aPassword.Set(
+                iProfile->ServerParameter(KSIPRegistrar,KSIPDigestPassword));
+            }
+        else
+            {
+            aPassword.Set(
+                iProfile->ServerParameter(KSIPOutboundProxy,KSIPDigestPassword));
+            }
+        }
+    return (aProxyHost.Length() && aUsername.Length() && aPassword.Length());
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPProfileContextBase::ExtractProxyHost
+// -----------------------------------------------------------------------------
+//    
+TPtrC8 CSIPProfileContextBase::ExtractProxyHost() const
+    {
+    TPtrC8 proxyHost(KNullDesC8);
+    if (iProfile)
+        {
+        TPtrC8 proxy(iProfile->Server(KSIPOutboundProxy));
+        if (proxy.Length() > 0)
+            {
+            TUriParser8 parser;
+            // If parsing fails, proxyHost will be left empty.
+            // The empty value can be considered as a failure situation
+            // in the calling function and handled there.
+            parser.Parse(proxy);
+            if (parser.Extract(EUriHost).Compare(KDynamicProxy) == 0)
+                {
+                parser.Parse(iProfile->DynamicProxy());
+                }
+            proxyHost.Set(parser.Extract(EUriHost));
+            }
+        }
+    return proxyHost; 
+    }