Merge remote-tracking branch 'upstream/dev' into add_api_stats

This commit is contained in:
J. Nick Koston 2025-05-22 21:29:11 -05:00
commit f0b311f839
No known key found for this signature in database
4 changed files with 18 additions and 12 deletions

View File

@ -887,7 +887,7 @@ APIError APIPlaintextFrameHelper::try_read_frame_(ParsedFrame *frame) {
// - At least 2 bytes in the buffer for the varints // - At least 2 bytes in the buffer for the varints
// Buffer layout: // Buffer layout:
// First 1-3 bytes: Message size varint (variable length) // First 1-3 bytes: Message size varint (variable length)
// - 2 bytes would only allow up to 16383, which is less than noise's 65535 // - 2 bytes would only allow up to 16383, which is less than noise's UINT16_MAX (65535)
// - 3 bytes allows up to 2097151, ensuring we support at least as much as noise // - 3 bytes allows up to 2097151, ensuring we support at least as much as noise
// Remaining 1-2 bytes: Message type varint (variable length) // Remaining 1-2 bytes: Message type varint (variable length)
// We now attempt to parse both varints. If either is incomplete, // We now attempt to parse both varints. If either is incomplete,
@ -900,9 +900,10 @@ APIError APIPlaintextFrameHelper::try_read_frame_(ParsedFrame *frame) {
continue; continue;
} }
if (msg_size_varint->as_uint32() > 65535) { if (msg_size_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
state_ = State::FAILED; state_ = State::FAILED;
HELPER_LOG("Bad packet: message size %" PRIu32 " exceeds maximum 65535", msg_size_varint->as_uint32()); HELPER_LOG("Bad packet: message size %" PRIu32 " exceeds maximum %u", msg_size_varint->as_uint32(),
std::numeric_limits<uint16_t>::max());
return APIError::BAD_DATA_PACKET; return APIError::BAD_DATA_PACKET;
} }
rx_header_parsed_len_ = msg_size_varint->as_uint16(); rx_header_parsed_len_ = msg_size_varint->as_uint16();
@ -912,9 +913,10 @@ APIError APIPlaintextFrameHelper::try_read_frame_(ParsedFrame *frame) {
// not enough data there yet // not enough data there yet
continue; continue;
} }
if (msg_type_varint->as_uint32() > 65535) { if (msg_type_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
state_ = State::FAILED; state_ = State::FAILED;
HELPER_LOG("Bad packet: message type %" PRIu32 " exceeds maximum 65535", msg_type_varint->as_uint32()); HELPER_LOG("Bad packet: message type %" PRIu32 " exceeds maximum %u", msg_type_varint->as_uint32(),
std::numeric_limits<uint16_t>::max());
return APIError::BAD_DATA_PACKET; return APIError::BAD_DATA_PACKET;
} }
rx_header_parsed_type_ = msg_type_varint->as_uint16(); rx_header_parsed_type_ = msg_type_varint->as_uint16();

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <deque> #include <deque>
#include <limits>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -101,7 +102,7 @@ class APIFrameHelper {
std::vector<uint8_t> data; std::vector<uint8_t> data;
uint16_t offset{0}; // Current offset within the buffer (uint16_t to reduce memory usage) uint16_t offset{0}; // Current offset within the buffer (uint16_t to reduce memory usage)
// Using uint16_t reduces memory usage since ESPHome API messages are limited to 64KB max // Using uint16_t reduces memory usage since ESPHome API messages are limited to UINT16_MAX (65535) bytes
uint16_t remaining() const { return static_cast<uint16_t>(data.size()) - offset; } uint16_t remaining() const { return static_cast<uint16_t>(data.size()) - offset; }
const uint8_t *current_data() const { return data.data() + offset; } const uint8_t *current_data() const { return data.data() + offset; }
}; };
@ -192,7 +193,7 @@ class APINoiseFrameHelper : public APIFrameHelper {
void send_explicit_handshake_reject_(const std::string &reason); void send_explicit_handshake_reject_(const std::string &reason);
// Fixed-size header buffer for noise protocol: // Fixed-size header buffer for noise protocol:
// 1 byte for indicator + 2 bytes for message size (16-bit value, not varint) // 1 byte for indicator + 2 bytes for message size (16-bit value, not varint)
// Note: Maximum message size is 65535, with a limit of 128 bytes during handshake phase // Note: Maximum message size is UINT16_MAX (65535), with a limit of 128 bytes during handshake phase
uint8_t rx_header_buf_[3]; uint8_t rx_header_buf_[3];
uint8_t rx_header_buf_len_ = 0; uint8_t rx_header_buf_len_ = 0;
@ -230,7 +231,7 @@ class APIPlaintextFrameHelper : public APIFrameHelper {
APIError try_read_frame_(ParsedFrame *frame); APIError try_read_frame_(ParsedFrame *frame);
// Fixed-size header buffer for plaintext protocol: // Fixed-size header buffer for plaintext protocol:
// We only need space for the two varints since we validate the indicator byte separately. // We only need space for the two varints since we validate the indicator byte separately.
// To match noise protocol's maximum message size (65535), we need: // To match noise protocol's maximum message size (UINT16_MAX = 65535), we need:
// 3 bytes for message size varint (supports up to 2097151) + 2 bytes for message type varint // 3 bytes for message size varint (supports up to 2097151) + 2 bytes for message type varint
// //
// While varints could theoretically be up to 10 bytes each for 64-bit values, // While varints could theoretically be up to 10 bytes each for 64-bit values,

View File

@ -25,6 +25,7 @@ from esphome.const import (
CONF_HARDWARE_UART, CONF_HARDWARE_UART,
CONF_ID, CONF_ID,
CONF_LEVEL, CONF_LEVEL,
CONF_LOGGER,
CONF_LOGS, CONF_LOGS,
CONF_ON_MESSAGE, CONF_ON_MESSAGE,
CONF_TAG, CONF_TAG,
@ -250,6 +251,7 @@ CONFIG_SCHEMA = cv.All(
async def to_code(config): async def to_code(config):
baud_rate = config[CONF_BAUD_RATE] baud_rate = config[CONF_BAUD_RATE]
level = config[CONF_LEVEL] level = config[CONF_LEVEL]
CORE.data.setdefault(CONF_LOGGER, {})[CONF_LEVEL] = level
initial_level = LOG_LEVELS[config.get(CONF_INITIAL_LEVEL, level)] initial_level = LOG_LEVELS[config.get(CONF_INITIAL_LEVEL, level)]
log = cg.new_Pvariable( log = cg.new_Pvariable(
config[CONF_ID], config[CONF_ID],

View File

@ -5,7 +5,7 @@ from esphome.const import CONF_LEVEL, CONF_LOGGER, ENTITY_CATEGORY_CONFIG, ICON_
from esphome.core import CORE from esphome.core import CORE
from esphome.cpp_helpers import register_component, register_parented from esphome.cpp_helpers import register_component, register_parented
from .. import CONF_LOGGER_ID, LOG_LEVEL_SEVERITY, Logger, logger_ns from .. import CONF_LOGGER_ID, LOG_LEVELS, Logger, logger_ns
CODEOWNERS = ["@clydebarrow"] CODEOWNERS = ["@clydebarrow"]
@ -21,9 +21,10 @@ CONFIG_SCHEMA = select.select_schema(
async def to_code(config): async def to_code(config):
levels = LOG_LEVEL_SEVERITY parent = await cg.get_variable(config[CONF_LOGGER_ID])
index = levels.index(CORE.config[CONF_LOGGER][CONF_LEVEL]) levels = list(LOG_LEVELS)
index = levels.index(CORE.data[CONF_LOGGER][CONF_LEVEL])
levels = levels[: index + 1] levels = levels[: index + 1]
var = await select.new_select(config, options=levels) var = await select.new_select(config, options=levels)
await register_parented(var, config[CONF_LOGGER_ID]) await register_parented(var, parent)
await register_component(var, config) await register_component(var, config)