resourcemgmt/hwresourcesmgr/server/src/HWRMPluginHandler.cpp
changeset 0 4e1aa6a622a0
child 20 1ddbe54d0645
--- /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 <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