os/kernelhwsrv/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/drivepublisher.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Class implementation of the drive publishing classes -
    15 // RDriveMediaErrorPublisher,
    16 // RDriveStateChangedPublisher,
    17 // CDriveTransferPublisher,
    18 // CDriveWriteTransferPublisher,
    19 // CDriveReadTransferPublisher,
    20 // CUsbTransferPublisher,
    21 // CUsbReadTransferPublisher,
    22 // CUsbReadTransferPublisher.
    23 // 
    24 //
    25 
    26 
    27 
    28 /**
    29  @file
    30  @internalTechnology
    31 */
    32 
    33 #include <e32std.h>
    34 #include <e32base.h>
    35 #include <e32property.h>
    36 #include <f32file.h>
    37 
    38 #include "mstypes.h"
    39 #include "msctypes.h"
    40 #include "usbmsshared.h"
    41 
    42 #include "drivepublisher.h"
    43 #include "drivemanager.h"
    44 #include "debug.h"
    45 #include "msdebug.h"
    46 
    47 //
    48 // Use Lookup table to translate from the internal pair of state variables
    49 // to the externally published drive state code.
    50 //
    51 LOCAL_D	const TUint8 table[][5] =
    52 {
    53 //TMountState=EDisconnected
    54 	{EUsbMsDriveState_Disconnected,
    55 	 EUsbMsDriveState_Disconnected,
    56 	 EUsbMsDriveState_Disconnected,
    57 	 EUsbMsDriveState_Disconnected,
    58 	 EUsbMsDriveState_Disconnected},
    59 //TMountState=EConnecting
    60 	{EUsbMsDriveState_Connecting,
    61 	 EUsbMsDriveState_Connecting,
    62 	 EUsbMsDriveState_Connecting,
    63 	 EUsbMsDriveState_Connecting,
    64 	 EUsbMsDriveState_Connecting},
    65 //TMountState=EConnected
    66 	//EIdle,EActive,ELocked,EMediaNotPresent,EErrDisMounted
    67 	{EUsbMsDriveState_Connected,
    68 	 EUsbMsDriveState_Active,
    69 	 EUsbMsDriveState_Locked,
    70 	 EUsbMsDriveState_MediaNotPresent,
    71 	 EUsbMsDriveState_Removed},
    72 //TMountState=EDisconnecting
    73 	{EUsbMsDriveState_Disconnecting,
    74 	 EUsbMsDriveState_Disconnecting,
    75 	 EUsbMsDriveState_Disconnecting,
    76 	 EUsbMsDriveState_Disconnecting,
    77 	 EUsbMsDriveState_Disconnecting}
    78 };
    79 
    80 
    81 //----------------------------------------------------------------------------
    82 /**
    83 Constructor
    84 */
    85 RDriveMediaErrorPublisher::RDriveMediaErrorPublisher()
    86 	{
    87 	__MSFNLOG
    88 	_LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
    89 	_LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
    90 
    91 	TInt result = RProperty::Define(EUsbMsDriveState_MediaError, RProperty::EInt,
    92 									KMassStorageReadPolicy, KMassStorageWritePolicy);
    93 
    94 	__ASSERT_DEBUG(result == KErrAlreadyExists || result == KErrNone, User::Invariant());
    95 
    96 	result = iMediaErrorProperty.Attach(KUsbMsDriveState_Category, EUsbMsDriveState_MediaError);
    97 	__ASSERT_DEBUG(result == KErrNone, User::Invariant());
    98 	}
    99 
   100 
   101 RDriveMediaErrorPublisher::~RDriveMediaErrorPublisher()
   102 	{
   103 	__MSFNLOG
   104 	iMediaErrorProperty.Close();
   105 	RProperty::Delete(KUsbMsDriveState_Category, EUsbMsDriveState_MediaError);
   106 	}
   107 
   108 /**
   109 Publishing method
   110 
   111 Publishes the Media Error property event
   112 
   113 @param aError ETrue if drive media has an error else EFalse for no error
   114 */
   115 void RDriveMediaErrorPublisher::PublishErrorL(TBool aError)
   116 	{
   117     __MSFNLOG
   118 	__PRINT1(_L("<< RDriveMediaErrorPublisher::PublishError %x"), aError);
   119 
   120 	TInt oldValue;
   121 	iMediaErrorProperty.Get(oldValue);
   122 
   123 	if (oldValue != aError)
   124 		{
   125 		User::LeaveIfError(iMediaErrorProperty.Set(aError));
   126 		}
   127 	}
   128 
   129 //----------------------------------------------------------------------------
   130 /**
   131 Constructor
   132 
   133 @param aDrives
   134 @param aDriveMap
   135 */
   136 RDriveStateChangedPublisher::RDriveStateChangedPublisher(const TMsDriveList& aDrives,
   137 														 const TLunToDriveMap& aDriveMap)
   138 	:
   139 	iDrives(aDrives),
   140 	iDriveMap(aDriveMap)
   141 	{
   142 	__MSFNLOG
   143 	_LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
   144 	_LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
   145 
   146 	TInt result = RProperty::Define(KUsbMsDriveState_Category,
   147 									EUsbMsDriveState_DriveStatus, RProperty::EByteArray,
   148 									KMassStorageReadPolicy, KMassStorageWritePolicy,
   149 									KUsbMsMaxDrives*2);
   150 	__ASSERT_DEBUG(result == KErrAlreadyExists || result == KErrNone, User::Invariant());
   151 	result = result;	// remove urel warning
   152 	}
   153 
   154 
   155 RDriveStateChangedPublisher::~RDriveStateChangedPublisher()
   156 	{
   157 	__MSFNLOG
   158 	RProperty::Delete(KUsbMsDriveState_Category, EUsbMsDriveState_DriveStatus);
   159 	}
   160 
   161 
   162 /**
   163 Publishing method
   164 
   165 Sends a property event on behalf of CMassStorageDrive, with the mountstate and drivestate
   166 values encoded into one 32-bit word.
   167 */
   168 void RDriveStateChangedPublisher::DriveStateChanged()
   169 	{
   170 	__MSFNLOG
   171 	TUsbMsDrivesStatus allDrivesStatus;
   172 
   173 	for(TUint8 i = 0; i < iDrives.Count(); i++)
   174 		{
   175 		allDrivesStatus.Append(iDriveMap[i]);
   176 
   177 		CMassStorageDrive::TMountState ms = iDrives[i]->MountState();
   178 		TLocalDriveRef::TDriveState ds = iDrives[i]->DriveState();
   179 		TInt driveStatus = EUsbMsDriveState_Error;
   180 		if((TUint8)ds < sizeof(table[0]) && (TUint8)ms < sizeof(table)/sizeof(table[0]))
   181 			{
   182 			driveStatus = table[ms][ds];
   183 			__PRINT3(_L("ms=%d ds=%d %d"), ms, ds, driveStatus);
   184 			}
   185 		allDrivesStatus.Append(driveStatus);
   186 		}
   187 
   188 
   189 	__PRINT1(_L("Publishing EUsbMsDriveState_DriveStatus for %d drives\n"),
   190 				allDrivesStatus.Length()/2);
   191 
   192 	if(KErrNone != RProperty::Set(KUsbMsDriveState_Category,
   193 								  EUsbMsDriveState_DriveStatus,
   194 								  allDrivesStatus))
   195 		{
   196 		__ASSERT_DEBUG(EFalse,User::Invariant());
   197 		}
   198 	}
   199 
   200 
   201 //----------------------------------------------------------------------------
   202 
   203 /**
   204 Private default constructor to ensure that NewL is used
   205 
   206 @param aSubKey
   207 @param aArray
   208 */
   209 CUsbTransferPublisher::CUsbTransferPublisher(TUsbMsDriveState_Subkey aSubKey,
   210                                              const TBytesTransferedList& aArray)
   211 :   iSubKey(aSubKey),
   212 	iArray(aArray)
   213 	{
   214     __MSFNLOG
   215 	}
   216 
   217 
   218 void CUsbTransferPublisher::ConstructL()
   219 	{
   220 	__MSFNLOG
   221 
   222 	_LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
   223 	_LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
   224 
   225 	TInt r = RProperty::Define(iSubKey, RProperty::EByteArray,
   226 							   KMassStorageReadPolicy, KMassStorageWritePolicy,
   227 							   KUsbMsMaxDrives*sizeof(TInt));
   228 
   229 	if (r != KErrAlreadyExists)
   230 		{
   231 		User::LeaveIfError(r);
   232 		}
   233 
   234 	// Attach to the properties here. Only do this once, continuously attaching
   235 	// will currently cause a memory leak
   236 	User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, iSubKey));
   237 
   238 	// Create the EDataTransferred timer
   239 	iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
   240 	iTimerRunning = EFalse;
   241 	}
   242 
   243 
   244 /**
   245 Destructor
   246 */
   247 CUsbTransferPublisher::~CUsbTransferPublisher()
   248 	{
   249 	__MSFNLOG
   250 	if(iTimer)
   251 		{
   252 		iTimer->Cancel();
   253 		}
   254 	delete iTimer;
   255 	iProperty.Close();
   256 
   257 	RProperty::Delete(KUsbMsDriveState_Category, iSubKey);
   258 	}
   259 
   260 
   261 /**
   262 A static wrapper for the DoPublishDataTransferredEvent member function
   263 for use as a timer callback function.
   264 
   265 @param obj 'this' pointer
   266 @return not used in CPeriodic callback (see TCallback)
   267 */
   268 TInt CUsbTransferPublisher::PublishDataTransferredEvent(TAny* obj)
   269 	{
   270 	__MSFNSLOG
   271 	static_cast<CUsbTransferPublisher*>(obj)->DoPublishDataTransferredEvent();
   272 	return 1;
   273 	}
   274 
   275 
   276 /**
   277 Update the data transferred properties if the counts have changed since
   278 the last update.
   279 */
   280 void CUsbTransferPublisher::DoPublishDataTransferredEvent()
   281 	{
   282     __MSFNLOG
   283 	if (PublishDataTransferred())
   284 		{
   285 		// some data has been transfered so reset the counter
   286 		iTimerCancelCnt = ETimerCancelDelay;
   287 		}
   288 
   289 	// Update the cancel count if no data was transferred the last
   290 	// (few) times this has been called
   291 	if (--iTimerCancelCnt == 0)
   292 		{
   293 		StopTimer();
   294 		iTimerCancelCnt = ETimerCancelDelay;
   295 		}
   296 	}
   297 
   298 
   299 /**
   300 Update the data transferred properties if the counts have changed since
   301 the last update.
   302 */
   303 TBool CUsbTransferPublisher::PublishDataTransferred()
   304 	{
   305 	__MSFNLOG
   306 	TUsbMsBytesTransferred bytesTransferred;
   307 	TBool dataTransferred = EFalse;
   308 
   309 	for (TInt i = 0; i < iArray.Count(); i++)
   310 		{
   311 		bytesTransferred[i] = GetBytesTransferred(i);
   312 		}
   313 
   314 	// Update the properties only if they have changed
   315 	// (or if there's an error reading the old value.)
   316 	// Possible optimisation: keep a copy of the value
   317 	// as a member variable so we don't need the Get.
   318 	TUsbMsBytesTransferred oldValue;
   319 
   320 	if ((iProperty.Get(oldValue) != KErrNone) || (oldValue != bytesTransferred))
   321 		{
   322 #ifdef __PRINT3
   323 		// trace of the bytes transferred
   324 		for (TInt j=0; j < iArray.Count(); j++)
   325 			{
   326 			if(oldValue[j] != bytesTransferred[j])
   327 				{
   328 				__PRINT3(_L("CDrivePublisher: KBytes[%d] %d->%d\n"), j, oldValue[j], bytesTransferred[j]);
   329 				}
   330 			}
   331 #endif
   332 		if (KErrNone != iProperty.Set(bytesTransferred))
   333 			{
   334 			__ASSERT_DEBUG(EFalse, User::Invariant());
   335 			}
   336 		dataTransferred = ETrue;
   337 		}
   338 
   339 	return dataTransferred;
   340 	}
   341 
   342 
   343 /**
   344 Starts timer to periodically publish results.
   345 If the timer is not yet running then start it.
   346 */
   347 void CUsbTransferPublisher::StartTimer()
   348 	{
   349 	__MSFNLOG
   350 	if (!iTimerRunning)
   351 		{
   352 		// EDataTransferred event every second
   353 		const TTimeIntervalMicroSeconds32 interval = 1 * 1000 * 1000;
   354 		TCallBack callback(PublishDataTransferredEvent, this);
   355 		__PRINT(_L("Starting timer"));
   356 		iTimer->Start(interval, interval, callback);
   357 		iTimerRunning = ETrue;
   358 		}
   359 	}
   360 
   361 
   362 /**
   363 Ensure that the Timer is stopped
   364 */
   365 void CUsbTransferPublisher::StopTimer()
   366 	{
   367 	__MSFNLOG
   368 	if (iTimerRunning)
   369 		{
   370 		__PRINT(_L("Stopping timer"));
   371 		iTimer->Cancel();
   372 		iTimerRunning = EFalse;
   373 		}
   374 	}
   375 
   376 
   377 //----------------------------------------------------------------------------
   378 /**
   379 Constructor for Write property
   380 
   381 @param aArray
   382 */
   383 CUsbWriteTransferPublisher* CUsbWriteTransferPublisher::NewL(const TBytesTransferedList& aArray)
   384 	{
   385 	__MSFNSLOG
   386 	CUsbWriteTransferPublisher* self = new (ELeave) CUsbWriteTransferPublisher(aArray);
   387 	CleanupStack::PushL(self);
   388 	self->ConstructL();
   389 	CleanupStack::Pop();
   390 	return self;
   391 	}
   392 
   393 
   394 CUsbWriteTransferPublisher::CUsbWriteTransferPublisher(const TBytesTransferedList& aArray)
   395 :   CUsbTransferPublisher(EUsbMsDriveState_KBytesWritten, aArray)
   396 	{
   397     __MSFNLOG
   398 	}
   399 
   400 
   401 //----------------------------------------------------------------------------
   402 /**
   403 Constructor for Read property
   404 
   405 @param aArray
   406 */
   407 CUsbReadTransferPublisher* CUsbReadTransferPublisher::NewL(const TBytesTransferedList& aArray)
   408 	{
   409 	__MSFNSLOG
   410 	CUsbReadTransferPublisher* self = new (ELeave) CUsbReadTransferPublisher(aArray);
   411 	CleanupStack::PushL(self);
   412 	self->ConstructL();
   413 	CleanupStack::Pop();
   414 	return self;
   415 	}
   416 
   417 
   418 CUsbReadTransferPublisher::CUsbReadTransferPublisher(const TBytesTransferedList& aArray)
   419 :   CUsbTransferPublisher(EUsbMsDriveState_KBytesRead, aArray)
   420 	{
   421     __MSFNLOG
   422 	}
   423 
   424 /**
   425 Transfer function for the property
   426 
   427 @return Cumulative bytes read since the host connected to the drive,
   428         in multiples of KBytesPerKilobyte rounded to nearest integer value.
   429         The KBytes refer to multiples of 1000, not 1024.
   430 */
   431 TUint CUsbTransferPublisher::GetBytesTransferred(TLun aLun) const
   432 {
   433 	return I64LOW(iArray[aLun] / (TUint64)1000);
   434 }