Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MESSAGECLASSIDHEADER_H
00028 #define MESSAGECLASSIDHEADER_H
00029
00030 #include "ByteOrder.h"
00031 #include "Log.h"
00032 #include "FletcherChecksum.h"
00033 #include "GpCoreToolsDLLExport.h"
00034
00035 namespace GpCoreTools {
00036
00037 #pragma pack(1)
00038
00039 class GPCORETOOLS_EXPORT MessageClassIdHeader
00040 {
00041 public:
00042 MessageClassIdHeader() {}
00043 inline MessageClassIdHeader(unsigned char msgClass, unsigned char msgId, unsigned int length);
00044 inline MessageClassIdHeader(const MessageClassIdHeader& o);
00045
00046 enum {SynchronizationSize=2, HeaderSize=4, CheckSumSize=2};
00047
00048 bool isValid() const {return _sync[0]==0xB5 && _sync[1]==0x62;}
00049 inline bool isValid(const FletcherChecksum& cksum, const char * payload=0,
00050 unsigned short payloadLength=0) const;
00051
00052 unsigned char messageClass() const {return _values.messageClass;}
00053 unsigned char messageId() const {return _values.messageId;}
00054
00055 inline void littleEndianValues();
00056 inline void bigEndianValues();
00057
00058 unsigned int lengthLittleEndian() const {return ByteOrder::littleEndianToNative(_values.length);}
00059 unsigned int lengthBigEndian() const {return ByteOrder::bigEndianToNative(_values.length);}
00060
00061 const char * header() const {return _bytes;}
00062 protected:
00063 unsigned char _sync[2];
00064 union {
00065 struct {
00066 unsigned char messageClass;
00067 unsigned char messageId;
00068 unsigned short length;
00069 } _values;
00070 char _bytes[HeaderSize];
00071 };
00072 };
00073
00074 inline MessageClassIdHeader::MessageClassIdHeader(unsigned char msgClass, unsigned char msgId, unsigned int length)
00075 {
00076 _sync[0]=0xB5;
00077 _sync[1]=0x62;
00078 _values.messageClass=msgClass;
00079 _values.messageId=msgId;
00080 _values.length=length;
00081 }
00082
00083 inline MessageClassIdHeader::MessageClassIdHeader(const MessageClassIdHeader& o)
00084 {
00085 _sync[0]=o._sync[0];
00086 _sync[1]=o._sync[1];
00087 _values.messageClass=o._values.messageClass;
00088 _values.messageId=o._values.messageId;
00089 _values.length=o._values.length;
00090 }
00091
00092 inline void MessageClassIdHeader::bigEndianValues()
00093 {
00094 #if BYTE_ORDER==LITTLE_ENDIAN
00095 ByteOrder::swap(_bytes[2], _bytes[3]);
00096 #endif
00097 }
00098
00099 inline void MessageClassIdHeader::littleEndianValues()
00100 {
00101 #if BYTE_ORDER==BIG_ENDIAN
00102 ByteOrder::swap(_bytes[2], _bytes[3]);
00103 #endif
00104 }
00105
00106 inline bool MessageClassIdHeader::isValid(const FletcherChecksum& cksum, const char * payload,
00107 unsigned short payloadLength) const
00108 {
00109 FletcherChecksum mycs;
00110 mycs.add(reinterpret_cast<const char *>(header()), HeaderSize);
00111 if(payload) {
00112 mycs.add(payload, payloadLength);
00113 }
00114 if(cksum==mycs) {
00115 return true;
00116 } else {
00117 Log::write(5, "bad checksum 0x%02hhX 0x%02hhX (in message) instead of 0x%02hhX 0x%02hhX (computed)\n", cksum.a(), cksum.b(), mycs.a(), mycs.b());
00118 return false;
00119 }
00120 }
00121
00122 #pragma pack() // restore original alignment
00123
00124 }
00125
00126 #endif // MESSAGECLASSIDHEADER_H