PHP-Script für LoRaWAN Sensordaten
07.07.2024
Elektronik | Funk | Software
Der Technik-Blog
Der Frame Counter ist ein Sicherheitsfeature von LoRaWAN. Während bei OTTA der Frame Counter nach jedem JOIN zurückgesetzt wird, bleibt der Frame Counter bei ABP bestehen. Besonders bei Selbstbau-Nodes wie mit dem ESP32 LoRa Board oder einem Arduino Uno kommt es zu Problemen mit dem Frame Counter im ABP Betrieb. In diesem Artikel geht es um Lösungsmöglichkeiten, wie man den Frame Counter Stand auch nach einem Reset oder Stromausfall im ESP32 beibehalten kann.
Source Code LoRaWAN ABP mit aktiven Frame Counter
So funktioniert die LoRa Payload
ESP32 LoRaWAN mit ABP
ESP32 im Arduino IDE installieren
Der Frame Counter ist ein Zähler, der bei jeder Aussendung um den Wert 1 erhöht wird. Der aktuelle Wert wird sowohl im Endgerät als auch am LoRaWAN-Server gespeichert. Der Uplink-Framecounter zählt jene Pakete, welche vom Endgerät zum LoRaWAN-Netzwerk gesendet werden. Der Downlink-Framecounter zählt jene Pakete, welche vom LoRaWAN-Netzwerk zum Endgerät gesendet werden. Grundsätzlich ist es nicht möglich, ein Datenpaket zu entschlüsseln, wenn man nicht den App-Session-Key kennt. Trotzdem besteht die Möglichkeit, ein Datenpaket mit einem Empfänger Binär (über die Modulation) aufzuzeichnen und erneut abzusenden. Das LoRaWAN-Netzwerk kann nicht unterscheiden, ob das Datenpaket vom gleichen Absender kommt oder ob es von einem fremden System kopiert und erneut abgesendet wurde. Mit dem Frame Counter wird dies verhindert. Der Frame Counter wird direkt in die Verschlüsselung mit hinein gerechnet, wodurch physikalisch jedes Datenpaket anders aussieht. Ein erneutes Absenden eines aufgezeichneten Datenpakets ist somit nicht mehr möglich. Übrigens wird so ein Angriff auch als Replay-Attack bezeichnet.
Jeder Mikrocontroller und auch jedes Development Board hat verschiedene Speicher eingebaut. Grundsätzlich findet man auf jedem Mikrocontroller einen Arbeitsspeicher (RAM) und einen Programmspeicher (meist Flash). Darüber hinaus gibt es dann entweder eine Partition im Flash, wo Daten permanent während der Programmlaufzeit abgespeichert werden können oder es gibt einen EEPROM. Auf vielen Entwicklungs-Boards findet man oft auch externe Speicher wie einen SPI-Flash oder einen batteriegepufferten RAM.
ESP32 Permanent Speicher
Der ESP32 hat einen bestimmten Speicherbereich (meist etwa 20 KB) im internen Flash reserviert, der genau für solche Zwecke vorgesehen ist.
Arduino Permanent Speicher
Der Arduino hat zwar auch einen Flash Speicher, aber auf diesen Speicher greift in der Regel nur der Bootloader zu. Während der Programmlaufzeit ist ein Zugriff nur bedingt und sehr aufwendig möglich. Aber es gibt einen integrierten EEPROM, der je nach Prozessortyp von 512 Byte bis zu zwei Kilobyte groß ist. Auch dieser Speicher ist für den Frame Counter geeignet. In diesem Artikel wird jedoch nur auf den ESP32 eingegangen, aber der Speicherzugriff am Arduino funktioniert ähnlich. Weitere Information zum Arduino EEPROM Zugriff gibt es in diesem Artikel.
Der folgende Beispielcode zeigt den Schreib- und Lesezugriff auf den internen Flash. Als Bibliothek wird die "Preferences Library" verwendet. Diese Library wird mit dem ESP32 im Arduino IDE bereits automatisch vorinstalliert.
//More information at: https://www.aeq-web.com #include <Preferences.h> Preferences preferences; void setup() { delay(2000); Serial.begin(115200); Serial.println(); Serial.print("Counter after Reboot: "); Serial.println(fcnt_read()); } void loop() { delay(10000); fcnt_up(); Serial.print("Counter: "); Serial.println(fcnt_read()); } unsigned int fcnt_read() { preferences.begin("fcnt", true); unsigned int counter = preferences.getUInt("counter", 0); preferences.end(); return counter; } void fcnt_up() { preferences.begin("fcnt", false); unsigned int counter = preferences.getUInt("counter", 0); preferences.putUInt("counter", counter+1); preferences.end(); }
Im Setup wird über die Funktion "fcnt_read()" der letzte Frame Counter aufgerufen und im Serial Monitor ausgegeben. Die Integer-Funktion "fcnt_read" startet mit "preferences.beginn" einen Speicherzugriff auf den Bereich "fcnt". Das "true" definiert einen Read-Only Zugriff. Anschließend wird ein neues Interger mit den Variablennamen "counter" deklariert. Über "getUInit" wird die Variable "counter" aus dem Speicher gelesen. Die Null am Ende dieser Zeile wird ausgegeben, wenn die Variable im zuvor definierten Speicherbereich nicht gefunden wurde. In der Praxis startet somit der Frame Counter auch erstmalig bei 0. Über das return wird der aktuelle Zählerstand von der Funktion zurück gegeben.
Die Funktion "fcnt_up" ruft zuerst den aktuellen Zählerstand (gleich wie bei "fcnt_read()") vom Speicher ab. Mit "putUInt" wird der neue Zählerstand in den Speicher geschrieben. Mit "counter+1" wird der Zähler vor dem Speichern um den Wert 1 erhöht.
Im Loop wird alle 10 Sekunden der Zählerstand mit "fcnt_up" um den Wert 1 erhöht. Anschließend wird aus dem Speicher der Zählerstand ausgelesen und über den Serial Monitor ausgegeben. Der Zählerstand bleibt somit auch nach einem Reset oder Programmupload erhalten.
Jeder Speicher hat eine begrenzte Anzahl an Schreibzyklen. Egal ob beim ESP32 der Flash Speicher oder am Arduino der EEPROM, man kann hier mit etwa 100.000 Schreibzyklen rechnen. Aus der Praxis ist jedoch bekannt, dass die maximale Anzahl an Schreibzyklen deutlich höher ist. Es ist keine Seltenheit, dass zum Beispiel erst nach 400.000 Zyklen beim Arduino EEPROM erstmalig ein Speicherfehler auftritt. Lesezugriffe können dagegen beliebig oft durchgeführt werden.
Intervall | Lebenszeit |
---|---|
Jede Minute | ~ 70 Tage |
Alle 5 Minuten | ~ 347 Tage |
Alle 15 Minuten | ~ 2,8 Jahre |
Jede Stunde | ~ 11,4 Jahre |
Um den jeweiligen Speicher zu schonen, kann man auch den Frame Counter in bestimmten Intervallen speichern. Hat man eine Wetterstation, die alle 10 Minuten neue Daten sendet, so könnte man den Frame Counter auch nur jede Stunde in den Speicher schreiben. Kommt es zu einem Stromausfall und der Zählerstand ist mit dem LoRaWAN Netzwerk nicht synchron abgespeichert, so ist damit zu rechnen, dass die nächsten Datenpakete abgelehnt werden. Sobald der Zähler wieder höher ist als jener vom vorherigen gültigen Datenpaket, nimmt das LoRaWAN Netzwerk diese Datenpakete wieder an. Man kann also den Speicher schonen, muss aber dafür kurze Ausfallzeiten nach einem Stromausfall bei der Hardware in Kauf nehmen. Alternativ bleibt nur die Möglichkeit, auf OTTA umzusteigen.
Der vollständige Quellcode basiert auf der LMIC Library mit angepassten Beispielcode für die permanente Speicherung des Framecounters. Der vollständige Beispielcode und alle weiteren Beispiele befinden sich auf dieser Seite.
Einstieg in das LoRaWAN (TTN) mit dem Heltec LoRa32 V3 und Einrichtung vom Board in der Arduino IDE
WeiterlesenStarthilfe LoRaWAN - Diese Seite richtet sich an alle Einsteiger, die mit LoRaWAN starten wollen und ihre Sensoren in das IoT-Netzwerkt TTN integrieren wollen
WeiterlesenAEQ-WEB © 2015-2024 All Right Reserved