Maschinelle Übersetzung, nicht von einem Muttersprachler geprüft. Englisch ist die maßgebliche Fassung.

Empfängervertrauen und SeefahrtAuf GitHub bearbeitenQuelle: docs/MARINE-INTEGRATIONS.md

Maritime Integrationen: der Vertrauenswert auf der Brücke

Der maritime Vertrauenswert von Kshana (MARITIME-TRUST.md) ist aus Software erreichbar, die Bootsfahrer bereits nutzen: ein Signal K-Server-Plugin und OpenCPN über Gate-Modus-NMEA per TCP. Ein Referenzaufbau bringt ihn auf einen kleinen Rechner neben dem Empfänger.

Beratende Software. Kshana ist keine typzugelassene Navigationsausrüstung (IEC 61108, IEC 61162) und wurde an keinem Leistungsstandard bewertet. Alles auf dieser Seite ist eine Hilfe für das Urteil des Navigators. Der Betreiber bleibt für die sichere Navigation des Schiffes und für jede Entscheidung verantwortlich, sich auf eine Lösung zu verlassen oder sich nicht mehr auf sie zu verlassen. Nichts hier sendet, und nichts hier macht eine Lösung genauer.

Baustein Wo Status in 0,35
Signal-K-Plugin integrations/signalk/ ausgeliefert, an aufgezeichneter synthetischer Ausgabe einem Unit-Test unterzogen; nicht auf npm veröffentlicht
OpenCPN über Gate-Modus-NMEA per TCP integrations/opencpn/ ausgeliefert und getestet (Wiedergabe auf Verbraucherseite); die Benutzeroberfläche von OpenCPN selbst wird von keinem Test gesteuert
natives Score-Panel-Plugin für OpenCPN integrations/opencpn/plugin/ gebaut, Logik einem Unit-Test unterzogen und in OpenCPN 5.8.4 unter einem virtuellen Display ausgeführt (Nachweis in integrations/opencpn/evidence/); nicht für den Plugin-Manager paketiert; wird erst nach Prüfung ausgeliefert
Referenzaufbau deploy/reference-build/ Teile, Betriebssystemschritte, systemd-Units (per Trockenlauf geprüft), eine Container-Option; nicht auf einem Schiff getestet

Alles liest eine einzige Sache: die Ausgabe von kshana receiver-trust live (JSON-Zeilen, der Satz $PKSHT, das Gate). Die Übertragungsformate stehen in MARITIME-TRUST.md. Das Signal-K-Plugin hält sein Wissen darüber in einer einzigen Datei, integrations/signalk/lib/adapter.js; eine Formatänderung ist eine Änderung an einer Datei.

Signal-K-Plugin#

Keine npm-Abhängigkeiten. Das Plugin selbst läuft auf Node 18 oder neuer; aktuelle signalk-server-Versionen brauchen Node 22 oder neuer, nutzen Sie in der Praxis also 22. Kopieren oder verknüpfen Sie integrations/signalk/ in das node_modules des Servers (zum Beispiel ~/.signalk/node_modules/signalk-kshana-trust), starten Sie den Server neu und aktivieren Sie Kshana GNSS trust unter Server, Plugin Config.

Woher die Epochen kommen (source)#

source Was das Plugin tut
spawn-signalk-nmea (Standard) Führt kshana receiver-trust live <sessionFile> aus und schreibt jeden rohen NMEA-0183-Satz, den der Server empfängt (das Ereignis nmea0183 des Servers), auf dessen Standardeingabe. Startet es mit Back-off neu, wenn es endet | Verwenden Sie es nur auf einem Server mit einer einzigen NMEA-Quelle: Es speist jeden Satz von jedem Provider verschachtelt ein, sodass ein zweiter GNSS-Empfänger oder AIS wie ein Empfänger aussieht, dessen Position springt, und als Spoofing bewertet werden kann. Bei mehr als einer Quelle verwenden Sie spawn-args mit dem eigenen --tcp-Strom dieses Empfängers oder tcp-pksht von einem Gate.
spawn-args Führt kshana receiver-trust live <sessionFile> <inputArgs...> aus, zum Beispiel ["--tcp","192.0.2.10:10110"] oder ["--udp","10110"]
tcp-json Verbindet sich mit einem Feed der JSON-Zeilen, die kshana schreibt (zum Beispiel vom Relay in integrations/opencpn/)
tcp-pksht Verbindet sich mit einem NMEA-Strom (etwa der Gate-Ausgabe des Dienstes oder Containers im Referenzaufbau, Port 10110) und liest nur dessen $PKSHT-Sätze

