applayerprotocols/telnetengine/TTELNET/TTELNET.CPP
changeset 0 b16258d2340f
equal deleted inserted replaced
-1:000000000000 0:b16258d2340f
       
     1 // Copyright (c) 1998-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 "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 //
       
    15 
       
    16 // Tiny Telnet - A simple telnet client to test CTelnetSession API
       
    17 #include "TTELNET.H"
       
    18 //#include <debug.h>
       
    19 
       
    20 
       
    21 // Device driver names
       
    22 #if defined (__WINS__)
       
    23 #define PDD_NAME _L("ECDRV")
       
    24 #define LDD_NAME _L("ECOMM")
       
    25 #else
       
    26 #define PDD_NAME _L("EUART1")
       
    27 #define LDD_NAME _L("ECOMM")
       
    28 #endif
       
    29 
       
    30 static CConsoleBase* console;
       
    31 
       
    32 
       
    33 
       
    34 LOCAL_C void CommInitL()
       
    35 //
       
    36 // Initialisation code - loads the serial LDD and PDD
       
    37 // starts the comm subsystem (for EPOC32 builds)
       
    38 // On a full EPOC implementation, this code would not
       
    39 // be required because higher level components (EIKON) 
       
    40 // automatically start the services.
       
    41 //
       
    42 	{
       
    43 	// Load the physical device driver
       
    44 	// The OS will automatically append .PDD and 
       
    45 	// search /System/Libs on all drives.
       
    46 	TInt r=User::LoadPhysicalDevice(PDD_NAME);
       
    47 	if (r != KErrNone && r!= KErrAlreadyExists)
       
    48 		User::Leave(r);
       
    49 	//test(r==KErrNone || r==KErrAlreadyExists);
       
    50 
       
    51 	// Similarly for the Logical device driver
       
    52 	r=User::LoadLogicalDevice(LDD_NAME);
       
    53 	if (r != KErrNone && r != KErrAlreadyExists)
       
    54 		User::Leave(r);
       
    55 	//test(r==KErrNone|| r==KErrAlreadyExists);
       
    56 
       
    57 	}
       
    58 
       
    59 
       
    60 
       
    61 void DriveEngineL();
       
    62 void SetupConsoleL();
       
    63 
       
    64 GLDEF_C TInt E32Main() // main function called by E32
       
    65     {
       
    66 	__UHEAP_MARK;
       
    67 	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
       
    68 	TRAPD(error,SetupConsoleL()); // more initialization, then do example
       
    69 	__ASSERT_ALWAYS(!error,User::Panic(_L("TTiny Telnet"),error));
       
    70 	delete cleanup; // destroy clean-up stack
       
    71 	
       
    72 	__UHEAP_MARKEND;
       
    73 	return 0; // and return
       
    74     }
       
    75 
       
    76 void SetupConsoleL() // initialize and call example code under cleanup stack
       
    77     {
       
    78 	console=Console::NewL(_L("Tiny Telnet"),
       
    79 		TSize(KDefaultConsWidth,KDefaultConsHeight));
       
    80 	CleanupStack::PushL(console);
       
    81 	TRAPD(error,DriveEngineL()); // perform example function
       
    82 	if (error) console->Printf(_L("failed: leave code=%d"), error);
       
    83 	else console->Printf(_L("ok"));
       
    84 	console->Printf(_L(" [press any key]"));
       
    85 	console->Getch(); // get and ignore character
       
    86 	CleanupStack::PopAndDestroy(); // close console
       
    87     }
       
    88 
       
    89 /*
       
    90 	TTelnet Test code starts here
       
    91 */
       
    92 
       
    93 void DriveEngineL()
       
    94 	{
       
    95 
       
    96 	//initialization for COMM port 
       
    97 	CommInitL();
       
    98 	
       
    99 	// Setup Active Scheduler
       
   100 	CActiveScheduler* myActiveScheduler = new(ELeave) CActiveScheduler;
       
   101 	CleanupStack::PushL(myActiveScheduler);
       
   102 	CActiveScheduler::Install(myActiveScheduler);
       
   103 
       
   104 	// Create Tiny Telnet
       
   105 	CTinyTelnet* aTinyTelnet = CTinyTelnet::NewLC(console);
       
   106 	//.. and post request to object
       
   107 	aTinyTelnet->RequestCharacter();
       
   108 
       
   109 	myActiveScheduler->Start();
       
   110 
       
   111 	CleanupStack::PopAndDestroy(2); //aTinyTelnet, myActiveScheduler	
       
   112 	}
       
   113 
       
   114 CTinyTelnet::CTinyTelnet() : CActiveConsole (EPriorityStandard)
       
   115 	{
       
   116 	}
       
   117 
       
   118 CTinyTelnet::~CTinyTelnet() 
       
   119 	{
       
   120 	delete iTelnetSession;
       
   121 	delete iCommandLine;
       
   122 	}
       
   123 
       
   124 CTinyTelnet* CTinyTelnet::NewLC(CConsoleBase* aConsole)
       
   125 	{
       
   126 	CTinyTelnet* self = new (ELeave) CTinyTelnet();
       
   127     CleanupStack::PushL(self);
       
   128 	self->ConstructL(aConsole);
       
   129 	return self;
       
   130 	}
       
   131 
       
   132 void CTinyTelnet::ConstructL(CConsoleBase* aConsole)
       
   133 	{
       
   134 	CActiveConsole::ConstructL(aConsole);
       
   135 
       
   136 	iState = EComplete;
       
   137 	iLocalEcho = FALSE;
       
   138 	iBinaryOnOff = FALSE;
       
   139 
       
   140 	iCommandLine=CLineEdit::NewL(iConsole,10);
       
   141 	// TODO 
       
   142 	// Modify iTelnetConfig members here for different speed window size etc
       
   143 //	iConfig.iTermType = _L8("vt100");
       
   144 	iConfig.iServerEcho = TRUE;
       
   145 	iTelnetSession = CTelnetSession::NewL(iConfig,this);
       
   146 	iConsole->Printf(_L("'<ESC>' for command prompt\n"));
       
   147 	};
       
   148 
       
   149 void CTinyTelnet::Error(TInt aError)
       
   150 	{
       
   151 	iConsole->Printf(_L("Error(%d)\n"),aError);
       
   152 	}
       
   153 
       
   154 void CTinyTelnet::ReadComplete(const TDesC8& aBuffer)
       
   155 	{
       
   156 	// I know the driver won't chuck more than 128 bytes at us
       
   157 	// The real code should use variable descriptors on the heap
       
   158 	TBuf<128> tmpBuffer;
       
   159 	// For unicode, use the overloaded copy
       
   160 	tmpBuffer.Copy(aBuffer);
       
   161 	iConsole->Printf(_L("%S"),&tmpBuffer);
       
   162 	Read();
       
   163 	}
       
   164 
       
   165 void CTinyTelnet::WriteComplete()
       
   166 	{
       
   167 	// Request another character
       
   168 	RequestCharacter();
       
   169 	return;
       
   170 	}
       
   171 
       
   172 void CTinyTelnet::ConnectionClosed()
       
   173 	{
       
   174 	iState = EDisconnected;
       
   175 	iConsole->Printf(_L("ConnectionClosed()\n"));
       
   176 	}
       
   177 
       
   178 void CTinyTelnet::OptionsChanged()
       
   179 	{
       
   180 	TOptionStatus status;
       
   181 	if(iState != EConnected)
       
   182 		{
       
   183 		iConsole->Printf(_L("No Connection , status not valid\n"));
       
   184 		}
       
   185 	else
       
   186 		iTelnetSession->OptionStatus(status);
       
   187 	}
       
   188 
       
   189 void CTinyTelnet::Connected()
       
   190 	{
       
   191 	iConsole->Printf(_L("Connected()"));
       
   192 	Read();
       
   193 	iState = EConnected;
       
   194 	}
       
   195 
       
   196 void CTinyTelnet::DisplayOptionStates()
       
   197 // It's debatable whether a user would ever want to see this stuff
       
   198 // It's just here as demo of the call
       
   199 	{
       
   200 	if(iState != EConnected)
       
   201 		{
       
   202 		iConsole->Printf(_L("No Connection , status not valid\n"));
       
   203 		}
       
   204 	else
       
   205 		{
       
   206 		TOptionStatus aStatus;
       
   207 		iTelnetSession->OptionStatus(aStatus);
       
   208 
       
   209 		iConsole->Printf(_L("Server Send   Binary         Option = %d\n"),aStatus.iServerBinary);
       
   210 		iConsole->Printf(_L("Client Send   Binary         Option = %d\n"),aStatus.iClientBinary);
       
   211 		iConsole->Printf(_L("Server Echo   Data           Option = %d\n"),aStatus.iEcho);
       
   212 		iConsole->Printf(_L("Client Supply Window Size    Option = %d\n"),aStatus.iNAWS);
       
   213 		iConsole->Printf(_L("Client Supply Terminal Speed Option = %d\n"),aStatus.iTerminalSpeed);
       
   214 		iConsole->Printf(_L("Client Supply Terminal Type  Option = %d\n"),aStatus.iTerminalType);
       
   215 		iConsole->Printf(_L("Server Supply Status         Option = %d\n"),aStatus.iServerStatus);
       
   216 		iConsole->Printf(_L("Client Supply Status         Option = %d\n"),aStatus.iClientStatus);
       
   217 		}
       
   218 	}
       
   219 
       
   220 void CTinyTelnet::ProcessKeyPress(TChar aChar)
       
   221 	{
       
   222 	if (aChar != EKeyEscape)
       
   223 		{
       
   224 		// Send input Character to echo host
       
   225 		if(Write(aChar) != KErrNone)
       
   226 			{
       
   227 			RequestCharacter();
       
   228 			}
       
   229 		else
       
   230 			{
       
   231 			if(iLocalEcho)
       
   232 				iConsole->Printf(_L("%C"), TUint(aChar));
       
   233 			}
       
   234 		}
       
   235 	else
       
   236 		{
       
   237 		if(DoCommand())
       
   238 			RequestCharacter();
       
   239 		}
       
   240 	}
       
   241 
       
   242 TBool CTinyTelnet::DoCommand()
       
   243 // Handle command strings from the user
       
   244 // Demo only
       
   245 	{
       
   246 	iCommandLine->Edit(_L("\nTinyTelnet>"), &iCommand);
       
   247 
       
   248 	// Seperate Command from Command Arguments.
       
   249 	TInt commandEnd;
       
   250 	TBuf<80> commandArgs;
       
   251 	TBool ret = TRUE;
       
   252 
       
   253 	iCommand.TrimAll();  // Remove leading/trailing/double white spaces              
       
   254 	
       
   255 	commandEnd = iCommand.Locate(' ');
       
   256 
       
   257 	if ( (commandEnd != iCommand.Length()) && (commandEnd != KErrNotFound) )
       
   258 		{
       
   259 		commandArgs = iCommand.Mid(commandEnd+1);
       
   260 		iCommand.SetLength(commandEnd);	
       
   261 		}
       
   262 	
       
   263 	if(iCommand.Length()==0) 
       
   264 		Cancel(); // do nothing
       
   265 	else if ( iCommand.MatchF(_L("open")) == 0 )
       
   266 		// Attempt to open a telnet session
       
   267 		Open(commandArgs);
       
   268 	else if ( iCommand.MatchF(_L("status")) == 0 )
       
   269 		{
       
   270 		// Display the state of the Telnet RFC options
       
   271 		DisplayOptionStates();
       
   272 		}
       
   273 	else if ( iCommand.MatchF(_L("openip")) == 0 )
       
   274 		// Other open
       
   275 		OpenIP(commandArgs);
       
   276 	else if ( iCommand.MatchF(_L("close")) == 0 )
       
   277 		// Close a connection
       
   278 		Close(commandArgs);
       
   279 	else if ( iCommand.MatchF(_L("help")) == 0 )
       
   280 		Help(commandArgs);
       
   281 	else if ( iCommand.MatchF(_L("echo")) == 0 )
       
   282 		{
       
   283 		// Toggle local echo
       
   284 		LocalEcho(commandArgs);
       
   285 		(iConfig.iServerEcho == TRUE) ? (iConfig.iServerEcho = FALSE) : (iConfig.iServerEcho = TRUE);
       
   286 		iTelnetSession->DoModifyConfig(iConfig);
       
   287 		}
       
   288 	else if ( iCommand.MatchF(_L("Logout")) == 0 )
       
   289 		// Force Telnet level logout to the host ,host could refuse 
       
   290 		iTelnetSession->DoForceLogout();
       
   291 	else if ( iCommand.MatchF(_L("AllowLogout")) == 0 )
       
   292 		// Demo only Toggle allow server to logout option
       
   293 		{
       
   294 		(iConfig.iAllowLogout == TRUE) ? (iConfig.iAllowLogout = FALSE) : (iConfig.iAllowLogout = TRUE);
       
   295 		iTelnetSession->DoModifyConfig(iConfig);
       
   296 		}
       
   297 	else if ( iCommand.MatchF(_L("Window")) == 0)
       
   298 		// Demo only, changes the window size
       
   299 		{
       
   300 		iConfig.iWindowSize.x = 60;
       
   301 		iConfig.iWindowSize.y = 20;
       
   302 		iTelnetSession->DoModifyConfig(iConfig);
       
   303 		}
       
   304 	else if ( iCommand.MatchF(_L("Speed")) == 0)
       
   305 		// Demo only, sets the speed
       
   306 		{
       
   307 		iConfig.iTermSpeed = _L8("9600");
       
   308 		iTelnetSession->DoModifyConfig(iConfig);
       
   309 		}
       
   310 	else if ( iCommand.MatchF(_L("Type")) == 0)
       
   311 		// Demo only, changes the terminal type
       
   312 		// See API document implementation of terminal type configuration
       
   313 		{
       
   314 		iConfig.iTermType = _L8("vt100");
       
   315 		iTelnetSession->DoModifyConfig(iConfig);
       
   316 		}
       
   317 
       
   318 	else if(iCommand.MatchF(_L("exit")) == 0)
       
   319 		{
       
   320 		// Clean exit, all destructors called
       
   321 		ret = FALSE;
       
   322 		CActiveScheduler::Stop();
       
   323 		}
       
   324 	else
       
   325 		{
       
   326 		iConsole->Printf(_L("command = %S.\n"),&iCommand);
       
   327 		iConsole->Printf(_L("unknown command\n"));
       
   328 		}
       
   329 	return ret;
       
   330 	}
       
   331 
       
   332 void CTinyTelnet::DoCancel()
       
   333 	{
       
   334 
       
   335 	}
       
   336 
       
   337 void CTinyTelnet::Open(TDesC& aCommandArg)
       
   338 	{
       
   339 	TInt err;
       
   340 	iCommandArg = aCommandArg;
       
   341 	err = iTelnetSession->Connect(iCommandArg);
       
   342 	if(err != KErrNone)
       
   343 		iState = EConnecting;
       
   344 	iConsole->Printf(_L("Connect returned - %d\n"), err);
       
   345 	}
       
   346 
       
   347 void CTinyTelnet::Help(TDesC& /*aCommandArg*/)
       
   348 	{
       
   349 	iConsole->Printf(_L("\nHelp\n"));
       
   350 	iConsole->Printf(_L("----\n\n"));
       
   351 	iConsole->Printf(_L(" <esc>				   - command prompt\n"));
       
   352 	iConsole->Printf(_L(" open <server>		   - connect to server on telnet port 23\n"));
       
   353 	iConsole->Printf(_L(" openip <aa.bb.cc.dd> - connect to server on telnet port 23\n"));
       
   354 	iConsole->Printf(_L(" close                - disconnect connection\n"));
       
   355 	iConsole->Printf(_L(" echo                 - toggle local echo on/off\n"));
       
   356 	iConsole->Printf(_L(" status               - print option status\n\n"));
       
   357 	}
       
   358 
       
   359 void CTinyTelnet::LocalEcho(TDesC& /*aCommandArg*/)
       
   360 	{
       
   361 	iLocalEcho = (!iLocalEcho);
       
   362 	}
       
   363 
       
   364 void CTinyTelnet::Logout(TDesC& /*aCommandArg*/)
       
   365 	{
       
   366 	iTelnetSession->DoForceLogout();
       
   367 	}
       
   368 
       
   369 void CTinyTelnet::OpenIP(TDesC& aCommandArg)
       
   370 	{
       
   371 	TInt err;
       
   372 	iAddress.Input(aCommandArg);	// Accepts a, a.b, a.b.c, a.b.c.d or 0xaabbccdd
       
   373 	err = iTelnetSession->Connect(iAddress);
       
   374 	iConsole->Printf(_L("Connect returned - %d\n"), err);
       
   375 	}
       
   376 
       
   377 void CTinyTelnet::Read()
       
   378 	{
       
   379 	iTelnetSession->Read();
       
   380 	}
       
   381 
       
   382 
       
   383 TInt CTinyTelnet::Write(TChar aChar)
       
   384 // Write characters to the Server
       
   385 // For Demo, we are trapping :-
       
   386 // CTRL+A AO  (Abort Output)
       
   387 // CTRL+B AYT (Are You There)
       
   388 // CTRL+C IP  (Interrupt Process)
       
   389 // CTRL+D EC  (Erase Character, NVT only)
       
   390 // CTRL+E EL  (Erase Line, NVT only)
       
   391 // CTRL+F BRK (Break)
       
   392 	{
       
   393 
       
   394 	TInt ret = KErrNone;
       
   395 	TTelnetUserControl code;
       
   396 	if (iState==EConnected)
       
   397 		{
       
   398 		TBuf8<10> buffer;
       
   399 		buffer.SetLength(0);
       
   400 
       
   401 		if(aChar == 1)
       
   402 			{
       
   403 			// ABORT OUTPUT
       
   404 			code = EAo;
       
   405 			ret = iTelnetSession->Write(code);
       
   406 			}
       
   407 		else if(aChar == 2)
       
   408 			{
       
   409 			// ARE YOU THERE
       
   410 			code = EAyt;
       
   411 			ret = iTelnetSession->Write(code);
       
   412 			}
       
   413 		else if(aChar == 3)
       
   414 			{
       
   415 			// INTERRUPT PROCESS
       
   416 			code = EIp;
       
   417 			ret = iTelnetSession->Write(code);
       
   418 			}
       
   419 		else if(aChar == 4)
       
   420 			{
       
   421 			// ERASE CHARACTER
       
   422 			code = EEc;
       
   423 			ret = iTelnetSession->Write(code);
       
   424 			}
       
   425 		else if(aChar == 5)
       
   426 			{
       
   427 			// ERASE LINE
       
   428 			code = EEl;
       
   429 			ret = iTelnetSession->Write(code);
       
   430 			}
       
   431 		else if(aChar == 6)
       
   432 			{
       
   433 			// BREAK
       
   434 			code = EBrk;
       
   435 			ret = iTelnetSession->Write(code);
       
   436 			}
       
   437 		else
       
   438 			{
       
   439 			buffer.Append(aChar);
       
   440 			ret = iTelnetSession->Write(buffer);
       
   441 			}
       
   442 		
       
   443 		
       
   444 		//iConsole->Printf(_L("Write returned - (%d)\n"), err);
       
   445 		}
       
   446 	else
       
   447 		{
       
   448 		ret = KErrDisconnected;
       
   449 		iConsole->Printf(_L("Not connected [write failed]\n"));
       
   450 		}
       
   451 	return ret;
       
   452 	}
       
   453 
       
   454 void CTinyTelnet::Close(TDesC& /*aCommandArg*/)
       
   455 	{
       
   456 	TInt err;
       
   457 	err = iTelnetSession->Disconnect();
       
   458 	iConsole->Printf(_L("Disconnect returned - %d\n"), err);
       
   459 	}
       
   460 
       
   461 
       
   462 //
       
   463 // CActiveConsole Implementation
       
   464 //
       
   465 void CActiveConsole::ConstructL(CConsoleBase* aConsole)
       
   466 	{
       
   467 	iConsole = aConsole;
       
   468 	CActiveScheduler::Add(this);
       
   469 	}
       
   470 
       
   471 CActiveConsole::~CActiveConsole()
       
   472 	{
       
   473 	Cancel();
       
   474 	}
       
   475 
       
   476 void CActiveConsole::RequestCharacter()
       
   477 	{
       
   478 	__ASSERT_DEBUG(!IsActive(), User::Panic(_L("CActiveConsole::RequestCharacter()"), KRequestPending));
       
   479 	iConsole->Read(iStatus);
       
   480 	SetActive();
       
   481 	}
       
   482 
       
   483 void CActiveConsole::RunL()
       
   484 	{
       
   485 	ProcessKeyPress(TChar(iConsole->KeyCode()));
       
   486 	}
       
   487 
       
   488 void CActiveConsole::DoCancel()
       
   489 	{
       
   490 	iConsole->ReadCancel();
       
   491 	}