diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCSServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCSServer.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,327 @@ +// Copyright (c) 2007-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: +// Name : SIPProfileCSServer.cpp +// Part of : SIP Profile Server +// implementation +// Version : 1.0 +// + + + +// INCLUDE FILES +#include "SipProfileActiveScheduler.h" +#include "SipProfileCSServer.h" +#include "SipProfileCSSession.h" +#include "SipProfileCSServer.pan" +#include "SipProfileCSServerCloseTimer.h" +#include "SipProfileSecurityPolicy.h" +#include "SipProfileLog.h" + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::NewL +// ----------------------------------------------------------------------------- +// +CSIPProfileCSServer* +CSIPProfileCSServer::NewL(CSIPProfileServerCore& aServerCore) + { + CSIPProfileCSServer* self = CSIPProfileCSServer::NewLC(aServerCore); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::NewLC +// ----------------------------------------------------------------------------- +// +CSIPProfileCSServer* +CSIPProfileCSServer::NewLC(CSIPProfileServerCore& aServerCore) + { + CSIPProfileCSServer* self = + new (ELeave) CSIPProfileCSServer(aServerCore,EPriorityHigh); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::ConstructL +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::ConstructL() + { + const TUint KSIPProfileServerTimerValue = 5; + StartL(KSipProfileServerName); + if (iServerCore.CanServerStop()) + { + PROFILE_DEBUG1("ProfileServer shutdown timer started") + iCloseTimer = CSipProfileCSServerCloseTimer::NewL(); + iCloseTimer->StopActiveSchedulerAfter(KSIPProfileServerTimerValue); + } + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::CSIPProfileCSServer +// ----------------------------------------------------------------------------- +// +CSIPProfileCSServer::CSIPProfileCSServer( + CSIPProfileServerCore& aServerCore, + TInt aPriority) + : CPolicyServer(aPriority, TSipProfilePlatSecPolicy), + iServerCore(aServerCore) + { + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::~CSIPProfileCSServer +// ----------------------------------------------------------------------------- +// +CSIPProfileCSServer::~CSIPProfileCSServer() + { + delete iCloseTimer; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::NewSessionL +// ----------------------------------------------------------------------------- +// +CSession2* CSIPProfileCSServer::NewSessionL(const TVersion &aVersion, + const RMessage2& /*aMessage*/) const + { + PROFILE_DEBUG1("CSIPProfileCSServer::NewSessionL") + + // Check we're the right version + if (!User::QueryVersionSupported( + TVersion(KSipProfileServerMajorVersionNumber, + KSipProfileServerMinorVersionNumber, + KSipProfileServerBuildVersionNumber), + aVersion)) + { + User::Leave(KErrNotSupported); + } + + if (iServerCore.BackupInProgress()) + { + User::Leave(KErrLocked); + } + + PROFILE_DEBUG1("CSIPProfileCSServer::NewSessionL, exit") + return CSIPProfileCSSession::NewL(*const_cast(this), + iServerCore); + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::IncrementSessions +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::IncrementSessions() + { + iSessionCount++; + if (iCloseTimer) + { + PROFILE_DEBUG1("ProfileServer shutdown timer stopped") + delete iCloseTimer; + iCloseTimer = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::DecrementSessions +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::DecrementSessions() + { + iSessionCount--; + + if (iSessionCount == 0 && iServerCore.CanServerStop()) + { + CActiveScheduler::Stop(); + } + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::ServerCanStop +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::ServerCanStop() + { + if (iSessionCount == 0) + { + CActiveScheduler::Stop(); + } + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSSession::ShutdownL +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::ShutdownL() + { + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSSession::CleanShutdownL +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::CleanShutdownL() + { + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::RunError +// ----------------------------------------------------------------------------- +// +TInt CSIPProfileCSServer::RunError(TInt aError) + { + Message().Complete(aError); + // The leave will result in an early return from CServer::RunL(), skipping + // the call to request another message. So do that now in order to keep the + // server running. + ReStart(); + return KErrNone; // handled the error fully + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::PanicClient +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::PanicClient(const RMessage2& aMessage, + TSIPProfileCSPanic aPanic) + { + aMessage.Panic(KSipProfileCSServerPanic, aPanic); + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::PanicServer +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::PanicServer(TSIPProfileCSPanic aPanic) + { + User::Panic(KSipProfileCSServerPanic, aPanic); + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::ThreadFunctionL +// ----------------------------------------------------------------------------- +// +void CSIPProfileCSServer::ThreadFunctionL(RMutex& aMutex) + { + // Give a name to this thread + User::LeaveIfError(User::RenameThread(KSipProfileServerName)); + + // Construct our server + CActiveScheduler* activeScheduler = new (ELeave) CSIPProfileActiveScheduler; + CActiveScheduler::Install(activeScheduler); + CleanupStack::PushL(activeScheduler); + CSIPProfileServerCore::NewLC(); + if (SignalClientSemaphore() == KErrNone) + { + // Semaphore signalled ok + PROFILE_DEBUG1("Start initiated by client") + } + else + { + PROFILE_DEBUG1("Start initiated by non-client") + // Server started by non-client. No need to signal. + } + aMutex.Signal(); + aMutex.Close(); + + // Start handling requests + CActiveScheduler::Start(); + + // This will be executed after the active scheduler has been stopped: + CleanupStack::PopAndDestroy(2); // server, activeScheduler + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::ThreadFunction +// ----------------------------------------------------------------------------- +// +TInt CSIPProfileCSServer::ThreadFunction(TAny* /*aNone*/) + { + _LIT(KSipProfileServerMutexName, "SipProfileServerMutex"); + + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + if (!cleanupStack) + { + PanicServer(ECreateTrapCleanup); + } + + // Protect server starting code with a mutex. + RMutex mutex; + TInt err = mutex.CreateGlobal(KSipProfileServerMutexName); + if (err != KErrNone) + { + err = mutex.OpenGlobal(KSipProfileServerMutexName); + if (err != KErrNone) + { + delete cleanupStack; + PanicServer(ESrvCreateServer); + return err; // silence warnings + } + } + mutex.Wait(); // Wait here until nobody else executes the code below. + + TFindServer findServer(KSipProfileServerName); + TFullName name; + if (findServer.Next(name) == KErrNone) + { + // Server already running. + SignalClientSemaphore(); + mutex.Signal(); + mutex.Close(); + } + else + { + // Server not running. Try to start it. + TRAP(err, ThreadFunctionL(mutex)); + if (err != KErrNone) + { + SignalClientSemaphore(); + mutex.Signal(); + mutex.Close(); + } + } + + delete cleanupStack; + return err; + } + +// ----------------------------------------------------------------------------- +// CSIPProfileCSServer::SignalClientSemaphore +// ----------------------------------------------------------------------------- +// +TInt CSIPProfileCSServer::SignalClientSemaphore() + { + RSemaphore semaphore; + TInt err = semaphore.OpenGlobal(KSipProfileServerSemaphoreName); + if (err == KErrNone) + { + semaphore.Signal(); + semaphore.Close(); + } + return err; + } + +// ----------------------------------------------------------------------------- +// E32Main +// ----------------------------------------------------------------------------- +// +TInt E32Main() + { + PROFILE_DEBUG1("Process created") + return CSIPProfileCSServer::ThreadFunction(NULL); + }