networkcontrol/ipnetworklayer/src/IPProtoCprStates.cpp
changeset 14 b33c3d136b7e
parent 0 af10295192d8
child 12 e9cc36e353d4
--- a/networkcontrol/ipnetworklayer/src/IPProtoCprStates.cpp	Tue Feb 02 01:27:53 2010 +0200
+++ b/networkcontrol/ipnetworklayer/src/IPProtoCprStates.cpp	Fri Apr 16 16:36:59 2010 +0300
@@ -37,12 +37,29 @@
 #include <comms-infras/simpleselectorbase.h>
 #include <commsdattypesv1_1_partner.h>
 #include <es_prot_internal.h>
+#include <elements/nm_messages_errorrecovery.h>
 
 using namespace Messages;
 using namespace MeshMachine;
 using namespace IpProtoCpr;
 using namespace ESock;
 
+DEFINE_SMELEMENT(TProvisionActivation, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TProvisionActivation::DoL()
+    {
+    CIPProtoConnectionProvider& node = iContext.Node();
+    
+    //Trap if memory allocation fails
+    TRAP( node.iProvisionError, node.iSubConnProvisioningInfo = new (ELeave) TDataMonitoringSubConnProvisioningInfo(NULL, NULL));
+    }
+
+DEFINE_SMELEMENT(THandleProvisionError, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void THandleProvisionError::DoL()
+    {
+    //Set node error
+    iContext.iNodeActivity->SetError(iContext.Node().iProvisionError);
+    }
+
 DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
 void TStoreProvision::DoL()
 	{
@@ -83,10 +100,13 @@
     	// 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);
+    	
+    	//this allocation taken care in previous activity entry
+    	//just append here
+    	//TDataMonitoringSubConnProvisioningInfo* subConnProvisioningInfo = new (ELeave) TDataMonitoringSubConnProvisioningInfo(NULL, NULL);
+    	CleanupStack::PushL(node.iSubConnProvisioningInfo);
+    	node.iNodeLocalExtensions.AppendExtensionL(node.iSubConnProvisioningInfo);
+    	CleanupStack::Pop(node.iSubConnProvisioningInfo);
     	
        	// 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
@@ -122,6 +142,85 @@
 		}
 	}
 
+DEFINE_SMELEMENT(TSendStoppedAndGoneDown, NetStateMachine::MStateTransition, IpProtoCpr::TContext)
+void TSendStoppedAndGoneDown::DoL()
+	{
+	ASSERT(iContext.iNodeActivity);
+
+	// stop has been caused by timer expiry, remove self from originators list, because we
+	// are not waiting for TStopped and in certain situations it would arrive after the node has been
+	// destroyed
+	if (iContext.Node().iTimerExpired)
+		{
+		TInt selfidx = iContext.iNodeActivity->FindOriginator(iContext.Node().SelfInterface());
+		ASSERT(selfidx != KErrNotFound);
+		iContext.iNodeActivity->RemoveOriginator(selfidx);
+		}
+		
+	TInt stopCode = KErrCancel;
+    MeshMachine::CNodeActivityBase* activity = iContext.iNodeActivity;
+    
+    if (activity && activity->Error() != KErrNone)
+        {
+        stopCode = activity->Error();
+        activity->SetError(KErrNone);
+        }
+
+	// Could be TStop, TStopped or TDataClientStopped (usually TStopped)
+	if  ( (iContext.iMessage.IsMessage<TCFServiceProvider::TStopped>()) ||
+		(iContext.iMessage.IsMessage<TCFServiceProvider::TStop>()) ||
+		(iContext.iMessage.IsMessage<TCFDataClient::TStopped>()) ||
+		(iContext.iMessage.IsMessage<TCFDataClient::TStop>()) )
+		{
+		stopCode = static_cast<const Messages::TSigNumber&>(iContext.iMessage).iValue;
+		}
+	else if ( (iContext.iMessage.IsMessage<TCFControlClient::TGoneDown>()) ||
+		(iContext.iMessage.IsMessage<TCFControlProvider::TDataClientGoneDown>()) )
+		{
+		stopCode = static_cast<const Messages::TSigNumberNumber&>(iContext.iMessage).iValue1;
+		}
+	else if ( iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>() )
+		{
+		// Action must be propagate or there is no error code (your activity flow is faulty)!
+		const Messages::TSigErrResponse& sig = static_cast<const Messages::TSigErrResponse&>(iContext.iMessage);
+		__ASSERT_DEBUG(sig.iErrResponse.iAction == Messages::TErrResponse::EPropagate, User::Invariant());
+   		stopCode = sig.iErrResponse.iError;
+		}
+
+	TCFServiceProvider::TStopped msg(stopCode);
+	iContext.iNodeActivity->PostToOriginators(msg);
+
+    const TProviderInfo& providerInfo = static_cast<const TProviderInfoExt&>(iContext.Node().AccessPointConfig().FindExtensionL(
+            STypeId::CreateSTypeId(TProviderInfoExt::EUid, TProviderInfoExt::ETypeId))).iProviderInfo;
+
+	TCFControlClient::TGoneDown goneDown(stopCode, providerInfo.APId());
+	TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl));
+    CNodeActivityBase* startActivity = iContext.Node().FindActivityById(ECFActivityStart);
+
+    for (TInt i = 0; iter[i]; i++)
+		{
+		//Send TGoneDown to every Ctrl client except
+		// * the originator (who would be recieving TStopped)
+		// * originators of the start activity (these will be errored separately)
+        if (iContext.iNodeActivity && iContext.iNodeActivity->FindOriginator(*iter[i]) >= 0)
+            {
+            continue; // ControlClient is a Stop originator
+            }
+		
+        // So far the control client is not a Stop originator
+        if (startActivity == NULL || startActivity->FindOriginator(*iter[i]) == KErrNotFound)
+			{
+            // ControlClient is not a Start originator
+			iter[i]->PostMessage(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), goneDown);
+			}
+		}
+
+	if (iContext.iNodeActivity)
+    	{
+        iContext.iNodeActivity->SetError(KErrNone);
+    	}
+	}
+
 DEFINE_SMELEMENT(TAwaitingDataMonitoringNotification, NetStateMachine::MState, IpProtoCpr::TContext)
 TBool TAwaitingDataMonitoringNotification::Accept()
 	{