Migrate e131 to use socket instead of WiFiUDP arduino library (#4832)

This commit is contained in:
Jesse Hills 2023-05-18 08:41:21 +12:00 committed by GitHub
parent 18f4e41550
commit 9e3ecc8372
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 68 deletions

View file

@ -4,6 +4,7 @@ from esphome.components.light.types import AddressableLightEffect
from esphome.components.light.effects import register_addressable_effect from esphome.components.light.effects import register_addressable_effect
from esphome.const import CONF_ID, CONF_NAME, CONF_METHOD, CONF_CHANNELS from esphome.const import CONF_ID, CONF_NAME, CONF_METHOD, CONF_CHANNELS
AUTO_LOAD = ["socket"]
DEPENDENCIES = ["network"] DEPENDENCIES = ["network"]
e131_ns = cg.esphome_ns.namespace("e131") e131_ns = cg.esphome_ns.namespace("e131")
@ -23,16 +24,11 @@ CHANNELS = {
CONF_UNIVERSE = "universe" CONF_UNIVERSE = "universe"
CONF_E131_ID = "e131_id" CONF_E131_ID = "e131_id"
CONFIG_SCHEMA = cv.All( CONFIG_SCHEMA = cv.Schema(
cv.Schema(
{ {
cv.GenerateID(): cv.declare_id(E131Component), cv.GenerateID(): cv.declare_id(E131Component),
cv.Optional(CONF_METHOD, default="MULTICAST"): cv.one_of( cv.Optional(CONF_METHOD, default="MULTICAST"): cv.one_of(*METHODS, upper=True),
*METHODS, upper=True
),
} }
),
cv.only_with_arduino,
) )

View file

@ -1,18 +1,7 @@
#ifdef USE_ARDUINO
#include "e131.h" #include "e131.h"
#include "e131_addressable_light_effect.h" #include "e131_addressable_light_effect.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#ifdef USE_ESP32
#include <WiFi.h>
#endif
#ifdef USE_ESP8266
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#endif
namespace esphome { namespace esphome {
namespace e131 { namespace e131 {
@ -22,17 +11,41 @@ static const int PORT = 5568;
E131Component::E131Component() {} E131Component::E131Component() {}
E131Component::~E131Component() { E131Component::~E131Component() {
if (udp_) { if (this->socket_) {
udp_->stop(); this->socket_->close();
} }
} }
void E131Component::setup() { void E131Component::setup() {
udp_ = make_unique<WiFiUDP>(); this->socket_ = socket::socket_ip(SOCK_DGRAM, IPPROTO_IP);
if (!udp_->begin(PORT)) { int enable = 1;
ESP_LOGE(TAG, "Cannot bind E131 to %d.", PORT); int err = this->socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
mark_failed(); 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; return;
} }
@ -43,24 +56,24 @@ void E131Component::loop() {
std::vector<uint8_t> payload; std::vector<uint8_t> payload;
E131Packet packet; E131Packet packet;
int universe = 0; int universe = 0;
uint8_t buf[1460];
while (uint16_t packet_size = udp_->parsePacket()) { ssize_t len = this->socket_->read(buf, sizeof(buf));
payload.resize(packet_size); if (len == -1) {
return;
if (!udp_->read(&payload[0], payload.size())) {
continue;
} }
payload.resize(len);
memmove(&payload[0], buf, len);
if (!packet_(payload, universe, packet)) { if (!this->packet_(payload, universe, packet)) {
ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size()); ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size());
continue; return;
} }
if (!process_(universe, packet)) { if (!this->process_(universe, packet)) {
ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count); ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count);
} }
} }
}
void E131Component::add_effect(E131AddressableLightEffect *light_effect) { void E131Component::add_effect(E131AddressableLightEffect *light_effect) {
if (light_effects_.count(light_effect)) { if (light_effects_.count(light_effect)) {
@ -106,5 +119,3 @@ bool E131Component::process_(int universe, const E131Packet &packet) {
} // namespace e131 } // namespace e131
} // namespace esphome } // namespace esphome
#endif // USE_ARDUINO

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#ifdef USE_ARDUINO #include "esphome/components/socket/socket.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include <map> #include <map>
@ -9,8 +8,6 @@
#include <set> #include <set>
#include <vector> #include <vector>
class UDP;
namespace esphome { namespace esphome {
namespace e131 { namespace e131 {
@ -47,7 +44,7 @@ class E131Component : public esphome::Component {
void leave_(int universe); void leave_(int universe);
E131ListenMethod listen_method_{E131_MULTICAST}; E131ListenMethod listen_method_{E131_MULTICAST};
std::unique_ptr<UDP> udp_; std::unique_ptr<socket::Socket> socket_;
std::set<E131AddressableLightEffect *> light_effects_; std::set<E131AddressableLightEffect *> light_effects_;
std::map<int, int> universe_consumers_; std::map<int, int> universe_consumers_;
std::map<int, E131Packet> universe_packets_; std::map<int, E131Packet> universe_packets_;
@ -55,5 +52,3 @@ class E131Component : public esphome::Component {
} // namespace e131 } // namespace e131
} // namespace esphome } // namespace esphome
#endif // USE_ARDUINO

View file

@ -1,7 +1,5 @@
#ifdef USE_ARDUINO
#include "e131.h"
#include "e131_addressable_light_effect.h" #include "e131_addressable_light_effect.h"
#include "e131.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
namespace esphome { namespace esphome {
@ -92,5 +90,3 @@ bool E131AddressableLightEffect::process_(int universe, const E131Packet &packet
} // namespace e131 } // namespace e131
} // namespace esphome } // namespace esphome
#endif // USE_ARDUINO

View file

@ -1,7 +1,5 @@
#pragma once #pragma once
#ifdef USE_ARDUINO
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/components/light/addressable_light_effect.h" #include "esphome/components/light/addressable_light_effect.h"
@ -44,5 +42,3 @@ class E131AddressableLightEffect : public light::AddressableLightEffect {
} // namespace e131 } // namespace e131
} // namespace esphome } // namespace esphome
#endif // USE_ARDUINO

View file

@ -1,15 +1,13 @@
#ifdef USE_ARDUINO #include <cstring>
#include "e131.h" #include "e131.h"
#include "esphome/components/network/ip_address.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/util.h" #include "esphome/core/util.h"
#include "esphome/components/network/ip_address.h"
#include <cstring>
#include <lwip/init.h>
#include <lwip/ip_addr.h>
#include <lwip/ip4_addr.h>
#include <lwip/igmp.h> #include <lwip/igmp.h>
#include <lwip/init.h>
#include <lwip/ip4_addr.h>
#include <lwip/ip_addr.h>
namespace esphome { namespace esphome {
namespace e131 { namespace e131 {
@ -62,7 +60,7 @@ const size_t E131_MIN_PACKET_SIZE = reinterpret_cast<size_t>(&((E131RawPacket *)
bool E131Component::join_igmp_groups_() { bool E131Component::join_igmp_groups_() {
if (listen_method_ != E131_MULTICAST) if (listen_method_ != E131_MULTICAST)
return false; return false;
if (!udp_) if (this->socket_ == nullptr)
return false; return false;
for (auto universe : universe_consumers_) { for (auto universe : universe_consumers_) {
@ -140,5 +138,3 @@ bool E131Component::packet_(const std::vector<uint8_t> &data, int &universe, E13
} // namespace e131 } // namespace e131
} // namespace esphome } // namespace esphome
#endif // USE_ARDUINO