Skip to content

Commit 5ab699d

Browse files
authored
Merge pull request #354 from david-cermak/feat/modem_iperf_test
feat(modem): Add iperf test of PPP netif
2 parents 18b2ae1 + 976e98d commit 5ab699d

File tree

10 files changed

+631
-1
lines changed

10 files changed

+631
-1
lines changed

.github/workflows/modem__build-host-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
strategy:
5353
matrix:
5454
idf_ver: ["release-v5.0", "release-v5.1", "latest"]
55-
test: ["target", "target_ota"]
55+
test: ["target", "target_ota", "target_iperf"]
5656

5757
runs-on: ubuntu-20.04
5858
container: espressif/idf:${{ matrix.idf_ver }}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# The following five lines of boilerplate have to be in your project's
2+
# CMakeLists in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.5)
4+
5+
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/advanced/components
6+
$ENV{IDF_PATH}/examples/common_components/iperf
7+
"../..")
8+
9+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
10+
project(pppd_test)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Target test for measuring TCP/UDP network performance
2+
3+
## Overview
4+
5+
The aim of this test is to run `iperf` application to measure network throughput of the esp_modem library.
6+
7+
### Configure PPP server
8+
9+
This test uses a network DCE device, which only needs a PPP server. To run the PPP server, use this command:
10+
```
11+
sudo pppd /dev/ttyUSB1 115200 192.168.11.1:192.168.11.2 ms-dns 8.8.8.8 modem local noauth debug nocrtscts nodetach +ipv6
12+
```
13+
14+
### Running using pytest
15+
16+
For checking the performance, you only need to execute the pytest, which will measure the network throughput automatically and report the resultant values. For running the pytest, you need to:
17+
* install IDF pytest packages by running: `./install.sh --enable-pytest`
18+
* add IDF internal packages to python path: `export PYTHONPATH=${DIF_PATH}/tools/ci/python_packages/`
19+
* run the pytest as **superuser**
20+
21+
It's useful to note that when running the test multiple times, you can use `pytest --skip-autoflash y` so the pytest wouldn't have to always reprogram the DUT.
22+
23+
### Performance summary
24+
25+
Here's an example of the resultant summary logged by the pytest
26+
```
27+
2023-11-29 18:28:25 INFO [Performance][tcp_tx_throughput]: 0.75 Mbps
28+
2023-11-29 18:28:25 INFO [Performance][tcp_rx_throughput]: 0.70 Mbps
29+
2023-11-29 18:28:25 INFO [Performance][udp_tx_throughput]: 0.73 Mbps
30+
2023-11-29 18:28:25 INFO [Performance][udp_rx_throughput]: 0.70 Mbps
31+
```
32+
33+
### Running the iperf manually
34+
35+
Execute `idf.py flash monitor` in one terminal and after connecting to the PPP server (after getting an IP address), you can use standard `iperf` commands.
36+
In another terminal, you need to execute the iperf counterpart.
37+
For example running for checking UDP performance, and running server on ESP32, please run:
38+
* iperf -u -s -i 3 (in ESP32 terminal)
39+
* iperf -u -c SERVER_IP -t 60 -i 3 (on the host side)
40+
41+
Note that command `pppd info` will print actual IP addresses:
42+
```
43+
iperf> pppd info
44+
ppp:
45+
IP: 192.168.11.2
46+
MASK: 255.255.255.255
47+
GW: 192.168.11.3
48+
```
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
idf_component_register(SRCS "NetworkDCE.cpp"
2+
"cmd_pppclient.c"
3+
"pppd_iperf_main.c")
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Unlicense OR CC0-1.0
5+
*/
6+
#include "cxx_include/esp_modem_dte.hpp"
7+
#include "esp_modem_config.h"
8+
#include "cxx_include/esp_modem_api.hpp"
9+
#include "cxx_include/esp_modem_dce_factory.hpp"
10+
#include <memory>
11+
#include <utility>
12+
13+
using namespace esp_modem;
14+
using namespace esp_modem::dce_factory;
15+
16+
class NetModule;
17+
typedef DCE_T<NetModule> NetDCE;
18+
19+
/**
20+
* @brief Custom factory which can build and create a DCE using a custom module
21+
*/
22+
class NetDCE_Factory: public Factory {
23+
public:
24+
template <typename T, typename ...Args>
25+
static DCE_T<T> *create(const config *cfg, Args &&... args)
26+
{
27+
return build_generic_DCE<T>(cfg, std::forward<Args>(args)...);
28+
}
29+
};
30+
31+
/**
32+
* @brief This is a null-module, doesn't define any AT commands, just passes everything to pppd
33+
*/
34+
class NetModule: public ModuleIf {
35+
public:
36+
explicit NetModule(std::shared_ptr<DTE> dte, const esp_modem_dce_config *cfg):
37+
dte(std::move(dte)) {}
38+
39+
bool setup_data_mode() override
40+
{
41+
return true;
42+
}
43+
44+
bool set_mode(modem_mode mode) override
45+
{
46+
return true;
47+
}
48+
49+
static esp_err_t init(esp_netif_t *netif)
50+
{
51+
// configure
52+
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
53+
dte_config.uart_config.baud_rate = 921600; // check also 460800
54+
esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("");
55+
56+
// create DTE and minimal network DCE
57+
auto uart_dte = create_uart_dte(&dte_config);
58+
dce = NetDCE_Factory::create<NetModule>(&dce_config, uart_dte, netif);
59+
return dce == nullptr ? ESP_FAIL : ESP_OK;
60+
}
61+
62+
static void deinit()
63+
{
64+
delete dce;
65+
}
66+
static void start()
67+
{
68+
dce->set_data();
69+
}
70+
static void stop()
71+
{
72+
dce->exit_data();
73+
}
74+
75+
private:
76+
static NetDCE *dce;
77+
std::shared_ptr<DTE> dte;
78+
};
79+
80+
NetDCE *NetModule::dce = nullptr;
81+
82+
extern "C" esp_err_t modem_init_network(esp_netif_t *netif)
83+
{
84+
return NetModule::init(netif);
85+
}
86+
87+
extern "C" esp_err_t modem_start_network()
88+
{
89+
NetModule::start();
90+
return ESP_OK;
91+
}
92+
93+
extern "C" void modem_stop_network()
94+
{
95+
NetModule::stop();
96+
}

0 commit comments

Comments
 (0)