diff -r 000000000000 -r c9bc50fca66e usbmgmt/usbmgrtest/t_catc/src/t_catc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbmgmt/usbmgrtest/t_catc/src/t_catc.cpp Tue Feb 02 02:02:59 2010 +0200 @@ -0,0 +1,723 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* TODO: This is used for non-loopback (i.e. bulk IN and OUT) performance +* testing. It has been modified (see TODO: speed enhancement! marks) from the +* vanilla version in the team directory (Camfiler01\softeng\Departmental\Pan +* \Team\USB\Useful Stuff\t_catc\t_catc.cpp) to make it faster +* +*/ + +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// + +LOCAL_D CConsoleBase* console; + +RCommServ TheCommServ; +RUsb TheUsb; + +TCommConfig TheConfigBuf; +TCommConfigV01& TheConfig = TheConfigBuf(); + +const TInt KReceiveBufferLength = 65536/*16384*/; // TODO: speed enhancement! +//const TInt KMaxBufferSize = 8192; // TODO: speed enhancement! +const TUint KChunkSize = 65536; + +//////////////////////////////////////////////////////////////////////////////// + +//_LIT(KUsbCsyName, "ECACM"); +_LIT(KUsbPortName, "ACM::0"); +_LIT(KUsbLddName, "EUSBC"); + +//////////////////////////////////////////////////////////////////////////////// + +#define _printf console->Printf +#define _getch console->Getch + +//////////////////////////////////////////////////////////////////////////////// + +TInt bReadCall = ETrue ; +TInt bUseZLP = EFalse ; +TInt bUseTerm = EFalse ; + +//////////////////////////////////////////////////////////////////////////////// + +#define PARM(_c,_x) _c, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x) + +#define LEAVE(_x) VerboseLeaveL(PARM(_x,_x)) +#define LEAVEIFERROR(_x) VerboseLeaveIfErrorL(PARM(_x,_x)) + +#define CHECK(_x) if(! (_x) ) \ + { \ + VerboseLeaveL(PARM(KErrGeneral,_x)); \ + } + +void VerboseLeaveL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode) + { + TInt filenameOffset = aFileName.LocateReverse('\\') + 1; + if (filenameOffset < 0) filenameOffset = 1; + TPtrC8 shortFileName = aFileName.Mid(filenameOffset); + TBuf<64> fName, code; + fName.Copy(shortFileName.Left(64)); + code.Copy(aCode.Left(64)); + _printf(_L("ERROR (%d) on line %d of file %S\n"), aError, aLineNum, &fName); + _printf(_L("Code: %S\n\n"), &code); + _printf(_L("[ press any key ]")); + _getch(); + User::Leave(aError); + } + +void VerboseLeaveIfErrorL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode) + { + if (aError) + { + VerboseLeaveL(aError, aLineNum, aFileName, aCode); + } + } + +//////////////////////////////////////////////////////////////////////////////// + +void ReadString(TDes& aDes) +/** + * Reads user input into the start of the descriptor aDes. + */ + { + TChar inputKey; + TInt count = 0; + + aDes.Zero(); + for (;;) + { + inputKey = (TInt) _getch(); + + if ((TInt)inputKey == EKeyEnter) + { + break; + } + + if(inputKey == EKeyBackspace) + { + if (count > 0) + { + _printf(_L("%C"), (TUint) inputKey); + aDes.Delete(--count,1); + } + } + else if(inputKey.IsPrint()) + { + _printf(_L("%C"), (TUint) inputKey); + aDes.Append(inputKey); + count++; + } + } + } + +//////////////////////////////////////////////////////////////////////////////// + +void Bulk_OUT_TestL() + { + TRequestStatus consoleStatus; + TRequestStatus status; + RComm port; + +// static TBuf8<1024> OUT_Buf; // TODO: speed enhancement! + static TBuf8 OUT_Buf; + + _printf(_L("\n")); + _printf(_L("+-----------------------------------------+\n")); + _printf(_L("|+---------------------------------------+|\n")); + _printf(_L("|| This test listens for data on the ACM ||\n")); + _printf(_L("|| (Bulk OUT) data port . ||\n")); + _printf(_L("|| ||\n")); + _printf(_L("|| Once running, Press any key to quit. ||\n")); + _printf(_L("|+---------------------------------------+|\n")); + _printf(_L("+------------------------------------[rjf]+\n")); + _printf(_L("\n")); + + LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE)); + CleanupClosePushL(port); + + port.SetConfig(TheConfigBuf); + port.SetReceiveBufferLength(KReceiveBufferLength); + + // prime the console for the abandon-ship + + console->Read(consoleStatus); + + TInt uReadCount = 0 ; + //TInt uThermoBar = 0 ; // TODO: speed enhancement! (remove ThermoBar fnality) + + _printf(_L("\tWatch : ")); + + TInt uAvgCount = 0 ; + TInt uNumReads = 0 ; + TInt uNumRooms = 0 ; + + while (1) + { + // setup read to collect a single block by whatever method + // has been selected. + + if( bReadCall ) + { + port.Read(status, OUT_Buf, KChunkSize); // TODO: speed enhancement! + + uNumReads++ ; + } + else + { + port.ReadOneOrMore(status, OUT_Buf); + + uNumRooms++ ; + } + + // either the read is complete, or user request to stop the test + + User::WaitForRequest(status,consoleStatus); + + if (consoleStatus == KRequestPending) + { + // still waiting for keypress, so it must have been the read + // that completed, check if it worked OK + + if (status != KErrNone) + { + console->ReadCancel(); + + LEAVE(status.Int()); + } + + // reassure watcher that there is something happening... + + if( uAvgCount == 0 ) + { + uAvgCount = OUT_Buf.Length() ; + } + else + { + uAvgCount = ( ( 9 * uAvgCount ) + OUT_Buf.Length() ) / 10 ; + } + + uReadCount += OUT_Buf.Length() ; + +/* if( uReadCount >= 1024 ) + { + // uThermoBar runs from 0..63 + + uThermoBar = ( uThermoBar + 1 ) & 0x3F ; + + if( uThermoBar < 32 ) + { + _printf(_L("*")); + } + else + { + _printf(_L("\b \b")); + } + + uReadCount -= 1024 ; + } + */ + } + else + { + // user must have wanted to stop, shut down the reader + + _printf(_L("\n")); + _printf(_L("\n")); + _printf(_L("\nReads=%d, Rooms=%d, Average Count=%d"),uNumReads,uNumRooms,uAvgCount); + _printf(_L("\n")); + + _printf(_L("\n\n\tCancelling Read()")); + + port.ReadCancel(); + + _printf(_L("\n\n\tRead() Cancelled")); + + break; + } + } + + _printf(_L("\n")); + _printf(_L("\tBulk OUT says bye...")); + _printf(_L("\n")); + + CleanupStack::PopAndDestroy(); // port + } + +///////////////////////////////////////////////////////////////////////////////// + +void Bulk_IN_TestL() + { + TRequestStatus consoleStatus; + TRequestStatus status; + RComm port; + +//#define uInBufSize 4096 // TODO: speed enhancement! reduce number of IPC calls +#define uInBufSize 65536 + + static TBuf8 IN_Buf; + static TBuf8 ZLP_Buf; + + _printf(_L("\n")); + _printf(_L("+-------------------------------------+\n")); + _printf(_L("|+-----------------------------------+|\n")); + _printf(_L("|| This test writes data on the ACM ||\n")); + _printf(_L("|| (Bulk IN) data port ||\n")); + _printf(_L("|| ||\n")); + _printf(_L("|| On running, Press any key to quit ||\n")); + _printf(_L("|+-----------------------------------+|\n")); + _printf(_L("+--------------------------------[rjf]+\n")); + _printf(_L("\n")); + + LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE)); + CleanupClosePushL(port); + + port.SetConfig(TheConfigBuf); + port.SetReceiveBufferLength(KReceiveBufferLength); + + // set up the ZLP and set a default pattern into the buffer + + ZLP_Buf.SetLength(0) ; + + IN_Buf.SetLength( uInBufSize ) ; + + int j = 0 ; + + for( int i = 0 ; i < uInBufSize ; i++ ) + { + if( ( i % 64 ) == 0 ) + { + j++; + } + + switch( i % 64 ) + { + case 0 : + IN_Buf[i] = 0xFF ; + break ; + case 1 : + IN_Buf[i] = j / 256 ; + break ; + case 2 : + IN_Buf[i] = j % 256 ; + break ; + case 3 : + IN_Buf[i] = 0xFF ; + break ; + default: + IN_Buf[i] = i ; + break ; + } + } + + // prime the console for the abandon-ship + + console->Read(consoleStatus); + + TInt bDoneBlock = EFalse ; + + TInt bNeedZLP = bUseZLP && ((IN_Buf.Length()%64)==0); + + TInt uWriteCount = 0 ; +// TInt uThermoBar = 0 ; // TODO: speed enhancement! + + _printf(_L("\tWatch : ")); + + while (1) + { + // setup write to send a single block, this is either the + // block in the buffer, or else may be a ZLP which is sent + // on every other pass, provided the size of the block is + // exactly N*64 + + if( bDoneBlock && bNeedZLP ) + { + port.Write(status, ZLP_Buf); + + bDoneBlock = EFalse; + } + else + { + port.Write(status, IN_Buf); + + uWriteCount += IN_Buf.Length() ; + + bDoneBlock = ETrue; + } + + // either the write is complete, or user request to stop the test + + User::WaitForRequest(status,consoleStatus); + + if (consoleStatus == KRequestPending) + { + if (status != KErrNone) + { + console->ReadCancel(); + + LEAVE(status.Int()); + } + + // reassure watcher that there is something happening... + +/* while( uWriteCount >= 1024 ) + { + // uThermoBar runs from 0..63 + + uThermoBar = ( uThermoBar + 1 ) & 0x3F ; + + if( uThermoBar < 32 ) + { + _printf(_L("*")); + } + else + { + _printf(_L("\b \b")); + } + + uWriteCount -= 1024 ; + } + */ + } + else + { + _printf(_L("\n\n\tCancelling Write()")); + + port.WriteCancel(); + + _printf(_L("\n\n\tWrite() Cancelled")); + + break; + } + } + + _printf(_L("\n")); + _printf(_L("\tBulk IN says bye...")); + _printf(_L("\n")); + + CleanupStack::PopAndDestroy(); // port + } + +//////////////////////////////////////////////////////////////////////////////// + +void SetHandshakingL() + { + RComm port; + + TCommCaps capsBuf; + TCommCapsV01& caps = capsBuf(); + + LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE)); + CleanupClosePushL(port); + + port.Caps(capsBuf); + + _printf(_L("\nPort handshaking capabilities: 0x%08X\n"), caps.iHandshake); + _printf(_L("\nCurrent handshaking options: 0x%08X\n"), TheConfig.iHandshake); + + _printf(_L("\n")); + +#define HS(b) _printf(_L("\tTheConfig.%s = %s\n"), #b, ((TheConfig.iHandshake & b) == b) ? "Set" : "Clear" ) ; + + HS(KConfigObeyXoff); + HS(KConfigSendXoff); + HS(KConfigObeyCTS); + HS(KConfigObeyDSR); + HS(KConfigFreeRTS); + HS(KConfigWriteBufferedComplete); + + _printf(_L("\n\n")); + _printf(_L("Handshaking options:\n\n")); + _printf(_L("1. No handshaking\n")); + _printf(_L("2. Toggle Xon/Xoff\n")); + _printf(_L("3. Toggle obey CTS\n")); + _printf(_L("4. Toggle obey DSR / free RTS\n")); + _printf(_L("5. Toggle write buffered complete\n")); + + TKeyCode key = console->Getch(); + + switch (key) + { + case '1': + TheConfig.iHandshake = 0; + break; + case '2': + TheConfig.iHandshake ^= KConfigObeyXoff; + TheConfig.iHandshake ^= KConfigSendXoff; + break; + case '3': + TheConfig.iHandshake ^= KConfigObeyCTS; + break; + case '4': + TheConfig.iHandshake ^= KConfigObeyDSR; + TheConfig.iHandshake ^= KConfigFreeRTS; + break; + case '5': + TheConfig.iHandshake ^= KConfigWriteBufferedComplete; + break; + default: + break; + } + + LEAVEIFERROR(port.SetConfig(TheConfigBuf)); + + _printf(_L("Handshaking options now: 0x%X\n"), TheConfig.iHandshake); + + CleanupStack::PopAndDestroy(); + } + +//////////////////////////////////////////////////////////////////////////////// + +void RestartUsbL() + { + TheUsb.Stop(); + + TRequestStatus status; + TheUsb.Start(status); + User::WaitForRequest(status); + LEAVEIFERROR(status.Int()); + + _printf(_L("Restarted USB.\n")); + } + +//////////////////////////////////////////////////////////////////////////////// + +/*void ThermoBar() + { + TUint uCol = 0 ; + + TTime now; + + TDateTime WasDT; + TDateTime NowDT; + + now.HomeTime(); + WasDT = now.DateTime(); + + for( TUint line = 0 ; line < 30 ; ) + { + for( TUint dotO = 0 ; dotO < 1000 ; dotO++ ) + { + for( TUint dotI = 0 ; dotI < 1000 ; dotI++ ) + { + ; + } + } + + _printf(_L("*")); + + now.HomeTime(); + NowDT = now.DateTime(); + + if( ( ++uCol >= 79 ) || ( WasDT.Second() != NowDT.Second() ) ) + { + _printf(_L("\n")); + + uCol = 0 ; + + line++ ; + + WasDT = now.DateTime() ; + } + } + } +*/ +//////////////////////////////////////////////////////////////////////////////// + +void ToggleTermL() + { + bUseTerm = ( bUseTerm == EFalse ) ; + + if( bUseTerm ) + { + TheConfig.iTerminatorCount = 1 ; + + TheConfig.iTerminator[0] = 0x7E ; + } + else + { + TheConfig.iTerminatorCount = 0 ; + } + } + +//////////////////////////////////////////////////////////////////////////////// + +void mainL() + { + _printf(_L("\n")); + _printf(_L("+--------------------------------+\n")); + _printf(_L("|+------------------------------+|\n")); + _printf(_L("|| T_CATC : V1.00 : 25-Feb-2003 ||\n")); + _printf(_L("|+------------------------------+|\n")); + _printf(_L("+---------------------------[rjf]+\n")); + _printf(_L("\n")); + + TInt ret = User::LoadLogicalDevice(KUsbLddName); + if ((ret != KErrNone) && (ret != KErrAlreadyExists)) + LEAVE(ret); + + _printf(_L("Loaded USB LDD\n")); + + ret = StartC32(); + if ((ret != KErrNone) && (ret != KErrAlreadyExists)) + LEAVE(ret); + + _printf(_L("Started C32\n")); + + LEAVEIFERROR(TheUsb.Connect()); + + _printf(_L("Connected to USB Manager\n")); + + _printf(_L("\n")); + _printf(_L("+-------------------------------------+\n")); + _printf(_L("|+-----------------------------------+|\n")); + _printf(_L("|| Please connect the USB cable now! ||\n")); + _printf(_L("|+-----------------------------------+|\n")); + _printf(_L("+--------------------------------[rjf]+\n")); + _printf(_L("\n")); + + TRequestStatus status; + + TheUsb.Start(status); + User::WaitForRequest(status); + LEAVEIFERROR(status.Int()); + + _printf(_L("Started USB\n")); + + LEAVEIFERROR(TheCommServ.Connect()); + + _printf(_L("Connected to C32\n")); + + RComm port; + + // The port's configuration seems to be junk at the beginning, so we set it to known values. + + TheConfig.iRate = EBps115200; + TheConfig.iDataBits = EData8; + TheConfig.iStopBits = EStop1; + TheConfig.iParity = EParityNone; + TheConfig.iHandshake = 0; + TheConfig.iTerminatorCount = 0; + + LEAVEIFERROR(port.Open(TheCommServ, KUsbPortName, ECommExclusive, ECommRoleDCE)); + CleanupClosePushL(port); + + port.SetConfig(TheConfigBuf); + + CleanupStack::PopAndDestroy(); // port + + TBool exit = EFalse; + +#define SHOW(h,l,t,f) \ + { \ + _printf(_L("\n ")); \ + _printf(_L(h)); \ + _printf(_L("\t")); \ + \ + if( l ) \ + { \ + _printf(_L(t)); \ + } \ + else \ + { \ + _printf(_L(f)); \ + } \ + \ + _printf(_L("\n")); \ + } + + while (!exit) + { + _printf(_L("\n")); + _printf(_L("Current Settings:\n")); + _printf(_L("\n")); + SHOW("OUT Method", bReadCall,"Read()","ReadOneOrMore()"); + SHOW("ZLP Method", bUseZLP, "Active","Suppressed" ); + SHOW("Term Method",bUseTerm, "Active","Suppressed" ); + _printf(_L("\n")); + _printf(_L("Available tests: \n")); + _printf(_L("\n")); + _printf(_L("1. Bulk OUT test \n")); + _printf(_L("2. Bulk IN test \n")); + _printf(_L("3. Set handshaking \n")); + _printf(_L("4. Restart USB \n")); +// _printf(_L("5. Run ThermoBar \n")); + _printf(_L("6. Swap Read Method \n")); + _printf(_L("7. Swap ZLP Method \n")); + _printf(_L("8. Swap Term Method \n")); + _printf(_L("\n")); + _printf(_L("Select (q to quit): ")); + + char ch = (char) _getch(); + _printf(_L("\n")); + + switch (ch) + { + case '1': Bulk_OUT_TestL(); break; + case '2': Bulk_IN_TestL(); break; + case '3': SetHandshakingL(); break; + case '4': RestartUsbL(); break; +// case '5': ThermoBar(); break; + case '6': bReadCall = ( bReadCall == EFalse ) ; break; + case '7': bUseZLP = ( bUseZLP == EFalse ) ; break; + case '8': ToggleTermL() ; break; + + case 'q': + case 'Q': + exit = ETrue; + break; + + default: + _printf(_L("\nInvalid key\n")); + break; + } + } + + TheCommServ.Close(); + TheUsb.Close(); + } + +//////////////////////////////////////////////////////////////////////////////// + +void consoleMainL() + { + console=Console::NewL(_L("T_ACM"),TSize(KConsFullScreen,KConsFullScreen)); + CleanupStack::PushL(console); + mainL(); + _printf(_L("[ press any key ]")); + _getch(); + CleanupStack::PopAndDestroy(); + } + +//////////////////////////////////////////////////////////////////////////////// + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + CTrapCleanup* cleanupStack=CTrapCleanup::New(); + TRAP_IGNORE(consoleMainL()); + delete cleanupStack; + __UHEAP_MARKEND; + return 0; + } + +//////////////////////////////////////////////////////////////////////////////// +