datacommsserver/esockserver/MobilityCoreProviders/src/mobilitymcpractivities.cpp
changeset 1 21d2ab05f085
parent 0 dfb7c4ff071f
child 2 dee179edb159
--- a/datacommsserver/esockserver/MobilityCoreProviders/src/mobilitymcpractivities.cpp	Thu Dec 17 09:22:25 2009 +0200
+++ b/datacommsserver/esockserver/MobilityCoreProviders/src/mobilitymcpractivities.cpp	Thu Jan 07 13:34:53 2010 +0200
@@ -1,9 +1,9 @@
 // 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 the License "Symbian Foundation License v1.0"
+// under the terms of "Eclipse Public License v1.0"
 // which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
 //
 // Initial Contributors:
 // Nokia Corporation - initial contribution.
@@ -16,10 +16,10 @@
 #include <elements/nm_messages_errorrecovery.h>
 #include <comms-infras/ss_coreprstates.h>
 #include "mobilitymcpractivities.h"
-#include "mobilitymcprstates.h"
-#include "ss_nodemessages_selector.h"
-#include "ss_nodemessages_mobility.h"
-#include "ss_nodemessages_availability.h"
+#include <comms-infras/mobilitymcprstates.h>
+#include <comms-infras/ss_nodemessages_selector.h>
+#include <comms-infras/ss_nodemessages_mobility.h>
+#include <comms-infras/ss_nodemessages_availability.h>
 #include <comms-infras/ss_logext.h>
 
 
@@ -43,7 +43,7 @@
 using namespace Messages;
 using namespace MeshMachine;
 
-///////////////////////////////////////////////////////////////////////////////
+//
 //Panics
 #ifdef _DEBUG
 _LIT (KCoreMobileMCprPanic,"CoreMobileMCprPanic");
@@ -87,7 +87,7 @@
 	//if it sees that the availability notification has influcenced what the currently preffered bearer should be.
 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TSendAvailabilityRequest, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake>)
 
-	//<BEGIN> MAIN LOOP ****************
+	//<BEGIN> MAIN LOOP ****************	
 	//The main mobility handshake loop. The loop is executed when performing migration from one service provider to another.
 	//The entry condition for the loop is that:
 	//- upgrade: a better then current access point is now available (a better access point reported available)
@@ -97,21 +97,21 @@
 	//      NOTE: if the current bearer ceases to be available completely (goes down), then this will be assisted by an error recovery request;
 	//      NOTE: This tuple doesn't actually do (b), i.e.: assumes the threshold of '1' (in 0..100 availability score range)
 	//Before awaitng for availability change or rejection by the client (TAwaitingCurrentCarrierRejectedOrAvailabilityChange), the activity
-	//first checks (TNoTagOrAwaitMobilityBlockedByErrorRecovery) if the availability has changed since it last checked
-	//(availability could have been reported amidst the previous handshake loop)
+	//first checks (TNoTagOrAwaitMobilityBlockedByErrorRecovery) if the availability has changed since it last checked 
+	//(availability could have been reported amidst the previous handshake loop) 
 	THROUGH_NODEACTIVITY_ENTRY(MobilityMCprStates::KStartMobilityHandshake, CMobilityActivity::TClearHandshakingFlag, CMobilityActivity::TNoTagOrAwaitMobilityBlockedByErrorRecovery)
 	NODEACTIVITY_ENTRY(MobilityMCprStates::KAwaitMobility, MeshMachine::TDoNothing, CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange, CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTriggerBlockedByErrorRecovery)
 
-		//Mobility has been triggered ((a) or (b)). Start mobility handshake (set handshaking flag and inform the client about the preferred bearer)
-		NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, MobilityMCprStates::TAwaitingMigrationRequestedOrRejected, CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards)
-		//The client accepts the new access point.
+		//Mobility has been triggered ((a) or (b)). Start mobility handshake (set handshaking flag and inform the client about the preferred bearer) 
+		NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, MobilityMCprStates::TAwaitingMigrationRequestedOrRejected, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards)
+		//The client accepts the new access point. 
 		//For the moment it is sufficient to use the re-connect activity, in the future we may want to
 		//customise the behavior, for example start the new layer before rebinding it, etc.
 		//Should rebinding fail, the mobility activity will be set to an error mode. The error mode will be cleared if
 		//there are other bearers this activity can offer. If there aren't the data client will be errored.
-		NODEACTIVITY_ENTRY(MobilityMCprStates::KReConnect, CMobilityActivity::TRequestReConnect, MCprStates::TAwaitingReConnectCompleteOrError, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards)
+		NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TRequestReConnect, MCprStates::TAwaitingReConnectCompleteOrError, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards)
 		//Rebinding has been successful. As far as MCPR is concerned, the mobility is finished, but the MCPR must await
