From dc46fe5343cfe337f8f3a44ae859ad3928b83ce1 Mon Sep 17 00:00:00 2001 From: Nachiket Kukade Date: Wed, 5 Jul 2023 16:04:03 +0530 Subject: [PATCH] fix(esp_wifi): Enable FTM for ESP32C2, fix other FTM issues Enable FTM for ESP32C2 and update wifi libs with below fixes - 1. Bugfixes in Initiator and Responder mode 2. Fix wrong RTT value in first FTM procedure without connection 3. Update FTM calibration values for ESP32S2, S3, C3 and C2 4. Update distance estimation logic 5. Add some useful command parameters in FTM example 6. Fix bug when number of FTM measurement frames received is more than (number_of_brusts * FTMs per brust). Co-authored-by: Sarvesh Bodakhe --- .../esp32c2/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32c2/include/soc/soc_caps.h | 1 + .../esp32c6/include/soc/Kconfig.soc_caps.in | 2 +- components/soc/esp32c6/include/soc/soc_caps.h | 2 +- examples/wifi/.build-test-rules.yml | 7 +- examples/wifi/ftm/README.md | 5 +- examples/wifi/ftm/main/ftm_main.c | 107 +++++++++++++----- 7 files changed, 91 insertions(+), 37 deletions(-) diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 099095f901..a260e80e7d 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -635,6 +635,10 @@ config SOC_WIFI_HW_TSF bool default y +config SOC_WIFI_FTM_SUPPORT + bool + default y + config SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW bool default y diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index b65323d251..845817b5ad 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -299,6 +299,7 @@ /*------------------------------------ WI-FI CAPS ------------------------------------*/ #define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */ +#define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ #define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */ /*---------------------------------- Bluetooth CAPS ----------------------------------*/ diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 3f53bccceb..1a49fd77f7 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1213,7 +1213,7 @@ config SOC_WIFI_HW_TSF config SOC_WIFI_FTM_SUPPORT bool - default y + default n config SOC_WIFI_GCMP_SUPPORT bool diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index f47b9cdf48..c5ba77fa76 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -501,7 +501,7 @@ /*------------------------------------ WI-FI CAPS ------------------------------------*/ #define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */ -#define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ +#define SOC_WIFI_FTM_SUPPORT (0) /*!< Support FTM */ #define SOC_WIFI_GCMP_SUPPORT (1) /*!< Support GCMP(GCMP128 and GCMP256) */ #define SOC_WIFI_WAPI_SUPPORT (1) /*!< Support WAPI */ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ diff --git a/examples/wifi/.build-test-rules.yml b/examples/wifi/.build-test-rules.yml index 1678d58eed..0dc1197282 100644 --- a/examples/wifi/.build-test-rules.yml +++ b/examples/wifi/.build-test-rules.yml @@ -5,10 +5,9 @@ examples/wifi: - if: SOC_WIFI_SUPPORTED != 1 examples/wifi/ftm: - enable: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3"] - temporary: true - reason: the other targets are not tested yet + disable: + - if: SOC_WIFI_FTM_SUPPORT != 1 + reason: requires hardware support examples/wifi/getting_started: disable: diff --git a/examples/wifi/ftm/README.md b/examples/wifi/ftm/README.md index a39ae9a329..d585ee76a1 100644 --- a/examples/wifi/ftm/README.md +++ b/examples/wifi/ftm/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | # FTM Example @@ -43,6 +43,7 @@ ftm> ``` Use `help` to get a list of available commands and options. Use `scan` command to scan for AP's that support FTM Responder mode. Before initiating FTM with an external AP, make sure that `FTM Responder` tag is visible in the respective scan result entry. Alternatively, start SoftAP on another device using `ap` command, it supports FTM Responder by default. If external FTM Initiators get a large error in distance readings with the SoftAP, note down the reading at zero distance in centimeters, say `cm0`. This distance can be offset using command `ftm -R -o ` to give accurate readings with the Initiator. +It is recommended to keep SoftAP bandwidth at 20MHz as it gives more accurate results. ```bash ftm> scan diff --git a/examples/wifi/ftm/main/ftm_main.c b/examples/wifi/ftm/main/ftm_main.c index e666c345b2..89fcfb544f 100644 --- a/examples/wifi/ftm/main/ftm_main.c +++ b/examples/wifi/ftm/main/ftm_main.c @@ -26,8 +26,17 @@ typedef struct { struct arg_str *ssid; struct arg_str *password; + struct arg_lit *disconnect; struct arg_end *end; -} wifi_args_t; +} wifi_sta_args_t; + +typedef struct { + struct arg_str *ssid; + struct arg_str *password; + struct arg_int *channel; + struct arg_int *bandwidth; + struct arg_end *end; +} wifi_ap_args_t; typedef struct { struct arg_str *ssid; @@ -48,8 +57,8 @@ typedef struct { struct arg_end *end; } wifi_ftm_args_t; -static wifi_args_t sta_args; -static wifi_args_t ap_args; +static wifi_sta_args_t sta_args; +static wifi_ap_args_t ap_args; static wifi_scan_arg_t scan_args; static wifi_ftm_args_t ftm_args; @@ -61,6 +70,8 @@ wifi_config_t g_ap_config = { #define ETH_ALEN 6 #define MAX_CONNECT_RETRY_ATTEMPTS 5 +#define DEFAULT_AP_CHANNEL 1 +#define DEFAULT_AP_BANDWIDTH 20 static bool s_reconnect = true; static int s_retry_num = 0; @@ -124,11 +135,11 @@ static void event_handler(void *arg, esp_event_base_t event_base, } else if (event_id == WIFI_EVENT_FTM_REPORT) { wifi_event_ftm_report_t *event = (wifi_event_ftm_report_t *) event_data; + s_rtt_est = event->rtt_est; + s_dist_est = event->dist_est; + s_ftm_report = event->ftm_report_data; + s_ftm_report_num_entries = event->ftm_report_num_entries; if (event->status == FTM_STATUS_SUCCESS) { - s_rtt_est = event->rtt_est; - s_dist_est = event->dist_est; - s_ftm_report = event->ftm_report_data; - s_ftm_report_num_entries = event->ftm_report_num_entries; xEventGroupSetBits(s_ftm_event_group, FTM_REPORT_BIT); } else { ESP_LOGI(TAG_STA, "FTM procedure with Peer("MACSTR") failed! (Status - %d)", @@ -147,6 +158,9 @@ static void ftm_process_report(void) int i; char *log = NULL; + if (s_ftm_report_num_entries == 0) + return; + if (!g_report_lvl) return; @@ -170,7 +184,10 @@ static void ftm_process_report(void) log_ptr += sprintf(log_ptr, "%6d|", s_ftm_report[i].dlog_token); } if (g_report_lvl & BIT1) { - log_ptr += sprintf(log_ptr, "%7" PRIu32 " |", s_ftm_report[i].rtt); + if (s_ftm_report[i].rtt != UINT32_MAX) + log_ptr += sprintf(log_ptr, "%7" PRIi32 " |", s_ftm_report[i].rtt); + else + log_ptr += sprintf(log_ptr, " INVALID |"); } if (g_report_lvl & BIT2) { log_ptr += sprintf(log_ptr, "%14llu |%14llu |%14llu |%14llu |", s_ftm_report[i].t1, @@ -250,6 +267,13 @@ static int wifi_cmd_sta(int argc, char **argv) arg_print_errors(stderr, sta_args.end, argv[0]); return 1; } + if (sta_args.disconnect->count) { + s_reconnect = false; + xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT); + esp_wifi_disconnect(); + xEventGroupWaitBits(s_wifi_event_group, DISCONNECTED_BIT, 0, 1, portTICK_PERIOD_MS); + return 0; + } ESP_LOGI(TAG_STA, "sta connecting to '%s'", sta_args.ssid->sval[0]); wifi_cmd_sta_join(sta_args.ssid->sval[0], sta_args.password->sval[0]); @@ -315,7 +339,7 @@ static int wifi_cmd_scan(int argc, char **argv) return 0; } -static bool wifi_cmd_ap_set(const char* ssid, const char* pass) +static bool wifi_cmd_ap_set(const char* ssid, const char* pass, uint8_t channel, uint8_t bw) { s_reconnect = false; strlcpy((char*) g_ap_config.ap.ssid, ssid, MAX_SSID_LEN); @@ -327,13 +351,29 @@ static bool wifi_cmd_ap_set(const char* ssid, const char* pass) } strlcpy((char*) g_ap_config.ap.password, pass, MAX_PASSPHRASE_LEN); } + if (!(channel >=1 && channel <= 14)) { + ESP_LOGE(TAG_AP, "Channel cannot be %d!", channel); + return false; + } + if (bw != 20 && bw != 40) { + ESP_LOGE(TAG_AP, "Cannot set %d MHz bandwidth!", bw); + return false; + } if (strlen(pass) == 0) { g_ap_config.ap.authmode = WIFI_AUTH_OPEN; } - + g_ap_config.ap.channel = channel; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &g_ap_config)); + if (bw == 40) { + esp_wifi_set_bandwidth(ESP_IF_WIFI_AP, WIFI_BW_HT40); + } else { + esp_wifi_set_bandwidth(ESP_IF_WIFI_AP, WIFI_BW_HT20); + } + ESP_LOGI(TAG_AP, "Starting SoftAP with FTM Responder support, SSID - %s, Password - %s, Primary Channel - %d, Bandwidth - %dMHz", + ap_args.ssid->sval[0], ap_args.password->sval[0], channel, bw); + return true; } @@ -346,10 +386,12 @@ static int wifi_cmd_ap(int argc, char** argv) return 1; } - if (true == wifi_cmd_ap_set(ap_args.ssid->sval[0], ap_args.password->sval[0])) - ESP_LOGI(TAG_AP, "Starting SoftAP with FTM Responder support, SSID - %s, Password - %s", ap_args.ssid->sval[0], ap_args.password->sval[0]); - else + if (!wifi_cmd_ap_set(ap_args.ssid->sval[0], ap_args.password->sval[0], + ap_args.channel->count != 0 ? ap_args.channel->ival[0] : DEFAULT_AP_CHANNEL, + ap_args.bandwidth->count != 0 ? ap_args.bandwidth->ival[0] : DEFAULT_AP_BANDWIDTH)) { ESP_LOGE(TAG_AP, "Failed to start SoftAP!"); + return 1; + } return 0; } @@ -486,11 +528,11 @@ static int wifi_cmd_ftm(int argc, char **argv) bits = xEventGroupWaitBits(s_ftm_event_group, FTM_REPORT_BIT | FTM_FAILURE_BIT, pdTRUE, pdFALSE, portMAX_DELAY); /* Processing data from FTM session */ + ftm_process_report(); + free(s_ftm_report); + s_ftm_report = NULL; + s_ftm_report_num_entries = 0; if (bits & FTM_REPORT_BIT) { - ftm_process_report(); - free(s_ftm_report); - s_ftm_report = NULL; - s_ftm_report_num_entries = 0; ESP_LOGI(TAG_STA, "Estimated RTT - %" PRId32 " nSec, Estimated Distance - %" PRId32 ".%02" PRId32 " meters", s_rtt_est, s_dist_est / 100, s_dist_est % 100); } else { @@ -533,8 +575,9 @@ ftm_responder: void register_wifi(void) { - sta_args.ssid = arg_str1(NULL, NULL, "", "SSID of AP"); + sta_args.ssid = arg_str0(NULL, NULL, "", "SSID of AP"); sta_args.password = arg_str0(NULL, NULL, "", "password of AP"); + sta_args.disconnect = arg_lit0("d", "disconnect", "Disconnect from the connected AP"); sta_args.end = arg_end(2); const esp_console_cmd_t sta_cmd = { @@ -547,8 +590,10 @@ void register_wifi(void) ESP_ERROR_CHECK( esp_console_cmd_register(&sta_cmd) ); - ap_args.ssid = arg_str1(NULL, NULL, "", "SSID of AP"); + ap_args.ssid = arg_str0(NULL, NULL, "", "SSID of AP"); ap_args.password = arg_str0(NULL, NULL, "", "password of AP"); + ap_args.channel = arg_int0("c", "channel", "<1-11>", "Primary channel of AP"); + ap_args.bandwidth = arg_int0("b", "bandwidth", "<20/40>", "Channel bandwidth"); ap_args.end = arg_end(2); const esp_console_cmd_t ap_cmd = { @@ -640,16 +685,20 @@ void app_main(void) register_system(); register_wifi(); - printf("\n ==========================================================\n"); - printf(" | Steps to test FTM |\n"); - printf(" | |\n"); - printf(" | 1. Use 'help' for detailed information on parameters |\n"); - printf(" | 2. Start SoftAP with command 'ap ' |\n"); - printf(" | OR |\n"); - printf(" | 2. Use 'scan' command to search for external AP's |\n"); - printf(" | 3. On second device initiate FTM with an AP using |\n"); - printf(" | command 'ftm -I -s ' |\n"); - printf(" ==========================================================\n\n"); + printf("\n ===============================================================\n"); + printf(" | Steps to test FTM Initiator |\n"); + printf(" | |\n"); + printf(" | 1. Use 'scan' command to scan AP's. In results, check AP's |\n"); + printf(" | with tag '[FTM Responder]' for supported AP's |\n"); + printf(" | 2. Optionally connect to the AP with 'sta '|\n"); + printf(" | 3. Initiate FTM with 'ftm -I -s ' |\n"); + printf(" |______________________________________________________________|\n"); + printf(" | Steps to test FTM Responder |\n"); + printf(" | |\n"); + printf(" | 1. Start SoftAP with command 'ap ' |\n"); + printf(" | 2. Optionally add '-c ' to set channel, '-b 40' for 40M |\n"); + printf(" | 3. Use 'help' for detailed information for all parameters |\n"); + printf(" ================================================================\n\n"); // start console REPL ESP_ERROR_CHECK(esp_console_start_repl(repl));