PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
PlusSerialLine.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2  Program: Plus
3  Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4  See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 #include "PlusConfigure.h"
8 #include "PlusSerialLine.h"
9 
10 //----------------------------------------------------------------------------
12  : MaxReplyTime(1000)
13  , SerialPortSpeed(9600)
14  , CommHandle(INVALID_HANDLE_VALUE)
15 {
16 
17 }
18 
19 //----------------------------------------------------------------------------
21 {
22  if (CommHandle != INVALID_HANDLE_VALUE)
23  {
24  Close();
25  }
26 }
27 
28 //----------------------------------------------------------------------------
30 {
31 #ifdef _WIN32
32  if (CommHandle != INVALID_HANDLE_VALUE)
33  {
34  CloseHandle(CommHandle);
35  }
36 #endif
37  CommHandle = INVALID_HANDLE_VALUE;
38 }
39 
40 //----------------------------------------------------------------------------
42 {
43  if (CommHandle != INVALID_HANDLE_VALUE)
44  {
45  Close();
46  }
47 
48  // Open serial port
49 #ifdef _WIN32
50  CommHandle = CreateFile(this->PortName.c_str(),
51  GENERIC_READ | GENERIC_WRITE,
52  0, // not allowed to share ports
53  0, // child-processes don't inherit handle
54  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
55  NULL); /* no template file */
56  if (CommHandle == INVALID_HANDLE_VALUE)
57  {
58  return false;
59  }
60 
61  if (!SetupComm(CommHandle, 16384, 16384))
62  {
63  Close();
64  return false;
65  }
66  DCB dcb;
67  GetCommState(CommHandle, &dcb);
68  dcb.BaudRate = SerialPortSpeed;
69  dcb.Parity = NOPARITY;
70  dcb.ByteSize = 8;
71  dcb.StopBits = ONESTOPBIT;
72  if (!SetCommState(CommHandle, &dcb))
73  {
74  Close();
75  return false;
76  }
77 
78  COMMTIMEOUTS timeouts;
79  GetCommTimeouts(CommHandle, &timeouts);
80  timeouts.ReadIntervalTimeout = 200;
81  timeouts.ReadTotalTimeoutConstant = MaxReplyTime;
82  timeouts.ReadTotalTimeoutMultiplier = 100;
83  timeouts.WriteTotalTimeoutConstant = MaxReplyTime;
84  timeouts.WriteTotalTimeoutMultiplier = 100;
85  if (!SetCommTimeouts(CommHandle, &timeouts))
86  {
87  Close();
88  return false;
89  }
90 
91  return true;
92 #else
93  LOG_ERROR("SerialLine::Open() is only implemented on Windows");
94  CommHandle = INVALID_HANDLE_VALUE;
95  return false;
96 #endif
97 }
98 
99 //----------------------------------------------------------------------------
100 int SerialLine::Write(const BYTE* data, int numberOfBytesToWrite)
101 {
102 #ifdef _WIN32
103  int numberOfBytesWrittenTotal = 0;
104  while (numberOfBytesToWrite > 0)
105  {
106  DWORD numberOfBytesWritten = 0;
107  if (WriteFile(CommHandle, &data[numberOfBytesWrittenTotal], numberOfBytesToWrite, &numberOfBytesWritten, NULL) == FALSE)
108  {
109  if (GetLastError() == ERROR_OPERATION_ABORTED)
110  {
111  // system error: clear error and retry
112  DWORD errors = 0;
113  ClearCommError(CommHandle, &errors, NULL);
114  }
115  else
116  {
117  // other error
118  return numberOfBytesWritten;
119  }
120  }
121  else if (numberOfBytesWritten == 0)
122  {
123  // no characters written, must have timed out
124  return numberOfBytesWrittenTotal;
125  }
126 
127  numberOfBytesToWrite -= numberOfBytesWritten;
128  numberOfBytesWrittenTotal += numberOfBytesWritten;
129  }
130  return numberOfBytesWrittenTotal;
131 #else
132  LOG_ERROR("SerialLine::Write() is only implemented on Windows");
133  return 0;
134 #endif
135 }
136 
137 //----------------------------------------------------------------------------
139 {
140  return Write(&data, 1) == 1;
141 }
142 
143 //----------------------------------------------------------------------------
144 int SerialLine::Read(BYTE* data, int maxNumberOfBytesToRead)
145 {
146 #ifdef _WIN32
147  int numberOfBytesReadTotal = 0;
148  while (maxNumberOfBytesToRead > 0)
149  {
150  DWORD numberOfBytesRead;
151  if (ReadFile(CommHandle, &data[numberOfBytesReadTotal], maxNumberOfBytesToRead, &numberOfBytesRead, NULL) == FALSE)
152  {
153  DWORD lastError = GetLastError();
154  if (lastError == ERROR_OPERATION_ABORTED)
155  {
156  // system error: clear error and retry
157  DWORD errors = 0;
158  ClearCommError(CommHandle, &errors, NULL);
159  }
160  else
161  {
162  // other error
163  return numberOfBytesReadTotal;
164  }
165  }
166  else if (numberOfBytesRead == 0)
167  {
168  // no characters read, must have timed out
169  return numberOfBytesReadTotal;
170  }
171  maxNumberOfBytesToRead -= numberOfBytesRead;
172  numberOfBytesReadTotal += numberOfBytesRead;
173  }
174  return numberOfBytesReadTotal;
175 #else
176  LOG_ERROR("SerialLine::Read() is only implemented on Windows");
177  return 0;
178 #endif
179 }
180 
181 //----------------------------------------------------------------------------
183 {
184  return Read(&data, 1) == 1;
185 }
186 
187 //----------------------------------------------------------------------------
189 {
190 #ifdef _WIN32
191  DWORD dwErrors = 0;
192  COMSTAT comStat;
193  ClearCommError(CommHandle, &dwErrors, &comStat);
194  return dwErrors;
195 #else
196  LOG_ERROR("SerialLine::ClearError() is only implemented on Windows");
197  return 0;
198 #endif
199 }
200 
201 //----------------------------------------------------------------------------
203 {
204  SerialPortSpeed = speed;
205 }
206 
207 //----------------------------------------------------------------------------
208 void SerialLine::SetMaxReplyTime(int maxreply)
209 {
210  MaxReplyTime = maxreply;
211 }
212 
213 //----------------------------------------------------------------------------
215 {
216  return MaxReplyTime;
217 }
218 
219 //----------------------------------------------------------------------------
221 {
222  return (CommHandle != INVALID_HANDLE_VALUE);
223 }
224 
225 //----------------------------------------------------------------------------
227 {
228 #ifdef _WIN32
229  DWORD dwErrorFlags = 0;
230  COMSTAT comStat;
231  ClearCommError(CommHandle, &dwErrorFlags, &comStat);
232  return ((int) comStat.cbInQue);
233 #else
234  LOG_ERROR("SerialLine::GetNumberOfBytesAvailableForReading() is only implemented on Windows");
235  return 0;
236 #endif
237 }
238 
239 //----------------------------------------------------------------------------
241 {
242 #ifdef _WIN32
243  DWORD dwFunc = CLRDTR;
244  if (onOff)
245  {
246  dwFunc = SETDTR;
247  }
248  if (EscapeCommFunction(CommHandle, dwFunc))
249  {
250  return PLUS_SUCCESS;
251  }
252  else
253  {
254  return PLUS_FAIL;
255  }
256 #else
257  LOG_ERROR("SerialLine::SetDTR() is only implemented on Windows");
258  return PLUS_FAIL;
259 #endif
260 }
261 
262 //----------------------------------------------------------------------------
264 {
265 #ifdef _WIN32
266  DWORD dwFunc = CLRRTS;
267  if (onOff)
268  {
269  dwFunc = SETRTS;
270  }
271  if (EscapeCommFunction(CommHandle, dwFunc))
272  {
273  return PLUS_SUCCESS;
274  }
275  else
276  {
277  return PLUS_FAIL;
278  }
279 #else
280  LOG_ERROR("SerialLine::SetRTS() is only implemented on Windows");
281  return PLUS_FAIL;
282 #endif
283 }
284 
285 //----------------------------------------------------------------------------
287 {
288 #ifdef _WIN32
289  DWORD dwStatus = 0;
290  if (!GetCommModemStatus(CommHandle, &dwStatus))
291  {
292  return PLUS_FAIL;
293  }
294  onOff = MS_DSR_ON & dwStatus;
295  return PLUS_SUCCESS;
296 #else
297  LOG_ERROR("SerialLine::GetDSR() is only implemented on Windows");
298  return PLUS_FAIL;
299 #endif
300 }
301 
302 //----------------------------------------------------------------------------
304 {
305 #ifdef _WIN32
306  DWORD dwStatus = 0;
307  if (!GetCommModemStatus(CommHandle, &dwStatus))
308  {
309  return PLUS_FAIL;
310  }
311  onOff = MS_CTS_ON & dwStatus;
312  return PLUS_SUCCESS;
313 #else
314  LOG_ERROR("SerialLine::GetCTS() is only implemented on Windows");
315  return PLUS_FAIL;
316 #endif
317 }
const uint32_t * data
Definition: phidget22.h:3971
PlusStatus SetRTS(bool onOff)
int Write(const BYTE *data, int numberOfBytesToWrite)
virtual ~SerialLine()
void SetMaxReplyTime(int maxreply)
igsioStatus PlusStatus
Definition: PlusCommon.h:40
int Read(BYTE *data, int maxNumberOfBytesToRead)
#define PLUS_FAIL
Definition: PlusCommon.h:43
DWORD ClearError()
#define FALSE
Definition: ATC3DGm.h:220
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus SetDTR(bool onOff)
PlusStatus GetCTS(bool &onOff)
#define INVALID_HANDLE_VALUE
unsigned int GetNumberOfBytesAvailableForReading() const
unsigned long DWORD
PlusStatus GetDSR(bool &onOff)
void SetSerialPortSpeed(DWORD speed)
bool IsHandleAlive() const
int GetMaxReplyTime() const
unsigned char BYTE