openthread: add iperf example for ot-network test

This commit is contained in:
zhangwenxu
2021-07-30 15:55:37 +08:00
committed by bot
parent ef75b5a188
commit 2be77287b3
22 changed files with 673 additions and 396 deletions
@@ -2,5 +2,7 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/iperf)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp_ot_cli)
+2
View File
@@ -5,4 +5,6 @@
PROJECT_NAME := esp_ot_cli
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/iperf
include $(IDF_PATH)/make/project.mk
+79 -6
View File
@@ -84,7 +84,9 @@ leader
Done
```
## Example1: TCP/UDP server and client
## Example1: Set up network
You need to prepare two esp32h2(or two ESP devices each connected to a 15.4 RCP) and flashed with this example.
### Step 1 Configure the project
@@ -92,10 +94,7 @@ Done
idf.py menuconfig
```
Enable the operation: Example Configuration -> Enable custom command in ot-cli -> Enable openthread tcp/udp socket
### Step 2 Build, Flash, and Run
You need to prepare two ESP devices each connected to a 15.4 RCP and flashed with this example.
```
idf.py -p PORT flash monitor
@@ -136,7 +135,6 @@ Done
leader
Done
```
Now the first device has formed a Thread network, on the second device run:
```bash
@@ -174,7 +172,21 @@ Done
Now the second device has joined the Thread network and acting as a router (or a child).
### Step 4 Set up tcp/udp socket server and client
## Example2: TCP/UDP server and client
You need to prepare two ESP devices each connected to a 15.4 RCP and flashed with this example.
### Step 1 Configure the project and Set up network
```bash
idf.py menuconfig
```
Enable the operation: Example Configuration -> Enable custom command in ot-cli
After configuring the project project, you should follow 'Example1' to set up network.
### Step 2 Set up tcp/udp socket server and client
In leader device, run this command in command line shell.
@@ -243,3 +255,64 @@ I (38321) ot_secket: This message is from server
I (38323) ot_secket: Socket client is closed.
```
## Example3 iperf:
### Step 1 Configure the project and Set up network
```bash
idf.py menuconfig
```
Enable the operation: Openthread -> Enable custom command in ot-cli
After configuring the project project, you should follow 'Example1' to set up network.
### Step 2 Iperf test:
Run this command for iperf help:
```bash
iperf
I(272113) OPENTHREAD:[INFO]-CLI-----: execute command: iperf
---iperf parameter---
-s : server mode, only receive
-u : upd mode
-V : use IPV6 address
-c <addr> : client mode, only transmit
-i <interval> : seconds between periodic bandwidth reports
-t <time> : time in seconds to transmit for (default 10 secs)
-p <port> : server port to listen on/connect to
-l <len_send_buf> : the lenth of send buffer
---example---
create a tcp server : iperf -s -i 3 -p 5001 -t 60
create a udp client : iperf -c <addr> -u -i 3 -t 60 -p 5001 -l 512
Done
```
In leader device, run this command to get the leader IPv6 address.
```bash
> ipaddr
fd00:db8:0:0:0:ff:fe00:fc00
fd00:db8:0:0:0:ff:fe00:ac00
fd00:db8:0:0:284a:cb4a:cb3b:2a42
fe80:0:0:0:146e:a00:0:1
```
Then run this command in command line shell.
```bash
# for setting up an iperf tcp server
> iperf -V -s -i 3 -p 5001 -t 20
# for setting up an iperf udp server
> iperf -V -s -u -i 3 -p 5001 -t 20
```
In router device, run this command in command line shell.
```bash
# for setting up an iperf tcp client
> iperf -V -c fd00:db8:0:0:284a:cb4a:cb3b:2a42 -i 1 -t 14 -p 5001 -l 512
# for setting up an iperf udp client
> iperf -V -c fd00:db8:0:0:284a:cb4a:cb3b:2a42 -u -i 1 -t 14 -p 5001 -l 512
```
@@ -1,7 +1,7 @@
set(srcs "esp_ot_cli.c")
if(CONFIG_OPENTHREAD_CLI_ESP_EXTENSION)
list(APPEND srcs "esp_ot_cli_extension.c" "esp_ot_tcp_socket.c" "esp_ot_udp_socket.c")
list(APPEND srcs "esp_ot_cli_extension.c" "esp_ot_tcp_socket.c" "esp_ot_udp_socket.c" "esp_ot_iperf.c")
endif()
idf_component_register(SRCS "${srcs}"
+5 -13
View File
@@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <unistd.h>
@@ -1,19 +1,12 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_openthread.h"
#include "esp_ot_cli_extension.h"
#include "esp_ot_iperf.h"
#include "esp_ot_tcp_socket.h"
#include "esp_ot_udp_socket.h"
#include "freertos/FreeRTOS.h"
@@ -26,6 +19,7 @@ static const otCliCommand kCommands[] = {
{"tcpsockclient", esp_ot_process_tcp_client},
{"udpsockserver", esp_ot_process_udp_server},
{"udpsockclient", esp_ot_process_udp_client},
{"iperf", esp_ot_process_iperf}
};
void esp_cli_custom_command_init()
@@ -1,18 +1,10 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
@@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) CO LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
@@ -0,0 +1,98 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_check.h"
#include "esp_log.h"
#include "esp_ot_iperf.h"
#include "iperf.h"
#include "openthread/cli.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TAG "ot-iperf"
void esp_ot_process_iperf(void *aContext, uint8_t aArgsLength, char *aArgs[])
{
(void)(aContext);
(void)(aArgsLength);
iperf_cfg_t cfg;
memset(&cfg, 0, sizeof(cfg));
// set iperf default flag: tcp server
IPERF_FLAG_SET(cfg.flag, IPERF_FLAG_TCP);
IPERF_FLAG_SET(cfg.flag, IPERF_FLAG_SERVER);
cfg.time = IPERF_DEFAULT_TIME;
cfg.type = IPERF_IP_TYPE_IPV4;
if (aArgsLength == 0) {
otCliOutputFormat("---iperf parameter---\n");
otCliOutputFormat("-V : use IPV6 address\n");
otCliOutputFormat("-s : server mode, only receive\n");
otCliOutputFormat("-u : upd mode\n");
otCliOutputFormat("-c <addr> : client mode, only transmit\n");
otCliOutputFormat("-i <interval> : seconds between periodic bandwidth reports\n");
otCliOutputFormat("-t <time> : time in seconds to transmit for (default 30 secs)\n");
otCliOutputFormat("-p <port> : server port to listen on/connect to\n");
otCliOutputFormat("-l <len_send_buf> : the lenth of send buffer\n");
otCliOutputFormat("---example---\n");
otCliOutputFormat("create a tcp server : iperf -s -i 3 -p 5001 -t 60\n");
otCliOutputFormat("create a udp client : iperf -c <addr> -u -i 3 -t 60 -p 5001 -l 512\n");
} else {
for (int i = 0; i < aArgsLength; i++) {
if (strcmp(aArgs[i], "-c") == 0) {
IPERF_FLAG_SET(cfg.flag, IPERF_FLAG_CLIENT);
IPERF_FLAG_CLR(cfg.flag, IPERF_FLAG_SERVER);
i++;
cfg.destination_ip6 = aArgs[i];
otCliOutputFormat("ip:%s\n", cfg.destination_ip6);
} else if (strcmp(aArgs[i], "-s") == 0) {
IPERF_FLAG_SET(cfg.flag, IPERF_FLAG_SERVER);
IPERF_FLAG_CLR(cfg.flag, IPERF_FLAG_CLIENT);
} else if (strcmp(aArgs[i], "-V") == 0) {
cfg.type = IPERF_IP_TYPE_IPV6;
} else if (strcmp(aArgs[i], "-u") == 0) {
IPERF_FLAG_SET(cfg.flag, IPERF_FLAG_UDP);
IPERF_FLAG_CLR(cfg.flag, IPERF_FLAG_TCP);
} else if (strcmp(aArgs[i], "-p") == 0) {
i++;
if (cfg.flag & IPERF_FLAG_SERVER) {
cfg.sport = atoi(aArgs[i]);
cfg.dport = IPERF_DEFAULT_PORT;
} else {
cfg.sport = IPERF_DEFAULT_PORT;
cfg.dport = atoi(aArgs[i]);
}
otCliOutputFormat("dp:%d\n", cfg.dport);
otCliOutputFormat("sp:%d\n", cfg.sport);
} else if (strcmp(aArgs[i], "-i") == 0) {
i++;
if (atoi(aArgs[i]) < 0) {
cfg.interval = IPERF_DEFAULT_INTERVAL;
} else {
cfg.interval = atoi(aArgs[i]);
}
otCliOutputFormat("i:%d\n", cfg.interval);
} else if (strcmp(aArgs[i], "-t") == 0) {
i++;
cfg.time = atoi(aArgs[i]);
if (cfg.time <= cfg.interval) {
cfg.time = cfg.interval;
}
otCliOutputFormat("t:%d\n", cfg.time);
} else if (strcmp(aArgs[i], "-l") == 0) {
i++;
if (atoi(aArgs[i]) <= 0) {
ESP_LOGE(TAG, "Invalid arguments.");
} else {
cfg.len_send_buf = atoi(aArgs[i]);
}
} else if (strcmp(aArgs[i], "-a") == 0) {
iperf_stop();
return;
}
}
iperf_start(&cfg);
}
}
@@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief User command "iperf" process.
*
*/
void esp_ot_process_iperf(void *aContext, uint8_t aArgsLength, char *aArgs[]);
#ifdef __cplusplus
}
#endif
@@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_check.h"
#include "esp_err.h"
@@ -32,7 +24,7 @@ static void tcp_socket_server_task(void *pvParameters)
int opt = 1;
int port = CONFIG_OPENTHREAD_CLI_TCP_SERVER_PORT;
int client_sock = 0;
struct timeval timeout;
struct timeval timeout = { 0 };
struct sockaddr_storage source_addr; // Large enough for both IPv6
struct sockaddr_in6 listen_addr = { 0 };
// The TCP server listen at the address "::", which means all addresses can be listened to.
@@ -154,7 +146,7 @@ void esp_ot_process_tcp_client(void *aContext, uint8_t aArgsLength, char *aArgs[
{
(void)(aContext);
(void)(aArgsLength);
if (aArgs[0] == NULL) {
if (aArgsLength == 0) {
ESP_LOGE(TAG, "Invalid arguments.");
} else {
xTaskCreate(tcp_socket_client_task, "ot_tcp_socket_client", 4096, aArgs[0], 4, NULL);
@@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
@@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_check.h"
#include "esp_err.h"
@@ -30,8 +22,9 @@ static void udp_socket_server_task(void *pvParameters)
int err = 0;
int len;
int listen_sock;
int port = CONFIG_OPENTHREAD_CLI_UDP_SERVER_PORT;
struct timeval timeout;
struct timeval timeout = { 0 };
struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
struct sockaddr_in6 listen_addr;
@@ -39,7 +32,7 @@ static void udp_socket_server_task(void *pvParameters)
listen_addr.sin6_family = AF_INET6;
listen_addr.sin6_port = htons(port);
listen_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
listen_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
ESP_GOTO_ON_FALSE((listen_sock >= 0), ESP_OK, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created");
@@ -98,7 +91,7 @@ static void udp_socket_client_task(void *pvParameters)
dest_addr.sin6_family = AF_INET6;
dest_addr.sin6_port = htons(port);
client_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
client_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
ESP_GOTO_ON_FALSE((client_sock >= 0), ESP_OK, exit, TAG, "Unable to create socket: errno %d", errno);
ESP_LOGI(TAG, "Socket created, sending to %s:%d", host_ip, port);
@@ -135,7 +128,7 @@ void esp_ot_process_udp_client(void *aContext, uint8_t aArgsLength, char *aArgs[
{
(void)(aContext);
(void)(aArgsLength);
if (aArgs[0] == NULL) {
if (aArgsLength == 0) {
ESP_LOGE(TAG, "Invalid arguments.");
} else {
xTaskCreate(udp_socket_client_task, "ot_udp_socket_client", 4096, aArgs[0], 4, NULL);
@@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
@@ -35,6 +35,7 @@ CONFIG_OPENTHREAD_ENABLED=y
#
# lwIP
#
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
CONFIG_LWIP_MULTICAST_PING=y
# end of lwIP