os/kernelhwsrv/kerneltest/e32test/device/t_serial.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\device\t_serial.cpp
    15 // 
    16 //
    17 
    18 //#define _DEBUG_DEVCOMM
    19 
    20 #define __E32TEST_EXTENSION__
    21 #include <e32base.h>
    22 #include <e32base_private.h>
    23 #include <e32test.h>
    24 #include <e32cons.h>
    25 #include <e32svr.h>
    26 #include <e32hal.h>
    27 #include <d32comm.h>
    28 #include <e32uid.h>
    29 #include <hal.h>
    30 #include "d_lddturnaroundtimertest.h"
    31 #include <u32hal.h>
    32 
    33 //#define DRIVER_TRACE_ON // disables or adjusts timeout for tests affected by LDD trace
    34 
    35 // Enable aggressive paging policy if required
    36 #if 0
    37 #define WDP_ENABLED // affects some tests
    38 #define FLUSH_WDP_CACHE UserSvr::HalFunction(EHalGroupVM,EVMHalFlushCache,0,0)
    39 #else
    40 #define FLUSH_WDP_CACHE
    41 #endif
    42 
    43 #if defined (__WINS__)
    44 #define PDD_NAME _L("ECDRV.PDD")
    45 #define LDD_NAME _L("ECOMM.LDD")
    46 #else
    47 #define PDD_NAME _L("EUART")
    48 #define LDD_NAME _L("ECOMM")
    49 #endif
    50 
    51 const char KSpinner[]={'|','/','-','\\',};
    52 
    53 #include "../power/async.h"
    54 
    55 #define CHECK(r,v)	{if ((r)!=(v)) {test.Printf(_L("Line %d Expected %d Got %d\n"),__LINE__,(v),(r)); test(0);}}
    56 
    57 // constant expressions for elements in an array, and 1st address past the end
    58 #define ELEMENTS(A) (sizeof(A)/sizeof(A[0]))
    59 #define LIMIT(A) (A + ELEMENTS(A))
    60 
    61 // Our own comms object with synchronous writes
    62 class RComm : public RBusDevComm
    63 	{
    64 public:
    65 	TInt WriteS(const TDesC8& aDes);
    66 	TInt WriteS(const TDesC8& aDes,TInt aLength);
    67 	// Override the read functions to flush the paging cache
    68 	inline void Read(TRequestStatus &aStatus,TDes8 &aDes)
    69 		{
    70 		FLUSH_WDP_CACHE;
    71 		RBusDevComm::Read(aStatus, aDes);
    72 		}
    73 	inline void Read(TRequestStatus &aStatus,TDes8 &aDes,TInt aLength)
    74 		{
    75 		FLUSH_WDP_CACHE;
    76 		RBusDevComm::Read(aStatus, aDes, aLength);
    77 		}
    78 	inline void ReadOneOrMore(TRequestStatus &aStatus,TDes8 &aDes)
    79 		{
    80 		FLUSH_WDP_CACHE;
    81 		RBusDevComm::ReadOneOrMore(aStatus, aDes);
    82 		}
    83 	};
    84 
    85 LOCAL_D RTest test(_L("T_SERIAL"));
    86 RComm* theSerialPorts[2];
    87 TCommCaps2 theCaps1Buf;
    88 TCommCapsV02& theCaps1=theCaps1Buf();
    89 TCommCaps2 theCaps2Buf;
    90 TCommCapsV02& theCaps2=theCaps2Buf();
    91 TInt PortA;
    92 TInt PortB;
    93 
    94 const TInt KWriteSize=250;
    95 const TInt KXonNumReads=0x10;
    96 const TInt KXonReadSize=0x400;
    97 
    98 class TSpeedAndName
    99 	{
   100 public:
   101 	TUint iMask;
   102 	TBps iSpeed;
   103 	const TText* iName;
   104 	};
   105 
   106 class TSpeedAndNameV2
   107 	{
   108 public:
   109 	TUint iMask;
   110 	TBps iSpeed;
   111 	const TText* iName;
   112 	TUint iBps;
   113 	};
   114 
   115 const TSpeedAndName KSpeeds[]=
   116 	{
   117 //	{KCapsBps50,EBps50,_S("50")},
   118 //	{KCapsBps75,EBps75,_S("75")},
   119 //	{KCapsBps110,EBps110,_S("110")},
   120 //	{KCapsBps134,EBps134,_S("134")},
   121 //	{KCapsBps150,EBps150,_S("150")},
   122 //	{KCapsBps300,EBps300,_S("300")},
   123 //	{KCapsBps600,EBps600,_S("600")},
   124 //	{KCapsBps1200,EBps1200,_S("1200")},
   125 //	{KCapsBps1800,EBps1800,_S("1800")},
   126 //	{KCapsBps2000,EBps2000,_S("2000")},
   127 //	{KCapsBps2400,EBps2400,_S("2400")},
   128 //	{KCapsBps3600,EBps3600,_S("3600")},
   129 //	{KCapsBps4800,EBps4800,_S("4800")},
   130 //	{KCapsBps7200,EBps7200,_S("7200")},
   131 	{KCapsBps9600,EBps9600,_S("9600")},
   132 	{KCapsBps19200,EBps19200,_S("19200")},
   133 //	{KCapsBps38400,EBps38400,_S("38400")},
   134 	{KCapsBps57600,EBps57600,_S("57600")},
   135 	{KCapsBps115200,EBps115200,_S("115200")},
   136 	};
   137 
   138 // These speeds are used to test break handling
   139 const TSpeedAndNameV2 KBreakSpeeds[]=
   140 	{
   141 //	{KCapsBps50,EBps50,_S("50"),50},
   142 //	{KCapsBps75,EBps75,_S("75"),75},
   143 //	{KCapsBps110,EBps110,_S("110"),110},
   144 //	{KCapsBps134,EBps134,_S("134"),134},
   145 //	{KCapsBps150,EBps150,_S("150"),150},
   146 	{KCapsBps300,EBps300,_S("300"),300},
   147 //	{KCapsBps600,EBps600,_S("600"),600},
   148 	{KCapsBps1200,EBps1200,_S("1200"),1200},
   149 //	{KCapsBps1800,EBps1800,_S("1800"),1800},
   150 //	{KCapsBps2000,EBps2000,_S("2000"),2000},
   151 //	{KCapsBps2400,EBps2400,_S("2400"),2400},
   152 //	{KCapsBps3600,EBps3600,_S("3600"),3600},
   153 	{KCapsBps4800,EBps4800,_S("4800"),4800},
   154 //	{KCapsBps7200,EBps7200,_S("7200"),7200},
   155 //	{KCapsBps9600,EBps9600,_S("9600"),9600},
   156 //	{KCapsBps19200,EBps19200,_S("19200"),19200},
   157 //	{KCapsBps38400,EBps38400,_S("38400"),38400},
   158 	{KCapsBps57600,EBps57600,_S("57600"),57600},
   159 	{KCapsBps115200,EBps115200,_S("115200"),115200},
   160 	};
   161 
   162 // Multiplying factors to give Min turnaround times in microseconds between Rx and Tx
   163 #if defined (__WINS__)
   164 const TUint KTurnaroundTimes[] =
   165 {
   166 	150,
   167 	120,
   168 	90,
   169 	60
   170 };
   171 #else
   172 const TUint KTurnaroundTimes[] =
   173 {
   174 #ifdef DRIVER_TRACE_ON
   175 	150,
   176 	120,
   177 	90,
   178 	60
   179 #else
   180 	15,
   181 	12,
   182 	9,
   183 	6
   184 #endif
   185 };
   186 #endif
   187 
   188 class TFrameAndName
   189 	{
   190 public:
   191 	TDataBits iData;
   192 	TStopBits iStop;
   193 	TParity iParity;
   194 	const TText* iName;
   195 	};
   196 
   197 const TFrameAndName KFrameTypes[]=
   198 	{
   199 	{EData8,EStop1,EParityNone,_S("8,N,1")},
   200 	{EData8,EStop1,EParityEven,_S("8,E,1")},
   201 	{EData8,EStop1,EParityOdd,_S("8,O,1")},
   202 
   203 	{EData8,EStop2,EParityNone,_S("8,N,2")},
   204 	{EData8,EStop2,EParityEven,_S("8,E,2")},
   205 	{EData8,EStop2,EParityOdd,_S("8,O,2")},
   206 
   207 	{EData7,EStop2,EParityNone,_S("7,N,2")},
   208 	{EData7,EStop2,EParityEven,_S("7,E,2")},
   209 	{EData7,EStop2,EParityOdd,_S("7,O,2")},
   210 
   211 	{EData7,EStop1,EParityNone,_S("7,N,1")},
   212 	{EData7,EStop1,EParityEven,_S("7,E,1")},
   213 	{EData7,EStop1,EParityOdd,_S("7,O,1")},
   214 
   215 //	{EData6,EStop2,EParityNone,_S("6,N,2")},
   216 //	{EData6,EStop2,EParityEven,_S("6,E,2")},
   217 //	{EData6,EStop2,EParityOdd,_S("6,O,2")},
   218 
   219 //	{EData6,EStop1,EParityNone,_S("6,N,1")},
   220 //	{EData6,EStop1,EParityEven,_S("6,E,1")},
   221 //	{EData6,EStop1,EParityOdd,_S("6,O,1")},
   222 
   223 //	{EData5,EStop1,EParityNone,_S("5,N,1")},
   224 //	{EData5,EStop1,EParityEven,_S("5,E,1")},
   225 //	{EData5,EStop1,EParityOdd,_S("5,O,1")},
   226 	};
   227 
   228 class THandShakeAndName
   229 	{
   230 public:
   231 	TUint iHandshake;
   232 	const TText* iName;
   233 	};
   234 
   235 THandShakeAndName KHandshakes[]=
   236 	{
   237 //	{KConfigObeyDSR,_S("DSR/DTR")},		// most cables don't actually support this
   238 	{KConfigObeyCTS,_S("CTS/RTS")},
   239 // 	{KConfigObeyDCD,_S("DCD")},
   240 	};
   241 
   242 enum TSerialTestFault
   243 	{
   244 	EBadArg,
   245 	};
   246 _LIT(KLddFileName, "D_LDDTURNAROUNDTIMERTEST.LDD");
   247 RLddTest1 ldd;
   248 
   249 #ifdef _DEBUG_DEVCOMM
   250 void CommDebug(RBusDevComm& aComm)
   251 	{
   252 	TCommDebugInfoPckg infopckg;
   253 	TCommDebugInfo& info = infopckg();
   254 	aComm.DebugInfo(infopckg);
   255 
   256 	test.Printf(_L("  LDD State        :    TX         RX    \r\n"));
   257 	test.Printf(_L("  Busy             : %10d %10d\r\n"), info.iTxBusy, info.iRxBusy);
   258 	test.Printf(_L("  Held             : %10d %10d\r\n"), info.iTxHeld, info.iRxHeld);
   259 	test.Printf(_L("  Length           : %10d %10d\r\n"), info.iTxLength, info.iRxLength);
   260 	test.Printf(_L("  Offset           : %10d %10d\r\n"), info.iTxOffset, info.iRxOffset);
   261 	test.Printf(_L("  Int Count        : %10d %10d\r\n"), info.iTxIntCount, info.iRxIntCount);
   262 	test.Printf(_L("  Err Count        : %10d %10d\r\n"), info.iTxErrCount, info.iRxErrCount);
   263 	test.Printf(_L("  Buf Count        : %10d %10d\r\n"), info.iTxBufCount, info.iRxBufCount);
   264 	test.Printf(_L("  Fill/Drain       : %10d %10d\r\n"), info.iFillingTxBuf, info.iFillingTxBuf);
   265 	test.Printf(_L("  XON              : %10d %10d\r\n"), info.iTxXon, info.iRxXon);
   266 	test.Printf(_L("  XOFF             : %10d %10d\r\n"), info.iTxXoff, info.iRxXoff);
   267 	test.Printf(_L("  Chars            : %10d %10d\r\n"), info.iTxChars, info.iRxChars);
   268 //	test.Printf(_L("  DFC Pending      : %10d %10d\r\n"), info.iTxDfcPend, info.iTxDfcPend);
   269 //	test.Printf(_L("  DFC Run/Count    : %10d %10d\r\n"), info.iRunningDfc, info.iDfcCount);
   270 //	test.Printf(_L("  DFC Req/Do/Drain : %10d %10d %10d\r\n"), info.iDfcReqSeq, info.iDfcHandlerSeq, info.iDoDrainSeq);
   271 	}
   272 #else
   273 void CommDebug(RBusDevComm& /*aComm*/)
   274 	{
   275 	test.Printf(_L("Debug Dump not available\r\n"));
   276 	}
   277 #endif
   278 
   279 TInt RComm::WriteS(const TDesC8& aDes)
   280 //
   281 // Syncronous write
   282 //
   283 	{
   284 
   285 	return(WriteS(aDes,aDes.Length()));
   286 	}
   287 
   288 
   289 TInt RComm::WriteS(const TDesC8& aDes,TInt aLength)
   290 //
   291 // Syncronous write
   292 //
   293 	{
   294 
   295 	TRequestStatus s;
   296 
   297 	// Force there to be paging events
   298 	FLUSH_WDP_CACHE;
   299 
   300 	//
   301 	Write(s,aDes,aLength);
   302 	User::WaitForRequest(s);
   303 	return(s.Int());
   304 	}
   305 
   306 void Panic(TSerialTestFault const& aFault)
   307 //
   308 // Panic the test code
   309 //
   310 	{
   311 	User::Panic(_L("Comm Test"),aFault);
   312 	}
   313 
   314 void StripeMem(TDes8& aBuf,TUint aStartChar,TUint anEndChar)
   315 //
   316 // Mark a buffer with repeating byte pattern
   317 //
   318 	{
   319 
   320 	__ASSERT_ALWAYS(aStartChar<=anEndChar,Panic(EBadArg));
   321 	if (aStartChar==anEndChar)
   322 		{
   323 		aBuf.Fill(aStartChar);
   324 		return;
   325 		}
   326 
   327 	TUint character=aStartChar;
   328 	for (TInt i=0;i<aBuf.Length();i++)
   329 		{
   330 		aBuf[i]=(TText8)character;
   331 		if(++character>anEndChar)
   332 			character=aStartChar;
   333 		}
   334 	}
   335 
   336 #define COLUMN_HEADER _L("                 InBuf         |         outbuf\n\r")
   337 
   338 bool CompareDescriptors(TDes8 &aLeft,TDes8 &aRight)
   339 //
   340 // Compare a couple of descriptors and dump them if they don't match
   341 //
   342 	{
   343 	TInt lLen=aLeft.Length();
   344 	TInt rLen=aRight.Length();
   345 	TInt minLen=Min(lLen,rLen);
   346 
   347 	aRight.SetLength(minLen);
   348 	aLeft.SetLength(minLen);
   349 	bool r = (aLeft.Compare(aRight)==0);
   350 	if (!r)
   351 		{
   352 		RDebug::Print(_L("Compare failed - dumping descriptors\n\r"));
   353 		TInt len=aLeft.Length();
   354 		RDebug::Print(COLUMN_HEADER);
   355 		TBuf8<0x100> buf;
   356 		for (TInt i=0;i<=len/8;i++)
   357 		{
   358 			buf.Zero();
   359 			buf.SetLength(0);
   360 			buf.AppendFormat(_L8("%4d: "),i*8);
   361 
   362 			for (TInt j=0;j<8;j++)
   363 				{
   364 				if ((i*8)+j<len)
   365 					{
   366 					TInt v=aLeft[(i*8)+j];
   367 					buf.AppendFormat(_L8("%02x "),v);
   368 					}
   369 				else
   370 					buf.AppendFormat(_L8("   "));
   371 				}
   372 			buf.AppendFormat(_L8(" | "));
   373 			for (TInt k=0;k<8;k++)
   374 				{
   375 				if ((i*8)+k>=len)
   376 					break;
   377 				TInt v=aRight[(i*8)+k];
   378 				buf.AppendFormat(_L8("%02x "),v);
   379 				}
   380 			buf.AppendFormat(_L8("\r\n"));
   381 			RDebug::RawPrint(buf);	
   382 			}
   383 		}
   384 
   385 	if (!r) {
   386 		theSerialPorts[0]->Close();
   387 		theSerialPorts[1]->Close();
   388 		aRight.SetLength(rLen);
   389 		aLeft.SetLength(lLen);
   390 	}
   391 	return r;
   392 }
   393 
   394 TInt CheckedWrite(TInt aBufSize)
   395 //
   396 // Write a buffer from one serial port to the other and vice versa.
   397 //
   398 	{
   399 	TUint8* inBuf=new TUint8[aBufSize];
   400 	test(inBuf!=NULL);
   401 	TUint8* outBuf=new TUint8[aBufSize];
   402 	test(outBuf!=NULL);
   403 	TPtr8 outDes(outBuf,aBufSize,aBufSize);
   404 	TPtr8 inDes(inBuf,aBufSize,aBufSize);
   405 
   406 	RTimer tim;
   407 	tim.CreateLocal();
   408 	TRequestStatus readStatus;
   409 	TRequestStatus timeStatus;
   410 
   411 	StripeMem(outDes,'A','Z');
   412 	inDes.FillZ();
   413 
   414 	const TInt KReadFirstPort=0;
   415 	const TInt KWriteFirstPort=1;
   416 
   417 	// Check the driver rejects an attempt to read more data than the buffer allows
   418 	theSerialPorts[KReadFirstPort]->Read(readStatus,inDes,aBufSize+1);
   419 	test(readStatus==KErrGeneral);
   420 
   421 	// Start reading for real
   422 	theSerialPorts[KReadFirstPort]->Read(readStatus,inDes);
   423 	test_Equal(KRequestPending, readStatus.Int());
   424 
   425 	// Synchronous write
   426 	TInt ret=theSerialPorts[KWriteFirstPort]->WriteS(outDes,aBufSize);
   427 	test(ret==KErrNone);
   428 
   429 	// Set a 6 second timer going
   430 	const TUint KTimeOut=12000000;
   431 	tim.After(timeStatus,KTimeOut);
   432 	test(timeStatus==KRequestPending);
   433 
   434 	// Wait for EITHER the read to complete, OR for the timer to timeout
   435 	User::WaitForRequest(readStatus,timeStatus);
   436 	if (timeStatus==KErrNone) // timer completed normally... oh dear, what happened to the read??
   437 		{
   438 		test.Printf(_L("RComm::Read() timed out!\n\r"));
   439 		theSerialPorts[KReadFirstPort]->ReadCancel();
   440 		test(EFalse);	// fail
   441 		}
   442 	else
   443 		{
   444 		tim.Cancel();
   445 		if (readStatus!=KErrNone)
   446 			test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
   447 		test(readStatus==KErrNone);
   448 		test(ret==KErrNone);
   449 		test.Printf(_L("\rRead %d of %d\n\r"),inDes.Length(),outDes.Length());
   450 		test(CompareDescriptors(outDes,inDes));
   451 		}
   452 
   453 	test.Printf(_L("\t\t\tReverse\n"));
   454 	theSerialPorts[KWriteFirstPort]->Read(readStatus,inDes,aBufSize);
   455 	theSerialPorts[KReadFirstPort]->WriteS(outDes,aBufSize);
   456 	User::WaitForRequest(readStatus);
   457 	tim.After(timeStatus,KTimeOut);
   458 	test(timeStatus==KRequestPending);
   459 	User::WaitForRequest(readStatus,timeStatus);
   460 	if (timeStatus==KErrNone)
   461 		{
   462 		test.Printf(_L("Timed Out!\n\r"));
   463 		theSerialPorts[KWriteFirstPort]->ReadCancel();
   464 		test(EFalse);	// fail
   465 		}
   466 	else
   467 		{
   468 		tim.Cancel();
   469 		if (readStatus!=KErrNone)
   470 				test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
   471 		test(readStatus==KErrNone);
   472 		test(ret==KErrNone);
   473 		test.Printf(_L("\rRead %d of %d\n\r"),inDes.Length(),outDes.Length());
   474 		outDes.SetLength(inDes.Length());
   475 		test(CompareDescriptors(outDes,inDes));
   476 		}
   477 
   478 	tim.Close();
   479 	delete [] inBuf;
   480 	delete [] outBuf;
   481 
   482 	return inDes.Length();
   483 	}
   484 
   485 TUint CheckZeroTurnaround(TInt aBufSize, TUint aDirection)
   486 //
   487 // Checks that when a Turnaround of 0ms was selected the write takes place immediately
   488 // aBufSize is selected such as it takes only slightly less than User timer granularity
   489 // at the Baud rate selected to transmit that buffer.
   490 // Checks that it takes less than a User side timer tick to complete a Write request
   491 // at the selected Baud rate. Therefore proving the write is not being delayed in the driver
   492 //
   493 	{
   494 	TUint8* inBuf=new TUint8[aBufSize];
   495 	test(inBuf!=NULL);
   496 	TUint8* outBuf=new TUint8[aBufSize];
   497 	test(outBuf!=NULL);
   498 	TPtr8 outDes(outBuf,aBufSize,aBufSize);
   499 	TPtr8 inDes(inBuf,aBufSize,aBufSize);
   500 	TInt numberRead = 0;
   501 
   502 	TTimeIntervalMicroSeconds32 aTimeOut=0;
   503 	UserHal::TickPeriod(aTimeOut);
   504 
   505 	RTimer timeoutTimer;
   506 	timeoutTimer.CreateLocal();
   507 	TRequestStatus readStatus;
   508 	TRequestStatus writeStatus;
   509 	TRequestStatus timeStatus;
   510 
   511 	StripeMem(outDes,'A','Z');
   512 	inDes.FillZ();
   513 
   514 	const TUint port_A = aDirection?1:0;
   515 	const TUint port_B = 1 - port_A;
   516 
   517 	// queue a read on port_A
   518 	test.Printf(_L("\r\nRead %d \r\n"), port_A);
   519 	theSerialPorts[port_A]->Read(readStatus,inDes);
   520 	test(readStatus==KRequestPending);
   521 
   522 	// write on port_B to complete read
   523 	theSerialPorts[port_B]->SetMinTurnaroundTime(0);
   524 	theSerialPorts[port_B]->Write(writeStatus,outDes,aBufSize);
   525 	test(writeStatus==KRequestPending || writeStatus==KErrNone );
   526 
   527 	// start the local turnaround timer
   528 	timeoutTimer.After(timeStatus, (20*aTimeOut.Int()));		// give it a 20% margin
   529 	test(timeStatus==KRequestPending);
   530 
   531 	User::WaitForRequest(readStatus, timeStatus);
   532 
   533 	if(timeStatus == KErrNone)
   534 		{
   535 		// if timeout first -> BAD
   536 		test.Printf(_L("Timed out!\r\n"));
   537 		theSerialPorts[port_A]->ReadCancel();
   538 		test(EFalse);	// fail
   539 		}
   540 	else
   541 		{
   542 		// else read was first -> GOOD
   543 		timeoutTimer.Cancel();
   544 
   545 		if (readStatus!=KErrNone)
   546 				test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
   547 		test(readStatus==KErrNone);
   548 		test(writeStatus==KErrNone);
   549 		test.Printf(_L("Good, read OK and took less than timeout\r\n"));
   550 		test(CompareDescriptors(outDes,inDes));
   551 		numberRead = inDes.Length();
   552 		}
   553 	timeoutTimer.Close();
   554 	delete inBuf;
   555 	delete outBuf;
   556 
   557 	return numberRead;
   558 	}
   559 
   560 
   561 TUint TimedCheckedWrite(TInt aBufSize, TUint aTurnaround, TUint aDirection)
   562 //
   563 // Checks that Write requests are delayed if a Turnaround != 0 is selected.
   564 // aTurnarund is chosen to be significantly greater than the time it takes to transmit
   565 // a buffer of aBufSize at the Baud rate.
   566 // Checks that for a given Turnaround time it always takes > that time to transmit
   567 // a buffer of aBufSize.
   568 // aDirection specifies the direction of transmission.
   569 //
   570 	{
   571 	TUint8* inBuf=new TUint8[aBufSize];
   572 	test(inBuf!=NULL);
   573 	TUint8* outBuf=new TUint8[aBufSize];
   574 	test(outBuf!=NULL);
   575 	TPtr8 outDes(outBuf,aBufSize,aBufSize);
   576 	TPtr8 inDes(inBuf,aBufSize,aBufSize);
   577 	TInt numberRead = 0;
   578 
   579 	TTimeIntervalMicroSeconds32 p=0;
   580 	UserHal::TickPeriod(p);
   581 	TInt tPeriod = p.Int();
   582 
   583 	const TUint KTimeOut = 1500000;		// 1500 milliseconds
   584 	RTimer timeoutTimer;
   585 	timeoutTimer.CreateLocal();
   586 	TRequestStatus readStatus;
   587 	TRequestStatus writeStatus;
   588 	TRequestStatus timeStatus;
   589 
   590 	RTimer turnaroundTimer;
   591 	turnaroundTimer.CreateLocal();
   592 	TRequestStatus turnaroundTimerStatus;
   593 
   594 	StripeMem(outDes,'A','Z');
   595 	inDes.FillZ();
   596 
   597 	const TUint port_A = aDirection?1:0;
   598 	const TUint port_B = 1 - port_A;
   599 
   600 	// set turnaround on port_A
   601 	TInt r = theSerialPorts[port_A]->SetMinTurnaroundTime(aTurnaround+tPeriod);
   602 	test(r== KErrNone);
   603 	r = theSerialPorts[port_B]->SetMinTurnaroundTime(0);
   604 	test(r== KErrNone);
   605 
   606 	// queue a short read on port_A
   607 	test.Printf(_L("\r\nRead %d to set turnaround %d\r\n"), port_A, aTurnaround+tPeriod);
   608 	theSerialPorts[port_A]->Read(readStatus,inDes);
   609 	test(readStatus==KRequestPending);
   610 
   611 	// start the local turnaround timer
   612 	turnaroundTimer.After(turnaroundTimerStatus, aTurnaround);
   613 	test(turnaroundTimerStatus==KRequestPending);
   614 
   615 	// write on port_B to complete read and start the driver's turnaround timer on A
   616 	theSerialPorts[port_B]->Write(writeStatus,outDes,aBufSize);
   617 	test((writeStatus==KRequestPending)||(writeStatus==KErrNone));		// may complete before coming back here as buffer size's small
   618 
   619 	User::WaitForRequest(readStatus);
   620 	test(readStatus==KErrNone);
   621 	test(writeStatus==KErrNone);
   622 	test(CompareDescriptors(outDes,inDes));
   623 	inDes.FillZ();
   624 
   625 	// queue a short read on port_B
   626 	theSerialPorts[port_B]->Read(readStatus, inDes);
   627 	test(readStatus==KRequestPending);
   628 
   629 	// write on port_A
   630 	theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
   631 	test(writeStatus==KRequestPending);
   632 
   633 	// wait on both the read on port_B and the local turnaround timer
   634 	User::WaitForRequest(readStatus, turnaroundTimerStatus);
   635 
   636 	if(turnaroundTimerStatus == KErrNone)
   637 		{
   638 		// if local turnaround timeout first -> GOOD
   639 		// start big timeout and wait on either timeout or read on port_B
   640 		timeoutTimer.After(timeStatus, KTimeOut);
   641 		test(timeStatus==KRequestPending);
   642 
   643 		User::WaitForRequest(readStatus, timeStatus);
   644 		if(timeStatus == KErrNone)
   645 			{
   646 			// if timeout first -> BAD
   647 			test.Printf(_L("Timed out!\r\n"));
   648 
   649 			theSerialPorts[port_B]->ReadCancel();
   650 			test(EFalse);	// fail
   651 			}
   652 		else
   653 			{
   654 			// else read was first -> GOOD
   655 			timeoutTimer.Cancel();
   656 
   657 			if (readStatus!=KErrNone)
   658 					test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
   659 			test(readStatus==KErrNone);
   660 			test(writeStatus==KErrNone);
   661 			test.Printf(_L("Good, read OK, write took longer than turnaround\r\n"));
   662 			test(CompareDescriptors(outDes,inDes));
   663 			numberRead = inDes.Length();
   664 			}
   665 		}
   666 	else if(readStatus == KErrNone)
   667 		{
   668 		TInt timerStatus = turnaroundTimerStatus.Int();
   669 		// else read was first -> BAD
   670 		turnaroundTimer.Cancel();
   671 		test.Printf(_L("read completed before turnaround\r\n"));
   672 		test.Printf(_L("turnaroundTImer status  %d ms!\r\n"),timerStatus);
   673 		test(EFalse);	// fail
   674 		}
   675 
   676 	timeoutTimer.Close();
   677 	turnaroundTimer.Close();
   678 	delete inBuf;
   679 	delete outBuf;
   680 
   681 	return numberRead;
   682 	}
   683 
   684 // Checks that setting the turnaround first time before any read or write, will start the
   685 // turnaround timer. It is make sure that first write will be delayed atleast min turnaround
   686 // time.
   687 void TestFirstDelayedWrite(TInt aBufSize, TUint aTurnaround, TUint aDirection)
   688 	{
   689 	test.Printf(_L("Loading logical device for getting kernel timer tick & count\n"));
   690 	TInt r=User::LoadLogicalDevice(KLddFileName);
   691 	test(r == KErrNone || r == KErrAlreadyExists);
   692 
   693 	test.Printf(_L("Opening of logical device\n"));
   694 	r = ldd.Open();
   695 	test(r == KErrNone || r == KErrAlreadyExists);
   696 
   697 
   698 	// Create input and an output buffers
   699 	TUint8* inBuf=new TUint8[aBufSize];
   700 	test(inBuf!=NULL);
   701 	TUint8* outBuf=new TUint8[aBufSize];
   702 	test(outBuf!=NULL);
   703 
   704 	// Fill the output buffer with stuff and empty the input buffer
   705 	TPtr8 outDes(outBuf,aBufSize,aBufSize);
   706 	TPtr8 inDes(inBuf,aBufSize,aBufSize);
   707 	StripeMem(outDes,'A','Z');
   708 	inDes.FillZ();
   709 	
   710 
   711 	// Configure both ports to 9600bps.
   712     TCommConfig cBuf1;
   713 	TCommConfigV01& c1=cBuf1();
   714 	theSerialPorts[0]->Config(cBuf1);
   715 	TCommConfig cBuf2;
   716 	TCommConfigV01& c2=cBuf2();
   717 	theSerialPorts[0]->Config(cBuf2);
   718 	c1.iHandshake=0;
   719 	c2.iHandshake=0;
   720 	c2.iFifo=EFifoDisable;
   721 	c2.iDataBits=c1.iDataBits=EData8;
   722 	c2.iStopBits=c1.iStopBits=EStop1;
   723 	c2.iParity=c1.iParity=EParityNone;
   724 	c2.iRate=c1.iRate=EBps9600;
   725     r = theSerialPorts[0]->SetConfig(cBuf1);
   726     test_Equal(KErrNone, r);
   727 	r = theSerialPorts[1]->SetConfig(cBuf2);
   728 	test(r == KErrNone);
   729 
   730 	// Create a timer
   731 	RTimer timeoutTimer;
   732 	timeoutTimer.CreateLocal();
   733 	TRequestStatus readStatus = 0xbaadf00d;
   734 	TRequestStatus writeStatus = 0xbaadf00d;
   735 	//TRequestStatus timeStatus = 0xbaadf00d;
   736 
   737 	const TUint port_A = aDirection?1:0;
   738 	const TUint port_B = 1 - port_A;
   739 
   740 	TUint time1 = 0, time2 = 0, time3 = 0;
   741 	// set turnaround on port_A
   742 	r = theSerialPorts[port_A]->SetMinTurnaroundTime(aTurnaround);
   743 	test(r== KErrNone);
   744 
   745 	//Capture the turnaround time
   746 	ldd.Test_getTimerCount(time1);
   747 
   748 	// set turnaround on port_B
   749 	r = theSerialPorts[port_B]->SetMinTurnaroundTime(0);
   750 	test(r== KErrNone);
   751 
   752 	// queue a short read on port_B
   753 	theSerialPorts[port_B]->Read(readStatus, inDes);
   754 	/* BOGUS TEST: Zero-length reads complete immediately.
   755 	test_Equal(KRequestPending, readStatus.Int());
   756 	*/
   757 
   758 	// write on port_A
   759 	theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
   760 	/* BOGUS TEST
   761 	test(writeStatus==KRequestPending);
   762 	*/
   763 
   764 	/* BOGUS TEST
   765 	The turnaround timer exists to introduce small delays between SUCCESSIVE reads & writes, 
   766 	so as not to flummox IrDA transceivers which are slow in changing between write & read 
   767 	modes. Setting a timer value does not have an immediate effect, it will
   768 	apply *after* the next read/write.
   769 
   770 	// start a local timeout with aTurnaround/3 and wait on it
   771 	timeoutTimer.After(timeStatus, aTurnaround/3);
   772 	test(timeStatus==KRequestPending);
   773 	User::WaitForRequest(timeStatus);
   774 	test(timeStatus==KErrNone);
   775 
   776 	// check that read on port_B has not completed yet (write on port_A has been delayed in the driver)
   777 	test_Equal(KRequestPending, readStatus.Int());
   778 	*/
   779 
   780 	// wait for write to complete
   781 	User::WaitForRequest(writeStatus);
   782 	if(writeStatus == KErrNone)
   783 		{
   784 		//record the time of write complete
   785 		ldd.Test_getTimerCount(time2);
   786 		}
   787 
   788 	//Wait for read to complete
   789 	User::WaitForRequest(readStatus);
   790 	test(readStatus==KErrNone);
   791 
   792 	//Covert turnaround time to timer ticks
   793 	time3 = aTurnaround / 1000;
   794 	ldd.Test_getTimerTicks(time3);
   795 
   796 	test.Printf(_L("Time1 %d\n"), time1);
   797 	test.Printf(_L("Time2 %d\n"), time2);
   798 	test.Printf(_L("Time3 %d\n"), time3);
   799 	//Write takes apporximately 250 ticks to write.
   800 	time2 = (time2 - time1); //Includes turnaround time + write time
   801 	time1 = time3 > time2 ? time3 - time2 : time2 - time3;
   802 	test.Printf(_L("Time differece %d\n"), time1);
   803 	//test(time1 == 0 || time1 == 1); <-- Apparently unreasonable on SMP hardware
   804 
   805 	timeoutTimer.Close();
   806 	test.Printf(_L("Closing the channel\n"));
   807 	ldd.Close();
   808 
   809 	test.Printf(_L("Freeing logical device\n"));
   810 	r = User::FreeLogicalDevice(KLddFileName);;
   811 	test(r==KErrNone);
   812 
   813 	delete inBuf;
   814 	delete outBuf;
   815 
   816 	}
   817 
   818 
   819 
   820 
   821 TUint ChangeTurnaroundTimeInDelayedWrite(TInt aBufSize, TUint aTurnaround, TUint aNewTurnaround, TUint aDirection)
   822 //
   823 // Checks that a delayed write will go based on the new timeout value if the Turnaround time is changed
   824 // when a write is being delayed in the driver
   825 // aBufSize is such that transmission of a buffer of that size at the baud rate selected << aTurnaround
   826 // Check that a Write is being delayed by a previous Read and that changing the turnaround will adjust
   827 // the turnaround timer based on the new value and write will happend after minturnaround time has elapsed
   828 //
   829 	{
   830 	test.Printf(_L("Loading logical device for getting kernel timer tick & count\n"));
   831 	TInt r=User::LoadLogicalDevice(KLddFileName);
   832 	test(r == KErrNone || r == KErrAlreadyExists);
   833 
   834 	test.Printf(_L("Opening of logical device\n"));
   835 	r = ldd.Open();
   836 	test(r == KErrNone || r == KErrAlreadyExists);
   837 
   838 	TUint8* inBuf=new TUint8[aBufSize];
   839 	test(inBuf!=NULL);
   840 	TUint8* outBuf=new TUint8[aBufSize];
   841 	test(outBuf!=NULL);
   842 	TPtr8 outDes(outBuf,aBufSize,aBufSize);
   843 	TPtr8 inDes(inBuf,aBufSize,aBufSize);
   844 	TInt numberRead = 0;
   845 
   846 	StripeMem(outDes,'A','Z');
   847 	inDes.FillZ();
   848 
   849 	RTimer timeoutTimer;
   850 	timeoutTimer.CreateLocal();
   851 	TRequestStatus readStatus;
   852 	TRequestStatus writeStatus;
   853 	TRequestStatus timeStatus;
   854 
   855 	const TUint port_A = aDirection?1:0;
   856 	const TUint port_B = 1 - port_A;
   857 
   858 	// set turnaround on port_A
   859 	r = theSerialPorts[port_A]->SetMinTurnaroundTime(aTurnaround);
   860 	test(r== KErrNone);
   861 	// set turnaround on port_B
   862 	r = theSerialPorts[port_B]->SetMinTurnaroundTime(0);
   863 	test(r== KErrNone);
   864 
   865 	// Issue a zero length read on port_A
   866 	theSerialPorts[port_A]->Read(readStatus,inDes,0);
   867 	User::WaitForRequest(readStatus);
   868 	test(readStatus==KErrNone);
   869 	//Record the start of turnaround time on port_A
   870 	TUint time1 = 0, time2 = 0, time3 = 0;
   871 	ldd.Test_getTimerCount(time1);
   872 
   873 	// queue a short read on port_B
   874 	theSerialPorts[port_B]->Read(readStatus, inDes);
   875 	test(readStatus==KRequestPending);
   876 
   877 	// write on port_A
   878 	theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
   879 	test(writeStatus==KRequestPending);
   880 
   881 	// start a local timeout with aTurnaround/3 and wait on it
   882 	timeoutTimer.After(timeStatus, aTurnaround/3);
   883 	test(timeStatus==KRequestPending);
   884 	User::WaitForRequest(timeStatus);
   885 	test(timeStatus==KErrNone);
   886 
   887 	// check that read on port_B has not completed yet (write on port_A has been delayed in the driver)
   888 #ifndef WDP_ENABLED // lots of paging screws up timing assumptions
   889 	test(readStatus==KRequestPending);
   890 	test(writeStatus==KRequestPending);
   891 #endif
   892 
   893 	// change turnaround on port_A (should adjust turnaround time accordingly)
   894 	r = theSerialPorts[port_A]->SetMinTurnaroundTime(aNewTurnaround);
   895 	test(r==KErrNone);
   896 
   897 	//Check read on port_B & write on port_A is still delayed.
   898 #if !defined(DRIVER_TRACE_ON) && !defined(WDP_ENABLED)
   899 	test(readStatus==KRequestPending);
   900 	test(writeStatus==KRequestPending);
   901 #endif
   902 	// wait for write to complete
   903 	User::WaitForRequest(writeStatus);
   904 	if(writeStatus == KErrNone)
   905 	{
   906 		//record the time of write complete
   907 		ldd.Test_getTimerCount(time2);
   908 	}
   909 
   910 	//Wait for read to complete
   911 	User::WaitForRequest(readStatus);
   912 	test(readStatus==KErrNone);
   913 
   914 	//Calculate the turnaround time, write should be delayed.
   915 	time3 = aNewTurnaround/1000;
   916 	//Convert to timer ticks
   917 	ldd.Test_getTimerTicks(time3);
   918 	test.Printf(_L("aTurnaround = %d, aNewTurnaround = %d\n"), aTurnaround, aNewTurnaround);
   919 	test.Printf(_L("Time1 = %d\n"), time1);
   920 	test.Printf(_L("Time2 = %d\n"), time2);
   921 	test.Printf(_L("Time3 = %d\n"), time3);
   922 	time1 = time2 - time1;
   923 	time1 = time3 > time1 ? (time3 - time1) : (time1 - time3);
   924 	test.Printf(_L("Time difference %d\n"), time1);
   925 #if !defined(DRIVER_TRACE_ON) && !defined(WDP_ENABLED)
   926 //	test((time1 == 1) || (time1 == 0));
   927 #endif
   928 	test.Printf(_L("Write delayed for requested time\r\n"));
   929 	test(CompareDescriptors(outDes,inDes));
   930 	numberRead = inDes.Length();
   931 
   932 	timeoutTimer.Close();
   933 	test.Printf(_L("Closing the channel\n"));
   934 	ldd.Close();
   935 
   936 	test.Printf(_L("Freeing logical device\n"));
   937 	r = User::FreeLogicalDevice(KLddFileName);;
   938 	test(r==KErrNone);
   939 
   940 	delete inBuf;
   941 	delete outBuf;
   942 
   943 	return numberRead;
   944 	}
   945 
   946 
   947 TUint StopInDelayedWrite(TInt aBufSize, TUint aTurnaround, TUint aDirection)
   948 //
   949 // Checks that when a write is being delayed and then is cancelled the driver's turnaround timer continues
   950 // ticking and if another write is queued it will be delayed by the remaining time
   951 // aBufSize is such that transmission of a buffer of that size at the baud rate selected << aTurnaround
   952 // Check that a Write is being delayed by a previous Read and that changing the Turnaround will make it
   953 // go ahead immediately
   954 //
   955 	{
   956 	TUint8* inBuf=new TUint8[aBufSize];
   957 	test(inBuf!=NULL);
   958 	TUint8* outBuf=new TUint8[aBufSize];
   959 	test(outBuf!=NULL);
   960 	TPtr8 outDes(outBuf,aBufSize,aBufSize);
   961 	TPtr8 inDes(inBuf,aBufSize,aBufSize);
   962 	TInt numberRead = 0;
   963 
   964 	TTimeIntervalMicroSeconds32 p=0;
   965 	UserHal::TickPeriod(p);
   966 	TInt tPeriod = p.Int();
   967 
   968 	const TUint KTimeOut = 1500000;		// 150 milliseconds
   969 	RTimer timeoutTimer;
   970 	timeoutTimer.CreateLocal();
   971 	TRequestStatus readStatus;
   972 	TRequestStatus writeStatus;
   973 	TRequestStatus timeStatus;
   974 
   975 	RTimer turnaroundTimer;
   976 	turnaroundTimer.CreateLocal();
   977 	TRequestStatus turnaroundTimerStatus;
   978 
   979 	StripeMem(outDes,'A','Z');
   980 	inDes.FillZ();
   981 
   982 	const TUint port_A = aDirection?1:0;
   983 	const TUint port_B = 1 - port_A;
   984 
   985 	// set turnaround on port_A
   986 	TInt r = theSerialPorts[port_A]->SetMinTurnaroundTime(aTurnaround+tPeriod);
   987 	test(r== KErrNone);
   988 	r = theSerialPorts[port_B]->SetMinTurnaroundTime(0);
   989 	test(r== KErrNone);
   990 
   991 
   992 	// queue a zero length read to start the turnaround on port_A
   993 	test.Printf(_L("\r\nRead Zero Length on %d to start turnaround %d\r\n"), port_A, aTurnaround);
   994 	test.Printf(_L("\r\nUsing %d character buffers\r\n"),aBufSize);
   995 
   996 	theSerialPorts[port_A]->Read(readStatus,inDes,0);
   997 	User::WaitForRequest(readStatus);
   998 	test(readStatus==KErrNone);
   999 
  1000 	// start the local turnaround timer
  1001 	turnaroundTimer.After(turnaroundTimerStatus, aTurnaround);
  1002 	test(turnaroundTimerStatus==KRequestPending);
  1003 
  1004 	// queue a short read on port_B
  1005 	theSerialPorts[port_B]->Read(readStatus, inDes);
  1006 	test(readStatus==KRequestPending);
  1007 
  1008 	// write on port_A
  1009 	theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
  1010 	test(writeStatus==KRequestPending);
  1011 
  1012 	// start a local timeout with aTurnaround/3 and wait on it
  1013 	timeoutTimer.After(timeStatus, aTurnaround/3);
  1014 	test(timeStatus==KRequestPending);
  1015 	User::WaitForRequest(timeStatus);
  1016 	test(timeStatus==KErrNone);
  1017 
  1018 	// check that read on port_B has not completed yet (write on port_A has been delayed in the driver)
  1019 	test(readStatus==KRequestPending);
  1020 
  1021 	// cancel write on port_A
  1022 	theSerialPorts[port_A]->WriteCancel();
  1023 	test(writeStatus==KErrCancel);
  1024 
  1025 	// ...and restart it again
  1026 	theSerialPorts[port_A]->Write(writeStatus,outDes,aBufSize);
  1027 #ifndef DRIVER_TRACE_ON
  1028 	test(writeStatus==KRequestPending);
  1029 #endif
  1030 
  1031 	// wait on both the read on port_B and the local turnaround timer
  1032 	User::WaitForRequest(readStatus, turnaroundTimerStatus);
  1033 
  1034 	// We are expecting this to have gone off by now...
  1035 	if(turnaroundTimerStatus == KErrNone) // this local timer is LESS than the driver turnaround
  1036 		{
  1037 		// if local turnaround timeout first -> GOOD
  1038 		// start big timeout and wait on either timeout or read on port_B
  1039 		timeoutTimer.After(timeStatus, KTimeOut);
  1040 		test(timeStatus==KRequestPending);
  1041 
  1042 		User::WaitForRequest(readStatus, timeStatus);
  1043 		if(timeStatus == KErrNone)
  1044 			{
  1045 			// if timeout first -> BAD
  1046 			test.Printf(_L("Timed out!\r\n"));
  1047 
  1048 			theSerialPorts[port_B]->ReadCancel();
  1049 			test(EFalse);	// fail
  1050 			}
  1051 		else
  1052 			{
  1053 			// else read was first -> GOOD
  1054 			timeoutTimer.Cancel();
  1055 
  1056 			if (readStatus!=KErrNone)
  1057 					test.Printf(_L("Read Failed! (%d) - should have completed (on delayed write data)\n\r"),readStatus.Int());
  1058 			test(readStatus==KErrNone);
  1059 			test(writeStatus==KErrNone);
  1060 			test.Printf(_L("OK, write later than turnaround\r\n"));
  1061 			test(CompareDescriptors(outDes,inDes));
  1062 			numberRead = inDes.Length();
  1063 			}
  1064 		}
  1065 	// failed here => second write has gone off faster than expected...
  1066 	else if(readStatus == KErrNone)
  1067 		{
  1068 		// else read was first -> BAD
  1069 		TInt timerStatus = turnaroundTimerStatus.Int();
  1070 		turnaroundTimer.Cancel();
  1071 		test.Printf(_L("read completed before turnaround\r\n"));
  1072 		test.Printf(_L("Turnaround timer status = %d\r\n"),timerStatus);
  1073 		test(EFalse);	// fail
  1074 		}
  1075 
  1076 	timeoutTimer.Close();
  1077 	turnaroundTimer.Close();
  1078 	delete inBuf;
  1079 	delete outBuf;
  1080 
  1081 	return numberRead;
  1082 	}
  1083 
  1084 void turnaroundTestReadWrite()
  1085 //
  1086 // Read and write at various speeds, with various turnarounds
  1087 // Check that the data received data matches sent data
  1088 	{
  1089 	// Open both serial ports
  1090 	TInt r=theSerialPorts[0]->Open(PortA);
  1091 	test(r==KErrNone);
  1092 	r=theSerialPorts[0]->QueryReceiveBuffer();
  1093 	test(r==0);
  1094 	r=theSerialPorts[1]->Open(PortB);
  1095 	test(r==KErrNone);
  1096 	r=theSerialPorts[1]->QueryReceiveBuffer();
  1097 	test(r==0);
  1098 
  1099 	// Perform the read/write test at each baudrate for 8N1, no handshaking
  1100 	TCommConfig cBuf1;
  1101 	TCommConfigV01& c1=cBuf1();
  1102 	theSerialPorts[0]->Config(cBuf1);
  1103 	TCommConfig cBuf2;
  1104 	TCommConfigV01& c2=cBuf2();
  1105 	theSerialPorts[0]->Config(cBuf2);
  1106 	c1.iHandshake=0;
  1107 	c2.iHandshake=0;
  1108 	c2.iFifo=EFifoDisable;
  1109 
  1110 	c2.iDataBits=c1.iDataBits=EData8;
  1111 	c2.iStopBits=c1.iStopBits=EStop1;
  1112 	c2.iParity=c1.iParity=EParityNone;
  1113 	c2.iRate=c1.iRate=EBps9600;
  1114 
  1115 	TBuf<0x40> msg;
  1116 
  1117 	test.Start(_L("Read/write test with default turnaround and at 9600 Bps"));
  1118 
  1119 	TTimeIntervalMicroSeconds32 p=0;
  1120 	UserHal::TickPeriod(p);
  1121 	TInt tPeriod = p.Int();
  1122 	test.Printf(_L("Tick period %d\r\n"), tPeriod);
  1123 
  1124 	TUint aBufLength = 96*p.Int()/10000;
  1125 	test.Printf(_L("Need to transmit %d chars at 9600 Bps\r\n"), aBufLength); // let's try with 10*tick period (approx)
  1126 
  1127 	theSerialPorts[0]->SetConfig(cBuf1);
  1128 	theSerialPorts[1]->SetConfig(cBuf2);
  1129 
  1130 	// These work fine
  1131 	test(CheckZeroTurnaround(aBufLength, 0)==aBufLength);
  1132 	test(CheckZeroTurnaround(aBufLength, 1)==aBufLength);
  1133 
  1134 	test.Next(_L("Read/write test at various speeds and min turnarounds"));
  1135 #if defined (__WINS__)
  1136 	const TUint KShortBufferSize=100;
  1137 #else
  1138 	const TUint KShortBufferSize=10;
  1139 #endif
  1140 	TUint direction=0;
  1141 	for(TUint i = 0; i < ELEMENTS(KSpeeds); ++i)
  1142 		{
  1143 		TInt turnaround;
  1144 		turnaround = KTurnaroundTimes[i]*p.Int();
  1145 
  1146 		if (theCaps1.iRate&KSpeeds[i].iMask && theCaps2.iRate&KSpeeds[i].iMask)
  1147 			{
  1148 			msg.Format(_L("\r\nRead/write @ %s Bps with %d millisec turnaround\r\n"), KSpeeds[i].iName, turnaround/1000);
  1149 			test.Next(msg);
  1150 
  1151 			c1.iRate=KSpeeds[i].iSpeed;
  1152 			TInt r=theSerialPorts[0]->SetConfig(cBuf1);
  1153 			test(r==KErrNone);
  1154 			c2.iRate=KSpeeds[i].iSpeed;
  1155 			r=theSerialPorts[1]->SetConfig(cBuf2);
  1156 			test(r==KErrNone);
  1157 
  1158 			test.Printf(_L("Do TimedCheckedWrite\r\n"));
  1159 			test(TimedCheckedWrite(KShortBufferSize, turnaround, direction)==KShortBufferSize);
  1160 			}
  1161 		else
  1162 			{
  1163 			msg.Format(_L("%s Bps not supported\r\n"),KSpeeds[i].iName);
  1164 			test.Next(msg);
  1165 			}
  1166 
  1167 		direction=1-direction;
  1168 
  1169 		msg.Format(_L("\r\nRead turnaround time back\r\n"));
  1170 			test.Next(msg);
  1171 
  1172 		TInt n = theSerialPorts[0]->MinTurnaroundTime();
  1173 		test(n==turnaround+tPeriod);
  1174 
  1175 		msg.Format(_L("Value returned was %d\r\n"), n/1000);
  1176 		test.Next(msg);
  1177 
  1178 		test.Printf(_L("Decrease turnaroundtime during delayed write\n"));
  1179 		test(ChangeTurnaroundTimeInDelayedWrite(KShortBufferSize, turnaround, turnaround - 10000, direction)==KShortBufferSize);
  1180 
  1181 		test.Printf(_L("Increase turnaroundtime during delayed write\n"));
  1182 		test(ChangeTurnaroundTimeInDelayedWrite(KShortBufferSize, turnaround, turnaround + 30000 ,direction)==KShortBufferSize);
  1183 
  1184 		direction=1-direction;
  1185 
  1186 		test.Printf(_L("\r\nDo StopInDelayedWrite @ %s Bps\r\n"), KSpeeds[i].iName);
  1187 		test(StopInDelayedWrite(KShortBufferSize, turnaround, direction)==KShortBufferSize);
  1188 		}
  1189 
  1190 	// return defaults for following tests
  1191 
  1192 	msg.Format(_L("\r\nSet default turnaround (0) on both ports \r\n"));
  1193 	test.Next(msg);
  1194 
  1195 	test(theSerialPorts[0]->SetMinTurnaroundTime(0)==KErrNone);
  1196 	test(theSerialPorts[1]->SetMinTurnaroundTime(0)==KErrNone);
  1197 
  1198 	theSerialPorts[0]->Close();
  1199 	theSerialPorts[1]->Close();
  1200 
  1201 	msg.Format(_L("\r\n... End of turnaround tests ...\r\n"));
  1202 	test.Next(msg);
  1203 
  1204 	test.End();
  1205 	}
  1206 
  1207 void testReadWrite()
  1208 //
  1209 // Read and write at various speeds
  1210 	{
  1211 	test.Start(_L("Testing read and write"));
  1212 
  1213 	TInt r=theSerialPorts[0]->Open(PortA);
  1214 	test(r==KErrNone);
  1215 	r=theSerialPorts[0]->QueryReceiveBuffer();
  1216 	test(r==0);
  1217 	r=theSerialPorts[1]->Open(PortB);
  1218 	test(r==KErrNone);
  1219 	r=theSerialPorts[1]->QueryReceiveBuffer();
  1220 	test(r==0);
  1221 
  1222 	TCommConfig cBuf1;
  1223 	TCommConfigV01& c1=cBuf1();
  1224 	theSerialPorts[0]->Config(cBuf1);
  1225 	TCommConfig cBuf2;
  1226 	TCommConfigV01& c2=cBuf2();
  1227 	theSerialPorts[0]->Config(cBuf2);
  1228 	c1.iHandshake=0;
  1229 	c2.iHandshake=0;
  1230 	c2.iFifo=EFifoDisable;
  1231 
  1232 	c2.iDataBits=c1.iDataBits=EData8;
  1233 	c2.iStopBits=c1.iStopBits=EStop1;
  1234 	c2.iParity=c1.iParity=EParityNone;
  1235 	c2.iRate=c1.iRate=EBps9600;
  1236 
  1237 	TBuf<0x40> mess;
  1238 	test.Printf(_L("Delayed first write\n"));
  1239     TestFirstDelayedWrite(0, 2343750, 1);
  1240 
  1241 	TInt numTests=sizeof(KSpeeds)/sizeof(TSpeedAndName);
  1242 	for (TInt i=0;i<numTests;i++)
  1243 		{
  1244 		if (theCaps1.iRate&KSpeeds[i].iMask && theCaps2.iRate&KSpeeds[i].iMask)
  1245 			{
  1246 			mess.Format(_L("read/write @ %s Bps"),KSpeeds[i].iName);
  1247 			test.Next(mess);
  1248 			c1.iRate=KSpeeds[i].iSpeed;
  1249 			TInt r=theSerialPorts[0]->SetConfig(cBuf1);
  1250 			test(r==KErrNone);
  1251 			c2.iRate=KSpeeds[i].iSpeed;
  1252 			r=theSerialPorts[1]->SetConfig(cBuf2);
  1253 			test(r==KErrNone);
  1254 			test.Printf(_L("DoCheckedWrite\r\n"));
  1255 			test(CheckedWrite(KWriteSize)==KWriteSize);
  1256 			}
  1257 		else
  1258 			{
  1259 			mess.Format(_L("%s Bps not supported"),KSpeeds[i].iName);
  1260 			test.Next(mess);
  1261 			}
  1262 		}
  1263 
  1264 	theSerialPorts[0]->Close();
  1265 	theSerialPorts[1]->Close();
  1266 
  1267 	test.End();
  1268 	}
  1269 
  1270 void testTiming()
  1271 //
  1272 // Read and write at various speeds
  1273 	{
  1274 
  1275 	test.Start(_L("Testing read and write speed"));
  1276 	const TInt KSamples=10;
  1277 	const TInt KNumWrites=100;
  1278 	const TInt KBufSize=2000;
  1279 	test.Printf(_L("%d sets of %d by %d characters @ 19200\n\r"),KSamples,KNumWrites,KBufSize);
  1280 
  1281 	TCommConfig cBuf1;
  1282 	TCommConfigV01& c1=cBuf1();
  1283 	theSerialPorts[0]->Config(cBuf1);
  1284 	TCommConfig cBuf2;
  1285 	TCommConfigV01& c2=cBuf2();
  1286 	theSerialPorts[0]->Config(cBuf2);
  1287 	c1.iHandshake=0;
  1288 	c2.iHandshake=0;
  1289 	c2.iFifo=EFifoDisable;
  1290 
  1291 	c2.iDataBits=c1.iDataBits=EData8;
  1292 	c2.iStopBits=c1.iStopBits=EStop1;
  1293 	c2.iParity=c1.iParity=EParityNone;
  1294 	c2.iRate=c1.iRate=EBps19200;
  1295 
  1296 	TInt r=theSerialPorts[0]->SetConfig(cBuf1);
  1297 	test(r==KErrNone);
  1298 	r=theSerialPorts[1]->SetConfig(cBuf2);
  1299 	test(r==KErrNone);
  1300 
  1301 	TUint samples[KSamples];
  1302 
  1303 	for (TInt i=0;i<KSamples;i++)
  1304 		{
  1305 		test.Printf(_L("."));
  1306 
  1307 		TUint8* inBuf=new TUint8[KBufSize];
  1308 		TUint8* outBuf=new TUint8[KBufSize];
  1309 		TPtr8 outDes(outBuf,KBufSize,KBufSize);
  1310 		TPtr8 inDes(inBuf,KBufSize,KBufSize);
  1311 
  1312 
  1313 		RTimer tim;
  1314 		tim.CreateLocal();
  1315 		TRequestStatus readStatus;
  1316 		TRequestStatus timeStatus;
  1317 
  1318 		StripeMem(outDes,'A','Z');
  1319 		inDes.FillZ();
  1320 
  1321 		TTime startTime;
  1322 		startTime.HomeTime();
  1323 		for (TInt l=0;l<KNumWrites;l++)
  1324 			{
  1325 			inDes.SetLength(KBufSize/3);
  1326 			theSerialPorts[0]->Read(readStatus,inDes);
  1327 
  1328 			TInt ret=theSerialPorts[1]->WriteS(outDes,KBufSize);
  1329 			const TUint KTimeOut=6000000;
  1330 			tim.After(timeStatus,KTimeOut);
  1331 
  1332 			User::WaitForRequest(readStatus,timeStatus);
  1333 
  1334 
  1335 			if (timeStatus==KErrNone)
  1336 				{
  1337 				test.Printf(_L("Timed Out!\n\r"));
  1338 				theSerialPorts[0]->ReadCancel();
  1339 				}
  1340 			else
  1341 				{
  1342 				tim.Cancel();
  1343 				if (readStatus!=KErrNone)
  1344 						test.Printf(_L("Read Failed! (%d)\n\r"),readStatus.Int());
  1345 				test(readStatus==KErrNone);
  1346 				test(ret==KErrNone);
  1347 				test(inDes.Length()==inDes.MaxLength());
  1348 				test(inDes.Length()==KBufSize);
  1349 				test(CompareDescriptors(outDes,inDes));
  1350 				}
  1351 
  1352 			}
  1353 		TTime endTime;
  1354 		endTime.HomeTime();
  1355 
  1356 		TInt64 delta=endTime.MicroSecondsFrom(startTime).Int64();
  1357 		delta=delta/1000;
  1358 		TInt delta32=I64INT(delta);
  1359 		samples[i]=delta32;
  1360 		test.Printf(_L("Read/Write %d time = %d ms\n\r"),KNumWrites*KBufSize,delta32);
  1361 		}
  1362 
  1363 	TInt avg=0;
  1364 	for (TInt j=0;j<KSamples;j++)
  1365 		{
  1366 		avg=avg+samples[j];
  1367 		}
  1368 	avg/=KSamples;
  1369 	test.Printf(_L("      Average time = %d ms\n\r"),avg);
  1370 	test.Printf(_L("Press a key\n\r"));
  1371 	test.Getch();
  1372 
  1373 	test.End();
  1374 	}
  1375 
  1376 void testBreak()
  1377 ///
  1378 /// Tests serial breaks
  1379 ///
  1380  	{
  1381 	TBuf<256> msg;
  1382 	test.Next(_L("Testing breaks"));
  1383 
  1384 	TCommConfig cBuf0;
  1385 	TCommConfigV01& c0=cBuf0();
  1386 	TCommConfig cBuf1;
  1387 	TCommConfigV01& c1=cBuf1();
  1388 
  1389 	TRequestStatus breakStatus;
  1390 	TRequestStatus readStatus;
  1391 	TRequestStatus writeStatus;
  1392 	TRequestStatus timerStatus;
  1393 
  1394 	TInt r=theSerialPorts[0]->Open(PortA);
  1395 	test(r==KErrNone);
  1396 	r=theSerialPorts[0]->QueryReceiveBuffer();
  1397 	test(r==0);
  1398 	r=theSerialPorts[1]->Open(PortB);
  1399 	test(r==KErrNone);
  1400 	r=theSerialPorts[1]->QueryReceiveBuffer();
  1401 	test(r==0);
  1402 
  1403 	theSerialPorts[0]->Config(cBuf0);
  1404 	theSerialPorts[1]->Config(cBuf1);
  1405 	c0.iRate=c1.iRate=EBps110;
  1406 	c0.iParityError=c1.iParityError=0;
  1407 	c0.iHandshake=c1.iHandshake=0;
  1408 
  1409 	c0.iDataBits=c1.iDataBits=EData8;
  1410 	c0.iStopBits=c1.iStopBits=EStop1;
  1411 	c0.iParity=c1.iParity=EParityNone;
  1412 
  1413 
  1414 	r=theSerialPorts[0]->SetConfig(cBuf0);
  1415 	test(r==KErrNone);
  1416 	r=theSerialPorts[1]->SetConfig(cBuf1);
  1417 	test(r==KErrNone);
  1418 
  1419 for(TUint i = 0; i < ELEMENTS(KBreakSpeeds) ; ++i)
  1420 		{
  1421 		if (theCaps1.iRate&KBreakSpeeds[i].iMask && theCaps2.iRate&KBreakSpeeds[i].iMask)
  1422 			{
  1423 			msg.Format(_L("Break tests @ %s Bps"), KBreakSpeeds[i].iName);
  1424 			test.Start(msg);
  1425 
  1426 			c0.iRate=KBreakSpeeds[i].iSpeed;
  1427 			TInt r=theSerialPorts[0]->SetConfig(cBuf0);
  1428 			test(r==KErrNone);
  1429 			c1.iRate=KBreakSpeeds[i].iSpeed;
  1430 			r=theSerialPorts[1]->SetConfig(cBuf1);
  1431 			test(r==KErrNone);
  1432 
  1433 
  1434 			// should take more than 1.5s
  1435 
  1436 			HBufC8* bigReadBuffer=HBufC8::NewL(KWriteSize);
  1437 			HBufC8* bigWriteBuffer=HBufC8::NewMaxL(KWriteSize);
  1438 			TPtr8 bigReadBufferPtr(bigReadBuffer->Des());
  1439 			TPtr8 bigWriteBufferPtr(bigWriteBuffer->Des());
  1440 
  1441 			StripeMem(bigWriteBufferPtr, 'A', 'Z');
  1442 			bigReadBufferPtr.FillZ();
  1443 
  1444 
  1445 			const TUint KWriteSize=1024 + KBreakSpeeds[i].iBps/4;
  1446 			const TInt KTimerTime=1500000;
  1447 			const TInt KBreakTime=3000000;
  1448 			const TInt KMinTurnaroundTime=150000;
  1449 
  1450 			RTimer timer;
  1451 			test(timer.CreateLocal()==KErrNone);
  1452 
  1453 
  1454 // Test 1
  1455 			test.Start(_L("Break after write"));
  1456 		//- start a user timer which will expire just after the TX would complete with no break
  1457 			timer.After(timerStatus, KTimerTime);
  1458 
  1459 		//- request TX (and RX) and request a break
  1460 			theSerialPorts[0]->Write(writeStatus, *bigWriteBuffer, KWriteSize);
  1461 			theSerialPorts[0]->Break(breakStatus, KBreakTime);
  1462 			theSerialPorts[1]->Read(readStatus, bigReadBufferPtr, KWriteSize);
  1463 
  1464 		// Make sure the timer completes first
  1465 			User::WaitForRequest(writeStatus, readStatus);
  1466 			User::WaitForRequest(breakStatus);
  1467 
  1468 			test(readStatus!=KErrNone && readStatus!=KRequestPending);
  1469 			test(breakStatus==KErrNone);
  1470 			test(writeStatus==KErrNone || writeStatus==KRequestPending);	// Can be still pending, since if the read is completed with an error then the write won't complete since the buffers may fill up
  1471 			test(timerStatus==KErrNone);
  1472 
  1473 			if (writeStatus==KRequestPending)
  1474 				theSerialPorts[0]->WriteCancel();
  1475 
  1476 // Test 2
  1477 			test.Next(_L("Write after break"));
  1478 		//- start a user timer which will expire just after the TX would complete with no break
  1479 			timer.After(timerStatus, KTimerTime);
  1480 
  1481 		//- request TX (and RX) and request a break
  1482 			theSerialPorts[1]->Read(readStatus, bigReadBufferPtr, KWriteSize);
  1483 			theSerialPorts[0]->Break(breakStatus, KBreakTime);
  1484 			theSerialPorts[0]->Write(writeStatus, *bigWriteBuffer, KWriteSize);
  1485 
  1486 		// Make sure the timer completes first
  1487 			User::WaitForRequest(breakStatus);
  1488 			User::WaitForRequest(writeStatus, readStatus);
  1489 
  1490 			test(readStatus!=KErrNone && readStatus!=KRequestPending);
  1491 			test(breakStatus==KErrNone);
  1492 			test(writeStatus==KErrNone || writeStatus==KRequestPending);	// write may not be able to cmoplete due to no remaining pending read
  1493 			test(timerStatus==KErrNone);
  1494 
  1495 			if (writeStatus==KRequestPending)
  1496 				theSerialPorts[0]->WriteCancel();
  1497 
  1498 // Test 3
  1499 			test.Next(_L("Cancellation of break"));
  1500 		//- Check cancellation of breaks
  1501 
  1502 		//- request TX (and RX) and request a break
  1503 			theSerialPorts[0]->Break(breakStatus, KBreakTime);
  1504 			theSerialPorts[1]->Read(readStatus, bigReadBufferPtr, KWriteSize);
  1505 			theSerialPorts[0]->Write(writeStatus, *bigWriteBuffer, KWriteSize);
  1506 
  1507 		//- cancel break
  1508 			theSerialPorts[0]->BreakCancel();
  1509 
  1510 			User::WaitForRequest(breakStatus);
  1511 			test(breakStatus.Int()==KErrCancel);
  1512 
  1513 			User::WaitForRequest(readStatus);
  1514 
  1515 			if (writeStatus==KRequestPending)
  1516 				theSerialPorts[0]->WriteCancel();
  1517 
  1518 // Test 4
  1519 
  1520 			test.Next(_L("Break during turnaround"));
  1521 		//- Check break still works during turnaround
  1522 			test (KErrNone==theSerialPorts[0]->SetMinTurnaroundTime(KMinTurnaroundTime));
  1523 
  1524 			theSerialPorts[0]->Read(readStatus, bigReadBufferPtr, 1);
  1525 			theSerialPorts[1]->Write(writeStatus, *bigWriteBuffer, 1);
  1526 			User::WaitForRequest(readStatus);
  1527 			User::WaitForRequest(writeStatus);
  1528 
  1529 		//- start a user timer which will expire just after the TX would complete with no break
  1530 			timer.After(timerStatus, KTimerTime);
  1531 
  1532 		//- request TX (and RX) and request a break
  1533 			theSerialPorts[0]->Break(breakStatus, KBreakTime);
  1534 			theSerialPorts[1]->Read(readStatus, bigReadBufferPtr, KWriteSize);
  1535 			theSerialPorts[0]->Write(writeStatus, *bigWriteBuffer, KWriteSize);
  1536 
  1537 		// Make sure the timer completes first
  1538 			User::WaitForRequest(writeStatus, readStatus);
  1539 			User::WaitForRequest(breakStatus);
  1540 
  1541 			test(readStatus!=KErrNone && readStatus!=KRequestPending);
  1542 			test(breakStatus==KErrNone);
  1543 			test(writeStatus==KErrNone || writeStatus==KRequestPending);
  1544 			test(timerStatus==KErrNone);
  1545 
  1546 			if (writeStatus==KRequestPending)
  1547 				theSerialPorts[0]->WriteCancel();
  1548 
  1549 			test (KErrNone==theSerialPorts[0]->SetMinTurnaroundTime(0));
  1550 
  1551 // End tests
  1552 			timer.Close();
  1553 			test.End();
  1554 			test.End();
  1555 			}
  1556 		else
  1557 			{
  1558 			msg.Format(_L("%s Bps not supported"),KBreakSpeeds[i].iName);
  1559 			test.Next(msg);
  1560 			}
  1561 		}	// end rate loop
  1562 
  1563 	theSerialPorts[0]->Close();
  1564 	theSerialPorts[1]->Close();
  1565 	}
  1566 
  1567 
  1568 
  1569 void testFraming()
  1570 //
  1571 // Test framing
  1572 //
  1573 	{
  1574 	test.Start(_L("Testing framing"));
  1575 
  1576 	TInt r=theSerialPorts[0]->Open(PortA);
  1577 	test(r==KErrNone);
  1578 	r=theSerialPorts[0]->QueryReceiveBuffer();
  1579 	test(r==0);
  1580 	r=theSerialPorts[1]->Open(PortB);
  1581 	test(r==KErrNone);
  1582 	r=theSerialPorts[1]->QueryReceiveBuffer();
  1583 	test(r==0);
  1584 
  1585 	TCommConfig cBuf0;
  1586 	TCommConfigV01& c0=cBuf0();
  1587 	TCommConfig cBuf1;
  1588 	TCommConfigV01& c1=cBuf1();
  1589 	TBuf<0x40> mess;
  1590 
  1591 	theSerialPorts[0]->Config(cBuf0);
  1592 	c0.iRate=EBps9600;
  1593 	c0.iHandshake=0;
  1594 	theSerialPorts[1]->Config(cBuf1);
  1595 	c1.iRate=EBps9600;
  1596 	c1.iHandshake=0;
  1597 
  1598 	TInt numTests=sizeof(KFrameTypes)/sizeof(TFrameAndName);
  1599 	for (TInt i=0;i<numTests;i++)
  1600 		{
  1601 		c0.iDataBits=KFrameTypes[i].iData;
  1602 		c0.iStopBits=KFrameTypes[i].iStop;
  1603 		c0.iParity=KFrameTypes[i].iParity;
  1604 		TInt r=theSerialPorts[0]->SetConfig(cBuf0);
  1605 		if (r==KErrNone)
  1606 			{
  1607 
  1608 			c1.iDataBits=KFrameTypes[i].iData;
  1609 			c1.iStopBits=KFrameTypes[i].iStop;
  1610 			c1.iParity=KFrameTypes[i].iParity;
  1611 			r=theSerialPorts[1]->SetConfig(cBuf1);
  1612 			if(r==KErrNone)
  1613 				{
  1614 				mess.Format(_L("read/write using %s "),KFrameTypes[i].iName);
  1615 				test.Next(mess);
  1616 				test(CheckedWrite(KWriteSize)==KWriteSize);
  1617 				}
  1618 			}
  1619 
  1620 		if (r!=KErrNone)
  1621 			test.Printf(_L("%s not supported\n\r"),KFrameTypes[i].iName);
  1622 		}
  1623 
  1624 	theSerialPorts[0]->Close();
  1625 	theSerialPorts[1]->Close();
  1626 	test.End();
  1627 	}
  1628 //
  1629 void testTerminators()
  1630 //
  1631 // Test termination masks - assumes that Checked write stripes memory starting with 'A'
  1632 //
  1633 	{
  1634 
  1635 	test.Next(_L("Testing termination masks"));
  1636 
  1637 	TCommConfig cBuf;
  1638 	TCommConfigV01& c=cBuf();
  1639 
  1640 	theSerialPorts[0]->Close();
  1641 	theSerialPorts[1]->Close();
  1642 
  1643 	TInt r=theSerialPorts[0]->Open(PortA);
  1644 	test(r==KErrNone);
  1645 	r=theSerialPorts[0]->QueryReceiveBuffer();
  1646 	test(r==0);
  1647 	r=theSerialPorts[1]->Open(PortB);
  1648 	test(r==KErrNone);
  1649 	r=theSerialPorts[1]->QueryReceiveBuffer();
  1650 	test(r==0);
  1651 	theSerialPorts[0]->Config(cBuf);
  1652 	c.iTerminator[0]='C';
  1653 	c.iTerminatorCount=1;
  1654 	c.iHandshake=0;
  1655 
  1656 	c.iDataBits=EData8;
  1657 	c.iStopBits=EStop1;
  1658 	c.iParity=EParityNone;
  1659 
  1660 	r=theSerialPorts[0]->SetConfig(cBuf);
  1661 	test(r==KErrNone);
  1662 
  1663 	TCommConfig cBuf1;
  1664 	TCommConfigV01& c1=cBuf1();
  1665 	theSerialPorts[1]->Config(cBuf1);
  1666 
  1667 	c1.iDataBits=EData8;
  1668 	c1.iStopBits=EStop1;
  1669 	c1.iParity=EParityNone;
  1670 
  1671 	c1.iTerminator[0]='C';
  1672 	c1.iTerminatorCount=1;
  1673 	c1.iHandshake=0;
  1674 
  1675 	r=theSerialPorts[1]->SetConfig(cBuf1);
  1676 	test(r==KErrNone);
  1677 
  1678 	User::After(100000);
  1679 	theSerialPorts[0]->ResetBuffers();
  1680 	theSerialPorts[1]->ResetBuffers();
  1681 
  1682 	test(CheckedWrite(KWriteSize)==3);
  1683 
  1684 	// Clear the ldd buffers
  1685 	theSerialPorts[0]->ResetBuffers();
  1686 	theSerialPorts[1]->ResetBuffers();
  1687 
  1688 	c.iTerminator[0]='Z';
  1689 	c.iTerminator[1]='X';
  1690 	c.iTerminator[2]='Y';
  1691 	c.iTerminator[3]='D';
  1692 
  1693 	c1.iTerminator[0]='Z';
  1694 	c1.iTerminator[1]='X';
  1695 	c1.iTerminator[2]='Y';
  1696 	c1.iTerminator[3]='D';
  1697 
  1698 /* 	Not yet - we have too much buffering in the driver & device.
  1699 	Unfortunately the ResetBuffers() above doesn't (and really can't) go
  1700 	deep enough. Under WINS NT buffers up some data and the following read
  1701 	(inside checked write) completes before the WriteS (and infact, after
  1702 	reading a semi random number of characters)
  1703 
  1704     c.iTerminatorCount=4;
  1705     c1.iTerminatorCount=4;
  1706 	r=theSerialPorts[0]->SetConfig(cBuf);
  1707 	test(r==KErrNone);
  1708 	r=theSerialPorts[1]->SetConfig(cBuf1);
  1709 	test(r==KErrNone);
  1710 
  1711 	test(CheckedWrite(KWriteSize)==4);
  1712 	theSerialPorts[0]->Config(cBuf);
  1713 */
  1714 	// Reset termination mask.
  1715 	c.iTerminatorCount=0;
  1716 	c1.iTerminatorCount=0;
  1717 	r=theSerialPorts[0]->SetConfig(cBuf);
  1718 	test(r==KErrNone);
  1719 	r=theSerialPorts[1]->SetConfig(cBuf1);
  1720 	test(r==KErrNone);
  1721 
  1722 	theSerialPorts[0]->Close();
  1723 	theSerialPorts[1]->Close();
  1724 	}
  1725 
  1726 void testXonXoff()
  1727 //
  1728 // tests XonXoff
  1729 //
  1730 	{
  1731 	test.Next(_L("Testing xon xoff"));
  1732 	test.Start(_L("Setup"));
  1733 
  1734 	TInt r=theSerialPorts[0]->Open(PortA);
  1735 	test(r==KErrNone);
  1736 	r=theSerialPorts[0]->QueryReceiveBuffer();
  1737 	test(r==0);
  1738 	r=theSerialPorts[1]->Open(PortB);
  1739 	test(r==KErrNone);
  1740 	r=theSerialPorts[1]->QueryReceiveBuffer();
  1741 	test(r==0);
  1742 
  1743 	TCommConfig cBuf;
  1744 	TCommConfigV01& c=cBuf();
  1745 
  1746 	theSerialPorts[0]->Config(cBuf);
  1747 	c.iHandshake=KConfigObeyXoff|KConfigSendXoff;
  1748 	c.iStopBits=EStop1;
  1749 	c.iParity=EParityNone;
  1750 	c.iDataBits=EData8;
  1751 	c.iRate=EBps19200;
  1752 	c.iXonChar=0x11;
  1753 	c.iXoffChar=0x13;
  1754 	c.iParityError=KConfigXonXoffDebug;
  1755 	c.iTerminatorCount=0;
  1756 	test(theSerialPorts[0]->SetConfig(cBuf)==KErrNone);
  1757 
  1758 	theSerialPorts[1]->Config(cBuf);
  1759 	c.iHandshake=KConfigObeyXoff|KConfigSendXoff;
  1760 	c.iStopBits=EStop1;
  1761 	c.iParity=EParityNone;
  1762 	c.iDataBits=EData8;
  1763 	c.iRate=EBps19200;
  1764 	c.iXonChar=0x11;
  1765 	c.iXoffChar=0x13;
  1766 	c.iParityError=KConfigXonXoffDebug;
  1767 	c.iTerminatorCount=0;
  1768 	test(theSerialPorts[1]->SetConfig(cBuf)==KErrNone);
  1769 
  1770 	theSerialPorts[0]->SetReceiveBufferLength(0x400);
  1771 	theSerialPorts[1]->SetReceiveBufferLength(0x400);
  1772 
  1773 	const TInt KXonWriteSize=KXonNumReads*KXonReadSize;
  1774 
  1775 	TUint8* inBuf=new TUint8[KXonReadSize];
  1776 	TUint8* outBuf=new TUint8[KXonWriteSize];
  1777 	TPtr8 outDes(outBuf,KXonWriteSize,KXonWriteSize);
  1778 	TPtr8 inDes(inBuf,KXonReadSize,KXonReadSize);
  1779 
  1780 	TRequestStatus readStatus;
  1781 	TRequestStatus writeStatus;
  1782 	TRequestStatus timeStatus;
  1783 	RTimer timer;
  1784 	timer.CreateLocal();
  1785 	TInt writePos=0;
  1786 
  1787 	StripeMem(outDes,'A','Z');
  1788 	inDes.FillZ();
  1789 
  1790 	test.Next(_L("Write bytes to com1"));
  1791 	test.Printf(_L("Reading after delay (1 of %d) avail = %d\n\r"),KXonNumReads, theSerialPorts[0]->QueryReceiveBuffer());
  1792 	theSerialPorts[0]->Read(readStatus,inDes,KXonReadSize);
  1793 	theSerialPorts[1]->Write(writeStatus,outDes,KXonWriteSize);
  1794 	timer.After(timeStatus,1000000);
  1795 	User::WaitForRequest(readStatus,timeStatus);
  1796 	test(readStatus==KErrNone);
  1797 	test(timeStatus==KRequestPending);
  1798 	TPtrC8 aOutDes = outDes.Mid(writePos,KXonReadSize);
  1799 	test(CompareDescriptors(inDes,(TDes8&)aOutDes));
  1800 
  1801 	writePos+=KXonReadSize;
  1802 
  1803 	if (timeStatus==KRequestPending)
  1804 		User::WaitForRequest(timeStatus);
  1805 
  1806 	TInt i;
  1807 	for (i=0;i<KXonNumReads-1;++i)
  1808 		{
  1809 		inDes.FillZ();
  1810 		timer.After(timeStatus,450000);
  1811 		User::WaitForRequest(timeStatus);
  1812 		test(timeStatus==KErrNone);
  1813 
  1814 		test.Printf(_L("Reading after delay (%d of %d) avail = %d\n\r"),i+2,KXonNumReads, theSerialPorts[0]->QueryReceiveBuffer());
  1815 		theSerialPorts[0]->Read(readStatus,inDes,KXonReadSize);
  1816 		timer.After(timeStatus,1000000);
  1817 		User::WaitForRequest(readStatus,timeStatus);
  1818 		if (readStatus!=KErrNone)
  1819 			test.Printf(_L("Read error %d\n\r"),readStatus.Int());
  1820 		test(readStatus==KErrNone);
  1821 		test(timeStatus==KRequestPending);
  1822 		TPtrC8 aOutDes = outDes.Mid(writePos,KXonReadSize);
  1823 		test(CompareDescriptors(inDes,(TDes8&)aOutDes));
  1824 		timer.Cancel();
  1825 		writePos+=KXonReadSize;
  1826 		}
  1827 
  1828 	test.Next(_L("2nd Large Write complete"));
  1829 	test(writeStatus==KErrNone);
  1830 
  1831 	delete [] inBuf;
  1832 	delete [] outBuf;
  1833 
  1834 	theSerialPorts[0]->Close();
  1835 	theSerialPorts[1]->Close();
  1836 
  1837 	test.End();
  1838 	}
  1839 
  1840 //
  1841 void testHWHandshaking()
  1842 //
  1843 // test hardware hand shaking
  1844 //
  1845 	{
  1846 
  1847 #if defined (__WINS__)
  1848 const TInt KHWReadSize=0x2000;
  1849 #else
  1850 const TInt KHWReadSize=0x400;
  1851 #endif
  1852 
  1853 	test.Start(_L("Testing hardware handshaking"));
  1854 
  1855 	TInt r=theSerialPorts[0]->Open(PortA);
  1856 	test(r==KErrNone);
  1857 	r=theSerialPorts[0]->QueryReceiveBuffer();
  1858 	test(r==0);
  1859 	r=theSerialPorts[1]->Open(PortB);
  1860 	test(r==KErrNone);
  1861 	r=theSerialPorts[1]->QueryReceiveBuffer();
  1862 	test(r==0);
  1863 
  1864 	TCommConfig cBuf0;
  1865 	TCommConfigV01& c0=cBuf0();
  1866 	TBuf<0x40> mess;
  1867 	theSerialPorts[0]->Config(cBuf0);
  1868 	c0.iRate=EBps115200;
  1869 	c0.iParityError=0;
  1870 	c0.iHandshake=0;
  1871 
  1872 	TCommConfig cBuf1;
  1873 	TCommConfigV01& c1=cBuf1();
  1874 	test(theSerialPorts[0]->SetConfig(cBuf0)==KErrNone);
  1875 
  1876 	theSerialPorts[1]->Config(cBuf1);
  1877 	c1.iRate=EBps115200;
  1878 	c1.iParityError=0;
  1879 	c1.iHandshake=0;
  1880 	test(theSerialPorts[1]->SetConfig(cBuf1)==KErrNone);
  1881 
  1882 	const TInt KXonWriteSize=KXonNumReads*KHWReadSize;
  1883 
  1884 	TUint8* inBuf=new TUint8[KHWReadSize];
  1885 	TUint8* outBuf=new TUint8[KXonWriteSize];
  1886 	TPtr8 outDes(outBuf,KXonWriteSize,KXonWriteSize);
  1887 	TPtr8 inDes(inBuf,KHWReadSize,KHWReadSize);
  1888 
  1889 //TUint8* inBuf2=new TUint8[KXonWriteSize];
  1890 //TPtr8 inDes2(inBuf2,KXonWriteSize,KXonWriteSize);
  1891 
  1892 #if defined (__WINS__)
  1893 	theSerialPorts[0]->SetReceiveBufferLength(0x50);
  1894 	theSerialPorts[1]->SetReceiveBufferLength(0x50);
  1895 #else
  1896 	theSerialPorts[0]->SetReceiveBufferLength(0x400);
  1897 	theSerialPorts[1]->SetReceiveBufferLength(0x400);
  1898 #endif
  1899 
  1900 	TInt numTests=sizeof(KHandshakes)/sizeof(THandShakeAndName);
  1901 	for(TInt j=0;j<numTests;j++)
  1902 		{
  1903 		mess.Format(_L("read/write using %s "),KHandshakes[j].iName);
  1904 		test.Next(mess);
  1905 		c0.iHandshake=c1.iHandshake=KHandshakes[j].iHandshake;
  1906 
  1907 		if((theCaps1.iHandshake & KHandshakes[j].iHandshake)
  1908 			&& (theCaps2.iHandshake & KHandshakes[j].iHandshake))
  1909 			{
  1910 			test(theSerialPorts[0]->SetConfig(cBuf0)==KErrNone);
  1911 			test(theSerialPorts[1]->SetConfig(cBuf1)==KErrNone);
  1912 			TRequestStatus readStatus;
  1913 			TRequestStatus writeStatus;
  1914 
  1915 			StripeMem(outDes,'A','Z');
  1916 			inDes.FillZ();
  1917 
  1918 			theSerialPorts[1]->Write(writeStatus,outDes,KXonWriteSize);
  1919 
  1920 //TRequestStatus writeStatus2;
  1921 //theSerialPorts[0]->Write(writeStatus2,outDes,KXonWriteSize);
  1922 
  1923 			TInt i;
  1924 			for (i=0;i<KXonNumReads;i++)
  1925 				{
  1926 				inDes.FillZ();
  1927 #if defined (__WINS__)
  1928 				User::After(600000);
  1929 #else
  1930 				User::After(300000);
  1931 #endif
  1932 				test.Printf(_L("Reading %d after delay (%d of %d) avail = %d\r\n"),KHWReadSize, i+1,KXonNumReads, theSerialPorts[0]->QueryReceiveBuffer());
  1933 				theSerialPorts[0]->Read(readStatus,inDes,KHWReadSize);
  1934 				User::WaitForRequest(readStatus);
  1935 				test(readStatus==KErrNone);
  1936 				TPtrC8 aOutDes = outDes.Mid(KHWReadSize*i,KHWReadSize);
  1937 				test(CompareDescriptors(inDes,(TDes8&)aOutDes));
  1938 				test(inDes.Length()==KHWReadSize);
  1939 				}
  1940 
  1941 			test.Next(_L("2nd Large Write complete"));
  1942 			User::WaitForRequest(writeStatus);
  1943 			test(writeStatus==KErrNone);
  1944 
  1945 //theSerialPorts[1]->Read(readStatus,inDes2,KXonWriteSize);
  1946 //User::WaitForRequest(writeStatus2);
  1947 //test(writeStatus2==KErrNone);
  1948 
  1949 //User::WaitForRequest(readStatus);
  1950 //test(readStatus==KErrNone);
  1951 
  1952 			}
  1953 		else
  1954 			{
  1955 			test.Printf(_L("Config not supported\r\n"));
  1956 			}
  1957 		}
  1958 	delete [] inBuf;
  1959 	delete [] outBuf;
  1960 
  1961 	theSerialPorts[0]->Close();
  1962 	theSerialPorts[1]->Close();
  1963 
  1964 	test.End();
  1965 	}
  1966 
  1967 void testWriteZero()
  1968 //
  1969 // Test a write of 0 bytes is still blocked by CTS flow control. 
  1970 // Test does a flow controlled Write(0) which is blocked by the remote 
  1971 // port state being closed (hence remote RTS disasserted, hence writer's 
  1972 // CTS likewise). Then it opens the remote port and asserts RTS - this 
  1973 // unblocks the original Write(0). 
  1974 // 
  1975 	{
  1976 	TInt r=theSerialPorts[0]->Open(PortA);
  1977 	test(r==KErrNone);
  1978 	r=theSerialPorts[0]->QueryReceiveBuffer();
  1979 	test(r==0);
  1980 
  1981 	test.Next(_L("Testing Write 0"));
  1982 
  1983 	TCommConfig cBuf1;
  1984 	TCommConfigV01& c1=cBuf1();
  1985 	theSerialPorts[0]->Config(cBuf1);
  1986 	c1.iRate=EBps19200;
  1987 	c1.iParityError=0;
  1988 	c1.iHandshake=KConfigObeyCTS;
  1989 
  1990 	r=theSerialPorts[0]->SetConfig(cBuf1);
  1991 	test(r==KErrNone);
  1992 
  1993 	test.Start(_L("Test Write(0) with remote RTS disasserted blocks"));
  1994 	TRequestStatus writeStat;
  1995 	theSerialPorts[0]->Write(writeStat,TPtr8(NULL,0),0);
  1996 
  1997 	RTimer timer;
  1998 	timer.CreateLocal();
  1999 	TRequestStatus timeStatus;
  2000 	timer.After(timeStatus,1000000);
  2001 	User::WaitForRequest(timeStatus,writeStat);
  2002 
  2003 	test(timeStatus==KErrNone);
  2004 	test(writeStat==KRequestPending);
  2005 
  2006 	r=theSerialPorts[1]->Open(PortB);
  2007 	test(r==KErrNone);
  2008 	r=theSerialPorts[1]->QueryReceiveBuffer();
  2009 	test(r==0);
  2010 
  2011 	TCommConfig cBuf2;
  2012 	TCommConfigV01& c2=cBuf2();
  2013 	theSerialPorts[1]->Config(cBuf2);
  2014 	c2.iRate=EBps19200;
  2015 	c2.iParityError=0;
  2016 	c2.iHandshake |= KConfigFreeRTS;
  2017 	r=theSerialPorts[1]->SetConfig(cBuf2);
  2018 	test(r==KErrNone);
  2019 
  2020 	test.Next(_L("Test Write(0) with remote RTS asserted completes"));
  2021 	timer.After(timeStatus,10000000);
  2022 	theSerialPorts[1]->SetSignals(KSignalRTS,0);
  2023 
  2024 	User::WaitForRequest(timeStatus,writeStat);
  2025 	if (writeStat==KRequestPending)
  2026 		test.Printf(_L("     Timed out!\n"));
  2027 	User::After(2000000);
  2028 
  2029 	test(writeStat==KErrNone);
  2030 	test(timeStatus==KRequestPending);
  2031 
  2032 	timer.Cancel();
  2033 
  2034 	theSerialPorts[0]->Close();
  2035 	theSerialPorts[1]->Close();
  2036 
  2037 	test.End();
  2038 	}
  2039 
  2040 
  2041 void testSingleCharacterReads()
  2042 //
  2043 // Test reading one character at a time.
  2044 //
  2045 	{
  2046 	const TInt KWriteSize=100;
  2047 	test.Start(_L("Test partial reads"));
  2048 
  2049 	TInt r=theSerialPorts[0]->Open(PortA);
  2050 	test(r==KErrNone);
  2051 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2052 	test(r==0);
  2053 	r=theSerialPorts[1]->Open(PortB);
  2054 	test(r==KErrNone);
  2055 	r=theSerialPorts[1]->QueryReceiveBuffer();
  2056 	test(r==0);
  2057 
  2058 	TCommConfig cBuf0;
  2059 	TCommConfigV01& c0=cBuf0();
  2060 	theSerialPorts[0]->Config(cBuf0);
  2061 
  2062 	TCommConfig cBuf1;
  2063 	TCommConfigV01& c1=cBuf1();
  2064 	theSerialPorts[1]->Config(cBuf1);
  2065 
  2066 	c0.iRate=c1.iRate=EBps9600;
  2067 	c0.iParityError=c1.iParityError=0;
  2068 	c0.iHandshake=c1.iHandshake=KConfigObeyCTS;
  2069 
  2070 	c0.iDataBits=c1.iDataBits=EData8;
  2071 	c0.iStopBits=c1.iStopBits=EStop1;
  2072 	c0.iParity=c1.iParity=EParityNone;
  2073 
  2074 	r=theSerialPorts[0]->SetConfig(cBuf0);
  2075 	test(r==KErrNone);
  2076 	r=theSerialPorts[1]->SetConfig(cBuf1);
  2077 	test(r==KErrNone);
  2078 	test.Printf(_L("Setconfig OK\r\n"));
  2079 
  2080 	TInt bufSiz=KWriteSize+3+(KWriteSize/2);
  2081 
  2082 	r=theSerialPorts[0]->SetReceiveBufferLength(bufSiz);
  2083 	if (r!=KErrNone)
  2084 		test.Printf(_L("Setting buffers to %d bytes for com0 failed %d\n\r"),bufSiz,r);
  2085 	r=theSerialPorts[1]->SetReceiveBufferLength(bufSiz+1);
  2086 	if (r!=KErrNone)
  2087 		test.Printf(_L("Setting buffers to %d bytes for com1 failed %d\n\r"),bufSiz,r);
  2088 
  2089 	TUint8* singleCharReadBuf=new TUint8[1];
  2090 	test(singleCharReadBuf!=NULL);
  2091 	TPtr8 singleCharReadDes(singleCharReadBuf,1,1);
  2092 	TUint8* multiCharWriteBuf=new TUint8[KWriteSize];
  2093 	test(multiCharWriteBuf!=NULL);
  2094 	TPtr8 multiCharWriteDes(multiCharWriteBuf,KWriteSize,KWriteSize);
  2095 	multiCharWriteDes.Fill('m');
  2096 
  2097 	RTimer tim;
  2098 	tim.CreateLocal();
  2099 
  2100 	for (TInt j=0;j<2;j++)
  2101 		{
  2102 		TInt readPort=0;
  2103 		TInt writePort=0;
  2104 		readPort=1-j;
  2105 		writePort=j;
  2106 
  2107 		TBuf<256> message;
  2108 		message.Format(_L("Reading single chars from port %d, writing %d to port %d"),readPort,multiCharWriteDes.Length(),writePort);
  2109 		test.Next(message);
  2110 
  2111 		TRequestStatus readZeroStat;
  2112 		theSerialPorts[readPort]->Read(readZeroStat,singleCharReadDes,0);//a zero length read completes immediately and
  2113 		User::WaitForRequest(readZeroStat);								 //will wake up the receiver
  2114 		test.Printf(_L("Have done a read zero: %d\n\r"),readZeroStat.Int());
  2115 		User::After(1000000);
  2116 
  2117 		TRequestStatus multiWriteStat;
  2118 		theSerialPorts[writePort]->Write(multiWriteStat,multiCharWriteDes);
  2119 //		User::WaitForRequest(multiWriteStat);
  2120 //		test.Printf(_L("Have done a write: %d\n\r"),multiWriteStat.Int());
  2121 
  2122 		TRequestStatus timStat;
  2123 		TInt spin=0;
  2124 		for (TInt i=0;i<KWriteSize;i++)
  2125 			{
  2126 			tim.After(timStat,10000000);
  2127 			TRequestStatus readStat;
  2128 			singleCharReadDes.SetLength(0);
  2129 			theSerialPorts[readPort]->Read(readStat,singleCharReadDes);
  2130 			User::WaitForRequest(readStat,timStat);
  2131 
  2132 			test.Printf(_L("r"));
  2133 			if (i%32==0)
  2134 				test.Printf(_L("\r%c"),KSpinner[spin++%4]);
  2135 
  2136 			if (readStat!=KErrNone)
  2137 				{
  2138 				TBuf<256> message;
  2139 				if (readStat==KRequestPending)
  2140 					{
  2141 					message.Format(_L("\n\rRead timed out after %d chars (of %d)\n\r"),i,KWriteSize);
  2142 					/*if (multiWriteStat==KErrNone)
  2143 						{
  2144 						User::WaitForRequest(multiWriteStat);
  2145 						theSerialPorts[readPort]->ReadCancel();
  2146 						theSerialPorts[writePort]->Write(multiWriteStat,multiCharWriteDes);
  2147 						}*/
  2148 					}
  2149 				else
  2150 					if (readStat!=KErrOverflow && readStat!=KErrCommsOverrun)
  2151 						message.Format(_L("\n\rRead Failed %d after %d chars (of %d)\n\r"),readStat.Int(),i,KWriteSize);
  2152 
  2153 				test.Printf(message);
  2154 				User::After(2000000);
  2155 				test(EFalse);
  2156 				}
  2157 
  2158 			tim.Cancel();
  2159 			if (singleCharReadDes[0]!='m')
  2160 				{
  2161 				test.Printf(_L("Received character: 0x%02x\n"),singleCharReadDes[0]);
  2162 				test(EFalse);
  2163 				}
  2164 			}
  2165 
  2166 		test.Printf(_L("Done\n\r"));
  2167 
  2168 		tim.After(timStat,1000000);
  2169 		User::WaitForRequest(timStat,multiWriteStat);
  2170 		if (timStat.Int()==KErrNone)
  2171 			{
  2172 			test.Printf(_L("Lost at least one char!\n\r"));
  2173 			theSerialPorts[writePort]->WriteCancel();
  2174 			test(EFalse);
  2175 			}
  2176 		else
  2177 			{
  2178 			tim.Cancel();
  2179 			}
  2180 		}
  2181 
  2182 	TUint8* singleCharWriteBuf=new TUint8[1];
  2183 	test(singleCharWriteBuf!=NULL);
  2184 	TPtr8 singleCharWriteDes(singleCharWriteBuf,1,1);
  2185 	singleCharWriteDes.Fill('s');
  2186 	TUint8* multiCharReadBuf=new TUint8[KWriteSize];
  2187 	test(multiCharReadBuf!=NULL);
  2188 	TPtr8 multiCharReadDes(multiCharReadBuf,KWriteSize,KWriteSize);
  2189 
  2190 	for (TInt k=0;k<2;k++)
  2191 		{
  2192 		TInt readPort=0;
  2193 		TInt writePort=0;
  2194 
  2195 		readPort=k;
  2196 		writePort=1-k;
  2197 
  2198 		TRequestStatus multiReadStat;
  2199 		theSerialPorts[readPort]->Read(multiReadStat,multiCharReadDes);
  2200 
  2201 		TBuf<256> message;
  2202 		message.Format(_L("Writing single chars to port %d"),readPort);
  2203 		test.Next(message);
  2204 
  2205 		TRequestStatus timStat;
  2206 		TInt spin=0;
  2207 		for (TInt i=0;i<KWriteSize;i++)
  2208 			{
  2209 			TRequestStatus writeStat;
  2210 			tim.After(timStat,5000000);
  2211 			theSerialPorts[writePort]->Write(writeStat,singleCharWriteDes);
  2212 			User::WaitForRequest(writeStat,timStat);
  2213 
  2214 			if ((i%32)==0)
  2215 				test.Printf(_L("\r%c"),KSpinner[spin++%4]);
  2216 
  2217 			if (writeStat!=KErrNone)
  2218 				{
  2219 				TBuf<256> message;
  2220 				if (writeStat==KRequestPending)
  2221 					message.Format(_L("\n\rWrite timed out after %d chars (of %d)\n\r"),i,KWriteSize);
  2222 				else
  2223 					message.Format(_L("\n\rWrite Failed %d after %d chars (of %d)\n\r"),writeStat.Int(),i,KWriteSize);
  2224 
  2225 				test.Printf(message);
  2226 				}
  2227 			test(writeStat==KErrNone);
  2228 			tim.Cancel();
  2229 			}
  2230 		test.Printf(_L("Done\n\r"));
  2231 
  2232 		tim.After(timStat,1000000);
  2233 		User::WaitForRequest(timStat,multiReadStat);
  2234 		if (timStat.Int()==KErrNone)
  2235 			{
  2236 			test.Printf(_L("Lost at least one char!\n\r"));
  2237 			theSerialPorts[readPort]->ReadCancel();
  2238 			test(EFalse);
  2239 			}
  2240 		else
  2241 			{
  2242 			tim.Cancel();
  2243 			test(multiReadStat==KErrNone);
  2244 			test(multiCharWriteDes.Length()==multiCharWriteDes.MaxLength());
  2245 			}
  2246 		}
  2247 
  2248 	test.End();
  2249 	tim.Close();
  2250 
  2251 	delete [] multiCharWriteBuf;
  2252 	delete [] singleCharReadBuf;
  2253 	delete [] singleCharWriteBuf;
  2254 	delete [] multiCharReadBuf;
  2255 
  2256 	theSerialPorts[0]->Close();
  2257 	theSerialPorts[1]->Close();
  2258 	}
  2259 
  2260 void testBiDirectionalSingleCharacterReads()
  2261 //
  2262 // Test reading and writing one character at a time.
  2263 //
  2264 	{
  2265 
  2266 	test.Start(_L("Test concurrent partial reads and writes"));
  2267 
  2268 	TInt r=theSerialPorts[0]->Open(PortA);
  2269 	test(r==KErrNone);
  2270 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2271 	test(r==0);
  2272 	r=theSerialPorts[1]->Open(PortB);
  2273 	test(r==KErrNone);
  2274 	r=theSerialPorts[1]->QueryReceiveBuffer();
  2275 	test(r==0);
  2276 
  2277 	TCommConfig cBuf0;
  2278 	TCommConfigV01& c0=cBuf0();
  2279 	theSerialPorts[0]->Config(cBuf0);
  2280 
  2281 	TCommConfig cBuf1;
  2282 	TCommConfigV01& c1=cBuf1();
  2283 	theSerialPorts[1]->Config(cBuf1);
  2284 
  2285 	c0.iRate=c1.iRate=EBps9600;
  2286 	c0.iParityError=c1.iParityError=0;
  2287 	c0.iHandshake=c1.iHandshake=KConfigObeyCTS;
  2288 
  2289 	c0.iDataBits=c1.iDataBits=EData8;
  2290 	c0.iStopBits=c1.iStopBits=EStop1;
  2291 	c0.iParity=c1.iParity=EParityNone;
  2292 
  2293 	r=theSerialPorts[0]->SetConfig(cBuf0);
  2294 	test(r==KErrNone);
  2295 	r=theSerialPorts[1]->SetConfig(cBuf1);
  2296 	test(r==KErrNone);
  2297 
  2298 	const TInt KWriteSize=4000;
  2299 	TUint8* singleCharReadBuf=new TUint8[1];
  2300 	test(singleCharReadBuf!=NULL);
  2301 	TPtr8 singleCharReadDes(singleCharReadBuf,1,1);
  2302 	TUint8* multiCharWriteBuf=new TUint8[KWriteSize];
  2303 	test(multiCharWriteBuf!=NULL);
  2304 	TPtr8 multiCharWriteDes(multiCharWriteBuf,KWriteSize,KWriteSize);
  2305 	multiCharWriteDes.Fill('m');
  2306 	TUint8* singleCharWriteBuf=new TUint8[1];
  2307 	test(singleCharWriteBuf!=NULL);
  2308 	TPtr8 singleCharWriteDes(singleCharWriteBuf,1,1);
  2309 	singleCharWriteDes.Fill('s');
  2310 	TUint8* multiCharReadBuf=new TUint8[KWriteSize];
  2311 	test(multiCharReadBuf!=NULL);
  2312 	TPtr8 multiCharReadDes(multiCharReadBuf,KWriteSize,KWriteSize);
  2313 
  2314 	TRequestStatus multiWriteStat;
  2315 	TRequestStatus multiReadStat;
  2316 	theSerialPorts[0]->Write(multiWriteStat,multiCharWriteDes);
  2317 	theSerialPorts[0]->Read(multiReadStat,multiCharReadDes);
  2318 
  2319 	TInt spin=0;
  2320 	for (TInt i=0;i<KWriteSize;i++)
  2321 		{
  2322 		if (i%32==0)
  2323 			test.Printf(_L("\r%c"),KSpinner[spin++%4]);
  2324 
  2325 		TRequestStatus readStat;
  2326 		TRequestStatus writeStat;
  2327 		theSerialPorts[1]->Read(readStat,singleCharReadDes);
  2328 		theSerialPorts[1]->Write(writeStat,singleCharWriteDes);
  2329 		User::WaitForRequest(readStat);
  2330 		User::WaitForRequest(writeStat);
  2331 
  2332 		if (readStat!=KErrNone)
  2333 			{
  2334 			test.Printf(_L("Read Failed %d after %d chars\n\r"),readStat.Int(),i);
  2335 			test(EFalse);
  2336 			}
  2337 		if (writeStat!=KErrNone)
  2338 			{
  2339 			test.Printf(_L("Write Failed %d after %d chars\n\r"),writeStat.Int(),i);
  2340 			test(EFalse);
  2341 			}
  2342 		}
  2343 
  2344 	test.Printf(_L("\n\r"));
  2345 
  2346 	RTimer tim;
  2347 	tim.CreateLocal();
  2348 	TRequestStatus timStat;
  2349 	tim.After(timStat,3000000);
  2350 	User::WaitForRequest(multiWriteStat,timStat);
  2351 	test(timStat==KRequestPending);
  2352 	tim.Cancel();
  2353 	User::WaitForRequest(timStat);
  2354 	test(timStat==KErrCancel);
  2355 	test(multiWriteStat==KErrNone);
  2356 	tim.After(timStat,3000000);
  2357 	User::WaitForRequest(multiReadStat,timStat);
  2358 	test(timStat==KRequestPending);
  2359 	tim.Cancel();
  2360 	tim.Close();
  2361 	User::WaitForRequest(timStat);
  2362 	test(timStat==KErrCancel);
  2363 	test(multiReadStat==KErrNone);
  2364 	test(multiCharWriteDes.Length()==multiCharWriteDes.MaxLength());
  2365 
  2366 	test.End();
  2367 
  2368 	delete [] multiCharWriteBuf;
  2369 	delete [] singleCharReadBuf;
  2370 	delete [] singleCharWriteBuf;
  2371 	delete [] multiCharReadBuf;
  2372 
  2373 	theSerialPorts[0]->Close();
  2374 	theSerialPorts[1]->Close();
  2375 	}
  2376 
  2377 void testMultiTerminatorCompletion()
  2378 //
  2379 // Test multiple terminator completions
  2380 //
  2381 	{
  2382 	test.Next(_L("Test partial reads with terminators"));
  2383 
  2384 	TInt r=theSerialPorts[0]->Open(PortA);
  2385 	test(r==KErrNone);
  2386 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2387 	test(r==0);
  2388 	r=theSerialPorts[1]->Open(PortB);
  2389 	test(r==KErrNone);
  2390 	r=theSerialPorts[1]->QueryReceiveBuffer();
  2391 	test(r==0);
  2392 
  2393 	TCommConfig cBuf0;
  2394 	TCommConfigV01& c0=cBuf0();
  2395 	theSerialPorts[0]->Config(cBuf0);
  2396 	TCommConfig cBuf1;
  2397 	TCommConfigV01& c1=cBuf1();
  2398 	theSerialPorts[1]->Config(cBuf1);
  2399 
  2400 	c0.iRate=c1.iRate=EBps9600;
  2401 	c0.iParityError=c1.iParityError=0;
  2402 
  2403 	c0.iHandshake=c1.iHandshake=KConfigObeyCTS;
  2404 
  2405 	c0.iDataBits=c1.iDataBits=EData8;
  2406 	c0.iStopBits=c1.iStopBits=EStop1;
  2407 	c0.iParity=c1.iParity=EParityNone;
  2408 
  2409 	r=theSerialPorts[0]->SetConfig(cBuf0);
  2410 	test(r==KErrNone);
  2411 	c1.iTerminator[0]='a';
  2412 	c1.iTerminatorCount=1;
  2413 	r=theSerialPorts[1]->SetConfig(cBuf1);
  2414 	test(r==KErrNone);
  2415 	const TInt KWriteSize=4000;
  2416 	TUint8* writeBuf=new TUint8[KWriteSize];
  2417 	test(writeBuf!=NULL);
  2418 	TPtr8 writeDes(writeBuf,KWriteSize,KWriteSize);
  2419 	writeDes.Fill('a');
  2420 	TUint8* readBuf=new TUint8[KWriteSize];
  2421 	test(readBuf!=NULL);
  2422 	TPtr8 readDes(readBuf,KWriteSize,KWriteSize);
  2423 	TRequestStatus writeStat;
  2424 	theSerialPorts[0]->Write(writeStat,writeDes);
  2425 	test(writeStat==KRequestPending);
  2426 	TInt spin=0;
  2427 	for (TInt i=0;i<KWriteSize;i++)
  2428 		{
  2429 		if (i%32==0)
  2430 			test.Printf(_L("\r%c"),KSpinner[spin++%4]);
  2431 		TRequestStatus readStat;
  2432 		readDes.SetLength(KWriteSize/2);
  2433 		theSerialPorts[1]->Read(readStat,readDes);
  2434 		User::WaitForRequest(readStat);
  2435 		test(readStat==KErrNone);
  2436 		test(readDes.Length()==1);
  2437 		}
  2438 	test.Printf(_L("\n\r"));
  2439 	User::WaitForRequest(writeStat);
  2440 
  2441 	delete [] readBuf;
  2442 	delete [] writeBuf;
  2443 
  2444 	theSerialPorts[0]->Close();
  2445 	theSerialPorts[1]->Close();
  2446 	}
  2447 
  2448 void TestSimpleWriting()
  2449 	{
  2450 	test.Next(_L("Test we can still write 0->1"));
  2451 	const TPtrC8 string1=_L8("If you strike me down, I shall become more powerful than you can possibly imagine.");
  2452 	TBuf8<100> inBuf;
  2453 	TRequestStatus stat;
  2454 	theSerialPorts[1]->Read(stat,inBuf,string1.Length());
  2455 	test(stat==KRequestPending);
  2456 	TInt r=theSerialPorts[0]->WriteS(string1,string1.Length());
  2457 	test(r==KErrNone);
  2458 	User::WaitForRequest(stat);
  2459 	test(stat==KErrNone);
  2460 	test(inBuf==string1);
  2461 
  2462 	test.Next(_L("Test we can still write 1->0"));
  2463 	const TPtrC8 string2=_L8("Who's the more foolish... the fool or the fool who follows him?");
  2464 	theSerialPorts[0]->Read(stat,inBuf,string2.Length());
  2465 	test(stat==KRequestPending);
  2466 	r=theSerialPorts[1]->WriteS(string2,string2.Length());
  2467 	test(r==KErrNone);
  2468 	User::WaitForRequest(stat);
  2469 	test(stat==KErrNone);
  2470 	test(inBuf==string2);
  2471 	}
  2472 
  2473 void TestPower()
  2474 	{
  2475 	test.Next(_L("Power up and down"));
  2476 
  2477 	TInt r=theSerialPorts[0]->Open(PortA);
  2478 	test(r==KErrNone);
  2479 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2480 	test(r==0);
  2481 	r=theSerialPorts[1]->Open(PortB);
  2482 	test(r==KErrNone);
  2483 	r=theSerialPorts[1]->QueryReceiveBuffer();
  2484 	test(r==0);
  2485 
  2486 	test.Start(_L("Power down while writing 0->1"));
  2487 	TCommConfig cBuf1;
  2488 	TCommConfigV01& c1=cBuf1();
  2489 	theSerialPorts[0]->Config(cBuf1);
  2490 	TCommConfig cBuf2;
  2491 	TCommConfigV01& c2=cBuf2();
  2492 	theSerialPorts[1]->Config(cBuf2);
  2493 	c1.iFifo=EFifoEnable;
  2494 
  2495 	c2.iDataBits=c1.iDataBits=EData8;
  2496 	c2.iStopBits=c1.iStopBits=EStop1;
  2497 	c2.iParity=c1.iParity=EParityEven;
  2498 	c1.iRate=c2.iRate=EBps19200;
  2499 	c1.iHandshake=c2.iHandshake=0;
  2500 
  2501 	r=theSerialPorts[0]->SetConfig(cBuf1);
  2502 	test(r==KErrNone);
  2503 	r=theSerialPorts[1]->SetConfig(cBuf2);
  2504 	test(r==KErrNone);
  2505 
  2506 	RTimer timer;
  2507 	test(timer.CreateLocal()==KErrNone);
  2508 	TTime wakeup;
  2509 	wakeup.HomeTime();
  2510 	wakeup+=TTimeIntervalSeconds(10);
  2511 	TRequestStatus done;
  2512 	timer.At(done,wakeup);
  2513 	test(done==KRequestPending);
  2514 	RAsyncSwitchOff async;
  2515 	r=async.Start(2000000);
  2516 	test(r==KErrNone);
  2517 
  2518 //	test(PowerCheckedWrite(KWriteSize*200)==KErrNone);
  2519 
  2520 	const TUint bigWriteSize=KWriteSize*200;
  2521 	TUint8* inBuf=new TUint8[bigWriteSize];
  2522 	test(inBuf!=NULL);
  2523 	TUint8* outBuf=new TUint8[bigWriteSize];
  2524 	test(outBuf!=NULL);
  2525 	TPtr8 outDes(outBuf,bigWriteSize,bigWriteSize);
  2526 	TPtr8 inDes(inBuf,bigWriteSize,bigWriteSize);
  2527 
  2528 	RTimer tim;
  2529 	tim.CreateLocal();
  2530 	TRequestStatus readStatus;
  2531 	TRequestStatus timeStatus;
  2532 
  2533 	StripeMem(outDes,'A','Z');
  2534 	inDes.FillZ();
  2535 
  2536 	theSerialPorts[0]->Read(readStatus,inDes,bigWriteSize);
  2537 	test(readStatus==KRequestPending);
  2538 
  2539 	test.Printf(_L("Write........."));
  2540 	r=theSerialPorts[1]->WriteS(outDes,bigWriteSize);
  2541 	test(r==KErrAbort);
  2542 	test.Printf(_L("Aborted by power down\n"));
  2543 	r=async.Wait();
  2544 	test(r==KErrNone);
  2545 	r=async.Start(2000000);
  2546 	test(r==KErrNone);
  2547 	const TUint KTimeOut=6000000;
  2548 	tim.After(timeStatus,KTimeOut);
  2549 	User::WaitForRequest(readStatus,timeStatus);
  2550 	if (timeStatus==KErrNone)
  2551 		{
  2552 		test.Printf(_L("Timed Out!\n\r"));
  2553 		theSerialPorts[0]->ReadCancel();
  2554 		test(EFalse);
  2555 		}
  2556 	tim.Cancel();
  2557 	test(readStatus==KErrAbort);
  2558 	r=async.Wait();
  2559 	test(r==KErrNone);
  2560 
  2561 	User::WaitForRequest(done);
  2562 	test(done==KErrNone);
  2563 
  2564 	test.Next(_L("Reset config"));
  2565 	TestSimpleWriting();
  2566 	test.Next(_L("Close and reopen"));
  2567 	theSerialPorts[0]->Close();
  2568 	theSerialPorts[1]->Close();
  2569 
  2570 	r=theSerialPorts[0]->Open(PortA);
  2571 	test(r==KErrNone);
  2572 	r=theSerialPorts[1]->Open(PortB);
  2573 	test(r==KErrNone);
  2574 
  2575 	theSerialPorts[0]->Config(cBuf1);
  2576 	theSerialPorts[1]->Config(cBuf2);
  2577 	c1.iFifo=EFifoEnable;
  2578 	c2.iDataBits=c1.iDataBits=EData8;
  2579 	c2.iStopBits=c1.iStopBits=EStop1;
  2580 	c2.iParity=c1.iParity=EParityNone;
  2581 	c1.iRate=c2.iRate=EBps19200;
  2582 	c1.iHandshake=c2.iHandshake=0;
  2583 
  2584 	r=theSerialPorts[0]->SetConfig(cBuf1);
  2585 	test(r==KErrNone);
  2586 	r=theSerialPorts[1]->SetConfig(cBuf2);
  2587 	test(r==KErrNone);
  2588 
  2589 	TestSimpleWriting();
  2590 
  2591 	test.Next(_L("Power down while writing 1->0"));
  2592 	theSerialPorts[0]->Config(cBuf1);
  2593 	theSerialPorts[1]->Config(cBuf2);
  2594 	c1.iFifo=EFifoEnable;
  2595 
  2596 	c2.iDataBits=c1.iDataBits=EData8;
  2597 	c2.iStopBits=c1.iStopBits=EStop1;
  2598 	c2.iParity=c1.iParity=EParityEven;
  2599 	c1.iRate=c2.iRate=EBps9600;
  2600 	c1.iHandshake=c2.iHandshake=0;
  2601 
  2602 	r=theSerialPorts[0]->SetConfig(cBuf1);
  2603 	test(r==KErrNone);
  2604 	r=theSerialPorts[1]->SetConfig(cBuf2);
  2605 	test(r==KErrNone);
  2606 
  2607 	wakeup.HomeTime();
  2608 	wakeup+=TTimeIntervalSeconds(10);
  2609 	timer.At(done,wakeup);
  2610 	test(done==KRequestPending);
  2611 	r=async.Start(2000000);
  2612 	test(r==KErrNone);
  2613 
  2614 //	test(PowerCheckedWrite(KWriteSize*200)==KErrNone);
  2615 	StripeMem(outDes,'A','Z');
  2616 	inDes.FillZ();
  2617 
  2618 	theSerialPorts[1]->Read(readStatus,inDes,bigWriteSize);
  2619 	test(readStatus==KRequestPending);
  2620 
  2621 	test.Printf(_L("Write........."));
  2622 	r=theSerialPorts[0]->WriteS(outDes,bigWriteSize);
  2623 	test(r==KErrAbort);
  2624 	test.Printf(_L("Aborted by power down\n"));
  2625 	tim.After(timeStatus,KTimeOut);
  2626 	User::WaitForRequest(readStatus,timeStatus);
  2627 	if (timeStatus==KErrNone)
  2628 		{
  2629 		test.Printf(_L("Timed Out!\n\r"));
  2630 		theSerialPorts[1]->ReadCancel();
  2631 		test(EFalse);
  2632 		}
  2633 	tim.Cancel();
  2634 	CHECK(readStatus.Int(),KErrAbort);
  2635 	r=async.Wait();
  2636 	test(r==KErrNone);
  2637 
  2638 	User::WaitForRequest(done);
  2639 	test(done==KErrNone);
  2640 
  2641 	test.Next(_L("Reset config"));
  2642 	TestSimpleWriting();
  2643 	test.Next(_L("Close and reopen"));
  2644 	theSerialPorts[0]->Close();
  2645 	theSerialPorts[1]->Close();
  2646 
  2647 	r=theSerialPorts[0]->Open(PortA);
  2648 	test(r==KErrNone);
  2649 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2650 	test(r==0);
  2651 	r=theSerialPorts[1]->Open(PortB);
  2652 	test(r==KErrNone);
  2653 	r=theSerialPorts[1]->QueryReceiveBuffer();
  2654 	test(r==0);
  2655 
  2656 	theSerialPorts[0]->Config(cBuf1);
  2657 	theSerialPorts[1]->Config(cBuf2);
  2658 	c1.iFifo=EFifoEnable;
  2659 	c2.iDataBits=c1.iDataBits=EData8;
  2660 	c2.iStopBits=c1.iStopBits=EStop1;
  2661 	c2.iParity=c1.iParity=EParityNone;
  2662 	c1.iRate=c2.iRate=EBps19200;
  2663 	c1.iHandshake=c2.iHandshake=0;
  2664 
  2665 	r=theSerialPorts[0]->SetConfig(cBuf1);
  2666 	test(r==KErrNone);
  2667 	r=theSerialPorts[1]->SetConfig(cBuf2);
  2668 	test(r==KErrNone);
  2669 
  2670 	TestSimpleWriting();
  2671 
  2672 	theSerialPorts[0]->Close();
  2673 	theSerialPorts[1]->Close();
  2674 
  2675 	test.Next(_L("Test signals are preserved"));
  2676 
  2677 	r=theSerialPorts[0]->Open(PortA);
  2678 	test(r==KErrNone);
  2679 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2680 	test(r==0);
  2681 	r=theSerialPorts[1]->Open(PortB);
  2682 	test(r==KErrNone);
  2683 	r=theSerialPorts[1]->QueryReceiveBuffer();
  2684 	test(r==0);
  2685 
  2686 	if((theCaps1.iHandshake & KCapsFreeRTSSupported) && (theCaps2.iHandshake & KCapsFreeRTSSupported))
  2687 		{//should also check for KConfigFreeDTR
  2688 		theSerialPorts[0]->Config(cBuf1);
  2689 		theSerialPorts[1]->Config(cBuf2);
  2690 
  2691 		c1.iHandshake=KConfigFreeRTS|KConfigFreeDTR;
  2692 		c2.iHandshake=KConfigFreeRTS|KConfigFreeDTR;
  2693 		r=theSerialPorts[0]->SetConfig(cBuf1);
  2694 		CHECK(r,KErrNone);
  2695 		r=theSerialPorts[1]->SetConfig(cBuf2);
  2696 		CHECK(r,KErrNone);
  2697 
  2698 		theSerialPorts[0]->SetSignals(KSignalRTS,KSignalDTR);
  2699 		theSerialPorts[1]->SetSignals(KSignalDTR,KSignalRTS);
  2700 
  2701 		TUint signals=theSerialPorts[0]->Signals();
  2702 		//test(signals==(KSignalRTS|KSignalDSR));//something weird happens here under WINS - the CD line is set(?)
  2703 		CHECK((signals&(KSignalRTS|KSignalDSR)) , (KSignalRTS|KSignalDSR));
  2704 		signals=theSerialPorts[1]->Signals();
  2705 		CHECK(signals,(KSignalDTR|KSignalCTS));
  2706 
  2707 		wakeup.HomeTime();
  2708 		wakeup+=TTimeIntervalSeconds(10);
  2709 		timer.At(done,wakeup);
  2710 		r=async.Start(5000000);
  2711 		CHECK(r,KErrNone);
  2712 		test(done==KRequestPending);
  2713 		User::WaitForRequest(done);
  2714 		test(done==KErrNone);
  2715 		r=async.Wait();
  2716 		CHECK(r,KErrNone);
  2717 
  2718 		User::After(100000);	// wait for both ports to power back up
  2719 		signals=theSerialPorts[0]->Signals();
  2720 		//test(signals==(KSignalRTS|KSignalDSR));
  2721 		CHECK((signals&(KSignalRTS|KSignalDSR)) , (KSignalRTS|KSignalDSR));
  2722 		signals=theSerialPorts[1]->Signals();
  2723 		CHECK(signals,(KSignalDTR|KSignalCTS));
  2724 		}
  2725 
  2726 	c1.iHandshake=0;
  2727 	c2.iHandshake=0;
  2728 	r=theSerialPorts[0]->SetConfig(cBuf1);
  2729 	test(r==KErrNone);
  2730 	r=theSerialPorts[1]->SetConfig(cBuf2);
  2731 	test(r==KErrNone);
  2732 
  2733 	theSerialPorts[0]->Close();
  2734 	theSerialPorts[1]->Close();
  2735 
  2736 	test.End();
  2737 	}
  2738 
  2739 void testSwitchIrDA()
  2740 	{
  2741 	test.Next(_L("Switch to IrDA"));
  2742 //Open the serial port channel.
  2743 
  2744 	TInt r=theSerialPorts[0]->Open(PortA);
  2745 	test(r==KErrNone);
  2746 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2747 	test(r==0);
  2748 
  2749 	theSerialPorts[0]->Caps(theCaps1Buf);
  2750 	if (!(theCaps1.iSIR&KCapsSIR115kbps))
  2751 		{
  2752 		theSerialPorts[0]->Close();
  2753 		test.Printf(_L("\t\tIrDA not supported\n"));
  2754 		return;
  2755 		}
  2756 
  2757 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2758 	test(r==0);
  2759 
  2760 
  2761 //Configure the channel for IrDA at 115.2k baud.
  2762 	TCommConfig cBuf1;
  2763 	TCommConfigV01& c1=cBuf1();
  2764 	theSerialPorts[0]->Config(cBuf1);
  2765 	c1.iSIREnable=ESIREnable;
  2766 	c1.iRate=EBps115200;
  2767 	c1.iDataBits=EData8;
  2768 	c1.iParity=EParityNone;
  2769 	c1.iStopBits=EStop1;
  2770 	c1.iHandshake=0;
  2771 	c1.iHandshake|=KConfigFreeDTR;
  2772 	c1.iHandshake|=KConfigFreeRTS;
  2773 	r=theSerialPorts[0]->SetConfig(cBuf1);
  2774 	test(r==KErrNone);
  2775 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2776 	test(r==0);
  2777 	const TUint8 KData[1] ={0x00};
  2778 	const TPtrC8 KDataPtr(KData,1);
  2779 	TRequestStatus stat;
  2780 	theSerialPorts[0]->Write(stat,KDataPtr);
  2781 	User::WaitForRequest(stat);
  2782 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2783 	test.Printf(_L("ReceiveBuf = %d\n"),r);
  2784 //	test(r==0);
  2785 
  2786 	theSerialPorts[0]->Write(stat,KDataPtr);
  2787 	User::WaitForRequest(stat);
  2788 	User::After(1000000);
  2789 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2790 	test.Printf(_L("ReceiveBuf = %d\n"),r);
  2791 	while (theSerialPorts[0]->QueryReceiveBuffer())
  2792 		{
  2793 		TBuf8<1> buf;
  2794 		theSerialPorts[0]->Read(stat,buf,1);
  2795 		test.Printf(_L("Data = "),&buf);
  2796 		User::WaitForRequest(stat);
  2797 		test.Printf(_L("%d\n"),buf[0]);
  2798 		}
  2799 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2800 	test.Printf(_L("ReceiveBuf = %d\n"),r);
  2801 	theSerialPorts[0]->Write(stat,KDataPtr);
  2802 	User::WaitForRequest(stat);
  2803 //Check for any received data pending (the answer is 1! Which is incorrect as nothing has sent me any IrDA data)
  2804 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2805 	test.Printf(_L("ReceiveBuf = %d\n"),r);
  2806 //	test(r==0);
  2807 	theSerialPorts[0]->Write(stat,KDataPtr);
  2808 	User::WaitForRequest(stat);
  2809 	User::After(1000000);
  2810 	r=theSerialPorts[0]->QueryReceiveBuffer();
  2811 
  2812 	theSerialPorts[0]->Close();
  2813 	}
  2814 
  2815 GLDEF_C TInt E32Main()
  2816 //
  2817 //
  2818 //
  2819     {
  2820 
  2821 #if defined (__WINS__)
  2822 	test.SetLogged(ETrue);	// log to $TEMP/EPOCWIND.OUT
  2823 #else
  2824 	test.SetLogged(EFalse);	//turn off serial port debugging!
  2825 #endif
  2826 
  2827 
  2828 	test.Title();
  2829 	test.Start(_L("Serial loopback test"));
  2830 
  2831 	TInt muid=0;
  2832 	test(HAL::Get(HAL::EMachineUid, muid)==KErrNone);
  2833 //CF
  2834 	TBool isAssabet=(muid==HAL::EMachineUid_Assabet);
  2835 
  2836 	PortA=0;
  2837 	PortB=3; // used to be 1 but it apparently doesn't exist
  2838 	TBuf <0x100> cmd;
  2839 	User::CommandLine(cmd);
  2840 
  2841 	TBool stress = EFalse;
  2842 	if (cmd.Length()>0)
  2843 		{
  2844 		if (cmd.Length() == 1)
  2845 			{
  2846 			if ((cmd[0] == 'S') || (cmd[0] == 's'))
  2847 				stress = ETrue;
  2848 			}
  2849 		else
  2850 			{
  2851 			if (cmd[0]>='0' && cmd[0]<='9')
  2852 				PortA=(TInt)(cmd[0]-'0');
  2853 			if (cmd[2]>='0' && cmd[2]<='9')
  2854 				PortB=(TInt)(cmd[2]-'0');
  2855 			if ((cmd[cmd.Length()-1] == 'S') || (cmd[cmd.Length()-1] == 's'))
  2856 				stress = ETrue;
  2857 			}
  2858 		}
  2859 
  2860 
  2861 	test.Printf(_L("Primary Port:%d Secondary Port:%d\n\r"),PortA,PortB);
  2862 
  2863 
  2864 	TInt r;
  2865     TBuf<10> pddName=PDD_NAME;
  2866 	test.Next(_L("Load PDDs"));
  2867 #ifdef __WINS__
  2868 	const TInt KMaxPdds=0;
  2869 #else
  2870 	const TInt KMaxPdds=10;
  2871 #endif
  2872 	TInt i;
  2873 	for (i=-1; i<KMaxPdds; ++i)
  2874 		{
  2875 		if (i==0)
  2876 			pddName.Append(TChar('0'));
  2877 		else if (i>0)
  2878 			pddName[pddName.Length()-1] = (TText)('0'+i);
  2879 		r=User::LoadPhysicalDevice(pddName);
  2880 		if (r==KErrNone || r==KErrAlreadyExists)
  2881 			test.Printf(_L("PDD %S loaded\n"),&pddName);
  2882 		}
  2883 
  2884 	test.Next(_L("Load LDD"));
  2885 	r=User::LoadLogicalDevice(LDD_NAME);
  2886 	test.Printf(_L("Load LDD Return %d\n\r"),r);
  2887 
  2888 	test.Next(_L("Create RComm objects"));
  2889 	theSerialPorts[0]=new RComm;
  2890 	theSerialPorts[1]=new RComm;
  2891 	test(theSerialPorts[0]!=NULL);
  2892 	test(theSerialPorts[1]!=NULL);
  2893 //
  2894 
  2895 	do
  2896 		{		
  2897 
  2898 		test.Next(_L("Open:"));
  2899 		r=theSerialPorts[0]->Open(PortA);
  2900 		test.Printf(_L("Open(Unit0)=%d\n\r"),r);
  2901 		test(r==KErrNone);
  2902 		r=theSerialPorts[1]->Open(PortB);
  2903 		test.Printf(_L("Open(Unit1)=%d\n\r"),r);
  2904 		test(r==KErrNone);
  2905 
  2906 		test.Next(_L("Get caps"));
  2907 		theSerialPorts[0]->Caps(theCaps1Buf);
  2908 		test(r==KErrNone);
  2909 		theSerialPorts[1]->Caps(theCaps2Buf);
  2910 		test(r==KErrNone);
  2911 
  2912 		theSerialPorts[0]->Close();
  2913 		theSerialPorts[1]->Close();
  2914 
  2915 		testReadWrite();
  2916 
  2917 		// testTiming();
  2918 
  2919 		turnaroundTestReadWrite();
  2920 
  2921 		testTerminators();
  2922 		testHWHandshaking();
  2923 
  2924 		if((theCaps1.iHandshake & KCapsObeyXoffSupported) && (theCaps2.iHandshake & KCapsObeyXoffSupported))
  2925 			testXonXoff();
  2926 
  2927 		if((theCaps1.iHandshake & KCapsObeyCTSSupported) && (theCaps2.iHandshake & KCapsObeyCTSSupported))
  2928 			{
  2929 			testSingleCharacterReads();
  2930 			testWriteZero();
  2931 	//CF - see description of problem with testTerminators()
  2932 			if (!isAssabet) testMultiTerminatorCompletion();
  2933 			testBiDirectionalSingleCharacterReads();
  2934 			}
  2935 
  2936 		testFraming();
  2937 		testBreak();
  2938 		testSwitchIrDA();
  2939 		} while (stress);
  2940 
  2941 	User::After(3000000);
  2942 	test.End();
  2943 	return(KErrNone);
  2944 	}