Package org.eclipse.remote.telnet.core

# Class TelnetProtocol

java.lang.Object
java.lang.Thread
org.eclipse.remote.telnet.core.TelnetProtocol

All Implemented Interfaces:
  `Runnable`

public class TelnetProtocol extends Thread
This class encapsulates a TELNET connection to a remote server. It processes incoming TELNET protocol data and generates outbound TELNET protocol data. It also manages two sets of TelnetOption objects: one for the local endpoint and one for the remote endpoint.

IMPORTANT: Understanding this code requires understanding the TELNET protocol and TELNET option processing, as defined in the RFCs listed below.

See Also:
  - RFC 854
  - RFC 855
  - RFC 856
  - RFC 857
  - RFC 858
  - RFC 859
  - RFC 860
  - RFC 861
  - RFC 1091
  - RFC 1096
  - RFC 1073
  - RFC 1079
  - RFC 1143
  - RFC 1572

## Nested Class Summary

## Nested classes/interfaces inherited from class java.lang.Thread

`Thread.State, Thread.UncaughtExceptionHandler`

## Field Summary

Fields
Modifier and Type
Field
Description
`protected static final int`
`BUFFER_SIZE`
Size of buffer for processing data received from remote endpoint.
`protected OutputStream`
`clientOutputStream`
This field holds a reference to an `OutputStream` object used to send data to the client.
`protected int`
`height`
This field holds the height of the Terminal screen in rows.
`protected boolean`
`ignoreSubnegotiation`
This field is true if an error occurs while processing a subnegotiation command.
`protected ReadableByteChannel`
`inputChannel`
This field holds a reference to an `ReadableByteChannel` object used to receive data from the remote endpoint.
`protected boolean`
`localEcho`
UNDER CONSTRUCTION
`protected org.eclipse.remote.telnet.core.TelnetOption[]`
`localOptions`
An array of TelnetOption objects representing the local endpoint's TELNET options.
`protected int`
`nextSubnegotiationByteIndex`
This field holds the index into array `receivedSubnegotiation` of the next unused byte.
`protected byte[]`
`processedBytes`
Holds incoming network data after the TELNET protocol bytes have been processed and removed.
`protected StringBuffer`
`processedStringBuffer`
This field holds a StringBuffer containing text recently received from the remote endpoint (after all TELNET protocol bytes have been processed and removed).
`protected ByteBuffer`
`rawBytes`
Holds raw bytes received from the remote endpoint, prior to any TELNET protocol processing.
`protected byte[]`
`receivedSubnegotiation`
An array of bytes that holds the TELNET subnegotiation command most recently received from the remote endpoint.
`protected boolean`
`remoteIsTelnetServer`
This field is true if the remote endpoint is a TELNET server, false if not.
`protected org.eclipse.remote.telnet.core.TelnetOption[]`
`remoteOptions`
An array of TelnetOption objects representing the remote endpoint's TELNET options.
`protected OutputStream`
`serverOutputStream`
This field holds a reference to an `OutputStream` object used to send data to the remote endpoint.
`protected TelnetCommandShell`
`shell`
This field holds a reference to the `TelnetCommandShell`.
`protected Socket`
`socket`
This method holds the Socket object for the TELNET connection.
`protected static final int`
`STATE_DO_RECEIVED`
TELNET connection state: Last byte processed was DO code.
`protected static final int`
`STATE_DONT_RECEIVED`
TELNET connection state: Last byte processed was DONT code.
`protected static final int`
`STATE_IAC_RECEIVED`
TELNET connection state: Last byte processed was IAC code.
`protected static final int`
`STATE_INITIAL`
TELNET connection state: Initial state.
`protected static final int`
`STATE_RECEIVING_SUBNEGOTIATION`
TELNET connection state: Currently receiving sub-negotiation data.
`protected static final int`
`STATE_SUBNEGOTIATION_STARTED`
TELNET connection state: Last byte processed was SB.
`protected static final int`
`STATE_WILL_RECEIVED`
TELNET connection state: Last byte processed was WILL code.
`protected static final int`
`STATE_WONT_RECEIVED`
TELNET connection state: Last byte processed was WONT code.
`static final byte`
`TELNET_AO`
Command code: Abort Output.
`static final byte`
`TELNET_AYT`
Command code: Are You There.
`static final byte`
`TELNET_BREAK`
Command code: Break.
`static final byte`
`TELNET_DM`
Command code: Data Mark.
`static final byte`
`TELNET_DO`
Command code: Do.
`static final byte`
`TELNET_DONT`
Command code: Don't.
`static final byte`
`TELNET_EC`
Command code: Erase Character.
`static final byte`
`TELNET_EL`
Command code: Erase Line.
`static final byte`
`TELNET_GA`
Command code: Go Ahead.
`static final byte`
`TELNET_IAC`
Command code: Interpret As Command.
`static final byte`
`TELNET_IP`
Command code: Interrupt Process.
`static final byte`
`TELNET_IS`
Command code: IS.
`static final byte`
`TELNET_NOP`
Command code: No-op.
`static final byte`
`TELNET_OPTION_ECHO`
Option code: Echo option.
`static final byte`
`TELNET_OPTION_NAWS`
Option code: Negotitate About Window Size (NAWS)
`static final byte`
`TELNET_OPTION_SUPPRESS_GA`
Option code: Suppress Go Ahead option.
`static final byte`
`TELNET_OPTION_TERMINAL_TYPE`
Option code: Terminal Type
`static final byte`
`TELNET_OPTION_TRANSMIT_BINARY`
Option code: Transmit Binary option.
`static final byte`
`TELNET_SB`
Command code: Subnegotiation Begin.
`static final byte`
`TELNET_SE`
Command code: Subnegotiation End.
`static final byte`
`TELNET_SEND`
Command code: SEND.
`static final byte`
`TELNET_WILL`
Command code: Will.
`static final byte`
`TELNET_WONT`
Command code: Won't.
`protected int`
`telnetState`
Holds the current state of the TELNET protocol processor.
`protected int`
`width`
This field holds the width of the Terminal screen in columns.

