Skip to content

Commit

Permalink
Merge branch 'feature/refactor_ftm_code_v4.4' into 'release/v4.4'
Browse files Browse the repository at this point in the history
Refactor and improve FTM code (Backport v4.4)

See merge request espressif/esp-idf!31402
  • Loading branch information
jack0c committed Jun 18, 2024
2 parents 834ae1c + 9d1a374 commit d07bdc7
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 31 deletions.
20 changes: 20 additions & 0 deletions components/esp_wifi/include/esp_wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
11 changes: 8 additions & 3 deletions components/esp_wifi/include/esp_wifi_types.h
Original file line number Diff line number Diff line change
@@ -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
*/
Expand Down Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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 */
Expand All @@ -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;

Expand Down
86 changes: 59 additions & 27 deletions examples/wifi/ftm/main/ftm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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;
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit d07bdc7

Please sign in to comment.