28 Oct 2016.

A Serial Terminal Server makes a serial connection available over the network, so that your application can access your devices without a direct serial connection. Typically this is used to establish a bi-directional connection between networked applications and older industrial equipment. In this article we will focus on a much simpler use case: Capturing serial logs, where we only need communication in one direction — a common use case when testing set-top boxes.

First the complete solution, for the impatient:

DEVICE=/dev/serial/by-path/platform-3f980000.usb-usb-0:1.3.3.1:1.0-port0
PORT=4953
socat -b 2048 -u "\"$DEVICE\",b115200,crnl,raw,ignoreeof,echo=0" - </dev/null \
    | ts %Y-%m-%dT%H:%M:%S%z \
    | gst-launch-1.0 fdsrc ! text/plain ! queue \
                     ! tcpserversink sync=false host=0.0.0.0 port=$PORT

This uses socat, the Swiss Army Knife of networking; ts from the moreutils package to timestamp each line; and GStreamer as our TCP server.

The above socat command transfers data from the serial device to standard output. The two layers of quoting are necessary so that socat doesn’t treat the “:” in the device path as separators. See the socat manual for details on the other parameters.

Then we pipe socat’s output to ts, which prepends an ISO 8601 timestamp to each line.

Finally, gst-launch runs a GStreamer pipeline that reads the text data from its standard input, starts up a server listening on the specified TCP port, and sends the data to any clients that connect. GStreamer is perhaps overkill for this but it gets the job done, and it supports multiple clients connecting/disconnecting and reading the same data simultaneously.

You’ll want to configure your init system to start the above service automatically on startup. I’ll leave that as an exercise to the reader.

Testing it

You can test this using netcat. This should print your set-top box’s serial output to the console:

nc $serial_server_address 4953

Or using socat:

socat TCP:$serial_server_address:4953 -

Installing the dependencies

Assuming you’re using Raspbian on a Raspberry Pi, here’s how to install these tools:

apt-get update &&
apt-get install \
    gstreamer1.0-plugins-base \
    gstreamer1.0-tools \
    moreutils \
    socat

Specifying the serial device

On a single server you can have multiple versions of the above script serving different serial devices, as long as each one uses a different TCP port.

We use /dev/serial/by-path/... (instead of /dev/ttyUSBx) because it won’t change across reboots. It refers to the physical USB port that your serial adapter is plugged into.

To find the path of your serial device, just run ls /dev/serial/by-path before and after plugging it in.

USB serial adapters

For out-of-the-box Linux support and good reliability, you only have two options:

  • The Tripp-Lite Keyspan adapter.
  • Anything using FTDI chips (buy direct from FTDI or from reputable vendors, as there are counterfeit chips on the market).