8 #include "PlusConfigure.h" 14 #include <vtkObjectFactory.h> 15 #include <vtkXMLDataElement.h> 16 #include <vtkXMLUtilities.h> 17 #include <vtksys/SystemTools.hxx> 33 void bin2hex(
const std::string& inputBinary, std::string& outputHexEncoded)
36 ss << std::hex << std::setfill(
'0');
37 for (
unsigned int i = 0;
i < inputBinary.size();
i++)
43 ss << std::setw(2) <<
int(inputBinary[
i]);
45 outputHexEncoded = ss.str();
49 void hex2bin(
const std::string& inputHexEncoded, std::string& outputBinary)
53 std::stringstream ss(inputHexEncoded);
54 while (ss >> std::hex >>
i)
56 outputBinary += static_cast<char>(
i);
67 , MaximumReplyDelaySec(0.100)
68 , MaximumReplyDurationSec(0.300)
69 , Mutex(vtkSmartPointer<vtkIGSIORecursiveCriticalSection>::New())
71 , FieldDataSource(nullptr)
106 LOG_TRACE(
"vtkPlusGenericSerialDevice::Connect");
110 LOG_ERROR(
"Already connected to serial port");
117 std::ostringstream strComPort;
124 strComPort <<
"\\\\.\\COM" << this->
SerialPort;
126 this->
Serial->SetPortName(strComPort.str());
134 LOG_ERROR(
"Cannot open serial port " << strComPort.str());
140 LOG_ERROR(
"COM port handle is not alive " << strComPort.str());
146 LOG_ERROR(
"Could not re-establish DTR (data-terminal-ready) line ");
152 LOG_ERROR(
"Could not re-establish RTS (request-to-send) line ");
162 LOG_TRACE(
"vtkPlusGenericSerialDevice::Disconnect");
174 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->
Mutex);
178 double startTime = vtkIGSIOAccurateTimer::GetSystemTime();
181 std::string textReceived;
183 LOG_DEBUG(
"Received from serial device without request: " << textReceived);
184 if (vtkIGSIOAccurateTimer::GetSystemTime() - startTime > maxReadTimeSec)
197 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->
Mutex);
201 if (onOff == this->
DTR)
221 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->
Mutex);
225 if (onOff == this->
RTS)
245 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->
Mutex);
254 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->
Mutex);
262 LOG_DEBUG(
"Send to Serial device: " << textToSend);
265 igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->
Mutex);
268 unsigned char packetLength = textToSend.size();
269 for (
int i = 0;
i < packetLength;
i++)
274 for (std::string::iterator lineEndingIt = this->
LineEndingBin.begin(); lineEndingIt != this->
LineEndingBin.end(); ++lineEndingIt)
279 if (textReceived != NULL)
281 textReceived->clear();
289 *textReceived +=
line;
292 *textReceived +=
line;
294 LOG_DEBUG(
"Received from serial device: " << (*textReceived));
302 const int waitPeriodSec = 0.010;
304 double startTime = vtkIGSIOAccurateTimer::GetSystemTime();
312 vtksys::SystemTools::Delay(waitPeriodSec * 1000);
321 textReceived.clear();
322 double startTime = vtkIGSIOAccurateTimer::GetSystemTime();
327 bool lineEndingFound =
false;
337 static vtkIGSIOLogHelper logHelper(60.0, 1e6);
338 CUSTOM_RETURN_WITH_FAIL_IF(
true,
"Failed to get a proper response within configured time (" << this->
MaximumReplyDurationSec <<
" sec)");
342 RETURN_WITH_FAIL_IF(
true,
"Failed to read a complete line from serial device. Received: " << textReceived);
350 textReceived.push_back(d);
351 lineEndingFound = textReceived.size() >= lineEndingLength
352 && (this->
LineEndingBin.compare(textReceived.substr(textReceived.size() - lineEndingLength, lineEndingLength)) == 0);
355 while (!lineEndingFound);
358 textReceived.erase(textReceived.size() - lineEndingLength, lineEndingLength);
363 igsioFieldMapType fieldMap;
388 XML_READ_SCALAR_ATTRIBUTE_REQUIRED(
unsigned long,
SerialPort, deviceConfig);
389 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
unsigned long,
BaudRate, deviceConfig);
392 XML_READ_CSTRING_ATTRIBUTE_OPTIONAL(
LineEnding, deviceConfig);
400 deviceConfig->SetUnsignedLongAttribute(
"SerialPort", this->
SerialPort);
401 deviceConfig->SetUnsignedLongAttribute(
"BaudRate", this->
BaudRate);
404 deviceConfig->SetAttribute(
"LineEnding", this->
LineEnding.c_str());
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
PlusStatus SetRTS(bool onOff)
int Write(const BYTE *data, int numberOfBytesToWrite)
vtkPlusGenericSerialDevice()
static const char * SERIAL_COMMAND_GET_CTS
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
virtual PlusStatus NotifyConfigured()
void SetMaxReplyTime(int maxreply)
PlusStatus GetCTS(bool &onOff)
int Read(BYTE *data, int maxNumberOfBytesToRead)
virtual PlusStatus AddItem(vtkImageData *frame, US_IMAGE_ORIENTATION usImageOrientation, US_IMAGE_TYPE imageType, long frameNumber, double unfilteredTimestamp=UNDEFINED_TIMESTAMP, double filteredTimestamp=UNDEFINED_TIMESTAMP, const igsioFieldMapType *customFields=NULL)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
void bin2hex(const std::string &inputBinary, std::string &outputHexEncoded)
std::string LineEndingBin
void SetLineEnding(const char *lineEndingHex)
Class for reading and writing data through the serial (RS-232) port.
DataSourceContainer Fields
void hex2bin(const std::string &inputHexEncoded, std::string &outputBinary)
PlusStatus SetDTR(bool onOff)
void PrintSelf(ostream &os, vtkIndent indent)
double MaximumReplyDurationSec
PlusStatus InternalUpdate()
static const char * SERIAL_COMMAND_GET_RTS
vtkStandardNewMacro(vtkPlusGenericSerialDevice)
virtual PlusStatus StopRecording()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
PlusStatus SetDTR(bool onOff)
PlusStatus GetCTS(bool &onOff)
~vtkPlusGenericSerialDevice()
bool StartThreadForInternalUpdates
PlusStatus InternalConnect()
vtkPlusDataSource * FieldDataSource
unsigned int GetNumberOfBytesAvailableForReading() const
double MaximumReplyDelaySec
vtkSmartPointer< vtkIGSIORecursiveCriticalSection > Mutex
virtual PlusStatus InternalDisconnect()
static const char * SERIAL_COMMAND_SET_RTS
virtual PlusStatus ReceiveResponse(std::string &textReceived, ReplyTermination acceptReply=REQUIRE_LINE_ENDING)
virtual PlusStatus SendText(const std::string &textToSend, std::string *textReceived=NULL) VTK_OVERRIDE
DataSourceContainerConstIterator GetFieldDataSourcessIteratorEnd() const
Generic interface for communicating with a serial device.
DataSourceContainerConstIterator GetFieldDataSourcessIteratorBegin() const
PlusStatus GetDSR(bool &onOff)
PlusStatus SetRTS(bool onOff)
PlusStatus GetDSR(bool &onOff)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
void SetSerialPortSpeed(DWORD speed)
bool IsHandleAlive() const
virtual bool WaitForResponse()