LoRaWAN MAC Layer und Frame-Struktur: MHDR, FHDR, FPort und MIC erklärt

Ein LoRaWAN-Paket ist deutlich mehr als die Anwendungsnutzlast eines Sensors. Vor und hinter dem Messwert liegen Header, Adresse, Steuerbits, Frame Counter, optionale MAC-Kommandos und ein Message Integrity Code. Wer nur den dekodierten Temperaturwert sieht, übersieht genau die Felder, die bei Join-Problemen, ADR, Bestätigungen oder Replay-Schutz entscheidend sind.

LoRa beschreibt die physikalische Funkübertragung. Der LoRaWAN MAC Layer organisiert darüber Nachrichtentypen, Adressierung, Empfangsfenster, Kommandos und Sicherheit. Diese Trennung hilft bei der Fehlersuche: Ein Gateway kann ein LoRa-Paket sauber demodulieren, während der Network Server den LoRaWAN-Frame wegen falschem MIC oder inkonsistentem Counter verwirft.

Frame in einem Satz: Ein regulärer LoRaWAN-Datenframe besteht aus MHDR, MACPayload und einem vier Byte langen MIC. Das MACPayload enthält FHDR sowie optional FPort und FRMPayload; das FHDR wiederum enthält DevAddr, FCtrl, FCnt und bis zu 15 Byte FOpts.

Physical Layer und MAC Layer auseinanderhalten

Die Seite Was ist LoRa? ordnet Chirp Spread Spectrum und den Physical Layer ein. Dort entstehen Präambel, LoRa-Header, Modulation, Bandbreite, Coding Rate und Spreading Factor. LoRaWAN setzt darauf seinen PHYPayload. Ein Funkanalysator kann deshalb physikalische Metadaten wie Frequenz und SNR liefern, ohne die verschlüsselte Anwendung zu kennen.

Der MAC Layer beginnt mit dem MHDR. Er entscheidet, ob Join, Rejoin, bestätigte oder unbestätigte Daten vorliegen und wie das restliche Paket behandelt werden muss. Gateway und Packet Forwarder sollen diese Semantik nicht als Anwendung auswerten; sie reichen empfangene Pakete samt Metadaten zum Network Server weiter.

Die äußere Struktur des PHYPayload

Nach der LoRaWAN-L2-Spezifikation 1.0.4 beginnt jeder Up- oder Downlink-PHYPayload mit einem Byte MHDR und endet mit vier Byte MIC. Dazwischen liegt je nach Nachricht ein MACPayload, Join-Request oder Join-Accept. Bei Datenframes ist das MACPayload mindestens sieben Byte lang; seine Obergrenze hängt von Region und verwendeter Datenrate ab.

Ebene Feld Länge Aufgabe
PHYPayload MHDR 1 Byte Frame-Typ und R1-Major-Version
PHYPayload MACPayload variabel Header, Port, Kommandos und Nutzlast
PHYPayload MIC 4 Byte Integrität und Authentizität des Frames
MACPayload FHDR 7 bis 22 Byte Adresse, Steuerung, Counter und FOpts
MACPayload FPort 0 oder 1 Byte Zuordnung von MAC- oder Anwendungsdaten
MACPayload FRMPayload variabel verschlüsselte MAC- oder Anwendungsdaten

MHDR: Ein Byte bestimmt den Nachrichtentyp

Die oberen drei Bits des MHDR bilden in 1.0.4 das FType-Feld, in vielen Darstellungen MType genannt. Es unterscheidet Join-Request, Join-Accept, unbestätigten Uplink, unbestätigten Downlink, bestätigten Uplink, bestätigten Downlink, RFU und Proprietary. Ein bestätigter Datenframe verlangt eine protokollgerechte Bestätigung; ein unbestätigter Frame nicht.

Drei mittlere Bits sind reserviert, zwei untere Bits tragen Major. Für die heute betrachtete R1-Familie steht Major auf 00. LoRaWAN 1.0.x und 1.1 teilen diesen Wert. Die genaue Minor-Version wird dem Server außerhalb des Frames bekannt gemacht, wie der Vergleich LoRaWAN 1.0.x und 1.1 erläutert.

FHDR: Der eigentliche Steuerkopf

