From a23d1b45afe2bb512004559c5360e0ddc91c48b8 Mon Sep 17 00:00:00 2001 From: Bogdan Kolendovskyy Date: Tue, 2 Apr 2024 14:58:26 +0200 Subject: [PATCH] feat(iperf): use iperf component in iperf example --- examples/ethernet/iperf/main/CMakeLists.txt | 2 +- examples/ethernet/iperf/main/cmd_ethernet.c | 246 ++---------------- examples/ethernet/iperf/main/cmd_ethernet.h | 17 +- ...t_example_main.c => ethernet_iperf_main.c} | 61 ++++- .../ethernet/iperf/main/idf_component.yml | 2 +- tools/ci/check_copyright_ignore.txt | 3 - 6 files changed, 78 insertions(+), 253 deletions(-) rename examples/ethernet/iperf/main/{ethernet_example_main.c => ethernet_iperf_main.c} (58%) diff --git a/examples/ethernet/iperf/main/CMakeLists.txt b/examples/ethernet/iperf/main/CMakeLists.txt index fc8e5dd8bb..a5933f6aa1 100644 --- a/examples/ethernet/iperf/main/CMakeLists.txt +++ b/examples/ethernet/iperf/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "cmd_ethernet.c" - "ethernet_example_main.c" + "ethernet_iperf_main.c" INCLUDE_DIRS ".") diff --git a/examples/ethernet/iperf/main/cmd_ethernet.c b/examples/ethernet/iperf/main/cmd_ethernet.c index cb4158af02..61a8a17efa 100644 --- a/examples/ethernet/iperf/main/cmd_ethernet.c +++ b/examples/ethernet/iperf/main/cmd_ethernet.c @@ -1,35 +1,17 @@ -/* Console example — Ethernet commands +/* + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ - 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 #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "sys/socket.h" // for INADDR_ANY +#include "cmd_ethernet.h" #include "esp_netif.h" -#include "esp_log.h" #include "esp_console.h" -#include "esp_event.h" #include "esp_eth.h" #include "esp_mac.h" -#include "esp_bit_defs.h" #include "argtable3/argtable3.h" -#include "ethernet_init.h" -#include "iperf.h" -#include "sdkconfig.h" - -static bool started = false; -static EventGroupHandle_t eth_event_group; -static const int GOTIP_BIT = BIT0; -static esp_eth_handle_t *s_eth_handles = NULL; -static uint8_t s_eth_port_cnt = 0; -static esp_netif_t **s_eth_netifs = NULL; /* "ethernet" command */ static struct { @@ -48,199 +30,26 @@ static int eth_cmd_control(int argc, char **argv) if (!strncmp(eth_control_args.control->sval[0], "info", 4)) { uint8_t mac_addr[6]; esp_netif_ip_info_t ip; - for(uint32_t i = 0; i < s_eth_port_cnt; i++) { - printf("%s:\r\n", esp_netif_get_desc(s_eth_netifs[i])); - esp_eth_ioctl(s_eth_handles[i], ETH_CMD_G_MAC_ADDR, mac_addr); + esp_netif_t *esp_netif; + // we can use esp_netif_next_unsafe since we one time initialize the network and we don't de-init + esp_netif = esp_netif_next_unsafe(NULL); + while(esp_netif != NULL) { + printf("%s:\r\n", esp_netif_get_desc(esp_netif)); + esp_eth_handle_t eth_hndl = esp_netif_get_io_driver(esp_netif); + esp_eth_ioctl(eth_hndl, ETH_CMD_G_MAC_ADDR, mac_addr); printf(" HW ADDR: " MACSTR "\r\n", MAC2STR(mac_addr)); - esp_netif_get_ip_info(s_eth_netifs[i], &ip); + esp_netif_get_ip_info(esp_netif, &ip); printf(" ETHIP: " IPSTR "\r\n", IP2STR(&ip.ip)); printf(" ETHMASK: " IPSTR "\r\n", IP2STR(&ip.netmask)); printf(" ETHGW: " IPSTR "\r\n", IP2STR(&ip.gw)); + esp_netif = esp_netif_next_unsafe(esp_netif); } } return 0; } -/* "iperf" command */ - -static 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; -} iperf_args; - -static int eth_cmd_iperf(int argc, char **argv) +void register_ethernet_commands(void) { - 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)); - - // ethernet iperf only support IPV4 address - cfg.type = IPERF_IP_TYPE_IPV4; - - /* iperf -a */ - 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(__func__, "Wrong mode! ESP32 should run in client or server mode"); - return 0; - } - - /* iperf -s */ - if (iperf_args.ip->count == 0) { - cfg.flag |= IPERF_FLAG_SERVER; - } - /* iperf -c SERVER_ADDRESS */ - else { - cfg.destination_ip4 = esp_ip4addr_aton(iperf_args.ip->sval[0]); - cfg.flag |= IPERF_FLAG_CLIENT; - } - - if (iperf_args.length->count == 0) { - cfg.len_send_buf = 0; - } else { - cfg.len_send_buf = iperf_args.length->ival[0]; - } - - /* wait for ip, could blocked here */ - xEventGroupWaitBits(eth_event_group, GOTIP_BIT, pdFALSE, pdTRUE, portMAX_DELAY); - - cfg.source_ip4 = INADDR_ANY; - - /* iperf -u */ - if (iperf_args.udp->count == 0) { - cfg.flag |= IPERF_FLAG_TCP; - } else { - cfg.flag |= IPERF_FLAG_UDP; - } - - /* iperf -p */ - 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]; - } - } - - /* iperf -i */ - 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; - } - } - - /* iperf -t */ - 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; - } - } - - printf("mode=%s-%s sip=" IPSTR ":%" PRIu16 ", dip=%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 ":%" PRIu16 ", interval=%" PRIu32 ", time=%" PRIu32 "\r\n", - cfg.flag & IPERF_FLAG_TCP ? "tcp" : "udp", - cfg.flag & IPERF_FLAG_SERVER ? "server" : "client", - (uint16_t) cfg.source_ip4 & 0xFF, - (uint16_t) (cfg.source_ip4 >> 8) & 0xFF, - (uint16_t) (cfg.source_ip4 >> 16) & 0xFF, - (uint16_t) (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; -} - -static void event_handler(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_START) { - started = true; - } else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_STOP) { - xEventGroupClearBits(eth_event_group, GOTIP_BIT); - started = false; - } else if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) { - xEventGroupSetBits(eth_event_group, GOTIP_BIT); - } -} - -void register_ethernet(void) -{ - eth_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - ESP_ERROR_CHECK(example_eth_init(&s_eth_handles, &s_eth_port_cnt)); - - ESP_ERROR_CHECK(esp_netif_init()); - s_eth_netifs = calloc(s_eth_port_cnt, sizeof(esp_netif_t *)); - esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH(); - esp_netif_config_t cfg_spi = { - .base = &esp_netif_config, - .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH - }; - char if_key_str[10]; - char if_desc_str[10]; - char num_str[3]; - for (int i = 0; i < s_eth_port_cnt; i++) { - itoa(i, num_str, 10); - strcat(strcpy(if_key_str, "ETH_"), num_str); - strcat(strcpy(if_desc_str, "eth"), num_str); - esp_netif_config.if_key = if_key_str; - esp_netif_config.if_desc = if_desc_str; - esp_netif_config.route_prio -= i*5; - s_eth_netifs[i] = esp_netif_new(&cfg_spi); - - // attach Ethernet driver to TCP/IP stack - ESP_ERROR_CHECK(esp_netif_attach(s_eth_netifs[i], esp_eth_new_netif_glue(s_eth_handles[i]))); - } - - ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &event_handler, NULL)); - for (int i = 0; i < s_eth_port_cnt; i++) { - ESP_ERROR_CHECK(esp_eth_start(s_eth_handles[i])); - } - eth_control_args.control = arg_str1(NULL, NULL, "", "Get info of Ethernet"); eth_control_args.end = arg_end(1); const esp_console_cmd_t cmd = { @@ -251,27 +60,4 @@ void register_ethernet(void) .argtable = ð_control_args }; ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); - - iperf_args.ip = arg_str0("c", "client", "", - "run in client mode, connecting to "); - 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", "", - "server port to listen on/connect to"); - iperf_args.length = arg_int0("l", "len", "", "set read/write buffer size"); - iperf_args.interval = arg_int0("i", "interval", "", - "seconds between periodic bandwidth reports"); - iperf_args.time = arg_int0("t", "time", "