ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
lwip_sockets_impl.cpp
Go to the documentation of this file.
3#include "socket.h"
4
5#ifdef USE_SOCKET_IMPL_LWIP_SOCKETS
6
7#include <cstring>
9#ifdef USE_HOST
10#include "esphome/core/wake.h"
11#endif
12
13namespace esphome::socket {
14
15LwIPSocketImpl::LwIPSocketImpl(int fd, bool monitor_loop) {
16 this->fd_ = fd;
17 if (!monitor_loop || this->fd_ < 0)
18 return;
19#ifdef USE_LWIP_FAST_SELECT
21#else
23#endif
24}
25
27
29 if (this->fd_ < 0) {
30 // Already closed, or never opened.
31 return 0;
32 }
33#ifdef USE_LWIP_FAST_SELECT
34 // Null the cached lwip_sock pointer before closing. The underlying lwip slot can be
35 // recycled for a new connection as soon as lwip_close() returns, so anything that
36 // might dereference cached_sock_ post-close (e.g. setsockopt(TCP_NODELAY)) would
37 // otherwise touch an unrelated socket's pcb. No per-socket callback unhook is needed —
38 // all LwIP sockets share the same static event_callback.
39 this->cached_sock_ = nullptr;
40#else
41 if (this->loop_monitored_) {
43 }
44#endif
45 int ret = lwip_close(this->fd_);
46 this->fd_ = -1; // Sentinel for "closed" — prevents double-close and makes use-after-close visible.
47 return ret;
48}
49
50int LwIPSocketImpl::setblocking(bool blocking) {
51 int fl = lwip_fcntl(this->fd_, F_GETFL, 0);
52 if (blocking) {
53 fl &= ~O_NONBLOCK;
54 } else {
55 fl |= O_NONBLOCK;
56 }
57 lwip_fcntl(this->fd_, F_SETFL, fl);
58 return 0;
59}
60
61size_t LwIPSocketImpl::getpeername_to(std::span<char, SOCKADDR_STR_LEN> buf) {
62 struct sockaddr_storage storage;
63 socklen_t len = sizeof(storage);
64 if (this->getpeername(reinterpret_cast<struct sockaddr *>(&storage), &len) != 0) {
65 buf[0] = '\0';
66 return 0;
67 }
68 return format_sockaddr_to(reinterpret_cast<struct sockaddr *>(&storage), len, buf);
69}
70
71size_t LwIPSocketImpl::getsockname_to(std::span<char, SOCKADDR_STR_LEN> buf) {
72 struct sockaddr_storage storage;
73 socklen_t len = sizeof(storage);
74 if (this->getsockname(reinterpret_cast<struct sockaddr *>(&storage), &len) != 0) {
75 buf[0] = '\0';
76 return 0;
77 }
78 return format_sockaddr_to(reinterpret_cast<struct sockaddr *>(&storage), len, buf);
79}
80
81// Helper to create a socket with optional monitoring
82static std::unique_ptr<LwIPSocketImpl> create_socket(int domain, int type, int protocol, bool loop_monitored = false) {
83 int ret = lwip_socket(domain, type, protocol);
84 if (ret == -1)
85 return nullptr;
86 return make_unique<LwIPSocketImpl>(ret, loop_monitored);
87}
88
89std::unique_ptr<Socket> socket(int domain, int type, int protocol) {
90 return create_socket(domain, type, protocol, false);
91}
92
93std::unique_ptr<Socket> socket_loop_monitored(int domain, int type, int protocol) {
94 return create_socket(domain, type, protocol, true);
95}
96
97} // namespace esphome::socket
98
99#endif // USE_SOCKET_IMPL_LWIP_SOCKETS
int getsockname(struct sockaddr *addr, socklen_t *addrlen)
size_t getsockname_to(std::span< char, SOCKADDR_STR_LEN > buf)
Format local address into a fixed-size buffer (no heap allocation)
LwIPSocketImpl(int fd, bool monitor_loop=false)
int getpeername(struct sockaddr *addr, socklen_t *addrlen)
size_t getpeername_to(std::span< char, SOCKADDR_STR_LEN > buf)
Format peer address into a fixed-size buffer (no heap allocation)
uint16_t type
uint32_t socklen_t
Definition headers.h:99
size_t format_sockaddr_to(const struct sockaddr *addr_ptr, socklen_t len, std::span< char, SOCKADDR_STR_LEN > buf)
Format sockaddr into caller-provided buffer, returns length written (excluding null)
Definition socket.cpp:56
struct lwip_sock * hook_fd_for_fast_select(int fd)
Resolve an fd to its lwip_sock and install the netconn event-callback hook so the main loop is woken ...
Definition socket.h:56
std::unique_ptr< Socket > socket_loop_monitored(int domain, int type, int protocol)
Create a socket and monitor it for data in the main loop.
std::string size_t len
bool wake_register_fd(int fd)
Register a socket file descriptor with the host select() loop.
Definition wake_host.cpp:46
void wake_unregister_fd(int fd)
Unregister a socket file descriptor. Not thread-safe — main loop only.
Definition wake_host.cpp:65
Platform-specific main loop wake primitives.