Companion-Protokoll
- Letzte Aktualisierung: 2026-03-08
- Protokollversion: Companion-Firmware v1.12.0+
HINWEIS: Dieses Dokument befindet sich noch in Entwicklung. Einige Informationen können ungenau sein.
Dieses Dokument bietet eine umfassende Anleitung zur Kommunikation mit MeshCore-Geräten über Bluetooth Low Energy (BLE, energiesparende Bluetooth-Variante).
Es ist plattformunabhängig und kann für Android, iOS, Python, JavaScript oder jede andere Plattform verwendet werden, die BLE unterstützt.
Offizielle Bibliotheken
Für bereits existierende Companion-Protokoll-Bibliotheken siehe folgende Repositories:
- JavaScript: https://github.com/meshcore-dev/meshcore.js
- Python: https://github.com/meshcore-dev/meshcore_py
Wichtiger Sicherheitshinweis
Sämtliche Geheimnisse, Hashes und kryptographische Werte in diesem Dokument sind ausschließlich Beispielwerte.
- Alle Hex-Werte, öffentlichen Schlüssel und Hashes dienen nur zur Veranschaulichung
- Verwende niemals Beispiel-Geheimnisse in Produktivsystemen
- Erzeuge stets neue, kryptographisch sichere Zufallswerte
- Setze in deiner Implementierung immer ordnungsgemäße Sicherheitspraktiken um
- Dieses Dokument dient ausschließlich der Protokolldokumentation
Inhaltsverzeichnis
- BLE-Verbindung
- Paketstruktur
- Befehle
- Kanalverwaltung
- Nachrichtenverarbeitung
- Antwort-Parsing
- Beispielhafte Implementierung
- Best Practices
- Fehlerbehebung
BLE-Verbindung
Service und Characteristics
MeshCore Companion-Geräte stellen einen BLE-Service mit folgenden UUIDs bereit:
- Service-UUID:
6E400001-B5A3-F393-E0A9-E50E24DCCA9E - RX Characteristic (App → Firmware):
6E400002-B5A3-F393-E0A9-E50E24DCCA9E - TX Characteristic (Firmware → App):
6E400003-B5A3-F393-E0A9-E50E24DCCA9E
Verbindungsschritte
- Nach Geräten suchen
- GATT-Verbindung herstellen
- Services und Characteristics ermitteln
6E400001-B5A3-F393-E0A9-E50E24DCCA9E suchen
- Die RX Characteristic 6E400002-B5A3-F393-E0A9-E50E24DCCA9E suchen
- Deine App schreibt hierhin, die Firmware liest daraus
- Die TX Characteristic 6E400003-B5A3-F393-E0A9-E50E24DCCA9E suchen
- Die Firmware schreibt hierhin, deine App liest daraus
- Benachrichtigungen aktivieren
- Initiale Befehle senden
CMD_APP_START senden, um deine App gegenüber der Firmware zu identifizieren und die Radioeinstellungen zu erhalten
- CMD_DEVICE_QUERY senden, um Geräteinformationen abzurufen und unterstützte Protokollversionen auszuhandeln
- CMD_SET_DEVICE_TIME senden, um die Uhr der Firmware zu setzen
- CMD_GET_CONTACTS senden, um alle Kontakte abzurufen
- CMD_GET_CHANNEL mehrfach senden, um alle Kanal-Slots abzurufen
- CMD_SYNC_NEXT_MESSAGE senden, um die nächste in der Firmware gespeicherte Nachricht abzurufen
- Listener für Push-Codes einrichten, beispielsweise PUSH_CODE_MSG_WAITING oder PUSH_CODE_ADVERT
- Siehe den Abschnitt Befehle für Informationen zu weiteren Befehlen
Hinweis: MeshCore-Geräte können sich nach einer Phase der Inaktivität trennen. Implementiere eine automatische Wiederverbindungslogik mit exponentiellem Backoff (schrittweise Verlängerung der Wartezeit zwischen Verbindungsversuchen).
BLE-Schreibtyp
Beim Schreiben von Befehlen auf die RX Characteristic muss der Schreibtyp angegeben werden:
- Write with Response (Standard): Wartet auf eine Bestätigung vom Gerät
- Write without Response: Schneller, aber ohne Bestätigung
- Android:
BluetoothGattCharacteristic.WRITE_TYPE_DEFAULToderWRITE_TYPE_NO_RESPONSEverwenden - iOS:
CBCharacteristicWriteType.withResponseoder.withoutResponseverwenden - Python (bleak):
write_gatt_char()mitresponse=TrueoderFalseverwenden
MTU (Maximum Transmission Unit)
Die standardmäßige BLE-MTU (maximale Übertragungseinheit) beträgt 23 Bytes (20 Bytes Nutzlast). Für größere Befehle wie SET_CHANNEL (50 Bytes) muss möglicherweise Folgendes gemacht werden:
- Größere MTU anfordern: MTU von 512 Bytes anfordern, sofern unterstützt
gatt.requestMtu(512)
- iOS: peripheral.maximumWriteValueLength(for:)
- Python (bleak): Die MTU wird automatisch ausgehandelt
Befehlsreihenfolge
Wichtig: Befehle müssen in der richtigen Reihenfolge gesendet werden:- Nach dem Verbindungsaufbau:
- Befehls-Antwort-Zuordnung:
CMD_GET_CHANNEL → RESP_CODE_CHANNEL_INFO)
Befehls-Warteschlange
Für einen zuverlässigen Betrieb empfiehlt sich die Implementierung einer Befehls-Warteschlange (Command Queue).
Warteschlangenstruktur:- Eine Warteschlange ausstehender Befehle führen
- Verfolgen, welcher Befehl gerade auf eine Antwort wartet
- Den nächsten Befehl erst senden, nachdem die Antwort eingegangen ist oder der Timeout abgelaufen ist
- Bei Timeout: Aktuellen Befehl verwerfen, nächsten aus der Warteschlange verarbeiten
- Bei Fehler: Fehler protokollieren, aktuellen Befehl verwerfen, nächsten verarbeiten
Paketstruktur
Das MeshCore-Protokoll nutzt ein binäres Format mit folgender Struktur:
- Befehle (Commands): Werden von der App über die RX Characteristic an die Firmware gesendet
- Antworten (Responses): Werden von der Firmware über TX-Characteristic-Notifications empfangen
- Alle mehrbytigen Ganzzahlen: Little-Endian-Bytereihenfolge (Ausnahme: CayenneLPP verwendet Big-Endian)
- Alle Strings: UTF-8-Kodierung
Das erste Byte gibt den Pakettyp an (siehe Antwort-Parsing).
---
Befehle
1. App Start
Zweck: Kommunikation mit dem Gerät initialisieren. Muss nach dem Verbindungsaufbau als erstes gesendet werden. Befehlsformat: Beispiel (hex): Antwort:PACKET_SELF_INFO (0x05)
---
2. Device Query
Zweck: Geräteinformationen abfragen. Befehlsformat: Beispiel (hex): Antwort:PACKET_DEVICE_INFO (0x0D) mit Geräteinformationen
---
3. Get Channel Info
Zweck: Informationen über einen bestimmten Kanal abrufen. Befehlsformat: Beispiel (Kanal 1 abfragen): Antwort:PACKET_CHANNEL_INFO (0x12) mit Kanaldetails
---
4. Set Channel
Zweck: Einen Kanal auf dem Gerät anlegen oder aktualisieren. Befehlsformat: Gesamtlänge: 50 Bytes Kanal-Index:- Index 0: Reserviert für öffentliche Kanäle (kein Secret)
- Index 1-7: Verfügbar für private Kanäle
- UTF-8-kodiert
- Maximal 32 Bytes
- Kürzere Namen werden mit Null-Bytes (0x00) aufgefüllt
- Für private Kanäle: 16-Byte-Geheimnis
- Für öffentliche Kanäle: Nur Nullen (0x00)
PACKET_ERROR zurück.
Antwort: PACKET_OK (0x00) bei Erfolg, PACKET_ERROR (0x01) bei Fehler
---
5. Send Channel Message
Zweck: Eine Textnachricht an einen Kanal senden. Befehlsformat: Zeitstempel: Unix-Zeitstempel in Sekunden (32-Bit vorzeichenlose Ganzzahl, Little-Endian) Beispiel („Hello" an Kanal 1 mit Zeitstempel 1234567890 senden): Antwort:PACKET_MSG_SENT (0x06) bei Erfolg
---
6. Send Channel Data Datagram
Zweck: Ein binäres Datagramm an einen Kanal senden. Im Gegensatz zu Kanal-Textnachrichten enthalten Datagramme keine eingebaute Absenderidentität und keinen Zeitstempel – falls benötigt, müssen Anwendungen beides innerhalb der binären Nutzlast selbst kodieren. Befehlsformat: Beispiel (Flood,DATA_TYPE_DEV, Nutzlast A1 B2 C3, Kanal 1):
Datentyp / Transport-Zuordnung:
0x0000(DATA_TYPE_RESERVED) ist ungültig und wird mitPACKET_ERRORabgelehnt.0xFFFF(DATA_TYPE_DEV) ist der Entwickler-Namensraum zum Experimentieren und Entwickeln von Apps.- Werte
0x0001–0xFFFEstehen für registrierte Anwendungs-/Community-Namensräume zur Verfügung. Siehe die Tabelle Registrierte data_type-Werte weiter unten.
- Die maximale Nutzlastlänge beträgt
MAX_CHANNEL_DATA_LENGTH = MAX_FRAME_SIZE - 9 = 163Bytes. - Größere Nutzlasten werden mit
PACKET_ERROR(ERR_CODE_ILLEGAL_ARG) abgelehnt.
PACKET_OK (0x00) bei Erfolg, oder PACKET_ERROR (0x01) mit einem der folgenden Fehlercodes:
ERR_CODE_NOT_FOUND(2) — unbekannterchannel_idxERR_CODE_ILLEGAL_ARG(6) — ungültigepath_len, reservierterdata_type(0x0000) oder Nutzlast größer alsMAX_CHANNEL_DATA_LENGTHERR_CODE_TABLE_FULL(3) — die Sendewarteschlange ist voll; später erneut versuchen
RESP_CODE_CHANNEL_DATA_RECV (0x1B) an den Host weitergeleitet; siehe Empfang von Kanal-Datagrammen.
Registrierte data_type-Werte
data_type ist ein Anwendungsbezeichner, kein Nutzlastformat-Bezeichner. Jeder registrierte Wert identifiziert eine Anwendung, die ihre eigenen internen Nutzlast-Schemata verwaltet. Die Firmware untersucht den Nutzlastinhalt nicht – data_type wird transparent transportiert.
| Wert | Konstante | Zweck |
|---|---|---|
| 0x0000 | DATA_TYPE_RESERVED | Reserviert; beim Senden ungültig |
| 0x0001 – 0x00FF | — | Reserviert für interne Verwendung |
| 0x0100 – 0xFEFF | — | Registrierte Anwendungs-Namensräume (siehe number_allocations.md) |
| 0xFF00 – 0xFFFE | — | Test/Entwicklung; keine Registrierung erforderlich |
| 0xFFFF | DATA_TYPE_DEV | Entwickler-/Experimentier-Namensraum |
Um eine neue Anwendung zu registrieren, reiche einen PR (Pull Request) ein, der eine Zeile zur Tabelle in docs/number_allocations.md hinzufügt. Interne Unterformate innerhalb einer zugewiesenen Application-ID werden von der jeweiligen Anwendung verwaltet und weder in der MeshCore-Firmware noch in diesem Dokument erfasst.
---
Empfang von Kanal-Datagrammen
Eingehende Gruppen-Datagramme (Funkebene PAYLOAD_TYPE_GRP_DATA, 0x06) werden als RESP_CODE_CHANNEL_DATA_RECV-Benachrichtigungen an den Host weitergeleitet.
RESP_CODE_CHANNEL_DATA_RECV, 0x1B):
Pfad-Bytes werden nicht weitergeleitet: Nur path_len wird im Empfangs-Frame mitgeteilt – der Pfad selbst wird nicht an den Host kopiert. Es befinden sich keine Pfad-Bytes zwischen Byte 5 und dem data_type-Feld an den Bytes 6–7, unabhängig von path_len.
Die Semantik der Pfadlänge unterscheidet sich zwischen Senden und Empfangen:
| Richtung | path_len = 0xFF | path_len ≠ 0xFF |
|---|---|---|
| Senden | Netzwerk fluten (Flood) | Direkte Route; der kodierte Pfad folgt (untere 6 Bits = Hash-Anzahl, obere 2 Bits + 1 = Hash-Größe; Byte-Anzahl auf dem Funk = hash_count × hash_size) |
| Empfangen | Paket kam über direkte Route an | Paket wurde geflutet; dies ist das kodierte pkt->path_len-Feld wie beobachtet (keine Pfad-Bytes folgen) |
Anders ausgedrückt: Die Bedeutung von 0xFF ist zwischen den beiden Richtungen invertiert, und beim Empfangen enthält das Feld nur Metadaten – niemals einen routbaren Pfad. path_len ist ein kodiertes Byte (siehe Packet::isValidPathLen / Packet::writePath in src/Packet.cpp), kein roher Byte-Zähler.
PACKET_MESSAGES_WAITING (0x83) senden, um den Host darüber zu benachrichtigen, dass Datagramme in der Warteschlange stehen; mit CMD_SYNC_NEXT_MESSAGE (0x0A) abrufbar.
Parsing-Pseudocode:
---
7. Get Message
Zweck: Die nächste in der Warteschlange stehende Nachricht vom Gerät anfordern. Befehlsformat: Beispiel (hex): Antwort:PACKET_CHANNEL_MSG_RECV(0x08) oderPACKET_CHANNEL_MSG_RECV_V3(0x11) für KanalnachrichtenPACKET_CONTACT_MSG_RECV(0x07) oderPACKET_CONTACT_MSG_RECV_V3(0x10) für KontaktnachrichtenPACKET_CHANNEL_DATA_RECV(0x1B) für Kanal-DatagrammePACKET_NO_MORE_MSGS(0x0A) wenn keine Nachrichten verfügbar sind
PACKET_MESSAGES_WAITING (0x83) als Benachrichtigung senden, wenn Nachrichten verfügbar sind.
---
8. Get Battery and Storage
Zweck: Batteriespannung und Speichernutzung des Geräts abfragen. Befehlsformat: Beispiel (hex): Antwort:PACKET_BATTERY (0x0C) mit Batterie-Millivolt und Speicherinformationen
---
Kanalverwaltung
Kanaltypen
- Öffentlicher Kanal
8b3387e9c5cdea6ac9e5edbaa115cd72
- Jeder kann diesem Kanal beitreten, Nachrichten sollten als öffentlich betrachtet werden
- Wird als Standard-Gruppen-Chat für öffentliche Kommunikation verwendet
- Hashtag-Kanäle
sha256("#test")
- Beispiel: Der Hashtag-Kanal #test hat den Schlüssel: 9cd8fcf22a47333b591d96a2b848b73f
- Wird als themenbasierter öffentlicher Gruppen-Chat verwendet, getrennt vom Standard-Öffentlichkeitskanal
- Private Kanäle
Kanal-Lebenszyklus
- Kanal setzen:
CMD_SET_CHANNEL mit Name und 16-Byte-Secret senden
- Kanal abrufen:
CMD_GET_CHANNEL mit dem Kanal-Index senden
- Die RESP_CODE_CHANNEL_INFO-Antwort parsen
- Kanal löschen:
CMD_SET_CHANNEL mit leerem Namen und Null-Secret senden
- Oder mit einem neuen Kanal überschreiben
---
Nachrichtenverarbeitung
Nachrichten empfangen
Nachrichten werden über die TX Characteristic (Notifications) empfangen. Das Gerät sendet:
- Kanalnachrichten:
PACKET_CHANNEL_MSG_RECV (0x08) – Standardformat
- PACKET_CHANNEL_MSG_RECV_V3 (0x11) – Version 3 mit SNR (Signal-Rausch-Verhältnis)
- Kontaktnachrichten:
PACKET_CONTACT_MSG_RECV (0x07) – Standardformat
- PACKET_CONTACT_MSG_RECV_V3 (0x10) – Version 3 mit SNR
- Benachrichtigungen:
PACKET_MESSAGES_WAITING (0x83) – Signalisiert, dass Nachrichten in der Warteschlange stehen
Kontaktnachricht-Format
Standardformat (PACKET_CONTACT_MSG_RECV, 0x07):
V3-Format (PACKET_CONTACT_MSG_RECV_V3, 0x10):
Parsing-Pseudocode:
Kanalnachricht-Format
Standardformat (PACKET_CHANNEL_MSG_RECV, 0x08):
V3-Format (PACKET_CHANNEL_MSG_RECV_V3, 0x11):
Parsing-Pseudocode:
Nachrichten senden
Verwende den Befehl SEND_CHANNEL_MESSAGE (siehe Befehle).
- Nachrichten sind gemäß MeshCore-Spezifikation auf 133 Zeichen begrenzt
- Längere Nachrichten sollten in Teile aufgeteilt werden
- Einen Teilindikator einfügen (z. B. „[1/3] Nachrichtentext")
Antwort-Parsing
Terminologie
In diesem Dokument wird eine spezifikationsbezogene Namenskonvention (PACKET_*) für die Bytes verwendet, die die Firmware an den Host zurücksendet. Im Firmware-Quellcode sind dieselben Werte je nach Zweck auf zwei #define-Familien aufgeteilt:
RESP_CODE_*— direkte Antworten auf einen Befehl (z. B.RESP_CODE_CHANNEL_DATA_RECV=PACKET_CHANNEL_DATA_RECV= 0x1B).PUSH_CODE_*— asynchrone Benachrichtigungen, die nicht an einen bestimmten Befehl gebunden sind (z. B.PUSH_CODE_MSG_WAITING=PACKET_MESSAGES_WAITING= 0x83).
RESP_CODE_X / PUSH_CODE_X dem PACKET_X dieses Dokuments mit demselben numerischen Wert.
Pakettypen
| Wert | Name | Beschreibung |
|---|---|---|
| 0x00 | PACKET_OK | Befehl erfolgreich ausgeführt |
| 0x01 | PACKET_ERROR | Befehl fehlgeschlagen |
| 0x02 | PACKET_CONTACT_START | Beginn der Kontaktliste |
| 0x03 | PACKET_CONTACT | Kontaktinformation |
| 0x04 | PACKET_CONTACT_END | Ende der Kontaktliste |
| 0x05 | PACKET_SELF_INFO | Eigene Geräteinformationen |
| 0x06 | PACKET_MSG_SENT | Bestätigung: Nachricht gesendet |
| 0x07 | PACKET_CONTACT_MSG_RECV | Kontaktnachricht (Standard) |
| 0x08 | PACKET_CHANNEL_MSG_RECV | Kanalnachricht (Standard) |
| 0x09 | PACKET_CURRENT_TIME | Aktuelle Uhrzeit-Antwort |
| 0x0A | PACKET_NO_MORE_MSGS | Keine weiteren Nachrichten verfügbar |
| 0x0C | PACKET_BATTERY | Batteriestand |
| 0x0D | PACKET_DEVICE_INFO | Geräteinformationen |
| 0x10 | PACKET_CONTACT_MSG_RECV_V3 | Kontaktnachricht (V3 mit SNR) |
| 0x11 | PACKET_CHANNEL_MSG_RECV_V3 | Kanalnachricht (V3 mit SNR) |
| 0x12 | PACKET_CHANNEL_INFO | Kanalinformationen |
| 0x1B | PACKET_CHANNEL_DATA_RECV | Kanal-Datagramm |
| 0x80 | PACKET_ADVERTISEMENT | Advertisement-Paket (Ankündigung) |
| 0x82 | PACKET_ACK | Empfangsbestätigung |
| 0x83 | PACKET_MESSAGES_WAITING | Benachrichtigung: Nachrichten warten |
| 0x88 | PACKET_LOG_DATA | RF-Logdaten (kann ignoriert werden) |
Antworten parsen
PACKET_OK (0x00): PACKET_ERROR (0x01): PACKET_CHANNEL_INFO (0x12): Hinweis: Das Gerät gibt in dieser Antwort das 16-Byte-Kanal-Secret zurück. PACKET_DEVICE_INFO (0x0D): Parsing-Pseudocode: PACKET_BATTERY (0x0C): Parsing-Pseudocode: PACKET_SELF_INFO (0x05): Parsing-Pseudocode: PACKET_MSG_SENT (0x06): PACKET_ACK (0x82):Fehlercodes
PACKET_ERROR (0x01) enthält in Byte 1 einen einzelnen Fehlercode-Byte. Die Werte entsprechen den ERR_CODE_*-Konstanten aus examples/companion_radio/MyMesh.cpp:
| Code | Konstante (Firmware) | Beschreibung |
|---|---|---|
| 1 | ERR_CODE_UNSUPPORTED_CMD | Unbekanntes oder nicht unterstütztes Befehls-Byte / Unterbefehl |
| 2 | ERR_CODE_NOT_FOUND | Ziel nicht gefunden (Kanal, Kontakt, Nachricht usw.) |
| 3 | ERR_CODE_TABLE_FULL | Interne Warteschlange oder Tabelle ist voll — später erneut versuchen |
| 4 | ERR_CODE_BAD_STATE | Operation im aktuellen Gerätezustand nicht zulässig (z. B. Iterator läuft bereits) |
| 5 | ERR_CODE_FILE_IO_ERROR | Dateisystem- oder Speicher-E/A-Fehler |
| 6 | ERR_CODE_ILLEGAL_ARG | Ungültiges Argument (falsche Länge, Wert außerhalb des Bereichs, reserviertes Feld usw.) |
PACKET_ERROR-Antwort und behandle unbekannte Codes als generische Fehler.
Frame-Verarbeitung
BLE-Implementierungen reihen auf Firmware-Ebene je einen Protokoll-Frame pro BLE-Schreib-/Notification-Vorgang ein und liefern ihn aus.
- Apps sollten jede Characteristic-Write/Notification als exakt einen Companion-Protokoll-Frame behandeln
- Apps sollten dennoch Frame-Längen vor dem Parsen validieren
- Zukünftige Transporte oder Firmware-Revisionen können abweichen – verlasse dich daher nicht auf feste Nutzlastgrößen bei Antworten variabler Länge
Antwortverarbeitung
- Befehls-Antwort-Muster:
- Asynchrone Nachrichten:
PACKET_MESSAGES_WAITING (0x83) den GET_MESSAGE-Befehl abfragen
- Eingehende Nachrichten parsen und an die zuständigen Handler weiterleiten
- Frame-Länge vor dem Dekodieren validieren
- Antwort-Zuordnung:
APP_START → PACKET_SELF_INFO
- DEVICE_QUERY → PACKET_DEVICE_INFO
- GET_CHANNEL → PACKET_CHANNEL_INFO
- SET_CHANNEL → PACKET_OK oder PACKET_ERROR
- SEND_CHANNEL_MESSAGE → PACKET_MSG_SENT
- GET_MESSAGE → PACKET_CHANNEL_MSG_RECV, PACKET_CONTACT_MSG_RECV, PACKET_CHANNEL_DATA_RECV oder PACKET_NO_MORE_MSGS
- SEND_CHANNEL_DATA → PACKET_OK oder PACKET_ERROR
- GET_BATTERY → PACKET_BATTERY
- Timeout-Behandlung:
SET_CHANNEL kann 1–2 Sekunden benötigen)
- Für Kanaloperationen einen längeren Timeout in Betracht ziehen
- Fehlerwiederherstellung:
PACKET_ERROR: Fehlercode protokollieren, aktuellen Befehl verwerfen
- Bei Verbindungsverlust: Befehls-Warteschlange leeren, Wiederverbindung versuchen
- Bei ungültiger Antwort: Warnung protokollieren, aktuellen Befehl verwerfen, fortfahren
---
Beispielhafte Implementierung
Initialisierung
Privaten Kanal erstellen
Nachricht senden
Nachrichten empfangen
---
Best Practices
- Verbindungsmanagement:
- Secret-Management:
- Nachrichtenverarbeitung:
CMD_SYNC_NEXT_MESSAGE senden, wenn PUSH_CODE_MSG_WAITING empfangen wird
- Nachrichten-Deduplizierung implementieren, um die doppelte Anzeige derselben Nachricht zu vermeiden
- Kanalverwaltung:
- Fehlerbehandlung:
RESP_CODE_ERR-Antworten angemessen behandeln
---
Fehlerbehebung
Verbindungsprobleme
- Gerät nicht gefunden: Sicherstellen, dass das Gerät eingeschaltet ist und sendet (Advertising)
- Verbindungs-Timeout: Bluetooth-Berechtigungen und Gerätenähe prüfen
- GATT-Fehler: Korrekte Service-/Characteristic-Erkennung sicherstellen
Befehlsprobleme
- Keine Antwort: Prüfen, ob Notifications aktiviert sind und die Verbindung besteht
- Fehlerantworten: Befehlsformat überprüfen und Fehlercode auswerten
- Timeout: Timeout-Wert erhöhen oder erneut versuchen
Nachrichtenprobleme
- Nachrichten werden nicht empfangen: Den
GET_MESSAGE-Befehl regelmäßig abfragen - Doppelte Nachrichten: Nachrichten-Deduplizierung implementieren, z. B. anhand von Zeitstempel/Inhalt als eindeutiger Kennung
- Abgeschnittene Nachrichten: Lange Nachrichten als separate, kürzere Nachrichten senden