Skip to content

Commit 69b31a0

Browse files
committed
feat: decoder handling measurement and discard of generic RPC messages with test example
1 parent b831ca1 commit 69b31a0

File tree

2 files changed

+119
-48
lines changed

2 files changed

+119
-48
lines changed

examples/decoder_example/decoder_example.ino

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,15 @@ void loop() {
9999
}
100100

101101
// MIXED INCOMING RESPONSE AND REQUEST
102+
Serial.println("-- Discard TEST --");
102103
blink_before();
103104
packer.clear();
104105
packer.serialize(resp_sz, 1, 1, nil, ret_sz, 3.0, 2);
106+
Serial.print("1st packet size: ");
107+
Serial.println(packer.size());
105108
packer.serialize(req_sz, 0, 1, "method", par_sz, 1.0, 2.0);
109+
Serial.print("full size: ");
110+
Serial.println(packer.size());
106111

107112
DummyTransport dummy_transport4(packer.data(), packer.size());
108113
RpcDecoder<> decoder4(dummy_transport4);
@@ -112,53 +117,19 @@ void loop() {
112117
Serial.println("Packet not ready");
113118
decoder4.advance();
114119
decoder4.parse_packet();
115-
decoder4.print_buffer();
116120
delay(100);
117121
}
118122

119-
if (decoder4.packet_incoming()){
120-
Serial.print("packet ready. type: ");
121-
Serial.println(decoder4.packet_type());
122-
123-
// as client knows the expected response types/error
124-
MsgPack::arr_size_t r_resp_sz(4);
125-
MsgPack::object::nil_t nil;
126-
int r_type;
127-
int r_msg_id;
128-
MsgPack::arr_size_t r_ret_sz(2);
129-
float r_float;
130-
int r_int;
131-
132-
Serial.print("Total Decoder buf size: ");
133-
Serial.println(decoder4.size());
134-
for (size_t i=1; i<decoder4.size(); i++){
135-
136-
if (decoder4.get_next_packet(unpacker, i)){
137-
138-
if (unpacker.deserialize(r_resp_sz, r_type, r_msg_id)){
139-
// consistency checks
140-
if (unpacker.unpackable(nil)) { // No error case
141-
if (unpacker.deserialize(nil, r_ret_sz, r_float, r_int)){
142-
// do more checks
143-
// fill the response
144-
Serial.print("Full packet decoded size: ");
145-
Serial.println(i);
146-
decoder4.pop_packet(i);
147-
Serial.print("1st Packet popped. Decoder buf size: ");
148-
Serial.println(decoder4.size());
149-
decoder4.print_buffer();
150-
break; //exit the loop
151-
}
152-
} else {
153-
// unpack the error
154-
}
155-
156-
}
157-
158-
}
159-
160-
}
161-
123+
while (decoder4.packet_incoming()){
124+
decoder4.print_buffer();
125+
size_t removed = decoder4.discard_packet();
126+
Serial.print("Removed bytes: ");
127+
Serial.println(removed);
128+
decoder4.print_buffer();
129+
decoder4.advance();
130+
decoder4.parse_packet();
162131
}
163132

133+
Serial.println("-- END Discard TEST --");
134+
164135
}

src/decoder.h

Lines changed: 104 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,7 @@ class RpcDecoder {
251251
}
252252

253253
size_t discard_packet() {
254-
// todo recursive packet size measurement
255-
// use pop_packet with size
256-
// return popped bytes
257-
return 0;
254+
return pop_packet(get_packet_size());
258255
}
259256

260257
inline size_t size() const {return _bytes_stored;}
@@ -291,6 +288,109 @@ void print_buffer(){
291288
inline size_t send(const uint8_t* data, const size_t size) {
292289
return _transport.write(data, size);
293290
}
291+
292+
size_t get_packet_size(){
293+
294+
size_t bytes_checked = 0;
295+
size_t container_size;
296+
static MsgPack::Unpacker unpacker;
297+
298+
while (bytes_checked < _bytes_stored){
299+
bytes_checked++;
300+
unpacker.clear();
301+
if (!unpacker.feed(_raw_buffer, bytes_checked)) continue;
302+
303+
if (unpackArray(unpacker, container_size)) {
304+
return bytes_checked;
305+
} else {
306+
continue;
307+
}
308+
309+
}
310+
311+
return 0;
312+
}
313+
314+
bool unpackObject(MsgPack::Unpacker& unpacker){
315+
316+
if (unpacker.isNil()){
317+
static MsgPack::object::nil_t nil;
318+
return unpacker.deserialize(nil);
319+
}
320+
if (unpacker.isBool()){
321+
static bool b;
322+
return unpacker.deserialize(b);
323+
}
324+
if (unpacker.isUInt() || unpacker.isInt()){
325+
static int integer;
326+
return unpacker.deserialize(integer);
327+
}
328+
if (unpacker.isFloat32()){
329+
static float num32;
330+
return unpacker.deserialize(num32);
331+
}
332+
if (unpacker.isFloat64()){
333+
static double num64;
334+
return unpacker.deserialize(num64);
335+
}
336+
if (unpacker.isStr()){
337+
static MsgPack::str_t string;
338+
return unpacker.deserialize(string);
339+
}
340+
if (unpacker.isBin()){
341+
static MsgPack::bin_t<uint8_t> bytes;
342+
return unpacker.deserialize(bytes);
343+
}
344+
if (unpacker.isArray()){
345+
static size_t arr_sz;
346+
return unpackArray(unpacker, arr_sz);
347+
}
348+
if (unpacker.isMap()){
349+
static size_t map_sz;
350+
return unpackMap(unpacker, map_sz);
351+
}
352+
if (unpacker.isFixExt() || unpacker.isExt()){
353+
static MsgPack::object::ext e;
354+
return unpacker.deserialize(e);
355+
}
356+
if (unpacker.isTimestamp()){
357+
static MsgPack::object::timespec t;
358+
return unpacker.deserialize(t);
359+
}
360+
361+
return false;
362+
}
363+
364+
bool unpackArray(MsgPack::Unpacker& unpacker, size_t& size) {
365+
366+
static MsgPack::arr_size_t sz;
367+
unpacker.deserialize(sz);
368+
369+
size = 0;
370+
for (size_t i=0; i<sz.size(); i++){
371+
if (unpackObject(unpacker)){
372+
size++;
373+
} else {
374+
return false;
375+
}
376+
}
377+
378+
}
379+
380+
bool unpackMap(MsgPack::Unpacker& unpacker, size_t& size) {
381+
static MsgPack::map_size_t sz;
382+
unpacker.deserialize(sz);
383+
384+
size = 0;
385+
for (size_t i=0; i<sz.size(); i++){
386+
if (unpackObject(unpacker) && unpackObject(unpacker)){ // must unpack key&value
387+
size++;
388+
} else {
389+
return false;
390+
}
391+
}
392+
}
393+
294394
};
295395

296396
#endif

0 commit comments

Comments
 (0)