diff -r 826cea16efd9 -r 13a33d82ad98 videoscheduler/SchedulerServer/src/CCseSchedulerServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoscheduler/SchedulerServer/src/CCseSchedulerServer.cpp Wed Sep 01 12:20:37 2010 +0100 @@ -0,0 +1,511 @@ +/* +* 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 // Common defines for client and server +#include "CseSchedulerServer.pan" // Server panic codes +#include "CseDebug.h" // Debug macros +#include +#include +#include +#include + + +// 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::NewLC"); + + CCseSchedulerServer* self = new ( ELeave ) CCseSchedulerServer; + CleanupStack::PushL( self ); + + self->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::~CCseSchedulerServer"); + DeleteSchedulerEngine(); + CSELOGSTRING_HIGH_LEVEL("<<>>CCseSchedulerServer::ThreadFunction"); + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + if ( !cleanupStack ) + { + CSELOGSTRING_HIGH_LEVEL("CCseSchedulerServer::ThreadFunction - Could not create cleanupstack: %d"); + return KErrNone; + } + + TRAPD( err, ThreadFunctionL( ) ); + if ( err ) + { + CSELOGSTRING2_HIGH_LEVEL("CCseSchedulerServer::ThreadFunction - Main thread leaved: %d", err ); + } + + delete cleanupStack; + + 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::PanicServer"); + _LIT( KSchedulerServer, "SchedulerServer" ); + User::Panic( KSchedulerServer, aPanic ); + 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::Inc"); + if ( iSessionCount!=KErrNotFound ) + { + iSessionCount++; + } + CSELOGSTRING_HIGH_LEVEL("<<>>CCseSchedulerServer::Dec"); + iSessionCount--; + + if ( iSessionCount<=0 ) + { + StopServer(); + } + CSELOGSTRING_HIGH_LEVEL("<<>>CCseSchedulerServer::DeleteSchedulerEngine"); + + if ( iContainerIx ) + { + if( iObjectCon->Count() > 0 ) + { + iSchedulerEngine->Close(); + } + + iContainerIx->Remove( iObjectCon ); + delete iContainerIx; + iContainerIx = NULL; + iSchedulerEngine = NULL; + } + + if( iStarterBreaker && iStarterBreaker->IsActive() ) + { + iStarterBreaker->Cancel(); + } + delete iStarterBreaker; + iStarterBreaker = NULL; + + 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::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::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::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::StarterCallback"); + TBool retVal( EFalse); + retVal = static_cast( aPtr )->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("<<