Main MRPT website > C++ reference for MRPT 1.9.9
cmt1.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 cmt1.cpp
11 
12  For information about objects in this file, see the appropriate header:
13  \ref Cmt1.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-12, 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 "cmt1.h"
35 #include <errno.h>
36 
37 #include <mrpt/config.h> // For HAVE_MALLOC_H
38 
39 #ifndef _WIN32
40 #include <unistd.h> // close
41 #include <sys/ioctl.h> // ioctl
42 #include <fcntl.h> // open, O_RDWR
43 #include <string.h> // strcpy
44 
45 /* Jerome Monceaux : bilock@gmail.com
46  * Add a specific case for apple
47  */
48 #ifdef HAVE_MALLOC_H
49 #include <malloc.h>
50 #elif defined(HAVE_MALLOC_MALLOC_H)
51 #include <malloc/malloc.h>
52 #endif
53 
54 #include <stdarg.h> // va_start, etc...
55 #include <sys/param.h>
56 // We have to redefine PATH_MAX from 4096 to CMT_MAX_FILENAME_LENGTH to mainain
57 // compatibility
58 // The PATH_MAX definition is used by realpath() to determine the maximum path
59 // length. According
60 // to the realpath (3) man page, the function is best avoided and it might be
61 // necessary to
62 // write a custom function for it (couldn't find a proper replacement).
63 #undef PATH_MAX
64 #define PATH_MAX CMT_MAX_FILENAME_LENGTH
65 #include <stdlib.h>
66 #else
67 #include <stdio.h> // fseek
68 #include <io.h>
69 #endif
70 
71 #ifndef _CRT_SECURE_NO_DEPRECATE
72 #define _CRT_SECURE_NO_DEPRECATE
73 #ifdef _WIN32
74 #pragma warning(disable : 4996)
75 #endif
76 #endif
77 
78 #ifdef _WIN32
79 #ifdef _MSC_VER
80 #define FSEEK(x) _fseeki64(m_handle, x, SEEK_SET)
81 #define FSEEK_R(x) _fseeki64(m_handle, x, SEEK_END)
82 #define FTELL() _ftelli64(m_handle)
83 #else
84 #define FSEEK(x) fseek(m_handle, x, SEEK_SET)
85 #define FSEEK_R(x) fseek(m_handle, x, SEEK_END)
86 #define FTELL() ftell(m_handle)
87 #endif
88 #else
89 #define FSEEK(x) fseeko(m_handle, x, SEEK_SET)
90 #define FSEEK_R(x) fseeko(m_handle, x, SEEK_END)
91 #define FTELL() ftello(m_handle)
92 #endif
93 
94 // The namespace of all Xsens software since 2006.
95 namespace xsens
96 {
97 #ifndef _WIN32
98 int _wcsnicmp(const wchar_t* s1, const wchar_t* s2, int count)
99 {
100  for (int i = 0; i < count; ++i, ++s1, ++s2)
101  if (*s1 == L'\0')
102  if (*s2 == L'\0')
103  return 0;
104  else
105  return -1;
106  else if (*s2 == L'\0')
107  return 1;
108  else if (*s1 < *s2)
109  return -1;
110  else if (*s1 > *s2)
111  return 1;
112  return 0;
113 }
114 #endif
115 
116 #if defined(_DEBUG) || defined(_LOG_ALWAYS)
117 #if !defined(_LOG_TO_DBVIEW)
118 #ifdef _LOG_TO_STDOUT
119 #else // !dbview && !stdout
120 FILE* debug_log_fp = nullptr;
121 int32_t debug_log_valid = 0;
122 
123 FILE* debug_qlog_fp = nullptr;
124 int32_t debug_qlog_valid = 0;
125 #endif
126 #endif
127 
128 // write to a log file/screen/debug-stream
129 void CMTLOG(const char* str, ...)
130 {
131 #ifdef _LOG_TO_STDOUT
132  va_list ptr;
133  va_start(ptr, str);
134  vprintf(str, ptr);
135 #else
136 #ifdef _LOG_TO_DBVIEW
137  char buf[2048];
138 
139  va_list ptr;
140  va_start(ptr, str);
141  vsprintf(buf, str, ptr);
142 
143  OutputDebugString(buf);
144 #else
145  if (debug_log_valid == 0)
146  {
147  debug_log_fp = fopen("debug_log_cmt.log", "w");
148  if (debug_log_fp != nullptr)
149  debug_log_valid = 1;
150  else
151  debug_log_valid = -1;
152  }
153  if (debug_log_valid == 1)
154  {
155  char buf[2048];
156 
157  va_list ptr;
158  va_start(ptr, str);
159  int32_t sz = vsprintf_s(buf, str, ptr);
160 
161  uint32_t nw = getTimeOfDay();
162  fprintf(debug_log_fp, "%5u.%03u %s", nw / 1000, nw % 1000, buf);
163  // fwrite(buf,1,sz,debug_log_fp);
164  fflush(debug_log_fp);
165  }
166 #endif
167 #endif
168 }
169 #endif
170 
171 // maybe log to nothing at this level
172 #ifdef _LOG_CMT1
173 #define CMT1LOG CMTLOG
174 #else
175 #define CMT1LOG(...)
176 #endif
177 
178 //////////////////////////////////////////////////////////////////////////////////////////
179 ///////////////////////////////////////// Cmt1s
180 ////////////////////////////////////////////
181 //////////////////////////////////////////////////////////////////////////////////////////
182 
183 //////////////////////////////////////////////////////////////////////////////////////////
184 // Default constructor, initializes all members to their default values.
185 Cmt1s::Cmt1s() : m_onBytesReceived(nullptr)
186 {
187  m_port = 0;
188  m_isOpen = false;
191  m_endTime = 0;
192  m_baudrate = 0;
193 
194 #ifdef _LOG_RX_TX
195  rx_log = nullptr;
196  tx_log = nullptr;
197 #endif
198 }
199 
200 //////////////////////////////////////////////////////////////////////////////////////////
201 // Destructor, de-initializes, frees memory allocated for buffers, etc.
203 //////////////////////////////////////////////////////////////////////////////////////////
204 // Close the serial communication port.
206 {
207 #ifdef _LOG_RX_TX
208  if (rx_log != nullptr) fclose(rx_log);
209  if (tx_log != nullptr) fclose(tx_log);
210  rx_log = nullptr;
211  tx_log = nullptr;
212 #endif
213  if (!m_isOpen) return m_lastResult = XRV_NOPORTOPEN;
214 
215 #ifdef _WIN32
216  ::FlushFileBuffers(m_handle);
217  // read all data before closing the handle, a Flush is not enough for FTDI
218  // devices unfortunately
219  // we first need to set the COMM timeouts to instantly return when no more
220  // data is available
221  COMMTIMEOUTS cto;
222  ::GetCommTimeouts(m_handle, &cto);
223  cto.ReadIntervalTimeout = MAXDWORD;
224  cto.ReadTotalTimeoutConstant = 0;
225  cto.ReadTotalTimeoutMultiplier = 0;
226  ::SetCommTimeouts(m_handle, &cto);
227  char buffer[1024];
228  DWORD length;
229  do
230  {
231  ::ReadFile(m_handle, buffer, 1024, &length, nullptr);
232  } while (length > 0);
233  ::CloseHandle(m_handle);
234 #else
235  ::close(m_handle);
236 #endif
237  m_isOpen = false;
238  m_endTime = 0;
239 
240  return m_lastResult = XRV_OK;
241 }
242 
243 //////////////////////////////////////////////////////////////////////////////////////////
244 // Manipulate the Serial control lines
246  const CmtControlLine mask, const CmtControlLine state)
247 {
248  if (!m_isOpen) return (m_lastResult = XRV_NOPORTOPEN);
249 #ifdef _WIN32
250  BOOL rv = 0;
251  if (mask & CMT_CONTROL_DTR)
252  {
253  if (state & CMT_CONTROL_DTR)
254  rv = EscapeCommFunction(m_handle, SETDTR);
255  else
256  rv = EscapeCommFunction(m_handle, CLRDTR);
257  }
258 
259  if (mask & CMT_CONTROL_RTS)
260  {
261  if (state & CMT_CONTROL_RTS)
262  rv = EscapeCommFunction(m_handle, SETRTS);
263  else
264  rv = EscapeCommFunction(m_handle, CLRRTS);
265  }
266  if (rv)
267  return m_lastResult = XRV_OK;
268  else
269  return m_lastResult = XRV_ERROR;
270 #else
271  bool rv = true;
272  int32_t status;
273  if (mask & CMT_CONTROL_DTR)
274  {
275  if (ioctl(m_handle, TIOCMGET, &status) == -1)
276  {
277  if (state & CMT_CONTROL_DTR)
278  status |= TIOCM_DTR;
279  else
280  status &= ~TIOCM_DTR;
281  rv = (ioctl(m_handle, TIOCMSET, &status) == -1);
282  }
283  else
284  rv = false;
285  }
286  if (rv && (mask & CMT_CONTROL_RTS))
287  {
288  if (ioctl(m_handle, TIOCMGET, &status) == -1)
289  {
290  if (state & CMT_CONTROL_RTS)
291  status |= TIOCM_RTS;
292  else
293  status &= ~TIOCM_RTS;
294  rv = (ioctl(m_handle, TIOCMSET, &status) == -1);
295  }
296  else
297  rv = false;
298  }
299  if (rv)
300  return m_lastResult = XRV_OK;
301  else
302  return m_lastResult = XRV_ERROR;
303 #endif
304 }
305 
306 //////////////////////////////////////////////////////////////////////////////////////////
307 // Flush all data to be transmitted / received.
309 {
310 #ifdef _WIN32
311  // Remove any 'old' data in buffer
312  PurgeComm(m_handle, PURGE_TXCLEAR | PURGE_RXCLEAR);
313 #else
314  tcflush(m_handle, TCIOFLUSH);
315 #endif
316  m_endTime = 0;
317  return (m_lastResult = XRV_OK);
318 }
319 
320 //////////////////////////////////////////////////////////////////////////////////////////
321 // Open a communication channel to the given serial port name.
323  const char* portName, const uint32_t baudRate, uint32_t readBufSize,
324  uint32_t writeBufSize)
325 {
326  MRPT_UNUSED_PARAM(readBufSize);
327  MRPT_UNUSED_PARAM(writeBufSize);
328  m_endTime = 0;
329 
330  CMT1LOG("L1: Open port %s at %d baud\n", portName, baudRate);
331 
332  if (m_isOpen)
333  {
334  CMT1LOG("L1: Port already open\n");
335  return (m_lastResult = XRV_ALREADYOPEN);
336  }
337  m_baudrate = baudRate;
338 
339 #ifdef _WIN32
340  char winPortName[32];
341 
342  // Open port
343  sprintf(winPortName, "\\\\.\\%s", portName);
344  m_handle = CreateFileA(
345  winPortName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0,
346  nullptr);
347  if (m_handle == INVALID_HANDLE_VALUE)
348  {
349  CMT1LOG("L1: Port cannot be opened\n");
351  }
352 
353  // Once here, port is open
354  m_isOpen = true;
355 
356  // Get the current state & then change it
357  GetCommState(m_handle, &m_commState); // Get current state
358 
359  m_commState.BaudRate = baudRate; // Setup the baud rate
360  m_commState.Parity = NOPARITY; // Setup the Parity
361  m_commState.ByteSize = 8; // Setup the data bits
362  m_commState.StopBits = TWOSTOPBITS; // Setup the stop bits
363  m_commState.fDsrSensitivity = FALSE; // Setup the flow control
364  m_commState.fOutxCtsFlow = FALSE; // NoFlowControl:
365  m_commState.fOutxDsrFlow = FALSE;
366  m_commState.fOutX = FALSE;
367  m_commState.fInX = FALSE;
368  if (!SetCommState(m_handle, (LPDCB)&m_commState))
369  { // Set new state
370  // Bluetooth ports cannot always be opened with 2 stopbits
371  // Now try to open port with 1 stopbit.
372  m_commState.StopBits = ONESTOPBIT;
373  if (!SetCommState(m_handle, (LPDCB)&m_commState))
374  {
375  CloseHandle(m_handle);
376  m_handle = INVALID_HANDLE_VALUE;
377  m_isOpen = false;
379  }
380  }
381  m_port = atoi(&portName[3]);
382  sprintf(m_portname, "%s", portName);
383 
385 
386  // Other initialization functions
387  EscapeCommFunction(m_handle, SETRTS); // Enable RTS (for Xbus Master use)
388  // Set DTR (Calibration sensors need DTR to startup, won't hurt otherwise
389  EscapeCommFunction(m_handle, SETDTR);
390  SetupComm(m_handle, readBufSize, writeBufSize); // Set queue size
391 
392  // Remove any 'old' data in buffer
393  // PurgeComm(m_handle, PURGE_TXCLEAR | PURGE_RXCLEAR);
394  PurgeComm(
395  m_handle,
396  PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
397 #else // !_WIN32
398  // Open port
399  m_handle = ::open(portName, O_RDWR | O_NOCTTY);
400  // O_RDWR: Read+Write
401  // O_NOCTTY: Raw input, no "controlling terminal"
402  // O_NDELAY: Don't care about DCD signal
403 
404  if (m_handle < 0)
405  {
406  // Port not open
408  }
409 
410  // Once here, port is open
411  m_isOpen = true;
412 
413  /* Start configuring of port for non-canonical transfer mode */
414  // Get current options for the port
415  tcgetattr(m_handle, &m_commState);
416 
417  // Set baudrate.
418  cfsetispeed(&m_commState, baudRate);
419  cfsetospeed(&m_commState, baudRate);
420 
421  // Enable the receiver and set local mode
422  m_commState.c_cflag |= (CLOCAL | CREAD);
423  // Set character size to data bits and set no parity Mask the characte size
424  // bits
425  m_commState.c_cflag &= ~(CSIZE | PARENB);
426  m_commState.c_cflag |= CS8; // Select 8 data bits
427  m_commState.c_cflag |= CSTOPB; // send 2 stop bits
428  // Disable hardware flow control
429  m_commState.c_cflag &= ~CRTSCTS;
430  m_commState.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
431  // Disable software flow control
432  m_commState.c_iflag &=
433  ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
434  // Set Raw output
435  m_commState.c_oflag &= ~OPOST;
436  // Timeout 0.001 sec for first byte, read minimum of 0 bytes
437  m_commState.c_cc[VMIN] = 0;
438  m_commState.c_cc[VTIME] = (m_timeout + 99) / 100; // 1
439 
440  // Set the new options for the port
441  tcsetattr(m_handle, TCSANOW, &m_commState);
442 
443  m_port = 0;
444  sprintf(m_portname, "%s", portName);
445 
446  tcflush(m_handle, TCIOFLUSH);
447 
448  // setting RTS and DTR; RTS for Xbus Master, DTR for calibration sensors
449  int cmbits;
450  if (ioctl(m_handle, TIOCMGET, &cmbits) < 0)
451  {
452  return (m_lastResult = XRV_ERROR);
453  }
454 
455  cmbits |= TIOCM_RTS | TIOCM_DTR;
456 
457  if (ioctl(m_handle, TIOCMSET, &cmbits) < 0)
458  {
459  return (m_lastResult = XRV_ERROR);
460  }
461 #endif // !_WIN32
462 
463  CMT1LOG("L1: Port opened\n");
464  return (m_lastResult = XRV_OK);
465 }
466 
467 #ifdef _WIN32
468 //////////////////////////////////////////////////////////////////////////////////////////
469 // Open a communication channel to the given COM port number.
471  const uint32_t portNumber, const uint32_t baudRate, uint32_t readBufSize,
472  uint32_t writeBufSize)
473 {
474  char comFileName[32];
475 
476  // Create file name
477  sprintf(comFileName, "COM%u", portNumber);
478 
479  return Cmt1s::open(comFileName, baudRate, readBufSize, writeBufSize);
480 }
481 #endif
482 
483 //////////////////////////////////////////////////////////////////////////////////////////
484 // Read data from the serial port and put it into the data buffer.
487 {
488  CMT1LOG("L1: readData, maxlength=%u, length=%p\n", maxLength, length);
489  uint32_t ln;
490  if (length == nullptr) length = &ln;
491 
492  if (!m_isOpen) return (m_lastResult = XRV_NOPORTOPEN);
493 
494 #ifdef _WIN32
495  BOOL rres = ::ReadFile(m_handle, data, maxLength, (DWORD*)length, nullptr);
496  if (m_onBytesReceived != nullptr && *length > 0)
497  {
498  CmtBinaryData* bytes = (CmtBinaryData*)malloc(sizeof(CmtBinaryData));
499  bytes->m_size = *length;
500  bytes->m_portNr = m_port;
501  memcpy(bytes->m_data, data, *length);
502 #ifdef _LOG_CALLBACKS
503  CMTLOG(
504  "C1: onBytesReceived(%d,(%d,%d),%p)\n",
507 #endif
511  }
512 
513  if (!rres)
514  {
515  CMT1LOG("L1: readData, ReadFile returned error %u\n", ::GetLastError());
516  return (m_lastResult = XRV_ERROR);
517  }
518 #else
519  *length = read(m_handle, data, maxLength);
520 #endif
521 
522 #ifdef _LOG_RX_TX
523  if (*length > 0)
524  {
525  if (rx_log == nullptr)
526  {
527  char fname[CMT_MAX_FILENAME_LENGTH];
528  sprintf(fname, "rx_%03d_%d.log", (int32_t)m_port, m_baudrate);
529  rx_log = fopen(fname, "wb");
530  }
531  fwrite(data, 1, *length, rx_log);
532  }
533 #endif
534 
535  CMT1LOG(
536  (length[0] ? "L1: readData returned success, read %u of %u bytes, "
537  "first: %02x\n"
538  : "L1: readData returned success, read %u bytes\n"),
539  length[0], maxLength, data[0]);
540  return (m_lastResult = XRV_OK);
541 }
542 
543 //////////////////////////////////////////////////////////////////////////////////////////
544 // Set the callback function for when bytes have been received
547  void* param)
548 {
550  {
551  m_onBytesReceived = func;
552  m_onBytesReceivedInstance = instance;
554  return m_lastResult = XRV_OK;
555  }
557 }
558 
559 //////////////////////////////////////////////////////////////////////////////////////////
560 // Set the default timeout value to use in blocking operations.
562 {
563  CMT1LOG("L1: Setting timeout to %u ms\n", ms);
564 
565  m_timeout = ms;
566 #ifdef _WIN32
567  // Set COM timeouts
568  COMMTIMEOUTS commTimeouts;
569 
570  GetCommTimeouts(m_handle, &commTimeouts); // Fill CommTimeouts structure
571 
572  // immediate return if data is available, wait 1ms otherwise
573  if (m_timeout > 0)
574  {
575  commTimeouts.ReadIntervalTimeout = 0;
576  commTimeouts.ReadTotalTimeoutConstant = m_timeout; // ms time
577  commTimeouts.ReadTotalTimeoutMultiplier = 0;
578  commTimeouts.WriteTotalTimeoutConstant = m_timeout;
579  commTimeouts.WriteTotalTimeoutMultiplier = 0;
580  }
581  else
582  {
583  // immediate return whether data is available or not
584  commTimeouts.ReadIntervalTimeout = MAXDWORD;
585  commTimeouts.ReadTotalTimeoutConstant = 0;
586  commTimeouts.ReadTotalTimeoutMultiplier = 0;
587  commTimeouts.WriteTotalTimeoutConstant = 0;
588  commTimeouts.WriteTotalTimeoutMultiplier = 0;
589  }
590 
591  SetCommTimeouts(m_handle, &commTimeouts); // Set CommTimeouts structure
592 #else
593  // Timeout 0.1 sec for first byte, read minimum of 0 bytes
594  m_commState.c_cc[VMIN] = 0;
595  m_commState.c_cc[VTIME] = (m_timeout + 99) / 100; // ds time
596 
597  // Set the new options for the port if it is open
598  if (m_isOpen) tcsetattr(m_handle, TCSANOW, &m_commState);
599 #endif
600  return (m_lastResult = XRV_OK);
601 }
602 
603 //////////////////////////////////////////////////////////////////////////////////////////
604 // Wait for data to arrive or a timeout to occur.
607 {
608  CMT1LOG("L1: waitForData, mto=%u, length=%p\n", m_timeout, length);
609  uint32_t timeout = m_timeout;
610 
611  uint32_t ln;
612  if (length == nullptr) length = &ln;
613  uint32_t eTime = getTimeOfDay(nullptr) + timeout;
614  uint32_t newLength = 0;
615 
616  *length = 0;
617  while ((*length < maxLength) && (getTimeOfDay() <= eTime))
618  {
619  readData(maxLength - *length, data + *length, &newLength);
620  *length += newLength;
621  }
622  CMT1LOG(
623  "L1: waitForData result: read %u of %u bytes\n", length[0], maxLength);
624 
625  if (length[0] < maxLength)
626  return (m_lastResult = XRV_TIMEOUT);
627  else
628  return (m_lastResult = XRV_OK);
629 }
630 
631 //////////////////////////////////////////////////////////////////////////////////////////
632 // Write the data to the serial port.
634  const uint32_t length, const uint8_t* data, uint32_t* written)
635 {
636  uint32_t bytes;
637  if (written == nullptr) written = &bytes;
638 
639  if (!m_isOpen) return (m_lastResult = XRV_NOPORTOPEN);
640 
641 #ifdef _WIN32
642  if (WriteFile(m_handle, data, length, (DWORD*)written, nullptr))
643  {
644 #ifdef _LOG_RX_TX
645  if (written[0] > 0)
646  {
647  if (tx_log == nullptr)
648  {
649  char fname[CMT_MAX_FILENAME_LENGTH];
650  sprintf(fname, "tx_%03d_%d.log", (int32_t)m_port, m_baudrate);
651  tx_log = fopen(fname, "wb");
652  }
653  fwrite(data, 1, *written, tx_log);
654  }
655 #endif
656  return (m_lastResult = XRV_OK);
657  }
658  else
659  return (m_lastResult = XRV_ERROR);
660 #else
661  *written = write(m_handle, data, length);
662  // if (*written == length)
663  return (m_lastResult = XRV_OK);
664 // else
665 // return (m_lastResult = XRV_ERROR);
666 #endif
667 }
668 
669 //////////////////////////////////////////////////////////////////////////////////////////
670 ///////////////////////////////////////// Cmt1f
671 ////////////////////////////////////////////
672 //////////////////////////////////////////////////////////////////////////////////////////
673 
674 //////////////////////////////////////////////////////////////////////////////////////////
675 // Default constructor, initializes all members to their default values.
677 {
678  m_readPos = 0;
679  m_writePos = 0;
681  m_reading = true;
682  m_isOpen = false;
683  m_filename[0] = '\0';
684  m_fileSize = 0;
685  m_readOnly = false;
686  m_unicode = false;
687 }
688 
689 //////////////////////////////////////////////////////////////////////////////////////////
690 // Destructor.
692 //////////////////////////////////////////////////////////////////////////////////////////
693 // Write data to the end of the file.
695 {
696  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
697  if (m_readOnly) return m_lastResult = XRV_READONLY;
698 
699  if (m_reading || m_writePos != m_fileSize)
700  {
701  m_reading = false;
702  FSEEK_R(0);
703  }
704  fwrite(data, 1, length, m_handle);
705  m_writePos = FTELL();
707 
708  return (m_lastResult = XRV_OK);
709 }
710 
711 //////////////////////////////////////////////////////////////////////////////////////////
712 // Close the file.
714 {
715  if (m_isOpen)
716  {
717 #ifdef _WIN32
718  fflush(m_handle);
719  fclose(m_handle);
720 #else
721  ::fflush(m_handle);
723 #endif
724  }
725  m_isOpen = false;
726  m_readPos = 0;
727  m_writePos = 0;
728  m_reading = true;
729  m_fileSize = 0;
730  m_readOnly = false;
731 
732  return m_lastResult = XRV_OK;
733 }
734 
735 //////////////////////////////////////////////////////////////////////////////////////////
736 // Close the file and delete it.
738 {
739  if (m_isOpen)
740  {
741 #ifdef _WIN32
742  fflush(m_handle);
743  fclose(m_handle);
744 #else
745  ::fflush(m_handle);
747 #endif
748  if (m_readOnly)
750  else
751  {
752 #ifdef _WIN32
753  if (m_unicode)
754  {
755  if (_wremove(m_filename_w) != 0)
757  else
759  }
760  else
761 #endif
762  {
763 #ifdef _WIN32
764  if (_unlink(m_filename) != 0)
765 #else
766  if (unlink(m_filename) != 0)
767 #endif
769  else
771  }
772  }
773  }
774  else
776 
777  m_isOpen = false;
778  m_readPos = 0;
779  m_writePos = 0;
780  m_reading = true;
781  m_fileSize = 0;
782  m_readOnly = false;
783 
784  return m_lastResult;
785 }
786 
787 //////////////////////////////////////////////////////////////////////////////////////////
788 // Create a new file.
789 XsensResultValue Cmt1f::create(const char* filename)
790 {
791  if (m_isOpen) return m_lastResult = XRV_ALREADYOPEN;
792 
793  //! \test does this work for non-existing files? Or do we need a check and
794  //! create?
795  m_handle = fopen(filename, "w+b"); // open for update (r/w)
796  if (m_handle == nullptr) return m_lastResult = XRV_OUTPUTCANNOTBEOPENED;
797 
798 #ifdef _WIN32
799  if (_fullpath(m_filename, filename, CMT_MAX_FILENAME_LENGTH) == nullptr)
800  {
801  fclose(m_handle);
802  remove(filename);
804  }
805 #else
806  // based on the assumption that this doesn't concern the serial port, handle
807  // it the same way using realpath(). Apparently realpath() doesn't require a
808  // maximum length. One would possibly want to write a wrapper for it.
809  if (realpath(filename, m_filename) == nullptr)
810  {
811  fclose(m_handle);
812  remove(filename);
814  }
815 #endif
817  m_unicode = false;
818 
819  m_isOpen = true;
820  m_readPos = 0;
821  m_writePos = 0;
822  m_fileSize = 0;
823  m_reading = true;
824  m_readOnly = false;
825  return m_lastResult = XRV_OK;
826 }
827 
828 //////////////////////////////////////////////////////////////////////////////////////////
829 // Create a new file.
830 XsensResultValue Cmt1f::create(const wchar_t* filename)
831 {
832  if (m_isOpen) return m_lastResult = XRV_ALREADYOPEN;
833 
834 #ifdef _WIN32
835  //! \test does this work for non-existing files? Or do we need a check and
836  //! create?
837  m_handle = _wfopen(filename, L"w+b"); // open for update (r/w)
838  if (m_handle == nullptr) return m_lastResult = XRV_OUTPUTCANNOTBEOPENED;
839 
840  if (_wfullpath(m_filename_w, filename, CMT_MAX_FILENAME_LENGTH) == nullptr)
841  {
842  fclose(m_handle);
843  _wremove(filename);
845  }
847 
848  m_isOpen = true;
849  m_readPos = 0;
850  m_writePos = 0;
851  m_fileSize = 0;
852  m_reading = true;
853  m_readOnly = false;
854 #else
855  MRPT_UNUSED_PARAM(filename);
856  char tFilename[CMT_MAX_FILENAME_LENGTH * 2];
857  wcstombs(tFilename, m_filename_w, CMT_MAX_FILENAME_LENGTH);
858  XsensResultValue res = create(tFilename);
859  if (res != XRV_OK) return res;
860 #endif
861  m_unicode = true;
862  return m_lastResult = XRV_OK;
863 }
864 
865 //////////////////////////////////////////////////////////////////////////////////////////
866 // Delete the given data from the file.
868  const CmtFilePos start, const uint32_t length)
869 {
870  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
871  if (m_readOnly) return m_lastResult = XRV_READONLY;
872 
873  gotoWrite();
874 
875  CmtFilePos wPos = start;
876  CmtFilePos rPos = wPos + length;
877 
878  size_t read1;
879  CmtFilePos endPos = (start + (CmtFilePos)length);
880  if (endPos < m_fileSize)
881  {
882  CmtFilePos remaining = m_fileSize - endPos;
883  char buffer[512];
884 
885  // copy data
886  FSEEK(rPos);
887 
888  while (remaining > 0)
889  {
890  if (remaining >= 512)
891  read1 = fread(buffer, 1, 512, m_handle);
892  else
893  read1 = fread(buffer, 1, (size_t)remaining, m_handle);
894 
895  remaining -= read1;
896  rPos += read1;
897 
898  // write block to the correct position
899  FSEEK(wPos);
900  wPos += fwrite(buffer, 1, read1, m_handle);
901  FSEEK(rPos);
902  }
903  m_fileSize -= length;
904  }
905  else
906  {
907  m_fileSize = start;
908  }
909 
910 #ifdef _WIN32
911  int32_t rv = _chsize(_fileno(m_handle), (int32_t)m_fileSize);
912 #else
913  int32_t rv = (ftruncate(fileno(m_handle), (int32_t)m_fileSize) == 0);
914 #endif
915  int32_t eno = 0;
916  if (rv != 0) eno = errno;
917  m_writePos = start;
918  FSEEK(wPos);
919  if (rv != 0)
920  {
921  switch (eno)
922  {
923  case EACCES:
924  return m_lastResult = XRV_BUSY;
925  case EBADF:
927  case ENOSPC:
928  return m_lastResult = XRV_OUTOFMEMORY;
929  case EINVAL:
931  default:
932  return m_lastResult = XRV_ERROR;
933  }
934  }
935 
936  return m_lastResult = XRV_OK;
937 }
938 
939 //////////////////////////////////////////////////////////////////////////////////////////
940 // Find a string of bytes in the file
942  const void* needleV, const uint32_t needleLength, CmtFilePos& pos)
943 {
944  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
945 
946  const char* needle = (const char*)needleV;
947 
948  gotoRead();
949 
950  pos = 0;
951 
952  char buffer[512];
953  uint32_t bufferPos, needlePos = 0;
954  size_t readBytes;
955  if (m_readPos & 0x1FF) // read a block of data
956  readBytes =
957  fread(buffer, 1, (512 - ((size_t)m_readPos & 0x1FF)), m_handle);
958  else
959  readBytes = fread(buffer, 1, 512, m_handle); // read a block of data
960 
961  while (readBytes > 0)
962  {
963  m_readPos += readBytes;
964  bufferPos = 0;
965 
966  while (bufferPos < readBytes && needlePos < needleLength)
967  {
968  if (buffer[bufferPos] == needle[needlePos])
969  {
970  // found a byte
971  ++needlePos;
972  }
973  else
974  {
975  if (needlePos > 0)
976  needlePos = 0;
977  else if (buffer[bufferPos] == needle[0])
978  {
979  // found a byte
980  needlePos = 1;
981  }
982  }
983  ++bufferPos;
984  }
985  if (needlePos < needleLength)
986  readBytes = fread(buffer, 1, 512, m_handle); // read next block
987  else
988  {
989  m_readPos = m_readPos + bufferPos - readBytes -
990  needleLength; // or without needleLength
991  pos = m_readPos; // - needleLength;
992  FSEEK(m_readPos);
993  return m_lastResult = XRV_OK;
994  }
995  }
996  return m_lastResult = XRV_ENDOFFILE;
997 }
998 
999 //////////////////////////////////////////////////////////////////////////////////////////
1000 // Flush all data to be written.
1002 {
1003  fflush(m_handle);
1004 
1005  return m_lastResult = XRV_OK;
1006 }
1007 
1008 //////////////////////////////////////////////////////////////////////////////////////////
1009 // Retrieve the filename that was last successfully opened.
1010 XsensResultValue Cmt1f::getName(char* filename) const
1011 {
1012  strcpy(filename, m_filename);
1013  return m_lastResult = XRV_OK;
1014 }
1015 
1016 //////////////////////////////////////////////////////////////////////////////////////////
1017 // Retrieve the filename that was last successfully opened.
1018 XsensResultValue Cmt1f::getName(wchar_t* filename) const
1019 {
1020 #ifdef _WIN32
1021  wcscpy(filename, m_filename_w);
1022 #else
1023  mbstowcs(filename, m_filename, CMT_MAX_FILENAME_LENGTH);
1024 #endif
1025  return m_lastResult = XRV_OK;
1026 }
1027 
1028 //////////////////////////////////////////////////////////////////////////////////////////
1029 // Change from writing to reading mode
1031 {
1032  if (m_reading) return;
1033 
1034  FSEEK(m_readPos);
1035  m_reading = true;
1036 }
1037 
1038 //////////////////////////////////////////////////////////////////////////////////////////
1039 // Change from reading to writing mode
1041 {
1042  if (!m_reading) return;
1043 
1044  FSEEK(m_writePos);
1045  m_reading = false;
1046 }
1047 
1048 //////////////////////////////////////////////////////////////////////////////////////////
1049 // Insert the given data into the file.
1051  const CmtFilePos start, const uint32_t length, const void* data)
1052 {
1053  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
1054  if (m_readOnly) return m_lastResult = XRV_READONLY;
1055 
1056  gotoWrite();
1057 
1058  CmtFilePos rPos = start;
1059  CmtFilePos wPos = rPos + length;
1060 
1061  size_t read1, read2;
1062  CmtFilePos remaining = m_fileSize - start;
1063  size_t bsize = (length > 512) ? length : 512;
1064  char* buffer1 = (char*)malloc(bsize);
1065  char* buffer2 = (char*)malloc(bsize);
1066  char* btemp;
1067 
1068  // copy data
1069  FSEEK(rPos);
1070 
1071  if (remaining >= (CmtFilePos)bsize)
1072  read1 = fread(buffer1, 1, bsize, m_handle);
1073  else
1074  read1 = fread(buffer1, 1, (size_t)remaining, m_handle);
1075 
1076  remaining -= read1;
1077  rPos += read1;
1078 
1079  while (remaining > 0)
1080  {
1081  // move data to correct buffer
1082  read2 = read1;
1083  btemp = buffer1;
1084  buffer1 = buffer2;
1085  buffer2 = btemp;
1086 
1087  // read next block
1088  if (remaining >= (CmtFilePos)bsize)
1089  read1 = fread(buffer1, 1, bsize, m_handle);
1090  else
1091  read1 = fread(buffer1, 1, (size_t)remaining, m_handle);
1092 
1093  remaining -= read1;
1094  rPos += read1;
1095 
1096  // write block to the correct position
1097  FSEEK(wPos);
1098  wPos += fwrite(buffer2, 1, read2, m_handle);
1099  FSEEK(rPos);
1100  }
1101 
1102  FSEEK(wPos);
1103  wPos += fwrite(buffer1, 1, read1, m_handle);
1104 
1105  FSEEK(start);
1106  m_writePos = start + fwrite(data, 1, length, m_handle);
1107  m_fileSize += length;
1108 
1109  free(buffer1);
1110  free(buffer2);
1111  return m_lastResult = XRV_OK;
1112 }
1113 
1114 //////////////////////////////////////////////////////////////////////////////////////////
1115 // Open a file.
1117  const char* filename, const bool create, const bool readOnly)
1118 {
1119  if (m_isOpen) return m_lastResult = XRV_ALREADYOPEN;
1120 
1121  //! \test does this work for non-existing files? Or do we need a check and
1122  //! create?
1123  m_readOnly = readOnly;
1124  if (readOnly)
1125  m_handle = fopen(filename, "rb"); // open for read only (r)
1126  else
1127  m_handle = fopen(filename, "r+b"); // open for update (r/w)
1128  if (m_handle == nullptr)
1129  {
1130  if (create)
1131  m_handle = fopen(filename, "w+b"); // create for update (r/w)
1132  else
1133  {
1134  m_handle = fopen(filename, "rb"); // open for read only (r)
1135  m_readOnly = true;
1136  }
1137  }
1138  if (m_handle == nullptr) return m_lastResult = XRV_INPUTCANNOTBEOPENED;
1139 
1140 #ifdef _WIN32
1141  if (_fullpath(m_filename, filename, CMT_MAX_FILENAME_LENGTH) == nullptr)
1142  {
1143  fclose(m_handle);
1144  return m_lastResult = XRV_INVALIDPARAM;
1145  }
1146 #else
1147  // use the same trick again.
1148  if (realpath(filename, m_filename) == nullptr)
1149  {
1150  fclose(m_handle);
1151  return m_lastResult = XRV_INVALIDPARAM;
1152  }
1153 #endif
1155  m_unicode = false;
1156 
1157  m_isOpen = true;
1158  m_readPos = 0;
1159  m_writePos = 0;
1160  m_reading = true;
1161  FSEEK_R(0);
1162  m_fileSize = FTELL();
1163  FSEEK(0);
1164  return (m_lastResult = XRV_OK);
1165 }
1166 
1167 //////////////////////////////////////////////////////////////////////////////////////////
1168 // Open a file.
1170  const wchar_t* filename, const bool create, const bool readOnly)
1171 {
1172  if (m_isOpen) return m_lastResult = XRV_ALREADYOPEN;
1173 
1174 #ifdef _WIN32
1175  //! \test does this work for non-existing files? Or do we need a check and
1176  //! create?
1177  m_readOnly = readOnly;
1178  if (readOnly)
1179  m_handle = _wfopen(filename, L"rb"); // open for read only (r)
1180  else
1181  m_handle = _wfopen(filename, L"r+b"); // open for update (r/w)
1182  if (m_handle == nullptr)
1183  {
1184  if (create)
1185  m_handle = _wfopen(filename, L"w+b"); // create for update (r/w)
1186  else
1187  {
1188  m_handle = _wfopen(filename, L"rb"); // open for read only (r)
1189  m_readOnly = true;
1190  }
1191  }
1192  if (m_handle == nullptr) return m_lastResult = XRV_INPUTCANNOTBEOPENED;
1193 
1194  if (_wfullpath(m_filename_w, filename, CMT_MAX_FILENAME_LENGTH) == nullptr)
1195  {
1196  fclose(m_handle);
1197  return m_lastResult = XRV_INVALIDPARAM;
1198  }
1200 
1201  m_isOpen = true;
1202  m_readPos = 0;
1203  m_writePos = 0;
1204  m_reading = true;
1205  FSEEK_R(0);
1206  m_fileSize = FTELL();
1207  FSEEK(0);
1208 #else
1209  char tFilename[CMT_MAX_FILENAME_LENGTH * 2];
1210  wcstombs(tFilename, filename, CMT_MAX_FILENAME_LENGTH * 2);
1211  XsensResultValue res = open(tFilename, create, readOnly);
1212  if (res != XRV_OK) return res;
1213 #endif
1214  m_unicode = true;
1215  return m_lastResult = XRV_OK;
1216 }
1217 
1218 //////////////////////////////////////////////////////////////////////////////////////////
1219 // Read data from the file and put it into the data buffer.
1221  const uint32_t maxLength, void* data, uint32_t* length)
1222 {
1223  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
1224 
1225  if (maxLength == 0) return m_lastResult = XRV_OK;
1226 
1227  uint32_t len;
1228  if (length == nullptr) length = &len;
1229 
1230  gotoRead();
1231 
1232  length[0] = (uint32_t)fread(data, 1, maxLength, m_handle);
1233  if (length[0] == 0) return (m_lastResult = XRV_ENDOFFILE);
1234 
1235  m_readPos += length[0];
1236  return m_lastResult = XRV_OK;
1237 }
1238 
1239 //////////////////////////////////////////////////////////////////////////////////////////
1240 // Read data from the file until the terminator and put it into the data buffer.
1242  const uint32_t maxLength, const char terminator, void* dataV,
1243  uint32_t* length)
1244 {
1245  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
1246 
1247  uint32_t len;
1248  if (length == nullptr) length = &len;
1249 
1250  char* data = (char*)dataV;
1251  int32_t readChar;
1252 
1253  gotoRead();
1254 
1255  *length = 0;
1256  readChar = (uint32_t)fgetc(m_handle);
1257 
1258  while (!feof(m_handle) && !ferror(m_handle))
1259  {
1260  data[*length] = (char)readChar;
1261  ++(*length);
1262  ++m_readPos;
1263 
1264  if (((char)readChar == terminator) || ((*length) >= maxLength))
1265  return m_lastResult = XRV_OK;
1266  }
1267  return m_lastResult = XRV_ENDOFFILE;
1268 }
1269 
1270 //////////////////////////////////////////////////////////////////////////////////////////
1271 // Set the new absolute read position
1273 {
1274  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
1275 
1276  if (m_readPos != pos)
1277  {
1278  m_readPos = pos;
1279  if (m_reading) FSEEK(m_readPos);
1280  }
1281 
1282  return m_lastResult = XRV_OK;
1283 }
1284 
1285 //////////////////////////////////////////////////////////////////////////////////////////
1286 // Set the new absolute write position
1288 {
1289  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
1290  if (m_readOnly) return m_lastResult = XRV_READONLY;
1291 
1292  if (pos == -1)
1293  {
1294  if (m_reading) m_reading = false;
1295  FSEEK_R(0);
1296  m_writePos = FTELL();
1297  }
1298  else
1299  {
1300  if (m_writePos != pos)
1301  {
1302  m_writePos = pos;
1303  if (!m_reading) FSEEK(m_writePos);
1304  }
1305  }
1306 
1307  return m_lastResult = XRV_OK;
1308 }
1309 
1310 //////////////////////////////////////////////////////////////////////////////////////////
1311 // Write data to the file.
1313 {
1314  if (!m_isOpen) return m_lastResult = XRV_NOFILEOPEN;
1315  if (m_readOnly) return m_lastResult = XRV_READONLY;
1316 
1317  gotoWrite();
1318  m_writePos += fwrite(data, 1, length, m_handle);
1319 
1321 
1322  return m_lastResult = XRV_OK;
1323 }
1324 
1325 } // end of xsens namespace
xsens::Cmt1f::open
XsensResultValue open(const char *filename, const bool create, const bool readOnly)
Open a file.
Definition: cmt1.cpp:1116
maxLength
GLsizei maxLength
Definition: glext.h:4932
XRV_NOFILEOPEN
@ XRV_NOFILEOPEN
Definition: xsens_std.h:201
mrpt::system::os::fclose
int void fclose(FILE *f)
An OS-independent version of fclose.
Definition: os.cpp:273
xsens::Cmt1s::m_onBytesReceivedInstance
int32_t m_onBytesReceivedInstance
Custom, user supplied parameter for the OnBytesReceived callback function, passed as the first argume...
Definition: cmt1.h:77
CmtControlLine
CmtControlLine
Definition: cmtdef.h:821
CMT_CONTROL_RTS
@ CMT_CONTROL_RTS
Definition: cmtdef.h:829
xsens::Cmt1f::close
XsensResultValue close(void)
Close the file.
Definition: cmt1.cpp:713
mrpt::system::os::vsprintf
int int vsprintf(char *buf, size_t bufSize, const char *format, va_list args) noexcept
An OS-independent version of vsprintf (Notice the bufSize param, which may be ignored in some compile...
Definition: os.cpp:212
xsens::Cmt1s::m_onBytesReceivedParam
void * m_onBytesReceivedParam
Custom, user supplied parameter for the OnBytesReceived callback function, passed as the last argumen...
Definition: cmt1.h:80
xsens::Cmt1s::waitForData
XsensResultValue waitForData(const uint32_t maxLength, uint8_t *data, uint32_t *length=nullptr)
Wait for data to arrive or a timeout to occur.
Definition: cmt1.cpp:605
FSEEK
#define FSEEK(x)
Definition: cmt1.cpp:84
CmtCallbackSelector
CmtCallbackSelector
Definition: cmtdef.h:1120
XRV_TIMEOUT
@ XRV_TIMEOUT
Definition: xsens_std.h:112
start
GLuint start
Definition: glext.h:3528
XRV_OUTPUTCANNOTBEOPENED
@ XRV_OUTPUTCANNOTBEOPENED
Definition: xsens_std.h:142
xsens::Cmt1s::m_baudrate
uint32_t m_baudrate
The baudrate that was last set to be used by the port.
Definition: cmt1.h:84
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::Cmt1f::getName
XsensResultValue getName(char *filename) const
Retrieve the filename that was last successfully opened.
Definition: cmt1.cpp:1010
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::Cmt1s::setCallbackFunction
XsensResultValue setCallbackFunction(CmtCallbackSelector tp, int32_t instance, CmtCallbackFunction func, void *param)
Set the callback function for when bytes have been received.
Definition: cmt1.cpp:545
FTELL
#define FTELL()
Definition: cmt1.cpp:86
XRV_ENDOFFILE
@ XRV_ENDOFFILE
Definition: xsens_std.h:148
MRPT_UNUSED_PARAM
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
XRV_OUTOFMEMORY
@ XRV_OUTOFMEMORY
Definition: xsens_std.h:121
XRV_INPUTCANNOTBEOPENED
@ XRV_INPUTCANNOTBEOPENED
Definition: xsens_std.h:139
xsens::Cmt1f::m_fileSize
CmtFilePos m_fileSize
Contains the size of the file.
Definition: cmt1.h:250
XRV_NOPORTOPEN
@ XRV_NOPORTOPEN
Definition: xsens_std.h:204
xsens::Cmt1f::insertData
XsensResultValue insertData(const CmtFilePos start, const uint32_t length, const void *data)
Insert the given data into the file. The function writes the given data to the file at the current wr...
Definition: cmt1.cpp:1050
xsens::Cmt1f::m_writePos
CmtFilePos m_writePos
The last write position in the file.
Definition: cmt1.h:254
uint8_t
unsigned char uint8_t
Definition: rptypes.h:41
FSEEK_R
#define FSEEK_R(x)
Definition: cmt1.cpp:85
xsens::Cmt1f::gotoRead
void gotoRead(void)
Change from writing to reading mode.
Definition: cmt1.cpp:1030
xsens::Cmt1f::setWritePos
XsensResultValue setWritePos(const CmtFilePos pos=-1)
Set the new absolute write position.
Definition: cmt1.cpp:1287
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::Cmt1s::m_handle
HANDLE m_handle
The serial port handle.
Definition: cmt1.h:104
length
GLuint GLsizei GLsizei * length
Definition: glext.h:4064
cmt1.h
xsens::Cmt1f::m_handle
FILE * m_handle
The file handle.
Definition: cmt1.h:248
xsens::Cmt1s::m_isOpen
bool m_isOpen
Indicates if the port is open or not.
Definition: cmt1.h:89
xsens::Cmt1f::setReadPos
XsensResultValue setReadPos(const CmtFilePos pos)
Set the new absolute read position.
Definition: cmt1.cpp:1272
xsens::Cmt1f::Cmt1f
Cmt1f()
Default constructor, initializes all members to their default values.
Definition: cmt1.cpp:676
mrpt::system::os::sprintf
int sprintf(char *buf, size_t bufSize, const char *format,...) noexcept MRPT_printf_format_check(3
An OS-independent version of sprintf (Notice the bufSize param, which may be ignored in some compiler...
Definition: os.cpp:189
xsens::Cmt1s::m_lastResult
XsensResultValue m_lastResult
The last result of an operation.
Definition: cmt1.h:91
xsens::Cmt1f::closeAndDelete
XsensResultValue closeAndDelete(void)
Close the file and delete it.
Definition: cmt1.cpp:737
xsens::Cmt1s::m_port
uint8_t m_port
The opened COM port nr.
Definition: cmt1.h:93
CmtCallbackFunction
XsensResultValue(__cdecl * CmtCallbackFunction)(int32_t, CmtCallbackSelector, void *, void *)
Definition: cmtdef.h:1160
xsens::Cmt1s::m_timeout
uint32_t m_timeout
Definition: cmt1.h:98
data
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:3547
CMTLOG
#define CMTLOG(...)
Definition: cmt1.h:41
xsens::Cmt1f::m_reading
bool m_reading
Indicates whether the last operation was a read or write operation. This value is used to check wheth...
Definition: cmt1.h:270
count
GLuint GLuint GLsizei count
Definition: glext.h:3528
CMT_MAX_FILENAME_LENGTH
#define CMT_MAX_FILENAME_LENGTH
Definition: cmtdef.h:926
xsens::Cmt1f::m_filename_w
wchar_t m_filename_w[CMT_MAX_FILENAME_LENGTH]
Contains the name of the file that was last successfully opened using unicode.
Definition: cmt1.h:261
xsens::Cmt1s::m_commState
DCB m_commState
Stored settings about the serial port.
Definition: cmt1.h:102
res
GLuint res
Definition: glext.h:7268
XRV_READONLY
@ XRV_READONLY
Definition: xsens_std.h:157
xsens::Cmt1s::flushData
XsensResultValue flushData(void)
Flush all data to be transmitted / received.
Definition: cmt1.cpp:308
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::Cmt1s::m_endTime
uint32_t m_endTime
The time at which an operation will end in ms, used by several functions.
Definition: cmt1.h:87
mask
GLenum GLint GLuint mask
Definition: glext.h:4050
CmtBinaryData
Definition: cmtdef.h:1152
xsens::Cmt1s::Cmt1s
Cmt1s()
Default constructor, initializes all members to their default values.
Definition: cmt1.cpp:185
status
_u8 status
Definition: rplidar_cmd.h:2
mrpt::system::os::strcpy
char * strcpy(char *dest, size_t destSize, const char *source) noexcept
An OS-independent version of strcpy.
Definition: os.cpp:297
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::Cmt1f::~Cmt1f
~Cmt1f()
Destructor.
Definition: cmt1.cpp:691
CMT1_DEFAULT_TIMEOUT
#define CMT1_DEFAULT_TIMEOUT
The default timeout value for blocking CMT1s operations in ms.
Definition: cmtdef.h:805
len
GLenum GLsizei len
Definition: glext.h:4712
xsens::Cmt1f::m_readPos
CmtFilePos m_readPos
The last read position in the file.
Definition: cmt1.h:252
buffer
GLuint buffer
Definition: glext.h:3917
FALSE
#define FALSE
Definition: xmlParser.h:231
xsens::Cmt1f::gotoWrite
void gotoWrite(void)
Change from reading to writing mode.
Definition: cmt1.cpp:1040
int32_t
__int32 int32_t
Definition: rptypes.h:46
CMT_CALLBACK_ONBYTESRECEIVED
@ CMT_CALLBACK_ONBYTESRECEIVED
Callback function, called when bytes have been read from a port.
Definition: cmtdef.h:1137
mrpt::system::os::fprintf
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
Definition: os.cpp:406
BOOL
int BOOL
Definition: xstypedefs.h:76
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::Cmt1s::m_portname
char m_portname[260]
Definition: cmt1.h:94
XRV_ERROR
@ XRV_ERROR
Definition: xsens_std.h:106
XRV_BUSY
@ XRV_BUSY
Definition: xsens_std.h:166
CmtBinaryData::m_portNr
uint8_t m_portNr
Definition: cmtdef.h:1156
xsens::Cmt1f::m_readOnly
bool m_readOnly
Indicates if the file was opened in read-only mode.
Definition: cmt1.h:272
XRV_INVALIDPARAM
@ XRV_INVALIDPARAM
Definition: xsens_std.h:95
CmtBinaryData::m_data
uint8_t m_data[CMT_MAXMSGLEN]
Definition: cmtdef.h:1155
xsens::Cmt1f::m_unicode
bool m_unicode
Indicates if we're using the unicode filename or the regular filename.
Definition: cmt1.h:265
CmtBinaryData::m_size
int32_t m_size
Definition: cmtdef.h:1154
CMT1LOG
#define CMT1LOG(...)
Definition: cmt1.cpp:175
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
mrpt::system::os::fopen
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
Definition: os.cpp:255
xsens::Cmt1s::~Cmt1s
~Cmt1s()
Destructor, de-initializes, frees memory allocated for buffers, etc.
Definition: cmt1.cpp:202
xsens::Cmt1f::m_filename
char m_filename[CMT_MAX_FILENAME_LENGTH]
Contains the name of the file that was last successfully opened.
Definition: cmt1.h:258
CmtFilePos
__int64 CmtFilePos
Definition: cmtf.h:25
xsens::Cmt1f::flushData
XsensResultValue flushData(void)
Flush all data to be written. This function writes any remaining data immediately and does not return...
Definition: cmt1.cpp:1001
xsens::Cmt1f::m_isOpen
bool m_isOpen
Indicates if the file is open or not.
Definition: cmt1.h:263
xsens::Cmt1f::writeData
XsensResultValue writeData(const uint32_t length, const void *data)
Write data to the file.
Definition: cmt1.cpp:1312
xsens::Cmt1s::escape
XsensResultValue escape(const CmtControlLine mask, const CmtControlLine state)
Manipulate the Serial control lines.
Definition: cmt1.cpp:245
XRV_ALREADYOPEN
@ XRV_ALREADYOPEN
Definition: xsens_std.h:145
XsensResultValue
XsensResultValue
Xsens return values.
Definition: xsens_std.h:31
XRV_INVALIDINSTANCE
@ XRV_INVALIDINSTANCE
Definition: xsens_std.h:169
xsens::Cmt1s::m_onBytesReceived
CmtCallbackFunction m_onBytesReceived
The bytes received function.
Definition: cmt1.h:74
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
param
GLfloat param
Definition: glext.h:3831
xsens::Cmt1f::m_lastResult
XsensResultValue m_lastResult
The last result of an operation.
Definition: cmt1.h:256
CMT_CONTROL_DTR
@ CMT_CONTROL_DTR
Definition: cmtdef.h:826
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