PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusCommand.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 "igtl_header.h"
9 #include "vtkImageData.h"
10 #include "vtkMatrix4x4.h"
11 #include "vtkPlusCommand.h"
13 #include "vtkVersion.h"
14 
15 const std::string vtkPlusCommand::DEVICE_NAME_COMMAND = "CMD";
16 const std::string vtkPlusCommand::DEVICE_NAME_REPLY = "ACK";
17 
18 //----------------------------------------------------------------------------
20  : CommandProcessor(NULL)
21  , ClientId(0)
22  , Id(0)
23  , RespondWithCommandMessage(true)
24 {
25 }
26 
27 //----------------------------------------------------------------------------
29 {
30 }
31 
32 //----------------------------------------------------------------------------
33 void vtkPlusCommand::PrintSelf(ostream& os, vtkIndent indent)
34 {
35  this->Superclass::PrintSelf(os, indent);
36 }
37 
38 //----------------------------------------------------------------------------
39 PlusStatus vtkPlusCommand::ReadConfiguration(vtkXMLDataElement* aConfig)
40 {
41  if (aConfig == NULL)
42  {
43  LOG_ERROR("vtkPlusCommand::ReadConfiguration failed, input is NULL");
44  return PLUS_FAIL;
45  }
46  SetName(aConfig->GetAttribute("Name"));
47  if (ValidateName() != PLUS_SUCCESS)
48  {
49  return PLUS_FAIL;
50  }
51  return PLUS_SUCCESS;
52 }
53 
54 //----------------------------------------------------------------------------
56 {
57  if (aConfig == NULL)
58  {
59  LOG_ERROR("vtkPlusCommand::WriteConfiguration failed, input is NULL");
60  return PLUS_FAIL;
61  }
62  aConfig->SetName("Command");
63  if (!this->Name.empty())
64  {
65  aConfig->SetAttribute("Name", this->Name.c_str());
66  }
67  else
68  {
69  // command name not set, so set the first command name as a default
70  std::list<std::string> cmdNames;
71  GetCommandNames(cmdNames);
72  if (!cmdNames.empty())
73  {
74  aConfig->SetAttribute("Name", cmdNames.front().c_str());
75  }
76  }
77  return PLUS_SUCCESS;
78 }
79 
80 //----------------------------------------------------------------------------
82 {
83  this->CommandProcessor = processor;
84 }
85 
86 //----------------------------------------------------------------------------
87 void vtkPlusCommand::SetMetaData(const igtl::MessageBase::MetaDataMap& metaData)
88 {
89  this->MetaData = metaData;
90 }
91 
92 //----------------------------------------------------------------------------
94 {
95  if (this->CommandProcessor == NULL)
96  {
97  LOG_ERROR("CommandProcessor is invalid");
98  return NULL;
99  }
100 
102  if (server == NULL)
103  {
104  LOG_ERROR("CommandProcessor::PlusServer is invalid");
105  return NULL;
106  }
107 
108  vtkPlusDataCollector* dataCollector = server->GetDataCollector();
109  if (dataCollector == NULL)
110  {
111  LOG_ERROR("CommandProcessor::PlusServer::DataCollector is invalid");
112  return NULL;
113  }
114  return dataCollector;
115 }
116 
117 //----------------------------------------------------------------------------
118 vtkIGSIOTransformRepository* vtkPlusCommand::GetTransformRepository()
119 {
120  if (this->CommandProcessor == NULL)
121  {
122  LOG_ERROR("CommandProcessor is invalid");
123  return NULL;
124  }
125 
127  if (server == NULL)
128  {
129  LOG_ERROR("CommandProcessor::PlusServer is invalid");
130  return NULL;
131  }
132 
133  vtkIGSIOTransformRepository* aRepository = server->GetTransformRepository();
134  if (aRepository == NULL)
135  {
136  LOG_ERROR("CommandProcessor::PlusServer::TransformRepository is invalid");
137  return NULL;
138  }
139  return aRepository;
140 }
141 
142 //----------------------------------------------------------------------------
144 {
145  if (this->Name.empty())
146  {
147  LOG_ERROR("Command name is not specified");
148  return PLUS_FAIL;
149  }
150  std::list<std::string> cmdNames;
151  GetCommandNames(cmdNames);
152  for (std::list<std::string>::iterator it = cmdNames.begin(); it != cmdNames.end(); ++it)
153  {
154  if (igsioCommon::IsEqualInsensitive(*it, this->Name))
155  {
156  // command found
157  return PLUS_SUCCESS;
158  }
159  }
160  LOG_ERROR("Command name " << this->Name << " is not recognized");
161  return PLUS_FAIL;
162 }
163 
164 //----------------------------------------------------------------------------
166 {
167  std::ostringstream ss;
168  ss << DEVICE_NAME_REPLY << "_" << Id;
169  return ss.str();
170 }
171 
172 //----------------------------------------------------------------------------
173 PlusStatus vtkPlusCommand::GenerateCommandDeviceName(const std::string& uid, std::string& outDeviceName)
174 {
175  if (uid.empty())
176  {
177  return PLUS_FAIL;
178  }
179 
180  outDeviceName = std::string(DEVICE_NAME_COMMAND) + "_" + uid;
181  return PLUS_SUCCESS;
182 }
183 
184 //----------------------------------------------------------------------------
186 {
187  std::string prefix = GetPrefixFromCommandDeviceName(deviceName);
188  if (!igsioCommon::IsEqualInsensitive(prefix, DEVICE_NAME_COMMAND))
189  {
190  return false;
191  }
192 
193  return true;
194 }
195 
196 //----------------------------------------------------------------------------
197 bool vtkPlusCommand::IsReplyDeviceName(const std::string& deviceName, const std::string& uid)
198 {
199  std::string prefix = GetPrefixFromCommandDeviceName(deviceName);
200  if (!igsioCommon::IsEqualInsensitive(prefix, DEVICE_NAME_REPLY))
201  {
202  // not ACK_...
203  return false;
204  }
205  if (uid.empty())
206  {
207  // ACK is received and no uid check is needed
208  return true;
209  }
210  std::string uidInDeviceName = GetUidFromCommandDeviceName(deviceName);
211  if (!igsioCommon::IsEqualInsensitive(uidInDeviceName, uid))
212  {
213  // uid mismatch
214  return false;
215  }
216  // this is an ACK_... message and the uid matches
217  return true;
218 }
219 
220 //----------------------------------------------------------------------------
222 {
223  std::string uid("");
224  std::size_t separatorPos = deviceName.find("_");
225  if (separatorPos != std::string::npos)
226  {
227  uid = deviceName.substr(separatorPos + 1);
228  }
229  return uid;
230 }
231 
232 //----------------------------------------------------------------------------
234 {
235  std::string prefix(deviceName);
236  std::size_t separatorPos = deviceName.find("_");
237  if (separatorPos != std::string::npos)
238  {
239  prefix = deviceName.substr(0, separatorPos);
240  }
241  return prefix;
242 }
243 
244 //------------------------------------------------------------------------------
246 {
247  // Append this->CommandResponses to 'responses'.
248  // Elements appended to 'responses' are removed from this->CommandResponseQueue.
249  responses.splice(responses.end(), this->CommandResponseQueue, this->CommandResponseQueue.begin(), this->CommandResponseQueue.end());
250 }
251 
252 //------------------------------------------------------------------------------
253 void vtkPlusCommand::QueueCommandResponse(PlusStatus status, const std::string& message, const std::string& error, const igtl::MessageBase::MetaDataMap* replyMetaData)
254 {
255  // Proper v1/v2 header version response handling is performed in vtkPlusOpenIGTLinkServer::CreateIgtlMessageFromCommandResponse
256 
257  vtkSmartPointer<vtkPlusCommandRTSCommandResponse> commandResponse = vtkSmartPointer<vtkPlusCommandRTSCommandResponse>::New();
258  commandResponse->SetClientId(this->ClientId);
259  commandResponse->SetOriginalId(this->Id);
260  commandResponse->SetDeviceName(this->DeviceName);
261  commandResponse->SetCommandName(this->GetName());
262  commandResponse->SetStatus(status);
263  commandResponse->SetRespondWithCommandMessage(this->RespondWithCommandMessage);
264  commandResponse->SetErrorString(error);
265  commandResponse->SetResultString(message);
266  if (replyMetaData != NULL)
267  {
268  commandResponse->SetParameters(*replyMetaData);
269  }
270  this->CommandResponseQueue.push_back(commandResponse);
271 }
static std::string GenerateReplyDeviceName(uint32_t uid)
virtual void PrintSelf(ostream &os, vtkIndent indent)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
std::string Name
static const std::string DEVICE_NAME_COMMAND
igsioStatus PlusStatus
Definition: PlusCommon.h:40
virtual void SetCommandProcessor(vtkPlusCommandProcessor *processor)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
virtual vtkIGSIOTransformRepository * GetTransformRepository()
Creates a PlusCommand from a string. If the commands are to be executed on the main thread then call ...
virtual vtkPlusOpenIGTLinkServer * GetPlusServer()
void PopCommandResponses(PlusCommandResponseList &responses)
#define PLUS_FAIL
Definition: PlusCommon.h:43
PlusStatus ValidateName()
vtkPlusCommandProcessor * CommandProcessor
void SetMetaData(const igtl::MessageBase::MetaDataMap &metaData)
virtual void GetCommandNames(std::list< std::string > &cmdNames)=0
Manages devices that record image or positional data.
const char ** deviceName
Definition: phidget22.h:1316
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
bool RespondWithCommandMessage
igtl::MessageBase::MetaDataMap MetaData
virtual ~vtkPlusCommand()
void QueueCommandResponse(PlusStatus status, const std::string &message, const std::string &error="", const igtl::MessageBase::MetaDataMap *metaData=nullptr)
virtual vtkPlusDataCollector * GetDataCollector()
std::string DeviceName
static std::string GetPrefixFromCommandDeviceName(const std::string &deviceName)
static bool IsCommandDeviceName(const std::string &deviceName)
static std::string GetUidFromCommandDeviceName(const std::string &deviceName)
const char * message
Definition: phidget22.h:2457
This class provides a network interface for data acquired by Plus as an OpenIGTLink server.
std::list< vtkSmartPointer< vtkPlusCommandResponse > > PlusCommandResponseList
PlusCommandResponseList CommandResponseQueue
static PlusStatus GenerateCommandDeviceName(const std::string &uid, std::string &outDeviceName)
static bool IsReplyDeviceName(const std::string &deviceName, const std::string &uid=std::string(""))
static const std::string DEVICE_NAME_REPLY
vtkNew< vtkPlusOpenIGTLinkServer > server