videoscheduler/SchedulerServer/src/CCseSchedulerServer.cpp
changeset 0 822a42b6c3f1
child 20 e53284de66c2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/videoscheduler/SchedulerServer/src/CCseSchedulerServer.cpp	Thu Dec 17 09:14:38 2009 +0200
@@ -0,0 +1,506 @@
+/*
+* Copyright (c) 2006 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 Scheduler server's Server class*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "CCseSchedulerServer.h"                // Header file for this class
+#include "CCseSchedulerServerSession.h"         // Server session
+#include "CCseSchedulerServerEngine.h"          // Server intelligence aka engine
+#include <ipvideo/CseSchedulerClientServerCommon.h>     // Common defines for client and server
+#include "CseSchedulerServer.pan"               // Server panic codes
+#include "CseDebug.h"                           // Debug macros
+#include <e32svr.h>
+#include <e32math.h>
+#include <e32uid.h>
+#include <e32def.h>
+
+
+// EXTERNAL DATA STRUCTURES
+// None
+
+// EXTERNAL FUNCTION PROTOTYPES  
+// None
+
+// 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,
+    };
+
+
+// MACROS
+// None
+
+// LOCAL CONSTANTS AND MACROS
+const TInt KDbStartTimeout              = 2000000;
+
+// MODULE DATA STRUCTURES
+// None
+
+// LOCAL FUNCTION PROTOTYPES
+// None
+
+// FORWARD DECLARATIONS
+// None
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::CCseSchedulerServer()
+// C++ constructor 
+// -----------------------------------------------------------------------------
+//
+CCseSchedulerServer::CCseSchedulerServer()
+    : CPolicyServer( EPriorityRealTimeServer, Policy, ESharableSessions ),
+    iContainerIx( NULL ),
+    iObjectCon( NULL ),
+    iSessionCount( 0 ),
+    iSchedulerEngine( NULL )
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::CCseSchedulerServer");
+    __DECLARE_NAME( _S( "CCseSchedulerServer" ) );
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::CCseSchedulerServer");
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::NewLC()
+// 
+// -----------------------------------------------------------------------------
+//
+CCseSchedulerServer* CCseSchedulerServer::NewLC( )
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::NewLC");
+    
+    CCseSchedulerServer* self = new ( ELeave ) CCseSchedulerServer;
+    CleanupStack::PushL( self );
+    
+    self->ConstructL( );
+    
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::NewLC");
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::ConstructL()
+// second-phase constructor; create the object container index.
+// -----------------------------------------------------------------------------
+//
+void CCseSchedulerServer::ConstructL( )
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::ConstructL");
+    iContainerIx = CObjectConIx::NewL();
+    iObjectCon = iContainerIx->CreateL(); 
+    StartL( KCseSchedulerServerName );
+    GetEngineObjectL();
+    iStarterBreaker = CPeriodic::NewL( CActive::EPriorityStandard );
+    
+    // break call chain
+	if( !iStarterBreaker->IsActive() )
+        {
+        // Give client 2 secs to make server session before we check 
+        // if server is needed or not.
+        iStarterBreaker->Start( KDbStartTimeout,
+                                KDbStartTimeout,
+                                TCallBack( StarterCallback, this ));
+        }
+    else
+        {
+        CSELOGSTRING_HIGH_LEVEL(
+            "CCseSchedulerServer::ConstructL - Breaker already active");
+        }
+    
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::ConstructL");    
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::~CCseSchedulerServer()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CCseSchedulerServer::~CCseSchedulerServer()
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::~CCseSchedulerServer");
+    DeleteSchedulerEngine();
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::~CCseSchedulerServer");
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::ThreadFunction()
+// The active scheduler is installed and started here.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCseSchedulerServer::ThreadFunction( )
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::ThreadFunction");
+	CTrapCleanup* cleanupStack = CTrapCleanup::New();    
+    if ( !cleanupStack )
+        {
+        PanicServer( ECseCreateTrapCleanup );
+        }
+
+    TRAPD( err, ThreadFunctionL( ) );
+    if ( err )
+        {
+        PanicServer( ECseSrvCreateServer );
+        }
+
+    delete cleanupStack;    
+    
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::ThreadFunction");
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::ThreadFunctionL()
+//
+// -----------------------------------------------------------------------------
+//
+void CCseSchedulerServer::ThreadFunctionL( )
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::ThreadFunctionL");
+
+    // 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
+    CCseSchedulerServer* server = CCseSchedulerServer::NewLC( );  // |-> 2    
+    
+    // Signal server is up
+    RProcess::Rendezvous( KErrNone );
+
+    // Start handling requests
+    CActiveScheduler::Start();
+
+    CleanupStack::PopAndDestroy( server ); // 2<-|
+    CleanupStack::PopAndDestroy( activeScheduler ); // 1<-|
+    
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::ThreadFunctionL");
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::PanicServer
+// Utility - panic the server
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+void CCseSchedulerServer::PanicServer( TCseSchedulerServPanic aPanic )
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::PanicServer");
+    _LIT( KSchedulerServer, "SchedulerServer" );
+    User::Panic( KSchedulerServer, aPanic );
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::PanicServer");
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::GetEngineObjectL()
+//
+// -----------------------------------------------------------------------------
+//
+CCseSchedulerServerEngine* CCseSchedulerServer::GetEngineObjectL()
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::GetEngineObjectL");
+        
+    if ( iObjectCon->Count() == 0 )
+        {
+        // Create scheduler engine
+        iSchedulerEngine = CCseSchedulerServerEngine::NewL( *this );
+       
+        // Add our engine to container
+        iObjectCon->AddL( iSchedulerEngine );
+        }
+    else
+        {
+        // default implementation return KErrNone.
+        if ( KErrNone != iSchedulerEngine->Open() )
+            {
+            User::Leave( KErrGeneral );
+            }
+        }
+    
+	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::GetEngineObjectL");
+    
+    // We have only one object in our container
+    return iSchedulerEngine;
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::Inc()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCseSchedulerServer::Inc()
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::Inc");
+    if ( iSessionCount!=KErrNotFound )
+        {
+        iSessionCount++;
+        }
+	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::Inc");
+    }
+
+// -----------------------------------------------------------------------------
+// CCseRTPServer::Dec()
+// 
+// -----------------------------------------------------------------------------
+//
+void CCseSchedulerServer::Dec()
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::Dec");
+    iSessionCount--;
+
+    if ( iSessionCount<=0 )
+        {
+        StopServer();
+        }
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::Dec");
+    }
+    
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::DeleteSchedulerEngine
+// Stops active scheduler and deletes object container and other objects.
+// -----------------------------------------------------------------------------
+void CCseSchedulerServer::DeleteSchedulerEngine()
+    {
+	CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::DeleteSchedulerEngine");
+    
+    if ( iContainerIx )
+        {
+        iSchedulerEngine->Close();
+        iContainerIx->Remove( iObjectCon );
+        delete iContainerIx; 
+		iContainerIx = NULL;
+		iSchedulerEngine = NULL;
+        }
+
+    if( iStarterBreaker->IsActive() )
+        {
+        iStarterBreaker->Cancel();
+        }
+    delete iStarterBreaker;    
+    iStarterBreaker = NULL;
+    
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::DeleteSchedulerEngine");
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::NewSessionL()
+// 
+// -----------------------------------------------------------------------------
+//
+
+CSession2* CCseSchedulerServer::NewSessionL( const TVersion& aVersion,
+                                             const RMessage2& /*aMessage*/ ) const
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::NewSessionL");
+    
+    // Check version is ok
+    TVersion v( KCseServMajorVersionNumber,
+                KCseServMinorVersionNumber,
+                KCseServBuildVersionNumber );
+    
+    if ( !User::QueryVersionSupported( v, aVersion ) )
+        {
+        User::Leave( KErrNotSupported );
+        }
+	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::NewSessionL");        
+    
+    // Make new session
+	return CCseSchedulerServerSession::NewL( ( CCseSchedulerServer* ) this );
+    }
+    
+// -----------------------------------------------------------------------------
+// CCseSchedulerServer::StopServer
+// Stops the server thread if no sessions active.
+// -----------------------------------------------------------------------------
+//
+void CCseSchedulerServer::StopServer()
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::StopServer");
+    TBool schedulerActive( iSchedulerEngine->IsSchedulerActive() );    
+    CSELOGSTRING2_HIGH_LEVEL("CCseSchedulerServer::StopServer - Session count: %d", iSessionCount);    
+    if ( (iSessionCount<=0) && (schedulerActive == EFalse))
+        {
+        CSELOGSTRING_HIGH_LEVEL("CCseSchedulerServer::StopServer - Call ActiveScheduler::Stop()");
+        CActiveScheduler::Stop();
+        }        
+
+    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::StopServer");
+    }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+// -----------------------------------------------------------------------------
+// StartThread()
+// Start the server thread. This is called from the client.
+// -----------------------------------------------------------------------------
+//
+TInt CCseSchedulerServer::StartThread()
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::StartThread");
+#if _DEBUG
+    __UHEAP_MARK;
+#endif
+       
+    // Check server not already started
+    TFindServer findCountServer( KCseSchedulerServerName );
+    TFullName name;
+    if ( findCountServer.Next( name ) == KErrNone )
+        { 
+        // Found server already
+        RProcess::Rendezvous( KErrNone );
+        CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::StartThread - Return value: KErrAlreadyExists");
+        return KErrAlreadyExists;
+        }
+
+    ThreadFunction( );
+
+#if _DEBUG
+    __UHEAP_MARKEND;
+#endif    
+	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::StartThread - Server down!");
+	
+    // All well
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------
+// CCseSchedulerServer::CustomSecurityCheckL()
+// --------------------------------------------------------------------------
+//
+CPolicyServer::TCustomResult CCseSchedulerServer::CustomSecurityCheckL(
+    const RMessage2& aMsg,
+    TInt& /*aAction*/,
+    TSecurityInfo& /*aMissing*/ )
+    {
+    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::CustomSecurityCheckL");
+    TCustomResult retVal ( EFail );
+    
+    // Check the messagge function range
+    if ( aMsg.Function() > ECseRequestBase && 
+         aMsg.Function() < ECseRequestLast )
+        {
+        
+        // Check if the client has required capabilities
+        // From .mmp-file capablity NetworkControl
+        if( // From .mmp-file following are CAP_SERVER capabilities
+            ! aMsg.HasCapability(ECapabilityNetworkServices ) ||
+            ! aMsg.HasCapability(ECapabilityLocalServices ) ||
+            ! aMsg.HasCapability(ECapabilityLocation ) ||
+            ! aMsg.HasCapability(ECapabilityReadUserData ) ||
+            ! aMsg.HasCapability(ECapabilityWriteUserData ) ||
+            ! aMsg.HasCapability(ECapabilityReadDeviceData ) ||
+            ! aMsg.HasCapability(ECapabilityWriteDeviceData ) ||        
+            ! aMsg.HasCapability(ECapabilityUserEnvironment ) ||
+            ! aMsg.HasCapability(ECapabilitySwEvent ) )
+            {         
+            CSELOGSTRING2_HIGH_LEVEL(
+                "CCseSchedulerServer::CustomSecurityCheckL() No capability for message %d!!!",
+                aMsg.Function() );                 
+            }
+        else
+            {
+            CSELOGSTRING2_HIGH_LEVEL(
+                "CCseSchedulerServer::CustomSecurityCheckL() Message %d inside range and capabilities ok",
+                aMsg.Function() );
+            retVal = EPass;
+            }
+        }
+    else
+        {
+        CSELOGSTRING2_HIGH_LEVEL(
+            "CCseSchedulerServer::CustomSecurityCheckL() Message %d outside known range!!!",
+            aMsg.Function() );            
+        }
+    
+    if( retVal == EPass )
+        {
+        CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::CustomSecurityCheckL - Passed");
+        }
+    else
+        {
+        CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::CustomSecurityCheckL - Failed");
+        }    
+    return retVal;
+    }
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServerEngine::StarterCallback
+// -----------------------------------------------------------------------------
+//
+TInt CCseSchedulerServer::StarterCallback( TAny* aPtr )
+	{
+	CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::StarterCallback");
+	TBool retVal( EFalse);
+	retVal = static_cast<CCseSchedulerServer*>( aPtr )->HandleStarterCallback();
+	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::StarterCallback");
+	return retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// CCseSchedulerServerEngine::HandleCompletitionCallback
+// -----------------------------------------------------------------------------
+//
+TInt CCseSchedulerServer::HandleStarterCallback() 
+	{
+	CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerServer::HandleStarterCallback ");
+	
+	// We dont want to use periodic anymore, so we cancel it. We just wanted to
+	// make call here 2 secs after server has been created.
+	iStarterBreaker->Cancel();  
+	
+	// Check if server can be stopped.
+    iSchedulerEngine->RequestReschedule();
+	
+	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerServer::HandleStarterCallback ");
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// E32Main()
+// Server startup
+// Returns: KErrNone
+// -----------------------------------------------------------------------------
+//
+GLDEF_C TInt E32Main()
+    {
+    return CCseSchedulerServer::StartThread();
+    }
+
+// End of File