diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index c18bba0bee8..88bbbe697fb 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -112,13 +112,7 @@ APIError APIFrameHelper::drain_overflow_and_handle_errors_() { return APIError::OK; } -// Single-buffer slow path: wraps data in iovec and delegates to the iovec slow path. -APIError APIFrameHelper::write_raw_slow_(const void *data, uint16_t len, ssize_t sent) { - struct iovec iov = {const_cast(data), len}; - return this->write_raw_slow_(&iov, 1, len, sent); -} - -// Multi-buffer slow path: handles partial writes, errors, and overflow buffering. +// Slow path: handles partial writes, errors, and overflow buffering. // Called when the inline fast path in the header couldn't complete the write. // sent == -1 means either the fast path write returned -1, or there was overflow backlog. APIError APIFrameHelper::write_raw_slow_(const struct iovec *iov, int iovcnt, uint16_t total_write_len, ssize_t sent) { diff --git a/esphome/components/api/api_frame_helper.h b/esphome/components/api/api_frame_helper.h index f8f9bf81ef2..d9bd5efa373 100644 --- a/esphome/components/api/api_frame_helper.h +++ b/esphome/components/api/api_frame_helper.h @@ -200,7 +200,8 @@ class APIFrameHelper { if (sent == static_cast(len)) [[likely]] return APIError::OK; } - return this->write_raw_slow_(data, len, sent); + struct iovec iov = {const_cast(data), len}; + return this->write_raw_slow_(&iov, 1, len, sent); } inline APIError ESPHOME_ALWAYS_INLINE write_raw_fast_(const struct iovec *iov, int iovcnt, uint16_t total_write_len) { ssize_t sent = -1; @@ -212,9 +213,7 @@ class APIFrameHelper { return this->write_raw_slow_(iov, iovcnt, total_write_len, sent); } - // Write methods — used by cold paths (handshake, error handling) - // These go through the slow path directly, avoiding inlining the fast path at the call site. - APIError write_raw_slow_(const void *data, uint16_t len, ssize_t sent); + // Slow path (out-of-line): handle partial writes, errors, overflow buffering APIError write_raw_slow_(const struct iovec *iov, int iovcnt, uint16_t total_write_len, ssize_t sent); // Socket ownership (4 bytes on 32-bit, 8 bytes on 64-bit) diff --git a/esphome/components/api/api_frame_helper_noise.cpp b/esphome/components/api/api_frame_helper_noise.cpp index 4b8b2f97069..150a110eb32 100644 --- a/esphome/components/api/api_frame_helper_noise.cpp +++ b/esphome/components/api/api_frame_helper_noise.cpp @@ -540,7 +540,8 @@ APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, uint16_t len) { header[2] = (uint8_t) len; if (len == 0) { - return this->write_raw_slow_(header, 3, -1); + struct iovec iov = {header, 3}; + return this->write_raw_slow_(&iov, 1, 3, -1); } struct iovec iov[2]; iov[0].iov_base = header; diff --git a/esphome/components/api/api_frame_helper_plaintext.cpp b/esphome/components/api/api_frame_helper_plaintext.cpp index cb97f9d3942..5a887801d55 100644 --- a/esphome/components/api/api_frame_helper_plaintext.cpp +++ b/esphome/components/api/api_frame_helper_plaintext.cpp @@ -219,11 +219,13 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) { "Bad indicator byte"; char msg[INDICATOR_MSG_SIZE]; memcpy_P(msg, MSG_PROGMEM, INDICATOR_MSG_SIZE); - this->write_raw_slow_(msg, INDICATOR_MSG_SIZE, -1); + struct iovec iov = {msg, INDICATOR_MSG_SIZE}; + this->write_raw_slow_(&iov, 1, INDICATOR_MSG_SIZE, -1); #else static const char MSG[] = "\x00" "Bad indicator byte"; - this->write_raw_slow_(MSG, INDICATOR_MSG_SIZE, -1); + struct iovec iov = {const_cast(MSG), INDICATOR_MSG_SIZE}; + this->write_raw_slow_(&iov, 1, INDICATOR_MSG_SIZE, -1); #endif } return aerr;