os/kernelhwsrv/kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-1229.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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-1229.cpp
    15 // @internalComponent
    16 // 
    17 //
    18 
    19 #include "PBASE-T_USBDI-1229.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 KHostNumWriteBytes = 1024*16;
    31 const TInt KBulkMaxTransferSize = KHostNumWriteBytes + 1000;
    32 const TInt KDeviceNumReadBytes = 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 KBulkTransferOutId[KMaxNumOutTransfers] = {1<<0, 1<<1};
    38 const TUint32 KBulkTransferIdMask = KBulkTransferOutId[0] | KBulkTransferOutId[1];
    39 
    40 const TInt KUndefinedStep	 		= -102;
    41 const TInt KUnexpectedTransferID 	= -103;
    42 const TInt KErrReturnedDeviceReadBytesTooVariable = -140;
    43 const TInt KTransferSuccess	 = +100;
    44 
    45 const TUint KRepeatedTimerInterval = 10000; //10ms
    46 const TUint KBaseTimer = 0;
    47 const TUint KTestTimer = 1;
    48 const TUint KMaxTimeDiffPercentage = 60; //on inspection worst result was just under 70%
    49 const TUint KMaxBytesReadDiffPercentage = 50;
    50 
    51 
    52 
    53 
    54 _LIT(KTestCaseId,"PBASE-T_USBDI-1229");
    55 const TFunctorTestCase<CUT_PBASE_T_USBDI_1229,TBool> CUT_PBASE_T_USBDI_1229::iFunctor(KTestCaseId);	
    56 
    57 CUT_PBASE_T_USBDI_1229* CUT_PBASE_T_USBDI_1229::NewL(TBool aHostRole)
    58 	{
    59 	CUT_PBASE_T_USBDI_1229* self = new (ELeave) CUT_PBASE_T_USBDI_1229(aHostRole);
    60 	CleanupStack::PushL(self);
    61 	self->ConstructL();
    62 	CleanupStack::Pop(self);
    63 	return self;
    64 	}
    65 	
    66 
    67 CUT_PBASE_T_USBDI_1229::CUT_PBASE_T_USBDI_1229(TBool aHostRole)
    68 :	CBaseBulkTestCase(KTestCaseId,aHostRole),
    69 	iCaseStep(EInProgress)
    70 	{
    71 	} 
    72 
    73 
    74 void CUT_PBASE_T_USBDI_1229::ConstructL()
    75 	{
    76 	BaseBulkConstructL();
    77 
    78 	iInBuffer = HBufC8::NewL(KTestBufferLength);
    79 
    80 	iBulkTestTimer = CBulkTestTimer::NewL(*this);	
    81 
    82 	//Create buffer to contain multiple lots of the payload pattern
    83 	//..so that we may grab cyclic chunks of said payload pattern
    84 	//..this is used to send to the client for validation purposes
    85 	//..AND for the host to send data
    86 	TInt repeats = KHostNumWriteBytes / (KLiteralEnglish5().Length()) + 1 + 1; //1 extra to accommodate start point plus 1 to accomodate remainder in division
    87 	iOutBuffer = HBufC8::NewL(KLiteralEnglish5().Length() * repeats);
    88 	iOutBufferPtr.Set(iOutBuffer->Des());
    89 	iOutBufferPtr.Zero();
    90 	for(TInt i=0;i<repeats;i++)
    91 		{
    92 		iOutBufferPtr.Append(KLiteralEnglish5());
    93 		}
    94 
    95 	RDebug::Printf("CUT_PBASE_T_USBDI_1229::ConstructL(): buffer created");
    96 	}
    97 
    98 
    99 CUT_PBASE_T_USBDI_1229::~CUT_PBASE_T_USBDI_1229()
   100 	{
   101 	LOG_FUNC
   102 	}
   103 	
   104 void CUT_PBASE_T_USBDI_1229::KillTransfers()
   105 	{
   106 	LOG_FUNC
   107 	
   108 	iOutTransfer[0]->Cancel();
   109 	iOutTransfer[1]->Cancel();
   110 	}
   111 
   112 void CUT_PBASE_T_USBDI_1229::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 read on its bulk out 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_1229::PostTransferAction()
   141 	{
   142 	switch(iTransferResult)
   143 		{
   144 		case KErrNone:
   145 			//do nothing
   146 			return;
   147 
   148 		case KTransferSuccess:
   149 			//indicates data validation failure
   150 			{
   151 			RDebug::Printf("Asking client to post validation recorded on the endpoint on its interface - ready for collection");
   152 			iCaseStep = ERequestPrepareEndpointValidationResult;
   153 			TRecordedValidationResultRequest request(1,1);
   154 			iControlEp0->SendRequest(request,this);
   155 			}
   156 			return;
   157 		
   158 		default:
   159 			{
   160 			iCaseStep = EFailed;
   161 			RDebug::Print(iMsg);
   162 			TTestCaseFailed request(iTransferResult,iMsg);
   163 			iControlEp0->SendRequest(request,this);
   164 			}
   165 			return;
   166 		}
   167 	}
   168 
   169 
   170 TBool CUT_PBASE_T_USBDI_1229::PerformNextTransfer(TInt aTransferId)
   171 	{
   172 	LOG_FUNC
   173 	
   174 	if(iNumWriteBytesRequested >= KTotalBytesToTransfer)
   175 		{
   176 		RDebug::Printf("All transfers sent - num bytes actually written = %d, num bytes required to be written = %d", iNumWriteBytesRequested, KTotalBytesToTransfer);
   177 		return EFalse; //Not writing any more - signal to user that no more transfers are required
   178 		}
   179 	TUint bytesToWrite = KTotalBytesToTransfer - iNumWriteBytesRequested;
   180 	TUint numWriteBytes = bytesToWrite < KHostNumWriteBytes ? bytesToWrite : KHostNumWriteBytes;
   181 
   182 	_LITDBG("PerformNextTransfer: None existant transfer ID requested");
   183 	__ASSERT_DEBUG(aTransferId==KBulkTransferOutId[0] || aTransferId==KBulkTransferOutId[1], User::Panic(lit, KErrArgument));
   184 	CBulkTransfer& bulkTransfer = aTransferId==KBulkTransferOutId[0]?*iOutTransfer[0]:*iOutTransfer[1];
   185 	bulkTransfer.TransferOut(iOutBufferPtr.Mid(iNumWriteBytesRequested%(KLiteralEnglish5().Length()), numWriteBytes), EFalse);
   186 	iNumWriteBytesRequested += numWriteBytes;
   187 
   188 	return ETrue;
   189 	}
   190 
   191 	
   192 void CUT_PBASE_T_USBDI_1229::RequestNumBytesSent(TUint8 aTimerIndex)
   193 	{
   194 	iInBufferPtr.Set(iInBuffer->Des());
   195 	iInBufferPtr.Zero(); //reset
   196 	iInBufferPtr.SetLength(KNumberStringLength);
   197 	TInterfaceGetRecordedNumBytesReadInPayload request(1,1,iInBufferPtr);
   198 	iControlEp0->SendRequest(request,this);
   199 	iControlEp0->LastRequestStartTime( iStartTime[aTimerIndex]);
   200 	}
   201 
   202 
   203 void CUT_PBASE_T_USBDI_1229::Ep0TransferCompleteL(TInt aCompletionCode)
   204 	{
   205 	LOG_FUNC
   206 	
   207 	RDebug::Printf("Ep0TransferCompleteL with aCompletionCode = %d, test step = %d", aCompletionCode, iCaseStep);
   208 	
   209 	if(aCompletionCode != KErrNone)
   210 		{
   211 		if(iCaseStep == EFailed)
   212 			{// ignore error, nad catch the TestFailed method called further down.
   213 			RDebug::Printf("***Failure sending FAIL message to client on endpoint 0***");
   214 			}
   215 		else
   216 			{
   217 			TBuf<256> msg;
   218 			KillTransfers();
   219 			_LIT(lit, "<Error %d> Transfer to control endpoint 0 was not successful");
   220 			msg.Format(lit,aCompletionCode);
   221 			RDebug::Print(msg);
   222 			iCaseStep = EFailed;
   223 			TTestCaseFailed request(aCompletionCode,msg);
   224 			iControlEp0->SendRequest(request,this);
   225 			return;
   226 			}
   227 		}
   228 	
   229 	switch(iCaseStep)
   230 		{
   231 		// Test case passed
   232 		case EPassed:
   233 			TestPassed();
   234 			break;
   235 		
   236 		// Test case failed	
   237 		case EFailed:
   238 			TestFailed(KErrCompletion);
   239 			break;
   240 		
   241 		case EGetTimerBase:
   242 			{
   243 			iControlEp0->LastRequestCompletionTime( iEndTime[KBaseTimer]);
   244 			RDebug::Printf("Asking client for continuous 'Read' and 'Validate'");
   245 			iCaseStep = ERequestRepeatedReadAndValidate;
   246 			TRepeatedReadAndValidateDataRequest request(1,1,KLiteralEnglish5(),KDeviceNumReadBytes,KTotalBytesToTransfer);// EP2 means endpoint index 2 not the actual endpoint number, here the ep with 32 byte max packet size
   247 			iControlEp0->SendRequest(request,this);
   248 			}
   249 			break;
   250 			
   251 		case ERequestRepeatedReadAndValidate:
   252 			{
   253 			RDebug::Printf("Try to perform ALL transfers");
   254 	
   255 			iCaseStep = ETransfer;	
   256 			
   257 			PerformNextTransfer(KBulkTransferOutId[0]);
   258 			PerformNextTransfer(KBulkTransferOutId[1]);
   259 			_LITDBG("Bulk test timer NOT instanciated");
   260 			__ASSERT_DEBUG(iBulkTestTimer, User::Panic(lit, KErrGeneral));
   261 			iBulkTestTimer->After(KRepeatedTimerInterval);
   262 			}
   263 			break;
   264 			
   265 		case ETransfer:
   266 		// we must be getting num bytes read
   267 			ExtractDeviceReadBytes();
   268 	
   269 			//Restart timer
   270 			_LITDBG("Bulk test timer NOT instanciated");
   271 			__ASSERT_DEBUG(iBulkTestTimer, User::Panic(lit, KErrGeneral));
   272 			iBulkTestTimer->After(KRepeatedTimerInterval);
   273 			break;
   274 			
   275 		case EDelayedTransferComplete:
   276 			PostTransferAction();
   277 			break;
   278 			
   279 		case ERequestPrepareEndpointValidationResult:
   280 			{
   281 			RDebug::Printf("Asking client to prepare the result of its continuous validation");
   282 			iCaseStep = ERequestValidationResult;
   283 			iInBufferPtr.Set(iInBuffer->Des());
   284 			iInBufferPtr.Zero(); //reset
   285 			iInBufferPtr.SetLength(KPassFailStringLength);
   286 			TInterfaceGetPayloadRequest request(1,iInBufferPtr);
   287 			iControlEp0->SendRequest(request,this);
   288 			}
   289 			break;
   290 	
   291 		case ERequestValidationResult:
   292 			RDebug::Printf("Collect client's return validation  result in a pass or fail string ...");
   293 			RDebug::RawPrint(*iInBuffer);
   294 			RDebug::Printf("\n");
   295 			iInBufferPtr.Set(iInBuffer->Des());
   296 			if(iInBufferPtr.Compare(KClientPassString) == 0)
   297 				{
   298 				RDebug::Printf("Client Validation Result is a PASS");
   299 				RDebug::Printf("This is the FINAL check - the whole test has a PASSED");
   300 				iCaseStep = EPassed;
   301 				TTestCasePassed request;
   302 				iControlEp0->SendRequest(request,this);
   303 				}
   304 			else
   305 				{
   306 				TBuf<256> msg;
   307 				_LIT(lit, "<Error> Bulk data VALIDATION check was NOT successful");
   308 				msg.Format(lit);
   309 				RDebug::Print(msg);
   310 				iCaseStep = EFailed;
   311 				TTestCaseFailed request(KErrCorrupt,msg);
   312 				iControlEp0->SendRequest(request,this);
   313 				}
   314 			break;
   315 	
   316 		default:
   317 			RDebug::Printf("<Error> Unknown test step");
   318 			TestFailed(KErrUnknown);
   319 			break;
   320 		}
   321 	}
   322 	
   323 void CUT_PBASE_T_USBDI_1229::TransferCompleteL(TInt aTransferId,TInt aCompletionCode)
   324 	{
   325 	LOG_FUNC
   326 	Cancel();
   327 	
   328 	iTransferResult = KErrNone;
   329 	RDebug::Printf("Transfer completed (id=%d), aCompletionCode = %d, test step = %d",aTransferId, aCompletionCode, iCaseStep);
   330 
   331 
   332 	switch(iCaseStep)
   333 		{
   334 		case ETransfer:
   335 			if(aCompletionCode != KErrNone)
   336 				{
   337 				KillTransfers();
   338 				iTransferResult = KErrCorrupt;
   339 				_LIT(lit, "<Error %d> The transfer completed with an error.");
   340 				iMsg.Format(lit, aCompletionCode);
   341 				break;
   342 				}
   343 			if(aTransferId != KBulkTransferOutId[0] && aTransferId != KBulkTransferOutId[1])
   344 				{
   345 				iTransferComplete = 0; //reset
   346 				iTransferResult = KUnexpectedTransferID;
   347 				_LIT(lit, "<Error %d> Unexpected transfer ID, wanted %d or %d, got %d");
   348 				iMsg.Format(lit, iTransferResult, KBulkTransferOutId[0], KBulkTransferOutId[1], aTransferId);
   349 				break;
   350 				}
   351 			RDebug::Printf("Transfer OUT %d completed - num bytes sent = %d", aTransferId, iNumWriteBytesRequested);
   352 			
   353 			if(PerformNextTransfer(aTransferId)==EFalse)
   354 				{
   355 				iTransferComplete |= aTransferId;
   356 				RDebug::Printf("All transfer OUT %ds completed (Transfer Completion Aggregation Mask 0x%x)", aTransferId, iTransferComplete);
   357 				}
   358 			
   359 			if(iTransferResult==KErrNone && (iTransferComplete & KBulkTransferIdMask) == KBulkTransferIdMask)
   360 				{
   361 				/*
   362 				Transfers all complete - now ask device to validate first interface's transfer OUT
   363 				*/
   364 				RDebug::Printf("All Transfers Completed Successfully: Transfer Completion Aggregation Mask 0x%x", iTransferComplete);
   365 				if(iTransferResult==KErrNone)
   366 					{
   367 					iBulkTestTimer->Cancel(); //Cancel Timer 
   368 					iTransferResult = KTransferSuccess;
   369 					if(iTimingError == KErrTooBig)
   370 						{
   371 						__PRINT_CONTROL_TRANSFER_TIMER_COMPARISON_WARNING
   372 						iTransferResult = KErrTooBig;
   373 						iTimingError = KErrNone; //reset
   374 						}
   375 					if(KMaxBytesReadDiffPercentage*iDeviceMaxTimedNumBytesRead > KPercent*iDeviceMinTimedNumBytesRead)
   376 						{
   377 						RDebug::Printf("Device APPARENTLY reading rate erratic:-");
   378 						RDebug::Printf("Min Timed Number of Bytes = %d", iDeviceMinTimedNumBytesRead);
   379 						RDebug::Printf("Max Timed Number of Bytes = %d", iDeviceMaxTimedNumBytesRead);
   380 						iTransferResult = KErrTooBig;
   381 						iDeviceMaxTimedNumBytesRead = 0;
   382 						iDeviceMinTimedNumBytesRead = KMaxTUint;
   383 						}
   384 					}
   385 				}
   386 			break;
   387 
   388 		default:
   389 			iTransferResult = KUndefinedStep;
   390 			_LIT(lit, "<Error %d> Undefined case step %d reached");
   391 			iMsg.Format(lit,KUndefinedStep, iCaseStep);
   392 			break;
   393 		}
   394 
   395 
   396 	if(iTransferResult == KErrReturnedDeviceReadBytesTooVariable)
   397 		//indicates apparent device read rate validation failure
   398 		{
   399 		iMsg.Format(_L("<Error %d> Device APPEARS not to be reading bytes at a constant rate"), iTransferResult);
   400 		}
   401 
   402 	if(iTransferResult == KErrTooBig)
   403 		//indicates timing validation failure
   404 		{
   405 		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);
   406 		}
   407 	
   408 	if(iTransferResult == KErrCompletion)
   409 		//indicates data validation failure
   410 		{
   411 		_LIT(lit, "<Error %d> Client has posted an error discovered in validation");
   412 		iMsg.Format(lit, iTransferResult);
   413 		}
   414 
   415 	if(iTransferResult != KErrNone)
   416 		{	
   417 		KillTransfers(); //harmless if tranfers are all done
   418 		if(!iControlEp0->IsActive())
   419 			{
   420 			PostTransferAction();
   421 			}
   422 		else
   423 			{
   424 			iCaseStep = EDelayedTransferComplete; //so that we move forward when the EP0 transfer has completed
   425 			}
   426 		}
   427 	}
   428 	
   429 void CUT_PBASE_T_USBDI_1229::DeviceInsertedL(TUint aDeviceHandle)
   430 	{
   431 	LOG_FUNC
   432 	
   433 	Cancel();
   434 	RDebug::Printf("this - %08x", this);
   435 	
   436 	TBuf<256> msg;
   437 	TInt err = KErrNone;
   438 	if(BaseBulkDeviceInsertedL(aDeviceHandle, EFalse) == EDeviceConfigurationError)
   439 		// Prepare for response from control transfer to client
   440 		{
   441 		err = KErrGeneral;
   442 		_LIT(lit, "Base class DeviceInsertedL failed");
   443 		msg.Format(lit);
   444 		}
   445 	else
   446 		{
   447 		if(SetUpInterfaceAndPipesL(aDeviceHandle, 2) == EDeviceConfigurationError)
   448 			// Prepare for response from control transfer to client
   449 			{
   450 			err = KErrGeneral;
   451 			_LIT(lit, "Base class SetUpInterfaceAndPipes for Interface 2 failed");
   452 			msg.Format(lit);
   453 			}
   454 		else
   455 			{
   456 	
   457 			iOutTransfer[0] = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkOut,iUsbInterface1,KBulkMaxTransferSize,*this,KBulkTransferOutId[0]);
   458 			iOutTransfer[1] = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkOut,iUsbInterface1,KBulkMaxTransferSize,*this,KBulkTransferOutId[1]);
   459 			
   460 			// Initialise the descriptors for transfer		
   461 			RDebug::Printf("Initialising the transfer descriptors - interface 1");
   462 			err = iUsbInterface1.InitialiseTransferDescriptors();
   463 			if(err != KErrNone)
   464 				{
   465 				_LIT(lit, "<Error %d> Unable to initialise transfer descriptors");
   466 				msg.Format(lit,err);
   467 				}
   468 			}
   469 		}
   470 	if(err != KErrNone)
   471 		{
   472 		RDebug::Print(msg);
   473 		iCaseStep = EFailed;
   474 		TTestCaseFailed request(err,msg);
   475 		iControlEp0->SendRequest(request,this);
   476 		}
   477 	else
   478 		{
   479 		iCaseStep = EGetTimerBase;
   480 		iDeviceMinTimedNumBytesRead = KMaxTUint;
   481 		iDeviceMaxTimedNumBytesRead = 0;
   482 		iDeviceNumBytesReadInTotal = 0;
   483 		RequestNumBytesSent(KBaseTimer);
   484 		}
   485 	}
   486 
   487 void CUT_PBASE_T_USBDI_1229::HandleBulkTestTimerFired()
   488 	{
   489 	if(iCaseStep == ETransfer)
   490 		{
   491 		RequestNumBytesSent(KTestTimer);
   492 		}
   493 	}
   494 	
   495 	} //end namespace