diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/serviceframework/src/upnpeventcontroller.cpp --- /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 + +#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( + 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( + 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( 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& 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