usbmgmt/usbmgrtest/t_catc/src/t_catc.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
--- /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 <e32base.h>
+#include <e32cons.h>
+#include <e32std.h>
+#include <badesca.h>
+#include <c32comm.h>
+#include <usbman.h>
+
+////////////////////////////////////////////////////////////////////////////////
+
+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<KChunkSize> 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<uInBufSize> IN_Buf;
+	static TBuf8<uInBufSize> 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;
+	}
+
+////////////////////////////////////////////////////////////////////////////////
+