### Fields inherited from class java.lang.Thread

`MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY`

## Constructor Summary

Constructors
Constructor
Description
`TelnetProtocol(Socket socket, TelnetCommandShell shell)`
This constructor just initializes some internal object state from its arguments.

## Method Summary

Modifier and Type
Method
Description
`OutputStream`
`getOutputStream()`
`protected void`
`initializeOptions()`
This method initializes the localOptions[] and remoteOptions[] arrays so that they contain references to TelnetOption objects representing our desired state for each option.
`boolean`
`isConnected()`
Returns true if the TCP connection represented by this object is connected, false otherwise.
`boolean`
`isRemoteTelnetServer()`
Returns true if the TCP connection represented by this object is connected and the remote endpoint is a TELNET server, false otherwise.
`boolean`
`localEcho()`
Returns true if local echoing is enabled for this TCP connection, false otherwise.
`protected int`
`processTelnetProtocol(int count)`
Process TELNET protocol data contained in the first count bytes of rawBytes.
`void`
`run()`
This method runs in its own thread.
`void`
`setClientOutputStream(OutputStream stream)`
`void`
`setTerminalSize(int newWidth, int newHeight)`
This method sets the terminal width and height to the supplied values.
`protected void`
`telnetServerDetected()`
This method is called whenever we receive a valid TELNET protocol command from the remote endpoint.

### Methods inherited from class java.lang.Thread

`activeCount, checkAccess, clone, countStackFrames, currentThread, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, onSpinWait, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, suspend, toString, yield`

### Methods inherited from class java.lang.Object

`equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

## Field Details

### STATE_INITIAL

protected static final int STATE_INITIAL
TELNET connection state: Initial state.

See Also:
  - Constant Field Values

### STATE_IAC_RECEIVED

protected static final int STATE_IAC_RECEIVED
TELNET connection state: Last byte processed was IAC code. code.

See Also:
  - Constant Field Values

### STATE_WILL_RECEIVED

protected static final int STATE_WILL_RECEIVED
TELNET connection state: Last byte processed was WILL code. code.

See Also:
  - Constant Field Values

### STATE_WONT_RECEIVED

protected static final int STATE_WONT_RECEIVED
TELNET connection state: Last byte processed was WONT code.

See Also:
  - Constant Field Values

### STATE_DO_RECEIVED

protected static final int STATE_DO_RECEIVED
TELNET connection state: Last byte processed was DO code.

See Also:
  - Constant Field Values

### STATE_DONT_RECEIVED

protected static final int STATE_DONT_RECEIVED
TELNET connection state: Last byte processed was DONT code.

See Also:
  - Constant Field Values

### STATE_SUBNEGOTIATION_STARTED

protected static final int STATE_SUBNEGOTIATION_STARTED
TELNET connection state: Last byte processed was SB.

See Also:
  - Constant Field Values

### STATE_RECEIVING_SUBNEGOTIATION

protected static final int STATE_RECEIVING_SUBNEGOTIATION
TELNET connection state: Currently receiving sub-negotiation data.

See Also:
  - Constant Field Values

### BUFFER_SIZE

protected static final int BUFFER_SIZE
Size of buffer for processing data received from remote endpoint.

See Also:
  - Constant Field Values

### rawBytes

protected ByteBuffer rawBytes
Holds raw bytes received from the remote endpoint, prior to any TELNET protocol processing.

### processedBytes

protected byte[] processedBytes
Holds incoming network data after the TELNET protocol bytes have been processed and removed.

### processedStringBuffer

protected StringBuffer processedStringBuffer
This field holds a StringBuffer containing text recently received from the remote endpoint (after all TELNET protocol bytes have been processed and removed).

### telnetState

protected int telnetState
Holds the current state of the TELNET protocol processor.

### remoteIsTelnetServer

protected boolean remoteIsTelnetServer
This field is true if the remote endpoint is a TELNET server, false if not. We set this to true if and only if the remote endpoint sends recognizable TELNET protocol data. We do not assume that the remote endpoint is a TELNET server just because it is listening on port 23. This allows us to successfully connect to a TELNET server listening on a port other than 23.

When this field first changes from false to true, we send all WILL or DO commands to the remote endpoint.

See Also:
  - `telnetServerDetected()`

### localOptions

protected org.eclipse.remote.telnet.core.TelnetOption[] localOptions
An array of TelnetOption objects representing the local endpoint's TELNET options. The array is indexed by the numeric TELNET option code.

### remoteOptions

protected org.eclipse.remote.telnet.core.TelnetOption[] remoteOptions
An array of TelnetOption objects representing the remote endpoint's TELNET options. The array is indexed by the numeric TELNET option code.

### receivedSubnegotiation

protected byte[] receivedSubnegotiation
An array of bytes that holds the TELNET subnegotiation command most recently received from the remote endpoint. This array does _not_ include the leading IAC SB bytes, nor does it include the trailing IAC SE bytes. The first byte of this array is always a TELNET option code.

### nextSubnegotiationByteIndex

protected int nextSubnegotiationByteIndex
This field holds the index into array `receivedSubnegotiation` of the next unused byte. This is used by method `processTelnetProtocol(int)` when the state machine is in states `STATE_SUBNEGOTIATION_STARTED` and `STATE_RECEIVING_SUBNEGOTIATION`.

### ignoreSubnegotiation

protected boolean ignoreSubnegotiation
This field is true if an error occurs while processing a subnegotiation command.

See Also:
  - `processTelnetProtocol(int)`

### width

protected int width
This field holds the width of the Terminal screen in columns.

### height

protected int height
This field holds the height of the Terminal screen in rows.

### shell

protected TelnetCommandShell shell
This field holds a reference to the `TelnetCommandShell`.

### socket

protected Socket socket
This method holds the Socket object for the TELNET connection.

### inputChannel

protected ReadableByteChannel inputChannel
This field holds a reference to an `ReadableByteChannel` object used to receive data from the remote endpoint.

### serverOutputStream

protected OutputStream serverOutputStream
This field holds a reference to an `OutputStream` object used to send data to the remote endpoint.

### clientOutputStream

protected OutputStream clientOutputStream
This field holds a reference to an `OutputStream` object used to send data to the client.

### localEcho

protected boolean localEcho
UNDER CONSTRUCTION

### TELNET_SE

static final byte TELNET_SE
Command code: Subnegotiation End.

See Also:
  - Constant Field Values

### TELNET_NOP

static final byte TELNET_NOP
Command code: No-op.

See Also:
  - Constant Field Values

### TELNET_DM

static final byte TELNET_DM
Command code: Data Mark.

See Also:
  - Constant Field Values

### TELNET_BREAK

static final byte TELNET_BREAK
Command code: Break.

See Also:
  - Constant Field Values

### TELNET_IP

static final byte TELNET_IP
Command code: Interrupt Process.

See Also:
  - Constant Field Values

### TELNET_AO

static final byte TELNET_AO
Command code: Abort Output.

See Also:
  - Constant Field Values

### TELNET_AYT

static final byte TELNET_AYT
Command code: Are You There.

See Also:
  - Constant Field Values

### TELNET_EC

static final byte TELNET_EC
Command code: Erase Character.

See Also:
  - Constant Field Values

### TELNET_EL

static final byte TELNET_EL
Command code: Erase Line.

See Also:
  - Constant Field Values

### TELNET_GA

static final byte TELNET_GA
Command code: Go Ahead.

See Also:
  - Constant Field Values

### TELNET_SB

static final byte TELNET_SB
Command code: Subnegotiation Begin.

See Also:
  - Constant Field Values

### TELNET_WILL

static final byte TELNET_WILL
Command code: Will.

See Also:
  - Constant Field Values

### TELNET_WONT

static final byte TELNET_WONT
Command code: Won't.

See Also:
  - Constant Field Values

### TELNET_DO

static final byte TELNET_DO
Command code: Do.

See Also:
  - Constant Field Values

### TELNET_DONT

static final byte TELNET_DONT
Command code: Don't.

See Also:
  - Constant Field Values

### TELNET_IAC

static final byte TELNET_IAC
Command code: Interpret As Command.

See Also:
  - Constant Field Values

### TELNET_IS

static final byte TELNET_IS
Command code: IS.

See Also:
  - Constant Field Values

### TELNET_SEND

static final byte TELNET_SEND
Command code: SEND.

See Also:
  - Constant Field Values

### TELNET_OPTION_TRANSMIT_BINARY

static final byte TELNET_OPTION_TRANSMIT_BINARY
Option code: Transmit Binary option.

See Also:
  - Constant Field Values

### TELNET_OPTION_ECHO

static final byte TELNET_OPTION_ECHO
Option code: Echo option.

See Also:
  - Constant Field Values

### TELNET_OPTION_SUPPRESS_GA

static final byte TELNET_OPTION_SUPPRESS_GA
Option code: Suppress Go Ahead option.

See Also:
  - Constant Field Values

### TELNET_OPTION_TERMINAL_TYPE

static final byte TELNET_OPTION_TERMINAL_TYPE
Option code: Terminal Type

See Also:
  - Constant Field Values

### TELNET_OPTION_NAWS

static final byte TELNET_OPTION_NAWS
Option code: Negotitate About Window Size (NAWS)

See Also:
  - Constant Field Values

## Constructor Details

### TelnetProtocol

public TelnetProtocol(Socket socket, TelnetCommandShell shell) throws IOException
This constructor just initializes some internal object state from its arguments.

Throws:
  `IOException`

## Method Details

### getOutputStream

public OutputStream getOutputStream()

### setClientOutputStream

public void setClientOutputStream(OutputStream stream)

### isConnected

public boolean isConnected()
Returns true if the TCP connection represented by this object is connected, false otherwise.

### isRemoteTelnetServer

public boolean isRemoteTelnetServer()
Returns true if the TCP connection represented by this object is connected and the remote endpoint is a TELNET server, false otherwise.

### setTerminalSize

public void setTerminalSize(int newWidth, int newHeight)
This method sets the terminal width and height to the supplied values. If either new value differs from the corresponding old value, we initiate a NAWS subnegotiation to inform the remote endpoint of the new terminal size.

### localEcho

public boolean localEcho()
Returns true if local echoing is enabled for this TCP connection, false otherwise.

### run

public void run()
This method runs in its own thread. It reads raw bytes from the TELNET connection socket, processes any TELNET protocol bytes (and removes them), and passes the remaining bytes to a TerminalDisplay object for display.

Specified by:
  `run` in interface `Runnable`
Overrides:
  `run` in class `Thread`

### initializeOptions

protected void initializeOptions()
This method initializes the localOptions[] and remoteOptions[] arrays so that they contain references to TelnetOption objects representing our desired state for each option. The goal is to achieve server-side echoing, suppression of Go Aheads, and to send the local terminal type and size to the remote endpoint.

### processTelnetProtocol

protected int processTelnetProtocol(int count)
Process TELNET protocol data contained in the first count bytes of rawBytes. This function preserves its state between calls, because a multi-byte TELNET command might be split between two (or more) calls to this function. The state is preserved in field telnetState. This function implements an FSA that recognizes TELNET option codes. TELNET option sub-negotiation is delegated to instances of TelnetOption.

Returns:
  The number of bytes remaining in the buffer after removing all TELNET protocol bytes.

### telnetServerDetected

protected void telnetServerDetected()
This method is called whenever we receive a valid TELNET protocol command from the remote endpoint. When it is called for the first time for this connection, we negotiate all options that we desire to be enabled.

This method does not negotiate options that we do not desire to be enabled, because all options are initially disabled.