Das Frame Header FHDR beginnt mit der vier Byte langen DevAddr. Danach folgen ein Byte FCtrl, zwei übertragene Byte FCnt und optional null bis 15 Byte FOpts. Alle mehrbyteigen Felder werden gemäß L2-Spezifikation little endian übertragen. Eine hexadezimale Darstellung wirkt deshalb häufig umgedreht, wenn man sie direkt mit der üblichen Schreibweise einer DevAddr vergleicht.

Die DevAddr identifiziert die aktive Gerätesitzung im Netz, nicht dauerhaft das physische Produkt. Nach einem neuen OTAA-Join kann das Gerät eine andere DevAddr erhalten. Für Inventar und Anwendung bleibt die globale DevEUI die stabilere Identität; ein Decoder sollte beide Rollen nicht vermischen.

FCtrl im Uplink

Im Uplink enthält FCtrl die Bits ADR, ADRACKReq, ACK und ClassB sowie vier Bits FOptsLen. ADR zeigt die Teilnahme am Adaptive-Data-Rate-Regelkreis. ADRACKReq fordert nach längerer Downlink-Stille eine Rückmeldung. ACK bestätigt einen zuvor empfangenen bestätigten Downlink. ClassB signalisiert, dass geplante Class-B-Ping-Slots aktiv sind.

FOptsLen gibt die tatsächliche Länge von FOpts an. Ein Wert null bedeutet, dass FOpts vollständig fehlt. Die Kombination der Steuerbits erklärt, weshalb ein Uplink auch ohne Anwendungsnutzlast fachlich relevant sein kann: Er kann eine Bestätigung, einen Klassenstatus oder MAC-Antworten transportieren.

FCtrl im Downlink

Im Downlink stehen ADR, ein reserviertes Bit, ACK, FPending und FOptsLen. FPending zeigt einem Class-A-Gerät, dass weitere Daten warten. Das Gerät kann darauf mit einem weiteren Uplink reagieren und dadurch neue RX1/RX2-Fenster öffnen. FPending selbst trägt die wartende Nutzlast nicht.

ACK bestätigt den zuletzt passenden bestätigten Uplink. Ein gesetztes ACK ist nicht dasselbe wie ADRACKReq und auch kein allgemeiner Nachweis, dass jede Anwendungsnachricht verarbeitet wurde. Es bestätigt den LoRaWAN-Frame auf MAC-Ebene, nicht die fachliche Ausführung eines Befehls hinter dem Application Server.

FCnt: 16 Bit im Frame, 32 Bit im Zustand

Das FCnt-Feld überträgt nur die unteren 16 Bit des 32-Bit-Frame-Counters. Gerät und Server rekonstruieren die oberen Bits aus dem bisherigen Sitzungszustand. Bei LoRaWAN 1.0.4 gibt es FCntUp und FCntDown. Version 1.1 führt dagegen zwei Downlink-Zähler: NFCntDown begleitet die Netzwerkkommunikation, AFCntDown die Anwendungsports.

Wiederverwendung eines Counter-Werts mit denselben Session Keys ist außerhalb der Wiederholung desselben Uplink-Frames unzulässig. Ein Server verwirft alte oder unplausible Frames, um Replay zu verhindern. Bei ABP müssen Counter einen Stromverlust überstehen. Ein Werkreset, der nur den Counter löscht, kann das Gerät daher aus seinem Netzkontext werfen.

FOpts: MAC-Kommandos ohne zusätzlichen Port

FOpts kann bis zu 15 Byte MAC-Kommandos an einen normalen Datenframe anhängen. So lassen sich etwa LinkADRReq, LinkADRAns oder Gerätestatus gemeinsam mit Anwendungsdaten transportieren. Sind FOpts vorhanden, darf FPort 0 nicht gleichzeitig verwendet werden; MAC-Kommandos dürfen nicht parallel in FOpts und FRMPayload stehen.

In LoRaWAN 1.0.4 sind piggyback übertragene FOpts nicht verschlüsselt. In LoRaWAN 1.1 werden sie mit NwkSEncKey verschlüsselt. Für 1.1 ist die LoRa-Alliance-Errata zu FOpts und FCntDwn zu berücksichtigen. Ein Packet Decoder braucht deshalb neben Schlüsseln auch die korrekte Minor-Version.

