--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/telnetengine/TTELNET/TTELNET.CPP Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,491 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+// Tiny Telnet - A simple telnet client to test CTelnetSession API
+#include "TTELNET.H"
+//#include <debug.h>
+
+
+// Device driver names
+#if defined (__WINS__)
+#define PDD_NAME _L("ECDRV")
+#define LDD_NAME _L("ECOMM")
+#else
+#define PDD_NAME _L("EUART1")
+#define LDD_NAME _L("ECOMM")
+#endif
+
+static CConsoleBase* console;
+
+
+
+LOCAL_C void CommInitL()
+//
+// Initialisation code - loads the serial LDD and PDD
+// starts the comm subsystem (for EPOC32 builds)
+// On a full EPOC implementation, this code would not
+// be required because higher level components (EIKON)
+// automatically start the services.
+//
+ {
+ // Load the physical device driver
+ // The OS will automatically append .PDD and
+ // search /System/Libs on all drives.
+ TInt r=User::LoadPhysicalDevice(PDD_NAME);
+ if (r != KErrNone && r!= KErrAlreadyExists)
+ User::Leave(r);
+ //test(r==KErrNone || r==KErrAlreadyExists);
+
+ // Similarly for the Logical device driver
+ r=User::LoadLogicalDevice(LDD_NAME);
+ if (r != KErrNone && r != KErrAlreadyExists)
+ User::Leave(r);
+ //test(r==KErrNone|| r==KErrAlreadyExists);
+
+ }
+
+
+
+void DriveEngineL();
+void SetupConsoleL();
+
+GLDEF_C TInt E32Main() // main function called by E32
+ {
+ __UHEAP_MARK;
+ CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
+ TRAPD(error,SetupConsoleL()); // more initialization, then do example
+ __ASSERT_ALWAYS(!error,User::Panic(_L("TTiny Telnet"),error));
+ delete cleanup; // destroy clean-up stack
+
+ __UHEAP_MARKEND;
+ return 0; // and return
+ }
+
+void SetupConsoleL() // initialize and call example code under cleanup stack
+ {
+ console=Console::NewL(_L("Tiny Telnet"),
+ TSize(KDefaultConsWidth,KDefaultConsHeight));
+ CleanupStack::PushL(console);
+ TRAPD(error,DriveEngineL()); // perform example function
+ if (error) console->Printf(_L("failed: leave code=%d"), error);
+ else console->Printf(_L("ok"));
+ console->Printf(_L(" [press any key]"));
+ console->Getch(); // get and ignore character
+ CleanupStack::PopAndDestroy(); // close console
+ }
+
+/*
+ TTelnet Test code starts here
+*/
+
+void DriveEngineL()
+ {
+
+ //initialization for COMM port
+ CommInitL();
+
+ // Setup Active Scheduler
+ CActiveScheduler* myActiveScheduler = new(ELeave) CActiveScheduler;
+ CleanupStack::PushL(myActiveScheduler);
+ CActiveScheduler::Install(myActiveScheduler);
+
+ // Create Tiny Telnet
+ CTinyTelnet* aTinyTelnet = CTinyTelnet::NewLC(console);
+ //.. and post request to object
+ aTinyTelnet->RequestCharacter();
+
+ myActiveScheduler->Start();
+
+ CleanupStack::PopAndDestroy(2); //aTinyTelnet, myActiveScheduler
+ }
+
+CTinyTelnet::CTinyTelnet() : CActiveConsole (EPriorityStandard)
+ {
+ }
+
+CTinyTelnet::~CTinyTelnet()
+ {
+ delete iTelnetSession;
+ delete iCommandLine;
+ }
+
+CTinyTelnet* CTinyTelnet::NewLC(CConsoleBase* aConsole)
+ {
+ CTinyTelnet* self = new (ELeave) CTinyTelnet();
+ CleanupStack::PushL(self);
+ self->ConstructL(aConsole);
+ return self;
+ }
+
+void CTinyTelnet::ConstructL(CConsoleBase* aConsole)
+ {
+ CActiveConsole::ConstructL(aConsole);
+
+ iState = EComplete;
+ iLocalEcho = FALSE;
+ iBinaryOnOff = FALSE;
+
+ iCommandLine=CLineEdit::NewL(iConsole,10);
+ // TODO
+ // Modify iTelnetConfig members here for different speed window size etc
+// iConfig.iTermType = _L8("vt100");
+ iConfig.iServerEcho = TRUE;
+ iTelnetSession = CTelnetSession::NewL(iConfig,this);
+ iConsole->Printf(_L("'<ESC>' for command prompt\n"));
+ };
+
+void CTinyTelnet::Error(TInt aError)
+ {
+ iConsole->Printf(_L("Error(%d)\n"),aError);
+ }
+
+void CTinyTelnet::ReadComplete(const TDesC8& aBuffer)
+ {
+ // I know the driver won't chuck more than 128 bytes at us
+ // The real code should use variable descriptors on the heap
+ TBuf<128> tmpBuffer;
+ // For unicode, use the overloaded copy
+ tmpBuffer.Copy(aBuffer);
+ iConsole->Printf(_L("%S"),&tmpBuffer);
+ Read();
+ }
+
+void CTinyTelnet::WriteComplete()
+ {
+ // Request another character
+ RequestCharacter();
+ return;
+ }
+
+void CTinyTelnet::ConnectionClosed()
+ {
+ iState = EDisconnected;
+ iConsole->Printf(_L("ConnectionClosed()\n"));
+ }
+
+void CTinyTelnet::OptionsChanged()
+ {
+ TOptionStatus status;
+ if(iState != EConnected)
+ {
+ iConsole->Printf(_L("No Connection , status not valid\n"));
+ }
+ else
+ iTelnetSession->OptionStatus(status);
+ }
+
+void CTinyTelnet::Connected()
+ {
+ iConsole->Printf(_L("Connected()"));
+ Read();
+ iState = EConnected;
+ }
+
+void CTinyTelnet::DisplayOptionStates()
+// It's debatable whether a user would ever want to see this stuff
+// It's just here as demo of the call
+ {
+ if(iState != EConnected)
+ {
+ iConsole->Printf(_L("No Connection , status not valid\n"));
+ }
+ else
+ {
+ TOptionStatus aStatus;
+ iTelnetSession->OptionStatus(aStatus);
+
+ iConsole->Printf(_L("Server Send Binary Option = %d\n"),aStatus.iServerBinary);
+ iConsole->Printf(_L("Client Send Binary Option = %d\n"),aStatus.iClientBinary);
+ iConsole->Printf(_L("Server Echo Data Option = %d\n"),aStatus.iEcho);
+ iConsole->Printf(_L("Client Supply Window Size Option = %d\n"),aStatus.iNAWS);
+ iConsole->Printf(_L("Client Supply Terminal Speed Option = %d\n"),aStatus.iTerminalSpeed);
+ iConsole->Printf(_L("Client Supply Terminal Type Option = %d\n"),aStatus.iTerminalType);
+ iConsole->Printf(_L("Server Supply Status Option = %d\n"),aStatus.iServerStatus);
+ iConsole->Printf(_L("Client Supply Status Option = %d\n"),aStatus.iClientStatus);
+ }
+ }
+
+void CTinyTelnet::ProcessKeyPress(TChar aChar)
+ {
+ if (aChar != EKeyEscape)
+ {
+ // Send input Character to echo host
+ if(Write(aChar) != KErrNone)
+ {
+ RequestCharacter();
+ }
+ else
+ {
+ if(iLocalEcho)
+ iConsole->Printf(_L("%C"), TUint(aChar));
+ }
+ }
+ else
+ {
+ if(DoCommand())
+ RequestCharacter();
+ }
+ }
+
+TBool CTinyTelnet::DoCommand()
+// Handle command strings from the user
+// Demo only
+ {
+ iCommandLine->Edit(_L("\nTinyTelnet>"), &iCommand);
+
+ // Seperate Command from Command Arguments.
+ TInt commandEnd;
+ TBuf<80> commandArgs;
+ TBool ret = TRUE;
+
+ iCommand.TrimAll(); // Remove leading/trailing/double white spaces
+
+ commandEnd = iCommand.Locate(' ');
+
+ if ( (commandEnd != iCommand.Length()) && (commandEnd != KErrNotFound) )
+ {
+ commandArgs = iCommand.Mid(commandEnd+1);
+ iCommand.SetLength(commandEnd);
+ }
+
+ if(iCommand.Length()==0)
+ Cancel(); // do nothing
+ else if ( iCommand.MatchF(_L("open")) == 0 )
+ // Attempt to open a telnet session
+ Open(commandArgs);
+ else if ( iCommand.MatchF(_L("status")) == 0 )
+ {
+ // Display the state of the Telnet RFC options
+ DisplayOptionStates();
+ }
+ else if ( iCommand.MatchF(_L("openip")) == 0 )
+ // Other open
+ OpenIP(commandArgs);
+ else if ( iCommand.MatchF(_L("close")) == 0 )
+ // Close a connection
+ Close(commandArgs);
+ else if ( iCommand.MatchF(_L("help")) == 0 )
+ Help(commandArgs);
+ else if ( iCommand.MatchF(_L("echo")) == 0 )
+ {
+ // Toggle local echo
+ LocalEcho(commandArgs);
+ (iConfig.iServerEcho == TRUE) ? (iConfig.iServerEcho = FALSE) : (iConfig.iServerEcho = TRUE);
+ iTelnetSession->DoModifyConfig(iConfig);
+ }
+ else if ( iCommand.MatchF(_L("Logout")) == 0 )
+ // Force Telnet level logout to the host ,host could refuse
+ iTelnetSession->DoForceLogout();
+ else if ( iCommand.MatchF(_L("AllowLogout")) == 0 )
+ // Demo only Toggle allow server to logout option
+ {
+ (iConfig.iAllowLogout == TRUE) ? (iConfig.iAllowLogout = FALSE) : (iConfig.iAllowLogout = TRUE);
+ iTelnetSession->DoModifyConfig(iConfig);
+ }
+ else if ( iCommand.MatchF(_L("Window")) == 0)
+ // Demo only, changes the window size
+ {
+ iConfig.iWindowSize.x = 60;
+ iConfig.iWindowSize.y = 20;
+ iTelnetSession->DoModifyConfig(iConfig);
+ }
+ else if ( iCommand.MatchF(_L("Speed")) == 0)
+ // Demo only, sets the speed
+ {
+ iConfig.iTermSpeed = _L8("9600");
+ iTelnetSession->DoModifyConfig(iConfig);
+ }
+ else if ( iCommand.MatchF(_L("Type")) == 0)
+ // Demo only, changes the terminal type
+ // See API document implementation of terminal type configuration
+ {
+ iConfig.iTermType = _L8("vt100");
+ iTelnetSession->DoModifyConfig(iConfig);
+ }
+
+ else if(iCommand.MatchF(_L("exit")) == 0)
+ {
+ // Clean exit, all destructors called
+ ret = FALSE;
+ CActiveScheduler::Stop();
+ }
+ else
+ {
+ iConsole->Printf(_L("command = %S.\n"),&iCommand);
+ iConsole->Printf(_L("unknown command\n"));
+ }
+ return ret;
+ }
+
+void CTinyTelnet::DoCancel()
+ {
+
+ }
+
+void CTinyTelnet::Open(TDesC& aCommandArg)
+ {
+ TInt err;
+ iCommandArg = aCommandArg;
+ err = iTelnetSession->Connect(iCommandArg);
+ if(err != KErrNone)
+ iState = EConnecting;
+ iConsole->Printf(_L("Connect returned - %d\n"), err);
+ }
+
+void CTinyTelnet::Help(TDesC& /*aCommandArg*/)
+ {
+ iConsole->Printf(_L("\nHelp\n"));
+ iConsole->Printf(_L("----\n\n"));
+ iConsole->Printf(_L(" <esc> - command prompt\n"));
+ iConsole->Printf(_L(" open <server> - connect to server on telnet port 23\n"));
+ iConsole->Printf(_L(" openip <aa.bb.cc.dd> - connect to server on telnet port 23\n"));
+ iConsole->Printf(_L(" close - disconnect connection\n"));
+ iConsole->Printf(_L(" echo - toggle local echo on/off\n"));
+ iConsole->Printf(_L(" status - print option status\n\n"));
+ }
+
+void CTinyTelnet::LocalEcho(TDesC& /*aCommandArg*/)
+ {
+ iLocalEcho = (!iLocalEcho);
+ }
+
+void CTinyTelnet::Logout(TDesC& /*aCommandArg*/)
+ {
+ iTelnetSession->DoForceLogout();
+ }
+
+void CTinyTelnet::OpenIP(TDesC& aCommandArg)
+ {
+ TInt err;
+ iAddress.Input(aCommandArg); // Accepts a, a.b, a.b.c, a.b.c.d or 0xaabbccdd
+ err = iTelnetSession->Connect(iAddress);
+ iConsole->Printf(_L("Connect returned - %d\n"), err);
+ }
+
+void CTinyTelnet::Read()
+ {
+ iTelnetSession->Read();
+ }
+
+
+TInt CTinyTelnet::Write(TChar aChar)
+// Write characters to the Server
+// For Demo, we are trapping :-
+// CTRL+A AO (Abort Output)
+// CTRL+B AYT (Are You There)
+// CTRL+C IP (Interrupt Process)
+// CTRL+D EC (Erase Character, NVT only)
+// CTRL+E EL (Erase Line, NVT only)
+// CTRL+F BRK (Break)
+ {
+
+ TInt ret = KErrNone;
+ TTelnetUserControl code;
+ if (iState==EConnected)
+ {
+ TBuf8<10> buffer;
+ buffer.SetLength(0);
+
+ if(aChar == 1)
+ {
+ // ABORT OUTPUT
+ code = EAo;
+ ret = iTelnetSession->Write(code);
+ }
+ else if(aChar == 2)
+ {
+ // ARE YOU THERE
+ code = EAyt;
+ ret = iTelnetSession->Write(code);
+ }
+ else if(aChar == 3)
+ {
+ // INTERRUPT PROCESS
+ code = EIp;
+ ret = iTelnetSession->Write(code);
+ }
+ else if(aChar == 4)
+ {
+ // ERASE CHARACTER
+ code = EEc;
+ ret = iTelnetSession->Write(code);
+ }
+ else if(aChar == 5)
+ {
+ // ERASE LINE
+ code = EEl;
+ ret = iTelnetSession->Write(code);
+ }
+ else if(aChar == 6)
+ {
+ // BREAK
+ code = EBrk;
+ ret = iTelnetSession->Write(code);
+ }
+ else
+ {
+ buffer.Append(aChar);
+ ret = iTelnetSession->Write(buffer);
+ }
+
+
+ //iConsole->Printf(_L("Write returned - (%d)\n"), err);
+ }
+ else
+ {
+ ret = KErrDisconnected;
+ iConsole->Printf(_L("Not connected [write failed]\n"));
+ }
+ return ret;
+ }
+
+void CTinyTelnet::Close(TDesC& /*aCommandArg*/)
+ {
+ TInt err;
+ err = iTelnetSession->Disconnect();
+ iConsole->Printf(_L("Disconnect returned - %d\n"), err);
+ }
+
+
+//
+// CActiveConsole Implementation
+//
+void CActiveConsole::ConstructL(CConsoleBase* aConsole)
+ {
+ iConsole = aConsole;
+ CActiveScheduler::Add(this);
+ }
+
+CActiveConsole::~CActiveConsole()
+ {
+ Cancel();
+ }
+
+void CActiveConsole::RequestCharacter()
+ {
+ __ASSERT_DEBUG(!IsActive(), User::Panic(_L("CActiveConsole::RequestCharacter()"), KRequestPending));
+ iConsole->Read(iStatus);
+ SetActive();
+ }
+
+void CActiveConsole::RunL()
+ {
+ ProcessKeyPress(TChar(iConsole->KeyCode()));
+ }
+
+void CActiveConsole::DoCancel()
+ {
+ iConsole->ReadCancel();
+ }