From f72130d074283357903f6b21fedd21180b74cc85 Mon Sep 17 00:00:00 2001 From: clydebarrow <2366188+clydebarrow@users.noreply.github.com> Date: Mon, 19 Oct 2026 11:18:23 +1100 Subject: [PATCH] [entity_transport] Fail when the packet buffer cannot be allocated Co-Authored-By: Claude Opus 5.5 --- .../entity_transport/entity_transport.cpp | 15 ++++++++++----- .../entity_transport/entity_transport.h | 3 +-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/esphome/components/entity_transport/entity_transport.cpp b/esphome/components/entity_transport/entity_transport.cpp index 85fe93acba7..40d1eb8a99f 100644 --- a/esphome/components/entity_transport/entity_transport.cpp +++ b/esphome/components/entity_transport/entity_transport.cpp @@ -58,7 +58,12 @@ void EntityTransport::setup() { this->mark_failed(LOG_STR("max_packet_size too small for the device name and entity ids")); return; } - this->buffer_ = std::make_unique(this->max_packet_size_); + RAMAllocator allocator; + this->buffer_ = allocator.allocate(this->max_packet_size_); + if (this->buffer_ == nullptr) { + this->mark_failed(LOG_STR("Not enough memory for the packet buffer")); + return; + } // The dictionary id changes when the device name or any entity changes uint32_t hash = fnv1a_hash(name.c_str()); for (const auto &entity : this->entities_) { @@ -163,12 +168,12 @@ void EntityTransport::loop() { size_t EntityTransport::write_header_(uint8_t type) const { this->buffer_[0] = type; - put_uint32(this->buffer_.get() + 1, this->dictionary_id_); + put_uint32(this->buffer_ + 1, this->dictionary_id_); return HEADER_SIZE; } bool EntityTransport::send_dictionary_() { - uint8_t *buf = this->buffer_.get(); + uint8_t *buf = this->buffer_; const auto &name = App.get_name(); size_t header = this->write_header_(PACKET_DICTIONARY); buf[header++] = name.size(); @@ -227,7 +232,7 @@ bool EntityTransport::send_updated_() { this->buffer_[SENSOR_COUNT_OFFSET] = 0; first = i; } - uint8_t *record = this->buffer_.get() + length; + uint8_t *record = this->buffer_ + length; record[0] = entity.number; #ifdef USE_SENSOR if (entity.is_sensor) { @@ -253,7 +258,7 @@ bool EntityTransport::send_updated_() { bool EntityTransport::flush_(size_t length, size_t first, size_t last) { if (length == DATA_HEADER_SIZE) return true; - if (!this->interface_->send_to_interface(PacketBuffer(this->buffer_.get(), length), {})) { + if (!this->interface_->send_to_interface(PacketBuffer(this->buffer_, length), {})) { ESP_LOGV(TAG, "Packet of %zu bytes not accepted, will retry", length); return false; } diff --git a/esphome/components/entity_transport/entity_transport.h b/esphome/components/entity_transport/entity_transport.h index 360e26a557b..b1c0a88c91f 100644 --- a/esphome/components/entity_transport/entity_transport.h +++ b/esphome/components/entity_transport/entity_transport.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include "esphome/components/packet_interface/packet_interface.h" @@ -130,7 +129,7 @@ class EntityTransport : public Component { remote_binary_sensors_; #endif // Packets are built here, allocated in setup() - std::unique_ptr buffer_; + uint8_t *buffer_{nullptr}; size_t max_packet_size_{0}; uint32_t update_interval_ms_{0}; uint32_t remote_timeout_ms_{0};