/*
* Copyright (c) 2008-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:
*
*/
/**
@file
@internalComponent
*/
#include "msmmserver.h"
#include <usb/hostms/msmmpolicypluginbase.h>
#include "msmm_internal_def.h"
#include "msmmsession.h"
#include "msmmengine.h"
#include "eventqueue.h"
#include "msmmterminator.h"
#include <usb/usblogger.h>
#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, "UsbHostMsmmServer");
#endif
// Static public functions
TInt CMsmmServer::ThreadFunction()
{
TInt ret = KErrNone;
__UHEAP_MARK;
// Create the cleanup stack
CTrapCleanup* cleanupStack = CTrapCleanup::New();
if (cleanupStack)
{
#ifdef __FLOG_ACTIVE
(void)CUsbLog::Connect();
#endif
TRAP(ret, ThreadFunctionL());
#ifdef __FLOG_ACTIVE
CUsbLog::Close();
#endif
delete cleanupStack;
}
else
{
ret = KErrNoMemory;
}
__UHEAP_MARKEND;
return ret;
}
void CMsmmServer::ThreadFunctionL()
{
LOG_STATIC_FUNC_ENTRY
TSecureId creatorSID = User::CreatorSecureId();
if (KFDFWSecureId != creatorSID)
{
// Only FDF process can be the creator of the MSMM server
User::Leave(KErrPermissionDenied);
}
// Create and install the active scheduler
CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);
// Create the server and leave it on cleanup stack
CMsmmServer::NewLC();
// Signal the client that the server is up and running
RProcess::Rendezvous(KErrNone);
RThread().SetPriority(EPriorityAbsoluteHigh);
// Start the active scheduler, the server will now service
// request messages from clients.
CActiveScheduler::Start();
// Free the server and active scheduler.
CleanupStack::PopAndDestroy(2, scheduler);
}
// Public functions
// Construction and destruction
CMsmmServer* CMsmmServer::NewLC()
{
LOG_STATIC_FUNC_ENTRY
CMsmmServer* self = new (ELeave) CMsmmServer(EPriorityHigh);
CleanupStack::PushL(self);
// Create a server with unique server name
self->StartL(KMsmmServerName);
self->ConstructL();
return self;
}
CMsmmServer::~CMsmmServer()
{
LOG_FUNC
delete iPolicyPlugin;
delete iEventQueue;
delete iEngine;
delete iTerminator;
REComSession::FinalClose();
#ifndef __OVER_DUMMYCOMPONENT__
iFs.RemoveProxyDrive(KPROXYDRIVENAME);
iFs.Close();
#endif
}
// CMsmmServer APIs
CSession2* CMsmmServer::NewSessionL(const TVersion& aVersion,
const RMessage2& aMessage) const
{
LOG_FUNC
if (KMaxClientCount <= SessionNumber())
{
// There is a connection to MSMM server already.
// Currently design of MSMM allows only one activated client
// at any time.
User::Leave(KErrInUse);
}
// Check the client-side API version number against the server version
// number.
TVersion serverVersion(KMsmmServMajorVersionNumber,
KMsmmServMinorVersionNumber, KMsmmServBuildVersionNumber);
if (!User::QueryVersionSupported(serverVersion, aVersion))
{
// Server version incompatible with client-side API
PanicClient(aMessage, ENoSupportedVersion);
User::Leave(KErrNotSupported);
}
// Version number is OK - create the session
return CMsmmSession::NewL(*(const_cast<CMsmmServer*>(this)), *iEventQueue);
}
TInt CMsmmServer::SessionNumber() const
{
LOG_FUNC
return iNumSessions;
}
void CMsmmServer::AddSession()
{
LOG_FUNC
++iNumSessions;
iTerminator->Cancel();
}
void CMsmmServer::RemoveSession()
{
LOG_FUNC
--iNumSessions;
if (iNumSessions == 0)
{
// Discard all pending adding interface events from queue
// and cancel event handler if a adding events is being
// handled in it.
iEventQueue->Finalize();
iTerminator->Cancel();
iTerminator->Start();
}
}
// Private functions
// CMsmmServer Construction
CMsmmServer::CMsmmServer(TInt aPriority)
:CPolicyServer(aPriority, KMsmmServerSecurityPolicy, EUnsharableSessions)
{
LOG_FUNC
//
}
void CMsmmServer::ConstructL()
{
LOG_FUNC
iEngine = CMsmmEngine::NewL();
iEventQueue = CDeviceEventQueue::NewL(*this);
iTerminator = CMsmmTerminator::NewL(*iEventQueue);
iPolicyPlugin = CMsmmPolicyPluginBase::NewL();
if (!iPolicyPlugin)
{
// Not any policy plugin implementation available
PanicServer(ENoPolicyPlugin);
}
// Initalize RFs connection and add the ELOCAL file system to file server
User::LeaveIfError(iFs.Connect());
#ifndef __OVER_DUMMYCOMPONENT__
TInt ret(KErrNone);
ret = iFs.AddProxyDrive(KFSEXTNAME);
if ((KErrNone != ret) && (KErrAlreadyExists != ret))
{
User::Leave(ret);
}
#endif
// Start automatic shutdown timer
iTerminator->Start();
}
// End of file