Skip to content

Commit

Permalink
Merge branch 'examples/tcp_client_linux_support' into 'master'
Browse files Browse the repository at this point in the history
tcp_client example: support for Linux target.

Closes IDF-5636

See merge request espressif/esp-idf!19203
  • Loading branch information
david-cermak committed Aug 18, 2022
2 parents 8226806 + 933a2a6 commit fbc32c0
Show file tree
Hide file tree
Showing 15 changed files with 475 additions and 85 deletions.
2 changes: 2 additions & 0 deletions examples/protocols/.build-test-rules.yml
Expand Up @@ -238,6 +238,8 @@ examples/protocols/sockets/tcp_client:
- if: IDF_TARGET != "esp32"
temporary: true
reason: lack of runners
enable:
- if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux"

examples/protocols/sockets/tcp_client_multi_net:
disable:
Expand Down
14 changes: 9 additions & 5 deletions examples/protocols/sockets/tcp_client/CMakeLists.txt
@@ -1,10 +1,14 @@
# The following five lines of boilerplate have to be in your project's
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)

# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
if(${IDF_TARGET} STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/")
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
else()
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
endif()

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(tcp_client)
64 changes: 39 additions & 25 deletions examples/protocols/sockets/tcp_client/README.md
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | Linux |
| ----------------- | ----- | -------- | -------- | -------- | -------- | ----- |


# TCP Client example
Expand All @@ -8,13 +8,38 @@

The application creates a TCP socket and tries to connect to the server with predefined IP address and port number. When a connection is successfully established, the application sends message and waits for the answer. After the server's reply, application prints received reply as ASCII text, waits for 2 seconds and sends another message.

## How to use example
## Configure the project
This example can be configured to run on ESP32 and Linux target to communicate over IPv4 and IPv6.

```
idf.py menuconfig
```

Set following parameters under ```Example Configuration``` Options:

* Set `IP version` of example to be IPV4 or IPV6.

* Set `IPV4 Address` in case your chose IP version IPV4 above.

* Set `IPV6 Address` in case your chose IP version IPV6 above.
* For IPv6 there's an additional option for ```Interface selection```.
* Enter the name of the interface to explicitely establish communication over a specific interface.
* On selecting ```Auto``` the example will find the first interface with an IPv6 address and use it.

* Set `Port` number that represents remote port the example will connect to.

Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.


Note: please replace `192.168.0.167 3333` with desired IPV4/IPV6 address (displayed in monitor console) and port number in the following command.


## How to use example:

In order to create TCP server that communicates with TCP Client example, choose one of the following options.

There are many host-side tools which can be used to interact with the UDP/TCP server/client.
One command line tool is [netcat](http://netcat.sourceforge.net) which can send and receive many kinds of packets.
Note: please replace `192.168.0.167 3333` with desired IPV4/IPV6 address (displayed in monitor console) and port number in the following command.

In addition to those tools, simple Python scripts can be found under sockets/scripts directory. Every script is designed to interact with one of the examples.

Expand All @@ -24,35 +49,24 @@ nc -l 192.168.0.167 3333
```

### Python scripts
Script example_test.py could be used as a counter part to the tcp-client project, ip protocol name (IPv4 or IPv6) shall be stated as argument. Example:
Script example_test.py could be used as a counter part to the tcp-client project, ip protocol name (IPv4 or IPv6) shall be stated as argument.

Note that this script is used in automated tests, as well, so the IDF test framework packages need to be imported.
Please run the following commands to configure the terminal to execute the script.
```
python example_test.py IPv4
export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/ci/python_packages"
python -m pip install -r $IDF_PATH/tools/ci/python_packages/ttfw_idf/requirements.txt
```
Note that this script is used in automated tests, as well, so the IDF test framework packages need to be imported;
please add `$IDF_PATH/tools/ci/python_packages` to `PYTHONPATH`.

## Hardware Required

This example can be run on any commonly available ESP32 development board.

## Configure the project

Example:
```
idf.py menuconfig
python example_test.py IPv4
```
## Hardware Required

Set following parameters under Example Configuration Options:

* Set `IP version` of example to be IPV4 or IPV6.

* Set `IPV4 Address` in case your chose IP version IPV4 above.

* Set `IPV6 Address` in case your chose IP version IPV6 above.

* Set `Port` number that represents remote port the example will connect to.
This example can be run on any commonly available ESP32 development board.
This example can also run on any Linux environment.

Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.

## Build and Flash

Expand Down
@@ -0,0 +1,6 @@
if(${IDF_TARGET} STREQUAL "linux")
idf_component_register(SRCS
esp_stubs/esp_stubs.c
INCLUDE_DIRS . include/stubs
REQUIRES main)
endif()
@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdlib.h>
#include "esp_err.h"
#include "esp_log.h"

extern void app_main(void);

void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
ESP_LOGE("ESP_ERROR_CHECK", "Failed with esp_err_t: 0x%x", rc);
ESP_LOGE("ESP_ERROR_CHECK", "Expression: %s", expression);
ESP_LOGE("ESP_ERROR_CHECK", "Functions: %s %s(%d)", function, file, line);
abort();
}

esp_err_t esp_event_loop_create_default(void)
{
return ESP_OK;
}

esp_err_t esp_netif_init(void)
{
return ESP_OK;
}

esp_err_t example_connect(void)
{
return ESP_OK;
}

esp_err_t nvs_flash_init(void)
{
return ESP_OK;
}

int main()
{
app_main();

return 0;
}
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "esp_err.h"

esp_err_t esp_event_loop_create_default(void);
@@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <sys/ioctl.h>
#include <net/if.h>
#include <ifaddrs.h>
#include "esp_err.h"

esp_err_t esp_netif_init(void);
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "esp_err.h"

esp_err_t nvs_flash_init(void);
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "esp_err.h"

esp_err_t example_connect(void);
15 changes: 13 additions & 2 deletions examples/protocols/sockets/tcp_client/main/CMakeLists.txt
@@ -1,2 +1,13 @@
idf_component_register(SRCS "tcp_client.c"
INCLUDE_DIRS ".")
if(${IDF_TARGET} STREQUAL "linux")
set(requires esp_stubs)
endif()

if("${CONFIG_EXAMPLE_IPV4}" STREQUAL y)
set(tcp_client_ip tcp_client_v4.c)
else()
set(tcp_client_ip tcp_client_v6.c)
endif()

idf_component_register(SRCS "tcp_client_main.c" "${tcp_client_ip}"
INCLUDE_DIRS "."
REQUIRES ${requires})
20 changes: 20 additions & 0 deletions examples/protocols/sockets/tcp_client/main/Kconfig.projbuild
Expand Up @@ -35,6 +35,26 @@ menu "Example Configuration"
help
The remote port to which the client example will connect to.

choice EXAMPLE_INTERFACE
prompt "Interface selection"
depends on EXAMPLE_IPV6
help
Example can use either "Auto" or "User specified".

config EXAMPLE_IFACE_AUTO
bool "Auto"

config EXAMPLE_USER_SPECIFIED_IFACE
bool "User specified interface"
endchoice

config EXAMPLE_USER_SPECIFIED_IFACE_NAME
string "User specified interface name"
default "st1"
depends on EXAMPLE_USER_SPECIFIED_IFACE
help
This interface will be used for communication.

choice EXAMPLE_SOCKET_IP_INPUT
prompt "Socket example source"
default EXAMPLE_SOCKET_IP_INPUT_STRING
Expand Down
27 changes: 27 additions & 0 deletions examples/protocols/sockets/tcp_client/main/tcp_client_main.c
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "nvs_flash.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "esp_event.h"


extern void tcp_client(void);

void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());

/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());

tcp_client();
}

0 comments on commit fbc32c0

Please sign in to comment.