networkcontrol/commsuserpromptmgr/state/src/netupsaction.cpp
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkcontrol/commsuserpromptmgr/state/src/netupsaction.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,660 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This file provides the implementation of the NetUps Utility Functions.
+// Most / all of thes methods seem destinated to migrate into the netupsstate.cpp file.
+// @internalAll
+// @prototype
+// 
+//
+
+
+#include "e32cmn.h"
+
+#include <comms-infras/ss_activities.h>
+
+#include "netupsaction.h"
+
+#include "netupsassert.h"
+#include "netupstypes.h"			// defines TNetUpsDecision
+#include "netupsstatemachine.h"		// defines the NetUps State Machine
+
+#include "netupsdatabaseentry.h"
+#include "netupsprocessentry.h"
+#include "netupsthreadentry.h"
+#include "netupsprocessmonitor.h"
+#include "netupsthreadmonitor.h"
+#include "netupssubsession.h"
+
+#include "netupspolicycheckrequestqueue.h"
+
+#include "netupsstatedef.h"
+
+#include <comms-infras/commsdebugutility.h> 		// defines the comms debug logging utility
+
+using namespace ESock;
+
+namespace NetUps
+{
+__FLOG_STMT(_LIT8(KNetUpsSubsys, 	"esock");)   
+__FLOG_STMT(_LIT8(KNetUpsComponent, "NetUps");) /*esockloader*/
+
+	namespace NetUpsFunctions 
+	{
+
+	void HandleUPSRequestL(CState& aState, TThreadKey& aThreadKey, const TPolicyCheckRequestData& aPolicyCheckRequestData, TRequestId aRequestId)
+	// Process Life Time Non Session
+	// Network Life Time Non Session 
+	// CNullState
+		{
+		__FLOG_STATIC7(KNetUpsSubsys, KNetUpsComponent, _L("::HandleUPSRequestL(), processId = %d, threadId = %d, serviceId  = %d, platSecCheckResult  = %d, NodeId  = %08x, originator  = %08x, requestId = %d"),
+					 aPolicyCheckRequestData.iProcessId.Id(),
+					 aPolicyCheckRequestData.iThreadId.Id(),		aPolicyCheckRequestData.iServiceId,
+					 aPolicyCheckRequestData.iPlatSecCheckResult, 	&aPolicyCheckRequestData.iCommsId.Node(),
+					 &(aPolicyCheckRequestData.iPolicyCheckRequestOriginator), aRequestId); 
+
+		aThreadKey.iThreadEntry.AddCommsIdL(aPolicyCheckRequestData.iCommsId);
+		TRAPD(err, aThreadKey.iThreadEntry.RequestQueue().SendRequestL(aPolicyCheckRequestData, aRequestId));
+		if (err != KErrNone)
+			{
+			// 1st back out the CommsId which we have just added, provided there are no
+			// connections currently associated with it.
+			aThreadKey.iThreadEntry.RemoveCommsId(aPolicyCheckRequestData.iCommsId);
+			// 2nd, leave with original error, presumably KErrNoMemory
+			User::Leave(err);
+			}
+
+		aState.PerformStateTransition(EPolicyCheckRequest, aThreadKey.iProcessEntry);
+		}
+
+	void HandleUpsRequestCompletion_ProcessLifeTimeNonSessionL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TNetUpsDecision aNetUpsDecision)
+		{ // Tested
+		// process life time, non session
+		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_ProcessLifeTimeNonSessionL(), processId = %d, threadId = %d, nodeId = %08x, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
+					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 	&aCommsIdKey.iCommsId.Node(),
+					 	&aPolicyCheckRequestOriginator,
+					 	aNetUpsDecision );
+					
+		switch(aNetUpsDecision) 
+			{			
+			case ENo:
+				//  if request fails, remove the record of the commsid (cosmetic).
+				aCommsIdKey.iThreadEntry.RemoveCommsId(aCommsIdKey.iCommsId);
+				// intended fall through
+			case EYes:
+				{
+				__ASSERT_DEBUG((aCommsIdKey.iThreadEntry.ThreadMonitor() != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsAction));					
+				if (aCommsIdKey.iThreadEntry.ThreadMonitor()->IsActive() == EFalse)
+					{
+					aCommsIdKey.iThreadEntry.ThreadMonitor()->Start();						
+					}
+				TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);
+				__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_ProcessLifeTimeNonSessionL(), error = %d"), rc);
+				break;	
+				}
+			case ESessionYes:
+			case ESessionNo:
+				{
+				HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(aState, aCommsIdKey, aPolicyCheckRequestOriginator, aNetUpsDecision);
+				break;
+				}
+			default:
+				{
+				HandleUPSErrorOnCompletion_ProcessLifeTimeNonSessionL(aCommsIdKey, aPolicyCheckRequestOriginator, KErrCorrupt);
+				break;
+				}
+			}
+		}
+
+	void HandleUPSErrorOnCompletion_ProcessLifeTimeNonSessionL(TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TInt aError)
+		{
+		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(), processId = %d, threadId = %d, nodeId = %08x, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
+					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 	&aCommsIdKey.iCommsId.Node(),
+					 	&aPolicyCheckRequestOriginator,
+					 	aError ); 
+
+		// Remove the entry on 1st time failure	
+		aCommsIdKey.iThreadEntry.RemoveCommsId(aCommsIdKey.iCommsId);
+		
+		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aError, aCommsIdKey.iCommsId);			
+		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUPSErrorOnCompletion_ProcessLifeTimeNonSessionL(), error = %d, rc = %d"), aError, rc );
+		}
+
+	void HandleUpsRequestCompletion_NetworkLifeTimeNonSessionL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TNetUpsDecision aNetUpsDecision)
+		{ // Tested
+		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_NetworkLifeTimeNonSessionL(), processId = %d, threadId = %d, nodeId = %08x, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
+					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 	&aCommsIdKey.iCommsId.Node(),
+					 	&aPolicyCheckRequestOriginator,
+					 	aNetUpsDecision ); 
+
+		// network life time, non session		
+		switch(aNetUpsDecision) 
+			{			
+			case EYes:
+				{
+				aCommsIdKey.iThreadEntry.IncrementConnectionCount(aCommsIdKey.iCommsId);
+
+				__ASSERT_DEBUG((aCommsIdKey.iThreadEntry.ThreadMonitor() != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsAction1));					
+				if (aCommsIdKey.iThreadEntry.ThreadMonitor()->IsActive() == EFalse)
+					{
+					aCommsIdKey.iThreadEntry.ThreadMonitor()->Start();
+					}
+				TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);
+				__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_NetworkLifeTimeNonSessionL(), error = %d"), rc );
+				break;
+				}
+			case ENo:
+				{
+				//  if request fails, remove the record of the commsid
+				aCommsIdKey.iThreadEntry.RemoveCommsId(aCommsIdKey.iCommsId);		
+				
+				__ASSERT_DEBUG((aCommsIdKey.iThreadEntry.ThreadMonitor() != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsAction2));					
+				if (aCommsIdKey.iThreadEntry.ThreadMonitor()->IsActive() == EFalse)
+					{
+					aCommsIdKey.iThreadEntry.ThreadMonitor()->Start();
+					}
+				TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);
+				__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_NetworkLifeTimeNonSessionL(), error = %d"), rc );
+				break;	
+				}
+			case ESessionYes:
+			case ESessionNo:
+				{
+				HandleUpsRequestCompletion_EnteringNetworkSessionLifeTimeL(aState, aCommsIdKey, aPolicyCheckRequestOriginator, aNetUpsDecision);
+				break;
+				}
+			default:
+				{
+				HandleUPSErrorOnCompletion_NetworkLifeTimeNonSessionL(aCommsIdKey, aPolicyCheckRequestOriginator, KErrCorrupt);
+				break;
+				}
+			}
+		}
+
+	void HandleUPSErrorOnCompletion_NetworkLifeTimeNonSessionL(TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TInt aError)
+		{
+		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringNetworkLifeTimeL(), processId = %d, threadId = %d, commsId = %08x, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
+					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 	&aCommsIdKey.iCommsId.Node(),
+					 	&aPolicyCheckRequestOriginator,
+					 	aError ); 
+
+		// Remove the entry on 1st time failure
+		aCommsIdKey.iThreadEntry.RemoveCommsId(aCommsIdKey.iCommsId);
+
+		TInt rc =  aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aError, aCommsIdKey.iCommsId);			
+		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUPSErrorOnCompletion_NetworkLifeTimeNonSessionL(), error = %d, rc = %d"), aError, rc );
+		}
+
+
+	void HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TNetUpsDecision aNetUpsDecision)
+		{ // Tested
+		// process life time, entering session mode
+
+		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(), processId = %d, threadId = %d, commsId = %d, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
+					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 	&aCommsIdKey.iCommsId.Node(),
+					 	&aPolicyCheckRequestOriginator,
+					 	aNetUpsDecision ); 
+
+		if (CNetUpsImpl::MapInternalStateToSessionMode(aState.State()) == CNetUpsImpl::ESessionMode)
+			{
+			// if already in session mode, reply with session decision
+			CNetUpsImpl::DetermineUpsDecision(aState.State(), aNetUpsDecision);					
+			}
+		else	
+			{
+			// otherwise not yet in session mode, so use the ups decision which has just returned.
+			TEvent event;		
+			aNetUpsDecision == ESessionYes ? event = EResponseSessionYes : event = EResponseSessionNo;	
+			aState.PerformStateTransition(event, aCommsIdKey.iProcessEntry);
+			}
+		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);								
+		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringProcessSessionLifeTimeL(), error = %d"), rc );
+
+		CleanUpThreadEntries_ProcessLifeTime(aCommsIdKey);
+						
+		if ((aCommsIdKey.iProcessEntry.ThreadEntry()).Count() == 0)
+			{
+			StartProcessMonitor(aCommsIdKey);
+			// if thread entry count = 0, must be ready to move from Transit_Session_Yes to Session_Yes
+			aState.PerformStateTransition(ETransitionForward, aCommsIdKey.iProcessEntry);
+			}
+		}		
+	
+	void HandleUPSErrorOnCompletion_EnteringProcessSessionLifeTimeL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TInt /*aError*/)
+		{				
+		// Covers the case that we are already in session life time, but outstanding UPS requests are completing
+		// Simply check if ready to transition to process life time.
+
+		// 	Determine the response to be given for all subsessions associated with this session.
+		TNetUpsDecision netUpsDecision;
+		CNetUpsImpl::DetermineUpsDecision(aState.State(), netUpsDecision);					
+		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(netUpsDecision, aCommsIdKey.iCommsId);								
+		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUPSErrorOnCompletion_EnteringProcessSessionLifeTimeL(), error = %d"), rc );
+		
+		CleanUpThreadEntries_ProcessLifeTime(aCommsIdKey);
+							
+		if ((aCommsIdKey.iProcessEntry.ThreadEntry()).Count() == 0)
+			{
+			StartProcessMonitor(aCommsIdKey);
+			// if thread entry count = 0, must be ready to move from Transit_Session_Yes to Session_Yes
+			aState.PerformStateTransition(ETransitionForward, aCommsIdKey.iProcessEntry);
+			}
+		}	
+
+	void CleanUpThreadEntries_ProcessLifeTime(TThreadKey& aThreadKey)
+		{ // Tested
+		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent, _L("::CleanUpThreadEntries_ProcessLifeTime() processId = %d, threadId = %d"),
+				 		aThreadKey.iProcessEntry.ProcessId().Id(), aThreadKey.iThreadEntry.ThreadId().Id() ); 
+
+		// 1st detach this subsession so it can be deleted inside CSubSession::RunL() 
+		// which is the top of this calling stack.
+		__ASSERT_DEBUG((aThreadKey.iThreadEntry.SubSession() != NULL), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
+		aThreadKey.iThreadEntry.SubSession()->SetReadyForDeletion();
+		aThreadKey.iThreadEntry.SetSubSession(NULL);			
+
+		// now clean up everything other than the current entry on the queue, 
+		// which is currently being processed and will be deleted by the subsession.
+		TNetUpsDecision netUpsDecision;
+		aThreadKey.iProcessEntry.UpsStateMachine().NetUpsImpl().DetermineUpsDecision(aThreadKey.iProcessEntry.NetUpsState(), netUpsDecision);
+		ReplyOutStandingRequests(aThreadKey, netUpsDecision);
+
+		// Code to bottom is used in method below, consider cloning
+		TInt count = aThreadKey.iProcessEntry.ThreadEntry().Count();
+		for (TInt i = count - 1; i >= 0; --i)
+			{
+			TBool readyToDelete = ETrue;
+			CThreadEntry* threadEntry = aThreadKey.iProcessEntry.ThreadEntry()[i];
+			if (threadEntry->ThreadMonitor() != NULL)
+				{
+				// Note: An active object remains active until immediately before its RunL is executed.
+				if (aThreadKey.iProcessEntry.ThreadEntry()[i]->ThreadMonitor()->IsActive() != EFalse)
+					{
+					threadEntry->ThreadMonitor()->Cancel();
+					}
+				delete threadEntry->ThreadMonitor();
+				threadEntry->SetThreadMonitor(NULL);
+				}
+						
+			if (threadEntry->SubSession() != NULL)
+				{
+				if (threadEntry->SubSession()->IsActive() == EFalse)
+					{
+					delete threadEntry->SubSession();
+					threadEntry->SetSubSession(NULL);
+					}
+				else
+					{
+					readyToDelete = EFalse;
+					TThreadKey threadKey(aThreadKey.iDatabaseEntry, aThreadKey.iProcessEntry, *threadEntry);
+					ReplyOutStandingRequests(threadKey, netUpsDecision);
+					}				
+				}
+	
+			if (readyToDelete)
+				{		
+				delete threadEntry;
+				aThreadKey.iProcessEntry.ThreadEntry().Remove(i);						
+				}									
+			}
+		}
+
+	void HandleUpsRequestCompletion_EnteringNetworkSessionLifeTimeL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TNetUpsDecision aNetUpsDecision)
+		{ // Tested
+		// network life time, non session mode
+		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringNetworkSessionLifeTimeL(), processId = %d, threadId = %d, commsId = %d, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
+					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 	&aCommsIdKey.iCommsId.Node(),
+					 	&aPolicyCheckRequestOriginator,
+					 	aNetUpsDecision ); 
+			
+		if (CNetUpsImpl::MapInternalStateToSessionMode(aState.State()) == CNetUpsImpl::ESessionMode)
+			{
+			// if already in session mode, reply with session decision
+			CNetUpsImpl::DetermineUpsDecision(aState.State(), aNetUpsDecision);		
+			}
+
+		if (aNetUpsDecision == ESessionYes)
+			{
+			aCommsIdKey.iThreadEntry.IncrementConnectionCount(aCommsIdKey.iCommsId);
+			}		
+
+		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, aCommsIdKey.iCommsId);					
+		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUpsRequestCompletion_EnteringNetworkSessionLifeTimeL(), error = %d"), rc );
+
+		CleanUpThreadEntries_NetworkLifeTime(aState, aCommsIdKey, aNetUpsDecision);
+		}			
+
+	void HandleUPSErrorOnCompletion_EnteringNetworkSessionLifeTimeL(CState& aState, TCommsIdKey& aCommsIdKey, MPolicyCheckRequestOriginator& aPolicyCheckRequestOriginator, TInt aError)
+		{
+		// network life time, non session mode
+#ifndef _DEBUG
+		(void) aError;
+#endif
+		__FLOG_STATIC5(KNetUpsSubsys, KNetUpsComponent,_L("::CleanUpThreadEntries_NetworkLifeTime(), processId = %d, threadId = %d, commsId = %d, aPolicyCheckRequestOriginator = %08x, netUpsDecision = %d"),
+					 	aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 	aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 	&aCommsIdKey.iCommsId.Node(),
+					 	&aPolicyCheckRequestOriginator,
+					 	aError ); 
+
+		// 	Determine the response to be given for all subsessions associated with this session.
+		TNetUpsDecision netUpsDecision = ENo;
+		CNetUpsImpl::DetermineUpsDecision(aState.State(), netUpsDecision);					
+		TInt rc = aPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(netUpsDecision, aCommsIdKey.iCommsId);								
+		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::HandleUPSErrorOnCompletion_EnteringNetworkSessionLifeTimeL(), error = %d"), rc );
+
+		CleanUpThreadEntries_NetworkLifeTime(aState, aCommsIdKey, netUpsDecision);					
+		}
+
+	void CleanUpThreadEntries_NetworkLifeTime(CState& aState, TCommsIdKey& aCommsIdKey, TNetUpsDecision aNetUpsDecision)
+		{ // Tested
+		// 1st detach this subsession so it can be deleted inside CSubSession::RunL() 
+		// which is the top of this calling stack.
+
+		__FLOG_STATIC4(KNetUpsSubsys, KNetUpsComponent,_L("::CleanUpThreadEntries_NetworkLifeTime(), processId = %d, threadId = %d, commsId = %d, netUpsDecision = %d"),
+				 aCommsIdKey.iProcessEntry.ProcessId().Id(),
+				 aCommsIdKey.iThreadEntry.ThreadId().Id(),
+				 &aCommsIdKey.iCommsId.Node(),
+				 aNetUpsDecision ); 
+
+		__ASSERT_DEBUG((aCommsIdKey.iThreadEntry.SubSession() != NULL), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
+		aCommsIdKey.iThreadEntry.SubSession()->SetReadyForDeletion();
+		aCommsIdKey.iThreadEntry.SetSubSession(NULL);			
+
+		ReplyOutStandingRequests(aCommsIdKey, aNetUpsDecision);
+
+		TBool allActiveObjectsCompleted = ETrue;
+		TInt count = aCommsIdKey.iProcessEntry.ThreadEntry().Count();
+		for (TInt i = 0; i < count; i++)
+			{
+			CThreadEntry* threadEntry = aCommsIdKey.iProcessEntry.ThreadEntry()[i];
+			if (threadEntry->ThreadMonitor() != NULL)
+				{
+				// Note: An active object remains active until immediately before its RunL is executed.				
+				if (threadEntry->ThreadMonitor()->IsActive() != EFalse)
+					{
+					threadEntry->ThreadMonitor()->Cancel();
+					}
+				delete threadEntry->ThreadMonitor();
+				threadEntry->SetThreadMonitor(NULL);
+				}
+			
+			if (threadEntry->SubSession() != NULL)
+				{
+				// Note: An active object remains active until immediately before its RunL is executed.				
+				if (threadEntry->SubSession()->IsActive() == EFalse)
+					{
+					delete threadEntry->SubSession();
+					threadEntry->SetSubSession(NULL);
+					}
+				else
+					{
+					allActiveObjectsCompleted = EFalse;
+					TThreadKey threadKey(aCommsIdKey.iDatabaseEntry, aCommsIdKey.iProcessEntry, *threadEntry);
+					ReplyOutStandingRequests(threadKey, aNetUpsDecision);
+					}	
+				}
+			}
+
+		__ASSERT_DEBUG(((aNetUpsDecision == ESessionYes) || (aNetUpsDecision == ESessionNo)), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
+		if (aNetUpsDecision == ESessionYes)
+			{				
+			PerformTransitionFromNetworkLifeTimeNonSession(aState, EResponseSessionYes, aCommsIdKey, allActiveObjectsCompleted);			
+			}
+		else if (aNetUpsDecision == ESessionNo)
+			{
+			TInt count = aCommsIdKey.iProcessEntry.ThreadEntry().Count();
+			TBool allCountsZero = ETrue;
+			for (TInt i = 0; i < count; i++)
+				{
+				if ( (aCommsIdKey.iProcessEntry.ThreadEntry())[i]->ConnectionCount() != 0 )
+					{
+					allCountsZero = EFalse;
+					break;
+					}
+				}
+						
+			if (allCountsZero)
+				{
+				PerformTransitionFromNetworkLifeTimeNonSession(aState, EResponseSessionNo_WithoutConnections, aCommsIdKey, allActiveObjectsCompleted);			
+				}	
+			else
+				{
+				PerformTransitionFromNetworkLifeTimeNonSession(aState, EResponseSessionNo_WithConnections, aCommsIdKey, allActiveObjectsCompleted);			
+				}			
+			}
+		}
+
+	void HandleProcessTermination(TProcessKey& aProcessKey)
+		{ // Not Tested
+		// Needed for process life time - session Yes / session No
+		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent, _L("::HandleProcessTermination() processId = %d"), aProcessKey.iProcessEntry.ProcessId().Id()); 
+		TBool retainProcessMonitor = ETrue;
+		DeleteProcessEntry(aProcessKey, retainProcessMonitor);
+		}
+
+	void HandleThreadTermination_DeleteThreadEntry(TThreadKey& aThreadKey)
+		{ // Tested
+		// Could add reason for thread termination, but end result is the same.
+
+		// Handles the following states:
+		// Process Life Time Non Session - No Movement
+		// Network Life Time Non Session - No Movement		
+		// The thread monitors should be cancelled before entry into any other state.
+		TNetUpsState state = aThreadKey.iProcessEntry.NetUpsState();
+		__ASSERT_DEBUG(((state == EProcLife_NonSession) || (state == ENetLife_NonSession)), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
+		
+		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent, _L("::HandleThreadTermination_DeleteThreadEntry() processId = %d, threadId = %d"),
+				 		aThreadKey.iProcessEntry.ProcessId().Id(), aThreadKey.iThreadEntry.ThreadId().Id() ); 
+
+		CThreadEntry& threadEntry = aThreadKey.iThreadEntry;
+		threadEntry.SetThreadMonitor(NULL); // Set the thread monitor to NULL, as  currently called
+											// from threadMonitor RunL, which deletes itself at end of RunL.
+
+		if (aThreadKey.iThreadEntry.SubSession() != NULL) 
+			{
+			// cancel all requests and reply back with KErrDied to the originator.
+			threadEntry.RequestQueue().CancelAllRequests(KErrDied);
+			DeleteThreadEntry(aThreadKey);						
+			if (aThreadKey.iProcessEntry.ThreadEntry().Count() == 0)		
+				{
+				DeleteProcessEntry(aThreadKey);
+				}				
+			}
+		}
+
+	void IncrementConnectionCountL(TCommsIdKey&)
+		{
+		__FLOG_STATIC0(KNetUpsSubsys, KNetUpsComponent, _L("::IncrementConnectionCountL"));
+		User::Panic(KNetUpsPanic, KPanicMethodNotSupported);
+		}				
+
+	void DecrementConnectionCount_NetworkLifeTime_SessionL(TCommsIdKey& aCommsIdKey)
+		{ // Tested
+		// Network Lifetime - Session No - MCPR Count
+		// Network Lifetime - Session Yes
+
+		// Remove the comms id 1st
+		//  
+		__FLOG_STATIC3(KNetUpsSubsys, KNetUpsComponent, _L("::DecrementConnectionCount_NetworkLifeTime_SessionL(), processId = %d, threadId = %d, commsId = %d, aError = %d"),
+					 aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 &aCommsIdKey.iCommsId.Node()); 
+
+		TNetUpsState state = aCommsIdKey.iProcessEntry.NetUpsState();
+
+		__ASSERT_DEBUG(((state == ENetLife_Transit_SessionYes) 					||
+						(state == ENetLife_SessionYes) 							||
+						(state == ENetLife_SessionNo_Transit_WithConnections) 	||
+						(state == ENetLife_SessionNo_WithConnections)),
+						User::Panic(KNetUpsPanic, KPanicInvalidLogic));
+
+		DecrementConnectionCount_NetworkLifeTime_NonSessionL(aCommsIdKey);
+									
+		if (aCommsIdKey.iProcessEntry.ThreadEntry().Count() == 0)
+			{
+			TProcessKey processKey(aCommsIdKey.iDatabaseEntry, aCommsIdKey.iProcessEntry);
+			DeleteProcessEntry(processKey);				
+			}			
+		}				
+	
+	void DecrementConnectionCount_NetworkLifeTime_NonSessionL(TCommsIdKey& aCommsIdKey)
+		{ // Tested
+		__FLOG_STATIC3(KNetUpsSubsys, KNetUpsComponent, _L("::DecrementConnectionCount_NetworkLifeTime_NonSessionL(), processId = %d, threadId = %d, commsId = %d, aError = %d"),
+					 aCommsIdKey.iProcessEntry.ProcessId().Id(),
+					 aCommsIdKey.iThreadEntry.ThreadId().Id(),
+					 &aCommsIdKey.iCommsId.Node()); 
+
+		aCommsIdKey.iThreadEntry.DecrementConnectionCount(aCommsIdKey.iCommsId);
+
+		TInt32 connectionCount = aCommsIdKey.iThreadEntry.ConnectionCount();
+		if (connectionCount == 0) 
+			{
+			TThreadKey threadKey(aCommsIdKey.iDatabaseEntry, aCommsIdKey.iProcessEntry, aCommsIdKey.iThreadEntry);
+			DeleteThreadEntry(threadKey);	// results in an active thread monitor being cancelled then deleted.			
+			}			
+		}				
+
+	void StartProcessMonitor(TProcessKey& aProcessKey)
+		{ // Tested
+		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent, _L("::StartProcessMonitor() processId = %d"), aProcessKey.iProcessEntry.ProcessId().Id()); 
+		__ASSERT_DEBUG((aProcessKey.iProcessEntry.ProcessMonitor() != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsAction3));					
+		__ASSERT_DEBUG((aProcessKey.iProcessEntry.ProcessMonitor()->IsActive() == EFalse), User::Panic(KNetUpsPanic, KPanicInvalidLogic));
+		aProcessKey.iProcessEntry.ProcessMonitor()->Start();			
+		}
+
+	void DeleteProcessEntry(TProcessKey& aProcessKey, TBool aRetainProcessMonitor)
+		{ //Not Tested
+		__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent, _L("::DeleteProcessEntry() processId = %d"), aProcessKey.iProcessEntry.ProcessId().Id()); 
+		
+		if (aRetainProcessMonitor != EFalse)
+			{
+			aProcessKey.iProcessEntry.SetProcessMonitor(NULL);
+			// running within the calling stack of CProcessMonitor::RunL(), so delete the
+			// process monitor when at the end of its RunL method.
+			}
+
+		for (TInt i = aProcessKey.iDatabaseEntry.ProcessEntry().Count() - 1; i >=0; --i )
+			{
+			if ((aProcessKey.iDatabaseEntry.ProcessEntry())[i]->ProcessId() == aProcessKey.iProcessEntry.ProcessId())
+				{
+				delete (aProcessKey.iDatabaseEntry.ProcessEntry())[i]; 
+				aProcessKey.iDatabaseEntry.ProcessEntry()[i] = 0; 
+				aProcessKey.iDatabaseEntry.ProcessEntry().Remove(i); // do we need to consider compression ?
+				break;
+				}	
+			}					
+		}
+
+	void DeleteThreadEntry(TThreadKey& aThreadKey)
+		{// Tested
+		__FLOG_STATIC2(KNetUpsSubsys, KNetUpsComponent, _L("::DeleteThreadEntry() processId = %d, threadId = %d"),
+				 		aThreadKey.iProcessEntry.ProcessId().Id(), aThreadKey.iThreadEntry.ThreadId().Id() ); 
+
+
+		for (TInt i = aThreadKey.iProcessEntry.ThreadEntry().Count() - 1; i >=0; --i )
+			{
+			if ((aThreadKey.iProcessEntry.ThreadEntry())[i]->ThreadId() == aThreadKey.iThreadEntry.ThreadId())
+				{
+				delete (aThreadKey.iProcessEntry.ThreadEntry())[i]; 
+				aThreadKey.iProcessEntry.ThreadEntry()[i] = 0; 
+				aThreadKey.iProcessEntry.ThreadEntry().Remove(i); // do we need to consider compression ?
+				break;
+				}	
+			}	
+		}
+
+	void ReplyOutStandingRequests(TThreadKey& aThreadKey)
+		{
+		CNetUpsImpl& netUpsImpl  = aThreadKey.iProcessEntry.UpsStateMachine().NetUpsImpl();
+		TNetUpsState netUpsState = aThreadKey.iProcessEntry.NetUpsState();
+
+		TNetUpsDecision netUpsDecision = ENo;
+		if (netUpsImpl.MapInternalStateToSessionMode(netUpsState) == CNetUpsImpl::ESessionMode)
+			{
+			aThreadKey.iProcessEntry.UpsStateMachine().NetUpsImpl().DetermineUpsDecision(netUpsState, netUpsDecision);
+			}
+			
+		ReplyOutStandingRequests(aThreadKey, netUpsDecision);
+		}
+
+	void ReplyOutStandingRequests(TThreadKey& aThreadKey, TNetUpsDecision aNetUpsDecision)
+		{
+		while (aThreadKey.iThreadEntry.RequestQueue().OutStandingRequestToProcess() != EFalse)
+			{
+
+			CPolicyCheckRequestData& policyCheckRequestData = aThreadKey.iThreadEntry.RequestQueue().GetOutStandingRequestToProcess();
+
+			if ((aNetUpsDecision == ESessionYes) || (aNetUpsDecision == EYes))
+				{
+				aThreadKey.iThreadEntry.IncrementConnectionCountL(policyCheckRequestData.iCommsId);
+				}
+			
+			TInt rc = policyCheckRequestData.iPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(aNetUpsDecision, 
+																									  policyCheckRequestData.iCommsId);
+			__FLOG_STATIC1(KNetUpsSubsys, KNetUpsComponent,_L("::ReplyOutStandingRequests(), error = %d"), rc );
+			aThreadKey.iThreadEntry.RequestQueue().DeleteOutStandingRequest();					
+			}	
+		}
+
+	void PerformTransitionFromNetworkLifeTimeNonSession(CState& aState, TEvent aEvent, TCommsIdKey& aCommsIdKey, TBool aAllActiveObjectsCompleted)
+		{
+		switch(aEvent)
+			{
+			case EResponseSessionYes:
+				aState.PerformStateTransition(EResponseSessionYes, aCommsIdKey.iProcessEntry);
+				break;
+			case EResponseSessionNo_WithoutConnections:
+				aState.PerformStateTransition(EResponseSessionNo_WithoutConnections, aCommsIdKey.iProcessEntry);
+				break;
+			case EResponseSessionNo_WithConnections:
+				aState.PerformStateTransition(EResponseSessionNo_WithConnections, aCommsIdKey.iProcessEntry);
+				break;
+			default:
+				User::Panic(KNetUpsPanic, KPanicInvalidLogic);					
+				break;
+			}
+
+		if (aAllActiveObjectsCompleted != EFalse)
+			{
+			switch(aEvent)
+				{
+				case EResponseSessionNo_WithoutConnections:
+					StartProcessMonitor(aCommsIdKey);
+					// drop through to perform state transition
+				case EResponseSessionYes:
+					// drop through to perform state transition
+				case EResponseSessionNo_WithConnections:
+					aState.PerformStateTransition(ETransitionForward, aCommsIdKey.iProcessEntry);	
+					break;
+				default:
+					User::Panic(KNetUpsPanic, KPanicInvalidLogic);					
+					break;
+				}
+			}
+		}
+	
+	} // end of namespace NetUpsFunctions
+} // end of namespace NetUps
+