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