Eine vollständige Ursachenanalyse

MeshDresden · Kategorie: Technik · Zielgruppe: Repeater-Betreiber und fortgeschrittene Nutzer



MeshCore gilt als robust – und ist es auch. Trotzdem gibt es Situationen, in denen Nachrichten lautlos verschwinden: keine Fehlermeldung, keine Bestätigung, kein Hinweis. Wer das zum ersten Mal erlebt, sucht zuerst am falschen Ort.

Dieser Bericht systematisiert alle bekannten Ursachen für Nachrichtenausfälle in MeshCore – vom physikalischen Layer bis zur Firmware-Konfiguration. Viele davon betreffen direkt den path.hash.mode und die damit zusammenhängenden Firmware-Versionen. Andere haben damit gar nichts zu tun, sind aber genauso tückisch.


Überblick: Die Ursachen auf einen Blick

Nachrichtenausfälle in MeshCore lassen sich in fünf Kategorien einteilen:

  1. Firmware-Inkompatibilität – falscher path.hash.mode trifft alten Repeater
  2. Uhren- und Timestamp-Probleme – Replay-Protection greift zu Unrecht
  3. LoRa-Physik und Funkstrecke – Signal kommt schlicht nicht an
  4. Duty-Cycle und Airtime – der Repeater schweigt aus gesetzlichen Gründen
  5. Routing- und Konfigurationsfehler – falsche Pfade, flood.max, Regionfilter

1. Firmware-Inkompatibilität durch path.hash.mode

Das Problem

Seit Firmware-Version 1.14 unterstützt MeshCore drei Hash-Größen für den Path-Eintrag im Paket: 1, 2 oder 3 Bytes pro Repeater-Hop. Der Modus wird mit set path.hash.mode <0|1|2> am Repeater gesetzt und bestimmt auch, welchen Modus der Repeater beim Weiterleiten seiner eigenen Adverts verwendet.

Das kritische Problem: Repeater mit Firmware ≤ 1.13 droppen alle Pakete mit 2- oder 3-Byte-Path-Hash kommentarlos. Es gibt keine Fehlermeldung. Die Nachricht verschwindet im Netz, ohne dass Sender oder Empfänger etwas merken.

Die drei Modi im Vergleich
ModusBytes/HopMax. Hops (Flood)Eindeutige IDsFirmware-Anforderung
01 Byte63254alle
12 Bytes3165.536≥ 1.14
23 Bytes2116.777.216≥ 1.14

Der Path ist im Paket auf 64 Bytes begrenzt. Daraus ergibt sich die maximale Hop-Anzahl je Modus: max_hops = 64 / hash_size.

Paketstruktur im Überblick

Das path_len-Byte kodiert Hash-Größe und Hop-Anzahl gemeinsam:

path_len = ((hash_size - 1) << 6) | (hop_count & 63)

Firmware ≤ 1.12 verstand diese Kodierung nicht und droppte Pakete mit mehr als 64 Path-Bytes. Ab 1.14 wird das Feld korrekt interpretiert.

Firmware-Kompatibilitätsmatrix
Wann ist mode 1 oder 2 sicher?
  • Für Adverts des Repeaters: Sofort nach Update auf ≥ 1.14 sinnvoll. Analyse-Tools wie LetsMesh.net können Repeater mit 2- oder 3-Byte-Hashes zuverlässiger unterscheiden. Pre-1.14-Repeater droppen diese Adverts, was aber die Netzfunktion nicht beeinträchtigt.
  • Für Channel- und Direktnachrichten: Erst dann umstellen, wenn die große Mehrheit der aktiven Repeater im regionalen Netz auf ≥ 1.14 aktualisiert ist. Der Sender legt den Modus fest, nicht der Repeater.
  • Companion App: Mode 1 und 2 sind erst ab App-Version 1.41.0 in den experimentellen Einstellungen verfügbar (Einstellungen → Experimentelle Einstellungen).
