datacommsserver/esockserver/ssock/ss_connstates.cpp
changeset 0 dfb7c4ff071f
child 1 21d2ab05f085
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/ss_connstates.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1720 @@
+// Copyright (c) 2005-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:
+//
+
+#include "SS_conn.H"
+#include "ss_connstates.h"
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_coreprstates.h>
+#include <comms-infras/ss_corepractivities.h>
+#include "ss_subconn.h"
+#include <comms-infras/ss_mcprnodemessages.h>
+#include <elements/sm_core.h>
+#include <commdbconnpref.h> //TCommDbConnPref
+#include <ss_glob.h> //TCommDbConnPref
+#include <connpref.h> //TConnPrefList
+#include <etelpckt.h>
+#include <comms-infras/metadata.h>
+#include <comms-infras/esock_params.h> //TConnAPPref
+#include <comms-infras/esock_params_internal.h> //TConnCSRPref
+
+#include <comms-infras/es_connectionservparameterbundle.h> // CConnectionServParameterBundle
+#include <comms-infras/es_accesspointstatus.h> // TAccessPointStatusFilter
+#include <comms-infras/cs_connservparams.h> // XAccessPointGenericParameterSet
+#include <comms-infras/cs_connservparams_internal.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <es_enum_internal.h>
+#include <nifvar_internal.h>
+#endif
+
+#include <elements/nm_messages_child.h>
+#include <elements/nm_messages_peer.h>
+#include <comms-infras/ss_nodemessages_dataclient.h>
+#include <comms-infras/ss_nodemessages_legacy.h>
+#include <comms-infras/ss_nodemessages_tiermanager.h>
+#include <comms-infras/ss_nodemessages_serviceprovider.h>
+#include <comms-infras/ss_nodemessages_internal_esock.h>
+#include <comms-infras/ss_nodemessages_selector.h>
+#include <comms-infras/ss_nodemessages_factory.h>
+#include <comms-infras/ss_nodemessages_tiermanagerfactory.h>
+
+#define SYMBIAN_NETWORKING_UPS
+
+#ifdef SYMBIAN_NETWORKING_UPS
+#include <comms-infras/ss_upsaccesspointconfigext.h>
+#include <comms-infras/upsmessages.h>
+#endif
+
+#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_ESockSSockscnsts, "ESockSSockscnsts");
+#endif
+
+using namespace ESock;
+using namespace SubSessActivities;
+using namespace NetStateMachine;
+using namespace ConnStates;
+using namespace ConnActivities;
+using namespace ConnectionServ;
+using namespace Elements;
+using namespace Messages;
+using namespace MeshMachine;
+
+//#ifdef LOG
+//	#define KESockActivityTag KESockCoreProviderTag
+//	_LIT8(KESockActivitySubTag, "esockactivity");
+//#endif
+
+_LIT (KCConnectionPanic,"CConnectionPanic");
+
+void ConnPanic(TInt aCode)
+	{
+	User::Panic(KCConnectionPanic, aCode);
+	}
+
+//
+//Start
+
+DEFINE_SMELEMENT(ConnStates::TErrorIfAlreadyStartedAttached, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TErrorIfAlreadyStartedAttached::DoL()
+	{
+	__ASSERT_DEBUG((subsessmessage_cast<ECNStart>(&iContext.iMessage))
+		|| (subsessmessage_cast<ECNAttach>(&iContext.iMessage)),
+			ConnPanic(KPanicIncorrectMessage));
+	RNodeInterface* sp = iContext.Node().ServiceProvider();
+	User::LeaveIfError(sp? KErrAlreadyExists : KErrNone);
+	}
+
+DEFINE_SMELEMENT(ConnStates::TParseECNStart, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TParseECNStart::DoL()
+	{
+	__ASSERT_DEBUG((subsessmessage_cast<ECNStart>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	ConnActivities::CStartAttachActivity& ac = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+    if (ac.Function() == ECNSetStartPrefs)
+    	{
+        //Extract preferences if ECNSetStartPrefs
+    	TConnPref prefs;
+		ac.ReadL(0, prefs);
+
+   		if(prefs.ExtensionId() != TConnPref::EConnPrefEComList)
+  			{
+  			ac.SelectionPrefs().SetPrefs(prefs);
+  			}
+  		else
+  			{
+  			RBuf8 buffer;
+  			TInt length = ac.GetDesLengthL(0);
+  			buffer.CreateL(length);
+  			CleanupClosePushL(buffer);
+  			ac.ReadL(0, buffer);
+
+  			TConnPrefList* prefsList = TConnPrefList::NewL();
+  			CleanupStack::PushL(prefsList);
+  			TPtrC8 ptr(buffer);
+  			TInt ret = prefsList->Load(ptr);
+  			User::LeaveIfError(ret);
+
+  			//This loop is used to check that there is no more than 1 instance
+  			//of TConnAPPref in the list passed to the CSR. This is not allowed
+  			//(as it may have adverse effects in the construction of the stack)
+  			//KErrArugment is returned if there is more than 1 instance present
+  			TInt instances = 0;
+  			for(TInt i=0; i<prefsList->Count(); i++)
+  				{
+  				TConnAPPref* pref = smetadata_cast<TConnAPPref>((*prefsList)[i]);
+  				if(pref)
+  				    {
+  					instances++;
+  				    }
+  				}
+  			if(instances > 1)
+  			    {
+  				User::Leave(KErrArgument);
+  			    }
+
+  			TConnCSRPref* csr = TConnCSRPref::NewL();
+  			CleanupStack::PushL(csr);
+  			ac.SetCSRPreferences(csr);
+  			csr->SetScope(TSelectionPrefs::EExplicitConnection);
+  			prefsList->AppendL(csr);
+
+  			ac.SelectionPrefs().SetPrefs(*prefsList);
+    		ac.SetConnPrefList(prefsList);
+
+    		CleanupStack::Pop(csr);
+    		CleanupStack::Pop(prefsList);
+    		CleanupStack::PopAndDestroy(&buffer);
+    		}
+		
+		// Complete the ECNSetStartPrefs, activity will be held until the 2nd IPC of the Start with Prefs
+   		// call is received. Null iSubSession so that the 2nd IPC can be aquired by the activity.
+   		ac.iMessage.Complete(KErrNone);
+   		ac.iSubSession = NULL;
+		}
+    else
+        {
+        ac.SetSelectionScope(TSelectionPrefs::EExplicitConnection);
+        }
+	}
+
+DEFINE_SMELEMENT(ConnStates::TSendStartingSelectionStateChange, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TSendStartingSelectionStateChange::DoL()
+	{
+	//Send the relevant progress (don't use ReceivedL or you will warp), also use Null Activity id.
+	RNodeInterface::OpenPostMessageClose(iContext.NodeId(), iContext.NodeId(), TCFMessage::TStateChange(TStateChange(KStartingSelection,KErrNone)).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TClearProgressQueue, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TClearProgressQueue::DoL()
+	{
+	iContext.Node().iProgressQueue.Reset();		// clear progress notification cache
+	iContext.Node().ResetLastProgressError();	// clear last progress in error
+	// Initialise iLastProgress with an invalid progress rather than 0 (which is actually KConnectionUninitialised)
+	// otherwise we can end up unintentionally filtering out a KConnectionUninitialised progress.
+	const TInt KInvalidProgress = -1;
+	iContext.Node().iLastProgress = TStateChange(KInvalidProgress, 0);
+	iContext.Node().iLastProgressError = TStateChange();
+	}
+
+DEFINE_SMELEMENT(ConnStates::TRequestCSRCreation, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TRequestCSRCreation::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	__ASSERT_DEBUG(static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).CSR().IsNull(), ConnPanic(KPanicExpectedNoCSR));
+	iContext.iNodeActivity->PostRequestTo(SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)), TCFInternalEsock::TCreateCSR(iContext.Node().iTierId).CRef(), EFalse);
+	}
+
+DEFINE_SMELEMENT(ConnStates::TProcessCSRCreation, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessCSRCreation::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	ConnActivities::CStartAttachActivity& ac = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+	__ASSERT_DEBUG(ac.CSR().IsNull(), User::Panic(KSpecAssert_ESockSSockscnsts, 1));
+	ac.SetCSR(message_cast<TCFInternalEsock::TCSRCreated>(iContext.iMessage).iNodeId);
+
+	
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), ac.CSR(),
+		TCFMessage::TProvisionConnectionInfo(iContext.Node().ConnectionInfo()).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TSelectMetaPlane, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TSelectMetaPlane::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	ConnActivities::CStartAttachActivity& ac = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+    //Diagnostic only. If attach then it must be ESelectFromExisting
+    __ASSERT_DEBUG(!iContext.Node().IsMonitor()
+    	|| ac.SelectionPrefs().Scope() & TSelectionPrefs::ESelectFromExisting, User::Panic(KSpecAssert_ESockSSockscnsts, 2));
+
+	if(ac.SelectionPrefs().Prefs().ExtensionId() != TConnPref::EConnPrefEComList)
+		{
+		ac.SelectionPrefs().SetSubSessionUniqueId(iContext.Node().UniqueId());
+		iContext.iNodeActivity->PostRequestTo(
+			ac.CSR(),
+			TCFSelector::TSimpleSelect(ac.SelectionPrefs()).CRef()
+			);
+		}
+	else
+		{
+		ac.CSRPreferences()->SetSubSessionUniqueId(iContext.Node().UniqueId());
+		RConnPrefList handle;
+		handle.Open(ac.ConnPrefList());
+
+		iContext.iNodeActivity->PostRequestTo(
+			ac.CSR(),
+			TCFSelector::TSelect(handle).CRef()
+			);
+		}
+	}
+
+DEFINE_SMELEMENT(ConnStates::TSendFinishedSelectionStateChange, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TSendFinishedSelectionStateChange::DoL()
+	{
+	//Send the relevant progress (don't use ReceivedL or you will warp), also use Null Activity id.
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.NodeId(),
+		TCFMessage::TStateChange(TStateChange(KFinishedSelection,KErrNone)).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TJoinReceivedCpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TJoinReceivedCpr::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	__ASSERT_DEBUG(iContext.Node().ServiceProvider()==NULL, ConnPanic(KPanicExpectedNoServiceProvider));
+
+	TCFDataClient::TBindTo& bt = message_cast<TCFDataClient::TBindTo>(iContext.iMessage);
+    iContext.Node().AddClientL(bt.iNodeId, TClientType(TCFClientType::EServProvider, TCFClientType::EActive));
+
+    //If this is attach, we need to see if we are a monitor or not
+    TClientType clientType(TCFClientType::ECtrl);
+
+    TUint selPrefs = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Flags();
+    if (selPrefs & TSelectionPrefs::EMonitor)
+    	{
+		clientType.SetFlags(TCFClientType::EMonitor);
+    	iContext.Node().iIsMonitor = ETrue;
+    	}
+
+	// If it is an attach set the flag cause it is used by NetUPS to check if a JoinRequest comes from an RConnection::Attach
+	if (selPrefs & TSelectionPrefs::EAttach)
+    	{
+		clientType.SetFlags(TCFClientType::EAttach);
+    	}
+    iContext.iNodeActivity->PostRequestTo(bt.iNodeId,
+    	TCFServiceProvider::TJoinRequest(iContext.NodeId(), clientType).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TJoinReceivedSCpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TJoinReceivedSCpr::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	__ASSERT_DEBUG(iContext.iPeer == iContext.Node().ServiceProvider(), ConnPanic(KPanicExpectedNoServiceProvider));
+
+	TCFServiceProvider::TCommsBinderResponse& br = message_cast<TCFServiceProvider::TCommsBinderResponse>(iContext.iMessage);
+    iContext.Node().AddClientL(br.iNodeId, TClientType(TCFClientType::EServProvider, TCFClientType::EDefault));
+
+    //If this is attach, we need to see if we are a monitor or not
+    TCFClientType clientType(TCFClientType::ECtrl);
+
+    TUint selPrefs = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Flags();
+    if (selPrefs & TSelectionPrefs::EMonitor)
+    	{
+		clientType.SetFlags(TCFClientType::EMonitor);
+    	}
+
+	// If it is an attach set the flag cause it is used by NetUPS to check if a JoinRequest comes from an RConnection::Attach
+	if (selPrefs & TSelectionPrefs::EAttach)
+    	{
+		clientType.SetFlags(TCFClientType::EAttach);
+    	}
+
+    iContext.iNodeActivity->PostRequestTo(br.iNodeId,
+    	TCFServiceProvider::TJoinRequest(iContext.NodeId(), clientType).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TJoinReceivedMcpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TJoinReceivedMcpr::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	__ASSERT_DEBUG(iContext.Node().ServiceProvider()==NULL, ConnPanic(KPanicExpectedNoServiceProvider));
+
+	TCFSelector::TSelectComplete& sc = message_cast<TCFSelector::TSelectComplete>(iContext.iMessage);
+	iContext.Node().AddClientL(sc.iNodeId,TClientType(TCFClientType::EServProvider, TCFClientType::EAvailabilityProvider));
+
+
+	iContext.iNodeActivity->PostRequestTo(sc.iNodeId,
+		TCFServiceProvider::TJoinRequest(iContext.NodeId(), TCFClientType(TCFClientType::ECtrl)).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TRequestCommsBinder, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TRequestCommsBinder::DoL()
+	{
+    __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+    RNodeInterface* sp = iContext.Node().ServiceProvider();
+    __ASSERT_DEBUG(sp, ConnPanic(KPanicNoServiceProvider));
+    iContext.iNodeActivity->PostRequestTo(*sp,
+    	TCFServiceProvider::TCommsBinderRequest(TSubConnOpen::EAttachToDefault).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TRequestCommsBinderFromMcpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TRequestCommsBinderFromMcpr::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EAvailabilityProvider));
+	RNodeInterface* mcpr = iter[0];
+	__ASSERT_DEBUG(mcpr, ConnPanic(KPanicNoAvailabilityProvider));
+	iContext.iNodeActivity->PostRequestTo(*mcpr,
+		TCFServiceProvider::TCommsBinderRequest().CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TProcessBinderResponseForCpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessBinderResponseForCpr::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	__ASSERT_DEBUG(iContext.Node().ServiceProvider()==NULL, ConnPanic(KPanicExpectedNoServiceProvider));
+
+	TCFServiceProvider::TCommsBinderResponse& br = message_cast<TCFServiceProvider::TCommsBinderResponse>(iContext.iMessage);
+
+	iContext.Node().AddClientL(br.iNodeId, TClientType(TCFClientType::EServProvider, TCFClientType::EActive));
+
+	//If this is attach, we need to see if we are a monitor or not
+	TCFClientType clientType;
+
+	TUint selPrefs = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Flags();
+	if (selPrefs & TSelectionPrefs::EMonitor)
+		{
+		clientType.SetFlags(TCFClientType::EMonitor);
+		iContext.Node().iIsMonitor = ETrue;
+		}
+
+	if (selPrefs & TSelectionPrefs::EAttach)
+		{
+		clientType.SetFlags(TCFClientType::EAttach);
+		}
+	
+	iContext.iNodeActivity->PostRequestTo(br.iNodeId,
+		TCFServiceProvider::TJoinRequest(iContext.NodeId(), clientType).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TStartConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TStartConnection::DoL()
+	{
+	RNodeInterface* cpr = iContext.Node().ServiceProvider();
+	__ASSERT_DEBUG(cpr, ConnPanic(KPanicNoServiceProvider));
+
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+    iContext.iNodeActivity->PostRequestTo(*cpr, TCFServiceProvider::TStart().CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TErrorOrCancel, NetStateMachine::MStateFork, ConnStates::TContext)
+/**
+If the activity has been cancelled, return KCancelTag else return KErrorTag
+ */
+TInt ConnStates::TErrorOrCancel::TransitionTag()
+	{
+	if (iContext.Activity()->Error() == KErrCancel)
+		{
+		return ConnActivities::CStartAttachActivity::KCancelTag;
+		}
+	else
+		{
+		__ASSERT_DEBUG(iContext.Activity()->Error() != KErrNone, User::Panic(KSpecAssert_ESockSSockscnsts, 3));		// meant to be called in error conditions only
+		return KErrorTag;
+		}
+	}
+
+//
+//Attach
+DEFINE_SMELEMENT(ConnStates::TParseECNAttach, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TParseECNAttach::DoL()
+	{
+	__ASSERT_DEBUG((subsessmessage_cast<ECNAttach>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	ConnActivities::CStartAttachActivity& ac = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+	//Read preferences
+	const TUint KMaxConnectionInfoLength = 32;
+	TBuf8<KMaxConnectionInfoLength> info;
+	ac.ReadL(1,info);
+	if (info.Length() < KConnInfoPart)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	TUint monitorMode = (RConnection::TConnAttachType)ac.Int0() == RConnection::EAttachTypeMonitor?
+		TSelectionPrefs::EMonitor : 0;
+	// The attach flag should always be set since it is used by NetUPS to check if a JoinRequest comes from an RConnection::Attach
+	ac.SetSelectionFlags(monitorMode | TSelectionPrefs::EAttach);
+
+	TConnArgBase& connInfo = *((TConnArgBase*)&info[0]);
+	if (connInfo.Version() < KConnArgVersion3)
+		{
+        TConnectionInfo& connI = static_cast<TConnectionInfo&>(connInfo);
+        TCommDbConnPref pref;
+		pref.SetIapId(connI.iIapId);
+    	ac.SelectionPrefs().SetPrefs(pref);
+    	ac.SetSelectionScope(TSelectionPrefs::ESelectFromExisting | TSelectionPrefs::EExplicitConnection);
+		}
+	else
+		{
+		__ASSERT_DEBUG(connInfo.Version() == KConnArgVersion3, User::Panic(KSpecAssert_ESockSSockscnsts, 4)); //Currently no support for > KConnArgVersion3;
+		TConnProviderInfo& provinfo = static_cast<TConnProviderInfo&>(connInfo);
+		__ASSERT_DEBUG(iContext.Node().iTierId.iUid == provinfo.iInfo[0], User::Panic(KSpecAssert_ESockSSockscnsts, 5));
+    	ac.SelectionPrefs().SetPrefs(TConnProviderInfoPref(provinfo));
+    	ac.SetSelectionScope(TSelectionPrefs::ESelectFromExisting);
+		}
+	}
+
+DEFINE_SMELEMENT(ConnStates::TCompleteLegacyAttach, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TCompleteLegacyAttach::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	iContext.Node().iLegacyConnection.CompleteAttachL(static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs());
+	}
+
+
+//
+//WaitForIncoming
+DEFINE_SMELEMENT(ConnStates::TRequestIncomingConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TRequestIncomingConnection::DoL()
+	{
+	__ASSERT_DEBUG((subsessmessage_cast<ECNWaitForIncoming>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+	RNodeInterface* sp = iContext.Node().ServiceProvider();
+	User::LeaveIfError(sp ? KErrNone : KErrNotReady);
+
+    iContext.iNodeActivity->PostRequestTo(*sp,
+    	TCFServiceProvider::TCommsBinderRequest(TSubConnOpen::EWaitForIncoming).CRef());
+	}
+
+DEFINE_SMELEMENT(ConnStates::TProcessIncomingConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessIncomingConnection::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+    CSubConnection* waitingSubConn = iContext.Node().Session()->CSubConnectionFromHandle(static_cast<CESockClientActivityBase&>(*iContext.iNodeActivity).Int0());
+	User::LeaveIfError(waitingSubConn != NULL ? KErrNone : KErrCancel);
+
+    TCFServiceProvider::TCommsBinderResponse& binderResp = message_cast<TCFServiceProvider::TCommsBinderResponse>(iContext.iMessage);
+    iContext.iNodeActivity->PostRequestTo(waitingSubConn->Id(),
+        TCFDataClient::TBindTo(binderResp.iNodeId).CRef());
+	}
+
+
+//
+//Stop
+DEFINE_SMELEMENT(ConnStates::TSendStopConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TSendStopConnection::DoL()
+	{
+	__ASSERT_DEBUG((subsessmessage_cast<ECNStop>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	CESockClientActivityBase& ac = static_cast<CESockClientActivityBase&>(*iContext.iNodeActivity);
+
+	//Convert the received enum (the stop type) into an error code that will be passed to the interface clients
+	TInt stopCode = KErrCancel;
+	switch (ac.Int0())
+		{
+		case RConnection::EStopNormal:
+			stopCode = KErrCancel;
+			break;
+		case RConnection::EStopAuthoritative:
+			stopCode = KErrConnectionTerminated;
+			break;
+		default:
+			__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSockscnsts, 6));
+		}
+
+	RNodeInterface* sp = iContext.Node().ServiceProvider();
+	if(sp)
+		{ // We can only post the 'stop' if we've got a service provider and its not already leaving (e.g., gone down).
+		if (!(sp->Flags() & TClientType::ELeaving))
+		    {
+			sp->PostMessage(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), TCFServiceProvider::TStop(stopCode).CRef());
+		    }
+		else
+			{
+			MESH_LOG((KESockConnectionTag, _L8("ConnStates::TSendStopConnection:\tDoL - IGNORING POST!")));
+			}
+		}
+	else
+		{ // Otherwise just set the activity idle and bail out.
+		iContext.Activity()->SetIdle();
+		}
+	}
+
+DEFINE_SMELEMENT(ConnStates::TConnectionSendStopSCPR, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TConnectionSendStopSCPR::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+
+	TInt stopCode = 0;
+
+	switch (static_cast<CESockClientActivityBase*>(iContext.iNodeActivity)->Int1())
+		{
+	case RConnection::EStopNormal:
+		stopCode = KErrCancel;
+		break;
+
+	case RConnection::EStopAuthoritative:
+		stopCode = KErrConnectionTerminated;
+		break;
+
+	default:
+		__ASSERT_DEBUG( false , User::Panic(KSpecAssert_ESockSSockscnsts, 7)); // CConnection should have verified the parameters before stopping the subconnection
+		}
+
+	// Send the stop message to the subconnection.
+	RNodeInterface* scpr = static_cast<CConnection&>(iContext.Node()).DefaultSubConnectionServiceProvider();
+	__ASSERT_DEBUG( scpr , User::Panic(KSpecAssert_ESockSSockscnsts, 8)); // subconnection must exist or the stop operation should not have been initiated
+	scpr->PostMessage(
+		TNodeCtxId(iContext.ActivityId(), iContext.NodeId()),
+		TCFServiceProvider::TStop(stopCode).CRef()
+		);
+	}
+
+DEFINE_SMELEMENT(ConnStates::TCancelStartOrAttachConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TCancelStartOrAttachConnection::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+
+	if (iContext.Node().FindActivityById(ECFActivityStart))
+		{
+		RClientInterface::OpenPostMessageClose(
+			TNodeCtxId(ECNStart, iContext.NodeId()),
+			TNodeCtxId(ECNStart, iContext.NodeId()),
+			TEBase::TCancel().CRef());
+		}
+	else if (iContext.Node().FindActivityById(ECFActivityConnectionAttach))
+		{
+		RClientInterface::OpenPostMessageClose(
+			TNodeCtxId(ECNAttach, iContext.NodeId()),
+			TNodeCtxId(ECNAttach, iContext.NodeId()),
+			TEBase::TCancel().CRef());
+		}
+	}
+
+//
+//Close
+DEFINE_SMELEMENT(ConnStates::TDetachDataClients, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TDetachDataClients::DoL()
+	{
+	while (ETrue)
+    	{
+    	TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData));
+    	RNodeInterface* client = iter[0];
+    	if (client)
+        	{
+#if defined(__GCCXML__)
+        	CSubConnection& subconn = *reinterpret_cast<CSubConnection*>(&client->RecipientId().Node());
+#else
+        	CSubConnection& subconn = *mcfnode_cast<CSubConnection>(&client->RecipientId().Node());
+#endif
+        	iContext.Node().RemoveClient(subconn.Id());
+        	subconn.RemoveClient(iContext.NodeId());
+        	}
+    	else
+        	{
+        	break;
+        	}
+    	}
+	}
+
+DEFINE_SMELEMENT(ConnStates::TStartOrAttachActive, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt ConnStates::TStartOrAttachActive::TransitionTag()
+	{
+	if (iContext.Node().FindActivityById(ECFActivityStart) || iContext.Node().FindActivityById(ECFActivityConnectionAttach))
+		{
+		return MeshMachine::KActiveTag;
+		}
+	return KNoTag;
+	}
+
+DEFINE_SMELEMENT(ConnStates::TAwaitingGoneDown, NetStateMachine::MState, ConnStates::TContext)
+TBool ConnStates::TAwaitingGoneDown::Accept()
+	{
+	if (!iContext.iMessage.IsMessage<TCFControlClient::TGoneDown>())
+    	{
+    	return EFalse;
+    	}
+
+    //TODO - fix this defect:
+    //1) TGoneDown should not be sent when stopping or closing
+    //2) FindActivityById(ECFActivityStop) is not safe
+    //3) why the condition iContext.Node().ServiceProvider()? Who can be sending TGoneDown if not the service provider?
+    bool stoppingOrClosing = iContext.Node().FindActivityById(ECFActivityStop) || iContext.Node().FindActivityById(ECFActivityDestroy);
+    if (!stoppingOrClosing && iContext.Node().ServiceProvider() &&
+        *iContext.Node().ServiceProvider() == iContext.iSender)
+        {
+        return ETrue;
+        }
+    iContext.iMessage.ClearMessageId();
+    return EFalse;
+	}
+
+DEFINE_SMELEMENT(ConnStates::TGenerateConnectionUpProgress, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TGenerateConnectionUpProgress::DoL()
+	{
+	TCFMessage::TStateChange msg(TStateChange(KConnectionUp, KErrNone));
+	RNodeInterface::OpenPostMessageClose(iContext.Node().Id(), iContext.Node().Id(), msg);
+	}
+
+DEFINE_SMELEMENT(ConnStates::TGenerateConnectionDownProgress, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TGenerateConnectionDownProgress::DoL()
+	{
+	// Do not self-post a message if there is a pending ConnectionClose activity.  When the ConnectionGoingDown
+	// activity (calling this method) terminates, the ConnectionClose activity unparks (being synchronised
+	// against ConnectionGoingDown), the CConnection is destroyed, and the subsequent self-dispatch
+	// will panic.
+    __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	TInt error = iContext.iNodeActivity->Error();
+
+	if (error == KErrNone && iContext.iMessage.IsMessage<TCFServiceProvider::TStopped>())
+		{
+		error = message_cast<TCFServiceProvider::TStopped>(iContext.iMessage).iValue;
+		}
+
+    __ASSERT_DEBUG(error != KErrNone, ConnPanic(KPanicIncorrectState));
+	
+	if (iContext.Node().CountActivities(ECFActivityDestroy) == 0)
+		{
+		TCFMessage::TStateChange msg(TStateChange(KConnectionDown, error));
+		CConnection& cc = iContext.Node();
+		RNodeInterface::OpenPostMessageClose(cc.Id(), cc.Id(), msg);
+		}
+	}
+
+//
+//Progress & Progress Request
+DEFINE_SMELEMENT(ConnStates::TProcessStateChange, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessStateChange::DoL()
+	{
+	TStateChange& progress = message_cast<TCFMessage::TStateChange>(iContext.iMessage).iStateChange;
+
+	//Check whether KDataTransferUnblocked is received and if yes, then traslate it to KConnectionUp (== KLinkLayerOpen)
+	// the log only sees the translated version, this goes into the queue, so it alright I suppose.
+	if (progress.iStage == KDataTransferUnblocked )
+		{
+		progress.iStage = KConnectionUp;	// KLinkLayerOpen
+		}
+
+	LOG( ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tProgressNotification(TInt aStage %d, TInt aError %d)"),
+		&(iContext.Node()), progress.iStage, progress.iError) );
+
+	//Diagnostic assertion.
+	//If ECFActivityConnectionStateChangeRequest is running, it has not been
+	//presented with the TStateChange message (channel activity id != 0?) which is a serious mistake.
+	__ASSERT_DEBUG(iContext.Node().CountActivities(ECFActivityConnectionStateChangeRequest)==0, User::Panic(KSpecAssert_ESockSSockscnsts, 9));
+
+	CConnection& cc = iContext.Node();
+	if (cc.iLastProgress == progress)
+		{
+		return; //ignore this duplicate
+		}
+	cc.iLastProgress = progress;
+
+	if (progress.iError != KErrNone)
+		{
+        cc.iLastProgressError = progress; //Save last progress in error for use by LastProgressErrorL()
+    	}
+
+	#ifdef ESOCK_LOGGING_ACTIVE
+		// Check to see if the progress queue is full causing older progress to be discarded.
+		// This has the potential to cause problems if a critical progress item is lost.
+		// Normally the queue is large enough such that this doesn't happen but this log entry
+		// serves as a warning if it ever does.
+		if( cc.iProgressQueue.IsFull() )
+			{
+			LOG( ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tThe maximum progress queue size of %d has been exceeded - discarding old progress to make space for new item"), this, KMaxProgressQueueLength); )
+			}
+	#endif
+
+	//Add the progress to queue
+	cc.iProgressQueue.Enque(progress);
+	}
+
+DEFINE_SMELEMENT(ConnStates::TProcessProgressRequest, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessProgressRequest::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	CESockClientActivityBase& ac = static_cast<CESockClientActivityBase&>(*iContext.iNodeActivity);
+	TUint selectedProgressStage = ac.Int1();
+
+	TStateChange progress;
+	TBool found = EFalse;
+
+	//Are we here as a result of receiving TStateChange (rather than ECNProgressNotification)?
+	TCFMessage::TStateChange* msg = message_cast<TCFMessage::TStateChange>(&iContext.iMessage);
+	if (msg)
+		{ //Yes, we have been triggered by a TStateChange message
+		//Check if this is the progress we are waiting for, otherwise dump the progress
+		//Check whether KDataTransferUnblocked is received and if yes, then traslate it to KConnectionUp (== KLinkLayerOpen)
+		if (msg->iStateChange.iStage == KDataTransferUnblocked )
+			{
+			msg->iStateChange.iStage = KConnectionUp;	// KLinkLayerOpen
+			}
+		if (selectedProgressStage == KConnProgressDefault
+			|| selectedProgressStage == msg->iStateChange.iStage
+				|| KErrNone != msg->iStateChange.iError)
+			{
+			progress = msg->iStateChange;
+			found = ETrue;
+			}
+		}
+	else
+		{ //No, we must have been triggered by a ECNProgressNotification message
+		__ASSERT_DEBUG((subsessmessage_cast<ECNProgressNotification>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+
+		//Process the queue looking for the progress of interest
+		found = iContext.Node().iProgressQueue.Deque(progress);
+		if (found && selectedProgressStage != KConnProgressDefault)
+			{
+			// For a selected progress request, dequeue entries until we find one which
+			// matches the criteria.  If we dequeue all entries, fall through without
+			// completing the message.  It it not considered useful to retain un-matching
+			// entries on the queue if a selected progress request is pending.
+			while (found)
+				{
+				if (progress.iStage == selectedProgressStage || progress.iError != KErrNone)
+					{
+					break;
+					}
+				found = iContext.Node().iProgressQueue.Deque(progress);
+				}
+			}
+		}
+
+	if (found)
+		{
+		//We have found a progress of interest, finish
+		TPckg<TStateChange> progressPkg(progress);
+		ac.WriteL(0,progressPkg);
+		ac.SetIdle(); //We are done
+		}
+	}
+
+
+//
+//Legacy enumeration
+DEFINE_SMELEMENT(ConnStates::TAwaitingEnumResponse, NetStateMachine::MState, ConnStates::TContext)
+TBool ConnStates::TAwaitingEnumResponse::Accept()
+	{
+	return iContext.iMessage.IsMessage<TCFInternalEsock::TLegacyConnectionEnumResponse>();
+	}
+
+DEFINE_SMELEMENT(ConnStates::TProcessEnumResponse, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessEnumResponse::DoL()
+	{
+	TCFInternalEsock::TLegacyConnectionEnumResponse& msg = message_cast<TCFInternalEsock::TLegacyConnectionEnumResponse>(iContext.iMessage);
+	iContext.Node().iLegacyConnection.CompleteDataPlaneEnumeration(address_cast<TNodeId>(iContext.iSender), msg.iValue1, reinterpret_cast<HBufC8*>(msg.iValue2), msg.iValue3);
+	}
+
+
+//
+//CStartAttachActivity
+MeshMachine::CNodeActivityBase* ConnActivities::CStartAttachActivity::NewWaitForIncomingConnectionActivityL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	{
+	//Leave from here will complete the client message
+	User::LeaveIfError(aNode.CountActivities(ECFActivityStart)? KErrInUse : KErrNone);
+	User::LeaveIfError(aNode.CountActivities(ECFActivityConnectionAttach)? KErrInUse : KErrNone);
+
+	// When waiting for an incoming connection we will additionally check that the connection is already started
+	User::LeaveIfError(aNode.CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) > 0 ? KErrNone : KErrNotReady );
+
+	return new (ELeave) ConnActivities::CStartAttachActivity(aActivitySig,aNode);
+	}
+
+MeshMachine::CNodeActivityBase* ConnActivities::CStartAttachActivity::NewStartConnectionActivityL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	{
+	//Leave from here will complete the client message
+	User::LeaveIfError(aNode.CountActivities(ECFActivityStart)? KErrInUse : KErrNone);
+	User::LeaveIfError(aNode.CountActivities(ECFActivityConnectionAttach)? KErrInUse : KErrNone);
+
+	// When starting a connection we will additionally check that the connection is not already started
+	User::LeaveIfError(aNode.CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) > 0 ? KErrInUse : KErrNone);
+
+	return new (ELeave) ConnActivities::CStartAttachActivity(aActivitySig,aNode);
+	}
+
+ConnActivities::CStartAttachActivity::~CStartAttachActivity()
+	{
+	// Call ABindingActivity base class to send TBindToComplete (before TDestroy)
+	FinalReplyToOriginator(KErrAbort);
+
+	if (!iCSR.IsNull())
+		{
+#ifndef __GCCXML__
+		RNodeInterface::OpenPostMessageClose(TNodeCtxId(ActivityId(), iNode.Id()), iCSR, TEChild::TDestroy().CRef());
+#endif
+		iCSR.SetNull(); // = TNodeId::NullCommsId();
+		}
+
+	if(iConnPrefList)
+		{
+		while(iConnPrefList->Count() != 0)
+			{
+			SMetaData* pref = (*iConnPrefList)[0];
+			if(pref != NULL)
+				delete pref;
+			iConnPrefList->Remove(0);
+			}
+
+		delete iConnPrefList;
+		iConnPrefList = NULL;
+		}
+	}
+
+
+TBool ConnActivities::CStartAttachActivity::Next(MeshMachine::TNodeContextBase& aContext)
+    {
+    // If the connection start preferences were set the activity will have completed the initial IPC and will
+    // now be waiting upon the async ECNStart IPC to arrive before proceeding. The TCFInternalEsock::TSubSess
+    // message will use the IPC number in the activity id part of aContext. MatchSender() will expect the
+    // activity Id and so will never give a match. Here we ensure that our second IPC is matched and accepted.
+    
+    TCFInternalEsock::TSubSess* msg = message_cast<TCFInternalEsock::TSubSess>(&aContext.iMessage);
+    if (!msg || msg->iMessage.Function() != ECNStart)
+        {
+        return CNodeActivityBase::Next(aContext);
+        }
+    
+    MESH_LOG((KESockConnectionTag, _L8("CStartAttachActivity::Next:\tAccepted ECNStart IPC after ECNSetStartPrefs")));
+    TBool nextRet = ACore::Next(&aContext);
+    if(nextRet)
+        {
+        MESH_LOG_ACTIVITY_EXT(KESockConnectionTag, this, &aContext, (_L8("CStartAttachActivity::Next:\tNext->transition")));
+        }
+    return nextRet;
+    }
+
+
+DEFINE_SMELEMENT(CStartAttachActivity::TNoTagOrStartPrefsSetTag, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TNoTagOrStartPrefsSetTag::TransitionTag()
+    {
+    CStartAttachActivity& ac = static_cast<CStartAttachActivity&>(*iContext.iNodeActivity);
+
+    if (ac.Function() == ECNSetStartPrefs)
+        {
+        return CStartAttachActivity::KStartPrefsSetTag | NetStateMachine::EForward;
+        }
+    return MeshMachine::KNoTag | NetStateMachine::EForward;
+    }
+
+DEFINE_SMELEMENT(CStartAttachActivity::TNoTagOrLegacyAttach, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TNoTagOrLegacyAttach::TransitionTag()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	const TConnPref& cp = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Prefs();
+	if (cp.ExtensionId()==TConnPref::EConnPrefCommDb)
+		{//this is legacy attach
+		return CStartAttachActivity::KExecuteLegacyAttach;
+		}
+	return KNoTag;
+	}
+
+DEFINE_SMELEMENT(CStartAttachActivity::TNoTagOrWaitAvailable, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TNoTagOrWaitAvailable::TransitionTag()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	ConnActivities::CStartAttachActivity& activity = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+	TConnPrefList* prefsList = activity.ConnPrefList();
+	if (prefsList)
+		{
+		TBool startAuto = EFalse;
+		for (TInt i = 0; i < prefsList->Count(); i++)
+				{
+				TConnAutoStartPref* pref = smetadata_cast<TConnAutoStartPref>((*prefsList)[i]);
+				if(pref)
+					{
+					startAuto = ETrue;
+					break;
+					}
+				}
+		if (startAuto)
+			{
+			TBool &autoStart = activity.AutoStartPresent();
+			autoStart = ETrue;
+			iContext.iNodeActivity->ClearPostedTo();
+			return KWaitAvailable;
+			}
+
+		}
+	return KNoTag;
+	}
+
+DEFINE_SMELEMENT(CStartAttachActivity::TErrorTagOrWaitAvailableBackward, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TErrorTagOrWaitAvailableBackward::TransitionTag()
+	{
+	__ASSERT_DEBUG((message_cast<TEBase::TError>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	ConnActivities::CStartAttachActivity& activity = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+	if (!activity.AutoStartPresent())
+		{
+		return KErrorTag;
+		}
+
+	TEBase::TError& msg = message_cast<TEBase::TError>(iContext.iMessage);
+	if (msg.iValue == KErrUmtsMaxNumOfContextExceededByNetwork ||
+		msg.iValue == KErrUmtsMaxNumOfContextExceededByPhone)
+		{
+		return KWaitAvailable | NetStateMachine::EBackward;
+		}
+	else
+		{
+		return KErrorTag;
+		}
+	}
+
+DEFINE_SMELEMENT(CStartAttachActivity::TAwaitingAvailableOrError, NetStateMachine::MState, TContext)
+TInt CStartAttachActivity::TAwaitingAvailableOrError::Accept()
+	{
+	if (iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>())
+		{
+		TCFAvailabilityControlClient::TAvailabilityNotification& msg = message_cast<TCFAvailabilityControlClient::TAvailabilityNotification>(iContext.iMessage);
+		if (msg.iAvailabilityStatus.Score() > TAvailabilityStatus::EMinAvailabilityScore)
+			{
+			RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.iSender,
+					TEBase::TCancel().CRef());
+			return ETrue;
+			}
+		return EFalse;
+		}
+	else if (iContext.iMessage.IsMessage<TEBase::TError>())
+		{
+		TEBase::TError* msg = message_cast<TEBase::TError>(&iContext.iMessage);
+		iContext.iNodeActivity->SetError(msg->iValue);
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+
+DEFINE_SMELEMENT(CStartAttachActivity::TSubscribeForAvailability, NetStateMachine::MStateTransition, TContext)
+void CStartAttachActivity::TSubscribeForAvailability::DoL()
+	{
+	__ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+	ConnActivities::CStartAttachActivity& activity = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+	TConnPrefList* connPrefList = activity.ConnPrefList();
+	if (connPrefList && connPrefList->Count()>0)
+		{
+		TBool startAuto = EFalse;
+		for (TInt i = 0; i < connPrefList->Count(); i++)
+				{
+				TConnAutoStartPref* pref = smetadata_cast<TConnAutoStartPref>((*connPrefList)[i]);
+				if(pref)
+					{
+					startAuto = ETrue;
+					break;
+					}
+				}
+		if (startAuto)
+			{
+			TAvailabilitySubscriptionOptions subscriptionOptions;
+			TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EAvailabilityProvider));
+			RNodeInterface* mcpr = iter[0];
+			__ASSERT_DEBUG(mcpr, ConnPanic(KPanicNoAvailabilityProvider));
+			RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), mcpr->RecipientId(),
+				TCFAvailabilityProvider::TAvailabilityNotificationRegistration(subscriptionOptions).CRef());
+			}
+		}
+	}
+
+DEFINE_SMELEMENT(CStartAttachActivity::TAwaitingSelectCompleteOrError, NetStateMachine::MState, TContext)
+TInt CStartAttachActivity::TAwaitingSelectCompleteOrError::Accept()
+	{
+	if (iContext.iMessage.IsMessage<TCFSelector::TSelectComplete>())
+		{
+		return ETrue;
+		}
+	else if(iContext.iMessage.IsMessage<TEBase::TError>())
+		{
+		TEBase::TError& errorMsg = message_cast<TEBase::TError>(iContext.iMessage);
+		iContext.Activity()->SetError(errorMsg.iValue);
+		return ETrue;
+		}
+
+	return EFalse;
+	}
+
+
+#ifdef SYMBIAN_NETWORKING_UPS
+
+DEFINE_SMELEMENT(CStartAttachActivity::TSendPolicyCheckRequestToServiceProvider, NetStateMachine::MStateTransition, ConnStates::TContext)
+void CStartAttachActivity::TSendPolicyCheckRequestToServiceProvider::DoL()
+	{
+	MPlatsecApiExt* platsec = NULL;
+	iContext.Node().ReturnInterfacePtrL(platsec);		// from CConnection
+	// TODO: what to do on an error (see TODO below)
+    __ASSERT_DEBUG(platsec, User::Panic(KSpecAssert_ESockSSockscnsts, 18));
+
+	TProcessId processId;
+	TThreadId threadId;
+	TInt err = platsec->GetProcessAndThreadId(processId, threadId);
+	if (err != KErrNone)
+		{
+		const TNodeId& self = iContext.Node().Id();
+		iContext.Node().SelfInterface().PostMessage(self, TEBase::TError(err).CRef());
+		iContext.Activity()->ClearPostedTo();
+		}
+	else
+		{
+		// KErrCorrupt is a default value for the platsec result.  The platsec result must be filled-in by the provider
+		// and not ESock because only the provider knows the (technology specific) policy to check against.
+		// Destination address is not valid in this context, so it is just a null descriptor.
+
+		const TPolicyCheckRequestParams params(processId, threadId, KErrCorrupt, KNullDesC8(), TUpsDestinationAddrType(ETNone), iContext.NodeId());
+
+		const UpsMessage::TPolicyCheckRequest checkMsg(params);
+
+		RNodeInterface* serviceProvider = iContext.Node().ServiceProvider();
+
+        __ASSERT_DEBUG(serviceProvider, User::Panic(KSpecAssert_ESockSSockscnsts, 19));
+		iContext.Activity()->PostRequestTo(*serviceProvider, checkMsg);
+		}
+	}
+
+DEFINE_SMELEMENT(CStartAttachActivity::TNoTagOrUpsErrorTag, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TNoTagOrUpsErrorTag::TransitionTag()
+	{
+	UpsMessage::TPolicyCheckResponse* policyCheckResponseMsg = message_cast<UpsMessage::TPolicyCheckResponse>(&iContext.iMessage);
+	if (policyCheckResponseMsg && policyCheckResponseMsg->iValue != KErrNone)
+		{
+		iContext.Activity()->SetError(policyCheckResponseMsg->iValue);
+		return KUpsErrorTag;
+		}
+	else
+		{
+		TEBase::TError* errorMsg = message_cast<TEBase::TError>(&iContext.iMessage);
+		// TODO: there is already code for this isn't there?  A template that checks for TError and
+		// sets the activity in error?
+		if (errorMsg)
+			{
+			iContext.Activity()->SetError(errorMsg->iValue);
+			return KUpsErrorTag;
+			}
+		}
+	return KNoTag;
+	}
+#endif
+
+//
+// CTierManagerActivity
+
+MeshMachine::CNodeActivityBase* ConnActivities::CTierManagerActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	{
+	return new(ELeave) ConnActivities::CTierManagerActivity(aActivitySig, aNode);
+	}
+
+// States
+
+DEFINE_SMELEMENT(CTierManagerActivity::TAwaitingTierManager, NetStateMachine::MState, TContext)
+TInt CTierManagerActivity::TAwaitingTierManager::Accept()
+	{
+	if(iContext.iMessage.IsMessage<TCFFactory::TPeerFoundOrCreated>())
+		{
+		TCFFactory::TPeerFoundOrCreated& msg = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
+		iContext.Activity()->iTierManager = msg.iNodeId;
+		iContext.Activity()->ClearPostedTo();
+
+		return ETrue;
+		}
+	else if(iContext.iMessage.IsMessage<TEBase::TCancel>())
+		{
+		iContext.Activity()->SetError(KErrCancel);
+
+		return ETrue;
+		}
+	else if(iContext.iMessage.IsMessage<TEBase::TError>())
+		{
+		// Register the error
+		TEBase::TError& errorMsg = message_cast<TEBase::TError>(iContext.iMessage);
+		iContext.Activity()->SetError(errorMsg.iValue);
+
+		return ETrue;
+		}
+
+	return EFalse;
+	}
+
+DEFINE_SMELEMENT(CTierManagerActivity::TAwaitingJoinComplete, NetStateMachine::MState, TContext)
+TInt CTierManagerActivity::TAwaitingJoinComplete::Accept()
+	{
+	if(iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>())
+		{
+		return ETrue;
+		}
+	else if(iContext.iMessage.IsMessage<TEBase::TCancel>())
+		{
+		iContext.Activity()->SetError(KErrCancel);
+
+		return ETrue;
+		}
+	else if(iContext.iMessage.IsMessage<TEBase::TError>())
+		{
+		// Register the error
+		TEBase::TError& errorMsg = message_cast<TEBase::TError>(iContext.iMessage);
+		iContext.Activity()->SetError(errorMsg.iValue);
+
+		return ETrue;
+		}
+
+	return EFalse;
+	}
+
+// Transitions
+
+DEFINE_SMELEMENT(CTierManagerActivity::TFindTierManager, NetStateMachine::MStateTransition, TContext)
+void CTierManagerActivity::TFindTierManager::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	// Find out if the tier UID has been set.
+	TBool tierUidIsNull = (iContext.Activity()->iTierUid == TUid::Null());
+
+	// Panic in UDEB, Leave in UREL. The tier UID should be set in the derived
+	// class's constructor
+	__ASSERT_DEBUG(!tierUidIsNull, User::Panic(KSpecAssert_ESockSSockscnsts, 10));
+	User::LeaveIfError(tierUidIsNull ? KErrNotReady : KErrNone);
+	TAlwaysFindFactoryQuery query;
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)),
+		 TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, iContext.Activity()->iTierUid, &query).CRef());
+	}
+
+DEFINE_SMELEMENT(CTierManagerActivity::TJoinTierManager, NetStateMachine::MStateTransition, TContext)
+void CTierManagerActivity::TJoinTierManager::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+		TCFServiceProvider::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::EAdministrative)).CRef());
+
+	iContext.Node().AddClientL(iContext.Activity()->iTierManager, TClientType(TCFClientType::EServProvider));
+	}
+
+// This solely exists separately from the other identical-looking version
+//    in this file
+//    ("AllInterfaceNotificationActivity::TLeaveTierManager::DoL()") because
+//    the activities referenced by its TContext have iTierManager
+//    at different offsets. This is because they have different parent
+//    classes and, as such, have different member variable.
+//
+// The terrible thing is, this is usable in the other place,
+//    and builds without complaint... then explodes when it tries
+//    to send messages to a garbage iTierManager.
+//
+//    TAKE CARE OF IT!!!
+DEFINE_SMELEMENT(CTierManagerActivity::TLeaveTierManager, NetStateMachine::MStateTransition, TContext)
+void CTierManagerActivity::TLeaveTierManager::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+		TEChild::TLeft().CRef());
+
+	iContext.Node().RemoveClient(iContext.Activity()->iTierManager);
+	}
+
+//
+// CAllInterfaceNotificationActivity
+
+CNodeActivityBase* ConnActivities::CAllInterfaceNotificationActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	{
+	return new (ELeave) ConnActivities::CAllInterfaceNotificationActivity(aActivitySig, aNode);
+	}
+
+ConnActivities::CAllInterfaceNotificationActivity::~CAllInterfaceNotificationActivity()
+	{
+	//Remove the only client here
+	RNodeInterface* aux = iNode.GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EAux));
+	if (aux)
+		{
+		iNode.RemoveClient(aux->RecipientId());
+		}
+	delete iAllInterfaceNotificationWorker; //delete this node (why via iAllInterfaceNotificationWorker??)
+	}
+
+// States
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingStart, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingStart::Accept()
+	{
+	return iContext.iMessage.IsMessage<TCFServiceProvider::TStart>();
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingTierManager, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingTierManager::Accept()
+	{
+	if(iContext.iMessage.IsMessage<TCFFactory::TPeerFoundOrCreated>())
+		{
+		TCFFactory::TPeerFoundOrCreated& msg = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
+		iContext.Activity()->iTierManager = msg.iNodeId;
+		iContext.Activity()->ClearPostedTo();
+
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingJoinComplete, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingJoinComplete::Accept()
+	{
+	return iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>();
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingLinkNotification, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingLinkNotification::Accept()
+	{
+	return (iContext.iMessage.IsMessage<TCFTierStatusProvider::TTierNotification>() ||
+			iContext.iMessage.IsMessage<TEBase::TCancel>() ||
+			iContext.iMessage.IsMessage<TEBase::TError>() );
+	}
+
+void AllInterfaceNotificationActivity::TAwaitingLinkNotification::Cancel()
+	{
+	__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnsts, 11));
+	}
+
+
+// for shutdown
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingLinkNotificationError, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingLinkNotificationError::Accept()
+	{
+	if(iContext.iMessage.IsMessage<TCFTierStatusProvider::TTierNotification>())
+		{
+		// we're already shutting down. so have detached from CConnection.
+		//  so we have to delete the enclosed object instead.
+		LOG( ESockLog::Printf(KESockConnectionTag, _L("AllInterfaceNotification received bundle when already shutting down so deleting it")));
+		TCFTierStatusProvider::TTierNotification& msg = message_cast<TCFTierStatusProvider::TTierNotification>(iContext.iMessage);
+		msg.iBundle->Close();
+       	iContext.iMessage.ClearMessageId();
+		}
+	else if(iContext.iMessage.IsMessage<TEBase::TCancel>())
+		{
+		LOG( ESockLog::Printf(KESockConnectionTag, _L("AllInterfaceNotification received TCancel when already shutting down so discarding it")));
+       	iContext.iMessage.ClearMessageId();
+		}
+
+	return iContext.iMessage.IsMessage<TEBase::TError>();
+	}
+
+
+// Transitions
+
+DEFINE_SMELEMENT(ConnectionGoingDownActivity::TStoreGoneDownError, NetStateMachine::MStateTransition, TContext)
+void ConnectionGoingDownActivity::TStoreGoneDownError::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+    TCFControlClient::TGoneDown& goneDownMessage = message_cast<TCFControlClient::TGoneDown>(iContext.iMessage);
+	LOG( ESockLog::Printf(KESockConnectionTag, _L("TStoreGoneDownError. error:%d"), goneDownMessage.iValue1));
+	iContext.Activity()->SetError(goneDownMessage.iValue1);
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAddClient, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TAddClient::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity() == NULL, ConnPanic(KPanicNoActivity));
+	__ASSERT_DEBUG(iContext.iPeer == NULL, User::Panic(KSpecAssert_ESockSSockscnsts, 12));
+	iContext.iPeer = iContext.Node().AddClientL(address_cast<TNodeId>(iContext.iSender), TClientType(TCFClientType::EAux));
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TFindTierManager, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TFindTierManager::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	// Find out if the tier UID has been set.
+	TBool tierUidIsNull = (iContext.Activity()->iTierUid == TUid::Null());
+
+	// Panic in UDEB, Leave in UREL. The tier UID should be set in the derived
+	// class's constructor
+	__ASSERT_DEBUG(!tierUidIsNull, User::Panic(KSpecAssert_ESockSSockscnsts, 13));
+	User::LeaveIfError(tierUidIsNull ? KErrNotReady : KErrNone);
+
+	TAlwaysFindFactoryQuery query;
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)),
+		TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, iContext.Activity()->iTierUid, &query).CRef());
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TJoinTierManager, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TJoinTierManager::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+		TCFServiceProvider::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::EAdministrative)).CRef());
+
+	iContext.Node().AddClientL(iContext.Activity()->iTierManager, TClientType(TCFClientType::EServProvider));
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TStartLinkNotification, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TStartLinkNotification::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	CConnectionServParameterBundle* queryBundle = CConnectionServParameterBundle::NewL();
+   	CleanupStack::PushL(queryBundle);
+   	CRefCountOwnedParameterBundle* bundleOwner = new(ELeave)CRefCountOwnedParameterBundle(queryBundle);
+   	CleanupStack::Pop();
+   	bundleOwner->Open();
+   	CleanupClosePushL(*bundleOwner);
+
+	CParameterSetContainer* psc = CParameterSetContainer::NewL(*queryBundle);
+
+	// Set up a status filter for connected access points only
+	TAccessPointStatusFilter availFilter;
+	availFilter.Configured(EAccessPointFlagIgnore);
+	availFilter.Restricted(EAccessPointFlagIgnore);
+	availFilter.Available(EAccessPointFlagIgnore);
+	availFilter.Started(EAccessPointFlagIgnore);
+	availFilter.Active(EAccessPointFlagMatchAny);
+	queryBundle->AddMatchConditionL(availFilter);
+	queryBundle->AddParameterSetToReturnL(XAccessPointGenericParameterSet::Type());
+	queryBundle->AddParameterSetToReturnL(XIpProtoAccessPointParameterSet::Type());
+
+   	const CAllInterfaceNotificationWorker* worker = iContext.Activity()->iAllInterfaceNotificationWorker;
+   	const RMessage2* rm2 = &(iContext.Activity()->iAllInterfaceNotificationWorker->iConnection.Message());
+
+   	RClientInterface::OpenPostMessageClose(worker->Id(), iContext.Activity()->iTierManager,
+   		TCFTierStatusProvider::TTierNotificationRegistration(bundleOwner, rm2).CRef());
+   	CleanupStack::Pop(); // bundleOwner
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TEnqueueNotification, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TEnqueueNotification::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	TCFTierStatusProvider::TTierNotification& msg = message_cast<TCFTierStatusProvider::TTierNotification>(iContext.iMessage);
+
+	__ASSERT_DEBUG(msg.iBundle, User::Panic(KSpecAssert_ESockSSockscnsts, 14));
+	if(msg.iBundle->PtrL()->CountParamSetContainers() > 0)
+		{
+		TInt i = 0;
+		TBool found = EFalse;
+		while(const CConnectionServParameterSetContainer* container = static_cast<const CConnectionServParameterSetContainer*>(msg.iBundle->Ptr()->GetParamSetContainer(i++)))
+			{
+			const XAccessPointGenericParameterSet* status = XAccessPointGenericParameterSet::FindInParamSetContainer(*container);
+			
+			TConnInterfaceState interfaceState;
+			if (status->AccessPointStatus().Active() == ConnectionServ::EAccessPointFlagTrue)
+				{
+				interfaceState = EInterfaceUp;
+				}
+			else
+				{			
+				interfaceState = EInterfaceDown;
+				}
+
+			const XIpProtoAccessPointParameterSet* ipApParams = XIpProtoAccessPointParameterSet::FindInParamSetContainer(*container);
+//			ASSERT(ipApParams);
+			if (ipApParams) // commsdat might be broken so XIpProtoAccessPointParameterSet not available
+				{
+				TConnectionInfo connectionInfo(ipApParams->IapId(), ipApParams->NetworkId());
+
+				TInterfaceNotification notification = { connectionInfo,  interfaceState };
+
+				iContext.Node().iConnection.iLegacyConnection.iNotificationQueue.Enque(notification);
+
+				found = ETrue;
+				}
+			}
+		if (found)
+			iContext.Node().iConnection.iLegacyConnection.CompleteAllInterfaceNotificationL(KErrNone);
+
+		}
+
+	msg.iBundle->Close();
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TCancelLinkNotification, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TCancelLinkNotification::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+   	TNodeId goo = iContext.Activity()->iTierManager;
+
+   	const CAllInterfaceNotificationWorker* worker = iContext.Activity()->iAllInterfaceNotificationWorker;
+
+	RNodeInterface::OpenPostMessageClose(worker->Id(), iContext.Activity()->iTierManager,
+		TEBase::TCancel().CRef());
+	}
+
+// This solely exists separately from the other identical-looking version
+//    in this file ("CTierManagerActivity::TLeaveTierManager::DoL()") because
+//    the activities referenced by its TContext have iTierManager
+//    at different offsets. This is because they have different parent
+//    classes and, as such, have different member variable.
+//
+// The terrible thing is, this is usable in the other place,
+//    and builds without complaint... then explodes when it tries
+//    to send messages to a garbage iTierManager.
+//
+//    TAKE CARE OF IT!!!
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TLeaveTierManager, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TLeaveTierManager::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+		TEChild::TLeft().CRef());
+
+	iContext.Node().RemoveClient(iContext.Activity()->iTierManager);
+	}
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TSendErrorToConnection, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TSendErrorToConnection::DoL()
+	{
+	// Send a TError to the CConnection to complete the shutdown handshake.
+	RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Node().iConnection.Id(), TEBase::TError(iContext.Activity()->KickOffMessageId(), KErrCancel).CRef());
+	}
+
+DEFINE_SMELEMENT(TNoTagOrCancelAllInterfaceWorker, NetStateMachine::MStateFork, TContext)
+TInt TNoTagOrCancelAllInterfaceWorker::TransitionTag()
+	{
+	// If this CConnection has an AllInterfaceNotificationWorker, return KCancelAllInterfaceWorker else return KNoTag.
+	AConnectionLegacy& cl = iContext.Node().iLegacyConnection;
+	return cl.iAllInterfaceNotificationWorker.IsNull() ? KNoTag : KCancelAllInterfaceWorker;
+	}
+
+DEFINE_SMELEMENT(TCancelAllInterfaceNotificationWorker, NetStateMachine::MStateTransition, TContext)
+void TCancelAllInterfaceNotificationWorker::DoL()
+	{
+	CConnection& cc = iContext.Node();
+	AConnectionLegacy& cl = cc.iLegacyConnection;
+	// If this CConnection has an AllInterfaceNotificationWorker, send a TCancel to it to begin
+	// the shutdown handshake.
+	if(!cl.iAllInterfaceNotificationWorker.IsNull())
+		{
+		TNodeCtxId dest(ECFActivityConnectionAllInterfaceNotification, cl.iAllInterfaceNotificationWorker);
+		RNodeInterface::OpenPostMessageClose(cc.Id(), dest, TEBase::TCancel().CRef());
+		cl.iAllInterfaceNotificationWorker.SetNull();
+		}
+	}
+
+//
+// CEnumerateConnectionsActivity
+
+MeshMachine::CNodeActivityBase* ConnActivities::CEnumerateConnectionsActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	{
+	return new(ELeave) ConnActivities::CEnumerateConnectionsActivity(aActivitySig, aNode);
+	}
+
+// States
+
+DEFINE_SMELEMENT(EnumerateConnectionsActivity::TAwaitingTierStatus, NetStateMachine::MState, TContext)
+TInt EnumerateConnectionsActivity::TAwaitingTierStatus::Accept()
+	{
+	TBool isTierStatus = iContext.iMessage.IsMessage<TCFTierStatusProvider::TTierStatus>();
+	TBool isError = iContext.iMessage.IsMessage<TEBase::TError>();
+
+	if(isTierStatus || isError)
+		{
+		// Leave the tier manager
+		RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+			TEChild::TLeft().CRef());
+
+		iContext.Node().RemoveClient(iContext.Activity()->iTierManager);
+		}
+
+	return isTierStatus;
+	}
+
+// Transitions
+
+DEFINE_SMELEMENT(EnumerateConnectionsActivity::TQueryTierStatus, NetStateMachine::MStateTransition, TContext)
+void EnumerateConnectionsActivity::TQueryTierStatus::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	// Clear the connection info cache
+	iContext.Node().iLegacyConnection.iConnectionInfoPtrArray.ResetAndDestroy();
+
+	CConnectionServParameterBundle* queryBundle = CConnectionServParameterBundle::NewL();
+   	CleanupStack::PushL(queryBundle);
+   	CRefCountOwnedParameterBundle* bundleOwner = new (ELeave)CRefCountOwnedParameterBundle(queryBundle);
+   	CleanupStack::Pop(queryBundle);
+   	bundleOwner->Open();
+   	CleanupClosePushL(*bundleOwner);
+
+	// Set up a status filter for connected access points only
+	TAccessPointStatusFilter availFilter;
+	availFilter.Configured(EAccessPointFlagIgnore);
+	availFilter.Restricted(EAccessPointFlagIgnore);
+	availFilter.Available(EAccessPointFlagIgnore);
+	availFilter.Started(EAccessPointFlagIgnore);
+	availFilter.Active(EAccessPointFlagMatchTrue);
+
+	queryBundle->AddMatchConditionL(availFilter);
+	queryBundle->AddParameterSetToReturnL(XIpProtoAccessPointParameterSet::Type());
+
+   	RClientInterface::OpenPostMessageClose(iContext.NodeId(), iContext.Activity()->iTierManager,
+   		TCFTierStatusProvider::TTierStatusQuery(bundleOwner, &iContext.Activity()->iMessage).CRef());
+   	CleanupStack::Pop(); // bundleOwner
+	}
+
+DEFINE_SMELEMENT(EnumerateConnectionsActivity::TCompleteClient, NetStateMachine::MStateTransition, TContext)
+void EnumerateConnectionsActivity::TCompleteClient::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	TPckg<TUint> pckg(iContext.Node().iLegacyConnection.iConnectionInfoPtrArray.Count());
+	iContext.Activity()->WriteL(0, pckg);
+	}
+
+DEFINE_SMELEMENT(EnumerateConnectionsActivity::TCacheConnectionInfo, NetStateMachine::MStateTransition, TContext)
+void EnumerateConnectionsActivity::TCacheConnectionInfo::DoL()
+	{
+	__ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+	TCFTierStatusProvider::TTierStatus& msg = message_cast<TCFTierStatusProvider::TTierStatus>(iContext.iMessage);
+
+	const CConnectionServParameterSetContainer* container;
+	const XIpProtoAccessPointParameterSet* ipApParams;
+
+	for (TInt i=0; i<msg.iBundle->PtrL()->CountParamSetContainers(); i++)
+		{
+		container = static_cast<const CConnectionServParameterSetContainer*>(msg.iBundle->Ptr()->GetParamSetContainer(i));
+
+		ipApParams = XIpProtoAccessPointParameterSet::FindInParamSetContainer(*container);
+		__ASSERT_DEBUG(ipApParams, User::Panic(KSpecAssert_ESockSSockscnsts, 16));
+
+		TSourcedConnectionInfo* connInfo = new(ELeave) TSourcedConnectionInfo(ipApParams->IapId(), ipApParams->NetworkId(), ipApParams->ConnectionType(), ipApParams->ControlClientId());
+		iContext.Node().iLegacyConnection.iConnectionInfoPtrArray.AppendL(connInfo);
+		}
+
+	msg.iBundle->Close();
+	}
+
+DEFINE_SMELEMENT(ConnectionCleanupActivities::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, TContext)
+TInt ConnectionCleanupActivities::TNoTagOrNoTagBackwards::TransitionTag()
+    {
+	if ( iContext.iMessage.IsMessage<TEPeer::TLeaveComplete>() )
+		{
+//		__ASSERT_DEBUG(iContext.Node().GetClientIter(RNodeInterface::ECtrl|RNodeInterface::EData)[0] == NULL,
+//		User::Panic(KCorePRPanic, KPanicClientsStillPresent));
+		if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TCFClientType(TCFClientType::EServProvider)) == NULL)
+			{ // This was the last service provider
+			return NetStateMachine::EForward | MeshMachine::KNoTag;
+			}
+		// There are more service providers to expect 'leave complete' from so
+		// loop round and wait for the next one.
+		return NetStateMachine::EBackward | MeshMachine::KNoTag;
+		}
+    __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSockscnsts, 17));
+    return KNoTag;
+    }
+
+DEFINE_SMELEMENT(ConnSubConnEventsActivity::TAwaitingSubConnEvent, NetStateMachine::MState, TContext)
+TInt ConnSubConnEventsActivity::TAwaitingSubConnEvent::Accept()
+	{
+	if(iContext.iMessage.IsMessage<TCFInternalEsock::TSubConnectionOpenedEvent>() ||
+	   iContext.iMessage.IsMessage<TCFInternalEsock::TSubConnectionClosedEvent>())
+		{
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+DEFINE_SMELEMENT(ConnSubConnEventsActivity::TProcessSubConnEvent, NetStateMachine::MStateTransition, TContext)
+void ConnSubConnEventsActivity::TProcessSubConnEvent::DoL()
+	{
+	CConnection& conn = static_cast<CConnection&>(iContext.Node());
+
+	if(iContext.iMessage.IsMessage<TCFInternalEsock::TSubConnectionOpenedEvent>())
+		{
+		const TCFInternalEsock::TSubConnectionOpenedEvent& msg = message_cast<TCFInternalEsock::TSubConnectionOpenedEvent>(iContext.iMessage);
+		conn.iLegacyConnection.SubConnectionEvent(msg.iSubConnectionOpenedEvent);
+		}
+	else
+		{
+		const TCFInternalEsock::TSubConnectionClosedEvent& msg = message_cast<TCFInternalEsock::TSubConnectionClosedEvent>(iContext.iMessage);
+		conn.iLegacyConnection.SubConnectionEvent(msg.iSubConnectionClosedEvent);
+		}
+	}
+
+CNodeActivityBase* CConnLegacyRMessage2Activity::NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode )
+	{
+	TUint c = GetNextActivityCountL(aActivitySig,aNode);
+	return new (ELeave) CConnLegacyRMessage2Activity( aActivitySig, aNode, c);
+	}
+	
+CConnLegacyRMessage2Activity::CConnLegacyRMessage2Activity( const TNodeActivity& aActivitySig, AMMNodeBase& aNode, TUint aNextActivityCount)
+	: MeshMachine::CNodeParallelMessageStoreActivityBase(aActivitySig, aNode, aNextActivityCount)
+	{
+	}
+
+CConnLegacyRMessage2Activity::~CConnLegacyRMessage2Activity()
+	{
+	if (Error() != KErrNone)
+		{
+		Complete(Error());
+		}
+	if (!iCancelMessage.IsNull())
+		{
+		iCancelMessage.Complete(KErrNone);
+		}
+	SetError(KErrNone);
+	}
+
+void CConnLegacyRMessage2Activity::PanicClient(const TDesC& aCatagory, TInt aCode)
+	{
+	if (!iSafeMessage.IsNull())
+		{
+		iSafeMessage.PanicClient(aCatagory, aCode);
+		}
+	}
+
+void CConnLegacyRMessage2Activity::Complete(TInt aCode)
+	{
+	if (!iSafeMessage.IsNull())
+		{
+		iSafeMessage.Complete(aCode);
+		}
+	}
+
+void CConnLegacyRMessage2Activity::SetCancelRequest(const Den::RSafeMessage& aMessage)
+	{
+	iCancelMessage.Duplicate(aMessage);
+	}
+
+
+DEFINE_SMELEMENT(TProcessLegacyRMessage2, NetStateMachine::MStateTransition, TContext)
+void TProcessLegacyRMessage2::DoL()
+	{
+	ASSERT(iContext.iMessage.IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)));
+	// static_cast as it will be a derivative and message_cast won't work
+	CConnLegacyRMessage2Activity* act = static_cast<CConnLegacyRMessage2Activity*>(iContext.Activity());
+	TCFSigLegacyRMessage2Ext& msg = static_cast<TCFSigLegacyRMessage2Ext&>(iContext.iMessage);
+	act->iSafeMessage.Duplicate(msg.iMessage);
+	
+	if (msg.CanProcess(iContext))
+		{
+		msg.ProcessL(iContext);
+		}
+	else
+		{
+		msg.ForwardL(iContext);
+		}
+	}
+
+DEFINE_SMELEMENT(TCompleteRMessage2, NetStateMachine::MStateTransition, TContext)
+void TCompleteRMessage2::DoL()
+	{
+	TCFLegacyMessage::TLegacyRMessage2Processed& msg = message_cast<TCFLegacyMessage::TLegacyRMessage2Processed>(iContext.iMessage);
+	CConnLegacyRMessage2Activity* act = static_cast<CConnLegacyRMessage2Activity*>(iContext.Activity());
+
+    if (msg.iResponse.iType == TLegacyRMessage2Response::EPanic)
+		{
+		act->PanicClient(msg.iResponse.iCatagory, msg.iResponse.iCode);
+		}
+    else
+		{
+		ASSERT(act->Message().IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)));
+		TInt error = static_cast<TCFSigLegacyRMessage2Ext&>(act->Message()).CheckError(iContext, msg.iResponse.iCode);
+		act->Complete(error);
+		}
+	}
+
+DEFINE_SMELEMENT(THandleRMessage2Error, NetStateMachine::MStateTransition, ConnStates::TContext)
+void THandleRMessage2Error::DoL()
+    {
+    CConnLegacyRMessage2Activity* act = static_cast<CConnLegacyRMessage2Activity*>(iContext.Activity());
+	
+	ASSERT(act->Message().IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)));
+	TInt error = static_cast<TCFSigLegacyRMessage2Ext&>(act->Message()).CheckError(iContext, act->Error());
+	act->SetError(error);
+	act->Complete(error);
+    }
+
+
+DEFINE_SMELEMENT(TCancelAllLegacyRMessage2Activities, NetStateMachine::MStateTransition, TContext)
+void TCancelAllLegacyRMessage2Activities::DoL()
+	{
+	const RPointerArray<CNodeActivityBase>& activities = iContext.Node().Activities();
+
+	for (TInt i = 0; i < activities.Count(); i++)
+		{
+		if (activities[i]->ActivitySigId() == ESock::ECFActivityConnectionLegacyRMessage2Handler)
+			{
+			activities[i]->Cancel(iContext);
+			}
+		}
+	}
+
+