Ein Strom, der bereits gespooft wird, wenn sich der Monitor zum ersten Mal verbindet, hat keine saubere Basislinie (die ersten calibration_s Sekunden werden nie bewertet). Starten Sie ihn vor der Fahrt.

Veröffentlichte Pfade#

Jede Epoche aktualisiert (Quelle kshana-trust):

Pfad Wert
navigation.gnss.kshana.band calibrating, nominal, degraded oder untrusted
navigation.gnss.kshana.score 0 bis 100 oder null während der Kalibrierung
navigation.gnss.kshana.reasons [{monitor, points}], größte zuerst: welche Prüfungen den Wert gesenkt haben
navigation.gnss.kshana.alarms die Monitore, die derzeit über ihrem Schwellenwert liegen
navigation.gnss.kshana.gate off, passed oder withheld (wenn anderswo ein Gate läuft; null von $PKSHT, wenn keines vorhanden ist)
navigation.gnss.kshana.reportedPosition {latitude, longitude, altitude}: die Position, die der zu prüfende Empfänger in dieser Epoche gemeldet hat (JSON-Schema 1,1 oder neuer; nicht veröffentlicht, wenn der Strom keine trägt, zum Beispiel von $PKSHT oder einem älteren kshana). Nur Vertrauenskontext: Das Plugin schreibt nie navigation.position, sodass der eigene Positionspfad des Schiffes unberührt bleibt
notifications.navigation.gnss.kshana.trust ausgelöst, wenn sich der Zustand ändert: {state, method, message}

Das Plugin sendet außerdem einmal beim Start Signal-K-Metadaten für diese Pfade. score ist der Vertrauenswert von Kshana von 0 bis 100, ein Wert und kein Verhältnis oder eine Wahrscheinlichkeit, daher trägt er keine SI-Einheit; seine Metadaten geben den Bereich, eine Beschreibung und Zonen an, die den Schwellenwerten unten folgen. reasons[].points sind Wertpunkte, die von diesem Wert von 0 bis 100 abgezogen werden.

Die Benachrichtigung ist normal, alert, warn oder alarm. Sie wird gelöscht, indem der Zustand normal veröffentlicht wird, nicht null: Ein Verbraucher, der nur null als gelöscht behandelt, sollte auch normal als gelöscht behandeln. Standardmäßig ergibt das Band degraded den Wert warn und das Band untrusted den Wert alarm, mit method: ["visual","sound"]. Sie wird nach clearAfterEpochs Epochen bei einem besseren Zustand zurückgenommen. Trifft für staleAfterS Sekunden keine Epoche ein, warnt sie, dass der Wert nicht aktualisiert wird. Die Kalibrierung löst nie eine Benachrichtigung aus. Die Quelle $PKSHT trägt keine Liste alarms (der Satz hat nur das Band, den Wert und die beiden wichtigsten Gründe).

Konfiguration (jeder Schwellenwert)#

