|
INET Framework for OMNeT++/OMNEST
|
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