-		//for the handshake (accept|reject) before it can offer another bearer.
+		//for the handshake (accept|reject) before it can offer another bearer. 
 		NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationCompleted, MobilityMCprStates::TAwaitingMigrationAcceptedOrRejected, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake|EBackward>)
 NODEACTIVITY_END()
 }
@@ -164,7 +164,7 @@
 ACTIVITY_MAP_END_BASE(MCprActivities, coreMCprActivities)
 }
 
-///////////////////////////////////////////////////////////////////////////////
+//
 // CMobilityActivity
 MeshMachine::CNodeActivityBase* MobilityMCprActivities::CMobilityActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
 	{
@@ -210,12 +210,11 @@
 	    //  - current bearer rejected;
 	    //  - proposed bearer rejected;
 	    //  - failure to migrate to the proposed bearer;
-        lastRejected = iAvailable ? iAvailable :
-                                    static_cast<RMetaServiceProviderInterface*>(aContext.Node().ServiceProvider());
+        lastRejected = iPreferred ? iPreferred : 
+                                    static_cast<RMetaServiceProviderInterface*>(aContext.Node().ServiceProvider()); 
 	    }
-
-    iCandidate = iAvailable;
-	iAvailable = NULL; //Do not remember rejected candidate any longer
+	
+	iPreferred = NULL; //Do not remember rejected candidate any longer
 	while ((candidate = static_cast<RMetaServiceProviderInterface*>(iter++)) != NULL)
 		{
 		const TAvailabilityStatus& status = candidate->AvailabilityStatus();
@@ -230,8 +229,7 @@
 		if (status.Score() > iAvailabilityScoreTreshold
 			&& candidate!=lastRejected)
 			{
-			if (candidate==aContext.Node().ServiceProvider()
-			    && Error() == KErrNone )
+			if (candidate->Flags() & TCFClientType::EStarted)
 				{
 				//The preferred one is the current one, is still available and was not just rejected.
 				//No need to do anything more.
@@ -239,7 +237,7 @@
 				}
 
 			//A new match found
-			iAvailable = candidate;
+			iPreferred = candidate;
 			return ETrue;
 			}
 		}
@@ -258,22 +256,6 @@
 	static_cast<CMobilityMetaConnectionProvider&>(iNode).iIsHandshakingNow = EFalse;
 	}
 
-DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext)
-TInt CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards::TransitionTag()
-	{
-	if (iContext.Activity()->Error() == KErrNone &&
-	    (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) ||
-	     message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage)))
-		{
-	        CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
-			if( activity.iCurrent!=activity.iAvailable )
-			    return MobilityMCprStates::KReConnect | NetStateMachine::EForward;
-			else
-		        return MeshMachine::KNoTag | NetStateMachine::EForward;
-		}
-	return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward;
-	}
-
 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext)
 TInt CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards::TransitionTag()
 	{
@@ -281,7 +263,7 @@
 	    (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) ||
 	     message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage)))
 		{
-			return MeshMachine::KNoTag | NetStateMachine::EForward;
+		return MeshMachine::KNoTag | NetStateMachine::EForward;
 		}
 	return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward;
 	}
@@ -290,13 +272,13 @@
 TInt CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger::TransitionTag()
 	{
 	//This is where the judgement is made on whether to trigger mobility (offer the client another bearer)
-	//or ignore and come back waiting.
+	//or ignore and come back waiting. 
 	__ASSERT_DEBUG(iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>() ||
-			iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(),
+			iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(), 
 			User::Panic(KCoreMobileMCprPanic, KPanicIncorrectMessage));
-	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));	
 	CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
-
+	
 	if (activity.EvaluatePreference(iContext))
 		{
         activity.SetError(KErrNone);
@@ -313,9 +295,9 @@
 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrAwaitMobility, NetStateMachine::MStateFork, CMobilityActivity::TContext)
 TInt CMobilityActivity::TNoTagOrAwaitMobility::TransitionTag()
 	{
-	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
+	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));	
 	CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
-
+	
 	if (activity.EvaluatePreference(iContext))
 		{
 		activity.SetError(KErrNone);
@@ -350,41 +332,26 @@
 
 	//Inform the CPR that a potential migration is available. We only support a single data client
 	//in this implementation.
-	__ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
+	__ASSERT_DEBUG(activity.iPreferred, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
 
 	//Compute all this here to keep EvaluatePreference() as fast as possible
-	activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().ServiceProvider());
+	activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted)));
 	__ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
 
 	//Perform a simple check if this is an upgrade or not
 	TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
 	RNodeInterface* sp = iter++;
