PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusRequestIdsCommand.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 "vtkPlusChannel.h"
11 #include "vtkPlusCommandResponse.h"
12 #include "vtkPlusDataCollector.h"
13 #include "vtkPlusDeviceFactory.h"
16 
18 
19 namespace
20 {
21  static const std::string REQUEST_CHANNEL_IDS_CMD = "RequestChannelIds";
22  static const std::string REQUEST_DEVICE_CHANNEL_IDS_CMD = "RequestDeviceChannelIds";
23  static const std::string REQUEST_DEVICE_IDS_CMD = "RequestDeviceIds";
24  static const std::string REQUEST_INPUT_DEVICE_IDS_CMD = "RequestInputDeviceIds";
25 }
26 
27 //----------------------------------------------------------------------------
29 {
30 }
31 
32 //----------------------------------------------------------------------------
34 {
35 }
36 
37 //----------------------------------------------------------------------------
39 {
40  SetName(REQUEST_CHANNEL_IDS_CMD);
41 }
43 {
44  SetName(REQUEST_DEVICE_IDS_CMD);
45 }
47 {
48  SetName(REQUEST_INPUT_DEVICE_IDS_CMD);
49 }
51 {
52  SetName(REQUEST_DEVICE_CHANNEL_IDS_CMD);
53 }
54 
55 //----------------------------------------------------------------------------
56 void vtkPlusRequestIdsCommand::GetCommandNames(std::list<std::string>& cmdNames)
57 {
58  cmdNames.clear();
59  cmdNames.push_back(REQUEST_CHANNEL_IDS_CMD);
60  cmdNames.push_back(REQUEST_DEVICE_IDS_CMD);
61  cmdNames.push_back(REQUEST_INPUT_DEVICE_IDS_CMD);
62  cmdNames.push_back(REQUEST_DEVICE_CHANNEL_IDS_CMD);
63 }
64 
65 //----------------------------------------------------------------------------
66 std::string vtkPlusRequestIdsCommand::GetDescription(const std::string& commandName)
67 {
68  std::string desc;
69  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, REQUEST_CHANNEL_IDS_CMD))
70  {
71  desc += REQUEST_CHANNEL_IDS_CMD;
72  desc += ": Request the list of channels for all devices.";
73  }
74  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, REQUEST_DEVICE_IDS_CMD))
75  {
76  desc += REQUEST_DEVICE_IDS_CMD;
77  desc += ": Request the list of devices. Attributes: DeviceType: restrict the returned list of devices to a specific type (VirtualCapture, VirtualVolumeReconstructor, etc.)";
78  }
79  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, REQUEST_INPUT_DEVICE_IDS_CMD))
80  {
81  desc += REQUEST_INPUT_DEVICE_IDS_CMD;
82  desc += ": Request the list of devices that are used as input to the requested device. Attributes: DeviceId: the id of the device to query.";
83  }
84  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, REQUEST_DEVICE_CHANNEL_IDS_CMD))
85  {
86  desc += REQUEST_DEVICE_CHANNEL_IDS_CMD;
87  desc += ": Request the list of channels for a given device. Attributes: DeviceId: the id of the device to query.";
88  }
89  return desc;
90 }
91 
92 //----------------------------------------------------------------------------
93 void vtkPlusRequestIdsCommand::PrintSelf(ostream& os, vtkIndent indent)
94 {
95  this->Superclass::PrintSelf(os, indent);
96 }
97 
98 //----------------------------------------------------------------------------
100 {
102  {
103  return PLUS_FAIL;
104  }
105  XML_READ_CSTRING_ATTRIBUTE_OPTIONAL(DeviceType, aConfig);
106  XML_READ_CSTRING_ATTRIBUTE_OPTIONAL(DeviceId, aConfig);
107  return PLUS_SUCCESS;
108 }
109 
110 //----------------------------------------------------------------------------
112 {
114  {
115  return PLUS_FAIL;
116  }
117  XML_WRITE_STRING_ATTRIBUTE_IF_NOT_EMPTY(DeviceId, aConfig);
118  XML_WRITE_STRING_ATTRIBUTE_IF_NOT_EMPTY(DeviceType, aConfig);
119  return PLUS_SUCCESS;
120 }
121 
122 //----------------------------------------------------------------------------
124 {
125  if (this->Name.empty())
126  {
127  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", "No command name specified.");
128  return PLUS_FAIL;
129  }
130 
131  vtkPlusDataCollector* dataCollector = this->GetDataCollector();
132  if (dataCollector == NULL)
133  {
134  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", "No data collector.");
135  return PLUS_FAIL;
136  }
137 
138  DeviceCollection aCollection;
139  if (dataCollector->GetDevices(aCollection) != PLUS_SUCCESS)
140  {
141  this->QueueCommandResponse(PLUS_FAIL, "Command failed, see error message.", "Unable to retrieve devices.");
142  return PLUS_FAIL;
143  }
144 
145  auto _FindDevice = [this](DeviceCollection & aCollection) -> vtkPlusDevice*
146  {
147  for (auto it = aCollection.begin(); it != aCollection.end(); ++it)
148  {
149  if (this->DeviceId == (*it)->GetDeviceId())
150  {
151  return (*it);
152  }
153  }
154  return (vtkPlusDevice*)nullptr;
155  };
156 
157  if (igsioCommon::IsEqualInsensitive(this->Name, REQUEST_CHANNEL_IDS_CMD))
158  {
159  std::string responseMessage;
160  bool addSeparator = false;
161  igtl::MessageBase::MetaDataMap keyValuePairs;
162 
163  for (DeviceCollectionConstIterator deviceIt = aCollection.begin(); deviceIt != aCollection.end(); ++deviceIt)
164  {
165  vtkPlusDevice* aDevice = *deviceIt;
166  if (aDevice->OutputChannelCount() > 0)
167  {
168  for (ChannelContainerConstIterator it = aDevice->GetOutputChannelsStart(); it != aDevice->GetOutputChannelsEnd(); ++it)
169  {
170  if (addSeparator)
171  {
172  responseMessage += ",";
173  }
174  responseMessage += (*it)->GetChannelId();
175  addSeparator = true;
176  keyValuePairs[(*it)->GetChannelId()] = std::pair<IANA_ENCODING_TYPE, std::string>(IANA_TYPE_US_ASCII, (*it)->GetChannelId());
177  }
178  }
179  }
180  std::ostringstream oss;
181  PlusIgtlClientInfo info;
182  if (this->CommandProcessor->GetPlusServer()->GetClientInfo(this->GetClientId(), info) != PLUS_SUCCESS)
183  {
184  LOG_WARNING("Unable to locate client data for client id: " << this->GetClientId());
185  }
186  if (info.GetClientHeaderVersion() <= IGTL_HEADER_VERSION_2)
187  {
188  oss << responseMessage;
189  }
190  else
191  {
192  oss << "Found: " << keyValuePairs.size() << " parameter" << (keyValuePairs.size() > 1 ? "s." : ".");
193  }
194 
195  this->QueueCommandResponse(PLUS_SUCCESS, oss.str(), "", &keyValuePairs);
196  return PLUS_SUCCESS;
197  }
198  else if (igsioCommon::IsEqualInsensitive(this->Name, REQUEST_DEVICE_IDS_CMD))
199  {
200  std::string responseMessage;
201  bool addSeparator = false;
202  igtl::MessageBase::MetaDataMap keyValuePairs;
203 
204  for (DeviceCollectionConstIterator deviceIt = aCollection.begin(); deviceIt != aCollection.end(); ++deviceIt)
205  {
206  vtkPlusDevice* aDevice = *deviceIt;
207  if (aDevice == NULL)
208  {
209  continue;
210  }
211  std::string deviceClassName;
212  if (!this->DeviceType.empty())
213  {
214  // Translate requested device ID (factory name) to c++ class name
215  vtkSmartPointer<vtkPlusDeviceFactory> factory = vtkSmartPointer<vtkPlusDeviceFactory>::New();
216  if (factory->GetDeviceClassName(this->DeviceType, deviceClassName) != PLUS_SUCCESS)
217  {
218  this->QueueCommandResponse(PLUS_FAIL, "Command failed, see error message.", "Unknown device type requested.");
219  return PLUS_FAIL;
220  }
221  }
222  if (deviceClassName.empty() || aDevice->GetClassName() == deviceClassName)
223  {
224  if (addSeparator)
225  {
226  responseMessage += ",";
227  }
228  responseMessage += aDevice->GetDeviceId();
229  addSeparator = true;
230 
231  keyValuePairs[aDevice->GetDeviceId()] = std::pair<IANA_ENCODING_TYPE, std::string>(IANA_TYPE_US_ASCII, aDevice->GetDeviceId());
232  }
233  }
234  std::ostringstream oss;
235  PlusIgtlClientInfo info;
236  if (this->CommandProcessor->GetPlusServer()->GetClientInfo(this->GetClientId(), info) != PLUS_SUCCESS)
237  {
238  LOG_WARNING("Unable to locate client data for client id: " << this->GetClientId());
239  }
240  if (info.GetClientHeaderVersion() <= IGTL_HEADER_VERSION_2)
241  {
242  oss << responseMessage;
243  }
244  else
245  {
246  oss << "Found: " << keyValuePairs.size() << " parameter" << (keyValuePairs.size() > 1 ? "s." : ".");
247  }
248  this->QueueCommandResponse(PLUS_SUCCESS, oss.str(), "", &keyValuePairs);
249  return PLUS_SUCCESS;
250  }
251  else if (igsioCommon::IsEqualInsensitive(this->Name, REQUEST_INPUT_DEVICE_IDS_CMD))
252  {
253  if (!this->DeviceId.empty())
254  {
255  this->QueueCommandResponse(PLUS_FAIL, "Command failed, see error message.", "Unknown device id requested.");
256  return PLUS_FAIL;
257  }
258 
259  std::vector<vtkPlusDevice*> list;
260  auto device = _FindDevice(aCollection);
261  if (device == nullptr)
262  {
263  this->QueueCommandResponse(PLUS_FAIL, "Command failed, see error message.", std::string("Device with id: ") + this->DeviceId + " not found.");
264  return PLUS_FAIL;
265  }
266 
267  if (device->GetInputDevicesRecursive(list) == PLUS_FAIL)
268  {
269  this->QueueCommandResponse(PLUS_FAIL, "Command failed, see error message.", "Error retrieving input devices.");
270  return PLUS_FAIL;;
271  }
272  list.insert(list.begin(), device);
273 
274  std::ostringstream oss;
275  for (auto it = list.begin(); it != list.end(); ++it)
276  {
277  oss << (*it)->GetDeviceId();
278  oss << ",";
279  }
280 
281  this->QueueCommandResponse(PLUS_SUCCESS, oss.str(), "", nullptr);
282  return PLUS_SUCCESS;
283  }
284  else if (igsioCommon::IsEqualInsensitive(this->Name, REQUEST_DEVICE_CHANNEL_IDS_CMD))
285  {
286  auto device = _FindDevice(aCollection);
287  if (device == nullptr)
288  {
289  this->QueueCommandResponse(PLUS_FAIL, "Command failed, see error message.", std::string("Device with id: ") + this->DeviceId + " not found.");
290  return PLUS_FAIL;
291  }
292 
293  std::ostringstream oss;
294  for (auto chanIter = device->GetOutputChannelsStart(); chanIter != device->GetOutputChannelsEnd(); ++chanIter)
295  {
296  oss << (*chanIter)->GetChannelId();
297  oss << ",";
298  }
299 
300  this->QueueCommandResponse(PLUS_SUCCESS, oss.str(), "", nullptr);
301  return PLUS_SUCCESS;
302  }
303 
304  this->QueueCommandResponse(PLUS_FAIL, "Command failed, see error message.", "Unknown command.");
305  return PLUS_FAIL;
306 }
PlusStatus GetDevices(DeviceCollection &OutVector) const
virtual void PrintSelf(ostream &os, vtkIndent indent)
virtual int GetClientId()
Abstract interface for tracker and video devices.
Definition: vtkPlusDevice.h:60
std::vector< vtkPlusDevice * >::const_iterator DeviceCollectionConstIterator
Definition: vtkPlusDevice.h:48
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
std::string Name
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
igsioStatus PlusStatus
Definition: PlusCommon.h:40
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
virtual std::string GetDeviceId() const
std::vector< vtkPlusDevice * > DeviceCollection
Definition: vtkPlusDevice.h:46
virtual const char * GetClassName()
virtual vtkPlusOpenIGTLinkServer * GetPlusServer()
#define PLUS_FAIL
Definition: PlusCommon.h:43
vtkPlusCommandProcessor * CommandProcessor
ChannelContainerConstIterator GetOutputChannelsEnd() const
Manages devices that record image or positional data.
virtual PlusStatus GetClientInfo(unsigned int clientId, PlusIgtlClientInfo &outClientInfo) const
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
virtual std::string GetDescription(const std::string &commandName)
ChannelContainerConstIterator GetOutputChannelsStart() const
ChannelContainer::const_iterator ChannelContainerConstIterator
Definition: vtkPlusDevice.h:35
int GetClientHeaderVersion() const
void QueueCommandResponse(PlusStatus status, const std::string &message, const std::string &error="", const igtl::MessageBase::MetaDataMap *metaData=nullptr)
virtual vtkPlusDataCollector * GetDataCollector()
vtkStandardNewMacro(vtkPlusRequestIdsCommand)
virtual void PrintSelf(ostream &os, vtkIndent indent)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
This class provides client information for vtkPlusOpenIGTLinkServer.
virtual int OutputChannelCount() const
virtual void GetCommandNames(std::list< std::string > &cmdNames)
const char ** deviceClassName
Definition: phidget22.h:1312