Auswirkung auf Nachrichtenlänge

Der nutzbare Textplatz reduziert sich mit steigendem Modus und steigender Hop-Anzahl, bleibt aber in der Praxis unkritisch:

HopsText-Bytes mode 0Text-Bytes mode 1Text-Bytes mode 2
3172 B168 B162 B
5170 B166 B160 B
10165 B155 B139 B
21154 B121 B84 B
31144 B83 B

(Direktnachricht, 9 Byte Overhead für dest_hash + src_hash + MAC + Timestamp + type)

Fazit: Die Nachrichtenlänge ist in der Praxis kein limitierender Faktor. Das entscheidende Problem ist die Firmware-Kompatibilität – nicht die Payload-Größe.


2. Uhren- und Timestamp-Probleme

Dies ist eine der häufigsten und am schwierigsten zu diagnostizierenden Ursachen für Nachrichtenausfälle in autonomen Repeater-Setups.

Wie Timestamps in MeshCore funktionieren

Jede MeshCore-Nachricht enthält einen 32-Bit-Unix-Timestamp (Sekunden seit 1.1.1970). Dieser Timestamp dient zwei Zwecken:

  1. Replay-Protection: Der Empfänger akzeptiert eine Nachricht nur, wenn ihr Timestamp größer ist als der zuletzt gesehene Timestamp desselben Senders. Nachrichten mit altem Timestamp werden als möglicher Replay-Angriff gewertet und lautlos verworfen.
  2. Advert-Gültigkeit: Adverts werden ebenfalls anhand ihres Timestamps validiert. Ein Advert mit einem Timestamp in der Vergangenheit wird vom Empfänger ignoriert.
Das Clock-Problem bei autonomem Betrieb
Die vier Fehlerszenarien

Szenario 1 – Neustart ohne Zeitquelle:
Ein Repeater ohne RTC und ohne aktive GPS- oder NTP-Synchronisierung greift nach einem Neustart auf den zuletzt im persistenten Speicher gesicherten Timestamp zurück – sofern ein solcher vorhanden ist. Hatte der Repeater zuvor eine funktionierende Zeitquelle (z.B. eine Remote-Management-Verbindung oder GPS), überlebt dieser Wert den Neustart im Flash und wird als Startzeit verwendet. Fehlt jeder gespeicherte Wert, fällt die Firmware auf einen eingebetteten Fallback zurück – je nach Build das Compile-Datum oder ein hardcodierter Standardwert. In beiden Fällen kann die resultierende Uhrzeit erheblich von der tatsächlichen Zeit abweichen, was dazu führt, dass Adverts und Nachrichten von anderen Knoten als veraltet verworfen werden.

Szenario 2 – Clock drift in die Zukunft:
Wenn ein Repeater-Clock versehentlich in die Zukunft springt, kann die Uhr anschließend nicht mehr rückwärts korrigiert werden – die Firmware akzeptiert keine Clock-Synchronisierung, die die Uhr rückwärts stellt. Einziger Ausweg: vollständiger Stromabbruch inklusive Batterie und Solar.

Szenario 3 – Companion-App synchronisiert falsche Zeit:
Die iOS-App hatte zeitweise einen Bug, bei dem sie die Zeit des Companion-Radios statt der Telefonuhr für die Clock-Synchronisierung eines Repeaters verwendete. War das Companion-Radio nicht korrekt gestellt, bekam der Repeater eine falsche Zeit.

Szenario 4 – Autonomer Repeater ohne Clock-Sync:
Ein Repeater ohne GPS und ohne regelmäßige Remote-Management-Verbindung driftet über Monate. Die Replay-Protection greift zunehmend fehlerhaft, der Repeater wird effektiv aus dem Netz ausgeschlossen – ohne jede Fehlermeldung.

