datacommsserver/esockserver/ssock/ss_conn.cpp
changeset 0 dfb7c4ff071f
child 1 21d2ab05f085
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2005-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 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalTechnology
       
    19 */
       
    20 
       
    21 #define SYMBIAN_NETWORKING_UPS
       
    22 
       
    23 #include <comms-infras/ss_log.h>
       
    24 #include <comms-infras/ss_nodemessages.h>
       
    25 #include <comms-infras/ss_nodemessages_serviceprovider.h>
       
    26 #include <comms-infras/ss_nodemessages_factory.h>
       
    27 #include <comms-infras/ss_nodemessages_subconn.h>
       
    28 #include "SS_conn.H"
       
    29 #include "ss_connstates.h"
       
    30 #include <comms-infras/ss_datamonitoringprovider.h>
       
    31 #include <comms-infras/ss_roles.h>
       
    32 #include <ss_glob.h>
       
    33 
       
    34 #include <comms-infras/ss_coreprstates.h>
       
    35 #include <comms-infras/ss_corepractivities.h>
       
    36 
       
    37 #include <elements/sm_core.h>
       
    38 #include <comms-infras/es_parameterbundle.h>
       
    39 #include <comms-infras/es_commsdataobject.h>
       
    40 #include <comms-infras/ss_commsdataobject.h>
       
    41 #include <nifman.h>
       
    42 #include <comms-infras/nifprvar.h>
       
    43 
       
    44 #include <in_sock.h> //KAfInet only
       
    45 
       
    46 #include <elements/nm_signatures.h>
       
    47 
       
    48 #include <comms-infras/ss_msgintercept.h>
       
    49 
       
    50 #ifdef SYMBIAN_NETWORKING_UPS
       
    51 #include <comms-infras/upsmessages.h>		// reference from ESock to UpsCoreProviders - should we move the UPS messages into ESock?
       
    52 #endif
       
    53 
       
    54 #ifdef _DEBUG
       
    55 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    56 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    57 // UNCOMMENT IF INSERTING AN ASSERT
       
    58 //_LIT(KSpecAssert_ESockSSocks_cn, "ESockSSocks_cn.");
       
    59 #endif
       
    60 
       
    61 
       
    62 
       
    63 using namespace ESock;
       
    64 using namespace SubSessActivities;
       
    65 using namespace NetStateMachine;
       
    66 using namespace ConnActivities;
       
    67 using namespace SubSessStates;
       
    68 using namespace CoreStates;
       
    69 using namespace Elements;
       
    70 using namespace Messages;
       
    71 using namespace MeshMachine;
       
    72 using namespace Den;
       
    73 
       
    74 //We reserve space for two preallocated activities that may start concurrently on the connection
       
    75 //node: destroy (connection close) and connection stop.
       
    76 static const TUint KDefaultMaxPreallocatedActivityCount = 2;
       
    77 static const TUint KMaxPreallocatedActivitySize = sizeof(CNodeRetryParallelActivity) + sizeof(APreallocatedOriginators<4>);
       
    78 static const TUint KConnectionPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize;
       
    79 
       
    80 //
       
    81 //Activities serving client (RConnection) requests
       
    82 namespace ConnectionStartActivity
       
    83 {
       
    84  //Synchronised activity, must wait for stop (exclusive with close)
       
    85 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, ConnectionStart, TCFInternalEsock::TSubSess, ConnActivities::CStartAttachActivity::NewStartConnectionActivityL)
       
    86 	FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ECNStart>, MeshMachine::TNoTag)
       
    87 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
       
    88 	
       
    89 	// If the IPC was ECNSetStartPrefs we expect another IPC to start the connection 
       
    90 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessStartBlockedByStop, ConnActivities::CStartAttachActivity::TNoTagOrStartPrefsSetTag)
       
    91 	NODEACTIVITY_ENTRY(ConnActivities::CStartAttachActivity::KStartPrefsSetTag, MeshMachine::TDoNothing, SubSessStates::TAwaitingIPC<ECNStart>, ConnActivities::CStartAttachActivity::TStartPrefsSetTag)
       
    92 	THROUGH_NODEACTIVITY_ENTRY(ConnActivities::CStartAttachActivity::KStartPrefsSetTag, SubSessStates::TAcquireMessageOwnership, ConnActivities::CStartAttachActivity::TStartPrefsSetTag)
       
    93 	THROUGH_NODEACTIVITY_ENTRY(ConnActivities::CStartAttachActivity::KStartPrefsSetTag, ConnStates::TParseECNStart, MeshMachine::TNoTag)
       
    94 	
       
    95 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TClearProgressQueue, MeshMachine::TNoTag)
       
    96 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TSendStartingSelectionStateChange, MeshMachine::TNoTag)
       
    97 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TRequestCSRCreation, TECABState<CoreNetStates::TAwaitingCSRCreated>, MeshMachine::TNoTag)
       
    98 	
       
    99 
       
   100 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessCSRCreation, MeshMachine::TNoTag)
       
   101 
       
   102 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TSelectMetaPlane, ConnActivities::CStartAttachActivity::TAwaitingSelectCompleteOrError, MeshMachine::TNoTagOrErrorTag)
       
   103 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
       
   104 
       
   105 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TJoinReceivedMcpr, TECABState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTag)
       
   106 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TRequestCommsBinderFromMcpr, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, MeshMachine::TNoTagOrErrorTag)
       
   107 	LAST_NODEACTIVITY_ENTRY(KErrorTag, CoreActivities::ABindingActivity::TSendBindToComplete) //Terminate the activity
       
   108 	
       
   109 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TSendFinishedSelectionStateChange, MeshMachine::TNoTag)
       
   110 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessBinderResponseForCpr, TECABState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTag)
       
   111 
       
   112 #ifdef SYMBIAN_NETWORKING_UPS
       
   113 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnActivities::CStartAttachActivity::TSendBindToComplete, MeshMachine::TNoTag)
       
   114 	NODEACTIVITY_ENTRY(KNoTag, CStartAttachActivity::TSendPolicyCheckRequestToServiceProvider, TAcceptErrorState<TAwaitingMessageState<UpsMessage::TPolicyCheckResponse> >, CStartAttachActivity::TNoTagOrUpsErrorTag)
       
   115   	//<legacy begin> - requesting and joining the default scpr just to satisfy the subconn related datamonitoring API.
       
   116   	//If the default scpr isn't there, we'll ignore the error here but we will dissallow subscribing to subcon-related data monitoring.
       
   117   	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TRequestCommsBinder, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, MeshMachine::TNoTagOrErrorTag)
       
   118  #endif
       
   119 
       
   120 
       
   121 #ifndef SYMBIAN_NETWORKING_UPS
       
   122   	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnActivities::CStartAttachActivity::TSendBindToComplete, MeshMachine::TNoTag)
       
   123   	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TRequestCommsBinder, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, MeshMachine::TNoTagOrErrorTag)
       
   124 #endif
       
   125 
       
   126 
       
   127   	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TJoinReceivedSCpr, TECABState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTag)
       
   128   	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToComplete, MeshMachine::TNoTag)
       
   129   	// Act on cancellation errors, ignore all others.
       
   130   	ROUTING_NODEACTIVITY_ENTRY(KErrorTag, ConnStates::TErrorOrCancel)
       
   131   	THROUGH_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TClearError, MeshMachine::TNoTag)
       
   132   	//</legacy end>>
       
   133 
       
   134 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnActivities::CStartAttachActivity::TSubscribeForAvailability, MeshMachine::TNoTag)
       
   135 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, ConnActivities::CStartAttachActivity::TNoTagOrWaitAvailable)
       
   136 	NODEACTIVITY_ENTRY(ConnActivities::CStartAttachActivity::KWaitAvailable, MeshMachine::TDoNothing, ConnActivities::CStartAttachActivity::TAwaitingAvailableOrError, MeshMachine::TNoTag)
       
   137 
       
   138 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TStartConnection, TAcceptErrorState<CoreNetStates::TAwaitingStarted>, CoreStates::TCancelOrErrorOrTag<KNoTag>)
       
   139 	// Handle error during start
       
   140 	THROUGH_NODEACTIVITY_ENTRY(KErrorTag, ConnStates::TGenerateConnectionDownProgress, ConnActivities::CStartAttachActivity::TErrorTagOrWaitAvailableBackward)
       
   141 	
       
   142 	LAST_NODEACTIVITY_ENTRY(KNoTag,  ConnStates::TGenerateConnectionUpProgress )
       
   143 
       
   144 	// Handle error during start.
       
   145 	THROUGH_NODEACTIVITY_ENTRY(ConnActivities::CStartAttachActivity::KCancelTag, MeshMachine::TDoNothing, MeshMachine::TErrorTag)	// just a tag
       
   146 #ifdef SYMBIAN_NETWORKING_UPS
       
   147 	THROUGH_NODEACTIVITY_ENTRY(CStartAttachActivity::KUpsErrorTag, TDoNothing, MeshMachine::TErrorTag)
       
   148 #endif
       
   149 	NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TSendClientLeavingRequestToServiceProviders, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
       
   150 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSetIdleIfNoServiceProviders, MeshMachine::TAwaitingLeaveComplete, ConnectionCleanupActivities::TNoTagOrNoTagBackwards)
       
   151 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
   152 NODEACTIVITY_END()
       
   153 }
       
   154 
       
   155 namespace ConnectionAttachActivity
       
   156 {
       
   157 typedef SubSessStates::TAwaitingSecuredIpc<SubSessStates::TAwaitingIPC<ECNAttach>, ECapabilityNetworkServices> TAwaitingSecuredAttachIpc;
       
   158 
       
   159 //Synchronised activity, must wait for stop (exclusive with close)
       
   160 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionAttach, ConnectionAttach, TCFInternalEsock::TSubSess, ConnActivities::CStartAttachActivity::NewStartConnectionActivityL)
       
   161 #ifdef SYMBIAN_NETWORKING_UPS
       
   162 	// UPS support.  Platform Security check now takes place in the Cpr as part of the control client join activity.
       
   163 	FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ECNAttach>, MeshMachine::TNoTag)
       
   164 #else
       
   165 	FIRST_NODEACTIVITY_ENTRY(TAwaitingSecuredAttachIpc, MeshMachine::TNoTag)
       
   166 #endif
       
   167 	// NOTE: TAcquireMessageOwnership MUST occur before any blocking takes place, otherwise the Player will
       
   168 	// complete the message upon return from the blocked activity.
       
   169 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, CoreNetStates::TNoTagBlockedByStop)
       
   170 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessAttachBlockedByStop, TECABState<CoreNetStates::TAwaitingCSRCreated>, MeshMachine::TNoTag)
       
   171 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessCSRCreation, MeshMachine::TNoTag)
       
   172 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TSelectMetaPlane, ConnActivities::CStartAttachActivity::TAwaitingSelectCompleteOrError, MeshMachine::TNoTagOrErrorTag)
       
   173 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
       
   174 
       
   175 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TJoinReceivedMcpr, TECABState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTag)
       
   176     NODEACTIVITY_ENTRY(KNoTag, ConnStates::TRequestCommsBinderFromMcpr, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, MeshMachine::TNoTagOrErrorTag)
       
   177 	LAST_NODEACTIVITY_ENTRY(KErrorTag, CoreActivities::ABindingActivity::TSendBindToComplete) //Terminate the activity
       
   178 
       
   179     NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessBinderResponseForCpr, TECABState<CoreStates::TAwaitingJoinComplete>, CStartAttachActivity::TNoTagOrLegacyAttach)
       
   180 
       
   181     //New Attach - go here
       
   182 	LAST_NODEACTIVITY_ENTRY(KNoTag, ConnActivities::CStartAttachActivity::TSendBindToComplete)
       
   183 	//Legacy Attach - go here
       
   184 	LAST_NODEACTIVITY_ENTRY(CStartAttachActivity::KExecuteLegacyAttach, ConnActivities::CStartAttachActivity::TSendBindToCompleteAndCompleteLegacyAttach)
       
   185 NODEACTIVITY_END()
       
   186 }
       
   187 
       
   188 namespace ConnectionStopActivity
       
   189 {
       
   190 //Synchronised activity, must wait for start to finish
       
   191 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStop, ConnectionStop, TCFInternalEsock::TSubSess, CPreallocatedESockClientActivity::New)
       
   192 	FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ECNStop>, MeshMachine::TNoTag)
       
   193 	// NOTE: TAcquireMessageOwnership MUST occur before any blocking takes place, otherwise the Player will
       
   194 	// complete the message upon return from the blocked activity.
       
   195 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, CoreNetStates::TActiveOrNoTagBlockedByGoneDown)
       
   196 	THROUGH_NODEACTIVITY_ENTRY(KActiveTag, ConnStates::TCancelStartOrAttachConnection, ConnStates::TNoTagOrNoBearerBlockedByStartOrAttach)
       
   197 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TCancelAndCloseZone0ClientExtIfaces, MeshMachine::TNoTag)
       
   198     THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TCancelAllLegacyRMessage2Activities, ConnStates::TNoTagBlockedByLegacyRMessage2Activities)
       
   199 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TSendStopConnection, TECABState<CoreNetStates::TAwaitingStopped>, MeshMachine::TNoTag)
       
   200     THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TGenerateConnectionDownProgress, MeshMachine::TNoTag)
       
   201 
       
   202 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProviders, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
       
   203 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSetIdleIfNoServiceProviders, MeshMachine::TAwaitingLeaveComplete, ConnectionCleanupActivities::TNoTagOrNoTagBackwards)
       
   204 	
       
   205 	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, MeshMachine::TDoNothing)
       
   206 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
   207 NODEACTIVITY_END()
       
   208 }
       
   209 
       
   210 /**
       
   211 	Legacy RConnection::Stop(TSubConnectionUniqueId aSubConnectionUniqueId) implementation
       
   212 */
       
   213 namespace ConnectionStopSCPRActivity
       
   214 {
       
   215 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStopSCPR, ConnectionStopSCPR, TCFInternalEsock::TSubSess, CESockClientActivityBase::NewL)
       
   216 	FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCPSStop>, MeshMachine::TNoTag)
       
   217 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
       
   218 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TConnectionSendStopSCPR, MeshMachine::TNoTag)
       
   219 	NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, TECABState<CoreNetStates::TAwaitingStopped>, MeshMachine::TNoTag)
       
   220 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
   221 NODEACTIVITY_END()
       
   222 }
       
   223 
       
   224 /**
       
   225 	Legacy RConnection::EnumerateConnections implementation
       
   226 */
       
   227 namespace EnumerateConnectionsActivity
       
   228 {
       
   229 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionEnumerateConnections, EnumerateConnections, TCFInternalEsock::TSubSess, CEnumerateConnectionsActivity::NewL)
       
   230 	FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ECNEnumerateConnections>, MeshMachine::TNoTag)
       
   231 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
       
   232 
       
   233 	// Find the tier manager and query it.
       
   234 	NODEACTIVITY_ENTRY(KNoTag, CTierManagerActivity::TFindTierManager, TECABState<CTierManagerActivity::TAwaitingTierManager>, MeshMachine::TErrorTagOr<MeshMachine::TTag<KNoTag> >)
       
   235 		LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
       
   236 
       
   237 	NODEACTIVITY_ENTRY(KNoTag, CTierManagerActivity::TJoinTierManager, TECABState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTag)
       
   238 
       
   239 	NODEACTIVITY_ENTRY(KNoTag, TQueryTierStatus, TECABState<TAwaitingTierStatus>, MeshMachine::TNoTag)
       
   240 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, TCacheConnectionInfo, MeshMachine::TNoTag)
       
   241 
       
   242 	LAST_NODEACTIVITY_ENTRY(KNoTag, TCompleteClient)
       
   243 NODEACTIVITY_END()
       
   244 }
       
   245 
       
   246 namespace ConnectionGoneUpActivity
       
   247 {
       
   248 DECLARE_DEFINE_NODEACTIVITY(ECFActivityAny, ConnectionGoneUp, TCFControlClient::TGoneUp)
       
   249 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneUp, MeshMachine::TNoTag)
       
   250 	LAST_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TGenerateConnectionUpProgress)
       
   251 NODEACTIVITY_END()
       
   252 }
       
   253 
       
   254 namespace ConnectionCloseActivity
       
   255 { //Cancells all other running activities
       
   256 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDestroy, ConnectionClose, TCFInternalEsock::TSubSess, CCloseActivity::New)
       
   257 	FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ECNClose>, MeshMachine::TNoTag)
       
   258 	// NOTE: TAcquireMessageOwnership MUST occur before any blocking takes place, otherwise the Player will
       
   259 	// complete the message upon return from the blocked activity.
       
   260 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, ConnStates::TActiveOrNoTagBlockedByStopOrGoneDown)
       
   261 	THROUGH_NODEACTIVITY_ENTRY(KActiveTag, ConnStates::TCancelStartOrAttachConnection, ConnStates::TNoTagBlockedByStartOrAttach)
       
   262 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TCancelAndCloseClientExtIfaces, ConnStates::TNoTagOrCancelAllInterfaceWorker)
       
   263 	// Handshake a shutdown of AllInterfaceNotificationWorker (send TCancel, await TError).
       
   264 	NODEACTIVITY_ENTRY(ConnStates::KCancelAllInterfaceWorker, ConnStates::TCancelAllInterfaceNotificationWorker, TAwaitingMessageState<TEBase::TError>, MeshMachine::TNoTag)
       
   265     THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TCancelAllLegacyRMessage2Activities, ConnStates::TNoTagBlockedByLegacyRMessage2Activities)
       
   266 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessClose, TECABState<MeshMachine::TAwaitingLeaveComplete>, MeshMachine::TNoTag)
       
   267 	//TDestroyAwaitingLeaveCompleteLoop loops back to its own triple if more SPs
       
   268 	NODEACTIVITY_ENTRY(KNoTag, TECABTransition<CoreNetStates::TSetIdleIfNoServiceProviders>, TECABState<MeshMachine::TAwaitingLeaveComplete>, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards)
       
   269 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) //Never gets here
       
   270 NODEACTIVITY_END()
       
   271 }
       
   272 
       
   273 namespace ConnectionStateChangeNotificationActivity
       
   274 {
       
   275 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionStateChangeRequest, ConnectionStateChangeNotification, TCFInternalEsock::TSubSess, CESockClientActivityBase::NewL)
       
   276 	FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ECNProgressNotification>, MeshMachine::TNoTag)
       
   277 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
       
   278 	//TAwaitingStateChangeLoop also cancels the activity when requested
       
   279 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessProgressRequest, TECABState<MeshMachine::TAwaitingMessageState<TCFMessage::TStateChange> >, 		MeshMachine::TNoTagBackward)
       
   280 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) //Never gets here
       
   281 NODEACTIVITY_END()
       
   282 }
       
   283 
       
   284 namespace ConnectionWaitForIncomingActivity
       
   285 { //Synchronised, waits for Start to complete
       
   286 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionWaitForIncoming, ConnectionWaitForIncoming, TCFInternalEsock::TSubSess, CStartAttachActivity::NewWaitForIncomingConnectionActivityL)
       
   287 	FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ECNWaitForIncoming>, MeshMachine::TNoTag)
       
   288 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
       
   289 	//We use ConnStates::TAwaitingBinderResponse (not CoreStates) for custom handling of the Cancel message
       
   290 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TRequestIncomingConnectionBlockedByStartAttach, TECABState<CoreNetStates::TAwaitingBinderResponse>, MeshMachine::TNoTag)
       
   291 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessIncomingConnection, TECABState<CoreNetStates::TAwaitingBindToComplete>, MeshMachine::TNoTag)
       
   292 	LAST_NODEACTIVITY_ENTRY(KNoTag, ConnActivities::CStartAttachActivity::TSendBindToComplete)
       
   293 NODEACTIVITY_END()
       
   294 }
       
   295 
       
   296 //
       
   297 //Activities serving framework requests
       
   298 namespace ConnectionStateChangeActivity
       
   299 {
       
   300 DECLARE_DEFINE_NODEACTIVITY(ECFActivityStateChange, ConnectionStateChange, TCFMessage::TStateChange)
       
   301 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessStateChange, MeshMachine::TAwaitingMessageState<TCFMessage::TStateChange>, MeshMachine::TNoTag)
       
   302 NODEACTIVITY_END()
       
   303 }
       
   304 
       
   305 
       
   306 
       
   307 namespace ConnectionGoingDownActivity
       
   308 {
       
   309 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGoneDown, ConnectionGoingDown, TCFControlClient::TGoneDown, PRActivities::CGoneDownActivity::NewL)
       
   310 	FIRST_NODEACTIVITY_ENTRY(ConnStates::TAwaitingGoneDown, MeshMachine::TNoTag)
       
   311 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnectionGoingDownActivity::TStoreGoneDownError, MeshMachine::TNoTag)
       
   312 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TCancelAndCloseZone0ClientExtIfaces, MeshMachine::TNoTag)
       
   313     THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TCancelAllLegacyRMessage2Activities, ConnStates::TNoTagBlockedByLegacyRMessage2Activities)
       
   314 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProviders, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
       
   315 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSetIdleIfNoServiceProviders, MeshMachine::TAwaitingLeaveComplete, ConnectionCleanupActivities::TNoTagOrNoTagBackwards)
       
   316 	LAST_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TGenerateConnectionDownProgress)
       
   317 NODEACTIVITY_END()
       
   318 }
       
   319 
       
   320 //
       
   321 //Activities serving framework requests for legacy actions
       
   322 namespace ConnectionClientEnumActivity
       
   323 {
       
   324 DECLARE_DEFINE_NODEACTIVITY(ECFActivityLegacyConnEnumResponse, ConnectionEnumResponse, TCFInternalEsock::TLegacyConnectionEnumResponse)
       
   325 	NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessEnumResponse, ConnStates::TAwaitingEnumResponse, MeshMachine::TNoTag)
       
   326 NODEACTIVITY_END()
       
   327 }
       
   328 
       
   329 //
       
   330 //CConn usually is a cntrl client of a default subconnection.
       
   331 //The subconnection will send events, which must be handled to avoid leakages
       
   332 namespace ConnSubConnectionEventNotification
       
   333 {
       
   334 DECLARE_DEFINE_NODEACTIVITY(ECFActivityConnectionWaitForIncoming, SubConEvent, TCFSubConnControlClient::TSubConnNotification)
       
   335 	NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TBinEvent, CoreNetStates::TAwaitingSubConEvent, MeshMachine::TNoTag)
       
   336 NODEACTIVITY_END()
       
   337 }
       
   338 
       
   339 namespace ConnSubConnEventsActivity
       
   340 {
       
   341 DECLARE_DEFINE_NODEACTIVITY(ECFActivityConnSubConnEvents, ConnSubConnEvents, TNodeSignal::TNullMessageId)
       
   342 	NODEACTIVITY_ENTRY(KNoTag, ConnSubConnEventsActivity::TProcessSubConnEvent, ConnSubConnEventsActivity::TAwaitingSubConnEvent, MeshMachine::TNoTag)
       
   343 NODEACTIVITY_END()
       
   344 }
       
   345 
       
   346 namespace ConnLegacyRMessage2Activity
       
   347 {
       
   348 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionLegacyRMessage2Handler, ConnectionLegacyRMessage2, TNodeSignal::TNullMessageId, CConnLegacyRMessage2Activity::NewL)
       
   349     FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingLegacyRMessage2Ext, MeshMachine::TNoTag)
       
   350     NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessLegacyRMessage2, TAcceptErrorState<CoreNetStates::TAwaitingRMessage2Processed>, MeshMachine::TNoTagOrErrorTag)
       
   351     LAST_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TCompleteRMessage2)
       
   352     LAST_NODEACTIVITY_ENTRY(KErrorTag, ConnStates::THandleRMessage2Error)
       
   353 NODEACTIVITY_END()
       
   354 }
       
   355 
       
   356 namespace ConnectionActivities
       
   357 {
       
   358 DECLARE_DEFINE_ACTIVITY_MAP(connectionActivities)
       
   359 	//-----Framework originated activities-----//
       
   360 	ACTIVITY_MAP_ENTRY(ConnectionStateChangeActivity, ConnectionStateChange)
       
   361 	ACTIVITY_MAP_ENTRY(ConnectionGoingDownActivity, ConnectionGoingDown)
       
   362 	ACTIVITY_MAP_ENTRY(ConnSubConnectionEventNotification, SubConEvent)
       
   363 	ACTIVITY_MAP_ENTRY(ConnSubConnEventsActivity, ConnSubConnEvents)
       
   364 	ACTIVITY_MAP_ENTRY(ConnectionStopSCPRActivity, ConnectionStopSCPR)
       
   365 	ACTIVITY_MAP_ENTRY(ConnectionGoneUpActivity,ConnectionGoneUp)
       
   366 	//-----Client (IPC) originated activities-----//
       
   367 	ACTIVITY_MAP_ENTRY(ConnectionWaitForIncomingActivity, ConnectionWaitForIncoming)
       
   368 	ACTIVITY_MAP_ENTRY(ConnectionCloseActivity, ConnectionClose)
       
   369 	ACTIVITY_MAP_ENTRY(ConnectionStartActivity, ConnectionStart)
       
   370 	ACTIVITY_MAP_ENTRY(ConnectionAttachActivity, ConnectionAttach)
       
   371 	ACTIVITY_MAP_ENTRY(ConnectionStateChangeNotificationActivity, ConnectionStateChangeNotification)
       
   372 	ACTIVITY_MAP_ENTRY(ConnectionStopActivity, ConnectionStop)
       
   373 
       
   374 	ACTIVITY_MAP_ENTRY(ConnLegacyRMessage2Activity, ConnectionLegacyRMessage2)
       
   375 
       
   376 #ifdef AVAILABILITY_READY
       
   377 	ACTIVITY_MAP_ENTRY(EnumerateConnectionsActivity, EnumerateConnections)
       
   378 #endif
       
   379 
       
   380 	//-----Responses from Data plane to legacy queries-----//
       
   381 	ACTIVITY_MAP_ENTRY(ConnectionClientEnumActivity, ConnectionEnumResponse)
       
   382 ACTIVITY_MAP_END()
       
   383 }
       
   384 
       
   385 // attribute table for CConnectionIfno
       
   386 START_ATTRIBUTE_TABLE(CConnectionInfo, CConnectionInfo::EUid, CConnectionInfo::ETypeId)
       
   387 END_ATTRIBUTE_TABLE()
       
   388 
       
   389 
       
   390 namespace ESock
       
   391 {
       
   392 CConnectionInfo* CConnectionInfo::NewL(const Den::TSubSessionUniqueId& aSubSessionId)
       
   393 	{
       
   394 	return new(ELeave) CConnectionInfo(aSubSessionId);
       
   395 	}
       
   396 }
       
   397 
       
   398 /**
       
   399 Constructor
       
   400 */
       
   401 CConnection::CConnection(CSockSession* aSession, CPlayer* aPlayer, TUid aTierId, const Den::TSubSessionUniqueId aSubSessionUniqueId)
       
   402 :	CMMSockSubSession(ConnectionActivities::connectionActivities::Self(), aSession, aPlayer, aSubSessionUniqueId),
       
   403     ASubSessionPlatsecApiExt(UniqueId()),
       
   404     TIfStaticFetcherNearestInHierarchy(this),
       
   405     iTierId(aTierId),
       
   406     iLegacyConnection(*this)
       
   407 	{
       
   408 	LOG_NODE_CREATE1(KESockConnectionTag, CConnection, ", session %08x", aSession);
       
   409 	}
       
   410 /**
       
   411 Destructor
       
   412 */
       
   413 CConnection::~CConnection()
       
   414 	{
       
   415 	//Do not call CConnection::FinalCompleteAllBlockedMessages from here!
       
   416 	//At this stage we must be completed.
       
   417 	iLegacyConnection.FinalCompleteAllBlockedMessages(KErrCancel); //complete any outstanding legacy messages
       
   418 	delete iConnectionInfo;
       
   419     LOG_NODE_DESTROY(KESockConnectionTag, CConnection);
       
   420 	}
       
   421 
       
   422 //MZTODO - only client activities? Is this a shutdown?
       
   423 //Signal from subsession to abbort all (client?) activities (always KErrAbort)
       
   424 void CConnection::FinalCompleteAllBlockedMessages(TInt /*aResult*/)
       
   425 	{
       
   426 	TNodeNullContext ctx(*this);
       
   427 	AbortActivitiesOriginatedBy(ctx); //Abort all activities
       
   428 	iLegacyConnection.FinalCompleteAllBlockedMessages(KErrCancel); //complete any outstanding legacy messages
       
   429 	}
       
   430 
       
   431 void CConnection::Received(TNodeContextBase& aContext)
       
   432     {
       
   433     TNodeSignal::TMessageId noPeerIds[] = {
       
   434     	TCFInternalEsock::TSubSess::Id(),
       
   435     	TEBase::TError::Id(), //May be comming from the CSR
       
   436     	TCFInternalEsock::TLegacyConnectionEnumResponse::Id(),	// self-dispatching helper from the data plane
       
   437     	TNodeSignal::TMessageId()	// list terminator
       
   438     	};
       
   439 
       
   440 	MeshMachine::AMMNodeBase::Received(noPeerIds, aContext);
       
   441 	MeshMachine::AMMNodeBase::PostReceived(aContext);
       
   442 	}
       
   443 
       
   444 void CConnection::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aCFMessage)
       
   445     {
       
   446 	ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aCFMessage, Id());
       
   447 
       
   448 	//First check if this is not our own error
       
   449 	TEBase::TError* msg = message_cast<TEBase::TError>(&aCFMessage);
       
   450 	if (msg	&& aSender == Id() && msg->iMsgId == TCFInternalEsock::TSubSess::Id())
       
   451 		{
       
   452 		//This is our own error, generated from the client (IPC) activity
       
   453 		//It is safe to just ignore it here, as the activity is
       
   454 		//completed (and so is the client RMessage2). If the activity didn't have
       
   455 		//the chance to acquire ownership of the message it is still safe to ignore it
       
   456 		//because there was no call to DoNotCompleteCurrentMessage().
       
   457 		return;
       
   458 		}
       
   459 
       
   460 	TNodeContext<CConnection> ctx(*this, aCFMessage, aSender, aRecipient);
       
   461     CConnection::Received(ctx);
       
   462     User::LeaveIfError(ctx.iReturn);
       
   463 	}
       
   464 
       
   465 void CConnection::ForwardToServiceProviderL(const TSignalBase& aCFMessage)
       
   466 	{
       
   467 	RNodeInterface* sp = ServiceProvider();
       
   468 	User::LeaveIfError(sp? KErrNone : KErrNotReady);
       
   469 	sp->PostMessage(Id(), aCFMessage);
       
   470 	}
       
   471 
       
   472 CConnection* CConnection::NewLC(CSockSession *aSession, CPlayer* aPlayer, TUid aId, const Den::TSubSessionUniqueId aSubSessionUniqueId)
       
   473 /**
       
   474 Create a new CConnection instance
       
   475 
       
   476 @param aSession Session under which CConnection was created
       
   477 @param aId Type Id of CConnection
       
   478 @return pointer to new CConnection instance on success
       
   479 @exception leaves if could not allocate memory
       
   480 */
       
   481 	{
       
   482 	CConnection* h = new (ELeave) CConnection(aSession, aPlayer, aId, aSubSessionUniqueId);
       
   483 	CleanupStack::PushL(h);
       
   484 	h->ConstructL();
       
   485 	ESOCK_DEBUG_REGISTER_GENERAL_NODE(ESockDebug::KConnectionNodeUid, h);
       
   486 	return h;
       
   487 	}
       
   488 
       
   489 CConnection* CConnection::NewLC(CSockSession* aSession, CPlayer* aPlayer, const CConnection& aExistingConnection, const Den::TSubSessionUniqueId aSubSessionUniqueId)
       
   490 /**
       
   491 Create a new CConnection object associated with the same interface as that of an existing CConnection object.
       
   492 
       
   493 @param aSession Session under which CConnection was created
       
   494 @param aExistingConnection Existing CConnection object whose interface to associate with
       
   495 @return pointer to new CConnection instance on success
       
   496 @exception leaves if could not allocate memory
       
   497 */
       
   498 	{
       
   499 	CConnection* h = new (ELeave) CConnection(aSession, aPlayer, aExistingConnection.iTierId, aSubSessionUniqueId);
       
   500 	CleanupStack::PushL(h);
       
   501 	h->ConstructL();
       
   502 	h->CloneL(aExistingConnection);
       
   503 	return h;
       
   504 	}
       
   505 
       
   506 void CConnection::ConstructL()
       
   507 	{
       
   508 	MeshMachine::AMMNodeBase::ConstructL(KConnectionPreallocatedActivityBufferSize);
       
   509 	CSockSubSession::ConstructL(NULL);
       
   510 
       
   511 	iConnectionInfo = CConnectionInfo::NewL(UniqueId());
       
   512 	}
       
   513 
       
   514 void CConnection::CloneL(const CConnection& aExistingConnection)
       
   515 /**
       
   516 Main body of CConnection::NewL(CSockSession* aSession, const CConnection& aExistingConnection)
       
   517 */
       
   518 	{
       
   519 	RNodeInterface* sp = aExistingConnection.ServiceProvider();
       
   520 	if (sp)
       
   521 		{
       
   522 	    AddClientL(sp->RecipientId(), TClientType(TCFClientType::EServProvider, TCFClientType::EActive));
       
   523 
       
   524 		// TODO IK: This is the wrong message to be using here, should use JoinRequest/Complete handshake
       
   525 	    sp->PostMessage(Id(), TCFFactory::TPeerFoundOrCreated(Id(), 0).CRef());
       
   526         }
       
   527 	else
       
   528 		{
       
   529 		LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x CloneL KErrNotReady"), this) );
       
   530 		User::Leave(KErrNotReady);
       
   531 		}
       
   532 	}
       
   533 
       
   534 
       
   535 RNodeInterface* CConnection::DefaultSubConnectionServiceProvider()
       
   536  	{
       
   537  	RNodeInterface* dscp = GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider,TCFClientType::EDefault))[0];
       
   538  	return dscp;
       
   539  	}
       
   540 
       
   541 void CConnection::ProcessMessageL()
       
   542 /**
       
   543 	Process RConnection messages
       
   544 
       
   545 	@exception Leaves on any error processing the request
       
   546 */
       
   547 	{
       
   548 	LOG_DETAILED( ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tCommand %d"), this, aMessage.Function()) );
       
   549 
       
   550 	//Some of the client (RMessage2) messages may need to be posted, for most it
       
   551 	//will be sufficient to dispatch them directly via ReceivedL (advantage of posting
       
   552 	//rather than dispatching -> of course mesh logging!)
       
   553 	switch (Message().Function())
       
   554 		{
       
   555 		case ECNReference:
       
   556 			GetReferenceL();
       
   557 			break;
       
   558 
       
   559 		case ECNStart:
       
   560 		case ECNSetStartPrefs:
       
   561 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNStart aMessage %08x"), this, &Message()) );
       
   562 			//If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
       
   563 			CMMSockSubSession::ReceivedL(ECNStart, TCFInternalEsock::TSubSess(ECNStart,Message()).CRef());
       
   564 			break;
       
   565 
       
   566 		case ECNAttach:
       
   567 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNAttach aMessage %08x"), this, &Message()) );
       
   568 			//If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
       
   569 			CMMSockSubSession::ReceivedL(ECNAttach, TCFInternalEsock::TSubSess(ECNAttach,Message()).CRef());
       
   570 			break;
       
   571 
       
   572 		case ECNStop:
       
   573 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNStop aMessage %08x"), this, &Message()) );
       
   574 
       
   575 			//Legacy support - if there is nothing to stop, return KErrNotReady
       
   576 			if (ServiceProvider() == NULL && CountActivities(ECFActivityStart) == 0)
       
   577 				{
       
   578 				User::Leave(KErrNotReady);
       
   579 				}
       
   580 
       
   581 			//If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
       
   582 			CMMSockSubSession::ReceivedL(ECNStop, TCFInternalEsock::TSubSess(ECNStop,Message()).CRef());
       
   583 			break;
       
   584 
       
   585 		case ECNWaitForIncoming:
       
   586 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNWaitForIncoming aMessage %08x"), this, &Message()) );
       
   587 			//If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
       
   588 			CMMSockSubSession::ReceivedL(ECNWaitForIncoming, TCFInternalEsock::TSubSess(ECNWaitForIncoming,Message()).CRef());
       
   589             break;
       
   590 
       
   591 		case ECNCancelWaitForIncoming:
       
   592 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNCancelWaitForIncoming aMessage %08x"), this, &Message()) );
       
   593 			CMMSockSubSession::ReceivedL(ECNWaitForIncoming, TEBase::TCancel().CRef());
       
   594 			//CANCELATION - Do not call DontCompleteCurrentRequest() for the ECNCancelWaitForIncoming to be completed!
       
   595             break;
       
   596 
       
   597 		case ECNProgressNotification:
       
   598 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNProgressNotification aMessage %08x"), this, &Message()) );
       
   599 			CMMSockSubSession::ReceivedL(ECNProgressNotification, TCFInternalEsock::TSubSess(ECNProgressNotification,Message()).CRef()); //the ownership of the RMessage2 is taken by the activity
       
   600 			break;
       
   601 
       
   602 		case ECNCancelProgressNotification:
       
   603 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNCancelProgressNotification aMessage %08x"), this, &Message()) );
       
   604 			CMMSockSubSession::ReceivedL(ECNProgressNotification, TEBase::TCancel().CRef());
       
   605 			//CANCELATION - Do not call DontCompleteCurrentRequest() for the ECNCancelProgressNotification to be completed!
       
   606 			break;
       
   607 
       
   608 		case ECNIoctl:
       
   609 		{
       
   610 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNIoctl aMessage %08x"), this, &Message()) );
       
   611 			RNodeInterface* sp = ServiceProvider();
       
   612 			User::LeaveIfError(sp? KErrNone : KErrNotReady);
       
   613 
       
   614 			CMMSockSubSession::ReceivedL(SafeMessage().Function(), TCprSendIoctl(SafeMessage()).CRef());
       
   615 			DontCompleteCurrentRequest(); //TLegacyControlMessage will complete the message
       
   616 		}
       
   617 			break;
       
   618 
       
   619 		case ECNCancelIoctl:
       
   620 		{
       
   621 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNCancelIoctl aMessage %08x"), this, &Message()) );
       
   622 			RNodeInterface* sp = ServiceProvider();
       
   623 			User::LeaveIfError(sp? KErrNone : KErrNotReady);
       
   624 
       
   625 			CancelIoctl();
       
   626 		}
       
   627 			break;
       
   628 
       
   629 #ifdef AVAILABILITY_READY
       
   630 		case ECNEnumerateConnections:
       
   631 			LOG(ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNEnumerateConnections aMessage %08x"), this, &Message()));
       
   632 			CMMSockSubSession::ReceivedL(ECFActivityConnectionEnumerateConnections, TCFInternalEsock::TSubSess(ECNEnumerateConnections, Message()).CRef());
       
   633  			break;
       
   634 #endif
       
   635 
       
   636 		case ECNControl:
       
   637 			ControlL();	//Decides how message gets completed
       
   638 			break;
       
   639 
       
   640 		case ECNProgress:
       
   641 		    ProgressL();
       
   642 			break;
       
   643 
       
   644 		case ECNLastProgressError:
       
   645             LastProgressErrorL();
       
   646 			break;
       
   647 
       
   648 		case ECNGetOrSetParameters:
       
   649 			GetOrSetParametersL();
       
   650 			break;
       
   651 
       
   652 		case ECNGetParametersResponseLength:
       
   653 			GetParametersResponseL(ETrue);
       
   654 			break;
       
   655 
       
   656 		case ECNGetParametersResponse:
       
   657 			GetParametersResponseL(EFalse);
       
   658 			break;
       
   659 
       
   660 
       
   661 		case ECNClose:
       
   662 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tECNClose aMessage %08x"), this, &Message()) );
       
   663 			SetClosing();
       
   664 			//If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
       
   665 			CMMSockSubSession::ReceivedL(ECNClose, TCFInternalEsock::TSubSess(ECNClose,Message()).CRef());
       
   666 			break;
       
   667 
       
   668 		case ESCPSStop:
       
   669             {
       
   670 			LOG( ESockLog::Printf(KESockConnectionTag, _L8("CConnection %08x\tESCPSStop aMessage %08x"), this, &Message()) );
       
   671 
       
   672 			// The filters match the legacy behaviour - subconnection has
       
   673 			// to exist (implies Connection started).
       
   674 			// Note: CNifAgentRef used to throw away the error returned
       
   675 			// by the EMI compatibility layer hence we return KErrNone here.
       
   676 		    TSubConnectionUniqueId subConnectionUniqueId = static_cast<TSubConnectionUniqueId>(Message().Int0());
       
   677 		    if (ServiceProvider() &&
       
   678 		        (ServiceProvider()->Type() & TCFClientType::EServProvider) &&
       
   679 		        subConnectionUniqueId <= KNifEntireConnectionSubConnectionId+1)
       
   680     		    {
       
   681     			RNodeInterface* scpr = DefaultSubConnectionServiceProvider();
       
   682 
       
   683 				if(scpr)
       
   684 					{ // We can only start the 'stop' activity if we've got a service provider.
       
   685 					RConnection::TConnStopType stopType = static_cast<RConnection::TConnStopType>(Message().Int1());
       
   686 
       
   687 					// Validate the stop code.
       
   688 					switch (stopType)
       
   689 						{
       
   690 					case RConnection::EStopNormal:
       
   691 					case RConnection::EStopAuthoritative:
       
   692 						break;
       
   693 
       
   694 					default:
       
   695 						User::Leave(KErrArgument);
       
   696 						}
       
   697 
       
   698 					// We start an activity to stop the subconnection and wait for it to send the TStopped response
       
   699 					// message.  We cannot simply post the subconnection a message to stop because it causes the
       
   700 					// response message to go stray as we would be performing an operation outside of an activity.
       
   701 					// If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed
       
   702 					// on leave.
       
   703 					CMMSockSubSession::ReceivedL(
       
   704 						ESCPSStop,
       
   705 						TCFInternalEsock::TSubSess(
       
   706 							ESCPSStop,
       
   707 							Message()
       
   708 							).CRef()
       
   709 						);
       
   710 					}
       
   711 				else
       
   712 					{ // Nothing to do
       
   713 				    SetReturn(KErrNone);
       
   714 					}
       
   715     		    }
       
   716     		else
       
   717         		{
       
   718     			User::Leave(KErrNotReady);
       
   719         		}
       
   720             }
       
   721 			break;
       
   722 
       
   723 		default:
       
   724 			//iLegacyConnection must handle lifetimes of its own RMessage2s.
       
   725 			iLegacyConnection.ProcessMessageL(Message());
       
   726 			break;
       
   727 		}
       
   728 	}
       
   729 
       
   730 void CConnection::GetReferenceL()
       
   731 	{
       
   732 	TName name;
       
   733 	ComposeSubSessionName(this, name);
       
   734 	Message().WriteL(0, name);
       
   735 	}
       
   736 
       
   737 _LIT_SECURITY_POLICY_C1(NifmanPolicyNetworkControl, ECapabilityNetworkControl);
       
   738 
       
   739 /**
       
   740 	Control method to send a general command towards the interface.
       
   741 */
       
   742 void CConnection::ControlL()
       
   743 	{
       
   744 	TUint optionLevel = static_cast<TUint>(Message().Int0());
       
   745 	TUint optionName  = static_cast<TUint>(Message().Int1());
       
   746 
       
   747 	// Check that clients are not trying to use internal connection options
       
   748    	// make sure this doesn't colide with new control levels
       
   749 	User::LeaveIfError((optionName & KConnInternalOptionBit)? KErrAccessDenied : KErrNone);
       
   750 
       
   751 	switch(optionLevel)
       
   752 		{
       
   753 	case KCOLInterface:
       
   754 		// This PlatSec check replaces that from Nifman's CNifSecureSession.
       
   755 		if(!NifmanPolicyNetworkControl.CheckPolicy(Message()))
       
   756 			{
       
   757 			User::Leave(KErrPermissionDenied);
       
   758 			}
       
   759 		break;
       
   760 
       
   761 	case KCOLConnection:
       
   762 		switch(optionName)
       
   763 			{
       
   764 			case KCoEnableCloneOpen:
       
   765 			case KCoDisableCloneOpen:
       
   766 				SetCloneOpenPolicyL(optionName);
       
   767 				break;
       
   768 
       
   769 			default:
       
   770 				iLegacyConnection.ControlL(optionName, optionLevel); //AConnectionLegacy decides when to complete message
       
   771 				DontCompleteCurrentRequest(); //TLegacyControlMessage will complete the message
       
   772 			}
       
   773 		// KCOLConnection is all legacy stuff; no providers can/should help with it
       
   774 		return;
       
   775 		}
       
   776 
       
   777 	TInt optionLength = SafeMessage().GetDesLengthL(2);
       
   778 	if (optionName & (KConnReadUserDataBit | KConnWriteUserDataBit) && optionLength == 0)
       
   779 		{
       
   780 		User::Leave(KErrArgument); //No buffer for data
       
   781 		}
       
   782 
       
   783 	RNodeInterface* sp = ServiceProvider();
       
   784 	User::LeaveIfError(sp? KErrNone : KErrNotReady);
       
   785 
       
   786 	TLegacyControlMessage msg(SafeMessage());
       
   787 	CMMSockSubSession::ReceivedL(SafeMessage().Function(), msg);
       
   788 	DontCompleteCurrentRequest(); //TLegacyControlMessage will complete the message
       
   789 	}
       
   790 
       
   791 
       
   792 void CConnection::ProgressL()
       
   793     {
       
   794 	if (iLastProgress.iStage != KConnectionUp && iLastProgress.iStage != KConnectionDown)
       
   795         {
       
   796 		RNodeInterface* sp = ServiceProvider();
       
   797 		User::LeaveIfError(sp? KErrNone : KErrNotReady);
       
   798 
       
   799 		TCprRetrieveProgress msg(SafeMessage(), iLastProgress);
       
   800 		CMMSockSubSession::ReceivedL(SafeMessage().Function(), msg);
       
   801         DontCompleteCurrentRequest(); //TCprRetrieveProgress will complete the message
       
   802         return;
       
   803         }
       
   804 
       
   805     TPckgBuf<TStateChange> progressBuf;
       
   806     progressBuf().iStage = iLastProgress.iStage;
       
   807     progressBuf().iError = iLastProgress.iError;
       
   808 
       
   809     Message().WriteL(0, progressBuf);
       
   810     SetReturn(KErrNone);
       
   811     }
       
   812 
       
   813 void CConnection::LastProgressErrorL()
       
   814     {
       
   815     if (iLastProgress.iStage != KConnectionUp && iLastProgress.iStage != KConnectionDown)
       
   816         {
       
   817 		RNodeInterface* sp = ServiceProvider();
       
   818 		User::LeaveIfError(sp? KErrNone : KErrNotReady);
       
   819 
       
   820         TCprRetrieveLastProgressError msg(SafeMessage(), iLastProgressError);
       
   821 		CMMSockSubSession::ReceivedL(SafeMessage().Function(), msg);
       
   822         DontCompleteCurrentRequest(); //TCprRetrieveLastProgressError will complete the message
       
   823         return;
       
   824         }
       
   825 
       
   826     TPckgBuf<TStateChange> progressBuf;
       
   827     progressBuf().iStage = iLastProgressError.iStage;
       
   828     progressBuf().iError = iLastProgressError.iError;
       
   829     ResetLastProgressError();
       
   830 
       
   831     Message().WriteL(0, progressBuf);
       
   832     SetReturn(KErrNone);
       
   833     }
       
   834 
       
   835 
       
   836 void CConnection::GetOrSetParametersL()
       
   837     {
       
   838     if (ServiceProvider() == NULL)
       
   839         {
       
   840     	SetReturn(KErrNotReady);
       
   841     	return;
       
   842         }
       
   843 
       
   844     if (iCommsDataObject)
       
   845     	{
       
   846     	SetReturn(KErrInUse);
       
   847     	return;
       
   848     	}
       
   849 
       
   850 	TInt cdoLength = Message().GetDesLengthL(0);
       
   851 	RBuf8 cdoBuffer;
       
   852 	cdoBuffer.CreateL(cdoLength);
       
   853 	CleanupClosePushL(cdoBuffer);
       
   854 	SafeMessage().ReadL(0, cdoBuffer);
       
   855 
       
   856    	TPtrC8 des(cdoBuffer);
       
   857    	iCommsDataObject = static_cast<XCommsDataObject*>(SMetaDataECom::LoadL(des));
       
   858 
       
   859 	// Last minute sanity check
       
   860 	if ((iCommsDataObject->OperationMode() == XCommsDataObject::EOperationGet
       
   861 		&& !iCommsDataObject->IsGetSupported())
       
   862 		|| (iCommsDataObject->OperationMode() == XCommsDataObject::EOperationSet
       
   863 		&& !iCommsDataObject->IsSetSupported()))
       
   864 		{
       
   865 		CleanupStack::PopAndDestroy(); // cdoBuffer
       
   866 		delete iCommsDataObject;
       
   867 		iCommsDataObject = NULL;
       
   868 		SetReturn(KErrCorrupt);
       
   869 		return;
       
   870 		}
       
   871 
       
   872    	// iCommsDataObject passed as *& and will be updated by the TGetOrSetParameters message
       
   873    	// upon error
       
   874 	RNodeInterface* sp = ServiceProvider();
       
   875 	if (sp == NULL)
       
   876 		{
       
   877 		delete iCommsDataObject;
       
   878 		iCommsDataObject = NULL;
       
   879 		SetReturn(KErrNotReady);
       
   880 		return;
       
   881 		}
       
   882 
       
   883 	TGetOrSetParameters msg(SafeMessage(), iCommsDataObject);
       
   884 	CMMSockSubSession::ReceivedL(SafeMessage().Function(), msg);
       
   885 	DontCompleteCurrentRequest(); //TLegacyControlMessage will complete the message
       
   886 	CleanupStack::PopAndDestroy(); // cdoBuffer
       
   887     }
       
   888 
       
   889 
       
   890 void CConnection::GetParametersResponseL(TBool aReturnLength)
       
   891 	{
       
   892     if (ServiceProvider() == NULL || !iCommsDataObject)
       
   893         {
       
   894     	SetReturn(KErrNotReady);
       
   895     	return;
       
   896         }
       
   897 
       
   898     if (aReturnLength)
       
   899     	{
       
   900     	// Client requesting required buffer length for the serialised object
       
   901     	iCommsDataObjectLength = iCommsDataObject->Length();
       
   902     	SetReturn(iCommsDataObjectLength);
       
   903     	}
       
   904     else
       
   905     	{
       
   906 		RBuf8 cdoBuffer;
       
   907 		cdoBuffer.CreateL(iCommsDataObjectLength);
       
   908 		CleanupClosePushL(cdoBuffer);
       
   909 		User::LeaveIfError(iCommsDataObject->Store(cdoBuffer));
       
   910 		Message().WriteL(0, cdoBuffer);
       
   911 		CleanupStack::PopAndDestroy();	// queryBundleBuffer
       
   912 
       
   913 		delete iCommsDataObject;
       
   914 		iCommsDataObject = NULL;
       
   915 		iCommsDataObjectLength = 0;
       
   916 
       
   917 		SetReturn(KErrNone);
       
   918     	}
       
   919 	}
       
   920 
       
   921 void CConnection::CancelIoctl()
       
   922 	{
       
   923 	const RPointerArray<CNodeActivityBase>& activities = Activities();
       
   924 	for (TInt i = 0; i < activities.Count(); i++)
       
   925 		{
       
   926 		if (activities[i]->ActivitySigId() == ESock::ECFActivityConnectionLegacyRMessage2Handler)
       
   927 			{
       
   928 			ConnActivities::CConnLegacyRMessage2Activity* act = static_cast<ConnActivities::CConnLegacyRMessage2Activity*>(activities[i]);
       
   929 			if (act->iSafeMessage.Function() == ECNIoctl)
       
   930 				{
       
   931 				act->SetCancelRequest(SafeMessage());
       
   932 				CMMSockSubSession::ReceivedL(act->iSafeMessage.Function(), TEBase::TCancel().CRef());
       
   933 				DontCompleteCurrentRequest();
       
   934 				}
       
   935 			}
       
   936 		}
       
   937 	}
       
   938 
       
   939 void CConnection::SetCloneOpenPolicyL(TUint aOptionName)
       
   940 	{
       
   941 	const TInt policyParamIndex = 2;
       
   942 
       
   943 	switch (aOptionName)
       
   944 		{
       
   945 		case KCoEnableCloneOpen:
       
   946 			{
       
   947 			// Enable the ability to perform a clone open towards this instance.  Read the
       
   948 			// security policy passed in the option and store it in this instance.
       
   949 			TSecurityPolicyBuf cloneOpenPolicy;
       
   950 			SafeMessage().ReadL(policyParamIndex, cloneOpenPolicy);
       
   951 			User::LeaveIfError(iCloneOpenPolicy.Set(cloneOpenPolicy));
       
   952 			iCloneOpenEnabled = ETrue;
       
   953 			break;
       
   954 			}
       
   955 		case KCoDisableCloneOpen:
       
   956 			{
       
   957 			// Disable the ability to perform a clone open towards this instance.
       
   958 			iCloneOpenEnabled = EFalse;
       
   959 			break;
       
   960 			}
       
   961 		}
       
   962 	}
       
   963 
       
   964 TInt CConnection::CheckCloneOpenPolicy(const RMessagePtr2& aMessage) const
       
   965 	{
       
   966 	if (iCloneOpenEnabled && iCloneOpenPolicy.CheckPolicy(aMessage))
       
   967 		return KErrNone;
       
   968 	else
       
   969 		return KErrPermissionDenied;
       
   970 	}
       
   971 
       
   972 
       
   973 /**
       
   974 @internalTechnology
       
   975 */
       
   976 void CConnection::ReturnInterfacePtrL(MPlatsecApiExt*& aInterface)
       
   977     {
       
   978     aInterface = this;
       
   979     }
       
   980 
       
   981 // AllInterfaceNotification
       
   982 
       
   983 /**
       
   984 	Legacy RConnection::AllInterfaceNotification implementation
       
   985 */
       
   986 namespace AllInterfaceNotificationActivity
       
   987 {
       
   988 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionAllInterfaceNotification, AllInterfaceNotification, TCFServiceProvider::TStart, CAllInterfaceNotificationActivity::NewL)
       
   989 	NODEACTIVITY_ENTRY(KNoTag, TAddClient, TAwaitingStart, MeshMachine::TNoTag)
       
   990 	// Find the tier manager and request notification from it.
       
   991 	NODEACTIVITY_ENTRY(KNoTag, TFindTierManager, TAwaitingTierManager, MeshMachine::TNoTag)
       
   992 	NODEACTIVITY_ENTRY(KNoTag, TJoinTierManager, TAwaitingJoinComplete, MeshMachine::TNoTag)
       
   993 
       
   994 	// Start the notification activity and wait for notification
       
   995 	NODEACTIVITY_ENTRY(KNoTag, TStartLinkNotification, TAwaitingLinkNotification, CoreStates::TCancelOrErrorOrTag<KNoTag>)
       
   996 
       
   997 	// Enqueue the notification and wait for the next one - we loop here forever
       
   998 	NODEACTIVITY_ENTRY(KNoTag, TEnqueueNotification, TAwaitingLinkNotification, CoreStates::TCancelOrErrorOrTag<KNoTag|EBackward>)
       
   999 
       
  1000 	THROUGH_TRIPLE_ENTRY(KErrorTag, MeshMachine::TStoreError, MeshMachine::TTag<KCancelTag>)
       
  1001 	// If we received a TCancel from CConnection, reply with TError to complete shutdown handshake. 
       
  1002 	THROUGH_NODEACTIVITY_ENTRY(KCancelTag, TSendErrorToConnection, MeshMachine::TTag<KCancelTag>)
       
  1003 	NODEACTIVITY_ENTRY(KCancelTag, TCancelLinkNotification, TAwaitingLinkNotificationError, MeshMachine::TNoTag)
       
  1004 	LAST_NODEACTIVITY_ENTRY(KNoTag, TLeaveTierManager) // no other sessions with tier so can safely fire & forget this
       
  1005 NODEACTIVITY_END()
       
  1006 }
       
  1007 
       
  1008 namespace AllInterfaceNotificationActivities
       
  1009 {
       
  1010 DECLARE_DEFINE_ACTIVITY_MAP(allInterfaceNotificationActivities)
       
  1011 	ACTIVITY_MAP_ENTRY(AllInterfaceNotificationActivity, AllInterfaceNotification)
       
  1012 ACTIVITY_MAP_END()
       
  1013 }
       
  1014 
       
  1015 CAllInterfaceNotificationWorker::CAllInterfaceNotificationWorker(ESock::CConnection& aConnection) :
       
  1016 	ACFMMNodeIdBase(AllInterfaceNotificationActivities::allInterfaceNotificationActivities::Self()),
       
  1017 	iConnection(aConnection)
       
  1018 	{
       
  1019 	LOG_NODE_CREATE(KESockConnectionTag, CAllInterfaceNotificationWorker);
       
  1020 	}
       
  1021 
       
  1022 CAllInterfaceNotificationWorker::~CAllInterfaceNotificationWorker()
       
  1023 	{
       
  1024 	LOG_NODE_DESTROY(KESockConnectionTag, CAllInterfaceNotificationWorker);
       
  1025 	}
       
  1026 
       
  1027 void CAllInterfaceNotificationWorker::Received(TNodeContextBase& aContext)
       
  1028     {
       
  1029 	TNodeSignal::TMessageId noPeerIds[] = {
       
  1030     	TCFServiceProvider::TStart::Id(),
       
  1031     	TNodeSignal::TMessageId()	// list terminator
       
  1032     	};
       
  1033     MeshMachine::AMMNodeBase::Received(noPeerIds, aContext);
       
  1034 	MeshMachine::AMMNodeBase::PostReceived(aContext);
       
  1035 	}
       
  1036 
       
  1037 void CAllInterfaceNotificationWorker::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
       
  1038     {
       
  1039 	TNodeContext<CAllInterfaceNotificationWorker> ctx(*this, aMessage, aSender, aRecipient);
       
  1040     CAllInterfaceNotificationWorker::Received(ctx);
       
  1041     User::LeaveIfError(ctx.iReturn);
       
  1042 	}
       
  1043 
       
  1044