TelnetApp.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2004 Andras Varga
00003 //
00004 // This library is free software, you can redistribute it and/or modify
00005 // it under  the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation;
00007 // either version 2 of the License, or any later version.
00008 // The library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 // See the GNU Lesser General Public License for more details.
00012 //
00013 
00014 
00015 #include "TelnetApp.h"
00016 
00017 
00018 #define MSGKIND_CONNECT  0
00019 #define MSGKIND_SEND     1
00020 #define MSGKIND_CLOSE    2
00021 
00022 
00023 Define_Module(TelnetApp);
00024 
00025 TelnetApp::TelnetApp()
00026 {
00027     timeoutMsg = NULL;
00028 }
00029 
00030 TelnetApp::~TelnetApp()
00031 {
00032     cancelAndDelete(timeoutMsg);
00033 }
00034 
00035 void TelnetApp::initialize()
00036 {
00037     TCPGenericCliAppBase::initialize();
00038 
00039     timeoutMsg = new cMessage("timer");
00040 
00041     numCharsToType = numLinesToType = 0;
00042     WATCH(numCharsToType);
00043     WATCH(numLinesToType);
00044 
00045     timeoutMsg->setKind(MSGKIND_CONNECT);
00046     scheduleAt((simtime_t)par("startTime"), timeoutMsg);
00047 }
00048 
00049 void TelnetApp::handleTimer(cMessage *msg)
00050 {
00051     switch (msg->getKind())
00052     {
00053         case MSGKIND_CONNECT:
00054             EV << "user fires up telnet program\n";
00055             connect();
00056             break;
00057 
00058         case MSGKIND_SEND:
00059            if (numCharsToType>0)
00060            {
00061                // user types a character and expects it to be echoed
00062                EV << "user types one character, " << numCharsToType-1 << " more to go\n";
00063                sendPacket(1,1);
00064                scheduleAt(simTime()+(simtime_t)par("keyPressDelay"), timeoutMsg);
00065                numCharsToType--;
00066            }
00067            else
00068            {
00069                EV << "user hits Enter key\n";
00070                // Note: reply length must be at least 2, otherwise we'll think
00071                // it's an echo when it comes back!
00072                sendPacket(1, 2+(long)par("commandOutputLength"));
00073                numCharsToType = (long)par("commandLength");
00074 
00075                // Note: no scheduleAt(), because user only starts typing next command
00076                // when output from previous one has arrived (see socketDataArrived())
00077            }
00078            break;
00079 
00080         case MSGKIND_CLOSE:
00081            EV << "user exits telnet program\n";
00082            close();
00083            break;
00084     }
00085 }
00086 
00087 void TelnetApp::socketEstablished(int connId, void *ptr)
00088 {
00089     TCPGenericCliAppBase::socketEstablished(connId, ptr);
00090 
00091     // schedule first sending
00092     numLinesToType = (long) par("numCommands");
00093     numCharsToType = (long) par("commandLength");
00094     timeoutMsg->setKind(numLinesToType>0 ? MSGKIND_SEND : MSGKIND_CLOSE);
00095     scheduleAt(simTime()+(simtime_t)par("thinkTime"), timeoutMsg);
00096 }
00097 
00098 void TelnetApp::socketDataArrived(int connId, void *ptr, cPacket *msg, bool urgent)
00099 {
00100     int len = msg->getByteLength();
00101     TCPGenericCliAppBase::socketDataArrived(connId, ptr, msg, urgent);
00102 
00103     if (len==1)
00104     {
00105         // this is an echo, ignore
00106         EV << "received echo\n";
00107     }
00108     else
00109     {
00110         // output from last typed command arrived.
00111         EV << "received output of command typed\n";
00112 
00113         // If user has finished working, she closes the connection, otherwise
00114         // starts typing again after a delay
00115         numLinesToType--;
00116 
00117         if (numLinesToType==0)
00118         {
00119             EV << "user has no more commands to type\n";
00120             timeoutMsg->setKind(MSGKIND_CLOSE);
00121             scheduleAt(simTime()+(simtime_t)par("thinkTime"), timeoutMsg);
00122         }
00123         else
00124         {
00125             EV << "user looks at output, then starts typing next command\n";
00126             timeoutMsg->setKind(MSGKIND_SEND);
00127             scheduleAt(simTime()+(simtime_t)par("thinkTime"), timeoutMsg);
00128         }
00129     }
00130 }
00131 
00132 void TelnetApp::socketClosed(int connId, void *ptr)
00133 {
00134     TCPGenericCliAppBase::socketClosed(connId, ptr);
00135 
00136     // start another session after a delay
00137     timeoutMsg->setKind(MSGKIND_CONNECT);
00138     scheduleAt(simTime()+(simtime_t)par("idleInterval"), timeoutMsg);
00139 }
00140 
00141 void TelnetApp::socketFailure(int connId, void *ptr, int code)
00142 {
00143     TCPGenericCliAppBase::socketFailure(connId, ptr, code);
00144 
00145     // reconnect after a delay
00146     timeoutMsg->setKind(MSGKIND_CONNECT);
00147     scheduleAt(simTime()+(simtime_t)par("reconnectInterval"), timeoutMsg);
00148 }
00149