datacommsserver/esockserver/core_states/ss_corepractivities.cpp.orig
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     //Determine who TErrorRecoveryRequest should be sent to.
       
   547     //If there is no ControlProvider we send a RecoveryRequest to ourselves to recover from the error,
       
   548     //otherwise we sned the RecoveryRequest up to our ControlProvider.
       
   549     //MCPrs typically put all of the error recovery function in a single error recovery activity therefore
       
   550     //it makes sense even for MCPrs to send TErrorRecoveryRequest to their error recovery function. By
       
   551     //posting a TErrorRecoveryRequest sub-classes of the MCPrs get a chance to override the default error
       
   552     //recovery.
       
   553     RNodeInterface*  errorRecoverer = iContext.Node().ControlProvider() ? iContext.Node().ControlProvider() : &iContext.Node().SelfInterface();
       
   554 
       
   555 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   556     CoreActivities::CErrorActivity& activity = static_cast<CoreActivities::CErrorActivity&>(*iContext.iNodeActivity);
       
   557     __ASSERT_DEBUG(activity.iErroredActivityId==MeshMachine::KActivityNull, User::Panic(KSpecAssert_ESockCrStaCPRAC, 4));
       
   558 	// Save a reference to the activity and a point
       
   559 	// Each time we use the activity, query it from the node, because the activity may have gone away (originator left node etc)
       
   560 	activity.iErroredActivityId = aa->ActivityId();
       
   561 
       
   562     activity.SetError(errmsg.iValue);
       
   563     activity.iMessageId = errmsg.iMsgId;
       
   564 
       
   565     TErrContext ctx(iContext.NodeId(), errmsg.iMsgId, aa->ActivitySigId(), TStateChange(0, errmsg.iValue));
       
   566 	TEErrorRecovery::TErrorRecoveryRequest msg(ctx);
       
   567 
       
   568     activity.PostRequestTo(
       
   569     	*errorRecoverer,//ControlProvider() verified above
       
   570     	TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef()
       
   571     	);
       
   572 
       
   573     //The original activiy might have set 'sent to', but that's surely
       
   574     //not meaningful anymore (we've just received a response from that 'sent to').
       
   575     //We could have pretended that the orginal activity knows it's sent
       
   576     //error recovery to the control provider but it's best just to clear
       
   577     //'sent to' (and handle TCancel from here (CErrorActivity::Next()).
       
   578     aa->ClearPostedTo();
       
   579     }
       
   580 
       
   581 EXPORT_DEFINE_SMELEMENT(CErrorActivity::TDoErrorRecovery, NetStateMachine::MStateTransition, CErrorActivity::TContext)
       
   582 EXPORT_C void CErrorActivity::TDoErrorRecovery::DoL()
       
   583     {
       
   584     __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   585     CoreActivities::CErrorActivity* act = static_cast<CoreActivities::CErrorActivity*>(iContext.iNodeActivity);
       
   586 	CNodeActivityBase* a = iContext.Node().FindActivityById(act->iErroredActivityId);
       
   587     if (a == NULL)
       
   588 		{
       
   589 		iContext.iNodeActivity->SetIdle();
       
   590 		return;
       
   591 		}
       
   592 
       
   593 	if (iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>())
       
   594 		{
       
   595 		TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse;
       
   596 		if (resp.iAction == TErrResponse::ERetry)
       
   597 			{ //rerun current transition
       
   598 			__CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to retry")));
       
   599 			__ASSERT_DEBUG(a->SupportsExtInterface(AContextStore::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
   600 
       
   601 			AContextStore* intf = reinterpret_cast<AContextStore*>(a->FetchExtInterfaceL(AContextStore::KInterfaceId));
       
   602 			__ASSERT_DEBUG(intf->IsStored(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 5));
       
   603 			intf->Retry(*a,iContext);
       
   604 			if (iContext.iReturn == KErrNone)
       
   605 				{ //retry succeded
       
   606 				act->SetError(KErrNone);
       
   607 				}
       
   608 			//if Retry had failed, then the d'tor of act will raise the error on
       
   609 			//and terminate act->iActivity,
       
   610 			}
       
   611 		else if (resp.iAction == TErrResponse::EPropagate)
       
   612 			{ //set new error values and fall through
       
   613 			__CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to propagate the error")));
       
   614 			act->iMessageId = resp.iMessageId;
       
   615 			a->SetError(resp.iError);
       
   616 			}
       
   617 		else //if (resp.iAction == TErrResponse::EIgnore)
       
   618 			{
       
   619 			__CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag,
       
   620 			_L8("WARNING: ADoErrorRecovery::DoL() - instructed to ignore the error!")));
       
   621 			}
       
   622 		}
       
   623 	}
       
   624 
       
   625 
       
   626 //-=========================================================
       
   627 //
       
   628 //Destroy Activity - will delete the node when destructed
       
   629 //
       
   630 //-=========================================================
       
   631 
       
   632 EXPORT_C MeshMachine::CNodeActivityBase* CDestroyActivity::New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   633 	{
       
   634 	TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CDestroyActivity));
       
   635 	CDestroyActivity* self = new (space) CDestroyActivity(aActivitySig, aNode);
       
   636 	self->InsertPreallocatedDestroyActivity(); //Destructing preallocated activity
       
   637 	return self;
       
   638 	}
       
   639 
       
   640 CDestroyActivity::CDestroyActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   641 :	CNodeRetryActivity(aActivitySig, aNode),
       
   642 	APreallocatedOriginators<1>(iOriginators)
       
   643 	{
       
   644 	//Mark the provider for deletion, so that it's not served by the factory from now on.
       
   645     static_cast<ESock::CMMCommsProviderBase&>(iNode).MarkMeForDeletion();
       
   646 	}
       
   647 
       
   648 void CDestroyActivity::Destroy()
       
   649 	{
       
   650 	ReturnPreallocatedSpace(this);
       
   651 	this->~CDestroyActivity(); //Run the destructor
       
   652 
       
   653 	//Delete the provider.
       
   654 	static_cast<ESock::CMMCommsProviderBase&>(iNode).DeleteMeNow();
       
   655 	}
       
   656 
       
   657 TBool CDestroyActivity::Next(TNodeContextBase& aContext)
       
   658     {
       
   659     if (aContext.iMessage.IsMessage<TEBase::TCancel>())
       
   660         {  
       
   661         return ETrue;
       
   662         }
       
   663     else
       
   664         return CNodeActivityBase::Next(aContext);
       
   665     }
       
   666 
       
   667 EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
       
   668 EXPORT_C TInt CDestroyActivity::TNoTagOrNoTagBackwards::TransitionTag()
       
   669     {
       
   670 	if (iContext.iMessage.IsMessage<TEChild::TLeft>())
       
   671 		{
       
   672 		TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData|TCFClientType::ECtrl));
       
   673 		__ASSERT_DEBUG(iter[0], User::Panic(KSpecAssert_ESockCrStaCPRAC, 7)); //One leaving client must still be there.
       
   674 		return iter[1] == NULL ?  MeshMachine::KNoTag : MeshMachine::KNoTag | NetStateMachine::EBackward;
       
   675 		}
       
   676 	else if (iContext.iMessage.IsMessage<TEPeer::TLeaveComplete>())
       
   677 		{
       
   678 		__ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl|TCFClientType::EData))==NULL,
       
   679 		User::Panic(KCorePrPanic, KPanicClientsStillPresent));
       
   680 		if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider))==NULL)
       
   681 			{
       
   682 			return NetStateMachine::EForward | MeshMachine::KNoTag;
       
   683 			}
       
   684 		return NetStateMachine::EBackward | MeshMachine::KNoTag; //Loop back to the same triple (& remove the peer)
       
   685 		}
       
   686 	__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCrStaCPRAC, 8));
       
   687 	return KNoTag;
       
   688 	}
       
   689 
       
   690 EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, NetStateMachine::MStateTransition, PRStates::TContext)
       
   691 EXPORT_C void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::DoL()
       
   692 	{
       
   693 	if (iContext.iMessage.IsMessage<TEChild::TLeft>())
       
   694 		{
       
   695 		ProcessClientLeaveL();
       
   696 		}
       
   697 	else
       
   698 		{
       
   699 		MakeClientsLeaveL();
       
   700 		}
       
   701 	}
       
   702 
       
   703 void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::MakeClientsLeaveL()
       
   704     {
       
   705     __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl))==NULL,
       
   706     	User::Panic(KCorePrPanic, KPanicClientsStillPresent));
       
   707 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   708 	iContext.iNodeActivity->ClearPostedTo();
       
   709 
       
   710 	//MZTODO: this asserion may need to be changed since TDestroy can
       
   711 	//come while data client is active etc.
       
   712     __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EActive|TCFClientType::EActivating|TCFClientType::EStarting|TCFClientType::EStarted))==NULL,
       
   713     	User::Panic(KCorePrPanic, KPanicClientsStillPresent));
       
   714 
       
   715    	TClientIter<TDefaultClientMatchPolicy> dciter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData),	TClientType(0, TCFClientType::ELeaving));
       
   716    	RNodeInterface* dc = NULL;
       
   717     while ((dc = dciter[0]) != NULL) //always inspect the first elem as we're invalidating the iterator with each hit.
       
   718         {
       
   719 		dc->PostMessage(iContext.NodeId(), TEChild::TDestroy().CRef());
       
   720 		dc->SetFlags(TCFClientType::ELeaving);
       
   721         }
       
   722 	}
       
   723 
       
   724 void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::ProcessClientLeaveL()
       
   725     {
       
   726     CDestroyActivity::TProcessClientLeave processClientLeave(iContext);
       
   727     processClientLeave.DoL();
       
   728     }
       
   729 
       
   730 
       
   731 //-=========================================================
       
   732 //
       
   733 //Loppin Activity
       
   734 //
       
   735 //-=========================================================
       
   736 EXPORT_C ACountLoopActivity::~ACountLoopActivity()
       
   737     {
       
   738     }
       
   739 
       
   740 
       
   741 EXPORT_C MeshMachine::CNodeActivityBase* CCountLoopActivityBase::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   742     {
       
   743     return new (ELeave) CCountLoopActivityBase(aActivitySig, aNode);
       
   744     }
       
   745 
       
   746 EXPORT_C CCountLoopActivityBase::CCountLoopActivityBase(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   747 :	MeshMachine::CNodeActivityBase(aActivitySig, aNode),
       
   748     TIfStaticFetcherNearestInHierarchy(this)
       
   749     {
       
   750 	}
       
   751 
       
   752 EXPORT_C CCountLoopActivityBase::~CCountLoopActivityBase()
       
   753     {
       
   754     }
       
   755 
       
   756 EXPORT_DEFINE_SMELEMENT(ACountLoopActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext)
       
   757 EXPORT_C TInt ACountLoopActivity::TNoTagOrNoTagBackwards::TransitionTag()
       
   758 	{
       
   759 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   760 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ACountLoopActivity::KInterfaceId),User::Panic(KCorePrPanic, KPanicInterfaceNotSupported));
       
   761 	ACountLoopActivity* countLoopActivity = static_cast<ACountLoopActivity*>(iContext.iNodeActivity->FetchExtInterface(ACountLoopActivity::KInterfaceId));
       
   762  	if (countLoopActivity->DecCount() > 0)
       
   763  		{
       
   764         return KNoTag | NetStateMachine::EBackward;
       
   765      	}
       
   766  	return KNoTag | NetStateMachine::EForward;
       
   767  	}
       
   768 
       
   769 
       
   770 
       
   771 
       
   772 
       
   773 //-=========================================================
       
   774 //
       
   775 //
       
   776 //Binding Activity
       
   777 //
       
   778 //
       
   779 //-=========================================================
       
   780 EXPORT_C ABindingActivity::~ABindingActivity()
       
   781 	{
       
   782     //Handle premature termination of the ABindingActivity object
       
   783     //by responding to the originator
       
   784 	//If the originator has not been replied to yet, reply now with an error code
       
   785 	if (IsBinding())
       
   786 		{
       
   787 		ReplyToOriginator(KErrAbort);
       
   788 		}
       
   789 	}
       
   790 
       
   791 EXPORT_C void ABindingActivity::StoreOriginator(const TRuntimeCtxId& aNodeCtxId)
       
   792     {
       
   793     //Check if the originator wasn't set before. If it was, it must be replied to before storing ths new one.
       
   794     __ASSERT_DEBUG(iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 9));
       
   795     iOriginator = aNodeCtxId;
       
   796     }
       
   797 
       
   798 EXPORT_C void ABindingActivity::ReplyToOriginator(TInt aError)
       
   799     {
       
   800     //NOTE: Please do not make this diagnostic panic conditional.
       
   801     //Please allow it to server everyone equally.
       
   802     //Please handle the error conditions properly so that you obey this API's semantics.
       
   803     //If you are not providing a clean error handling solution for your activity,
       
   804     //please use IsBinding() before calling this API!
       
   805     __ASSERT_DEBUG(!iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 10)); //The iOriginator must be set.
       
   806     RClientInterface::OpenPostMessageClose(iOurNode, iOriginator, TCFDataClient::TBindToComplete(aError).CRef());
       
   807     iOriginator.SetNull();
       
   808     }
       
   809 
       
   810 EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CoreStates::TContext)
       
   811 EXPORT_C void ABindingActivity::TSendBindToComplete::DoL()
       
   812 	{
       
   813     __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   814     __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 11));
       
   815     ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId));
       
   816     bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error());
       
   817 	}
       
   818 
       
   819 EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToCompleteIfExpected, NetStateMachine::MStateTransition, CoreStates::TContext)
       
   820 EXPORT_C void ABindingActivity::TSendBindToCompleteIfExpected::DoL()
       
   821 	{
       
   822     __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   823     __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 12));
       
   824     ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId));
       
   825     if (bindingActivity->IsBinding())
       
   826 	    {
       
   827 		bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error());
       
   828 	    }
       
   829 	}
       
   830 
       
   831 void ABindingActivity::FinalReplyToOriginator(TInt aError)
       
   832 /**
       
   833 Intended to be called from derived class destructors to arrange for a TBindToComplete reply to be sent
       
   834 before any other messages in those derived class destructors (for example TDestroy).
       
   835 */
       
   836 	{
       
   837 	if (IsBinding())
       
   838 		{
       
   839 		ReplyToOriginator(aError);
       
   840 		// Ensure that we don't send another reply in ~ABindingActivity.
       
   841 		iOriginator = Messages::TNodeCtxId();
       
   842 		}
       
   843 	}
       
   844 
       
   845 } // CoreActivities
       
   846 
       
   847 
       
   848 namespace PRActivities
       
   849 {
       
   850 DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesPR)
       
   851 	ACTIVITY_MAP_ENTRY(PRDataClientJoinActivity, PRDataClientJoin)
       
   852 	ACTIVITY_MAP_ENTRY(PRControlClientJoinActivity, PRControlClientJoin)
       
   853 	ACTIVITY_MAP_ENTRY(PRClientLeaveActivity, PRClientLeave)
       
   854 	ACTIVITY_MAP_ENTRY(PRForwardStateChangeActivity, PRForwardStateChange)
       
   855 	ACTIVITY_MAP_ENTRY(PRBindToActivity, PRBindTo)
       
   856 	ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart)
       
   857 	ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop)
       
   858 ACTIVITY_MAP_END_BASE(CoreActivities,coreActivitiesAll)
       
   859 
       
   860 //Activity Map provided by CorePr to be used by SCprs.
       
   861 //(it is further extended in CoreSCpr).
       
   862 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesSCpr)
       
   863 	ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
       
   864     ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
       
   865     ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
       
   866 	ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
       
   867 	ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
       
   868 	ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
       
   869 	ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown)
       
   870 	ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro
       
   871 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   872 	ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams)
       
   873 	ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams)
       
   874 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   875     ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
       
   876 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
       
   877 
       
   878 //Activity Map provided by CorePr to be used by Cprs.
       
   879 //(it is further extended in CoreCpr).
       
   880 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesCpr)
       
   881 	ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision)
       
   882     ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart)
       
   883     ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop)
       
   884 	ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
       
   885 	ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
       
   886 	ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy)
       
   887 	ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown)
       
   888 	ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro
       
   889     ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange)
       
   890 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   891     ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams)
       
   892     ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams)
       
   893 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   894     ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
       
   895 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
       
   896 
       
   897 //Activity Map provided by CorePr to be used by MCprs.
       
   898 //(it is further extended in CoreMCpr).
       
   899 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesMCpr)
       
   900 	ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
       
   901 	ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive)
       
   902     ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange)
       
   903     ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler)
       
   904 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
       
   905 
       
   906 //Activity Map provided by CorePr to be used by TMs.
       
   907 //(it is further extended in CoreTM).
       
   908 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesTM)
       
   909 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR)
       
   910 
       
   911 
       
   912 
       
   913 
       
   914 //-=========================================================
       
   915 //
       
   916 //CBindToActivity
       
   917 //
       
   918 //-=========================================================
       
   919 EXPORT_C CBindToActivity::CBindToActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TInt aNextActivityCount)
       
   920 	:	MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aNextActivityCount),
       
   921 		CoreActivities::ABindingActivity(aNode.Id()),
       
   922 	    TIfStaticFetcherNearestInHierarchy(this)
       
   923 		{
       
   924 		}
       
   925 
       
   926 EXPORT_C MeshMachine::CNodeActivityBase* CBindToActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   927     {
       
   928      //there can be only one BindTo activity running at a time.
       
   929     TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
   930 	__ASSERT_DEBUG(c == 1,User::Panic(KCorePrPanic, KPanicPeerMisbehaving));
       
   931     if (c > 1)
       
   932         {
       
   933         User::Leave(KErrInUse);
       
   934         }
       
   935     return new (ELeave) CBindToActivity(aActivitySig, aNode, c);
       
   936     }
       
   937 
       
   938 EXPORT_C CBindToActivity::~CBindToActivity()
       
   939     {
       
   940     //If the activity is aborted then no cleanup will be performed (the destroy activity will do
       
   941     //that for us) so we should not assert that iSuccessfulDataClients is empty or iNewServiceProvider
       
   942     //is null.
       
   943 
       
   944     //CBindToActivity::TCommit or CBindToActivity::TCancel should have been executed
       
   945     //and rendered iSuccessfulDataClients empty.
       
   946 	//__ASSERT_DEBUG(iSuccessfulDataClients.Count() == 0, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
   947 
       
   948 	//CBindToActivity::iNewServiceProvider should have been cleared by CBindToActivity::TCommit or CBindToActivity::TCancel
       
   949 	//__ASSERT_DEBUG(iNewServiceProvider == NULL, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
   950 
       
   951     iSuccessfulDataClients.Close();
       
   952     }
       
   953 
       
   954 Messages::RNodeInterface* CBindToActivity::NextDataClient()
       
   955 	{
       
   956 	TClientIter<TDefaultClientMatchPolicy> iter = iNode.GetClientIter<TDefaultClientMatchPolicy>(
       
   957 												/*include*/TClientType(TCFClientType::EData),
       
   958 												/*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint));
       
   959     iCurrentDataClient = iter++;
       
   960     while (iCurrentDataClient && (iSuccessfulDataClients.Find(iCurrentDataClient) != KErrNotFound))
       
   961     	{
       
   962         iCurrentDataClient = iter++;
       
   963         };
       
   964     return iCurrentDataClient;
       
   965 	}
       
   966 
       
   967 TBool CBindToActivity::DataClientsAutocommit()
       
   968  	{
       
   969  	TInt nonLeavingDataClients = iNode.CountClients<TDefaultClientMatchPolicy>(
       
   970  								/*include*/TClientType(TCFClientType::EData),
       
   971  								/*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint));
       
   972  	return nonLeavingDataClients <=1 && IsAutocommit();
       
   973  	}
       
   974 
       
   975 
       
   976 void CBindToActivity::AddClientAsSuccessfulL(Messages::RNodeInterface* aDataClient)
       
   977 	{
       
   978 	__ASSERT_DEBUG(aDataClient, User::Panic(KCorePrPanic, KPanicDataClient));
       
   979 	__ASSERT_DEBUG(iSuccessfulDataClients.Find(aDataClient) == KErrNotFound, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
   980 	iSuccessfulDataClients.Append(aDataClient);
       
   981 	}
       
   982 
       
   983 void CBindToActivity::RemoveClientFromSuccessful(Messages::RNodeInterface* aDataClient)
       
   984 	{
       
   985 	TInt index = iSuccessfulDataClients.Find(aDataClient);
       
   986 	__ASSERT_DEBUG(index >= 0, User::Panic(KCorePrPanic, KPanicDataClient));
       
   987 	iSuccessfulDataClients.Remove(index);
       
   988 	}
       
   989 
       
   990 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendControlClientJoinRequest, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
   991 void CBindToActivity::TSendControlClientJoinRequest::DoL()
       
   992     {
       
   993 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
   994     CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
   995 	const TCFDataClient::TBindTo& bindToMsg(message_cast<const TCFDataClient::TBindTo>(iContext.iMessage));
       
   996 
       
   997 	__ASSERT_DEBUG(!bindToMsg.iNodeId.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
   998     RNodeInterface* newServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId,
       
   999                             TClientType(TCFClientType::EServProvider, TCFClientType::EActivating));
       
  1000     __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
  1001     activity.iNewServiceProvider = bindToMsg.iNodeId;
       
  1002     //Join the new service provider
       
  1003     iContext.Activity()->PostRequestTo(*newServiceProvider,
       
  1004                             TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
       
  1005     }
       
  1006 
       
  1007 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TAwaitingBindToCompleteOrError, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
       
  1008 TBool CBindToActivity::TAwaitingBindToCompleteOrError::Accept()
       
  1009     {
       
  1010 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1011     CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1012     if (CoreNetStates::TAwaitingBindToComplete(iContext).Accept())
       
  1013 	    {
       
  1014 	    if (activity.IsBinding())
       
  1015 	    	{
       
  1016 	    	//Activity is binding (i.e.: we havent received TBindToComplete as a response
       
  1017 	    	//to null-carrying TBindTo.
       
  1018 		    activity.ReplyToOriginator(KErrNone);
       
  1019 	    	}
       
  1020 	    activity.ResetCurrentDataClient();
       
  1021 	    return ETrue;
       
  1022 	    }
       
  1023     else if (iContext.iMessage.IsMessage<TEBase::TError>())
       
  1024     	{
       
  1025 	    activity.ReplyToOriginator(message_cast<TEBase::TError>(iContext.iMessage).iValue);
       
  1026     	activity.RemoveClientFromSuccessful(activity.CurrentDataClient());
       
  1027     	activity.ResetCurrentDataClient();
       
  1028     	return ETrue;
       
  1029     	}
       
  1030 	return EFalse;
       
  1031     }
       
  1032 
       
  1033 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrDataClientReady, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1034 TInt CBindToActivity::TNoTagOrDataClientReady::TransitionTag()
       
  1035     {
       
  1036     //Any non-leaving dataclients already present?
       
  1037     if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(
       
  1038     	/*include*/TClientType(TCFClientType::EData),
       
  1039     	/*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint)))
       
  1040 	    {
       
  1041 	    return KDataClientReady;
       
  1042 	    }
       
  1043 	return KNoTag;
       
  1044     }
       
  1045 
       
  1046 
       
  1047 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TRequestCommsBinder, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1048 void CBindToActivity::TRequestCommsBinder::DoL()
       
  1049     {
       
  1050 	__ASSERT_DEBUG(iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)),User::Panic(KCorePrPanic, KPanicDataClient));
       
  1051 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1052   	CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1053 
       
  1054   	//The service provider has been joined already and must be found here
       
  1055     __ASSERT_DEBUG(!activity.iNewServiceProvider.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
  1056     RNodeInterface* newServiceProvider = iContext.Node().FindClient(activity.iNewServiceProvider);
       
  1057     __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
  1058     //We must not be in this transition if dc was not found
       
  1059     __ASSERT_DEBUG(activity.CurrentDataClient(), User::Panic(KCorePrPanic, KPanicDataClient));
       
  1060 
       
  1061     // Also if it is not so common to have multiple DataClient (except
       
  1062     // 	for the relation "SCPR<-CPR"), there are situation where it happens
       
  1063     // 	and where only one of them is marked as Default.
       
  1064     // So, we check if this is the case and, in case the
       
  1065     //	Originator of this activity is NOT a Default one, send ECreateNew.
       
  1066 
       
  1067     // If the Current DC is marked as Default, we ask to the lower layer
       
  1068     //	to "AttachToDefault". If it is not, we ask "CreateNew".
       
  1069     TInt subConnOpenType = (activity.CurrentDataClient()->Flags() & TCFClientType::EDefault) ?
       
  1070    			TSubConnOpen::EAttachToDefault : TSubConnOpen::ECreateNew;
       
  1071 
       
  1072     // --- WORKAROUND START ---
       
  1073     // [399TODO] There are situation were we don't have any DataClient marked
       
  1074     //	as Default, but, asking for ECreateNew, the lower layer doesn't
       
  1075     //	manage the request very well.
       
  1076     //	This is a WORKAROUND and need fixing (see DEF113154).
       
  1077     //	In the meanwhile, we count the number of "DefaultDataClient" and,
       
  1078     //	if the result is "0", we ask the lower layer "AttachToDefault"
       
  1079     TInt numberOfDefaultDataClient = iContext.Node().CountClients<TDefaultClientMatchPolicy>(
       
  1080     		TClientType(TCFClientType::EData, TCFClientType::EDefault)
       
  1081     		);
       
  1082     if (numberOfDefaultDataClient == 0)
       
  1083     	{
       
  1084     	subConnOpenType = TSubConnOpen::EAttachToDefault;
       
  1085     	}
       
  1086     // --- WORKAROUND END ---
       
  1087 
       
  1088     // Send "TCommsBinderRequest" to the Current ServiceProvider
       
  1089    	activity.PostRequestTo(
       
  1090    			*newServiceProvider,
       
  1091    			TCFServiceProvider::TCommsBinderRequest(subConnOpenType).CRef()
       
  1092    			);
       
  1093     }
       
  1094 
       
  1095 
       
  1096 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCreateDataClient, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1097 void CBindToActivity::TCreateDataClient::DoL()
       
  1098     {
       
  1099 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1100 
       
  1101 	IssuePeerCreationRequestL ();
       
  1102     }
       
  1103 
       
  1104 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindTo, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1105 void CBindToActivity::TSendBindTo::DoL()
       
  1106     {
       
  1107 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1108 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1109 
       
  1110 	//Provisionally stash the current dataclient as successful. If it fails to bind, we'll unstash it
       
  1111 	//We're doing this now, as stashing may fail and we don't want that to be the sole reason for
       
  1112 	//unrolling.
       
  1113 	bindToActivity.AddClientAsSuccessfulL(bindToActivity.CurrentDataClient());
       
  1114 
       
  1115 	TCFServiceProvider::TCommsBinderResponse* commsBinderResponse = message_cast<TCFServiceProvider::TCommsBinderResponse>(&iContext.iMessage);
       
  1116 	Messages::TNodeId commsBinder = commsBinderResponse ? commsBinderResponse->iNodeId : Messages::TNodeId::NullId();
       
  1117 
       
  1118 	bindToActivity.PostRequestTo(*bindToActivity.CurrentDataClient(),
       
  1119 			TCFDataClient::TBindTo(commsBinder, !bindToActivity.DataClientsAutocommit()).CRef());
       
  1120     }
       
  1121 
       
  1122 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1123 void CBindToActivity::TSendBindToComplete::DoL()
       
  1124     {
       
  1125 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1126 	iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete().CRef());
       
  1127     }
       
  1128 
       
  1129 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrCommit, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1130 TInt CBindToActivity::TNoTagOrCommit::TransitionTag()
       
  1131     {
       
  1132 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1133 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1134 	if (bindToActivity.IsAutocommit())
       
  1135 		{
       
  1136 		return KCommit;
       
  1137 		}
       
  1138 	return KNoTag;
       
  1139     }
       
  1140 
       
  1141 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1142 EXPORT_C TInt CBindToActivity::TNoTagOrBindToComplete::TransitionTag()
       
  1143     {
       
  1144     TCFFactory::TPeerFoundOrCreated& dcJoined = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
       
  1145 
       
  1146     if (dcJoined.iNodeId.IsNull())
       
  1147     	{
       
  1148     	//Factory decided not to create a dataclient;
       
  1149     	return KBindToComplete;
       
  1150     	}
       
  1151 
       
  1152     //factory created a new citizen.
       
  1153     return KNoTag;
       
  1154     }
       
  1155 
       
  1156 
       
  1157 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReady, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1158 TInt CBindToActivity::TNoTagOrBearerReady::TransitionTag()
       
  1159     {
       
  1160 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1161 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1162     TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(iContext.iMessage);
       
  1163     bindToActivity.SetAutocommit(!bindToReq.iValue);
       
  1164 
       
  1165     if (bindToReq.iNodeId.IsNull())
       
  1166     	//received a null service provider, the node is at the stack's bottom.
       
  1167         {
       
  1168         return KBearerReady;
       
  1169         }
       
  1170 
       
  1171     RNodeInterface* sp = iContext.Node().ServiceProvider();
       
  1172     if (sp && bindToReq.iNodeId == sp->RecipientId())
       
  1173         {
       
  1174         //received the same service provider, it's already bound to.
       
  1175         bindToActivity.iNewServiceProvider = sp->RecipientId();
       
  1176 		return KBearerReady;
       
  1177 		}
       
  1178     RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToReq.iNodeId);
       
  1179 	if (newServiceProvider)
       
  1180 		{
       
  1181 		__ASSERT_DEBUG(newServiceProvider->Type() == TCFClientType::EServProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
  1182 		//Ok, we've received a TBindTo holding a service provider that we already know of and that is not
       
  1183 		//our current service provider. We're going to assume this node tolerates multiple service providers (like MCPRs do).
       
  1184 		//the current service provider will be swapped, but won't be dropped.
       
  1185 		bindToActivity.iNewServiceProvider = bindToReq.iNodeId;
       
  1186 		newServiceProvider->SetFlags(TCFClientType::EActivating);
       
  1187 		bindToActivity.SetDontLeaveServiceProvider();
       
  1188 		return KBearerReady;
       
  1189 		}
       
  1190 	else
       
  1191 	    {
       
  1192         bindToActivity.iNewServiceProvider = TNodeId::NullId();
       
  1193 	    }
       
  1194 	//The node received a new service provider...
       
  1195 	return KNoTag;
       
  1196     }
       
  1197 
       
  1198 
       
  1199 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReadyOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext)
       
  1200 TInt CBindToActivity::TNoTagOrBearerReadyOrBindToComplete::TransitionTag()
       
  1201 	{
       
  1202 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1203 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1204 
       
  1205     if (!bindToActivity.NextDataClient())
       
  1206     	{
       
  1207     	//No more dataclients to bind
       
  1208     	return KBindToComplete;
       
  1209     	}
       
  1210 
       
  1211     if (bindToActivity.iNewServiceProvider.IsNull())
       
  1212     	{
       
  1213     	//There is no service provider (new or old) below us.
       
  1214     	return KBearerReady;
       
  1215     	}
       
  1216 
       
  1217     return KNoTag;
       
  1218     }
       
  1219 
       
  1220 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCommit, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1221 void CBindToActivity::TCommit::DoL()
       
  1222     {
       
  1223 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1224 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1225 
       
  1226 	TInt count = bindToActivity.DataClientsAutocommit() ? 0 : bindToActivity.iSuccessfulDataClients.Count();
       
  1227     while (count )
       
  1228     	{
       
  1229     	bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TCFDataClient::TCommitBindTo().CRef());
       
  1230         };
       
  1231     bindToActivity.iSuccessfulDataClients.Reset();
       
  1232     RNodeInterface* sp = iContext.Node().ServiceProvider();
       
  1233 
       
  1234     if (sp && sp->RecipientId() != bindToActivity.iNewServiceProvider)
       
  1235     	{
       
  1236     	if (bindToActivity.ShouldLeaveServiceProvider())
       
  1237     		{
       
  1238 	    	bindToActivity.PostRequestTo(*sp, TEPeer::TLeaveRequest().CRef());
       
  1239 	    	sp->SetFlags(TCFClientType::ELeaving);
       
  1240     		}
       
  1241         else
       
  1242         	{
       
  1243         	//Didn't leave, no need for waiting for TLeaveComplete;
       
  1244         	bindToActivity.SetIdle();
       
  1245         	}
       
  1246     	sp->ClearFlags(TCFClientType::EActive);
       
  1247     	}
       
  1248     else
       
  1249     	{
       
  1250     	//Didn't leave, no need for waiting for TLeaveComplete;
       
  1251     	bindToActivity.SetIdle();
       
  1252     	}
       
  1253 
       
  1254     if (!bindToActivity.iNewServiceProvider.IsNull() && (sp == NULL || sp->RecipientId() != bindToActivity.iNewServiceProvider))
       
  1255         {
       
  1256         RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
       
  1257         if (newServiceProvider)
       
  1258             {
       
  1259             __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
  1260             newServiceProvider->ClearFlags(TCFClientType::EActivating);
       
  1261             newServiceProvider->SetFlags(TCFClientType::EActive);
       
  1262             // Note: iContext.Node().ServiceProvider() must be re-evaluated in the ASSERT below (i.e. don't use any previously cached value).
       
  1263             __ASSERT_DEBUG(iContext.Node().ServiceProvider() == newServiceProvider, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
  1264             }
       
  1265         }
       
  1266     bindToActivity.iNewServiceProvider = TNodeId::NullId();
       
  1267     }
       
  1268 
       
  1269 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCancel, NetStateMachine::MStateTransition, CBindToActivity::TContext)
       
  1270 void CBindToActivity::TCancel::DoL()
       
  1271     {
       
  1272 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1273 	CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity);
       
  1274 	TInt count = bindToActivity.iSuccessfulDataClients.Count();
       
  1275     while (count )
       
  1276     	{
       
  1277     	bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TEBase::TCancel().CRef());
       
  1278         };
       
  1279     bindToActivity.iSuccessfulDataClients.Reset();
       
  1280 
       
  1281 	TBool setIdle = ETrue;
       
  1282     if (!bindToActivity.iNewServiceProvider.IsNull())
       
  1283         {
       
  1284         RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider);
       
  1285         if (newServiceProvider && newServiceProvider != iContext.Node().ServiceProvider())
       
  1286             {
       
  1287             __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState));
       
  1288             newServiceProvider->ClearFlags(TCFClientType::EActivating);
       
  1289             if (bindToActivity.ShouldLeaveServiceProvider())
       
  1290                 {
       
  1291                 bindToActivity.PostRequestTo(*newServiceProvider, TEPeer::TLeaveRequest().CRef());
       
  1292                 newServiceProvider->SetFlags(TCFClientType::ELeaving);
       
  1293                 setIdle = EFalse;
       
  1294                 }
       
  1295             }
       
  1296         }
       
  1297 
       
  1298     if (setIdle)
       
  1299         {
       
  1300         bindToActivity.SetIdle();
       
  1301         }
       
  1302     bindToActivity.iNewServiceProvider = TNodeId::NullId();
       
  1303     }
       
  1304 
       
  1305 
       
  1306 //-=========================================================
       
  1307 //
       
  1308 //Rejoin DataClient Activity
       
  1309 //
       
  1310 //-=========================================================
       
  1311 EXPORT_C MeshMachine::CNodeActivityBase* CRejoinDataClientActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1312     {
       
  1313 	TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
  1314     return new(ELeave)CRejoinDataClientActivity(aActivitySig, c, aNode);
       
  1315     }
       
  1316 
       
  1317 CRejoinDataClientActivity::~CRejoinDataClientActivity()
       
  1318     {
       
  1319     if ( iDataClients.Count() )
       
  1320         {
       
  1321         if (Error() != KErrNone)
       
  1322             {
       
  1323             //An error has occured when processing rejoin as the activity hasn't been properly wrapped
       
  1324             //up. This error must have happened before any of the clients have been added to the new
       
  1325             //owner as such addition must either collectively succeed or collectively fail. Reinstall
       
  1326             //clients in at the current owner.
       
  1327             for (TInt i = 0; i < iDataClients.Count(); i++)
       
  1328                 {
       
  1329                 if (!(iDataClients[i].iDataClient.Flags() & TCFClientType::EActive))
       
  1330                     {
       
  1331 #ifndef __GCCXML__
       
  1332 					//If the dataclient managed to report idle in the mean time, have him destroyed
       
  1333                     RClientInterface::OpenPostMessageClose(iNode.Id(), iDataClients[i].iDataClient.RecipientId(), TEChild::TDestroy().CRef());
       
  1334 #endif
       
  1335                     }
       
  1336                 iDataClients[i].iDataClient.ClearFlags(TCFClientType::EActivating);
       
  1337 #ifndef __GCCXML__
       
  1338                 //Simulate client leaving on the new owner.
       
  1339                 RClientInterface::OpenPostMessageClose(iDataClients[i].iDataClient.RecipientId(), iDataClients[i].iNewOwner,
       
  1340                 	TEChild::TLeft().CRef());
       
  1341 #endif
       
  1342                 }
       
  1343             }
       
  1344         else
       
  1345             {
       
  1346             //All clear. Remove the clients for good.
       
  1347             for (TInt i = 0; i < iDataClients.Count(); i++)
       
  1348                 {
       
  1349                 iNode.RemoveClient(iDataClients[i].iDataClient.RecipientId());
       
  1350                 }
       
  1351             }
       
  1352         }
       
  1353     iDataClients.Reset();
       
  1354     }
       
  1355 
       
  1356 
       
  1357 void CRejoinDataClientActivity::TCFDataClientJoiningRequest::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient)
       
  1358     {
       
  1359     const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient);  //This message type operates on nodes
       
  1360 	MeshMachine::AMMNodeBase* nodeBase = reinterpret_cast<MeshMachine::AMMNodeBase*>(nodeId.Node().FetchNodeInterfaceL(AMMNodeBase::KInterfaceId));
       
  1361     RNodeInterface* client = NULL;
       
  1362     client = nodeBase->AddClientL(iDataClient, iDataClientType);
       
  1363     client->SetFlags(TCFClientType::EJoining|TCFClientType::EStarted);
       
  1364     RClientInterface::OpenPostMessageClose(nodeId, aSender, TCFPeer::TJoinComplete().CRef());
       
  1365     }
       
  1366 
       
  1367 
       
  1368 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TAwaitingJoinComplete, NetStateMachine::MState, CRejoinDataClientActivity::TContext)
       
  1369 TBool CRejoinDataClientActivity::TAwaitingJoinComplete::Accept()
       
  1370     {
       
  1371 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 13));
       
  1372 	if (iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>())
       
  1373     	{
       
  1374     	return ETrue;
       
  1375     	}
       
  1376     else if (iContext.iMessage.IsMessage<TEBase::TError>())
       
  1377         {
       
  1378 	    iContext.iNodeActivity->SetError(message_cast<TEBase::TError>(iContext.iMessage).iValue);
       
  1379 	    iContext.iNodeActivity->SetIdle();
       
  1380 	    iContext.iMessage.ClearMessageId();
       
  1381         }
       
  1382 	return EFalse;
       
  1383     }
       
  1384 
       
  1385 
       
  1386 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinDataClient, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext)
       
  1387 EXPORT_C void CRejoinDataClientActivity::TRejoinDataClient::DoL()
       
  1388     {
       
  1389 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 14));
       
  1390 	CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity);
       
  1391 
       
  1392 	TCFRejoiningProvider::TRejoinDataClientRequest& rejoinDCMsg = message_cast<TCFRejoiningProvider::TRejoinDataClientRequest>(iContext.iMessage);
       
  1393 	RNodeInterface* subject = iContext.Node().FindClient(rejoinDCMsg.iNodeId1);
       
  1394 	if (NULL == subject //client not found
       
  1395 	    || subject->Flags() & TCFClientType::ELeaving //client leaving/gone
       
  1396 	    || !(subject->Flags() & TCFClientType::EActive)) //client reported idle or never bound to
       
  1397     	{
       
  1398     	User::Leave(KErrNotFound);
       
  1399     	}
       
  1400     if (subject->Flags() & TCFClientType::EActivating) //client requested by someone
       
  1401         {
       
  1402     	User::Leave(KErrInUse);
       
  1403         }
       
  1404 
       
  1405     rejoinActivity->iDataClients.AppendL(TMigrationPairs(*subject, rejoinDCMsg.iNodeId2));
       
  1406 
       
  1407 	CRejoinDataClientActivity::TCFDataClientJoiningRequest msg(subject->RecipientId(), subject->ClientType());
       
  1408 
       
  1409     RClientInterface::OpenPostMessageClose(
       
  1410     	iContext.NodeId(),
       
  1411     	rejoinDCMsg.iNodeId2,
       
  1412     	msg);
       
  1413 
       
  1414     //Set Client being migrated to a new owner.. reference handed over. secure lifetime.
       
  1415     subject->SetFlags(TCFClientType::EActivating);
       
  1416     }
       
  1417 
       
  1418 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TApplyRejoin, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext)
       
  1419 void CRejoinDataClientActivity::TApplyRejoin::DoL()
       
  1420     {
       
  1421 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 15));
       
  1422 	CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity);
       
  1423 	__ASSERT_DEBUG(rejoinActivity->iDataClients.Count(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 16));
       
  1424     for (TInt i = 0; i < rejoinActivity->iDataClients.Count(); i++)
       
  1425         {
       
  1426         RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->iDataClients[i].iDataClient.RecipientId(),
       
  1427         	TCFFlow::TRejoin(rejoinActivity->iDataClients[i].iNewOwner).CRef());
       
  1428         rejoinActivity->iDataClients[i].iDataClient.SetFlags(TCFClientType::ELeaving);
       
  1429         }
       
  1430     rejoinActivity->PostRequestTo(iContext.NodeId(), TCFScpr::TApplyRequest().CRef());
       
  1431     }
       
  1432 
       
  1433 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinLoopTag,NetStateMachine::MStateFork, CRejoinDataClientActivity::TContext)
       
  1434 EXPORT_C TInt CRejoinDataClientActivity::TRejoinLoopTag::TransitionTag()
       
  1435 	{
       
  1436 	if (iContext.iMessage.IsMessage<TCFRejoiningProvider::TRejoinDataClientRequest>())
       
  1437     	{
       
  1438     	return CoreStates::KLoopTag | NetStateMachine::EBackward;
       
  1439     	}
       
  1440 	return MeshMachine::KNoTag | NetStateMachine::EForward;
       
  1441 	}
       
  1442 
       
  1443 //-=========================================================
       
  1444 //
       
  1445 // CommsBinderActivity (parallel)
       
  1446 //
       
  1447 //-=========================================================
       
  1448 
       
  1449 EXPORT_C MeshMachine::CNodeActivityBase* CCommsBinderActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode )
       
  1450     {
       
  1451 	TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
  1452     return new(ELeave)CCommsBinderActivity(aActivitySig, aNode, c);
       
  1453     }
       
  1454 
       
  1455 EXPORT_C CCommsBinderActivity::CCommsBinderActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aNextActivityCount)
       
  1456 :	MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aNextActivityCount),
       
  1457 	TIfStaticFetcherNearestInHierarchy(this)
       
  1458 	{
       
  1459 	}
       
  1460 
       
  1461 //-=========================================================
       
  1462 //
       
  1463 // CCommsBinderActivity
       
  1464 //
       
  1465 // Aggregate class containing common functionality for
       
  1466 // CommsBinderActivity and CCommsBinderCombiningActivity.
       
  1467 //
       
  1468 //-=========================================================
       
  1469 
       
  1470 EXPORT_C TBool CCommsBinderActivity::TDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
       
  1471   	{
       
  1472   	TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
       
  1473   	__ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 17)); //Diagnostic
       
  1474   	if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext))
       
  1475   		{
       
  1476   		return EFalse;
       
  1477   		}
       
  1478 	return ETrue;
       
  1479    	}
       
  1480 
       
  1481 EXPORT_C TBool CCommsBinderActivity::TDefaultDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
       
  1482   	{
       
  1483   	TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
       
  1484   	__ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 18)); //Diagnostic
       
  1485   	if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext, TCFClientType::EDefault))
       
  1486   		{
       
  1487   		return EFalse;
       
  1488   		}
       
  1489 	return ETrue;
       
  1490    	}
       
  1491 
       
  1492 EXPORT_C /*virtual*/ CCommsBinderActivity::~CCommsBinderActivity()
       
  1493 	{
       
  1494 	if(!iBinderRequestParameters.IsNull())
       
  1495 		{
       
  1496 		iBinderRequestParameters.Close();
       
  1497 		}
       
  1498 	}
       
  1499 
       
  1500 EXPORT_C void CCommsBinderActivity::StoreBinder(RNodeInterface* aDataClient)
       
  1501     {
       
  1502     __ASSERT_DEBUG(iPendingBinder == aDataClient || iPendingBinder == NULL, User::Panic(KSpecAssert_ESockCrStaCPRAC, 19));
       
  1503 	iPendingBinder = aDataClient;
       
  1504     }
       
  1505 
       
  1506 EXPORT_C RNodeInterface* CCommsBinderActivity::Binder() const
       
  1507     {
       
  1508 	return iPendingBinder;
       
  1509     }
       
  1510 
       
  1511 EXPORT_C void CCommsBinderActivity::StoreBinderRequestParameters(const RCFParameterFamilyBundleC& aBinderRequestParameters)
       
  1512 	{
       
  1513 	__ASSERT_DEBUG(iBinderRequestParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 20));
       
  1514 	if(! aBinderRequestParameters.IsNull())
       
  1515 		{
       
  1516 		iBinderRequestParameters.Open(aBinderRequestParameters);
       
  1517 		}
       
  1518 	}
       
  1519 
       
  1520 void CCommsBinderActivity::SendCustomFlowProvision()
       
  1521 /**
       
  1522 Send a custom message that provisions a flow with flow parameters
       
  1523 */
       
  1524 	{
       
  1525     __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 21));
       
  1526 
       
  1527 	// Only send the message if we have parameters to send
       
  1528 	if(!iBinderRequestParameters.IsNull())
       
  1529 		{
       
  1530 		RParameterFamily parameterFamily =
       
  1531 			iBinderRequestParameters.FindFamily(KFlowParametersFamily);
       
  1532 
       
  1533 		if(!parameterFamily.IsNull())
       
  1534 			{
       
  1535 			STypeId typeId = STypeId::CreateSTypeId(CFlowRequestParameters::EUid, CFlowRequestParameters::EType);
       
  1536 			CFlowRequestParameters* flowParams =	static_cast<CFlowRequestParameters*>(parameterFamily.FindParameterSet(typeId, RParameterFamily::ERequested));
       
  1537 
       
  1538 				iPendingBinder->PostMessage(
       
  1539 					iNode.Id(),
       
  1540 					TCFInternalEsock::TFlowProvision(
       
  1541 						flowParams->GetFlowParams()
       
  1542 						).CRef()
       
  1543 					);
       
  1544 			}
       
  1545 		}
       
  1546 	}
       
  1547 
       
  1548 
       
  1549 void CCommsBinderActivity::SendBinderResponseToOriginator()
       
  1550 /**
       
  1551 Send out CommsBinderResponse to all originators.
       
  1552 
       
  1553 We send to all originators that have joined up until this point, and store this count
       
  1554 in iOriginatorsCountSnapshot.  See comment in ProcessBindToComplete().
       
  1555 */
       
  1556     {
       
  1557     __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 22));
       
  1558 
       
  1559 	PostRequestTo(
       
  1560 		address_cast<Messages::TNodeId>(FirstOriginator().RecipientId()),
       
  1561 		TCFServiceProvider::TCommsBinderResponse(iPendingBinder->RecipientId()).CRef());
       
  1562 
       
  1563 	iPendingBinder->SetFlags(TCFClientType::EActivating);
       
  1564     }
       
  1565 
       
  1566 void CCommsBinderActivity::BindToComplete()
       
  1567     {
       
  1568     __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 23));
       
  1569 	TUint c = iNode.CountActivities(ActivitySigId());
       
  1570     // Note: this routine can be used with parallel and non-parallel binder activities.  In the
       
  1571     // former case we start with multiple activities and eventually end up with a single one.  In
       
  1572     // the latter case we have a single activity throughout.
       
  1573 	if(c == 1)
       
  1574 		{
       
  1575 		iPendingBinder->ClearFlags(TCFClientType::EActivating);
       
  1576 		}
       
  1577 	iPendingBinder = NULL;
       
  1578     }
       
  1579 
       
  1580 //
       
  1581 // CCommsBinderActivity methods that are embedded transitions/states/stateforks
       
  1582 //
       
  1583 
       
  1584 EXPORT_C RNodeInterface* CCommsBinderActivity::IsDataClientPresent(TNodeContextBase& aContext, TUint aClientFlags)
       
  1585 /**
       
  1586 Check if we have a data client and, if so, store it as the binder for this activity.
       
  1587 
       
  1588 @param aContext Node context
       
  1589 @param aClientFlags client flags to use in iterator check
       
  1590 @return ETrue if data client present, else EFalse.
       
  1591 */
       
  1592 	{
       
  1593 	// Be careful not to use a client to which we have already sent TDestroy previously.
       
  1594 	// Find the first data client that does not have the ELeaving flag set.  If all are
       
  1595 	// marked ELeaving then return EFalse - they are on the way out and will disappear
       
  1596 	// eventually.  The effect will be that a new data client will be created.
       
  1597 	RNodeInterface* dataClient = aContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, aClientFlags), TClientType(0, TCFClientType::ELeaving));
       
  1598 	return dataClient;
       
  1599 	}
       
  1600 
       
  1601 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
       
  1602 EXPORT_C TInt CCommsBinderActivity::TNoTagOrUseExisting::TransitionTag()
       
  1603 	{
       
  1604 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 24));
       
  1605 	TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
       
  1606 
       
  1607 	// Save away the parameters sent to us so that they are accessible during the activity
       
  1608 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1609 	CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1610 	intf->StoreBinderRequestParameters(msg.iFamilyBundle);
       
  1611 
       
  1612 	if(msg.iValue == TSubConnOpen::EAttachToDefault)
       
  1613 		{
       
  1614 		RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext);
       
  1615 		if (dc)
       
  1616 			{
       
  1617 			__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1618 			CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1619 
       
  1620 			intf->StoreBinder(dc);
       
  1621 			return CoreStates::KUseExisting;
       
  1622 			}
       
  1623 		}
       
  1624 	return MeshMachine::KNoTag;
       
  1625 	}
       
  1626 
       
  1627 //MZTODO - logic of:
       
  1628 //TNoTagOrWaitForIncomingOrUseExisting
       
  1629 //&
       
  1630 //TNoTagOrWaitForIncomingOrUseExistingDefault
       
  1631 //has been copied but does not seem right, as both use EDefault?
       
  1632 //Why?
       
  1633 
       
  1634 //[401TODO] DL : Only one of TNoTagOrWaitForIncomingOrUseExisting(Default) is used, is it ok to nuke one?
       
  1635 
       
  1636 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
       
  1637 EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting::TransitionTag()
       
  1638 	{
       
  1639 	TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
       
  1640 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 25));
       
  1641 
       
  1642     if (msg.iValue == TSubConnOpen::EWaitForIncoming)
       
  1643     	{
       
  1644     	return CoreNetStates::KWaitForIncoming;
       
  1645     	}
       
  1646 
       
  1647 	else
       
  1648 		{
       
  1649 		RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault);
       
  1650 		if (dc)
       
  1651 			{
       
  1652 			__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1653 			CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1654 
       
  1655 			intf->StoreBinder(dc);
       
  1656 			return CoreStates::KUseExisting;
       
  1657 			}
       
  1658 		}
       
  1659 
       
  1660 	return MeshMachine::KNoTag;
       
  1661 	}
       
  1662 
       
  1663 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault, NetStateMachine::MStateFork, CCommsBinderActivity::TContext)
       
  1664 EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault::TransitionTag()
       
  1665 	{
       
  1666 	TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
       
  1667 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 26));
       
  1668 
       
  1669 	if(msg.iValue == TSubConnOpen::EAttachToDefault)
       
  1670 		{
       
  1671 		RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault);
       
  1672 		if (dc)
       
  1673 			{
       
  1674 			__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1675 			CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1676 
       
  1677 			intf->StoreBinder(dc);
       
  1678 			return CoreStates::KUseExisting;
       
  1679 			}
       
  1680 		}
       
  1681 	else if (msg.iValue == TSubConnOpen::EWaitForIncoming)
       
  1682     	{
       
  1683     	return CoreNetStates::KWaitForIncoming;
       
  1684     	}
       
  1685 	return MeshMachine::KNoTag;
       
  1686 	}
       
  1687 
       
  1688 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TStorePendingBinder, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
       
  1689 EXPORT_C void CCommsBinderActivity::TStorePendingBinder::DoL()
       
  1690 	{
       
  1691 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 27));
       
  1692 	message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
       
  1693 
       
  1694 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1695 	CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1696 
       
  1697     intf->StoreBinder(iContext.iPeer);
       
  1698 	}
       
  1699 
       
  1700 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendBinderResponse, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
       
  1701 EXPORT_C void CCommsBinderActivity::TSendBinderResponse::DoL()
       
  1702 	{
       
  1703 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 28));
       
  1704 
       
  1705 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1706 	CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1707 
       
  1708     intf->SendBinderResponseToOriginator();
       
  1709 	}
       
  1710 
       
  1711 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendCustomFlowProvision, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext)
       
  1712 EXPORT_C void CCommsBinderActivity::TSendCustomFlowProvision::DoL()
       
  1713 	{
       
  1714 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 29));
       
  1715 
       
  1716 	__ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported));
       
  1717 	CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1718 
       
  1719     intf->SendCustomFlowProvision();
       
  1720 	}
       
  1721 
       
  1722 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TAwaitingBindToComplete, NetStateMachine::MState, PRStates::TContext)
       
  1723 EXPORT_C TBool CCommsBinderActivity::TAwaitingBindToComplete::Accept()
       
  1724 	{
       
  1725 	CoreNetStates::TAwaitingBindToComplete awaitingBindToComplete(iContext);
       
  1726 	if (awaitingBindToComplete.Accept())
       
  1727 		{
       
  1728 	    CCommsBinderActivity* binderActivity = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId));
       
  1729 	    __ASSERT_DEBUG(binderActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 30));
       
  1730 	    binderActivity->BindToComplete();
       
  1731 		iContext.Node().DestroyOrphanedDataClients();
       
  1732 		return ETrue;
       
  1733 		}
       
  1734 	return EFalse;
       
  1735 	}
       
  1736 
       
  1737 //-=========================================================
       
  1738 //
       
  1739 //CNoBearer Activity
       
  1740 //
       
  1741 //-=========================================================
       
  1742 
       
  1743 CNoBearer::CNoBearer(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount)
       
  1744 :	MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aActivitiesCount),
       
  1745 	ABindingActivity(aNode.Id()),
       
  1746     TIfStaticFetcherNearestInHierarchy(this)
       
  1747 	{
       
  1748 	}
       
  1749 
       
  1750 /*virtual*/ CNoBearer::~CNoBearer()
       
  1751 	{
       
  1752 	iNoBearerParameters.Close();
       
  1753 	}
       
  1754 
       
  1755 EXPORT_C MeshMachine::CNodeActivityBase* CNoBearer::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1756 	{
       
  1757 	TUint c = GetNextActivityCountL(aActivitySig,aNode);
       
  1758     return new(ELeave)CNoBearer(aActivitySig, aNode, c);
       
  1759 	}
       
  1760 
       
  1761 EXPORT_C TNodePeerId& CNoBearer::GetOriginator()
       
  1762     {
       
  1763     __ASSERT_DEBUG(iOriginators.Count() == 1, User::Panic(KSpecAssert_ESockCrStaCPRAC, 31));
       
  1764     return iOriginators[0];
       
  1765     }
       
  1766 
       
  1767 EXPORT_C void CNoBearer::ReturnInterfacePtrL(CoreActivities::ABindingActivity*& aInterface)
       
  1768 	{
       
  1769 	aInterface = this;
       
  1770 	}
       
  1771 
       
  1772 EXPORT_C TBool CNoBearer::TServiceProviderMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
       
  1773 	{
       
  1774 	TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
       
  1775   	__ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 32)); //Diagnostic
       
  1776   	if (c == 1 || aContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) != 0)
       
  1777   		{
       
  1778   		return EFalse;
       
  1779   		}
       
  1780 	return ETrue;
       
  1781 	}
       
  1782 
       
  1783 EXPORT_DEFINE_SMELEMENT(CNoBearer::TRequestCommsBinder, NetStateMachine::MStateTransition, CNoBearer::TContext)
       
  1784 EXPORT_C void CNoBearer::TRequestCommsBinder::DoL()
       
  1785 	{
       
  1786 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1787   	CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1788 
       
  1789 	RNodeInterface* sp = iContext.Node().ServiceProvider();
       
  1790 	__ASSERT_DEBUG(sp, User::Panic(KCorePrPanic, KPanicNoServiceProvider));
       
  1791 
       
  1792 	TSubConnOpen::TSubConnType type = TSubConnOpen::EAttachToDefault;
       
  1793 	if (!(noBearer.GetOriginator().Flags() & TCFClientType::EDefault))
       
  1794     	{
       
  1795     	type = TSubConnOpen::ECreateNew;
       
  1796     	}
       
  1797 
       
  1798 	noBearer.PostRequestTo(
       
  1799 			*sp,
       
  1800 			TCFServiceProvider::TCommsBinderRequest(
       
  1801 					type, noBearer.iNoBearerParameters
       
  1802 					).CRef()
       
  1803 			);
       
  1804 	}
       
  1805 
       
  1806 EXPORT_DEFINE_SMELEMENT(CNoBearer::TStoreRequestParameters, NetStateMachine::MStateTransition, CNoBearer::TContext)
       
  1807 EXPORT_C void CNoBearer::TStoreRequestParameters::DoL()
       
  1808 	{
       
  1809 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1810   	CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1811 	const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage);
       
  1812 	__ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 33)); // handle should be empty when this fn is called
       
  1813 	if(noBearerMessage.iFamilyBundle.IsNull())
       
  1814 		{
       
  1815 		noBearer.iNoBearerParameters.Open();
       
  1816 		}
       
  1817 		else
       
  1818 		{
       
  1819 		noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle);
       
  1820 		}
       
  1821 	}
       
  1822 
       
  1823 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrDataClientsToStart, NetStateMachine::MStateFork, CNoBearer::TContext)
       
  1824 TInt CNoBearer::TNoTagOrDataClientsToStart::TransitionTag()
       
  1825 	{
       
  1826 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1827   	CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1828 
       
  1829 	const TNodePeerId& originator = activity.GetOriginator();
       
  1830 	__ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 34));
       
  1831 
       
  1832 	if (activity.Error() == KErrNone && (originator.Flags() & (TCFClientType::EStarting|TCFClientType::EStarted|TCFClientType::ELeaving)) == 0)
       
  1833 		{
       
  1834 		//Start dc
       
  1835 		return CoreNetStates::KDataClientsToStart;
       
  1836 		}
       
  1837 	//Finish the activity
       
  1838 	return MeshMachine::KNoTag;
       
  1839 	}
       
  1840 
       
  1841 EXPORT_DEFINE_SMELEMENT(CNoBearer::TStartOriginatingDataClient, NetStateMachine::MStateTransition, CNoBearer::TContext)
       
  1842 void CNoBearer::TStartOriginatingDataClient::DoL()
       
  1843     {
       
  1844 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1845   	CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1846 	TNodePeerId& originator = activity.GetOriginator();
       
  1847 	__ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 35));
       
  1848 	activity.PostRequestTo(originator.Peer(), TCFDataClient::TStart().CRef());
       
  1849 	originator.SetFlags(TCFClientType::EStarting);
       
  1850     }
       
  1851 
       
  1852 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresent, NetStateMachine::MStateFork, CNoBearer::TContext)
       
  1853 EXPORT_C TInt CNoBearer::TNoTagOrBearerPresent::TransitionTag()
       
  1854 	{
       
  1855 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1856 	CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity);
       
  1857 	const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage);
       
  1858 	__ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 36)); // should not yet be set when this fn is called
       
  1859 	noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle);
       
  1860 
       
  1861 	CoreNetStates::TNoTagOrBearerPresent fork(iContext);
       
  1862 	return fork.TransitionTag();
       
  1863 	}
       
  1864 
       
  1865 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresentForAutostart, NetStateMachine::MStateFork, CNoBearer::TContext)
       
  1866 EXPORT_C TInt CNoBearer::TNoTagOrBearerPresentForAutostart::TransitionTag()
       
  1867 	{
       
  1868  	TInt cntrlClients = iContext.Node().CountClients<TDefaultClientMatchPolicy>(
       
  1869  								/*include*/TClientType(TCFClientType::ECtrl));
       
  1870  	if (cntrlClients > 0 &&
       
  1871  		iContext.Node().ServiceProvider() &&
       
  1872  		!(iContext.Node().ServiceProvider()->Flags() & TCFClientType::EStarted))
       
  1873  		{
       
  1874  		//This fork calculates if the NoBearer activity (which this fork has been implemented for)
       
  1875  		//should attempt to autostart the service provider when returning it to the sender of TNoBearer.
       
  1876  		//The philosphy here is that if the local node doesn't have a control client, then there's noone
       
  1877  		//that could posibly start it. It will hence decide to autostart as the top layer of what looks
       
  1878  		//like an implicit connection. In the future this autostart behaviour should become a specialty
       
  1879  		//of someone more concrete (rather than generic function). We are speculating about the implicit
       
  1880  		//top layer that could acquire this function if it ever comes into being.
       
  1881  		return CoreNetStates::KBearerPresent;
       
  1882  		}
       
  1883  	return KNoTag;
       
  1884 	}
       
  1885 
       
  1886 
       
  1887 //-=========================================================
       
  1888 //
       
  1889 //CStartActivity Activity
       
  1890 //
       
  1891 //-=========================================================
       
  1892 CStartActivity::CStartActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1893 	:	MeshMachine::CNodeRetryActivity(aActivitySig, aNode),
       
  1894 		CoreActivities::ABindingActivity(aNode.Id()),
       
  1895 		TIfStaticFetcherNearestInHierarchy(this)
       
  1896 		{
       
  1897 		}
       
  1898 
       
  1899 EXPORT_C CStartActivity::~CStartActivity()
       
  1900 	{
       
  1901 	}
       
  1902 
       
  1903 EXPORT_C MeshMachine::CNodeActivityBase* CStartActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1904     {
       
  1905     return new (ELeave) CStartActivity(aActivitySig, aNode);
       
  1906     }
       
  1907 
       
  1908 //-=========================================================
       
  1909 //
       
  1910 //Gone Down Activity
       
  1911 //
       
  1912 //-=========================================================
       
  1913 MeshMachine::CNodeActivityBase* CGoneDownActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1914     {
       
  1915     CGoneDownActivity* self = new (ELeave) CGoneDownActivity(aActivitySig,aNode);
       
  1916     return self;
       
  1917     }
       
  1918 
       
  1919 CGoneDownActivity::CGoneDownActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
  1920 :	MeshMachine::CNodeRetryActivity(aActivitySig, aNode)
       
  1921 	{
       
  1922 	}
       
  1923 
       
  1924 CGoneDownActivity::~CGoneDownActivity()
       
  1925     {
       
  1926     //This is a gone down activity. Error mode is its only/natural state
       
  1927     //CGoneDownActivity inherits ultimatelly from CNodeActivityBase, which
       
  1928     //will attempt to interpret the error mode as a failure to execute (and
       
  1929     //auto respond to orignators), which we don't want. Hence clearing
       
  1930     //the error and allowing 'this' to die peacefully.
       
  1931     SetError(KErrNone);
       
  1932     }
       
  1933 
       
  1934 void CGoneDownActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const TStateTriple& aFirst)
       
  1935 	{
       
  1936 	//399TODO: for the moment ignore duplicated TGoneDown messages
       
  1937 	//but this needs to be fixed (someone is sending TGoneDown from TSendDataClientStopped
       
  1938 	//hence the problem)
       
  1939 
       
  1940 	//ASSERT(IsIdle());
       
  1941 	if (!IsIdle())
       
  1942 		{
       
  1943 		return;
       
  1944 		}
       
  1945 
       
  1946 	//This activity provides service for only one single requestor at a time.
       
  1947 	__ASSERT_DEBUG(iOriginators.Count()==0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 37)); //Diagnostic panic
       
  1948 
       
  1949     TCFControlClient::TGoneDown& msg = message_cast<TCFControlClient::TGoneDown>(aContext.iMessage);
       
  1950     SetError(msg.iValue1);
       
  1951     iGoneDownApId = msg.iValue2;
       
  1952 
       
  1953 	MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->starting activity"), this));
       
  1954 	NetStateMachine::ACore::Start(&aContext, aFirst);
       
  1955 
       
  1956 	MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->activity started"), this));
       
  1957     (void)aOriginator;
       
  1958 	}
       
  1959 
       
  1960 //Find next DC to rebind
       
  1961 TBool CGoneDownActivity::IsIdle() const
       
  1962 	{
       
  1963 	return NetStateMachine::ACore::IsIdle();
       
  1964 	}
       
  1965 
       
  1966 DEFINE_SMELEMENT(CGoneDownActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CGoneDownActivity::TContext)
       
  1967 void CGoneDownActivity::TSendErrorRecoveryReq::DoL()
       
  1968     {
       
  1969 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  1970 	CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity);
       
  1971 
       
  1972 	//TInt error = ExtractErrorCode(iContext.iMessage);
       
  1973     TErrContext ctx(iContext.NodeId(), TCFControlClient::TGoneDown::Id(), activity.ActivitySigId(), TStateChange(0, activity.Error()));
       
  1974     ctx.iInfo = (TAny*)activity.iGoneDownApId;
       
  1975 	TEErrorRecovery::TErrorRecoveryRequest msg(ctx);
       
  1976 
       
  1977     //We can not set SetSentTo() to Control Provider, because the response may not be coming from it
       
  1978     //(for example it could be coming from the MCpr and we could be the SCpr).
       
  1979     //Normally this would be a problem because any unrelated TError message arriving to the node
       
  1980     //and presented to the awaiting state would easily be confused with the response (TError ==
       
  1981     //no recovery on the MCpr == EPropagate).
       
  1982     //We avoid the problem by checking all arriving TError messages if they are adressed to our activity.
       
  1983     __ASSERT_DEBUG(iContext.Node().ControlProvider(), User::Panic(KCorePrPanic, KPanicNoControlProvider));
       
  1984     activity.PostRequestTo(*iContext.Node().ControlProvider(),
       
  1985     	TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef());
       
  1986     activity.ClearPostedTo();
       
  1987     }
       
  1988 
       
  1989 DEFINE_SMELEMENT(CGoneDownActivity::TIgnoreOrPropagate, NetStateMachine::MStateFork, CGoneDownActivity::TContext)
       
  1990 TInt CGoneDownActivity::TIgnoreOrPropagate::TransitionTag()
       
  1991     {
       
  1992     __ASSERT_DEBUG(iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 38));
       
  1993     RNodeInterface* sp = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted));
       
  1994     if (sp)
       
  1995         {
       
  1996         return CoreStates::KIgnore | NetStateMachine::EForward;
       
  1997         }
       
  1998     //There is no started service provider, the reconnection, mobility, etc must have failed,
       
  1999     //continue with tearing this layer down.
       
  2000     CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity);
       
  2001     TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse;
       
  2002     resp.iAction=TErrResponse::EPropagate;
       
  2003     __ASSERT_DEBUG(activity.Error()!=KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 39));
       
  2004     resp.iError = activity.Error();
       
  2005     return CoreStates::KPropagate | NetStateMachine::EForward;
       
  2006 	}
       
  2007 
       
  2008 
       
  2009 EXPORT_DEFINE_SMELEMENT(CStartActivity::TAwaitingBindToCompleteOrCancel, NetStateMachine::MState, CStartActivity::TContext)
       
  2010 TBool CStartActivity::TAwaitingBindToCompleteOrCancel::Accept()
       
  2011 	{
       
  2012 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity));
       
  2013 	if (iContext.iMessage.IsMessage<TEBase::TCancel>())
       
  2014 		{
       
  2015 		iContext.iNodeActivity->SetError(KErrCancel);
       
  2016 		iContext.iMessage.ClearMessageId();
       
  2017 		return EFalse;
       
  2018 		}
       
  2019 	else
       
  2020 		{
       
  2021 		CoreNetStates::TAwaitingBindToComplete state(iContext);
       
  2022 		return state.Accept();
       
  2023 		}
       
  2024 	}
       
  2025 } //PRActivities
       
  2026 
       
  2027 EXPORT_DEFINE_SMELEMENT(PRDataClientStopActivity::TNoTagOrProviderStopped, NetStateMachine::MStateFork, PRDataClientStopActivity::TContext)
       
  2028 EXPORT_C TInt PRDataClientStopActivity::TNoTagOrProviderStopped::TransitionTag()
       
  2029 	{
       
  2030 	iContext.iNodeActivity->SetError(message_cast<TCFDataClient::TStop>(iContext.iMessage).iValue);
       
  2031     if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(
       
  2032 	    TClientType(TCFClientType::EData, TCFClientType::EStarted)) != NULL)
       
  2033 		{
       
  2034 		// At least one started data client
       
  2035         return MeshMachine::KNoTag;
       
  2036 		}
       
  2037 	return CoreNetStates::KProviderStopped;
       
  2038     }
       
  2039 
       
  2040 
       
  2041