os/kernelhwsrv/kerneltest/e32test/usb/t_usb_device/src/activerw.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2000-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 // e32test/usb/t_usb_device/src/activerw.cpp
    15 // USB Test Program T_USB_DEVICE, functional part.
    16 // Device-side part, to work against T_USB_HOST running on the host.
    17 // 
    18 //
    19 
    20 #include "general.h"									// CActiveControl, CActiveRW
    21 #include "config.h"
    22 #include "activerw.h"
    23 #include "activetimer.h" 
    24 #include "usblib.h"										// Helpers
    25 
    26 _LIT(KFileName, "\\T_USBFILE.BIN");
    27 
    28 extern RTest test;
    29 extern TBool gVerbose;
    30 extern TBool gSkip;
    31 extern TBool gStopOnFail;
    32 extern TBool gAltSettingOnNotify;
    33 extern TInt8 gSettingNumber [128];
    34 extern TInt gSoakCount;
    35 extern CActiveRW* gRW[KMaxConcurrentTests];				// the USB read/write active object
    36 extern IFConfigPtr gInterfaceConfig [128] [KMaxInterfaceSettings];
    37 extern TInt gActiveTestCount;
    38 
    39 static TInt gYieldRepeat = 0;
    40 static const TInt KYieldRepeat = 100;
    41 
    42 //
    43 // --- class CActiveRW ---------------------------------------------------------
    44 //
    45 
    46 CActiveRW::CActiveRW(CConsoleBase* aConsole, RDEVCLIENT* aPort, RFs aFs, TUint16 aIndex, TBool aLastSetting)
    47 	: CActive(EPriorityNormal),
    48 		#ifndef USB_SC
    49 		iWriteBuf((TUint8 *)NULL,0,0),		// temporary initialisation
    50 		iReadBuf((TUint8 *)NULL,0,0),		// temporary initialisation	
    51 	  	#endif
    52 	  iConsole(aConsole),
    53 	  iPort(aPort),
    54 	  iBufSz(0),
    55 	  iMaxPktSz(0),
    56 	  iCurrentXfer(ETxferNone),
    57 	  iXferMode(::ENone),
    58 	  iDoStop(EFalse),
    59 	  iPktNum(0),
    60 	  iFs(aFs),
    61 	  iRepeat(0),
    62 	  iComplete(EFalse),
    63 	  iResult(EFalse),
    64 	  iIndex (aIndex),
    65 	  iLastSetting (aLastSetting)
    66 	{
    67 	gActiveTestCount++;
    68 	TUSB_VERBOSE_PRINT("CActiveRW::CActiveRW()");
    69 	}
    70 
    71 
    72 CActiveRW* CActiveRW::NewL(CConsoleBase* aConsole, RDEVCLIENT* aPort, RFs aFs, TUint16 aIndex, TBool aLastSetting)
    73 	{
    74 	TUSB_VERBOSE_APRINT("CActiveRW::NewL()");
    75 
    76 	CActiveRW* self = new (ELeave) CActiveRW(aConsole, aPort, aFs, aIndex, aLastSetting);
    77 	CleanupStack::PushL(self);
    78 	self->ConstructL();
    79 	CActiveScheduler::Add(self);
    80 	CleanupStack::Pop();									// self
    81 	return self;
    82 	}
    83 
    84 
    85 void CActiveRW::ConstructL()
    86 	{
    87 	TUSB_VERBOSE_PRINT("CActiveRW::ConstructL()");
    88 
    89 	// Create read timeout timer active object (but don't activate it yet)
    90 	iTimeoutTimer = CActiveTimer::NewL(iConsole, iPort);
    91 	if (!iTimeoutTimer)
    92 		{
    93 		TUSB_PRINT("Failed to create timeout timer");
    94 		}
    95 	}
    96 
    97 
    98 CActiveRW::~CActiveRW()
    99 	{
   100 	TUSB_VERBOSE_PRINT("CActiveRW::~CActiveRW()");
   101 	Cancel();												// base class
   102 	delete iTimeoutTimer;
   103 	#ifdef USB_SC
   104 	if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient)
   105 		{
   106 		iSCReadBuf.Close();
   107 		}
   108 	if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient)
   109 		{
   110 		iSCWriteBuf.Close();
   111 		}
   112 	#else
   113 	User::Free((TAny *)iReadBuf.Ptr());
   114 	User::Free((TAny *)iWriteBuf.Ptr());
   115 	#endif
   116 	iFile.Close();
   117 	gRW[iIndex] = NULL;
   118 	gActiveTestCount--;
   119 	}
   120 
   121 
   122 void CActiveRW::SetTestParams(TestParamPtr aTpPtr)
   123 	{
   124 	iBufSz = aTpPtr->minSize;
   125 	iPktNum = aTpPtr->packetNumber;
   126 	
   127 	iTestParams = *aTpPtr;
   128 
   129 	gYieldRepeat = ((iTestParams.settingRepeat != 0) || (iIndex == 0))? 0 : KYieldRepeat;
   130 
   131 	if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient)
   132 		{
   133 		#ifndef USB_SC
   134 		TAny * newBuffer = User::Alloc(aTpPtr->maxSize);
   135 		if (newBuffer == NULL)
   136 			{
   137 			TUSB_PRINT ("Failure to allocate heap memory");
   138 			test(EFalse);
   139 			}
   140 		iReadBuf.Set((TUint8 *)newBuffer,0,(TInt)aTpPtr->maxSize);
   141 		#endif
   142 		TBuf8<KUsbDescSize_Endpoint> descriptor;
   143 		TUSB_VERBOSE_PRINT2 ("GetEndpointDescriptor Alt Setting %d Endpoint %d",iTestParams.alternateSetting, iTestParams.outPipe);
   144 		TInt r = iPort->GetEndpointDescriptor(iTestParams.alternateSetting, (TENDPOINTNUMBER)iTestParams.outPipe, descriptor);
   145 		if ((TUint)r != iReadSize)
   146 			{
   147 			TUSB_PRINT("Failed to get endpoint descriptor");
   148 			test(EFalse);
   149 			return;
   150 			}
   151 
   152 		iMaxPktSz = EpSize(descriptor[KEpDesc_PacketSizeOffset],descriptor[KEpDesc_PacketSizeOffset+1]);		
   153 		TUSB_VERBOSE_PRINT5 ("Out Endpoint 0x%x attributes 0x%x interface %d setting %d max packet size %d",
   154 			descriptor[KEpDesc_AddressOffset],descriptor[KEpDesc_AttributesOffset],iTestParams.interfaceNumber,iTestParams.alternateSetting,iMaxPktSz);
   155 		if (!gSkip && iMaxPktSz != (TUint)gInterfaceConfig[iTestParams.interfaceNumber][iTestParams.alternateSetting]->iInfoPtr->iEndpointData[iTestParams.outPipe-1].iSize)
   156 			{
   157 			TUSB_PRINT4("Error - Interface %d Setting %d Endpoint %d Max Packet Size %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe,iMaxPktSz);
   158 			test(EFalse);
   159 			return;
   160 			}
   161 		}
   162 	if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient)
   163 		{
   164 		#ifndef USB_SC
   165 		TAny * newBuffer = User::Alloc(aTpPtr->maxSize);
   166 		if (newBuffer == NULL)
   167 			{
   168 			TUSB_PRINT ("Failure to allocate heap memory");
   169 			test(EFalse);
   170 			}
   171 		iWriteBuf.Set((TUint8 *)newBuffer,0,(TInt)aTpPtr->maxSize);
   172 		#endif
   173 		TBuf8<KUsbDescSize_Endpoint> descriptor;
   174 		TUSB_VERBOSE_PRINT2 ("GetEndpointDescriptor Alt Setting %d Endpoint %d",iTestParams.alternateSetting, iTestParams.inPipe);
   175 		TInt r = iPort->GetEndpointDescriptor(iTestParams.alternateSetting, (TENDPOINTNUMBER)iTestParams.inPipe, descriptor);
   176 		if (r != KErrNone)
   177 			{
   178 			TUSB_PRINT("Failed to get endpoint descriptor");
   179 			test(EFalse);
   180 			return;
   181 			}
   182 
   183 		TInt maxPktSz = EpSize(descriptor[KEpDesc_PacketSizeOffset],descriptor[KEpDesc_PacketSizeOffset+1]);		
   184 		TUSB_VERBOSE_PRINT5 ("In Endpoint 0x%x attributes 0x%x interface %d setting %d max packet size %d",
   185 			descriptor[KEpDesc_AddressOffset],descriptor[KEpDesc_AttributesOffset],iTestParams.interfaceNumber,iTestParams.alternateSetting,maxPktSz);
   186 		if (!gSkip && maxPktSz != gInterfaceConfig[iTestParams.interfaceNumber][iTestParams.alternateSetting]->iInfoPtr->iEndpointData[iTestParams.inPipe-1].iSize)
   187 			{
   188 			TUSB_PRINT4("Error - Interface %d Setting %d Endpoint %d Max Packet Size %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.inPipe,maxPktSz);
   189 			test(EFalse);
   190 			return;
   191 			}
   192 		}
   193 		
   194 	}
   195 
   196 
   197 void CActiveRW::SetTransferMode(TXferMode aMode)
   198 	{
   199 	iXferMode = aMode;
   200 	if (aMode == EReceiveOnly || aMode == ETransmitOnly)
   201 		{
   202 		// For streaming transfers we do this only once.
   203 		iBufSz = iTestParams.maxSize;
   204 		}
   205 	}
   206 
   207 void CActiveRW::Suspend(TXferType aType)
   208 	{
   209 	if (aType == ESuspend)
   210 		TUSB_VERBOSE_PRINT1("Index %d Suspend",iIndex);
   211 	if (aType == EAltSetting)
   212 		TUSB_VERBOSE_PRINT3("Index %d Suspend for Alternate Setting - interface %d setting %d",iIndex,iTestParams.interfaceNumber,iTestParams.alternateSetting);	
   213 	iStatus = KRequestPending;
   214 	iCurrentXfer = aType;
   215 	if (!IsActive())
   216 		{
   217 		SetActive();
   218 		}
   219 	}
   220 
   221 void CActiveRW::Resume()
   222 	{	
   223 	TUSB_VERBOSE_PRINT3("Index %d Resume interface %d setting %d",iIndex,iTestParams.interfaceNumber,iTestParams.alternateSetting);
   224 	TRequestStatus* status = &iStatus;
   225 	User::RequestComplete(status,KErrNone);
   226 	if (!IsActive())
   227 		{
   228 		SetActive();
   229 		}
   230 	}
   231 
   232 void CActiveRW::Yield()
   233 	{
   234 	TUSB_VERBOSE_PRINT1("Index %d Scheduler Yield",iIndex);
   235 	// removes the active object from the scheduler queue then adds it back in again
   236 	Deque();	
   237 	CActiveScheduler::Add(this);
   238 	}
   239 
   240 void CActiveRW::ResumeAltSetting(TUint aAltSetting)
   241 	{
   242 	if (iCurrentXfer == EAltSetting && iTestParams.alternateSetting == aAltSetting)
   243 		{
   244 		Resume();
   245 		}
   246 	}
   247 
   248 void CActiveRW::StartOrSuspend()
   249 	{
   250 	TInt altSetting;
   251 	
   252 	iPort->GetAlternateSetting (altSetting);
   253 	if (iTestParams.alternateSetting != altSetting)
   254 		{
   255 		Suspend(EAltSetting);
   256 		}
   257 	else
   258 		{
   259 		#ifdef USB_SC
   260 		TInt r;
   261 		if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber])
   262 			{
   263 			gSettingNumber[iTestParams.interfaceNumber] = iTestParams.alternateSetting;
   264 			r = iPort->StartNextOutAlternateSetting(ETrue);
   265 			TUSB_VERBOSE_PRINT1("StartNextOutAlternateSetting retValue %d",r);
   266 			test_Value(r, (r >= KErrNone) || (r == KErrNotReady)   || (r == KErrGeneral));
   267 			}
   268 		TUSB_VERBOSE_PRINT4 ("CActiveRW::StartOrSuspend() interface %d setting %d Out %d In %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe,iTestParams.inPipe);
   269 		if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient)
   270 			{
   271 			r = iPort->OpenEndpoint(iSCReadBuf,iTestParams.outPipe);
   272 			test_KErrNone(r);
   273 			}
   274 		if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient)
   275 			{
   276 			r = iPort->OpenEndpoint(iSCWriteBuf,iTestParams.inPipe);
   277 			test_KErrNone(r);
   278 			}
   279 		#endif
   280 		if (iXferMode == EReceiveOnly)
   281 			{
   282 			// read data and process any available
   283 			iReadSize = ReadData();
   284 			if (iReadSize != 0)
   285 				{
   286 				ProcessReadXfer();
   287 				}
   288 			}
   289 		else
   290 			{
   291 			SendData();										// or we send data
   292 			if (iXferMode == ETransmitOnly)
   293 				{
   294 				iPktNum++;				
   295 				iRepeat++;		
   296 				}
   297 			}	
   298 		}
   299 	}
   300 
   301 void CActiveRW::RunL()
   302 	{
   303 	#ifdef USB_SC
   304 	TInt r = 0;
   305 	#else
   306 	TInt altSetting;	
   307 	#endif
   308 	
   309 	TUSB_VERBOSE_PRINT("CActiveRW::RunL()");
   310 
   311 	if ((iStatus != KErrNone) && (iStatus != KErrEof))
   312 		{
   313 		TUSB_PRINT1("Error %d in RunL", iStatus.Int());
   314 		}
   315 	if (iDoStop)
   316 		{
   317 		TUSB_PRINT("Stopped");
   318 		iDoStop = EFalse;
   319 		return;
   320 		}
   321 	switch (iCurrentXfer)
   322 		{
   323 	case EWaitSetting:
   324 		#ifdef USB_SC
   325 		if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient)
   326 			{
   327 			r = iSCReadBuf.Close();
   328 			test_KErrNone(r);
   329 			}
   330 		if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient)
   331 			{
   332 			r = iSCWriteBuf.Close();
   333 			test_KErrNone(r);
   334 			}
   335 		#endif
   336 		if (iTestParams.settingRepeat  && ((iRepeat < iTestParams.repeat) || !iLastSetting))
   337 			{
   338 			gRW[iTestParams.afterIndex]->Resume();			
   339 			}
   340 		Suspend(ESuspend);	
   341 		break;
   342 			
   343 	case ESuspend:
   344 		#ifdef USB_SC
   345 		TUSB_VERBOSE_PRINT3("Index %d Resumed interface %d setting test=%d",iIndex,iTestParams.interfaceNumber,iTestParams.alternateSetting);	
   346 		if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber])
   347 			{
   348 			r = iPort->StartNextOutAlternateSetting(ETrue);
   349 			TUSB_VERBOSE_PRINT1("StartNextOutAlternateSetting retValue %d",r);
   350 			test_Value(r, (r >= KErrNone) || (r == KErrNotReady)  || (r == KErrGeneral));
   351 			if (r != KErrNotReady)
   352 				{
   353 				gSettingNumber[iTestParams.interfaceNumber] = r;
   354 				}
   355 			if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber])
   356 				{
   357 				Suspend(EAltSetting);
   358 				break;
   359 				}
   360 			}
   361 		#else
   362 		iPort->GetAlternateSetting (altSetting);
   363 		TUSB_VERBOSE_PRINT4("Index %d Resumed interface %d setting test=%d actual=%d",iIndex,iTestParams.interfaceNumber,iTestParams.alternateSetting,altSetting);	
   364 		if (gAltSettingOnNotify)
   365 			{
   366 			if (iTestParams.alternateSetting != altSetting)
   367 				{
   368 				Suspend(EAltSetting);
   369 				break;
   370 				}
   371 			}
   372 		#endif
   373 			
   374 		// If alternate setting is ok drops through to EAltSetting to start next read or write
   375 		iCurrentXfer = EAltSetting;
   376 			
   377 	case EAltSetting:
   378 		#ifdef USB_SC
   379 		if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber])
   380 			{
   381 			r = iPort->StartNextOutAlternateSetting(ETrue);
   382 			TUSB_VERBOSE_PRINT1("StartNextOutAlternateSetting retValue %d",r);
   383 			test_Value(r, (r >= KErrNone) || (r == KErrNotReady)   || (r == KErrGeneral));
   384 			if (r != KErrNotReady)
   385 				{
   386 				gSettingNumber[iTestParams.interfaceNumber] = r;
   387 				}
   388 			if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber])
   389 				{
   390 				Suspend(EAltSetting);
   391 				break;
   392 				}
   393 			}
   394 		TUSB_VERBOSE_PRINT4 ("CActiveRW::Runl() EAltSetting interface %d setting %d Out %d In %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe,iTestParams.inPipe);
   395 		if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient)
   396 			{
   397 			r = iPort->OpenEndpoint(iSCReadBuf,iTestParams.outPipe);
   398 			test_KErrNone(r);
   399 			}
   400 		if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient)
   401 			{
   402 			r = iPort->OpenEndpoint(iSCWriteBuf,iTestParams.inPipe);
   403 			test_KErrNone(r);
   404 			}
   405 		#endif
   406 		if (iXferMode == EReceiveOnly)
   407 			{
   408 			// read data and process any available
   409 			iReadSize = ReadData();
   410 			if (iReadSize != 0)
   411 				{
   412 				ProcessReadXfer();
   413 				}		
   414 			}
   415 		else
   416 			{
   417 			SendData();										// or we send data
   418 			if (iXferMode == ETransmitOnly)
   419 				{
   420 				iPktNum++;				
   421 				iRepeat++;		
   422 				}
   423 			}
   424 		break;
   425 
   426 	case EWriteXfer:
   427 		ProcessWriteXfer();
   428 		break;
   429 		
   430 	case EReadXfer:
   431 		#ifdef USB_SC
   432 		iReadSize = ReadData();
   433 		if (iReadSize != 0)
   434 			{
   435 			ProcessReadXfer();
   436 			}
   437 		#else
   438 		iReadSize = iReadBuf.Length();
   439 		ProcessReadXfer();
   440 		#endif
   441 		break;
   442 		
   443 	default:
   444 		TUSB_PRINT("Oops. (Shouldn't end up here...)");
   445 		break;
   446 		}
   447 	return;
   448 	}
   449 
   450 void CActiveRW::ProcessWriteXfer()
   451 	{
   452 	if (iXferMode == ETransmitOnly)
   453 		{
   454 		if (iTestParams.settingRepeat && iRepeat)
   455 			{	
   456 			if (((iRepeat % iTestParams.settingRepeat) == 0) || (iRepeat >= iTestParams.repeat))
   457 				{
   458 				if ((iRepeat < iTestParams.repeat) || !iLastSetting)
   459 					{
   460 					#ifdef USB_SC
   461 					if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient)
   462 						{
   463 						test_KErrNone(iSCWriteBuf.Close());
   464 						}
   465 					#endif
   466 					gRW[iTestParams.afterIndex]->Resume();			
   467 					}
   468 				if (iRepeat < iTestParams.repeat)
   469 					{
   470 					Suspend(ESuspend);	
   471 					return;					
   472 					}
   473 				}
   474 			}
   475 
   476 		if ((iTestParams.repeat == 0) || (iRepeat < iTestParams.repeat))
   477 			{
   478 			// Yield the scheduler to ensure other activeObjects can run
   479 			if (iRepeat && gYieldRepeat)
   480 				{
   481 				if ((iRepeat % gYieldRepeat) == 0)
   482 					{
   483 					Yield();
   484 					}
   485 				}
   486 			SendData();							// next we send data			
   487 			iPktNum++;				
   488 			iRepeat++;
   489 			}
   490 		else
   491 			{
   492 			TestComplete(ETrue);
   493 			}
   494 		}
   495 	else
   496 		{
   497 		// read data and process any available
   498 		iReadSize = ReadData();
   499 		if (iReadSize != 0)
   500 			{
   501 			ProcessReadXfer();
   502 			}
   503 		}
   504 
   505 	return;
   506 	}
   507 
   508 void CActiveRW::ProcessReadXfer()
   509 	{
   510 	if ((iReadOffset + iReadSize) > iBufSz)
   511 		{
   512 		TUSB_PRINT2("*** rcv'd too much data: 0x%x (expected: 0x%x)", iReadOffset + iReadSize, iBufSz);
   513 		test(EFalse);
   514 		}
   515 
   516 	if (iXferMode == EReceiveOnly)
   517 		{
   518 		if (iReadOffset == 0)
   519 			{
   520 			#ifdef USB_SC
   521 			const TUint32 num = *reinterpret_cast<const TUint32*>(iSCReadData);
   522 			#else
   523 			const TUint32 num = *reinterpret_cast<const TUint32*>(iReadBuf.Ptr());
   524 			#endif	
   525 			if (num != iPktNum)
   526 				{
   527 				TUSB_PRINT3("*** Repeat %d rcv'd wrong pkt number: 0x%x (expected: 0x%x)", iRepeat, num, iPktNum);
   528 				iPktNum = num;
   529 				test(EFalse);
   530 				}
   531 			}
   532 		if (iDiskAccessEnabled)
   533 			{
   534 			// Write out to disk previous completed Read
   535 			#ifdef USB_SC
   536 			TPtr8 readBuf((TUint8 *)iSCReadData,iReadSize,iReadSize);
   537 			WriteBufferToDisk(readBuf, iReadSize);
   538 			#else	
   539 			TUSB_VERBOSE_PRINT2("Max Buffer Size = %d (iReadBuf.Size(): %d)", iTestParams.maxSize, iReadBuf.Size());
   540 			WriteBufferToDisk(iReadBuf, iTestParams.maxSize);
   541 			#endif
   542 			}		
   543 		iReadOffset += iReadSize;
   544 		if (iReadOffset >= iBufSz)
   545 			{
   546 			iReadOffset = 0;			
   547 			}
   548 		else
   549 			{
   550 			#ifdef USB_SC
   551 			iReadSize = ReadData();
   552 			if (iReadSize)
   553 				{
   554 				ProcessReadXfer();
   555 				}
   556 			#endif
   557 			return;
   558 			}
   559 		iPktNum++;
   560 		iRepeat++;
   561 		iReadSize = 0;
   562 		if (iTestParams.settingRepeat)
   563 			{	
   564 			if (((iRepeat % iTestParams.settingRepeat) == 0) || (iRepeat >= iTestParams.repeat))
   565 				{
   566 				#ifdef USB_SC
   567 				if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient)
   568 					{
   569 					test_KErrNone(iSCReadBuf.Close());
   570 					}
   571 				#endif
   572 				if ((iRepeat < iTestParams.repeat) || !iLastSetting)
   573 					{
   574 					gRW[iTestParams.afterIndex]->Resume();			
   575 					}
   576 				if (iRepeat < iTestParams.repeat)
   577 					{
   578 					Suspend(ESuspend);	
   579 					return;					
   580 					}
   581 				}
   582 			}
   583 		if ((iTestParams.repeat == 0) || (iRepeat < iTestParams.repeat))
   584 			{
   585 			// Yield the scheduler to ensure other activeObjects can run
   586 			if (iRepeat && gYieldRepeat)
   587 				{
   588 				if ((iRepeat % gYieldRepeat) == 0)
   589 					{
   590 					Yield();
   591 					}
   592 				}
   593 			#ifdef USB_SC
   594 			TRequestStatus* status = &iStatus;
   595 			User::RequestComplete(status,KErrNone);
   596 			if (!IsActive())
   597 				{
   598 				SetActive();
   599 				}	
   600 			#else
   601 			iReadSize = ReadData();			
   602 			#endif
   603 			}
   604 		else
   605 			{
   606 			TestComplete(ETrue);
   607 			}
   608 		}
   609 	else
   610 		{
   611 		if (iXferMode == ELoopComp)
   612 			{
   613 			test(CompareBuffers());
   614 			}
   615 		else if (iBufSz > 3)
   616 			{
   617 			if (iReadOffset == 0)
   618 				{
   619 				#ifdef USB_SC
   620 				const TUint32 num = *reinterpret_cast<const TUint32*>(iSCReadData);
   621 				#else
   622 				const TUint32 num = *reinterpret_cast<const TUint32*>(iReadBuf.Ptr());
   623 				#endif
   624 				if (num != iPktNum)
   625 					{
   626 					TUSB_PRINT2("*** rcv'd wrong pkt number: 0x%x (expected: 0x%x)", num, iPktNum);
   627 					}
   628 				}
   629 			}
   630 		iReadOffset += iReadSize;
   631 		if (iReadOffset >= iBufSz)
   632 			{
   633 			iReadOffset = 0;			
   634 			}
   635 		else
   636 			{
   637 			iReadSize = ReadData();
   638 			if (iReadSize)
   639 				{
   640 				ProcessReadXfer();
   641 				}
   642 			return;
   643 			}
   644 		if ((TUint)iBufSz == iTestParams.maxSize)
   645 			{
   646 			iBufSz = iTestParams.minSize;
   647 			}
   648 		else
   649 			{
   650 			iBufSz++;
   651 			}
   652 		iPktNum++;
   653 		iRepeat++;
   654 		iReadSize = 0;
   655 		if (iTestParams.settingRepeat)
   656 			{	
   657 			if (((iRepeat % iTestParams.settingRepeat) == 0) || (iRepeat >= iTestParams.repeat))
   658 				{
   659 				if (iRepeat < iTestParams.repeat)
   660 					{
   661 					SendWaitSetting();
   662 					return;					
   663 					}
   664 				else
   665 					{
   666 					#ifdef USB_SC
   667 					if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient)
   668 						{
   669 						test_KErrNone(iSCReadBuf.Close());
   670 						}
   671 					if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient)
   672 						{
   673 						test_KErrNone(iSCWriteBuf.Close());
   674 						}
   675 					#endif	
   676 					if (!iLastSetting)
   677 						{
   678 						gRW[iTestParams.afterIndex]->Resume();			
   679 						}
   680 					}
   681 				}
   682 			}
   683 			
   684 		if ((iTestParams.repeat == 0) || (iRepeat < iTestParams.repeat))
   685 			{
   686 			// Yield the scheduler to ensure other activeObjects can run
   687 			if (iRepeat && gYieldRepeat)
   688 				{
   689 				if ((iRepeat % gYieldRepeat) == 0)
   690 					{
   691 					Yield();
   692 					}
   693 				}
   694 			SendData();				
   695 			}
   696 		else
   697 			{
   698 			TestComplete(ETrue);
   699 			}	
   700 		}
   701 
   702 	return;
   703 	}
   704 
   705 void CActiveRW::SendWaitSetting()
   706 	{
   707 	__ASSERT_ALWAYS(!IsActive(), User::Panic(KActivePanic, 662));
   708 	#ifdef	USB_SC
   709 	TAny* inBuffer;
   710 	TUint inBufLength;
   711 	test_KErrNone(iSCWriteBuf.GetInBufferRange(inBuffer, inBufLength));
   712 	test_KErrNone(iSCWriteBuf.WriteBuffer(inBuffer,KWaitSettingSize,FALSE,iStatus));
   713 	#else
   714 	iWriteBuf.SetLength(KWaitSettingSize);
   715 	iPort->Write(iStatus, (TENDPOINTNUMBER)iTestParams.inPipe, iWriteBuf, KWaitSettingSize);
   716 	#endif
   717 	iCurrentXfer = EWaitSetting;
   718 	if (!IsActive())
   719 		{
   720 		SetActive();
   721 		}
   722 	}
   723 
   724 	
   725 void CActiveRW::SendData()
   726 	{
   727 	__ASSERT_ALWAYS(!IsActive(), User::Panic(KActivePanic, 663));
   728 	#ifdef	USB_SC
   729 	TUint8* inBuffer;
   730 	TUint inBufLength;
   731 	test_KErrNone(iSCWriteBuf.GetInBufferRange((TAny*&)inBuffer, inBufLength));
   732 	if (iDiskAccessEnabled)
   733 		{
   734 		TPtr8 writeBuf((TUint8 *)inBuffer,iBufSz,iBufSz);
   735 		ReadBufferFromDisk(writeBuf, iBufSz);
   736 		}
   737 	if (iBufSz > 3)
   738 		*reinterpret_cast<TUint32*>(inBuffer) = iPktNum;
   739 	
   740 	if (iXferMode == ELoopComp)
   741 		{
   742 		for (TUint i = 4; i < iBufSz; i++)
   743 			{
   744 			*(inBuffer+i) = static_cast<TUint8>((iPktNum+i) & 0x000000ff);
   745 			}
   746 		}
   747 	TUSB_VERBOSE_PRINT3("SendData interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.inPipe);
   748 	iCurrentXfer = EWriteXfer;
   749 	TInt r = iSCWriteBuf.WriteBuffer(inBuffer, iBufSz, FALSE, iStatus);
   750 	test_KErrNone(r);
   751 	#else
   752 	if (iDiskAccessEnabled)
   753 		{
   754 		ReadBufferFromDisk(iWriteBuf, iBufSz);
   755 		}
   756 	iWriteBuf.SetLength(iBufSz);
   757 	if (iBufSz > 3)
   758 		*reinterpret_cast<TUint32*>(const_cast<TUint8*>(iWriteBuf.Ptr())) = iPktNum;
   759 	if (iXferMode == ELoopComp)
   760 		{
   761 		for (TUint i = 4; i < iBufSz; i++)
   762 			{
   763 			iWriteBuf[i] = static_cast<TUint8>((iPktNum+i) & 0x000000ff);
   764 			}
   765 		}
   766 
   767 	TUSB_VERBOSE_PRINT3("SendData interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.inPipe);
   768 	iCurrentXfer = EWriteXfer;
   769 	iPort->Write(iStatus, (TENDPOINTNUMBER)iTestParams.inPipe, iWriteBuf, iBufSz);
   770 	#endif
   771 	if (!IsActive())
   772 		{
   773 		SetActive();
   774 		}
   775 	}
   776 
   777 TInt CActiveRW::WriteToDisk(TChar aDriveLetter)
   778 	{
   779 	iDiskAccessEnabled = ETrue;
   780 	TInt r = KErrNone;
   781 
   782 	iFileName.Format(_L("%c:"), aDriveLetter.operator TUint());
   783 	iFileName.Append(KFileName);
   784 	TUSB_PRINT1("\nFilename = %S", &iFileName);
   785 
   786 	// open the record file
   787 	r = iFile.Replace(iFs, iFileName, EFileWrite);
   788 	iFileOffset = 0;
   789 	if (r != KErrNone)
   790 		{
   791 		TUSB_PRINT1("RFile::Replace() returned %d", r);
   792 		iDiskAccessEnabled = EFalse;
   793 		return r;
   794 		}
   795 		
   796 	return r;
   797 	}
   798 
   799 
   800 TInt CActiveRW::ReadFromDisk(TChar aDriveLetter, TInt aMaxFileSize)
   801 	{
   802 	iDiskAccessEnabled = ETrue;
   803 	TInt r = KErrNone;
   804 
   805 	iFileName.Format(_L("%c:"), aDriveLetter.operator TUint());
   806 	iFileName.Append(KFileName);
   807 	TUSB_PRINT1("\nFilename = %S", &iFileName);
   808 	TUSB_PRINT1("File size: %d", aMaxFileSize);
   809 
   810 	// First create the file & fill it
   811 	r = iFile.Replace(iFs, iFileName, EFileWrite);
   812 	if (r != KErrNone)
   813 		{
   814 		TUSB_PRINT1("RFile::Replace() returned %d", r);
   815 		iDiskAccessEnabled = EFalse;
   816 		return r;
   817 		}
   818 	const TInt KBufferSize = 4 * 1024;
   819 	TBuf8<KBufferSize> buffer;
   820 	buffer.SetLength(KBufferSize);
   821 	for (TInt n = 0; n < KBufferSize; n++)
   822 		{
   823 		buffer[n] = static_cast<TUint8>(n & 0x000000ff);
   824 		}
   825 	TUSB_PRINT("Writing data to file (this may take some minutes...)");
   826 	for (TInt n = 0; n < aMaxFileSize; n += KBufferSize)
   827 		{
   828 		r = iFile.Write(buffer, KBufferSize);
   829 		if (r != KErrNone)
   830 			{
   831 			TUSB_PRINT1("RFile::Write() returned %d (disk full?)", r);
   832 			iFile.Close();
   833 			iDiskAccessEnabled = EFalse;
   834 			return r;
   835 			}
   836 		}
   837 	TUSB_PRINT("Done.");
   838 	iFile.Close();
   839 	// Now open the file for reading
   840 	r = iFile.Open(iFs, iFileName, EFileRead);
   841 	if (r != KErrNone)
   842 		{
   843 		TUSB_PRINT1("RFile::Open() returned %d", r);
   844 		iDiskAccessEnabled = EFalse;
   845 		return r;
   846 		}
   847 	iFileOffset = 0;
   848 
   849 	return r;
   850 	}
   851 
   852 
   853 void CActiveRW::WriteBufferToDisk(TDes8& aBuffer, TInt aLen)
   854 	{
   855 	TUSB_VERBOSE_PRINT1("CActiveRW::WriteBufferToDisk(), len = %d", aLen);
   856 	TInt r = iFile.Write(aBuffer, aLen);
   857 	if (r != KErrNone)
   858 		{
   859 		TUSB_PRINT2("Error writing to %S (%d)", &iFileName, r);
   860 		iDiskAccessEnabled = EFalse;
   861 		return;
   862 		}
   863 	iFileOffset += aLen;
   864 	}
   865 
   866 
   867 void CActiveRW::ReadBufferFromDisk(TDes8& aBuffer, TInt aLen)
   868 	{
   869 	const TInt r = iFile.Read(aBuffer, aLen);
   870 	if (r != KErrNone)
   871 		{
   872 		TUSB_PRINT2("Error reading from %S (%d)", &iFileName, r);
   873 		iDiskAccessEnabled = EFalse;
   874 		return;
   875 		}
   876 	TInt readLen = aBuffer.Length();
   877 	TUSB_VERBOSE_PRINT1("CActiveRW::ReadBufferFromDisk(), len = %d\n", readLen);
   878 	if (readLen < aLen)
   879 		{
   880 		TUSB_PRINT3("Only %d bytes of %d read from file %S)",
   881 					readLen, aLen, &iFileName);
   882 		iDiskAccessEnabled = EFalse;
   883 		return;
   884 		}
   885 	iFileOffset += aLen;
   886 	}
   887 
   888 
   889 TUint CActiveRW::ReadData()
   890 	{
   891 	__ASSERT_ALWAYS(!IsActive(), User::Panic(KActivePanic, 664));
   892 	iCurrentXfer = EReadXfer;
   893 	#ifdef	USB_SC
   894 	TUint readSize = 0;			// note that this returns zero when asynchronous read is pending 
   895 	TInt r = 0;
   896 	do
   897 		{
   898 		r = iSCReadBuf.GetBuffer (iSCReadData,readSize,iReadZlp,iStatus);
   899 		test_Value(r, (r == KErrNone) || (r == KErrCompletion) || (r == KErrEof));
   900 		TUSB_VERBOSE_PRINT4("Get Buffer Return code %d Status %d DataPtr 0x%x Size %d", r, iStatus.Int(),iSCReadData,readSize);	
   901 		}
   902 	while ((r == KErrCompletion && readSize == 0) || (r == KErrEof));
   903 	if (r == KErrCompletion)
   904 		{
   905 		return readSize;
   906 		}
   907 	else
   908 		{
   909 		if (!IsActive())
   910 			{
   911 			SetActive();
   912 			}
   913 		return 0;
   914 		}
   915 	#else
   916 	iReadBuf.SetLength (0);
   917 	if (iBufSz <= iMaxPktSz)
   918 		{
   919 		// Testing the packet version of Read()
   920 		TUSB_VERBOSE_PRINT3("ReadData (single packet) interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe);
   921 		iPort->ReadPacket(iStatus, (TENDPOINTNUMBER)iTestParams.outPipe, iReadBuf, iBufSz);
   922 		}
   923 	else if ((TUint)iBufSz == iTestParams.maxSize)
   924 		{
   925 		// Testing the two-parameter version
   926 		TUSB_VERBOSE_PRINT3("ReadData (w/o length) interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe);
   927 		iPort->Read(iStatus, (TENDPOINTNUMBER)iTestParams.outPipe, iReadBuf);
   928 		}
   929 	else
   930 		{
   931 		// otherwise, we use the universal default version
   932 		// Testing the three-parameter version
   933 		TUSB_VERBOSE_PRINT3("ReadData (normal) interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe);
   934 		iPort->Read(iStatus, (TENDPOINTNUMBER)iTestParams.outPipe, iReadBuf, iBufSz);
   935 		}
   936 	if (!IsActive())
   937 		{
   938 		SetActive();
   939 		}
   940 	return 0;
   941 	#endif
   942 	}
   943 
   944 
   945 void CActiveRW::Stop()
   946 	{
   947 	if (!IsActive())
   948 		{
   949 		TUSB_PRINT("CActiveRW::Stop(): Not active");
   950 		return;
   951 		}
   952 	TUSB_PRINT("Cancelling outstanding transfer requests\n");
   953 	iBufSz = 0;
   954 	iPktNum = 0;
   955 	iDoStop = ETrue;
   956 	iCurrentXfer = ETxferNone;
   957 	Cancel();
   958 	}
   959 
   960 
   961 void CActiveRW::DoCancel()
   962 	{
   963 	TUSB_VERBOSE_PRINT("CActiveRW::DoCancel()");
   964 	// Canceling the transfer requests can be done explicitly
   965 	// for every transfer...
   966 	iPort->WriteCancel((TENDPOINTNUMBER)iTestParams.inPipe);
   967 	iPort->ReadCancel((TENDPOINTNUMBER)iTestParams.outPipe);
   968 	// or like this:
   969 	// iPort->EndpointTransferCancel(~0);	
   970 	}
   971 
   972 
   973 TBool CActiveRW::CompareBuffers()
   974 	{
   975 	TUSB_VERBOSE_PRINT2("CActiveRW::CompareBuffers() ReadOffset %d ReadSize %d",iReadOffset,iReadSize);
   976 	#ifdef USB_SC
   977 	TUint8 *readPtr = reinterpret_cast<TUint8*>(iSCReadData);
   978 	TUint8* writePtr;
   979 	TUint inBufLength;
   980 	test_KErrNone(iSCWriteBuf.GetInBufferRange((TAny*&)writePtr, inBufLength));
   981 	writePtr += iReadOffset;
   982 	#endif
   983 	for (TUint i = 0; i < iReadSize; i++)
   984 		{
   985 		#ifdef USB_SC
   986 		if (*readPtr != *writePtr)
   987 			{
   988 			TUSB_PRINT3 ("*** Error while comparing tx & rx buffers packet 0x%x length %d index %d",iPktNum, iReadSize,i + iReadOffset); 
   989 			TUSB_PRINT2 ("*** Read byte 0x%x Write byte 0x%x",*readPtr,*writePtr); 
   990 			return EFalse;
   991 			}
   992 		readPtr++;
   993 		writePtr++;
   994 		#else
   995 		if (iReadBuf[i] != iWriteBuf[i + iReadOffset])
   996 			{
   997 			TUSB_PRINT3 ("*** Error while comparing tx & rx buffers packet 0x%x length %d index %d",iPktNum, iReadSize,i + iReadOffset); 
   998 			TUSB_PRINT5 ("WriteBuf Start 0x%x 0x%x 0x%x 0x%x 0x%x",
   999 				iWriteBuf[i], iWriteBuf[i+1], iWriteBuf[i+2], iWriteBuf[i+3], iWriteBuf[i+4]); 
  1000 			TUSB_PRINT5 ("ReadBuf Start 0x%x 0x%x 0x%x 0x%x 0x%x",
  1001 				iReadBuf[i], iReadBuf[i+1], iReadBuf[i+2], iReadBuf[i+3], iReadBuf[i+4]);
  1002 			if (iReadSize >= 10)
  1003 				{
  1004 				TUSB_PRINT5 ("WriteBuf End 0x%x 0x%x 0x%x 0x%x 0x%x",
  1005 					iWriteBuf[iReadSize-5], iWriteBuf[iReadSize-4], iWriteBuf[iReadSize-3], iWriteBuf[iReadSize-2], iWriteBuf[iReadSize-1]); 
  1006 				TUSB_PRINT5 ("ReadBuf End 0x%x 0x%x 0x%x 0x%x 0x%x",
  1007 					iReadBuf[iReadSize-5], iReadBuf[iReadSize-4], iReadBuf[iReadSize-3], iReadBuf[iReadSize-2], iReadBuf[iReadSize-1]); 
  1008 				}
  1009 			return EFalse;
  1010 			}
  1011 		#endif
  1012 		}
  1013 	return ETrue;
  1014 	}
  1015 
  1016 void CActiveRW::TestComplete(TBool aResult)
  1017 	{
  1018 	TUSB_VERBOSE_PRINT("CActiveRW::TestComplete()");
  1019 
  1020 	iResult = aResult;
  1021 	
  1022 	if (iComplete || !iResult || iTestParams.repeat == 0)
  1023 		{
  1024 		test(iResult);
  1025 		test.End();
  1026 		gRW[iIndex] = NULL;
  1027 		delete this;
  1028 		}
  1029 	else
  1030 		{
  1031 		iComplete = ETrue;
  1032 		}
  1033 	}
  1034 
  1035 // -eof-