Gegenmassnahmen
MaßnahmeAufwandWirkung
RTC-Modul (z.B. DS3231)mittelpermanente Zeithaltung über Neustarts
GPS-Modul + gps sync CLImittelsehr genaue Zeit, automatisch
Regelmäßige Remote-Management-VerbindunggeringClock-Sync via Smartphone
Cron-Job mit meshcore-cli / Pythonmittelprogrammatische Synchronisierung

Für den Funkturm Wilsdruff: Der Repeater läuft solar-powered autonom. Ohne RTC-Modul oder GPS ist ein Clock-Reset nach Stromausfall wahrscheinlich. Empfehlung: RTC-Modul nachrüsten oder in meshcore-bot-web eine regelmäßige Clock-Synchronisierung per Python-meshcore-Paket implementieren.


3. LoRa-Physik und Funkstrecke

Nicht jeder Nachrichtenausfall hat eine Software-Ursache. Die Physik des LoRa-Übertragungswegs ist mindestens genauso wichtig.

SNR und Empfangsqualität
SNRBewertungZuverlässigkeit
> +5 dBgutsehr hoch
−5 bis +5 dBmoderatschwankend
< −5 dBschlechtPaketverluste wahrscheinlich
Weitere physikalische Ursachen

Kollisionen durch simultane Übertragungen: LoRa-Pakete belegen die Frequenz für die gesamte Time-on-Air – bei SF12 und 125 kHz Bandbreite können das mehrere Sekunden sein. MeshCore begegnet dem durch randomisierte Weiterleitungsverzögerungen (txdelay), aber in dichten Netzen bleibt Kollision ein relevanter Faktor.

Channel Activity Detection (CAD): Bevor ein Repeater sendet, prüft er ob der Kanal frei ist. Ist er für mehr als 4 Sekunden belegt, verwirft der Repeater das Paket mit einem Timeout-Fehler.

Frequenz- und Parametermismatch: Sender und Empfänger müssen auf exakt denselben Parametern funken (Frequenz, BW, SF, CR). Ein einziges abweichendes Bit führt zu totalem Ausfall ohne jede Rückmeldung.

Verschlüsselungsmismatch: Wenn der empfangende Knoten den falschen Channel-Schlüssel hat, kann er die Nachricht nicht entschlüsseln – sie wird lautlos verworfen.


4. Duty-Cycle, Airtime-Limiter und EU-Regulierung

Das gesetzliche Rahmenproblem

Im EU-Frequenzband 869,525 MHz gilt ein gesetzlicher Duty-Cycle von maximal 10%. Das bedeutet: Pro Stunde darf ein Sender maximal 360 Sekunden senden.

EinstellungEffective Duty-CycleEU-konform
af = 1 (Default)~50%NEIN
af = 2~33%nein
af = 9~10%ja
set dutycycle 1010%ja

Wichtig: Der Standardwert af = 1 ist in Deutschland nicht gesetzeskonform. Repeater-Betreiber sind dafür verantwortlich, den korrekten Wert zu setzen.

Wie der Limiter Nachrichten verwirft

Wenn ein Repeater seinen Duty-Cycle ausgeschöpft hat, schweigt er. Er empfängt Pakete, leitet sie aber nicht weiter. Aus Sicht des sendenden Clients sieht es aus wie ein Funkausfall oder ein toter Repeater.

Der neue dutycycle-Befehl (ab Firmware 1.15.0)
set dutycycle 10    # EU-konform, 10% Limit
set dutycycle 50    # alter Default (nicht EU-konform)
set dutycycle 100   # kein Limit (nur für Tests!)

5. Routing- und Konfigurationsfehler

Veralteter direkter Pfad (stale path)

MeshCore lernt beim ersten erfolgreichen Flood-Durchlauf den direkten Pfad zu einem Knoten und speichert ihn. Fällt ein Repeater im gespeicherten Pfad aus, schlägt die Nachricht dreimal fehl, bevor der Client den Pfad zurücksetzt und erneut flutet. In dieser Übergangszeit kommen Nachrichten nicht an.

