sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // @file PBASE-T_USBDI-1234.cpp sl@0: // @internalComponent sl@0: // sl@0: // sl@0: sl@0: #include "PBASE-T_USBDI-1234.h" sl@0: #include "modelleddevices.h" sl@0: #include "testpolicy.h" sl@0: #include "testliterals.h" sl@0: sl@0: namespace NUnitTesting_USBDI sl@0: { sl@0: const TInt KBulkTransferSize = 583; sl@0: const TUint KHostNumWriteBytes1 = 210; sl@0: const TUint KHostNumWriteBytes2 = 350; sl@0: const TUint KHostNumWriteBytes3 = KBulkTransferSize - KHostNumWriteBytes1 sl@0: - KHostNumWriteBytes2; // 23 sl@0: const TUint KHostNumReadBytes1 = 301; sl@0: const TUint KHostNumReadBytes2 = 21; sl@0: const TUint KHostNumReadBytes3 = KBulkTransferSize - KHostNumReadBytes1 sl@0: - KHostNumReadBytes2; // 261 sl@0: sl@0: sl@0: //Make these single bit values ... sl@0: // ... so that their completion can be easily recorded in a bit mask! sl@0: const TInt KBulkTransferInId0 = 1<<0; sl@0: const TInt KBulkTransferInId1 = 1<<1; sl@0: const TInt KBulkTransferInId2 = 1<<2; sl@0: const TInt KBulkTransferOutId0 = 1<<3; sl@0: const TInt KBulkTransferOutId1 = 1<<4; sl@0: const TInt KBulkTransferOutId2 = 1<<5; sl@0: sl@0: const TInt KUnexpectedTransferID = -101; sl@0: const TInt KUndefinedStep = -102; sl@0: sl@0: _LIT(KTestCaseId,"PBASE-T_USBDI-1234"); sl@0: // the name is very important sl@0: const TFunctorTestCase sl@0: CUT_PBASE_T_USBDI_1234::iFunctor(KTestCaseId); sl@0: sl@0: CUT_PBASE_T_USBDI_1234* CUT_PBASE_T_USBDI_1234::NewL(TBool aHostRole) sl@0: { sl@0: CUT_PBASE_T_USBDI_1234* self = new (ELeave) CUT_PBASE_T_USBDI_1234(aHostRole); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CUT_PBASE_T_USBDI_1234::CUT_PBASE_T_USBDI_1234(TBool aHostRole) : sl@0: CBaseBulkTestCase(KTestCaseId, aHostRole), iCaseStep(EInProgress) sl@0: { sl@0: sl@0: } sl@0: sl@0: void CUT_PBASE_T_USBDI_1234::ExecuteHostTestCaseL() sl@0: { sl@0: CBaseBulkTestCase::ExecuteHostTestCaseL(); sl@0: iInterface0Watcher = new (ELeave) CInterfaceWatcher(iUsbInterface0,TCallBack(CUT_PBASE_T_USBDI_1234::Interface0ResumedL,this)); sl@0: iInterface1Watcher = new (ELeave) CInterfaceWatcher(iUsbInterface1,TCallBack(CUT_PBASE_T_USBDI_1234::Interface1ResumedL,this)); sl@0: iInterface2Watcher = new (ELeave) CInterfaceWatcher(iUsbInterface1,TCallBack(CUT_PBASE_T_USBDI_1234::Interface2ResumedL,this)); sl@0: } sl@0: sl@0: void CUT_PBASE_T_USBDI_1234::ConstructL() sl@0: { sl@0: BaseBulkConstructL(); sl@0: } sl@0: sl@0: CUT_PBASE_T_USBDI_1234::~CUT_PBASE_T_USBDI_1234() sl@0: { sl@0: LOG_FUNC sl@0: // Cancel any async operations sl@0: sl@0: Cancel(); // Cancel host timer sl@0: sl@0: if (iInterface1Watcher) sl@0: { sl@0: delete iInterface1Watcher; sl@0: } sl@0: if (iInterface0Watcher) sl@0: { sl@0: delete iInterface0Watcher; sl@0: } sl@0: if (iInterface2Watcher) sl@0: { sl@0: delete iInterface2Watcher; sl@0: } sl@0: sl@0: } sl@0: sl@0: void CUT_PBASE_T_USBDI_1234::DeviceInsertedL(TUint aDeviceHandle) sl@0: { sl@0: LOG_FUNC sl@0: sl@0: Cancel(); sl@0: sl@0: if (BaseBulkDeviceInsertedL(aDeviceHandle) == EDeviceConfigurationError) sl@0: // Prepare for response from control transfer to client sl@0: { sl@0: iCaseStep = EFailed; sl@0: } sl@0: sl@0: // Create the bulk transfers sl@0: iInTransfer[0] sl@0: = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkIn,iUsbInterface1,KBulkTransferSize,*this,KBulkTransferInId0); sl@0: iInTransfer[1] sl@0: = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkIn,iUsbInterface1,KBulkTransferSize,*this,KBulkTransferInId1); sl@0: iInTransfer[2] sl@0: = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkIn,iUsbInterface1,KBulkTransferSize,*this,KBulkTransferInId2); sl@0: iOutTransfer[0] sl@0: = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkOut,iUsbInterface1,KBulkTransferSize,*this,KBulkTransferOutId0); sl@0: iOutTransfer[1] sl@0: = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkOut,iUsbInterface1,KBulkTransferSize,*this,KBulkTransferOutId1); sl@0: iOutTransfer[2] sl@0: = new (ELeave) CBulkTransfer(iTestPipeInterface1BulkOut,iUsbInterface1,KBulkTransferSize,*this,KBulkTransferOutId2); sl@0: sl@0: // Initialise the descriptors for transfer sl@0: RDebug::Printf("Initialising the transfer descriptors"); sl@0: TInt err = iUsbInterface1.InitialiseTransferDescriptors(); sl@0: if (err != KErrNone) sl@0: { sl@0: TBuf<256> msg; sl@0: msg.Format(_L(" Unable to initialise transfer descriptors"),err); sl@0: RDebug::Print(msg); sl@0: iCaseStep = EFailed; sl@0: TTestCaseFailed request(err, msg); sl@0: iControlEp0->SendRequest(request, this); sl@0: return; sl@0: } sl@0: sl@0: iCaseStep = ESuspendDevice; sl@0: sl@0: TrySuspendDeviceByInterfaces(); sl@0: sl@0: } sl@0: sl@0: TInt CUT_PBASE_T_USBDI_1234::Interface0ResumedL(TAny* aPtr) sl@0: { sl@0: sl@0: // when device is really resumed , the whole of interfaces' previous call PermitSuspendAndWaitForResume()'s requests of the device will be completed , random chose one . sl@0: LOG_CFUNC sl@0: RDebug::Printf("Interface 0 resumed"); sl@0: CUT_PBASE_T_USBDI_1234* self = sl@0: reinterpret_cast(aPtr); sl@0: TInt completionCode = self->iInterface0Watcher->CompletionCode(); sl@0: RDebug::Printf("watcher 0 errCode=%d",completionCode); sl@0: self->iSuspendedI0 = EFalse; sl@0: sl@0: switch (self->iCaseStep) sl@0: { sl@0: sl@0: case EValidateResumebyInterface: sl@0: { sl@0: if (completionCode == KErrNone) sl@0: { sl@0: RDebug::Printf("device resumed succeed, do bulk transfer!"); sl@0: self->iCaseStep = EBulkTransferOutWhenResume; sl@0: self->SendEpTransferRequest(); sl@0: } sl@0: else sl@0: { sl@0: RDebug::Printf("device resumed failed, ",completionCode); sl@0: self->iCaseStep = EFailed; sl@0: self->SendEpRequest(); sl@0: } sl@0: } sl@0: sl@0: break; sl@0: sl@0: default: sl@0: break; sl@0: }; sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CUT_PBASE_T_USBDI_1234::Interface1ResumedL(TAny* aPtr) sl@0: { sl@0: LOG_CFUNC sl@0: RDebug::Printf("Interface 1 resumed"); sl@0: CUT_PBASE_T_USBDI_1234* self = sl@0: reinterpret_cast(aPtr); sl@0: RDebug::Printf("watcher 1 iStatus=%d", sl@0: self->iInterface1Watcher->CompletionCode()); sl@0: self->iSuspendedI1 = EFalse; sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt CUT_PBASE_T_USBDI_1234::Interface2ResumedL(TAny* aPtr) sl@0: { sl@0: LOG_CFUNC sl@0: RDebug::Printf("Interface 2 resumed"); sl@0: CUT_PBASE_T_USBDI_1234* self = sl@0: reinterpret_cast(aPtr); sl@0: RDebug::Printf("watcher 2 iStatus=%d", sl@0: self->iInterface2Watcher->CompletionCode()); sl@0: self->iSuspendedI2 = EFalse; sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CUT_PBASE_T_USBDI_1234::DeviceStateChangeL( sl@0: RUsbDevice::TDeviceState aPreviousState, sl@0: RUsbDevice::TDeviceState aNewState, TInt aCompletionCode) sl@0: { sl@0: LOG_FUNC sl@0: Cancel(); sl@0: sl@0: RDebug::Printf( sl@0: "Device State change from %d to %d err=%d", sl@0: aPreviousState, aNewState, aCompletionCode); sl@0: } sl@0: sl@0: void CUT_PBASE_T_USBDI_1234::Ep0TransferCompleteL(TInt aCompletionCode) sl@0: { sl@0: LOG_FUNC sl@0: sl@0: RDebug::Printf( sl@0: "Ep0TransferCompleteL with aCompletionCode = %d", sl@0: aCompletionCode); sl@0: sl@0: if (aCompletionCode != KErrNone) sl@0: { sl@0: if (iCaseStep == EFailed) sl@0: {// ignore error, and catch the TestFailed method called further down. sl@0: RDebug::Printf("***Failure sending FAIL message to client on endpoint 0***"); sl@0: } sl@0: else sl@0: { sl@0: TBuf<256> msg; sl@0: msg.Format(_L(" Transfer to control endpoint 0 was not successful"),aCompletionCode); sl@0: RDebug::Print(msg); sl@0: iCaseStep = EFailed; sl@0: TTestCaseFailed request(aCompletionCode, msg); sl@0: iControlEp0->SendRequest(request, this); sl@0: return; sl@0: } sl@0: } sl@0: sl@0: switch (iCaseStep) sl@0: { sl@0: // Test case passed sl@0: case EPassed: sl@0: TestPassed(); sl@0: break; sl@0: sl@0: // Test case failed sl@0: case EFailed: sl@0: TestFailed(KErrCompletion); sl@0: break; sl@0: sl@0: case EBulkTransferOutWhenResume: sl@0: RDebug::Printf("Try to send data"); sl@0: iOutTransfer[0]->TransferOut(KLiteralEnglish8().Mid(0, KHostNumWriteBytes1), EFalse); sl@0: iOutTransfer[1]->TransferOut(KLiteralEnglish8().Mid(KHostNumWriteBytes1, KHostNumWriteBytes2), EFalse); sl@0: iOutTransfer[2]->TransferOut(KLiteralEnglish8().Mid(KHostNumWriteBytes1+KHostNumWriteBytes2, sl@0: KHostNumWriteBytes3), ETrue); //do not suppress ZLP on this last one (though should be irrelevant here) sl@0: break; sl@0: sl@0: case EValidBulkTransfeOut: sl@0: RDebug::Printf("Try to receive data"); sl@0: iInTransfer[0]->TransferIn(KHostNumReadBytes1); sl@0: iInTransfer[1]->TransferIn(KHostNumReadBytes2); sl@0: iInTransfer[2]->TransferIn(KHostNumReadBytes3); sl@0: break; sl@0: sl@0: default: sl@0: RDebug::Printf(" Unknown test step"); sl@0: TestFailed(KErrUnknown); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: void CUT_PBASE_T_USBDI_1234::TransferCompleteL(TInt aTransferId, sl@0: TInt aCompletionCode) sl@0: { sl@0: LOG_FUNC sl@0: Cancel(); sl@0: sl@0: TInt err(KErrNone); sl@0: TBuf<256> msg; sl@0: RDebug::Printf("Transfer completed (id=%d), aCompletionCode = %d", sl@0: aTransferId, aCompletionCode); sl@0: sl@0: switch (iCaseStep) sl@0: { sl@0: case EBulkTransferOutWhenResume: sl@0: if (aCompletionCode != KErrNone) sl@0: { sl@0: err = KErrCorrupt; sl@0: msg.Format(_L(" No data sent on bulk OUT request"),aCompletionCode); sl@0: break; // switch(iCaseStep) sl@0: } sl@0: sl@0: switch (aTransferId) sl@0: { sl@0: case KBulkTransferOutId0: sl@0: case KBulkTransferOutId1: sl@0: case KBulkTransferOutId2: sl@0: iTransferComplete |= aTransferId; sl@0: RDebug::Printf("Transfer %d completed", aTransferId); sl@0: break; // switch(aTransferId) sl@0: sl@0: default: sl@0: iTransferComplete = 0; //reset sl@0: err = KUnexpectedTransferID; sl@0: msg.Format(_L(" Unexpected transfer ID, wanted %d, %d or %d, got %d"), sl@0: err, KBulkTransferOutId0, KBulkTransferOutId1, KBulkTransferOutId2, aTransferId); sl@0: break; // switch(aTransferId) sl@0: } sl@0: sl@0: if (err == KErrNone && iTransferComplete sl@0: == (KBulkTransferOutId0 | KBulkTransferOutId1 sl@0: | KBulkTransferOutId2)) sl@0: { sl@0: RDebug::Printf( sl@0: "Try to receive back sent data. Transfers Completed %d", sl@0: iTransferComplete); sl@0: iCaseStep = EValidBulkTransfeOut; sl@0: TUint numBytes[KNumSplitWriteSections] = sl@0: { sl@0: KHostNumReadBytes1, KHostNumReadBytes2, sl@0: KHostNumReadBytes3 sl@0: }; sl@0: TSplitWriteCachedReadDataRequest request(1, 1, 1, numBytes); sl@0: iControlEp0->SendRequest(request, this); sl@0: iTransferComplete = 0; //reset sl@0: } sl@0: break; // switch(iCaseStep) sl@0: sl@0: case EValidBulkTransfeOut: //transfer in sl@0: if (aCompletionCode != KErrNone) sl@0: { sl@0: err = KErrCorrupt; sl@0: msg.Format(_L(" No data sent on bulk IN request"),aCompletionCode); sl@0: break; // switch(iCaseStep) sl@0: } sl@0: sl@0: switch (aTransferId) sl@0: { sl@0: case KBulkTransferInId0: sl@0: case KBulkTransferInId1: sl@0: case KBulkTransferInId2: sl@0: iTransferComplete |= aTransferId; sl@0: break; // switch(aTransferId) sl@0: sl@0: default: sl@0: iTransferComplete = 0; //reset sl@0: err = KUnexpectedTransferID; sl@0: msg.Format(_L(" Unexpected transfer ID, wanted %d, %d or %d, got %d"), sl@0: err, KBulkTransferInId0, KBulkTransferInId1, KBulkTransferInId2, aTransferId); sl@0: break; // switch(aTransferId) sl@0: } sl@0: sl@0: if (err==KErrNone && iTransferComplete == (KBulkTransferInId0 sl@0: | KBulkTransferInId1 | KBulkTransferInId2)) sl@0: { sl@0: // compare data rcvd now sl@0: TPtrC8 data1(iInTransfer[0]->DataPolled()); sl@0: TPtrC8 data2(iInTransfer[1]->DataPolled()); sl@0: TPtrC8 data3(iInTransfer[2]->DataPolled()); sl@0: if (ValidateData(data1, KLiteralEnglish8().Mid(0, KHostNumReadBytes1)) == EFalse) sl@0: { sl@0: err = KErrCompletion; //indicates data validation failure sl@0: break; // switch(iCaseStep) sl@0: } sl@0: sl@0: if (ValidateData(data2, KLiteralEnglish8().Mid(KHostNumReadBytes1, KHostNumReadBytes2)) sl@0: == EFalse) sl@0: { sl@0: err = KErrCompletion; //indicates data validation failure sl@0: break; // switch(iCaseStep) sl@0: } sl@0: sl@0: if (ValidateData(data3, KLiteralEnglish8().Mid(KHostNumReadBytes1+KHostNumReadBytes2, sl@0: KHostNumReadBytes3)) == EFalse) sl@0: { sl@0: err = KErrCompletion; //indicates data validation failure sl@0: break; // switch(iCaseStep) sl@0: } sl@0: sl@0: // Comparison is a match sl@0: RDebug::Printf("Comparison for IN transfer is a match"); sl@0: iCaseStep = EPassed; sl@0: TTestCasePassed request; sl@0: iControlEp0->SendRequest(request, this); sl@0: iTransferComplete = 0; //reset sl@0: } sl@0: break; // switch(iCaseStep) sl@0: sl@0: default: sl@0: err = KUndefinedStep; sl@0: msg.Format(_L(" Undefined case step %d reached"),KUndefinedStep, iCaseStep); sl@0: break; // switch(iCaseStep) sl@0: } sl@0: sl@0: if (err == KErrCompletion) sl@0: { sl@0: //indicates data validation failure sl@0: msg.Format(_L(" Bulk transfer IN data received does not match Bulk Transfer OUT data"), err); sl@0: } sl@0: sl@0: if (err!=KErrNone) sl@0: { sl@0: RDebug::Print(msg); sl@0: iCaseStep = EFailed; sl@0: TTestCaseFailed request(err, msg); sl@0: iControlEp0->SendRequest(request, this); sl@0: } sl@0: sl@0: } sl@0: sl@0: void CUT_PBASE_T_USBDI_1234::TrySuspendDeviceByInterfaces() sl@0: { sl@0: // Suspend interface 0 sl@0: RDebug::Printf("Suspending interface 0"); sl@0: iInterface0Watcher->SuspendAndWatch(); sl@0: iSuspendedI0 = ETrue; sl@0: sl@0: // Suspend interface 1 sl@0: RDebug::Printf("Suspending interface 1"); sl@0: iInterface1Watcher->SuspendAndWatch(); sl@0: iSuspendedI1 = ETrue; sl@0: sl@0: // Suspend interface 2 sl@0: RDebug::Printf("Suspending interface 2"); sl@0: iInterface2Watcher->SuspendAndWatch(); sl@0: iSuspendedI2 = ETrue; sl@0: sl@0: TimeoutIn(10); // Give 10 seconds for device to suspend sl@0: sl@0: // scenario2 : device could do the bulk transfer must wait device really resumed. sl@0: iUsbInterface0.CancelPermitSuspend(); sl@0: sl@0: iCaseStep = EValidateResumebyInterface; sl@0: sl@0: } sl@0: sl@0: void CUT_PBASE_T_USBDI_1234::SendEpRequest() sl@0: { sl@0: TTestCasePassed request; sl@0: iControlEp0->SendRequest(request, this); sl@0: } sl@0: void CUT_PBASE_T_USBDI_1234::SendEpTransferRequest() sl@0: { sl@0: TEndpointReadRequest request(1, 1, KBulkTransferSize);// EP1 means endpoint index 1 not the actual endpoint number sl@0: iControlEp0->SendRequest(request, this); sl@0: } sl@0: sl@0: }//end namespace sl@0: sl@0: