Merge branch 'feat/move_iperf_component' into 'master'

feat: move iperf to component registry

Closes RDT-618

See merge request espressif/esp-idf!29537
This commit is contained in:
Jiang Jiang Jian 2024-03-26 19:53:40 +08:00
commit 38733a752d
28 changed files with 99 additions and 2668 deletions

View File

@ -3,5 +3,5 @@ dependencies:
path: ${IDF_PATH}/examples/bluetooth/esp_ble_mesh/common_components/fast_prov path: ${IDF_PATH}/examples/bluetooth/esp_ble_mesh/common_components/fast_prov
example_init: example_init:
path: ${IDF_PATH}/examples/bluetooth/esp_ble_mesh/common_components/example_init path: ${IDF_PATH}/examples/bluetooth/esp_ble_mesh/common_components/example_init
iperf: espressif/iperf:
path: ${IDF_PATH}/examples/common_components/iperf version: "~0.1.1"

View File

@ -1,11 +0,0 @@
idf_component_register(SRCS "iperf.c"
"wifi_stats.c"
"wifi_twt.c"
"wifi_cmd.c"
INCLUDE_DIRS "include"
REQUIRES lwip
PRIV_REQUIRES esp_timer)
if(CONFIG_SOC_WIFI_HE_SUPPORT)
idf_component_optional_requires(PRIVATE esp_wifi console)
endif()

View File

@ -1,31 +0,0 @@
menu "Iperf Configuration"
config IPERF_SOCKET_RX_TIMEOUT
int "iperf socket TCP/UDP rx timeout in seconds"
default 10
help
The value is used for iperf socket TCP/UDP rx timeout, iperf will be aborted
and socket will be closed and shutdown.
config IPERF_SOCKET_TCP_TX_TIMEOUT
int "iperf socket TCP tx timeout in seconds"
default 10
help
The value is used for iperf socket TCP tx timeout, iperf will be aborted
and socket will be closed and shutdown.
config IPERF_TRAFFIC_TASK_PRIORITY
int "iperf traffic task priority"
default 4
range 1 24
help
The value is used for iperf traffic task priority.
config IPERF_REPORT_TASK_PRIORITY
int "iperf result report task priority"
default 6
range 1 24
help
The value is used for iperf result report task priority.
endmenu

View File

@ -1,14 +0,0 @@
# iperf Component
This directory contains an implementation for iperf network performance tester
Note that it's incompatible with `iperf3`
This component is used as part of the following ESP-IDF examples:
- [esp_wifi](../../wifi/iperf).
- [wifi_coexist](../../bluetooth/esp_ble_mesh/wifi_coexist).
- [ethernet](../../ethernet/iperf)
To learn more about how to use this component, please check API Documentation from header file [iperf.h](./include/iperf.h).
Please note that this component is not considered to be a part of ESP-IDF stable API, and only for example use for now.

View File

