networkcontrol/ipnetworklayer/src/IPProtoCprStates.cpp
changeset 0 af10295192d8
child 7 db85996de7c4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkcontrol/ipnetworklayer/src/IPProtoCprStates.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,317 @@
+// Copyright (c) 2006-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:
+// IPProto Connection Provider implementation
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <comms-infras/ss_nodemessages.h>
+#include <comms-infras/corecpractivities.h>
+
+#include <comms-infras/ss_metaconnprov.h>
+#include <comms-infras/sockmes.h> // for ioctl ipc
+
+#include "IPProtoCprStates.h"
+#include "IPProtoMessages.h"
+#include "linkcprextensionapi.h"
+#include <comms-infras/ss_datamonitoringprovider.h>
+#include <comms-infras/ss_connlegacy.h>
+#include <nifvar.h> // KLinkLayerOpen
+#include <comms-infras/ss_nodemessages_internal.h>
+#include <comms-infras/ss_legacyinterfaces.h>
+#include <comms-infras/simpleselectorbase.h>
+#include <commsdattypesv1_1_partner.h>
+#include <es_prot_internal.h>
+
+using namespace Messages;
+using namespace MeshMachine;
+using namespace IpProtoCpr;
+using namespace ESock;
+
+DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TStoreProvision::DoL()
+	{
+	PRStates::TStoreProvision storeProvision(iContext);
+	storeProvision.DoL();
+
+	CIPProtoConnectionProvider& node = iContext.Node();
+
+	// Retrieve the idle timer values from the provisioning information bucket
+	const Meta::SMetaData* extension =
+		node.AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TIdleTimerValues::iUid, TIdleTimerValues::iId));
+
+    if (extension)
+        {
+        const TIdleTimerValues* vals = static_cast<const TIdleTimerValues*>(extension);
+        node.SetTimers(vals->iShortTimer, vals->iMediumTimer, vals->iLongTimer);
+        }
+
+    if (!node.iNodeLocalExtensionsCreated)
+    	{
+    	node.iNodeLocalExtensions.Open();
+
+    	TPacketActivity* packetActivity = new(ELeave)TPacketActivity(&iContext.Node().iPeriodActivity);
+        CleanupStack::PushL(packetActivity);
+        node.iNodeLocalExtensions.AppendExtensionL(packetActivity);
+        CleanupStack::Pop(packetActivity);
+        
+        // Allocate and add the data monitoring shared memory pointers to the provisioning info
+    	TDataMonitoringConnProvisioningInfo* connProvisioningInfo = new (ELeave) TDataMonitoringConnProvisioningInfo(&node.iDataVolumes, &node.iThresholds);
+    	CleanupStack::PushL(connProvisioningInfo);
+    	node.iNodeLocalExtensions.AppendExtensionL(connProvisioningInfo);
+    	CleanupStack::Pop(connProvisioningInfo);
+
+    	// Allocate the data monitoring subconnection data structure.
+    	//
+    	// This used to be allocated in the SCPR, but it has been moved here to the CPR.  This is because there can be
+    	// temporary circumstances where there is more than one SCPR present - one or more of these in a leaving
+    	// state and one in an active state.  The access point config cannot presently hold provisioning information
+    	// specific to an SCPR instance, so it is allocated and managed here in the CPR as a shared entity.  Only
+    	// one SCPR instance should be using this at a time, however.
+    	TDataMonitoringSubConnProvisioningInfo* subConnProvisioningInfo = new (ELeave) TDataMonitoringSubConnProvisioningInfo(NULL, NULL);
+    	CleanupStack::PushL(subConnProvisioningInfo);
+    	node.iNodeLocalExtensions.AppendExtensionL(subConnProvisioningInfo);
+    	CleanupStack::Pop(subConnProvisioningInfo);
+    	
+       	// The CLinkCprExtensionApi may have been added previously if this is a reconnect scenario
+    	// We add it again in this new override of the extensions, if the old container is fully superceded
+    	// it will be closed and destroyed.
+       	extension = CLinkCprExtensionApi::NewLC(iContext.Node());
+       	node.iNodeLocalExtensions.AppendExtensionL(extension);
+    	CleanupStack::Pop(); // CLinkCprExtensionApi
+    	
+    	node.iNodeLocalExtensionsCreated = ETrue;
+    	}
+    
+    RMetaExtensionContainer mec;
+    mec.Open(iContext.Node().AccessPointConfig());
+    CleanupClosePushL(mec);
+    mec.AppendContainerL(node.iNodeLocalExtensions);
+    
+	iContext.Node().iAccessPointConfig.Close();
+    iContext.Node().iAccessPointConfig.Open(mec);
+	CleanupStack::PopAndDestroy(&mec);
+	
+	// For the case that this is an update of the provisioned info we forward it to non-leaving data clients
+	TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(
+		TClientType(TCFClientType::EData),
+		TClientType(0, TClientType::ELeaving)
+		);
+
+	for (TInt i = 0; iter[i]; i++)
+		{
+		iter[i]->PostMessage(
+			iContext.NodeId(),
+			TCFDataClient::TProvisionConfig(iContext.Node().iAccessPointConfig).CRef()
+			);
+		}
+	}
+
+DEFINE_SMELEMENT(TAwaitingDataMonitoringNotification, NetStateMachine::MState, IpProtoCpr::TContext)
+TBool TAwaitingDataMonitoringNotification::Accept()
+	{
+	return iContext.iMessage.IsMessage<TCFDataMonitoringNotification::TDataMonitoringNotification>();
+	}
+
+
+DEFINE_SMELEMENT( TAwaitingGoneDown , NetStateMachine::MState, IpProtoCpr::TContext)
+TBool TAwaitingGoneDown::Accept()
+	{
+	if  (iContext.iMessage.IsMessage<TCFControlClient::TGoneDown>())
+		{
+		iContext.Node().LinkDown();
+		}
+	// return EFalse to allow further PRActivities processing
+	return EFalse;
+	}
+
+
+DEFINE_SMELEMENT(TProcessDataMonitoringNotification, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TProcessDataMonitoringNotification::DoL()
+	{
+	TCFDataMonitoringNotification::TDataMonitoringNotification& msg =
+		message_cast<TCFDataMonitoringNotification::TDataMonitoringNotification>(iContext.iMessage);
+
+	iContext.Node().DataNotificationL(msg);
+	}
+
+DEFINE_SMELEMENT(TAwaitingStart, NetStateMachine::MState, IpProtoCpr::TContext)
+TBool TAwaitingStart::Accept()
+	{
+	CoreNetStates::TAwaitingStart state(iContext);
+	if (state.Accept())
+		{
+		iContext.Node().DisableTimers();
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+DEFINE_SMELEMENT(TCleanupStart, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TCleanupStart::DoL()
+ 	{
+ 	//Re-enable idle timers disabled by IpProtoCpr::TAwaitingStart
+	iContext.Node().EnableTimers();
+	}
+
+DEFINE_SMELEMENT(TCheckIfLastControlClientLeaving, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TCheckIfLastControlClientLeaving::DoL()
+	{
+	CIPProtoConnectionProvider& node = iContext.Node();
+	node.ForceCheckShortTimerMode();
+	}
+
+DEFINE_SMELEMENT(TAwaitingOpenCloseRoute, NetStateMachine::MState, IpProtoCpr::TContext)
+TBool TAwaitingOpenCloseRoute::Accept()
+	{
+	return (iContext.iMessage.IsMessage<TCFIPProtoMessage::TOpenCloseRoute>());
+	}
+
+DEFINE_SMELEMENT(TDoOpenCloseRoute, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TDoOpenCloseRoute::DoL()
+	{
+	TCFIPProtoMessage::TOpenCloseRoute& msg = message_cast<TCFIPProtoMessage::TOpenCloseRoute>(iContext.iMessage);
+	if (msg.iValue)
+		iContext.Node().OpenRoute();
+	else
+		iContext.Node().CloseRoute();
+	}
+
+
+
+
+
+DEFINE_SMELEMENT(TLinkUp, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TLinkUp::DoL()
+	{
+	iContext.Node().LinkUp();
+	}
+
+DEFINE_SMELEMENT(TLinkDown, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TLinkDown::DoL()
+	{
+	iContext.Node().LinkDown();
+	}
+
+DEFINE_SMELEMENT(TStoreAndFilterDeprecatedAndForwardStateChange, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TStoreAndFilterDeprecatedAndForwardStateChange::DoL()
+	{
+	TCFMessage::TStateChange& msg = message_cast<TCFMessage::TStateChange>(iContext.iMessage);
+	//Forward to control clients if there are any
+
+    ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x TStateChange\tProgress: %d, Error: %d"), &iContext.Node(), msg.iStateChange.iStage, msg.iStateChange.iError) );
+
+	//We are the only node accessing this CLinkCprExtensionApi interface so we can do it safely here.
+	//This is rather an exceptional situation, please keep the const_cast.
+	const CLinkCprExtensionApi* linkCPR = static_cast<const CLinkCprExtensionApi*>(iContext.Node().AccessPointConfig().FindExtension(CLinkCprExtensionApi::TypeId()));
+	const_cast<CLinkCprExtensionApi*>(linkCPR)->SetLastProgress(msg.iStateChange);
+
+	if ((KLinkLayerOpen != msg.iStateChange.iStage) && (KLinkLayerClosed != msg.iStateChange.iStage) )
+		{
+		//KLinkLayerOpen is now redundant with TCFControlClient::TGoneUp & TCFServiceProvider::TStarted 
+		//KLinkLayerClosed is now redundant with TCFControlClient::TGoneDown & TCFServiceProvider::TStopped
+		//They have therefore been deprecated. Stack nodes are requested not to send the deprecated
+		//signals anymore. If stack nodes do send the deprecated signals, the signals will be eaten here 
+		//because they confuse convergence and mobility layers, which may live just above. 
+		TInt ctrlClientCount = iContext.Node().PostToClients<TDefaultClientMatchPolicy>(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.iMessage, TClientType(TCFClientType::ECtrl));
+		if (0==ctrlClientCount)
+			{ //If there are no control clients any more, forward to the control provider
+			iContext.Node().PostToClients<TDefaultClientMatchPolicy>(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.iMessage, TClientType(TCFClientType::ECtrlProvider));
+			}
+		}
+	}
+
+DEFINE_SMELEMENT(TSendStopToSelf, NetStateMachine::MStateTransition, TContext)
+void TSendStopToSelf::DoL()
+ 	{
+	iContext.iNodeActivity->PostRequestTo(iContext.NodeId(),
+		TCFServiceProvider::TStop(iContext.iNodeActivity->Error()).CRef());
+	}
+
+
+DEFINE_SMELEMENT(TSendStarted, NetStateMachine::MStateTransition, TContext)
+void TSendStarted::DoL()
+ 	{
+ 	//Set the idle timers
+	iContext.Node().EnableTimers();
+	iContext.Node().SetUsageProfile(KConnProfileMedium);
+	iContext.Node().SetTimerMode(CIPProtoConnectionProvider::ETimerMedium);
+
+	CoreNetStates::TSendStarted transition(iContext);
+	transition.DoL();
+	}
+
+DEFINE_SMELEMENT(IpProtoCpr::TProcessDataClientStatusChange, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void IpProtoCpr::TProcessDataClientStatusChange::DoL()
+    {
+    TCFControlProvider::TDataClientStatusChange& msg = message_cast<TCFControlProvider::TDataClientStatusChange>(iContext.iMessage);
+
+   	if(msg.iValue == TCFControlProvider::TDataClientStatusChange::EStarted)
+		{
+		iContext.iPeer->SetFlags(TCFClientType::EStarted);
+		}
+	else
+		{
+		iContext.iPeer->ClearFlags(TCFClientType::EStarted);
+		}
+
+    if(!msg.iValue && !iContext.Node().iSubConnEventDataSent)
+    	{ // We're only interested in the provider being stopped.
+    	ADataMonitoringProtocolReq* dmInterface = NULL;
+		iContext.Node().ReturnInterfacePtrL(dmInterface);
+
+		ADataMonitoringProvider* dmProvider = static_cast<ADataMonitoringProvider*>(dmInterface);
+
+    	ASSERT(dmProvider); // Must always support this interface
+
+    	TCFMessage::TSubConnDataTransferred wholeConnMsg(KNifEMCompatibilityLayerEntireSubConnectionUid, dmProvider->DataVolumesPtr()->iSentBytes, dmProvider->DataVolumesPtr()->iReceivedBytes);
+    	TCFMessage::TSubConnDataTransferred defaultSubConnMsg(KNifEMCompatibilityLayerFakeSubConnectionId, dmProvider->DataVolumesPtr()->iSentBytes, dmProvider->DataVolumesPtr()->iReceivedBytes);
+
+    	RNodeInterface* ctrlClient = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl));
+		if(ctrlClient)
+			{ // Can't send this if the client's gone
+			ctrlClient->PostMessage(iContext.NodeId(), wholeConnMsg);
+			ctrlClient->PostMessage(iContext.NodeId(), defaultSubConnMsg);
+
+			iContext.Node().iSubConnEventDataSent = ETrue;
+			}
+    	}
+    }
+
+DEFINE_SMELEMENT(TAwaitingIoctlMessage, NetStateMachine::MState, IpProtoCpr::TContext)
+TBool TAwaitingIoctlMessage::Accept()
+	{
+	if (iContext.iMessage.IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)))
+		{
+		TCFSigLegacyRMessage2Ext& msg = static_cast<TCFSigLegacyRMessage2Ext&>(iContext.iMessage);
+		if (msg.iMessage.Function() == ECNIoctl)
+			{
+			return ETrue;
+			}
+		}
+	return EFalse;
+	}
+
+DEFINE_SMELEMENT(TForwardToDefaultDataClient, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TForwardToDefaultDataClient::DoL()
+	{
+	ASSERT(iContext.iMessage.IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)));
+
+	RNodeInterface* dc = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData));	
+	iContext.Activity()->PostRequestTo(*dc, iContext.iMessage);
+	}