--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneclientserver/phoneserver/Src/Standard/CPhSrvSession.cpp Tue Feb 02 01:11:09 2010 +0200
@@ -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<TInt> 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<TInt>( &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