+
+
+
+
+
diff --git a/data_embed/script.js b/data_embed/script.js
index e0c26fa..dab331f 100644
--- a/data_embed/script.js
+++ b/data_embed/script.js
@@ -237,8 +237,10 @@ function loadSettings(settings) {
RebootModeTime.disabled = !RebootModeCheckbox.check;
// WiFi Auto AP
+ document.getElementById("wifi.autoAP.enabled").checked = settings.wifi.autoAP.enabled;
document.getElementById("wifi.autoAP.password").value = settings.wifi.autoAP.password;
document.getElementById("wifi.autoAP.timeout").value = settings.wifi.autoAP.timeout;
+ toggleWiFiAutoAPFields();
// OTA
document.getElementById("ota.username").value = settings.ota.username;
@@ -432,6 +434,18 @@ WebadminCheckbox.addEventListener("change", function () {
WebadminPassword.disabled = !this.checked;
});
+// WiFi Auto AP Switches
+const WiFiAutoAPCheckbox = document.querySelector('input[name="wifi.autoAP.enabled"]');
+WiFiAutoAPCheckbox.addEventListener("change", function () {
+ toggleWiFiAutoAPFields();
+});
+
+function toggleWiFiAutoAPFields() {
+ const isEnabled = WiFiAutoAPCheckbox.checked;
+ const autoAPConfig = document.getElementById('wifi-autoap-config');
+ if (autoAPConfig) autoAPConfig.style.display = isEnabled ? 'block' : 'none';
+}
+
document.querySelector(".new button").addEventListener("click", function () {
const networksContainer = document.querySelector(".list-networks");
diff --git a/include/configuration.h b/include/configuration.h
index abf5cc7..38080c3 100644
--- a/include/configuration.h
+++ b/include/configuration.h
@@ -32,6 +32,7 @@ public:
class WiFi_Auto_AP {
public:
+ bool enabled; // Enable Auto AP
String password;
int timeout;
};
diff --git a/include/network_manager.h b/include/network_manager.h
new file mode 100644
index 0000000..fac3964
--- /dev/null
+++ b/include/network_manager.h
@@ -0,0 +1,82 @@
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * Class for managing network connections
+ */
+class NetworkManager
+{
+private:
+ class WiFiNetwork {
+ public:
+ String ssid;
+ String psk;
+ };
+
+ bool _wifiAPmode = false;
+ bool _wifiSTAmode = false;
+ bool _ethernetMode = false;
+ bool _ethernetConnected = false;
+ unsigned long _apStartup = 0;
+ unsigned long _apTimeout = 0;
+
+ String _hostName = "";
+ std::vector _wifiNetworks;
+
+ int _findWiFiNetworkIndex(const String& ssid) const;
+ bool _connectWiFi(const WiFiNetwork& network);
+ void _processAPTimeout();
+ void _onNetworkEvent(arduino_event_id_t event, arduino_event_info_t /*info*/);
+
+public:
+ // Constructor
+ NetworkManager();
+
+ // Destructor
+ ~NetworkManager();
+
+ // Initialize network module
+ bool setup();
+ void loop();
+
+ void setHostName(const String& hostName);
+
+ // WiFi methods
+ bool setupAP(String apName, String apPsk = "");
+ bool disableAP();
+ void setAPTimeout(unsigned long timeout);
+ void addWiFiNetwork(const String& ssid, const String& psk = "");
+ void clearWiFiNetworks();
+ bool hasWiFiNetworks() const;
+ size_t getWiFiNetworkCount() const;
+ bool connectWiFi();
+ bool connectWiFi(const String& ssid, const String& psk = "");
+ bool disconnectWiFi();
+ String getWiFiSSID() const;
+ String getWiFiAPSSID() const;
+ IPAddress getWiFiIP() const;
+ IPAddress getWiFiAPIP() const;
+ wifi_mode_t getWiFiMode() const;
+ uint8_t* getWiFimacAddress(uint8_t* mac);
+ String getWiFimacAddress(void) const;
+
+ // Ethernet methods
+ bool ethernetConnect(eth_phy_type_t type, uint8_t phy_addr, uint8_t mdc, uint8_t mdio, int power, eth_clock_mode_t clock_mode, bool use_mac_from_efuse = false);
+ bool setEthernetIP(const String& staticIP, const String& gateway, const String& subnet, const String& dns1, const String& dns2);
+ bool ethernetDisconnect();
+ IPAddress getEthernetIP() const;
+ String getEthernetMACAddress() const;
+
+ // Check if any network is available
+ bool isConnected() const;
+
+ // Check if specific network is connected
+ bool isWiFiConnected() const;
+ bool isEthernetConnected() const;
+ bool isModemConnected() const;
+
+ bool isWifiAPActive() const;
+};
diff --git a/include/ntp_utils.h b/include/ntp_utils.h
index d016a23..59acde2 100644
--- a/include/ntp_utils.h
+++ b/include/ntp_utils.h
@@ -24,7 +24,7 @@
namespace NTP_Utils {
- void setup();
+ bool setup();
void update();
String getFormatedTime();
diff --git a/include/wifi_utils.h b/include/wifi_utils.h
index a7540f8..be2e035 100644
--- a/include/wifi_utils.h
+++ b/include/wifi_utils.h
@@ -27,7 +27,6 @@ namespace WIFI_Utils {
void checkWiFi();
void startAutoAP();
void startWiFi();
- void checkAutoAPTimeout();
void setup();
}
diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp
index 47c1c07..14fbe23 100644
--- a/src/LoRa_APRS_iGate.cpp
+++ b/src/LoRa_APRS_iGate.cpp
@@ -41,9 +41,10 @@ ___________________________________________________________________*/
#include
#include
#include
-#include
+#include
#include
#include "configuration.h"
+#include "network_manager.h"
#include "aprs_is_utils.h"
#include "station_utils.h"
#include "battery_utils.h"
@@ -79,9 +80,7 @@ WiFiClient mqttClient;
bool gpsInfoToggle = false;
#endif
-uint8_t myWiFiAPIndex = 0;
-int myWiFiAPSize = Config.wifiAPs.size();
-WiFi_AP *currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
+NetworkManager *networkManager;
bool isUpdatingOTA = false;
uint32_t lastBatteryCheck = 0;
@@ -101,6 +100,12 @@ String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seven
void setup() {
Serial.begin(115200);
+ networkManager = new NetworkManager();
+ networkManager->setup();
+ if (Config.wifiAutoAP.enabled) {
+ networkManager->setAPTimeout(Config.wifiAutoAP.timeout * 60 * 1000); // Convert minutes to milliseconds
+ }
+ networkManager->setHostName("iGATE-" + Config.callsign);
POWER_Utils::setup();
Utils::setupDisplay();
LoRa_Utils::setup();
@@ -132,7 +137,7 @@ void loop() {
Utils::checkSleepByLowBatteryVoltage(1);
SLEEP_Utils::startSleeping();
} else {
- WIFI_Utils::checkAutoAPTimeout();
+ networkManager->loop();
if (isUpdatingOTA) {
ElegantOTA.loop();
@@ -161,11 +166,14 @@ void loop() {
#endif
#ifdef HAS_A7670
+ // TODO: Make this part of Network manager, and use ESP-IDF network stack instead manual AT commands
if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect();
#else
WIFI_Utils::checkWiFi();
- if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !aprsIsClient.connected()) APRS_IS_Utils::connect();
- if (Config.mqtt.active && (WiFi.status() == WL_CONNECTED) && !mqttClient.connected()) MQTT_Utils::connect();
+ if (networkManager->isConnected()) {
+ if (Config.aprs_is.active && !aprsIsClient.connected()) APRS_IS_Utils::connect();
+ if (Config.mqtt.active && !mqttClient.connected()) MQTT_Utils::connect();
+ }
#endif
NTP_Utils::update();
@@ -216,4 +224,4 @@ void loop() {
Utils::checkRebootTime();
Utils::checkSleepByLowBatteryVoltage(1);
}
-}
\ No newline at end of file
+}
diff --git a/src/aprs_is_utils.cpp b/src/aprs_is_utils.cpp
index 2dc93b9..97be61b 100644
--- a/src/aprs_is_utils.cpp
+++ b/src/aprs_is_utils.cpp
@@ -16,9 +16,10 @@
* along with LoRa APRS iGate. If not, see .
*/
-#include
-#include
+#include
+#include
#include "configuration.h"
+#include "network_manager.h"
#include "aprs_is_utils.h"
#include "station_utils.h"
#include "board_pinout.h"
@@ -32,6 +33,7 @@
extern Configuration Config;
+extern NetworkManager *networkManager;
extern WiFiClient aprsIsClient;
extern uint32_t lastScreenOn;
extern String firstLine;
@@ -93,7 +95,7 @@ namespace APRS_IS_Utils {
void checkStatus() {
String wifiState, aprsisState;
- if (WiFi.status() == WL_CONNECTED) {
+ if (networkManager->isWiFiConnected()) {
wifiState = "OK";
} else {
if (backupDigiMode || Config.digi.ecoMode == 1 || Config.digi.ecoMode == 2) {
@@ -408,7 +410,7 @@ namespace APRS_IS_Utils {
}
void firstConnection() {
- if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !aprsIsClient.connected()) {
+ if (Config.aprs_is.active && networkManager->isConnected() && !aprsIsClient.connected()) {
connect();
while (!passcodeValid) {
listenAPRSIS();
@@ -416,4 +418,4 @@ namespace APRS_IS_Utils {
}
}
-}
\ No newline at end of file
+}
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 4ffb2a6..e50eef6 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -47,6 +47,7 @@ bool Configuration::writeFile() {
data["other"]["startupDelay"] = startupDelay;
+ data["wifi"]["autoAP"]["enabled"] = wifiAutoAP.enabled;
data["wifi"]["autoAP"]["password"] = wifiAutoAP.password;
data["wifi"]["autoAP"]["timeout"] = wifiAutoAP.timeout;
@@ -214,8 +215,10 @@ bool Configuration::readFile() {
if (!data["other"].containsKey("startupDelay")) needsRewrite = true;
startupDelay = data["other"]["startupDelay"] | 0;
- if (!data["wifi"]["autoAP"].containsKey("password") ||
+ if (!data["wifi"]["autoAP"].containsKey("enabled") ||
+ !data["wifi"]["autoAP"].containsKey("password") ||
!data["wifi"]["autoAP"].containsKey("timeout")) needsRewrite = true;
+ wifiAutoAP.enabled = data["wifi"]["autoAP"]["enabled"] | true;
wifiAutoAP.password = data["wifi"]["autoAP"]["password"] | "1234567890";
wifiAutoAP.timeout = data["wifi"]["autoAP"]["timeout"] | 10;
@@ -446,6 +449,7 @@ void Configuration::setDefaultValues() {
startupDelay = 0;
+ wifiAutoAP.enabled = true;
wifiAutoAP.password = "1234567890";
wifiAutoAP.timeout = 10;
diff --git a/src/lora_utils.cpp b/src/lora_utils.cpp
index 5394944..d9653f7 100644
--- a/src/lora_utils.cpp
+++ b/src/lora_utils.cpp
@@ -17,8 +17,8 @@
*/
#include
-#include
#include "configuration.h"
+#include "network_manager.h"
#include "aprs_is_utils.h"
#include "station_utils.h"
#include "board_pinout.h"
@@ -29,6 +29,7 @@
extern Configuration Config;
+extern NetworkManager *networkManager;
extern uint32_t lastRxTime;
extern bool packetIsBeacon;
@@ -181,7 +182,7 @@ namespace LoRa_Utils {
int state = radio.transmit("\x3c\xff\x01" + newPacket);
transmitFlag = true;
if (state == RADIOLIB_ERR_NONE) {
- if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
+ if (Config.syslog.active && networkManager->isConnected()) {
SYSLOG_Utils::log(3, newPacket, 0, 0.0, 0); // TX
}
Utils::print("---> LoRa Packet Tx : ");
@@ -243,7 +244,7 @@ namespace LoRa_Utils {
receivedPackets.push_back(receivedPacket);
}
- if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
+ if (Config.syslog.active && networkManager->isConnected()) {
SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
}
} else {
@@ -257,7 +258,7 @@ namespace LoRa_Utils {
snr = radio.getSNR();
freqError = radio.getFrequencyError();
Utils::println(F("CRC error!"));
- if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
+ if (Config.syslog.active && networkManager->isConnected()) {
SYSLOG_Utils::log(0, packet, rssi, snr, freqError); // CRC
}
packet = "";
diff --git a/src/mqtt_utils.cpp b/src/mqtt_utils.cpp
index 7793962..5462198 100644
--- a/src/mqtt_utils.cpp
+++ b/src/mqtt_utils.cpp
@@ -16,7 +16,7 @@
* along with LoRa APRS iGate. If not, see .
*/
-#include
+#include
#include
#include "configuration.h"
#include "station_utils.h"
diff --git a/src/network_manager.cpp b/src/network_manager.cpp
new file mode 100644
index 0000000..b94693c
--- /dev/null
+++ b/src/network_manager.cpp
@@ -0,0 +1,337 @@
+#include
+
+#include "network_manager.h"
+
+ // Constructor
+NetworkManager::NetworkManager() { }
+
+// Destructor
+NetworkManager::~NetworkManager() { }
+
+// Private methods
+
+int NetworkManager::_findWiFiNetworkIndex(const String& ssid) const {
+ for (size_t i = 0; i < _wifiNetworks.size(); i++) {
+ if (_wifiNetworks[i].ssid == ssid) {
+ return static_cast(i);
+ }
+ }
+ return -1;
+}
+
+bool NetworkManager::_connectWiFi(const WiFiNetwork& network) {
+ if (network.ssid.isEmpty()) {
+ return false;
+ }
+
+ _wifiSTAmode = true;
+
+ if (!_hostName.isEmpty()) {
+ WiFi.setHostname(_hostName.c_str());
+ }
+
+ WiFi.mode(_wifiAPmode ? WIFI_AP_STA : WIFI_STA);
+
+ Serial.println("[NM] Attempting to connect to WiFi: " + network.ssid);
+ WiFi.begin(network.ssid.c_str(), network.psk.c_str());
+
+ Serial.print("[NM] Connecting ");
+
+ int attempts = 0;
+ while (!isWiFiConnected() && attempts < 10) {
+ delay(500);
+ #ifdef INTERNAL_LED_PIN
+ digitalWrite(INTERNAL_LED_PIN,HIGH);
+ #endif
+ Serial.print('.');
+ delay(500);
+ #ifdef INTERNAL_LED_PIN
+ digitalWrite(INTERNAL_LED_PIN,LOW);
+ #endif
+ attempts++;
+ }
+ Serial.println();
+
+ if (isWiFiConnected()) {
+ Serial.println("[NM] WiFi connected! IP: " + WiFi.localIP().toString());
+ return true;
+ }
+
+ Serial.println("[NM] Failed to connect to WiFi after " + String(attempts) + " attempts. SSID: " +
+ network.ssid);
+ return false;
+}
+
+void NetworkManager::_processAPTimeout() {
+ if (!_wifiAPmode || _apTimeout == 0) {
+ return;
+ }
+
+ // If any station is connected, reset the timer
+ if (WiFi.softAPgetStationNum() > 0) {
+ _apStartup = millis();
+ return;
+ }
+
+ if (millis() - _apStartup > _apTimeout) {
+ Serial.println("[NM] AP timeout reached. Disabling AP mode.");
+ disableAP();
+ }
+}
+
+void NetworkManager::_onNetworkEvent(arduino_event_id_t event, arduino_event_info_t /*info*/) {
+ switch (event) {
+ case ARDUINO_EVENT_ETH_START:
+ Serial.println("[NM] ETH Started");
+ if (!_hostName.isEmpty()) {
+ Serial.println("[NM] ETH Setting Hostname: " + _hostName);
+ ETH.setHostname(_hostName.c_str());
+ }
+ break;
+ case ARDUINO_EVENT_ETH_CONNECTED:
+ Serial.println("[NM] ETH Connected");
+ break;
+ case ARDUINO_EVENT_ETH_GOT_IP:
+ Serial.println("[NM] ETH Got IP");
+ _ethernetConnected = true;
+ break;
+ case ARDUINO_EVENT_ETH_DISCONNECTED:
+ Serial.println("[NM] ETH Disconnected");
+ _ethernetConnected = false;
+ break;
+ case ARDUINO_EVENT_ETH_STOP:
+ Serial.println("[NM] ETH Stopped");
+ _ethernetConnected = false;
+ break;
+ default:
+ break;
+ }
+}
+
+// Initialize
+bool NetworkManager::setup() {
+ Serial.println("[NM] Initializing Networking...");
+
+ WiFi.onEvent(
+ [this](arduino_event_id_t event, arduino_event_info_t info) {
+ _onNetworkEvent(event, info);
+ });
+
+ return true;
+}
+
+void NetworkManager::loop() {
+ if (_wifiAPmode) {
+ _processAPTimeout();
+ }
+}
+
+void NetworkManager::setHostName(const String& hostName) {
+ _hostName = hostName;
+}
+
+// WiFi methods
+
+bool NetworkManager::setupAP(String apName, String apPsk) {
+ _wifiAPmode = true;
+
+ Serial.println("[NM] Starting AP mode: " + apName);
+
+ // Full WiFi reset sequence
+ WiFi.disconnect(true);
+ WiFi.mode(WIFI_OFF);
+ delay(200);
+
+ // Set up AP mode with optimized settings
+ WiFi.mode(WIFI_AP);
+
+ bool apStarted = WiFi.softAP(apName.c_str(), apPsk.c_str());
+ delay(1000); // Give AP time to fully initialize
+
+ if (apStarted) {
+ Serial.println("[NM] AP setup successful");
+ _apStartup = millis();
+ }
+ else {
+ Serial.println("[NM] AP setup failed");
+ return false;
+ }
+
+ IPAddress apIP = getWiFiAPIP();
+ Serial.println("[NM] AP IP assigned: " + apIP.toString());
+
+ return true;
+}
+
+bool NetworkManager::disableAP() {
+ WiFi.mode(_wifiSTAmode ? WIFI_STA : WIFI_OFF);
+ _wifiAPmode = false;
+
+ return true;
+}
+
+void NetworkManager::setAPTimeout(unsigned long timeout) {
+ Serial.println("[NM] Setting AP timeout to " + String(timeout / 1000) + " sec");
+ _apTimeout = timeout;
+}
+
+void NetworkManager::addWiFiNetwork(const String& ssid, const String& psk) {
+ if (ssid.isEmpty()) {
+ return;
+ }
+
+ int index = _findWiFiNetworkIndex(ssid);
+ if (index >= 0) {
+ Serial.println("[NM] Updating WiFi network: " + ssid);
+ _wifiNetworks[static_cast(index)].psk = psk;
+ return;
+ }
+
+ Serial.println("[NM] Adding WiFi network: " + ssid);
+ WiFiNetwork network;
+ network.ssid = ssid;
+ network.psk = psk;
+ _wifiNetworks.push_back(network);
+}
+
+void NetworkManager::clearWiFiNetworks() {
+ _wifiNetworks.clear();
+}
+
+bool NetworkManager::hasWiFiNetworks() const {
+ return !_wifiNetworks.empty();
+}
+
+size_t NetworkManager::getWiFiNetworkCount() const {
+ return _wifiNetworks.size();
+}
+
+bool NetworkManager::connectWiFi() {
+ if (_wifiNetworks.empty()) {
+ return false;
+ }
+
+ for (size_t i = 0; i < _wifiNetworks.size(); i++) {
+ disconnectWiFi();
+ if (_connectWiFi(_wifiNetworks[i])) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool NetworkManager::connectWiFi(const String& ssid, const String& psk) {
+ addWiFiNetwork(ssid, psk);
+ return connectWiFi();
+}
+
+bool NetworkManager::disconnectWiFi() {
+ WiFi.disconnect(true);
+ WiFi.mode(_wifiAPmode ? WIFI_AP : WIFI_OFF);
+
+ _wifiSTAmode = false;
+ return true;
+}
+
+String NetworkManager::getWiFiSSID() const {
+ return WiFi.SSID();
+}
+
+String NetworkManager::getWiFiAPSSID() const {
+ return WiFi.softAPSSID();
+}
+
+IPAddress NetworkManager::getWiFiIP() const {
+ return WiFi.localIP();
+}
+
+IPAddress NetworkManager::getWiFiAPIP() const {
+ return WiFi.softAPIP();
+}
+
+wifi_mode_t NetworkManager::getWiFiMode() const {
+ return WiFi.getMode();
+}
+
+uint8_t* NetworkManager::getWiFimacAddress(uint8_t* mac) {
+ return WiFi.macAddress(mac);
+}
+
+String NetworkManager::getWiFimacAddress(void) const {
+ return WiFi.macAddress();
+}
+
+// Ethernet methods
+bool NetworkManager::ethernetConnect(eth_phy_type_t type, uint8_t phy_addr, uint8_t mdc, uint8_t mdio, int power, eth_clock_mode_t clock_mode, bool use_mac_from_efuse) {
+ _ethernetMode = true;
+ Serial.println("[NM] Setting up Ethernet...");
+
+ #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
+ // SDK 5.x (Arduino SDK 3.x)
+ #pragma message("Compiling ETH init: SDK 5.x (Arduino core 3.x)")
+ return ETH.begin(type, phy_addr, mdc, mdio, power, clock_mode, use_mac_from_efuse);
+ #else
+ // SDK 4.x (Arduino SDK 2.x)
+ #pragma message("Compiling ETH init: SDK 4.x (Arduino core 2.x)")
+ return ETH.begin(phy_addr, power, mdc, mdio, type, clock_mode, use_mac_from_efuse);
+ #endif
+}
+
+bool NetworkManager::setEthernetIP(const String& staticIP, const String& gateway, const String& subnet, const String& dns1, const String& dns2) {
+ if (staticIP.isEmpty()) {
+ return false;
+ }
+
+ IPAddress ip, gw, sn, d1, d2;
+ if (!ip.fromString(staticIP) || !gw.fromString(gateway) || !sn.fromString(subnet)) {
+ Serial.println("[NM] Invalid static IP configuration");
+ return false;
+ }
+
+ if (!dns1.isEmpty() && d1.fromString(dns1)) {
+ if (!dns2.isEmpty() && d2.fromString(dns2)) {
+ ETH.config(ip, gw, sn, d1, d2);
+ } else {
+ ETH.config(ip, gw, sn, d1);
+ }
+ } else {
+ ETH.config(ip, gw, sn);
+ }
+
+ Serial.println("[NM] Ethernet static IP: " + staticIP);
+ return true;
+}
+
+IPAddress NetworkManager::getEthernetIP() const {
+ return ETH.localIP();
+}
+
+String NetworkManager::getEthernetMACAddress() const {
+ return ETH.macAddress();
+}
+
+// Check if network is available
+bool NetworkManager::isConnected() const {
+ return isWiFiConnected() || isEthernetConnected() || isModemConnected();
+}
+
+// Check if WiFi is connected
+bool NetworkManager::isWiFiConnected() const {
+ return _wifiSTAmode ? WiFi.status() == WL_CONNECTED : false;
+}
+
+bool NetworkManager::isWifiAPActive() const {
+ return _wifiAPmode;
+}
+
+// Check if Ethernet is connected
+bool NetworkManager::isEthernetConnected() const {
+ return _ethernetMode && _ethernetConnected && ETH.linkUp();
+}
+
+// Check if Modem is connected
+bool NetworkManager::isModemConnected() const {
+ // Implement Modem connection check logic here
+ return false;
+}
diff --git a/src/ntp_utils.cpp b/src/ntp_utils.cpp
index b835384..1874501 100644
--- a/src/ntp_utils.cpp
+++ b/src/ntp_utils.cpp
@@ -18,35 +18,49 @@
#include
#include
-#include
#include "configuration.h"
+#include "network_manager.h"
#include "ntp_utils.h"
#include "time.h"
extern Configuration Config;
-
+extern NetworkManager *networkManager;
WiFiUDP ntpUDP;
-NTPClient* timeClient;
+NTPClient* timeClient = nullptr;
namespace NTP_Utils {
- void setup() {
- if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") {
+ bool setup() {
+ if (networkManager->isConnected() && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") {
int gmt = Config.ntp.gmtCorrection * 3600;
+ Serial.println("[NTP] Setting up, TZ offset: " + String(gmt) + " Server: " + Config.ntp.server);
timeClient = new NTPClient(ntpUDP, Config.ntp.server.c_str(), gmt, 15 * 60 * 1000); // Update interval 15 min
timeClient->begin();
+ return true;
}
+ return false;
}
void update() {
- if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") timeClient->update();
+ if (!networkManager->isConnected() || Config.digi.ecoMode != 0 || Config.callsign == "NOCALL-10") {
+ return;
+ }
+ if (timeClient == nullptr) {
+ if (!setup()) {
+ return;
+ }
+ }
+
+ timeClient->update();
}
String getFormatedTime() {
- if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0) return timeClient->getFormattedTime();
+ if (networkManager->isConnected() && Config.digi.ecoMode == 0 && timeClient != nullptr) {
+ return timeClient->getFormattedTime();
+ }
return "DigiEcoMode Active";
}
-}
\ No newline at end of file
+}
diff --git a/src/syslog_utils.cpp b/src/syslog_utils.cpp
index 95d9d52..1c48fd6 100644
--- a/src/syslog_utils.cpp
+++ b/src/syslog_utils.cpp
@@ -17,13 +17,14 @@
*/
#include
-#include
#include "configuration.h"
+#include "network_manager.h"
#include "syslog_utils.h"
#include "gps_utils.h"
extern Configuration Config;
+extern NetworkManager *networkManager;
extern String versionDate;
extern String versionNumber;
@@ -33,7 +34,7 @@ WiFiUDP udpClient;
namespace SYSLOG_Utils {
void log(const uint8_t type, const String& packet, const int rssi, const float snr, const int freqError) {
- if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
+ if (Config.syslog.active && networkManager->isConnected()) {
String syslogPacket = "<165>1 - ";
syslogPacket.concat(Config.callsign);
syslogPacket.concat(" CA2RXU_LoRa_iGate_");
@@ -140,7 +141,7 @@ namespace SYSLOG_Utils {
}
void setup() {
- if (WiFi.status() == WL_CONNECTED) {
+ if (networkManager->isConnected()) {
udpClient.begin(0);
if (Config.syslog.active) Serial.println("init : Syslog Server ... done! (at " + Config.syslog.server + ")");
}
diff --git a/src/utils.cpp b/src/utils.cpp
index c7b023e..65b5292 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -18,9 +18,9 @@
#include
#include
-#include
#include "telemetry_utils.h"
#include "configuration.h"
+#include "network_manager.h"
#include "station_utils.h"
#include "battery_utils.h"
#include "aprs_is_utils.h"
@@ -37,6 +37,7 @@
#define DAY_MS (24UL * 60UL * 60UL * 1000UL)
extern Configuration Config;
+extern NetworkManager *networkManager;
extern TinyGPSPlus gps;
extern String versionDate;
extern String firstLine;
@@ -52,7 +53,6 @@ extern int rssi;
extern float snr;
extern int freqError;
extern String distance;
-extern bool WiFiConnected;
extern int wxModuleType;
extern bool backupDigiMode;
extern bool shouldSleepLowVoltage;
@@ -75,7 +75,7 @@ String secondaryBeaconPacket;
namespace Utils {
void processStatus() {
- bool sendOverAPRSIS = Config.beacon.sendViaAPRSIS && Config.aprs_is.active && WiFi.status() == WL_CONNECTED;
+ bool sendOverAPRSIS = Config.beacon.sendViaAPRSIS && Config.aprs_is.active && networkManager->isConnected();
bool sendOverRF = !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF;
if (!sendOverAPRSIS && !sendOverRF) {
@@ -104,12 +104,14 @@ namespace Utils {
String getLocalIP() {
if (Config.digi.ecoMode == 1 || Config.digi.ecoMode == 2) {
return "** WiFi AP Killed **";
- } else if (!WiFiConnected) {
- return "IP : 192.168.4.1";
+ } else if (networkManager->isEthernetConnected()) {
+ return "LAN: " + networkManager->getEthernetIP().toString();
+ } else if (!networkManager->isWiFiConnected() && networkManager->isWifiAPActive()) {
+ return "IP : " + networkManager->getWiFiAPIP().toString();
} else if (backupDigiMode) {
return "- BACKUP DIGI MODE -";
} else {
- return "IP : " + String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
+ return "IP : " + networkManager->getWiFiIP().toString();
}
}
@@ -481,4 +483,4 @@ namespace Utils {
}
}
-}
\ No newline at end of file
+}
diff --git a/src/web_utils.cpp b/src/web_utils.cpp
index 6197b37..8eebfc2 100644
--- a/src/web_utils.cpp
+++ b/src/web_utils.cpp
@@ -161,7 +161,7 @@ namespace WEB_Utils {
Config.callsign = getParamStringSafe("callsign", Config.callsign);
Config.tacticalCallsign = getParamStringSafe("tacticalCallsign", Config.tacticalCallsign);
-
+ Config.wifiAutoAP.enabled = request->hasParam("wifi.autoAP.enabled", true);
Config.wifiAutoAP.password = getParamStringSafe("wifi.autoAP.password", Config.wifiAutoAP.password);
Config.wifiAutoAP.timeout = getParamIntSafe("wifi.autoAP.timeout", Config.wifiAutoAP.timeout);
diff --git a/src/wifi_utils.cpp b/src/wifi_utils.cpp
index 2781f17..a249676 100644
--- a/src/wifi_utils.cpp
+++ b/src/wifi_utils.cpp
@@ -18,6 +18,7 @@
#include
#include "configuration.h"
+#include "network_manager.h"
#include "board_pinout.h"
#include "wifi_utils.h"
#include "display.h"
@@ -25,16 +26,11 @@
extern Configuration Config;
+extern NetworkManager *networkManager;
-extern uint8_t myWiFiAPIndex;
-extern int myWiFiAPSize;
-extern WiFi_AP *currentWiFi;
extern bool backupDigiMode;
extern uint32_t lastServerCheck;
-bool WiFiConnected = false;
-uint32_t WiFiAutoAPTime = millis();
-bool WiFiAutoAPStarted = false;
uint8_t wifiCounter = 0;
uint32_t lastBackupDigiTime = millis();
uint32_t lastWiFiCheck = 0;
@@ -44,32 +40,35 @@ namespace WIFI_Utils {
void checkWiFi() {
if (Config.digi.ecoMode != 0) return;
+
+ if (!networkManager->hasWiFiNetworks()) {
+ return;
+ }
+
uint32_t currentTime = millis();
if (backupDigiMode) {
- if (WiFi.status() != WL_CONNECTED && ((currentTime - lastBackupDigiTime) >= 15 * 60 * 1000)) {
+ if (!networkManager->isWiFiConnected() && ((currentTime - lastBackupDigiTime) >= 15 * 60 * 1000)) {
Serial.println("*** Stopping BackUp Digi Mode ***");
backupDigiMode = false;
wifiCounter = 0;
- } else if (WiFi.status() == WL_CONNECTED) {
+ } else if (networkManager->isWiFiConnected()) {
Serial.println("*** WiFi Reconnect Success (Stopping Backup Digi Mode) ***");
backupDigiMode = false;
wifiCounter = 0;
}
}
- if (!backupDigiMode && ((currentTime - lastWiFiCheck) >= 30 * 1000) && !WiFiAutoAPStarted) {
+ if (!backupDigiMode && ((currentTime - lastWiFiCheck) >= 30 * 1000) && !networkManager->isWifiAPActive()) {
lastWiFiCheck = currentTime;
- if (WiFi.status() == WL_CONNECTED) {
+ if (networkManager->isWiFiConnected()) {
if (Config.digi.backupDigiMode && (currentTime - lastServerCheck > 30 * 1000)) {
Serial.println("*** Server Connection LOST → Backup Digi Mode ***");
backupDigiMode = true;
- WiFi.disconnect();
lastBackupDigiTime = currentTime;
}
} else {
Serial.println("Reconnecting to WiFi...");
- WiFi.disconnect();
WIFI_Utils::startWiFi();
if (Config.digi.backupDigiMode) wifiCounter++;
@@ -83,97 +82,50 @@ namespace WIFI_Utils {
}
void startAutoAP() {
- WiFi.mode(WIFI_MODE_NULL);
-
- WiFi.mode(WIFI_AP);
- WiFi.softAP(Config.callsign + "-AP", Config.wifiAutoAP.password);
-
- WiFiAutoAPTime = millis();
- WiFiAutoAPStarted = true;
+ displayShow("", " Starting Auto AP", " Please connect to it " , " loading ...", 1000);
+ networkManager->setupAP(Config.callsign + "-AP", Config.wifiAutoAP.password);
}
void startWiFi() {
- bool startAP = false;
- if (currentWiFi->ssid == "") {
- startAP = true;
- } else {
- uint8_t wifiCounter = 0;
- String hostName = "iGATE-" + Config.callsign;
- WiFi.setHostname(hostName.c_str());
- WiFi.mode(WIFI_STA);
- WiFi.disconnect();
- delay(500);
- unsigned long start = millis();
- displayShow("", "Connecting to WiFi:", "", currentWiFi->ssid + " ...", 0);
- Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.print("' ");
- WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
- while (WiFi.status() != WL_CONNECTED && wifiCounter < myWiFiAPSize) {
- delay(500);
- #ifdef INTERNAL_LED_PIN
- digitalWrite(INTERNAL_LED_PIN, HIGH);
- #endif
- Serial.print('.');
- delay(500);
- #ifdef INTERNAL_LED_PIN
- digitalWrite(INTERNAL_LED_PIN, LOW);
- #endif
- if ((millis() - start) > 10000){
- delay(1000);
- if (myWiFiAPIndex >= (myWiFiAPSize - 1)) {
- myWiFiAPIndex = 0;
- wifiCounter++;
- } else {
- myWiFiAPIndex++;
- }
- wifiCounter++;
- currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
- start = millis();
- Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ...");
- displayShow("", "Connecting to WiFi:", "", currentWiFi->ssid + " ...", 0);
- WiFi.disconnect();
- WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
- }
+ networkManager->clearWiFiNetworks();
+ for (size_t i = 0; i < Config.wifiAPs.size(); i++) {
+ const WiFi_AP& wifiAP = Config.wifiAPs[i];
+ if (wifiAP.ssid.isEmpty()) {
+ continue;
}
+
+ networkManager->addWiFiNetwork(wifiAP.ssid, wifiAP.password);
}
+
+ if (!networkManager->hasWiFiNetworks()) {
+ Serial.println("WiFi SSID not set!");
+ if (Config.wifiAutoAP.enabled) {
+ Serial.println("Starting AP fallback...");
+ startAutoAP();
+ }
+ return;
+ }
+
+ displayShow("", "Connecting to WiFi:", "", " loading ...", 0);
+ networkManager->connectWiFi();
+
#ifdef INTERNAL_LED_PIN
digitalWrite(INTERNAL_LED_PIN, LOW);
#endif
- if (WiFi.status() == WL_CONNECTED) {
+ if (networkManager->isWiFiConnected()) {
Serial.print("\nConnected as ");
- Serial.print(WiFi.localIP());
+ Serial.print(networkManager->getWiFiIP());
Serial.print(" / MAC Address: ");
- Serial.println(WiFi.macAddress());
+ Serial.println(networkManager->getWiFimacAddress());
displayShow("", " Connected!!", "" , " loading ...", 1000);
} else {
- startAP = true;
-
- Serial.println("\nNot connected to WiFi! Starting Auto AP");
- displayShow("", " WiFi Not Connected!", "" , " loading ...", 1000);
- }
- WiFiConnected = !startAP;
- if (startAP) {
- Serial.println("\nNot connected to WiFi! Starting Auto AP");
- displayShow("", " Starting Auto AP", " Please connect to it " , " loading ...", 1000);
-
- startAutoAP();
- }
- }
-
- void checkAutoAPTimeout() {
- if (WiFiAutoAPStarted && Config.wifiAutoAP.timeout > 0) {
- if (WiFi.softAPgetStationNum() > 0) {
- WiFiAutoAPTime = 0;
+ Serial.println("\nNot connected to WiFi!");
+ if (Config.wifiAutoAP.enabled) {
+ Serial.println("Starting AP fallback...");
+ displayShow("", " WiFi Not Connected!", "" , " loading ...", 1000);
+ startAutoAP();
} else {
- if (WiFiAutoAPTime == 0) {
- WiFiAutoAPTime = millis();
- } else if ((millis() - WiFiAutoAPTime) > Config.wifiAutoAP.timeout * 60 * 1000) {
- Serial.println("Stopping auto AP");
-
- WiFiAutoAPStarted = false;
- WiFi.softAPdisconnect(true);
-
- Serial.println("Auto AP stopped (timeout)");
- }
+ displayShow("", " WiFi Not Connected!", "" , " loading ...", 1000);
}
}
}
@@ -183,4 +135,4 @@ namespace WIFI_Utils {
btStop();
}
-}
\ No newline at end of file
+}