1125 lines
27 KiB
Markdown
1125 lines
27 KiB
Markdown
# 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 Datenpfad
|
||
|
||
Der serverseitige TCP-/RS232-Datenpfad 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
|
||
```
|
||
|
||
Auch der Client-Datenpfad ist implementiert:
|
||
|
||
```text
|
||
Virtueller serieller Port
|
||
│
|
||
▼
|
||
rs2322tcp-client
|
||
│
|
||
│ TCP-Control
|
||
▼
|
||
Session
|
||
│
|
||
│ TCP-Data
|
||
▼
|
||
rs2322tcp-server
|
||
│
|
||
▼
|
||
reale serielle
|
||
Schnittstelle
|
||
│
|
||
▼
|
||
Gerät
|
||
```
|
||
|
||
Der Client kann mehrere konfigurierte virtuelle serielle Schnittstellen
|
||
gleichzeitig verwalten.
|
||
|
||
## Client
|
||
|
||
Der Client soll gleichberechtigt unter folgenden Betriebssystemen
|
||
eingesetzt werden können:
|
||
|
||
- Linux
|
||
- Windows
|
||
|
||
Die gemeinsame Client-Logik ist von der plattformspezifischen
|
||
Bereitstellung der virtuellen seriellen Schnittstelle getrennt.
|
||
|
||
Der Client besteht im Wesentlichen aus:
|
||
|
||
- Control-Verbindung zum Server
|
||
- Verwaltung der vom Server angebotenen Geräte
|
||
- Runtime zur Verwaltung mehrerer virtueller Ports
|
||
- virtuellen seriellen Schnittstellen
|
||
- TCP-Data-Connections
|
||
- bidirektionalen Bridges zwischen virtuellem Port und TCP-Verbindung
|
||
- grafischer Benutzeroberfläche
|
||
|
||
### Linux
|
||
|
||
Unter Linux ist die virtuelle serielle Schnittstelle ü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.
|
||
|
||
### Windows
|
||
|
||
Die gemeinsame Client-Architektur ist bereits auf eine
|
||
plattformabhängige Implementierung der virtuellen seriellen
|
||
Schnittstelle vorbereitet.
|
||
|
||
Unter Windows wird dieselbe gemeinsame Client- und Konfigurationslogik
|
||
verwendet. Für Tests können vorhandene virtuelle COM-Port-Verbindungen
|
||
verwendet werden.
|
||
|
||
Mit Version `v0.0.11` wurde der Windows-Client mit funktionierender
|
||
Fyne-GUI sowie der automatischen Übertragung der konfigurierten Rotor-
|
||
Startbytes praktisch getestet.
|
||
|
||
## 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.
|
||
|
||
### Client-Konfiguration
|
||
|
||
Über die Client-Konfiguration werden unter anderem festgelegt:
|
||
|
||
- Server-Adresse
|
||
- Server-Port
|
||
- reservierter Bereich der virtuellen seriellen Schnittstellen
|
||
- Zuordnung virtueller Schnittstellen zu Remote-Geräten
|
||
|
||
Beispiel:
|
||
|
||
```json
|
||
{
|
||
"server": {
|
||
"address": "127.0.0.1",
|
||
"port": 5000
|
||
},
|
||
"virtual_port_range": {
|
||
"first": 100,
|
||
"last": 199
|
||
},
|
||
"virtual_ports": [
|
||
{
|
||
"port": "/dev/ttyUSB100",
|
||
"remote_device": "radio"
|
||
},
|
||
{
|
||
"port": "/dev/ttyUSB101",
|
||
"remote_device": "rotor"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
Der konfigurierte Bereich
|
||
|
||
```json
|
||
"virtual_port_range": {
|
||
"first": 100,
|
||
"last": 199
|
||
}
|
||
```
|
||
|
||
definiert den für `rs2322tcp` vorgesehenen Bereich virtueller
|
||
Schnittstellen.
|
||
|
||
Die konkrete Zuordnung wird über `virtual_ports` festgelegt.
|
||
|
||
Beispielsweise:
|
||
|
||
```text
|
||
/dev/ttyUSB100 -> radio
|
||
/dev/ttyUSB101 -> rotor
|
||
```
|
||
|
||
Ein leerer Wert für `remote_device` kennzeichnet eine freie virtuelle
|
||
Schnittstelle.
|
||
|
||
Virtuelle Schnittstellen bleiben dadurch auch ohne aktuelle
|
||
Gerätezuordnung in der Client-Konfiguration erhalten.
|
||
|
||
### Gerätezuordnung
|
||
|
||
Die vom Server angebotenen Geräte können über die grafische
|
||
Benutzeroberfläche den konfigurierten virtuellen Schnittstellen
|
||
zugeordnet werden.
|
||
|
||
Dabei gelten folgende Regeln:
|
||
|
||
- Eine virtuelle Schnittstelle kann nur einem Gerät zugeordnet werden.
|
||
- Ein Gerät kann nicht gleichzeitig mehreren virtuellen Schnittstellen
|
||
zugeordnet werden.
|
||
- Eine bereits belegte Schnittstelle kann auf ihre aktuelle Zuordnung
|
||
oder auf „nicht verbunden“ gesetzt werden.
|
||
- Freie virtuelle Schnittstellen werden automatisch zur Auswahl
|
||
angeboten.
|
||
- Änderungen werden zunächst nur im Arbeitsspeicher gehalten.
|
||
- Beim Schließen des Gerätezuordnungsfensters werden die Änderungen in
|
||
`client.json` gespeichert.
|
||
- Wird das Hauptfenster geschlossen, während ungespeicherte Änderungen
|
||
vorhanden sind, wird der Anwender darauf hingewiesen.
|
||
|
||
## Prüfung der virtuellen seriellen Schnittstellen
|
||
|
||
Beim Start des Linux-Clients werden die in `client.json` definierten
|
||
virtuellen Schnittstellen mit den tatsächlich vorhandenen öffentlichen
|
||
symbolischen Links verglichen.
|
||
|
||
Dabei werden ausschließlich zwei Listen miteinander verglichen:
|
||
|
||
```text
|
||
vorhandene symbolische Links
|
||
↕
|
||
definierte virtuelle Ports
|
||
```
|
||
|
||
Es werden insbesondere folgende Abweichungen erkannt:
|
||
|
||
- Ein in `client.json` definierter Port besitzt keinen entsprechenden
|
||
öffentlichen Symlink.
|
||
- Ein öffentlicher Symlink ist vorhanden, aber nicht in `client.json`
|
||
eingetragen.
|
||
|
||
Bei einer Abweichung wird der Clientstart abgebrochen und dem Anwender
|
||
ein verständlicher Hinweis angezeigt.
|
||
|
||
Der Client legt fehlende öffentliche Links nicht automatisch an.
|
||
|
||
Damit bleibt die Systemkonfiguration unter der Kontrolle des Anwenders.
|
||
|
||
Die Prüfung selbst verändert keine Systemdateien und benötigt keine
|
||
Root-Rechte.
|
||
|
||
## Manuelle Einrichtung der virtuellen seriellen Ports unter Linux
|
||
|
||
Die öffentlichen virtuellen seriellen Ports werden unter Linux einmalig
|
||
eingerichtet.
|
||
|
||
Der laufende `rs2322tcp-client` benötigt anschließend keine Root-Rechte.
|
||
|
||
Zunächst wird das Verzeichnis für die internen virtuellen Links angelegt:
|
||
|
||
```bash
|
||
mkdir -p ~/.rs2322tcp/virtual
|
||
```
|
||
|
||
Anschließend werden die öffentlichen `/dev/ttyUSBxxx`-Links einmalig
|
||
mit administrativen Rechten angelegt.
|
||
|
||
Beispiel:
|
||
|
||
```bash
|
||
sudo ln -s "$HOME/.rs2322tcp/virtual/ttyUSB100" /dev/ttyUSB100
|
||
sudo ln -s "$HOME/.rs2322tcp/virtual/ttyUSB101" /dev/ttyUSB101
|
||
```
|
||
|
||
Die Zuordnung ist:
|
||
|
||
```text
|
||
/dev/ttyUSB100 -> ~/.rs2322tcp/virtual/ttyUSB100 -> PTY
|
||
/dev/ttyUSB101 -> ~/.rs2322tcp/virtual/ttyUSB101 -> PTY
|
||
```
|
||
|
||
Die äußeren Links unter `/dev` gehören dabei `root`. Das ist beabsichtigt.
|
||
|
||
Der Client selbst läuft anschließend als normaler Benutzer.
|
||
|
||
Die internen Links unter:
|
||
|
||
```text
|
||
~/.rs2322tcp/virtual/
|
||
```
|
||
|
||
werden vom Client auf die jeweils verwendeten PTYs gesetzt.
|
||
|
||
Die Einrichtung eines neuen virtuellen Ports besteht daher aus:
|
||
|
||
1. Einen freien Port aus dem konfigurierten Bereich auswählen.
|
||
2. Den öffentlichen `/dev/ttyUSBxxx`-Symlink einmalig anlegen.
|
||
3. Den Port in `client.json` eintragen.
|
||
4. Den Client starten.
|
||
5. Die Gerätezuordnung gegebenenfalls über die GUI vornehmen.
|
||
|
||
Der Client prüft beim Start, ob die Konfiguration und die vorhandenen
|
||
Symlinks übereinstimmen.
|
||
|
||
Die konkrete Einrichtung ist Linux-spezifisch. Für Windows wird später
|
||
eine eigene plattformspezifische Lösung verwendet.
|
||
|
||
## 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
|
||
```
|
||
|
||
Der PTY-Slave wird über den vom Anwender eingerichteten virtuellen
|
||
`/dev/ttyUSBxxx`-Symlink erreichbar.
|
||
|
||
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.
|
||
|
||
## Vollständiger Simulationsaufbau auf einem Ubuntu-PC
|
||
|
||
Der komplette Datenweg kann für Entwicklung und Tests auf einem einzigen
|
||
Ubuntu-PC ausgeführt werden. Dazu laufen gleichzeitig drei Programme:
|
||
|
||
1. `rs2322tcp-pty-test` als simuliertes Rotorgerät
|
||
2. `rs2322tcp-server` mit `configs/server-test.json`
|
||
3. `rs2322tcp-client`
|
||
|
||
Der Datenweg ist:
|
||
|
||
```text
|
||
Testprogramm oder Hersteller-Software
|
||
│
|
||
▼
|
||
/dev/ttyUSB100
|
||
│
|
||
▼
|
||
rs2322tcp-client
|
||
│ TCP
|
||
▼
|
||
rs2322tcp-server
|
||
│
|
||
▼
|
||
/dev/pts/N
|
||
│
|
||
▼
|
||
rs2322tcp-pty-test
|
||
simuliertes Rotorgerät
|
||
```
|
||
|
||
### 1. PTY-Simulator starten
|
||
|
||
In einem ersten Terminal:
|
||
|
||
```bash
|
||
cd ~/rs2322tcp
|
||
go run ./cmd/rs2322tcp-pty-test
|
||
```
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
rs2322tcp-pty-test
|
||
Port: /dev/pts/1
|
||
Modus: Rotor-Simulation mit Echo-Fallback
|
||
Warte auf Daten ...
|
||
```
|
||
|
||
Der ausgegebene PTY-Pfad wird im nächsten Schritt benötigt.
|
||
|
||
Der Simulator hält Master und Slave während seiner gesamten Laufzeit geöffnet.
|
||
Bei der bekannten Rotor-Anfrage wird automatisch die konfigurierte Rotor-Antwort
|
||
gesendet. Alle anderen Daten werden als Echo zurückgegeben.
|
||
|
||
### 2. Testkonfiguration des Servers anpassen
|
||
|
||
In `configs/server-test.json` wird der Rotor auf den aktuell vom Simulator
|
||
ausgegebenen PTY-Slave gesetzt.
|
||
|
||
Beispiel:
|
||
|
||
```json
|
||
{
|
||
"id": "rotor",
|
||
"name": "Antennenrotor",
|
||
"serial_port": "/dev/pts/1",
|
||
"baud_rate": 600,
|
||
"data_bits": 8,
|
||
"parity": "none",
|
||
"stop_bits": 1
|
||
}
|
||
```
|
||
|
||
Die PTY-Nummer ist nicht dauerhaft fest. Nach jedem neuen Start des
|
||
PTY-Simulators muss der tatsächlich ausgegebene `/dev/pts/N`-Pfad geprüft und
|
||
gegebenenfalls manuell in `server-test.json` eingetragen werden.
|
||
|
||
Im Echtbetrieb wird hier wieder ein fester Hardware-Port verwendet, zum Beispiel:
|
||
|
||
```text
|
||
/dev/ttyUSB0
|
||
```
|
||
|
||
Die serverseitige Zuordnung bleibt bewusst manuell und fest konfiguriert, weil
|
||
mehrere unterschiedliche Hardwaregeräte gleichzeitig am Server angeschlossen
|
||
sein können.
|
||
|
||
### 3. Server starten
|
||
|
||
In einem zweiten Terminal:
|
||
|
||
```bash
|
||
cd ~/rs2322tcp
|
||
go run ./cmd/rs2322tcp-server -config ./configs/server-test.json
|
||
```
|
||
|
||
Beispiel:
|
||
|
||
```text
|
||
rs2322tcp-server dev
|
||
Control-Server gestartet auf [::]:5000
|
||
Geräte: 3
|
||
```
|
||
|
||
### 4. Server-Monitor als Sniffer
|
||
|
||
Ist in der Server-Konfiguration
|
||
|
||
```json
|
||
"serial_monitor": true
|
||
```
|
||
|
||
gesetzt, protokolliert der Server den übertragenen Datenverkehr. Im
|
||
Simulationsaufbau werden dadurch unter anderem die Richtungen
|
||
|
||
```text
|
||
TCP RX
|
||
SERIAL TX
|
||
SERIAL RX
|
||
TCP TX
|
||
```
|
||
|
||
sichtbar.
|
||
|
||
Ein typischer Ablauf ist:
|
||
|
||
```text
|
||
TCP RX 57 00 00 00 00 00 00 00 00 00 00 1F 20
|
||
SERIAL TX 57 00 00 00 00 00 00 00 00 00 00 1F 20
|
||
SERIAL RX 57 07 01 06 00 01 03 06 02 00 01 20
|
||
TCP TX 57 07 01 06 00 01 03 06 02 00 01 20
|
||
```
|
||
|
||
Der Server arbeitet damit gleichzeitig als Monitor beziehungsweise Sniffer für
|
||
den übertragenen seriellen Datenverkehr.
|
||
|
||
### 5. Client-Konfiguration für den lokalen Test
|
||
|
||
Für den lokalen Test kann `configs/client.json` beispielsweise so aussehen:
|
||
|
||
```json
|
||
{
|
||
"server": {
|
||
"address": "127.0.0.1",
|
||
"port": 5000
|
||
},
|
||
"virtual_port_range": {
|
||
"first": 100,
|
||
"last": 199
|
||
},
|
||
"virtual_ports": [
|
||
{
|
||
"port": "/dev/ttyUSB100",
|
||
"remote_device": "rotor",
|
||
"startup_bytes": "57 00 00 00 00 00 00 00 00 00 00 1F 20"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
Der öffentliche virtuelle Port `/dev/ttyUSB100` muss vorher wie im Abschnitt
|
||
zur manuellen Einrichtung der virtuellen Ports einmalig angelegt worden sein.
|
||
|
||
### 6. Client starten
|
||
|
||
In einem dritten Terminal:
|
||
|
||
```bash
|
||
cd ~/rs2322tcp
|
||
go run ./cmd/rs2322tcp-client
|
||
```
|
||
|
||
Nach erfolgreichem Verbindungsaufbau werden die konfigurierten `startup_bytes`
|
||
automatisch zum zugeordneten Rotor übertragen.
|
||
|
||
Der Server-Monitor muss dann den vollständigen Ablauf
|
||
|
||
```text
|
||
TCP RX -> SERIAL TX -> SERIAL RX -> TCP TX
|
||
```
|
||
|
||
zeigen.
|
||
|
||
Damit ist der gesamte Datenweg vom virtuellen Client-Port über TCP zum
|
||
simulierten Rotor und wieder zurück geprüft.
|
||
|
||
### 7. Virtuellen Port direkt testen
|
||
|
||
Eine Antwort kann beispielsweise mit
|
||
|
||
```bash
|
||
cat /dev/ttyUSB100 | xxd -g 1
|
||
```
|
||
|
||
beobachtet werden.
|
||
|
||
In einem zweiten Terminal kann eine Rotor-Anfrage gesendet werden:
|
||
|
||
```bash
|
||
printf '\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x20' > /dev/ttyUSB100
|
||
```
|
||
|
||
Der Rückweg erfolgt über denselben vollständigen Datenpfad zurück zu
|
||
`/dev/ttyUSB100`.
|
||
|
||
### Hinweis zu `/dev/pts/N`
|
||
|
||
`/dev/pts/N` wird in diesem Aufbau ausschließlich als temporärer Test-Port
|
||
für den PTY-Simulator verwendet. Die Nummer ist nicht dauerhaft und kann sich
|
||
nach einem Neustart des Simulators ändern.
|
||
|
||
Im produktiven Betrieb sind die serverseitigen Geräte dagegen echte,
|
||
fest angeschlossene Hardware-Schnittstellen, beispielsweise:
|
||
|
||
```text
|
||
/dev/ttyUSB0
|
||
/dev/ttyUSB1
|
||
/dev/ttyUSB3
|
||
```
|
||
|
||
## 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.
|
||
|
||
Für die Linux-PTY-Funktion und den beschriebenen Simulationsaufbau wird
|
||
`rs2322tcp` ohne `socat` betrieben. Die benötigten PTYs werden direkt aus Go
|
||
erzeugt.
|
||
|
||
## Hardwaretest mit SPID Rot2Prog
|
||
|
||
Für den praktischen Hardwaretest wurde ein SPID Rot2Prog als
|
||
Antennenrotor über einen FT232R USB-to-RS232-Adapter angeschlossen.
|
||
|
||
Unter Linux wurde der Adapter als:
|
||
|
||
```text
|
||
/dev/ttyUSB0
|
||
```
|
||
|
||
erkannt.
|
||
|
||
Der Rot2Prog verwendet für die RS232-Kommunikation:
|
||
|
||
```text
|
||
600 Baud
|
||
8 Datenbits
|
||
keine Parität
|
||
1 Stopbit
|
||
```
|
||
|
||
also:
|
||
|
||
```text
|
||
600 8N1
|
||
```
|
||
|
||
### Rotor einschalten
|
||
|
||
Vor dem Kommunikationstest muss der SPID-Rot2Prog eingeschaltet sein.
|
||
|
||
Der Controller muss für die serielle Steuerung im SPID-/Auto-Betrieb
|
||
betrieben werden.
|
||
|
||
Der Zustand des Controllers kann über die vorhandenen Bedientasten
|
||
und die LED-Anzeigen kontrolliert werden.
|
||
|
||
### Direkter Hardwaretest
|
||
|
||
Der serielle Port kann zunächst unabhängig von `rs2322tcp` getestet
|
||
werden:
|
||
|
||
```bash
|
||
stty -F /dev/ttyUSB0 600 cs8 -cstopb -parenb raw -echo
|
||
```
|
||
|
||
Kontrolle:
|
||
|
||
```bash
|
||
stty -F /dev/ttyUSB0
|
||
```
|
||
|
||
Anschließend kann die serielle Antwort des Controllers beobachtet werden:
|
||
|
||
```bash
|
||
cat /dev/ttyUSB0 | xxd -g 1
|
||
```
|
||
|
||
Eine Statusabfrage kann beispielsweise mit folgendem Paket gesendet
|
||
werden:
|
||
|
||
```bash
|
||
printf '\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x20' > /dev/ttyUSB0
|
||
```
|
||
|
||
Bei erfolgreicher Kommunikation antwortet der Rot2Prog mit einem
|
||
12-Byte-Datenpaket.
|
||
|
||
### Test über rs2322tcp
|
||
|
||
Nach erfolgreichem direkten Hardwaretest wird der reale serielle Port
|
||
im Server konfiguriert:
|
||
|
||
```text
|
||
Rotor:
|
||
/dev/ttyUSB0
|
||
600 Baud
|
||
8 Datenbits
|
||
keine Parität
|
||
1 Stopbit
|
||
```
|
||
|
||
Der Client stellt dem Anwender dafür beispielsweise den virtuellen Port:
|
||
|
||
```text
|
||
/dev/ttyUSB101
|
||
```
|
||
|
||
zur Verfügung.
|
||
|
||
Die gleiche Statusabfrage kann anschließend über den vollständigen
|
||
rs2322tcp-Datenpfad gesendet werden:
|
||
|
||
```bash
|
||
printf '\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x20' > /dev/ttyUSB101
|
||
```
|
||
|
||
Der Datenweg ist dann:
|
||
|
||
```text
|
||
/dev/ttyUSB101
|
||
│
|
||
▼
|
||
rs2322tcp-client
|
||
│
|
||
│ TCP
|
||
▼
|
||
rs2322tcp-server
|
||
│
|
||
▼
|
||
/dev/ttyUSB0
|
||
│
|
||
│ 600 Baud / 8N1
|
||
▼
|
||
SPID Rot2Prog
|
||
│
|
||
│ Antwort
|
||
▼
|
||
rs2322tcp-server
|
||
│
|
||
│ TCP
|
||
▼
|
||
rs2322tcp-client
|
||
│
|
||
▼
|
||
/dev/ttyUSB101
|
||
```
|
||
|
||
Damit kann die Antwort des Rotors wieder über den virtuellen seriellen
|
||
Port gelesen werden.
|
||
|
||
Ein erfolgreich beobachteter Antwort-Datenstrom war:
|
||
|
||
```text
|
||
57 03 06 05 0C 01 03 06 02 0F 01 20
|
||
```
|
||
|
||
Damit wurde die bidirektionale Übertragung zwischen dem virtuellen
|
||
seriellen Port des Clients und dem realen SPID-Rot2Prog über TCP
|
||
erfolgreich nachgewiesen.
|
||
|
||
## 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 stellt
|
||
eine simulierte serielle Gegenstelle bereit.
|
||
|
||
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 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.
|
||
|
||
Die Verwaltung der virtuellen Ports verfügt über Tests für:
|
||
|
||
- automatische Portreservierung
|
||
- gezielte Reservierung einer konfigurierten Portnummer
|
||
- Freigabe virtueller Ports
|
||
- Erstellung und Entfernung der internen PTY-Links
|
||
- Abgleich vorhandener virtueller Ports mit der Client-Konfiguration
|
||
|
||
Die Gerätezuordnung verfügt über Tests für:
|
||
|
||
- Zuordnung von Geräten zu virtuellen Ports
|
||
- Freigabe virtueller Ports
|
||
- Vermeidung doppelter Zuordnungen
|
||
- Speicherung der Konfiguration
|
||
- Laden der gespeicherten Zuordnung
|
||
|
||
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/
|
||
│ ├── com0com-test/
|
||
│ ├── rs2322tcp-client/
|
||
│ ├── rs2322tcp-client-test/
|
||
│ ├── rs2322tcp-device-sim/
|
||
│ ├── rs2322tcp-pty-test/
|
||
│ └── 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
|
||
|
||
Die gemeinsame Client-Architektur ist für eine spätere
|
||
Windows-Unterstützung vorbereitet.
|
||
|
||
## 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 Entwicklungsstand:
|
||
|
||
- `v0.0.1` – Projektgrundlage und Buildsystem
|
||
- `v0.0.2` – Client-Control- und Data-Verbindungen
|
||
- `v0.0.3` – Linux-PTY-Unterstützung und Geräte-Simulator
|
||
- `v0.0.4` – interaktive TX-Funktion des Geräte-Simulators
|
||
- `v0.0.5` – konfigurierbare lokale virtuelle serielle Ports
|
||
- `v0.0.6` – Client-Runtime und Serial-Bridge
|
||
- `0.0.7` – Geräteerkennung und grafische Gerätezuordnung
|
||
- `0.0.8` – Validierung der virtuellen Ports und Überarbeitung der Client-GUI
|
||
|
||
## Entwicklungsstand
|
||
|
||
Das Projekt befindet sich weiterhin in der 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-Runtime zur Verwaltung mehrerer virtueller Ports
|
||
- gezielte Zuordnung konfigurierter virtueller Portnummern
|
||
- 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
|
||
- grafische Gerätezuordnung im Client
|
||
- Speicherung der Gerätezuordnung in `client.json`
|
||
- Laden der Gerätezuordnung beim Neustart
|
||
- Validierung der vorhandenen virtuellen Ports beim Clientstart
|
||
- Abgleich von vorhandenen Symlinks und konfigurierten virtuellen Ports
|
||
- Linux-Portverwaltung ohne Root-Rechte im laufenden Client
|
||
- verständlicher Fehlerdialog bei fehlerhafter Portkonfiguration
|
||
- anpassbare allgemeine Schriftgröße der GUI
|
||
- überarbeitete Fenstergrößen der GUI
|
||
|
||
Noch nicht vollständig implementiert sind insbesondere:
|
||
|
||
- die Windows-Implementierung der virtuellen seriellen Schnittstelle
|
||
- automatische Geräteantworten und Protokollsimulation
|
||
- weitere produktive Funktionen des Clients und der GUI
|
||
- weiterführende Diagnose- und Logging-Funktionen
|
||
|
||
## Lizenz
|
||
|
||
GPL-3.0-or-later
|