mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-16 04:22:22 +00:00
feat: move iperf to component registry
This commit is contained in:
@@ -1,3 +1,2 @@
|
||||
idf_component_register(SRCS "cmd_wifi.c"
|
||||
"iperf_example_main.c"
|
||||
idf_component_register(SRCS "iperf_example_main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/* Iperf example — declarations of command registration functions.
|
||||
|
||||
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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "cmd_system.h"
|
||||
#include "cmd_wifi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,616 +0,0 @@
|
||||
/* Iperf Example - wifi commands
|
||||
|
||||
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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_console.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "cmd_decl.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_mac.h"
|
||||
#include "iperf.h"
|
||||
#include "esp_coexist.h"
|
||||
#include "wifi_cmd.h"
|
||||
|
||||
typedef struct {
|
||||
struct arg_str *ip;
|
||||
struct arg_lit *server;
|
||||
struct arg_lit *udp;
|
||||
struct arg_lit *version;
|
||||
struct arg_int *port;
|
||||
struct arg_int *length;
|
||||
struct arg_int *interval;
|
||||
struct arg_int *time;
|
||||
struct arg_int *bw_limit;
|
||||
struct arg_lit *abort;
|
||||
struct arg_end *end;
|
||||
} wifi_iperf_t;
|
||||
|
||||
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;
|
||||
|
||||
static wifi_iperf_t iperf_args;
|
||||
static wifi_args_t sta_args;
|
||||
static wifi_scan_arg_t scan_args;
|
||||
static wifi_args_t ap_args;
|
||||
static bool reconnect = true;
|
||||
static const char *TAG = "cmd_wifi";
|
||||
esp_netif_t *netif_ap = NULL;
|
||||
esp_netif_t *netif_sta = NULL;
|
||||
|
||||
EventGroupHandle_t wifi_event_group;
|
||||
const int CONNECTED_BIT = BIT0;
|
||||
const int DISCONNECTED_BIT = BIT1;
|
||||
|
||||
static void scan_done_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
uint16_t sta_number = 0;
|
||||
uint8_t i;
|
||||
wifi_ap_record_t *ap_list_buffer;
|
||||
|
||||
esp_wifi_scan_get_ap_num(&sta_number);
|
||||
if (!sta_number) {
|
||||
ESP_LOGE(TAG, "No AP found");
|
||||
return;
|
||||
}
|
||||
|
||||
ap_list_buffer = malloc(sta_number * sizeof(wifi_ap_record_t));
|
||||
if (ap_list_buffer == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to malloc buffer to print scan results");
|
||||
esp_wifi_clear_ap_list();
|
||||
return;
|
||||
}
|
||||
|
||||
if (esp_wifi_scan_get_ap_records(&sta_number, (wifi_ap_record_t *)ap_list_buffer) == ESP_OK) {
|
||||
for (i = 0; i < sta_number; i++) {
|
||||
#if CONFIG_SOC_WIFI_HE_SUPPORT
|
||||
char ssid_rssi[46] = { 0, };
|
||||
sprintf(ssid_rssi, "[%s][rssi=%d]", ap_list_buffer[i].ssid, ap_list_buffer[i].rssi);
|
||||
if (ap_list_buffer[i].phy_11ax) {
|
||||
ESP_LOGW(TAG,
|
||||
"[%2d]%45s authmode:0x%x, channel:%2d[%d], phymode:%4s, "MACSTR", bssid-index:%d, bss_color:%d, disabled:%d",
|
||||
i, ssid_rssi, ap_list_buffer[i].authmode,
|
||||
ap_list_buffer[i].primary, ap_list_buffer[i].second,
|
||||
ap_list_buffer[i].phy_11ax ? "11ax" : (ap_list_buffer[i].phy_11n ? "11n" :
|
||||
(ap_list_buffer[i].phy_11g ? "11g" : (ap_list_buffer[i].phy_11b ? "11b" : ""))),
|
||||
MAC2STR(ap_list_buffer[i].bssid), ap_list_buffer[i].he_ap.bssid_index,
|
||||
ap_list_buffer[i].he_ap.bss_color, ap_list_buffer[i].he_ap.bss_color_disabled);
|
||||
} else {
|
||||
ESP_LOGI(TAG,
|
||||
"[%2d]%45s authmode:0x%x, channel:%2d[%d], phymode:%4s, "MACSTR"",
|
||||
i, ssid_rssi, ap_list_buffer[i].authmode,
|
||||
ap_list_buffer[i].primary, ap_list_buffer[i].second,
|
||||
ap_list_buffer[i].phy_11ax ? "11ax" : (ap_list_buffer[i].phy_11n ? "11n" :
|
||||
(ap_list_buffer[i].phy_11g ? "11g" : (ap_list_buffer[i].phy_11b ? "11b" : ""))),
|
||||
MAC2STR(ap_list_buffer[i].bssid));
|
||||
}
|
||||
#else
|
||||
ESP_LOGI(TAG, "[%s][rssi=%d]", ap_list_buffer[i].ssid, ap_list_buffer[i].rssi);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
free(ap_list_buffer);
|
||||
ESP_LOGI(TAG, "sta scan done");
|
||||
}
|
||||
|
||||
static void got_ip_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
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 (reconnect) {
|
||||
ESP_LOGI(TAG, "sta disconnect, reconnect...");
|
||||
esp_wifi_connect();
|
||||
} else {
|
||||
ESP_LOGI(TAG, "sta disconnect");
|
||||
}
|
||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||
xEventGroupSetBits(wifi_event_group, DISCONNECTED_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();
|
||||
ESP_ERROR_CHECK( esp_event_loop_create_default() );
|
||||
netif_ap = esp_netif_create_default_wifi_ap();
|
||||
assert(netif_ap);
|
||||
netif_sta = esp_netif_create_default_wifi_sta();
|
||||
assert(netif_sta);
|
||||
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_SCAN_DONE,
|
||||
&scan_done_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(IP_EVENT,
|
||||
IP_EVENT_STA_GOT_IP,
|
||||
&got_ip_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() );
|
||||
|
||||
#if CONFIG_EXTERNAL_COEX_ENABLE
|
||||
esp_external_coex_gpio_set_t gpio_pin;
|
||||
gpio_pin.request = 1;
|
||||
gpio_pin.priority = 2;
|
||||
gpio_pin.grant = 3;
|
||||
#if SOC_EXTERNAL_COEX_LEADER_TX_LINE
|
||||
gpio_pin.tx_line = 4;
|
||||
#endif
|
||||
|
||||
esp_external_coex_set_work_mode(EXTERNAL_COEX_LEADER_ROLE);
|
||||
#if SOC_EXTERNAL_COEX_LEADER_TX_LINE
|
||||
ESP_ERROR_CHECK(esp_enable_extern_coex_gpio_pin(EXTERN_COEX_WIRE_4, gpio_pin));
|
||||
#else
|
||||
ESP_ERROR_CHECK(esp_enable_extern_coex_gpio_pin(EXTERN_COEX_WIRE_3, gpio_pin));
|
||||
#endif /* SOC_EXTERNAL_COEX_LEADER_TX_LINE */
|
||||
#endif /* CONFIG_EXTERNAL_COEX_ENABLE */
|
||||
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||
esp_wifi_enable_rx_statistics(true, true);
|
||||
#else
|
||||
esp_wifi_enable_rx_statistics(true, false);
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
||||
esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true);
|
||||
#endif
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
static bool wifi_cmd_sta_join(const char *ssid, const char *pass, bool enable_he_mcs9)
|
||||
{
|
||||
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 (enable_he_mcs9 == true) {
|
||||
wifi_config.sta.he_mcs9_enabled = 1;
|
||||
}
|
||||
|
||||
if (bits & CONNECTED_BIT) {
|
||||
reconnect = false;
|
||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||
ESP_ERROR_CHECK( esp_wifi_disconnect() );
|
||||
xEventGroupWaitBits(wifi_event_group, DISCONNECTED_BIT, 0, 1, portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
reconnect = true;
|
||||
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
|
||||
esp_wifi_connect();
|
||||
|
||||
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 5000 / portTICK_PERIOD_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 connecting to '%s'", sta_args.ssid->sval[0]);
|
||||
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
|
||||
wifi_cmd_sta_join(sta_args.ssid->sval[0], sta_args.password->sval[0], false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_cmd_sta40(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_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_protocol(0, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_bandwidth(0, WIFI_BW_HT40));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
|
||||
|
||||
ESP_LOGI(TAG, "sta connecting to '%s'", sta_args.ssid->sval[0]);
|
||||
wifi_cmd_sta_join(sta_args.ssid->sval[0], sta_args.password->sval[0], false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_cmd_sta_mcs89(int argc, char **argv)
|
||||
{
|
||||
#if CONFIG_SOC_WIFI_HE_SUPPORT
|
||||
int nerrors = arg_parse(argc, argv, (void **) &sta_args);
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, sta_args.end, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_protocol(0, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_bandwidth(0, WIFI_BW_HT20));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
|
||||
|
||||
ESP_LOGI(TAG, "sta connecting to '%s'", sta_args.ssid->sval[0]);
|
||||
wifi_cmd_sta_join(sta_args.ssid->sval[0], sta_args.password->sval[0], true);
|
||||
#else
|
||||
ESP_LOGW(TAG, "HE-MCS[0, 9] is not supported");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool wifi_cmd_sta_scan(const char *ssid)
|
||||
{
|
||||
wifi_scan_config_t scan_config = { 0 };
|
||||
scan_config.ssid = (uint8_t *) ssid;
|
||||
|
||||
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||
esp_wifi_scan_start(&scan_config, false);
|
||||
|
||||
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 start to scan");
|
||||
if ( scan_args.ssid->count == 1 ) {
|
||||
wifi_cmd_sta_scan(scan_args.ssid->sval[0]);
|
||||
} else {
|
||||
wifi_cmd_sta_scan(NULL);
|
||||
}
|
||||
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_WPA_WPA2_PSK
|
||||
},
|
||||
};
|
||||
|
||||
reconnect = false;
|
||||
strlcpy((char *) wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid));
|
||||
if (pass) {
|
||||
if (strlen(pass) != 0 && strlen(pass) < 8) {
|
||||
reconnect = true;
|
||||
ESP_LOGE(TAG, "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(WIFI_IF_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 mode, %s %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 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 mode, connected %s", cfg.ap.ssid);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "sta mode, disconnected");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGI(TAG, "NULL mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t wifi_get_local_ip(void)
|
||||
{
|
||||
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0);
|
||||
esp_netif_t *netif = netif_ap;
|
||||
esp_netif_ip_info_t ip_info;
|
||||
wifi_mode_t mode;
|
||||
|
||||
esp_wifi_get_mode(&mode);
|
||||
if (WIFI_MODE_STA == mode) {
|
||||
bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0);
|
||||
if (bits & CONNECTED_BIT) {
|
||||
netif = netif_sta;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "sta has no IP");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
esp_netif_get_ip_info(netif, &ip_info);
|
||||
return ip_info.ip.addr;
|
||||
}
|
||||
|
||||
static int wifi_cmd_iperf(int argc, char **argv)
|
||||
{
|
||||
int nerrors = arg_parse(argc, argv, (void **) &iperf_args);
|
||||
iperf_cfg_t cfg;
|
||||
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, iperf_args.end, argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
// now wifi iperf only support IPV4 address
|
||||
cfg.type = IPERF_IP_TYPE_IPV4;
|
||||
|
||||
if ( iperf_args.abort->count != 0) {
|
||||
iperf_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( ((iperf_args.ip->count == 0) && (iperf_args.server->count == 0)) ||
|
||||
((iperf_args.ip->count != 0) && (iperf_args.server->count != 0)) ) {
|
||||
ESP_LOGE(TAG, "should specific client/server mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iperf_args.ip->count == 0) {
|
||||
cfg.flag |= IPERF_FLAG_SERVER;
|
||||
} else {
|
||||
cfg.destination_ip4 = esp_ip4addr_aton(iperf_args.ip->sval[0]);
|
||||
cfg.flag |= IPERF_FLAG_CLIENT;
|
||||
}
|
||||
|
||||
cfg.source_ip4 = wifi_get_local_ip();
|
||||
if (cfg.source_ip4 == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iperf_args.udp->count == 0) {
|
||||
cfg.flag |= IPERF_FLAG_TCP;
|
||||
} else {
|
||||
cfg.flag |= IPERF_FLAG_UDP;
|
||||
}
|
||||
|
||||
if (iperf_args.length->count == 0) {
|
||||
cfg.len_send_buf = 0;
|
||||
} else {
|
||||
cfg.len_send_buf = iperf_args.length->ival[0];
|
||||
}
|
||||
|
||||
if (iperf_args.port->count == 0) {
|
||||
cfg.sport = IPERF_DEFAULT_PORT;
|
||||
cfg.dport = IPERF_DEFAULT_PORT;
|
||||
} else {
|
||||
if (cfg.flag & IPERF_FLAG_SERVER) {
|
||||
cfg.sport = iperf_args.port->ival[0];
|
||||
cfg.dport = IPERF_DEFAULT_PORT;
|
||||
} else {
|
||||
cfg.sport = IPERF_DEFAULT_PORT;
|
||||
cfg.dport = iperf_args.port->ival[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (iperf_args.interval->count == 0) {
|
||||
cfg.interval = IPERF_DEFAULT_INTERVAL;
|
||||
} else {
|
||||
cfg.interval = iperf_args.interval->ival[0];
|
||||
if (cfg.interval <= 0) {
|
||||
cfg.interval = IPERF_DEFAULT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (iperf_args.time->count == 0) {
|
||||
cfg.time = IPERF_DEFAULT_TIME;
|
||||
} else {
|
||||
cfg.time = iperf_args.time->ival[0];
|
||||
if (cfg.time <= cfg.interval) {
|
||||
cfg.time = cfg.interval;
|
||||
}
|
||||
}
|
||||
|
||||
/* iperf -b */
|
||||
if (iperf_args.bw_limit->count == 0) {
|
||||
cfg.bw_lim = IPERF_DEFAULT_NO_BW_LIMIT;
|
||||
} else {
|
||||
cfg.bw_lim = iperf_args.bw_limit->ival[0];
|
||||
if (cfg.bw_lim <= 0) {
|
||||
cfg.bw_lim = IPERF_DEFAULT_NO_BW_LIMIT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ESP_LOGI(TAG, "mode=%s-%s sip=%" PRId32 ".%" PRId32 ".%" PRId32 ".%" PRId32 ":%d,\
|
||||
dip=%" PRId32 ".%" PRId32 ".%" PRId32 ".%" PRId32 ":%d,\
|
||||
interval=%" PRId32 ", time=%" PRId32 "",
|
||||
cfg.flag & IPERF_FLAG_TCP ? "tcp" : "udp",
|
||||
cfg.flag & IPERF_FLAG_SERVER ? "server" : "client",
|
||||
cfg.source_ip4 & 0xFF, (cfg.source_ip4 >> 8) & 0xFF, (cfg.source_ip4 >> 16) & 0xFF,
|
||||
(cfg.source_ip4 >> 24) & 0xFF, cfg.sport,
|
||||
cfg.destination_ip4 & 0xFF, (cfg.destination_ip4 >> 8) & 0xFF,
|
||||
(cfg.destination_ip4 >> 16) & 0xFF, (cfg.destination_ip4 >> 24) & 0xFF, cfg.dport,
|
||||
cfg.interval, cfg.time);
|
||||
|
||||
iperf_start(&cfg);
|
||||
|
||||
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) );
|
||||
|
||||
const esp_console_cmd_t sta40_cmd = {
|
||||
.command = "sta40",
|
||||
.help = "WiFi is station mode, set protocol to bgn and cbw to 40MHz, join a specified AP",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_sta40,
|
||||
.argtable = &sta_args
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&sta40_cmd) );
|
||||
|
||||
const esp_console_cmd_t stamcs89_cmd = {
|
||||
.command = "stamcs89",
|
||||
.help = "WiFi is station mode, set protocol to ax and mcs set to HE-MCS[0,9], join a specified AP",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_sta_mcs89,
|
||||
.argtable = &sta_args
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&stamcs89_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
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&scan_cmd) );
|
||||
|
||||
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) );
|
||||
|
||||
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) );
|
||||
|
||||
iperf_args.ip = arg_str0("c", "client", "<ip>", "run in client mode, connecting to <host>");
|
||||
iperf_args.server = arg_lit0("s", "server", "run in server mode");
|
||||
iperf_args.udp = arg_lit0("u", "udp", "use UDP rather than TCP");
|
||||
iperf_args.version = arg_lit0("V", "ipv6_domain", "use IPV6 address rather than IPV4");
|
||||
iperf_args.port = arg_int0("p", "port", "<port>", "server port to listen on/connect to");
|
||||
iperf_args.length = arg_int0("l", "len", "<length>", "Set read/write buffer size");
|
||||
iperf_args.interval = arg_int0("i", "interval", "<interval>", "seconds between periodic bandwidth reports");
|
||||
iperf_args.time = arg_int0("t", "time", "<time>", "time in seconds to transmit for (default 10 secs)");
|
||||
iperf_args.bw_limit = arg_int0("b", "bandwidth", "<bandwidth>", "bandwidth to send at in Mbits/sec");
|
||||
iperf_args.abort = arg_lit0("a", "abort", "abort running iperf");
|
||||
iperf_args.end = arg_end(1);
|
||||
const esp_console_cmd_t iperf_cmd = {
|
||||
.command = "iperf",
|
||||
.help = "iperf command",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_iperf,
|
||||
.argtable = &iperf_args
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK( esp_console_cmd_register(&iperf_cmd) );
|
||||
|
||||
register_wifi_cmd();
|
||||
register_wifi_stats();
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Register WiFi functions
|
||||
void register_wifi(void);
|
||||
void initialise_wifi(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,9 @@
|
||||
dependencies:
|
||||
cmd_system:
|
||||
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system
|
||||
iperf:
|
||||
path: ${IDF_PATH}/examples/common_components/iperf
|
||||
espressif/iperf-cmd:
|
||||
version: "~0.1.1"
|
||||
esp-qa/wifi-cmd:
|
||||
version: "~0.0.2"
|
||||
esp-qa/ping-cmd:
|
||||
version: "~0.0.1"
|
||||
|
||||
@@ -14,7 +14,58 @@
|
||||
#include "esp_err.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_console.h"
|
||||
#include "cmd_decl.h"
|
||||
#include "cmd_system.h"
|
||||
|
||||
/* component manager */
|
||||
#include "iperf.h"
|
||||
#include "wifi_cmd.h"
|
||||
#include "iperf_cmd.h"
|
||||
#include "ping_cmd.h"
|
||||
|
||||
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||
#include "esp_wifi_he.h"
|
||||
#endif
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
||||
extern int wifi_cmd_get_tx_statistics(int argc, char **argv);
|
||||
extern int wifi_cmd_clr_tx_statistics(int argc, char **argv);
|
||||
#endif
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||
extern int wifi_cmd_get_rx_statistics(int argc, char **argv);
|
||||
extern int wifi_cmd_clr_rx_statistics(int argc, char **argv);
|
||||
#endif
|
||||
|
||||
|
||||
void iperf_hook_show_wifi_stats(iperf_traffic_type_t type, iperf_status_t status)
|
||||
{
|
||||
if (status == IPERF_STARTED) {
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
||||
if (type != IPERF_UDP_SERVER) {
|
||||
wifi_cmd_clr_tx_statistics(0, NULL);
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||
if (type != IPERF_UDP_CLIENT) {
|
||||
wifi_cmd_clr_rx_statistics(0, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (status == IPERF_STOPPED) {
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
||||
if (type != IPERF_UDP_SERVER) {
|
||||
wifi_cmd_get_tx_statistics(0, NULL);
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||
if (type != IPERF_UDP_SERVER) {
|
||||
wifi_cmd_get_rx_statistics(0, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
@@ -25,7 +76,22 @@ void app_main(void)
|
||||
}
|
||||
ESP_ERROR_CHECK( ret );
|
||||
|
||||
initialise_wifi();
|
||||
/* initialise wifi */
|
||||
app_wifi_initialise_config_t config = APP_WIFI_CONFIG_DEFAULT();
|
||||
config.storage = WIFI_STORAGE_RAM;
|
||||
config.ps_type = WIFI_PS_NONE;
|
||||
app_initialise_wifi(&config);
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||
esp_wifi_enable_rx_statistics(true, true);
|
||||
#else
|
||||
esp_wifi_enable_rx_statistics(true, false);
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
||||
esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true);
|
||||
#endif
|
||||
|
||||
|
||||
esp_console_repl_t *repl = NULL;
|
||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||
@@ -45,7 +111,11 @@ void app_main(void)
|
||||
|
||||
/* Register commands */
|
||||
register_system();
|
||||
register_wifi();
|
||||
app_register_all_wifi_commands();
|
||||
app_register_iperf_commands();
|
||||
app_register_ping_commands();
|
||||
app_register_iperf_hook_func(iperf_hook_show_wifi_stats);
|
||||
|
||||
|
||||
printf("\n ==================================================\n");
|
||||
printf(" | Steps to test WiFi throughput |\n");
|
||||
|
||||
@@ -16,19 +16,12 @@ The test env wifi_iperf do need the following config::
|
||||
|
||||
"""
|
||||
import os
|
||||
import time
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Tuple
|
||||
|
||||
import pexpect
|
||||
import pytest
|
||||
from common_test_methods import get_env_config_variable
|
||||
from common_test_methods import get_host_ip_by_interface
|
||||
from idf_iperf_test_util import IperfUtility
|
||||
from idf_iperf_test_util.IperfUtility import SCAN_RETRY_COUNT
|
||||
from idf_iperf_test_util.IperfUtility import SCAN_TIMEOUT
|
||||
from idf_iperf_test_util.IperfUtility import TEST_TIME
|
||||
from pytest_embedded import Dut
|
||||
|
||||
# configurations
|
||||
@@ -39,105 +32,6 @@ NO_BANDWIDTH_LIMIT = -1 # iperf send bandwith is not limited
|
||||
BEST_PERFORMANCE_CONFIG = '99'
|
||||
|
||||
|
||||
class IperfTestUtilitySoftap(IperfUtility.IperfTestUtility):
|
||||
""" iperf test implementation """
|
||||
def __init__(self, dut: Dut, softap_dut: Dut, config_name:str, test_result:Any=None) -> None:
|
||||
IperfUtility.IperfTestUtility.__init__(self, dut, config_name, 'softap', '1234567890', None, None, test_result)
|
||||
self.softap_dut = softap_dut
|
||||
self.softap_ip = '192.168.4.1'
|
||||
|
||||
def setup(self) -> Tuple[str,int]:
|
||||
"""
|
||||
setup iperf test:
|
||||
|
||||
1. kill current iperf process
|
||||
2. reboot DUT (currently iperf is not very robust, need to reboot DUT)
|
||||
3. scan to get AP RSSI
|
||||
4. connect to AP
|
||||
"""
|
||||
self.softap_dut.write('restart')
|
||||
self.softap_dut.expect_exact("Type 'help' to get the list of commands.")
|
||||
self.softap_dut.expect('iperf>', timeout=30)
|
||||
self.softap_dut.write('ap {} {}'.format(self.ap_ssid, self.ap_password))
|
||||
self.dut.write('restart')
|
||||
self.dut.expect_exact("Type 'help' to get the list of commands.")
|
||||
self.dut.expect('iperf>', timeout=30)
|
||||
self.dut.write('scan {}'.format(self.ap_ssid))
|
||||
for _ in range(SCAN_RETRY_COUNT):
|
||||
try:
|
||||
rssi = int(self.dut.expect(r'\[{}]\[rssi=(-\d+)]'.format(self.ap_ssid),
|
||||
timeout=SCAN_TIMEOUT).group(1))
|
||||
break
|
||||
except pexpect.TIMEOUT:
|
||||
continue
|
||||
else:
|
||||
raise AssertionError('Failed to scan AP')
|
||||
self.dut.write('sta {} {}'.format(self.ap_ssid, self.ap_password))
|
||||
dut_ip = self.dut.expect(r'sta ip: ([\d.]+), mask: ([\d.]+), gw: ([\d.]+)').group(1).decode('utf-8')
|
||||
return dut_ip, rssi
|
||||
|
||||
def _test_once(self, proto:str, direction:str, bw_limit:int) -> Tuple[str, int, int]:
|
||||
""" do measure once for one type """
|
||||
# connect and scan to get RSSI
|
||||
dut_ip, rssi = self.setup()
|
||||
|
||||
assert direction in ['rx', 'tx']
|
||||
assert proto in ['tcp', 'udp']
|
||||
|
||||
# run iperf test
|
||||
if direction == 'tx':
|
||||
if proto == 'tcp':
|
||||
self.softap_dut.write('iperf -s -i 1 -t {}'.format(TEST_TIME))
|
||||
# wait until DUT TCP server created
|
||||
try:
|
||||
self.softap_dut.expect('iperf tcp server create successfully', timeout=1)
|
||||
except pexpect.TIMEOUT:
|
||||
# compatible with old iperf example binary
|
||||
pass
|
||||
if bw_limit > 0:
|
||||
self.dut.write('iperf -c {} -i 1 -t {} -b {}'.format(self.softap_ip, TEST_TIME, bw_limit))
|
||||
else:
|
||||
self.dut.write('iperf -c {} -i 1 -t {}'.format(self.softap_ip, TEST_TIME))
|
||||
else:
|
||||
self.softap_dut.write('iperf -s -u -i 1 -t {}'.format(TEST_TIME))
|
||||
if bw_limit > 0:
|
||||
self.dut.write('iperf -c {} -u -i 1 -t {} -b {}'.format(self.softap_ip, TEST_TIME, bw_limit))
|
||||
else:
|
||||
self.dut.write('iperf -c {} -u -i 1 -t {}'.format(self.softap_ip, TEST_TIME))
|
||||
else:
|
||||
if proto == 'tcp':
|
||||
self.dut.write('iperf -s -i 1 -t {}'.format(TEST_TIME))
|
||||
# wait until DUT TCP server created
|
||||
try:
|
||||
self.dut.expect('iperf tcp server create successfully', timeout=1)
|
||||
except pexpect.TIMEOUT:
|
||||
# compatible with old iperf example binary
|
||||
pass
|
||||
if bw_limit > 0:
|
||||
self.softap_dut.write('iperf -c {} -i 1 -t {} -b {}'.format(dut_ip, TEST_TIME, bw_limit))
|
||||
else:
|
||||
self.softap_dut.write('iperf -c {} -i 1 -t {}'.format(dut_ip, TEST_TIME))
|
||||
else:
|
||||
self.dut.write('iperf -s -u -i 1 -t {}'.format(TEST_TIME))
|
||||
if bw_limit > 0:
|
||||
self.softap_dut.write('iperf -c {} -u -i 1 -t {} -b {}'.format(dut_ip, TEST_TIME, bw_limit))
|
||||
else:
|
||||
self.softap_dut.write('iperf -c {} -u -i 1 -t {}'.format(dut_ip, TEST_TIME))
|
||||
time.sleep(TEST_TIME + 5)
|
||||
|
||||
if direction == 'tx':
|
||||
server_raw_data = self.dut.expect(pexpect.TIMEOUT, timeout=0).decode('utf-8')
|
||||
else:
|
||||
server_raw_data = self.dut.expect(pexpect.TIMEOUT, timeout=0).decode('utf-8')
|
||||
self.dut.write('iperf -a')
|
||||
self.softap_dut.write('iperf -a')
|
||||
self.dut.write('heap')
|
||||
heap_size = self.dut.expect(r'min heap size: (\d+)\D').group(1)
|
||||
|
||||
# return server raw data (for parsing test results) and RSSI
|
||||
return server_raw_data, rssi, heap_size
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32s2', 'esp32c3', 'esp32s3'], reason='lack of runners (run only for ESP32)')
|
||||
@pytest.mark.timeout(1200)
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
idf_component_register(SRCS "itwt.c"
|
||||
idf_component_register(SRCS "itwt_main.c"
|
||||
"wifi_stats_cmd.c"
|
||||
"wifi_itwt_cmd.c"
|
||||
INCLUDE_DIRS ".")
|
||||
|
||||
@@ -3,7 +3,3 @@ dependencies:
|
||||
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system
|
||||
cmd_nvs:
|
||||
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_nvs
|
||||
cmd_wifi:
|
||||
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_wifi
|
||||
iperf:
|
||||
path: ${IDF_PATH}/examples/common_components/iperf
|
||||
|
||||
@@ -26,11 +26,12 @@
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_console.h"
|
||||
#include "cmd_system.h"
|
||||
#include "wifi_cmd.h"
|
||||
#include "esp_wifi_he.h"
|
||||
#include "esp_pm.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
#include "wifi_cmd.h"
|
||||
|
||||
/*******************************************************
|
||||
* Constants
|
||||
*******************************************************/
|
||||
18
examples/wifi/itwt/main/wifi_cmd.h
Normal file
18
examples/wifi/itwt/main/wifi_cmd.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void register_wifi_itwt(void);
|
||||
void register_wifi_stats(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
227
examples/wifi/itwt/main/wifi_itwt_cmd.c
Normal file
227
examples/wifi/itwt/main/wifi_itwt_cmd.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#if CONFIG_SOC_WIFI_HE_SUPPORT
|
||||
|
||||
#include "esp_console.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_wifi_he.h"
|
||||
|
||||
/*******************************************************
|
||||
* Constants
|
||||
*******************************************************/
|
||||
static const char *TAG = "twt";
|
||||
|
||||
/*******************************************************
|
||||
* Structures
|
||||
*******************************************************/
|
||||
typedef struct {
|
||||
struct arg_int *setup;
|
||||
struct arg_int *teardown;
|
||||
struct arg_int *suspend;
|
||||
struct arg_int *trigger; //1-trigger-enabled, 0-non-trigger-enabled, setup
|
||||
struct arg_int *flowtype; //1-unannounced, 0-announced, setup
|
||||
struct arg_int *negtype;
|
||||
struct arg_int *wakeinvlexp; //setup
|
||||
struct arg_int *wakeduraunit; //1-TU, 0-256us
|
||||
struct arg_int *wakeinvlman; //setup
|
||||
struct arg_int *minwakedur; //setup
|
||||
struct arg_int *flowid;
|
||||
struct arg_int *twtid;
|
||||
struct arg_int *setup_timeout_time_ms;
|
||||
struct arg_int *suspend_time_ms;
|
||||
struct arg_int *all_twt;
|
||||
struct arg_end *end;
|
||||
} wifi_itwt_args_t;
|
||||
|
||||
typedef struct {
|
||||
struct arg_int *timeout;
|
||||
struct arg_end *end;
|
||||
} wifi_itwt_send_probereq_t;
|
||||
|
||||
/*******************************************************
|
||||
* Variable Definitions
|
||||
*******************************************************/
|
||||
static wifi_itwt_args_t itwt_args;
|
||||
static wifi_itwt_send_probereq_t itwt_probe_args;
|
||||
|
||||
/*******************************************************
|
||||
* Function Declarations
|
||||
*******************************************************/
|
||||
|
||||
/*******************************************************
|
||||
* Function Definitions
|
||||
*******************************************************/
|
||||
static int wifi_cmd_itwt(int argc, char **argv)
|
||||
{
|
||||
int nerrors = arg_parse(argc, argv, (void **) &itwt_args);
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, itwt_args.end, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
if (itwt_args.setup->count) {
|
||||
if (itwt_args.wakeinvlman->count) {
|
||||
if (itwt_args.wakeinvlman->ival[0] < 0 || itwt_args.wakeinvlman->ival[0] > 65535) {
|
||||
ESP_LOGE(TAG, "(itwt)expect [0, 65535], wake_invl_mant: %d", itwt_args.wakeinvlman->ival[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (itwt_args.wakeinvlexp->count) {
|
||||
if (itwt_args.wakeinvlexp->ival[0] < 0 || itwt_args.wakeinvlexp->ival[0] > 31) {
|
||||
ESP_LOGE(TAG, "(itwt)expect [0, 31], wake_invl_expn: %d", itwt_args.wakeinvlexp->ival[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (itwt_args.minwakedur->count) {
|
||||
if (itwt_args.minwakedur->ival[0] < 0 || itwt_args.minwakedur->ival[0] > 255) {
|
||||
ESP_LOGE(TAG, "(itwt)expect [0, 255], min_wake_dura: %d", itwt_args.minwakedur->ival[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (itwt_args.wakeduraunit->count) {
|
||||
if (itwt_args.wakeduraunit->ival[0] < 0 || itwt_args.wakeduraunit->ival[0] > 1) {
|
||||
ESP_LOGE(TAG, "(itwt)expect [0, 1], wake duration unit: %d", itwt_args.wakeduraunit->ival[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (itwt_args.twtid->count) {
|
||||
if (itwt_args.twtid->ival[0] < 0 || itwt_args.twtid->ival[0] > 32767) {
|
||||
ESP_LOGE(TAG, "(itwt)expect [0, 32767], twt id: %d", itwt_args.twtid->ival[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (itwt_args.setup_timeout_time_ms->count) {
|
||||
if (itwt_args.setup_timeout_time_ms->ival[0] < 0 || itwt_args.setup_timeout_time_ms->ival[0] > 65535) {
|
||||
ESP_LOGE(TAG, "(itwt)expect [0, 65535], setup timeout time: %d", itwt_args.setup_timeout_time_ms->ival[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
wifi_twt_setup_config_t setup_config = {
|
||||
.setup_cmd = (itwt_args.setup->ival[0] <= TWT_DEMAND) ? itwt_args.setup->ival[0] : TWT_REQUEST,
|
||||
.flow_id = 0,
|
||||
.twt_id = itwt_args.twtid->count ? itwt_args.twtid->ival[0] : 0,
|
||||
.flow_type = itwt_args.flowtype->count ? ((itwt_args.flowtype->ival[0] == 0) ? 0 : 1) : 0,
|
||||
.min_wake_dura = itwt_args.minwakedur->count ? itwt_args.minwakedur->ival[0] : 255,
|
||||
.wake_duration_unit = itwt_args.wakeduraunit->count ? itwt_args.wakeduraunit->ival[0] : 0,
|
||||
.wake_invl_expn = itwt_args.wakeinvlexp->count ? itwt_args.wakeinvlexp->ival[0] : 10,
|
||||
.wake_invl_mant = itwt_args.wakeinvlman->count ? itwt_args.wakeinvlman->ival[0] : 512,
|
||||
.trigger = itwt_args.trigger->count ? (itwt_args.trigger->ival[0] ? 1 : 0) : 1,
|
||||
.timeout_time_ms = itwt_args.setup_timeout_time_ms->count ? itwt_args.setup_timeout_time_ms->ival[0] : 5000,
|
||||
};
|
||||
err = esp_wifi_sta_itwt_setup(&setup_config);
|
||||
ESP_LOGI(TAG, "(itwt)setup, trigger:%d, %s, flow_id:%d, err:0x%x",
|
||||
setup_config.trigger, setup_config.flow_type ? "unannounce" : "announced", setup_config.flow_id, err);
|
||||
}
|
||||
if (itwt_args.teardown->count) {
|
||||
// teardown a given flow id, all_twt has a high priority
|
||||
int flow_id = itwt_args.flowid->count ? itwt_args.flowid->ival[0] : (-1);
|
||||
bool all_twt = itwt_args.all_twt->count ? ((itwt_args.all_twt->ival[0] == 1) ? true : false) : false;
|
||||
flow_id = (all_twt == true) ? FLOW_ID_ALL : flow_id;
|
||||
if (flow_id >= 0) {
|
||||
err = esp_wifi_sta_itwt_teardown(flow_id);
|
||||
ESP_LOGI(TAG, "(itwt)teardown, flow_id:%d, all_twt:%d, err:0x%x", flow_id, all_twt, err);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "(itwt)teardown, should specify an existing flow id");
|
||||
}
|
||||
}
|
||||
if (itwt_args.suspend->count) {
|
||||
// suspend a given flow id
|
||||
int flow_id = itwt_args.flowid->count ? itwt_args.flowid->ival[0] : (-1);
|
||||
bool all_twt = itwt_args.all_twt->count ? (itwt_args.all_twt->ival[0] ? true : false) : false;
|
||||
flow_id = (all_twt == true) ? FLOW_ID_ALL : flow_id;
|
||||
int suspend_time_ms = itwt_args.suspend_time_ms->count ? itwt_args.suspend_time_ms->ival[0] : 0;
|
||||
if (flow_id > 0) {
|
||||
err = esp_wifi_sta_itwt_suspend(flow_id, suspend_time_ms);
|
||||
ESP_LOGI(TAG, "(itwt)suspend, flow_id:%d, all_twt:%d, suspend:%d ms, err:0x%x", flow_id, all_twt, suspend_time_ms, err);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "(itwt)suspend, should specify an existing flow id");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_cmd_itwt_probe(int argc, char **argv)
|
||||
{
|
||||
int nerrors = arg_parse(argc, argv, (void **) &itwt_probe_args);
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, itwt_probe_args.end, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
if (itwt_probe_args.timeout->count) {
|
||||
if (itwt_probe_args.timeout->ival[0] > 0) {
|
||||
ESP_LOGI(TAG, "(itwt)send probe req, timeout:%d ms", itwt_probe_args.timeout->ival[0]);
|
||||
err = esp_wifi_sta_itwt_send_probe_req(itwt_probe_args.timeout->ival[0]);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "(itwt)invalid input, timeout:%d ms", itwt_probe_args.timeout->ival[0]);
|
||||
}
|
||||
}
|
||||
ESP_LOGI(TAG, "err:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
void register_wifi_itwt(void)
|
||||
{
|
||||
/* itwt setup/teardown */
|
||||
itwt_args.setup = arg_int0(NULL, "setup", "<setup>", "twt setup/teardown an individual flow id");
|
||||
itwt_args.teardown = arg_int0(NULL, "teardown", "<setup>", "twt setup/teardown an individual flow id");
|
||||
itwt_args.suspend = arg_int0(NULL, "suspend", "<setup>", "twt setup/teardown an individual flow id");
|
||||
itwt_args.trigger = arg_int0("t", NULL, "<trigger>", "trigger");
|
||||
itwt_args.flowtype = arg_int0("f", NULL, "<flow_type>", "flow type: 0-announced, 1-unannounced");
|
||||
itwt_args.negtype = arg_int0("n", NULL, "<neg_type>", "negotiate type");
|
||||
itwt_args.minwakedur = arg_int0("d", NULL, "<minwakedur>", "Norminal Min. Wake Duration");
|
||||
itwt_args.wakeduraunit = arg_int0("u", NULL, "<wakeduraunit>", "wake duration unit 0-256us, 1-TU (TU = 1024us)");
|
||||
itwt_args.wakeinvlexp = arg_int0("e", NULL, "<wakeinvlexp>", "Wake Interval Exponent");
|
||||
itwt_args.wakeinvlman = arg_int0("m", NULL, "<wakeinvlman>", "Wake Interval Mantissa");
|
||||
itwt_args.flowid = arg_int0("i", NULL, "<flow_id>", "Flow ID");
|
||||
itwt_args.suspend_time_ms = arg_int0("s", NULL, "<suspend_time_ms>", "time of suspending iTWT agreements, unit ms");
|
||||
itwt_args.twtid = arg_int0("w", NULL, "<twt_id>", "TWT ID");
|
||||
itwt_args.setup_timeout_time_ms = arg_int0("u", NULL, "<setup_timeout_time_ms>", "iTWT setup timeout time, unit ms");
|
||||
itwt_args.all_twt = arg_int0("a", NULL, "<all_twt>", "All TWT");
|
||||
itwt_args.end = arg_end(1);
|
||||
const esp_console_cmd_t itwt_cmd = {
|
||||
.command = "itwt",
|
||||
.help = "itwt setup, teardown or suspend",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_itwt,
|
||||
.argtable = &itwt_args
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&itwt_cmd));
|
||||
|
||||
/* itwt probe */
|
||||
itwt_probe_args.timeout = arg_int0("t", NULL, "[timeout]", "time of sending a probe request frame and receiving a probe response frame from ap, unit ms");
|
||||
itwt_probe_args.end = arg_end(1);
|
||||
const esp_console_cmd_t itwt_probe_cmd = {
|
||||
.command = "probe",
|
||||
.help = "send probe request for TSF update when at lease one itwt agreement setup",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_itwt_probe,
|
||||
.argtable = &itwt_probe_args
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&itwt_probe_cmd));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void register_wifi_itwt(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SOC_WIFI_HE_SUPPORT */
|
||||
585
examples/wifi/itwt/main/wifi_stats_cmd.c
Normal file
585
examples/wifi/itwt/main/wifi_stats_cmd.c
Normal file
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||
|
||||
#include "esp_console.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_wifi_types.h"
|
||||
#include "wifi_stats.h"
|
||||
#include "esp_private/esp_wifi_he_private.h"
|
||||
|
||||
/*******************************************************
|
||||
* Macros
|
||||
*******************************************************/
|
||||
/*
|
||||
* enable/disable rx/tx statistics after Wi-Fi started:
|
||||
* (1) esp_wifi_enable_rx_statistics(true, true); //rx_stats=true, rx_mu_stats=true
|
||||
* (2) esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //aci=ESP_WIFI_ACI_BE, tx_stats=true
|
||||
*/
|
||||
|
||||
/*******************************************************
|
||||
* Constants
|
||||
*******************************************************/
|
||||
static const char *TAG = "stats";
|
||||
|
||||
/*******************************************************
|
||||
* Structures
|
||||
*******************************************************/
|
||||
|
||||
/*******************************************************
|
||||
* Variable Definitions
|
||||
*******************************************************/
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||
esp_test_rx_mu_statistics_t rx_mu_stats = { 0, }; //10932 bytes
|
||||
#endif
|
||||
|
||||
/*******************************************************
|
||||
* Function Declarations
|
||||
*******************************************************/
|
||||
|
||||
/*******************************************************
|
||||
* Function Definitions
|
||||
*******************************************************/
|
||||
const char *tx_fail_error2str(esp_test_tx_fail_error_t error)
|
||||
{
|
||||
switch (error) {
|
||||
case TEST_TX_FAIL_ERROR_H00:
|
||||
return "0x00";
|
||||
case TEST_TX_FAIL_ERROR_H53:
|
||||
return "0x53";
|
||||
case TEST_TX_FAIL_ERROR_H63:
|
||||
return "0x63";
|
||||
case TEST_TX_FAIL_ERROR_H75:
|
||||
return "0x75";
|
||||
case TEST_TX_FAIL_ERROR_H41:
|
||||
return "0x41";
|
||||
case TEST_TX_FAIL_ERROR_H42:
|
||||
return "0x42";
|
||||
case TEST_TX_FAIL_ERROR_H47:
|
||||
return "0x47";
|
||||
case TEST_TX_FAIL_ERROR_H80:
|
||||
return "0x80";
|
||||
case TEST_TX_FAIL_ERROR_H5A:
|
||||
return "0x5A";
|
||||
case TEST_TX_FAIL_ERROR_HXX:
|
||||
return "Others";
|
||||
case TEST_TX_FAIL_ERROR_MAX:
|
||||
return "Undefined";
|
||||
}
|
||||
return "Undefined";
|
||||
}
|
||||
|
||||
const char *tx_fail_match2str(esp_test_tx_fail_match_t match)
|
||||
{
|
||||
switch (match) {
|
||||
case TEST_TX_WAIT_MATCH:
|
||||
return "MATCH";
|
||||
case TEST_TX_WAIT_NOT2SELF:
|
||||
return "NOT2SELF";
|
||||
case TEST_TX_MISMATCH:
|
||||
return "MISMATCH";
|
||||
case TEST_TX_WAIT_TIMEOUT:
|
||||
return "TIMEOUT";
|
||||
case TEST_TX_WAIT_MAX:
|
||||
return "Undefined";
|
||||
}
|
||||
return "Undefined";
|
||||
}
|
||||
|
||||
const char *tx_fail_state2str(esp_test_tx_fail_state_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case TEST_TX_SUCCESS:
|
||||
return "TX Success";
|
||||
case TEST_TX_FAIL_RTS:
|
||||
return "TX RTS";
|
||||
case TEST_TX_WAIT_CTS: //RX
|
||||
return "Wait CTS";
|
||||
case TEST_TX_FAIL_CTS:
|
||||
return "TX RTS";
|
||||
case TEST_TX_FAIL_DATA:
|
||||
return "TX DATA";
|
||||
case TEST_TX_WAIT_ACK: //RX
|
||||
return "Wait ACK/BA";
|
||||
case TEST_TX_FAIL_MAX:
|
||||
return "Undefined";
|
||||
}
|
||||
return "Undefined";
|
||||
}
|
||||
|
||||
int wifi_cmd_clr_tx_statistics(int argc, char **argv)
|
||||
{
|
||||
ESP_LOGW(TAG, "Clear tx statistics");
|
||||
int i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
esp_wifi_clr_tx_statistics(i); //BE
|
||||
esp_wifi_clr_tx_tb_statistics(i);
|
||||
}
|
||||
esp_test_clr_hw_statistics();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_hw_tb_statistics(void)
|
||||
{
|
||||
esp_test_hw_tb_statistics_t hw_tb_stats = { 0, };
|
||||
esp_test_get_hw_tb_statistics(&hw_tb_stats);
|
||||
printf("(test)rx_trig:%d, tx_bfrpt:%d, tb_times:%d, tb_qos_null:%d, tb_qos_data:%d, tb_cca_cancel:%d, tb_sifs_abort:%d, tb_pwr_outof_range:%d\n",
|
||||
hw_tb_stats.rx_trig,
|
||||
hw_tb_stats.tx_bfrpt, //including TB and Non-TB
|
||||
hw_tb_stats.tb_times,
|
||||
hw_tb_stats.tb_qos_null,
|
||||
hw_tb_stats.tb_times - hw_tb_stats.tb_qos_null,
|
||||
hw_tb_stats.tb_cca_cancel,
|
||||
hw_tb_stats.tb_sifs_abort,
|
||||
hw_tb_stats.tb_pwr_outof_range);
|
||||
}
|
||||
|
||||
int wifi_cmd_get_tx_statistics(int argc, char **argv)
|
||||
{
|
||||
uint8_t i, h, j, k;
|
||||
|
||||
ESP_LOGW(TAG, "Get tx statistics");
|
||||
esp_test_tx_tb_statistics_t tb_stats = { 0, }; //32 bytes
|
||||
esp_test_tx_statistics_t tx_stats = { 0, }; //136 bytes
|
||||
esp_test_tx_fail_statistics_t tx_fail[TEST_TX_FAIL_MAX] = { 0, }; //TEST_TX_FAIL_MAX * 164 bytes
|
||||
|
||||
print_hw_tb_statistics();
|
||||
//only check BE
|
||||
for (i = 2; i < 3; i++) {
|
||||
esp_wifi_get_tx_tb_statistics(i, &tb_stats);
|
||||
/* TB */
|
||||
printf("(test)aci:%" PRIu8 ", tb(suc:%" PRIu32 ", ack:%" PRIu32 ", err:%" PRIu32 "), "
|
||||
"count(suc:%" PRIu32 ", ack:%" PRIu32 ", err:%" PRIu32 ", tot:%" PRIu32 ", max_sent:%" PRIu32 ")\n",
|
||||
i,
|
||||
tb_stats.complete_suc_tb,
|
||||
tb_stats.complete_ack_tb,
|
||||
tb_stats.complete_err_tb,
|
||||
tb_stats.complete_tb_suc_count,
|
||||
tb_stats.complete_tb_ack_count,
|
||||
tb_stats.complete_tb_err_count,
|
||||
tb_stats.complete_tb_tot_count,
|
||||
tb_stats.complete_tb_pack_sent);
|
||||
|
||||
esp_wifi_get_tx_statistics(i, &tx_stats, (esp_test_tx_fail_statistics_t *) &tx_fail);
|
||||
int tot_tx_times = tx_stats.tb_times + (tx_stats.tx_enable - tx_stats.tb_last); //TB + EDCA
|
||||
int tot_fail = tx_fail[1].count + tx_fail[2].count + tx_fail[3].count + tx_fail[4].count + tx_fail[5].count;
|
||||
printf("(test)aci:%" PRIu8 ", enable:%" PRIu32 ", complete:%" PRIu32 ", tb_times:%" PRIu32 ", tb_last:%" PRIu32 ", edca:%" PRIu32 ", "
|
||||
"succ:%" PRIu32 ", fail(%" PRIu32 ",%" PRIu32 ",%" PRIu32 ", cts:%" PRIu32 "/%2.2f%%, ack:%" PRIu32 "/%2.2f%%, tot:%d, %.2f%%), "
|
||||
"edca(ack:%" PRIu32 ", ba:%" PRIu32 "), tb(hw-ba:%" PRIu32 ", sw-ba:%" PRIu32 ")\n",
|
||||
i, tx_stats.tx_enable,
|
||||
tx_stats.tx_complete,
|
||||
tx_stats.tb_times,
|
||||
tx_stats.tb_last,
|
||||
tx_stats.tx_enable - tx_stats.tb_last,
|
||||
tx_fail[0].count,
|
||||
tx_fail[1].count,
|
||||
tx_fail[3].count,
|
||||
tx_fail[4].count,
|
||||
tx_fail[2].count,
|
||||
(float) ((float) tx_fail[2].count / (float) tot_tx_times) * 100, //rx cts
|
||||
tx_fail[5].count, (float) ((float) tx_fail[5].count / (float) tot_tx_times) * 100, //rx ack
|
||||
tot_fail,
|
||||
(float) ((float) tot_fail / (float) tot_tx_times) * 100,
|
||||
tx_stats.rx_ack,
|
||||
tx_stats.rx_ba,
|
||||
tx_stats.tb_rx_ba, //including ACKs
|
||||
tx_stats.rx_dump_ba);
|
||||
|
||||
printf("(test)aci:%" PRIu8 ", txFrames:%" PRIu32 ", s-mpdu:%" PRIu32 "(%.2f%%), "
|
||||
"bitmap(max:%d, min:%d, tot:%" PRIu32 ", avg:%.2f), "
|
||||
"retry(edca:%" PRIu32 ", tb:%" PRIu32 ", %.2f%%), collision:%" PRIu32 ", timeout:%" PRIu32 "\n",
|
||||
i,
|
||||
tx_stats.tx_succ,
|
||||
tx_stats.rx_ack,
|
||||
((float) (tx_stats.rx_ack) / (float) tot_tx_times) * 100,
|
||||
tx_stats.rx_max_bitmap,
|
||||
tx_stats.rx_min_bitmap,
|
||||
tx_stats.rx_tot_bitmap,
|
||||
(float) tx_stats.rx_tot_bitmap / (float) (tx_stats.tb_rx_ba + tx_stats.rx_ba),
|
||||
tx_stats.retry_edca, tx_stats.retry_tb, (float) (tx_stats.retry_edca + tx_stats.retry_tb) / (float) tx_stats.tx_succ * 100,
|
||||
tx_stats.collision, tx_stats.timeout);
|
||||
|
||||
float tot_rtt_ms = (float) tx_stats.tx_tot_rtt / (float) 1000;
|
||||
printf("(test)aci:%" PRIu8 ", seqno_rtt[%" PRIu32 ",%" PRIu32 "], hw_rtt[%" PRIu32 ", %" PRIu32 "], muedca[enable:%" PRIu32 ", times:%" PRIu32 ", %.2f, %.2f, tot:%.2f], avg:%.3f ms, tot:%.3f secs\n",
|
||||
i,
|
||||
tx_stats.tx_seq_min_rtt,
|
||||
tx_stats.tx_seq_max_rtt,
|
||||
tx_stats.tx_min_rtt,
|
||||
tx_stats.tx_max_rtt,
|
||||
tx_stats.tx_muedca_enable,
|
||||
tx_stats.muedca_times,
|
||||
(float) tx_stats.tx_min_muedca_time / (float) 1000,
|
||||
(float) tx_stats.tx_max_muedca_time / (float) 1000,
|
||||
(float) tx_stats.tx_tot_muedca_time / (float) 1000, //ms
|
||||
(float) tot_rtt_ms / (float) tot_tx_times, //ms
|
||||
(float) tot_rtt_ms / (float) 1000); //seconds
|
||||
/* fail state */
|
||||
for (h = 1; h < TEST_TX_FAIL_MAX; h++) { //state
|
||||
for (j = 0; j < TEST_TX_WAIT_MAX; j++) { //match
|
||||
for (k = 0; k < TEST_TX_FAIL_ERROR_MAX; k++) { //error
|
||||
if (tx_fail[h].match[j][k]) {
|
||||
printf("(test)[%d][%d][%d](%16s + %16s + %16s)%3" PRIu32 "/%3" PRIu32 "(%.2f%%)\n", h, j, k, tx_fail_state2str(h),
|
||||
tx_fail_match2str(j), tx_fail_error2str(k),
|
||||
tx_fail[h].match[j][k], tx_fail[h].count,
|
||||
((float) tx_fail[h].match[j][k] / (float) tx_fail[h].count) * 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
wifi_cmd_clr_tx_statistics(0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_rx_statistics_nonmimo(const esp_test_rx_mu_statistics_t *mu_stats)
|
||||
{
|
||||
if (!mu_stats->nonmimo_rx) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i, j;
|
||||
int tot_rx_nonmimo = 0;
|
||||
ESP_LOGW(TAG, "(nonmimo)dut rx:%" PRIu32, mu_stats->nonmimo_rx);
|
||||
ESP_LOGW(TAG, "(nonmimo)ru_alloc_96_num_2046:%" PRIu32 ", ru_alloc_112_num_2046:%" PRIu32, mu_stats->ru_alloc_96_num_2046, mu_stats->ru_alloc_112_num_2046);
|
||||
ESP_LOGW(TAG, "(nonmimo)sigb, mcs0:%" PRIu32 "(%2.2f%%), mcs1:%" PRIu32 "(%2.2f%%), mcs2:%" PRIu32 "(%2.2f%%), mcs3:%" PRIu32 "(%2.2f%%), mcs4:%" PRIu32 "(%2.2f%%), mcs5:%" PRIu32 "(%2.2f%%)",
|
||||
mu_stats->nonmimo_sigb_mcs[0], ((float) mu_stats->nonmimo_sigb_mcs[0] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_sigb_mcs[1], ((float) mu_stats->nonmimo_sigb_mcs[1] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_sigb_mcs[2], ((float) mu_stats->nonmimo_sigb_mcs[2] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_sigb_mcs[3], ((float) mu_stats->nonmimo_sigb_mcs[3] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_sigb_mcs[4], ((float) mu_stats->nonmimo_sigb_mcs[4] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_sigb_mcs[5], ((float) mu_stats->nonmimo_sigb_mcs[5] / (float) mu_stats->nonmimo_rx) * 100);
|
||||
ESP_LOGW(TAG, "(nonmimo)users, num1:%" PRIu32 "(%2.2f%%), num2:%" PRIu32 "(%2.2f%%), num3:%" PRIu32 "(%2.2f%%), num4:%" PRIu32 "(%2.2f%%), num5:%" PRIu32 "(%2.2f%%), num6:%" PRIu32 "(%2.2f%%), num7:%" PRIu32 "(%2.2f%%), num8:%" PRIu32 "(%2.2f%%), num9:%" PRIu32 "(%2.2f%%)",
|
||||
mu_stats->nonmimo_user_num_occu[0], ((float) mu_stats->nonmimo_user_num_occu[0] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_user_num_occu[1], ((float) mu_stats->nonmimo_user_num_occu[1] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_user_num_occu[2], ((float) mu_stats->nonmimo_user_num_occu[2] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_user_num_occu[3], ((float) mu_stats->nonmimo_user_num_occu[3] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_user_num_occu[4], ((float) mu_stats->nonmimo_user_num_occu[4] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_user_num_occu[5], ((float) mu_stats->nonmimo_user_num_occu[5] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_user_num_occu[6], ((float) mu_stats->nonmimo_user_num_occu[6] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_user_num_occu[7], ((float) mu_stats->nonmimo_user_num_occu[7] / (float) mu_stats->nonmimo_rx) * 100,
|
||||
mu_stats->nonmimo_user_num_occu[8], ((float) mu_stats->nonmimo_user_num_occu[8] / (float) mu_stats->nonmimo_rx) * 100);
|
||||
for (i = 0; i < 256; i++) {
|
||||
for (j = 0; j < 9; j++) {
|
||||
if (!mu_stats->nonmimo_ru_alloc[i][j]) {
|
||||
continue;
|
||||
}
|
||||
ESP_LOGI(TAG, "(nonmimo)ru_allocation:0x%2x(%3" PRIu8 "), position:%" PRIu8 ", %5" PRIu32 "(%2.2f%%)", i, i, j + 1, mu_stats->nonmimo_ru_alloc[i][j],
|
||||
((float) mu_stats->nonmimo_ru_alloc[i][j] / (float) mu_stats->nonmimo_rx) * 100);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ESP_TEST_RX_MU_USER_NUM; i++) {
|
||||
if (!mu_stats->nonmimo[i].aid) {
|
||||
continue;
|
||||
}
|
||||
if (mu_stats->aid != mu_stats->nonmimo[i].aid) {
|
||||
continue;
|
||||
}
|
||||
tot_rx_nonmimo = mu_stats->nonmimo[i].occu_nsts[0] + mu_stats->nonmimo[i].occu_nsts[1] + mu_stats->nonmimo[i].occu_nsts[2] + mu_stats->nonmimo[i].occu_nsts[3];
|
||||
printf("[%" PRIu8 "]%said:0x%x, txbf:%" PRIu32 ", dcm:%" PRIu32 "\n", i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
||||
mu_stats->nonmimo[i].txbf, mu_stats->nonmimo[i].dcm);
|
||||
printf("[%d]%said:0x%x, "
|
||||
"mcs0:%" PRIu32 "(%2.2f%%), mcs1:%" PRIu32 "(%2.2f%%), mcs2:%" PRIu32 "(%2.2f%%), mcs3:%" PRIu32 "(%2.2f%%), mcs4:%" PRIu32 "(%2.2f%%), "
|
||||
"mcs5:%" PRIu32 "(%2.2f%%), mcs6:%" PRIu32 "(%2.2f%%), mcs7:%" PRIu32 "(%2.2f%%), mcs8:%" PRIu32 "(%2.2f%%), mcs9:%" PRIu32 "(%2.2f%%), "
|
||||
"mcs10:%" PRIu32 "(%2.2f%%), mcs11:%" PRIu32 "(%2.2f%%)\n",
|
||||
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
||||
mu_stats->nonmimo[i].occu_mcs[0], ((float) mu_stats->nonmimo[i].occu_mcs[0] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[1], ((float) mu_stats->nonmimo[i].occu_mcs[1] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[2], ((float) mu_stats->nonmimo[i].occu_mcs[2] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[3], ((float) mu_stats->nonmimo[i].occu_mcs[3] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[4], ((float) mu_stats->nonmimo[i].occu_mcs[4] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[5], ((float) mu_stats->nonmimo[i].occu_mcs[5] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[6], ((float) mu_stats->nonmimo[i].occu_mcs[6] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[7], ((float) mu_stats->nonmimo[i].occu_mcs[7] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[8], ((float) mu_stats->nonmimo[i].occu_mcs[8] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[9], ((float) mu_stats->nonmimo[i].occu_mcs[9] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[10], ((float) mu_stats->nonmimo[i].occu_mcs[10] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_mcs[11], ((float) mu_stats->nonmimo[i].occu_mcs[11] / (float) tot_rx_nonmimo) * 100);
|
||||
printf("[%" PRIu8 "]%said:0x%x, "
|
||||
"nsts0:%" PRIu32 "(%2.2f%%), nsts1:%" PRIu32 "(%2.2f%%), nsts2:%" PRIu32 "(%2.2f%%), nsts3:%" PRIu32 "(%2.2f%%)\n",
|
||||
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
||||
mu_stats->nonmimo[i].occu_nsts[0], ((float) mu_stats->nonmimo[i].occu_nsts[0] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_nsts[1], ((float) mu_stats->nonmimo[i].occu_nsts[1] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_nsts[2], ((float) mu_stats->nonmimo[i].occu_nsts[2] / (float) tot_rx_nonmimo) * 100,
|
||||
mu_stats->nonmimo[i].occu_nsts[3], ((float) mu_stats->nonmimo[i].occu_nsts[3] / (float) tot_rx_nonmimo) * 100);
|
||||
printf("[%" PRIu8 "]%said:0x%x, "
|
||||
"tot_rx_nonmimo:%8d, sta/dut:%2.2f%%\n",
|
||||
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
||||
tot_rx_nonmimo, ((float) tot_rx_nonmimo / (float) mu_stats->nonmimo_rx) * 100);
|
||||
}
|
||||
}
|
||||
|
||||
void print_rx_statistics_mimo(const esp_test_rx_mu_statistics_t *mu_stats)
|
||||
{
|
||||
if (!mu_stats->mimo_rx) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i;
|
||||
int tot_rx_mimo = 0;
|
||||
ESP_LOGW(TAG, "(mimo)dut rx:%" PRIu32 "", mu_stats->mimo_rx);
|
||||
ESP_LOGW(TAG, "(mimo)sigb, mcs0:%" PRIu32 "(%2.2f%%), mcs1:%" PRIu32 "(%2.2f%%), mcs2:%" PRIu32 "(%2.2f%%), mcs3:%" PRIu32 "(%2.2f%%), mcs4:%" PRIu32 "(%2.2f%%), mcs5:%" PRIu32 "(%2.2f%%)",
|
||||
mu_stats->mimo_sigb_mcs[0], ((float) mu_stats->mimo_sigb_mcs[0] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_sigb_mcs[1], ((float) mu_stats->mimo_sigb_mcs[1] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_sigb_mcs[2], ((float) mu_stats->mimo_sigb_mcs[2] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_sigb_mcs[3], ((float) mu_stats->mimo_sigb_mcs[3] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_sigb_mcs[4], ((float) mu_stats->mimo_sigb_mcs[4] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_sigb_mcs[5], ((float) mu_stats->mimo_sigb_mcs[5] / (float) mu_stats->mimo_rx) * 100);
|
||||
ESP_LOGW(TAG, "(mimo)users num2:%" PRIu32 "(%2.2f%%), num3:%" PRIu32 "(%2.2f%%), num4:%" PRIu32 "(%2.2f%%), num5:%" PRIu32 "(%2.2f%%), num6:%" PRIu32 "(%2.2f%%), num7:%" PRIu32 "(%2.2f%%), num8:%" PRIu32 "(%2.2f%%)",
|
||||
mu_stats->mimo_user_num_occu[0], ((float) mu_stats->mimo_user_num_occu[0] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_user_num_occu[1], ((float) mu_stats->mimo_user_num_occu[1] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_user_num_occu[2], ((float) mu_stats->mimo_user_num_occu[2] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_user_num_occu[3], ((float) mu_stats->mimo_user_num_occu[3] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_user_num_occu[4], ((float) mu_stats->mimo_user_num_occu[4] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_user_num_occu[5], ((float) mu_stats->mimo_user_num_occu[5] / (float) mu_stats->mimo_rx) * 100,
|
||||
mu_stats->mimo_user_num_occu[6], ((float) mu_stats->mimo_user_num_occu[6] / (float) mu_stats->mimo_rx) * 100);
|
||||
for (i = 0; i < ESP_TEST_RX_MU_USER_NUM; i++) {
|
||||
if (!mu_stats->mimo[i].aid) {
|
||||
continue;
|
||||
}
|
||||
tot_rx_mimo = mu_stats->mimo[i].occu_ss[0] + mu_stats->mimo[i].occu_ss[1] + mu_stats->mimo[i].occu_ss[2] + mu_stats->mimo[i].occu_ss[3];
|
||||
printf("[%" PRIu8 "]%said:0x%x, "
|
||||
"mcs0:%" PRIu32 "(%2.2f%%), mcs1:%" PRIu32 "(%2.2f%%), mcs2:%" PRIu32 "(%2.2f%%), mcs3:%" PRIu32 "(%2.2f%%), mcs4:%" PRIu32 "(%2.2f%%), "
|
||||
"mcs5:%" PRIu32 "(%2.2f%%), mcs6:%" PRIu32 "(%2.2f%%), mcs7:%" PRIu32 "(%2.2f%%), mcs8:%" PRIu32 "(%2.2f%%), mcs9:%" PRIu32 "(%2.2f%%), "
|
||||
"mcs10:%" PRIu32 "(%2.2f%%), mcs11:%" PRIu32 "(%2.2f%%)\n",
|
||||
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
||||
mu_stats->mimo[i].occu_mcs[0], ((float) mu_stats->mimo[i].occu_mcs[0] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[1], ((float) mu_stats->mimo[i].occu_mcs[1] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[2], ((float) mu_stats->mimo[i].occu_mcs[2] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[3], ((float) mu_stats->mimo[i].occu_mcs[3] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[4], ((float) mu_stats->mimo[i].occu_mcs[4] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[5], ((float) mu_stats->mimo[i].occu_mcs[5] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[6], ((float) mu_stats->mimo[i].occu_mcs[6] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[7], ((float) mu_stats->mimo[i].occu_mcs[7] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[8], ((float) mu_stats->mimo[i].occu_mcs[8] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[9], ((float) mu_stats->mimo[i].occu_mcs[9] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[10], ((float) mu_stats->mimo[i].occu_mcs[10] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_mcs[11], ((float) mu_stats->mimo[i].occu_mcs[11] / (float) tot_rx_mimo) * 100);
|
||||
printf("[%" PRIu8 "]%said:0x%x, "
|
||||
"ss0:%" PRIu32 "(%2.2f%%), ss1:%" PRIu32 "(%2.2f%%), ss2:%" PRIu32 "(%2.2f%%), ss3:%" PRIu32 "(%2.2f%%)\n",
|
||||
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
||||
mu_stats->mimo[i].occu_ss[0], ((float) mu_stats->mimo[i].occu_ss[0] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_ss[1], ((float) mu_stats->mimo[i].occu_ss[1] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_ss[2], ((float) mu_stats->mimo[i].occu_ss[2] / (float) tot_rx_mimo) * 100,
|
||||
mu_stats->mimo[i].occu_ss[3], ((float) mu_stats->mimo[i].occu_ss[3] / (float) tot_rx_mimo) * 100);
|
||||
printf("[%" PRIu8 "]%said:0x%x, "
|
||||
"tot_rx_mimo:%8d, sta/dut:%2.2f%%\n",
|
||||
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
||||
tot_rx_mimo, ((float) tot_rx_mimo / (float) mu_stats->mimo_rx) * 100);
|
||||
}
|
||||
}
|
||||
|
||||
void print_hw_rx_statistics(void)
|
||||
{
|
||||
esp_test_hw_rx_statistics_t hw_rx_stats = { 0, };
|
||||
esp_test_get_hw_rx_statistics(&hw_rx_stats);
|
||||
printf(
|
||||
"WDEVRX_FCS_ERR :%d\n"
|
||||
"WDEVRX_ABORT :%d\n"
|
||||
"WDEVRX_ABORT_FCS_PASS :%d\n"
|
||||
"NRX_ERR_PWRDROP :%d\n"
|
||||
"NRX_HESIGB_ERR :%d\n"
|
||||
"WDEVRX_SAMEBM_ERRCNT :%d\n"
|
||||
"WDEVRX_MPDU :%d\n"
|
||||
"WDEVRX_END_CNT :%d\n"
|
||||
"WDEVRX_DATASUC :%d\n"
|
||||
"WDEVRX_LASTUNMATCH_ERR :%d\n"
|
||||
"RXHUNG_STATIS :%d\n"
|
||||
"TXHUNG_STATIS :%d\n"
|
||||
"RXTXHUNG :%" PRIu32 "\n"
|
||||
"WDEVRX_CFO :%d\n"
|
||||
"WDEVRX_SF :%d\n"
|
||||
"WDEVRX_OTHER_UCAST :%d\n"
|
||||
"WDEVRX_BUF_FULLCNT :%d\n"
|
||||
"WDEVRX_FIFO_OVFCNT :%d\n"
|
||||
"WDEVRX_TKIP_ERRCNT :%d\n"
|
||||
"WDEVRX_BTBLOCK_ERR :%d\n"
|
||||
"WDEVRX_FREQHOP_ERR :%d\n"
|
||||
"WDEVRX_ACK_INT_CNT :%d\n"
|
||||
"WDEVRX_RTS_INT_CNT :%d\n"
|
||||
"BRX_ERR_AGC :%d\n"
|
||||
"BRX_ERR :%d\n"
|
||||
"NRX_ERR :%d\n"
|
||||
"NRX_ERR_ABORT :%d\n"
|
||||
"NRX_ERR_AGCEXIT :%d\n"
|
||||
"NRX_ERR_BBOFF :%d\n"
|
||||
"NRX_ERR_FDM_WDG :%d\n"
|
||||
"NRX_ERR_RESTART :%d\n"
|
||||
"NRX_ERR_SERV :%d\n"
|
||||
"NRX_ERR_TXOVER :%d\n"
|
||||
"NRX_HE_UNSUPPORT :%d\n"
|
||||
"NRX_HTSIG_ERR :%d\n"
|
||||
"NRX_HEUNSUPPORT :%d\n"
|
||||
"NRX_HESIGA_CRC :%d\n",
|
||||
hw_rx_stats.rx_fcs_err,
|
||||
hw_rx_stats.rx_abort,
|
||||
hw_rx_stats.rx_abort_fcs_pass,
|
||||
hw_rx_stats.nrx_err_pwrdrop,
|
||||
hw_rx_stats.nrx_hesigb_err,
|
||||
hw_rx_stats.rx_samebm_errcnt,
|
||||
hw_rx_stats.rx_mpdu,
|
||||
hw_rx_stats.rx_end_cnt,
|
||||
hw_rx_stats.rx_datasuc,
|
||||
hw_rx_stats.rx_lastunmatch_err,
|
||||
hw_rx_stats.rxhung_statis,
|
||||
hw_rx_stats.txhung_statis,
|
||||
hw_rx_stats.rxtxhung,
|
||||
hw_rx_stats.rx_cfo_hz,
|
||||
hw_rx_stats.rx_sf,
|
||||
hw_rx_stats.rx_other_ucast,
|
||||
hw_rx_stats.rx_buf_fullcnt,
|
||||
hw_rx_stats.rx_fifo_ovfcnt,
|
||||
hw_rx_stats.rx_tkip_errcnt,
|
||||
hw_rx_stats.rx_btblock_err,
|
||||
hw_rx_stats.rx_freqhop_err,
|
||||
hw_rx_stats.rx_ack_int_cnt,
|
||||
hw_rx_stats.rx_rts_int_cnt,
|
||||
hw_rx_stats.brx_err_agc,
|
||||
hw_rx_stats.brx_err,
|
||||
hw_rx_stats.nrx_err,
|
||||
hw_rx_stats.nrx_err_abort,
|
||||
hw_rx_stats.nrx_err_agcexit,
|
||||
hw_rx_stats.nrx_err_bboff,
|
||||
hw_rx_stats.nrx_err_fdm_wdg,
|
||||
hw_rx_stats.nrx_err_restart,
|
||||
hw_rx_stats.nrx_err_serv,
|
||||
hw_rx_stats.nrx_err_txover,
|
||||
hw_rx_stats.nrx_err_unsupport,
|
||||
hw_rx_stats.nrx_htsig_err,
|
||||
hw_rx_stats.nrx_heunsupport,
|
||||
hw_rx_stats.nrx_hesiga_crc
|
||||
);
|
||||
}
|
||||
|
||||
int wifi_cmd_clr_rx_statistics(int argc, char **argv)
|
||||
{
|
||||
ESP_LOGW(TAG, "Clear rx statistics");
|
||||
esp_wifi_clr_rx_statistics(0);
|
||||
esp_wifi_clr_rx_statistics(7);
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||
esp_test_clr_rx_error_occurs();
|
||||
esp_wifi_clr_rx_mu_statistics();
|
||||
#endif
|
||||
esp_test_clr_hw_statistics();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_rx_mu_statistics(void)
|
||||
{
|
||||
/* mu */
|
||||
esp_wifi_get_rx_mu_statistics(&rx_mu_stats);
|
||||
/* MIMO */
|
||||
print_rx_statistics_mimo(&rx_mu_stats);
|
||||
/* non-MIMO */
|
||||
print_rx_statistics_nonmimo(&rx_mu_stats);
|
||||
}
|
||||
|
||||
int wifi_cmd_get_rx_statistics(int argc, char **argv)
|
||||
{
|
||||
ESP_LOGW(TAG, "Get rx statistics");
|
||||
esp_test_rx_statistics_t rx_stats = { 0, };
|
||||
esp_test_rx_error_occurs_t rx_error_occurs = { 0, };
|
||||
|
||||
esp_wifi_get_rx_statistics(0, &rx_stats); //tid=0
|
||||
print_hw_tb_statistics();
|
||||
|
||||
ESP_LOGW(TAG, "(0)legacy:%" PRIu32 ", ht(ht:%" PRIu32 ", ht_retry:%" PRIu32 "/%2.2f%%, ht_noeb:%" PRIu32 "/%2.2f%%)",
|
||||
rx_stats.legacy,
|
||||
rx_stats.ht, rx_stats.ht_retry,
|
||||
rx_stats.ht_retry ? ((float) ((float) rx_stats.ht_retry / (float) rx_stats.ht) * 100) : 0,
|
||||
rx_stats.ht_noeb, rx_stats.ht_noeb ? ((float) ((float) rx_stats.ht_noeb / (float) rx_stats.ht) * 100) : 0);
|
||||
ESP_LOGW(TAG, "(0)su(su:%" PRIu32 ", su_txbf:%" PRIu32 ", su_stbc:%" PRIu32 ", su_retry:%" PRIu32 "/%2.2f%%, ersu:%" PRIu32 ", ersu_dcm:%" PRIu32 ", su_noeb:%" PRIu32 "/%2.2f%%)",
|
||||
rx_stats.su,
|
||||
rx_stats.su_txbf, rx_stats.su_stbc,
|
||||
rx_stats.su_retry,
|
||||
rx_stats.su_retry ? ((float) ((float) rx_stats.su_retry / (float) rx_stats.su) * 100) : 0,
|
||||
rx_stats.ersu,
|
||||
rx_stats.ersu_dcm,
|
||||
rx_stats.su_noeb, rx_stats.su_noeb ? ((float) ((float) rx_stats.su_noeb / (float) rx_stats.su) * 100) : 0);
|
||||
ESP_LOGW(TAG, "(0)mu(mu:%" PRIu32 ", mimo:%" PRIu32 ", non-mimo:%" PRIu32 ", txbf:%" PRIu32 ", stbc:%" PRIu32 ", mu_retry:%" PRIu32 "/%2.2f%%, mu_noeb:%" PRIu32 "/%2.2f%%)",
|
||||
rx_stats.mu,
|
||||
rx_stats.mu_mimo,
|
||||
rx_stats.mu_ofdma, rx_stats.mu_txbf, rx_stats.mu_stbc,
|
||||
rx_stats.mu_retry,
|
||||
rx_stats.mu_retry ? ((float) ((float) rx_stats.mu_retry / (float) rx_stats.mu) * 100) : 0,
|
||||
rx_stats.mu_noeb, rx_stats.mu_noeb ? ((float) ((float) rx_stats.mu_noeb / (float) rx_stats.mu) * 100) : 0);
|
||||
|
||||
memset(&rx_stats, 0, sizeof(rx_stats));
|
||||
esp_wifi_get_rx_statistics(7, &rx_stats); //tid=7
|
||||
ESP_LOGW(TAG, "(7)legacy:%" PRIu32 ", ht:%" PRIu32 ", su:%" PRIu32 ", su_txbf:%" PRIu32 ", ersu:%" PRIu32 ", mu:%" PRIu32, rx_stats.legacy,
|
||||
rx_stats.ht, rx_stats.su, rx_stats.su_txbf, rx_stats.ersu, rx_stats.mu);
|
||||
ESP_LOGW(TAG, "(hw)isr:%" PRIu32 ", nblks:%" PRIu32, rx_stats.rx_isr, rx_stats.rx_nblks);
|
||||
/* hw rx statistics */
|
||||
print_hw_rx_statistics();
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||
print_rx_mu_statistics();
|
||||
#endif
|
||||
esp_test_get_rx_error_occurs(&rx_error_occurs);
|
||||
ESP_LOGW(TAG, "(rx)tot_errors:%" PRIu32, rx_error_occurs.tot);
|
||||
int known_errors = 0; //rx error: 0x40-0xff
|
||||
int i;
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (rx_error_occurs.occurs[i]) {
|
||||
known_errors += rx_error_occurs.occurs[i];
|
||||
printf("[%3d] 0x%x, %8" PRIu32 ", %2.2f%%\n", i, (i ? 0xf5 : 0xc6), rx_error_occurs.occurs[i], ((float) rx_error_occurs.occurs[i] / (float) rx_error_occurs.tot) * 100);
|
||||
}
|
||||
}
|
||||
if (rx_error_occurs.tot - known_errors) {
|
||||
printf("[%3d]others, %8" PRIu32 ", %2.2f%%\n\n", i, rx_error_occurs.tot - known_errors, ((float) known_errors / (float) rx_error_occurs.tot) * 100);
|
||||
}
|
||||
wifi_cmd_clr_rx_statistics(0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS */
|
||||
|
||||
void register_wifi_stats(void)
|
||||
{
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
||||
/* get tx statistics */
|
||||
const esp_console_cmd_t tx_stats_cmd = {
|
||||
.command = "tx",
|
||||
.help = "get tx statistics",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_get_tx_statistics,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&tx_stats_cmd));
|
||||
/* clear tx statistics */
|
||||
const esp_console_cmd_t clr_cmd = {
|
||||
.command = "clrtx",
|
||||
.help = "clear tx statistics",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_clr_tx_statistics,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&clr_cmd));
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||
/* get rx statistics */
|
||||
const esp_console_cmd_t rx_stats_cmd = {
|
||||
.command = "rx",
|
||||
.help = "get rx statistics",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_get_rx_statistics,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&rx_stats_cmd));
|
||||
/* clear rx statistics */
|
||||
const esp_console_cmd_t clr_rx_cmd = {
|
||||
.command = "clrrx",
|
||||
.help = "clear rx statistics",
|
||||
.hint = NULL,
|
||||
.func = &wifi_cmd_clr_rx_statistics,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&clr_rx_cmd));
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user