ESP32 WiFi Drv
#include <WiFi.h>
From: "https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html"
WiFi Driver Feature List How to Write a Wi-Fi Application Preperation
Setting Wi-Fi Compile Time Options Init Wi-Fi Start Connect Wi-Fi Event Handling
Write Error Recovery Routines ESP32 Wi-Fi API Error Code ESP32 Wi-Fi API Parameter Init ESP32 Wi-Fi Programming Model
ESP32 Wi-Fi Event Description wifi_event_wifi_ready wifi_event_scan_code wifi_event_sta_start
wifi_event_sta_stop wifi_event_sta_connected wifi_event_sta_disconnected ip_event_sta_got_ip
ip_event_got_ip6 ip_event_sta_lost_ip wifi_event_ap_start wifi_event_ap_stop
wifi_event_ap_staconnected wifi_event_ap_stadisconnected wifi_event_ap_probereqrecvd wifi_event_sta_beacon_timeout
wifi_event_connectionless_module_wake_interval_start ESP32 Wi-Fi staion_general Scenario Wi-Fi/LWIP Init Phase Wi-Fi Configuration Phase
Wi-Fi Start Phase WiFi Connect Phase Wi-Fi Got IP Phase Wi-Fi Disconnect Phase
Wi-Fi IP Change Phase Wi-Fi Deinit Phase ESP32 Wi-Fi AP General Scenario ESP32 Wi-Fi Scan
Scan Configuration Scan All Aps On All Channels (foreground) Scan Configuration Phase Wi-Fi Drivers Internal Scan Phase
Scan Done Event Handling Phase Scan All Aps On All channels (background) Scan For Specific Ap On All Channels Scan In Wi-Fi Connect
Scan In Blocked Mode Parallel Scan Scan When Wi-Fi is Connecting ESP32 Wi-Fi Staion Connecting Scenario
Scan Phase Auth Phase Assocition Phase Four Way Handshake Phase
Wi-Fi Reason Code Wi-Fi Reason Code Related to Wrong Password Wi-Fi Reason Code Related to Low Rssi ESP32 Wi-Fi Station Connecting When Multiple Aps Are Found
Wi-Fi Reconnect Wi-Fi Beacon Timeout ESP32 Wi-Fi Configuration Wi-Fi Mode
Station Basic Configuration AP Basic Configuration Wi-Fi Protocol Mode Long Range
LR Compatibility LR Impacts to Traditions Wi-Fi Device LR Transmission Distance LR Throughput
When to Use LR Wi-Fi Country Code Home Channel Wi-Fi Vendor IE Configuration
Wi-Fi Easy Connect WPA2 enterprise ESP32 Currently Supports the Following EAP Methods Wireless Network Management
Radio Resource Measurement ESP32 Wi-Fi Power Saving Mode Station Sleep AP Sleep
Disconnected State Sleep Connectionless Modules Power Saving Connectionless Modules TX Connectionless Modules RX
Default Mode ESP32 Wi-Fi Throughput Wi-Fi 80211 Packet Send Preconditions of Using Esp_wifi_80211_tx
Data Rate Side Effects to Avoid in Different Scenarios Wi-Fi Sniffer Mode Wi-Fi Multiple Antennas
Wi-Fi Multiple Antennas Configuration Wi-Fi Channel State Information Wi-Fi Channel State Information Configure Wi-Fi HT20
Wi-Fi QOS Wi-Fi AMSDU Wi-Fi Fragment Wi-Fi Enrollee
Wi-Fi Buffer Useage Why Buffer Configuration Is important Dynamic VS Static Buffer Peak Wi-Fi Dynamic Buffer
How to Improve Wi-Fi Performance Protocol Stack Operation Mode ESP32 Datapath Paramters
How to Configure Parameters Using PSRAM Wi-Fi Menuconfig Wi-Fi Buffer Configure
Wi-Fi NVS Flash Wi-Fi Aggregate MAC Protocol Data Unit Troubleshooting

Wi-Fi Driver

