Rationalized function naming in tn2217.c:
- Prefix tn2217_: functions called from outside tn2217.c. Either
directly (exported) or through the ops table.
- No prefix: all functions related with the handling of the telnet
protocol.
- Prefix comport_: All functions related with the COMPORT option
Code in tn2217.c is using writen_ni() with the non-blocking socket
fd. This will not work. Instead of making the fd blocking (which is also
a solution), I made writen_ni work with both, blocking and non-blocking
fds.
Also added a time-out version of writen_ni(), called writento_ni() for
future use (we way want to protect writes with timeouts). Currently
commented out.
Combined commit. No time and too messy to split it up.
- Cleaned up, improved debugging output
- Correct options negotiations
- Refactored wait_cond(), waid_cmd(), not to repeat code from read()
See also discussion in issue #95
Don't wait for negotiations to finish and for port configuration to be
completed if picocom is run with --noinit (in which case s->set_termios
will not be set).
When an RFC2217 socket is closed, optionally, try to drain the
buffered data allowing the remote server to read and process
them. First the socket is shutdown only in the transmit (write)
direction. Then data are read from it (and discarded) until the server
closes the other direction (read(2) returns zero).
Also, don't bother trying to reset the port to its original settings
before exiting, since closing the connection to the remote server will
do this anyway (as per RFC2217).
Before picocom enters it's main loop and data are written to serial
port, and also before the first data are read from the port, the port
must first be configured. That is: The first data read from picocom's
standard input (or the initstring) must be written to the port, *after*
the port has been configured to the settings specified by picocom's
command-line arguments; also, the first data must be read from the port,
after the port has been configured (as any data read before, will most
likely be garbage).
When tn2217_write() is called it checks that the initial negotiations
have completed, and that the RFC2217 port-configuration commands have
been transmitted. If this is not true, then the function waits by
reading from the port and processing commands until the condition
becomes true or a timeout expires.
When tn2217_read() is called it checks that the initial negotiations
have completed, that the RFC2217 port-configuration commands have been
transmitted *AND* that their replies have been received. Any user-data
read by picocom before the replies to the commands are received will
most likely be data read by the server using the old port configuration
and therefore useless (garbage). To make the test easier, we actually
check that an equal number of replies-to-configuration-commands has been
received as configuration-commands have been sent (a misbehaving server
can confuse us by sending multiple replies to commands, but this is
always the case). Again, then the function waits by reading from the
port and processing commands until the condition becomes true or a
timeout expires.
See also discussion in issue #95
Use the same code to parse options (parity, databits, stopbits, etc)
from a termios structure and to write options to a termios structure for
both: native and RFC2217 ports.
Seems to work ok, but more thorough testing is needed.
Also fixed some minor bugs (typos) when setting stopbits, and when
setting modem-control lines.
Cleaned up debuging output a bit.
If picocom is compiled *with* custom-baudrate support (USE_CUSTOM_BAUD)
for Linux, then it uses a new set of ioctl's (TCGETS2 vs TCGETS, etc) to
access the serial ports. This patch allows the custom baudrate support
to be disabled at runtime (without recompiling), and picocom to switch
to using the old ioctl's.
To disable custom baudrate support (and switch back to the "old" ioctls)
simply define the environment variable NO_CUSTOM_BAUD, before starting
picocom.
This applies only to Linux and, obviously, only when picocom has been
compiled with custom baudrate support (USE_CUSTOM_BAUD).
Use the same code to parse the baudrate from a termios structure and to
write the baudrate to a termios structure for both: native
and RFC2217 ports. Also use the same code to translate between
speeds (expressed in bits-per-second) and budrate-codes.
Seems to work ok, but more testing is needed, especially around some
corner-cases.
Use the same code to parse the flow-control setting from a termios
structure and to write the flow-control settings to a termios structure
for both: native and RFC2217 ports.
Send and receive file commands pass the port filedes to a newly exec'ed
binary, as its stdin/stdout. This obviously will not work for RFC2217
ports (as the data-stream contains inline signaling that must be removed
by the term framework).
In order to support send- and receive- file commands for RFC2217 ports,
the execed binary must be connected (probably through pipes) to a newly
forked process that monitors the pipes and forwards the data to the
RFC2217 port using the term_read() / term_write() functions that do the
necessary filtering. This may still not work if the execed binary
expects to find a tty connected to its stdin/stdout. In this case
there's nothing we can do...
Anyway, this is too much work so, for now, so I just disable the
commands.
Add support for connecting to remote COM-PORT servers using RFC 2217.
This commit adds a term_ops provider that translates all termios
and modem ioctls into TELNET operations.
It supports:
- IPv4 and IPv6 hosts and ports numbers, per getaddrinfo()
- baud rate changes up to 115200
- data bit size, parity, stop bits
- sending BREAK
- control over remote hardware flow control mode
- control over remote signals: RTS, DTR
- visibility of remote signals: CD, RI, DSR, CTS
- flushing remote rx/tx buffers
Limitations
- There will be some delay between some operations (eg DTR toggle)
so rapid toggling can result in a temporarily inconsistent local
state. However, it will eventually synchronise with the remote
state if allowed to settle.
- The terminal's FD is the raw TCP connection, so sx/rx likely won't
work.
- More baud rates could be supported.
- Remote parity modes SPACE and MARK are not supported.
- Stop bit size 1.5 is not supported.
- In-protocol flow control is not supported.
- BREAK is implemented with a local usleep of 250ms, which may be
eaten up or extended by the network.