diff -r 6b1d113cdff3 -r 6638e7f4bd8f telephonyprotocols/pdplayer/src/pdptiermanager.cpp --- a/telephonyprotocols/pdplayer/src/pdptiermanager.cpp Mon May 03 13:37:20 2010 +0300 +++ b/telephonyprotocols/pdplayer/src/pdptiermanager.cpp Thu May 06 15:10:38 2010 +0100 @@ -1,536 +1,536 @@ -// Copyright (c) 2008-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: -// - -/** - @file - @internalComponent -*/ - -#include "pdptiermanager.h" -#include "mbmsengine.h" -#include "pdptiermanagerselector.h" -#include -#include -#include -#include - -#include "pdpmcpr.h" - -#ifdef SYMBIAN_TRACE_ENABLE -#define KPDPTierMgrTag KESockMetaConnectionTag -_LIT8(KPDPTierMgrSubTag, "pdptiermgr"); -#endif - -using namespace Messages; -using namespace MeshMachine; -using namespace ESock; -using namespace ConnectionServ; -using namespace NetStateMachine; -using namespace CommsDat; - -namespace PDPTierManagerActivities -{ -DECLARE_DEFINE_ACTIVITY_MAP(stateMap) -ACTIVITY_MAP_END_BASE(TMActivities, coreTMActivities) -} - - -CContextTypeChecker::CContextTypeChecker(RPacketService& aPacketService, MContextEventsObserver& aCallback):CActive(EPriorityStandard), - iPacketService(aPacketService), iCallback(aCallback) - { - CActiveScheduler::Add(this); - } - -CContextTypeChecker::~CContextTypeChecker() - { - iContextName = NULL; - } - -void CContextTypeChecker::Start(const TName* aContextName) - { - iContextName = aContextName; - iPacketService.EnumerateContextsInNif(iStatus, *iContextName, iCountInNif); - SetActive(); - } - -void CContextTypeChecker::RunL() - { - User::LeaveIfError(iStatus.Int()); - if (iCountInNif == 1) // This is a primary context - { - iCallback.PrimaryContextAddedL(iContextName); - } - else - { - iCallback.SecondaryContextAdded(iContextName); - } - } - -void CContextTypeChecker::DoCancel() - { - iPacketService.CancelAsyncRequest(EPacketEnumerateContextsInNif); - } - -TInt CContextTypeChecker::RunError(TInt aError) - { - // Report an error - iCallback.ContextTypeCheckingError(iContextName, aError); - return KErrNone; // Make ActiveScheduler happy - } - -CPrimaryContextsMonitor::CPrimaryContextsMonitor(RPacketService& aPacketService, MContentionObserver& aCallback) : CActive(EPriorityStandard), - iPacketService(aPacketService), iCallback(aCallback) - { - CActiveScheduler::Add(this); - } - -CPrimaryContextsMonitor::~CPrimaryContextsMonitor() - { - Cancel(); - iContextMonitors.ResetAndDestroy(); - delete iContextTypeChecker; - iAddedContextsNames.ResetAndDestroy(); - } - -void CPrimaryContextsMonitor::StartL() - { - iContextTypeChecker = new(ELeave) CContextTypeChecker(iPacketService, *this); - iState = EEnumeratingContexts; - iPacketService.EnumerateNifs(iStatus, iInitialNifsCount); - SetActive(); - } - -void CPrimaryContextsMonitor::PrimaryContextAddedL(const TName* aContextName) - { - // Create new status monitor for this context - StartContextStatusMonitoringL(*aContextName); - RemoveContextNameAndCheckNext(aContextName); - } - -void CPrimaryContextsMonitor::SecondaryContextAdded(const TName* aContextName) - { - // This is not a primary context, just delete its name. - RemoveContextNameAndCheckNext(aContextName); - } - -void CPrimaryContextsMonitor::RemoveContextNameAndCheckNext(const TName* aContextName) - { - TInt nameIndex = iAddedContextsNames.Find(aContextName); - __ASSERT_DEBUG(nameIndex != KErrNotFound, User::Invariant()); - delete iAddedContextsNames[nameIndex]; - iAddedContextsNames.Remove(nameIndex); - - if (iAddedContextsNames.Count() > 1) - // Should be more than one here, coz we are waiting for new context added all the time, - // so the last one item is always empty. - { - iContextTypeChecker->Start(iAddedContextsNames[0]); - } - } - -void CPrimaryContextsMonitor::PrimaryContextDeleted(const CContextStatusMonitor* aContextStatusMonitor) - { - if (aContextStatusMonitor->IsPassedThroughActiveState()) - { - iCallback.ContentionResolved(); - } - DeleteContextStatusMonitor(aContextStatusMonitor); - } - -void CPrimaryContextsMonitor::ContextTypeCheckingError(const TName* aContextName, TInt aError) - { - RemoveContextNameAndCheckNext(aContextName); - ProcessError(aError); - } - - -void CPrimaryContextsMonitor::ContextMonitoringError(const CContextStatusMonitor* aContextStatusMonitor, TInt aError) - { - DeleteContextStatusMonitor(aContextStatusMonitor); - ProcessError(aError); - } - -void CPrimaryContextsMonitor::DeleteContextStatusMonitor(const CContextStatusMonitor* aContextStatusMonitor) - { - TInt monitorIndex = iContextMonitors.Find(aContextStatusMonitor); - __ASSERT_DEBUG(monitorIndex != KErrNotFound, User::Invariant()); - delete iContextMonitors[monitorIndex]; - iContextMonitors.Remove(monitorIndex); - } - -void CPrimaryContextsMonitor::ProcessError( - #ifdef _DEBUG - TInt aError - #else //remove compilation warning in release builds - TInt /*aError*/ - #endif - ) - { - __ASSERT_DEBUG(aError != KErrNone, User::Invariant()); - __FLOG_STATIC1(KPDPTierMgrTag, KPDPTierMgrSubTag, _L("PDP context monitoring error: %d"), aError); - } - -void CPrimaryContextsMonitor::RunL() - { - User::LeaveIfError(iStatus.Int()); - SwitchStateL(); - RPacketService::TNifInfoV2Pckg nifInfoV2Pckg(iCurrentNifInfo); - switch(iState) - { - case EGettingInfo: - StartContextStatusMonitoringL(iCurrentNifInfo.iContextName); - iPacketService.GetNifInfo(iStatus, iCurrentNifIndex, nifInfoV2Pckg); - ++iCurrentNifIndex; - SetActive(); - break; - case EListening: - // All functions in RPacketService and RPacketContext, - // that can be used to check if context is primary, are asynchronous. - // We could not call them here, coz can miss some events from NotifyContextAdded - // So subscribe to NotifyContextAdded as soon as possible and check context - // type using CContextTypeChecker active object - TName *contextName = new (ELeave) TName; - CleanupStack::PushL(contextName); - iAddedContextsNames.AppendL(contextName); - CleanupStack::Pop(contextName); - // subscribe to NotifyContextAdded - iPacketService.NotifyContextAdded(iStatus, *contextName); - SetActive(); - // if there are any items in iAddedContextsNames except that one that has been added above, i.e count > 1 - // starting asynchronous context type checking - if (!iContextTypeChecker->IsActive() && iAddedContextsNames.Count()>1) - { - iContextTypeChecker->Start(iAddedContextsNames[0]); - } - break; - } - } -void CPrimaryContextsMonitor::DoCancel() - { - switch(iState) - { - case EEnumeratingContexts: - iPacketService.CancelAsyncRequest(EPacketEnumerateNifs); - break; - case EGettingInfo: - iPacketService.CancelAsyncRequest(EPacketGetNifInfo); - break; - case EListening: - iPacketService.CancelAsyncRequest(EPacketNotifyContextAdded); - break; - } - - } - -TInt CPrimaryContextsMonitor::RunError(TInt aError) - { - // Process an error - ProcessError(aError); - return KErrNone; // Make ActiveScheduler happy - } - - -void CPrimaryContextsMonitor::SwitchStateL() - { - if (iState == EEnumeratingContexts) - { - if (iInitialNifsCount > 0) - { - iState = EGettingInfo; - } - else - { - iState = EListening; - } - } - else if (iState == EGettingInfo && iCurrentNifIndex == iInitialNifsCount) - { - StartContextStatusMonitoringL(iCurrentNifInfo.iContextName); - iState = EListening; - } - } - -void CPrimaryContextsMonitor::StartContextStatusMonitoringL(const TName& aContextName) - { - CContextStatusMonitor* newStatusMonitor = new (ELeave) CContextStatusMonitor(iPacketService, *this); - CleanupStack::PushL(newStatusMonitor); - iContextMonitors.AppendL(newStatusMonitor); - CleanupStack::Pop(newStatusMonitor); - newStatusMonitor->StartL(aContextName); - } - -CContextStatusMonitor::CContextStatusMonitor(RPacketService& aPacketService, MContextEventsObserver& aCallback):CActive(EPriorityStandard), - iPacketService(aPacketService), iCallback(aCallback) - { - CActiveScheduler::Add(this); - } - -CContextStatusMonitor::~CContextStatusMonitor() - { - Cancel(); - iPacketContext.Close(); - } - -TBool CContextStatusMonitor::StartL(const TName& aContextName) - { - iContextName.Copy(aContextName); - User::LeaveIfError(iPacketContext.OpenExistingContext(iPacketService, iContextName)); - User::LeaveIfError(iPacketContext.GetStatus(iContextStatus)); - - if (iContextStatus == RPacketContext::EStatusDeleted) - { - return EFalse; - } - - if (iContextStatus == RPacketContext::EStatusActive || - iContextStatus == RPacketContext::EStatusSuspended || - iContextStatus == RPacketContext::EStatusDeactivating) - { - iWasActive = ETrue; - } - - iPacketContext.NotifyStatusChange(iStatus, iContextStatus); - SetActive(); - return ETrue; - } - -void CContextStatusMonitor::RunL() - { - User::LeaveIfError(iStatus.Int()); - if (iContextStatus == RPacketContext::EStatusActive) - { - iWasActive = ETrue; - } - - if (iContextStatus == RPacketContext::EStatusDeleted) - { - iPacketContext.CancelAsyncRequest(EPacketContextNotifyStatusChange); - iCallback.PrimaryContextDeleted(this); - } - else - { - iPacketContext.NotifyStatusChange(iStatus, iContextStatus); - SetActive(); - } - } - -void CContextStatusMonitor::DoCancel() - { - iPacketContext.CancelAsyncRequest(EPacketContextNotifyStatusChange); - } - -TInt CContextStatusMonitor::RunError(TInt aError) - { - iCallback.ContextMonitoringError(this, aError); - return KErrNone; - } - -CPdpContentionManager* CPdpContentionManager::NewL(const ESock::CTierManagerBase& aTierManager, RPacketService& aPacketService) - { - CPdpContentionManager* self = new (ELeave) CPdpContentionManager(aTierManager); - CleanupStack::PushL(self); - self->ConstructL(aPacketService); - CleanupStack::Pop(self); - return self; - } - -CPdpContentionManager::CPdpContentionManager(const ESock::CTierManagerBase& aTierManager): -CContentionManager(aTierManager) - { - } - -CPdpContentionManager::~CPdpContentionManager() - { - delete iPrimaryContextsMonitor; - } - -void CPdpContentionManager::ConstructL(RPacketService& aPacketService) - { - iPrimaryContextsMonitor = new (ELeave) CPrimaryContextsMonitor(aPacketService, *this); - } - -void CPdpContentionManager::StartMonitoringL() - { - if (iPrimaryContextsMonitor) - { - iPrimaryContextsMonitor->StartL(); - } - } - -void CPdpContentionManager::ContentionResolved(const TContentionRequestItem& aContentionRequest, TBool aResult) - { - CPdpMetaConnectionProvider* pdpMcpr = static_cast(aContentionRequest.iMcpr); - - pdpMcpr->ContentionResolved(aContentionRequest.iPendingCprId, aResult); - } - -void CPdpContentionManager::ContentionOccured(ESock::CMetaConnectionProviderBase& aMcpr) - { - CPdpMetaConnectionProvider& pdpMcpr = static_cast(aMcpr); - - pdpMcpr.ContentionOccured(); - } - -void CPdpContentionManager::ReportContentionAvailabilityStatus(ESock::CMetaConnectionProviderBase& aMcpr, const ESock::TAvailabilityStatus& aStatus) const - { - CPdpMetaConnectionProvider& pdpMcpr = static_cast(aMcpr); - - pdpMcpr.ReportContentionAvailabilityStatus(aStatus); - } - -/** -The NewL factory function for PDPTierManager. -This function also acts as the single ECom entry point into this object. -@param aFactory The reference to CTierManagerFactoryBase -@return CPDPTierManager* -*/ -CPDPTierManager* CPDPTierManager::NewL(ESock::CTierManagerFactoryBase& aFactory) - { - CPDPTierManager* self = new(ELeave)CPDPTierManager(aFactory, PDPTierManagerActivities::stateMap::Self()); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - -/** -Constructor for CPDPTierManager -*/ -CPDPTierManager::CPDPTierManager(ESock::CTierManagerFactoryBase& aFactory, - const MeshMachine::TNodeActivityMap& aActivityMap) - :CCoreTierManager(aFactory,aActivityMap) - { - LOG_NODE_CREATE(KPDPTierMgrTag, CPDPTierManager); - } - -/** -Descructor for CPDPTierManager -*/ -CPDPTierManager::~CPDPTierManager() - { - LOG_NODE_DESTROY(KPDPTierMgrTag, CPDPTierManager); - delete iPdpContentionManager; - iPdpContentionManager = NULL; - if (iMBMSEngine) - { - iMBMSEngine->Cancel(); - delete iMBMSEngine; - iMBMSEngine = NULL; - } - } - -/** -Create selector for this Tier. -@return MProviderSelector* -*/ -MProviderSelector* CPDPTierManager::DoCreateProviderSelectorL(const Meta::SMetaData& aSelectionPreferences) - { - __CFLOG_VAR((KPDPTierMgrTag, KPDPTierMgrSubTag, _L8("CPdpTierManager[%08x]::DoSelectProvider()"), this)); - return TPdpSelectorFactory::NewSelectorL(aSelectionPreferences); - } - -/** -ConstructL function of CPDPTierManager. -This function is used to retrieve tsy name. -@return void -*/ -void CPDPTierManager::ConstructL() - { - __CFLOG_VAR((KPDPTierMgrTag, KPDPTierMgrSubTag, _L8("ConstructL::In CPDPTierManager"))); - iMBMSEngine = CMBMSEngine::NewL(NodeId(), *this); - } - -/** - The PacketServiceAttachedCallbackL is a callback function. - It's called by MBMSEngine when RPacketService has been attached. -*/ -void CPDPTierManager::PacketServiceAttachedCallbackL() - { - if (!iPdpContentionManager) - { - iPdpContentionManager = CPdpContentionManager::NewL(*this, iMBMSEngine->GetRPacketService()); - } - static_cast(iPdpContentionManager)->StartMonitoringL(); - } - -/** -The ReceivedL function for PDPTierManager. -The messages from RConnectionServ are received in ReceivedL function. -@param aCFMessage The reference to Messages::TSignatureBase -@return TInt* -*/ -void CPDPTierManager::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) - { - //TODO I think that the generic TCancel handling will do this - so perhaps remove this and CancelAndRemoveFromRequestList! - if (aMessage.IsMessage()) - { - TRAPD(err, iMBMSEngine->CancelAndRemoveFromRequestListL(aSender)); - if (err == KErrNone) - { - aMessage.ClearMessageId(); - } - else if (err != KErrNotFound) - { - User::Leave(err); - } - // err == KErrNotFound - // Probably this is not cancel for MBMS request but cancel for PDP availability notification request - // It will be processed by core TM then. - } - - if (aMessage.IsMessage()) - { - TCFTierStatusProvider::TTierNotificationRegistration* msgTNR = message_cast(&aMessage); - - const Messages::TNodeSignal::TMessageId requestType = TCFTierStatusProvider::TTierNotificationRegistration::Id(); - CRefCountOwnedParameterBundle* requestBundleOwner = msgTNR->iBundle; - - TRAPD(err, iMBMSEngine->AddToRequestListL(FindClient(aSender), aSender, requestType, requestBundleOwner)); - if (err == KErrNone) - { - aMessage.ClearMessageId(); - } - else if (err != KErrArgument) - { - User::Leave(err); - } - // err == KErrArgument - // Probably this is not MBMS notification request but PDP availability notification request - // It will be processed by core TM then. - } - - TNodeContext ctx(*this, aMessage, aSender, aRecipient); - CCoreTierManager::Received(ctx); - User::LeaveIfError(ctx.iReturn); - } - -TBool CPDPTierManager::HandleContentionL(ESock::CMetaConnectionProviderBase* aMcpr, Messages::TNodeId& aPendingCprId, TUint aPriority) - { - User::LeaveIfNull(iMBMSEngine); - if (!iPdpContentionManager) - { - iPdpContentionManager = CPdpContentionManager::NewL(*this, iMBMSEngine->GetRPacketService()); - } - return iPdpContentionManager->HandleContentionL(aMcpr, aPendingCprId, aPriority); - } - -TBool CPDPTierManager::IsUnavailableDueToContention(const ESock::CMetaConnectionProviderBase* aMetaConnectionProvider) const - { - if (!iPdpContentionManager) - return EFalse; - return iPdpContentionManager->IsUnavailableDueToContention(aMetaConnectionProvider); - } - - +// Copyright (c) 2008-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: +// + +/** + @file + @internalComponent +*/ + +#include "pdptiermanager.h" +#include "mbmsengine.h" +#include "pdptiermanagerselector.h" +#include +#include +#include +#include + +#include "pdpmcpr.h" + +#ifdef SYMBIAN_TRACE_ENABLE +#define KPDPTierMgrTag KESockMetaConnectionTag +_LIT8(KPDPTierMgrSubTag, "pdptiermgr"); +#endif + +using namespace Messages; +using namespace MeshMachine; +using namespace ESock; +using namespace ConnectionServ; +using namespace NetStateMachine; +using namespace CommsDat; + +namespace PDPTierManagerActivities +{ +DECLARE_DEFINE_ACTIVITY_MAP(stateMap) +ACTIVITY_MAP_END_BASE(TMActivities, coreTMActivities) +} + + +CContextTypeChecker::CContextTypeChecker(RPacketService& aPacketService, MContextEventsObserver& aCallback):CActive(EPriorityStandard), + iPacketService(aPacketService), iCallback(aCallback) + { + CActiveScheduler::Add(this); + } + +CContextTypeChecker::~CContextTypeChecker() + { + iContextName = NULL; + } + +void CContextTypeChecker::Start(const TName* aContextName) + { + iContextName = aContextName; + iPacketService.EnumerateContextsInNif(iStatus, *iContextName, iCountInNif); + SetActive(); + } + +void CContextTypeChecker::RunL() + { + User::LeaveIfError(iStatus.Int()); + if (iCountInNif == 1) // This is a primary context + { + iCallback.PrimaryContextAddedL(iContextName); + } + else + { + iCallback.SecondaryContextAdded(iContextName); + } + } + +void CContextTypeChecker::DoCancel() + { + iPacketService.CancelAsyncRequest(EPacketEnumerateContextsInNif); + } + +TInt CContextTypeChecker::RunError(TInt aError) + { + // Report an error + iCallback.ContextTypeCheckingError(iContextName, aError); + return KErrNone; // Make ActiveScheduler happy + } + +CPrimaryContextsMonitor::CPrimaryContextsMonitor(RPacketService& aPacketService, MContentionObserver& aCallback) : CActive(EPriorityStandard), + iPacketService(aPacketService), iCallback(aCallback) + { + CActiveScheduler::Add(this); + } + +CPrimaryContextsMonitor::~CPrimaryContextsMonitor() + { + Cancel(); + iContextMonitors.ResetAndDestroy(); + delete iContextTypeChecker; + iAddedContextsNames.ResetAndDestroy(); + } + +void CPrimaryContextsMonitor::StartL() + { + iContextTypeChecker = new(ELeave) CContextTypeChecker(iPacketService, *this); + iState = EEnumeratingContexts; + iPacketService.EnumerateNifs(iStatus, iInitialNifsCount); + SetActive(); + } + +void CPrimaryContextsMonitor::PrimaryContextAddedL(const TName* aContextName) + { + // Create new status monitor for this context + StartContextStatusMonitoringL(*aContextName); + RemoveContextNameAndCheckNext(aContextName); + } + +void CPrimaryContextsMonitor::SecondaryContextAdded(const TName* aContextName) + { + // This is not a primary context, just delete its name. + RemoveContextNameAndCheckNext(aContextName); + } + +void CPrimaryContextsMonitor::RemoveContextNameAndCheckNext(const TName* aContextName) + { + TInt nameIndex = iAddedContextsNames.Find(aContextName); + __ASSERT_DEBUG(nameIndex != KErrNotFound, User::Invariant()); + delete iAddedContextsNames[nameIndex]; + iAddedContextsNames.Remove(nameIndex); + + if (iAddedContextsNames.Count() > 1) + // Should be more than one here, coz we are waiting for new context added all the time, + // so the last one item is always empty. + { + iContextTypeChecker->Start(iAddedContextsNames[0]); + } + } + +void CPrimaryContextsMonitor::PrimaryContextDeleted(const CContextStatusMonitor* aContextStatusMonitor) + { + if (aContextStatusMonitor->IsPassedThroughActiveState()) + { + iCallback.ContentionResolved(); + } + DeleteContextStatusMonitor(aContextStatusMonitor); + } + +void CPrimaryContextsMonitor::ContextTypeCheckingError(const TName* aContextName, TInt aError) + { + RemoveContextNameAndCheckNext(aContextName); + ProcessError(aError); + } + + +void CPrimaryContextsMonitor::ContextMonitoringError(const CContextStatusMonitor* aContextStatusMonitor, TInt aError) + { + DeleteContextStatusMonitor(aContextStatusMonitor); + ProcessError(aError); + } + +void CPrimaryContextsMonitor::DeleteContextStatusMonitor(const CContextStatusMonitor* aContextStatusMonitor) + { + TInt monitorIndex = iContextMonitors.Find(aContextStatusMonitor); + __ASSERT_DEBUG(monitorIndex != KErrNotFound, User::Invariant()); + delete iContextMonitors[monitorIndex]; + iContextMonitors.Remove(monitorIndex); + } + +void CPrimaryContextsMonitor::ProcessError( + #ifdef _DEBUG + TInt aError + #else //remove compilation warning in release builds + TInt /*aError*/ + #endif + ) + { + __ASSERT_DEBUG(aError != KErrNone, User::Invariant()); + __FLOG_STATIC1(KPDPTierMgrTag, KPDPTierMgrSubTag, _L("PDP context monitoring error: %d"), aError); + } + +void CPrimaryContextsMonitor::RunL() + { + User::LeaveIfError(iStatus.Int()); + SwitchStateL(); + RPacketService::TNifInfoV2Pckg nifInfoV2Pckg(iCurrentNifInfo); + switch(iState) + { + case EGettingInfo: + StartContextStatusMonitoringL(iCurrentNifInfo.iContextName); + iPacketService.GetNifInfo(iStatus, iCurrentNifIndex, nifInfoV2Pckg); + ++iCurrentNifIndex; + SetActive(); + break; + case EListening: + // All functions in RPacketService and RPacketContext, + // that can be used to check if context is primary, are asynchronous. + // We could not call them here, coz can miss some events from NotifyContextAdded + // So subscribe to NotifyContextAdded as soon as possible and check context + // type using CContextTypeChecker active object + TName *contextName = new (ELeave) TName; + CleanupStack::PushL(contextName); + iAddedContextsNames.AppendL(contextName); + CleanupStack::Pop(contextName); + // subscribe to NotifyContextAdded + iPacketService.NotifyContextAdded(iStatus, *contextName); + SetActive(); + // if there are any items in iAddedContextsNames except that one that has been added above, i.e count > 1 + // starting asynchronous context type checking + if (!iContextTypeChecker->IsActive() && iAddedContextsNames.Count()>1) + { + iContextTypeChecker->Start(iAddedContextsNames[0]); + } + break; + } + } +void CPrimaryContextsMonitor::DoCancel() + { + switch(iState) + { + case EEnumeratingContexts: + iPacketService.CancelAsyncRequest(EPacketEnumerateNifs); + break; + case EGettingInfo: + iPacketService.CancelAsyncRequest(EPacketGetNifInfo); + break; + case EListening: + iPacketService.CancelAsyncRequest(EPacketNotifyContextAdded); + break; + } + + } + +TInt CPrimaryContextsMonitor::RunError(TInt aError) + { + // Process an error + ProcessError(aError); + return KErrNone; // Make ActiveScheduler happy + } + + +void CPrimaryContextsMonitor::SwitchStateL() + { + if (iState == EEnumeratingContexts) + { + if (iInitialNifsCount > 0) + { + iState = EGettingInfo; + } + else + { + iState = EListening; + } + } + else if (iState == EGettingInfo && iCurrentNifIndex == iInitialNifsCount) + { + StartContextStatusMonitoringL(iCurrentNifInfo.iContextName); + iState = EListening; + } + } + +void CPrimaryContextsMonitor::StartContextStatusMonitoringL(const TName& aContextName) + { + CContextStatusMonitor* newStatusMonitor = new (ELeave) CContextStatusMonitor(iPacketService, *this); + CleanupStack::PushL(newStatusMonitor); + iContextMonitors.AppendL(newStatusMonitor); + CleanupStack::Pop(newStatusMonitor); + newStatusMonitor->StartL(aContextName); + } + +CContextStatusMonitor::CContextStatusMonitor(RPacketService& aPacketService, MContextEventsObserver& aCallback):CActive(EPriorityStandard), + iPacketService(aPacketService), iCallback(aCallback) + { + CActiveScheduler::Add(this); + } + +CContextStatusMonitor::~CContextStatusMonitor() + { + Cancel(); + iPacketContext.Close(); + } + +TBool CContextStatusMonitor::StartL(const TName& aContextName) + { + iContextName.Copy(aContextName); + User::LeaveIfError(iPacketContext.OpenExistingContext(iPacketService, iContextName)); + User::LeaveIfError(iPacketContext.GetStatus(iContextStatus)); + + if (iContextStatus == RPacketContext::EStatusDeleted) + { + return EFalse; + } + + if (iContextStatus == RPacketContext::EStatusActive || + iContextStatus == RPacketContext::EStatusSuspended || + iContextStatus == RPacketContext::EStatusDeactivating) + { + iWasActive = ETrue; + } + + iPacketContext.NotifyStatusChange(iStatus, iContextStatus); + SetActive(); + return ETrue; + } + +void CContextStatusMonitor::RunL() + { + User::LeaveIfError(iStatus.Int()); + if (iContextStatus == RPacketContext::EStatusActive) + { + iWasActive = ETrue; + } + + if (iContextStatus == RPacketContext::EStatusDeleted) + { + iPacketContext.CancelAsyncRequest(EPacketContextNotifyStatusChange); + iCallback.PrimaryContextDeleted(this); + } + else + { + iPacketContext.NotifyStatusChange(iStatus, iContextStatus); + SetActive(); + } + } + +void CContextStatusMonitor::DoCancel() + { + iPacketContext.CancelAsyncRequest(EPacketContextNotifyStatusChange); + } + +TInt CContextStatusMonitor::RunError(TInt aError) + { + iCallback.ContextMonitoringError(this, aError); + return KErrNone; + } + +CPdpContentionManager* CPdpContentionManager::NewL(const ESock::CTierManagerBase& aTierManager, RPacketService& aPacketService) + { + CPdpContentionManager* self = new (ELeave) CPdpContentionManager(aTierManager); + CleanupStack::PushL(self); + self->ConstructL(aPacketService); + CleanupStack::Pop(self); + return self; + } + +CPdpContentionManager::CPdpContentionManager(const ESock::CTierManagerBase& aTierManager): +CContentionManager(aTierManager) + { + } + +CPdpContentionManager::~CPdpContentionManager() + { + delete iPrimaryContextsMonitor; + } + +void CPdpContentionManager::ConstructL(RPacketService& aPacketService) + { + iPrimaryContextsMonitor = new (ELeave) CPrimaryContextsMonitor(aPacketService, *this); + } + +void CPdpContentionManager::StartMonitoringL() + { + if (iPrimaryContextsMonitor) + { + iPrimaryContextsMonitor->StartL(); + } + } + +void CPdpContentionManager::ContentionResolved(const TContentionRequestItem& aContentionRequest, TBool aResult) + { + CPdpMetaConnectionProvider* pdpMcpr = static_cast(aContentionRequest.iMcpr); + + pdpMcpr->ContentionResolved(aContentionRequest.iPendingCprId, aResult); + } + +void CPdpContentionManager::ContentionOccured(ESock::CMetaConnectionProviderBase& aMcpr) + { + CPdpMetaConnectionProvider& pdpMcpr = static_cast(aMcpr); + + pdpMcpr.ContentionOccured(); + } + +void CPdpContentionManager::ReportContentionAvailabilityStatus(ESock::CMetaConnectionProviderBase& aMcpr, const ESock::TAvailabilityStatus& aStatus) const + { + CPdpMetaConnectionProvider& pdpMcpr = static_cast(aMcpr); + + pdpMcpr.ReportContentionAvailabilityStatus(aStatus); + } + +/** +The NewL factory function for PDPTierManager. +This function also acts as the single ECom entry point into this object. +@param aFactory The reference to CTierManagerFactoryBase +@return CPDPTierManager* +*/ +CPDPTierManager* CPDPTierManager::NewL(ESock::CTierManagerFactoryBase& aFactory) + { + CPDPTierManager* self = new(ELeave)CPDPTierManager(aFactory, PDPTierManagerActivities::stateMap::Self()); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +Constructor for CPDPTierManager +*/ +CPDPTierManager::CPDPTierManager(ESock::CTierManagerFactoryBase& aFactory, + const MeshMachine::TNodeActivityMap& aActivityMap) + :CCoreTierManager(aFactory,aActivityMap) + { + LOG_NODE_CREATE(KPDPTierMgrTag, CPDPTierManager); + } + +/** +Descructor for CPDPTierManager +*/ +CPDPTierManager::~CPDPTierManager() + { + LOG_NODE_DESTROY(KPDPTierMgrTag, CPDPTierManager); + delete iPdpContentionManager; + iPdpContentionManager = NULL; + if (iMBMSEngine) + { + iMBMSEngine->Cancel(); + delete iMBMSEngine; + iMBMSEngine = NULL; + } + } + +/** +Create selector for this Tier. +@return MProviderSelector* +*/ +MProviderSelector* CPDPTierManager::DoCreateProviderSelectorL(const Meta::SMetaData& aSelectionPreferences) + { + __CFLOG_VAR((KPDPTierMgrTag, KPDPTierMgrSubTag, _L8("CPdpTierManager[%08x]::DoSelectProvider()"), this)); + return TPdpSelectorFactory::NewSelectorL(aSelectionPreferences); + } + +/** +ConstructL function of CPDPTierManager. +This function is used to retrieve tsy name. +@return void +*/ +void CPDPTierManager::ConstructL() + { + __CFLOG_VAR((KPDPTierMgrTag, KPDPTierMgrSubTag, _L8("ConstructL::In CPDPTierManager"))); + iMBMSEngine = CMBMSEngine::NewL(NodeId(), *this); + } + +/** + The PacketServiceAttachedCallbackL is a callback function. + It's called by MBMSEngine when RPacketService has been attached. +*/ +void CPDPTierManager::PacketServiceAttachedCallbackL() + { + if (!iPdpContentionManager) + { + iPdpContentionManager = CPdpContentionManager::NewL(*this, iMBMSEngine->GetRPacketService()); + } + static_cast(iPdpContentionManager)->StartMonitoringL(); + } + +/** +The ReceivedL function for PDPTierManager. +The messages from RConnectionServ are received in ReceivedL function. +@param aCFMessage The reference to Messages::TSignatureBase +@return TInt* +*/ +void CPDPTierManager::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) + { + //TODO I think that the generic TCancel handling will do this - so perhaps remove this and CancelAndRemoveFromRequestList! + if (aMessage.IsMessage()) + { + TRAPD(err, iMBMSEngine->CancelAndRemoveFromRequestListL(aSender)); + if (err == KErrNone) + { + aMessage.ClearMessageId(); + } + else if (err != KErrNotFound) + { + User::Leave(err); + } + // err == KErrNotFound + // Probably this is not cancel for MBMS request but cancel for PDP availability notification request + // It will be processed by core TM then. + } + + if (aMessage.IsMessage()) + { + TCFTierStatusProvider::TTierNotificationRegistration* msgTNR = message_cast(&aMessage); + + const Messages::TNodeSignal::TMessageId requestType = TCFTierStatusProvider::TTierNotificationRegistration::Id(); + CRefCountOwnedParameterBundle* requestBundleOwner = msgTNR->iBundle; + + TRAPD(err, iMBMSEngine->AddToRequestListL(FindClient(aSender), aSender, requestType, requestBundleOwner)); + if (err == KErrNone) + { + aMessage.ClearMessageId(); + } + else if (err != KErrArgument) + { + User::Leave(err); + } + // err == KErrArgument + // Probably this is not MBMS notification request but PDP availability notification request + // It will be processed by core TM then. + } + + TNodeContext ctx(*this, aMessage, aSender, aRecipient); + CCoreTierManager::Received(ctx); + User::LeaveIfError(ctx.iReturn); + } + +TBool CPDPTierManager::HandleContentionL(ESock::CMetaConnectionProviderBase* aMcpr, Messages::TNodeId& aPendingCprId, TUint aPriority) + { + User::LeaveIfNull(iMBMSEngine); + if (!iPdpContentionManager) + { + iPdpContentionManager = CPdpContentionManager::NewL(*this, iMBMSEngine->GetRPacketService()); + } + return iPdpContentionManager->HandleContentionL(aMcpr, aPendingCprId, aPriority); + } + +TBool CPDPTierManager::IsUnavailableDueToContention(const ESock::CMetaConnectionProviderBase* aMetaConnectionProvider) const + { + if (!iPdpContentionManager) + return EFalse; + return iPdpContentionManager->IsUnavailableDueToContention(aMetaConnectionProvider); + } + +