commsfwsupport/commselements/meshmachine/inc/mm_activities.h
changeset 0 dfb7c4ff071f
child 18 9644881fedd0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwsupport/commselements/meshmachine/inc/mm_activities.h	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1393 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// generic framework node state machine states
+// 
+//
+
+/**
+ @file
+ @publishedPartner
+ @released
+*/
+
+#ifndef SYMBIAN_MM_ACTIVITIES_H
+#define SYMBIAN_MM_ACTIVITIES_H
+
+#include <elements/mm_node.h>
+#include <elements/mm_nodepeer.h>
+#include <elements/mm_activities_internal.h>
+#include <elements/nm_address_internal.h>
+#include <elements/nm_signatures.h>
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ElemMeshMachActH, "ElemMeshMachActH");
+#endif
+
+//-=========================================================
+//
+// MACROS
+//
+//-=========================================================
+
+/**
+Declare and export a node activity.
+
+@param name  The name of the activity, which will be used to put it into the node's activity map
+
+@see DECLARE_NODEACTIVITY
+*/
+#define DECLARE_EXPORT_NODEACTIVITY( name ) \
+	struct name \
+		{ \
+		IMPORT_C static const MeshMachine::TNodeActivity& Self(); \
+		IMPORT_C static const NetStateMachine::TStateTriple& FirstTriple(); \
+		static const MeshMachine::TNodeActivity iSelf; \
+		static const NetStateMachine::TStateTriple iData[]; \
+		};
+
+/**
+Declares a node activity. A node activity is a state machine. It contains multiple nodeactivity
+entries, which respresent the states, transitions and forks of the state machine.
+
+@param name  The name of the activity, which will be used to put it into the node's activity map
+
+@see DEFINE_NODEACTIVITY
+@see NODEACTIVITY_ENTRY
+*/
+#define DECLARE_NODEACTIVITY( name ) \
+	struct name \
+		{ \
+		inline static const MeshMachine::TNodeActivity& Self() {return iSelf;} \
+		inline static const NetStateMachine::TStateTriple& FirstTriple() {return iData[1];} \
+		static const MeshMachine::TNodeActivity iSelf; \
+		static const NetStateMachine::TStateTriple iData[]; \
+		};
+
+#ifdef SYMBIAN_TRACE_ENABLE
+/**
+Define and export a custom node activity.
+
+@param id        Identifier for the activity
+@param name      The name of the activity
+@param msgtype   Message which will kickoff this activity
+@param ctor      Constructor for the custom activity class
+
+@see DEFINE_CUSTOM_NODEACTIVITY
+*/
+	#define DEFINE_EXPORT_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
+		EXPORT_C const MeshMachine::TNodeActivity& name :: Self() {return iSelf;} \
+		EXPORT_C const NetStateMachine::TStateTriple& name :: FirstTriple() {return iData[1];} \
+		const MeshMachine::TNodeActivity name :: iSelf = {id, msgtype::EId, msgtype::ERealm, name :: iData[1], &ctor, _S8(#name)}; \
+		DEFINE_TRIPLES_TABLE( name :: iData )
+
+/**
+Define a custom node activity. A custom node activity is a node activity which defines its own
+node activity class. This is used, for example, if the activity wishes to share some custom context
+information between the states and transition in the activity.
+
+Node activity class must derive from CNodeActivityBase.
+
+@param id        Identifier for the activity
+@param name      The name of the activity
+@param msgtype   Message which will kickoff this activity
+@param ctor      Constructor for the custom activity class
+
+@see DEFINE_NODEACTIVITY
+@see CNodeActivityBase
+*/
+	#define DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
+		const MeshMachine::TNodeActivity name :: iSelf = {id, msgtype::EId, msgtype::ERealm, name :: iData[1], &ctor, _S8(#name)}; \
+		DEFINE_TRIPLES_TABLE( name :: iData )
+
+#else
+
+/**
+Define and export a custom node activity.
+
+@param id        Identifier for the activity
+@param name      The name of the activity
+@param msgtype   Message which will kickoff this activity
+@param ctor      Constructor for the custom activity class
+
+@see DEFINE_CUSTOM_NODEACTIVITY
+*/
+	#define DEFINE_EXPORT_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
+		EXPORT_C const MeshMachine::TNodeActivity& name :: Self() {return iSelf;} \
+		EXPORT_C const NetStateMachine::TStateTriple& name :: FirstTriple() {return iData[1];} \
+		const MeshMachine::TNodeActivity name :: iSelf = {id, msgtype::EId, msgtype::ERealm, name :: iData[1], &ctor, NULL}; \
+		DEFINE_TRIPLES_TABLE( name :: iData )
+
+/**
+Define a custom node activity. A custom node activity is a node activity which defines its own
+node activity class. This is used, for example, if the activity wishes to share some custom context
+information between the states and transition in the activity.
+
+Node activity class must derive from CNodeActivityBase.
+
+@param id        Identifier for the activity
+@param name      The name of the activity
+@param msgtype   Message which will kickoff this activity
+@param ctor      Constructor for the custom activity class
+
+@see DEFINE_NODEACTIVITY
+@see CNodeActivityBase
+*/
+	#define DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
+		const MeshMachine::TNodeActivity name :: iSelf = {id, msgtype::EId, msgtype::ERealm, name :: iData[1], &ctor, NULL}; \
+		DEFINE_TRIPLES_TABLE( name :: iData )
+
+#endif
+
+/**
+Define and declare a custom node activity
+
+@param id        Identifier for the activity
+@param name      The name of the activity
+@param msgtype   Message which will kickoff this activity
+@param ctor      Constructor for the custom activity class
+
+@see DEFINE_CUSTOM_NODEACTIVITY
+*/
+#define DECLARE_DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
+	DECLARE_NODEACTIVITY( name ) \
+	DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor )
+
+/**
+Define and export node activity
+
+@param id        Identifier for the activity
+@param name      The name of the activity
+@param msgtype   Message which will kickoff this activity
+
+@see DEFINE_NODEACTIVITY
+*/
+#define DEFINE_EXPORT_NODEACTIVITY( id, name, msgtype ) \
+	DEFINE_EXPORT_CUSTOM_NODEACTIVITY( id, name, msgtype, MeshMachine::CNodeActivityBase::NewL )
+
+/**
+Define the start of a node activity. There must be a matching @c NODEACTIVITY_END to close the
+node activity.
+
+The @c id is a unique identifier for the activity. It allows activities to be overridden in an
+activity map. When deriving from an activity map, if you specify a node activity in your map
+whose id is the same as one in the parent map, the one in the parent map with be overriden.
+
+The @c name of the activity is used to add it to the activity map.
+
+The @c msgtype is the type of message which will initiate this activity. This can be left as the
+null message, in which case it will be the first state which decides whether to start the activity
+or not.
+
+@code
+namespace ExampleActivity {
+DEFINE_NODEACTIVITY(EFoobarActivity, SimpleFoobarActivity, TFoobar)
+    FIRST_NODEACTIVITY_ENTRY(TAwaitingFoobar, TDoOneThingOrAnother)
+	NODEACTIVITY_ENTRY(KDoOneThing, TDoTheThing, TAwaitingResponseToThing, TNoTag)
+	NODEACTIVITY_ENTRY(KAnother, TDoTheOtherThing, TAwaitingResponseToThing, TNoTag)
+	LAST_NODEACTIVITY_ENTRY(KNoTag, TDoFinalThing)
+NODEACTIVITY_END()
+} // end namespace ExampleActivity
+@endcode
+
+A node activity must start with either a @c FIRST_NODEACTIVITY_ENTRY or a @c SINGLE_NODEACTIVITY_ENTRY. In
+the latter case there should be no other entries in the node activity.
+
+The activity object (@c CNodeActivityBase) is only created once the second @c NODEACTIVITY_ENTRY is entered.
+
+@param id        Identifier for the activity
+@param name      The name of the activity
+@param msgtype   Message which will kickoff this activity
+
+@see DEFINE_ACTIVITY_MAP
+*/
+#define DEFINE_NODEACTIVITY( id, name, msgtype ) \
+	DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, MeshMachine::CNodeActivityBase::NewL )
+
+/**
+Define and declare a node activity
+
+@param id        Identifier for the activity
+@param name      The name of the activity
+@param msgtype   Message which will kickoff this activity
+
+@see DEFINE_ACTIVITY_MAP
+*/
+#define DECLARE_DEFINE_NODEACTIVITY( id, name, msgtype ) \
+	DECLARE_DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, MeshMachine::CNodeActivityBase::NewL )
+
+/**
+Define an entry in a node activity.
+
+@param transitionTag     Condition on which the entry is entered
+@param stateTransition   Transition to be executed
+@param state             State to enter after
+@param stateFork         Fork to decide which entry to enter next
+
+@see DEFINE_NODEACTIVITY
+*/
+#define NODEACTIVITY_ENTRY( transitionTag, stateTransition, state, stateFork ) \
+	STATE_TRIPLE_ENTRY( transitionTag, stateTransition, state, stateFork )
+
+/**
+Define the first entry in a node activity
+
+@param firstState       Initial state of the activity
+@param firstStateFork   Fork to decide which entry to enter next
+
+@see DEFINE_NODEACTIVITY
+*/
+#define FIRST_NODEACTIVITY_ENTRY( firstState, firstStateFork ) \
+	FIRST_TRIPLE_ENTRY( firstState, firstStateFork )
+
+/**
+Define a through entry. Through entries execute a transition but do not
+enter a state. Instead they move onto the next entry in the node activity
+using the @c stateFork to decide which entry this is.
+
+@param transitionTag   Condition on which the entry is entered
+@param stateTransition Transition to be executed
+@param stateFork       Fork to decide which entry to enter next
+*/
+#define THROUGH_NODEACTIVITY_ENTRY( transitionTag, stateTransition, stateFork ) \
+	THROUGH_TRIPLE_ENTRY( transitionTag, stateTransition, stateFork )
+
+/**
+Define the final entry in a node activity.
+
+@param transitionTag  Condition on which the entry is entered
+@param lastTransition Final transition to be executed
+
+@see DEFINE_NODEACTIVITY
+*/
+#define LAST_NODEACTIVITY_ENTRY( transitionTag, lastTransition ) \
+	LAST_TRIPLE_ENTRY( transitionTag, lastTransition )
+
+/**
+Define a single node activity entry. This is the first and last entry in any
+node activity in which it is used.
+
+@param state             Initial state of the activity
+@param stateTransition   Transition to execute once the state is fulfilled
+
+@see DEFINE_NODEACTIVITY
+*/
+#define SINGLE_NODEACTIVITY_ENTRY( stateTransition, state ) \
+	STATE_TRIPLE_ENTRY( MeshMachine::KNoTag, stateTransition, state, MeshMachine::TNoTag )
+
+/**
+Define a routing node activity entry. Routing entries neither execute any
+transition, nor wait in any state. These are useful only for redirecting the
+path of execution in the state machine.
+
+@param transitionTag  Condition on which the entry is entered
+@param stateFork      Fork to decide the next transition to enter
+*/
+#define ROUTING_NODEACTIVITY_ENTRY( transitionTag, stateFork ) \
+	THROUGH_TRIPLE_ENTRY( transitionTag, MeshMachine::TDoNothing, stateFork )
+
+/**
+Marks the end of a node activity.
+
+@see DEFINE_NODEACTIVITY
+*/
+#define NODEACTIVITY_END() \
+	TRIPLES_TABLE_END()
+
+
+
+/**
+Declare and export an activity map
+
+@param map Name of the activity map
+@see DECLARE_ACTIVITY_MAP
+*/
+#define DECLARE_EXPORT_ACTIVITY_MAP( map ) \
+	struct map \
+		{ \
+		IMPORT_C static const MeshMachine::TNodeActivityMap& Self(); \
+		static const MeshMachine::TNodeActivityMap iSelf; \
+		static const MeshMachine::TNodeActivityMap::TStaticNodeActivity iData[]; \
+		};
+
+/**
+Define and export the activity map
+
+@param map Name of the activity map
+@see DEFINE_ACTIVITY_MAP
+*/
+#define DEFINE_EXPORT_ACTIVITY_MAP( map ) \
+	EXPORT_C const MeshMachine::TNodeActivityMap& map :: Self() {return iSelf;} \
+	const MeshMachine::TNodeActivityMap map :: iSelf = {map :: iData[0]}; \
+	const MeshMachine::TNodeActivityMap::TStaticNodeActivity map :: iData[] = {
+
+/**
+Declare an activity map.
+
+For example,
+@code
+DECLARE_ACTIVITY_MAP(MyNodeActivityMap)
+@endcode
+
+This can then be passed into the constructor of a mesh machine node as follows.
+
+@code
+CMyMeshNode::CMyMeshNode(CConnectionProviderFactoryBase& aFactory)
+    : CCoreConnectionProvider(aFactory, MyNodeActivityMap::Self())
+	{
+	...
+@endcode
+
+@param map Name of the activity map
+*/
+#define DECLARE_ACTIVITY_MAP( map ) \
+	struct map \
+		{ \
+		inline static const MeshMachine::TNodeActivityMap& Self() {return iSelf;} \
+		static const MeshMachine::TNodeActivityMap iSelf; \
+		static const MeshMachine::TNodeActivityMap::TStaticNodeActivity iData[]; \
+		}; \
+
+/**
+Define an activity map. An activity map is a collection of node activities. The activity map can be
+based on another activity map or this macro can be used to define a standalone activity map.
+
+Once defined an activity map can be passed into the constructor of a node, to define
+what activities that node is capable of executing.
+
+@code
+DECLARE_DEFINE_ACTIVITY_MAP(MyNodeActivityMap)
+	ACTIVITY_MAP_ENTRY(MyNodeActivities, MyFirstActivity)
+	ACTIVITY_MAP_ENTRY(MyNodeActivities, MySecondActivity)
+ACTIVITY_MAP_END_BASE(BaseActivities, BaseActivityMap)
+@endcode
+
+@param map Name of the activity map
+
+@see ACTIVITY_MAP_END_BASE
+@see ACTIVITY_MAP_END
+*/
+#define DEFINE_ACTIVITY_MAP( map ) \
+	const MeshMachine::TNodeActivityMap map :: iSelf = {map :: iData[0]}; \
+	const MeshMachine::TNodeActivityMap::TStaticNodeActivity map :: iData[] = {
+
+/**
+Define and declare an activity map.
+
+@param map Name of the activity map
+
+@see DEFINE_ACTIVITY_MAP
+*/
+#define DECLARE_DEFINE_ACTIVITY_MAP( map ) \
+	DECLARE_ACTIVITY_MAP(map) \
+	DEFINE_ACTIVITY_MAP(map)
+
+/**
+Create an entry in an activity map.
+
+@param name_space Namespace of the activity
+@param name       Name of the activity
+
+@see DEFINE_ACTIVITY_MAP
+*/
+#define ACTIVITY_MAP_ENTRY( name_space, name ) &name_space::name::Self,
+
+/**
+Mark the end of an activity map. This macro should be used for standalone activity
+maps.
+
+@see DEFINE_ACTIVITY_MAP
+*/
+#define ACTIVITY_MAP_END() \
+	NULL, \
+	NULL \
+	};
+
+/**
+Mark the end of an activity map. This macro should be used for an activity map based
+on other activity maps.
+
+@param name_space The namespace of the base map
+@param base_map   The name of the base map
+
+@see DEFINE_ACTIVITY_MAP
+*/
+#define ACTIVITY_MAP_END_BASE( name_space, base_map ) \
+	NULL, \
+	(MeshMachine::TNodeActivityMap::TStaticNodeActivity)&name_space::base_map::Self \
+	};
+
+namespace MeshMachine
+{
+/**
+Base class for all node activity objects. Non custom node activities will use this by default.
+**/
+class CNodeActivityBase : public CBase,
+                          public NetInterfaces::AApiExtBase,
+                          protected NetStateMachine::ACore,
+                          protected NetInterfaces::TInterfaceControl
+	{
+    friend class AMMNodeBase;
+    friend class AContextStore; //to be able access NetStateMachine::ACore
+    friend class AActivitySemaphore; //to be able access NetStateMachine::ACore
+
+public:
+	/**
+	   Create a new activity. This should never be called by user code.
+
+	   @param aActivitySig Context information about how the activity is to be started
+	   @param aNode        The node to which this activity will belong.
+	   @return A pointer to the new Activity base object. Ownership is transferred.
+	*/
+    IMPORT_C static CNodeActivityBase* NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
+
+	/**
+	Get the @c id of the activity.
+	   @return The activity id of the activity
+	*/
+	IMPORT_C virtual TUint16 ActivityId() const;
+
+	/**
+	   Remove an originator from the originator list.
+
+	   @param aIndex Index of originator to remove
+	*/
+	IMPORT_C void RemoveOriginator(TInt aIndex);
+
+	/**
+	Check if the activity is running.
+	   @return ETrue if the activity is still running, otherwise EFalse.
+	*/
+	IMPORT_C virtual TBool IsIdle() const;
+
+	/**
+	   Put the activity into the idle state. This stops the activity running and notifies the mesh machine that
+	   it's ok to delete this activity.
+	*/
+	IMPORT_C virtual void SetIdle();
+
+	/**
+	   Return the activity signature id of the activity. This may not necessarily be the same as the activity id
+	   in the case of parallel activities, where the activity id will be [8 bit unique id|8 bit activity sig]
+
+	   @return The activity signature id
+	*/
+    TUint ActivitySigId() const
+   		{
+  		return iActivitySig.iId;
+   		}
+
+	/**
+	Get the current error state for the activity.
+	   @return The activity's current error state. @c KErrNone indicates there is no error.
+	*/
+	TInt Error() const
+		{
+		return iError;
+		}
+
+	/**
+	   Set the error state of the activity.
+
+	   @param aError error code to set
+	*/
+	void SetError(TInt aError)
+		{
+		if (iError == KErrNone || aError == KErrNone)
+    		{
+    		iError = aError;
+    		};
+		}
+
+	/**
+	Get the id of the node that the last request from this activity was sent to.
+	   @return Node id of the last node the activity has posted a request to
+	*/
+	const Messages::TNodeId PostedToId() const
+		{
+		return iPostedToId;
+		}
+
+	/**
+	Get the id of the message that started this activity.
+	   @return Message id of message that kicked off this activity
+	*/
+	const Messages::TNodeSignal::TMessageId KickOffMessageId() const
+		{
+		return Messages::TNodeSignal::TMessageId(iActivitySig.iKickOffMessageId, iActivitySig.iKickOffMessageRealm);
+		}
+
+	/**
+	Get the id of the node that started this activity.
+	   @return Node peer id of the node whose message first kicked off this activity
+	*/
+	const Messages::TNodePeerId& FirstOriginator() const
+		{
+		__ASSERT_DEBUG(iOriginators.Count(), User::Panic(KSpecAssert_ElemMeshMachActH, 1));
+		return iOriginators[0];
+		}
+
+	/**
+	In essence the same as FirstOriginator(). This should be used in preference in situations where the activity should
+	be run in parallel, and therefore only ever have one originator.
+	   @return Node peer id of the node whose message first kicked off this activity
+	*/
+	const Messages::TNodePeerId& SoleOriginator() const
+		{
+		__ASSERT_DEBUG(iOriginators.Count() == 1, User::Panic(KSpecAssert_ElemMeshMachActH, 2));
+		return iOriginators[0];
+		}
+
+	/**
+	   Post a request to a node.
+
+	   @param aRecepient Endpoint for the message
+	   @param aMessage   Message to send
+	   @param aRecipientIdCritical If true, the postedTo id is set to the id of the recipient. If false, the postedTo id is set to null.
+	   @see PostedToId
+	*/
+	IMPORT_C void PostRequestTo(const Messages::RNodeInterface& aRecepient, const Messages::TSignalBase& aMessage, const TBool aRecipientIdCritical = ETrue);
+	/**
+	   Post a request to a node.
+
+	   @param aRecepient Endpoint for the message
+	   @param aMessage   Message to send
+	   @param aRecipientIdCritical If true, the postedTo id is set to the id of the recipient. If false, the postedTo id is set to null.
+	   @see PostedToId
+	*/
+	IMPORT_C void PostRequestTo(const Messages::TNodeId& aRecepient, const Messages::TSignalBase& aMessage, const TBool aRecipientIdCritical = ETrue);
+
+	/**
+	   Manually set the postedTo id
+
+	   @param aNodeId Node id to set the postedTo id to
+	*/
+	IMPORT_C void SetPostedTo(const Messages::TNodeId& aNodeId);
+
+	/**
+	   Clear the postedTo id
+	*/
+	IMPORT_C void ClearPostedTo();
+
+#ifdef SYMBIAN_TRACE_ENABLE
+	/**
+	   @return the human readable name of the activity
+	*/
+    const TText8* ActivityName() const
+        {
+        return (iActivitySig.iName)? iActivitySig.iName : _S8("Undefined");
+        }
+
+	/**
+	   @return the human readable description of the current node activity entry
+	*/
+    const TText8* CurrentTripleName() const
+        {
+        return ACore::CurrentTripleName();
+        }
+#endif
+
+public:
+	/**
+	Cancels the activity. Only to be called by the meshmachine.
+	@param aContext the context in which the activity is being executed
+	@internalAll
+	*/
+	IMPORT_C virtual void Cancel(TNodeContextBase& aContext);
+
+	/**
+	Attempt to advance the activity one entry. Only to be called by the mesh machine
+	@param aContext the context in which the activity is being executed
+	@return Whether the activity advanced
+	@internalAll
+	*/
+	IMPORT_C virtual TBool Next(TNodeContextBase& aContext);
+
+	/**
+	Find the originator matching the parameters
+	@param aPeerToFind Matching criteria
+	@return Index of the matching originator. KErrNotFound if not found.
+	@internalAll
+	*/
+	IMPORT_C TInt FindOriginator(const Messages::RNodeInterface& aPeerToFind) const;
+
+	/**
+   	Find the originator matching the parameters
+	@param aPeerToFind Matching criteria
+	@return Index of the matching originator. KErrNotFound if not found.
+	@internalAll
+	*/
+	IMPORT_C TInt FindOriginator(const Messages::TRuntimeCtxId& aPeerToFind) const;
+
+	/**
+   	Find the originator matching the parameters
+	@param aOriginator xx
+	@return Index of the matching originator. KErrNotFound if not found.
+
+	@internalAll
+	*/
+	IMPORT_C TInt FindOriginator(const Messages::TNodePeerId& aOriginator) const;
+
+	/**
+	Post a message to an originator
+	@param aOriginator originator to post the message to
+	@param aMessage    message to post
+	@return Whether the posting succeeded
+	@internalAll
+	*/
+	IMPORT_C TBool PostToOriginator(const Messages::TNodePeerId& aOriginator, const Messages::TSignalBase& aMessage) const;
+
+	/**
+    Post a message to all originators
+	@param aMessageSig the message to post
+	@param aFlagsToSet Flags to set on the peer as the message is being sent
+	@param aFlagsToClear Flags to cleared on the peer as the message is being sent
+	@return number of originators the message was posted to
+	@internalAll
+	*/
+	IMPORT_C TInt PostToOriginators(const Messages::TSignalBase& aMessageSig, TUint32 aFlagsToSet = 0, TUint32 aFlagsToClear = 0);
+
+	/**
+	Calls cancel on current state. Sends TError to all originators and sets activity idle
+	@param aContext the context in which the activity is being executed
+	@param aIsNodeBeingDestroyed  indicate to the activity as to whether the node is being destroyed
+	@internalAll
+	*/
+	IMPORT_C void Abort(TNodeContextBase& aContext, TBool aIsNodeBeingDestroyed = EFalse);
+
+	
+protected:
+	/**
+	Constructor for CNodeActivityBase
+	@param aActivitySig Signature with which to create the activity
+	@param aNode        Node which will own the activity
+	*/
+	IMPORT_C explicit CNodeActivityBase(const TNodeActivity& aActivitySig, AMMNodeBase& aNode);
+	/**
+	Destructor. If the Activity is running in error mode, a message is sent to the originator.
+	*/
+	IMPORT_C virtual ~CNodeActivityBase();
+
+	/**
+	Destroy the activity.
+
+	Used primarily by preallocated activities to return extracted space
+	*/
+    virtual void Destroy()
+    	{
+    	delete this;
+    	};
+
+	/**
+
+	@param aInterfaceId id of requested interface
+	@return Interface control for accessing the extension interfaces of the activity
+	@see TInterfaceControl
+	*/
+    IMPORT_C virtual NetInterfaces::TInterfaceControl* DoFetchInterfaceControlL(TInt aInterfaceId);
+
+	/**
+	Signal the activity that an event has happened in the mesh machine. Used for waking up sleeping activities
+	which use mutexes.
+
+	@param # The context in which the activity is being executed
+	@return ETrue if the activity was awoken
+	@see AActivitySemaphore
+	*/
+	virtual TBool Signal(TNodeContextBase& /*aContext*/) { return EFalse; };
+
+protected:
+	/**
+	Test whether a activity can start given the current context. If it can, the first transition will be executed.
+	Note that this is a static method, and as such the activity hasn't been instanciated when this is called
+
+	@param aContext the context in which the activity may be executed
+	@param aActivitySig the activity which we are testing for the accept condition
+	@param aTransitionTag the condition which must be matched by the first entry for the activity to be accepted. Set to KExecuteAlways to skip this check
+
+	@return the first entry triple for the activity if it's accepted. NULL otherwise
+	*/
+	static const NetStateMachine::TStateTriple* Accept(TNodeContextBase& aContext, const TNodeActivity& aActivitySig, TInt aTransitionTag);
+
+	/**
+	Start a new activity. The first transition should have been run within the @c Accept() method before this is called.
+
+	@param aContext  The context to start the activity in
+	@param aOriginator  The peer that requires this activity to start
+	@param aFirst       First entry triple in the activity, as returned by @c Accept()
+	*/
+	IMPORT_C virtual void StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const NetStateMachine::TStateTriple& aFirst);
+
+protected:
+	/**
+	Append self to the node's list of running activities.
+
+	Should only be accessed from @c Activity::NewL. Generally activities can choose to be inserted or appended
+	(if they do not choose they are appended by default). When inserting, extreme caution must be taken, as
+	this behavior is reserved for destroying activities.
+	*/
+	IMPORT_C void AppendActivityL();
+
+	/**
+	Append self to the node's list of running activities. This should only be called if you are certain that
+	the activity list has space for the append.
+	*/
+	IMPORT_C void AppendPreallocatedActivity();
+
+	/**
+	Insert an activity at the start of the node's list of running activities.
+	*/
+	IMPORT_C void InsertPreallocatedDestroyActivity();
+
+	/**
+	Borrow some preallocated memory from the node. This preallocated memory is used for activities that
+	absolutely cannot fail in any scenario, such as for Destroying the node. For this reason, when the
+	node is created, some memory is allocated so that a destroying activity can't even fail in an out
+	of memory situation.
+
+	This method is static as the memory must be borrowed before the activity object is constructed.
+
+	The memory is returned using @c ReturnPreallocatedSpace().
+
+	@param aNode The node that owns the preallocated space. This must be the node that the activity runs on.
+	@param aSize Size of buffer to allocate.
+
+	@return A pointer to the allocated block of memory
+	*/
+	IMPORT_C static TAny* BorrowPreallocatedSpace(AMMNodeBase& aNode, TUint aSize);
+
+	/**
+	Return preallocated space to the node. The node does not have to be passed in as a parameter as it will
+	already be a member of the activity.
+
+	@param aSpace Memory buffer to return.
+	*/
+	IMPORT_C void ReturnPreallocatedSpace(TAny* aSpace);
+	
+	/**
+	Test whether aContext carries a message that is to be expected by 'this' in its current state. 
+	The method is effectivelly a filter that hides the messages flowing throught the node, but not
+	intended for 'this'. The method will check:
+	- if aContext carries a message from PostedToId (if set) then the message should be presented to 'this'.
+	- if aContext carries a message from one of the originators then the message should be presented to 'this'.
+	@return ETrue if the sender of the current message matches PostedToId if it is set.
+	*/
+	IMPORT_C TBool MatchSender(const TNodeContextBase& aContext) const;	
+
+protected:
+	/**
+	The node the activity is running on
+	*/
+	AMMNodeBase& iNode;
+
+	/**
+	All the nodes that have started the same activity
+	*/
+	RArray<Messages::XNodePeerId> iOriginators;
+
+private: //Shouldn't be accessed directly
+	TInt     iError;    //Risk of failure is a generic property of an activity.
+	                    //Activities may choose to use external error handling activities,
+	                    //or may choose to handle errors locally. In the latter case,
+	                    //the activity may want to know it's running an error mode
+	                    //(by setting this member).
+	                    //iError must be cleared before the activity goes out of scope
+	                    //to indicate the error has been handled.
+
+	const TNodeActivity& iActivitySig;
+
+	// Last node a message was sent to
+	Messages::TNodeId iPostedToId;
+	};
+
+
+/**
+Activity type that generates a unique activity id every time it is instantiated.
+The id is generated from the @c <TNodeActivityId::EActivityParallelRangeMin,TCFNodeActivityId::EActivityParallelRangeMax>
+range. The id should never be found in a static activity map.
+A new instance id is created rather than adding a new originator to the existing activity.
+*/
+class CNodeParallelActivityBase : public CNodeActivityBase
+
+	{
+public:
+	/**
+    Create a new activity. This should never be called by user code.
+
+	@param aActivitySig Context information about how the activity is to be started
+	@param aNode        The node to which this activity will belong.
+	@return A pointer to the new activity. Ownership is transfered.
+	*/
+    IMPORT_C static CNodeActivityBase* NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
+
+	/**
+	Get the activity id
+	@return The activity id of the activity
+	*/
+   	IMPORT_C virtual TUint16 ActivityId() const;
+
+protected:
+	/**
+	For use by custom activity NewLs to generate the unique part of the activity id.
+	@param aActivitySig Context information about how the activity is to be started
+	@param aNode        The node to which this activity will belong.
+	@return Generated unique component of activity id
+	*/
+	IMPORT_C static TUint GetNextActivityCountL( const TNodeActivity& aActivitySig, const AMMNodeBase& aNode );
+
+	/**
+	Constructor for CNodeParallelActivityBase
+	@param aActivitySig Context information about how the activity is to be started
+	@param aNode        The node to which this activity will belong.
+	@param aNextActivityCount The unique part of the activity id
+	*/
+    IMPORT_C CNodeParallelActivityBase( const TNodeActivity& aActivitySig, AMMNodeBase& aNode, TUint aNextActivityCount );
+
+protected:
+	/**
+	The activity id. The id format is [8 bit unique id|8 bit activity sig].
+	*/
+    TUint16 iActivityId;
+	};
+
+/**
+   Base class for parallel activities which store their kickoff message.
+
+   @see CNodeParallelActivityBase
+*/
+class CNodeParallelMessageStoreActivityBase : public CNodeParallelActivityBase
+	{
+public:
+	IMPORT_C static CNodeActivityBase* NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode );
+	IMPORT_C ~CNodeParallelMessageStoreActivityBase();
+
+	/**
+	   @return Kick off message for this activity
+	*/
+	IMPORT_C Messages::TSignalBase& Message();
+
+protected:
+	IMPORT_C virtual void StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const NetStateMachine::TStateTriple& aFirst);
+	void SaveMessageL(Messages::TSignalBase& aMessage);
+	
+	IMPORT_C CNodeParallelMessageStoreActivityBase( const MeshMachine::TNodeActivity& aActivitySig,
+		MeshMachine::AMMNodeBase& aNode, TUint aNextActivityCount );
+
+private:
+	Messages::TSignalBase* iMsg;
+	TBuf8<__Align8(Messages::TSignalBase::KMaxInlineMessageSize + Messages::TSignalBase::KMaxUnstoredOverhead)> iMsgBuf;
+	};
+
+/**
+
+If an activity has a transition or fork that is blocked by a mutex, the context must be stored so
+that when the transition or fork is unblocked it would be able to continue with the context that
+it had before it was blocked. If this aggregate wasn't used in the previous scenario, the context
+of the event that triggered the unblocking would be used, and this may have the wrong message, or
+event originator set.
+
+Error recovery is another scenario this class is useful in.
+*/
+class AContextStore
+    {
+public:
+    /**
+    Interface id
+    */
+    static const TInt KInterfaceId = 0x102864DC;
+
+protected:
+    /**
+    Constructor for AContextStore
+    */
+    explicit AContextStore()
+        {
+        }
+    /**
+    Destructor for AContextStore
+    */
+    ~AContextStore()
+        {
+    	iContextDesc.Close();
+        }
+
+public:
+	/**
+	Used for error recovery. If the context is stored, loads the stored context and reruns the last transition that was run.
+
+	@param aActivity The activity to retry
+	@param aContext  The context within which the retrying is taking place. NOTE: This is not the stored context
+
+	@see StoreContext
+	@see LoadContext
+	*/
+	IMPORT_C void Retry(CNodeActivityBase& aActivity, TNodeContextBase& aContext);
+
+    /**
+	Store context in buffer. Designed to be called from a transition to store the transitions context for error recovery or
+	to wait on a mutex.
+
+	@param aContext The context to store
+	@return Error code. @c KErrNone if storage is successful.
+	*/
+	IMPORT_C TInt StoreContext(const TNodeContextBase& aContext);
+
+	/**
+	Check of the context is stored.
+	@return @c ETrue if a context is stored. @c EFalse otherwise.
+	*/
+	IMPORT_C TBool IsStored() const;
+
+	/**
+	Get the id of the message which requested @c Retry()
+	@return Message Id of message which kicked off the @c ::Retry
+
+	@see AContextStore::Retry
+	*/
+ 	IMPORT_C const Messages::TNodeSignal::TMessageId& RetryingForMessageId() const; //Needs to be moved to error-recoverable activity class
+
+protected:
+	/**
+	Load a stored context. Once the stored context has been loaded the status of @c iContextDesc is undefined and load shouldn't
+	be called again until something has been stored.
+
+	The pointer returned uses memory allocated in the @c aCtxBuff that is passed in, and as such, does not need to be freed. However @c aCtxBuff and @c aMsgBuff
+	must be cleaned up after use.
+
+	@param aNode The node for the context
+	@param aNodeActivity The activity for the context.
+	@param aCtxBuff  A memory buffer in which the context will be created.
+	@param aMsgBuff  A memory buffer in which the message will be created.
+	@param aDummy    Will become the recipient node id in the context.
+
+	@return Pointer to loaded context
+	*/
+	IMPORT_C TNodeContextBase* LoadContext(AMMNodeBase& aNode, CNodeActivityBase* aNodeActivity, TDes8& aCtxBuff, TDes8& aMsgBuff, const Messages::TNodeId& aDummy);
+
+protected:
+	/**
+    Buffer to store the context.
+	*/
+	RBuf8 iContextDesc;
+	/**
+	Message id of the message which kicked off the retry attempt
+	*/
+	Messages::TNodeSignal::TMessageId iRetryingForMessageId;
+	};
+
+/**
+Aggregate class for activities which wish to use mutexes.
+
+After a serialised state or transition has been unblocked, signalled and invoked, AActivitySemaphore
+clears all of the synchronisation related information (e.g stored context), assuming that the job has
+been done. Sometimes however the serialised state, upon more careful inspection of the environment
+(context), may decide that it still does not want to be executed and it wishes to sleep again.
+
+In such case it would call Wait() and return @c EIgnore from its @c TransitionTag(). The same applies to a
+serialised transition. It may want to call Wait() instead of, for example sending a request message.
+
+After calling Wait() the serialised state will be woken up when the policy matches, which allows the serialised state
+to finish its job.
+ */
+class AActivitySemaphore : public AContextStore
+    {
+public:
+    /**
+    Interface id
+    */
+    static const TInt KInterfaceId = 10015; //Normally a UID - 10015 for compatibility reasons
+
+public:
+	/**
+	Park a state.
+
+	@param aContext The context which the state is to run in. This will be stored
+
+	@return @c KErrNone if successful. System wide error code otherwise
+	*/
+	IMPORT_C static TInt ParkState(const TNodeContextBase& aContext);
+
+	/**
+	Unpark a state.
+
+	@param aContext The context which the state is to run in.
+
+	@return @c KErrNone if successful. System wide error code otherwise
+	*/
+	IMPORT_C static TInt UnparkState(const TNodeContextBase& aContext);
+
+	/**
+	Park a transition
+
+	@param aContext The context which the transition is to run in.
+	*/
+	IMPORT_C static void ParkTransitionL(const TNodeContextBase& aContext);
+
+	/**
+	Signals to the activity that an event has occurred. Used for waking up sleeping activities
+	which use mutexes. The activity is expected to check if the mutex has now cleared.
+
+	@param aContext Current context in the state machine.
+
+	@return @c ETrue if the state or transition has been unparked
+	*/
+	IMPORT_C TBool Signal(TNodeContextBase& aContext);
+
+	/**
+	Tell the activity to wait. The activity will wait until Signal() is called.
+	*/
+	IMPORT_C void Wait();
+
+	/**
+	Check if the activity is waiting
+	@return ETrue if the activity is currently waiting
+	*/
+	TBool IsWaiting() const
+		{
+		__ASSERT_DEBUG(!(iFlags&KIsWaiting) || IsStored(), User::Panic(KSpecAssert_ElemMeshMachActH, 3));
+
+		return iFlags&KIsWaiting;
+		}
+
+protected:
+    /**
+    Constructor for AActivitySemaphore
+    */
+    explicit AActivitySemaphore()
+    :   iFlags(0)
+		{
+        }
+    /**
+    Destructor for AActivitySemaphore
+    */
+    ~AActivitySemaphore()
+        {
+        }
+
+protected:
+	/**
+	Set the @c isWaiting flag
+	*/
+	inline void SetIsWaiting() { iFlags|=KIsWaiting; };
+	/**
+	Clear the @c isWaiting flag
+	*/
+	inline void ClearIsWaiting() { iFlags&=~KIsWaiting; };
+
+	/**
+	Check if the WillWait flag is set. The WillWait flag indicates whether the activity will be in a waiting state at the end of the signal function.
+	This is distinct from "is waiting" which indicates whether the activity was waiting on entry to the Signal()
+	function.
+
+	@return ETrue if the WillWait flag is set
+	*/
+	inline TBool WillWait() const { return (iFlags&KWillWait)==KWillWait; };
+	/**
+	Set the willWait flag
+	*/
+	inline void SetWillWait() { iFlags|=KWillWait; };
+	/**
+	Clear the willWait flag
+	*/
+	inline void ClearWillWait() { iFlags&=~KWillWait; };
+
+private:
+	//Is waiting for mutex? == not idle yet, even if last triple
+ 	//iIsWaiting prevents Idle condition following the last
+	//transition (in case the transition has parked the activity
+	//and wants to be reexecuted). When reexecuting, the activity
+	//mustn't be idle (iIsWaiting has to be true), on the
+	//other hand the transition may to park the activity again
+	//We need to distinguish the entry value of iIsWaiting from
+	//the exit value of iIsWaiting, we hance need this aditional
+	//flag.
+
+	inline TBool IsTransition() const { return (iFlags&KIsTransition)==KIsTransition; };
+	inline void SetIsTransition() { iFlags|=KIsTransition; };
+	inline void ClearIsTransition() { iFlags&=~KIsTransition; };
+
+	enum { KIsWaiting = 0x1, KWillWait = 0x2, KIsTransition = 0x4 };
+
+	TUint8 iFlags;
+    };
+
+/**
+Activity class base for activities which wish to use synchronisation or retries.
+*/
+class CNodeRetryActivity : public CNodeActivityBase, public AActivitySemaphore,
+                public ITFHIERARCHY_2(CNodeRetryActivity, AContextStore, AActivitySemaphore)
+	{
+public:
+	/**
+	Defines a helper list of interfaces.
+ 	*/
+	typedef ITFHIERARCHY_2(CNodeRetryActivity, AContextStore, AActivitySemaphore) TIfStaticFetcherNearestInHierarchy;
+
+public:
+	/**
+    Create a new activity. This should never be called by user code.
+
+	@param aActivitySig Context information about how the activity is to be started
+	@param aNode        The node to which this activity will belong.
+	@return A pointer to the new object. Ownership is transfered.
+	*/
+    IMPORT_C static CNodeActivityBase* NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
+
+	/**
+	Fetch the context store interface
+	@param aInterface pointer into which a pointer to the interface will be placed.
+	*/
+    IMPORT_C void ReturnInterfacePtrL(AContextStore*& aInterface);
+
+	/**
+	Fetch the activity semaphore interface
+	@param aInterface On return, contains a pointer to the interface.
+	*/
+    IMPORT_C void ReturnInterfacePtrL(AActivitySemaphore*& aInterface);
+
+	/**
+	Check if the activity has stopped running
+	@return @c ETrue if the activity is still running, otherwise @c EFalse.
+	*/
+    IMPORT_C virtual TBool IsIdle() const;
+
+	/**
+	Put the activity into the idle state. This stops the activity running and notifies the mesh machine that
+	it is ok to delete this activity.
+	*/
+    IMPORT_C virtual void SetIdle();
+
+protected:
+	/**
+	Signal the activity that an event has occurred and that it is worthwhile checking
+	to see if the mutex has now cleared.
+
+	@param aContext Current context in the state machine.
+
+	@return @c ETrue if state or transition has been unparked
+	*/
+	IMPORT_C virtual TBool Signal(TNodeContextBase& aContext);
+
+    /**
+    Constructor for CNodeRetryActivity
+	@param aActivitySig Context information about how the activity is to be started
+	@param aNode        The node to which this activity will belong.
+    */
+    IMPORT_C CNodeRetryActivity( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
+	};
+
+/**
+Base class for activities that run in parallel and can be synchronised or retried.
+*/
+class CNodeRetryParallelActivity : public CNodeParallelActivityBase, public AActivitySemaphore,
+                public ITFHIERARCHY_2(CNodeRetryParallelActivity, AContextStore, AActivitySemaphore)
+	{
+public:
+	/**
+	Defines a helper list of interfaces.
+ 	*/
+ 	typedef ITFHIERARCHY_2(CNodeRetryParallelActivity, AContextStore, AActivitySemaphore) TIfStaticFetcherNearestInHierarchy;
+
+public:
+	/**
+    Create a new activity. This should never be called by user code.
+
+	@param aActivitySig Context information about how the activity is to be started
+	@param aNode        The node to which this activity will belong.
+	@return A pointer to the new object. Ownership is transfered.
+	*/
+    IMPORT_C static CNodeActivityBase* NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
+
+	/**
+	Fetch the context store interface
+	@param aInterface On return, contains a pointer to the store interface
+	*/
+    IMPORT_C void ReturnInterfacePtrL(AContextStore*& aInterface);
+
+	/**
+	Fetch the activity semaphore interface
+	@param aInterface On return, contains a pointer to the semaphore interface
+	*/
+    IMPORT_C void ReturnInterfacePtrL(AActivitySemaphore*& aInterface);
+
+	/**
+	Check if the activity has stopped
+	@return @c ETrue if the activity is still running, otherwise @c EFalse
+	*/
+    IMPORT_C virtual TBool IsIdle() const;
+
+	/**
+	Put the activity into the idle state. This stops the activity running and notifies the mesh machine that
+	it is ok to delete this activity.
+	*/
+    IMPORT_C virtual void SetIdle();
+
+protected:
+	/**
+	Signal to the activity that an event has occurred and that it is worthwhile checking
+	to see if the mutex has now cleared.
+
+	@param aContext Current context in the state machine.
+
+	@return @c ETrue if state or transition has been unparked
+	*/
+	IMPORT_C virtual TBool Signal(TNodeContextBase& aContext);
+
+	/**
+    Constructor for CNodeRetryParallelActivity
+
+	@param aActivitySig Context information about how the activity is to be started
+	@param aNode        The node to which this activity will belong.
+	@param aActivitiesCount The unique part of the activity id
+    */
+    IMPORT_C CNodeRetryParallelActivity( const TNodeActivity& aActivitySig, AMMNodeBase& aNode, TUint aActivitiesCount );
+	};
+
+/**
+Aggregate originator array template for activities that use preallocated space.
+This object has a fixed size array to hold the originators which will be allocated from the preallocated space
+when the node activity object is created.
+*/
+template <TInt ORIGINATORSCOUNT>
+class APreallocatedOriginators
+	{
+protected:
+	/**
+	Initialise the array and ensure it is empty as it should be on creation.
+	Generally, iOriginators from the activity will be passed into this as a reference. A new
+	RArray will then be created using the preallocated space.
+
+	@param aOriginators Array of originators for which to preallocate space
+	*/
+	explicit APreallocatedOriginators(RArray<Messages::XNodePeerId>& aOriginators)
+	:	iOriginatorsRef(aOriginators)
+		{
+		iOriginatorsRef = RArray<Messages::XNodePeerId>(sizeof(Messages::XNodePeerId), (Messages::XNodePeerId*)iOriginatorBuf, ORIGINATORSCOUNT);
+		for (TInt i = iOriginatorsRef.Count() - 1; i >= 0; --i)
+			{
+			iOriginatorsRef.Remove(i);
+			}
+		}
+    /**
+    Destructor for APreallocatedOriginators.
+    */
+	~APreallocatedOriginators()
+		{
+		iOriginatorsRef = RArray<Messages::XNodePeerId>();
+		}
+
+private:
+	//The originator's list
+	RArray<Messages::XNodePeerId>& iOriginatorsRef;
+    //Preallocated space in the originator's list
+    TUint8 iOriginatorBuf[__Align8(sizeof(Messages::XNodePeerId) * ORIGINATORSCOUNT)];
+	};
+
+/**
+Base for preallocated node activity class
+*/
+template <TInt ORIGINATORSCOUNT>
+class CPreallocatedNodeActivityBase : public MeshMachine::CNodeActivityBase,
+                                      protected MeshMachine::APreallocatedOriginators<ORIGINATORSCOUNT>
+/**
+@internalTechnology
+*/
+	{
+public:
+	/**
+    Create a new activity. This should never be called by user code.
+
+	@param aActivitySig Context information about how the activity is to be started
+	@param aNode        The node to which this activity will belong.
+	*/
+    static MeshMachine::CNodeActivityBase* New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+    	{
+   		TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CPreallocatedNodeActivityBase));
+		CPreallocatedNodeActivityBase* self = new (space) CPreallocatedNodeActivityBase(aActivitySig, aNode);
+		self->AppendPreallocatedActivity();
+		return self;
+    	}
+
+protected:
+
+
+	CPreallocatedNodeActivityBase(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	:	CNodeActivityBase(aActivitySig, aNode),
+		APreallocatedOriginators<ORIGINATORSCOUNT>(iOriginators)
+		{
+		}
+
+	/**
+	Destroy the activity. Return the preallocated space and call the destructor directly. i.e. not though delete
+	as delete would try and release the memory again
+	*/
+	virtual void Destroy()
+		{
+		ReturnPreallocatedSpace(this);
+		this->~CPreallocatedNodeActivityBase(); //Run the destructor
+		}
+private:
+	/**
+	Private NewL with no implementation to hide the CNodeActivityBase::NewL
+	Creation of preallocated activities doesn't fail and hence a non-leaving ::New should be used instead
+	*/
+    static MeshMachine::CNodeActivityBase* NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+	};
+
+//-=========================================================
+//
+// CPreallocatedNodeActivityBase
+//
+//-=========================================================
+template <TInt ORIGINATORSCOUNT>
+class CPreallocatedNodeRetryActivity : public MeshMachine::CNodeRetryActivity,
+                                      protected MeshMachine::APreallocatedOriginators<ORIGINATORSCOUNT>
+/**
+@internalTechnology
+*/
+	{
+public:
+    static MeshMachine::CNodeActivityBase* New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+    	{
+   		TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CPreallocatedNodeRetryActivity));
+		CPreallocatedNodeRetryActivity* self = new (space) CPreallocatedNodeRetryActivity(aActivitySig, aNode);
+		self->AppendPreallocatedActivity();
+		return self;
+    	}
+
+protected:
+	CPreallocatedNodeRetryActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	:	CNodeRetryActivity(aActivitySig, aNode),
+		APreallocatedOriginators<ORIGINATORSCOUNT>(iOriginators)
+		{
+		}
+
+	virtual void Destroy()
+		{
+		ReturnPreallocatedSpace(this);
+		this->~CPreallocatedNodeRetryActivity(); //Run the destructor
+		}
+private:
+	/*
+	Private NewL with no implementation to hide the CNodeActivityBase::NewL
+	Creation of preallocated activities doesn't fail and hence a non-leaving ::New should be used instead*/
+    static MeshMachine::CNodeActivityBase* NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
+	};
+
+} //namespace MeshMachine
+
+#endif //SYMBIAN_MM_ACTIVITIES_H
+