diff -r 000000000000 -r 4e1aa6a622a0 resourcemgmt/hwresourcesmgr/server/src/HWRMPluginHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resourcemgmt/hwresourcesmgr/server/src/HWRMPluginHandler.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,420 @@ +// Copyright (c) 2006-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: +// + + + + +// INCLUDE FILES +#include +#include "HWRMPluginHandler.h" +#include "HWRMClientServer.h" +#include "HWRMService.h" +#include "HWRMtrace.h" + + +// EXTERNAL DATA STRUCTURES +// None + +// EXTERNAL FUNCTION PROTOTYPES +// None + +// CONSTANTS +// None + +// MACROS +// None + +// LOCAL CONSTANTS AND MACROS +_LIT( KPanicCategory, "HWRMPluginHandler" ); + +// MODULE DATA STRUCTURES +// None + +// LOCAL FUNCTION PROTOTYPES +// None + +// FORWARD DECLARATIONS +// None + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::CHWRMPluginHandler +// C++ constructor +// ----------------------------------------------------------------------------- +// +CHWRMPluginHandler::CHWRMPluginHandler(TInt aRequestTimeout) + : iPlugin(NULL), + iTransIdCounter(0), + iTransactionList(NULL), + iPluginTimer(NULL), + iRequestTimeout(aRequestTimeout) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CHWRMPluginHandler()" )); + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CHWRMPluginHandler - return " )); + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::ConstructL +// 2nd phase constructor gets plugin instance. +// ----------------------------------------------------------------------------- +// +void CHWRMPluginHandler::ConstructL(const TDesC8& aMatch) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::ConstructL()" )); + + // get plugin instance + iPlugin = CHWRMPluginService::NewL(aMatch, this); + iTransactionList = CHWRMPluginTransactionList::NewL(); + iPluginTimer = CHWRMGenericTimer::NewL(*this, iRequestTimeout, 0); + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::ConstructL - return" )); + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CHWRMPluginHandler* CHWRMPluginHandler::NewL(const TDesC8& aMatch, TInt aRequestTimeout) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::NewL()" ) ); + + CHWRMPluginHandler* self = new( ELeave ) CHWRMPluginHandler(aRequestTimeout); + + CleanupStack::PushL( self ); + self->ConstructL(aMatch); + CleanupStack::Pop(); + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::NewL - return 0x%x" ), self ); + + return self; + } + +// --------------------------------------------------------- +// Destructor +// --------------------------------------------------------- +// +CHWRMPluginHandler::~CHWRMPluginHandler() + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::~CHWRMPluginHandler()" ) ); + + delete iPluginTimer; + + if ( iPlugin ) + { + // Cancel any ongoing requests + while ( iTransactionList->GetFirstItem() ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::~CHWRMPluginHandler - Canceling transaction %d" ), iTransactionList->GetFirstItem()->iTransId ); + TRAPD(err, CancelCommandL(iTransactionList->GetFirstItem()->iTransId)); + if ( err != KErrNone ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::~CHWRMPluginHandler - Canceling transaction %d failed" ), iTransactionList->GetFirstItem()->iTransId ); + } + } + + delete iPlugin; + iPlugin = NULL; + } + + // delete transaction list + delete iTransactionList; + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::~CHWRMPluginHandler - return " )); + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::ProcessCommandL +// Handles plugin requests from sessions. +// Only one concurrent request is supported. +// ----------------------------------------------------------------------------- +// +TUint8 CHWRMPluginHandler::ProcessCommandL( TInt aCommandId, + TDesC8& aData, + CHWRMService* aCompletionCallback ) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMPluginHandler::ProcessCommandL(0x%x, , 0x%x)" ), aCommandId, aCompletionCallback ); + + __ASSERT_ALWAYS(iPlugin, User::Panic(KPanicCategory, EPanicBadHandle)); + + // Generate new transaction ID. + iTransIdCounter++; + if ( iTransIdCounter == 0 ) + { + // Counter will overflow back to zero when it hits max. + // However, zero indicates completed transaction as return value, so + // increase counter again. + iTransIdCounter++; + } + + // If we run out of transIds, return server is busy. + if ( iTransactionList->FindTransaction(iTransIdCounter, EFalse) ) + { + User::Leave(KErrServerBusy); + } + + // Create transaction data before call in case it leaves + TTime obsoletionTime; + obsoletionTime.UniversalTime(); + obsoletionTime += iRequestTimeout; + THWRMTransactionData* data = new(ELeave) THWRMTransactionData(aCompletionCallback, iTransIdCounter, aCommandId, obsoletionTime); + + // Push transaction data to cleanup stack so that it will clean out if ProcessCommandL leaves. + CleanupStack::PushL( data ); + + iPlugin->ProcessCommandL( aCommandId, data->iTransId, aData ); + + TUint8 retval(0); + + // data still needed, do not destroy, just pop + CleanupStack::Pop( data ); + + // Add data to list + iTransactionList->AddTransaction( data ); + + retval = data->iTransId; + + // Start timer if it is not already started + if ( !iPluginTimer->IsActive()) + { + iPluginTimer->Set(iRequestTimeout); + } + + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::ProcessCommandL - return 0x%x" ), retval ); + + return retval; + + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::CancelCommandL +// Cancels the currently executing request +// ----------------------------------------------------------------------------- +// +void CHWRMPluginHandler::CancelCommandL( TUint8 aTransId ) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CancelCommandL()" )); + + __ASSERT_ALWAYS(iPlugin, User::Panic(KPanicCategory, EPanicBadHandle)); + + // Find correct transaction data and remove it from list + THWRMTransactionData* data = static_cast(iTransactionList->FindTransaction(aTransId, ETrue)); + + // cancel request timer if no more transactions open + if ( iTransactionList->Count() == 0 ) + { + iPluginTimer->Cancel(); + } + + // If transaction is not open, do nothing + // Do not cancel if request has no callback (i.e. final destructor state restorings) + // (these are canceled by timeout if they do not complete successfully) + if ( data && data->iCompletionCallback ) + { + CleanupStack::PushL( data ); + + iPlugin->CancelCommandL( data->iTransId, data->iCommandId ); + + // Destroy the transaction data, since transaction is over. + CleanupStack::PopAndDestroy( data ); + data = NULL; + } + else + { + TTime now; + now.UniversalTime(); + if ( data && data->iObsoletionTime >= now ) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CancelCommandL - Not cancelled because no callback" ) ); + + // Push data back to list + iTransactionList->AddTransaction( data ); + } + else + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CancelCommandL - Cancelled because command was obsolete" ) ); + } + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::CancelCommandL - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::ProcessResponseL +// Routes response from plugin to correct service instance +// ----------------------------------------------------------------------------- +// +void CHWRMPluginHandler::ProcessResponseL( TInt aCommandId, + TUint8 aTransId, + TDesC8& aData ) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMPluginHandler::ProcessResponseL(0x%x, 0x%x, )" ), aCommandId, aTransId ); + + // Find and remove correct transaction data and remove it from queue + THWRMTransactionData* data = static_cast(iTransactionList->FindTransaction(aTransId, ETrue)); + + // cancel request timer if no more transactions open + if ( iTransactionList->Count() == 0 ) + { + iPluginTimer->Cancel(); + } + + // If transaction is not open, response not expected. + if ( data ) + { + CleanupStack::PushL( data ); + + // Check that command ID is the expected one + if ( data->iCommandId != aCommandId ) + { + COMPONENT_TRACE3(_L( "HWRM Server - CHWRMPluginHandler::ProcessResponseL - Command ID mismatch, expected: 0x%x, got 0x%x" ), data->iCommandId, aCommandId ); + User::Leave(KErrBadHandle); + } + + // Route data to callback service if one is needed + if ( data->iCompletionCallback ) + { + data->iCompletionCallback->ProcessResponseL(aCommandId, aTransId, aData, EFalse); + } + + CleanupStack::PopAndDestroy( data ); + data = NULL; + } + else + { + // There is problem in adaptation, as unexpected transaction was completed. + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::ProcessResponseL - No transaction data found!" ) ); + User::Leave(KErrBadHandle); + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::ProcessResponseL - return" ) ); + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::EventL +// Routes indication from plugin to correct indication handler +// ----------------------------------------------------------------------------- +// +void CHWRMPluginHandler::EventL( const TUint32 aIndId, TDesC8& aData ) + { + COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::EventL(), Count() = %d" ), iIndicationCallbacks.Count() ); + + for (TUint i=0; iProcessIndicationL(aIndId, aData); + } + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::RegisterForIndications +// Registers a handler for receiving HWRM plug-in indications +// ----------------------------------------------------------------------------- +// +void CHWRMPluginHandler::RegisterForIndications(MHWRMIndicationHandler* aCallback) + { + COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::RegisterForIndications(), Count() = %d" ), iIndicationCallbacks.Count() ); + + iIndicationCallbacks.Append(aCallback); + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::DeregisterForIndications +// Deregisters handlers for receiving HWRM plug-in indications +// ----------------------------------------------------------------------------- +// +void CHWRMPluginHandler::DeregisterForIndications(MHWRMIndicationHandler* aCallback) + { + COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::DeregisterForIndications(), Count() = %d" ), iIndicationCallbacks.Count() ); + + TInt findErr = iIndicationCallbacks.Find(aCallback); + COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::DeregisterForIndications(), findErr = %d" ), findErr ); + + if ( findErr != KErrNotFound ) + { + iIndicationCallbacks.Remove(findErr); + COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::DeregisterForIndications(), item removed, Count() = %d" ), iIndicationCallbacks.Count() ); + } + } + +// ----------------------------------------------------------------------------- +// CHWRMPluginHandler::GenericTimerFired +// Cancels all obsolete transactions. TimerId is irrelevant as only one timer. +// ----------------------------------------------------------------------------- +// +void CHWRMPluginHandler::GenericTimerFired(TInt /*aTimerId*/, TBool /*aCutOff*/) + { + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired()" ) ); + + __ASSERT_ALWAYS(iPlugin, User::Panic(KPanicCategory, EPanicBadHandle)); + + // Since requests are added to end of list always, they are in order of obsolescense. + // Cancel requests that are obsolete and notify callback service + TInt err(KErrNone); + TTime now; + now.UniversalTime(); + THWRMTransactionData* data = static_cast(iTransactionList->GetFirstItem()); + + while ( data && ( data->iObsoletionTime < now ) ) + { + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired - Canceling obsolete transaction 0x%x" ), data->iTransId ); + + // Cancel transaction. + TRAP(err, iPlugin->CancelCommandL( data->iTransId, data->iCommandId )); + if ( err != KErrNone ) + { + // Ignore errors as we cannot do anything about it anyway. Just trace. + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired - Canceling obsolete transaction FAILED (%d)!" ), err ); + } + + // Notify service that request was canceled by timeout + if ( data->iCompletionCallback ) + { + TBuf8<1> emptyDes; + TRAP(err, data->iCompletionCallback->ProcessResponseL(data->iCommandId, data->iTransId, emptyDes, ETrue)); + if ( err != KErrNone ) + { + // Ignore errors as we cannot do anything about it anyway. Just trace. + COMPONENT_TRACE2(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired - Notifying obsolete transaction cancel FAILED (%d)!" ), err ); + } + } + + // Destroy the transaction data, since transaction is over. + iTransactionList->RemoveFirstItem(); + delete data; + data = NULL; + + // get next data to check + data = static_cast(iTransactionList->GetFirstItem()); + } + + // Restart timer if there is more transactions in list + if ( data ) + { + iPluginTimer->Set(iRequestTimeout); + } + + COMPONENT_TRACE1(_L( "HWRM Server - CHWRMPluginHandler::GenericTimerFired - return" ) ); + } + + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File