lwip/linux: Add lwip support for networking component under linux

linux/lwip: Wrap some IO posix functions
* to workaourd the FreeRTOS EINTR issue (when building without lwip)
* to correctly choose the sub-system based on fd (when building with
lwip) -- passing control to either linux/system or to lwip
This commit also addapts tapio-if to provide DHCP client by default and
configurable settings for static IP
pull/11344/head
David Cermak 2023-04-03 20:31:51 +02:00 zatwierdzone przez David Čermák
rodzic 0bfffa0160
commit b2af4d9689
31 zmienionych plików z 277 dodań i 88 usunięć

Wyświetl plik

@ -282,8 +282,8 @@ test_sockets_on_host:
- grep "Socket unable to connect" test.log - grep "Socket unable to connect" test.log
# test the udp-client example with lwip sockets # test the udp-client example with lwip sockets
- cd ${IDF_PATH}/examples/protocols/sockets/udp_client - cd ${IDF_PATH}/examples/protocols/sockets/udp_client
- echo 'CONFIG_EXAMPLE_IPV4_ADDR="127.0.0.1"' >> sdkconfig.defaults
- idf.py --preview set-target linux - idf.py --preview set-target linux
- cat sdkconfig.ci.linux > sdkconfig
- idf.py build - idf.py build
- timeout 5 ./build/udp_client.elf >test.log || true - timeout 5 ./build/udp_client.elf >test.log || true
- grep "Message sent" test.log - grep "Message sent" test.log

Wyświetl plik

@ -32,8 +32,15 @@ if(NOT ${IDF_TARGET} STREQUAL "linux")
# due to cyclic dependencies present in IDF for lwip/esp_netif/mbedtls # due to cyclic dependencies present in IDF for lwip/esp_netif/mbedtls
idf_component_get_property(lwip lwip COMPONENT_LIB) idf_component_get_property(lwip lwip COMPONENT_LIB)
set_property(TARGET ${lwip} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 5) set_property(TARGET ${lwip} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 5)
else()
# Check if LWIP in the build for linux target to adapt esp-tls compatibility layer
idf_build_get_property(build_components BUILD_COMPONENTS)
if("lwip" IN_LIST build_components)
target_compile_definitions(${COMPONENT_LIB} PRIVATE ESP_TLS_WITH_LWIP=1)
endif()
endif() endif()
if(CONFIG_ESP_TLS_USE_SECURE_ELEMENT) if(CONFIG_ESP_TLS_USE_SECURE_ELEMENT)
idf_component_optional_requires(PRIVATE espressif__esp-cryptoauthlib esp-cryptoauthlib) idf_component_optional_requires(PRIVATE espressif__esp-cryptoauthlib esp-cryptoauthlib)
endif() endif()

Wyświetl plik

@ -17,9 +17,10 @@
#include "esp_tls.h" #include "esp_tls.h"
#include "esp_tls_private.h" #include "esp_tls_private.h"
#include "esp_tls_error_capture_internal.h" #include "esp_tls_error_capture_internal.h"
#include <fcntl.h>
#include <errno.h> #include <errno.h>
#if CONFIG_IDF_TARGET_LINUX #if CONFIG_IDF_TARGET_LINUX && !ESP_TLS_WITH_LWIP
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
@ -36,7 +37,7 @@ static inline char *ip6addr_ntoa(const ip6_addr_t *addr)
return (char *)inet_ntop(AF_INET6, addr->s6_addr, str, 40); return (char *)inet_ntop(AF_INET6, addr->s6_addr, str, 40);
} }
#endif #endif // CONFIG_IDF_TARGET_LINUX && !ESP_TLS_WITH_LWIP
static const char *TAG = "esp-tls"; static const char *TAG = "esp-tls";

Wyświetl plik

