networkcontrol/iptransportlayer/src/ipcpr_states.cpp
changeset 0 af10295192d8
child 20 7e41d162e158
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkcontrol/iptransportlayer/src/ipcpr_states.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,362 @@
+// 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:
+// IP Connection Provider state definitions.
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#define SYMBIAN_NETWORKING_UPS
+
+#include "IPCpr.h"
+#include "ipcpr_states.h"
+#include "IPMessages.h"
+#include <comms-infras/ss_nodemessages.h>
+#include <comms-infras/ss_nodemessages_internal_esock.h>
+#include <comms-infras/ss_datamonitoringprovider.h>
+
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+#include <comms-infras/ss_nodemessages_scpr.h>
+#include <tcprecvwin.h>
+#include <cs_genevent.h>
+#include <comms-infras/ss_protopt.h>
+#include <in_sock.h>
+#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+
+using namespace Messages;
+using namespace MeshMachine;
+using namespace ESock;
+using namespace IpCprActivities;
+using namespace IpCprStates;
+
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+using namespace TcpAdaptiveReceiveWindow;
+#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+
+const TInt KNifEMCompatibilityLayerEntireSubConnectionUid = 0;
+const TInt KNifEMCompatibilityLayerFakeSubConnectionId = 1;
+
+DEFINE_SMELEMENT( TAwaitingPolicyParams, NetStateMachine::MState, IpCprStates::TContext)
+TBool IpCprStates::TAwaitingPolicyParams::Accept()
+    {
+	return iContext.iMessage.IsMessage<TCFIPMessage::TPolicyParams>();
+    }
+/**
+Security policies
+*/
+
+_LIT_SECURITY_POLICY_C1(KIpCprStopSecurityPolicy, ECapabilityNetworkControl);
+    
+/**
+IpCpr Stop capability check transition
+*/
+DEFINE_SMELEMENT( TCheckStopCapabilities, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TCheckStopCapabilities::DoL()
+    {
+    MPlatsecApiExt* platsec = reinterpret_cast<MPlatsecApiExt*>(address_cast<TNodeId>(iContext.iSender).Node().FetchNodeInterfaceL(MPlatsecApiExt::KInterfaceId));
+    TInt err = platsec->CheckPolicy(KIpCprStopSecurityPolicy);
+	User::LeaveIfError(err);
+    }
+
+/**
+
+*/
+DEFINE_SMELEMENT( TSendPolicyParams, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TSendPolicyParams::DoL()
+    {
+	TCFIPMessage::TPolicyParams& policyParams = message_cast<TCFIPMessage::TPolicyParams>(iContext.iMessage);
+	// change originator to current ipcpr
+//	policyParams.iSender = iContext.Node()();
+
+	RNodeInterface* ctrlProvider = iContext.Node().ControlProvider();
+
+
+	if(ctrlProvider)
+		{
+		ctrlProvider->PostMessage(iContext.NodeId(), policyParams);
+		}
+	else
+		{
+		User::Leave(KErrCorrupt);
+		}
+    }
+
+DEFINE_SMELEMENT( TAwaitingSubConnDataTransferred, NetStateMachine::MState, IpCprStates::TContext)
+TBool IpCprStates::TAwaitingSubConnDataTransferred::Accept()
+	{
+	return(iContext.iMessage.IsMessage<TCFMessage::TSubConnDataTransferred>());
+	}
+
+DEFINE_SMELEMENT( TProcessSubConnDataTransferred, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TProcessSubConnDataTransferred::DoL()
+	{
+	TCFMessage::TSubConnDataTransferred& msg = message_cast<TCFMessage::TSubConnDataTransferred>(iContext.iMessage);
+
+	RNodeInterface* ctrlClient = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl));
+	if(ctrlClient) // Ditch the notifications if there's no one to send to.
+		{
+		TTime now;
+		now.UniversalTime();
+
+		if(msg.iValue1 == KNifEMCompatibilityLayerEntireSubConnectionUid)
+			{
+		    TSubConnectionClosedEvent wholeConnEvent;
+		    wholeConnEvent.iSubConnectionUniqueId = KNifEMCompatibilityLayerEntireSubConnectionUid ;
+		    wholeConnEvent.iTotalUplinkDataVolume = msg.iValue2;
+		    wholeConnEvent.iTotalDownlinkDataVolume = msg.iValue3;
+		    wholeConnEvent.iTimeClosed = now;
+			TCFInternalEsock::TSubConnectionClosedEvent wholeConnMsg(wholeConnEvent);
+			ctrlClient->PostMessage(iContext.NodeId(), wholeConnMsg);
+			}
+		else
+			{
+			TSubConnectionClosedEvent defaultSubConnEvent;
+			defaultSubConnEvent.iSubConnectionUniqueId = KNifEMCompatibilityLayerEntireSubConnectionUid;
+			defaultSubConnEvent.iTotalUplinkDataVolume = msg.iValue2;
+			defaultSubConnEvent.iTotalDownlinkDataVolume = msg.iValue3;
+			defaultSubConnEvent.iTimeClosed = now;
+			TCFInternalEsock::TSubConnectionClosedEvent subConnMsg(defaultSubConnEvent);
+			ctrlClient->PostMessage(iContext.NodeId(), subConnMsg);
+			}
+		}
+	}
+
+
+DEFINE_SMELEMENT( TSendInitialSubConnectionOpenedEvent, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TSendInitialSubConnectionOpenedEvent::DoL()
+	{
+	RNodeInterface* ctrlClient = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl));
+	if(ctrlClient) // Ditch the notifications if there's no one to send to.
+		{
+	    TSubConnectionOpenedEvent wholeConnEvent;
+	    wholeConnEvent.iSubConnectionUniqueId = KNifEMCompatibilityLayerEntireSubConnectionUid ;
+		TCFInternalEsock::TSubConnectionOpenedEvent wholeConnMsg(wholeConnEvent);
+		ctrlClient->PostMessage(iContext.NodeId(), wholeConnMsg);
+		}
+	}
+
+DEFINE_SMELEMENT( TSendSubsequentSubConnectionOpenedEvent, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TSendSubsequentSubConnectionOpenedEvent::DoL()
+	{
+	RNodeInterface* ctrlClient = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl));
+	if(ctrlClient) // Ditch the notifications if there's no one to send to.
+		{
+    	// If it's the default subconnection then use the fake subconnection id.
+    	// Otherwise cook one up from the pointer of the SCPR.
+    	TUint subConnectionUniqueId = KNifEMCompatibilityLayerFakeSubConnectionId;
+    	TUint dataClientCount = iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData));
+    	if(dataClientCount > 1)
+    		{
+    		subConnectionUniqueId = reinterpret_cast<TUint>(address_cast<TNodeId>(iContext.iSender).Ptr());
+    		}
+
+	    TSubConnectionOpenedEvent defaultSubConnEvent;
+	    defaultSubConnEvent.iSubConnectionUniqueId = subConnectionUniqueId;
+	    TCFInternalEsock::TSubConnectionOpenedEvent subConnMsg(defaultSubConnEvent);
+	    ctrlClient->PostMessage(iContext.NodeId(), subConnMsg);
+    	}
+	}
+
+
+#ifndef SYMBIAN_NETWORKING_UPS
+
+_LIT_SECURITY_POLICY_C1(KIpCprStartSecurityPolicy, ECapabilityNetworkServices);
+
+/**
+IpCpr Start capability check transition
+*/
+DEFINE_SMELEMENT( TCheckStartCapabilities, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TCheckStartCapabilities::DoL()
+    {
+    MPlatsecApiExt* platsec = iContext.iCFMessageSig.FetchPlatsecApiInterfaceL();
+    TInt err = platsec->CheckPolicy(KIpCprStartSecurityPolicy);
+	User::LeaveIfError(err);
+    }
+
+#endif  //SYMBIAN_NETWORKING_UPS
+
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+/*
+Constructor for the new parameter set to be sent in parameter bundle while requesting for bearer type.
+@param aFamily - Specified the family the parameterset belongs to
+	    aType - Specifies the type
+@return object of type XBearerInfo
+*/
+EXPORT_C XBearerInfo* XBearerInfo::NewL(RParameterFamily aFamily, RParameterFamily::TParameterSetType aType)
+{
+	//call NewL
+	XBearerInfo *obj = XBearerInfo::NewL();
+	CleanupStack::PushL(obj);
+	
+	//add the parameterset to the family specified.
+	aFamily.AddParameterSetL(obj, aType);
+	CleanupStack::Pop(obj);
+	
+	return obj;	
+}
+
+/*
+Constructs object of XBearerInfo
+@return object of type XBearerInfo
+*/
+EXPORT_C XBearerInfo* XBearerInfo::NewL()
+{
+	return new(ELeave)XBearerInfo();
+}
+
+//Attribute table for data members of XBearerInfo class. Needed because the class derieves from SMetaData
+START_ATTRIBUTE_TABLE(XBearerInfo, XBearerInfo::EUid, XBearerInfo::EId)
+	REGISTER_ATTRIBUTE(XBearerInfo, iBearerType, TMetaNumber)
+END_ATTRIBUTE_TABLE()
+
+/**
+ * State Transition which initialises the Parameter bundle to request for the bearer type.
+ */
+DEFINE_SMELEMENT(IpCprStates::TInitialiseParams, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TInitialiseParams::DoL()
+    {
+   	RCFParameterFamilyBundle newBundle;
+	//create new bundle
+	newBundle.CreateL();
+	if(!iContext.Node().iParameterBundle.IsNull())
+		{
+		iContext.Node().iParameterBundle.Close();
+		}
+	iContext.Node().iParameterBundle.Open(newBundle);
+	//Create new family
+	RParameterFamily family = newBundle.CreateFamilyL(KBearerInfo);
+	//construct object to be added to the parameterset
+	//coverity[returned_pointer]
+	// We are trying to initializing the family parameter and returning the pointer to XbearerInfo object.
+	XBearerInfo *bearerInfo = XBearerInfo::NewL(family, RParameterFamily::ERequested);
+   }
+
+/**
+ * State Transition which receives the response message to the bearer type request.
+ * Extracts the bearer type and updates it in the NetMCPR
+ */
+DEFINE_SMELEMENT(IpCprStates::TUpdateProvisionConfigAtStartup, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TUpdateProvisionConfigAtStartup::DoL()
+    {
+	//Cast the message to response type
+    TCFScpr::TGetParamsResponse& paramResponse = message_cast<TCFScpr::TGetParamsResponse>(iContext.iMessage);
+	if( (! paramResponse.iFamilyBundle.IsNull()))
+		{
+		//Open the bundle
+		iContext.Node().GetParameterBundle().Open(paramResponse.iFamilyBundle);
+		CleanupClosePushL(iContext.Node().GetParameterBundle());
+		//Get the family ie. KBearerInfo
+		RParameterFamily family = iContext.Node().GetParameterBundle().FindFamily(KBearerInfo);	
+		if(!family.IsNull())
+			{
+			//Find the parameter set
+			XBearerInfo *bearerTypePtr = static_cast<XBearerInfo*>(family.FindParameterSet(STypeId::CreateSTypeId(KIpBearerInfoUid, KIpBearerInfoParameterType), RParameterFamily::ERequested));
+			if(bearerTypePtr)
+				{
+				//Set the bearer type in NetMCPR
+				CTCPReceiveWindowSize* winSizePtr =	const_cast<CTCPReceiveWindowSize *>(static_cast<const CTCPReceiveWindowSize *>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(CTCPReceiveWindowSize::ERealmId,CTCPReceiveWindowSize::iId))));
+				CSAPSetOpt* protOptPtr = const_cast<CSAPSetOpt *>(static_cast<const CSAPSetOpt *>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(CSAPSetOpt::EUid,CSAPSetOpt::ETypeId))));
+				//Set TCP Receive window value.
+				if(winSizePtr && protOptPtr)
+					{
+					winSizePtr->SetTcpWin(bearerTypePtr->GetBearerType());
+					protOptPtr->AddProtocolOptionL(KSolInetTcp, KSoTcpRecvWinAuto, winSizePtr->GetTcpWin());
+					protOptPtr->AddProtocolOptionL(KSolInetTcp, KSoTcpMaxRecvWin, winSizePtr->GetTcpMaxWin());
+					}		
+				}
+			}
+		// Decrease reference count by calling close of the reference passed in CleanupClosePushL at line no 261
+		CleanupStack::PopAndDestroy();
+		}
+    }
+
+/**
+ * State Transition to update the NetMCPR with bearer type recd. after receiving the modulation change notification.
+ * Receives the TPlaneNotification message containting the new bearer.
+ */
+DEFINE_SMELEMENT(IpCprStates::TUpdateProvisionConfigAtModulation, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TUpdateProvisionConfigAtModulation::DoL()
+    {
+	
+    TInt index = 0;
+	//Cast the message to TPlaneNotification
+    TCFSubConnControlClient::TPlaneNotification& paramsChanged = message_cast<TCFSubConnControlClient::TPlaneNotification>(iContext.iMessage);
+    
+	//Obtain the pointer to CEventParamsGranted class from the message
+    const CEventParamsGranted * event = static_cast<const CEventParamsGranted*>(paramsChanged.iRefCountOwnedNotification->Ptr());
+    
+	//Obtain the parameter set
+ 	const XBearerInfo * msg = static_cast<const XBearerInfo *>(event->FindParameterSet(KBearerInfo, index));
+	
+	//Set the bearer type at NetMCPR
+	CTCPReceiveWindowSize* winSizePtr =	const_cast<CTCPReceiveWindowSize *>(static_cast<const CTCPReceiveWindowSize *>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(CTCPReceiveWindowSize::ERealmId,CTCPReceiveWindowSize::iId))));
+	CSAPSetOpt* protOptPtr = const_cast<CSAPSetOpt *>(static_cast<const CSAPSetOpt *>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(CSAPSetOpt::EUid,CSAPSetOpt::ETypeId))));
+	
+	// Set the TCP receive window and maximum value
+	if(winSizePtr && protOptPtr)
+		{
+		winSizePtr->SetTcpWin((const_cast<XBearerInfo*>(msg))->GetBearerType());
+		protOptPtr->UpdateProtocolOption(KSolInetTcp, KSoTcpRecvWinAuto, winSizePtr->GetTcpWin());
+		protOptPtr->UpdateProtocolOption(KSolInetTcp, KSoTcpMaxRecvWin, winSizePtr->GetTcpMaxWin());
+		}
+    
+    //Decrease the ref count
+    paramsChanged.iRefCountOwnedNotification->Close();
+    
+	}
+
+/**
+ * StateTransition which sends request message containing the Parameter bundle to self.
+ * When sent to self, it is sent to the service providers.
+ */
+DEFINE_SMELEMENT(IpCprStates::TSendParamsToSelf, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TSendParamsToSelf::DoL()
+    {
+   	ASSERT( ! iContext.Node().GetParameterBundle().IsNull()); // params initialised already
+	iContext.iNodeActivity->PostRequestTo(iContext.NodeId(), TCFScpr::TGetParamsRequest(iContext.Node().GetParameterBundle()).CRef());
+    }
+    
+    
+/**
+ * StateTransition to send bearer characteristics to data clients. The TCP Receive window size is obtained from 
+ * Lookup Table using the bearer type obtained. Send the window size data clients. In this case, it will be sent 
+ * before TStartDataClient.
+ */
+DEFINE_SMELEMENT(TSendTransportNotificationToDataClients, NetStateMachine::MStateTransition, IpCprStates::TContext)
+void IpCprStates::TSendTransportNotificationToDataClients::DoL()
+	{
+		
+	//Send TTransportNotification message to the data clients. 
+	//Initialise the iter variable which will know all data clients.
+	//Exclude data clients that are ELeaving otherwise the PostMessage() below will panic.
+	
+   	TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData), TClientType(0, TCFClientType::ELeaving));
+	TInt dataCliNum = NULL;
+	RNodeInterface* dataClient = iter[dataCliNum];
+	//Initialise message with window sizes
+	TCFMessage::TTransportNotification message; 
+  
+  	while (dataClient)
+   		{
+		//Post messages to the data client.
+ 		dataClient->PostMessage(iContext.NodeId(), message);
+ 		dataCliNum++;
+ 		dataClient = iter[dataCliNum];
+   		}
+}
+
+#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW