00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef HH_SENF_Scheduler_Console_Telnet_
00027 #define HH_SENF_Scheduler_Console_Telnet_ 1
00028
00029
00030 #include <vector>
00031 #include <map>
00032 #include <senf/Scheduler/Scheduler.hh>
00033 #include <senf/Scheduler/ClockService.hh>
00034
00035
00036
00037
00038 namespace senf {
00039 namespace term {
00040
00135 class BaseTelnetProtocol
00136 {
00137 public:
00138 static unsigned const DEFAULT_REQUEST_TIMEOUT_MS = 500u;
00139
00140 typedef ClientSocketHandle<senf::MakeSocketPolicy<
00141 ConnectedCommunicationPolicy,
00142 StreamFramingPolicy,
00143 ReadablePolicy,
00144 WriteablePolicy>::policy> Handle;
00145
00146 typedef unsigned char option_type;
00147
00148 struct TelnetHandler;
00149
00150 void write(std::string const & s);
00151
00153 void write(char c);
00154
00157 Handle handle();
00158
00159 void sendNOP();
00160 void sendBRK();
00161 void sendIP();
00162 void sendAO();
00163 void sendAYT();
00164 void sendEC();
00165 void sendEL();
00166 void sendGA();
00167
00168 void sendOptionParameters(option_type option, std::string const & data);
00170
00173 void requestLocalOption(option_type option, bool enabled = true);
00175
00176 void acceptLocalOption(option_type option, bool enabled = true);
00178
00181 void requestPeerOption(option_type option, bool enabled = true);
00183
00184 void acceptPeerOption(option_type option, bool enabled = true);
00186
00189 bool localOption(option_type option);
00190 bool peerOption(option_type option);
00191
00192 protected:
00193 explicit BaseTelnetProtocol(Handle handle);
00194 BaseTelnetProtocol();
00195
00196 virtual ~BaseTelnetProtocol();
00197
00198 template <class Handler>
00199 void registerHandler(Handler * h, bool request=true);
00201
00202 void incrementRequestCounter();
00203
00207 void decrementRequestCounter();
00208
00209 bool requestsPending();
00210
00211 #ifndef DOXYGEN
00212 private:
00213 #endif
00214 virtual void v_setupComplete() = 0;
00215
00226 virtual void v_charReceived(char c) = 0;
00227 virtual void v_eof() = 0;
00228
00229 virtual void v_handleNOP();
00230 virtual void v_handleBRK();
00231 virtual void v_handleIP();
00232 virtual void v_handleAO();
00233 virtual void v_handleAYT();
00234 virtual void v_handleEC();
00235 virtual void v_handleEL();
00236 virtual void v_handleGA();
00237
00238 private:
00239 void handleChar(char c);
00240 void handleNormalChar(char c);
00241 void handleCommand(char c);
00242 void handleOption(char c);
00243 void handleCR(char c);
00244 void handleSBOption(char c);
00245 void handleSBData(char c);
00246 void handleSBIAC(char c);
00247 void emit(char c);
00248 void processCommand();
00249 void transmit(char c);
00250
00251 void sendWILL(char option);
00252 void sendWONT(char option);
00253 void sendDO(char option);
00254 void sendDONT(char option);
00255
00256 void readHandler(int state);
00257 void writeHandler(int state);
00258 void timeout();
00259
00260 enum Command {
00261 CMD_NONE = 0,
00262 CMD_SE = 240,
00263 CMD_NOP = 241,
00264 CMD_DM = 242,
00265 CMD_BRK = 243,
00266 CMD_IP = 244,
00267 CMD_AO = 245,
00268 CMD_AYT = 246,
00269 CMD_EC = 247,
00270 CMD_EL = 248,
00271 CMD_GA = 249,
00272 CMD_SB = 250,
00273 CMD_WILL = 251,
00274 CMD_WONT = 252,
00275 CMD_DO = 253,
00276 CMD_DONT = 254,
00277 CMD_IAC = 255,
00278 };
00279
00280 struct OptInfo
00281 {
00282 enum WantState { WANTED, ACCEPTED, DISABLED };
00283 enum OptionState { NONE, REQUEST_SENT, ACKNOWLEDGED };
00284
00285 OptInfo();
00286 OptInfo(bool local, option_type option);
00287
00288
00289
00290 bool const local;
00291 option_type const option;
00292
00293 WantState wantState;
00294 OptionState optionState;
00295 bool enabled;
00296
00297 };
00298
00299 OptInfo & getOption(bool local, option_type option);
00300 void request(OptInfo & info, bool enabled);
00301 void response(OptInfo & info, bool enabled);
00302
00303 typedef std::map<std::pair<bool, option_type>, OptInfo> OptionsMap;
00304 OptionsMap options_;
00305
00306 typedef std::map<option_type, TelnetHandler*> OptionHandlerMap;
00307 OptionHandlerMap handlers_;
00308
00309 Handle handle_;
00310
00311 typedef std::vector<char> SendQueue;
00312 SendQueue sendQueue_;
00313
00314 enum CharState { NORMAL, IAC_SEEN, EXPECT_OPTION, CR_SEEN,
00315 SB_OPTION, SB_DATA, SB_IAC_SEEN };
00316 CharState charState_;
00317
00318 Command command_;
00319 option_type option_;
00320 std::string data_;
00321
00322 scheduler::FdEvent inputEvent_;
00323 scheduler::FdEvent outputEvent_;
00324
00325 unsigned pendingRequests_;
00326
00327 ClockService::clock_type requestTimeout_;
00328 scheduler::TimerEvent timeout_;
00329
00330 friend class TelnetHandler;
00331 };
00332
00337 struct BaseTelnetProtocol::TelnetHandler
00338 : public virtual BaseTelnetProtocol
00339 {
00340 virtual ~TelnetHandler();
00341 virtual void v_init() = 0;
00342 virtual void v_handleOptionParameters(std::string const & data) = 0;
00344 };
00345
00352 namespace telnetopt { BaseTelnetProtocol::option_type const ECHO = 1u; }
00353 namespace telnetopt { BaseTelnetProtocol::option_type const TRANSMIT_BINARY = 0u; }
00354 namespace telnetopt { BaseTelnetProtocol::option_type const SUPPRESS_GO_AHEAD = 3u; }
00355 namespace telnetopt { BaseTelnetProtocol::option_type const TERMINAL_TYPE = 24u; }
00356 namespace telnetopt { BaseTelnetProtocol::option_type const NAWS = 31u; }
00357 namespace telnetopt { BaseTelnetProtocol::option_type const LINEMODE = 34u; }
00358
00362 namespace telnethandler {
00363
00377 class TerminalType
00378 : public BaseTelnetProtocol::TelnetHandler
00379 {
00380 public:
00381 static option_type const OPTION_CODE = telnetopt::TERMINAL_TYPE;
00382
00383 void nextTerminalType();
00384 std::string const & terminalType() const;
00385
00386 protected:
00387 TerminalType();
00388
00389 private:
00390 virtual void v_init();
00391 virtual void v_handleOptionParameters(std::string const & data);
00392
00393 std::string type_;
00394 };
00395
00408 class NAWS
00409 : public BaseTelnetProtocol::TelnetHandler
00410 {
00411 public:
00412 static option_type const OPTION_CODE = telnetopt::NAWS;
00413
00414 unsigned width() const;
00415 unsigned height() const;
00416
00417 protected:
00418 NAWS();
00419
00420 # ifndef DOXYGEN
00421 private:
00422 # endif
00423 virtual void v_windowSizeChanged() = 0;
00424
00427 private:
00428 virtual void v_init();
00429 virtual void v_handleOptionParameters(std::string const & data);
00430
00431 unsigned width_;
00432 unsigned height_;
00433 };
00434
00435 }
00436
00437 }}
00438
00439
00440 #include "Telnet.cci"
00441
00442
00443 #include "Telnet.cti"
00444 #endif
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455