3#ifdef USE_API_PLAINTEXT
19static const char *
const TAG =
"api.plaintext";
21#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
23#ifdef HELPER_LOG_PACKETS
24#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
25#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str())
27#define LOG_PACKET_RECEIVED(buffer) ((void) 0)
28#define LOG_PACKET_SENDING(data, len) ((void) 0)
59 if (frame ==
nullptr) {
60 HELPER_LOG(
"Bad argument for try_read_frame_");
94 HELPER_LOG(
"Header buffer overflow");
116 uint8_t varint_pos = 1;
117 uint32_t consumed = 0;
120 if (!msg_size_varint.has_value()) {
125 if (msg_size_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
127 HELPER_LOG(
"Bad packet: message size %" PRIu32
" exceeds maximum %u", msg_size_varint->as_uint32(),
128 std::numeric_limits<uint16_t>::max());
134 varint_pos += consumed;
137 if (!msg_type_varint.has_value()) {
141 if (msg_type_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
143 HELPER_LOG(
"Bad packet: message type %" PRIu32
" exceeds maximum %u", msg_type_varint->as_uint32(),
144 std::numeric_limits<uint16_t>::max());
166 if (
static_cast<uint16_t
>(received) != to_read) {
188 std::vector<uint8_t> frame;
204 static constexpr uint8_t INDICATOR_MSG_SIZE = 19;
206 static const char MSG_PROGMEM[]
PROGMEM =
"\x00"
207 "Bad indicator byte";
208 char msg[INDICATOR_MSG_SIZE];
209 memcpy_P(msg, MSG_PROGMEM, INDICATOR_MSG_SIZE);
212 static const char MSG[] =
"\x00"
213 "Bad indicator byte";
216 iov[0].
iov_len = INDICATOR_MSG_SIZE;
238 if (packets.empty()) {
242 std::vector<uint8_t> *raw_buffer = buffer.
get_buffer();
243 uint8_t *buffer_data = raw_buffer->data();
247 uint16_t total_write_len = 0;
249 for (
const auto &packet : packets) {
253 uint8_t total_header_len = 1 + size_varint_len + type_varint_len;
280 uint8_t *buf_start = buffer_data + packet.offset;
284 buf_start[header_offset] = 0x00;
292 size_t packet_len =
static_cast<size_t>(total_header_len + packet.payload_size);
293 this->
reusable_iovs_.push_back({buf_start + header_offset, packet_len});
294 total_write_len += packet_len;
APIError handle_socket_read_result_(ssize_t received)
std::vector< uint8_t > rx_buf_
std::vector< struct iovec > reusable_iovs_
uint8_t frame_header_padding_
APIError write_raw_(const struct iovec *iov, int iovcnt, uint16_t total_write_len)
APIError try_read_frame_(std::vector< uint8_t > *frame)
Read a packet into the rx_buf_.
uint8_t rx_header_buf_[6]
uint16_t rx_header_parsed_type_
APIError init() override
Initialize the frame helper, returns OK if successful.
uint16_t rx_header_parsed_len_
APIError write_protobuf_packets(ProtoWriteBuffer buffer, std::span< const PacketInfo > packets) override
APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) override
APIError read_packet(ReadPacketBuffer *buffer) override
uint8_t rx_header_buf_pos_
static constexpr uint32_t varint(uint32_t value)
Calculates the size in bytes needed to encode a uint32_t value as a varint.
Representation of a VarInt - in ProtoBuf should be 64bit but we only use 32bit.
void encode_to_buffer_unchecked(uint8_t *buffer, size_t len)
Encode the varint value to a pre-allocated buffer without bounds checking.
static optional< ProtoVarInt > parse(const uint8_t *buffer, uint32_t len, uint32_t *consumed)
std::vector< uint8_t > * get_buffer() const
virtual ssize_t read(void *buf, size_t len)=0
std::vector< uint8_t > container
const uint8_t ESPHOME_WEBSERVER_INDEX_HTML[] PROGMEM