Extend device simulator with interactive TX
This commit is contained in:
parent
2a61b5a79c
commit
ea4499b93f
4 changed files with 536 additions and 178 deletions
150
CHANGELOG.md
150
CHANGELOG.md
|
|
@ -2,58 +2,102 @@
|
||||||
|
|
||||||
Alle wesentlichen Änderungen am Projekt werden in dieser Datei dokumentiert.
|
Alle wesentlichen Änderungen am Projekt werden in dieser Datei dokumentiert.
|
||||||
|
|
||||||
## [Unreleased]
|
## [0.0.4] - 2026-08-10
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Linux-PTY-Unterstützung für die clientseitige virtuelle serielle Schnittstelle
|
|
||||||
|
- Interaktiver Geräte-Simulator `rs2322tcp-device-sim`
|
||||||
|
- Senden beliebiger Bytefolgen über eine interaktive Hex-Eingabe
|
||||||
|
- Ausgabe empfangener Daten als Hex-Dump
|
||||||
|
- Unterstützung von Hex-Eingaben mit und ohne Leerzeichen
|
||||||
|
- Fehlerbehandlung für ungültige Hex-Eingaben
|
||||||
|
- Automatisierte Tests für die Hex-Konvertierung
|
||||||
|
- Erweiterte Dokumentation des Geräte-Simulators und des PTY-Testaufbaus
|
||||||
|
- Möglichkeit, den Simulator als virtuelle serielle Gegenstelle für
|
||||||
|
externe Software zu verwenden
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
- Byte-orientierte Übertragung mit beliebigen Binärdaten getestet
|
||||||
|
- Übertragung aller Bytewerte `00` bis `FF` getestet
|
||||||
|
- Übertragung vom PTY-Slave zum PTY-Master getestet
|
||||||
|
- Übertragung vom PTY-Master zum PTY-Slave getestet
|
||||||
|
- `go test ./...` erfolgreich
|
||||||
|
- `go test -race ./...` erfolgreich
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.0.3] - 2026-08-10
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Linux-PTY-Unterstützung für die clientseitige virtuelle serielle
|
||||||
|
Schnittstelle
|
||||||
- Abstraktion der virtuellen seriellen Schnittstelle über `VirtualSerial`
|
- Abstraktion der virtuellen seriellen Schnittstelle über `VirtualSerial`
|
||||||
- Automatisierter bidirektionaler PTY-Test mit allen 256 möglichen Bytewerten
|
- Automatisierter bidirektionaler PTY-Test mit allen 256 möglichen Bytewerten
|
||||||
- Eigenständiges Programm `rs2322tcp-device-sim` als Simulator für ein angeschlossenes serielles Gerät
|
- Eigenständiges Programm `rs2322tcp-device-sim` als Simulator für ein
|
||||||
|
angeschlossenes serielles Gerät
|
||||||
- Hexadezimale Darstellung der vom Geräte-Simulator empfangenen Rohdaten
|
- Hexadezimale Darstellung der vom Geräte-Simulator empfangenen Rohdaten
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
- PTY-Slave und PTY-Master erfolgreich miteinander getestet
|
||||||
|
- Bidirektionale Übertragung von Binärdaten getestet
|
||||||
|
- Bytefolgen mit Werten von `00` bis `FF` erfolgreich übertragen
|
||||||
|
- Empfang beliebiger Datenblöcke über den PTY-Master getestet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.0.2] - 2026-08-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
- Implementierung der seriellen Schnittstellenschicht unter `internal/serial`
|
- Implementierung der seriellen Schnittstellenschicht unter `internal/serial`
|
||||||
- Verwendung von `go.bug.st/serial v1.7.1` für die Ansteuerung der seriellen Schnittstellen
|
- Verwendung von `go.bug.st/serial v1.7.1` für die Ansteuerung der seriellen Schnittstellen
|
||||||
- Konfigurationsunterstützung für Baudrate, Datenbits, Parität und Stopbits
|
- Konfigurationsunterstützung für Baudrate, Datenbits, Parität und Stopbits
|
||||||
- Öffnen und Schließen serieller Schnittstellen über die interne Serial-Abstraktion
|
- Serielle Geräte können über Konfiguration definiert werden
|
||||||
- Lesen und Schreiben von RS232-Daten über die Serial-Abstraktion
|
- Server-Control-Verbindung
|
||||||
- Dynamische TCP-Data-Listener für konfigurierte Geräte
|
- Session-Verwaltung
|
||||||
- Session-Verwaltung für dynamische Data-Listener
|
- Dynamische Data-Ports pro Gerät
|
||||||
- Session-Verwaltung für aktive DataConnections
|
- Serverseitiger Aufbau der TCP-Data-Verbindung
|
||||||
- Bidirektionale Datenübertragung zwischen TCP und RS232
|
- `DataConnection` für die bidirektionale Datenübertragung
|
||||||
- Öffnen der seriellen Schnittstelle erst beim Aufbau einer tatsächlichen Data-Verbindung
|
- `DataListener` zur Annahme von Data-Verbindungen
|
||||||
- Begrenzung auf eine aktive Data-Verbindung pro konfiguriertem Gerät
|
- TCP → RS232 Datenübertragung
|
||||||
- Integrationstest mit virtuellen seriellen Schnittstellen über `socat`
|
- RS232 → TCP Datenübertragung
|
||||||
- Tests für TCP → RS232 und RS232 → TCP
|
|
||||||
- Tests für Session-Reconnect und Ressourcenverwaltung
|
|
||||||
- Client-Control-Verbindung unter `internal/client`
|
- Client-Control-Verbindung unter `internal/client`
|
||||||
- Clientseitige Verarbeitung von `HELLO`
|
- Clientseitige Verarbeitung von `HELLO`
|
||||||
- Clientseitige Abfrage der konfigurierten Geräte über `GET_DEVICES`
|
- Clientseitige Abfrage der konfigurierten Geräte über `GET_DEVICES`
|
||||||
- Clientseitige Verarbeitung der vom Server gelieferten Geräteinformationen einschließlich dynamischem Data-Port
|
- Clientseitige Verarbeitung der vom Server gelieferten Geräteinformationen
|
||||||
|
einschließlich dynamischem Data-Port
|
||||||
- Clientseitiger Aufbau der TCP-Data-Verbindung
|
- Clientseitiger Aufbau der TCP-Data-Verbindung
|
||||||
- Integrationstest für die vollständige Client-/Server-Kommunikation
|
- Integrationstest für die vollständige Client-/Server-Kommunikation
|
||||||
- End-to-End-Test der TCP-/RS232-Datenübertragung in beide Richtungen
|
- End-to-End-Test der TCP-/RS232-Datenübertragung in beide Richtungen
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Go-Version des Projektes auf Go `1.25.0` aktualisiert
|
- Serial-Kommunikation vollständig über `go.bug.st/serial`
|
||||||
- `go.bug.st/serial` wird in Version `v1.7.1` verwendet
|
- Server öffnet serielle Schnittstellen erst bei aktiver Data-Verbindung
|
||||||
- `golang.org/x/sys v0.43.0` wird als indirekte Abhängigkeit verwendet
|
- Pro Gerät wird nur eine aktive Data-Verbindung zugelassen
|
||||||
- Die Serial-Bibliothek `go.bug.st/serial` wurde zusätzlich auf dem privaten Git-Server des Projektes als Ausfallsicherung gespiegelt:
|
- Session- und Ressourcenverwaltung überarbeitet
|
||||||
`git.lang-dieter.de/third-party/go-serial`
|
- Race Condition im `DataListener` behoben
|
||||||
- Der `DataListener` wurde nebenläufigkeitssicher implementiert
|
|
||||||
- Das Schließen eines `DataListener` kann gleichzeitig mit einem laufenden `Accept()` erfolgen
|
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- `go test ./...` erfolgreich
|
- Unit-Tests für Serial
|
||||||
- `go test -race ./...` erfolgreich
|
- Unit-Tests für Session
|
||||||
- Race Condition im `DataListener` erkannt und behoben
|
- Unit-Tests für DataConnection
|
||||||
|
- Unit-Tests für DataListener
|
||||||
|
- Integrationstest mit virtuellen seriellen Schnittstellen über `socat`
|
||||||
|
- Tests für TCP → RS232 und RS232 → TCP
|
||||||
|
- Tests für Session-Reconnect und Ressourcenverwaltung
|
||||||
- Client-/Server-Integrationstest erfolgreich
|
- Client-/Server-Integrationstest erfolgreich
|
||||||
- Race-Test des Client-/Server-Integrationstests erfolgreich
|
- Race-Test des Client-/Server-Integrationstests erfolgreich
|
||||||
- Automatisierter bidirektionaler PTY-Test mit einem vollständigen Bytebereich von `0x00` bis `0xFF`
|
|
||||||
- Race-Detection für die neue Linux-PTY-Komponente erfolgreich
|
|
||||||
### Status
|
### Status
|
||||||
|
|
||||||
Die grundlegende TCP-/RS232-Datenübertragung ist serverseitig implementiert und der Client kann inzwischen die Control-Verbindung sowie die zugehörige Data-Verbindung aufbauen.
|
Die grundlegende TCP-/RS232-Datenübertragung ist serverseitig implementiert
|
||||||
|
und der Client kann die Control-Verbindung sowie die zugehörige
|
||||||
|
Data-Verbindung aufbauen.
|
||||||
|
|
||||||
Der aktuelle Datenpfad ist:
|
Der aktuelle Datenpfad ist:
|
||||||
|
|
||||||
|
|
@ -103,49 +147,19 @@ Der Geräte-Simulator ist als eigenständiges Testprogramm vorhanden und kann
|
||||||
eine serielle Schnittstelle öffnen und empfangene Rohdaten hexadezimal
|
eine serielle Schnittstelle öffnen und empfangene Rohdaten hexadezimal
|
||||||
anzeigen.
|
anzeigen.
|
||||||
|
|
||||||
Die TX-Funktion des Geräte-Simulators sowie die vollständige Integration der
|
Die interaktive TX-Funktion des Geräte-Simulators sowie die vollständige
|
||||||
virtuellen seriellen Schnittstelle in den Client-Datenpfad sind noch nicht
|
Integration der virtuellen seriellen Schnittstelle in den produktiven
|
||||||
implementiert.
|
Client-Datenpfad sind noch nicht abgeschlossen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## [0.0.1] - 2026-08-09
|
## [0.0.1] - 2026-08-09
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Grundstruktur des Projektes `rs2322tcp`
|
- Initiale Projektstruktur
|
||||||
- Go-Modul `git.lang-dieter.de/rs2322tcp`
|
- Go-Modul und Build-Grundlagen
|
||||||
- separates Programmgerüst für `rs2322tcp-client`
|
- Basis für Server und Client
|
||||||
- separates Programmgerüst für `rs2322tcp-server`
|
- Konfigurationsgrundlagen
|
||||||
- gemeinsame Versionierungsinformationen
|
- Versionsverwaltung und Build-Metadaten
|
||||||
- Git-basierte Build-Informationen
|
- Erste Dokumentation
|
||||||
- zentrales Build-Skript `scripts/build.sh`
|
|
||||||
- automatische Quellcode-Formatierung beim Build
|
|
||||||
- automatische Tests beim Build
|
|
||||||
- SHA256-Prüfsummen der erzeugten Binärdateien
|
|
||||||
- `.gitignore` für Build- und Entwicklungsdateien
|
|
||||||
- erste Projekt- und Architekturdokumentation
|
|
||||||
|
|
||||||
### Build-Ziele
|
|
||||||
|
|
||||||
Der erste Build unterstützt:
|
|
||||||
|
|
||||||
- Linux amd64 – Client und Server
|
|
||||||
- Linux arm64 – Server
|
|
||||||
- Windows amd64 – Client
|
|
||||||
|
|
||||||
### Architekturentscheidungen
|
|
||||||
|
|
||||||
- TCP wird für die Übertragung der RS232-Daten verwendet.
|
|
||||||
- Windows und Linux werden als gleichberechtigte Client-Plattformen betrachtet.
|
|
||||||
- Der Server ist zunächst für den Raspberry Pi 5 vorgesehen.
|
|
||||||
- Tailscale wird als vertrauenswürdiges Netzwerk verwendet.
|
|
||||||
- Eine zusätzliche TLS-Schicht ist zunächst nicht vorgesehen.
|
|
||||||
- Für eine spätere Audioübertragung ist ein separates UDP-basiertes Transportkonzept vorgesehen.
|
|
||||||
- `socat` kann für Entwicklung und Diagnose eingesetzt werden.
|
|
||||||
- Eine Sniffer-/Logging-Funktion für den übertragenen Datenverkehr ist vorgesehen.
|
|
||||||
|
|
||||||
### Status
|
|
||||||
|
|
||||||
Version `0.0.1` enthält ausschließlich die Projektgrundlage.
|
|
||||||
|
|
||||||
Die eigentliche TCP-/RS232-Kommunikation und die virtuelle serielle Schnittstelle sind noch nicht implementiert.
|
|
||||||
|
|
|
||||||
309
README.md
309
README.md
|
|
@ -22,13 +22,13 @@ Verbindung über ein Netzwerk erfolgt.
|
||||||
|
|
||||||
Typische Anwendungen sind beispielsweise:
|
Typische Anwendungen sind beispielsweise:
|
||||||
|
|
||||||
- Funkgeräte mit CAT-Steuerung
|
- Funkgeräte mit CAT-Steuerung
|
||||||
- Antennenrotoren mit herstellerspezifischen seriellen Protokollen
|
- Antennenrotoren mit herstellerspezifischen seriellen Protokollen
|
||||||
- andere Geräte, die über RS232 gesteuert werden
|
- andere Geräte, die über RS232 gesteuert werden
|
||||||
|
|
||||||
## Architektur
|
## Architektur
|
||||||
|
|
||||||
``` text
|
```text
|
||||||
Client-PC Raspberry Pi 5
|
Client-PC Raspberry Pi 5
|
||||||
───────────────── ─────────────────
|
───────────────── ─────────────────
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ rs2322tcp-client │
|
||||||
|
|
||||||
Die serverseitige TCP-/RS232-Verbindung ist implementiert:
|
Die serverseitige TCP-/RS232-Verbindung ist implementiert:
|
||||||
|
|
||||||
``` text
|
```text
|
||||||
TCP-Control
|
TCP-Control
|
||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
|
|
@ -80,7 +80,7 @@ Pro konfiguriertem Gerät ist nur eine aktive Data-Verbindung vorgesehen.
|
||||||
|
|
||||||
Die Datenübertragung erfolgt bidirektional:
|
Die Datenübertragung erfolgt bidirektional:
|
||||||
|
|
||||||
``` text
|
```text
|
||||||
TCP ───────────────► RS232
|
TCP ───────────────► RS232
|
||||||
TCP ◄────────────── RS232
|
TCP ◄────────────── RS232
|
||||||
```
|
```
|
||||||
|
|
@ -90,8 +90,8 @@ TCP ◄────────────── RS232
|
||||||
Der Client soll gleichberechtigt unter folgenden Betriebssystemen
|
Der Client soll gleichberechtigt unter folgenden Betriebssystemen
|
||||||
eingesetzt werden können:
|
eingesetzt werden können:
|
||||||
|
|
||||||
- Windows
|
- Windows
|
||||||
- Linux
|
- Linux
|
||||||
|
|
||||||
Die plattformspezifische Bereitstellung der virtuellen seriellen
|
Die plattformspezifische Bereitstellung der virtuellen seriellen
|
||||||
Schnittstelle wird vom gemeinsamen Client-Kern getrennt.
|
Schnittstelle wird vom gemeinsamen Client-Kern getrennt.
|
||||||
|
|
@ -126,7 +126,7 @@ Die serverseitige Serial-Kommunikation verwendet `go.bug.st/serial`.
|
||||||
|
|
||||||
Für die Ansteuerung der seriellen Schnittstellen wird derzeit verwendet:
|
Für die Ansteuerung der seriellen Schnittstellen wird derzeit verwendet:
|
||||||
|
|
||||||
``` text
|
```text
|
||||||
go.bug.st/serial v1.7.1
|
go.bug.st/serial v1.7.1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ Die Bibliothek wurde zusätzlich auf dem privaten Git-Server des
|
||||||
Projektes gespiegelt, um bei einem Ausfall des ursprünglichen Anbieters
|
Projektes gespiegelt, um bei einem Ausfall des ursprünglichen Anbieters
|
||||||
weiterhin auf den verwendeten Quellstand zugreifen zu können:
|
weiterhin auf den verwendeten Quellstand zugreifen zu können:
|
||||||
|
|
||||||
``` text
|
```text
|
||||||
git.lang-dieter.de/third-party/go-serial
|
git.lang-dieter.de/third-party/go-serial
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -161,14 +161,14 @@ Client und Server erhalten jeweils eine eigene JSON-Konfiguration.
|
||||||
|
|
||||||
Über die Konfiguration werden unter anderem festgelegt:
|
Über die Konfiguration werden unter anderem festgelegt:
|
||||||
|
|
||||||
- Netzwerkparameter
|
- Netzwerkparameter
|
||||||
- serielle Schnittstelle
|
- serielle Schnittstelle
|
||||||
- Baudrate
|
- Baudrate
|
||||||
- Datenbits
|
- Datenbits
|
||||||
- Parität
|
- Parität
|
||||||
- Stopbits
|
- Stopbits
|
||||||
- Bezeichnung des Gerätes
|
- Bezeichnung des Gerätes
|
||||||
- weitere für die jeweilige Schnittstelle erforderliche Parameter
|
- weitere für die jeweilige Schnittstelle erforderliche Parameter
|
||||||
|
|
||||||
Die konkrete Konfigurationsstruktur befindet sich in der Entwicklung.
|
Die konkrete Konfigurationsstruktur befindet sich in der Entwicklung.
|
||||||
|
|
||||||
|
|
@ -191,7 +191,7 @@ Für den Linux-Client wird die virtuelle serielle Schnittstelle direkt
|
||||||
|
|
||||||
Dabei entsteht ein PTY-Paar:
|
Dabei entsteht ein PTY-Paar:
|
||||||
|
|
||||||
``` text
|
```text
|
||||||
/dev/ptmx
|
/dev/ptmx
|
||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
|
|
@ -223,42 +223,157 @@ Der Simulator ist bewusst als eigenständiges Programm ausgeführt. Der
|
||||||
`rs2322tcp-server` muss nicht wissen, ob am seriellen Port ein echtes
|
`rs2322tcp-server` muss nicht wissen, ob am seriellen Port ein echtes
|
||||||
Gerät oder der Simulator angeschlossen ist.
|
Gerät oder der Simulator angeschlossen ist.
|
||||||
|
|
||||||
Der aktuelle Simulator kann eine serielle Schnittstelle öffnen und
|
Der Simulator kann:
|
||||||
empfangene Rohdaten als Hexdump anzeigen.
|
|
||||||
|
- 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:
|
Beispiel:
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
rs2322tcp-device-sim -port /dev/pts/7
|
go run ./cmd/rs2322tcp-device-sim -port /dev/pts/7
|
||||||
```
|
```
|
||||||
|
|
||||||
Beispielausgabe:
|
Zum Senden wird eine Hex-Folge eingegeben:
|
||||||
|
|
||||||
``` text
|
```text
|
||||||
rs2322tcp-device-sim
|
TX> 46 41 00 10 0D
|
||||||
Port: /dev/pts/7
|
```
|
||||||
Warte auf Daten ...
|
|
||||||
|
|
||||||
12:34:01.123 RX 5 Bytes
|
Der Simulator überträgt diese fünf Bytes.
|
||||||
|
|
||||||
|
Empfangene Daten werden beispielsweise so angezeigt:
|
||||||
|
|
||||||
|
```text
|
||||||
|
RX 5 Bytes
|
||||||
46 41 00 10 0D
|
46 41 00 10 0D
|
||||||
```
|
```
|
||||||
|
|
||||||
Die Daten werden zunächst nicht interpretiert. Dadurch kann der
|
Die Hex-Eingabe kann mit oder ohne Leerzeichen erfolgen:
|
||||||
Simulator auch zum Beobachten unbekannter serieller Protokolle verwendet
|
|
||||||
werden.
|
```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
|
Der Simulator soll insbesondere auch als Sniffer dienen können, wenn
|
||||||
externe Hersteller-Software untersucht werden soll. Dadurch lassen sich
|
externe Hersteller-Software untersucht werden soll. Dadurch lassen sich
|
||||||
die von einer Software gesendeten seriellen Kommandos zunächst als
|
die von einer Software gesendeten seriellen Kommandos zunächst als
|
||||||
Rohdaten beobachten.
|
Rohdaten beobachten.
|
||||||
|
|
||||||
Geplante Erweiterungen sind:
|
Geplante bzw. mögliche Erweiterungen sind:
|
||||||
|
|
||||||
- manuelles Senden von Rohbytes
|
- automatische Geräteantworten
|
||||||
- Anzeige von RX und TX
|
- Protokollsimulation
|
||||||
- automatische Geräteantworten
|
- Aufzeichnung und Wiedergabe von Datenströmen
|
||||||
- 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
|
## Tests
|
||||||
|
|
||||||
|
|
@ -266,46 +381,36 @@ Die wichtigsten Komponenten verfügen über automatisierte Tests.
|
||||||
|
|
||||||
Der aktuelle Stand wird unter anderem mit folgenden Befehlen geprüft:
|
Der aktuelle Stand wird unter anderem mit folgenden Befehlen geprüft:
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
go test ./...
|
go test ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
und:
|
und:
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
go test -race ./...
|
go test -race ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
Der Race Detector wird eingesetzt, um Probleme bei der nebenläufigen
|
Der Race Detector wird eingesetzt, um Probleme bei der nebenläufigen
|
||||||
Verarbeitung von Sessions, Data-Listenern und DataConnections zu
|
Verarbeitung von Sessions, Data-Listenern, DataConnections und Client-
|
||||||
erkennen.
|
Komponenten zu erkennen.
|
||||||
|
|
||||||
Die Linux-PTY-Komponente verfügt über einen automatisierten
|
Die Linux-PTY-Komponente wurde mit einem vollständigen Bytebereich von
|
||||||
bidirektionalen Byte-Test.
|
`0x00` bis `0xFF` geprüft.
|
||||||
|
|
||||||
Dabei werden alle 256 möglichen Bytewerte übertragen:
|
Der Geräte-Simulator verfügt zusätzlich über automatisierte Tests für
|
||||||
|
die Hex-Konvertierung und die Behandlung ungültiger Eingaben.
|
||||||
|
|
||||||
``` text
|
Für die Prüfung des Arbeitsbaums:
|
||||||
00 01 02 03 ... FD FE FF
|
|
||||||
|
```bash
|
||||||
|
git diff --check
|
||||||
|
git status
|
||||||
```
|
```
|
||||||
|
|
||||||
Geprüft werden beide Richtungen:
|
|
||||||
|
|
||||||
``` text
|
|
||||||
PTY-Slave → Client
|
|
||||||
Client → PTY-Slave
|
|
||||||
```
|
|
||||||
|
|
||||||
Für den Integrationstest des Client-/Server-Datenpfades werden virtuelle
|
|
||||||
serielle Schnittstellen verwendet. Während der Entwicklung kann hierfür
|
|
||||||
`socat` eingesetzt werden.
|
|
||||||
|
|
||||||
Damit kann der Datenpfad ohne angeschlossene RS232-Hardware getestet
|
|
||||||
werden.
|
|
||||||
|
|
||||||
## Projektstruktur
|
## Projektstruktur
|
||||||
|
|
||||||
``` text
|
```text
|
||||||
rs2322tcp/
|
rs2322tcp/
|
||||||
├── cmd/
|
├── cmd/
|
||||||
│ ├── rs2322tcp-client/
|
│ ├── rs2322tcp-client/
|
||||||
|
|
@ -332,26 +437,26 @@ rs2322tcp/
|
||||||
|
|
||||||
Der Build erfolgt über das zentrale Build-Skript:
|
Der Build erfolgt über das zentrale Build-Skript:
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
./scripts/build.sh
|
./scripts/build.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Das Skript führt unter anderem folgende Schritte aus:
|
Das Skript führt unter anderem folgende Schritte aus:
|
||||||
|
|
||||||
- Formatierung des Go-Quellcodes
|
- Formatierung des Go-Quellcodes
|
||||||
- Ausführung der Tests
|
- Ausführung der Tests
|
||||||
- Bereinigung der Go-Module
|
- Bereinigung der Go-Module
|
||||||
- Ermittlung der Git-Versionsinformationen
|
- Ermittlung der Git-Versionsinformationen
|
||||||
- Build der vorgesehenen Zielplattformen
|
- Build der vorgesehenen Zielplattformen
|
||||||
- Einbettung der Versionsinformationen über den Go-Linker
|
- Einbettung der Versionsinformationen über den Go-Linker
|
||||||
- Erzeugung von SHA256-Prüfsummen
|
- Erzeugung von SHA256-Prüfsummen
|
||||||
|
|
||||||
Aktuell werden folgende Builds erzeugt:
|
Aktuell werden folgende Builds erzeugt:
|
||||||
|
|
||||||
- Linux amd64 -- Client und Server
|
- Linux amd64 -- Client und Server
|
||||||
- Linux arm64 -- Server
|
- Linux arm64 -- Server
|
||||||
- Linux armv7 -- Server
|
- Linux armv7 -- Server
|
||||||
- Linux armv6 -- Server
|
- Linux armv6 -- Server
|
||||||
|
|
||||||
## Versionierung
|
## Versionierung
|
||||||
|
|
||||||
|
|
@ -363,41 +468,45 @@ Build-Datum erfasst.
|
||||||
|
|
||||||
Release-Versionen werden über Git-Tags gekennzeichnet.
|
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
|
## Entwicklungsstand
|
||||||
|
|
||||||
Das Projekt befindet sich weiterhin in der frühen Entwicklungsphase.
|
Das Projekt befindet sich weiterhin in der frühen Entwicklungsphase.
|
||||||
|
|
||||||
Die ursprüngliche Projektgrundlage aus Version `0.0.1` wurde inzwischen
|
|
||||||
um eine funktionierende serverseitige TCP-/RS232-Datenübertragung und
|
|
||||||
die clientseitige Grundlage für virtuelle serielle Schnittstellen
|
|
||||||
erweitert.
|
|
||||||
|
|
||||||
Implementiert und getestet sind derzeit:
|
Implementiert und getestet sind derzeit:
|
||||||
|
|
||||||
- Server-Control-Verbindung
|
- Server-Control-Verbindung
|
||||||
- Session-Verwaltung
|
- Session-Verwaltung
|
||||||
- dynamische Data-Ports
|
- dynamische Data-Ports
|
||||||
- DataConnection
|
- DataConnection
|
||||||
- bidirektionale TCP-/RS232-Datenübertragung
|
- bidirektionale TCP-/RS232-Datenübertragung
|
||||||
- Serial-Abstraktion
|
- Serial-Abstraktion
|
||||||
- Konfiguration der seriellen Parameter
|
- Konfiguration der seriellen Parameter
|
||||||
- Client-Control-Verbindung
|
- Client-Control-Verbindung
|
||||||
- Client-DataConnection
|
- Client-DataConnection
|
||||||
- Client-Integrationstests
|
- Client-Integrationstests
|
||||||
- Linux-PTY-Abstraktion
|
- Linux-PTY-Abstraktion
|
||||||
- Linux-PTY im Raw Mode
|
- Linux-PTY im Raw Mode
|
||||||
- automatisierter bidirektionaler 256-Byte-PTY-Test
|
- automatisierter bidirektionaler 256-Byte-PTY-Test
|
||||||
- nebenläufigkeitssichere Data-Listener
|
- nebenläufigkeitssichere Data-Listener
|
||||||
- Race-Detection
|
- Race-Detection
|
||||||
- eigenständiger Geräte-Simulator mit RX-Hexdump
|
- 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:
|
Noch nicht vollständig implementiert sind insbesondere:
|
||||||
|
|
||||||
- die vollständige Anbindung der virtuellen seriellen Schnittstelle an
|
- die vollständige Anbindung der virtuellen seriellen Schnittstelle an
|
||||||
den produktiven Client-Anwendungsdatenpfad
|
den produktiven Client-Anwendungsdatenpfad
|
||||||
- die Windows-Implementierung der virtuellen seriellen Schnittstelle
|
- die Windows-Implementierung der virtuellen seriellen Schnittstelle
|
||||||
- TX-Funktion des Geräte-Simulators
|
- automatische Geräteantworten und Protokollsimulation
|
||||||
- automatische Geräteantworten und Protokollsimulation
|
|
||||||
|
|
||||||
## Lizenz
|
## Lizenz
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,24 +7,37 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*
|
*
|
||||||
* Beschreibung:
|
* Beschreibung:
|
||||||
* Einfacher Simulator für ein serielles Endgerät.
|
* Interaktiver Simulator für ein serielles Endgerät.
|
||||||
*
|
*
|
||||||
* Der Simulator öffnet eine angegebene serielle Schnittstelle und protokolliert
|
* Der Simulator öffnet eine angegebene serielle Schnittstelle und protokolliert
|
||||||
* alle vom angeschlossenen System empfangenen Bytes als Hexdump.
|
* alle vom angeschlossenen System empfangenen Bytes als Hexdump.
|
||||||
*
|
*
|
||||||
|
* Zusätzlich können über die Standardeingabe hexadezimal angegebene Bytefolgen
|
||||||
|
* an das serielle Gerät gesendet werden. Dadurch kann der Simulator sowohl als
|
||||||
|
* passiver Sniffer als auch als einfaches interaktives Testgerät verwendet
|
||||||
|
* werden.
|
||||||
|
*
|
||||||
* Der Simulator stellt bewusst keine eigene PTY-Erzeugung bereit. Für
|
* Der Simulator stellt bewusst keine eigene PTY-Erzeugung bereit. Für
|
||||||
* Entwicklung und Integrationstests kann ihm beispielsweise ein unter Linux
|
* Entwicklung und Integrationstests kann ihm beispielsweise ein unter Linux
|
||||||
* erzeugter PTY-Slave (/dev/pts/N) übergeben werden. Im späteren Testaufbau
|
* erzeugter PTY-Slave (/dev/pts/N) übergeben werden. Im späteren Testaufbau
|
||||||
* kann derselbe Simulator jedoch auch direkt mit einer echten seriellen
|
* kann derselbe Simulator jedoch auch direkt mit einer echten seriellen
|
||||||
* Schnittstelle verbunden werden.
|
* Schnittstelle verbunden werden.
|
||||||
*
|
*
|
||||||
* Der Simulator dient zunächst als passives Gegenstück zum
|
* Der Simulator dient zunächst als externes Gegenstück zum
|
||||||
* rs2322tcp-server. Er soll insbesondere ermöglichen, die vom Server an ein
|
* rs2322tcp-server. Er ermöglicht insbesondere, die vom Server an ein
|
||||||
* simuliertes Gerät übertragenen Bytes sichtbar zu machen.
|
* simuliertes Gerät übertragenen Bytes sichtbar zu machen und umgekehrt
|
||||||
|
* definierte Bytefolgen an den Server zurückzusenden.
|
||||||
*
|
*
|
||||||
* Zukünftige Erweiterungen können unter anderem das manuelle Senden von
|
* Eingabeformat:
|
||||||
* Bytes, automatische Geräteantworten, Protokollsimulation und das Aufzeichnen
|
*
|
||||||
* bzw. Wiedergeben von Datenströmen umfassen.
|
* TX> 46 41 00 10 0D
|
||||||
|
*
|
||||||
|
* Die Leerzeichen zwischen den Bytes sind optional. Groß- und Kleinschreibung
|
||||||
|
* der Hex-Ziffern spielt keine Rolle.
|
||||||
|
*
|
||||||
|
* Zukünftige Erweiterungen können unter anderem automatische Geräteantworten,
|
||||||
|
* Protokollsimulation und das Aufzeichnen bzw. Wiedergeben von Datenströmen
|
||||||
|
* umfassen.
|
||||||
*
|
*
|
||||||
* Aufruf:
|
* Aufruf:
|
||||||
*
|
*
|
||||||
|
|
@ -36,12 +49,16 @@
|
||||||
* Port: /dev/pts/7
|
* Port: /dev/pts/7
|
||||||
* Warte auf Daten ...
|
* Warte auf Daten ...
|
||||||
*
|
*
|
||||||
* Empfangene Daten werden mit Zeitstempel, Richtung und Byteanzahl ausgegeben:
|
* Empfangene und gesendete Daten werden mit Zeitstempel, Richtung und
|
||||||
|
* Byteanzahl ausgegeben:
|
||||||
*
|
*
|
||||||
* 12:34:01.123 RX 5 Bytes
|
* 12:34:01.123 RX 5 Bytes
|
||||||
* 46 41 00 10 0D
|
* 46 41 00 10 0D
|
||||||
*
|
*
|
||||||
* Der Simulator interpretiert die empfangenen Daten nicht. Die Darstellung
|
* 12:34:05.456 TX 5 Bytes
|
||||||
|
* 46 41 01 10 0D
|
||||||
|
*
|
||||||
|
* Der Simulator interpretiert die seriellen Daten nicht. Die Darstellung
|
||||||
* erfolgt ausschließlich als Rohdaten in hexadezimaler Form.
|
* erfolgt ausschließlich als Rohdaten in hexadezimaler Form.
|
||||||
*
|
*
|
||||||
* ============================================================================
|
* ============================================================================
|
||||||
|
|
@ -50,10 +67,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/hex"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
@ -92,6 +113,13 @@ func main() {
|
||||||
fmt.Printf("Port: %s\n", *port)
|
fmt.Printf("Port: %s\n", *port)
|
||||||
fmt.Println("Warte auf Daten ...")
|
fmt.Println("Warte auf Daten ...")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
fmt.Println("Hex-Bytes senden mit:")
|
||||||
|
fmt.Println("TX> 46 41 00 10 0D")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Die Standardeingabe wird parallel zur seriellen Schnittstelle gelesen.
|
||||||
|
// Dadurch kann der Simulator gleichzeitig Daten empfangen und senden.
|
||||||
|
go readTX(fd)
|
||||||
|
|
||||||
// Der Simulator arbeitet byteorientiert. Die Größe des Puffers ist
|
// Der Simulator arbeitet byteorientiert. Die Größe des Puffers ist
|
||||||
// bewusst ausreichend groß gewählt, damit auch größere Datenblöcke
|
// bewusst ausreichend groß gewählt, damit auch größere Datenblöcke
|
||||||
|
|
@ -135,15 +163,130 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// readTX liest Zeilen von stdin und interpretiert sie als Folge von
|
||||||
|
// hexadezimal angegebenen Bytes.
|
||||||
|
//
|
||||||
|
// Die Eingabe wird bewusst zeilenorientiert verarbeitet. Dadurch kann eine
|
||||||
|
// komplette Bytefolge zuerst geprüft werden, bevor sie an die serielle
|
||||||
|
// Schnittstelle gesendet wird.
|
||||||
|
func readTX(fd int) {
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
|
||||||
|
fmt.Print("TX> ")
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := strings.TrimSpace(scanner.Text())
|
||||||
|
|
||||||
|
if line == "" {
|
||||||
|
fmt.Print("TX> ")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := parseHexBytes(line)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Ungültige Hex-Eingabe: %v\n", err)
|
||||||
|
fmt.Print("TX> ")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) == 0 {
|
||||||
|
fmt.Print("TX> ")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeAll(fd, data); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Senden: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
printTX(data)
|
||||||
|
fmt.Print("TX> ")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Lesen von stdin: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bei EOF (Ctrl+D) wird der Dateideskriptor geschlossen. Dadurch wird
|
||||||
|
// der blockierende Lesevorgang im Haupt-Goroutine beendet und der
|
||||||
|
// Simulator kann sauber verlassen werden.
|
||||||
|
_ = unix.Close(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseHexBytes wandelt eine zeilenorientierte Hex-Eingabe in einen
|
||||||
|
// Byte-Block um.
|
||||||
|
//
|
||||||
|
// Leerzeichen zwischen den Bytes sind erlaubt und werden entfernt. Dadurch
|
||||||
|
// werden beispielsweise sowohl
|
||||||
|
//
|
||||||
|
// 46 41 00 10 0D
|
||||||
|
//
|
||||||
|
// als auch
|
||||||
|
//
|
||||||
|
// 464100100D
|
||||||
|
//
|
||||||
|
// akzeptiert. Die Funktion selbst enthält keine Ausgabe und ist deshalb
|
||||||
|
// unabhängig vom interaktiven Terminalbetrieb testbar.
|
||||||
|
func parseHexBytes(line string) ([]byte, error) {
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
hexText := strings.Join(fields, "")
|
||||||
|
|
||||||
|
if hexText == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := hex.DecodeString(hexText)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeAll schreibt alle Bytes des angegebenen Datenblocks auf den seriellen
|
||||||
|
// Dateideskriptor. unix.Write() darf weniger Bytes als angefordert schreiben.
|
||||||
|
func writeAll(fd int, data []byte) error {
|
||||||
|
for len(data) > 0 {
|
||||||
|
n, err := unix.Write(fd, data)
|
||||||
|
if err != nil {
|
||||||
|
if err == unix.EINTR {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return io.ErrShortWrite
|
||||||
|
}
|
||||||
|
|
||||||
|
data = data[n:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// printRX gibt einen empfangenen Datenblock als Hexdump aus.
|
// printRX gibt einen empfangenen Datenblock als Hexdump aus.
|
||||||
//
|
//
|
||||||
// Die Daten werden absichtlich nicht als Text interpretiert. Dadurch bleiben
|
// Die Daten werden absichtlich nicht als Text interpretiert. Dadurch bleiben
|
||||||
// auch nicht druckbare Bytes und Bytes oberhalb von 0x7F sichtbar und können
|
// auch nicht druckbare Bytes und Bytes oberhalb von 0x7F sichtbar und können
|
||||||
// bei der Analyse serieller Protokolle eindeutig nachvollzogen werden.
|
// bei der Analyse serieller Protokolle eindeutig nachvollzogen werden.
|
||||||
func printRX(data []byte) {
|
func printRX(data []byte) {
|
||||||
|
printHexDump("RX", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// printTX gibt einen gesendeten Datenblock als Hexdump aus.
|
||||||
|
func printTX(data []byte) {
|
||||||
|
printHexDump("TX", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// printHexDump gibt einen Datenblock mit Zeitstempel, Richtung und Byteanzahl
|
||||||
|
// als Hexdump aus.
|
||||||
|
func printHexDump(direction string, data []byte) {
|
||||||
fmt.Printf(
|
fmt.Printf(
|
||||||
"%s RX %d Bytes\n",
|
"%s %s %d Bytes\n",
|
||||||
time.Now().Format("15:04:05.000"),
|
time.Now().Format("15:04:05.000"),
|
||||||
|
direction,
|
||||||
len(data),
|
len(data),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
92
cmd/rs2322tcp-device-sim/main_test.go
Normal file
92
cmd/rs2322tcp-device-sim/main_test.go
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* ============================================================================
|
||||||
|
* Projekt.....: rs2322tcp
|
||||||
|
* Datei.......: main_test.go
|
||||||
|
* Copyright (C) 2026 Dieter Lang
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* Beschreibung:
|
||||||
|
* Unit-Tests für die Hex-Eingabe des Geräte-Simulators.
|
||||||
|
*
|
||||||
|
* Getestet werden gültige Bytefolgen, optionale Leerzeichen, Groß- und
|
||||||
|
* Kleinschreibung sowie typische ungültige Eingaben.
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseHexBytes(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
want []byte
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "mehrere Bytes mit Leerzeichen",
|
||||||
|
input: "46 41 00 10 0D",
|
||||||
|
want: []byte{0x46, 0x41, 0x00, 0x10, 0x0D},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mehrere Bytes ohne Leerzeichen",
|
||||||
|
input: "464100100D",
|
||||||
|
want: []byte{0x46, 0x41, 0x00, 0x10, 0x0D},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "gemischte Groß- und Kleinschreibung",
|
||||||
|
input: "0a FF 01 b7",
|
||||||
|
want: []byte{0x0A, 0xFF, 0x01, 0xB7},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ein Byte",
|
||||||
|
input: "00",
|
||||||
|
want: []byte{0x00},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "leere Eingabe",
|
||||||
|
input: "",
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nur Leerzeichen",
|
||||||
|
input: " ",
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ungültiges Hex-Zeichen",
|
||||||
|
input: "GG",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ungerade Hex-Länge",
|
||||||
|
input: "4",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "dreistellige Eingabe",
|
||||||
|
input: "100",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := parseHexBytes(tt.input)
|
||||||
|
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Fatalf("Fehlerstatus: got %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(got, tt.want) {
|
||||||
|
t.Fatalf("Ergebnis: got % X, want % X", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue