Skip to content

Commit

Permalink
fix(eppp_link): Added test-app with server and client on one ESP
Browse files Browse the repository at this point in the history
  • Loading branch information
david-cermak committed Dec 22, 2023
1 parent 046e7e4 commit ad2507e
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 28 deletions.
55 changes: 29 additions & 26 deletions components/eppp_link/eppp_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "esp_check.h"
#include "esp_event.h"
#include "esp_netif_ppp.h"
#include "eppp_link_types.h"
#include "eppp_link.h"

#if CONFIG_EPPP_LINK_DEVICE_SPI
#include "driver/spi_master.h"
Expand All @@ -32,7 +32,7 @@ static int s_retry_num = 0;

#if CONFIG_EPPP_LINK_DEVICE_SPI
static spi_device_handle_t s_spi_device;
#define SPI_HOST SPI2_HOST
#define EPPP_SPI_HOST SPI2_HOST
#define GPIO_MOSI 11
#define GPIO_MISO 13
#define GPIO_SCLK 12
Expand All @@ -51,6 +51,7 @@ struct eppp_handle {
QueueHandle_t ready_semaphore;
#elif CONFIG_EPPP_LINK_DEVICE_UART
QueueHandle_t uart_event_queue;
uart_port_t uart_port;
#endif
esp_netif_t *netif;
enum eppp_type role;
Expand All @@ -64,9 +65,9 @@ struct packet {

static esp_err_t transmit(void *h, void *buffer, size_t len)
{
struct eppp_handle *handle = h;
#if CONFIG_EPPP_LINK_DEVICE_SPI
#define MAX_PAYLOAD 1600
struct eppp_handle *handle = h;
struct packet buf = { };

uint8_t *current_buffer = buffer;
Expand All @@ -84,7 +85,8 @@ static esp_err_t transmit(void *h, void *buffer, size_t len)
}
} while (remaining > 0);
#elif CONFIG_EPPP_LINK_DEVICE_UART
uart_write_bytes(UART_NUM_1, buffer, len);
ESP_LOG_BUFFER_HEXDUMP("ppp_uart_send", buffer, len, ESP_LOG_VERBOSE);
uart_write_bytes(handle->uart_port, buffer, len);
#endif
return ESP_OK;
}
Expand Down Expand Up @@ -237,7 +239,7 @@ static esp_err_t init_master(spi_device_handle_t *spi, esp_netif_t *netif)
bus_cfg.flags = 0;
bus_cfg.intr_flags = 0;

