ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
wake_on_lan.cpp
Go to the documentation of this file.
1#include "wake_on_lan.h"
2#if defined(USE_NETWORK) && !defined(USE_ZEPHYR)
3#include "esphome/core/log.h"
5
7
8ESPHOME_LOG_TAG(TAG, "wake_on_lan.button");
9static const uint8_t PREFIX[6] = {255, 255, 255, 255, 255, 255};
10
11void WakeOnLanButton::set_macaddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f) {
12 macaddr_[0] = a;
13 macaddr_[1] = b;
14 macaddr_[2] = c;
15 macaddr_[3] = d;
16 macaddr_[4] = e;
17 macaddr_[5] = f;
18}
19
21 LOG_BUTTON("", "Wake-on-LAN Button", this);
22 ESP_LOGCONFIG(TAG, " Target MAC address: %02X:%02X:%02X:%02X:%02X:%02X", this->macaddr_[0], this->macaddr_[1],
23 this->macaddr_[2], this->macaddr_[3], this->macaddr_[4], this->macaddr_[5]);
24}
25
27 if (this->broadcast_socket_ == nullptr) {
28 ESP_LOGW(TAG, "Socket not available");
29 return;
30 }
31 if (!network::is_connected()) {
32 ESP_LOGW(TAG, "Network not connected");
33 return;
34 }
35 ESP_LOGI(TAG, "Sending Wake-on-LAN Packet");
36 struct sockaddr_storage saddr{};
37 auto addr_len =
38 socket::set_sockaddr(reinterpret_cast<sockaddr *>(&saddr), sizeof(saddr), "255.255.255.255", this->port_);
39 if (addr_len == 0) {
40 ESP_LOGW(TAG, "Invalid broadcast address");
41 return;
42 }
43 uint8_t buffer[6 + sizeof this->macaddr_ * 16];
44 memcpy(buffer, PREFIX, sizeof(PREFIX));
45 for (size_t i = 0; i != 16; i++) {
46 memcpy(buffer + i * sizeof(this->macaddr_) + sizeof(PREFIX), this->macaddr_, sizeof(this->macaddr_));
47 }
48 if (this->broadcast_socket_->sendto(buffer, sizeof(buffer), 0, reinterpret_cast<const sockaddr *>(&saddr),
49 addr_len) <= 0) {
50 ESP_LOGW(TAG, "sendto() error %d", errno);
51 }
52}
53
55 this->broadcast_socket_ = socket::socket_udp_send(AF_INET, IPPROTO_IP);
56 if (this->broadcast_socket_ == nullptr) {
57 this->status_set_error(LOG_STR("Could not create socket"));
58 this->mark_failed();
59 return;
60 }
61 int enable = 1;
62 auto err = this->broadcast_socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
63 if (err != 0) {
64 this->status_set_warning(LOG_STR("Socket unable to set reuseaddr"));
65 // we can still continue
66 }
67 err = this->broadcast_socket_->setsockopt(SOL_SOCKET, SO_BROADCAST, &enable, sizeof(int));
68 if (err != 0) {
69 this->status_set_warning(LOG_STR("Socket unable to set broadcast"));
70 }
71}
72
73} // namespace esphome::wake_on_lan
74
75#endif
void mark_failed()
Mark this component as failed.
void set_macaddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f)
std::unique_ptr< socket::UDPSendSocket > broadcast_socket_
Definition wake_on_lan.h:20
uint8_t macaddr_[MAC_ADDRESS_SIZE]
Definition wake_on_lan.h:23
uint16_t addr_len
uint32_t buffer
Definition gif.cpp:50
ESPHOME_ALWAYS_INLINE bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
Definition util.h:36
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().
ESPHOME_LOG_TAG(TAG, "wake_on_lan.button")