This commit is contained in:
J. Nick Koston 2025-07-11 11:46:03 -10:00
parent 3ed533d709
commit 0350471fa9
No known key found for this signature in database
3 changed files with 4 additions and 38 deletions

View File

@ -1614,11 +1614,6 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
if (err == APIError::WOULD_BLOCK)
return false;
if (err != APIError::OK) {
if (err == APIError::MESSAGE_TOO_LARGE) {
// Log error for oversized messages - safe here since we're not in the middle of encoding
ESP_LOGE(TAG, "%s: Message type %u is too large to send (exceeds %u byte limit)",
this->get_client_combined_info().c_str(), message_type, PacketInfo::MAX_PAYLOAD_SIZE);
}
on_fatal_error();
if (err == APIError::SOCKET_WRITE_FAILED && errno == ECONNRESET) {
ESP_LOGW(TAG, "%s: Connection reset", this->get_client_combined_info().c_str());

View File

@ -62,8 +62,6 @@ const char *api_error_to_str(APIError err) {
return "BAD_HANDSHAKE_ERROR_BYTE";
} else if (err == APIError::CONNECTION_CLOSED) {
return "CONNECTION_CLOSED";
} else if (err == APIError::MESSAGE_TOO_LARGE) {
return "MESSAGE_TOO_LARGE";
}
return "UNKNOWN";
}
@ -621,11 +619,6 @@ APIError APINoiseFrameHelper::write_protobuf_packet(uint8_t type, ProtoWriteBuff
uint16_t payload_size =
static_cast<uint16_t>(buffer.get_buffer()->size() - frame_header_padding_ - frame_footer_size_);
// Check if message exceeds PacketInfo limits
if (payload_size > PacketInfo::MAX_PAYLOAD_SIZE) {
return APIError::MESSAGE_TOO_LARGE;
}
PacketInfo packet{type, 0, payload_size};
return write_protobuf_packets(buffer, std::span<const PacketInfo>(&packet, 1));
}
@ -1014,11 +1007,6 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
APIError APIPlaintextFrameHelper::write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) {
uint16_t payload_size = static_cast<uint16_t>(buffer.get_buffer()->size() - frame_header_padding_);
// Check if message exceeds PacketInfo limits
if (payload_size > PacketInfo::MAX_PAYLOAD_SIZE) {
return APIError::MESSAGE_TOO_LARGE;
}
PacketInfo packet{type, 0, payload_size};
return write_protobuf_packets(buffer, std::span<const PacketInfo>(&packet, 1));
}

View File

@ -28,27 +28,11 @@ struct ReadPacketBuffer {
uint16_t data_len;
};
// Packet info structure - packed into 4 bytes using bit fields
// Note: While the API protocol supports message sizes up to 65535 (uint16_t),
// we limit offset to 2047 (11 bits) and payload_size to 8191 (13 bits) for practical reasons:
// 1. Messages larger than 8KB are rare but do occur (e.g., select entities with many options)
// 2. Very large messages may cause memory pressure on constrained devices
// 3. The typical MTU-based batch size (MAX_BATCH_PACKET_SIZE) is 1390 bytes
//
// Why MAX_OFFSET (2047) > MAX_BATCH_PACKET_SIZE (1390):
// When batching, messages are only included if the total batch size stays under
// MAX_BATCH_PACKET_SIZE. However, we need extra headroom in MAX_OFFSET for:
// - Protocol headers and padding for each message in the batch
// - Future protocol extensions that might need additional offset space
// Large messages (> MAX_BATCH_PACKET_SIZE) are sent individually with offset=0.
// Packet info structure for batching multiple messages
struct PacketInfo {
static constexpr uint16_t MAX_OFFSET = 2047; // 11 bits max
static constexpr uint16_t MAX_PAYLOAD_SIZE = 8191; // 13 bits max
uint32_t message_type : 8; // 8 bits: 0-255
uint32_t offset : 11; // 11 bits: 0-2047
uint32_t payload_size : 13; // 13 bits: 0-8191
// Total: 32 bits = 4 bytes exactly
uint8_t message_type; // Message type (0-255)
uint16_t offset; // Offset in buffer where message starts
uint16_t payload_size; // Size of the message payload
PacketInfo(uint8_t type, uint16_t off, uint16_t size) : message_type(type), offset(off), payload_size(size) {}
};
@ -77,7 +61,6 @@ enum class APIError : uint16_t {
HANDSHAKESTATE_SPLIT_FAILED = 1020,
BAD_HANDSHAKE_ERROR_BYTE = 1021,
CONNECTION_CLOSED = 1022,
MESSAGE_TOO_LARGE = 1023,
};
const char *api_error_to_str(APIError err);