if (spi_bus_initialize(SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO) != ESP_OK) {
if (spi_bus_initialize(EPPP_SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO) != ESP_OK) {
return ESP_FAIL;
}

Expand All @@ -254,7 +256,7 @@ static esp_err_t init_master(spi_device_handle_t *spi, esp_netif_t *netif)
dev_cfg.cs_ena_posttrans = 3;
dev_cfg.queue_size = 3;

if (spi_bus_add_device(SPI_HOST, &dev_cfg, spi) != ESP_OK) {
if (spi_bus_add_device(EPPP_SPI_HOST, &dev_cfg, spi) != ESP_OK) {
return ESP_FAIL;
}

Expand Down Expand Up @@ -317,7 +319,7 @@ static esp_err_t init_slave(spi_device_handle_t *spi, esp_netif_t *netif)
gpio_set_pull_mode(GPIO_CS, GPIO_PULLUP_ONLY);

//Initialize SPI slave interface
if (spi_slave_initialize(SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO) != ESP_OK) {
if (spi_slave_initialize(EPPP_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO) != ESP_OK) {
return ESP_FAIL;
}
return ESP_OK;
Expand Down Expand Up @@ -353,7 +355,7 @@ static esp_err_t perform_transaction_master(union transaction *t, struct eppp_ha

static esp_err_t perform_transaction_slave(union transaction *t, struct eppp_handle *h)
{
return spi_slave_transmit(SPI_HOST, &t->slave, portMAX_DELAY);
return spi_slave_transmit(EPPP_SPI_HOST, &t->slave, portMAX_DELAY);
}

_Noreturn static void ppp_task(void *args)
Expand Down Expand Up @@ -488,22 +490,21 @@ _Noreturn static void ppp_task(void *args)
#define UART_BAUDRATE 4000000
#define UART_QUEUE_SIZE 16

static esp_err_t init_uart(struct eppp_handle *h)
static esp_err_t init_uart(struct eppp_handle *h, eppp_config_t *config)
{
h->uart_port = config->uart.port;
uart_config_t uart_config = {};
uart_config.baud_rate = UART_BAUDRATE;
uart_config.baud_rate = config->uart.baud;
uart_config.data_bits = UART_DATA_8_BITS;
uart_config.parity = UART_PARITY_DISABLE;
uart_config.stop_bits = UART_STOP_BITS_1;
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
uart_config.source_clk = UART_SCLK_DEFAULT;

ESP_RETURN_ON_ERROR(uart_driver_install(UART_NUM_1, BUF_SIZE, 0, UART_QUEUE_SIZE, &h->uart_event_queue, 0), TAG, "Failed to install UART");
ESP_RETURN_ON_ERROR(uart_param_config(UART_NUM_1, &uart_config), TAG, "Failed to set params");
int tx_io_num = h->role == EPPP_CLIENT ? UART_TX_CLIENT_TO_SERVER : UART_TX_SERVER_TO_CLIENT;
int rx_io_num = h->role == EPPP_CLIENT ? UART_TX_SERVER_TO_CLIENT : UART_TX_CLIENT_TO_SERVER;
ESP_RETURN_ON_ERROR(uart_set_pin(UART_NUM_1, tx_io_num, rx_io_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE), TAG, "Failed to set UART pins");
ESP_RETURN_ON_ERROR(uart_set_rx_timeout(UART_NUM_1, 1), TAG, "Failed to set UART Rx timeout");
ESP_RETURN_ON_ERROR(uart_driver_install(h->uart_port, config->uart.rx_buffer_size, 0, config->uart.queue_size, &h->uart_event_queue, 0), TAG, "Failed to install UART");
ESP_RETURN_ON_ERROR(uart_param_config(h->uart_port, &uart_config), TAG, "Failed to set params");
ESP_RETURN_ON_ERROR(uart_set_pin(h->uart_port, config->uart.tx_io, config->uart.rx_io, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE), TAG, "Failed to set UART pins");
ESP_RETURN_ON_ERROR(uart_set_rx_timeout(h->uart_port, 1), TAG, "Failed to set UART Rx timeout");
return ESP_OK;
}

Expand All @@ -513,14 +514,16 @@ _Noreturn static void ppp_task(void *args)

esp_netif_t *netif = args;
struct eppp_handle *h = esp_netif_get_io_driver(netif);
uart_event_t event;
uart_event_t event = {};
while (1) {
xQueueReceive(h->uart_event_queue, &event, pdMS_TO_TICKS(pdMS_TO_TICKS(100)));
if (xQueueReceive(h->uart_event_queue, &event, pdMS_TO_TICKS(100) != pdTRUE)) {
continue;
}
if (event.type == UART_DATA) {
size_t len;
uart_get_buffered_data_len(UART_NUM_1, &len);
uart_get_buffered_data_len(h->uart_port, &len);
if (len) {
len = uart_read_bytes(UART_NUM_1, buffer, BUF_SIZE, 0);
len = uart_read_bytes(h->uart_port, buffer, BUF_SIZE, 0);
ESP_LOG_BUFFER_HEXDUMP("ppp_uart_recv", buffer, len, ESP_LOG_VERBOSE);
esp_netif_receive(netif, buffer, len, NULL);
}
Expand All @@ -533,7 +536,7 @@ _Noreturn static void ppp_task(void *args)
#endif // CONFIG_EPPP_LINK_DEVICE_SPI / UART


static esp_netif_t *default_setup(enum eppp_type role)
static esp_netif_t *default_setup(enum eppp_type role, eppp_config_t *config)
{
s_event_group = xEventGroupCreate();
if (esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL) != ESP_OK) {
Expand All @@ -559,7 +562,7 @@ static esp_netif_t *default_setup(enum eppp_type role)
init_slave(&s_spi_device, netif);
}
#elif CONFIG_EPPP_LINK_DEVICE_UART
init_uart(esp_netif_get_io_driver(netif));
init_uart(esp_netif_get_io_driver(netif), config);
#endif

netif_start(netif);
Expand All @@ -578,12 +581,12 @@ static esp_netif_t *default_setup(enum eppp_type role)
return netif;
}

esp_netif_t *eppp_connect(void)
esp_netif_t *eppp_connect(eppp_config_t *config)
{
return default_setup(EPPP_CLIENT);
return default_setup(EPPP_CLIENT, config);
}

esp_netif_t *eppp_listen(void)
esp_netif_t *eppp_listen(eppp_config_t *config)
{
return default_setup(EPPP_SERVER);
return default_setup(EPPP_SERVER, config);
}
27 changes: 25 additions & 2 deletions components/eppp_link/include/eppp_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@
* SPDX-License-Identifier: Apache-2.0
*/

esp_netif_t *eppp_connect(void);
typedef struct eppp_config_t {
struct eppp_config_uart_s {
int port;
int baud;
int tx_io;
int rx_io;
int queue_size;
int rx_buffer_size;
} uart;

esp_netif_t *eppp_listen(void);
struct eppp_config_task_s {
bool run_task;
int stack_size;
int priority;
} task;

struct eppp_config_pppos_s {
uint32_t our_ip4_addr;
uint32_t their_ip4_addr;
} ppp;

} eppp_config_t;

esp_netif_t *eppp_connect(eppp_config_t *config);

esp_netif_t *eppp_listen(eppp_config_t *config);
8 changes: 8 additions & 0 deletions components/eppp_link/test/test_app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# The following four 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)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/iperf)


include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_app)
37 changes: 37 additions & 0 deletions components/eppp_link/test/test_app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

# Test application running both server and client on the same device

Need to connect client's Tx to server's Rx and vice versa:
GPIO25 - GPIO4
GPIO26 - GPIO5

We wait for the connection and then we start pinging the client's address on server's netif.

## Example of output:

```
I (393) eppp_test_app: [APP] Startup..
I (393) eppp_test_app: [APP] Free memory: 296332 bytes
I (393) eppp_test_app: [APP] IDF version: v5.3-dev-1154-gf14d9e7431-dirty
I (423) uart: ESP_INTR_FLAG_IRAM flag not set while CONFIG_UART_ISR_IN_IRAM is enabled, flag updated
I (423) uart: queue free spaces: 16
I (433) eppp_link: Waiting for IP address
I (433) uart: ESP_INTR_FLAG_IRAM flag not set while CONFIG_UART_ISR_IN_IRAM is enabled, flag updated
I (443) uart: queue free spaces: 16
I (443) eppp_link: Waiting for IP address
I (6473) esp-netif_lwip-ppp: Connected
I (6513) eppp_link: Got IPv4 event: Interface "pppos_client" address: 192.168.11.2
I (6523) esp-netif_lwip-ppp: Connected
I (6513) eppp_link: Connected!
I (6523) eppp_link: Got IPv4 event: Interface "pppos_server" address: 192.168.11.1
I (6553) main_task: Returned from app_main()
64bytes from 192.168.11.2 icmp_seq=1 ttl=255 time=18 ms
64bytes from 192.168.11.2 icmp_seq=2 ttl=255 time=19 ms
64bytes from 192.168.11.2 icmp_seq=3 ttl=255 time=19 ms
64bytes from 192.168.11.2 icmp_seq=4 ttl=255 time=20 ms
64bytes from 192.168.11.2 icmp_seq=5 ttl=255 time=19 ms
64bytes from 192.168.11.2 icmp_seq=6 ttl=255 time=19 ms
64bytes from 192.168.11.2 icmp_seq=7 ttl=255 time=19 ms
From 192.168.11.2 icmp_seq=8 timeout // <-- Disconnected Tx-Rx wires
From 192.168.11.2 icmp_seq=9 timeout
```
2 changes: 2 additions & 0 deletions components/eppp_link/test/test_app/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
idf_component_register(SRCS app_main.c
INCLUDE_DIRS ".")
140 changes: 140 additions & 0 deletions components/eppp_link/test/test_app/main/app_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "eppp_link.h"
#include "lwip/sockets.h"
#include "esp_log.h"
#include "ping/ping_sock.h"
#include "driver/uart.h"

static const char *TAG = "eppp_test_app";

static void test_on_ping_success(esp_ping_handle_t hdl, void *args)
{
uint8_t ttl;
uint16_t seqno;
uint32_t elapsed_time, recv_len;
ip_addr_t target_addr;
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
esp_ping_get_profile(hdl, ESP_PING_PROF_TTL, &ttl, sizeof(ttl));
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len));
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
printf("%" PRId32 "bytes from %s icmp_seq=%d ttl=%d time=%" PRId32 " ms\n",
recv_len, inet_ntoa(target_addr.u_addr.ip4), seqno, ttl, elapsed_time);
}

static void test_on_ping_timeout(esp_ping_handle_t hdl, void *args)
{
uint16_t seqno;
ip_addr_t target_addr;
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
printf("From %s icmp_seq=%d timeout\n", inet_ntoa(target_addr.u_addr.ip4), seqno);
}

static void test_on_ping_end(esp_ping_handle_t hdl, void *args)
{
uint32_t transmitted;
uint32_t received;
uint32_t total_time_ms;
esp_ping_get_profile(hdl, ESP_PING_PROF_REQUEST, &transmitted, sizeof(transmitted));
esp_ping_get_profile(hdl, ESP_PING_PROF_REPLY, &received, sizeof(received));
esp_ping_get_profile(hdl, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms));
printf("%" PRId32 " packets transmitted, %" PRId32 " received, time %" PRId32 "ms\n", transmitted, received, total_time_ms);

}

static void client_task(void *ctx)
{
eppp_config_t *client_config = ctx;
esp_netif_t *eppp_client = eppp_connect(client_config);

if (eppp_client == NULL) {
ESP_LOGE(TAG, "Failed to connect");
}

vTaskDelete(NULL);
}

void app_main(void)
{
ESP_LOGI(TAG, "[APP] Startup..");
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());


ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());