Schlüssel Standard Bedeutung
source spawn-signalk-nmea siehe oben
command kshana die ausführbare Datei (Spawn-Modi). Sie führt jede ausführbare Datei als Benutzer des Servers aus: Nur ein Administrator des Signal-K-Servers sollte die Plugin-Konfiguration ändern können
sessionFile /etc/kshana/session.toml die Grenzen, Schwellenwerte und Wertgewichte des Schiffes (Spawn-Modi)
inputArgs [] Argumente, die in beiden Spawn-Modi zu kshana receiver-trust live <sessionFile> hinzugefügt werden: die Eingabe für spawn-args, zusätzliche Flags wie --replay (ein gespeichertes Log, schneller als in Echtzeit eingespeist) für spawn-signalk-nmea. Das Plugin lehnt --gate, --listen, --json und --pksht ab (es liest das JSON von kshana auf der Standardausgabe), und für spawn-signalk-nmea auch die Eingabe-Flags (--stdin, --file, --tcp, --udp, --follow, --from-end)
host, port 127.0.0.1, 10111 TCP-Modi (das Gate bedient auf 10110: setzen Sie den Port für tcp-pksht)
thresholdMode band band: das Band, das Kshana meldet, mit den Grenzen in der Sitzungsdatei. score: die beiden Werte unten
warnBelowScore 90 Modus score: darunter ist der Zustand degradedState (die Standardgrenze von Kshana für nominal)
alarmBelowScore 55 Modus score: darunter ist der Zustand alarm (die Standardgrenze von Kshana für degraded)
degradedState warn Zustand für das Band degraded: normal, alert oder warn
raiseAfterEpochs 1 aufeinanderfolgende Epochen bei einem schlechteren Zustand, bevor die Benachrichtigung ausgelöst wird
clearAfterEpochs 10 aufeinanderfolgende Epochen bei einem besseren Zustand, bevor sie zurückgenommen wird
staleAfterS 10 warnt, wenn so lange keine Epoche eintrifft; 0 schaltet es ab
method ["visual","sound"] Benachrichtigungsmethoden

Das Plugin sperrt nicht: Es verändert nie eine Lösung. Eine Lösung für ein Kartensystem als ungültig zu markieren ist das Gate, unten.

Tests#

cd integrations/signalk && npm test

node:test, keine Abhängigkeiten, kein Netzwerk außer 127.0.0.1. Die Tests parsen und spielen einen Auszug von 66 Epochen der JSON-Zeilen und $PKSHT-Sätze ab, die kshana receiver-trust live für die synthetische Ostsee-Demo geschrieben hat (erfundene Daten, nur Text), und prüfen die Übereinstimmung der beiden Formate, das Halte- und Lösch-Verhalten, den Score-Modus, Veraltung und die drei Eingabepfade gegen einen lokalen Feed und einen Stellvertreter-Kindprozess. Diese Tests starten keinen echten Signal-K-Server; ein separater skriptgesteuerter Lauf tut es, siehe unten.

In einem echten Signal-K-Server ausgeführt#

integrations/signalk/evidence/ enthält ein Skript, das das Plugin in das festgelegte Paket signalk-server 2.33.0 lädt (in einem privaten Netzwerk-Namensraum nur mit Loopback) und aufzeichnet, was die eigenen REST- und WebSocket-APIs des Servers zeigen. Die Vertrauenspfade erscheinen, die Benachrichtigung geht auf warn, alarm, normal (nach der Haltezeit) und wieder auf warn, wenn die Daten ausbleiben, und mit dem echten kshana, das über die eigene NMEA-Eingabe des Servers gespeist wurde, veröffentlichte es auch reportedPosition, nie navigation.position. Eine Serverversion, ein Lauf, kein echtes Schiff; Grenzen und Reproduktion im Nachweis-README.

OpenCPN#

OpenCPN liest NMEA aus dem Netzwerk, und kshana receiver-trust live --gate kann den gesperrten Strom selbst auf einem TCP-Port bereitstellen.

Empfohlen: die direkte Verbindung.

some-nmea-source | kshana receiver-trust live session.toml --gate --listen tcp:10110

(some-nmea-source ist der serielle Port des Empfängers, gelesen mit stty und cat, ein Multiplexer oder die Eingaben --tcp/--udp von kshana selbst; das kshana-gate.service des Referenzaufbaus tut dies unter systemd.) --listen tcp:<port> bindet an die Loopback-Adresse; beliebig viele nur lesende Clients können sich verbinden, und einer, der nicht mithalten kann, wird fallen gelassen, ohne die anderen zu verzögern.

