ESPHome 2025.12.0-dev
Loading...
Searching...
No Matches
e131.cpp
Go to the documentation of this file.
1#include "e131.h"
2#ifdef USE_NETWORK
4#include "esphome/core/log.h"
5
6#include <algorithm>
7
8namespace esphome {
9namespace e131 {
10
11static const char *const TAG = "e131";
12static const int PORT = 5568;
13
15
17 if (this->socket_) {
18 this->socket_->close();
19 }
20}
21
23 this->socket_ = socket::socket_ip(SOCK_DGRAM, IPPROTO_IP);
24
25 int enable = 1;
26 int err = this->socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
27 if (err != 0) {
28 ESP_LOGW(TAG, "Socket unable to set reuseaddr: errno %d", err);
29 // we can still continue
30 }
31 err = this->socket_->setblocking(false);
32 if (err != 0) {
33 ESP_LOGW(TAG, "Socket unable to set nonblocking mode: errno %d", err);
34 this->mark_failed();
35 return;
36 }
37
38 struct sockaddr_storage server;
39
40 socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), PORT);
41 if (sl == 0) {
42 ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno);
43 this->mark_failed();
44 return;
45 }
46
47 err = this->socket_->bind((struct sockaddr *) &server, sizeof(server));
48 if (err != 0) {
49 ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno);
50 this->mark_failed();
51 return;
52 }
53
55}
56
58 std::vector<uint8_t> payload;
59 E131Packet packet;
60 int universe = 0;
61 uint8_t buf[1460];
62
63 ssize_t len = this->socket_->read(buf, sizeof(buf));
64 if (len == -1) {
65 return;
66 }
67 payload.resize(len);
68 memmove(&payload[0], buf, len);
69
70 if (!this->packet_(payload, universe, packet)) {
71 ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size());
72 return;
73 }
74
75 if (!this->process_(universe, packet)) {
76 ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count);
77 }
78}
79
81 if (std::find(light_effects_.begin(), light_effects_.end(), light_effect) != light_effects_.end()) {
82 return;
83 }
84
85 ESP_LOGD(TAG, "Registering '%s' for universes %d-%d.", light_effect->get_name(), light_effect->get_first_universe(),
86 light_effect->get_last_universe());
87
88 light_effects_.push_back(light_effect);
89
90 for (auto universe = light_effect->get_first_universe(); universe <= light_effect->get_last_universe(); ++universe) {
92 }
93}
94
96 auto it = std::find(light_effects_.begin(), light_effects_.end(), light_effect);
97 if (it == light_effects_.end()) {
98 return;
99 }
100
101 ESP_LOGD(TAG, "Unregistering '%s' for universes %d-%d.", light_effect->get_name(), light_effect->get_first_universe(),
102 light_effect->get_last_universe());
103
104 // Swap with last element and pop for O(1) removal (order doesn't matter)
105 *it = light_effects_.back();
106 light_effects_.pop_back();
107
108 for (auto universe = light_effect->get_first_universe(); universe <= light_effect->get_last_universe(); ++universe) {
110 }
111}
112
114 bool handled = false;
115
116 ESP_LOGV(TAG, "Received E1.31 packet for %d universe, with %d bytes", universe, packet.count);
117
118 for (auto *light_effect : light_effects_) {
119 handled = light_effect->process_(universe, packet) || handled;
120 }
121
122 return handled;
123}
124
125} // namespace e131
126} // namespace esphome
127#endif
virtual void mark_failed()
Mark this component as failed.
std::vector< E131AddressableLightEffect * > light_effects_
Definition e131.h:49
void loop() override
Definition e131.cpp:57
void add_effect(E131AddressableLightEffect *light_effect)
Definition e131.cpp:80
void remove_effect(E131AddressableLightEffect *light_effect)
Definition e131.cpp:95
bool process_(int universe, const E131Packet &packet)
Definition e131.cpp:113
std::unique_ptr< socket::Socket > socket_
Definition e131.h:48
void setup() override
Definition e131.cpp:22
bool packet_(const std::vector< uint8_t > &data, int &universe, E131Packet &packet)
const char * get_name() const
Returns the name of this effect.
uint16_t universe
uint32_t socklen_t
Definition headers.h:97
__int64 ssize_t
Definition httplib.h:178
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
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
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:500