networkcontrol/ipnetworklayer/src/IPProtoCPR.cpp
changeset 0 af10295192d8
child 7 db85996de7c4
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     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 // IPProto Connection Provider implementation
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #define SYMBIAN_NETWORKING_UPS
       
    24 
       
    25 #include <comms-infras/corecprstates.h>
       
    26 #include <comms-infras/corecpractivities.h>
       
    27 #include <comms-infras/ss_log.h>
       
    28 #include <comms-infras/ss_legacyinterfaces.h>
       
    29 #include <comms-infras/ss_datamon_apiext.h>
       
    30 #include <es_prot.h> // ESocketTimerPriority/KConnProfile(None/Long/Medium)
       
    31 #include <e32def.h>
       
    32 #include <es_prot_internal.h>
       
    33 
       
    34 
       
    35 #include "IPProtoCprStates.h"
       
    36 #include "IPProtoCPR.h"
       
    37 #include "IPProtoMCpr.h"
       
    38 #include "IPProtoMessages.h"
       
    39 #include "linkcprextensionapi.h"
       
    40 
       
    41 #include <comms-infras/ss_nodemessages_factory.h>
       
    42 #include <comms-infras/ss_msgintercept.h>
       
    43 #include <comms-infras/ss_nodemessages_internal.h>
       
    44 
       
    45 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
    46 #include <comms-infras/ss_nodemessages_subconn.h>
       
    47 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
    48 
       
    49 #ifdef _DEBUG
       
    50    #include <networking/idletimertest.h>
       
    51 #endif
       
    52 
       
    53 using namespace Messages;
       
    54 using namespace MeshMachine;
       
    55 using namespace IpProtoCpr;
       
    56 using namespace ESock;
       
    57 using namespace NetStateMachine;
       
    58 using namespace PRActivities;
       
    59 
       
    60 
       
    61 
       
    62 //We reserve space for two preallocated activities that may start concurrently on the CPR
       
    63 //node: destroy and data client stop.
       
    64 static const TUint KDefaultMaxPreallocatedActivityCount = 2;
       
    65 static const TUint KMaxPreallocatedActivitySize = sizeof(MeshMachine::CNodeRetryParallelActivity) + sizeof(MeshMachine::APreallocatedOriginators<4>);
       
    66 static const TUint KIPProtoCPRPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize;
       
    67 
       
    68 //-=========================================================
       
    69 //
       
    70 // Activities
       
    71 //
       
    72 //-=========================================================
       
    73 
       
    74 namespace IPProtoCprProvisionActivity
       
    75 {
       
    76 DECLARE_DEFINE_NODEACTIVITY(ECFActivityStoreProvision, IPProtoCprProvision, TCFDataClient::TProvisionConfig)
       
    77 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingProvision, MeshMachine::TNoTag)
       
    78 	LAST_NODEACTIVITY_ENTRY(KNoTag, IpProtoCpr::TStoreProvision)
       
    79 NODEACTIVITY_END()
       
    80 }
       
    81 
       
    82 
       
    83 namespace IPProtoCprConnectionDownActivity
       
    84 {
       
    85 // In the event that a StopConnection has been issued this activity will not receive
       
    86 // a ConnectionDown message. It will be received instead by the running StopConnectionActivity.
       
    87 //
       
    88 // In the event that the Idle Timer has expired, this node will originate a StopConnection
       
    89 // to itself, the StopConnectionActivity will post a ConnectionDown to the origator (this
       
    90 // node) and the StopConnectionActivity will go idle. The ConnectionDown message will then
       
    91 // be received by this activity.
       
    92 
       
    93 DECLARE_DEFINE_NODEACTIVITY(ECFActivityGoneDown, IPProtoCprConnectionDown, TCFServiceProvider::TStopped)
       
    94 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStopped, MeshMachine::TNoTag)
       
    95 	LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendGoneDown)
       
    96 NODEACTIVITY_END()
       
    97 }
       
    98 
       
    99 namespace IPProtoCprBinderRequestActivity
       
   100 {
       
   101 //The reason IPProtoCPR overrides this activity is that IPProto layer doesn't
       
   102 //implement non-default SCPRs and although higher levels will ask for them
       
   103 //(in QoS scenarios) IPProto will assume the higher levels will do fine
       
   104 //with default SCPRs instead. The current QoS solution involves GuQoS and
       
   105 //multiplexining channels at IPProto layer.
       
   106 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBinderRequest, IPProtoCprBinderRequest, TCFServiceProvider::TCommsBinderRequest, PRActivities::CCommsBinderActivity::NewL)
       
   107 //	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBinderRequest, CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingBlockedByBinderRequest)
       
   108 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBinderRequest, CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefaultBlockedByBinderRequest)
       
   109 	NODEACTIVITY_ENTRY(KNoTag, PRStates::TCreateDataClient, CoreNetStates::TAwaitingDataClientJoin, MeshMachine::TNoTag)
       
   110 
       
   111 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CCommsBinderActivity::TProcessDataClientCreation, TTag<CoreStates::KUseExisting>)
       
   112 
       
   113 	NODEACTIVITY_ENTRY(CoreStates::KUseExisting, CCommsBinderActivity::TSendBinderResponse, CCommsBinderActivity::TAwaitingBindToComplete, MeshMachine::TNoTagOrErrorTag)
       
   114 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
   115 
       
   116 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TClearError)
       
   117 	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KWaitForIncoming, MeshMachine::TRaiseError<KErrNotSupported>)
       
   118 NODEACTIVITY_END()
       
   119 }
       
   120 
       
   121 
       
   122 
       
   123 namespace IPProtoCprDataMonitoringActivity
       
   124 {
       
   125 DECLARE_DEFINE_NODEACTIVITY(ECFActivityDataMonitoring, IPProtoCprDataMonitoring, TCFDataMonitoringNotification::TDataMonitoringNotification)
       
   126 	FIRST_NODEACTIVITY_ENTRY(IpProtoCpr::TAwaitingDataMonitoringNotification, MeshMachine::TNoTag)
       
   127 	LAST_NODEACTIVITY_ENTRY(KNoTag, IpProtoCpr::TProcessDataMonitoringNotification)
       
   128 NODEACTIVITY_END()
       
   129 }
       
   130 
       
   131 namespace IPProtoCprOpenCloseRouteActivity
       
   132 {
       
   133 DECLARE_DEFINE_NODEACTIVITY(ECFActivityOpenCloseRoute, IPProtoCprOpenCloseRoute, TCFIPProtoMessage::TOpenCloseRoute)
       
   134 	FIRST_NODEACTIVITY_ENTRY(IpProtoCpr::TAwaitingOpenCloseRoute, MeshMachine::TNoTag)
       
   135 	LAST_NODEACTIVITY_ENTRY(KNoTag, IpProtoCpr::TDoOpenCloseRoute)
       
   136 NODEACTIVITY_END()
       
   137 }
       
   138 
       
   139 namespace IPProtoCprForwardStateChangeActivity
       
   140 {
       
   141 DECLARE_DEFINE_NODEACTIVITY(ECFActivityForwardStateChange, IPProtoCprForwardStateChange, TCFMessage::TStateChange)
       
   142 	NODEACTIVITY_ENTRY(KNoTag, IpProtoCpr::TStoreAndFilterDeprecatedAndForwardStateChange, MeshMachine::TAwaitingMessageState<TCFMessage::TStateChange>, MeshMachine::TNoTag)
       
   143 NODEACTIVITY_END()
       
   144 }
       
   145 
       
   146 
       
   147 
       
   148 
       
   149 namespace IPProtoCprLinkDown
       
   150 {
       
   151 	
       
   152 	DECLARE_DEFINE_NODEACTIVITY(ECFActivityGoneDown, IPProtoCprLinkDownOnMesg, TCFControlClient::TGoneDown)
       
   153 	// Our Service Provider has gone down unexpectedly (we haven't issued a TStop)
       
   154 	NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, TAwaitingGoneDown, MeshMachine::TNoTag)
       
   155 	NODEACTIVITY_END()
       
   156 }
       
   157 
       
   158 
       
   159 
       
   160 namespace IPProtoCprStartActivity
       
   161 {
       
   162 typedef MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingDataClientStarted> TAwaitingDataClientStartedOrError;
       
   163 
       
   164 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, IPProtoCprStart, TCFServiceProvider::TStart, PRActivities::CStartActivity::NewL)
       
   165     FIRST_NODEACTIVITY_ENTRY(IpProtoCpr::TAwaitingStart, CoreNetStates::TNoTagOrBearerPresentBlockedByStop)
       
   166 	NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TBindSelfToPresentBearer, CoreNetStates::TAwaitingBindToComplete, TTag<CoreNetStates::KBearerPresent>)
       
   167 
       
   168 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendNoBearer, MeshMachine::TAwaitingMessageState<TCFControlProvider::TBearer>, TErrorTagOr<TTag<CoreNetStates::KBearerPresent> >)
       
   169 
       
   170 	//Start the service provider, use the default cancellation.
       
   171 	//Forward TCancel to the service provider, wait for TStarted or TError (via the Error Activity)
       
   172 	//When TStarted arrives after TCancel the activity will move to the nearest KErrorTag
       
   173 	NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreNetStates::TStartServiceProviderRetry, CoreNetStates::TAwaitingStarted, MeshMachine::TNoTagOrErrorTag)
       
   174 	LAST_NODEACTIVITY_ENTRY(KErrorTag, IpProtoCpr::TCleanupStart)
       
   175 
       
   176 	//Start data clients, use the default cancellation.
       
   177 	//Forward TCancel to the self, wait for TCFDataClient::TStarted or TError (via the Error Activity)
       
   178 	//When TCFDataClient::TStarted arrives after TCancel the activity will move to the nearest KErrorTag
       
   179 	NODEACTIVITY_ENTRY(KNoTag, TLinkUpAndTStartSelf, TAwaitingDataClientStartedOrError, MeshMachine::TNoTagOrErrorTag)
       
   180 	LAST_NODEACTIVITY_ENTRY(KNoTag, IpProtoCpr::TSendStarted)
       
   181 
       
   182 	//IPProto layer must stop the lower layer on failure to start as it would detach the lower layer from the idle timer impl.
       
   183 	NODEACTIVITY_ENTRY(KErrorTag, IpProtoCpr::TSendStopToSelf, CoreNetStates::TAwaitingStopped, MeshMachine::TErrorTag)
       
   184 	LAST_NODEACTIVITY_ENTRY(KErrorTag, IpProtoCpr::TCleanupStart)
       
   185 NODEACTIVITY_END()
       
   186 }
       
   187 
       
   188 namespace IPProtoCprClientLeaveActivity
       
   189 { //This activity will wait for ECFActivityBinderRequest to complete
       
   190 using namespace  CprClientLeaveActivity;
       
   191 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityClientLeave, IPProtoCprClientLeave, Messages::TNodeSignal::TNullMessageId, CClientLeaveActivity::NewL) //May be waiting for both messages
       
   192 	FIRST_NODEACTIVITY_ENTRY(CoreStates::TAwaitingClientLeave, MeshMachine::TNoTag)
       
   193 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CprClientLeaveActivity::CClientLeaveActivity::TRemoveClientAndDestroyOrphanedDataClients, CClientLeaveActivity::TNoTagOrSendPriorityToCtrlProvider)
       
   194 	NODEACTIVITY_ENTRY(CprStates::KSendPriorityToCtrlProvider, CClientLeaveActivity::TUpdatePriorityForControlProvider, CoreStates::TAwaitingJoinComplete, CClientLeaveActivity::TNoTagOrSendPriorityToServProvider)
       
   195 	NODEACTIVITY_ENTRY(CprStates::KSendPriorityToServProvider, CClientLeaveActivity::TUpdatePriorityForServiceProviders, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
       
   196  	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CprClientLeaveActivity::CClientLeaveActivity::TSendLeaveCompleteAndSendDataClientIdleIfNeeded, MeshMachine::TNoTag)
       
   197  	LAST_NODEACTIVITY_ENTRY(KNoTag, IpProtoCpr::TCheckIfLastControlClientLeaving)
       
   198 NODEACTIVITY_END()
       
   199 }
       
   200 
       
   201 DECLARE_DEFINE_NODEACTIVITY(ECFIpProtoCprActivityDataClientStatusChange, IPProtoCprDataClientStatusChangeActivity, TCFControlProvider::TDataClientStatusChange)
       
   202 	NODEACTIVITY_ENTRY(KNoTag, IpProtoCpr::TProcessDataClientStatusChange, CoreNetStates::TAwaitingDataClientStatusChange, MeshMachine::TNoTag)
       
   203 NODEACTIVITY_END()
       
   204 
       
   205 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   206 namespace IPProtoCprNotificationActivity
       
   207 {
       
   208 DECLARE_DEFINE_NODEACTIVITY(ECFActivityNotification, IPProtoCprNotification, TCFSubConnControlClient::TPlaneNotification)
       
   209 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TPassPlaneEventToControlClients, CoreNetStates::TAwaitingConEvent, MeshMachine::TNoTag)
       
   210 NODEACTIVITY_END()
       
   211 }
       
   212 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   213 
       
   214 namespace IPProtoCprIoctlActivity
       
   215 {
       
   216 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityIoctl, IPProtoCprIoctl, TNodeSignal::TNullMessageId, MeshMachine::CNodeParallelMessageStoreActivityBase::NewL)
       
   217     FIRST_NODEACTIVITY_ENTRY(IpProtoCpr::TAwaitingIoctlMessage, MeshMachine::TNoTag)
       
   218     NODEACTIVITY_ENTRY(KNoTag, IpProtoCpr::TForwardToDefaultDataClient, CoreNetStates::TAwaitingRMessage2Processed, MeshMachine::TNoTag)
       
   219     LAST_NODEACTIVITY_ENTRY(KNoTag, CoreStates::TPostToOriginators)
       
   220 NODEACTIVITY_END()
       
   221 }
       
   222 
       
   223 namespace IPProtoCprActivities
       
   224 {
       
   225 DECLARE_DEFINE_ACTIVITY_MAP(activityMap)
       
   226 	ACTIVITY_MAP_ENTRY(IPProtoCprForwardStateChangeActivity, IPProtoCprForwardStateChange)
       
   227 	ACTIVITY_MAP_ENTRY(IPProtoCprLinkDown, IPProtoCprLinkDownOnMesg) 
       
   228 	ACTIVITY_MAP_ENTRY(IPProtoCprProvisionActivity, IPProtoCprProvision)
       
   229 	ACTIVITY_MAP_ENTRY(IPProtoCprBinderRequestActivity, IPProtoCprBinderRequest)
       
   230 	ACTIVITY_MAP_ENTRY(IPProtoCprDataMonitoringActivity, IPProtoCprDataMonitoring)
       
   231 	ACTIVITY_MAP_ENTRY(IPProtoCprConnectionDownActivity, IPProtoCprConnectionDown)
       
   232 	ACTIVITY_MAP_ENTRY(IPProtoCprOpenCloseRouteActivity, IPProtoCprOpenCloseRoute)
       
   233 	ACTIVITY_MAP_ENTRY(IPProtoCprStartActivity, IPProtoCprStart)
       
   234 	ACTIVITY_MAP_ENTRY(IPProtoCprDataClientStatusChangeActivity, IPProtoCprDataClientStatusChangeActivity)
       
   235 	ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle)
       
   236 	ACTIVITY_MAP_ENTRY(IPProtoCprClientLeaveActivity, IPProtoCprClientLeave)
       
   237 	ACTIVITY_MAP_ENTRY(IPProtoCprIoctlActivity, IPProtoCprIoctl)
       
   238 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   239 	ACTIVITY_MAP_ENTRY(IPProtoCprNotificationActivity, IPProtoCprNotification)
       
   240 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   241 ACTIVITY_MAP_END_BASE(CprActivities, coreCprActivities)
       
   242 }
       
   243 
       
   244 //-=========================================================
       
   245 //
       
   246 // CIPProtoConnectionProvider methods
       
   247 //
       
   248 //-=========================================================
       
   249 CIPProtoConnectionProvider* CIPProtoConnectionProvider::NewL(CConnectionProviderFactoryBase& aFactory)
       
   250     {
       
   251     CIPProtoConnectionProvider* prov = new (ELeave) CIPProtoConnectionProvider(aFactory,IPProtoCprActivities::activityMap::Self());
       
   252     CleanupStack::PushL(prov);
       
   253     prov->ConstructL();
       
   254     CleanupStack::Pop(prov);
       
   255     return prov;
       
   256     }
       
   257 
       
   258 CIPProtoConnectionProvider::~CIPProtoConnectionProvider()
       
   259     {
       
   260     LOG_NODE_DESTROY(KIPProtoCprTag, CIPProtoConnectionProvider);
       
   261 
       
   262     CancelTimer();
       
   263     delete iTimer;
       
   264     
       
   265     iNodeLocalExtensions.Close();
       
   266     }
       
   267 
       
   268 CIPProtoConnectionProvider::CIPProtoConnectionProvider(CConnectionProviderFactoryBase& aFactory, const MeshMachine::TNodeActivityMap& aActivityMap) :
       
   269 	CCoreConnectionProvider(aFactory,aActivityMap),
       
   270 	ALegacySubConnectionActiveApiExt(this),
       
   271 	TIfStaticFetcherNearestInHierarchy(this),
       
   272     iDataMonitoringConnProvisioningInfo(&iDataVolumes, &iThresholds)
       
   273     {
       
   274     LOG_NODE_CREATE(KIPProtoCprTag, CIPProtoConnectionProvider);
       
   275     }
       
   276 
       
   277 void CIPProtoConnectionProvider::ConstructL()
       
   278     {
       
   279     iTimer = COneShotTimer::NewL(ESocketTimerPriority, this);
       
   280 
       
   281     ADataMonitoringProvider::ConstructL();
       
   282     CCoreConnectionProvider::ConstructL(KIPProtoCPRPreallocatedActivityBufferSize);
       
   283     }
       
   284 
       
   285 void CIPProtoConnectionProvider::ReturnInterfacePtrL(ADataMonitoringProtocolReq*& aInterface)
       
   286 	{
       
   287 	aInterface = this;
       
   288 	}
       
   289 
       
   290 void CIPProtoConnectionProvider::ReturnInterfacePtrL(MLinkCprApiExt*& aInterface) 	  	 
       
   291 	{ 	  	 
       
   292 	//Get the extension from the Access Point Config, it must be there by now (constructed on provision) 	  	 
       
   293 	//We are the only node ever accessing the interface, this is why we can safely return it as non-const. 	  	 
       
   294 	CLinkCprExtensionApi* ext = const_cast<CLinkCprExtensionApi*>(static_cast<const CLinkCprExtensionApi*>(AccessPointConfig().FindExtension(CLinkCprExtensionApi::TypeId()))); 	  	 
       
   295 	ASSERT(ext); //Udeb 	  	 
       
   296 	User::LeaveIfError(ext? KErrNone : KErrCorrupt); //Urel 	  	 
       
   297 	aInterface = ext; 	  	 
       
   298 	}
       
   299 
       
   300 
       
   301 void CIPProtoConnectionProvider::ReturnInterfacePtrL(ESock::MLegacyControlApiExt*& aInterface)
       
   302 	{
       
   303 	aInterface = this;
       
   304 	}
       
   305 
       
   306 void CIPProtoConnectionProvider::ReturnInterfacePtrL(ESock::ALegacySubConnectionActiveApiExt*& aInterface)
       
   307 	{
       
   308 	aInterface = this;
       
   309 	}
       
   310 
       
   311 /**
       
   312 Retrieves the ALegacyEnumerateSubConnectionsApiExt implementation
       
   313 */
       
   314 void CIPProtoConnectionProvider::ReturnInterfacePtrL(ESock::ALegacyEnumerateSubConnectionsApiExt*& aInterface)
       
   315     {
       
   316     aInterface = this;
       
   317     }
       
   318 
       
   319 
       
   320 void CIPProtoConnectionProvider::EnumerateSubConnections(CLegacyEnumerateSubConnectionsResponder*& aResponder)
       
   321 	{
       
   322 	TInt count = CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EStarted));
       
   323 
       
   324 	/*
       
   325 	  Plus one for to match legacy behaviour. The extra subconnection is there to
       
   326 	  represent the connectino and all its subconnections as a whole.
       
   327 
       
   328 	  So subconnection array is accessed as:
       
   329 	    [0] = Entire connection
       
   330 		[1] = Default subconnection
       
   331 		[2] = non-default subconnection ...
       
   332 		...
       
   333 	*/
       
   334 	count += 1;
       
   335 	CLegacyEnumerateSubConnectionsResponder::CompleteClient(aResponder, count);
       
   336 	}
       
   337 
       
   338 void CIPProtoConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
       
   339     {
       
   340 	ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient);
       
   341     TNodeContext<CIPProtoConnectionProvider> ctx(*this, aMessage, aSender, aRecipient);
       
   342    	Received(ctx);
       
   343     User::LeaveIfError(ctx.iReturn);
       
   344 	}
       
   345 
       
   346 void CIPProtoConnectionProvider::Received(MeshMachine::TNodeContextBase& aContext)
       
   347     {
       
   348     Messages::TNodeSignal::TMessageId noPeerIds[] = {
       
   349         TCFFactory::TPeerFoundOrCreated::Id(),
       
   350         TCFPeer::TJoinRequest::Id(),
       
   351         //TDataMonitoringInternal no-peer as Flow sending directly.
       
   352         TCFDataMonitoringNotification::TDataMonitoringNotification::Id(),
       
   353         TCFIPProtoMessage::TOpenCloseRoute::Id(),
       
   354         Messages::TNodeSignal::TMessageId()
       
   355         };
       
   356 
       
   357     MeshMachine::AMMNodeBase::Received(noPeerIds, aContext);
       
   358 	MeshMachine::AMMNodeBase::PostReceived(aContext);
       
   359 	}
       
   360 
       
   361 void CIPProtoConnectionProvider::LinkUp()
       
   362 	{
       
   363 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tLinkUp()"), this) );
       
   364 	ASSERT(!iLinkUp);
       
   365 	iLinkUp = ETrue;
       
   366 	iLastControlClientsCount = ControlClientsCount();
       
   367 
       
   368 	TTime now;
       
   369 	now.UniversalTime();
       
   370 	iStartTime = now;
       
   371 	}
       
   372 
       
   373 void CIPProtoConnectionProvider::LinkDown()
       
   374 	{
       
   375 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tLinkDown()"), this) );
       
   376 
       
   377 	iLinkUp = EFalse;
       
   378 	CancelTimer();
       
   379 	}
       
   380 
       
   381 void CIPProtoConnectionProvider::OpenRoute()
       
   382 	{
       
   383 	if (iTimerExpired)
       
   384 		{
       
   385 		return;
       
   386 		}
       
   387 	iRouteCount++;
       
   388 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tOpenRoute() count %d"), this, iRouteCount) );
       
   389 	}
       
   390 
       
   391 void CIPProtoConnectionProvider::CloseRoute()
       
   392 	{
       
   393 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tCloseRoute() count %d timer expired: %d"), this, iRouteCount-1, iTimerExpired) );
       
   394 	if (iTimerExpired)
       
   395 		{
       
   396 		return;
       
   397 		}
       
   398 	ASSERT(iRouteCount > 0);
       
   399 	if (--iRouteCount == 0 && !iTimer->IsActive())
       
   400 		{
       
   401 		// if the number of calls to CloseRoute() matches those to OpenRoute(), then ensure that
       
   402 		// the idle timer is running.
       
   403 		TTimerType newMode;
       
   404 
       
   405 		if ( (iRouteCountStretchOne)
       
   406 			&& (iTickThreshold[iTimerMode] != (TInt)KMaxTUint32)
       
   407 			)
       
   408 			{
       
   409 			// Note that there is a slim possiblility that the OpenRoute / CloseRoute event pair
       
   410 			// occured too quickly and that a TimerComplete event did not occur to check iRouteCount.
       
   411 			// To account for the OpenRoute / CloseRoute event pair artificially lengthen the iRouteCount.
       
   412 			// If the current timer is disabled then the OpenRoute / CloseRoute event pair
       
   413 			// would never have been detected so then dont stretch the event.
       
   414 			newMode = DecideTimerMode(1);
       
   415 			}
       
   416 		else
       
   417 			{
       
   418 			newMode = DecideTimerMode(iRouteCount);
       
   419 			}
       
   420 
       
   421 		if (newMode != ETimerUnknown)
       
   422 			SetTimerMode(newMode);
       
   423 		else
       
   424 			ResetTimer();
       
   425 		}
       
   426 
       
   427 	}
       
   428 
       
   429 void CIPProtoConnectionProvider::TimerComplete(TInt /*aError*/)
       
   430 	{
       
   431 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer Complete %d/%d ticks, Mode %d"), this, iExpiredTicks+1, iTickThreshold[iTimerMode], iTimerMode) );
       
   432 
       
   433 	if (iTimerMode == ETimerImmediate)
       
   434 		{
       
   435 		ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tIdle timeout completed - stopping interface"), this) );
       
   436 		TimerExpired();
       
   437 		return;
       
   438 		}
       
   439 
       
   440 	ASSERT(iLinkUp);
       
   441 
       
   442 	// reset the iRouteCountStretchOne
       
   443 	iRouteCountStretchOne = EFalse;
       
   444 
       
   445 	// Determine if we need to alter the timer mode
       
   446 	TTimerType newMode = DecideTimerMode(iRouteCount);
       
   447 	iConnectionControlActivity = EFalse; // (do not reset before DecideTimerMode())
       
   448 
       
   449 	if (0 == iRouteCount)
       
   450 		{
       
   451 		// Note that there is a slim possiblility that the OpenRoute / CloseRoute event pair
       
   452 		// occured too quickly and that a TimerComplete event did not occur to check iRouteCount.
       
   453 		// If this occurs then the newMode selected here will be incorrect.
       
   454 		// Extend iRouteCount if iRouteCount > 0 -> iRouteCount = 0 is seen before the next timer event
       
   455 		iRouteCountStretchOne = ETrue;
       
   456 		}
       
   457 
       
   458 	// Also a similar issue of connection Start/Attach type activity occuring too quickly to
       
   459 	// be noticed by iConnectionControlActivity might be present.
       
   460 	// TODO create a test and solution to prove the connection Start/Attach type activity.
       
   461 
       
   462 	// set new timer mode if required
       
   463 	if (newMode != ETimerUnknown)
       
   464 		SetTimerMode(newMode);
       
   465 
       
   466 	if (iPeriodActivity)
       
   467 		{
       
   468 		iPeriodActivity = EFalse;
       
   469 
       
   470 		// Reset the timer on packet activity (if the timer mode hasn't just been changed).
       
   471 		// (Should this reset only the Long timer, or should it reset the timer in all modes ?)
       
   472 
       
   473 		if (newMode == ETimerUnknown)
       
   474 			{
       
   475 			ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer reset due to packet activity"), this) );
       
   476 			ResetTimer();
       
   477 			}
       
   478 		}
       
   479 	else
       
   480 		{
       
   481 		if (newMode == ETimerUnknown)
       
   482 			{
       
   483 			// No Activity and no change in timer state, check if timer has expired
       
   484 			// (checking first for a value of KMaxTUint32, which means the timer is disabled).
       
   485 
       
   486 			if (iTickThreshold[iTimerMode] != (TInt)KMaxTUint32)
       
   487 				{
       
   488 				if (iTickThreshold[iTimerMode] <= ++iExpiredTicks)
       
   489 					{
       
   490 					ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tIdle timeout completed"), this) );
       
   491 					TimerExpired();
       
   492 					}
       
   493 				else
       
   494 					{
       
   495 					StartNextTick();
       
   496 					}
       
   497 				}
       
   498 			}
       
   499 		}
       
   500 	}
       
   501 
       
   502 CIPProtoConnectionProvider::TTimerType CIPProtoConnectionProvider::DecideTimerMode(TInt aRouteCount)
       
   503 	{
       
   504 	TTimerType newMode = ETimerUnknown;
       
   505 	TInt currentControlClientsCount = ControlClientsCount();
       
   506 	if (currentControlClientsCount > iLastControlClientsCount)
       
   507 		{
       
   508 		iConnectionControlActivity = ETrue;
       
   509 		}
       
   510 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tDecideTimerMode() currentControlClientsCount %d iLastControlClientsCount %d iRouteCount %d"), this, currentControlClientsCount, iLastControlClientsCount, iRouteCount) );
       
   511 	iLastControlClientsCount = currentControlClientsCount;
       
   512 
       
   513 	switch (iTimerMode)
       
   514 		{
       
   515 	case ETimerShort:
       
   516 		if (aRouteCount > 0) // any Flows or ESock Sessions?
       
   517 			{
       
   518 			ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer mode changed from Short to Long due to presence of protocol flows"), this) );
       
   519 			newMode = ETimerLong;
       
   520 			}
       
   521 		else if (iLastControlClientsCount > 0) // any new Control Clients attached?
       
   522 			{
       
   523 			ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer mode changed from Short to Medium due to presence of control providers"), this) );
       
   524 			newMode = ETimerMedium;
       
   525 			}
       
   526 		break;
       
   527 
       
   528 	case ETimerMedium:
       
   529 		if (aRouteCount > 0)
       
   530 			{
       
   531 			ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer mode changed from Medium to Long due to presence of flows"), this) );
       
   532 			newMode = ETimerLong;
       
   533 			}
       
   534 		else if (iLastControlClientsCount == 0)
       
   535 			{
       
   536 			ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer mode changed from Medium to Short due to absence of flows and control providers"), this) );
       
   537 			newMode = ETimerShort;
       
   538 			}
       
   539 		else if (iConnectionControlActivity && iTickThreshold[iTimerMode] != (TInt)KMaxTUint32)
       
   540 			{
       
   541 			// there has been connection Start/Attach type activity, so reset medium timer
       
   542 			ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tMedium timer reset due to connection control activity"), this) );
       
   543 			newMode = ETimerMedium;
       
   544 			}
       
   545 		else if (0 == aRouteCount && iTickThreshold[iTimerMode] == (TInt)KMaxTUint32 && iTickThreshold[ETimerShort] != (TInt)KMaxTUint32)
       
   546 			{
       
   547 			// There are no sockets and the current timer is disabled but the short timer is set
       
   548 			ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer set to Short because there are no Sockets and Long or Medium timer is disabled"), this) );
       
   549 			newMode = ETimerShort;
       
   550 			}
       
   551 		break;
       
   552 
       
   553 	case ETimerLong:
       
   554 		if (0 == aRouteCount)
       
   555 			{
       
   556 			if (iLastControlClientsCount > 0)
       
   557 				{
       
   558 				ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer mode changed from Long to Medium due to presence of control providers"), this) );
       
   559 				newMode = ETimerMedium;
       
   560 				}
       
   561 			else
       
   562 				{
       
   563 				ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer mode changed from Long to Short due to absence of flows and control providers"), this) );
       
   564 				newMode = ETimerShort;
       
   565 				}
       
   566 			}
       
   567 		break;
       
   568 
       
   569 	default:
       
   570 		break;
       
   571 		}
       
   572 
       
   573 	return (newMode);
       
   574 	}
       
   575 
       
   576 /**
       
   577  Start the next one second tick for the Idle Timer.
       
   578  As the Idle Timer is implemented as a repeated one second timeout rather than a single timeout period,
       
   579  this routine is necessary to ensure overall accuracy.  The period of each "one second" tick
       
   580  is adjusted slightly to compensate for any accumulated inaccuracies.
       
   581  */
       
   582 void CIPProtoConnectionProvider::StartNextTick()
       
   583 	{
       
   584 	/*
       
   585 	The inactivity timeout period is made up of a number of successive
       
   586 	one second timer periods up to the desired inactivity timeout.
       
   587 	This is done because certain operations are needed every second.
       
   588 	However, this can result in cumulative errors in the final timeout
       
   589 	period.  An attempt is made here to keep the final timeout period
       
   590 	accurate by adjusting the duration of a timer tick every so often
       
   591 	to compensate for any observed drift.  This is only best-effort
       
   592 	synchronisation which ignores drift that seems way out - as could
       
   593 	happen if user altered system time, for example,
       
   594 	*/
       
   595 
       
   596 	if (iExpiredTicks % KTimerCorrectionPeriod == 0)
       
   597 		{
       
   598 		TTime currentTime;
       
   599 		currentTime.HomeTime();
       
   600 
       
   601 		// Time interval for timer synch & high limit for validity of observed timer drift
       
   602 		const TTimeIntervalMicroSeconds KTimeCheckInterval(KTimerCorrectionPeriod * KTimerTick);
       
   603 
       
   604 		iDriftCheckTime += KTimeCheckInterval;
       
   605 
       
   606 		// Only act on latest timer drift if it's within sensible limits.
       
   607 		// Might not be if user has reset system time, for example.
       
   608 		if ( currentTime > iDriftCheckTime )
       
   609 			{
       
   610 			TInt64 t = currentTime.MicroSecondsFrom(iDriftCheckTime).Int64();
       
   611 			if ( t < KTimeCheckInterval.Int64())
       
   612 				iTotalTimerDrift += I64LOW(t);
       
   613 			}
       
   614 		else
       
   615 			{
       
   616 			TInt64 t = iDriftCheckTime.MicroSecondsFrom(currentTime).Int64();
       
   617  			if (t < KTimerTick-KMinTimerTick)
       
   618 				iTotalTimerDrift -= I64LOW(t);
       
   619 			}
       
   620 
       
   621 		iDriftCheckTime = currentTime;
       
   622 
       
   623 		if (iTotalTimerDrift > KTimerTick - KMinTimerTick)
       
   624 			TimerAfter(KMinTimerTick);
       
   625 		else if (iTotalTimerDrift > 0)
       
   626 			TimerAfter(KTimerTick - iTotalTimerDrift);
       
   627 		else
       
   628 			TimerAfter(KTimerTick);
       
   629 		}
       
   630 	else
       
   631 		TimerAfter(KTimerTick);
       
   632 	}
       
   633 
       
   634 void CIPProtoConnectionProvider::SetTimers(TUint32 aShortTimer, TUint32 aMediumTimer, TUint32 aLongTimer)
       
   635 	{
       
   636 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tSetTimers(aShortTimer %ds, aMediumTimer %ds, aLongTimer %ds)"), this, aShortTimer, aMediumTimer, aLongTimer) );
       
   637 
       
   638 	// Commsdat field: LAST_SESSION_CLOSED_TIMEOUT
       
   639 	iTickThreshold[ETimerShort] = aShortTimer;
       
   640 	// Commsdat field: LAST_SOCKET_CLOSED_TIMEOUT
       
   641 	iTickThreshold[ETimerMedium] = aMediumTimer;
       
   642 	// Commsdat field: LAST_SOCKET_ACTIVITY_TIMEOUT
       
   643 	iTickThreshold[ETimerLong] = aLongTimer;
       
   644 	iTickThreshold[ETimerImmediate] = 0;
       
   645 	}
       
   646 
       
   647 void CIPProtoConnectionProvider::ResetTimer()
       
   648     {
       
   649 	/**
       
   650 	Restart the Idle Timer.
       
   651 	Used when switching the timer into a different mode of operation.
       
   652 	*/
       
   653 
       
   654     // Initial the iRouteCountStretchOne boolean
       
   655     // Extend iRouteCount if a iRouteCount > 0 is seen before the next timer event
       
   656     iRouteCountStretchOne = ETrue;
       
   657 
       
   658 #ifdef ESOCK_EXTLOG_ACTIVE
       
   659 	TBuf8<9> mode;	// enough for "Immediate"
       
   660 	TInt len(0);
       
   661 	switch(iTimerMode)
       
   662 		{
       
   663 		case ETimerLong:
       
   664 			mode = _L8("Long");
       
   665 			len = iTickThreshold[ETimerLong];
       
   666 			break;
       
   667 
       
   668 		case ETimerMedium:
       
   669 			mode = _L8("Medium");
       
   670 			len = iTickThreshold[ETimerMedium];
       
   671 			break;
       
   672 
       
   673 		case ETimerShort:
       
   674 			mode = _L8("Short");
       
   675 			len = iTickThreshold[ETimerShort];
       
   676 			break;
       
   677 
       
   678 		case ETimerImmediate:
       
   679 			mode = _L8("Immediate");
       
   680 			break;
       
   681 
       
   682 		default:
       
   683 			mode = _L8("Unknown");
       
   684 		}
       
   685 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer mode set to %S (%d ticks)"), this, &mode, len) );
       
   686 #endif
       
   687 
       
   688 	// if we are not in the packet activity monitoring mode, reset the activity flag.
       
   689 	if (iTimerMode != ETimerLong)
       
   690 		{
       
   691 		iPeriodActivity = EFalse;
       
   692 		}
       
   693 
       
   694 	if ( !iLinkUp || iTimer->IsActive() )
       
   695 
       
   696 		{
       
   697 		return;
       
   698 		}
       
   699 
       
   700 	iExpiredTicks = 0;
       
   701 	iTotalTimerDrift = 0;
       
   702 	iDriftCheckTime.HomeTime();
       
   703 	// Only start the timer if it is not disabled (i.e. KMaxTUint32)
       
   704 	// Defensive check against ETimerUnknown.
       
   705 	if ( iTimerMode != ETimerUnknown && iTickThreshold[iTimerMode] != (TInt)KMaxTUint32 )
       
   706 		{
       
   707 		TimerAfter(KTimerTick);
       
   708 		}
       
   709 	}
       
   710 
       
   711 void CIPProtoConnectionProvider::DisableTimers()
       
   712 	{
       
   713 	if(0 == iTimerDisableCount)
       
   714 		{
       
   715 		CancelTimer();
       
   716 		}
       
   717 	iTimerDisableCount++;
       
   718 	}
       
   719 
       
   720 void CIPProtoConnectionProvider::EnableTimers()
       
   721 	{
       
   722 	--iTimerDisableCount;
       
   723 	if(0 == iTimerDisableCount)
       
   724 		{
       
   725 		ResetTimer();
       
   726 		}
       
   727 	}
       
   728 
       
   729 void CIPProtoConnectionProvider::CancelTimer()
       
   730     {
       
   731     if (iTimer)
       
   732     	{
       
   733     	iTimer->Cancel();
       
   734     	}
       
   735     }
       
   736 
       
   737 void CIPProtoConnectionProvider::StopConnection()
       
   738 	{
       
   739 	if (!iTimerExpired)
       
   740 		{
       
   741 		iTimerExpired = ETrue;
       
   742 		CancelTimer();
       
   743 		if (CountActivities(ECFActivityStop) == 0)
       
   744 			{
       
   745 			RClientInterface::OpenPostMessageClose(Id(), TNodeCtxId(ECFActivityStop, Id()), TCFServiceProvider::TStop(KErrTimedOut).CRef());
       
   746 			}
       
   747 		}
       
   748 	}
       
   749 
       
   750 void CIPProtoConnectionProvider::TimerExpired()
       
   751 	{
       
   752 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimerExpired()"), this) );
       
   753 	StopConnection();
       
   754 	}
       
   755 
       
   756 TInt CIPProtoConnectionProvider::ControlClientsCount()
       
   757 	{
       
   758 	return CountClients<TDefaultClientMatchPolicy>(
       
   759 		TClientType(TCFClientType::ECtrl),
       
   760 		TClientType(TCFClientType::ECtrl, TCFClientType::EMonitor)
       
   761 		);
       
   762 	}
       
   763 
       
   764 void CIPProtoConnectionProvider::SetUsageProfile(TInt aProfile)
       
   765 	{
       
   766 	ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tSetUsageProfile(%d)"), this, aProfile) );
       
   767 
       
   768 	TInt currentControlClientsCount = ControlClientsCount();
       
   769 
       
   770 	switch (aProfile)
       
   771 		{
       
   772 	case KConnProfileMedium:
       
   773 		if (currentControlClientsCount == 0)
       
   774 			{
       
   775 			// Move from short to medium timer
       
   776 			if (iTimerMode == ETimerShort)
       
   777 				{
       
   778 				ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tUsage profile %d - timer mode set to Medium"), this, aProfile) );
       
   779 				SetTimerMode(ETimerMedium);
       
   780 				}
       
   781 			}
       
   782 		break;
       
   783 
       
   784 	case KConnProfileNone:
       
   785 		if (currentControlClientsCount == 0 && iRouteCount == 0)
       
   786 			{
       
   787 			if (iTimerMode == ETimerMedium)
       
   788 				{
       
   789 				// Moving from medium to short timer
       
   790 				ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tUsage profile %d - timer mode set to Short"), this, aProfile) );
       
   791 				SetTimerMode(ETimerShort);
       
   792 				}
       
   793 			else if ((iTimerMode == ETimerUnknown) && !iLinkUp)
       
   794 				{
       
   795 				ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tUsage profile %d - stopping interface"), this, aProfile) );
       
   796 				}
       
   797 			}
       
   798 
       
   799 		break;
       
   800 
       
   801 	default:
       
   802 		ASSERT(0);
       
   803 		}
       
   804 	}
       
   805 
       
   806 void CIPProtoConnectionProvider::SetTimerMode(TTimerType aTimerMode)
       
   807 	{
       
   808 	iTimerMode = aTimerMode;
       
   809 	ResetTimer();
       
   810 	};
       
   811 
       
   812 void CIPProtoConnectionProvider::TimerAfter(TInt aInterval)
       
   813 	{
       
   814 	ASSERT(iTimer);
       
   815 	iTimer->After(aInterval);
       
   816 	}
       
   817 
       
   818 TInt CIPProtoConnectionProvider::ControlL(TUint aOptionLevel, TUint aOptionName, TDes8& aOption, MPlatsecApiExt* aPlatsecItf)
       
   819 	{
       
   820 	switch(aOptionLevel)
       
   821 		{
       
   822 #ifdef _DEBUG
       
   823 		// We're only servicing 'testing' control options here.  They used
       
   824 		// to be serviced by Dummy NIF but now the idle timers are
       
   825 		// associated with the IPProto layer rather than the link layer.
       
   826 	case KCOLInterface:
       
   827 		if (aOption.Length() != sizeof(TInt))
       
   828 			{
       
   829 			return KErrArgument;
       
   830 			}
       
   831 		switch(aOptionName)
       
   832 			{
       
   833 		case KTestSoDummyNifSetLastSessionClosedTimeout:
       
   834 			iTickThreshold[ETimerShort] = *(reinterpret_cast<const TInt*>(aOption.Ptr()));
       
   835 			break;
       
   836 
       
   837 		case KTestSoDummyNifSetLastSocketClosedTimeout:
       
   838 			iTickThreshold[ETimerMedium] = *(reinterpret_cast<const TInt*>(aOption.Ptr()));
       
   839 			break;
       
   840 
       
   841 		case KTestSoDummyNifSetLastSocketActivityTimeout:
       
   842 			iTickThreshold[ETimerLong] = *(reinterpret_cast<const TInt*>(aOption.Ptr()));
       
   843 			break;
       
   844 
       
   845 		default:
       
   846 			return KErrNotSupported;
       
   847 			}
       
   848 		break;
       
   849 #endif // _DEBUG
       
   850 
       
   851 	case KCOLProvider:
       
   852 		switch(aOptionName)
       
   853 			{
       
   854 		case KConnDisableTimers:
       
   855 			{
       
   856 			if(!aPlatsecItf->HasCapability(ECapabilityNetworkControl))
       
   857 				{
       
   858 				return KErrPermissionDenied;
       
   859 				}
       
   860 
       
   861 			if (aOption.Length() != sizeof(TBool))
       
   862 				{
       
   863 				return KErrArgument;
       
   864 				}
       
   865 
       
   866 			TBool disable = *reinterpret_cast<const TBool*>(aOption.Ptr());
       
   867 			if(disable)
       
   868 				{
       
   869 				DisableTimers();
       
   870 				}
       
   871 			else
       
   872 				{
       
   873 				EnableTimers();
       
   874 				}
       
   875 			break;
       
   876 			}
       
   877 		case KConnGetInterfaceName:
       
   878 			{
       
   879 			if(aOption.Length() != sizeof(TConnInterfaceName))
       
   880 				{
       
   881 				return KErrArgument;
       
   882 				}
       
   883 
       
   884  			TConnInterfaceName* connItfName;
       
   885 			connItfName = reinterpret_cast<TConnInterfaceName*>(const_cast<TUint8*>(aOption.Ptr()));
       
   886 
       
   887 			XInterfaceNames* itfNames = static_cast<XInterfaceNames*>(const_cast<Meta::SMetaData*>(AccessPointConfig().FindExtension(XInterfaceNames::TypeId())));
       
   888 
       
   889 			if(!itfNames)
       
   890 				{
       
   891 				return KErrNotFound;
       
   892 				}
       
   893 
       
   894 			// Interface indices are 1-based we so perform subtract 1 to get the correct
       
   895 			// name from the store.
       
   896 			TUint ret = itfNames->InterfaceName(connItfName->iIndex - 1, connItfName->iName);
       
   897 
       
   898 			return ret;
       
   899 			}
       
   900 		default:
       
   901 			return KErrNotSupported;
       
   902 			}
       
   903 		break;
       
   904 
       
   905 	default:
       
   906 		return KErrNotSupported;
       
   907 		}
       
   908 
       
   909 	return KErrNone;
       
   910 	}
       
   911 
       
   912 void CIPProtoConnectionProvider::ForceCheckShortTimerMode()
       
   913 /**
       
   914  * This method allow to force to check if it's possible to switch
       
   915  * 	to the TimerMode "Short" without waiting for the next tick.
       
   916  *
       
   917  * The "IdleTimer" inside IPProtoCpr can work in 3 different TimerMode:
       
   918  * 	1) Short 2) Medium 3) Long.
       
   919  * Depending on the Number of CtrlClients attached and on the
       
   920  * 	Activity in the lower planes, the Timer change is mode.
       
   921  * A problem poped-out when there are no more CtrlClient and there is no
       
   922  * 	Activity: the timer needs to switch to "Short" and, if nothing happens
       
   923  * 	in the meanwhile that the Short timeout finish, send a "StopSelf" message.
       
   924  * BUT this is based on the "count" of the number of CtrlClient and this
       
   925  * 	"count" is done ONLY every Tick. That, in this case, has 1 second freq.
       
   926  * This means that in many situation the Timer lose almost 1 second BEFORE
       
   927  * 	to recognize that it has to switch to Short mode.
       
   928  *
       
   929  * This method allow to "force" the check to see if it's the right moment
       
   930  * 	to switch to Short mode and, if it is the case, it does so.
       
   931  * We overriden the activity "ClientLeaveActivity" so this method is
       
   932  * 	called when a "ClientLeave" message is processed by this node.
       
   933  *
       
   934  * It's clear that this is just a patch: the whole timer needs a refactoring.
       
   935  */
       
   936 	{
       
   937 	// If the number of ControlClient goes to "0", it needs to
       
   938 	// 	force to switch the TimerMode to "ShortTimeout".
       
   939 	// This is to avoid to waste *1 Tick* (waiting for the next one)
       
   940 	//	to recognize that the number of ControlClient is "0".
       
   941 	//
       
   942 	// We do exactly what it's done when a Tick is complete:
       
   943 	//	this will switch the Mode to Short Timeout.
       
   944 	if ( iLastControlClientsCount >= 1 &&	// - If there was at least 1 Control Clients
       
   945 			iTimerMode == ETimerMedium &&	// - AND the TimerMode is on Medium
       
   946 			iTimerExpired == EFalse &&		// - AND The time is not ALREADY Expired
       
   947 			ControlClientsCount() == 0		// - AND There are no more Control Clients Attached
       
   948 			)
       
   949 		{
       
   950 		ESOCK_EXTLOG_VAR( (KESockConnectionTag, KIPProtoCprSubTag, _L8("CIPProtoConnectionProvider %x:\tTimer mode FORCED to Short due to absence of flows and control providers"), this) );
       
   951 		iLastControlClientsCount = 0;
       
   952 		TTimerType newMode = ETimerShort;
       
   953 
       
   954 		iConnectionControlActivity = EFalse;
       
   955 
       
   956 		iTimerMode = newMode;
       
   957 		iPeriodActivity = EFalse;
       
   958 		iExpiredTicks = 0;
       
   959 		iTotalTimerDrift = 0;
       
   960 		iDriftCheckTime.HomeTime();
       
   961 
       
   962 		// The timer may never have been started if no sockets were ever opened and the "medium"
       
   963 		// and "long" timers were infinite. So we make sure that it is running.
       
   964 		ResetTimer();
       
   965 		}
       
   966 	}
       
   967 
       
   968 void CIPProtoConnectionProvider::GetSubConnectionInfo(TSubConnectionInfo &aInfo)
       
   969 	{
       
   970 	aInfo.iTimeStarted = iStartTime;
       
   971 	}
       
   972 
       
   973 //
       
   974 // CIPProtoConnectionProvider::COneShotTimer
       
   975 //
       
   976 CIPProtoConnectionProvider::COneShotTimer* CIPProtoConnectionProvider::COneShotTimer::NewL(TInt aPriority, CIPProtoConnectionProvider* aOwner)
       
   977 	{
       
   978 	COneShotTimer* self = new (ELeave)COneShotTimer(aPriority, aOwner);
       
   979 	CleanupStack::PushL(self);
       
   980 	self->ConstructL();
       
   981 	CleanupStack::Pop(self);
       
   982 	return self;
       
   983 	}
       
   984 CIPProtoConnectionProvider::COneShotTimer::COneShotTimer(TInt aPriority, CIPProtoConnectionProvider* aOwner)
       
   985 	: CTimer(aPriority), iOwner(aOwner)
       
   986 	{
       
   987 	CActiveScheduler::Add(this);
       
   988 	}
       
   989 
       
   990 void CIPProtoConnectionProvider::COneShotTimer::RunL()
       
   991 	{
       
   992 	iOwner->TimerComplete(iStatus.Int());
       
   993 	}
       
   994 
       
   995 void CIPProtoConnectionProvider::COneShotTimer::ConstructL()
       
   996 	{
       
   997 	CTimer::ConstructL();
       
   998 	}
       
   999