Alternative: das Relay. integrations/opencpn/nmea-tcp-relay.mjs ist ein abhängigkeitsfreier Node-Fan-out, der dasselbe für ein kshana ohne --listen leistet oder jeden anderen Zeilenstrom bereitstellt (die Container-Option nutzt es für die JSON-Epochen):

some-nmea-source | kshana receiver-trust live session.toml --gate --json trust.jsonl \
  | node integrations/opencpn/nmea-tcp-relay.mjs --listen 10110

Es leitet Bytes unverändert weiter, nur ganze Zeilen, und lässt einen Client fallen, der nicht liest. Bevorzugen Sie die direkte Verbindung: ein Prozess weniger in der Kette.

In OpenCPN: Options, Connections, Add Connection, Network, Protokoll TCP, Adresse 127.0.0.1, Port 10110, Richtung Input. Solange das Vertrauen nicht eingebrochen ist, ist der Strom der eigene des Empfängers, plus ein Satz $PKSHT je Zyklus. Solange es eingebrochen ist, hat das weitergeleitete GGA die Qualität 0, RMC den Status V, und die Modusanzeigen sagen, dass keine Lösung vorliegt, mit neu berechneten Prüfsummen: Die Ausrüstung sieht, dass der Empfänger selbst die Lösung für ungültig erklärt, und löst ihren eigenen Alarm aus. Die Sätze $PKSHT sind im NMEA-Debug-Fenster von OpenCPN sichtbar (Options, Connections, "NMEA debug window"). Die Positionsfelder bleiben, wie sie empfangen wurden.

Lesen Sie "Gate mode" in MARITIME-TRUST.md, bevor Sie sich darauf verlassen: Es ist ein Opt-in, fügt Latenz hinzu (ein Zyklus wird zurückgehalten, bis seine Epoche bewertet ist), ist ein einzelner Punkt in der Kette und kann eine gute Lösung zurückhalten ebenso wie eine gefälschte durchlassen.

Tests#

cd integrations/opencpn && npm test

test/relay.test.mjs spielt einen aufgezeichneten Auszug des synthetischen gesperrten Stroms ab (186 Sätze um den Moment, in dem das Vertrauen einbricht, geschrieben von kshana receiver-trust live --gate) und leitet ihn über einen echten TCP-Socket durch das Relay und prüft, was ein Verbraucher empfängt: den Strom Byte für Byte bei beliebiger Zerstückelung; gültige Prüfsummen bei jedem Satz, auch bei umgeschriebenen; GGA und RMC stimmen überein, gültig und dann ungültig ohne Flackern; ein $PKSHT je Zyklus, dessen Gate-Feld W genau dort steht, wo die Lösung ungültig ist; zwei Verbraucher identisch; eine unvollständige Zeile wird nie weitergeleitet. Dies prüft den Strom, den OpenCPN erhält, nicht den eigenen Bildschirm von OpenCPN.

Eine Ende-zu-Ende-Prüfung mit der echten Binärdatei, nicht Teil der Standardtests (sie braucht ein gebautes kshana):

KSHANA_BIN=target/release/kshana npm run e2e            # kshana --gate --listen | TCP consumer; the consumer's bytes must equal the gate's stdout
KSHANA_BIN=target/release/kshana npm run e2e -- relay   # kshana --gate | relay | TCP consumer

Beide lassen die einstündige synthetische Demo laufen und prüfen, dass die Lösung gültig und dann ungültig wird, mit einem $PKSHT je Epoche.

Natives Plugin#

