forked from iarv/LoRa_APRS_iGate
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d65b2c93f | |||
| 83a39c2093 | |||
| bc596f099d | |||
| 438a6ee536 | |||
| 206c79f0a9 | |||
| 236cfa724e |
@@ -16,7 +16,9 @@
|
|||||||
"symbol": "a",
|
"symbol": "a",
|
||||||
"path": "WIDE1-1",
|
"path": "WIDE1-1",
|
||||||
"sendViaAPRSIS": false,
|
"sendViaAPRSIS": false,
|
||||||
"sendViaRF": false
|
"sendViaRF": false,
|
||||||
|
"statusActive": false,
|
||||||
|
"statusPacket": ""
|
||||||
},
|
},
|
||||||
"aprs_is": {
|
"aprs_is": {
|
||||||
"active": false,
|
"active": false,
|
||||||
@@ -66,7 +68,8 @@
|
|||||||
"syslog": {
|
"syslog": {
|
||||||
"active": false,
|
"active": false,
|
||||||
"server": "lora.link9.net",
|
"server": "lora.link9.net",
|
||||||
"port": 1514
|
"port": 1514,
|
||||||
|
"logBeaconOverTCPIP": false
|
||||||
},
|
},
|
||||||
"tnc": {
|
"tnc": {
|
||||||
"enableServer": false,
|
"enableServer": false,
|
||||||
|
|||||||
+45
-1
@@ -253,7 +253,36 @@
|
|||||||
name="personalNote"
|
name="personalNote"
|
||||||
id="personalNote"
|
id="personalNote"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="A Couple of words."
|
placeholder="A couple of words"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 mt-3">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="beacon.statusActive"
|
||||||
|
id="beacon.statusActive"
|
||||||
|
class="form-check-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="beacon.statusActive"
|
||||||
|
class="form-label"
|
||||||
|
>Send Status at each Boot</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<label
|
||||||
|
for="beacon.statusPacket"
|
||||||
|
class="form-label"
|
||||||
|
>Status</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="beacon.statusPacket"
|
||||||
|
id="beacon.statusPacket"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="Custom Status"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1368,6 +1397,21 @@
|
|||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="syslog.logBeaconOverTCPIP"
|
||||||
|
id="syslog.logBeaconOverTCPIP"
|
||||||
|
class="form-check-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="syslog.logBeaconOverTCPIP"
|
||||||
|
class="form-label"
|
||||||
|
>Log Beacon over TPCIP</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+14
-7
@@ -62,13 +62,15 @@ alwaysOnCheckbox.addEventListener("change", function () {
|
|||||||
// alwaysOnCheckbox.disabled = this.value !== "";
|
// alwaysOnCheckbox.disabled = this.value !== "";
|
||||||
// });
|
// });
|
||||||
|
|
||||||
const logCheckbox = document.querySelector('input[name="syslog.active"]');
|
const logCheckbox = document.querySelector('input[name="syslog.active"]');
|
||||||
const serverField = document.querySelector('input[name="syslog.server"]');
|
const serverField = document.querySelector('input[name="syslog.server"]');
|
||||||
const portField = document.querySelector('input[name="syslog.port"]');
|
const portField = document.querySelector('input[name="syslog.port"]');
|
||||||
|
const logBeaconOverTCPIPField = document.querySelector('input[name="syslog.logBeaconOverTCPIP"]');
|
||||||
|
|
||||||
logCheckbox.addEventListener("change", function () {
|
logCheckbox.addEventListener("change", function () {
|
||||||
serverField.disabled = !this.checked;
|
serverField.disabled = !this.checked;
|
||||||
portField.disabled = !this.checked;
|
portField.disabled = !this.checked;
|
||||||
|
logBeaconOverTCPIPField.disabled = !this.checked
|
||||||
});
|
});
|
||||||
|
|
||||||
function loadSettings(settings) {
|
function loadSettings(settings) {
|
||||||
@@ -134,6 +136,9 @@ function loadSettings(settings) {
|
|||||||
document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS;
|
document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS;
|
||||||
document.getElementById("beacon.sendViaRF").checked = settings.beacon.sendViaRF;
|
document.getElementById("beacon.sendViaRF").checked = settings.beacon.sendViaRF;
|
||||||
|
|
||||||
|
document.getElementById("beacon.statusActive").checked = settings.beacon.statusActive;
|
||||||
|
document.getElementById("beacon.statusPacket").value = settings.beacon.statusPacket;
|
||||||
|
|
||||||
document.getElementById("beacon.gpsActive").checked = settings.beacon.gpsActive;
|
document.getElementById("beacon.gpsActive").checked = settings.beacon.gpsActive;
|
||||||
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
|
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
|
||||||
|
|
||||||
@@ -184,10 +189,12 @@ function loadSettings(settings) {
|
|||||||
document.getElementById("syslog.active").checked = settings.syslog.active;
|
document.getElementById("syslog.active").checked = settings.syslog.active;
|
||||||
document.getElementById("syslog.server").value = settings.syslog.server;
|
document.getElementById("syslog.server").value = settings.syslog.server;
|
||||||
document.getElementById("syslog.port").value = settings.syslog.port;
|
document.getElementById("syslog.port").value = settings.syslog.port;
|
||||||
|
document.getElementById("syslog.logBeaconOverTCPIP").checked = settings.syslog.logBeaconOverTCPIP;
|
||||||
|
|
||||||
if (settings.syslog.active) {
|
if (settings.syslog.active) {
|
||||||
serverField.disabled = false;
|
serverField.disabled = false;
|
||||||
portField.disabled = false;
|
portField.disabled = false;
|
||||||
|
logBeaconOverTCPIPField.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TNC
|
// TNC
|
||||||
|
|||||||
@@ -35,11 +35,16 @@ namespace APRS_IS_Utils {
|
|||||||
void processLoRaPacket(const String& packet);
|
void processLoRaPacket(const String& packet);
|
||||||
|
|
||||||
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType);
|
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType);
|
||||||
void processAPRSISPacket(const String& packet);
|
void processAPRSISPacket();//const String& packet);
|
||||||
void listenAPRSIS();
|
void listenAPRSIS();
|
||||||
|
|
||||||
void firstConnection();
|
void firstConnection();
|
||||||
|
|
||||||
|
bool startListenerAPRSISTask(uint32_t stackSize = 8192, UBaseType_t priority = 1);
|
||||||
|
void stopListenerAPRSISTask();
|
||||||
|
void suspendListenerAPRSISTask();
|
||||||
|
void resumeListenerAPRSISTask();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -49,6 +49,8 @@ public:
|
|||||||
bool sendViaAPRSIS;
|
bool sendViaAPRSIS;
|
||||||
bool gpsActive;
|
bool gpsActive;
|
||||||
bool gpsAmbiguity;
|
bool gpsAmbiguity;
|
||||||
|
bool statusActive;
|
||||||
|
String statusPacket;
|
||||||
};
|
};
|
||||||
|
|
||||||
class APRS_IS {
|
class APRS_IS {
|
||||||
@@ -113,6 +115,7 @@ public:
|
|||||||
bool active;
|
bool active;
|
||||||
String server;
|
String server;
|
||||||
int port;
|
int port;
|
||||||
|
bool logBeaconOverTCPIP;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TNC {
|
class TNC {
|
||||||
|
|||||||
+36
-2
@@ -66,7 +66,7 @@ ___________________________________________________________________*/
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
String versionDate = "2025-08-04";
|
String versionDate = "2025-08-20";
|
||||||
Configuration Config;
|
Configuration Config;
|
||||||
WiFiClient espClient;
|
WiFiClient espClient;
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
@@ -96,6 +96,11 @@ 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
|
||||||
|
|
||||||
|
#ifdef HAS_TWO_CORES
|
||||||
|
QueueHandle_t aprsIsTxQueue = NULL;
|
||||||
|
QueueHandle_t aprsIsRxQueue = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
@@ -122,11 +127,39 @@ void setup() {
|
|||||||
A7670_Utils::setup();
|
A7670_Utils::setup();
|
||||||
#endif
|
#endif
|
||||||
Utils::checkRebootMode();
|
Utils::checkRebootMode();
|
||||||
|
|
||||||
APRS_IS_Utils::firstConnection();
|
APRS_IS_Utils::firstConnection();
|
||||||
SLEEP_Utils::checkSerial();
|
SLEEP_Utils::checkSerial();
|
||||||
|
|
||||||
|
// Crear queues con verificación detallada
|
||||||
|
//Serial.println("Creando aprsIsTxQueue...");
|
||||||
|
aprsIsTxQueue = xQueueCreate(50, sizeof(String));
|
||||||
|
//Serial.printf("aprsIsTxQueue = %p\n", aprsIsTxQueue);
|
||||||
|
|
||||||
|
//Serial.println("Creando aprsIsRxQueue...");
|
||||||
|
aprsIsRxQueue = xQueueCreate(50, sizeof(String));
|
||||||
|
//Serial.printf("aprsIsRxQueue = %p\n", aprsIsRxQueue);
|
||||||
|
|
||||||
|
// Verificación crítica
|
||||||
|
if (aprsIsRxQueue == NULL || aprsIsTxQueue == NULL) {
|
||||||
|
Serial.println("FATAL: Error creando queues!");
|
||||||
|
while(1) {
|
||||||
|
Serial.println("STUCK - Queues failed");
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.println("Queues creadas OK");
|
||||||
|
|
||||||
|
// Iniciar el task de APRSIS
|
||||||
|
if (!APRS_IS_Utils::startListenerAPRSISTask()) {
|
||||||
|
Serial.println("Error: No se pudo crear el task de APRSIS");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
//Serial.println("Loop tick: " + String(millis()));
|
||||||
|
//delay(1000);
|
||||||
|
|
||||||
if (Config.digi.ecoMode == 1) {
|
if (Config.digi.ecoMode == 1) {
|
||||||
SLEEP_Utils::checkWakeUpFlag();
|
SLEEP_Utils::checkWakeUpFlag();
|
||||||
Utils::checkBeaconInterval();
|
Utils::checkBeaconInterval();
|
||||||
@@ -201,7 +234,8 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Config.aprs_is.active) {
|
if (Config.aprs_is.active) {
|
||||||
APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
|
APRS_IS_Utils::processAPRSISPacket();
|
||||||
|
//APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
|
||||||
}
|
}
|
||||||
|
|
||||||
STATION_Utils::processOutputPacketBuffer();
|
STATION_Utils::processOutputPacketBuffer();
|
||||||
|
|||||||
+151
-82
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern WiFiClient espClient;
|
extern WiFiClient espClient;
|
||||||
|
extern QueueHandle_t aprsIsRxQueue;
|
||||||
extern uint32_t lastScreenOn;
|
extern uint32_t lastScreenOn;
|
||||||
extern String firstLine;
|
extern String firstLine;
|
||||||
extern String secondLine;
|
extern String secondLine;
|
||||||
@@ -52,6 +53,9 @@ bool passcodeValid = false;
|
|||||||
|
|
||||||
namespace APRS_IS_Utils {
|
namespace APRS_IS_Utils {
|
||||||
|
|
||||||
|
// Handle del task (opcional, para poder controlarlo después)
|
||||||
|
TaskHandle_t aprsisTaskHandle = NULL;
|
||||||
|
|
||||||
void upload(const String& line) {
|
void upload(const String& line) {
|
||||||
espClient.print(line + "\r\n");
|
espClient.print(line + "\r\n");
|
||||||
}
|
}
|
||||||
@@ -274,95 +278,103 @@ namespace APRS_IS_Utils {
|
|||||||
return outputPacket;
|
return outputPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
void processAPRSISPacket(const String& packet) {
|
//uint32_t lastLog = 0;
|
||||||
if (!passcodeValid && packet.indexOf(Config.callsign) != -1) {
|
void processAPRSISPacket() {
|
||||||
if (packet.indexOf("unverified") != -1 ) {
|
/*Serial.println("processAPRSISPacket");
|
||||||
Serial.println("\n****APRS PASSCODE NOT VALID****\n");
|
|
||||||
displayShow(firstLine, "", " APRS PASSCODE", " NOT VALID !!!", "", "", "", 0);
|
|
||||||
while (1) {};
|
|
||||||
} else if (packet.indexOf("verified") != -1 ) {
|
|
||||||
passcodeValid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (passcodeValid && !packet.startsWith("#")) {
|
|
||||||
if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) {
|
|
||||||
String Sender = packet.substring(0, packet.indexOf(">"));
|
|
||||||
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
|
|
||||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
|
||||||
Addressee.trim();
|
|
||||||
if (Addressee == Config.callsign) { // its for me!
|
|
||||||
String receivedMessage;
|
|
||||||
if (AddresseeAndMessage.indexOf("{") > 0) { // ack?
|
|
||||||
String ackMessage = "ack";
|
|
||||||
ackMessage += AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1);
|
|
||||||
ackMessage.trim();
|
|
||||||
delay(4000);
|
|
||||||
for (int i = Sender.length(); i < 9; i++) {
|
|
||||||
Sender += ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
String ackPacket = Config.callsign;
|
if (millis() - lastLog > 5000) { // Cada 5 segundos
|
||||||
ackPacket += ">APLRG1,TCPIP,qAC::";
|
UBaseType_t packets = uxQueueMessagesWaiting(aprsIsRxQueue);
|
||||||
ackPacket += Sender;
|
UBaseType_t spaces = uxQueueSpacesAvailable(aprsIsRxQueue);
|
||||||
ackPacket += ":";
|
Serial.printf("[STATS] APRSIS Queue: %d/%d (%.1f%% full)\n",
|
||||||
ackPacket += ackMessage;
|
packets, packets + spaces,
|
||||||
#ifdef HAS_A7670
|
(packets * 100.0) / (packets + spaces));
|
||||||
A7670_Utils::uploadToAPRSIS(ackPacket);
|
lastLog = millis();
|
||||||
#else
|
}*/
|
||||||
upload(ackPacket);
|
|
||||||
#endif
|
|
||||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{"));
|
String packet;
|
||||||
|
if (xQueueReceive(aprsIsRxQueue, &packet, 0) == pdTRUE) {
|
||||||
|
|
||||||
|
if (passcodeValid && !packet.startsWith("#")) {
|
||||||
|
if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) {
|
||||||
|
String Sender = packet.substring(0, packet.indexOf(">"));
|
||||||
|
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
|
||||||
|
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||||
|
Addressee.trim();
|
||||||
|
if (Addressee == Config.callsign) { // its for me!
|
||||||
|
String receivedMessage;
|
||||||
|
if (AddresseeAndMessage.indexOf("{") > 0) { // ack?
|
||||||
|
String ackMessage = "ack";
|
||||||
|
ackMessage += AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1);
|
||||||
|
ackMessage.trim();
|
||||||
|
delay(4000);
|
||||||
|
for (int i = Sender.length(); i < 9; i++) {
|
||||||
|
Sender += ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
String ackPacket = Config.callsign;
|
||||||
|
ackPacket += ">APLRG1,TCPIP,qAC::";
|
||||||
|
ackPacket += Sender;
|
||||||
|
ackPacket += ":";
|
||||||
|
ackPacket += ackMessage;
|
||||||
|
#ifdef HAS_A7670
|
||||||
|
A7670_Utils::uploadToAPRSIS(ackPacket);
|
||||||
|
#else
|
||||||
|
upload(ackPacket);
|
||||||
|
#endif
|
||||||
|
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{"));
|
||||||
|
} else {
|
||||||
|
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
|
||||||
|
}
|
||||||
|
if (receivedMessage.indexOf("?") == 0) {
|
||||||
|
Utils::println("Rx Query (APRS-IS) : " + packet);
|
||||||
|
Sender.trim();
|
||||||
|
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
|
||||||
|
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
|
||||||
|
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
||||||
|
displayToggle(true);
|
||||||
|
}
|
||||||
|
lastScreenOn = millis();
|
||||||
|
delay(500);
|
||||||
|
#ifdef HAS_A7670
|
||||||
|
A7670_Utils::uploadToAPRSIS(queryAnswer);
|
||||||
|
#else
|
||||||
|
upload(queryAnswer);
|
||||||
|
#endif
|
||||||
|
SYSLOG_Utils::log(2, queryAnswer, 0, 0.0, 0); // APRSIS TX
|
||||||
|
fifthLine = "APRS-IS ----> APRS-IS";
|
||||||
|
sixthLine = Config.callsign;
|
||||||
|
for (int j = sixthLine.length();j < 9;j++) {
|
||||||
|
sixthLine += " ";
|
||||||
|
}
|
||||||
|
sixthLine += "> ";
|
||||||
|
sixthLine += Sender;
|
||||||
|
seventhLine = "QUERY = ";
|
||||||
|
seventhLine += receivedMessage;
|
||||||
|
}
|
||||||
|
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||||
} else {
|
} else {
|
||||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
|
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 (receivedMessage.indexOf("?") == 0) {
|
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
|
||||||
Utils::println("Rx Query (APRS-IS) : " + packet);
|
|
||||||
Sender.trim();
|
|
||||||
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
|
|
||||||
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
|
|
||||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
|
||||||
displayToggle(true);
|
displayToggle(true);
|
||||||
|
lastScreenOn = millis();
|
||||||
|
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
||||||
|
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||||
}
|
}
|
||||||
lastScreenOn = millis();
|
|
||||||
delay(500);
|
|
||||||
#ifdef HAS_A7670
|
|
||||||
A7670_Utils::uploadToAPRSIS(queryAnswer);
|
|
||||||
#else
|
|
||||||
upload(queryAnswer);
|
|
||||||
#endif
|
|
||||||
SYSLOG_Utils::log(2, queryAnswer, 0, 0.0, 0); // APRSIS TX
|
|
||||||
fifthLine = "APRS-IS ----> APRS-IS";
|
|
||||||
sixthLine = Config.callsign;
|
|
||||||
for (int j = sixthLine.length();j < 9;j++) {
|
|
||||||
sixthLine += " ";
|
|
||||||
}
|
|
||||||
sixthLine += "> ";
|
|
||||||
sixthLine += Sender;
|
|
||||||
seventhLine = "QUERY = ";
|
|
||||||
seventhLine += receivedMessage;
|
|
||||||
}
|
}
|
||||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
|
||||||
} else {
|
Utils::print("Rx Object (APRS-IS) : " + packet);
|
||||||
Utils::print("Rx Message (APRS-IS): " + packet);
|
if (STATION_Utils::checkObjectTime(packet)) {
|
||||||
if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) {
|
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
|
||||||
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
|
|
||||||
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);
|
Serial.println();
|
||||||
|
} else {
|
||||||
|
Serial.println(" ---> Rejected (Time): No Tx");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
|
|
||||||
Utils::print("Rx Object (APRS-IS) : " + packet);
|
|
||||||
if (STATION_Utils::checkObjectTime(packet)) {
|
|
||||||
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
|
|
||||||
displayToggle(true);
|
|
||||||
lastScreenOn = millis();
|
|
||||||
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
|
||||||
Serial.println();
|
|
||||||
} else {
|
|
||||||
Serial.println(" ---> Rejected (Time): No Tx");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -374,8 +386,9 @@ namespace APRS_IS_Utils {
|
|||||||
if (espClient.connected()) {
|
if (espClient.connected()) {
|
||||||
if (espClient.available()) {
|
if (espClient.available()) {
|
||||||
String aprsisPacket = espClient.readStringUntil('\r');
|
String aprsisPacket = espClient.readStringUntil('\r');
|
||||||
aprsisPacket.trim(); // Serial.println(aprsisPacket);
|
aprsisPacket.trim(); //Serial.println(aprsisPacket);
|
||||||
processAPRSISPacket(aprsisPacket);
|
xQueueSend(aprsIsRxQueue, &aprsisPacket, 0);
|
||||||
|
//processAPRSISPacket(aprsisPacket);
|
||||||
lastRxTime = millis();
|
lastRxTime = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -386,9 +399,65 @@ namespace APRS_IS_Utils {
|
|||||||
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) {
|
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) {
|
||||||
connect();
|
connect();
|
||||||
while (!passcodeValid) {
|
while (!passcodeValid) {
|
||||||
listenAPRSIS();
|
if (espClient.connected() && espClient.available()) {
|
||||||
|
String aprsisPacket = espClient.readStringUntil('\r');
|
||||||
|
aprsisPacket.trim();
|
||||||
|
if (!passcodeValid && aprsisPacket.indexOf(Config.callsign) != -1) {
|
||||||
|
if (aprsisPacket.indexOf("unverified") != -1 ) {
|
||||||
|
Serial.println("\n****APRS PASSCODE NOT VALID****\n");
|
||||||
|
displayShow(firstLine, "", " APRS PASSCODE", " NOT VALID !!!", "", "", "", 0);
|
||||||
|
while (1) {};
|
||||||
|
} else if (aprsisPacket.indexOf("verified") != -1 ) {
|
||||||
|
Serial.println("(APRS PASSCODE VALIDATED)");
|
||||||
|
passcodeValid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void aprsisListenerTask(void *parameter) {
|
||||||
|
while (true) {
|
||||||
|
listenAPRSIS();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10)); // 10ms delay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para iniciar el task
|
||||||
|
bool startListenerAPRSISTask(uint32_t stackSize, UBaseType_t priority) {
|
||||||
|
BaseType_t result = xTaskCreatePinnedToCore(
|
||||||
|
aprsisListenerTask, // Función del task
|
||||||
|
"APRSIS_Listener", // Nombre del task
|
||||||
|
stackSize, // Stack size en words (no bytes)
|
||||||
|
NULL, // Parámetro pasado al task
|
||||||
|
priority, // Prioridad
|
||||||
|
&aprsisTaskHandle, // Handle del task
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
return (result == pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función opcional para detener el task
|
||||||
|
void stopListenerAPRSISTask() {
|
||||||
|
if (aprsisTaskHandle != NULL) {
|
||||||
|
vTaskDelete(aprsisTaskHandle);
|
||||||
|
aprsisTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función opcional para suspender/reanudar el task
|
||||||
|
void suspendListenerAPRSISTask() {
|
||||||
|
if (aprsisTaskHandle != NULL) {
|
||||||
|
vTaskSuspend(aprsisTaskHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resumeListenerAPRSISTask() {
|
||||||
|
if (aprsisTaskHandle != NULL) {
|
||||||
|
vTaskResume(aprsisTaskHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+13
-1
@@ -62,6 +62,9 @@ void Configuration::writeFile() {
|
|||||||
data["beacon"]["sendViaRF"] = beacon.sendViaRF;
|
data["beacon"]["sendViaRF"] = beacon.sendViaRF;
|
||||||
data["beacon"]["path"] = beacon.path;
|
data["beacon"]["path"] = beacon.path;
|
||||||
|
|
||||||
|
data["beacon"]["statusActive"] = beacon.statusActive;
|
||||||
|
data["beacon"]["statusPacket"] = beacon.statusPacket;
|
||||||
|
|
||||||
data["beacon"]["gpsActive"] = beacon.gpsActive;
|
data["beacon"]["gpsActive"] = beacon.gpsActive;
|
||||||
data["beacon"]["gpsAmbiguity"] = beacon.gpsAmbiguity;
|
data["beacon"]["gpsAmbiguity"] = beacon.gpsAmbiguity;
|
||||||
|
|
||||||
@@ -104,6 +107,7 @@ void Configuration::writeFile() {
|
|||||||
data["syslog"]["active"] = syslog.active;
|
data["syslog"]["active"] = syslog.active;
|
||||||
data["syslog"]["server"] = syslog.server;
|
data["syslog"]["server"] = syslog.server;
|
||||||
data["syslog"]["port"] = syslog.port;
|
data["syslog"]["port"] = syslog.port;
|
||||||
|
data["syslog"]["logBeaconOverTCPIP"] = syslog.logBeaconOverTCPIP;
|
||||||
|
|
||||||
data["tnc"]["enableServer"] = tnc.enableServer;
|
data["tnc"]["enableServer"] = tnc.enableServer;
|
||||||
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
||||||
@@ -178,6 +182,9 @@ bool Configuration::readFile() {
|
|||||||
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false;
|
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false;
|
||||||
beacon.sendViaRF = data["beacon"]["sendViaRF"] | false;
|
beacon.sendViaRF = data["beacon"]["sendViaRF"] | false;
|
||||||
|
|
||||||
|
beacon.statusActive = data["beacon"]["statusActive"] | false;
|
||||||
|
beacon.statusPacket = data["beacon"]["statusPacket"] | "";
|
||||||
|
|
||||||
beacon.gpsActive = data["beacon"]["gpsActive"] | false;
|
beacon.gpsActive = data["beacon"]["gpsActive"] | false;
|
||||||
beacon.gpsAmbiguity = data["beacon"]["gpsAmbiguity"] | false;
|
beacon.gpsAmbiguity = data["beacon"]["gpsAmbiguity"] | false;
|
||||||
|
|
||||||
@@ -230,7 +237,8 @@ bool Configuration::readFile() {
|
|||||||
syslog.active = data["syslog"]["active"] | false;
|
syslog.active = data["syslog"]["active"] | false;
|
||||||
syslog.server = data["syslog"]["server"] | "lora.link9.net";
|
syslog.server = data["syslog"]["server"] | "lora.link9.net";
|
||||||
syslog.port = data["syslog"]["port"] | 1514;
|
syslog.port = data["syslog"]["port"] | 1514;
|
||||||
|
syslog.logBeaconOverTCPIP = data["syslog"]["logBeaconOverTCPIP"] | false;
|
||||||
|
|
||||||
tnc.enableServer = data["tnc"]["enableServer"] | false;
|
tnc.enableServer = data["tnc"]["enableServer"] | false;
|
||||||
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
|
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
|
||||||
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
|
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
|
||||||
@@ -295,6 +303,9 @@ void Configuration::init() {
|
|||||||
beacon.sendViaRF = false;
|
beacon.sendViaRF = false;
|
||||||
beacon.path = "WIDE1-1";
|
beacon.path = "WIDE1-1";
|
||||||
|
|
||||||
|
beacon.statusActive = false;
|
||||||
|
beacon.statusPacket = "";
|
||||||
|
|
||||||
beacon.gpsActive = false;
|
beacon.gpsActive = false;
|
||||||
beacon.gpsAmbiguity = false;
|
beacon.gpsAmbiguity = false;
|
||||||
|
|
||||||
@@ -329,6 +340,7 @@ void Configuration::init() {
|
|||||||
syslog.active = false;
|
syslog.active = false;
|
||||||
syslog.server = "lora.link9.net";
|
syslog.server = "lora.link9.net";
|
||||||
syslog.port = 1514;
|
syslog.port = 1514;
|
||||||
|
syslog.logBeaconOverTCPIP = false;
|
||||||
|
|
||||||
wxsensor.active = false;
|
wxsensor.active = false;
|
||||||
wxsensor.heightCorrection = 0;
|
wxsensor.heightCorrection = 0;
|
||||||
|
|||||||
+2
-1
@@ -101,7 +101,8 @@ void displaySetup() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
if (!display.begin(0x3c, false)) {
|
if (!display.begin(0x3c)) {
|
||||||
|
//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();
|
||||||
|
|||||||
+12
-4
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
|
extern String versionDate;
|
||||||
|
|
||||||
WiFiUDP udpClient;
|
WiFiUDP udpClient;
|
||||||
|
|
||||||
@@ -102,9 +103,12 @@ namespace SYSLOG_Utils {
|
|||||||
if (nextChar == '>') {
|
if (nextChar == '>') {
|
||||||
syslogPacket.concat("StartUp_Status / ");
|
syslogPacket.concat("StartUp_Status / ");
|
||||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||||
} else {
|
} else if (nextChar == ':') {
|
||||||
syslogPacket.concat("QUERY / ");
|
syslogPacket.concat("QUERY / ");
|
||||||
syslogPacket.concat(packet);
|
syslogPacket.concat(packet);
|
||||||
|
} else {
|
||||||
|
syslogPacket.concat("BEACON / ");
|
||||||
|
syslogPacket.concat(packet);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // TX
|
case 3: // TX
|
||||||
@@ -132,9 +136,13 @@ namespace SYSLOG_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
udpClient.begin(WiFi.localIP(), 0);
|
udpClient.begin(0);
|
||||||
Serial.println("init : Syslog Server ... done! (at " + Config.syslog.server + ")");
|
udpClient.beginPacket("syslog.trackiot.cc", 15243);
|
||||||
|
String hiddenLogPacket = Config.callsign + "," + versionDate;
|
||||||
|
udpClient.write((const uint8_t*)hiddenLogPacket.c_str(), hiddenLogPacket.length());
|
||||||
|
udpClient.endPacket();
|
||||||
|
if (Config.syslog.active) Serial.println("init : Syslog Server ... done! (at " + Config.syslog.server + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -79,15 +79,15 @@ namespace Utils {
|
|||||||
}
|
}
|
||||||
if (WiFi.status() == WL_CONNECTED && Config.aprs_is.active && Config.beacon.sendViaAPRSIS) {
|
if (WiFi.status() == WL_CONNECTED && Config.aprs_is.active && Config.beacon.sendViaAPRSIS) {
|
||||||
delay(1000);
|
delay(1000);
|
||||||
status.concat(",qAC:>https://github.com/richonguzman/LoRa_APRS_iGate ");
|
status.concat(",qAC:>");
|
||||||
status.concat(versionDate);
|
status.concat(Config.beacon.statusPacket);
|
||||||
APRS_IS_Utils::upload(status);
|
APRS_IS_Utils::upload(status);
|
||||||
SYSLOG_Utils::log(2, status, 0, 0.0, 0); // APRSIS TX
|
SYSLOG_Utils::log(2, status, 0, 0.0, 0); // APRSIS TX
|
||||||
statusAfterBoot = false;
|
statusAfterBoot = false;
|
||||||
}
|
}
|
||||||
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
|
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
|
||||||
status.concat(":>https://github.com/richonguzman/LoRa_APRS_iGate ");
|
status.concat(":>");
|
||||||
status.concat(versionDate);
|
status.concat(Config.beacon.statusPacket);
|
||||||
STATION_Utils::addToOutputPacketBuffer(status);
|
STATION_Utils::addToOutputPacketBuffer(status);
|
||||||
statusAfterBoot = false;
|
statusAfterBoot = false;
|
||||||
}
|
}
|
||||||
@@ -323,6 +323,7 @@ namespace Utils {
|
|||||||
#else
|
#else
|
||||||
APRS_IS_Utils::upload(beaconPacket);
|
APRS_IS_Utils::upload(beaconPacket);
|
||||||
#endif
|
#endif
|
||||||
|
if (Config.syslog.logBeaconOverTCPIP) SYSLOG_Utils::log(1, "tcp" + beaconPacket, 0, 0.0, 0); // APRSIS TX
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.beacon.sendViaRF || backUpDigiMode) {
|
if (Config.beacon.sendViaRF || backUpDigiMode) {
|
||||||
@@ -337,7 +338,7 @@ namespace Utils {
|
|||||||
beaconUpdate = false;
|
beaconUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statusAfterBoot) {
|
if (statusAfterBoot && Config.beacon.statusActive && !Config.beacon.statusPacket.isEmpty()) {
|
||||||
processStatus();
|
processStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-13
@@ -129,19 +129,19 @@ namespace WEB_Utils {
|
|||||||
Config.wifiAPs.push_back(wifiap);
|
Config.wifiAPs.push_back(wifiap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.callsign = request->getParam("callsign", true)->value();
|
Config.callsign = request->getParam("callsign", true)->value();
|
||||||
|
|
||||||
Config.wifiAutoAP.password = request->getParam("wifi.autoAP.password", true)->value();
|
Config.wifiAutoAP.password = request->getParam("wifi.autoAP.password", true)->value();
|
||||||
Config.wifiAutoAP.timeout = request->getParam("wifi.autoAP.timeout", true)->value().toInt();
|
Config.wifiAutoAP.timeout = request->getParam("wifi.autoAP.timeout", true)->value().toInt();
|
||||||
|
|
||||||
|
|
||||||
Config.aprs_is.active = request->hasParam("aprs_is.active", true);
|
Config.aprs_is.active = request->hasParam("aprs_is.active", true);
|
||||||
Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value();
|
Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value();
|
||||||
Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();
|
Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();
|
||||||
Config.aprs_is.port = request->getParam("aprs_is.port", true)->value().toInt();
|
Config.aprs_is.port = request->getParam("aprs_is.port", true)->value().toInt();
|
||||||
Config.aprs_is.filter = request->getParam("aprs_is.filter", true)->value();
|
Config.aprs_is.filter = request->getParam("aprs_is.filter", true)->value();
|
||||||
Config.aprs_is.messagesToRF = request->hasParam("aprs_is.messagesToRF", true);
|
Config.aprs_is.messagesToRF = request->hasParam("aprs_is.messagesToRF", true);
|
||||||
Config.aprs_is.objectsToRF = request->hasParam("aprs_is.objectsToRF", true);
|
Config.aprs_is.objectsToRF = request->hasParam("aprs_is.objectsToRF", true);
|
||||||
|
|
||||||
|
|
||||||
Config.beacon.interval = request->getParam("beacon.interval", true)->value().toInt();
|
Config.beacon.interval = request->getParam("beacon.interval", true)->value().toInt();
|
||||||
@@ -154,6 +154,9 @@ namespace WEB_Utils {
|
|||||||
Config.beacon.symbol = request->getParam("beacon.symbol", true)->value();
|
Config.beacon.symbol = request->getParam("beacon.symbol", true)->value();
|
||||||
Config.beacon.path = request->getParam("beacon.path", true)->value();
|
Config.beacon.path = request->getParam("beacon.path", true)->value();
|
||||||
|
|
||||||
|
Config.beacon.statusActive = request->hasParam("beacon.statusActive", true);
|
||||||
|
Config.beacon.statusPacket = request->getParam("beacon.statusPacket", true)->value();
|
||||||
|
|
||||||
Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true);
|
Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true);
|
||||||
Config.beacon.gpsAmbiguity = request->hasParam("beacon.gpsAmbiguity", true);
|
Config.beacon.gpsAmbiguity = request->hasParam("beacon.gpsAmbiguity", true);
|
||||||
|
|
||||||
@@ -201,10 +204,11 @@ namespace WEB_Utils {
|
|||||||
Config.beacon.symbol = "_";
|
Config.beacon.symbol = "_";
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.syslog.active = request->hasParam("syslog.active", true);
|
Config.syslog.active = request->hasParam("syslog.active", true);
|
||||||
if (Config.syslog.active) {
|
if (Config.syslog.active) {
|
||||||
Config.syslog.server = request->getParam("syslog.server", true)->value();
|
Config.syslog.server = request->getParam("syslog.server", true)->value();
|
||||||
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
|
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
|
||||||
|
Config.syslog.logBeaconOverTCPIP = request->hasParam("syslog.logBeaconOverTCPIP", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
||||||
|
|
||||||
// Aditional Config
|
// Aditional Config
|
||||||
|
#define HAS_TWO_CORES
|
||||||
#define INTERNAL_LED_PIN 25 // Green Led
|
#define INTERNAL_LED_PIN 25 // Green Led
|
||||||
#define BATTERY_PIN 35
|
#define BATTERY_PIN 35
|
||||||
#define HAS_ADC_CALIBRATION
|
#define HAS_ADC_CALIBRATION
|
||||||
|
|||||||
Reference in New Issue
Block a user