ESPHome 2025.6.2
Loading...
Searching...
No Matches
proto.cpp
Go to the documentation of this file.
1#include "proto.h"
2#include <cinttypes>
4#include "esphome/core/log.h"
5
6namespace esphome {
7namespace api {
8
9static const char *const TAG = "api.proto";
10
11void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
12 uint32_t i = 0;
13 bool error = false;
14 while (i < length) {
15 uint32_t consumed;
16 auto res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
17 if (!res.has_value()) {
18 ESP_LOGV(TAG, "Invalid field start at %" PRIu32, i);
19 break;
20 }
21
22 uint32_t field_type = (res->as_uint32()) & 0b111;
23 uint32_t field_id = (res->as_uint32()) >> 3;
24 i += consumed;
25
26 switch (field_type) {
27 case 0: { // VarInt
28 res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
29 if (!res.has_value()) {
30 ESP_LOGV(TAG, "Invalid VarInt at %" PRIu32, i);
31 error = true;
32 break;
33 }
34 if (!this->decode_varint(field_id, *res)) {
35 ESP_LOGV(TAG, "Cannot decode VarInt field %" PRIu32 " with value %" PRIu32 "!", field_id, res->as_uint32());
36 }
37 i += consumed;
38 break;
39 }
40 case 2: { // Length-delimited
41 res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
42 if (!res.has_value()) {
43 ESP_LOGV(TAG, "Invalid Length Delimited at %" PRIu32, i);
44 error = true;
45 break;
46 }
47 uint32_t field_length = res->as_uint32();
48 i += consumed;
49 if (field_length > length - i) {
50 ESP_LOGV(TAG, "Out-of-bounds Length Delimited at %" PRIu32, i);
51 error = true;
52 break;
53 }
54 if (!this->decode_length(field_id, ProtoLengthDelimited(&buffer[i], field_length))) {
55 ESP_LOGV(TAG, "Cannot decode Length Delimited field %" PRIu32 "!", field_id);
56 }
57 i += field_length;
58 break;
59 }
60 case 5: { // 32-bit
61 if (length - i < 4) {
62 ESP_LOGV(TAG, "Out-of-bounds Fixed32-bit at %" PRIu32, i);
63 error = true;
64 break;
65 }
66 uint32_t val = encode_uint32(buffer[i + 3], buffer[i + 2], buffer[i + 1], buffer[i]);
67 if (!this->decode_32bit(field_id, Proto32Bit(val))) {
68 ESP_LOGV(TAG, "Cannot decode 32-bit field %" PRIu32 " with value %" PRIu32 "!", field_id, val);
69 }
70 i += 4;
71 break;
72 }
73 default:
74 ESP_LOGV(TAG, "Invalid field type at %" PRIu32, i);
75 error = true;
76 break;
77 }
78 if (error) {
79 break;
80 }
81 }
82}
83
84#ifdef HAS_PROTO_MESSAGE_DUMP
85std::string ProtoMessage::dump() const {
86 std::string out;
87 this->dump_to(out);
88 return out;
89}
90#endif
91
92} // namespace api
93} // namespace esphome
std::string dump() const
Definition proto.cpp:85
virtual bool decode_32bit(uint32_t field_id, Proto32Bit value)
Definition proto.h:341
virtual void dump_to(std::string &out) const =0
virtual bool decode_length(uint32_t field_id, ProtoLengthDelimited value)
Definition proto.h:340
virtual bool decode_varint(uint32_t field_id, ProtoVarInt value)
Definition proto.h:339
void decode(const uint8_t *buffer, size_t length)
Definition proto.cpp:11
static optional< ProtoVarInt > parse(const uint8_t *buffer, uint32_t len, uint32_t *consumed)
Definition proto.h:22
mopeka_std_values val[4]
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4)
Encode a 32-bit value given four bytes in most to least significant byte order.
Definition helpers.h:200
uint16_t length
Definition tt21100.cpp:0