-	while (sp && sp!=activity.iCurrent && sp!=activity.iAvailable)
+	while (sp && sp!=activity.iCurrent && sp!=activity.iPreferred)
 		{
 		sp = iter++;
 		}
 
 	TBool isUpgrade = (sp != activity.iCurrent); //If current was found first -> this is not an upgrade
-	if( activity.iCurrent == activity.iAvailable && activity.iCandidate )
-	    {
-		// The available client is the same as the current and a candidate exists, this indicates that
-		// an error has occured when trying to start the candidate bearer and the control as reverted to
-		// the current bearer. In this situation the notification needs to look as if the bearer has
-		// migrated from the failed candidate to the current bearer.
-		TCFMobilityControlClient::TMigrationNotification msg(activity.iCandidate->ProviderInfo().APId(),
-											   activity.iAvailable->ProviderInfo().APId(),
-											   isUpgrade, EFalse);
-		activity.PostToOriginators(msg);
-	    }
-	else
-	    {
-		// Standard case where migration is going from current to available.
-		TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(),
-											   activity.iAvailable->ProviderInfo().APId(),
-											   isUpgrade, EFalse);
-		activity.PostToOriginators(msg);
-	    }
+	TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(),
+	                                       activity.iPreferred->ProviderInfo().APId(),
+	                                       isUpgrade, EFalse);
 
+	activity.PostToOriginators(msg);
 	activity.ClearPostedTo();
 	activity.SetHandshakingFlag();
 	}
@@ -408,13 +375,13 @@
 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
 	CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity);
 
-	__ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
+	__ASSERT_DEBUG(activity.iPreferred, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
 	__ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider));
-	__ASSERT_DEBUG(activity.iCurrent!=activity.iAvailable, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1));
+	__ASSERT_DEBUG(activity.iCurrent!=activity.iPreferred, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1));
 
 	// For the moment it is sufficient to use the re-connect activity, in the future we may want to
 	// customise the behavior, for example start the new layer before rebinding it, etc.
-	TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iAvailable->RecipientId());
+	TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iPreferred->RecipientId());
 	activity.PostRequestTo(iContext.NodeId(), msg);
 	}
 
@@ -435,7 +402,7 @@
 	}
 
 
-///////////////////////////////////////////////////////////////////////////////
+//
 //CConnectionRecoveryActivity
 MeshMachine::CNodeActivityBase* CConnectionRecoveryActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
 	{
@@ -501,26 +468,27 @@
 void CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL()
 	{
 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
-	RNodeInterface* newSP = NULL;
-	RNodeInterface* curSP = iContext.Node().ServiceProvider(); //Our current started Service Provider.
+	RNodeInterface* startingSP = NULL;
+	RNodeInterface* stoppingSP = NULL;
 
 	//Choose Service Providers to work on
 	TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider));
 	RNodeInterface* itf = NULL;
-	for (itf = iter++; itf!=NULL && newSP==NULL; itf = iter++)
+	for (itf = iter++; itf!=NULL && stoppingSP==NULL; itf = iter++)
 		{
-		if (itf==curSP)
+		if (itf->Flags() & TCFClientType::EStarted)
 			{
-			newSP = iter++; //And the new one to try next
+			stoppingSP = itf; //Our current started Service Provider.
+			startingSP = iter++; //And the new one to try next
 			}
 		}
 
 	//Sanity check.
 	//The new provider must not be started, there can be only one started at a time.
-	__ASSERT_DEBUG(newSP==NULL || (newSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3));
+	__ASSERT_DEBUG(startingSP==NULL || (startingSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3));
 
 	//If there is no other Service Provider to try, return KErrNotFound
-	if (newSP==NULL || curSP == NULL)
+	if (startingSP==NULL || stoppingSP == NULL)
 		{
 #ifdef __CFLOG_ACTIVE
 		__CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("WARNING: CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() - no more choices, abandoning recovery.")));
@@ -531,7 +499,7 @@
 	//Diagnostinc - there must be a data client or we cannot be here
 	__ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)), User::Panic(KCoreMobileMCprPanic, KPanicNoDataClient));
 	iContext.iNodeActivity->PostRequestTo(iContext.NodeId(),
-			TCFMcpr::TReConnect(curSP->RecipientId(), newSP->RecipientId()).CRef());
+			TCFMcpr::TReConnect(stoppingSP->RecipientId(), startingSP->RecipientId()).CRef());
 	}
 
 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext)
@@ -540,7 +508,7 @@
 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity));
 	CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity);
 
-	RNodeInterface* started = iContext.Node().ServiceProvider();
+	RNodeInterface* started = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted));
 	TUint apId = (TUint)activity.iOriginalErrContext.iInfo;
 	RNodeInterface* gonedownsp = iContext.Node().FindServiceProvider(apId);
 	if (started && started != gonedownsp)