authorisation/userpromptservice/server/source/upsserver/upssubsession.cpp
changeset 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/authorisation/userpromptservice/server/source/upsserver/upssubsession.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -0,0 +1,192 @@
+/*
+* 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 the License "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: 
+* Implements CUpsSession.	 See class and function definitions for
+* more information.
+*
+*/
+
+
+/**
+ @file
+*/
+
+#include "upsserver.h"
+#include "authoriser.h"
+#include <ups/upserr.h>
+
+namespace UserPromptService
+{
+
+CUpsSubsession* CUpsSubsession::NewL(CUpsSession &aSession, const RMessage2& aMessage)
+/**
+	Factory function allocates a new, initialized instance of CUpsSubsession.
+
+	@param	aMessage		Standard server-side handle to message.
+	@return					New, initialized instance of CUpsSubsession which
+							is owned by the caller.
+ */
+	{
+	CUpsSubsession* self = new(ELeave) CUpsSubsession(aSession);
+	// Note that CUpsSubsession ulitmately derives from CObject and therefore it MUST NOT be deleted directly,
+	// instead it should be closed if we leave. 
+	// nb. CUpsSession does NOT derive from CObject...
+	CleanupClosePushL(*self);
+	self->ConstructL(aMessage);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CUpsSubsession::CUpsSubsession(CUpsSession &aSession)
+/**
+	This private constructor prevents direct instantiation and provides
+	a single point of definition from which to call the superclass c'tor.
+ */
+:	CScsSubsession(aSession)
+	{
+	// empty.
+	//RDebug::Printf("0x%x CUpsSubsession(session %x)\n", this, &aSession);
+	}
+
+void CUpsSubsession::ConstructL(const RMessage2& aMessage)
+/**
+	Initialize this subsession object by opening a handle to the
+	thread whose identifier has been sent.
+
+	@param	aSession		Ref to session creating us
+	@param	aMessage		Standard server-side handle to message.
+ */
+	{
+	// ARGS: TThreadId, TProcessId
+
+	TPckg<TThreadId> tidBuf(iClientTid);
+	aMessage.ReadL(0, tidBuf);
+
+	TPckg<TProcessId> pidBuf(iClientPid);
+	aMessage.ReadL(1, pidBuf);
+	}
+
+CUpsSubsession::~CUpsSubsession()
+/**
+	Close this object's handle to the SS client thread.
+ */
+	{
+	//RDebug::Printf("0x%x ~CUpsSubsession()\n", this);
+	iDestination.Close();
+	iOpaqueData.Close();
+	}
+
+TBool CUpsSubsession::DoServiceL(TInt aFunction, const RMessage2& aMessage)
+/**
+	Implement CScsSubsession by handling the supplied message.
+
+	@param	aFunction		Function identifier without SCS code.
+	@param	aMessage		Standard server-side handle to message.
+	@return ETrue means complete client request now.
+ */
+	{
+	UserPromptService::TSubsessionFunction f =
+		static_cast<UserPromptService::TSubsessionFunction>(aFunction);
+	//RDebug::Printf("0x%x CUpsSubsession::DoServiceL function %d\n", this, f);
+	switch (f)
+		{
+	case UserPromptService::ESubsessPreparePrompt:
+		PreparePromptL(aMessage);
+		break;
+
+	case UserPromptService::ESubsessExecutePrompt:
+		ExecutePromptL(aMessage);
+		return EFalse; // If ExecutePrompt returns, instead of leaving, it must have setup an async req
+	BULLSEYE_OFF
+	default:
+		User::Leave(KErrNotSupported);
+		break;
+	BULLSEYE_RESTORE
+		}
+	return ETrue;
+	}
+
+void CUpsSubsession::PreparePromptL(const RMessage2& aMessage)
+	/**
+	   Save service, description, and opaque data for use in the
+	   following execute prompt command.
+	*/
+	{
+	// TIpcArgs is TServiceId aServiceId, const TDesC* aDestination, const TDesC8* aOpaqueData
+	
+	iServiceId.iUid = aMessage.Int0();
+
+	// Get Description
+	TInt destinationLength = aMessage.GetDesLengthL(1);
+	iDestination.Close();
+	iDestination.CreateL(destinationLength);
+	aMessage.ReadL(1, iDestination);
+
+	// Get Opaque Data
+	TInt opaqueDataLength = aMessage.GetDesLengthL(2);
+	iOpaqueData.Close();
+	if(opaqueDataLength)
+		{
+		iOpaqueData.CreateL(opaqueDataLength);
+		aMessage.ReadL(2, iOpaqueData);
+		}
+	}
+
+void CUpsSubsession::ExecutePromptL(const RMessage2& aMessage)
+	/**
+	  Create and start the CAuthoriser to process the request.
+	*/
+	{
+	// TIpcArgs is OUT:TUpsDecision& aDecision, IN:TBool aServerCheckOk
+
+	// The authorizer object is derived from CAsyncRequest and its
+	// lifecycle is automatically managed by the SCS framework
+	//
+	// iDestination and iOpaqueData are transfered to the CAuthoriser,
+	// our handles will be closed.
+	TBool serverCheckOk = aMessage.Int1();
+	CUpsSession *session = static_cast<CUpsSession*>(&iSession);
+	RPolicyCacheCountedHandle &cacheManager = session->UpsServer()->iPolicyCache;
+	CleanupReleasePushL(cacheManager);
+	if(!cacheManager.IsOpen())
+		{
+		cacheManager.OpenL();
+		}
+	CAuthoriser *authoriser = CAuthoriser::NewL(cacheManager,
+												session, this, serverCheckOk,
+												iClientTid, iClientPid,
+												aMessage, iServiceId, iDestination, iOpaqueData);
+	CleanupStack::Pop(&cacheManager); // transfered ownership to the new CAuthoriser
+	CleanupStack::PushL(authoriser);
+	authoriser->TransferToScsFrameworkL();
+	CleanupStack::Pop(authoriser); // authoriser now owned by SCS framework
+
+	/**
+	   The authoriser is now responsible for completing the request,
+	   so we must NOT leave.
+	   
+	   We could start the request processing off by calling an
+	   authoriser function from within a TRAP handler, but for future
+	   proofing we tell the authoriser to self complete so the
+	   processing all happens within the active scheduler framework
+	   and the authoriser state machine. This will make it much easier
+	   to completly restart request processing (if we decide to when
+	   policies are changed).
+	*/
+	authoriser->Wakeup();
+	}
+
+
+} // End of namespace UserPromptService
+// End of file