upnp/upnpstack/serviceframework/src/upnpeventcontroller.cpp
changeset 0 f5a58ecadc66
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnp/upnpstack/serviceframework/src/upnpeventcontroller.cpp	Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,355 @@
+/** @file
+* Copyright (c) 2008-2008 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:  Encapsulates http client for eventing
+*
+*/
+
+
+
+#include <e32base.h>
+
+#include "upnpsettings.h"
+#include "upnpeventcontroller.h"
+#include "upnpgenamessagefactory.h"
+#include "upnphttpmessagefactory.h"
+#include "upnphttpinitialeventtransaction.h"
+#include "upnpnonmoderatedeventqueuemanager.h"
+#include "upnpmoderatedeventqueuemanager.h"
+#include "upnpinitialeventqueuemanager.h"
+#include "upnpdeviceimplementationbase.h"
+#include "upnpcommonupnplits.h"
+
+#define KLogFile _L("UPnPStack.txt")
+#include "upnpcustomlog.h"
+  
+  
+// -----------------------------------------------------------------------------
+// CUpnpEventController::CUpnpEventController
+// Default C++ constructor
+// -----------------------------------------------------------------------------
+//  
+CUpnpEventController::CUpnpEventController( CUpnpServiceImplementation& aServiceImpl )
+    :iServiceImpl( aServiceImpl )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::CUpnpEventController
+// Destructor
+// -----------------------------------------------------------------------------
+//  
+CUpnpEventController::~CUpnpEventController()
+    {
+    iPendingTransactions.ResetAndDestroy();
+    delete iModQueue;
+    delete iNonModQueue;
+    delete iInitialEventQueue;
+    delete iSubscriberLibrary;
+    delete iHttpEngine;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::NewLC
+// Two phased constructor
+// -----------------------------------------------------------------------------
+//  
+CUpnpEventController* CUpnpEventController::NewLC( CUpnpServiceImplementation& aServiceImpl )
+    {
+    CUpnpEventController* self = new (ELeave) CUpnpEventController( aServiceImpl );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::NewL
+// Two phased constructor
+// -----------------------------------------------------------------------------
+//  
+CUpnpEventController* CUpnpEventController::NewL( CUpnpServiceImplementation& aServiceImpl )
+    {
+    CUpnpEventController* self=CUpnpEventController::NewLC( aServiceImpl );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::ConstructL
+// Two phased constructor
+// -----------------------------------------------------------------------------
+//  
+void CUpnpEventController::ConstructL()
+    {
+    iSubscriberLibrary = CUpnpSubscriberLibrary::NewL( *this );
+    iHttpEngine = CUpnpHttpClientEngine::NewL( *this, CUpnpSettings::GetIapL() );
+    iNonModQueue = CUpnpNonModeratedEventQueueManager::NewL( iServiceImpl , *this, iSubscriberLibrary );
+    iModQueue =  CUpnpModeratedEventQueueManager::NewL(  iServiceImpl , *this, iSubscriberLibrary );
+    iInitialEventQueue = CUpnpInitialEventQueueManager::NewL(  iServiceImpl , *this, iSubscriberLibrary );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::SendInitialNotification
+// Sends initial event
+// -----------------------------------------------------------------------------
+//  
+void CUpnpEventController::SendInitialNotification( )
+    {
+    iInitialEventQueue->SendEvent();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::SendNonModeratedNotification
+// Sends not-moderated events
+// -----------------------------------------------------------------------------
+//  
+void CUpnpEventController::SendNonModeratedNotification( )
+    {
+    iNonModQueue->SendEvent();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::SendModeratedNotification
+// Sends moderated event
+// -----------------------------------------------------------------------------
+//  
+void CUpnpEventController::SendModeratedNotification(  )
+    {
+    iModQueue->SendEvent();
+    }
+    
+// -----------------------------------------------------------------------------
+// CUpnpEventController::SendTransactionL
+// Sends event to subscriber
+// -----------------------------------------------------------------------------
+//  
+void  CUpnpEventController::SendTransactionL( CUpnpHttpTransaction* aTransaction )
+    {
+    CleanupStack::PushL( aTransaction );
+    iPendingTransactions.AppendL( aTransaction );
+    CleanupStack::Pop( aTransaction );
+    
+    iHttpEngine->SendL( *aTransaction );
+    }
+ 
+// -----------------------------------------------------------------------------
+// CUpnpEventController::SubscribeL
+// Proccess subscribe message
+// -----------------------------------------------------------------------------
+//  
+void CUpnpEventController::SubscribeL( CUpnpGenaMessage* aMessage )
+    {
+    TInt subscribers = iSubscriberLibrary->SubscriberLibrary().Count();
+        
+    CUpnpSubscriberLibraryElement* subscriber( NULL );
+    TUpnpErrorCode subscriptionState 
+        = iSubscriberLibrary->AddInfoL( aMessage, &subscriber );
+
+    // Responding:
+    if ( subscriber && subscriptionState == EHttpOk )
+        {
+        // for a new subscriber: SID generation
+        if ( subscribers < iSubscriberLibrary->SubscriberLibrary().Count() )
+            {
+            GenerateSidL( subscriber );
+            }
+            
+        HBufC8* timeout( TimerHeaderLC( subscriber->Timeout() ) );
+        
+        CUpnpHttpMessage* messageOut = reinterpret_cast<CUpnpHttpMessage*>(
+                                    RUpnpGenaMessageFactory::SubscribeResponseL(
+                                                    aMessage->SessionId(), 
+                                                    aMessage->Sender(), 
+                                                    subscriber->Sid(), 
+                                                    timeout->Des() )
+                                                                            );
+        CleanupStack::PopAndDestroy( timeout );                    
+        timeout = NULL;
+        CleanupStack::PushL( messageOut );
+
+        iServiceImpl.SendL( messageOut );
+
+        CleanupStack::PopAndDestroy( messageOut );
+        messageOut = NULL;
+        
+            
+        // for a new subscriber: initial event message
+        if ( subscribers < iSubscriberLibrary->SubscriberLibrary().Count() )
+            {
+            SendInitialNotification( );
+            }
+        }
+    else
+        {       
+        CUpnpHttpMessage* messageOut = RUpnpHttpMessageFactory::UpnpResponseErrorL( 
+                                                                aMessage, 
+                                                                subscriptionState 
+                                                                                  );
+        CleanupStack::PushL( messageOut );
+        iServiceImpl.SendL( messageOut );
+        CleanupStack::PopAndDestroy( messageOut );
+        }       
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::UnSubscribeL
+// Proccess unsubscribe message
+// -----------------------------------------------------------------------------
+//  
+void CUpnpEventController::UnSubscribeL( CUpnpGenaMessage* aMessage )
+    {
+    TUpnpErrorCode subscriptionState( CheckHeaders( aMessage ) );
+
+    if ( subscriptionState == EUndefined )
+        {
+        subscriptionState = iSubscriberLibrary->Remove( aMessage->Sid() );
+        } 
+    
+    if ( subscriptionState == EHttpOk )
+        {
+        CUpnpHttpMessage* messageOut = reinterpret_cast<CUpnpHttpMessage*>(
+                RUpnpGenaMessageFactory::UnsubscribeResponseL( aMessage->SessionId(), 
+                                                               aMessage->Sender() ) 
+                                                                           );
+        CleanupStack::PushL( messageOut );        
+        iServiceImpl.SendL( messageOut );
+        CleanupStack::PopAndDestroy( messageOut );   
+        }
+    else
+        {
+        CUpnpHttpMessage* messageOut = RUpnpHttpMessageFactory::UpnpResponseErrorL( 
+                                                                    aMessage,
+                                                                    subscriptionState
+                                                                                   );
+        CleanupStack::PushL( messageOut );
+        iServiceImpl.SendL( messageOut );
+        CleanupStack::PopAndDestroy( messageOut );
+        }
+    } 
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::CancelInvalidSessions
+// Cancels not completed transaction 
+// -----------------------------------------------------------------------------
+// 
+void CUpnpEventController::CancelInvalidSessions( const TDesC8& aSid )
+    {
+    for ( TInt i(0) ; i < iPendingTransactions.Count() ; i++ )
+        {
+        if ( static_cast<CUpnpGenaMessage*>( iPendingTransactions[i]->Request() )->Sid().Compare( aSid ) == 0 )
+            {         
+            iHttpEngine->Cancel( *iPendingTransactions[i] );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::SubscribersAmount
+// Returns number of subscribers 
+// -----------------------------------------------------------------------------
+// 
+TInt CUpnpEventController::SubscribersAmount()
+    {
+    return iSubscriberLibrary->SubscriberLibrary().Count();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::CheckHeader
+// Check if unsubscribe header are comlete 
+// -----------------------------------------------------------------------------
+// 
+TUpnpErrorCode CUpnpEventController::CheckHeaders( CUpnpGenaMessage* aMessage )
+    {
+    TUpnpErrorCode subscriptionState( EUndefined );
+
+    // Errors: Incompatible headers
+    if ( aMessage->Sid().Compare( KNoHeader) != 0 )
+        {
+        if ( aMessage->Nt().Compare( KNoHeader) != 0 )
+            {
+            subscriptionState = EBadRequest;
+            }
+        else if (aMessage->Callback().Compare( KNoHeader ) != 0 )
+            {
+            subscriptionState = EBadRequest;
+            }
+        else
+            {
+            }
+        }
+    return subscriptionState;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::GenerateSidL
+// Genereated uuid for a subscriber 
+// -----------------------------------------------------------------------------
+// 
+void CUpnpEventController::GenerateSidL( CUpnpSubscriberLibraryElement* aSubscriber )
+    {
+    HBufC8* uuid = iServiceImpl.DeviceImpl().GenerateUuidL();
+    CleanupStack::PushL( uuid );
+    aSubscriber->SetSidL( *uuid );
+    CleanupStack::PopAndDestroy( uuid );
+    LOGS("  new subscriber:");
+    }
+// -----------------------------------------------------------------------------
+// CUpnpEventController::SubscribersAmount
+// Returns evented state variables
+// -----------------------------------------------------------------------------
+//    
+RPointerArray<CUpnpStateVariable>& CUpnpEventController::EventedStateVariables()
+    {
+    return iServiceImpl.EventedStateVariables();
+    }
+   
+// -----------------------------------------------------------------------------
+// CUpnpEventController::SubscriberRemoved
+// Resumes processing when subscriber  has been removed
+// -----------------------------------------------------------------------------
+//    
+void CUpnpEventController::SubscriberRemoved( CUpnpSubscriberLibraryElement* aSubscriber , TInt aPos )
+    {
+    CancelInvalidSessions( aSubscriber->Sid() );
+    
+    iNonModQueue->UpdateQueue( aPos );
+    iModQueue->UpdateQueue( aPos );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpEventController::TimerHeaderLC
+// Creates timeout header
+// -----------------------------------------------------------------------------
+//    
+HBufC8* CUpnpEventController::TimerHeaderLC( const TDesC8& aTimeout )
+    {
+    HBufC8* timeout= HBufC8::NewLC( aTimeout.Length() + KTimeoutPrefix().Length() );
+    timeout->Des().Zero();
+    timeout->Des().Append( KTimeoutPrefix );
+    timeout->Des().Append( aTimeout );
+    return timeout;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpEventController::ClientResponseRecivedLD
+// Handles event response
+// -----------------------------------------------------------------------------
+//          
+void CUpnpEventController::ClientResponseRecivedLD( CUpnpHttpTransaction& aEndedTransaction )
+{
+    TInt idx( iPendingTransactions.Find( &aEndedTransaction ) );
+    ASSERT( idx >= 0 ); //it should never happen that we received transaction that wasn't sent by us
+    iPendingTransactions.Remove( idx );
+    aEndedTransaction.ProcessResponseL();
+    delete ( &aEndedTransaction );
+}
+//end of file