ESP32 Wi-Fi Feature List
The following features are supported: - 4 virtual Wi-Fi interfaces, which are STA, AP, Sniffer and reserved. - Station-only mode, AP-only mode, station/AP-coexistence mode - IEEE 802.11b, IEEE 802.11g, IEEE 802.11n, and APIs to configure the protocol mode - WPA/WPA2/WPA3/WPA2-Enterprise/WPA3-Enterprise/WAPI/WPS and DPP - AMSDU, AMPDU, HT40, QoS, and other key features - Modem-sleep - The Espressif-specific ESP-NOW protocol and Long Range mode, which supports - up to 1 km of data traffic - Up to 20 MBit/s TCP throughput and 30 MBit/s UDP throughput over the air - Sniffer - Both fast scan and all-channel scan - Multiple antennas - Channel state information
How To Write a Wi-Fi Application

Preparation
Generally, the most effective way to begin your own Wi-Fi application is to select an example which is similar to your own application, and port the useful part into your project. It is not a MUST, but it is strongly recommended that you take some time to read this article first, especially if you want to program a robust Wi-Fi application. This article is supplementary to the Wi-Fi APIs/Examples. It describes the principles of using the Wi-Fi APIs, the limitations of the current Wi-Fi API implementation, and the most common pitfalls in using Wi-Fi. This article also reveals some design details of the Wi-Fi driver. We recommend you to select an example .
Setting Wi-Fi Compile-time Options
Refer to Wi-Fi Menuconfig.
Init Wi-Fi
Refer to ESP32 Wi-Fi station General Scenario and ESP32 Wi-Fi AP General Scenario.
Start/Connect Wi-Fi
Refer to ESP32 Wi-Fi station General Scenario and ESP32 Wi-Fi AP General Scenario.
Event-Handling
Generally, it is easy to write code in “sunny-day” scenarios, such as WIFI_EVENT_STA_START and WIFI_EVENT_STA_CONNECTED. The hard part is to write routines in “rainy-day” scenarios, such as WIFI_EVENT_STA_DISCONNECTED. Good handling of “rainy-day” scenarios is fundamental to robust Wi-Fi applications. Refer to ESP32 Wi-Fi Event Description, ESP32 Wi-Fi station General Scenario, and ESP32 Wi-Fi AP General Scenario. See also an overview of event handling in ESP-IDF.
Write Error-Recovery Routines Correctly at All Times
Just like the handling of “rainy-day” scenarios, a good error-recovery routine is also fundamental to robust Wi-Fi applications. Refer to ESP32 Wi-Fi API Error Code.
ESP32 Wi-Fi API Error Code
All of the ESP32 Wi-Fi APIs have well-defined return values, namely, the error code. The error code can be categorized into: - No errors, e.g., ESP_OK means that the API returns successfully. - Recoverable errors, such as ESP_ERR_NO_MEM. - Non-recoverable, non-critical errors. - Non-recoverable, critical errors. Whether the error is critical or not depends on the API and the application scenario, and it is defined by the API user.
The primary principle to write a robust application with Wi-Fi API is to always check the error code and write the error-handling code.
Generally, the error-handling code can be used: For recoverable errors, in which case you can write a recoverable-error code. For example, when esp_wifi_start() returns ESP_ERR_NO_MEM, the recoverable-error code vTaskDelay can be called in order to get a microseconds’ delay for another try. For non-recoverable, yet non-critical errors, in which case printing the error code is a good method for error handling. For non-recoverable and also critical errors, in which case “assert” may be a good method for error handling. For example, if esp_wifi_set_mode() returns ESP_ERR_WIFI_NOT_INIT, it means that the Wi-Fi driver is not initialized by esp_wifi_init() successfully. You can detect this kind of error very quickly in the application development phase. In esp_err.h, ESP_ERROR_CHECK checks the return values. It is a rather commonplace error-handling code and can be used as the default error-handling code in the application development phase. However, it is strongly recommended that API users write their own error-handling code.
ESP32 Wi-Fi API Parameter Initialization
When initializing struct parameters for the API, one of two approaches should be followed: Explicitly set all fields of the parameter. Use get API to get current configuration first, then set application specific fields. Initializing or getting the entire structure is very important, because most of the time the value 0 indicates that the default value is used. More fields may be added to the struct in the future and initializing these to zero ensures the application will still work correctly after ESP-IDF is updated to a new release.
ESP32 Wi-Fi Programming Model
The ESP32 Wi-Fi programming model is depicted as follows: Wi-Fi Programming Model The Wi-Fi driver can be considered a black box that knows nothing about high-layer code, such as the TCP/IP stack, application task, and event task. The application task (code) generally calls Wi-Fi driver APIs to initialize Wi-Fi and handles Wi-Fi events when necessary. Wi-Fi driver receives API calls, handles them, and posts events to the application. Wi-Fi event handling is based on the esp_event library. Events are sent by the Wi-Fi driver to the default event loop. Application may handle these events in callbacks registered using esp_event_handler_register(). Wi-Fi events are also handled by esp_netif component to provide a set of default behaviors. For example, when Wi-Fi station connects to an AP, esp_netif will automatically start the DHCP client by default.
ESP32 Wi-Fi Event Description

