EN

MeshCore KISS Modem Protokoll

MeshCore KISS Modem Protokoll

MeshCore KISS Modem Protokoll

Standard-KISS-TNC-Firmware (Terminal Node Controller) für MeshCore LoRa-Funkgeräte. Kompatibel mit jedem KISS-Client (wie Direwolf, APRSdroid, YAAC usw.) zum Senden und Empfangen von Rohdatenpaketen. MeshCore-spezifische Erweiterungen (Kryptografie, Funkkonfiguration, Telemetrie) sind über den Standard-SetHardware-Befehl (0x06) verfügbar.

Serielle Konfiguration

115200 Baud, 8N1, keine Flusskontrolle (no flow control).

Frame-Format

Standard-KISS-Framing gemäß der KA9Q/K3MC-Spezifikation.

ByteNameDescription
0xC0FENDFrame-Begrenzer
0xDBFESCEscape-Zeichen
0xDCTFENDEscaped FEND (FESC + TFEND = 0xC0)
0xDDTFESCEscaped FESC (FESC + TFESC = 0xDB)
CLI
┌──────┬───────────┬──────────────┬──────┐
│ FEND │ Type Byte │ Data (escaped)│ FEND │
│ 0xC0 │  1 byte   │ 0-510 bytes  │ 0xC0 │
└──────┴───────────┴──────────────┴──────┘

Typ-Byte (Type Byte)

Das Typ-Byte (Type Byte) ist in zwei Nibbles (Halb-Bytes) aufgeteilt:

BitsFeldDescription
7-4PortPortnummer (0 für Single-Port-TNC)
3-0CommandBefehlsnummer

Maximale, nicht-escapte Frame-Größe: 512 Bytes.

Standard-KISS-Befehle

Host an TNC

CommandValueDataDescription
Data0x00Raw packetPaket zum Senden in die Warteschlange stellen (nur eines gleichzeitig ausstehend)
TXDELAY0x01Delay (1 byte)Sende-Keyup-Verzögerung in 10-ms-Einheiten (Standard: 50 = 500ms)
Persistence0x02P (1 byte)CSMA-Persistenzparameter 0-255 (Standard: 63)
SlotTime0x03Interval (1 byte)CSMA-Slot-Intervall in 10-ms-Einheiten (Standard: 10 = 100ms)
TXtail0x04Delay (1 byte)Post-TX-Haltezeit in 10-ms-Einheiten (Standard: 0)
FullDuplex0x05Mode (1 byte)0 = Halbduplex, ungleich Null = Vollduplex (Standard: 0)
SetHardware0x06Sub-command + dataMeshCore-Erweiterungen (siehe unten)
Return0xFF-KISS-Modus verlassen (keine Operation)

TNC an Host

TypeValueDataDescription
Data0x00Raw packetEmpfangenes Paket vom Funkgerät

Datenframes enthalten nur Rohpaketdaten, ohne vorangestellte Metadaten. Die Nutzlast des Datenbefehls (Data command payload) ist auf 255 Bytes begrenzt, um der maximalen Übertragungseinheit (MTU – Maximum Transmission Unit) von MeshCore zu entsprechen; Frames, die größer als 255 Bytes sind, werden stillschweigend verworfen. Die KISS-Spezifikation empfiehlt mindestens 1024 Bytes für allgemeine TNCs; dieses Modem ist jedoch nur für MeshCore-Pakete vorgesehen, deren Protokoll-MTU 255 Bytes beträgt.

Es kann immer nur ein Paket zur Funkübertragung anstehen. Wenn der Host einen zweiten Datenframe sendet, bevor der erste abgeschlossen ist, antwortet das Modem mit Fehler (0xF1) und TxBusy (0x07).

Host-Ausgabe-Gegendruck (Host Output Backpressure)

Ausgehende Frames werden in eine 2-Slot-Warteschlange kodiert und geleert, sobald serieller Ausgabespeicher verfügbar ist; loop() blockiert niemals bei Schreibvorgängen. Der TX-Status des Funkgeräts schreitet unabhängig von der Host-Lesegeschwindigkeit voran. TxDone wird beibehalten, bis es in die Warteschlange gestellt werden kann. Ist die ausgehende Warteschlange voll, antwortet das Modem mit Fehler (0xF1) und TxBusy (0x07). Hosts sollten die serielle Schnittstelle zeitnah auslesen, um verzögerte Antworten zu vermeiden.

CSMA-Verhalten

