99#define RESP_MSG 1
1010#define NOTIFY_MSG 2
1111
12+ #define REQUEST_SIZE 4
13+ #define RESPONSE_SIZE 4
14+ #define NOTIFY_SIZE 3
15+
1216#define MAX_BUFFER_SIZE 1024
1317#define CHUNK_SIZE 32
1418
@@ -18,6 +22,96 @@ class RpcDecoder {
1822public:
1923 RpcDecoder (ITransport& transport) : _transport(transport) {}
2024
25+ template <typename ... Args>
26+ bool send_call (const int call_type, const MsgPack::str_t method, int & msg_id, Args&&... args) {
27+
28+ if (call_type!=CALL_MSG && call_type!=NOTIFY_MSG) return false ;
29+
30+ static MsgPack::Packer packer;
31+ packer.clear ();
32+
33+ if (call_type == CALL_MSG){
34+ msg_id = _msg_id;
35+ MsgPack::arr_size_t call_size (REQUEST_SIZE);
36+ packer.serialize (call_size, call_type, msg_id, method);
37+ } else {
38+ MsgPack::arr_size_t call_size (NOTIFY_SIZE);
39+ packer.serialize (call_size, call_type, method);
40+ }
41+
42+ MsgPack::arr_size_t arg_size (sizeof ...(args));
43+ packer.serialize (arg_size, std::forward<Args>(args)...);
44+
45+ #ifdef DEBUG
46+ Serial.print (" Sending: " );
47+ for (size_t i=0 ; i<packer.size (); i++){
48+ Serial.print (packer.data ()[i], HEX);
49+ Serial.print (" " );
50+ }
51+ Serial.println (" " );
52+ #endif
53+
54+ if (send (reinterpret_cast <const uint8_t *>(packer.data ()), packer.size ()) == packer.size ()){
55+ _msg_id++;
56+ return true ;
57+ }
58+ return false ;
59+ }
60+
61+ template <typename RType>
62+ bool get_response (const int msg_id, RType& result, RpcError& error) {
63+
64+ if (!packet_incoming () || packet_type ()!=RESP_MSG) return false ;
65+
66+ static MsgPack::Unpacker unpacker;
67+
68+ size_t bytes_checked = 0 ;
69+
70+ while (bytes_checked < _bytes_stored) {
71+ bytes_checked++;
72+ unpacker.clear ();
73+ if (!unpacker.feed (_raw_buffer, bytes_checked)) continue ;
74+ MsgPack::arr_size_t resp_size;
75+ int resp_type;
76+ int resp_id;
77+ if (!unpacker.deserialize (resp_size, resp_type, resp_id)) continue ;
78+ if (resp_size.size () != RESPONSE_SIZE) continue ;
79+ if (resp_type != RESP_MSG) continue ;
80+ if (resp_id != msg_id) continue ;
81+
82+ MsgPack::object::nil_t nil;
83+ if (unpacker.unpackable (nil)){ // No error
84+ if (!unpacker.deserialize (nil, result)) continue ;
85+ } else { // RPC returned an error
86+ if (!unpacker.deserialize (error, nil)) continue ;
87+ }
88+ pop_packet (bytes_checked);
89+ return true ;
90+ }
91+ #ifdef DEBUG
92+ print_buffer ();
93+ #endif
94+ return false ;
95+ }
96+
97+ template <typename RType>
98+ bool send_response (const int msg_id, const RpcError& error, const RType& result) {
99+ static MsgPack::Packer packer;
100+ MsgPack::arr_size_t resp_size (RESPONSE_SIZE);
101+ MsgPack::object::nil_t nil;
102+
103+ packer.clear ();
104+ packer.serialize (resp_size, RESP_MSG, msg_id);
105+
106+ if (error.code == NO_ERR){
107+ packer.serialize (nil, result);
108+ } else {
109+ packer.serialize (error, nil);
110+ }
111+
112+ return send (reinterpret_cast <const uint8_t *>(packer.data ()), packer.size ()) == packer.size ();
113+
114+ }
21115
22116 void process (){
23117 if (advance ()) parse_packet ();
@@ -119,8 +213,8 @@ void print_buffer(){
119213 ITransport& _transport;
120214 uint8_t _raw_buffer[BufferSize];
121215 size_t _bytes_stored = 0 ;
122-
123216 int _packet_type = NO_MSG;
217+ int _msg_id = 0 ;
124218
125219 inline bool buffer_full () const { return _bytes_stored == BufferSize; }
126220 inline bool buffer_empty () const { return _bytes_stored == 0 ;}
@@ -129,6 +223,9 @@ void print_buffer(){
129223 while (_transport.read (discard_buf, CHUNK_SIZE) > 0 );
130224 _bytes_stored = 0 ;
131225 }
226+ inline size_t send (const uint8_t * data, const size_t size) {
227+ return _transport.write (data, size);
228+ }
132229};
133230
134231#endif
0 commit comments