// 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 <ecom/ecom.h>#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(<aMatch>)" )); // 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(<aMatch>)" ) ); 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, <aData>, 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<THWRMTransactionData*>(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, <aData> )" ), aCommandId, aTransId ); // Find and remove correct transaction data and remove it from queue THWRMTransactionData* data = static_cast<THWRMTransactionData*>(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; i<iIndicationCallbacks.Count(); i++) { MHWRMIndicationHandler* pHandler = iIndicationCallbacks[i]; COMPONENT_TRACE2( _L( "HWRM Server - CHWRMPluginHandler::EventL(), callback %d" ), i ); pHandler->ProcessIndicationL(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<THWRMTransactionData*>(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<THWRMTransactionData*>(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