devicecommunicator.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 "devicecommunicator.h"
66 #include "xsdevice_def.h"
67 
68 #include <xstypes/xsbusid.h>
69 #include <xstypes/xsmessage.h>
70 #include <xstypes/xsfilepos.h>
71 #include "protocolhandler.h"
72 
73 #ifdef LOG_COMMUNICATOR_RX_TX
74  #include <xscommon/xprintf.h>
75 #endif
76 
84  : m_gotoConfigTimeout(m_defaultGotoConfigTimeout)
85  , m_nextRxChannelId(0)
86 #ifdef LOG_COMMUNICATOR_RX_TX_TIMESTAMPED
87  , m_logStart(XsTimeStamp::now())
88 #endif
89 {
90  assert(rxChannels > 0);
91 
92  for (XsSize i = 0; i < rxChannels; ++i)
93  addRxChannel();
94 
95 #ifdef LOG_COMMUNICATOR_RX_TX
96  generateLogFiles();
97 #endif
98 }
99 
101 {
102 }
103 
111 {
112  XsXbusMessageId expected = static_cast<XsXbusMessageId>(msg.getMessageId() + 1);
113 
114  std::shared_ptr<ReplyObject> reply = addReplyObject(expected);
115  if (!writeMessage(msg))
116  {
117  rcv.clear();
118  JLALERTG("Failed to write message because " << lastResult() << " " << lastResultText());
119  return false;
120  }
121 
122  rcv = reply->message(timeout);
123  if (rcv.getMessageId() == expected)
124  return true;
125 
126  if (rcv.getMessageId() == XMID_Error)
127  {
128  setLastResult(static_cast<XsResultValue>(rcv.getDataByte(0)));
129  JLALERTG("Received error " << lastResult());
130  }
131  else
132  {
134  JLALERTG("Timeout waiting for reply to " << msg.getMessageId() << ", timeout = " << timeout << " ms.");
135  }
136 
137  return false;
138 }
139 
144 {
145  (void)enable;
146 }
147 
159 {
160  if (timeout)
161  m_gotoConfigTimeout = timeout;
162  else
164 }
165 
169 {
170  XsMessage snd(XMID_ReqDid);
171  snd.setBusId(XS_BID_MASTER);
172 
173  XsMessage rcv_did;
174  if (!doTransaction(snd, rcv_did))
176 
177  uint64_t deviceId = rcv_did.getDataLong();
178  if (rcv_did.getDataSize() == 8)
179  {
180  XsDeviceId did1(deviceId);
181  XsDeviceId did2(rcv_did.getDataLong(4));
182  if (!did1.isLegacyDeviceId() || !did2.isLegacyDeviceId())//a must-have workaround for Mk5s with FTT firmware
183  deviceId = rcv_did.getDataLongLong();
184  }
185 
186  XsMessage rcv_pdc;
187  XsString productCode;
188  snd.setMessageId(XMID_ReqProductCode);
189  if (doTransaction(snd, rcv_pdc))
190  {
191  const char* pc = (const char*) rcv_pdc.getDataBuffer();
192  std::string result(pc ? pc : "", rcv_pdc.getDataSize());
193  std::string::size_type thingy = result.find(" ");
194  if (thingy < rcv_pdc.getDataSize())
195  result.erase(result.begin() + (unsigned)thingy, result.end());
196  productCode = result;
197  }
198 
199  XsMessage rcv_hw;
200  snd.setMessageId(XMID_ReqHardwareVersion);
201  uint16_t hardwareVersion = 0;
202  if (doTransaction(snd, rcv_hw))
203  hardwareVersion = rcv_hw.getDataShort();
204 
205  setMasterDeviceId(XsDeviceId(productCode.c_str(), hardwareVersion, 0, deviceId));
206 
207  return XRV_OK;
208 }
209 
213 {
214  XsMessage snd(XMID_GotoConfig), rcv;
215  snd.setBusId(XS_BID_MASTER);
216 
217  JLDEBUGG("Sending gotoConfig");
218  if (!doTransaction(snd, rcv, gotoConfigTimeout()))
219  {
220  JLALERTG("Failed to go to config, XRV: " << rcv.toResultValue());
221  return setAndReturnLastResult(rcv.toResultValue());
222  }
223  JLDEBUGG("Received gotoConfig ACK");
225 }
226 
230 {
231  JLDEBUGG("");
233  snd.setBusId(XS_BID_MASTER);
234 
235  if (!doTransaction(snd, defaultTimeout()))
236  {
237  JLDEBUGG("Transaction failed");
239  }
240  JLDEBUGG("Now in measurement mode");
242 }
243 
249 {
250  XsByteArray raw;
251  if (ProtocolHandler::composeMessage(raw, message) < 0)
252  {
254  return false;
255  }
256  JLTRACEG("did: " << masterDeviceId() << " writing message " << message.toHexString(10));
258  if (lastResult() == XRV_OK)
259  {
260 #ifdef LOG_COMMUNICATOR_RX_TX
261  logTxStream(message);
262 #endif
263  if (masterDevice() != nullptr)
264  masterDevice()->onMessageSent(message);
265  return true;
266  }
267  return false;
268 }
269 
275 {
276  RxChannelId channel = m_nextRxChannelId++;
278  return channel;
279 }
280 
290 XsResultValue DeviceCommunicator::extractMessages(const XsByteArray& rawIn, std::deque<XsMessage>& messages, RxChannelId channel)
291 {
292  if (channel >= m_messageExtractors.size())
293  return XRV_ERROR;
294 
295  assert(protocolManager());
296 
297  XsResultValue res = m_messageExtractors[channel].processNewData(masterDevice(), rawIn, messages);
298 
299  if (res == XRV_OK)
300  {
301  for (auto const& msg : messages)
302  {
303  if (masterDevice() != nullptr)
305  }
306  }
307  return res;
308 }
309 
313 {
314  return m_messageExtractors.size();
315 }
316 
320 {
321  assert(channel < m_messageExtractors.size());
322  return m_messageExtractors[channel];
323 }
324 
328 {
329 #ifdef LOG_COMMUNICATOR_RX_TX
330  logRxStream(message);
331 #endif
333 }
334 
335 /* Now the disabled stuff starts */
336 
339 {
340 }
341 
343 {
344  return XsMessage();
345 }
346 
347 std::deque<XsMessage> DeviceCommunicator::readMessagesFromStartOfFile(uint8_t, int)
348 {
349  return std::deque<XsMessage>();
350 }
351 
353 {
354 }
355 
357 {
358  return XRV_UNSUPPORTED;
359 }
360 
362 {
363  return XRV_UNSUPPORTED;
364 }
365 
367 {
368 }
369 
371 {
372  return false;
373 }
374 
376 {
377  return XsString();
378 }
379 
381 {
382  return 0;
383 }
384 
386 {
387  return 0;
388 }
389 
391 {
392  return XsFilePos(0);
393 }
394 
396 {
397 }
398 
400 {
401  return false;
402 }
403 
405 {
406 }
407 
409 {
410  return XsMessage();
411 }
412 
414 
415 #ifdef LOG_COMMUNICATOR_RX_TX
416 void DeviceCommunicator::generateLogFiles()
417 {
418  XsString date = XsTime::getDateAsString();
419  XsString time = XsTime::getTimeAsString();
420 
421 #ifdef LOG_COMMUNICATOR_RX_TX_TIMESTAMPED
422  XsString extension("mts");
423 #else
424  XsString extension("mtb");
425 #endif
426 
427  auto generateFilename = [&](XsString const & stream)
428  {
429  std::string temp = xprintf("communicator_%s_%s_%s.%s", stream.c_str(), date.c_str(), time.c_str(), extension.c_str());
430  return XsString(temp);
431  };
432 
433  m_rxLog.create(generateFilename("rx"), false);
434  m_txLog.create(generateFilename("tx"), false);
435 }
436 
437 void DeviceCommunicator::logTxStream(XsMessage const& msg)
438 {
439  assert(m_txLog.isOpen());
440 
441 #ifdef LOG_COMMUNICATOR_RX_TX_TIMESTAMPED
442  XsTimeStamp diff = XsTimeStamp::now() - m_logStart;
443  std::string timestamp = xprintf("%d ", diff.msTime());
444  m_txLog.write(timestamp.c_str(), 1, timestamp.length());
445 #endif
446 
447  m_txLog.write(msg.rawMessage().data(), 1, msg.rawMessage().size());
448  m_txLog.flush();
449 }
450 
451 void DeviceCommunicator::logRxStream(XsMessage const& msg)
452 {
453  assert(m_rxLog.isOpen());
454 
455 #ifdef LOG_COMMUNICATOR_RX_TX_TIMESTAMPED
456  XsTimeStamp diff = XsTimeStamp::now() - m_logStart;
457  std::string timestamp = xprintf("%d ", diff.msTime());
458  m_rxLog.write(timestamp.c_str(), 1, timestamp.length());
459 #endif
460 
461  m_rxLog.write(msg.rawMessage().data(), 1, msg.rawMessage().size());
462  m_rxLog.flush();
463 }
464 
465 #endif
DeviceCommunicator::m_gotoConfigTimeout
uint32_t m_gotoConfigTimeout
Definition: devicecommunicator.h:153
XS_BID_MASTER
#define XS_BID_MASTER
The bus identifier of the master device.
Definition: xsbusid.h:73
XMID_ReqProductCode
@ XMID_ReqProductCode
Definition: xsxbusmessageid.h:118
XsString
struct XsString XsString
Definition: xsstring.h:87
XMID_GotoConfig
@ XMID_GotoConfig
Definition: xsxbusmessageid.h:158
Communicator::lastResultText
XsString lastResultText() const
Get the accompanying error text for the value returned by lastResult() It may provide situation-speci...
Definition: communicator.cpp:177
DeviceCommunicator::loadLogFile
void loadLogFile(XsDevice *device) override
Load a complete logfile.
msg
msg
XMID_GotoMeasurement
@ XMID_GotoMeasurement
Definition: xsxbusmessageid.h:101
XsMessage
struct XsMessage XsMessage
Definition: xsmessage.h:85
XsByteArray
A list of uint8_t values.
Communicator::defaultTimeout
uint32_t defaultTimeout() const
Definition: communicator.h:145
DeviceCommunicator::doTransaction
virtual bool doTransaction(const XsMessage &msg, XsMessage &rcv, uint32_t timeout) override
Write a message and await the reply.
Definition: devicecommunicator.cpp:110
DeviceCommunicator::handleMessage
void handleMessage(const XsMessage &message) override
Handles a message.
Definition: devicecommunicator.cpp:327
XMID_Error
@ XMID_Error
Definition: xsxbusmessageid.h:187
Communicator::protocolManager
std::shared_ptr< ProtocolManager > protocolManager() const
Definition: communicator.cpp:142
XRV_TIMEOUT
@ XRV_TIMEOUT
258: A timeout occurred
Definition: xsresultvalue.h:128
Communicator::setMasterDeviceId
void setMasterDeviceId(const XsDeviceId &deviceId)
Sets a master device ID.
Definition: communicator.cpp:150
Communicator::masterDeviceId
XsDeviceId masterDeviceId() const
Definition: communicator.cpp:157
DeviceCommunicator::extractMessages
XsResultValue extractMessages(const XsByteArray &rawIn, std::deque< XsMessage > &messages, RxChannelId channel=0)
Read all messages available in the incoming data stream after adding new data supplied in rawIn.
Definition: devicecommunicator.cpp:290
DeviceCommunicator::gotoConfig
XsResultValue gotoConfig(bool) override
Request a device to go to config mode.
Definition: devicecommunicator.cpp:212
Communicator::handleMessage
virtual void handleMessage(const XsMessage &message)
Handles a message.
Definition: communicator.cpp:191
Communicator::addReplyObject
std::shared_ptr< ReplyObject > addReplyObject(uint8_t mid)
Add a MidReplyObject.
Definition: communicator.cpp:274
DeviceCommunicator::gotoConfigTimeout
uint32_t gotoConfigTimeout() const
Definition: devicecommunicator.h:91
protocolhandler.h
XRV_INVALIDMSG
@ XRV_INVALIDMSG
4: The message is invalid or not implemented
Definition: xsresultvalue.h:91
JLALERTG
#define JLALERTG(msg)
Definition: journaller.h:281
DeviceCommunicator::openLogFile
bool openLogFile(const XsString &filename) override
Open the log file `.
DeviceCommunicator::addRxChannel
RxChannelId addRxChannel()
Adds an RX (receive) channel to the device communicator. Each channel maintains its own message parsi...
Definition: devicecommunicator.cpp:274
XRV_ERROR
@ XRV_ERROR
256: A generic error occurred
Definition: xsresultvalue.h:126
XsDevice::onMessageReceived
virtual XSNOEXPORT void onMessageReceived(const XsMessage &message)
DeviceCommunicator::m_defaultGotoConfigTimeout
static const uint32_t m_defaultGotoConfigTimeout
Definition: devicecommunicator.h:151
XRV_OK
@ XRV_OK
0: Operation was performed successfully
Definition: xsresultvalue.h:85
ProtocolHandler::composeMessage
static int composeMessage(XsByteArray &raw, const XsMessage &msg)
Compose a message for transmission.
Definition: protocolhandler.cpp:278
XsResultValue
XsResultValue
Xsens result values.
Definition: xsresultvalue.h:82
DeviceCommunicator::readMessage
XsMessage readMessage(uint8_t msgId=0) override
Read a message from the open file.
Communicator::lastResult
XsResultValue lastResult() const
Get the result value of the last operation.
Definition: communicator.cpp:167
DeviceCommunicator::RxChannelId
XsSize RxChannelId
A typedef for Rx chanel ID.
Definition: devicecommunicator.h:81
DeviceCommunicator::closeLogFile
void closeLogFile() override
Close the log file.
DeviceCommunicator::writeMessage
bool writeMessage(const XsMessage &message) override
Write message to the device.
Definition: devicecommunicator.cpp:248
uint32_t
unsigned int uint32_t
Definition: pstdint.h:485
DeviceCommunicator::DeviceCommunicator
DeviceCommunicator(RxChannelId rxChannels=1)
Default constructor.
Definition: devicecommunicator.cpp:83
DeviceCommunicator::writeRawData
virtual XsResultValue writeRawData(const XsByteArray &data)=0
Writes a raw data to a device.
DeviceCommunicator::m_messageExtractors
std::vector< MessageExtractor > m_messageExtractors
Definition: devicecommunicator.h:156
DeviceCommunicator::messageExtractor
MessageExtractor & messageExtractor(RxChannelId=0)
Returns the message extractor for the given rx channel.
Definition: devicecommunicator.cpp:319
DeviceCommunicator::logFileName
XsString logFileName() const override
DeviceCommunicator::~DeviceCommunicator
~DeviceCommunicator() override
Definition: devicecommunicator.cpp:100
xsbusid.h
DeviceCommunicator::logFileReadPosition
XsFilePos logFileReadPosition() const override
JLTRACEG
#define JLTRACEG(msg)
Definition: journaller.h:279
DeviceCommunicator::readMessagesFromStartOfFile
std::deque< XsMessage > readMessagesFromStartOfFile(uint8_t msgId, int maxMsgs=0) override
Read multiple similar messages from the start of the open file.
Communicator::masterDevice
XsDevice * masterDevice() const
Definition: communicator.cpp:135
DeviceCommunicator::setKeepAlive
void setKeepAlive(bool enable) override
Does nothing.
Definition: devicecommunicator.cpp:143
xsdevice_def.h
XsSize
size_t XsSize
XsSize must be unsigned number!
Definition: xstypedefs.h:74
DeviceCommunicator::abortLoadLogFile
void abortLoadLogFile() override
Aborts loading a logfile.
XsXbusMessageId
XsXbusMessageId
Xsens Xbus Message Identifiers.
Definition: xsxbusmessageid.h:73
DeviceCommunicator::readLogFile
virtual XsResultValue readLogFile(XsDevice *device)
Read a log file into cache.
XsDeviceId
struct XsDeviceId XsDeviceId
Definition: xsdeviceid.h:912
XsMessage
Structure for storing a single message.
Definition: xsmessage.h:202
DeviceCommunicator::logFileDate
XsTimeStamp logFileDate() const override
DeviceCommunicator::logFileSize
XsFilePos logFileSize() const override
DeviceCommunicator::readSinglePacketFromFile
virtual XsResultValue readSinglePacketFromFile()
Read a single XsDataPacket from an open log file.
XsDeviceId
Contains an Xsens device ID and provides operations for determining the type of device.
Definition: xsdeviceid.h:192
XsDevice::onMessageSent
virtual XSNOEXPORT void onMessageSent(const XsMessage &message)
DeviceCommunicator::readMessageFromStartOfFile
XsMessage readMessageFromStartOfFile(uint8_t msgId, int maxMsgs=0) override
Read a message from the start of the open file.
DeviceCommunicator::gotoMeasurement
XsResultValue gotoMeasurement() override
Request a device to go to measurement mode.
Definition: devicecommunicator.cpp:229
xsmessage.h
MessageExtractor
Definition: messageextractor.h:75
DeviceCommunicator::m_nextRxChannelId
RxChannelId m_nextRxChannelId
Definition: devicecommunicator.h:155
JLDEBUGG
#define JLDEBUGG(msg)
Definition: journaller.h:280
DeviceCommunicator::messageExtractorCount
XsSize messageExtractorCount() const
Returns the number of message extractor this device communicator has.
Definition: devicecommunicator.cpp:312
DeviceCommunicator::isReadingFromFile
bool isReadingFromFile() const override
DeviceCommunicator::setGotoConfigTimeout
void setGotoConfigTimeout(uint32_t timeout) override
Set the timeout for the gotoConfig function.
Definition: devicecommunicator.cpp:158
XRV_CONFIGCHECKFAIL
@ XRV_CONFIGCHECKFAIL
293: A configuration-time check of the device failed
Definition: xsresultvalue.h:165
DeviceCommunicator::getDeviceId
XsResultValue getDeviceId() override
Request a device to get device ID.
Definition: devicecommunicator.cpp:168
xprintf.h
XRV_UNSUPPORTED
@ XRV_UNSUPPORTED
303: The requested functionality is not supported by the device
Definition: xsresultvalue.h:178
Communicator::setLastResult
void setLastResult(XsResultValue lastResult, XsString const &text=XsString()) const
Sets the last result.
Definition: communicator.cpp:238
XMID_ReqHardwareVersion
@ XMID_ReqHardwareVersion
Definition: xsxbusmessageid.h:121
XMID_ReqDid
@ XMID_ReqDid
Definition: xsxbusmessageid.h:78
xsfilepos.h
XRV_COULDNOTREADSETTINGS
@ XRV_COULDNOTREADSETTINGS
271: A required settings file could not be opened or is missing some data
Definition: xsresultvalue.h:141
Communicator::setAndReturnLastResult
XsResultValue setAndReturnLastResult(XsResultValue lastResult, XsString const &text=XsString()) const
Sets the last result and returns it.
Definition: communicator.cpp:248
devicecommunicator.h
XsFilePos
int64_t XsFilePos
The type that is used for positioning inside a file.
Definition: xsfilepos.h:102
XsString
A 0-terminated managed string of characters.
XsDevice
Definition: xsdevice_def.h:164
XsTimeStamp
This class contains method to set, retrieve and compare timestamps.
Definition: xstimestamp.h:115
DeviceCommunicator::waitForLastTaskCompletion
void waitForLastTaskCompletion() override
Wait for the last processing task to complete in the threadpool.
DeviceCommunicator::resetLogFileReadPosition
void resetLogFileReadPosition(void) override
Resets the logfile read position.


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