convergedconnectionhandler/cchserver/src/cchserverbase.cpp
changeset 0 a4daefaec16c
child 14 be41ab7b952f
--- /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 <ecom/ecom.h>
+
+// 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<CCCHServerBase&>( *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 <class T>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 <class T>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<CObjectConIx>( iObjectConIx );
+    }
+
+// ---------------------------------------------------------------------------
+// CCCHServerBase::RequestStorage
+// Return instance of request storage.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CCCHRequestStorage& CCCHServerBase::RequestStorage()
+    {
+    return ConstructObject<CCCHRequestStorage>( this, iRequestStorage );
+    }
+
+// ---------------------------------------------------------------------------
+// CCCHServerBase::ConnMonHandler
+// Return instance of ConnMonHandler.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CCCHConnMonHandler& CCCHServerBase::ConnMonHandler()
+    {
+    return ConstructObject<CCCHConnMonHandler>( this, iConnMonHandler );
+    }
+    
+// -----------------------------------------------------------------------------
+// CCCHServerBase::PluginHandler
+// Return instance of plug-in handler.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CCCHPluginHandler& CCCHServerBase::PluginHandler()
+    {
+    return ConstructObject<CCCHPluginHandler>( this, iPluginHandler );
+    }
+
+// ---------------------------------------------------------------------------
+// CCCHServerBase::SPSHandler
+// Return instance of SPSHandler.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CCCHSPSHandler& CCCHServerBase::SPSHandler()
+    {
+    return ConstructObject<CCCHSPSHandler>( this, iSPSHandler );
+    }
+    
+// ---------------------------------------------------------------------------
+// CCCHServerBase::ServiceHandler
+// Return instance of ServiceHandler.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CCCHServiceHandler& CCCHServerBase::ServiceHandler()
+    {
+    return ConstructObject<CCCHServiceHandler>( this, iServiceHandler );
+    }
+
+// ---------------------------------------------------------------------------
+// CCCHServerBase::FeatureManager
+// Return instance of FeatureManager.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CCchFeatureManager& CCCHServerBase::FeatureManager()
+    {
+    return ConstructObject<CCchFeatureManager>( 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<TUint> 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