3#ifdef USE_API_PLAINTEXT
18static const char *
const TAG =
"api.plaintext";
21static constexpr size_t API_MAX_LOG_BYTES = 168;
23#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
24#define HELPER_LOG(msg, ...) \
26 char peername_buf[socket::SOCKADDR_STR_LEN]; \
27 this->get_peername_to(peername_buf); \
28 ESP_LOGVV(TAG, "%s (%s): " msg, this->client_name_, peername_buf, ##__VA_ARGS__); \
31#define HELPER_LOG(msg, ...) ((void) 0)
34#ifdef HELPER_LOG_PACKETS
35#define LOG_PACKET_RECEIVED(buffer) \
37 char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \
38 ESP_LOGVV(TAG, "Received frame: %s", \
39 format_hex_pretty_to(hex_buf_, (buffer).data(), \
40 (buffer).size() < API_MAX_LOG_BYTES ? (buffer).size() : API_MAX_LOG_BYTES)); \
42#define LOG_PACKET_SENDING(data, len) \
44 char hex_buf_[format_hex_pretty_size(API_MAX_LOG_BYTES)]; \
45 ESP_LOGVV(TAG, "Sending raw: %s", \
46 format_hex_pretty_to(hex_buf_, data, (len) < API_MAX_LOG_BYTES ? (len) : API_MAX_LOG_BYTES)); \
49#define LOG_PACKET_RECEIVED(buffer) ((void) 0)
50#define LOG_PACKET_SENDING(data, len) ((void) 0)
108 HELPER_LOG(
"Header buffer overflow");
130 uint8_t varint_pos = 1;
131 uint32_t consumed = 0;
134 if (!msg_size_varint.has_value()) {
139 if (msg_size_varint->as_uint32() > MAX_MESSAGE_SIZE) {
141 HELPER_LOG(
"Bad packet: message size %" PRIu32
" exceeds maximum %u", msg_size_varint->as_uint32(),
148 varint_pos += consumed;
151 if (!msg_type_varint.has_value()) {
155 if (msg_type_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
157 HELPER_LOG(
"Bad packet: message type %" PRIu32
" exceeds maximum %u", msg_type_varint->as_uint32(),
158 std::numeric_limits<uint16_t>::max());
167 if (this->
rx_buf_.size() != this->rx_header_parsed_len_) {
180 if (
static_cast<uint16_t
>(received) != to_read) {
186 LOG_PACKET_RECEIVED(this->
rx_buf_);
216 static constexpr uint8_t INDICATOR_MSG_SIZE = 19;
218 static const char MSG_PROGMEM[]
PROGMEM =
"\x00"
219 "Bad indicator byte";
220 char msg[INDICATOR_MSG_SIZE];
221 memcpy_P(msg, MSG_PROGMEM, INDICATOR_MSG_SIZE);
224 static const char MSG[] =
"\x00"
225 "Bad indicator byte";
228 iov[0].
iov_len = INDICATOR_MSG_SIZE;
245 std::span<const MessageInfo> messages) {
250 if (messages.empty()) {
254 uint8_t *buffer_data = buffer.
get_buffer()->data();
258 uint16_t total_write_len = 0;
260 for (
const auto &msg : messages) {
264 uint8_t total_header_len = 1 + size_varint_len + type_varint_len;
291 uint8_t *buf_start = buffer_data + msg.offset;
295 buf_start[header_offset] = 0x00;
302 size_t msg_len =
static_cast<size_t>(total_header_len + msg.payload_size);
303 iovs.
push_back({buf_start + header_offset, msg_len});
304 total_write_len += msg_len;
Minimal static vector - saves memory by avoiding std::vector overhead.
void push_back(const T &value)
APIError handle_socket_read_result_(ssize_t received)
std::vector< uint8_t > rx_buf_
uint8_t frame_header_padding_
std::unique_ptr< socket::Socket > socket_
APIError write_raw_(const struct iovec *iov, int iovcnt, uint16_t total_write_len)
uint8_t rx_header_buf_[6]
uint16_t rx_header_parsed_type_
APIError try_read_frame_()
Read a packet into the rx_buf_.
APIError init() override
Initialize the frame helper, returns OK if successful.
uint16_t rx_header_parsed_len_
APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) override
APIError read_packet(ReadPacketBuffer *buffer) override
uint8_t rx_header_buf_pos_
APIError write_protobuf_messages(ProtoWriteBuffer buffer, std::span< const MessageInfo > messages) override
static constexpr uint32_t varint(uint32_t value)
Calculates the size in bytes needed to encode a uint32_t value as a varint.
static optional< ProtoVarInt > parse(const uint8_t *buffer, uint32_t len, uint32_t *consumed)
Parse a varint from buffer. consumed must be a valid pointer (not null).
std::vector< uint8_t > * get_buffer() const
void encode_varint_to_buffer(uint32_t val, uint8_t *buffer)
Encode a varint directly into a pre-allocated buffer.
const uint8_t ESPHOME_WEBSERVER_INDEX_HTML[] PROGMEM