--- /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;
+ }