diff -r 000000000000 -r bde4ae8d615e os/kernelhwsrv/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/drivepublisher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/kernelhwsrv/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/drivepublisher.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,434 @@ +// 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 the License "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: +// Class implementation of the drive publishing classes - +// RDriveMediaErrorPublisher, +// RDriveStateChangedPublisher, +// CDriveTransferPublisher, +// CDriveWriteTransferPublisher, +// CDriveReadTransferPublisher, +// CUsbTransferPublisher, +// CUsbReadTransferPublisher, +// CUsbReadTransferPublisher. +// +// + + + +/** + @file + @internalTechnology +*/ + +#include +#include +#include +#include + +#include "mstypes.h" +#include "msctypes.h" +#include "usbmsshared.h" + +#include "drivepublisher.h" +#include "drivemanager.h" +#include "debug.h" +#include "msdebug.h" + +// +// Use Lookup table to translate from the internal pair of state variables +// to the externally published drive state code. +// +LOCAL_D const TUint8 table[][5] = +{ +//TMountState=EDisconnected + {EUsbMsDriveState_Disconnected, + EUsbMsDriveState_Disconnected, + EUsbMsDriveState_Disconnected, + EUsbMsDriveState_Disconnected, + EUsbMsDriveState_Disconnected}, +//TMountState=EConnecting + {EUsbMsDriveState_Connecting, + EUsbMsDriveState_Connecting, + EUsbMsDriveState_Connecting, + EUsbMsDriveState_Connecting, + EUsbMsDriveState_Connecting}, +//TMountState=EConnected + //EIdle,EActive,ELocked,EMediaNotPresent,EErrDisMounted + {EUsbMsDriveState_Connected, + EUsbMsDriveState_Active, + EUsbMsDriveState_Locked, + EUsbMsDriveState_MediaNotPresent, + EUsbMsDriveState_Removed}, +//TMountState=EDisconnecting + {EUsbMsDriveState_Disconnecting, + EUsbMsDriveState_Disconnecting, + EUsbMsDriveState_Disconnecting, + EUsbMsDriveState_Disconnecting, + EUsbMsDriveState_Disconnecting} +}; + + +//---------------------------------------------------------------------------- +/** +Constructor +*/ +RDriveMediaErrorPublisher::RDriveMediaErrorPublisher() + { + __MSFNLOG + _LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy); + _LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid); + + TInt result = RProperty::Define(EUsbMsDriveState_MediaError, RProperty::EInt, + KMassStorageReadPolicy, KMassStorageWritePolicy); + + __ASSERT_DEBUG(result == KErrAlreadyExists || result == KErrNone, User::Invariant()); + + result = iMediaErrorProperty.Attach(KUsbMsDriveState_Category, EUsbMsDriveState_MediaError); + __ASSERT_DEBUG(result == KErrNone, User::Invariant()); + } + + +RDriveMediaErrorPublisher::~RDriveMediaErrorPublisher() + { + __MSFNLOG + iMediaErrorProperty.Close(); + RProperty::Delete(KUsbMsDriveState_Category, EUsbMsDriveState_MediaError); + } + +/** +Publishing method + +Publishes the Media Error property event + +@param aError ETrue if drive media has an error else EFalse for no error +*/ +void RDriveMediaErrorPublisher::PublishErrorL(TBool aError) + { + __MSFNLOG + __PRINT1(_L("<< RDriveMediaErrorPublisher::PublishError %x"), aError); + + TInt oldValue; + iMediaErrorProperty.Get(oldValue); + + if (oldValue != aError) + { + User::LeaveIfError(iMediaErrorProperty.Set(aError)); + } + } + +//---------------------------------------------------------------------------- +/** +Constructor + +@param aDrives +@param aDriveMap +*/ +RDriveStateChangedPublisher::RDriveStateChangedPublisher(const TMsDriveList& aDrives, + const TLunToDriveMap& aDriveMap) + : + iDrives(aDrives), + iDriveMap(aDriveMap) + { + __MSFNLOG + _LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy); + _LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid); + + TInt result = RProperty::Define(KUsbMsDriveState_Category, + EUsbMsDriveState_DriveStatus, RProperty::EByteArray, + KMassStorageReadPolicy, KMassStorageWritePolicy, + KUsbMsMaxDrives*2); + __ASSERT_DEBUG(result == KErrAlreadyExists || result == KErrNone, User::Invariant()); + result = result; // remove urel warning + } + + +RDriveStateChangedPublisher::~RDriveStateChangedPublisher() + { + __MSFNLOG + RProperty::Delete(KUsbMsDriveState_Category, EUsbMsDriveState_DriveStatus); + } + + +/** +Publishing method + +Sends a property event on behalf of CMassStorageDrive, with the mountstate and drivestate +values encoded into one 32-bit word. +*/ +void RDriveStateChangedPublisher::DriveStateChanged() + { + __MSFNLOG + TUsbMsDrivesStatus allDrivesStatus; + + for(TUint8 i = 0; i < iDrives.Count(); i++) + { + allDrivesStatus.Append(iDriveMap[i]); + + CMassStorageDrive::TMountState ms = iDrives[i]->MountState(); + TLocalDriveRef::TDriveState ds = iDrives[i]->DriveState(); + TInt driveStatus = EUsbMsDriveState_Error; + if((TUint8)ds < sizeof(table[0]) && (TUint8)ms < sizeof(table)/sizeof(table[0])) + { + driveStatus = table[ms][ds]; + __PRINT3(_L("ms=%d ds=%d %d"), ms, ds, driveStatus); + } + allDrivesStatus.Append(driveStatus); + } + + + __PRINT1(_L("Publishing EUsbMsDriveState_DriveStatus for %d drives\n"), + allDrivesStatus.Length()/2); + + if(KErrNone != RProperty::Set(KUsbMsDriveState_Category, + EUsbMsDriveState_DriveStatus, + allDrivesStatus)) + { + __ASSERT_DEBUG(EFalse,User::Invariant()); + } + } + + +//---------------------------------------------------------------------------- + +/** +Private default constructor to ensure that NewL is used + +@param aSubKey +@param aArray +*/ +CUsbTransferPublisher::CUsbTransferPublisher(TUsbMsDriveState_Subkey aSubKey, + const TBytesTransferedList& aArray) +: iSubKey(aSubKey), + iArray(aArray) + { + __MSFNLOG + } + + +void CUsbTransferPublisher::ConstructL() + { + __MSFNLOG + + _LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy); + _LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid); + + TInt r = RProperty::Define(iSubKey, RProperty::EByteArray, + KMassStorageReadPolicy, KMassStorageWritePolicy, + KUsbMsMaxDrives*sizeof(TInt)); + + if (r != KErrAlreadyExists) + { + User::LeaveIfError(r); + } + + // Attach to the properties here. Only do this once, continuously attaching + // will currently cause a memory leak + User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, iSubKey)); + + // Create the EDataTransferred timer + iTimer = CPeriodic::NewL(CActive::EPriorityStandard); + iTimerRunning = EFalse; + } + + +/** +Destructor +*/ +CUsbTransferPublisher::~CUsbTransferPublisher() + { + __MSFNLOG + if(iTimer) + { + iTimer->Cancel(); + } + delete iTimer; + iProperty.Close(); + + RProperty::Delete(KUsbMsDriveState_Category, iSubKey); + } + + +/** +A static wrapper for the DoPublishDataTransferredEvent member function +for use as a timer callback function. + +@param obj 'this' pointer +@return not used in CPeriodic callback (see TCallback) +*/ +TInt CUsbTransferPublisher::PublishDataTransferredEvent(TAny* obj) + { + __MSFNSLOG + static_cast(obj)->DoPublishDataTransferredEvent(); + return 1; + } + + +/** +Update the data transferred properties if the counts have changed since +the last update. +*/ +void CUsbTransferPublisher::DoPublishDataTransferredEvent() + { + __MSFNLOG + if (PublishDataTransferred()) + { + // some data has been transfered so reset the counter + iTimerCancelCnt = ETimerCancelDelay; + } + + // Update the cancel count if no data was transferred the last + // (few) times this has been called + if (--iTimerCancelCnt == 0) + { + StopTimer(); + iTimerCancelCnt = ETimerCancelDelay; + } + } + + +/** +Update the data transferred properties if the counts have changed since +the last update. +*/ +TBool CUsbTransferPublisher::PublishDataTransferred() + { + __MSFNLOG + TUsbMsBytesTransferred bytesTransferred; + TBool dataTransferred = EFalse; + + for (TInt i = 0; i < iArray.Count(); i++) + { + bytesTransferred[i] = GetBytesTransferred(i); + } + + // Update the properties only if they have changed + // (or if there's an error reading the old value.) + // Possible optimisation: keep a copy of the value + // as a member variable so we don't need the Get. + TUsbMsBytesTransferred oldValue; + + if ((iProperty.Get(oldValue) != KErrNone) || (oldValue != bytesTransferred)) + { +#ifdef __PRINT3 + // trace of the bytes transferred + for (TInt j=0; j < iArray.Count(); j++) + { + if(oldValue[j] != bytesTransferred[j]) + { + __PRINT3(_L("CDrivePublisher: KBytes[%d] %d->%d\n"), j, oldValue[j], bytesTransferred[j]); + } + } +#endif + if (KErrNone != iProperty.Set(bytesTransferred)) + { + __ASSERT_DEBUG(EFalse, User::Invariant()); + } + dataTransferred = ETrue; + } + + return dataTransferred; + } + + +/** +Starts timer to periodically publish results. +If the timer is not yet running then start it. +*/ +void CUsbTransferPublisher::StartTimer() + { + __MSFNLOG + if (!iTimerRunning) + { + // EDataTransferred event every second + const TTimeIntervalMicroSeconds32 interval = 1 * 1000 * 1000; + TCallBack callback(PublishDataTransferredEvent, this); + __PRINT(_L("Starting timer")); + iTimer->Start(interval, interval, callback); + iTimerRunning = ETrue; + } + } + + +/** +Ensure that the Timer is stopped +*/ +void CUsbTransferPublisher::StopTimer() + { + __MSFNLOG + if (iTimerRunning) + { + __PRINT(_L("Stopping timer")); + iTimer->Cancel(); + iTimerRunning = EFalse; + } + } + + +//---------------------------------------------------------------------------- +/** +Constructor for Write property + +@param aArray +*/ +CUsbWriteTransferPublisher* CUsbWriteTransferPublisher::NewL(const TBytesTransferedList& aArray) + { + __MSFNSLOG + CUsbWriteTransferPublisher* self = new (ELeave) CUsbWriteTransferPublisher(aArray); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + + +CUsbWriteTransferPublisher::CUsbWriteTransferPublisher(const TBytesTransferedList& aArray) +: CUsbTransferPublisher(EUsbMsDriveState_KBytesWritten, aArray) + { + __MSFNLOG + } + + +//---------------------------------------------------------------------------- +/** +Constructor for Read property + +@param aArray +*/ +CUsbReadTransferPublisher* CUsbReadTransferPublisher::NewL(const TBytesTransferedList& aArray) + { + __MSFNSLOG + CUsbReadTransferPublisher* self = new (ELeave) CUsbReadTransferPublisher(aArray); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + + +CUsbReadTransferPublisher::CUsbReadTransferPublisher(const TBytesTransferedList& aArray) +: CUsbTransferPublisher(EUsbMsDriveState_KBytesRead, aArray) + { + __MSFNLOG + } + +/** +Transfer function for the property + +@return Cumulative bytes read since the host connected to the drive, + in multiples of KBytesPerKilobyte rounded to nearest integer value. + The KBytes refer to multiples of 1000, not 1024. +*/ +TUint CUsbTransferPublisher::GetBytesTransferred(TLun aLun) const +{ + return I64LOW(iArray[aLun] / (TUint64)1000); +}