Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "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:
// e32test\device\t_loop.cpp
//
//
//#define _DEBUG_DEVCOMM
#include <e32base.h>
#include <e32base_private.h>
#include <e32test.h>
#include <e32svr.h>
#include <d32comm.h>
#include <e32math.h>
#include <e32uid.h>
#if defined (__WINS__)
#define __COMM_LDD _L("ECOMM")
#define __COMM_PDD1 _L("ECDRV")
#else
#define __COMM_LDD _L("ECOMM")
#define __COMM_PDD1 _L("EUART1")
#define __COMM_PDD2 _L("EUART2")
#endif
const char KSpinner[]={'|','/','-','\\',};
const TInt KKeyboardPriority = 4;
const TInt KTimerPriority = 3;
const TInt KWriterPriority = 2;
const TInt KReaderPriority = 1;
////////////////////////////////////////////////////////////////////////////////
RTest Test(_L("T_LOOP"));
#define TEST(a) __DoTest((a), __FILE__, __LINE__, 0)
#define TESTERR(a,b) __DoTest((a), __FILE__, __LINE__, b)
void __DoTest(TBool aCondition, char* aFile, TInt aLine, TInt aErr)
{
if (aCondition)
return;
if (aErr==0)
Test.Printf(_L("\r\nCheckpoint Fail at %s:%d\r\n"), aFile, aLine);
else
Test.Printf(_L("\r\nCheckpoint Fail at %s:%d: Return code = %d (0x%x)\r\n"), aFile, aLine, aErr, aErr);
__DEBUGGER();
Test.Getch();
User::Exit(aErr);
}
////////////////////////////////////////////////////////////////////////////////
class CDevCommTestBase;
// This needs:
// inline void Read(TRequestStatus &aStatus) { iConsole->Read(aStatus); }
// inline void ReadCancel() { iConsole->ReadCancel(); }
// inline void TKeyCode KeyCode() { return iConsole->KeyCode(); }
// adding to RTest
class CKeyReader : public CActive
{
public:
CKeyReader(CDevCommTestBase* aTester, RTest& aTest);
~CKeyReader();
void Start();
protected:
void RunL();
void DoCancel();
public:
RTest& iTest;
TKeyCode iKey;
CDevCommTestBase* iTester;
};
class CDevCommIOBase : public CActive
{
public:
CDevCommIOBase(CDevCommTestBase* aTester, TInt aPriority);
~CDevCommIOBase();
void CreateL(TInt aBufferSize);
void UpdateCount();
void ResetCount();
public:
CDevCommTestBase* iTester;
TPtr8 iDes;
TUint8* iBuffer;
TInt iSize;
TInt iCount;
TInt iTotal;
};
class CDevCommWriterBase : public CDevCommIOBase
{
public:
CDevCommWriterBase(CDevCommTestBase* aTester);
~CDevCommWriterBase();
void Ready();
void Start();
protected:
void RunL();
void DoCancel();
};
class CDevCommReaderBase : public CDevCommIOBase
{
public:
CDevCommReaderBase(CDevCommTestBase* aTester);
~CDevCommReaderBase();
void Ready();
void Start();
protected:
void RunL();
void DoCancel();
};
class CDevCommTimerBase : public CTimer
{
public:
CDevCommTimerBase(CDevCommTestBase* aTester);
void CreateL();
protected:
void RunL();
public:
CDevCommTestBase* iTester;
};
enum THandshakeMode
{
EHandshakeNone,
EHandshakeHardware,
EHandshakeSoftware
};
class CDevCommTestBase : public CAsyncOneShot
{
public:
CDevCommTestBase();
~CDevCommTestBase();
void CreateL(TInt aBufferSize);
TInt Open(TInt aPort);
void Close();
void Debug();
TInt SetHandshaking(THandshakeMode aMode);
TInt LineFailOn();
TInt LineFailOff();
TInt ZeroTerminate();
void ShowLoopSignals(TUint aOutState, TUint aInState);
virtual void ReadComplete(TInt aStatus);
virtual void WriteComplete(TInt aStatus);
virtual void TimeComplete(TInt aStatus);
virtual void KeyComplete(TKeyCode aKey);
void Start();
public:
RBusDevComm iComm;
CDevCommWriterBase* iWriter;
CDevCommReaderBase* iReader;
CDevCommTimerBase* iTimer;
CKeyReader* iKeyboard;
TInt iBufferSize;
};
CKeyReader::CKeyReader(CDevCommTestBase* aTester, RTest& aTest)
: CActive(KKeyboardPriority), iTest(aTest), iTester(aTester)
{
__DECLARE_NAME(_S("CKeyReader"));
CActiveScheduler::Add(this);
}
CKeyReader::~CKeyReader()
{
Cancel();
}
void CKeyReader::Start()
{
if (IsActive())
return;
SetActive();
iTest.Console()->Read(iStatus);
}
void CKeyReader::RunL()
{
iKey = iTest.Console()->KeyCode();
iTester->KeyComplete(iKey);
Start();
}
void CKeyReader::DoCancel()
{
iTest.Console()->ReadCancel();
}
CDevCommIOBase::CDevCommIOBase(CDevCommTestBase* aTester, TInt aPriority)
: CActive(aPriority), iTester(aTester), iDes(NULL, 0)
{
__DECLARE_NAME(_S("CDevCommIOBase"));
CActiveScheduler::Add(this);
}
CDevCommIOBase::~CDevCommIOBase()
{
if (iBuffer)
User::Free(iBuffer);
}
void CDevCommIOBase::CreateL(TInt aSize)
{
iSize = aSize;
if (iSize>0)
iBuffer = (TUint8*)User::AllocL(iSize);
iDes.Set(iBuffer, iSize, iSize);
}
void CDevCommIOBase::UpdateCount()
{
iCount += iDes.Length();
iTotal += iDes.Length();
}
void CDevCommIOBase::ResetCount()
{
iCount = 0;
}
CDevCommWriterBase::CDevCommWriterBase(CDevCommTestBase* aTester)
: CDevCommIOBase(aTester, KWriterPriority)
{
__DECLARE_NAME(_S("CDevCommWriterBase"));
}
CDevCommWriterBase::~CDevCommWriterBase()
{
Cancel();
}
void CDevCommWriterBase::Start()
{
__ASSERT_ALWAYS(iBuffer!=NULL, User::Panic(_L("No Buffer"), 0));
if (IsActive())
return;
SetActive();
iTester->iComm.Write(iStatus, iDes);
}
void CDevCommWriterBase::Ready()
{
if (IsActive())
return;
SetActive();
iTester->iComm.Write(iStatus, TPtr8(NULL, 0));
}
void CDevCommWriterBase::RunL()
{
UpdateCount();
iTester->WriteComplete(iStatus.Int());
}
void CDevCommWriterBase::DoCancel()
{
iTester->iComm.WriteCancel();
}
CDevCommReaderBase::CDevCommReaderBase(CDevCommTestBase* aTester)
: CDevCommIOBase(aTester, KReaderPriority)
{
__DECLARE_NAME(_S("CDevCommReaderBase"));
}
CDevCommReaderBase::~CDevCommReaderBase()
{
Cancel();
}
void CDevCommReaderBase::Start()
{
__ASSERT_ALWAYS(iBuffer!=NULL, User::Panic(_L("No Buffer"), 0));
if (IsActive())
return;
SetActive();
iDes.SetLength(iDes.MaxLength()-iCount);
iTester->iComm.Read(iStatus, iDes);
}
void CDevCommReaderBase::Ready()
{
if (IsActive())
return;
SetActive();
TPtr8 ptr(NULL, 0);
iTester->iComm.Read(iStatus, ptr);
}
void CDevCommReaderBase::RunL()
{
UpdateCount();
iTester->ReadComplete(iStatus.Int());
}
void CDevCommReaderBase::DoCancel()
{
iTester->iComm.ReadCancel();
}
CDevCommTimerBase::CDevCommTimerBase(CDevCommTestBase* aTester)
: CTimer(KTimerPriority), iTester(aTester)
{
__DECLARE_NAME(_S("CDevCommTestTimerBase"));
CActiveScheduler::Add(this);
}
void CDevCommTimerBase::CreateL()
{
ConstructL();
}
void CDevCommTimerBase::RunL()
{
iTester->TimeComplete(iStatus.Int());
}
CDevCommTestBase::CDevCommTestBase()
: CAsyncOneShot(-1)
{
__DECLARE_NAME(_S("CDevCommTestBase"));
}
CDevCommTestBase::~CDevCommTestBase()
{
delete iKeyboard;
delete iTimer;
delete iWriter;
delete iReader;
iComm.Close();
}
void CDevCommTestBase::CreateL(TInt aBufferSize)
{
iBufferSize = aBufferSize;
iKeyboard = new (ELeave) CKeyReader(this, Test);
iTimer = new (ELeave) CDevCommTimerBase(this);
iWriter = new (ELeave) CDevCommWriterBase(this);
iReader = new (ELeave) CDevCommReaderBase(this);
iKeyboard->Start();
iWriter->CreateL(iBufferSize);
iTimer->CreateL();
iReader->CreateL(iBufferSize/16);
}
void CDevCommTestBase::Start()
{
Call();
}
TInt CDevCommTestBase::Open(TInt aPort)
{
TInt err;
if (err = iComm.Open(aPort), err!=KErrNone)
return err;
TCommConfig cBuf;
TCommConfigV01 &c=cBuf();
iComm.Config(cBuf);
c.iStopBits = EStop1;
c.iDataBits = EData8;
c.iParity = EParityNone;
c.iHandshake = 0
// | KConfigObeyXoff
// | KConfigSendXoff
| KConfigObeyCTS
// | KConfigFailCTS
| KConfigObeyDSR
// | KConfigFailDSR
// | KConfigObeyDCD
// | KConfigFailDCD
// | KConfigFreeRTS
// | KConfigFreeDTR
;
c.iRate = EBps115200;
c.iFifo = EFifoEnable;
c.iTerminatorCount = 0;
c.iTerminator[0] = 0x00;
if (err = iComm.SetConfig(cBuf), err!=KErrNone)
{
iComm.Close();
return err;
}
return KErrNone;
}
TInt CDevCommTestBase::ZeroTerminate()
{
TCommConfig cBuf;
TCommConfigV01 &c=cBuf();
iComm.Config(cBuf);
c.iTerminatorCount = 1;
c.iTerminator[0] = 0x00;
return iComm.SetConfig(cBuf);
}
void CDevCommTestBase::Close()
{
iTimer->Cancel();
iReader->Cancel();
iWriter->Cancel();
iComm.Close();
}
TInt CDevCommTestBase::SetHandshaking(THandshakeMode aMode)
{
TCommConfig cBuf;
TCommConfigV01 &c=cBuf();
iComm.Config(cBuf);
switch (aMode)
{
case EHandshakeNone:
c.iHandshake = 0
// | KConfigObeyXoff
// | KConfigSendXoff
// | KConfigObeyCTS
// | KConfigFailCTS
// | KConfigObeyDSR
// | KConfigFailDSR
// | KConfigObeyDCD
// | KConfigFailDCD
| KConfigFreeRTS
| KConfigFreeDTR
;
break;
case EHandshakeSoftware:
c.iXonChar=0x11;
c.iXoffChar=0x13;
c.iHandshake = 0
| KConfigObeyXoff
| KConfigSendXoff
// | KConfigObeyCTS
// | KConfigFailCTS
// | KConfigObeyDSR
// | KConfigFailDSR
// | KConfigObeyDCD
// | KConfigFailDCD
| KConfigFreeRTS
| KConfigFreeDTR
;
break;
case EHandshakeHardware:
c.iHandshake = 0
// | KConfigObeyXoff
// | KConfigSendXoff
| KConfigObeyCTS
// | KConfigFailCTS
| KConfigObeyDSR
// | KConfigFailDSR
// | KConfigObeyDCD
// | KConfigFailDCD
// | KConfigFreeRTS
// | KConfigFreeDTR
;
break;
}
return iComm.SetConfig(cBuf);
}
TInt CDevCommTestBase::LineFailOn()
{
TCommConfig cBuf;
TCommConfigV01 &c=cBuf();
iComm.Config(cBuf);
c.iHandshake |= (KConfigFailDSR|KConfigFailDCD);
return iComm.SetConfig(cBuf);
}
TInt CDevCommTestBase::LineFailOff()
{
TCommConfig cBuf;
TCommConfigV01 &c=cBuf();
iComm.Config(cBuf);
c.iHandshake &= ~(KConfigFailDSR|KConfigFailDCD);
return iComm.SetConfig(cBuf);
}
void CDevCommTestBase::ShowLoopSignals(TUint aOutState, TUint aInState)
{
TPtrC cts, dsr, dcd;
TPtrC rts, dtr;
rts.Set(aOutState & KSignalRTS ? _L("RTS On ") : _L("RTS Off"));
dtr.Set(aOutState & KSignalDTR ? _L("DTR On ") : _L("DTR Off"));
Test.Printf(_L("%S, %S : "), &rts, &dtr);
cts.Set(aInState & KSignalCTS ? _L("CTS On ") : _L("CTS Off"));
dsr.Set(aInState & KSignalDSR ? _L("DSR On ") : _L("DSR Off"));
dcd.Set(aInState & KSignalDCD ? _L("DCD On ") : _L("DCD Off"));
Test.Printf(_L("%S, %S, %S "), &cts, &dsr, &dcd);
rts.Set(aInState & KSignalRTS ? _L("RTS On ") : _L("RTS Off"));
dtr.Set(aInState & KSignalDTR ? _L("DTR On ") : _L("DTR Off"));
Test.Printf(_L("[%S, %S]\r\n"), &rts, &dtr);
}
#ifdef _DEBUG_DEVCOMM
void CDevCommTestBase::Debug()
{
TCommDebugInfoPckg infopckg;
TCommDebugInfo& info = infopckg();
iComm.DebugInfo(infopckg);
Test.Printf(_L(" LDD State : TX RX \r\n"));
Test.Printf(_L(" Busy : %10d %10d\r\n"), info.iTxBusy, info.iRxBusy);
Test.Printf(_L(" Held : %10d %10d\r\n"), info.iTxHeld, info.iRxHeld);
Test.Printf(_L(" Length : %10d %10d\r\n"), info.iTxLength, info.iRxLength);
Test.Printf(_L(" Offset : %10d %10d\r\n"), info.iTxOffset, info.iRxOffset);
Test.Printf(_L(" Int Count : %10d %10d\r\n"), info.iTxIntCount, info.iRxIntCount);
Test.Printf(_L(" Err Count : %10d %10d\r\n"), info.iTxErrCount, info.iRxErrCount);
Test.Printf(_L(" Buf Count : %10d %10d\r\n"), info.iTxBufCount, info.iRxBufCount);
Test.Printf(_L(" Fill/Drain : %10d %10d\r\n"), info.iFillingTxBuf, info.iFillingTxBuf);
Test.Printf(_L(" XON : %10d %10d\r\n"), info.iTxXon, info.iRxXon);
Test.Printf(_L(" XOFF : %10d %10d\r\n"), info.iTxXoff, info.iRxXoff);
Test.Printf(_L(" Chars : %10d %10d\r\n"), info.iTxChars, info.iRxChars);
// Test.Printf(_L(" DFC Pending : %10d %10d\r\n"), info.iTxDfcPend, info.iTxDfcPend);
// Test.Printf(_L(" DFC Run/Count : %10d %10d\r\n"), info.iRunningDfc, info.iDfcCount);
// Test.Printf(_L(" DFC Req/Do/Drain : %10d %10d %10d\r\n"), info.iDfcReqSeq, info.iDfcHandlerSeq, info.iDoDrainSeq);
}
#else
void CDevCommTestBase::Debug()
{
Test.Printf(_L("Debug Dump not available\r\n"));
}
#endif
void CDevCommTestBase::ReadComplete(TInt /*aStatus*/)
{}
void CDevCommTestBase::WriteComplete(TInt /*aStatus*/)
{}
void CDevCommTestBase::TimeComplete(TInt /*aStatus*/)
{}
void CDevCommTestBase::KeyComplete(TKeyCode /*aKey*/)
{}
////////////////////////////////////////////////////////////////////////////////
void StripeMem(TUint8 *aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset=0)
//
// Mark a buffer with repeating byte pattern
//
{
TUint character=aStartChar+(aOffset%((anEndChar+1)-aStartChar));
for (TInt i=aStartPos;i<anEndPos;i++)
{
aBuf[i]=(TText8)character;
if(++character>anEndChar)
character=aStartChar;
}
}
inline void StripeDes(TDes8 &aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset=0)
{
StripeMem((TUint8 *)aBuf.Ptr(), aStartPos, anEndPos, aStartChar, anEndChar, aOffset);
}
TBool CheckMem(TUint8 *aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset=0)
//
// Mark a buffer with repeating byte pattern
//
{
TUint character=aStartChar+(aOffset%((anEndChar+1)-aStartChar));
for (TInt i=aStartPos;i<anEndPos;i++)
{
if (aBuf[i]!=(TText8)character)
return EFalse;
if(++character>anEndChar)
character=aStartChar;
}
return ETrue;
}
inline TBool CheckDes(TDes8 &aBuf, TInt aStartPos, TInt anEndPos, TUint aStartChar, TUint anEndChar, TInt aOffset=0)
{
return CheckMem((TUint8 *)aBuf.Ptr(), aStartPos, anEndPos, aStartChar, anEndChar, aOffset);
}
////////////////////////////////////////////////////////////////////////////////
void CommStart()
{
TInt ret;
Test.Printf(_L("Loading Drivers\r\n"));
ret = User::LoadPhysicalDevice(__COMM_PDD1);
TESTERR(ret==KErrNone || ret==KErrAlreadyExists, ret);
// ret = User::LoadPhysicalDevice(__COMM_PDD2);
// TESTERR(ret==KErrNone || ret==KErrAlreadyExists, ret);
ret = User::LoadLogicalDevice(__COMM_LDD);
TESTERR(ret==KErrNone || ret==KErrAlreadyExists, ret);
Test.Printf(_L("OK\r\n"));
}
////////////////////////////////////////////////////////////////////////////////
class CTestRandTerm : public CDevCommTestBase
{
public:
enum TTestRandTermState { EIdle, EWaitReady, EWaitReset, EWaitIO };
enum TTestFailType { ETestFailBoth, ETestFailRead, ETestFailWrite, ETestBadData };
public:
static CTestRandTerm* NewL(TInt aPort);
CTestRandTerm();
~CTestRandTerm();
virtual void ReadComplete(TInt aStatus);
virtual void WriteComplete(TInt aStatus);
virtual void TimeComplete(TInt aStatus);
virtual void KeyComplete(TKeyCode aKey);
void Reset();
void Write();
void Read();
TBool CheckRead();
void Halt();
void Fail(TTestFailType aType, TInt aError);
protected:
virtual void RunL();
public:
TTestRandTermState iState;
TInt64 iSeed;
TInt iCount;
TInt iOffset;
TInt iRetries;
TInt iPackets;
TInt iSpin;
TBool iTrace;
};
CTestRandTerm::CTestRandTerm()
{
}
CTestRandTerm::~CTestRandTerm()
{
}
CTestRandTerm* CTestRandTerm::NewL(TInt aPort)
{
CTestRandTerm* tester = new (ELeave) CTestRandTerm;
CleanupStack::PushL(tester);
tester->CreateL(1000);
User::LeaveIfError(tester->Open(aPort));
CleanupStack::Pop();
return tester;
}
void CTestRandTerm::Reset()
{
Test.Printf(_L("Resetting Port\r\n"));
iReader->Cancel();
iWriter->Cancel();
iTimer->Cancel();
LineFailOff();
iComm.ResetBuffers();
iTimer->After(1000000);
iState = EWaitReset;
}
void CTestRandTerm::RunL()
{
iCount = 0;
iState = EIdle;
iSeed = 1;
Test.Printf(_L("Waiting for Port\r\n"));
ZeroTerminate();
iWriter->Ready();
iTimer->After(1000000);
iState = EWaitReady;
}
void CTestRandTerm::ReadComplete(TInt aStatus)
{
if (iTrace)
Test.Printf(_L("CTestRandTerm::ReadComplete(%d) len = %d/%d\r\n"), aStatus, iWriter->iDes.Length(), iWriter->iDes.MaxLength());
if (aStatus!=KErrNone)
{
Fail(ETestFailRead, aStatus);
return;
}
switch (iState)
{
case EWaitIO:
iRetries = 0;
iTimer->Cancel();
if (CheckRead())
{
iPackets++;
if (iReader->iCount==iWriter->iCount)
{
iCount += iWriter->iCount;
Test.Printf(_L("%c %6d %d\r"), KSpinner[iSpin++ & 3], iPackets, iCount);
Write();
Read();
}
else
{
iOffset = iReader->iCount;
Test.Printf(_L("%c\r"), KSpinner[iSpin++ & 3]);
Read();
}
}
else
{
Fail(ETestBadData, KErrNone);
}
break;
default:
break;
}
}
void CTestRandTerm::WriteComplete(TInt aStatus)
{
if (iTrace)
{
Test.Printf(_L("CTestRandTerm::WriteComplete(%d) len = %d/%d\r\n"), aStatus, iWriter->iDes.Length(), iWriter->iDes.MaxLength());
}
if (aStatus!=KErrNone)
{
Fail(ETestFailWrite, aStatus);
return;
}
switch (iState)
{
case EWaitReady:
iRetries = 0;
iTimer->Cancel();
iState = EWaitIO;
Test.Printf(_L("Port Ready\r\n"));
LineFailOn();
Write();
Read();
break;
case EWaitIO:
iRetries = 0;
if (iReader->iCount==iWriter->iCount)
{
Write();
Read();
}
break;
default:
break;
}
}
void CTestRandTerm::TimeComplete(TInt aStatus)
{
if (iTrace)
Test.Printf(_L("CTestRandTerm::TimeComplete(%d)\r\n"), aStatus);
if (aStatus!=KErrNone)
{
__DEBUGGER();
return;
}
switch (iState)
{
case EWaitReset:
Test.Printf(_L("Waiting for Port\r\n"));
iWriter->Ready();
iTimer->After(1000000);
iState = EWaitReady;
break;
case EWaitReady:
if (++iRetries>10)
{
Test.Printf(_L("Too many retries\r\n"));
Halt();
}
else
{
Test.Printf(_L("%c\r"), KSpinner[iSpin++ & 3]);
iWriter->Ready();
iTimer->After(1000000);
}
break;
case EWaitIO:
Fail(ETestFailBoth, KErrTimedOut);
break;
default:
Reset();
break;
}
}
void CTestRandTerm::KeyComplete(TKeyCode aKey)
{
if (iTrace)
Test.Printf(_L("CTestRandTerm::KeyComplete(%d)\r\n"), aKey);
switch ((TInt)aKey)
{
case EKeyEscape:
Halt();
break;
case 'd':
case 'D':
Debug();
break;
case 'q':
case 'Q':
iTrace = 0;
break;
case 'v':
case 'V':
iTrace = 1;
break;
default:
break;
}
}
void CTestRandTerm::Fail(TTestFailType aType, TInt aError)
{
switch (aType)
{
case ETestFailBoth:
Test.Printf(_L("Timeout at offset %d\r\n"), iOffset);
break;
case ETestFailRead:
Test.Printf(_L("Read fail (%d) at offset %d\r\n"), aError, iOffset);
break;
case ETestFailWrite:
Test.Printf(_L("Write fail (%d) at offset %d\r\n"), aError, iOffset);
break;
case ETestBadData:
Test.Printf(_L("Data verify failure at offset %d\r\n"), iOffset);
break;
}
Debug();
Reset();
}
void CTestRandTerm::Write()
{
iOffset = 0;
iWriter->ResetCount();
iReader->ResetCount();
TInt i;
TInt j = 0;
StripeDes(iWriter->iDes, 0, iBufferSize, '@', 'Z');
while (j<iBufferSize)
{
i = Math::Rand(iSeed) % (iBufferSize/4);
if (j+i<iBufferSize)
iWriter->iDes[j+i] = '\0';
j += i;
}
iWriter->Start();
}
void CTestRandTerm::Read()
{
iReader->Start();
iTimer->After(5000000);
}
TBool CTestRandTerm::CheckRead()
{
TPtrC8 ref;
ref.Set(iWriter->iDes.Ptr()+iOffset, iReader->iDes.Length());
return ref.Compare(iReader->iDes)==0;
}
void CTestRandTerm::Halt()
{
iReader->Cancel();
iWriter->Cancel();
iTimer->Cancel();
CActiveScheduler::Stop();
}
////////////////////////////////////////////////////////////////////////////////
class CTestSignals : public CDevCommTestBase
{
public:
enum TTestState { EAllOff, ERtsOn, EDtrOn, EAllOn, EMonitor };
public:
static CTestSignals* NewL(TInt aPort);
CTestSignals();
~CTestSignals();
virtual void KeyComplete(TKeyCode aKey);
virtual void ReadComplete(TInt aStatus);
void Halt();
void DoSignals(TTestState aState);
protected:
virtual void RunL();
public:
TTestState iState;
};
CTestSignals::CTestSignals()
{
}
CTestSignals::~CTestSignals()
{
}
CTestSignals* CTestSignals::NewL(TInt aPort)
{
CTestSignals* tester = new (ELeave) CTestSignals;
CleanupStack::PushL(tester);
tester->CreateL(0);
User::LeaveIfError(tester->Open(aPort));
CleanupStack::Pop();
return tester;
}
void CTestSignals::RunL()
{
TCommConfig cBuf;
TCommConfigV01 &c=cBuf();
iComm.Config(cBuf);
c.iHandshake = KConfigFreeRTS | KConfigFreeDTR;
iComm.SetConfig(cBuf);
iReader->Ready();
}
void CTestSignals::Halt()
{
Test.Printf(_L(" \r"));
CActiveScheduler::Stop();
}
void CTestSignals::ReadComplete(TInt /*aStatus*/)
{
DoSignals(EAllOff);
}
void CTestSignals::KeyComplete(TKeyCode aKey)
{
switch (aKey)
{
case EKeyEscape:
Halt();
break;
default:
switch (iState)
{
case EAllOff:
DoSignals(ERtsOn);
break;
case ERtsOn:
DoSignals(EDtrOn);
break;
case EDtrOn:
DoSignals(EAllOn);
break;
case EAllOn:
DoSignals(EAllOff);
break;
default:
break;
}
}
}
void CTestSignals::DoSignals(TTestState aState)
{
TUint set=0, clr=0;
switch (aState)
{
case EAllOff:
set = 0;
clr = KSignalRTS | KSignalDTR;
break;
case ERtsOn:
set = KSignalRTS;
clr = KSignalDTR;
break;
case EDtrOn:
set = KSignalDTR;
clr = KSignalRTS;
break;
case EAllOn:
set = KSignalRTS | KSignalDTR;
clr = 0;
break;
default:
set = 0;
clr = 0;
}
iComm.SetSignals(set, clr);
TUint sig = iComm.Signals();
ShowLoopSignals(set, sig);
iState = aState;
Test.Printf(_L("Press key for next state\r"));
}
////////////////////////////////////////////////////////////////////////////////
class CTestPerf : public CDevCommTestBase
{
public:
enum TTestRandTermState { EIdle, EWaitReady, EWaitReset, EWaitIO };
enum TTestFailType { ETestFailBoth, ETestFailRead, ETestFailWrite, ETestBadData };
public:
static CTestPerf* NewL(TInt aPort);
CTestPerf();
~CTestPerf();
virtual void ReadComplete(TInt aStatus);
virtual void WriteComplete(TInt aStatus);
virtual void TimeComplete(TInt aStatus);
virtual void KeyComplete(TKeyCode aKey);
void Reset();
void Write();
void Read();
TBool CheckRead();
void Halt();
void Fail(TTestFailType aType, TInt aError);
protected:
virtual void RunL();
public:
TTestRandTermState iState;
TInt64 iSeed;
TInt iCount;
TInt iOffset;
TInt iRetries;
TInt iPackets;
TInt iSpin;
TBool iTrace;
TTime iStartTime;
TInt iRate;
TInt iSpeed;
};
CTestPerf::CTestPerf()
{
}
CTestPerf::~CTestPerf()
{
}
CTestPerf* CTestPerf::NewL(TInt aPort)
{
CTestPerf* tester = new (ELeave) CTestPerf;
CleanupStack::PushL(tester);
tester->CreateL(250);
User::LeaveIfError(tester->Open(aPort));
CleanupStack::Pop();
StripeDes(tester->iWriter->iDes, 0, tester->iBufferSize, '@', 'Z');
return tester;
}
void CTestPerf::Reset()
{
Test.Printf(_L("Resetting Port\r\n"));
iReader->Cancel();
iWriter->Cancel();
iTimer->Cancel();
LineFailOff();
iComm.ResetBuffers();
iTimer->After(1000000);
iState = EWaitReset;
}
void CTestPerf::RunL()
{
iCount = 0;
iState = EIdle;
iSeed = 1;
Test.Printf(_L("Waiting for Port\r\n"));
ZeroTerminate();
iWriter->Ready();
iTimer->After(1000000);
iState = EWaitReady;
}
void CTestPerf::ReadComplete(TInt aStatus)
{
if (iTrace)
Test.Printf(_L("CTestPerf::ReadComplete(%d) len = %d/%d\r\n"), aStatus, iWriter->iDes.Length(), iWriter->iDes.MaxLength());
if (aStatus!=KErrNone)
{
Fail(ETestFailRead, aStatus);
return;
}
switch (iState)
{
case EWaitIO:
iRetries = 0;
iTimer->Cancel();
iCount += iReader->iCount;
iPackets++;
{
TTime end;
end.UniversalTime();
TInt64 difftime = (end.MicroSecondsFrom(iStartTime).Int64()+TInt64(500000))/TInt64(1000000);
if (difftime==0)
difftime = 1;
TInt64 cps = MAKE_TINT64(0,iCount)/difftime;
TInt rate = (I64INT(cps)*10000)/11520;
iRate += rate;
iSpeed += I64INT(cps);
Test.Printf(_L("%c %6d %d (%dbps=%d.%02d%%)\r"), KSpinner[iSpin++ & 3], iPackets, iCount, iSpeed/iPackets, (iRate/iPackets)/100, (iRate/iPackets)%100);
}
Read();
break;
default:
break;
}
}
void CTestPerf::WriteComplete(TInt aStatus)
{
if (iTrace)
{
Test.Printf(_L("CTestPerf::WriteComplete(%d) len = %d/%d\r\n"), aStatus, iWriter->iDes.Length(), iWriter->iDes.MaxLength());
}
if (aStatus!=KErrNone)
{
Fail(ETestFailWrite, aStatus);
return;
}
switch (iState)
{
case EWaitReady:
iRetries = 0;
iTimer->Cancel();
iState = EWaitIO;
Test.Printf(_L("Port Ready\r\n"));
LineFailOn();
iStartTime.UniversalTime();;
Write();
Read();
break;
case EWaitIO:
iRetries = 0;
Write();
break;
default:
break;
}
}
void CTestPerf::TimeComplete(TInt aStatus)
{
if (iTrace)
Test.Printf(_L("CTestPerf::TimeComplete(%d)\r\n"), aStatus);
if (aStatus!=KErrNone)
{
__DEBUGGER();
return;
}
switch (iState)
{
case EWaitReset:
Test.Printf(_L("Waiting for Port\r\n"));
iWriter->Ready();
iTimer->After(1000000);
iState = EWaitReady;
break;
case EWaitReady:
if (++iRetries>10)
{
Test.Printf(_L("Too many retries\r\n"));
Halt();
}
else
{
Test.Printf(_L("%c\r"), KSpinner[iSpin++ & 3]);
iWriter->Ready();
iTimer->After(1000000);
}
break;
case EWaitIO:
Fail(ETestFailBoth, KErrTimedOut);
break;
default:
Reset();
break;
}
}
void CTestPerf::KeyComplete(TKeyCode aKey)
{
if (iTrace)
Test.Printf(_L("CTestPerf::KeyComplete(%d)\r\n"), aKey);
switch ((TInt)aKey)
{
case EKeyEscape:
Halt();
break;
case 'd':
case 'D':
Test.Printf(_L("\r\n"));
Debug();
break;
case 'q':
case 'Q':
iTrace = 0;
break;
case 'v':
case 'V':
iTrace = 1;
break;
case 's':
case 'S':
Test.Printf(_L("\r\n"));
Test.Printf(_L("Keyboard : %08x, %d\r\n"), iKeyboard->iStatus.Int(), iKeyboard->IsActive());
Test.Printf(_L("Timer : %08x, %d\r\n"), iTimer->iStatus.Int(), iTimer->IsActive());
Test.Printf(_L("Reader : %08x, %d\r\n"), iReader->iStatus.Int(), iReader->IsActive());
Test.Printf(_L("Writer : %08x, %d\r\n"), iWriter->iStatus.Int(), iWriter->IsActive());
break;
default:
break;
}
}
void CTestPerf::Fail(TTestFailType aType, TInt aError)
{
switch (aType)
{
case ETestFailBoth:
Test.Printf(_L("\r\nTimeout at offset %d\r\n"), iOffset);
break;
case ETestFailRead:
Test.Printf(_L("\r\nRead fail (%d) at offset %d\r\n"), aError, iOffset);
break;
case ETestFailWrite:
Test.Printf(_L("\r\nWrite fail (%d) at offset %d\r\n"), aError, iOffset);
break;
case ETestBadData:
Test.Printf(_L("\r\nData verify failure at offset %d\r\n"), iOffset);
break;
}
Debug();
Reset();
}
void CTestPerf::Write()
{
iOffset = 0;
iWriter->ResetCount();
iWriter->Start();
}
void CTestPerf::Read()
{
iReader->ResetCount();
iReader->Start();
iTimer->After(5000000);
}
TBool CTestPerf::CheckRead()
{
TPtrC8 ref;
ref.Set(iWriter->iDes.Ptr()+iOffset, iReader->iDes.Length());
return ref.Compare(iReader->iDes)==0;
}
void CTestPerf::Halt()
{
iReader->Cancel();
iWriter->Cancel();
iTimer->Cancel();
CActiveScheduler::Stop();
}
////////////////////////////////////////////////////////////////////////////////
class CTestXonXoff : public CDevCommTestBase
{
public:
enum TTestRandTermState { EIdle, EWaitReady, EWaitReset, EWaitIO };
enum TTestFailType { ETestFailBoth, ETestFailRead, ETestFailWrite, ETestBadData };
public:
static CTestXonXoff* NewL(TInt aPort);
CTestXonXoff();
~CTestXonXoff();
virtual void ReadComplete(TInt aStatus);
virtual void WriteComplete(TInt aStatus);
virtual void TimeComplete(TInt aStatus);
virtual void KeyComplete(TKeyCode aKey);
void Reset();
void Write();
void Read();
TBool CheckRead();
void Halt();
void Fail(TTestFailType aType, TInt aError);
protected:
virtual void RunL();
public:
TTestRandTermState iState;
TInt64 iSeed;
TInt iCount;
TInt iOffset;
TInt iRetries;
TInt iPackets;
TInt iSpin;
TBool iTrace;
TTime iStartTime;
TInt iRate;
TInt iSpeed;
};
CTestXonXoff::CTestXonXoff()
{
}
CTestXonXoff::~CTestXonXoff()
{
}
CTestXonXoff* CTestXonXoff::NewL(TInt aPort)
{
CTestXonXoff* tester = new (ELeave) CTestXonXoff;
CleanupStack::PushL(tester);
tester->CreateL(16384);
User::LeaveIfError(tester->Open(aPort));
User::LeaveIfError(tester->SetHandshaking(EHandshakeSoftware));
CleanupStack::Pop();
StripeDes(tester->iWriter->iDes, 0, tester->iBufferSize, '@', 'Z');
return tester;
}
void CTestXonXoff::Reset()
{
Test.Printf(_L("Resetting Port\r\n"));
iReader->Cancel();
iWriter->Cancel();
iTimer->Cancel();
LineFailOff();
iComm.ResetBuffers();
iTimer->After(1000000);
iState = EWaitReset;
}
void CTestXonXoff::RunL()
{
iCount = 0;
iState = EIdle;
iSeed = 1;
Test.Printf(_L("Waiting for Port\r\n"));
ZeroTerminate();
iWriter->Ready();
iTimer->After(1000000);
// iState = EWaitReady;
// WriteComplete(0);
}
void CTestXonXoff::ReadComplete(TInt aStatus)
{
if (iTrace)
Test.Printf(_L("CTestXonXoff::ReadComplete(%d) len = %d/%d (%d)\r\n"), aStatus, iReader->iDes.Length(), iReader->iDes.MaxLength(), iReader->iTotal);
if (aStatus!=KErrNone)
{
Fail(ETestFailRead, aStatus);
return;
}
switch (iState)
{
case EWaitIO:
iRetries = 0;
iTimer->Cancel();
if (!CheckDes(iReader->iDes, 0, iReader->iDes.Length(), '@', 'Z', iCount & 0x3fff))
{
Fail(ETestBadData, aStatus);
return;
}
iCount += iReader->iCount;
iPackets++;
{
TTime end;
end.UniversalTime();
TInt64 difftime = (end.MicroSecondsFrom(iStartTime).Int64()+TInt64(500000))/TInt64(1000000);
if (difftime==0)
difftime = 1;
TInt64 cps = MAKE_TINT64(0,iCount)/difftime;
TInt rate = (I64INT(cps)*10000)/11520;
iRate += rate;
iSpeed += I64INT(cps);
Test.Printf(_L("%c %6d %d (%dbps=%d.%02d%%)\r"), KSpinner[iSpin++ & 3], iPackets, iCount, iSpeed/iPackets, (iRate/iPackets)/100, (iRate/iPackets)%100);
}
Read();
break;
default:
break;
}
}
void CTestXonXoff::WriteComplete(TInt aStatus)
{
if (iTrace)
{
Test.Printf(_L("CTestXonXoff::WriteComplete(%d) len = %d/%d (%d)\r\n"), aStatus, iWriter->iDes.Length(), iWriter->iDes.MaxLength(), iWriter->iTotal);
}
if (aStatus!=KErrNone)
{
Fail(ETestFailWrite, aStatus);
return;
}
switch (iState)
{
case EWaitReady:
iRetries = 0;
iTimer->Cancel();
iState = EWaitIO;
Test.Printf(_L("Port Ready\r\n"));
LineFailOn();
iStartTime.UniversalTime();;
Write();
Read();
break;
case EWaitIO:
iRetries = 0;
Write();
break;
default:
break;
}
}
void CTestXonXoff::TimeComplete(TInt aStatus)
{
if (iTrace)
Test.Printf(_L("CTestXonXoff::TimeComplete(%d)\r\n"), aStatus);
if (aStatus!=KErrNone)
{
__DEBUGGER();
return;
}
switch (iState)
{
case EWaitReset:
Test.Printf(_L("Waiting for Port\r\n"));
iWriter->Ready();
iTimer->After(1000000);
iState = EWaitReady;
break;
case EWaitReady:
if (++iRetries>10)
{
Test.Printf(_L("Too many retries\r\n"));
Halt();
}
else
{
Test.Printf(_L("%c\r"), KSpinner[iSpin++ & 3]);
iWriter->Ready();
iTimer->After(1000000);
}
break;
case EWaitIO:
Fail(ETestFailBoth, KErrTimedOut);
break;
default:
Reset();
break;
}
}
void CTestXonXoff::KeyComplete(TKeyCode aKey)
{
if (iTrace)
Test.Printf(_L("CTestXonXoff::KeyComplete(%d)\r\n"), aKey);
switch ((TInt)aKey)
{
case EKeyEscape:
Halt();
break;
case 'd':
case 'D':
Test.Printf(_L("\r\n"));
Debug();
break;
case 'q':
case 'Q':
iTrace = 0;
break;
case 'v':
case 'V':
iTrace = 1;
break;
case 's':
case 'S':
Test.Printf(_L("\r\n"));
Test.Printf(_L("Keyboard : %08x, %d\r\n"), iKeyboard->iStatus.Int(), iKeyboard->IsActive());
Test.Printf(_L("Timer : %08x, %d\r\n"), iTimer->iStatus.Int(), iTimer->IsActive());
Test.Printf(_L("Reader : %08x, %d\r\n"), iReader->iStatus.Int(), iReader->IsActive());
Test.Printf(_L("Writer : %08x, %d\r\n"), iWriter->iStatus.Int(), iWriter->IsActive());
break;
default:
break;
}
}
void CTestXonXoff::Fail(TTestFailType aType, TInt aError)
{
switch (aType)
{
case ETestFailBoth:
Test.Printf(_L("\r\nTimeout at offset %d\r\n"), iOffset);
break;
case ETestFailRead:
Test.Printf(_L("\r\nRead fail (%d) at offset %d\r\n"), aError, iOffset);
break;
case ETestFailWrite:
Test.Printf(_L("\r\nWrite fail (%d) at offset %d\r\n"), aError, iOffset);
break;
case ETestBadData:
Test.Printf(_L("\r\nData verify failure at offset %d\r\n"), iOffset);
break;
}
Debug();
Reset();
}
void CTestXonXoff::Write()
{
iOffset = 0;
iWriter->ResetCount();
StripeDes(iWriter->iDes, 0, iWriter->iDes.Length(), '@', 'Z');
iWriter->Start();
}
void CTestXonXoff::Read()
{
User::After(1000000);
iReader->ResetCount();
iReader->Start();
iTimer->After(5000000);
}
TBool CTestXonXoff::CheckRead()
{
TPtrC8 ref;
ref.Set(iWriter->iDes.Ptr()+iOffset, iReader->iDes.Length());
return ref.Compare(iReader->iDes)==0;
}
void CTestXonXoff::Halt()
{
iReader->Cancel();
iWriter->Cancel();
iTimer->Cancel();
CActiveScheduler::Stop();
}
////////////////////////////////////////////////////////////////////////////////
TInt E32Main()
{
TInt err;
Test.Start(_L("Comm Driver Tests"));
CommStart();
Test.Printf(_L("Insert plug in then press a key\r\n"));
Test.Getch();
TEST(CTrapCleanup::New()!=NULL);
CActiveScheduler* Scheduler = new CActiveScheduler;
TEST(Scheduler!=NULL);
CActiveScheduler::Install(Scheduler);
/*
CTestSignals* testsignals = NULL;
TRAP(err, testsignals = CTestSignals::NewL(0));
TEST(err==KErrNone);
testsignals->Start();
Scheduler->Start();
delete testsignals;
CTestRandTerm* testrandterm = NULL;
TRAP(err, testrandterm = CTestRandTerm::NewL(0));
TEST(err==KErrNone);
testrandterm->Start();
Scheduler->Start();
delete testrandterm;
CTestPerf* testperf = NULL;
TRAP(err, testperf = CTestPerf::NewL(0));
TEST(err==KErrNone);
testperf->Start();
Scheduler->Start();
delete testperf;
*/
CTestXonXoff* testx = NULL;
TRAP(err, testx = CTestXonXoff::NewL(0));
TEST(err==KErrNone);
testx->Start();
Scheduler->Start();
delete testx;
/*
CTestXonXoff* testx1 = NULL;
TRAP(err, testx1 = CTestXonXoff::NewL(0));
TEST(err==KErrNone);
testx1->Start();
CTestXonXoff* testx2 = NULL;
TRAP(err, testx2 = CTestXonXoff::NewL(1));
TEST(err==KErrNone);
testx2->Start();
Scheduler->Start();
delete testx1;
delete testx2;
*/
Test.End();
return KErrNone;
}