/* Sets up the default EPPP-connection
*/
uint32_t server_ip = ESP_IP4TOADDR(192, 168, 11, 1);
uint32_t client_ip = ESP_IP4TOADDR(192, 168, 11, 2);
eppp_config_t server_config = {
.uart = {
.port = UART_NUM_1,
.baud = 921600,
.tx_io = 25,
.rx_io = 26,
.queue_size = 16,
.rx_buffer_size = 1024,
},
. task = {
.run_task = true,
.stack_size = 4096,
.priority = 18,
},
. ppp = {
.our_ip4_addr = server_ip,
.their_ip4_addr = client_ip,
}
};
eppp_config_t client_config = {};
memcpy(&client_config, &server_config, sizeof(server_config));
client_config.uart.port = UART_NUM_2;
client_config.uart.tx_io = 4;
client_config.uart.rx_io = 5;
client_config.ppp.our_ip4_addr = client_ip;
client_config.ppp.their_ip4_addr = server_ip;
xTaskCreate(client_task, "client_task", 4096, &client_config, 5, NULL);

esp_netif_t *eppp_server = eppp_listen(&server_config);
if (eppp_server == NULL) {
ESP_LOGE(TAG, "Failed to setup connection");
return ;
}

// Try to ping client's IP on server interface, so the packets go over the wires
// (if we didn't set the interface, ping would run locally on the client's netif)
ip_addr_t target_addr = { .type = IPADDR_TYPE_V4, .u_addr.ip4.addr = client_ip };

esp_ping_config_t ping_config = ESP_PING_DEFAULT_CONFIG();
ping_config.timeout_ms = 2000;
ping_config.interval_ms = 1000,
ping_config.target_addr = target_addr;
ping_config.count = 100;
ping_config.interface = esp_netif_get_netif_impl_index(eppp_server);
/* set callback functions */
esp_ping_callbacks_t cbs;
cbs.on_ping_success = test_on_ping_success;
cbs.on_ping_timeout = test_on_ping_timeout;
cbs.on_ping_end = test_on_ping_end;
esp_ping_handle_t ping;
esp_ping_new_session(&ping_config, &cbs, &ping);
/* start ping */
esp_ping_start(ping);

}
4 changes: 4 additions & 0 deletions components/eppp_link/test/test_app/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies:
espressif/eppp_link:
version: "*"
override_path: "../../.."
1 change: 1 addition & 0 deletions components/eppp_link/test/test_app/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_LWIP_PPP_SUPPORT=y

0 comments on commit ad2507e

Please sign in to comment.