os/kernelhwsrv/kerneltest/e32test/device/t_term.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_term.cpp
    15 // T_TERM.CPP - Dumb terminal
    16 // 
    17 //
    18 
    19 #define VERBOSE
    20 #define _PC_CARD_SERIAL
    21 
    22 #include <e32test.h>
    23 #include <e32twin.h>
    24 #include <d32comm.h>
    25 #include <f32file.h>
    26 
    27 void StartLoader();
    28 
    29 const TPtrC KCaptureFileName=_L("C:\\CAPTURE.TXT");
    30 const TPtrC KUploadFileName=_L("Z:\\UPLOAD.TXT");
    31 RFs TheFs;
    32 RFile TheCaptureFile;
    33 RFile TheUploadFile;
    34 
    35 RChunk TheCaptureChunk;
    36 TPtr8 TheCapturedText(NULL,0,0);
    37 
    38 TBuf8<1024> ch;
    39 TBuf8<1024> chw;
    40 TBuf<1024>	buf;
    41 TCommConfig TheConfigBuf;
    42 TCommConfigV01 &TheConfig=TheConfigBuf();
    43 TInt TheLastError=KErrNone;
    44 
    45 const TInt KMaxDumpLength=0x100;
    46 
    47 enum TTermPanic
    48 	{
    49 	EStraySignal,
    50 	ELoadPhysicalDeviceErr,
    51 	ELoadLogicalDeviceErr,
    52 	EOpenErr,
    53 	EConnectFsErr,
    54 	ECaptureFileOpen,
    55 	EOpenUploadFile,
    56 	EChunkCreateErr,
    57 	};
    58 
    59 enum TRxMode
    60 	{
    61 	ENormal=0,
    62 	ELoopBack=1,
    63 	ECountChars=2,
    64 	ECapture=128,
    65 	};
    66 
    67 struct SSettings
    68 	{
    69 	TBool iNotFinished;
    70 	TBool iLocalEcho;
    71 	TInt iAddLF;
    72 	TBool iDump;
    73 	TInt iDumpRepeat;
    74 	TBuf8<KMaxDumpLength> iDumpData;
    75 	TRxMode iRxMode;
    76 	TInt iCharCount;
    77 	TInt iMaxInOne;
    78 	TInt iInfraRed;
    79 	TBool iWaitAfterWrite;
    80 	// Fifo
    81 	// Brk
    82 	};
    83 
    84 LOCAL_D SSettings TheSettings;
    85 LOCAL_D RBusDevComm TheCommPort;
    86 LOCAL_D RConsole TheWindow;
    87 
    88 LOCAL_C TInt CommWriteSync(RBusDevComm &aComm, const TDesC8 &aData)
    89 	{
    90 	TRequestStatus stat;
    91 	aComm.Write(stat, aData);
    92 	User::WaitForRequest(stat);
    93 	return stat.Int();
    94 	}
    95 
    96 LOCAL_C TInt WaitAfterWrite(RBusDevComm& aComm)
    97 	{
    98 	TRequestStatus s;
    99 	TBuf8<1> b;
   100 	aComm.Write(s,b);
   101 	User::WaitForRequest(s);
   102 	return s.Int();
   103 	}
   104 
   105 LOCAL_C TInt RateToInt(TBps aRate)
   106 //
   107 //
   108 //
   109 	{
   110 
   111 	switch (aRate)
   112 		{
   113 	case EBps230400:	return 230400;
   114 	case EBps115200:	return 115200;
   115     case EBps57600:	return 57600;
   116     case EBps38400:	return 38400;
   117     case EBps19200:	return 19200;
   118     case EBps9600:	return 9600;
   119 	case EBps7200:	return 7200;
   120     case EBps4800:	return 4800;
   121 	case EBps3600:	return 3600;
   122     case EBps2400:	return 2400;
   123 	case EBps2000:	return 2000;
   124 	case EBps1800:	return 1800;
   125     case EBps1200:	return 1200;
   126     case EBps600:	return 600;
   127     case EBps300:	return 300;
   128     case EBps150:	return 150;
   129 	case EBps134:	return 134;
   130     case EBps110:	return 110;
   131 	case EBps75:	return 75;
   132 	case EBps50:	return 50;
   133 	default:	return -1;
   134 		}
   135 	}
   136 
   137 LOCAL_C TBps IntToRate(TInt aVal)
   138 //
   139 //
   140 //
   141 	{
   142 
   143 	if (aVal>=230400) return EBps230400;
   144 	if (aVal>=115200) return EBps115200;
   145 	if (aVal>=57600) return EBps57600;
   146 	if (aVal>=38400) return EBps38400;
   147 	if (aVal>=19200) return EBps19200;
   148 	if (aVal>=9600) return EBps9600;
   149 	if (aVal>=7200) return EBps7200;
   150 	if (aVal>=4800) return EBps4800;
   151 	if (aVal>=3600) return EBps3600;
   152 	if (aVal>=2400) return EBps2400;
   153 	if (aVal>=2000) return EBps2000;
   154 	if (aVal>=1800) return EBps1800;
   155 	if (aVal>=1200) return EBps1200;
   156 	if (aVal>=600) return EBps600;
   157 	if (aVal>=300) return EBps300;
   158 	if (aVal>=150) return EBps150;
   159 	if (aVal>=134) return EBps134;
   160 	if (aVal>=110) return EBps110;
   161 	if (aVal>=75) return EBps75;
   162 	if (aVal>=50) return EBps50;
   163 	return EBps50;
   164 	}
   165 
   166 LOCAL_C void ConfigString(TDes &aBuf, const TCommConfigV01 &aConfig, const SSettings &aSettings)
   167 //
   168 //	Construct a Configuaration string
   169 //
   170 	{
   171 
   172 	// Config
   173 	aBuf.Format(_L(" %d "), RateToInt(aConfig.iRate));
   174 	switch (aConfig.iParity)
   175 		{
   176 	case EParityEven: aBuf.Append(_L("E")); break;
   177 	case EParityOdd: aBuf.Append(_L("O")); break;
   178 	case EParityNone: aBuf.Append(_L("N")); break;
   179     default: break;
   180 		}
   181 	switch (aConfig.iDataBits)
   182 		{
   183 	case EData5: aBuf.Append(_L("5")); break;
   184 	case EData6: aBuf.Append(_L("6")); break;
   185 	case EData7: aBuf.Append(_L("7")); break;
   186 	case EData8: aBuf.Append(_L("8")); break;
   187     default: break;
   188 		}
   189 	if (aConfig.iStopBits==EStop1)
   190 		aBuf.Append(_L("1 "));
   191 	else
   192 		aBuf.Append(_L("2 "));
   193 
   194 	aBuf.Append(_L("Use:"));
   195 	if (aConfig.iHandshake==0)
   196 		aBuf.Append(_L("NoControl "));
   197 	if (aConfig.iHandshake&(KConfigObeyXoff|KConfigSendXoff))
   198 		aBuf.Append(_L("XonXoff "));
   199 	if (aConfig.iHandshake&KConfigObeyCTS)
   200 		aBuf.Append(_L("CTS/RTS "));
   201 	if (aConfig.iHandshake&KConfigObeyDSR)
   202 		aBuf.Append(_L("DSR/DTR "));
   203 	if (aConfig.iHandshake&KConfigWriteBufferedComplete)
   204 		aBuf.Append(_L("Early "));
   205 	//|KConfigObeyDCD|KConfigFailDCD|))
   206 
   207 
   208 //	if (aConfig.iBreak==TEiger::EBreakOn)
   209 //		aBuf.Append(_L(" Brk"));
   210 	if (aConfig.iFifo==EFifoEnable)
   211 		aBuf.Append(_L(" Fifo"));
   212 	
   213 	// Settings
   214 	if (aSettings.iLocalEcho)
   215 		aBuf.Append(_L("LocalEcho "));
   216 	if (aSettings.iAddLF)
   217 		aBuf.Append(_L("AddLF "));
   218 	if ((aSettings.iRxMode&~ECapture)==ELoopBack)
   219 		aBuf.Append(_L("LpBk"));
   220 	else if ((aSettings.iRxMode&~ECapture)==ECountChars)
   221 		aBuf.Append(_L("CtCh"));
   222 	aBuf.Append(_L(" "));
   223 	aBuf.AppendNum((TInt)(RThread().Priority()));
   224 	if (aSettings.iInfraRed==1)
   225 		aBuf.Append(_L("IR1"));
   226 	else if (aSettings.iInfraRed==2)
   227 		aBuf.Append(_L("IR2"));
   228 	if (aSettings.iWaitAfterWrite)
   229 		aBuf.Append(_L("Wait"));
   230 
   231 	aBuf.Append(_L("Last Err: "));
   232 	if (TheLastError==KErrNone)
   233 		aBuf.Append(_L("None "));
   234 	else if (TheLastError==KErrCommsLineFail)
   235 		aBuf.Append(_L("LineFail "));
   236 	else if (TheLastError==KErrCommsFrame)
   237 		aBuf.Append(_L("Frame "));
   238 	else if (TheLastError==KErrCommsOverrun)
   239 		aBuf.Append(_L("Overrun "));
   240 	else if (TheLastError==KErrCommsParity)
   241 		aBuf.Append(_L("Parity "));
   242 	else if (TheLastError==KErrAbort)
   243 		aBuf.Append(_L("Abort "));
   244 	else if (TheLastError==KErrBadPower)
   245 		aBuf.Append(_L("BadPower "));
   246 	else if (TheLastError==KErrNotReady)
   247 		aBuf.Append(_L("NotReady "));
   248 	else
   249 		aBuf.AppendNum(TheLastError);
   250 	}
   251 
   252 LOCAL_C void GetRate(TBps &aRate, const TDesC &aDes)
   253 //
   254 //	Set Baud rate
   255 //
   256 	{
   257 
   258 	TInt32 i;
   259 	if (TLex(aDes).Val(i)==KErrNone)
   260 		aRate=IntToRate(i);
   261 	}
   262 
   263 LOCAL_C void GetParity(TParity &aParity, const TDesC &aDes)
   264 //
   265 //
   266 //
   267 	{
   268 
   269 	if (aDes.FindF(_L("O"))>=0)
   270 		aParity=EParityOdd;
   271   	if (aDes.FindF(_L("E"))>=0)
   272 		aParity=EParityEven;
   273 	if (aDes.FindF(_L("N"))>=0)
   274 		aParity=EParityNone;
   275 	}
   276 
   277 LOCAL_C void GetHandshake(TUint &aHandshake, const TDesC &aDes)
   278 //
   279 //
   280 //
   281 	{
   282 
   283 	if (aDes.FindF(_L("N"))>=0)
   284 		aHandshake=0;
   285 	if (aDes.FindF(_L("X"))>=0)
   286 		aHandshake=KConfigObeyXoff|KConfigSendXoff;
   287 	if (aDes.FindF(_L("C"))>=0)
   288 		aHandshake=KConfigObeyCTS;
   289 	if (aDes.FindF(_L("D"))>=0)
   290 		aHandshake=KConfigObeyDSR|KConfigFreeRTS;
   291 	if (aDes.FindF(_L("E"))>=0)
   292 		aHandshake|=KConfigWriteBufferedComplete;
   293 	}
   294 
   295 LOCAL_C void GetStopBit(TStopBits &aStop, const TDesC &aDes)
   296 	{
   297 
   298 	TInt32 in;
   299 	if (TLex(aDes).Val(in)==KErrNone)
   300 		{
   301 		if (in==1)
   302 			aStop=EStop1;
   303 		if (in==2)
   304 			aStop=EStop2;
   305 		}
   306 	else
   307 		{
   308 		if (aStop==EStop1)
   309 			aStop=EStop2;
   310 		else
   311 			aStop=EStop1;
   312 		}
   313 	}
   314 
   315 LOCAL_C void GetLength(TDataBits &aData, const TDesC &aDes)
   316 	{
   317 
   318 	TInt32 in;
   319 	if (TLex(aDes).Val(in)==KErrNone)
   320 		{
   321 		switch (in)
   322 			{
   323 		case 5: aData=EData5; break;
   324 		case 6: aData=EData6; break;
   325 		case 7: aData=EData7; break;
   326 		case 8: aData=EData8; break;
   327 		default: break;
   328 			}
   329 		}
   330 	}
   331 
   332 LOCAL_C void GetInfraRedMode(TInt &aInfraRed, const TDesC &aDes)
   333 	{
   334 
   335 	if (aDes.FindF(_L("0"))>=0)
   336 		aInfraRed=0;
   337 	else if (aDes.FindF(_L("1"))>=0)
   338 		aInfraRed=1;
   339 	else if (aDes.FindF(_L("2"))>=0)
   340 		aInfraRed=2;
   341 	}
   342 
   343 LOCAL_C void GetWaitMode(TBool &aWait, const TDesC &aDes)
   344 	{
   345 
   346 	if (aDes.FindF(_L("0"))>=0)
   347 		aWait=EFalse;
   348 	else if (aDes.FindF(_L("1"))>=0)
   349 		aWait=ETrue;
   350 	}
   351 
   352 /*LOCAL_C void GetBreak(const TDesC &aDes)
   353 	{
   354 
   355 	if (aDes==_L(""))
   356 		{
   357 		if (data.iBreak==TEiger::EBreakOn)
   358 			data.iBreak=TEiger::EBreakOff;
   359 		else
   360 			data.iBreak=TEiger::EBreakOn;
   361 		}
   362 	if (aDes.FindF(_L("N"))>=0)
   363 		data.iBreak=TEiger::EBreakOn;
   364 	if (aDes.FindF(_L("F"))>=0)
   365 		data.iBreak=TEiger::EBreakOff;
   366 	SetConfig();
   367 	}
   368 */
   369 LOCAL_C void GetFifo(TUint& aFifo, const TDesC &aDes)
   370 	{
   371 
   372 	if (aDes==_L(""))
   373 		{
   374 		if (aFifo==EFifoEnable)
   375 			aFifo=EFifoDisable;
   376 		else
   377 			aFifo=EFifoEnable;
   378 		}
   379 	if (aDes.FindF(_L("N"))>=0)
   380 		aFifo=EFifoEnable;
   381 	if (aDes.FindF(_L("F"))>=0)
   382 		aFifo=EFifoDisable;
   383 	}
   384 
   385 LOCAL_C void GetEcho(TBool &aEcho, const TDesC &aDes)
   386 	{
   387 
   388 	if (aDes==_L(""))
   389 		{
   390 		if (aEcho)
   391 			aEcho=EFalse;
   392 		else
   393 			aEcho=ETrue;
   394 		}
   395 	if (aDes.FindF(_L("N"))>=0)
   396 		aEcho=ETrue;
   397 	if (aDes.FindF(_L("F"))>=0)
   398 		aEcho=EFalse;
   399 	}
   400 
   401 LOCAL_C void GetRxMode(TRxMode &aMode, const TDesC &aDes)
   402 	{
   403 
   404 	if (aDes.FindF(_L("N"))>=0)
   405 		aMode=ENormal;
   406 	if (aDes.FindF(_L("L"))>=0)
   407 		aMode=ELoopBack;
   408 	if (aDes.FindF(_L("C"))>=0)
   409 		aMode=ECountChars;
   410 	if (aDes.FindF(_L("S"))>=0)
   411 		{
   412 		aMode=TRxMode(TInt(aMode)|ECapture);
   413 //		TInt r=TheCaptureFile.Create(TheFs,KCaptureFileName,EFileWrite);
   414 //		if (r!=KErrNone)
   415 //			User::Panic(_L("T_TERM CAP"),r);
   416 		}
   417 	if (aDes.FindF(_L("Z"))>=0)
   418 		{
   419 		aMode=TRxMode(TInt(aMode)&~ECapture);
   420 //		TheCaptureFile.Close();
   421 		}
   422 	if (aDes.FindF(_L("0"))>=0)
   423 		RThread().SetPriority(EPriorityNormal);
   424 	if (aDes.FindF(_L("1"))>=0)
   425 		RThread().SetPriority(EPriorityAbsoluteHigh);
   426 	}
   427 
   428 LOCAL_C void GetDump(SSettings &aSettings, const TDesC &aDes)
   429 	{
   430 	
   431 	TInt32 in;
   432 	if (TLex(aDes).Val(in)==KErrNone)
   433 		{
   434 		aSettings.iDump=ETrue;
   435 		aSettings.iDumpRepeat=in;
   436 		return;
   437 		}
   438 	if (aDes.Length()!=0)
   439 		{
   440 		TBuf8<16> b=_L8("0123456789ABCDEF");
   441 		aSettings.iDumpData.Zero();
   442 		TInt i;
   443 		for (i=0; i<16; i++)
   444 			aSettings.iDumpData+=b;
   445 		return;
   446 		}
   447 	RConsole dialog;
   448 	TInt r=dialog.Init(_L("Type data to dump to comm.  Escape to finish"),TSize(KConsFullScreen,KConsFullScreen));
   449 	r=dialog.Control(_L("+Maximize +NewLine"));
   450 	aSettings.iDumpData=_L8("");
   451 	TConsoleKey k;
   452 	do 
   453 		{
   454 		dialog.Read(k);
   455 		if (k.Code()==EKeyEscape)
   456 			break;
   457 		TText a=(TText)k.Code();
   458 		TPtrC s(&a,1);
   459 		dialog.Write(s);
   460 		aSettings.iDumpData.Append(k.Code());
   461 		//if (a=='\r')
   462 		//	dialog.Write(_L("\n"));
   463 		} while (aSettings.iDumpData.Length()<KMaxDumpLength);
   464 
   465 	dialog.Destroy();
   466 	dialog.Close();
   467 	}
   468 
   469 
   470 
   471 LOCAL_C void CommandWindow(TCommConfigV01 &aConfig, SSettings &aSettings)
   472 //
   473 //	Display some words of wisdom and get a command from the user
   474 //
   475 	{
   476 
   477 	TBuf<32> b;
   478 	b.Num(aSettings.iCharCount);
   479 	b+=_L(" ");
   480 	b.AppendNum(aSettings.iMaxInOne);
   481 	b+=_L("\n");
   482 	RConsole dialog;
   483 	TInt r=dialog.Init(_L("."),TSize(KConsFullScreen,KConsFullScreen));
   484 	r=dialog.Control(_L("+Maximize +NewLine"));
   485 	dialog.Write(_L("B<n> Set Bps to n               P[Odd|Even|None] Set Parity\n"));
   486 	dialog.Write(_L("S[1|2] Set/Toggle stop bits     L<n> Set Data Length (5<=n<=8)\n"));
   487 	dialog.Write(_L("K[On|Off] Set/Toggle BRK        F[On|Off] Set/Toggle Fifo\n"));
   488 	dialog.Write(_L("H[None|X|CtsRts|DsrDtr] Handshaking\n"));
   489 	dialog.Write(_L("D[<n>] Set data or Dump data n times\n"));
   490  	dialog.Write(_L("J Toggle Add Line Feed          E Toggle local Echo\n"));
   491 	dialog.Write(_L("U [NLC] Set Rx Mode\n"));
   492 	dialog.Write(b);
   493 	dialog.Write(_L("Q Quit\n"));
   494 	dialog.Write(_L("\n:"));
   495 
   496 	//	Get a command
   497 	TBuf<0x80> des=_L("");
   498 	TConsoleKey k;
   499 	dialog.Read(k);
   500 	while ((k.Code()!='\r') && (k.Code()!=EKeyEscape))
   501 		{
   502 		TText a=(TText)k.Code();
   503 		TPtrC s(&a,1);
   504 		dialog.Write(s);
   505 		des.Append(k.Code());
   506 		dialog.Read(k);
   507 		}
   508 
   509 	if (k.Code()!=EKeyEscape && des.Length()>0)
   510 		{
   511 		des.UpperCase();
   512 		TBuf<0x80> right(des.Right(des.Length()-1));
   513 		if (des[0]=='B')
   514 			GetRate(aConfig.iRate, right);
   515 		if (des[0]=='P')
   516 			GetParity(aConfig.iParity, right);
   517 		if (des[0]=='S')
   518 			GetStopBit(aConfig.iStopBits, right);
   519 		if (des[0]=='L')
   520 			GetLength(aConfig.iDataBits, right);
   521 //		if (des[0]=='K')
   522 //			GetBreak(aSettings.iBreak, right);
   523 		if (des[0]=='F')
   524 			GetFifo(aConfig.iFifo, right);
   525 		if (des[0]=='I')
   526 			GetInfraRedMode(aSettings.iInfraRed, right);
   527 		if (aSettings.iInfraRed==1)
   528 			{
   529 			aConfig.iSIREnable=ESIREnable;
   530 			aConfig.iSIRSettings=KConfigSIRPulseWidthMinimum;
   531 			}
   532 		else if (aSettings.iInfraRed==2)
   533 			{
   534 			aConfig.iSIREnable=ESIREnable;
   535 			aConfig.iSIRSettings=KConfigSIRPulseWidthMaximum;
   536 			}
   537 		else
   538 			{
   539 			aConfig.iSIREnable=ESIRDisable;
   540 			aConfig.iSIRSettings=0;
   541 			}
   542 		if (des[0]=='H')
   543 			GetHandshake(aConfig.iHandshake, right);
   544 		if (des[0]=='E')
   545 			GetEcho(aSettings.iLocalEcho, right);
   546 		if (des[0]=='D')
   547 			GetDump(aSettings, right);
   548 		if (des[0]=='J')
   549 			aSettings.iAddLF=!aSettings.iAddLF;
   550 		if (des[0]=='U')
   551 			{
   552 			GetRxMode(aSettings.iRxMode, right);
   553 			aSettings.iCharCount=0;
   554 			aSettings.iMaxInOne=0;
   555 			}
   556 		if (des[0]=='Q')
   557 			aSettings.iNotFinished=EFalse;
   558 		if (des[0]=='W')
   559 			GetWaitMode(aSettings.iWaitAfterWrite, right);
   560 		}
   561 
   562 	dialog.Destroy();
   563 	dialog.Close();
   564 	}
   565 
   566 // The following decl is a hack for the Eiger build.
   567 // Without it T_TERM.EXE has no .data or .bss section.  This means the data offset
   568 // field in the file header is zero.  When the kernel comes to copy the data sections
   569 // from rom into ram it reads the data size field (which is the size of all data
   570 // sections) from the header and tries to copy data from 0x00000000 (the data offset),
   571 // causing a data abort.
   572 TInt dummy=10;	 
   573 #if defined (__WINS__)
   574 #define PDD_NAME _L("ECDRV")
   575 #define LDD_NAME _L("ECOMM")
   576 #else
   577 #define PDD_NAME _L("EUART")
   578 #define LDD_NAME _L("ECOMM")
   579 #endif
   580 
   581 LOCAL_C void ProcessError(TInt anError)
   582 	{
   583 	TBuf<80> buf;
   584 	if (anError!=KErrNone)
   585 		{
   586 		TheLastError=anError;
   587 		ConfigString(buf, TheConfig, TheSettings);
   588 		TheWindow.SetTitle(buf);
   589 		}
   590 	}
   591 
   592 LOCAL_C void HandleRx(TRequestStatus& aStatus, TBool /*aFinish*/)
   593 	{
   594 	chw.Copy(ch);
   595 	switch(TheSettings.iRxMode & ~ECapture)
   596 		{
   597 		case ENormal:
   598 			{
   599 			buf.Copy(chw);
   600 			TheWindow.Write(buf);
   601 			break;
   602 			}
   603 		case ELoopBack:
   604 			{
   605 			ProcessError(CommWriteSync(TheCommPort,chw));
   606 			if (TheSettings.iWaitAfterWrite)
   607 				ProcessError(WaitAfterWrite(TheCommPort));
   608 			break;
   609 			}
   610 		case ECountChars:
   611 			{
   612 			TInt l=chw.Length();
   613 			TheSettings.iCharCount+=l;
   614 			if (l>TheSettings.iMaxInOne)
   615 				TheSettings.iMaxInOne=l;
   616 			break;
   617 			}
   618 		}
   619 	if ((TheSettings.iRxMode & ECapture)!=0 && TheCaptureChunk.Handle()!=0)
   620 		{
   621 //		TheCaptureFile.Write(chw);
   622 		TInt newLen=TheCapturedText.Length()+chw.Length();
   623 		TheCaptureChunk.Adjust(newLen);
   624 		TheCapturedText.Append(chw);
   625 		}
   626 //	if ((TheSettings.iRxMode & ~ECapture)==ELoopBack && !aFinish)
   627 //		TheCommPort.Read(aStatus, ch);
   628 //	else
   629 		TheCommPort.ReadOneOrMore(aStatus, ch);
   630 	}
   631 
   632 LOCAL_C TInt LoadDeviceDrivers()
   633 //
   634 // Load ECOMM.LDD and all PDDs with name EUART?.PDD
   635 //
   636 	{
   637 	TInt c=0;
   638 	TInt r;
   639 	TInt i;
   640 	TFileName n=PDD_NAME;
   641 	r=User::LoadPhysicalDevice(n);
   642 	if (r==KErrNone || r==KErrAlreadyExists)
   643 		c++;
   644 	n+=_L("0");
   645 	TInt p=n.Length()-1;
   646 	for (i=0; i<10; i++)
   647 		{
   648 		n[p]=TText('0'+i);
   649 		r=User::LoadPhysicalDevice(n);
   650 		if (r==KErrNone || r==KErrAlreadyExists)
   651 			c++;
   652 		}
   653 	r=User::LoadLogicalDevice(LDD_NAME);
   654 	if (r==KErrNone || r==KErrAlreadyExists)
   655 		c++;
   656 	return c;
   657 	}
   658 
   659 GLDEF_C TInt E32Main()
   660 //
   661 // Term
   662 //
   663     {
   664 
   665 	// Open the window asap
   666 	TheWindow.Init(_L("TERM"),TSize(KConsFullScreen,KConsFullScreen));
   667 
   668 	// Initialisation
   669 	TInt r=TheFs.Connect();
   670 	if (r!=KErrNone)
   671 		User::Panic(_L("T_TERM"), EConnectFsErr);
   672 
   673 	TBuf<256> cmd;
   674 	User::CommandLine(cmd);
   675 	TInt port=0;
   676 	if (cmd.Length()>0 && cmd[0]>='0' && cmd[0]<='9')
   677 		port=cmd[0]-'0';
   678 
   679 	// Load Device Drivers
   680 	TConsoleKey keystroke;
   681 	TInt nDeviceDrivers=LoadDeviceDrivers();
   682 	if (nDeviceDrivers<2)
   683 		{
   684 #if defined (VERBOSE)
   685 		TBuf<32> outBuf;
   686 		outBuf.AppendFormat(_L("Failed(0) 0x%X\n\r"),r);
   687 		TheWindow.Write(outBuf);
   688 		TheWindow.Read(keystroke);
   689 #endif
   690 		User::Panic(_L("T_TERM"), ELoadPhysicalDeviceErr);
   691 		}
   692 
   693 	r=TheCaptureChunk.CreateLocal(0x1000,0x1000000);		// 16Mb
   694 	if (r!=KErrNone)
   695 		r=TheCaptureChunk.CreateLocal(0x1000,0x100000);		// 1Mb
   696 	if (r!=KErrNone)
   697 		TheCaptureChunk.SetHandle(0);
   698 	else
   699 		TheCapturedText.Set(TheCaptureChunk.Base(),0,0x1000000);
   700 
   701 	TheSettings.iNotFinished=ETrue;
   702 	TheSettings.iLocalEcho=ETrue;
   703 	TheSettings.iAddLF=FALSE;
   704 	TheSettings.iDump=EFalse;
   705 	TheSettings.iDumpRepeat=1;
   706 	TheSettings.iDumpData=_L8("Some Text\r");
   707 	TheSettings.iRxMode=ENormal;
   708 	TheSettings.iCharCount=0;
   709 	TheSettings.iMaxInOne=0;
   710 	TheSettings.iInfraRed=0;
   711 	TheSettings.iWaitAfterWrite=EFalse;
   712 	
   713 	// Comms Config
   714 	r=TheCommPort.Open(port); // Comm port
   715 	if (r!=KErrNone)
   716 		User::Panic(_L("T_TERM"), EOpenErr);
   717 
   718 	TheCommPort.Config(TheConfigBuf);	// get config
   719 	TheConfig.iHandshake=0; //KConfigObeyXoff|KConfigSendXoff;
   720 	TheCommPort.SetConfig(TheConfigBuf);
   721 	TheCommPort.SetReceiveBufferLength(8192);
   722 
   723 	//	Set up a console window
   724 	TheWindow.Control(_L("+Maximize +Newline"));
   725 	TheWindow.Write(_L("= for command\n"));
   726 	TBuf<0x80> buf;
   727 	ConfigString(buf, TheConfig, TheSettings);
   728 	TheWindow.SetTitle(buf);
   729 
   730 	TConsoleKey k;
   731 	TRequestStatus readStat, keyStat;
   732 
   733 	// main loop
   734 	TheWindow.Read(k, keyStat);
   735 	TheCommPort.ReadOneOrMore(readStat, ch);
   736 	do
   737 		{
   738 		User::WaitForRequest(readStat, keyStat);
   739 		if (keyStat!=KRequestPending)
   740 			{
   741 			TKeyCode c=k.Code();
   742 			if (c<256 && c!='=' && c!='\x15' && c!='\x3' && c!='\x12' && c!='\x18')
   743 				{
   744 				TText8 a8=(TText8)c;
   745 				TText a=(TText)c;
   746 				TPtrC8 s8(&a8,1);
   747 				TPtrC s(&a,1);
   748 				ProcessError(CommWriteSync(TheCommPort, s8));
   749 				if (TheSettings.iWaitAfterWrite)
   750 					ProcessError(WaitAfterWrite(TheCommPort));
   751 				if (TheSettings.iLocalEcho)
   752 					{
   753 					TheWindow.Write(s);
   754 					if (c=='\r' && TheSettings.iAddLF) TheWindow.Write(_L("\n"));
   755 					}
   756 				}
   757 			if (c=='\x3')
   758 				{
   759 				TheCommPort.ReadCancel();
   760 				HandleRx(readStat,ETrue);
   761 				}
   762 			else if (c=='=')
   763 				{
   764 				CommandWindow(TheConfig, TheSettings);
   765 				TheCommPort.ReadCancel();
   766 				TheCommPort.SetConfig(TheConfigBuf);
   767 				TheCommPort.ReadOneOrMore(readStat, ch);
   768 				ConfigString(buf, TheConfig, TheSettings);
   769 				TheWindow.SetTitle(buf);
   770 				}
   771 			else if (c=='\x15')
   772 				{
   773 				TInt r=TheUploadFile.Open(TheFs,KUploadFileName,EFileRead);
   774 				if (r!=KErrNone)
   775 					User::Panic(_L("T_TERM"),EOpenUploadFile);
   776 				TBuf8<0x100> buf;
   777 				do	{
   778 					TheUploadFile.Read(buf);
   779 					ProcessError(CommWriteSync(TheCommPort,buf));
   780 					if (TheSettings.iWaitAfterWrite)
   781 						ProcessError(WaitAfterWrite(TheCommPort));
   782 					} while(buf.Length()!=0);
   783 				TheUploadFile.Close();
   784 				}
   785 			else if (c=='\x12')
   786 				{
   787 //				TInt i=0;
   788 //				TInt len=TheCapturedText.Length();
   789 //				while(i<len)
   790 //					{
   791 //					TInt l=Min(0x100,len-i);
   792 //					TPtrC8 p(TheCapturedText.Ptr()+i,l);
   793 //					ProcessError(CommWriteSync(TheCommPort,p));
   794 //					if (TheSettings.iWaitAfterWrite)
   795 //						ProcessError(WaitAfterWrite(TheCommPort));
   796 //					i+=l;
   797 //					}
   798 				if (TheCaptureChunk.Handle())
   799 					{
   800 					ProcessError(CommWriteSync(TheCommPort,TheCapturedText));
   801 					if (TheSettings.iWaitAfterWrite)
   802 						ProcessError(WaitAfterWrite(TheCommPort));
   803 					}
   804 				}
   805 			else if (c=='\x18')
   806 				{
   807 				if (TheCaptureChunk.Handle())
   808 					TheCapturedText.Zero();
   809 				}
   810 			TheWindow.Read(k, keyStat);
   811 			}
   812 		else if (readStat!=KRequestPending)
   813 			{
   814 			ProcessError(readStat.Int());
   815 			if (readStat!=KErrAbort && readStat!=KErrBadPower && readStat!=KErrNotReady)
   816 				HandleRx(readStat,EFalse);
   817 			else
   818 				TheCommPort.ReadOneOrMore(readStat, ch);
   819 			}
   820 		else
   821 			{
   822 			User::Panic(_L("T_TERM"), EStraySignal);
   823 			}
   824 
   825 		if (TheSettings.iDump)
   826 			{
   827 			TheSettings.iDump=EFalse;
   828 			TInt i;
   829 			for (i=0; i<TheSettings.iDumpRepeat; i++)
   830 				{
   831 				ProcessError(CommWriteSync(TheCommPort, TheSettings.iDumpData));
   832 				if (TheSettings.iWaitAfterWrite)
   833 					ProcessError(WaitAfterWrite(TheCommPort));
   834 				}
   835 			}
   836 		} while(TheSettings.iNotFinished);
   837 
   838 	TheWindow.Destroy();
   839 	TheWindow.Close();
   840 	TheCommPort.Close();
   841 	return(KErrNone);
   842     }
   843