11static constexpr uint32_t NETWORK_POLL_ID = 0;
12static constexpr uint32_t NETWORK_POLL_INTERVAL_MS = 1000;
15 size_t address_count = 0;
16 for (
const char *
const *it = this->
addresses_; it !=
nullptr && *it !=
nullptr; it++)
19 for (
const char *
const *it = this->
addresses_; it !=
nullptr && *it !=
nullptr; it++) {
23 ESP_LOGW(TAG,
"Invalid address %s",
address);
32#ifdef USE_UDP_IPV6_SEND
43 auto err = this->
broadcast_socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable,
sizeof(
int));
48 err = this->
broadcast_socket_->setsockopt(SOL_SOCKET, SO_BROADCAST, &enable,
sizeof(
int));
53#ifdef USE_UDP_IPV6_SEND
80 if (server.ss_family == AF_INET6)
90 this->
listen_socket_->setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, &v6only,
sizeof(v6only)) != 0) {
91 ESP_LOGW(TAG,
"Failed to clear IPV6_V6ONLY: errno %d", errno);
107 ESP_LOGE(TAG,
"Unable to set nonblocking: errno %d", errno);
113 err = this->
listen_socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable,
sizeof(enable));
122 ESP_LOGE(TAG,
"Socket unable to bind: errno %d", errno);
131 this->
set_interval(NETWORK_POLL_ID, NETWORK_POLL_INTERVAL_MS, [
this]() {
141#ifdef USE_SOCKET_IPV6
155#ifdef USE_SOCKET_IPV6
171#ifdef USE_UDP_IPV6_SEND
180 this->
set_poll_warning_(POLL_MCAST_IF, LOG_STR(
"Failed to set IPv6 multicast interface"));
199 ESP_LOGW(TAG,
"%s. Error %d", LOG_STR_ARG(what), errno);
213 std::array<uint8_t, MAX_PACKET_SIZE + 1> buf;
220 size_t packet_len =
static_cast<size_t>(
len);
221 if (packet_len > MAX_PACKET_SIZE) {
222 ESP_LOGV(TAG,
"Packet longer than %zu bytes dropped", MAX_PACKET_SIZE);
225 ESP_LOGV(TAG,
"Received packet of length %zu", packet_len);
234 " Broadcast Port: %u",
236 for (
const char *
const *it = this->
addresses_; it !=
nullptr && *it !=
nullptr; it++) {
238 ESP_LOGCONFIG(TAG,
" Address: %s",
address);
244 " Broadcasting: %s\n"
254#ifdef USE_UDP_IPV6_SEND
255 const bool v6 = entry.sa.sa_family == AF_INET6;
258 ESP_LOGV(TAG,
"Egress interface not set yet, multicast packet dropped");
267 if (sock ==
nullptr) {
268 ESP_LOGW(TAG,
"Broadcast socket not initialized");
271 auto result = sock->
sendto(data,
size, 0, &entry.sa, sockaddr_size);
275 if (errno == ENOMEM) {
276 ESP_LOGV(TAG,
"sendto() out of memory");
278 ESP_LOGW(TAG,
"sendto() error %d", errno);
void mark_failed()
Mark this component as failed.
void status_set_warning()
bool cancel_interval(const char *name)
Cancel an interval function.
bool status_has_warning() const
void disable_loop()
Disable this component's loop.
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
void status_clear_warning()
ssize_t sendto(const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
void set_poll_warning_(PollStep step, const LogString *what)
std::unique_ptr< socket::UDPSendSocket > send_socket_v6_
const char * listen_address_
FixedVector< SockaddrEntry > sockaddrs_
LazyCallbackManager< void(std::span< const uint8_t >)> packet_listeners_
bool network_poll_()
One pass of the network poll; true once nothing is left to do.
std::unique_ptr< socket::UDPSendSocket > broadcast_socket_
void dump_config() override
const char *const * addresses_
std::unique_ptr< socket::UDPSocket > listen_socket_
bool send_packet(const uint8_t *data, size_t size)
Returns false if the packet could not be sent to every destination.
ESPHOME_ALWAYS_INLINE bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
std::unique_ptr< UDPSendSocket > socket_udp_send(int domain, int protocol)
Create a send-only UDP socket (socket_udp_send), a UDP socket with receive support (socket_udp),...
socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const char *ip_address, uint16_t port)
Set a sockaddr to the specified address and port for the IP version used by socket_ip().
bool set_ipv6_multicast_if(Socket *sock, uint32_t if_index_in=0)
Configure the outgoing IPv6 multicast interface on the given socket.
bool join_multicast_group(UDPSocket *sock, const char *ip_address, uint32_t *if_index_out=nullptr)
Join a multicast group on the given socket.
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().
std::unique_ptr< UDPSocket > socket_udp_loop_monitored(int domain, int protocol)
ESPHOME_LOG_TAG(TAG, "udp.packet_interface")