Direktnachrichten in MeshCore: Warum sie nicht ankommen und wie man es löst
Kanäle laufen, aber die Direktnachricht bleibt auf Failed: Fast immer fehlt der Kontakt auf einer Seite, der Advert oder der Scope. So läuft eine DM technisch, und so bringst du sie zum Laufen.
Das Problem: Kanal geht, DM nicht
Das Muster ist in der Support-Gruppe seit Monaten das gleiche: Im Kanal liest man mit und schreibt mit, aber die Direktnachricht an einen bestimmten Kontakt geht als Failed raus oder verschwindet ohne Rückmeldung. Die Ursache ist fast nie die Funkstrecke. Sie liegt in dem, was eine DM von einer Kanalnachricht unterscheidet.
Wie eine DM technisch läuft
Kontakt und Advert
Eine Kanalnachricht ist mit dem Kanalschlüssel verschlüsselt, den alle Teilnehmer kennen. Eine DM ist dagegen an den Public Key des Empfängers gebunden. Dein Companion kann sie nur verschlüsseln, wenn er den Key des Gegenübers hat, und das Gegenüber kann nur antworten, wenn es deinen Key hat. Beide Seiten müssen sich also gegenseitig in der Kontaktliste stehen haben.
Den Key verteilt der Advert. Ein Companion sendet ihn nicht automatisch, sondern nur, wenn du ihn in der App auslöst. Wer nie einen Advert gesendet hat, taucht bei niemandem als Kontakt auf. Ob ein empfangener Advert automatisch als Kontakt übernommen wird, steuert die Option Auto-Add in der App. Ist sie aus, musst du Kontakte von Hand übernehmen.
Pfad statt Flood
Kanalnachrichten werden immer per Flood verteilt: Jeder Repeater in Reichweite wiederholt sie, bis das Hop-Limit erreicht ist. DMs arbeiten anders. Ist zum Kontakt ein Pfad bekannt, geht die Nachricht gerichtet über genau die Repeater in diesem Pfad. Das spart Airtime, weil nicht das ganze Netz wiederholt. Ist kein Pfad bekannt, startet der Companion eine Path Discovery, die als Flood läuft. Den Pfad sieht nur der Empfänger, nicht der Sender.
Das hat zwei Konsequenzen. Erstens ist ein gelernter Pfad nur so gut wie die Repeater darin. Fällt einer aus oder zieht ein mobiler Repeater weiter, läuft die DM ins Leere. Zweitens hängt die Path Discovery an denselben Regeln wie jeder andere Flood, und da kommen die Regionen ins Spiel.
Default Scope seit 1.15
Viele Repeater in Norddeutschland leiten ungescopte Floods nicht mehr oder nur begrenzt weiter. Auf Stock-Firmware unter 1.15 hat denyf * dabei nicht nur Kanal-Floods gesperrt, sondern auch DMs ohne Pfad, Traces und Adverts. Seit 1.15 gibt es deshalb den Default Scope im Companion. Er gibt allen ungescopten Floods deines Geräts eine Region mit, auch der Path Discovery und dem Advert.
Wichtig: Der Scope wirkt nur beim Senden, nie beim Empfangen. Damit die DM in beide Richtungen funktioniert, muss der Default Scope bei Sender und Empfänger gesetzt sein. Welche Region für dich passt, steht in Regionen und Scopes.
set radio.default_region de-hh
Kanalnachricht und DM im Vergleich
| Kanalnachricht | Direktnachricht | |
|---|---|---|
| Verschlüsselung | Kanalschlüssel | Public Key des Empfängers |
| Voraussetzung | Kanal auf beiden Seiten | Kontakt auf beiden Seiten |
| Routing | Immer Flood | Pfad, wenn bekannt, sonst Flood |
| Scope | Pro Kanal gesetzt | Default Scope des Companions |
| Bestätigung | Keine | ACK vom Empfänger |
| Airtime | Jeder Repeater wiederholt | Nur Repeater im Pfad |
Aus der Tabelle folgt auch: Ein privater Kanal flutet genauso wie Public. Für Gespräche zu zweit ist die DM die netzschonendere Wahl.
Die typischen Ursachen
| Symptom | Ursache | Lösung |
|---|---|---|
| DM sofort Failed | Gegenüber hat deinen Key nicht | Advert senden, gegenseitig speichern |
| Kontakt fehlt in der Liste | Advert vom Gegenüber nie angekommen | Gegenüber Advert senden lassen, Auto-Add prüfen |
| Kanal geht, DM nicht | Repeater sperrt ungescopte Floods | Default Scope setzen, auf beiden Seiten |
| DM ging früher, jetzt nicht mehr | Pfad veraltet | Pfad zurücksetzen, neue Discovery |
| Neue Kontakte werden nicht gespeichert | Kontaktlimit des Companions erreicht | Alte Kontakte löschen |
| Alles weg nach Update | Companion verliert Kontakte beim Neuflash | Backup vor dem Update, Import aus JSON |
Kontakt fehlt auf einer Seite. Der häufigste Fall. Du siehst das Gegenüber, aber das Gegenüber sieht dich nicht. Empfangen ist einfacher als Senden, und ein Advert, der bei dir ankommt, sagt nichts darüber, ob deiner beim anderen ankam.
Advert nie gesendet. Wer den Companion frisch eingerichtet hat und nur mitliest, ist für das Netz unsichtbar.
Scope nicht gesetzt. Seit 1.15 der zweithäufigste Fall. Ohne Default Scope läuft die Path Discovery ungescopt und bleibt am ersten Repeater mit denyf * hängen. Repeater ab 1.16 begrenzen ungescopte Floods mit flood.max.unscoped 3–5 statt sie komplett zu sperren, aber darauf kannst du dich nicht verlassen.
Pfad veraltet. Mobile Repeater und abgeschaltete Nodes zerstören gelernte Pfade. Auch Firmware-Mischbetrieb stört: Seit 1.14 sind Pfade mehrere Byte lang, Repeater unter 1.14 verwerfen sie.
Kontaktlimit des Companions. Die Kontaktliste ist je nach Hardware auf etwa 160 bis 350 Einträge begrenzt. T114 und Xiao liegen bei rund 160. Der T-Beam hat nur 110 kB Speicher und fällt nach Stromverlust auf 25 Kontakte zurück. In dichten Netzen wie Hamburg füllt Auto-Add die Liste in Tagen.
Repeater mit denyf. Ein einzelner Repeater im Pfad, der die Region nicht kennt, reicht. Regionen sind reine Hashes ohne Hierarchie. de ist nicht Parent von de-hh, jeder Repeater auf der Strecke muss die Region exakt so eingetragen haben.
Schritt für Schritt
- Beide Geräte auf 1.15 oder neuer. Ältere Firmware kennt den Default Scope nicht. Vor dem Update Kontakte sichern, Companions verlieren sie beim Neuflash.
- Default Scope auf beiden Companions setzen. Die kleinste sinnvolle Region, in Hamburg
de-hhoderhansemesh, nichtdeoderde-nord. Welche Regionen die Repeater um dich kennen, zeigt Discover Regions in der App oder die Regionen-Liste im Wiki. - Advert senden, auf beiden Seiten. Danach prüfen, ob das Gegenüber in der eigenen Kontaktliste steht und umgekehrt.
- Kontaktliste aufräumen. Ist sie voll, nimmt der Companion keinen neuen Kontakt an. Einträge löschen, die du nie anschreibst.
- Pfad zurücksetzen. Wenn eine DM früher lief und jetzt hängt, den gespeicherten Pfad zum Kontakt löschen und die Discovery neu laufen lassen.
- Uhrzeit prüfen. Companions ohne GPS oder ohne WLAN-Zeitabgleich können mit falscher Uhr Adverts verwerfen. Vor allem WLAN-Companions brauchen eine korrekte Zeiteinstellung.
- Kurz schreiben. Mit Scope blieben Nachrichten über 127 Zeichen in der Firmware hängen. Mit Umlauten passen ohnehin nur etwa 113 bis 121 Zeichen in ein Paket.
Läuft es danach immer noch nicht, hilft der Trace Path in der App. Er zeigt, welche Repeater die Strecke bilden. Fehlt einer davon in beiden Richtungen, ist der Link asymmetrisch: Du hörst den Repeater, aber er hört dich nicht. Dann liegt es an Antenne, Standort oder Störungen am Repeater, nicht an der DM-Konfiguration.
Bestätigungen: ACK ist keine Lesebestätigung
Nur DMs bekommen eine Bestätigung. Der Empfänger-Companion schickt ein ACK zurück, sobald das Paket bei ihm angekommen ist. Kanalnachrichten bekommen nichts, dort weißt du nie, ob jemand mitgelesen hat.
Das ACK sagt aber nur, dass der Companion die Nachricht hat, nicht, dass der Mensch sie gelesen hat.
Bleibt das ACK aus, obwohl die Nachricht ankam, ist meist der Rückweg das Problem: Der Empfänger hat keinen Default Scope gesetzt, oder der Rückpfad läuft über einen Repeater, der besser hört als sendet. Auf dem Repeater hilft set multi.acks 1, auf dem Companion ein ACK-Timeout von 2 Sekunden. Beides gleicht Paketverluste im Rückkanal aus, aber nicht einen fehlenden Scope.
Was das für Repeater-Betreiber heißt
Wer einen Repeater betreibt, entscheidet mit, ob DMs in seiner Umgebung funktionieren. Stock-Firmware unter 1.15 mit denyf * sperrt DMs ohne Pfad komplett. Ab 1.16 ist flood.max.unscoped 3–5 die bessere Wahl, denn 0 bricht auch Remote-Admin. Und die Regionen sollten mit den Nachbar-Repeatern abgestimmt sein. Ein Repeater, der de-hh nicht kennt, ist für jede DM in Hamburg ein Loch im Pfad.
Fragen?
Wenn die DM trotz allem hängt, hilft die Community in der Telegram-Gruppe: t.me/meshcorede. Am besten mit Firmware-Version beider Geräte, gesetztem Default Scope und einem Screenshot vom Trace Path. Welche Hardware welches Kontaktlimit hat, steht in der Geräteübersicht.