phoneclientserver/phoneserver/Src/Standard/CPhSrvSession.cpp
changeset 0 ff3b6d0fd310
child 3 a4a774cb6ea7
child 12 ae8abd0db65c
--- /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