diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index 466389df67..7f518032c3 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -349,42 +349,22 @@ menu "Wi-Fi" help The maximum time that wifi keep alive, unit: seconds. + config ESP_WIFI_FTM_ENABLE + bool "WiFi FTM" + default n + depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3) + help + Enable feature Fine Timing Measurement for calculating WiFi Round-Trip-Time (RTT). + config ESP_WIFI_FTM_INITIATOR_SUPPORT bool "FTM Initiator support" default y - depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3) - - config ESP_WIFI_FTM_REPORT_LOG_ENABLE - bool "FTM Report logging" - default n - depends on ESP_WIFI_FTM_INITIATOR_SUPPORT - help - Select this option to get a detailed report of FTM Procedure with raw values - - config ESP_WIFI_FTM_REPORT_SHOW_RTT - depends on ESP_WIFI_FTM_REPORT_LOG_ENABLE - bool "Show RTT values" - default y - - config ESP_WIFI_FTM_REPORT_SHOW_DIAG - depends on ESP_WIFI_FTM_REPORT_LOG_ENABLE - bool "Show dialog tokens" - default y - - config ESP_WIFI_FTM_REPORT_SHOW_T1T2T3T4 - depends on ESP_WIFI_FTM_REPORT_LOG_ENABLE - bool "Show T1 to T4" - default y - - config ESP_WIFI_FTM_REPORT_SHOW_RSSI - depends on ESP_WIFI_FTM_REPORT_LOG_ENABLE - bool "Show RSSI levels" - default y + depends on ESP_WIFI_FTM_ENABLE config ESP_WIFI_FTM_RESPONDER_SUPPORT bool "FTM Responder support" default y - depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3) + depends on ESP_WIFI_FTM_ENABLE config ESP_WIFI_STA_DISCONNECTED_PM_ENABLE bool "Power Management for station at disconnected" diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 3c5a93a106..428cc7d918 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -72,17 +72,6 @@ typedef enum { WIFI_LOG_MODULE_MESH, /*logs related to Mesh*/ } wifi_log_module_t; -/** - * @brief FTM Report log levels configuration - * - */ -typedef struct { - uint8_t show_rtt:1; /**< Display all valid Round-Trip-Time readings for FTM frames */ - uint8_t show_diag:1; /**< Display dialogue tokens for all FTM frames with valid readings */ - uint8_t show_t1t2t3t4:1;/**< Display all valid T1, T2, T3, T4 readings considered while calculating RTT */ - uint8_t show_rxrssi:1; /**< Display RSSI for each FTM frame with valid readings */ -} ftm_report_log_level_t; - /** * @brief WiFi log submodule definition * @@ -598,17 +587,6 @@ void esp_wifi_set_sleep_delay_time(uint32_t return_to_sleep_delay); */ void esp_wifi_set_keep_alive_time(uint32_t keep_alive_time); -/** - * @brief Set FTM Report log level - * - * @param log_lvl Log levels configuration - * - * @return - * - ESP_OK: succeed - * - ESP_ERR_NOT_SUPPORTED: No FTM support - */ -esp_err_t esp_wifi_set_ftm_report_log_level(ftm_report_log_level_t *log_lvl); - #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index f159857c02..03b8ae6a75 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -233,6 +233,7 @@ typedef struct { uint8_t max_connection; /**< Max number of stations allowed to connect in, default 4, max 10 */ uint16_t beacon_interval; /**< Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 */ wifi_cipher_type_t pairwise_cipher; /**< pairwise cipher of SoftAP, group cipher will be derived using this. cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP and WIFI_CIPHER_TYPE_TKIP_CCMP. */ + bool ftm_responder; /**< Enable FTM Responder mode */ } wifi_ap_config_t; /** @brief STA configuration settings for the ESP32 */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 85cc831811..465f98ecb5 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 85cc8318118f4a50256aa876e940f06c837942e0 +Subproject commit 465f98ecb515d01c352d06601baee0162a7e2269 diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 73284f5514..f63527d79b 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -290,22 +290,6 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) } adc2_cal_include(); //This enables the ADC2 calibration constructor at start up. -#ifdef CONFIG_ESP_WIFI_FTM_REPORT_LOG_ENABLE - ftm_report_log_level_t log_lvl = {0}; -#ifdef CONFIG_ESP_WIFI_FTM_REPORT_SHOW_RTT - log_lvl.show_rtt = 1; -#endif -#ifdef CONFIG_ESP_WIFI_FTM_REPORT_SHOW_DIAG - log_lvl.show_diag = 1; -#endif -#ifdef CONFIG_ESP_WIFI_FTM_REPORT_SHOW_T1T2T3T4 - log_lvl.show_t1t2t3t4 = 1; -#endif -#ifdef CONFIG_ESP_WIFI_FTM_REPORT_SHOW_RSSI - log_lvl.show_rxrssi = 1; -#endif - esp_wifi_set_ftm_report_log_level(&log_lvl); -#endif esp_wifi_config_info(); return result; } @@ -344,3 +328,10 @@ void set_xpd_sar(bool en) adc_power_release(); } } + +#ifndef CONFIG_ESP_WIFI_FTM_ENABLE +void ieee80211_ftm_attach(void) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} +#endif diff --git a/examples/wifi/ftm/README.md b/examples/wifi/ftm/README.md index ae00bb9267..20b6bdf410 100644 --- a/examples/wifi/ftm/README.md +++ b/examples/wifi/ftm/README.md @@ -25,7 +25,7 @@ Use this example to perform FTM between a Station and a SoftAP or en external AP ## How to use example With this example, users can scan for AP's that support FTM Responder role and perform FTM procedure with different configurations. Below steps show how to do this using 2 devices in Station and SoftAP mode. -First make sure that `FTM Initiator support` on Station and `FTM Responder support` on SoftAP is enabled in the project configuration menu (`idf.py menuconfig`). These options are located in `Component config -> Wi-Fi`. Furthermore for getting a per frame detailed report of the FTM procedure on the console, enable `FTM Report logging` option. Users can also access this report data in the example code. +First make sure that `WiFi FTM` is enabled in the project configuration menu (`idf.py menuconfig`). This option is located in `Component config -> Wi-Fi`. `FTM Initiator support` needs to be enabled on Station side and `FTM Responder support` needs to be enabled on SoftAP side, both are enabled by default. Furthermore for getting a detailed report on FTM sessions, enable `FTM Report logging` option in the `Example Configuration`. Build and flash the example on a supported device to see below output - ```bash diff --git a/examples/wifi/ftm/main/Kconfig.projbuild b/examples/wifi/ftm/main/Kconfig.projbuild new file mode 100644 index 0000000000..e9e3c577d3 --- /dev/null +++ b/examples/wifi/ftm/main/Kconfig.projbuild @@ -0,0 +1,30 @@ +menu "Example Configuration" + + config ESP_FTM_REPORT_LOG_ENABLE + bool "FTM Report logging" + default n + depends on ESP_WIFI_FTM_INITIATOR_SUPPORT + help + Select this option to get a detailed report of FTM Procedure with raw values + + config ESP_FTM_REPORT_SHOW_DIAG + depends on ESP_FTM_REPORT_LOG_ENABLE + bool "Show dialog tokens" + default y + + config ESP_FTM_REPORT_SHOW_RTT + depends on ESP_FTM_REPORT_LOG_ENABLE + bool "Show RTT values" + default y + + config ESP_FTM_REPORT_SHOW_T1T2T3T4 + depends on ESP_FTM_REPORT_LOG_ENABLE + bool "Show T1 to T4" + default y + + config ESP_FTM_REPORT_SHOW_RSSI + depends on ESP_FTM_REPORT_LOG_ENABLE + bool "Show RSSI levels" + default y + +endmenu diff --git a/examples/wifi/ftm/main/ftm_main.c b/examples/wifi/ftm/main/ftm_main.c index 8934d2075c..4698e1a969 100644 --- a/examples/wifi/ftm/main/ftm_main.c +++ b/examples/wifi/ftm/main/ftm_main.c @@ -59,6 +59,22 @@ const int FTM_REPORT_BIT = BIT0; const int FTM_FAILURE_BIT = BIT1; wifi_ftm_report_entry_t *g_ftm_report; uint8_t g_ftm_report_num_entries; +static uint32_t g_rtt_est, g_dist_est; + +const int g_report_lvl = +#ifdef CONFIG_ESP_FTM_REPORT_SHOW_DIAG + BIT0 | +#endif +#ifdef CONFIG_ESP_FTM_REPORT_SHOW_RTT + BIT1 | +#endif +#ifdef CONFIG_ESP_FTM_REPORT_SHOW_T1T2T3T4 + BIT2 | +#endif +#ifdef CONFIG_ESP_FTM_REPORT_SHOW_RSSI + BIT3 | +#endif +0; uint16_t g_scan_ap_num; wifi_ap_record_t *g_ap_list_buffer; @@ -94,11 +110,11 @@ static void ftm_report_handler(void *arg, esp_event_base_t event_base, wifi_event_ftm_report_t *event = (wifi_event_ftm_report_t *) event_data; if (event->status == FTM_STATUS_SUCCESS) { - ESP_LOGI(TAG_STA, "Estimated RTT - %d nSec, Estimated Distance - %d.%02d meters", event->rtt_est, - event->dist_est / 100, event->dist_est % 100); - xEventGroupSetBits(ftm_event_group, FTM_REPORT_BIT); + g_rtt_est = event->rtt_est; + g_dist_est = event->dist_est; g_ftm_report = event->ftm_report_data; g_ftm_report_num_entries = event->ftm_report_num_entries; + xEventGroupSetBits(ftm_event_group, FTM_REPORT_BIT); } else { ESP_LOGI(TAG_STA, "FTM procedure with Peer("MACSTR") failed! (Status - %d)", MAC2STR(event->peer_mac), event->status); @@ -106,6 +122,47 @@ static void ftm_report_handler(void *arg, esp_event_base_t event_base, } } +static void ftm_process_report(void) +{ + int i; + char *log = malloc(200); + + if (!g_report_lvl) + return; + + if (!log) { + ESP_LOGE(TAG_STA, "Failed to alloc buffer for FTM report"); + return; + } + + bzero(log, 200); + sprintf(log, "%s%s%s%s", g_report_lvl & BIT0 ? " Diag |":"", g_report_lvl & BIT1 ? " RTT |":"", + g_report_lvl & BIT2 ? " T1 | T2 | T3 | T4 |":"", + g_report_lvl & BIT3 ? " RSSI |":""); + ESP_LOGI(TAG_STA, "FTM Report:"); + ESP_LOGI(TAG_STA, "|%s", log); + for (i = 0; i < g_ftm_report_num_entries; i++) { + char *log_ptr = log; + + bzero(log, 200); + if (g_report_lvl & BIT0) { + log_ptr += sprintf(log_ptr, "%6d|", g_ftm_report[i].dlog_token); + } + if (g_report_lvl & BIT1) { + log_ptr += sprintf(log_ptr, "%7u |", g_ftm_report[i].rtt); + } + if (g_report_lvl & BIT2) { + log_ptr += sprintf(log_ptr, "%14llu |%14llu |%14llu |%14llu |", g_ftm_report[i].t1, + g_ftm_report[i].t2, g_ftm_report[i].t3, g_ftm_report[i].t4); + } + if (g_report_lvl & BIT3) { + log_ptr += sprintf(log_ptr, "%6d |", g_ftm_report[i].rssi); + } + ESP_LOGI(TAG_STA, "|%s", log); + } + free(log); +} + void initialise_wifi(void) { esp_log_level_set("wifi", ESP_LOG_WARN); @@ -248,7 +305,8 @@ static bool wifi_cmd_ap_set(const char* ssid, const char* pass) .ssid_len = 0, .max_connection = 4, .password = "", - .authmode = WIFI_AUTH_WPA2_PSK + .authmode = WIFI_AUTH_WPA2_PSK, + .ftm_responder = true }, }; @@ -368,8 +426,6 @@ static int wifi_cmd_ftm(int argc, char **argv) if (ftm_args.ssid->count == 1) { ap_record = find_ftm_responder_ap(ftm_args.ssid->sval[0]); if (ap_record) { - printf("Starting FTM with " MACSTR " on channel %d\n", MAC2STR(ap_record->bssid), - ap_record->primary); memcpy(ftmi_cfg.resp_mac, ap_record->bssid, 6); ftmi_cfg.channel = ap_record->primary; } else { @@ -379,9 +435,10 @@ static int wifi_cmd_ftm(int argc, char **argv) if (ftm_args.frm_count->count != 0) { uint8_t count = ftm_args.frm_count->ival[0]; - if (count != 0 && count != 16 && count != 24 && - count != 32 && count != 64) { - count = 0; + if (count != 0 && count != 16 && + count != 24 && count != 32 && count != 64) { + ESP_LOGE(TAG_STA, "Invalid Frame Count! Valid options are 0/16/24/32/64"); + return 0; } ftmi_cfg.frm_count = count; } @@ -391,18 +448,14 @@ static int wifi_cmd_ftm(int argc, char **argv) ftm_args.burst_period->ival[0] < 256) { ftmi_cfg.burst_period = ftm_args.burst_period->ival[0]; } else { - ftmi_cfg.burst_period = 0; + ESP_LOGE(TAG_STA, "Invalid Burst Period! Valid range is 2-255"); + return 0; } } ftm_start: - if (ftmi_cfg.burst_period == 0) { - ESP_LOGI(TAG_STA, "Starting FTM Initiator with Frm Count %d, Burst Period - No Preference", - ftmi_cfg.frm_count); - } else { - ESP_LOGI(TAG_STA, "Starting FTM Initiator with Frm Count %d, Burst Period - %dmSec", - ftmi_cfg.frm_count, ftmi_cfg.burst_period * 100); - } + ESP_LOGI(TAG_STA, "Requesting FTM session with Frm Count - %d, Burst Period - %dmSec (0: No Preference)", + ftmi_cfg.frm_count, ftmi_cfg.burst_period*100); if (ESP_OK != esp_wifi_ftm_initiate_session(&ftmi_cfg)) { ESP_LOGE(TAG_STA, "Failed to start FTM session"); @@ -413,13 +466,12 @@ ftm_start: pdFALSE, pdFALSE, portMAX_DELAY); /* Processing data from FTM session */ if (bits & FTM_REPORT_BIT) { - int i; - for (i = 0; i < g_ftm_report_num_entries; i++) { - /* NOTE: Process FTM report elements here, e.g. g_ftm_report[i].rtt etc */ - } + ftm_process_report(); free(g_ftm_report); g_ftm_report = NULL; g_ftm_report_num_entries = 0; + ESP_LOGI(TAG_STA, "Estimated RTT - %d nSec, Estimated Distance - %d.%02d meters", + g_rtt_est, g_dist_est / 100, g_dist_est % 100); xEventGroupClearBits(ftm_event_group, FTM_REPORT_BIT); } else { /* Failure case */ diff --git a/examples/wifi/ftm/sdkconfig.defaults b/examples/wifi/ftm/sdkconfig.defaults new file mode 100644 index 0000000000..a45b08d478 --- /dev/null +++ b/examples/wifi/ftm/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_ESP_WIFI_FTM_ENABLE=y