FPort trennt Netzwerk- und Anwendungsnutzlast

Ist FRMPayload vorhanden, muss FPort mitgesendet werden. FPort 0 bedeutet, dass FRMPayload ausschließlich MAC-Kommandos enthält. Die Ports 1 bis 223 sind anwendungsspezifisch. Port 224 dient dem MAC-Testprotokoll; 224 bis 255 sind für Nutzung und Zuweisung durch die LoRa Alliance reserviert.

Ein Anwendungsport ist kein TCP- oder UDP-Port. Er ist ein einzelnes Byte innerhalb des LoRaWAN-Frames und hilft der Anwendung, Payload-Formate zu unterscheiden. Ein Sensor kann etwa Messdaten und Diagnose auf getrennten FPorts senden. Das Payloadschema, Einheiten und Versionierung definiert LoRaWAN nicht.

FRMPayload wird verschlüsselt

Bei 1.0.4 wird FRMPayload auf FPort 0 mit NwkSKey verschlüsselt, auf FPort 1 bis 255 mit AppSKey. Damit kann der Network Server MAC-Kommandos verarbeiten, während Anwendungsdaten für den Application Server geschützt bleiben. Headerfelder wie DevAddr und FCtrl müssen für Routing und Protokollsteuerung lesbar bleiben.

LoRaWAN 1.1 verwendet für FPort 0 NwkSEncKey und für Anwendungsports weiterhin AppSKey. Verschlüsselung allein beweist aber noch nicht die Authentizität des gesamten Frames. Dafür kommt der MIC hinzu. Die beiden Mechanismen erfüllen unterschiedliche Aufgaben.

MIC: vier Byte für Integrität und Authentizität

Der Message Integrity Code steht am Ende des PHYPayload und wird über den Frame sowie einen zusätzlichen Block mit Richtung, Adresse, Counter und Länge berechnet. In 1.0.4 basiert der Datenframe-MIC auf NwkSKey. Der Empfänger verwirft den Frame, wenn die Berechnung nicht zum übertragenen MIC passt.

LoRaWAN 1.1 teilt den Uplink-MIC zwischen SNwkSIntKey und FNwkSIntKey und bindet zusätzlich Datenrate, Kanalindex und gegebenenfalls den bestätigten Counter ein. Das unterstützt die getrennten Backendrollen beim Roaming. Ein gültiger MIC sagt dennoch nichts darüber aus, ob ein Temperaturfühler richtig kalibriert ist oder die Anwendung den Wert fachlich akzeptiert hat.

Drei verschiedene Prüfungen

  • Funkprüfung: Präambel, Modulation und PHY-CRC wurden empfangen
  • MAC-Prüfung: Counter, Nachrichtentyp und MIC sind gültig
  • Anwendungsprüfung: Payloadschema, Einheit, Wertebereich und Assetbezug sind plausibel

Join-Frames haben eine andere Nutzlast

Ein Join-Request enthält keine DevAddr und keinen normalen FHDR. Bei 1.0.4 transportiert er JoinEUI, DevEUI und DevNonce zwischen MHDR und MIC. Der Join-Accept liefert unter anderem JoinNonce, Home_NetID, DevAddr, Downlink-Einstellungen, RXDelay und optional eine CFList. Aus dem Join entstehen die Session Keys und Counterzustände.

LoRaWAN 1.1 ergänzt Rejoin-Request als eigenen MType. Seine verschiedenen Typen unterstützen Handover, Zustandswiederherstellung und Rekeying. Ein Decoder, der jedes Paket nach dem normalen Datenframe-Schema interpretiert, produziert bei Join und Rejoin zwangsläufig falsche Felder.

Wie viel Anwendungsnutzlast bleibt übrig

Die maximale MACPayload-Länge ist regional und datenratenabhängig. Von ihr gehen mindestens sieben Byte FHDR und bei vorhandener Nutzlast ein Byte FPort ab; FOpts verkleinert den verbleibenden Raum weiter. MHDR und MIC liegen zusätzlich außerhalb des MACPayload. Die maximale Anwendungspayload ist deshalb nicht einfach die maximale Funkpaketlänge.

