mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
docs: remove old wifi.rst files after document split
This commit is contained in:
+1
-1
@@ -89,7 +89,7 @@ BLUFI_DOCS = ['api-guides/ble/blufi.rst', 'api-reference/bluetooth/esp_blufi.rst
|
||||
|
||||
WIFI_DOCS = [
|
||||
'api-guides/low-power-mode/low-power-mode-wifi.rst',
|
||||
'api-guides/wifi.rst',
|
||||
'api-guides/wifi-driver/**',
|
||||
'api-guides/wifi-security.rst',
|
||||
'api-guides/wireshark-user-guide.rst',
|
||||
'api-reference/network/esp_now.rst',
|
||||
|
||||
@@ -48,7 +48,7 @@ API Guides
|
||||
host-apps
|
||||
:SOC_USB_OTG_SUPPORTED and not esp32p4 and not esp32h4: usb-otg-console
|
||||
:SOC_USB_SERIAL_JTAG_SUPPORTED: usb-serial-jtag-console
|
||||
:SOC_WIFI_SUPPORTED: wifi
|
||||
:SOC_WIFI_SUPPORTED: wifi-driver/index
|
||||
:SOC_WIFI_SUPPORTED: wifi-security
|
||||
wifi-expansion
|
||||
:SOC_WIFI_SUPPORTED or SOC_BT_SUPPORTED or SOC_IEEE802154_SUPPORTED: phy
|
||||
|
||||
@@ -204,7 +204,7 @@ Common priorities are:
|
||||
- FreeRTOS Timer Task to handle FreeRTOS timer callbacks is created when the scheduler initializes and has minimum task priority (1, :ref:`configurable <CONFIG_FREERTOS_TIMER_TASK_PRIORITY>`).
|
||||
- :doc:`/api-reference/system/esp_event` system task to manage the default system event loop and execute callbacks has high priority (20, ``ESP_TASK_EVENT_PRIO``). This configuration is only used if the application calls :cpp:func:`esp_event_loop_create_default`. It is possible to call :cpp:func:`esp_event_loop_create` with a custom task configuration instead.
|
||||
- :doc:`/api-guides/lwip` TCP/IP task has high priority (18, ``ESP_TASK_TCPIP_PRIO``).
|
||||
:SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi` task has high priority (23).
|
||||
:SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi-driver/index` task has high priority (23).
|
||||
:SOC_WIFI_SUPPORTED: - Wi-Fi wpa_supplicant component may create dedicated tasks while the Wi-Fi Protected Setup (WPS), WPA2 EAP-TLS, Device Provisioning Protocol (DPP) or BSS Transition Management (BTM) features are in use. These tasks all have low priority (2).
|
||||
:SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/controller_vhci` task has high priority (23, ``ESP_TASK_BT_CONTROLLER_PRIO``). The Bluetooth Controller needs to respond to requests with low latency, so it should always be among the highest priority task in the system.
|
||||
:SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/nimble/index` task has high priority (21).
|
||||
@@ -220,7 +220,7 @@ Common priorities are:
|
||||
- FreeRTOS Timer Task to handle FreeRTOS timer callbacks is created when the scheduler initializes and has minimum task priority (1, :ref:`configurable <CONFIG_FREERTOS_TIMER_TASK_PRIORITY>`). This task is pinned to Core 0.
|
||||
- :doc:`/api-reference/system/esp_event` system task to manage the default system event loop and execute callbacks has high priority (20, ``ESP_TASK_EVENT_PRIO``) and it is pinned to Core 0. This configuration is only used if the application calls :cpp:func:`esp_event_loop_create_default`, it is possible to call :cpp:func:`esp_event_loop_create` with a custom task configuration instead.
|
||||
- :doc:`/api-guides/lwip` TCP/IP task has high priority (18, ``ESP_TASK_TCPIP_PRIO``) and is not pinned to any core (:ref:`configurable<CONFIG_LWIP_TCPIP_TASK_AFFINITY>`).
|
||||
:SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi` task has high priority (23) and is pinned to Core 0 by default (:ref:`configurable<CONFIG_ESP_WIFI_TASK_CORE_ID>`).
|
||||
:SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi-driver/index` task has high priority (23) and is pinned to Core 0 by default (:ref:`configurable<CONFIG_ESP_WIFI_TASK_CORE_ID>`).
|
||||
:SOC_WIFI_SUPPORTED: - Wi-Fi wpa_supplicant component may create dedicated tasks while the Wi-Fi Protected Setup (WPS), WPA2 EAP-TLS, Device Provisioning Protocol (DPP) or BSS Transition Management (BTM) features are in use. These tasks all have low priority (2) and are not pinned to any core.
|
||||
:SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/controller_vhci` task has high priority (23, ``ESP_TASK_BT_CONTROLLER_PRIO``) and is pinned to Core 0 by default (:ref:`configurable <{IDF_TARGET_CONTROLLER_CORE_CONFIG}>`). The Bluetooth Controller needs to respond to requests with low latency, so it should always be among the highest priority task assigned to a single CPU.
|
||||
:SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/nimble/index` task has high priority (21) and is pinned to Core 0 by default (:ref:`configurable <CONFIG_BT_NIMBLE_PINNED_TO_CORE_CHOICE>`).
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#############
|
||||
Wi-Fi Driver
|
||||
#############
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
overview
|
||||
station-scenarios
|
||||
wifi-modes
|
||||
wifi-mac-protocols
|
||||
security-and-roaming
|
||||
wifi-performance-and-power-save
|
||||
wifi-vendor-features
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
||||
Security and Roaming
|
||||
============================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
|
||||
Supported Wi-Fi Security Modes
|
||||
--------------------------------
|
||||
|
||||
{IDF_TARGET_NAME} supports the following Wi-Fi security modes. For detailed configuration and usage, refer to :doc:`Wi-Fi Security <../wifi-security>`.
|
||||
|
||||
- Open
|
||||
- WEP
|
||||
- WPA-Personal
|
||||
- WPA2-Personal
|
||||
- WPA3-Personal
|
||||
- Wi-Fi Enterprise
|
||||
|
||||
|
||||
Wi-Fi Easy Connect™ (DPP)
|
||||
--------------------------
|
||||
|
||||
Wi-Fi Easy Connect\ :sup:`TM` (or Device Provisioning Protocol) is a secure and standardized provisioning protocol for configuring Wi-Fi devices. More information can be found in :doc:`esp_dpp <../../api-reference/network/esp_dpp>`.
|
||||
|
||||
|
||||
WPS Enrollee
|
||||
-------------------------
|
||||
|
||||
{IDF_TARGET_NAME} supports WPS enrollee feature in Wi-Fi mode :cpp:enumerator:`WIFI_MODE_STA` or :cpp:enumerator:`WIFI_MODE_APSTA`. Currently, {IDF_TARGET_NAME} supports WPS enrollee type PBC and PIN.
|
||||
|
||||
|
||||
Wireless Network Management
|
||||
----------------------------
|
||||
|
||||
Wireless Network Management allows client devices to exchange information about the network topology, including information related to RF environment. This makes each client network-aware, facilitating overall improvement in the performance of the wireless network. It is part of 802.11v specification. It also enables the client to support Network assisted Roaming.
|
||||
- Network assisted Roaming: Enables WLAN to send messages to associated clients, resulting clients to associate with APs with better link metrics. This is useful for both load balancing and in directing poorly connected clients.
|
||||
|
||||
Current implementation of 802.11v includes support for BSS transition management frames.
|
||||
|
||||
Radio Resource Measurement
|
||||
---------------------------
|
||||
|
||||
Radio Resource Measurement (802.11k) is intended to improve the way traffic is distributed within a network. In a WLAN, each device normally connects to the access point (AP) that provides the strongest signal. Depending on the number and geographic locations of the subscribers, this arrangement can sometimes lead to excessive demand on one AP and underutilization of others, resulting in degradation of overall network performance. In a network conforming to 802.11k, if the AP having the strongest signal is loaded to its full capacity, a wireless device can be moved to one of the underutilized APs. Even though the signal may be weaker, the overall throughput is greater because more efficient use is made of the network resources.
|
||||
|
||||
Current implementation of 802.11k includes support for beacon measurement report, link measurement report, and neighbor request.
|
||||
|
||||
Refer ESP-IDF example :idf_file:`examples/wifi/roaming/README.md` to set up and use these APIs. Example code only demonstrates how these APIs can be used, and the application should define its own algorithm and cases as required.
|
||||
|
||||
Fast BSS Transition
|
||||
---------------------------
|
||||
|
||||
Fast BSS transition (802.11r FT), is a standard to permit continuous connectivity aboard wireless devices in motion, with fast and secure client transitions from one Basic Service Set (abbreviated BSS, and also known as a base station or more colloquially, an access point) to another performed in a nearly seamless manner **avoiding 802.1i 4 way handshake** . 802.11r specifies transitions between access points by redefining the security key negotiation protocol, allowing both the negotiation and requests for wireless resources to occur in parallel. The key derived from the server to be cached in the wireless network, so that a reasonable number of future connections can be based on the cached key, avoiding the 802.1X process
|
||||
|
||||
|
||||
{IDF_TARGET_NAME} station supports FT for WPA2-PSK networks. Do note that {IDF_TARGET_NAME} station only support FT over the air protocol only.
|
||||
|
||||
A config option :ref:`CONFIG_ESP_WIFI_11R_SUPPORT` and configuration parameter :cpp:type:`ft_enabled` in :cpp:type:`wifi_sta_config_t` is provided to enable 802.11r support for station. Refer ESP-IDF example :idf_file:`examples/wifi/roaming/README.md` for further details.
|
||||
|
||||
.. only:: SOC_WIFI_FTM_SUPPORT
|
||||
|
||||
Wi-Fi Location
|
||||
-------------------------------
|
||||
|
||||
Wi-Fi Location will improve the accuracy of a device's location data beyond the Access Point, which will enable creation of new and feature-rich applications and services such as geo-fencing, network management, and navigation. One of the protocols used to determine the device location with respect to the Access Point is Fine Timing Measurement which calculates Time-of-Flight of a Wi-Fi frame.
|
||||
|
||||
Fine Timing Measurement (FTM)
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
FTM is used to measure Wi-Fi Round Trip Time (Wi-Fi RTT) which is the time a Wi-Fi signal takes to travel from a device to another device and back again. Using Wi-Fi RTT, the distance between the devices can be calculated with a simple formula of `RTT * c / 2`, where c is the speed of light.
|
||||
|
||||
FTM uses timestamps given by Wi-Fi interface hardware at the time of arrival or departure of frames exchanged between a pair of devices. One entity called FTM Initiator (mostly a station device) discovers the FTM Responder (can be a station or an Access Point) and negotiates to start an FTM procedure. The procedure uses multiple Action frames sent in bursts and its ACK's to gather the timestamps data. FTM Initiator gathers the data in the end to calculate an average Round-Trip-Time.
|
||||
|
||||
{IDF_TARGET_NAME} supports FTM in below configuration:
|
||||
|
||||
- {IDF_TARGET_NAME} as FTM Initiator in station mode.
|
||||
- {IDF_TARGET_NAME} as FTM Responder in AP mode.
|
||||
|
||||
.. only:: esp32c6
|
||||
|
||||
{IDF_TARGET_NAME} ECO1 and older versions do not support FTM Initiator mode.
|
||||
|
||||
.. attention::
|
||||
|
||||
Distance measurement using RTT is not accurate, and factors such as RF interference, multi-path travel, antenna orientation, and lack of calibration increase these inaccuracies. For better results, it is suggested to perform FTM between two ESP32 chip series devices as station and AP.
|
||||
|
||||
Refer to ESP-IDF example :idf_file:`examples/wifi/ftm/README.md` for steps on how to set up and perform FTM.
|
||||
@@ -0,0 +1,898 @@
|
||||
Station Scenarios
|
||||
=========================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
.. _wifi-station-general-scenario:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi Station General Scenario
|
||||
-------------------------------------------------
|
||||
|
||||
Below is a "big scenario" which describes some small scenarios in station mode:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: Sample Wi-Fi Event Scenarios in Station Mode
|
||||
:align: center
|
||||
|
||||
seqdiag sample-scenarios-station-mode {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 140;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
MAIN_TASK [label = "Main\ntask"];
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
LwIP_TASK [label = "LwIP\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
=== 1. Init Phase ===
|
||||
MAIN_TASK -> LwIP_TASK [label="1.1> Create / init LwIP"];
|
||||
MAIN_TASK -> EVENT_TASK [label="1.2> Create / init event"];
|
||||
MAIN_TASK -> WIFI_TASK [label="1.3> Create / init Wi-Fi"];
|
||||
MAIN_TASK -> APP_TASK [label="1.4> Create app task"];
|
||||
=== 2. Configure Phase ===
|
||||
MAIN_TASK -> WIFI_TASK [label="2> Configure Wi-Fi"];
|
||||
=== 3. Start Phase ===
|
||||
MAIN_TASK -> WIFI_TASK [label="3.1> Start Wi-Fi"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.2> WIFI_EVENT_STA_START"];
|
||||
APP_TASK <- EVENT_TASK [label="3.3> WIFI_EVENT_STA_START"];
|
||||
=== 4. Connect Phase ===
|
||||
APP_TASK -> WIFI_TASK [label="4.1> Connect Wi-Fi"];
|
||||
EVENT_TASK <- WIFI_TASK [label="4.2> WIFI_EVENT_STA_CONNECTED"];
|
||||
APP_TASK <- EVENT_TASK [label="4.3> WIFI_EVENT_STA_CONNECTED"];
|
||||
=== 5. Got IP Phase ===
|
||||
EVENT_TASK -> LwIP_TASK [label="5.1> Start DHCP client"];
|
||||
EVENT_TASK <- LwIP_TASK [label="5.2> IP_EVENT_STA_GOT_IP"];
|
||||
APP_TASK <- EVENT_TASK [label="5.3> IP_EVENT_STA_GOT_IP"];
|
||||
APP_TASK -> APP_TASK [label="5.4> socket related init"];
|
||||
=== 6. Disconnect Phase ===
|
||||
EVENT_TASK <- WIFI_TASK [label="6.1> WIFI_EVENT_STA_DISCONNECTED"];
|
||||
APP_TASK <- EVENT_TASK [label="6.2> WIFI_EVENT_STA_DISCONNECTED"];
|
||||
APP_TASK -> APP_TASK [label="6.3> disconnect handling"];
|
||||
=== 7. IP Change Phase ===
|
||||
EVENT_TASK <- LwIP_TASK [label="7.1> IP_EVENT_STA_GOT_IP"];
|
||||
APP_TASK <- EVENT_TASK [label="7.2> IP_EVENT_STA_GOT_IP"];
|
||||
APP_TASK -> APP_TASK [label="7.3> Socket error handling"];
|
||||
=== 8. Deinit Phase ===
|
||||
APP_TASK -> WIFI_TASK [label="8.1> Disconnect Wi-Fi"];
|
||||
APP_TASK -> WIFI_TASK [label="8.2> Stop Wi-Fi"];
|
||||
APP_TASK -> WIFI_TASK [label="8.3> Deinit Wi-Fi"];
|
||||
}
|
||||
|
||||
|
||||
1. Wi-Fi/LwIP Init Phase
|
||||
++++++++++++++++++++++++++++++
|
||||
|
||||
- s1.1: The main task calls :cpp:func:`esp_netif_init()` to create an LwIP core task and initialize LwIP-related work.
|
||||
|
||||
- s1.2: The main task calls :cpp:func:`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 :cpp:func:`esp_netif_create_default_wifi_ap()` or :cpp:func:`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 :cpp:func:`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 initialization 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 :cpp:func:`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 :ref:`wifi-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 :cpp:func:`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 :cpp:func:`esp_wifi_start()` to start the Wi-Fi driver.
|
||||
- s3.2: The Wi-Fi driver posts :ref:`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 :ref:`wifi-event-sta-start` to the application task. We recommend that you call :cpp:func:`esp_wifi_connect()`. However, you can also call :cpp:func:`esp_wifi_connect()` in other phrases after the :ref:`wifi-event-sta-start` arises.
|
||||
|
||||
4. Wi-Fi Connect Phase
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
- s4.1: Once :cpp:func:`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 :ref:`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, :ref:`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 :ref:`ip-event-sta-got-ip` will arise and the event task will perform common handling.
|
||||
- s5.3: In the application event callback, :ref:`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 :ref:`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, :ref:`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 :ref:`wifi-event-sta-disconnected` to the application task. The recommended actions are: 1) call :cpp:func:`esp_wifi_connect()` to reconnect the Wi-Fi, 2) close all sockets, and 3) re-create them if necessary. For details, please refer to :ref:`wifi-event-sta-disconnected`.
|
||||
|
||||
7. Wi-Fi IP Change Phase
|
||||
++++++++++++++++++++++++++++++++++
|
||||
|
||||
- s7.1: If the IP address is changed, the :ref:`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 :cpp:func:`esp_wifi_disconnect()` to disconnect the Wi-Fi connectivity.
|
||||
- s8.2: Call :cpp:func:`esp_wifi_stop()` to stop the Wi-Fi driver.
|
||||
- s8.3: Call :cpp:func:`esp_wifi_deinit()` to unload the Wi-Fi driver.
|
||||
|
||||
|
||||
.. _wifi-scan:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi Scan
|
||||
-----------------------------
|
||||
|
||||
Currently, the :cpp:func:`esp_wifi_scan_start()` API is supported only in station or station/AP mode.
|
||||
|
||||
Scan Type
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 15 50
|
||||
|
||||
* - 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 :cpp:type:`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 :cpp:type:`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 :cpp:type:`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 :cpp:func:`esp_wifi_scan_start()`. The table below provides a detailed description of :cpp:type:`wifi_scan_config_t`.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 15 50
|
||||
|
||||
* - 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 :cpp:func:`esp_wifi_set_config()`, refer to :ref:`Station Basic Configuration <station-basic-configuration>`.
|
||||
|
||||
Scan All APs on All Channels (Foreground)
|
||||
+++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Scenario:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: Foreground Scan of all Wi-Fi Channels
|
||||
:align: center
|
||||
|
||||
seqdiag foreground-scan-all-channels {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 160;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
APP_TASK -> WIFI_TASK [label="1.1 > Configure country code"];
|
||||
APP_TASK -> WIFI_TASK [label="1.2 > Scan configuration"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.1 > Scan channel 1"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.2 > Scan channel 2"];
|
||||
WIFI_TASK -> WIFI_TASK [label="..."];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.x > Scan channel N"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"];
|
||||
APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"];
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
**************************
|
||||
|
||||
- s1.1: Call :cpp:func:`esp_wifi_set_country()` to set the country info if the default country info is not what you want. Refer to :ref:`Wi-Fi Country Code <wifi-country-code>`.
|
||||
- s1.2: Call :cpp:func:`esp_wifi_scan_start()` to configure the scan. To do so, you can refer to `Scan Configuration`_. Since this is an all-channel scan, just set the SSID/BSSID/channel to 0.
|
||||
|
||||
|
||||
Wi-Fi Driver's Internal Scan Phase
|
||||
**************************************
|
||||
|
||||
- s2.1: The Wi-Fi driver switches to channel 1. In this case, the scan type is WIFI_SCAN_TYPE_ACTIVE, and a probe request is broadcasted. Otherwise, the Wi-Fi will wait for a beacon from the APs. The Wi-Fi driver will stay in channel 1 for some time. The dwell time is configured in min/max time, with the default value being 120 ms.
|
||||
- s2.2: The Wi-Fi driver switches to channel 2 and performs the same operation as in step 2.1.
|
||||
- s2.3: The Wi-Fi driver scans the last channel N, where N is determined by the country code which is configured in step 1.1.
|
||||
|
||||
Scan-Done Event Handling Phase
|
||||
*********************************
|
||||
|
||||
- s3.1: When all channels are scanned, :ref:`wifi-event-scan-done` will arise.
|
||||
- s3.2: The application's event callback function notifies the application task that :ref:`wifi-event-scan-done` is received. :cpp:func:`esp_wifi_scan_get_ap_num()` is called to get the number of APs that have been found in this scan. Then, it allocates enough entries and calls :cpp:func:`esp_wifi_scan_get_ap_records()` to get the AP records. Please note that the AP records in the Wi-Fi driver will be freed once :cpp:func:`esp_wifi_scan_get_ap_records()` is called. Do not call :cpp:func:`esp_wifi_scan_get_ap_records()` twice for a single scan-done event. If :cpp:func:`esp_wifi_scan_get_ap_records()` is not called when the scan-done event occurs, the AP records allocated by the Wi-Fi driver will not be freed. So, make sure you call :cpp:func:`esp_wifi_scan_get_ap_records()`, yet only once.
|
||||
|
||||
Scan All APs on All Channels (Background)
|
||||
++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Scenario:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: Background Scan of all Wi-Fi Channels
|
||||
:align: center
|
||||
|
||||
seqdiag background-scan-all-channels {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 160;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
APP_TASK -> WIFI_TASK [label="1.1 > Configure country code"];
|
||||
APP_TASK -> WIFI_TASK [label="1.2 > Scan configuration"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.1 > Scan channel 1"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.2 > Back to home channel H"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.3 > Scan channel 2"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.4 > Back to home channel H"];
|
||||
WIFI_TASK -> WIFI_TASK [label="..."];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.x-1 > Scan channel N"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.x > Back to home channel H"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"];
|
||||
APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"];
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: Scan of specific Wi-Fi Channels
|
||||
:align: center
|
||||
|
||||
seqdiag scan-specific-channels {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 160;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
APP_TASK -> WIFI_TASK [label="1.1 > Configure country code"];
|
||||
APP_TASK -> WIFI_TASK [label="1.2 > Scan configuration"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.1 > Scan channel C1"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.2 > Scan channel C2"];
|
||||
WIFI_TASK -> WIFI_TASK [label="..."];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.x > Scan channel CN, or the AP is found"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"];
|
||||
APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"];
|
||||
}
|
||||
|
||||
This scan is similar to `Scan All APs on All Channels (Foreground)`_. The differences are:
|
||||
|
||||
- s1.1: In step 1.2, the target AP will be configured to SSID/BSSID.
|
||||
- s2.1 ~ s2.N: Each time the Wi-Fi driver scans an AP, it will check whether it is a target AP or not. If the scan is ``WIFI_FAST_SCAN`` scan and the target AP is found, then the scan-done event will arise and scanning will end; otherwise, the scan will continue. Please note that the first scanned channel may not be channel 1, because the Wi-Fi driver optimizes the scanning sequence.
|
||||
|
||||
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 :ref:`Station Basic Configuration <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-wifi-connect:
|
||||
|
||||
Scan in Wi-Fi Connect
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
When :cpp:func:`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, :ref:`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 :cpp:func:`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 :cpp:func:`esp_wifi_scan_start()` at the same time, or the same application task calls :cpp:func:`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 {IDF_TARGET_NAME}'s Wi-Fi functionality improves continuously.
|
||||
|
||||
.. _scan-when-wifi-is-connecting:
|
||||
|
||||
Scan When Wi-Fi Is Connecting
|
||||
+++++++++++++++++++++++++++++++
|
||||
|
||||
The :cpp:func:`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 :ref:`wifi-event-sta-disconnected`.
|
||||
- The application calls :cpp:func:`esp_wifi_connect()` to reconnect on receiving the disconnect event.
|
||||
- Another application task, e.g., the console task, calls :cpp:func:`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 choose to define a maximum continuous reconnection counter and stop reconnecting once the counter reaches the maximum.
|
||||
- The application can choose to reconnect immediately in the first N continuous reconnection, then give a delay sometime and reconnect again.
|
||||
|
||||
The application can define its own reconnection strategy to avoid the scan starve to death. Refer to :ref:`wifi-reconnect`.
|
||||
|
||||
.. _wifi-station-connecting-scenario:
|
||||
|
||||
{IDF_TARGET_NAME} 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 :ref:`wifi-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:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: Wi-Fi Station Connecting Process
|
||||
:align: center
|
||||
|
||||
seqdiag station-connecting-process {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 160;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
AP [label = "AP"];
|
||||
|
||||
=== 1. Scan Phase ===
|
||||
WIFI_TASK -> WIFI_TASK [label="1.1 > Scan"];
|
||||
EVENT_TASK <- WIFI_TASK [label="1.2 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
=== 2. Auth Phase ===
|
||||
WIFI_TASK -> AP [label="2.1 > Auth request"];
|
||||
EVENT_TASK <- WIFI_TASK [label="2.2 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
WIFI_TASK <- AP [label="2.3 > Auth response"];
|
||||
EVENT_TASK <- WIFI_TASK [label="2.4 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
=== 3. Assoc Phase ===
|
||||
WIFI_TASK -> AP [label="3.1 > Assoc request"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.2 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
WIFI_TASK <- AP [label="3.3 > Assoc response"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.4 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
=== 4. 4-way Handshake Phase ===
|
||||
EVENT_TASK <- WIFI_TASK [label="4.1 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
WIFI_TASK <- AP [label="4.2 > 1/4 EAPOL"];
|
||||
WIFI_TASK -> AP [label="4.3 > 2/4 EAPOL"];
|
||||
EVENT_TASK <- WIFI_TASK [label="4.4 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
WIFI_TASK <- AP [label="4.5 > 3/4 EAPOL"];
|
||||
WIFI_TASK -> AP [label="4.6 > 4/4 EAPOL"];
|
||||
EVENT_TASK <- WIFI_TASK [label="4.7 > WIFI_EVENT_STA_CONNECTED"];
|
||||
}
|
||||
|
||||
|
||||
Scan Phase
|
||||
+++++++++++++++++++++
|
||||
|
||||
- s1.1: The Wi-Fi driver begins scanning in "Wi-Fi Connect". Refer to :ref:`scan-in-wifi-connect` for more details.
|
||||
- s1.2: If the scan fails to find the target AP, :ref:`wifi-event-sta-disconnected` will arise and the reason code could either be ``WIFI_REASON_NO_AP_FOUND`` or ``WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY`` or ``WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD`` or ``WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD`` depending of the Station's configuration. Refer to `Wi-Fi Reason Code`_.
|
||||
|
||||
Auth Phase
|
||||
+++++++++++++++++++++
|
||||
|
||||
- s2.1: The authentication request packet is sent and the auth timer is enabled.
|
||||
- s2.2: If the authentication response packet is not received before the authentication timer times out, :ref:`wifi-event-sta-disconnected` will arise and the reason code will be ``WIFI_REASON_AUTH_EXPIRE``. Refer to `Wi-Fi Reason Code`_.
|
||||
- s2.3: The auth-response packet is received and the auth-timer is stopped.
|
||||
- s2.4: The AP rejects authentication in the response and :ref:`wifi-event-sta-disconnected` arises, while the reason code is ``WIFI_REASON_AUTH_FAIL`` or the reasons specified by the AP. Refer to `Wi-Fi Reason Code`_.
|
||||
|
||||
Association Phase
|
||||
+++++++++++++++++++++
|
||||
|
||||
- s3.1: The association request is sent and the association timer is enabled.
|
||||
- s3.2: If the association response is not received before the association timer times out, :ref:`wifi-event-sta-disconnected` will arise and the reason code will be ``WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY``. Refer to `Wi-Fi Reason Code`_.
|
||||
- s3.3: The association response is received and the association timer is stopped.
|
||||
- s3.4: The AP rejects the association in the response and :ref:`wifi-event-sta-disconnected` arises, while the reason code is the one specified in the association response. Refer to `Wi-Fi Reason Code`_.
|
||||
|
||||
|
||||
Four-way Handshake Phase
|
||||
++++++++++++++++++++++++++
|
||||
|
||||
- s4.1: The handshake timer is enabled, and the 1/4 EAPOL is not received before the handshake timer expires. :ref:`wifi-event-sta-disconnected` will arise and the reason code will be ``WIFI_REASON_HANDSHAKE_TIMEOUT``. Refer to `Wi-Fi Reason Code`_.
|
||||
- s4.2: The 1/4 EAPOL is received.
|
||||
- s4.3: The station replies 2/4 EAPOL.
|
||||
- s4.4: If the 3/4 EAPOL is not received before the handshake timer expires, :ref:`wifi-event-sta-disconnected` will arise and the reason code will be ``WIFI_REASON_HANDSHAKE_TIMEOUT``. Refer to `Wi-Fi Reason Code`_.
|
||||
- s4.5: The 3/4 EAPOL is received.
|
||||
- s4.6: The station replies 4/4 EAPOL.
|
||||
- s4.7: The station raises :ref:`wifi-event-sta-connected`.
|
||||
|
||||
|
||||
.. _esp_wifi_reason_code:
|
||||
|
||||
Wi-Fi Reason Code
|
||||
+++++++++++++++++++++
|
||||
|
||||
The table below shows the reason-code defined in {IDF_TARGET_NAME}. The first column is the macro name defined in :component_file:`esp_wifi/include/esp_wifi_types.h`. The common prefix ``WIFI_REASON`` is removed, which means that ``UNSPECIFIED`` actually stands for ``WIFI_REASON_UNSPECIFIED`` and so on. The second column is the value of the reason. This reason value is same as defined in section 9.4.1.7 of IEEE 802.11-2020. (For more information, refer to the standard mentioned above.) The last column describes the reason. Reason-codes starting from 200 are Espressif defined reason-codes and are not part of IEEE 802.11-2020.\
|
||||
|
||||
Also note that REASON_NO_AP_FOUND_XXX codes are mentioned in increasing order of importance. So if a single AP has a combination of the above reasons for failure, the more important one will be reported. Additionally, if there are multiple APs that satisfy the identifying criteria and connecting to all of them fails for different reasons mentioned above, then the reason code reported is for the AP that failed connection due to the least important reason code, as it was the one closest to a successful connection.\
|
||||
|
||||
Following reason codes are renamed to their shorter form to wrap the table in page width.
|
||||
|
||||
- TRANSMISSION_LINK_ESTABLISHMENT_FAILED : TX_LINK_EST_FAILED
|
||||
- NO_AP_FOUND_W_COMPATIBLE_SECURITY : NO_AP_FOUND_SECURITY
|
||||
- NO_AP_FOUND_IN_AUTHMODE_THRESHOLD : NO_AP_FOUND_AUTHMODE
|
||||
- NO_AP_FOUND_IN_RSSI_THRESHOLD : NO_AP_FOUND_RSSI
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 41 10 49
|
||||
:class: longtable
|
||||
|
||||
* - Reason code
|
||||
- Value
|
||||
- Description
|
||||
* - UNSPECIFIED
|
||||
- 1
|
||||
- Generally, it means an internal failure, e.g., the memory runs out, the internal TX fails, or the reason is received from the remote side.
|
||||
* - AUTH_EXPIRE
|
||||
- 2
|
||||
- The previous authentication is no longer valid.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- auth is timed out.
|
||||
- the reason is received from the AP.
|
||||
|
||||
For the ESP AP, this reason is reported when:
|
||||
|
||||
- the AP has not received any packets from the station in the past five minutes.
|
||||
- the AP is stopped by calling :cpp:func:`esp_wifi_stop()`.
|
||||
- the station is de-authed by calling :cpp:func:`esp_wifi_deauth_sta()`.
|
||||
* - AUTH_LEAVE
|
||||
- 3
|
||||
- De-authenticated, because the sending station is leaving (or has left).
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - DISASSOC_DUE_TO_INACTIVITY
|
||||
- 4
|
||||
- Disassociated due to inactivity.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- assoc is timed out.
|
||||
- it is received from the AP.
|
||||
|
||||
* - ASSOC_TOOMANY
|
||||
- 5
|
||||
- Disassociated, because the AP is unable to handle all currently associated STAs at the same time.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
|
||||
For the ESP AP, this reason is reported when:
|
||||
|
||||
- the stations associated with the AP reach the maximum number that the AP can support.
|
||||
* - CLASS2_FRAME_FROM_NONAUTH_STA
|
||||
- 6
|
||||
- Class-2 frame received from a non-authenticated STA.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
|
||||
For the ESP AP, this reason is reported when:
|
||||
|
||||
- the AP receives a packet with data from a non-authenticated station.
|
||||
* - CLASS3_FRAME_FROM_NONASSOC_STA
|
||||
- 7
|
||||
- Class-3 frame received from a non-associated STA.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
|
||||
For the ESP AP, this reason is reported when:
|
||||
|
||||
- the AP receives a packet with data from a non-associated station.
|
||||
* - ASSOC_LEAVE
|
||||
- 8
|
||||
- Disassociated, because the sending station is leaving (or has left) BSS.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
- the station is disconnected by :cpp:func:`esp_wifi_disconnect()` and other APIs.
|
||||
* - ASSOC_NOT_AUTHED
|
||||
- 9
|
||||
- station requesting (re)association is not authenticated by the responding STA.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
|
||||
For the ESP AP, this reason is reported when:
|
||||
|
||||
- the AP receives packets with data from an associated, yet not authenticated, station.
|
||||
* - DISASSOC_PWRCAP_BAD
|
||||
- 10
|
||||
- Disassociated, because the information in the Power Capability element is unacceptable.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - DISASSOC_SUPCHAN_BAD
|
||||
- 11
|
||||
- Disassociated, because the information in the Supported Channels element is unacceptable.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - BSS_TRANSITION_DISASSOC
|
||||
- 12
|
||||
- AP wants us to move to another AP, sent as a part of BTM procedure. Please note that when station is sending BTM request and moving to another AP, ROAMING reason code will be reported instead of this.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - IE_INVALID
|
||||
- 13
|
||||
- Invalid element, i.e., an element whose content does not meet the specifications of the Standard in frame formats clause.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
|
||||
For the ESP AP, this reason is reported when:
|
||||
|
||||
- the AP parses a wrong WPA or RSN IE.
|
||||
* - MIC_FAILURE
|
||||
- 14
|
||||
- Message integrity code (MIC) failure.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - 4WAY_HANDSHAKE_TIMEOUT
|
||||
- 15
|
||||
- Four-way handshake times out. For legacy reasons, in ESP this reason code is replaced with ``WIFI_REASON_HANDSHAKE_TIMEOUT``.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- the handshake times out.
|
||||
- it is received from the AP.
|
||||
* - GROUP_KEY_UPDATE_TIMEOUT
|
||||
- 16
|
||||
- Group-Key Handshake times out.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - IE_IN_4WAY_DIFFERS
|
||||
- 17
|
||||
- The element in the four-way handshake is different from the (Re-)Association Request/Probe and Response/Beacon frame.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
- the station finds that the four-way handshake IE differs from the IE in the (Re-)Association Request/Probe and Response/Beacon frame.
|
||||
* - GROUP_CIPHER_INVALID
|
||||
- 18
|
||||
- Invalid group cipher.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - PAIRWISE_CIPHER_INVALID
|
||||
- 19
|
||||
- Invalid pairwise cipher.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - AKMP_INVALID
|
||||
- 20
|
||||
- Invalid AKMP.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
- it is received from the AP.
|
||||
* - UNSUPP_RSN_IE_VERSION
|
||||
- 21
|
||||
- Unsupported RSNE version.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - INVALID_RSN_IE_CAP
|
||||
- 22
|
||||
- Invalid RSNE capabilities.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - 802_1X_AUTH_FAILED
|
||||
- 23
|
||||
- IEEE 802.1X. authentication failed.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
|
||||
For the ESP AP, this reason is reported when:
|
||||
|
||||
- IEEE 802.1X. authentication fails.
|
||||
* - CIPHER_SUITE_REJECTED
|
||||
- 24
|
||||
- Cipher suite rejected due to security policies.
|
||||
|
||||
For the ESP station, this reason is reported when:
|
||||
|
||||
- it is received from the AP.
|
||||
* - TDLS_PEER_UNREACHABLE
|
||||
- 25
|
||||
- TDLS direct-link teardown due to TDLS peer STA unreachable via the TDLS direct link.
|
||||
* - TDLS_UNSPECIFIED
|
||||
- 26
|
||||
- TDLS direct-link teardown for unspecified reason.
|
||||
* - SSP_REQUESTED_DISASSOC
|
||||
- 27
|
||||
- Disassociated because session terminated by SSP request.
|
||||
* - NO_SSP_ROAMING_AGREEMENT
|
||||
- 28
|
||||
- Disassociated because of lack of SSP roaming agreement.
|
||||
* - BAD_CIPHER_OR_AKM
|
||||
- 29
|
||||
- Requested service rejected because of SSP cipher suite or AKM requirement.
|
||||
* - NOT_AUTHORIZED_THIS_LOCATION
|
||||
- 30
|
||||
- Requested service not authorized in this location.
|
||||
* - SERVICE_CHANGE_PRECLUDES_TS
|
||||
- 31
|
||||
- TS deleted because QoS AP lacks sufficient bandwidth for this QoS STA due to a change in BSS service characteristics or operational mode (e.g., an HT BSS change from 40 MHz channel to 20 MHz channel).
|
||||
* - UNSPECIFIED_QOS
|
||||
- 32
|
||||
- Disassociated for unspecified, QoS-related reason.
|
||||
* - NOT_ENOUGH_BANDWIDTH
|
||||
- 33
|
||||
- Disassociated because QoS AP lacks sufficient bandwidth for this QoS STA.
|
||||
* - MISSING_ACKS
|
||||
- 34
|
||||
- Disassociated because excessive number of frames need to be acknowledged, but are not acknowledged due to AP transmissions and/or poor channel conditions.
|
||||
* - EXCEEDED_TXOP
|
||||
- 35
|
||||
- Disassociated because STA is transmitting outside the limits of its TXOPs.
|
||||
* - STA_LEAVING
|
||||
- 36
|
||||
- Requesting STA is leaving the BSS (or resetting).
|
||||
* - END_BA
|
||||
- 37
|
||||
- Requesting STA is no longer using the stream or session.
|
||||
* - UNKNOWN_BA
|
||||
- 38
|
||||
- Requesting STA received frames using a mechanism for which a setup has not been completed.
|
||||
* - TIMEOUT
|
||||
- 39
|
||||
- Requested from peer STA due to timeout
|
||||
* - Reserved
|
||||
- 40 ~ 45
|
||||
- Reserved as per IEEE80211-2020 specifications.
|
||||
* - PEER_INITIATED
|
||||
- 46
|
||||
- In a Disassociation frame: Disassociated because authorized access limit reached.
|
||||
* - AP_INITIATED
|
||||
- 47
|
||||
- In a Disassociation frame: Disassociated due to external service requirements.
|
||||
* - INVALID_FT_ACTION_FRAME_COUNT
|
||||
- 48
|
||||
- Invalid FT Action frame count.
|
||||
* - INVALID_PMKID
|
||||
- 49
|
||||
- Invalid pairwise master key identifier (PMKID).
|
||||
* - INVALID_MDE
|
||||
- 50
|
||||
- Invalid MDE.
|
||||
* - INVALID_FTE
|
||||
- 51
|
||||
- Invalid FTE
|
||||
* - TX_LINK_EST_FAILED
|
||||
- 67
|
||||
- TRANSMISSION_LINK_ESTABLISHMENT_FAILED will be reported when Transmission link establishment in alternative channel failed.
|
||||
* - ALTERATIVE_CHANNEL_OCCUPIED
|
||||
- 68
|
||||
- The alternative channel is occupied.
|
||||
* - BEACON_TIMEOUT
|
||||
- 200
|
||||
- Espressif-specific Wi-Fi reason code: when the station loses N beacons continuously, it will disrupt the connection and report this reason.
|
||||
* - NO_AP_FOUND
|
||||
- 201
|
||||
- Espressif-specific Wi-Fi reason code: when the station fails to scan the target AP, this reason code will be reported. In case of security mismatch or station's configuration mismatch, new reason codes NO_AP_FOUND_XXX will be reported.
|
||||
* - AUTH_FAIL
|
||||
- 202
|
||||
- Espressif-specific Wi-Fi reason code: the authentication fails, but not because of a timeout.
|
||||
* - ASSOC_FAIL
|
||||
- 203
|
||||
- Espressif-specific Wi-Fi reason code: the association fails, but not because of DISASSOC_DUE_TO_INACTIVITY or ASSOC_TOOMANY.
|
||||
* - HANDSHAKE_TIMEOUT
|
||||
- 204
|
||||
- Espressif-specific Wi-Fi reason code: the handshake fails for the same reason as that in WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT.
|
||||
* - CONNECTION_FAIL
|
||||
- 205
|
||||
- Espressif-specific Wi-Fi reason code: the connection to the AP has failed.
|
||||
* - AP_TSF_RESET
|
||||
- 206
|
||||
- Espressif-specific Wi-Fi reason code: the disconnection happened due to AP's TSF reset.
|
||||
* - ROAMING
|
||||
- 207
|
||||
- Espressif-specific Wi-Fi reason code: the station is roaming to another AP, this reason code is just for info, station will automatically move to another AP.
|
||||
* - ASSOC_COMEBACK_TIME_TOO_LONG
|
||||
- 208
|
||||
- Espressif-specific Wi-Fi reason code: This reason code will be reported when Assoc comeback time in association response is too high.
|
||||
* - SA_QUERY_TIMEOUT
|
||||
- 209
|
||||
- Espressif-specific Wi-Fi reason code: This reason code will be reported when AP did not reply of SA query sent by ESP station.
|
||||
* - NO_AP_FOUND_SECURITY
|
||||
- 210
|
||||
- Espressif-specific Wi-Fi reason code: NO_AP_FOUND_W_COMPATIBLE_SECURITY will be reported if an AP that fits identifying criteria (e.g. ssid) is found but the connection is rejected due to incompatible security configuration. These situations could be:
|
||||
|
||||
- The Access Point is offering WEP security, but our station's password is not WEP-compliant.
|
||||
- The station is configured in Open mode; however, the Access Point is broadcasting in secure mode.
|
||||
- The Access Point uses Enterprise security, but we haven't set up the corresponding enterprise configuration, and vice versa.
|
||||
- SAE-PK is configured in the station configuration, but the Access Point does not support SAE-PK.
|
||||
- SAE-H2E is configured in the station configuration; however, the AP only supports WPA3-PSK or WPA3-WPA2-PSK.
|
||||
- The station is configured in secure mode (Password or Enterprise mode); however, an Open AP is found during the scan.
|
||||
- SAE HnP is configured in the station configuration; however, the AP supports H2E only.
|
||||
- H2E is disabled in the station configuration; however, the AP is WPA3-EXT-PSK, which requires H2E support.
|
||||
- The Access Point requires PMF, but the station is not configured for PMF capable/required.
|
||||
- The station configuration requires PMF, but the AP is not configured for PMF capable/required.
|
||||
- The Access Point is using unsupported group management/pairwise ciphers.
|
||||
- OWE is not enabled in the station configuration, but the discovered AP is using OWE only mode.
|
||||
- The Access Point is broadcasting an invalid RSNXE in its beacons.
|
||||
- The Access Point is in Independent BSS mode.
|
||||
|
||||
* - NO_AP_FOUND_AUTHMODE
|
||||
- 211
|
||||
- Espressif-specific Wi-Fi reason code: NO_AP_FOUND_IN_AUTHMODE_THRESHOLD will be reported if an AP that fit identifying criteria (e.g. ssid) is found but the authmode threhsold set in the wifi_config_t is not met.
|
||||
* - NO_AP_FOUND_RSSI
|
||||
- 212
|
||||
- Espressif-specific Wi-Fi reason code: NO_AP_FOUND_IN_RSSI_THRESHOLD will be reported if an AP that fits identifying criteria (e.g. ssid) is found but the RSSI threhsold set in the wifi_config_t is not met.
|
||||
|
||||
Wi-Fi Reason code related to wrong password
|
||||
++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
The table below shows the Wi-Fi reason-code may related to wrong password.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 10 40
|
||||
|
||||
* - Reason code
|
||||
- Value
|
||||
- Description
|
||||
* - 4WAY_HANDSHAKE_TIMEOUT
|
||||
- 15
|
||||
- Four-way handshake times out. Setting wrong password when STA connecting to an encrypted AP.
|
||||
* - NO_AP_FOUND
|
||||
- 201
|
||||
- This may related to wrong password in the two scenarios:
|
||||
|
||||
- Setting password when STA connecting to an unencrypted AP.
|
||||
- Does not set password when STA connecting to an encrypted AP.
|
||||
* - HANDSHAKE_TIMEOUT
|
||||
- 204
|
||||
- Four-way handshake fails.
|
||||
|
||||
Wi-Fi Reason code related to low RSSI
|
||||
++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
The table below shows the Wi-Fi reason-code may related to low RSSI.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 10 40
|
||||
|
||||
* - Reason code
|
||||
- Value
|
||||
- Description
|
||||
* - NO_AP_FOUND_IN_RSSI_THRESHOLD
|
||||
- 212
|
||||
- The station fails to scan the target AP due to low RSSI
|
||||
* - HANDSHAKE_TIMEOUT
|
||||
- 204
|
||||
- Four-way handshake fails.
|
||||
|
||||
.. _wifi-station-connecting-when-multiple-aps-are-found:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi Station Connecting When Multiple APs Are Found
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This scenario is similar as :ref:`wifi-station-connecting-scenario`. The difference is that the station will not raise the event :ref:`wifi-event-sta-disconnected` unless it fails to connect all of the found APs.
|
||||
|
||||
.. _wifi-reconnect:
|
||||
|
||||
Wi-Fi Reconnect
|
||||
-----------------
|
||||
|
||||
The station may disconnect due to many reasons, e.g., the connected AP is restarted. It is the application's responsibility to reconnect. The recommended reconnection strategy is to call :cpp:func:`esp_wifi_connect()` on receiving event :ref:`wifi-event-sta-disconnected`.
|
||||
|
||||
Sometimes the application needs more complex reconnection strategy:
|
||||
|
||||
- If the disconnect event is raised because the :cpp:func:`esp_wifi_disconnect()` is called, the application may not want to do the reconnection.
|
||||
- If the :cpp:func:`esp_wifi_scan_start()` may be called at anytime, a better reconnection strategy is necessary. Refer to :ref:`scan-when-wifi-is-connecting`.
|
||||
|
||||
Another thing that need to be considered is that the reconnection may not connect the same AP if there are more than one APs with the same SSID. The reconnection always select current best APs to connect.
|
||||
|
||||
Wi-Fi Beacon Timeout
|
||||
---------------------------
|
||||
|
||||
The beacon timeout mechanism is used by {IDF_TARGET_NAME} station to detect whether the AP is alive or not. If the station does not receive the beacon of the connected AP within the inactive time, the beacon timeout happens. The application can set inactive time via API :cpp:func:`esp_wifi_set_inactive_time()`.
|
||||
|
||||
After the beacon times out, the station sends 5 probe requests to the AP. If still no probe response or beacon is received from AP, the station disconnects from the AP and raises the event :ref:`wifi-event-sta-disconnected`.
|
||||
|
||||
It should be considered that the timer used for beacon timeout will be reset during the scanning process. It means that the scan process will affect the triggering of the event :ref:`wifi-event-sta-beacon-timeout`.
|
||||
@@ -0,0 +1,94 @@
|
||||
Wi-Fi MAC Protocols
|
||||
==========================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
Wi-Fi HT20/40
|
||||
--------------
|
||||
|
||||
.. only:: esp32 or esp32s2 or esp32c3 or esp32s3 or esp32c5 or esp32c6
|
||||
|
||||
{IDF_TARGET_NAME} supports Wi-Fi bandwidth HT20 or HT40 and does not support HT20/40 coexist. :cpp:func:`esp_wifi_set_bandwidth()` can be used to change the default bandwidth of station or AP. The default bandwidth for {IDF_TARGET_NAME} station and AP is HT40.
|
||||
|
||||
In station mode, the actual bandwidth is firstly negotiated during the Wi-Fi connection. It is HT40 only if both the station and the connected AP support HT40, otherwise it is HT20. If the bandwidth of connected AP is changes, the actual bandwidth is negotiated again without Wi-Fi disconnecting.
|
||||
|
||||
Similarly, in AP mode, the actual bandwidth is negotiated between AP and the stations that connect to the AP. It is HT40 if the AP and one of the stations support HT40, otherwise it is HT20.
|
||||
|
||||
In station/AP coexist mode, the station/AP can configure HT20/40 separately. If both station and AP are negotiated to HT40, the HT40 channel should be the channel of station because the station always has higher priority than AP in {IDF_TARGET_NAME}. For example, the configured bandwidth of AP is HT40, the configured primary channel is 6, and the configured secondary channel is 10. The station is connected to an router whose primary channel is 6 and secondary channel is 2, then the actual channel of AP is changed to primary 6 and secondary 2 automatically.
|
||||
|
||||
Theoretically, the HT40 can gain better throughput because the maximum raw physical (PHY) data rate for HT40 is 150 Mbps while it is 72 Mbps for HT20. However, if the device is used in some special environment, e.g., there are too many other Wi-Fi devices around the {IDF_TARGET_NAME} device, the performance of HT40 may be degraded. So if the applications need to support same or similar scenarios, it is recommended that the bandwidth is always configured to HT20.
|
||||
|
||||
.. only:: esp32c5
|
||||
|
||||
.. note::
|
||||
|
||||
When operating in the 2.4 GHz + 5 GHz band mode (``WIFI_BAND_MODE_AUTO``), can use the function :cpp:func:`esp_wifi_set_bandwidths()` to configure the bandwidth for the 2.4 GHz and 5 GHz bands separately.
|
||||
|
||||
|
||||
.. only:: esp32c2
|
||||
|
||||
{IDF_TARGET_NAME} supports Wi-Fi bandwidth HT20 and does not support Wi-Fi bandwidth HT40 or HT20/40 coexist.
|
||||
|
||||
Wi-Fi QoS
|
||||
-------------------------
|
||||
|
||||
{IDF_TARGET_NAME} supports all the mandatory features required in WFA Wi-Fi QoS Certification.
|
||||
|
||||
Four ACs (Access Category) are defined in Wi-Fi specification, and each AC has its own priority to access the Wi-Fi channel. Moreover, a map rule is defined to map the QoS priority of other protocol, e.g., 802.11D or TCP/IP precedence is mapped to Wi-Fi AC.
|
||||
|
||||
The table below describes how the IP Precedences are mapped to Wi-Fi ACs in {IDF_TARGET_NAME}. It also indicates whether the AMPDU is supported for this AC. The table is sorted from high to low priority. That is to say, the AC_VO has the highest priority.
|
||||
|
||||
+------------------+------------------------+-----------------+
|
||||
| IP Precedence | Wi-Fi AC | Support AMPDU? |
|
||||
+==================+========================+=================+
|
||||
| 6, 7 | AC_VO (Voice) | No |
|
||||
+------------------+------------------------+-----------------+
|
||||
| 4, 5 | AC_VI (Video) | Yes |
|
||||
+------------------+------------------------+-----------------+
|
||||
| 3, 0 | AC_BE (Best Effort) | Yes |
|
||||
+------------------+------------------------+-----------------+
|
||||
| 1, 2 | AC_BK (Background) | Yes |
|
||||
+------------------+------------------------+-----------------+
|
||||
|
||||
The application can make use of the QoS feature by configuring the IP precedence via socket option IP_TOS. Here is an example to make the socket to use VI queue::
|
||||
|
||||
const int ip_precedence_vi = 4;
|
||||
const int ip_precedence_offset = 5;
|
||||
int priority = (ip_precedence_vi << ip_precedence_offset);
|
||||
setsockopt(socket_id, IPPROTO_IP, IP_TOS, &priority, sizeof(priority));
|
||||
|
||||
Theoretically, the higher priority AC has better performance than the lower priority AC. However, it is not always true. Here are some suggestions about how to use the Wi-Fi QoS:
|
||||
|
||||
- Some really important application traffic can be put into the AC_VO queue. But avoid using the AC_VO queue for heavy traffic, as it may impact the management frames which also use this queue. Eventually, it is worth noting that the AC_VO queue does not support AMPDU, and its performance with heavy traffic is no better than other queues.
|
||||
- Avoid using more than two precedences supported by different AMPDUs, e.g., when socket A uses precedence 0, socket B uses precedence 1, and socket C uses precedence 2. This can be a bad design because it may need much more memory. To be specific, the Wi-Fi driver may generate a Block Ack session for each precedence and it needs more memory if the Block Ack session is set up.
|
||||
|
||||
|
||||
Wi-Fi Aggregate MAC Protocol Data Unit (AMPDU)
|
||||
----------------------------------------------------
|
||||
|
||||
{IDF_TARGET_NAME} supports both receiving and transmitting AMPDU, and the AMPDU can greatly improve the Wi-Fi throughput.
|
||||
|
||||
Generally, the AMPDU should be enabled. Disabling AMPDU is usually for debugging purposes.
|
||||
|
||||
|
||||
Wi-Fi AMSDU
|
||||
-------------------------
|
||||
|
||||
.. only:: not SOC_SPIRAM_SUPPORTED
|
||||
|
||||
{IDF_TARGET_NAME} supports receiving AMSDU.
|
||||
|
||||
.. only:: SOC_SPIRAM_SUPPORTED
|
||||
|
||||
{IDF_TARGET_NAME} supports receiving and transmitting AMSDU. AMSDU TX is disabled by default, since enable AMSDU TX need more memory. Select :ref:`CONFIG_ESP_WIFI_AMSDU_TX_ENABLED` to enable AMSDU Tx feature, it depends on :ref:`CONFIG_SPIRAM`.
|
||||
|
||||
Wi-Fi Fragment
|
||||
-------------------------
|
||||
|
||||
.. only:: not SOC_WIFI_TXOP_SUPPORT
|
||||
|
||||
{IDF_TARGET_NAME} supports Wi-Fi receiving fragment, but does not support Wi-Fi transmitting fragment.
|
||||
|
||||
.. only:: SOC_WIFI_TXOP_SUPPORT
|
||||
|
||||
{IDF_TARGET_NAME} supports Wi-Fi receiving and transmitting fragment.
|
||||
@@ -0,0 +1,100 @@
|
||||
Wi-Fi Modes
|
||||
===================================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
.. _wifi-ap-general-scenario:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi AP General Scenario
|
||||
---------------------------------------------
|
||||
|
||||
Below is a "big scenario" which describes some small scenarios in AP mode:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: Sample Wi-Fi Event Scenarios in AP Mode
|
||||
:align: center
|
||||
|
||||
seqdiag sample-scenarios-soft-ap-mode {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 140;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
MAIN_TASK [label = "Main\ntask"];
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
LwIP_TASK [label = "LwIP\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
=== 1. Init Phase ===
|
||||
MAIN_TASK -> LwIP_TASK [label="1.1> Create / init LwIP"];
|
||||
MAIN_TASK -> EVENT_TASK [label="1.2> Create / init event"];
|
||||
MAIN_TASK -> WIFI_TASK [label="1.3> Create / init Wi-Fi"];
|
||||
MAIN_TASK -> APP_TASK [label="1.4> Create app task"];
|
||||
=== 2. Configure Phase ===
|
||||
MAIN_TASK -> WIFI_TASK [label="2> Configure Wi-Fi"];
|
||||
=== 3. Start Phase ===
|
||||
MAIN_TASK -> WIFI_TASK [label="3.1> Start Wi-Fi"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.2> WIFI_EVENT_AP_START"];
|
||||
APP_TASK <- EVENT_TASK [label="3.3> WIFI_EVENT_AP_START"];
|
||||
=== 4. Connect Phase ===
|
||||
EVENT_TASK <- WIFI_TASK [label="4.1> WIFI_EVENT_AP_STACONNECTED"];
|
||||
APP_TASK <- EVENT_TASK [label="4.2> WIFI_EVENT_AP_STACONNECTED"];
|
||||
=== 5. Disconnect Phase ===
|
||||
EVENT_TASK <- WIFI_TASK [label="5.1> WIFI_EVENT_AP_STADISCONNECTED"];
|
||||
APP_TASK <- EVENT_TASK [label="5.2> WIFI_EVENT_AP_STADISCONNECTED"];
|
||||
APP_TASK -> APP_TASK [label="5.3> disconnect handling"];
|
||||
=== 6. Deinit Phase ===
|
||||
APP_TASK -> WIFI_TASK [label="6.1> Disconnect Wi-Fi"];
|
||||
APP_TASK -> WIFI_TASK [label="6.2> Stop Wi-Fi"];
|
||||
APP_TASK -> WIFI_TASK [label="6.3> Deinit Wi-Fi"];
|
||||
}
|
||||
|
||||
|
||||
Wi-Fi Sniffer Mode
|
||||
---------------------------
|
||||
|
||||
The Wi-Fi sniffer mode can be enabled by :cpp:func:`esp_wifi_set_promiscuous`. If the sniffer mode is enabled, the following packets **can** be dumped to the application:
|
||||
|
||||
- 802.11 Management frame.
|
||||
- 802.11 Data frame, including MPDU, AMPDU, and AMSDU.
|
||||
- 802.11 MIMO frame, for MIMO frame, the sniffer only dumps the length of the frame.
|
||||
- 802.11 Control frame.
|
||||
- 802.11 CRC error frame.
|
||||
|
||||
The following packets will **NOT** be dumped to the application:
|
||||
|
||||
- Other 802.11 error frames.
|
||||
|
||||
For frames that the sniffer **can** dump, the application can additionally decide which specific type of packets can be filtered to the application by using :cpp:func:`esp_wifi_set_promiscuous_filter()` and :cpp:func:`esp_wifi_set_promiscuous_ctrl_filter()`. By default, it will filter all 802.11 data and management frames to the application. If you want to filter the 802.11 control frames, the filter parameter in :cpp:func:`esp_wifi_set_promiscuous_filter()` should include `WIFI_PROMIS_FILTER_MASK_CTRL` type, and if you want to differentiate control frames further, then call :cpp:func:`esp_wifi_set_promiscuous_ctrl_filter()`.
|
||||
|
||||
The Wi-Fi sniffer mode can be enabled in the Wi-Fi mode of :cpp:enumerator:`WIFI_MODE_NULL`, :cpp:enumerator:`WIFI_MODE_STA`, :cpp:enumerator:`WIFI_MODE_AP`, or :cpp:enumerator:`WIFI_MODE_APSTA`. In other words, the sniffer mode is active when the station is connected to the AP, or when the AP has a Wi-Fi connection. Please note that the sniffer has a **great impact** on the throughput of the station or AP Wi-Fi connection. Generally, the sniffer should be enabled **only if** the station/AP Wi-Fi connection does not experience heavy traffic.
|
||||
|
||||
Another noteworthy issue about the sniffer is the callback :cpp:type:`wifi_promiscuous_cb_t`. The callback will be called directly in the Wi-Fi driver task, so if the application has a lot of work to do for each filtered packet, the recommendation is to post an event to the application task in the callback and defer the real work to the application task.
|
||||
|
||||
|
||||
.. only:: SOC_WIFI_NAN_SUPPORT
|
||||
|
||||
Wi-Fi Aware\ :sup:`TM` (NAN)
|
||||
----------------------------
|
||||
|
||||
Wi-Fi Aware\ :sup:`TM` or NAN (Neighbor Awareness Networking) is a protocol that allows Wi-Fi devices to discover services in their proximity. NAN uses direct device-to-device communication and does not require any Internet or AP connection.
|
||||
|
||||
Multiple NAN devices in the vicinity will form a NAN cluster which allows them to communicate with each other. NAN devices in a cluster synchronise their clocks and listen to each other periodically on Channel 6. Devices can advertise (Publish) or seek for (Subscribe) services within their NAN Cluster using Service Discovery protocols. Matching of services is done by service name and optionally matching filters. Once a Subscriber gets a match with a Publisher, it can either send a message (Follow-up) or establish a datapath (NDP) with the Publisher. After NDP is setup both devices will obtain an IPv6 address and can use it for communication.
|
||||
|
||||
Please note that NAN Datapath security is not supported i.e., the data packets will go out unencrypted. NAN uses a separate interface for Discovery and Datapath, which is other than that used for STA and AP. NAN operates in standalone mode, which means co-existence with STA or AP interface is not supported.
|
||||
|
||||
Refer to ESP-IDF examples :idf_file:`examples/wifi/wifi_aware/nan_publisher/README.md` and :idf_file:`examples/wifi/wifi_aware/nan_subscriber/README.md` to setup a NAN Publisher and Subscriber.
|
||||
|
||||
|
||||
Unsynchronized Service Discovery (USD)
|
||||
--------------------------------------------
|
||||
|
||||
Unsynchronized Service Discovery (USD) is a mechanism for devices to discover the services that have been made discoverable on new devices that enter the RF environment, without requiring synchronization between the devices.
|
||||
|
||||
USD uses Service Info field in the SDEA of a Publish and Follow-up message to convey the service specific information.
|
||||
|
||||
Refer to ESP-IDF examples :idf_file:`examples/wifi/wifi_aware/usd_publisher/README.md` and :idf_file:`examples/wifi/wifi_aware/usd_subscriber/README.md` to setup a NAN-USD Publisher and Subscriber.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,236 @@
|
||||
Wi-Fi Vendor Features
|
||||
===================================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
.. only:: SOC_WIFI_MESH_SUPPORT
|
||||
|
||||
ESP-WIFI-MESH
|
||||
-------------------------
|
||||
|
||||
For details, see the :doc:`ESP-WIFI-MESH <../esp-wifi-mesh>`.
|
||||
|
||||
|
||||
Wi-Fi 80211 Packet Send
|
||||
---------------------------
|
||||
|
||||
The :cpp:func:`esp_wifi_80211_tx()` API can be used to:
|
||||
|
||||
- Send the beacon, probe request, probe response, and action frame.
|
||||
- Send the non-QoS data frame.
|
||||
|
||||
It cannot be used for sending encrypted or QoS frames.
|
||||
|
||||
Preconditions of Using :cpp:func:`esp_wifi_80211_tx()`
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
- The Wi-Fi mode is station, or AP, or station/AP.
|
||||
- Either ``esp_wifi_set_promiscuous(true)``, or :cpp:func:`esp_wifi_start()`, or both of these APIs return :c:macro:`ESP_OK`. This is because Wi-Fi hardware must be initialized before :cpp:func:`esp_wifi_80211_tx()` is called. In {IDF_TARGET_NAME}, both ``esp_wifi_set_promiscuous(true)`` and :cpp:func:`esp_wifi_start()` can trigger the initialization of Wi-Fi hardware.
|
||||
- The parameters of :cpp:func:`esp_wifi_80211_tx()` are hereby correctly provided.
|
||||
|
||||
Data Rate
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
- The default data rate is 1 Mbps.
|
||||
- Can set any rate through :cpp:func:`esp_wifi_config_80211_tx_rate()` API.
|
||||
- Can set any bandwidth through :cpp:func:`esp_wifi_set_bandwidth()` API.
|
||||
|
||||
Side-Effects to Avoid in Different Scenarios
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Theoretically, if the side-effects the API imposes on the Wi-Fi driver or other stations/APs are not considered, a raw 802.11 packet can be sent over the air with any destination MAC, any source MAC, any BSSID, or any other types of packet. However, robust or useful applications should avoid such side-effects. The table below provides some tips and recommendations on how to avoid the side-effects of :cpp:func:`esp_wifi_80211_tx()` in different scenarios.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 10 50
|
||||
|
||||
* - Scenario
|
||||
- Description
|
||||
* - No Wi-Fi connection
|
||||
- In this scenario, no Wi-Fi connection is set up, so there are no side-effects on the Wi-Fi driver. If ``en_sys_seq==true``, the Wi-Fi driver is responsible for the sequence control. If ``en_sys_seq==false``, the application needs to ensure that the buffer has the correct sequence.
|
||||
|
||||
Theoretically, the MAC address can be any address. However, this may impact other stations/APs with the same MAC/BSSID.
|
||||
|
||||
Side-effect example#1 The application calls :cpp:func:`esp_wifi_80211_tx()` to send a beacon with BSSID == mac_x in AP mode, but the mac_x is not the MAC of the AP interface. Moreover, there is another AP, e.g., “other-AP”, whose BSSID is mac_x. If this happens, an “unexpected behavior” may occur, because the stations which connect to the “other-AP” cannot figure out whether the beacon is from the “other-AP” or the :cpp:func:`esp_wifi_80211_tx()`.
|
||||
|
||||
To avoid the above-mentioned side-effects, it is recommended that:
|
||||
|
||||
- If :cpp:func:`esp_wifi_80211_tx` is called in station mode, the first MAC should be a multicast MAC or the exact target-device’s MAC, while the second MAC should be that of the station interface.
|
||||
|
||||
- If :cpp:func:`esp_wifi_80211_tx` is called in AP mode, the first MAC should be a multicast MAC or the exact target-device’s MAC, while the second MAC should be that of the AP interface.
|
||||
|
||||
The recommendations above are only for avoiding side-effects and can be ignored when there are good reasons.
|
||||
|
||||
* - Have Wi-Fi connection
|
||||
- When the Wi-Fi connection is already set up, and the sequence is controlled by the application, the latter may impact the sequence control of the Wi-Fi connection as a whole. So, the ``en_sys_seq`` need to be true, otherwise ``ESP_ERR_INVALID_ARG`` is returned.
|
||||
|
||||
The MAC-address recommendations in the “No Wi-Fi connection” scenario also apply to this scenario.
|
||||
|
||||
If the Wi-Fi mode is station mode, the MAC address1 is the MAC of AP to which the station is connected, and the MAC address2 is the MAC of station interface, it is said that the packet is sent from the station to AP. Otherwise, if the Wi-Fi is in AP mode, the MAC address1 is the MAC of the station that connects to this AP, and the MAC address2 is the MAC of AP interface, it is said that the packet is sent from the AP to station. To avoid conflicting with Wi-Fi connections, the following checks are applied:
|
||||
|
||||
- If the packet type is data and is sent from the station to AP, the ToDS bit in IEEE 80211 frame control should be 1 and the FromDS bit should be 0. Otherwise, the packet will be discarded by Wi-Fi driver.
|
||||
|
||||
- If the packet type is data and is sent from the AP to station, the ToDS bit in IEEE 80211 frame control should be 0 and the FromDS bit should be 1. Otherwise, the packet will be discarded by Wi-Fi driver.
|
||||
|
||||
- If the packet is sent from station to AP or from AP to station, the Power Management, More Data, and Re-Transmission bits should be 0. Otherwise, the packet will be discarded by Wi-Fi driver.
|
||||
|
||||
``ESP_ERR_INVALID_ARG`` is returned if any check fails.
|
||||
|
||||
|
||||
Wi-Fi Vendor IE Configuration
|
||||
-----------------------------------
|
||||
|
||||
By default, all Wi-Fi management frames are processed by the Wi-Fi driver, and the application can ignore them. However, some applications may have to handle the beacon, probe request, probe response, and other management frames. For example, if you insert some vendor-specific IE into the management frames, it is only the management frames which contain this vendor-specific IE that will be processed. In {IDF_TARGET_NAME}, :cpp:func:`esp_wifi_set_vendor_ie()` and :cpp:func:`esp_wifi_set_vendor_ie_cb()` are responsible for this kind of tasks.
|
||||
|
||||
|
||||
.. only:: SOC_WIFI_CSI_SUPPORT
|
||||
|
||||
Wi-Fi Channel State Information
|
||||
------------------------------------
|
||||
|
||||
.. only:: esp32 or esp32s2 or esp32c3 or esp32s3
|
||||
|
||||
Channel state information (CSI) refers to the channel information of a Wi-Fi connection. In {IDF_TARGET_NAME}, this information consists of channel frequency responses of sub-carriers and is estimated when packets are received from the transmitter. Each channel frequency response of sub-carrier is recorded by two bytes of signed characters. The first one is imaginary part and the second one is real part. There are up to three fields of channel frequency responses according to the type of received packet. They are legacy long training field (LLTF), high throughput LTF (HT-LTF), and space time block code HT-LTF (STBC-HT-LTF). For different types of packets which are received on channels with different state, the sub-carrier index and total bytes of signed characters of CSI are shown in the following table.
|
||||
|
||||
+-------------+--------------------+-----------------------------------------+--------------------------------------------------------+----------------------------------------------------------+
|
||||
| channel | secondary channel | none | below | above |
|
||||
+-------------+--------------------+-------------+---------------------------+----------+---------------------------------------------+----------+-----------------------------------------------+
|
||||
| packet | signal mode | non HT | HT | non HT | HT | non HT | HT |
|
||||
+ +--------------------+-------------+---------------------------+----------+-----------------+---------------------------+----------+-------------------+---------------------------+
|
||||
| information | channel bandwidth | 20 MHz | 20 MHz | 20 MHz | 20 MHz | 40 MHz | 20 MHz | 20 MHz | 40 MHz |
|
||||
+ +--------------------+-------------+-------------+-------------+----------+----------+------+-------------+-------------+----------+----------+--------+-------------+-------------+
|
||||
| | STBC | non STBC | non STBC | STBC | non STBC | non STBC | STBC | non STBC | STBC | non STBC | non STBC | STBC | non STBC | STBC |
|
||||
+-------------+--------------------+-------------+-------------+-------------+----------+----------+------+-------------+-------------+----------+----------+--------+-------------+-------------+
|
||||
| sub-carrier | LLTF | 0~31, -32~-1| 0~31, -32~-1| 0~31, -32~-1| 0~63 | 0~63 | 0~63 | 0~63 | 0~63 | -64~-1 | -64~-1 | -64~-1 | -64~-1 | -64~-1 |
|
||||
+ +--------------------+-------------+-------------+-------------+----------+----------+------+-------------+-------------+----------+----------+--------+-------------+-------------+
|
||||
| index | HT-LTF | - | 0~31, -32~-1| 0~31, -32~-1| - | 0~63 | 0~62 | 0~63, -64~-1| 0~60, -60~-1| - | -64~-1 | -62~-1 | 0~63, -64~-1| 0~60, -60~-1|
|
||||
+ +--------------------+-------------+-------------+-------------+----------+----------+------+-------------+-------------+----------+----------+--------+-------------+-------------+
|
||||
| | STBC-HT-LTF | - | - | 0~31, -32~-1| - | - | 0~62 | - | 0~60, -60~-1| - | - | -62~-1 | - | 0~60, -60~-1|
|
||||
+-------------+--------------------+-------------+-------------+-------------+----------+----------+------+-------------+-------------+----------+----------+--------+-------------+-------------+
|
||||
| total bytes | 128 | 256 | 384 | 128 | 256 | 380 | 384 | 612 | 128 | 256 | 376 | 384 | 612 |
|
||||
+----------------------------------+-------------+-------------+-------------+----------+----------+------+-------------+-------------+----------+----------+--------+-------------+-------------+
|
||||
|
||||
All of the information in the table can be found in the structure wifi_csi_info_t.
|
||||
|
||||
- Secondary channel refers to secondary_channel field of rx_ctrl field.
|
||||
- Signal mode of packet refers to sig_mode field of rx_ctrl field.
|
||||
- Channel bandwidth refers to cwb field of rx_ctrl field.
|
||||
- STBC refers to stbc field of rx_ctrl field.
|
||||
- Total bytes refers to len field.
|
||||
- The CSI data corresponding to each Long Training Field (LTF) type is stored in a buffer starting from the buf field. Each item is stored as two bytes: imaginary part followed by real part. The order of each item is the same as the sub-carrier in the table. The order of LTF is: LLTF, HT-LTF, STBC-HT-LTF. However, all 3 LTFs may not be present, depending on the channel and packet information (see above).
|
||||
- If first_word_invalid field of :cpp:type:`wifi_csi_info_t` is true, it means that the first four bytes of CSI data is invalid due to a hardware limitation in {IDF_TARGET_NAME}.
|
||||
- More information like RSSI, noise floor of RF, receiving time and antenna is in the rx_ctrl field.
|
||||
|
||||
When imaginary part and real part data of sub-carrier are used, please refer to the table below.
|
||||
|
||||
+-----------------+-------------------+------------------------------+--------------------------+
|
||||
| PHY standard | Sub-carrier range | Pilot sub-carrier | Sub-carrier (total/data) |
|
||||
+=================+===================+==============================+==========================+
|
||||
| 802.11a/g | -26 to +26 | -21, -7, +7, +21 | 52 total, 48 usable |
|
||||
+-----------------+-------------------+------------------------------+--------------------------+
|
||||
| 802.11n, 20 MHz | -28 to +28 | -21, -7, +7, +21 | 56 total, 52 usable |
|
||||
+-----------------+-------------------+------------------------------+--------------------------+
|
||||
| 802.11n, 40 MHz | -57 to +57 | -53, -25, -11, +11, +25, +53 | 114 total, 108 usable |
|
||||
+-----------------+-------------------+------------------------------+--------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
- For STBC packet, CSI is provided for every space-time stream without CSD (cyclic shift delay). As each cyclic shift on the additional chains shall be -200 ns, only the CSD angle of first space-time stream is recorded in sub-carrier 0 of HT-LTF and STBC-HT-LTF for there is no channel frequency response in sub-carrier 0. CSD[10:0] is 11 bits, ranging from -pi to pi.
|
||||
|
||||
- If LLTF, HT-LTF, or STBC-HT-LTF is not enabled by calling API :cpp:func:`esp_wifi_set_csi_config()`, the total bytes of CSI data will be fewer than that in the table. For example, if LLTF and HT-LTF is not enabled and STBC-HT-LTF is enabled, when a packet is received with the condition above/HT/40MHz/STBC, the total bytes of CSI data is 244 ((61 + 60) * 2 + 2 = 244. The result is aligned to four bytes, and the last two bytes are invalid).
|
||||
|
||||
.. only:: esp32c5
|
||||
|
||||
Channel state information (CSI) refers to the channel information of a Wi-Fi connection. In {IDF_TARGET_NAME}, this information consists of channel frequency responses of sub-carriers and is estimated when packets are received from the transmitter. Each channel frequency response of sub-carrier is recorded by two bytes of signed characters. The first one is imaginary part and the second one is real part. Except for the IEEE 802.11g mode, all other modes have two LTF sequences (LLTF + HT/VHT/HE-LTF). {IDF_TARGET_NAME} can determine whether to include LLTF or HT/VHT/HE-LTF through ``acquire_csi_force_lltf`` field of :cpp:struct:`wifi_csi_acquire_config_t`. For different types of packets which are received on channels with different state, the sub-carrier index and total bytes of signed characters of CSI are shown in the following table.
|
||||
|
||||
+-------------+-------------------+--------------------------------------------+-----------------------------------+--------------------------------------------------------------------------+--------------------------------------------------------------------------+
|
||||
| channel | secondary channel | none | below | above |
|
||||
+-------------+-------------------+--------------+-----------------------------+-----------------------------------+--------------+-----------------------------------------------------------+--------------+-----------------------------------------------------------+
|
||||
| packet | signal mode | non HT | HT | HE | non HT | HT | non HT | HT |
|
||||
| +-------------------+--------------+-----------------------------+-----------------------------------+--------------+-----------------------------+-----------------------------+--------------+-----------------------------+-----------------------------+
|
||||
| information | channel bandwidth | 20 MHz | 20 MHz | 20 MHz | 20 MHz | 20 MHz | 40 MHz | 20 MHz | 20 MHz | 40 MHz |
|
||||
| +-------------------+--------------+--------------+--------------+---------------+-------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|
||||
| | STBC | non STBC | non STBC | STBC | non STBC | STBC | non STBC | non STBC | STBC | none STBC | STBC | non STBC | non STBC | STBC | non STBC | STBC |
|
||||
+-------------+-------------------+--------------+--------------+--------------+---------------+-------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|
||||
| sub-carrier | LLTF | 0~26, -26~-1 | — | — | — | — | 0~52 | — | — | — | — | -53~-1 | — | — | — | — |
|
||||
| +-------------------+--------------+--------------+--------------+---------------+-------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|
||||
| index | HT-LTF (HT-LTF1) | — | 0~28, -28~-1 | 0~28, -28~-1 | — | — | — | 0~56 | 0~56 | 0~58, -58~-1 | 0~58, -58~-1 | — | -57~-1 | -57~-1 | 0~58, -58~-1 | 0~58, -58~-1 |
|
||||
| +-------------------+--------------+--------------+--------------+---------------+-------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|
||||
| | HT-LTF2 | — | — | 0~28, -28~-1 | — | — | — | — | 0~56 | — | 0~58, -58~-1 | — | — | -57~-1 | — | 0~58, -58~-1 |
|
||||
| +-------------------+--------------+--------------+--------------+---------------+-------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|
||||
| | HE-LTF (HE-LTF1) | — | — | — | 0~122, -122~1 | Determined by | — | — | — | — | — | — | — | — | — | — |
|
||||
| +-------------------+--------------+--------------+--------------+---------------+ +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|
||||
| | HE-LTF2 | — | — | — | — | wifi_csi_config_t | — | — | — | — | — | — | — | — | — | — |
|
||||
+-------------+-------------------+--------------+--------------+--------------+---------------+-------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|
||||
| total bytes | 106 | 114 | 228 | 490 | 490 | 106 | 114 | 228 | 234 | 468 | 106 | 114 | 228 | 234 | 468 |
|
||||
+---------------------------------+--------------+--------------+--------------+---------------+-------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
|
||||
|
||||
.. note::
|
||||
|
||||
- In HT/VHT/HE modes, there are two LTF sequences: LLTF + HT/VHT/HE-LTF. If the ``acquire_csi_force_lltf`` field of :cpp:struct:`wifi_csi_acquire_config_t` is set to false, the CSI data will only contain HT/VHT/HE-LTF (as shown in the table above); otherwise, the CSI data will only contain LLTF. The sub-carrier index and total bytes for LLTF in HT/VHT/HE modes are the same as those for LLTF in non-HT modes.
|
||||
- In VHT mode, the sub-carrier index and total bytes are the same as those in HT mode.
|
||||
|
||||
All of the information in the table can be found in the structure :cpp:type:`wifi_csi_info_t`.
|
||||
|
||||
- Secondary channel refers to ``second`` field of ``rx_ctrl`` field.
|
||||
- signal mode of packet refers to ``cur_bb_format`` field of ``rx_ctrl`` field.
|
||||
- total bytes refers to ``len`` field
|
||||
- The CSI data corresponding to each Long Training Field (LTF) type is stored in a buffer starting from the buf field. Each item is stored as two bytes: imaginary part followed by real part. The order of each item is the same as the sub-carrier in the table.
|
||||
- If ``first_word_invalid`` of :cpp:type:`wifi_csi_info_t` is true, it means that the first four bytes of CSI data is invalid due to a hardware limitation in {IDF_TARGET_NAME}.
|
||||
- If ``rx_channel_estimate_info_vld`` of ``rx_ctrl`` field is 1, indicates that the CSI data is valid; otherwise, the CSI data is invalid.
|
||||
- More information like RSSI, noise floor of RF, receiving time and antenna is in the ``rx_ctrl`` field.
|
||||
|
||||
For STBC packets, the subcarrier indices of HE-LTF1 and HE-LTF2 are determined by ``acquire_csi_he_stbc_mode`` field of :cpp:type:`wifi_csi_config_t`. Please refer to the table below for details.
|
||||
|
||||
+---------------------+----------------------+----------------------+
|
||||
| acquire_csi_he_stbc | HE-LTF1 | HE-LTF2 |
|
||||
+---------------------+----------------------+----------------------+
|
||||
| 0 | -122~-1, 0~122 | — |
|
||||
+---------------------+----------------------+----------------------+
|
||||
| 1 | — | -122~-1, 0~122 |
|
||||
+---------------------+----------------------+----------------------+
|
||||
| 2 | Sample evenly among the HE-LTF1 and HE-LTF2 |
|
||||
+---------------------+----------------------+----------------------+
|
||||
|
||||
When imaginary part and real part data of sub-carrier are used, please refer to the table below.
|
||||
|
||||
+-----------------------+-------------------+------------------------------------------+------------------------------+
|
||||
| PHY standard | Sub-carrier range | Invalid sub-carrier | Sub-carrier (total/data) |
|
||||
+=======================+===================+==========================================+==============================+
|
||||
| 802.11a/g | -26 to +26 | 0 | 53 total, 52 usable |
|
||||
+-----------------------+-------------------+------------------------------------------+------------------------------+
|
||||
| 802.11n, 20 MHz | -28 to +28 | 0 | 57 total, 56 usable |
|
||||
+-----------------------+-------------------+------------------------------------------+------------------------------+
|
||||
| 802.11n, 40 MHz | -58 to +58 | -1, 0, 1 | 117 total, 114 usable |
|
||||
+-----------------------+-------------------+------------------------------------------+------------------------------+
|
||||
| 802.11ac, 20 MHz | -28 to +28 | 0 | 57 total, 56 usable |
|
||||
+-----------------------+-------------------+------------------------------------------+------------------------------+
|
||||
| 802.11ax, 20 MHz (SU) | -122 to + 122 | -1, 0, 1 | 245 total, 242 usable |
|
||||
+-----------------------+-------------------+------------------------------------------+------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
- When the PHY is 802.11ax, please refer to the protocol for sub-carrier range and invalid sub-carrier for MU packets.
|
||||
|
||||
.. note::
|
||||
|
||||
- For STBC packet, CSI is provided for every space-time stream without CSD (cyclic shift delay). As each cyclic shift on the additional chains shall be -200 ns, only the CSD angle of first space-time stream is recorded in sub-carrier 0 of HT-LTF1 (HE-LTF1) and HT-LTF2 (HE-LTF2) for there is no channel frequency response in sub-carrier 0. CSD[10:0] is 11 bits, ranging from -pi to pi.
|
||||
|
||||
|
||||
Wi-Fi Channel State Information Configure
|
||||
-------------------------------------------
|
||||
|
||||
To use Wi-Fi CSI, the following steps need to be done.
|
||||
|
||||
- Select Wi-Fi CSI in menuconfig. Go to ``Menuconfig`` > ``Components config`` > ``Wi-Fi`` > ``Wi-Fi CSI (Channel State Information)``.
|
||||
- Set CSI receiving callback function by calling API :cpp:func:`esp_wifi_set_csi_rx_cb()`.
|
||||
- Configure CSI by calling API :cpp:func:`esp_wifi_set_csi_config()`.
|
||||
- Enable CSI by calling API :cpp:func:`esp_wifi_set_csi()`.
|
||||
|
||||
The CSI receiving callback function runs from Wi-Fi task. So, do not do lengthy operations in the callback function. Instead, post necessary data to a queue and handle it from a lower priority task. Because station does not receive any packet when it is disconnected and only receives packets from AP when it is connected, it is suggested to enable sniffer mode to receive more CSI data by calling :cpp:func:`esp_wifi_set_promiscuous()`.
|
||||
|
||||
|
||||
Wi-Fi Multiple Antennas
|
||||
------------------------
|
||||
|
||||
Please refer to the :doc:`PHY <../../api-guides/phy>`.
|
||||
@@ -9,7 +9,7 @@ Wi-Fi Expansion
|
||||
|
||||
.. only:: SOC_WIFI_SUPPORTED
|
||||
|
||||
{IDF_TARGET_NAME} does support Wi-Fi functionality natively, please refer to :doc:`wifi` documentation. Even though Wi-Fi is supported on {IDF_TARGET_NAME}, it is possible to expand it and use another instance of Wi-Fi expansion interfaces using `esp_wifi_remote <https://components.espressif.com/components/espressif/esp_wifi_remote>`_ component.
|
||||
{IDF_TARGET_NAME} does support Wi-Fi functionality natively, please refer to :doc:`wifi-driver/index` documentation. Even though Wi-Fi is supported on {IDF_TARGET_NAME}, it is possible to expand it and use another instance of Wi-Fi expansion interfaces using `esp_wifi_remote <https://components.espressif.com/components/espressif/esp_wifi_remote>`_ component.
|
||||
|
||||
|
||||
{IDF_TARGET_NAME} esp_wifi_remote
|
||||
|
||||
@@ -43,28 +43,73 @@ Wi-Fi Enterprise
|
||||
---------------------------------
|
||||
|
||||
Introduction
|
||||
++++++++++++
|
||||
++++++++++++++
|
||||
|
||||
Enterprise security is the secure authentication mechanism for enterprise wireless networks. It uses the RADIUS server for authentication of network users before connecting to the Access Point (AP). The authentication process is based on 802.1X policy and comes with different Extended Authentication Protocol (EAP) methods such as TLS, TTLS, PEAP, and EAP-FAST. RADIUS server authenticates the users based on their credentials (username and password), digital certificates, or both.
|
||||
Wi-Fi Enterprise provides secure authentication mechanisms for enterprise wireless networks. It is based on the IEEE 802.1X standard and requires a RADIUS server to authenticate network users before they connect to an Access Point (AP). Depending on the Extended Authentication Protocol (EAP) method used, authentication can rely on user credentials (username and password), digital certificates, or both.
|
||||
|
||||
When {IDF_TARGET_NAME}, operating in station mode, connects to an Enterprise AP, it initiates an authentication request. The AP forwards this request to the configured RADIUS server, which validates the station based on the selected EAP method and configured parameters.
|
||||
|
||||
.. note::
|
||||
|
||||
{IDF_TARGET_NAME} supports Wi-Fi Enterprise only in station mode.
|
||||
|
||||
{IDF_TARGET_NAME} supports **WPA2-Enterprise** and **WPA3-Enterprise**. WPA3-Enterprise builds upon the foundation of WPA2-Enterprise with the additional requirement of using Protected Management Frames (PMF) and server certificate validation on all WPA3 connections. **WPA3-Enterprise also offers an additional secure mode using 192-bit minimum-strength security protocols and cryptographic tools to better protect sensitive data.** The 192-bit security mode offered by WPA3-Enterprise ensures the right combination of cryptographic tools is used and sets a consistent baseline of security within a WPA3 network. WPA3-Enterprise 192-bit mode is only supported by modules having :c:macro:`SOC_WIFI_GCMP_SUPPORT` support. Enable :ref:`CONFIG_ESP_WIFI_SUITE_B_192` flag to support WPA3-Enterprise with 192-bit mode.
|
||||
WPA2-Enterprise and WPA3-Enterprise
|
||||
++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
{IDF_TARGET_NAME} supports the following EAP methods:
|
||||
- EAP-TLS: This is a certificate-based method and only requires SSID and EAP-IDF.
|
||||
- PEAP: This is a Protected EAP method. Usernames and passwords are mandatory.
|
||||
- EAP-TTLS: This is a credential-based method. Only server authentication is mandatory while user authentication is optional. Username and Password are mandatory. It supports different Phase2 methods, such as:
|
||||
- PAP: Password Authentication Protocol.
|
||||
- CHAP: Challenge Handshake Authentication Protocol.
|
||||
- MSCHAP and MSCHAP-V2.
|
||||
- EAP-FAST: This is an authentication method based on Protected Access Credentials (PAC) which also uses identity and password. Currently, :ref:`CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT` flag should be disabled to use this feature.
|
||||
{IDF_TARGET_NAME} supports both **WPA2-Enterprise** and **WPA3-Enterprise**.
|
||||
|
||||
- :example:`wifi/wifi_eap_fast` demonstrates how to connect {IDF_TARGET_NAME} to an AP with Wi-Fi Enterprise authentication using EAP-FAST, including the installation of a CA certificate, setting user credentials, enabling Wi-Fi Enterprise mode, and handling connection to the AP.
|
||||
**WPA2-Enterprise** provides authentication using 802.1X/EAP and relies on secure credentials or certificates. For secure connectivity, the AP and station negotiate and agree on an appropriate cipher suite. {IDF_TARGET_NAME} supports the following:
|
||||
|
||||
- 802.1X/EAP (WPA) AKM method
|
||||
- AES-CCM cipher suite
|
||||
- Additional cipher suites supported by mbedtls when the `USE_MBEDTLS_CRYPTO` flag is enabled
|
||||
|
||||
**WPA3-Enterprise** enhances WPA2-Enterprise by requiring Protected Management Frames (PMF) and mandatory server certificate validation on all WPA3 connections.
|
||||
|
||||
WPA3-Enterprise also introduces an additional secure mode using **192-bit minimum-strength security protocols** (“Suite B”). This mode ensures a consistent baseline of cryptographic strength.
|
||||
|
||||
- WPA3-Enterprise 192-bit mode is supported only on modules that have :c:macro:`SOC_WIFI_GCMP_SUPPORT`.
|
||||
- To enable WPA3-Enterprise 192-bit mode, configure :ref:`CONFIG_ESP_WIFI_SUITE_B_192`.
|
||||
|
||||
Supported EAP Methods
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
{IDF_TARGET_NAME} supports multiple EAP methods for Enterprise authentication. These methods may require different combinations of SSID, identity, username/password, CA certificate, or client certificate.
|
||||
|
||||
The following EAP methods are supported:
|
||||
|
||||
- **EAP-TLS**
|
||||
|
||||
Certificate-based method requiring SSID and EAP identity. Client certificates are used for authentication.
|
||||
|
||||
- **PEAP**
|
||||
|
||||
A Protected EAP method requiring a username and password.
|
||||
|
||||
- **EAP-TTLS**
|
||||
|
||||
A credential-based method. Server authentication is mandatory; user authentication is optional depending on the Phase 2 method. Username and password are typically required. Supported Phase 2 methods include:
|
||||
|
||||
- PAP: Password Authentication Protocol
|
||||
- CHAP: Challenge Handshake Authentication Protocol
|
||||
- MSCHAP
|
||||
- MSCHAP-V2
|
||||
|
||||
- **EAP-FAST**
|
||||
|
||||
An authentication method based on Protected Access Credentials (PAC), requiring an identity and password. To use EAP-FAST, :ref:`CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT` must be **disabled**.
|
||||
|
||||
Examples
|
||||
++++++++++
|
||||
|
||||
- :example:`wifi/wifi_eap_fast`
|
||||
|
||||
Demonstrates connecting {IDF_TARGET_NAME} to an AP using EAP-FAST, including CA certificate installation, credential configuration, enabling Enterprise mode, and connecting to the AP.
|
||||
|
||||
- :example:`wifi/wifi_enterprise`
|
||||
|
||||
Demonstrates connecting {IDF_TARGET_NAME} using EAP-TLS, EAP-PEAP, and EAP-TTLS. For details on generating certificates with OpenSSL and running the example, refer to :example_file:`wifi/wifi_enterprise/README.md`.
|
||||
|
||||
- :example:`wifi/wifi_enterprise` demonstrates how to connect {IDF_TARGET_NAME} to an AP with Wi-Fi Enterprise authentication using other EAP methods, such as EAP-TLS, EAP-PEAP, EAP-TTLS. For details on generating certificates with OpenSSL commands and running the example, refer to :example_file:`wifi/wifi_enterprise/README.md`.
|
||||
|
||||
WPA3-Personal
|
||||
-------------
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -75,6 +75,7 @@ api-guides/ulp_macros api-reference/system/ulp_macros
|
||||
api-guides/ulp-risc-v api-reference/system/ulp-risc-v
|
||||
api-guides/console api-reference/system/console
|
||||
api-guides/event-handling api-reference/system/esp_event
|
||||
api-guides/wifi api-guides/wifi-driver/index
|
||||
|
||||
api-reference/network/tcpip_adapter migration-guides/tcpip-adapter
|
||||
api-reference/system/system api-reference/system/misc_system_api
|
||||
|
||||
@@ -48,7 +48,7 @@ API 指南
|
||||
host-apps
|
||||
:SOC_USB_OTG_SUPPORTED and not esp32p4 and not esp32h4: usb-otg-console
|
||||
:SOC_USB_SERIAL_JTAG_SUPPORTED: usb-serial-jtag-console
|
||||
:SOC_WIFI_SUPPORTED: wifi
|
||||
:SOC_WIFI_SUPPORTED: wifi-driver/index
|
||||
:SOC_WIFI_SUPPORTED: wifi-security
|
||||
wifi-expansion
|
||||
:SOC_WIFI_SUPPORTED or SOC_BT_SUPPORTED or SOC_IEEE802154_SUPPORTED: phy
|
||||
|
||||
@@ -204,7 +204,7 @@ ESP-IDF 启动的系统任务预设了固定优先级。启动时,一些任务
|
||||
- FreeRTOS 初始化调度器时会创建定时器任务,用于处理 FreeRTOS 定时器的回调函数,优先级最低(1, :ref:`可配置 <CONFIG_FREERTOS_TIMER_TASK_PRIORITY>` )。
|
||||
- 系统任务 :doc:`/api-reference/system/esp_event` 用于管理默认的系统事件循环并执行回调函数,优先级较高 (20, ``ESP_TASK_EVENT_PRIO``)。仅在应用程序调用 :cpp:func:`esp_event_loop_create_default` 时使用此配置。可以调用 :cpp:func:`esp_event_loop_create` 添加自定义任务配置。
|
||||
- :doc:`/api-guides/lwip` TCP/IP 任务优先级较高 (18, ``ESP_TASK_TCPIP_PRIO``)。
|
||||
:SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi` 任务优先级较高 (23).
|
||||
:SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi-driver/index` 任务优先级较高 (23).
|
||||
:SOC_WIFI_SUPPORTED: - 使用 Wi-Fi Protected Setup (WPS)、WPA2 EAP-TLS、Device Provisioning Protocol (DPP) 或 BSS Transition Management (BTM) 等功能时,Wi-Fi wpa_supplicant 组件可能会创建优先级较低的专用任务 (2)。
|
||||
:SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/controller_vhci` 任务优先级较高 (23, ``ESP_TASK_BT_CONTROLLER_PRIO``)。蓝牙控制器需要以低延迟响应请求,因此其任务应始终为系统最高优先级的任务之一。
|
||||
:SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/nimble/index` 任务优先级较高 (21).
|
||||
@@ -220,7 +220,7 @@ ESP-IDF 启动的系统任务预设了固定优先级。启动时,一些任务
|
||||
- FreeRTOS 初始化调度器时会创建定时器任务,用于处理 FreeRTOS 定时器的回调函数,优先级最低(1, :ref:`可配置 <CONFIG_FREERTOS_TIMER_TASK_PRIORITY>` )且固定在核 0 上执行。
|
||||
- 系统任务 :doc:`/api-reference/system/esp_event` 用于管理默认的系统事件循环并执行回调函数,优先级较高 (20, ``ESP_TASK_EVENT_PRIO``) 且固定在核 0 上执行。此配置仅在应用程序调用 :cpp:func:`esp_event_loop_create_default` 时使用。可以调用 :cpp:func:`esp_event_loop_create` 添加自定义任务配置。
|
||||
- :doc:`/api-guides/lwip` TCP/IP 任务优先级较高 (18, ``ESP_TASK_TCPIP_PRIO``) 且并未固定在特定内核上执行( :ref:`可配置 <CONFIG_LWIP_TCPIP_TASK_AFFINITY>` )。
|
||||
:SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi` 任务优先级较高 (23) 且默认固定在核 0 上执行( :ref:`可配置 <CONFIG_ESP_WIFI_TASK_CORE_ID>` )。
|
||||
:SOC_WIFI_SUPPORTED: - :doc:`/api-guides/wifi-driver/index` 任务优先级较高 (23) 且默认固定在核 0 上执行( :ref:`可配置 <CONFIG_ESP_WIFI_TASK_CORE_ID>` )。
|
||||
:SOC_WIFI_SUPPORTED: - 使用 Wi-Fi Protected Setup (WPS)、WPA2 EAP-TLS、Device Provisioning Protocol (DPP) 或 BSS Transition Management (BTM) 等功能时,Wi-Fi wpa_supplicant 组件可能会创建优先级较低的专用任务 (2),这些任务并未固定在特定内核上执行。
|
||||
:SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/controller_vhci` 任务优先级较高 (23, ``ESP_TASK_BT_CONTROLLER_PRIO``) 且默认固定在核 0 上执行( :ref:`可配置 <{IDF_TARGET_CONTROLLER_CORE_CONFIG}>` )。蓝牙控制器需要以低延迟响应请求,因此其任务应始终为最高优先级的任务之一并分配给单个 CPU 执行。
|
||||
:SOC_BT_SUPPORTED: - :doc:`/api-reference/bluetooth/nimble/index` 任务优先级较高 (21) 且默认固定在核 0 上执行( :ref:`可配置 <CONFIG_BT_NIMBLE_PINNED_TO_CORE_CHOICE>` ).
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
###############
|
||||
Wi-Fi 驱动程序
|
||||
###############
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
overview
|
||||
station-scenarios
|
||||
wifi-modes
|
||||
wifi-mac-protocols
|
||||
security-and-roaming
|
||||
wifi-performance-and-power-save
|
||||
wifi-vendor-features
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
||||
安全与漫游
|
||||
=================
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
|
||||
支持的 Wi-Fi 安全模式
|
||||
-------------------------
|
||||
|
||||
{IDF_TARGET_NAME} 支持以下 Wi-Fi 安全模式。有关详细配置和使用说明,请参阅 :doc:`Wi-Fi 安全性 <../wifi-security>`。
|
||||
|
||||
- Open
|
||||
- WEP
|
||||
- 个人级 WPA
|
||||
- 个人级 WPA2
|
||||
- 个人级 WPA3
|
||||
- 企业级 Wi-Fi
|
||||
|
||||
|
||||
Wi-Fi Easy Connect™ (DPP)
|
||||
--------------------------
|
||||
|
||||
Wi-Fi Easy Connect\ :sup:`TM` (也称为设备配置协议)是一个安全且标准化的配置协议,用于配置 Wi-Fi 设备。更多信息请参考 :doc:`esp_dpp <../../api-reference/network/esp_dpp>`。
|
||||
|
||||
|
||||
WPS 注册
|
||||
-------------------------
|
||||
|
||||
在 Wi-Fi 模式 WIFI_MODE_STA 或 WIFI_MODE_APSTA 下,{IDF_TARGET_NAME} 支持 WPS 注册功能。目前,{IDF_TARGET_NAME} 支持的 WPS enrollee 类型有 PBC 和 PIN。
|
||||
|
||||
|
||||
无线网络管理
|
||||
----------------------------
|
||||
|
||||
无线网络管理让客户端设备能够交换有关网络拓扑结构的信息,包括与射频环境相关的信息。这使每个客户端都能感知网络状况,从而促进无线网络性能的整体改进。这是 802.11v 规范的一部分。它还使客户端能够支持网络辅助漫游。
|
||||
网络辅助漫游让 WLAN 能够向关联的客户端发送消息,从而使客户端与具有更好链路指标的 AP 关联。这对于促进负载平衡以及引导连接不良的客户端都很有用。
|
||||
|
||||
目前 802.11v 的实现支持 BSS 过渡管理帧。
|
||||
|
||||
无线资源管理
|
||||
---------------------------
|
||||
|
||||
无线电资源测量 (802.11k) 旨在改善网络内流量的分配方式。在无线局域网中,一般情况下,无线设备会连接发射信号最强的接入点 (AP)。根据用户的数量和地理位置,这种分配方式有时会导致某个接入点超负荷而其它接入点利用不足,从而导致整体网络性能下降。在符合 802.11k 规范的网络中,如果信号最强的 AP 已满负荷,无线设备则转移到其它未充分利用的 AP。尽管信号可能较弱,但由于更有效地利用了网络资源,总体吞吐量会更大。
|
||||
|
||||
目前 802.11k 的实现支持信标测量报告、链路测量报告和邻居请求。
|
||||
|
||||
请参考 IDF 示例程序 :idf_file:`examples/wifi/roaming/README.md` 来设置和使用这些 API。示例代码只演示了如何使用这些 API,应用程序应根据需要定义自己的算法和案例。
|
||||
|
||||
快速 BSS 切换
|
||||
---------------
|
||||
|
||||
快速 BSS 切换 (802.11r FT) 是一种标准,旨在允许移动中的无线设备保持连续连接,让客户端从一个 BSS(Basic Service Set,基站,口头也称 AP)快速安全地切换到另一个 BSS, 实现几乎无缝的连接, **避免 802.11i 的四次握手过程**。802.11r 重新定义了安全密钥协商协议,规定了 AP 之间的转换方式,允许以并行的方式协商和请求无线资源。服务器生成的密钥会缓存在无线网络中,未来可以基于此缓存的密钥建立一定数量的连接,避免了 802.11x 过程。
|
||||
|
||||
|
||||
{IDF_TARGET_NAME} station 模式支持 WPA2-PSK 网络 FT。注意,{IDF_TARGET_NAME} station 模式仅支持空中 FT 协议。
|
||||
|
||||
在 :cpp:type:`wifi_sta_config_t` 中提供了配置选项 :ref:`CONFIG_ESP_WIFI_11R_SUPPORT` 和配置参数 :cpp:type:`ft_enabled`,可启用 station 的 802.11r 支持。详细信息请参阅 ESP-IDF 示例 :idf_file:`examples/wifi/roaming/README.md`。
|
||||
|
||||
.. only:: SOC_WIFI_FTM_SUPPORT
|
||||
|
||||
Wi-Fi Location
|
||||
-------------------------------
|
||||
|
||||
Wi-Fi Location 将提高 AP 以外设备位置数据的准确性,这有助于创建新的、功能丰富的应用程序和服务,例如地理围栏、网络管理、导航等。用于确定设备相对于接入点的位置的协议之一是精细定时测量 (FTM),它会计算 Wi-Fi 帧的飞行时间。
|
||||
|
||||
精细定时测量 (FTM)
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
FTM 用于测量 Wi-Fi 往返时间(Wi-Fi RTT),即 Wi-Fi 信号从一个设备到另一个设备并返回所需的时间。使用 Wi-Fi RTT,设备之间的距离可以用一个简单的公式 `RTT * c / 2` 来计算,其中 c 是光速。
|
||||
|
||||
对于设备之间交换的帧,FTM 在帧到达或离开时使用时间戳,这个时间戳由 Wi-Fi 接口硬件提供。FTM 发起方(主要是 station 设备)发现 FTM 响应方(可以是 station 或 AP),并协商启动 FTM 程序。该程序以突发形式发送的多个动作帧及其 ACK 来收集时间戳数据。FTM 发起方最后收集数据以计算平均往返时间。
|
||||
|
||||
{IDF_TARGET_NAME} 在以下配置中支持 FTM:
|
||||
|
||||
- {IDF_TARGET_NAME} 在 station 模式下为 FTM 发起方。
|
||||
- {IDF_TARGET_NAME} 在 AP 模式下为 FTM 响应方。
|
||||
|
||||
.. only:: esp32c6
|
||||
|
||||
{IDF_TARGET_NAME} ECO1 及更早的版本不支持 FTM 发起方模式。
|
||||
|
||||
.. attention::
|
||||
|
||||
使用 RTT 的距离测量并不准确,RF 干扰、多径传播、天线方向和缺乏校准等因素会增加这些不准确度。为了获得更好的结果,建议在两个 ESP32 芯片系列设备(ESP32-C2 除外)之间执行 FTM,这两个设备可分别设置为 station 和 AP 模式。
|
||||
|
||||
请参考 ESP-IDF 示例 :idf_file:`examples/wifi/ftm/README.md`,了解设置和执行 FTM 的详细步骤。
|
||||
@@ -0,0 +1,898 @@
|
||||
Station 场景
|
||||
==============
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
.. _wifi-station-general-scenario:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi Station 通用场景
|
||||
------------------------------------------------
|
||||
|
||||
下图为 station 模式下的宏观场景,其中包含不同阶段的具体描述:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: station 模式下 Wi-Fi 事件场景示例
|
||||
:align: center
|
||||
|
||||
seqdiag sample-scenarios-station-mode {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 140;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
MAIN_TASK [label = "Main\ntask"];
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
LwIP_TASK [label = "LwIP\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
=== 1. 初始化阶段 ===
|
||||
MAIN_TASK -> LwIP_TASK [label="1.1> 创建/初始化 LwIP"];
|
||||
MAIN_TASK -> EVENT_TASK [label="1.2> 创建/初始化事件"];
|
||||
MAIN_TASK -> WIFI_TASK [label="1.3> 创建/初始化 Wi-Fi"];
|
||||
MAIN_TASK -> APP_TASK [label="1.4> 创建应用程序任务"];
|
||||
=== 2. 配置阶段 ===
|
||||
MAIN_TASK -> WIFI_TASK [label="2> 配置 Wi-Fi"];
|
||||
=== 3. 启动阶段 ===
|
||||
MAIN_TASK -> WIFI_TASK [label="3.1> 启动 Wi-Fi"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.2> WIFI_EVENT_STA_START"];
|
||||
APP_TASK <- EVENT_TASK [label="3.3> WIFI_EVENT_STA_START"];
|
||||
=== 4. 连接阶段 ===
|
||||
APP_TASK -> WIFI_TASK [label="4.1> 连接 Wi-Fi"];
|
||||
EVENT_TASK <- WIFI_TASK [label="4.2> WIFI_EVENT_STA_CONNECTED"];
|
||||
APP_TASK <- EVENT_TASK [label="4.3> WIFI_EVENT_STA_CONNECTED"];
|
||||
=== 5. 获取 IP 阶段 ===
|
||||
EVENT_TASK -> LwIP_TASK [label="5.1> 启动 DHCP 客户端"];
|
||||
EVENT_TASK <- LwIP_TASK [label="5.2> IP_EVENT_STA_GOT_IP"];
|
||||
APP_TASK <- EVENT_TASK [label="5.3> IP_EVENT_STA_GOT_IP"];
|
||||
APP_TASK -> APP_TASK [label="5.4> 套接字相关初始化"];
|
||||
=== 6. 断开阶段 ===
|
||||
EVENT_TASK <- WIFI_TASK [label="6.1> WIFI_EVENT_STA_DISCONNECTED"];
|
||||
APP_TASK <- EVENT_TASK [label="6.2> WIFI_EVENT_STA_DISCONNECTED"];
|
||||
APP_TASK -> APP_TASK [label="6.3> 断开处理"];
|
||||
=== 7. IP 更改阶段 ===
|
||||
EVENT_TASK <- LwIP_TASK [label="7.1> IP_EVENT_STA_GOT_IP"];
|
||||
APP_TASK <- EVENT_TASK [label="7.2> IP_EVENT_STA_GOT_IP"];
|
||||
APP_TASK -> APP_TASK [label="7.3> 套接字错误处理"];
|
||||
=== 8. 清理阶段 ===
|
||||
APP_TASK -> WIFI_TASK [label="8.1> 断开 Wi-Fi 连接"];
|
||||
APP_TASK -> WIFI_TASK [label="8.2> 终止 Wi-Fi"];
|
||||
APP_TASK -> WIFI_TASK [label="8.3> 清理 Wi-Fi"];
|
||||
}
|
||||
|
||||
|
||||
1. Wi-Fi/LwIP 初始化阶段
|
||||
++++++++++++++++++++++++++++++
|
||||
|
||||
- s1.1:主任务通过调用函数 :cpp:func:`esp_netif_init()` 创建一个 LwIP 核心任务,并初始化 LwIP 相关工作。
|
||||
|
||||
- s1.2:主任务通过调用函数 :cpp:func:`esp_event_loop_create()` 创建一个系统事件任务,并初始化应用程序事件的回调函数。在此情况下,该回调函数唯一的动作就是将事件中继到应用程序任务中。
|
||||
|
||||
- s1.3:主任务通过调用函数 :cpp:func:`esp_netif_create_default_wifi_ap()` 或 :cpp:func:`esp_netif_create_default_wifi_sta()` 创建有 TCP/IP 堆栈的默认网络接口实例绑定 station 或 AP。
|
||||
|
||||
- s1.4:主任务通过调用函数 :cpp:func:`esp_wifi_init()` 创建 Wi-Fi 驱动程序任务,并初始化 Wi-Fi 驱动程序。
|
||||
|
||||
- s1.5:主任务通过调用 OS API 创建应用程序任务。
|
||||
|
||||
推荐按照 s1.1 ~ s1.5 的步骤顺序针对基于 Wi-Fi/LwIP 的应用程序进行初始化。但这一顺序 **并非** 强制,你可以在第 s1.1 步创建应用程序任务,然后在该应用程序任务中进行所有其它初始化操作。不过,如果你的应用程序任务依赖套接字,那么在初始化阶段创建应用程序任务可能并不适用。此时,你可以在接收到 IP 后再进行任务创建。
|
||||
|
||||
2. Wi-Fi 配置阶段
|
||||
+++++++++++++++++++++++++++++++
|
||||
|
||||
Wi-Fi 驱动程序初始化成功后,可以进入到配置阶段。该场景下,Wi-Fi 驱动程序处于 station 模式。因此,首先你需调用函数 :cpp:func:`esp_wifi_set_mode` (WIFI_MODE_STA) 将 Wi-Fi 模式配置为 station 模式。可通过调用其它 esp_wifi_set_xxx API 进行更多设置,例如:协议模式、国家代码、带宽等。请参阅 :ref:`{IDF_TARGET_NAME} Wi-Fi 配置 <wifi-configuration>`。
|
||||
|
||||
一般情况下,我们会在建立 Wi-Fi 连接之前配置 Wi-Fi 驱动程序,但这 **并非** 强制要求。也就是说,只要 Wi-Fi 驱动程序已成功初始化,你可以在任意阶段进行配置。但是,如果你的 Wi-Fi 在建立连接后不需要更改配置,则应先在此阶段完成配置。因为调用配置 API(例如 :cpp:func:`esp_wifi_set_protocol()`)将会导致 Wi-Fi 连接断开,为操作带来不便。
|
||||
|
||||
如果 menuconfig 已使能 Wi-Fi NVS flash,则不论当前阶段还是后续的 Wi-Fi 配置信息都将被存储至该 flash 中。那么,当主板上电/重新启动时,就不需从头开始配置 Wi-Fi 驱动程序,只需调用函数 esp_wifi_get_xxx API 获取之前存储的配置信息。当然,如果不想使用之前的配置,你也可以重新配置 Wi-Fi 驱动程序。
|
||||
|
||||
3. Wi-Fi 启动阶段
|
||||
++++++++++++++++++++++++++++++++
|
||||
|
||||
- s3.1:调用函数 :cpp:func:`esp_wifi_start()` 启动 Wi-Fi 驱动程序。
|
||||
- s3.2:Wi-Fi 驱动程序将事件 :ref:`WIFI_EVENT_STA_START <wifi-event-sta-start>` 发布到事件任务中,然后,事件任务将执行一些正常操作并调用应用程序的事件回调函数。
|
||||
- s3.3:应用程序的事件回调函数将事件 :ref:`WIFI_EVENT_STA_START <wifi-event-sta-start>` 中继到应用程序任务中。此时,推荐调用函数 :cpp:func:`esp_wifi_connect()` 进行 Wi-Fi 连接。当然,你也可以等待在 :ref:`WIFI_EVENT_STA_START <wifi-event-sta-start>` 事件发生后的其它阶段再调用此函数。
|
||||
|
||||
4. Wi-Fi 连接阶段
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
- s4.1:调用函数 :cpp:func:`esp_wifi_connect()` 后,Wi-Fi 驱动程序将启动内部扫描/连接过程。
|
||||
|
||||
- s4.2:如果内部扫描/连接过程成功,将产生 :ref:`WIFI_EVENT_STA_CONNECTED <wifi-event-sta-connected>` 事件。然后,事件任务将启动 DHCP 客户端服务,最终触发 DHCP 程序。
|
||||
|
||||
- s4.3:在此情况下,应用程序的事件回调函数会将 :ref:`WIFI_EVENT_STA_CONNECTED <wifi-event-sta-connected>` 事件中继到应用程序任务中。通常,应用程序不需进行操作,而你可以执行任何动作,例如:打印日志等。
|
||||
|
||||
步骤 s4.2 中 Wi-Fi 连接可能会由于某些原因而失败,例如:密码错误、未找到 AP 等。这种情况下,将引发 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件并提示连接错误原因。有关如何处理中断 Wi-Fi 连接的事件,请参阅下文阶段 6 的描述。
|
||||
|
||||
5. Wi-Fi 获取 IP 阶段
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
- s5.1:一旦步骤 4.2 中的 DHCP 客户端初始化完成,Wi-Fi 驱动程序将进入 *获取 IP* 阶段。
|
||||
- s5.2:如果 Wi-Fi 成功从 DHCP 服务器接收到 IP 地址,则将引发 :ref:`IP_EVENT_STA_GOT_IP <ip-event-sta-got-ip>` 事件,事件任务将执行正常处理。
|
||||
- s5.3:应用程序的事件回调函数将事件 :ref:`IP_EVENT_STA_GOT_IP <ip-event-sta-got-ip>` 中继到应用程序任务中。对于那些基于 LwIP 构建的应用程序,此事件较为特殊,因为它意味着应用程序已准备就绪,可以开始任务,例如:创建 TCP/UDP 套接字等。此时较为容易犯的一个错误就是在接收到 :ref:`IP_EVENT_STA_GOT_IP <ip-event-sta-got-ip>` 事件之前就初始化套接字。**切忌在接收到 IP 之前启动任何套接字相关操作。**
|
||||
|
||||
6. Wi-Fi 断开阶段
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
- s6.1:当 Wi-Fi 因为某些原因(例如:AP 掉电、RSSI 较弱等)连接中断时,将产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件。此事件也可能在上文阶段 3 中发生。在这里,事件任务将通知 LwIP 任务清除/移除所有 UDP/TCP 连接。然后,所有应用程序套接字都将处于错误状态。也就是说,:ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件发生时,任何套接字都无法正常工作。
|
||||
- s6.2:上述情况下,应用程序的事件回调函数会将 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件中继到应用程序任务中。推荐调用函数 :cpp:func:`esp_wifi_connect()` 重新连接 Wi-Fi,关闭所有套接字,并在必要时重新创建套接字。请参阅 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>`。
|
||||
|
||||
7. Wi-Fi IP 更改阶段
|
||||
++++++++++++++++++++++++++++++++++
|
||||
|
||||
- s7.1:如果 IP 地址发生更改,将引发 :ref:`IP_EVENT_STA_GOT_IP <ip-event-sta-got-ip>` 事件,其中 "ip_change" 被置为 "true"。
|
||||
- s7.2:**此事件对应用程序至关重要。这一事件发生时,适合关闭所有已创建的套接字并进行重新创建。**
|
||||
|
||||
|
||||
8. Wi-Fi 清理阶段
|
||||
++++++++++++++++++++++++++++
|
||||
|
||||
- s8.1:调用函数 :cpp:func:`esp_wifi_disconnect()` 断开 Wi-Fi 连接。
|
||||
- s8.2:调用函数 :cpp:func:`esp_wifi_stop()` 终止 Wi-Fi 驱动程序。
|
||||
- s8.3:调用函数 :cpp:func:`esp_wifi_deinit()` 清理 Wi-Fi 驱动程序。
|
||||
|
||||
|
||||
.. _wifi-scan:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi 扫描
|
||||
----------------------------------
|
||||
|
||||
目前,仅 station 或 station/AP 共存模式支持 :cpp:func:`esp_wifi_scan_start()` API。
|
||||
|
||||
扫描类型
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 15 50
|
||||
|
||||
* - 模式
|
||||
- 描述
|
||||
* - 主动扫描
|
||||
- 通过发送 probe request 进行扫描。该模式为默认的扫描模式。
|
||||
* - 被动扫描
|
||||
- 不发送 probe request。跳至某一特定信道并等待 beacon。应用程序可通过 :cpp:type:`wifi_scan_config_t` 中的 scan_type 字段使能被动扫描。
|
||||
* - 前端扫描
|
||||
- 在 station 模式下 Wi-Fi 未连接时,可进行前端扫描。Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。
|
||||
* - 后端扫描
|
||||
- 在 station 模式或 station/AP 共存模式下 Wi-Fi 已连接时,可进行后端扫描。Wi-Fi 驱动程序决定进行前端扫描还是后端扫描,应用程序无法配置这两种模式。
|
||||
* - 全信道扫描
|
||||
- 扫描所有信道。:cpp:type:`wifi_scan_config_t` 中的 channel 字段为 0 时,当前模式为全信道扫描。
|
||||
* - 特定信道扫描
|
||||
- 仅扫描特定的信道。:cpp:type:`wifi_scan_config_t` 中的 channel 字段为 1-14 时,当前模式为特定信道扫描。
|
||||
|
||||
上表中的扫描模式可以任意组合,因此共有 8 种不同扫描方式:
|
||||
|
||||
- 全信道后端主动扫描
|
||||
- 全信道后端被动扫描
|
||||
- 全信道前端主动扫描
|
||||
- 全信道后端被动扫描
|
||||
- 特定信道后端主动扫描
|
||||
- 特定信道后端被动扫描
|
||||
- 特定信道前端主动扫描
|
||||
- 特定信道前端被动扫描
|
||||
|
||||
扫描配置
|
||||
+++++++++++++++++
|
||||
|
||||
扫描类型与其他扫描属性通过函数 :cpp:func:`esp_wifi_scan_start()` 进行配置。下表详细描述了函数 :cpp:type:`wifi_scan_config_t` 各字段信息。
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 15 50
|
||||
|
||||
* - 字段
|
||||
- 描述
|
||||
* - ssid
|
||||
- 如果该字段的值不为 NULL,则仅可扫描到具有相同 SSID 值的 AP。
|
||||
* - bssid
|
||||
- 如果该字段的值不为 NULL,则仅可扫描到具有相同 BSSID 值的 AP。
|
||||
* - channel
|
||||
- 如果该字段值为 0,将进行全信道扫描;反之,将针对特定信道进行扫描。
|
||||
* - show_hidden
|
||||
- 如果该字段值为 0,本次扫描将忽略具有隐藏 SSID 的 AP;反之,这些 AP 也会在扫描时被视为正常 AP。
|
||||
* - scan_type
|
||||
- 如果该字段值为为 WIFI_SCAN_TYPE_ACTIVE,则本次扫描为主动扫描;反之,将被视为被动扫描。
|
||||
* - scan_time
|
||||
- 该字段用于控制每个信道的扫描时间。
|
||||
|
||||
被动扫描时,scan_time.passive 字段负责为每个信道指定扫描时间。
|
||||
|
||||
主动扫描时,每个信道的扫描时间如下列表所示。其中,min 代表 scan_time_active_min,max 代表 scan_time_active_max。
|
||||
|
||||
- min=0, max=0:每个信道的扫描时间为 120 ms。
|
||||
- min>0, max=0:每个信道的扫描时间为 120 ms。
|
||||
- min=0, max>0:每个信道的扫描时间为 ``max`` ms。
|
||||
- min>0, max>0:每个信道扫描的最短时间为 ``min`` ms。 如果在这段时间内未找到 AP,将跳转至下一个信道。如这段时间内找到 AP,则该信道的扫描时间为 ``max`` ms。
|
||||
|
||||
如希望提升 Wi-Fi 扫描性能,则可修改上述两个参数。
|
||||
|
||||
|
||||
调用 API :cpp:func:`esp_wifi_set_config()` 可全局配置一些扫描属性,请参阅 :ref:`Station 基本配置 <station-basic-configuration>`。
|
||||
|
||||
在所有信道中扫描全部 AP(前端)
|
||||
+++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
场景:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: 所有 Wi-Fi 信道的前端扫描
|
||||
:align: center
|
||||
|
||||
seqdiag foreground-scan-all-channels {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 160;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
APP_TASK -> WIFI_TASK [label="1.1 > 配置国家代码"];
|
||||
APP_TASK -> WIFI_TASK [label="1.2 > 扫描配置"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.1 > 扫描信道 1"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.2 > 扫描信道 2"];
|
||||
WIFI_TASK -> WIFI_TASK [label="..."];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.x > 扫描信道 N"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"];
|
||||
APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"];
|
||||
}
|
||||
|
||||
|
||||
上述场景中描述了全信道前端扫描过程。仅 station 模式支持前端扫描,该模式下 station 未连接任何 AP。前端扫描还是后端扫描完全由 Wi-Fi 驱动程序决定,应用程序无法配置这一模式。
|
||||
|
||||
详细描述:
|
||||
|
||||
扫描配置阶段
|
||||
**************************
|
||||
|
||||
- s1.1:如果默认的国家信息有误,调用函数 :cpp:func:`esp_wifi_set_country()` 进行配置。请参阅 :ref:`Wi-Fi 国家/地区代码 <wifi-country-code>`。
|
||||
- s1.2:调用函数 :cpp:func:`esp_wifi_scan_start()` 配置扫描信息,可参阅 `扫描配置`_。该场景为全信道扫描,将 SSID/BSSID/channel 设置为 0 即可。
|
||||
|
||||
|
||||
Wi-Fi 驱动程序内部扫描阶段
|
||||
**************************************
|
||||
|
||||
- s2.1:Wi-Fi 驱动程序切换至信道 1,此时的扫描类型为 WIFI_SCAN_TYPE_ACTIVE,同时发送一个 probe request。反之,Wi-Fi 将等待接收 AP beacon。Wi-Fi 驱动程序将在信道 1 停留一段时间。min/max 扫描时间中定义了 Wi-Fi 在信道 1 中停留的时间长短,默认为 120 ms。
|
||||
- s2.2:Wi-Fi 驱动程序跳转至信道 2,并重复进行 s2.1 中的步骤。
|
||||
- s2.3:Wi-Fi 驱动程序扫描最后的信道 N,N 的具体数值由步骤 s1.1 中配置的国家代码决定。
|
||||
|
||||
扫描完成后事件处理阶段
|
||||
*********************************
|
||||
|
||||
- s3.1:当所有信道扫描全部完成后,将产生 :ref:`WIFI_EVENT_SCAN_DONE <wifi-event-scan-done>` 事件。
|
||||
- s3.2:应用程序的事件回调函数告知应用程序任务已接收到 :ref:`WIFI_EVENT_SCAN_DONE <wifi-event-scan-done>` 事件。调用函数 :cpp:func:`esp_wifi_scan_get_ap_num()` 获取在本次扫描中找到的 AP 数量。然后,分配出足够的条目,并调用函数 :cpp:func:`esp_wifi_scan_get_ap_records()` 获取 AP 记录。请注意,一旦调用 :cpp:func:`esp_wifi_scan_get_ap_records()`,Wi-Fi 驱动程序中的 AP 记录将被释放。但是,请不要在单个扫描完成事件中重复调用两次 :cpp:func:`esp_wifi_scan_get_ap_records()`。反之,如果扫描完成事件发生后未调用 :cpp:func:`esp_wifi_scan_get_ap_records()`,则 Wi-Fi 驱动程序中的 AP 记录不会被释放。因此,请务必确保调用函数 :cpp:func:`esp_wifi_scan_get_ap_records()`,且仅调用一次。
|
||||
|
||||
在所有信道上扫描全部 AP(后端)
|
||||
++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
场景:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: 所有 Wi-Fi 信道的后端扫描
|
||||
:align: center
|
||||
|
||||
seqdiag background-scan-all-channels {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 160;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
APP_TASK -> WIFI_TASK [label="1.1 > 配置国家代码"];
|
||||
APP_TASK -> WIFI_TASK [label="1.2 > 扫描配置"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.1 > 扫描信道 1"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.2 > 返回主信道 H"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.3 > 扫描信道 2"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.4 > 返回主信道 H"];
|
||||
WIFI_TASK -> WIFI_TASK [label="..."];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.x-1 > 扫描信道 N"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.x > 返回主信道 H"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"];
|
||||
APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"];
|
||||
}
|
||||
|
||||
上述场景为一次全信道后端扫描。与 `在所有信道中扫描全部 AP(前端)`_ 相比,全信道后端扫描的不同之处在于:在跳至下一个信道之前,Wi-Fi 驱动程序会先返回主信道停留 30 ms,以便 Wi-Fi 连接有一定的时间发送/接收数据。
|
||||
|
||||
在所有信道中扫描特定 AP
|
||||
+++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
场景:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: 扫描特定的 Wi-Fi 信道
|
||||
:align: center
|
||||
|
||||
seqdiag scan-specific-channels {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 160;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
APP_TASK -> WIFI_TASK [label="1.1 > 配置国家代码"];
|
||||
APP_TASK -> WIFI_TASK [label="1.2 > 扫描配置"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.1 > 扫描信道 C1"];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.2 > 扫描信道 C2"];
|
||||
WIFI_TASK -> WIFI_TASK [label="..."];
|
||||
WIFI_TASK -> WIFI_TASK [label="2.x > 扫描信道 CN,或找到 AP"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"];
|
||||
APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"];
|
||||
}
|
||||
|
||||
该扫描过程与 `在所有信道中扫描全部 AP(前端)`_ 相似。区别在于:
|
||||
|
||||
- s1.1:在步骤 1.2 中,目标 AP 将配置为 SSID/BSSID。
|
||||
- s2.1 ~ s2.N:每当 Wi-Fi 驱动程序扫描某个 AP 时,它将检查该 AP 是否为目标 AP。如果本次扫描类型为 ``WIFI_FAST_SCAN``,且确认已找到目标 AP,则将产生扫描完成事件,同时结束本次扫描;反之,扫描将继续。请注意,第一个扫描的信道可能不是信道 1,因为 Wi-Fi 驱动程序会优化扫描顺序。
|
||||
|
||||
如果有多个匹配目标 AP 信息的 AP,例如:碰巧扫描到两个 SSID 为 "ap" 的 AP。如果本次扫描类型为 ``WIFI_FAST_SCAN``,则仅可找到第一个扫描到的 "ap";如果本次扫描类型为 ``WIFI_ALL_CHANNEL_SCAN``,则两个 "ap“ 都将被找到,且 station 将根据配置规则连接至其需要连接的 "ap",请参阅 :ref:`Station 基本配置 <station-basic-configuration>`。
|
||||
|
||||
你可以在任意信道中扫描某个特定的 AP,或扫描该信道中的所有 AP。这两种扫描过程也较为相似。
|
||||
|
||||
.. _scan-in-wifi-connect:
|
||||
|
||||
在 Wi-Fi 连接模式下扫描
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
调用函数 :cpp:func:`esp_wifi_connect()` 后,Wi-Fi 驱动程序将首先尝试扫描已配置的 AP。Wi-Fi 连接模式下的扫描过程与 `在所有信道中扫描特定 AP`_ 过程相同,但连接模式下扫描结束后将不会产生扫描完成事件。如果已找到目标 AP,则 Wi-Fi 驱动程序将开始 Wi-Fi 连接;反之,将产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件。请参阅 `在所有信道中扫描特定 AP`_。
|
||||
|
||||
在阻塞模式下扫描
|
||||
++++++++++++++++++++
|
||||
|
||||
如果函数 :cpp:func:`esp_wifi_scan_start()` 中的 block 参数为 "true",则扫描将以阻塞模式进行,应用任务会被阻塞,直到扫描完成。阻塞模式下的扫描和正常扫描相似,不同之处在于,阻塞模式下扫描完成之后将不会触发扫描完成事件。
|
||||
|
||||
并行扫描
|
||||
+++++++++++++
|
||||
|
||||
有时,可能会有两个应用程序任务同时调用函数 :cpp:func:`esp_wifi_scan_start()`,或者某个应用程序任务在获取扫描完成事件之前再次调用了函数 :cpp:func:`esp_wifi_scan_start()`。这两种情况都有可能会发生。**但是,Wi-Fi 驱动程序并不足以支持多个并行的扫描。因此,应避免上述并行扫描**。随着 {IDF_TARGET_NAME} 的 Wi-Fi 功能不断提升,未来的版本中可能会增加并行扫描支持。
|
||||
|
||||
.. _scan-when-wifi-is-connecting:
|
||||
|
||||
连接 Wi-Fi 时扫描
|
||||
+++++++++++++++++++++++++++++++
|
||||
|
||||
如果 Wi-Fi 正在连接,则调用函数 :cpp:func:`esp_wifi_scan_start()` 后扫描将立即失败,因为 Wi-Fi 连接优先级高于扫描。如果扫描是因为 Wi-Fi 连接而失败的,此时推荐采取的策略为:等待一段时间后重试。因为一旦 Wi-Fi 连接完成后,扫描将立即成功。
|
||||
|
||||
但是,延时重试策略并非万无一失。试想以下场景:
|
||||
|
||||
- 如果 station 正在连接一个不存在的 AP,或正在使用错误的密码连接一个 AP,此时将产生事件 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>`。
|
||||
- 接收到断开连接事件后,应用程序调用函数 :cpp:func:`esp_wifi_connect()` 进行重新连接。
|
||||
- 而另一个应用程序任务(如,控制任务)调用了函数 :cpp:func:`esp_wifi_scan_start()` 进行扫描。这种情况下,每一次扫描都会立即失败,因为 station 一直处于正在连接状态。
|
||||
- 扫描失败后,应用程序将等待一段时间后进行重新扫描。
|
||||
|
||||
上述场景中的扫描永远不会成功,因为 Wi-Fi 一直处于正在连接过程中。因此,如果你的应用程序也可能发生相似的场景,那么就需要为其配置一个更佳的重新连接策略。例如:
|
||||
|
||||
- 应用程序可以定义一个连续重新连接次数的最大值,当重新连接的次数达到这个最大值时,立刻停止重新连接。
|
||||
- 应用程序可以选择在前 N 次连续重连时立即进行重连,然后延迟一段时间后再次尝试重连。
|
||||
|
||||
可以给应用程序定义其特殊的重新连接策略,以防止扫描无法成功。请参阅 :ref:`Wi-Fi 重新连接 <wifi-reconnect>`。
|
||||
|
||||
.. _wifi-station-connecting-scenario:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi Station 连接场景
|
||||
------------------------------------------------------------
|
||||
|
||||
该场景仅针对在扫描阶段只找到一个目标 AP 的情况,对于多个相同 SSID AP 的情况,请参阅 :ref:`{IDF_TARGET_NAME} Wi-Fi Station 在发现多个 AP 时的连接策略 <wifi-station-connecting-when-multiple-aps-are-found>`。
|
||||
|
||||
通常,应用程序无需关心这一连接过程。如感兴趣,可参看下述简介。
|
||||
|
||||
场景:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: Wi-Fi station 连接过程
|
||||
:align: center
|
||||
|
||||
seqdiag station-connecting-process {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 160;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
AP [label = "AP"];
|
||||
|
||||
=== 1. 扫描阶段 ===
|
||||
WIFI_TASK -> WIFI_TASK [label="1.1 > 扫描"];
|
||||
EVENT_TASK <- WIFI_TASK [label="1.2 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
=== 2. 认证阶段 ===
|
||||
WIFI_TASK -> AP [label="2.1 > Auth request"];
|
||||
EVENT_TASK <- WIFI_TASK [label="2.2 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
WIFI_TASK <- AP [label="2.3 > Auth response"];
|
||||
EVENT_TASK <- WIFI_TASK [label="2.4 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
=== 3. 关联阶段 ===
|
||||
WIFI_TASK -> AP [label="3.1 > Assoc request"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.2 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
WIFI_TASK <- AP [label="3.3 > Assoc response"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.4 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
=== 4. 四次握手阶段 ===
|
||||
EVENT_TASK <- WIFI_TASK [label="4.1 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
WIFI_TASK <- AP [label="4.2 > 1/4 EAPOL"];
|
||||
WIFI_TASK -> AP [label="4.3 > 2/4 EAPOL"];
|
||||
EVENT_TASK <- WIFI_TASK [label="4.4 > WIFI_EVENT_STA_DISCONNECTED"];
|
||||
WIFI_TASK <- AP [label="4.5 > 3/4 EAPOL"];
|
||||
WIFI_TASK -> AP [label="4.6 > 4/4 EAPOL"];
|
||||
EVENT_TASK <- WIFI_TASK [label="4.7 > WIFI_EVENT_STA_CONNECTED"];
|
||||
}
|
||||
|
||||
|
||||
扫描阶段
|
||||
+++++++++++++++++++++
|
||||
|
||||
- s1.1:Wi-Fi 驱动程序开始在“Wi-Fi 连接”模式下扫描。详细信息请参阅 :ref:`在 Wi-Fi 连接模式下扫描 <scan-in-wifi-connect>`。
|
||||
- s1.2:如果未找到目标 AP,将产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件,原因代码可能为 ``WIFI_REASON_NO_AP_FOUND``、``WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY``、``WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD`` 或 ``WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD``, 具体取决于 station 的配置。请参阅 `Wi-Fi 原因代码`_。
|
||||
|
||||
认证阶段
|
||||
+++++++++++++++++++++
|
||||
|
||||
- s2.1:发送认证请求数据包并使能认证计时器。
|
||||
- s1.2:如果在认证计时器超时之前未接收到认证响应数据包,将产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件,且原因代码为 ``WIFI_REASON_AUTH_EXPIRE``。请参阅 `Wi-Fi 原因代码`_。
|
||||
- s2.3:接收到认证响应数据包,且认证计时器终止。
|
||||
- s2.4:AP 在响应中拒绝认证且产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件,原因代码为 ``WIFI_REASON_AUTH_FAIL`` 或为 AP 指定的其它原因。请参阅 `Wi-Fi 原因代码`_。
|
||||
|
||||
关联阶段
|
||||
+++++++++++++++++++++
|
||||
|
||||
- s3.1:发送关联请求并使能关联计时器。
|
||||
- s3.2:如果在关联计时器超时之前未接收到关联响应,将产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件,且原因代码为 ``WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY``。请参阅 `Wi-Fi 原因代码`_。
|
||||
- s3.3:接收到关联响应,且关联计时器终止。
|
||||
- s3.4:AP 在响应中拒绝关联且产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件,原因代码将在关联响应中指定。请参阅 `Wi-Fi 原因代码`_。
|
||||
|
||||
|
||||
四次握手阶段
|
||||
++++++++++++++++++++++++++
|
||||
|
||||
- s4.1:使能握手定时器,定时器终止之前未接收到 1/4 EAPOL,此时将产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件,且原因代码为 ``WIFI_REASON_HANDSHAKE_TIMEOUT``。请参阅 `Wi-Fi 原因代码`_。
|
||||
- s4.2:接收到 1/4 EAPOL。
|
||||
- s4.3:station 回复 2/4 EAPOL。
|
||||
- s4.4:如果在握手定时器终止之前未接收到 3/4 EAPOL,将产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件,且原因代码为 ``WIFI_REASON_HANDSHAKE_TIMEOUT``。请参阅 `Wi-Fi 原因代码`_。
|
||||
- s4.5:接收到 3/4 EAPOL。
|
||||
- s4.6:station 回复 4/4 EAPOL。
|
||||
- s4.7:station 产生 :ref:`WIFI_EVENT_STA_CONNECTED <wifi-event-sta-connected>` 事件。
|
||||
|
||||
|
||||
.. _esp_wifi_reason_code:
|
||||
|
||||
Wi-Fi 原因代码
|
||||
+++++++++++++++++++++
|
||||
|
||||
下表罗列了 {IDF_TARGET_NAME} 中定义的原因代码。其中,第一列为 :component_file:`esp_wifi/include/esp_wifi_types.h` 中定义的宏名称。名称中省去了前缀 ``WIFI_REASON``,也就是说,名称 ``UNSPECIFIED`` 实际应为 ``WIFI_REASON_UNSPECIFIED``,以此类推。第二列为原因代码的相应数值,该数值与 IEEE 802.11-2020 第 9.4.1.7 节中的定义一致 。(更多详细信息,请参阅前文描述。)最后一列为原因的描述。原因代码从 200 开始为乐鑫自定义的原因代码,这些代码不属于 IEEE 802.11-2020 标准的一部分。
|
||||
|
||||
另请注意,REASON_NO_AP_FOUND_XXX 代码按照重要性递增排列。因此,如果单个接入点(AP)因上述多种原因而导致连接失败,则会报告其中较为重要的原因代码。此外,如果有多个接入点满足标识条件,但它们因上述不同原因均连接失败,则报告的原因代码是因最不重要的原因代码而导致连接失败的接入点的代码,因为这是最接近成功连接的情况。
|
||||
|
||||
以下原因代码被重命名为较短的形式以适应表格页面宽度:
|
||||
|
||||
- TRANSMISSION_LINK_ESTABLISHMENT_FAILED : TX_LINK_EST_FAILED
|
||||
- NO_AP_FOUND_W_COMPATIBLE_SECURITY : NO_AP_FOUND_SECURITY
|
||||
- NO_AP_FOUND_IN_AUTHMODE_THRESHOLD : NO_AP_FOUND_AUTHMODE
|
||||
- NO_AP_FOUND_IN_RSSI_THRESHOLD : NO_AP_FOUND_RSSI
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 41 10 49
|
||||
:class: longtable
|
||||
|
||||
* - 原因代码
|
||||
- 数值
|
||||
- 描述
|
||||
* - UNSPECIFIED
|
||||
- 1
|
||||
- 出现内部错误,例如:内存已满,内部发送失败,或该原因已被远端接收等。
|
||||
* - AUTH_EXPIRE
|
||||
- 2
|
||||
- 先前的 authentication 已失效。
|
||||
|
||||
对于 ESP station,出现以下情况时将报告该代码:
|
||||
|
||||
- authentication 超时;
|
||||
- 从 AP 接收到该代码。
|
||||
|
||||
对于 ESP AP,出现以下情况时将报告该代码:
|
||||
|
||||
- 在过去五分钟之内,AP 未从 station 接收到任何数据包;
|
||||
- 由于调用了函数 :cpp:func:`esp_wifi_stop()` 导致 AP 终止;
|
||||
- 由于调用了函数 :cpp:func:`esp_wifi_deauth_sta()` 导致 station 的 authentication 取消。
|
||||
* - AUTH_LEAVE
|
||||
- 3
|
||||
- authentication 取消,因为发送端 station 正在离开(或已经离开)。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - DISASSOC_DUE_TO_INACTIVITY
|
||||
- 4
|
||||
- 因为 AP 不活跃,association 取消。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 关联超时。
|
||||
- 从 AP 接收到该代码。
|
||||
|
||||
* - ASSOC_TOOMANY
|
||||
- 5
|
||||
- association 取消,因为 AP 无法同时处理所有当前已关联的 STA。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
|
||||
对于 ESP AP,出现以下情况时将报告该代码:
|
||||
|
||||
- 与 AP 相关联的 station 数量已到达 AP 可支持的最大值。
|
||||
* - CLASS2_FRAME_FROM_NONAUTH_STA
|
||||
- 6
|
||||
- 从一个未认证 station 接收到 class-2 frame。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
|
||||
对于 ESP AP,出现以下情况时将报告该代码:
|
||||
|
||||
- AP 从一个未认证 station 接收到数据包。
|
||||
* - CLASS3_FRAME_FROM_NONASSOC_STA
|
||||
- 7
|
||||
- 从一个未关联 station 接收到的 class-3 frame。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
|
||||
对于 ESP AP,出现以下情况时将报告该代码:
|
||||
|
||||
- AP 从未关联 station 接收到数据包。
|
||||
* - ASSOC_LEAVE
|
||||
- 8
|
||||
- association 取消,因为发送端 station 正在离开(或已经离开)BSS。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
- 由于调用 :cpp:func:`esp_wifi_disconnect()` 和其它 API,station 断开连接。
|
||||
* - ASSOC_NOT_AUTHED
|
||||
- 9
|
||||
- station 的 re(association) 请求未被响应 station 认证。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
|
||||
对于 ESP AP,出现以下情况时将报告该代码:
|
||||
|
||||
- AP 从一个已关联,但未认证的 station 接收到数据包。
|
||||
* - DISASSOC_PWRCAP_BAD
|
||||
- 10
|
||||
- association 取消,因为无法接收功率能力 (Power Capability) 元素中的信息。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - DISASSOC_SUPCHAN_BAD
|
||||
- 11
|
||||
- association 取消,因为无法接收支持的信道 (Supported Channels) 元素中的信息。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - BSS_TRANSITION_DISASSOC
|
||||
- 12
|
||||
- AP 希望切换到另一个 AP,作为 BTM 过程的一部分发送。请注意,当 station 发送 BTM 请求并切换到另一个 AP 时,将报告 ROAMING 原因代码,而不是此代码。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - IE_INVALID
|
||||
- 13
|
||||
- 无效元素,即内容不符合 Wi-Fi 协议中帧格式 (Frame formats) 章节所描述标准的元素。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
|
||||
对于 ESP AP,出现以下情况时将报告该代码:
|
||||
|
||||
- AP 解析了一个错误的 WPA 或 RSN IE。
|
||||
* - MIC_FAILURE
|
||||
- 14
|
||||
- 消息完整性代码 (MIC) 出错。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - 4WAY_HANDSHAKE_TIMEOUT
|
||||
- 15
|
||||
- 四次握手超时。由于某些历史原因,在 ESP 中该原因代码实为 ``WIFI_REASON_HANDSHAKE_TIMEOUT``。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 握手超时。
|
||||
- 从 AP 接收到该代码。
|
||||
* - GROUP_KEY_UPDATE_TIMEOUT
|
||||
- 16
|
||||
- 组密钥 (Group-Key) 握手超时。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - IE_IN_4WAY_DIFFERS
|
||||
- 17
|
||||
- 四次握手中产生的元素与 (re-)association 后的 request/probe 以及 response/beacon frame 中的信息不同。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
- station 发现四次握手的 IE 与 (re-)association 后的 request/probe 以及 response/beacon frame 中的 IE 不同。
|
||||
* - GROUP_CIPHER_INVALID
|
||||
- 18
|
||||
- 无效组密文。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - PAIRWISE_CIPHER_INVALID
|
||||
- 19
|
||||
- 无效成对密文。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - AKMP_INVALID
|
||||
- 20
|
||||
- 无效 AKMP。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
- 从 AP 接收到该代码。
|
||||
* - UNSUPP_RSN_IE_VERSION
|
||||
- 21
|
||||
- 不支持的 RSNE 版本。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - INVALID_RSN_IE_CAP
|
||||
- 22
|
||||
- 无效的 RSNE 性能。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - 802_1X_AUTH_FAILED
|
||||
- 23
|
||||
- IEEE 802.1X. authentication 失败。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
|
||||
对于 ESP AP,出现以下情况时将报告该代码:
|
||||
|
||||
- IEEE 802.1X. authentication 失败。
|
||||
* - CIPHER_SUITE_REJECTED
|
||||
- 24
|
||||
- 因安全策略,安全密钥算法套件 (cipher suite) 被拒。
|
||||
|
||||
对于 ESP station,出现以下情况时报告该代码:
|
||||
|
||||
- 从 AP 接收到该代码。
|
||||
* - TDLS_PEER_UNREACHABLE
|
||||
- 25
|
||||
- 通过 TDLS 直连无法到达 TDLS 对端 STA,导致 TDLS 直连中断。
|
||||
* - TDLS_UNSPECIFIED
|
||||
- 26
|
||||
- 不明原因的 TDLS 直连中断。
|
||||
* - SSP_REQUESTED_DISASSOC
|
||||
- 27
|
||||
- association 取消,由于会话被 SSP request 终止。
|
||||
* - NO_SSP_ROAMING_AGREEMENT
|
||||
- 28
|
||||
- association 取消,由于缺乏 SSP 漫游认证。
|
||||
* - BAD_CIPHER_OR_AKM
|
||||
- 29
|
||||
- 请求的服务被拒绝,由于 SSP 密码套件或者 AKM 的需求。
|
||||
* - NOT_AUTHORIZED_THIS_LO CATION
|
||||
- 30
|
||||
- 请求的服务在此位置未得到授权。
|
||||
* - SERVICE_CHANGE_PRECLUDES_TS
|
||||
- 31
|
||||
- TS 被删除,原因是:BSS 服务特性或者运行模式改变导致 Qos AP 缺少足够的带宽给 Qos STA 使用(例如:一个HT BSS 从 40 MHz 的信道切换到 20 MHz 的信道)。
|
||||
* - UNSPECIFIED_QOS
|
||||
- 32
|
||||
- association 取消,由于不明确的 QoS 相关原因。
|
||||
* - NOT_ENOUGH_BANDWIDTH
|
||||
- 33
|
||||
- association 取消,由于 QoS AP 缺少足够的带宽给该 QoS STA 使用。
|
||||
* - MISSING_ACKS
|
||||
- 34
|
||||
- association 取消,原因是:大量的帧需要被确认,但由于 AP 传输或者糟糕的信道条件而没有被确认。
|
||||
* - EXCEEDED_TXOP
|
||||
- 35
|
||||
- association 取消,由于 STA 的传输超过了 TXOPs 的限制。
|
||||
* - STA_LEAVING
|
||||
- 36
|
||||
- 请求 STA 离开了 BSS 或者重置了。
|
||||
* - END_BA
|
||||
- 37
|
||||
- 请求 STA 不再使用该流或者会话。
|
||||
* - UNKNOWN_BA
|
||||
- 38
|
||||
- 请求 STA 使用一种尚未完成的机制接收帧。
|
||||
* - TIMEOUT
|
||||
- 39
|
||||
- 对端 STA 的请求超时。
|
||||
* - Reserved
|
||||
- 40 ~ 45
|
||||
- 根据 IEEE 802.11-2020 协议保留。
|
||||
* - PEER_INITIATED
|
||||
- 46
|
||||
- 在 Disassociation 帧中:已达到授权访问限制。
|
||||
* - AP_INITIATED
|
||||
- 47
|
||||
- 在 Disassociation 帧中:外部服务需求。
|
||||
* - INVALID_FT_ACTION_FRAME_COUNT
|
||||
- 48
|
||||
- 无效的 FT Action 帧计数。
|
||||
* - INVALID_PMKID
|
||||
- 49
|
||||
- 无效的成对主密钥标识符(PMKID)。
|
||||
* - INVALID_MDE
|
||||
- 50
|
||||
- 无效的 MDE。
|
||||
* - INVALID_FTE
|
||||
- 51
|
||||
- 无效的 FTE。
|
||||
* - TX_LINK_EST_FAILED
|
||||
- 67
|
||||
- 在备用信道中建立传输链路失败。
|
||||
* - ALTERATIVE_CHANNEL_OCCUPIED
|
||||
- 68
|
||||
- 备用信道被占用。
|
||||
* - BEACON_TIMEOUT
|
||||
- 200
|
||||
- 乐鑫特有的 Wi-Fi 原因代码: 当 station 连续失去 N 个 beacon,将中断连接并报告该代码。
|
||||
* - NO_AP_FOUND
|
||||
- 201
|
||||
- 乐鑫特有的 Wi-Fi 原因代码: 当 station 未扫描到目标 AP 时,将报告该代码。
|
||||
* - AUTH_FAIL
|
||||
- 202
|
||||
- 乐鑫特有的 Wi-Fi 原因代码: authentication 失败,但并非由超时而引发。
|
||||
* - ASSOC_FAIL
|
||||
- 203
|
||||
- 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 DISASSOC_DUE_TO_INACTIVITY 或 ASSOC_TOOMANY 引发。
|
||||
* - HANDSHAKE_TIMEOUT
|
||||
- 204
|
||||
- 乐鑫特有的 Wi-Fi 原因代码: 握手失败,与 WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT 中失败原因相同。
|
||||
* - CONNECTION_FAIL
|
||||
- 205
|
||||
- 乐鑫特有的 Wi-Fi 原因代码: AP 连接失败。
|
||||
* - AP_TSF_RESET
|
||||
- 206
|
||||
- 乐鑫特有的 Wi-Fi 原因代码:由于 AP 的 TSF 重置导致断开连接。
|
||||
* - ROAMING
|
||||
- 207
|
||||
- 乐鑫特有的 Wi-Fi 原因代码:station 正在漫游到另一个 AP,此原因代码仅供参考,station 将自动切换到另一个 AP。
|
||||
* - ASSOC_COMEBACK_TIME_TOO_LONG
|
||||
- 208
|
||||
- 乐鑫特有的 Wi-Fi 原因代码:当关联响应中的 Assoc 回来时间过长时,将报告此原因代码。
|
||||
* - SA_QUERY_TIMEOUT
|
||||
- 209
|
||||
- 乐鑫特有的 Wi-Fi 原因代码:当 ESP station 发送的 SA 查询未收到 AP 的回复时,将报告此原因代码。
|
||||
* - NO_AP_FOUND_SECURITY
|
||||
- 210
|
||||
- 乐鑫特有的 Wi-Fi 原因代码:当找到符合标识条件(例如 SSID)的 AP,但由于安全配置不兼容导致连接被拒绝时,将报告 NO_AP_FOUND_W_COMPATIBLE_SECURITY。可能的情况包括:
|
||||
|
||||
- 接入点提供 WEP 安全性,但 station 密码不符合 WEP 要求。
|
||||
- station 配置为开放模式,但接入点以安全模式广播。
|
||||
- 接入点使用企业安全性,但我们未设置相应的企业配置,反之亦然。
|
||||
- station 配置为 SAE-PK,但接入点不支持 SAE-PK。
|
||||
- station 配置为 SAE-H2E,但 AP 仅支持 WPA3-PSK 或 WPA3-WPA2-PSK。
|
||||
- station 配置为安全模式(密码或企业模式),但扫描中找到的 AP 是开放模式。
|
||||
- station 配置为 SAE HnP,但 AP 仅支持 H2E。
|
||||
- station 禁用 H2E,但 AP 是 WPA3-EXT-PSK,需支持 H2E。
|
||||
- 接入点需要 PMF,但 station 未配置为支持 PMF。
|
||||
- station 要求 PMF,但接入点未配置为支持 PMF。
|
||||
- 接入点使用不支持的组管理/对等加密算法。
|
||||
- station 未启用 OWE,但发现的 AP 使用 OWE 模式。
|
||||
- 接入点在信标中广播了无效的 RSNXE 信息。
|
||||
- 接入点处于独立 BSS 模式。
|
||||
|
||||
* - NO_AP_FOUND_AUTHMODE
|
||||
- 211
|
||||
- 乐鑫特有的 Wi-Fi 原因代码:当找到符合标识条件(例如 SSID)的 AP,但未满足 wifi_config_t 中设置的身份验证模式阈值时,将报告 NO_AP_FOUND_IN_AUTHMODE_THRESHOLD。
|
||||
* - NO_AP_FOUND_RSSI
|
||||
- 212
|
||||
- 乐鑫特有的 Wi-Fi 原因代码:当找到符合标识条件(例如 SSID)的 AP,但未满足 wifi_config_t 中设置的 RSSI 阈值时,将报告 NO_AP_FOUND_IN_RSSI_THRESHOLD。
|
||||
|
||||
与密码错误有关的 Wi-Fi 原因代码
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
下表罗列了与密码错误相关的 Wi-Fi 原因代码。
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 10 40
|
||||
|
||||
* - 原因代码
|
||||
- 数值
|
||||
- 描述
|
||||
* - 4WAY_HANDSHAKE_TIMEOUT
|
||||
- 15
|
||||
- 四次握手超时。STA 在连接加密的 AP 的时候设置了错误的密码。
|
||||
* - NO_AP_FOUND
|
||||
- 201
|
||||
- 这可能与以下两种场景中的密码错误有关:
|
||||
|
||||
- STA 连接到未加密的 AP 时设置了密码。
|
||||
- STA 连接到加密的 AP 时未设置密码。
|
||||
* - HANDSHAKE_TIMEOUT
|
||||
- 204
|
||||
- 四次握手失败。
|
||||
|
||||
与低 RSSI 有关的 Wi-Fi 原因代码
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
下表罗列了与低 RSSI 相关的 Wi-Fi 原因代码。
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 10 40
|
||||
|
||||
* - 原因代码
|
||||
- 数值
|
||||
- 描述
|
||||
* - NO_AP_FOUND_IN_RSSI_THRESHOLD
|
||||
- 212
|
||||
- 低 RSSI 导致 station 无法扫描到目标 AP
|
||||
* - HANDSHAKE_TIMEOUT
|
||||
- 204
|
||||
- 四次握手失败。
|
||||
|
||||
.. _wifi-station-connecting-when-multiple-aps-are-found:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi Station 在发现多个 AP 时的连接策略
|
||||
----------------------------------------------------------------------
|
||||
|
||||
该场景与 :ref:`{IDF_TARGET_NAME} Wi-Fi Station 连接场景 <wifi-station-connecting-scenario>` 相似,不同之处在于该场景中不会产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件,除非 station 无法连接所有找到的 AP。
|
||||
|
||||
.. _wifi-reconnect:
|
||||
|
||||
Wi-Fi 重新连接
|
||||
---------------------------
|
||||
|
||||
出于多种原因,station 可能会断开连接,例如:连接的 AP 重新启动等。应用程序应负责重新连接。推荐使用的方法为:在接收到 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件后调用函数 :cpp:func:`esp_wifi_connect()`。
|
||||
|
||||
但有时,应用程序需要更复杂的方式进行重新连接:
|
||||
|
||||
- 如果断开连接事件是由调用函数 :cpp:func:`esp_wifi_disconnect()` 引发的,那么应用程序可能不希望进行重新连接。
|
||||
- 如果 station 随时可能调用函数 :cpp:func:`esp_wifi_scan_start()` 开始扫描,此时就需要一个更佳的重新连接方法,请参阅 :ref:`连接 Wi-Fi 时扫描 <scan-when-wifi-is-connecting>`。
|
||||
|
||||
另一点需要注意的是,如果存在多个具有相同 SSID 的 AP,那么重新连接后可能不会连接到之前的同一个 AP。重新连接时,station 将永远选择最佳的 AP 进行连接。
|
||||
|
||||
Wi-Fi beacon 超时
|
||||
---------------------------
|
||||
|
||||
{IDF_TARGET_NAME} 使用 beacon 超时机制检测 AP 是否活跃。如果 station 在 inactive 时间内未收到所连接 AP 的 beacon,将发生 beacon 超时。inactive 时间通过调用函数 :cpp:func:`esp_wifi_set_inactive_time()` 设置。
|
||||
|
||||
beacon 超时发生后,station 将向 AP 发送 5 个 probe request,如果仍未从 AP 接收到 probe response 或 beacon,station 将与 AP 断开连接并产生 :ref:`WIFI_EVENT_STA_DISCONNECTED <wifi-event-sta-disconnected>` 事件。
|
||||
|
||||
需要注意的是,扫描过程中会重置 beacon 超时所使用的定时器,即扫描过程会影响 :ref:`WIFI_EVENT_STA_BEACON_TIMEOUT <wifi-event-sta-beacon-timeout>` 事件的触发。
|
||||
@@ -0,0 +1,94 @@
|
||||
Wi-Fi MAC 协议
|
||||
==========================
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
Wi-Fi HT20/40
|
||||
-------------------------
|
||||
|
||||
.. only:: esp32 or esp32s2 or esp32c3 or esp32s3 or esp32c6 or esp32c5
|
||||
|
||||
{IDF_TARGET_NAME} 支持 Wi-Fi 带宽 HT20 或 HT40,不支持 HT20/40 共存,调用函数 :cpp:func:`esp_wifi_set_bandwidth()` 可改变 station/AP 的默认带宽。{IDF_TARGET_NAME} station 和 AP 的默认带宽为 HT40。
|
||||
|
||||
station 模式下,实际带宽首先在 Wi-Fi 连接时协商。只有当 station 和所连 AP 都支持 HT40 时,带宽才为 HT40,否则为 HT20。如果所连的 AP 的带宽发生变化,则在不断开 Wi-Fi 连接的情况下再次协商实际带宽。
|
||||
|
||||
同样,在 AP 模式下,在 AP 与所连 station 协商实际带宽。如果 AP 和其中一个 station 支持 HT40, 则为 HT40, 否则为 HT20。
|
||||
|
||||
在 station/AP 共存模式下,station 和 AP 都可独立配置为 HT20/40。如果 station 和 AP 都协商为 HT40,由于 {IDF_TARGET_NAME} 中,station 的优先级总高于 AP,HT40 信道是 station 的信道。例如,AP 的配置带宽为 HT40,配置的主信道为 6,配置的辅助信道为 10。如果,station 所连路由器的主信道为 6、辅助信道为 2,AP 的实际信道将自动更改为主 6 和辅 2。
|
||||
|
||||
理论上,HT40 可以获得更大的吞吐量,因为 HT40 的最大原始 PHY 数据速率为 150 Mbps,而 HT20 为 72 Mbps。但是,如果设备在某些特殊环境中使用,例如,{IDF_TARGET_NAME} 周围其他 Wi-Fi 设备过多,HT40 的性能可能会降低。因此,如果应用程序需要支持相同或类似的情况,建议始终将带宽配置为 HT20。
|
||||
|
||||
.. only:: esp32c5
|
||||
|
||||
.. note::
|
||||
|
||||
当工作在 2.4 GHz + 5 GHz 频段模式(``WIFI_BAND_MODE_AUTO``)时,需要使用函数: :cpp:func:`esp_wifi_set_bandwidths()` 分别设置 2.4 GHz 频段 和 5 GHz 频段的带宽。
|
||||
|
||||
|
||||
.. only:: esp32c2
|
||||
|
||||
{IDF_TARGET_NAME} 仅支持 Wi-Fi 带宽 HT20,不支持 Wi-Fi 带宽 HT40 或 HT20/40 共存。
|
||||
|
||||
Wi-Fi QoS
|
||||
-------------------------
|
||||
|
||||
{IDF_TARGET_NAME} 支持 WFA Wi-Fi QoS 认证所要求的所有必备功能。
|
||||
|
||||
Wi-Fi 协议中定义了四个 AC(访问类别),每个 AC 有各自的优先级访问 Wi-Fi 信道。此外,还定义了映射规则以映射其他协议的 QoS 优先级,例如 802.11D 或 TCP/IP 到 Wi-Fi AC。
|
||||
|
||||
下表描述 {IDF_TARGET_NAME} 中 IP 优先级如何映射到 Wi-Fi AC,还指明此 AC 是否支持 AMPDU。该表按优先级降序排列,即 AC_VO 拥有最高优先级。
|
||||
|
||||
+-----------+---------------------+----------------+
|
||||
| IP 优先级 | Wi-Fi AC | 是否支持 AMPDU |
|
||||
+===========+=====================+================+
|
||||
| 6, 7 | AC_VO (Voice) | 否 |
|
||||
+-----------+---------------------+----------------+
|
||||
| 4, 5 | AC_VI (Video) | 是 |
|
||||
+-----------+---------------------+----------------+
|
||||
| 3, 0 | AC_BE (Best Effort) | 是 |
|
||||
+-----------+---------------------+----------------+
|
||||
| 1, 2 | AC_BK (Background) | 是 |
|
||||
+-----------+---------------------+----------------+
|
||||
|
||||
应用程序可以通过套接字选项 IP_TOS 配置 IP 优先级使用 QoS 功能。下面是使套接字使用 VI 队列的示例::
|
||||
|
||||
const int ip_precedence_vi = 4;
|
||||
const int ip_precedence_offset = 5;
|
||||
int priority = (ip_precedence_vi << ip_precedence_offset);
|
||||
setsockopt(socket_id, IPPROTO_IP, IP_TOS, &priority, sizeof(priority));
|
||||
|
||||
理论上,高优先级的 AC 比低优先级 AC 具有更好的性能,但并非总是如此,下面是一些关于如何使用 Wi-Fi QoS 的建议:
|
||||
|
||||
- 可以把一些真正重要的应用程序流量放到 AC_VO 队列中。避免通过 AC_VO 队列发送大流量。一方面,AC_VO 队列不支持 AMPDU,如果流量很大,性能不会优于其他队列。另一方面,可能会影响同样使用 AC_VO 队列的管理帧。
|
||||
- 避免使用 AMPDU 支持的、两个以上的不同优先级,比如 socket A 使用优先级 0,socket B 使用优先级 1,socket C 使用优先级 2。因为可能需要更多的内存,不是好的设计。具体来说,Wi-Fi 驱动程序可能会为每个优先级生成一个 Block Ack 会话,如果设置了 Block Ack 会话,则需要更多内存。
|
||||
|
||||
|
||||
Wi-Fi AMPDU
|
||||
--------------------
|
||||
|
||||
{IDF_TARGET_NAME} 同时支持接收和发送 AMPDU,AMPDU 可以大大提高 Wi-Fi 的吞吐量。
|
||||
|
||||
通常,应使能 AMPDU。禁用 AMPDU 通常用于调试目的。
|
||||
|
||||
|
||||
Wi-Fi AMSDU
|
||||
-------------------------
|
||||
|
||||
.. only:: not SOC_SPIRAM_SUPPORTED
|
||||
|
||||
{IDF_TARGET_NAME} 支持接收 AMSDU。
|
||||
|
||||
.. only:: SOC_SPIRAM_SUPPORTED
|
||||
|
||||
{IDF_TARGET_NAME} 支持接收和发送 AMSDU。开启 AMSDU 发送比较消耗内存,默认不开启 AMSDU 发送。可通过选项 :ref:`CONFIG_ESP_WIFI_AMSDU_TX_ENABLED` 使能 AMSDU 发送功能, 但是使能 AMSDU 发送依赖于 :ref:`CONFIG_SPIRAM` 。
|
||||
|
||||
Wi-Fi 分片
|
||||
-------------------------
|
||||
|
||||
.. only:: not SOC_WIFI_TXOP_SUPPORT
|
||||
|
||||
{IDF_TARGET_NAME} 支持 Wi-Fi 接收分片,但不支持 Wi-Fi 发送分片。
|
||||
|
||||
.. only:: SOC_WIFI_TXOP_SUPPORT
|
||||
|
||||
{IDF_TARGET_NAME} 支持 Wi-Fi 接收和发送分片。
|
||||
@@ -0,0 +1,100 @@
|
||||
Wi-Fi 模式
|
||||
===============
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
.. _wifi-ap-general-scenario:
|
||||
|
||||
{IDF_TARGET_NAME} Wi-Fi AP 通用场景
|
||||
---------------------------------------------
|
||||
|
||||
下图为 AP 模式下的宏观场景,其中包含不同阶段的具体描述:
|
||||
|
||||
.. seqdiag::
|
||||
:caption: AP 模式下 Wi-Fi 事件场景示例
|
||||
:align: center
|
||||
|
||||
seqdiag sample-scenarios-soft-ap-mode {
|
||||
activation = none;
|
||||
node_width = 80;
|
||||
node_height = 60;
|
||||
edge_length = 140;
|
||||
span_height = 5;
|
||||
default_shape = roundedbox;
|
||||
default_fontsize = 12;
|
||||
|
||||
MAIN_TASK [label = "Main\ntask"];
|
||||
APP_TASK [label = "App\ntask"];
|
||||
EVENT_TASK [label = "Event\ntask"];
|
||||
LwIP_TASK [label = "LwIP\ntask"];
|
||||
WIFI_TASK [label = "Wi-Fi\ntask"];
|
||||
|
||||
=== 1. 初始化阶段 ===
|
||||
MAIN_TASK -> LwIP_TASK [label="1.1> 创建/初始化 LwIP"];
|
||||
MAIN_TASK -> EVENT_TASK [label="1.2> 创建/初始化事件"];
|
||||
MAIN_TASK -> WIFI_TASK [label="1.3> 创建/初始化 Wi-Fi"];
|
||||
MAIN_TASK -> APP_TASK [label="1.4> 创建应用程序任务"];
|
||||
=== 2. 配置阶段 ===
|
||||
MAIN_TASK -> WIFI_TASK [label="2> 配置 Wi-Fi"];
|
||||
=== 3. 启动阶段 ===
|
||||
MAIN_TASK -> WIFI_TASK [label="3.1> 启动 Wi-Fi"];
|
||||
EVENT_TASK <- WIFI_TASK [label="3.2> WIFI_EVENT_AP_START"];
|
||||
APP_TASK <- EVENT_TASK [label="3.3> WIFI_EVENT_AP_START"];
|
||||
=== 4. 连接阶段 ===
|
||||
EVENT_TASK <- WIFI_TASK [label="4.1> WIFI_EVENT_AP_STACONNECTED"];
|
||||
APP_TASK <- EVENT_TASK [label="4.2> WIFI_EVENT_AP_STACONNECTED"];
|
||||
=== 5. 断开阶段 ===
|
||||
EVENT_TASK <- WIFI_TASK [label="5.1> WIFI_EVENT_AP_STADISCONNECTED"];
|
||||
APP_TASK <- EVENT_TASK [label="5.2> WIFI_EVENT_AP_STADISCONNECTED"];
|
||||
APP_TASK -> APP_TASK [label="5.3> 断开处理"];
|
||||
=== 6. 清理阶段 ===
|
||||
APP_TASK -> WIFI_TASK [label="6.1> 断开 Wi-Fi 连接"];
|
||||
APP_TASK -> WIFI_TASK [label="6.2> 终止 Wi-Fi"];
|
||||
APP_TASK -> WIFI_TASK [label="6.3> 清理 Wi-Fi"];
|
||||
}
|
||||
|
||||
|
||||
Wi-Fi Sniffer 模式
|
||||
---------------------------
|
||||
|
||||
Wi-Fi Sniffer 模式可以通过 :cpp:func:`esp_wifi_set_promiscuous()` 使能。如果使能 Sniffer 模式, **可以** 向应用程序转储以下数据包。
|
||||
|
||||
- 802.11 管理帧
|
||||
- 802.11 数据帧,包括 MPDU、AMPDU、AMSDU 等
|
||||
- 802.11 MIMO 帧,Sniffer 模式仅转储 MIMO 帧的长度。
|
||||
- 802.11 控制帧
|
||||
- 802.11 CRC 错误帧
|
||||
|
||||
**不可以** 向应用程序转储以下数据包。
|
||||
|
||||
- 802.11 其它错误帧
|
||||
|
||||
对于 Sniffer 模式 **可以** 转储的帧,应用程序可以另外使用 :cpp:func:`esp_wifi_set_promiscuous_filter()` 和 :cpp:func:`esp_wifi_set_promiscuous_ctrl_filter()` 决定筛选哪些特定类型的数据包。应用程序默认筛选所有 802.11 数据和管理帧。如果你想要筛选 802.11 控制帧,:cpp:func:`esp_wifi_set_promiscuous_filter()` 中的 filter 参数需要包含 “WIFI_PROMIS_FILTER_MASK_CTRL” 类型, 如果你想进一步区分 802.11 控制帧,那么调用 :cpp:func:`esp_wifi_set_promiscuous_ctrl_filter()`。
|
||||
|
||||
可以在 WIFI_MODE_NULL、WIFI_MODE_STA、WIFI_MODE_AP、WIFI_MODE_APSTA 等 Wi-Fi 模式下使能 Wi-Fi Sniffer 模式。也就是说,当 station 连接到 AP,或者 AP 有 Wi-Fi 连接时,就可以使能。请注意,Sniffer 模式对 station/AP Wi-Fi 连接的吞吐量有 **很大影响**。通常,除非有特别原因,当 station/AP Wi-Fi 连接出现大量流量,不应使能。
|
||||
|
||||
该模式下还应注意回调函数 :cpp:type:`wifi_promiscuous_cb_t` 的使用。该回调将直接在 Wi-Fi 驱动程序任务中进行,所以如果应用程序需处理大量过滤的数据包,建议在回调中向应用程序任务发布一个事件,把真正的工作推迟到应用程序任务中完成。
|
||||
|
||||
|
||||
.. only:: SOC_WIFI_NAN_SUPPORT
|
||||
|
||||
Wi-Fi Aware\ :sup:`TM` (NAN)
|
||||
----------------------------
|
||||
|
||||
Wi-Fi Aware\ :sup:`TM` 或 NAN,即 Neighbor Awareness Networking (邻居感知网络,下文简称 NAN) 协议可以让 Wi-Fi 设备发现附近的其他设备。NAN 使用设备间直接通信,无需通过互联网或 AP 连接。
|
||||
|
||||
多个邻近的 NAN 设备组成一个 NAN 集群,集群中的设备可相互通信。同一集群中的 NAN 设备会同步时钟,并定期在信道 6 上互相监听。NAN 设备还可通过服务发现协议,在所处集群内提供(发布)或获取(订阅)服务。通过服务名称和匹配过滤器(可选),可以完成服务匹配。当订阅设备匹配到发布设备时,就可以发送信息(跟进)或与发布设备建立数据通路 (NDP)。NDP 建立后,订阅设备和发布设备都会获得一个 IPv6 地址用于通信。
|
||||
|
||||
注意,数据包发送是不加密的,无法保证 NDP 的安全性。NAN 为发现 (Discovery) 和数据通路单独的接口,该接口与 STA 和 AP 所用的接口不同。NAN 以独立模式运行,不支持与 STA 或 AP 接口共存。
|
||||
|
||||
要了解如何设置 NAN 发布设备和订阅设备,请参考 ESP-IDF 示例::idf_file:`examples/wifi/wifi_aware/nan_publisher/README.md` 和 :idf_file:`examples/wifi/wifi_aware/nan_subscriber/README.md`。
|
||||
|
||||
|
||||
非同步服务发现 (USD)
|
||||
---------------------------
|
||||
|
||||
非同步服务发现 (USD) 是一种机制,可让设备在新的设备进入射频环境时发现其提供的可用服务,而无需设备之间进行同步。
|
||||
|
||||
USD 通过发布 (Publish) 及跟进消息 (Follow-up message) 中的 SDEA 的服务信息 (Service Info) 字段来传递服务相关信息。
|
||||
|
||||
要了解如何设置 NAN-USD 发布设备和订阅设备,请参考 ESP-IDF 示例::idf_file:`examples/wifi/wifi_aware/usd_publisher/README.md` 和 :idf_file:`examples/wifi/wifi_aware/usd_subscriber/README.md`。
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,236 @@
|
||||
Wi-Fi Vendor 特性
|
||||
========================
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
.. only:: SOC_WIFI_MESH_SUPPORT
|
||||
|
||||
ESP-WIFI-MESH
|
||||
-------------------------
|
||||
|
||||
详细信息请参阅 :doc:`ESP-WIFI-MESH <../esp-wifi-mesh>`.
|
||||
|
||||
|
||||
Wi-Fi 80211 数据包发送
|
||||
---------------------------
|
||||
|
||||
:cpp:func:`esp_wifi_80211_tx()` API 可用于:
|
||||
|
||||
- 发送 beacon、probe request、probe response 和 action 帧。
|
||||
- 发送非 QoS 数据帧。
|
||||
|
||||
不能用于发送加密或 QoS 帧。
|
||||
|
||||
使用 :cpp:func:`esp_wifi_80211_tx()` 的前提条件
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
- Wi-Fi 模式为 station 模式,AP 模式,或 station/AP 共存模式。
|
||||
- API esp_wifi_set_promiscuous(true) 或 :cpp:func:`esp_wifi_start()`,或者二者都返回 :c:macro:`ESP_OK`。这是为确保在调用函数 :cpp:func:`esp_wifi_80211_tx()` 前,Wi-Fi 硬件已经初始化。对于 {IDF_TARGET_NAME},esp_wifi_set_promiscuous(true) 和 :cpp:func:`esp_wifi_start()` 都可以触发 Wi-Fi 硬件初始化。
|
||||
- 提供正确的 :cpp:func:`esp_wifi_80211_tx()` 参数。
|
||||
|
||||
传输速率
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
- 默认传输速率为 1 Mbps。
|
||||
- 可以通过函数 :cpp:func:`esp_wifi_config_80211_tx_rate()` 设置任意速率。
|
||||
- 可以通过函数 :cpp:func:`esp_wifi_set_bandwidth()` 设置任意带宽。
|
||||
|
||||
在不同情况下需要避免的副作用
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
理论上,如果不考虑 API 对 Wi-Fi 驱动程序或其他 station 或 AP 的副作用,可以通过空中发送一个原始的 802.11 数据包,包括任何目的地址的 MAC、任何源地址的 MAC、任何 BSSID、或任何其他类型的数据包。但是,一个具有强健、有用的应用程序应该避免这种副作用。下表针对如何避免 :cpp:func:`esp_wifi_80211_tx()` 的副作用提供了一些提示或建议。
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 10 55
|
||||
|
||||
* - 场景
|
||||
- 描述
|
||||
* - 无 Wi-Fi 连接
|
||||
- 在这种情况下,因为没有 Wi-Fi 连接,Wi-Fi 驱动程序不会受到副作用影响。如果 ``en_sys_seq==true``,则 Wi-Fi 驱动程序负责序列控制。如果 ``en_sys_seq==false``,应用程序需要确保缓冲区的序列正确。
|
||||
|
||||
理论上,MAC 地址可以是任何地址。但是,这样可能会影响其他使用相同 MAC/BSSID 的 station/AP。
|
||||
|
||||
例如,AP 模式下,应用程序调用函数 :cpp:func:`esp_wifi_80211_tx` 发送带有 BSSID == mac_x 的 beacon,但是 mac_x 并非 AP 接口的 MAC。而且,还有另一个 AP(我们称之为 “other-AP”)的 bssid 是 mac_x。因此,连接到 “other-AP” 的 station 无法分辨 beacon 来自 “other-AP” 还是 :cpp:func:`esp_wifi_80211_tx`,就会出现 “意外行为”。
|
||||
|
||||
为了避免上述副作用,我们建议:
|
||||
|
||||
- 如果在 station 模式下调用函数 :cpp:func:`esp_wifi_80211_tx`,第一个 MAC 应该是组播 MAC 或是目标设备的 MAC,第二个 MAC 应该是 station 接口的 MAC。
|
||||
|
||||
- 如果在 AP 模式下调用函数 :cpp:func:`esp_wifi_80211_tx`,第一个 MAC 应该是组播 MAC 或是目标设备的 MAC,第二个 MAC 应该是 AP 接口的 MAC。
|
||||
|
||||
上述建议仅供避免副作用,在有充分理由的情况下可以忽略。
|
||||
|
||||
* - 有 Wi-Fi 连接
|
||||
- 当 Wi-Fi 已连接,且序列由应用程序控制,应用程序可能会影响整个 Wi-Fi 连接的序列控制。 因此,en_sys_seq 要为 true,否则将返回 ``ESP_ERR_INVALID_ARG``。
|
||||
|
||||
“无 Wi-Fi 连接”情况下的 MAC 地址建议也适用于此情况。
|
||||
|
||||
如果 Wi-Fi 模式是 station 模式,MAC 的地址 1 是 station 所连 AP 的 MAC,地址 2 是 station 接口的 MAC,那么就称数据包是从 station 发送到 AP。另一方面,如果 Wi-Fi 模式是 AP 模式,且 MAC 地址 1 是该 AP 所连 station 的 MAC,地址 2 是 AP 接口的 MAC,那么就称数据包是从 AP 发送到 station。为避免与 Wi-Fi 连接冲突,可采用以下检查方法:
|
||||
|
||||
- 如果数据包类型是数据,且是从 station 发送到 AP,IEEE 802.11 Frame control 字段中的 ToDS 位应该为 1,FromDS 位为 0,否则,Wi-Fi 驱动程序不接受该数据包。
|
||||
|
||||
- 如果数据包类型是数据,且是从 AP 发送到 station,IEEE 802.11 Frame control 字段中的 ToDS 位应该为 0,FromDS 位为 1,否则,Wi-Fi 驱动程序不接受该数据包。
|
||||
|
||||
- 如果数据包是从 station 发送到 AP,或从 AP 到 station,Power Management、More Data 和 Re-Transmission 位应该为 0,否则,Wi-Fi 驱动程序不接受该数据包。
|
||||
|
||||
如果任何检查失败,将返回 ``ESP_ERR_INVALID_ARG``。
|
||||
|
||||
|
||||
Wi-Fi 供应商 IE 配置
|
||||
-----------------------------
|
||||
|
||||
默认情况下,所有 Wi-Fi 管理帧都由 Wi-Fi 驱动程序处理,应用程序不需要任何操作。但是,某些应用程序可能需要处理 beacon、probe request、probe response 和其他管理帧。例如,如果在管理帧中插入一些只针对供应商的 IE,则只有包含此 IE 的管理帧才能得到处理。{IDF_TARGET_NAME} 中,:cpp:func:`esp_wifi_set_vendor_ie()` 和 :cpp:func:`esp_wifi_set_vendor_ie_cb()` 负责此类任务。
|
||||
|
||||
|
||||
.. only:: SOC_WIFI_CSI_SUPPORT
|
||||
|
||||
Wi-Fi 信道状态信息
|
||||
------------------------------------
|
||||
|
||||
.. only:: esp32 or esp32s2 or esp32c3 or esp32s3
|
||||
|
||||
信道状态信息 (CSI) 是指 Wi-Fi 连接的信道信息。{IDF_TARGET_NAME} 中,CSI 由子载波的信道频率响应组成,CSI 从发送端接收数据包时开始估计。每个子载波信道频率响由两个字节的有符号字符记录,第一个字节是虚部,第二个字节是实部。根据接收数据包的类型,信道频率响应最多有三个字段。分别是 LLTF、HT-LTF 和 STBC-HT-LTF。对于在不同状态的信道上接收到的不同类型的数据包,CSI 的子载波索引和总字节数如下表所示。
|
||||
|
||||
+------------+-------------+-----------------------------------------+-----------------------------------------------------+--------------------------------------------------------+
|
||||
| 信道 | 辅助信道 | | 下 | 上 |
|
||||
+------------+-------------+-------------+---------------------------+---------+-------------------------------------------+---------+----------------------------------------------+
|
||||
| 数据包信息 | 信号模式 | 非 HT | HT | 非 HT | HT | 非 HT | HT |
|
||||
| +-------------+-------------+---------------------------+---------+---------------+---------------------------+---------+------------------+---------------------------+
|
||||
| | 信道带宽 | 20 MHz | 20 MHz | 20 MHz | 20 MHz | 40 MHz | 20 MHz | 20 MHz | 40 MHz |
|
||||
| +-------------+-------------+-------------+-------------+---------+--------+------+-------------+-------------+---------+---------+--------+-------------+-------------+
|
||||
| | STBC | 非 STBC | 非 STBC | STBC | 非 STBC | 非 STBC| STBC | 非 STBC | STBC | 非 STBC | 非 STBC | STBC | 非 STBC | STBC |
|
||||
+------------+-------------+-------------+-------------+-------------+---------+--------+------+-------------+-------------+---------+---------+--------+-------------+-------------+
|
||||
| 子载波索引 | LLTF | 0~31,-32~-1 | 0~31,-32~-1 | 0~31,-32~-1 | 0~63 | 0~63 | 0~63 | 0~63 | 0~63 | -64~-1 | -64~-1 | -64~-1 | -64~-1 | -64~-1 |
|
||||
| +-------------+-------------+-------------+-------------+---------+--------+------+-------------+-------------+---------+---------+--------+-------------+-------------+
|
||||
| | HT-LTF | — | 0~31,-32~-1 | 0~31,-32~-1 | — | 0~63 | 0~62 | 0~63,-64~-1 | 0~60,-60~-1 | — | -64~-1 | -62~-1 | 0~63,-64~-1 | 0~60,-60~-1 |
|
||||
| +-------------+-------------+-------------+-------------+---------+--------+------+-------------+-------------+---------+---------+--------+-------------+-------------+
|
||||
| | STBC-HT-LTF | — | — | 0~31,-32~-1 | — | — | 0~62 | — | 0~60,-60~-1 | — | — | -62~-1 | — | 0~60,-60~-1 |
|
||||
+------------+-------------+-------------+-------------+-------------+---------+--------+------+-------------+-------------+---------+---------+--------+-------------+-------------+
|
||||
| 总字节数 | 128 | 256 | 384 | 128 | 256 | 380 | 384 | 612 | 128 | 256 | 376 | 384 | 612 |
|
||||
+--------------------------+-------------+-------------+-------------+---------+--------+------+-------------+-------------+---------+---------+--------+-------------+-------------+
|
||||
|
||||
表中的所有信息可以在 wifi_csi_info_t 结构中找到。
|
||||
|
||||
- 辅助信道指 rx_ctrl 字段的 secondary_channel 字段。
|
||||
- 数据包的信号模式指 rx_ctrl 字段的 sig_mode 字段。
|
||||
- 信道带宽指 rx_ctrl 字段中的 cwb 字段。
|
||||
- STBC 指 rx_ctrl 字段的 stbc 字段。
|
||||
- 总字节数指 len 字段。
|
||||
- 每个长训练字段 (LTF) 类型对应的 CSI 数据存储在从 buf 字段开始的缓冲区中。每个元素以两个字节的形式存储:虚部和实部。每个元素的顺序与表中的子载波相同。LTF 的顺序是 LLTF、HT-LTF 和 STBC-HT-LTF。但是,根据信道和数据包的信息,3 个 LTF 可能都不存在(见上文)。
|
||||
- 如果 :cpp:type:`wifi_csi_info_t` 的 first_word_invalid 字段为 true,表示由于 {IDF_TARGET_NAME} 的硬件限制,CSI 数据的前四个字节无效。
|
||||
- 更多信息,如 RSSI,射频的噪声底,接收时间和天线 rx_ctrl 领域。
|
||||
|
||||
子载波的虚部和实部的使用请参考下表。
|
||||
|
||||
+----------------+-------------------+------------------------------+------------------------------+
|
||||
| PHY 标准 | 子载波范围 | 导频子载波 | 子载波个数(总数/数据子载波)|
|
||||
+================+===================+==============================+==============================+
|
||||
| 802.11a/g | -26 to +26 | -21, -7, +7, +21 | 52 total, 48 usable |
|
||||
+----------------+-------------------+------------------------------+------------------------------+
|
||||
| 802.11n, 20 MHz| -28 to +28 | -21, -7, +7, +21 | 56 total, 52 usable |
|
||||
+----------------+-------------------+------------------------------+------------------------------+
|
||||
| 802.11n, 40 MHz| -57 to +57 | -53, -25, -11, +11, +25, +53 | 114 total, 108 usable |
|
||||
+----------------+-------------------+------------------------------+------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
- 对于 STBC 数据包,每个空时流都提供了 CSI,不会出现 CSD(循环移位延迟)。由于附加链上的每一次循环移位为 -200 ns,因为子载波 0 中没有信道频率响应,在 HT-LTF 和 STBC-HT-LTF 中只记录第一空时流的 CSD 角度。CSD[10:0] 是 11 位,范围从 -pi 到 pi。
|
||||
|
||||
- 如果调用 API :cpp:func:`esp_wifi_set_csi_config()` 没有使能 LLTF、HT-LTF 或 STBC-HT-LTF,则 CSI 数据的总字节数会比表中的少。例如,如果没有使能 LLTF 和 HT-LTF,而使能 STBC-HT-LTF,当接收到上述条件、HT、40 MHz 或 STBC 的数据包时,CSI 数据的总字节数为 244((61+60)*2+2=244,结果对齐为四个字节,最后两个字节无效)。
|
||||
|
||||
.. only:: esp32c5
|
||||
|
||||
信道状态信息 (CSI) 是指 Wi-Fi 连接的信道信息。{IDF_TARGET_NAME} 中,CSI 由子载波的信道频率响应组成,CSI 从发送端接收数据包时开始估计。每个子载波信道频率响由两个字节的有符号字符记录,第一个字节是虚部,第二个字节是实部。除了 IEEE 802.11g 模式外,其他模式均存在两段 LTF 序列(LLTF + HT/VHT/HE-LTF)。{IDF_TARGET_NAME}可以通过 :cpp:struct:`wifi_csi_acquire_config_t` 中 ``acquire_csi_force_lltf`` 字段决定包含 LLTF 或 HT/VHT/HE-LTF。对于在不同状态的信道上接收到的不同类型的数据包,CSI 的子载波索引和总字节数如下表所示。
|
||||
|
||||
+------------+------------------+-----------------------------------------+--------------------------------------------+----------------------------------------------------------------+----------------------------------------------------------------+
|
||||
| 信道 | 辅助信道 | | 下 | 上 |
|
||||
+------------+------------------+-------------+---------------------------+--------------------------------------------+-------------+--------------------------------------------------+-------------+--------------------------------------------------+
|
||||
| 数据包信息 | 信号模式 | 非 HT | HT | HE | 非 HT | HT | 非 HT | HT |
|
||||
| +------------------+-------------+---------------------------+--------------------------------------------+-------------+----------------------+---------------------------+-------------+----------------------+---------------------------+
|
||||
| | 信道带宽 | 20 MHz | 20 MHz | 20 MHz | 20 MHz | 20 MHz | 40 MHz | 20 MHz | 20 MHz | 40 MHz |
|
||||
| +------------------+-------------+-------------+-------------+---------------+----------------------------+-------------+-------------+--------+-------------+-------------+-------------+-------------+--------+-------------+-------------+
|
||||
| | STBC | 非 STBC | 非 STBC | STBC | 非 STBC | STBC | 非 STBC | 非 STBC | STBC | 非 STBC | STBC | 非 STBC | 非 STBC | STBC | 非 STBC | STBC |
|
||||
+------------+------------------+-------------+-------------+-------------+---------------+----------------------------+-------------+-------------+--------+-------------+-------------+-------------+-------------+--------+-------------+-------------+
|
||||
| 子载波索引 | LLTF | 0~26,-26~-1 | — | — | — | — | 0~52 | — | — | — | — | -53~-1| — | — | — | — |
|
||||
| +------------------+-------------+-------------+-------------+---------------+----------------------------+-------------+-------------+--------+-------------+-------------+-------------+-------------+--------+-------------+-------------+
|
||||
| | HT-LTF (HT-LTF1) | — | 0~28,-28~-1 | 0~28,-28~-1 | — | — | — | 0~56| 0~56 | 0~58,-58~-1 | 0~58,-58~-1 | — | -57~-1| -57~-1 | 0~58,-58~-1 | 0~58,-58~-1 |
|
||||
| +------------------+-------------+-------------+-------------+---------------+----------------------------+-------------+-------------+--------+-------------+-------------+-------------+-------------+--------+-------------+-------------+
|
||||
| | HT-LTF2 | — | — | 0~28,-28~-1 | — | — | — | — | 0~56 | — | 0~58,-58~-1 | — | — | -57~-1 | — | 0~58,-58~-1 |
|
||||
| +------------------+-------------+-------------+-------------+---------------+----------------------------+-------------+-------------+--------+-------------+-------------+-------------+-------------+--------+-------------+-------------+
|
||||
| | HE-LTF (HE-LTF1) | — | — | — | 0~122,-122~1 | 由CSI配置决定 | — | — | — | — | — | — | — | — | — | — |
|
||||
| +------------------+-------------+-------------+-------------+---------------+ +-------------+-------------+--------+-------------+-------------+-------------+-------------+--------+-------------+-------------+
|
||||
| | HE-LTF2 | — | — | — | — | | — | — | — | — | — | — | — | — | — | — |
|
||||
+------------+------------------+-------------+-------------+-------------+---------------+----------------------------+-------------+-------------+--------+-------------+-------------+-------------+-------------+--------+-------------+-------------+
|
||||
| 总字节数 | 106 | 114| 228 | 490 | 490 | 106 | 114| 228 | 234 | 468 | 106 | 114| 228 | 234 | 468 |
|
||||
+-------------------------------+-------------+-------------+-------------+---------------+----------------------------+-------------+-------------+--------+-------------+-------------+-------------+-------------+--------+-------------+-------------+
|
||||
|
||||
.. note::
|
||||
|
||||
- HT/VHT/HE 模式均存在两段 LTF 序列即:LLTF + HT/VHT/HE-LTF, 如果 :cpp:struct:`wifi_csi_acquire_config_t` 中 ``acquire_csi_force_lltf`` 为 false 时, CSI 数据中仅包含 HT/VHT/HE-LTF(如上表所示), 否则 CSI 数据中仅包含 LLTF。 HT/VHT/HE 模式 LLTF 的子载波索引和 CSI 总字节数同非 HT 模式 LLTF 子载波索引和 CSI 总字节数一致。
|
||||
- VHT 模式时子载波索引和 CSI 总字节数同 HT 模式的子载波索引和 CSI 总字节数一致。
|
||||
|
||||
表中的信息可以在 :cpp:type:`wifi_csi_info_t` 结构体中找到。
|
||||
|
||||
- 辅助信道指 ``rx_ctrl`` 字段的 ``second`` 字段。
|
||||
- 数据包的信号模式指 ``rx_ctrl`` 字段的 ``cur_bb_format`` 字段。
|
||||
- 总字节数指 ``len`` 字段。
|
||||
- 每个长训练字段 (LTF) 类型对应的 CSI 数据存储在从 buf 字段开始的缓冲区中。每个元素以两个字节的形式存储:虚部和实部。每个元素的顺序与表中的子载波相同。LTF 的顺序是 LLTF、HT/VHT/HE-LTF。根据信道和数据包的信息,LTF 的存在情况见上文。
|
||||
- 如果 ``first_word_invalid`` 字段为 true,表示由于 {IDF_TARGET_NAME} 的硬件限制,CSI 数据的前四个字节无效。
|
||||
- 如果 ``rx_ctrl`` 字段中的 ``rx_channel_estimate_info_vld`` 为 1,表明CSI数据是有效的,否则,CSI数据是无效的。
|
||||
- 更多信息,如 RSSI、射频底噪声、接收时间及天线,请参见 ``rx_ctrl`` 字段。
|
||||
|
||||
对于 STBC 数据包,HE-LTF 和 STBC-HE-LTF 的子载波索引由 :cpp:type:`wifi_csi_config_t` 中的 ``acquire_csi_he_stbc_mode`` 字段决定,具体请参见下表。
|
||||
|
||||
+---------------------+------------------+-------------------+
|
||||
| acquire_csi_he_stbc | HE-LTF1 | HE-LTF2 |
|
||||
+---------------------+------------------+-------------------+
|
||||
| 0 | -122~-1, 0~122 | — |
|
||||
+---------------------+------------------+-------------------+
|
||||
| 1 | — | -122~-1, 0~122 |
|
||||
+---------------------+------------------+-------------------+
|
||||
| 2 | 在 HE-LTF1 和 HE-LTF2 中进行均匀采样 |
|
||||
+---------------------+------------------+-------------------+
|
||||
|
||||
有效子载波的虚部和实部的使用请参考下表。
|
||||
|
||||
+-----------------------+------------------+------------------------------------------+------------------------------+
|
||||
| PHY 标准 | 子载波范围 | 无效子载波 | 子载波个数(总数/数据子载波)|
|
||||
+=======================+==================+==========================================+==============================+
|
||||
| 802.11a/g | -26 to +26 | 0 | 53 total, 52 usable |
|
||||
+-----------------------+------------------+------------------------------------------+------------------------------+
|
||||
| 802.11n, 20 MHz | -28 to +28 | 0 | 57 total, 56 usable |
|
||||
+-----------------------+------------------+------------------------------------------+------------------------------+
|
||||
| 802.11n, 40 MHz | -58 to +58 | -1, 0, 1 | 117 total, 114 usable |
|
||||
+-----------------------+------------------+------------------------------------------+------------------------------+
|
||||
| 802.11ac, 20 MHz | -28 to +28 | 0 | 57 total, 56 usable |
|
||||
+-----------------------+------------------+------------------------------------------+------------------------------+
|
||||
| 802.11ax, 20 MHz (SU) | -122 to + 122 | -1, 0, 1 | 245 total, 242 usable |
|
||||
+-----------------------+------------------+------------------------------------------+------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
- PHY 为 802.11ax时,MU 数据包的 CSI 子载波范围和无效子载波索引请参考协议。
|
||||
|
||||
.. note::
|
||||
|
||||
- 对于 STBC 数据包,每个空时流都提供了 CSI,不会出现 CSD(循环移位延迟)。由于附加链上的每一次循环移位为 -200 ns,因为子载波 0 中没有信道频率响应,在 HT-LTF1 和 HT-LTF2 中只记录第一空时流的 CSD 角度。CSD[10:0] 是 11 位,范围从 -pi 到 pi。
|
||||
|
||||
|
||||
Wi-Fi 信道状态信息配置
|
||||
-------------------------------------------
|
||||
|
||||
要使用 Wi-Fi CSI,需要执行以下步骤。
|
||||
|
||||
- 在菜单配置中选择 Wi-Fi CSI。方法是 ``Menuconfig`` > ``Components config`` > ``Wi-Fi`` > ``Wi-Fi CSI (Channel State Information)``。
|
||||
- 调用 API :cpp:func:`esp_wifi_set_csi_rx_cb()` 设置 CSI 接收回调函数。
|
||||
- 调用 API :cpp:func:`esp_wifi_set_csi_config()` 配置 CSI。
|
||||
- 调用 API :cpp:func:`esp_wifi_set_csi()` 使能 CSI。
|
||||
|
||||
CSI 接收回调函数从 Wi-Fi 任务中运行。因此,不要在回调函数中进行冗长的操作。可以将需要的数据发布到队列中,并从一个较低优先级的任务中处理。由于 station 在断开连接时不会收到任何数据包,只有在连接时才会收到来自 AP 的数据包,因此建议通过调用函数 :cpp:func:`esp_wifi_set_promiscuous()` 使能 Sniffer 模式接收更多 CSI 数据。
|
||||
|
||||
|
||||
Wi-Fi 多根天线
|
||||
--------------------------
|
||||
|
||||
具体请参考 :doc:`PHY <../../api-guides/phy>`。
|
||||
@@ -39,32 +39,78 @@ API 及用法
|
||||
|
||||
为最大限度地利用 PMF 的额外安全性优势,已弃用 ``pmf_cfg`` 中的 ``capable`` 标志,并在内部设置为 ``true``。
|
||||
|
||||
|
||||
企业级 Wi-Fi
|
||||
---------------------------------
|
||||
----------------------
|
||||
|
||||
简介
|
||||
++++++++++++
|
||||
++++++++
|
||||
|
||||
企业级安全是企业无线网的安全认证机制,采用 RADIUS 服务器在设备接入到接入点 (AP) 前认证网络用户。该机制基于 802.1X 标准完成认证,并采用多种扩展认证协议 (EAP) 方法,如 TLS、TTLS、PEAP 和 EAP-FAST。RADIUS 服务器根据用户凭证(用户名和密码)、数字证书或两者的组合进行用户认证。
|
||||
企业级 Wi-Fi (Wi-Fi Enterprise) 为企业无线网络提供安全认证机制。该机制基于 IEEE 802.1X 标准运作,并依赖 RADIUS 服务器在设备连接到接入点 (AP) 之前进行用户身份验证。根据所使用的可扩展认证协议 (EAP) 方法,认证可以基于用户凭证(用户名和密码)、数字证书,或两者结合。
|
||||
|
||||
当 {IDF_TARGET_NAME} 以 station 模式连接企业级 AP 时,会发起认证请求。AP 会将该请求转发给配置的 RADIUS 服务器,由其根据所选 EAP 方法和参数对设备进行验证。
|
||||
|
||||
.. note::
|
||||
|
||||
{IDF_TARGET_NAME} 仅在 station 模式下支持企业级 Wi-Fi。
|
||||
|
||||
{IDF_TARGET_NAME} 支持 **企业级 WPA2** 和 **企业级 WPA3**。企业级 WPA3 构建在企业级 WPA2 的基础之上,并额外要求在所有 WPA3 连接中使用受保护的管理帧 (PMF) 和服务器证书验证。此外,**企业级 WPA3 还提供了一种更安全的模式,使用 192 位最低强度的安全协议和加密工具,更好地保护敏感数据**。企业级 WPA3 的 192 位模式可以确保用户正确使用密码工具组合,并在 WPA3 网络中设立了一致的安全基准。需要注意的是,只有支持 :c:macro:`SOC_WIFI_GCMP_SUPPORT` 的模组才支持企业级 WPA3 的 192 位模式。如需使用该模式,请启用 :ref:`CONFIG_ESP_WIFI_SUITE_B_192` 标志。
|
||||
企业级 WPA2 和企业级 WPA3
|
||||
++++++++++++++++++++++++++++++
|
||||
|
||||
{IDF_TARGET_NAME} 支持以下 EAP 方法:
|
||||
- EAP-TLS:该认证方法基于证书实现,仅需提供 SSID 和 EAP-IDF。
|
||||
- PEAP:该认证方法为受保护的 EAP 方法,必须提供用户名和密码。
|
||||
- EAP-TTLS:该认证方法基于凭证实现,必须提供服务器证书,用户证书为可选项。该方法支持多种第二阶段方法,如:
|
||||
- PAP:密码认证协议
|
||||
- CHAP:挑战握手认证协议
|
||||
- MSCHAP 和 MSCHAP-V2
|
||||
- EAP-FAST:该认证方法基于受保护访问凭证 (PAC) 实现,同时也使用身份和密码。目前,需禁用 :ref:`CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT` 标志以使用此功能。
|
||||
{IDF_TARGET_NAME} 支持 **企业级 WPA2 (WPA2-Enterprise)** 和 **企业级 WPA3 (WPA3-Enterprise)**。
|
||||
|
||||
- :example:`wifi/wifi_eap_fast` 演示如何使用 EAP-FAST 通过企业级 Wi-Fi 认证将 {IDF_TARGET_NAME} 连接到 AP,包括 CA 证书的安装、用户凭据的设置、启用 Wi-Fi 企业模式以及如何连接到 AP。
|
||||
**企业级 WPA2** 使用 802.1X/EAP 进行身份验证,并依赖安全的凭证或证书。为建立安全连接,AP 与 station 会协商并选定适当的加密套件。{IDF_TARGET_NAME} 支持以下内容:
|
||||
|
||||
- 802.1X/EAP(WPA)AKM 方法
|
||||
- AES-CCM cipher suite
|
||||
- 启用 `USE_MBEDTLS_CRYPTO` 后可使用 mbedtls 支持的其他 cipher suite
|
||||
|
||||
**企业级 WPA3** 在企业级 WPA2 的基础上加强了安全性,并对所有 WPA3 连接增加两项强制要求:必须启用受保护管理帧 (PMF),并强制执行服务器证书验证。
|
||||
|
||||
此外,企业级 WPA3 还支持 **192 位最低强度安全模式 (Suite B)**,提供更高的加密强度。
|
||||
|
||||
- 企业级 WPA3 的 192 位模式仅适用于支持 :c:macro:`SOC_WIFI_GCMP_SUPPORT` 的芯片。
|
||||
- 若需启用该模式,请配置 :ref:`CONFIG_ESP_WIFI_SUITE_B_192`。
|
||||
|
||||
支持的 EAP 方法
|
||||
+++++++++++++++++++++
|
||||
|
||||
{IDF_TARGET_NAME} 支持多种企业级认证的 EAP 方法。不同方法可能需要不同的配置参数,如 SSID、身份标识、用户名/密码、CA 证书或客户端证书等。
|
||||
|
||||
支持以下 EAP 方法:
|
||||
|
||||
- **EAP-TLS**
|
||||
|
||||
基于证书的认证方式,需要提供 SSID 和 EAP 身份;通过客户端证书进行设备认证。
|
||||
|
||||
- **PEAP**
|
||||
|
||||
一种受保护的 EAP 方法,需要提供用户名和密码。
|
||||
|
||||
- **EAP-TTLS**
|
||||
|
||||
一种基于凭证的认证方式。服务器认证为必选;用户认证取决于 Phase 2 方法。通常需要提供用户名和密码。支持的 Phase 2 方法包括:
|
||||
|
||||
- PAP:密码认证协议
|
||||
- CHAP:挑战握手认证协议
|
||||
- MSCHAP
|
||||
- MSCHAP-V2
|
||||
|
||||
- **EAP-FAST**
|
||||
|
||||
基于受保护访问凭证 (PAC) 的认证方法,需要身份标识和密码。使用 EAP-FAST 时需要 **禁用** :ref:`CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT`。
|
||||
|
||||
示例
|
||||
++++++++
|
||||
|
||||
- :example:`wifi/wifi_eap_fast`
|
||||
|
||||
演示如何使用 EAP-FAST 将 {IDF_TARGET_NAME} 连接到企业级 Wi-Fi,包括 CA 证书安装、凭证配置、启用企业级模式以及连接 AP。
|
||||
|
||||
- :example:`wifi/wifi_enterprise`
|
||||
|
||||
演示使用 EAP-TLS、EAP-PEAP 和 EAP-TTLS 连接企业级 Wi-Fi。有关使用 OpenSSL 生成证书及运行示例的说明,请参考 :example_file:`wifi/wifi_enterprise/README.md`。
|
||||
|
||||
- :example:`wifi/wifi_enterprise` 演示如何使用除 ESP-FAST 之外的其他 EAP 方法(如 EAP-TLS、EAP-PEAP、EAP-TTLS)通过 Wi-Fi 企业认证将 {IDF_TARGET_NAME} 连接到 AP。有关使用 OpenSSL 命令生成证书和运行示例的详细信息,请参阅 :example_file:`wifi/wifi_enterprise/README.md`。
|
||||
|
||||
个人级 WPA3
|
||||
-------------
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user