diff -r 000000000000 -r a4daefaec16c convergedconnectionhandler/cchserver/src/cchserverbase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/convergedconnectionhandler/cchserver/src/cchserverbase.cpp Mon Jan 18 20:12:36 2010 +0200 @@ -0,0 +1,674 @@ +/* +* Copyright (c) 2006-2009 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: CCCHServerBase implementation +* +*/ + + +// INCLUDE FILES +#include "cchlogger.h" +#include "cchserverbase.h" +#include "cchsession.h" +#include "cchrequeststorage.h" +#include "cchconnmonhandler.h" +#include "cchspshandler.h" +#include "cchservicehandler.h" +#include "cchpluginhandler.h" +#include "cchfeaturemanager.h" +#include "cchwakeupeventnotifier.h" +#include "cchstartupcounter.h" +#include "cchactivescheduler.h" + +#include + +// EXTERNAL DATA STRUCTURES +// None + +// EXTERNAL FUNCTION PROTOTYPES +// None + +// CONSTANTS +// None + +// MACROS +// None + +// LOCAL CONSTANTS AND MACROS +// None + +// MODULE DATA STRUCTURES +// None + +// LOCAL FUNCTION PROTOTYPES +GLDEF_C TInt E32Main(); +#ifdef _DEBUG +GLDEF_C void MemUsage(); +#endif +// FORWARD DECLARATIONS +// None + +// ============================= LOCAL FUNCTIONS ============================= + +// --------------------------------------------------------------------------- +// InitServerL Creates CCHServer. +// Returns: None. +// --------------------------------------------------------------------------- +// +static void InitServerL() + { + CCHLOGSTRING("CCCHServerBase::InitServerL"); + + // This is only for startup situation, because starter does not use + // connect metod, which in normal situation reserves the mutex + RMutex serverStartMutex; + CleanupClosePushL( serverStartMutex ); + TInt createError( serverStartMutex.CreateGlobal( KCCHServerStartMutex ) ); + if ( KErrNone != createError ) + { + User::LeaveIfError( serverStartMutex.OpenGlobal( KCCHServerStartMutex ) ); + } + + serverStartMutex.Wait(); + CCHLOGSTRING( "CCCHServerBase::InitServerL: mutex available" ); + + TFullName name; + TFindServer findServer( KCCHServerName ); + // Check that the server does not exists. + if( findServer.Next( name ) == KErrNotFound ) + { + User::LeaveIfError( User::RenameThread( KCCHServerName ) ); + + // create and install the active scheduler we need + CCchActiveScheduler* scheduler = new (ELeave) CCchActiveScheduler; + CleanupStack::PushL( scheduler ); + CActiveScheduler::Install( scheduler ); + + // create the server (leave it on the cleanup stack) + CCCHServerBase* server = NULL; + TRAPD( err, server = CCCHServerBase::NewL() ); + + if ( KErrNone != err ) + { + CCHLOGSTRING2 + ("InitServerL: Server creation failed, error = %d", err ); + + server->PanicServer( ECCHErrCreateServer ); + } + + // Scheduler needs server, because server might needs to be restarted + scheduler->SetServer( server ); + // Initialisation complete, now signal the client + RProcess::Rendezvous( KErrNone ); + + // Release and close mutex + CCHLOGSTRING( "CCCHServerBase::InitServerL: Release the mutex" ); + serverStartMutex.Signal(); + serverStartMutex.Close(); + + // Ready to run + CCHLOGSTRING( "CCCHServerBase::InitServerL: Server Running..." ); + CActiveScheduler::Start(); + + // Cleanup the mutex, scheduler and server + delete server; + server = NULL; + + CleanupStack::PopAndDestroy( scheduler ); + } + else + { + CCHLOGSTRING( "CCCHServerBase::InitServerL: cch server already exists" ); + RProcess::Rendezvous( KErrAlreadyExists ); + // Release and close mutex + CCHLOGSTRING( "CCCHServerBase::InitServerL: Release the mutex" ); + serverStartMutex.Signal(); + serverStartMutex.Close(); + } + CleanupStack::PopAndDestroy( &serverStartMutex ); + } + +// ============================ MEMBER FUNCTIONS ============================= + +// --------------------------------------------------------------------------- +// CCCHServerBase::CCCHServerBase +// C++ default constructor can NOT contain any code, that might leave. +// --------------------------------------------------------------------------- +// +CCCHServerBase::CCCHServerBase() : + CPolicyServer( EPriorityHigh, KCCHPolicy ), + iSessionCounter( 0 ) + { + CCHLOGSTRING( "CCCHServerBase::CCCHServerBase" ); + iVoIPEmergencyNoteShown = EFalse; + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ConstructL +// Symbian 2nd phase constructor can leave. +// --------------------------------------------------------------------------- +// +void CCCHServerBase::ConstructL() + { + CCHLOGSTRING( "CCCHServerBase::ConstructL" ); + iWakeUpEventNotifier = CCchWakeUpEventNotifier::NewL( *this ); + + InitServerObjectsL(); + //Start server + StartL( KCCHServerName ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::NewL +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CCCHServerBase* CCCHServerBase::NewL() + { + CCCHServerBase* self = CCCHServerBase::NewLC(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::NewLC +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CCCHServerBase* CCCHServerBase::NewLC() + { + CCCHServerBase* self = new (ELeave)CCCHServerBase(); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// Destructor +CCCHServerBase::~CCCHServerBase() + { + delete iStartupCounter; + delete iWakeUpEventNotifier; + + ReleaseAllResources(); + REComSession::FinalClose(); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::NewSessionL +// This is called by RSessionBase (base class for client interface). +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CSession2* CCCHServerBase::NewSessionL( const TVersion& aVersion, + const RMessage2& /* aMessage */ ) const + { + CCHLOGSTRING( "CCCHServerBase::NewSessionL" ); + + TVersion version( KCCHServMajorVersionNumber, + KCCHServMinorVersionNumber, + KCCHServBuildVersionNumber ); + + if ( !User::QueryVersionSupported( version , aVersion ) ) + { + User::Leave( KErrNotSupported ); + } + CCCHSession* session = + CCCHSession::NewL( const_cast( *this ) ); + return session; + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ShutdownServerL +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CCCHServerBase::ShutDownServerL() + { + CCHLOGSTRING( "CCCHServerBase::ShutDownServerL - IN" ); + + if ( !iSessionCounter && IsServerShutdownAllowedL() ) + { + CCHLOGSTRING( "CCCHServerBase::ShutDownServerL - Allowed" ); + // if session counter is zero -> close server + // MSI: Shouldn't we continue in minimal mode? + // CActiveScheduler::Current()->Stop(); + TRAP_IGNORE( StartMinimalServerL() ); + } + CCHLOGSTRING( "CCCHServerBase::ShutDownServerL - OUT" ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::InitServerL +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CCCHServerBase::InitServerObjectsL() + { + CCHLOGSTRING( "CCCHServerBase::InitServerObjectsL: IN" ); + + ServiceHandler().InitServiceHandlerL(); + + if ( iServiceHandler->IsStartupFlagSet() ) + { + // Start monitoring startup flag registration, this may set startup + // flag to OFF if crashes happens more than KCCHMaxStartupCount during + // startup flag registration + TRAP_IGNORE( CreateStartupCounterL() ); + // If CCH cannot load the Plug-ins, CCH can still + // try to load them later + TRAP_IGNORE( iServiceHandler->LoadPluginsL() ); + RequestStorage().ScanNetworks(); + // initialization is now done. update states and send notification to + // all clients + iServerObjectsInit = ETrue; + iServiceHandler->UpdateL(); + } + else + { + // Startup flag is not ON, we have to be sure that startup counter + // is truly zero for the next time when startup flag is ON + ResetStartupCounterL(); + StartMinimalServerL(); + } + CCHLOGSTRING( "CCCHServerBase::InitServerObjectsL: OUT" ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::StartMinimalServerL +// Start server in settings monitoring mode +// --------------------------------------------------------------------------- +// +void CCCHServerBase::StartMinimalServerL() + { + CCHLOGSTRING( "CCCHServerBase::StartMinimalServerL IN" ); + + iWakeUpEventNotifier->StartL(); + ReleaseAllResources(); + CCHLOGSTRING( "CCCHServerBase::StartMinimalServerL OUT" ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ReleaseAllResources +// Start server in settings monitoring mode +// --------------------------------------------------------------------------- +// +void CCCHServerBase::ReleaseAllResources() + { + CCHLOGSTRING( "CCCHServerBase::ReleaseAllResources" ); + + delete iServiceHandler; + iServiceHandler = NULL; + delete iSPSHandler; + iSPSHandler = NULL; + delete iConnMonHandler; + iConnMonHandler = NULL; + delete iRequestStorage; + iRequestStorage = NULL; + delete iPluginHandler; + iPluginHandler = NULL; + delete iFeatureManager; + iFeatureManager = NULL; + delete iObjectConIx; + iObjectConIx = NULL; + } + + +// --------------------------------------------------------------------------- +// CCCHServerBase::NotifySessionCreatedL +// Increase session counter +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CCCHServerBase::NotifySessionCreatedL() + { + CCHLOGSTRING( "CCCHServerBase::NotifySessionCreatedL" ); + + iWakeUpEventNotifier->Stop(); + + if ( iSessionCounter == 0 && IsServerShutdownAllowedL() ) + { + ServiceHandler().InitServiceHandlerL(); + } + iSessionCounter++; + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::NotifySessionClosed +// Decrease session counter +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CCCHServerBase::NotifySessionClosed() + { + CCHLOGSTRING( "CCCHServerBase::NotifySessionClosed" ); + if ( 0 < iSessionCounter ) + { + iSessionCounter--; + } + if ( 0 >= iSessionCounter ) + { + iSessionCounter = 0; + TRAP_IGNORE( ShutDownServerL() ); + } + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::PanicClient +// Panic client with given error code. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CCCHServerBase::PanicClient( + const RMessage2& aMessage, + TInt aPanic ) + { + CCHLOGSTRING2("CCCHServerBase::PanicClient: Panic = %d", aPanic ); + _LIT( KTxtServer, "CCH Server Client" ); + aMessage.Panic( KTxtServer, aPanic ); + CCHLOGSTRING("CCCHServerBase::PanicClient exiting" ); + } + +// --------------------------------------------------------------------------- +// PanicServer implements server panic handler. +// Panic server with given error code. +// Returns: None. +// --------------------------------------------------------------------------- +// +void CCCHServerBase::PanicServer( + TInt aPanic ) + { + CCHLOGSTRING2("CCCHServerBase::PanicServer: Panic = %d", aPanic ); + _LIT( KTxtServerPanic, "CCH Server" ); + User::Panic( KTxtServerPanic, aPanic ); + CCHLOGSTRING("CCCHServerBase::PanicServer exit" ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ConstructObject +// Create requested object and/or return reference to it. +// --------------------------------------------------------------------------- +// +template T& CCCHServerBase::ConstructObject( + CCCHServerBase* aThis, + T*& aObject ) + { + TInt error = KErrNone; + if ( !aObject ) + { + TRAP( error, aObject = T::NewL( *aThis ) ); + } + + if ( KErrNone != error ) + { + // Failed to create object, have to Panic! + PanicServer( ECCHErrCreateServer ); + } + return *aObject; + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ConstructObject +// Create requested object and/or return reference to it. +// --------------------------------------------------------------------------- +// +template T& CCCHServerBase::ConstructObject( + T*& aObject ) + { + TInt error = KErrNone; + if ( !aObject ) + { + TRAP( error, aObject = T::NewL() ); + } + + if ( KErrNone != error ) + { + // Failed to create object, have to Panic! + PanicServer( ECCHErrCreateServer ); + } + return *aObject; + } + +TBool CCCHServerBase::VoIPEmergencyNoteShown() + { + return iVoIPEmergencyNoteShown; + } + +void CCCHServerBase::SetVoIPEmergencyNoteShown( TBool aShown ) + { + iVoIPEmergencyNoteShown = aShown; + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ObjectContainerIx +// Return object container index. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +CObjectConIx& CCCHServerBase::ObjectContainerIx() + { + return ConstructObject( iObjectConIx ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::RequestStorage +// Return instance of request storage. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +CCCHRequestStorage& CCCHServerBase::RequestStorage() + { + return ConstructObject( this, iRequestStorage ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ConnMonHandler +// Return instance of ConnMonHandler. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +CCCHConnMonHandler& CCCHServerBase::ConnMonHandler() + { + return ConstructObject( this, iConnMonHandler ); + } + +// ----------------------------------------------------------------------------- +// CCCHServerBase::PluginHandler +// Return instance of plug-in handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CCCHPluginHandler& CCCHServerBase::PluginHandler() + { + return ConstructObject( this, iPluginHandler ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::SPSHandler +// Return instance of SPSHandler. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +CCCHSPSHandler& CCCHServerBase::SPSHandler() + { + return ConstructObject( this, iSPSHandler ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ServiceHandler +// Return instance of ServiceHandler. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +CCCHServiceHandler& CCCHServerBase::ServiceHandler() + { + return ConstructObject( this, iServiceHandler ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::FeatureManager +// Return instance of FeatureManager. +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +CCchFeatureManager& CCCHServerBase::FeatureManager() + { + return ConstructObject( iFeatureManager ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::WakeUp +// Creates all required objects needed by full server mode. +// --------------------------------------------------------------------------- +// +void CCCHServerBase::WakeUp() + { + CCHLOGSTRING( "CCCHServerBase::WakeUp IN" ); + if ( iSessionCounter == 0 && !iServerObjectsInit ) + { + TRAPD( err, InitServerObjectsL() ); + if ( KErrNone != err ) + { + // Failed to create required objects, have to Panic! + PanicServer( ECCHErrCreateServer ); + } + } + CCHLOGSTRING( "CCCHServerBase::WakeUp OUT" ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::CreateStartupCounterL +// +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CCCHServerBase::CreateStartupCounterL() + { + if ( !iStartupCounter ) + { + iStartupCounter = CCchStartupCounter::NewL( *this ); + } + iStartupCounter->StartupOccuredL(); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::ResetStartupCounterL +// +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CCCHServerBase::ResetStartupCounterL() + { + if ( !iStartupCounter ) + { + iStartupCounter = CCchStartupCounter::NewL( *this ); + } + iStartupCounter->ResetStartupCounter(); + delete iStartupCounter; + iStartupCounter = NULL; + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::Restart +// +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +void CCCHServerBase::Restart() + { + CCHLOGSTRING( "CCCHServerBase::Restart IN" ); + + // Send notify to our client + TRAP_IGNORE( iServiceHandler->HandleRestartL() ); + + // Do we have to make reregistration + if ( iServiceHandler->IsStartupFlagSet() ) + { + delete iServiceHandler; + iServiceHandler = NULL; + delete iPluginHandler; + iPluginHandler = NULL; + TRAP_IGNORE( InitServerObjectsL() ); + } + + CCHLOGSTRING( "CCCHServerBase::Restart OUT" ); + } + +// --------------------------------------------------------------------------- +// CCCHServerBase::IsServerShutdownAllowedL +// (other items were commented in a header). +// --------------------------------------------------------------------------- +// +TBool CCCHServerBase::IsServerShutdownAllowedL() + { + CCHLOGSTRING( "CCCHServerBase::IsServerShutdownAllowedL" ); + + TBool shutDownAllowed( ETrue ); + + if ( iSPSHandler && iServiceHandler ) + { + // Get service IDs + RArray serviceIds; + CleanupClosePushL( serviceIds ); + + iSPSHandler->GetServiceIdsL( serviceIds ); + + TCCHSubserviceState state( ECCHUninitialized ); + + for ( TInt i( 0 ); i < serviceIds.Count(); i++ ) + { + state = iServiceHandler->ServiceState( serviceIds[i] ); + + if ( ECCHDisabled != state && ECCHUninitialized != state ) + { + shutDownAllowed = EFalse; + } + } + + CleanupStack::PopAndDestroy( &serviceIds ); + } + + CCHLOGSTRING2("CCCHServerBase::IsServerShutdownAllowedL: shutDownAllowed = %d", shutDownAllowed ); + return shutDownAllowed; + } + +// ========================== OTHER EXPORTED FUNCTIONS ======================= + +// --------------------------------------------------------------------------- +// E32Main implements the executable entry function. +// Note that because the target type of the CCHServer module +// is EXEDLL, the entry point has different signature depending +// on the build platform. +// Creates a cleanup stack and runs the server. +// Returns: Zero +// --------------------------------------------------------------------------- +// +GLDEF_C TInt E32Main() + { + TInt error( KErrNoMemory ); + __UHEAP_MARK; + CCHLOGSTRING( "CCCHServerBase E32Main" ); + CTrapCleanup* cleanup = CTrapCleanup::New(); + + + if ( cleanup ) + { + TRAP( error, InitServerL() ); + delete cleanup; + } + + __UHEAP_MARKEND; + + return error; + } + +// End of File