userlibandfileserver/fileserver/smassstorage/drivepublisher.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2007-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  @file
       
    28  @internalTechnology
       
    29 */
       
    30 
       
    31 #include "massstoragedebug.h"
       
    32 #include "drivepublisher.h"
       
    33 #include "drivemanager.h"
       
    34 
       
    35 
       
    36 // 
       
    37 // Use Lookup table to translate from the internal pair of state variables
       
    38 // to the externally published drive state code.
       
    39 //
       
    40 LOCAL_D	const TUint8 table[][5] =
       
    41 {
       
    42 //TMountState=EDisconnected
       
    43 	{EUsbMsDriveState_Disconnected, 
       
    44 	 EUsbMsDriveState_Disconnected, 
       
    45 	 EUsbMsDriveState_Disconnected, 
       
    46 	 EUsbMsDriveState_Disconnected, 
       
    47 	 EUsbMsDriveState_Disconnected},
       
    48 //TMountState=EConnecting
       
    49 	{EUsbMsDriveState_Connecting,
       
    50 	 EUsbMsDriveState_Connecting, 
       
    51 	 EUsbMsDriveState_Connecting, 
       
    52 	 EUsbMsDriveState_Connecting, 
       
    53 	 EUsbMsDriveState_Connecting},
       
    54 //TMountState=EConnected
       
    55 	//EIdle,EActive,ELocked,EMediaNotPresent,EErrDisMounted
       
    56 	{EUsbMsDriveState_Connected, 
       
    57 	 EUsbMsDriveState_Active, 
       
    58 	 EUsbMsDriveState_Locked, 
       
    59 	 EUsbMsDriveState_MediaNotPresent, 
       
    60 	 EUsbMsDriveState_Removed},
       
    61 //TMountState=EDisconnecting
       
    62 	{EUsbMsDriveState_Disconnecting, 
       
    63 	 EUsbMsDriveState_Disconnecting, 
       
    64 	 EUsbMsDriveState_Disconnecting, 
       
    65 	 EUsbMsDriveState_Disconnecting, 
       
    66 	 EUsbMsDriveState_Disconnecting}
       
    67 };
       
    68 
       
    69 
       
    70 //----------------------------------------------------------------------------
       
    71 /**
       
    72 Constructor
       
    73 */
       
    74 RDriveMediaErrorPublisher::RDriveMediaErrorPublisher()
       
    75 	{
       
    76 	__FNLOG("RDriveMediaErrorPublisher::RDriveMediaErrorPublisher()");
       
    77 
       
    78 	_LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
       
    79 	_LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
       
    80 
       
    81 	TInt result = RProperty::Define(EUsbMsDriveState_MediaError, RProperty::EInt,
       
    82 									KMassStorageReadPolicy, KMassStorageWritePolicy);
       
    83    
       
    84 	__ASSERT_DEBUG(result == KErrAlreadyExists || result == KErrNone, User::Invariant());
       
    85    
       
    86 	result = iMediaErrorProperty.Attach(KUsbMsDriveState_Category, EUsbMsDriveState_MediaError);
       
    87 	__ASSERT_DEBUG(result == KErrNone, User::Invariant());
       
    88 	}
       
    89 
       
    90 
       
    91 RDriveMediaErrorPublisher::~RDriveMediaErrorPublisher()
       
    92 	{
       
    93 	__FNLOG("RDriveStatePublisher::~RDriveStatePublisher()");
       
    94 
       
    95 	iMediaErrorProperty.Close();
       
    96 	RProperty::Delete(KUsbMsDriveState_Category, EUsbMsDriveState_MediaError);
       
    97 	}
       
    98 
       
    99 /**
       
   100 Publishing method
       
   101 
       
   102 Publishes the Media Error property event
       
   103 
       
   104 @param aError ETrue if drive media has an error else EFalse for no error
       
   105 */
       
   106 void RDriveMediaErrorPublisher::PublishError(TBool aError)
       
   107 	{
       
   108 	__PRINT1(_L("<< RDriveMediaErrorPublisher::PublishError %x"), aError);
       
   109 
       
   110 	TInt oldValue;
       
   111 	iMediaErrorProperty.Get(oldValue);
       
   112 
       
   113 	if (oldValue != aError)
       
   114 		{
       
   115 		User::LeaveIfError(iMediaErrorProperty.Set(aError));
       
   116 		}
       
   117 	}
       
   118 
       
   119 //----------------------------------------------------------------------------
       
   120 /**
       
   121 Constructor
       
   122 
       
   123 @param aDrives
       
   124 @param aDriveMap
       
   125 */
       
   126 RDriveStateChangedPublisher::RDriveStateChangedPublisher(TRefMsDriveList aDrives,
       
   127 														 TRefDriveMap aDriveMap)
       
   128 	:
       
   129 	iDrives(aDrives),
       
   130 	iDriveMap(aDriveMap)
       
   131 	{
       
   132 	__FNLOG("RDriveStateChangedPublisher::RDriveStateChangedPublisher()");
       
   133 
       
   134 	_LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
       
   135 	_LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
       
   136 
       
   137 	TInt result = RProperty::Define(KUsbMsDriveState_Category,
       
   138 									EUsbMsDriveState_DriveStatus, RProperty::EByteArray,
       
   139 									KMassStorageReadPolicy, KMassStorageWritePolicy,
       
   140 									KUsbMsMaxDrives*2);
       
   141 	__ASSERT_DEBUG(result == KErrAlreadyExists || result == KErrNone, User::Invariant());
       
   142 	result = result;	// remove urel warning
       
   143 	}
       
   144 
       
   145 
       
   146 RDriveStateChangedPublisher::~RDriveStateChangedPublisher()
       
   147 	{
       
   148 	__FNLOG("RDriveStateChangedPublisher::~RDriveStateChangedPublisher()");
       
   149 
       
   150 	RProperty::Delete(KUsbMsDriveState_Category, EUsbMsDriveState_DriveStatus);
       
   151 	}
       
   152 
       
   153 
       
   154 /**
       
   155 Publishing method
       
   156 
       
   157 Sends a property event on behalf of CMassStorageDrive, with the mountstate and drivestate 
       
   158 values encoded into one 32-bit word.
       
   159 */
       
   160 void RDriveStateChangedPublisher::DriveStateChanged()
       
   161 	{
       
   162 	__FNLOG("RDriveStateChangedPublisher::DriveStateChanged");
       
   163 
       
   164 
       
   165 	TUsbMsDrivesStatus allDrivesStatus;
       
   166 	for(TUint8 i=0; i<KUsbMsMaxDrives && iDrives[i]; i++)
       
   167 		{
       
   168 		allDrivesStatus.Append(iDriveMap[i]); 
       
   169 
       
   170 		CMassStorageDrive::TMountState ms = iDrives[i]->MountState();
       
   171 		CMassStorageDrive::TDriveState ds = iDrives[i]->DriveState();
       
   172 		TInt driveStatus = EUsbMsDriveState_Error;
       
   173 		if((TUint8)ds < sizeof(table[0]) && (TUint8)ms < sizeof(table)/sizeof(table[0]))
       
   174 			{
       
   175 			driveStatus = table[ms][ds];
       
   176 			__PRINT3(_L("ms=%d ds=%d %d"), ms, ds, driveStatus);
       
   177 			}
       
   178 		allDrivesStatus.Append(driveStatus);
       
   179 		}
       
   180 
       
   181 	__PRINT1(_L("Publishing EUsbMsDriveState_DriveStatus for %d drives\n"),
       
   182 				allDrivesStatus.Length()/2);
       
   183 
       
   184 	if(KErrNone != RProperty::Set(KUsbMsDriveState_Category,
       
   185 								  EUsbMsDriveState_DriveStatus, 
       
   186 								  allDrivesStatus))
       
   187 		{
       
   188 		__ASSERT_DEBUG(EFalse,User::Invariant());
       
   189 		}
       
   190 	}
       
   191 
       
   192 
       
   193 //----------------------------------------------------------------------------
       
   194 #ifndef USB_TRANSFER_PUBLISHER
       
   195 /**
       
   196 Private default constructor to ensure that NewL is used
       
   197 
       
   198 @param aSubKey 
       
   199 @param aDrives
       
   200 */
       
   201 CDriveTransferPublisher::CDriveTransferPublisher(
       
   202 	TUsbMsDriveState_Subkey aSubKey,
       
   203 	TRefMsDriveList aDrives)
       
   204 	:
       
   205 	iSubKey(aSubKey),
       
   206 	iDrives(aDrives)
       
   207 	{
       
   208 	}
       
   209 
       
   210 
       
   211 void CDriveTransferPublisher::ConstructL()
       
   212 	{
       
   213 	__FNLOG("CDriveTransferPublisher::ConstructL");
       
   214 
       
   215 	_LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
       
   216 	_LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
       
   217 
       
   218 	TInt r = RProperty::Define(iSubKey, RProperty::EByteArray, 
       
   219 							   KMassStorageReadPolicy, KMassStorageWritePolicy,
       
   220 							   KUsbMsMaxDrives*sizeof(TInt));
       
   221 
       
   222 	if (r != KErrAlreadyExists) 
       
   223 		{
       
   224 		User::LeaveIfError(r);
       
   225 		}
       
   226 
       
   227 	User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, iSubKey));
       
   228 
       
   229 	// Create the EDataTransferred timer
       
   230 	iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
   231 	iTimerRunning = EFalse;
       
   232 	}
       
   233 
       
   234 
       
   235 /**
       
   236 Destructor
       
   237 */
       
   238 CDriveTransferPublisher::~CDriveTransferPublisher()
       
   239 	{
       
   240 	__FNLOG("CDriveTransferPublisher::~CDriveTransferPublisher");
       
   241 
       
   242 	if(iTimer)
       
   243 		{
       
   244 		iTimer->Cancel();
       
   245 		}
       
   246 	delete iTimer;
       
   247 
       
   248 	iProperty.Close();
       
   249 
       
   250 	RProperty::Delete(KUsbMsDriveState_Category, iSubKey);
       
   251 	}
       
   252 
       
   253 
       
   254 /**
       
   255 A static wrapper for the DoPublishDataTransferredEvent member function
       
   256 for use as a timer callback function.
       
   257 
       
   258 @param obj 'this' pointer
       
   259 @return not used in CPeriodic callback (see TCallback)
       
   260 */
       
   261 TInt CDriveTransferPublisher::PublishDataTransferredEvent(TAny* obj)
       
   262 	{
       
   263 	__FNLOG("CDrivePublisher::PublishDataTransferredEvent");
       
   264 	static_cast<CDriveTransferPublisher*>(obj)->DoPublishDataTransferredEvent();
       
   265 	return 1;
       
   266 	}
       
   267 
       
   268 
       
   269 /**
       
   270 Update the data transferred properties if the counts have changed since
       
   271 the last update.
       
   272 */
       
   273 void CDriveTransferPublisher::DoPublishDataTransferredEvent()
       
   274 	{
       
   275 	if (PublishDataTransferred())
       
   276 		{
       
   277 		// some data has been transfered so reset the counter
       
   278 		iTimerCancelCnt = ETimerCancelDelay;
       
   279 		}
       
   280 
       
   281 	// Update the cancel count if no data was transferred the last
       
   282 	// (few) times this has been called
       
   283 	if (--iTimerCancelCnt == 0)
       
   284 		{
       
   285 		StopTimer();
       
   286 		iTimerCancelCnt = ETimerCancelDelay;
       
   287 		}
       
   288 	}
       
   289 
       
   290 
       
   291 /**
       
   292 Update the data transferred properties if the counts have changed since 
       
   293 the last update.
       
   294 */
       
   295 TBool CDriveTransferPublisher::PublishDataTransferred()
       
   296 	{
       
   297 	__FNLOG("CDriveWriteTransferPublisher::PublishDataTransferred");
       
   298 
       
   299 	TUsbMsBytesTransferred bytesTransferred;
       
   300 	TBool dataTransferred = EFalse;
       
   301 
       
   302 	for (TInt i=0; i < iDrives.Count() && iDrives[i]; i++)
       
   303 		{
       
   304 		bytesTransferred[i] = GetBytesTransferred(i);
       
   305 		}
       
   306 
       
   307 	// Update the properties only if they have changed
       
   308 	// (or if there's an error reading the old value.)
       
   309 	// Possible optimisation: keep a copy of the value
       
   310 	// as a member variable so we don't need the Get.
       
   311 	TUsbMsBytesTransferred oldValue;
       
   312 
       
   313 	if ((iProperty.Get(oldValue) != KErrNone) || (oldValue != bytesTransferred))
       
   314 		{
       
   315 #ifdef __PRINT3
       
   316 		for (TInt j=0; j < iDrives.Count() && iDrives[j]; j++)
       
   317 			{
       
   318 			if(oldValue[j] != bytesTransferred[j])
       
   319 				{
       
   320 				__PRINT3(_L("CDrivePublisher: KBytes[%d] %d->%d\n"), j, oldValue[j], bytesTransferred[j]);
       
   321 				}
       
   322 			}
       
   323 #endif
       
   324 		if (KErrNone != iProperty.Set(bytesTransferred))
       
   325 			{
       
   326 			__ASSERT_DEBUG(EFalse, User::Invariant());
       
   327 			}
       
   328 		dataTransferred = ETrue;
       
   329 		}
       
   330 
       
   331 	return dataTransferred;
       
   332 	}
       
   333 
       
   334 
       
   335 /**
       
   336 Starts timer to periodically publish results.
       
   337 If the timer is not yet running then start it.
       
   338 */
       
   339 void CDriveTransferPublisher::StartTimer()
       
   340 	{
       
   341 	__FNLOG("CDrivePublisher::StartTimer");
       
   342 
       
   343 	if (!iTimerRunning)
       
   344 		{
       
   345 		// EDataTransferred event every second
       
   346 		const TTimeIntervalMicroSeconds32 interval = 1 * 1000 * 1000;
       
   347 		TCallBack callback(PublishDataTransferredEvent, this);
       
   348 		__PRINT(_L("Starting timer"));
       
   349 		iTimer->Start(interval, interval, callback);
       
   350 		iTimerRunning = ETrue;
       
   351 		}
       
   352 	}
       
   353 
       
   354 
       
   355 /**
       
   356 Ensure that the Timer is stopped
       
   357 */
       
   358 void CDriveTransferPublisher::StopTimer()
       
   359 	{
       
   360 	__FNLOG("CDrivePublisher::StopTimer");
       
   361 
       
   362 	if (iTimerRunning)
       
   363 		{
       
   364 		__PRINT(_L("Stopping timer"));
       
   365 		iTimer->Cancel();
       
   366 		iTimerRunning = EFalse;
       
   367 		}
       
   368 	}
       
   369 
       
   370 
       
   371 //----------------------------------------------------------------------------
       
   372 /**
       
   373 Constructor for Write property
       
   374 
       
   375 @param aDrives
       
   376 */
       
   377 CDriveWriteTransferPublisher* CDriveWriteTransferPublisher::NewL(TRefMsDriveList aDrives)
       
   378 	{
       
   379 	__FNLOG("CDriveWriteTransferPublisher::NewL");
       
   380 
       
   381 	CDriveWriteTransferPublisher* self = new (ELeave) CDriveWriteTransferPublisher(aDrives);
       
   382 	CleanupStack::PushL(self);
       
   383 	self->ConstructL();
       
   384 	CleanupStack::Pop();
       
   385 	return self;
       
   386 	}
       
   387 
       
   388 
       
   389 /**
       
   390 Constructor
       
   391 
       
   392 @param aDrives
       
   393 */
       
   394 CDriveWriteTransferPublisher::CDriveWriteTransferPublisher(TRefMsDriveList aDrives)
       
   395 	:
       
   396 	CDriveTransferPublisher(EUsbMsDriveState_KBytesWritten, aDrives)
       
   397 	{
       
   398 	}
       
   399 
       
   400 
       
   401 /**
       
   402 Transfer function for Write property
       
   403 
       
   404 @param aLun
       
   405 */
       
   406 TUint CDriveWriteTransferPublisher::GetBytesTransferred(TUint aLun) const
       
   407 	{
       
   408 	return iDrives[aLun]->KBytesWritten();
       
   409 	}
       
   410 
       
   411 
       
   412 //----------------------------------------------------------------------------
       
   413 /**
       
   414 Constructor for Read property
       
   415 
       
   416 @param aDrives
       
   417 */
       
   418 CDriveReadTransferPublisher* CDriveReadTransferPublisher::NewL(TRefMsDriveList aDrives)
       
   419 	{
       
   420 	__FNLOG("CDriveWriteTransferPublisher::NewL");
       
   421 
       
   422 	CDriveReadTransferPublisher* self = new (ELeave) CDriveReadTransferPublisher(aDrives);
       
   423 	CleanupStack::PushL(self);
       
   424 	self->ConstructL();
       
   425 	CleanupStack::Pop();
       
   426 	return self;
       
   427 	}
       
   428 
       
   429 
       
   430 /**
       
   431 Constructor
       
   432 
       
   433 @param aDrives
       
   434 */
       
   435 CDriveReadTransferPublisher::CDriveReadTransferPublisher(TRefMsDriveList aDrives)
       
   436 	:
       
   437 	CDriveTransferPublisher(EUsbMsDriveState_KBytesRead, aDrives)
       
   438 	{
       
   439 	}
       
   440 
       
   441 
       
   442 /**
       
   443 Transfer function for Read property
       
   444 
       
   445 @param aLun
       
   446 */
       
   447 TUint CDriveReadTransferPublisher::GetBytesTransferred(TUint aLun) const
       
   448 	{
       
   449 	return iDrives[aLun]->KBytesRead();
       
   450 	}
       
   451 
       
   452 
       
   453 //----------------------------------------------------------------------------
       
   454 #else
       
   455 /**
       
   456 Private default constructor to ensure that NewL is used
       
   457  
       
   458 @param aSubKey
       
   459 @param aArray
       
   460 */
       
   461 CUsbTransferPublisher::CUsbTransferPublisher(
       
   462 	TUsbMsDriveState_Subkey aSubKey,
       
   463 	TRefBytesTransferedList aArray)
       
   464 	:
       
   465 	iSubKey(aSubKey),
       
   466 	iArray(aArray)
       
   467 	{
       
   468 	}
       
   469 
       
   470 
       
   471 void CUsbTransferPublisher::ConstructL()
       
   472 	{
       
   473 	__FNLOG("CUsbTransferPublisher::ConstructL");
       
   474 
       
   475 	_LIT_SECURITY_POLICY_PASS(KMassStorageReadPolicy);
       
   476 	_LIT_SECURITY_POLICY_S0(KMassStorageWritePolicy, KUsbMsDriveState_Category.iUid);
       
   477 
       
   478 	TInt r = RProperty::Define(iSubKey, RProperty::EByteArray, 
       
   479 							   KMassStorageReadPolicy, KMassStorageWritePolicy,
       
   480 							   KUsbMsMaxDrives*sizeof(TInt));
       
   481 
       
   482 	if (r != KErrAlreadyExists) 
       
   483 		{
       
   484 		User::LeaveIfError(r);
       
   485 		}
       
   486 
       
   487 	// Attach to the properties here. Only do this once, continuously attaching
       
   488 	// will currently cause a memory leak
       
   489 	User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, iSubKey));
       
   490 
       
   491 	// Create the EDataTransferred timer
       
   492 	iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
   493 	iTimerRunning = EFalse;
       
   494 	}
       
   495 
       
   496 
       
   497 /**
       
   498 Destructor
       
   499 */
       
   500 CUsbTransferPublisher::~CUsbTransferPublisher()
       
   501 	{
       
   502 	__FNLOG("CUsbTransferPublisher::~CDriveTransferPublisher");
       
   503 
       
   504 	if(iTimer)
       
   505 		{
       
   506 		iTimer->Cancel();
       
   507 		}
       
   508 	delete iTimer;
       
   509 
       
   510 	iProperty.Close();
       
   511 
       
   512 	RProperty::Delete(KUsbMsDriveState_Category, iSubKey);
       
   513 	}
       
   514 
       
   515 
       
   516 /**
       
   517 A static wrapper for the DoPublishDataTransferredEvent member function
       
   518 for use as a timer callback function.
       
   519 
       
   520 @param obj 'this' pointer
       
   521 @return not used in CPeriodic callback (see TCallback)
       
   522 */
       
   523 TInt CUsbTransferPublisher::PublishDataTransferredEvent(TAny* obj)
       
   524 	{
       
   525 	__FNLOG("CUsbTransferPublisher::PublishDataTransferredEvent");
       
   526 	static_cast<CUsbTransferPublisher*>(obj)->DoPublishDataTransferredEvent();
       
   527 	return 1;
       
   528 	}
       
   529 
       
   530 
       
   531 /**
       
   532 Update the data transferred properties if the counts have changed since
       
   533 the last update.
       
   534 */
       
   535 void CUsbTransferPublisher::DoPublishDataTransferredEvent()
       
   536 	{
       
   537 	if (PublishDataTransferred())
       
   538 		{
       
   539 		// some data has been transfered so reset the counter
       
   540 		iTimerCancelCnt = ETimerCancelDelay;
       
   541 		}
       
   542 
       
   543 	// Update the cancel count if no data was transferred the last
       
   544 	// (few) times this has been called
       
   545 	if (--iTimerCancelCnt == 0)
       
   546 		{
       
   547 		StopTimer();
       
   548 		iTimerCancelCnt = ETimerCancelDelay;
       
   549 		}
       
   550 	}
       
   551 
       
   552 
       
   553 /**
       
   554 Update the data transferred properties if the counts have changed since 
       
   555 the last update.
       
   556 */
       
   557 TBool CUsbTransferPublisher::PublishDataTransferred()
       
   558 	{
       
   559 	__FNLOG("CUsbWriteTransferPublisher::PublishDataTransferred");
       
   560 
       
   561 	TUsbMsBytesTransferred bytesTransferred;
       
   562 	TBool dataTransferred = EFalse;
       
   563 
       
   564 	for (TInt i = 0; i < iArray.Count(); i++)
       
   565 		{
       
   566 		bytesTransferred[i] = GetBytesTransferred(i);
       
   567 		}
       
   568 
       
   569 	// Update the properties only if they have changed
       
   570 	// (or if there's an error reading the old value.)
       
   571 	// Possible optimisation: keep a copy of the value
       
   572 	// as a member variable so we don't need the Get.
       
   573 	TUsbMsBytesTransferred oldValue;
       
   574 
       
   575 	if ((iProperty.Get(oldValue) != KErrNone) || (oldValue != bytesTransferred))
       
   576 		{
       
   577 #ifdef __PRINT3
       
   578 		// trace of the bytes transferred
       
   579 		for (TInt j=0; j < iArray.Count(); j++)
       
   580 			{
       
   581 			if(oldValue[j] != bytesTransferred[j])
       
   582 				{
       
   583 				__PRINT3(_L("CDrivePublisher: KBytes[%d] %d->%d\n"), j, oldValue[j], bytesTransferred[j]);
       
   584 				}
       
   585 			}
       
   586 #endif
       
   587 		if (KErrNone != iProperty.Set(bytesTransferred))
       
   588 			{
       
   589 			__ASSERT_DEBUG(EFalse, User::Invariant());
       
   590 			}
       
   591 		dataTransferred = ETrue;
       
   592 		}
       
   593 
       
   594 	return dataTransferred;
       
   595 	}
       
   596 
       
   597 
       
   598 /**
       
   599 Starts timer to periodically publish results.
       
   600 If the timer is not yet running then start it.
       
   601 */
       
   602 void CUsbTransferPublisher::StartTimer()
       
   603 	{
       
   604 	__FNLOG("CUsbTransferPublisher::StartTimer");
       
   605 
       
   606 	if (!iTimerRunning)
       
   607 		{
       
   608 		// EDataTransferred event every second
       
   609 		const TTimeIntervalMicroSeconds32 interval = 1 * 1000 * 1000;
       
   610 		TCallBack callback(PublishDataTransferredEvent, this);
       
   611 		__PRINT(_L("Starting timer"));
       
   612 		iTimer->Start(interval, interval, callback);
       
   613 		iTimerRunning = ETrue;
       
   614 		}
       
   615 	}
       
   616 
       
   617 
       
   618 /**
       
   619 Ensure that the Timer is stopped
       
   620 */
       
   621 void CUsbTransferPublisher::StopTimer()
       
   622 	{
       
   623 	__FNLOG("CUsbTransferPublisher::StopTimer");
       
   624 
       
   625 	if (iTimerRunning)
       
   626 		{
       
   627 		__PRINT(_L("Stopping timer"));
       
   628 		iTimer->Cancel();
       
   629 		iTimerRunning = EFalse;
       
   630 		}
       
   631 	}
       
   632 
       
   633 
       
   634 //----------------------------------------------------------------------------
       
   635 /**
       
   636 Constructor for Write property
       
   637 
       
   638 @param aArray
       
   639 */
       
   640 CUsbWriteTransferPublisher* CUsbWriteTransferPublisher::NewL(TRefBytesTransferedList aArray)
       
   641 	{
       
   642 	__FNLOG("CUsbWriteTransferPublisher::NewL");
       
   643 
       
   644 	CUsbWriteTransferPublisher* self = new (ELeave) CUsbWriteTransferPublisher(aArray);
       
   645 	CleanupStack::PushL(self);
       
   646 	self->ConstructL();
       
   647 	CleanupStack::Pop();
       
   648 	return self;
       
   649 	}
       
   650 
       
   651 
       
   652 CUsbWriteTransferPublisher::CUsbWriteTransferPublisher(
       
   653 	TRefBytesTransferedList aArray)
       
   654 	:
       
   655 	CUsbTransferPublisher(EUsbMsDriveState_KBytesWritten, aArray)
       
   656 	{
       
   657 	}
       
   658 
       
   659 
       
   660 //----------------------------------------------------------------------------
       
   661 /**
       
   662 Constructor for Read property
       
   663 
       
   664 @param aArray
       
   665 */
       
   666 CUsbReadTransferPublisher* CUsbReadTransferPublisher::NewL(TRefBytesTransferedList aArray)
       
   667 	{
       
   668 	__FNLOG("CUsbWriteTransferPublisher::NewL");
       
   669 
       
   670 	CUsbReadTransferPublisher* self = new (ELeave) CUsbReadTransferPublisher(aArray);
       
   671 	CleanupStack::PushL(self);
       
   672 	self->ConstructL();
       
   673 	CleanupStack::Pop();
       
   674 	return self;
       
   675 	}
       
   676 
       
   677 
       
   678 CUsbReadTransferPublisher::CUsbReadTransferPublisher(
       
   679 	TRefBytesTransferedList aArray)
       
   680 	:
       
   681 	CUsbTransferPublisher(EUsbMsDriveState_KBytesRead, aArray)
       
   682 	{
       
   683 	}
       
   684 #endif // USB_TRANSFER_PUBLISHER