hwrmhaptics/hapticspluginmanager/src/hwrmhapticsservice.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hwrmhaptics/hapticspluginmanager/src/hwrmhapticsservice.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,723 @@
+/*
+* Copyright (c) 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:  Haptic service implementation.
+*
+*/
+
+
+#include <s32mem.h>              // RDesReadStream
+#include <hwrmhaptics.h>
+#include <hwrmhapticsobserver.h>
+#include <hwrmlogicalactuators.h>
+#include <hwrmhapticscommands.h> // adaptation interface
+#include <hwrmhapticspacketizer.h>
+
+#include "hwrmhapticsclientserver.h" // panic codes, service ID
+#include "hwrmhapticsserver.h" // default case in ExecuteMessageL
+#include "hwrmhapticsservice.h"
+#include "hwrmhapticspluginmanager.h"
+#include "hwrmhapticsreservationhandler.h"
+#include "hwrmhapticscommondata.h"
+#include "hwrmhapticstrace.h"
+#include "hwrmhapticspluginrequestdata.h"
+
+_LIT( KPanicCategory, "HWRMHapticsSService" );
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CHWRMHapticsService* CHWRMHapticsService::NewL(
+        CHWRMHapticsPluginManager* aPluginHandler,
+        CHWRMHapticsReservationHandler* aReservationHandler,
+        CHWRMHapticsCommonData& aHapticsCommonData,
+        const RMessage2& aMessage )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::NewL()" ) ) );
+
+    CHWRMHapticsService* self = 
+        new ( ELeave ) CHWRMHapticsService( aHapticsCommonData, aMessage );
+    
+    CleanupStack::PushL( self );
+    self->ConstructL( aPluginHandler, aReservationHandler );
+    CleanupStack::Pop( self );
+
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::NewL - return 0x%x" ), self ) );
+    
+    return self;
+    }
+   
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsService::~CHWRMHapticsService()
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService()" ) ) );
+
+    // Cleanup haptics just in case regular cleanup failed
+    CleanupHaptics();
+
+    if ( iPacketizer )
+        {
+        delete iPacketizer;
+        iPacketizer = NULL;
+        }
+    
+    // Complete any pending requests
+    while ( iTransactionList->FirstItem() )
+        {
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - Deleting request %d" ), iTransactionList->FirstItem()->TransactionId() ) );
+        CHWRMHapticsPluginRequestData* data = 
+            static_cast<CHWRMHapticsPluginRequestData*>(
+                iTransactionList->RemoveFirstItem() );
+
+        if ( data->RequestMessage().Handle() )
+            {
+            // Check that this request is not first one of a split request
+            if ( !data->CommandSplit() || 
+                 !CheckForMessage(data->RequestMessage().Handle()) )
+                {
+                COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - Canceling pending message" ) ) );
+                data->RequestMessage().Complete( KErrCancel );
+                }
+            else
+                {
+                COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - Split request, not canceling message yet" ) ) );
+                }
+            }
+
+        TRAPD ( err, iPluginManager->CancelCommandL( data->TransactionId() ) );
+        
+        if ( err != KErrNone )
+            {
+            COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - Cancelling Command (transid: %d) failed: %d" ), data->TransactionId(), err ) );
+            }
+
+        delete data;
+        }
+        
+    // Destroy transaction list
+    delete iTransactionList;
+
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::~CHWRMHapticsService() - return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Handles Haptics requests. 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CHWRMHapticsService::ExecuteMessageL( 
+                                                const RMessage2& aMessage )
+    {
+    COMPONENT_TRACE( ( _L( "e_HWRMHAPTICS_SERVICE_EXECUTEMESSAGEL 1" ) ) );
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL(0x%x)" ), aMessage.Function() ) );
+    __ASSERT_ALWAYS( iPluginManager,
+                     User::Panic( KPanicCategory, EPanicBadHandle ) );
+    __ASSERT_ALWAYS( iReservationHandler,
+                     User::Panic( KPanicCategory, EPanicBadHandle ) );
+    
+    if ( aMessage.IsNull() )
+        {
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL - NULL message!" ) ) );
+        User::Leave( KErrBadHandle );
+        }
+
+    TBool completeMessage( EFalse );
+    
+    switch( aMessage.Function() )
+        {
+        case RMessage2::EDisConnect:
+            {
+            // send command to close actuator, if actuator has 
+            // been opened (i.e. packetizer exists)
+            if ( iPacketizer )
+                {
+                SendMsgToPluginManagerL( aMessage );
+                }
+
+            CleanupHaptics();
+            break;
+            }
+        case EHWRMHaptics:
+        case EHWRMHapticsBridgeCommand: // flow through
+            {
+            // send haptics message
+            SendMsgToPluginManagerL( aMessage );
+            break;
+            }
+        case EHWRMHapticsPlayEffect:
+            {
+            // check if suspended
+            if ( iSuspended )
+                {
+                // no effect playing, just complete the message
+                COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL - Haptics suspended; Play not executed." ) )  );
+                aMessage.Complete( KErrNone );
+                }
+            else if ( iReservationHandler->IsReserved( this ) &&
+                      iReservationHandler->ReservedPriorityHigher( iSid ) )
+                {
+                // haptics has not been reserved for some other client with
+                // higher (or equal) priority, notify caller with an error code
+                COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL - Haptics Reserved!" ) ) );
+                User::Leave( KErrInUse );
+                }
+            else
+                {
+                // send play effect -command forwards to plugin manager
+                SendMsgToPluginManagerL( aMessage );
+                }
+            
+            break;
+            }
+        case EHWRMHapticsOpenActuator:
+            {
+            // get actuator type
+            THWRMLogicalActuators actuator = 
+                    static_cast<THWRMLogicalActuators>( aMessage.Int2() );
+            
+            // open the plugin to send the message to appropriate actuator;
+            TBool created = iPluginManager->OpenPluginToActuatorL( actuator );
+
+            // reset packetizer instance
+            if ( iPacketizer )
+                {
+                delete iPacketizer;
+                iPacketizer = NULL;
+                }
+            
+            iPacketizer = CHWRMHapticsPacketizer::NewL( actuator );
+
+            // if plugin was not created, it already exists. Inform client 
+            // about the last status of the plugin.
+            if ( !created )
+                {
+                iHapticsCommonData.NotifyActuatorEvent( actuator, iSession );
+                }
+            
+            // send the open device message;
+            SendMsgToPluginManagerL( aMessage );
+
+            break;
+            }
+        case EHWRMHapticsCleanup:
+            {
+            CleanupHaptics();
+
+            // complete as there is no ProcessResponse for this
+            aMessage.Complete( KErrNone );
+            break;
+            }
+        case EHWRMHapticsReserve:
+            {
+            COMPONENT_TRACE( ( _L("CHWRMHapticsService::ExecuteMessageL - EHWRMReserveHaptics") ) );
+            
+            ReserveHapticsL( aMessage );
+
+            // Since using dummy messages for freeze state restores, need complete always.
+            completeMessage = ETrue;
+            
+            break;
+            }           
+        case EHWRMHapticsRelease:
+            {
+            COMPONENT_TRACE( ( _L("CHWRMHapticsService::ExecuteMessageL - EHWRMReleaseHaptics") ) );
+
+            ReleaseHaptics();
+            
+            // Since using dummy messages for default state restores, need complete always.
+            completeMessage = ETrue;
+
+            break;
+            }           
+        case EHWRMHapticsSuppActuators:
+            {
+            // get the supported logical actuator types from 
+            // the plugin manager
+            TUint32 types = iPluginManager->GetSupportedActuatorInfo();
+            
+            // write the supported types to aMessage
+            TPckg<TUint32> actuatorInfoRetPckg( types );
+            TInt err = aMessage.Write( 0, actuatorInfoRetPckg, 0 );
+            
+            // complete the message
+            aMessage.Complete( err );
+            break;
+            }
+
+        case EHWRMHapticsSetLicenseProp:
+            {
+            // The license key is set automatically if it is given as empty
+            // string and if LicenseAutoSettingAllowed check succeeds.
+            // The actual license key setting occures in lower layer,
+            // here it is enough to create new command message.
+            
+            // check license key length
+            if ( aMessage.Int1() == 0 )
+                {
+                // check if automatic license key setting is allowed
+                // for the calling client
+                if ( iPluginManager->LicenseAutoSettingAllowed( aMessage ) &&
+                     iPacketizer )
+                    {
+                    // create buffer for new request data
+                    HWRMHapticsCommand::RHWRMHapticsReqData reqData;
+                    
+                    // client is allowed to get automatic license key setting,
+                    // create new command package
+                    TInt err = iPacketizer->EncSetPlatformLicenseKeyReq(
+                                        iPacketizer->DeviceHandle(),
+                                        reqData );
+                    
+                    // write new request data to request message, if creating
+                    // it succeeded
+                    if ( err == KErrNone )
+                        {
+                        aMessage.Write( 0, reqData, 0 );
+                        }
+                    
+                    reqData.Close();
+                    }
+                }
+            
+            // send message to plugin manager
+            SendMsgToPluginManagerL( aMessage );
+            break;
+            }
+        case EHWRMHapticsStatusNotification:
+            {
+            // store the message. It will be completed only
+            // when the haptics/actuator status for this client changes
+            // (thus the command should always be asynchronous on the 
+            // client side)
+            iHapticsCommonData.AddStatusObserver( aMessage );
+            
+            break;
+            }
+        case EHWRMHapticsGetStatus:
+            {
+            // get the current status value for this client
+            MHWRMHapticsObserver::THWRMHapticsStatus status =
+                iHapticsCommonData.CurrentStatus( aMessage.Session() );
+
+            // write the status to message
+            TPckg<MHWRMHapticsObserver::THWRMHapticsStatus> statusPckg( status );
+            TInt err = aMessage.Write( 0, statusPckg, 0 );
+            
+            // complete message
+            aMessage.Complete( err );
+
+            break;
+            }
+        default:
+            {
+            // Cannot identify the message, panic the client
+            aMessage.Panic( KPanicCategory, EPanicIllegalFunction );
+            break;
+            }
+
+        }//switch
+
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ExecuteMessageL - return 0x%x" ), completeMessage ) );
+    COMPONENT_TRACE( ( _L( "e_HWRMHAPTICS_SERVICE_EXECUTEMESSAGEL 0" ) ) );
+    
+    return completeMessage;
+    }
+    
+// ---------------------------------------------------------------------------
+// Handles Haptics requests responses.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ProcessResponseL( TInt aCommandId,  
+                                                     TUint8 aTransId,
+                                                     const TDesC8& aData )
+    {
+    COMPONENT_TRACE( ( _L( "e_HWRMHAPTICS_SERVICE_PROCESSRESPONSEL 1" ) ) );
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ProcessResponseL(0x%x, 0x%x, <data>)" ), aCommandId, aTransId ) );
+
+    if( aCommandId == HWRMHapticsCommand::EHapticsCmdId )
+        {
+        TInt contextErr = CompleteRequestL( aTransId, aData );
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ProcessResponseL - CompleteRequestL ret = %d" ), contextErr ) );
+
+        // Leave if there is error in context
+        User::LeaveIfError( contextErr );
+        }
+             
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ProcessResponseL - return" ) ) );
+    COMPONENT_TRACE( ( _L( "e_HWRMHAPTICS_SERVICE_PROCESSRESPONSEL 0" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Suspends haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::SuspendResource()
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::SuspendSubResource()" ) ) );
+    
+    iSuspended = ETrue;
+
+    // notify client that haptics for it has been suspended
+    iHapticsCommonData.NotifyStatus( 
+        MHWRMHapticsObserver::EHWRMHapticsStatusSuspended, iSession );
+    
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::SuspendSubResource - return" ) ) );
+    }
+    
+// ---------------------------------------------------------------------------
+// Resumes haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ResumeResource()
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ResumeSubResource()" ) ) );
+
+    iSuspended = EFalse;
+
+    // notify client that haptics for it is now available
+    iHapticsCommonData.NotifyStatus( 
+        MHWRMHapticsObserver::EHWRMHapticsStatusAvailable, iSession );
+    
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ResumeSubResource - return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Cancels outstanding request by completing the RMessage2 and removing data
+// from transaction list.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::CancelRequest( TUint8 aTransId )
+    {
+    CHWRMHapticsPluginRequestData* data = 
+        static_cast<CHWRMHapticsPluginRequestData*>(
+        iTransactionList->FindTransaction( aTransId, ETrue ) );
+    
+    if ( data && data->RequestMessage().Handle() )
+        {
+        data->RequestMessage().Complete( KErrTimedOut );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+//
+CHWRMHapticsService::CHWRMHapticsService(
+                CHWRMHapticsCommonData& aHapticsCommonData, 
+                const RMessage2& aMessage )
+    : iHapticsCommonData( aHapticsCommonData ), iSid( aMessage.SecureId() ),
+      iSession( aMessage.Session() )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CHWRMHapticsService()" ) ) );
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CHWRMHapticsService - return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ConstructL(
+        CHWRMHapticsPluginManager* aPluginManager,
+        CHWRMHapticsReservationHandler* aReservationHandler )
+    {    
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ConstructL(0x%x)" ), aPluginManager ) );
+
+    if ( !aPluginManager )
+        {
+        User::Leave( KErrBadHandle );
+        }
+        
+    iPluginManager = aPluginManager;
+    iReservationHandler = aReservationHandler;
+
+    iTransactionList = new( ELeave ) CHWRMHapticsPluginTransactionList();
+   
+    // set this session to the common data for storing the client 
+    // specific status information
+    iHapticsCommonData.AddSessionL( iSession );
+
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ConstructL - return " ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Completes request. Subclass calls this from ProcessResponseL
+// ---------------------------------------------------------------------------
+//
+TInt CHWRMHapticsService::CompleteRequestL( TUint8 aTransId, 
+                                            const TDesC8& aData )
+    {
+    // return value
+    TInt contextErr( KErrNone );
+
+    // find transaction data
+    CHWRMHapticsPluginRequestData* data = 
+        static_cast<CHWRMHapticsPluginRequestData*>(
+        iTransactionList->FindTransaction( aTransId, ETrue ) );
+    
+    CleanupStack::PushL( data );
+
+    if ( data && data->RequestMessage().Handle() )
+        {
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequestL - iRequestMessage.Handle() ok." ) ) );
+
+        // data storage for the protocol version and error code
+        CHWRMHapticsRespData* respData = 
+            CHWRMHapticsRespData::NewLC( KErrNone, KNullDesC8 );
+
+        // internalize data using stream reader
+        RDesReadStream reader( aData );
+        CleanupClosePushL( reader );
+        reader >> *respData;
+        CleanupStack::PopAndDestroy( &reader );
+        
+        // status filled in message decoding
+        TInt vibeStatus = KErrNone;
+        
+        // decode data, if no error
+        if ( respData->ErrorCode() == KErrNone )
+            {
+            if ( data->RequestMessage().Function() == EHWRMHapticsBridgeCommand )
+                {
+                // bridge command handling
+                COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequest - inside EHWRMHapticsBridgeCommand case:" ) ) );
+                DATADUMP_TRACE( _L("CHWRMHapticsService::CompleteRequest - (EHWRMHapticsBridgeCommand case) - data dump "), respData->Data() );
+
+                // write error code and response data
+                TPckg<TInt> vibeDummyCodePckg( KErrNone );
+                data->RequestMessage().Write( 1, vibeDummyCodePckg, 0 );
+                data->RequestMessage().Write( 2, respData->Data(), 0 );
+                }
+            else
+                {
+                // decode the message and send it to the callback service
+                CDesC8ArraySeg* decodeArray = NULL;
+                TRAPD( err, decodeArray = iPacketizer->DecodeMessageL(
+                                            respData->Data(), vibeStatus ) );
+
+                COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequestL - Return msg decoding, err = %d" ), err ) );
+
+                for ( TInt i = 0; err == KErrNone && 
+                      i < decodeArray->MdcaCount(); ++i )
+                    {
+                    // write data back to client
+                    err = data->RequestMessage().Write(
+                                KHapticsMessageResponseArgsOffset + i,
+                                decodeArray->MdcaPoint( i ), 0 );
+                    }
+
+                COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequestL - Data writing err = %d" ), err ) );
+                }
+            }
+        
+        CleanupStack::PopAndDestroy( respData );
+        
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequestL - calling iRequestMessage.Complete()") ) ) ;
+        data->RequestMessage().Complete( vibeStatus );
+        }
+    else
+        {
+        // transaction data not found
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CompleteRequest - No transaction data found!" ) ) );
+        contextErr = KErrBadHandle;
+        }    
+
+    // cleanup data
+    CleanupStack::PopAndDestroy( data );
+    
+    return contextErr;
+    }
+
+// ---------------------------------------------------------------------------
+// Checks transaction list if specified message is in any transaction.
+// ---------------------------------------------------------------------------
+//
+TBool CHWRMHapticsService::CheckForMessage( TInt aHandle )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CheckForMessage - Checking for message: 0x%x" ), aHandle ) );
+    
+    CHWRMHapticsPluginRequestData* data = 
+        static_cast<CHWRMHapticsPluginRequestData*>(
+            iTransactionList->FirstItem() );
+    
+    TBool retval( EFalse );
+    
+    while ( !retval && data )
+        {
+        if ( data->RequestMessage().Handle() == aHandle )
+            {
+            retval = ETrue;
+            }
+        
+        data = static_cast<CHWRMHapticsPluginRequestData*>( data->NextItem() );
+        }
+        
+    return retval;
+    }
+        
+// ---------------------------------------------------------------------------
+// Cleans up haptics. 
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::CleanupHaptics()
+    {
+    if ( !iCleanupDone )
+        {
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CleanupHaptics()" ) ) );
+
+        // release haptics in case this client has made the reservation
+        ReleaseHaptics();
+
+        iSuspended = EFalse;
+        
+        // remove priority of the client from reservation handler
+        iReservationHandler->RemovePriority( iSid );
+
+        // remove this session from the common data
+        iHapticsCommonData.RemoveSession( iSession );
+
+        iCleanupDone = ETrue;
+        
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::CleanupHaptics - return" ) ) );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Handles Haptics requests. 
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::SendMsgToPluginManagerL( const RMessage2& aMessage )
+    {
+    // Create new data (TransId is updated later, commandId is not important)
+    CHWRMHapticsPluginRequestData* data( NULL );
+    if ( aMessage.Function() == RMessage2::EDisConnect )
+        {
+        data = new ( ELeave ) 
+            CHWRMHapticsPluginRequestData( RMessage2(), 0, 0, EFalse );
+        }
+    else 
+        {
+        data = new ( ELeave ) 
+            CHWRMHapticsPluginRequestData( aMessage, 0, 0, EFalse );
+        }
+    
+    CleanupStack::PushL( data );
+
+    if ( aMessage.Function() == RMessage2::EDisConnect )
+        {
+        // form from Disconnect message actuator closing request
+        RBuf8 closeBuf;
+        CleanupClosePushL( closeBuf );
+        
+        User::LeaveIfError( iPacketizer->EncCloseDeviceReq( 
+                            iPacketizer->DeviceHandle(), closeBuf ) );
+        
+        HBufC8* reqData = closeBuf.AllocL();
+        
+        CleanupStack::PopAndDestroy( &closeBuf );
+        
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::SendMsgToPluginManagerL - Disconnect actuator") ) );
+        
+        // created buffer is deleted in the request data object
+        data->SetRequestData( reqData );
+
+        // command to plugin manager
+        TUint8 transId = iPluginManager->ProcessCommandL( 
+                                            HWRMHapticsCommand::EHapticsCmdId, 
+                                            *reqData, this );
+        data->SetTransactionId( transId );
+        }
+    else        
+        {
+        // read message data into a heap buffer
+        HBufC8* reqData = HBufC8::NewL( aMessage.GetDesLength( 0 ) );
+        TPtr8 dataPtr = reqData->Des();
+        TInt err = aMessage.Read( 0, dataPtr, 0 );
+        
+        COMPONENT_TRACE( ( _L( "CHWRMHapticsService::SendMsgToPluginManagerL - aMessageRead err = %d"), err ) );
+        
+        // created buffer is deleted in the request data object
+        data->SetRequestData( reqData );
+
+        // command to plugin manager
+        TUint8 transId = iPluginManager->ProcessCommandL( 
+                                            HWRMHapticsCommand::EHapticsCmdId, 
+                                            *reqData, this);
+        data->SetTransactionId( transId );
+        }
+    
+    // data still needed, do not destroy, just pop
+    CleanupStack::Pop( data );
+    
+    // Add data to list
+    iTransactionList->AddTransaction( data );
+    }
+
+// ---------------------------------------------------------------------------
+// Reserves haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ReserveHapticsL( const RMessage2& aMessage )
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ReserveHapticsL()" ) ) );
+    
+    // Reserve the haptics
+    TBool noCoeEnv = aMessage.Int0();
+    TBool suspended = iReservationHandler->ReserveL( iSid, noCoeEnv, this );
+    
+    // if reservation became the affective reservation, inform all other 
+    // clients that haptics is reserved
+    if ( !suspended )
+        {
+        iHapticsCommonData.BroadcastStatus( 
+            MHWRMHapticsObserver::EHWRMHapticsStatusReserved, iSession );
+        }
+    
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ReserveHapticsL() return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Releases haptics.
+// ---------------------------------------------------------------------------
+//
+void CHWRMHapticsService::ReleaseHaptics()
+    {
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ReleaseHaptics()" ) ) );
+
+    // get info is haptics currently reserved for this client
+    TBool activeReservation = iReservationHandler->ActiveReservation( this );
+
+    // release reservation (removes, if this has a reservation)
+    TBool reserved = iReservationHandler->Release( this );
+
+    // if haptics is still reserved for another client, notify client
+    if ( reserved )
+        {
+        iHapticsCommonData.NotifyStatus( 
+            MHWRMHapticsObserver::EHWRMHapticsStatusReserved, iSession );
+        }
+    else if ( activeReservation )
+        {
+        // haptics was reserved for this client, but there are no more 
+        // reservations --> inform all clients, which have been blocked
+        iHapticsCommonData.BroadcastStatus( 
+            MHWRMHapticsObserver::EHWRMHapticsStatusAvailable, iSession );
+        }
+           
+    COMPONENT_TRACE( ( _L( "CHWRMHapticsService::ReleaseHaptics() return" ) ) );
+    }
+
+
+//  End of File