From bafc57f02ec3d2bc4ba1d381fb82a819a62ca4b8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 15 May 2025 03:06:36 -0500 Subject: [PATCH 1/2] fix refactoring error --- esphome/components/api/api_frame_helper.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index 73efc55824..82ebd531f6 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -283,7 +283,10 @@ APIError APINoiseFrameHelper::loop() { return err; if (this->tx_buf_.empty()) return APIError::OK; - return try_send_tx_buf_(); + err = try_send_tx_buf_(); + if (err == APIError::WOULD_BLOCK) + return APIError::OK; // Convert WOULD_BLOCK to OK to avoid connection termination + return err; } /** Read a packet into the rx_buf_. If successful, stores frame data in the frame parameter @@ -802,7 +805,10 @@ APIError APIPlaintextFrameHelper::loop() { } if (this->tx_buf_.empty()) return APIError::OK; - return try_send_tx_buf_(); + APIError err = try_send_tx_buf_(); + if (err == APIError::WOULD_BLOCK) + return APIError::OK; // Convert WOULD_BLOCK to OK to avoid connection termination + return err; } /** Read a packet into the rx_buf_. If successful, stores frame data in the frame parameter From 2646ec166baf88fe4ccff5f3896c025d4dcee800 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 15 May 2025 03:24:47 -0500 Subject: [PATCH 2/2] save some bytes --- esphome/components/api/api_frame_helper.cpp | 5 +++-- esphome/components/api/api_frame_helper.h | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index 82ebd531f6..2d9bed2174 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -185,9 +185,10 @@ APIError APIFrameHelper::try_send_tx_buf_() { } else if (sent == 0) { // Nothing sent but not an error return APIError::WOULD_BLOCK; - } else if (static_cast(sent) < front_buffer.remaining()) { + } else if (static_cast(sent) < front_buffer.remaining()) { // Partially sent, update offset - front_buffer.offset += sent; + // Cast to ensure no overflow issues with uint16_t + front_buffer.offset += static_cast(sent); return APIError::WOULD_BLOCK; // Stop processing more buffers if we couldn't send a complete buffer } else { // Buffer completely sent, remove it from the queue diff --git a/esphome/components/api/api_frame_helper.h b/esphome/components/api/api_frame_helper.h index 15d9d8664d..f711b091cb 100644 --- a/esphome/components/api/api_frame_helper.h +++ b/esphome/components/api/api_frame_helper.h @@ -121,9 +121,10 @@ class APIFrameHelper { // Buffer containing data to be sent struct SendBuffer { std::vector data; - size_t offset{0}; // Current offset within the buffer + uint16_t offset{0}; // Current offset within the buffer (uint16_t to reduce memory usage) - size_t remaining() const { return data.size() - offset; } + // Using uint16_t reduces memory usage since ESPHome API messages are limited to 64KB max + uint16_t remaining() const { return static_cast(data.size()) - offset; } const uint8_t *current_data() const { return data.data() + offset; } };