dvrengine/CommonRecordingEngine/src/CCRServer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 16:02:30 +0300
changeset 16 ae43a6765dd5
parent 0 822a42b6c3f1
permissions -rw-r--r--
Revision: 201009 Kit: 201015

/*
* Copyright (c) 2007 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:    Implementation of CR servers server class*
*/




// INCLUDE FILES
#include "CCRServer.h"
#include "CCRSession.h"
#include "CCREngine.h"
#include <ipvideo/CRTypeDefs.h> // Constants exported from client library
#include <e32svr.h>
#include <e32math.h>
#include <e32uid.h>
#include "videoserviceutilsLogger.h"

// CONSTANTS
// Platform security. Custom check is applied to all IPCs.
static const int KRangeCount( 1 );

static const TInt SecurityRanges[KRangeCount] =
    {
    0, // Range is from 0 to KMaxTInt
    };

static const TUint8 SecurityRangesPolicy[KRangeCount] =
    {
    CPolicyServer::ECustomCheck
    };

static const CPolicyServer::TPolicy Policy =
    {
    CPolicyServer::EAlwaysPass,
    KRangeCount,
    SecurityRanges,
    SecurityRangesPolicy,
    NULL,
    };

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CCRServer::NewLC()
// 
// -----------------------------------------------------------------------------
//
CCRServer* CCRServer::NewLC(  )
    {
    CCRServer* self = new( ELeave ) CCRServer;
    CleanupStack::PushL( self );  
    self->ConstructL( );
    return self;
    }

// -----------------------------------------------------------------------------
// CCRServer::CCRServer()
// C++ constructor 
// -----------------------------------------------------------------------------
//
CCRServer::CCRServer()
  : CPolicyServer( EPriorityRealTimeServer, Policy, ESharableSessions ),
    iSessionCount( 0 )
    {
    __DECLARE_NAME( _S( "CCRServer" ) );
    }

// -----------------------------------------------------------------------------
// CCRServer::ConstructL()
// second-phase constructor; create the object container index.
// -----------------------------------------------------------------------------
//
void CCRServer::ConstructL(  )
    {
    LOG( "CCRServer::ConstructL()" );    
    
    iContainerIx = CObjectConIx::NewL();
    iObjectCon = iContainerIx->CreateL();
    
    StartL( KCRServerNameExe );
    }

// -----------------------------------------------------------------------------
// CCRServer::~CCRServer()
// Destructor.
// -----------------------------------------------------------------------------
//
CCRServer::~CCRServer()
    {
    LOG( "CCRServer::~CCRServer()" );

    DeleteRtpEngine();
    }

// -----------------------------------------------------------------------------
// CCRServer::ThreadFunction()
// The active scheduler is installed and started here.
// -----------------------------------------------------------------------------
//
TInt CCRServer::ThreadFunction(  )
    {
    CTrapCleanup* cleanupStack = CTrapCleanup::New();    
    if ( !cleanupStack )
        {
        PanicServer( KErrNoMemory );
        }

    TRAPD( err, ThreadFunctionL( ) );
    if ( err )
        {
        PanicServer( KErrServerTerminated );
        }

    delete cleanupStack;
    cleanupStack = NULL;
    
    return KErrNone;    
    }

// -----------------------------------------------------------------------------
// CCRServer::ThreadFunctionL()
//
// -----------------------------------------------------------------------------
//
void CCRServer::ThreadFunctionL(  )
    {
    LOG( "CCRServer::ThreadFunctionL() - In" );

    // Construct active scheduler
    CActiveScheduler* activeScheduler = new ( ELeave ) CActiveScheduler;
    CleanupStack::PushL( activeScheduler ); // |-> 1

    // Install active scheduler. 
    // We don't need to check whether an active scheduler is already installed
    // as this is a new thread, so there won't be one
    CActiveScheduler::Install( activeScheduler );

    // Construct our server, pushed cleanup stack and leaved there
    CCRServer* server = CCRServer::NewLC( );  // |-> 2    
    
    // Signal server is up
    RProcess::Rendezvous( KErrNone );

    // Start handling requests
    CActiveScheduler::Start();

    CleanupStack::PopAndDestroy( server ); // 2<-|
    CleanupStack::PopAndDestroy( activeScheduler ); // 1<-|
    
    LOG( "CCRServer::ThreadFunctionL() - Out" );    
    }

// -----------------------------------------------------------------------------
// CCRServer::SignalClientL
// Signal the client that server is running.
// -----------------------------------------------------------------------------
void CCRServer::SignalClientL()
    {
    RSemaphore semaphore;
    User::LeaveIfError( semaphore.OpenGlobal( KCRServerSemaphoreName ) );
    semaphore.Signal();
    semaphore.Close();
    }

// -----------------------------------------------------------------------------
// CCRServer::PanicServer
// Utility - panic the server
// -----------------------------------------------------------------------------
void CCRServer::PanicServer( TInt aPanic )
    {
    LOG1( "CCRServer::PanicServer(), aPanic: %d", aPanic );
    
    User::Panic( KCRServerNameExe, aPanic );
    }

// -----------------------------------------------------------------------------
// CCRServer::GetEngineObjectL()
//
// -----------------------------------------------------------------------------
//
CCREngine* CCRServer::GetEngineObjectL()
    {
    if ( iObjectCon->Count() == 0 )
        {
        // Create CR engine
        iEngine = CCREngine::NewL( );

        // Add our engine to container
        iObjectCon->AddL( iEngine );
        }
    else
        {
        // default implementation return KErrNone.
        if ( KErrNone != iEngine->Open() )
            {
            User::Leave( KErrGeneral );
            }
        }

    // We have only one object in our container
    return iEngine;
    }