@ -1,7 +1,7 @@
if(NOT ${IDF_TARGET} STREQUAL "linux") if(NOT ${IDF_TARGET} STREQUAL "linux")
set(req lwip esp_event) set(req lwip esp_event)
else() else()
set(req linux) set(req linux esp_event)
endif() endif()
idf_component_register(SRCS "esp_http_client.c" idf_component_register(SRCS "esp_http_client.c"

Wyświetl plik

@ -1,14 +1,12 @@
set(priv_req mbedtls) set(priv_req mbedtls)
set(priv_inc_dir "src/util") set(priv_inc_dir "src/util")
set(requires http_parser) set(requires http_parser esp_event)
if(NOT ${IDF_TARGET} STREQUAL "linux") if(NOT ${IDF_TARGET} STREQUAL "linux")
list(APPEND priv_req lwip esp_timer) list(APPEND priv_req lwip esp_timer)
list(APPEND priv_inc_dir "src/port/esp32") list(APPEND priv_inc_dir "src/port/esp32")
list(APPEND requires esp_event)
else() else()
list(APPEND priv_inc_dir "src/port/linux") list(APPEND priv_inc_dir "src/port/linux")
list(APPEND priv_req pthread) list(APPEND priv_req pthread)
list(APPEND requires linux)
endif() endif()
idf_component_register(SRCS "src/httpd_main.c" idf_component_register(SRCS "src/httpd_main.c"

Wyświetl plik

@ -6,6 +6,7 @@
#include <string.h> #include <string.h>
#include "esp_chip_info.h" #include "esp_chip_info.h"
#include "esp_mac.h"
void esp_chip_info(esp_chip_info_t *out_info) void esp_chip_info(esp_chip_info_t *out_info)
{ {
@ -18,3 +19,15 @@ void esp_chip_info(esp_chip_info_t *out_info)
out_info->revision = 0; out_info->revision = 0;
out_info->cores = 1; out_info->cores = 1;
} }
esp_err_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
{
// Provide Locally Administered (OUI range) MAC address on POSIX/Linux
mac[0] = 0x02;
mac[1] = 0x12;
mac[2] = 0x34;
mac[3] = 0x56;
mac[4] = 0x78;
mac[5] = 0xab;
return ESP_OK;
}

Wyświetl plik

@ -60,6 +60,18 @@ if(${target} STREQUAL "linux")
if(NOT CONFIG_FREERTOS_SMP) if(NOT CONFIG_FREERTOS_SMP)
list(APPEND srcs "${kernel_dir}/portable/${arch}/port_idf.c") list(APPEND srcs "${kernel_dir}/portable/${arch}/port_idf.c")
endif() endif()
# Check if we need to address the FreeRTOS EINTR coexistence with linux system calls
# if we're building without lwIP, we need to use linux system select which will receive
# EINTR event on every FreeRTOS interrupt, we workaround this problem by wrapping select()
# to bypass and silence the EINTR events
set(BYPASS_EINTR_ISSUE 0)
idf_build_get_property(build_components BUILD_COMPONENTS)
if(NOT "lwip" IN_LIST build_components)
set(BYPASS_EINTR_ISSUE 1)
list(APPEND srcs esp_additions/arch/linux/FreeRTOSSimulator_wrappers.c)
endif()
else() else()
list(APPEND srcs list(APPEND srcs
"app_startup.c" "app_startup.c"
@ -99,6 +111,9 @@ idf_component_register(SRCS "${srcs}"
if(${target} STREQUAL "linux") if(${target} STREQUAL "linux")
target_compile_definitions(${COMPONENT_LIB} PUBLIC "projCOVERAGE_TEST=0") target_compile_definitions(${COMPONENT_LIB} PUBLIC "projCOVERAGE_TEST=0")
target_link_libraries(${COMPONENT_LIB} PUBLIC pthread) target_link_libraries(${COMPONENT_LIB} PUBLIC pthread)
if(BYPASS_EINTR_ISSUE)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=select")
endif()
else() else()
idf_component_get_property(COMPONENT_DIR freertos COMPONENT_DIR) idf_component_get_property(COMPONENT_DIR freertos COMPONENT_DIR)

Wyświetl plik

@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <pthread.h>
#include "esp_err.h"
#include "errno.h"
/** This module addresses the FreeRTOS simulator's coexistence with linux system calls from user apps.
* It's only included when building without lwIP, so we need to use linux system's select() which would receive
* EINTR event on every FreeRTOS interrupt; we workaround this problem by wrapping select()
* to bypass and silence these events.
*/
extern int __real_select (int fd, fd_set * rfds, fd_set * wfds, fd_set *efds, struct timeval *tval);
static inline int64_t get_us(void)
{
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
return spec.tv_nsec / 1000 + spec.tv_sec * 1000000;
}
int __wrap_select (int fd, fd_set * rfds, fd_set * wfds, fd_set *efds, struct timeval *tval)
{
int ret;
struct timeval *tv = tval;
int64_t start = 0;
int64_t timeout_us = 0;
if (tv != NULL) {
start = get_us();
timeout_us = tval->tv_sec * 1000000 + tval->tv_usec;
struct timeval timeval_local = { .tv_sec = tval->tv_sec, .tv_usec = tval->tv_usec };
tv = &timeval_local; // this (tv != NULL) indicates that we should handle timeouts
}
while ((ret = __real_select(fd, rfds, wfds, efds, tv)) < 0 && errno == EINTR) {
if (tv != NULL) {
int64_t now = get_us();
timeout_us -= now - start;
if (timeout_us < 0) {
errno = 0;
ret = 0;
break;
}
start = now;
tv->tv_usec = timeout_us % 1000000;
tv->tv_sec = timeout_us / 1000000;
}
}
return ret;
}

Wyświetl plik

@ -3,6 +3,5 @@ if(NOT "${target}" STREQUAL "linux")
return() return()
endif() endif()
idf_component_register(SRCS esp_event_stubs.c idf_component_register(INCLUDE_DIRS include
INCLUDE_DIRS include ${IDF_PATH}/components/esp_event/include
REQUIRED_IDF_TARGETS linux) REQUIRED_IDF_TARGETS linux)

Wyświetl plik

@ -1,18 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_err.h"
#include "esp_event.h"
esp_err_t esp_event_loop_create_default(void)
{
return ESP_OK;
}
esp_err_t esp_event_post(esp_event_base_t event_base, int32_t event_id,
const void* event_data, size_t event_data_size, TickType_t ticks_to_wait)
{
return ESP_OK;
}

Wyświetl plik

@ -9,7 +9,7 @@
extern "C" { extern "C" {
#endif #endif
#if CONFIG_IDF_TARGET_LINUX #if CONFIG_IDF_TARGET_LINUX && !defined(__containerof)
#define __containerof(ptr, type, member) ({ \ #define __containerof(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );}) (type *)( (char *)__mptr - offsetof(type,member) );})

Wyświetl plik

@ -13,6 +13,7 @@ set(include_dirs
port/freertos/include/ port/freertos/include/
port/${target}/include port/${target}/include
port/${target}/include/arch port/${target}/include/arch
port/${target}/include/sys
) )
set(srcs set(srcs
@ -142,6 +143,9 @@ if(NOT ${target} STREQUAL "linux")
else() else()
list(APPEND srcs "port/${target}/no_vfs_syscalls.c") list(APPEND srcs "port/${target}/no_vfs_syscalls.c")
endif() endif()
else()
# This wraps some posix IO functions to conditionally pass control to lwip
list(APPEND srcs "port/${target}/vfs_lwip.c")
endif() endif()
if(CONFIG_LWIP_ICMP) if(CONFIG_LWIP_ICMP)
@ -206,4 +210,13 @@ if(${target} STREQUAL "linux")
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
target_link_libraries(${COMPONENT_LIB} PRIVATE Threads::Threads) target_link_libraries(${COMPONENT_LIB} PRIVATE Threads::Threads)
set(WRAP_FUNCTIONS select
read
fcntl
write
close)
foreach(wrap ${WRAP_FUNCTIONS})
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __wrap_${wrap}")
endforeach()
endif() endif()

Wyświetl plik

@ -4,9 +4,13 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#pragma once #pragma once
#ifdef LWIP_HDR_ESP_LWIPOPTS_H #include "sdkconfig.h"
// ignore when included from lwipopts.h since lwip provides all necessary definitions
#else #ifdef LWIP_HDR_LINUX_SYS_SOCKETS_H
// otherwise include system fcntl // only if we prefer linux system sockets, include from system paths
#include_next <sys/fcntl.h> #include_next <fcntl.h>
#elif CONFIG_IDF_TARGET_LINUX
// need to declare, as on linux we bypass IDF vfs and wrap posix io functions
extern int fcntl(int s, int cmd, ...);
#endif #endif
// ignore otherwise (typically included from lwipopts.h) since lwip provides all necessary definitions

Wyświetl plik

@ -3,11 +3,11 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#ifndef LWIP_HDR_LINUX_SYS_SOCKETS_H #pragma once
#define LWIP_HDR_LINUX_SYS_SOCKETS_H #ifdef LWIP_HDR_LINUX_SYS_SOCKETS_H
/* only if we prefer linux system sockets, include from system paths */
#include_next <sys/socket.h>
#else
/* Include lwip sockets by default */ /* Include lwip sockets by default */
#include "lwip/sockets.h" #include "lwip/sockets.h"
#else
/* Otherwise use system sockets if LWIP_HDR_LINUX_SYS_SOCKETS_H already defined */
#include_next <sys/socket.h>
#endif /* LWIP_HDR_LINUX_SYS_SOCKETS_H */ #endif /* LWIP_HDR_LINUX_SYS_SOCKETS_H */

Wyświetl plik

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/socket.h>
#include <stdarg.h>
extern int __real_fcntl(int s, int cmd, ...);
extern int __real_close(int s);
extern ssize_t __real_write (int fd, const void *buf, size_t n);
extern ssize_t __real_read (int fd, void *buf, size_t n);
extern int __real_select (int fd, fd_set * rfds, fd_set * wfds, fd_set *efds, struct timeval *tval);
ssize_t __wrap_write (int fd, const void *buf, size_t n)
{
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET)
return lwip_write(fd, buf, n);
#endif
return __real_write(fd, buf, n);
}
ssize_t __wrap_read (int fd, void *buf, size_t n)
{
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET)
return lwip_read(fd, buf, n);
#endif
return __real_read(fd, buf, n);
}
int __wrap_select (int fd, fd_set * rds, fd_set * wfds, fd_set *efds, struct timeval *tval)
{
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET)
return lwip_select(fd, rds, wfds, efds, tval);
#endif
return __real_select(fd, rds, wfds, efds, tval);
}
int __wrap_fcntl(int fd, int cmd, ...)
{
va_list args;
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET) {
va_start(args, cmd);
int arg = va_arg(args, int);
va_end(args);
return lwip_fcntl(fd, cmd, arg);
}
#endif
return __real_fcntl(fd, cmd, args);
}
int __wrap_close(int fd)
{
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET)
return lwip_close(fd);
#endif
return __real_close(fd);
}

Wyświetl plik

@ -22,3 +22,13 @@ idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "include" INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include" PRIV_INCLUDE_DIRS "private_include"
REQUIRES ${req}) REQUIRES ${req})
if(${IDF_TARGET} STREQUAL "linux")
# Check if LWIP in the build for linux target to add esp_timer to the dependencies
# since socks_proxy transport needs it and lwip & linux build could use it
idf_build_get_property(build_components BUILD_COMPONENTS)
if("lwip" IN_LIST build_components)
idf_component_get_property(esp_timer esp_timer COMPONENT_LIB)
target_link_libraries(${COMPONENT_LIB} PUBLIC ${esp_timer})
endif()
endif()

Wyświetl plik

@ -3,7 +3,7 @@ menu "Example Connection Configuration"
config EXAMPLE_CONNECT_LWIP_TAPIF config EXAMPLE_CONNECT_LWIP_TAPIF
bool "connect using lwip to linux tap interface" bool "connect using lwip to linux tap interface"
depends on IDF_TARGET_LINUX && ESP_NETIF_TCPIP_LWIP depends on IDF_TARGET_LINUX && ESP_NETIF_TCPIP_LWIP
default n default y
if EXAMPLE_CONNECT_LWIP_TAPIF if EXAMPLE_CONNECT_LWIP_TAPIF
config EXAMPLE_CONNECT_IPV4 config EXAMPLE_CONNECT_IPV4
@ -18,24 +18,28 @@ menu "Example Connection Configuration"
help help
Set to true to setup link local address and wait until it's valid Set to true to setup link local address and wait until it's valid
config EXAMPLE_CONNECT_WAIT_FOR_IP
bool "run DHCP and wait for IP"
default y
config EXAMPLE_CONNECT_TAPIF_IP_ADDR config EXAMPLE_CONNECT_TAPIF_IP_ADDR
string "Static IP address" string "Static IP address"
default "192.168.5.100" default "192.168.5.100"
depends on EXAMPLE_CONNECT_IPV4 depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help help
Set static IP address. Set static IP address.
config EXAMPLE_CONNECT_TAPIF_NETMASK config EXAMPLE_CONNECT_TAPIF_NETMASK
string "Static netmask address" string "Static netmask address"
default "255.255.255.0" default "255.255.255.0"
depends on EXAMPLE_CONNECT_IPV4 depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help help
Set static netmask address. Set static netmask address.
config EXAMPLE_CONNECT_TAPIF_GW config EXAMPLE_CONNECT_TAPIF_GW
string "Static gateway address" string "Static gateway address"
default "192.168.5.1" default "192.168.5.1"
depends on EXAMPLE_CONNECT_IPV4 depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help help
Set static gateway address. Set static gateway address.

Wyświetl plik

@ -110,6 +110,8 @@ sudo iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT
It's also possible to configure the lwip interface to use DHCP client (common setup for most default network interfaces, such as Ethernet or WiFi station) It's also possible to configure the lwip interface to use DHCP client (common setup for most default network interfaces, such as Ethernet or WiFi station)
and set up a DHCP server on the host machine to assign the IP address dynamically. and set up a DHCP server on the host machine to assign the IP address dynamically.
This component sets up a DHCP client if `CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP` is enabled and waits for assigning an IP address. See below the description of DHCP client workflow for tap interface:
1) **Configure and set the `esp-netif` up** 1) **Configure and set the `esp-netif` up**
* Same as in [API usage](#Usage-of-the-API), but update the base esp-netif config `3c)` to enable DHCP client * Same as in [API usage](#Usage-of-the-API), but update the base esp-netif config `3c)` to enable DHCP client
@ -125,14 +127,17 @@ and set up a DHCP server on the host machine to assign the IP address dynamicall
esp_netif_action_connected(tap_netif, 0, 0, 0); esp_netif_action_connected(tap_netif, 0, 0, 0);
``` ```
* Wait for the IP address to be assigned. * Wait for the IP address to be assigned.
This could be implemented as a wait loop below, as the esp-event currently doesn't support IP events on Linux target. This could be implemented using an event handler
```cpp ```cpp
esp_netif_inherent_config_t base_cfg = {
...
.get_ip_event = TAP0_GOT_IP,
...
};
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, TAP0_GOT_IP, event_handler, NULL));
// wait for the IP event (e.g. using signalling semaphores from the handler)
// ...
esp_netif_ip_info_t ip_info = {}; esp_netif_ip_info_t ip_info = {};
while (ip_info.ip.addr == 0) {
ESP_LOGI("tap-init", "No IP assigned, waiting...");
usleep(1000000);
esp_netif_get_ip_info(tap_netif, &ip_info);
}
ESP_LOGI("tap-init", "Assigned IP address:"IPSTR ",", IP2STR(&ip_info.ip)); ESP_LOGI("tap-init", "Assigned IP address:"IPSTR ",", IP2STR(&ip_info.ip));
``` ```

