Skip to content

Commit

Permalink
feat(eppp): Add support for transport via Ethernet link
Browse files Browse the repository at this point in the history
  • Loading branch information
david-cermak committed Jul 25, 2024
1 parent 5964ead commit 776e40c
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 10 deletions.
17 changes: 15 additions & 2 deletions components/eppp_link/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
idf_component_register(SRCS eppp_link.c eppp_sdio_slave.c eppp_sdio_host.c
if(CONFIG_EPPP_LINK_DEVICE_ETH)
set(transport_src eppp_eth.c)
endif()

if(CONFIG_EPPP_LINK_DEVICE_SDIO)
set(transport_src eppp_sdio_slave.c eppp_sdio_host.c)
endif()

idf_component_register(SRCS eppp_link.c ${transport_src}
INCLUDE_DIRS "include"
PRIV_REQUIRES esp_netif esp_driver_spi esp_driver_gpio esp_timer driver)
PRIV_REQUIRES esp_netif esp_driver_spi esp_driver_gpio esp_timer driver esp_eth)

if(CONFIG_EPPP_LINK_DEVICE_ETH)
idf_component_get_property(ethernet_init espressif__ethernet_init COMPONENT_LIB)
target_link_libraries(${COMPONENT_LIB} PRIVATE ${ethernet_init})
endif()
20 changes: 20 additions & 0 deletions components/eppp_link/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ menu "eppp_link"
help
Use SDIO.

config EPPP_LINK_DEVICE_ETH
bool "Ethernet"
depends on SOC_EMAC_SUPPORTED
help
Use Ethernet.
This transport could employ a full fledged Ethernet connection
between two EPPP nodes via standard Ethernet cable.
It could be also effectively connected directly on PCB, EMAC to EMAC,
without any Ethernet PHY chips (using eth_dummy_phy driver).

endchoice

config EPPP_LINK_CONN_MAX_RETRY
Expand Down Expand Up @@ -67,4 +77,14 @@ menu "eppp_link"

endchoice

config EPPP_LINK_ETHERNET_OUR_ADDRESS
string "MAC address our local node"
default "06:00:00:00:00:01"
depends on EPPP_LINK_DEVICE_ETH

config EPPP_LINK_ETHERNET_THEIR_ADDRESS
string "MAC address the remote node"
default "06:00:00:00:00:02"
depends on EPPP_LINK_DEVICE_ETH

endmenu
18 changes: 12 additions & 6 deletions components/eppp_link/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ We usually call this node a SLAVE microcontroller. The "HOST" microcontroller ru
brings in the WiFi connectivity from the "SLAVE" microcontroller.

```
SLAVE micro HOST micro
\|/ +----------------+ +----------------+
| | | serial line | |
+---+ WiFi NAT PPPoS |=== UART / SPI / SDIO =====| PPPoS client |
| (server)| | |
+----------------+ +----------------+
SLAVE micro HOST micro
\|/ +----------------+ +----------------+
| | | (serial) line | |
+---+ WiFi NAT PPPoS |=== UART / SPI / SDIO / ETH ===| PPPoS client |
| (server)| | |
+----------------+ +----------------+
```

## API
Expand Down Expand Up @@ -55,3 +55,9 @@ Tested with WiFi-NAPT example

* TCP - 9Mbits/s
* UDP - 11Mbits/s

### Ethernet

- Internal EMAC with real PHY chip
* TCP - 5Mbits/s
* UDP - 8Mbits/s
109 changes: 109 additions & 0 deletions components/eppp_link/eppp_eth.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_check.h"
#include "esp_event.h"
#include "esp_mac.h"
#include "eppp_link.h"
#include "eppp_transport.h"
#include "esp_eth_driver.h"
#include "ethernet_init.h"
#include "esp_eth_spec.h"

typedef struct header {
uint8_t dst[ETH_ADDR_LEN];
uint8_t src[ETH_ADDR_LEN];
uint16_t len;
} __attribute__((packed)) header_t;

static const char *TAG = "eppp_ethernet";
static bool s_is_connected = false;
static esp_eth_handle_t *s_eth_handles = NULL;
static uint8_t s_out_buffer[ETH_MAX_PACKET_SIZE];
static uint8_t s_their_mac[ETH_ADDR_LEN];
static uint8_t s_our_mac[ETH_ADDR_LEN];

