[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 <noreply@anthropic.com>
This commit is contained in:
clydebarrow
2026-10-19 14:40:33 +11:00
co-authored by Claude Code
parent e633f54997
commit 32c097dfad
3 changed files with 8 additions and 22 deletions
@@ -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);
}
@@ -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<uint8_t> 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,
+6 -14
View File
@@ -20,17 +20,19 @@ using packet_interface::PacketBuffer;
using packet_interface::PacketMetaData;
using Packet = std::vector<uint8_t>;
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<Packet> 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