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