ESPHome 2026.1.0-dev
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::socket {
10
12
13std::unique_ptr<Socket> socket_ip(int type, int protocol) {
14#if USE_NETWORK_IPV6
15 return socket(AF_INET6, type, protocol);
16#else
17 return socket(AF_INET, type, protocol);
18#endif /* USE_NETWORK_IPV6 */
19}
20
21std::unique_ptr<Socket> socket_ip_loop_monitored(int type, int protocol) {
22#if USE_NETWORK_IPV6
23 return socket_loop_monitored(AF_INET6, type, protocol);
24#else
25 return socket_loop_monitored(AF_INET, type, protocol);
26#endif /* USE_NETWORK_IPV6 */
27}
28
29socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const std::string &ip_address, uint16_t port) {
30#if USE_NETWORK_IPV6
31 if (ip_address.find(':') != std::string::npos) {
32 if (addrlen < sizeof(sockaddr_in6)) {
33 errno = EINVAL;
34 return 0;
35 }
36 auto *server = reinterpret_cast<sockaddr_in6 *>(addr);
37 memset(server, 0, sizeof(sockaddr_in6));
38 server->sin6_family = AF_INET6;
39 server->sin6_port = htons(port);
40
41#ifdef USE_SOCKET_IMPL_BSD_SOCKETS
42 // Use standard inet_pton for BSD sockets
43 if (inet_pton(AF_INET6, ip_address.c_str(), &server->sin6_addr) != 1) {
44 errno = EINVAL;
45 return 0;
46 }
47#else
48 // Use LWIP-specific functions
49 ip6_addr_t ip6;
50 inet6_aton(ip_address.c_str(), &ip6);
51 memcpy(server->sin6_addr.un.u32_addr, ip6.addr, sizeof(ip6.addr));
52#endif
53 return sizeof(sockaddr_in6);
54 }
55#endif /* USE_NETWORK_IPV6 */
56 if (addrlen < sizeof(sockaddr_in)) {
57 errno = EINVAL;
58 return 0;
59 }
60 auto *server = reinterpret_cast<sockaddr_in *>(addr);
61 memset(server, 0, sizeof(sockaddr_in));
62 server->sin_family = AF_INET;
63 server->sin_addr.s_addr = inet_addr(ip_address.c_str());
64 server->sin_port = htons(port);
65 return sizeof(sockaddr_in);
66}
67
68socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port) {
69#if USE_NETWORK_IPV6
70 if (addrlen < sizeof(sockaddr_in6)) {
71 errno = EINVAL;
72 return 0;
73 }
74 auto *server = reinterpret_cast<sockaddr_in6 *>(addr);
75 memset(server, 0, sizeof(sockaddr_in6));
76 server->sin6_family = AF_INET6;
77 server->sin6_port = htons(port);
78 server->sin6_addr = IN6ADDR_ANY_INIT;
79 return sizeof(sockaddr_in6);
80#else
81 if (addrlen < sizeof(sockaddr_in)) {
82 errno = EINVAL;
83 return 0;
84 }
85 auto *server = reinterpret_cast<sockaddr_in *>(addr);
86 memset(server, 0, sizeof(sockaddr_in));
87 server->sin_family = AF_INET;
88 server->sin_addr.s_addr = ESPHOME_INADDR_ANY;
89 server->sin_port = htons(port);
90 return sizeof(sockaddr_in);
91#endif /* USE_NETWORK_IPV6 */
92}
93} // namespace esphome::socket
94#endif
uint16_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:13
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:21
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:29
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:68
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.