mirror of
https://github.com/richonguzman/LoRa_APRS_iGate.git
synced 2026-04-30 10:32:17 +02:00
Compare commits
18 Commits
betterClea
...
V3.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
796ba35357 | ||
|
|
57873e4181 | ||
|
|
453222d69f | ||
|
|
fbb347fb7f | ||
|
|
50fd831fdb | ||
|
|
3a2c0304d0 | ||
|
|
b24c2b2527 | ||
|
|
db0da96d7f | ||
|
|
bf6a0faa90 | ||
|
|
61cf118a3b | ||
|
|
44719083a6 | ||
|
|
808d740477 | ||
|
|
23c8257c80 | ||
|
|
db4582db13 | ||
|
|
09e06d36e8 | ||
|
|
e6d44c1b7f | ||
|
|
d4fc99466f | ||
|
|
41f09af7b5 |
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -19,6 +19,8 @@ jobs:
|
|||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
- name: heltec-lora32-v2
|
- name: heltec-lora32-v2
|
||||||
chip: esp32
|
chip: esp32
|
||||||
|
- name: heltec-lora32-v2_915
|
||||||
|
chip: esp32
|
||||||
- name: heltec_wifi_lora_32_V3
|
- name: heltec_wifi_lora_32_V3
|
||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
- name: heltec_wifi_lora_32_V3_2
|
- name: heltec_wifi_lora_32_V3_2
|
||||||
@@ -96,7 +98,9 @@ jobs:
|
|||||||
- name: XIAO_ESP32S3_WIO_SX1262
|
- name: XIAO_ESP32S3_WIO_SX1262
|
||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
- name: TROY_LoRa_APRS
|
- name: TROY_LoRa_APRS
|
||||||
chip: esp32
|
chip: esp32
|
||||||
|
- name: ESP32_9M2IBR_1W_LoRa_GPS
|
||||||
|
chip: esp32
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ ____________________________________________________
|
|||||||
<br />
|
<br />
|
||||||
|
|
||||||
# Timeline (Versions):
|
# Timeline (Versions):
|
||||||
|
- 2026-02-26 9M2IBR ESP32 1W (400M30S) + GPS board added.
|
||||||
|
- 2026-02-25 Code Improvements: reduced String comparisons and improved logic for faster code execution.
|
||||||
|
- 2026-02-15 Digipeater code/logic improved.
|
||||||
|
- 2026-02-08 Heltec V2 915MHz added.
|
||||||
|
- 2026-02-05 Improved "digiBackupMode" to check "APRS-IS" server connection.
|
||||||
- 2026-01-07 Tactical Callsign added.
|
- 2026-01-07 Tactical Callsign added.
|
||||||
- 2026-01-05 Heltec V4 support added.
|
- 2026-01-05 Heltec V4 support added.
|
||||||
- 2025-12-22 Heltec Wireless Paper V1.2 and VisionMaster E290 Added. Thanks HA5SZI.
|
- 2025-12-22 Heltec Wireless Paper V1.2 and VisionMaster E290 Added. Thanks HA5SZI.
|
||||||
@@ -85,7 +90,7 @@ ____________________________________________________
|
|||||||
- 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 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.
|
||||||
- 2024.08.23 Wemos S2 Mini DIY LoRa added.
|
- 2024.08.23 Wemos S2 Mini DIY LoRa added.
|
||||||
- 2024.08.19 HELTEC Wireless Paper working (still missing Epaper code).
|
- 2024.08.19 HELTEC Wireless Paper working (still missing Epaper code).
|
||||||
- 2024.08.13 Web Authentication for WebUI. Thanks Mitja S57PNX.
|
- 2024.08.13 Web Authentication for WebUI. Thanks Mitja S57PNX.
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
int interval;
|
int interval;
|
||||||
String overlay;
|
String overlay;
|
||||||
String symbol;
|
String symbol;
|
||||||
String path;
|
String path;
|
||||||
bool sendViaAPRSIS;
|
bool sendViaAPRSIS;
|
||||||
bool sendViaRF;
|
bool sendViaRF;
|
||||||
int beaconFreq;
|
int beaconFreq;
|
||||||
@@ -78,7 +78,7 @@ public:
|
|||||||
long rxFreq;
|
long rxFreq;
|
||||||
int rxSpreadingFactor;
|
int rxSpreadingFactor;
|
||||||
int rxCodingRate4;
|
int rxCodingRate4;
|
||||||
long rxSignalBandwidth;
|
long rxSignalBandwidth;
|
||||||
bool txActive;
|
bool txActive;
|
||||||
long txFreq;
|
long txFreq;
|
||||||
int txSpreadingFactor;
|
int txSpreadingFactor;
|
||||||
@@ -188,10 +188,10 @@ public:
|
|||||||
BATTERY battery;
|
BATTERY battery;
|
||||||
WXSENSOR wxsensor;
|
WXSENSOR wxsensor;
|
||||||
SYSLOG syslog;
|
SYSLOG syslog;
|
||||||
TNC tnc;
|
TNC tnc;
|
||||||
OTA ota;
|
OTA ota;
|
||||||
WEBADMIN webadmin;
|
WEBADMIN webadmin;
|
||||||
NTP ntp;
|
NTP ntp;
|
||||||
REMOTE_MANAGEMENT remoteManagement;
|
REMOTE_MANAGEMENT remoteManagement;
|
||||||
MQTT mqtt;
|
MQTT mqtt;
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
|
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
|
||||||
|
|
||||||
void displaySetup();
|
void displaySetup();
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace GPS_Utils {
|
namespace GPS_Utils {
|
||||||
|
|
||||||
String getiGateLoRaBeaconPacket();
|
String getiGateLoRaBeaconPacket();
|
||||||
char *ax25_base91enc(char *s, uint8_t n, uint32_t v);
|
char *ax25_base91enc(char *s, uint8_t n, uint32_t v);
|
||||||
String encodeGPS(float latitude, float longitude, const String& overlay, const String& symbol);
|
String encodeGPS(float latitude, float longitude, const String& overlay, const String& symbol);
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -21,8 +21,9 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
namespace SLEEP_Utils {
|
namespace SLEEP_Utils {
|
||||||
|
|
||||||
void setup();
|
void setup();
|
||||||
void checkWakeUpFlag();
|
void checkWakeUpFlag();
|
||||||
void startSleeping();
|
void startSleeping();
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -37,8 +37,7 @@ namespace STATION_Utils {
|
|||||||
void deleteNotHeard();
|
void deleteNotHeard();
|
||||||
void updateLastHeard(const String& station);
|
void updateLastHeard(const String& station);
|
||||||
bool wasHeard(const String& station);
|
bool wasHeard(const String& station);
|
||||||
void clean25SegBuffer();
|
bool isIn25SegHashBuffer(const String& station, const String& textMessage);
|
||||||
bool check25SegBuffer(const String& station, const String& textMessage);
|
|
||||||
void processOutputPacketBufferUltraEcoMode();
|
void processOutputPacketBufferUltraEcoMode();
|
||||||
void processOutputPacketBuffer();
|
void processOutputPacketBuffer();
|
||||||
void addToOutputPacketBuffer(const String& packet, bool flag = false);
|
void addToOutputPacketBuffer(const String& packet, bool flag = false);
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -27,7 +27,8 @@ namespace TELEMETRY_Utils {
|
|||||||
void sendEquationsUnitsParameters();
|
void sendEquationsUnitsParameters();
|
||||||
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType);
|
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType);
|
||||||
String generateEncodedTelemetry();
|
String generateEncodedTelemetry();
|
||||||
|
void checkEUPInterval();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#define WX_UTILS_H_
|
#define WX_UTILS_H_
|
||||||
|
|
||||||
#include <Adafruit_Sensor.h>
|
#include <Adafruit_Sensor.h>
|
||||||
#include <Adafruit_AHTX0.h>
|
#include <Adafruit_AHTX0.h>
|
||||||
#include <Adafruit_BME280.h>
|
#include <Adafruit_BME280.h>
|
||||||
#include <Adafruit_BMP280.h>
|
#include <Adafruit_BMP280.h>
|
||||||
#include <Adafruit_BME680.h>
|
#include <Adafruit_BME680.h>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ ___________________________________________________________________*/
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
String versionDate = "2026-02-20";
|
String versionDate = "2026-02-26";
|
||||||
String versionNumber = "3.2";
|
String versionNumber = "3.2";
|
||||||
Configuration Config;
|
Configuration Config;
|
||||||
WiFiClient aprsIsClient;
|
WiFiClient aprsIsClient;
|
||||||
@@ -188,7 +188,6 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Config.loramodule.txActive && (Config.digi.mode == 2 || Config.digi.mode == 3 || backupDigiMode)) { // If Digi enabled
|
if (Config.loramodule.txActive && (Config.digi.mode == 2 || Config.digi.mode == 3 || backupDigiMode)) { // If Digi enabled
|
||||||
STATION_Utils::clean25SegBuffer();
|
|
||||||
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
|
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,30 +135,30 @@ namespace APRS_IS_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String checkForStartingBytes(const String& packet) {
|
String checkForStartingBytes(const String& packet) {
|
||||||
if (packet.indexOf("\x3c\xff\x01") != -1) {
|
int index = packet.indexOf("\x3c\xff\x01");
|
||||||
return packet.substring(0, packet.indexOf("\x3c\xff\x01"));
|
return (index != -1) ? packet.substring(0, index) : packet;
|
||||||
} else {
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String buildPacketToUpload(const String& packet) {
|
String buildPacketToUpload(const String& packet) {
|
||||||
String packetToUpload = packet.substring(3, packet.indexOf(":"));
|
int colonIndex = packet.indexOf(":");
|
||||||
|
String packetToUpload = packet.substring(3, colonIndex);
|
||||||
if (Config.aprs_is.active && passcodeValid && Config.aprs_is.messagesToRF) {
|
if (Config.aprs_is.active && passcodeValid && Config.aprs_is.messagesToRF) {
|
||||||
packetToUpload += ",qAR,";
|
packetToUpload += ",qAR,";
|
||||||
} else {
|
} else {
|
||||||
packetToUpload += ",qAO,";
|
packetToUpload += ",qAO,";
|
||||||
}
|
}
|
||||||
packetToUpload += Config.callsign;
|
packetToUpload += Config.callsign;
|
||||||
packetToUpload += checkForStartingBytes(packet.substring(packet.indexOf(":")));
|
packetToUpload += checkForStartingBytes(packet.substring(colonIndex));
|
||||||
return packetToUpload;
|
return packetToUpload;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool processReceivedLoRaMessage(const String& sender, const String& packet, bool thirdParty) {
|
bool processReceivedLoRaMessage(const String& sender, const String& packet, bool thirdParty) {
|
||||||
String receivedMessage;
|
String receivedMessage;
|
||||||
if (packet.indexOf("{") > 0) { // ack?
|
int leftCurlyBraceIndex = packet.indexOf("{");
|
||||||
|
int colonIndex = packet.indexOf(":");
|
||||||
|
if (leftCurlyBraceIndex > 0) { // ack?
|
||||||
String ackMessage = "ack";
|
String ackMessage = "ack";
|
||||||
ackMessage.concat(packet.substring(packet.indexOf("{") + 1));
|
ackMessage.concat(packet.substring(leftCurlyBraceIndex + 1));
|
||||||
ackMessage.trim();
|
ackMessage.trim();
|
||||||
//Serial.println(ackMessage);
|
//Serial.println(ackMessage);
|
||||||
|
|
||||||
@@ -180,9 +180,9 @@ namespace APRS_IS_Utils {
|
|||||||
addToBuffer += ":";
|
addToBuffer += ":";
|
||||||
addToBuffer += ackMessage;
|
addToBuffer += ackMessage;
|
||||||
STATION_Utils::addToOutputPacketBuffer(addToBuffer);
|
STATION_Utils::addToOutputPacketBuffer(addToBuffer);
|
||||||
receivedMessage = packet.substring(packet.indexOf(":") + 1, packet.indexOf("{"));
|
receivedMessage = packet.substring(colonIndex + 1, leftCurlyBraceIndex);
|
||||||
} else {
|
} else {
|
||||||
receivedMessage = packet.substring(packet.indexOf(":") + 1);
|
receivedMessage = packet.substring(colonIndex + 1);
|
||||||
}
|
}
|
||||||
if (receivedMessage.indexOf("?") == 0) {
|
if (receivedMessage.indexOf("?") == 0) {
|
||||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
||||||
@@ -207,29 +207,30 @@ namespace APRS_IS_Utils {
|
|||||||
if (Sender != Config.callsign && Utils::callsignIsValid(Sender)) {
|
if (Sender != Config.callsign && Utils::callsignIsValid(Sender)) {
|
||||||
STATION_Utils::updateLastHeard(Sender);
|
STATION_Utils::updateLastHeard(Sender);
|
||||||
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
|
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
|
||||||
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
|
int doubleColonIndex = packet.indexOf("::");
|
||||||
|
const String& AddresseeAndMessage = packet.substring(doubleColonIndex + 2);
|
||||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||||
Addressee.trim();
|
Addressee.trim();
|
||||||
bool queryMessage = false;
|
bool queryMessage = false;
|
||||||
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
|
if (doubleColonIndex > 10 && Addressee == Config.callsign) { // its a message for me!
|
||||||
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
|
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
|
||||||
}
|
}
|
||||||
if (!queryMessage) {
|
if (queryMessage) return;
|
||||||
const String& aprsPacket = buildPacketToUpload(packet);
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,26 +246,30 @@ namespace APRS_IS_Utils {
|
|||||||
outputPacket.concat(",TCPIP,");
|
outputPacket.concat(",TCPIP,");
|
||||||
outputPacket.concat(Config.callsign);
|
outputPacket.concat(Config.callsign);
|
||||||
outputPacket.concat("*");
|
outputPacket.concat("*");
|
||||||
|
int colonEqualIndex = packet.indexOf(":=");
|
||||||
|
int doubleColonIndex = packet.indexOf("::");
|
||||||
|
int colonInvAccentIndex = packet.indexOf(":`");
|
||||||
|
|
||||||
switch (packetType) {
|
switch (packetType) {
|
||||||
case 0: // gps
|
case 0: // gps
|
||||||
if (packet.indexOf(":=") > 0) {
|
if (colonEqualIndex > 0) {
|
||||||
outputPacket += packet.substring(packet.indexOf(":="));
|
outputPacket += packet.substring(colonEqualIndex);
|
||||||
} else {
|
} else {
|
||||||
outputPacket += packet.substring(packet.indexOf(":!"));
|
outputPacket += packet.substring(packet.indexOf(":!"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1: // messages
|
case 1: // messages
|
||||||
outputPacket += packet.substring(packet.indexOf("::"));
|
outputPacket += packet.substring(doubleColonIndex);
|
||||||
break;
|
break;
|
||||||
case 2: // status
|
case 2: // status
|
||||||
outputPacket += packet.substring(packet.indexOf(":>"));
|
outputPacket += packet.substring(packet.indexOf(":>"));
|
||||||
break;
|
break;
|
||||||
case 3: // telemetry
|
case 3: // telemetry
|
||||||
outputPacket += packet.substring(packet.indexOf("::"));
|
outputPacket += packet.substring(doubleColonIndex);
|
||||||
break;
|
break;
|
||||||
case 4: // mic-e
|
case 4: // mic-e
|
||||||
if (packet.indexOf(":`") > 0) {
|
if (colonInvAccentIndex > 0) {
|
||||||
outputPacket += packet.substring(packet.indexOf(":`"));
|
outputPacket += packet.substring(colonInvAccentIndex);
|
||||||
} else {
|
} else {
|
||||||
outputPacket += packet.substring(packet.indexOf(":'"));
|
outputPacket += packet.substring(packet.indexOf(":'"));
|
||||||
}
|
}
|
||||||
@@ -316,18 +321,21 @@ namespace APRS_IS_Utils {
|
|||||||
if (packet.startsWith("#")) {
|
if (packet.startsWith("#")) {
|
||||||
if (Config.digi.backupDigiMode) lastServerCheck = currentTime;
|
if (Config.digi.backupDigiMode) lastServerCheck = currentTime;
|
||||||
} else {
|
} else {
|
||||||
if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) {
|
int doubleColonIndex = packet.indexOf("::");
|
||||||
|
if (Config.aprs_is.messagesToRF && doubleColonIndex > 0) {
|
||||||
String Sender = packet.substring(0, packet.indexOf(">"));
|
String Sender = packet.substring(0, packet.indexOf(">"));
|
||||||
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
|
const String& AddresseeAndMessage = packet.substring(doubleColonIndex + 2);
|
||||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
int colonIndex = AddresseeAndMessage.indexOf(":");
|
||||||
|
String Addressee = AddresseeAndMessage.substring(0, colonIndex);
|
||||||
Addressee.trim();
|
Addressee.trim();
|
||||||
if (Addressee == Config.callsign) { // its for me!
|
if (Addressee == Config.callsign) { // its for me!
|
||||||
String receivedMessage;
|
String receivedMessage;
|
||||||
if (AddresseeAndMessage.indexOf("{") > 0) { // ack?
|
int curlyBraceIndex = AddresseeAndMessage.indexOf("{");
|
||||||
|
if (curlyBraceIndex > 0) { // ack?
|
||||||
processAckMessage(Sender, AddresseeAndMessage);
|
processAckMessage(Sender, AddresseeAndMessage);
|
||||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{"));
|
receivedMessage = AddresseeAndMessage.substring(colonIndex + 1, curlyBraceIndex);
|
||||||
} else {
|
} else {
|
||||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
|
receivedMessage = AddresseeAndMessage.substring(colonIndex + 1);
|
||||||
}
|
}
|
||||||
if (receivedMessage.indexOf("?") == 0) {
|
if (receivedMessage.indexOf("?") == 0) {
|
||||||
Utils::println("Rx Query (APRS-IS) : " + packet);
|
Utils::println("Rx Query (APRS-IS) : " + packet);
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -96,12 +96,12 @@ bool Configuration::writeFile() {
|
|||||||
data["lora"]["rxFreq"] = loramodule.rxFreq;
|
data["lora"]["rxFreq"] = loramodule.rxFreq;
|
||||||
data["lora"]["rxCodingRate4"] = loramodule.rxCodingRate4;
|
data["lora"]["rxCodingRate4"] = loramodule.rxCodingRate4;
|
||||||
data["lora"]["rxSignalBandwidth"] = loramodule.rxSignalBandwidth;
|
data["lora"]["rxSignalBandwidth"] = loramodule.rxSignalBandwidth;
|
||||||
data["lora"]["txActive"] = loramodule.txActive;
|
data["lora"]["txActive"] = loramodule.txActive;
|
||||||
data["lora"]["txFreq"] = loramodule.txFreq;
|
data["lora"]["txFreq"] = loramodule.txFreq;
|
||||||
data["lora"]["txCodingRate4"] = loramodule.txCodingRate4;
|
data["lora"]["txCodingRate4"] = loramodule.txCodingRate4;
|
||||||
data["lora"]["txSignalBandwidth"] = loramodule.txSignalBandwidth;
|
data["lora"]["txSignalBandwidth"] = loramodule.txSignalBandwidth;
|
||||||
data["lora"]["power"] = loramodule.power;
|
data["lora"]["power"] = loramodule.power;
|
||||||
|
|
||||||
int rxSpreadingFactor = loramodule.rxSpreadingFactor;
|
int rxSpreadingFactor = loramodule.rxSpreadingFactor;
|
||||||
int txSpreadingFactor = loramodule.txSpreadingFactor;
|
int txSpreadingFactor = loramodule.txSpreadingFactor;
|
||||||
#if defined(HAS_SX1276) || defined(HAS_SX1278)
|
#if defined(HAS_SX1276) || defined(HAS_SX1278)
|
||||||
@@ -222,7 +222,7 @@ bool Configuration::readFile() {
|
|||||||
callsign = data["callsign"] | "NOCALL-10";
|
callsign = data["callsign"] | "NOCALL-10";
|
||||||
if (!data.containsKey("tacticalCallsign")) needsRewrite = true;
|
if (!data.containsKey("tacticalCallsign")) needsRewrite = true;
|
||||||
tacticalCallsign = data["tacticalCallsign"] | "";
|
tacticalCallsign = data["tacticalCallsign"] | "";
|
||||||
|
|
||||||
if (!data["aprs_is"].containsKey("active") ||
|
if (!data["aprs_is"].containsKey("active") ||
|
||||||
!data["aprs_is"].containsKey("passcode") ||
|
!data["aprs_is"].containsKey("passcode") ||
|
||||||
!data["aprs_is"].containsKey("server") ||
|
!data["aprs_is"].containsKey("server") ||
|
||||||
@@ -300,14 +300,14 @@ bool Configuration::readFile() {
|
|||||||
loramodule.rxFreq = data["lora"]["rxFreq"] | 433775000;
|
loramodule.rxFreq = data["lora"]["rxFreq"] | 433775000;
|
||||||
loramodule.rxSpreadingFactor = data["lora"]["rxSpreadingFactor"] | 12;
|
loramodule.rxSpreadingFactor = data["lora"]["rxSpreadingFactor"] | 12;
|
||||||
loramodule.rxCodingRate4 = data["lora"]["rxCodingRate4"] | 5;
|
loramodule.rxCodingRate4 = data["lora"]["rxCodingRate4"] | 5;
|
||||||
loramodule.rxSignalBandwidth = data["lora"]["rxSignalBandwidth"] | 125000;
|
loramodule.rxSignalBandwidth = data["lora"]["rxSignalBandwidth"] | 125000;
|
||||||
loramodule.txActive = data["lora"]["txActive"] | false;
|
loramodule.txActive = data["lora"]["txActive"] | false;
|
||||||
loramodule.txFreq = data["lora"]["txFreq"] | 433775000;
|
loramodule.txFreq = data["lora"]["txFreq"] | 433775000;
|
||||||
loramodule.txSpreadingFactor = data["lora"]["txSpreadingFactor"] | 12;
|
loramodule.txSpreadingFactor = data["lora"]["txSpreadingFactor"] | 12;
|
||||||
loramodule.txCodingRate4 = data["lora"]["txCodingRate4"] | 5;
|
loramodule.txCodingRate4 = data["lora"]["txCodingRate4"] | 5;
|
||||||
loramodule.txSignalBandwidth = data["lora"]["txSignalBandwidth"] | 125000;
|
loramodule.txSignalBandwidth = data["lora"]["txSignalBandwidth"] | 125000;
|
||||||
loramodule.power = data["lora"]["power"] | 20;
|
loramodule.power = data["lora"]["power"] | 20;
|
||||||
|
|
||||||
if (!data["display"].containsKey("alwaysOn") ||
|
if (!data["display"].containsKey("alwaysOn") ||
|
||||||
!data["display"].containsKey("timeout") ||
|
!data["display"].containsKey("timeout") ||
|
||||||
!data["display"].containsKey("turn180")) needsRewrite = true;
|
!data["display"].containsKey("turn180")) needsRewrite = true;
|
||||||
@@ -381,7 +381,7 @@ bool Configuration::readFile() {
|
|||||||
mqtt.password = data["mqtt"]["password"] | "";
|
mqtt.password = data["mqtt"]["password"] | "";
|
||||||
mqtt.port = data["mqtt"]["port"] | 1883;
|
mqtt.port = data["mqtt"]["port"] | 1883;
|
||||||
mqtt.beaconOverMqtt = data["mqtt"]["beaconOverMqtt"] | false;
|
mqtt.beaconOverMqtt = data["mqtt"]["beaconOverMqtt"] | false;
|
||||||
|
|
||||||
if (!data["ota"].containsKey("username") ||
|
if (!data["ota"].containsKey("username") ||
|
||||||
!data["ota"].containsKey("password")) needsRewrite = true;
|
!data["ota"].containsKey("password")) needsRewrite = true;
|
||||||
ota.username = data["ota"]["username"] | "";
|
ota.username = data["ota"]["username"] | "";
|
||||||
@@ -426,7 +426,7 @@ bool Configuration::readFile() {
|
|||||||
writeFile();
|
writeFile();
|
||||||
delay(1000);
|
delay(1000);
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
Serial.println("Config read successfuly");
|
Serial.println("Config read successfuly");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -434,7 +434,7 @@ bool Configuration::readFile() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::setDefaultValues() {
|
void Configuration::setDefaultValues() {
|
||||||
|
|
||||||
WiFi_AP wifiap;
|
WiFi_AP wifiap;
|
||||||
@@ -470,14 +470,14 @@ void Configuration::setDefaultValues() {
|
|||||||
beacon.sendViaAPRSIS = true;
|
beacon.sendViaAPRSIS = true;
|
||||||
beacon.sendViaRF = false;
|
beacon.sendViaRF = false;
|
||||||
beacon.beaconFreq = 1;
|
beacon.beaconFreq = 1;
|
||||||
|
|
||||||
beacon.statusActive = false;
|
beacon.statusActive = false;
|
||||||
beacon.statusPacket = "";
|
beacon.statusPacket = "";
|
||||||
|
|
||||||
beacon.gpsActive = false;
|
beacon.gpsActive = false;
|
||||||
beacon.ambiguityLevel = 0;
|
beacon.ambiguityLevel = 0;
|
||||||
|
|
||||||
personalNote = "";
|
personalNote = "";
|
||||||
|
|
||||||
blacklist = "";
|
blacklist = "";
|
||||||
|
|
||||||
@@ -500,7 +500,7 @@ void Configuration::setDefaultValues() {
|
|||||||
display.alwaysOn = true;
|
display.alwaysOn = true;
|
||||||
display.timeout = 4;
|
display.timeout = 4;
|
||||||
display.turn180 = false;
|
display.turn180 = false;
|
||||||
|
|
||||||
battery.sendInternalVoltage = false;
|
battery.sendInternalVoltage = false;
|
||||||
battery.monitorInternalVoltage = false;
|
battery.monitorInternalVoltage = false;
|
||||||
battery.internalSleepVoltage = 2.9;
|
battery.internalSleepVoltage = 2.9;
|
||||||
|
|||||||
@@ -43,58 +43,53 @@ extern bool backupDigiMode;
|
|||||||
|
|
||||||
namespace DIGI_Utils {
|
namespace DIGI_Utils {
|
||||||
|
|
||||||
String buildPacket(const String& path, const String& packet, bool thirdParty, bool crossFreq) {
|
String cleanPathAsterisks(String path) {
|
||||||
String stationCallsign = (Config.tacticalCallsign == "" ? Config.callsign : Config.tacticalCallsign);
|
String terms[] = {",WIDE1*", ",WIDE2*", "*"};
|
||||||
if (!crossFreq) {
|
for (String term : terms) {
|
||||||
String packetToRepeat = packet.substring(0, packet.indexOf(",") + 1);
|
int index = path.indexOf(term);
|
||||||
String tempPath = path;
|
if (index != -1) path.remove(index, term.length()); // less memory than: tempPath.replace("*", "");
|
||||||
int digiMode = Config.digi.mode;
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
if (path.indexOf("WIDE1-1") != -1 && (digiMode == 2 || digiMode == 3)) {
|
String buildPacket(const String& path, const String& packet, bool thirdParty, bool crossFreq) {
|
||||||
|
String stationCallsign = (Config.tacticalCallsign == "" ? Config.callsign : Config.tacticalCallsign);
|
||||||
|
String suffix = thirdParty ? ":}" : ":";
|
||||||
|
int suffixIndex = packet.indexOf(suffix);
|
||||||
|
String packetToRepeat;
|
||||||
|
if (!crossFreq) {
|
||||||
|
int digiMode = Config.digi.mode;
|
||||||
|
String tempPath = path;
|
||||||
|
|
||||||
|
if (tempPath.indexOf("WIDE1-1") != -1 && (digiMode == 2 || digiMode == 3)) { // WIDE1-1
|
||||||
|
if (tempPath.indexOf("*") != -1 ) return ""; // "*" shouldn't be in WIDE1-1 (only) type of packet
|
||||||
tempPath.replace("WIDE1-1", stationCallsign + "*");
|
tempPath.replace("WIDE1-1", stationCallsign + "*");
|
||||||
} else if (path.indexOf("WIDE2-") != -1 && digiMode == 3) {
|
} else if (tempPath.indexOf("WIDE2-") != -1 && digiMode == 3) { // WIDE2-n Digipeater
|
||||||
int wide1AsteriskIndex = path.indexOf(",WIDE1*"); // less memory than: tempPath.replace(",WIDE1*", "");
|
tempPath = cleanPathAsterisks(path);
|
||||||
if (wide1AsteriskIndex != -1) {
|
if (tempPath.indexOf("WIDE2-1") != -1) {
|
||||||
tempPath.remove(wide1AsteriskIndex, 7);
|
|
||||||
}
|
|
||||||
int asteriskIndex = path.indexOf("*"); // less memory than: tempPath.replace("*", "");
|
|
||||||
if (asteriskIndex != -1) {
|
|
||||||
tempPath.remove(asteriskIndex, 1);
|
|
||||||
}
|
|
||||||
if (path.indexOf("WIDE2-1") != -1) {
|
|
||||||
tempPath.replace("WIDE2-1", stationCallsign + "*");
|
tempPath.replace("WIDE2-1", stationCallsign + "*");
|
||||||
} else if (path.indexOf("WIDE2-2") != -1) {
|
} else if (tempPath.indexOf("WIDE2-2") != -1) {
|
||||||
tempPath.replace("WIDE2-2", stationCallsign + "*,WIDE2-1");
|
tempPath.replace("WIDE2-2", stationCallsign + "*,WIDE2-1");
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
packetToRepeat = packet.substring(0, packet.indexOf(",") + 1);
|
||||||
packetToRepeat += tempPath;
|
packetToRepeat += tempPath;
|
||||||
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(packet.indexOf(thirdParty ? ":}" : ":")));
|
|
||||||
return packetToRepeat;
|
|
||||||
} else { // CrossFreq Digipeater
|
} else { // CrossFreq Digipeater
|
||||||
String suffix = thirdParty ? ":}" : ":";
|
packetToRepeat = cleanPathAsterisks(packet.substring(0, suffixIndex));
|
||||||
int suffixIndex = packet.indexOf(suffix);
|
if (packetToRepeat.indexOf(stationCallsign) != -1) return ""; // stationCallsign shouldn't be in path
|
||||||
String packetToRepeat = packet.substring(0, suffixIndex);
|
|
||||||
|
|
||||||
String terms[] = {",WIDE1*", ",WIDE2*", "*"};
|
|
||||||
for (String term : terms) {
|
|
||||||
int index = packetToRepeat.indexOf(term);
|
|
||||||
if (index != -1) {
|
|
||||||
packetToRepeat.remove(index, term.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
packetToRepeat += ",";
|
packetToRepeat += ",";
|
||||||
packetToRepeat += stationCallsign;
|
packetToRepeat += stationCallsign;
|
||||||
packetToRepeat += "*";
|
packetToRepeat += "*";
|
||||||
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(suffixIndex));
|
|
||||||
return packetToRepeat;
|
|
||||||
}
|
}
|
||||||
|
packetToRepeat += APRS_IS_Utils::checkForStartingBytes(packet.substring(suffixIndex));
|
||||||
|
return packetToRepeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
String generateDigipeatedPacket(const String& packet, bool thirdParty){
|
String generateDigipeatedPacket(const String& packet, bool thirdParty){
|
||||||
String temp;
|
String temp;
|
||||||
if (thirdParty) { // only header is used
|
if (thirdParty) { // only header is used
|
||||||
const String& header = packet.substring(0, packet.indexOf(":}"));
|
const String& header = packet.substring(0, packet.indexOf(":}"));
|
||||||
temp = header.substring(header.indexOf(">") + 1);
|
temp = header.substring(header.indexOf(">") + 1);
|
||||||
} else {
|
} else {
|
||||||
@@ -104,7 +99,7 @@ namespace DIGI_Utils {
|
|||||||
int digiMode = Config.digi.mode;
|
int digiMode = Config.digi.mode;
|
||||||
bool crossFreq = abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000; // CrossFreq Digi
|
bool crossFreq = abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) >= 125000; // CrossFreq Digi
|
||||||
|
|
||||||
if (commaIndex > 2) { // Packet has "path"
|
if (commaIndex > 2) { // "path" found
|
||||||
const String& path = temp.substring(commaIndex + 1);
|
const String& path = temp.substring(commaIndex + 1);
|
||||||
if (digiMode == 2 || backupDigiMode) {
|
if (digiMode == 2 || backupDigiMode) {
|
||||||
bool hasWide = path.indexOf("WIDE1-1") != -1;
|
bool hasWide = path.indexOf("WIDE1-1") != -1;
|
||||||
@@ -154,28 +149,28 @@ namespace DIGI_Utils {
|
|||||||
if (Sender == stationCallsign) return; // Avoid listening to self packets
|
if (Sender == stationCallsign) return; // Avoid listening to self packets
|
||||||
if (!thirdPartyPacket && Config.tacticalCallsign == "" && !Utils::callsignIsValid(Sender)) return; // No thirdParty + no tactical y no valid callsign
|
if (!thirdPartyPacket && Config.tacticalCallsign == "" && !Utils::callsignIsValid(Sender)) return; // No thirdParty + no tactical y no valid callsign
|
||||||
|
|
||||||
if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2))) {
|
if (STATION_Utils::isIn25SegHashBuffer(Sender, temp.substring(temp.indexOf(":") + 2))) return;
|
||||||
STATION_Utils::updateLastHeard(Sender);
|
|
||||||
Utils::typeOfPacket(temp, 2); // Digi
|
STATION_Utils::updateLastHeard(Sender);
|
||||||
bool queryMessage = false;
|
Utils::typeOfPacket(temp, 2); // Digi
|
||||||
int doubleColonIndex = temp.indexOf("::");
|
bool queryMessage = false;
|
||||||
if (doubleColonIndex > 10) { // it's a message
|
int doubleColonIndex = temp.indexOf("::");
|
||||||
String AddresseeAndMessage = temp.substring(doubleColonIndex + 2);
|
if (doubleColonIndex > 10) { // it's a message
|
||||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
String AddresseeAndMessage = temp.substring(doubleColonIndex + 2);
|
||||||
Addressee.trim();
|
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||||
if (Addressee == stationCallsign) { // it's a message for me!
|
Addressee.trim();
|
||||||
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
|
if (Addressee == stationCallsign) { // 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 != "") {
|
|
||||||
STATION_Utils::addToOutputPacketBuffer(loraPacket);
|
|
||||||
if (Config.digi.ecoMode != 1) displayToggle(true);
|
|
||||||
lastScreenOn = millis();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (queryMessage) return; // answer should not be repeated.
|
||||||
|
|
||||||
|
String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket);
|
||||||
|
if (loraPacket != "") {
|
||||||
|
STATION_Utils::addToOutputPacketBuffer(loraPacket);
|
||||||
|
if (Config.digi.ecoMode != 1) displayToggle(true);
|
||||||
|
lastScreenOn = millis();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
#ifdef HAS_TFT
|
#ifdef HAS_TFT
|
||||||
#include <TFT_eSPI.h>
|
#include <TFT_eSPI.h>
|
||||||
|
|
||||||
TFT_eSPI tft = TFT_eSPI();
|
TFT_eSPI tft = TFT_eSPI();
|
||||||
TFT_eSprite sprite = TFT_eSprite(&tft);
|
TFT_eSprite sprite = TFT_eSprite(&tft);
|
||||||
|
|
||||||
#ifdef HELTEC_WIRELESS_TRACKER
|
#ifdef HELTEC_WIRELESS_TRACKER
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
String lastEpaperText;
|
String lastEpaperText;
|
||||||
#else
|
#else
|
||||||
#include <Adafruit_GFX.h>
|
#include <Adafruit_GFX.h>
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#ifdef HAS_SH1106
|
||||||
#include <Adafruit_SH110X.h>
|
#include <Adafruit_SH110X.h>
|
||||||
Adafruit_SH1106G display(128, 64, &Wire, OLED_RST);
|
Adafruit_SH1106G display(128, 64, &Wire, OLED_RST);
|
||||||
#else
|
#else
|
||||||
@@ -117,7 +117,7 @@ void displaySetup() {
|
|||||||
digitalWrite(OLED_RST, HIGH);
|
digitalWrite(OLED_RST, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#ifdef HAS_SH1106
|
||||||
if (display.begin(0x3c, false)) {
|
if (display.begin(0x3c, false)) {
|
||||||
displayFound = true;
|
displayFound = true;
|
||||||
if (Config.display.turn180) display.setRotation(2);
|
if (Config.display.turn180) display.setRotation(2);
|
||||||
@@ -157,7 +157,7 @@ void displayToggle(bool toggle) {
|
|||||||
display.printCenter("EPAPER Display Disabled by toggle...");
|
display.printCenter("EPAPER Display Disabled by toggle...");
|
||||||
display.update();
|
display.update();
|
||||||
#else
|
#else
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#ifdef HAS_SH1106
|
||||||
if (displayFound) display.oled_command(SH110X_DISPLAYON);
|
if (displayFound) display.oled_command(SH110X_DISPLAYON);
|
||||||
#else
|
#else
|
||||||
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
|
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
|
||||||
@@ -171,12 +171,12 @@ void displayToggle(bool toggle) {
|
|||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
display.update();
|
display.update();
|
||||||
#else
|
#else
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#ifdef HAS_SH1106
|
||||||
if (displayFound) display.oled_command(SH110X_DISPLAYOFF);
|
if (displayFound) display.oled_command(SH110X_DISPLAYOFF);
|
||||||
#else
|
#else
|
||||||
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
|
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ void displayShow(const String& header, const String& line1, const String& line2,
|
|||||||
#else
|
#else
|
||||||
if (displayFound) {
|
if (displayFound) {
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#ifdef HAS_SH1106
|
||||||
display.setTextColor(SH110X_WHITE);
|
display.setTextColor(SH110X_WHITE);
|
||||||
#else
|
#else
|
||||||
display.setTextColor(WHITE);
|
display.setTextColor(WHITE);
|
||||||
@@ -234,7 +234,7 @@ 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)
|
#ifdef HAS_SH1106
|
||||||
display.setContrast(1);
|
display.setContrast(1);
|
||||||
#else
|
#else
|
||||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||||
@@ -288,7 +288,7 @@ void displayShow(const String& header, const String& line1, const String& line2,
|
|||||||
#else
|
#else
|
||||||
if (displayFound) {
|
if (displayFound) {
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
#ifdef HAS_SH1106
|
||||||
display.setTextColor(SH110X_WHITE);
|
display.setTextColor(SH110X_WHITE);
|
||||||
#else
|
#else
|
||||||
display.setTextColor(WHITE);
|
display.setTextColor(WHITE);
|
||||||
@@ -301,7 +301,7 @@ 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)
|
#ifdef HAS_SH1106
|
||||||
display.setContrast(1);
|
display.setContrast(1);
|
||||||
#else
|
#else
|
||||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||||
|
|||||||
@@ -29,29 +29,20 @@ bool validateKISSFrame(const String& kissFormattedFrame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String encodeAddressAX25(String tnc2Address) {
|
String encodeAddressAX25(String tnc2Address) {
|
||||||
bool hasBeenDigipited = tnc2Address.indexOf('*') != -1;
|
bool hasBeenDigipited = tnc2Address.indexOf('*') != -1;
|
||||||
int tnc2AddressIndex = tnc2Address.indexOf('-');
|
if (tnc2Address.indexOf('-') == -1) {
|
||||||
if (tnc2AddressIndex == -1) {
|
if (hasBeenDigipited) tnc2Address = tnc2Address.substring(0, tnc2Address.length() - 1);
|
||||||
if (hasBeenDigipited) {
|
|
||||||
tnc2Address = tnc2Address.substring(0, tnc2Address.length() - 1);
|
|
||||||
}
|
|
||||||
tnc2Address += "-0";
|
tnc2Address += "-0";
|
||||||
}
|
}
|
||||||
|
|
||||||
int separatorIndex = tnc2AddressIndex;
|
int separatorIndex = tnc2Address.indexOf('-');;
|
||||||
int ssid = tnc2Address.substring(separatorIndex + 1).toInt();
|
int ssid = tnc2Address.substring(separatorIndex + 1).toInt();
|
||||||
|
|
||||||
String kissAddress = "";
|
String kissAddress = "";
|
||||||
for (int i = 0; i < 6; ++i) {
|
for (int i = 0; i < 6; ++i) {
|
||||||
char addressChar;
|
char addressChar = ' ';
|
||||||
if (tnc2Address.length() > i && i < separatorIndex) {
|
if (tnc2Address.length() > i && i < separatorIndex) addressChar = tnc2Address.charAt(i);
|
||||||
addressChar = tnc2Address.charAt(i);
|
|
||||||
} else {
|
|
||||||
addressChar = ' ';
|
|
||||||
}
|
|
||||||
kissAddress += (char)(addressChar << 1);
|
kissAddress += (char)(addressChar << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
kissAddress += (char)((ssid << 1) | 0b01100000 | (hasBeenDigipited ? HAS_BEEN_DIGIPITED_MASK : 0));
|
kissAddress += (char)((ssid << 1) | 0b01100000 | (hasBeenDigipited ? HAS_BEEN_DIGIPITED_MASK : 0));
|
||||||
return kissAddress;
|
return kissAddress;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -43,7 +43,7 @@ bool transmitFlag = true;
|
|||||||
#ifdef HAS_SX1268
|
#ifdef HAS_SX1268
|
||||||
#if defined(LIGHTGATEWAY_1_0) || defined(LIGHTGATEWAY_PLUS_1_0)
|
#if defined(LIGHTGATEWAY_1_0) || defined(LIGHTGATEWAY_PLUS_1_0)
|
||||||
SPIClass loraSPI(FSPI);
|
SPIClass loraSPI(FSPI);
|
||||||
SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN, loraSPI);
|
SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN, loraSPI);
|
||||||
#else
|
#else
|
||||||
SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
|
SX1268 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
|
||||||
#endif
|
#endif
|
||||||
@@ -100,11 +100,11 @@ namespace LoRa_Utils {
|
|||||||
while (true);
|
while (true);
|
||||||
}
|
}
|
||||||
#endif*/
|
#endif*/
|
||||||
|
|
||||||
radio.setSpreadingFactor(Config.loramodule.rxSpreadingFactor);
|
radio.setSpreadingFactor(Config.loramodule.rxSpreadingFactor);
|
||||||
radio.setCodingRate(Config.loramodule.rxCodingRate4);
|
radio.setCodingRate(Config.loramodule.rxCodingRate4);
|
||||||
float signalBandwidth = Config.loramodule.rxSignalBandwidth / 1000;
|
float signalBandwidth = Config.loramodule.rxSignalBandwidth / 1000;
|
||||||
radio.setBandwidth(signalBandwidth);
|
radio.setBandwidth(signalBandwidth);
|
||||||
radio.setCRC(true);
|
radio.setCRC(true);
|
||||||
|
|
||||||
#if (defined(RADIO_RXEN) && defined(RADIO_TXEN)) // QRP Labs LightGateway has 400M22S (SX1268)
|
#if (defined(RADIO_RXEN) && defined(RADIO_TXEN)) // QRP Labs LightGateway has 400M22S (SX1268)
|
||||||
@@ -174,7 +174,7 @@ namespace LoRa_Utils {
|
|||||||
changeFreqTx();
|
changeFreqTx();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INTERNAL_LED_PIN
|
#ifdef INTERNAL_LED_PIN
|
||||||
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, HIGH); // disabled in Ultra Eco Mode
|
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, HIGH); // disabled in Ultra Eco Mode
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -95,7 +95,7 @@ namespace MQTT_Utils {
|
|||||||
void setup() {
|
void setup() {
|
||||||
if (!Config.mqtt.active) return;
|
if (!Config.mqtt.active) return;
|
||||||
pubSub.setClient(mqttClient);
|
pubSub.setClient(mqttClient);
|
||||||
pubSub.setCallback(receivedFromMqtt);
|
pubSub.setCallback(receivedFromMqtt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -25,6 +25,8 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#define SECS_TO_WAIT 3 // soon to be deleted...
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern uint32_t lastRxTime;
|
extern uint32_t lastRxTime;
|
||||||
@@ -40,17 +42,16 @@ std::vector<LastHeardStation> lastHeardObjects;
|
|||||||
struct OutputPacketBuffer {
|
struct OutputPacketBuffer {
|
||||||
String packet;
|
String packet;
|
||||||
bool isBeacon;
|
bool isBeacon;
|
||||||
|
OutputPacketBuffer(const String& p, bool b) : packet(p), isBeacon(b) {}
|
||||||
};
|
};
|
||||||
std::vector<OutputPacketBuffer> outputPacketBuffer;
|
std::vector<OutputPacketBuffer> outputPacketBuffer;
|
||||||
|
|
||||||
struct Packet25SegBuffer {
|
struct Packet25SegBuffer {
|
||||||
uint32_t receivedTime;
|
uint32_t receivedTime;
|
||||||
String station;
|
uint32_t hash;
|
||||||
String payload;
|
|
||||||
};
|
};
|
||||||
std::vector<Packet25SegBuffer> packet25SegBuffer;
|
std::vector<Packet25SegBuffer> packet25SegBuffer;
|
||||||
|
|
||||||
|
|
||||||
bool saveNewDigiEcoModeConfig = false;
|
bool saveNewDigiEcoModeConfig = false;
|
||||||
bool packetIsBeacon = false;
|
bool packetIsBeacon = false;
|
||||||
|
|
||||||
@@ -59,19 +60,18 @@ namespace STATION_Utils {
|
|||||||
|
|
||||||
std::vector<String> loadCallsignList(const String& list) {
|
std::vector<String> loadCallsignList(const String& list) {
|
||||||
std::vector<String> loadedList;
|
std::vector<String> loadedList;
|
||||||
|
int start = 0;
|
||||||
|
int listLength = list.length();
|
||||||
|
|
||||||
String callsigns = list;
|
while (start < listLength) {
|
||||||
callsigns.trim();
|
while (start < listLength && list[start] == ' ') start++; // avoid blank spaces
|
||||||
|
if (start >= listLength) break;
|
||||||
|
|
||||||
while (callsigns.length() > 0) { // != ""
|
int end = start;
|
||||||
int spaceIndex = callsigns.indexOf(" ");
|
while (end < listLength && list[end] != ' ') end++; // find another blank space or reach listLength
|
||||||
if (spaceIndex == -1) { // No more spaces, add the last part
|
|
||||||
loadedList.push_back(callsigns);
|
loadedList.emplace_back(list.substring(start, end));
|
||||||
break;
|
start = end + 1; // keep on searching if listLength not reached
|
||||||
}
|
|
||||||
loadedList.push_back(callsigns.substring(0, spaceIndex));
|
|
||||||
callsigns = callsigns.substring(spaceIndex + 1);
|
|
||||||
callsigns.trim(); // Trim in case of multiple spaces
|
|
||||||
}
|
}
|
||||||
return loadedList;
|
return loadedList;
|
||||||
}
|
}
|
||||||
@@ -85,8 +85,9 @@ namespace STATION_Utils {
|
|||||||
for (size_t i = 0; i < list.size(); i++) {
|
for (size_t i = 0; i < list.size(); i++) {
|
||||||
int wildcardIndex = list[i].indexOf("*");
|
int wildcardIndex = list[i].indexOf("*");
|
||||||
if (wildcardIndex >= 0) {
|
if (wildcardIndex >= 0) {
|
||||||
String wildcard = list[i].substring(0, wildcardIndex);
|
if (wildcardIndex >= 2 && callsign.length() >= wildcardIndex && strncmp(callsign.c_str(), list[i].c_str(), wildcardIndex) == 0) {
|
||||||
if (callsign.startsWith(wildcard)) return true;
|
return true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (list[i] == callsign) return true;
|
if (list[i] == callsign) return true;
|
||||||
}
|
}
|
||||||
@@ -127,36 +128,33 @@ namespace STATION_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void deleteNotHeard() {
|
void deleteNotHeard() {
|
||||||
std::vector<LastHeardStation> lastHeardStation_temp;
|
uint32_t currentTime = millis();
|
||||||
for (int i = 0; i < lastHeardStations.size(); i++) {
|
uint32_t timeout = Config.rememberStationTime * 60UL * 1000UL;
|
||||||
if (millis() - lastHeardStations[i].lastHeardTime < Config.rememberStationTime * 60 * 1000) {
|
|
||||||
lastHeardStation_temp.push_back(lastHeardStations[i]);
|
for (int i = lastHeardStations.size() - 1; i >= 0; i--) {
|
||||||
|
if (currentTime - lastHeardStations[i].lastHeardTime >= timeout) {
|
||||||
|
lastHeardStations.erase(lastHeardStations.begin() + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastHeardStations.clear();
|
|
||||||
for (int j = 0; j < lastHeardStation_temp.size(); j++) {
|
|
||||||
lastHeardStations.push_back(lastHeardStation_temp[j]);
|
|
||||||
}
|
|
||||||
lastHeardStation_temp.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateLastHeard(const String& station) {
|
void updateLastHeard(const String& station) {
|
||||||
deleteNotHeard();
|
deleteNotHeard();
|
||||||
bool stationHeard = false;
|
uint32_t currentTime = millis();
|
||||||
for (int i = 0; i < lastHeardStations.size(); i++) {
|
for (size_t i = 0; i < lastHeardStations.size(); i++) {
|
||||||
if (lastHeardStations[i].station == station) {
|
if (lastHeardStations[i].station == station) {
|
||||||
lastHeardStations[i].lastHeardTime = millis();
|
lastHeardStations[i].lastHeardTime = currentTime;
|
||||||
stationHeard = true;
|
Utils::showActiveStations();
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station});
|
lastHeardStations.emplace_back(LastHeardStation{currentTime, station});
|
||||||
Utils::showActiveStations();
|
Utils::showActiveStations();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wasHeard(const String& station) {
|
bool wasHeard(const String& station) {
|
||||||
deleteNotHeard();
|
deleteNotHeard();
|
||||||
for (int i = 0; i < lastHeardStations.size(); i++) {
|
for (size_t i = 0; i < lastHeardStations.size(); i++) {
|
||||||
if (lastHeardStations[i].station == station) {
|
if (lastHeardStations[i].station == station) {
|
||||||
Utils::println(" ---> Listened Station");
|
Utils::println(" ---> Listened Station");
|
||||||
return true;
|
return true;
|
||||||
@@ -166,18 +164,33 @@ namespace STATION_Utils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clean25SegBuffer() {
|
void clean25SegHashBuffer() {
|
||||||
if (!packet25SegBuffer.empty() && (millis() - packet25SegBuffer[0].receivedTime) > 25 * 1000) packet25SegBuffer.erase(packet25SegBuffer.begin());
|
uint32_t currentTime = millis();
|
||||||
}
|
for (int i = packet25SegBuffer.size() - 1; i >= 0; i--) {
|
||||||
|
if ((currentTime - packet25SegBuffer[i].receivedTime) > 25 * 1000) {
|
||||||
bool check25SegBuffer(const String& station, const String& textMessage) {
|
packet25SegBuffer.erase(packet25SegBuffer.begin() + i);
|
||||||
if (!packet25SegBuffer.empty()) {
|
|
||||||
for (int i = 0; i < packet25SegBuffer.size(); i++) {
|
|
||||||
if (packet25SegBuffer[i].station == station && packet25SegBuffer[i].payload == textMessage) return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
packet25SegBuffer.emplace_back(Packet25SegBuffer{millis(), station, textMessage});
|
}
|
||||||
return true;
|
|
||||||
|
uint32_t makeHash(const String& station, const String& payload) { // DJB2 Hash
|
||||||
|
uint32_t h = 5381;
|
||||||
|
for (size_t i = 0; i < station.length(); i++)
|
||||||
|
h = ((h << 5) + h) + station[i];
|
||||||
|
for (size_t i = 0; i < payload.length(); i++)
|
||||||
|
h = ((h << 5) + h) + payload[i];
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isIn25SegHashBuffer(const String& station, const String& textMessage) {
|
||||||
|
clean25SegHashBuffer();
|
||||||
|
uint32_t newHash = makeHash(station, textMessage);
|
||||||
|
uint32_t currentTime = millis();
|
||||||
|
for (int i = 0; i < packet25SegBuffer.size(); i++) {
|
||||||
|
if (packet25SegBuffer[i].hash == newHash) return true;
|
||||||
|
}
|
||||||
|
packet25SegBuffer.push_back({currentTime, newHash});
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void processOutputPacketBufferUltraEcoMode() {
|
void processOutputPacketBufferUltraEcoMode() {
|
||||||
@@ -201,7 +214,7 @@ namespace STATION_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void processOutputPacketBuffer() {
|
void processOutputPacketBuffer() {
|
||||||
int timeToWait = 3 * 1000; // 3 segs between packet Tx and also Rx ???
|
int timeToWait = SECS_TO_WAIT * 1000; // 3 segs between packet Tx and also Rx ???
|
||||||
uint32_t lastRx = millis() - lastRxTime;
|
uint32_t lastRx = millis() - lastRxTime;
|
||||||
uint32_t lastTx = millis() - lastTxTime;
|
uint32_t lastTx = millis() - lastTxTime;
|
||||||
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
|
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
|
||||||
@@ -229,11 +242,7 @@ namespace STATION_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addToOutputPacketBuffer(const String& packet, bool flag) {
|
void addToOutputPacketBuffer(const String& packet, bool flag) {
|
||||||
OutputPacketBuffer entry;
|
outputPacketBuffer.emplace_back(OutputPacketBuffer{packet, flag});
|
||||||
entry.packet = packet;
|
|
||||||
entry.isBeacon = flag;
|
|
||||||
|
|
||||||
outputPacketBuffer.push_back(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -29,10 +29,11 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern bool sendStartTelemetry;
|
|
||||||
|
|
||||||
int telemetryCounter = random(1,999);
|
int telemetryCounter = random(1,999);
|
||||||
|
uint32_t telemetryEUPTime = 0;
|
||||||
|
bool sendEUP = false; // Equations Units Parameters
|
||||||
|
|
||||||
|
|
||||||
namespace TELEMETRY_Utils {
|
namespace TELEMETRY_Utils {
|
||||||
@@ -89,7 +90,7 @@ namespace TELEMETRY_Utils {
|
|||||||
sendBaseTelemetryPacket("EQNS.", getEquationCoefficients());
|
sendBaseTelemetryPacket("EQNS.", getEquationCoefficients());
|
||||||
sendBaseTelemetryPacket("UNIT.", getUnitLabels());
|
sendBaseTelemetryPacket("UNIT.", getUnitLabels());
|
||||||
sendBaseTelemetryPacket("PARM.", getParameterNames());
|
sendBaseTelemetryPacket("PARM.", getParameterNames());
|
||||||
sendStartTelemetry = false;
|
sendEUP = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType) {
|
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType) {
|
||||||
@@ -106,7 +107,7 @@ namespace TELEMETRY_Utils {
|
|||||||
case 3: tempValue = (value * 8); break; // Pressure
|
case 3: tempValue = (value * 8); break; // Pressure
|
||||||
default: tempValue = value; break;
|
default: tempValue = value; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int firstByte = tempValue / 91;
|
int firstByte = tempValue / 91;
|
||||||
tempValue -= firstByte * 91;
|
tempValue -= firstByte * 91;
|
||||||
@@ -127,4 +128,11 @@ namespace TELEMETRY_Utils {
|
|||||||
return telemetry;
|
return telemetry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void checkEUPInterval() {
|
||||||
|
if (telemetryEUPTime == 0 || millis() - telemetryEUPTime > 24UL * 60UL * 60UL * 1000UL) {
|
||||||
|
sendEUP = true;
|
||||||
|
telemetryEUPTime = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -45,7 +45,7 @@ String inputSerialBuffer = "";
|
|||||||
|
|
||||||
|
|
||||||
namespace TNC_Utils {
|
namespace TNC_Utils {
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
if (Config.tnc.enableServer && Config.digi.ecoMode == 0) {
|
if (Config.tnc.enableServer && Config.digi.ecoMode == 0) {
|
||||||
tncServer.stop();
|
tncServer.stop();
|
||||||
|
|||||||
112
src/utils.cpp
112
src/utils.cpp
@@ -58,11 +58,11 @@ extern bool backupDigiMode;
|
|||||||
extern bool shouldSleepLowVoltage;
|
extern bool shouldSleepLowVoltage;
|
||||||
extern bool transmitFlag;
|
extern bool transmitFlag;
|
||||||
extern bool passcodeValid;
|
extern bool passcodeValid;
|
||||||
|
extern bool sendEUP; // Equations Units Parameters
|
||||||
|
|
||||||
extern std::vector<LastHeardStation> lastHeardStations;
|
extern std::vector<LastHeardStation> lastHeardStations;
|
||||||
|
|
||||||
bool statusAfterBoot = true;
|
bool statusUpdate = true;
|
||||||
bool sendStartTelemetry = true;
|
|
||||||
bool beaconUpdate = false;
|
bool beaconUpdate = false;
|
||||||
uint32_t lastBeaconTx = 0;
|
uint32_t lastBeaconTx = 0;
|
||||||
uint32_t lastScreenOn = millis();
|
uint32_t lastScreenOn = millis();
|
||||||
@@ -75,26 +75,30 @@ String secondaryBeaconPacket;
|
|||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
void processStatus() {
|
void processStatus() {
|
||||||
String status = APRSPacketLib::generateBasePacket(Config.callsign, "APLRG1", Config.beacon.path);
|
bool sendOverAPRSIS = Config.beacon.sendViaAPRSIS && Config.aprs_is.active && WiFi.status() == WL_CONNECTED;
|
||||||
|
bool sendOverRF = !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF;
|
||||||
|
|
||||||
if (WiFi.status() == WL_CONNECTED && Config.aprs_is.active && Config.beacon.sendViaAPRSIS) {
|
if (!sendOverAPRSIS && !sendOverRF) {
|
||||||
delay(1000);
|
statusUpdate = false;
|
||||||
status.concat(",qAC:>");
|
return;
|
||||||
status.concat(Config.beacon.statusPacket);
|
|
||||||
APRS_IS_Utils::upload(status);
|
|
||||||
SYSLOG_Utils::log(2, status, 0, 0.0, 0); // APRSIS TX
|
|
||||||
}
|
}
|
||||||
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
|
|
||||||
status.concat(":>");
|
String statusPacket = APRSPacketLib::generateBasePacket(Config.callsign, "APLRG1", Config.beacon.path);
|
||||||
status.concat(Config.beacon.statusPacket);
|
statusPacket += sendOverAPRSIS ? ",qAC:>" : ":>";
|
||||||
STATION_Utils::addToOutputPacketBuffer(status, true); // treated also as beacon on Tx Freq
|
statusPacket += Config.beacon.statusPacket;
|
||||||
|
|
||||||
|
if (sendOverAPRSIS) {
|
||||||
|
APRS_IS_Utils::upload(statusPacket);
|
||||||
|
SYSLOG_Utils::log(2, statusPacket, 0, 0.0, 0); // APRSIS TX
|
||||||
|
} else {
|
||||||
|
STATION_Utils::addToOutputPacketBuffer(statusPacket, true); // treated also as beacon on Tx Freq
|
||||||
}
|
}
|
||||||
statusAfterBoot = false;
|
statusUpdate = false;
|
||||||
lastStatusTx = millis();
|
lastStatusTx = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkStatusInterval() {
|
void checkStatusInterval() {
|
||||||
if (lastStatusTx == 0 || millis() - lastStatusTx > DAY_MS) statusAfterBoot = true;
|
if (lastStatusTx == 0 || millis() - lastStatusTx > DAY_MS) statusUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getLocalIP() {
|
String getLocalIP() {
|
||||||
@@ -157,7 +161,8 @@ namespace Utils {
|
|||||||
if (beaconUpdate) {
|
if (beaconUpdate) {
|
||||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true);
|
if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true);
|
||||||
|
|
||||||
if (sendStartTelemetry &&
|
TELEMETRY_Utils::checkEUPInterval();
|
||||||
|
if (sendEUP &&
|
||||||
Config.battery.sendVoltageAsTelemetry &&
|
Config.battery.sendVoltageAsTelemetry &&
|
||||||
!Config.wxsensor.active &&
|
!Config.wxsensor.active &&
|
||||||
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&
|
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&
|
||||||
@@ -290,7 +295,7 @@ namespace Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkStatusInterval();
|
checkStatusInterval();
|
||||||
if (statusAfterBoot && Config.beacon.statusActive && !Config.beacon.statusPacket.isEmpty()) processStatus();
|
if (statusUpdate && Config.beacon.statusActive && !Config.beacon.statusPacket.isEmpty()) processStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkDisplayInterval() {
|
void checkDisplayInterval() {
|
||||||
@@ -417,44 +422,53 @@ namespace Utils {
|
|||||||
|
|
||||||
bool callsignIsValid(const String& callsign) {
|
bool callsignIsValid(const String& callsign) {
|
||||||
if (callsign == "WLNK-1") return true;
|
if (callsign == "WLNK-1") return true;
|
||||||
|
int totalCallsignLength = callsign.length();
|
||||||
|
if (totalCallsignLength < 4) return false;
|
||||||
|
|
||||||
String cleanCallsign;
|
int hyphenIndex = callsign.indexOf("-");
|
||||||
int hypenCallsignIndex = callsign.indexOf("-");
|
int baseCallsignLength = (hyphenIndex > 0) ? hyphenIndex : totalCallsignLength;
|
||||||
if (hypenCallsignIndex > 0) { // SSID Validation
|
|
||||||
cleanCallsign = callsign.substring(0, hypenCallsignIndex);
|
if (hyphenIndex > 0) { // SSID Validation
|
||||||
String ssid = callsign.substring(hypenCallsignIndex + 1);
|
if (hyphenIndex < 4) return false; // base Callsign must have at least 4 characters
|
||||||
if (ssid.indexOf("-") != -1 || ssid.length() > 2) return false;
|
int ssidStart = hyphenIndex + 1;
|
||||||
if (ssid.length() == 2 && ssid[0] == '0') return false;
|
int ssidLength = totalCallsignLength - ssidStart;
|
||||||
for (int i = 0; i < ssid.length(); i++) {
|
if (ssidLength == 0 || ssidLength > 2) return false;
|
||||||
if (!isAlphaNumeric(ssid[i])) return false;
|
if (callsign.indexOf('-', ssidStart) != -1) return false; // avoid another "-" in ssid
|
||||||
|
if (ssidLength == 2 && callsign[ssidStart] == '0') return false; // ssid can't start with "0"
|
||||||
|
for (int i = ssidStart; i < totalCallsignLength; i++) {
|
||||||
|
if (!isDigit(callsign[i])) return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseCallsignLength < 4 || baseCallsignLength > 6) return false;
|
||||||
|
|
||||||
|
bool padded = false; // Callsigns with 4 characters like A0AA are padded into 5 characters for further analisis : A0AA --> _A0AA
|
||||||
|
if (baseCallsignLength == 4 && isAlpha(callsign[0]) && isDigit(callsign[1]) && isAlpha(callsign[2]) && isAlpha(callsign[3])) padded = true;
|
||||||
|
char c0, c1, c2, c3;
|
||||||
|
if (padded) {
|
||||||
|
c0 = ' ';
|
||||||
|
c1 = callsign[0];
|
||||||
|
c2 = callsign[1];
|
||||||
|
c3 = callsign[2];
|
||||||
} else {
|
} else {
|
||||||
cleanCallsign = callsign;
|
c0 = callsign[0];
|
||||||
|
c1 = callsign[1];
|
||||||
|
c2 = callsign[2];
|
||||||
|
c3 = callsign[3];
|
||||||
|
}
|
||||||
|
if (!isDigit(c2) || !isAlpha(c3)) { // __0A__ must be validated
|
||||||
|
if (c0 != 'R' && !isDigit(c1) && !isAlpha(c2)) return false; // to accepto R0A___
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanCallsign.length() < 4 || cleanCallsign.length() > 6) return false;
|
bool isValid =
|
||||||
|
((isAlphaNumeric(c0) || c0 == ' ') && isAlpha(c1)) || // AA0A (+A+A) + _A0AA (+A) + 0A0A (+A+A)
|
||||||
|
(isAlpha(c0) && isDigit(c1)) || // A00A (+A+A)
|
||||||
|
(c0 == 'R' && baseCallsignLength == 6 && isDigit(c1) && isAlpha(c2) && isAlpha(c3) && isAlpha(callsign[4])); // R0AA (+A+A)
|
||||||
|
if (!isValid) return false; // also 00__ avoided
|
||||||
|
|
||||||
if (cleanCallsign.length() < 6 && isAlpha(cleanCallsign[0]) && isDigit(cleanCallsign[1]) && isAlpha(cleanCallsign[2]) && isAlpha(cleanCallsign[3]) ) {
|
if (baseCallsignLength > 4 ) { // to validate ____AA
|
||||||
cleanCallsign = " " + cleanCallsign; // A0AA --> _A0AA
|
for (int i = 4; i < baseCallsignLength; i++) {
|
||||||
}
|
if (!isAlpha(callsign[i])) return false;
|
||||||
|
|
||||||
if (!isDigit(cleanCallsign[2]) || !isAlpha(cleanCallsign[3])) { // __0A__ must be validated
|
|
||||||
if (cleanCallsign[0] != 'R' && !isDigit(cleanCallsign[1]) && !isAlpha(cleanCallsign[2])) return false; // to accepto R0A___
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isValid = false;
|
|
||||||
if ((isAlphaNumeric(cleanCallsign[0]) || cleanCallsign[0] == ' ') && isAlpha(cleanCallsign[1])) {
|
|
||||||
isValid = true; // AA0A (+A+A) + _A0AA (+A) + 0A0A (+A+A)
|
|
||||||
} else if (isAlpha(cleanCallsign[0]) && isDigit(cleanCallsign[1])) {
|
|
||||||
isValid = true; // A00A (+A+A)
|
|
||||||
} else if (cleanCallsign[0] == 'R' && cleanCallsign.length() == 6 && isDigit(cleanCallsign[1]) && isAlpha(cleanCallsign[2]) && isAlpha(cleanCallsign[3]) && isAlpha(cleanCallsign[4])) {
|
|
||||||
isValid = true; // R0AA (+A+A)
|
|
||||||
}
|
|
||||||
if (!isValid) return false; // also 00__ avoided
|
|
||||||
|
|
||||||
if (cleanCallsign.length() > 4) { // to validate ____AA
|
|
||||||
for (int i = 5; i <= cleanCallsign.length(); i++) {
|
|
||||||
if (!isAlpha(cleanCallsign[i - 1])) return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -88,7 +88,7 @@ namespace WEB_Utils {
|
|||||||
return request->requestAuthentication();
|
return request->requestAuthentication();
|
||||||
|
|
||||||
File file = SPIFFS.open("/igate_conf.json");
|
File file = SPIFFS.open("/igate_conf.json");
|
||||||
|
|
||||||
String fileContent;
|
String fileContent;
|
||||||
while(file.available()){
|
while(file.available()){
|
||||||
fileContent += String((char)file.read());
|
fileContent += String((char)file.read());
|
||||||
@@ -161,7 +161,7 @@ namespace WEB_Utils {
|
|||||||
|
|
||||||
Config.callsign = getParamStringSafe("callsign", Config.callsign);
|
Config.callsign = getParamStringSafe("callsign", Config.callsign);
|
||||||
Config.tacticalCallsign = getParamStringSafe("tacticalCallsign", Config.tacticalCallsign);
|
Config.tacticalCallsign = getParamStringSafe("tacticalCallsign", Config.tacticalCallsign);
|
||||||
|
|
||||||
Config.wifiAutoAP.password = getParamStringSafe("wifi.autoAP.password", Config.wifiAutoAP.password);
|
Config.wifiAutoAP.password = getParamStringSafe("wifi.autoAP.password", Config.wifiAutoAP.password);
|
||||||
Config.wifiAutoAP.timeout = getParamIntSafe("wifi.autoAP.timeout", Config.wifiAutoAP.timeout);
|
Config.wifiAutoAP.timeout = getParamIntSafe("wifi.autoAP.timeout", Config.wifiAutoAP.timeout);
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ namespace WEB_Utils {
|
|||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
||||||
response->addHeader("Location", "/?success=1");
|
response->addHeader("Location", "/?success=1");
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|
||||||
displayToggle(false);
|
displayToggle(false);
|
||||||
delay(500);
|
delay(500);
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
@@ -309,7 +309,7 @@ namespace WEB_Utils {
|
|||||||
errorPage += "<h1>Configuration Error:</h1>";
|
errorPage += "<h1>Configuration Error:</h1>";
|
||||||
errorPage += "<p>Couldn't save new configuration. Please try again.</p>";
|
errorPage += "<p>Couldn't save new configuration. Please try again.</p>";
|
||||||
errorPage += "<a href='/'>Back</a></body></html>";
|
errorPage += "<a href='/'>Back</a></body></html>";
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(500, "text/html", errorPage);
|
AsyncWebServerResponse *response = request->beginResponse(500, "text/html", errorPage);
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
*
|
*
|
||||||
* This file is part of LoRa APRS iGate.
|
* This file is part of LoRa APRS iGate.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -66,7 +66,7 @@ namespace WIFI_Utils {
|
|||||||
backupDigiMode = true;
|
backupDigiMode = true;
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
lastBackupDigiTime = currentTime;
|
lastBackupDigiTime = currentTime;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Serial.println("Reconnecting to WiFi...");
|
Serial.println("Reconnecting to WiFi...");
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
|
|||||||
63
variants/ESP32_9M2IBR_1W_LoRa_GPS/board_pinout.h
Normal file
63
variants/ESP32_9M2IBR_1W_LoRa_GPS/board_pinout.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||||
|
*
|
||||||
|
* This file is part of LoRa APRS iGate.
|
||||||
|
*
|
||||||
|
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOARD_PINOUT_H_
|
||||||
|
#define BOARD_PINOUT_H_
|
||||||
|
|
||||||
|
// LoRa Radio
|
||||||
|
#define HAS_SX1268
|
||||||
|
#define HAS_1W_LORA
|
||||||
|
#define HAS_TCXO
|
||||||
|
#define RADIO_SCLK_PIN 18
|
||||||
|
#define RADIO_MISO_PIN 19
|
||||||
|
#define RADIO_MOSI_PIN 23
|
||||||
|
#define RADIO_CS_PIN 5
|
||||||
|
#define RADIO_RST_PIN 27
|
||||||
|
#define RADIO_DIO1_PIN 12
|
||||||
|
#define RADIO_BUSY_PIN 14
|
||||||
|
#define RADIO_RXEN 32
|
||||||
|
#define RADIO_TXEN 25
|
||||||
|
#define RADIO_WAKEUP_PIN RADIO_DIO1_PIN
|
||||||
|
#define GPIO_WAKEUP_PIN GPIO_SEL_12
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
#define USE_WIRE_WITH_OLED_PINS
|
||||||
|
|
||||||
|
// Display
|
||||||
|
#define HAS_DISPLAY
|
||||||
|
#define HAS_SH1106
|
||||||
|
|
||||||
|
#undef OLED_SDA
|
||||||
|
#undef OLED_SCL
|
||||||
|
#undef OLED_RST
|
||||||
|
|
||||||
|
#define OLED_SDA 21
|
||||||
|
#define OLED_SCL 22
|
||||||
|
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
||||||
|
|
||||||
|
// GPS
|
||||||
|
#define HAS_GPS
|
||||||
|
#define GPS_BAUDRATE 9600
|
||||||
|
#define GPS_RX 17
|
||||||
|
#define GPS_TX 16
|
||||||
|
|
||||||
|
// Aditional Config
|
||||||
|
#define INTERNAL_LED_PIN 2
|
||||||
|
#define BATTERY_PIN 35
|
||||||
|
|
||||||
|
#endif
|
||||||
12
variants/ESP32_9M2IBR_1W_LoRa_GPS/platformio.ini
Normal file
12
variants/ESP32_9M2IBR_1W_LoRa_GPS/platformio.ini
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[env:ESP32_9M2IBR_1W_LoRa_GPS]
|
||||||
|
board = esp32dev
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
-D RADIOLIB_EXCLUDE_LR11X0=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX127X=1
|
||||||
|
-D RADIOLIB_EXCLUDE_SX128X=1
|
||||||
|
-D ESP32_9M2IBR_1W_LoRa_GPS
|
||||||
|
lib_deps =
|
||||||
|
${common.lib_deps}
|
||||||
|
${common.display_libs}
|
||||||
|
adafruit/Adafruit SH110X @ 2.1.10
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
#define INTERNAL_LED_PIN 25
|
#define INTERNAL_LED_PIN 25
|
||||||
#define BATTERY_PIN 37
|
#define BATTERY_PIN 37
|
||||||
|
|
||||||
#define ADC_CTRL 21
|
#define ADC_CTRL_PIN 21
|
||||||
#define ADC_CTRL_ON_STATE LOW
|
#define ADC_CTRL_ON_STATE LOW
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define HAS_DISPLAY
|
#define HAS_DISPLAY
|
||||||
|
#define HAS_SH1106
|
||||||
|
|
||||||
#undef OLED_SDA
|
#undef OLED_SDA
|
||||||
#undef OLED_SCL
|
#undef OLED_SCL
|
||||||
|
|||||||
Reference in New Issue
Block a user