networkcontrol/commsuserpromptmgr/utils/src/netupssubsession.cpp
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkcontrol/commsuserpromptmgr/utils/src/netupssubsession.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,352 @@
+// 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 methods for NetUps SubSession
+// @internalAll
+// @prototype
+// 
+//
+
+#include <e32base.h>		// define Active Scheduler
+#include <e32property.h>	// defines properties
+
+#include <ups/upsclient.h>
+#include <ups/upstypes.h>
+
+#include "netupsassert.h"
+#include "netupskeys.h"
+
+#include "netupsimpl.h"
+#include "netupsstatemachine.h"
+#include "netupssubsession.h"
+#include "netupsprocessentry.h"
+#include "netupsthreadentry.h"
+#include "netupsthreadmonitor.h"
+#include "netupspolicycheckrequestqueue.h"
+
+#include <comms-infras/commsdebugutility.h> 		// defines the comms debug logging utility
+
+namespace NetUps
+{
+__FLOG_STMT(_LIT8(KNetUpsSubsys, 	"esock");)   
+__FLOG_STMT(_LIT8(KNetUpsComponent, "NetUps");) /*esockloader*/
+
+CSubSession* CSubSession::NewL(UserPromptService::RUpsSession& aUpsSession, CDatabaseEntry& aDatabaseEntry, CProcessEntry& aProcessEntry, CThreadEntry&	aThreadEntry)
+	{
+	CSubSession* self = new (ELeave) CSubSession(aDatabaseEntry, aProcessEntry, aThreadEntry);
+
+	CleanupStack::PushL(self);
+	self->ConstructL(aUpsSession);
+	CleanupStack::Pop(self);
+
+	CActiveScheduler::Add(self);
+	return self;	
+	}
+	
+CSubSession::CSubSession(CDatabaseEntry& aDatabaseEntry, CProcessEntry& aProcessEntry, CThreadEntry&	aThreadEntry)
+  : CActive(EPriorityStandard), iDatabaseEntry(aDatabaseEntry), iProcessEntry(aProcessEntry), iThreadEntry(aThreadEntry),
+    iDecision(EUpsDecNo), iCommsId(NULL), iPolicyCheckRequestOriginator(NULL), iReadyForDeletion(EFalse)
+    {
+#ifdef _DEBUG    
+	iState = EPCRPIdle;
+#endif // _DEBUG
+	}
+
+CSubSession::~CSubSession()
+	{
+	if (IsActive())
+		{
+		Cancel();	
+		}
+
+	iUpsSubSession.Close();	
+	iUpsOpaqueData.Close();
+	
+#ifdef _DEBUG
+	iSimulatedDelay.Close();
+#endif // _DEBUG
+
+	__FLOG_1(_L("CSubSession %08x:\t~CSubSession()"), this);	
+	__FLOG_CLOSE;	
+	}
+
+TInt CSubSession::Authorise(const CPolicyCheckRequestData& aPolicyCheckRequestData)
+	{
+	__FLOG_6(_L("CSubSession %08x:\tAuthoriseL() processId = %d, threadId = %d, serviceId = %d, platsec result = %d, Originator  = %08x"),
+		this, aPolicyCheckRequestData.iProcessId.Id(), aPolicyCheckRequestData.iThreadId.Id(), (TInt32) aPolicyCheckRequestData.iServiceId, aPolicyCheckRequestData.iPlatSecCheckResult, &aPolicyCheckRequestData.iPolicyCheckRequestOriginator);
+
+	TInt rc = KErrNone;
+
+	_LIT(KAp,		  "AccessPoint = \"");	
+	_LIT(KTerminator, "\"");
+
+	TInt length = aPolicyCheckRequestData.iDestinationName.Length() + 
+				  aPolicyCheckRequestData.iAccessPointName.Length();
+	if (length > EMaxUnformattedLength)
+		{
+		__FLOG_4(_L("CSubSession %08x:\t AuthoriseL() = %d, iDestinationName.Length() = %d, iAccessPointName.Length() = %d, length = %d"), CActive::IsActive(), aPolicyCheckRequestData.iDestinationName.Length(), aPolicyCheckRequestData.iAccessPointName.Length(), length);
+		rc = KErrOverflow;
+		}
+	else
+		{
+		iPolicyCheckRequestOriginator 	= &const_cast<MPolicyCheckRequestOriginator&>(aPolicyCheckRequestData.iPolicyCheckRequestOriginator);
+		iCommsId 						= &aPolicyCheckRequestData.iCommsId;	
+
+		ASSERT(iUpsOpaqueData.Length() == 0);
+		iUpsOpaqueData.Append(KAp);
+		iUpsOpaqueData.Append(aPolicyCheckRequestData.iAccessPointName);
+		iUpsOpaqueData.Append(KTerminator);			
+		
+		iUpsSubSession.Authorise(aPolicyCheckRequestData.iPlatSecCheckResult,  
+				 TUid::Uid(aPolicyCheckRequestData.iServiceId),
+				 aPolicyCheckRequestData.iDestinationName,
+				 iUpsOpaqueData, 
+				 iDecision, 
+				 iStatus);
+
+#ifdef _DEBUG
+		iState =  EPCRPSimulateDelay;
+#endif // _DEBUG
+
+		SetActive();		
+		}
+	
+	return rc;
+	}
+
+void CSubSession::RunL()
+	{
+	__FLOG_3(_L("CSubSession %08x:\tRunL(): IsActive() = %d, iStatus.Int() = %d"), this, CActive::IsActive(), iStatus.Int());	
+
+#ifdef _DEBUG
+	switch (iState)
+		{
+		case EPCRPSimulateRequest:
+#endif
+			{
+			__FLOG_5(_L("CSubSession %08x:\tRunL() iDecision = %d, iCommsId = %08x, iPolicyCheckRequestOriginator = %08x, iReadyForDeletion = %d"), this, iDecision, iCommsId, iPolicyCheckRequestOriginator, iReadyForDeletion);	
+
+			__ASSERT_DEBUG((iPolicyCheckRequestOriginator != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsSubSession));
+			__ASSERT_DEBUG((iCommsId 					  != NULL), User::Panic(KNetUpsPanic, KPanicNullPointer_NetUpsSubSession1));
+
+			TNetUpsDecision netUpsDecision = static_cast<TNetUpsDecision>(iDecision);
+			TCommsIdKey commsIdKey(iDatabaseEntry, iProcessEntry, iThreadEntry, *iCommsId);
+
+#ifdef _DEBUG
+			// Logic to put the NetUps into its error paths; don't include in production build
+			ModifyIStatusValue(netUpsDecision);
+#endif
+			if (iStatus == KErrNone)
+				{
+				iProcessEntry.UpsStateMachine().HandleUPSRequestCompletionL(commsIdKey, *iPolicyCheckRequestOriginator, netUpsDecision); 	
+				// if HandleUPSRequestCompletionL() leaves, then the error is managed in CSubSession::RunError(TInt aError) below
+				}
+			else	
+				{
+				// no state change has occured, at the most a threadEntry, processEntry, and databaseEntry have been created which
+				// can be just left for the moment - could consider removing them later.
+				iProcessEntry.UpsStateMachine().HandleUPSErrorOnCompletionL(commsIdKey, *iPolicyCheckRequestOriginator, iStatus.Int()); 	
+				}
+
+			// Reset the temporary variables
+			ResetAuthorisationRequestParameters();
+			
+			DeleteCurrentRequestFromQueue();
+			
+			if (SubSessionReadyForDeletion() == EFalse)
+				{
+				PostNextRequestFromQueue();
+				}
+			else
+				{
+				delete this;
+				}		
+#ifdef _DEBUG
+			break;	
+#endif
+			}
+#ifdef _DEBUG
+		case EPCRPSimulateDelay:
+			{
+			iSimulatedDelay.After(iStatus,EDelay);
+			iState = EPCRPSimulateRequest;
+			SetActive();	
+					
+			break;				
+			}
+		default:
+			User::Panic(KNetUpsPanic, KPanicInvalidLogic);
+			break;
+		}
+#endif // _DEBUG
+	}
+
+void CSubSession::DoCancel()
+	{
+	__FLOG_1(_L("CSubSession %08x:\tDoCancel()"), this);	
+
+	iUpsSubSession.CancelPrompt();
+
+#ifdef _DEBUG
+	iSimulatedDelay.Cancel();
+#endif
+
+	if (iCommsId)
+		{
+		iThreadEntry.RemoveCommsId(*iCommsId);		
+		} 
+
+	ResetAuthorisationRequestParameters();
+	
+#ifdef _DEBUG
+	User::After(ECancelDelay);
+#endif	
+	}
+
+void CSubSession::DeleteCurrentRequestFromQueue()
+	{
+	// Determine whether the last entry on the queue should be flushed.
+	// The logic here needs to be reviewed as there are various cases
+	// when the thread entry exists and when it does not. The up shot is
+	// that is is probably better to remove the entry of the queueu during
+	// the HandleUpsRequestCompletion, to keep the logic all in the one place.
+	// However, for now:			
+	
+	CNetUpsImpl::TSessionMode 	sessionMode  = CNetUpsImpl::MapInternalStateToSessionMode(iProcessEntry.NetUpsState());
+	CNetUpsImpl::TLifeTimeMode 	lifeTimeMode = iProcessEntry.UpsStateMachine().NetUpsImpl().LifeTimeMode();
+
+	switch(sessionMode)
+		{			
+		case CNetUpsImpl::ENonSessionMode:
+			// finished with current entry, delete it.
+			iThreadEntry.RequestQueue().DeleteCurrentEntry();
+			break;
+		case CNetUpsImpl::ESessionMode:
+			switch(lifeTimeMode)
+				{
+				case CNetUpsImpl::EProcessLifeTimeMode:
+					// thread entry gone, queue already deleted.
+					break;
+				case CNetUpsImpl::ENetworkLifeTimeMode:
+					// thread entry remains, delete last queue entry
+					iThreadEntry.RequestQueue().DeleteCurrentEntry();
+					break;
+				default:
+					User::Panic(KNetUpsPanic, KPanicInvalidLogic);
+					break;
+				}
+			break;
+		default:
+			User::Panic(KNetUpsPanic, KPanicInvalidLogic);
+			break;
+		}			
+	}
+
+void CSubSession::PostNextRequestFromQueue()
+	{
+#ifdef _DEBUG
+	iState = EPCRPIdle;
+#endif
+	// determine there is an opportunity for the next entry to be forwarded to the UPS server.			
+	while ((iThreadEntry.RequestQueue().IsEmpty() == EFalse) && (IsActive() == EFalse))
+		{
+		CPolicyCheckRequestData&  policyCheckRequestData = iThreadEntry.RequestQueue().GetNextRequest();
+		__FLOG_2(_L("CSubSession: %08x:\t RunL(), post next request, policyCheckRequest = %08x"), this, &policyCheckRequestData);		
+		TInt err = Authorise(policyCheckRequestData);
+		if (err != KErrNone)
+			{
+			const Messages::TNodeId& commsId = policyCheckRequestData.iCommsId;
+			policyCheckRequestData.iPolicyCheckRequestOriginator.ProcessPolicyCheckResponse(KErrCancel, commsId);
+			iThreadEntry.RequestQueue().DeleteCurrentEntry();
+#ifdef _DEBUG
+			iState = EPCRPIdle;
+#endif
+			}
+		}	
+	}
+
+void CSubSession::ConstructL(UserPromptService::RUpsSession& aUpsSession)
+	{
+	// 	Interesting opportunity to log the process and thread ids
+	//	RProcess process;
+	// 	TSecureId secureId = process.SecureId();
+	__FLOG_OPEN(KNetUpsSubsys, KNetUpsComponent);
+	__FLOG_1(_L("CSubSession %08x:\tConstructL()"), this);	
+	RThread thread;
+	TInt ret = thread.Open(iThreadEntry.ThreadId());
+	if (ret != KErrNone)
+		{
+		__FLOG_2(_L("CSubSession %08x:\tError %d opening thread %d\n"), ret, iThreadEntry.ThreadId().Id());
+		User::Leave(ret);
+		}
+	(void) User::LeaveIfError(iUpsSubSession.Initialise(aUpsSession, thread));
+	
+	thread.Close();
+	
+	iUpsOpaqueData.CreateL(EMaxFormattedLength);
+	#ifdef _DEBUG
+	(void) User::LeaveIfError(iSimulatedDelay.CreateLocal()); // Add temporary delay for Nadeem
+#endif
+
+	}
+
+void CSubSession::SetReadyForDeletion()
+	{
+	__FLOG_1(_L("CSubSession %08x:\tSetReadyForDeletion()"), this);	
+	iReadyForDeletion = ETrue;
+	}
+
+TBool CSubSession::SubSessionReadyForDeletion()
+	{
+	return iReadyForDeletion;
+	}
+
+void CSubSession::ResetAuthorisationRequestParameters()
+	{
+	iUpsOpaqueData.Zero();	
+	iPolicyCheckRequestOriginator 	= NULL;	
+	iCommsId 						= NULL;	
+	}
+
+TInt CSubSession::RunError(TInt aError)
+	{
+	__FLOG_2(_L("CSubSession %08x:\tRunError(), aError = %d"), this, aError);	
+	(void) aError;
+
+	// Handles Leaves from CSubSession::RunL.
+	// We don't allocate any memory in the RunL, so this method should never be called.
+	
+	return KErrNone;	
+	}
+
+#ifdef _DEBUG
+void CSubSession::ModifyIStatusValue(TNetUpsDecision aNetUpsDecision)
+	{
+	TInt rc = RProperty::Get(KUidNetUpsTestNotifCategory, KNetUpsSubSessionError, iTestErrorCode);
+	if (  	(rc == KErrNone) &&
+			(iTestErrorCode != KErrNone) && 
+		  ( ((aNetUpsDecision == EYes)  && 
+		    (iProcessEntry.NetUpsState() == EProcLife_NonSession) || (iProcessEntry.NetUpsState() == ENetLife_NonSession))
+		     ||
+			 ((aNetUpsDecision == ESessionYes) &&
+		     ((iProcessEntry.NetUpsState() == EProcLife_Transit_SessionYes ) || (iProcessEntry.NetUpsState() == EProcLife_Transit_SessionNo ) ||
+		      (iProcessEntry.NetUpsState() == ENetLife_SessionNo_Transit_WithoutConnections  ) || (iProcessEntry.NetUpsState() == ENetLife_SessionNo_Transit_WithConnections  ) ||
+		      (iProcessEntry.NetUpsState() == ENetLife_Transit_SessionYes  )) )
+		      ) )
+		{
+		iStatus = iTestErrorCode;
+		}	
+	}
+#endif
+
+} // end of namespace