commsfwsupport/commselements/meshmachine/inc/mm_activities.h
changeset 0 dfb7c4ff071f
child 18 9644881fedd0
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // generic framework node state machine states
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @publishedPartner
       
    21  @released
       
    22 */
       
    23 
       
    24 #ifndef SYMBIAN_MM_ACTIVITIES_H
       
    25 #define SYMBIAN_MM_ACTIVITIES_H
       
    26 
       
    27 #include <elements/mm_node.h>
       
    28 #include <elements/mm_nodepeer.h>
       
    29 #include <elements/mm_activities_internal.h>
       
    30 #include <elements/nm_address_internal.h>
       
    31 #include <elements/nm_signatures.h>
       
    32 
       
    33 
       
    34 #ifdef _DEBUG
       
    35 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    36 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    37 _LIT(KSpecAssert_ElemMeshMachActH, "ElemMeshMachActH");
       
    38 #endif
       
    39 
       
    40 //-=========================================================
       
    41 //
       
    42 // MACROS
       
    43 //
       
    44 //-=========================================================
       
    45 
       
    46 /**
       
    47 Declare and export a node activity.
       
    48 
       
    49 @param name  The name of the activity, which will be used to put it into the node's activity map
       
    50 
       
    51 @see DECLARE_NODEACTIVITY
       
    52 */
       
    53 #define DECLARE_EXPORT_NODEACTIVITY( name ) \
       
    54 	struct name \
       
    55 		{ \
       
    56 		IMPORT_C static const MeshMachine::TNodeActivity& Self(); \
       
    57 		IMPORT_C static const NetStateMachine::TStateTriple& FirstTriple(); \
       
    58 		static const MeshMachine::TNodeActivity iSelf; \
       
    59 		static const NetStateMachine::TStateTriple iData[]; \
       
    60 		};
       
    61 
       
    62 /**
       
    63 Declares a node activity. A node activity is a state machine. It contains multiple nodeactivity
       
    64 entries, which respresent the states, transitions and forks of the state machine.
       
    65 
       
    66 @param name  The name of the activity, which will be used to put it into the node's activity map
       
    67 
       
    68 @see DEFINE_NODEACTIVITY
       
    69 @see NODEACTIVITY_ENTRY
       
    70 */
       
    71 #define DECLARE_NODEACTIVITY( name ) \
       
    72 	struct name \
       
    73 		{ \
       
    74 		inline static const MeshMachine::TNodeActivity& Self() {return iSelf;} \
       
    75 		inline static const NetStateMachine::TStateTriple& FirstTriple() {return iData[1];} \
       
    76 		static const MeshMachine::TNodeActivity iSelf; \
       
    77 		static const NetStateMachine::TStateTriple iData[]; \
       
    78 		};
       
    79 
       
    80 #ifdef SYMBIAN_TRACE_ENABLE
       
    81 /**
       
    82 Define and export a custom node activity.
       
    83 
       
    84 @param id        Identifier for the activity
       
    85 @param name      The name of the activity
       
    86 @param msgtype   Message which will kickoff this activity
       
    87 @param ctor      Constructor for the custom activity class
       
    88 
       
    89 @see DEFINE_CUSTOM_NODEACTIVITY
       
    90 */
       
    91 	#define DEFINE_EXPORT_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
       
    92 		EXPORT_C const MeshMachine::TNodeActivity& name :: Self() {return iSelf;} \
       
    93 		EXPORT_C const NetStateMachine::TStateTriple& name :: FirstTriple() {return iData[1];} \
       
    94 		const MeshMachine::TNodeActivity name :: iSelf = {id, msgtype::EId, msgtype::ERealm, name :: iData[1], &ctor, _S8(#name)}; \
       
    95 		DEFINE_TRIPLES_TABLE( name :: iData )
       
    96 
       
    97 /**
       
    98 Define a custom node activity. A custom node activity is a node activity which defines its own
       
    99 node activity class. This is used, for example, if the activity wishes to share some custom context
       
   100 information between the states and transition in the activity.
       
   101 
       
   102 Node activity class must derive from CNodeActivityBase.
       
   103 
       
   104 @param id        Identifier for the activity
       
   105 @param name      The name of the activity
       
   106 @param msgtype   Message which will kickoff this activity
       
   107 @param ctor      Constructor for the custom activity class
       
   108 
       
   109 @see DEFINE_NODEACTIVITY
       
   110 @see CNodeActivityBase
       
   111 */
       
   112 	#define DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
       
   113 		const MeshMachine::TNodeActivity name :: iSelf = {id, msgtype::EId, msgtype::ERealm, name :: iData[1], &ctor, _S8(#name)}; \
       
   114 		DEFINE_TRIPLES_TABLE( name :: iData )
       
   115 
       
   116 #else
       
   117 
       
   118 /**
       
   119 Define and export a custom node activity.
       
   120 
       
   121 @param id        Identifier for the activity
       
   122 @param name      The name of the activity
       
   123 @param msgtype   Message which will kickoff this activity
       
   124 @param ctor      Constructor for the custom activity class
       
   125 
       
   126 @see DEFINE_CUSTOM_NODEACTIVITY
       
   127 */
       
   128 	#define DEFINE_EXPORT_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
       
   129 		EXPORT_C const MeshMachine::TNodeActivity& name :: Self() {return iSelf;} \
       
   130 		EXPORT_C const NetStateMachine::TStateTriple& name :: FirstTriple() {return iData[1];} \
       
   131 		const MeshMachine::TNodeActivity name :: iSelf = {id, msgtype::EId, msgtype::ERealm, name :: iData[1], &ctor, NULL}; \
       
   132 		DEFINE_TRIPLES_TABLE( name :: iData )
       
   133 
       
   134 /**
       
   135 Define a custom node activity. A custom node activity is a node activity which defines its own
       
   136 node activity class. This is used, for example, if the activity wishes to share some custom context
       
   137 information between the states and transition in the activity.
       
   138 
       
   139 Node activity class must derive from CNodeActivityBase.
       
   140 
       
   141 @param id        Identifier for the activity
       
   142 @param name      The name of the activity
       
   143 @param msgtype   Message which will kickoff this activity
       
   144 @param ctor      Constructor for the custom activity class
       
   145 
       
   146 @see DEFINE_NODEACTIVITY
       
   147 @see CNodeActivityBase
       
   148 */
       
   149 	#define DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
       
   150 		const MeshMachine::TNodeActivity name :: iSelf = {id, msgtype::EId, msgtype::ERealm, name :: iData[1], &ctor, NULL}; \
       
   151 		DEFINE_TRIPLES_TABLE( name :: iData )
       
   152 
       
   153 #endif
       
   154 
       
   155 /**
       
   156 Define and declare a custom node activity
       
   157 
       
   158 @param id        Identifier for the activity
       
   159 @param name      The name of the activity
       
   160 @param msgtype   Message which will kickoff this activity
       
   161 @param ctor      Constructor for the custom activity class
       
   162 
       
   163 @see DEFINE_CUSTOM_NODEACTIVITY
       
   164 */
       
   165 #define DECLARE_DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor ) \
       
   166 	DECLARE_NODEACTIVITY( name ) \
       
   167 	DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, ctor )
       
   168 
       
   169 /**
       
   170 Define and export node activity
       
   171 
       
   172 @param id        Identifier for the activity
       
   173 @param name      The name of the activity
       
   174 @param msgtype   Message which will kickoff this activity
       
   175 
       
   176 @see DEFINE_NODEACTIVITY
       
   177 */
       
   178 #define DEFINE_EXPORT_NODEACTIVITY( id, name, msgtype ) \
       
   179 	DEFINE_EXPORT_CUSTOM_NODEACTIVITY( id, name, msgtype, MeshMachine::CNodeActivityBase::NewL )
       
   180 
       
   181 /**
       
   182 Define the start of a node activity. There must be a matching @c NODEACTIVITY_END to close the
       
   183 node activity.
       
   184 
       
   185 The @c id is a unique identifier for the activity. It allows activities to be overridden in an
       
   186 activity map. When deriving from an activity map, if you specify a node activity in your map
       
   187 whose id is the same as one in the parent map, the one in the parent map with be overriden.
       
   188 
       
   189 The @c name of the activity is used to add it to the activity map.
       
   190 
       
   191 The @c msgtype is the type of message which will initiate this activity. This can be left as the
       
   192 null message, in which case it will be the first state which decides whether to start the activity
       
   193 or not.
       
   194 
       
   195 @code
       
   196 namespace ExampleActivity {
       
   197 DEFINE_NODEACTIVITY(EFoobarActivity, SimpleFoobarActivity, TFoobar)
       
   198     FIRST_NODEACTIVITY_ENTRY(TAwaitingFoobar, TDoOneThingOrAnother)
       
   199 	NODEACTIVITY_ENTRY(KDoOneThing, TDoTheThing, TAwaitingResponseToThing, TNoTag)
       
   200 	NODEACTIVITY_ENTRY(KAnother, TDoTheOtherThing, TAwaitingResponseToThing, TNoTag)
       
   201 	LAST_NODEACTIVITY_ENTRY(KNoTag, TDoFinalThing)
       
   202 NODEACTIVITY_END()
       
   203 } // end namespace ExampleActivity
       
   204 @endcode
       
   205 
       
   206 A node activity must start with either a @c FIRST_NODEACTIVITY_ENTRY or a @c SINGLE_NODEACTIVITY_ENTRY. In
       
   207 the latter case there should be no other entries in the node activity.
       
   208 
       
   209 The activity object (@c CNodeActivityBase) is only created once the second @c NODEACTIVITY_ENTRY is entered.
       
   210 
       
   211 @param id        Identifier for the activity
       
   212 @param name      The name of the activity
       
   213 @param msgtype   Message which will kickoff this activity
       
   214 
       
   215 @see DEFINE_ACTIVITY_MAP
       
   216 */
       
   217 #define DEFINE_NODEACTIVITY( id, name, msgtype ) \
       
   218 	DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, MeshMachine::CNodeActivityBase::NewL )
       
   219 
       
   220 /**
       
   221 Define and declare a node activity
       
   222 
       
   223 @param id        Identifier for the activity
       
   224 @param name      The name of the activity
       
   225 @param msgtype   Message which will kickoff this activity
       
   226 
       
   227 @see DEFINE_ACTIVITY_MAP
       
   228 */
       
   229 #define DECLARE_DEFINE_NODEACTIVITY( id, name, msgtype ) \
       
   230 	DECLARE_DEFINE_CUSTOM_NODEACTIVITY( id, name, msgtype, MeshMachine::CNodeActivityBase::NewL )
       
   231 
       
   232 /**
       
   233 Define an entry in a node activity.
       
   234 
       
   235 @param transitionTag     Condition on which the entry is entered
       
   236 @param stateTransition   Transition to be executed
       
   237 @param state             State to enter after
       
   238 @param stateFork         Fork to decide which entry to enter next
       
   239 
       
   240 @see DEFINE_NODEACTIVITY
       
   241 */
       
   242 #define NODEACTIVITY_ENTRY( transitionTag, stateTransition, state, stateFork ) \
       
   243 	STATE_TRIPLE_ENTRY( transitionTag, stateTransition, state, stateFork )
       
   244 
       
   245 /**
       
   246 Define the first entry in a node activity
       
   247 
       
   248 @param firstState       Initial state of the activity
       
   249 @param firstStateFork   Fork to decide which entry to enter next
       
   250 
       
   251 @see DEFINE_NODEACTIVITY
       
   252 */
       
   253 #define FIRST_NODEACTIVITY_ENTRY( firstState, firstStateFork ) \
       
   254 	FIRST_TRIPLE_ENTRY( firstState, firstStateFork )
       
   255 
       
   256 /**
       
   257 Define a through entry. Through entries execute a transition but do not
       
   258 enter a state. Instead they move onto the next entry in the node activity
       
   259 using the @c stateFork to decide which entry this is.
       
   260 
       
   261 @param transitionTag   Condition on which the entry is entered
       
   262 @param stateTransition Transition to be executed
       
   263 @param stateFork       Fork to decide which entry to enter next
       
   264 */
       
   265 #define THROUGH_NODEACTIVITY_ENTRY( transitionTag, stateTransition, stateFork ) \
       
   266 	THROUGH_TRIPLE_ENTRY( transitionTag, stateTransition, stateFork )
       
   267 
       
   268 /**
       
   269 Define the final entry in a node activity.
       
   270 
       
   271 @param transitionTag  Condition on which the entry is entered
       
   272 @param lastTransition Final transition to be executed
       
   273 
       
   274 @see DEFINE_NODEACTIVITY
       
   275 */
       
   276 #define LAST_NODEACTIVITY_ENTRY( transitionTag, lastTransition ) \
       
   277 	LAST_TRIPLE_ENTRY( transitionTag, lastTransition )
       
   278 
       
   279 /**
       
   280 Define a single node activity entry. This is the first and last entry in any
       
   281 node activity in which it is used.
       
   282 
       
   283 @param state             Initial state of the activity
       
   284 @param stateTransition   Transition to execute once the state is fulfilled
       
   285 
       
   286 @see DEFINE_NODEACTIVITY
       
   287 */
       
   288 #define SINGLE_NODEACTIVITY_ENTRY( stateTransition, state ) \
       
   289 	STATE_TRIPLE_ENTRY( MeshMachine::KNoTag, stateTransition, state, MeshMachine::TNoTag )
       
   290 
       
   291 /**
       
   292 Define a routing node activity entry. Routing entries neither execute any
       
   293 transition, nor wait in any state. These are useful only for redirecting the
       
   294 path of execution in the state machine.
       
   295 
       
   296 @param transitionTag  Condition on which the entry is entered
       
   297 @param stateFork      Fork to decide the next transition to enter
       
   298 */
       
   299 #define ROUTING_NODEACTIVITY_ENTRY( transitionTag, stateFork ) \
       
   300 	THROUGH_TRIPLE_ENTRY( transitionTag, MeshMachine::TDoNothing, stateFork )
       
   301 
       
   302 /**
       
   303 Marks the end of a node activity.
       
   304 
       
   305 @see DEFINE_NODEACTIVITY
       
   306 */
       
   307 #define NODEACTIVITY_END() \
       
   308 	TRIPLES_TABLE_END()
       
   309 
       
   310 
       
   311 
       
   312 /**
       
   313 Declare and export an activity map
       
   314 
       
   315 @param map Name of the activity map
       
   316 @see DECLARE_ACTIVITY_MAP
       
   317 */
       
   318 #define DECLARE_EXPORT_ACTIVITY_MAP( map ) \
       
   319 	struct map \
       
   320 		{ \
       
   321 		IMPORT_C static const MeshMachine::TNodeActivityMap& Self(); \
       
   322 		static const MeshMachine::TNodeActivityMap iSelf; \
       
   323 		static const MeshMachine::TNodeActivityMap::TStaticNodeActivity iData[]; \
       
   324 		};
       
   325 
       
   326 /**
       
   327 Define and export the activity map
       
   328 
       
   329 @param map Name of the activity map
       
   330 @see DEFINE_ACTIVITY_MAP
       
   331 */
       
   332 #define DEFINE_EXPORT_ACTIVITY_MAP( map ) \
       
   333 	EXPORT_C const MeshMachine::TNodeActivityMap& map :: Self() {return iSelf;} \
       
   334 	const MeshMachine::TNodeActivityMap map :: iSelf = {map :: iData[0]}; \
       
   335 	const MeshMachine::TNodeActivityMap::TStaticNodeActivity map :: iData[] = {
       
   336 
       
   337 /**
       
   338 Declare an activity map.
       
   339 
       
   340 For example,
       
   341 @code
       
   342 DECLARE_ACTIVITY_MAP(MyNodeActivityMap)
       
   343 @endcode
       
   344 
       
   345 This can then be passed into the constructor of a mesh machine node as follows.
       
   346 
       
   347 @code
       
   348 CMyMeshNode::CMyMeshNode(CConnectionProviderFactoryBase& aFactory)
       
   349     : CCoreConnectionProvider(aFactory, MyNodeActivityMap::Self())
       
   350 	{
       
   351 	...
       
   352 @endcode
       
   353 
       
   354 @param map Name of the activity map
       
   355 */
       
   356 #define DECLARE_ACTIVITY_MAP( map ) \
       
   357 	struct map \
       
   358 		{ \
       
   359 		inline static const MeshMachine::TNodeActivityMap& Self() {return iSelf;} \
       
   360 		static const MeshMachine::TNodeActivityMap iSelf; \
       
   361 		static const MeshMachine::TNodeActivityMap::TStaticNodeActivity iData[]; \
       
   362 		}; \
       
   363 
       
   364 /**
       
   365 Define an activity map. An activity map is a collection of node activities. The activity map can be
       
   366 based on another activity map or this macro can be used to define a standalone activity map.
       
   367 
       
   368 Once defined an activity map can be passed into the constructor of a node, to define
       
   369 what activities that node is capable of executing.
       
   370 
       
   371 @code
       
   372 DECLARE_DEFINE_ACTIVITY_MAP(MyNodeActivityMap)
       
   373 	ACTIVITY_MAP_ENTRY(MyNodeActivities, MyFirstActivity)
       
   374 	ACTIVITY_MAP_ENTRY(MyNodeActivities, MySecondActivity)
       
   375 ACTIVITY_MAP_END_BASE(BaseActivities, BaseActivityMap)
       
   376 @endcode
       
   377 
       
   378 @param map Name of the activity map
       
   379 
       
   380 @see ACTIVITY_MAP_END_BASE
       
   381 @see ACTIVITY_MAP_END
       
   382 */
       
   383 #define DEFINE_ACTIVITY_MAP( map ) \
       
   384 	const MeshMachine::TNodeActivityMap map :: iSelf = {map :: iData[0]}; \
       
   385 	const MeshMachine::TNodeActivityMap::TStaticNodeActivity map :: iData[] = {
       
   386 
       
   387 /**
       
   388 Define and declare an activity map.
       
   389 
       
   390 @param map Name of the activity map
       
   391 
       
   392 @see DEFINE_ACTIVITY_MAP
       
   393 */
       
   394 #define DECLARE_DEFINE_ACTIVITY_MAP( map ) \
       
   395 	DECLARE_ACTIVITY_MAP(map) \
       
   396 	DEFINE_ACTIVITY_MAP(map)
       
   397 
       
   398 /**
       
   399 Create an entry in an activity map.
       
   400 
       
   401 @param name_space Namespace of the activity
       
   402 @param name       Name of the activity
       
   403 
       
   404 @see DEFINE_ACTIVITY_MAP
       
   405 */
       
   406 #define ACTIVITY_MAP_ENTRY( name_space, name ) &name_space::name::Self,
       
   407 
       
   408 /**
       
   409 Mark the end of an activity map. This macro should be used for standalone activity
       
   410 maps.
       
   411 
       
   412 @see DEFINE_ACTIVITY_MAP
       
   413 */
       
   414 #define ACTIVITY_MAP_END() \
       
   415 	NULL, \
       
   416 	NULL \
       
   417 	};
       
   418 
       
   419 /**
       
   420 Mark the end of an activity map. This macro should be used for an activity map based
       
   421 on other activity maps.
       
   422 
       
   423 @param name_space The namespace of the base map
       
   424 @param base_map   The name of the base map
       
   425 
       
   426 @see DEFINE_ACTIVITY_MAP
       
   427 */
       
   428 #define ACTIVITY_MAP_END_BASE( name_space, base_map ) \
       
   429 	NULL, \
       
   430 	(MeshMachine::TNodeActivityMap::TStaticNodeActivity)&name_space::base_map::Self \
       
   431 	};
       
   432 
       
   433 namespace MeshMachine
       
   434 {
       
   435 /**
       
   436 Base class for all node activity objects. Non custom node activities will use this by default.
       
   437 **/
       
   438 class CNodeActivityBase : public CBase,
       
   439                           public NetInterfaces::AApiExtBase,
       
   440                           protected NetStateMachine::ACore,
       
   441                           protected NetInterfaces::TInterfaceControl
       
   442 	{
       
   443     friend class AMMNodeBase;
       
   444     friend class AContextStore; //to be able access NetStateMachine::ACore
       
   445     friend class AActivitySemaphore; //to be able access NetStateMachine::ACore
       
   446 
       
   447 public:
       
   448 	/**
       
   449 	   Create a new activity. This should never be called by user code.
       
   450 
       
   451 	   @param aActivitySig Context information about how the activity is to be started
       
   452 	   @param aNode        The node to which this activity will belong.
       
   453 	   @return A pointer to the new Activity base object. Ownership is transferred.
       
   454 	*/
       
   455     IMPORT_C static CNodeActivityBase* NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
       
   456 
       
   457 	/**
       
   458 	Get the @c id of the activity.
       
   459 	   @return The activity id of the activity
       
   460 	*/
       
   461 	IMPORT_C virtual TUint16 ActivityId() const;
       
   462 
       
   463 	/**
       
   464 	   Remove an originator from the originator list.
       
   465 
       
   466 	   @param aIndex Index of originator to remove
       
   467 	*/
       
   468 	IMPORT_C void RemoveOriginator(TInt aIndex);
       
   469 
       
   470 	/**
       
   471 	Check if the activity is running.
       
   472 	   @return ETrue if the activity is still running, otherwise EFalse.
       
   473 	*/
       
   474 	IMPORT_C virtual TBool IsIdle() const;
       
   475 
       
   476 	/**
       
   477 	   Put the activity into the idle state. This stops the activity running and notifies the mesh machine that
       
   478 	   it's ok to delete this activity.
       
   479 	*/
       
   480 	IMPORT_C virtual void SetIdle();
       
   481 
       
   482 	/**
       
   483 	   Return the activity signature id of the activity. This may not necessarily be the same as the activity id
       
   484 	   in the case of parallel activities, where the activity id will be [8 bit unique id|8 bit activity sig]
       
   485 
       
   486 	   @return The activity signature id
       
   487 	*/
       
   488     TUint ActivitySigId() const
       
   489    		{
       
   490   		return iActivitySig.iId;
       
   491    		}
       
   492 
       
   493 	/**
       
   494 	Get the current error state for the activity.
       
   495 	   @return The activity's current error state. @c KErrNone indicates there is no error.
       
   496 	*/
       
   497 	TInt Error() const
       
   498 		{
       
   499 		return iError;
       
   500 		}
       
   501 
       
   502 	/**
       
   503 	   Set the error state of the activity.
       
   504 
       
   505 	   @param aError error code to set
       
   506 	*/
       
   507 	void SetError(TInt aError)
       
   508 		{
       
   509 		if (iError == KErrNone || aError == KErrNone)
       
   510     		{
       
   511     		iError = aError;
       
   512     		};
       
   513 		}
       
   514 
       
   515 	/**
       
   516 	Get the id of the node that the last request from this activity was sent to.
       
   517 	   @return Node id of the last node the activity has posted a request to
       
   518 	*/
       
   519 	const Messages::TNodeId PostedToId() const
       
   520 		{
       
   521 		return iPostedToId;
       
   522 		}
       
   523 
       
   524 	/**
       
   525 	Get the id of the message that started this activity.
       
   526 	   @return Message id of message that kicked off this activity
       
   527 	*/
       
   528 	const Messages::TNodeSignal::TMessageId KickOffMessageId() const
       
   529 		{
       
   530 		return Messages::TNodeSignal::TMessageId(iActivitySig.iKickOffMessageId, iActivitySig.iKickOffMessageRealm);
       
   531 		}
       
   532 
       
   533 	/**
       
   534 	Get the id of the node that started this activity.
       
   535 	   @return Node peer id of the node whose message first kicked off this activity
       
   536 	*/
       
   537 	const Messages::TNodePeerId& FirstOriginator() const
       
   538 		{
       
   539 		__ASSERT_DEBUG(iOriginators.Count(), User::Panic(KSpecAssert_ElemMeshMachActH, 1));
       
   540 		return iOriginators[0];
       
   541 		}
       
   542 
       
   543 	/**
       
   544 	In essence the same as FirstOriginator(). This should be used in preference in situations where the activity should
       
   545 	be run in parallel, and therefore only ever have one originator.
       
   546 	   @return Node peer id of the node whose message first kicked off this activity
       
   547 	*/
       
   548 	const Messages::TNodePeerId& SoleOriginator() const
       
   549 		{
       
   550 		__ASSERT_DEBUG(iOriginators.Count() == 1, User::Panic(KSpecAssert_ElemMeshMachActH, 2));
       
   551 		return iOriginators[0];
       
   552 		}
       
   553 
       
   554 	/**
       
   555 	   Post a request to a node.
       
   556 
       
   557 	   @param aRecepient Endpoint for the message
       
   558 	   @param aMessage   Message to send
       
   559 	   @param aRecipientIdCritical If true, the postedTo id is set to the id of the recipient. If false, the postedTo id is set to null.
       
   560 	   @see PostedToId
       
   561 	*/
       
   562 	IMPORT_C void PostRequestTo(const Messages::RNodeInterface& aRecepient, const Messages::TSignalBase& aMessage, const TBool aRecipientIdCritical = ETrue);
       
   563 	/**
       
   564 	   Post a request to a node.
       
   565 
       
   566 	   @param aRecepient Endpoint for the message
       
   567 	   @param aMessage   Message to send
       
   568 	   @param aRecipientIdCritical If true, the postedTo id is set to the id of the recipient. If false, the postedTo id is set to null.
       
   569 	   @see PostedToId
       
   570 	*/
       
   571 	IMPORT_C void PostRequestTo(const Messages::TNodeId& aRecepient, const Messages::TSignalBase& aMessage, const TBool aRecipientIdCritical = ETrue);
       
   572 
       
   573 	/**
       
   574 	   Manually set the postedTo id
       
   575 
       
   576 	   @param aNodeId Node id to set the postedTo id to
       
   577 	*/
       
   578 	IMPORT_C void SetPostedTo(const Messages::TNodeId& aNodeId);
       
   579 
       
   580 	/**
       
   581 	   Clear the postedTo id
       
   582 	*/
       
   583 	IMPORT_C void ClearPostedTo();
       
   584 
       
   585 #ifdef SYMBIAN_TRACE_ENABLE
       
   586 	/**
       
   587 	   @return the human readable name of the activity
       
   588 	*/
       
   589     const TText8* ActivityName() const
       
   590         {
       
   591         return (iActivitySig.iName)? iActivitySig.iName : _S8("Undefined");
       
   592         }
       
   593 
       
   594 	/**
       
   595 	   @return the human readable description of the current node activity entry
       
   596 	*/
       
   597     const TText8* CurrentTripleName() const
       
   598         {
       
   599         return ACore::CurrentTripleName();
       
   600         }
       
   601 #endif
       
   602 
       
   603 public:
       
   604 	/**
       
   605 	Cancels the activity. Only to be called by the meshmachine.
       
   606 	@param aContext the context in which the activity is being executed
       
   607 	@internalAll
       
   608 	*/
       
   609 	IMPORT_C virtual void Cancel(TNodeContextBase& aContext);
       
   610 
       
   611 	/**
       
   612 	Attempt to advance the activity one entry. Only to be called by the mesh machine
       
   613 	@param aContext the context in which the activity is being executed
       
   614 	@return Whether the activity advanced
       
   615 	@internalAll
       
   616 	*/
       
   617 	IMPORT_C virtual TBool Next(TNodeContextBase& aContext);
       
   618 
       
   619 	/**
       
   620 	Find the originator matching the parameters
       
   621 	@param aPeerToFind Matching criteria
       
   622 	@return Index of the matching originator. KErrNotFound if not found.
       
   623 	@internalAll
       
   624 	*/
       
   625 	IMPORT_C TInt FindOriginator(const Messages::RNodeInterface& aPeerToFind) const;
       
   626 
       
   627 	/**
       
   628    	Find the originator matching the parameters
       
   629 	@param aPeerToFind Matching criteria
       
   630 	@return Index of the matching originator. KErrNotFound if not found.
       
   631 	@internalAll
       
   632 	*/
       
   633 	IMPORT_C TInt FindOriginator(const Messages::TRuntimeCtxId& aPeerToFind) const;
       
   634 
       
   635 	/**
       
   636    	Find the originator matching the parameters
       
   637 	@param aOriginator xx
       
   638 	@return Index of the matching originator. KErrNotFound if not found.
       
   639 
       
   640 	@internalAll
       
   641 	*/
       
   642 	IMPORT_C TInt FindOriginator(const Messages::TNodePeerId& aOriginator) const;
       
   643 
       
   644 	/**
       
   645 	Post a message to an originator
       
   646 	@param aOriginator originator to post the message to
       
   647 	@param aMessage    message to post
       
   648 	@return Whether the posting succeeded
       
   649 	@internalAll
       
   650 	*/
       
   651 	IMPORT_C TBool PostToOriginator(const Messages::TNodePeerId& aOriginator, const Messages::TSignalBase& aMessage) const;
       
   652 
       
   653 	/**
       
   654     Post a message to all originators
       
   655 	@param aMessageSig the message to post
       
   656 	@param aFlagsToSet Flags to set on the peer as the message is being sent
       
   657 	@param aFlagsToClear Flags to cleared on the peer as the message is being sent
       
   658 	@return number of originators the message was posted to
       
   659 	@internalAll
       
   660 	*/
       
   661 	IMPORT_C TInt PostToOriginators(const Messages::TSignalBase& aMessageSig, TUint32 aFlagsToSet = 0, TUint32 aFlagsToClear = 0);
       
   662 
       
   663 	/**
       
   664 	Calls cancel on current state. Sends TError to all originators and sets activity idle
       
   665 	@param aContext the context in which the activity is being executed
       
   666 	@param aIsNodeBeingDestroyed  indicate to the activity as to whether the node is being destroyed
       
   667 	@internalAll
       
   668 	*/
       
   669 	IMPORT_C void Abort(TNodeContextBase& aContext, TBool aIsNodeBeingDestroyed = EFalse);
       
   670 
       
   671 	
       
   672 protected:
       
   673 	/**
       
   674 	Constructor for CNodeActivityBase
       
   675 	@param aActivitySig Signature with which to create the activity
       
   676 	@param aNode        Node which will own the activity
       
   677 	*/
       
   678 	IMPORT_C explicit CNodeActivityBase(const TNodeActivity& aActivitySig, AMMNodeBase& aNode);
       
   679 	/**
       
   680 	Destructor. If the Activity is running in error mode, a message is sent to the originator.
       
   681 	*/
       
   682 	IMPORT_C virtual ~CNodeActivityBase();
       
   683 
       
   684 	/**
       
   685 	Destroy the activity.
       
   686 
       
   687 	Used primarily by preallocated activities to return extracted space
       
   688 	*/
       
   689     virtual void Destroy()
       
   690     	{
       
   691     	delete this;
       
   692     	};
       
   693 
       
   694 	/**
       
   695 
       
   696 	@param aInterfaceId id of requested interface
       
   697 	@return Interface control for accessing the extension interfaces of the activity
       
   698 	@see TInterfaceControl
       
   699 	*/
       
   700     IMPORT_C virtual NetInterfaces::TInterfaceControl* DoFetchInterfaceControlL(TInt aInterfaceId);
       
   701 
       
   702 	/**
       
   703 	Signal the activity that an event has happened in the mesh machine. Used for waking up sleeping activities
       
   704 	which use mutexes.
       
   705 
       
   706 	@param # The context in which the activity is being executed
       
   707 	@return ETrue if the activity was awoken
       
   708 	@see AActivitySemaphore
       
   709 	*/
       
   710 	virtual TBool Signal(TNodeContextBase& /*aContext*/) { return EFalse; };
       
   711 
       
   712 protected:
       
   713 	/**
       
   714 	Test whether a activity can start given the current context. If it can, the first transition will be executed.
       
   715 	Note that this is a static method, and as such the activity hasn't been instanciated when this is called
       
   716 
       
   717 	@param aContext the context in which the activity may be executed
       
   718 	@param aActivitySig the activity which we are testing for the accept condition
       
   719 	@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
       
   720 
       
   721 	@return the first entry triple for the activity if it's accepted. NULL otherwise
       
   722 	*/
       
   723 	static const NetStateMachine::TStateTriple* Accept(TNodeContextBase& aContext, const TNodeActivity& aActivitySig, TInt aTransitionTag);
       
   724 
       
   725 	/**
       
   726 	Start a new activity. The first transition should have been run within the @c Accept() method before this is called.
       
   727 
       
   728 	@param aContext  The context to start the activity in
       
   729 	@param aOriginator  The peer that requires this activity to start
       
   730 	@param aFirst       First entry triple in the activity, as returned by @c Accept()
       
   731 	*/
       
   732 	IMPORT_C virtual void StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const NetStateMachine::TStateTriple& aFirst);
       
   733 
       
   734 protected:
       
   735 	/**
       
   736 	Append self to the node's list of running activities.
       
   737 
       
   738 	Should only be accessed from @c Activity::NewL. Generally activities can choose to be inserted or appended
       
   739 	(if they do not choose they are appended by default). When inserting, extreme caution must be taken, as
       
   740 	this behavior is reserved for destroying activities.
       
   741 	*/
       
   742 	IMPORT_C void AppendActivityL();
       
   743 
       
   744 	/**
       
   745 	Append self to the node's list of running activities. This should only be called if you are certain that
       
   746 	the activity list has space for the append.
       
   747 	*/
       
   748 	IMPORT_C void AppendPreallocatedActivity();
       
   749 
       
   750 	/**
       
   751 	Insert an activity at the start of the node's list of running activities.
       
   752 	*/
       
   753 	IMPORT_C void InsertPreallocatedDestroyActivity();
       
   754 
       
   755 	/**
       
   756 	Borrow some preallocated memory from the node. This preallocated memory is used for activities that
       
   757 	absolutely cannot fail in any scenario, such as for Destroying the node. For this reason, when the
       
   758 	node is created, some memory is allocated so that a destroying activity can't even fail in an out
       
   759 	of memory situation.
       
   760 
       
   761 	This method is static as the memory must be borrowed before the activity object is constructed.
       
   762 
       
   763 	The memory is returned using @c ReturnPreallocatedSpace().
       
   764 
       
   765 	@param aNode The node that owns the preallocated space. This must be the node that the activity runs on.
       
   766 	@param aSize Size of buffer to allocate.
       
   767 
       
   768 	@return A pointer to the allocated block of memory
       
   769 	*/
       
   770 	IMPORT_C static TAny* BorrowPreallocatedSpace(AMMNodeBase& aNode, TUint aSize);
       
   771 
       
   772 	/**
       
   773 	Return preallocated space to the node. The node does not have to be passed in as a parameter as it will
       
   774 	already be a member of the activity.
       
   775 
       
   776 	@param aSpace Memory buffer to return.
       
   777 	*/
       
   778 	IMPORT_C void ReturnPreallocatedSpace(TAny* aSpace);
       
   779 	
       
   780 	/**
       
   781 	Test whether aContext carries a message that is to be expected by 'this' in its current state. 
       
   782 	The method is effectivelly a filter that hides the messages flowing throught the node, but not
       
   783 	intended for 'this'. The method will check:
       
   784 	- if aContext carries a message from PostedToId (if set) then the message should be presented to 'this'.
       
   785 	- if aContext carries a message from one of the originators then the message should be presented to 'this'.
       
   786 	@return ETrue if the sender of the current message matches PostedToId if it is set.
       
   787 	*/
       
   788 	IMPORT_C TBool MatchSender(const TNodeContextBase& aContext) const;	
       
   789 
       
   790 protected:
       
   791 	/**
       
   792 	The node the activity is running on
       
   793 	*/
       
   794 	AMMNodeBase& iNode;
       
   795 
       
   796 	/**
       
   797 	All the nodes that have started the same activity
       
   798 	*/
       
   799 	RArray<Messages::XNodePeerId> iOriginators;
       
   800 
       
   801 private: //Shouldn't be accessed directly
       
   802 	TInt     iError;    //Risk of failure is a generic property of an activity.
       
   803 	                    //Activities may choose to use external error handling activities,
       
   804 	                    //or may choose to handle errors locally. In the latter case,
       
   805 	                    //the activity may want to know it's running an error mode
       
   806 	                    //(by setting this member).
       
   807 	                    //iError must be cleared before the activity goes out of scope
       
   808 	                    //to indicate the error has been handled.
       
   809 
       
   810 	const TNodeActivity& iActivitySig;
       
   811 
       
   812 	// Last node a message was sent to
       
   813 	Messages::TNodeId iPostedToId;
       
   814 	};
       
   815 
       
   816 
       
   817 /**
       
   818 Activity type that generates a unique activity id every time it is instantiated.
       
   819 The id is generated from the @c <TNodeActivityId::EActivityParallelRangeMin,TCFNodeActivityId::EActivityParallelRangeMax>
       
   820 range. The id should never be found in a static activity map.
       
   821 A new instance id is created rather than adding a new originator to the existing activity.
       
   822 */
       
   823 class CNodeParallelActivityBase : public CNodeActivityBase
       
   824 
       
   825 	{
       
   826 public:
       
   827 	/**
       
   828     Create a new activity. This should never be called by user code.
       
   829 
       
   830 	@param aActivitySig Context information about how the activity is to be started
       
   831 	@param aNode        The node to which this activity will belong.
       
   832 	@return A pointer to the new activity. Ownership is transfered.
       
   833 	*/
       
   834     IMPORT_C static CNodeActivityBase* NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
       
   835 
       
   836 	/**
       
   837 	Get the activity id
       
   838 	@return The activity id of the activity
       
   839 	*/
       
   840    	IMPORT_C virtual TUint16 ActivityId() const;
       
   841 
       
   842 protected:
       
   843 	/**
       
   844 	For use by custom activity NewLs to generate the unique part of the activity id.
       
   845 	@param aActivitySig Context information about how the activity is to be started
       
   846 	@param aNode        The node to which this activity will belong.
       
   847 	@return Generated unique component of activity id
       
   848 	*/
       
   849 	IMPORT_C static TUint GetNextActivityCountL( const TNodeActivity& aActivitySig, const AMMNodeBase& aNode );
       
   850 
       
   851 	/**
       
   852 	Constructor for CNodeParallelActivityBase
       
   853 	@param aActivitySig Context information about how the activity is to be started
       
   854 	@param aNode        The node to which this activity will belong.
       
   855 	@param aNextActivityCount The unique part of the activity id
       
   856 	*/
       
   857     IMPORT_C CNodeParallelActivityBase( const TNodeActivity& aActivitySig, AMMNodeBase& aNode, TUint aNextActivityCount );
       
   858 
       
   859 protected:
       
   860 	/**
       
   861 	The activity id. The id format is [8 bit unique id|8 bit activity sig].
       
   862 	*/
       
   863     TUint16 iActivityId;
       
   864 	};
       
   865 
       
   866 /**
       
   867    Base class for parallel activities which store their kickoff message.
       
   868 
       
   869    @see CNodeParallelActivityBase
       
   870 */
       
   871 class CNodeParallelMessageStoreActivityBase : public CNodeParallelActivityBase
       
   872 	{
       
   873 public:
       
   874 	IMPORT_C static CNodeActivityBase* NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode );
       
   875 	IMPORT_C ~CNodeParallelMessageStoreActivityBase();
       
   876 
       
   877 	/**
       
   878 	   @return Kick off message for this activity
       
   879 	*/
       
   880 	IMPORT_C Messages::TSignalBase& Message();
       
   881 
       
   882 protected:
       
   883 	IMPORT_C virtual void StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const NetStateMachine::TStateTriple& aFirst);
       
   884 	void SaveMessageL(Messages::TSignalBase& aMessage);
       
   885 	
       
   886 	IMPORT_C CNodeParallelMessageStoreActivityBase( const MeshMachine::TNodeActivity& aActivitySig,
       
   887 		MeshMachine::AMMNodeBase& aNode, TUint aNextActivityCount );
       
   888 
       
   889 private:
       
   890 	Messages::TSignalBase* iMsg;
       
   891 	TBuf8<__Align8(Messages::TSignalBase::KMaxInlineMessageSize + Messages::TSignalBase::KMaxUnstoredOverhead)> iMsgBuf;
       
   892 	};
       
   893 
       
   894 /**
       
   895 
       
   896 If an activity has a transition or fork that is blocked by a mutex, the context must be stored so
       
   897 that when the transition or fork is unblocked it would be able to continue with the context that
       
   898 it had before it was blocked. If this aggregate wasn't used in the previous scenario, the context
       
   899 of the event that triggered the unblocking would be used, and this may have the wrong message, or
       
   900 event originator set.
       
   901 
       
   902 Error recovery is another scenario this class is useful in.
       
   903 */
       
   904 class AContextStore
       
   905     {
       
   906 public:
       
   907     /**
       
   908     Interface id
       
   909     */
       
   910     static const TInt KInterfaceId = 0x102864DC;
       
   911 
       
   912 protected:
       
   913     /**
       
   914     Constructor for AContextStore
       
   915     */
       
   916     explicit AContextStore()
       
   917         {
       
   918         }
       
   919     /**
       
   920     Destructor for AContextStore
       
   921     */
       
   922     ~AContextStore()
       
   923         {
       
   924     	iContextDesc.Close();
       
   925         }
       
   926 
       
   927 public:
       
   928 	/**
       
   929 	Used for error recovery. If the context is stored, loads the stored context and reruns the last transition that was run.
       
   930 
       
   931 	@param aActivity The activity to retry
       
   932 	@param aContext  The context within which the retrying is taking place. NOTE: This is not the stored context
       
   933 
       
   934 	@see StoreContext
       
   935 	@see LoadContext
       
   936 	*/
       
   937 	IMPORT_C void Retry(CNodeActivityBase& aActivity, TNodeContextBase& aContext);
       
   938 
       
   939     /**
       
   940 	Store context in buffer. Designed to be called from a transition to store the transitions context for error recovery or
       
   941 	to wait on a mutex.
       
   942 
       
   943 	@param aContext The context to store
       
   944 	@return Error code. @c KErrNone if storage is successful.
       
   945 	*/
       
   946 	IMPORT_C TInt StoreContext(const TNodeContextBase& aContext);
       
   947 
       
   948 	/**
       
   949 	Check of the context is stored.
       
   950 	@return @c ETrue if a context is stored. @c EFalse otherwise.
       
   951 	*/
       
   952 	IMPORT_C TBool IsStored() const;
       
   953 
       
   954 	/**
       
   955 	Get the id of the message which requested @c Retry()
       
   956 	@return Message Id of message which kicked off the @c ::Retry
       
   957 
       
   958 	@see AContextStore::Retry
       
   959 	*/
       
   960  	IMPORT_C const Messages::TNodeSignal::TMessageId& RetryingForMessageId() const; //Needs to be moved to error-recoverable activity class
       
   961 
       
   962 protected:
       
   963 	/**
       
   964 	Load a stored context. Once the stored context has been loaded the status of @c iContextDesc is undefined and load shouldn't
       
   965 	be called again until something has been stored.
       
   966 
       
   967 	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
       
   968 	must be cleaned up after use.
       
   969 
       
   970 	@param aNode The node for the context
       
   971 	@param aNodeActivity The activity for the context.
       
   972 	@param aCtxBuff  A memory buffer in which the context will be created.
       
   973 	@param aMsgBuff  A memory buffer in which the message will be created.
       
   974 	@param aDummy    Will become the recipient node id in the context.
       
   975 
       
   976 	@return Pointer to loaded context
       
   977 	*/
       
   978 	IMPORT_C TNodeContextBase* LoadContext(AMMNodeBase& aNode, CNodeActivityBase* aNodeActivity, TDes8& aCtxBuff, TDes8& aMsgBuff, const Messages::TNodeId& aDummy);
       
   979 
       
   980 protected:
       
   981 	/**
       
   982     Buffer to store the context.
       
   983 	*/
       
   984 	RBuf8 iContextDesc;
       
   985 	/**
       
   986 	Message id of the message which kicked off the retry attempt
       
   987 	*/
       
   988 	Messages::TNodeSignal::TMessageId iRetryingForMessageId;
       
   989 	};
       
   990 
       
   991 /**
       
   992 Aggregate class for activities which wish to use mutexes.
       
   993 
       
   994 After a serialised state or transition has been unblocked, signalled and invoked, AActivitySemaphore
       
   995 clears all of the synchronisation related information (e.g stored context), assuming that the job has
       
   996 been done. Sometimes however the serialised state, upon more careful inspection of the environment
       
   997 (context), may decide that it still does not want to be executed and it wishes to sleep again.
       
   998 
       
   999 In such case it would call Wait() and return @c EIgnore from its @c TransitionTag(). The same applies to a
       
  1000 serialised transition. It may want to call Wait() instead of, for example sending a request message.
       
  1001 
       
  1002 After calling Wait() the serialised state will be woken up when the policy matches, which allows the serialised state
       
  1003 to finish its job.
       
  1004  */
       
  1005 class AActivitySemaphore : public AContextStore
       
  1006     {
       
  1007 public:
       
  1008     /**
       
  1009     Interface id
       
  1010     */
       
  1011     static const TInt KInterfaceId = 10015; //Normally a UID - 10015 for compatibility reasons
       
  1012 
       
  1013 public:
       
  1014 	/**
       
  1015 	Park a state.
       
  1016 
       
  1017 	@param aContext The context which the state is to run in. This will be stored
       
  1018 
       
  1019 	@return @c KErrNone if successful. System wide error code otherwise
       
  1020 	*/
       
  1021 	IMPORT_C static TInt ParkState(const TNodeContextBase& aContext);
       
  1022 
       
  1023 	/**
       
  1024 	Unpark a state.
       
  1025 
       
  1026 	@param aContext The context which the state is to run in.
       
  1027 
       
  1028 	@return @c KErrNone if successful. System wide error code otherwise
       
  1029 	*/
       
  1030 	IMPORT_C static TInt UnparkState(const TNodeContextBase& aContext);
       
  1031 
       
  1032 	/**
       
  1033 	Park a transition
       
  1034 
       
  1035 	@param aContext The context which the transition is to run in.
       
  1036 	*/
       
  1037 	IMPORT_C static void ParkTransitionL(const TNodeContextBase& aContext);
       
  1038 
       
  1039 	/**
       
  1040 	Signals to the activity that an event has occurred. Used for waking up sleeping activities
       
  1041 	which use mutexes. The activity is expected to check if the mutex has now cleared.
       
  1042 
       
  1043 	@param aContext Current context in the state machine.
       
  1044 
       
  1045 	@return @c ETrue if the state or transition has been unparked
       
  1046 	*/
       
  1047 	IMPORT_C TBool Signal(TNodeContextBase& aContext);
       
  1048 
       
  1049 	/**
       
  1050 	Tell the activity to wait. The activity will wait until Signal() is called.
       
  1051 	*/
       
  1052 	IMPORT_C void Wait();
       
  1053 
       
  1054 	/**
       
  1055 	Check if the activity is waiting
       
  1056 	@return ETrue if the activity is currently waiting
       
  1057 	*/
       
  1058 	TBool IsWaiting() const
       
  1059 		{
       
  1060 		__ASSERT_DEBUG(!(iFlags&KIsWaiting) || IsStored(), User::Panic(KSpecAssert_ElemMeshMachActH, 3));
       
  1061 
       
  1062 		return iFlags&KIsWaiting;
       
  1063 		}
       
  1064 
       
  1065 protected:
       
  1066     /**
       
  1067     Constructor for AActivitySemaphore
       
  1068     */
       
  1069     explicit AActivitySemaphore()
       
  1070     :   iFlags(0)
       
  1071 		{
       
  1072         }
       
  1073     /**
       
  1074     Destructor for AActivitySemaphore
       
  1075     */
       
  1076     ~AActivitySemaphore()
       
  1077         {
       
  1078         }
       
  1079 
       
  1080 protected:
       
  1081 	/**
       
  1082 	Set the @c isWaiting flag
       
  1083 	*/
       
  1084 	inline void SetIsWaiting() { iFlags|=KIsWaiting; };
       
  1085 	/**
       
  1086 	Clear the @c isWaiting flag
       
  1087 	*/
       
  1088 	inline void ClearIsWaiting() { iFlags&=~KIsWaiting; };
       
  1089 
       
  1090 	/**
       
  1091 	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.
       
  1092 	This is distinct from "is waiting" which indicates whether the activity was waiting on entry to the Signal()
       
  1093 	function.
       
  1094 
       
  1095 	@return ETrue if the WillWait flag is set
       
  1096 	*/
       
  1097 	inline TBool WillWait() const { return (iFlags&KWillWait)==KWillWait; };
       
  1098 	/**
       
  1099 	Set the willWait flag
       
  1100 	*/
       
  1101 	inline void SetWillWait() { iFlags|=KWillWait; };
       
  1102 	/**
       
  1103 	Clear the willWait flag
       
  1104 	*/
       
  1105 	inline void ClearWillWait() { iFlags&=~KWillWait; };
       
  1106 
       
  1107 private:
       
  1108 	//Is waiting for mutex? == not idle yet, even if last triple
       
  1109  	//iIsWaiting prevents Idle condition following the last
       
  1110 	//transition (in case the transition has parked the activity
       
  1111 	//and wants to be reexecuted). When reexecuting, the activity
       
  1112 	//mustn't be idle (iIsWaiting has to be true), on the
       
  1113 	//other hand the transition may to park the activity again
       
  1114 	//We need to distinguish the entry value of iIsWaiting from
       
  1115 	//the exit value of iIsWaiting, we hance need this aditional
       
  1116 	//flag.
       
  1117 
       
  1118 	inline TBool IsTransition() const { return (iFlags&KIsTransition)==KIsTransition; };
       
  1119 	inline void SetIsTransition() { iFlags|=KIsTransition; };
       
  1120 	inline void ClearIsTransition() { iFlags&=~KIsTransition; };
       
  1121 
       
  1122 	enum { KIsWaiting = 0x1, KWillWait = 0x2, KIsTransition = 0x4 };
       
  1123 
       
  1124 	TUint8 iFlags;
       
  1125     };
       
  1126 
       
  1127 /**
       
  1128 Activity class base for activities which wish to use synchronisation or retries.
       
  1129 */
       
  1130 class CNodeRetryActivity : public CNodeActivityBase, public AActivitySemaphore,
       
  1131                 public ITFHIERARCHY_2(CNodeRetryActivity, AContextStore, AActivitySemaphore)
       
  1132 	{
       
  1133 public:
       
  1134 	/**
       
  1135 	Defines a helper list of interfaces.
       
  1136  	*/
       
  1137 	typedef ITFHIERARCHY_2(CNodeRetryActivity, AContextStore, AActivitySemaphore) TIfStaticFetcherNearestInHierarchy;
       
  1138 
       
  1139 public:
       
  1140 	/**
       
  1141     Create a new activity. This should never be called by user code.
       
  1142 
       
  1143 	@param aActivitySig Context information about how the activity is to be started
       
  1144 	@param aNode        The node to which this activity will belong.
       
  1145 	@return A pointer to the new object. Ownership is transfered.
       
  1146 	*/
       
  1147     IMPORT_C static CNodeActivityBase* NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
       
  1148 
       
  1149 	/**
       
  1150 	Fetch the context store interface
       
  1151 	@param aInterface pointer into which a pointer to the interface will be placed.
       
  1152 	*/
       
  1153     IMPORT_C void ReturnInterfacePtrL(AContextStore*& aInterface);
       
  1154 
       
  1155 	/**
       
  1156 	Fetch the activity semaphore interface
       
  1157 	@param aInterface On return, contains a pointer to the interface.
       
  1158 	*/
       
  1159     IMPORT_C void ReturnInterfacePtrL(AActivitySemaphore*& aInterface);
       
  1160 
       
  1161 	/**
       
  1162 	Check if the activity has stopped running
       
  1163 	@return @c ETrue if the activity is still running, otherwise @c EFalse.
       
  1164 	*/
       
  1165     IMPORT_C virtual TBool IsIdle() const;
       
  1166 
       
  1167 	/**
       
  1168 	Put the activity into the idle state. This stops the activity running and notifies the mesh machine that
       
  1169 	it is ok to delete this activity.
       
  1170 	*/
       
  1171     IMPORT_C virtual void SetIdle();
       
  1172 
       
  1173 protected:
       
  1174 	/**
       
  1175 	Signal the activity that an event has occurred and that it is worthwhile checking
       
  1176 	to see if the mutex has now cleared.
       
  1177 
       
  1178 	@param aContext Current context in the state machine.
       
  1179 
       
  1180 	@return @c ETrue if state or transition has been unparked
       
  1181 	*/
       
  1182 	IMPORT_C virtual TBool Signal(TNodeContextBase& aContext);
       
  1183 
       
  1184     /**
       
  1185     Constructor for CNodeRetryActivity
       
  1186 	@param aActivitySig Context information about how the activity is to be started
       
  1187 	@param aNode        The node to which this activity will belong.
       
  1188     */
       
  1189     IMPORT_C CNodeRetryActivity( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
       
  1190 	};
       
  1191 
       
  1192 /**
       
  1193 Base class for activities that run in parallel and can be synchronised or retried.
       
  1194 */
       
  1195 class CNodeRetryParallelActivity : public CNodeParallelActivityBase, public AActivitySemaphore,
       
  1196                 public ITFHIERARCHY_2(CNodeRetryParallelActivity, AContextStore, AActivitySemaphore)
       
  1197 	{
       
  1198 public:
       
  1199 	/**
       
  1200 	Defines a helper list of interfaces.
       
  1201  	*/
       
  1202  	typedef ITFHIERARCHY_2(CNodeRetryParallelActivity, AContextStore, AActivitySemaphore) TIfStaticFetcherNearestInHierarchy;
       
  1203 
       
  1204 public:
       
  1205 	/**
       
  1206     Create a new activity. This should never be called by user code.
       
  1207 
       
  1208 	@param aActivitySig Context information about how the activity is to be started
       
  1209 	@param aNode        The node to which this activity will belong.
       
  1210 	@return A pointer to the new object. Ownership is transfered.
       
  1211 	*/
       
  1212     IMPORT_C static CNodeActivityBase* NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode );
       
  1213 
       
  1214 	/**
       
  1215 	Fetch the context store interface
       
  1216 	@param aInterface On return, contains a pointer to the store interface
       
  1217 	*/
       
  1218     IMPORT_C void ReturnInterfacePtrL(AContextStore*& aInterface);
       
  1219 
       
  1220 	/**
       
  1221 	Fetch the activity semaphore interface
       
  1222 	@param aInterface On return, contains a pointer to the semaphore interface
       
  1223 	*/
       
  1224     IMPORT_C void ReturnInterfacePtrL(AActivitySemaphore*& aInterface);
       
  1225 
       
  1226 	/**
       
  1227 	Check if the activity has stopped
       
  1228 	@return @c ETrue if the activity is still running, otherwise @c EFalse
       
  1229 	*/
       
  1230     IMPORT_C virtual TBool IsIdle() const;
       
  1231 
       
  1232 	/**
       
  1233 	Put the activity into the idle state. This stops the activity running and notifies the mesh machine that
       
  1234 	it is ok to delete this activity.
       
  1235 	*/
       
  1236     IMPORT_C virtual void SetIdle();
       
  1237 
       
  1238 protected:
       
  1239 	/**
       
  1240 	Signal to the activity that an event has occurred and that it is worthwhile checking
       
  1241 	to see if the mutex has now cleared.
       
  1242 
       
  1243 	@param aContext Current context in the state machine.
       
  1244 
       
  1245 	@return @c ETrue if state or transition has been unparked
       
  1246 	*/
       
  1247 	IMPORT_C virtual TBool Signal(TNodeContextBase& aContext);
       
  1248 
       
  1249 	/**
       
  1250     Constructor for CNodeRetryParallelActivity
       
  1251 
       
  1252 	@param aActivitySig Context information about how the activity is to be started
       
  1253 	@param aNode        The node to which this activity will belong.
       
  1254 	@param aActivitiesCount The unique part of the activity id
       
  1255     */
       
  1256     IMPORT_C CNodeRetryParallelActivity( const TNodeActivity& aActivitySig, AMMNodeBase& aNode, TUint aActivitiesCount );
       
  1257 	};
       
  1258 
       
  1259 /**
       
  1260 Aggregate originator array template for activities that use preallocated space.
       
  1261 This object has a fixed size array to hold the originators which will be allocated from the preallocated space
       
  1262 when the node activity object is created.
       
  1263 */
       
  1264 template <TInt ORIGINATORSCOUNT>
       
  1265 class APreallocatedOriginators
       
  1266 	{
       
  1267 protected:
       
  1268 	/**
       
  1269 	Initialise the array and ensure it is empty as it should be on creation.
       
  1270 	Generally, iOriginators from the activity will be passed into this as a reference. A new
       
  1271 	RArray will then be created using the preallocated space.
       
  1272 
       
  1273 	@param aOriginators Array of originators for which to preallocate space
       
  1274 	*/
       
  1275 	explicit APreallocatedOriginators(RArray<Messages::XNodePeerId>& aOriginators)
       
  1276 	:	iOriginatorsRef(aOriginators)
       
  1277 		{
       
  1278 		iOriginatorsRef = RArray<Messages::XNodePeerId>(sizeof(Messages::XNodePeerId), (Messages::XNodePeerId*)iOriginatorBuf, ORIGINATORSCOUNT);
       
  1279 		for (TInt i = iOriginatorsRef.Count() - 1; i >= 0; --i)
       
  1280 			{
       
  1281 			iOriginatorsRef.Remove(i);
       
  1282 			}
       
  1283 		}
       
  1284     /**
       
  1285     Destructor for APreallocatedOriginators.
       
  1286     */
       
  1287 	~APreallocatedOriginators()
       
  1288 		{
       
  1289 		iOriginatorsRef = RArray<Messages::XNodePeerId>();
       
  1290 		}
       
  1291 
       
  1292 private:
       
  1293 	//The originator's list
       
  1294 	RArray<Messages::XNodePeerId>& iOriginatorsRef;
       
  1295     //Preallocated space in the originator's list
       
  1296     TUint8 iOriginatorBuf[__Align8(sizeof(Messages::XNodePeerId) * ORIGINATORSCOUNT)];
       
  1297 	};
       
  1298 
       
  1299 /**
       
  1300 Base for preallocated node activity class
       
  1301 */
       
  1302 template <TInt ORIGINATORSCOUNT>
       
  1303 class CPreallocatedNodeActivityBase : public MeshMachine::CNodeActivityBase,
       
  1304                                       protected MeshMachine::APreallocatedOriginators<ORIGINATORSCOUNT>
       
  1305 /**
       
  1306 @internalTechnology
       
  1307 */
       
  1308 	{
       
  1309 public:
       
  1310 	/**
       
  1311     Create a new activity. This should never be called by user code.
       
  1312 
       
  1313 	@param aActivitySig Context information about how the activity is to be started
       
  1314 	@param aNode        The node to which this activity will belong.
       
  1315 	*/
       
  1316     static MeshMachine::CNodeActivityBase* New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1317     	{
       
  1318    		TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CPreallocatedNodeActivityBase));
       
  1319 		CPreallocatedNodeActivityBase* self = new (space) CPreallocatedNodeActivityBase(aActivitySig, aNode);
       
  1320 		self->AppendPreallocatedActivity();
       
  1321 		return self;
       
  1322     	}
       
  1323 
       
  1324 protected:
       
  1325 
       
  1326 
       
  1327 	CPreallocatedNodeActivityBase(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1328 	:	CNodeActivityBase(aActivitySig, aNode),
       
  1329 		APreallocatedOriginators<ORIGINATORSCOUNT>(iOriginators)
       
  1330 		{
       
  1331 		}
       
  1332 
       
  1333 	/**
       
  1334 	Destroy the activity. Return the preallocated space and call the destructor directly. i.e. not though delete
       
  1335 	as delete would try and release the memory again
       
  1336 	*/
       
  1337 	virtual void Destroy()
       
  1338 		{
       
  1339 		ReturnPreallocatedSpace(this);
       
  1340 		this->~CPreallocatedNodeActivityBase(); //Run the destructor
       
  1341 		}
       
  1342 private:
       
  1343 	/**
       
  1344 	Private NewL with no implementation to hide the CNodeActivityBase::NewL
       
  1345 	Creation of preallocated activities doesn't fail and hence a non-leaving ::New should be used instead
       
  1346 	*/
       
  1347     static MeshMachine::CNodeActivityBase* NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
       
  1348 	};
       
  1349 
       
  1350 //-=========================================================
       
  1351 //
       
  1352 // CPreallocatedNodeActivityBase
       
  1353 //
       
  1354 //-=========================================================
       
  1355 template <TInt ORIGINATORSCOUNT>
       
  1356 class CPreallocatedNodeRetryActivity : public MeshMachine::CNodeRetryActivity,
       
  1357                                       protected MeshMachine::APreallocatedOriginators<ORIGINATORSCOUNT>
       
  1358 /**
       
  1359 @internalTechnology
       
  1360 */
       
  1361 	{
       
  1362 public:
       
  1363     static MeshMachine::CNodeActivityBase* New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1364     	{
       
  1365    		TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CPreallocatedNodeRetryActivity));
       
  1366 		CPreallocatedNodeRetryActivity* self = new (space) CPreallocatedNodeRetryActivity(aActivitySig, aNode);
       
  1367 		self->AppendPreallocatedActivity();
       
  1368 		return self;
       
  1369     	}
       
  1370 
       
  1371 protected:
       
  1372 	CPreallocatedNodeRetryActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1373 	:	CNodeRetryActivity(aActivitySig, aNode),
       
  1374 		APreallocatedOriginators<ORIGINATORSCOUNT>(iOriginators)
       
  1375 		{
       
  1376 		}
       
  1377 
       
  1378 	virtual void Destroy()
       
  1379 		{
       
  1380 		ReturnPreallocatedSpace(this);
       
  1381 		this->~CPreallocatedNodeRetryActivity(); //Run the destructor
       
  1382 		}
       
  1383 private:
       
  1384 	/*
       
  1385 	Private NewL with no implementation to hide the CNodeActivityBase::NewL
       
  1386 	Creation of preallocated activities doesn't fail and hence a non-leaving ::New should be used instead*/
       
  1387     static MeshMachine::CNodeActivityBase* NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode);
       
  1388 	};
       
  1389 
       
  1390 } //namespace MeshMachine
       
  1391 
       
  1392 #endif //SYMBIAN_MM_ACTIVITIES_H
       
  1393