16 #include <itkMutexLockHolder.h> 17 #include <itksys/SystemTools.hxx> 20 #include <igtlTransformMessage.h> 23 #include <igtl_status.h> 26 #include <igtlTrackingDataMessage.h> 35 m_Name(
"Unspecified Device"),
36 m_StopCommunication(false),
37 m_Hostname(
"127.0.0.1"),
40 m_MultiThreader(nullptr), m_SendThreadID(0), m_ReceiveThreadID(0), m_ConnectThreadID(0)
42 m_ReadFully = ReadFully;
53 m_MultiThreader = itk::MultiThreader::New();
74 if (m_MultiThreader.IsNotNull())
76 if ((m_SendThreadID != 0))
78 m_MultiThreader->TerminateThread(m_SendThreadID);
80 if ((m_ReceiveThreadID != 0))
82 m_MultiThreader->TerminateThread(m_ReceiveThreadID);
84 if ((m_ConnectThreadID != 0))
86 m_MultiThreader->TerminateThread(m_ConnectThreadID);
89 m_MultiThreader =
nullptr;
100 itkDebugMacro(
"setting m_State to " << state);
123 igtl::MessageHeader::Pointer headerMsg;
124 headerMsg = igtl::MessageHeader::New();
127 headerMsg->InitPack();
131 socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize(), 0);
141 return IGTL_STATUS_NOT_PRESENT;
146 return IGTL_STATUS_TIME_OUT;
148 else if (r == headerMsg->GetPackSize())
152 int crcCheck = headerMsg->Unpack(1);
154 if (crcCheck & igtl::MessageHeader::UNPACK_HEADER)
157 igtl::TimeStamp::Pointer ts;
158 ts = igtl::TimeStamp::New();
164 headerMsg->GetTimeStamp(ts);
165 ts->GetTimeStamp(&sec, &nanosec);
179 const char* curDevType = headerMsg->GetDeviceType();
180 if (std::strstr(curDevType,
"GET_") !=
nullptr ||
181 std::strstr(curDevType,
"STP_") !=
nullptr ||
182 std::strstr(curDevType,
"RTS_") !=
nullptr)
185 this->InvokeEvent(CommandReceivedEvent());
186 return IGTL_STATUS_OK;
190 igtl::MessageBase::Pointer curMessage;
195 if (curMessage.IsNull())
197 socket->Skip(headerMsg->GetBodySizeToRead(), 0);
200 return IGTL_STATUS_NOT_FOUND;
204 curMessage->SetMessageHeader(headerMsg);
205 curMessage->AllocatePack();
208 int receiveCheck = 0;
209 receiveCheck = socket->Receive(curMessage->GetPackBodyPointer(),
210 curMessage->GetPackBodySize(), m_ReadFully);
212 if (receiveCheck > 0)
214 int c = curMessage->Unpack(1);
215 if (!(c & igtl::MessageHeader::UNPACK_BODY))
217 return IGTL_STATUS_CHECKSUM_ERROR;
225 if (std::strstr(curDevType,
"STT_") !=
nullptr)
228 this->InvokeEvent(CommandReceivedEvent());
235 this->InvokeEvent(MessageReceivedEvent());
237 return IGTL_STATUS_OK;
241 MITK_WARN(
"IGTLDevice") <<
"Received a valid header but could not " 242 <<
"read the whole message.";
243 return IGTL_STATUS_UNKNOWN_ERROR;
250 return IGTL_STATUS_CHECKSUM_ERROR;
258 return IGTL_STATUS_UNKNOWN_ERROR;
268 igtl::Socket::Pointer socket)
273 MITK_ERROR(
"IGTLDevice") <<
"Could not send message because message is not " 274 "valid. Please check.";
278 igtl::MessageBase* sendMessage = msg->GetMessage();
283 int sendSuccess = socket->Send(sendMessage->GetPackPointer(), sendMessage->GetPackSize());
288 this->InvokeEvent(MessageSentEvent());
289 return IGTL_STATUS_OK;
293 return IGTL_STATUS_UNKNOWN_ERROR;
309 bool localStopCommunication;
315 while ((this->
GetState() ==
Running) && (localStopCommunication ==
false))
317 (this->*ComFunction)();
325 itksys::SystemTools::Delay(1);
332 MITK_ERROR(
"IGTLDevice::RunCommunication") <<
"Error while communicating. Thread stopped.";
338 MITK_DEBUG(
"IGTLDevice::RunCommunication") <<
"Reached end of communication.";
423 std::string returnType(
"RTS_");
424 returnType.append(type);
426 igtl::MessageBase::Pointer rtsMsg =
430 if (rtsMsg.IsNotNull())
463 igtl::TrackingDataMessage::Pointer msg = this->
m_MessageQueue->PullTrackingMessage();
487 mitk::IGTLMessageQueue::Pointer queue,
490 queue->EnableNoBufferingMode(enable);
496 struct itk::MultiThreader::ThreadInfoStruct * pInfo =
497 (
struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
498 if (pInfo ==
nullptr)
500 return ITK_THREAD_RETURN_VALUE;
502 if (pInfo->UserData ==
nullptr)
504 return ITK_THREAD_RETURN_VALUE;
507 if (igtlDevice !=
nullptr)
511 igtlDevice->m_SendThreadID = 0;
512 return ITK_THREAD_RETURN_VALUE;
518 struct itk::MultiThreader::ThreadInfoStruct * pInfo =
519 (
struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
520 if (pInfo ==
nullptr)
522 return ITK_THREAD_RETURN_VALUE;
524 if (pInfo->UserData ==
nullptr)
526 return ITK_THREAD_RETURN_VALUE;
529 if (igtlDevice !=
nullptr)
534 igtlDevice->m_ReceiveThreadID = 0;
535 return ITK_THREAD_RETURN_VALUE;
541 struct itk::MultiThreader::ThreadInfoStruct * pInfo =
542 (
struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
543 if (pInfo ==
nullptr)
545 return ITK_THREAD_RETURN_VALUE;
547 if (pInfo->UserData ==
nullptr)
549 return ITK_THREAD_RETURN_VALUE;
552 if (igtlDevice !=
nullptr)
557 igtlDevice->m_ConnectThreadID = 0;
558 return ITK_THREAD_RETURN_VALUE;
itk::FastMutexLock::Pointer m_ReceivingFinishedMutex
IGTLDeviceState GetState() const
Returns current object state (Setup, Ready or Running)
itk::FastMutexLock::Pointer m_StopCommunicationMutex
mitk::IGTLMessageFactory::Pointer m_MessageFactory
void SetState(IGTLDeviceState state)
change object state
static ITK_THREAD_RETURN_TYPE ThreadStartConnecting(void *data)
static start method for the connection thread.
bool StartCommunication()
Starts the communication between the two devices.
igtl::MessageBase::Pointer GetNextMiscMessage()
itk::FastMutexLock::Pointer m_StateMutex
static const int SOCKET_SEND_RECEIVE_TIMEOUT_MSEC
itk::FastMutexLock::Pointer m_ConnectingFinishedMutex
DataCollection - Class to facilitate loading/accessing structured data.
igtl::MessageBase::Pointer GetNextCommand()
Returns the oldest message in the command queue.
igtl::ImageMessage::Pointer GetNextImage2dMessage()
Returns the oldest message in the receive queue.
igtl::TransformMessage::Pointer GetNextTransformMessage()
igtl::ImageMessage::Pointer GetNextImage3dMessage()
virtual void Connect()
Call this method to check for other devices that want to connect to this one.
virtual void Send()=0
Call this method to send a message. The message will be read from the queue.
bool SendRTSMessage(const char *type)
Send RTS message of given type.
unsigned int ReceivePrivate(igtl::Socket *device)
Call this method to receive a message from the given device.
unsigned int SendMessagePrivate(mitk::IGTLMessage::Pointer msg, igtl::Socket::Pointer socket)
Sends a message.
virtual bool TestConnection()
TestConnection() tries to connect to a IGTL device on the current ip and port.
virtual void Receive()=0
Call this method to receive a message.
virtual bool CloseConnection()
Closes the connection to the device.
itk::MutexLockHolder< itk::FastMutexLock > MutexLockHolder
IGTLDeviceState
Type for state variable. The IGTLDevice is always in one of these states.
mitk::IGTLMessageQueue::Pointer m_MessageQueue
itk::FastMutexLock::Pointer m_SendingFinishedMutex
Interface for all OpenIGTLink Devices.
igtl::TrackingDataMessage::Pointer GetNextTrackingDataMessage()
void EnableNoBufferingMode(mitk::IGTLMessageQueue::Pointer queue, bool enable=true)
Sets the buffering mode of the given queue.
virtual bool StopCommunication()
Stops the communication between the two devices.
static ITK_THREAD_RETURN_TYPE ThreadStartReceiving(void *data)
static start method for the receiving thread.
static ITK_THREAD_RETURN_TYPE ThreadStartSending(void *data)
static start method for the sending thread.
igtl::Socket::Pointer m_Socket
void SendMessage(mitk::IGTLMessage::Pointer msg)
Adds the given message to the sending queue.
igtl::StringMessage::Pointer GetNextStringMessage()
void RunCommunication(void(IGTLDevice::*ComFunction)(void), itk::FastMutexLock *mutex)
Continuously calls the given function.