mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-19 00:36:33 +00:00
Adding detailed documentation to support_wifi (#23697)
* Adding detailed documentation to support_wifi * fix compilation * Another leftover
This commit is contained in:
parent
79e76bddfb
commit
60d59fde09
@ -46,6 +46,17 @@ const uint8_t WIFI_RETRY_OFFSET_SEC = WIFI_RETRY_SECONDS; // seconds
|
||||
#include "esp_netif.h"
|
||||
#endif // ESP32
|
||||
|
||||
/**
|
||||
* Converts WiFi RSSI (signal strength) to a quality percentage
|
||||
*
|
||||
* @param rssi The RSSI value in dBm (typically negative, e.g. -70)
|
||||
* @return Quality as a percentage (0-100)
|
||||
*
|
||||
* The function maps RSSI values to a percentage scale:
|
||||
* - RSSI <= -100 dBm: 0% quality (very poor/no signal)
|
||||
* - RSSI >= -50 dBm: 100% quality (excellent signal)
|
||||
* - Values in between are linearly mapped (each 2.5 dBm = 5%)
|
||||
*/
|
||||
int WifiGetRssiAsQuality(int rssi) {
|
||||
int quality = 0;
|
||||
|
||||
@ -67,6 +78,18 @@ const char kWifiEncryptionTypes[] PROGMEM = "OPEN|WEP|WPA/PSK|WPA2/PSK|WPA/WPA2/
|
||||
#endif // ESP32
|
||||
;
|
||||
|
||||
/**
|
||||
* Returns a string representation of the WiFi encryption type
|
||||
*
|
||||
* @param i Index of the network in the WiFi scan results
|
||||
* @return String containing the encryption type (e.g., "WPA2/PSK")
|
||||
*
|
||||
* The function maps the encryption type values from WiFi.encryptionType() to
|
||||
* human-readable strings defined in kWifiEncryptionTypes.
|
||||
*
|
||||
* ESP8266 and ESP32 use different encryption type enumerations, so this function
|
||||
* normalizes them to a consistent set of values.
|
||||
*/
|
||||
String WifiEncryptionType(uint32_t i) {
|
||||
#ifdef ESP8266
|
||||
// Reference. WiFi.encryptionType =
|
||||
@ -86,6 +109,18 @@ String WifiEncryptionType(uint32_t i) {
|
||||
return stemp1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the WiFi configuration timeout counter
|
||||
*
|
||||
* @return Current state of the WiFi configuration counter (true if active, false if not)
|
||||
*
|
||||
* If the WiFi configuration counter is active, this function resets it to the maximum
|
||||
* value (WIFI_CONFIG_SEC). This extends the time available for configuration before
|
||||
* the device automatically restarts.
|
||||
*
|
||||
* The function is typically called during user interaction with WiFi configuration
|
||||
* to prevent timeout while the user is actively configuring.
|
||||
*/
|
||||
bool WifiConfigCounter(void)
|
||||
{
|
||||
if (Wifi.config_counter) {
|
||||
@ -94,6 +129,24 @@ bool WifiConfigCounter(void)
|
||||
return (Wifi.config_counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a WiFi configuration mode
|
||||
*
|
||||
* @param type The configuration mode to activate (from enum WifiConfigModes)
|
||||
*
|
||||
* This function handles the transition to different WiFi configuration modes:
|
||||
* - WIFI_RESTART: Triggers a device restart
|
||||
* - WIFI_SERIAL: Enables configuration via serial for 3 minutes
|
||||
* - WIFI_MANAGER/WIFI_MANAGER_RESET_ONLY: Activates the WiFi manager web interface
|
||||
*
|
||||
* The function sets up a timeout counter (Wifi.config_counter) that will trigger
|
||||
* appropriate actions when it expires. It also disconnects from any current WiFi
|
||||
* connection before changing modes.
|
||||
*
|
||||
* Error handling:
|
||||
* - Ignores requests for WIFI_RETRY or WIFI_WAIT if already in configuration mode
|
||||
* - Falls back to WIFI_SERIAL if WIFI_MANAGER is requested but webserver is disabled
|
||||
*/
|
||||
void WifiConfig(uint8_t type)
|
||||
{
|
||||
if (!Wifi.config_type) {
|
||||
@ -134,6 +187,23 @@ void WifiConfig(uint8_t type)
|
||||
extern "C" void phy_bbpll_en_usb(bool en);
|
||||
#endif // CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
/**
|
||||
* Sets the WiFi operating mode with proper handling for different ESP platforms
|
||||
*
|
||||
* @param wifi_mode The WiFi mode to set (WIFI_OFF, WIFI_STA, WIFI_AP, WIFI_AP_STA)
|
||||
*
|
||||
* This function handles platform-specific requirements when changing WiFi modes:
|
||||
* - For ESP32-C3: Enables USB serial-jtag after WiFi startup
|
||||
* - Ensures the hostname is set before mode changes
|
||||
* - Handles proper sleep/wake transitions for power management
|
||||
*
|
||||
* The function includes retry logic if setting the mode fails on the first attempt.
|
||||
* For WIFI_OFF mode, it properly puts the WiFi into deep sleep to save power.
|
||||
*
|
||||
* Error handling:
|
||||
* - Retries mode setting up to 2 times if it fails
|
||||
* - Adds delay between attempts to allow hardware to stabilize
|
||||
*/
|
||||
void WifiSetMode(WiFiMode_t wifi_mode) {
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
// https://github.com/espressif/arduino-esp32/issues/6264#issuecomment-1094376906
|
||||
@ -162,6 +232,25 @@ void WifiSetMode(WiFiMode_t wifi_mode) {
|
||||
delay(100); // Must allow for some time to init.
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the WiFi sleep mode based on system settings
|
||||
*
|
||||
* This function sets the appropriate WiFi sleep mode to balance power consumption
|
||||
* and network responsiveness according to user settings:
|
||||
*
|
||||
* - WIFI_NONE_SLEEP: No sleep (highest power consumption, fastest response)
|
||||
* - WIFI_LIGHT_SLEEP: Light sleep during idle times (medium power saving)
|
||||
* - WIFI_MODEM_SLEEP: Default sleep mode (moderate power saving)
|
||||
*
|
||||
* The sleep mode is determined by:
|
||||
* - TasmotaGlobal.sleep: Global sleep setting
|
||||
* - Settings->flag5.wifi_no_sleep: Option to disable sleep
|
||||
* - Settings->flag3.sleep_normal: SetOption60 - Use normal sleep instead of dynamic sleep
|
||||
* - TasmotaGlobal.wifi_stay_asleep: Flag to maintain sleep state
|
||||
*
|
||||
* Note: Sleep modes affect power consumption and network responsiveness.
|
||||
* Some ESP32 variants may have specific sleep behavior requirements.
|
||||
*/
|
||||
void WiFiSetSleepMode(void)
|
||||
{
|
||||
/* Excerpt from the esp8266 non os sdk api reference (v2.2.1):
|
||||
@ -202,6 +291,29 @@ void WiFiSetSleepMode(void)
|
||||
delay(100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a WiFi connection with the specified parameters
|
||||
*
|
||||
* @param flag WiFi AP selection: 0=AP1, 1=AP2, 2=Toggle between APs, 3=Current AP
|
||||
* @param channel Optional WiFi channel to connect on (0 for auto)
|
||||
*
|
||||
* This function handles the WiFi connection process:
|
||||
* 1. Disconnects from any current connections
|
||||
* 2. Sets the WiFi mode to station mode
|
||||
* 3. Configures sleep mode and power settings
|
||||
* 4. Attempts to connect to the selected access point
|
||||
*
|
||||
* The function supports multiple connection scenarios:
|
||||
* - Connecting to a specific AP (primary or backup)
|
||||
* - Toggling between configured APs
|
||||
* - Connecting to a specific channel and BSSID for multi-AP installations
|
||||
* - Using static IP configuration if specified in settings
|
||||
*
|
||||
* Error handling:
|
||||
* - Skips empty SSIDs by toggling to the alternate AP
|
||||
* - Logs connection details for troubleshooting
|
||||
* - Optionally waits for connection result based on settings
|
||||
*/
|
||||
void WifiBegin(uint8_t flag, uint8_t channel) {
|
||||
#ifdef USE_EMULATION
|
||||
UdpDisconnect();
|
||||
@ -267,6 +379,34 @@ void WifiBegin(uint8_t flag, uint8_t channel) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages WiFi network scanning and connection based on scan results
|
||||
*
|
||||
* This function implements a state machine for WiFi scanning operations:
|
||||
* - States 1-5: Network scanning for automatic connection
|
||||
* - States 6-69: Network scanning for the wifiscan command
|
||||
*
|
||||
* For automatic connection (states 1-5):
|
||||
* 1. Initializes scan parameters
|
||||
* 2. Starts an asynchronous WiFi scan
|
||||
* 3. Processes scan results to find the best network
|
||||
* 4. Connects to the best available network
|
||||
*
|
||||
* For wifiscan command (states 6-69):
|
||||
* 1. Performs a WiFi scan
|
||||
* 2. Formats and publishes scan results via MQTT
|
||||
* 3. Maintains scan results for 1 minute before cleanup
|
||||
*
|
||||
* The function selects networks based on:
|
||||
* - Signal strength (RSSI)
|
||||
* - Match with configured SSIDs
|
||||
* - Security type (open networks require no password)
|
||||
*
|
||||
* Error handling:
|
||||
* - Logs scan progress and results
|
||||
* - Handles scan failures gracefully
|
||||
* - Manages memory by cleaning up scan results
|
||||
*/
|
||||
void WifiBeginAfterScan(void)
|
||||
{
|
||||
// Not active
|
||||
@ -432,16 +572,58 @@ void WifiBeginAfterScan(void)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of successful WiFi connections since boot
|
||||
*
|
||||
* @return Number of successful WiFi connections
|
||||
*
|
||||
* This function provides access to the internal counter that tracks
|
||||
* how many times the device has successfully connected to WiFi networks.
|
||||
* The counter is incremented each time a connection is established.
|
||||
*/
|
||||
uint16_t WifiLinkCount(void)
|
||||
{
|
||||
return Wifi.link_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total time the device has been disconnected from WiFi
|
||||
*
|
||||
* @return String representation of the total disconnected time
|
||||
*
|
||||
* This function calculates the cumulative time the device has spent
|
||||
* without a WiFi connection since boot. The time is formatted as a
|
||||
* human-readable duration string (e.g., "1h 23m 45s").
|
||||
*
|
||||
* The downtime is tracked by recording timestamps when disconnections
|
||||
* occur and calculating the difference when connections are restored.
|
||||
*/
|
||||
String WifiDowntime(void)
|
||||
{
|
||||
return GetDuration(Wifi.downtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the WiFi connection state and triggers related events
|
||||
*
|
||||
* @param state The new WiFi state (1 = connected, 0 = disconnected)
|
||||
*
|
||||
* This function manages the WiFi connection state tracking:
|
||||
* 1. When connected (state=1):
|
||||
* - Sets the wifi_connected rules flag
|
||||
* - Increments the connection counter
|
||||
* - Updates the total downtime
|
||||
* 2. When disconnected (state=0):
|
||||
* - Sets the wifi_disconnected rules flag
|
||||
* - Records the disconnection timestamp
|
||||
*
|
||||
* The function also updates the global state variables:
|
||||
* - TasmotaGlobal.global_state.wifi_down (inverted state)
|
||||
* - TasmotaGlobal.global_state.network_down (cleared when WiFi is up)
|
||||
*
|
||||
* This state tracking enables proper event handling and metrics for
|
||||
* WiFi connection reliability.
|
||||
*/
|
||||
void WifiSetState(uint8_t state)
|
||||
{
|
||||
if (state == TasmotaGlobal.global_state.wifi_down) {
|
||||
@ -507,22 +689,63 @@ void WifiSetState(uint8_t state)
|
||||
bool WifiGetIP(IPAddress *ip, bool exclude_ap = false);
|
||||
// IPv4 for Wifi
|
||||
// Returns only IPv6 global address (no loopback and no link-local)
|
||||
/**
|
||||
* Retrieves the IPv4 address of the WiFi interface
|
||||
*
|
||||
* @param ip Pointer to store the IPv4 address (can be nullptr to just check existence)
|
||||
* @return true if a valid IPv4 address exists, false otherwise
|
||||
*
|
||||
* This function gets the current IPv4 address of the WiFi interface if connected.
|
||||
* If the ip parameter is provided, the address is copied to it.
|
||||
* The function returns true only if a valid (non-zero) IPv4 address exists.
|
||||
*/
|
||||
bool WifiGetIPv4(IPAddress *ip)
|
||||
{
|
||||
uint32_t wifi_uint = (WL_CONNECTED == WiFi.status()) ? (uint32_t)WiFi.localIP() : 0; // See issue #23115
|
||||
if (ip != nullptr) { *ip = wifi_uint; }
|
||||
return wifi_uint != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the WiFi interface has a valid IPv4 address
|
||||
*
|
||||
* @return true if a valid IPv4 address exists, false otherwise
|
||||
*
|
||||
* This is a convenience wrapper around WifiGetIPv4() that only checks
|
||||
* for the existence of an IPv4 address without retrieving it.
|
||||
*/
|
||||
bool WifiHasIPv4(void)
|
||||
{
|
||||
return WifiGetIPv4(nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the WiFi IPv4 address as a string
|
||||
*
|
||||
* @return String containing the IPv4 address or empty string if none
|
||||
*
|
||||
* This function returns the current IPv4 address of the WiFi interface
|
||||
* formatted as a string (e.g., "192.168.1.100"). If no valid IPv4 address
|
||||
* exists, an empty string is returned.
|
||||
*/
|
||||
String WifiGetIPv4Str(void)
|
||||
{
|
||||
IPAddress ip;
|
||||
return WifiGetIPv4(&ip) ? ip.toString() : String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the IPv4 address of the Ethernet interface
|
||||
*
|
||||
* @param ip Pointer to store the IPv4 address (can be nullptr to just check existence)
|
||||
* @return true if a valid IPv4 address exists, false otherwise
|
||||
*
|
||||
* This function gets the current IPv4 address of the Ethernet interface if connected.
|
||||
* If the ip parameter is provided, the address is copied to it.
|
||||
* The function returns true only if a valid (non-zero) IPv4 address exists.
|
||||
*
|
||||
* On platforms without Ethernet support, this always returns false.
|
||||
*/
|
||||
bool EthernetGetIPv4(IPAddress *ip)
|
||||
{
|
||||
//#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET)
|
||||
@ -535,10 +758,29 @@ bool EthernetGetIPv4(IPAddress *ip)
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the Ethernet interface has a valid IPv4 address
|
||||
*
|
||||
* @return true if a valid IPv4 address exists, false otherwise
|
||||
*
|
||||
* This is a convenience wrapper around EthernetGetIPv4() that only checks
|
||||
* for the existence of an IPv4 address without retrieving it.
|
||||
*/
|
||||
bool EthernetHasIPv4(void)
|
||||
{
|
||||
return EthernetGetIPv4(nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Ethernet IPv4 address as a string
|
||||
*
|
||||
* @return String containing the IPv4 address or empty string if none
|
||||
*
|
||||
* This function returns the current IPv4 address of the Ethernet interface
|
||||
* formatted as a string (e.g., "192.168.1.100"). If no valid IPv4 address
|
||||
* exists, an empty string is returned.
|
||||
*/
|
||||
String EthernetGetIPv4Str(void)
|
||||
{
|
||||
IPAddress ip;
|
||||
@ -831,6 +1073,32 @@ bool HasIP(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies WiFi connection status and manages reconnection
|
||||
*
|
||||
* This function checks if the device has a valid WiFi connection with an IP address.
|
||||
* It handles connection state transitions and reconnection attempts:
|
||||
*
|
||||
* 1. If connected with a valid IP:
|
||||
* - Updates connection state
|
||||
* - Resets retry counters
|
||||
* - Stores network parameters for quick reconnection
|
||||
* - Updates DNS server information
|
||||
*
|
||||
* 2. If disconnected or connection issues:
|
||||
* - Updates connection state
|
||||
* - Manages retry attempts based on failure type
|
||||
* - Triggers appropriate reconnection strategy
|
||||
* - Handles fallback to WiFi configuration modes
|
||||
*
|
||||
* The function implements an adaptive retry mechanism that adjusts based on
|
||||
* the type of connection failure (AP not found, wrong password, etc.).
|
||||
*
|
||||
* Error handling:
|
||||
* - Logs specific connection failure reasons
|
||||
* - Implements exponential backoff for retries
|
||||
* - Triggers device restart after excessive failures (100 max retries)
|
||||
*/
|
||||
void WifiCheckIp(void) {
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_WIFI D_CHECKING_CONNECTION));
|
||||
Wifi.counter = WIFI_CHECK_SEC;
|
||||
@ -930,6 +1198,28 @@ void WifiCheckIp(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main WiFi management function called periodically from the main loop
|
||||
*
|
||||
* @param param Configuration mode parameter (WIFI_SERIAL, WIFI_MANAGER, etc.)
|
||||
*
|
||||
* This function serves as the central WiFi management routine that:
|
||||
* 1. Decrements the WiFi check counter
|
||||
* 2. Handles WiFi configuration modes (WIFI_SERIAL, WIFI_MANAGER)
|
||||
* 3. Manages configuration timeout countdown
|
||||
* 4. Calls WifiCheckIp() to verify connection status
|
||||
* 5. Updates WiFi state based on connection status
|
||||
* 6. Triggers periodic network rescans if enabled
|
||||
*
|
||||
* The function implements a state machine that manages:
|
||||
* - WiFi configuration timeouts
|
||||
* - Connection monitoring
|
||||
* - Periodic rescanning of networks
|
||||
* - WiFi scan state processing
|
||||
*
|
||||
* It's designed to be called regularly from the main loop to maintain
|
||||
* WiFi connectivity and handle configuration changes.
|
||||
*/
|
||||
void WifiCheck(uint8_t param)
|
||||
{
|
||||
Wifi.counter--;
|
||||
@ -966,6 +1256,20 @@ void WifiCheck(uint8_t param)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current WiFi state or configuration mode
|
||||
*
|
||||
* @return Current WiFi state:
|
||||
* - WIFI_RESTART: WiFi is being restarted
|
||||
* - WIFI_SERIAL: Serial configuration mode active
|
||||
* - WIFI_MANAGER: WiFi manager configuration mode active
|
||||
* - WIFI_MANAGER_RESET_ONLY: WiFi manager reset-only mode active
|
||||
* - -1: WiFi is down (not connected)
|
||||
*
|
||||
* This function provides the current WiFi state for status reporting and
|
||||
* decision making. It returns the active configuration mode if one is running,
|
||||
* WIFI_RESTART if WiFi is up and running normally, or -1 if WiFi is down.
|
||||
*/
|
||||
int WifiState(void)
|
||||
{
|
||||
int state = -1;
|
||||
@ -975,6 +1279,16 @@ int WifiState(void)
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current WiFi transmit power
|
||||
*
|
||||
* @return Current WiFi transmit power in dBm as a float
|
||||
*
|
||||
* This function returns the current WiFi transmit power setting.
|
||||
* If a fixed power is set in Settings->wifi_output_power, that value is used.
|
||||
* The power is stored internally as an integer (tenths of dBm) and
|
||||
* returned as a float value in dBm.
|
||||
*/
|
||||
float WifiGetOutputPower(void) {
|
||||
if (Settings->wifi_output_power) {
|
||||
Wifi.last_tx_pwr = Settings->wifi_output_power;
|
||||
@ -982,6 +1296,19 @@ float WifiGetOutputPower(void) {
|
||||
return (float)(Wifi.last_tx_pwr) / 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the WiFi transmit power based on settings
|
||||
*
|
||||
* This function configures the WiFi transmit power:
|
||||
* - If Settings->wifi_output_power is non-zero, it sets a fixed power level
|
||||
* - If Settings->wifi_output_power is zero, it enables dynamic power management
|
||||
*
|
||||
* For fixed power, the value is converted from tenths of dBm to dBm
|
||||
* (e.g., 170 becomes 17.0 dBm).
|
||||
*
|
||||
* The function adds a delay after setting the power to allow the hardware
|
||||
* to stabilize.
|
||||
*/
|
||||
void WifiSetOutputPower(void) {
|
||||
if (Settings->wifi_output_power) {
|
||||
WiFiHelper::setOutputPower((float)(Settings->wifi_output_power) / 10);
|
||||
@ -991,6 +1318,28 @@ void WifiSetOutputPower(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically adjusts WiFi transmit power based on signal strength
|
||||
*
|
||||
* This function implements dynamic power management to optimize power consumption
|
||||
* while maintaining reliable WiFi connectivity. It works by:
|
||||
*
|
||||
* 1. Measuring the current RSSI (signal strength)
|
||||
* 2. Calculating the minimum required transmit power based on:
|
||||
* - Current RSSI
|
||||
* - WiFi sensitivity threshold for the current PHY mode
|
||||
* - Maximum allowed transmit power for the current PHY mode
|
||||
*
|
||||
* The function adjusts power based on different WiFi standards:
|
||||
* - 802.11b: Different sensitivity and max power than other modes
|
||||
* - 802.11g: Optimized for 54Mbps operation
|
||||
* - 802.11n/ax: Higher sensitivity requirements
|
||||
*
|
||||
* This helps reduce overall power consumption while maintaining connection quality.
|
||||
* The function is only active when Settings->wifi_output_power is 0 (dynamic mode).
|
||||
*
|
||||
* Original concept by ESPEasy (@TD-er).
|
||||
*/
|
||||
void WiFiSetTXpowerBasedOnRssi(void) {
|
||||
// Dynamic WiFi transmit power based on RSSI lowering overall DC power usage.
|
||||
// Original idea by ESPEasy (@TD-er)
|
||||
@ -1070,6 +1419,14 @@ RF_PRE_INIT()
|
||||
}
|
||||
#endif // WIFI_RF_PRE_INIT
|
||||
|
||||
/**
|
||||
* Enables WiFi by setting the check counter to trigger immediate processing
|
||||
*
|
||||
* This function activates WiFi by setting the Wifi.counter to 1, which will
|
||||
* cause the WifiCheck function to process WiFi operations on the next cycle.
|
||||
* It's a simple way to trigger WiFi initialization or reconnection from
|
||||
* other parts of the code.
|
||||
*/
|
||||
void WifiEnable(void) {
|
||||
Wifi.counter = 1;
|
||||
}
|
||||
@ -1082,6 +1439,26 @@ void WifiEnable(void) {
|
||||
void WifiEvents(arduino_event_t *event);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes WiFi connection parameters and starts the connection process
|
||||
*
|
||||
* This function sets up the WiFi system for initial connection:
|
||||
* 1. Registers event handlers for ESP32
|
||||
* 2. Initializes WiFi state variables
|
||||
* 3. Sets up retry timers with a randomized offset based on chip ID
|
||||
* 4. Configures WiFi for non-persistent settings
|
||||
*
|
||||
* The function is typically called during device startup or after a
|
||||
* WiFi reconfiguration. It prepares the WiFi subsystem but doesn't
|
||||
* actually establish the connection (that happens in subsequent
|
||||
* WifiCheck calls).
|
||||
*
|
||||
* The retry timing includes a chip-specific offset to prevent multiple
|
||||
* devices from attempting to reconnect simultaneously, which helps
|
||||
* avoid network congestion in multi-device installations.
|
||||
*
|
||||
* Note: This function will not do anything if network_wifi flag is disabled.
|
||||
*/
|
||||
void WifiConnect(void)
|
||||
{
|
||||
if (!Settings->flag4.network_wifi) { return; }
|
||||
@ -1117,6 +1494,26 @@ void WifiConnect(void)
|
||||
#endif // WIFI_RF_PRE_INIT
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a clean shutdown of WiFi connections and services
|
||||
*
|
||||
* @param option If true, performs a more thorough cleanup including SDK WiFi calibration data
|
||||
*
|
||||
* This function properly terminates WiFi connections and related services:
|
||||
* 1. Disconnects any active UDP emulation services
|
||||
* 2. Disconnects MQTT if enabled
|
||||
* 3. Disconnects from WiFi with appropriate cleanup based on the option parameter
|
||||
*
|
||||
* When option=true (used with WIFI_FORCE_RF_CAL_ERASE enabled):
|
||||
* - Performs a simple disconnect
|
||||
* - Erases SDK WiFi configuration and calibration data
|
||||
*
|
||||
* When option=false (default, used for normal shutdown and DeepSleep):
|
||||
* - Performs a more standard disconnect that preserves calibration data
|
||||
*
|
||||
* The function includes delays to ensure network buffers are properly flushed
|
||||
* before disconnection.
|
||||
*/
|
||||
void WifiShutdown(bool option) {
|
||||
// option = false - Legacy disconnect also used by DeepSleep
|
||||
// option = true - Disconnect with SDK wifi calibrate sector erase when WIFI_FORCE_RF_CAL_ERASE enabled
|
||||
@ -1155,6 +1552,18 @@ void WifiShutdown(bool option) {
|
||||
delay(100); // Flush anything in the network buffers.
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely disables WiFi functionality
|
||||
*
|
||||
* This function performs a full shutdown of WiFi:
|
||||
* 1. Checks if WiFi is already disabled to avoid redundant operations
|
||||
* 2. Calls WifiShutdown() to properly terminate connections
|
||||
* 3. Sets WiFi mode to WIFI_OFF to disable the radio
|
||||
* 4. Updates the global state to indicate WiFi is down
|
||||
*
|
||||
* After calling this function, WiFi will remain disabled until explicitly
|
||||
* re-enabled. This is useful for power saving or when WiFi is not needed.
|
||||
*/
|
||||
void WifiDisable(void) {
|
||||
if (!TasmotaGlobal.global_state.wifi_down) {
|
||||
WifiShutdown();
|
||||
@ -1163,6 +1572,26 @@ void WifiDisable(void) {
|
||||
TasmotaGlobal.global_state.wifi_down = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a clean device restart with proper shutdown procedures
|
||||
*
|
||||
* This function handles different types of restart operations:
|
||||
* 1. Normal restart: Performs cleanup and calls ESP.restart()
|
||||
* 2. Halt (TasmotaGlobal.restart_halt): Enters an infinite loop with watchdog feeding
|
||||
* 3. Deep sleep (TasmotaGlobal.restart_deepsleep): Enters deep sleep mode
|
||||
*
|
||||
* Before restarting, the function:
|
||||
* 1. Resets PWM outputs
|
||||
* 2. Performs a clean WiFi shutdown
|
||||
* 3. Clears any crash dump data
|
||||
* 4. For ESP32-C3: Forces GPIO hold for relays to maintain state during reset
|
||||
*
|
||||
* The halt mode is useful for debugging, as it keeps the device running
|
||||
* but in a known state with visual LED feedback.
|
||||
*
|
||||
* Deep sleep mode puts the device into the lowest power state, with only
|
||||
* hardware-triggered wake up possible.
|
||||
*/
|
||||
void EspRestart(void) {
|
||||
ResetPwm();
|
||||
WifiShutdown(true);
|
||||
@ -1209,6 +1638,22 @@ extern "C" {
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a Gratuitous ARP packet to update network ARP tables
|
||||
*
|
||||
* This function sends a Gratuitous ARP announcement to inform other devices
|
||||
* on the network about the device's MAC and IP address mapping. This helps
|
||||
* maintain connectivity by refreshing ARP cache entries on network devices,
|
||||
* particularly useful with routers that might otherwise expire ARP entries.
|
||||
*
|
||||
* The function:
|
||||
* 1. Finds the active station interface
|
||||
* 2. Verifies it has a valid IP address
|
||||
* 3. Sends a gratuitous ARP packet
|
||||
*
|
||||
* This implementation handles differences between LWIP v1 and v2.
|
||||
* Backported from https://github.com/esp8266/Arduino/pull/6889
|
||||
*/
|
||||
void stationKeepAliveNow(void) {
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_WIFI "Sending Gratuitous ARP"));
|
||||
for (netif* interface = netif_list; interface != nullptr; interface = interface->next)
|
||||
@ -1229,6 +1674,22 @@ void stationKeepAliveNow(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Periodically sends Gratuitous ARP packets to maintain network presence
|
||||
*
|
||||
* This function manages the timing for sending Gratuitous ARP packets
|
||||
* based on the configured interval in Settings->param[P_ARP_GRATUITOUS].
|
||||
*
|
||||
* The timing can be configured as:
|
||||
* - Values 1-100: Seconds between ARP packets
|
||||
* - Values >100: Minutes between ARP packets (value - 100)
|
||||
* e.g., 105 = 5 minutes, 110 = 10 minutes
|
||||
* - Value 0: Feature disabled
|
||||
*
|
||||
* This helps maintain connectivity with network devices that might
|
||||
* otherwise expire ARP cache entries, particularly useful with some
|
||||
* router models that aggressively clear their ARP tables.
|
||||
*/
|
||||
void wifiKeepAlive(void) {
|
||||
static uint32_t wifi_timer = millis(); // Wifi keepalive timer
|
||||
|
||||
@ -1246,11 +1707,37 @@ void wifiKeepAlive(void) {
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
// expose a function to be called by WiFi32
|
||||
/**
|
||||
* Returns the configured DNS resolution timeout
|
||||
*
|
||||
* @return DNS timeout value in milliseconds from settings
|
||||
*
|
||||
* This function exposes the DNS timeout setting to be used by WiFi32
|
||||
* and other components that need to know how long to wait for DNS
|
||||
* resolution before timing out.
|
||||
*/
|
||||
int32_t WifiDNSGetTimeout(void) {
|
||||
return Settings->dns_timeout;
|
||||
}
|
||||
// read Settings for DNS IPv6 priority
|
||||
/**
|
||||
* Determines if IPv6 should be prioritized for DNS resolution
|
||||
*
|
||||
* @return true if IPv6 should be prioritized, false otherwise
|
||||
*
|
||||
* This function determines whether IPv6 addresses should be prioritized
|
||||
* over IPv4 for DNS resolution based on:
|
||||
*
|
||||
* 1. User settings (Settings->flag6.dns_ipv6_priority)
|
||||
* 2. Availability of IPv4 and IPv6 addresses
|
||||
*
|
||||
* The logic ensures that:
|
||||
* - If only IPv4 is available, IPv4 is prioritized regardless of settings
|
||||
* - If only IPv6 is available, IPv6 is prioritized regardless of settings
|
||||
* - If both are available, the user setting determines priority
|
||||
*
|
||||
* When the priority changes, the DNS cache is cleared on ESP32 to ensure
|
||||
* proper resolution with the new priority.
|
||||
*/
|
||||
bool WifiDNSGetIPv6Priority(void) {
|
||||
#ifdef USE_IPV6
|
||||
// we prioritize IPv6 only if a global IPv6 address is available, otherwise revert to IPv4 if we have one as well
|
||||
@ -1280,6 +1767,22 @@ bool WifiDNSGetIPv6Priority(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a hostname to an IP address with enhanced handling
|
||||
*
|
||||
* @param aHostname The hostname to resolve
|
||||
* @param aResult Reference to store the resulting IP address
|
||||
* @return true if resolution was successful, false otherwise
|
||||
*
|
||||
* This function extends the standard hostname resolution with:
|
||||
* 1. Direct IP address parsing (for ESP_IDF_VERSION_MAJOR >= 5 with IPv6)
|
||||
* 2. IPv6 zone auto-fixing for link-local addresses
|
||||
* 3. Timeout handling based on Settings->dns_timeout
|
||||
* 4. Detailed logging of resolution results and timing
|
||||
*
|
||||
* The function is used throughout Tasmota for all DNS resolution needs,
|
||||
* providing consistent behavior and error handling.
|
||||
*/
|
||||
bool WifiHostByName(const char* aHostname, IPAddress& aResult) {
|
||||
#ifdef USE_IPV6
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
@ -1305,11 +1808,40 @@ bool WifiHostByName(const char* aHostname, IPAddress& aResult) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a hostname can be resolved via DNS
|
||||
*
|
||||
* @param aHostname The hostname to check
|
||||
* @return true if the hostname can be resolved, false otherwise
|
||||
*
|
||||
* This is a convenience wrapper around WifiHostByName that simply checks
|
||||
* if a hostname can be resolved without needing the resulting IP address.
|
||||
*/
|
||||
bool WifiDnsPresent(const char* aHostname) {
|
||||
IPAddress aResult;
|
||||
return WifiHostByName(aHostname, aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Periodically polls NTP servers to synchronize device time
|
||||
*
|
||||
* This function manages the NTP time synchronization process:
|
||||
* 1. Determines when to attempt synchronization based on:
|
||||
* - Initial sync attempt shortly after boot
|
||||
* - Hourly sync attempts thereafter
|
||||
* - Forced sync requests via TasmotaGlobal.ntp_force_sync
|
||||
*
|
||||
* 2. Calls WifiGetNtp() to retrieve the current time from NTP servers
|
||||
*
|
||||
* 3. Updates the RTC time if a valid time is received
|
||||
*
|
||||
* The function implements a staggered sync schedule based on the device's
|
||||
* chip ID to prevent all devices from querying NTP servers simultaneously.
|
||||
*
|
||||
* Time synchronization is skipped if:
|
||||
* - The network is down
|
||||
* - The user has manually set the time
|
||||
*/
|
||||
void WifiPollNtp() {
|
||||
static uint8_t ntp_sync_minute = 0;
|
||||
static uint32_t ntp_run_time = 0;
|
||||
@ -1348,6 +1880,27 @@ void WifiPollNtp() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current time from an NTP server
|
||||
*
|
||||
* @return Current time in nanoseconds since Unix epoch, or 0 on failure
|
||||
*
|
||||
* This function implements the NTP client protocol:
|
||||
* 1. Selects an NTP server from configured options or fallbacks
|
||||
* 2. Resolves the server hostname to an IP address
|
||||
* 3. Creates a UDP socket with a random local port
|
||||
* 4. Sends an NTP request packet
|
||||
* 5. Waits for and processes the response
|
||||
*
|
||||
* The function handles various error conditions:
|
||||
* - DNS resolution failures
|
||||
* - Socket creation failures
|
||||
* - Packet send/receive errors
|
||||
* - Invalid or unsynchronized server responses
|
||||
*
|
||||
* If a server fails, the function increments ntp_server_id to try
|
||||
* the next configured server on the next attempt.
|
||||
*/
|
||||
uint64_t WifiGetNtp(void) {
|
||||
static uint8_t ntp_server_id = 0;
|
||||
|
||||
@ -1466,6 +2019,30 @@ uint64_t WifiGetNtp(void) {
|
||||
extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
|
||||
|
||||
// typedef void (*WiFiEventSysCb)(arduino_event_t *event);
|
||||
|
||||
/**
|
||||
* Event handler for ESP32 WiFi and network events
|
||||
*
|
||||
* @param event Pointer to the arduino_event_t structure containing event details
|
||||
*
|
||||
* This function processes WiFi and network events on ESP32 platforms:
|
||||
*
|
||||
* 1. IPv6 address assignment:
|
||||
* - Logs when global or local IPv6 addresses are assigned
|
||||
* - Distinguishes between WiFi and Ethernet interfaces
|
||||
*
|
||||
* 2. WiFi connection events:
|
||||
* - Creates IPv6 link-local addresses when WiFi connects
|
||||
* - Works around race conditions in the ESP-IDF LWIP implementation
|
||||
*
|
||||
* 3. IPv4 address assignment:
|
||||
* - Logs when IPv4 addresses are assigned
|
||||
* - Includes subnet mask and gateway information
|
||||
*
|
||||
* The function also ensures DNS servers are properly maintained by calling
|
||||
* WiFiHelper::scrubDNS() to restore DNS settings that might be zeroed by
|
||||
* internal reconnection processes.
|
||||
*/
|
||||
void WifiEvents(arduino_event_t *event) {
|
||||
switch (event->event_id) {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user