usbmgmt/usbmgrtest/t_usbmodem/src/t_usbmodem.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_usbmodem/src/t_usbmodem.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,966 @@
+/*
+* 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:
+* This test is used to pipe data to and from the USB ACM comm port to
+* a real comm port connected to a modem.
+*
+*/
+
+#include "t_usbmodem.h"
+#include <e32debug.h>
+
+//
+//--- class CSimplexRead ----------------------------------------------------
+//
+CSimplexRead* CSimplexRead::NewL(CDuplex& aDuplex)
+	{
+	CSimplexRead* self = new (ELeave) CSimplexRead(aDuplex);
+	self->ConstructL();
+	CActiveScheduler::Add(self);
+	return (self);	
+	}
+
+void CSimplexRead::ConstructL()
+	{
+	// Not much to do yet
+	}
+
+void CSimplexRead::StartL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexRead::StartL\n"));
+#endif
+	if(IsActive())
+		{
+		RDebug::Print(_L(": CSimplexRead::StartL Warning - Already active\n"));
+		return;
+		}
+	//iBuffer.SetMax();	
+	iCommPort->ReadOneOrMore(iStatus, iBuffer);
+	SetActive();
+	}
+
+void CSimplexRead::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexRead::RunL - iStatus:%d iBuffer.Length:%d TotalAmount Left:%d\n"),iStatus.Int(),iBuffer.Length(),iTotalAmount);
+#endif
+	//RDebug::Print(_L(">%S<\n"),&iBuffer);
+	//Notify Duplex object
+	iDuplex.NotifyRead(iStatus.Int(),iBuffer.Length(), iBuffer);
+	}
+
+void CSimplexRead::DoCancel(void)
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexRead::DoCancel\n"));
+#endif
+	if(iCommPort)
+		iCommPort->ReadCancel();
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexRead::DoCancel done\n"));
+#endif
+	}
+
+//
+//--- class CSimplexWrite ----------------------------------------------------
+//
+CSimplexWrite* CSimplexWrite::NewL(CDuplex& aDuplex)
+	{
+	CSimplexWrite* self = new (ELeave) CSimplexWrite(aDuplex);
+	self->ConstructL();
+	CActiveScheduler::Add(self);
+	return (self);	
+	}
+
+void CSimplexWrite::ConstructL()
+	{
+	// Not much to do yet
+	}
+
+void CSimplexWrite::StartL(TDes8& aBuf)
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexWrite::StartL - About to write l=%d\n"),aBuf.Length());
+#endif
+	if(IsActive())
+		{
+		RDebug::Print(_L(": CSimplexWrite::StartL Warning - Already active\n"));
+		return;
+		}
+
+	iCommPort->Write(iStatus, aBuf);
+	SetActive();
+	}
+
+void CSimplexWrite::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexWrite::RunL - iStatus:%d"),iStatus.Int());
+#endif
+	//Notify Duplex object
+	iDuplex.NotifyWrite(iStatus.Int());
+	}
+
+void CSimplexWrite::DoCancel(void)
+	{
+	if(iCommPort)
+		iCommPort->WriteCancel();
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSimplexWrite:: Comm port write Canceled\n"));
+#endif
+	}
+
+//
+// --- class CDuplex ---------------------------------------------------------
+//
+CDuplex* CDuplex::NewL()
+	{
+	CDuplex* self = new (ELeave) CDuplex();
+	self->ConstructL();
+	return (self);	
+	}
+
+void CDuplex::ConstructL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::ConstructL\n"));
+#endif
+	//Create reader and writer
+	iSimplexRead = CSimplexRead::NewL(*this);
+	iSimplexWrite = CSimplexWrite::NewL(*this);
+	}
+
+void CDuplex::StartL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::StartL\n"));
+#endif
+	iSimplexRead->StartL();
+	}
+
+void CDuplex::Cancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::Cancel\n"));
+#endif
+	if(iSimplexRead)
+		iSimplexRead->Cancel(); 
+	if(iSimplexWrite)
+		iSimplexWrite->Cancel();
+	}
+
+#ifdef _DEBUG
+	void CDuplex::NotifyRead(TInt aErr,TInt aSize, TDes8& aBuf)
+#endif
+
+#ifndef _DEBUG
+	void CDuplex::NotifyRead(TInt aErr,TInt /*aSize*/, TDes8& aBuf)
+#endif
+	{
+	TInt ignoreErr;
+
+	// Check if error
+	switch(aErr)
+		{
+		case KErrNone:
+			// Start the write
+#ifdef _DEBUG
+			RDebug::Print(_L(": CDuplex::NotifyRead err:%d recvd:%d\n"), aErr, aSize);
+#endif
+			TRAP(ignoreErr, iSimplexWrite->StartL(aBuf));
+			break;
+		default:
+#ifdef _DEBUG
+			RDebug::Print(_L(": CDuplex::NotifyRead error:%d\n"), aErr);
+#endif
+			Cancel();
+			break;
+		}
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::NotifyRead Done \n"), aErr, aSize);
+#endif
+	return;
+	}
+
+void CDuplex::NotifyWrite(TInt aErr)
+	{
+	TInt ignoreErr;
+
+	// Check if error
+	switch(aErr)
+		{
+		case KErrNone:
+			//Not much right now, just trigger another read
+#ifdef _DEBUG
+			RDebug::Print(_L(": CDuplex::NotifyWrite err:%d \n"), aErr);
+#endif
+			TRAP(ignoreErr, iSimplexRead->StartL());
+			break;
+		default:
+#ifdef _DEBUG
+			RDebug::Print(_L(": CDuplex::NotifyWrite error:%d\n"), aErr);
+#endif
+			Cancel();
+			break;
+		}
+#ifdef _DEBUG
+	RDebug::Print(_L(": CDuplex::NotifyWrite Done \n"), aErr);
+#endif
+
+	return;
+	}
+
+CDuplex::~CDuplex()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": Deleting CDuplex\n"));
+#endif
+	Cancel();
+	delete iSimplexRead;
+	delete iSimplexWrite;
+	}
+
+//
+//----- class CConfigChangeNotifier -----------------------------------------
+//
+CConfigChangeNotifier::CConfigChangeNotifier()
+	:CActive(CActive::EPriorityStandard)
+	{
+	}
+
+CConfigChangeNotifier* CConfigChangeNotifier::NewL()
+	{
+	CConfigChangeNotifier* self = new (ELeave) CConfigChangeNotifier();
+	CActiveScheduler::Add(self);				// Add to active scheduler
+	return self;
+	}
+	
+void CConfigChangeNotifier::DoCancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CConfigChangeNotifier::DoCancel"));
+#endif
+	TheUsbPort.NotifyConfigChangeCancel();
+	}
+
+void CConfigChangeNotifier::StartL()
+	{
+	if (IsActive())
+		{
+		RDebug::Print(_L(": Config chabge Notifier Already active"));
+		return;
+		}
+	TheUsbPort.NotifyConfigChange(iStatus, TheUsbConfigBuf);
+	SetActive();
+	}
+
+void CConfigChangeNotifier::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": Config Change Notifier activated"));
+#endif
+	// Set the serial port config
+	TCommConfig aConfig;
+	TheUsbPort.Config(aConfig);
+	TheSerialPort.SetConfig(aConfig);
+	StartL();
+	}
+
+//
+//----- class CSignalChageNotifier -----------------------------------------
+//
+CSignalChangeNotifier::CSignalChangeNotifier(TBool aIsUsbPort)
+	:CActive(CActive::EPriorityStandard),
+	iIsUsbPort(aIsUsbPort)
+	{
+	}
+
+CSignalChangeNotifier* CSignalChangeNotifier::NewL(TBool aIsUsbPort)
+	{
+	CSignalChangeNotifier* self = new (ELeave) CSignalChangeNotifier(aIsUsbPort);
+	CActiveScheduler::Add(self);				// Add to active scheduler
+	return self;
+	}
+	
+void CSignalChangeNotifier::DoCancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CSignalChangeNotifier::DoCancel"));
+#endif
+	if (iIsUsbPort)
+		TheUsbPort.NotifySignalChangeCancel();
+	else 
+		TheSerialPort.NotifySignalChangeCancel();
+	}
+
+void CSignalChangeNotifier::StartL()
+	{
+	if (IsActive())
+		{
+		RDebug::Print(_L(": Signal Notifier Already active"));
+		return;
+		}
+	else if (iIsUsbPort)
+		{
+		RDebug::Print(_L(": Starting Signal Notifier for USB"));
+		TheUsbPort.NotifySignalChange(iStatus, iInSignals, KSignalDCEInputs | KSignalDCEOutputs | KSignalBreak);
+		}
+	else 
+		{
+		RDebug::Print(_L(": Starting Signal Notifier for serial port"));
+		TheSerialPort.NotifySignalChange(iStatus, iInSignals, KSignalDTEInputs);
+		}
+
+	SetActive();
+	}
+
+void CSignalChangeNotifier::RunL()
+	{
+	// if this object is for USB,
+	if (iIsUsbPort)
+		{
+#ifdef _DEBUG
+		RDebug::Print(_L(": Signal Change Notifier activated for USB - %x"), iInSignals);
+#endif
+		if ( iInSignals & KRTSChanged )
+			{
+			if ( iInSignals & KSignalRTS )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": Serial RTS on"));
+#endif
+				TheSerialPort.SetSignals( KSignalRTS, 0 );
+				//TheUsbPort.SetSignals( KSignalCTS, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": Serial RTS off"));
+#endif
+				TheSerialPort.SetSignals( 0, KSignalRTS );
+				//TheUsbPort.SetSignals( 0, KSignalCTS );
+				}
+			}
+	
+		if ( iInSignals & KDTRChanged )
+			{
+			if ( iInSignals & KSignalDTR )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": Serial DTR on"));
+#endif
+				TheSerialPort.SetSignals( KSignalDTR, 0 );
+				//TheUsbPort.SetSignals( KSignalDSR, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": Serial DTR off"));
+#endif
+				TheSerialPort.SetSignals( 0, KSignalDTR );
+				//TheUsbPort.SetSignals( 0, KSignalDSR );
+				}
+			}
+
+		}
+	else 
+		{
+#ifdef _DEBUG
+		RDebug::Print(_L(": Signal Change Notifier activated for Serial port - %x"), iInSignals);
+#endif
+		if ( iInSignals & KCTSChanged )
+			{
+			if ( iInSignals & KSignalCTS )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB CTS on"));
+#endif
+				TheUsbPort.SetSignals( KSignalCTS, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB CTS off"));
+#endif
+				TheUsbPort.SetSignals( 0, KSignalCTS );
+				}
+			}
+		if ( iInSignals & KDSRChanged )
+			{
+			if ( iInSignals & KSignalDSR )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB DSR on"));
+#endif
+				TheUsbPort.SetSignals( KSignalDSR, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB DSR off"));
+#endif
+				TheUsbPort.SetSignals( 0, KSignalDSR );
+				}
+			}
+
+		if ( iInSignals & KDCDChanged )
+			{
+				if ( iInSignals & KSignalDCD )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB DCD on"));
+#endif
+				TheUsbPort.SetSignals( KSignalDCD, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB DCD off"));
+#endif
+				TheUsbPort.SetSignals( 0, KSignalDCD );
+				}
+			}
+
+		if ( iInSignals & KRNGChanged )
+			{
+			if ( iInSignals & KSignalRNG )
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB RNG on"));
+#endif
+				TheUsbPort.SetSignals( KSignalRNG, 0 );
+				}
+			else
+				{
+#ifdef _DEBUG
+				RDebug::Print(_L(": USB RNG off"));
+#endif
+				TheUsbPort.SetSignals( 0, KSignalRNG );
+				}
+			}
+		}
+	StartL();
+	}
+
+//
+//----- class CFControlChangeNotifier -----------------------------------------
+//
+CFControlChangeNotifier::CFControlChangeNotifier()
+	:CActive(CActive::EPriorityStandard)
+	{
+	}
+
+CFControlChangeNotifier* CFControlChangeNotifier::NewL()
+	{
+	CFControlChangeNotifier* self = new (ELeave) CFControlChangeNotifier();
+	CActiveScheduler::Add(self);				// Add to active scheduler
+	return self;
+	}
+	
+void CFControlChangeNotifier::DoCancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CFControlChangeNotifier::DoCancel()"));
+#endif
+	TheUsbPort.NotifyFlowControlChangeCancel();
+	}
+
+void CFControlChangeNotifier::StartL()
+	{
+	if (IsActive())
+		{
+		RDebug::Print(_L(": FlowControl Notifier Already active"));
+		return;
+		}
+	TheUsbPort.NotifyFlowControlChange(iStatus, iFlowControl);
+	SetActive();
+	}
+
+void CFControlChangeNotifier::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": FlowControl Notifier activated"));
+#endif
+	StartL();
+	}
+
+//
+// --- class CActiveConsole -------------------------------------------------
+//
+
+CActiveConsole::CActiveConsole()
+	: CActive(CActive::EPriorityStandard),
+	iIsRunning(EFalse)
+	{}
+
+
+CActiveConsole* CActiveConsole::NewLC()
+	{
+	CActiveConsole* self = new (ELeave) CActiveConsole();
+	self->ConstructL();
+	return self;
+	}
+
+
+CActiveConsole* CActiveConsole::NewL()
+	{
+	CActiveConsole* self = NewLC();
+	return self;
+	}
+
+CActiveConsole::~CActiveConsole()
+	{
+	delete iUsbToSerial;
+	delete iSerialToUsb;
+	}
+
+void CActiveConsole::DoCancel()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::DoCancel()"));
+#endif
+	iUsbConfigChangeNotifier->Cancel();
+	iSerialSignalChangeNotifier->Cancel();
+	iUsbSignalChangeNotifier->Cancel();
+	//iUsbFControlNotifier->Cancel();
+	
+	iUsbToSerial->Cancel();
+	iSerialToUsb->Cancel();
+	
+	iIsRunning = EFalse;
+	}
+
+void CActiveConsole::RunL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::RunL()"));
+#endif
+	ProcessKeyPressL();
+	WaitForKeyPress();
+	}
+
+void CActiveConsole::ConstructL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::ConstructL()"));
+#endif
+	CActiveScheduler::Add(this);				// Add to active scheduler
+
+	// Create 2 reader writer AOs/ threads
+	// 1 for reading from USb and writing to serial
+	iUsbToSerial = CDuplex::NewL();
+	iUsbToSerial->SetRxPort(&TheUsbPort);
+	iUsbToSerial->SetTxPort(&TheSerialPort);
+	
+	// 1 for reading from Serial and writing to Usb
+	iSerialToUsb = CDuplex::NewL();
+	iSerialToUsb->SetRxPort(&TheSerialPort);
+	iSerialToUsb->SetTxPort(&TheUsbPort);
+
+	iSerialSignalChangeNotifier = CSignalChangeNotifier::NewL(EFalse);
+	iUsbSignalChangeNotifier = CSignalChangeNotifier::NewL(ETrue);
+//	iUsbFControlNotifier = CFControlChangeNotifier::NewL();
+	iUsbConfigChangeNotifier = CConfigChangeNotifier::NewL();
+	}
+
+void CActiveConsole::Start()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::Start()"));
+#endif
+	if (iIsRunning)
+		{
+		TheWindow.Write(_L(": Invalid Key pressed, already running\n"));
+		return;
+		}
+	iIsRunning = ETrue;
+	TInt ignoreErr;
+	TRAP(ignoreErr, iUsbConfigChangeNotifier->StartL());
+	TRAP(ignoreErr, iSerialSignalChangeNotifier->StartL());
+	TRAP(ignoreErr, iUsbSignalChangeNotifier->StartL());
+//	iUsbFControlNotifier->StartL();
+	
+	TRAP(ignoreErr, iUsbToSerial->StartL());
+	TRAP(ignoreErr, iSerialToUsb->StartL());
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::Start() done"));
+#endif
+	}
+
+void CActiveConsole::WaitForKeyPress()
+	{
+	if (IsActive())
+		{
+		RDebug::Print(_L(": ActiveConsole -- Already Running\n"));
+		return;
+		}
+		
+	TheWindow.Write(_L("Press Escape to STOP\n"));
+	TheWindow.Write(_L("Press Enter to EXIT\n"));
+	if (!iIsRunning)
+		{
+		TheWindow.Write(_L("Press Spacebar to START test\n"));
+		}
+	else
+		{
+		TheWindow.Write(_L("1 DTR on	A DTR off\n"));
+		TheWindow.Write(_L("2 RTS on	B RTS off\n"));
+		TheWindow.Write(_L("3 DSR on	C DSR off\n"));
+		TheWindow.Write(_L("4 CTS on	D CTS off\n"));
+		TheWindow.Write(_L("5 DCD on	E DCD off\n"));
+		TheWindow.Write(_L("6 RNG on	F RNG off\n"));
+		TheWindow.Write(_L("7 BRK on	G BRK off\n"));
+		}
+	TheWindow.Write(_L("\n"));
+	TheWindow.Write(_L("\n"));
+	TheWindow.Read(iKeypress, iStatus);
+	SetActive();
+	}
+
+void CActiveConsole::ProcessKeyPressL()
+	{
+#ifdef _DEBUG
+	RDebug::Print(_L(": CActiveConsole::ProcessKeyPressL()"));
+#endif
+	switch (iKeypress.Code())
+		{
+		case EKeyEscape:
+			RDebug::Print(_L(": Stopping CactiveConsole"));
+			DoCancel();
+			break;
+		case EKeySpace:
+			RDebug::Print(_L(": Starting"));
+			Start();
+			break;
+		case EKeyEnter:
+			RDebug::Print(_L(": Exiting"));
+			DoCancel();
+
+			RDebug::Print(_L(": Closing ports and servers"));
+	
+			TheUsbPort.Close();
+			TheSerialPort.Close();
+			TheUsbServer.Close();
+			TheCommServer.Close();
+
+			CActiveScheduler::Stop();
+			break;
+		case '1':
+			TheUsbPort.SetSignals ( KSignalDTR, 0 );
+			break;
+		case '2':
+			TheUsbPort.SetSignals ( KSignalRTS, 0 );
+			break;
+		case '3':
+			TheUsbPort.SetSignals ( KSignalDSR, 0 );
+			break;
+		case '4':
+			TheUsbPort.SetSignals ( KSignalCTS, 0 );
+			break;
+		case '5':
+			TheUsbPort.SetSignals ( KSignalDCD, 0 );
+			break;
+		case '6':
+			TheUsbPort.SetSignals ( KSignalRNG, 0 );
+			break;
+		case '7':
+			TheUsbPort.Break ( iBreakRequest, 1000 );
+			break;
+		case 'A':
+			TheUsbPort.SetSignals ( 0, KSignalDTR );
+			break;
+		case 'B':
+			TheUsbPort.SetSignals ( 0, KSignalRTS );
+			break;
+		case 'C':
+			TheUsbPort.SetSignals ( 0, KSignalDSR );
+			break;
+		case 'D':
+			TheUsbPort.SetSignals ( 0, KSignalCTS );
+			break;
+		case 'E':
+			TheUsbPort.SetSignals ( 0, KSignalDCD );
+			break;
+		case 'F':
+			TheUsbPort.SetSignals ( 0, KSignalRNG );
+			break;
+		default:
+			TheWindow.Write(_L(": Invalid Key pressed\n"));
+		}
+	}
+
+/*
+LOCAL_C TInt RateToInt(TBps aRate)
+	{
+	switch (aRate)
+		{
+	case EBps115200:	return 115200;
+    case EBps57600:	return 57600;
+    case EBps38400:	return 38400;
+    case EBps19200:	return 19200;
+    case EBps9600:	return 9600;
+	case EBps7200:	return 7200;
+    case EBps4800:	return 4800;
+	case EBps3600:	return 3600;
+    case EBps2400:	return 2400;
+	case EBps2000:	return 2000;
+	case EBps1800:	return 1800;
+    case EBps1200:	return 1200;
+    case EBps600:	return 600;
+    case EBps300:	return 300;
+    case EBps150:	return 150;
+	case EBps134:	return 134;
+    case EBps110:	return 110;
+	case EBps75:	return 75;
+	case EBps50:	return 50;
+	default:	return -1;
+		}
+	}
+
+LOCAL_C void ConfigString(TDes &aBuf, const TCommNotificationV01 &aConfig)
+	{
+	// Config
+	aBuf.Format(_L(" %d "), RateToInt(aConfig.iRate));
+	switch (aConfig.iParity)
+		{
+	case EParityEven: aBuf.Append(_L("E")); break;
+	case EParityOdd: aBuf.Append(_L("O")); break;
+	case EParityNone: aBuf.Append(_L("N")); break;
+    default: break;
+		}
+	switch (aConfig.iDataBits)
+		{
+	case EData5: aBuf.Append(_L("5")); break;
+	case EData6: aBuf.Append(_L("6")); break;
+	case EData7: aBuf.Append(_L("7")); break;
+	case EData8: aBuf.Append(_L("8")); break;
+    default: break;
+		}
+	if (aConfig.iStopBits==EStop1)
+		aBuf.Append(_L("1 "));
+	else
+		aBuf.Append(_L("2 "));
+
+	aBuf.Append(_L("Use:"));
+	if (aConfig.iHandshake==0)
+		aBuf.Append(_L("NoControl "));
+	if (aConfig.iHandshake&(KConfigObeyXoff|KConfigSendXoff))
+		aBuf.Append(_L("XonXoff "));
+	if (aConfig.iHandshake&KConfigObeyCTS)
+		aBuf.Append(_L("CTS/RTS "));
+	if (aConfig.iHandshake&KConfigObeyDSR)
+		aBuf.Append(_L("DSR/DTR "));
+	if (aConfig.iHandshake&KConfigWriteBufferedComplete)
+		aBuf.Append(_L("Early "));
+	//|KConfigObeyDCD|KConfigFailDCD|))
+
+//	if (aConfig.iBreak==TEiger::EBreakOn)
+//		aBuf.Append(_L("Brk "));
+//	if (aConfig.iFifo==EFifoEnable)
+//		aBuf.Append(_L("Fifo "));
+	}
+	
+LOCAL_C void PrintCaps()
+	{
+	TCommCaps2 caps;
+	TheUsbPort.Caps(caps);
+	TUint notifycaps = caps().iNotificationCaps;
+	RDebug::Print(_L("Capabilities:\n"));
+	if (notifycaps&KNotifySignalsChangeSupported)
+		RDebug::Print(_L("Notify Signals Change supported\n"));
+	if (notifycaps&KNotifyRateChangeSupported)
+		RDebug::Print(_L("Notify Rate Change supported\n"));
+	if (notifycaps&KNotifyDataFormatChangeSupported)
+		RDebug::Print(_L("Notify Data Format Change supported\n"));
+	if (notifycaps&KNotifyHandshakeChangeSupported)
+		RDebug::Print(_L("Notify Handshake Change supported\n"));
+	if (notifycaps&KNotifyBreakSupported)
+		RDebug::Print(_L("Notify Break supported\n"));
+	if (notifycaps&KNotifyFlowControlChangeSupported)
+		RDebug::Print(_L("Notify Flow Control Change supported\n"));
+	if (notifycaps&KNotifyDataAvailableSupported)
+		RDebug::Print(_L("Notify Data Available supported\n"));
+	if (notifycaps&KNotifyOutputEmptySupported)
+		RDebug::Print(_L("Notify Output Empty supported\n"));
+	RDebug::Print(_L("\n"));
+	if ((caps().iRoleCaps)&KCapsRoleSwitchSupported)
+		RDebug::Print(_L("Role switching is supported\n"));
+	RDebug::Print(_L("\n"));
+	if ((caps().iFlowControlCaps)&KCapsFlowControlStatusSupported)
+		RDebug::Print(_L("Retrieve flow control status is supported\n"));
+	}
+*/
+LOCAL_C void DoInitL()
+	{
+	// Do the necessary initialisation of the C32, 2 comm ports, USB stuff.
+	// Load Device Drivers
+	TInt r;
+
+	RDebug::Print(_L("E32Main: Load USB LDD \n"));
+	r=User::LoadLogicalDevice(USBLDD_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed 0x%X\n\r"),r);
+		User::Panic(_L("T_TERM"), ELoadLogicalDeviceErr);
+		}
+
+	RDebug::Print(_L("E32Main: Load Serial PDD \n "));
+	r=User::LoadPhysicalDevice(SERIALPDD_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed 0x%X\n\r"),r);
+		User::Panic(_L("T_TERM"), ELoadLogicalDeviceErr);
+		}
+
+	RDebug::Print(_L("E32Main: Load SERIAL LDD \n"));
+	r=User::LoadLogicalDevice(SERIALLDD_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed 0x%X\n\r"),r);
+		User::Panic(_L("T_TERM"), ELoadLogicalDeviceErr);
+		}
+	RDebug::Print(_L("E32Main: Loaded Device Drivers\n"));
+	
+	r = StartC32();
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to start C32. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Started c32"));
+
+	r = TheUsbServer.Connect();
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to connect to UsbMan Server. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Connected to UsbMan Server"));
+
+	TRequestStatus startStatus;
+	TheUsbServer.Start(startStatus);
+	User::WaitForRequest(startStatus);
+	if (startStatus != KErrNone && startStatus != KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to Start USB services. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Started USB services"));
+
+	// Comms Config
+	r = TheCommServer.Connect();
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Connect to C32. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Connected to C32 Server"));
+
+	r = TheCommServer.LoadCommModule(USBCSY_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to load USB CSY. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Loaded USB CSY"));
+
+	r = TheCommServer.LoadCommModule(SERIALCSY_NAME);
+	if (r!=KErrNone && r!=KErrAlreadyExists)
+		{
+		RDebug::Print(_L("E32Main: Failed to load serial CSY. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Loaded Serial CSY"));
+
+	r = TheUsbPort.Open(TheCommServer, USBPORT_NAME,ECommExclusive,ECommRoleDCE); // Comm port
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Open USB Comm Port. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Opened USB Comm Port"));
+
+
+	r = TheSerialPort.Open(TheCommServer, SERIALPORT_NAME,ECommExclusive,ECommRoleDTE); // Comm port
+	if (r!=KErrNone)
+		{
+		RDebug::Print(_L("E32Main: Failed to Open Serial Comm Port. Error = %d"), r);
+		User::Panic(_L("T_TERM"), EOpenErr);
+		}
+	RDebug::Print(_L("E32Main: Opened Serial Comm Port"));
+
+	// Print the caps
+	//PrintCaps();
+
+	RDebug::Print(_L("E32Main: Reading Serial Comm Port config"));
+	TheSerialPort.Config(TheSerialConfigBuf);	// get config
+	RDebug::Print(_L("E32Main: Reading Usb Comm Port config"));
+	TheUsbPort.Config(TheUsbConfigBuf);	// get config
+
+	TBuf<80> buf;
+	buf.FillZ();
+	//ConfigString(buf, TheUsbConfig);
+	RDebug::Print(_L("E32Main: Old USB Port Settings"));
+	RDebug::Print(buf);
+	RDebug::Print(_L(""));
+	buf.FillZ();
+	//ConfigString(buf, TheSerialConfig);
+	RDebug::Print(_L("E32Main: Old Serial Port Settings"));
+	RDebug::Print(buf);
+	RDebug::Print(_L(""));
+
+	TCommConfig serialConfig;
+	TheSerialPort.Config(serialConfig);	// get config
+	serialConfig().iHandshake = 0;
+	serialConfig().iRate = EBps1152000;
+	TheSerialPort.SetConfig(serialConfig);
+
+	RDebug::Print(_L(""));	}
+
+/// Main function
+//
+GLDEF_C TInt E32Main()
+	{
+	RDebug::Print(_L("E32Main: Starting!"));
+	// Construct the active scheduler
+	CActiveScheduler* myScheduler = new (ELeave) CActiveScheduler();
+
+	// Install as the active scheduler
+	CActiveScheduler::Install(myScheduler);
+
+	// Create objects and console handler
+	// Open the window asap
+	TheWindow.Init(_L("TERM"),TSize(KConsFullScreen,KConsFullScreen));
+
+	TheWindow.Control(_L("+Maximize +Newline"));
+	RDebug::Print(_L("E32Main: Initialised Window!"));
+
+	DoInitL();
+	
+	// Does the construction, 
+	CActiveConsole* myActiveConsole = CActiveConsole::NewL();
+
+    // Call request function to start the test
+	myActiveConsole->WaitForKeyPress();	
+	// Start active scheduler
+	CActiveScheduler::Start();
+
+	// Suspend thread for 2 secs
+	User::After(2000000);
+
+	delete myActiveConsole;
+	return KErrNone;
+	}
+