networkcontrol/commsuserpromptmgr/state/src/netupsaction.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This file provides the implementation of the NetUps Utility Functions.
       
    15 // Most / all of thes methods seem destinated to migrate into the netupsstate.cpp file.
       
    16 // @internalAll
       
    17 // @prototype
       
    18 // 
       
    19 //
       
    20 
       
    21 
       
    22 #include "e32cmn.h"
       
    23 
       
    24 #include <comms-infras/ss_activities.h>
       
    25 
       
    26 #include "netupsaction.h"
       
    27 
       
    28 #include "netupsassert.h"
       
    29 #include "netupstypes.h"			// defines TNetUpsDecision
       
    30 #include "netupsstatemachine.h"		// defines the NetUps State Machine
       
    31 
       
    32 #include "netupsdatabaseentry.h"
       
    33 #include "netupsprocessentry.h"
       
    34 #include "netupsthreadentry.h"
       
    35 #include "netupsprocessmonitor.h"
       
    36 #include "netupsthreadmonitor.h"
       
    37 #include "netupssubsession.h"
       
    38 
       
    39 #include "netupspolicycheckrequestqueue.h"
       
    40 
       
    41 #include "netupsstatedef.h"
       
    42 
       
    43 #include <comms-infras/commsdebugutility.h> 		// defines the comms debug logging utility
       
    44 
       
    45 using namespace ESock;
       
    46 
       
    47 namespace NetUps
       
    48 {
       
    49 __FLOG_STMT(_LIT8(KNetUpsSubsys, 	"esock");)   
       
    50 __FLOG_STMT(_LIT8(KNetUpsComponent, "NetUps");) /*esockloader*/
       
    51 
       
    52 	namespace NetUpsFunctions 
       
    53 	{
       
    54 
       
    55 	void HandleUPSRequestL(CState& aState, TThreadKey& aThreadKey, const TPolicyCheckRequestData& aPolicyCheckRequestData, TRequestId aRequestId)
       
    56 	// Process Life Time Non Session
       
    57 	// Network Life Time Non Session 
       
    58 	// CNullState
       
    59 		{
       
    60 		__FLOG_STATIC7(KNetUpsSubsys, KNetUpsComponent, _L("::HandleUPSRequestL(), processId = %d, threadId = %d, serviceId  = %d, platSecCheckResult  = %d, NodeId  = %08x, originator  = %08x, requestId = %d"),
       
    61 					 aPolicyCheckRequestData.iProcessId.Id(),
       
    62 					 aPolicyCheckRequestData.iThreadId.Id(),		aPolicyCheckRequestData.iServiceId,
       
    63 					 aPolicyCheckRequestData.iPlatSecCheckResult, 	&aPolicyCheckRequestData.iCommsId.Node(),
       
    64 					 &(aPolicyCheckRequestData.iPolicyCheckRequestOriginator), aRequestId); 
       
    65 
       
    66 		aThreadKey.iThreadEntry.AddCommsIdL(aPolicyCheckRequestData.iCommsId);
       
    67 		TRAPD(err, aThreadKey.iThreadEntry.RequestQueue().SendRequestL(aPolicyCheckRequestData, aRequestId));
       
    68 		if (err != KErrNone)
       
    69 			{
       
    70 			// 1st back out the CommsId which we have just added, provided there are no
       
    71 			// connections currently associated with it.
       
    72 			aThreadKey.iThreadEntry.RemoveCommsId(aPolicyCheckRequestData.iCommsId);
       
    73 			// 2nd, leave with original error, presumably KErrNoMemory
       
    74 			User::Leave(err);
       
    75 			}
       
    76 
       
    77 		aState.PerformStateTransition(EPolicyCheckRequest, aThreadKey.iProcessEntry);
       
    78 		}
       
    79 
       
    80 	void HandleUpsRequestCompletion_ProcessLifeTimeNonSessionL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TNetUpsDecision aNetUpsDecision)
       
    81 		{ // Tested
       
    82 		// process life time, non session
       
    83 		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_ProcessLifeTimeNonSessionL(), processId = %d, threadId = %d, nodeId = %08x, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
       
    84 					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
    85 					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
    86 					 	&aCommsIdKey.iCommsId.Node(),
       
    87 					 	&aPolicyCheckRequestOriginator,
       
    88 					 	aNetUpsDecision );
       
    89 					
       
    90 		switch(aNetUpsDecision) 
       
    91 			{			
       
    92 			case ENo:
       
    93 				//  if request fails, remove the record of the commsid (cosmetic).
       
    94 				aCommsIdKey.iThreadEntry.RemoveCommsId(aCommsIdKey.iCommsId);
       
    95 				// intended fall through
       
    96 			case EYes:
       
    97 				{
       
    98 				__ASSERT_DEBUG((aCommsIdKey.iThreadEntry.ThreadMonitor() != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsAction));					
       
    99 				if (aCommsIdKey.iThreadEntry.ThreadMonitor()->IsActive() == EFalse)
       
   100 					{
       
   101 					aCommsIdKey.iThreadEntry.ThreadMonitor()->Start();						
       
   102 					}
       
   103 				TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);
       
   104 				__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_ProcessLifeTimeNonSessionL(), error = %d"), rc);
       
   105 				break;	
       
   106 				}
       
   107 			case ESessionYes:
       
   108 			case ESessionNo:
       
   109 				{
       
   110 				HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(aState, aCommsIdKey, aPolicyCheckRequestOriginator, aNetUpsDecision);
       
   111 				break;
       
   112 				}
       
   113 			default:
       
   114 				{
       
   115 				HandleUPSErrorOnCompletion_ProcessLifeTimeNonSessionL(aCommsIdKey, aPolicyCheckRequestOriginator, KErrCorrupt);
       
   116 				break;
       
   117 				}
       
   118 			}
       
   119 		}
       
   120 
       
   121 	void HandleUPSErrorOnCompletion_ProcessLifeTimeNonSessionL(TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TInt aError)
       
   122 		{
       
   123 		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(), processId = %d, threadId = %d, nodeId = %08x, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
       
   124 					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   125 					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   126 					 	&aCommsIdKey.iCommsId.Node(),
       
   127 					 	&aPolicyCheckRequestOriginator,
       
   128 					 	aError ); 
       
   129 
       
   130 		// Remove the entry on 1st time failure	
       
   131 		aCommsIdKey.iThreadEntry.RemoveCommsId(aCommsIdKey.iCommsId);
       
   132 		
       
   133 		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aError, aCommsIdKey.iCommsId);			
       
   134 		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUPSErrorOnCompletion_ProcessLifeTimeNonSessionL(), error = %d, rc = %d"), aError, rc );
       
   135 		}
       
   136 
       
   137 	void HandleUpsRequestCompletion_NetworkLifeTimeNonSessionL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TNetUpsDecision aNetUpsDecision)
       
   138 		{ // Tested
       
   139 		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_NetworkLifeTimeNonSessionL(), processId = %d, threadId = %d, nodeId = %08x, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
       
   140 					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   141 					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   142 					 	&aCommsIdKey.iCommsId.Node(),
       
   143 					 	&aPolicyCheckRequestOriginator,
       
   144 					 	aNetUpsDecision ); 
       
   145 
       
   146 		// network life time, non session		
       
   147 		switch(aNetUpsDecision) 
       
   148 			{			
       
   149 			case EYes:
       
   150 				{
       
   151 				aCommsIdKey.iThreadEntry.IncrementConnectionCount(aCommsIdKey.iCommsId);
       
   152 
       
   153 				__ASSERT_DEBUG((aCommsIdKey.iThreadEntry.ThreadMonitor() != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsAction1));					
       
   154 				if (aCommsIdKey.iThreadEntry.ThreadMonitor()->IsActive() == EFalse)
       
   155 					{
       
   156 					aCommsIdKey.iThreadEntry.ThreadMonitor()->Start();
       
   157 					}
       
   158 				TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);
       
   159 				__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_NetworkLifeTimeNonSessionL(), error = %d"), rc );
       
   160 				break;
       
   161 				}
       
   162 			case ENo:
       
   163 				{
       
   164 				//  if request fails, remove the record of the commsid
       
   165 				aCommsIdKey.iThreadEntry.RemoveCommsId(aCommsIdKey.iCommsId);		
       
   166 				
       
   167 				__ASSERT_DEBUG((aCommsIdKey.iThreadEntry.ThreadMonitor() != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsAction2));					
       
   168 				if (aCommsIdKey.iThreadEntry.ThreadMonitor()->IsActive() == EFalse)
       
   169 					{
       
   170 					aCommsIdKey.iThreadEntry.ThreadMonitor()->Start();
       
   171 					}
       
   172 				TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);
       
   173 				__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_NetworkLifeTimeNonSessionL(), error = %d"), rc );
       
   174 				break;	
       
   175 				}
       
   176 			case ESessionYes:
       
   177 			case ESessionNo:
       
   178 				{
       
   179 				HandleUpsRequestCompletion_EnteringNetworkSessionLifeTimeL(aState, aCommsIdKey, aPolicyCheckRequestOriginator, aNetUpsDecision);
       
   180 				break;
       
   181 				}
       
   182 			default:
       
   183 				{
       
   184 				HandleUPSErrorOnCompletion_NetworkLifeTimeNonSessionL(aCommsIdKey, aPolicyCheckRequestOriginator, KErrCorrupt);
       
   185 				break;
       
   186 				}
       
   187 			}
       
   188 		}
       
   189 
       
   190 	void HandleUPSErrorOnCompletion_NetworkLifeTimeNonSessionL(TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TInt aError)
       
   191 		{
       
   192 		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringNetworkLifeTimeL(), processId = %d, threadId = %d, commsId = %08x, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
       
   193 					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   194 					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   195 					 	&aCommsIdKey.iCommsId.Node(),
       
   196 					 	&aPolicyCheckRequestOriginator,
       
   197 					 	aError ); 
       
   198 
       
   199 		// Remove the entry on 1st time failure
       
   200 		aCommsIdKey.iThreadEntry.RemoveCommsId(aCommsIdKey.iCommsId);
       
   201 
       
   202 		TInt rc =  aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aError, aCommsIdKey.iCommsId);			
       
   203 		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUPSErrorOnCompletion_NetworkLifeTimeNonSessionL(), error = %d, rc = %d"), aError, rc );
       
   204 		}
       
   205 
       
   206 
       
   207 	void HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TNetUpsDecision aNetUpsDecision)
       
   208 		{ // Tested
       
   209 		// process life time, entering session mode
       
   210 
       
   211 		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(), processId = %d, threadId = %d, commsId = %d, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
       
   212 					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   213 					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   214 					 	&aCommsIdKey.iCommsId.Node(),
       
   215 					 	&aPolicyCheckRequestOriginator,
       
   216 					 	aNetUpsDecision ); 
       
   217 
       
   218 		if (CNetUpsImpl::MapInternalStateToSessionMode(aState.State()) == CNetUpsImpl::ESessionMode)
       
   219 			{
       
   220 			// if already in session mode, reply with session decision
       
   221 			CNetUpsImpl::DetermineUpsDecision(aState.State(), aNetUpsDecision);					
       
   222 			}
       
   223 		else	
       
   224 			{
       
   225 			// otherwise not yet in session mode, so use the ups decision which has just returned.
       
   226 			TEvent event;		
       
   227 			aNetUpsDecision == ESessionYes ? event = EResponseSessionYes : event = EResponseSessionNo;	
       
   228 			aState.PerformStateTransition(event, aCommsIdKey.iProcessEntry);
       
   229 			}
       
   230 		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);								
       
   231 		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(), error = %d"), rc );
       
   232 
       
   233 		CleanUpThreadEntries_ProcessLifeTime(aCommsIdKey);
       
   234 						
       
   235 		if ((aCommsIdKey.iProcessEntry.ThreadEntry()).Count() == 0)
       
   236 			{
       
   237 			StartProcessMonitor(aCommsIdKey);
       
   238 			// if thread entry count = 0, must be ready to move from Transit_Session_Yes to Session_Yes
       
   239 			aState.PerformStateTransition(ETransitionForward, aCommsIdKey.iProcessEntry);
       
   240 			}
       
   241 		}		
       
   242 	
       
   243 	void HandleUPSErrorOnCompletion_EnteringProcessSessionLifeTimeL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TInt /*aError*/)
       
   244 		{				
       
   245 		// Covers the case that we are already in session life time, but outstanding UPS requests are completing
       
   246 		// Simply check if ready to transition to process life time.
       
   247 
       
   248 		// 	Determine the response to be given for all subsessions associated with this session.
       
   249 		TNetUpsDecision netUpsDecision;
       
   250 		CNetUpsImpl::DetermineUpsDecision(aState.State(), netUpsDecision);					
       
   251 		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(netUpsDecision, aCommsIdKey.iCommsId);								
       
   252 		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUPSErrorOnCompletion_EnteringProcessSessionLifeTimeL(), error = %d"), rc );
       
   253 		
       
   254 		CleanUpThreadEntries_ProcessLifeTime(aCommsIdKey);
       
   255 							
       
   256 		if ((aCommsIdKey.iProcessEntry.ThreadEntry()).Count() == 0)
       
   257 			{
       
   258 			StartProcessMonitor(aCommsIdKey);
       
   259 			// if thread entry count = 0, must be ready to move from Transit_Session_Yes to Session_Yes
       
   260 			aState.PerformStateTransition(ETransitionForward, aCommsIdKey.iProcessEntry);
       
   261 			}
       
   262 		}	
       
   263 
       
   264 	void CleanUpThreadEntries_ProcessLifeTime(TThreadKey& aThreadKey)
       
   265 		{ // Tested
       
   266 		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent, _L("::CleanUpThreadEntries_ProcessLifeTime() processId = %d, threadId = %d"),
       
   267 				 		aThreadKey.iProcessEntry.ProcessId().Id(), aThreadKey.iThreadEntry.ThreadId().Id() ); 
       
   268 
       
   269 		// 1st detach this subsession so it can be deleted inside CSubSession::RunL() 
       
   270 		// which is the top of this calling stack.
       
   271 		__ASSERT_DEBUG((aThreadKey.iThreadEntry.SubSession() != NULL), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
       
   272 		aThreadKey.iThreadEntry.SubSession()->SetReadyForDeletion();
       
   273 		aThreadKey.iThreadEntry.SetSubSession(NULL);			
       
   274 
       
   275 		// now clean up everything other than the current entry on the queue, 
       
   276 		// which is currently being processed and will be deleted by the subsession.
       
   277 		TNetUpsDecision netUpsDecision;
       
   278 		aThreadKey.iProcessEntry.UpsStateMachine().NetUpsImpl().DetermineUpsDecision(aThreadKey.iProcessEntry.NetUpsState(), netUpsDecision);
       
   279 		ReplyOutStandingRequests(aThreadKey, netUpsDecision);
       
   280 
       
   281 		// Code to bottom is used in method below, consider cloning
       
   282 		TInt count = aThreadKey.iProcessEntry.ThreadEntry().Count();
       
   283 		for (TInt i = count - 1; i >= 0; --i)
       
   284 			{
       
   285 			TBool readyToDelete = ETrue;
       
   286 			CThreadEntry* threadEntry = aThreadKey.iProcessEntry.ThreadEntry()[i];
       
   287 			if (threadEntry->ThreadMonitor() != NULL)
       
   288 				{
       
   289 				// Note: An active object remains active until immediately before its RunL is executed.
       
   290 				if (aThreadKey.iProcessEntry.ThreadEntry()[i]->ThreadMonitor()->IsActive() != EFalse)
       
   291 					{
       
   292 					threadEntry->ThreadMonitor()->Cancel();
       
   293 					}
       
   294 				delete threadEntry->ThreadMonitor();
       
   295 				threadEntry->SetThreadMonitor(NULL);
       
   296 				}
       
   297 						
       
   298 			if (threadEntry->SubSession() != NULL)
       
   299 				{
       
   300 				if (threadEntry->SubSession()->IsActive() == EFalse)
       
   301 					{
       
   302 					delete threadEntry->SubSession();
       
   303 					threadEntry->SetSubSession(NULL);
       
   304 					}
       
   305 				else
       
   306 					{
       
   307 					readyToDelete = EFalse;
       
   308 					TThreadKey threadKey(aThreadKey.iDatabaseEntry, aThreadKey.iProcessEntry, *threadEntry);
       
   309 					ReplyOutStandingRequests(threadKey, netUpsDecision);
       
   310 					}				
       
   311 				}
       
   312 	
       
   313 			if (readyToDelete)
       
   314 				{		
       
   315 				delete threadEntry;
       
   316 				aThreadKey.iProcessEntry.ThreadEntry().Remove(i);						
       
   317 				}									
       
   318 			}
       
   319 		}
       
   320 
       
   321 	void HandleUpsRequestCompletion_EnteringNetworkSessionLifeTimeL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TNetUpsDecision aNetUpsDecision)
       
   322 		{ // Tested
       
   323 		// network life time, non session mode
       
   324 		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringNetworkSessionLifeTimeL(), processId = %d, threadId = %d, commsId = %d, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
       
   325 					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   326 					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   327 					 	&aCommsIdKey.iCommsId.Node(),
       
   328 					 	&aPolicyCheckRequestOriginator,
       
   329 					 	aNetUpsDecision ); 
       
   330 			
       
   331 		if (CNetUpsImpl::MapInternalStateToSessionMode(aState.State()) == CNetUpsImpl::ESessionMode)
       
   332 			{
       
   333 			// if already in session mode, reply with session decision
       
   334 			CNetUpsImpl::DetermineUpsDecision(aState.State(), aNetUpsDecision);		
       
   335 			}
       
   336 
       
   337 		if (aNetUpsDecision == ESessionYes)
       
   338 			{
       
   339 			aCommsIdKey.iThreadEntry.IncrementConnectionCount(aCommsIdKey.iCommsId);
       
   340 			}		
       
   341 
       
   342 		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);					
       
   343 		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringNetworkSessionLifeTimeL(), error = %d"), rc );
       
   344 
       
   345 		CleanUpThreadEntries_NetworkLifeTime(aState, aCommsIdKey, aNetUpsDecision);
       
   346 		}			
       
   347 
       
   348 	void HandleUPSErrorOnCompletion_EnteringNetworkSessionLifeTimeL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TInt aError)
       
   349 		{
       
   350 		// network life time, non session mode
       
   351 #ifndef _DEBUG
       
   352 		(void) aError;
       
   353 #endif
       
   354 		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::CleanUpThreadEntries_NetworkLifeTime(), processId = %d, threadId = %d, commsId = %d, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
       
   355 					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   356 					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   357 					 	&aCommsIdKey.iCommsId.Node(),
       
   358 					 	&aPolicyCheckRequestOriginator,
       
   359 					 	aError ); 
       
   360 
       
   361 		// 	Determine the response to be given for all subsessions associated with this session.
       
   362 		TNetUpsDecision netUpsDecision = ENo;
       
   363 		CNetUpsImpl::DetermineUpsDecision(aState.State(), netUpsDecision);					
       
   364 		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(netUpsDecision, aCommsIdKey.iCommsId);								
       
   365 		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUPSErrorOnCompletion_EnteringNetworkSessionLifeTimeL(), error = %d"), rc );
       
   366 
       
   367 		CleanUpThreadEntries_NetworkLifeTime(aState, aCommsIdKey, netUpsDecision);					
       
   368 		}
       
   369 
       
   370 	void CleanUpThreadEntries_NetworkLifeTime(CState& aState, TCommsIdKey& aCommsIdKey, TNetUpsDecision aNetUpsDecision)
       
   371 		{ // Tested
       
   372 		// 1st detach this subsession so it can be deleted inside CSubSession::RunL() 
       
   373 		// which is the top of this calling stack.
       
   374 
       
   375 		__FLOG_STATIC4(KNetUpsSubsys, KNetUpsComponent,_L("::CleanUpThreadEntries_NetworkLifeTime(), processId = %d, threadId = %d, commsId = %d, netUpsDecision = %d"),
       
   376 				 aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   377 				 aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   378 				 &aCommsIdKey.iCommsId.Node(),
       
   379 				 aNetUpsDecision ); 
       
   380 
       
   381 		__ASSERT_DEBUG((aCommsIdKey.iThreadEntry.SubSession() != NULL), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
       
   382 		aCommsIdKey.iThreadEntry.SubSession()->SetReadyForDeletion();
       
   383 		aCommsIdKey.iThreadEntry.SetSubSession(NULL);			
       
   384 
       
   385 		ReplyOutStandingRequests(aCommsIdKey, aNetUpsDecision);
       
   386 
       
   387 		TBool allActiveObjectsCompleted = ETrue;
       
   388 		TInt count = aCommsIdKey.iProcessEntry.ThreadEntry().Count();
       
   389 		for (TInt i = 0; i < count; i++)
       
   390 			{
       
   391 			CThreadEntry* threadEntry = aCommsIdKey.iProcessEntry.ThreadEntry()[i];
       
   392 			if (threadEntry->ThreadMonitor() != NULL)
       
   393 				{
       
   394 				// Note: An active object remains active until immediately before its RunL is executed.				
       
   395 				if (threadEntry->ThreadMonitor()->IsActive() != EFalse)
       
   396 					{
       
   397 					threadEntry->ThreadMonitor()->Cancel();
       
   398 					}
       
   399 				delete threadEntry->ThreadMonitor();
       
   400 				threadEntry->SetThreadMonitor(NULL);
       
   401 				}
       
   402 			
       
   403 			if (threadEntry->SubSession() != NULL)
       
   404 				{
       
   405 				// Note: An active object remains active until immediately before its RunL is executed.				
       
   406 				if (threadEntry->SubSession()->IsActive() == EFalse)
       
   407 					{
       
   408 					delete threadEntry->SubSession();
       
   409 					threadEntry->SetSubSession(NULL);
       
   410 					}
       
   411 				else
       
   412 					{
       
   413 					allActiveObjectsCompleted = EFalse;
       
   414 					TThreadKey threadKey(aCommsIdKey.iDatabaseEntry, aCommsIdKey.iProcessEntry, *threadEntry);
       
   415 					ReplyOutStandingRequests(threadKey, aNetUpsDecision);
       
   416 					}	
       
   417 				}
       
   418 			}
       
   419 
       
   420 		__ASSERT_DEBUG(((aNetUpsDecision == ESessionYes) || (aNetUpsDecision == ESessionNo)), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
       
   421 		if (aNetUpsDecision == ESessionYes)
       
   422 			{				
       
   423 			PerformTransitionFromNetworkLifeTimeNonSession(aState, EResponseSessionYes, aCommsIdKey, allActiveObjectsCompleted);			
       
   424 			}
       
   425 		else if (aNetUpsDecision == ESessionNo)
       
   426 			{
       
   427 			TInt count = aCommsIdKey.iProcessEntry.ThreadEntry().Count();
       
   428 			TBool allCountsZero = ETrue;
       
   429 			for (TInt i = 0; i < count; i++)
       
   430 				{
       
   431 				if ( (aCommsIdKey.iProcessEntry.ThreadEntry())[i]->ConnectionCount() != 0 )
       
   432 					{
       
   433 					allCountsZero = EFalse;
       
   434 					break;
       
   435 					}
       
   436 				}
       
   437 						
       
   438 			if (allCountsZero)
       
   439 				{
       
   440 				PerformTransitionFromNetworkLifeTimeNonSession(aState, EResponseSessionNo_WithoutConnections, aCommsIdKey, allActiveObjectsCompleted);			
       
   441 				}	
       
   442 			else
       
   443 				{
       
   444 				PerformTransitionFromNetworkLifeTimeNonSession(aState, EResponseSessionNo_WithConnections, aCommsIdKey, allActiveObjectsCompleted);			
       
   445 				}			
       
   446 			}
       
   447 		}
       
   448 
       
   449 	void HandleProcessTermination(TProcessKey& aProcessKey)
       
   450 		{ // Not Tested
       
   451 		// Needed for process life time - session Yes / session No
       
   452 		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent, _L("::HandleProcessTermination() processId = %d"), aProcessKey.iProcessEntry.ProcessId().Id()); 
       
   453 		TBool retainProcessMonitor = ETrue;
       
   454 		DeleteProcessEntry(aProcessKey, retainProcessMonitor);
       
   455 		}
       
   456 
       
   457 	void HandleThreadTermination_DeleteThreadEntry(TThreadKey& aThreadKey)
       
   458 		{ // Tested
       
   459 		// Could add reason for thread termination, but end result is the same.
       
   460 
       
   461 		// Handles the following states:
       
   462 		// Process Life Time Non Session - No Movement
       
   463 		// Network Life Time Non Session - No Movement		
       
   464 		// The thread monitors should be cancelled before entry into any other state.
       
   465 		TNetUpsState state = aThreadKey.iProcessEntry.NetUpsState();
       
   466 		__ASSERT_DEBUG(((state == EProcLife_NonSession) || (state == ENetLife_NonSession)), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
       
   467 		
       
   468 		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent, _L("::HandleThreadTermination_DeleteThreadEntry() processId = %d, threadId = %d"),
       
   469 				 		aThreadKey.iProcessEntry.ProcessId().Id(), aThreadKey.iThreadEntry.ThreadId().Id() ); 
       
   470 
       
   471 		CThreadEntry& threadEntry = aThreadKey.iThreadEntry;
       
   472 		threadEntry.SetThreadMonitor(NULL); // Set the thread monitor to NULL, as  currently called
       
   473 											// from threadMonitor RunL, which deletes itself at end of RunL.
       
   474 
       
   475 		if (aThreadKey.iThreadEntry.SubSession() != NULL) 
       
   476 			{
       
   477 			// cancel all requests and reply back with KErrDied to the originator.
       
   478 			threadEntry.RequestQueue().CancelAllRequests(KErrDied);
       
   479 			DeleteThreadEntry(aThreadKey);						
       
   480 			if (aThreadKey.iProcessEntry.ThreadEntry().Count() == 0)		
       
   481 				{
       
   482 				DeleteProcessEntry(aThreadKey);
       
   483 				}				
       
   484 			}
       
   485 		}
       
   486 
       
   487 	void IncrementConnectionCountL(TCommsIdKey&)
       
   488 		{
       
   489 		__FLOG_STATIC0(KNetUpsSubsys, KNetUpsComponent, _L("::IncrementConnectionCountL"));
       
   490 		User::Panic(KNetUpsPanic, KPanicMethodNotSupported);
       
   491 		}				
       
   492 
       
   493 	void DecrementConnectionCount_NetworkLifeTime_SessionL(TCommsIdKey& aCommsIdKey)
       
   494 		{ // Tested
       
   495 		// Network Lifetime - Session No - MCPR Count
       
   496 		// Network Lifetime - Session Yes
       
   497 
       
   498 		// Remove the comms id 1st
       
   499 		//  
       
   500 		__FLOG_STATIC3(KNetUpsSubsys, KNetUpsComponent, _L("::DecrementConnectionCount_NetworkLifeTime_SessionL(), processId = %d, threadId = %d, commsId = %d, aError = %d"),
       
   501 					 aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   502 					 aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   503 					 &aCommsIdKey.iCommsId.Node()); 
       
   504 
       
   505 		TNetUpsState state = aCommsIdKey.iProcessEntry.NetUpsState();
       
   506 
       
   507 		__ASSERT_DEBUG(((state == ENetLife_Transit_SessionYes) 					||
       
   508 						(state == ENetLife_SessionYes) 							||
       
   509 						(state == ENetLife_SessionNo_Transit_WithConnections) 	||
       
   510 						(state == ENetLife_SessionNo_WithConnections)),
       
   511 						User::Panic(KNetUpsPanic, KPanicInvalidLogic));
       
   512 
       
   513 		DecrementConnectionCount_NetworkLifeTime_NonSessionL(aCommsIdKey);
       
   514 									
       
   515 		if (aCommsIdKey.iProcessEntry.ThreadEntry().Count() == 0)
       
   516 			{
       
   517 			TProcessKey processKey(aCommsIdKey.iDatabaseEntry, aCommsIdKey.iProcessEntry);
       
   518 			DeleteProcessEntry(processKey);				
       
   519 			}			
       
   520 		}				
       
   521 	
       
   522 	void DecrementConnectionCount_NetworkLifeTime_NonSessionL(TCommsIdKey& aCommsIdKey)
       
   523 		{ // Tested
       
   524 		__FLOG_STATIC3(KNetUpsSubsys, KNetUpsComponent, _L("::DecrementConnectionCount_NetworkLifeTime_NonSessionL(), processId = %d, threadId = %d, commsId = %d, aError = %d"),
       
   525 					 aCommsIdKey.iProcessEntry.ProcessId().Id(),
       
   526 					 aCommsIdKey.iThreadEntry.ThreadId().Id(),
       
   527 					 &aCommsIdKey.iCommsId.Node()); 
       
   528 
       
   529 		aCommsIdKey.iThreadEntry.DecrementConnectionCount(aCommsIdKey.iCommsId);
       
   530 
       
   531 		TInt32 connectionCount = aCommsIdKey.iThreadEntry.ConnectionCount();
       
   532 		if (connectionCount == 0) 
       
   533 			{
       
   534 			TThreadKey threadKey(aCommsIdKey.iDatabaseEntry, aCommsIdKey.iProcessEntry, aCommsIdKey.iThreadEntry);
       
   535 			DeleteThreadEntry(threadKey);	// results in an active thread monitor being cancelled then deleted.			
       
   536 			}			
       
   537 		}				
       
   538 
       
   539 	void StartProcessMonitor(TProcessKey& aProcessKey)
       
   540 		{ // Tested
       
   541 		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent, _L("::StartProcessMonitor() processId = %d"), aProcessKey.iProcessEntry.ProcessId().Id()); 
       
   542 		__ASSERT_DEBUG((aProcessKey.iProcessEntry.ProcessMonitor() != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsAction3));					
       
   543 		__ASSERT_DEBUG((aProcessKey.iProcessEntry.ProcessMonitor()->IsActive() == EFalse), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
       
   544 		aProcessKey.iProcessEntry.ProcessMonitor()->Start();			
       
   545 		}
       
   546 
       
   547 	void DeleteProcessEntry(TProcessKey& aProcessKey, TBool aRetainProcessMonitor)
       
   548 		{ //Not Tested
       
   549 		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent, _L("::DeleteProcessEntry() processId = %d"), aProcessKey.iProcessEntry.ProcessId().Id()); 
       
   550 		
       
   551 		if (aRetainProcessMonitor != EFalse)
       
   552 			{
       
   553 			aProcessKey.iProcessEntry.SetProcessMonitor(NULL);
       
   554 			// running within the calling stack of CProcessMonitor::RunL(), so delete the
       
   555 			// process monitor when at the end of its RunL method.
       
   556 			}
       
   557 
       
   558 		for (TInt i = aProcessKey.iDatabaseEntry.ProcessEntry().Count() - 1; i >=0; --i )
       
   559 			{
       
   560 			if ((aProcessKey.iDatabaseEntry.ProcessEntry())[i]->ProcessId() == aProcessKey.iProcessEntry.ProcessId())
       
   561 				{
       
   562 				delete (aProcessKey.iDatabaseEntry.ProcessEntry())[i]; 
       
   563 				aProcessKey.iDatabaseEntry.ProcessEntry()[i] = 0; 
       
   564 				aProcessKey.iDatabaseEntry.ProcessEntry().Remove(i); // do we need to consider compression ?
       
   565 				break;
       
   566 				}	
       
   567 			}					
       
   568 		}
       
   569 
       
   570 	void DeleteThreadEntry(TThreadKey& aThreadKey)
       
   571 		{// Tested
       
   572 		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent, _L("::DeleteThreadEntry() processId = %d, threadId = %d"),
       
   573 				 		aThreadKey.iProcessEntry.ProcessId().Id(), aThreadKey.iThreadEntry.ThreadId().Id() ); 
       
   574 
       
   575 
       
   576 		for (TInt i = aThreadKey.iProcessEntry.ThreadEntry().Count() - 1; i >=0; --i )
       
   577 			{
       
   578 			if ((aThreadKey.iProcessEntry.ThreadEntry())[i]->ThreadId() == aThreadKey.iThreadEntry.ThreadId())
       
   579 				{
       
   580 				delete (aThreadKey.iProcessEntry.ThreadEntry())[i]; 
       
   581 				aThreadKey.iProcessEntry.ThreadEntry()[i] = 0; 
       
   582 				aThreadKey.iProcessEntry.ThreadEntry().Remove(i); // do we need to consider compression ?
       
   583 				break;
       
   584 				}	
       
   585 			}	
       
   586 		}
       
   587 
       
   588 	void ReplyOutStandingRequests(TThreadKey& aThreadKey)
       
   589 		{
       
   590 		CNetUpsImpl& netUpsImpl  = aThreadKey.iProcessEntry.UpsStateMachine().NetUpsImpl();
       
   591 		TNetUpsState netUpsState = aThreadKey.iProcessEntry.NetUpsState();
       
   592 
       
   593 		TNetUpsDecision netUpsDecision = ENo;
       
   594 		if (netUpsImpl.MapInternalStateToSessionMode(netUpsState) == CNetUpsImpl::ESessionMode)
       
   595 			{
       
   596 			aThreadKey.iProcessEntry.UpsStateMachine().NetUpsImpl().DetermineUpsDecision(netUpsState, netUpsDecision);
       
   597 			}
       
   598 			
       
   599 		ReplyOutStandingRequests(aThreadKey, netUpsDecision);
       
   600 		}
       
   601 
       
   602 	void ReplyOutStandingRequests(TThreadKey& aThreadKey, TNetUpsDecision aNetUpsDecision)
       
   603 		{
       
   604 		while (aThreadKey.iThreadEntry.RequestQueue().OutStandingRequestToProcess() != EFalse)
       
   605 			{
       
   606 
       
   607 			CPolicyCheckRequestData& policyCheckRequestData = aThreadKey.iThreadEntry.RequestQueue().GetOutStandingRequestToProcess();
       
   608 
       
   609 			if ((aNetUpsDecision == ESessionYes) || (aNetUpsDecision == EYes))
       
   610 				{
       
   611 				aThreadKey.iThreadEntry.IncrementConnectionCountL(policyCheckRequestData.iCommsId);
       
   612 				}
       
   613 			
       
   614 			TInt rc = policyCheckRequestData.iPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, 
       
   615 																									  policyCheckRequestData.iCommsId);
       
   616 			__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::ReplyOutStandingRequests(), error = %d"), rc );
       
   617 			aThreadKey.iThreadEntry.RequestQueue().DeleteOutStandingRequest();					
       
   618 			}	
       
   619 		}
       
   620 
       
   621 	void PerformTransitionFromNetworkLifeTimeNonSession(CState& aState, TEvent aEvent, TCommsIdKey& aCommsIdKey, TBool aAllActiveObjectsCompleted)
       
   622 		{
       
   623 		switch(aEvent)
       
   624 			{
       
   625 			case EResponseSessionYes:
       
   626 				aState.PerformStateTransition(EResponseSessionYes, aCommsIdKey.iProcessEntry);
       
   627 				break;
       
   628 			case EResponseSessionNo_WithoutConnections:
       
   629 				aState.PerformStateTransition(EResponseSessionNo_WithoutConnections, aCommsIdKey.iProcessEntry);
       
   630 				break;
       
   631 			case EResponseSessionNo_WithConnections:
       
   632 				aState.PerformStateTransition(EResponseSessionNo_WithConnections, aCommsIdKey.iProcessEntry);
       
   633 				break;
       
   634 			default:
       
   635 				User::Panic(KNetUpsPanic, KPanicInvalidLogic);					
       
   636 				break;
       
   637 			}
       
   638 
       
   639 		if (aAllActiveObjectsCompleted != EFalse)
       
   640 			{
       
   641 			switch(aEvent)
       
   642 				{
       
   643 				case EResponseSessionNo_WithoutConnections:
       
   644 					StartProcessMonitor(aCommsIdKey);
       
   645 					// drop through to perform state transition
       
   646 				case EResponseSessionYes:
       
   647 					// drop through to perform state transition
       
   648 				case EResponseSessionNo_WithConnections:
       
   649 					aState.PerformStateTransition(ETransitionForward, aCommsIdKey.iProcessEntry);	
       
   650 					break;
       
   651 				default:
       
   652 					User::Panic(KNetUpsPanic, KPanicInvalidLogic);					
       
   653 					break;
       
   654 				}
       
   655 			}
       
   656 		}
       
   657 	
       
   658 	} // end of namespace NetUpsFunctions
       
   659 } // end of namespace NetUps
       
   660