From 6e6139061dd09a1a38ef85e81fa6c17dfd19258d 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 --- components/esp_wifi/lib | 2 +- .../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 +++++++++++++----- 8 files changed, 92 insertions(+), 38 deletions(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 019806ed40..3a3abfa142 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 019806ed40c268eb87438d7afcb5452ba4c3e70f +Subproject commit 3a3abfa142355be2a1d26e2448f6c70af87ad389 diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 7041a4918b..c88374144b 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -651,6 +651,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 b1663fea31..6345456714 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -305,6 +305,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 a3e54d240a..eb1e8927b0 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1245,7 +1245,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 7311face16..964fb82bcb 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -511,7 +511,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));