rs2322tcp/README.md
2026-08-10 13:51:26 +02:00

513 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# rs2322tcp
`rs2322tcp` ermöglicht die transparente Übertragung von RS232-Daten über
TCP/IP.
Das Projekt ist für den Einsatz geeignet, bei dem eine vorhandene
Software eine serielle Schnittstelle erwartet, das zugehörige Gerät sich
jedoch an einem entfernten Standort befindet.
## Ziel
Auf der Client-Seite soll vorhandene Hersteller-Software eine normale
serielle Schnittstelle vorfinden.
Die Daten werden vom `rs2322tcp-client` über TCP an einen entfernten
`rs2322tcp-server` übertragen. Der Server verbindet die
Netzwerkverbindung mit einer realen seriellen Schnittstelle.
Damit sollen weder die vorhandene Software auf dem Client noch die
angeschlossenen Geräte auf der Remote-Seite erkennen müssen, dass die
Verbindung über ein Netzwerk erfolgt.
Typische Anwendungen sind beispielsweise:
- Funkgeräte mit CAT-Steuerung
- Antennenrotoren mit herstellerspezifischen seriellen Protokollen
- andere Geräte, die über RS232 gesteuert werden
## Architektur
```text
Client-PC Raspberry Pi 5
───────────────── ─────────────────
Hersteller-Software rs2322tcp-server
│ │
│ virtuelle │
│ serielle Schnittstelle │
▼ │
rs2322tcp-client │
│ │
└──────────── TCP/IP ──────────────────┘
┌──────────┴──────────┐
│ │
USB-to-RS232 USB-to-RS232
│ │
Funkgerät Rotor
```
## Aktueller Server-Datenpfad
Die serverseitige TCP-/RS232-Verbindung ist implementiert:
```text
TCP-Control
Session
├── Gerät 1 ──► dynamischer Data-Port
│ │
│ ▼
│ TCP Data
│ │
│ ▼
│ Serial Layer
│ │
│ ▼
│ RS232
└── Gerät 2 ──► dynamischer Data-Port
```
Die serielle Schnittstelle wird erst geöffnet, wenn ein Client
tatsächlich eine Data-Verbindung zum entsprechenden dynamischen TCP-Port
aufbaut.
Pro konfiguriertem Gerät ist nur eine aktive Data-Verbindung vorgesehen.
Die Datenübertragung erfolgt bidirektional:
```text
TCP ───────────────► RS232
TCP ◄────────────── RS232
```
## Client
Der Client soll gleichberechtigt unter folgenden Betriebssystemen
eingesetzt werden können:
- Windows
- Linux
Die plattformspezifische Bereitstellung der virtuellen seriellen
Schnittstelle wird vom gemeinsamen Client-Kern getrennt.
Unter Linux ist die virtuelle serielle Schnittstelle inzwischen über
einen direkt aus Go erzeugten PTY implementiert. Die Implementierung
verwendet `/dev/ptmx` und stellt den zugehörigen PTY-Slave unter
`/dev/pts/N` bereit.
Die PTY-Schnittstelle wird im Raw Mode betrieben. Dadurch werden die
übertragenen Daten als transparenter Byte-Strom behandelt.
Die allgemeine Client-Logik verwendet dafür die Abstraktion
`VirtualSerial`. Die Linux-spezifische Implementierung ist von dieser
Abstraktion getrennt.
Für die PTY-Funktion ist keine externe Laufzeitabhängigkeit wie `socat`
erforderlich.
## Server
Der Server ist zunächst für den Betrieb auf einem Raspberry Pi 5
vorgesehen.
Mehrere USB-to-RS232-Adapter können angeschlossen werden. Anzahl,
Bezeichnung und serielle Parameter der Anschlüsse werden über eine
Konfigurationsdatei festgelegt.
Die serverseitige Serial-Kommunikation verwendet `go.bug.st/serial`.
## Serielle Schnittstelle
Für die Ansteuerung der seriellen Schnittstellen wird derzeit verwendet:
```text
go.bug.st/serial v1.7.1
```
Die Bibliothek wurde zusätzlich auf dem privaten Git-Server des
Projektes gespiegelt, um bei einem Ausfall des ursprünglichen Anbieters
weiterhin auf den verwendeten Quellstand zugreifen zu können:
```text
git.lang-dieter.de/third-party/go-serial
```
Die verwendete Version `v1.7.1` ist auf dem Backup-Repository
einschließlich Git-Tag vorhanden.
## Netzwerk
Für die Übertragung der RS232-Daten wird TCP verwendet.
Die beteiligten Systeme werden zunächst über ein vertrauenswürdiges
Tailscale-Netz verbunden.
Eine zusätzliche TLS-Verschlüsselung ist deshalb derzeit nicht
vorgesehen.
Für eine spätere Übertragung von Audio-Daten ist ein separates
Netzwerk-/Transportkonzept vorgesehen. Hierfür soll UDP verwendet bzw.
untersucht werden.
## Konfiguration
Client und Server erhalten jeweils eine eigene JSON-Konfiguration.
Über die Konfiguration werden unter anderem festgelegt:
- Netzwerkparameter
- serielle Schnittstelle
- Baudrate
- Datenbits
- Parität
- Stopbits
- Bezeichnung des Gerätes
- weitere für die jeweilige Schnittstelle erforderliche Parameter
Die konkrete Konfigurationsstruktur befindet sich in der Entwicklung.
## Diagnose und Logging
Für Debugging und Diagnose soll eine Protokollierung des übertragenen
Datenverkehrs möglich sein.
Insbesondere soll eine Darstellung der übertragenen Bytes möglich sein,
um Probleme bei der Kommunikation zwischen Hersteller-Software und Gerät
analysieren zu können.
Während der Entwicklung kann `socat` als zusätzliches Werkzeug für Tests
und Diagnose eingesetzt werden.
## Virtuelle serielle Schnittstelle unter Linux
Für den Linux-Client wird die virtuelle serielle Schnittstelle direkt
über den Linux-PTY-Mechanismus erzeugt.
Dabei entsteht ein PTY-Paar:
```text
/dev/ptmx
PTY Master
PTY Slave
/dev/pts/N
```
Die externe Hersteller-Software arbeitet mit dem PTY-Slave `/dev/pts/N`.
Der `rs2322tcp-client` verwendet den PTY-Master und transportiert die
Bytes über TCP zum Server.
Die PTY-Implementierung arbeitet im Raw Mode und wurde mit einem
vollständigen Bytebereich von `0x00` bis `0xFF` geprüft.
Dabei wurde die bidirektionale Übertragung aller 256 möglichen Bytewerte
erfolgreich getestet.
## Geräte-Simulator
Das Programm `rs2322tcp-device-sim` dient als Simulator für ein an der
seriellen Schnittstelle angeschlossenes Gerät.
Der Simulator ist bewusst als eigenständiges Programm ausgeführt. Der
`rs2322tcp-server` muss nicht wissen, ob am seriellen Port ein echtes
Gerät oder der Simulator angeschlossen ist.
Der Simulator kann:
- Daten von einer seriellen Schnittstelle oder einem Linux-PTY empfangen
- empfangene Rohdaten als Hexdump anzeigen
- beliebige Bytefolgen über eine interaktive Hex-Eingabe senden
- ungültige Hex-Eingaben erkennen
- als virtuelle serielle Gegenstelle für externe Software dienen
Beispiel:
```bash
go run ./cmd/rs2322tcp-device-sim -port /dev/pts/7
```
Zum Senden wird eine Hex-Folge eingegeben:
```text
TX> 46 41 00 10 0D
```
Der Simulator überträgt diese fünf Bytes.
Empfangene Daten werden beispielsweise so angezeigt:
```text
RX 5 Bytes
46 41 00 10 0D
```
Die Hex-Eingabe kann mit oder ohne Leerzeichen erfolgen:
```text
46 41 00 10 0D
```
und:
```text
464100100D
```
sind gleichwertig.
Auch Groß- und Kleinschreibung kann gemischt werden:
```text
0a FF 01 b7
```
Ungültige Eingaben wie
```text
GG
```
oder
```text
4
```
werden erkannt und führen nicht zum Beenden des Simulators.
Der Simulator soll insbesondere auch als Sniffer dienen können, wenn
externe Hersteller-Software untersucht werden soll. Dadurch lassen sich
die von einer Software gesendeten seriellen Kommandos zunächst als
Rohdaten beobachten.
Geplante bzw. mögliche Erweiterungen sind:
- automatische Geräteantworten
- Protokollsimulation
- Aufzeichnung und Wiedergabe von Datenströmen
## PTY-Testprogramm
Für die Entwicklung existiert zusätzlich das separate Testprogramm:
```text
~/rs2322tcp-pty-test
```
Es erzeugt unter Linux ein PTY, setzt den Slave in den Raw Mode und zeigt
den Namen des Slave-Gerätes an.
Beispiel:
```bash
cd ~/rs2322tcp-pty-test
go run .
```
Ausgabe:
```text
PTY Slave: /dev/pts/2
PTY ist im Raw Mode.
Warte auf Daten vom PTY-Slave ...
Mit Ctrl+C beenden.
```
Das Programm zeigt anschließend beliebige empfangene Bytes unmittelbar
als Hexdump an.
Der Testaufbau ermöglicht damit Tests in beiden Richtungen:
```text
Master → Slave
Slave → Master
```
und eignet sich auch als einfacher Beobachtungspunkt für den Datenstrom.
## Sniffer-Funktion
Der Empfänger des Testaufbaus kann gleichzeitig als einfacher Sniffer
verwendet werden.
Dadurch kann später auch externe Software angeschlossen werden, um zu
beobachten, welche Kommandos diese Software tatsächlich über die serielle
Schnittstelle versendet.
Besonders für die Entwicklung von Protokollen für Funkgeräte oder andere
Hardware ist das hilfreich.
Der Sniffer verändert die empfangenen Daten nicht, sondern zeigt die
empfangenen Bytes lediglich an.
## Externe USB-to-Seriell-Adapter
Für den späteren praktischen Einsatz sind USB-to-Seriell-Adapter
vorgesehen.
Unter Linux werden solche Adapter normalerweise als serielle Gerätedateien
bereitgestellt, beispielsweise:
```text
/dev/ttyUSB0
```
Die Kommunikation erfolgt über die normale serielle Schnittstelle des
Betriebssystems und die vorhandene Serial-Abstraktion.
Das Projekt benötigt für die serielle Kommunikation keine direkte
`libusb`-Anbindung. Bei üblichen USB-to-Seriell-Adaptern, beispielsweise
mit FTDI-Chips, wird die serielle Schnittstelle über den Linux-Kernel-
Treiber bereitgestellt.
Eine spezielle Hardware-Anbindung über `libusb` ist für `rs2322tcp`
daher nicht vorgesehen.
## Tests
Die wichtigsten Komponenten verfügen über automatisierte Tests.
Der aktuelle Stand wird unter anderem mit folgenden Befehlen geprüft:
```bash
go test ./...
```
und:
```bash
go test -race ./...
```
Der Race Detector wird eingesetzt, um Probleme bei der nebenläufigen
Verarbeitung von Sessions, Data-Listenern, DataConnections und Client-
Komponenten zu erkennen.
Die Linux-PTY-Komponente wurde mit einem vollständigen Bytebereich von
`0x00` bis `0xFF` geprüft.
Der Geräte-Simulator verfügt zusätzlich über automatisierte Tests für
die Hex-Konvertierung und die Behandlung ungültiger Eingaben.
Für die Prüfung des Arbeitsbaums:
```bash
git diff --check
git status
```
## Projektstruktur
```text
rs2322tcp/
├── cmd/
│ ├── rs2322tcp-client/
│ ├── rs2322tcp-device-sim/
│ └── rs2322tcp-server/
├── configs/
├── docs/
├── internal/
│ ├── client/
│ ├── config/
│ ├── serial/
│ ├── server/
│ ├── transport/
│ └── version/
├── scripts/
│ └── build.sh
├── CHANGELOG.md
├── LICENSE
├── README.md
└── go.mod
```
## Build
Der Build erfolgt über das zentrale Build-Skript:
```bash
./scripts/build.sh
```
Das Skript führt unter anderem folgende Schritte aus:
- Formatierung des Go-Quellcodes
- Ausführung der Tests
- Bereinigung der Go-Module
- Ermittlung der Git-Versionsinformationen
- Build der vorgesehenen Zielplattformen
- Einbettung der Versionsinformationen über den Go-Linker
- Erzeugung von SHA256-Prüfsummen
Aktuell werden folgende Builds erzeugt:
- Linux amd64 -- Client und Server
- Linux arm64 -- Server
- Linux armv7 -- Server
- Linux armv6 -- Server
## Versionierung
Die Versionierung erfolgt über Git.
Die Git-Informationen werden beim Build in die Binärdateien eingebettet.
Neben der Version werden unter anderem Build-Nummer, Commit und
Build-Datum erfasst.
Release-Versionen werden über Git-Tags gekennzeichnet.
Aktueller Stand:
- `v0.0.1` erste Projektversion
- `v0.0.2` Client-Control- und Data-Verbindungen
- `v0.0.3` Linux-PTY-Unterstützung und Geräte-Simulator
- `v0.0.4` in Vorbereitung: interaktive TX-Funktion und automatisierte
Tests des Geräte-Simulators
## Entwicklungsstand
Das Projekt befindet sich weiterhin in der frühen Entwicklungsphase.
Implementiert und getestet sind derzeit:
- Server-Control-Verbindung
- Session-Verwaltung
- dynamische Data-Ports
- DataConnection
- bidirektionale TCP-/RS232-Datenübertragung
- Serial-Abstraktion
- Konfiguration der seriellen Parameter
- Client-Control-Verbindung
- Client-DataConnection
- Client-Integrationstests
- Linux-PTY-Abstraktion
- Linux-PTY im Raw Mode
- automatisierter bidirektionaler 256-Byte-PTY-Test
- nebenläufigkeitssichere Data-Listener
- Race-Detection
- eigenständiger Geräte-Simulator mit RX-Hexdump
- interaktive TX-Hex-Eingabe des Geräte-Simulators
- automatisierte Tests der Hex-Konvertierung
Noch nicht vollständig implementiert sind insbesondere:
- die vollständige Anbindung der virtuellen seriellen Schnittstelle an
den produktiven Client-Anwendungsdatenpfad
- die Windows-Implementierung der virtuellen seriellen Schnittstelle
- automatische Geräteantworten und Protokollsimulation
## Lizenz
GPL-3.0-or-later