datacommsserver/esockserver/core_states/ss_corepractivities.cpp~
changeset 2 dee179edb159
parent 1 21d2ab05f085
child 3 b6139031a239
equal deleted inserted replaced
1:21d2ab05f085 2:dee179edb159
     1 // Copyright (c) 2006-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 // COREPRACTIVITIES.CPP
       
    15 // Core PR Activities
       
    16 // THIS API IS INTERNAL TO NETWORKING AND IS SUBJECT TO CHANGE AND NOT FOR EXTERNAL USE
       
    17 //
       
    18 //
       
    19 
       
    20 /**
       
    21  @file
       
    22  @internalComponent
       
    23 */
       
    24 
       
    25 #define SYMBIAN_NETWORKING_UPS
       
    26 
       
    27 #include "ss_corepractivities.h"
       
    28 
       
    29 
       
    30 #include <comms-infras/ss_log.h>
       
    31 #include "ss_internal_activities.h"
       
    32 #include <comms-infras/ss_coreprstates.h>
       
    33 #include <comms-infras/ss_subconnprov.h>
       
    34 #include <comms-infras/ss_mcprnodemessages.h>
       
    35 
       
    36 #include <comms-infras/ss_protocolparameterset.h>
       
    37 #include <ss_glob.h>
       
    38 
       
    39 
       
    40 #include <elements/nm_messages_child.h>
       
    41 #include <elements/nm_messages_peer.h>
       
    42 #include <elements/nm_messages_errorrecovery.h>
       
    43 #include "ss_nodemessages_dataclient.h"
       
    44 #include "ss_nodemessages_serviceprovider.h"
       
    45 #include <comms-infras/ss_nodemessages_rejoiningprovider.h>
       
    46 #include <comms-infras/ss_nodemessages_flow.h>
       
    47 #include "ss_nodemessages_factory.h"
       
    48 #include <comms-infras/ss_nodemessages_internal_esock.h>
       
    49 
       
    50 
       
    51 #ifdef _DEBUG
       
    52 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    53 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    54 _LIT(KSpecAssert_ESockCrStaCPRAC, "ESockCrStaCPRAC");
       
    55 #endif
       
    56 
       
    57 #if defined __CFLOG_ACTIVE || defined ESOCK_EXTLOG_ACTIVE
       
    58 	#define KCoreProviderStatesTag KESockCoreProviderTag
       
    59 	_LIT8(KCoreProviderStatesSubTag, "coreprovstate");
       
    60 #endif
       
    61 
       
    62 using namespace NetStateMachine;
       
    63 using namespace CoreStates;
       
    64 using namespace CoreNetStates;
       
    65 using namespace PRStates;
       
    66 using namespace PRActivities;
       
    67 using namespace CoreActivities;
       
    68 using namespace ESock;
       
    69 using namespace CorePanics;
       
    70 using namespace Elements;
       
    71 using namespace Messages;
       
    72 using namespace MeshMachine;
       
    73 using namespace Factories;
       
    74 
       
    75 
       
    76 #ifdef _DEBUG
       
    77 _LIT (KCorePrPanic,"CorePrPanic");
       
    78 #endif
       
    79 
       
    80 namespace CoreErrorActivity
       
    81 { //Special parallel activity, must be started as the last one
       
    82 DEFINE_EXPORT_CUSTOM_NODEACTIVITY(ECFActivityError, CoreError, TEBase::TError, CErrorActivity::NewL)
       
    83 	FIRST_NODEACTIVITY_ENTRY(CErrorActivity::TCFAwaitingError, MeshMachine::TNoTag)
       
    84 	NODEACTIVITY_ENTRY(KNoTag, CErrorActivity::TSendErrorRecoveryReq, MeshMachine::TAwaitingMessageState<TEErrorRecovery::TErrorRecoveryResponse>, MeshMachine::TNoTag)
       
    85 	LAST_NODEACTIVITY_ENTRY(KNoTag, CErrorActivity::TDoErrorRecovery)
       
    86 NODEACTIVITY_END()
       
    87 }
       
    88 
       
    89 namespace PRProvisionActivity
       
    90 {
       
    91 DECLARE_DEFINE_NODEACTIVITY(ECFActivityStoreProvision, PrProvision, TCFDataClient::TProvisionConfig)
       
    92 	NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreProvision, CoreNetStates::TAwaitingProvision, MeshMachine::TNoTag)
       
    93 NODEACTIVITY_END()
       
    94 }
       
    95 
       
    96 namespace PRControlClientJoinActivity
       
    97 {
       
    98 DEFINE_EXPORT_NODEACTIVITY(ECFActivityClientJoin, PRControlClientJoin, TNodeSignal::TNullMessageId) //May be waiting for both messages
       
    99 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TAddControlClientAndSendJoinCompleteIfRequest, CoreNetStates::TAwaitingControlClientJoin, MeshMachine::TNoTag)
       
   100 NODEACTIVITY_END()
       
   101 }
       
   102 
       
   103 namespace PRDataClientJoinActivity
       
   104 { //This activity needs the activity object (& it can fail on AddClientL, so no point converting)
       
   105 DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientJoin, PRDataClientJoin, TCFPeer::TJoinRequest)
       
   106 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientJoinRequest, MeshMachine::TNoTag)
       
   107 	LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TAddDataClientAndRespond)
       
   108 NODEACTIVITY_END()
       
   109 }
       
   110 
       
   111 namespace PRClientLeaveActivity
       
   112 {//This activity will wait for ECFActivityBinderRequest to complete
       
   113 DEFINE_EXPORT_NODEACTIVITY(ECFActivityClientLeave, PRClientLeave, TNodeSignal::TNullMessageId) //May be waiting for both messages
       
   114 NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessClientLeave, CoreStates::TAwaitingClientLeave, MeshMachine::TNoTag)
       
   115 NODEACTIVITY_END()
       
   116 }
       
   117 
       
   118 namespace PRDataClientIdleActivity
       
   119 {
       
   120 DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientIdle, PRDataClientIdle, TCFControlProvider::TIdle)
       
   121     NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::THandleDataClientIdle, CoreNetStates::TAwaitingDataClientIdle, MeshMachine::TNoTag)
       
   122 NODEACTIVITY_END()
       
   123 }
       
   124 
       
   125 namespace PRDataClientActiveActivity
       
   126 {
       
   127 DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientActive, PRDataClientActive, TCFControlProvider::TActive)
       
   128 	NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TAwaitingDataClientActive, MeshMachine::TNoTag)
       
   129 NODEACTIVITY_END()
       
   130 }
       
   131 
       
   132 namespace PRDestroyActivity
       
   133 {
       
   134 //The generic Destroy activity. Carries out the node's goodbye handshake.
       
   135 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDestroy, PRDestroy, TEChild::TDestroy, CoreActivities::CDestroyActivity::New)
       
   136 	FIRST_NODEACTIVITY_ENTRY(MeshMachine::TAwaitingDestroy, CoreActivities::CDestroyActivity::TNoTagBlockedByActivitiesOrLeavingDataClient)
       
   137 
       
   138     //Stop self first
       
   139     NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreStates::TNoTagOrNoClients)
       
   140 
       
   141     //The node mustn't go out of scope with clients present. The node must get rid of them first.
       
   142 	NODEACTIVITY_ENTRY(KNoTag, CoreActivities::CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, CoreStates::TAwaitingClientLeave,  CDestroyActivity::TNoTagOrNoTagBackwards)
       
   143 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::CDestroyActivity::TProcessClientLeave, TTag<KNoClients>)
       
   144 
       
   145  	THROUGH_NODEACTIVITY_ENTRY(KNoClients, PRStates::TProcessDestroy, MeshMachine::TNoTag)
       
   146  	NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards)
       
   147  	LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingAndRemoveControlProvider)
       
   148 NODEACTIVITY_END()
       
   149 }
       
   150 
       
   151 namespace PRSetParamsRequest
       
   152 {
       
   153 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   154 DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRSetParams, TCFScpr::TSetParamsRequest)
       
   155 	FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent)
       
   156 	NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, MeshMachine::TTag<CoreNetStates::KBearerPresent>)
       
   157 	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TStoreParamsAndPostToOriginators)
       
   158 	LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreAndRespondWithCurrentParams)
       
   159 NODEACTIVITY_END()
       
   160 #else
       
   161 DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRSetParams, TNodeSignal::TNullMessageId)
       
   162 NODEACTIVITY_END()
       
   163 #endif
       
   164 }
       
   165 
       
   166 // no Store in case of GetParamsRequest
       
   167 namespace PRGetParamsRequest
       
   168 {
       
   169 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   170 DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRGetParams, TCFScpr::TGetParamsRequest)
       
   171 	FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent)
       
   172 	NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, MeshMachine::TTag<CoreNetStates::KBearerPresent>)
       
   173 	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreStates::TPostToOriginators)
       
   174 	LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TRespondWithRetrievedParams)
       
   175 NODEACTIVITY_END()
       
   176 #else
       
   177 DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRGetParams, TNodeSignal::TNullMessageId)
       
   178 NODEACTIVITY_END()
       
   179 #endif
       
   180 }
       
   181 
       
   182 namespace PRBindToActivity
       
   183 {
       
   184 //PRBindToActivity is responsible for handling TCFDataClient::TBindTo;
       
   185 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBindTo, PRBindTo, TCFDataClient::TBindTo, CBindToActivity::NewL)
       
   186 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBindTo, CBindToActivity::TNoTagOrBearerReady)
       
   187     //TBindTo can hold:
       
   188     //[KNoTag] 		 - a valid serviceProvider cookie that this node isn't bound to;
       
   189     //[KBearerReady] - a valid serviceProvider cookie that this node is already bound to;
       
   190     //[KBearerReady] - a NULL serviceProvider (this node is at the stack's bottom);
       
   191 
       
   192 	  //{ JOINING NEW SERVICE PROVIDER
       
   193 		//a valid serviceProvider supplied, new to this node, let's join it;
       
   194 	    NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TSendControlClientJoinRequest, CoreStates::TAwaitingJoinComplete, TTag<KBearerReady>)
       
   195 	  //}
       
   196 
       
   197 	//serviceProvider provisionally joined. Now the activity needs to propagate iteslf (TBindTo) to its dataclients.
       
   198 	//The dataclients are either present or not. If not this activity will assume this is the layer construction phase
       
   199 	//and will attempt to construct a default dataclient.
       
   200 	THROUGH_NODEACTIVITY_ENTRY(KBearerReady, MeshMachine::TDoNothing, CBindToActivity::TNoTagOrDataClientReady)
       
   201 
       
   202 	  //{ DATA CLIENT CREATION
       
   203 		//No dataclients present, assume this is the layer creation phase. Attempt to create a dataclient.
       
   204 		NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TCreateDataClient, TAcceptErrorState<CoreNetStates::TAwaitingDataClientJoin>, MeshMachine::TErrorTagOr<CBindToActivity::TNoTagOrBindToComplete>)
       
   205 	    //BindTo activity is the pre-start layer builder, hence it always requests the dataclient from the factory.
       
   206 	    //The factory (being aware of the phase) may decide to:
       
   207 	    //1. create a new dataclient          -> process dataclient creation            [KNoTag]
       
   208 	    //2. return a preexisting dataclient  -> bind the client                        [KDataClientReady]
       
   209 	    //3. not to create a dataclient       -> send TBindToComplete to the originator [KBindToComplete]
       
   210 		THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessDataClientCreation, TTag<KDataClientReady>)
       
   211 	  //}
       
   212 
       
   213     THROUGH_NODEACTIVITY_ENTRY(KDataClientReady, MeshMachine::TDoNothing, CBindToActivity::TNoTagOrBearerReadyOrBindToComplete)
       
   214       //{ BINDING DATACLIENTS LOOP
       
   215 	    //Dataclient(s) is/are ready. Depending on whether the node has the lower layer or not,
       
   216 	    //we will [KNoTag] or will not [KNoBearer] need to request a binder for the dataclient.
       
   217 
       
   218 		  //{SERVICE PROVIDER PRESENT
       
   219 			NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TRequestCommsBinder, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, TErrorTagOr<TTag<KBearerReady> >)
       
   220 	      //}
       
   221 		NODEACTIVITY_ENTRY(KBearerReady, PRActivities::CBindToActivity::TSendBindTo, CBindToActivity::TAwaitingBindToCompleteOrError,
       
   222 																					 TErrorTagOr<TTag<KDataClientReady | NetStateMachine::EBackward> >)
       
   223 	  //}
       
   224 
       
   225 	//Binding is finished. If this is not autocommit (see TCFDataClient::TBindTo), the activity will reply TCFDataClient::TBindToComplete
       
   226 	//to the sender await for the confirmation (TCFDataClient::TCommitBindTo) or cancelation (TBase::TCancel) from the sender.
       
   227 	//If this is autommit, the activity will skip awaiting for TCFDataClient::TCommitBindTo and commit itself.
       
   228 	THROUGH_NODEACTIVITY_ENTRY(KBindToComplete, CBindToActivity::TSendBindToComplete, CBindToActivity::TNoTagOrCommit)
       
   229 	NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingMessageState<TCFDataClient::TCommitBindTo>, TErrorTagOr<TTag<KCommit> >)
       
   230 
       
   231 	//commiting (either implicit or explicit).
       
   232 	NODEACTIVITY_ENTRY(KCommit, CBindToActivity::TCommit, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
       
   233 
       
   234 	//This is not autocommit and the sender has just explicitly cancelled. Alternativelly this is an error path.
       
   235 	//Cancelling/processing error entiles sending TCancel to all dataclients awaiting confirmation
       
   236 	//as well as it entiles leaving the new service provider.
       
   237 	NODEACTIVITY_ENTRY(KErrorTag, CBindToActivity::TCancel, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
       
   238 
       
   239 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
   240 NODEACTIVITY_END()
       
   241 }
       
   242 
       
   243 namespace PRStartActivity
       
   244 {
       
   245 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, PRStart, TCFServiceProvider::TStart, PRActivities::CStartActivity::NewL)
       
   246     FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStart, CoreNetStates::TNoTagOrBearerPresentBlockedByStop)
       
   247 	NODEACTIVITY_ENTRY(KBearerPresent, CoreNetStates::TBindSelfToPresentBearer, CoreNetStates::TAwaitingBindToComplete, TTag<KBearerPresent>)
       
   248 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendNoBearer, MeshMachine::TAwaitingMessageState<TCFControlProvider::TBearer>, CoreNetStates::TNoTagOrBearerPresentOrErrorTag)
       
   249 
       
   250 	//Start the service provider, use the default cancellation.
       
   251 	//Forward TCancel to the service provider, wait for TStarted or TError (via the Error Activity)
       
   252 	//When TStarted arrives after TCancel the activity will move to the nearest KErrorTag
       
   253 	NODEACTIVITY_ENTRY(KBearerPresent, CoreNetStates::TStartServiceProviderRetry, CoreNetStates::TAwaitingStarted, MeshMachine::TNoTagOrErrorTag)
       
   254 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
       
   255 	//Start data clients, use the default cancellation.
       
   256 	//Forward TCancel to the self, wait for TCFDataClient::TStarted or TError (via the Error Activity)
       
   257 	//When TCFDataClient::TStarted arrives after TCancel the activity will move to the nearest KErrorTag
       
   258 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStartSelf, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTagOrErrorTag)
       
   259 	NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TErrorTag)
       
   260 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
       
   261 	LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStarted)
       
   262 NODEACTIVITY_END()
       
   263 }
       
   264 
       
   265 namespace PRStopActivity
       
   266 {
       
   267 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStop, PRStop, TCFServiceProvider::TStop, MeshMachine::CNodeRetryActivity::NewL)
       
   268 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStop, TActiveOrNoTagBlockedByBindTo)
       
   269 	THROUGH_NODEACTIVITY_ENTRY(KActiveTag, CoreNetStates::TCancelDataClientStart, MeshMachine::TNoTag)
       
   270 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreNetStates::TNoTagOrNoBearer)
       
   271 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStop, CoreNetStates::TAwaitingStopped, MeshMachine::TNoTag)
       
   272 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, TTag<CoreNetStates::KNoBearer>)
       
   273 	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, PRStates::TSendStoppedAndGoneDown)
       
   274 NODEACTIVITY_END()
       
   275 }
       
   276 
       
   277 namespace PRDataClientStartActivity
       
   278 {
       
   279 DECLARE_DEFINE_NODEACTIVITY(ECFActivityStartDataClient, PRDataClientStart, TCFDataClient::TStart)
       
   280     FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, CoreNetStates::TNoTagOrNoDataClients)
       
   281 	NODEACTIVITY_ENTRY(KNoTag, PRStates::TStartDataClients, TAcceptErrorState<CoreNetStates::TAwaitingDataClientsStarted>, MeshMachine::TErrorTagOr<MeshMachine::TTag<CoreNetStates::KNoDataClients> >)
       
   282 	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClients, PRStates::TSendDataClientStarted)
       
   283 
       
   284 	NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TErrorTag)
       
   285 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
       
   286 NODEACTIVITY_END()
       
   287 }
       
   288 
       
   289 namespace PRDataClientStopActivity
       
   290 {
       
   291 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStopDataClient, PRDataClientStop, TCFDataClient::TStop, MeshMachine::CNodeRetryActivity::NewL)
       
   292 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStop, MeshMachine::TNoTag)
       
   293 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessDataClientStop, CoreNetStates::TNoTagOrDataClientsToStopBlockedByStarting)
       
   294 
       
   295 	NODEACTIVITY_ENTRY(CoreNetStates::KDataClientsToStop, CoreNetStates::TStopDataClients, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TNoTag)
       
   296 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TNoTagOrUnbindOnStop)
       
   297 
       
   298 	NODEACTIVITY_ENTRY(CoreNetStates::KUnbind, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
       
   299 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TDestroyOrphanedDataClients, MeshMachine::TNoTag)
       
   300 	LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendDataClientStopped)
       
   301 NODEACTIVITY_END()
       
   302 }
       
   303 
       
   304 
       
   305 namespace PRForwardStateChangeActivity
       
   306 {
       
   307 DECLARE_DEFINE_NODEACTIVITY(ECFActivityForwardStateChange, PRForwardStateChange, TCFMessage::TStateChange)
       
   308 	NODEACTIVITY_ENTRY(KNoTag, PRStates::TForwardStateChange, MeshMachine::TAwaitingMessageState<TCFMessage::TStateChange>, MeshMachine::TNoTag)
       
   309 NODEACTIVITY_END()
       
   310 }
       
   311 
       
   312 namespace PRDataClientStatusChangeActivity
       
   313 {
       
   314 DECLARE_DEFINE_NODEACTIVITY(ECFActivityDataClientStatusChange, PRDataClientStatusChange, TCFControlProvider::TDataClientStatusChange)
       
   315 	NODEACTIVITY_ENTRY(KNoTag, PRStates::THandleDataClientStatusChangeAndDestroyOrphans, CoreNetStates::TAwaitingDataClientStatusChange, MeshMachine::TNoTag)
       
   316 NODEACTIVITY_END()
       
   317 }
       
   318 
       
   319 namespace PRGoneDownActivity
       
   320 {
       
   321 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGoneDown, PRGoneDown, TCFControlClient::TGoneDown, CGoneDownActivity::NewL)
       
   322 	// Our Service Provider has gone down unexpectedly (we haven't issued a TStop)
       
   323 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneDown, MeshMachine::TNoTag)
       
   324 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TCancelAndCloseZone0ClientExtIfaces, MeshMachine::TNoTag)
       
   325 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
       
   326 	NODEACTIVITY_ENTRY(KNoTag, CGoneDownActivity::TSendErrorRecoveryReq, MeshMachine::TAwaitingErrorRecoveryResponseOrError, CoreStates::TRetryOrIgnoreOrPropagate)
       
   327 	THROUGH_NODEACTIVITY_ENTRY(CoreStates::KRetry, MeshMachine::TDoNothing, CGoneDownActivity::TIgnoreOrPropagate)
       
   328 	LAST_NODEACTIVITY_ENTRY(CoreStates::KIgnore, MeshMachine::TDoNothing)
       
   329 	NODEACTIVITY_ENTRY(CoreStates::KPropagate, CoreNetStates::TCancelStartAndStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TNoTag)
       
   330 	LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendGoneDown)
       
   331 NODEACTIVITY_END()
       
   332 }
       
   333 
       
   334 
       
   335 namespace PRGoneUpActivity
       
   336 {
       
   337 // This Activity forward the TGoneUp event to the Control Clients nodes that are
       
   338 // not in the originator lis
       
   339 
       
   340 DECLARE_DEFINE_NODEACTIVITY(ECFActivityGoneUp, PRGoneUp, TCFControlClient::TGoneUp)
       
   341 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneUp, MeshMachine::TNoTag)
       
   342     LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendGoneUp)
       
   343 NODEACTIVITY_END()
       
   344 }
       
   345 
       
   346 namespace PRLegacyRMessage2HandlerActivity
       
   347 {
       
   348 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityLegacyRMessage2Handler, PRLegacyRMessage2Handler, TNodeSignal::TNullMessageId, MeshMachine::CNodeParallelMessageStoreActivityBase::NewL)
       
   349 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingLegacyRMessage2Ext, MeshMachine::TNoTag)
       
   350 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TProcessOrForwardRMessage2Ext, CoreNetStates::TAwaitingRMessage2Processed, MeshMachine::TNoTag)
       
   351     LAST_NODEACTIVITY_ENTRY(KNoTag, CoreStates::TPostToOriginators)
       
   352 NODEACTIVITY_END()
       
   353 }
       
   354 
       
   355 
       
   356 namespace CoreActivities
       
   357 {
       
   358 DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesAll)
       
   359 	ACTIVITY_MAP_ENTRY(CoreErrorActivity, CoreError) //Must be first in the table
       
   360 ACTIVITY_MAP_END()
       
   361 
       
   362 //-=========================================================
       
   363 //
       
   364 //Error Activity
       
   365 //
       
   366 //-=========================================================
       
   367 MeshMachine::CNodeActivityBase* CErrorActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode )
       
   368     {
       
   369 	TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
   370     return new(ELeave)CErrorActivity(aActivitySig, aNode, c);
       
   371     }
       
   372 
       
   373 CErrorActivity::CErrorActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount)
       
   374 	:	MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aActivitiesCount), iErroredActivityId(MeshMachine::KActivityNull)
       
   375 	{
       
   376 	}
       
   377 
       
   378 CErrorActivity::~CErrorActivity()
       
   379 	{
       
   380 	if (Error() != KErrNone)
       
   381 		{
       
   382 		CNodeActivityBase* a = iNode.FindActivityById(iErroredActivityId);
       
   383 		if (a)
       
   384 			{
       
   385 			a->SetError(Error());
       
   386 			a->SetIdle();
       
   387 			}
       
   388     	}
       
   389     SetError(KErrNone);
       
   390     }
       
   391 
       
   392 TBool CErrorActivity::IsIdle() const
       
   393 	{
       
   394 	return NetStateMachine::ACore::IsIdle();
       
   395 	}
       
   396 
       
   397 void CErrorActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& /*aOriginator*/, const TStateTriple& aFirst)
       
   398 	{
       
   399 	__ASSERT_DEBUG(IsIdle(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 1));
       
   400   	MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CErrorActivity %08x:\tStartL->starting activity"), this));
       
   401 
       
   402 	NetStateMachine::ACore::Start(&aContext, aFirst);
       
   403 
       
   404     MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CErrorActivity %08x:\tStartL->activity started"),this));
       
   405 	}
       
   406 
       
   407 TBool CErrorActivity::Next(TNodeContextBase& aContext)
       
   408 	{
       
   409 	TBool ret = EFalse;
       
   410 
       
   411 
       
   412 	if (aContext.iMessage.IsMessage<TEBase::TCancel>())
       
   413 		{
       
   414 		CNodeActivityBase* a = iNode.FindActivityById(iErroredActivityId);
       
   415 		//Special handling for TCancel.
       
   416 		if (a && a->FindOriginator(aContext.iSender) != KErrNotFound)
       
   417 			{
       
   418 			ret = ETrue;
       
   419 			//iActiviy could have handled it, but chose not to.
       
   420 			Cancel(aContext);
       
   421 			//consume the message, otherwise the iActivity will get idled and iActivity reference
       
   422 			//will become invalid.
       
   423 			aContext.iMessage.ClearMessageId();
       
   424 			}
       
   425 		}
       
   426 	else
       
   427 		{
       
   428 		//If we have sent TErrorRecoveryRequest, we had to have set PostedToId() to the recipient (ControlProvider)
       
   429 		//as otherwise there would be no path for propagating the potential TCancel.
       
   430 		//The response however (TErrorRecoveryResponse or TError) will not necesserily come from that recipient (CP)
       
   431 		//(for example it could be coming from the MCpr and we could be the SCpr).
       
   432 		//Normally this would be a problem because any unrelated TError message arriving to the node
       
   433 		//and presented to the awaiting state would easily be confused with the response (TError == no recovery on the MCpr == EPropagate).
       
   434 		//We avoid the problem by checking all arriving  messages if they are adressed to our activity (but we don't
       
   435 		//check the sender.
       
   436 	    const TNodeCtxId* recipient = address_cast<const TNodeCtxId>(&aContext.iRecipient);
       
   437 		if (recipient && (ActivityId() == recipient->NodeCtx()))
       
   438 			{
       
   439 			ret = ACore::Next(&aContext);
       
   440 			if(ret)
       
   441 				{
       
   442 		    	MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CNodeActivityBase %08x:\tNext->transition"), this));
       
   443 				}
       
   444 			}
       
   445 		}
       
   446 	return ret;
       
   447   	}
       
   448 
       
   449 EXPORT_DEFINE_SMELEMENT(CErrorActivity::TAwaitingError, NetStateMachine::MState, CErrorActivity::TContext)
       
   450 EXPORT_C TBool CErrorActivity::TAwaitingError::Accept()
       
   451     {
       
   452 	if (! iContext.iMessage.IsMessage<TEBase::TError>())
       
   453 		{
       
   454 		return EFalse;
       
   455 		}
       
   456 
       
   457 	TEBase::TError& errorMessage = message_cast<TEBase::TError>(iContext.iMessage);
       
   458 
       
   459 	//Diagnostic panic only. TError message should not be travelling around with KErrNone.
       
   460 	//If you see this panic, please send a proper error code.
       
   461 	__ASSERT_DEBUG(errorMessage.iValue != KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 2));
       
   462 
       
   463     MeshMachine::CNodeActivityBase* aa = iContext.Node().FindAddressedActivity(iContext);
       
   464 
       
   465     //TError is always a response. If there is no activity addressed by the TError,
       
   466     //then we assume the activity hasn't bothered waiting for the result.
       
   467     //We hence ignore the error.
       
   468     if (aa)
       
   469     	{
       
   470         aa->SetError(errorMessage.iValue);
       
   471     	aa->SetIdle();
       
   472     	}
       
   473     errorMessage.ClearMessageId();
       
   474     return EFalse;
       
   475     }
       
   476 
       
   477 DEFINE_SMELEMENT(CErrorActivity::TCFAwaitingError, NetStateMachine::MState, CErrorActivity::TContext)
       
   478 EXPORT_C TBool CErrorActivity::TCFAwaitingError::Accept()
       
   479     {
       
   480 	if (! iContext.iMessage.IsMessage<TEBase::TError>())
       
   481 		{
       
   482 		return EFalse;
       
   483 		}
       
   484 
       
   485 	TEBase::TError& errorMessage = message_cast<TEBase::TError>(iContext.iMessage);
       
   486 
       
   487 	//Diagnostic panic only. TError message should not be travelling around with KErrNone.
       
   488 	//If you see this panic, please send a proper error code.
       
   489 	__ASSERT_DEBUG(errorMessage.iValue != KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 3));
       
   490 
       
   491 	RNodeInterface* client = iContext.Node().FindClient(iContext.iSender);
       
   492 	if (client &&
       
   493 		client->Type() & TCFClientType::EServProvider &&
       
   494 		iContext.Node().ControlProvider() != NULL &&
       
   495 		iContext.Node().CountActivities(ECFActivityDestroy) == 0)
       
   496 		{
       
   497 		//this is the only way out into the activity and into error recovery steps
       
   498 		//that error activity is responsible for doing.
       
   499 		return ETrue;
       
   500 		}
       
   501 
       
   502     return CErrorActivity::TAwaitingError::Accept();
       
   503     }
       
   504 
       
   505 //Simply leaving from this DoL will NOT have the effect of sending TError to originators
       
   506 //of the Errored activity! iContext.iNodeActivity is the Error activity.
       
   507 //Reassign iContext.iNodeActivity before leaving or handle the error.
       
   508 EXPORT_DEFINE_SMELEMENT(CErrorActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CErrorActivity::TContext)
       
   509 EXPORT_C void CErrorActivity::TSendErrorRecoveryReq::DoL()
       
   510     {
       
   511 	//Find matching activity, if any
       
   512     MeshMachine::CNodeActivityBase* aa = iContext.Node().FindAddressedActivity(iContext);
       
   513     //we are started based on the fact the the last message iContext.Node()'s received is TError
       
   514     TEBase::TError& errmsg = message_cast<TEBase::TError>(iContext.iMessage);
       
   515 
       
   516 	//The error comes from someone else than our Data Client (or we wouldn't be here).
       
   517 	//It may be our Service Provider or it can be some other node which has originated
       
   518 	//an activity on us (in which case the errored activity must be present).
       
   519     if (aa==NULL)
       
   520     	{
       
   521         __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ASendErrorRecoveryReq::DoL - TError but no addressed activity - ignoring")));
       
   522 #ifdef SYMBIAN_NETWORKING_UPS
       
   523 		// Terminate the error activity (not UPS specific).
       
   524         iContext.iNodeActivity->SetIdle();
       
   525 #endif //SYMBIAN_NETWORKING_UPS
       
   526         return;
       
   527     	}
       
   528 
       
   529 	 AContextStore* intf = NULL;
       
   530      if (aa->SupportsExtInterface(AContextStore::KInterfaceId))
       
   531     	{
       
   532     	//FetchExtInterfaceL below can never leave because it is being checked few lines above in the "if"
       
   533 	    intf = reinterpret_cast<AContextStore*>(aa->FetchExtInterfaceL(AContextStore::KInterfaceId));
       
   534     	}
       
   535 
       
   536     //Check if there is any point in sending Error Recovery Request
       
   537     if (intf==NULL || !intf->IsStored() || !iContext.Node().ControlProvider())
       
   538         {
       
   539         __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ERROR: ASendErrorRecoveryReq::DoL - KErrNotSupported")));
       
   540         iContext.iNodeActivity->SetIdle();
       
   541         aa->SetError(errmsg.iValue);
       
   542     	aa->SetIdle();
       
   543     	return;
       
   544         }
       
   545 
       
   546 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   547     CoreActivities::CErrorActivity& activity = static_cast<CoreActivities::CErrorActivity&>(*iContext.iNodeActivity);
       
   548     __ASSERT_DEBUG(activity.iErroredActivityId==MeshMachine::KActivityNull, User::Panic(KSpecAssert_ESockCrStaCPRAC, 4));
       
   549 	// Save a reference to the activity and a point
       
   550 	// Each time we use the activity, query it from the node, because the activity may have gone away (originator left node etc)
       
   551 	activity.iErroredActivityId = aa->ActivityId();
       
   552 
       
   553     activity.SetError(errmsg.iValue);
       
   554     activity.iMessageId = errmsg.iMsgId;
       
   555 
       
   556     TErrContext ctx(iContext.NodeId(), errmsg.iMsgId, aa->ActivitySigId(), TStateChange(0, errmsg.iValue));
       
   557 	TEErrorRecovery::TErrorRecoveryRequest msg(ctx);
       
   558 
       
   559     activity.PostRequestTo(
       
   560     	*iContext.Node().ControlProvider(),//ControlProvider() verified above
       
   561     	TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef()
       
   562     	);
       
   563 
       
   564     //The original activiy might have set 'sent to', but that's surely
       
   565     //not meaningful anymore (we've just received a response from that 'sent to').
       
   566     //We could have pretended that the orginal activity knows it's sent
       
   567     //error recovery to the control provider but it's best just to clear
       
   568     //'sent to' (and handle TCancel from here (CErrorActivity::Next()).
       
   569     aa->ClearPostedTo();
       
   570     }
       
   571 
       
   572 EXPORT_DEFINE_SMELEMENT(CErrorActivity::TDoErrorRecovery, NetStateMachine::MStateTransition, CErrorActivity::TContext)
       
   573 EXPORT_C void CErrorActivity::TDoErrorRecovery::DoL()
       
   574     {
       
   575     __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   576     CoreActivities::CErrorActivity* act = static_cast<CoreActivities::CErrorActivity*>(iContext.iNodeActivity);
       
   577 	CNodeActivityBase* a = iContext.Node().FindActivityById(act->iErroredActivityId);
       
   578     if (a == NULL)
       
   579 		{
       
   580 		iContext.iNodeActivity->SetIdle();
       
   581 		return;
       
   582 		}
       
   583 
       
   584 	if (iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>())
       
   585 		{
       
   586 		TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse;
       
   587 		if (resp.iAction == TErrResponse::ERetry)
       
   588 			{ //rerun current transition
       
   589 			__CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to retry")));
       
   590 			__ASSERT_DEBUG(a->SupportsExtInterface(AContextStore::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
   591 
       
   592 			AContextStore* intf = reinterpret_cast<AContextStore*>(a->FetchExtInterfaceL(AContextStore::KInterfaceId));
       
   593 			__ASSERT_DEBUG(intf->IsStored(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 5));
       
   594 			intf->Retry(*a,iContext);
       
   595 			if (iContext.iReturn == KErrNone)
       
   596 				{ //retry succeded
       
   597 				act->SetError(KErrNone);
       
   598 				}
       
   599 			//if Retry had failed, then the d'tor of act will raise the error on
       
   600 			//and terminate act->iActivity,
       
   601 			}
       
   602 		else if (resp.iAction == TErrResponse::EPropagate)
       
   603 			{ //set new error values and fall through
       
   604 			__CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to propagate the error")));
       
   605 			act->iMessageId = resp.iMessageId;
       
   606 			a->SetError(resp.iError);
       
   607 			}
       
   608 		else //if (resp.iAction == TErrResponse::EIgnore)
       
   609 			{
       
   610 			__CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag,
       
   611 			_L8("WARNING: ADoErrorRecovery::DoL() - instructed to ignore the error!")));
       
   612 			}
       
   613 		}
       
   614 	}
       
   615 
       
   616 
       
   617 //-=========================================================
       
   618 //
       
   619 //Destroy Activity - will delete the node when destructed
       
   620 //
       
   621 //-=========================================================
       
   622 
       
   623 EXPORT_C MeshMachine::CNodeActivityBase* CDestroyActivity::New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   624 	{
       
   625 	TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CDestroyActivity));
       
   626 	CDestroyActivity* self = new (space) CDestroyActivity(aActivitySig, aNode);
       
   627 	self->InsertPreallocatedDestroyActivity(); //Destructing preallocated activity
       
   628 	return self;
       
   629 	}
       
   630 
       
   631 CDestroyActivity::CDestroyActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   632 :	CNodeRetryActivity(aActivitySig, aNode),
       
   633 	APreallocatedOriginators<1>(iOriginators)
       
   634 	{
       
   635 	//Mark the provider for deletion, so that it's not served by the factory from now on.
       
   636     static_cast<ESock::CMMCommsProviderBase&>(iNode).MarkMeForDeletion();
       
   637 	}
       
   638 
       
   639 void CDestroyActivity::Destroy()
       
   640 	{
       
   641 	ReturnPreallocatedSpace(this);
       
   642 	this->~CDestroyActivity(); //Run the destructor
       
   643 
       
   644 	//Delete the provider.
       
   645 	static_cast<ESock::CMMCommsProviderBase&>(iNode).DeleteMeNow();
       
   646 	}
       
   647 
       
   648 TBool CDestroyActivity::Next(TNodeContextBase& aContext)
       
   649     {
       
   650     if (aContext.iMessage.IsMessage<TEBase::TCancel>())
       
   651         {  
       
   652         return ETrue;
       
   653         }
       
   654     else
       
   655         return CNodeActivityBase::Next(aContext);
       
   656     }
       
   657 
       
   658 EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
       
   659 EXPORT_C TInt CDestroyActivity::TNoTagOrNoTagBackwards::TransitionTag()
       
   660     {
       
   661 	if (iContext.iMessage.IsMessage<TEChild::TLeft>())
       
   662 		{
       
   663 		TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData|TCFClientType::ECtrl));
       
   664 		__ASSERT_DEBUG(iter[0], User::Panic(KSpecAssert_ESockCrStaCPRAC, 7)); //One leaving client must still be there.
       
   665 		return iter[1] == NULL ?  MeshMachine::KNoTag : MeshMachine::KNoTag | NetStateMachine::EBackward;
       
   666 		}
       
   667 	else if (iContext.iMessage.IsMessage<TEPeer::TLeaveComplete>())
       
   668 		{
       
   669 		__ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl|TCFClientType::EData))==NULL,
       
   670 		User::Panic(KCorePrPanic, KPanicClientsStillPresent));
       
   671 		if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider))==NULL)
       
   672 			{
       
   673 			return NetStateMachine::EForward | MeshMachine::KNoTag;
       
   674 			}
       
   675 		return NetStateMachine::EBackward | MeshMachine::KNoTag; //Loop back to the same triple (& remove the peer)
       
   676 		}
       
   677 	__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCrStaCPRAC, 8));
       
   678 	return KNoTag;
       
   679 	}
       
   680 
       
   681 EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, NetStateMachine::MStateTransition, PRStates::TContext)
       
   682 EXPORT_C void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::DoL()
       
   683 	{
       
   684 	if (iContext.iMessage.IsMessage<TEChild::TLeft>())
       
   685 		{
       
   686 		ProcessClientLeaveL();
       
   687 		}
       
   688 	else
       
   689 		{
       
   690 		MakeClientsLeaveL();
       
   691 		}
       
   692 	}
       
   693 
       
   694 void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::MakeClientsLeaveL()
       
   695     {
       
   696     __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl))==NULL,
       
   697     	User::Panic(KCorePrPanic, KPanicClientsStillPresent));
       
   698 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   699 	iContext.iNodeActivity->ClearPostedTo();
       
   700 
       
   701 	//MZTODO: this asserion may need to be changed since TDestroy can
       
   702 	//come while data client is active etc.
       
   703     __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EActive|TCFClientType::EActivating|TCFClientType::EStarting|TCFClientType::EStarted))==NULL,
       
   704     	User::Panic(KCorePrPanic, KPanicClientsStillPresent));
       
   705 
       
   706    	TClientIter<TDefaultClientMatchPolicy> dciter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData),	TClientType(0, TCFClientType::ELeaving));
       
   707    	RNodeInterface* dc = NULL;
       
   708     while ((dc = dciter[0]) != NULL) //always inspect the first elem as we're invalidating the iterator with each hit.
       
   709         {
       
   710 		dc->PostMessage(iContext.NodeId(), TEChild::TDestroy().CRef());
       
   711 		dc->SetFlags(TCFClientType::ELeaving);
       
   712         }
       
   713 	}
       
   714 
       
   715 void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::ProcessClientLeaveL()
       
   716     {
       
   717     CDestroyActivity::TProcessClientLeave processClientLeave(iContext);
       
   718     processClientLeave.DoL();
       
   719     }
       
   720 
       
   721 
       
   722 //-=========================================================
       
   723 //
       
   724 //Loppin Activity
       
   725 //
       
   726 //-=========================================================
       
   727 EXPORT_C ACountLoopActivity::~ACountLoopActivity()
       
   728     {
       
   729     }
       
   730 
       
   731 
       
   732 EXPORT_C MeshMachine::CNodeActivityBase* CCountLoopActivityBase::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   733     {
       
   734     return new (ELeave) CCountLoopActivityBase(aActivitySig, aNode);
       
   735     }
       
   736 
       
   737 EXPORT_C CCountLoopActivityBase::CCountLoopActivityBase(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   738 :	MeshMachine::CNodeActivityBase(aActivitySig, aNode),
       
   739     TIfStaticFetcherNearestInHierarchy(this)
       
   740     {
       
   741 	}
       
   742 
       
   743 EXPORT_C CCountLoopActivityBase::~CCountLoopActivityBase()
       
   744     {
       
   745     }
       
   746 
       
   747 EXPORT_DEFINE_SMELEMENT(ACountLoopActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
       
   748 EXPORT_C TInt ACountLoopActivity::TNoTagOrNoTagBackwards::TransitionTag()
       
   749 	{
       
   750 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   751 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ACountLoopActivity::KInterfaceId),User::Panic(KCorePrPanic, KPanicInterfaceNotSupported));
       
   752 	ACountLoopActivity* countLoopActivity = static_cast<ACountLoopActivity*>(iContext.iNodeActivity->FetchExtInterface(ACountLoopActivity::KInterfaceId));
       
   753  	if (countLoopActivity->DecCount() > 0)
       
   754  		{
       
   755         return KNoTag | NetStateMachine::EBackward;
       
   756      	}
       
   757  	return KNoTag | NetStateMachine::EForward;
       
   758  	}
       
   759 
       
   760 
       
   761 
       
   762 
       
   763 
       
   764 //-=========================================================
       
   765 //
       
   766 //
       
   767 //Binding Activity
       
   768 //
       
   769 //
       
   770 //-=========================================================
       
   771 EXPORT_C ABindingActivity::~ABindingActivity()
       
   772 	{
       
   773     //Handle premature termination of the ABindingActivity object
       
   774     //by responding to the originator
       
   775 	//If the originator has not been replied to yet, reply now with an error code
       
   776 	if (IsBinding())
       
   777 		{
       
   778 		ReplyToOriginator(KErrAbort);
       
   779 		}
       
   780 	}
       
   781 
       
   782 EXPORT_C void ABindingActivity::StoreOriginator(const TRuntimeCtxId& aNodeCtxId)
       
   783     {
       
   784     //Check if the originator wasn't set before. If it was, it must be replied to before storing ths new one.
       
   785     __ASSERT_DEBUG(iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 9));
       
   786     iOriginator = aNodeCtxId;
       
   787     }
       
   788 
       
   789 EXPORT_C void ABindingActivity::ReplyToOriginator(TInt aError)
       
   790     {
       
   791     //NOTE: Please do not make this diagnostic panic conditional.
       
   792     //Please allow it to server everyone equally.
       
   793     //Please handle the error conditions properly so that you obey this API's semantics.
       
   794     //If you are not providing a clean error handling solution for your activity,
       
   795     //please use IsBinding() before calling this API!
       
   796     __ASSERT_DEBUG(!iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 10)); //The iOriginator must be set.
       
   797     RClientInterface::OpenPostMessageClose(iOurNode, iOriginator, TCFDataClient::TBindToComplete(aError).CRef());
       
   798     iOriginator.SetNull();
       
   799     }
       
   800 
       
   801 EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CoreStates::TContext)
       
   802 EXPORT_C void ABindingActivity::TSendBindToComplete::DoL()
       
   803 	{
       
   804     __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   805     __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 11));
       
   806     ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId));
       
   807     bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error());
       
   808 	}
       
   809 
       
   810 EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToCompleteIfExpected, NetStateMachine::MStateTransition, CoreStates::TContext)
       
   811 EXPORT_C void ABindingActivity::TSendBindToCompleteIfExpected::DoL()
       
   812 	{
       
   813     __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   814     __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 12));
       
   815     ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId));
       
   816     if (bindingActivity->IsBinding())
       
   817 	    {
       
   818 		bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error());
       
   819 	    }
       
   820 	}
       
   821 
       
   822 void ABindingActivity::FinalReplyToOriginator(TInt aError)
       
   823 /**
       
   824 Intended to be called from derived class destructors to arrange for a TBindToComplete reply to be sent
       
   825 before any other messages in those derived class destructors (for example TDestroy).
       
   826 */
       
   827 	{
       
   828 	if (IsBinding())
       
   829 		{
       
   830 		ReplyToOriginator(aError);
       
   831 		// Ensure that we don't send another reply in ~ABindingActivity.
       
   832 		iOriginator = Messages::TNodeCtxId();
       
   833 		}
       
   834 	}
       
   835 
       
   836 } // CoreActivities
       
   837 
       
   838 
       
   839 namespace PRActivities
       
   840 {
       
   841 DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesPR)
       
   842 	ACTIVITY_MAP_ENTRY(PRDataClientJoinActivity, PRDataClientJoin)
       
   843 	ACTIVITY_MAP_ENTRY(PRControlClientJoinActivity, PRControlClientJoin)
       
   844 	ACTIVITY_MAP_ENTRY(PRClientLeaveActivity, PRClientLeave)
       
   845 	ACTIVITY_MAP_ENTRY(PRForwardStateChangeActivity, PRForwardStateChange)
       
   846 	ACTIVITY_MAP_ENTRY(PRBindToActivity, PRBindTo)
       
   847 ACTIVITY_MAP_END_BASE(CoreActivities,coreActivitiesAll)
       
   848 
       
   849 //Activity Map provided by CorePr to be used by SCprs.
       
   850 //(it is further extended in CoreSCpr).
       
   851 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesSCpr)
       
   852 	ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
       
   853     ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
       
   854     ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
       
   855 	ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
       
   856 	ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
       
   857 	ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
       
   858 	ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
       
   859 	ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
       
   860 	ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown)
       
   861 	ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro
       
   862 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   863 	ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams)
       
   864 	ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams)
       
   865 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   866     ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
       
   867 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
       
   868 
       
   869 //Activity Map provided by CorePr to be used by Cprs.
       
   870 //(it is further extended in CoreCpr).
       
   871 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesCpr)
       
   872 	ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
       
   873     ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
       
   874     ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
       
   875 	ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
       
   876 	ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
       
   877 	ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
       
   878 	ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
       
   879 	ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
       
   880 	ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown)
       
   881 	ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro
       
   882     ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange)
       
   883 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   884     ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams)
       
   885     ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams)
       
   886 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   887     ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
       
   888 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
       
   889 
       
   890 //Activity Map provided by CorePr to be used by MCprs.
       
   891 //(it is further extended in CoreMCpr).
       
   892 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesMCpr)
       
   893 	ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
       
   894 	ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
       
   895     ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange)
       
   896     ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
       
   897 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
       
   898 
       
   899 //Activity Map provided by CorePr to be used by TMs.
       
   900 //(it is further extended in CoreTM).
       
   901 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesTM)
       
   902 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
       
   903 
       
   904 
       
   905 
       
   906 
       
   907 //-=========================================================
       
   908 //
       
   909 //CBindToActivity
       
   910 //
       
   911 //-=========================================================
       
   912 EXPORT_C CBindToActivity::CBindToActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TInt aNextActivityCount)
       
   913 	:	MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aNextActivityCount),
       
   914 		CoreActivities::ABindingActivity(aNode.Id()),
       
   915 	    TIfStaticFetcherNearestInHierarchy(this)
       
   916 		{
       
   917 		}
       
   918 
       
   919 EXPORT_C MeshMachine::CNodeActivityBase* CBindToActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   920     {
       
   921      //there can be only one BindTo activity running at a time.
       
   922     TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
   923 	__ASSERT_DEBUG(c == 1,User::Panic(KCorePrPanic, KPanicPeerMisbehaving));
       
   924     if (c > 1)
       
   925         {
       
   926         User::Leave(KErrInUse);
       
   927         }
       
   928     return new (ELeave) CBindToActivity(aActivitySig, aNode, c);
       
   929     }
       
   930 
       
   931 EXPORT_C CBindToActivity::~CBindToActivity()
       
   932     {
       
   933     //If the activity is aborted then no cleanup will be performed (the destroy activity will do
       
   934     //that for us) so we should not assert that iSuccessfulDataClients is empty or iNewServiceProvider
       
   935     //is null.
       
   936 
       
   937     //CBindToActivity::TCommit or CBindToActivity::TCancel should have been executed
       
   938     //and rendered iSuccessfulDataClients empty.
       
   939 	//__ASSERT_DEBUG(iSuccessfulDataClients.Count() == 0, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
   940 
       
   941 	//CBindToActivity::iNewServiceProvider should have been cleared by CBindToActivity::TCommit or CBindToActivity::TCancel
       
   942 	//__ASSERT_DEBUG(iNewServiceProvider == NULL, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
   943 
       
   944     iSuccessfulDataClients.Close();
       
   945     }
       
   946 
       
   947 Messages::RNodeInterface* CBindToActivity::NextDataClient()
       
   948 	{
       
   949 	TClientIter<TDefaultClientMatchPolicy> iter = iNode.GetClientIter<TDefaultClientMatchPolicy>(
       
   950 												/*include*/TClientType(TCFClientType::EData),
       
   951 												/*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint));
       
   952     iCurrentDataClient = iter++;
       
   953     while (iCurrentDataClient && (iSuccessfulDataClients.Find(iCurrentDataClient) != KErrNotFound))
       
   954     	{
       
   955         iCurrentDataClient = iter++;
       
   956         };
       
   957     return iCurrentDataClient;
       
   958 	}
       
   959 
       
   960 TBool CBindToActivity::DataClientsAutocommit()
       
   961  	{
       
   962  	TInt nonLeavingDataClients = iNode.CountClients<TDefaultClientMatchPolicy>(
       
   963  								/*include*/TClientType(TCFClientType::EData),
       
   964  								/*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint));
       
   965  	return nonLeavingDataClients <=1 && IsAutocommit();
       
   966  	}
       
   967 
       
   968 
       
   969 void CBindToActivity::AddClientAsSuccessfulL(Messages::RNodeInterface* aDataClient)
       
   970 	{
       
   971 	__ASSERT_DEBUG(aDataClient, User::Panic(KCorePrPanic, KPanicDataClient));
       
   972 	__ASSERT_DEBUG(iSuccessfulDataClients.Find(aDataClient) == KErrNotFound, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
   973 	iSuccessfulDataClients.Append(aDataClient);
       
   974 	}
       
   975 
       
   976 void CBindToActivity::RemoveClientFromSuccessful(Messages::RNodeInterface* aDataClient)
       
   977 	{
       
   978 	TInt index = iSuccessfulDataClients.Find(aDataClient);
       
   979 	__ASSERT_DEBUG(index >= 0, User::Panic(KCorePrPanic, KPanicDataClient));
       
   980 	iSuccessfulDataClients.Remove(index);
       
   981 	}
       
   982 
       
   983 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendControlClientJoinRequest, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
   984 void CBindToActivity::TSendControlClientJoinRequest::DoL()
       
   985     {
       
   986 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   987     CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
   988 	const TCFDataClient::TBindTo& bindToMsg(message_cast<const TCFDataClient::TBindTo>(iContext.iMessage));
       
   989 
       
   990 	__ASSERT_DEBUG(!bindToMsg.iNodeId.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
   991     RNodeInterface* newServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId,
       
   992                             TClientType(TCFClientType::EServProvider, TCFClientType::EActivating));
       
   993     __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
   994     activity.iNewServiceProvider = bindToMsg.iNodeId;
       
   995     //Join the new service provider
       
   996     iContext.Activity()->PostRequestTo(*newServiceProvider,
       
   997                             TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
       
   998     }
       
   999 
       
  1000 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TAwaitingBindToCompleteOrError, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
       
  1001 TBool CBindToActivity::TAwaitingBindToCompleteOrError::Accept()
       
  1002     {
       
  1003 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1004     CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1005     if (CoreNetStates::TAwaitingBindToComplete(iContext).Accept())
       
  1006 	    {
       
  1007 	    if (activity.IsBinding())
       
  1008 	    	{
       
  1009 	    	//Activity is binding (i.e.: we havent received TBindToComplete as a response
       
  1010 	    	//to null-carrying TBindTo.
       
  1011 		    activity.ReplyToOriginator(KErrNone);
       
  1012 	    	}
       
  1013 	    activity.ResetCurrentDataClient();
       
  1014 	    return ETrue;
       
  1015 	    }
       
  1016     else if (iContext.iMessage.IsMessage<TEBase::TError>())
       
  1017     	{
       
  1018 	    activity.ReplyToOriginator(message_cast<TEBase::TError>(iContext.iMessage).iValue);
       
  1019     	activity.RemoveClientFromSuccessful(activity.CurrentDataClient());
       
  1020     	activity.ResetCurrentDataClient();
       
  1021     	return ETrue;
       
  1022     	}
       
  1023 	return EFalse;
       
  1024     }
       
  1025 
       
  1026 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrDataClientReady, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1027 TInt CBindToActivity::TNoTagOrDataClientReady::TransitionTag()
       
  1028     {
       
  1029     //Any non-leaving dataclients already present?
       
  1030     if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(
       
  1031     	/*include*/TClientType(TCFClientType::EData),
       
  1032     	/*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint)))
       
  1033 	    {
       
  1034 	    return KDataClientReady;
       
  1035 	    }
       
  1036 	return KNoTag;
       
  1037     }
       
  1038 
       
  1039 
       
  1040 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TRequestCommsBinder, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1041 void CBindToActivity::TRequestCommsBinder::DoL()
       
  1042     {
       
  1043 	__ASSERT_DEBUG(iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)),User::Panic(KCorePrPanic, KPanicDataClient));
       
  1044 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1045   	CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1046 
       
  1047   	//The service provider has been joined already and must be found here
       
  1048     __ASSERT_DEBUG(!activity.iNewServiceProvider.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
  1049     RNodeInterface* newServiceProvider = iContext.Node().FindClient(activity.iNewServiceProvider);
       
  1050     __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
  1051     //We must not be in this transition if dc was not found
       
  1052     __ASSERT_DEBUG(activity.CurrentDataClient(), User::Panic(KCorePrPanic, KPanicDataClient));
       
  1053 
       
  1054     // Also if it is not so common to have multiple DataClient (except
       
  1055     // 	for the relation "SCPR<-CPR"), there are situation where it happens
       
  1056     // 	and where only one of them is marked as Default.
       
  1057     // So, we check if this is the case and, in case the
       
  1058     //	Originator of this activity is NOT a Default one, send ECreateNew.
       
  1059 
       
  1060     // If the Current DC is marked as Default, we ask to the lower layer
       
  1061     //	to "AttachToDefault". If it is not, we ask "CreateNew".
       
  1062     TInt subConnOpenType = (activity.CurrentDataClient()->Flags() & TCFClientType::EDefault) ?
       
  1063    			TSubConnOpen::EAttachToDefault : TSubConnOpen::ECreateNew;
       
  1064 
       
  1065     // --- WORKAROUND START ---
       
  1066     // [399TODO] There are situation were we don't have any DataClient marked
       
  1067     //	as Default, but, asking for ECreateNew, the lower layer doesn't
       
  1068     //	manage the request very well.
       
  1069     //	This is a WORKAROUND and need fixing (see DEF113154).
       
  1070     //	In the meanwhile, we count the number of "DefaultDataClient" and,
       
  1071     //	if the result is "0", we ask the lower layer "AttachToDefault"
       
  1072     TInt numberOfDefaultDataClient = iContext.Node().CountClients<TDefaultClientMatchPolicy>(
       
  1073     		TClientType(TCFClientType::EData, TCFClientType::EDefault)
       
  1074     		);
       
  1075     if (numberOfDefaultDataClient == 0)
       
  1076     	{
       
  1077     	subConnOpenType = TSubConnOpen::EAttachToDefault;
       
  1078     	}
       
  1079     // --- WORKAROUND END ---
       
  1080 
       
  1081     // Send "TCommsBinderRequest" to the Current ServiceProvider
       
  1082    	activity.PostRequestTo(
       
  1083    			*newServiceProvider,
       
  1084    			TCFServiceProvider::TCommsBinderRequest(subConnOpenType).CRef()
       
  1085    			);
       
  1086     }
       
  1087 
       
  1088 
       
  1089 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCreateDataClient, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1090 void CBindToActivity::TCreateDataClient::DoL()
       
  1091     {
       
  1092 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1093 
       
  1094 	IssuePeerCreationRequestL ();
       
  1095     }
       
  1096 
       
  1097 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindTo, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1098 void CBindToActivity::TSendBindTo::DoL()
       
  1099     {
       
  1100 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1101 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1102 
       
  1103 	//Provisionally stash the current dataclient as successful. If it fails to bind, we'll unstash it
       
  1104 	//We're doing this now, as stashing may fail and we don't want that to be the sole reason for
       
  1105 	//unrolling.
       
  1106 	bindToActivity.AddClientAsSuccessfulL(bindToActivity.CurrentDataClient());
       
  1107 
       
  1108 	TCFServiceProvider::TCommsBinderResponse* commsBinderResponse = message_cast<TCFServiceProvider::TCommsBinderResponse>(&iContext.iMessage);
       
  1109 	Messages::TNodeId commsBinder = commsBinderResponse ? commsBinderResponse->iNodeId : Messages::TNodeId::NullId();
       
  1110 
       
  1111 	bindToActivity.PostRequestTo(*bindToActivity.CurrentDataClient(),
       
  1112 			TCFDataClient::TBindTo(commsBinder, !bindToActivity.DataClientsAutocommit()).CRef());
       
  1113     }
       
  1114 
       
  1115 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1116 void CBindToActivity::TSendBindToComplete::DoL()
       
  1117     {
       
  1118 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1119 	iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete().CRef());
       
  1120     }
       
  1121 
       
  1122 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrCommit, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1123 TInt CBindToActivity::TNoTagOrCommit::TransitionTag()
       
  1124     {
       
  1125 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1126 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1127 	if (bindToActivity.IsAutocommit())
       
  1128 		{
       
  1129 		return KCommit;
       
  1130 		}
       
  1131 	return KNoTag;
       
  1132     }
       
  1133 
       
  1134 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1135 EXPORT_C TInt CBindToActivity::TNoTagOrBindToComplete::TransitionTag()
       
  1136     {
       
  1137     TCFFactory::TPeerFoundOrCreated& dcJoined = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
       
  1138 
       
  1139     if (dcJoined.iNodeId.IsNull())
       
  1140     	{
       
  1141     	//Factory decided not to create a dataclient;
       
  1142     	return KBindToComplete;
       
  1143     	}
       
  1144 
       
  1145     //factory created a new citizen.
       
  1146     return KNoTag;
       
  1147     }
       
  1148 
       
  1149 
       
  1150 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReady, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1151 TInt CBindToActivity::TNoTagOrBearerReady::TransitionTag()
       
  1152     {
       
  1153 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1154 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1155     TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(iContext.iMessage);
       
  1156     bindToActivity.SetAutocommit(!bindToReq.iValue);
       
  1157 
       
  1158     if (bindToReq.iNodeId.IsNull())
       
  1159     	//received a null service provider, the node is at the stack's bottom.
       
  1160         {
       
  1161         return KBearerReady;
       
  1162         }
       
  1163 
       
  1164     RNodeInterface* sp = iContext.Node().ServiceProvider();
       
  1165     if (sp && bindToReq.iNodeId == sp->RecipientId())
       
  1166         {
       
  1167         //received the same service provider, it's already bound to.
       
  1168         bindToActivity.iNewServiceProvider = sp->RecipientId();
       
  1169 		return KBearerReady;
       
  1170 		}
       
  1171     RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToReq.iNodeId);
       
  1172 	if (newServiceProvider)
       
  1173 		{
       
  1174 		__ASSERT_DEBUG(newServiceProvider->Type() == TCFClientType::EServProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
  1175 		//Ok, we've received a TBindTo holding a service provider that we already know of and that is not
       
  1176 		//our current service provider. We're going to assume this node tolerates multiple service providers (like MCPRs do).
       
  1177 		//the current service provider will be swapped, but won't be dropped.
       
  1178 		bindToActivity.iNewServiceProvider = bindToReq.iNodeId;
       
  1179 		newServiceProvider->SetFlags(TCFClientType::EActivating);
       
  1180 		bindToActivity.SetDontLeaveServiceProvider();
       
  1181 		return KBearerReady;
       
  1182 		}
       
  1183 	else
       
  1184 	    {
       
  1185         bindToActivity.iNewServiceProvider = TNodeId::NullId();
       
  1186 	    }
       
  1187 	//The node received a new service provider...
       
  1188 	return KNoTag;
       
  1189     }
       
  1190 
       
  1191 
       
  1192 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReadyOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1193 TInt CBindToActivity::TNoTagOrBearerReadyOrBindToComplete::TransitionTag()
       
  1194 	{
       
  1195 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1196 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1197 
       
  1198     if (!bindToActivity.NextDataClient())
       
  1199     	{
       
  1200     	//No more dataclients to bind
       
  1201     	return KBindToComplete;
       
  1202     	}
       
  1203 
       
  1204     if (bindToActivity.iNewServiceProvider.IsNull())
       
  1205     	{
       
  1206     	//There is no service provider (new or old) below us.
       
  1207     	return KBearerReady;
       
  1208     	}
       
  1209 
       
  1210     return KNoTag;
       
  1211     }
       
  1212 
       
  1213 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCommit, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1214 void CBindToActivity::TCommit::DoL()
       
  1215     {
       
  1216 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1217 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1218 
       
  1219 	TInt count = bindToActivity.DataClientsAutocommit() ? 0 : bindToActivity.iSuccessfulDataClients.Count();
       
  1220     while (count )
       
  1221     	{
       
  1222     	bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TCFDataClient::TCommitBindTo().CRef());
       
  1223         };
       
  1224     bindToActivity.iSuccessfulDataClients.Reset();
       
  1225     RNodeInterface* sp = iContext.Node().ServiceProvider();
       
  1226 
       
  1227     if (sp && sp->RecipientId() != bindToActivity.iNewServiceProvider)
       
  1228     	{
       
  1229     	if (bindToActivity.ShouldLeaveServiceProvider())
       
  1230     		{
       
  1231 	    	bindToActivity.PostRequestTo(*sp, TEPeer::TLeaveRequest().CRef());
       
  1232 	    	sp->SetFlags(TCFClientType::ELeaving);
       
  1233     		}
       
  1234         else
       
  1235         	{
       
  1236         	//Didn't leave, no need for waiting for TLeaveComplete;
       
  1237         	bindToActivity.SetIdle();
       
  1238         	}
       
  1239     	sp->ClearFlags(TCFClientType::EActive);
       
  1240     	}
       
  1241     else
       
  1242     	{
       
  1243     	//Didn't leave, no need for waiting for TLeaveComplete;
       
  1244     	bindToActivity.SetIdle();
       
  1245     	}
       
  1246 
       
  1247     if (!bindToActivity.iNewServiceProvider.IsNull() && (sp == NULL || sp->RecipientId() != bindToActivity.iNewServiceProvider))
       
  1248         {
       
  1249         RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
       
  1250         if (newServiceProvider)
       
  1251             {
       
  1252             __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
  1253             newServiceProvider->ClearFlags(TCFClientType::EActivating);
       
  1254             newServiceProvider->SetFlags(TCFClientType::EActive);
       
  1255             // Note: iContext.Node().ServiceProvider() must be re-evaluated in the ASSERT below (i.e. don't use any previously cached value).
       
  1256             __ASSERT_DEBUG(iContext.Node().ServiceProvider() == newServiceProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
  1257             }
       
  1258         }
       
  1259     bindToActivity.iNewServiceProvider = TNodeId::NullId();
       
  1260     }
       
  1261 
       
  1262 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCancel, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1263 void CBindToActivity::TCancel::DoL()
       
  1264     {
       
  1265 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1266 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1267 	TInt count = bindToActivity.iSuccessfulDataClients.Count();
       
  1268     while (count )
       
  1269     	{
       
  1270     	bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TEBase::TCancel().CRef());
       
  1271         };
       
  1272     bindToActivity.iSuccessfulDataClients.Reset();
       
  1273 
       
  1274 	TBool setIdle = ETrue;
       
  1275     if (!bindToActivity.iNewServiceProvider.IsNull())
       
  1276         {
       
  1277         RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
       
  1278         if (newServiceProvider && newServiceProvider != iContext.Node().ServiceProvider())
       
  1279             {
       
  1280             __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
  1281             newServiceProvider->ClearFlags(TCFClientType::EActivating);
       
  1282             if (bindToActivity.ShouldLeaveServiceProvider())
       
  1283                 {
       
  1284                 bindToActivity.PostRequestTo(*newServiceProvider, TEPeer::TLeaveRequest().CRef());
       
  1285                 newServiceProvider->SetFlags(TCFClientType::ELeaving);
       
  1286                 setIdle = EFalse;
       
  1287                 }
       
  1288             }
       
  1289         }
       
  1290 
       
  1291     if (setIdle)
       
  1292         {
       
  1293         bindToActivity.SetIdle();
       
  1294         }
       
  1295     bindToActivity.iNewServiceProvider = TNodeId::NullId();
       
  1296     }
       
  1297 
       
  1298 
       
  1299 //-=========================================================
       
  1300 //
       
  1301 //Rejoin DataClient Activity
       
  1302 //
       
  1303 //-=========================================================
       
  1304 EXPORT_C MeshMachine::CNodeActivityBase* CRejoinDataClientActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1305     {
       
  1306 	TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
  1307     return new(ELeave)CRejoinDataClientActivity(aActivitySig, c, aNode);
       
  1308     }
       
  1309 
       
  1310 CRejoinDataClientActivity::~CRejoinDataClientActivity()
       
  1311     {
       
  1312     if ( iDataClients.Count() )
       
  1313         {
       
  1314         if (Error() != KErrNone)
       
  1315             {
       
  1316             //An error has occured when processing rejoin as the activity hasn't been properly wrapped
       
  1317             //up. This error must have happened before any of the clients have been added to the new
       
  1318             //owner as such addition must either collectively succeed or collectively fail. Reinstall
       
  1319             //clients in at the current owner.
       
  1320             for (TInt i = 0; i < iDataClients.Count(); i++)
       
  1321                 {
       
  1322                 if (!(iDataClients[i].iDataClient.Flags() & TCFClientType::EActive))
       
  1323                     {
       
  1324 #ifndef __GCCXML__
       
  1325 					//If the dataclient managed to report idle in the mean time, have him destroyed
       
  1326                     RClientInterface::OpenPostMessageClose(iNode.Id(), iDataClients[i].iDataClient.RecipientId(), TEChild::TDestroy().CRef());
       
  1327 #endif
       
  1328                     }
       
  1329                 iDataClients[i].iDataClient.ClearFlags(TCFClientType::EActivating);
       
  1330 #ifndef __GCCXML__
       
  1331                 //Simulate client leaving on the new owner.
       
  1332                 RClientInterface::OpenPostMessageClose(iDataClients[i].iDataClient.RecipientId(), iDataClients[i].iNewOwner,
       
  1333                 	TEChild::TLeft().CRef());
       
  1334 #endif
       
  1335                 }
       
  1336             }
       
  1337         else
       
  1338             {
       
  1339             //All clear. Remove the clients for good.
       
  1340             for (TInt i = 0; i < iDataClients.Count(); i++)
       
  1341                 {
       
  1342                 iNode.RemoveClient(iDataClients[i].iDataClient.RecipientId());
       
  1343                 }
       
  1344             }
       
  1345         }
       
  1346     iDataClients.Reset();
       
  1347     }
       
  1348 
       
  1349 
       
  1350 void CRejoinDataClientActivity::TCFDataClientJoiningRequest::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
       
  1351     {
       
  1352     const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient);  //This message type operates on nodes
       
  1353 	MeshMachine::AMMNodeBase* nodeBase = reinterpret_cast<MeshMachine::AMMNodeBase*>(nodeId.Node().FetchNodeInterfaceL(AMMNodeBase::KInterfaceId));
       
  1354     RNodeInterface* client = NULL;
       
  1355     client = nodeBase->AddClientL(iDataClient, iDataClientType);
       
  1356     client->SetFlags(TCFClientType::EJoining|TCFClientType::EStarted);
       
  1357     RClientInterface::OpenPostMessageClose(nodeId, aSender, TCFPeer::TJoinComplete().CRef());
       
  1358     }
       
  1359 
       
  1360 
       
  1361 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TAwaitingJoinComplete, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
       
  1362 TBool CRejoinDataClientActivity::TAwaitingJoinComplete::Accept()
       
  1363     {
       
  1364 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 13));
       
  1365 	if (iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>())
       
  1366     	{
       
  1367     	return ETrue;
       
  1368     	}
       
  1369     else if (iContext.iMessage.IsMessage<TEBase::TError>())
       
  1370         {
       
  1371 	    iContext.iNodeActivity->SetError(message_cast<TEBase::TError>(iContext.iMessage).iValue);
       
  1372 	    iContext.iNodeActivity->SetIdle();
       
  1373 	    iContext.iMessage.ClearMessageId();
       
  1374         }
       
  1375 	return EFalse;
       
  1376     }
       
  1377 
       
  1378 
       
  1379 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinDataClient, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext)
       
  1380 EXPORT_C void CRejoinDataClientActivity::TRejoinDataClient::DoL()
       
  1381     {
       
  1382 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 14));
       
  1383 	CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity);
       
  1384 
       
  1385 	TCFRejoiningProvider::TRejoinDataClientRequest& rejoinDCMsg = message_cast<TCFRejoiningProvider::TRejoinDataClientRequest>(iContext.iMessage);
       
  1386 	RNodeInterface* subject = iContext.Node().FindClient(rejoinDCMsg.iNodeId1);
       
  1387 	if (NULL == subject //client not found
       
  1388 	    || subject->Flags() & TCFClientType::ELeaving //client leaving/gone
       
  1389 	    || !(subject->Flags() & TCFClientType::EActive)) //client reported idle or never bound to
       
  1390     	{
       
  1391     	User::Leave(KErrNotFound);
       
  1392     	}
       
  1393     if (subject->Flags() & TCFClientType::EActivating) //client requested by someone
       
  1394         {
       
  1395     	User::Leave(KErrInUse);
       
  1396         }
       
  1397 
       
  1398     rejoinActivity->iDataClients.AppendL(TMigrationPairs(*subject, rejoinDCMsg.iNodeId2));
       
  1399 
       
  1400 	CRejoinDataClientActivity::TCFDataClientJoiningRequest msg(subject->RecipientId(), subject->ClientType());
       
  1401 
       
  1402     RClientInterface::OpenPostMessageClose(
       
  1403     	iContext.NodeId(),
       
  1404     	rejoinDCMsg.iNodeId2,
       
  1405     	msg);
       
  1406 
       
  1407     //Set Client being migrated to a new owner.. reference handed over. secure lifetime.
       
  1408     subject->SetFlags(TCFClientType::EActivating);
       
  1409     }
       
  1410 
       
  1411 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TApplyRejoin, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext)
       
  1412 void CRejoinDataClientActivity::TApplyRejoin::DoL()
       
  1413     {
       
  1414 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 15));
       
  1415 	CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity);
       
  1416 	__ASSERT_DEBUG(rejoinActivity->iDataClients.Count(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 16));
       
  1417     for (TInt i = 0; i < rejoinActivity->iDataClients.Count(); i++)
       
  1418         {
       
  1419         RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->iDataClients[i].iDataClient.RecipientId(),
       
  1420         	TCFFlow::TRejoin(rejoinActivity->iDataClients[i].iNewOwner).CRef());
       
  1421         rejoinActivity->iDataClients[i].iDataClient.SetFlags(TCFClientType::ELeaving);
       
  1422         }
       
  1423     rejoinActivity->PostRequestTo(iContext.NodeId(), TCFScpr::TApplyRequest().CRef());
       
  1424     }
       
  1425 
       
  1426 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinLoopTag,NetStateMachine::MStateFork, CRejoinDataClientActivity::TContext)
       
  1427 EXPORT_C TInt CRejoinDataClientActivity::TRejoinLoopTag::TransitionTag()
       
  1428 	{
       
  1429 	if (iContext.iMessage.IsMessage<TCFRejoiningProvider::TRejoinDataClientRequest>())
       
  1430     	{
       
  1431     	return CoreStates::KLoopTag | NetStateMachine::EBackward;
       
  1432     	}
       
  1433 	return MeshMachine::KNoTag | NetStateMachine::EForward;
       
  1434 	}
       
  1435 
       
  1436 //-=========================================================
       
  1437 //
       
  1438 // CommsBinderActivity (parallel)
       
  1439 //
       
  1440 //-=========================================================
       
  1441 
       
  1442 EXPORT_C MeshMachine::CNodeActivityBase* CCommsBinderActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode )
       
  1443     {
       
  1444 	TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
  1445     return new(ELeave)CCommsBinderActivity(aActivitySig, aNode, c);
       
  1446     }
       
  1447 
       
  1448 EXPORT_C CCommsBinderActivity::CCommsBinderActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aNextActivityCount)
       
  1449 :	MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aNextActivityCount),
       
  1450 	TIfStaticFetcherNearestInHierarchy(this)
       
  1451 	{
       
  1452 	}
       
  1453 
       
  1454 //-=========================================================
       
  1455 //
       
  1456 // CCommsBinderActivity
       
  1457 //
       
  1458 // Aggregate class containing common functionality for
       
  1459 // CommsBinderActivity and CCommsBinderCombiningActivity.
       
  1460 //
       
  1461 //-=========================================================
       
  1462 
       
  1463 EXPORT_C TBool CCommsBinderActivity::TDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
       
  1464   	{
       
  1465   	TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
       
  1466   	__ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 17)); //Diagnostic
       
  1467   	if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext))
       
  1468   		{
       
  1469   		return EFalse;
       
  1470   		}
       
  1471 	return ETrue;
       
  1472    	}
       
  1473 
       
  1474 EXPORT_C TBool CCommsBinderActivity::TDefaultDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
       
  1475   	{
       
  1476   	TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
       
  1477   	__ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 18)); //Diagnostic
       
  1478   	if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext, TCFClientType::EDefault))
       
  1479   		{
       
  1480   		return EFalse;
       
  1481   		}
       
  1482 	return ETrue;
       
  1483    	}
       
  1484 
       
  1485 EXPORT_C /*virtual*/ CCommsBinderActivity::~CCommsBinderActivity()
       
  1486 	{
       
  1487 	if(!iBinderRequestParameters.IsNull())
       
  1488 		{
       
  1489 		iBinderRequestParameters.Close();
       
  1490 		}
       
  1491 	}
       
  1492 
       
  1493 EXPORT_C void CCommsBinderActivity::StoreBinder(RNodeInterface* aDataClient)
       
  1494     {
       
  1495     __ASSERT_DEBUG(iPendingBinder == aDataClient || iPendingBinder == NULL, User::Panic(KSpecAssert_ESockCrStaCPRAC, 19));
       
  1496 	iPendingBinder = aDataClient;
       
  1497     }
       
  1498 
       
  1499 EXPORT_C RNodeInterface* CCommsBinderActivity::Binder() const
       
  1500     {
       
  1501 	return iPendingBinder;
       
  1502     }
       
  1503 
       
  1504 EXPORT_C void CCommsBinderActivity::StoreBinderRequestParameters(const RCFParameterFamilyBundleC& aBinderRequestParameters)
       
  1505 	{
       
  1506 	__ASSERT_DEBUG(iBinderRequestParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 20));
       
  1507 	if(! aBinderRequestParameters.IsNull())
       
  1508 		{
       
  1509 		iBinderRequestParameters.Open(aBinderRequestParameters);
       
  1510 		}
       
  1511 	}
       
  1512 
       
  1513 void CCommsBinderActivity::SendCustomFlowProvision()
       
  1514 /**
       
  1515 Send a custom message that provisions a flow with flow parameters
       
  1516 */
       
  1517 	{
       
  1518     __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 21));
       
  1519 
       
  1520 	// Only send the message if we have parameters to send
       
  1521 	if(!iBinderRequestParameters.IsNull())
       
  1522 		{
       
  1523 		RParameterFamily parameterFamily =
       
  1524 			iBinderRequestParameters.FindFamily(KFlowParametersFamily);
       
  1525 
       
  1526 		if(!parameterFamily.IsNull())
       
  1527 			{
       
  1528 			STypeId typeId = STypeId::CreateSTypeId(CFlowRequestParameters::EUid, CFlowRequestParameters::EType);
       
  1529 			CFlowRequestParameters* flowParams =	static_cast<CFlowRequestParameters*>(parameterFamily.FindParameterSet(typeId, RParameterFamily::ERequested));
       
  1530 
       
  1531 				iPendingBinder->PostMessage(
       
  1532 					iNode.Id(),
       
  1533 					TCFInternalEsock::TFlowProvision(
       
  1534 						flowParams->GetFlowParams()
       
  1535 						).CRef()
       
  1536 					);
       
  1537 			}
       
  1538 		}
       
  1539 	}
       
  1540 
       
  1541 
       
  1542 void CCommsBinderActivity::SendBinderResponseToOriginator()
       
  1543 /**
       
  1544 Send out CommsBinderResponse to all originators.
       
  1545 
       
  1546 We send to all originators that have joined up until this point, and store this count
       
  1547 in iOriginatorsCountSnapshot.  See comment in ProcessBindToComplete().
       
  1548 */
       
  1549     {
       
  1550     __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 22));
       
  1551 
       
  1552 	PostRequestTo(
       
  1553 		address_cast<Messages::TNodeId>(FirstOriginator().RecipientId()),
       
  1554 		TCFServiceProvider::TCommsBinderResponse(iPendingBinder->RecipientId()).CRef());
       
  1555 
       
  1556 	iPendingBinder->SetFlags(TCFClientType::EActivating);
       
  1557     }
       
  1558 
       
  1559 void CCommsBinderActivity::BindToComplete()
       
  1560     {
       
  1561     __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 23));
       
  1562 	TUint c = iNode.CountActivities(ActivitySigId());
       
  1563     // Note: this routine can be used with parallel and non-parallel binder activities.  In the
       
  1564     // former case we start with multiple activities and eventually end up with a single one.  In
       
  1565     // the latter case we have a single activity throughout.
       
  1566 	if(c == 1)
       
  1567 		{
       
  1568 		iPendingBinder->ClearFlags(TCFClientType::EActivating);
       
  1569 		}
       
  1570 	iPendingBinder = NULL;
       
  1571     }
       
  1572 
       
  1573 //
       
  1574 // CCommsBinderActivity methods that are embedded transitions/states/stateforks
       
  1575 //
       
  1576 
       
  1577 EXPORT_C RNodeInterface* CCommsBinderActivity::IsDataClientPresent(TNodeContextBase& aContext, TUint aClientFlags)
       
  1578 /**
       
  1579 Check if we have a data client and, if so, store it as the binder for this activity.
       
  1580 
       
  1581 @param aContext Node context
       
  1582 @param aClientFlags client flags to use in iterator check
       
  1583 @return ETrue if data client present, else EFalse.
       
  1584 */
       
  1585 	{
       
  1586 	// Be careful not to use a client to which we have already sent TDestroy previously.
       
  1587 	// Find the first data client that does not have the ELeaving flag set.  If all are
       
  1588 	// marked ELeaving then return EFalse - they are on the way out and will disappear
       
  1589 	// eventually.  The effect will be that a new data client will be created.
       
  1590 	RNodeInterface* dataClient = aContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, aClientFlags), TClientType(0, TCFClientType::ELeaving));
       
  1591 	return dataClient;
       
  1592 	}
       
  1593 
       
  1594 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
       
  1595 EXPORT_C TInt CCommsBinderActivity::TNoTagOrUseExisting::TransitionTag()
       
  1596 	{
       
  1597 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 24));
       
  1598 	TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
       
  1599 
       
  1600 	// Save away the parameters sent to us so that they are accessible during the activity
       
  1601 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1602 	CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1603 	intf->StoreBinderRequestParameters(msg.iFamilyBundle);
       
  1604 
       
  1605 	if(msg.iValue == TSubConnOpen::EAttachToDefault)
       
  1606 		{
       
  1607 		RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext);
       
  1608 		if (dc)
       
  1609 			{
       
  1610 			__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1611 			CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1612 
       
  1613 			intf->StoreBinder(dc);
       
  1614 			return CoreStates::KUseExisting;
       
  1615 			}
       
  1616 		}
       
  1617 	return MeshMachine::KNoTag;
       
  1618 	}
       
  1619 
       
  1620 //MZTODO - logic of:
       
  1621 //TNoTagOrWaitForIncomingOrUseExisting
       
  1622 //&
       
  1623 //TNoTagOrWaitForIncomingOrUseExistingDefault
       
  1624 //has been copied but does not seem right, as both use EDefault?
       
  1625 //Why?
       
  1626 
       
  1627 //[401TODO] DL : Only one of TNoTagOrWaitForIncomingOrUseExisting(Default) is used, is it ok to nuke one?
       
  1628 
       
  1629 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
       
  1630 EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting::TransitionTag()
       
  1631 	{
       
  1632 	TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
       
  1633 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 25));
       
  1634 
       
  1635     if (msg.iValue == TSubConnOpen::EWaitForIncoming)
       
  1636     	{
       
  1637     	return CoreNetStates::KWaitForIncoming;
       
  1638     	}
       
  1639 
       
  1640 	else
       
  1641 		{
       
  1642 		RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault);
       
  1643 		if (dc)
       
  1644 			{
       
  1645 			__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1646 			CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1647 
       
  1648 			intf->StoreBinder(dc);
       
  1649 			return CoreStates::KUseExisting;
       
  1650 			}
       
  1651 		}
       
  1652 
       
  1653 	return MeshMachine::KNoTag;
       
  1654 	}
       
  1655 
       
  1656 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
       
  1657 EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault::TransitionTag()
       
  1658 	{
       
  1659 	TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
       
  1660 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 26));
       
  1661 
       
  1662 	if(msg.iValue == TSubConnOpen::EAttachToDefault)
       
  1663 		{
       
  1664 		RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault);
       
  1665 		if (dc)
       
  1666 			{
       
  1667 			__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1668 			CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1669 
       
  1670 			intf->StoreBinder(dc);
       
  1671 			return CoreStates::KUseExisting;
       
  1672 			}
       
  1673 		}
       
  1674 	else if (msg.iValue == TSubConnOpen::EWaitForIncoming)
       
  1675     	{
       
  1676     	return CoreNetStates::KWaitForIncoming;
       
  1677     	}
       
  1678 	return MeshMachine::KNoTag;
       
  1679 	}
       
  1680 
       
  1681 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TStorePendingBinder, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
       
  1682 EXPORT_C void CCommsBinderActivity::TStorePendingBinder::DoL()
       
  1683 	{
       
  1684 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 27));
       
  1685 	message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
       
  1686 
       
  1687 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1688 	CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1689 
       
  1690     intf->StoreBinder(iContext.iPeer);
       
  1691 	}
       
  1692 
       
  1693 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendBinderResponse, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
       
  1694 EXPORT_C void CCommsBinderActivity::TSendBinderResponse::DoL()
       
  1695 	{
       
  1696 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 28));
       
  1697 
       
  1698 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1699 	CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1700 
       
  1701     intf->SendBinderResponseToOriginator();
       
  1702 	}
       
  1703 
       
  1704 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendCustomFlowProvision, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
       
  1705 EXPORT_C void CCommsBinderActivity::TSendCustomFlowProvision::DoL()
       
  1706 	{
       
  1707 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 29));
       
  1708 
       
  1709 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1710 	CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1711 
       
  1712     intf->SendCustomFlowProvision();
       
  1713 	}
       
  1714 
       
  1715 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TAwaitingBindToComplete, NetStateMachine::MState, PRStates::TContext)
       
  1716 EXPORT_C TBool CCommsBinderActivity::TAwaitingBindToComplete::Accept()
       
  1717 	{
       
  1718 	CoreNetStates::TAwaitingBindToComplete awaitingBindToComplete(iContext);
       
  1719 	if (awaitingBindToComplete.Accept())
       
  1720 		{
       
  1721 	    CCommsBinderActivity* binderActivity = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1722 	    __ASSERT_DEBUG(binderActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 30));
       
  1723 	    binderActivity->BindToComplete();
       
  1724 		iContext.Node().DestroyOrphanedDataClients();
       
  1725 		return ETrue;
       
  1726 		}
       
  1727 	return EFalse;
       
  1728 	}
       
  1729 
       
  1730 //-=========================================================
       
  1731 //
       
  1732 //CNoBearer Activity
       
  1733 //
       
  1734 //-=========================================================
       
  1735 
       
  1736 CNoBearer::CNoBearer(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount)
       
  1737 :	MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aActivitiesCount),
       
  1738 	ABindingActivity(aNode.Id()),
       
  1739     TIfStaticFetcherNearestInHierarchy(this)
       
  1740 	{
       
  1741 	}
       
  1742 
       
  1743 /*virtual*/ CNoBearer::~CNoBearer()
       
  1744 	{
       
  1745 	iNoBearerParameters.Close();
       
  1746 	}
       
  1747 
       
  1748 EXPORT_C MeshMachine::CNodeActivityBase* CNoBearer::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1749 	{
       
  1750 	TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
  1751     return new(ELeave)CNoBearer(aActivitySig, aNode, c);
       
  1752 	}
       
  1753 
       
  1754 EXPORT_C TNodePeerId& CNoBearer::GetOriginator()
       
  1755     {
       
  1756     __ASSERT_DEBUG(iOriginators.Count() == 1, User::Panic(KSpecAssert_ESockCrStaCPRAC, 31));
       
  1757     return iOriginators[0];
       
  1758     }
       
  1759 
       
  1760 EXPORT_C void CNoBearer::ReturnInterfacePtrL(CoreActivities::ABindingActivity*& aInterface)
       
  1761 	{
       
  1762 	aInterface = this;
       
  1763 	}
       
  1764 
       
  1765 EXPORT_C TBool CNoBearer::TServiceProviderMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
       
  1766 	{
       
  1767 	TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
       
  1768   	__ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 32)); //Diagnostic
       
  1769   	if (c == 1 || aContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) != 0)
       
  1770   		{
       
  1771   		return EFalse;
       
  1772   		}
       
  1773 	return ETrue;
       
  1774 	}
       
  1775 
       
  1776 EXPORT_DEFINE_SMELEMENT(CNoBearer::TRequestCommsBinder, NetStateMachine::MStateTransition, CNoBearer::TContext)
       
  1777 EXPORT_C void CNoBearer::TRequestCommsBinder::DoL()
       
  1778 	{
       
  1779 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1780   	CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1781 
       
  1782 	RNodeInterface* sp = iContext.Node().ServiceProvider();
       
  1783 	__ASSERT_DEBUG(sp, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
  1784 
       
  1785 	TSubConnOpen::TSubConnType type = TSubConnOpen::EAttachToDefault;
       
  1786 	if (!(noBearer.GetOriginator().Flags() & TCFClientType::EDefault))
       
  1787     	{
       
  1788     	type = TSubConnOpen::ECreateNew;
       
  1789     	}
       
  1790 
       
  1791 	noBearer.PostRequestTo(
       
  1792 			*sp,
       
  1793 			TCFServiceProvider::TCommsBinderRequest(
       
  1794 					type, noBearer.iNoBearerParameters
       
  1795 					).CRef()
       
  1796 			);
       
  1797 	}
       
  1798 
       
  1799 EXPORT_DEFINE_SMELEMENT(CNoBearer::TStoreRequestParameters, NetStateMachine::MStateTransition, CNoBearer::TContext)
       
  1800 EXPORT_C void CNoBearer::TStoreRequestParameters::DoL()
       
  1801 	{
       
  1802 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1803   	CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1804 	const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage);
       
  1805 	__ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 33)); // handle should be empty when this fn is called
       
  1806 	if(noBearerMessage.iFamilyBundle.IsNull())
       
  1807 		{
       
  1808 		noBearer.iNoBearerParameters.Open();
       
  1809 		}
       
  1810 		else
       
  1811 		{
       
  1812 		noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle);
       
  1813 		}
       
  1814 	}
       
  1815 
       
  1816 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrDataClientsToStart, NetStateMachine::MStateFork, CNoBearer::TContext)
       
  1817 TInt CNoBearer::TNoTagOrDataClientsToStart::TransitionTag()
       
  1818 	{
       
  1819 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1820   	CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1821 
       
  1822 	const TNodePeerId& originator = activity.GetOriginator();
       
  1823 	__ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 34));
       
  1824 
       
  1825 	if (activity.Error() == KErrNone && (originator.Flags() & (TCFClientType::EStarting|TCFClientType::EStarted|TCFClientType::ELeaving)) == 0)
       
  1826 		{
       
  1827 		//Start dc
       
  1828 		return CoreNetStates::KDataClientsToStart;
       
  1829 		}
       
  1830 	//Finish the activity
       
  1831 	return MeshMachine::KNoTag;
       
  1832 	}
       
  1833 
       
  1834 EXPORT_DEFINE_SMELEMENT(CNoBearer::TStartOriginatingDataClient, NetStateMachine::MStateTransition, CNoBearer::TContext)
       
  1835 void CNoBearer::TStartOriginatingDataClient::DoL()
       
  1836     {
       
  1837 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1838   	CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1839 	TNodePeerId& originator = activity.GetOriginator();
       
  1840 	__ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 35));
       
  1841 	activity.PostRequestTo(originator.Peer(), TCFDataClient::TStart().CRef());
       
  1842 	originator.SetFlags(TCFClientType::EStarting);
       
  1843     }
       
  1844 
       
  1845 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresent, NetStateMachine::MStateFork, CNoBearer::TContext)
       
  1846 EXPORT_C TInt CNoBearer::TNoTagOrBearerPresent::TransitionTag()
       
  1847 	{
       
  1848 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1849 	CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1850 	const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage);
       
  1851 	__ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 36)); // should not yet be set when this fn is called
       
  1852 	noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle);
       
  1853 
       
  1854 	CoreNetStates::TNoTagOrBearerPresent fork(iContext);
       
  1855 	return fork.TransitionTag();
       
  1856 	}
       
  1857 
       
  1858 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresentForAutostart, NetStateMachine::MStateFork, CNoBearer::TContext)
       
  1859 EXPORT_C TInt CNoBearer::TNoTagOrBearerPresentForAutostart::TransitionTag()
       
  1860 	{
       
  1861  	TInt cntrlClients = iContext.Node().CountClients<TDefaultClientMatchPolicy>(
       
  1862  								/*include*/TClientType(TCFClientType::ECtrl));
       
  1863  	if (cntrlClients > 0 &&
       
  1864  		iContext.Node().ServiceProvider() &&
       
  1865  		!(iContext.Node().ServiceProvider()->Flags() & TCFClientType::EStarted))
       
  1866  		{
       
  1867  		//This fork calculates if the NoBearer activity (which this fork has been implemented for)
       
  1868  		//should attempt to autostart the service provider when returning it to the sender of TNoBearer.
       
  1869  		//The philosphy here is that if the local node doesn't have a control client, then there's noone
       
  1870  		//that could posibly start it. It will hence decide to autostart as the top layer of what looks
       
  1871  		//like an implicit connection. In the future this autostart behaviour should become a specialty
       
  1872  		//of someone more concrete (rather than generic function). We are speculating about the implicit
       
  1873  		//top layer that could acquire this function if it ever comes into being.
       
  1874  		return CoreNetStates::KBearerPresent;
       
  1875  		}
       
  1876  	return KNoTag;
       
  1877 	}
       
  1878 
       
  1879 
       
  1880 //-=========================================================
       
  1881 //
       
  1882 //CStartActivity Activity
       
  1883 //
       
  1884 //-=========================================================
       
  1885 CStartActivity::CStartActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1886 	:	MeshMachine::CNodeRetryActivity(aActivitySig, aNode),
       
  1887 		CoreActivities::ABindingActivity(aNode.Id()),
       
  1888 		TIfStaticFetcherNearestInHierarchy(this)
       
  1889 		{
       
  1890 		}
       
  1891 
       
  1892 EXPORT_C CStartActivity::~CStartActivity()
       
  1893 	{
       
  1894 	}
       
  1895 
       
  1896 EXPORT_C MeshMachine::CNodeActivityBase* CStartActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1897     {
       
  1898     return new (ELeave) CStartActivity(aActivitySig, aNode);
       
  1899     }
       
  1900 
       
  1901 //-=========================================================
       
  1902 //
       
  1903 //Gone Down Activity
       
  1904 //
       
  1905 //-=========================================================
       
  1906 MeshMachine::CNodeActivityBase* CGoneDownActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1907     {
       
  1908     CGoneDownActivity* self = new (ELeave) CGoneDownActivity(aActivitySig,aNode);
       
  1909     return self;
       
  1910     }
       
  1911 
       
  1912 CGoneDownActivity::CGoneDownActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1913 :	MeshMachine::CNodeRetryActivity(aActivitySig, aNode)
       
  1914 	{
       
  1915 	}
       
  1916 
       
  1917 CGoneDownActivity::~CGoneDownActivity()
       
  1918     {
       
  1919     //This is a gone down activity. Error mode is its only/natural state
       
  1920     //CGoneDownActivity inherits ultimatelly from CNodeActivityBase, which
       
  1921     //will attempt to interpret the error mode as a failure to execute (and
       
  1922     //auto respond to orignators), which we don't want. Hence clearing
       
  1923     //the error and allowing 'this' to die peacefully.
       
  1924     SetError(KErrNone);
       
  1925     }
       
  1926 
       
  1927 void CGoneDownActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const TStateTriple& aFirst)
       
  1928 	{
       
  1929 	//399TODO: for the moment ignore duplicated TGoneDown messages
       
  1930 	//but this needs to be fixed (someone is sending TGoneDown from TSendDataClientStopped
       
  1931 	//hence the problem)
       
  1932 
       
  1933 	//ASSERT(IsIdle());
       
  1934 	if (!IsIdle())
       
  1935 		{
       
  1936 		return;
       
  1937 		}
       
  1938 
       
  1939 	//This activity provides service for only one single requestor at a time.
       
  1940 	__ASSERT_DEBUG(iOriginators.Count()==0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 37)); //Diagnostic panic
       
  1941 
       
  1942     TCFControlClient::TGoneDown& msg = message_cast<TCFControlClient::TGoneDown>(aContext.iMessage);
       
  1943     SetError(msg.iValue1);
       
  1944     iGoneDownApId = msg.iValue2;
       
  1945 
       
  1946 	MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->starting activity"), this));
       
  1947 	NetStateMachine::ACore::Start(&aContext, aFirst);
       
  1948 
       
  1949 	MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->activity started"), this));
       
  1950     (void)aOriginator;
       
  1951 	}
       
  1952 
       
  1953 //Find next DC to rebind
       
  1954 TBool CGoneDownActivity::IsIdle() const
       
  1955 	{
       
  1956 	return NetStateMachine::ACore::IsIdle();
       
  1957 	}
       
  1958 
       
  1959 DEFINE_SMELEMENT(CGoneDownActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CGoneDownActivity::TContext)
       
  1960 void CGoneDownActivity::TSendErrorRecoveryReq::DoL()
       
  1961     {
       
  1962 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1963 	CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity);
       
  1964 
       
  1965 	//TInt error = ExtractErrorCode(iContext.iMessage);
       
  1966     TErrContext ctx(iContext.NodeId(), TCFControlClient::TGoneDown::Id(), activity.ActivitySigId(), TStateChange(0, activity.Error()));
       
  1967     ctx.iInfo = (TAny*)activity.iGoneDownApId;
       
  1968 	TEErrorRecovery::TErrorRecoveryRequest msg(ctx);
       
  1969 
       
  1970     //We can not set SetSentTo() to Control Provider, because the response may not be coming from it
       
  1971     //(for example it could be coming from the MCpr and we could be the SCpr).
       
  1972     //Normally this would be a problem because any unrelated TError message arriving to the node
       
  1973     //and presented to the awaiting state would easily be confused with the response (TError ==
       
  1974     //no recovery on the MCpr == EPropagate).
       
  1975     //We avoid the problem by checking all arriving TError messages if they are adressed to our activity.
       
  1976     __ASSERT_DEBUG(iContext.Node().ControlProvider(), User::Panic(KCorePrPanic, KPanicNoControlProvider));
       
  1977     activity.PostRequestTo(*iContext.Node().ControlProvider(),
       
  1978     	TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef());
       
  1979     activity.ClearPostedTo();
       
  1980     }
       
  1981 
       
  1982 DEFINE_SMELEMENT(CGoneDownActivity::TIgnoreOrPropagate, NetStateMachine::MStateFork, CGoneDownActivity::TContext)
       
  1983 TInt CGoneDownActivity::TIgnoreOrPropagate::TransitionTag()
       
  1984     {
       
  1985     __ASSERT_DEBUG(iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 38));
       
  1986     RNodeInterface* sp = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted));
       
  1987     if (sp)
       
  1988         {
       
  1989         return CoreStates::KIgnore | NetStateMachine::EForward;
       
  1990         }
       
  1991     //There is no started service provider, the reconnection, mobility, etc must have failed,
       
  1992     //continue with tearing this layer down.
       
  1993     CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity);
       
  1994     TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse;
       
  1995     resp.iAction=TErrResponse::EPropagate;
       
  1996     __ASSERT_DEBUG(activity.Error()!=KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 39));
       
  1997     resp.iError = activity.Error();
       
  1998     return CoreStates::KPropagate | NetStateMachine::EForward;
       
  1999 	}
       
  2000 
       
  2001 
       
  2002 EXPORT_DEFINE_SMELEMENT(CStartActivity::TAwaitingBindToCompleteOrCancel, NetStateMachine::MState, CStartActivity::TContext)
       
  2003 TBool CStartActivity::TAwaitingBindToCompleteOrCancel::Accept()
       
  2004 	{
       
  2005 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  2006 	if (iContext.iMessage.IsMessage<TEBase::TCancel>())
       
  2007 		{
       
  2008 		iContext.iNodeActivity->SetError(KErrCancel);
       
  2009 		iContext.iMessage.ClearMessageId();
       
  2010 		return EFalse;
       
  2011 		}
       
  2012 	else
       
  2013 		{
       
  2014 		CoreNetStates::TAwaitingBindToComplete state(iContext);
       
  2015 		return state.Accept();
       
  2016 		}
       
  2017 	}
       
  2018 } //PRActivities
       
  2019 
       
  2020 EXPORT_DEFINE_SMELEMENT(PRDataClientStopActivity::TNoTagOrProviderStopped, NetStateMachine::MStateFork, PRDataClientStopActivity::TContext)
       
  2021 EXPORT_C TInt PRDataClientStopActivity::TNoTagOrProviderStopped::TransitionTag()
       
  2022 	{
       
  2023 	iContext.iNodeActivity->SetError(message_cast<TCFDataClient::TStop>(iContext.iMessage).iValue);
       
  2024     if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(
       
  2025 	    TClientType(TCFClientType::EData, TCFClientType::EStarted)) != NULL)
       
  2026 		{
       
  2027 		// At least one started data client
       
  2028         return MeshMachine::KNoTag;
       
  2029 		}
       
  2030 	return CoreNetStates::KProviderStopped;
       
  2031     }
       
  2032 
       
  2033 
       
  2034