sl@0: // Copyright (c) 2000-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: // e32test/usb/t_usb_device/src/activerw.cpp sl@0: // USB Test Program T_USB_DEVICE, functional part. sl@0: // Device-side part, to work against T_USB_HOST running on the host. sl@0: // sl@0: // sl@0: sl@0: #include "general.h" // CActiveControl, CActiveRW sl@0: #include "config.h" sl@0: #include "activerw.h" sl@0: #include "activetimer.h" sl@0: #include "usblib.h" // Helpers sl@0: sl@0: _LIT(KFileName, "\\T_USBFILE.BIN"); sl@0: sl@0: extern RTest test; sl@0: extern TBool gVerbose; sl@0: extern TBool gSkip; sl@0: extern TBool gStopOnFail; sl@0: extern TBool gAltSettingOnNotify; sl@0: extern TInt8 gSettingNumber [128]; sl@0: extern TInt gSoakCount; sl@0: extern CActiveRW* gRW[KMaxConcurrentTests]; // the USB read/write active object sl@0: extern IFConfigPtr gInterfaceConfig [128] [KMaxInterfaceSettings]; sl@0: extern TInt gActiveTestCount; sl@0: sl@0: static TInt gYieldRepeat = 0; sl@0: static const TInt KYieldRepeat = 100; sl@0: sl@0: // sl@0: // --- class CActiveRW --------------------------------------------------------- sl@0: // sl@0: sl@0: CActiveRW::CActiveRW(CConsoleBase* aConsole, RDEVCLIENT* aPort, RFs aFs, TUint16 aIndex, TBool aLastSetting) sl@0: : CActive(EPriorityNormal), sl@0: #ifndef USB_SC sl@0: iWriteBuf((TUint8 *)NULL,0,0), // temporary initialisation sl@0: iReadBuf((TUint8 *)NULL,0,0), // temporary initialisation sl@0: #endif sl@0: iConsole(aConsole), sl@0: iPort(aPort), sl@0: iBufSz(0), sl@0: iMaxPktSz(0), sl@0: iCurrentXfer(ETxferNone), sl@0: iXferMode(::ENone), sl@0: iDoStop(EFalse), sl@0: iPktNum(0), sl@0: iFs(aFs), sl@0: iRepeat(0), sl@0: iComplete(EFalse), sl@0: iResult(EFalse), sl@0: iIndex (aIndex), sl@0: iLastSetting (aLastSetting) sl@0: { sl@0: gActiveTestCount++; sl@0: TUSB_VERBOSE_PRINT("CActiveRW::CActiveRW()"); sl@0: } sl@0: sl@0: sl@0: CActiveRW* CActiveRW::NewL(CConsoleBase* aConsole, RDEVCLIENT* aPort, RFs aFs, TUint16 aIndex, TBool aLastSetting) sl@0: { sl@0: TUSB_VERBOSE_APRINT("CActiveRW::NewL()"); sl@0: sl@0: CActiveRW* self = new (ELeave) CActiveRW(aConsole, aPort, aFs, aIndex, aLastSetting); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CActiveScheduler::Add(self); sl@0: CleanupStack::Pop(); // self sl@0: return self; sl@0: } sl@0: sl@0: sl@0: void CActiveRW::ConstructL() sl@0: { sl@0: TUSB_VERBOSE_PRINT("CActiveRW::ConstructL()"); sl@0: sl@0: // Create read timeout timer active object (but don't activate it yet) sl@0: iTimeoutTimer = CActiveTimer::NewL(iConsole, iPort); sl@0: if (!iTimeoutTimer) sl@0: { sl@0: TUSB_PRINT("Failed to create timeout timer"); sl@0: } sl@0: } sl@0: sl@0: sl@0: CActiveRW::~CActiveRW() sl@0: { sl@0: TUSB_VERBOSE_PRINT("CActiveRW::~CActiveRW()"); sl@0: Cancel(); // base class sl@0: delete iTimeoutTimer; sl@0: #ifdef USB_SC sl@0: if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: iSCReadBuf.Close(); sl@0: } sl@0: if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: iSCWriteBuf.Close(); sl@0: } sl@0: #else sl@0: User::Free((TAny *)iReadBuf.Ptr()); sl@0: User::Free((TAny *)iWriteBuf.Ptr()); sl@0: #endif sl@0: iFile.Close(); sl@0: gRW[iIndex] = NULL; sl@0: gActiveTestCount--; sl@0: } sl@0: sl@0: sl@0: void CActiveRW::SetTestParams(TestParamPtr aTpPtr) sl@0: { sl@0: iBufSz = aTpPtr->minSize; sl@0: iPktNum = aTpPtr->packetNumber; sl@0: sl@0: iTestParams = *aTpPtr; sl@0: sl@0: gYieldRepeat = ((iTestParams.settingRepeat != 0) || (iIndex == 0))? 0 : KYieldRepeat; sl@0: sl@0: if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: #ifndef USB_SC sl@0: TAny * newBuffer = User::Alloc(aTpPtr->maxSize); sl@0: if (newBuffer == NULL) sl@0: { sl@0: TUSB_PRINT ("Failure to allocate heap memory"); sl@0: test(EFalse); sl@0: } sl@0: iReadBuf.Set((TUint8 *)newBuffer,0,(TInt)aTpPtr->maxSize); sl@0: #endif sl@0: TBuf8 descriptor; sl@0: TUSB_VERBOSE_PRINT2 ("GetEndpointDescriptor Alt Setting %d Endpoint %d",iTestParams.alternateSetting, iTestParams.outPipe); sl@0: TInt r = iPort->GetEndpointDescriptor(iTestParams.alternateSetting, (TENDPOINTNUMBER)iTestParams.outPipe, descriptor); sl@0: if ((TUint)r != iReadSize) sl@0: { sl@0: TUSB_PRINT("Failed to get endpoint descriptor"); sl@0: test(EFalse); sl@0: return; sl@0: } sl@0: sl@0: iMaxPktSz = EpSize(descriptor[KEpDesc_PacketSizeOffset],descriptor[KEpDesc_PacketSizeOffset+1]); sl@0: TUSB_VERBOSE_PRINT5 ("Out Endpoint 0x%x attributes 0x%x interface %d setting %d max packet size %d", sl@0: descriptor[KEpDesc_AddressOffset],descriptor[KEpDesc_AttributesOffset],iTestParams.interfaceNumber,iTestParams.alternateSetting,iMaxPktSz); sl@0: if (!gSkip && iMaxPktSz != (TUint)gInterfaceConfig[iTestParams.interfaceNumber][iTestParams.alternateSetting]->iInfoPtr->iEndpointData[iTestParams.outPipe-1].iSize) sl@0: { sl@0: TUSB_PRINT4("Error - Interface %d Setting %d Endpoint %d Max Packet Size %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe,iMaxPktSz); sl@0: test(EFalse); sl@0: return; sl@0: } sl@0: } sl@0: if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: #ifndef USB_SC sl@0: TAny * newBuffer = User::Alloc(aTpPtr->maxSize); sl@0: if (newBuffer == NULL) sl@0: { sl@0: TUSB_PRINT ("Failure to allocate heap memory"); sl@0: test(EFalse); sl@0: } sl@0: iWriteBuf.Set((TUint8 *)newBuffer,0,(TInt)aTpPtr->maxSize); sl@0: #endif sl@0: TBuf8 descriptor; sl@0: TUSB_VERBOSE_PRINT2 ("GetEndpointDescriptor Alt Setting %d Endpoint %d",iTestParams.alternateSetting, iTestParams.inPipe); sl@0: TInt r = iPort->GetEndpointDescriptor(iTestParams.alternateSetting, (TENDPOINTNUMBER)iTestParams.inPipe, descriptor); sl@0: if (r != KErrNone) sl@0: { sl@0: TUSB_PRINT("Failed to get endpoint descriptor"); sl@0: test(EFalse); sl@0: return; sl@0: } sl@0: sl@0: TInt maxPktSz = EpSize(descriptor[KEpDesc_PacketSizeOffset],descriptor[KEpDesc_PacketSizeOffset+1]); sl@0: TUSB_VERBOSE_PRINT5 ("In Endpoint 0x%x attributes 0x%x interface %d setting %d max packet size %d", sl@0: descriptor[KEpDesc_AddressOffset],descriptor[KEpDesc_AttributesOffset],iTestParams.interfaceNumber,iTestParams.alternateSetting,maxPktSz); sl@0: if (!gSkip && maxPktSz != gInterfaceConfig[iTestParams.interfaceNumber][iTestParams.alternateSetting]->iInfoPtr->iEndpointData[iTestParams.inPipe-1].iSize) sl@0: { sl@0: TUSB_PRINT4("Error - Interface %d Setting %d Endpoint %d Max Packet Size %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.inPipe,maxPktSz); sl@0: test(EFalse); sl@0: return; sl@0: } sl@0: } sl@0: sl@0: } sl@0: sl@0: sl@0: void CActiveRW::SetTransferMode(TXferMode aMode) sl@0: { sl@0: iXferMode = aMode; sl@0: if (aMode == EReceiveOnly || aMode == ETransmitOnly) sl@0: { sl@0: // For streaming transfers we do this only once. sl@0: iBufSz = iTestParams.maxSize; sl@0: } sl@0: } sl@0: sl@0: void CActiveRW::Suspend(TXferType aType) sl@0: { sl@0: if (aType == ESuspend) sl@0: TUSB_VERBOSE_PRINT1("Index %d Suspend",iIndex); sl@0: if (aType == EAltSetting) sl@0: TUSB_VERBOSE_PRINT3("Index %d Suspend for Alternate Setting - interface %d setting %d",iIndex,iTestParams.interfaceNumber,iTestParams.alternateSetting); sl@0: iStatus = KRequestPending; sl@0: iCurrentXfer = aType; sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: } sl@0: sl@0: void CActiveRW::Resume() sl@0: { sl@0: TUSB_VERBOSE_PRINT3("Index %d Resume interface %d setting %d",iIndex,iTestParams.interfaceNumber,iTestParams.alternateSetting); sl@0: TRequestStatus* status = &iStatus; sl@0: User::RequestComplete(status,KErrNone); sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: } sl@0: sl@0: void CActiveRW::Yield() sl@0: { sl@0: TUSB_VERBOSE_PRINT1("Index %d Scheduler Yield",iIndex); sl@0: // removes the active object from the scheduler queue then adds it back in again sl@0: Deque(); sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: void CActiveRW::ResumeAltSetting(TUint aAltSetting) sl@0: { sl@0: if (iCurrentXfer == EAltSetting && iTestParams.alternateSetting == aAltSetting) sl@0: { sl@0: Resume(); sl@0: } sl@0: } sl@0: sl@0: void CActiveRW::StartOrSuspend() sl@0: { sl@0: TInt altSetting; sl@0: sl@0: iPort->GetAlternateSetting (altSetting); sl@0: if (iTestParams.alternateSetting != altSetting) sl@0: { sl@0: Suspend(EAltSetting); sl@0: } sl@0: else sl@0: { sl@0: #ifdef USB_SC sl@0: TInt r; sl@0: if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber]) sl@0: { sl@0: gSettingNumber[iTestParams.interfaceNumber] = iTestParams.alternateSetting; sl@0: r = iPort->StartNextOutAlternateSetting(ETrue); sl@0: TUSB_VERBOSE_PRINT1("StartNextOutAlternateSetting retValue %d",r); sl@0: test_Value(r, (r >= KErrNone) || (r == KErrNotReady) || (r == KErrGeneral)); sl@0: } sl@0: TUSB_VERBOSE_PRINT4 ("CActiveRW::StartOrSuspend() interface %d setting %d Out %d In %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe,iTestParams.inPipe); sl@0: if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: r = iPort->OpenEndpoint(iSCReadBuf,iTestParams.outPipe); sl@0: test_KErrNone(r); sl@0: } sl@0: if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: r = iPort->OpenEndpoint(iSCWriteBuf,iTestParams.inPipe); sl@0: test_KErrNone(r); sl@0: } sl@0: #endif sl@0: if (iXferMode == EReceiveOnly) sl@0: { sl@0: // read data and process any available sl@0: iReadSize = ReadData(); sl@0: if (iReadSize != 0) sl@0: { sl@0: ProcessReadXfer(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: SendData(); // or we send data sl@0: if (iXferMode == ETransmitOnly) sl@0: { sl@0: iPktNum++; sl@0: iRepeat++; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CActiveRW::RunL() sl@0: { sl@0: #ifdef USB_SC sl@0: TInt r = 0; sl@0: #else sl@0: TInt altSetting; sl@0: #endif sl@0: sl@0: TUSB_VERBOSE_PRINT("CActiveRW::RunL()"); sl@0: sl@0: if ((iStatus != KErrNone) && (iStatus != KErrEof)) sl@0: { sl@0: TUSB_PRINT1("Error %d in RunL", iStatus.Int()); sl@0: } sl@0: if (iDoStop) sl@0: { sl@0: TUSB_PRINT("Stopped"); sl@0: iDoStop = EFalse; sl@0: return; sl@0: } sl@0: switch (iCurrentXfer) sl@0: { sl@0: case EWaitSetting: sl@0: #ifdef USB_SC sl@0: if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: r = iSCReadBuf.Close(); sl@0: test_KErrNone(r); sl@0: } sl@0: if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: r = iSCWriteBuf.Close(); sl@0: test_KErrNone(r); sl@0: } sl@0: #endif sl@0: if (iTestParams.settingRepeat && ((iRepeat < iTestParams.repeat) || !iLastSetting)) sl@0: { sl@0: gRW[iTestParams.afterIndex]->Resume(); sl@0: } sl@0: Suspend(ESuspend); sl@0: break; sl@0: sl@0: case ESuspend: sl@0: #ifdef USB_SC sl@0: TUSB_VERBOSE_PRINT3("Index %d Resumed interface %d setting test=%d",iIndex,iTestParams.interfaceNumber,iTestParams.alternateSetting); sl@0: if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber]) sl@0: { sl@0: r = iPort->StartNextOutAlternateSetting(ETrue); sl@0: TUSB_VERBOSE_PRINT1("StartNextOutAlternateSetting retValue %d",r); sl@0: test_Value(r, (r >= KErrNone) || (r == KErrNotReady) || (r == KErrGeneral)); sl@0: if (r != KErrNotReady) sl@0: { sl@0: gSettingNumber[iTestParams.interfaceNumber] = r; sl@0: } sl@0: if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber]) sl@0: { sl@0: Suspend(EAltSetting); sl@0: break; sl@0: } sl@0: } sl@0: #else sl@0: iPort->GetAlternateSetting (altSetting); sl@0: TUSB_VERBOSE_PRINT4("Index %d Resumed interface %d setting test=%d actual=%d",iIndex,iTestParams.interfaceNumber,iTestParams.alternateSetting,altSetting); sl@0: if (gAltSettingOnNotify) sl@0: { sl@0: if (iTestParams.alternateSetting != altSetting) sl@0: { sl@0: Suspend(EAltSetting); sl@0: break; sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: // If alternate setting is ok drops through to EAltSetting to start next read or write sl@0: iCurrentXfer = EAltSetting; sl@0: sl@0: case EAltSetting: sl@0: #ifdef USB_SC sl@0: if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber]) sl@0: { sl@0: r = iPort->StartNextOutAlternateSetting(ETrue); sl@0: TUSB_VERBOSE_PRINT1("StartNextOutAlternateSetting retValue %d",r); sl@0: test_Value(r, (r >= KErrNone) || (r == KErrNotReady) || (r == KErrGeneral)); sl@0: if (r != KErrNotReady) sl@0: { sl@0: gSettingNumber[iTestParams.interfaceNumber] = r; sl@0: } sl@0: if (iTestParams.alternateSetting != gSettingNumber[iTestParams.interfaceNumber]) sl@0: { sl@0: Suspend(EAltSetting); sl@0: break; sl@0: } sl@0: } sl@0: TUSB_VERBOSE_PRINT4 ("CActiveRW::Runl() EAltSetting interface %d setting %d Out %d In %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe,iTestParams.inPipe); sl@0: if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: r = iPort->OpenEndpoint(iSCReadBuf,iTestParams.outPipe); sl@0: test_KErrNone(r); sl@0: } sl@0: if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: r = iPort->OpenEndpoint(iSCWriteBuf,iTestParams.inPipe); sl@0: test_KErrNone(r); sl@0: } sl@0: #endif sl@0: if (iXferMode == EReceiveOnly) sl@0: { sl@0: // read data and process any available sl@0: iReadSize = ReadData(); sl@0: if (iReadSize != 0) sl@0: { sl@0: ProcessReadXfer(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: SendData(); // or we send data sl@0: if (iXferMode == ETransmitOnly) sl@0: { sl@0: iPktNum++; sl@0: iRepeat++; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case EWriteXfer: sl@0: ProcessWriteXfer(); sl@0: break; sl@0: sl@0: case EReadXfer: sl@0: #ifdef USB_SC sl@0: iReadSize = ReadData(); sl@0: if (iReadSize != 0) sl@0: { sl@0: ProcessReadXfer(); sl@0: } sl@0: #else sl@0: iReadSize = iReadBuf.Length(); sl@0: ProcessReadXfer(); sl@0: #endif sl@0: break; sl@0: sl@0: default: sl@0: TUSB_PRINT("Oops. (Shouldn't end up here...)"); sl@0: break; sl@0: } sl@0: return; sl@0: } sl@0: sl@0: void CActiveRW::ProcessWriteXfer() sl@0: { sl@0: if (iXferMode == ETransmitOnly) sl@0: { sl@0: if (iTestParams.settingRepeat && iRepeat) sl@0: { sl@0: if (((iRepeat % iTestParams.settingRepeat) == 0) || (iRepeat >= iTestParams.repeat)) sl@0: { sl@0: if ((iRepeat < iTestParams.repeat) || !iLastSetting) sl@0: { sl@0: #ifdef USB_SC sl@0: if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: test_KErrNone(iSCWriteBuf.Close()); sl@0: } sl@0: #endif sl@0: gRW[iTestParams.afterIndex]->Resume(); sl@0: } sl@0: if (iRepeat < iTestParams.repeat) sl@0: { sl@0: Suspend(ESuspend); sl@0: return; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if ((iTestParams.repeat == 0) || (iRepeat < iTestParams.repeat)) sl@0: { sl@0: // Yield the scheduler to ensure other activeObjects can run sl@0: if (iRepeat && gYieldRepeat) sl@0: { sl@0: if ((iRepeat % gYieldRepeat) == 0) sl@0: { sl@0: Yield(); sl@0: } sl@0: } sl@0: SendData(); // next we send data sl@0: iPktNum++; sl@0: iRepeat++; sl@0: } sl@0: else sl@0: { sl@0: TestComplete(ETrue); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // read data and process any available sl@0: iReadSize = ReadData(); sl@0: if (iReadSize != 0) sl@0: { sl@0: ProcessReadXfer(); sl@0: } sl@0: } sl@0: sl@0: return; sl@0: } sl@0: sl@0: void CActiveRW::ProcessReadXfer() sl@0: { sl@0: if ((iReadOffset + iReadSize) > iBufSz) sl@0: { sl@0: TUSB_PRINT2("*** rcv'd too much data: 0x%x (expected: 0x%x)", iReadOffset + iReadSize, iBufSz); sl@0: test(EFalse); sl@0: } sl@0: sl@0: if (iXferMode == EReceiveOnly) sl@0: { sl@0: if (iReadOffset == 0) sl@0: { sl@0: #ifdef USB_SC sl@0: const TUint32 num = *reinterpret_cast(iSCReadData); sl@0: #else sl@0: const TUint32 num = *reinterpret_cast(iReadBuf.Ptr()); sl@0: #endif sl@0: if (num != iPktNum) sl@0: { sl@0: TUSB_PRINT3("*** Repeat %d rcv'd wrong pkt number: 0x%x (expected: 0x%x)", iRepeat, num, iPktNum); sl@0: iPktNum = num; sl@0: test(EFalse); sl@0: } sl@0: } sl@0: if (iDiskAccessEnabled) sl@0: { sl@0: // Write out to disk previous completed Read sl@0: #ifdef USB_SC sl@0: TPtr8 readBuf((TUint8 *)iSCReadData,iReadSize,iReadSize); sl@0: WriteBufferToDisk(readBuf, iReadSize); sl@0: #else sl@0: TUSB_VERBOSE_PRINT2("Max Buffer Size = %d (iReadBuf.Size(): %d)", iTestParams.maxSize, iReadBuf.Size()); sl@0: WriteBufferToDisk(iReadBuf, iTestParams.maxSize); sl@0: #endif sl@0: } sl@0: iReadOffset += iReadSize; sl@0: if (iReadOffset >= iBufSz) sl@0: { sl@0: iReadOffset = 0; sl@0: } sl@0: else sl@0: { sl@0: #ifdef USB_SC sl@0: iReadSize = ReadData(); sl@0: if (iReadSize) sl@0: { sl@0: ProcessReadXfer(); sl@0: } sl@0: #endif sl@0: return; sl@0: } sl@0: iPktNum++; sl@0: iRepeat++; sl@0: iReadSize = 0; sl@0: if (iTestParams.settingRepeat) sl@0: { sl@0: if (((iRepeat % iTestParams.settingRepeat) == 0) || (iRepeat >= iTestParams.repeat)) sl@0: { sl@0: #ifdef USB_SC sl@0: if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: test_KErrNone(iSCReadBuf.Close()); sl@0: } sl@0: #endif sl@0: if ((iRepeat < iTestParams.repeat) || !iLastSetting) sl@0: { sl@0: gRW[iTestParams.afterIndex]->Resume(); sl@0: } sl@0: if (iRepeat < iTestParams.repeat) sl@0: { sl@0: Suspend(ESuspend); sl@0: return; sl@0: } sl@0: } sl@0: } sl@0: if ((iTestParams.repeat == 0) || (iRepeat < iTestParams.repeat)) sl@0: { sl@0: // Yield the scheduler to ensure other activeObjects can run sl@0: if (iRepeat && gYieldRepeat) sl@0: { sl@0: if ((iRepeat % gYieldRepeat) == 0) sl@0: { sl@0: Yield(); sl@0: } sl@0: } sl@0: #ifdef USB_SC sl@0: TRequestStatus* status = &iStatus; sl@0: User::RequestComplete(status,KErrNone); sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: #else sl@0: iReadSize = ReadData(); sl@0: #endif sl@0: } sl@0: else sl@0: { sl@0: TestComplete(ETrue); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (iXferMode == ELoopComp) sl@0: { sl@0: test(CompareBuffers()); sl@0: } sl@0: else if (iBufSz > 3) sl@0: { sl@0: if (iReadOffset == 0) sl@0: { sl@0: #ifdef USB_SC sl@0: const TUint32 num = *reinterpret_cast(iSCReadData); sl@0: #else sl@0: const TUint32 num = *reinterpret_cast(iReadBuf.Ptr()); sl@0: #endif sl@0: if (num != iPktNum) sl@0: { sl@0: TUSB_PRINT2("*** rcv'd wrong pkt number: 0x%x (expected: 0x%x)", num, iPktNum); sl@0: } sl@0: } sl@0: } sl@0: iReadOffset += iReadSize; sl@0: if (iReadOffset >= iBufSz) sl@0: { sl@0: iReadOffset = 0; sl@0: } sl@0: else sl@0: { sl@0: iReadSize = ReadData(); sl@0: if (iReadSize) sl@0: { sl@0: ProcessReadXfer(); sl@0: } sl@0: return; sl@0: } sl@0: if ((TUint)iBufSz == iTestParams.maxSize) sl@0: { sl@0: iBufSz = iTestParams.minSize; sl@0: } sl@0: else sl@0: { sl@0: iBufSz++; sl@0: } sl@0: iPktNum++; sl@0: iRepeat++; sl@0: iReadSize = 0; sl@0: if (iTestParams.settingRepeat) sl@0: { sl@0: if (((iRepeat % iTestParams.settingRepeat) == 0) || (iRepeat >= iTestParams.repeat)) sl@0: { sl@0: if (iRepeat < iTestParams.repeat) sl@0: { sl@0: SendWaitSetting(); sl@0: return; sl@0: } sl@0: else sl@0: { sl@0: #ifdef USB_SC sl@0: if ((TENDPOINTNUMBER)iTestParams.outPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: test_KErrNone(iSCReadBuf.Close()); sl@0: } sl@0: if ((TENDPOINTNUMBER)iTestParams.inPipe <= KMaxEndpointsPerClient) sl@0: { sl@0: test_KErrNone(iSCWriteBuf.Close()); sl@0: } sl@0: #endif sl@0: if (!iLastSetting) sl@0: { sl@0: gRW[iTestParams.afterIndex]->Resume(); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: if ((iTestParams.repeat == 0) || (iRepeat < iTestParams.repeat)) sl@0: { sl@0: // Yield the scheduler to ensure other activeObjects can run sl@0: if (iRepeat && gYieldRepeat) sl@0: { sl@0: if ((iRepeat % gYieldRepeat) == 0) sl@0: { sl@0: Yield(); sl@0: } sl@0: } sl@0: SendData(); sl@0: } sl@0: else sl@0: { sl@0: TestComplete(ETrue); sl@0: } sl@0: } sl@0: sl@0: return; sl@0: } sl@0: sl@0: void CActiveRW::SendWaitSetting() sl@0: { sl@0: __ASSERT_ALWAYS(!IsActive(), User::Panic(KActivePanic, 662)); sl@0: #ifdef USB_SC sl@0: TAny* inBuffer; sl@0: TUint inBufLength; sl@0: test_KErrNone(iSCWriteBuf.GetInBufferRange(inBuffer, inBufLength)); sl@0: test_KErrNone(iSCWriteBuf.WriteBuffer(inBuffer,KWaitSettingSize,FALSE,iStatus)); sl@0: #else sl@0: iWriteBuf.SetLength(KWaitSettingSize); sl@0: iPort->Write(iStatus, (TENDPOINTNUMBER)iTestParams.inPipe, iWriteBuf, KWaitSettingSize); sl@0: #endif sl@0: iCurrentXfer = EWaitSetting; sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: } sl@0: sl@0: sl@0: void CActiveRW::SendData() sl@0: { sl@0: __ASSERT_ALWAYS(!IsActive(), User::Panic(KActivePanic, 663)); sl@0: #ifdef USB_SC sl@0: TUint8* inBuffer; sl@0: TUint inBufLength; sl@0: test_KErrNone(iSCWriteBuf.GetInBufferRange((TAny*&)inBuffer, inBufLength)); sl@0: if (iDiskAccessEnabled) sl@0: { sl@0: TPtr8 writeBuf((TUint8 *)inBuffer,iBufSz,iBufSz); sl@0: ReadBufferFromDisk(writeBuf, iBufSz); sl@0: } sl@0: if (iBufSz > 3) sl@0: *reinterpret_cast(inBuffer) = iPktNum; sl@0: sl@0: if (iXferMode == ELoopComp) sl@0: { sl@0: for (TUint i = 4; i < iBufSz; i++) sl@0: { sl@0: *(inBuffer+i) = static_cast((iPktNum+i) & 0x000000ff); sl@0: } sl@0: } sl@0: TUSB_VERBOSE_PRINT3("SendData interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.inPipe); sl@0: iCurrentXfer = EWriteXfer; sl@0: TInt r = iSCWriteBuf.WriteBuffer(inBuffer, iBufSz, FALSE, iStatus); sl@0: test_KErrNone(r); sl@0: #else sl@0: if (iDiskAccessEnabled) sl@0: { sl@0: ReadBufferFromDisk(iWriteBuf, iBufSz); sl@0: } sl@0: iWriteBuf.SetLength(iBufSz); sl@0: if (iBufSz > 3) sl@0: *reinterpret_cast(const_cast(iWriteBuf.Ptr())) = iPktNum; sl@0: if (iXferMode == ELoopComp) sl@0: { sl@0: for (TUint i = 4; i < iBufSz; i++) sl@0: { sl@0: iWriteBuf[i] = static_cast((iPktNum+i) & 0x000000ff); sl@0: } sl@0: } sl@0: sl@0: TUSB_VERBOSE_PRINT3("SendData interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.inPipe); sl@0: iCurrentXfer = EWriteXfer; sl@0: iPort->Write(iStatus, (TENDPOINTNUMBER)iTestParams.inPipe, iWriteBuf, iBufSz); sl@0: #endif sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: } sl@0: sl@0: TInt CActiveRW::WriteToDisk(TChar aDriveLetter) sl@0: { sl@0: iDiskAccessEnabled = ETrue; sl@0: TInt r = KErrNone; sl@0: sl@0: iFileName.Format(_L("%c:"), aDriveLetter.operator TUint()); sl@0: iFileName.Append(KFileName); sl@0: TUSB_PRINT1("\nFilename = %S", &iFileName); sl@0: sl@0: // open the record file sl@0: r = iFile.Replace(iFs, iFileName, EFileWrite); sl@0: iFileOffset = 0; sl@0: if (r != KErrNone) sl@0: { sl@0: TUSB_PRINT1("RFile::Replace() returned %d", r); sl@0: iDiskAccessEnabled = EFalse; sl@0: return r; sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TInt CActiveRW::ReadFromDisk(TChar aDriveLetter, TInt aMaxFileSize) sl@0: { sl@0: iDiskAccessEnabled = ETrue; sl@0: TInt r = KErrNone; sl@0: sl@0: iFileName.Format(_L("%c:"), aDriveLetter.operator TUint()); sl@0: iFileName.Append(KFileName); sl@0: TUSB_PRINT1("\nFilename = %S", &iFileName); sl@0: TUSB_PRINT1("File size: %d", aMaxFileSize); sl@0: sl@0: // First create the file & fill it sl@0: r = iFile.Replace(iFs, iFileName, EFileWrite); sl@0: if (r != KErrNone) sl@0: { sl@0: TUSB_PRINT1("RFile::Replace() returned %d", r); sl@0: iDiskAccessEnabled = EFalse; sl@0: return r; sl@0: } sl@0: const TInt KBufferSize = 4 * 1024; sl@0: TBuf8 buffer; sl@0: buffer.SetLength(KBufferSize); sl@0: for (TInt n = 0; n < KBufferSize; n++) sl@0: { sl@0: buffer[n] = static_cast(n & 0x000000ff); sl@0: } sl@0: TUSB_PRINT("Writing data to file (this may take some minutes...)"); sl@0: for (TInt n = 0; n < aMaxFileSize; n += KBufferSize) sl@0: { sl@0: r = iFile.Write(buffer, KBufferSize); sl@0: if (r != KErrNone) sl@0: { sl@0: TUSB_PRINT1("RFile::Write() returned %d (disk full?)", r); sl@0: iFile.Close(); sl@0: iDiskAccessEnabled = EFalse; sl@0: return r; sl@0: } sl@0: } sl@0: TUSB_PRINT("Done."); sl@0: iFile.Close(); sl@0: // Now open the file for reading sl@0: r = iFile.Open(iFs, iFileName, EFileRead); sl@0: if (r != KErrNone) sl@0: { sl@0: TUSB_PRINT1("RFile::Open() returned %d", r); sl@0: iDiskAccessEnabled = EFalse; sl@0: return r; sl@0: } sl@0: iFileOffset = 0; sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: void CActiveRW::WriteBufferToDisk(TDes8& aBuffer, TInt aLen) sl@0: { sl@0: TUSB_VERBOSE_PRINT1("CActiveRW::WriteBufferToDisk(), len = %d", aLen); sl@0: TInt r = iFile.Write(aBuffer, aLen); sl@0: if (r != KErrNone) sl@0: { sl@0: TUSB_PRINT2("Error writing to %S (%d)", &iFileName, r); sl@0: iDiskAccessEnabled = EFalse; sl@0: return; sl@0: } sl@0: iFileOffset += aLen; sl@0: } sl@0: sl@0: sl@0: void CActiveRW::ReadBufferFromDisk(TDes8& aBuffer, TInt aLen) sl@0: { sl@0: const TInt r = iFile.Read(aBuffer, aLen); sl@0: if (r != KErrNone) sl@0: { sl@0: TUSB_PRINT2("Error reading from %S (%d)", &iFileName, r); sl@0: iDiskAccessEnabled = EFalse; sl@0: return; sl@0: } sl@0: TInt readLen = aBuffer.Length(); sl@0: TUSB_VERBOSE_PRINT1("CActiveRW::ReadBufferFromDisk(), len = %d\n", readLen); sl@0: if (readLen < aLen) sl@0: { sl@0: TUSB_PRINT3("Only %d bytes of %d read from file %S)", sl@0: readLen, aLen, &iFileName); sl@0: iDiskAccessEnabled = EFalse; sl@0: return; sl@0: } sl@0: iFileOffset += aLen; sl@0: } sl@0: sl@0: sl@0: TUint CActiveRW::ReadData() sl@0: { sl@0: __ASSERT_ALWAYS(!IsActive(), User::Panic(KActivePanic, 664)); sl@0: iCurrentXfer = EReadXfer; sl@0: #ifdef USB_SC sl@0: TUint readSize = 0; // note that this returns zero when asynchronous read is pending sl@0: TInt r = 0; sl@0: do sl@0: { sl@0: r = iSCReadBuf.GetBuffer (iSCReadData,readSize,iReadZlp,iStatus); sl@0: test_Value(r, (r == KErrNone) || (r == KErrCompletion) || (r == KErrEof)); sl@0: TUSB_VERBOSE_PRINT4("Get Buffer Return code %d Status %d DataPtr 0x%x Size %d", r, iStatus.Int(),iSCReadData,readSize); sl@0: } sl@0: while ((r == KErrCompletion && readSize == 0) || (r == KErrEof)); sl@0: if (r == KErrCompletion) sl@0: { sl@0: return readSize; sl@0: } sl@0: else sl@0: { sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: return 0; sl@0: } sl@0: #else sl@0: iReadBuf.SetLength (0); sl@0: if (iBufSz <= iMaxPktSz) sl@0: { sl@0: // Testing the packet version of Read() sl@0: TUSB_VERBOSE_PRINT3("ReadData (single packet) interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe); sl@0: iPort->ReadPacket(iStatus, (TENDPOINTNUMBER)iTestParams.outPipe, iReadBuf, iBufSz); sl@0: } sl@0: else if ((TUint)iBufSz == iTestParams.maxSize) sl@0: { sl@0: // Testing the two-parameter version sl@0: TUSB_VERBOSE_PRINT3("ReadData (w/o length) interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe); sl@0: iPort->Read(iStatus, (TENDPOINTNUMBER)iTestParams.outPipe, iReadBuf); sl@0: } sl@0: else sl@0: { sl@0: // otherwise, we use the universal default version sl@0: // Testing the three-parameter version sl@0: TUSB_VERBOSE_PRINT3("ReadData (normal) interface %d setting %d endpoint %d",iTestParams.interfaceNumber,iTestParams.alternateSetting,iTestParams.outPipe); sl@0: iPort->Read(iStatus, (TENDPOINTNUMBER)iTestParams.outPipe, iReadBuf, iBufSz); sl@0: } sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: return 0; sl@0: #endif sl@0: } sl@0: sl@0: sl@0: void CActiveRW::Stop() sl@0: { sl@0: if (!IsActive()) sl@0: { sl@0: TUSB_PRINT("CActiveRW::Stop(): Not active"); sl@0: return; sl@0: } sl@0: TUSB_PRINT("Cancelling outstanding transfer requests\n"); sl@0: iBufSz = 0; sl@0: iPktNum = 0; sl@0: iDoStop = ETrue; sl@0: iCurrentXfer = ETxferNone; sl@0: Cancel(); sl@0: } sl@0: sl@0: sl@0: void CActiveRW::DoCancel() sl@0: { sl@0: TUSB_VERBOSE_PRINT("CActiveRW::DoCancel()"); sl@0: // Canceling the transfer requests can be done explicitly sl@0: // for every transfer... sl@0: iPort->WriteCancel((TENDPOINTNUMBER)iTestParams.inPipe); sl@0: iPort->ReadCancel((TENDPOINTNUMBER)iTestParams.outPipe); sl@0: // or like this: sl@0: // iPort->EndpointTransferCancel(~0); sl@0: } sl@0: sl@0: sl@0: TBool CActiveRW::CompareBuffers() sl@0: { sl@0: TUSB_VERBOSE_PRINT2("CActiveRW::CompareBuffers() ReadOffset %d ReadSize %d",iReadOffset,iReadSize); sl@0: #ifdef USB_SC sl@0: TUint8 *readPtr = reinterpret_cast(iSCReadData); sl@0: TUint8* writePtr; sl@0: TUint inBufLength; sl@0: test_KErrNone(iSCWriteBuf.GetInBufferRange((TAny*&)writePtr, inBufLength)); sl@0: writePtr += iReadOffset; sl@0: #endif sl@0: for (TUint i = 0; i < iReadSize; i++) sl@0: { sl@0: #ifdef USB_SC sl@0: if (*readPtr != *writePtr) sl@0: { sl@0: TUSB_PRINT3 ("*** Error while comparing tx & rx buffers packet 0x%x length %d index %d",iPktNum, iReadSize,i + iReadOffset); sl@0: TUSB_PRINT2 ("*** Read byte 0x%x Write byte 0x%x",*readPtr,*writePtr); sl@0: return EFalse; sl@0: } sl@0: readPtr++; sl@0: writePtr++; sl@0: #else sl@0: if (iReadBuf[i] != iWriteBuf[i + iReadOffset]) sl@0: { sl@0: TUSB_PRINT3 ("*** Error while comparing tx & rx buffers packet 0x%x length %d index %d",iPktNum, iReadSize,i + iReadOffset); sl@0: TUSB_PRINT5 ("WriteBuf Start 0x%x 0x%x 0x%x 0x%x 0x%x", sl@0: iWriteBuf[i], iWriteBuf[i+1], iWriteBuf[i+2], iWriteBuf[i+3], iWriteBuf[i+4]); sl@0: TUSB_PRINT5 ("ReadBuf Start 0x%x 0x%x 0x%x 0x%x 0x%x", sl@0: iReadBuf[i], iReadBuf[i+1], iReadBuf[i+2], iReadBuf[i+3], iReadBuf[i+4]); sl@0: if (iReadSize >= 10) sl@0: { sl@0: TUSB_PRINT5 ("WriteBuf End 0x%x 0x%x 0x%x 0x%x 0x%x", sl@0: iWriteBuf[iReadSize-5], iWriteBuf[iReadSize-4], iWriteBuf[iReadSize-3], iWriteBuf[iReadSize-2], iWriteBuf[iReadSize-1]); sl@0: TUSB_PRINT5 ("ReadBuf End 0x%x 0x%x 0x%x 0x%x 0x%x", sl@0: iReadBuf[iReadSize-5], iReadBuf[iReadSize-4], iReadBuf[iReadSize-3], iReadBuf[iReadSize-2], iReadBuf[iReadSize-1]); sl@0: } sl@0: return EFalse; sl@0: } sl@0: #endif sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: void CActiveRW::TestComplete(TBool aResult) sl@0: { sl@0: TUSB_VERBOSE_PRINT("CActiveRW::TestComplete()"); sl@0: sl@0: iResult = aResult; sl@0: sl@0: if (iComplete || !iResult || iTestParams.repeat == 0) sl@0: { sl@0: test(iResult); sl@0: test.End(); sl@0: gRW[iIndex] = NULL; sl@0: delete this; sl@0: } sl@0: else sl@0: { sl@0: iComplete = ETrue; sl@0: } sl@0: } sl@0: sl@0: // -eof-