Das TNC implementiert p-persistent CSMA (Carrier Sense Multiple Access) für den Halbduplex-Betrieb:

  1. Wenn ein Paket in die Warteschlange gestellt wird, wird die Trägererkennung (carrier detect) überwacht.
  2. Wenn der Kanal frei wird, wird ein Zufallswert von 0-255 generiert.
  3. Wenn der Wert kleiner oder gleich P (Persistenz) ist, wird nach einer Wartezeit von TXDELAY gesendet.
  4. Andernfalls wird SlotTime gewartet und der Vorgang ab Schritt 1 wiederholt.
Im Vollduplex-Modus wird CSMA umgangen und Pakete werden nach TXDELAY gesendet.

SetHardware-Erweiterungen (0x06)

MeshCore-spezifische Funktionen verwenden den Standard-KISS-SetHardware-Befehl. Das erste Byte der SetHardware-Daten ist ein Unterbefehl (Sub-command). Standard-KISS-Clients ignorieren diese Frames.

Frame-Format

CLI
┌──────┬──────┬─────────────┬──────────────┬──────┐
│ FEND │ 0x06 │ Sub-command  │ Data (escaped)│ FEND │
│ 0xC0 │      │   1 byte    │   variable   │ 0xC0 │
└──────┴──────┴─────────────┴──────────────┴──────┘

Anforderungs-Unterbefehle (Host an TNC)

Sub-commandValueData
GetIdentity0x01-
GetRandom0x02Length (1 byte, 1-64)
VerifySignature0x03PubKey (32) + Signature (64) + Data
SignData0x04Data to sign
EncryptData0x05Key (32) + Plaintext
DecryptData0x06Key (32) + MAC (2) + Ciphertext
KeyExchange0x07Remote PubKey (32)
Hash0x08Data to hash
SetRadio0x09Freq (4) + BW (4) + SF (1) + CR (1)
SetTxPower0x0APower dBm (1)
GetRadio0x0B-
GetTxPower0x0C-
GetCurrentRssi0x0D-
IsChannelBusy0x0E-
GetAirtime0x0FPacket length (1)
GetNoiseFloor0x10-
GetVersion0x11-
GetStats0x12-
GetBattery0x13-
GetMCUTemp0x14-
GetSensors0x15Permissions (1)
GetDeviceName0x16-
Ping0x17-
Reboot0x18-
SetSignalReport0x19Enable (1): 0x00=disable, nonzero=enable
GetSignalReport0x1A-

Antwort-Unterbefehle (TNC an Host)

Antwortcodes verwenden die High-Bit-Konvention (das höchstwertige Bit ist gesetzt): response = command | 0x80. Allgemeine und unaufgeforderte Antworten verwenden den Bereich 0xF0+.

Sub-commandValueData
Identity0x81PubKey (32)
Random0x82Random bytes (1-64)
Verify0x83Result (1): 0x00=invalid, 0x01=valid
Signature0x84Signature (64)
Encrypted0x85MAC (2) + Ciphertext
Decrypted0x86Plaintext
SharedSecret0x87Shared secret (32)
Hash0x88SHA-256 hash (32)
Radio0x8BFreq (4) + BW (4) + SF (1) + CR (1)
TxPower0x8CPower dBm (1)
CurrentRssi0x8DRSSI dBm (1, signed)
ChannelBusy0x8EResult (1): 0x00=clear, 0x01=busy
Airtime0x8FMilliseconds (4)
NoiseFloor0x90dBm (2, signed)
Version0x91Version (1) + Reserved (1)
Stats0x92RX (4) + TX (4) + Errors (4)
Battery0x93Millivolts (2)
MCUTemp0x94Temperature (2, signed)
Sensors0x95CayenneLPP payload
DeviceName0x96Name (variable, UTF-8)
Pong0x97-
SignalReport0x9AStatus (1): 0x00=disabled, 0x01=enabled
OK0xF0-
Error0xF1Error code (1)
TxDone0xF8Result (1): 0x00=failed, 0x01=success
RxMeta0xF9SNR (1) + RSSI (1)

Fehlercodes

CodeValueDescription
InvalidLength0x01Anforderungsdaten zu kurz
InvalidParam0x02Ungültiger Parameterwert
NoCallback0x03Funktion nicht verfügbar
MacFailed0x04MAC-Verifizierung fehlgeschlagen
UnknownCmd0x05Unbekannter Unterbefehl
EncryptFailed0x06Verschlüsselung fehlgeschlagen
TxBusy0x07Funk-TX belegt, oder Host-Ausgangswarteschlange voll

Unaufgeforderte Ereignisse (Unsolicited Events)

Das TNC sendet diese SetHardware-Frames ohne vorherige Anfrage:

