Title
Page icon
Create new category
Edit page index title
Edit category
Edit link
Serial tunneling (through Ethernet) - A Lua example
Goal
We establish a network connection (e.g. over Ethernet) to send serial commands from one device to another (or vice versa).
Receive serial input on device 1 (Server/Client).
Send received data over TCP socket connection to device 2 (Server/Client).
Transmit received data (from device 1) to serial output on device 2.
Overview

Code
Let's start with importing the necessary packages.
Package | Function |
|---|---|
<a href="https://luarocks.org/modules/luarocks/luars232">luars232</a> | Interaction with the serial port (based on <a href="https://github.com/ynezz/librs232">librs232</a>). |
<a href="https://luarocks.org/modules/luarocks/luasocket">socket</a> | Support for TCP/UDP transport (see "Glossary" section IP/TCP).<br> |
<a href="https://oldwiki.archive.openwrt.org/doc/techref/uci">uci</a> | Uci bindings to access systems config settings (see section "Config File" below). |
Now defining some table structures holding possible options for our serial connection. For an explanation of these options, see section "Glossary" below.
Going further, defining all functions we want to invoke later. We will look at each one separately, from top to bottom.
First we define a variable *out *(a handler for the predefined C stream io.stderr), to be able to later send a message directly to the error stream (console).
Next we access the serial port with the port name (SERIAL.PORT_NAME) declared in the config file.
If we receive no error back, we can go on and set the serial options defined in the config file. If an error occurred, it will be send to the error stream (console).
Function on the client side to establish a TCP socket connection to the host (Server device).
host: IP address of the Server
port: Port at which the connection should start
Function on the server side to establish a TCP socket server.
port: Port at which the connection should start
Server side determines the port number, client has to use the same number (check in config)
Next we define a function to handle the serial input (for each device).
First reading from the serial connection and storing the received data in data_read. If there is any data (data_read ~= nil), we send the data to the other device (see server_send() below) over our TCP socket connection.
This function is going to forward the received data to the serial port. After we check if an error occurred during the transmission.
Next, a function to handle the incoming data on the TCP socket connection. It consists of 2 parts, one if the code is running on the server side, one for client side.
In both cases, we change the timeout values for the socket object to 0.1sec..
By default, all I/O operations are blocking. So the receive call is blocking indefinitely. The settimeout() method sets a limit on the amount of time the I/O method can block.
Now we can go ahead and receive data from the TCP connection (the 1 indicates that we are going to read 1 byte at a time).
Send the data received from the serial input to the other device.
That's it for the function part. Now we can take a look at the execution logic.
First setting up the serial connection.
Reading socket mode and port from the config.
Establish socket connection (as server or client, depending on config).
Main part for handling the application. Running forever (while true).
Finally closing the socket connection.
Config
Serial
Option | Value (Default) |
|---|---|
PORT_NAME | Default for serial communication using RS232: "/dev/ttyS1" |
BAUD | 9600, 19200, 38400, 57600, 115200 (default 115200) |
DATA_BITS | 6, 7, 8 (default 8) |
PARITY | "NONE", "ODD", "EVEN" (default "NONE") |
STOP_BITS | 1, 2 (default 1) |
FLOW_CONTROL | "OFF", "HW", "XONXOFF" (default "OFF") |
Server
Option | Value |
|---|---|
MODE<br> | "SERVER", "CLIENT" |
SERVER_IP | Enter the IP of the device in SERVER MODE. The device in CLIENT MODE will then connect to this specific IP |
PORT<br> | <p>Enter the port you want to use. If you enter 0 in the SERVER device config, it will chose an ephemeral port by <span style="font-family: var(--font);">himself and print it out. You will then have to enter this printed port in the config of the CLIENT device. </span></p> |
Glossary
Ethernet
IP/TCP
Port
Serial
Serial characteristics (Baud rate, Data bits, Stop bits, Parity bits, Flow control)
Server/Client
Tunneling