mirror of
https://github.com/richonguzman/LoRa_APRS_iGate.git
synced 2026-10-31 02:51:58 +01:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3618558b21 | ||
|
|
e1eda2e64a | ||
|
|
759cddd0e5 | ||
|
|
8186ff4fbd | ||
|
|
3720fe9881 |
No files matched your search
+1
-1
@@ -38,7 +38,7 @@ lib_deps =
|
||||
ESP32Async/AsyncTCP @ 3.4.10
|
||||
ESP32Async/ESPAsyncWebServer @ 3.11.1
|
||||
mikalhart/TinyGPSPlus @ 1.0.3
|
||||
richonguzman/APRSPacketLib @ 1.0.4
|
||||
richonguzman/APRSPacketLib @ 1.0.6
|
||||
display_libs =
|
||||
adafruit/Adafruit GFX Library @ 1.12.6
|
||||
adafruit/Adafruit SSD1306 @ 2.5.17
|
||||
|
||||
@@ -28,10 +28,9 @@ namespace APRS_IS_Utils {
|
||||
void connect();
|
||||
|
||||
void checkStatus();
|
||||
String checkForStartingBytes(const String& packet);
|
||||
|
||||
String buildPacketToUpload(const String& packet);
|
||||
bool processReceivedLoRaMessage(const String& sender, const String& packet, bool thirdParty);
|
||||
bool processReceivedLoRaMessage(const String& sender, const String& packet);
|
||||
void processLoRaPacket(const String& packet);
|
||||
|
||||
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType);
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
|
||||
namespace DIGI_Utils {
|
||||
|
||||
String buildPacket(const String& path, const String& packet, bool thirdParty, bool crossFreq);
|
||||
String generateDigipeatedPacket(const String& packet, bool thirdParty);
|
||||
String buildPacket(const String& path, const String& packet, bool crossFreq);
|
||||
String generateDigipeatedPacket(const String& packet);
|
||||
void processLoRaPacket(const String& packet);
|
||||
void checkEcoMode();
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1
-6
@@ -25,13 +25,8 @@
|
||||
namespace GPS_Utils {
|
||||
|
||||
String getiGateLoRaBeaconPacket();
|
||||
char *ax25_base91enc(char *s, uint8_t n, uint32_t v);
|
||||
String encodeGPS(float latitude, float longitude, const String& overlay, const String& symbol);
|
||||
void generateBeaconFirstPart();
|
||||
void generateBeacons();
|
||||
String decodeEncodedGPS(const String& packet);
|
||||
String getReceivedGPS(const String& packet);
|
||||
String getDistanceAndComment(const String& packet);
|
||||
String buildDistanceAndComment(float latitude, float longitude, const String& comment);
|
||||
|
||||
void setup();
|
||||
void getData();
|
||||
|
||||
@@ -84,7 +84,6 @@ public:
|
||||
// Ethernet methods
|
||||
bool ethernetConnect(eth_phy_type_t type, uint8_t phy_addr, uint8_t mdc, uint8_t mdio, int power, eth_clock_mode_t clock_mode, bool use_mac_from_efuse = false);
|
||||
bool setEthernetIP(const String& staticIP, const String& gateway, const String& subnet, const String& dns1, const String& dns2);
|
||||
bool ethernetDisconnect();
|
||||
IPAddress getEthernetIP() const;
|
||||
String getEthernetMACAddress() const;
|
||||
|
||||
|
||||
@@ -19,12 +19,16 @@
|
||||
#ifndef SYSLOG_H_
|
||||
#define SYSLOG_H_
|
||||
|
||||
#include <APRSPacketLib.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
namespace SYSLOG_Utils {
|
||||
|
||||
void log(const uint8_t type ,const String& packet, const int rssi, const float snr, const int freqError);
|
||||
void logLoRaRx(APRSPacket& aprsPacket, const String& packet, const int rssi, const float snr, const int freqError);
|
||||
void logAPRSISTx(const String& packet);
|
||||
void logLoRaTx(const String& packet);
|
||||
void logCRCError(const String& packet, const int rssi, const float snr, const int freqError);
|
||||
void setup();
|
||||
|
||||
}
|
||||
|
||||
+3
-2
@@ -19,9 +19,9 @@
|
||||
#ifndef UTILS_H_
|
||||
#define UTILS_H_
|
||||
|
||||
#include <APRSPacketLib.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
class ReceivedPacket {
|
||||
public:
|
||||
String rxTime;
|
||||
@@ -39,7 +39,8 @@ namespace Utils {
|
||||
void checkBeaconInterval();
|
||||
void checkDisplayInterval();
|
||||
void validateFreqs();
|
||||
void typeOfPacket(const String& packet, const uint8_t packetType);
|
||||
void updateLoRaPacketDisplayInfo(APRSPacket& aprsPacket, const uint8_t packetType);
|
||||
void updateAPRSISPacketDisplayInfo(const String& packet);
|
||||
void print(const String& text);
|
||||
void println(const String& text);
|
||||
void checkRebootMode();
|
||||
|
||||
@@ -68,7 +68,7 @@ ___________________________________________________________________*/
|
||||
#endif
|
||||
|
||||
|
||||
String versionDate = "2026-09-15";
|
||||
String versionDate = "2026-09-23";
|
||||
String versionNumber = "4.0.1";
|
||||
Configuration Config;
|
||||
WiFiClient aprsIsClient;
|
||||
|
||||
+23
-34
@@ -33,6 +33,7 @@
|
||||
|
||||
|
||||
extern Configuration Config;
|
||||
extern APRSPacket lastAprsPacket;
|
||||
extern NetworkManager *networkManager;
|
||||
extern WiFiClient aprsIsClient;
|
||||
extern uint32_t lastScreenOn;
|
||||
@@ -135,11 +136,6 @@ namespace APRS_IS_Utils {
|
||||
secondLine += aprsisState;
|
||||
}
|
||||
|
||||
String checkForStartingBytes(const String& packet) {
|
||||
int index = packet.indexOf("\x3c\xff\x01");
|
||||
return (index != -1) ? packet.substring(0, index) : packet;
|
||||
}
|
||||
|
||||
String buildPacketToUpload(const String& packet) {
|
||||
int colonIndex = packet.indexOf(":");
|
||||
String packetToUpload = packet.substring(3, colonIndex);
|
||||
@@ -149,11 +145,11 @@ namespace APRS_IS_Utils {
|
||||
packetToUpload += ",qAO,";
|
||||
}
|
||||
packetToUpload += Config.callsign;
|
||||
packetToUpload += checkForStartingBytes(packet.substring(colonIndex));
|
||||
packetToUpload += APRSPacketLib::checkForStartingBytes(packet.substring(colonIndex));
|
||||
return packetToUpload;
|
||||
}
|
||||
|
||||
bool processReceivedLoRaMessage(const String& sender, const String& packet, bool thirdParty) {
|
||||
bool processReceivedLoRaMessage(const String& sender, const String& packet) {
|
||||
String receivedMessage;
|
||||
int leftCurlyBraceIndex = packet.indexOf("{");
|
||||
int colonIndex = packet.indexOf(":");
|
||||
@@ -165,7 +161,7 @@ namespace APRS_IS_Utils {
|
||||
|
||||
String addToBuffer = Config.callsign;
|
||||
addToBuffer += ">APLRG1";
|
||||
if (!thirdParty) addToBuffer += ",RFONLY";
|
||||
if (lastAprsPacket.header == "") addToBuffer += ",RFONLY";
|
||||
if (Config.beacon.path != "") {
|
||||
addToBuffer += ",";
|
||||
addToBuffer += Config.beacon.path;
|
||||
@@ -186,51 +182,44 @@ namespace APRS_IS_Utils {
|
||||
receivedMessage = packet.substring(colonIndex + 1);
|
||||
}
|
||||
if (receivedMessage.indexOf("?") == 0) {
|
||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
||||
displayToggle(true);
|
||||
}
|
||||
STATION_Utils::addToOutputPacketBuffer(QUERY_Utils::process(receivedMessage, sender, false, thirdParty));
|
||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true);
|
||||
|
||||
STATION_Utils::addToOutputPacketBuffer(QUERY_Utils::process(receivedMessage, sender, false, lastAprsPacket.header != ""));
|
||||
lastScreenOn = millis();
|
||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + sender, "TYPE --> QUERY", 0);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void processLoRaPacket(const String& packet) {
|
||||
if (passcodeValid && (aprsIsClient.connected() || modemLoggedToAPRSIS)) {
|
||||
if (packet.indexOf("NOGATE") == -1 && packet.indexOf("RFONLY") == -1) {
|
||||
int firstColonIndex = packet.indexOf(":");
|
||||
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
|
||||
const String& Sender = packet.substring(3, packet.indexOf(">"));
|
||||
if (Sender != Config.callsign && Utils::callsignIsValid(Sender)) {
|
||||
STATION_Utils::updateLastHeard(Sender);
|
||||
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
|
||||
int doubleColonIndex = packet.indexOf("::");
|
||||
const String& AddresseeAndMessage = packet.substring(doubleColonIndex + 2);
|
||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||
Addressee.trim();
|
||||
if (lastAprsPacket.path.indexOf("NOGATE") == -1 && lastAprsPacket.path.indexOf("RFONLY") == -1) {
|
||||
if (lastAprsPacket.header == "" && lastAprsPacket.path.indexOf("TCPIP") == -1) {
|
||||
if (lastAprsPacket.sender != Config.callsign && Utils::callsignIsValid(lastAprsPacket.sender)) {
|
||||
STATION_Utils::updateLastHeard(lastAprsPacket.sender);
|
||||
Utils::updateLoRaPacketDisplayInfo(lastAprsPacket, 0); // LoRa-APRS
|
||||
bool queryMessage = false;
|
||||
if (doubleColonIndex > 10 && Addressee == Config.callsign) { // its a message for me!
|
||||
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
|
||||
if (lastAprsPacket.type == 1 && lastAprsPacket.addressee == Config.callsign) { // its a message for me!
|
||||
String AddresseeAndMessage = lastAprsPacket.addressee + ":" + lastAprsPacket.payload;
|
||||
queryMessage = processReceivedLoRaMessage(lastAprsPacket.sender, APRSPacketLib::checkForStartingBytes(AddresseeAndMessage));
|
||||
}
|
||||
if (queryMessage) return;
|
||||
|
||||
const String& aprsPacket = buildPacketToUpload(packet);
|
||||
const String& aprsPacketToUpload = buildPacketToUpload(packet);
|
||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
||||
displayToggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
#ifdef HAS_A7670
|
||||
stationBeacon = true;
|
||||
A7670_Utils::uploadToAPRSIS(aprsPacket);
|
||||
A7670_Utils::uploadToAPRSIS(aprsPacketToUpload);
|
||||
stationBeacon = false;
|
||||
#else
|
||||
upload(aprsPacket);
|
||||
upload(aprsPacketToUpload);
|
||||
#endif
|
||||
Utils::println("---> Uploaded to APRS-IS");
|
||||
Utils::println("(Uploaded to APRS-IS)");
|
||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
}
|
||||
}
|
||||
@@ -351,7 +340,7 @@ namespace APRS_IS_Utils {
|
||||
#else
|
||||
upload(queryAnswer);
|
||||
#endif
|
||||
SYSLOG_Utils::log(2, queryAnswer, 0, 0.0, 0); // APRSIS TX
|
||||
SYSLOG_Utils::logAPRSISTx(queryAnswer);
|
||||
fifthLine = "APRS-IS ----> APRS-IS";
|
||||
sixthLine = Config.callsign;
|
||||
for (int j = sixthLine.length();j < 9;j++) {
|
||||
@@ -369,7 +358,7 @@ namespace APRS_IS_Utils {
|
||||
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
|
||||
displayToggle(true);
|
||||
lastScreenOn = currentTime;
|
||||
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
||||
Utils::updateAPRSISPacketDisplayInfo(packet); // APRS-LoRa
|
||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
}
|
||||
}
|
||||
@@ -379,7 +368,7 @@ namespace APRS_IS_Utils {
|
||||
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
|
||||
displayToggle(true);
|
||||
lastScreenOn = currentTime;
|
||||
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
||||
Utils::updateAPRSISPacketDisplayInfo(packet); // APRS-LoRa
|
||||
Serial.println();
|
||||
} else {
|
||||
Serial.println(" ---> Rejected (Time): No Tx");
|
||||
|
||||
+56
-47
@@ -16,6 +16,7 @@
|
||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <APRSPacketLib.h>
|
||||
#include <WiFi.h>
|
||||
#include "configuration.h"
|
||||
#include "station_utils.h"
|
||||
@@ -29,6 +30,7 @@
|
||||
|
||||
extern Configuration Config;
|
||||
extern uint32_t lastScreenOn;
|
||||
extern APRSPacket lastAprsPacket;
|
||||
extern String iGateBeaconPacket;
|
||||
extern String firstLine;
|
||||
extern String secondLine;
|
||||
@@ -42,13 +44,32 @@ extern bool backupDigiMode;
|
||||
|
||||
namespace DIGI_Utils {
|
||||
|
||||
String cleanPath(String path) {
|
||||
String terms[] = {"WIDE1*,", "WIDE2*,", "*"};
|
||||
for (String term : terms) {
|
||||
int index = path.indexOf(term);
|
||||
if (index != -1) path.remove(index, term.length()); // less memory than: tempPath.replace("*", "");
|
||||
String cleanPath(const String& path) {
|
||||
String result;
|
||||
unsigned int start = 0;
|
||||
while (true) {
|
||||
int delim = path.indexOf(',', start);
|
||||
int end = (delim == -1) ? path.length() : delim;
|
||||
String token = path.substring(start, end);
|
||||
if (token != "WIDE1*" && token != "WIDE2*") {
|
||||
if (result.length() > 0) result += ",";
|
||||
result += token;
|
||||
}
|
||||
if (delim == -1) break;
|
||||
start = delim + 1;
|
||||
}
|
||||
return path;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int pathTokenIndex(const String& path, const String& token) {
|
||||
unsigned int start = 0;
|
||||
while (start < path.length()) {
|
||||
int end = path.indexOf(",", start);
|
||||
if (end == -1) end = path.length();
|
||||
if (path.substring(start, end) == token) return start;
|
||||
start = end + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
String processMode3Path(const String& path, const String& stationCallsign) {
|
||||
@@ -80,9 +101,9 @@ namespace DIGI_Utils {
|
||||
return tempPacket + "*" + path.substring(ownTokenEnd);
|
||||
}
|
||||
|
||||
String buildPacket(const String& path, const String& packet, bool thirdParty, bool crossFreq) {
|
||||
String buildPacket(const String& path, const String& packet, bool crossFreq) {
|
||||
String stationCallsign = (Config.tacticalCallsign == "" ? Config.callsign : Config.tacticalCallsign);
|
||||
String suffix = thirdParty ? ":}" : ":";
|
||||
String suffix = (lastAprsPacket.header != "") ? ":}" : ":";
|
||||
int suffixIndex = packet.indexOf(suffix);
|
||||
String packetToRepeat;
|
||||
if (!crossFreq) {
|
||||
@@ -94,12 +115,13 @@ namespace DIGI_Utils {
|
||||
tempPath.replace("WIDE1-1", stationCallsign + "*");
|
||||
} else if (tempPath.indexOf("WIDE2-") != -1 && digiMode == 2) { // WIDE2-n Digipeater
|
||||
tempPath = cleanPath(path);
|
||||
if (tempPath.indexOf("WIDE2-1") != -1) {
|
||||
tempPath.replace("WIDE2-1", stationCallsign + "*");
|
||||
} else if (tempPath.indexOf("WIDE2-2") != -1) {
|
||||
tempPath.replace("WIDE2-2", stationCallsign + "*,WIDE2-1");
|
||||
int idx = pathTokenIndex(tempPath, "WIDE2-1");
|
||||
if (idx != -1) {
|
||||
tempPath = tempPath.substring(0, idx) + stationCallsign + "*" + tempPath.substring(idx + 7);
|
||||
} else {
|
||||
return "";
|
||||
idx = pathTokenIndex(tempPath, "WIDE2-2");
|
||||
if (idx == -1) return "";
|
||||
tempPath = tempPath.substring(0, idx) + stationCallsign + "*,WIDE2-1" + tempPath.substring(idx + 7);
|
||||
}
|
||||
} else if (digiMode == 3) { // Repeat if station callsign is in path (free to repeat).
|
||||
tempPath = processMode3Path(tempPath, stationCallsign);
|
||||
@@ -114,13 +136,13 @@ namespace DIGI_Utils {
|
||||
packetToRepeat += stationCallsign;
|
||||
packetToRepeat += "*";
|
||||
}
|
||||
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(suffixIndex));
|
||||
packetToRepeat += APRSPacketLib::checkForStartingBytes(packet.substring(suffixIndex));
|
||||
return packetToRepeat;
|
||||
}
|
||||
|
||||
String generateDigipeatedPacket(const String& packet, bool thirdParty){
|
||||
String generateDigipeatedPacket(const String& packet){
|
||||
String temp;
|
||||
if (thirdParty) { // only header is used
|
||||
if (lastAprsPacket.header != "") { // thirdparty : only header is used
|
||||
const String& header = packet.substring(0, packet.indexOf(":}"));
|
||||
temp = header.substring(header.indexOf(">") + 1);
|
||||
} else {
|
||||
@@ -135,7 +157,7 @@ namespace DIGI_Utils {
|
||||
if (digiMode == 1 || backupDigiMode) {
|
||||
bool hasWide = path.indexOf("WIDE1-1") != -1;
|
||||
if (hasWide || crossFreq) {
|
||||
return buildPacket(path, packet, thirdParty, !hasWide);
|
||||
return buildPacket(path, packet, !hasWide);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -147,62 +169,49 @@ namespace DIGI_Utils {
|
||||
|
||||
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 (hasWide1 || hasWide2) return buildPacket(path, packet, false); // regular APRS with WIDEn-N
|
||||
|
||||
if (crossFreq) return buildPacket(path, packet, thirdParty, true); // CrossFreq (without WIDE)
|
||||
if (crossFreq) return buildPacket(path, packet, true); // CrossFreq (without WIDE)
|
||||
|
||||
return "";
|
||||
}
|
||||
if (digiMode == 3) {
|
||||
String stationCallsign = (Config.tacticalCallsign == "" ? Config.callsign : Config.tacticalCallsign);
|
||||
bool containsOwnCall = path.indexOf(stationCallsign) != -1;
|
||||
if (containsOwnCall) return buildPacket(path, packet, thirdParty, false);
|
||||
if (containsOwnCall) return buildPacket(path, packet, false);
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
if (commaIndex == -1 && (digiMode == 1 || backupDigiMode || digiMode == 2) && crossFreq) return buildPacket("", packet, thirdParty, true); // no "path" but is CrossFreq Digi
|
||||
if (commaIndex == -1 && (digiMode == 1 || backupDigiMode || digiMode == 2) && crossFreq) return buildPacket("", packet, true); // no "path" but is CrossFreq Digi
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void processLoRaPacket(const String& packet) {
|
||||
if (packet.indexOf("NOGATE") >= 0) return;
|
||||
if (lastAprsPacket.path.indexOf("NOGATE") >= 0) return;
|
||||
|
||||
bool thirdPartyPacket = false;
|
||||
String temp, Sender;
|
||||
int firstColonIndex = packet.indexOf(":");
|
||||
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party
|
||||
thirdPartyPacket = true;
|
||||
temp = packet.substring(packet.indexOf(":}") + 2);
|
||||
Sender = temp.substring(0, temp.indexOf(">"));
|
||||
} else {
|
||||
temp = packet.substring(3);
|
||||
Sender = packet.substring(3, packet.indexOf(">"));
|
||||
}
|
||||
String temp = (lastAprsPacket.header != "") ? packet.substring(packet.indexOf(":}") + 2) : packet.substring(3);
|
||||
|
||||
String stationCallsign = Config.tacticalCallsign == "" ? Config.callsign : Config.tacticalCallsign;
|
||||
if (Sender == stationCallsign) return; // Avoid listening to self packets
|
||||
if (!thirdPartyPacket && Config.tacticalCallsign == "" && !Utils::callsignIsValid(Sender)) return; // No thirdParty + no tactical y no valid callsign
|
||||
if (lastAprsPacket.sender == stationCallsign) return; // Avoid listening to self packets
|
||||
if (lastAprsPacket.header == "" && Config.tacticalCallsign == "" && !Utils::callsignIsValid(lastAprsPacket.sender)) return; // No thirdParty + no tactical y no valid callsign
|
||||
|
||||
if (STATION_Utils::isIn25SegHashBuffer(Sender, temp.substring(temp.indexOf(":") + 2))) return;
|
||||
if (STATION_Utils::isIn25SegHashBuffer(lastAprsPacket.sender, temp.substring(temp.indexOf(":") + 2))) return;
|
||||
|
||||
STATION_Utils::updateLastHeard(Sender);
|
||||
Utils::typeOfPacket(temp, 2); // Digi
|
||||
bool queryMessage = false;
|
||||
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 == stationCallsign) { // it's a message for me!
|
||||
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
|
||||
STATION_Utils::updateLastHeard(lastAprsPacket.sender);
|
||||
Utils::updateLoRaPacketDisplayInfo(lastAprsPacket, 1); // Digi
|
||||
bool queryMessage = false;
|
||||
if (lastAprsPacket.type == 1) { // MESSAGE
|
||||
if (lastAprsPacket.addressee == stationCallsign) { // it's a message for me!
|
||||
String AddresseeAndMessage = lastAprsPacket.addressee + ":" + lastAprsPacket.payload;
|
||||
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(lastAprsPacket.sender, APRSPacketLib::checkForStartingBytes(AddresseeAndMessage));
|
||||
}
|
||||
}
|
||||
if (queryMessage) return; // answer should not be repeated.
|
||||
|
||||
String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket);
|
||||
String loraPacket = generateDigipeatedPacket(packet.substring(3));
|
||||
if (loraPacket != "") {
|
||||
STATION_Utils::addToOutputPacketBuffer(loraPacket);
|
||||
if (Config.digi.ecoMode != 1) displayToggle(true);
|
||||
|
||||
@@ -101,100 +101,6 @@ namespace GPS_Utils {
|
||||
|
||||
}
|
||||
|
||||
String decodeEncodedGPS(const String& packet) {
|
||||
int indexOfExclamation = packet.indexOf(":!");
|
||||
int indexOfEqual = packet.indexOf(":=");
|
||||
|
||||
const uint8_t OFFSET = 3; // Offset for encoded data in the packet
|
||||
String infoGPS;
|
||||
if (indexOfExclamation > 10) {
|
||||
infoGPS = packet.substring(indexOfExclamation + OFFSET);
|
||||
} else if (indexOfEqual > 10) {
|
||||
infoGPS = packet.substring(indexOfEqual + OFFSET);
|
||||
}
|
||||
|
||||
float decodedLatitude = APRSPacketLib::decodeBase91EncodedLatitude(infoGPS.substring(0,4));
|
||||
float decodedLongitude = APRSPacketLib::decodeBase91EncodedLongitude(infoGPS.substring(4,8));
|
||||
|
||||
return buildDistanceAndComment(decodedLatitude, decodedLongitude, infoGPS.substring(12));
|
||||
}
|
||||
|
||||
String getReceivedGPS(const String& packet) {
|
||||
int indexOfExclamation = packet.indexOf(":!");
|
||||
int indexOfEqual = packet.indexOf(":=");
|
||||
int indexOfAt = packet.indexOf(":@");
|
||||
|
||||
String infoGPS;
|
||||
if (indexOfExclamation > 10) {
|
||||
infoGPS = packet.substring(indexOfExclamation + 2);
|
||||
} else if (indexOfEqual > 10) {
|
||||
infoGPS = packet.substring(indexOfEqual + 2);
|
||||
} else if (indexOfAt > 10) {
|
||||
infoGPS = packet.substring(indexOfAt + 9); // 9 = 2+7 (when 7 is timestamp characters)
|
||||
}
|
||||
|
||||
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(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(longitudeColonIndex + 1, longitudeColonIndex + 3).toFloat() / (60*100);
|
||||
if (Longitude.endsWith("W")) convertedLongitude = -convertedLongitude; // Handle Western Hemisphere
|
||||
|
||||
return buildDistanceAndComment(convertedLatitude, convertedLongitude, infoGPS.substring(19));
|
||||
}
|
||||
|
||||
String getDistanceAndComment(const String& packet) {
|
||||
int indexOfAt = packet.indexOf(":@");
|
||||
if (indexOfAt > 10) return getReceivedGPS(packet);
|
||||
|
||||
const uint8_t nonEncondedLatitudeOffset = 9; // "N" / "S"
|
||||
const uint8_t nonEncondedLongitudeOffset = 19; // "E" / "W"
|
||||
const uint8_t encodedByteOffset = 14;
|
||||
|
||||
int indexOfExclamation = packet.indexOf(":!");
|
||||
int indexOfEqual = packet.indexOf(":=");
|
||||
int baseIndex = - 1;
|
||||
if (indexOfExclamation > 10) {
|
||||
baseIndex = indexOfExclamation;
|
||||
} else if (indexOfEqual > 10) {
|
||||
baseIndex = indexOfEqual;
|
||||
}
|
||||
if (baseIndex == -1) return " _ / _ / _ ";
|
||||
|
||||
int latitudeIndex = baseIndex + nonEncondedLatitudeOffset;
|
||||
int longitudeIndex = baseIndex + nonEncondedLongitudeOffset;
|
||||
int encodedByteIndex = baseIndex + encodedByteOffset;
|
||||
int packetLength = packet.length();
|
||||
|
||||
if (latitudeIndex < packetLength && longitudeIndex < packetLength) {
|
||||
char latChar = packet[latitudeIndex];
|
||||
char lngChar = packet[longitudeIndex];
|
||||
if ((latChar == 'N' || latChar == 'S') && (lngChar == 'E' || lngChar == 'W')) return getReceivedGPS(packet);
|
||||
}
|
||||
if (encodedByteIndex < packetLength) {
|
||||
char byteChar = packet[encodedByteIndex];
|
||||
if (byteChar == 'G' || byteChar == 'Q' || byteChar == '[' || byteChar == 'H' || byteChar == 'X' || byteChar == '3') return decodeEncodedGPS(packet);
|
||||
}
|
||||
return " _ / _ / _ ";
|
||||
}
|
||||
|
||||
/*String getDistanceAndCommentFromMicE(const String& packet) {
|
||||
int indexOfMicE1 = packet.indexOf(":`");
|
||||
int indexOfMicE2 = packet.indexOf(":\'");
|
||||
|
||||
if (indexOfMicE1 > 10 || indexOfMicE2 > 10) {
|
||||
return decodeEncodedGPS(packet);
|
||||
}
|
||||
return " _ / _ / _ ";
|
||||
}*/
|
||||
|
||||
void setup() {
|
||||
#ifdef HAS_GPS
|
||||
if (Config.beacon.gpsActive && Config.digi.ecoMode != 1) {
|
||||
|
||||
+8
-8
@@ -65,6 +65,7 @@ int backoffMax = 4; // Max Backoff value (number of CAD slots to wai
|
||||
|
||||
int rssi, freqError;
|
||||
float snr;
|
||||
APRSPacket lastAprsPacket;
|
||||
|
||||
|
||||
namespace LoRa_Utils {
|
||||
@@ -230,7 +231,7 @@ namespace LoRa_Utils {
|
||||
transmitFlag = true;
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
if (Config.syslog.active && networkManager->isConnected()) {
|
||||
SYSLOG_Utils::log(3, newPacket, 0, 0.0, 0); // TX
|
||||
SYSLOG_Utils::logLoRaTx(newPacket);
|
||||
}
|
||||
Utils::print("---> LoRa Packet Tx : ");
|
||||
Utils::println(newPacket);
|
||||
@@ -276,9 +277,9 @@ namespace LoRa_Utils {
|
||||
rssi = radio.getRSSI();
|
||||
snr = radio.getSNR();
|
||||
freqError = radio.getFrequencyError();
|
||||
Utils::println("<--- LoRa Packet Rx : " + packet.substring(3));
|
||||
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
|
||||
Utils::println("<--- LoRa Packet Rx (RSSI:" + String(rssi) + " | SNR:" + String(snr) + " | FreqErr:" + String(freqError) + ") : " + packet.substring(3));
|
||||
|
||||
lastAprsPacket = APRSPacketLib::processReceivedPacket(packet.substring(3), rssi, snr, freqError);
|
||||
if (Config.digi.ecoMode == 0) {
|
||||
if (receivedPackets.size() >= 10) {
|
||||
receivedPackets.erase(receivedPackets.begin());
|
||||
@@ -290,14 +291,13 @@ namespace LoRa_Utils {
|
||||
receivedPacket.SNR = snr;
|
||||
receivedPackets.push_back(receivedPacket);
|
||||
|
||||
APRSPacket aprsPacket = APRSPacketLib::processReceivedPacket(packet.substring(3), rssi, snr, freqError);
|
||||
if (aprsPacket.type == 0 || aprsPacket.type == 4) { // 0 = GPS, 4 = Mic-E (only ones with position)
|
||||
MAP_Utils::upsert(aprsPacket.sender, aprsPacket.latitude, aprsPacket.longitude, aprsPacket.path, aprsPacket.overlay + aprsPacket.symbol, aprsPacket.rssi, aprsPacket.snr);
|
||||
if (lastAprsPacket.type == 0 || lastAprsPacket.type == 4) { // 0 = GPS, 4 = Mic-E (only ones with position)
|
||||
MAP_Utils::upsert(lastAprsPacket.sender, lastAprsPacket.latitude, lastAprsPacket.longitude, lastAprsPacket.path, lastAprsPacket.overlay + lastAprsPacket.symbol, lastAprsPacket.rssi, lastAprsPacket.snr);
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.syslog.active && networkManager->isConnected()) {
|
||||
SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
|
||||
SYSLOG_Utils::logLoRaRx(lastAprsPacket, packet, rssi, snr, freqError); // RX
|
||||
}
|
||||
} else {
|
||||
packet = "";
|
||||
@@ -310,7 +310,7 @@ namespace LoRa_Utils {
|
||||
freqError = radio.getFrequencyError();
|
||||
Utils::println(F("CRC error!"));
|
||||
if (Config.syslog.active && networkManager->isConnected()) {
|
||||
SYSLOG_Utils::log(0, packet, rssi, snr, freqError); // CRC
|
||||
SYSLOG_Utils::logCRCError(packet, rssi, snr, freqError);
|
||||
}
|
||||
packet = "";
|
||||
} else {
|
||||
|
||||
+132
-98
@@ -16,6 +16,7 @@
|
||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <APRSPacketLib.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include "configuration.h"
|
||||
#include "network_manager.h"
|
||||
@@ -30,117 +31,150 @@ extern String versionNumber;
|
||||
|
||||
WiFiUDP udpClient;
|
||||
|
||||
namespace {
|
||||
|
||||
String createSyslogStart() {
|
||||
String syslogStartPacket = "<165>1 - ";
|
||||
syslogStartPacket.concat(Config.callsign);
|
||||
syslogStartPacket.concat(" CA2RXU_LoRa_iGate_");
|
||||
syslogStartPacket.concat(versionNumber);
|
||||
syslogStartPacket.concat(" - - - "); //RFC5424 The Syslog Protocol
|
||||
return syslogStartPacket;
|
||||
}
|
||||
|
||||
void sendSyslogPacket(const String& syslogPacket) {
|
||||
udpClient.beginPacket(Config.syslog.server.c_str(), Config.syslog.port);
|
||||
udpClient.write((const uint8_t*)syslogPacket.c_str(), syslogPacket.length());
|
||||
udpClient.endPacket();
|
||||
}
|
||||
|
||||
String formatSignalData(int rssi, float snr, int freqError) {
|
||||
char signalData[35];
|
||||
snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
|
||||
return String(signalData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace SYSLOG_Utils {
|
||||
|
||||
void log(const uint8_t type, const String& packet, const int rssi, const float snr, const int freqError) {
|
||||
void logLoRaRx(APRSPacket& aprsPacket, const String& packet, const int rssi, const float snr, const int freqError) {
|
||||
if (Config.syslog.active && networkManager->isConnected()) {
|
||||
String syslogPacket = "<165>1 - ";
|
||||
syslogPacket.concat(Config.callsign);
|
||||
syslogPacket.concat(" CA2RXU_LoRa_iGate_");
|
||||
syslogPacket.concat(versionNumber);
|
||||
syslogPacket.concat(" - - - "); //RFC5424 The Syslog Protocol
|
||||
String syslogPacket = createSyslogStart();
|
||||
syslogPacket.concat("RX / ");
|
||||
|
||||
char signalData[35];
|
||||
snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
|
||||
|
||||
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
|
||||
syslogPacket.concat("CRC / CRC-ERROR / ");
|
||||
syslogPacket.concat(packet);
|
||||
syslogPacket.concat(signalData);
|
||||
switch (aprsPacket.type) {
|
||||
case 1: // MESSAGE
|
||||
syslogPacket.concat("MESSAGE / ");
|
||||
syslogPacket.concat(aprsPacket.sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(aprsPacket.addressee);
|
||||
syslogPacket.concat(":");
|
||||
syslogPacket.concat(aprsPacket.payload);
|
||||
break;
|
||||
case 1: // RX
|
||||
syslogPacket.concat("RX / ");
|
||||
if (nextChar == ':') {
|
||||
syslogPacket.concat("MESSAGE / ");
|
||||
syslogPacket.concat(sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||
} else if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
|
||||
syslogPacket.concat("GPS / ");
|
||||
syslogPacket.concat(sender);
|
||||
syslogPacket.concat(" / ");
|
||||
if (packet.indexOf("WIDE1-1") > 10) {
|
||||
syslogPacket.concat(packet.substring(greaterThanIndex + 1, packet.indexOf(",")));
|
||||
syslogPacket.concat(" / WIDE1-1");
|
||||
} else {
|
||||
syslogPacket.concat(packet.substring(greaterThanIndex + 1, colonIndex));
|
||||
syslogPacket.concat(" / -");
|
||||
case 0: // GPS
|
||||
syslogPacket.concat("GPS / ");
|
||||
syslogPacket.concat(aprsPacket.sender);
|
||||
syslogPacket.concat(" / ");
|
||||
if (aprsPacket.path.indexOf("WIDE1-1") != -1) {
|
||||
syslogPacket.concat(aprsPacket.tocall);
|
||||
syslogPacket.concat(" / WIDE1-1");
|
||||
} else {
|
||||
syslogPacket.concat(aprsPacket.tocall);
|
||||
if (aprsPacket.path != "") {
|
||||
syslogPacket.concat(",");
|
||||
syslogPacket.concat(aprsPacket.path);
|
||||
}
|
||||
} else if (nextChar == '>') {
|
||||
syslogPacket.concat("STATUS / ");
|
||||
syslogPacket.concat(sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||
} else if (nextChar == '`' || nextChar == '\'') { // both Mic-E DTIs are valid
|
||||
syslogPacket.concat("MIC-E / ");
|
||||
syslogPacket.concat(sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(String(nextChar)); // restore the actual indicator received
|
||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||
// append distance for Mic-E, same as the GPS path
|
||||
//syslogPacket.concat(" / ");
|
||||
//syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
|
||||
} else if (nextChar == ';') {
|
||||
syslogPacket.concat("OBJECT / ");
|
||||
syslogPacket.concat(sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||
} else if (telemetryPacketIndex >= 10 && packet.indexOf(":=/") == -1) {
|
||||
syslogPacket.concat("TELEMETRY / ");
|
||||
syslogPacket.concat(sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(packet.substring(telemetryPacketIndex + 3));
|
||||
} else {
|
||||
syslogPacket.concat(packet);
|
||||
}
|
||||
syslogPacket.concat(signalData);
|
||||
if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
|
||||
syslogPacket.concat(" / ");
|
||||
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
|
||||
syslogPacket.concat(" / -");
|
||||
}
|
||||
break;
|
||||
case 2: // APRSIS TX
|
||||
syslogPacket.concat("APRSIS TX / ");
|
||||
if (nextChar == '>') {
|
||||
syslogPacket.concat("StartUp_Status / ");
|
||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||
} else if (nextChar == ':') {
|
||||
syslogPacket.concat("QUERY / ");
|
||||
syslogPacket.concat(packet);
|
||||
} else {
|
||||
syslogPacket.concat("BEACON / ");
|
||||
syslogPacket.concat(packet);
|
||||
}
|
||||
case 2: // STATUS
|
||||
syslogPacket.concat("STATUS / ");
|
||||
syslogPacket.concat(aprsPacket.sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(aprsPacket.payload);
|
||||
break;
|
||||
case 3: // TX
|
||||
syslogPacket.concat("TX / ");
|
||||
if (packet.indexOf("RFONLY") > 10) {
|
||||
syslogPacket.concat("RFONLY / ");
|
||||
syslogPacket.concat(packet);
|
||||
} else if (nextChar == ':') {
|
||||
syslogPacket.concat("MESSAGE / ");
|
||||
syslogPacket.concat(sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||
} else {
|
||||
syslogPacket.concat(packet);
|
||||
}
|
||||
case 4: // MIC-E
|
||||
syslogPacket.concat("MIC-E / ");
|
||||
syslogPacket.concat(aprsPacket.sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(packet.indexOf(":`") != -1 ? "`" : "'"); // restore the actual indicator received
|
||||
break;
|
||||
default:
|
||||
syslogPacket = "<165>1 - ERROR LoRa - - - ERROR / Error in Syslog Packet"; //RFC5424 The Syslog Protocol
|
||||
case 5: // OBJECT
|
||||
syslogPacket.concat("OBJECT / ");
|
||||
syslogPacket.concat(aprsPacket.sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(aprsPacket.payload);
|
||||
break;
|
||||
case 3: // TELEMETRY
|
||||
syslogPacket.concat("TELEMETRY / ");
|
||||
syslogPacket.concat(aprsPacket.sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(aprsPacket.payload);
|
||||
break;
|
||||
default: // type == 6, unrecognized -- payload is the full, uncut packet
|
||||
syslogPacket.concat(aprsPacket.payload);
|
||||
break;
|
||||
}
|
||||
udpClient.beginPacket(Config.syslog.server.c_str(), Config.syslog.port);
|
||||
udpClient.write((const uint8_t*)syslogPacket.c_str(), syslogPacket.length());
|
||||
udpClient.endPacket();
|
||||
syslogPacket.concat(formatSignalData(rssi, snr, freqError));
|
||||
if (aprsPacket.type == 0 || aprsPacket.type == 4) { // GPS or Mic-E -- both already carry
|
||||
syslogPacket.concat(" / "); // clean lat/lon + comment in aprsPacket
|
||||
syslogPacket.concat(GPS_Utils::buildDistanceAndComment(aprsPacket.latitude, aprsPacket.longitude, aprsPacket.payload));
|
||||
}
|
||||
sendSyslogPacket(syslogPacket);
|
||||
}
|
||||
}
|
||||
|
||||
void logAPRSISTx(const String& packet) {
|
||||
if (Config.syslog.active && networkManager->isConnected()) {
|
||||
String syslogPacket = createSyslogStart();
|
||||
syslogPacket.concat("APRSIS TX / ");
|
||||
|
||||
APRSPacket aprsPacket = APRSPacketLib::processReceivedPacket(packet, 0, 0, 0);
|
||||
if (aprsPacket.type == 2) { // STATUS
|
||||
syslogPacket.concat("StartUp_Status / ");
|
||||
syslogPacket.concat(aprsPacket.payload);
|
||||
} else if (aprsPacket.type == 1) { // MESSAGE
|
||||
syslogPacket.concat("QUERY / ");
|
||||
syslogPacket.concat(packet);
|
||||
} else {
|
||||
syslogPacket.concat("BEACON / ");
|
||||
syslogPacket.concat(packet);
|
||||
}
|
||||
sendSyslogPacket(syslogPacket);
|
||||
}
|
||||
}
|
||||
|
||||
void logLoRaTx(const String& packet) {
|
||||
if (Config.syslog.active && networkManager->isConnected()) {
|
||||
String syslogPacket = createSyslogStart();
|
||||
syslogPacket.concat("TX / ");
|
||||
|
||||
APRSPacket aprsPacket = APRSPacketLib::processReceivedPacket(packet, 0, 0, 0);
|
||||
if (aprsPacket.path.indexOf("RFONLY") != -1) {
|
||||
syslogPacket.concat("RFONLY / ");
|
||||
syslogPacket.concat(packet);
|
||||
} else if (aprsPacket.type == 1) {
|
||||
syslogPacket.concat("MESSAGE / ");
|
||||
syslogPacket.concat(aprsPacket.sender);
|
||||
syslogPacket.concat(" ---> ");
|
||||
syslogPacket.concat(aprsPacket.addressee);
|
||||
syslogPacket.concat(":");
|
||||
syslogPacket.concat(aprsPacket.payload);
|
||||
} else {
|
||||
syslogPacket.concat(packet);
|
||||
}
|
||||
sendSyslogPacket(syslogPacket);
|
||||
}
|
||||
}
|
||||
|
||||
void logCRCError(const String& packet, const int rssi, const float snr, const int freqError) {
|
||||
if (Config.syslog.active && networkManager->isConnected()) {
|
||||
String syslogPacket = createSyslogStart();
|
||||
syslogPacket.concat("CRC / CRC-ERROR / ");
|
||||
syslogPacket.concat(packet);
|
||||
syslogPacket.concat(formatSignalData(rssi, snr, freqError));
|
||||
sendSyslogPacket(syslogPacket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+56
-37
@@ -89,7 +89,7 @@ namespace Utils {
|
||||
|
||||
if (sendOverAPRSIS) {
|
||||
APRS_IS_Utils::upload(statusPacket);
|
||||
SYSLOG_Utils::log(2, statusPacket, 0, 0.0, 0); // APRSIS TX
|
||||
SYSLOG_Utils::logAPRSISTx(statusPacket);
|
||||
} else {
|
||||
STATION_Utils::addToOutputPacketBuffer(statusPacket, true); // treated also as beacon on Tx Freq
|
||||
}
|
||||
@@ -288,7 +288,7 @@ namespace Utils {
|
||||
#else
|
||||
APRS_IS_Utils::upload(beaconPacket);
|
||||
#endif
|
||||
if (Config.syslog.logBeaconOverTCPIP) SYSLOG_Utils::log(1, "tcp" + beaconPacket, 0, 0.0, 0); // APRSIS TX
|
||||
if (Config.syslog.logBeaconOverTCPIP) SYSLOG_Utils::logAPRSISTx(beaconPacket);
|
||||
}
|
||||
|
||||
if (Config.beacon.sendViaRF || backupDigiMode) {
|
||||
@@ -325,21 +325,65 @@ namespace Utils {
|
||||
}
|
||||
}
|
||||
|
||||
void typeOfPacket(const String& packet, const uint8_t packetType) {
|
||||
void updateLoRaPacketDisplayInfo(APRSPacket& aprsPacket, const uint8_t packetType) {
|
||||
switch (packetType) {
|
||||
case 0: // LoRa-APRS
|
||||
fifthLine = "LoRa Rx ----> APRS-IS";
|
||||
break;
|
||||
case 1: // APRS-LoRa
|
||||
fifthLine = "APRS-IS ----> LoRa Tx";
|
||||
break;
|
||||
case 2: // Digipeater
|
||||
case 1: // Digipeater
|
||||
fifthLine = "LoRa Rx ----> LoRa Tx";
|
||||
break;
|
||||
}
|
||||
|
||||
int firstColonIndex = packet.indexOf(":");
|
||||
char nextChar = packet[firstColonIndex + 1];
|
||||
String sender = aprsPacket.sender;
|
||||
for (int i = sender.length(); i < 9; i++) {
|
||||
sender += " ";
|
||||
}
|
||||
sixthLine = sender;
|
||||
|
||||
switch (aprsPacket.type) {
|
||||
case 1: // MESSAGE
|
||||
sixthLine += "> MESSAGE";
|
||||
break;
|
||||
case 2: // STATUS
|
||||
sixthLine += "> NEW STATUS";
|
||||
break;
|
||||
case 0: // GPS
|
||||
sixthLine += "> GPS BEACON";
|
||||
if (!Config.syslog.active) GPS_Utils::buildDistanceAndComment(aprsPacket.latitude, aprsPacket.longitude, aprsPacket.payload);
|
||||
seventhLine = "RSSI:";
|
||||
seventhLine += String(rssi);
|
||||
seventhLine += "dBm";
|
||||
seventhLine += (rssi <= -100) ? " " : " ";
|
||||
if (distance.indexOf(".") == 1) seventhLine += " ";
|
||||
seventhLine += "D:";
|
||||
seventhLine += distance;
|
||||
seventhLine += "km";
|
||||
break;
|
||||
case 3: // TELEMETRY
|
||||
sixthLine += "> TELEMETRY";
|
||||
break;
|
||||
case 4: // MIC-E
|
||||
sixthLine += "> MIC-E";
|
||||
break;
|
||||
case 5: // OBJECT
|
||||
sixthLine += "> OBJECT";
|
||||
break;
|
||||
default: // unrecognized
|
||||
sixthLine += "> ?????????";
|
||||
break;
|
||||
}
|
||||
if (aprsPacket.type != 0) { // Common assignment for non-GPS cases
|
||||
seventhLine = "RSSI:";
|
||||
seventhLine += String(rssi);
|
||||
seventhLine += "dBm SNR: ";
|
||||
seventhLine += String(snr);
|
||||
seventhLine += "dBm";
|
||||
}
|
||||
}
|
||||
|
||||
void updateAPRSISPacketDisplayInfo(const String& packet) {
|
||||
fifthLine = "APRS-IS ----> LoRa Tx";
|
||||
|
||||
String sender = packet.substring(0,packet.indexOf(">"));
|
||||
for (int i = sender.length(); i < 9; i++) {
|
||||
@@ -347,37 +391,12 @@ namespace Utils {
|
||||
}
|
||||
sixthLine = sender;
|
||||
|
||||
if (nextChar == ':') {
|
||||
if (packet.indexOf("::") > 0) {
|
||||
sixthLine += "> MESSAGE";
|
||||
} else if (nextChar == '>') {
|
||||
sixthLine += "> NEW STATUS";
|
||||
} else if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
|
||||
sixthLine += "> GPS BEACON";
|
||||
if (!Config.syslog.active) GPS_Utils::getDistanceAndComment(packet); // to be checked!!!
|
||||
seventhLine = "RSSI:";
|
||||
seventhLine += String(rssi);
|
||||
seventhLine += "dBm";
|
||||
seventhLine += (rssi <= -100) ? " " : " ";
|
||||
if (distance.indexOf(".") == 1) seventhLine += " ";
|
||||
seventhLine += "D:";
|
||||
seventhLine += distance;
|
||||
seventhLine += "km";
|
||||
} else if (nextChar == '`' || nextChar == '\'') {
|
||||
sixthLine += "> MIC-E";
|
||||
} else if (nextChar == ';') {
|
||||
sixthLine += "> OBJECT";
|
||||
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
|
||||
sixthLine += "> TELEMETRY";
|
||||
} else {
|
||||
sixthLine += "> ??????????";
|
||||
}
|
||||
if (nextChar != '!' && nextChar != '=' && nextChar != '@') { // Common assignment for non-GPS cases
|
||||
seventhLine = "RSSI:";
|
||||
seventhLine += String(rssi);
|
||||
seventhLine += "dBm SNR: ";
|
||||
seventhLine += String(snr);
|
||||
seventhLine += "dBm";
|
||||
sixthLine += "> OBJECT";
|
||||
}
|
||||
seventhLine = "";
|
||||
}
|
||||
|
||||
void print(const String& text) {
|
||||
|
||||
Reference in new issue
Block a user