static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
ESP_LOGI(TAG, "Ethernet Link Up");
s_is_connected = true;
break;
case ETHERNET_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "Ethernet Link Down");
s_is_connected = false;
break;
case ETHERNET_EVENT_START:
ESP_LOGI(TAG, "Ethernet Started");
break;
case ETHERNET_EVENT_STOP:
ESP_LOGI(TAG, "Ethernet Stopped");
break;
default:
break;
}
}

static esp_err_t receive(esp_eth_handle_t h, uint8_t *buffer, uint32_t len, void *netif)
{
header_t *head = (header_t *)buffer;
size_t packet_len = head->len;
if (len >= packet_len) {
esp_err_t ret = esp_netif_receive(netif, buffer + ETH_HEADER_LEN, packet_len, NULL);
free(buffer);
return ret;
}
return ESP_FAIL;
}

esp_err_t eppp_transport_init(eppp_config_t *config, esp_netif_t *esp_netif)
{
uint8_t eth_port_cnt = 0;
ESP_ERROR_CHECK(ethernet_init_all(&s_eth_handles, &eth_port_cnt));
if (eth_port_cnt > 1) {
ESP_LOGW(TAG, "multiple Ethernet devices detected, the first initialized is to be used!");
}
ESP_ERROR_CHECK(esp_eth_update_input_path(s_eth_handles[0], receive, esp_netif));
sscanf(CONFIG_EPPP_LINK_ETHERNET_OUR_ADDRESS, "%2" PRIu8 ":%2" PRIu8 ":%2" PRIi8 ":%2" PRIu8 ":%2" PRIu8 ":%2" PRIu8,
&s_our_mac[0], &s_our_mac[1], &s_our_mac[2], &s_our_mac[3], &s_our_mac[4], &s_our_mac[5]);

sscanf(CONFIG_EPPP_LINK_ETHERNET_THEIR_ADDRESS, "%2" PRIu8 ":%2" PRIu8 ":%2" PRIi8 ":%2" PRIu8 ":%2" PRIu8 ":%2" PRIu8,
&s_their_mac[0], &s_their_mac[1], &s_their_mac[2], &s_their_mac[3], &s_their_mac[4], &s_their_mac[5]);
esp_eth_ioctl(s_eth_handles[0], ETH_CMD_S_MAC_ADDR, s_our_mac);
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
ESP_ERROR_CHECK(esp_eth_start(s_eth_handles[0]));
return ESP_OK;
}

void eppp_transport_deinit(void)
{
ethernet_deinit_all(s_eth_handles);
}

esp_err_t eppp_transport_tx(void *h, void *buffer, size_t len)
{
if (!s_is_connected) {
return ESP_OK;
}
// setup Ethernet header
header_t *head = (header_t *)s_out_buffer;
memcpy(head->dst, s_their_mac, ETH_ADDR_LEN);
memcpy(head->src, s_our_mac, ETH_ADDR_LEN);
head->len = len;
// handle frame size: ETH_MIN_PAYLOAD_LEN <= len <= ETH_MAX_PAYLOAD_LEN
size_t frame_payload_len = len < ETH_MIN_PAYLOAD_LEN ? ETH_MIN_PAYLOAD_LEN : len;
if (frame_payload_len > ETH_MAX_PAYLOAD_LEN) {
return ESP_FAIL;
}
memcpy(s_out_buffer + ETH_HEADER_LEN, buffer, len);
return esp_eth_transmit(s_eth_handles[0], s_out_buffer, frame_payload_len + ETH_HEADER_LEN);
}
26 changes: 24 additions & 2 deletions components/eppp_link/eppp_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "esp_event.h"
#include "esp_netif_ppp.h"
#include "eppp_link.h"
#include "esp_serial_slave_link/essl_sdio.h"
#include "eppp_transport.h"

#if CONFIG_EPPP_LINK_DEVICE_SPI
#include "driver/spi_master.h"
Expand All @@ -24,6 +24,12 @@
#include "driver/uart.h"
#endif

#if CONFIG_EPPP_LINK_DEVICE_ETH
#define EPPP_NEEDS_TASK 0
#else
#define EPPP_NEEDS_TASK 1
#endif

