diff --git a/data_embed/index.html b/data_embed/index.html index 611dc07..0c4ab20 100644 --- a/data_embed/index.html +++ b/data_embed/index.html @@ -1853,46 +1853,68 @@
-
- -
+
+
-
-
-
- -
- - minutesEnable Auto AP
- Set to 0 if you don't - want WiFi AP to stop. + Create WiFi AP when no network is available +
+
+
+
+
+
+
+ +
+ +
+
+
+ +
+ + minutes +
+ Set to 0 if you don't + want WiFi AP to stop. +
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 +}