Compare commits

..

1 Commits

Author SHA1 Message Date
richonguzman ee25ec6873 checkItOut 2025-02-28 14:20:49 -03:00
31 changed files with 250 additions and 619 deletions
-2
View File
@@ -57,8 +57,6 @@ jobs:
chip: esp32s3 chip: esp32s3
- name: ttgo_t_deck_GPS - name: ttgo_t_deck_GPS
chip: esp32s3 chip: esp32s3
- name: ttgo_t_beam_s3_SUPREME_v3
chip: esp32s3
- name: ESP32_DIY_LoRa_A7670 - name: ESP32_DIY_LoRa_A7670
chip: esp32 chip: esp32
- name: ESP32_DIY_LoRa_A7670_915 - name: ESP32_DIY_LoRa_A7670_915
+2 -4
View File
@@ -54,9 +54,7 @@ ____________________________________________________
## Timeline (Versions): ## Timeline (Versions):
- 2025.03.03 T-Beam Supreme board added and more BlackList rules added. - 2025.02.25 Objects Rules updated and GPS Boards: Satellites in Screen, Wx Height Correction from GPS Data.
- 2025.02.28 Heltec Wireless Paper with Epaper working. Thanks SzymonPriv for pointing to the right library.
- 2025.02.25 Objects Rules update, GPS Boards: Satellites on Screen, Wx Height Correction from GPS Data.
- 2025.01.22 Added LILYGO T-DECK PLUS (and DIY+GPS version) board support. - 2025.01.22 Added LILYGO T-DECK PLUS (and DIY+GPS version) board support.
- 2025.01.11 Added HELTEC V3.2 board support. - 2025.01.11 Added HELTEC V3.2 board support.
- 2025.01.07 TROY_LoRa_APRS board added. GMT in quarter hour fix and Beacon fix for TNC. - 2025.01.07 TROY_LoRa_APRS board added. GMT in quarter hour fix and Beacon fix for TNC.
@@ -68,7 +66,7 @@ ____________________________________________________
- 2024.10.25 Added QRP Labs LightGateway 1.0 support. - 2024.10.25 Added QRP Labs LightGateway 1.0 support.
- 2024.10.21 Boards with GPS can now send Real-GPS Beacon (also posible: GPS ambiguity of ~ 1 km). - 2024.10.21 Boards with GPS can now send Real-GPS Beacon (also posible: GPS ambiguity of ~ 1 km).
- 2024.10.14 Received Packets in WebUI show real Local Time (NTP with GMT offset). - 2024.10.14 Received Packets in WebUI show real Local Time (NTP with GMT offset).
- 2024.10.08 New EcoMode for Remote Digipeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP 150mA). APRS Message/Queries can start/stop this mode too. - 2024.10.08 New EcoMode for Remote Digipeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP and all was 150mA). APRS Message/Queries can start/stop this mode too.
- 2024.10.06 Cross Frequency Digipeater Rules added. - 2024.10.06 Cross Frequency Digipeater Rules added.
- 2024.09.23 Libraries Update for SDK3 - 2024.09.23 Libraries Update for SDK3
- 2024.09.23 Added Enconded Telemetry for Battery (+ External Voltage) in Station GPS Beacon Packet. - 2024.09.23 Added Enconded Telemetry for Battery (+ External Voltage) in Station GPS Beacon Packet.
+2 -2
View File
@@ -32,9 +32,9 @@ lib_deps =
arduino-libraries/NTPClient @ 3.2.1 arduino-libraries/NTPClient @ 3.2.1
ayushsharma82/ElegantOTA @ 3.1.5 ayushsharma82/ElegantOTA @ 3.1.5
bblanchon/ArduinoJson @ 6.21.3 bblanchon/ArduinoJson @ 6.21.3
ESP32Async/AsyncTCP @ 3.3.5
ESP32Async/ESPAsyncWebServer @ 3.7.0
jgromes/RadioLib @ 7.1.0 jgromes/RadioLib @ 7.1.0
mathieucarbou/AsyncTCP @ 3.2.5
mathieucarbou/ESPAsyncWebServer @ 3.2.3
mikalhart/TinyGPSPlus @ 1.0.3 mikalhart/TinyGPSPlus @ 1.0.3
display_libs = display_libs =
adafruit/Adafruit GFX Library @ 1.11.9 adafruit/Adafruit GFX Library @ 1.11.9
+1 -5
View File
@@ -84,10 +84,6 @@
"ntp": { "ntp": {
"gmtCorrection": 0.0 "gmtCorrection": 0.0
}, },
"remoteManagement": {
"managers": "",
"rfOnly": true
},
"other": { "other": {
"rememberStationTime": 30, "rememberStationTime": 30,
"lowPowerMode": false, "lowPowerMode": false,
@@ -97,5 +93,5 @@
"rebootModeTime": 6 "rebootModeTime": 6
}, },
"personalNote": "", "personalNote": "",
"blacklist": "" "blackList": ""
} }
+5 -64
View File
@@ -590,20 +590,20 @@
</svg> </svg>
Black List Black List
</h5> </h5>
<small>Add Callsigns with space between them to Blacklist them (* wild card allowed)</small> <small>Add Callsigns with space between them to Black List them (* wild card allowed)</small>
</div> </div>
<div class="col-9 mt-2"> <div class="col-9 mt-2">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<label <label
for="blacklist" for="blackList"
class="form-label" class="form-label"
>Blacklist</label >Black List</label
> >
<input <input
type="text" type="text"
name="blacklist" name="blackList"
id="blacklist" id="blackList"
class="form-control" class="form-control"
placeholder="Station Callsign" placeholder="Station Callsign"
oninput="this.value = this.value.toUpperCase();" oninput="this.value = this.value.toUpperCase();"
@@ -1708,65 +1708,6 @@
</div> </div>
<hr /> <hr />
<div class="row my-5 d-flex align-items-top">
<div class="col-lg-3 col-sm-12">
<h5>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
class="bi bi-cloud-upload-fill"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M8 0a5.53 5.53 0 0 0-3.594 1.342c-.766.66-1.321 1.52-1.464 2.383C1.266 4.095 0 5.555 0 7.318 0 9.366 1.708 11 3.781 11H7.5V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V11h4.188C14.502 11 16 9.57 16 7.773c0-1.636-1.242-2.969-2.834-3.194C12.923 1.999 10.69 0 8 0m-.5 14.5V11h1v3.5a.5.5 0 0 1-1 0"
/>
</svg>
Remote Management
</h5>
<small
>Manage Station via APRS Messages. Leave empty to disable!
</small>
</div>
<div class="col-lg-9 col-sm-12">
<div class="col-12">
<label
for="remoteManagement.managers"
class="form-label"
>Callsign-SSID of Managers, space separated, trailing * wildcard allowed</label
>
<div class="input-group">
<input
type="text"
name="remoteManagement.managers"
id="remoteManagement.managers"
class="form-control"
/>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="form-check form-switch">
<input
type="checkbox"
name="remoteManagement.rfOnly"
id="remoteManagement.rfOnly"
class="form-check-input"
/>
<label
for="remoteManagement.rfOnly"
class="form-label"
>Managers commands only via RF (not APRS-IS)</label
>
</div>
</div>
</div>
</div>
</div>
<hr />
<div class="row my-5 d-flex align-items-top"> <div class="row my-5 d-flex align-items-top">
<div class="col-lg-3 col-sm-12"> <div class="col-lg-3 col-sm-12">
<h5> <h5>
+1 -5
View File
@@ -138,7 +138,7 @@ function loadSettings(settings) {
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity; document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
// Black List // Black List
document.getElementById("blacklist").value = settings.blacklist; document.getElementById("blackList").value = settings.blackList;
// Digi // Digi
document.getElementById("digi.mode").value = settings.digi.mode; document.getElementById("digi.mode").value = settings.digi.mode;
@@ -223,10 +223,6 @@ function loadSettings(settings) {
document.getElementById("other.lowPowerMode").checked = settings.other.lowPowerMode; document.getElementById("other.lowPowerMode").checked = settings.other.lowPowerMode;
document.getElementById("other.lowVoltageCutOff").value = settings.other.lowVoltageCutOff || 0 document.getElementById("other.lowVoltageCutOff").value = settings.other.lowVoltageCutOff || 0
// Management over APRS
document.getElementById("remoteManagement.managers").value = settings.remoteManagement.managers;
document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly;
updateImage(); updateImage();
refreshSpeedStandard(); refreshSpeedStandard();
toggleFields(); toggleFields();
+2 -8
View File
@@ -122,11 +122,6 @@ public:
float gmtCorrection; float gmtCorrection;
}; };
class REMOTE_MANAGEMENT {
public:
String managers;
bool rfOnly;
};
class Configuration { class Configuration {
public: public:
@@ -138,7 +133,7 @@ public:
bool rebootMode; bool rebootMode;
int rebootModeTime; int rebootModeTime;
String personalNote; String personalNote;
String blacklist; String blackList;
std::vector<WiFi_AP> wifiAPs; std::vector<WiFi_AP> wifiAPs;
WiFi_Auto_AP wifiAutoAP; WiFi_Auto_AP wifiAutoAP;
BEACON beacon; BEACON beacon;
@@ -152,8 +147,7 @@ public:
TNC tnc; TNC tnc;
OTA ota; OTA ota;
WEBADMIN webadmin; WEBADMIN webadmin;
NTP ntp; NTP ntp;
REMOTE_MANAGEMENT remoteManagement;
void init(); void init();
void writeFile(); void writeFile();
+2 -4
View File
@@ -18,10 +18,8 @@ struct LastHeardStation {
namespace STATION_Utils { namespace STATION_Utils {
void loadBlacklist(); void loadBlackList();
void loadManagers(); bool checkBlackList(const String& callsign);
bool isBlacklisted(const String& callsign);
bool isManager(const String& callsign);
bool checkObjectTime(const String& packet); bool checkObjectTime(const String& packet);
void deleteNotHeard(); void deleteNotHeard();
void updateLastHeard(const String& station); void updateLastHeard(const String& station);
+2 -2
View File
@@ -13,10 +13,10 @@ default_envs = ttgo-lora32-v21
extra_configs = extra_configs =
common_settings.ini common_settings.ini
variants/*/platformio.ini variants/*/platformio.ini
[env] [env]
platform = espressif32 @ 6.7.0 platform = espressif32 @ 6.10.0
board_build.partitions = min_spiffs.csv board_build.partitions = min_spiffs.csv
framework = arduino framework = arduino
monitor_speed = 115200 monitor_speed = 115200
-1
View File
@@ -6,7 +6,6 @@
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
#ifdef HAS_A7670 #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 TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
+6 -23
View File
@@ -26,11 +26,13 @@ ___________________________________________________________________*/
#include <WiFi.h> #include <WiFi.h>
#include <vector> #include <vector>
#include "configuration.h" #include "configuration.h"
#include "battery_utils.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "station_utils.h" #include "station_utils.h"
#include "battery_utils.h" #include "battery_utils.h"
#include "board_pinout.h" #include "board_pinout.h"
#include "syslog_utils.h" #include "syslog_utils.h"
#include "query_utils.h"
#include "power_utils.h" #include "power_utils.h"
#include "lora_utils.h" #include "lora_utils.h"
#include "wifi_utils.h" #include "wifi_utils.h"
@@ -46,8 +48,7 @@ ___________________________________________________________________*/
#include "A7670_utils.h" #include "A7670_utils.h"
#endif #endif
String versionDate = "2025.02.28";
String versionDate = "2025.03.20";
Configuration Config; Configuration Config;
WiFiClient espClient; WiFiClient espClient;
#ifdef HAS_GPS #ifdef HAS_GPS
@@ -67,16 +68,11 @@ uint32_t lastBatteryCheck = 0;
bool backUpDigiMode = false; bool backUpDigiMode = false;
bool modemLoggedToAPRSIS = false; bool modemLoggedToAPRSIS = false;
#ifdef HAS_EPAPER
uint32_t lastEpaperTime = 0;
extern String lastEpaperText;
#endif
std::vector<ReceivedPacket> receivedPackets; std::vector<ReceivedPacket> receivedPackets;
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine; String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
//#define STARTUP_DELAY 5 //min
//#define STARTUP_DELAY 5 //min
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
@@ -85,8 +81,7 @@ void setup() {
LoRa_Utils::setup(); LoRa_Utils::setup();
Utils::validateFreqs(); Utils::validateFreqs();
GPS_Utils::setup(); GPS_Utils::setup();
STATION_Utils::loadBlacklist(); STATION_Utils::loadBlackList();
STATION_Utils::loadManagers();
#ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers #ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers
displayShow("", " STARTUP DELAY ...", "", "", 0); displayShow("", " STARTUP DELAY ...", "", "", 0);
@@ -224,19 +219,7 @@ void loop() {
STATION_Utils::processOutputPacketBuffer(); STATION_Utils::processOutputPacketBuffer();
#ifdef HAS_EPAPER // Only consider updating every 10 seconds (when data to show is different from before) displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
if(lastEpaperTime == 0 || millis() - lastEpaperTime > 10000) {
String posibleEpaperText = firstLine + secondLine + thirdLine + fourthLine + fifthLine + sixthLine + seventhLine;
if (lastEpaperText != posibleEpaperText) {
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
lastEpaperText = posibleEpaperText;
lastEpaperTime = millis();
}
}
#else
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
#endif
Utils::checkRebootTime(); Utils::checkRebootTime();
Utils::checkSleepByLowBatteryVoltage(1); Utils::checkSleepByLowBatteryVoltage(1);
} }
+32 -33
View File
@@ -9,7 +9,6 @@
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern WiFiClient espClient; extern WiFiClient espClient;
extern uint32_t lastScreenOn; extern uint32_t lastScreenOn;
@@ -59,7 +58,7 @@ namespace APRS_IS_Utils {
aprsAuth += Config.callsign; aprsAuth += Config.callsign;
aprsAuth += " pass "; aprsAuth += " pass ";
aprsAuth += Config.aprs_is.passcode; aprsAuth += Config.aprs_is.passcode;
aprsAuth += " vers CA2RXU_iGate 2.3 filter "; aprsAuth += " vers CA2RXU_LoRa_iGate 2.0 filter ";
aprsAuth += Config.aprs_is.filter; aprsAuth += Config.aprs_is.filter;
upload(aprsAuth); upload(aprsAuth);
} }
@@ -174,35 +173,37 @@ namespace APRS_IS_Utils {
void processLoRaPacket(const String& packet) { void processLoRaPacket(const String& packet) {
if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) { if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) {
if (packet.indexOf("NOGATE") == -1 && packet.indexOf("RFONLY") == -1) { if (packet != "") {
int firstColonIndex = packet.indexOf(":"); if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) {
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) { int firstColonIndex = packet.indexOf(":");
const String& Sender = packet.substring(3, packet.indexOf(">")); if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
if (Sender != Config.callsign && Utils::checkValidCallsign(Sender)) { const String& Sender = packet.substring(3, packet.indexOf(">"));
STATION_Utils::updateLastHeard(Sender); if (Sender != Config.callsign && Utils::checkValidCallsign(Sender) && !STATION_Utils::checkBlackList(Sender)) {
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS STATION_Utils::updateLastHeard(Sender);
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
Addressee.trim(); String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
bool queryMessage = false; Addressee.trim();
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me! bool queryMessage = false;
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false); if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
} queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
if (!queryMessage) { }
const String& aprsPacket = buildPacketToUpload(packet); if (!queryMessage) {
if (!Config.display.alwaysOn && Config.display.timeout != 0) { const String& aprsPacket = buildPacketToUpload(packet);
displayToggle(true); if (!Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
}
lastScreenOn = millis();
#ifdef HAS_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} }
lastScreenOn = millis();
#ifdef HAS_A7670
stationBeacon = true;
A7670_Utils::uploadToAPRSIS(aprsPacket);
stationBeacon = false;
#else
upload(aprsPacket);
#endif
Utils::println("---> Uploaded to APRS-IS");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} }
} }
} }
@@ -298,7 +299,6 @@ namespace APRS_IS_Utils {
} }
if (receivedMessage.indexOf("?") == 0) { if (receivedMessage.indexOf("?") == 0) {
Utils::println("Rx Query (APRS-IS) : " + packet); Utils::println("Rx Query (APRS-IS) : " + packet);
Sender.trim();
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false); String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n"))); //Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
if (!Config.display.alwaysOn && Config.display.timeout != 0) { if (!Config.display.alwaysOn && Config.display.timeout != 0) {
@@ -322,7 +322,6 @@ namespace APRS_IS_Utils {
seventhLine = "QUERY = "; seventhLine = "QUERY = ";
seventhLine += receivedMessage; seventhLine += receivedMessage;
} }
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else { } else {
Utils::print("Rx Message (APRS-IS): " + packet); Utils::print("Rx Message (APRS-IS): " + packet);
if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) { if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) {
@@ -330,9 +329,9 @@ namespace APRS_IS_Utils {
displayToggle(true); displayToggle(true);
lastScreenOn = millis(); lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa Utils::typeOfPacket(packet, 1); // APRS-LoRa
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} }
} }
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) { } else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
Utils::print("Rx Object (APRS-IS) : " + packet); Utils::print("Rx Object (APRS-IS) : " + packet);
if (STATION_Utils::checkObjectTime(packet)) { if (STATION_Utils::checkObjectTime(packet)) {
-1
View File
@@ -5,7 +5,6 @@
#include "power_utils.h" #include "power_utils.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastBatteryCheck; extern uint32_t lastBatteryCheck;
+3 -12
View File
@@ -99,7 +99,7 @@ void Configuration::writeFile() {
data["personalNote"] = personalNote; data["personalNote"] = personalNote;
data["blacklist"] = blacklist; data["blackList"] = blackList;
data["webadmin"]["active"] = webadmin.active; data["webadmin"]["active"] = webadmin.active;
data["webadmin"]["username"] = webadmin.username; data["webadmin"]["username"] = webadmin.username;
@@ -107,9 +107,6 @@ void Configuration::writeFile() {
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection; data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
data["remoteManagement"]["managers"] = remoteManagement.managers;
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
serializeJson(data, configFile); serializeJson(data, configFile);
configFile.close(); configFile.close();
@@ -226,10 +223,7 @@ bool Configuration::readFile() {
personalNote = data["personalNote"] | "personal note here"; personalNote = data["personalNote"] | "personal note here";
blacklist = data["blacklist"] | "station callsign"; blackList = data["blackList"] | "station callsign";
remoteManagement.managers = data["remoteManagement"]["managers"] | "";
remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true;
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
WiFi_AP wifiap; WiFi_AP wifiap;
@@ -337,7 +331,7 @@ void Configuration::init() {
personalNote = ""; personalNote = "";
blacklist = ""; blackList = "";
webadmin.active = false; webadmin.active = false;
webadmin.username = "admin"; webadmin.username = "admin";
@@ -345,9 +339,6 @@ void Configuration::init() {
ntp.gmtCorrection = 0.0; ntp.gmtCorrection = 0.0;
remoteManagement.managers = "";
remoteManagement.rfOnly = true;
Serial.println("All is Written!"); Serial.println("All is Written!");
} }
+38 -36
View File
@@ -2,6 +2,7 @@
#include "configuration.h" #include "configuration.h"
#include "station_utils.h" #include "station_utils.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "query_utils.h"
#include "digi_utils.h" #include "digi_utils.h"
#include "wifi_utils.h" #include "wifi_utils.h"
#include "lora_utils.h" #include "lora_utils.h"
@@ -9,7 +10,6 @@
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastScreenOn; extern uint32_t lastScreenOn;
extern String iGateBeaconPacket; extern String iGateBeaconPacket;
@@ -117,44 +117,46 @@ namespace DIGI_Utils {
} }
void processLoRaPacket(const String& packet) { void processLoRaPacket(const String& packet) {
if (packet.indexOf("NOGATE") == -1) { if (packet != "") {
bool thirdPartyPacket = false; if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) {
String temp, Sender; bool thirdPartyPacket = false;
int firstColonIndex = packet.indexOf(":"); String temp, Sender;
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party int firstColonIndex = packet.indexOf(":");
thirdPartyPacket = true; if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party
temp = packet.substring(packet.indexOf(":}") + 2); thirdPartyPacket = true;
Sender = temp.substring(0, temp.indexOf(">")); temp = packet.substring(packet.indexOf(":}") + 2);
} else { Sender = temp.substring(0, temp.indexOf(">"));
temp = packet.substring(3); } else {
Sender = packet.substring(3, packet.indexOf(">")); temp = packet.substring(3);
} Sender = packet.substring(3, packet.indexOf(">"));
if (Sender != Config.callsign) { // Avoid listening to own packets
if (!thirdPartyPacket && !Utils::checkValidCallsign(Sender)) {
return;
} }
if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) { if (Sender != Config.callsign && !STATION_Utils::checkBlackList(Sender)) { // Avoid listening to own packets
STATION_Utils::updateLastHeard(Sender); if (!thirdPartyPacket && !Utils::checkValidCallsign(Sender)) {
Utils::typeOfPacket(temp, 2); // Digi return;
bool queryMessage = false;
if (temp.indexOf("::") > 10) { // it's a message
String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (Addressee == Config.callsign) { // it's a message for me!
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
}
} }
if (!queryMessage) { if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) {
String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket); STATION_Utils::updateLastHeard(Sender);
if (loraPacket != "") { Utils::typeOfPacket(temp, 2); // Digi
if (Config.lowPowerMode) { bool queryMessage = false;
LoRa_Utils::sendNewPacket(loraPacket); if (temp.indexOf("::") > 10) { // it's a message
} else { String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
STATION_Utils::addToOutputPacketBuffer(loraPacket); String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
Addressee.trim();
if (Addressee == Config.callsign) { // it's a message for me!
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
}
}
if (!queryMessage) {
String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket);
if (loraPacket != "") {
if (Config.lowPowerMode) {
LoRa_Utils::sendNewPacket(loraPacket);
} else {
STATION_Utils::addToOutputPacketBuffer(loraPacket);
}
displayToggle(true);
lastScreenOn = millis();
} }
displayToggle(true);
lastScreenOn = millis();
} }
} }
} }
+29 -98
View File
@@ -24,22 +24,14 @@
uint16_t redColor = 0xc8a2; uint16_t redColor = 0xc8a2;
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
#include <heltec-eink-modules.h> //
#include "Fonts/FreeSansBold9pt7b.h"
EInkDisplay_WirelessPaperV1_1 display;
String lastEpaperText;
#else #else
#include <Adafruit_GFX.h> #include <Adafruit_GFX.h>
#if defined(TTGO_T_Beam_S3_SUPREME_V3) #include <Adafruit_SSD1306.h>
#include <Adafruit_SH110X.h> #ifdef HELTEC_WSL_V3_DISPLAY
Adafruit_SH1106G display(128, 64, &Wire, OLED_RST); Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
#else #else
#include <Adafruit_SSD1306.h> Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
#ifdef HELTEC_WSL_V3_DISPLAY
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
#else
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
#endif
#endif #endif
#endif #endif
#endif #endif
@@ -71,9 +63,7 @@ void displaySetup() {
#endif #endif
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
display.landscape(); //
display.printCenter("LoRa APRS iGate Initialising...");
display.update();
#else #else
#ifdef OLED_DISPLAY_HAS_RST_PIN #ifdef OLED_DISPLAY_HAS_RST_PIN
pinMode(OLED_RST, OUTPUT); pinMode(OLED_RST, OUTPUT);
@@ -82,30 +72,17 @@ void displaySetup() {
digitalWrite(OLED_RST, HIGH); digitalWrite(OLED_RST, HIGH);
#endif #endif
#if defined(TTGO_T_Beam_S3_SUPREME_V3) if(display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
if (!display.begin(0x3c, false)) { displayFound = true;
displayFound = true; if (Config.display.turn180) display.setRotation(2);
if (Config.display.turn180) display.setRotation(2); display.clearDisplay();
display.clearDisplay(); display.setTextColor(WHITE);
display.setTextColor(SH110X_WHITE); display.setTextSize(1);
display.setTextSize(1); display.setCursor(0, 0);
display.setCursor(0, 0); display.ssd1306_command(SSD1306_SETCONTRAST);
display.setContrast(1); display.ssd1306_command(1);
display.display(); display.display();
} }
#else
if(display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
displayFound = true;
if (Config.display.turn180) display.setRotation(2);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
}
#endif
#endif #endif
#endif #endif
delay(1000); delay(1000);
@@ -119,14 +96,9 @@ void displayToggle(bool toggle) {
digitalWrite(TFT_BL, HIGH); digitalWrite(TFT_BL, HIGH);
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
display.printCenter("EPAPER Display Disabled by toggle..."); // ... to be continued
display.update();
#else #else
#if defined(TTGO_T_Beam_S3_SUPREME_V3) if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
if (displayFound) display.oled_command(SH110X_DISPLAYON);
#else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
#endif
#endif #endif
#endif #endif
} else { } else {
@@ -134,15 +106,9 @@ void displayToggle(bool toggle) {
digitalWrite(TFT_BL, LOW); digitalWrite(TFT_BL, LOW);
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
display.printCenter("Enabled EPAPER Display..."); // ... to be continued
display.update();
#else #else
#if defined(TTGO_T_Beam_S3_SUPREME_V3) if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
if (displayFound) display.oled_command(SH110X_DISPLAYOFF);
#else
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
#endif
#endif #endif
#endif #endif
} }
@@ -175,24 +141,11 @@ void displayShow(const String& header, const String& line1, const String& line2,
sprite.pushSprite(0,0); sprite.pushSprite(0,0);
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
display.clearMemory(); // ... to be continued
display.setCursor(5,10);
display.setFont(&FreeSansBold9pt7b);
display.println(header);
display.setFont(NULL);
for (int i = 0; i < 3; i++) {
display.setCursor(0, 25 + (14 * i));
display.println(*lines[i]);
}
display.update();
#else #else
if (displayFound) { if (displayFound) {
display.clearDisplay(); display.clearDisplay();
#if defined(TTGO_T_Beam_S3_SUPREME_V3) display.setTextColor(WHITE);
display.setTextColor(SH110X_WHITE);
#else
display.setTextColor(WHITE);
#endif
display.setTextSize(1); display.setTextSize(1);
display.setCursor(0, 0); display.setCursor(0, 0);
display.println(header); display.println(header);
@@ -200,12 +153,8 @@ void displayShow(const String& header, const String& line1, const String& line2,
display.setCursor(0, 8 + (8 * i)); display.setCursor(0, 8 + (8 * i));
display.println(*lines[i]); display.println(*lines[i]);
} }
#if defined(TTGO_T_Beam_S3_SUPREME_V3) display.ssd1306_command(SSD1306_SETCONTRAST);
display.setContrast(1); display.ssd1306_command(1);
#else
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
#endif
display.display(); display.display();
} }
#endif #endif
@@ -240,25 +189,11 @@ void displayShow(const String& header, const String& line1, const String& line2,
sprite.pushSprite(0,0); sprite.pushSprite(0,0);
#else #else
#ifdef HAS_EPAPER #ifdef HAS_EPAPER
lastEpaperText = header + line1 + line2 + line3 + line4 + line5 + line6; // ... to be continued
display.clearMemory();
display.setCursor(5,10);
display.setFont(&FreeSansBold9pt7b);
display.println(header);
display.setFont(NULL);
for (int i = 0; i < 6; i++) {
display.setCursor(0, 25 + (14 * i));
display.println(*lines[i]);
}
display.update();
#else #else
if (displayFound) { if (displayFound) {
display.clearDisplay(); display.clearDisplay();
#if defined(TTGO_T_Beam_S3_SUPREME_V3) display.setTextColor(WHITE);
display.setTextColor(SH110X_WHITE);
#else
display.setTextColor(WHITE);
#endif
display.setTextSize(2); display.setTextSize(2);
display.setCursor(0, 0); display.setCursor(0, 0);
display.println(header); display.println(header);
@@ -267,12 +202,8 @@ void displayShow(const String& header, const String& line1, const String& line2,
display.setCursor(0, 16 + (8 * i)); display.setCursor(0, 16 + (8 * i));
display.println(*lines[i]); display.println(*lines[i]);
} }
#if defined(TTGO_T_Beam_S3_SUPREME_V3) display.ssd1306_command(SSD1306_SETCONTRAST);
display.setContrast(1); display.ssd1306_command(1);
#else
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
#endif
display.display(); display.display();
} }
#endif #endif
+53 -68
View File
@@ -110,30 +110,22 @@ namespace GPS_Utils {
} }
String decodeEncodedGPS(const String& packet) { String decodeEncodedGPS(const String& packet) {
int indexOfExclamation = packet.indexOf(":!"); const String& GPSPacket = packet.substring(packet.indexOf(":!")+3);
int indexOfEqual = packet.indexOf(":="); const String& encodedLatitude = GPSPacket.substring(0,4);
const String& encodedLongtitude = GPSPacket.substring(4,8);
const String& comment = GPSPacket.substring(12);
const uint8_t OFFSET = 3; // Offset for encoded data in the packet int Y1 = int(encodedLatitude[0]);
String GPSPacket; int Y2 = int(encodedLatitude[1]);
if (indexOfExclamation > 10) { int Y3 = int(encodedLatitude[2]);
GPSPacket = packet.substring(indexOfExclamation + OFFSET); int Y4 = int(encodedLatitude[3]);
} else if (indexOfEqual > 10) { float decodedLatitude = 90.0 - ((((Y1-33) * pow(91,3)) + ((Y2-33) * pow(91,2)) + ((Y3-33) * 91) + Y4-33) / 380926.0);
GPSPacket = packet.substring(indexOfEqual + OFFSET);
} int X1 = int(encodedLongtitude[0]);
int X2 = int(encodedLongtitude[1]);
String encodedLatitude = GPSPacket.substring(0,4); int X3 = int(encodedLongtitude[2]);
int Y1 = encodedLatitude[0] - 33; int X4 = int(encodedLongtitude[3]);
int Y2 = encodedLatitude[1] - 33; float decodedLongitude = -180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0);
int Y3 = encodedLatitude[2] - 33;
int Y4 = encodedLatitude[3] - 33;
float decodedLatitude = 90.0 - (((Y1 * pow(91,3)) + (Y2 * pow(91,2)) + (Y3 * 91) + Y4) / 380926.0);
String encodedLongitude = GPSPacket.substring(4,8);
int X1 = encodedLongitude[0] - 33;
int X2 = encodedLongitude[1] - 33;
int X3 = encodedLongitude[2] - 33;
int X4 = encodedLongitude[3] - 33;
float decodedLongitude = -180.0 + (((X1 * pow(91,3)) + (X2 * pow(91,2)) + (X3 * 91) + X4) / 190463.0);
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1); distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
@@ -144,7 +136,6 @@ namespace GPS_Utils {
decodedGPS += distance; decodedGPS += distance;
decodedGPS += "km"; decodedGPS += "km";
String comment = GPSPacket.substring(12);
if (comment != "") { if (comment != "") {
decodedGPS += " / "; decodedGPS += " / ";
decodedGPS += comment; decodedGPS += comment;
@@ -153,30 +144,33 @@ namespace GPS_Utils {
} }
String getReceivedGPS(const String& packet) { String getReceivedGPS(const String& packet) {
int indexOfExclamation = packet.indexOf(":!");
int indexOfEqual = packet.indexOf(":=");
int indexOfAt = packet.indexOf(":@");
String infoGPS; String infoGPS;
if (indexOfExclamation > 10) { if (packet.indexOf(":!") > 10) {
infoGPS = packet.substring(indexOfExclamation + 2); infoGPS = packet.substring(packet.indexOf(":!") + 2);
} else if (indexOfEqual > 10) { } else if (packet.indexOf(":=") > 10) {
infoGPS = packet.substring(indexOfEqual + 2); infoGPS = packet.substring(packet.indexOf(":=") + 2);
} else if (indexOfAt > 10) {
infoGPS = packet.substring(indexOfAt + 9); // 9 = 2+7 (when 7 is timestamp characters)
} }
const String& Latitude = infoGPS.substring(0,8);
const String& Longitude = infoGPS.substring(9,18);
const String& comment = infoGPS.substring(19);
float convertedLatitude, convertedLongitude;
const String& firstLatPart = Latitude.substring(0,2);
const String& secondLatPart = Latitude.substring(2,4);
const String& thirdLatPart = Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3);
convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100));
String Latitude = infoGPS.substring(0,8); // First 8 characters are Latitude const String& firstLngPart = Longitude.substring(0,3);
float convertedLatitude = Latitude.substring(0,2).toFloat(); // First 2 digits (Degrees) const String& secondLngPart = Longitude.substring(3,5);
convertedLatitude += Latitude.substring(2,4).toFloat() / 60; // Next 2 digits (Minutes) const String& thirdLngPart = Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3);
convertedLatitude += Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3).toFloat() / (60*100); convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100));
if (Latitude.endsWith("S")) convertedLatitude = -convertedLatitude; // Handle Southern Hemisphere
if (String(Latitude[7]) == "S") {
String Longitude = infoGPS.substring(9,18); // Next 9 characters are Longitude convertedLatitude = -convertedLatitude;
float convertedLongitude = Longitude.substring(0,3).toFloat(); // First 3 digits (Degrees) }
convertedLongitude += Longitude.substring(3,5).toFloat() / 60; // Next 2 digits (Minutes) if (String(Longitude[8]) == "W") {
convertedLongitude += Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3).toFloat() / (60*100); convertedLongitude = -convertedLongitude;
if (Longitude.endsWith("W")) convertedLongitude = -convertedLongitude; // Handle Western Hemisphere }
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1); distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
@@ -187,7 +181,6 @@ namespace GPS_Utils {
decodedGPS += distance; decodedGPS += distance;
decodedGPS += "km"; decodedGPS += "km";
String comment = infoGPS.substring(19);
if (comment != "") { if (comment != "") {
decodedGPS += " / "; decodedGPS += " / ";
decodedGPS += comment; decodedGPS += comment;
@@ -196,30 +189,22 @@ namespace GPS_Utils {
} }
String getDistanceAndComment(const String& packet) { String getDistanceAndComment(const String& packet) {
int indexOfAt = packet.indexOf(":@"); uint8_t encodedBytePosition = 0;
if (indexOfAt > 10) { if (packet.indexOf(":!") > 10) {
return getReceivedGPS(packet); encodedBytePosition = packet.indexOf(":!") + 14;
} else { }
const uint8_t ENCODED_BYTE_OFFSET = 14; // Offset for encoded data in the packet if (packet.indexOf(":=") > 10) {
int indexOfExclamation = packet.indexOf(":!"); encodedBytePosition = packet.indexOf(":=") + 14;
int indexOfEqual = packet.indexOf(":="); }
uint8_t encodedBytePosition = 0; if (encodedBytePosition != 0) {
if (indexOfExclamation > 10) { // Determine the position where encoded data starts char currentChar = packet[encodedBytePosition];
encodedBytePosition = indexOfExclamation + ENCODED_BYTE_OFFSET; if (currentChar == 'G' || currentChar == 'Q' || currentChar == '[' || currentChar == 'H' || currentChar == 'X') {
} else if (indexOfEqual > 10) { return decodeEncodedGPS(packet);
encodedBytePosition = indexOfEqual + ENCODED_BYTE_OFFSET;
}
if (encodedBytePosition != 0) {
char currentChar = packet[encodedBytePosition];
if (currentChar == 'G' || currentChar == 'Q' || currentChar == '[' || currentChar == 'H' || currentChar == 'X') {
return decodeEncodedGPS(packet); // If valid encoded data position is found, decode it
} else {
return getReceivedGPS(packet);
}
} else { } else {
return " _ / _ / _ "; return getReceivedGPS(packet);
} }
} else {
return " _ / _ / _ ";
} }
} }
-1
View File
@@ -1,7 +1,6 @@
#include <Arduino.h> #include <Arduino.h>
#include "kiss_protocol.h" #include "kiss_protocol.h"
bool validateTNC2Frame(const String& tnc2FormattedFrame) { bool validateTNC2Frame(const String& tnc2FormattedFrame) {
return (tnc2FormattedFrame.indexOf(':') != -1) && (tnc2FormattedFrame.indexOf('>') != -1); return (tnc2FormattedFrame.indexOf(':') != -1) && (tnc2FormattedFrame.indexOf('>') != -1);
} }
+18 -26
View File
@@ -2,14 +2,12 @@
#include <WiFi.h> #include <WiFi.h>
#include "configuration.h" #include "configuration.h"
#include "aprs_is_utils.h" #include "aprs_is_utils.h"
#include "station_utils.h"
#include "board_pinout.h" #include "board_pinout.h"
#include "syslog_utils.h" #include "syslog_utils.h"
#include "ntp_utils.h" #include "ntp_utils.h"
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastRxTime; extern uint32_t lastRxTime;
@@ -184,33 +182,27 @@ namespace LoRa_Utils {
int state = radio.readData(packet); int state = radio.readData(packet);
if (state == RADIOLIB_ERR_NONE) { if (state == RADIOLIB_ERR_NONE) {
if (packet != "") { if (packet != "") {
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) + ")");
String sender = packet.substring(3, packet.indexOf(">")); if (!Config.lowPowerMode && !Config.digi.ecoMode) {
if (packet.substring(0,3) == "\x3c\xff\x01" && !STATION_Utils::isBlacklisted(sender)){ // avoid processing BlackListed stations if (receivedPackets.size() >= 10) {
rssi = radio.getRSSI(); receivedPackets.erase(receivedPackets.begin());
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) + ")");
if (!Config.lowPowerMode && !Config.digi.ecoMode) {
if (receivedPackets.size() >= 10) {
receivedPackets.erase(receivedPackets.begin());
}
ReceivedPacket receivedPacket;
receivedPacket.rxTime = NTP_Utils::getFormatedTime();
receivedPacket.packet = packet.substring(3);
receivedPacket.RSSI = rssi;
receivedPacket.SNR = snr;
receivedPackets.push_back(receivedPacket);
} }
ReceivedPacket receivedPacket;
receivedPacket.rxTime = NTP_Utils::getFormatedTime();
receivedPacket.packet = packet.substring(3);
receivedPacket.RSSI = rssi;
receivedPacket.SNR = snr;
receivedPackets.push_back(receivedPacket);
}
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) { if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
} }
} else {
packet = "";
}
lastRxTime = millis(); lastRxTime = millis();
return packet; return packet;
} }
-1
View File
@@ -5,7 +5,6 @@
#include "ota_utils.h" #include "ota_utils.h"
#include "display.h" #include "display.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastScreenOn; extern uint32_t lastScreenOn;
extern bool isUpdatingOTA; extern bool isUpdatingOTA;
+12 -55
View File
@@ -4,17 +4,9 @@
#include "power_utils.h" #include "power_utils.h"
#if defined(HAS_AXP192) || defined(HAS_AXP2101) #if defined(HAS_AXP192) || defined(HAS_AXP2101)
#ifdef TTGO_T_Beam_S3_SUPREME_V3 #define I2C_SDA 21
#define I2C0_SDA 17 #define I2C_SCL 22
#define I2C0_SCL 18 #define IRQ_PIN 35
#define I2C1_SDA 42
#define I2C1_SCL 41
#define IRQ_PIN 40
#else
#define I2C_SDA 21
#define I2C_SCL 22
#define IRQ_PIN 35
#endif
#endif #endif
#ifdef HAS_AXP192 #ifdef HAS_AXP192
@@ -62,13 +54,8 @@ namespace POWER_Utils {
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.setALDO4Voltage(3300);
PMU.enableALDO4();
#else
PMU.setALDO3Voltage(3300); PMU.setALDO3Voltage(3300);
PMU.enableALDO3(); PMU.enableALDO3();
#endif
#endif #endif
#ifdef HELTEC_WIRELESS_TRACKER #ifdef HELTEC_WIRELESS_TRACKER
digitalWrite(VEXT_CTRL, HIGH); digitalWrite(VEXT_CTRL, HIGH);
@@ -82,11 +69,7 @@ namespace POWER_Utils {
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
#ifdef TTGO_T_Beam_S3_SUPREME_V3 PMU.disableALDO3();
PMU.disableALDO4();
#else
PMU.disableALDO3();
#endif
#endif #endif
#ifdef HELTEC_WIRELESS_TRACKER #ifdef HELTEC_WIRELESS_TRACKER
digitalWrite(VEXT_CTRL, LOW); digitalWrite(VEXT_CTRL, LOW);
@@ -100,13 +83,8 @@ namespace POWER_Utils {
PMU.enableLDO2(); PMU.enableLDO2();
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
#ifdef TTGO_T_Beam_S3_SUPREME_V3 PMU.setALDO2Voltage(3300);
PMU.setALDO3Voltage(3300); PMU.enableALDO2();
PMU.enableALDO3();
#else
PMU.setALDO2Voltage(3300);
PMU.enableALDO2();
#endif
#endif #endif
} }
@@ -115,11 +93,7 @@ namespace POWER_Utils {
PMU.disableLDO2(); PMU.disableLDO2();
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
#ifdef TTGO_T_Beam_S3_SUPREME_V3 PMU.disableALDO2();
PMU.disableALDO3();
#else
PMU.disableALDO2();
#endif
#endif #endif
} }
@@ -137,29 +111,20 @@ namespace POWER_Utils {
} }
return result; return result;
#elif defined(HAS_AXP2101) #elif defined(HAS_AXP2101)
#ifdef TTGO_T_Beam_S3_SUPREME_V3 bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
bool result = PMU.begin(Wire1, AXP2101_SLAVE_ADDRESS, I2C1_SDA, I2C1_SCL);
#else
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
#endif
if (result) { if (result) {
PMU.disableDC2(); PMU.disableDC2();
PMU.disableDC3(); PMU.disableDC3();
PMU.disableDC4(); PMU.disableDC4();
PMU.disableDC5(); PMU.disableDC5();
#ifndef TTGO_T_Beam_S3_SUPREME_V3 PMU.disableALDO1();
PMU.disableALDO1(); PMU.disableALDO4();
PMU.disableALDO4();
#endif
PMU.disableBLDO1(); PMU.disableBLDO1();
PMU.disableBLDO2(); PMU.disableBLDO2();
PMU.disableDLDO1(); PMU.disableDLDO1();
PMU.disableDLDO2(); PMU.disableDLDO2();
PMU.setDC1Voltage(3300); PMU.setDC1Voltage(3300);
PMU.enableDC1(); PMU.enableDC1();
#ifdef TTGO_T_Beam_S3_SUPREME_V3
PMU.setALDO1Voltage(3300);
#endif
PMU.setButtonBatteryChargeVoltage(3300); PMU.setButtonBatteryChargeVoltage(3300);
PMU.enableButtonBatteryCharge(); PMU.enableButtonBatteryCharge();
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ); PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
@@ -187,16 +152,8 @@ namespace POWER_Utils {
#endif #endif
#ifdef HAS_AXP2101 #ifdef HAS_AXP2101
bool beginStatus = false; Wire.begin(SDA, SCL);
#ifdef TTGO_T_Beam_S3_SUPREME_V3 if (begin(Wire)) {
Wire1.begin(I2C1_SDA, I2C1_SCL);
Wire.begin(I2C0_SDA, I2C0_SCL);
if (begin(Wire1)) beginStatus = true;
#else
Wire.begin(SDA, SCL);
if (begin(Wire)) beginStatus = true;
#endif
if (beginStatus) {
Serial.println("AXP2101 init done!"); Serial.println("AXP2101 init done!");
} else { } else {
Serial.println("AXP2101 init failed!"); Serial.println("AXP2101 init failed!");
+18 -63
View File
@@ -22,9 +22,9 @@ namespace QUERY_Utils {
String queryQuestion = query; String queryQuestion = query;
queryQuestion.toUpperCase(); queryQuestion.toUpperCase();
if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") { if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
answer.concat("?APRSV ?APRSP ?APRSL ?APRSSSR ?EM=? ?TX=? "); // ?APRSH ?WHERE callsign answer.concat("?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign");
} else if (queryQuestion == "?APRSV") { } else if (queryQuestion == "?APRSV") {
answer.concat("CA2RXU_LoRa_iGate 2.3 v"); answer.concat("CA2RXU_LoRa_iGate 2.0 v");
answer.concat(versionDate); answer.concat(versionDate);
} else if (queryQuestion == "?APRSP") { } else if (queryQuestion == "?APRSP") {
answer.concat("iGate QTH: "); answer.concat("iGate QTH: ");
@@ -46,69 +46,29 @@ namespace QUERY_Utils {
char signalData[35]; char signalData[35];
snprintf(signalData, sizeof(signalData), " %ddBm / %.2fdB / %dHz", rssi, snr, freqError); snprintf(signalData, sizeof(signalData), " %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
answer.concat(signalData); answer.concat(signalData);
} /*else if (queryQuestion.indexOf("?APRSH") == 0) { } else if (queryQuestion.indexOf("?APRSH") == 0) {
// sacar callsign despues de ?APRSH // sacar callsign despues de ?APRSH
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?"); Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
answer.concat("?APRSH on development 73!"); answer.concat("?APRSH on development 73!");
} *//*else if (queryQuestion.indexOf("?WHERE") == 0) { } else if (queryQuestion.indexOf("?WHERE") == 0) {
// agregar callsign para completar donde esta X callsign --> posicion // agregar callsign para completar donde esta X callsign --> posicion
Serial.println("estaciones escuchadas directo (ultimos 30 min)"); Serial.println("estaciones escuchadas directo (ultimos 30 min)");
answer.concat("?WHERE on development 73!"); answer.concat("?WHERE on development 73!");
} */ } else if (queryQuestion.indexOf("?APRSEEM") == 0 && Config.digi.ecoMode == true) { // Exit Digipeater EcoMode
else if (STATION_Utils::isManager(station) && (!queryFromAPRSIS || !Config.remoteManagement.rfOnly)) { answer = "DigiEcoMode:Stop";
if (queryQuestion.indexOf("?EM=OFF") == 0) { Config.digi.ecoMode = false;
if ((Config.digi.mode == 2 || Config.digi.mode == 3) && Config.loramodule.txActive && Config.loramodule.rxActive && !Config.aprs_is.active) { Config.display.alwaysOn = true;
if (Config.digi.ecoMode) { // Exit Digipeater EcoMode Config.display.timeout = 10;
answer = "DigiEcoMode:OFF"; shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
Config.digi.ecoMode = false; saveNewDigiEcoModeConfig = true;
Config.display.alwaysOn = true; } else if (queryQuestion.indexOf("?APRSSEM") == 0 && Config.digi.ecoMode == false) { // Start Digipeater EcoMode
Config.display.timeout = 10; answer = "DigiEcoMode:Start";
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart. Config.digi.ecoMode = true;
saveNewDigiEcoModeConfig = true; shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
} else { saveNewDigiEcoModeConfig = true;
answer = "DigiEcoMode was OFF"; } else if (queryQuestion.indexOf("?APRSEMS") == 0) { // Digipeater EcoMode Status
} answer = (Config.digi.ecoMode) ? "DigiEcoMode:ON" : "DigiEcoMode:OFF";
} else {
answer = "DigiEcoMode 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) { // Start Digipeater EcoMode
answer = "DigiEcoMode:ON";
Config.digi.ecoMode = true;
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
saveNewDigiEcoModeConfig = true;
} else {
answer = "DigiEcoMode was ON";
}
} else {
answer = "DigiEcoMode control not possible";
}
} else if (queryQuestion.indexOf("?EM=?") == 0) { // Digipeater EcoMode Status
answer = (Config.digi.ecoMode) ? "DigiEcoMode:ON" : "DigiEcoMode:OFF";
} else if (queryQuestion.indexOf("?TX=ON") == 0) {
if (Config.loramodule.txActive) {
answer = "TX was ON";
} else {
Config.loramodule.txActive = true;
answer = "TX=ON";
}
} else if (queryQuestion.indexOf("?TX=OFF") == 0) {
if (!Config.loramodule.txActive) {
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
answer = "New Config Saved";
Config.writeFile();
}
} }
if (answer == "") return "";
String queryAnswer = Config.callsign; String queryAnswer = Config.callsign;
queryAnswer += ">APLRG1"; queryAnswer += ">APLRG1";
@@ -130,11 +90,6 @@ namespace QUERY_Utils {
queryAnswer += processedStation; queryAnswer += processedStation;
queryAnswer += ":"; queryAnswer += ":";
queryAnswer += answer; queryAnswer += answer;
queryAnswer += " *";
queryAnswer += char(random(97, 123));
queryAnswer += char(random(97, 123));
queryAnswer += "*";
return queryAnswer; return queryAnswer;
} }
+17 -40
View File
@@ -7,7 +7,6 @@
#include "utils.h" #include "utils.h"
#include <vector> #include <vector>
extern Configuration Config; extern Configuration Config;
extern uint32_t lastRxTime; extern uint32_t lastRxTime;
extern String fourthLine; extern String fourthLine;
@@ -17,8 +16,7 @@ uint32_t lastTxTime = millis();
std::vector<LastHeardStation> lastHeardStations; std::vector<LastHeardStation> lastHeardStations;
std::vector<String> outputPacketBuffer; std::vector<String> outputPacketBuffer;
std::vector<Packet25SegBuffer> packet25SegBuffer; std::vector<Packet25SegBuffer> packet25SegBuffer;
std::vector<String> blacklist; std::vector<String> blackList;
std::vector<String> managers;
std::vector<LastHeardStation> lastHeardObjects; std::vector<LastHeardStation> lastHeardObjects;
bool saveNewDigiEcoModeConfig = false; bool saveNewDigiEcoModeConfig = false;
@@ -26,52 +24,31 @@ bool saveNewDigiEcoModeConfig = false;
namespace STATION_Utils { namespace STATION_Utils {
std::vector<String> loadCallSignList(const String& list) { void loadBlackList() {
std::vector<String> loadedList; if (Config.blackList != "") {
String callsigns = Config.blackList;
int spaceIndex = callsigns.indexOf(" ");
String callsigns = list; while (spaceIndex >= 0) {
callsigns.trim(); blackList.push_back(callsigns.substring(0, spaceIndex));
callsigns = callsigns.substring(spaceIndex + 1);
while (callsigns.length() > 0) { // != "" spaceIndex = callsigns.indexOf(" ");
int spaceIndex = callsigns.indexOf(" ");
if (spaceIndex == -1) { // No more spaces, add the last part
loadedList.push_back(callsigns);
break;
} }
loadedList.push_back(callsigns.substring(0, spaceIndex)); callsigns.trim();
callsigns = callsigns.substring(spaceIndex + 1); if (callsigns.length() > 0) blackList.push_back(callsigns); // Add the last word if available
callsigns.trim(); // Trim in case of multiple spaces
} }
return loadedList;
} }
void loadBlacklist() { bool checkBlackList(const String& callsign) {
blacklist = loadCallSignList(Config.blacklist); for (int i = 0; i < blackList.size(); i++) {
} if (blackList[i].indexOf("*") >= 0) { // use wild card
String wildCard = blackList[i].substring(0, blackList[i].indexOf("*"));
void loadManagers() { if (callsign.startsWith(wildCard))return true;
managers = loadCallSignList(Config.remoteManagement.managers);
}
bool checkCallsignList(const std::vector<String>& list, const String& callsign) {
for (int i = 0; i < list.size(); i++) {
int wildcardIndex = list[i].indexOf("*");
if (wildcardIndex >= 0) {
String wildcard = list[i].substring(0, wildcardIndex);
if (callsign.startsWith(wildcard)) return true;
} else { } else {
if (list[i] == callsign) return true; if (blackList[i] == callsign) return true;
} }
} }
return false; return false;
}
bool isBlacklisted(const String& callsign) {
return checkCallsignList(blacklist, callsign);
}
bool isManager(const String& callsign) {
return checkCallsignList(managers, callsign);
} }
void cleanObjectsHeard() { void cleanObjectsHeard() {
+4 -6
View File
@@ -4,7 +4,6 @@
#include "syslog_utils.h" #include "syslog_utils.h"
#include "gps_utils.h" #include "gps_utils.h"
extern Configuration Config; extern Configuration Config;
WiFiUDP udpClient; WiFiUDP udpClient;
@@ -38,16 +37,15 @@ namespace SYSLOG_Utils {
syslogPacket.concat(sender); syslogPacket.concat(sender);
syslogPacket.concat(" ---> "); syslogPacket.concat(" ---> ");
syslogPacket.concat(packet.substring(colonIndex + 2)); syslogPacket.concat(packet.substring(colonIndex + 2));
} else if (nextChar == '!' || nextChar == '=' || nextChar == '@') { } else if (nextChar == '!' || nextChar == '=') {
syslogPacket.concat("GPS / "); syslogPacket.concat("GPS / ");
syslogPacket.concat(sender); syslogPacket.concat(sender);
syslogPacket.concat(" / "); syslogPacket.concat(" / ");
int greaterThanIndex = packet.indexOf(">");
if (packet.indexOf("WIDE1-1") > 10) { if (packet.indexOf("WIDE1-1") > 10) {
syslogPacket.concat(packet.substring(greaterThanIndex + 1, packet.indexOf(","))); syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(",")));
syslogPacket.concat(" / WIDE1-1"); syslogPacket.concat(" / WIDE1-1");
} else { } else {
syslogPacket.concat(packet.substring(greaterThanIndex + 1, colonIndex)); syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, colonIndex));
syslogPacket.concat(" / -"); syslogPacket.concat(" / -");
} }
} else if (nextChar == '>') { } else if (nextChar == '>') {
@@ -74,7 +72,7 @@ namespace SYSLOG_Utils {
syslogPacket.concat(packet); syslogPacket.concat(packet);
} }
syslogPacket.concat(signalData); syslogPacket.concat(signalData);
if (nextChar == '!' || nextChar == '=' || nextChar == '@') { if (nextChar == '!' || nextChar == '=') {
syslogPacket.concat(" / "); syslogPacket.concat(" / ");
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet)); syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
} }
-1
View File
@@ -5,7 +5,6 @@
#include "station_utils.h" #include "station_utils.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
#define MAX_CLIENTS 4 #define MAX_CLIENTS 4
+1 -5
View File
@@ -5,7 +5,6 @@
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint32_t lastBeaconTx; extern uint32_t lastBeaconTx;
extern std::vector<ReceivedPacket> receivedPackets; extern std::vector<ReceivedPacket> receivedPackets;
@@ -207,7 +206,7 @@ namespace WEB_Utils {
Config.personalNote = request->getParam("personalNote", true)->value(); Config.personalNote = request->getParam("personalNote", true)->value();
Config.blacklist = request->getParam("blacklist", true)->value(); Config.blackList = request->getParam("blackList", true)->value();
Config.webadmin.active = request->hasParam("webadmin.active", true); Config.webadmin.active = request->hasParam("webadmin.active", true);
if (Config.webadmin.active) { if (Config.webadmin.active) {
@@ -217,9 +216,6 @@ namespace WEB_Utils {
Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toFloat(); Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toFloat();
Config.remoteManagement.managers = request->getParam("remoteManagement.managers", true)->value();
Config.remoteManagement.rfOnly = request->getParam("remoteManagement.rfOnly", true);
Config.writeFile(); Config.writeFile();
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", ""); AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
-1
View File
@@ -5,7 +5,6 @@
#include "display.h" #include "display.h"
#include "utils.h" #include "utils.h"
extern Configuration Config; extern Configuration Config;
extern uint8_t myWiFiAPIndex; extern uint8_t myWiFiAPIndex;
+1
View File
@@ -31,6 +31,7 @@ Adafruit_Si7021 sensor = Adafruit_Si7021();
#endif #endif
namespace WX_Utils { namespace WX_Utils {
void getWxModuleAddres() { void getWxModuleAddres() {
@@ -4,7 +4,5 @@ board_build.mcu = esp32s3
build_flags = build_flags =
${common.build_flags} ${common.build_flags}
-D HELTEC_WP -D HELTEC_WP
-D WIRELESS_PAPER
lib_deps = lib_deps =
${common.lib_deps} ${common.lib_deps}
todd-herbert/heltec-eink-modules@^4.4.0
@@ -1,37 +0,0 @@
#ifndef BOARD_PINOUT_H_
#define BOARD_PINOUT_H_
// LoRa Radio
#define HAS_SX1262
#define RADIO_SCLK_PIN 12
#define RADIO_MISO_PIN 13
#define RADIO_MOSI_PIN 11
#define RADIO_CS_PIN 10
#define RADIO_DIO0_PIN -1
#define RADIO_RST_PIN 5
#define RADIO_DIO1_PIN 1
#define RADIO_BUSY_PIN 4
// Display
#define HAS_DISPLAY
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
#define OLED_SDA 17
#define OLED_SCL 18
#define OLED_RST 16
#define OLED_DISPLAY_HAS_RST_PIN
// Aditional Config
#define HAS_AXP2101
// GPS
#define HAS_GPS
#define GPS_RX 8
#define GPS_TX 9
#define BOARD_HAS_PSRAM
#endif
@@ -1,12 +0,0 @@
[env:ttgo_t_beam_s3_SUPREME_v3]
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
build_flags =
${common.build_flags}
${common.usb_flags}
-D TTGO_T_Beam_S3_SUPREME_V3
lib_deps =
${common.lib_deps}
${common.display_libs}
lewisxhe/XPowersLib @ 0.2.4
adafruit/Adafruit SH110X @ 2.1.10