From b024bb66a91c073e89950063ed685c20e01002e4 Mon Sep 17 00:00:00 2001 From: Marcel Peterkau Date: Thu, 18 Sep 2025 07:59:01 +0200 Subject: [PATCH] made LoRa-UART Command handler more robust --- Software/src/lora_net.cpp | 134 +++++++++++++++++++++++++------------- 1 file changed, 87 insertions(+), 47 deletions(-) diff --git a/Software/src/lora_net.cpp b/Software/src/lora_net.cpp index b6b667d..026dac3 100644 --- a/Software/src/lora_net.cpp +++ b/Software/src/lora_net.cpp @@ -102,37 +102,57 @@ void LoRa_Process() while (SerialLoRa.available() && !packageReceived) { - if (bufferPtr < sizeof(packageInput) - 1) - { - char c = SerialLoRa.read(); - packageInput[bufferPtr] = c; - packageInput[bufferPtr + 1] = '\0'; // always terminate string + char c = SerialLoRa.read(); - if (c == '\n') + // CR ignorieren (falls CRLF) + if (c == '\r') + { + continue; + } + + if (c == '\n') + { + // Zeilenende: String sauber terminieren, Größe setzen + packageInput[bufferPtr] = '\0'; + receivedSize = bufferPtr; + bufferPtr = 0; + packageReceived = true; + Debug_pushMessage("Got LoRa UART: %s\n", packageInput); + break; + } + + // Optional: in Uppercase wandeln (macht Kommandos robust) + if (c >= 'a' && c <= 'z') + c = (char)(c - 'a' + 'A'); + + // Erlaubte Zeichen (Ziffern, Großbuchstaben, Space, Komma, Punkt, Semikolon) + bool allowed = + (c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c == ' ' || c == ',' || c == '.' || c == ';'); + + if (allowed) + { + if (bufferPtr < sizeof(packageInput) - 1) { - packageReceived = true; - receivedSize = bufferPtr; - bufferPtr = 0; - Debug_pushMessage("Got LoRa UART: %s\n", packageInput); - } - else if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == ' ' || c == ',' || c == '.')) // Accept numbers, uppercase letters, and some special chars - { - bufferPtr++; + packageInput[bufferPtr++] = c; + packageInput[bufferPtr] = '\0'; // immer NUL-terminiert halten } else { - Debug_pushMessage("Invalid character received: %c\n", c); + Debug_pushMessage("Buffer overflow. Resetting buffer.\n"); + bufferPtr = 0; } } else { - Debug_pushMessage("Buffer overflow. Resetting buffer.\n"); - bufferPtr = 0; + Debug_pushMessage("Invalid character received: %c\n", c); } } if (packageReceived) { + // Hinweis: receivedSize ist jetzt strlen(packageInput), ohne \n/\r Parse_LoRa_UartCommand(packageInput, receivedSize); packageReceived = false; } @@ -244,44 +264,60 @@ void printParameters(struct Configuration configuration) Serial.println("----------------------------------------"); } #endif - #ifdef FEATURE_ENABLE_UARTLORA +#include + +static void rstrip(char *s) +{ + size_t n = strlen(s); + while (n && (s[n - 1] == '\r' || s[n - 1] == '\n' || isspace((unsigned char)s[n - 1]))) + { + s[--n] = '\0'; + } +} +static void lstrip(char *s) +{ + size_t i = 0, n = strlen(s); + while (i < n && isspace((unsigned char)s[i])) + i++; + if (i) + memmove(s, s + i, n - i + 1); +} + void Parse_LoRa_UartCommand(char input[], int size) { - Debug_pushMessage("Start parsing, size: %d\n", size); - char delimiter[] = ";"; + + // Auf mehreren Delimitern splitten: ;, CR, LF, Tabs/Spaces + const char *delims = ";\r\n\t "; char *ptr; - char command[8]; - char value[8]; - ptr = strtok(input, delimiter); - - ptr = strtok(input, delimiter); - - while (ptr != NULL) + // erstes Token (Kommando) + ptr = strtok(input, delims); + if (!ptr) { - strncpy(command, ptr, sizeof(command) - 1); // Platz für Nullterminator lassen - command[sizeof(command) - 1] = '\0'; // Nullterminator setzen - - ptr = strtok(NULL, delimiter); - - if (ptr != NULL) - { - strncpy(value, ptr, sizeof(value) - 1); // Platz für Nullterminator lassen - value[sizeof(value) - 1] = '\0'; // Nullterminator setzen - } - else - { - // Wenn ptr NULL ist, setze value auf leeren String - value[0] = '\0'; - } - - // Hier kannst du den Wert und das Kommando verarbeiten - Debug_pushMessage("Command: %s, Value: %s\n", command, value); + Debug_pushMessage("No command token\n"); + return; } - Debug_pushMessage("Parsed LoRa UART Command: %s Value: %s\n", command, value); + char command[16]; + strncpy(command, ptr, sizeof(command) - 1); + command[sizeof(command) - 1] = '\0'; + lstrip(command); + rstrip(command); + + // zweites Token (optional: Wert) + ptr = strtok(NULL, delims); + char value[16] = {0}; + if (ptr) + { + strncpy(value, ptr, sizeof(value) - 1); + value[sizeof(value) - 1] = '\0'; + lstrip(value); + rstrip(value); + } + + Debug_pushMessage("Parsed LoRa UART Command: %s Value: %s\n", command, value); if (!strcmp(command, "ENABLE")) { @@ -329,5 +365,9 @@ void Parse_LoRa_UartCommand(char input[], int size) { PersistenceData.activeFaction = FACTION_3; } + else + { + Debug_pushMessage("Unknown command: %s\n", command); + } } -#endif \ No newline at end of file +#endif