usbclasses/usbphoneasmodem/classimplementation/mscfileserver/src/bulkonlytransport.cpp
changeset 34 7858bc6ead78
parent 31 dfdd8240f7c8
child 35 9d8b04ca6939
--- a/usbclasses/usbphoneasmodem/classimplementation/mscfileserver/src/bulkonlytransport.cpp	Fri May 14 16:51:51 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1491 +0,0 @@
-// Copyright (c) 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 "bulkonlytransport.h"
-#include "mscfileserver.h"
-#include "usbmscfileshared.h"
-#include "debug.h"
-#define InEndpoint EEndpoint1
-#define OutEndpoint EEndpoint2
-//This value defined in USB Mass Storage Bulk Only Transrt spec and not supposed to be changed
-LOCAL_D const TInt KRequiredNumberOfEndpoints = 2; // in addition to endpoint 0. 
-
-
-//CBW offsets
-LOCAL_D const TInt KCbwSignatureOffset = 0;
-LOCAL_D const TInt KCbwTagOffset = 4;
-LOCAL_D const TInt KCbwDataTransferLengthOffset = 8;
-LOCAL_D const TInt KCbwFlagOffset = 12;
-LOCAL_D const TInt KCbwLunOffset = 13;
-LOCAL_D const TInt KCbwCbLengthOffset = 14;
-LOCAL_D const TInt KMaxCbwcbLength = 16;
-// CSW offsets
-LOCAL_D const TInt KCswSingnatureOffset = 0;
-LOCAL_D const TInt KCswTagOffset = 4;
-LOCAL_D const TInt KCswDataResidueOffset = 8;
-LOCAL_D const TInt KCswStatusOffset = 12;
-LOCAL_D const TInt KCswLength = 13;
-LOCAL_D const TInt KUsbNumInterfacesOffset = 4;
-
-/**
- This function unpacks into the TUsbRequestHdr class from a descriptor with 
- the alignment that would be introduced on the USB bus.
- 
- @param aBuffer Input buffer
- @param aTarget Unpacked header.
- @return Error.
- */
-TInt TUsbRequestHdr::Decode(const TDesC8& aBuffer)
-
-    {
-    if (aBuffer.Length() < static_cast<TInt> (KRequestHdrSize))
-        {
-        TRACE_ERROR((_L("TUsbRequestHdr::Decode buffer invalid length %d"),aBuffer.Length()))
-        return KErrGeneral;
-        }
-
-    // Decode as SPEC 1.3.3
-    iRequestType = aBuffer[0];
-    iRequest = static_cast<TEp0Request>(aBuffer[1]);
-    iValue = static_cast<TUint16>(aBuffer[2] + (aBuffer[3] << 8));
-    iIndex = static_cast<TUint16>(aBuffer[4] + (aBuffer[5] << 8));
-    iLength = static_cast<TUint16>(aBuffer[6] + (aBuffer[7] << 8));
-    TRACE_INFO((_L("type=%d request=%d value=%d index=%d length=%d"), iRequestType,iRequest,iValue,iIndex,iLength))
-
-    return KErrNone;
-    }
-
-/**
- This function determines whether data is required by the host in response 
- to a message header.
-
- @return TBool	Flag indicating whether a data response required.
- */
-TBool TUsbRequestHdr::IsDataResponseRequired() const
-
-    {
-    return (iRequestType & 0x80) ? ETrue : EFalse;
-    }
-
-//
-/**
- Called by CBulkOnlyTransport to create an instance of CControlInterface
-
- @param aParent reference to the CBulkOnlyTransport
- */
-CControlInterface* CControlInterface::NewL(CBulkOnlyTransport& aParent)
-    {
-    CControlInterface* self = new (ELeave) CControlInterface(aParent);
-    CleanupStack::PushL(self);
-    self->ConstructL();
-    CActiveScheduler::Add(self);
-    CleanupStack::Pop();
-    return self;
-    }
-
-void CControlInterface::ConstructL()
-    {
-    }
-
-/**
- c'tor
-
- @param aParent reference to the CBulkOnlyTransport
- */
-CControlInterface::CControlInterface(CBulkOnlyTransport& aParent) :
-	CActive(EPriorityStandard),
-	iParent(aParent),
-	iCurrentState(ENone)
-    {
-    }
-
-/**
- d'tor
- */
-CControlInterface::~CControlInterface()
-    {
-    TRACE_FUNC
-	Cancel();
-    }
-
-/**
- Called by  CBulkOnlyTransportStart to start control interface
- */
-TInt CControlInterface::Start()
-    {
-    TRACE_FUNC
-    TInt res = ReadEp0Data();
-    return (res);
-    }
-
-/**
- Called by CBulkOnlyTransportStart to stop control interface
- */
-void CControlInterface::Stop()
-    {
-    TRACE_FUNC
-    // Don't need to be any thing if we're not in active state
-    if (!IsActive())
-        {
-        TRACE_INFO((_L("Not active")))
-        return;
-        }
-
-    TRACE_INFO((_L("Stopping...")))
-
-    // Stop by cancel
-    Cancel();
-    iCurrentState = ENone;
-    }
-
-/**
- Cancel outstanding request (if any)
- */
-void CControlInterface::DoCancel()
-    {
-    TRACE_FUNC
-    switch(iCurrentState)
-        {
-        case EReadEp0Data:
-        iParent.Ldd().ReadCancel(EEndpoint0);
-        break;
-        case ESendMaxLun:
-        iParent.Ldd().WriteCancel(EEndpoint0);
-        break;
-        default:
-        TRACE_ERROR((_L("\nWrong state !")))
-        __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsControlInterfaceBadState));
-        }
-    }
-
-/**
- Implement CControlInterface state machine
- */
-void CControlInterface::RunL()
-    {
-    TRACE_FUNC
-    if (iStatus != KErrNone)
-        {
-        TRACE_ERROR(( _L( "Error %d in RunL" ), iStatus.Int() ))
-
-        //read EP0  again 
-        ReadEp0Data();
-        return;
-        }
-
-    switch (iCurrentState)
-        {
-        case ESendMaxLun:
-            ReadEp0Data();
-            break;
-
-        case EReadEp0Data:
-            DecodeEp0Data();
-            break;
-
-        default:
-            TRACE_ERROR(( _L( "error: (Shouldn't end up here...)" ) ))
-            __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsControlInterfaceBadState));
-            break;
-        }
-    return;
-    }
-
-/**
- Post a read request to EEndpoint0 to read request header
- */
-TInt CControlInterface::ReadEp0Data()
-    {
-    TRACE_FUNC
-    if ( IsActive() )
-        {
-        TRACE_ERROR(( _L( "Still active" ) ))
-        return KErrServerBusy;
-        }
-
-    iParent.Ldd().Read(iStatus, EEndpoint0, iData, KRequestHdrSize);
-
-    iCurrentState = EReadEp0Data;
-
-    SetActive();
-    return KErrNone;
-    }
-
-/**
- Decode request header and do appropriate action - get max LUN info or post a reset request
- */
-void CControlInterface::DecodeEp0Data()
-    {
-    TRACE_FUNC
-    if ( IsActive() )
-        {
-        TRACE_ERROR(( _L( "Still active" ) ))
-        __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsControlInterfaceStillActive));
-        return;
-        }
-
-    TInt err = iRequestHeader.Decode(iData);
-
-    if (err != KErrNone)
-        {
-        TRACE_WARNING((_L("Decode header error : err=%d"), err))
-        return;
-        }
-
-    switch(iRequestHeader.iRequest)
-        {
-        // GET MAX LUN (0xFE)
-        case TUsbRequestHdr::EReqGetMaxLun:
-            {
-            TRACE_INFO((_L("DecodeEp0Data : 'Get Max LUN' Request MaxLun = %d" ),
-                            iParent.MaxLun() ))
-
-            if ( iRequestHeader.iRequestType != 0xA1 //value from USB MS BOT spec
-                    || iRequestHeader.iIndex> 15 || iRequestHeader.iValue != 0 || iRequestHeader.iLength != 1)
-                {
-                TRACE_ERROR((_L("GetMaxLun command packet check error")))
-                iParent.Ldd().EndpointZeroRequestError();
-                break;
-                }
-
-            iData.FillZ(1); //Return only 1 byte to host 
-            iData[0] = static_cast<TUint8>(iParent.MaxLun()); // Supported Units
-            iParent.Ldd().Write(iStatus, EEndpoint0, iData, 1);
-
-            iCurrentState = ESendMaxLun;
-            SetActive();
-
-            return;
-            }
-
-        // RESET (0xFF)
-        case TUsbRequestHdr::EReqReset:
-            {
-            TRACE_INFO((_L("DecodeEp0Data : 'Mass Storage Reset' Request")))
-
-            if ( iRequestHeader.iRequestType != 0x21 //value from USB MS BOT spec
-                    || iRequestHeader.iIndex> 15 || iRequestHeader.iValue != 0 || iRequestHeader.iLength != 0)
-                {
-                TRACE_ERROR((_L("MSC Reset command packet check error")))
-                iParent.Ldd().EndpointZeroRequestError();
-                break;
-                }
-
-            iParent.HwStop();
-            iParent.Controller().Reset();
-            iParent.HwStart(ETrue);
-
-            err = iParent.Ldd().SendEp0StatusPacket();
-            TRACE_INFO((_L("SendEp0StatusPacket: err=%d"), err))
-
-            return;
-            }
-        // Unknown?
-        default:
-            {
-            TRACE_ERROR((_L("DecodeEp0Data : Unknown Request")))
-            }
-        }
-    ReadEp0Data(); //try to get another request 
-    }
-
-//-------------------------------------
-/**
- Create CBulkOnlyTransport object
- @param aNumDrives - The number of drives available for MS
- @param aController - reference to the parent
- @return pointer to newly created object
- */
-CBulkOnlyTransport* CBulkOnlyTransport::NewL(TInt aNumDrives,CMscFileController& aController)
-    {
-	CBulkOnlyTransport* self = new(ELeave) CBulkOnlyTransport(aNumDrives, aController);
-    CleanupStack::PushL(self);
-    self->ConstructL();
-    CleanupStack::Pop(self);
-    return self;
-    }
-
-/**
- c'tor 
- @param aNumDrives - The number of drives available for MS
- @param aController - reference to the parent
- */
-CBulkOnlyTransport::CBulkOnlyTransport(TInt aNumDrives,CMscFileController& aController):
-	CActive(EPriorityStandard),
-	iMaxLun(aNumDrives-1),
-	iController(aController),
-	iReadBuf(NULL,0),
-	iWriteBuf(NULL,0),
-	iStallAllowed(ETrue)
-    {
-    }
-
-/**
- Constructs the CBulkOnlyTranspor object
- */
-void CBulkOnlyTransport::ConstructL()
-    {
-    TRACE_FUNC
-    iControlInterface = CControlInterface::NewL(*this);
-    iDeviceStateNotifier = CActiveDeviceStateNotifier::NewL(*this);
-    CActiveScheduler::Add(this);
-    }
-
-/**
- Destructor
- */
-CBulkOnlyTransport::~CBulkOnlyTransport()
-    {
-    TRACE_FUNC
-    if (iInterfaceConfigured)
-        {
-        Stop();
-        }
-    delete iControlInterface;
-    delete iDeviceStateNotifier;
-    }
-
-/**
- Set or unset configuration descriptor for USB MassStorage Bulk Only transport
-
- @param aUnset indicate whether set or unset descriptor
- @return KErrNone if operation was completed successfully, errorcode otherwise
- */
-TInt CBulkOnlyTransport::SetupConfigurationDescriptor(TBool aUnset)
-    {
-    TRACE_FUNC
-    TInt ret(KErrNone);
-    TInt configDescriptorSize(0);
-
-    iLdd.GetConfigurationDescriptorSize(configDescriptorSize);
-    if (static_cast<TUint> (configDescriptorSize) != KUsbDescSize_Config)
-        {
-        return KErrCorrupt;
-        }
-
-    TBuf8<KUsbDescSize_Config> configDescriptor;
-    ret = iLdd.GetConfigurationDescriptor(configDescriptor);
-    if (ret != KErrNone)
-        {
-        return ret;
-        }
-
-    // I beleive that other fields setted up during LDD initialisation
-    if (aUnset)
-        {
-        --configDescriptor[KUsbNumInterfacesOffset];
-        }
-    else
-        {
-        ++configDescriptor[KUsbNumInterfacesOffset];
-        }
-    ret = iLdd.SetConfigurationDescriptor(configDescriptor);
-
-    return ret;
-    }
-
-/**
- Set up interface descriptor
-
- @return KErrNone if operation was completed successfully, errorcode otherwise
- */
-TInt CBulkOnlyTransport::SetupInterfaceDescriptors()
-    {
-    TRACE_FUNC
-    // Device caps
-    TUsbDeviceCaps d_caps;
-    TInt ret = iLdd.DeviceCaps(d_caps);
-    if (ret != KErrNone)
-        {
-        return ret;
-        }
-    TInt totalEndpoints = d_caps().iTotalEndpoints;
-    if (totalEndpoints < KRequiredNumberOfEndpoints)
-        {
-        return KErrHardwareNotAvailable;
-        }
-
-    // Endpoint caps
-    TUsbcEndpointData data[KUsbcMaxEndpoints];
-	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
-    ret = iLdd.EndpointCaps(dataptr);
-    if (ret != KErrNone)
-        {
-        return ret;
-        }
-
-    // Set the active interface
-    TUsbcInterfaceInfoBuf ifc;
-    TInt ep_found = 0;
-    TBool foundBulkIN = EFalse;
-    TBool foundBulkOUT = EFalse;
-
-    for (TInt i = 0; i < totalEndpoints; i++)
-        {
-        const TUsbcEndpointCaps* caps = &data[i].iCaps;
-        const TInt maxPacketSize = caps->MaxPacketSize();
-		if (!foundBulkIN &&
-			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirIn)) == (KUsbEpTypeBulk | KUsbEpDirIn))
-            {
-            // InEndpoint is going to be our TX (IN, write) endpoint
-            ifc().iEndpointData[0].iType = KUsbEpTypeBulk;
-            ifc().iEndpointData[0].iDir = KUsbEpDirIn;
-            ifc().iEndpointData[0].iSize = maxPacketSize;
-            ifc().iEndpointData[0].iInterval_Hs = 0;
-			ifc().iEndpointData[0].iFeatureWord1 = KUsbcEndpointInfoFeatureWord1_DMA;
-            foundBulkIN = ETrue;
-            if (++ep_found == KRequiredNumberOfEndpoints)
-                {
-                break;
-                }
-            continue;
-            }
-		if (!foundBulkOUT &&
-			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirOut)) == (KUsbEpTypeBulk | KUsbEpDirOut))
-            {
-            // OutEndpoint is going to be our RX (OUT, read) endpoint
-            ifc().iEndpointData[1].iType = KUsbEpTypeBulk;
-            ifc().iEndpointData[1].iDir = KUsbEpDirOut;
-            ifc().iEndpointData[1].iSize = maxPacketSize;
-            ifc().iEndpointData[1].iInterval_Hs = 0;
-			ifc().iEndpointData[1].iFeatureWord1 = KUsbcEndpointInfoFeatureWord1_DMA;
-            foundBulkOUT = ETrue;
-            if (++ep_found == KRequiredNumberOfEndpoints)
-                {
-                break;
-                }
-            continue;
-            }
-        }
-    if (ep_found != KRequiredNumberOfEndpoints)
-        {
-        return KErrHardwareNotAvailable;
-        }
-    _LIT16(string, "USB Mass Storage Interface");
-    ifc().iString = const_cast<TDesC16*> (&string);
-    ifc().iTotalEndpointsUsed = KRequiredNumberOfEndpoints;
-    ifc().iClass.iClassNum = 0x08; // Mass Storage
-    ifc().iClass.iSubClassNum = 0x06; // SCSI Transparent Command Set
-    ifc().iClass.iProtocolNum = 0x50; // Bulk Only Transport
-
-	TUint bandwidth_priority = (EUsbcBandwidthOUTDefault | EUsbcBandwidthINDefault);
-    if (d_caps().iHighSpeed)
-        {
-        // If this device supports USB High-speed, then we request 64KB buffers
-        // (otherwise the default 4KB ones will do).
-        bandwidth_priority = (EUsbcBandwidthOUTPlus2 | EUsbcBandwidthINPlus2);
-        // Also, tell the Protocol about it, because it might want to do some
-        // optimizing too.
-        iProtocol->ReportHighSpeedDevice();
-        }
-    ret = iLdd.SetInterface(0, ifc, bandwidth_priority);
-    return ret;
-    }
-
-/**
- Called by the protocol after processing the packet to indicate that more data is required.  
-
- @param aData reference to the data buffer. 
- */
-void CBulkOnlyTransport::SetupReadData(TPtr8& aData)
-    {
-    TRACE_FUNC
-    TRACE_INFO((_L("Length = %d  (bytes)"), aData.Length()))
-    iReadBuf.Set(aData);
-    iReadSetUp = ETrue;
-    }
-
-/**
- Called by the protocol after processing the packet to indicate that data should be written to the host.  
-
- @param aData reference to the data buffer. 
- */
-void CBulkOnlyTransport::SetupWriteData(TPtrC8& aData)
-    {
-    TRACE_FUNC
-    TRACE_INFO((_L("Length = %d  (bytes)"), aData.Length()))
-    iWriteBuf.Set(aData);
-    iWriteSetUp = ETrue;
-    }
-
-TInt CBulkOnlyTransport::Start()
-    {
-    TRACE_FUNC_ENTRY
-
-    TInt err = KErrNone;
-
-    if (!iProtocol)
-        {
-        return KErrBadHandle; //protocol should be set up before start
-        }
-
-    if (IsActive())
-        {
-        TRACE_ERROR((_L("Active before start!")))
-        return KErrInUse;
-        }
-
-    if ((err = iLdd.Open(0)) != KErrNone )
-        {
-        TRACE_ERROR((_L("Error during open ldd!")))
-        return err;
-        }
-
-    if ((err = SetupConfigurationDescriptor()) != KErrNone ||
-            (err = SetupInterfaceDescriptors()) != KErrNone )
-        {
-        iLdd.Close();
-        TRACE_ERROR((_L("Error during descriptors setup!")))
-        return err;
-        }
-
-    iDeviceStateNotifier->Activate(); // activate notifier wich will wait until USB became configured
-    TUsbcDeviceState deviceStatus = EUsbcDeviceStateDefault;
-    err = iLdd.DeviceStatus(deviceStatus);
-    TRACE_INFO((_L("Device status = %d"), deviceStatus))
-    if (err == KErrNone && deviceStatus == EUsbcDeviceStateConfigured)
-        {
-        TRACE_INFO(_L("Starting bulk only transport\n"));
-        err = HwStart();
-        }
-    iInterfaceConfigured = ETrue;
-    TRACE_FUNC_EXIT
-    return err;
-    }
-
-TInt CBulkOnlyTransport::HwStart(TBool aDiscard)
-    {
-    TRACE_FUNC_ENTRY
-
-    TInt res = iControlInterface->Start();
-
-    iCurrentState = ENone;
-    iWriteSetUp = EFalse;
-    iReadSetUp = EFalse;
-    iStarted = ETrue;
-
-    if (aDiscard)
-        {
-        TInt bytes;
-        const TInt err = iLdd.QueryReceiveBuffer(OutEndpoint, bytes);
-        if (err != KErrNone || bytes <= 0)
-            {
-            TRACE_ERROR((_L("Error: err=%d bytes=%d"), bytes))
-            }
-        else
-            {
-            TRACE_ERROR((_L("RxBuffer has %d bytes"), bytes))
-            ReadAndDiscardData(bytes);
-            }
-        }
-
-    ReadCBW();
-    TRACE_FUNC_EXIT
-    return res;
-    }
-
-TInt CBulkOnlyTransport::HwStop()
-    {
-    TRACE_FUNC
-
-    if (iStarted)
-        {
-        Cancel();
-        iControlInterface->Cancel();
-        iProtocol->Cancel();
-        iStarted = EFalse;
-        }
-    return KErrNone;
-    }
-
-TInt CBulkOnlyTransport::HwSuspend()
-    {
-    TRACE_FUNC
-    return KErrNone;
-    }
-
-TInt CBulkOnlyTransport::HwResume()
-    {
-    TRACE_FUNC
-    return KErrNone;
-    }
-
-/**
- Stops the Bulk Only Transport
- */
-TInt CBulkOnlyTransport::Stop()
-    {
-    TRACE_FUNC
-    iControlInterface->Cancel();
-    iDeviceStateNotifier->Cancel();
-    Cancel();
-    if (iInterfaceConfigured)
-        {
-        iLdd.ReleaseInterface(0);
-        SetupConfigurationDescriptor(ETrue);
-        iLdd.Close();
-        }
-    iCurrentState = ENone;
-    iInterfaceConfigured = EFalse;
-
-    return KErrNone;
-    }
-
-/**
- Read aLength bytes of data from the host into the read buffer.
- @param aLength The number of bytes to read from the host.
- */
-void CBulkOnlyTransport::ReadCBW()
-    {
-    TRACE_FUNC
-    if (IsActive())
-        {
-        TRACE_ERROR(( _L( "Still active" ) ))
-        __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsBulkOnlyStillActive));
-        return;
-        }
-
-    iCbwBuf.SetMax();
-    iLdd.ReadUntilShort(iStatus, OutEndpoint, iCbwBuf, iCbwBuf.Length());
-
-    iCurrentState = EWaitForCBW;
-    SetActive();
-    }
-
-void CBulkOnlyTransport::DoCancel()
-    {
-    TRACE_FUNC
-    iLdd.WriteCancel(InEndpoint);
-    iLdd.ReadCancel(OutEndpoint);
-    }
-
-void CBulkOnlyTransport::Activate(TInt aReason)
-    {
-    SetActive();
-    TRequestStatus* r = &iStatus;
-    User::RequestComplete(r, aReason);
-    }
-
-void CBulkOnlyTransport::RunL()
-    {
-    TRACE_FUNC
-    if (iStatus != KErrNone)
-        {
-        TRACE_ERROR((_L("Error %d in RunL, halt endpoints \n"), iStatus.Int()))
-        SetPermError(); //halt endpoints for reset recovery
-        return;
-        }
-
-    switch (iCurrentState)
-        {
-        case EWaitForCBW:
-            TRACE_INFO((_L("EWaitForCBW")))
-            DecodeCBW();
-            break;
-
-        case EWritingData:
-            TRACE_INFO((_L("EWritingData")))
-            iWriteSetUp = EFalse; //the buffer was used
-
-            if (iDataResidue && iStallAllowed)
-                {
-                StallEndpointAndWaitForClear(InEndpoint);
-                }
-
-            SendCSW(iCbwTag, iDataResidue, iCmdStatus);
-            break;
-
-        case EReadingData:
-            {
-            TRACE_INFO((_L("EReadingData")))
-
-            TInt ret = KErrNone;
-            FOREVER
-                {
-                if (iReadSetUp)
-                    {
-                    ret = iProtocol->ReadComplete(KErrNone);
-                    }
-
-                TUint deviceDataLength = static_cast<TUint>(iReadBuf.Length());
-                if(ret == KErrCompletion)
-                    {
-                    // The protocol has indicated with KErrCompletion that sufficient
-                    // data is available in the buffer to process the transfer immediately.
-                    iDataResidue -= deviceDataLength;
-                    iLdd.Read(iStatus, OutEndpoint, iReadBuf, deviceDataLength);
-                    User::WaitForRequest(iStatus);
-                    if (iStatus != KErrNone)
-                        {
-                        // An error occurred - halt endpoints for reset recovery
-                        TRACE_ERROR((_L("Error %d in EReadingData, halt endpoints"),
-                                        iStatus.Int()))
-                        SetPermError();
-                        return;
-                        }
-                    }
-                else if(ret == KErrNotReady)
-                    {
-                    // The protocol has indicated with KErrNotReady that insufficient
-                    // data is available in the buffer, so should wait for it to arrive
-                    ReadData(deviceDataLength);
-                    break;
-                    }
-                else
-                    {
-                    // The protocol has indicated that transfer is 
-                    // complete, so send the CSW response to the host.
-                    iReadSetUp = EFalse;
-
-                    if (ret != KErrNone)
-                        {
-                        iCmdStatus = ECommandFailed;
-                        }
-
-                    if (iDataResidue)
-                        {
-                        TRACE_INFO((_L("Discarding residue")))
-                        // we have to read as much data as available that host PC sends;
-                        // otherwise, bulk-out endpoint will need to keep sending NAK back.
-                        ReadAndDiscardData(iDataResidue);
-                        }
-                    SendCSW(iCbwTag, iDataResidue, iCmdStatus);
-                    break;
-                    }
-                }
-            }
-        break;
-
-        case ESendingCSW:
-        TRACE_INFO((_L("ESendingCSW")))
-        ReadCBW();
-        break;
-
-        case EPermErr:
-        TRACE_INFO((_L("EPermErr")))
-        StallEndpointAndWaitForClear(InEndpoint);
-        break;
-
-        default:
-        SetPermError(); // unexpected state
-        }
-    }
-
-/**
- Prepare incase we need to read data from host
- Called in DecodeCBW(...)
- @param aHostDataLength The number of bytes to read from the host.
- */
-void CBulkOnlyTransport::PrepareReadFromHost(TUint aHostDataLength)
-    {
-    if (!iReadSetUp)
-        {
-			iDataResidue =aHostDataLength;
-			TRACE_INFO((_L("Read buffer was not setup\n")))
-            //Use next block instead of StallEndpointAndWaitForClear(OutEndpoint); 
-            {
-            iBuf.SetLength(KBOTMaxBufSize);
-            TUint c =0;
-            TRequestStatus status;
-            while (c<aHostDataLength)
-                {
-                TInt len;
-                if (aHostDataLength - c> KBOTMaxBufSize)
-                    {
-                    len = KBOTMaxBufSize;
-                    }
-                else
-                    {
-                    len = aHostDataLength - c;
-                    }
-
-                iLdd.Read(status, OutEndpoint, iBuf, len);
-                User::WaitForRequest(status);
-                c += KBOTMaxBufSize;
-                }
-            }
-
-        if (iWriteSetUp) //case (10)
-            {
-            TRACE_INFO((_L("case 10\n")))
-            SendCSW(iCbwTag, aHostDataLength, EPhaseError);
-            }
-        else // case (9)
-
-            {
-            TRACE_INFO((_L("Case 9\n")))
-            SendCSW(iCbwTag, aHostDataLength, iCmdStatus);
-            }
-
-        return;
-        }
-    else
-        {
-        TUint deviceDataLength = static_cast<TUint>(iReadBuf.Length());
-        iDataResidue =aHostDataLength - deviceDataLength;
-        TRACE_INFO((_L("deviceDataLength=%d, DataResidue (read from host) =%d\n"),
-                        deviceDataLength,iDataResidue))
-
-        if (deviceDataLength <= aHostDataLength) // case (11) and (12)
-
-            {
-            TRACE_INFO((_L("Case 11 or 12\n")))
-            ReadData(deviceDataLength);
-            return;
-            }
-
-        if (deviceDataLength> aHostDataLength) // case  (13)
-
-            {
-            TRACE_INFO((_L("Case 13\n")))
-            /**
-             * Comment following line in order to pass compliant test.
-             * As spec said in case 13:"The device may receive data up to a
-             * total of dCBWDataTransferLength."
-             * Here we choose to ignore incoming data.
-             */
-            //StallEndpointAndWaitForClear(OutEndpoint); //Stall Out endpoint
-            if (iReadSetUp)
-                {
-                iLdd.Read(iStatus, OutEndpoint, iReadBuf, aHostDataLength);
-                User::WaitForRequest(iStatus);
-                iProtocol->ReadComplete(KErrGeneral);
-                iReadSetUp = EFalse;
-                }
-            SendCSW(iCbwTag, aHostDataLength, EPhaseError);
-            return;
-            }
-        }
-    }
-
-/**
- Prepare incase we need to read data from host
- Called in DecodeCBW(...)
- @param aHostDataLength The number of bytes to write to the host.
- */
-void CBulkOnlyTransport::PrepareWriteToHost(TUint aHostDataLength)
-    {
-    if (!iWriteSetUp) //write buffer was not set up 
-        {
-        TRACE_INFO((_L("Write buffer was not setup")))
-        iDataResidue =aHostDataLength;
-        TRACE_INFO((_L("DataResidue (write to host)=%d"),iDataResidue))
-
-        //------------------------------------
-        if (aHostDataLength <= KBOTMaxBufSize)
-            {
-            TRACE_INFO((_L("Case 4 or 8\n")))
-            iBuf.FillZ(aHostDataLength);
-            iLdd.Write(iStatus, InEndpoint, iBuf, aHostDataLength);
-            SetActive();
-            iCurrentState = EWritingData;
-            iStallAllowed = EFalse;
-            if (iReadSetUp) //read buffer WAS set up - case (8)
-
-                {
-                TRACE_INFO((_L("It is Case 8")))
-                iCmdStatus = EPhaseError;
-                }
-            return;
-            }
-        else
-        //------------------------------------
-        //					Use next block instead of StallEndpointAndWaitForClear(InEndpoint);
-
-            {
-            iBuf.FillZ(KBOTMaxBufSize);
-            TUint c =0;
-            TRequestStatus status;
-            while (c<aHostDataLength)
-                {
-                TInt len;
-                if (aHostDataLength - c> KBOTMaxBufSize)
-                    {
-                    len = KBOTMaxBufSize;
-                    }
-                else
-                    {
-                    len = aHostDataLength - c;
-                    }
-
-                iLdd.Write(status, InEndpoint, iBuf, len);
-                User::WaitForRequest(status);
-                c += KBOTMaxBufSize;
-                }
-            }
-
-        if (iReadSetUp) //read buffer WAS set up - case (8)
-            {
-            TRACE_INFO(_L("Case 8"));
-            SendCSW(iCbwTag, aHostDataLength, EPhaseError);
-            //don't care to reset any flag - should get reset recovery
-            }
-        else // case (4)
-            {
-            TRACE_INFO((_L("Case 4")))
-            SendCSW(iCbwTag, aHostDataLength, iCmdStatus);
-            }
-        return;
-        }
-    else
-        {
-        //================== 
-        TUint deviceDataLength = static_cast<TUint>(iWriteBuf.Length());
-        iDataResidue =aHostDataLength - deviceDataLength;
-        TRACE_INFO((_L("Device data length = %d, DataResidue (write to host)=%d"),
-                        deviceDataLength, iDataResidue))
-
-        if (deviceDataLength < aHostDataLength &&
-                aHostDataLength < KBOTMaxBufSize )
-            {
-            TRACE_INFO((_L("Case 5 (padding)\n")))
-            iBuf.Zero();
-            iBuf.Append(iWriteBuf);
-            iBuf.SetLength(aHostDataLength);
-            iStallAllowed = EFalse;
-            TRACE_INFO((_L("iBuf.Length=%d\n"),iBuf.Length()))
-            iLdd.Write(iStatus, InEndpoint, iBuf, aHostDataLength);
-            SetActive();
-            iCurrentState = EWritingData;
-            return;
-            }
-
-        //===================
-
-        if (deviceDataLength == aHostDataLength) //case (6)[==]
-
-            {
-            TRACE_INFO((_L("Case 6\n")))
-            WriteData(deviceDataLength);
-            return;
-            }
-        else if (deviceDataLength < aHostDataLength) //case (5)[<]
-
-            {
-            TRACE_INFO((_L("Case 5\n")))
-            WriteData(deviceDataLength, ETrue); // Send ZLP
-            return;
-            }
-        else // deviceDataLength > aHostDataLength - case (7)
-
-            {
-            TRACE_INFO((_L("Case 7\n")))
-            iCmdStatus = EPhaseError;
-            iDataResidue = 0;
-            WriteData(aHostDataLength);
-            return;
-            }
-        }
-    }
-
-/**
- Decode the CBW received from the host via OutEndpoint
-
- - If the header is valid, the data content is passed to the parser.
- - Depending on the command, more data may be transmitted/received.
- - ...or the CSW is sent (if not a data command).
-
- */
-void CBulkOnlyTransport::DecodeCBW()
-    {
-    TRACE_FUNC
-    if (!CheckCBW()) //check if CBW valid and meaningful
-
-        {
-        // CBW not valid or meaningful
-        // Specification says: "If the CBW is not valid, the device shall STALL
-        // the Bulk-In pipe. Also, the device shall either STALL the Bulk-Out pipe,
-        // or the device shall accept and discard any Bulk-Out data. The device
-        // shall maintain this state until a Reset Recovery."
-        // Here we keep bulk-in ep stalled and ignore bulk-out ep.
-        SetPermError();
-        return;
-        }
-
-    TPtrC8 aData;
-    aData.Set(&iCbwBuf[KCbwCbLengthOffset], KMaxCbwcbLength + 1); //prepare data for protocol starting form Length 
-    TUint8 lun = static_cast<TUint8> (iCbwBuf[13] & 0x0f);
-
-	iCbwTag  =	static_cast<TUint32>(iCbwBuf[KCbwTagOffset])		| 
-				static_cast<TUint32>(iCbwBuf[KCbwTagOffset+1])	<<8 | 
-				static_cast<TUint32>(iCbwBuf[KCbwTagOffset+2])	<<16| 
-				static_cast<TUint32>(iCbwBuf[KCbwTagOffset+3])	<<24;
-
-    TInt i = KCbwDataTransferLengthOffset;
-	TUint hostDataLength = 	static_cast<TUint32>(iCbwBuf[i  ])		| 
-							static_cast<TUint32>(iCbwBuf[i+1]) <<8 	| 
-							static_cast<TUint32>(iCbwBuf[i+2]) <<16	| 
-							static_cast<TUint32>(iCbwBuf[i+3]) <<24;
-
-    TBool dataToHost = iCbwBuf[KCbwFlagOffset] & 0x80;
-
-    TRACE_INFO((_L("lun =%d, hostDataLength=%d, CBWtag = 0x%X\n, dataToHost=%d"),
-                    lun, hostDataLength, iCbwTag, dataToHost))
-    //
-    TBool ret = iProtocol->DecodePacket(aData, lun);
-    //
-
-    iStallAllowed = ETrue;
-
-    if (!ret)
-        {
-        TRACE_INFO((_L("Command Failed")))
-        iCmdStatus = ECommandFailed;
-        }
-    else
-        {
-        TRACE_INFO((_L("Command Passed")))
-        iCmdStatus = ECommandPassed;
-        }
-
-    if (hostDataLength == 0)
-        {
-        TRACE_INFO((_L("No data transfer expected\n")))
-        iDataResidue = 0;
-        if (iWriteSetUp || iReadSetUp) // case (2) and (3)
-
-            {
-            TRACE_INFO((_L("Case 2 or 3\n")))
-            SendCSW(iCbwTag, 0, EPhaseError);
-            }
-        else
-            {
-            TRACE_INFO((_L("Case 1\n")))
-            SendCSW(iCbwTag, 0, iCmdStatus); //case (1)
-            }
-
-        return;
-        }
-    else
-        {
-        // Data Direction, To or From Host
-        if (dataToHost)
-            {
-            PrepareWriteToHost(hostDataLength);
-            }
-        else
-            {
-            PrepareReadFromHost(hostDataLength);
-            }
-        }
-    }
-
-/**
- Check if CBW Valid and Meaningful.  
-
- @return ETrue if CBW is Valid and Meaningful, EFalse otherwise
- */
-TBool CBulkOnlyTransport::CheckCBW()
-    {
-    TRACE_FUNC
-
-    // Check valid
-
-    // Check length
-    if (iCbwBuf.Length() != KCbwLength)
-        {
-        TRACE_INFO((_L("Bad length: %d"), iCbwBuf.Length()))
-        return EFalse;
-        }
-
-    // Check signature
-    TInt i = KCbwSignatureOffset;
-	if (iCbwBuf[i  ] != 0x55 ||         // CBW Singature from USB Bulk-Only Transport spec
-		iCbwBuf[i+1] != 0x53 ||
-		iCbwBuf[i+2] != 0x42 ||
-		iCbwBuf[i+3] != 0x43)
-        {
-        TRACE_INFO((_L("Bad signature")))
-        TRACE_INFO((_L(" 0x%x, 0x%x, 0x%x, 0x%x"),
-                        iCbwBuf[i], iCbwBuf[i+1], iCbwBuf[i+2],iCbwBuf[i+3]))
-        return EFalse;
-        }
-
-    // Check meaningful
-
-    // Check reserved bits ( must be zero )
-    if ((iCbwBuf[KCbwLunOffset] & 0xF0) || (iCbwBuf[KCbwCbLengthOffset] & 0xE0))
-        {
-        TRACE_INFO((_L("Reserved bits not zero\n")))
-        return EFalse;
-        }
-
-    // check command block length
-    TInt cbwcbLength = iCbwBuf[KCbwCbLengthOffset] & 0x1F;
-    if (cbwcbLength>KMaxCbwcbLength)
-        {
-        TRACE_INFO((_L("Incorrect block length\n")))
-        return EFalse;
-        }
-
-    //check LUN
-    TInt8 lun = static_cast<TUint8>(iCbwBuf[KCbwLunOffset] & 0x0f);
-    if (iMaxLun < lun)
-        {
-        TRACE_INFO((_L("bad lun: %d"), lun))
-        return EFalse;
-        }
-
-    return ETrue;
-    }
-
-/**
- Initiate stalling of bulk IN endpoint.
- Used when protocol wants to force host to initiate a reset recovery.
- */
-void CBulkOnlyTransport::SetPermError()
-    {
-    TRACE_FUNC
-    iCurrentState = EPermErr;
-    Activate(KErrNone);
-    }
-
-/**
- Send data provided by protocol to the host
-
- @param aLength amount of data (in bytes) to be send to host
- */
-void CBulkOnlyTransport::WriteData(TUint aLength, TBool aZlpRequired)
-    {
-    TRACE_FUNC
-
-    if (IsActive())
-        {
-        TRACE_INFO((_L("Still active")))
-        __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsBulkOnlyStillActive));
-        return;
-        }
-    iLdd.Write(iStatus, InEndpoint, iWriteBuf, aLength, aZlpRequired);
-    iCurrentState = EWritingData;
-    SetActive();
-    }
-
-/**
- Request data form the host for the protocol
-
- @param aLength amount of data (in bytes) to be received from the host
- */
-void CBulkOnlyTransport::ReadData(TUint aLength)
-    {
-    TRACE_FUNC
-    if (IsActive())
-        {
-        TRACE_INFO((_L("Still active")))
-        __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsBulkOnlyStillActive));
-        return;
-        }
-    iLdd.Read(iStatus, OutEndpoint, iReadBuf, aLength);
-    SetActive();
-    iCurrentState = EReadingData;
-    }
-
-/**
- Send Command Status Wrapper to the host
-
- @param aTag Echo of Command Block Tag sent by the host.
- @param aDataResidue the difference between the amount of data expected by the
- host, and the actual amount of data processed by the device.
- @param aStatus indicates the success or failure of the command.
- */
-void CBulkOnlyTransport::SendCSW(TUint aTag, TUint aDataResidue, TCswStatus aStatus)
-    {
-    TRACE_FUNC
-    TRACE_INFO((_L("DataResidue = %d, Status = %d \n"), aDataResidue, aStatus))
-
-    if (IsActive())
-        {
-        TRACE_INFO((_L("Still active")))
-        __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsSvrPncCat, EMsBulkOnlyStillActive));
-        return;
-        }
-    TBuf8<KCswLength> csw(KCswLength);
-
-    TInt i = KCswSingnatureOffset;
-    csw[i] = 0x55; // CSW Singature from USB Bulk-Only Transport spec
-    csw[i + 1] = 0x53;
-    csw[i + 2] = 0x42;
-    csw[i + 3] = 0x53;
-
-    i = KCswTagOffset;
-
-    csw[i] = static_cast<TUint8> ((aTag & 0x000000FF));
-    csw[i + 1] = static_cast<TUint8> ((aTag & 0x0000FF00) >> 8);
-    csw[i + 2] = static_cast<TUint8> ((aTag & 0x00FF0000) >> 16);
-    csw[i + 3] = static_cast<TUint8> ((aTag & 0xFF000000) >> 24);
-
-    i = KCswDataResidueOffset;
-    csw[i] = static_cast<TUint8> ((aDataResidue & 0x000000FF));
-    csw[i + 1] = static_cast<TUint8> ((aDataResidue & 0x0000FF00) >> 8);
-    csw[i + 2] = static_cast<TUint8> ((aDataResidue & 0x00FF0000) >> 16);
-    csw[i + 3] = static_cast<TUint8> ((aDataResidue & 0xFF000000) >> 24);
-
-    csw[KCswStatusOffset] = static_cast<TUint8> (aStatus);
-
-    iLdd.Write(iStatus, InEndpoint, csw, KCswLength);
-
-    iCurrentState = ESendingCSW;
-
-    SetActive();
-    }
-
-/**
- Associates the transport with the protocol.  Called during initialization of the controller.
-
- @param aProtocol reference to the protocol
- */
-void CBulkOnlyTransport::RegisterProtocol(MProtocolBase& aProtocol)
-    {
-    TRACE_FUNC
-    iProtocol = &aProtocol;
-    }
-
-/**
- Used by CControlInterface
-
- @return reference to the controller which instantiate the CBulkOnlyTransport
- */
-CMscFileController& CBulkOnlyTransport::Controller()
-    {
-    return iController;
-    }
-
-/**
- @return the number of logical units supported by the device. 
- Logical Unit Numbers on the device shall be numbered contiguously starting from LUN
- 0 to a maximum LUN of 15 (Fh).
- */
-TInt CBulkOnlyTransport::MaxLun()
-    {
-    return iMaxLun;
-    }
-
-/**
- Used by CControlInterface
- @return reference to USB logical driver
- */
-RDevUsbcClient& CBulkOnlyTransport::Ldd()
-    {
-    return iLdd;
-    }
-
-
-void CBulkOnlyTransport::StallEndpointAndWaitForClear(TEndpointNumber aEndpoint)
-    {
-    TRACE_FUNC
-    __ASSERT_DEBUG(aEndpoint != EEndpoint0, User::Panic(KUsbMsSvrPncCat, EMsWrongEndpoint));
-
-    // Now stall this endpoint
-    TRACE_INFO((_L("Stalling endpoint %d"), aEndpoint))
-    TInt r = iLdd.HaltEndpoint(aEndpoint);
-    if (r != KErrNone)
-        {
-        TRACE_ERROR((_L("Error: stalling ep %d failed: %d"), aEndpoint, r))
-        }
-    TEndpointState ep_state;
-    TInt i = 0;
-    do
-        {
-        // Wait for 10ms before checking the ep status
-        User::After(10000);
-        iLdd.EndpointStatus(aEndpoint, ep_state);
-        if (++i >= 1000)
-            {
-            // 10 secs should be enough
-            TRACE_ERROR((_L("Error: Checked for ep %d de-stall %d seconds - giving up now..."),
-                            aEndpoint, i / 100))
-            // We can only hope for a Reset Recovery
-            return;
-            }
-        }while ((ep_state == EEndpointStateStalled) && iStarted);
-    TRACE_INFO((_L("Checked for ep %d de-stall: %d time(s)"), aEndpoint, i))
-    }
-
-/**
- * Read out rest data from OutEndpoint and discard them
- */
-void CBulkOnlyTransport::ReadAndDiscardData(TInt aBytes)
-    {
-    TRACE_FUNC
-    const TUint bufsize = static_cast<TUint>(iReadBuf.Length());
-    __ASSERT_ALWAYS(bufsize> 0, User::Panic(_L("Buffer size is zero"), bufsize));
-    TRequestStatus status;
-    while (aBytes> 0)
-        {
-        TRACE_INFO((_L("Bytes still to be read: %d\n"), aBytes))
-        iLdd.ReadOneOrMore(status, OutEndpoint, iReadBuf, bufsize);
-        User::WaitForRequest(status);
-        TInt err = status.Int();
-        if (err != KErrNone)
-            {
-            // Bad.
-            break;
-            }
-        aBytes -= iReadBuf.Length();
-        }
-    iReadBuf.SetLength(bufsize);
-    }
-
-/**
- Called by the protocol to determine how many bytes of data are available in the read buffer. 
-
- @return The number of bytes available in the read buffer
- */
-TInt CBulkOnlyTransport::BytesAvailable()
-    {
-    TInt bytes = 0;
-    TInt err = iLdd.QueryReceiveBuffer(OutEndpoint, bytes);
-    if (err != KErrNone)
-        bytes = 0;
-    return bytes;
-    }
-
-//
-// --- class CActiveDeviceStateNotifier ---------------------------------------------------------
-//
-CActiveDeviceStateNotifier::CActiveDeviceStateNotifier(CBulkOnlyTransport& aParent)
-/**
- *
- */
-	: CActive(EPriorityStandard),
-	  iParent(aParent),
-	  iDeviceState(EUsbcNoState),
-            iOldDeviceState(EUsbcNoState)
-    {
-
-    }
-
-
-CActiveDeviceStateNotifier* CActiveDeviceStateNotifier::NewL(CBulkOnlyTransport& aParent)
-/**
- *
- */
-    {
-	CActiveDeviceStateNotifier* self = new (ELeave) CActiveDeviceStateNotifier(aParent);
-    CleanupStack::PushL(self);
-    self->ConstructL();
-    CActiveScheduler::Add(self);
-    CleanupStack::Pop(); // self
-    return (self);
-    }
-
-void CActiveDeviceStateNotifier::ConstructL()
-/**
- *
- */
-    {
-    TRACE_FUNC
-	}
-
-CActiveDeviceStateNotifier::~CActiveDeviceStateNotifier()
-/**
- *
- */
-    {
-    TRACE_FUNC
-    Cancel();												// base class
-    }
-
-void CActiveDeviceStateNotifier::DoCancel()
-/**
- *
- */
-    {
-    TRACE_FUNC
-    iParent.Ldd().AlternateDeviceStatusNotifyCancel();
-    }
-
-void CActiveDeviceStateNotifier::RunL()
-/**
- *
- */
-    {
-    TRACE_FUNC
-    // This displays the device state.
-    // In a real world program, the user could take here appropriate action (cancel a
-    // transfer request or whatever).
-    if (!(iDeviceState & KUsbAlternateSetting))
-        {
-
-        switch (iDeviceState)
-            {
-            case EUsbcDeviceStateUndefined:
-            TRACE_INFO((_L("Device State notifier: Undefined\n")))
-            iParent.HwStop();
-            break;
-            case EUsbcDeviceStateAttached:
-            TRACE_INFO((_L("Device State notifier: Attached\n")))
-            iParent.HwStop();
-            break;
-            case EUsbcDeviceStatePowered:
-            TRACE_INFO((_L("Device State notifier: Powered\n")))
-            iParent.HwStop();
-            break;
-            case EUsbcDeviceStateDefault:
-            TRACE_INFO((_L("Device State notifier: Default\n")))
-            iParent.HwStop();
-            break;
-            case EUsbcDeviceStateAddress:
-            TRACE_INFO((_L("Device State notifier: Address\n")))
-            iParent.HwStop();
-            break;
-            case EUsbcDeviceStateConfigured:
-            TRACE_INFO((_L("Device State notifier: Configured\n")))
-            if (iOldDeviceState == EUsbcDeviceStateSuspended)
-                {
-                iParent.HwResume();
-                }
-            else
-                {
-                iParent.HwStart();
-                }
-            break;
-            case EUsbcDeviceStateSuspended:
-            TRACE_INFO((_L("Device State notifier: Suspended\n")))
-            if (iOldDeviceState == EUsbcDeviceStateConfigured)
-                {
-                iParent.HwSuspend();
-                }
-            break;
-            default:
-            TRACE_INFO((_L("Device State notifier: ***BAD***\n")))
-            iParent.HwStop();
-            break;
-            }
-        iOldDeviceState = iDeviceState;
-        }
-    else if (iDeviceState & KUsbAlternateSetting)
-        {
-        TRACE_INFO((_L("Device State notifier: Alternate interface setting has changed: now %d\n"),
-                        iDeviceState & ~KUsbAlternateSetting))
-        }
-    Activate();
-    }
-
-void CActiveDeviceStateNotifier::Activate()
-/**
- *
- */
-    {
-    TRACE_FUNC
-    if (IsActive())
-        {
-        TRACE_INFO((_L("Still active")))
-        return;
-        }
-    iParent.Ldd().AlternateDeviceStatusNotify(iStatus, iDeviceState);
-    SetActive();
-    }
-