Skip to content

Commit 979a28a

Browse files
committed
feat: smart decoder with RPC packet parsing
1 parent 880b3e4 commit 979a28a

File tree

2 files changed

+78
-10
lines changed

2 files changed

+78
-10
lines changed

examples/decoder_example/decoder_example.ino

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#define DEBUG
12
#include <Arduino_RPClite.h>
23

34
void blink_before(){
@@ -27,16 +28,29 @@ void loop() {
2728
blink_before();
2829
MsgPack::arr_size_t req_sz(4);
2930
MsgPack::arr_size_t par_sz(2);
31+
packer.clear();
3032
packer.serialize(req_sz, 0, 1, "method", par_sz, 1.0, 2.0);
3133

3234
DummyTransport dummy_transport(packer.data(), packer.size());
3335
RpcDecoder<> decoder(dummy_transport);
3436

3537
while (!decoder.packet_available()){
38+
decoder.print_buffer();
3639
Serial.println("Packet not ready");
3740
decoder.advance();
41+
uint8_t decoded = decoder.parse_packet();
42+
if (decoded > 0){
43+
Serial.print("Bytes decoded: ");
44+
Serial.println(decoded);
45+
}
46+
decoder.print_buffer();
47+
delay(100);
48+
}
49+
50+
if (decoder.packet_available()){
51+
Serial.print("packet ready. size: ");
52+
Serial.println(decoder.packet_size());
3853
}
3954

40-
Serial.println("packet ready");
4155

4256
}

src/decoder.h

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,29 +43,68 @@ class RpcDecoder {
4343
}
4444

4545
// Tries to parse the first packet only
46-
void parse_packet(){
46+
size_t parse_packet(){
4747

4848
// Nop in case 1st packet is ready... waiting to deliver
49-
if (_packet_ready){return;}
49+
if (_packet_ready){return _packet_size;}
5050

51-
size_t bytes_checked = 0;
51+
size_t bytes_checked = 3;
5252

53-
MsgPack::Unpacker unpacker;
5453
while (bytes_checked < _bytes_stored) {
55-
if (unpacker.feed(_raw_buffer, bytes_checked)) {
54+
bytes_checked++;
55+
56+
if (is_packet_complete(bytes_checked)) {
5657
_packet_ready = true;
57-
_packet_size = bytes_checked + 1;
58-
return;
59-
} else {
60-
bytes_checked++;
58+
_packet_size = bytes_checked;
59+
break;
6160
}
6261
}
6362

63+
return _packet_size;
64+
65+
}
66+
67+
bool is_packet_complete(size_t size) {
68+
69+
static MsgPack::Unpacker unpacker;
70+
unpacker.clear();
71+
72+
if (unpacker.feed(_raw_buffer, size)){
73+
size_t min_packet_indices;
74+
75+
MsgPack::arr_size_t elem_size;
76+
if (unpacker.deserialize(elem_size)){
77+
min_packet_indices = elem_size.size() + 1;
78+
if (unpacker.size() < min_packet_indices) return false;
79+
int type;
80+
if (unpacker.deserialize(type)) {
81+
if (type == 0 || type == 1) { // request or response
82+
int _id;
83+
MsgPack::str_t callback;
84+
MsgPack::arr_size_t param_size;
85+
unpacker.deserialize(_id, callback, param_size);
86+
return (unpacker.size() == min_packet_indices + param_size.size());
87+
} else if (type == 2) { // notification
88+
MsgPack::str_t callback;
89+
MsgPack::arr_size_t param_size;
90+
unpacker.deserialize(callback, param_size);
91+
return (unpacker.size() == min_packet_indices + param_size.size());
92+
}
93+
}
94+
95+
}
96+
97+
}
98+
99+
return false;
100+
64101
}
65102

66103
// Check if a packet is available
67104
bool packet_available() const { return _packet_ready; }
68105

106+
size_t packet_size() const {return _packet_size;}
107+
69108
// Get the oldest packet (returns false if no packet available)
70109
bool get_next_packet(MsgPack::Unpacker& unpacker) {
71110
if (!_packet_ready) return false;
@@ -100,6 +139,21 @@ class RpcDecoder {
100139
return _packet_size;
101140
}
102141

142+
#ifdef DEBUG
143+
void print_buffer(){
144+
145+
Serial.print("buf size: ");
146+
Serial.print(_bytes_stored);
147+
Serial.print(" : ");
148+
149+
for (size_t i = 0; i < _bytes_stored; i++) {
150+
Serial.print(_raw_buffer[i], HEX);
151+
Serial.print(" ");
152+
}
153+
Serial.println();
154+
}
155+
#endif
156+
103157
private:
104158
ITransport& _transport;
105159
uint8_t _raw_buffer[BufferSize];

0 commit comments

Comments
 (0)