protocolhandler.cpp
Go to the documentation of this file.
1 
2 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions, and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions, and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the names of the copyright holders nor the names of their contributors
16 // may be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
26 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
28 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
29 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
30 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
31 //
32 
33 
34 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
35 // All rights reserved.
36 //
37 // Redistribution and use in source and binary forms, with or without modification,
38 // are permitted provided that the following conditions are met:
39 //
40 // 1. Redistributions of source code must retain the above copyright notice,
41 // this list of conditions, and the following disclaimer.
42 //
43 // 2. Redistributions in binary form must reproduce the above copyright notice,
44 // this list of conditions, and the following disclaimer in the documentation
45 // and/or other materials provided with the distribution.
46 //
47 // 3. Neither the names of the copyright holders nor the names of their contributors
48 // may be used to endorse or promote products derived from this software without
49 // specific prior written permission.
50 //
51 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
52 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
53 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
54 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
56 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
58 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
60 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
61 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
62 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
63 //
64 
65 #include "protocolhandler.h"
66 #include <xstypes/xsmessage.h>
67 #include <xstypes/xsresultvalue.h>
68 #include <iomanip>
69 #define DUMP_BUFFER_ON_ERROR 512 // this define doubles as the maximum buffer dump size, set to 0 to remove limit
70 #ifdef DUMP_BUFFER_ON_ERROR
71  #include <sstream>
72  #include <algorithm>
73 #endif
74 
87  : m_ignoreMaxMsgSize(false)
88 {}
89 
92 {}
93 
98 static int expectedMessageSize(const unsigned char* buffer, int sz)
99 {
100  const XsMessageHeader* hdr = (const XsMessageHeader*) buffer;
101  if (sz < 4)
102  return XS_LEN_MSGHEADERCS; // no size information available at all, return a minimum message
103 
104  // we have size information
105  if (hdr->m_length == XS_EXTLENCODE)
106  {
107  if (sz < 6)
108  return XS_EXTLENCODE + XS_LEN_MSGEXTHEADERCS; // typical minimum size at which point extended size is needed
109 
111  }
112  return XS_LEN_MSGHEADERCS + (int)(hdr->m_length);
113 }
114 
116 inline std::string dumpBuffer(const uint8_t* buff, XsSize sz)
117 {
118 #ifdef DUMP_BUFFER_ON_ERROR
119  std::ostringstream ostr;
120  ostr << std::hex << std::setfill('0');
121 #if DUMP_BUFFER_ON_ERROR > 0
122  sz = std::min<XsSize>(sz, DUMP_BUFFER_ON_ERROR);
123 #endif
124  for (XsSize i = 0; i < sz; ++i)
125  ostr << " " << std::setw(2) << (int) buff[i];
126  return ostr.str();
127 #else
128  return std::string();
129 #endif
130 }
131 
135 {
136  JLTRACEG("Entry");
137  type = static_cast<XsProtocolType>(ProtocolHandler::type());
138  MessageLocation rv;
139 
140  int bufferSize = (int)raw.size();
141  if (bufferSize == 0)
142  return rv;
143 
144  const unsigned char* buffer = raw.data();
145 
146  // loop through the buffer to find a preamble
147  for (int pre = 0; pre < bufferSize; ++pre)
148  {
149  if (buffer[pre] == XS_PREAMBLE)
150  {
151  JLTRACEG("Preamble found at " << pre);
152  int remaining = bufferSize - pre; // remaining bytes in buffer INCLUDING preamble
153 
154  if (remaining < XS_LEN_MSGHEADERCS)
155  {
156  JLTRACEG("Not enough header data read");
157  if (rv.m_incompletePos == -1)
158  {
159  rv.m_incompletePos = pre;
161  }
162  break;
163  }
164 
165  // read header
166  const uint8_t* msgStart = &(buffer[pre]);
167  const XsMessageHeader* hdr = (const XsMessageHeader*)msgStart;
168  if (hdr->m_busId == 0 && hdr->m_messageId == 0)
169  {
170  // found 'valid' message that isn't actually valid... happens inside GPS raw data
171  // skip to next preamble
172  // and completely ignore this message, since it cannot be valid
173  //JLDEBUGG("Found invalid valid message");
174  continue;
175  }
176 
177  // check the reported size
178  int target = expectedMessageSize(&buffer[pre], remaining);
179 
180  JLTRACEG("Bytes in buffer=" << remaining << ", full target = " << target);
181 
183  {
184  // skip current preamble
185  JLALERTG("Invalid message length: " << target);
186  continue;
187  }
188 
189  if (remaining < target)
190  {
191  // not enough data read, skip current preamble
192  JLTRACEG("Not enough data read: " << remaining << " / " << target);
193  if (rv.m_incompletePos == -1)
194  {
195  rv.m_incompletePos = pre;
196  rv.m_incompleteSize = target;
197  }
198  continue;
199  }
200 
201  XsMessage rcv;
202  // we have read enough data to fulfill our target so we'll try to parse the message
203  // and check the checksum
204  if (rcv.loadFromString(msgStart, (uint16_t)target))
205  {
206  JLTRACEG("OK, size = " << (int) rcv.getTotalMessageSize() << " buffer: " << dumpBuffer(msgStart, target));
207  rv.m_size = (int) rcv.getTotalMessageSize();
208  rv.m_startPos = pre;
209 #if 0
210  JLDEBUGG("OK: rv.m_size = " << rv.m_size <<
211  " rv.m_startPos = " << rv.m_startPos <<
212  " rv.m_incompletePos = " << rv.m_incompletePos <<
213  " pre = " << pre << " msg " << dumpBuffer(msgStart, target) <<
214  " buffer " << dumpBuffer(buffer, bufferSize));
215 #endif
216  break;
217  }
218 
219  // Only alert the checksum error if this is not an embedded message
220  if (rv.m_incompletePos == -1)
221  {
222  JLALERTG(
223  "Invalid checksum for msg at offset " << pre << " bufferSize = " << bufferSize
224  << " buffer at offset: " << dumpBuffer(raw.data() + pre, raw.size() - pre));
225  }
226  else
227  {
228  JLTRACEG("Invalid checksum, size = " << (int)rcv.getTotalMessageSize() << " buffer: " << dumpBuffer(msgStart, target));
229  }
230  }
231  }
232 
233  JLTRACEG("Exit");
234  return rv;
235 }
236 
240 {
241  XsMessage message;
242 
243  const unsigned char* buffer = raw.data();
244  const uint8_t* msgStart = &(buffer[location.m_startPos]);
245 
246  if (message.loadFromString(msgStart, (uint16_t)location.m_size))
247  {
248  JLTRACEG("OK, size = " << (int)message.getTotalMessageSize() << " buffer: " << dumpBuffer(msgStart, location.m_size));
249  location.m_size = (int)message.getTotalMessageSize();
250 
251  return message;
252  }
253 
254  message.clear();
255  location.m_startPos = -1;
256  location.m_incompletePos = -1;
257 
258  return message;
259 }
260 
263 {
264  return XS_LEN_MSGHEADERCS; // minimum size of xsens xbus protocol message
265 }
266 
269 {
270  return XS_LEN_MSGEXTHEADERCS + XS_MAXDATALEN; // maximum size of xsens xbus protocol message
271 }
272 
279 {
280  if (msg.getTotalMessageSize() < 5) // minimum size of an xsens message including envelope is 5 bytes
281  return -1;
282 
283  raw.assign(msg.getTotalMessageSize(), msg.getMessageStart());
284  return (int) raw.size();
285 }
286 
288 {
289  return XPT_Xbus;
290 }
291 
293 {
294  m_ignoreMaxMsgSize = ignore;
295 }
XS_MAXDATALEN
#define XS_MAXDATALEN
Definition: xsmessage.h:157
ProtocolHandler::convertToMessage
XsMessage convertToMessage(MessageLocation &location, const XsByteArray &raw) const override
Converts raw data using location into a XsMessage object.
Definition: protocolhandler.cpp:239
msg
msg
XsMessageHeader
A message header.
Definition: xsmessage.h:169
XsByteArray
A list of uint8_t values.
XsMessageHeader::m_busId
uint8_t m_busId
The bus ID.
Definition: xsmessage.h:172
ProtocolHandler::m_ignoreMaxMsgSize
bool m_ignoreMaxMsgSize
Definition: protocolhandler.h:73
ProtocolHandler::~ProtocolHandler
virtual ~ProtocolHandler()
Destructor.
Definition: protocolhandler.cpp:91
XsMessageHeader::LengthData::m_extended
struct XsMessageHeader::LengthData::ExtendedLength m_extended
The extended length, only valid if normal length is 255.
ProtocolHandler::maximumMessageSize
int maximumMessageSize() const override
Returns the maximum size of a valid message of this protocol including preambles and checksums.
Definition: protocolhandler.cpp:268
protocolhandler.h
XsMessageHeader::m_length
uint8_t m_length
The length of the message.
Definition: xsmessage.h:174
JLALERTG
#define JLALERTG(msg)
Definition: journaller.h:281
XsMessageHeader::LengthData::ExtendedLength::m_length
struct XsMessageHeader::LengthData::ExtendedLength::ExtendedParts m_length
Extended length, only valid if normal length is 255.
ProtocolHandler::type
int type() const override
Returns the type of the protocol handler.
Definition: protocolhandler.cpp:287
XsMessageHeader::LengthData::ExtendedLength::ExtendedParts::m_low
uint8_t m_low
Low byte of extended length.
Definition: xsmessage.h:186
XsMessageHeader::m_datlen
union XsMessageHeader::LengthData m_datlen
Data or length and data.
ProtocolHandler::composeMessage
static int composeMessage(XsByteArray &raw, const XsMessage &msg)
Compose a message for transmission.
Definition: protocolhandler.cpp:278
XS_LEN_MSGHEADERCS
#define XS_LEN_MSGHEADERCS
Definition: xsmessage.h:149
uint32_t
unsigned int uint32_t
Definition: pstdint.h:485
MessageLocation::m_size
int m_size
The size of the message, when less than 0 it indicates the expected message size.
Definition: messagelocation.h:74
JLTRACEG
#define JLTRACEG(msg)
Definition: journaller.h:279
DUMP_BUFFER_ON_ERROR
#define DUMP_BUFFER_ON_ERROR
Definition: protocolhandler.cpp:69
XsSize
size_t XsSize
XsSize must be unsigned number!
Definition: xstypedefs.h:74
MessageLocation::m_incompleteSize
int m_incompleteSize
Definition: messagelocation.h:89
XS_LEN_MSGEXTHEADERCS
#define XS_LEN_MSGEXTHEADERCS
Definition: xsmessage.h:150
expectedMessageSize
static int expectedMessageSize(const unsigned char *buffer, int sz)
Compute the expected message size given a possibly incomplete message.
Definition: protocolhandler.cpp:98
XsMessage
Structure for storing a single message.
Definition: xsmessage.h:202
XS_EXTLENCODE
#define XS_EXTLENCODE
Definition: xsmessage.h:145
XPT_Xbus
@ XPT_Xbus
The Xsens Xbus protocol, enabled by default, always 0.
Definition: xsprotocoltype.h:74
xsmessage.h
MessageLocation::m_incompletePos
int m_incompletePos
Definition: messagelocation.h:82
JLDEBUGG
#define JLDEBUGG(msg)
Definition: journaller.h:280
ProtocolHandler::ignoreMaximumMessageSize
void ignoreMaximumMessageSize(bool ignore) override
Tells the protocol handler to ignore/expand its maximum message size.
Definition: protocolhandler.cpp:292
XsProtocolType
XsProtocolType
Protocol types (XsDevice::enableProtocol())
Definition: xsprotocoltype.h:72
dumpBuffer
std::string dumpBuffer(const uint8_t *buff, XsSize sz)
Write the contents of a uint8 buffer to string as hex characters.
Definition: protocolhandler.cpp:116
XsMessageHeader::LengthData::ExtendedLength::ExtendedParts::m_high
uint8_t m_high
High byte of extended length.
Definition: xsmessage.h:185
ProtocolHandler::ProtocolHandler
ProtocolHandler()
Default constructor.
Definition: protocolhandler.cpp:86
XS_PREAMBLE
#define XS_PREAMBLE
Definition: xsmessage.h:144
ProtocolHandler::minimumMessageSize
int minimumMessageSize() const override
Returns the minimum size of a valid message of this protocol including preambles and checksums.
Definition: protocolhandler.cpp:262
xsresultvalue.h
XsMessageHeader::m_messageId
uint8_t m_messageId
The message ID.
Definition: xsmessage.h:173
MessageLocation
Stores the location of a message in a buffer using a start position and a size.
Definition: messagelocation.h:70
MessageLocation::m_startPos
int m_startPos
The offset of the first byte of the message or -1 if no message.
Definition: messagelocation.h:73
ProtocolHandler::findMessage
MessageLocation findMessage(XsProtocolType &type, const XsByteArray &raw) const override
Find the first message in the raw byte stream.
Definition: protocolhandler.cpp:134


xsens_mti_driver
Author(s):
autogenerated on Sun Sep 3 2023 02:43:20