TxDone (0xF8): Wird gesendet, nachdem die Funkübertragung abgeschlossen ist. Enthält ein einzelnes Byte: 0x01 für Erfolg, 0x00 für Fehler. Die Übermittlung an den Host kann unter seriellem Gegendruck verzögert werden, wird aber nicht verworfen. RxMeta (0xF9): Wird nach jedem Standard-Datenframe (Typ 0x00) mit SNR (1 Byte, signed, Wert x4) und RSSI (1 Byte, signed, dBm) gesendet. Wird zusammen mit dem Datenframe in die Warteschlange gestellt; wird weggelassen, wenn der Datenframe nicht in die Warteschlange gestellt werden kann. Standardmäßig aktiviert; kann mit SetSignalReport umgeschaltet werden. Standard-KISS-Clients ignorieren diesen Frame.

Datenformate

Funkparameter (SetRadio / Radio response)

Alle Werte sind Little-Endian.

FeldSizeDescription
Frequency4 bytesHz (z.B. 869618000)
Bandwidth4 bytesHz (z.B. 62500)
SF1 byteSpreading Factor (5-12)
CR1 byteCoding Rate (5-8)

Version (Version response)

FeldSizeDescription
Version1 byteFirmware-Version
Reserved1 byteImmer 0

Verschlüsselt (Encrypted response)

FeldSizeDescription
MAC2 bytesHMAC-SHA256 auf 2 Bytes gekürzt
CiphertextvariableAES-128 Block-verschlüsselte Daten mit Null-Padding

Sendezeit (Airtime response)

Alle Werte sind Little-Endian.

FeldSizeDescription
Airtime4 bytesuint32_t, geschätzte Sendezeit in Millisekunden

Grundrauschen (NoiseFloor response)

Alle Werte sind Little-Endian.

FeldSizeDescription
Noise floor2 bytesint16_t, dBm (signed)

Das Modem kalibriert das Grundrauschen alle 2 Sekunden neu, mit einem AGC-Reset (Automatic Gain Control) alle 30 Sekunden.

Statistiken (Stats response)

Alle Werte sind Little-Endian.

FeldSizeDescription
RX4 bytesEmpfangene Pakete
TX4 bytesGesendete Pakete
Errors4 bytesEmpfangsfehler

Batterie (Battery response)

Alle Werte sind Little-Endian.

FeldSizeDescription
Millivolts2 bytesuint16_t, Batteriespannung in mV

MCU-Temperatur (MCUTemp response)

Alle Werte sind Little-Endian.

FeldSizeDescription
Temperature2 bytesint16_t, Zehntel °C (z.B. 253 = 25.3°C)

Gibt den NoCallback-Fehler zurück, wenn das Board keine Temperaturmessungen unterstützt.

Gerätename (DeviceName response)

FeldSizeDescription
NamevariableUTF-8-String, kein Null-Terminator

Neustart (Reboot)

Sendet eine OK-Antwort, leert die serielle Schnittstelle und startet dann das Gerät neu. Der Host sollte erwarten, dass die Verbindung getrennt wird.

Sensor-Berechtigungen (GetSensors)

BitValueDescription
00x01Basis (Batterie)
10x02Standort (GPS)
20x04Umgebung (Temperatur, Luftfeuchtigkeit, Druck)

Verwenden Sie 0x07 für alle Berechtigungen.

Sensordaten (Sensors response)

Die Daten werden im CayenneLPP-Format zurückgegeben. Informationen zur Analyse finden Sie in der CayenneLPP-Dokumentation.

Kryptografische Algorithmen

OperationAlgorithm
Identität / Signieren / VerifizierenEd25519
SchlüsselaustauschX25519 (ECDH – Elliptic Curve Diffie-Hellman)
VerschlüsselungAES-128 Blockverschlüsselung mit Null-Padding + HMAC-SHA256 (MAC auf 2 Bytes gekürzt)
HashingSHA-256

Hinweise

  • Die maximale Nutzlastgröße (255 Bytes) entspricht der MeshCore MAX_TRANS_UNIT (Maximum Transmission Unit); es sind keine Änderungen für die KISS-Empfehlung "1024+ empfohlen" erforderlich (dies gilt für allgemeine TNCs, nicht für MeshCore).
  • Das Modem generiert die Identität beim ersten Start (wird im Flash-Speicher gespeichert).
  • Alle Mehrbyte-Werte sind Little-Endian, sofern nicht anders angegeben.
  • SNR-Werte (Signal-Rausch-Verhältnis) in RxMeta werden mit 4 multipliziert, um eine Präzision von 0,25 dB zu erreichen.
  • TxDone wird nach jeder Übertragung als SetHardware-Ereignis gesendet.
  • Standard-KISS-Clients empfangen nur Datenframes vom Typ 0x00 und können alle SetHardware-Frames (0x06) bedenkenlos ignorieren.
  • Siehe packet_format.md für das Paketformat.

Quelle: docs.meshcore.io