upnp/upnpstack/upnputils/src/upnpsymbianserverbase.cpp
changeset 0 f5a58ecadc66
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnp/upnpstack/upnputils/src/upnpsymbianserverbase.cpp	Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,275 @@
+/** @file
+ * Copyright (c) 2005-2006 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:  Implementation of CUpnpSymbianServerBase
+ *
+ */
+
+#include <upnpsymbianserverbase.h>
+#include "upnpuheapmark.h"
+#include "upnpcustomlog.h"
+
+#include <ecom/ecom.h>
+
+const TInt KUpnpSymbianServerShutdownInterval = 2000000;
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::StartServerL
+// Create and start the server.
+// -----------------------------------------------------------------------------
+//
+void CUpnpSymbianServerBase::StartServerL( const TDesC& aThreadName,
+    TServerFactoryMethodLC aServerFactoryMethodLC )
+    {
+    User::LeaveIfError( User::RenameThread( aThreadName ) );
+    // Construct active scheduler
+    CActiveScheduler* activeScheduler = new( ELeave ) CActiveScheduler;
+    CleanupStack::PushL( activeScheduler );
+
+    // Install active scheduler
+    // We don't need to check whether an active scheduler is already installed
+    // as this is a new thread, so there won't be one
+    CActiveScheduler::Install( activeScheduler );
+
+    // Construct our server
+    CUpnpSymbianServerBase* serverObject = aServerFactoryMethodLC();
+    LOGS( "UpnpSymbianServer *** Ready to accept connections" );
+
+    RProcess::Rendezvous( KErrNone );
+
+    // Start handling requests
+    CActiveScheduler::Start();
+
+    LOGS( "UpnpSymbianServer *** Active scheduler stopped" );
+    LOGS( "UpnpSymbianServer *** Prepared for shutdown" );
+
+    CleanupStack::PopAndDestroy( serverObject );
+    REComSession::FinalClose();
+    CleanupStack::PopAndDestroy( activeScheduler );
+    LOGS( "UpnpSymbianServer *** Shutdown complete" );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::StartServer
+// Create and start the server.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CUpnpSymbianServerBase::StartServer( const TDesC& aThreadName,
+        TServerFactoryMethodLC aServerFactoryMethodLC )
+    {
+    __UPNP_UHEAP_MARK;
+
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    if ( !( cleanupStack ) )
+        {
+        User::Panic( aThreadName, ECreateTrapCleanup );
+        }
+
+    TRAPD( err, StartServerL( aThreadName, aServerFactoryMethodLC) );
+    if ( err != KErrNone )
+        {
+        //there's no need to panic server
+        //f.e. KErrAlreadyExist is valid in case of simultanous start
+        }
+
+    delete cleanupStack;
+    cleanupStack = NULL;
+
+    __UPNP_UHEAP_MARKEND;
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::CUpnpSymbianServerBase
+// Constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CUpnpSymbianServerBase::CUpnpSymbianServerBase()
+: CServer2( EPriorityNormal )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::~CUpnpSymbianServerBase
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CUpnpSymbianServerBase::~CUpnpSymbianServerBase()
+    {
+    delete iShutdownTimer;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::BaseConstructL
+// Second phase base constructor. It must be called by derived class.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpSymbianServerBase::BaseConstructL()
+    {
+    StartL( ServerName() );
+    iShutdownTimer = CUpnpNotifyTimer::NewL( this );
+    SuggestShutdown();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::PanicClient
+// Panic client.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpSymbianServerBase::PanicClient(
+        const RMessage2& aMessage, TInt aPanic ) const
+    {
+    LOG_FUNC_NAME;
+    aMessage.Panic( ServerName(), aPanic );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::PanicServer
+// Panic server.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpSymbianServerBase::PanicServer( TInt aPanic ) const
+    {
+    User::Panic( ServerName(), aPanic );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::IncrementSessionCount
+// Increment sessions.
+// -----------------------------------------------------------------------------
+//
+void CUpnpSymbianServerBase::IncrementSessionCount()
+    {
+    LOG_FUNC_NAME;
+    iSessionCount++;
+    iShutdownTimer->Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::DecrementSessions
+// Decrement sessions.
+// -----------------------------------------------------------------------------
+//
+void CUpnpSymbianServerBase::DecrementSessionCount()
+    {
+    LOG_FUNC_NAME;
+    iSessionCount--;
+    ASSERT( iSessionCount >= 0 );
+    SuggestShutdown();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::SuggestShutdown
+// Checks every stop condidion and starts closing server timeout if all of them
+// are fulfilled.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpSymbianServerBase::SuggestShutdown()
+    {
+    if ( (iSessionCount <= 0) && CanBeStopped() )
+        {
+        iShutdownTimer->Start( KUpnpSymbianServerShutdownInterval );
+        }
+    }
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::TimerEventL
+// End of shutdown timer event
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpSymbianServerBase::TimerEventL( CUpnpNotifyTimer* aTimer )
+    {
+    ASSERT( iShutdownTimer == aTimer );
+    ASSERT( (iSessionCount <= 0) && CanBeStopped() );
+    CActiveScheduler::Stop();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::RunL
+// Invoked when server receives message.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpSymbianServerBase::RunL()
+    {
+    switch( Message().Function() )
+        {
+        case RMessage2::EConnect:
+        IncrementSessionCount();
+        break;
+        case RMessage2::EDisConnect:
+        DecrementSessionCount();
+        break;
+        }
+    CServer2::RunL();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::RunError
+// RunError is called when RunL leaves.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CUpnpSymbianServerBase::RunError( TInt aError )
+    {
+    LOG_FUNC_NAME;
+    if ( aError == KErrBadDescriptor )
+        {
+        // A bad descriptor error implies a badly programmed client, so panic it;
+        // otherwise report the error to the client
+        LOGS( "RunError - BadClient" );
+        PanicClient( Message(), EBadDescriptor );
+        }
+    else if ( aError != KErrCorrupt )
+        {
+        LOGS( "RunError - Faulty Message" );
+        if ( !Message().IsNull() )
+            {
+            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();
+
+    // Handled the error fully
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::NewSessionL
+// Create new session or leaves with KErrNotSupported if version is unsupported.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSession2* CUpnpSymbianServerBase::NewSessionL(
+        const TVersion& aVersion, const RMessage2& aMessage ) const
+    {
+    LOG_FUNC_NAME;
+    // Check we're the right version
+    if ( !User::QueryVersionSupported( SupportedVersion(), aVersion ) )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    return NewSessionL( aMessage );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpSymbianServerBase::CanBeStopped
+// Default implementation for transient servers - no additional stopping conditions
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CUpnpSymbianServerBase::CanBeStopped() const
+    {
+    return ETrue;
+    }
+
+// End Of File