Wyświetl plik

@ -4,26 +4,25 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdlib.h> #include <stdlib.h>
#include "esp_err.h"
#include "esp_log.h"
#include <stdlib.h>
#include "esp_netif.h"
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_netif.h"
// Use linux system sockets to connect to tap interface
#define LWIP_HDR_LINUX_SYS_SOCKETS_H
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <lwip/sys.h> #include <lwip/sys.h>
#include "errno.h" #include "errno.h"
#define LWIP_HDR_LINUX_SYS_SOCKETS_H
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
#include <esp_netif_net_stack.h>
#define DEVTAP "/dev/net/tun" #define DEVTAP "/dev/net/tun"
#define DEVTAP_NAME "tap0" #define DEVTAP_NAME "tap0"

Wyświetl plik

@ -7,6 +7,26 @@
#include "esp_netif.h" // esp-netif #include "esp_netif.h" // esp-netif
#include "tapio.h" // esp-netif's driver side #include "tapio.h" // esp-netif's driver side
#include "lwip/tapif.h" // esp-netif's network stack side #include "lwip/tapif.h" // esp-netif's network stack side
#include "esp_log.h"
#if CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
static const char *TAG = "linux_connect";
static EventGroupHandle_t s_events;
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
xEventGroupSetBits(s_events, 1);
}
#endif // CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#define TAP0_GOT_IP (0x1234)
esp_err_t example_connect(void) esp_err_t example_connect(void)
{ {
@ -25,14 +45,20 @@ esp_err_t example_connect(void)
}; };
// configure inherent esp-netif parameters // configure inherent esp-netif parameters
esp_netif_ip_info_t ip_info = {}; esp_netif_ip_info_t ip_info = {};
esp_netif_flags_t netif_flags = (ESP_NETIF_FLAG_EVENT_IP_MODIFIED | ESP_NETIF_FLAG_AUTOUP);
#if !CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
ip_info.ip.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_IP_ADDR); ip_info.ip.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_IP_ADDR);
ip_info.netmask.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_NETMASK); ip_info.netmask.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_NETMASK);
ip_info.gw.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_GW); ip_info.gw.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_GW);
#else
netif_flags |= ESP_NETIF_DHCP_CLIENT;
#endif
esp_netif_inherent_config_t base_cfg = { esp_netif_inherent_config_t base_cfg = {
.if_key = "TAP", .if_key = "TAP",
.flags = ESP_NETIF_FLAG_AUTOUP,
.ip_info = &ip_info, .ip_info = &ip_info,
.flags = netif_flags,
.get_ip_event = TAP0_GOT_IP,
.route_prio = 100 .route_prio = 100
}; };
@ -46,6 +72,15 @@ esp_err_t example_connect(void)
// create the interface and attach it to the tapio-handle // create the interface and attach it to the tapio-handle
esp_netif_t *tap_netif = esp_netif_new(&cfg); esp_netif_t *tap_netif = esp_netif_new(&cfg);
esp_netif_attach(tap_netif, driver_cfg.handle); esp_netif_attach(tap_netif, driver_cfg.handle);
#if CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
ESP_LOGI(TAG, "Waiting for IP addresses...");
esp_netif_action_connected(tap_netif, 0, 0, 0);
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, TAP0_GOT_IP, event_handler, NULL));
s_events = xEventGroupCreate();
xEventGroupWaitBits(s_events, 1, pdFALSE, pdFALSE, portMAX_DELAY);
esp_netif_get_ip_info(tap_netif, &ip_info);
ESP_LOGI(TAG, "Assigned IP address:"IPSTR ",", IP2STR(&ip_info.ip));
#endif // CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#endif // EXAMPLE_CONNECT_LWIP_TAPIF #endif // EXAMPLE_CONNECT_LWIP_TAPIF
return ESP_OK; return ESP_OK;
} }

Wyświetl plik

@ -5,8 +5,7 @@ cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
if(${IDF_TARGET} STREQUAL "linux") if(${IDF_TARGET} STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/" list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs)
"$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
set(COMPONENTS main) set(COMPONENTS main)
endif() endif()

Wyświetl plik

@ -3,7 +3,7 @@
# (If this was a component, we would set COMPONENT_EMBED_TXTFILES here.) # (If this was a component, we would set COMPONENT_EMBED_TXTFILES here.)
set(requires "") set(requires "")
if(${IDF_TARGET} STREQUAL "linux") if(${IDF_TARGET} STREQUAL "linux")
list(APPEND requires esp_stubs esp-tls esp_http_client protocol_examples_common nvs_flash) list(APPEND requires esp_stubs esp_event esp-tls esp_http_client protocol_examples_common nvs_flash)
endif() endif()
idf_component_register(SRCS "esp_http_client_example.c" idf_component_register(SRCS "esp_http_client_example.c"
INCLUDE_DIRS "." INCLUDE_DIRS "."

Wyświetl plik

@ -22,11 +22,9 @@
#include "esp_crt_bundle.h" #include "esp_crt_bundle.h"
#endif #endif
#if !CONFIG_IDF_TARGET_LINUX
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_system.h" #include "esp_system.h"
#endif
#include "esp_http_client.h" #include "esp_http_client.h"

Wyświetl plik

@ -5,8 +5,7 @@ cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
if(${IDF_TARGET} STREQUAL "linux") if(${IDF_TARGET} STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/" list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
"$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
set(COMPONENTS main) set(COMPONENTS main)
endif() endif()

Wyświetl plik

@ -6,9 +6,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "esp_err.h" #include "esp_err.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_event.h"
extern void app_main(void);
esp_err_t esp_netif_init(void) esp_err_t esp_netif_init(void)
{ {
@ -19,10 +16,3 @@ esp_err_t example_connect(void)
{ {
return ESP_OK; return ESP_OK;
} }
int main(void)
{
app_main();
return 0;
}

Wyświetl plik

@ -1,8 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2023 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);

Wyświetl plik

@ -8,4 +8,12 @@
#include <ifaddrs.h> #include <ifaddrs.h>
#include "esp_err.h" #include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
esp_err_t esp_netif_init(void); esp_err_t esp_netif_init(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -4,8 +4,7 @@ cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
if("${IDF_TARGET}" STREQUAL "linux") if("${IDF_TARGET}" STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/" list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
"$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
set(COMPONENTS main) set(COMPONENTS main)
endif() endif()

Wyświetl plik

@ -1,5 +1,5 @@
if(${IDF_TARGET} STREQUAL "linux") if(${IDF_TARGET} STREQUAL "linux")
set(requires esp_stubs protocol_examples_common nvs_flash) set(requires esp_event esp_stubs protocol_examples_common nvs_flash)
endif() endif()
if("${CONFIG_EXAMPLE_IPV4}" STREQUAL y) if("${CONFIG_EXAMPLE_IPV4}" STREQUAL y)

Wyświetl plik

@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16)
if("${IDF_TARGET}" STREQUAL "linux") if("${IDF_TARGET}" STREQUAL "linux")
# This example uses an extra component with common functionality for lwip's port on linux target # This example uses an extra component with common functionality for lwip's port on linux target
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_tapif_io) set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_tapif_io)
set(COMPONENTS main esp_netif protocol_examples_tapif_io startup esp_hw_support esp_system nvs_flash) set(COMPONENTS main esp_netif lwip protocol_examples_tapif_io startup esp_hw_support esp_system nvs_flash)
else() else()
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection on ESP target # This example uses an extra component for common functions such as Wi-Fi and Ethernet connection on ESP target
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)

Wyświetl plik

@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="linux"
CONFIG_EXAMPLE_IPV4_ADDR="127.0.0.1"
CONFIG_EXAMPLE_CONNECT_LWIP_TAPIF=n