@ -1,89 +0,0 @@
/* Iperf Example - iperf declaration
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.
*/
#ifndef __IPERF_H_
#define __IPERF_H_
#include "esp_err.h"
#include "esp_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define IPERF_IP_TYPE_IPV4 0
#define IPERF_IP_TYPE_IPV6 1
#define IPERF_TRANS_TYPE_TCP 0
#define IPERF_TRANS_TYPE_UDP 1
#define IPERF_FLAG_SET(cfg, flag) ((cfg) |= (flag))
#define IPERF_FLAG_CLR(cfg, flag) ((cfg) &= (~(flag)))
#define IPERF_FLAG_CLIENT (1)
#define IPERF_FLAG_SERVER (1 << 1)
#define IPERF_FLAG_TCP (1 << 2)
#define IPERF_FLAG_UDP (1 << 3)
#define IPERF_DEFAULT_PORT 5001
#define IPERF_DEFAULT_INTERVAL 3
#define IPERF_DEFAULT_TIME 30
#define IPERF_DEFAULT_NO_BW_LIMIT -1
#define IPERF_TRAFFIC_TASK_NAME "iperf_traffic"
#define IPERF_TRAFFIC_TASK_PRIORITY CONFIG_IPERF_TRAFFIC_TASK_PRIORITY
#define IPERF_TRAFFIC_TASK_STACK 4096
#define IPERF_REPORT_TASK_NAME "iperf_report"
#define IPERF_REPORT_TASK_PRIORITY CONFIG_IPERF_REPORT_TASK_PRIORITY
#define IPERF_REPORT_TASK_STACK 4096
#define IPERF_DEFAULT_IPV4_UDP_TX_LEN (1470)
#define IPERF_DEFAULT_IPV6_UDP_TX_LEN (1450)
#define IPERF_DEFAULT_UDP_RX_LEN (16 << 10)
#define IPERF_DEFAULT_TCP_TX_LEN (16 << 10)
#define IPERF_DEFAULT_TCP_RX_LEN (16 << 10)
#define IPERF_MAX_DELAY 64
#define IPERF_SOCKET_RX_TIMEOUT CONFIG_IPERF_SOCKET_RX_TIMEOUT
#define IPERF_SOCKET_TCP_TX_TIMEOUT CONFIG_IPERF_SOCKET_TCP_TX_TIMEOUT
#define IPERF_SOCKET_ACCEPT_TIMEOUT 5
typedef enum {
MBITS_PER_SEC, KBITS_PER_SEC, BITS_PER_SEC
} iperf_output_format;
typedef struct {
uint32_t flag;
union {
uint32_t destination_ip4;
char *destination_ip6;
};
union {
uint32_t source_ip4;
char *source_ip6;
};
uint8_t type;
uint16_t dport;
uint16_t sport;
uint32_t interval;
uint32_t time;
uint16_t len_send_buf;
int32_t bw_lim;
iperf_output_format format;
} iperf_cfg_t;
esp_err_t iperf_start(iperf_cfg_t *cfg);
esp_err_t iperf_stop(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,26 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
int wifi_cmd_get_tx_statistics(int argc, char **argv);
int wifi_cmd_clr_tx_statistics(int argc, char **argv);
int wifi_cmd_get_rx_statistics(int argc, char **argv);
int wifi_cmd_clr_rx_statistics(int argc, char **argv);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,609 +0,0 @@
/* Iperf Example - iperf implementation
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 "sdkconfig.h"
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_check.h"
#include "esp_log.h"
#include "esp_rom_sys.h"
#include "esp_timer.h"
#include "iperf.h"
#include "wifi_stats.h"
typedef struct {
iperf_cfg_t cfg;
bool finish;
uint32_t actual_len;
uint32_t buffer_len;
uint8_t *buffer;
uint32_t sockfd;
} iperf_ctrl_t;
static bool s_iperf_is_running = false;
static iperf_ctrl_t s_iperf_ctrl;
static const char *TAG = "iperf";
inline static bool iperf_is_udp_client(void)
{
return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_CLIENT) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_UDP));
}
inline static bool iperf_is_udp_server(void)
{
return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_SERVER) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_UDP));
}
inline static bool iperf_is_tcp_client(void)
{
return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_CLIENT) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_TCP));
}
inline static bool iperf_is_tcp_server(void)
{
return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_SERVER) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_TCP));
}
static int iperf_get_socket_error_code(int sockfd)
{
return errno;
}
static int iperf_show_socket_error_reason(const char *str, int sockfd)
{
int err = errno;
if (err != 0) {
ESP_LOGW(TAG, "%s error, error code: %d, reason: %s", str, err, strerror(err));
}
return err;
}
static void iperf_report_task(void *arg)
{
uint32_t interval = s_iperf_ctrl.cfg.interval;
uint32_t time = s_iperf_ctrl.cfg.time;
TickType_t delay_interval = (interval * 1000) / portTICK_PERIOD_MS;
uint32_t cur = 0;
double average = 0;
double actual_bandwidth = 0;
int k = 1;
const double coefficient[3] = {1048576.0, 1024.0, 1.0};
const char unit[3] = {'M', 'K', '\0'};
iperf_output_format format = s_iperf_ctrl.cfg.format;
printf("\n%16s %s\n", "Interval", "Bandwidth");
while (!s_iperf_ctrl.finish) {
vTaskDelay(delay_interval);
actual_bandwidth = (s_iperf_ctrl.actual_len / coefficient[format] * 8) / interval;
printf("%4" PRIi32 "-%4" PRIi32 " sec %.2f %cbits/sec\n", cur, cur + interval,
actual_bandwidth, unit[format]);
cur += interval;
average = ((average * (k - 1) / k) + (actual_bandwidth / k));
k++;
s_iperf_ctrl.actual_len = 0;
if (cur >= time) {
printf("%4d-%4" PRIu32 " sec %.2f %cbits/sec\n", 0, time,
average, unit[format]);
break;
}
}
s_iperf_ctrl.finish = true;
vTaskDelete(NULL);
}
static esp_err_t iperf_start_report(void)
{
int ret;
ret = xTaskCreatePinnedToCore(iperf_report_task, IPERF_REPORT_TASK_NAME, IPERF_REPORT_TASK_STACK, NULL, IPERF_REPORT_TASK_PRIORITY, NULL, CONFIG_FREERTOS_NUMBER_OF_CORES - 1);
if (ret != pdPASS) {
ESP_LOGE(TAG, "create task %s failed", IPERF_REPORT_TASK_NAME);
return ESP_FAIL;
}
return ESP_OK;
}
static void IRAM_ATTR socket_recv(int recv_socket, struct sockaddr_storage listen_addr, uint8_t type)
{
bool iperf_recv_start = true;
uint8_t *buffer;
int want_recv = 0;
int actual_recv = 0;
#ifdef CONFIG_LWIP_IPV6
socklen_t socklen = (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
#else
socklen_t socklen = sizeof(struct sockaddr_in);
#endif
const char *error_log = (type == IPERF_TRANS_TYPE_TCP) ? "tcp server recv" : "udp server recv";
buffer = s_iperf_ctrl.buffer;
want_recv = s_iperf_ctrl.buffer_len;
while (!s_iperf_ctrl.finish) {
actual_recv = recvfrom(recv_socket, buffer, want_recv, 0, (struct sockaddr *)&listen_addr, &socklen);
if (actual_recv < 0) {
iperf_show_socket_error_reason(error_log, recv_socket);
s_iperf_ctrl.finish = true;
break;
} else {
if (iperf_recv_start) {
iperf_start_report();
iperf_recv_start = false;
}
s_iperf_ctrl.actual_len += actual_recv;
}
}
}
static void IRAM_ATTR socket_send(int send_socket, struct sockaddr_storage dest_addr, uint8_t type, int bw_lim)
{
uint8_t *buffer;
uint32_t *pkt_id_p;
uint32_t pkt_cnt = 0;
int actual_send = 0;
int want_send = 0;
int period_us = -1;
int delay_us = 0;
int64_t prev_time = 0;
int64_t send_time = 0;
int err = 0;
#ifdef CONFIG_LWIP_IPV6
const socklen_t socklen = (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
#else
const socklen_t socklen = sizeof(struct sockaddr_in);
#endif
const char *error_log = (type == IPERF_TRANS_TYPE_TCP) ? "tcp client send" : "udp client send";
buffer = s_iperf_ctrl.buffer;
pkt_id_p = (uint32_t *)s_iperf_ctrl.buffer;
want_send = s_iperf_ctrl.buffer_len;
iperf_start_report();
if (bw_lim > 0) {
period_us = want_send * 8 / bw_lim;
}
while (!s_iperf_ctrl.finish) {
if (period_us > 0) {
send_time = esp_timer_get_time();
if (actual_send > 0){
// Last packet "send" was successful, check how much off the previous loop duration was to the ideal send period. Result will adjust the
// next send delay.
delay_us += period_us + (int32_t)(prev_time - send_time);
} else {
// Last packet "send" was not successful. Ideally we should try to catch up the whole previous loop duration (e.g. prev_time - send_time).
// However, that's not possible since the most probable reason why the send was unsuccessful is the HW was not able to process the packet.
// Hence, we cannot queue more packets with shorter (or no) delay to catch up since we are already at the performance edge. The best we
// can do is to reset the send delay (which is probably big negative number) and start all over again.
delay_us = 0;
}
prev_time = send_time;
}
*pkt_id_p = htonl(pkt_cnt++); // datagrams need to be sequentially numbered
actual_send = sendto(send_socket, buffer, want_send, 0, (struct sockaddr *)&dest_addr, socklen);
if (actual_send != want_send) {
if (type == IPERF_TRANS_TYPE_UDP) {
err = iperf_get_socket_error_code(send_socket);
// ENOMEM is expected under heavy load => do not print it
if (err != ENOMEM) {
iperf_show_socket_error_reason(error_log, send_socket);
}
} else if (type == IPERF_TRANS_TYPE_TCP) {
iperf_show_socket_error_reason(error_log, send_socket);
break;
}
} else {
s_iperf_ctrl.actual_len += actual_send;
}
// The send delay may be negative, it indicates we are trying to catch up and hence to not delay the loop at all.
if (delay_us > 0) {
esp_rom_delay_us(delay_us);
}
}
}
static esp_err_t iperf_run_tcp_server(void)
{
int listen_socket = -1;
int client_socket = -1;
int opt = 1;
int err = 0;
esp_err_t ret = ESP_OK;
struct sockaddr_in remote_addr;
struct timeval timeout = { 0 };
socklen_t addr_len = sizeof(struct sockaddr);
struct sockaddr_storage listen_addr = { 0 };
struct sockaddr_in listen_addr4 = { 0 };
#ifdef CONFIG_LWIP_IPV6
struct sockaddr_in6 listen_addr6 = { 0 };
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#else
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Invalid AF types");
#endif
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
// The TCP server listen at the address "::", which means all addresses can be listened to.
inet6_aton("::", &listen_addr6.sin6_addr);
listen_addr6.sin6_family = AF_INET6;
listen_addr6.sin6_port = htons(s_iperf_ctrl.cfg.sport);
listen_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
ESP_GOTO_ON_FALSE((listen_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(listen_socket, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
ESP_LOGI(TAG, "Socket created");
err = bind(listen_socket, (struct sockaddr *)&listen_addr6, sizeof(listen_addr6));
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to bind: errno %d, IPPROTO: %d", errno, AF_INET6);
err = listen(listen_socket, 1);
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Error occurred during listen: errno %d", errno);
memcpy(&listen_addr, &listen_addr6, sizeof(listen_addr6));
} else
#endif
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
listen_addr4.sin_family = AF_INET;
listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ESP_GOTO_ON_FALSE((listen_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
ESP_LOGI(TAG, "Socket created");
err = bind(listen_socket, (struct sockaddr *)&listen_addr4, sizeof(listen_addr4));
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to bind: errno %d, IPPROTO: %d", errno, AF_INET);
err = listen(listen_socket, 5);
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Error occurred during listen: errno %d", errno);
memcpy(&listen_addr, &listen_addr4, sizeof(listen_addr4));
}
timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
client_socket = accept(listen_socket, (struct sockaddr *)&remote_addr, &addr_len);
ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to accept connection: errno %d", errno);
ESP_LOGI(TAG, "accept: %s,%d", inet_ntoa(remote_addr.sin_addr), htons(remote_addr.sin_port));
timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
wifi_cmd_clr_tx_statistics(0, NULL);
#endif
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
wifi_cmd_clr_rx_statistics(0, NULL);
#endif
socket_recv(client_socket, listen_addr, IPERF_TRANS_TYPE_TCP);
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
wifi_cmd_get_rx_statistics(0, NULL);
#endif
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
wifi_cmd_get_tx_statistics(0, NULL);
#endif
exit:
if (client_socket != -1) {
close(client_socket);
}
if (listen_socket != -1) {
shutdown(listen_socket, 0);
close(listen_socket);
ESP_LOGI(TAG, "TCP Socket server is closed.");
}
s_iperf_ctrl.finish = true;
return ret;
}
static esp_err_t iperf_run_tcp_client(void)
{
int client_socket = -1;
int err = 0;
esp_err_t ret = ESP_OK;
struct sockaddr_storage dest_addr = { 0 };
struct sockaddr_in dest_addr4 = { 0 };
struct timeval timeout = { 0 };
#ifdef CONFIG_LWIP_IPV6
struct sockaddr_in6 dest_addr6 = { 0 };
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#else
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Invalid AF types");
#endif
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
client_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
inet6_aton(s_iperf_ctrl.cfg.destination_ip6, &dest_addr6.sin6_addr);
dest_addr6.sin6_family = AF_INET6;
dest_addr6.sin6_port = htons(s_iperf_ctrl.cfg.dport);
err = connect(client_socket, (struct sockaddr *)&dest_addr6, sizeof(struct sockaddr_in6));
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to connect: errno %d", errno);
ESP_LOGI(TAG, "Successfully connected");
memcpy(&dest_addr, &dest_addr6, sizeof(dest_addr6));
} else
#endif
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
dest_addr4.sin_family = AF_INET;
dest_addr4.sin_port = htons(s_iperf_ctrl.cfg.dport);
dest_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.destination_ip4;
err = connect(client_socket, (struct sockaddr *)&dest_addr4, sizeof(struct sockaddr_in));
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to connect: errno %d", errno);
ESP_LOGI(TAG, "Successfully connected");
memcpy(&dest_addr, &dest_addr4, sizeof(dest_addr4));
}
timeout.tv_sec = IPERF_SOCKET_TCP_TX_TIMEOUT;
setsockopt(client_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
wifi_cmd_clr_rx_statistics(0, NULL);
#endif
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
wifi_cmd_clr_tx_statistics(0, NULL);
#endif
socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_TCP, s_iperf_ctrl.cfg.bw_lim);
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
wifi_cmd_get_rx_statistics(0, NULL);
#endif
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
wifi_cmd_get_tx_statistics(0, NULL);
#endif
exit:
if (client_socket != -1) {
shutdown(client_socket, 0);
close(client_socket);
ESP_LOGI(TAG, "TCP Socket client is closed.");
}
s_iperf_ctrl.finish = true;
return ret;
}
static esp_err_t iperf_run_udp_server(void)
{
int listen_socket = -1;
int opt = 1;
int err = 0;
esp_err_t ret = ESP_OK;
struct timeval timeout = { 0 };
struct sockaddr_storage listen_addr = { 0 };
struct sockaddr_in listen_addr4 = { 0 };
#ifdef CONFIG_LWIP_IPV6
struct sockaddr_in6 listen_addr6 = { 0 };
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#else
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#endif
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
// The UDP server listen at the address "::", which means all addresses can be listened to.
inet6_aton("::", &listen_addr6.sin6_addr);
listen_addr6.sin6_family = AF_INET6;
listen_addr6.sin6_port = htons(s_iperf_ctrl.cfg.sport);
listen_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
ESP_GOTO_ON_FALSE((listen_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created");
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
err = bind(listen_socket, (struct sockaddr *)&listen_addr6, sizeof(struct sockaddr_in6));
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to bind: errno %d", errno);
ESP_LOGI(TAG, "Socket bound, port %" PRIu16, listen_addr6.sin6_port);
memcpy(&listen_addr, &listen_addr6, sizeof(listen_addr6));
} else
#endif
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
listen_addr4.sin_family = AF_INET;
listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
listen_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ESP_GOTO_ON_FALSE((listen_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created");
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
err = bind(listen_socket, (struct sockaddr *)&listen_addr4, sizeof(struct sockaddr_in));
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to bind: errno %d", errno);
ESP_LOGI(TAG, "Socket bound, port %d", listen_addr4.sin_port);
memcpy(&listen_addr, &listen_addr4, sizeof(listen_addr4));
}
timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
wifi_cmd_clr_rx_statistics(0, NULL);
#endif
socket_recv(listen_socket, listen_addr, IPERF_TRANS_TYPE_UDP);
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
wifi_cmd_get_rx_statistics(0, NULL);
#endif
exit:
if (listen_socket != -1) {
shutdown(listen_socket, 0);
close(listen_socket);
}
ESP_LOGI(TAG, "Udp socket server is closed.");
s_iperf_ctrl.finish = true;
return ret;
}
static esp_err_t iperf_run_udp_client(void)
{
int client_socket = -1;
int opt = 1;
esp_err_t ret = ESP_OK;
struct sockaddr_storage dest_addr = { 0 };
struct sockaddr_in dest_addr4 = { 0 };
#ifdef CONFIG_LWIP_IPV6
struct sockaddr_in6 dest_addr6 = { 0 };
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#else
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#endif
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
inet6_aton(s_iperf_ctrl.cfg.destination_ip6, &dest_addr6.sin6_addr);
dest_addr6.sin6_family = AF_INET6;
dest_addr6.sin6_port = htons(s_iperf_ctrl.cfg.dport);
client_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created, sending to %s:%" PRIu16, s_iperf_ctrl.cfg.destination_ip6, s_iperf_ctrl.cfg.dport);
setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
memcpy(&dest_addr, &dest_addr6, sizeof(dest_addr6));
} else
#endif
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
dest_addr4.sin_family = AF_INET;
dest_addr4.sin_port = htons(s_iperf_ctrl.cfg.dport);
dest_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.destination_ip4;
client_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created, sending to %d.%d.%d.%d:%" PRIu16,
(uint16_t) s_iperf_ctrl.cfg.destination_ip4 & 0xFF,
(uint16_t) (s_iperf_ctrl.cfg.destination_ip4 >> 8) & 0xFF,
(uint16_t) (s_iperf_ctrl.cfg.destination_ip4 >> 16) & 0xFF,
(uint16_t) (s_iperf_ctrl.cfg.destination_ip4 >> 24) & 0xFF,
s_iperf_ctrl.cfg.dport);
setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
memcpy(&dest_addr, &dest_addr4, sizeof(dest_addr4));
}
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
wifi_cmd_clr_tx_statistics(0, NULL);
#endif
socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_UDP, s_iperf_ctrl.cfg.bw_lim);
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
wifi_cmd_get_tx_statistics(0, NULL);
#endif
exit:
if (client_socket != -1) {
shutdown(client_socket, 0);
close(client_socket);
}
s_iperf_ctrl.finish = true;
ESP_LOGI(TAG, "UDP Socket client is closed");
return ret;
}
static void iperf_task_traffic(void *arg)
{
if (iperf_is_udp_client()) {
iperf_run_udp_client();
} else if (iperf_is_udp_server()) {
iperf_run_udp_server();
} else if (iperf_is_tcp_client()) {
iperf_run_tcp_client();
} else {
iperf_run_tcp_server();
}
if (s_iperf_ctrl.buffer) {
free(s_iperf_ctrl.buffer);
s_iperf_ctrl.buffer = NULL;
}
ESP_LOGI(TAG, "iperf exit");
s_iperf_is_running = false;
vTaskDelete(NULL);
}
static uint32_t iperf_get_buffer_len(void)
{
if (iperf_is_udp_client()) {
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.len_send_buf) {
return s_iperf_ctrl.cfg.len_send_buf;
} else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
return IPERF_DEFAULT_IPV6_UDP_TX_LEN;
} else {
return IPERF_DEFAULT_IPV4_UDP_TX_LEN;
}
#else
return (s_iperf_ctrl.cfg.len_send_buf == 0 ? IPERF_DEFAULT_IPV4_UDP_TX_LEN : s_iperf_ctrl.cfg.len_send_buf);
#endif
} else if (iperf_is_udp_server()) {
return IPERF_DEFAULT_UDP_RX_LEN;
} else if (iperf_is_tcp_client()) {
return (s_iperf_ctrl.cfg.len_send_buf == 0 ? IPERF_DEFAULT_TCP_TX_LEN : s_iperf_ctrl.cfg.len_send_buf);
} else {
return IPERF_DEFAULT_TCP_RX_LEN;
}
return 0;
}
esp_err_t iperf_start(iperf_cfg_t *cfg)
{
BaseType_t ret;
if (!cfg) {
return ESP_FAIL;
}
if (s_iperf_is_running) {
ESP_LOGW(TAG, "iperf is running");
return ESP_FAIL;
}
memset(&s_iperf_ctrl, 0, sizeof(s_iperf_ctrl));
memcpy(&s_iperf_ctrl.cfg, cfg, sizeof(*cfg));
s_iperf_is_running = true;
s_iperf_ctrl.finish = false;
s_iperf_ctrl.buffer_len = iperf_get_buffer_len();
s_iperf_ctrl.buffer = (uint8_t *)malloc(s_iperf_ctrl.buffer_len);
if (!s_iperf_ctrl.buffer) {
ESP_LOGE(TAG, "create buffer: not enough memory");
return ESP_FAIL;
}
memset(s_iperf_ctrl.buffer, 0, s_iperf_ctrl.buffer_len);
ret = xTaskCreatePinnedToCore(iperf_task_traffic, IPERF_TRAFFIC_TASK_NAME, IPERF_TRAFFIC_TASK_STACK, NULL, IPERF_TRAFFIC_TASK_PRIORITY, NULL, CONFIG_FREERTOS_NUMBER_OF_CORES - 1);
if (ret != pdPASS) {
ESP_LOGE(TAG, "create task %s failed", IPERF_TRAFFIC_TASK_NAME);
free(s_iperf_ctrl.buffer);
s_iperf_ctrl.buffer = NULL;
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t iperf_stop(void)
{
if (s_iperf_is_running) {
s_iperf_ctrl.finish = true;
}
while (s_iperf_is_running) {
ESP_LOGI(TAG, "wait current iperf to stop ...");
vTaskDelay(300 / portTICK_PERIOD_MS);
}
return ESP_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,6 @@ examples/ethernet/iperf:
- esp_driver_gpio - esp_driver_gpio
- esp_driver_spi - esp_driver_spi
depends_filepatterns: depends_filepatterns:
- examples/common_components/iperf/**/*
- examples/common_components/protocol_examples_common/**/* - examples/common_components/protocol_examples_common/**/*
- examples/system/console/advanced/components/cmd_system/**/* - examples/system/console/advanced/components/cmd_system/**/*
- examples/ethernet/basic/components/ethernet_init/**/* - examples/ethernet/basic/components/ethernet_init/**/*

View File

@ -3,5 +3,5 @@ dependencies:
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system
ethernet_init: ethernet_init:
path: ${IDF_PATH}/examples/ethernet/basic/components/ethernet_init path: ${IDF_PATH}/examples/ethernet/basic/components/ethernet_init
iperf: espressif/iperf:
path: ${IDF_PATH}/examples/common_components/iperf version: "~0.1.1"

View File

@ -11,8 +11,6 @@
- lwip - lwip
- openthread - openthread
depends_filepatterns: depends_filepatterns:
- examples/common_components/iperf/*
- examples/common_components/iperf/**/*
- examples/openthread/* - examples/openthread/*
- examples/openthread/**/* - examples/openthread/**/*

View File

@ -8,7 +8,7 @@ dependencies:
version: ">=5.0" version: ">=5.0"
protocol_examples_common: protocol_examples_common:
path: ${IDF_PATH}/examples/common_components/protocol_examples_common path: ${IDF_PATH}/examples/common_components/protocol_examples_common
iperf:
path: ${IDF_PATH}/examples/common_components/iperf
ot_led: ot_led:
path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led
espressif/iperf:
version: "~0.1.1"

View File

@ -4,7 +4,7 @@ dependencies:
version: "~1.0.0" version: "~1.0.0"
idf: idf:
version: ">=4.1.0" version: ">=4.1.0"
iperf:
path: ${IDF_PATH}/examples/common_components/iperf
ot_led: ot_led:
path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led
espressif/iperf:
version: "~0.1.1"

View File

@ -1,3 +1,2 @@
idf_component_register(SRCS "cmd_wifi.c" idf_component_register(SRCS "iperf_example_main.c"
"iperf_example_main.c"
INCLUDE_DIRS ".") INCLUDE_DIRS ".")

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -1,5 +1,9 @@
dependencies: dependencies:
cmd_system: cmd_system:
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system
iperf: espressif/iperf-cmd:
path: ${IDF_PATH}/examples/common_components/iperf version: "~0.1.1"
esp-qa/wifi-cmd:
version: "~0.0.2"
esp-qa/ping-cmd:
version: "~0.0.1"

View File

@ -14,7 +14,58 @@
#include "esp_err.h" #include "esp_err.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "esp_console.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) void app_main(void)
{ {
@ -25,7 +76,22 @@ void app_main(void)
} }
ESP_ERROR_CHECK( ret ); 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_t *repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
@ -45,7 +111,11 @@ void app_main(void)
/* Register commands */ /* Register commands */
register_system(); 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("\n ==================================================\n");
printf(" | Steps to test WiFi throughput |\n"); printf(" | Steps to test WiFi throughput |\n");

View File

@ -16,19 +16,12 @@ The test env wifi_iperf do need the following config::
""" """
import os import os
import time
from typing import Any
from typing import Callable from typing import Callable
from typing import Tuple
import pexpect
import pytest import pytest
from common_test_methods import get_env_config_variable from common_test_methods import get_env_config_variable
from common_test_methods import get_host_ip_by_interface from common_test_methods import get_host_ip_by_interface
from idf_iperf_test_util import IperfUtility 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 from pytest_embedded import Dut
# configurations # configurations
@ -39,105 +32,6 @@ NO_BANDWIDTH_LIMIT = -1 # iperf send bandwith is not limited
BEST_PERFORMANCE_CONFIG = '99' 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.esp32
@pytest.mark.temp_skip_ci(targets=['esp32s2', 'esp32c3', 'esp32s3'], reason='lack of runners (run only for ESP32)') @pytest.mark.temp_skip_ci(targets=['esp32s2', 'esp32c3', 'esp32s3'], reason='lack of runners (run only for ESP32)')
@pytest.mark.timeout(1200) @pytest.mark.timeout(1200)

View File

@ -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 ".") INCLUDE_DIRS ".")