// -----------------------------------------------------------------------------
// CCRServer::Inc()
// 
// -----------------------------------------------------------------------------
//
void CCRServer::Inc()
    {
    iSessionCount++;
    LOG1( "CCRServer::Inc(), New iSessionCount: %d", iSessionCount );
    }

// -----------------------------------------------------------------------------
// CCRServer::Dec()
// 
// -----------------------------------------------------------------------------
//
void CCRServer::Dec()
    {
    iSessionCount--;
    LOG1( "CCRServer::Dec(), New iSessionCount: %d", iSessionCount );

    if ( iSessionCount <= 0 )
        {
        StopServer();
        }
    }

// -----------------------------------------------------------------------------
// CCRServer::NewSessionL()
// 
// -----------------------------------------------------------------------------
//
CSession2* CCRServer::NewSessionL(
    const TVersion& aVersion,
    const RMessage2& /*aMessage*/ ) const
    {
    // Check version is ok
    TVersion v( KCRServMajorVersionNumber,
                KCRServMinorVersionNumber,
                KCRServBuildVersionNumber );
    
    if ( !User::QueryVersionSupported( v, aVersion ) )
        {
        User::Leave( KErrNotSupported );
        }
        
    // Make new session
    return CCRSession::NewL( ( CCRServer* ) this );
    }

// -----------------------------------------------------------------------------
// CCRServer::StopServer
// Stops the server thread if no sessions active.
// -----------------------------------------------------------------------------
//
void CCRServer::StopServer()
    {
    LOG( "CCRServer::StopServer()" );    
    
    CActiveScheduler::Stop();
    }
    
// -----------------------------------------------------------------------------
// CCRServer::DeleteRtpEngine
// Stops active scheduler and deletes object container and other objects.
// -----------------------------------------------------------------------------
//
void CCRServer::DeleteRtpEngine()
    {
    LOG1( "CCRServer::DeleteRtpEngine(), iContainerIx: %d", iContainerIx );
    
    if ( iContainerIx )
        {
        iContainerIx->Remove( iObjectCon );
        delete iContainerIx; iContainerIx = NULL;
        }
    }

// ========================== OTHER EXPORTED FUNCTIONS =========================

// -----------------------------------------------------------------------------
// StartThread()
// Start the server thread. This is called from the client.
// -----------------------------------------------------------------------------
//
TInt CCRServer::StartThread()
    {
#ifdef _DEBUG
    __UHEAP_MARK;
#endif
    
    LOG( "CCRServer::StartThread() - In" );
    // Check server not already started
    TFindServer findCountServer( KCRServerNameExe );
    TFullName name;
    if ( findCountServer.Next( name ) == KErrNone )
        { 
        // Found server already
        TRAP_IGNORE( CCRServer::SignalClientL() );
        return KErrAlreadyExists;
        }
    
    ThreadFunction( );
    
    LOG( "CCRServer::StartThread() - Out" );

#ifdef _DEBUG
    __UHEAP_MARKEND;
#endif
    
    return KErrNone;
    }

// -----------------------------------------------------------------------------
// E32Main()
// Server startup
// Returns: KErrNone
// -----------------------------------------------------------------------------
//
GLDEF_C TInt E32Main()
    {
    return CCRServer::StartThread();
    }
    
// --------------------------------------------------------------------------
// CCRServer::CustomSecurityCheckL()
// --------------------------------------------------------------------------
//
CPolicyServer::TCustomResult CCRServer::CustomSecurityCheckL(
    const RMessage2& aMsg,
    TInt& /*aAction*/,
    TSecurityInfo& /*aMissing*/ )
    {
    
    TCustomResult retVal ( EFail );
    
    // Check the messagge function range
    if ( ( aMsg.Function() > ECRServBase && 
           aMsg.Function() < ECRServLastEnum ) ||
         ( aMsg.Function() > ECRLiveTvBase && 
           aMsg.Function() < ECRLiveTvLastEnum ) )
        {
        // Check if the client has required capabilities                
        // From .mmp-file following are CAP_APPLICATION capabilities
        if( ! aMsg.HasCapability(ECapabilityNetworkServices ) ||
            ! aMsg.HasCapability(ECapabilityLocalServices ) ||
            ! aMsg.HasCapability(ECapabilityLocation ) ||
            ! aMsg.HasCapability(ECapabilityReadUserData ) ||
            ! aMsg.HasCapability(ECapabilityWriteUserData ) ||
            ! aMsg.HasCapability(ECapabilityReadDeviceData ) ||
            ! aMsg.HasCapability(ECapabilityWriteDeviceData ) ||
            ! aMsg.HasCapability(ECapabilitySwEvent ) )
            {
            LOG1(
                "CCRServer::CustomSecurityCheckL() No capability for message %d!!!",
                aMsg.Function() );                 
            }
        else
            {
            LOG1(
                "CCRServer::CustomSecurityCheckL() Message %d inside range and capabilities ok",
                aMsg.Function() );
            retVal = EPass;
            }        
        }
    else
        {
        LOG1(
            "CCRServer::CustomSecurityCheckL() Message %d outside known range!!!",
            aMsg.Function() );            
        }
       
    return retVal;

    }
// End of File