mirror of
https://github.com/garagetinkering/Video_Game_Mini_Maps.git
synced 2026-01-17 17:47:00 +01:00
initial commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# 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)
|
||||
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(pppos_host)
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
# Client side demo of ESP-PPP-Link
|
||||
|
||||
This is a basic demo of using esp-mqtt library, but connects to the internet using a PPPoS client. To run this example, you would need a PPP server that provides connectivity to the MQTT broker used in this example (by default a public broker accessible on the internet).
|
||||
|
||||
If configured, this example could also run a ping session and an iperf console.
|
||||
|
||||
|
||||
The PPP server could be a Linux computer with `pppd` service or an ESP32 acting like a connection gateway with PPPoS server (see the "slave" project).
|
||||
@@ -0,0 +1,6 @@
|
||||
if(CONFIG_EXAMPLE_WIFI_OVER_EPPP_CHANNEL)
|
||||
set(wifi_over_channels channel_wifi_station.c)
|
||||
endif()
|
||||
idf_component_register(SRCS app_main.c register_iperf.c
|
||||
${wifi_over_channels}
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,119 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config EXAMPLE_GLOBAL_DNS
|
||||
hex "Set global DNS server"
|
||||
range 0 0xFFFFFFFF
|
||||
default 0x08080808
|
||||
help
|
||||
Global DNS server address.
|
||||
|
||||
config EXAMPLE_MQTT
|
||||
bool "Run mqtt example"
|
||||
default y
|
||||
help
|
||||
Run MQTT client after startup.
|
||||
|
||||
config EXAMPLE_BROKER_URL
|
||||
string "Broker URL"
|
||||
depends on EXAMPLE_MQTT
|
||||
default "mqtt://mqtt.eclipseprojects.io"
|
||||
help
|
||||
URL of the broker to connect to.
|
||||
|
||||
config EXAMPLE_IPERF
|
||||
bool "Run iperf"
|
||||
default y
|
||||
help
|
||||
Init and run iperf console.
|
||||
|
||||
config EXAMPLE_SPI_HOST
|
||||
int "SPI Host"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 1
|
||||
range 0 2
|
||||
help
|
||||
SPI host to use (SPI1_HOST=0, SPI2_HOST=1, SPI3_HOST=2).
|
||||
|
||||
config EXAMPLE_SPI_MOSI_PIN
|
||||
int "MOSI Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 23
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI MOSI.
|
||||
|
||||
config EXAMPLE_SPI_MISO_PIN
|
||||
int "MISO Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 19
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI MISO.
|
||||
|
||||
config EXAMPLE_SPI_SCLK_PIN
|
||||
int "SCLK Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 18
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI SCLK.
|
||||
|
||||
config EXAMPLE_SPI_CS_PIN
|
||||
int "CS Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 5
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI CS.
|
||||
|
||||
config EXAMPLE_SPI_INTR_PIN
|
||||
int "Interrupt Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 17
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI interrupt.
|
||||
|
||||
config EXAMPLE_SPI_FREQUENCY
|
||||
int "SPI Frequency (Hz)"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 4000000
|
||||
range 100000 80000000
|
||||
help
|
||||
SPI frequency in Hz.
|
||||
|
||||
config EXAMPLE_UART_TX_PIN
|
||||
int "TXD Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_UART
|
||||
default 17
|
||||
range 0 31
|
||||
help
|
||||
Pin number of UART TX.
|
||||
|
||||
config EXAMPLE_UART_RX_PIN
|
||||
int "RXD Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_UART
|
||||
default 18
|
||||
range 0 31
|
||||
help
|
||||
Pin number of UART RX.
|
||||
|
||||
config EXAMPLE_UART_BAUDRATE
|
||||
int "Baudrate"
|
||||
depends on EPPP_LINK_DEVICE_UART
|
||||
default 921600
|
||||
range 0 4000000
|
||||
help
|
||||
Baudrate used by the PPP over UART
|
||||
|
||||
config EXAMPLE_WIFI_OVER_EPPP_CHANNEL
|
||||
bool "Use WiFi over EPPP channel"
|
||||
default n
|
||||
depends on EPPP_LINK_CHANNELS_SUPPORT && ESP_WIFI_REMOTE_ENABLED
|
||||
help
|
||||
Enable this option to use WiFi over EPPP channel.
|
||||
If this option is enabled, the example will only start the Wi-Fi driver,
|
||||
but the Wi-Fi netif will reside on client's end and will channel
|
||||
the Rx and Tx data via EPPP channels.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 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 "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "console_ping.h"
|
||||
|
||||
void register_iperf(void);
|
||||
|
||||
static const char *TAG = "eppp_host_example";
|
||||
|
||||
#if CONFIG_EXAMPLE_MQTT
|
||||
static void mqtt_event_handler(void *args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mqtt_app_start(void)
|
||||
{
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = "mqtt://mqtt.eclipseprojects.io",
|
||||
};
|
||||
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
esp_mqtt_client_start(client);
|
||||
}
|
||||
#endif // MQTT
|
||||
|
||||
void station_over_eppp_channel(void *arg);
|
||||
|
||||
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
|
||||
*/
|
||||
eppp_config_t config = EPPP_DEFAULT_CLIENT_CONFIG();
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SPI
|
||||
config.transport = EPPP_TRANSPORT_SPI;
|
||||
config.spi.is_master = true;
|
||||
config.spi.host = CONFIG_EXAMPLE_SPI_HOST;
|
||||
config.spi.mosi = CONFIG_EXAMPLE_SPI_MOSI_PIN;
|
||||
config.spi.miso = CONFIG_EXAMPLE_SPI_MISO_PIN;
|
||||
config.spi.sclk = CONFIG_EXAMPLE_SPI_SCLK_PIN;
|
||||
config.spi.cs = CONFIG_EXAMPLE_SPI_CS_PIN;
|
||||
config.spi.intr = CONFIG_EXAMPLE_SPI_INTR_PIN;
|
||||
config.spi.freq = CONFIG_EXAMPLE_SPI_FREQUENCY;
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_UART
|
||||
config.transport = EPPP_TRANSPORT_UART;
|
||||
config.uart.tx_io = CONFIG_EXAMPLE_UART_TX_PIN;
|
||||
config.uart.rx_io = CONFIG_EXAMPLE_UART_RX_PIN;
|
||||
config.uart.baud = CONFIG_EXAMPLE_UART_BAUDRATE;
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_ETH
|
||||
config.transport = EPPP_TRANSPORT_ETHERNET;
|
||||
#else
|
||||
config.transport = EPPP_TRANSPORT_SDIO;
|
||||
config.sdio.is_host = true;
|
||||
#endif
|
||||
esp_netif_t *eppp_netif = eppp_connect(&config);
|
||||
if (eppp_netif == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to connect");
|
||||
return ;
|
||||
}
|
||||
// Setup global DNS
|
||||
esp_netif_dns_info_t dns;
|
||||
dns.ip.u_addr.ip4.addr = esp_netif_htonl(CONFIG_EXAMPLE_GLOBAL_DNS);
|
||||
dns.ip.type = ESP_IPADDR_TYPE_V4;
|
||||
ESP_ERROR_CHECK(esp_netif_set_dns_info(eppp_netif, ESP_NETIF_DNS_MAIN, &dns));
|
||||
|
||||
// Initialize console REPL
|
||||
ESP_ERROR_CHECK(console_cmd_init());
|
||||
|
||||
#if CONFIG_EXAMPLE_IPERF
|
||||
register_iperf();
|
||||
|
||||
printf("\n =======================================================\n");
|
||||
printf(" | Steps to Test EPPP-host bandwidth |\n");
|
||||
printf(" | |\n");
|
||||
printf(" | 1. Wait for the ESP32 to get an IP |\n");
|
||||
printf(" | 2. Server: 'iperf -u -s -i 3' (on host) |\n");
|
||||
printf(" | 3. Client: 'iperf -u -c SERVER_IP -t 60 -i 3' |\n");
|
||||
printf(" | |\n");
|
||||
printf(" =======================================================\n\n");
|
||||
|
||||
#endif // CONFIG_EXAMPLE_IPERF
|
||||
|
||||
// Register the ping command
|
||||
ESP_ERROR_CHECK(console_cmd_ping_register());
|
||||
// start console REPL
|
||||
ESP_ERROR_CHECK(console_cmd_start());
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_WIFI_OVER_EPPP_CHANNEL
|
||||
station_over_eppp_channel(eppp_netif);
|
||||
#endif
|
||||
#if CONFIG_EXAMPLE_MQTT
|
||||
mqtt_app_start();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 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 "esp_event.h"
|
||||
#include "esp_netif.h"
|
||||
#include "eppp_link.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_wifi_remote.h"
|
||||
|
||||
#define CHAT_CHANNEL 1
|
||||
#define WIFI_CHANNEL 2
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
HELLO,
|
||||
START,
|
||||
ERROR,
|
||||
} state_t;
|
||||
|
||||
typedef struct context {
|
||||
eppp_channel_fn_t transmit;
|
||||
EventGroupHandle_t flags;
|
||||
state_t state;
|
||||
esp_netif_t *eppp;
|
||||
} context_t;
|
||||
|
||||
#define HELLO_BIT BIT0
|
||||
#define START_BIT BIT1
|
||||
#define CONNECT_BIT BIT2
|
||||
#define SERVER_UP_BIT BIT3
|
||||
|
||||
#define ALL_BITS (HELLO_BIT | START_BIT | CONNECT_BIT | SERVER_UP_BIT)
|
||||
|
||||
static uint8_t s_wifi_mac_addr[6] = { 0 };
|
||||
static const char *TAG = "eppp_host_example_with_channels";
|
||||
|
||||
esp_netif_t* esp_wifi_remote_create_default_sta(void);
|
||||
|
||||
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "IP event_handler: event_base=%s event_id=%d", event_base, event_id);
|
||||
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
||||
ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_remote_get_mac(wifi_interface_t ifx, uint8_t mac[6])
|
||||
{
|
||||
if (ifx != WIFI_IF_STA) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
|
||||
}
|
||||
for (int i = 0; i < sizeof(s_wifi_mac_addr); i++) {
|
||||
if (s_wifi_mac_addr[i] == 0) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
memcpy(mac, s_wifi_mac_addr, sizeof(s_wifi_mac_addr));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t eppp_receive(esp_netif_t *netif, int nr, void *buffer, size_t len)
|
||||
{
|
||||
context_t *ctx = eppp_get_context(netif);
|
||||
if (nr == CHAT_CHANNEL) {
|
||||
ESP_LOGI(TAG, "Received channel=%d len=%d %.*s", nr, (int)len, (int)len, (char *)buffer);
|
||||
const char hello[] = "Hello client";
|
||||
const char mac[] = "MAC: ";
|
||||
const char connected[] = "Connected";
|
||||
const char server_up[] = "Server up";
|
||||
size_t mac_len = 5 /* MAC: */ + 6 * 2 /* 6 bytes per char */ + 5 /* : */ + 1 /* \0 */;
|
||||
if (len == sizeof(server_up) && memcmp(buffer, server_up, len) == 0) {
|
||||
if (ctx->state == UNKNOWN) {
|
||||
ESP_LOGI(TAG, "Server is up");
|
||||
ctx->state = HELLO;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Received server up in unexpected state %d", ctx->state);
|
||||
ctx->state = ERROR;
|
||||
}
|
||||
xEventGroupSetBits(ctx->flags, SERVER_UP_BIT);
|
||||
} else if (len == sizeof(hello) && memcmp(buffer, hello, len) == 0) {
|
||||
if (ctx->state == HELLO) {
|
||||
xEventGroupSetBits(ctx->flags, HELLO_BIT);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Received hello in unexpected state %d", ctx->state);
|
||||
ctx->state = ERROR;
|
||||
}
|
||||
} else if (len == mac_len && memcmp(buffer, mac, 5) == 0) {
|
||||
if (ctx->state == HELLO) {
|
||||
uint8_t mac_addr[6];
|
||||
sscanf((char *)buffer + 5, "%2" PRIx8 ":%2" PRIx8 ":%2" PRIx8 ":%2" PRIx8 ":%2" PRIx8 ":%2" PRIx8,
|
||||
&mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], &mac_addr[4], &mac_addr[5]);
|
||||
ESP_LOGI(TAG, "Parsed MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
memcpy(s_wifi_mac_addr, mac_addr, sizeof(s_wifi_mac_addr));
|
||||
xEventGroupSetBits(ctx->flags, START_BIT);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Received MAC in unexpected state %d", ctx->state);
|
||||
ctx->state = ERROR;
|
||||
}
|
||||
} else if (len == sizeof(connected) && memcmp(buffer, connected, len) == 0) {
|
||||
if (ctx->state == START) {
|
||||
xEventGroupSetBits(ctx->flags, CONNECT_BIT);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Received connected in unexpected state %d", ctx->state);
|
||||
ctx->state = ERROR;
|
||||
}
|
||||
}
|
||||
} else if (nr == WIFI_CHANNEL) {
|
||||
ESP_LOGD(TAG, "Received WIFI channel=%d len=%d", nr, (int)len);
|
||||
ESP_LOG_BUFFER_HEXDUMP("wifi-receive", buffer, len, ESP_LOG_VERBOSE);
|
||||
return esp_wifi_remote_channel_rx(ctx->eppp, buffer, NULL, len);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Incorrect channel number %d", nr);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t wifi_transmit(void *h, void *buffer, size_t len)
|
||||
{
|
||||
esp_netif_t *eppp = (esp_netif_t *)h;
|
||||
context_t *ctx = eppp_get_context(eppp);
|
||||
ESP_LOG_BUFFER_HEXDUMP("wifi-transmit", buffer, len, ESP_LOG_VERBOSE);
|
||||
return ctx->transmit(eppp, WIFI_CHANNEL, buffer, len);
|
||||
}
|
||||
|
||||
void esp_netif_destroy_wifi_remote(void *esp_netif);
|
||||
|
||||
void station_over_eppp_channel(void *arg)
|
||||
{
|
||||
__attribute__((unused)) esp_err_t ret;
|
||||
esp_netif_t *wifi = NULL;
|
||||
context_t ctx = {
|
||||
.transmit = NULL,
|
||||
.flags = NULL,
|
||||
.state = UNKNOWN,
|
||||
.eppp = (esp_netif_t *)arg
|
||||
};
|
||||
ESP_GOTO_ON_FALSE(ctx.eppp != NULL, ESP_FAIL, err, TAG, "Incorrect EPPP netif");
|
||||
ESP_GOTO_ON_FALSE(ctx.flags = xEventGroupCreate(), ESP_FAIL, err, TAG, "Failed to create event group");
|
||||
ESP_GOTO_ON_ERROR(eppp_add_channels(ctx.eppp, &ctx.transmit, eppp_receive, &ctx), err, TAG, "Failed to add channels");
|
||||
ESP_GOTO_ON_FALSE(ctx.transmit, ESP_FAIL, err, TAG, "Channel tx function is not set");
|
||||
ESP_GOTO_ON_ERROR(esp_wifi_remote_channel_set(WIFI_IF_STA, ctx.eppp, wifi_transmit), err, TAG, "Failed to set wifi channel tx function");
|
||||
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, &ctx);
|
||||
|
||||
while (1) {
|
||||
EventBits_t bits = xEventGroupWaitBits(ctx.flags, ALL_BITS, pdTRUE, pdFALSE, pdMS_TO_TICKS(1000));
|
||||
if (bits & HELLO_BIT) {
|
||||
ESP_LOGI(TAG, "Hello done");
|
||||
if (wifi == NULL) {
|
||||
wifi = esp_wifi_remote_create_default_sta();
|
||||
}
|
||||
const char command[] = "Get MAC";
|
||||
ctx.transmit(ctx.eppp, CHAT_CHANNEL, (void*)command, sizeof(command));
|
||||
} else if (bits & START_BIT) {
|
||||
ctx.state = START;
|
||||
ESP_LOGI(TAG, "Starting WIFI");
|
||||
esp_event_post(WIFI_REMOTE_EVENT, WIFI_EVENT_STA_START, NULL, 0, 0);
|
||||
} else if (bits & CONNECT_BIT) {
|
||||
ESP_LOGI(TAG, "WIFI connected");
|
||||
esp_event_post(WIFI_REMOTE_EVENT, WIFI_EVENT_STA_CONNECTED, NULL, 0, 0);
|
||||
} else if ((bits & SERVER_UP_BIT) == SERVER_UP_BIT || ctx.state != START) {
|
||||
if (ctx.state == ERROR) {
|
||||
esp_netif_destroy_wifi_remote(wifi);
|
||||
wifi = NULL;
|
||||
ESP_LOGI(TAG, "WiFi netif has been destroyed");
|
||||
}
|
||||
const char hello[] = "Hello server";
|
||||
ctx.transmit(ctx.eppp, CHAT_CHANNEL, (void*)hello, sizeof(hello));
|
||||
ctx.state = HELLO;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
dependencies:
|
||||
console_cmd_ping:
|
||||
version: '*'
|
||||
espressif/eppp_link:
|
||||
version: '*'
|
||||
espressif/iperf-cmd: ^0.1.1
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "sys/socket.h" // for INADDR_ANY
|
||||
#include "esp_netif.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_netif_ppp.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#include "esp_console.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_bit_defs.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "iperf.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* "iperf" command */
|
||||
|
||||
static struct {
|
||||
struct arg_str *ip;
|
||||
struct arg_lit *server;
|
||||
struct arg_lit *udp;
|
||||
struct arg_lit *version;
|
||||
struct arg_int *port;
|
||||
struct arg_int *length;
|
||||
struct arg_int *interval;
|
||||
struct arg_int *time;
|
||||
struct arg_int *bw_limit;
|
||||
struct arg_lit *abort;
|
||||
struct arg_end *end;
|
||||
} iperf_args;
|
||||
|
||||
static int ppp_cmd_iperf(int argc, char **argv)
|
||||
{
|
||||
int nerrors = arg_parse(argc, argv, (void **)&iperf_args);
|
||||
// ethernet iperf only support IPV4 address
|
||||
iperf_cfg_t cfg = {.type = IPERF_IP_TYPE_IPV4};
|
||||
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, iperf_args.end, argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* iperf -a */
|
||||
if (iperf_args.abort->count != 0) {
|
||||
iperf_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((iperf_args.ip->count == 0) && (iperf_args.server->count == 0)) ||
|
||||
((iperf_args.ip->count != 0) && (iperf_args.server->count != 0))) {
|
||||
ESP_LOGE(__func__, "Wrong mode! ESP32 should run in client or server mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* iperf -s */
|
||||
if (iperf_args.ip->count == 0) {
|
||||
cfg.flag |= IPERF_FLAG_SERVER;
|
||||
}
|
||||
/* iperf -c SERVER_ADDRESS */
|
||||
else {
|
||||
cfg.destination_ip4 = esp_ip4addr_aton(iperf_args.ip->sval[0]);
|
||||
cfg.flag |= IPERF_FLAG_CLIENT;
|
||||
}
|
||||
|
||||
if (iperf_args.length->count == 0) {
|
||||
cfg.len_send_buf = 0;
|
||||
} else {
|
||||
cfg.len_send_buf = iperf_args.length->ival[0];
|
||||
}
|
||||
|
||||
cfg.source_ip4 = INADDR_ANY;
|
||||
|
||||
/* iperf -u */
|
||||
if (iperf_args.udp->count == 0) {
|
||||
cfg.flag |= IPERF_FLAG_TCP;
|
||||
} else {
|
||||
cfg.flag |= IPERF_FLAG_UDP;
|
||||
}
|
||||
|
||||
/* iperf -p */
|
||||
if (iperf_args.port->count == 0) {
|
||||
cfg.sport = IPERF_DEFAULT_PORT;
|
||||
cfg.dport = IPERF_DEFAULT_PORT;
|
||||
} else {
|
||||
if (cfg.flag & IPERF_FLAG_SERVER) {
|
||||
cfg.sport = iperf_args.port->ival[0];
|
||||
cfg.dport = IPERF_DEFAULT_PORT;
|
||||
} else {
|
||||
cfg.sport = IPERF_DEFAULT_PORT;
|
||||
cfg.dport = iperf_args.port->ival[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* iperf -i */
|
||||
if (iperf_args.interval->count == 0) {
|
||||
cfg.interval = IPERF_DEFAULT_INTERVAL;
|
||||
} else {
|
||||
cfg.interval = iperf_args.interval->ival[0];
|
||||
if (cfg.interval <= 0) {
|
||||
cfg.interval = IPERF_DEFAULT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* iperf -t */
|
||||
if (iperf_args.time->count == 0) {
|
||||
cfg.time = IPERF_DEFAULT_TIME;
|
||||
} else {
|
||||
cfg.time = iperf_args.time->ival[0];
|
||||
if (cfg.time <= cfg.interval) {
|
||||
cfg.time = cfg.interval;
|
||||
}
|
||||
}
|
||||
|
||||
/* iperf -b */
|
||||
if (iperf_args.bw_limit->count == 0) {
|
||||
cfg.bw_lim = IPERF_DEFAULT_NO_BW_LIMIT;
|
||||
} else {
|
||||
cfg.bw_lim = iperf_args.bw_limit->ival[0];
|
||||
if (cfg.bw_lim <= 0) {
|
||||
cfg.bw_lim = IPERF_DEFAULT_NO_BW_LIMIT;
|
||||
}
|
||||
}
|
||||
|
||||
printf("mode=%s-%s sip=" IPSTR ":%" PRIu16 ", dip=%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 ":%" PRIu16 ", interval=%" PRIu32 ", time=%" PRIu32 "\r\n",
|
||||
cfg.flag & IPERF_FLAG_TCP ? "tcp" : "udp",
|
||||
cfg.flag & IPERF_FLAG_SERVER ? "server" : "client",
|
||||
(uint16_t) cfg.source_ip4 & 0xFF,
|
||||
(uint16_t) (cfg.source_ip4 >> 8) & 0xFF,
|
||||
(uint16_t) (cfg.source_ip4 >> 16) & 0xFF,
|
||||
(uint16_t) (cfg.source_ip4 >> 24) & 0xFF,
|
||||
cfg.sport,
|
||||
cfg.destination_ip4 & 0xFF, (cfg.destination_ip4 >> 8) & 0xFF,
|
||||
(cfg.destination_ip4 >> 16) & 0xFF, (cfg.destination_ip4 >> 24) & 0xFF, cfg.dport,
|
||||
cfg.interval, cfg.time);
|
||||
|
||||
iperf_start(&cfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void register_iperf(void)
|
||||
{
|
||||
|
||||
iperf_args.ip = arg_str0("c", "client", "<ip>",
|
||||
"run in client mode, connecting to <host>");
|
||||
iperf_args.server = arg_lit0("s", "server", "run in server mode");
|
||||
iperf_args.udp = arg_lit0("u", "udp", "use UDP rather than TCP");
|
||||
iperf_args.version = arg_lit0("V", "ipv6_domain", "use IPV6 address rather than IPV4");
|
||||
iperf_args.port = arg_int0("p", "port", "<port>",
|
||||
"server port to listen on/connect to");
|
||||
iperf_args.length = arg_int0("l", "len", "<length>", "set read/write buffer size");
|
||||
iperf_args.interval = arg_int0("i", "interval", "<interval>",
|
||||
"seconds between periodic bandwidth reports");
|
||||
iperf_args.time = arg_int0("t", "time", "<time>", "time in seconds to transmit for (default 10 secs)");
|
||||
iperf_args.bw_limit = arg_int0("b", "bandwidth", "<bandwidth>", "bandwidth to send at in Mbits/sec");
|
||||
iperf_args.abort = arg_lit0("a", "abort", "abort running iperf");
|
||||
iperf_args.end = arg_end(1);
|
||||
const esp_console_cmd_t iperf_cmd = {
|
||||
.command = "iperf",
|
||||
.help = "iperf command",
|
||||
.hint = NULL,
|
||||
.func = &ppp_cmd_iperf,
|
||||
.argtable = &iperf_args
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&iperf_cmd));
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_EPPP_LINK_DEVICE_SPI=y
|
||||
CONFIG_EPPP_LINK_CHANNELS_SUPPORT=y
|
||||
CONFIG_EPPP_LINK_USES_PPP=y
|
||||
@@ -0,0 +1,3 @@
|
||||
CONFIG_IDF_TARGET="esp32c3"
|
||||
CONFIG_EPPP_LINK_DEVICE_UART=y
|
||||
CONFIG_EPPP_LINK_CHANNELS_SUPPORT=y
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_EPPP_LINK_DEVICE_ETH=y
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32p4"
|
||||
CONFIG_EPPP_LINK_DEVICE_SDIO=y
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_EPPP_LINK_DEVICE_SPI=y
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_EPPP_LINK_DEVICE_UART=y
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following five 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)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(pppos_slave)
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
# Wi-Fi station to PPPoS server
|
||||
|
||||
This example demonstrate using NAPT to bring connectivity from WiFi station to PPPoS server.
|
||||
|
||||
This example expect a PPPoS client to connect to the server and use the connectivity.
|
||||
The client could be a Linux computer with `pppd` service or another microcontroller with PPP client (or another ESP32 with not WiFi interface)
|
||||
@@ -0,0 +1,6 @@
|
||||
if(CONFIG_EXAMPLE_WIFI_OVER_EPPP_CHANNEL)
|
||||
set(wifi_over_channels channel_wifi_station.c)
|
||||
endif()
|
||||
idf_component_register(SRCS eppp_slave.c
|
||||
${wifi_over_channels}
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,111 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config ESP_WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
help
|
||||
SSID (network name) for the example to connect to.
|
||||
|
||||
config ESP_WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "mypassword"
|
||||
help
|
||||
WiFi password (WPA or WPA2) for the example to use.
|
||||
|
||||
config ESP_MAXIMUM_RETRY
|
||||
int "Maximum retry"
|
||||
default 5
|
||||
help
|
||||
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
|
||||
|
||||
config EXAMPLE_SPI_HOST
|
||||
int "SPI Host"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 1
|
||||
range 0 2
|
||||
help
|
||||
SPI host to use (SPI1_HOST=0, SPI2_HOST=1, SPI3_HOST=2).
|
||||
|
||||
config EXAMPLE_SPI_MOSI_PIN
|
||||
int "MOSI Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 23
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI MOSI.
|
||||
|
||||
config EXAMPLE_SPI_MISO_PIN
|
||||
int "MISO Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 19
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI MISO.
|
||||
|
||||
config EXAMPLE_SPI_SCLK_PIN
|
||||
int "SCLK Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 18
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI SCLK.
|
||||
|
||||
config EXAMPLE_SPI_CS_PIN
|
||||
int "CS Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 5
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI CS.
|
||||
|
||||
config EXAMPLE_SPI_INTR_PIN
|
||||
int "Interrupt Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 17
|
||||
range 0 39
|
||||
help
|
||||
Pin number of SPI interrupt.
|
||||
|
||||
config EXAMPLE_SPI_FREQUENCY
|
||||
int "SPI Frequency (Hz)"
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
default 1000000
|
||||
range 100000 80000000
|
||||
help
|
||||
SPI frequency in Hz.
|
||||
|
||||
config EXAMPLE_UART_TX_PIN
|
||||
int "TXD Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_UART
|
||||
default 18
|
||||
range 0 31
|
||||
help
|
||||
Pin number of UART TX.
|
||||
|
||||
config EXAMPLE_UART_RX_PIN
|
||||
int "RXD Pin Number"
|
||||
depends on EPPP_LINK_DEVICE_UART
|
||||
default 17
|
||||
range 0 31
|
||||
help
|
||||
Pin number of UART RX.
|
||||
|
||||
config EXAMPLE_UART_BAUDRATE
|
||||
int "Baudrate"
|
||||
depends on EPPP_LINK_DEVICE_UART
|
||||
default 921600
|
||||
range 0 4000000
|
||||
help
|
||||
Baudrate used by the PPP over UART
|
||||
|
||||
config EXAMPLE_WIFI_OVER_EPPP_CHANNEL
|
||||
bool "Use WiFi over EPPP channel"
|
||||
default n
|
||||
depends on EPPP_LINK_CHANNELS_SUPPORT
|
||||
help
|
||||
Enable this option to use WiFi over EPPP channel.
|
||||
If this option is enabled, the example will only start the Wi-Fi driver,
|
||||
but the Wi-Fi netif will reside on client's end and will channel
|
||||
the Rx and Tx data via EPPP channels.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 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 "esp_event.h"
|
||||
#include "esp_netif.h"
|
||||
#include "eppp_link.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_private/wifi.h"
|
||||
|
||||
#define CHAT_CHANNEL 1
|
||||
#define WIFI_CHANNEL 2
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
HELLO,
|
||||
START,
|
||||
ERROR,
|
||||
} state_t;
|
||||
|
||||
typedef struct context {
|
||||
eppp_channel_fn_t transmit;
|
||||
EventGroupHandle_t flags;
|
||||
state_t state;
|
||||
esp_netif_t *eppp;
|
||||
} context_t;
|
||||
|
||||
#define HELLO_BIT BIT0
|
||||
#define START_BIT BIT1
|
||||
#define CONNECT_BIT BIT2
|
||||
#define DISCONNECT_BIT BIT3
|
||||
|
||||
#define ALL_BITS (HELLO_BIT | START_BIT | CONNECT_BIT | DISCONNECT_BIT)
|
||||
|
||||
static const char *TAG = "eppp_host_example_with_channels";
|
||||
static context_t *s_eppp_channel_ctx = NULL;
|
||||
|
||||
static esp_err_t eppp_receive(esp_netif_t *netif, int nr, void *buffer, size_t len)
|
||||
{
|
||||
context_t *ctx = eppp_get_context(netif);
|
||||
if (nr == CHAT_CHANNEL) {
|
||||
ESP_LOGI(TAG, "Received channel=%d len=%d %.*s", nr, (int)len, (int)len, (char *)buffer);
|
||||
const char hello[] = "Hello server";
|
||||
const char mac[] = "Get MAC";
|
||||
if (len == sizeof(hello) && memcmp(buffer, hello, len) == 0) {
|
||||
if (ctx->state == HELLO) {
|
||||
xEventGroupSetBits(ctx->flags, HELLO_BIT);
|
||||
} else {
|
||||
ctx->state = ERROR;
|
||||
}
|
||||
} else if (len == sizeof(mac) && memcmp(buffer, mac, 5) == 0) {
|
||||
if (ctx->state == HELLO) {
|
||||
xEventGroupSetBits(ctx->flags, START_BIT);
|
||||
} else {
|
||||
ctx->state = ERROR;
|
||||
}
|
||||
}
|
||||
} else if (nr == WIFI_CHANNEL) {
|
||||
ESP_LOGD(TAG, "Received WIFI channel=%d len=%d", nr, (int)len);
|
||||
ESP_LOG_BUFFER_HEXDUMP("wifi-receive", buffer, len, ESP_LOG_VERBOSE);
|
||||
return esp_wifi_internal_tx(WIFI_IF_STA, buffer, len);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Incorrect channel number %d", nr);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t wifi_receive(void *buffer, uint16_t len, void *eb)
|
||||
{
|
||||
s_eppp_channel_ctx->transmit(s_eppp_channel_ctx->eppp, WIFI_CHANNEL, buffer, len);
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
context_t *ctx = arg;
|
||||
ESP_LOGI(TAG, "event_handler: event_base=%s event_id=%d", event_base, event_id);
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
ESP_LOGI(TAG, "WIFI start event");
|
||||
esp_wifi_connect();
|
||||
xEventGroupSetBits(ctx->flags, CONNECT_BIT);
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
ESP_LOGI(TAG, "connect to the AP fail");
|
||||
xEventGroupSetBits(ctx->flags, DISCONNECT_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void init_wifi_driver(context_t *ctx)
|
||||
{
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID,
|
||||
event_handler, ctx));
|
||||
wifi_config_t wifi_config = {
|
||||
.sta = {
|
||||
.ssid = CONFIG_ESP_WIFI_SSID,
|
||||
.password = CONFIG_ESP_WIFI_PASSWORD,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
}
|
||||
|
||||
void station_over_eppp_channel(void *arg)
|
||||
{
|
||||
__attribute__((unused)) esp_err_t ret;
|
||||
context_t ctx = {
|
||||
.transmit = NULL,
|
||||
.flags = NULL,
|
||||
.state = UNKNOWN,
|
||||
.eppp = (esp_netif_t *)arg
|
||||
};
|
||||
ESP_GOTO_ON_FALSE(ctx.flags = xEventGroupCreate(), ESP_FAIL, err, TAG, "Failed to create event group");
|
||||
ESP_GOTO_ON_ERROR(eppp_add_channels(ctx.eppp, &ctx.transmit, eppp_receive, &ctx), err, TAG, "Failed to add channels");
|
||||
ESP_GOTO_ON_FALSE(ctx.transmit, ESP_FAIL, err, TAG, "Channel tx function is not set");
|
||||
init_wifi_driver(&ctx);
|
||||
|
||||
while (1) {
|
||||
EventBits_t bits = xEventGroupWaitBits(ctx.flags, ALL_BITS, pdTRUE, pdFALSE, pdMS_TO_TICKS(1000));
|
||||
if (bits & HELLO_BIT) {
|
||||
ESP_LOGI(TAG, "Hello from client received");
|
||||
const char hello[] = "Hello client";
|
||||
ctx.transmit(ctx.eppp, CHAT_CHANNEL, (void*)hello, sizeof(hello));
|
||||
} else if (bits & START_BIT) {
|
||||
ctx.state = START;
|
||||
ESP_LOGI(TAG, "Starting WIFI");
|
||||
uint8_t mac[6];
|
||||
if (esp_wifi_get_mac(WIFI_IF_STA, mac) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_wifi_get_mac failed");
|
||||
ctx.state = ERROR;
|
||||
continue;
|
||||
}
|
||||
char mac_data[5 /* MAC: */ + 6 * 2 /* 6 bytes per char */ + 5 /* : */ + 1 /* \0 */];
|
||||
sprintf(mac_data, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
ESP_LOGI(TAG, "Sending MAC: %.*s", (int)sizeof(mac_data), mac_data);
|
||||
ctx.transmit(ctx.eppp, CHAT_CHANNEL, (void*)mac_data, sizeof(mac_data));
|
||||
ret = esp_wifi_start();
|
||||
ESP_LOGI(TAG, "WIFI start result: %d", ret);
|
||||
s_eppp_channel_ctx = &ctx;
|
||||
esp_wifi_internal_reg_rxcb(WIFI_IF_STA, wifi_receive);
|
||||
} else if (bits & CONNECT_BIT) {
|
||||
ESP_LOGI(TAG, "WIFI connected");
|
||||
const char connected[] = "Connected";
|
||||
ctx.transmit(ctx.eppp, CHAT_CHANNEL, (void*)connected, sizeof(connected));
|
||||
} else if (bits & DISCONNECT_BIT) {
|
||||
const char disconnected[] = "Disconnected";
|
||||
ctx.transmit(ctx.eppp, CHAT_CHANNEL, (void*)disconnected, sizeof(disconnected));
|
||||
} else if (ctx.state != START) {
|
||||
ctx.state = HELLO;
|
||||
const char up[] = "Server up";
|
||||
esp_wifi_disconnect();
|
||||
esp_wifi_stop();
|
||||
ctx.transmit(ctx.eppp, CHAT_CHANNEL, (void*)up, sizeof(up));
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "eppp_link.h"
|
||||
#include "inttypes.h"
|
||||
|
||||
static const char *TAG = "eppp_slave";
|
||||
|
||||
#if defined(CONFIG_SOC_WIFI_SUPPORTED) && !defined(CONFIG_EXAMPLE_WIFI_OVER_EPPP_CHANNEL)
|
||||
|
||||
/* FreeRTOS event group to signal when we are connected*/
|
||||
static EventGroupHandle_t s_wifi_event_group;
|
||||
|
||||
/* The event group allows multiple bits for each event, but we only care about two events:
|
||||
* - we are connected to the AP with an IP
|
||||
* - we failed to connect after the maximum amount of retries */
|
||||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_FAIL_BIT BIT1
|
||||
|
||||
static int s_retry_num = 0;
|
||||
|
||||
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "event_handler: event_base=%s event_id=%" PRIi32, event_base, event_id);
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
ESP_LOGI(TAG, "WIFI start event");
|
||||
esp_wifi_connect();
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
if (s_retry_num < CONFIG_ESP_MAXIMUM_RETRY) {
|
||||
esp_wifi_connect();
|
||||
s_retry_num++;
|
||||
ESP_LOGI(TAG, "retry to connect to the AP");
|
||||
} else {
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
|
||||
}
|
||||
ESP_LOGI(TAG, "connect to the AP fail");
|
||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
||||
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
s_retry_num = 0;
|
||||
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void init_network_interface(void)
|
||||
{
|
||||
s_wifi_event_group = xEventGroupCreate();
|
||||
|
||||
esp_netif_create_default_wifi_sta();
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
|
||||
esp_event_handler_instance_t instance_any_id;
|
||||
esp_event_handler_instance_t instance_got_ip;
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
ESP_EVENT_ANY_ID,
|
||||
&event_handler,
|
||||
NULL,
|
||||
&instance_any_id));
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
|
||||
IP_EVENT_STA_GOT_IP,
|
||||
&event_handler,
|
||||
NULL,
|
||||
&instance_got_ip));
|
||||
|
||||
wifi_config_t wifi_config = {
|
||||
.sta = {
|
||||
.ssid = CONFIG_ESP_WIFI_SSID,
|
||||
.password = CONFIG_ESP_WIFI_PASSWORD,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
|
||||
ESP_LOGI(TAG, "wifi_init_sta finished.");
|
||||
|
||||
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
|
||||
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
|
||||
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
|
||||
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
portMAX_DELAY);
|
||||
|
||||
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
|
||||
* happened. */
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
|
||||
CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
|
||||
} else if (bits & WIFI_FAIL_BIT) {
|
||||
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
|
||||
CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "UNEXPECTED EVENT");
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
// If the SoC does not have WiFi capabilities, we can initialize a different network interface, this function is a placeholder for that purpose.
|
||||
// This function is also a no-op if EXAMPLE_WIFI_OVER_EPPP_CHANNEL==1, since the Wi-Fi network interface will live on the other peer (on the host side).
|
||||
void init_network_interface(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif // SoC WiFi capable chip || WiFi over EPPP channel
|
||||
|
||||
void station_over_eppp_channel(void *arg);
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
//Initialize NVS
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
init_network_interface(); // WiFi station if withing SoC capabilities (otherwise a placeholder)
|
||||
|
||||
eppp_config_t config = EPPP_DEFAULT_SERVER_CONFIG();
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SPI
|
||||
config.transport = EPPP_TRANSPORT_SPI;
|
||||
config.spi.is_master = false;
|
||||
config.spi.host = CONFIG_EXAMPLE_SPI_HOST;
|
||||
config.spi.mosi = CONFIG_EXAMPLE_SPI_MOSI_PIN;
|
||||
config.spi.miso = CONFIG_EXAMPLE_SPI_MISO_PIN;
|
||||
config.spi.sclk = CONFIG_EXAMPLE_SPI_SCLK_PIN;
|
||||
config.spi.cs = CONFIG_EXAMPLE_SPI_CS_PIN;
|
||||
config.spi.intr = CONFIG_EXAMPLE_SPI_INTR_PIN;
|
||||
config.spi.freq = CONFIG_EXAMPLE_SPI_FREQUENCY;
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_UART
|
||||
config.transport = EPPP_TRANSPORT_UART;
|
||||
config.uart.tx_io = CONFIG_EXAMPLE_UART_TX_PIN;
|
||||
config.uart.rx_io = CONFIG_EXAMPLE_UART_RX_PIN;
|
||||
config.uart.baud = CONFIG_EXAMPLE_UART_BAUDRATE;
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
config.transport = EPPP_TRANSPORT_SDIO;
|
||||
#endif // transport device
|
||||
|
||||
esp_netif_t *eppp_netif = eppp_listen(&config);
|
||||
if (eppp_netif == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to setup connection");
|
||||
return ;
|
||||
}
|
||||
#ifdef CONFIG_EXAMPLE_WIFI_OVER_EPPP_CHANNEL
|
||||
station_over_eppp_channel(eppp_netif);
|
||||
#else
|
||||
ESP_ERROR_CHECK(esp_netif_napt_enable(eppp_netif));
|
||||
#endif // CONFIG_EXAMPLE_WIFI_OVER_EPPP_CHANNEL
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/eppp_link:
|
||||
version: '*'
|
||||
@@ -0,0 +1,4 @@
|
||||
CONFIG_IDF_TARGET="esp32s2"
|
||||
CONFIG_EPPP_LINK_DEVICE_SPI=y
|
||||
CONFIG_EPPP_LINK_CHANNELS_SUPPORT=y
|
||||
CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n
|
||||
@@ -0,0 +1,4 @@
|
||||
CONFIG_IDF_TARGET="esp32c2"
|
||||
CONFIG_EPPP_LINK_DEVICE_UART=y
|
||||
CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n
|
||||
CONFIG_EPPP_LINK_USES_PPP=y
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_EPPP_LINK_DEVICE_ETH=y
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_LWIP_IPV6=n
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32c6"
|
||||
CONFIG_EPPP_LINK_DEVICE_SDIO=y
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_EPPP_LINK_DEVICE_SPI=y
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_EPPP_LINK_DEVICE_UART=y
|
||||
@@ -0,0 +1,3 @@
|
||||
CONFIG_LWIP_IP_FORWARD=y
|
||||
CONFIG_LWIP_IPV4_NAPT=y
|
||||
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
||||
Reference in New Issue
Block a user