integrations/opencpn/plugin/ ist ein Score-Panel für OpenCPN (Wert, Band, Gate, wichtigste Gründe, ein Alarm, wenn das Vertrauen untrusted wird), das $PKSHT aus dem eigenen NMEA-Strom von OpenCPN liest und daher keine Verbindung über die oben genannte hinaus braucht. Es wird mit CMake gegen den Header der OpenCPN-Plugin-API (eingebunden, mit seinem Quell-Commit) und wxWidgets gebaut; ctest führt die wx-freien Logiktests aus und prüft, dass die Bibliothek die Einstiegspunkte exportiert, die OpenCPN nachschlägt. Es wurde innerhalb von OpenCPN 5.8.4 unter einem virtuellen Display auf dem synthetischen gesperrten Strom ausgeführt (OpenCPN reichte $PKSHT an das Plugin, das Panel wurde rot, und die eigene Position von OpenCPN fror ein, als das Gate einrastete; Screenshots, Log und Skript in integrations/opencpn/evidence/), aber nicht auf einem echten Desktop, anderen Versionen oder Plattformen, und es ist nicht für den Plugin-Manager von OpenCPN paketiert. Siehe das README.md des Plugins. Es steht unter GPL-3.0-or-later, anders als der Rest des Repositorys (LICENSING.md).

Screenshots aus diesem Lauf, in integrations/opencpn/evidence/ (ein Lauf, OpenCPN 5.8.4 unter einem virtuellen Display, synthetische Daten; README.md nennt die Grenzen):

Das OpenCPN-Kartenfenster mit dem Kshana-Score-Panel-Plugin auf dem synthetischen gesperrten Strom, vor dem Vertrauenseinbruch: Kein Panel ist geöffnet (es öffnet sich selbst beim Alarm), die Schiffsposition in der Statusleiste lautet 54 32,4659 N 018 46,1670 E mit Geschwindigkeit 16,48 kn und Kurs 088, und die Lösungsanzeige oben rechts zeigt drei Balken. Dasselbe OpenCPN-Fenster nach dem Einbruch: Das Kshana-Panel ist rot geöffnet mit dem Wert 47 und dem Wort UNTRUSTED, den Zeilen gate: fix marked invalid, cn0-spread -30.0, speed-log -21.0 und Alter 2 s sowie der Angabe, dass dies beratende Software ist, keine typzugelassene Navigationsausrüstung, und dass der Betreiber verantwortlich bleibt. Die Statusleiste lautet weiterhin 54 32,4672 N 018 46,2227 E, und die Lösungsanzeige ist auf zwei Balken gefallen. OpenCPN, direkt von kshana receiver-trust live --gate --listen gespeist: Das Kshana-Panel ist rot geöffnet mit dem Wert 44 und UNTRUSTED, den Zeilen gate: fix marked invalid, cn0-spread -30.0, speed-log -18.8 und Alter 1 s sowie der Hinweisaussage. Dieser Lauf stützt die Beobachtung des Positionseinfrierens nicht: OpenCPN arbeitete noch den anfänglichen Schwall von Epochen ab.

Diese zeigen die Verkabelung und die gesperrte Lösung, die OpenCPN erreicht, nicht, dass ein Alarm für ein echtes Schiff rechtzeitig oder richtig ist. Beratende Software, kein typzugelassenes Gerät.

Referenzaufbau#

deploy/reference-build/: eine generische Teileliste, Betriebssystem-Einrichtung, zwei systemd-Units (der beratende Monitor und das Opt-in-Gate), eine Container-Option und die Signal-K-Verdrahtung. deploy/reference-build/check-units.sh führt systemd-analyze verify auf den Units aus, ohne etwas zu starten.

Grenzen#

  • Der Wert ist nur so gut wie die Prüfungen dahinter, die auf die Physik eines Schiffes und seine anderen Sensoren schauen; eine in sich stimmige Fälschung mit passender Uhr wird von reinen NMEA-Monitoren nicht gesehen (MARITIME-TRUST.md). Das Ausbleiben eines Alarms ist kein Beleg für eine gute Lösung.
  • Keine Zahl auf dieser Seite ist eine gemessene Erkennungs- oder Fehlalarmrate. Die obigen Tests prüfen die Verkabelung an synthetischem Text; sie sagen nichts darüber aus, wie sich ein Monitor bei echter Störung schlägt.
  • Nicht typzugelassen; der Betreiber bleibt verantwortlich.