/*
* Copyright (c) 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: This module contains implementation of CSettingServer
* class member functions.
*
*/
// INCLUDE FILES
#include <e32std.h>
#include <e32svr.h>
#include "SettingServerClient.h"
#include "SettingServer.h"
#include <StifLogger.h>
#include "Logging.h"
// EXTERNAL DATA STRUCTURES
// EXTERNAL FUNCTION PROTOTYPES
// CONSTANTS
// MACROS
// LOCAL CONSTANTS AND MACROS
// MODULE DATA STRUCTURES
// Struct to pass parameters to server thread
struct TThreadStartSetting
{
TFileName iName; // Server name
RThread iServerThread; // The server thread
RSemaphore iStarted; // Startup syncronisation semaphore
TInt iStartupResult;// Start-up result
};
// LOCAL FUNCTION PROTOTYPES
// FORWARD DECLARATIONS
// ==================== LOCAL FUNCTIONS =======================================
// None
#undef LOGGER
#define LOGGER iSettingServerLogger
// ================= MEMBER FUNCTIONS =========================================
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: PanicServer
Description: Panics the server.
Parameters: const TSettingServerPanic aPanic :in: Panic code
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
void CSettingServer::PanicServer( const TSettingServerPanic aPanic )
{
/*#ifdef USE_LOGGER
// Check if logger is available, if so, use it.
CStifLogger* log = (CStifLogger*) Dll::Tls();
if (log)
{
log->Log(_L("SettingServer.DLL Panic %d"), aPanic);
}
#endif
*/
RDebug::Print( _L( "CSettingServer::PanicServer" ) );
_LIT( KTxtServer,"CSettingServer" );
User::Panic( KTxtServer,aPanic );
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: NewL
Description: Returns new CSettingServer object
Parameters: const TName& aName: in: Server name
Return Values: None
Errors/Exceptions: Leaves if memory allocation, ConstructL or StartL
leaves.
Status: Proposal
-------------------------------------------------------------------------------
*/
CSettingServer* CSettingServer::NewL( const TName& aName )
{
CSettingServer* self = new( ELeave ) CSettingServer();
CleanupStack::PushL( self );
// Construct the server
self->ConstructL();
// Start the server
self->StartL( aName );
CleanupStack::Pop( self );
return self;
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: ConstructL
Description: Second level constructor.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
void CSettingServer::ConstructL()
{
// Create logger, in Wins use HTML in HW default logger
TLoggerSettings loggerSettings;
// Directory must create by hand if test engine log wanted
loggerSettings.iCreateLogDirectories = EFalse;
loggerSettings.iOverwrite = ETrue;
loggerSettings.iTimeStamp = ETrue;
loggerSettings.iLineBreak = ETrue;
loggerSettings.iEventRanking = EFalse;
loggerSettings.iThreadId = EFalse;
loggerSettings.iHardwareFormat = CStifLogger::ETxt;
#ifndef FORCE_STIF_INTERNAL_LOGGING_TO_RDEBUG
loggerSettings.iEmulatorFormat = CStifLogger::EHtml;
loggerSettings.iHardwareOutput = CStifLogger::EFile;
loggerSettings.iEmulatorOutput = CStifLogger::EFile;
#else
RDebug::Print( _L( "STIF SettingServer logging forced to RDebug" ) );
loggerSettings.iEmulatorFormat = CStifLogger::ETxt;
loggerSettings.iHardwareOutput = CStifLogger::ERDebug;
loggerSettings.iEmulatorOutput = CStifLogger::ERDebug;
#endif
loggerSettings.iUnicode = EFalse;
loggerSettings.iAddTestCaseTitle = EFalse;
iSettingServerLogger = CStifLogger::NewL(
_L( "C:\\logs\\testframework\\testengine\\"),
_L( "SettingServer" ),
loggerSettings );
// iLoggerSettings initializations to indicate is setting in use
iLoggerSettings.iIsDefined.iCreateLogDir = EFalse;
iLoggerSettings.iEmulatorPath.Copy( _L( "" ) );
iLoggerSettings.iEmulatorFormat = CStifLogger::ETxt;
iLoggerSettings.iEmulatorOutput = CStifLogger::EFile;
iLoggerSettings.iHardwarePath.Copy( _L( "" ) );
iLoggerSettings.iHardwareFormat = CStifLogger::ETxt;
iLoggerSettings.iHardwareOutput = CStifLogger::EFile;
iLoggerSettings.iOverwrite = ETrue;
iLoggerSettings.iTimeStamp = ETrue;
iLoggerSettings.iLineBreak = ETrue;
iLoggerSettings.iEventRanking = EFalse;
iLoggerSettings.iThreadId = EFalse;
iLoggerSettings.iUnicode = EFalse;
iLoggerSettings.iAddTestCaseTitle = EFalse;
iLoggerSettings.iIsDefined.iPath = EFalse;
iLoggerSettings.iIsDefined.iHwPath = EFalse;
iLoggerSettings.iIsDefined.iFormat = EFalse;
iLoggerSettings.iIsDefined.iHwFormat = EFalse;
iLoggerSettings.iIsDefined.iOutput = EFalse;
iLoggerSettings.iIsDefined.iHwOutput = EFalse;
iLoggerSettings.iIsDefined.iOverwrite = EFalse;
iLoggerSettings.iIsDefined.iLineBreak = EFalse;
iLoggerSettings.iIsDefined.iTimeStamp = EFalse;
iLoggerSettings.iIsDefined.iEventRanking = EFalse;
iLoggerSettings.iIsDefined.iThreadId = EFalse;
iLoggerSettings.iIsDefined.iUnicode = EFalse;
iLoggerSettings.iIsDefined.iAddTestCaseTitle = EFalse;
__TRACE( KInit,( _L( "-.-.-.-.-.-.-.-.-.- SettingServer log starts -.-.-.-.-.-.-.-.-.-" ) ) );
__TRACE( KInit,( _L( "CSettingServer::ConstructL()" ) ) );
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: CSettingServer
Description: Constructor.
Initialises non-zero member variables and base class with correct
priority.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
CSettingServer::CSettingServer() :
CServer2( CSettingServer::ESettingServerSchedulerPriority )
{
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: ~CSettingServer
Description: Destructor.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
CSettingServer::~CSettingServer()
{
delete iSettingServerLogger;
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: NewSessionL
Description: Returns new session.
Parameters: const TVersion &aVersion:in :Version required
Return Values: CSharableSession* New session
Errors/Exceptions: Leaves if invalid version
Leaves if CSettingServer construction leaves
Status: Proposal
-------------------------------------------------------------------------------
*/
CSession2* CSettingServer::NewSessionL( const TVersion& aVersion,
const RMessage2& /*aMessage*/ ) const
{
// check version is ok
TVersion v( KSettingServerMajorVersionNumber,
KSettingServerMinorVersionNumber,
KSettingServerVersionNumber
);
if( !User::QueryVersionSupported( v, aVersion ) )
{
User::Leave( KErrNotSupported );
}
return CLoggerSetting::NewL( ( CSettingServer* ) this );
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: OpenSession
Description: Opens session. Session calls calls this when session is
properly constructed.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
void CSettingServer::OpenSession()
{
iSessions++;
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: Logger
Description: Return pointer to the Logger(iSettingServerLogger)
Parameters: None
Return Values: CStifLogger*: Pointer to Logger
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
CStifLogger* CSettingServer::Logger()
{
return iSettingServerLogger;
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: CloseSession
Description: Closes session. CLoggerSetting::CloseSession calls this
to inform server class.
If there are not any active sessions, then stop active scheduler and
close whole server.
Parameters: None
Return Values: None
Errors/Exceptions: Function panics if OpenSessions() and CloseSessions()
does not match.
Status: Proposal
-------------------------------------------------------------------------------
*/
void CSettingServer::CloseSession()
{
__ASSERT_ALWAYS ( iSessions > 0, CSettingServer::PanicServer(ETooManyCloseSessions));
iSessions--;
if ( iSessions == 0 )
{
// Stop the active scheduler if no-one is using server anymore
CActiveScheduler::Stop();
}
}
/*
-------------------------------------------------------------------------------
Class: CSettingServer
Method: ThreadFunction
Description: The thread function, where Setting Server lives in
Parameters: TAny* aStartInfo aName: in: Start-up information
Return Values: TInt: Result from server start
Errors/Exceptions: Panics current thread if:
Invalid start-up information
Clean-up stack can't be created
Setting Server can't be started
Status: Proposal
-------------------------------------------------------------------------------
*/
TInt CSettingServer::ThreadFunction( TAny* aStarted )
{
__UHEAP_MARK;
// Get start-up information
TThreadStartSetting* startInfo = ( TThreadStartSetting* ) aStarted;
__ASSERT_ALWAYS( startInfo,PanicServer( ENoStartupInformation ) );
// Create clean-up stack
CTrapCleanup* tc = CTrapCleanup::New();
__ASSERT_ALWAYS( tc, PanicServer(ECreateTrapCleanup));
// Construct and install active scheduler
CActiveScheduler* scheduler = new CActiveScheduler;
__ASSERT_ALWAYS( scheduler, PanicServer( EMainSchedulerError ) );
CActiveScheduler::Install( scheduler );
// Construct server
CSettingServer* server = NULL;
RDebug::Print( startInfo->iName );
TRAPD( err, server = CSettingServer::NewL( startInfo->iName ) );
__ASSERT_ALWAYS( !err, PanicServer( ESvrCreateServer ) );
// Inform that we are up and running
startInfo->iStartupResult = KErrNone;
startInfo->iStarted.Signal();
// Start handling requests
CActiveScheduler::Start();
// Execution continues from here after CActiveScheduler::Stop
// Delete the server. This should be deleted before scheduler,
// if server still has any active objects
delete server;
server = NULL;
// Delete scheduler.
delete scheduler;
scheduler = NULL;
// Delete clean-up stack
delete tc;
tc = NULL;
__UHEAP_MARKEND;
return KErrNone;
}
// ================= OTHER EXPORTED FUNCTIONS =================================
/*
-------------------------------------------------------------------------------
Class: -
Method: StartNewServer
Description: Starts a new server. Server will be running its own
thread and this functions returns when server is up and running or
server start-up fails.
Parameters: TName& aServerName: inout: The name of the server
Return Values: TInt: Symbian error code
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
EXPORT_C TInt StartNewServer( TName& aServerName )
{
__UHEAP_MARK;
_LIT(KServerName, "SettingServer");
//Ccheck server not already started
TFindServer findServer( KServerName );
TFullName name;
if( findServer.Next( name ) == KErrNone )
{
// Server already started, nothing to do
aServerName = KServerName;
__UHEAP_MARKEND;
return KErrAlreadyExists;
}
// Construct start-up information object
TThreadStartSetting* startInfo = new TThreadStartSetting();
if( startInfo == NULL )
{
__UHEAP_MARKEND;
return KErrNoMemory;
}
// Fill the start-up information
startInfo->iName = KServerName;
startInfo->iStartupResult = KErrNone;
startInfo->iStarted.CreateLocal( 0 );
// Create thread
TInt res = startInfo->iServerThread.Create(
startInfo->iName , // Name of thread
CSettingServer::ThreadFunction, // Thread function
KDefaultStackSize, // Stack size
KDefaultHeapSize, // Heap initial size
KMaxHeapSize, // Heap start max size
startInfo // Parameter to thread function
);
// If thread creation failed
if( res != KErrNone )
{
startInfo->iStarted.Close(); // Close semaphore
delete startInfo;
startInfo = NULL;
__UHEAP_MARKEND;
return res;
}
// Now start thread
startInfo->iServerThread.SetPriority( EPriorityMuchMore );
startInfo->iServerThread.Resume();
// Wait until the thread is started
startInfo->iStarted.Wait();
// Server is started( or it has returned error )
// Set server name
aServerName = KServerName;
// Free memory
TInt r = startInfo->iStartupResult;
startInfo->iServerThread.Close();
startInfo->iStarted.Close();
delete startInfo;
startInfo = NULL;
__UHEAP_MARKEND;
// Return start-up result.
return r;
}
// End of File