Die aktuellen Regional Parameters RP002-1.0.5 sind für konkrete Grenzwerte maßgeblich. Ein Codec sollte außerdem nicht jede mögliche Byteposition füllen. Versionskennung, Fehlerstatus und zukünftige Erweiterungen brauchen Reserve, und langsamere Datenraten verursachen mit großen Frames lange Airtime.

Ein Datenframe schrittweise lesen

  1. MHDR auswerten und Uplink, Downlink, Join oder Proprietary unterscheiden.
  2. Bei Datenframes DevAddr in Little-Endian-Reihenfolge rekonstruieren.
  3. FCtrl richtungsabhängig in ADR, ACK, FPending oder ClassB und FOptsLen zerlegen.
  4. FCnt mit dem serverseitigen 32-Bit-Sitzungszustand vervollständigen.
  5. FOpts nach Minor-Version entschlüsseln beziehungsweise als MAC-Kommandos parsen.
  6. FPort bestimmen und FRMPayload mit dem richtigen Session Key entschlüsseln.
  7. MIC mit Version, Richtung, Counter und zuständigen Network Keys prüfen.
  8. Erst danach den anwendungsspezifischen Payloadcodec anwenden.

Typische Diagnosefehler

  • LoRa-PHY-Empfang mit erfolgreicher LoRaWAN-Verarbeitung gleichsetzen
  • die übertragene 16-Bit-FCnt-Hälfte als vollständigen Counter behandeln
  • FOpts und FRMPayload gleichzeitig als Anwendungspayload dekodieren
  • für FPort 0 den AppSKey statt des Network Encryption Keys verwenden
  • 1.0.x- und 1.1-MIC- beziehungsweise FOpts-Regeln vermischen
  • die maximale MACPayload-Länge mit frei verfügbarer Anwendungsnutzlast verwechseln

Viele dieser Fehler werden sichtbar, wenn Gateway-Metadaten, Network-Server-Log und Geräteprofil gemeinsam betrachtet werden. Eine einzelne Hex-Zeile ohne Region, Richtung, Version und Sitzungszustand reicht selten für eine belastbare Diagnose.

Frame-Struktur verbindet die übrigen LoRaWAN-Themen

Die Geräteklassen A, B und C nutzen dieselbe grundlegende Datenframe-Struktur, unterscheiden sich aber in den Empfangszeitpunkten. Der ADR-Mechanismus verwendet FCtrl-Bits und MAC-Kommandos. Beim LoRaWAN-Roaming entscheiden DevAddr, NetID, Keys und MIC darüber, welches Backend einen Frame kontrolliert.

Die Frame-Struktur ist damit kein isoliertes Entwicklerdetail. Sie ist das gemeinsame Vokabular, mit dem Gerät, Network Server, Join Server und Anwendung ihren Zustand koordinieren.

Häufige Fragen

Wie ist ein LoRaWAN-Datenframe aufgebaut?

Außen stehen ein Byte MHDR, das variable MACPayload und vier Byte MIC. Im MACPayload folgen FHDR sowie optional FPort und FRMPayload; FHDR enthält DevAddr, FCtrl, FCnt und FOpts.

Ist der gesamte LoRaWAN-Frame verschlüsselt?

Nein. FRMPayload wird verschlüsselt, und in LoRaWAN 1.1 auch FOpts. Routing- und Steuerfelder wie MHDR, DevAddr und FCtrl bleiben lesbar. Der MIC schützt Integrität und Authentizität.

Warum werden nur 16 Bit des Frame Counters übertragen?

Das spart Airtime. Gerät und Server führen intern einen 32-Bit-Counter und rekonstruieren die oberen Bits aus dem Sitzungszustand.

Was bedeutet FPort 0?

FPort 0 kennzeichnet ein FRMPayload, das ausschließlich MAC-Kommandos enthält. Anwendungsdaten verwenden in der Regel Ports 1 bis 223.

Was ist der Unterschied zwischen MIC und Verschlüsselung?

Verschlüsselung verbirgt die Nutzlast. Der MIC ermöglicht dem Empfänger zu prüfen, ob der Frame von einem berechtigten Sitzungspartner stammt und unverändert ist.