os/kernelhwsrv/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/drivepublisher.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/drivepublisher.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,434 @@
1.4 +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// Class implementation of the drive publishing classes -
1.18 +// RDriveMediaErrorPublisher,
1.19 +// RDriveStateChangedPublisher,
1.20 +// CDriveTransferPublisher,
1.21 +// CDriveWriteTransferPublisher,
1.22 +// CDriveReadTransferPublisher,
1.23 +// CUsbTransferPublisher,
1.24 +// CUsbReadTransferPublisher,
1.25 +// CUsbReadTransferPublisher.
1.26 +//
1.27 +//
1.28 +
1.29 +
1.30 +
1.31 +/**
1.32 + @file
1.33 + @internalTechnology
1.34 +*/
1.35 +
1.36 +#include <e32std.h>
1.37 +#include <e32base.h>
1.38 +#include <e32property.h>
1.39 +#include <f32file.h>
1.40 +
1.41 +#include "mstypes.h"
1.42 +#include "msctypes.h"
1.43 +#include "usbmsshared.h"
1.44 +
1.45 +#include "drivepublisher.h"
1.46 +#include "drivemanager.h"
1.47 +#include "debug.h"
1.48 +#include "msdebug.h"
1.49 +
1.50 +//
1.51 +// Use Lookup table to translate from the internal pair of state variables
1.52 +// to the externally published drive state code.
1.53 +//
1.54 +LOCAL_D const TUint8 table[][5] =
1.55 +{
1.56 +//TMountState=EDisconnected
1.57 + {EUsbMsDriveState_Disconnected,
1.58 + EUsbMsDriveState_Disconnected,
1.59 + EUsbMsDriveState_Disconnected,
1.60 + EUsbMsDriveState_Disconnected,
1.61 + EUsbMsDriveState_Disconnected},
1.62 +//TMountState=EConnecting
1.63 + {EUsbMsDriveState_Connecting,
1.64 + EUsbMsDriveState_Connecting,
1.65 + EUsbMsDriveState_Connecting,
1.66 + EUsbMsDriveState_Connecting,
1.67 + EUsbMsDriveState_Connecting},
1.68 +//TMountState=EConnected
1.69 + //EIdle,EActive,ELocked,EMediaNotPresent,EErrDisMounted
1.70 + {EUsbMsDriveState_Connected,
1.71 + EUsbMsDriveState_Active,
1.72 + EUsbMsDriveState_Locked,
1.73 + EUsbMsDriveState_MediaNotPresent,
1.74 + EUsbMsDriveState_Removed},
1.75 +//TMountState=EDisconnecting
1.76 + {EUsbMsDriveState_Disconnecting,
1.77 + EUsbMsDriveState_Disconnecting,
1.78 + EUsbMsDriveState_Disconnecting,
1.79 + EUsbMsDriveState_Disconnecting,
1.80 + EUsbMsDriveState_Disconnecting}
1.81 +};
1.82 +
1.83 +
1.84 +//----------------------------------------------------------------------------
1.85 +/**
1.86 +Constructor
1.87 +*/
1.88 +RDriveMediaErrorPublisher::RDriveMediaErrorPublisher()
1.89 + {
1.90 + __MSFNLOG
1.91 + _LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
1.92 + _LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
1.93 +
1.94 + TInt result = RProperty::Define(EUsbMsDriveState_MediaError, RProperty::EInt,
1.95 + KMassStorageReadPolicy, KMassStorageWritePolicy);
1.96 +
1.97 + __ASSERT_DEBUG(result == KErrAlreadyExists || result == KErrNone, User::Invariant());
1.98 +
1.99 + result = iMediaErrorProperty.Attach(KUsbMsDriveState_Category, EUsbMsDriveState_MediaError);
1.100 + __ASSERT_DEBUG(result == KErrNone, User::Invariant());
1.101 + }
1.102 +
1.103 +
1.104 +RDriveMediaErrorPublisher::~RDriveMediaErrorPublisher()
1.105 + {
1.106 + __MSFNLOG
1.107 + iMediaErrorProperty.Close();
1.108 + RProperty::Delete(KUsbMsDriveState_Category, EUsbMsDriveState_MediaError);
1.109 + }
1.110 +
1.111 +/**
1.112 +Publishing method
1.113 +
1.114 +Publishes the Media Error property event
1.115 +
1.116 +@param aError ETrue if drive media has an error else EFalse for no error
1.117 +*/
1.118 +void RDriveMediaErrorPublisher::PublishErrorL(TBool aError)
1.119 + {
1.120 + __MSFNLOG
1.121 + __PRINT1(_L("<< RDriveMediaErrorPublisher::PublishError %x"), aError);
1.122 +
1.123 + TInt oldValue;
1.124 + iMediaErrorProperty.Get(oldValue);
1.125 +
1.126 + if (oldValue != aError)
1.127 + {
1.128 + User::LeaveIfError(iMediaErrorProperty.Set(aError));
1.129 + }
1.130 + }
1.131 +
1.132 +//----------------------------------------------------------------------------
1.133 +/**
1.134 +Constructor
1.135 +
1.136 +@param aDrives
1.137 +@param aDriveMap
1.138 +*/
1.139 +RDriveStateChangedPublisher::RDriveStateChangedPublisher(const TMsDriveList& aDrives,
1.140 + const TLunToDriveMap& aDriveMap)
1.141 + :
1.142 + iDrives(aDrives),
1.143 + iDriveMap(aDriveMap)
1.144 + {
1.145 + __MSFNLOG
1.146 + _LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
1.147 + _LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
1.148 +
1.149 + TInt result = RProperty::Define(KUsbMsDriveState_Category,
1.150 + EUsbMsDriveState_DriveStatus, RProperty::EByteArray,
1.151 + KMassStorageReadPolicy, KMassStorageWritePolicy,
1.152 + KUsbMsMaxDrives*2);
1.153 + __ASSERT_DEBUG(result == KErrAlreadyExists || result == KErrNone, User::Invariant());
1.154 + result = result; // remove urel warning
1.155 + }
1.156 +
1.157 +
1.158 +RDriveStateChangedPublisher::~RDriveStateChangedPublisher()
1.159 + {
1.160 + __MSFNLOG
1.161 + RProperty::Delete(KUsbMsDriveState_Category, EUsbMsDriveState_DriveStatus);
1.162 + }
1.163 +
1.164 +
1.165 +/**
1.166 +Publishing method
1.167 +
1.168 +Sends a property event on behalf of CMassStorageDrive, with the mountstate and drivestate
1.169 +values encoded into one 32-bit word.
1.170 +*/
1.171 +void RDriveStateChangedPublisher::DriveStateChanged()
1.172 + {
1.173 + __MSFNLOG
1.174 + TUsbMsDrivesStatus allDrivesStatus;
1.175 +
1.176 + for(TUint8 i = 0; i < iDrives.Count(); i++)
1.177 + {
1.178 + allDrivesStatus.Append(iDriveMap[i]);
1.179 +
1.180 + CMassStorageDrive::TMountState ms = iDrives[i]->MountState();
1.181 + TLocalDriveRef::TDriveState ds = iDrives[i]->DriveState();
1.182 + TInt driveStatus = EUsbMsDriveState_Error;
1.183 + if((TUint8)ds < sizeof(table[0]) && (TUint8)ms < sizeof(table)/sizeof(table[0]))
1.184 + {
1.185 + driveStatus = table[ms][ds];
1.186 + __PRINT3(_L("ms=%d ds=%d %d"), ms, ds, driveStatus);
1.187 + }
1.188 + allDrivesStatus.Append(driveStatus);
1.189 + }
1.190 +
1.191 +
1.192 + __PRINT1(_L("Publishing EUsbMsDriveState_DriveStatus for %d drives\n"),
1.193 + allDrivesStatus.Length()/2);
1.194 +
1.195 + if(KErrNone != RProperty::Set(KUsbMsDriveState_Category,
1.196 + EUsbMsDriveState_DriveStatus,
1.197 + allDrivesStatus))
1.198 + {
1.199 + __ASSERT_DEBUG(EFalse,User::Invariant());
1.200 + }
1.201 + }
1.202 +
1.203 +
1.204 +//----------------------------------------------------------------------------
1.205 +
1.206 +/**
1.207 +Private default constructor to ensure that NewL is used
1.208 +
1.209 +@param aSubKey
1.210 +@param aArray
1.211 +*/
1.212 +CUsbTransferPublisher::CUsbTransferPublisher(TUsbMsDriveState_Subkey aSubKey,
1.213 + const TBytesTransferedList& aArray)
1.214 +: iSubKey(aSubKey),
1.215 + iArray(aArray)
1.216 + {
1.217 + __MSFNLOG
1.218 + }
1.219 +
1.220 +
1.221 +void CUsbTransferPublisher::ConstructL()
1.222 + {
1.223 + __MSFNLOG
1.224 +
1.225 + _LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
1.226 + _LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
1.227 +
1.228 + TInt r = RProperty::Define(iSubKey, RProperty::EByteArray,
1.229 + KMassStorageReadPolicy, KMassStorageWritePolicy,
1.230 + KUsbMsMaxDrives*sizeof(TInt));
1.231 +
1.232 + if (r != KErrAlreadyExists)
1.233 + {
1.234 + User::LeaveIfError(r);
1.235 + }
1.236 +
1.237 + // Attach to the properties here. Only do this once, continuously attaching
1.238 + // will currently cause a memory leak
1.239 + User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, iSubKey));
1.240 +
1.241 + // Create the EDataTransferred timer
1.242 + iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
1.243 + iTimerRunning = EFalse;
1.244 + }
1.245 +
1.246 +
1.247 +/**
1.248 +Destructor
1.249 +*/
1.250 +CUsbTransferPublisher::~CUsbTransferPublisher()
1.251 + {
1.252 + __MSFNLOG
1.253 + if(iTimer)
1.254 + {
1.255 + iTimer->Cancel();
1.256 + }
1.257 + delete iTimer;
1.258 + iProperty.Close();
1.259 +
1.260 + RProperty::Delete(KUsbMsDriveState_Category, iSubKey);
1.261 + }
1.262 +
1.263 +
1.264 +/**
1.265 +A static wrapper for the DoPublishDataTransferredEvent member function
1.266 +for use as a timer callback function.
1.267 +
1.268 +@param obj 'this' pointer
1.269 +@return not used in CPeriodic callback (see TCallback)
1.270 +*/
1.271 +TInt CUsbTransferPublisher::PublishDataTransferredEvent(TAny* obj)
1.272 + {
1.273 + __MSFNSLOG
1.274 + static_cast<CUsbTransferPublisher*>(obj)->DoPublishDataTransferredEvent();
1.275 + return 1;
1.276 + }
1.277 +
1.278 +
1.279 +/**
1.280 +Update the data transferred properties if the counts have changed since
1.281 +the last update.
1.282 +*/
1.283 +void CUsbTransferPublisher::DoPublishDataTransferredEvent()
1.284 + {
1.285 + __MSFNLOG
1.286 + if (PublishDataTransferred())
1.287 + {
1.288 + // some data has been transfered so reset the counter
1.289 + iTimerCancelCnt = ETimerCancelDelay;
1.290 + }
1.291 +
1.292 + // Update the cancel count if no data was transferred the last
1.293 + // (few) times this has been called
1.294 + if (--iTimerCancelCnt == 0)
1.295 + {
1.296 + StopTimer();
1.297 + iTimerCancelCnt = ETimerCancelDelay;
1.298 + }
1.299 + }
1.300 +
1.301 +
1.302 +/**
1.303 +Update the data transferred properties if the counts have changed since
1.304 +the last update.
1.305 +*/
1.306 +TBool CUsbTransferPublisher::PublishDataTransferred()
1.307 + {
1.308 + __MSFNLOG
1.309 + TUsbMsBytesTransferred bytesTransferred;
1.310 + TBool dataTransferred = EFalse;
1.311 +
1.312 + for (TInt i = 0; i < iArray.Count(); i++)
1.313 + {
1.314 + bytesTransferred[i] = GetBytesTransferred(i);
1.315 + }
1.316 +
1.317 + // Update the properties only if they have changed
1.318 + // (or if there's an error reading the old value.)
1.319 + // Possible optimisation: keep a copy of the value
1.320 + // as a member variable so we don't need the Get.
1.321 + TUsbMsBytesTransferred oldValue;
1.322 +
1.323 + if ((iProperty.Get(oldValue) != KErrNone) || (oldValue != bytesTransferred))
1.324 + {
1.325 +#ifdef __PRINT3
1.326 + // trace of the bytes transferred
1.327 + for (TInt j=0; j < iArray.Count(); j++)
1.328 + {
1.329 + if(oldValue[j] != bytesTransferred[j])
1.330 + {
1.331 + __PRINT3(_L("CDrivePublisher: KBytes[%d] %d->%d\n"), j, oldValue[j], bytesTransferred[j]);
1.332 + }
1.333 + }
1.334 +#endif
1.335 + if (KErrNone != iProperty.Set(bytesTransferred))
1.336 + {
1.337 + __ASSERT_DEBUG(EFalse, User::Invariant());
1.338 + }
1.339 + dataTransferred = ETrue;
1.340 + }
1.341 +
1.342 + return dataTransferred;
1.343 + }
1.344 +
1.345 +
1.346 +/**
1.347 +Starts timer to periodically publish results.
1.348 +If the timer is not yet running then start it.
1.349 +*/
1.350 +void CUsbTransferPublisher::StartTimer()
1.351 + {
1.352 + __MSFNLOG
1.353 + if (!iTimerRunning)
1.354 + {
1.355 + // EDataTransferred event every second
1.356 + const TTimeIntervalMicroSeconds32 interval = 1 * 1000 * 1000;
1.357 + TCallBack callback(PublishDataTransferredEvent, this);
1.358 + __PRINT(_L("Starting timer"));
1.359 + iTimer->Start(interval, interval, callback);
1.360 + iTimerRunning = ETrue;
1.361 + }
1.362 + }
1.363 +
1.364 +
1.365 +/**
1.366 +Ensure that the Timer is stopped
1.367 +*/
1.368 +void CUsbTransferPublisher::StopTimer()
1.369 + {
1.370 + __MSFNLOG
1.371 + if (iTimerRunning)
1.372 + {
1.373 + __PRINT(_L("Stopping timer"));
1.374 + iTimer->Cancel();
1.375 + iTimerRunning = EFalse;
1.376 + }
1.377 + }
1.378 +
1.379 +
1.380 +//----------------------------------------------------------------------------
1.381 +/**
1.382 +Constructor for Write property
1.383 +
1.384 +@param aArray
1.385 +*/
1.386 +CUsbWriteTransferPublisher* CUsbWriteTransferPublisher::NewL(const TBytesTransferedList& aArray)
1.387 + {
1.388 + __MSFNSLOG
1.389 + CUsbWriteTransferPublisher* self = new (ELeave) CUsbWriteTransferPublisher(aArray);
1.390 + CleanupStack::PushL(self);
1.391 + self->ConstructL();
1.392 + CleanupStack::Pop();
1.393 + return self;
1.394 + }
1.395 +
1.396 +
1.397 +CUsbWriteTransferPublisher::CUsbWriteTransferPublisher(const TBytesTransferedList& aArray)
1.398 +: CUsbTransferPublisher(EUsbMsDriveState_KBytesWritten, aArray)
1.399 + {
1.400 + __MSFNLOG
1.401 + }
1.402 +
1.403 +
1.404 +//----------------------------------------------------------------------------
1.405 +/**
1.406 +Constructor for Read property
1.407 +
1.408 +@param aArray
1.409 +*/
1.410 +CUsbReadTransferPublisher* CUsbReadTransferPublisher::NewL(const TBytesTransferedList& aArray)
1.411 + {
1.412 + __MSFNSLOG
1.413 + CUsbReadTransferPublisher* self = new (ELeave) CUsbReadTransferPublisher(aArray);
1.414 + CleanupStack::PushL(self);
1.415 + self->ConstructL();
1.416 + CleanupStack::Pop();
1.417 + return self;
1.418 + }
1.419 +
1.420 +
1.421 +CUsbReadTransferPublisher::CUsbReadTransferPublisher(const TBytesTransferedList& aArray)
1.422 +: CUsbTransferPublisher(EUsbMsDriveState_KBytesRead, aArray)
1.423 + {
1.424 + __MSFNLOG
1.425 + }
1.426 +
1.427 +/**
1.428 +Transfer function for the property
1.429 +
1.430 +@return Cumulative bytes read since the host connected to the drive,
1.431 + in multiples of KBytesPerKilobyte rounded to nearest integer value.
1.432 + The KBytes refer to multiples of 1000, not 1024.
1.433 +*/
1.434 +TUint CUsbTransferPublisher::GetBytesTransferred(TLun aLun) const
1.435 +{
1.436 + return I64LOW(iArray[aLun] / (TUint64)1000);
1.437 +}