WIFI_EVENT_WIFI_READY
The Wi-Fi driver will never generate this event, which, as a result, can be ignored by the application event callback. This event may be removed in future releases.
WIFI_EVENT_SCAN_DONE
The scan-done event is triggered by esp_wifi_scan_start() and will arise in the following scenarios: The scan is completed, e.g., the target AP is found successfully, or all channels have been scanned. The scan is stopped by esp_wifi_scan_stop(). The esp_wifi_scan_start() is called before the scan is completed. A new scan will override the current scan and a scan-done event will be generated. The scan-done event will not arise in the following scenarios: It is a blocked scan. The scan is caused by esp_wifi_connect(). Upon receiving this event, the event task does nothing. The application event callback needs to call esp_wifi_scan_get_ap_num() and esp_wifi_scan_get_ap_records() to fetch the scanned AP list and trigger the Wi-Fi driver to free the internal memory which is allocated during the scan (do not forget to do this!). Refer to ESP32 Wi-Fi Scan for a more detailed description.
WIFI_EVENT_STA_START
If esp_wifi_start() returns ESP_OK and the current Wi-Fi mode is station or station/AP, then this event will arise. Upon receiving this event, the event task will initialize the LwIP network interface (netif). Generally, the application event callback needs to call esp_wifi_connect() to connect to the configured AP.
WIFI_EVENT_STA_STOP
If esp_wifi_stop() returns ESP_OK and the current Wi-Fi mode is station or station/AP, then this event will arise. Upon receiving this event, the event task will release the station’s IP address, stop the DHCP client, remove TCP/UDP-related connections, and clear the LwIP station netif, etc. The application event callback generally does not need to do anything.
WIFI_EVENT_STA_CONNECTED
If esp_wifi_connect() returns ESP_OK and the station successfully connects to the target AP, the connection event will arise. Upon receiving this event, the event task starts the DHCP client and begins the DHCP process of getting the IP address. Then, the Wi-Fi driver is ready for sending and receiving data. This moment is good for beginning the application work, provided that the application does not depend on LwIP, namely the IP address. However, if the application is LwIP-based, then you need to wait until the got ip event comes in.
WIFI_EVENT_STA_DISCONNECTED
This event can be generated in the following scenarios: - When esp_wifi_disconnect() or esp_wifi_stop() is called and the station is already connected to the AP. - When esp_wifi_connect() is called, but the Wi-Fi driver fails to set up a connection with the AP due to certain reasons, e.g., the scan fails to find the target AP or the authentication times out. If there are more than one AP with the same SSID, the disconnected event will be raised after the station fails to connect all of the found APs. - When the Wi-Fi connection is disrupted because of specific reasons, e.g. , the station continuously loses N beacons, the AP kicks off the station, or the AP’s authentication mode is changed. Upon receiving this event, the default behaviors of the event task are: - Shutting down the station’s LwIP netif. - Notifying the LwIP task to clear the UDP/TCP connections which cause the wrong status to all sockets. For socket-based applications, the application callback can choose to close all sockets and re-create them, if necessary, upon receiving this event. The most common event handle code for this event in application is to call esp_wifi_connect() to reconnect the Wi-Fi. However, if the event is raised because esp_wifi_disconnect() is called, the application should not call esp_wifi_connect() to reconnect. It is the application’s responsibility to distinguish whether the event is caused by esp_wifi_disconnect() or other reasons. Sometimes a better reconnection strategy is required. Refer to Wi-Fi Reconnect and Scan When Wi-Fi Is Connecting. Another thing that deserves attention is that the default behavior of LwIP is to abort all TCP socket connections on receiving the disconnect. In mose cases, it is not a problem. However, for some special applications, this may not be what they want. Consider the following scenarios: The application creates a TCP connection to maintain the application-level keep-alive data that is sent out every 60 seconds. Due to certain reasons, the Wi-Fi connection is cut off, and the WIFI_EVENT_STA_DISCONNECTED is raised. According to the current implementation, all TCP connections will be removed and the keep-alive socket will be in a wrong status. However, since the application designer believes that the network layer should ignore this error at the Wi-Fi layer, the application does not close the socket. Five seconds later, the Wi-Fi connection is restored because esp_wifi_connect() is called in the application event callback function. Moreover, the station connects to the same AP and gets the same IPV4 address as before. Sixty seconds later, when the application sends out data with the keep-alive socket, the socket returns an error and the application closes the socket and re-creates it when necessary. In above scenarios, ideally, the application sockets and the network layer should not be affected, since the Wi-Fi connection only fails temporarily and recovers very quickly. The application can enable “Keep TCP connections when IP changed” via LwIP menuconfig.
IP_EVENT_STA_GOT_IP
This event arises when the DHCP client successfully gets the IPV4 address from the DHCP server, or when the IPV4 address is changed. The event means that everything is ready and the application can begin its tasks (e.g., creating sockets). The IPV4 may be changed because of the following reasons: The DHCP client fails to renew/rebind the IPV4 address, and the station’s IPV4 is reset to 0. The DHCP client rebinds to a different address. The static-configured IPV4 address is changed. Whether the IPV4 address is changed or not is indicated by the field ip_change of ip_event_got_ip_t. The socket is based on the IPV4 address, which means that, if the IPV4 changes, all sockets relating to this IPV4 will become abnormal. Upon receiving this event, the application needs to close all sockets and recreate the application when the IPV4 changes to a valid one.
IP_EVENT_GOT_IP6
This event arises when the IPV6 SLAAC support auto-configures an address for the ESP32, or when this address changes. The event means that everything is ready and the application can begin its tasks, e.g., creating sockets.
IP_EVENT_STA_LOST_IP
This event arises when the IPV4 address becomes invalid. IP_EVENT_STA_LOST_IP does not arise immediately after the Wi-Fi disconnects. Instead, it starts an IPV4 address lost timer. If the IPV4 address is got before ip lost timer expires, IP_EVENT_STA_LOST_IP does not happen. Otherwise, the event arises when the IPV4 address lost timer expires. Generally, the application can ignore this event, because it is just a debug event to inform that the IPV4 address is lost.
WIFI_EVENT_AP_START
Similar to WIFI_EVENT_STA_START.
WIFI_EVENT_AP_STOP
Similar to WIFI_EVENT_STA_STOP.
WIFI_EVENT_AP_STACONNECTED
Every time a station is connected to ESP32 AP, the WIFI_EVENT_AP_STACONNECTED will arise. Upon receiving this event, the event task will do nothing, and the application callback can also ignore it. However, you may want to do something, for example, to get the info of the connected STA.
WIFI_EVENT_AP_STADISCONNECTED
This event can happen in the following scenarios: The application calls esp_wifi_disconnect(), or esp_wifi_deauth_sta(), to manually disconnect the station. The Wi-Fi driver kicks off the station, e.g., because the AP has not received any packets in the past five minutes. The time can be modified by esp_wifi_set_inactive_time(). The station kicks off the AP. When this event happens, the event task will do nothing, but the application event callback needs to do something, e.g., close the socket which is related to this station.
WIFI_EVENT_AP_PROBEREQRECVED
This event is disabled by default. The application can enable it via API esp_wifi_set_event_mask(). When this event is enabled, it will be raised each time the AP receives a probe request.
WIFI_EVENT_STA_BEACON_TIMEOUT
If the station does not receive the beacon of the connected AP within the inactive time, the beacon timeout happens, the WIFI_EVENT_STA_BEACON_TIMEOUT will arise. The application can set inactive time via API esp_wifi_set_inactive_time().
WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START
The WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START will arise at the start of connectionless module Interval. See connectionless module power save.
ESP32 Wi-Fi Station General Scenario
Below is a “big scenario” which describes some small scenarios in station mode: Sample Wi-Fi Event Scenarios in Station Mode
1. Wi-Fi/LwIP Init Phase
s1.1: The main task calls esp_netif_init() to create an LwIP core task and initialize LwIP-related work. s1.2: The main task calls esp_event_loop_create() to create a system Event task and initialize an application event’s callback function. In the scenario above, the application event’s callback function does nothing but relaying the event to the application task. s1.3: The main task calls esp_netif_create_default_wifi_ap() or esp_netif_create_default_wifi_sta() to create default network interface instance binding station or AP with TCP/IP stack. s1.4: The main task calls esp_wifi_init() to create the Wi-Fi driver task and initialize the Wi-Fi driver. s1.5: The main task calls OS API to create the application task. Step 1.1 ~ 1.5 is a recommended sequence that initializes a Wi-Fi-/LwIP-based application. However, it is NOT a must-follow sequence, which means that you can create the application task in step 1.1 and put all other initializations in the application task. Moreover, you may not want to create the application task in the initialization phase if the application task depends on the sockets. Rather, you can defer the task creation until the IP is obtained.
2. Wi-Fi Configuration Phase
Once the Wi-Fi driver is initialized, you can start configuring the Wi-Fi driver. In this scenario, the mode is station, so you may need to call esp_wifi_set_mode() (WIFI_MODE_STA) to configure the Wi-Fi mode as station. You can call other esp_wifi_set_xxx APIs to configure more settings, such as the protocol mode, the country code, and the bandwidth. Refer to ESP32 Wi-Fi Configuration. Generally, the Wi-Fi driver should be configured before the Wi-Fi connection is set up. But this is NOT mandatory, which means that you can configure the Wi-Fi connection anytime, provided that the Wi-Fi driver is initialized successfully. However, if the configuration does not need to change after the Wi-Fi connection is set up, you should configure the Wi-Fi driver at this stage, because the configuration APIs (such as esp_wifi_set_protocol()) will cause the Wi-Fi to reconnect, which may not be desirable. If the Wi-Fi NVS flash is enabled by menuconfig, all Wi-Fi configuration in this phase, or later phases, will be stored into flash. When the board powers on/reboots, you do not need to configure the Wi-Fi driver from scratch. You only need to call esp_wifi_get_xxx APIs to fetch the configuration stored in flash previously. You can also configure the Wi-Fi driver if the previous configuration is not what you want.
3. Wi-Fi Start Phase
s3.1: Call esp_wifi_start() to start the Wi-Fi driver. s3.2: The Wi-Fi driver posts WIFI_EVENT_STA_START to the event task; then, the event task will do some common things and will call the application event callback function. s3.3: The application event callback function relays the WIFI_EVENT_STA_START to the application task. We recommend that you call esp_wifi_connect(). However, you can also call esp_wifi_connect() in other phrases after the WIFI_EVENT_STA_START arises.
4. Wi-Fi Connect Phase
s4.1: Once esp_wifi_connect() is called, the Wi-Fi driver will start the internal scan/connection process. s4.2: If the internal scan/connection process is successful, the WIFI_EVENT_STA_CONNECTED will be generated. In the event task, it starts the DHCP client, which will finally trigger the DHCP process. s4.3: In the above-mentioned scenario, the application event callback will relay the event to the application task. Generally, the application needs to do nothing, and you can do whatever you want, e.g., print a log. In step 4.2, the Wi-Fi connection may fail because, for example, the password is wrong, or the AP is not found. In a case like this, WIFI_EVENT_STA_DISCONNECTED will arise and the reason for such a failure will be provided. For handling events that disrupt Wi-Fi connection, please refer to phase 6.
5. Wi-Fi ‘Got IP’ Phase
s5.1: Once the DHCP client is initialized in step 4.2, the got IP phase will begin. s5.2: If the IP address is successfully received from the DHCP server, then IP_EVENT_STA_GOT_IP will arise and the event task will perform common handling. s5.3: In the application event callback, IP_EVENT_STA_GOT_IP is relayed to the application task. For LwIP-based applications, this event is very special and means that everything is ready for the application to begin its tasks, e.g., creating the TCP/UDP socket. A very common mistake is to initialize the socket before IP_EVENT_STA_GOT_IP is received. DO NOT start the socket-related work before the IP is received.
6. Wi-Fi Disconnect Phase
s6.1: When the Wi-Fi connection is disrupted, e.g., the AP is powered off or the RSSI is poor, WIFI_EVENT_STA_DISCONNECTED will arise. This event may also arise in phase 3. Here, the event task will notify the LwIP task to clear/remove all UDP/TCP connections. Then, all application sockets will be in a wrong status. In other words, no socket can work properly when this event happens. s6.2: In the scenario described above, the application event callback function relays WIFI_EVENT_STA_DISCONNECTED to the application task. The recommended actions are: 1) call esp_wifi_connect() to reconnect the Wi-Fi, 2) close all sockets, and 3) re-create them if necessary. For details, please refer to WIFI_EVENT_STA_DISCONNECTED.
7 . Wi-Fi IP Change Phase
s7.1: If the IP address is changed, the IP_EVENT_STA_GOT_IP will arise with “ip_change” set to true. s7.2: This event is important to the application. When it occurs, the timing is good for closing all created sockets and recreating them.
8. Wi-Fi Deinit Phase
s8.1: Call esp_wifi_disconnect() to disconnect the Wi-Fi connectivity. s8.2: Call esp_wifi_stop() to stop the Wi-Fi driver. s8.3: Call esp_wifi_deinit() to unload the Wi-Fi driver.
ESP32 Wi-Fi AP General Scenario
Below is a “big scenario” which describes some small scenarios in AP mode: Sample Wi-Fi Event Scenarios in AP Mode
ESP32 Wi-Fi Scan
Currently, the esp_wifi_scan_start() API is supported only in station or station/AP mode.
Scan Type
Mode Description
Active Scan Scan by sending a probe request. The default scan is an active scan.
Passive Scan No probe request is sent out. Just switch to the specific channel and wait
for a beacon. Application can enable it via the scan_type field of
wifi_scan_config_t.
Foreground Scan This scan is applicable when there is no Wi-Fi connection in station mode.
Foreground or background scanning is controlled by the Wi-Fi driver and cannot
be configured by the application.
Background Scan This scan is applicable when there is a Wi-Fi connection in station mode or
in station/AP mode. Whether it is a foreground scan or background scan depends
on the Wi-Fi driver and cannot be configured by the application.
All-Channel Scan It scans all of the channels. If the channel field of wifi_scan_config_t
is set to 0, it is an all-channel scan.
Specific Channel Scan It scans specific channels only. If the channel field of wifi_scan_config_t
set to 1-14, it is a specific-channel scan.
The scan modes in above table can be combined arbitrarily, so there are in total 8 different scans: All-Channel Background Active Scan All-Channel Background Passive Scan All-Channel Foreground Active Scan All-Channel Foreground Passive Scan Specific-Channel Background Active Scan Specific-Channel Background Passive Scan Specific-Channel Foreground Active Scan Specific-Channel Foreground Passive Scan
Scan Configuration
The scan type and other per-scan attributes are configured by
esp_wifi_scan_start().
The table below provides a detailed description of wifi_scan_config_t.
Field Description
ssid If the SSID is not NULL, it is only the AP with the same SSID that can be
scanned.
bssid If the BSSID is not NULL, it is only the AP with the same BSSID that can be
scanned.
channel If “channel” is 0, there will be an all-channel scan; otherwise, there will
be a specific-channel scan.
show_hidden If “show_hidden” is 0, the scan ignores the AP with a hidden SSID; otherwise
, the scan considers the hidden AP a normal one.
scan_type If “scan_type” is WIFI_SCAN_TYPE_ACTIVE, the scan is “active”; otherwise, it
is a “passive” one.
scan_time This field is used to control how long the scan dwells on each channel.
For passive scans, scan_time.passive designates the dwell time for each channel.
For active scans, dwell times for each channel are listed in the table
below. Here, min is short for scan time.active.min and max is short for
scan_time.active.max.
  • min=0, max=0: scan dwells on each channel for 120 ms.
  • min>0, max=0: scan dwells on each channel for 120 ms.
  • min=0, max>0: scan dwells on each channel for max ms.
  • min>0, max>0: the minimum time the scan dwells on each channel is min 
    ms. If no AP is found during this time frame, the scan switches to the
    next channel. Otherwise, the scan dwells on the channel for max ms.

