realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileCSServer.cpp
changeset 0 307788aac0a8
--- /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);
+    }