diff --git a/src/A7670_utils.cpp b/src/A7670_utils.cpp
index e1f2f73..51b5518 100644
--- a/src/A7670_utils.cpp
+++ b/src/A7670_utils.cpp
@@ -1,17 +1,17 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
- *
+ *
* This file is part of LoRa APRS iGate.
- *
+ *
* LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see .
*/
@@ -26,7 +26,7 @@
#ifdef HAS_A7670
- #define TINY_GSM_MODEM_SIM7600 //The AT instruction of A7670 is compatible with SIM7600
+ #define TINY_GSM_MODEM_SIM7600 //The AT instruction of A7670 is compatible with SIM7600
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialAT Serial1
#include
@@ -115,6 +115,8 @@
if (SerialAT.available()) {
String response = SerialAT.readString();
//Serial.println(response); // DEBUG of Modem AT message
+ int responseOKIndex = response.indexOf("OK");
+ int callsignIndex = ATMessage.indexOf(Config.callsign);
if(response.indexOf("verified") >= 0) {
Serial.println("Logged! (User Validated)\n");
displayShow(firstLine, "Connecting APRS-IS...", "---> Logged!", " ", 1000);
@@ -122,7 +124,7 @@
validAT = true;
i = 1;
delayATMessage = 0;
- } else if (ATMessage == "AT+NETOPEN" && response.indexOf("OK") >= 0) {
+ } else if (ATMessage == "AT+NETOPEN" && responseOKIndex >= 0) {
Serial.println("Port Open!");
displayShow(firstLine, "Opening Port...", "---> Port Open", " ", 0);
validAT = true;
@@ -145,14 +147,14 @@
validAT = true;
i = 1;
delayATMessage = 0;
- } else if (ATMessage.indexOf(Config.callsign) >= 3 && !modemLoggedToAPRSIS && response.indexOf("OK") >= 0 && !stationBeacon) { // login info
+ } else if (callsignIndex >= 3 && !modemLoggedToAPRSIS && responseOKIndex >= 0 && !stationBeacon) { // login info
validAT = true;
delayATMessage = 0;
- } else if (ATMessage.indexOf(Config.callsign) == 0 && !beaconSent && response.indexOf("OK") >= 0 && !stationBeacon) { // self beacon or querys
+ } else if (callsignIndex == 0 && !beaconSent && responseOKIndex >= 0 && !stationBeacon) { // self beacon or querys
validAT = true;
i = 1;
delayATMessage = 0;
- } else if (stationBeacon && response.indexOf("OK") >= 0) { //upload others beacons
+ } else if (stationBeacon && responseOKIndex >= 0) { //upload others beacons
validAT = true;
i = 1;
delayATMessage = 0;
@@ -200,7 +202,7 @@
if (beaconBytesSent) {
Serial.print(".");
beaconSent = checkATResponse(packet);
- }
+ }
if (!beaconSent) {
Serial.println("------------------------------------> UPLOAD FAILED!!!");
} else {
@@ -221,5 +223,5 @@
delay(1);
}
}
-
+
#endif
\ No newline at end of file
diff --git a/src/digi_utils.cpp b/src/digi_utils.cpp
index 5874e0d..944c7ff 100644
--- a/src/digi_utils.cpp
+++ b/src/digi_utils.cpp
@@ -99,39 +99,39 @@ namespace DIGI_Utils {
} else {
temp = packet.substring(packet.indexOf(">") + 1, packet.indexOf(":"));
}
- if (temp.indexOf(",") > 2) { // checks for path in temp
- const String& path = temp.substring(temp.indexOf(",") + 1); // extract path after tocall
- if (Config.digi.mode == 2 || backupDigiMode) {
- if (path.indexOf("WIDE1-1") != - 1) {
- return buildPacket(path, packet, thirdParty, false);
- } else if (path.indexOf("WIDE1-1") == -1 && (abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000)) { // CrossFreq Digi
- return buildPacket(path, packet, thirdParty, true);
- } else {
- return "";
- }
- } else if (Config.digi.mode == 3) {
- if (path.indexOf("WIDE1-1") != -1 || path.indexOf("WIDE2-") != -1) {
- int wide1Index = path.indexOf("WIDE1-1");
- int wide2Index = path.indexOf("WIDE2-");
+ int commaIndex = temp.indexOf(",");
+ int digiMode = Config.digi.mode;
+ bool crossFreq = abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000; // CrossFreq Digi
- // WIDE1-1 && WIDE2-n / only WIDE1-1 / only WIDE2-n
- if ((wide1Index != -1 && wide2Index != -1 && wide1Index < wide2Index) || (wide1Index != -1 && wide2Index == -1) || (wide1Index == -1 && wide2Index != -1)) {
- return buildPacket(path, packet, thirdParty, false);
- }
- return "";
- } else if (path.indexOf("WIDE1-1") == -1 && path.indexOf("WIDE2-") == -1 && (abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000)) { // CrossFreq Digi
- return buildPacket(path, packet, thirdParty, true);
- } else {
- return "";
+ if (commaIndex > 2) { // Packet has "path"
+ const String& path = temp.substring(commaIndex + 1);
+ if (digiMode == 2 || backupDigiMode) {
+ bool hasWide = path.indexOf("WIDE1-1") != -1;
+ if (hasWide || crossFreq) {
+ return buildPacket(path, packet, thirdParty, !hasWide);
}
- } else {
return "";
}
- } else if (temp.indexOf(",") == -1 && (Config.digi.mode == 2 || backupDigiMode || Config.digi.mode == 3) && (abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000)) {
- return buildPacket("", packet, thirdParty, true);
- } else {
+ if (digiMode == 3) {
+ int wide1Index = path.indexOf("WIDE1-1");
+ int wide2Index = path.indexOf("WIDE2-");
+ bool hasWide1 = wide1Index != -1;
+ bool hasWide2 = wide2Index != -1;
+
+ if (hasWide1 && hasWide2 && wide2Index < wide1Index) return ""; // check that WIDE1 before WIDE2
+
+ if (hasWide1 || hasWide2) return buildPacket(path, packet, thirdParty, false); // regular APRS with WIDEn-N
+
+ if (crossFreq) return buildPacket(path, packet, thirdParty, true); // CrossFreq (without WIDE)
+
+ return "";
+ }
return "";
}
+
+ if (commaIndex == -1 && (digiMode == 2 || backupDigiMode || digiMode == 3) && crossFreq) return buildPacket("", packet, thirdParty, true); // no "path" but is CrossFreq Digi
+
+ return "";
}
void processLoRaPacket(const String& packet) {
@@ -156,8 +156,9 @@ namespace DIGI_Utils {
STATION_Utils::updateLastHeard(Sender);
Utils::typeOfPacket(temp, 2); // Digi
bool queryMessage = false;
- if (temp.indexOf("::") > 10) { // it's a message
- String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
+ int doubleColonIndex = temp.indexOf("::");
+ if (doubleColonIndex > 10) { // it's a message
+ String AddresseeAndMessage = temp.substring(doubleColonIndex + 2);
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (Addressee == (Config.tacticalCallsign == "" ? Config.callsign : Config.tacticalCallsign)) { // it's a message for me!
@@ -173,7 +174,6 @@ namespace DIGI_Utils {
}
}
}
- //}
}
}
\ No newline at end of file
diff --git a/src/gps_utils.cpp b/src/gps_utils.cpp
index fc23cd9..6de8441 100644
--- a/src/gps_utils.cpp
+++ b/src/gps_utils.cpp
@@ -134,15 +134,17 @@ namespace GPS_Utils {
}
String Latitude = infoGPS.substring(0,8); // First 8 characters are Latitude
+ int latitudeColonIndex = Latitude.indexOf(".");
float convertedLatitude = Latitude.substring(0,2).toFloat(); // First 2 digits (Degrees)
convertedLatitude += Latitude.substring(2,4).toFloat() / 60; // Next 2 digits (Minutes)
- convertedLatitude += Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3).toFloat() / (60*100);
+ convertedLatitude += Latitude.substring(latitudeColonIndex + 1, latitudeColonIndex + 3).toFloat() / (60*100);
if (Latitude.endsWith("S")) convertedLatitude = -convertedLatitude; // Handle Southern Hemisphere
String Longitude = infoGPS.substring(9,18); // Next 9 characters are Longitude
+ int longitudeColonIndex = Longitude.indexOf(".");
float convertedLongitude = Longitude.substring(0,3).toFloat(); // First 3 digits (Degrees)
convertedLongitude += Longitude.substring(3,5).toFloat() / 60; // Next 2 digits (Minutes)
- convertedLongitude += Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3).toFloat() / (60*100);
+ convertedLongitude += Longitude.substring(longitudeColonIndex + 1, longitudeColonIndex + 3).toFloat() / (60*100);
if (Longitude.endsWith("W")) convertedLongitude = -convertedLongitude; // Handle Western Hemisphere
return buildDistanceAndComment(convertedLatitude, convertedLongitude, infoGPS.substring(19));
diff --git a/src/kiss_utils.cpp b/src/kiss_utils.cpp
index 091208d..45dde7e 100644
--- a/src/kiss_utils.cpp
+++ b/src/kiss_utils.cpp
@@ -1,17 +1,17 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
- *
+ *
* This file is part of LoRa APRS iGate.
- *
+ *
* LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see .
*/
@@ -29,17 +29,16 @@ bool validateKISSFrame(const String& kissFormattedFrame) {
}
String encodeAddressAX25(String tnc2Address) {
- bool hasBeenDigipited = tnc2Address.indexOf('*') != -1;
-
- if (tnc2Address.indexOf('-') == -1) {
+ bool hasBeenDigipited = tnc2Address.indexOf('*') != -1;
+ int tnc2AddressIndex = tnc2Address.indexOf('-');
+ if (tnc2AddressIndex == -1) {
if (hasBeenDigipited) {
tnc2Address = tnc2Address.substring(0, tnc2Address.length() - 1);
}
-
tnc2Address += "-0";
}
- int separatorIndex = tnc2Address.indexOf('-');
+ int separatorIndex = tnc2AddressIndex;
int ssid = tnc2Address.substring(separatorIndex + 1).toInt();
String kissAddress = "";
@@ -131,8 +130,9 @@ String encodeKISS(const String& frame) {
if (validateTNC2Frame(frame)) {
String address = "";
- bool dstAddresWritten = false;
- for (int p = 0; p <= frame.indexOf(':'); p++) {
+ bool dstAddresWritten = false;
+ int colonFrameIndex = frame.indexOf(':');
+ for (int p = 0; p <= colonFrameIndex; p++) {
char currentChar = frame.charAt(p);
if (currentChar == ':' || currentChar == '>' || currentChar == ',') {
if (!dstAddresWritten && (currentChar == ',' || currentChar == ':')) {
@@ -151,7 +151,7 @@ String encodeKISS(const String& frame) {
ax25Frame.setCharAt(ax25Frame.length() - 1, (char)(lastAddressChar | IS_LAST_ADDRESS_POSITION_MASK));
ax25Frame += (char)APRS_CONTROL_FIELD;
ax25Frame += (char)APRS_INFORMATION_FIELD;
- ax25Frame += frame.substring(frame.indexOf(':') + 1);
+ ax25Frame += frame.substring(colonFrameIndex + 1);
}
String kissFrame = encapsulateKISS(ax25Frame, CMD_DATA);
diff --git a/src/query_utils.cpp b/src/query_utils.cpp
index d7bb053..aee6710 100644
--- a/src/query_utils.cpp
+++ b/src/query_utils.cpp
@@ -77,10 +77,14 @@ namespace QUERY_Utils {
answer.concat("?WHERE on development 73!");
} */
else if (STATION_Utils::isManager(station) && (!queryFromAPRSIS || !Config.remoteManagement.rfOnly)) {
- if (queryQuestion.indexOf("?EM=OFF") == 0) {
- if ((Config.digi.mode == 2 || Config.digi.mode == 3) && Config.loramodule.txActive && Config.loramodule.rxActive && !Config.aprs_is.active) {
- if (Config.digi.ecoMode == 1 || Config.digi.ecoMode == 2) { // Exit Digipeater EcoMode or Digipeater without WiFiAP
- answer = (Config.digi.ecoMode == 1) ? "DigiEcoMode:OFF" : "Digipeater + WiFiAP enabled";
+ int digiMode = Config.digi.mode;
+ int digiEcoMode = Config.digi.ecoMode;
+ int radioTxActive = Config.loramodule.txActive;
+ bool onlyRadioActive = radioTxActive && Config.loramodule.rxActive && !Config.aprs_is.active;
+ if (queryQuestion.startsWith("?EM=OFF")) {
+ if ((digiMode == 2 || digiMode == 3) && onlyRadioActive) {
+ if (digiEcoMode == 1 || digiEcoMode == 2) { // Exit Digipeater EcoMode or Digipeater without WiFiAP
+ answer = (digiEcoMode == 1) ? "DigiEcoMode:OFF" : "Digipeater + WiFiAP enabled";
Config.digi.ecoMode = 0;
Config.display.alwaysOn = true;
Config.display.timeout = 10;
@@ -92,9 +96,9 @@ namespace QUERY_Utils {
} else {
answer = "Digipeater Mode control not possible";
}
- } else if (queryQuestion.indexOf("?EM=ON") == 0) {
- if ((Config.digi.mode == 2 || Config.digi.mode == 3) && Config.loramodule.txActive && Config.loramodule.rxActive && !Config.aprs_is.active) {
- if (Config.digi.ecoMode == 0) { // Start Digipeater EcoMode
+ } else if (queryQuestion.startsWith("?EM=ON")) {
+ if ((digiMode == 2 || digiMode == 3) && onlyRadioActive) {
+ if (digiEcoMode == 0) { // Start Digipeater EcoMode
answer = "DigiEcoMode:ON";
Config.digi.ecoMode = 1;
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sent before restart.
@@ -105,31 +109,29 @@ namespace QUERY_Utils {
} else {
answer = "Digipeater Mode control not possible";
}
- } else if (queryQuestion.indexOf("?EM=?") == 0) { // Digipeater EcoMode Status
- if (Config.digi.ecoMode == 0) {
- answer = "DigiEcoMode:OFF";
- } else if (Config.digi.ecoMode == 1) {
- answer = "DigiEcoMode:ON";
- } else {
- answer = "DigiEcoMode:OFF/Only Serial Output";
+ } else if (queryQuestion.startsWith("?EM=?")) { // Digipeater EcoMode Status
+ switch (digiEcoMode) {
+ case 0: answer = "DigiEcoMode:OFF"; break;
+ case 1: answer = "DigiEcoMode:ON"; break;
+ default: answer = "DigiEcoMode:OFF/Only Serial Output";
}
- } else if (queryQuestion.indexOf("?TX=ON") == 0) {
- if (Config.loramodule.txActive) {
+ } else if (queryQuestion.startsWith("?TX=ON")) {
+ if (radioTxActive) {
answer = "TX was ON";
} else {
Config.loramodule.txActive = true;
answer = "TX=ON";
}
- } else if (queryQuestion.indexOf("?TX=OFF") == 0) {
- if (!Config.loramodule.txActive) {
+ } else if (queryQuestion.startsWith("?TX=OFF")) {
+ if (!radioTxActive) {
answer = "TX was OFF";
} else {
Config.loramodule.txActive = false;
answer = "TX=OFF";
}
- } else if (queryQuestion.indexOf("?TX=?") == 0) {
- answer = (Config.loramodule.txActive) ? "TX=ON" : "TX=OFF";
- } else if (queryQuestion.indexOf("?COMMIT") == 0) { // saving for next reboot
+ } else if (queryQuestion.startsWith("?TX=?")) {
+ answer = (radioTxActive) ? "TX=ON" : "TX=OFF";
+ } else if (queryQuestion.startsWith("?COMMIT")) { // saving for next reboot
answer = "New Config Saved";
Config.writeFile();
}
diff --git a/src/syslog_utils.cpp b/src/syslog_utils.cpp
index 3adda85..95d9d52 100644
--- a/src/syslog_utils.cpp
+++ b/src/syslog_utils.cpp
@@ -1,17 +1,17 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
- *
+ *
* This file is part of LoRa APRS iGate.
- *
+ *
* LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see .
*/
@@ -43,9 +43,11 @@ namespace SYSLOG_Utils {
char signalData[35];
snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
- int colonIndex = packet.indexOf(":");
- char nextChar = packet[colonIndex + 1];
- String sender = packet.substring(3, packet.indexOf(">"));
+ int colonIndex = packet.indexOf(":");
+ char nextChar = packet[colonIndex + 1];
+ int greaterThanIndex = packet.indexOf(">");
+ int telemetryPacketIndex = packet.indexOf(":T#");
+ String sender = packet.substring(3, greaterThanIndex);
switch (type) {
case 0: // CRC
@@ -58,13 +60,12 @@ namespace SYSLOG_Utils {
if (nextChar == ':') {
syslogPacket.concat("MESSAGE / ");
syslogPacket.concat(sender);
- syslogPacket.concat(" ---> ");
+ syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(colonIndex + 2));
} else if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
syslogPacket.concat("GPS / ");
syslogPacket.concat(sender);
syslogPacket.concat(" / ");
- int greaterThanIndex = packet.indexOf(">");
if (packet.indexOf("WIDE1-1") > 10) {
syslogPacket.concat(packet.substring(greaterThanIndex + 1, packet.indexOf(",")));
syslogPacket.concat(" / WIDE1-1");
@@ -87,11 +88,11 @@ namespace SYSLOG_Utils {
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(colonIndex + 2));
- } else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
+ } else if (telemetryPacketIndex >= 10 && packet.indexOf(":=/") == -1) {
syslogPacket.concat("TELEMETRY / ");
syslogPacket.concat(sender);
syslogPacket.concat(" ---> ");
- syslogPacket.concat(packet.substring(packet.indexOf(":T#") + 3));
+ syslogPacket.concat(packet.substring(telemetryPacketIndex + 3));
} else {
syslogPacket.concat(packet);
}
diff --git a/src/utils.cpp b/src/utils.cpp
index b856190..58a91f0 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -312,7 +312,6 @@ namespace Utils {
}
void typeOfPacket(const String& packet, const uint8_t packetType) {
- String sender = packet.substring(0,packet.indexOf(">"));
switch (packetType) {
case 0: // LoRa-APRS
fifthLine = "LoRa Rx ----> APRS-IS";
@@ -328,6 +327,7 @@ namespace Utils {
int firstColonIndex = packet.indexOf(":");
char nextChar = packet[firstColonIndex + 1];
+ String sender = packet.substring(0,packet.indexOf(">"));
for (int i = sender.length(); i < 9; i++) {
sender += " ";
}
@@ -419,9 +419,10 @@ namespace Utils {
if (callsign == "WLNK-1") return true;
String cleanCallsign;
- if (callsign.indexOf("-") > 0) { // SSID Validation
- cleanCallsign = callsign.substring(0, callsign.indexOf("-"));
- String ssid = callsign.substring(callsign.indexOf("-") + 1);
+ int hypenCallsignIndex = callsign.indexOf("-");
+ if (hypenCallsignIndex > 0) { // SSID Validation
+ cleanCallsign = callsign.substring(0, hypenCallsignIndex);
+ String ssid = callsign.substring(hypenCallsignIndex + 1);
if (ssid.indexOf("-") != -1 || ssid.length() > 2) return false;
if (ssid.length() == 2 && ssid[0] == '0') return false;
for (int i = 0; i < ssid.length(); i++) {