diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 454b02eab2..fcf0a93f67 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -1237,6 +1237,26 @@ esp_err_t esp_wifi_ftm_end_session(void); */ esp_err_t esp_wifi_ftm_resp_set_offset(int16_t offset_cm); +/** + * @brief Get FTM measurements report copied into a user provided buffer. + * + * @attention 1. To get the FTM report, user first needs to allocate a buffer of size + * (sizeof(wifi_ftm_report_entry_t) * num_entries) where the API will fill up to num_entries + * valid FTM measurements in the buffer. Total number of entries can be found in the event + * WIFI_EVENT_FTM_REPORT as ftm_report_num_entries + * @attention 2. The internal FTM report is freed upon use of this API which means the API can only be used + * once afer every FTM session initiated + * @attention 3. Passing the buffer as NULL merely frees the FTM report + * + * @param report Pointer to the buffer for receiving the FTM report + * @param num_entries Number of FTM report entries to be filled in the report + * + * @return + * - ESP_OK: succeed + * - others: failed + */ +esp_err_t esp_wifi_ftm_get_report(wifi_ftm_report_entry_t *report, uint8_t num_entries); + /** * @brief Enable or disable 11b rate of specified interface * diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 249abece54..720a32399b 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -582,7 +582,9 @@ typedef struct { uint8_t resp_mac[6]; /**< MAC address of the FTM Responder */ uint8_t channel; /**< Primary channel of the FTM Responder */ uint8_t frm_count; /**< No. of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0(No pref), 16, 24, 32, 64) */ - uint16_t burst_period; /**< Requested time period between consecutive FTM bursts in 100's of milliseconds (0 - No pref) */ + uint16_t burst_period; /**< Requested period between FTM bursts in 100's of milliseconds (allowed values 0(No pref) - 100) */ + bool use_get_report_api; /**< True - Using esp_wifi_ftm_get_report to get FTM report, False - Using ftm_report_data from + WIFI_EVENT_FTM_REPORT to get FTM report */ } wifi_ftm_initiator_cfg_t; /** @@ -757,6 +759,8 @@ typedef enum { FTM_STATUS_CONF_REJECTED, /**< Peer rejected FTM configuration in FTM Request */ FTM_STATUS_NO_RESPONSE, /**< Peer did not respond to FTM Requests */ FTM_STATUS_FAIL, /**< Unknown error during FTM exchange */ + FTM_STATUS_NO_VALID_MSMT, /**< FTM session did not result in any valid measurements */ + FTM_STATUS_USER_TERM, /**< User triggered termination */ } wifi_ftm_status_t; /** Argument structure for */ @@ -777,7 +781,8 @@ typedef struct { uint32_t rtt_raw; /**< Raw average Round-Trip-Time with peer in Nano-Seconds */ uint32_t rtt_est; /**< Estimated Round-Trip-Time with peer in Nano-Seconds */ uint32_t dist_est; /**< Estimated one-way distance in Centi-Meters */ - wifi_ftm_report_entry_t *ftm_report_data; /**< Pointer to FTM Report with multiple entries, should be freed after use */ + wifi_ftm_report_entry_t *ftm_report_data; /**< Pointer to FTM Report, should be freed after use. Note: Highly recommended + to use API esp_wifi_ftm_get_report to get the report instead of using this */ uint8_t ftm_report_num_entries; /**< Number of entries in the FTM Report data */ } wifi_event_ftm_report_t; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 569c42ab49..a4068355ff 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 569c42ab4991c781179cd0d24c0a8a17b7b2587c +Subproject commit a4068355ffda0716b5c07fa0c6a2fd4be2d8375a diff --git a/examples/wifi/ftm/main/ftm_main.c b/examples/wifi/ftm/main/ftm_main.c index f1e1490c9c..2841a54018 100644 --- a/examples/wifi/ftm/main/ftm_main.c +++ b/examples/wifi/ftm/main/ftm_main.c @@ -69,6 +69,8 @@ wifi_config_t g_ap_config = { #define ETH_ALEN 6 #define MAX_CONNECT_RETRY_ATTEMPTS 5 +#define DEFAULT_WAIT_TIME_MS (10 * 1000) +#define MAX_FTM_BURSTS 8 #define DEFAULT_AP_CHANNEL 1 #define DEFAULT_AP_BANDWIDTH 20 @@ -84,7 +86,6 @@ static const int DISCONNECTED_BIT = BIT1; static EventGroupHandle_t s_ftm_event_group; static const int FTM_REPORT_BIT = BIT0; static const int FTM_FAILURE_BIT = BIT1; -static wifi_ftm_report_entry_t *s_ftm_report; static uint8_t s_ftm_report_num_entries; static uint32_t s_rtt_est, s_dist_est; static bool s_ap_started; @@ -136,10 +137,12 @@ static void event_handler(void *arg, esp_event_base_t event_base, 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) { xEventGroupSetBits(s_ftm_event_group, FTM_REPORT_BIT); + } else if (event->status == FTM_STATUS_USER_TERM) { + /* Do Nothing */ + ESP_LOGI(TAG_STA, "User terminated FTM procedure"); } else { ESP_LOGI(TAG_STA, "FTM procedure with Peer("MACSTR") failed! (Status - %d)", MAC2STR(event->peer_mac), event->status); @@ -152,21 +155,38 @@ static void event_handler(void *arg, esp_event_base_t event_base, } } -static void ftm_process_report(void) +static void ftm_print_report(void) { int i; char *log = NULL; + wifi_ftm_report_entry_t *ftm_report = NULL; - if (s_ftm_report_num_entries == 0) + if (s_ftm_report_num_entries == 0) { + /* FTM Failure case */ return; + } - if (!g_report_lvl) - return; + if (!g_report_lvl) { + /* No need to print, just free the internal FTM report */ + esp_wifi_ftm_get_report(NULL, 0); + goto exit; + } + + ftm_report = malloc(sizeof(wifi_ftm_report_entry_t) * s_ftm_report_num_entries); + if (!ftm_report) { + ESP_LOGE(TAG_STA, "Failed to alloc buffer for FTM report"); + goto exit; + } + bzero(ftm_report, sizeof(wifi_ftm_report_entry_t) * s_ftm_report_num_entries); + if (ESP_OK != esp_wifi_ftm_get_report(ftm_report, s_ftm_report_num_entries)) { + ESP_LOGE(TAG_STA, "Could not get FTM report"); + goto exit; + } log = malloc(200); if (!log) { ESP_LOGE(TAG_STA, "Failed to alloc buffer for FTM report"); - return; + goto exit; } bzero(log, 200); @@ -180,24 +200,32 @@ static void ftm_process_report(void) bzero(log, 200); if (g_report_lvl & BIT0) { - log_ptr += sprintf(log_ptr, "%6d|", s_ftm_report[i].dlog_token); + log_ptr += sprintf(log_ptr, "%6d|", ftm_report[i].dlog_token); } if (g_report_lvl & BIT1) { - if (s_ftm_report[i].rtt != UINT32_MAX) - log_ptr += sprintf(log_ptr, "%7" PRIi32 " |", s_ftm_report[i].rtt); + if (ftm_report[i].rtt != UINT32_MAX) + log_ptr += sprintf(log_ptr, "%7" PRIi32 " |", 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, - s_ftm_report[i].t2, s_ftm_report[i].t3, s_ftm_report[i].t4); + log_ptr += sprintf(log_ptr, "%14llu |%14llu |%14llu |%14llu |", ftm_report[i].t1, + ftm_report[i].t2, ftm_report[i].t3, ftm_report[i].t4); } if (g_report_lvl & BIT3) { - log_ptr += sprintf(log_ptr, "%6d |", s_ftm_report[i].rssi); + log_ptr += sprintf(log_ptr, "%6d |", ftm_report[i].rssi); } ESP_LOGI(TAG_STA, "|%s", log); } - free(log); + +exit: + if (log) { + free(log); + } + if (ftm_report) { + free(ftm_report); + } + s_ftm_report_num_entries = 0; } void initialise_wifi(void) @@ -244,7 +272,7 @@ static bool wifi_cmd_sta_join(const char *ssid, const char *pass) s_reconnect = false; xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT); ESP_ERROR_CHECK( esp_wifi_disconnect() ); - xEventGroupWaitBits(s_wifi_event_group, DISCONNECTED_BIT, 0, 1, portTICK_RATE_MS); + xEventGroupWaitBits(s_wifi_event_group, DISCONNECTED_BIT, 0, 1, portMAX_DELAY); } s_reconnect = true; @@ -270,7 +298,7 @@ static int wifi_cmd_sta(int argc, char **argv) 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); + xEventGroupWaitBits(s_wifi_event_group, DISCONNECTED_BIT, 0, 1, portMAX_DELAY); return 0; } @@ -457,11 +485,13 @@ static int wifi_cmd_ftm(int argc, char **argv) { int nerrors = arg_parse(argc, argv, (void **) &ftm_args); wifi_ap_record_t *ap_record; + uint32_t wait_time_ms = DEFAULT_WAIT_TIME_MS; EventBits_t bits; wifi_ftm_initiator_cfg_t ftmi_cfg = { .frm_count = 32, .burst_period = 2, + .use_get_report_api = true, }; if (nerrors != 0) { @@ -505,11 +535,11 @@ static int wifi_cmd_ftm(int argc, char **argv) } if (ftm_args.burst_period->count != 0) { - if (ftm_args.burst_period->ival[0] >= 2 && - ftm_args.burst_period->ival[0] < 256) { + if (ftm_args.burst_period->ival[0] >= 0 && + ftm_args.burst_period->ival[0] <= 100) { ftmi_cfg.burst_period = ftm_args.burst_period->ival[0]; } else { - ESP_LOGE(TAG_STA, "Invalid Burst Period! Valid range is 2-255"); + ESP_LOGE(TAG_STA, "Invalid Burst Period! Valid range is 0-100"); return 0; } } @@ -523,17 +553,19 @@ 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; + pdTRUE, pdFALSE, wait_time_ms / portTICK_PERIOD_MS); if (bits & FTM_REPORT_BIT) { + /* Print detailed data from FTM session */ + ftm_print_report(); ESP_LOGI(TAG_STA, "Estimated RTT - %d nSec, Estimated Distance - %d.%02d meters", s_rtt_est, s_dist_est / 100, s_dist_est % 100); + } else if (bits & FTM_FAILURE_BIT) { + /* FTM Failure case */ + ESP_LOGE(TAG_STA, "FTM procedure failed!"); } else { - /* Failure case */ + /* Timeout, end session gracefully */ + ESP_LOGE(TAG_STA, "FTM procedure timed out!"); + esp_wifi_ftm_end_session(); } return 0; @@ -628,7 +660,7 @@ void register_wifi(void) ftm_args.initiator = arg_lit0("I", "ftm_initiator", "FTM Initiator mode"); ftm_args.ssid = arg_str0("s", "ssid", "SSID", "SSID of AP"); ftm_args.frm_count = arg_int0("c", "frm_count", "<0/8/16/24/32/64>", "FTM frames to be exchanged (0: No preference)"); - ftm_args.burst_period = arg_int0("p", "burst_period", "<2-255 (x 100 mSec)>", "Periodicity of FTM bursts in 100's of miliseconds (0: No preference)"); + ftm_args.burst_period = arg_int0("p", "burst_period", "<0-100 (x 100 mSec)>", "Periodicity of FTM bursts in 100's of miliseconds (0: No preference)"); /* FTM Responder commands */ ftm_args.responder = arg_lit0("R", "ftm_responder", "FTM Responder mode"); ftm_args.enable = arg_lit0("e", "enable", "Restart SoftAP with FTM enabled");