diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/ProfileAgent/Server/Src/sipalrmigrationcontroller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/sipalrmigrationcontroller.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,437 @@ +// 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: +// Name : sipalrmigrationcontroller.cpp +// Part of : SIP / SIP Profile Server +// Version : SIP/6.0 +// + + + +#include "sipalrmigrationcontroller.h" +#include "sipalrmonitor.h" +#include "sipalrmigrationobserver.h" +#include "sipalrmigrationobserverinfo.h" +#include "SipProfileLog.h" + + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::NewLC +// ----------------------------------------------------------------------------- +// +CSipAlrMigrationController* +CSipAlrMigrationController::NewLC(CSipAlrMonitor& aAlrMonitor, TUint32 aSnapId) + { + CSipAlrMigrationController* self = + new (ELeave) CSipAlrMigrationController(aAlrMonitor, aSnapId); + CleanupStack::PushL(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::CSipAlrMigrationController +// ----------------------------------------------------------------------------- +// +CSipAlrMigrationController::CSipAlrMigrationController( + CSipAlrMonitor& aAlrMonitor, + TUint32 aSnapId) : + iAlrMonitor(aAlrMonitor), + iSnapId(aSnapId) +#ifdef CPPUNIT_TEST + // Set the array granularity to 1, so it allocates memory in each append + , iObservers(1) +#endif + { + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::~CSipAlrMigrationController +// ----------------------------------------------------------------------------- +// +CSipAlrMigrationController::~CSipAlrMigrationController() + { + PROFILE_DEBUG1("~CSipAlrMigrCtrl") + + iAlrMonitor.FreeResources(*this); + iObservers.Close(); + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::AlrEvent +// If migration is disallowed, the original IAP id is offered again. +// ----------------------------------------------------------------------------- +// +void CSipAlrMigrationController::AlrEvent(MSipAlrObserver::TEvent aEvent, + TUint32 aSnapId, + TUint32 aIapId) + { + PROFILE_DEBUG3("CSipAlrMigrationController::AlrEvent", (TInt)(aEvent)) + + switch (aEvent) + { + case MSipAlrObserver::EIapAvailable: + if (aIapId == iAllowedIapId) + { + // Pass the failed IAP to observer, not the original IAP. + SendMigrationResult(iOfferedIapId, EFalse); + } + else + { + IapAvailable(aSnapId, aIapId); + } + break; + + case MSipAlrObserver::EIapActive: + iAllowedIapId = aIapId; + SendMigrationResult(aIapId, ETrue); + break; + + case MSipAlrObserver::ENoNewIapAvailable: + NoNewIapAvailable(); + break; + + case MSipAlrObserver::ERefreshError: + // Start from the end, as RefreshIAPsFailed() causes entries to + // remove themselves from the array. + for (TInt i = iObservers.Count() - 1; i >= 0; --i) + { + iObservers[i].iObserver.RefreshIAPsFailed(); + } + break; + + case MSipAlrObserver::EOfferedIapRejected: + OfferedIapRejected(); + break; + + + default: + User::Panic(_L("ALRMigrationCtrl::AlrEvent"), KErrArgument); + } + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::SnapId +// ----------------------------------------------------------------------------- +// +TUint32 CSipAlrMigrationController::SnapId() const + { + return iSnapId; + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::IsUsed +// ----------------------------------------------------------------------------- +// +TBool CSipAlrMigrationController::IsUsed() const + { + return iObservers.Count() > 0; + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::AttachProfileL +// Initiate monitoring only after first observer exists. Otherwise IAP +// available event could not be forwarded to observer. +// ----------------------------------------------------------------------------- +// +TUint32 +CSipAlrMigrationController::AttachProfileL(MSipAlrMigrationObserver& aObserver) + { + TSipAlrMigrationObserverInfo observerInfo(aObserver); + iObservers.AppendL(observerInfo); + + const TInt KFirstObserverExists = 1; + if (iObservers.Count() == KFirstObserverExists) + { + PROFILE_DEBUG3("CSipAlrMigrCtrl::AttachProfileL snapId", iSnapId) + iAlrMonitor.MonitorSnapL(iSnapId, *this); + return KNoIap; + } + + return iAllowedIapId; + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::DetachProfile +// This is typically called from destructors, so don't leave. +// ----------------------------------------------------------------------------- +// +void +CSipAlrMigrationController::DetachProfile(MSipAlrMigrationObserver& aObserver) + { + TInt index = FindIndex(aObserver); + if (index != KErrNotFound) + { + iObservers.Remove(index); + } + + if (iObservers.Count() == 0) + { + PROFILE_DEBUG1("CSipAlrMigrCtrl::DetachProfile free resources") + + iAlrMonitor.FreeResources(*this); + ResetFlags(); + } + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::IapAvailable +// Set all observers "waiting", before using IapAvailable. Even if the first +// observer syncronously uses SetMigrationPermission, ObserversWaitingPermission +// returns correct value. +// If an IAP comes available before each observer has (dis)allowed a previous +// IAP, pass the new IAP to observers and forget the older IAP. +// ----------------------------------------------------------------------------- +// +void +CSipAlrMigrationController::IapAvailable(TUint32 aSnapId, TUint32 aIapId) + { + PROFILE_DEBUG4("CSipAlrMigrCtrl::IapAvailable snap,iap", aSnapId, aIapId) + + iOfferedIapId = aIapId; + iMigrationDisallowed = EFalse; + iRefreshIssued = EFalse; + + for (TInt i = 0; i < iObservers.Count(); ++i) + { + iObservers[i].iIsWaitingForPermission = ETrue; + iObservers[i].iIsWaitingForAcceptance = ETrue; + } + + for (TInt i = 0; i < iObservers.Count(); ++i) + { + iObservers[i].iObserver.IapAvailable(aSnapId, aIapId); + } + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::SetMigrationPermission +// Handle only the latest IAP. If IAP==EMostRecentIap don't care if the observer +// has already used SetMigrationPermission. Otherwise do nothing if observer is +// not waiting, as it has already automatically called SetMigrationPermission. +// ----------------------------------------------------------------------------- +// +void CSipAlrMigrationController::SetMigrationPermission( + MSipAlrMigrationObserver& aObserver, + TBool aAllow, + TUint32 aIapId) + { + PROFILE_DEBUG5("CSipAlrMigrCtrl::SetMigrPermission iap,allow,offeredIap", + aIapId, + aAllow, + iOfferedIapId) + + TInt index = FindIndex(aObserver); + // If no pending observers, result has been forwarded. Don't do it twice. + if (ObserversWaitingPermission() && + index != KErrNotFound && + ((aIapId == EMostRecentIap) || + (aIapId == iOfferedIapId && + iObservers[index].iIsWaitingForPermission))) + { + iObservers[index].iIsWaitingForPermission = EFalse; + if (!aAllow) + { + iMigrationDisallowed = ETrue; + } + + if (!ObserversWaitingPermission()) + { + PROFILE_DEBUG3("CSipAlrMigrCtrl::SetMigrPermission, allow=", + !iMigrationDisallowed) + TInt err(KErrNone); + if (iMigrationDisallowed) + { + err = iAlrMonitor.DisallowMigration(iSnapId); + } + else + { + err = iAlrMonitor.AllowMigration(iSnapId); + } + if (err != KErrNone) + { + for (TInt i = 0; i < iObservers.Count(); ++i) + { + iObservers[i].iObserver.ErrorOccurred(err); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::RefreshIapAvailabilityL +// ----------------------------------------------------------------------------- +// +void CSipAlrMigrationController::RefreshIapAvailabilityL(TUint32 aSnapId) + { + if (!iRefreshIssued && aSnapId == iSnapId) + { + iAlrMonitor.RefreshIapAvailabilityL(aSnapId); + iRefreshIssued = ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::SetIapAcceptance +// Pass result to ALR monitor if any profile succeeds with new IAP or all failed +// ----------------------------------------------------------------------------- +// +TInt CSipAlrMigrationController::SetIapAcceptance( + MSipAlrMigrationObserver& aObserver, + TBool aIapWorks) + { + PROFILE_DEBUG4("CSipAlrMigrCtrl::SetIapAcceptance, iap,works=", + iAllowedIapId, + aIapWorks) + + TInt index = FindIndex(aObserver); + if (index != KErrNotFound && iObservers[index].iIsWaitingForAcceptance) + { + iObservers[index].iIsWaitingForAcceptance = EFalse; + if (aIapWorks) + { + // IAP works, no need to wait other observers + for (TInt i = 0; i < iObservers.Count(); ++i) + { + iObservers[i].iIsWaitingForAcceptance = EFalse; + } + PROFILE_DEBUG1("CSipAlrMigrCtrl::SetIapAcceptance accepted") + return iAlrMonitor.NewIapAccepted(iSnapId); + } + + if (!ObserversWaitingAcceptance()) + { + // Nobody got IAP to work + PROFILE_DEBUG1("CSipAlrMigrCtrl::SetIapAcceptance rejected") + return iAlrMonitor.NewIapRejected(iSnapId); + } + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::SendMigrationResult +// ----------------------------------------------------------------------------- +// +void +CSipAlrMigrationController::SendMigrationResult(TUint32 aIapId, TBool aAllowed) + { + PROFILE_DEBUG5("CSipAlrMigrCtrl::SendMigrationResult iap,allow,obsCount", + aIapId, + aAllowed, + iObservers.Count()) + + for (TInt i = 0; i < iObservers.Count(); ++i) + { + MSipAlrMigrationObserver& obs = iObservers[i].iObserver; + TRAPD(err, if (aAllowed) + { + obs.MigrationIsAllowedL(aIapId); + } + else + { + obs.MigrationIsDisallowedL(aIapId); + }); + + if (err != KErrNone) + { + PROFILE_DEBUG4("MigrationIs(Dis)AllowedL leaves err,index", err, i) + obs.ErrorOccurred(err); + } + } + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::FindIndex +// ----------------------------------------------------------------------------- +// +TInt +CSipAlrMigrationController::FindIndex(MSipAlrMigrationObserver& aObserver) const + { + TSipAlrMigrationObserverInfo observerInfo(aObserver); + TIdentityRelation + compare(TSipAlrMigrationObserverInfo::CompareObservers); + return iObservers.Find(observerInfo, compare); + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::ObserversWaitingPermission +// ----------------------------------------------------------------------------- +// +TBool CSipAlrMigrationController::ObserversWaitingPermission() const + { + for (TInt i = 0; i < iObservers.Count(); ++i) + { + if (iObservers[i].iIsWaitingForPermission) + { + return ETrue; + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::ObserversWaitingAcceptance +// ----------------------------------------------------------------------------- +// +TBool CSipAlrMigrationController::ObserversWaitingAcceptance() const + { + for (TInt i = 0; i < iObservers.Count(); ++i) + { + if (iObservers[i].iIsWaitingForAcceptance) + { + return ETrue; + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::NoNewIapAvailable +// ----------------------------------------------------------------------------- +// +void CSipAlrMigrationController::NoNewIapAvailable() const + { + for (TInt i = 0; i < iObservers.Count(); ++i) + { + iObservers[i].iObserver.NoNewIapAvailable(); + } + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::ResetFlags +// ----------------------------------------------------------------------------- +// +void CSipAlrMigrationController::ResetFlags() + { + iRefreshIssued = EFalse; + iAllowedIapId = KNoIap; + iOfferedIapId = KNoIap; + iMigrationDisallowed = EFalse; + } + +// ----------------------------------------------------------------------------- +// CSipAlrMigrationController::OfferedIapRejected +// ----------------------------------------------------------------------------- +// +void CSipAlrMigrationController::OfferedIapRejected() const + { + // Start from the end, as RefreshIAPsFailed() causes entries to + // remove themselves from the array. + for (TInt i = iObservers.Count() - 1; i >= 0; --i) + { + iObservers[i].iObserver.OfferedIapRejected(); + } + }