From 32c097dfad2077cf928e787e7c0d4905a3caf43f Mon Sep 17 00:00:00 2001 From: clydebarrow <2366188+clydebarrow@users.noreply.github.com> Date: Sun, 18 Oct 2026 20:38:40 +1100 Subject: [PATCH] [udp] Take the packet size from the copy buffer The link derives max_packet_size from the span it is given, so a packet larger than the copy buffer cannot be copied into it. Co-Authored-By: Claude Code --- .../packet_interface/udp_packet_interface.cpp | 5 ----- .../packet_interface/udp_packet_interface.h | 5 ++--- tests/components/udp/udp_packet_interface.cpp | 20 ++++++------------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/esphome/components/udp/packet_interface/udp_packet_interface.cpp b/esphome/components/udp/packet_interface/udp_packet_interface.cpp index 211c27b36cc..0a3e063d033 100644 --- a/esphome/components/udp/packet_interface/udp_packet_interface.cpp +++ b/esphome/components/udp/packet_interface/udp_packet_interface.cpp @@ -35,11 +35,6 @@ bool UdpPacketInterface::send_to_interface(const PacketBuffer &data, const Packe auto span = data.as_span(); return this->parent_->send_packet(span.data(), span.size()); } - if (size > this->tx_buffer_.size()) { - ESP_LOGW(TAG, "%s: Packet of %zu bytes is larger than the %zu byte buffer", this->name_, size, - this->tx_buffer_.size()); - return false; - } data.copy_to(this->tx_buffer_.data(), size); return this->parent_->send_packet(this->tx_buffer_.data(), size); } diff --git a/esphome/components/udp/packet_interface/udp_packet_interface.h b/esphome/components/udp/packet_interface/udp_packet_interface.h index dea77ea74ec..bd28c3ea87b 100644 --- a/esphome/components/udp/packet_interface/udp_packet_interface.h +++ b/esphome/components/udp/packet_interface/udp_packet_interface.h @@ -19,10 +19,9 @@ namespace esphome::udp { */ class UdpPacketInterface : public packet_interface::PacketInterface { public: - /// @param tx_buffer Joins packets split across buffers, sized by code generation to max_packet_size; must outlive - /// the link. A larger max_packet_size set later is limited to it for those packets. + /// @param tx_buffer Joins packets split across buffers; its size is the largest packet, and it must outlive the link UdpPacketInterface(UDPComponent *udp_component, std::span tx_buffer) - : parent_(udp_component), tx_buffer_(tx_buffer) {} + : packet_interface::PacketInterface(tx_buffer.size()), parent_(udp_component), tx_buffer_(tx_buffer) {} void setup() override; bool send_to_interface(const packet_interface::PacketBuffer &data, diff --git a/tests/components/udp/udp_packet_interface.cpp b/tests/components/udp/udp_packet_interface.cpp index c183c52bcea..3174e9cd069 100644 --- a/tests/components/udp/udp_packet_interface.cpp +++ b/tests/components/udp/udp_packet_interface.cpp @@ -20,17 +20,19 @@ using packet_interface::PacketBuffer; using packet_interface::PacketMetaData; using Packet = std::vector; -class TestUdp : public UdpPacketInterface { +// The copy buffer is a base, so it is set up before the link's constructor sees it +struct UdpBufferStorage { + uint8_t tx_buffer_storage[8]{}; +}; + +class TestUdp : public UdpBufferStorage, public UdpPacketInterface { public: explicit TestUdp(UDPComponent *udp) : UdpPacketInterface(udp, this->tx_buffer_storage) { - this->set_max_packet_size(8); this->add_packet_interface_listener( [this](const PacketBuffer &data, const PacketMetaData &) { this->received.push_back(to_vector(data)); }); } using UdpPacketInterface::receive_; - // The base class only keeps the pointer, so the storage can be a member set up after it - uint8_t tx_buffer_storage[8]{}; std::vector received; }; @@ -71,16 +73,6 @@ TEST_F(UdpPacketInterfaceTest, OversizedPacketNotSent) { EXPECT_FALSE(this->link_.send_to_interface(PacketBuffer(&header, 1, &body, nullptr, 0), {})); } -TEST_F(UdpPacketInterfaceTest, SplitPacketLimitedToBuffer) { - this->link_.setup(); - // Raised above the copy buffer after code generation sized it - this->link_.set_max_packet_size(100); - uint8_t header = 0; - Packet body_data{1, 2, 3, 4, 5, 6, 7, 8}; - PacketBuffer body(body_data); - EXPECT_FALSE(this->link_.send_to_interface(PacketBuffer(&header, 1, &body, nullptr, 0), {})); -} - } // namespace esphome::udp::testing #endif