diff --git a/components/wifi/example/main/wifi_example.cpp b/components/wifi/example/main/wifi_example.cpp index a7713f4e9..ea1632d02 100644 --- a/components/wifi/example/main/wifi_example.cpp +++ b/components/wifi/example/main/wifi_example.cpp @@ -105,7 +105,9 @@ extern "C" void app_main(void) { { logger.info("Starting WiFi AP example..."); //! [wifi ap example] - espp::WifiAp wifi_ap({.ssid = CONFIG_ESP_WIFI_SSID, .password = CONFIG_ESP_WIFI_PASSWORD}); + espp::WifiAp wifi_ap({.ssid = CONFIG_ESP_WIFI_SSID, + .password = CONFIG_ESP_WIFI_PASSWORD, + .log_level = espp::Logger::Verbosity::DEBUG}); //! [wifi ap example] std::this_thread::sleep_for(num_seconds_to_run * 1s); diff --git a/components/wifi/include/wifi_ap.hpp b/components/wifi/include/wifi_ap.hpp index 5100c1918..36ee8b503 100644 --- a/components/wifi/include/wifi_ap.hpp +++ b/components/wifi/include/wifi_ap.hpp @@ -9,6 +9,7 @@ #include "nvs_flash.h" #include "base_component.hpp" +#include "wifi_format_helpers.hpp" namespace espp { /** @@ -33,7 +34,10 @@ class WifiAp : public BaseComponent { std::string ssid; /**< SSID for the access point. */ std::string password; /**< Password for the access point. If empty, the AP will be open / have no security. */ - uint8_t channel{1}; /**< WiFi channel, range [1,13]. */ + wifi_phy_rate_t phy_rate{ + WIFI_PHY_RATE_MCS0_LGI}; /**< PHY rate to use for the access point. Default is MCS0_LGI (6.5 + - 13.5 Mbps Long Guard Interval). */ + uint8_t channel{1}; /**< WiFi channel, range [1,13]. */ uint8_t max_number_of_stations{4}; /**< Max number of connected stations to this AP. */ Logger::Verbosity log_level{Logger::Verbosity::WARN}; /**< Verbosity of WifiAp logger. */ }; @@ -112,6 +116,12 @@ class WifiAp : public BaseComponent { logger_.error("Could not create default event loop: {}", err); } + logger_.debug("Setting WiFi phy rate to {}", config.phy_rate); + err = esp_wifi_config_80211_tx_rate(WIFI_IF_AP, config.phy_rate); + if (err != ESP_OK) { + logger_.error("Could not set WiFi PHY rate: {}", err); + } + // NOTE: Start phase logger_.debug("Starting WiFi"); err = esp_wifi_start(); diff --git a/components/wifi/include/wifi_format_helpers.hpp b/components/wifi/include/wifi_format_helpers.hpp new file mode 100644 index 000000000..b3393015a --- /dev/null +++ b/components/wifi/include/wifi_format_helpers.hpp @@ -0,0 +1,103 @@ +#pragma once + +#include + +#include "format.hpp" + +// for libfmt formtating of wifi_phy_rate_t +template <> struct fmt::formatter : fmt::formatter { + template + auto format(const wifi_phy_rate_t &value, FormatContext &ctx) const -> decltype(ctx.out()) { + switch (value) { + // base + case WIFI_PHY_RATE_1M_L: + return fmt::format_to(ctx.out(), "1 Mbps with long preamble"); + case WIFI_PHY_RATE_2M_L: + return fmt::format_to(ctx.out(), "2 Mbps with long preamble"); + case WIFI_PHY_RATE_5M_L: + return fmt::format_to(ctx.out(), "5.5 Mbps with long preamble"); + case WIFI_PHY_RATE_11M_L: + return fmt::format_to(ctx.out(), "11 Mbps with long preamble"); + case WIFI_PHY_RATE_2M_S: + return fmt::format_to(ctx.out(), "2 Mbps with short preamble"); + case WIFI_PHY_RATE_5M_S: + return fmt::format_to(ctx.out(), "5.5 Mbps with short preamble"); + case WIFI_PHY_RATE_11M_S: + return fmt::format_to(ctx.out(), "11 Mbps with short preamble"); + + // HT + case WIFI_PHY_RATE_48M: + return fmt::format_to(ctx.out(), "48 Mbps"); + case WIFI_PHY_RATE_24M: + return fmt::format_to(ctx.out(), "24 Mbps"); + case WIFI_PHY_RATE_12M: + return fmt::format_to(ctx.out(), "12 Mbps"); + case WIFI_PHY_RATE_6M: + return fmt::format_to(ctx.out(), "6 Mbps"); + case WIFI_PHY_RATE_54M: + return fmt::format_to(ctx.out(), "54 Mbps"); + case WIFI_PHY_RATE_36M: + return fmt::format_to(ctx.out(), "36 Mbps"); + case WIFI_PHY_RATE_18M: + return fmt::format_to(ctx.out(), "18 Mbps"); + case WIFI_PHY_RATE_9M: + return fmt::format_to(ctx.out(), "9 Mbps"); + + // Long GI + case WIFI_PHY_RATE_MCS0_LGI: + return fmt::format_to(ctx.out(), "MCS0_LGI (6.5-13.5 Mbps)"); + case WIFI_PHY_RATE_MCS1_LGI: + return fmt::format_to(ctx.out(), "MCS1_LGI (13-27 Mbps)"); + case WIFI_PHY_RATE_MCS2_LGI: + return fmt::format_to(ctx.out(), "MCS2_LGI (19.5-40.5 Mbps)"); + case WIFI_PHY_RATE_MCS3_LGI: + return fmt::format_to(ctx.out(), "MCS3_LGI (26-54 Mbps)"); + case WIFI_PHY_RATE_MCS4_LGI: + return fmt::format_to(ctx.out(), "MCS4_LGI (39-81 Mbps)"); + case WIFI_PHY_RATE_MCS5_LGI: + return fmt::format_to(ctx.out(), "MCS5_LGI (52-108 Mbps)"); + case WIFI_PHY_RATE_MCS6_LGI: + return fmt::format_to(ctx.out(), "MCS6_LGI (58.5-121.5 Mbps)"); + case WIFI_PHY_RATE_MCS7_LGI: + return fmt::format_to(ctx.out(), "MCS7_LGI (65-135 Mbps)"); +#if CONFIG_SOC_WIFI_HE_SUPPORT || !CONFIG_SOC_WIFI_SUPPORTED + case WIFI_PHY_RATE_MCS8_LGI: + return fmt::format_to(ctx.out(), "MCS8_LGI (97.5 Mbps)"); + case WIFI_PHY_RATE_MCS9_LGI: + return fmt::format_to(ctx.out(), "MCS9_LGI (108.3 Mbps)"); +#endif + + // Short GI + case WIFI_PHY_RATE_MCS0_SGI: + return fmt::format_to(ctx.out(), "MCS0_SGI (7.2-15 Mbps)"); + case WIFI_PHY_RATE_MCS1_SGI: + return fmt::format_to(ctx.out(), "MCS1_SGI (14.4-30 Mbps)"); + case WIFI_PHY_RATE_MCS2_SGI: + return fmt::format_to(ctx.out(), "MCS2_SGI (21.7-45 Mbps)"); + case WIFI_PHY_RATE_MCS3_SGI: + return fmt::format_to(ctx.out(), "MCS3_SGI (28.9-60 Mbps)"); + case WIFI_PHY_RATE_MCS4_SGI: + return fmt::format_to(ctx.out(), "MCS4_SGI (43.3-90 Mbps)"); + case WIFI_PHY_RATE_MCS5_SGI: + return fmt::format_to(ctx.out(), "MCS5_SGI (57.8-120 Mbps)"); + case WIFI_PHY_RATE_MCS6_SGI: + return fmt::format_to(ctx.out(), "MCS6_SGI (65.0-135 Mbps)"); + case WIFI_PHY_RATE_MCS7_SGI: + return fmt::format_to(ctx.out(), "MCS7_SGI (72.2-150 Mbps)"); +#if CONFIG_SOC_WIFI_HE_SUPPORT || !CONFIG_SOC_WIFI_SUPPORTED + case WIFI_PHY_RATE_MCS8_SGI: + return fmt::format_to(ctx.out(), "MCS8_SGI (103.2 Mbps)"); + case WIFI_PHY_RATE_MCS9_SGI: + return fmt::format_to(ctx.out(), "MCS9_SGI (114.7 Mbps)"); +#endif + + // LORA + case WIFI_PHY_RATE_LORA_250K: + return fmt::format_to(ctx.out(), "LoRa 250Kbps"); + case WIFI_PHY_RATE_LORA_500K: + return fmt::format_to(ctx.out(), "LoRa 500Kbps"); + default: + return fmt::format_to(ctx.out(), "Unknown PHY rate: {}", static_cast(value)); + } + } +}; diff --git a/components/wifi/include/wifi_sta.hpp b/components/wifi/include/wifi_sta.hpp index f4f9c99d3..174513096 100644 --- a/components/wifi/include/wifi_sta.hpp +++ b/components/wifi/include/wifi_sta.hpp @@ -10,6 +10,7 @@ #include "nvs_flash.h" #include "base_component.hpp" +#include "wifi_format_helpers.hpp" namespace espp { /** @@ -50,6 +51,9 @@ class WifiSta : public BaseComponent { std::string ssid; /**< SSID for the access point. */ std::string password; /**< Password for the access point. If empty, the AP will be open / have no security. */ + wifi_phy_rate_t phy_rate{ + WIFI_PHY_RATE_MCS0_LGI}; /**< PHY rate to use for the station. Default is MCS0_LGI (6.5 + - 13.5 Mbps Long Guard Interval). */ size_t num_connect_retries{ 0}; /**< Number of times to retry connecting to the AP before stopping. After this many retries, on_disconnected will be called. */ @@ -77,33 +81,40 @@ class WifiSta : public BaseComponent { // Code below is modified from: // https://github.com/espressif/esp-idf/blob/1c84cfde14dcffdc77d086a5204ce8a548dce935/examples/wifi/getting_started/station/main/station_example_main.c esp_err_t err; + logger_.debug("Initializing WiFiSta"); err = esp_netif_init(); if (err != ESP_OK) { logger_.error("Could not initialize netif: {}", err); } + logger_.debug("Creating default event loop"); err = esp_event_loop_create_default(); if (err != ESP_OK) { logger_.error("Could not create default event loop: {}", err); } // Create default WiFi STA + logger_.debug("Creating default WiFi STA netif"); netif_ = esp_netif_create_default_wifi_sta(); if (netif_ == nullptr) { logger_.error("Could not create default WiFi STA"); } + logger_.debug("Wifi init..."); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); err = esp_wifi_init(&cfg); if (err != ESP_OK) { logger_.error("Could not init wifi subsystem: {}", err); } + // register our event handlers + logger_.debug("Adding event handler for WIFI_EVENT(s)"); err = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &WifiSta::event_handler, this, &event_handler_instance_any_id_); if (err != ESP_OK) { logger_.error("Could not add wifi ANY event handler: {}", err); } + logger_.debug("Adding IP event handler for IP_EVENT_STA_GOT_IP"); err = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &WifiSta::event_handler, this, &event_handler_instance_got_ip_); @@ -135,14 +146,25 @@ class WifiSta : public BaseComponent { memcpy(wifi_config.sta.bssid, config.ap_mac, 6); } + logger_.debug("Setting WiFi mode to STA"); err = esp_wifi_set_mode(WIFI_MODE_STA); if (err != ESP_OK) { logger_.error("Could not set WiFi mode STA: {}", err); } + + logger_.debug("Setting Wifi config"); err = esp_wifi_set_config(WIFI_IF_STA, &wifi_config); if (err != ESP_OK) { logger_.error("Could not set WiFi config: {}", err); } + + logger_.debug("Setting WiFi PHY rate to {}", config.phy_rate); + err = esp_wifi_config_80211_tx_rate(WIFI_IF_STA, config.phy_rate); + if (err != ESP_OK) { + logger_.error("Could not set WiFi PHY rate: {}", err); + } + + logger_.debug("Starting WiFi"); err = esp_wifi_start(); if (err != ESP_OK) { logger_.error("Could not start WiFi: {}", err);