--- /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<CSIPProfileCSServer*>(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);
+ }