os/kernelhwsrv/kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-1230.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-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 // @file PBASE-T_USBDI-1230.cpp
    15 // @internalComponent
    16 // 
    17 //
    18 
    19 #include "PBASE-T_USBDI-1230.h"
    20 #include "testpolicy.h"
    21 #include "modelleddevices.h"
    22 #include "testliterals.h"
    23 
    24 
    25  
    26 
    27 namespace NUnitTesting_USBDI
    28 	{
    29 const TUint KTotalBytesToTransfer = 1024*64+511; //64kB + 511 bytes
    30 const TUint KHostNumReadBytes = 1024*16;
    31 const TInt KBulkMaxTransferSize = KHostNumReadBytes + 1000;
    32 const TInt KDeviceNumWriteBytes = 1024;
    33 
    34 
    35 //Make these single bit values ... 
    36 // ... so that their completion can be easily recorded in a bit mask!
    37 const TUint32 KBulkTransferInId0 = 1<<0;
    38 const TUint32 KBulkTransferInId1 = 1<<1; 
    39 const TUint32 KBulkTransferInId[KMaxNumInTransfers] = {KBulkTransferInId0, KBulkTransferInId1};
    40 const TUint32 KBulkTransferIdMask = KBulkTransferInId[0] | KBulkTransferInId[1];
    41 
    42 const TInt KUndefinedStep	 		= -102;
    43 const TInt KUnexpectedTransferID 	= -103;
    44 const TInt KErrReturnedDeviceReadBytesTooVariable = -140;
    45 const TInt KTransferSuccess	 = +100;
    46 
    47 const TUint KRepeatedTimerInterval = 10000; //10ms
    48 const TUint KBaseTimer = 0;
    49 const TUint KTestTimer = 1;
    50 const TUint KMaxTimeDiffPercentage = 60; //on inspection worst result was just under 70%
    51 const TUint KMaxBytesWrittenDiffPercentage = 50;
    52 
    53 
    54 
    55 
    56 _LIT(KTestCaseId,"PBASE-T_USBDI-1230");
    57 const TFunctorTestCase<CUT_PBASE_T_USBDI_1230,TBool> CUT_PBASE_T_USBDI_1230::iFunctor(KTestCaseId);	
    58 
    59 CUT_PBASE_T_USBDI_1230* CUT_PBASE_T_USBDI_1230::NewL(TBool aHostRole)
    60 	{
    61 	CUT_PBASE_T_USBDI_1230* self = new (ELeave) CUT_PBASE_T_USBDI_1230(aHostRole);
    62 	CleanupStack::PushL(self);
    63 	self->ConstructL();
    64 	CleanupStack::Pop(self);
    65 	return self;
    66 	}
    67 	
    68 
    69 CUT_PBASE_T_USBDI_1230::CUT_PBASE_T_USBDI_1230(TBool aHostRole)
    70 :	CBaseBulkTestCase(KTestCaseId,aHostRole),
    71 	iCaseStep(EInProgress)
    72 	{
    73 	} 
    74 
    75 
    76 void CUT_PBASE_T_USBDI_1230::ConstructL()
    77 	{
    78 	BaseBulkConstructL();
    79 
    80 	iInBuffer = HBufC8::NewL(KTestBufferLength);
    81 
    82 	iBulkTestTimer = CBulkTestTimer::NewL(*this);	
    83 
    84 	//Create buffer to contain multiple lots of the payload pattern
    85 	//..so that we may grab cyclic chunks of said payload pattern
    86 	TInt repeats = KHostNumReadBytes / (KLiteralEnglish5().Length()) + 1 + 1; //1 extra to accommodate start point plus 1 to accomodate remainder in division
    87 	iValidateBuffer = HBufC8::NewL(KLiteralEnglish5().Length() * repeats);
    88 	iValidateBufferPtr.Set(iValidateBuffer->Des());
    89 	iValidateBufferPtr.Zero();
    90 	for(TInt i=0;i<repeats;i++)
    91 		{
    92 		iValidateBufferPtr.Append(KLiteralEnglish5());
    93 		}
    94 	
    95 	RDebug::Printf("CUT_PBASE_T_USBDI_1230::ConstructL(): buffer created");
    96 	}
    97 
    98 
    99 CUT_PBASE_T_USBDI_1230::~CUT_PBASE_T_USBDI_1230()
   100 	{
   101 	LOG_FUNC
   102 	}
   103 	
   104 void CUT_PBASE_T_USBDI_1230::KillTransfers()
   105 	{
   106 	LOG_FUNC
   107 	
   108 	iInTransfer[0]->Cancel();
   109 	iInTransfer[1]->Cancel();
   110 	}
   111 
   112 void CUT_PBASE_T_USBDI_1230::ExtractDeviceReadBytes()
   113 	{
   114 	LOG_FUNC
   115 	
   116 	iControlEp0->LastRequestCompletionTime( iEndTime[KTestTimer]);
   117 	iTimingError = iTimingError == KErrNone ? CheckTimes(KBaseTimer, KTestTimer, KMaxTimeDiffPercentage) : iTimingError;
   118 	ResetTimes(KTestTimer);
   119 	
   120 	RDebug::Printf("Collect client's return of the number of bytes written on its bulk in endpoint ...");
   121 	TLex8 lex(iInBufferPtr.Left(KNumberStringLength));
   122 	TUint32 numBytes = 0;
   123 	User::LeaveIfError(lex.Val(numBytes, EDecimal));
   124 	RDebug::Printf("********************NUM*BYTES****************************");
   125 	RDebug::Printf("         NUM BYTES READ BY CLIENT ==== %d ====           ", numBytes);
   126 	RDebug::Printf("********************NUM*BYTES****************************");
   127 	RDebug::Printf("\n");
   128 
   129 	if(numBytes != 0)
   130 		//Do not count this case - it may result from the remote resetting when all bulk transfers have completed
   131 		{
   132 		TUint numBytesSinceLast = numBytes - iDeviceNumBytesReadInTotal;
   133 		iDeviceNumBytesReadInTotal = numBytes;
   134 		iDeviceMinTimedNumBytesRead = numBytesSinceLast < iDeviceMinTimedNumBytesRead ?  numBytesSinceLast : iDeviceMinTimedNumBytesRead ;
   135 		iDeviceMaxTimedNumBytesRead = numBytesSinceLast > iDeviceMaxTimedNumBytesRead ?  numBytesSinceLast : iDeviceMaxTimedNumBytesRead ;;
   136 		}
   137 	}
   138 
   139 
   140 void CUT_PBASE_T_USBDI_1230::PostTransferAction()
   141 	{
   142 	switch(iTransferResult)
   143 		{
   144 		case KErrNone:
   145 			//do nothing
   146 			return;
   147 
   148 		case KTransferSuccess:
   149 			{
   150 			// Indicates success - comparison is a match
   151 			RDebug::Printf("Comparison for IN transfer is a match");
   152 			iCaseStep = EPassed;
   153 			TTestCasePassed request;
   154 			iTransferComplete = 0; //reset
   155 			iControlEp0->SendRequest(request,this);
   156 			}
   157 			return; 
   158 			
   159 			
   160 		default:
   161 			{
   162 			iCaseStep = EFailed;
   163 			RDebug::Print(iMsg);
   164 			TTestCaseFailed request(iTransferResult,iMsg);
   165 			iControlEp0->SendRequest(request,this);
   166 			}
   167 			return;
   168 		}
   169 	}
   170 
   171 
   172 TInt CUT_PBASE_T_USBDI_1230::ValidatePreviousAndPerformNextTransfers(TInt aTransferId)
   173 		{
   174 	LOG_FUNC
   175 	
   176 	TUint8 index = 0;
   177 	switch(aTransferId)
   178 		{
   179 		case KBulkTransferInId0:
   180 			index = 0;
   181 			break;
   182 
   183 		case KBulkTransferInId1:
   184 			index = 1;
   185 			break;
   186 		
   187 		default:
   188 			_LIT(lit, "TRANSFER ID OUT OF RANGE");
   189 			User::Panic(lit, KErrArgument);
   190 			return 0; //should never get here
   191 		}
   192 
   193 	RDebug::Printf("\n");
   194 	RDebug::Printf("Transfer[%d]", index);
   195 	
   196 	
   197 	if(iNumBytesExpected[index] != 0)
   198 		{
   199 		TPtrC8 data1(iInTransfer[index]->DataPolled());
   200 		if(ValidateData(data1, iValidateBufferPtr.Mid(iValidationStringStartPointTransfer[index], iNumBytesExpected[index])) == EFalse)
   201 			{
   202 			RDebug::Printf("=====VALIDATION FAILURE: Point of Validation String Entry %d, Newly Read Bytes %d=====",iValidationStringStartPointTransfer[index], iNumBytesExpected[index]);
   203 			iIsValid = EFalse;
   204 			}
   205 		iNumBytesExpected[index] = 0; //reset
   206 		}
   207 	if(iNumBytesRequestedSoFar >= KTotalBytesToTransfer)
   208 		//if we are near the end end the other transfer will mop up remaining bytes...
   209 		{
   210 		RDebug::Printf("****ALL DONE for Transfer[%d]****", index);
   211 		return KBulkTransferInId[index];
   212 		}
   213 	iValidationStringStartPointTransfer[index] = iNumBytesRequestedSoFar%(KLiteralEnglish5().Length()); //PRIOR TO THIS TRANSFER
   214 	TUint bytesLeftToRead = KTotalBytesToTransfer - iNumBytesRequestedSoFar;
   215 	iNumBytesExpected[index] = bytesLeftToRead < KHostNumReadBytes ? bytesLeftToRead : KHostNumReadBytes;
   216 	iNumBytesRequestedSoFar += iNumBytesExpected[index];
   217 	iInTransfer[index]->TransferIn(KHostNumReadBytes); //rely on ZLP to complete the last 'TransferIn'
   218 	iExpectedNextTransferNumber = 1 - iExpectedNextTransferNumber;
   219 
   220 	return 0;
   221 	}
   222 
   223 	
   224 void CUT_PBASE_T_USBDI_1230::RequestNumBytesSent(TUint8 aTimerIndex)
   225 	{
   226 	iInBufferPtr.Set(iInBuffer->Des());
   227 	iInBufferPtr.Zero(); //reset
   228 	iInBufferPtr.SetLength(KNumberStringLength);
   229 	TInterfaceGetRecordedNumBytesReadInPayload request(1,1,iInBufferPtr);
   230 	iControlEp0->SendRequest(request,this);
   231  	iControlEp0->LastRequestStartTime( iStartTime[aTimerIndex]);
   232 	}
   233 
   234 
   235 void CUT_PBASE_T_USBDI_1230::Ep0TransferCompleteL(TInt aCompletionCode)
   236 	{
   237 	LOG_FUNC
   238 	
   239 	RDebug::Printf("Ep0TransferCompleteL with aCompletionCode = %d, test step = %d", aCompletionCode, iCaseStep);
   240 	
   241 	if(aCompletionCode != KErrNone)
   242 		{
   243 		if(iCaseStep == EFailed)
   244 			{// ignore error, nad catch the TestFailed method called further down.
   245 			RDebug::Printf("***Failure sending FAIL message to client on endpoint 0***");
   246 			}
   247 		else
   248 			{
   249 			TBuf<256> msg;
   250 			KillTransfers();
   251 			_LIT(lit, "<Error %d> Transfer to control endpoint 0 was not successful");
   252 			msg.Format(lit,aCompletionCode);
   253 			RDebug::Print(msg);
   254 			iCaseStep = EFailed;
   255 			TTestCaseFailed request(aCompletionCode,msg);
   256 			iControlEp0->SendRequest(request,this);
   257 			return;
   258 			}
   259 		}
   260 	
   261 	switch(iCaseStep)
   262 		{
   263 		// Test case passed
   264 		case EPassed:
   265 			TestPassed();
   266 			break;
   267 		
   268 		// Test case failed	
   269 		case EFailed:
   270 			TestFailed(KErrCompletion);
   271 			break;
   272 		
   273 		case EGetTimerBase:
   274 			{
   275 			iControlEp0->LastRequestCompletionTime( iEndTime[KBaseTimer]);
   276 			RDebug::Printf("Asking client for repeated 'Write'");
   277 			iCaseStep = ERequestRepeatedWrite;	
   278 			TRepeatedWriteDataRequest request(1,1,KLiteralEnglish5(),KDeviceNumWriteBytes,KTotalBytesToTransfer);// EP2 means endpoint index 2 not the actual endpoint number, here the ep with 32 byte max packet size
   279 			iControlEp0->SendRequest(request,this);
   280 			}
   281 			break;
   282 			
   283 		case ERequestRepeatedWrite:
   284 			{
   285 			RDebug::Printf("Try to perform ALL transfers");
   286 			
   287 			iCaseStep = ETransfer;	
   288 			iIsValid = ETrue; //innocent until proved guilty
   289 			RDebug::Printf("\n");
   290 			ValidatePreviousAndPerformNextTransfers(KBulkTransferInId[0]); //should not validate - just perform necessary transfers
   291 			ValidatePreviousAndPerformNextTransfers(KBulkTransferInId[1]); //should not validate - just perform necessary transfers
   292 			RDebug::Printf("\n");
   293 			_LITDBG("Bulk test timer NOT instanciated");
   294 			__ASSERT_DEBUG(iBulkTestTimer, User::Panic(lit, KErrGeneral));
   295 			iBulkTestTimer->After(KRepeatedTimerInterval);
   296 			}
   297 			break;
   298 			
   299 		case ETransfer:
   300 		// we must be getting num bytes read
   301 			{
   302 			ExtractDeviceReadBytes();
   303 	
   304 			//Restart timer
   305 			_LITDBG("Bulk test timer NOT instanciated");
   306 			__ASSERT_DEBUG(iBulkTestTimer, User::Panic(lit, KErrGeneral));
   307 			iBulkTestTimer->After(KRepeatedTimerInterval);
   308 			}
   309 			break;
   310 			
   311 		case EDelayedTransferComplete:
   312 			{
   313 			PostTransferAction();
   314 			}
   315 			break;
   316 			
   317 		default:
   318 			RDebug::Printf("<Error> Unknown test step");
   319 			TestFailed(KErrUnknown);
   320 			break;
   321 		}
   322 	}
   323 	
   324 void CUT_PBASE_T_USBDI_1230::TransferCompleteL(TInt aTransferId,TInt aCompletionCode)
   325 	{
   326 	LOG_FUNC
   327 	Cancel();
   328 	
   329 	iTransferResult = KErrNone;
   330 	RDebug::Printf("Transfer completed (id=%d), aCompletionCode = %d, test step = %d",aTransferId, aCompletionCode, iCaseStep);
   331 
   332 
   333 	switch(iCaseStep)
   334 		{
   335 		case ETransfer:
   336 			if(aCompletionCode != KErrNone)
   337 				{
   338 				KillTransfers();
   339 				iTransferResult = KErrCorrupt;
   340 				_LIT(lit, "<Error %d> The transfer completed with an error.");
   341 				iMsg.Format(lit, aCompletionCode);
   342 				break;
   343 				}
   344 			if(aTransferId != KBulkTransferInId[0] && aTransferId != KBulkTransferInId[1])
   345 				{
   346 				iTransferComplete = 0; //reset
   347 				iTransferResult = KUnexpectedTransferID;
   348 				_LIT(lit, "<Error %d> Unexpected transfer ID, wanted %d or %d, got %d");
   349 				iMsg.Format(lit, iTransferResult, KBulkTransferInId[0], KBulkTransferInId[1], aTransferId);
   350 				break;
   351 				}
   352 		
   353 			RDebug::Printf("Transfer IN %d completed - num bytes requested = %d", aTransferId, iNumBytesRequestedSoFar);
   354 	
   355 			RDebug::Printf("\n");
   356 			iTransferComplete |= ValidatePreviousAndPerformNextTransfers(aTransferId);
   357 			RDebug::Printf("\n");
   358 			
   359 			if(iTransferResult==KErrNone && (iTransferComplete & KBulkTransferIdMask) == KBulkTransferIdMask)
   360 				{
   361 				/*
   362 				Transfers all complete - now check validation
   363 				*/
   364 				RDebug::Printf("All Transfers Completed Successfully: Transfer Completion Aggregation Mask 0x%x", iTransferComplete);
   365 				iBulkTestTimer->Cancel(); //Cancel Timer 
   366 				iTransferResult = KTransferSuccess;
   367 				if(!iIsValid)
   368 					{
   369 					iTransferResult = KErrCompletion; //indicates data validation failure
   370 					iIsValid = ETrue; //reset
   371 					}
   372 			
   373 				if(iTimingError == KErrTooBig)
   374 					{
   375 					__PRINT_CONTROL_TRANSFER_TIMER_COMPARISON_WARNING
   376 					iTransferResult = KErrTooBig;
   377 					iTimingError = KErrNone; //reset
   378 					}
   379 				
   380 				if(KMaxBytesWrittenDiffPercentage*iDeviceMaxTimedNumBytesRead > KPercent*iDeviceMinTimedNumBytesRead)
   381 					{
   382 					RDebug::Printf("Device APPARENTLY reading rate erratic:-");
   383 					RDebug::Printf("Min Timed Number of Bytes = %d", iDeviceMinTimedNumBytesRead);
   384 					RDebug::Printf("Max Timed Number of Bytes = %d", iDeviceMaxTimedNumBytesRead);
   385 					iTransferResult = KErrTooBig;
   386 					iDeviceMaxTimedNumBytesRead = 0;
   387 					iDeviceMinTimedNumBytesRead = KMaxTUint;
   388 					}
   389 				}
   390 			break;
   391 
   392 		default:
   393 			iTransferResult = KUndefinedStep;
   394 			_LIT(lit, "<Error %d> Undefined case step %d reached");
   395 			iMsg.Format(lit,KUndefinedStep, iCaseStep);
   396 			break;
   397 		}
   398 
   399 
   400 	if(iTransferResult == KErrReturnedDeviceReadBytesTooVariable)
   401 		//indicates apparent device read rate validation failure
   402 		{
   403 		iMsg.Format(_L("<Error %d> Device APPEARS not to be reading bytes at a constant rate"), iTransferResult);
   404 		}
   405 
   406 	if(iTransferResult == KErrTooBig)
   407 		//indicates timing validation failure
   408 		{
   409 		iMsg.Format(_L("<Error %d> Timer comparison showed too great a difference in transfer times between the time taken by EP0 transfers with and without a bulk transfer"), iTransferResult);
   410 		}
   411 	
   412 	if(iTransferResult == KErrCompletion)
   413 		//indicates data validation failure
   414 		{
   415 		_LIT(lit, "<Error %d> Client has posted an error discovered in validation");
   416 		iMsg.Format(lit, iTransferResult);
   417 		}
   418 
   419 	if(iTransferResult != KErrNone)
   420 		{	
   421 		KillTransfers(); //harmless if tranfers are all done
   422 		if(!iControlEp0->IsActive())
   423 			{
   424 			PostTransferAction();
   425 			}
   426 		else
   427 			{
   428 			iCaseStep = EDelayedTransferComplete; //so that we move forward when the EP0 transfer has completed
   429 			}
   430 		}
   431 	}
   432 	
   433 void CUT_PBASE_T_USBDI_1230::DeviceInsertedL(TUint aDeviceHandle)
   434 	{
   435 	LOG_FUNC
   436 	
   437 	Cancel();
   438 	RDebug::Printf("this - %08x", this);
   439 	
   440 	TBuf<256> msg;
   441 	TInt err = KErrNone;
   442 	if(BaseBulkDeviceInsertedL(aDeviceHandle, EFalse) == EDeviceConfigurationError)
   443 		// Prepare for response from control transfer to client
   444 		{
   445 		err = KErrGeneral;
   446 		_LIT(lit, "Base class DeviceInsertedL failed");
   447 		msg.Format(lit);
   448 		}
   449 	else
   450 		{
   451 		if(SetUpInterfaceAndPipesL(aDeviceHandle, 2) == EDeviceConfigurationError)
   452 			// Prepare for response from control transfer to client
   453 			{
   454 			err = KErrGeneral;
   455 			_LIT(lit, "Base class SetUpInterfaceAndPipes for Interface 2 failed");
   456 			msg.Format(lit);
   457 			}
   458 		else
   459 			{
   460 	
   461 			iInTransfer[0] = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkIn,iUsbInterface1,KBulkMaxTransferSize,*this,KBulkTransferInId[0]);
   462 			iInTransfer[1] = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkIn,iUsbInterface1,KBulkMaxTransferSize,*this,KBulkTransferInId[1]);
   463 			
   464 			// Initialise the descriptors for transfer		
   465 			RDebug::Printf("Initialising the transfer descriptors - interface 1");
   466 			err = iUsbInterface1.InitialiseTransferDescriptors();
   467 			if(err != KErrNone)
   468 				{
   469 				_LIT(lit, "<Error %d> Unable to initialise transfer descriptors");
   470 				msg.Format(lit,err);
   471 				}
   472 			}
   473 		}
   474 	if(err != KErrNone)
   475 		{
   476 		RDebug::Print(msg);
   477 		iCaseStep = EFailed;
   478 		TTestCaseFailed request(err,msg);
   479 		iControlEp0->SendRequest(request,this);
   480 		}
   481 	else
   482 		{
   483 		iCaseStep = EGetTimerBase;
   484 		iDeviceMinTimedNumBytesRead = KMaxTUint;
   485 		iDeviceMaxTimedNumBytesRead = 0;
   486 		iDeviceNumBytesReadInTotal = 0;
   487 		RequestNumBytesSent(KBaseTimer);
   488 		}
   489 	}
   490 
   491 void CUT_PBASE_T_USBDI_1230::HandleBulkTestTimerFired()
   492 	{
   493 	if(iCaseStep == ETransfer)
   494 		{
   495 		RequestNumBytesSent(KTestTimer);
   496 		}
   497 	}
   498 	
   499 	} //end namespace