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) 1997-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_modem1.cpp
// Test program for PC Card Serial Port Driver - Requires Dacom GoldCard Modem.
//
//
#include <e32std.h>
#include <e32std_private.h>
#include <e32test.h>
#include <e32cons.h>
#include <e32svr.h>
#include <e32hal.h>
#include <e32uid.h>
#include <d32comm.h>
#include <hal.h>
class RComm : public RBusDevComm
{
public:
TInt WriteS(const TDesC8& aDes);
};
const TInt KBlockSize=256;
// Block size Line rate
const TInt KBlocksShort=4; // 4*256=1K - <1200
const TInt KBlocksMedium=12; // 12*256=3K - <4800
const TInt KBlocksLong=64; // 64*256=16K - <28800
const TInt KBlocksVeryLong=128; // 128*256=32K - 28800
enum TLineRate {EV21_300,EBell103_300,EV22_1200,EBell212_1200,EV22bis_2400,
EV32_4800,EV32_9600,EV32bis_14400,EV34_28800,ELineRateEnd};
const TInt KMaxLineRates=ELineRateEnd;
const TInt KStandardRxBufferSize=0x400;
#if !defined (__WINS__)
#define PDD_NAME _L("EUARTn")
#define LDD_NAME _L("ECOMM")
#else
#define PDD_NAME _L("ECDRV.PDD")
#define LDD_NAME _L("ECOMM.LDD")
#endif
LOCAL_D RTest test(_L("T_MODEM1"));
LOCAL_D TInt LineModeData[KMaxLineRates]={0,64,1,69,2,9,9,10,11};
LOCAL_D TInt LineRateData[KMaxLineRates]={300,300,1200,1200,2400,4800,9600,14400,28800};
LOCAL_D TInt LineConnectData[KMaxLineRates]={1200,1200,1200,1200,2400,4800,9600,14400,28800};
LOCAL_D RComm *theSerialPort;
TInt RComm::WriteS(const TDesC8& aDes)
//
// Syncronous write
//
{
TRequestStatus s;
Write(s,aDes,aDes.Length());
User::WaitForRequest(s);
return(s.Int());
}
LOCAL_C TPtrC BaudRateInText(TBps aRate)
//
// Convert into Baudrate text
//
{
switch (aRate)
{
case EBps50: return(_L("50")); break;
case EBps75: return(_L("75")); break;
case EBps110: return(_L("110")); break;
case EBps134: return(_L("134")); break;
case EBps150: return(_L("150")); break;
case EBps300: return(_L("300")); break;
case EBps600: return(_L("600")); break;
case EBps1200: return(_L("1200")); break;
case EBps1800: return(_L("1800")); break;
case EBps2000: return(_L("2000")); break;
case EBps2400: return(_L("2400")); break;
case EBps3600: return(_L("3600")); break;
case EBps4800: return(_L("4800")); break;
case EBps7200: return(_L("7200")); break;
case EBps9600: return(_L("9600")); break;
case EBps19200: return(_L("19200")); break;
case EBps38400: return(_L("38400")); break;
case EBps57600: return(_L("57600")); break;
case EBps115200: return(_L("115000")); break;
default: return(_L("Unknown")); break;
}
}
LOCAL_C TInt TranslateCrLf(TDes8 &aDes)
//
// Search for CR/LF characters in a string and replace them with
// '\r' '\n' format. Also replaces unprintable characters with "?"
//
{
TText8 buf[KBlockSize];
TText8 *pS=(TText8*)aDes.Ptr();
TText8 *pSE=pS+aDes.Size();
TText8 *pT=&buf[0];
TText8 *pTMax=pT+(KBlockSize-1);
for (;pS<pSE;pS++,pT++)
{
if (pT>=pTMax)
return(KErrTooBig);
if (*pS=='\xD'||*pS=='\xA')
{
*pT++='\\';
*pT=(*pS=='\xD')?'r':'n';
}
else if (((TChar)*pS).IsPrint())
*pT=*pS;
else
*pT='\?';
}
*pT=0;
if ((pT-&buf[0])>aDes.MaxLength())
return(KErrTooBig);
aDes.Copy(&buf[0]);
return(KErrNone);
}
/* ???
LOCAL_C void PrintBuf(TDes8 &aBuf)
//
// Print the contents of a buffer
//
{
TInt len=aBuf.Length();
for (TInt i=0;i<=len/8;i++)
{
test.Printf(_L("%4d: "),i*8);
for (TInt j=0;j<8;j++)
{
if ((i*8)+j>=len)
break;
TInt v=aBuf[(i*8)+j];
test.Printf(_L("%02x "),v);
}
test.Printf(_L("\n\r"));
}
}
*/
LOCAL_C void testLoopBack(TLineRate aLineRate,TBps aBaudRate)
//
// Perform an analogue loopback test at the specified linerate
//
{
TInt err;
TBuf<64> b;
TPtrC bd=BaudRateInText(aBaudRate);
b.Format(_L("Loopback test(%S)"),&bd);
test.Start(b);
TBuf8<KBlockSize> txBuf;
theSerialPort->ResetBuffers();
txBuf.Format(_L8("AT&F+MS=%d,0,%d,%d\\N0&K3&D2M0\r"),LineModeData[aLineRate],LineRateData[aLineRate],LineRateData[aLineRate]);
test(theSerialPort->WriteS(txBuf)==KErrNone);
TBuf8<KBlockSize> rxBuf;
User::After(2000000); // 2Secs
err=theSerialPort->QueryReceiveBuffer();
test(err>0);
rxBuf.SetLength(err);
TRequestStatus rxStat;
theSerialPort->ReadOneOrMore(rxStat,rxBuf);
User::WaitForRequest(rxStat);
// test.Printf(_L(" Rx(%d):"),rxStat); // ???
test(rxStat==KErrNone);
txBuf.Append(_L("\r\nOK\r\n"));
err=rxBuf.Compare(txBuf);
// test(TranslateCrLf(rxBuf)==KErrNone); // ???
// test.Printf(_L(" %S\r\n"),&rxBuf); // ???
test(err==0);
test.Next(_L("Get loopback"));
txBuf.Format(_L8("AT&T1\r"));
test(theSerialPort->WriteS(txBuf)==KErrNone);
User::After(5000000); // 5Secs
err=theSerialPort->QueryReceiveBuffer();
test(err>0);
rxBuf.SetLength(err);
theSerialPort->ReadOneOrMore(rxStat,rxBuf);
User::WaitForRequest(rxStat);
test.Printf(_L(" Rx(%d):"),rxStat);
test(rxStat==KErrNone);
txBuf.AppendFormat(_L8("\r\nCONNECT %d\r\n"),LineConnectData[aLineRate]);
err=rxBuf.Compare(txBuf);
test(TranslateCrLf(rxBuf)==KErrNone);
test.Printf(_L(" %S\r\n"),&rxBuf); // Print what we got back (without CR/LF etc).
// Sometimes get extra character as modem goes on-line so just look for command echo + connect
test(err>=0);
User::After(2000000); // 2Secs
TInt totalBlocksToTransfer;
if (aBaudRate<EBps1200||aLineRate<EV22_1200)
totalBlocksToTransfer=KBlocksShort;
else if (aBaudRate<EBps4800||aLineRate<EV32_4800)
totalBlocksToTransfer=KBlocksMedium;
else if (aLineRate<EV34_28800)
totalBlocksToTransfer=KBlocksLong;
else
totalBlocksToTransfer=KBlocksVeryLong;
b.Format(_L("Transfering data(%dK)"),(totalBlocksToTransfer*KBlockSize)/1024);
test.Next(b);
TInt loopBackFail=KErrGeneral;
TRequestStatus txStat;
txBuf.SetLength(KBlockSize);
TInt i;
for (i=0;i<KBlockSize;i++)
txBuf[i]=(TUint8)i;
theSerialPort->Write(txStat,txBuf,KBlockSize);
TInt txBlks=(totalBlocksToTransfer-1);
rxBuf.Fill(0,KBlockSize);
theSerialPort->Read(rxStat,rxBuf,KBlockSize);
TInt rxBlks=0;
TRequestStatus tStat;
RTimer tim;
test(tim.CreateLocal()==KErrNone);
tim.After(tStat,40000000); // 40Secs
test.Printf(_L(">"));
FOREVER
{
User::WaitForAnyRequest();
if (tStat!=KRequestPending)
{
// test.Printf(_L("t")); // Timed out
theSerialPort->ReadCancel(); // Cancel serial read
User::WaitForRequest(rxStat);
if (txBlks>0)
{
theSerialPort->WriteCancel(); // Cancel serial write
User::WaitForRequest(txStat);
}
loopBackFail=KErrTimedOut; // Test failed
break;
}
else if (rxStat!=KRequestPending)
{
// test.Printf(_L("r")); // Serial rx request complete
if (rxStat!=0)
{
loopBackFail=rxStat.Int(); // Test failed
goto endSerial;
}
for (i=0;i<KBlockSize;i++)
{
if (rxBuf[i]!=i)
{
loopBackFail=KErrCorrupt; // Test failed
rxBuf[KBlockSize-1]=0;
// PrintBuf(rxBuf); // ???
// goto endSerial; // !!!Ignore compare fails for now!!!
}
}
test.Printf(_L("<"));
if (++rxBlks<totalBlocksToTransfer)
{
rxBuf.Fill(0,KBlockSize);
theSerialPort->Read(rxStat,rxBuf,KBlockSize);
}
else
{
loopBackFail=KErrNone;
endSerial:
tim.Cancel(); // Cancel timer request.
User::WaitForRequest(tStat);
if (txBlks>0)
{
theSerialPort->WriteCancel(); // Cancel serial write
User::WaitForRequest(txStat);
}
break;
}
}
else if (txStat!=KRequestPending)
{
// test.Printf(_L("s")); // Serial tx request complete
if (txBlks>0)
{
theSerialPort->Write(txStat,txBuf,KBlockSize);
test.Printf(_L(">"));
txBlks--;
}
}
else
{
// test.Printf(_L("?")); // Stray signal - cancel everything
theSerialPort->ReadCancel(); // Cancel serial read
User::WaitForRequest(rxStat);
tim.Cancel(); // Cancel timer request.
User::WaitForRequest(tStat);
if (txBlks>0)
{
theSerialPort->WriteCancel(); // Cancel serial write
User::WaitForRequest(txStat);
}
loopBackFail=KErrDied;
break;
}
}
test.Printf(_L(" (%d)\r\n"),loopBackFail);
// !!! At this point RTS may or may not be asserted following the write cancel. The
// following seems necessary to make sure RTS is asserted so any remaining Rx data
// can be received.and thrown away
User::After(2000000);
theSerialPort->ResetBuffers();
User::After(1000000); // Wait 1Secs for any remaining Rx data
tim.Close();
test.Next(_L("Disconnect"));
theSerialPort->ResetBuffers(); // Through away any remaining Rx data.
txBuf.Format(_L8("+++"));
test(theSerialPort->WriteS(txBuf)==KErrNone);
User::After(2000000); // 2Secs
err=theSerialPort->QueryReceiveBuffer();
test(err>0);
rxBuf.SetLength(err);
theSerialPort->ReadOneOrMore(rxStat,rxBuf);
User::WaitForRequest(rxStat);
test(rxStat==KErrNone);
txBuf.Append(_L("\r\nOK\r\n"));
err=rxBuf.Compare(txBuf);
// test(TranslateCrLf(rxBuf)==KErrNone); // ???
// test.Printf(_L(" %S\r\n"),&rxBuf); // ???
test(err==0);
txBuf.Format(_L8("ATH0\r"));
test(theSerialPort->WriteS(txBuf)==KErrNone);
User::After(4000000); // 4Secs
err=theSerialPort->QueryReceiveBuffer();
test(err>0);
rxBuf.SetLength(err);
theSerialPort->ReadOneOrMore(rxStat,rxBuf);
User::WaitForRequest(rxStat);
test(rxStat==KErrNone);
txBuf.Append(_L("\r\nOK\r\n"));
err=rxBuf.Compare(txBuf);
// test(TranslateCrLf(rxBuf)==KErrNone); // ???
// test.Printf(_L(" %S\r\n"),&rxBuf); // ???
test(err==0);
test.Next(_L("Check result"));
test(loopBackFail==KErrNone || loopBackFail==KErrCorrupt); // !!!Ignore compare fails for now!!!
// test(loopBackFail==KErrNone);
test.End();
}
LOCAL_C void testAllLineRates(TBps aRate)
//
// Perform loopback test at the specified baudrate in as many line modes that
// are supported at this baudrate
//
{
test.Start(_L("Setting baudrate"));
TCommConfig cBuf;
TCommConfigV01 &c=cBuf();
theSerialPort->Config(cBuf);
c.iRate=aRate;
c.iDataBits=EData8;
c.iStopBits=EStop1;
c.iParity=EParityNone;
c.iHandshake=KConfigObeyCTS;
// c.iHandshake=0;
test(theSerialPort->SetConfig(cBuf)==KErrNone);
if (aRate>=EBps38400)
{
test.Next(_L("Testing at V.34-28800"));
testLoopBack(EV34_28800,aRate);
}
if (aRate>=EBps19200)
{
test.Next(_L("Testing at V.32bis-14400"));
testLoopBack(EV32bis_14400,aRate);
}
if (aRate>=EBps9600)
{
test.Next(_L("Testing at V.32-9600"));
testLoopBack(EV32_9600,aRate);
}
// if (aRate>=EBps4800)
// {
// test.Next(_L("Testing at V.32-4800"));
// testLoopBack(EV32_4800,aRate);
// }
if (aRate>=EBps2400)
{
test.Next(_L("Testing at V.22bis-2400"));
testLoopBack(EV22bis_2400,aRate);
}
// if (aRate>=EBps1200)
// {
// test.Next(_L("Testing at Bell212-1200"));
// testLoopBack(EBell212_1200,aRate);
// }
// if (aRate>=EBps1200)
// {
// test.Next(_L("Testing at V.22-1200"));
// testLoopBack(EV22_1200,aRate);
// }
// test.Next(_L("Testing at Bell103-300"));
// testLoopBack(EBell103_300,aRate);
test.Next(_L("Testing at V.21-300"));
testLoopBack(EV21_300,aRate);
test.End();
}
GLDEF_C TInt E32Main()
{
// test.SetLogged(EFalse); // Turn off serial port debugging!
TInt r;
test.Title();
test.Start(_L("PC Card Modem Test Program"));
RProcess proc;
TBuf <0x100> cmd;
proc.CommandLine(cmd);
// First parameter (if present) sets the serial port number
TInt port=0;
if ((cmd.Length()>0) && (cmd[0]>='1' && cmd[0]<='4'))
port=(TInt)(cmd[0]-'0');
// 2nd parameter (if present) sets the start speed
// (4=115K,3=57600,2=38400,1=19200,0=9600)
TInt startSpeed=4;
if ((cmd.Length()>3) && (cmd[2]>='0' && cmd[2]<='4'))
startSpeed=(TInt)(cmd[2]-'0');
test.Next(_L("Load Device Drivers"));
TBuf<10> pddName=PDD_NAME;
#if !defined (__WINS__)
pddName[5]=(TText)('1'+port);
TInt muid=0;
if (HAL::Get(HAL::EMachineUid, muid)==KErrNone)
{
// Brutus uses EUART4 for both COM3 and COM4
if (muid==HAL::EMachineUid_Brutus && port==4)
pddName[5]=(TText)'4';
}
#endif
r=User::LoadPhysicalDevice(pddName);
test(r==KErrNone||r==KErrAlreadyExists);
r=User::LoadLogicalDevice(LDD_NAME);
test(r==KErrNone||r==KErrAlreadyExists);
test.Next(_L("Open serial port"));
theSerialPort=new RComm;
test(theSerialPort!=NULL);
r=theSerialPort->Open(port);
test(r==KErrNone);
// TCommCaps capsBuf;
// TCommCapsV01& caps=capsBuf();
// theSerialPort->Caps(capsBuf);
// Check that the driver powering sequence has completed successfully by
// issueing a few simple driver control functions.
test.Next(_L("Modem power tests"));
test(theSerialPort->SetReceiveBufferLength(KStandardRxBufferSize)==KErrNone);
r=theSerialPort->ReceiveBufferLength();
// test.Printf(_L("(%d)"),r); // ???
test(r==KStandardRxBufferSize);
r=(TInt)theSerialPort->Signals();
// test.Printf(_L("(%d)"),r); // ???
test(r>=0);
RTimer timer;
TRequestStatus rs;
test(timer.CreateLocal()==KErrNone);
TTime tim;
tim.HomeTime();
tim+=TTimeIntervalSeconds(8);
timer.At(rs,tim);
UserHal::SwitchOff();
User::WaitForRequest(rs);
test(rs.Int()==KErrNone);
r=theSerialPort->ReceiveBufferLength();
// test.Printf(_L("(%d)"),r); // ???
test(r==KStandardRxBufferSize);
r=(TInt)theSerialPort->Signals();
// test.Printf(_L("(%d)"),r); // ???
test(r>=0);
User::After(2000000); // 2Secs !!!
if (startSpeed>=4)
{
test.Next(_L("Testing at 115K"));
testAllLineRates(EBps115200);
}
if (startSpeed>=3)
{
test.Next(_L("Testing at 57600"));
testAllLineRates(EBps57600);
}
if (startSpeed>=2)
{
test.Next(_L("Testing at 38400"));
testAllLineRates(EBps38400);
}
if (startSpeed>=1)
{
test.Next(_L("Testing at 19200"));
testAllLineRates(EBps19200);
}
test.Next(_L("Testing at 9600"));
testAllLineRates(EBps9600);
test.Next(_L("Close serial port"));
theSerialPort->Close();
delete theSerialPort;
test.End();
return(KErrNone);
}