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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // @file PBASE-T_USBDI-1229.cpp
19 #include "PBASE-T_USBDI-1229.h"
20 #include "testpolicy.h"
21 #include "modelleddevices.h"
22 #include "testliterals.h"
27 namespace NUnitTesting_USBDI
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;
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];
40 const TInt KUndefinedStep = -102;
41 const TInt KUnexpectedTransferID = -103;
42 const TInt KErrReturnedDeviceReadBytesTooVariable = -140;
43 const TInt KTransferSuccess = +100;
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;
54 _LIT(KTestCaseId,"PBASE-T_USBDI-1229");
55 const TFunctorTestCase<CUT_PBASE_T_USBDI_1229,TBool> CUT_PBASE_T_USBDI_1229::iFunctor(KTestCaseId);
57 CUT_PBASE_T_USBDI_1229* CUT_PBASE_T_USBDI_1229::NewL(TBool aHostRole)
59 CUT_PBASE_T_USBDI_1229* self = new (ELeave) CUT_PBASE_T_USBDI_1229(aHostRole);
60 CleanupStack::PushL(self);
62 CleanupStack::Pop(self);
67 CUT_PBASE_T_USBDI_1229::CUT_PBASE_T_USBDI_1229(TBool aHostRole)
68 : CBaseBulkTestCase(KTestCaseId,aHostRole),
69 iCaseStep(EInProgress)
74 void CUT_PBASE_T_USBDI_1229::ConstructL()
78 iInBuffer = HBufC8::NewL(KTestBufferLength);
80 iBulkTestTimer = CBulkTestTimer::NewL(*this);
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());
90 for(TInt i=0;i<repeats;i++)
92 iOutBufferPtr.Append(KLiteralEnglish5());
95 RDebug::Printf("CUT_PBASE_T_USBDI_1229::ConstructL(): buffer created");
99 CUT_PBASE_T_USBDI_1229::~CUT_PBASE_T_USBDI_1229()
104 void CUT_PBASE_T_USBDI_1229::KillTransfers()
108 iOutTransfer[0]->Cancel();
109 iOutTransfer[1]->Cancel();
112 void CUT_PBASE_T_USBDI_1229::ExtractDeviceReadBytes()
116 iControlEp0->LastRequestCompletionTime( iEndTime[KTestTimer]);
117 iTimingError = iTimingError == KErrNone ? CheckTimes(KBaseTimer, KTestTimer, KMaxTimeDiffPercentage) : iTimingError;
118 ResetTimes(KTestTimer);
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");
130 //Do not count this case - it may result from the remote resetting when all bulk transfers have completed
132 TUint numBytesSinceLast = numBytes - iDeviceNumBytesReadInTotal;
133 iDeviceNumBytesReadInTotal = numBytes;
134 iDeviceMinTimedNumBytesRead = numBytesSinceLast < iDeviceMinTimedNumBytesRead ? numBytesSinceLast : iDeviceMinTimedNumBytesRead ;
135 iDeviceMaxTimedNumBytesRead = numBytesSinceLast > iDeviceMaxTimedNumBytesRead ? numBytesSinceLast : iDeviceMaxTimedNumBytesRead ;;
140 void CUT_PBASE_T_USBDI_1229::PostTransferAction()
142 switch(iTransferResult)
148 case KTransferSuccess:
149 //indicates data validation failure
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);
162 TTestCaseFailed request(iTransferResult,iMsg);
163 iControlEp0->SendRequest(request,this);
170 TBool CUT_PBASE_T_USBDI_1229::PerformNextTransfer(TInt aTransferId)
174 if(iNumWriteBytesRequested >= KTotalBytesToTransfer)
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
179 TUint bytesToWrite = KTotalBytesToTransfer - iNumWriteBytesRequested;
180 TUint numWriteBytes = bytesToWrite < KHostNumWriteBytes ? bytesToWrite : KHostNumWriteBytes;
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;
192 void CUT_PBASE_T_USBDI_1229::RequestNumBytesSent(TUint8 aTimerIndex)
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]);
203 void CUT_PBASE_T_USBDI_1229::Ep0TransferCompleteL(TInt aCompletionCode)
207 RDebug::Printf("Ep0TransferCompleteL with aCompletionCode = %d, test step = %d", aCompletionCode, iCaseStep);
209 if(aCompletionCode != KErrNone)
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***");
219 _LIT(lit, "<Error %d> Transfer to control endpoint 0 was not successful");
220 msg.Format(lit,aCompletionCode);
223 TTestCaseFailed request(aCompletionCode,msg);
224 iControlEp0->SendRequest(request,this);
238 TestFailed(KErrCompletion);
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);
251 case ERequestRepeatedReadAndValidate:
253 RDebug::Printf("Try to perform ALL transfers");
255 iCaseStep = ETransfer;
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);
266 // we must be getting num bytes read
267 ExtractDeviceReadBytes();
270 _LITDBG("Bulk test timer NOT instanciated");
271 __ASSERT_DEBUG(iBulkTestTimer, User::Panic(lit, KErrGeneral));
272 iBulkTestTimer->After(KRepeatedTimerInterval);
275 case EDelayedTransferComplete:
276 PostTransferAction();
279 case ERequestPrepareEndpointValidationResult:
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);
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)
298 RDebug::Printf("Client Validation Result is a PASS");
299 RDebug::Printf("This is the FINAL check - the whole test has a PASSED");
301 TTestCasePassed request;
302 iControlEp0->SendRequest(request,this);
307 _LIT(lit, "<Error> Bulk data VALIDATION check was NOT successful");
311 TTestCaseFailed request(KErrCorrupt,msg);
312 iControlEp0->SendRequest(request,this);
317 RDebug::Printf("<Error> Unknown test step");
318 TestFailed(KErrUnknown);
323 void CUT_PBASE_T_USBDI_1229::TransferCompleteL(TInt aTransferId,TInt aCompletionCode)
328 iTransferResult = KErrNone;
329 RDebug::Printf("Transfer completed (id=%d), aCompletionCode = %d, test step = %d",aTransferId, aCompletionCode, iCaseStep);
335 if(aCompletionCode != KErrNone)
338 iTransferResult = KErrCorrupt;
339 _LIT(lit, "<Error %d> The transfer completed with an error.");
340 iMsg.Format(lit, aCompletionCode);
343 if(aTransferId != KBulkTransferOutId[0] && aTransferId != KBulkTransferOutId[1])
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);
351 RDebug::Printf("Transfer OUT %d completed - num bytes sent = %d", aTransferId, iNumWriteBytesRequested);
353 if(PerformNextTransfer(aTransferId)==EFalse)
355 iTransferComplete |= aTransferId;
356 RDebug::Printf("All transfer OUT %ds completed (Transfer Completion Aggregation Mask 0x%x)", aTransferId, iTransferComplete);
359 if(iTransferResult==KErrNone && (iTransferComplete & KBulkTransferIdMask) == KBulkTransferIdMask)
362 Transfers all complete - now ask device to validate first interface's transfer OUT
364 RDebug::Printf("All Transfers Completed Successfully: Transfer Completion Aggregation Mask 0x%x", iTransferComplete);
365 if(iTransferResult==KErrNone)
367 iBulkTestTimer->Cancel(); //Cancel Timer
368 iTransferResult = KTransferSuccess;
369 if(iTimingError == KErrTooBig)
371 __PRINT_CONTROL_TRANSFER_TIMER_COMPARISON_WARNING
372 iTransferResult = KErrTooBig;
373 iTimingError = KErrNone; //reset
375 if(KMaxBytesReadDiffPercentage*iDeviceMaxTimedNumBytesRead > KPercent*iDeviceMinTimedNumBytesRead)
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;
389 iTransferResult = KUndefinedStep;
390 _LIT(lit, "<Error %d> Undefined case step %d reached");
391 iMsg.Format(lit,KUndefinedStep, iCaseStep);
396 if(iTransferResult == KErrReturnedDeviceReadBytesTooVariable)
397 //indicates apparent device read rate validation failure
399 iMsg.Format(_L("<Error %d> Device APPEARS not to be reading bytes at a constant rate"), iTransferResult);
402 if(iTransferResult == KErrTooBig)
403 //indicates timing validation failure
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);
408 if(iTransferResult == KErrCompletion)
409 //indicates data validation failure
411 _LIT(lit, "<Error %d> Client has posted an error discovered in validation");
412 iMsg.Format(lit, iTransferResult);
415 if(iTransferResult != KErrNone)
417 KillTransfers(); //harmless if tranfers are all done
418 if(!iControlEp0->IsActive())
420 PostTransferAction();
424 iCaseStep = EDelayedTransferComplete; //so that we move forward when the EP0 transfer has completed
429 void CUT_PBASE_T_USBDI_1229::DeviceInsertedL(TUint aDeviceHandle)
434 RDebug::Printf("this - %08x", this);
438 if(BaseBulkDeviceInsertedL(aDeviceHandle, EFalse) == EDeviceConfigurationError)
439 // Prepare for response from control transfer to client
442 _LIT(lit, "Base class DeviceInsertedL failed");
447 if(SetUpInterfaceAndPipesL(aDeviceHandle, 2) == EDeviceConfigurationError)
448 // Prepare for response from control transfer to client
451 _LIT(lit, "Base class SetUpInterfaceAndPipes for Interface 2 failed");
457 iOutTransfer[0] = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkOut,iUsbInterface1,KBulkMaxTransferSize,*this,KBulkTransferOutId[0]);
458 iOutTransfer[1] = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkOut,iUsbInterface1,KBulkMaxTransferSize,*this,KBulkTransferOutId[1]);
460 // Initialise the descriptors for transfer
461 RDebug::Printf("Initialising the transfer descriptors - interface 1");
462 err = iUsbInterface1.InitialiseTransferDescriptors();
465 _LIT(lit, "<Error %d> Unable to initialise transfer descriptors");
474 TTestCaseFailed request(err,msg);
475 iControlEp0->SendRequest(request,this);
479 iCaseStep = EGetTimerBase;
480 iDeviceMinTimedNumBytesRead = KMaxTUint;
481 iDeviceMaxTimedNumBytesRead = 0;
482 iDeviceNumBytesReadInTotal = 0;
483 RequestNumBytesSent(KBaseTimer);
487 void CUT_PBASE_T_USBDI_1229::HandleBulkTestTimerFired()
489 if(iCaseStep == ETransfer)
491 RequestNumBytesSent(KTestTimer);