--- 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 <comms-infras/ss_log.h>
-#include <comms-infras/coretiermanagerstates.h>
-#include <comms-infras/coretiermanageractivities.h>
-#include <pcktcs.h>
-
-#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<CPdpMetaConnectionProvider*>(aContentionRequest.iMcpr);
-
- pdpMcpr->ContentionResolved(aContentionRequest.iPendingCprId, aResult);
- }
-
-void CPdpContentionManager::ContentionOccured(ESock::CMetaConnectionProviderBase& aMcpr)
- {
- CPdpMetaConnectionProvider& pdpMcpr = static_cast<CPdpMetaConnectionProvider&>(aMcpr);
-
- pdpMcpr.ContentionOccured();
- }
-
-void CPdpContentionManager::ReportContentionAvailabilityStatus(ESock::CMetaConnectionProviderBase& aMcpr, const ESock::TAvailabilityStatus& aStatus) const
- {
- CPdpMetaConnectionProvider& pdpMcpr = static_cast<CPdpMetaConnectionProvider&>(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<CPdpContentionManager*>(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<TEBase::TCancel>())
- {
- 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>())
- {
- TCFTierStatusProvider::TTierNotificationRegistration* msgTNR = message_cast<TCFTierStatusProvider::TTierNotificationRegistration>(&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<CPDPTierManager> 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 <comms-infras/ss_log.h>
+#include <comms-infras/coretiermanagerstates.h>
+#include <comms-infras/coretiermanageractivities.h>
+#include <pcktcs.h>
+
+#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<CPdpMetaConnectionProvider*>(aContentionRequest.iMcpr);
+
+ pdpMcpr->ContentionResolved(aContentionRequest.iPendingCprId, aResult);
+ }
+
+void CPdpContentionManager::ContentionOccured(ESock::CMetaConnectionProviderBase& aMcpr)
+ {
+ CPdpMetaConnectionProvider& pdpMcpr = static_cast<CPdpMetaConnectionProvider&>(aMcpr);
+
+ pdpMcpr.ContentionOccured();
+ }
+
+void CPdpContentionManager::ReportContentionAvailabilityStatus(ESock::CMetaConnectionProviderBase& aMcpr, const ESock::TAvailabilityStatus& aStatus) const
+ {
+ CPdpMetaConnectionProvider& pdpMcpr = static_cast<CPdpMetaConnectionProvider&>(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<CPdpContentionManager*>(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<TEBase::TCancel>())
+ {
+ 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>())
+ {
+ TCFTierStatusProvider::TTierNotificationRegistration* msgTNR = message_cast<TCFTierStatusProvider::TTierNotificationRegistration>(&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<CPDPTierManager> 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);
+ }
+
+