snark
actuators/quickset/ptcr/packet.h
1 // This file is part of snark, a generic and flexible library
2 // for robotics research.
3 //
4 // Copyright (C) 2011 The University of Sydney
5 //
6 // snark is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // snark is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 // for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with snark. If not, see <http://www.gnu.org/licenses/>.
18 
19 #ifndef SNARK_ACTUATORS_QUICKSET_ptcr_PACKET_H_
20 #define SNARK_ACTUATORS_QUICKSET_ptcr_PACKET_H_
21 
22 #include <comma/packed/byte.h>
23 #include <comma/packed/little_endian.h>
24 #include <comma/packed/struct.h>
25 
26 namespace snark { namespace quickset { namespace ptcr {
27 
28 struct constants
29 {
30  static const unsigned char stx = 0x02;
31  static const unsigned char etx = 0x03;
32  static const unsigned char ack = 0x06;
33  static const unsigned char nak = 0x15;
34  static const unsigned char esc = 0x1B;
35 };
36 
37 template < typename B >
38 struct header : public comma::packed::packed_struct< header< B >, 3 >
39 {
40  comma::packed::byte type;
41  comma::packed::byte address;
42  comma::packed::const_byte< B::id > id;
43 
44  header( unsigned char t ) { type = t; address = 0; }
45 };
46 
47 template < typename B >
48 struct lrc : public comma::packed::packed_struct< lrc< B >, 1 >
49 {
50  comma::packed::byte value;
51 
52  bool ok() const;
53  void set();
54 };
55 
56 template < typename B >
57 struct footer : public comma::packed::packed_struct< footer< B >, 2 >
58 {
59  lrc< B > footer_lrc;
60  comma::packed::const_byte< 0x03 > etx;
61 };
62 
63 template < typename B >
64 struct packet : public comma::packed::packed_struct< packet< B >, 3 + 2 + B::size >
65 {
66  header< B > packet_header;
67  B body;
68  footer< B > packet_footer;
69 
70  packet() : packet_header( constants::stx ) {}
71  packet( unsigned char type ) : packet_header( type ) {}
72  packet( const B& body ) : packet_header( constants::stx ), body( body ) { packet_footer.footer_lrc.set(); }
73  packet( const B& body, unsigned char type ) : packet_header( type ), body( body ) { packet_footer.footer_lrc.set(); }
74 };
75 
76 inline static unsigned char get_lrc( const char* begin, const char* end )
77 {
78  unsigned char c = 0;
79  for( const char* p = begin; p < end; ++p ) { c ^= static_cast< unsigned char >( *p ); }
80  return c;
81 }
82 
83 template < typename B >
84 inline void lrc< B >::set() { value = get_lrc( value.data() - B::size - 1, value.data() ); }
85 
86 template < typename B >
87 inline bool lrc< B >::ok() const
88 {
89  return value() == get_lrc( value.data() - B::size - 1, value.data() );
90 }
91 
92 } } } // namespace snark { namespace quickset { namespace ptcr {
93 
94 #endif // #ifndef SNARK_ACTUATORS_QUICKSET_ptcr_PACKET_H_