[fpc-pascal] Serial to TCP gateway in FPC?

Bo Berglund bo.berglund at gmail.com
Thu Jun 29 10:39:05 CEST 2017

On Wed, 28 Jun 2017 10:55:47 -0700 (MST), turro75
<valerio.turrini at gmail.com> wrote:

>I don't know if useful, here You can find a terminal + serial to eth or
>reversed based on lnet, custom serial component and richmemo

but I have two problems:
1) I have failed to install LNet into my Lazarus 1.6 on Windows.
See thread titled "Installing LNet in Lazarus 1.6 fails" in the
Lazarus list.
So I turned to Indy instead, but I think LNet would serve me better.

2) I need the relay gateway to be running also on Raspberry Pi3, i.e.
the system must be cross-platform and it seems like the example is for
Windows (COM ports with strange syntax etc).

3) I also noted in the comments in TurSeriale.pas:
  "The Windows port driver does receive callbacks in chunks that
   are typically 8 bytes long.
   With ReceiveMode = rmRAW, TSeriale will simply pass this chunks
   on to the application without any processing."
Does this mean that if a single character is received it is not passed
along? My protocol is exchanging single bytes for state changes and
these have rather tight timeouts as well, so a long delay in
forwarding the bytes will break the protocol.

State of my effort as of now:
Server side:
I am using ser2net on a RPi3 on the remote location to translate the
serial port connection into a socket connection. This seems to work
but there are issues.

Client side:
Here I have written a relaying application myself with Lazarus 1.6 and
FPC 3.0.0. I used the FPC built-in serial unit as adviced in the
hardware wiki for the serial port. For the TCP client I finally went
with Indy's TIdTcpClient and it seemed to work a bit.

For some unknown reason (so far) the remote side loses connection to
the target system (no response after initially being able to talk to
it). In fact this is reproducible 100%, the first handshake works and
the system can be set to the new state, but on the next state change
the 1-byte command is not responded to so the connection fails.

In order to trace this I need to have better control at the remote
side so I wanted to expand the Windows side client to be able to run
in server mode so I can install it on the RPi3 instead of using
ser2net. Then I think I could examine all data traffic with timing to
figure out the problem.

So my current aim is to convert the current program into an
application that can run either as a server or a client on the network
and do this:

- Listen for connection on a specific TCP port (only one allowed)
- When client connects open the predefined serial port
- Enter relay mode where all bytes coming in on the socket connection
are sent to the serial port and all bytes coming in on the serial port
are sent to teh socket.
- Keep doing this until the TCP client disconnects, when the serial
port is also closed and the system waits for another connect.
- To not lock up forever, there should be a (long) timeout in the
relay mode such that in the absence of incoming data the timeout is
decremented until triggered. Then the ports are closed and the system
goes to wait mode.

- Wait for some connect command (not sure how to do this)
- Connect to local serial port
- Connect to remote TCP port
- Enter relay mode as above if both connections succeed
- Exit relay mode on some disconnect command
- Disconnect both TCP and serial ports

I would like to also add some data logging to this system so I can see
what is happening on the lines.

Using the FPC built-in serial unit I can handle the serial connection,
but I have trouble with the TCP part since the Indy components are a
bit too involved and hard to understand.

So in order for the program to run as a server I need a TCP server
component I can integrate into this without too much fussing about.
There is only one single client allowed and data should not be
processed at all, just transferred...

(And I failed to install LNet in Lazarus...)

Bo Berglund
Developer in Sweden

More information about the fpc-pascal mailing list