diff --git a/esphome/components/e131/__init__.py b/esphome/components/e131/__init__.py index bb662e09893..cec0bdf4faf 100644 --- a/esphome/components/e131/__init__.py +++ b/esphome/components/e131/__init__.py @@ -4,6 +4,7 @@ from esphome.components.light.effects import register_addressable_effect from esphome.const import CONF_ID, CONF_NAME, CONF_METHOD, CONF_CHANNELS +AUTO_LOAD = ["socket"] DEPENDENCIES = ["network"] e131_ns = cg.esphome_ns.namespace("e131") @@ -23,16 +24,11 @@ CONF_UNIVERSE = "universe" CONF_E131_ID = "e131_id" -CONFIG_SCHEMA = cv.All( - cv.Schema( - { - cv.GenerateID(): cv.declare_id(E131Component), - cv.Optional(CONF_METHOD, default="MULTICAST"): cv.one_of( - *METHODS, upper=True - ), - } - ), - cv.only_with_arduino, +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(): cv.declare_id(E131Component), + cv.Optional(CONF_METHOD, default="MULTICAST"): cv.one_of(*METHODS, upper=True), + } ) diff --git a/esphome/components/e131/e131.cpp b/esphome/components/e131/e131.cpp index 6d584687ced..818006ced79 100644 --- a/esphome/components/e131/e131.cpp +++ b/esphome/components/e131/e131.cpp @@ -1,18 +1,7 @@ -#ifdef USE_ARDUINO - #include "e131.h" #include "e131_addressable_light_effect.h" #include "esphome/core/log.h" -#ifdef USE_ESP32 -#include -#endif - -#ifdef USE_ESP8266 -#include -#include -#endif - namespace esphome { namespace e131 { @@ -22,17 +11,41 @@ static const int PORT = 5568; E131Component::E131Component() {} E131Component::~E131Component() { - if (udp_) { - udp_->stop(); + if (this->socket_) { + this->socket_->close(); } } void E131Component::setup() { - udp_ = make_unique(); + this->socket_ = socket::socket_ip(SOCK_DGRAM, IPPROTO_IP); - if (!udp_->begin(PORT)) { - ESP_LOGE(TAG, "Cannot bind E131 to %d.", PORT); - mark_failed(); + int enable = 1; + int err = this->socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)); + if (err != 0) { + ESP_LOGW(TAG, "Socket unable to set reuseaddr: errno %d", err); + // we can still continue + } + err = this->socket_->setblocking(false); + if (err != 0) { + ESP_LOGW(TAG, "Socket unable to set nonblocking mode: errno %d", err); + this->mark_failed(); + return; + } + + struct sockaddr_storage server; + + socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), PORT); + if (sl == 0) { + ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno); + this->mark_failed(); + return; + } + server.ss_family = AF_INET; + + err = this->socket_->bind((struct sockaddr *) &server, sizeof(server)); + if (err != 0) { + ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno); + this->mark_failed(); return; } @@ -43,22 +56,22 @@ void E131Component::loop() { std::vector payload; E131Packet packet; int universe = 0; + uint8_t buf[1460]; - while (uint16_t packet_size = udp_->parsePacket()) { - payload.resize(packet_size); - - if (!udp_->read(&payload[0], payload.size())) { - continue; - } + ssize_t len = this->socket_->read(buf, sizeof(buf)); + if (len == -1) { + return; + } + payload.resize(len); + memmove(&payload[0], buf, len); - if (!packet_(payload, universe, packet)) { - ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size()); - continue; - } + if (!this->packet_(payload, universe, packet)) { + ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size()); + return; + } - if (!process_(universe, packet)) { - ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count); - } + if (!this->process_(universe, packet)) { + ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count); } } @@ -106,5 +119,3 @@ bool E131Component::process_(int universe, const E131Packet &packet) { } // namespace e131 } // namespace esphome - -#endif // USE_ARDUINO diff --git a/esphome/components/e131/e131.h b/esphome/components/e131/e131.h index 8bf8999c21f..364a05af756 100644 --- a/esphome/components/e131/e131.h +++ b/esphome/components/e131/e131.h @@ -1,7 +1,6 @@ #pragma once -#ifdef USE_ARDUINO - +#include "esphome/components/socket/socket.h" #include "esphome/core/component.h" #include @@ -9,8 +8,6 @@ #include #include -class UDP; - namespace esphome { namespace e131 { @@ -47,7 +44,7 @@ class E131Component : public esphome::Component { void leave_(int universe); E131ListenMethod listen_method_{E131_MULTICAST}; - std::unique_ptr udp_; + std::unique_ptr socket_; std::set light_effects_; std::map universe_consumers_; std::map universe_packets_; @@ -55,5 +52,3 @@ class E131Component : public esphome::Component { } // namespace e131 } // namespace esphome - -#endif // USE_ARDUINO diff --git a/esphome/components/e131/e131_addressable_light_effect.cpp b/esphome/components/e131/e131_addressable_light_effect.cpp index 7a3e71808eb..42eb0fc56b3 100644 --- a/esphome/components/e131/e131_addressable_light_effect.cpp +++ b/esphome/components/e131/e131_addressable_light_effect.cpp @@ -1,7 +1,5 @@ -#ifdef USE_ARDUINO - -#include "e131.h" #include "e131_addressable_light_effect.h" +#include "e131.h" #include "esphome/core/log.h" namespace esphome { @@ -92,5 +90,3 @@ bool E131AddressableLightEffect::process_(int universe, const E131Packet &packet } // namespace e131 } // namespace esphome - -#endif // USE_ARDUINO diff --git a/esphome/components/e131/e131_addressable_light_effect.h b/esphome/components/e131/e131_addressable_light_effect.h index b3e481e43b5..56df9cd80f3 100644 --- a/esphome/components/e131/e131_addressable_light_effect.h +++ b/esphome/components/e131/e131_addressable_light_effect.h @@ -1,7 +1,5 @@ #pragma once -#ifdef USE_ARDUINO - #include "esphome/core/component.h" #include "esphome/components/light/addressable_light_effect.h" @@ -44,5 +42,3 @@ class E131AddressableLightEffect : public light::AddressableLightEffect { } // namespace e131 } // namespace esphome - -#endif // USE_ARDUINO diff --git a/esphome/components/e131/e131_packet.cpp b/esphome/components/e131/e131_packet.cpp index f199d3574b2..ac8b72f6e7c 100644 --- a/esphome/components/e131/e131_packet.cpp +++ b/esphome/components/e131/e131_packet.cpp @@ -1,15 +1,13 @@ -#ifdef USE_ARDUINO - +#include #include "e131.h" +#include "esphome/components/network/ip_address.h" #include "esphome/core/log.h" #include "esphome/core/util.h" -#include "esphome/components/network/ip_address.h" -#include +#include #include -#include #include -#include +#include namespace esphome { namespace e131 { @@ -62,7 +60,7 @@ const size_t E131_MIN_PACKET_SIZE = reinterpret_cast(&((E131RawPacket *) bool E131Component::join_igmp_groups_() { if (listen_method_ != E131_MULTICAST) return false; - if (!udp_) + if (this->socket_ == nullptr) return false; for (auto universe : universe_consumers_) { @@ -140,5 +138,3 @@ bool E131Component::packet_(const std::vector &data, int &universe, E13 } // namespace e131 } // namespace esphome - -#endif // USE_ARDUINO