diff -r 1f002146abb4 -r 8d5d7fcf9b59 phoneclientserver/phoneserver/src/standard/cphsrvsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phoneclientserver/phoneserver/src/standard/cphsrvsession.cpp Wed Jul 21 18:26:52 2010 +0300 @@ -0,0 +1,417 @@ +/* +* Copyright (c) 2002-2005 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: Session. +* +*/ + + + +// INCLUDE FILES +#include "cphsrvserver.h" +#include "cphsrvsession.h" +#include "cphsrvsubsessionbase.h" +#include "phsrvsubsessionfactory.h" +#include "phcltclientserver.h" + +// CONSTANTS + + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPhSrvSession::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CPhSrvSession* CPhSrvSession::NewL( CPhSrvServer& aServer ) + { + CPhSrvSession* self = new ( ELeave ) CPhSrvSession(); + CleanupStack::PushL( self ); + self->ConstructL( aServer ); + CleanupStack::Pop(); + return self; + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::CPhSrvSession +// C++ constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +CPhSrvSession::CPhSrvSession() + { + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::~CPhSrvSession +// Destructor. +// ----------------------------------------------------------------------------- +// +CPhSrvSession::~CPhSrvSession() + { + if ( iServer ) + { + iServer->CancelCreateAll( *this ); + } + + delete iObjectIx; + + if ( iContainer ) + { + iServer->RemoveContainer( iContainer ); + iContainer = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::ServiceL +// +// Calls DispatchMessageL under trap harness. +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::ServiceL( const RMessage2& aMessage ) + { + TRAPD( err, ProcessRequestL( aMessage ) ); + if ( err != KErrNone ) + { + aMessage.Complete( err ); + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::ProcessRequestL +// +// Checks the function specified by the client message +// and depending on the type, performs an appropriate action. +// +// If the function is one of the "special" factory sub-session +// creation op-codes, then this session will process it. +// +// If the function is a generic subsession function, then the +// subsession which can handle this function is identified by +// it's unique handle, and it is asked to process the request. +// +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::ProcessRequestL( const RMessage2& aMessage ) + { + if ( HandleCommandL( aMessage ) ) + { + return; + } + + const TInt function = aMessage.Function(); + const TUint32 sid = aMessage.SecureId().iId; + + // Is this a message that results in a new subsession? + if ( PhSrvSubSessionFactory::PhSrvSubSessionFactoryIsCreationFunction( + function ) ) + { + if ( !PhSrvSubSessionFactory::PhSrvSubSessionFactoryIsCreationAllowed( + function, + sid ) ) + { + aMessage.Complete( KErrPermissionDenied ); + } + else + { + // Need to create a new subsession + CPhSrvSubSessionBase* subSession = + PhSrvSubSessionFactory::PhSrvSubSessionFactoryCreateLC( + function, + *this ); + + // Add to container (takes ownership) + iContainer->AddL( subSession ); + if (function != EPhoneServerImageHandlerSubSessionOpen ) + { + CleanupStack::Pop( subSession ); + } + // Get a handle for the object + const TInt handle = iObjectIx->AddL( subSession ); + + // Inform client of the handle its been allocated + TPckg handlePckg( handle ); + Write( + aMessage, + 3, + handlePckg ); + + if ( !aMessage.IsNull() ) + { + // Complete the message + aMessage.Complete( KErrNone ); + } + } + } + else + { + // Find an appropriate object and pass the message to it + // for processing... + const TInt handle = aMessage.Int3(); + + // Fetch the sub-session by its handle + CObject* object = iObjectIx->At( handle ); + if ( !object ) + { + PanicClient( + aMessage, + EPhCltServerInitiatedPanicInvalidHandle ); + } + + // We can cast the object to a subsession instance, since that's + // all we store in the object container + CPhSrvSubSessionBase* subSession = + static_cast< CPhSrvSubSessionBase* >( object ); + + if ( subSession ) + { + // Check that the subsession can handle this request + if ( !subSession->PhSrvMessageDecoderCanProcessMessage( function ) ) + { + PanicClient( + aMessage, + EPhCltServerInitiatedPanicInvalidHandle ); + } + else + { + // Get it to process this request + subSession->PhSrvMessageProcessorHandleMessageL( aMessage ); + } + } + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::SubSessionCount +// +// Return the number of subsessions +// ----------------------------------------------------------------------------- +// +TInt CPhSrvSession::SubSessionCount() const + { + return iContainer->Count(); + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::SubSessionA +// +// Return a subsession from an index +// ----------------------------------------------------------------------------- +// +CPhSrvSubSessionBase& CPhSrvSession::SubSessionAt( TInt aIndex ) const + { + return *static_cast< CPhSrvSubSessionBase* >( ( *iContainer )[ aIndex ] ); + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::CloseSubsession +// +// Remove object from object index +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::CloseSubSession( const RMessage2& aMessage ) + { + TInt handle = aMessage.Int3(); + + CObject* obj = iObjectIx->At( handle ); + __ASSERT_ALWAYS( obj, + PanicClient( + aMessage, + EPhCltServerInitiatedPanicInvalidHandle ) ); + iObjectIx->Remove( handle ); + + if ( !aMessage.IsNull() ) + { + aMessage.Complete( KErrNone ); + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::PanicClient +// +// Panic the client's thread +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::PanicClient( + const RMessage2& aMessage, + TPhCltServerInitiatedPanic aPanic ) const + { + if ( !aMessage.IsNull() ) + { + _LIT( KPhServerPanicCategory, "PhSrvServer" ); + aMessage.Panic( KPhServerPanicCategory, aPanic ); + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::ConstructL +// +// Symbian OS 2nd phase constructor +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::ConstructL( CPhSrvServer& aServer ) + { + iContainer = aServer.NewContainerL(); + iObjectIx = CObjectIx::NewL(); + + iServer = &aServer; + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::SubSessionUniqueHandle +// +// Return the unique handle for the specified subsession +// ----------------------------------------------------------------------------- +// +TInt CPhSrvSession::SubSessionUniqueHandle( + const CPhSrvSubSessionBase& aSubSession ) const + { + // Ensure that the handle really is unique. + // return iObjectIx->At( &aSubSession ); is unique only in same session. + return reinterpret_cast( &aSubSession ); + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::PhoneServer +// +// Returns the Phone Server +// ----------------------------------------------------------------------------- +// +CPhSrvServer& CPhSrvSession::PhoneServer() const + { + return *static_cast< CPhSrvServer* >( const_cast< CServer2* >( Server() ) ); + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::Write +// +// Write to the client address space. Panic client upon error +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::Write( + const RMessage2& aMessage, + TInt aLocation, + const TDesC8& aDes, + TInt aOffset ) + { + TInt ret = aMessage.Write( aLocation, aDes, aOffset ); + if ( ret != KErrNone ) + { + PanicClient( + aMessage, + EPhCltServerInitiatedPanicBadDescriptor ); + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::Read +// +// Read from the client address space. Panic client upon error +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::Read( + const RMessage2& aMessage, + TInt aLocation, + TDes8& aDes, + TInt aOffset ) + { + TInt ret = aMessage.Read( aLocation, aDes, aOffset ); + if ( ret != KErrNone ) + { + PanicClient( + aMessage, + EPhCltServerInitiatedPanicBadDescriptor ); + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::Read +// +// Read from the client address space. Panic client upon error +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::Read( + const RMessage2& aMessage, + TInt aLocation, + TDes& aDes, + TInt aOffset ) + { + TInt ret = aMessage.Read( aLocation, aDes, aOffset ); + if ( ret != KErrNone ) + { + PanicClient( + aMessage, + EPhCltServerInitiatedPanicBadDescriptor ); + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::CompleteCreateAll +// ----------------------------------------------------------------------------- +// +void CPhSrvSession::CompleteCreateAll( TInt aError ) + { + if ( iCreateAll ) + { + iCreateAll = EFalse; + iCreateAllMsg.Complete( aError ); + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvSession::HandleCommandL +// ----------------------------------------------------------------------------- +// +TBool CPhSrvSession::HandleCommandL( const RMessage2& aMessage ) + { + TBool result = EFalse; + + switch ( aMessage.Function() ) + { + case EPhoneCreateAll: + result = ETrue; + + iServer->CancelCreateAll( *this ); + iServer->CreateAllL( *this ); + + iCreateAll = ETrue; + iCreateAllMsg = aMessage; + break; + + default: + break; + } + + return result; + } + + +// End of File