mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
wifi/ftm: Additional FTM features implementation
Update wifi lib with below features - 1. ASAP mode for both Initiator and Responder 2. Offchannel FTM while connected to AP (ASAP only) 3. Support up to 3 Initiators simultaneously 4. Session termination, failure support etc 5. Mem-zero AP scan buffer in get_records API
This commit is contained in:
parent
82c6e0628a
commit
c1d5eafd16
@ -1177,6 +1177,31 @@ esp_err_t esp_wifi_set_rssi_threshold(int32_t rssi);
|
||||
*/
|
||||
esp_err_t esp_wifi_ftm_initiate_session(wifi_ftm_initiator_cfg_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief End the ongoing FTM Initiator session
|
||||
*
|
||||
* @attention This API works only on FTM Initiator
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_ftm_end_session(void);
|
||||
|
||||
/**
|
||||
* @brief Set offset in cm for FTM Responder. An equivalent offset is calculated in picoseconds
|
||||
* and added in TOD of FTM Measurement frame (T1).
|
||||
*
|
||||
* @attention Use this API only in AP mode before performing FTM as responder
|
||||
*
|
||||
* @param offset_cm T1 Offset to be added in centimeters
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_ftm_resp_set_offset(int16_t offset_cm);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable 11b rate of specified interface
|
||||
*
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 012747d3cf1901b9600d45aee69e17546bc47b61
|
||||
Subproject commit 8dc3acb6a620b01b9fa69cc8f11e276af8e61580
|
@ -32,18 +32,17 @@ Build and flash the example on a supported device to see below output -
|
||||
==========================================================
|
||||
| Steps to test FTM |
|
||||
| |
|
||||
| 1. Use 'help' to gain overview of commands |
|
||||
| 2. Use 'scan' command to search for external AP's |
|
||||
| 1. Use 'help' for detailed information on parameters |
|
||||
| 2. Start SoftAP with command 'ap <SSID> <password>' |
|
||||
| OR |
|
||||
| 2. Start SoftAP on another device using 'ap' command |
|
||||
| 3. Start FTM with command 'ftm -I -s <SSID>' |
|
||||
| |
|
||||
| 2. Use 'scan' command to search for external AP's |
|
||||
| 3. On second device initiate FTM with an AP using |
|
||||
| command 'ftm -I -s <SSID>' |
|
||||
==========================================================
|
||||
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` is visible in the respective scan result entry.
|
||||
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 <cm0>` to give accurate readings with the Initiator.
|
||||
|
||||
```bash
|
||||
ftm> scan
|
||||
@ -65,17 +64,17 @@ ftm>
|
||||
```
|
||||
|
||||
Issue `ftm -I` to initiate a session with default configuration of 32 FTM frames. For more configurations below options are available -
|
||||
`ftm [-I] [-c <0/16/24/32/64>] [-p <2-255 (x 100 mSec)>] [-s SSID]`
|
||||
`ftm [-I] [-c <0/8/16/24/32/64>] [-p <2-255 (x 100 mSec)>] [-s SSID]`
|
||||
Where -
|
||||
* `-I` OR `--ftm_initiator`: FTM Initiator mode
|
||||
* `-c` OR `--frm_count`: FTM frames to be exchanged (Valid values: 0=No preference, 16, 24, 32, 64, default: 32)
|
||||
* `-c` OR `--frm_count`: FTM frames to be exchanged (Valid values: 0=No preference, 8, 16, 24, 32, 64, default: 32)
|
||||
* `-p` OR `--burst_period`: Periodicity of FTM bursts in 100's of miliseconds (0: No preference, default: 2)
|
||||
* `-s` OR `--ssid=SSID`: SSID of AP that supports FTM Responder mode
|
||||
|
||||
Currently FTM is only supported in below configuration -
|
||||
1. Station as Initiator and SoftAP as Responder on supported ESP devices
|
||||
2. Station as Initiator and an external AP that supports FTM in Responder mode
|
||||
The first option should be preferred since ESP devices are self calibrated for high resolution measurement. FTM Responder support for external Stations and ASAP mode will follow in future updates.
|
||||
The first option should be preferred since ESP devices are self calibrated for high resolution measurement.
|
||||
|
||||
## Example Output
|
||||
Example output of an FTM Procedure -
|
||||
|
@ -34,10 +34,16 @@ typedef struct {
|
||||
} wifi_scan_arg_t;
|
||||
|
||||
typedef struct {
|
||||
struct arg_lit *mode;
|
||||
/* FTM Initiator */
|
||||
struct arg_lit *initiator;
|
||||
struct arg_int *frm_count;
|
||||
struct arg_int *burst_period;
|
||||
struct arg_str *ssid;
|
||||
/* FTM Responder */
|
||||
struct arg_lit *responder;
|
||||
struct arg_lit *enable;
|
||||
struct arg_lit *disable;
|
||||
struct arg_int *offset;
|
||||
struct arg_end *end;
|
||||
} wifi_ftm_args_t;
|
||||
|
||||
@ -46,6 +52,12 @@ static wifi_args_t ap_args;
|
||||
static wifi_scan_arg_t scan_args;
|
||||
static wifi_ftm_args_t ftm_args;
|
||||
|
||||
wifi_config_t g_ap_config = {
|
||||
.ap.max_connection = 4,
|
||||
.ap.authmode = WIFI_AUTH_WPA2_PSK,
|
||||
.ap.ftm_responder = true
|
||||
};
|
||||
|
||||
static bool s_reconnect = true;
|
||||
static const char *TAG_STA = "ftm_station";
|
||||
static const char *TAG_AP = "ftm_ap";
|
||||
@ -60,6 +72,7 @@ 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;
|
||||
bool g_ap_started;
|
||||
|
||||
const int g_report_lvl =
|
||||
#ifdef CONFIG_ESP_FTM_REPORT_SHOW_DIAG
|
||||
@ -79,46 +92,44 @@ const int g_report_lvl =
|
||||
uint16_t g_scan_ap_num;
|
||||
wifi_ap_record_t *g_ap_list_buffer;
|
||||
|
||||
static void wifi_connected_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
static void event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
wifi_event_sta_connected_t *event = (wifi_event_sta_connected_t *)event_data;
|
||||
if (event_id == WIFI_EVENT_STA_CONNECTED) {
|
||||
wifi_event_sta_connected_t *event = (wifi_event_sta_connected_t *)event_data;
|
||||
|
||||
ESP_LOGI(TAG_STA, "Connected to %s (BSSID: "MACSTR", Channel: %d)", event->ssid,
|
||||
MAC2STR(event->bssid), event->channel);
|
||||
ESP_LOGI(TAG_STA, "Connected to %s (BSSID: "MACSTR", Channel: %d)", event->ssid,
|
||||
MAC2STR(event->bssid), event->channel);
|
||||
|
||||
xEventGroupClearBits(wifi_event_group, DISCONNECTED_BIT);
|
||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||
}
|
||||
xEventGroupClearBits(wifi_event_group, DISCONNECTED_BIT);
|
||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||
} else if (event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
if (s_reconnect) {
|
||||
ESP_LOGI(TAG_STA, "sta disconnect, s_reconnect...");
|
||||
esp_wifi_connect();
|
||||
} else {
|
||||
ESP_LOGI(TAG_STA, "sta disconnect");
|
||||
}
|
||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||
xEventGroupSetBits(wifi_event_group, DISCONNECTED_BIT);
|
||||
} else if (event_id == WIFI_EVENT_FTM_REPORT) {
|
||||
wifi_event_ftm_report_t *event = (wifi_event_ftm_report_t *) event_data;
|
||||
|
||||
static void disconnect_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
if (s_reconnect) {
|
||||
ESP_LOGI(TAG_STA, "sta disconnect, s_reconnect...");
|
||||
esp_wifi_connect();
|
||||
} else {
|
||||
ESP_LOGI(TAG_STA, "sta disconnect");
|
||||
}
|
||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||
xEventGroupSetBits(wifi_event_group, DISCONNECTED_BIT);
|
||||
}
|
||||
|
||||
static void ftm_report_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
wifi_event_ftm_report_t *event = (wifi_event_ftm_report_t *) event_data;
|
||||
|
||||
if (event->status == FTM_STATUS_SUCCESS) {
|
||||
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);
|
||||
xEventGroupSetBits(ftm_event_group, FTM_FAILURE_BIT);
|
||||
if (event->status == FTM_STATUS_SUCCESS) {
|
||||
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);
|
||||
xEventGroupSetBits(ftm_event_group, FTM_FAILURE_BIT);
|
||||
}
|
||||
} else if (event_id == WIFI_EVENT_AP_START) {
|
||||
g_ap_started = true;
|
||||
} else if (event_id == WIFI_EVENT_AP_STOP) {
|
||||
g_ap_started = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,21 +189,14 @@ void initialise_wifi(void)
|
||||
ESP_ERROR_CHECK( esp_event_loop_create_default() );
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
|
||||
esp_event_handler_instance_t instance_any_id;
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
WIFI_EVENT_STA_CONNECTED,
|
||||
&wifi_connected_handler,
|
||||
NULL,
|
||||
NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
WIFI_EVENT_STA_DISCONNECTED,
|
||||
&disconnect_handler,
|
||||
NULL,
|
||||
NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
WIFI_EVENT_FTM_REPORT,
|
||||
&ftm_report_handler,
|
||||
NULL,
|
||||
NULL));
|
||||
ESP_EVENT_ANY_ID,
|
||||
&event_handler,
|
||||
NULL,
|
||||
&instance_any_id));
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM) );
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL) );
|
||||
ESP_ERROR_CHECK(esp_wifi_start() );
|
||||
@ -299,34 +303,23 @@ static int wifi_cmd_scan(int argc, char **argv)
|
||||
|
||||
static bool wifi_cmd_ap_set(const char* ssid, const char* pass)
|
||||
{
|
||||
wifi_config_t wifi_config = {
|
||||
.ap = {
|
||||
.ssid = "",
|
||||
.ssid_len = 0,
|
||||
.max_connection = 4,
|
||||
.password = "",
|
||||
.authmode = WIFI_AUTH_WPA2_PSK,
|
||||
.ftm_responder = true
|
||||
},
|
||||
};
|
||||
|
||||
s_reconnect = false;
|
||||
strlcpy((char*) wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid));
|
||||
strlcpy((char*) g_ap_config.ap.ssid, ssid, MAX_SSID_LEN);
|
||||
if (pass) {
|
||||
if (strlen(pass) != 0 && strlen(pass) < 8) {
|
||||
s_reconnect = true;
|
||||
ESP_LOGE(TAG_AP, "password less than 8");
|
||||
return false;
|
||||
}
|
||||
strlcpy((char*) wifi_config.ap.password, pass, sizeof(wifi_config.ap.password));
|
||||
strlcpy((char*) g_ap_config.ap.password, pass, MAX_PASSPHRASE_LEN);
|
||||
}
|
||||
|
||||
if (strlen(pass) == 0) {
|
||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||
g_ap_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &g_ap_config));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -419,10 +412,14 @@ static int wifi_cmd_ftm(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ftm_args.mode->count == 0) {
|
||||
goto ftm_start;
|
||||
if (ftm_args.initiator->count != 0 && ftm_args.responder->count != 0) {
|
||||
ESP_LOGE(TAG_STA, "Invalid FTM cmd argument");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ftm_args.responder->count != 0)
|
||||
goto ftm_responder;
|
||||
|
||||
if (ftm_args.ssid->count == 1) {
|
||||
ap_record = find_ftm_responder_ap(ftm_args.ssid->sval[0]);
|
||||
if (ap_record) {
|
||||
@ -435,9 +432,9 @@ 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 &&
|
||||
if (count != 0 && count != 8 && count != 16 &&
|
||||
count != 24 && count != 32 && count != 64) {
|
||||
ESP_LOGE(TAG_STA, "Invalid Frame Count! Valid options are 0/16/24/32/64");
|
||||
ESP_LOGE(TAG_STA, "Invalid Frame Count! Valid options are 0/8/16/24/32/64");
|
||||
return 0;
|
||||
}
|
||||
ftmi_cfg.frm_count = count;
|
||||
@ -453,7 +450,6 @@ static int wifi_cmd_ftm(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
ftm_start:
|
||||
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);
|
||||
|
||||
@ -477,6 +473,37 @@ ftm_start:
|
||||
/* Failure case */
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
ftm_responder:
|
||||
if (ftm_args.offset->count != 0) {
|
||||
int16_t offset_cm = ftm_args.offset->ival[0];
|
||||
|
||||
esp_wifi_ftm_resp_set_offset(offset_cm);
|
||||
}
|
||||
|
||||
if (ftm_args.enable->count != 0) {
|
||||
if (!g_ap_started) {
|
||||
ESP_LOGE(TAG_AP, "Start the SoftAP first with 'ap' command");
|
||||
return 0;
|
||||
}
|
||||
g_ap_config.ap.ftm_responder = true;
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &g_ap_config));
|
||||
ESP_LOGI(TAG_AP, "Re-starting SoftAP with FTM Responder enabled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ftm_args.disable->count != 0) {
|
||||
if (!g_ap_started) {
|
||||
ESP_LOGE(TAG_AP, "Start the SoftAP first with 'ap' command");
|
||||
return 0;
|
||||
}
|
||||
g_ap_config.ap.ftm_responder = false;
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &g_ap_config));
|
||||
ESP_LOGI(TAG_AP, "Re-starting SoftAP with FTM Responder disabled");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -531,10 +558,16 @@ void register_wifi(void)
|
||||
};
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&query_cmd) );
|
||||
|
||||
ftm_args.mode = arg_lit1("I", "ftm_initiator", "FTM Initiator mode");
|
||||
/* FTM Initiator commands */
|
||||
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/16/24/32/64>", "FTM frames to be exchanged (0: No preference)");
|
||||
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 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");
|
||||
ftm_args.disable = arg_lit0("d", "disable", "Restart SoftAP with FTM disabled");
|
||||
ftm_args.offset = arg_int0("o", "offset", "Offset in cm", "T1 offset in cm for FTM Responder");
|
||||
ftm_args.end = arg_end(1);
|
||||
|
||||
const esp_console_cmd_t ftm_cmd = {
|
||||
@ -572,12 +605,12 @@ void app_main(void)
|
||||
printf("\n ==========================================================\n");
|
||||
printf(" | Steps to test FTM |\n");
|
||||
printf(" | |\n");
|
||||
printf(" | 1. Use 'help' to gain overview of commands |\n");
|
||||
printf(" | 2. Use 'scan' command to search for external AP's |\n");
|
||||
printf(" | 1. Use 'help' for detailed information on parameters |\n");
|
||||
printf(" | 2. Start SoftAP with command 'ap <SSID> <password>' |\n");
|
||||
printf(" | OR |\n");
|
||||
printf(" | 2. Start SoftAP on another device using 'ap' command |\n");
|
||||
printf(" | 3. Start FTM with command 'ftm -I -s <SSID>' |\n");
|
||||
printf(" | |\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 <SSID>' |\n");
|
||||
printf(" ==========================================================\n\n");
|
||||
|
||||
// start console REPL
|
||||
|
Loading…
Reference in New Issue
Block a user