@@ -13,105 +13,9 @@ class StreamPacket {
1313 };
1414
1515 public:
16- // ================= Sender =================
17-
18- // chunked отправщик
19- class Sender {
20- public:
21- Sender (Print& s) : _s(s) {}
22-
23- // начать пакет
24- template <typename Tp>
25- bool beginPacket (Tp type, size_t len) {
26- return StreamPacket::_beginSend (_s, (uint8_t )type, len);
27- }
28-
29- // отправить чанк
30- template <typename Td>
31- bool send (const Td& data) {
32- return send (&data, sizeof (Td));
33- }
34-
35- // отправить чанк
36- bool send (const void * data, size_t len) {
37- _crc = StreamPacket::_crc8 (data, len, _crc);
38- return _s.write ((uint8_t *)data, len) == len;
39- }
40-
41- // завершить отправку
42- bool endPacket () {
43- return _s.write (_crc);
44- }
45-
46- private:
47- Print& _s;
48- uint8_t _crc = 0 ;
49- };
50-
51- // ================= READER =================
52-
53- // асинхронный парсер
54- class Reader {
55- public:
56- Reader (Stream& s, ParseCallback cb = nullptr ) : _s(s), _cb(cb) {}
57-
58- // коллбэк вида f(uint8_t type, void* data, size_t len)
59- void onData (ParseCallback cb) {
60- _cb = cb;
61- }
62-
63- // тикер, вызывать в loop
64- void tick () {
65- if (_data) {
66- if (_s.available ()) {
67- _tmr = millis ();
68- size_t rlen = min (int (_p.length + 1 - _idx), _s.available ());
69-
70- if (_s.readBytes (_data + _idx, rlen) != rlen) {
71- delete _data;
72- _data = nullptr ;
73- return ;
74- }
75-
76- _p.crc = _crc8 (_data + _idx, rlen, _p.crc );
77- _idx += rlen;
78-
79- if (_idx == _p.length + 1 ) {
80- if (!_p.crc ) _cb (_p.type , _data, _p.length );
81- delete _data;
82- _data = nullptr ;
83- }
84-
85- } else {
86- if (millis () - _tmr >= SP_TOUT) {
87- delete _data;
88- _data = nullptr ;
89- }
90- }
91-
92- } else {
93- if ((size_t )_s.available () < sizeof (_p) + 1 ||
94- _s.read () != SP_START ||
95- _s.readBytes ((uint8_t *)&_p, sizeof (_p)) != sizeof (_p) ||
96- _crc8 (&_p, sizeof (_p))) return ;
97-
98- _data = new uint8_t [_p.length + 1 ];
99- if (!_data) return ;
100-
101- _idx = 0 ;
102- _p.crc = 0 ;
103- _tmr = millis ();
104- }
105- }
106-
107- private:
108- Stream& _s;
109- uint8_t * _data = nullptr ;
110- ParseCallback _cb = nullptr ;
111- Packet _p;
112- uint32_t _tmr = 0 ;
113- uint16_t _idx = 0 ;
114- };
16+ class Sender ;
17+ class Reader ;
18+ class ReaderBuf ;
11519
11620 // ================= STATIC =================
11721
@@ -190,4 +94,153 @@ class StreamPacket {
19094 p.crc = _crc8 (&p, sizeof (p) - 1 );
19195 return s.write ((uint8_t )SP_START) == 1 && s.write ((uint8_t *)&p, sizeof (p)) == sizeof (p);
19296 }
97+ };
98+
99+ // ================= Sender =================
100+
101+ // chunked отправщик
102+ class StreamPacket ::Sender {
103+ public:
104+ Sender (Print& s) : _s(s) {}
105+
106+ // начать пакет
107+ template <typename Tp>
108+ bool beginPacket (Tp type, size_t len) {
109+ return StreamPacket::_beginSend (_s, (uint8_t )type, len);
110+ }
111+
112+ // отправить чанк
113+ template <typename Td>
114+ bool send (const Td& data) {
115+ return send (&data, sizeof (Td));
116+ }
117+
118+ // отправить чанк
119+ bool send (const void * data, size_t len) {
120+ _crc = StreamPacket::_crc8 (data, len, _crc);
121+ return _s.write ((uint8_t *)data, len) == len;
122+ }
123+
124+ // завершить отправку
125+ bool endPacket () {
126+ return _s.write (_crc);
127+ }
128+
129+ private:
130+ Print& _s;
131+ uint8_t _crc = 0 ;
132+ };
133+
134+ // ================= READER BUF =================
135+
136+ // асинхронный парсер со своим буфером
137+ class StreamPacket ::ReaderBuf {
138+ public:
139+ ReaderBuf (Stream& s, ParseCallback cb = nullptr ) : _s(s), _cb(cb) {}
140+
141+ // коллбэк вида f(uint8_t type, void* data, size_t len)
142+ void onData (ParseCallback cb) {
143+ _cb = cb;
144+ }
145+
146+ // тикер, вызывать в loop
147+ void tick () {
148+ if (_data) {
149+ if (_s.available ()) {
150+ _tmr = millis ();
151+ size_t rlen = min (int (_p.length + 1 - _idx), _s.available ());
152+
153+ if (_s.readBytes (_data + _idx, rlen) != rlen) {
154+ delete _data;
155+ _data = nullptr ;
156+ return ;
157+ }
158+
159+ _p.crc = _crc8 (_data + _idx, rlen, _p.crc );
160+ _idx += rlen;
161+
162+ if (_idx == _p.length + 1 ) {
163+ if (!_p.crc && _cb) _cb (_p.type , _data, _p.length );
164+ delete _data;
165+ _data = nullptr ;
166+ }
167+
168+ } else {
169+ if (millis () - _tmr >= SP_TOUT) {
170+ delete _data;
171+ _data = nullptr ;
172+ }
173+ }
174+
175+ } else {
176+ if ((size_t )_s.available () < sizeof (_p) + 1 ||
177+ _s.read () != SP_START ||
178+ _s.readBytes ((uint8_t *)&_p, sizeof (_p)) != sizeof (_p) ||
179+ _crc8 (&_p, sizeof (_p))) return ;
180+
181+ _data = new uint8_t [_p.length + 1 ];
182+ if (!_data) return ;
183+
184+ _idx = 0 ;
185+ _p.crc = 0 ;
186+ _tmr = millis ();
187+ }
188+ }
189+
190+ private:
191+ Stream& _s;
192+ uint8_t * _data = nullptr ;
193+ ParseCallback _cb = nullptr ;
194+ Packet _p;
195+ uint32_t _tmr = 0 ;
196+ uint16_t _idx = 0 ;
197+ };
198+
199+ // ================= READER =================
200+
201+ // асинхронный парсер
202+ class StreamPacket ::Reader {
203+ public:
204+ Reader (Stream& s, ParseCallback cb = nullptr ) : _s(s), _cb(cb) {}
205+
206+ // коллбэк вида f(uint8_t type, void* data, size_t len)
207+ void onData (ParseCallback cb) {
208+ _cb = cb;
209+ }
210+
211+ // тикер, вызывать в loop
212+ void tick () {
213+ if (_p.length ) {
214+ if ((uint16_t )_s.available () >= _p.length ) {
215+ uint8_t buf[_p.length ];
216+ if (_s.readBytes (buf, _p.length ) == _p.length && _cb && !_crc8 (buf, _p.length )) {
217+ _cb (_p.type , buf, _p.length - 1 );
218+ }
219+ _p.length = 0 ;
220+ } else if (_pAv != (uint16_t )_s.available ()) {
221+ _pAv = _s.available ();
222+ _tmr = millis ();
223+ } else if (uint16_t (uint16_t (millis ()) - _tmr) >= SP_TOUT) {
224+ _p.length = 0 ;
225+ }
226+ } else {
227+ if ((size_t )_s.available () < sizeof (_p) + 1 ||
228+ _s.read () != SP_START ||
229+ _s.readBytes ((uint8_t *)&_p, sizeof (_p)) != sizeof (_p) ||
230+ _crc8 (&_p, sizeof (_p))) {
231+ _p.length = 0 ;
232+ return ;
233+ }
234+ ++_p.length ;
235+ _tmr = millis ();
236+ _pAv = 0 ;
237+ }
238+ }
239+
240+ private:
241+ Stream& _s;
242+ ParseCallback _cb = nullptr ;
243+ Packet _p;
244+ uint16_t _pAv = 0 ;
245+ uint16_t _tmr = 0 ;
193246};
0 commit comments