Data Link Serial Protocol
Loading...
Searching...
No Matches
DataLinkSerialProtocol.h
1#pragma once
2
3#ifndef ARDUINO
4#include <cstdint>
5#else
6#include <Arduino.h>
7#endif
8
9
13namespace proto
14{
19 {
23 eXOR = 0x20,
27 eHDR = 0x7B,
31 eESC = 0x7C,
35 eFTR = 0x7D,
36 };
37
74 template<uint8_t NMaxMessage = 10>
75 struct Bicoder
76 {
77 static_assert( (0U < NMaxMessage) and (NMaxMessage < 127U),
78 "The max length of the message is out of range" );
79
84 static constexpr uint8_t maxEncodedSize = 2U * NMaxMessage + 2U;
85
86 Bicoder() = default;
87
110 bool decodeByte( const uint8_t data );
126 bool decodeMessage( const uint8_t* data, uint8_t size );
127
143 bool encodeMessage( const uint8_t* data, uint8_t size );
144
154 void reset();
155
164 bool isCompleted() const { return m_isCompleted; }
165
172 uint8_t size() const { return m_index; }
173
179 const uint8_t* buff() const { return m_message; }
180
181 private :
182 using State_t = bool (Bicoder::*)(const uint8_t data);
183
184 bool waitHeader(const uint8_t data);
185 bool inMessage(const uint8_t data);
186 bool afterEscape(const uint8_t data);
187
188 void appendMessage( const uint8_t data );
189 bool pushByte( const uint8_t data );
190 bool encodeByte( const uint8_t data );
191
192 State_t m_state { &Bicoder::waitHeader };
193 uint8_t m_message[maxEncodedSize] = { 0 };
194 uint8_t m_index { 0 };
195 bool m_isCompleted { false };
196 };
197
198 template<uint8_t N>
199 void Bicoder<N>::appendMessage( const uint8_t data )
200 {
201 m_message[m_index] = data;
202 m_index++;
203 }
204
205 template<uint8_t N>
206 bool Bicoder<N>::pushByte( const uint8_t data )
207 {
208 if( m_index >= N )
209 {
210 reset();
211 return false;
212 }
213
214 appendMessage( data );
215
216 return true;
217 }
218
219 template<uint8_t N>
221 {
222 m_index = 0;
223 m_state = &Bicoder::waitHeader;
224 m_isCompleted = false;
225 }
226
227 template<uint8_t N>
228 bool Bicoder<N>::decodeByte( const uint8_t data )
229 {
230 return (this->*m_state)( data );
231 }
232
233 template<uint8_t N>
234 bool Bicoder<N>::decodeMessage( const uint8_t* data, uint8_t size )
235 {
236 reset();
237
238 for( uint8_t i = 0; (i < size); ++i )
239 {
240 if( not decodeByte( data[i] ) )
241 return false;
242 }
243
244 return m_isCompleted;
245 }
246
247 template<uint8_t N>
248 bool Bicoder<N>::encodeByte( const uint8_t data )
249 {
250 switch( data )
251 {
252 case( ESpecial::eHDR ) :
253 case( ESpecial::eESC ) :
254 case( ESpecial::eFTR ) :
255 appendMessage( ESpecial::eESC );
256 appendMessage( data ^ ESpecial::eXOR );
257 break;
258 default :
259 appendMessage( data );
260 }
261
262 return true;
263 }
264
265 template<uint8_t N>
266 bool Bicoder<N>::encodeMessage( const uint8_t* data, uint8_t size )
267 {
268 reset();
269
270 if( N < size )
271 return false;
272
273 m_message[m_index++] = ESpecial::eHDR;
274
275 for( uint8_t i = 0; i < size; ++i )
276 encodeByte( data[i] );
277
278 m_message[m_index++] = ESpecial::eFTR;
279
280 return m_isCompleted = true;
281 }
282
283 template<uint8_t N>
284 bool Bicoder<N>::waitHeader( const uint8_t data )
285 {
286 reset();
287
288 if( data == ESpecial::eHDR )
289 m_state = &Bicoder::inMessage;
290
291 return true;
292 }
293
294 template<uint8_t N>
295 bool Bicoder<N>::inMessage( const uint8_t data )
296 {
297 switch( data )
298 {
299 case ESpecial::eFTR :
300 m_state = &Bicoder::waitHeader;
301 m_isCompleted = true;
302 return true;
303 case ESpecial::eESC :
304 m_state = &Bicoder::afterEscape;
305 return true;
306 case ESpecial::eHDR :
307 reset();
308 return false;
309 default :
310 return pushByte( data );
311 }
312 }
313
314 template<uint8_t N>
315 bool Bicoder<N>::afterEscape( const uint8_t data )
316 {
317 m_state = &Bicoder::inMessage;
318 pushByte( data ^ ESpecial::eXOR );
319 return true;
320 }
321}// proto
322
Definition DataLinkSerialProtocol.h:14
ESpecial
Definition DataLinkSerialProtocol.h:19
@ eFTR
Definition DataLinkSerialProtocol.h:35
@ eHDR
Definition DataLinkSerialProtocol.h:27
@ eXOR
Definition DataLinkSerialProtocol.h:23
@ eESC
Definition DataLinkSerialProtocol.h:31
Definition DataLinkSerialProtocol.h:76
uint8_t size() const
Definition DataLinkSerialProtocol.h:172
void reset()
Definition DataLinkSerialProtocol.h:220
static constexpr uint8_t maxEncodedSize
Definition DataLinkSerialProtocol.h:84
bool isCompleted() const
Definition DataLinkSerialProtocol.h:164
bool decodeMessage(const uint8_t *data, uint8_t size)
Definition DataLinkSerialProtocol.h:234
bool decodeByte(const uint8_t data)
Definition DataLinkSerialProtocol.h:228
bool encodeMessage(const uint8_t *data, uint8_t size)
Definition DataLinkSerialProtocol.h:266
const uint8_t * buff() const
Definition DataLinkSerialProtocol.h:179