Skip to content

Commit a436275

Browse files
committed
mod: dumb decoder defers packet size measurement to user. decoder example
1 parent a0ec7c3 commit a436275

File tree

3 files changed

+127
-80
lines changed

3 files changed

+127
-80
lines changed

examples/decoder_example/decoder_example.ino

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33

44
void blink_before(){
55
digitalWrite(LED_BUILTIN, HIGH);
6-
delay(200);
6+
delay(100);
77
digitalWrite(LED_BUILTIN, LOW);
8-
delay(200);
8+
delay(100);
99
digitalWrite(LED_BUILTIN, HIGH);
10-
delay(200);
10+
delay(100);
1111
digitalWrite(LED_BUILTIN, LOW);
12-
delay(200);
12+
delay(100);
1313
digitalWrite(LED_BUILTIN, HIGH);
14-
delay(200);
14+
delay(100);
1515
digitalWrite(LED_BUILTIN, LOW);
16-
delay(200);
16+
delay(100);
1717
}
1818

1919
MsgPack::Packer packer;
@@ -27,30 +27,74 @@ void loop() {
2727

2828
blink_before();
2929
MsgPack::arr_size_t req_sz(4);
30+
MsgPack::arr_size_t notify_sz(3);
31+
MsgPack::arr_size_t resp_sz(4);
3032
MsgPack::arr_size_t par_sz(2);
33+
34+
// REQUEST
3135
packer.clear();
3236
packer.serialize(req_sz, 0, 1, "method", par_sz, 1.0, 2.0);
3337

3438
DummyTransport dummy_transport(packer.data(), packer.size());
3539
RpcDecoder<> decoder(dummy_transport);
3640

37-
while (!decoder.packet_available()){
41+
while (!decoder.packet_incoming()){
3842
decoder.print_buffer();
3943
Serial.println("Packet not ready");
4044
decoder.advance();
41-
uint8_t decoded = decoder.parse_packet();
42-
if (decoded > 0){
43-
Serial.print("Bytes decoded: ");
44-
Serial.println(decoded);
45-
}
45+
decoder.parse_packet();
4646
decoder.print_buffer();
4747
delay(100);
4848
}
4949

50-
if (decoder.packet_available()){
51-
Serial.print("packet ready. size: ");
52-
Serial.println(decoder.packet_size());
50+
if (decoder.packet_incoming()){
51+
Serial.print("packet incoming. type: ");
52+
Serial.println(decoder.packet_type());
53+
}
54+
55+
// NOTIFICATION
56+
blink_before();
57+
packer.clear();
58+
packer.serialize(notify_sz, 2, "method", par_sz, 1.0, 2.0);
59+
60+
DummyTransport dummy_transport2(packer.data(), packer.size());
61+
RpcDecoder<> decoder2(dummy_transport2);
62+
63+
while (!decoder2.packet_incoming()){
64+
decoder2.print_buffer();
65+
Serial.println("Packet not ready");
66+
decoder2.advance();
67+
decoder2.parse_packet();
68+
decoder2.print_buffer();
69+
delay(100);
5370
}
5471

72+
if (decoder2.packet_incoming()){
73+
Serial.print("packet ready. type: ");
74+
Serial.println(decoder2.packet_type());
75+
}
5576

77+
// RESPONSE
78+
blink_before();
79+
packer.clear();
80+
MsgPack::object::nil_t nil;
81+
MsgPack::arr_size_t ret_sz(2);
82+
packer.serialize(resp_sz, 1, 1, nil, ret_sz, 3.0, 2);
83+
84+
DummyTransport dummy_transport3(packer.data(), packer.size());
85+
RpcDecoder<> decoder3(dummy_transport3);
86+
87+
while (!decoder3.packet_incoming()){
88+
decoder3.print_buffer();
89+
Serial.println("Packet not ready");
90+
decoder3.advance();
91+
decoder3.parse_packet();
92+
decoder3.print_buffer();
93+
delay(100);
94+
}
95+
96+
if (decoder3.packet_incoming()){
97+
Serial.print("packet ready. type: ");
98+
Serial.println(decoder3.packet_type());
99+
}
56100
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <Arduino_RPClite.h>
2+
3+
void blink_before(){
4+
digitalWrite(LED_BUILTIN, HIGH);
5+
delay(200);
6+
digitalWrite(LED_BUILTIN, LOW);
7+
delay(200);
8+
digitalWrite(LED_BUILTIN, HIGH);
9+
delay(200);
10+
digitalWrite(LED_BUILTIN, LOW);
11+
delay(200);
12+
digitalWrite(LED_BUILTIN, HIGH);
13+
delay(200);
14+
digitalWrite(LED_BUILTIN, LOW);
15+
delay(200);
16+
}
17+
18+
MsgPack::Packer packer;
19+
MsgPack::Unpacker unpacker;
20+
21+
void setup() {
22+
Serial.begin(9600);
23+
}
24+
25+
void loop() {
26+
27+
size_t expected_index_size = 5;
28+
blink_before();
29+
MsgPack::arr_size_t req_sz(4);
30+
MsgPack::arr_size_t par_sz(2);
31+
packer.clear();
32+
packer.serialize(req_sz, 0, 1, "method", par_sz, 1.0, 2.0);
33+
34+
Serial.print("packet size: ");
35+
Serial.println(packer.size());
36+
37+
for (size_t i=1; i< packer.size(); i++){
38+
unpacker.clear();
39+
if (unpacker.feed(packer.data(), i) && unpacker.size() >= expected_index_size){
40+
Serial.println("problem ");
41+
Serial.println(i);
42+
}
43+
}
44+
45+
}

src/decoder.h

Lines changed: 23 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "MsgPack.h"
55

66

7+
#define NO_MSG -1
78
#define CALL_MSG 0
89
#define RESP_MSG 1
910
#define NOTIFY_MSG 2
@@ -42,101 +43,59 @@ class RpcDecoder {
4243
return true;
4344
}
4445

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

48-
// Nop in case 1st packet is ready... waiting to deliver
49-
if (_packet_ready){return _packet_size;}
50-
51-
size_t bytes_checked = 3;
52-
53-
while (bytes_checked < _bytes_stored) {
54-
bytes_checked++;
55-
56-
if (is_packet_complete(bytes_checked)) {
57-
_packet_ready = true;
58-
_packet_size = bytes_checked;
59-
break;
60-
}
61-
}
62-
63-
return _packet_size;
64-
65-
}
66-
67-
bool is_packet_complete(size_t size) {
48+
if (packet_incoming() || buffer_empty()){return;}
6849

6950
static MsgPack::Unpacker unpacker;
7051
unpacker.clear();
52+
unpacker.feed(_raw_buffer, _bytes_stored);
7153

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 == CALL_MSG || type == RESP_MSG) { // 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 == NOTIFY_MSG) { // 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-
54+
MsgPack::arr_size_t elem_size;
55+
int type;
56+
if (unpacker.deserialize(elem_size, type)){
57+
_packet_type = type;
9758
}
9859

99-
return false;
100-
10160
}
10261

10362
// Check if a packet is available
104-
bool packet_available() const { return _packet_ready; }
63+
inline bool packet_incoming() const { return _packet_type >= CALL_MSG; }
10564

106-
size_t packet_size() const {return _packet_size;}
65+
int packet_type() const {return _packet_type;}
10766

10867
// Get the oldest packet (returns false if no packet available)
109-
bool get_next_packet(MsgPack::Unpacker& unpacker) {
110-
if (!_packet_ready) return false;
111-
return unpacker.feed(_raw_buffer, _packet_size);
68+
bool get_next_packet(MsgPack::Unpacker& unpacker, size_t size) {
69+
if (!packet_incoming()) return false;
70+
unpacker.clear();
71+
return unpacker.feed(_raw_buffer, size);
11272
}
11373

11474
// Try to recover buffer error condition
11575
void recover() {
11676
// ensure parsing was attempted
11777
parse_packet();
118-
if (buffer_full() && !_packet_ready){
78+
if (buffer_full() && !packet_incoming()){
11979
flush_buffer();
12080
}
12181
}
12282

12383
// Discard the oldest packet. Returns the number of freed_bytes
124-
size_t pop_packet() {
84+
size_t pop_packet(size_t size) {
12585

126-
if (!_packet_ready) return false;
86+
if (size > _bytes_stored) return 0;
12787

128-
const size_t remaining_bytes = _bytes_stored - _packet_size;
88+
const size_t remaining_bytes = _bytes_stored - size;
12989

13090
// Shift remaining data forward (manual memmove for compatibility)
13191
for (size_t i = 0; i < remaining_bytes; i++) {
132-
_raw_buffer[i] = _raw_buffer[_packet_size + i];
92+
_raw_buffer[i] = _raw_buffer[size + i];
13393
}
13494

13595
_bytes_stored = remaining_bytes;
136-
_packet_ready = false;
137-
_packet_size = 0; // Reset packet state
96+
_packet_type = NO_MSG;
13897

139-
return _packet_size;
98+
return size;
14099
}
141100

142101
#ifdef DEBUG
@@ -159,11 +118,10 @@ void print_buffer(){
159118
uint8_t _raw_buffer[BufferSize];
160119
size_t _bytes_stored = 0;
161120

162-
bool _packet_ready = false;
163-
size_t _packet_size = 0;
121+
int _packet_type = NO_MSG;
164122

165123
inline bool buffer_full() const { return _bytes_stored == BufferSize; }
166-
inline bool buffer_empy() const { return _bytes_stored == 0;}
124+
inline bool buffer_empty() const { return _bytes_stored == 0;}
167125
inline void flush_buffer() {
168126
uint8_t* discard_buf;
169127
while (_transport.read(discard_buf, CHUNK_SIZE) > 0);

0 commit comments

Comments
 (0)