/* * EMS-ESP - https://github.com/emsesp/EMS-ESP * Copyright 2020-2025 emsesp.org * * This program 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. * * This program 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 this program. If not, see . */ #ifndef EMSESP_NETWORK_H_ #define EMSESP_NETWORK_H_ #ifndef EMSESP_STANDALONE #include #include #include #include #include #include #endif #include #include #include namespace emsesp { #define NETWORK_RECONNECTION_DELAY_SHORT 3000 // 3 seconds #define NETWORK_RECONNECTION_DELAY_LONG 60000 // 60 seconds #define MAX_NETWORK_RECONNECTION_ATTEMPTS 3 // maximum number of network reconnection attempts #define DNS_PORT 53 // copied from Tasmota #if CONFIG_IDF_TARGET_ESP32S2 #define MAX_TX_PWR_DBM_11b 195 #define MAX_TX_PWR_DBM_54g 150 #define MAX_TX_PWR_DBM_n 130 #define WIFI_SENSITIVITY_11b -880 #define WIFI_SENSITIVITY_54g -750 #define WIFI_SENSITIVITY_n -720 #elif CONFIG_IDF_TARGET_ESP32S3 #define MAX_TX_PWR_DBM_11b 210 #define MAX_TX_PWR_DBM_54g 190 #define MAX_TX_PWR_DBM_n 185 #define WIFI_SENSITIVITY_11b -880 #define WIFI_SENSITIVITY_54g -760 #define WIFI_SENSITIVITY_n -720 #elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 #define MAX_TX_PWR_DBM_11b 210 #define MAX_TX_PWR_DBM_54g 190 #define MAX_TX_PWR_DBM_n 185 #define WIFI_SENSITIVITY_11b -880 #define WIFI_SENSITIVITY_54g -760 #define WIFI_SENSITIVITY_n -730 #else #define MAX_TX_PWR_DBM_11b 195 #define MAX_TX_PWR_DBM_54g 160 #define MAX_TX_PWR_DBM_n 140 #define WIFI_SENSITIVITY_11b -880 #define WIFI_SENSITIVITY_54g -750 #define WIFI_SENSITIVITY_n -700 #endif // which physical interface we are currently using for the active network connection. // Mapped from the esp-netif description string returned by esp_netif_get_desc(): "sta" -> WIFI, // "ap" -> AP, "eth"/"eth1"/"eth2"/... (arduino-esp32 v3.x suffixes ETH netifs because it supports // multiple ETH instances) -> ETHERNET. Anything else stays as NONE. enum class NetIface : uint8_t { NONE = 0, WIFI, ETHERNET, AP, }; class Network { public: void begin(); void loop(); uint16_t getWifiReconnects() const { return connectcount_; } uint32_t network_ip() const { return network_ip_; } NetIface network_iface() const { return network_iface_; } bool ethernet_connected() const { return network_iface_ == NetIface::ETHERNET && network_ip_ != 0; } bool wifi_connected() const { return network_iface_ == NetIface::WIFI && network_ip_ != 0; } bool ap_connected() const { return network_iface_ == NetIface::AP && network_ip_ != 0; } bool network_connected() const { return ethernet_connected() || wifi_connected(); // don't include AP here } bool has_ipv6() const { return has_ipv6_ && (network_iface_ == NetIface::WIFI || network_iface_ == NetIface::ETHERNET); } uint16_t getWifiReconnects() { return connectcount_; } std::string getLocalIP() const; std::string getMacAddress() const; uint8_t getStationNum() const; void reconnect(); // map a netif description string (from esp_netif_get_desc) to a NetIface static NetIface iface_from_desc(const char * desc) { if (!desc) { return NetIface::NONE; } if (strcmp(desc, "sta") == 0) { return NetIface::WIFI; } if (strcmp(desc, "ap") == 0) { return NetIface::AP; } // any "eth*" (eth, eth0, eth1, ...) is treated as Ethernet if (strncmp(desc, "eth", 3) == 0) { return NetIface::ETHERNET; } return NetIface::NONE; } private: static uuid::log::Logger logger_; bool findNetworks(); void checkConnection(); void startmDNS() const; bool formatBSSID(const String & bssid, uint8_t (&mac)[6]); void startAP(); void startWIFI(); void startEthernet(); void setWiFiPower(uint8_t tx_power); const char * disconnectReason(uint8_t code); void stopAP(); #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-private-field" #endif unsigned long lastConnectionAttempt_ = 0; uint16_t connectcount_ = 0; // number of network reconnects uint32_t network_ip_ = 0; NetIface network_iface_ = NetIface::NONE; bool has_ipv6_ = false; bool juststopped_ = false; bool eth_started_ = false; // true after ETH.begin() has succeeded once; prevents repeated re-init while DHCP is still running volatile uint8_t last_disconnect_reason_ = 0; uint16_t connnect_retry_ = 0; // number of network re-connection attempts volatile bool wifi_connect_pending_ = false; // Network and AP settings bool enableMDNS_; bool staticIPConfig_; IPAddress localIP_; IPAddress gatewayIP_; IPAddress subnetMask_; IPAddress dnsIP1_; IPAddress dnsIP2_; String hostname_; String ssid_; String password_; bool bandwidth20_; bool nosleep_; uint8_t tx_power_; String bssid_; uint8_t phy_type_; int8_t eth_power_; uint8_t eth_phy_addr_; uint8_t eth_clock_mode_; // AP settings uint8_t ap_provisionMode_; String ap_ssid_; String ap_password_; uint8_t ap_channel_; bool ap_ssid_hidden_; uint8_t ap_max_clients_; IPAddress ap_localIP_; IPAddress ap_gatewayIP_; IPAddress ap_subnetMask_; #if defined(__clang__) #pragma clang diagnostic pop #endif // for the captive portal in AP mode #ifndef EMSESP_STANDALONE DNSServer * ap_dnsServer_; #endif }; } // namespace emsesp #endif