ESPHome 2025.6.0
Loading...
Searching...
No Matches
socket.cpp
Go to the documentation of this file.
1#include "socket.h"
2#if defined(USE_SOCKET_IMPL_LWIP_TCP) || defined(USE_SOCKET_IMPL_LWIP_SOCKETS) || defined(USE_SOCKET_IMPL_BSD_SOCKETS)
3#include <cerrno>
4#include <cstring>
5#include <string>
6#include "esphome/core/log.h"
8
9namespace esphome {
10namespace socket {
11
13
14bool Socket::ready() const {
15#ifdef USE_SOCKET_SELECT_SUPPORT
16 if (!loop_monitored_) {
17 // Non-monitored sockets always return true (assume data may be available)
18 return true;
19 }
20
21 // For loop-monitored sockets, check with the Application's select() results
22 int fd = this->get_fd();
23 if (fd < 0) {
24 // No valid file descriptor, assume ready (fallback behavior)
25 return true;
26 }
27
28 return App.is_socket_ready(fd);
29#else
30 // Without select() support, we can't monitor sockets in the loop
31 // Always return true (assume data may be available)
32 return true;
33#endif
34}
35
36std::unique_ptr<Socket> socket_ip(int type, int protocol) {
37#if USE_NETWORK_IPV6
38 return socket(AF_INET6, type, protocol);
39#else
40 return socket(AF_INET, type, protocol);
41#endif /* USE_NETWORK_IPV6 */
42}
43
44std::unique_ptr<Socket> socket_ip_loop_monitored(int type, int protocol) {
45#if USE_NETWORK_IPV6
46 return socket_loop_monitored(AF_INET6, type, protocol);
47#else
48 return socket_loop_monitored(AF_INET, type, protocol);
49#endif /* USE_NETWORK_IPV6 */
50}
51
52socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const std::string &ip_address, uint16_t port) {
53#if USE_NETWORK_IPV6
54 if (ip_address.find(':') != std::string::npos) {
55 if (addrlen < sizeof(sockaddr_in6)) {
56 errno = EINVAL;
57 return 0;
58 }
59 auto *server = reinterpret_cast<sockaddr_in6 *>(addr);
60 memset(server, 0, sizeof(sockaddr_in6));
61 server->sin6_family = AF_INET6;
62 server->sin6_port = htons(port);
63
64 ip6_addr_t ip6;
65 inet6_aton(ip_address.c_str(), &ip6);
66 memcpy(server->sin6_addr.un.u32_addr, ip6.addr, sizeof(ip6.addr));
67 return sizeof(sockaddr_in6);
68 }
69#endif /* USE_NETWORK_IPV6 */
70 if (addrlen < sizeof(sockaddr_in)) {
71 errno = EINVAL;
72 return 0;
73 }
74 auto *server = reinterpret_cast<sockaddr_in *>(addr);
75 memset(server, 0, sizeof(sockaddr_in));
76 server->sin_family = AF_INET;
77 server->sin_addr.s_addr = inet_addr(ip_address.c_str());
78 server->sin_port = htons(port);
79 return sizeof(sockaddr_in);
80}
81
82socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port) {
83#if USE_NETWORK_IPV6
84 if (addrlen < sizeof(sockaddr_in6)) {
85 errno = EINVAL;
86 return 0;
87 }
88 auto *server = reinterpret_cast<sockaddr_in6 *>(addr);
89 memset(server, 0, sizeof(sockaddr_in6));
90 server->sin6_family = AF_INET6;
91 server->sin6_port = htons(port);
92 server->sin6_addr = IN6ADDR_ANY_INIT;
93 return sizeof(sockaddr_in6);
94#else
95 if (addrlen < sizeof(sockaddr_in)) {
96 errno = EINVAL;
97 return 0;
98 }
99 auto *server = reinterpret_cast<sockaddr_in *>(addr);
100 memset(server, 0, sizeof(sockaddr_in));
101 server->sin_family = AF_INET;
102 server->sin_addr.s_addr = ESPHOME_INADDR_ANY;
103 server->sin_port = htons(port);
104 return sizeof(sockaddr_in);
105#endif /* USE_NETWORK_IPV6 */
106}
107} // namespace socket
108} // namespace esphome
109#endif
bool is_socket_ready(int fd) const
Check if there's data available on a socket without blocking This function is thread-safe for reading...
bool ready() const
Check if socket has data ready to read For loop-monitored sockets, checks with the Application's sele...
Definition socket.cpp:14
virtual int get_fd() const
Get the underlying file descriptor (returns -1 if not supported)
Definition socket.h:54
bool loop_monitored_
Whether this socket is monitored by the event loop.
Definition socket.h:63
uint8_t type
uint32_t socklen_t
Definition headers.h:97
std::unique_ptr< Socket > socket_ip(int type, int protocol)
Create a socket in the newest available IP domain (IPv6 or IPv4) of the given type and protocol.
Definition socket.cpp:36
std::unique_ptr< Socket > socket(int domain, int type, int protocol)
Create a socket of the given domain, type and protocol.
std::unique_ptr< Socket > socket_ip_loop_monitored(int type, int protocol)
Definition socket.cpp:44
socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const std::string &ip_address, uint16_t port)
Set a sockaddr to the specified address and port for the IP version used by socket_ip().
Definition socket.cpp:52
socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port)
Set a sockaddr to the any address and specified port for the IP version used by socket_ip().
Definition socket.cpp:82
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.
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
Application App
Global storage of Application pointer - only one Application can exist.