static const int GOT_IPV4 = BIT0;
static const int CONNECTION_FAILED = BIT1;
#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED)
Expand Down Expand Up @@ -98,6 +104,8 @@ esp_err_t eppp_sdio_host_init(struct eppp_config_sdio_s *config);
esp_err_t eppp_sdio_slave_init(void);
void eppp_sdio_slave_deinit(void);
void eppp_sdio_host_deinit(void);
#elif CONFIG_EPPP_LINK_DEVICE_ETH

#else
static esp_err_t transmit(void *h, void *buffer, size_t len)
{
Expand Down Expand Up @@ -224,6 +232,8 @@ static esp_netif_t *netif_init(eppp_type_t role, eppp_config_t *eppp_config)
.handle = h,
#if CONFIG_EPPP_LINK_DEVICE_SDIO
.transmit = role == EPPP_CLIENT ? eppp_sdio_host_tx : eppp_sdio_slave_tx,
#elif CONFIG_EPPP_LINK_DEVICE_ETH
.transmit = eppp_transport_tx,
#else
.transmit = transmit,
#endif
Expand Down Expand Up @@ -691,6 +701,7 @@ esp_err_t eppp_perform(esp_netif_t *netif)

#endif // CONFIG_EPPP_LINK_DEVICE_SPI / UART

#if EPPP_NEEDS_TASK
static void ppp_task(void *args)
{
esp_netif_t *netif = args;
Expand All @@ -699,6 +710,7 @@ static void ppp_task(void *args)
h->exited = true;
vTaskDelete(NULL);
}
#endif

static bool have_some_eppp_netif(esp_netif_t *netif, void *ctx)
{
Expand Down Expand Up @@ -738,6 +750,8 @@ void eppp_deinit(esp_netif_t *netif)
} else {
eppp_sdio_slave_deinit();
}
#elif CONFIG_EPPP_LINK_DEVICE_ETH
eppp_transport_deinit();
#endif
netif_deinit(netif);
}
Expand Down Expand Up @@ -781,6 +795,13 @@ esp_netif_t *eppp_init(eppp_type_t role, eppp_config_t *config)
ESP_LOGE(TAG, "Failed to initialize SDIO %d", ret);
return NULL;
}
#elif CONFIG_EPPP_LINK_DEVICE_ETH
esp_err_t ret = eppp_transport_init(config, netif);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize SDIO %d", ret);
return NULL;
}

#endif
return netif;
}
Expand Down Expand Up @@ -834,12 +855,13 @@ esp_netif_t *eppp_open(eppp_type_t role, eppp_config_t *config, int connect_time
}

eppp_netif_start(netif);

#if EPPP_NEEDS_TASK
if (xTaskCreate(ppp_task, "ppp connect", config->task.stack_size, netif, config->task.priority, NULL) != pdTRUE) {
ESP_LOGE(TAG, "Failed to create a ppp connection task");
eppp_deinit(netif);
return NULL;
}
#endif
int netif_cnt = get_netif_num(netif);
if (netif_cnt < 0) {
eppp_close(netif);
Expand Down
14 changes: 14 additions & 0 deletions components/eppp_link/eppp_transport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once

esp_err_t eppp_transport_init(eppp_config_t *config, esp_netif_t *esp_netif);

esp_err_t eppp_transport_tx(void *h, void *buffer, size_t len);

esp_err_t eppp_transport_rx(esp_netif_t *netif);

void eppp_transport_deinit(void);
2 changes: 2 additions & 0 deletions components/eppp_link/examples/host/sdkconfig.ci.eth
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_EPPP_LINK_DEVICE_ETH=y
2 changes: 2 additions & 0 deletions components/eppp_link/examples/host/sdkconfig.ci.sdio
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32p4"
CONFIG_EPPP_LINK_DEVICE_SDIO=y
2 changes: 2 additions & 0 deletions components/eppp_link/examples/slave/sdkconfig.ci.eth
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_EPPP_LINK_DEVICE_ETH=y
2 changes: 2 additions & 0 deletions components/eppp_link/examples/slave/sdkconfig.ci.sdio
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32c6"
CONFIG_EPPP_LINK_DEVICE_SDIO=y
1 change: 1 addition & 0 deletions components/eppp_link/idf_component.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ description: The component provides a general purpose PPP connectivity, typicall
dependencies:
idf: '>=5.2'
espressif/esp_serial_slave_link: "^1.1.0"
espressif/ethernet_init: '>=0.0.7'

0 comments on commit 776e40c

Please sign in to comment.