datacommsserver/esockserver/MobilityCoreProviders/src/mobilitycpr.cpp
changeset 0 dfb7c4ff071f
child 18 9644881fedd0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/MobilityCoreProviders/src/mobilitycpr.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,225 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Mobility Connection Provider implementation
+// 
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <comms-infras/corecprstates.h>
+#include <comms-infras/corecpractivities.h>
+#include "mobilitycpr.h"
+#include <comms-infras/ss_log.h>
+#include <comms-infras/api_ext_list.h>
+
+#include <comms-infras/ss_msgintercept.h>
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ESockMbCrCPR, "ESockMbCrCPR");
+#endif
+
+#ifdef SYMBIAN_TRACE_ENABLE
+#define KIPCprTag KESockConnectionTag
+// _LIT8(KIPCprSubTag, "mobilitycpr");
+#endif // SYMBIAN_TRACE_ENABLE
+
+using namespace ESock;
+using namespace NetStateMachine;
+using namespace Messages;
+using namespace MeshMachine;
+
+//We reserve space for two preallocated activities that may start concurrently on the CPR
+//node: destroy and data client stop.
+static const TUint KDefaultMaxPreallocatedActivityCount = 2;
+static const TUint KMaxPreallocatedActivitySize = sizeof(MeshMachine::CNodeRetryParallelActivity) + sizeof(MeshMachine::APreallocatedOriginators<4>);
+static const TUint KMobilityCPRPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize;
+
+//-=========================================================
+//
+// CMobilityConnectionProvider methods
+//
+//-=========================================================
+EXPORT_C CMobilityConnectionProvider* CMobilityConnectionProvider::NewL(CConnectionProviderFactoryBase& aFactory, const MeshMachine::TNodeActivityMap& aActivityMap)
+    {
+    CMobilityConnectionProvider* provider = new (ELeave) CMobilityConnectionProvider(aFactory, aActivityMap);
+    CleanupStack::PushL(provider);
+    provider->ConstructL(KMobilityCPRPreallocatedActivityBufferSize);
+    CleanupStack::Pop(provider);
+	return provider;
+    }
+
+EXPORT_C CMobilityConnectionProvider::CMobilityConnectionProvider(CConnectionProviderFactoryBase& aFactory, const MeshMachine::TNodeActivityMap& aActivityMap)
+:	CCoreConnectionProvider(aFactory, aActivityMap),
+	TIfStaticFetcherNearestInHierarchy(this)
+    {
+    LOG_NODE_CREATE(KIPCprTag, CMobilityConnectionProvider);
+    }
+
+EXPORT_C CMobilityConnectionProvider::~CMobilityConnectionProvider()
+    {
+    LOG_NODE_DESTROY(KIPCprTag, CMobilityConnectionProvider);
+    }
+
+EXPORT_C void CMobilityConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
+	{
+	ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient);
+	CCoreConnectionProvider::ReceivedL(aSender, aRecipient, aMessage);
+	}
+
+EXPORT_C void CMobilityConnectionProvider::ReturnInterfacePtrL(AMobilityProtocolReq*& aInterface)
+	{
+	aInterface = this;
+	}
+
+EXPORT_C void CMobilityConnectionProvider::OpenExtensionInterface(TSubSessionUniqueId aClientId, const Messages::TRuntimeCtxId& aControlClient, CCommsApiExtResponder* aResponder)
+	{
+	__ASSERT_DEBUG(aResponder, User::Panic(KSpecAssert_ESockMbCrCPR, 1)); //Responder must be valid here
+	__ASSERT_DEBUG(aClientId != 0, User::Panic(KSpecAssert_ESockMbCrCPR, 2)); //Client id must be valid here.
+
+	if (iMobilityActivity)
+		{
+		//Only one mobility client is supported by this implementation,
+		//and this client has already opened the interface.
+		CCommsApiExtResponder::Complete(aResponder,KErrInUse);
+		return;
+		}
+
+	TCFMobilityProvider::TStartMobility msg(aResponder, aClientId);
+	__ASSERT_DEBUG_NO_LEAVE(ReceivedL(aControlClient, Id(), msg)); //ReceivedL can never leave on MM nodes
+
+	if (iMobilityActivity==NULL)
+		{
+		CCommsApiExtResponder::Complete(aResponder,KErrNoMemory);
+		}
+	}
+
+EXPORT_C void CMobilityConnectionProvider::CloseExtensionInterface(TSubSessionUniqueId aClientId)
+	{
+	//Ignore all close requests for any other client than ours
+	if (iMobilityActivity==NULL || iMobilityActivity->iClientId!=aClientId)
+		{
+		return;
+		}
+
+	//The activity has no originators, cancel it explicitly
+	TNodeNullContext ctx(*this,iMobilityActivity);
+	iMobilityActivity->Cancel(ctx);
+	iMobilityActivity = NULL; //New mobility interface can be opened now
+	}
+
+EXPORT_C void CMobilityConnectionProvider::SubscribeForMessage(TSubSessionUniqueId aClientId, CCommsMobilitySrvResp* aRespExt)
+	{
+	__ASSERT_DEBUG(aRespExt, User::Panic(KSpecAssert_ESockMbCrCPR, 3)); //Responder must be valid here
+	//If the interface was opened successfuly, iMobilityActivity is set.
+	//It could only be cleared again if:
+	//1) The mobility activity generated or not handled received error message.
+	//But the activity is supposed to do that.
+	//2) The node received and is currently processing TDestroy before this
+	//activity was terminated, which can never happen, as the Control Client
+	//would cancel it before leaving or it would be aborted on the Control Client
+	//leaving (so before sending TDataClientIdle).
+	__ASSERT_DEBUG(iMobilityActivity, User::Panic(KSpecAssert_ESockMbCrCPR, 4));
+	__ASSERT_DEBUG(iMobilityActivity->iClientId==aClientId, User::Panic(KSpecAssert_ESockMbCrCPR, 5));
+	(void)(iMobilityActivity->iClientId==aClientId);   //keep compiler happy
+	iMobilityActivity->SetResponder(*aRespExt);
+	}
+
+EXPORT_C void CMobilityConnectionProvider::CancelSubscription(TSubSessionUniqueId aClientId)
+	{
+	//Ignore all cancel requests for any other client than ours
+	if (iMobilityActivity==NULL || iMobilityActivity->iClientId!=aClientId)
+		{
+		return;
+		}
+
+	__ASSERT_DEBUG(iMobilityActivity, User::Panic(KSpecAssert_ESockMbCrCPR, 7));
+	CCommsApiExtResponder::Complete(iMobilityActivity->iResponder, KErrCancel);
+	}
+
+EXPORT_C void CMobilityConnectionProvider::MigrateToPreferredCarrier(TSubSessionUniqueId aClientId)
+	{
+	//If the interface was opened successfuly, iMobilityActivity is set.
+	//It could only be cleared again if:
+	//1) The mobility activity generated or not handled received error message.
+	//But the activity is supposed to do that.
+	//2) The node received and is currently processing TDestroy before this
+	//activity was terminated, which can never happen, as the Control Client
+	//would cancel it before leaving or it would be aborted on the Control Client
+	//leaving (so before sending TDataClientIdle).
+	__ASSERT_DEBUG(iMobilityActivity, User::Panic(KSpecAssert_ESockMbCrCPR, 8));
+	__ASSERT_DEBUG(iMobilityActivity->iClientId==aClientId, User::Panic(KSpecAssert_ESockMbCrCPR, 9));
+	(void)(iMobilityActivity->iClientId==aClientId); //keep compiler happy
+	TCFMobilityProvider::TMigrationRequested msg;
+	__ASSERT_DEBUG_NO_LEAVE(ReceivedL(NodeId(), Id(), msg)); //ReceivedL can never leave on MM nodes
+	}
+
+EXPORT_C void CMobilityConnectionProvider::IgnorePreferredCarrier(TSubSessionUniqueId aClientId)
+	{
+	//If the interface was opened successfuly, iMobilityActivity is set.
+	//It could only be cleared again if:
+	//1) The mobility activity generated or not handled received error message.
+	//But the activity is supposed to do that.
+	//2) The node received and is currently processing TDestroy before this
+	//activity was terminated, which can never happen, as the Control Client
+	//would cancel it before leaving or it would be aborted on the Control Client
+	//leaving (so before sending TDataClientIdle).
+	__ASSERT_DEBUG(iMobilityActivity, User::Panic(KSpecAssert_ESockMbCrCPR, 10));
+	__ASSERT_DEBUG(iMobilityActivity->iClientId==aClientId, User::Panic(KSpecAssert_ESockMbCrCPR, 11));
+	(void)(iMobilityActivity->iClientId==aClientId); //keep compiler happy
+	TCFMobilityProvider::TMigrationRejected msg(KErrNone);
+	__ASSERT_DEBUG_NO_LEAVE(ReceivedL(NodeId(), Id(), msg)); //ReceivedL can never leave on MM nodes
+	}
+
+EXPORT_C void CMobilityConnectionProvider::NewCarrierAccepted(TSubSessionUniqueId aClientId)
+	{
+	//If the interface was opened successfuly, iMobilityActivity is set.
+	//It could only be cleared again if:
+	//1) The mobility activity generated or not handled received error message.
+	//But the activity is supposed to do that.
+	//2) The node received and is currently processing TDestroy before this
+	//activity was terminated, which can never happen, as the Control Client
+	//would cancel it before leaving or it would be aborted on the Control Client
+	//leaving (so before sending TDataClientIdle).
+	__ASSERT_DEBUG(iMobilityActivity, User::Panic(KSpecAssert_ESockMbCrCPR, 12));
+	__ASSERT_DEBUG(iMobilityActivity->iClientId==aClientId, User::Panic(KSpecAssert_ESockMbCrCPR, 13));
+	(void)(iMobilityActivity->iClientId==aClientId);//keep compiler happy
+	TCFMobilityProvider::TMigrationAccepted msg;
+	__ASSERT_DEBUG_NO_LEAVE(ReceivedL(NodeId(), Id(), msg)); //ReceivedL can never leave on MM nodes
+	}
+
+EXPORT_C void CMobilityConnectionProvider::NewCarrierRejected(TSubSessionUniqueId aClientId)
+	{
+	//If the interface was opened successfuly, iMobilityActivity is set.
+	//It could only be cleared again if:
+	//1) The mobility activity generated or not handled received error message.
+	//But the activity is supposed to do that.
+	//2) The node received and is currently processing TDestroy before this
+	//activity was terminated, which can never happen, as the Control Client
+	//would cancel it before leaving or it would be aborted on the Control Client
+	//leaving (so before sending TDataClientIdle).
+	__ASSERT_DEBUG(iMobilityActivity, User::Panic(KSpecAssert_ESockMbCrCPR, 14));
+	__ASSERT_DEBUG(iMobilityActivity->iClientId==aClientId, User::Panic(KSpecAssert_ESockMbCrCPR, 15));
+	(void)(iMobilityActivity->iClientId==aClientId);//keep compiler happy
+	TCFMobilityProvider::TMigrationRejected msg(KErrNone);
+	__ASSERT_DEBUG_NO_LEAVE(ReceivedL(NodeId(), Id(), msg)); //ReceivedL can never leave on MM nodes
+	}
+
+