21 #include <itksys/SystemTools.hxx>
23 #include <sys/types.h>
26 #include <sys/ioctl.h>
32 #define INVALID_HANDLE_VALUE -1
39 m_DeviceName(
""), m_PortNumber(COM1), m_BaudRate(BaudRate9600),
40 m_DataBits(DataBits8), m_Parity(None), m_StopBits(StopBits1),
41 m_HardwareHandshake(HardwareHandshakeOff),
42 m_ReceiveTimeout(500), m_SendTimeout(500), m_Connected(false)
44 #ifdef WIN32 // Windows
63 if (m_DeviceName.empty())
64 ss <<
"\\\\.\\COM" << static_cast<unsigned int>(m_PortNumber);
66 ss <<
"\\\\.\\" << m_DeviceName;
68 m_ComPortHandle = CreateFile(ss.str().c_str(), GENERIC_READ | GENERIC_WRITE,
77 GetCommState(m_ComPortHandle, &m_PreviousDeviceControlBlock);
78 GetCommTimeouts(m_ComPortHandle, &m_PreviousTimeout);
79 GetCommMask(m_ComPortHandle, &m_PreviousMask);
81 if (this->ApplyConfiguration() !=
OK)
83 CloseHandle(m_ComPortHandle);
92 if (m_DeviceName.empty())
93 ss <<
"/dev/ttyS" << static_cast<unsigned int>(m_PortNumber) - 1;
98 m_FileDescriptor = open(ss.str().c_str(), O_RDWR|O_NONBLOCK|O_EXCL);
99 if (m_FileDescriptor < 0)
102 fcntl(m_FileDescriptor, F_SETFL, 0);
103 tcflush(m_FileDescriptor, TCIOFLUSH);
104 if (this->ApplyConfiguration() !=
OK)
106 close(m_FileDescriptor);
120 ClearReceiveBuffer();
122 SetCommState(m_ComPortHandle, &m_PreviousDeviceControlBlock);
123 SetCommTimeouts(m_ComPortHandle, &m_PreviousTimeout);
124 SetCommMask(m_ComPortHandle, m_PreviousMask);
125 PurgeComm(m_ComPortHandle, PURGE_TXCLEAR | PURGE_RXCLEAR);
126 CloseHandle(m_ComPortHandle);
134 ClearReceiveBuffer();
136 close(m_FileDescriptor);
145 if (numberOfBytes == 0)
147 if (m_Connected ==
false)
154 DWORD numberOfBytesRead = 0;
155 char* buffer =
new char[numberOfBytes];
156 if (ReadFile(m_ComPortHandle, buffer, numberOfBytes, &numberOfBytesRead, NULL) != 0)
158 if (numberOfBytesRead > 0)
160 answer.assign(buffer, numberOfBytesRead);
162 if (numberOfBytesRead == numberOfBytes)
185 unsigned long bytesRead = 0;
186 unsigned long bytesLeft = numberOfBytes;
187 auto buffer =
new char[numberOfBytes];
189 while ((bytesLeft > 0) && (bytesRead < numberOfBytes))
191 int num = read(m_FileDescriptor, &buffer[bytesRead], 1);
205 if (eol && *eol == buffer[bytesRead-1])
209 answer.assign(buffer, bytesRead);
211 if ( bytesRead == numberOfBytes ||
212 (eol && answer.size() > 0 && *eol == answer.at(answer.size()-1)) )
224 if (m_Connected ==
false)
231 DWORD bytesWritten = 0;
232 if (WriteFile(m_ComPortHandle, input.data(),
static_cast<DWORD
>(input.size()), &bytesWritten, NULL) == TRUE)
235 return GetLastError();
241 long bytesWritten = 0;
242 long bytesLeft = input.size();
244 while (bytesLeft > 0)
246 bytesWritten = write(m_FileDescriptor, input.data() + bytesWritten, bytesLeft);
247 if (bytesWritten <= 0)
249 bytesLeft -= bytesWritten;
254 if (tcdrain(m_FileDescriptor) == -1)
263 #ifdef WIN32 // Windows implementation
264 return ApplyConfigurationWin();
266 return ApplyConfigurationUnix();
275 int mitk::SerialCommunication::ApplyConfigurationWin()
281 if (GetCommState(m_ComPortHandle, &controlSettings) == 0)
286 std::ostringstream o;
287 o <<
"baud=" << m_BaudRate <<
" parity=" <<
static_cast<char>(m_Parity) <<
" data=" << m_DataBits <<
" stop=" << m_StopBits;
288 if (BuildCommDCBA(o.str().c_str(), &controlSettings) == 0)
291 if (m_HardwareHandshake == HardwareHandshakeOn)
293 controlSettings.fDtrControl = DTR_CONTROL_ENABLE;
294 controlSettings.fRtsControl = RTS_CONTROL_ENABLE;
295 controlSettings.fOutxCtsFlow = TRUE;
296 controlSettings.fRtsControl = RTS_CONTROL_HANDSHAKE;
300 controlSettings.fDtrControl = DTR_CONTROL_DISABLE;
301 controlSettings.fRtsControl = RTS_CONTROL_DISABLE;
302 controlSettings.fOutxCtsFlow = FALSE;
303 controlSettings.fRtsControl = RTS_CONTROL_DISABLE;
305 if (SetCommState(m_ComPortHandle, &controlSettings) == FALSE)
306 return GetLastError();
308 COMMTIMEOUTS timeouts;
310 timeouts.ReadIntervalTimeout = m_ReceiveTimeout;
311 timeouts.ReadTotalTimeoutMultiplier = 0;
312 timeouts.ReadTotalTimeoutConstant = m_ReceiveTimeout;
313 timeouts.WriteTotalTimeoutMultiplier = 0;
314 timeouts.WriteTotalTimeoutConstant = m_SendTimeout;
315 if (SetCommTimeouts(m_ComPortHandle, &timeouts) == FALSE)
316 return GetLastError();
318 PurgeComm(m_ComPortHandle, PURGE_TXCLEAR | PURGE_RXCLEAR);
331 struct termios termIOStructure;
332 if ( tcgetattr(m_FileDescriptor, &termIOStructure) != 0 )
335 cfmakeraw(&termIOStructure);
336 termIOStructure.c_cflag |= CLOCAL;
337 if (m_HardwareHandshake == HardwareHandshakeOn)
339 termIOStructure.c_cflag |= CRTSCTS;
340 termIOStructure.c_iflag &= ~(IXON|IXOFF);
344 termIOStructure.c_cflag &= ~CRTSCTS;
345 termIOStructure.c_iflag &= ~(IXON|IXOFF);
347 termIOStructure.c_cflag &= ~CSIZE;
351 termIOStructure.c_cflag |= CS7;
355 termIOStructure.c_cflag |= CS8;
360 termIOStructure.c_cflag |= CSTOPB;
364 termIOStructure.c_cflag &= ~CSTOPB;
369 termIOStructure.c_cflag |= (PARENB|PARODD);
372 termIOStructure.c_cflag |= PARENB;
373 termIOStructure.c_cflag &= ~PARODD;
376 termIOStructure.c_cflag &= ~PARENB;
417 case BaudRate1000000:
420 case BaudRate1152000:
426 case BaudRate1500000:
429 case BaudRate2000000:
432 case BaudRate2500000:
435 case BaudRate3000000:
438 case BaudRate3500000:
441 case BaudRate4000000:
446 MITK_WARN(
"mitk::SerialCommunication") <<
"Baud rate not recognized, using default of 9600 Baud.";
450 cfsetispeed(&termIOStructure, baudrate);
451 cfsetospeed(&termIOStructure, baudrate);
453 termIOStructure.c_cc[VMIN] = 0;
454 termIOStructure.c_cc[VTIME] = m_ReceiveTimeout / 100;
456 if (tcsetattr(m_FileDescriptor, TCSANOW, &termIOStructure) == 0)
470 SetCommBreak(m_ComPortHandle);
471 itksys::SystemTools::Delay(ms);
472 ClearCommBreak(m_ComPortHandle);
479 tcsendbreak(m_FileDescriptor, ms);
488 PurgeComm(m_ComPortHandle, PURGE_RXCLEAR);
491 tcflush(m_FileDescriptor, TCIFLUSH);
499 PurgeComm(m_ComPortHandle, PURGE_TXCLEAR);
502 tcflush(m_FileDescriptor, TCOFLUSH);
int ApplyConfigurationUnix()
Applies the configuration for Linux.
void ClearReceiveBuffer()
erase the receive buffer of the serial interface
int ApplyConfiguration()
configures the serial interface with all parameters
int Send(const std::string &input, bool block=false)
Send the string input.
void CloseConnection()
Closes the connection.
int Receive(std::string &answer, unsigned int numberOfBytes, const char *eol=nullptr)
Read numberOfBytes characters from the serial interface.
void ClearSendBuffer()
erase the send buffer of the serial interface
void SendBreak(unsigned int ms=400)
Send the break signal for ms milliseconds.
virtual ~SerialCommunication()
int OpenConnection()
Opens connection to the COM port with port number m_PortNumber or the device name m_DeviceName and al...
#define INVALID_HANDLE_VALUE