flood.max zu niedrig
set flood.max 64    # Default, empfohlen
set flood.max 10    # würde Pakete nach 10 Hops still verwerfen
Loop-Detection mit Hash-Kollision
Stufe1-Byte-Hash2-Byte-Hash
minimal≥ 4× eigene ID verwirft≥ 2× eigene ID verwirft
moderate≥ 2× eigene ID verwirft≥ 1× eigene ID verwirft
strict≥ 1× eigene ID verwirft≥ 1× eigene ID verwirft

Bei strict mit 1-Byte-Hashes und Kollisionen kann ein Repeater legitime Pakete verwerfen, weil er glaubt, sie bereits gesehen zu haben. Das ist ein direktes Zusammenspiel von Loop-Detection und dem Kollisionsproblem bei mode 0.

Regionfilter und Kanalschlüssel

Ein falsch konfigurierter Regionfilter (REGION_DENY_FLOOD, REGION_DENY_DIRECT) oder ein falscher Channel-Schlüssel führen ebenfalls zu stillen Drops ohne Fehlermeldung.


Diagnose: Systematisches Vorgehen

Schritt 1 – Firmware-Version prüfen
get fw.version

Ziel: alle Repeater im Netz auf ≥ 1.14. Veraltete Firmware ist die häufigste Ursache für stille Drops bei mode 1/2.

Schritt 2 – Clock-Status prüfen
get time

Das Ergebnis sollte einem plausiblen Unix-Timestamp entsprechen (≥ 1.700.000.000 für das Jahr 2023+). Ist der Wert deutlich niedriger, läuft die Uhr falsch.

Schritt 3 – Airtime und Duty-Cycle prüfen
get dutycycle    # ab v1.15.0
get af           # vor v1.15.0
get stats        # TX/RX-Counts, Airtime, Uptime
Schritt 4 – Nachbarn und SNR analysieren
get neighbors

Zeigt die zuletzt gesehenen Nachbarknoten mit Timestamp und SNR (Wert × 4). Ein Repeater ohne Nachbarn hat entweder ein HF-Problem oder ist ausgefallen.

Schritt 5 – Hash-Mode im Netz erfassen

Über LetsMesh.net lässt sich ablesen, welche Repeater 1-, 2- oder 3-Byte-Adverts senden – ohne jeden Repeater einzeln abzufragen.


Zusammenfassung: Ursachen und Gegenmassnahmen

UrsacheSymptomLösung
path.hash.mode 1/2 + pre-1.14-Repeaterstilles DropFirmware-Update oder mode 0 behalten
Falsche Repeater-UhrReplay-Drop, Advert-IgnoreRTC, GPS oder regelmäßige Clock-Sync
Clock in der ZukunftSync nicht möglichVollständiger Stromabbruch
Niedriger SNRPaketverlusteAntennenoptimierung, Repeater-Positionierung
Kollisionen / CAD-Timeoutsporadische Ausfälletxdelay erhöhen, Kanalauslastung reduzieren
Duty-Cycle erschöpftRepeater schweigtset dutycycle 10 (EU-konform)
Stale Path nach Repeater-Ausfall3× Fehlschlag, dann Floodnormales Verhalten, kein Handlungsbedarf
flood.max zu niedrigentfernte Knoten nicht erreichbarDefault 64 verwenden
Loop-Detection + Hash-KollisionPakete werden verworfenmode 1 (mehr eindeutige IDs)
Falscher Channel-Schlüsselstilles DropKanalschlüssel auf allen Geräten prüfen
RegionfilterPakete werden geblocktRegion-Konfiguration prüfen

Quellen: MeshCore Dokumentation · MeshCore GitHub FAQ · MeshCore CLI Reference · EastMesh Wiki · MeshCore Switzerland Settings · GitHub Issues #1329, #1332, #1882, #2047

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert