ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
lwip_raw_common_impl.h
Go to the documentation of this file.
1#pragma once
3
4#ifdef USE_SOCKET_IMPL_LWIP_TCP
5
6#include "headers.h"
7#include "lwip/ip.h"
8
9namespace esphome::socket {
10
11// ---- LWIP thread safety ----
12//
13// On RP2040 (Pico W), arduino-pico sets PICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1.
14// This means lwip callbacks (recv_fn, accept_fn, err_fn) run from a low-priority
15// user IRQ context, not the main loop (see low_priority_irq_handler() in pico-sdk
16// async_context_threadsafe_background.c). They can preempt main-loop code at any point.
17//
18// Without locking, this causes race conditions between recv_fn and read() on the
19// shared rx_buf_ pbuf chain — recv_fn calls pbuf_cat() while read() is freeing
20// nodes, leading to use-after-free and infinite-loop crashes. See esphome#10681.
21//
22// On ESP8266, lwip callbacks run from the SYS context which cooperates with user
23// code (CONT context) — they never preempt each other, so no locking is needed.
24//
25// esphome::LwIPLock is the platform-provided RAII guard (see helpers.h/helpers.cpp).
26// On RP2040, it acquires cyw43_arch_lwip_begin/end (WiFi) or ethernet_arch_lwip_begin/end
27// (Ethernet). On ESP8266, it's a no-op.
28//
29// Each .cpp file that needs locking defines its own LWIP_LOCK() macro:
30// #define LWIP_LOCK() esphome::LwIPLock lwip_lock_guard
31// This is a per-TU convenience macro, not defined here to avoid macro leaking.
32
35int lwip_ip_to_sockaddr(sa_family_t family, const ip_addr_t *ip, uint16_t port_host, struct sockaddr *name,
36 socklen_t *addrlen);
37
41bool sockaddr_to_lwip(const struct sockaddr *addr, socklen_t addrlen, ip_addr_t *ip, uint16_t *port);
42
45bool sockaddr_to_lwip_bind(sa_family_t family, const struct sockaddr *addr, socklen_t addrlen, ip_addr_t *ip,
46 uint16_t *port);
47
49int lwip_err_to_errno(err_t err);
50
51} // namespace esphome::socket
52
53#endif // USE_SOCKET_IMPL_LWIP_TCP
uint32_t socklen_t
Definition headers.h:109
uint8_t sa_family_t
Definition headers.h:69
bool sockaddr_to_lwip(const struct sockaddr *addr, socklen_t addrlen, ip_addr_t *ip, uint16_t *port)
Convert sockaddr to lwip ip_addr_t and host-order port.
int lwip_err_to_errno(err_t err)
errno for a failed lwip call
bool sockaddr_to_lwip_bind(sa_family_t family, const struct sockaddr *addr, socklen_t addrlen, ip_addr_t *ip, uint16_t *port)
sockaddr_to_lwip variant for bind: promotes AF_INET6 sockets to IPADDR_TYPE_ANY so they accept both I...
int lwip_ip_to_sockaddr(sa_family_t family, const ip_addr_t *ip, uint16_t port_host, struct sockaddr *name, socklen_t *addrlen)
Convert lwip ip_addr_t + host-order port to sockaddr, based on the socket's address family.