View File

@ -3,7 +3,3 @@ dependencies:
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system
cmd_nvs: cmd_nvs:
path: ${IDF_PATH}/examples/system/console/advanced/components/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

View File

@ -26,11 +26,12 @@
#include "nvs_flash.h" #include "nvs_flash.h"
#include "esp_console.h" #include "esp_console.h"
#include "cmd_system.h" #include "cmd_system.h"
#include "wifi_cmd.h"
#include "esp_wifi_he.h" #include "esp_wifi_he.h"
#include "esp_pm.h" #include "esp_pm.h"
#include "esp_timer.h" #include "esp_timer.h"
#include "wifi_cmd.h"
/******************************************************* /*******************************************************
* Constants * Constants
*******************************************************/ *******************************************************/

View File

@ -10,12 +10,9 @@
extern "C" { extern "C" {
#endif #endif
void register_wifi_cmd(void);
void register_wifi_itwt(void); void register_wifi_itwt(void);
void register_wifi_stats(void); void register_wifi_stats(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1034,8 +1034,6 @@ examples/build_system/cmake/multi_config/main/func.h
examples/build_system/cmake/multi_config/main/func_dev.c examples/build_system/cmake/multi_config/main/func_dev.c
examples/build_system/cmake/multi_config/main/func_prod.c examples/build_system/cmake/multi_config/main/func_prod.c
examples/build_system/cmake/multi_config/main/multi_config_example_main.c examples/build_system/cmake/multi_config/main/multi_config_example_main.c
examples/common_components/iperf/include/iperf.h
examples/common_components/iperf/iperf.c
examples/common_components/protocol_examples_common/addr_from_stdin.c examples/common_components/protocol_examples_common/addr_from_stdin.c
examples/common_components/protocol_examples_common/include/addr_from_stdin.h examples/common_components/protocol_examples_common/include/addr_from_stdin.h
examples/common_components/protocol_examples_common/include/protocol_examples_common.h examples/common_components/protocol_examples_common/include/protocol_examples_common.h
@ -1192,9 +1190,6 @@ examples/wifi/fast_scan/main/fast_scan.c
examples/wifi/ftm/main/ftm_main.c examples/wifi/ftm/main/ftm_main.c
examples/wifi/getting_started/softAP/main/softap_example_main.c examples/wifi/getting_started/softAP/main/softap_example_main.c
examples/wifi/getting_started/station/main/station_example_main.c examples/wifi/getting_started/station/main/station_example_main.c
examples/wifi/iperf/main/cmd_decl.h
examples/wifi/iperf/main/cmd_wifi.c
examples/wifi/iperf/main/cmd_wifi.h
examples/wifi/iperf/main/iperf_example_main.c examples/wifi/iperf/main/iperf_example_main.c
examples/wifi/power_save/main/power_save.c examples/wifi/power_save/main/power_save.c
examples/wifi/roaming/main/roaming_example.c examples/wifi/roaming/main/roaming_example.c

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
import logging import logging
import os import os
@ -33,7 +33,7 @@ class TestResult(object):
""" record, analysis test result and convert data to output format """ """ record, analysis test result and convert data to output format """
PC_BANDWIDTH_LOG_PATTERN = re.compile(r'(\d+\.\d+)\s*-\s*(\d+.\d+)\s+sec\s+[\d.]+\s+MBytes\s+([\d.]+)\s+Mbits\/sec') PC_BANDWIDTH_LOG_PATTERN = re.compile(r'(\d+\.\d+)\s*-\s*(\d+.\d+)\s+sec\s+[\d.]+\s+MBytes\s+([\d.]+)\s+Mbits\/sec')
DUT_BANDWIDTH_LOG_PATTERN = re.compile(r'(\d+)-\s+(\d+)\s+sec\s+([\d.]+)\s+Mbits/sec') DUT_BANDWIDTH_LOG_PATTERN = re.compile(r'([\d.]+)\s*-\s*([\d.]+)\s+sec\s+([\d.]+)\s+Mbits/sec')
ZERO_POINT_THRESHOLD = -88 # RSSI, dbm ZERO_POINT_THRESHOLD = -88 # RSSI, dbm
ZERO_THROUGHPUT_THRESHOLD = -92 # RSSI, dbm ZERO_THROUGHPUT_THRESHOLD = -92 # RSSI, dbm
@ -278,7 +278,7 @@ class IperfTestUtility(object):
self.dut.write('restart') self.dut.write('restart')
self.dut.expect_exact("Type 'help' to get the list of commands.") self.dut.expect_exact("Type 'help' to get the list of commands.")
self.dut.expect('iperf>') self.dut.expect('iperf>')
self.dut.write('scan {}'.format(self.ap_ssid)) self.dut.write('sta_scan {}'.format(self.ap_ssid))
for _ in range(SCAN_RETRY_COUNT): for _ in range(SCAN_RETRY_COUNT):
try: try:
rssi = int(self.dut.expect(r'\[{}]\[rssi=(-\d+)]'.format(self.ap_ssid), rssi = int(self.dut.expect(r'\[{}]\[rssi=(-\d+)]'.format(self.ap_ssid),
@ -288,7 +288,7 @@ class IperfTestUtility(object):
continue continue
else: else:
raise AssertionError('Failed to scan AP') raise AssertionError('Failed to scan AP')
self.dut.write('sta {} {}'.format(self.ap_ssid, self.ap_password)) self.dut.write('sta_connect {} {}'.format(self.ap_ssid, self.ap_password))
dut_ip = self.dut.expect(r'sta ip: ([\d.]+), mask: ([\d.]+), gw: ([\d.]+)').group(1) dut_ip = self.dut.expect(r'sta ip: ([\d.]+), mask: ([\d.]+), gw: ([\d.]+)').group(1)
return dut_ip, rssi return dut_ip, rssi
@ -338,7 +338,7 @@ class IperfTestUtility(object):
self.dut.write('iperf -s -i 1 -t {}'.format(TEST_TIME)) self.dut.write('iperf -s -i 1 -t {}'.format(TEST_TIME))
# wait until DUT TCP server created # wait until DUT TCP server created
try: try:
self.dut.expect('iperf: Socket created', timeout=5) self.dut.expect('Socket created', timeout=5)
except pexpect.TIMEOUT: except pexpect.TIMEOUT:
# compatible with old iperf example binary # compatible with old iperf example binary
logging.info('create iperf tcp server fail') logging.info('create iperf tcp server fail')
@ -358,7 +358,7 @@ class IperfTestUtility(object):
self.dut.write('iperf -s -u -i 1 -t {}'.format(TEST_TIME)) self.dut.write('iperf -s -u -i 1 -t {}'.format(TEST_TIME))
# wait until DUT TCP server created # wait until DUT TCP server created
try: try:
self.dut.expect('iperf: Socket bound', timeout=5) self.dut.expect('Socket bound', timeout=5)
except pexpect.TIMEOUT: except pexpect.TIMEOUT:
# compatible with old iperf example binary # compatible with old iperf example binary
logging.info('create iperf udp server fail') logging.info('create iperf udp server fail')