Files
DarkEmergency-Timer/Software/src/lora_net.cpp

374 lines
12 KiB
C++

#include "lora_net.h"
#ifdef FEATURE_ENABLE_LORA
LoRa_E220 e220ttl(GPIO_LORA_TX, GPIO_LORA_RX, GPIO_LORA_AUX, 3, 4); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
void printParameters(struct Configuration configuration);
void printModuleInformation(struct ModuleInformation moduleInformation);
#elif defined(FEATURE_ENABLE_UARTLORA)
SoftwareSerial SerialLoRa(GPIO_LORA_RX, GPIO_LORA_TX); // RX, TX
void Parse_LoRa_UartCommand(char input[], int size);
#endif
bool InitLoRa(void (*MPinHelper)(int, int))
{
bool returnval = false;
#ifdef FEATURE_ENABLE_LORA
e220ttl.setMPins = MPinHelper;
returnval = e220ttl.begin();
if (returnval == true)
{
ResponseStructContainer c;
c = e220ttl.getConfiguration();
// It's important get configuration pointer before all other operation
Configuration configuration = *(Configuration *)c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.code);
ResponseStructContainer cMi;
cMi = e220ttl.getModuleInformation();
// It's important get information pointer before all other operation
// ModuleInformation mi = *(ModuleInformation *)cMi.data;
Serial.println(cMi.status.getResponseDescription());
Serial.println(cMi.status.code);
// ----------------------- DEFAULT TRANSPARENT WITH RSSI -----------------------
configuration.ADDL = 0x02;
configuration.ADDH = 0x00;
configuration.CHAN = 23;
configuration.SPED.uartBaudRate = UART_BPS_9600;
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
configuration.SPED.uartParity = MODE_00_8N1;
configuration.OPTION.subPacketSetting = SPS_200_00;
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_ENABLED;
configuration.OPTION.transmissionPower = POWER_22;
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
configuration.TRANSMISSION_MODE.enableLBT = LBT_ENABLED;
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
// Set configuration changed and set to not hold the configuration
ResponseStatus rs = e220ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
Serial.println(rs.getResponseDescription());
Serial.println(rs.code);
c.close();
printParameters(configuration);
}
else
{
MaintainDTC(DTC_NO_LORA_FOUND, DTC_WARN, true);
}
#elif defined(FEATURE_ENABLE_UARTLORA)
SerialLoRa.begin(9600);
returnval = true;
#endif
return returnval;
}
void LoRa_Process()
{
#ifdef FEATURE_ENABLE_LORA
if (e220ttl.available() > 1)
{
ResponseContainer rc = e220ttl.receiveMessageRSSI();
// If something goes wrong, print error
if (rc.status.code != 1)
{
Serial.println(rc.status.getResponseDescription());
}
else
{
// Print the data received
Serial.println(rc.status.getResponseDescription());
Serial.println(rc.data);
Serial.print("RSSI: ");
Serial.println(rc.rssi, DEC);
}
}
#elif defined(FEATURE_ENABLE_UARTLORA)
static char packageInput[32];
static bool packageReceived = false;
static unsigned int bufferPtr = 0;
int receivedSize = 0;
while (SerialLoRa.available() && !packageReceived)
{
char c = SerialLoRa.read();
// 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)
{
packageInput[bufferPtr++] = c;
packageInput[bufferPtr] = '\0'; // immer NUL-terminiert halten
}
else
{
Debug_pushMessage("Buffer overflow. Resetting buffer.\n");
bufferPtr = 0;
}
}
else
{
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;
}
#endif
}
void sendStatus_LoRa()
{
#ifdef FEATURE_ENABLE_LORA
struct
{
MessageType_t type = "STATUS";
MessageStatus_t status;
} __attribute__((packed)) sendStatus;
sendStatus.status.nodeid = 0x0002;
sendStatus.status.millis = millis();
sendStatus.status.faction_active = 1;
sendStatus.status.faction_1_timer = 0xBBBBBBBB;
sendStatus.status.faction_2_timer = 0xCCCCCCCC;
sendStatus.status.faction_3_timer = 0xDDDDDDDD;
ResponseStatus rs = e220ttl.sendFixedMessage(0xFF, 0xFF, 23, (byte *)&sendStatus, sizeof(sendStatus));
Serial.println(rs.getResponseDescription());
#elif defined(FEATURE_ENABLE_UARTLORA)
SerialLoRa.print(PersistenceData.faction_1_timer);
SerialLoRa.write(";");
SerialLoRa.print(PersistenceData.faction_2_timer);
SerialLoRa.write(";");
SerialLoRa.print(PersistenceData.faction_3_timer);
SerialLoRa.write(";");
SerialLoRa.print(PersistenceData.activeFaction);
SerialLoRa.write(";");
SerialLoRa.print(globals.battery_level);
SerialLoRa.write('\n');
#endif
}
#ifdef FEATURE_ENABLE_LORA
void printParameters(struct Configuration configuration)
{
Serial.println("----------------------------------------");
Serial.print(F("HEAD : "));
Serial.print(configuration.COMMAND, HEX);
Serial.print(" ");
Serial.print(configuration.STARTING_ADDRESS, HEX);
Serial.print(" ");
Serial.println(configuration.LENGHT, HEX);
Serial.println(F(" "));
Serial.print(F("AddH : "));
Serial.println(configuration.ADDH, HEX);
Serial.print(F("AddL : "));
Serial.println(configuration.ADDL, HEX);
Serial.println(F(" "));
Serial.print(F("Chan : "));
Serial.print(configuration.CHAN, DEC);
Serial.print(" -> ");
Serial.println(configuration.getChannelDescription());
Serial.println(F(" "));
Serial.print(F("SpeedParityBit : "));
Serial.print(configuration.SPED.uartParity, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getUARTParityDescription());
Serial.print(F("SpeedUARTDatte : "));
Serial.print(configuration.SPED.uartBaudRate, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getUARTBaudRateDescription());
Serial.print(F("SpeedAirDataRate : "));
Serial.print(configuration.SPED.airDataRate, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getAirDataRateDescription());
Serial.println(F(" "));
Serial.print(F("OptionSubPacketSett: "));
Serial.print(configuration.OPTION.subPacketSetting, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getSubPacketSetting());
Serial.print(F("OptionTranPower : "));
Serial.print(configuration.OPTION.transmissionPower, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getTransmissionPowerDescription());
Serial.print(F("OptionRSSIAmbientNo: "));
Serial.print(configuration.OPTION.RSSIAmbientNoise, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getRSSIAmbientNoiseEnable());
Serial.println(F(" "));
Serial.print(F("TransModeWORPeriod : "));
Serial.print(configuration.TRANSMISSION_MODE.WORPeriod, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
Serial.print(F("TransModeEnableLBT : "));
Serial.print(configuration.TRANSMISSION_MODE.enableLBT, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
Serial.print(F("TransModeEnableRSSI: "));
Serial.print(configuration.TRANSMISSION_MODE.enableRSSI, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
Serial.print(F("TransModeFixedTrans: "));
Serial.print(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());
Serial.println("----------------------------------------");
}
#endif
#ifdef FEATURE_ENABLE_UARTLORA
#include <ctype.h>
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);
// Auf mehreren Delimitern splitten: ;, CR, LF, Tabs/Spaces
const char *delims = ";\r\n\t ";
char *ptr;
// erstes Token (Kommando)
ptr = strtok(input, delims);
if (!ptr)
{
Debug_pushMessage("No command token\n");
return;
}
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"))
{
globals.timer_disabled = false;
Debug_pushMessage("Enabled by LoRa\n");
}
else if (!strcmp(command, "DISABLE"))
{
globals.timer_disabled = true;
Debug_pushMessage("Disabled by LoRa\n");
}
else if (!strcmp(command, "RESET"))
{
PersistenceData.activeFaction = NONE;
PersistenceData.faction_1_timer = 0;
PersistenceData.faction_2_timer = 0;
PersistenceData.faction_3_timer = 0;
Debug_pushMessage("Reset by LoRa\n");
}
else if (!strcmp(command, "TMRSTP"))
{
PersistenceData.activeFaction = NONE;
}
else if (!strcmp(command, "TMR1"))
{
PersistenceData.faction_1_timer = atol(value);
}
else if (!strcmp(command, "TMR2"))
{
PersistenceData.faction_2_timer = atol(value);
}
else if (!strcmp(command, "TMR3"))
{
PersistenceData.faction_3_timer = atol(value);
}
else if (!strcmp(command, "EFAC1"))
{
PersistenceData.activeFaction = FACTION_1;
}
else if (!strcmp(command, "EFAC2"))
{
PersistenceData.activeFaction = FACTION_2;
}
else if (!strcmp(command, "EFAC3"))
{
PersistenceData.activeFaction = FACTION_3;
}
else
{
Debug_pushMessage("Unknown command: %s\n", command);
}
}
#endif