Main MRPT website > C++ reference for MRPT 1.9.9
cmt2.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 /*! \file cmt2.cpp
11 
12  For information about objects in this file, see the appropriate header:
13  \ref Cmt2.h
14 
15  \section FileCopyright Copyright Notice
16  Copyright (C) Xsens Technologies B.V., 2006. All rights reserved.
17 
18  This source code is intended for use only by Xsens Technologies BV and
19  those that have explicit written permission to use it from
20  Xsens Technologies BV.
21 
22  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
23  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
25  PARTICULAR PURPOSE.
26 
27  \section FileChangelog Changelog
28  \par 2006-04-05, v0.0.1
29  \li Job Mulder: Created
30  \par 2006-07-21, v0.1.0
31  \li Job Mulder: Updated file for release 0.1.0
32 */
33 
34 #include "cmt2.h"
35 
36 namespace xsens
37 {
38 #ifdef _LOG_CMT2
39 #define CMT2LOG CMTLOG
40 #else
41 #define CMT2LOG(...)
42 #endif
43 
44 //////////////////////////////////////////////////////////////////////////////////////////
45 int32_t findValidMessage(const uint8_t* buffer, const uint16_t bufferLength)
46 {
47  MessageHeader* hdr = nullptr;
48  uint16_t pre = 0;
49  uint16_t target;
50  bool extended;
52  int32_t res;
53  Message* msg;
54 
55  // find the preamble
56  while (pre < bufferLength && (buffer[pre] != CMT_PREAMBLE)) ++pre;
57 
58  if (pre >= bufferLength) return -1;
59 
60  // check if the message is valid
61  length = bufferLength - pre;
62  if (length < CMT_LEN_MSGHEADERCS) return -1;
63 
64  // parse header
65 
66  hdr = (MessageHeader*)(buffer + pre);
67  if (hdr->m_length == CMT_EXTLENCODE)
68  {
69  extended = true;
70  if (length < CMT_LEN_MSGEXTHEADERCS) return -1;
71  }
72  else
73  extended = false;
74 
75  // check the reported size
76  target = extended
77  ? ((uint16_t)hdr->m_datlen.m_extended.m_length.m_high * 256 +
81  if (target <= length)
82  {
83  // header seems to be ok, check checksum
84  // check the checksum
85 
86  msg = new Message(buffer + pre, (uint16_t)target, (uint16_t)target);
87  if (msg->isChecksumOk())
88  {
89  delete msg;
90  return (int32_t)pre;
91  }
92  delete msg;
93  }
94 
95  // try next message
96  res = findValidMessage(buffer + pre + 1, length - 1);
97  if (res == -1) return -1;
98  return res + pre + 1;
99 }
100 
101 //////////////////////////////////////////////////////////////////////////////////////////
102 ///////////////////////////////////////// Cmt2s
103 ////////////////////////////////////////////
104 //////////////////////////////////////////////////////////////////////////////////////////
105 
106 //////////////////////////////////////////////////////////////////////////////////////////
107 // Default constructor, initializes all members to their default values.
108 Cmt2s::Cmt2s() : m_onMessageReceived(nullptr), m_onMessageSent(nullptr)
109 {
111  m_readBufferCount = 0;
114  m_toEnd = 0;
115 }
116 
117 //////////////////////////////////////////////////////////////////////////////////////////
118 // Destructor, de-initializes, frees memory allocated for buffers, etc.
121 {
122  if (m_cmt1s.getPortNr())
123  {
124  CMT2LOG("L2: Closing port %d\n", (int32_t)m_cmt1s.getPortNr());
125  m_toEnd = 0;
126  return m_lastResult = m_cmt1s.close();
127  }
128  else
129  return m_lastResult = XRV_NOPORTOPEN;
130 }
131 
132 //////////////////////////////////////////////////////////////////////////////////////////
133 // Retrieve the port that the object is connected to.
135 {
136  m_cmt1s.getPortName(portname);
137  // we know there should be at least "/dev/x"
138  if (strlen(portname) < 6) return m_lastResult = XRV_ERROR;
139  return m_lastResult = XRV_OK;
140 }
141 
142 //////////////////////////////////////////////////////////////////////////////////////////
143 // Retrieve the port that the object is connected to.
145 {
146  port = m_cmt1s.getPortNr();
147  if (port == 0) return m_lastResult = XRV_ERROR;
148  return m_lastResult = XRV_OK;
149 }
150 
151 //////////////////////////////////////////////////////////////////////////////////////////
152 // Retrieve the port that the object is connected to.
154 {
155  port = m_cmt1s.getPortNr();
156  if (port == 0) return m_lastResult = XRV_ERROR;
157  return m_lastResult = XRV_OK;
158 }
159 
160 //////////////////////////////////////////////////////////////////////////////////////////
161 // Open a communication channel to the given serial port name.
162 XsensResultValue Cmt2s::open(const char* portName, const uint32_t baudRate)
163 {
164  CMT2LOG("L2: Opening port %s @baud %d\n", portName, baudRate);
165  m_baudrate = baudRate;
166  m_lastResult = m_cmt1s.open(portName, baudRate);
167  m_toEnd = 0;
168  CMT2LOG(
169  "L2: Port open result %d: %s\n", (int32_t)m_lastResult,
171  return m_lastResult;
172 }
173 
174 #ifdef _WIN32
175 //////////////////////////////////////////////////////////////////////////////////////////
176 // Open a communication channel to the given COM port number.
177 XsensResultValue Cmt2s::open(const uint32_t portNumber, const uint32_t baudRate)
178 {
179  CMT2LOG("L2: Opening port %d @baud %d\n", (int32_t)portNumber, baudRate);
180  m_baudrate = baudRate;
181  m_lastResult = m_cmt1s.open(portNumber, baudRate);
182  m_toEnd = 0;
183  CMT2LOG(
184  "L2: Port open result %d: %s\n", (int32_t)m_lastResult,
186  return m_lastResult;
187 }
188 #endif
189 
190 //////////////////////////////////////////////////////////////////////////////////////////
191 // Read a message from the COM port.
193 {
195  uint16_t pre = 0;
196  uint32_t length = 0;
197  uint32_t target = 0;
198  uint16_t i;
199  bool extended = false;
200 
201  CMT2LOG("L2: readMessage started, bufferCount=%u\n", m_readBufferCount);
202 
203  if (m_readBufferCount == 0)
204  m_readBuffer[0] = (uint8_t)~CMT_PREAMBLE; // create a value that is
205  // definitely NOT a preamble
206 
210  &length);
212 
213  while (m_readBufferCount > 0)
214  {
215  while (m_readBufferCount > 0)
216  {
217  // find preamble
218  while ((pre < m_readBufferCount) &&
219  (m_readBuffer[pre] != CMT_PREAMBLE))
220  ++pre;
221 
222  if (pre == m_readBufferCount)
223  {
224  CMT2LOG("L2: readMessage no preamble found in buffer\n");
225  m_readBufferCount = 0;
226  return m_lastResult = XRV_TIMEOUT;
227  }
228 
229  CMT2LOG(
230  "L2: readMessage preamble found at position %u\n",
231  (uint32_t)pre);
232  // shift buffer to start
233  if (pre)
234  {
235  m_readBufferCount -= pre;
236  for (i = 0; i < m_readBufferCount; ++i)
237  m_readBuffer[i] = m_readBuffer[i + pre];
238  }
239 
241  {
242  CMT2LOG("L2: readMessage not enough header data read\n");
243  return m_lastResult = XRV_TIMEOUT;
244  }
245 
246  // read header
247  if (hdr->m_length == CMT_EXTLENCODE)
248  {
249  extended = true;
251  {
252  CMT2LOG(
253  "L2: readMessage not enough extended header data "
254  "read\n");
255  return m_lastResult = XRV_TIMEOUT;
256  }
257  }
258  else
259  extended = false;
260 
261  // check the reported size
262  target =
263  (extended
265  256 +
267  : (uint16_t)(hdr->m_length));
268  CMT2LOG(
269  "L2: readMessage bytes in buffer=%u, extended=%u, target=%u\n",
270  (uint32_t)m_readBufferCount, (uint32_t)extended,
271  (uint32_t)target);
272  if ((uint32_t)target > (uint32_t)CMT_MAXDATALEN)
273  {
274  // skip current preamble
275  pre = 1;
276  CMT2LOG(
277  "L2: readMessage invalid message length %u\n",
278  (uint32_t)target);
279  continue;
280  }
281  break; // everything seems to be ok, get out of inner while() loop
282  }
283 
284  // header seems to be ok, read until end and check checksum
285  if (extended)
286  target += CMT_LEN_MSGEXTHEADERCS;
287  else
288  target += CMT_LEN_MSGHEADERCS;
289 
290  // read the entire message
291  if (m_readBufferCount < target)
292  {
293  CMT2LOG(
294  "L2: readMessage readBufferCount %u < target %u\n",
296  return m_lastResult = XRV_TIMEOUT;
297  }
298 
299  // check the checksum
300  if (rcv->loadFromString(m_readBuffer, (uint16_t)target) == XRV_OK)
301  {
302  CMT2LOG("L2: readMessage OK\n");
303  if (m_onMessageReceived != nullptr)
304  {
305  CmtBinaryData* bytes =
306  (CmtBinaryData*)malloc(sizeof(CmtBinaryData));
307  bytes->m_size = target;
308  bytes->m_portNr = m_cmt1s.getPortNr();
309  // bytes->m_type = CMT_CALLBACK_ONMESSAGERECEIVED;
310  memcpy(bytes->m_data, m_readBuffer, target);
311 #ifdef _LOG_CALLBACKS
312  CMTLOG(
313  "C2: m_onMessageReceived(%d,(%d,%d),%p)\n",
315  (int32_t)bytes->m_size, (int32_t)bytes->m_portNr,
317 #endif
320  bytes, m_onMessageReceivedParam);
321  }
322 
323  m_readBufferCount -= (uint16_t)target;
324  if (m_readBufferCount)
325  for (i = 0; i < m_readBufferCount; ++i)
326  m_readBuffer[i] = m_readBuffer[i + target];
327 
328  return m_lastResult = XRV_OK;
329  }
330  CMT2LOG(
331  "L2: readMessage invalid checksum %02x %02x %02x %02x %02x\n",
332  rcv->getMessageStart()[0], rcv->getMessageStart()[1],
333  rcv->getMessageStart()[2], rcv->getMessageStart()[3],
334  rcv->getMessageStart()[4]);
335  // skip current preamble
336  pre = 1;
337  }
338 
339  CMT2LOG("L2: readMessage timed out\n");
340  // a timeout occurred
341  return m_lastResult = XRV_TIMEOUT;
342 }
343 
344 //////////////////////////////////////////////////////////////////////////////////////////
345 // Set the callback function for when a message has been received or sent
348  void* param)
349 {
350  switch (tp)
351  {
353  m_onMessageReceived = func;
354  m_onMessageReceivedInstance = instance;
356  return m_lastResult = XRV_OK;
358  m_onMessageSent = func;
359  m_onMessageSentInstance = instance;
361  return m_lastResult = XRV_OK;
362  default:
363  break;
364  }
366 }
367 
368 //////////////////////////////////////////////////////////////////////////////////////////
369 // Set the default timeout value to use in blocking operations.
371 {
372  CMT2LOG("L2: Setting timeout to %u ms\n", ms);
373  if ((m_lastResult = m_cmt1s.setTimeout(ms / 2)) != XRV_OK)
374  return m_lastResult; // this can't actually happen
375  m_timeout = ms;
376  m_toEnd = 0;
377  return (m_lastResult = XRV_OK);
378 }
379 
380 //////////////////////////////////////////////////////////////////////////////////////////
381 // Wait for a message to arrive.
383  Message* rcv, const uint8_t msgId, uint32_t timeoutOverride,
384  bool acceptErrorMessage)
385 {
387  uint16_t pre = 0;
388  uint32_t length = 0;
389  uint32_t target;
390  uint16_t i;
391  bool extended;
392  bool readsome = (m_readBufferCount > 0);
393  uint32_t toRestore = m_toEnd;
394 
395  CMT2LOG(
396  "L2: waitForMessage x%02x, TO=%u, TOend=%u, TOO=%u\n", (uint32_t)msgId,
397  m_timeout, m_toEnd, timeoutOverride);
398 
399  // The end-time may be misinterpreted around midnight, where it may be
400  // considered
401  // expired even if this is not the case. However, this is extremely rare.
402  if (m_toEnd == 0)
403  {
404  if (timeoutOverride != 0)
405  m_toEnd = (getTimeOfDay() + (uint32_t)timeoutOverride) %
407  else
408  m_toEnd =
410  if (m_toEnd == 0) m_toEnd = 1;
411  }
412 
413  if (m_readBufferCount == 0)
414  m_readBuffer[0] = (uint8_t)~CMT_PREAMBLE; // create a value that is
415  // definitely NOT a preamble
416 
417  do
418  {
419  // find preamble
420  while (m_readBuffer[pre] != CMT_PREAMBLE)
421  {
422  if ((++pre) >= m_readBufferCount)
423  {
424  m_readBufferCount = 0;
425  pre = 0;
426  if (m_toEnd >= getTimeOfDay())
427  {
431  if (m_readBufferCount > 0) readsome = true;
432  }
433  }
434  if (m_toEnd < getTimeOfDay()) break;
435  }
436  // shift buffer to start
437  if (pre)
438  {
439  m_readBufferCount -= pre;
440  for (i = 0; i < m_readBufferCount; ++i)
441  {
442  m_readBuffer[i] = m_readBuffer[i + pre];
443  }
444  }
445 
446  pre = 1; // make sure we skip the first item in the next iteration
447  // read header
449  (m_toEnd >= getTimeOfDay()))
450  {
455  }
457  (m_toEnd < getTimeOfDay()))
458  {
459  CMT2LOG(
460  "L2: waitForMessage timeout occurred trying to read header\n");
461  break;
462  }
463 
464  if (hdr->m_length == CMT_EXTLENCODE)
465  {
466  extended = true;
468  (m_toEnd >= getTimeOfDay()))
469  {
474  }
476  (m_toEnd < getTimeOfDay()))
477  {
478  CMT2LOG(
479  "L2: waitForMessage timeout occurred trying to read "
480  "extended header\n");
481  break;
482  }
483  }
484  else
485  extended = false;
486 
487  // check the reported size
488  if (extended &&
489  (((uint16_t)hdr->m_datlen.m_extended.m_length.m_high * 256 +
492  continue;
493 
494  // header seems to be ok, read until end and check checksum
495  if (extended)
496  target = ((uint16_t)hdr->m_datlen.m_extended.m_length.m_high * 256 +
499  else
500  target = hdr->m_length + CMT_LEN_MSGHEADERCS;
501 
502  // read the entire message
503  while ((m_readBufferCount < target) && (m_toEnd >= getTimeOfDay()))
504  {
507  &length);
509  }
510  if ((m_readBufferCount < target) && (m_toEnd < getTimeOfDay()))
511  {
512  CMT2LOG("L2: waitForMessage timeout occurred\n");
513  break;
514  }
515 
516  // check the checksum
517  // msg=new Message(m_readBuffer,(uint16_t) target, (uint16_t) target);
518  if (rcv->loadFromString(m_readBuffer, (uint16_t)target) == XRV_OK)
519  {
520  CMT2LOG(
521  "L2: waitForMessage received msg Id x%02x while expecting "
522  "x%02x, msg size=%u\n",
523  (uint32_t)rcv->getMessageId(), (uint32_t)msgId, target);
524  if (m_onMessageReceived != nullptr)
525  {
526  CmtBinaryData* bytes =
527  (CmtBinaryData*)malloc(sizeof(CmtBinaryData));
528  bytes->m_size = target;
529  bytes->m_portNr = m_cmt1s.getPortNr();
530  // bytes->m_type = CMT_CALLBACK_ONMESSAGERECEIVED;
531  memcpy(bytes->m_data, m_readBuffer, target);
532 #ifdef _LOG_CALLBACKS
533  CMTLOG(
534  "C2: m_onMessageReceived(%d,(%d,%d),%p)\n",
536  (int32_t)bytes->m_size, (int32_t)bytes->m_portNr,
538 #endif
541  bytes, m_onMessageReceivedParam);
542  }
543 
544  m_readBufferCount -= (uint16_t)target;
545  if (m_readBufferCount)
546  {
547  for (i = 0; i < m_readBufferCount; ++i)
548  {
549  m_readBuffer[i] = m_readBuffer[i + target];
550  }
551  }
552 
553  if ((msgId == 0) || (msgId == rcv->getMessageId()) ||
554  (acceptErrorMessage && rcv->getMessageId() == CMT_MID_ERROR))
555  {
556  m_toEnd = toRestore;
557  return m_lastResult = XRV_OK;
558  }
559  }
560  else
561  {
562  rcv->clear();
563  CMT2LOG("L2: waitForMessage load from string failed\n");
564  }
565  } while (m_toEnd >= getTimeOfDay());
566 
567  // a timeout occurred
568  if (readsome)
569  {
570  // check if the current data contains a valid message
572 
573  if (pos != -1)
574  {
575  CMT2LOG("L2: waitForMessage found message in message\n");
576  // shift data to start of buffer
577  pre = (uint16_t)pos;
578  m_readBufferCount -= pre;
579  for (i = 0; i < m_readBufferCount; ++i)
580  {
581  m_readBuffer[i] = m_readBuffer[i + pre];
582  }
584  rcv, msgId, 0, acceptErrorMessage); // parse the message
585  m_toEnd = toRestore;
586  return m_lastResult; // set by waitForMessage
587  }
588 
590  }
591  else
593  m_toEnd = toRestore;
594  return m_lastResult;
595 }
596 
597 //////////////////////////////////////////////////////////////////////////////////////////
598 // Send a message over the COM port.
600 {
601  CMT2LOG(
602  "L2: writeMessage %2x %2x %2x %2x %2x\n",
603  (int32_t)msg->getMessageStart()[0], (int32_t)msg->getMessageStart()[1],
604  (int32_t)msg->getMessageStart()[2], (int32_t)msg->getMessageStart()[3],
605  (int32_t)msg->getMessageStart()[4]);
606  uint32_t written = 0;
608  msg->getTotalMessageSize(), msg->getMessageStart(), &written);
609 
610  if (m_lastResult != XRV_OK)
611  {
612  CMT2LOG(
613  "L2: writeMessage returns %d: %s\n", (int32_t)m_lastResult,
615  return m_lastResult;
616  }
617 
618  if (written != msg->getTotalMessageSize())
619  {
620  CMT2LOG(
621  "L2: writeMessage wrote %u of %u bytes, returns %d: %s\n", written,
624  return (m_lastResult = XRV_ERROR);
625  }
626 
627  if (m_onMessageSent != nullptr)
628  {
629  CmtBinaryData* bytes = (CmtBinaryData*)malloc(sizeof(CmtBinaryData));
630  bytes->m_size = msg->getTotalMessageSize();
631  bytes->m_portNr = m_cmt1s.getPortNr();
632  memcpy(
633  bytes->m_data, msg->getMessageStart(), msg->getTotalMessageSize());
634 #ifdef _LOG_CALLBACKS
635  CMTLOG(
636  "C2: m_onMessageSent(%d,(%d,%d),%p)\n",
639 #endif
643  }
644 
645  CMT2LOG("L2: writeMessage successful\n");
646  return (m_lastResult = XRV_OK);
647 }
648 
649 //////////////////////////////////////////////////////////////////////////////////////////
650 ///////////////////////////////////////// Cmt2f
651 ////////////////////////////////////////////
652 //////////////////////////////////////////////////////////////////////////////////////////
653 
654 //////////////////////////////////////////////////////////////////////////////////////////
655 // Default constructor
657 {
659  m_readOnly = true;
660 }
661 
662 //////////////////////////////////////////////////////////////////////////////////////////
663 // Destructor.
665 //////////////////////////////////////////////////////////////////////////////////////////
666 // Close the file.
668 {
669  if (!m_cmt1f.isOpen()) return m_lastResult = XRV_NOFILEOPEN;
670 
671  // save any unsaved data
672  // close the file
673  m_cmt1f.close();
674  m_readOnly = true;
675  return m_lastResult = XRV_OK;
676 }
677 
678 //////////////////////////////////////////////////////////////////////////////////////////
679 // Close the file and delete it.
681 {
682  if (!m_cmt1f.isOpen()) return m_lastResult = XRV_NOFILEOPEN;
683 
684  // close the file
686  m_readOnly = true;
687  return m_lastResult = XRV_OK;
688 }
689 
690 //////////////////////////////////////////////////////////////////////////////////////////
691 // Create a new file with level 2 header
692 XsensResultValue Cmt2f::create(const char* filename)
693 {
694  if (m_cmt1f.isOpen()) return m_lastResult = XRV_ALREADYOPEN;
695 
696  // create file
697  m_lastResult = m_cmt1f.create(filename);
698  if (m_lastResult != XRV_OK) return m_lastResult;
699 
700  m_readOnly = false;
701 
702  // check if we can actually write to the file
703  m_lastResult = m_cmt1f.writeData(5, "Xsens");
705  if (m_lastResult != XRV_OK) m_cmt1f.close();
706  return m_lastResult;
707 }
708 
709 //////////////////////////////////////////////////////////////////////////////////////////
710 // Create a new file with level 2 header
711 XsensResultValue Cmt2f::create(const wchar_t* filename)
712 {
713  if (m_cmt1f.isOpen()) return m_lastResult = XRV_ALREADYOPEN;
714 
715  // create file
716  m_lastResult = m_cmt1f.create(filename);
717  if (m_lastResult != XRV_OK) return m_lastResult;
718 
719  m_readOnly = false;
720 
721  // check if we can actually write to the file
722  m_lastResult = m_cmt1f.writeData(5, "Xsens");
724  if (m_lastResult != XRV_OK) m_cmt1f.close();
725  return m_lastResult;
726 }
727 
728 //////////////////////////////////////////////////////////////////////////////////////////
729 Cmt1f* Cmt2f::getCmt1f(void) { return &m_cmt1f; }
730 //////////////////////////////////////////////////////////////////////////////////////////
731 // Return the error code of the last operation.
733 //////////////////////////////////////////////////////////////////////////////////////////
734 // Retrieve the filename that was last successfully opened.
735 XsensResultValue Cmt2f::getName(char* filename) const
736 {
737  return m_lastResult = m_cmt1f.getName(filename);
738 }
739 
740 //////////////////////////////////////////////////////////////////////////////////////////
741 // Retrieve the filename that was last successfully opened.
742 XsensResultValue Cmt2f::getName(wchar_t* filename) const
743 {
744  return m_lastResult = m_cmt1f.getName(filename);
745 }
746 
747 //////////////////////////////////////////////////////////////////////////////////////////
748 // Return whether the file is open or not.
749 bool Cmt2f::isOpen(void) const { return m_cmt1f.isOpen(); }
750 //////////////////////////////////////////////////////////////////////////////////////////
751 // Open a file and read the header
752 XsensResultValue Cmt2f::open(const char* filename, const bool readOnly)
753 {
754  if (m_cmt1f.isOpen()) return m_lastResult = XRV_ALREADYOPEN;
755  m_lastResult = m_cmt1f.open(filename, !readOnly, readOnly);
756  m_readOnly = readOnly;
757  return m_lastResult;
758 }
759 
760 //////////////////////////////////////////////////////////////////////////////////////////
761 // Open a file and read the header
762 XsensResultValue Cmt2f::open(const wchar_t* filename, const bool readOnly)
763 {
764  if (m_cmt1f.isOpen()) return m_lastResult = XRV_ALREADYOPEN;
765  m_lastResult = m_cmt1f.open(filename, !readOnly, readOnly);
766  m_readOnly = readOnly;
767  return m_lastResult;
768 }
769 
770 //////////////////////////////////////////////////////////////////////////////////////////
771 // Read the next message from the file
773 {
774  CmtFilePos pos;
775  uint8_t needle = CMT_PREAMBLE;
777  uint32_t length, bcount;
779  bool extended;
780  uint16_t target;
781 
782  while (m_lastResult == XRV_OK)
783  {
784  bcount = 0;
785 
786  // find a message preamble
787  m_lastResult = m_cmt1f.find(&needle, 1, pos);
788 
789  if (m_lastResult != XRV_OK) return m_lastResult;
790 
791  // read header
793  bcount += length;
794  if (m_lastResult != XRV_OK) return m_lastResult;
795 
796  if (hdr->m_length == CMT_EXTLENCODE)
797  {
798  extended = true;
800  CMT_LEN_MSGEXTHEADERCS - bcount, &buffer[bcount], &length);
801  bcount += length;
802  if (m_lastResult != XRV_OK)
803  {
804  m_cmt1f.setReadPos(pos + 1);
805  continue;
806  }
807  }
808  else
809  extended = false;
810 
811  // check the reported size
812  if (extended &&
813  (((uint16_t)hdr->m_datlen.m_extended.m_length.m_high * 256 +
816  {
817  m_cmt1f.setReadPos(pos + 1);
818  continue;
819  }
820 
821  // header seems to be ok, read until end and check checksum
822  if (extended)
823  target = ((uint16_t)hdr->m_datlen.m_extended.m_length.m_high * 256 +
826  else
827  target = hdr->m_length + CMT_LEN_MSGHEADERCS;
828 
829  // read the entire message
830  m_lastResult =
831  m_cmt1f.readData(target - bcount, &buffer[bcount], &length);
832  bcount += length;
833  if (m_lastResult != XRV_OK)
834  {
835  m_cmt1f.setReadPos(pos + 1);
836  continue;
837  }
838 
839  // check the checksum
840  // msg=new Message(m_readBuffer,(uint16_t) target, (uint16_t) target);
841  if (msg->loadFromString(buffer, (uint16_t)target) == XRV_OK)
842  {
843  if ((msgId == 0) || (msgId == msg->getMessageId()))
844  return m_lastResult = XRV_OK;
845  pos += target - 1;
846  }
847  msg->clear();
848  m_cmt1f.setReadPos(pos + 1);
849  }
850  return m_lastResult;
851 }
852 
853 //////////////////////////////////////////////////////////////////////////////////////////
854 // Get the current file size
856 //////////////////////////////////////////////////////////////////////////////////////////
857 // Get the current read position of the file
859 //////////////////////////////////////////////////////////////////////////////////////////
860 // Set the read position to the given position
862 {
863  return m_lastResult = m_cmt1f.setReadPos(pos);
864 }
865 
866 //////////////////////////////////////////////////////////////////////////////////////////
867 // Write a message to the end of the file
869 {
870  if (m_readOnly) return m_lastResult = XRV_READONLY;
872  msg->getTotalMessageSize(), msg->getMessageStart());
873 }
874 
875 } // end of xsens namespace
xsens::Cmt2s::close
XsensResultValue close(void)
Close the serial communication port.
Definition: cmt2.cpp:120
xsens::Cmt2s::m_cmt1s
Cmt1s m_cmt1s
The CMT level 1 object that this class operates on.
Definition: cmt2.h:79
xsens::Cmt2f::writeMessage
XsensResultValue writeMessage(const Message *msg)
Write a message to the end of the file.
Definition: cmt2.cpp:868
xsens::Cmt1f::open
XsensResultValue open(const char *filename, const bool create, const bool readOnly)
Open a file.
Definition: cmt1.cpp:1116
xsens::Cmt2s::setTimeout
XsensResultValue setTimeout(const uint32_t ms=CMT2_DEFAULT_TIMEOUT)
Set the default timeout value to use in blocking operations.
Definition: cmt2.cpp:370
xsens::Message::getTotalMessageSize
uint16_t getTotalMessageSize(void) const
Return the length of the message buffer.
Definition: cmtmessage.cpp:378
XRV_NOFILEOPEN
@ XRV_NOFILEOPEN
Definition: xsens_std.h:201
CMT_MAXDATALEN
#define CMT_MAXDATALEN
Definition: cmtdef.h:75
xsens::Cmt2f::setReadPosition
XsensResultValue setReadPosition(CmtFilePos pos)
Set the read position to the given position.
Definition: cmt2.cpp:861
xsens::Cmt1s::getPortNr
uint8_t getPortNr(void) const
Retrieve the port number that was last successfully opened.
Definition: cmt1.h:143
CMT_CALLBACK_ONMESSAGERECEIVED
@ CMT_CALLBACK_ONMESSAGERECEIVED
Callback function, called when a full message has been received from a port.
Definition: cmtdef.h:1140
xsens::Cmt2s::m_onMessageSentParam
void * m_onMessageSentParam
Custom, user supplied parameter for the OnMessageSent callback function, passed as the last argument.
Definition: cmt2.h:73
xsens::Cmt2s::m_readBuffer
uint8_t m_readBuffer[CMT_DEFAULT_READ_BUFFER_SIZE]
Buffer for reading data until a valid message is read.
Definition: cmt2.h:84
uint16_t
unsigned __int16 uint16_t
Definition: rptypes.h:44
cmt2.h
xsens::findValidMessage
int32_t findValidMessage(const uint8_t *buffer, const uint16_t bufferLength)
Find a valid message in the given buffer.
Definition: cmt2.cpp:45
xsens::Cmt1f::close
XsensResultValue close(void)
Close the file.
Definition: cmt1.cpp:713
xsens::Cmt2f::Cmt2f
Cmt2f()
Default constructor.
Definition: cmt2.cpp:656
CmtCallbackSelector
CmtCallbackSelector
Definition: cmtdef.h:1120
XRV_TIMEOUT
@ XRV_TIMEOUT
Definition: xsens_std.h:112
xsens::getTimeOfDay
uint32_t getTimeOfDay(tm *date_, time_t *secs_)
A platform-independent clock.
Definition: xsens_time.cpp:34
XRV_OK
@ XRV_OK
Operation was performed successfully.
Definition: xsens_std.h:34
xsens::Cmt2f::readMessage
XsensResultValue readMessage(Message *msg, const uint8_t msgId=0)
Read the next message from the file, when msgId is non-zero, the first matching message will be retur...
Definition: cmt2.cpp:772
xsens::Cmt2s::waitForMessage
XsensResultValue waitForMessage(Message *rcv, const uint8_t msgId, uint32_t timeoutOverride, bool acceptErrorMessage)
Wait for a message to arrive.
Definition: cmt2.cpp:382
xsens::Cmt1f::getName
XsensResultValue getName(char *filename) const
Retrieve the filename that was last successfully opened.
Definition: cmt1.cpp:1010
CMT_PREAMBLE
#define CMT_PREAMBLE
Definition: cmtdef.h:60
xsens::Message::clear
void clear(void)
Clear all data in the message.
Definition: cmtmessage.cpp:147
xsens::Cmt1s::writeData
XsensResultValue writeData(const uint32_t length, const uint8_t *data, uint32_t *written)
Write the data to the serial port.
Definition: cmt1.cpp:633
xsens::Cmt1f::create
XsensResultValue create(const char *filename)
Open an empty file.
Definition: cmt1.cpp:789
xsens::Cmt2s::getPortNr
XsensResultValue getPortNr(uint8_t &port) const
Retrieve the port that the object is connected to.
Definition: cmt2.cpp:144
xsens::Cmt2f::~Cmt2f
~Cmt2f()
Destructor.
Definition: cmt2.cpp:664
XRV_TIMEOUTNODATA
@ XRV_TIMEOUTNODATA
Definition: xsens_std.h:115
XSENS_MS_PER_DAY
#define XSENS_MS_PER_DAY
The number of milliseconds in a normal day.
Definition: xsens_time.h:21
XRV_NOPORTOPEN
@ XRV_NOPORTOPEN
Definition: xsens_std.h:204
xsens::Cmt2s::open
XsensResultValue open(const char *portName, const uint32_t baudRate=CMT_DEFAULT_BAUD_RATE)
Open a communication channel to the given serial port name.
Definition: cmt2.cpp:162
uint8_t
unsigned char uint8_t
Definition: rptypes.h:41
CMT_MAXMSGLEN
#define CMT_MAXMSGLEN
Definition: cmtdef.h:77
xsens::Cmt2f::isOpen
bool isOpen(void) const
Return whether the file is open or not.
Definition: cmt2.cpp:749
xsens::Cmt1f::find
XsensResultValue find(const void *needle, const uint32_t needleLength, CmtFilePos &pos)
Find a string of bytes in the file.
Definition: cmt1.cpp:941
xsens::Cmt2s::~Cmt2s
~Cmt2s()
Destructor, de-initialize, free memory allocated for buffers, etc.
Definition: cmt2.cpp:119
length
GLuint GLsizei GLsizei * length
Definition: glext.h:4064
xsens::Cmt1f::setReadPos
XsensResultValue setReadPos(const CmtFilePos pos)
Set the new absolute read position.
Definition: cmt1.cpp:1272
xsens::Cmt1s::getPortName
void getPortName(char *portname) const
Retrieve the port name that was last successfully opened.
Definition: cmt1.h:145
xsens::Cmt2f::m_cmt1f
Cmt1f m_cmt1f
The Cmt1f object that is used for the low-level operations.
Definition: cmt2.h:201
xsens::Cmt2s::m_onMessageSentInstance
int32_t m_onMessageSentInstance
Custom, user supplied parameter for the OnMessageSent callback function, passed as the first argument...
Definition: cmt2.h:70
xsens::Cmt2f::close
XsensResultValue close(void)
Close the file.
Definition: cmt2.cpp:667
xsens::Cmt1f::closeAndDelete
XsensResultValue closeAndDelete(void)
Close the file and delete it.
Definition: cmt1.cpp:737
xsens::Cmt2f::open
XsensResultValue open(const char *filename, const bool readOnly=false)
Open a file and read the header.
Definition: cmt2.cpp:752
CMT_DEFAULT_BAUD_RATE
#define CMT_DEFAULT_BAUD_RATE
The default baud rate of the Cmt1s serial communication.
Definition: cmtdef.h:798
CmtCallbackFunction
XsensResultValue(__cdecl * CmtCallbackFunction)(int32_t, CmtCallbackSelector, void *, void *)
Definition: cmtdef.h:1160
xsens::Cmt2s::getPortName
XsensResultValue getPortName(char *portname) const
Definition: cmt2.cpp:134
CMT_MID_ERROR
#define CMT_MID_ERROR
Definition: cmtdef.h:474
CMTLOG
#define CMTLOG(...)
Definition: cmt1.h:41
xsens::Message::loadFromString
XsensResultValue loadFromString(const uint8_t *source, const uint16_t size)
Read the entire message from the given source string.
Definition: cmtmessage.cpp:398
xsensResultText
const char * xsensResultText(const XsensResultValue result)
Definition: xsens_std.cpp:13
xsens::Cmt2f::closeAndDelete
XsensResultValue closeAndDelete(void)
Close the file and delete it.
Definition: cmt2.cpp:680
xsens::Cmt2f::m_readOnly
bool m_readOnly
When set to true, the file is read-only and attempts to write to it will fail.
Definition: cmt2.h:207
xsens::MessageHeader
A message header.
Definition: cmtmessage.h:36
xsens::Cmt2s::setCallbackFunction
XsensResultValue setCallbackFunction(CmtCallbackSelector tp, int32_t instance, CmtCallbackFunction func, void *param)
Set the callback function for when a message has been received or sent.
Definition: cmt2.cpp:346
xsens::Cmt1f::isOpen
bool isOpen(void) const
Return whether the file is open or not.
Definition: cmt1.h:363
xsens::Message::getMessageId
uint8_t getMessageId(void) const
Return the current value of the m_messageId field.
Definition: cmtmessage.h:236
xsens::MessageHeader::_mdl::_mextd::_mlen::m_high
uint8_t m_high
Definition: cmtmessage.h:47
res
GLuint res
Definition: glext.h:7268
xsens::Cmt2s::m_lastResult
XsensResultValue m_lastResult
The last result of an operation.
Definition: cmt2.h:81
XRV_READONLY
@ XRV_READONLY
Definition: xsens_std.h:157
xsens::Cmt2f::getLastResult
XsensResultValue getLastResult(void) const
Return the error code of the last operation.
Definition: cmt2.cpp:732
xsens::Message::getMessageStart
const uint8_t * getMessageStart(void) const
Return the start of the message buffer.
Definition: cmtmessage.h:241
xsens::MessageHeader::m_length
uint8_t m_length
Definition: cmtmessage.h:41
CMT2_DEFAULT_TIMEOUT
#define CMT2_DEFAULT_TIMEOUT
Timeout in ms for level 2.
Definition: cmtdef.h:807
xsens::Cmt1f::deleteData
XsensResultValue deleteData(const CmtFilePos start, const uint32_t length)
Delete the given data from the file. The function erases the given data from the file at the given wr...
Definition: cmt1.cpp:867
xsens::Cmt1f
The low-level file communication class.
Definition: cmt1.h:240
xsens::Cmt2f::create
XsensResultValue create(const char *filename)
Create a new file with level 2 header.
Definition: cmt2.cpp:692
xsens::Cmt2f::getFileSize
CmtFilePos getFileSize(void)
Get the current file size.
Definition: cmt2.cpp:855
xsens::Cmt2f::m_lastResult
XsensResultValue m_lastResult
The last result of an operation.
Definition: cmt2.h:203
CmtBinaryData
Definition: cmtdef.h:1152
CMT_LEN_MSGEXTHEADERCS
#define CMT_LEN_MSGEXTHEADERCS
Definition: cmtdef.h:68
xsens::Cmt2f::getName
XsensResultValue getName(char *filename) const
Retrieve the filename that was last successfully opened.
Definition: cmt2.cpp:735
xsens::Cmt1f::appendData
XsensResultValue appendData(const uint32_t length, const void *data)
Write data to the end of the file.
Definition: cmt1.cpp:694
xsens::Cmt2s::m_readBufferCount
uint16_t m_readBufferCount
The number of valid bytes in the readBuffer.
Definition: cmt2.h:86
buffer
GLuint buffer
Definition: glext.h:3917
xsens::Cmt2f::getCmt1f
Cmt1f * getCmt1f(void)
Get a reference to the embedded Cmt1f object.
Definition: cmt2.cpp:729
xsens::Cmt2s::m_onMessageReceivedParam
void * m_onMessageReceivedParam
Custom, user supplied parameter for the OnMessageReceived callback function, passed as the last argum...
Definition: cmt2.h:59
int32_t
__int32 int32_t
Definition: rptypes.h:46
xsens::MessageHeader::m_datlen
union xsens::MessageHeader::_mdl m_datlen
xsens::Cmt2s::m_onMessageReceivedInstance
int32_t m_onMessageReceivedInstance
Custom, user supplied parameter for the OnMessageReceived callback function, passed as the first argu...
Definition: cmt2.h:56
CMT_LEN_MSGHEADERCS
#define CMT_LEN_MSGHEADERCS
Definition: cmtdef.h:67
xsens::Cmt1f::readData
XsensResultValue readData(const uint32_t maxLength, void *data, uint32_t *length)
Read data from the file and put it into the data buffer.
Definition: cmt1.cpp:1220
xsens::Cmt2s::readMessage
XsensResultValue readMessage(Message *rcv)
Read a message from the COM port.
Definition: cmt2.cpp:192
XRV_ERROR
@ XRV_ERROR
Definition: xsens_std.h:106
CmtBinaryData::m_portNr
uint8_t m_portNr
Definition: cmtdef.h:1156
xsens::Cmt2s::m_baudrate
uint32_t m_baudrate
The baudrate that was last set to be used by the port.
Definition: cmt2.h:77
xsens::MessageHeader::_mdl::m_extended
struct xsens::MessageHeader::_mdl::_mextd m_extended
CMT_LEN_MSGHEADER
#define CMT_LEN_MSGHEADER
Definition: cmtdef.h:65
XRV_INVALIDPARAM
@ XRV_INVALIDPARAM
Definition: xsens_std.h:95
CmtBinaryData::m_data
uint8_t m_data[CMT_MAXMSGLEN]
Definition: cmtdef.h:1155
xsens::Cmt2f::getReadPosition
CmtFilePos getReadPosition(void)
Get the current read position.
Definition: cmt2.cpp:858
xsens::Cmt2s::writeMessage
XsensResultValue writeMessage(Message *msg)
Send a message over the COM port.
Definition: cmt2.cpp:599
CmtBinaryData::m_size
int32_t m_size
Definition: cmtdef.h:1154
CMT_EXTLENCODE
#define CMT_EXTLENCODE
Definition: cmtdef.h:63
xsens::Cmt1s::setTimeout
XsensResultValue setTimeout(const uint32_t ms=CMT1_DEFAULT_TIMEOUT)
Set the default timeout value to use in blocking operations.
Definition: cmt1.cpp:561
xsens::Cmt1f::getFileSize
CmtFilePos getFileSize(void) const
Return the size of the file.
Definition: cmt1.h:329
xsens::Message
Class for storing a single message.
Definition: cmtmessage.h:83
CMT2LOG
#define CMT2LOG(...)
Definition: cmt2.cpp:41
CmtFilePos
__int64 CmtFilePos
Definition: cmtf.h:25
xsens::Cmt1f::getReadPos
CmtFilePos getReadPos(void) const
Return the current read position.
Definition: cmt1.h:350
xsens::Cmt1f::writeData
XsensResultValue writeData(const uint32_t length, const void *data)
Write data to the file.
Definition: cmt1.cpp:1312
XRV_ALREADYOPEN
@ XRV_ALREADYOPEN
Definition: xsens_std.h:145
XsensResultValue
XsensResultValue
Xsens return values.
Definition: xsens_std.h:31
xsens::Cmt2s::m_onMessageReceived
CmtCallbackFunction m_onMessageReceived
The message received function.
Definition: cmt2.h:53
xsens::Cmt2s::m_onMessageSent
CmtCallbackFunction m_onMessageSent
The message sent function.
Definition: cmt2.h:67
xsens::Message::isChecksumOk
bool isChecksumOk(void) const
Compute the checksum and compare it with the stored checksum.
Definition: cmtmessage.cpp:390
xsens::Cmt2s::m_timeout
uint32_t m_timeout
Timeout in ms for blocking operations.
Definition: cmt2.h:88
xsens::Cmt2s::Cmt2s
Cmt2s()
Default constructor, initialize all members to their default values.
Definition: cmt2.cpp:108
xsens::Cmt1s::close
XsensResultValue close(void)
Close the serial communication port.
Definition: cmt1.cpp:205
xsens::Cmt1s::open
XsensResultValue open(const char *portName, const uint32_t baudRate=CMT_DEFAULT_BAUD_RATE, uint32_t readBufSize=CMT_DEFAULT_READ_BUFFER_SIZE, uint32_t writeBufSize=CMT_DEFAULT_WRITE_BUFFER_SIZE)
Open a communcation channel to the given serial port name.
Definition: cmt1.cpp:322
xsens
The namespace of all Xsens software since 2006.
Definition: cmt1.cpp:95
uint32_t
unsigned __int32 uint32_t
Definition: rptypes.h:47
xsens::Cmt2s::m_toEnd
uint32_t m_toEnd
The timestamp at which to end an operation.
Definition: cmt2.h:90
param
GLfloat param
Definition: glext.h:3831
CMT_CALLBACK_ONMESSAGESENT
@ CMT_CALLBACK_ONMESSAGESENT
Callback function, called when a full message has been sent by a port.
Definition: cmtdef.h:1142
xsens::MessageHeader::_mdl::_mextd::_mlen::m_low
uint8_t m_low
Definition: cmtmessage.h:48
xsens::MessageHeader::_mdl::_mextd::m_length
struct xsens::MessageHeader::_mdl::_mextd::_mlen m_length
mrpt::system::os::memcpy
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
Definition: os.cpp:356
xsens::Cmt1s::readData
XsensResultValue readData(const uint32_t maxLength, uint8_t *data, uint32_t *length=nullptr)
Read data from the serial port and put it into the data buffer.
Definition: cmt1.cpp:485



Page generated by Doxygen 1.8.17 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at miƩ 12 jul 2023 10:03:34 CEST