WiFi Serial Ports

Background

I use a lot of devices that (still) communicate solely via the lowly serial port, whether that be via RS-232C or RS-485. Given that I also live in the modern world, I have a real need to connect to these devices remotely (over the Internet) or to distributed machines (such as VMs) with the need for excess cabling (i.e. serial-to-USB devices).

I’ve used several solutions in the past, with mixed success. The MOXA W2250 Ethernet/WiFi devices I still rely upon daily to run HVAC, lighting and energy management in my home “mostly just work” – but are somewhat quirky, and lack great user interfaces (to be fair, these particular units are EOL).

I’ve also used a Black Box LES401A with success (I think it’s actually an older re-labeled B&B Electronics unit), but it’s bulky, has just one port, and is Ethernet-only.

Enter the Lantronix PremierWave XN. While technically it, too, is EOL, it still has fairly recent firmware releases. Its feature set, capabilities and user interface are miles ahead of what I experienced on the W2250 or LES401A. Plus, it can be found for “cheap” on surplus, which is a huge bonus for personal/volunteer projects.

Pool Systems Automation

Currently I’m working on a Pool Systems Automation project, which happens to fall under both the personal and volunteer categories. I need to connect a DirectLogic DL06 PLC via RS-232, a pool chemical controller (Chemtrol PC-2100) via RS-485 and a BeagleBone Black to WiFi.

I should mention that when I started on this project, I intended to utilize esp-link for both serial devices. While I’m very impressed by the efforts of its developer, I found that it had some shortcomings for my application (in particular, the hard-coded baud/parity configurations). Still, it’s definitely in the hopper for future projects.

PLC Programming

To program the DirectLogic DL06 PLC, I utilize the Lantronix Com Port Redirector software, which creates virtual COM ports on a Windows-based client. This works quite well, and has proven reliable. At the moment, I am programming via a Laptop (connected via WiFi) only a dozen feet away. But in the future, I may very well want to debug/monitor this same PLC remotely (via a VPN).

Linux Virtual COM Port

The second serial port of the DL06 PLC is used for monitoring via Modbus. The Chemtrol unit can also be monitored remotely via its built-in RS-485 port. Both are monitored by software on a BeagleBone Black board that runs Debian Linux.

From what I can tell, Lantronix does not have a Linux tool that is similar to Com Port Redirector available. Fortunately, after researching several options, I’ve found that socat does exactly what I need, and is fairly ubiquitous in the Linux world.

A virtual serial port is created using the following syntax:

socat pty,link=/dev/ttyV0,group=dialout,perm=0666,rawer tcp:x.x.x.x:y

Where:

  • pty generates a pseudo terminal.
  • link generates a symbolic link that points to the actual pseudo terminal (pty). I’ve chosen the names “ttyV0“, “ttyV1“, etc., (where “V” suggests “virtual”) though I suppose this is a matter of personal preference.
  • group defines the permissions of the device. I’ve chosen “dialout” to be consistent with other serial ports on the system.
  • perm – for now, I’m sticking with 0666 to give read/write to all groups. Still having some issues with actually making dialout work with the tools I’m using.
  • rawer sets “rawer than raw mode”, passing I/O “almost unprocessed”. I have used raw with success, but raw is obsolete in favor of rawer.
  • tcp:x.x.x.x:y defines the address and TCP port of the target device. For the PremierWave XN, TCP port 10001 is used for physical “Port 1” and TCP port 10002 is used for physical “Port 2”.

RFC 2217

A quick note about RFC 2217: This setup does not support it, but I don’t need it. From what I can tell, the benefits of RFC 2217 are:

  • the ability to configure the remote host (baud rate, etc)
  • to support flow control
  • to manage modem line signalling such as carrier detect (CD)

None of these features are needed. The remote host is statically configured, and both flow control and modem line signalling are not required.

If you need RFC 2217, I’ve seen multiple recommendations for ser2net, but I’ve never tried it.

Automatic Configuration at Boot

To configure both virtual serial ports upon boot, I utilize two systemd configuration files, named socat-serial-ttyV0.service and socat-serial-ttyV1.service in the folder /etc/systemd/system. An example configuration for ttyV0 is as follows:

[Unit]
Description=Socat Serial ttyV0
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=socat-serial-ttyv0

ExecStart=/usr/bin/socat pty,link=/dev/ttyV0,group=dialout,perm=0666,rawer tcp:x.x.x.x:y
Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

Where:

  • The definition for Wants and After, set equal to network-online.target, is intended to delay startup until after the network is deemed online.
  • The ExecStart line is per the socat definition above. Observe that I’ve redacted the IP and port I’m actually using in my system.
  • Restart should be set to always if automatic reconnect is desired. As I understand it, socat exits gracefully (status 0) when a connection closes. Setting this value to always causes an indefinite retry cycle upon disconnect (every 10 seconds, per the setting below). This has been shown to result in recovery in the event that a network device is disconnected, then later reconnected.
  • RestartSec was added to eliminate startup errors (i.e. “Start request repeated too quickly.”). The default value is 100 ms. I am not sure why this is required – I would assume that network-online.target should delay the initial startup attempt (and it should be successful). Further investigation may be required (though for now, it works).

The rest of the configuration is pretty standard for a systemd startup script, pulled from various examples.

Once these files are defined, execute the following within the folder to enable at startup:

systemctl enable socat-serial-ttyV0.service
systemctl enable socat-serial-ttyV1.service

Security

I’ve never trusted my serial to Ethernet/WiFi devices from a security perspective. Particularly as many of the units I use are EOL, there is a risk of vulnerabilities that are never fixed (lack of further firmware updates). These devices probably aren’t very secure, regardless.

To mitigate some of the risk, I always place them in an isolated VLAN. This VLAN has very limited ability to interact with outside networks:

  • no outbound access whatsoever (no Internet)
  • inbound access (from the LAN or VPN) to ports deemed necessary for operation and management

When WiFi is used, I set up a special non-broadcast SSID bound to the VLAN.

I’m no security expert, but this seems to be reasonable protection, especially for the small-scale operations I run.