mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/ftm_support' into 'master'
Add FTM support for ESP32-S2 & ESP32-C3 Closes IDFGH-3034 and WIFI-3293 See merge request espressif/esp-idf!10441
This commit is contained in:
commit
20b20eef72
@ -91,6 +91,9 @@ static system_event_id_t esp_event_legacy_wifi_event_id(int32_t event_id)
|
|||||||
case WIFI_EVENT_ROC_DONE:
|
case WIFI_EVENT_ROC_DONE:
|
||||||
return SYSTEM_EVENT_ROC_DONE;
|
return SYSTEM_EVENT_ROC_DONE;
|
||||||
|
|
||||||
|
case WIFI_EVENT_FTM_REPORT:
|
||||||
|
return SYSTEM_EVENT_FTM_REPORT;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ESP_LOGE(TAG, "invalid wifi event id %d", event_id);
|
ESP_LOGE(TAG, "invalid wifi event id %d", event_id);
|
||||||
return SYSTEM_EVENT_MAX;
|
return SYSTEM_EVENT_MAX;
|
||||||
|
@ -70,6 +70,7 @@ esp_err_t esp_event_send_to_default_loop(system_event_t *event)
|
|||||||
HANDLE_SYS_EVENT_ARG(WIFI, SCAN_DONE, scan_done);
|
HANDLE_SYS_EVENT_ARG(WIFI, SCAN_DONE, scan_done);
|
||||||
HANDLE_SYS_EVENT(WIFI, STA_START);
|
HANDLE_SYS_EVENT(WIFI, STA_START);
|
||||||
HANDLE_SYS_EVENT(WIFI, STA_STOP);
|
HANDLE_SYS_EVENT(WIFI, STA_STOP);
|
||||||
|
HANDLE_SYS_EVENT_ARG(WIFI, FTM_REPORT, ftm_report);
|
||||||
|
|
||||||
/* STA events */
|
/* STA events */
|
||||||
HANDLE_SYS_EVENT_ARG(WIFI, STA_CONNECTED, connected);
|
HANDLE_SYS_EVENT_ARG(WIFI, STA_CONNECTED, connected);
|
||||||
@ -207,6 +208,10 @@ static void esp_system_event_debug(const system_event_t* event)
|
|||||||
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_AUTHMODE_CHNAGE, old_mode:%d, new_mode:%d", auth_change->old_mode, auth_change->new_mode);
|
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_AUTHMODE_CHNAGE, old_mode:%d, new_mode:%d", auth_change->old_mode, auth_change->new_mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SYSTEM_EVENT_FTM_REPORT: {
|
||||||
|
ESP_LOGD(TAG, "SYSTEM_EVENT_FTM_REPORT");
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SYSTEM_EVENT_STA_GOT_IP: {
|
case SYSTEM_EVENT_STA_GOT_IP: {
|
||||||
const system_event_sta_got_ip_t *got_ip = &event->event_info.got_ip;
|
const system_event_sta_got_ip_t *got_ip = &event->event_info.got_ip;
|
||||||
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_GOT_IP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR,
|
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_GOT_IP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR,
|
||||||
|
@ -50,6 +50,7 @@ typedef enum {
|
|||||||
SYSTEM_EVENT_AP_PROBEREQRECVED, /*!< Receive probe request packet in soft-AP interface */
|
SYSTEM_EVENT_AP_PROBEREQRECVED, /*!< Receive probe request packet in soft-AP interface */
|
||||||
SYSTEM_EVENT_ACTION_TX_STATUS, /*!< Receive status of Action frame transmitted */
|
SYSTEM_EVENT_ACTION_TX_STATUS, /*!< Receive status of Action frame transmitted */
|
||||||
SYSTEM_EVENT_ROC_DONE, /*!< Indicates the completion of Remain-on-Channel operation status */
|
SYSTEM_EVENT_ROC_DONE, /*!< Indicates the completion of Remain-on-Channel operation status */
|
||||||
|
SYSTEM_EVENT_FTM_REPORT, /*!< Receive report of FTM procedure */
|
||||||
SYSTEM_EVENT_GOT_IP6, /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */
|
SYSTEM_EVENT_GOT_IP6, /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */
|
||||||
SYSTEM_EVENT_ETH_START, /*!< ESP32 ethernet start */
|
SYSTEM_EVENT_ETH_START, /*!< ESP32 ethernet start */
|
||||||
SYSTEM_EVENT_ETH_STOP, /*!< ESP32 ethernet stop */
|
SYSTEM_EVENT_ETH_STOP, /*!< ESP32 ethernet stop */
|
||||||
@ -95,6 +96,9 @@ typedef wifi_event_ap_stadisconnected_t system_event_ap_stadisconnected_t;
|
|||||||
/** Argument structure of event */
|
/** Argument structure of event */
|
||||||
typedef wifi_event_ap_probe_req_rx_t system_event_ap_probe_req_rx_t;
|
typedef wifi_event_ap_probe_req_rx_t system_event_ap_probe_req_rx_t;
|
||||||
|
|
||||||
|
/** Argument structure of SYSTEM_EVENT_FTM_REPORT event */
|
||||||
|
typedef wifi_event_ftm_report_t system_event_ftm_report_t;
|
||||||
|
|
||||||
/** Argument structure of event */
|
/** Argument structure of event */
|
||||||
typedef ip_event_ap_staipassigned_t system_event_ap_staipassigned_t;
|
typedef ip_event_ap_staipassigned_t system_event_ap_staipassigned_t;
|
||||||
|
|
||||||
@ -117,6 +121,7 @@ typedef union {
|
|||||||
system_event_ap_staconnected_t sta_connected; /*!< a station connected to ESP32 soft-AP */
|
system_event_ap_staconnected_t sta_connected; /*!< a station connected to ESP32 soft-AP */
|
||||||
system_event_ap_stadisconnected_t sta_disconnected; /*!< a station disconnected to ESP32 soft-AP */
|
system_event_ap_stadisconnected_t sta_disconnected; /*!< a station disconnected to ESP32 soft-AP */
|
||||||
system_event_ap_probe_req_rx_t ap_probereqrecved; /*!< ESP32 soft-AP receive probe request packet */
|
system_event_ap_probe_req_rx_t ap_probereqrecved; /*!< ESP32 soft-AP receive probe request packet */
|
||||||
|
system_event_ftm_report_t ftm_report; /*!< Report of FTM procedure */
|
||||||
system_event_ap_staipassigned_t ap_staipassigned; /**< ESP32 soft-AP assign an IP to the station*/
|
system_event_ap_staipassigned_t ap_staipassigned; /**< ESP32 soft-AP assign an IP to the station*/
|
||||||
system_event_got_ip6_t got_ip6; /*!< ESP32 station or ap or ethernet ipv6 addr state change to preferred */
|
system_event_got_ip6_t got_ip6; /*!< ESP32 station or ap or ethernet ipv6 addr state change to preferred */
|
||||||
} system_event_info_t;
|
} system_event_info_t;
|
||||||
|
@ -331,6 +331,43 @@ menu "Wi-Fi"
|
|||||||
If neither of them are enabled, the other 7.4KB IRAM memory would be taken by this option.
|
If neither of them are enabled, the other 7.4KB IRAM memory would be taken by this option.
|
||||||
Wi-Fi power-save mode average current would be reduced if this option is enabled.
|
Wi-Fi power-save mode average current would be reduced if this option is enabled.
|
||||||
|
|
||||||
|
config ESP_WIFI_FTM_INITIATOR_SUPPORT
|
||||||
|
bool "FTM Initiator support"
|
||||||
|
default y
|
||||||
|
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3)
|
||||||
|
|
||||||
|
config ESP_WIFI_FTM_REPORT_LOG_ENABLE
|
||||||
|
bool "FTM Report logging"
|
||||||
|
default n
|
||||||
|
depends on ESP_WIFI_FTM_INITIATOR_SUPPORT
|
||||||
|
help
|
||||||
|
Select this option to get a detailed report of FTM Procedure with raw values
|
||||||
|
|
||||||
|
config ESP_WIFI_FTM_REPORT_SHOW_RTT
|
||||||
|
depends on ESP_WIFI_FTM_REPORT_LOG_ENABLE
|
||||||
|
bool "Show RTT values"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config ESP_WIFI_FTM_REPORT_SHOW_DIAG
|
||||||
|
depends on ESP_WIFI_FTM_REPORT_LOG_ENABLE
|
||||||
|
bool "Show dialog tokens"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config ESP_WIFI_FTM_REPORT_SHOW_T1T2T3T4
|
||||||
|
depends on ESP_WIFI_FTM_REPORT_LOG_ENABLE
|
||||||
|
bool "Show T1 to T4"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config ESP_WIFI_FTM_REPORT_SHOW_RSSI
|
||||||
|
depends on ESP_WIFI_FTM_REPORT_LOG_ENABLE
|
||||||
|
bool "Show RSSI levels"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config ESP_WIFI_FTM_RESPONDER_SUPPORT
|
||||||
|
bool "FTM Responder support"
|
||||||
|
default y
|
||||||
|
depends on (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3)
|
||||||
|
|
||||||
endmenu # Wi-Fi
|
endmenu # Wi-Fi
|
||||||
|
|
||||||
menu "PHY"
|
menu "PHY"
|
||||||
|
@ -72,6 +72,17 @@ typedef enum {
|
|||||||
WIFI_LOG_MODULE_MESH, /*logs related to Mesh*/
|
WIFI_LOG_MODULE_MESH, /*logs related to Mesh*/
|
||||||
} wifi_log_module_t;
|
} wifi_log_module_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FTM Report log levels configuration
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t show_rtt:1; /**< Display all valid Round-Trip-Time readings for FTM frames */
|
||||||
|
uint8_t show_diag:1; /**< Display dialogue tokens for all FTM frames with valid readings */
|
||||||
|
uint8_t show_t1t2t3t4:1;/**< Display all valid T1, T2, T3, T4 readings considered while calculating RTT */
|
||||||
|
uint8_t show_rxrssi:1; /**< Display RSSI for each FTM frame with valid readings */
|
||||||
|
} ftm_report_log_level_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief WiFi log submodule definition
|
* @brief WiFi log submodule definition
|
||||||
*
|
*
|
||||||
@ -558,6 +569,18 @@ esp_err_t esp_wifi_internal_set_spp_amsdu(wifi_interface_t ifidx, bool spp_cap,
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void esp_wifi_internal_optimize_wake_ahead_time(void);
|
void esp_wifi_internal_optimize_wake_ahead_time(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set FTM Report log level
|
||||||
|
*
|
||||||
|
* @param log_lvl Log levels configuration
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: succeed
|
||||||
|
* - ESP_ERR_NOT_SUPPORTED: No FTM support
|
||||||
|
*/
|
||||||
|
esp_err_t esp_wifi_set_ftm_report_log_level(ftm_report_log_level_t *log_lvl);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -203,6 +203,8 @@ extern uint64_t g_wifi_feature_caps;
|
|||||||
|
|
||||||
#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0)
|
#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0)
|
||||||
#define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1)
|
#define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1)
|
||||||
|
#define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2)
|
||||||
|
#define CONFIG_FEATURE_FTM_RESPONDER_BIT (1<<3)
|
||||||
|
|
||||||
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
||||||
.event_handler = &esp_event_send_internal, \
|
.event_handler = &esp_event_send_internal, \
|
||||||
@ -1153,6 +1155,20 @@ esp_err_t esp_wifi_statis_dump(uint32_t modules);
|
|||||||
*/
|
*/
|
||||||
esp_err_t esp_wifi_set_rssi_threshold(int32_t rssi);
|
esp_err_t esp_wifi_set_rssi_threshold(int32_t rssi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start an FTM Initiator session by sending FTM request
|
||||||
|
* If successful, event WIFI_EVENT_FTM_REPORT is generated with the result of the FTM procedure
|
||||||
|
*
|
||||||
|
* @attention Use this API only in Station mode
|
||||||
|
*
|
||||||
|
* @param cfg FTM Initiator session configuration
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: succeed
|
||||||
|
* - others: failed
|
||||||
|
*/
|
||||||
|
esp_err_t esp_wifi_ftm_initiate_session(wifi_ftm_initiator_cfg_t *cfg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -178,7 +178,9 @@ typedef struct {
|
|||||||
uint32_t phy_11n:1; /**< bit: 2 flag to identify if 11n mode is enabled or not */
|
uint32_t phy_11n:1; /**< bit: 2 flag to identify if 11n mode is enabled or not */
|
||||||
uint32_t phy_lr:1; /**< bit: 3 flag to identify if low rate is enabled or not */
|
uint32_t phy_lr:1; /**< bit: 3 flag to identify if low rate is enabled or not */
|
||||||
uint32_t wps:1; /**< bit: 4 flag to identify if WPS is supported or not */
|
uint32_t wps:1; /**< bit: 4 flag to identify if WPS is supported or not */
|
||||||
uint32_t reserved:27; /**< bit: 5..31 reserved */
|
uint32_t ftm_responder:1; /**< bit: 5 flag to identify if FTM is supported in responder mode */
|
||||||
|
uint32_t ftm_initiator:1; /**< bit: 6 flag to identify if FTM is supported in initiator mode */
|
||||||
|
uint32_t reserved:25; /**< bit: 7..31 reserved */
|
||||||
wifi_country_t country; /**< country information of AP */
|
wifi_country_t country; /**< country information of AP */
|
||||||
} wifi_ap_record_t;
|
} wifi_ap_record_t;
|
||||||
|
|
||||||
@ -515,6 +517,17 @@ typedef struct {
|
|||||||
uint8_t data[0]; /**< Appended Data payload */
|
uint8_t data[0]; /**< Appended Data payload */
|
||||||
} wifi_action_tx_req_t;
|
} wifi_action_tx_req_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FTM Initiator configuration
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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) */
|
||||||
|
} wifi_ftm_initiator_cfg_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief WiFi PHY rate encodings
|
* @brief WiFi PHY rate encodings
|
||||||
*
|
*
|
||||||
@ -672,6 +685,40 @@ typedef struct {
|
|||||||
int32_t rssi; /**< RSSI value of bss */
|
int32_t rssi; /**< RSSI value of bss */
|
||||||
} wifi_event_bss_rssi_low_t;
|
} wifi_event_bss_rssi_low_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FTM operation status types
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
FTM_STATUS_SUCCESS = 0, /**< FTM exchange is successful */
|
||||||
|
FTM_STATUS_UNSUPPORTED, /**< Peer does not support FTM */
|
||||||
|
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 */
|
||||||
|
} wifi_ftm_status_t;
|
||||||
|
|
||||||
|
/** Argument structure for */
|
||||||
|
typedef struct {
|
||||||
|
uint8_t dlog_token; /**< Dialog Token of the FTM frame */
|
||||||
|
int8_t rssi; /**< RSSI of the FTM frame received */
|
||||||
|
uint32_t rtt; /**< Round Trip Time in pSec with a peer */
|
||||||
|
uint64_t t1; /**< Time of departure of FTM frame from FTM Responder in pSec */
|
||||||
|
uint64_t t2; /**< Time of arrival of FTM frame at FTM Initiator in pSec */
|
||||||
|
uint64_t t3; /**< Time of departure of ACK from FTM Initiator in pSec */
|
||||||
|
uint64_t t4; /**< Time of arrival of ACK at FTM Responder in pSec */
|
||||||
|
} wifi_ftm_report_entry_t;
|
||||||
|
|
||||||
|
/** Argument structure for WIFI_EVENT_FTM_REPORT event */
|
||||||
|
typedef struct {
|
||||||
|
uint8_t peer_mac[6]; /**< MAC address of the FTM Peer */
|
||||||
|
wifi_ftm_status_t status; /**< Status of the FTM operation */
|
||||||
|
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 */
|
||||||
|
uint8_t ftm_report_num_entries; /**< Number of entries in the FTM Report data */
|
||||||
|
} wifi_event_ftm_report_t;
|
||||||
|
|
||||||
#define WIFI_STATIS_BUFFER (1<<0)
|
#define WIFI_STATIS_BUFFER (1<<0)
|
||||||
#define WIFI_STATIS_RXTX (1<<1)
|
#define WIFI_STATIS_RXTX (1<<1)
|
||||||
#define WIFI_STATIS_HW (1<<2)
|
#define WIFI_STATIS_HW (1<<2)
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit bad7d9df47543691d8be80b449f416bf5d581746
|
Subproject commit 56d0911c8a27bd97e7939057bf82c61e82a689e6
|
@ -56,6 +56,12 @@ uint64_t g_wifi_feature_caps =
|
|||||||
#if (CONFIG_ESP32_SPIRAM_SUPPORT | CONFIG_ESP32S2_SPIRAM_SUPPORT)
|
#if (CONFIG_ESP32_SPIRAM_SUPPORT | CONFIG_ESP32S2_SPIRAM_SUPPORT)
|
||||||
CONFIG_FEATURE_CACHE_TX_BUF_BIT |
|
CONFIG_FEATURE_CACHE_TX_BUF_BIT |
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_ESP_WIFI_FTM_INITIATOR_SUPPORT
|
||||||
|
CONFIG_FEATURE_FTM_INITIATOR_BIT |
|
||||||
|
#endif
|
||||||
|
#if CONFIG_ESP_WIFI_FTM_RESPONDER_SUPPORT
|
||||||
|
CONFIG_FEATURE_FTM_RESPONDER_BIT |
|
||||||
|
#endif
|
||||||
0;
|
0;
|
||||||
|
|
||||||
static bool s_wifi_adc_xpd_flag;
|
static bool s_wifi_adc_xpd_flag;
|
||||||
@ -248,6 +254,23 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
adc2_cal_include(); //This enables the ADC2 calibration constructor at start up.
|
adc2_cal_include(); //This enables the ADC2 calibration constructor at start up.
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESP_WIFI_FTM_REPORT_LOG_ENABLE
|
||||||
|
ftm_report_log_level_t log_lvl = {0};
|
||||||
|
#ifdef CONFIG_ESP_WIFI_FTM_REPORT_SHOW_RTT
|
||||||
|
log_lvl.show_rtt = 1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_ESP_WIFI_FTM_REPORT_SHOW_DIAG
|
||||||
|
log_lvl.show_diag = 1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_ESP_WIFI_FTM_REPORT_SHOW_T1T2T3T4
|
||||||
|
log_lvl.show_t1t2t3t4 = 1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_ESP_WIFI_FTM_REPORT_SHOW_RSSI
|
||||||
|
log_lvl.show_rxrssi = 1;
|
||||||
|
#endif
|
||||||
|
esp_wifi_set_ftm_report_log_level(&log_lvl);
|
||||||
|
#endif
|
||||||
esp_wifi_config_info();
|
esp_wifi_config_info();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1459,6 +1459,26 @@ For establishing a secure connection, AP and Station negotiate and agree on the
|
|||||||
|
|
||||||
Detailed information on creating certificates and how to run wpa2_enterprise example on {IDF_TARGET_NAME} can be found in :example:`wifi/wpa2_enterprise`.
|
Detailed information on creating certificates and how to run wpa2_enterprise example on {IDF_TARGET_NAME} can be found in :example:`wifi/wpa2_enterprise`.
|
||||||
|
|
||||||
|
.. only:: esp32s2 or esp32c3
|
||||||
|
|
||||||
|
Wi-Fi Location
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Wi-Fi Location will improve the accuracy of a device's location data beyond the Access Point, which will enable creation of new, feature-rich applications and services such as geo-fencing, network management, navigation and others. One of the protocols used to determine the device location with respect to the Access Point is Fine Timing Measurement which calculates Time-of-Flight of a WiFi frame.
|
||||||
|
|
||||||
|
Fine Timing Measurement (FTM)
|
||||||
|
+++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
FTM is used to measure Wi-Fi Round Trip Time (Wi-Fi RTT) which is the time a WiFi signal takes to travel from a device to another device and back again. Using WiFi RTT the distance between the devices can be calculated with a simple formula of `RTT * c / 2`, where c is the speed of light.
|
||||||
|
FTM uses timestamps given by WiFi interface hardware at the time of arrival or departure of frames exchanged between a pair of devices. One entity called FTM Initiator (mostly a Station device) discovers the FTM Responder (can be a Station or an Access Point) and negotiates to start an FTM procedure. The procedure uses multiple Action frames sent in bursts and its ACK's to gather the timestamps data. FTM Initiator gathers the data in the end to calculate an average Round-Trip-Time.
|
||||||
|
{IDF_TARGET_NAME} supports FTM in below configuration:
|
||||||
|
|
||||||
|
- {IDF_TARGET_NAME} as FTM Initiator in Station mode.
|
||||||
|
- {IDF_TARGET_NAME} as FTM Responder in SoftAP mode.
|
||||||
|
|
||||||
|
Distance measurement using RTT is not accurate, factors such as RF interference, multi-path travel, antenna orientation and lack of calibration increase these inaccuracies. For better results it is suggested to perform FTM between two {IDF_TARGET_NAME} devices as Station and SoftAP.
|
||||||
|
Refer to IDF example :idf_file:`examples/wifi/ftm/README.md` for steps on how to setup and perform FTM.
|
||||||
|
|
||||||
{IDF_TARGET_NAME} Wi-Fi Power-saving Mode
|
{IDF_TARGET_NAME} Wi-Fi Power-saving Mode
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
@ -2318,4 +2338,4 @@ Please refer to a separate document with :doc:`wireshark-user-guide`.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:hidden:
|
:hidden:
|
||||||
|
|
||||||
wireshark-user-guide
|
wireshark-user-guide
|
||||||
|
@ -38,6 +38,12 @@ Show how to scan for all the available APs.
|
|||||||
|
|
||||||
See the [README.md](./scan/README.md) file in the project [scan](./scan/).
|
See the [README.md](./scan/README.md) file in the project [scan](./scan/).
|
||||||
|
|
||||||
|
## FTM(Fine Timing Measurement)
|
||||||
|
|
||||||
|
Shows how to use FTM(Fine Timing Measurement).
|
||||||
|
|
||||||
|
See the [README.md](./ftm/README.md) file in the project [ftm](./ftm/).
|
||||||
|
|
||||||
# More
|
# More
|
||||||
|
|
||||||
See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples.
|
See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples.
|
||||||
|
8
examples/wifi/ftm/CMakeLists.txt
Normal file
8
examples/wifi/ftm/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||||
|
# in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/components)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(ftm)
|
98
examples/wifi/ftm/README.md
Normal file
98
examples/wifi/ftm/README.md
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
| Supported Targets | ESP32-S2 | ESP32-C3 |
|
||||||
|
| ----------------- | -------- | -------- |
|
||||||
|
|
||||||
|
# FTM Example
|
||||||
|
|
||||||
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
One of the ways in which WiFi enabled devices can measure their distance to the Access Point is by measuring Wi-Fi Round Trip Time (Wi-Fi RTT). Wi-Fi RTT is the time a WiFi signal takes to travel from Station to an AP. This time is proportional to the actual distance between them. Given the RTT, the distance can be calculated with below simple formula -
|
||||||
|
|
||||||
|
> distance = RTT * c / 2
|
||||||
|
> (Where c is the speed of light)
|
||||||
|
|
||||||
|
Wi-Fi RTT is calculated using a procedure called Fine Timing Measurement(FTM). During FTM procedure, a burst of Action frames is transmitted by one device(FTM Responder) to another(FTM Initiator) and each of them is ACK'ed. Hardware in both the devices mark time-of-arrival (TOA) and time-of-departure (TOD) of both Action frame and its ACK. In the end, the FTM Initiator collects the data for all pairs of Action frame and ACK and calculates RTT for each pair with below formula -
|
||||||
|
|
||||||
|
> RTT[i] = (T4[i] - T1[i]) - (T3[i] - T2[i]) Where
|
||||||
|
> T1[i] : TOD of i'th Action frame from Responder
|
||||||
|
> T2[i] : TOA of i'th Action frame at Initiator
|
||||||
|
> T3[i] : TOD of i'th ACK from Initiator
|
||||||
|
> T4[i] : TOA of i'th ACK at Responder
|
||||||
|
|
||||||
|
Average RTT is calculated over all such pairs to get a more accurate result.
|
||||||
|
Use this example to perform FTM between a Station and a SoftAP or en external AP that supports FTM Responder mode. Both Station and SoftAP need to be run on the supported ESP targets that support FTM and have it enabled.
|
||||||
|
|
||||||
|
## How to use example
|
||||||
|
|
||||||
|
With this example, users can scan for AP's that support FTM Responder role and perform FTM procedure with different configurations. Below steps show how to do this using 2 devices in Station and SoftAP mode.
|
||||||
|
First make sure that `FTM Initiator support` on Station and `FTM Responder support` on SoftAP is enabled in the project configuration menu (`idf.py menuconfig`). These options are located in `Component config -> Wi-Fi`. Furthermore for getting a per frame detailed report of the FTM procedure on the console, enable `FTM Report logging` option. Users can also access this report data in the example code.
|
||||||
|
Build and flash the example on a supported device to see below output -
|
||||||
|
|
||||||
|
```bash
|
||||||
|
==========================================================
|
||||||
|
| Steps to test FTM |
|
||||||
|
| |
|
||||||
|
| 1. Use 'help' to gain overview of commands |
|
||||||
|
| 2. Use 'scan' command to search for external AP's |
|
||||||
|
| OR |
|
||||||
|
| 2. Start SoftAP on another device using 'ap' command |
|
||||||
|
| 3. Start FTM with 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.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ftm> scan
|
||||||
|
I (476765) ftm_station: sta start to scan
|
||||||
|
ftm> I (478805) ftm_station: [Abeeys Palace][rssi=84]
|
||||||
|
I (478805) ftm_station: [privateproperty][rssi=76]
|
||||||
|
I (478805) ftm_station: [C904][rssi=69]
|
||||||
|
I (478815) ftm_station: [FTM][rssi=-94][FTM Responder]
|
||||||
|
I (478815) ftm_station: [Velop][rssi=-115]
|
||||||
|
I (478825) ftm_station: sta scan done
|
||||||
|
```
|
||||||
|
|
||||||
|
AP's that support FTM Responder mode can be seen in the scan results. Or setup a SoftAP on another device using the `ap` command -
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ftm> ap FTM password
|
||||||
|
I (91271) ftm_ap: Starting SoftAP with FTM Responder support, SSID - FTM, Password - password
|
||||||
|
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]`
|
||||||
|
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)
|
||||||
|
* `-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.
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
Example output of an FTM Procedure -
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ftm> scan
|
||||||
|
I (356414) ftm_station: sta start to scan
|
||||||
|
I (358514) ftm_station: [DigitalFortress][rssi=114]
|
||||||
|
I (358524) ftm_station: [TEST][rssi=-96][FTM Responder]
|
||||||
|
I (358524) ftm_station: sta scan done
|
||||||
|
ftm> ftm -I -s TEST
|
||||||
|
Starting FTM with 18:fe:34:72:50:c9 on channel 1
|
||||||
|
I (391824) ftm_station: Starting FTM Initiator with Frm Count 32, Burst Period - 200mSec
|
||||||
|
W (391834) wifi:Starting FTM session in 0.200 Sec
|
||||||
|
W (393564) wifi:FTM session ends with 26 valid readings out of 31, Avg raw RTT: 49.218 nSec, Avg RSSI: -1
|
||||||
|
I (393564) ftm_station: Estimated RTT - 33 nSec, Estimated Distance - 5.07 meters
|
||||||
|
```
|
||||||
|
|
||||||
|
The final statement gives the average calculated RTT along with an estimated distance between the Station and the AP. This distance is measured by first adjusting the RTT with any physical analog delays and a calibration delta. Distances measured using RTT are not perfectly accurate, and are subjected to various errors like RF interference, multi-path, path loss, orientations etc.
|
||||||
|
The design requires line-of-sight with straightforward propagation path with no less than -70dBm RSSI for better results.
|
2
examples/wifi/ftm/main/CMakeLists.txt
Normal file
2
examples/wifi/ftm/main/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
idf_component_register(SRCS "ftm_main.c"
|
||||||
|
INCLUDE_DIRS ".")
|
533
examples/wifi/ftm/main/ftm_main.c
Normal file
533
examples/wifi/ftm/main/ftm_main.c
Normal file
@ -0,0 +1,533 @@
|
|||||||
|
/* Wi-Fi FTM Example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "cmd_system.h"
|
||||||
|
#include "argtable3/argtable3.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_console.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct arg_str *ssid;
|
||||||
|
struct arg_str *password;
|
||||||
|
struct arg_end *end;
|
||||||
|
} wifi_args_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct arg_str *ssid;
|
||||||
|
struct arg_end *end;
|
||||||
|
} wifi_scan_arg_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct arg_lit *mode;
|
||||||
|
struct arg_int *frm_count;
|
||||||
|
struct arg_int *burst_period;
|
||||||
|
struct arg_str *ssid;
|
||||||
|
struct arg_end *end;
|
||||||
|
} wifi_ftm_args_t;
|
||||||
|
|
||||||
|
static wifi_args_t sta_args;
|
||||||
|
static wifi_args_t ap_args;
|
||||||
|
static wifi_scan_arg_t scan_args;
|
||||||
|
static wifi_ftm_args_t ftm_args;
|
||||||
|
|
||||||
|
static bool s_reconnect = true;
|
||||||
|
static const char *TAG_STA = "ftm_station";
|
||||||
|
static const char *TAG_AP = "ftm_ap";
|
||||||
|
|
||||||
|
static EventGroupHandle_t wifi_event_group;
|
||||||
|
const int CONNECTED_BIT = BIT0;
|
||||||
|
const int DISCONNECTED_BIT = BIT1;
|
||||||
|
|
||||||
|
static EventGroupHandle_t ftm_event_group;
|
||||||
|
const int FTM_REPORT_BIT = BIT0;
|
||||||
|
const int FTM_FAILURE_BIT = BIT1;
|
||||||
|
wifi_ftm_report_entry_t *g_ftm_report;
|
||||||
|
uint8_t g_ftm_report_num_entries;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
xEventGroupClearBits(wifi_event_group, DISCONNECTED_BIT);
|
||||||
|
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
ESP_LOGI(TAG_STA, "Estimated RTT - %d nSec, Estimated Distance - %d.%02d meters", event->rtt_est,
|
||||||
|
event->dist_est / 100, event->dist_est % 100);
|
||||||
|
xEventGroupSetBits(ftm_event_group, FTM_REPORT_BIT);
|
||||||
|
g_ftm_report = event->ftm_report_data;
|
||||||
|
g_ftm_report_num_entries = event->ftm_report_num_entries;
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialise_wifi(void)
|
||||||
|
{
|
||||||
|
esp_log_level_set("wifi", ESP_LOG_WARN);
|
||||||
|
static bool initialized = false;
|
||||||
|
|
||||||
|
if (initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
|
wifi_event_group = xEventGroupCreate();
|
||||||
|
ftm_event_group = xEventGroupCreate();
|
||||||
|
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_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_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() );
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool wifi_cmd_sta_join(const char *ssid, const char *pass)
|
||||||
|
{
|
||||||
|
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0);
|
||||||
|
|
||||||
|
wifi_config_t wifi_config = { 0 };
|
||||||
|
|
||||||
|
strlcpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
|
||||||
|
if (pass) {
|
||||||
|
strlcpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits & CONNECTED_BIT) {
|
||||||
|
s_reconnect = false;
|
||||||
|
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||||
|
ESP_ERROR_CHECK( esp_wifi_disconnect() );
|
||||||
|
xEventGroupWaitBits(wifi_event_group, DISCONNECTED_BIT, 0, 1, portTICK_RATE_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
s_reconnect = true;
|
||||||
|
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||||
|
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
|
||||||
|
ESP_ERROR_CHECK( esp_wifi_connect() );
|
||||||
|
|
||||||
|
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 5000 / portTICK_RATE_MS);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wifi_cmd_sta(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **) &sta_args);
|
||||||
|
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, sta_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool wifi_perform_scan(const char *ssid, bool internal)
|
||||||
|
{
|
||||||
|
wifi_scan_config_t scan_config = { 0 };
|
||||||
|
scan_config.ssid = (uint8_t *) ssid;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||||
|
ESP_ERROR_CHECK( esp_wifi_scan_start(&scan_config, true) );
|
||||||
|
|
||||||
|
esp_wifi_scan_get_ap_num(&g_scan_ap_num);
|
||||||
|
if (g_scan_ap_num == 0) {
|
||||||
|
ESP_LOGI(TAG_STA, "No matching AP found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ap_list_buffer) {
|
||||||
|
free(g_ap_list_buffer);
|
||||||
|
}
|
||||||
|
g_ap_list_buffer = malloc(g_scan_ap_num * sizeof(wifi_ap_record_t));
|
||||||
|
if (g_ap_list_buffer == NULL) {
|
||||||
|
ESP_LOGE(TAG_STA, "Failed to malloc buffer to print scan results");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_wifi_scan_get_ap_records(&g_scan_ap_num, (wifi_ap_record_t *)g_ap_list_buffer) == ESP_OK) {
|
||||||
|
if (!internal) {
|
||||||
|
for (i = 0; i < g_scan_ap_num; i++) {
|
||||||
|
ESP_LOGI(TAG_STA, "[%s][rssi=%d]""%s", g_ap_list_buffer[i].ssid, g_ap_list_buffer[i].rssi,
|
||||||
|
g_ap_list_buffer[i].ftm_responder ? "[FTM Responder]" : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG_STA, "sta scan done");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wifi_cmd_scan(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **) &scan_args);
|
||||||
|
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, scan_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG_STA, "sta start to scan");
|
||||||
|
if ( scan_args.ssid->count == 1 ) {
|
||||||
|
wifi_perform_scan(scan_args.ssid->sval[0], false);
|
||||||
|
} else {
|
||||||
|
wifi_perform_scan(NULL, false);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
s_reconnect = false;
|
||||||
|
strlcpy((char*) wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid));
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(pass) == 0) {
|
||||||
|
wifi_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));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wifi_cmd_ap(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void**) &ap_args);
|
||||||
|
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, ap_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wifi_cmd_query(int argc, char **argv)
|
||||||
|
{
|
||||||
|
wifi_config_t cfg;
|
||||||
|
wifi_mode_t mode;
|
||||||
|
|
||||||
|
esp_wifi_get_mode(&mode);
|
||||||
|
if (WIFI_MODE_AP == mode) {
|
||||||
|
esp_wifi_get_config(WIFI_IF_AP, &cfg);
|
||||||
|
ESP_LOGI(TAG_AP, "AP mode, %s %s", cfg.ap.ssid, cfg.ap.password);
|
||||||
|
} else if (WIFI_MODE_STA == mode) {
|
||||||
|
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0);
|
||||||
|
if (bits & CONNECTED_BIT) {
|
||||||
|
esp_wifi_get_config(WIFI_IF_STA, &cfg);
|
||||||
|
ESP_LOGI(TAG_STA, "sta mode, connected %s", cfg.ap.ssid);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG_STA, "sta mode, disconnected");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG_STA, "NULL mode");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wifi_ap_record_t *find_ftm_responder_ap(const char *ssid)
|
||||||
|
{
|
||||||
|
bool retry_scan = false;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
if (!ssid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
if (!g_ap_list_buffer || (g_scan_ap_num == 0)) {
|
||||||
|
ESP_LOGI(TAG_STA, "Scanning for %s", ssid);
|
||||||
|
if (false == wifi_perform_scan(ssid, true)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < g_scan_ap_num; i++) {
|
||||||
|
if (strcmp((const char *)g_ap_list_buffer[i].ssid, ssid) == 0)
|
||||||
|
return &g_ap_list_buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!retry_scan) {
|
||||||
|
retry_scan = true;
|
||||||
|
if (g_ap_list_buffer) {
|
||||||
|
free(g_ap_list_buffer);
|
||||||
|
g_ap_list_buffer = NULL;
|
||||||
|
}
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG_STA, "No matching AP found");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wifi_cmd_ftm(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **) &ftm_args);
|
||||||
|
wifi_ap_record_t *ap_record;
|
||||||
|
|
||||||
|
wifi_ftm_initiator_cfg_t ftmi_cfg = {
|
||||||
|
.frm_count = 32,
|
||||||
|
.burst_period = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, ftm_args.end, argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftm_args.mode->count == 0) {
|
||||||
|
goto ftm_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftm_args.ssid->count == 1) {
|
||||||
|
ap_record = find_ftm_responder_ap(ftm_args.ssid->sval[0]);
|
||||||
|
if (ap_record) {
|
||||||
|
printf("Starting FTM with " MACSTR " on channel %d\n", MAC2STR(ap_record->bssid),
|
||||||
|
ap_record->primary);
|
||||||
|
memcpy(ftmi_cfg.resp_mac, ap_record->bssid, 6);
|
||||||
|
ftmi_cfg.channel = ap_record->primary;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftm_args.frm_count->count != 0) {
|
||||||
|
uint8_t count = ftm_args.frm_count->ival[0];
|
||||||
|
if (count != 0 && count != 16 && count != 24 &&
|
||||||
|
count != 32 && count != 64) {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
ftmi_cfg.frm_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftm_args.burst_period->count != 0) {
|
||||||
|
if (ftm_args.burst_period->ival[0] >= 2 &&
|
||||||
|
ftm_args.burst_period->ival[0] < 256) {
|
||||||
|
ftmi_cfg.burst_period = ftm_args.burst_period->ival[0];
|
||||||
|
} else {
|
||||||
|
ftmi_cfg.burst_period = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ftm_start:
|
||||||
|
if (ftmi_cfg.burst_period == 0) {
|
||||||
|
ESP_LOGI(TAG_STA, "Starting FTM Initiator with Frm Count %d, Burst Period - No Preference",
|
||||||
|
ftmi_cfg.frm_count);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG_STA, "Starting FTM Initiator with Frm Count %d, Burst Period - %dmSec",
|
||||||
|
ftmi_cfg.frm_count, ftmi_cfg.burst_period * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ESP_OK != esp_wifi_ftm_initiate_session(&ftmi_cfg)) {
|
||||||
|
ESP_LOGE(TAG_STA, "Failed to start FTM session");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventBits_t bits = xEventGroupWaitBits(ftm_event_group, FTM_REPORT_BIT | FTM_FAILURE_BIT,
|
||||||
|
pdFALSE, pdFALSE, portMAX_DELAY);
|
||||||
|
/* Processing data from FTM session */
|
||||||
|
if (bits & FTM_REPORT_BIT) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < g_ftm_report_num_entries; i++) {
|
||||||
|
/* NOTE: Process FTM report elements here, e.g. g_ftm_report[i].rtt etc */
|
||||||
|
}
|
||||||
|
free(g_ftm_report);
|
||||||
|
g_ftm_report = NULL;
|
||||||
|
g_ftm_report_num_entries = 0;
|
||||||
|
xEventGroupClearBits(ftm_event_group, FTM_REPORT_BIT);
|
||||||
|
} else {
|
||||||
|
/* Failure case */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_wifi(void)
|
||||||
|
{
|
||||||
|
sta_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
|
||||||
|
sta_args.password = arg_str0(NULL, NULL, "<pass>", "password of AP");
|
||||||
|
sta_args.end = arg_end(2);
|
||||||
|
|
||||||
|
const esp_console_cmd_t sta_cmd = {
|
||||||
|
.command = "sta",
|
||||||
|
.help = "WiFi is station mode, join specified soft-AP",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_sta,
|
||||||
|
.argtable = &sta_args
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&sta_cmd) );
|
||||||
|
|
||||||
|
ap_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
|
||||||
|
ap_args.password = arg_str0(NULL, NULL, "<pass>", "password of AP");
|
||||||
|
ap_args.end = arg_end(2);
|
||||||
|
|
||||||
|
const esp_console_cmd_t ap_cmd = {
|
||||||
|
.command = "ap",
|
||||||
|
.help = "AP mode, configure ssid and password",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_ap,
|
||||||
|
.argtable = &ap_args
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&ap_cmd) );
|
||||||
|
|
||||||
|
scan_args.ssid = arg_str0(NULL, NULL, "<ssid>", "SSID of AP want to be scanned");
|
||||||
|
scan_args.end = arg_end(1);
|
||||||
|
|
||||||
|
const esp_console_cmd_t scan_cmd = {
|
||||||
|
.command = "scan",
|
||||||
|
.help = "WiFi is station mode, start scan ap",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_scan,
|
||||||
|
.argtable = &scan_args
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&scan_cmd) );
|
||||||
|
|
||||||
|
const esp_console_cmd_t query_cmd = {
|
||||||
|
.command = "query",
|
||||||
|
.help = "query WiFi info",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_query,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&query_cmd) );
|
||||||
|
|
||||||
|
ftm_args.mode = arg_lit1("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.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.end = arg_end(1);
|
||||||
|
|
||||||
|
const esp_console_cmd_t ftm_cmd = {
|
||||||
|
.command = "ftm",
|
||||||
|
.help = "FTM command",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_ftm,
|
||||||
|
.argtable = &ftm_args
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&ftm_cmd) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
esp_err_t ret = nvs_flash_init();
|
||||||
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
ret = nvs_flash_init();
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK( ret );
|
||||||
|
|
||||||
|
initialise_wifi();
|
||||||
|
|
||||||
|
esp_console_repl_t *repl = NULL;
|
||||||
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
|
repl_config.prompt = "ftm>";
|
||||||
|
// init console REPL environment
|
||||||
|
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
|
||||||
|
/* Register commands */
|
||||||
|
register_system();
|
||||||
|
register_wifi();
|
||||||
|
|
||||||
|
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(" | 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(" ==========================================================\n\n");
|
||||||
|
|
||||||
|
// start console REPL
|
||||||
|
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user