If you want to improve the performance of the scan, you can try to modify
these two parameters.
There are also some global scan attributes which are configured by
API esp_wifi_set_config(), refer to Station Basic Configuration
Scan All APs on All Channels (Foreground)
Scenario: Foreground Scan of all Wi-Fi Channels The scenario above describes an all-channel, foreground scan. The foreground scan can only occur in station mode where the station does not connect to any AP. Whether it is a foreground or background scan is totally determined by the Wi-Fi driver, and cannot be configured by the application. Detailed scenario description:
Scan Configuration Phase

Wi-Fi Driver’s Internal Scan Phase

Scan-Done Event Handling Phase

Scan All APs on All Channels (Background)
Scenario: Background Scan of all Wi-Fi Channels The scenario above is an all-channel background scan. Compared to Scan All APs on All Channels (Foreground) , the difference in the all-channel background scan is that the Wi-Fi driver will scan the back-to-home channel for 30 ms before it switches to the next channel to give the Wi-Fi connection a chance to transmit/receive data.
Scan for Specific AP on All Channels
Scenario: Scan of specific Wi-Fi Channels This scan is similar to Scan All APs on All Channels (Foreground). The differences are: It is a possible situation that there are multiple APs that match the target AP info, e.g., two APs with the SSID of “ap” are scanned. In this case, if the scan is WIFI_FAST_SCAN, then only the first scanned “ap” will be found. If the scan is WIFI_ALL_CHANNEL_SCAN, both “ap” will be found and the station will connect the “ap” according to the configured strategy. Refer to Station Basic Configuration. You can scan a specific AP, or all of them, in any given channel. These two scenarios are very similar.
Scan in Wi-Fi Connect
When esp_wifi_connect() is called, the Wi-Fi driver will try to scan the configured AP first. The scan in “Wi-Fi Connect” is the same as Scan for Specific AP On All Channels, except that no scan-done event will be generated when the scan is completed. If the target AP is found, the Wi-Fi driver will start the Wi-Fi connection; otherwise, WIFI_EVENT_STA_DISCONNECTED will be generated. Refer to Scan for Specific AP On All Channels.
Scan in Blocked Mode
If the block parameter of esp_wifi_scan_start() is true, then the scan is a blocked one, and the application task will be blocked until the scan is done. The blocked scan is similar to an unblocked one, except that no scan-done event will arise when the blocked scan is completed.
Parallel Scan
Two application tasks may call esp_wifi_scan_start() at the same time, or the same application task calls esp_wifi_scan_start() before it gets a scan-done event. Both scenarios can happen. However, the Wi-Fi driver does not support multiple concurrent scans adequately. As a result, concurrent scans should be avoided. Support for concurrent scan will be enhanced in future releases, as the ESP32’s Wi-Fi functionality improves continuously.
Scan When Wi-Fi Is Connecting
The esp_wifi_scan_start() fails immediately if the Wi-Fi is connecting, because the connecting has higher priority than the scan. If scan fails because of connecting, the recommended strategy is to delay for some time and retry scan again. The scan will succeed once the connecting is completed. However, the retry/delay strategy may not work all the time. Considering the following scenarios: The station is connecting a non-existing AP or it connects the existing AP with a wrong password, it always raises the event WIFI_EVENT_STA_DISCONNECTED. The application calls esp_wifi_connect() to reconnect on receiving the disconnect event. Another application task, e.g., the console task, calls esp_wifi_scan_start() to do scan, the scan always fails immediately because the station keeps connecting. When scan fails, the application simply delays for some time and retries the scan. In the above scenarios, the scan will never succeed because the connecting is in process. So if the application supports similar scenario, it needs to implement a better reconnection strategy. For example: The application can define its own reconnection strategy to avoid the scan starve to death. Refer to .
ESP32 Wi-Fi Station Connecting Scenario
This scenario depicts the case if only one target AP is found in the scan phase. For scenarios where more than one AP with the same SSID is found, refer to ESP32 Wi-Fi Station Connecting When Multiple APs Are Found. Generally, the application can ignore the connecting process. Below is a brief introduction to the process for those who are really interested. Scenario: Wi-Fi Station Connecting Process
Scan Phase

Auth Phase