|
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 states templates and helper macros |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @publishedPartner |
|
21 @released |
|
22 */ |
|
23 |
|
24 |
|
25 #ifndef SYMBIAN_MM_STATES_H |
|
26 #define SYMBIAN_MM_STATES_H |
|
27 |
|
28 #include <elements/sm_core.h> |
|
29 #include <elements/mm_context.h> |
|
30 #include <elements/mm_log.h> |
|
31 #include <elements/mm_activities.h> //for AContextStore, logging only |
|
32 #include <elements/nm_signatures.h> |
|
33 |
|
34 |
|
35 #ifdef _DEBUG |
|
36 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
37 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
38 _LIT(KSpecAssert_ElemMeshMachStaH, "ElemMeshMachStaH"); |
|
39 #endif |
|
40 |
|
41 //-========================================================= |
|
42 // |
|
43 // MACROS |
|
44 // |
|
45 //-========================================================= |
|
46 #define DECLARE_SMELEMENT_HEADER(element, base, intf, context) \ |
|
47 NONSHARABLE_CLASS(element) : public base \ |
|
48 { \ |
|
49 public: \ |
|
50 explicit element(context& aContext) : \ |
|
51 base(aContext) {} \ |
|
52 NETSM_DECLARE_CTR(intf) |
|
53 |
|
54 #define EXPORT_DECLARE_SMELEMENT_HEADER(element, base, intf, context) \ |
|
55 class element : public base \ |
|
56 { \ |
|
57 public: \ |
|
58 explicit element(context& aContext) : \ |
|
59 base(aContext) {} \ |
|
60 EXPORT_NETSM_DECLARE_CTR(intf) \ |
|
61 |
|
62 #define DECLARE_SMELEMENT_FOOTER(element) \ |
|
63 }; \ |
|
64 |
|
65 |
|
66 |
|
67 #define DEFINE_SMELEMENT(element, intf, context) \ |
|
68 NETSM_DEFINE_CTR(element, intf, context) \ |
|
69 |
|
70 #define EXPORT_DEFINE_SMELEMENT(element, intf, context) \ |
|
71 EXPORT_NETSM_DEFINE_CTR(element, intf, context) \ |
|
72 |
|
73 |
|
74 |
|
75 #define DECLARE_AGGREGATED_TRANSITION2(Name, T1, T2) \ |
|
76 typedef MeshMachine::TAggregatedTransition<T1, T2, TContext> Name; |
|
77 |
|
78 #define DECLARE_AGGREGATED_TRANSITION3(Name, T1, T2, T3) \ |
|
79 DECLARE_AGGREGATED_TRANSITION2(Name##Name__TR3, T1, T2) \ |
|
80 DECLARE_AGGREGATED_TRANSITION2(Name, Name##Name__TR3, T3) |
|
81 |
|
82 #define DECLARE_AGGREGATED_TRANSITION4(Name, T1, T2, T3, T4) \ |
|
83 DECLARE_AGGREGATED_TRANSITION3(Name##Name__TR4, T1, T2, T3) \ |
|
84 DECLARE_AGGREGATED_TRANSITION2(Name, Name##Name__TR4, T4) |
|
85 |
|
86 #define DECLARE_AGGREGATED_TRANSITION5(Name, T1, T2, T3, T4, T5) \ |
|
87 DECLARE_AGGREGATED_TRANSITION3(Name##Name__TR5, T1, T2, T3) \ |
|
88 DECLARE_AGGREGATED_TRANSITION3(Name, Name##Name__TR5, T4, T5) |
|
89 |
|
90 #define DECLARE_AGGREGATED_TRANSITION6(Name, T1, T2, T3, T4, T5, T6) \ |
|
91 DECLARE_AGGREGATED_TRANSITION4(Name##Name__TR6, T1, T2, T3, T4) \ |
|
92 DECLARE_AGGREGATED_TRANSITION3(Name, Name##Name__TR6, T5, T6) |
|
93 |
|
94 #define DECLARE_AGGREGATED_TRANSITION7(Name, T1, T2, T3, T4, T5, T6, T7) \ |
|
95 DECLARE_AGGREGATED_TRANSITION4(Name##Name__TR7, T1, T2, T3, T4) \ |
|
96 DECLARE_AGGREGATED_TRANSITION4(Name, Name##Name__TR7, T5, T6, T7) |
|
97 |
|
98 |
|
99 #define DECLARE_SERIALIZABLE_STATE(Name, Policy, State) \ |
|
100 typedef MeshMachine::TSerializableStateFork<Policy, State> Name; |
|
101 |
|
102 #define DECLARE_SERIALIZABLE_STATE_WITH_ERRORTAG(Name, Policy, ErrorTagPolicy, State) \ |
|
103 typedef MeshMachine::TSerializableStateFork<Policy, State> Name; |
|
104 |
|
105 #define DECLARE_SERIALIZABLE_TRANSITION(Name, Policy, StateTransition) \ |
|
106 typedef MeshMachine::TSerializableTransition<Policy, StateTransition> Name; |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 namespace MeshMachine |
|
113 { |
|
114 |
|
115 //In an (unusual) case where an MState needs to raise |
|
116 //raise an error, it can produce KErrorTag as its |
|
117 //transition tag. The way the actual error code |
|
118 //is conveyed is undefined at this level. It is suggested |
|
119 //to use the context for that. It is herby enforced to |
|
120 //use a naming convention for states that can raise |
|
121 //an error 'E' suffix (e.g.: AwaitSomethingE). |
|
122 const TInt KNoTag = NetStateMachine::KExecuteAlways - 3; |
|
123 const TInt KErrorTag = NetStateMachine::KExecuteAlways - 4; |
|
124 const TInt KCancelTag = NetStateMachine::KExecuteAlways - 5; |
|
125 const TInt KActiveTag = NetStateMachine::KExecuteAlways - 6; |
|
126 |
|
127 |
|
128 class AMMNodeBase; |
|
129 typedef MeshMachine::TNodeContext<AMMNodeBase> TContext; |
|
130 |
|
131 //-========================================================= |
|
132 // |
|
133 //Default cancel handling for states |
|
134 // |
|
135 //-========================================================= |
|
136 template <class TCONTEXT> |
|
137 class TState : public NetStateMachine::AContext<TCONTEXT>, |
|
138 public NetStateMachine::MState |
|
139 { |
|
140 public: |
|
141 NETSM_TPL_DECLARE_CTR(TState, NetStateMachine::MState, TCONTEXT) |
|
142 typedef TCONTEXT TContext; |
|
143 |
|
144 TState(TCONTEXT& aContext) : |
|
145 NetStateMachine::AContext<TCONTEXT>(aContext) |
|
146 { |
|
147 } |
|
148 |
|
149 virtual void Cancel() |
|
150 { |
|
151 if (this->iContext.iNodeActivity) |
|
152 { |
|
153 this->iContext.iNodeActivity->SetError(KErrCancel); |
|
154 } |
|
155 } |
|
156 }; |
|
157 |
|
158 //-========================================================= |
|
159 // |
|
160 // Default error handling State Transition |
|
161 // |
|
162 //-========================================================= |
|
163 template <class TCONTEXT> |
|
164 class TStateTransition : public NetStateMachine::AContext<TCONTEXT>, |
|
165 public NetStateMachine::MStateTransition |
|
166 { |
|
167 public: |
|
168 NETSM_TPL_DECLARE_CTR(TStateTransition, NetStateMachine::MStateTransition, TCONTEXT) |
|
169 typedef TCONTEXT TContext; |
|
170 |
|
171 TStateTransition(TCONTEXT& aContext) : |
|
172 NetStateMachine::AContext<TCONTEXT>(aContext) |
|
173 { |
|
174 } |
|
175 |
|
176 virtual void Error( TInt aError ) |
|
177 { |
|
178 NetStateMachine::AContext<TCONTEXT>::iContext.iReturn = aError; |
|
179 if(NetStateMachine::AContext<TCONTEXT>::iContext.iNodeActivity != NULL) |
|
180 { |
|
181 NetStateMachine::AContext<TCONTEXT>::iContext.iNodeActivity->SetError(aError); |
|
182 NetStateMachine::AContext<TCONTEXT>::iContext.iNodeActivity->SetIdle(); //By default, set activity to idle |
|
183 } |
|
184 } |
|
185 }; |
|
186 |
|
187 //-========================================================= |
|
188 // |
|
189 //Default state fork |
|
190 // |
|
191 //-========================================================= |
|
192 template <class TCONTEXT> |
|
193 class TStateFork : public NetStateMachine::AContext<TCONTEXT>, |
|
194 public NetStateMachine::MStateFork |
|
195 { |
|
196 public: |
|
197 NETSM_TPL_DECLARE_CTR(TStateFork, NetStateMachine::MStateTransition, TCONTEXT) |
|
198 typedef TCONTEXT TContext; |
|
199 |
|
200 TStateFork(TCONTEXT& aContext) : |
|
201 NetStateMachine::AContext<TCONTEXT>(aContext) |
|
202 { |
|
203 } |
|
204 |
|
205 virtual TInt TransitionTag() |
|
206 { |
|
207 return KNoTag | NetStateMachine::EForward; |
|
208 } |
|
209 }; |
|
210 |
|
211 |
|
212 //-========================================================= |
|
213 // |
|
214 //Serializable states & transitions |
|
215 // |
|
216 //-========================================================= |
|
217 template <TInt ERRORTAG> |
|
218 class TStateErrorTransitionTag |
|
219 { |
|
220 public: |
|
221 static TInt ErrorTag(const TNodeContextBase& /*aContext*/) { return ERRORTAG; }; |
|
222 }; |
|
223 |
|
224 template <class TPOLICY, typename TSTATEFORK, class TERRORTAGPOLICY = TStateErrorTransitionTag<KErrorTag> > |
|
225 class TSerializableStateFork : public TSTATEFORK |
|
226 { |
|
227 public: |
|
228 typedef typename TSTATEFORK::TContext TContext; |
|
229 |
|
230 NETSM_TPL_DECLARE_CTR(TSerializableStateFork, NetStateMachine::MStateFork, TContext) |
|
231 |
|
232 TSerializableStateFork(TContext& aContext) |
|
233 : TSTATEFORK(aContext) |
|
234 { |
|
235 } |
|
236 |
|
237 virtual TInt TransitionTag() |
|
238 { |
|
239 if (TPOLICY::IsBlocked(TSTATEFORK::iContext)) |
|
240 { |
|
241 return (AActivitySemaphore::ParkState(TSTATEFORK::iContext)==KErrNone)? |
|
242 NetStateMachine::EIgnore : TERRORTAGPOLICY::ErrorTag(TSTATEFORK::iContext); |
|
243 } |
|
244 else |
|
245 { |
|
246 MeshMachine::AActivitySemaphore* as = static_cast<MeshMachine::AActivitySemaphore*>(TSTATEFORK::iContext.iNodeActivity->FetchExtInterface(MeshMachine::AActivitySemaphore::KInterfaceId)); |
|
247 __ASSERT_DEBUG(as, User::Panic(KSpecAssert_ElemMeshMachStaH, 1)); //State/transition mismatched with the activity object (activity doesn't support serialisation - wrong derivation?) |
|
248 |
|
249 // Log whether the state unparked |
|
250 if(as->IsWaiting()) |
|
251 { |
|
252 AActivitySemaphore::UnparkState(TSTATEFORK::iContext); |
|
253 } |
|
254 |
|
255 return TSTATEFORK::TransitionTag(); |
|
256 } |
|
257 } |
|
258 }; |
|
259 |
|
260 template <class TPOLICY, typename TSTATETRANSITION> |
|
261 class TSerializableTransition : public TSTATETRANSITION |
|
262 { |
|
263 public: |
|
264 typedef typename TSTATETRANSITION::TContext TContext; |
|
265 |
|
266 NETSM_TPL_DECLARE_CTR(TSerializableTransition, NetStateMachine::MStateTransition, TContext) |
|
267 |
|
268 TSerializableTransition(TContext& aContext) |
|
269 : TSTATETRANSITION(aContext) |
|
270 { |
|
271 } |
|
272 |
|
273 virtual void DoL() |
|
274 { |
|
275 //If this assertion fires, the serilisable transition has been |
|
276 //wrongly positioned in the first triple of its activity. |
|
277 __ASSERT_DEBUG(TSTATETRANSITION::iContext.iNodeActivity, User::Panic(KSpecAssert_ElemMeshMachStaH, 2)); |
|
278 if (TPOLICY::IsBlocked(TSTATETRANSITION::iContext)) |
|
279 { |
|
280 AActivitySemaphore::ParkTransitionL(TSTATETRANSITION::iContext); |
|
281 } |
|
282 else |
|
283 { |
|
284 #ifdef SYMBIAN_TRACE_ENABLE |
|
285 // Log whether the transition unparked |
|
286 MeshMachine::AActivitySemaphore* as = static_cast<MeshMachine::AActivitySemaphore*>(TSTATETRANSITION::iContext.iNodeActivity->FetchExtInterface(MeshMachine::AActivitySemaphore::KInterfaceId)); |
|
287 __ASSERT_DEBUG(as, User::Panic(KSpecAssert_ElemMeshMachStaH, 3)); //State/transition mismatched with the activity object (activity doesn't support serialisation - wrong derivation?) |
|
288 if(as->IsWaiting()) |
|
289 { |
|
290 MESH_LOG_CONTEXT_EXT(KMeshMachineSubTag, TSTATETRANSITION::iContext, _L8("TSerializableTransition::DoL unparked")); |
|
291 } |
|
292 #endif |
|
293 TSTATETRANSITION::DoL(); |
|
294 } |
|
295 } |
|
296 }; |
|
297 |
|
298 //-========================================================= |
|
299 // |
|
300 //Aggregated transitions |
|
301 // |
|
302 //-========================================================= |
|
303 |
|
304 template <class T1, class T2, class TCONTEXT> |
|
305 class TAggregatedTransition : public TStateTransition<TCONTEXT> |
|
306 { |
|
307 public: |
|
308 NETSM_TPL_DECLARE_CTR(TAggregatedTransition, NetStateMachine::MStateTransition, TCONTEXT) |
|
309 |
|
310 TAggregatedTransition(TCONTEXT& aContext) |
|
311 : TStateTransition<TCONTEXT>(aContext) |
|
312 { |
|
313 } |
|
314 |
|
315 virtual void DoL() |
|
316 { |
|
317 T1 t1(NetStateMachine::AContext<TCONTEXT>::iContext); |
|
318 T2 t2(NetStateMachine::AContext<TCONTEXT>::iContext); |
|
319 t1.DoL(); |
|
320 t2.DoL(); |
|
321 } |
|
322 |
|
323 virtual void Error(TInt aError) |
|
324 { |
|
325 T1 t1(NetStateMachine::AContext<TCONTEXT>::iContext); |
|
326 T2 t2(NetStateMachine::AContext<TCONTEXT>::iContext); |
|
327 t1.Error(aError); |
|
328 t2.Error(aError); |
|
329 } |
|
330 }; |
|
331 |
|
332 //-========================================================= |
|
333 // |
|
334 //Commonly used states |
|
335 // |
|
336 //-========================================================= |
|
337 |
|
338 template<typename TMESSAGE> |
|
339 class TAwaitingMessageState : public MeshMachine::TState<MeshMachine::TContext> |
|
340 { |
|
341 public: |
|
342 NETSM_TPL_DECLARE_CTR(TAwaitingMessageState, NetStateMachine::MState, MeshMachine::TContext) |
|
343 |
|
344 explicit TAwaitingMessageState(MeshMachine::TContext& aContext) : |
|
345 MeshMachine::TState<MeshMachine::TContext>(aContext) {} |
|
346 |
|
347 virtual TBool Accept() |
|
348 { |
|
349 #ifdef __GCCXML__ |
|
350 return EFalse; |
|
351 #else |
|
352 Messages::TNodeSignal& msg = this->iContext.iMessage; //Arm compiler is getting confused otherwise |
|
353 return msg.IsMessage<TMESSAGE>(); |
|
354 #endif |
|
355 } |
|
356 }; |
|
357 |
|
358 template<typename TMESSAGE1, class TMESSAGE2> |
|
359 class TAwaiting2MessagesState : public MeshMachine::TState<TContext> |
|
360 { |
|
361 public: |
|
362 NETSM_TPL_DECLARE_CTR(TAwaiting2MessagesState, NetStateMachine::MState, TContext) |
|
363 |
|
364 explicit TAwaiting2MessagesState(TContext& aContext) : |
|
365 MeshMachine::TState<TContext>(aContext) {} |
|
366 |
|
367 virtual TBool Accept() |
|
368 { |
|
369 #ifdef __GCCXML__ |
|
370 return EFalse; |
|
371 #else |
|
372 Messages::TNodeSignal& msg = this->iContext.iMessage; //Arm compiler is getting confused otherwise |
|
373 return msg.IsMessage<TMESSAGE1>() |
|
374 || msg.IsMessage<TMESSAGE2>(); |
|
375 #endif |
|
376 } |
|
377 }; |
|
378 |
|
379 template<typename TMESSAGE, TUint32 FlagsToSet = 0, TUint32 FlagsToClear = 0> |
|
380 class TAwaitingPeerMessage : public MeshMachine::TState<TContext> |
|
381 { |
|
382 public: |
|
383 NETSM_TPL_DECLARE_CTR(TAwaitingPeerMessage, NetStateMachine::MState, TContext) |
|
384 |
|
385 TAwaitingPeerMessage(TContext& aContext) : |
|
386 MeshMachine::TState<TContext>(aContext) |
|
387 { |
|
388 } |
|
389 virtual TBool Accept() |
|
390 { |
|
391 #ifndef __GCCXML__ |
|
392 Messages::TNodeSignal& msg = this->iContext.iMessage; //Arm compiler is getting confused otherwise |
|
393 if (msg.IsMessage<TMESSAGE>()) |
|
394 { |
|
395 __ASSERT_DEBUG(this->iContext.iPeer, User::Panic(KSpecAssert_ElemMeshMachStaH, 4)); |
|
396 this->iContext.iPeer->ClearFlags(FlagsToClear); |
|
397 this->iContext.iPeer->SetFlags(FlagsToSet); |
|
398 return ETrue; |
|
399 } |
|
400 #endif |
|
401 return EFalse; |
|
402 } |
|
403 }; |
|
404 |
|
405 class AAcceptErrorState |
|
406 { |
|
407 protected: |
|
408 IMPORT_C static TBool Accept(MeshMachine::TNodeContextBase& aContext, TBool aSuperAccept); |
|
409 }; |
|
410 |
|
411 template<class TSTATE> |
|
412 class TAcceptErrorState : public TSTATE, public AAcceptErrorState |
|
413 { |
|
414 public: |
|
415 typedef typename TSTATE::TContext TContext; |
|
416 NETSM_TPL_DECLARE_CTR(TAcceptErrorState, NetStateMachine::MState, TContext) |
|
417 |
|
418 explicit TAcceptErrorState(TContext& aContext) |
|
419 : TSTATE(aContext) |
|
420 { |
|
421 } |
|
422 |
|
423 virtual TBool Accept() |
|
424 { |
|
425 return AAcceptErrorState::Accept(this->iContext, TSTATE::Accept()); |
|
426 } |
|
427 |
|
428 virtual void Cancel() |
|
429 { |
|
430 if(this->iContext.iNodeActivity != NULL) |
|
431 { |
|
432 this->iContext.iNodeActivity->SetError(KErrCancel); |
|
433 } |
|
434 TSTATE::Cancel(); |
|
435 } |
|
436 }; |
|
437 |
|
438 EXPORT_DECLARE_SMELEMENT_HEADER( TAwaitingNull, TState<TContext>, NetStateMachine::MState, TContext ) |
|
439 IMPORT_C virtual TBool Accept(); |
|
440 DECLARE_SMELEMENT_FOOTER( TAwaitingNull ) |
|
441 |
|
442 EXPORT_DECLARE_SMELEMENT_HEADER( TAwaitingAny, TState<TContext>, NetStateMachine::MState, TContext ) |
|
443 IMPORT_C virtual TBool Accept(); |
|
444 DECLARE_SMELEMENT_FOOTER( TAwaitingAny ) |
|
445 |
|
446 EXPORT_DECLARE_SMELEMENT_HEADER( TAwaitingClientLeavingRequest, TState<TContext>, NetStateMachine::MState, TContext ) |
|
447 IMPORT_C virtual TBool Accept(); |
|
448 DECLARE_SMELEMENT_FOOTER( TAwaitingClientLeavingRequest ) |
|
449 |
|
450 EXPORT_DECLARE_SMELEMENT_HEADER( TAwaitingLeaveComplete, TState<TContext>, NetStateMachine::MState, TContext ) |
|
451 IMPORT_C virtual TBool Accept(); |
|
452 DECLARE_SMELEMENT_FOOTER( TAwaitingLeaveComplete ) |
|
453 |
|
454 EXPORT_DECLARE_SMELEMENT_HEADER( TAwaitingDestroy, TState<TContext>, NetStateMachine::MState, TContext ) |
|
455 IMPORT_C virtual TBool Accept(); |
|
456 DECLARE_SMELEMENT_FOOTER( TAwaitingDestroy ) |
|
457 |
|
458 EXPORT_DECLARE_SMELEMENT_HEADER( TAwaitingCancel, TState<TContext>, NetStateMachine::MState, TContext ) |
|
459 IMPORT_C virtual TBool Accept(); |
|
460 DECLARE_SMELEMENT_FOOTER( TAwaitingCancel ) |
|
461 |
|
462 EXPORT_DECLARE_SMELEMENT_HEADER( TAwaitingErrorRecoveryResponseOrError, TState<TContext>, NetStateMachine::MState, TContext ) |
|
463 IMPORT_C virtual TBool Accept(); |
|
464 DECLARE_SMELEMENT_FOOTER( TAwaitingErrorRecoveryResponseOrError ) |
|
465 |
|
466 //-========================================================= |
|
467 // |
|
468 //Commonly used state forks |
|
469 // |
|
470 //-========================================================= |
|
471 |
|
472 template<TInt TAG> |
|
473 class TTag : public MeshMachine::TStateFork<TContext> |
|
474 { |
|
475 public: |
|
476 NETSM_TPL_DECLARE_CTR(TTag, NetStateMachine::MStateFork, TContext) |
|
477 |
|
478 TTag(TContext& aContext) |
|
479 : MeshMachine::TStateFork<TContext>(aContext) |
|
480 { |
|
481 } |
|
482 |
|
483 virtual TInt TransitionTag() |
|
484 { |
|
485 return TAG; |
|
486 } |
|
487 }; |
|
488 |
|
489 template<TInt ACTIVITYSIG> |
|
490 class TActiveOrNoTag : public MeshMachine::TStateFork<TContext> |
|
491 { |
|
492 public: |
|
493 NETSM_TPL_DECLARE_CTR(TActiveOrNoTag, NetStateMachine::MStateFork, TContext) |
|
494 |
|
495 explicit TActiveOrNoTag(TContext& aContext) |
|
496 : MeshMachine::TStateFork<TContext>(aContext) |
|
497 { |
|
498 } |
|
499 |
|
500 virtual TInt TransitionTag() |
|
501 { |
|
502 return (this->iContext.iNode.CountActivities(ACTIVITYSIG))? |
|
503 MeshMachine::KActiveTag : MeshMachine::KNoTag; |
|
504 } |
|
505 }; |
|
506 |
|
507 class AErrorTagOr |
|
508 { |
|
509 protected: |
|
510 IMPORT_C static TInt TransitionTag(MeshMachine::TNodeContextBase& aContext); |
|
511 }; |
|
512 |
|
513 template<class TFORK> |
|
514 class TErrorTagOr : public TFORK, public AErrorTagOr |
|
515 { |
|
516 public: |
|
517 typedef typename TFORK::TContext TContext; |
|
518 NETSM_TPL_DECLARE_CTR(TErrorTagOr, NetStateMachine::MStateFork, TContext) |
|
519 |
|
520 explicit TErrorTagOr(TContext& aContext) |
|
521 : TFORK(aContext) |
|
522 { |
|
523 } |
|
524 |
|
525 virtual TInt TransitionTag() |
|
526 { |
|
527 TUint tag = AErrorTagOr::TransitionTag(this->iContext); |
|
528 return (tag!=0)? tag : TFORK::TransitionTag(); |
|
529 } |
|
530 }; |
|
531 |
|
532 EXPORT_DECLARE_SMELEMENT_HEADER( TNoTag, TStateFork<TContext>, NetStateMachine::MStateFork, TContext ) |
|
533 DECLARE_SMELEMENT_FOOTER( TNoTag ) |
|
534 |
|
535 EXPORT_DECLARE_SMELEMENT_HEADER( TNoTagBackward, TStateFork<TContext>, NetStateMachine::MStateFork, TContext ) |
|
536 IMPORT_C virtual TInt TransitionTag(); |
|
537 DECLARE_SMELEMENT_FOOTER( TNoTagBackward ) |
|
538 |
|
539 EXPORT_DECLARE_SMELEMENT_HEADER( TErrorTag, TStateFork<TContext>, NetStateMachine::MStateFork, TContext ) |
|
540 IMPORT_C virtual TInt TransitionTag(); |
|
541 DECLARE_SMELEMENT_FOOTER( TErrorTag ) |
|
542 |
|
543 EXPORT_DECLARE_SMELEMENT_HEADER( TNoTagOrErrorTag, TStateFork<TContext>, NetStateMachine::MStateFork, TContext ) |
|
544 IMPORT_C virtual TInt TransitionTag(); |
|
545 DECLARE_SMELEMENT_FOOTER( TNoTagOrErrorTag ) |
|
546 |
|
547 |
|
548 |
|
549 /** |
|
550 This state fork will return KNoTag if no error is present in the activity, or a |
|
551 user supplied tag if an error condition has occured. |
|
552 */ |
|
553 template<TInt TAG> |
|
554 NONSHARABLE_CLASS(TNoTagOrCustomErrorTag) : public MeshMachine::TStateFork<TContext> |
|
555 { |
|
556 public: |
|
557 NETSM_TPL_DECLARE_CTR(TNoTagOrCustomErrorTag, NetStateMachine::MStateFork, TContext) |
|
558 |
|
559 TNoTagOrCustomErrorTag(TContext& aContext) |
|
560 : MeshMachine::TStateFork<TContext>(aContext) |
|
561 { |
|
562 } |
|
563 |
|
564 virtual TInt TransitionTag() |
|
565 { |
|
566 Messages::TEBase::TError* msg = Messages::message_cast<Messages::TEBase::TError>(&iContext.iMessage); |
|
567 if (KErrNone==iContext.iNodeActivity->Error() && NULL==msg) |
|
568 { |
|
569 return KNoTag | NetStateMachine::EForward; |
|
570 } |
|
571 if (msg) |
|
572 { |
|
573 iContext.iNodeActivity->SetError(msg->iValue); |
|
574 } |
|
575 return TAG; |
|
576 } |
|
577 }; |
|
578 |
|
579 |
|
580 //-========================================================= |
|
581 // |
|
582 // Commonly used transitions |
|
583 // |
|
584 //-========================================================= |
|
585 |
|
586 //RaiseError - this transion, when invoked, just leaves with the error |
|
587 //given as the template parameter. |
|
588 template<TInt ERROR> |
|
589 class TRaiseError : public MeshMachine::TStateTransition<TContext> |
|
590 { |
|
591 public: |
|
592 NETSM_TPL_DECLARE_CTR(TRaiseError, NetStateMachine::MStateTransition,TContext) |
|
593 |
|
594 TRaiseError(TContext& aContext) : |
|
595 MeshMachine::TStateTransition<TContext>(aContext) |
|
596 { |
|
597 } |
|
598 |
|
599 virtual void DoL() |
|
600 { |
|
601 User::Leave(ERROR); |
|
602 } |
|
603 }; |
|
604 |
|
605 |
|
606 //ARetryTransition - used to turn standard transitions into "retry" ones, |
|
607 //so that they can be used directly in a "retry activity". |
|
608 template<class TSTATETRANSITION, class MESSAGE> |
|
609 class TRetryTransition : public TSTATETRANSITION |
|
610 { |
|
611 public: |
|
612 typedef typename TSTATETRANSITION::TContext TContext; |
|
613 NETSM_TPL_DECLARE_CTR(TRetryTransition, NetStateMachine::MStateTransition, TContext) |
|
614 |
|
615 explicit TRetryTransition(TContext& aContext) |
|
616 : TSTATETRANSITION(aContext) |
|
617 { |
|
618 } |
|
619 |
|
620 virtual void DoL() |
|
621 { |
|
622 __ASSERT_DEBUG(this->iContext.iNodeActivity, User::Panic(KSpecAssert_ElemMeshMachStaH, 5)); |
|
623 MeshMachine::AContextStore* intf = reinterpret_cast<MeshMachine::AContextStore*>(this->iContext.iNodeActivity->FetchExtInterfaceL(MeshMachine::AContextStore::KInterfaceId)); |
|
624 Messages::TNodeSignal::TMessageId retryingFor = intf->RetryingForMessageId(); |
|
625 if (retryingFor.IsNull() || retryingFor == MESSAGE::Id()) |
|
626 { |
|
627 User::LeaveIfError(intf->StoreContext(this->iContext)); |
|
628 TSTATETRANSITION::DoL(); |
|
629 } |
|
630 } |
|
631 }; |
|
632 |
|
633 //TPostMsgToSender - just posts a reply to the sender of the message being |
|
634 //processed. Only works for SigVoid obviously |
|
635 template<class MESSAGETYPE> |
|
636 class TPostMessageToSender : public MeshMachine::TStateTransition<TContext> |
|
637 { |
|
638 public: |
|
639 NETSM_TPL_DECLARE_CTR(TPostMessageToSender, NetStateMachine::MStateTransition, TContext) |
|
640 |
|
641 explicit TPostMessageToSender(TContext& aContext) |
|
642 : MeshMachine::TStateTransition<TContext>(aContext) |
|
643 { |
|
644 } |
|
645 |
|
646 virtual void DoL() |
|
647 { |
|
648 this->iContext.PostToSender(MESSAGETYPE().CRef()); |
|
649 } |
|
650 }; |
|
651 |
|
652 //TPostMsgToOriginators - just posts a reply to all originators of the activity |
|
653 //Only works for SigVoid obviously |
|
654 template<class MESSAGETYPE, TUint16 FLAGSTOSET = 0, TUint16 FLAGSTOCLEAR = 0> |
|
655 class TPostMessageToOriginators : public MeshMachine::TStateTransition<TContext> |
|
656 { |
|
657 public: |
|
658 NETSM_TPL_DECLARE_CTR(TPostMessageToOriginators, NetStateMachine::MStateTransition, TContext) |
|
659 |
|
660 explicit TPostMessageToOriginators(TContext& aContext) |
|
661 : MeshMachine::TStateTransition<TContext>(aContext) |
|
662 { |
|
663 } |
|
664 |
|
665 virtual void DoL() |
|
666 { |
|
667 __ASSERT_DEBUG(this->iContext.iNodeActivity, User::Panic(KSpecAssert_ElemMeshMachStaH, 6)); |
|
668 this->iContext.iNodeActivity->PostToOriginators(MESSAGETYPE().CRef(), FLAGSTOSET, FLAGSTOCLEAR); |
|
669 } |
|
670 }; |
|
671 |
|
672 EXPORT_DECLARE_SMELEMENT_HEADER( TDoNothing, TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext ) |
|
673 IMPORT_C virtual void DoL(); |
|
674 DECLARE_SMELEMENT_FOOTER( TDoNothing ) |
|
675 |
|
676 EXPORT_DECLARE_SMELEMENT_HEADER( TSetIdle, TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext ) |
|
677 IMPORT_C virtual void DoL(); |
|
678 DECLARE_SMELEMENT_FOOTER( TSetIdle ) |
|
679 |
|
680 EXPORT_DECLARE_SMELEMENT_HEADER( TRemoveClient, TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext ) |
|
681 IMPORT_C virtual void DoL(); |
|
682 DECLARE_SMELEMENT_FOOTER( TRemoveClient ) |
|
683 |
|
684 EXPORT_DECLARE_SMELEMENT_HEADER( TRaiseActivityError, TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext ) |
|
685 IMPORT_C virtual void DoL(); |
|
686 DECLARE_SMELEMENT_FOOTER( TRaiseActivityError ) |
|
687 |
|
688 EXPORT_DECLARE_SMELEMENT_HEADER( TRaiseAndClearActivityError, TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext ) |
|
689 IMPORT_C virtual void DoL(); |
|
690 DECLARE_SMELEMENT_FOOTER( TRaiseAndClearActivityError ) |
|
691 |
|
692 EXPORT_DECLARE_SMELEMENT_HEADER( TStoreError, TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext ) |
|
693 IMPORT_C virtual void DoL(); |
|
694 DECLARE_SMELEMENT_FOOTER( TStoreError ) |
|
695 |
|
696 EXPORT_DECLARE_SMELEMENT_HEADER( TClearError, TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext ) |
|
697 IMPORT_C virtual void DoL(); |
|
698 DECLARE_SMELEMENT_FOOTER( TClearError ) |
|
699 |
|
700 EXPORT_DECLARE_SMELEMENT_HEADER( TForwardMessageToOriginators, TStateTransition<TContext>, NetStateMachine::MStateTransition, TContext ) |
|
701 IMPORT_C virtual void DoL(); |
|
702 DECLARE_SMELEMENT_FOOTER( TForwardMessageToOriginators ) |
|
703 |
|
704 } //namespace MeshMachine |
|
705 |
|
706 |
|
707 #endif |
|
708 // SYMBIAN_MM_STATES_H |
|
709 |