cmtmessage.h

Go to the documentation of this file.
00001 #ifndef _CMT_MONOLITHIC
00002 /*! \file
00003         \brief        Contains the CMT Message interface
00004 
00005         This level contains the message interface of Cmt.
00006         All code should be OS-independent.
00007 
00008         \section FileCopyright Copyright Notice 
00009         Copyright (C) Xsens Technologies B.V., 2006.  All rights reserved.
00010 
00011         This source code is intended for use only by Xsens Technologies BV and
00012         those that have explicit written permission to use it from
00013         Xsens Technologies BV.
00014 
00015         THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
00016         KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
00017         IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
00018         PARTICULAR PURPOSE.
00019 */
00020 #endif
00021 #ifndef _CMTMESSAGE_H_2006_05_24
00022 #define _CMTMESSAGE_H_2006_05_24
00023 
00024 #ifndef _CMT_MONOLITHIC
00025 #        include "cmtdef.h"
00026 #        include "cmt1.h"
00027 #endif
00028 
00029 namespace xsens {
00030 
00031 //////////////////////////////////////////////////////////////////////////////////////////
00032 /*! \brief Compute the checksum of the given byte string.
00033 */
00034 uint8_t computeChecksum(const uint8_t* buffer, uint32_t length);
00035 
00036 //////////////////////////////////////////////////////////////////////////////////////////
00037 /* different alignment commands for gcc / MSVS, the structure needs to be 1-byte aligned.
00038 */
00039 #ifdef _MSC_VER
00040         #pragma pack(push, 1)
00041 #endif
00042 /*! \brief A message header.
00043         
00044         DO NOT REORDER THE MEMBERS!
00045 */
00046 struct MessageHeader {
00047         uint8_t m_preamble;
00048         uint8_t m_busId;
00049         uint8_t m_messageId;
00050         uint8_t m_length;
00051         union _mdl {
00052                 struct _mextd {
00053                         struct _mlen {
00054                                 uint8_t m_high;
00055                                 uint8_t m_low;
00056                         } m_length;
00057                         uint8_t m_data[CMT_MAXDATALEN];
00058                 } m_extended;
00059                 uint8_t m_data[254];
00060         } m_datlen;
00061 }
00062 // different alignment commands for gcc / MSVS
00063 #ifdef _MSC_VER
00064         ;
00065         #pragma pack(pop)
00066 #else
00067         /*! \cond NODOXYGEN */        __attribute__((__packed__))        /*! \endcond */;
00068 #endif
00069 
00070 
00071 #define swapEndian16(src) (((src) >> 8) | ((src) << 8))
00072 #define swapEndian32(src) (((src) >> 24) | ((src) >> 8 & 0xFF00) | ((src) << 8 & 0xFF0000) | ((src) << 24))
00073 
00074 //////////////////////////////////////////////////////////////////////////////////////////
00075 //! \brief Class for storing a single message.
00076 class Message {
00077 protected:
00078 
00079                 //! The message header is the data buffer with interpretation
00080         MessageHeader* m_buffer;
00081                 //! The checksum in the m_data or m_extendedData buffer
00082         uint8_t* m_checksum;
00083                 //! The maximum size of the message, including header and footer
00084         uint32_t m_maxLength;
00085         
00086                 //! Internal checksum computation
00087         uint8_t calcChecksum(void) const
00088         { return computeChecksum(((uint8_t*)m_buffer) + 1, getTotalMessageSize()-2); }
00089                 //! Internal function to get the start of the data buffer.
00090         uint8_t* getDataStart(void) const;
00091 
00092 public:
00093         bool m_autoUpdateChecksum;
00094 
00095         /*! \brief Create a Message object with the given data length and message Id.
00096         
00097                 The function allocates enough memory to hold an entire message with the given 
00098                 data length.
00099                 \param msgId        The message Id that will be assigend to the m_messageId field.
00100                 \param length        The length of the data in the message. This value is stored in 
00101                                                 \c m_createdLength as well as \c m_length or \c m_extendedLength.
00102                 \param maxLength        The maximum data length that can be stored in the structure.
00103         */
00104         Message(const uint8_t msgId = 0, const uint16_t length = 0,        const uint16_t maxLength = CMT_MAXMSGLEN);
00105 
00106         /*! \brief Create a message from the given source string
00107         
00108                 This is done through a simple memory copy. The number of bytes copied is taken
00109                 from the data in the message (so the message is interpreted first).
00110                 Note that this does NOT recompute the checksum, nor is it checked.
00111                 
00112                 \param source                The source string containing message data
00113                 \param size                        The size of the source string
00114                 \param maxLength        The maximum data length that can be stored in the structure.
00115         */
00116         Message(const uint8_t* source, const uint16_t size, const uint16_t maxLength = CMT_MAXMSGLEN);
00117 
00118         Message(const Message& src);
00119 
00120                 //! Destructor
00121         ~Message();
00122 
00123                 //! Clear all data in the message
00124         void clear(void);
00125 
00126                 //! Return the current value of the m_busId field.
00127         uint8_t getBusId(void) const { return m_buffer->m_busId; }
00128         /*! \brief Return a pointer to the data buffer.
00129         
00130                 \param offset An optional offset in the data buffer from where to start reading.
00131         */
00132         uint8_t* getDataBuffer(const uint16_t offset = 0)
00133                 { return &((getDataStart())[offset]); }
00134         const uint8_t* getDataBuffer(const uint16_t offset = 0) const
00135                 { return &((getDataStart())[offset]); }
00136         /*! \brief Return the current value of the data as an unsigned byte (8 bits).
00137         
00138                 \param offset An optional offset in the data buffer from where to start reading.
00139         */
00140         uint8_t getDataByte(const uint16_t offset = 0) const
00141                 { return (getDataStart()[offset]); }
00142         /*! \brief Return the current value of the data as a double (64 bits).
00143         
00144                 \param offset An optional offset in the data buffer from where to start reading.
00145         */
00146         double getDataDouble(const uint16_t offset=0) const;
00147         /*! \brief Return the current value of the data as a float (32 bits).
00148         
00149                 \param offset An optional offset in the data buffer from where to start reading.
00150         */
00151         float getDataFloat(const uint16_t offset=0) const;
00152         /*! \brief Return the current value of the data as a double, converting it from FP 12.20
00153         
00154                 \param offset An optional offset in the data buffer from where to start reading.
00155         */
00156         double getDataF1220(const uint16_t offset=0) const;
00157         /*! \brief Return the current value of the data as a double, converting it from FP 16.32
00158         
00159                 \param offset An optional offset in the data buffer from where to start reading.
00160         */
00161         double getDataFP1632(const uint16_t offset=0) const;
00162         /*! \brief Return current data value as double, conversion depends on outputSettings.
00163         
00164                 \param outputSettings MT output settings
00165                 \param offset An optional offset in the data buffer from where to start reading.
00166         */
00167         double getDataFPValue(const uint64_t outputSettings, const uint16_t offset = 0) const;
00168         /*! \brief Return current data values as double, conversion depends on outputSetting.
00169         
00170                 \param dest destination array
00171                 \param outputSettings MT output settings
00172                 \param offset offset in the data buffer from where to start reading.
00173                 \param numValues number of values to be read
00174         */
00175         void getDataFPValue(double *dest, const uint64_t outputSettings, uint16_t offset, const int16_t numValues) const;
00176         /*! \brief Return the current value of the data as an uint32_t (32 bits).
00177         
00178                 \param offset An optional offset in the data buffer from where to start reading.
00179         */
00180         uint32_t getDataLong(const uint16_t offset=0) const;
00181         /*! \brief Return the current value of the data as an uint16_t (16 bits).
00182         
00183                 \param offset An optional offset in the data buffer from where to start reading.
00184         */
00185         uint16_t getDataShort(const uint16_t offset=0) const;
00186                 //! Return the length of the data part of the message.
00187         uint16_t getDataSize(void) const;
00188                 //! Return the current value of the m_messageId field.
00189         uint8_t getMessageId(void) const { return m_buffer->m_messageId; }
00190         /*! \brief Return the start of the message buffer.
00191         
00192                 The function returns the address of the \c m_preamble member.
00193         */
00194         const uint8_t* getMessageStart(void) const
00195                 { return (uint8_t*) m_buffer; }
00196         /*! \brief Return the length of the message buffer.
00197         
00198                 The function returns the total size of the message, including the checksum. This
00199                 is in effect the number of bytes that would be transferred if the message were to
00200                 be sent over a communications channel.
00201         */
00202         uint16_t getTotalMessageSize(void) const;
00203                 //! Compute the checksum and compare it with the stored checksum. Equal is ok.
00204         bool isChecksumOk(void) const;
00205         /*! \brief Read the entire message from the given source string
00206         
00207                 This is done through a simple memory copy. The number of bytes copied is \c
00208                 m_createdLength.
00209                 \param source                The source string containing message data
00210                 \param size                        The size of the source string
00211         */
00212         XsensResultValue loadFromString(const uint8_t* source, const uint16_t size);
00213         /*! \brief Compute the checksum field and fill it.
00214         
00215                 The checksum field should normally be correct at all times, but if you have
00216                 somehow managed to mess it up, this function can be used to recompute it.
00217         */
00218         void recomputeChecksum(void) { m_checksum[0] = calcChecksum(); }
00219                 //! Resize the data area to the given size
00220         void resizeData(const uint16_t newSize);
00221                 //! Set the new value of the m_busId field and update the checksum.
00222         void setBusId(const uint8_t busId);
00223         /*! \brief Write a string of bytes into the data buffer.
00224 
00225                 \param data                The data to write to the buffer.
00226                 \param offset        An optional offset in the data buffer from where to start writing.
00227                 \param count        An optional number of bytes to write, if set to 0 (not set), as
00228                                                 many bytes as will fit into the buffer from the given point will 
00229                                                 be written.
00230         */
00231         void setDataBuffer(const uint8_t* data, const uint16_t offset = 0,
00232                                                                 const uint16_t count = 0);
00233         /*! \brief Write an unsigned byte (8 bits) into the data buffer.
00234         
00235                 \param data                The data to write to the buffer.
00236                 \param offset        An optional offset in the data buffer from where to start writing.
00237         */
00238         void setDataByte(const uint8_t data, const uint16_t offset = 0);
00239         /*! \brief Write a double (64 bits) into the data buffer.
00240         
00241                 \param data                The data to write to the buffer.
00242                 \param offset An optional offset in the data buffer from where to start writing.
00243         */
00244         void setDataDouble(const double data, const uint16_t offset=0);
00245         /*! \brief Write a float (32 bits) into the data buffer.
00246         
00247                 \param data                The data to write to the buffer.
00248                 \param offset An optional offset in the data buffer from where to start writing.
00249         */
00250         void setDataFloat(const float data, const uint16_t offset = 0);
00251         /*! \brief Write a double (64 bits) into the data buffer, after converting it to F1220.
00252         
00253                 \param data                The data to write to the buffer.
00254                 \param offset        An optional offset in the data buffer from where to start writing.
00255         */
00256         void setDataF1220(const double data, const uint16_t offset = 0);
00257         /*! \brief Write a double (64 bits) into the data buffer, after converting it to FP1632.
00258         
00259                 \param data                The data to write to the buffer.
00260                 \param offset        An optional offset in the data buffer from where to start writing.
00261         */
00262         void setDataFP1632(const double data, const uint16_t offset = 0);
00263         /*! \brief Write a floating/fixed point value into to the data buffer, conversion depends on outputSettings
00264         
00265                 \param outputSettings MT output settings
00266                 \param data                The data to write to the buffer.
00267                 \param offset An optional offset in the data buffer from where to start writing.
00268         */
00269         void setDataFPValue(const uint64_t outputSettings, const double data, const uint16_t offset = 0);
00270         /*! \brief Write a floating/fixed point value into to the data buffer, conversion depends on outputSettings
00271         
00272                 \param outputSettings MT output settings
00273                 \param data                The data array to be written to the buffer.
00274                 \param offset Offset in the data buffer from where to start writing.
00275                 \param numValues number of values to be written
00276         */
00277         void setDataFPValue(const uint64_t outputSettings, const double *data, uint16_t offset, const uint16_t numValues);
00278         /*! \brief Write an uint32_t (32 bits) into the data buffer.
00279         
00280                 \param data                The data to write to the buffer.
00281                 \param offset An optional offset in the data buffer from where to start writing.
00282         */
00283         void setDataLong(const uint32_t data, const uint16_t offset = 0);
00284         /*! \brief Write an uint16_t (16 bits) into the data buffer.
00285         
00286                 \param data                The data to write to the buffer.
00287                 \param offset An optional offset in the data buffer from where to start writing.
00288         */
00289         void setDataShort(const uint16_t data, const uint16_t offset = 0);
00290                 //! Set the new value of the m_messageId field and update the checksum.
00291         void setMessageId(const uint8_t msgId);
00292 
00293                 //! Copy message src into this
00294         void operator = (const Message& src);
00295 
00296                 //! Remove a number of bytes from the message (this will reduce the message size)
00297         void deleteData(uint16_t size, uint16_t offset = 0);
00298                 //! Insert a number of bytes into the message (this will increase the message size)
00299         void insertData(uint16_t size, uint16_t offset = 0);
00300 };
00301 
00302 }; // end of xsens namespace
00303 
00304 #endif        // _CMTMESSAGE_H_2006_05_24
Generated on Sun May 8 08:05:57 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3