Medical Imaging Interaction Toolkit  2018.4.99-b585543d
Medical Imaging Interaction Toolkit
mitkUSTelemedDevice.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkUSTelemedDevice.h"
14 
15 #include "mitkUSTelemedSDKHeader.h"
16 
17 mitk::USTelemedDevice::USTelemedDevice(std::string manufacturer, std::string model)
18 : mitk::USDevice(manufacturer, model),
19 m_ControlsProbes(mitk::USTelemedProbesControls::New(this)),
20 m_ControlsBMode(mitk::USTelemedBModeControls::New(this)),
21 m_ControlsDoppler(mitk::USTelemedDopplerControls::New(this)),
22 m_ImageSource(mitk::USTelemedImageSource::New()), m_UsgMainInterface(0),
23 m_Probe(0), m_UsgDataView(0), m_ProbesCollection(0)
24 {
25  SetNumberOfOutputs(1);
26  SetNthOutput(0, this->MakeOutput(0));
27 }
28 
30 {
31 }
32 
34 {
35  return "org.mitk.modules.us.USTelemedDevice";
36 }
37 
38 mitk::USControlInterfaceBMode::Pointer mitk::USTelemedDevice::GetControlInterfaceBMode()
39 {
40  return m_ControlsBMode.GetPointer();
41 }
42 
43 mitk::USControlInterfaceProbes::Pointer mitk::USTelemedDevice::GetControlInterfaceProbes()
44 {
45  return m_ControlsProbes.GetPointer();
46 };
47 
48 mitk::USControlInterfaceDoppler::Pointer mitk::USTelemedDevice::GetControlInterfaceDoppler()
49 {
50  return m_ControlsDoppler.GetPointer();
51 };
52 
54 {
55  CoInitialize(nullptr); // initialize COM library
56 
57  return true;
58 }
59 
61 {
62  // create main Telemed API COM library object
63  HRESULT hr;
64 
65  hr = CoCreateInstance(Usgfw2Lib::CLSID_Usgfw2, nullptr, CLSCTX_INPROC_SERVER, Usgfw2Lib::IID_IUsgfw2,(LPVOID*) &m_UsgMainInterface);
66  if (FAILED(hr))
67  {
68  SAFE_RELEASE(m_UsgMainInterface);
69  MITK_ERROR("USDevice")("USTelemedDevice") << "Error at connecting to ultrasound device (" << hr << ").";
70  return false;
71  }
72 
74 
75  return true;
76 }
77 
79 {
80  // control objects cannot be active anymore
81  m_ControlsBMode->SetIsActive(false);
82  m_ControlsDoppler->SetIsActive(false);
83  m_ControlsProbes->SetIsActive(false);
84 
86 
87  return true;
88 }
89 
91 {
92  // probe controls are available now
93  m_ControlsProbes->SetIsActive(true);
94 
95  if ( m_ControlsProbes->GetProbesCount() < 1 )
96  {
97  MITK_WARN("USDevice")("USTelemedDevice") << "No probe found.";
98  return false;
99  }
100 
101  // select first probe as a default
102  m_ControlsProbes->SelectProbe(0);
103 
104  // set scan mode b as default for activation -
105  // control interfaces can override this later
106  HRESULT hr = m_UsgDataView->put_ScanMode(Usgfw2Lib::SCAN_MODE_B);
107  if (FAILED(hr))
108  {
109  MITK_ERROR("USDevice")("USTelemedDevice") << "Could not set scan mode b (" << hr << ").";
110  return false;
111  }
112 
113  // start ultrasound scanning with selected scan mode
114  hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN);
115  if (FAILED(hr))
116  {
117  MITK_ERROR("USDevice")("USTelemedDevice") << "Start scanning failed (" << hr << ").";
118  return false;
119  }
120 
121  m_ControlsBMode->ReinitializeControls();
122 
123  return true;
124 }
125 
127 {
128  this->StopScanning();
129  return true;
130 }
131 
133 {
134  if ( freeze )
135  {
136  m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_FREEZE);
137  }
138  else
139  {
140  m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN);
141  }
142 }
143 
144 mitk::USImageSource::Pointer mitk::USTelemedDevice::GetUSImageSource()
145 {
146  return m_ImageSource.GetPointer();
147 }
148 
150 {
151  if (m_UsgDataView) { this->StopScanning(); };
152 
157 }
158 
160 {
161  if ( ! m_UsgDataView )
162  {
163  MITK_WARN("USDevice")("USTelemedDevice") << "Cannot stop scanning as Telemed Data View is null.";
164  return;
165  }
166 
167  HRESULT hr;
168  hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_STOP);
169 
170  if (FAILED(hr))
171  {
172  MITK_ERROR("USDevice")("USTelemedDevice") << "Stop scanning failed (" << hr << ").";
173  mitkThrow() << "Stop scanning failed (" << hr << ").";
174  }
175 }
176 
178 {
179  return m_UsgMainInterface;
180 }
181 
182 void mitk::USTelemedDevice::SetActiveDataView(Usgfw2Lib::IUsgDataView* usgDataView)
183 {
184  // do nothing if the usg data view hasn't changed
185  if ( m_UsgDataView != usgDataView )
186  {
187  // scan converter plugin is connected to IUsgDataView -> a new plugin
188  // must be created when changing IUsgDataView
189  m_UsgDataView = usgDataView;
190  if ( ! m_ImageSource->CreateAndConnectConverterPlugin(m_UsgDataView, Usgfw2Lib::SCAN_MODE_B)) { return; }
191 
192  // b mode control object must know about active data view
193  m_ControlsBMode->SetUsgDataView(m_UsgDataView);
194  }
195 }
196 
198 {
199  IConnectionPointContainer* cpc = nullptr;
200  HRESULT hr = m_UsgMainInterface->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc);
201  if (hr != S_OK)
202  cpc = nullptr;
203 
204  if (cpc != nullptr)
205  hr = cpc->FindConnectionPoint(Usgfw2Lib::IID_IUsgDeviceChangeSink, &m_UsgDeviceChangeCpnt);
206 
207  if (hr != S_OK)
208  {
209  m_UsgDeviceChangeCpnt = nullptr;
211  }
212  SAFE_RELEASE(cpc);
213 
214  if (m_UsgDeviceChangeCpnt != nullptr)
215  hr = m_UsgDeviceChangeCpnt->Advise((IUnknown*)((Usgfw2Lib::IUsgDeviceChangeSink*)this), &m_UsgDeviceChangeCpntCookie);
216 }
217 
218 // --- Methods for Telemed API Interfaces
219 
220 HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerArrive(IUnknown *pUsgBeamformer, ULONG *reserved)
221 {
222  this->Connect();
223 
224  return S_OK;
225 }
226 
227 HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerRemove(IUnknown *pUsgBeamformer, ULONG *reserved)
228 {
229  if ( this->GetIsActive() ) { this->Deactivate(); }
230 
231  this->Disconnect();
232 
233  return S_OK;
234 }
235 
236 HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeArrive(IUnknown*, ULONG* probeIndex)
237 {
238  m_ControlsProbes->ProbeAdded(static_cast<unsigned int>(*probeIndex));
239 
240  this->Activate();
241 
242  return S_OK;
243 };
244 
245 HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeRemove(IUnknown*, ULONG* probeIndex)
246 {
247  m_ControlsProbes->ProbeRemoved(static_cast<unsigned int>(*probeIndex));
248 
249  if ( this->GetIsActive() ) { this->Deactivate(); }
250 
251  return S_OK;
252 };
253 
254 STDMETHODIMP_(ULONG) mitk::USTelemedDevice::AddRef()
255 {
256  ++m_RefCount;
257  return m_RefCount;
258 }
259 
260 STDMETHODIMP_(ULONG) mitk::USTelemedDevice::Release()
261 {
262  --m_RefCount;
263  return m_RefCount;
264 }
265 
266 STDMETHODIMP mitk::USTelemedDevice::QueryInterface(REFIID riid, void** ppv)
267 {
268  if (riid == IID_IUnknown || riid == Usgfw2Lib::IID_IUsgDeviceChangeSink)
269  {
270  *ppv = (IUsgDeviceChangeSink*)this;
271  return S_OK;
272  }
273  if (riid == IID_IDispatch)
274  {
275  *ppv = (IDispatch*)this;
276  return S_OK;
277  }
278  return E_NOINTERFACE;
279 }
280 
282 {
283  if (pctinfo == nullptr) return E_INVALIDARG;
284  *pctinfo = 0;
285  return S_OK;
286 }
287 
288 HRESULT mitk::USTelemedDevice::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
289 {
290  if (pptinfo == nullptr) return E_INVALIDARG;
291  *pptinfo = nullptr;
292  if(itinfo != 0) return DISP_E_BADINDEX;
293  return S_OK;
294 }
295 
296 HRESULT mitk::USTelemedDevice::GetIDsOfNames(const IID &riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
297 {
298  // this is not used - must use the same fixed dispid's from Usgfw2 idl file
299  return S_OK;
300 }
301 
302 HRESULT mitk::USTelemedDevice::Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
303 {
304  if ( (dispIdMember >= 1) && (dispIdMember <= 6) )
305  {
306  if (pDispParams->cArgs != 2) // we need 2 arguments
307  return S_OK;
308 
309  IUnknown *unkn = nullptr;
310  ULONG *res = nullptr;
311 
312  VARIANTARG* p1;
313  VARIANTARG* p;
314  p1 = pDispParams->rgvarg;
315 
316  p = p1;
317  if (p->vt == (VT_BYREF|VT_UI4))
318  res = p->pulVal;
319  p1++;
320 
321  p = p1;
322  if (p->vt == VT_UNKNOWN)
323  unkn = (IUnknown*)(p->punkVal);
324 
325  if (dispIdMember == 1)
326  OnProbeArrive(unkn, res);
327  else if (dispIdMember == 2)
328  OnBeamformerArrive(unkn, res);
329  else if (dispIdMember == 3)
330  OnProbeRemove(unkn, res);
331  else if (dispIdMember == 4)
332  OnBeamformerRemove(unkn, res);
333  else if (dispIdMember == 5)
334  OnProbeStateChanged(unkn, res);
335  else if (dispIdMember == 6)
336  OnBeamformerStateChanged(unkn, res);
337  }
338 
339  return S_OK;
340 }
virtual bool OnConnection()
Is called during the connection process. Connect to the Telemed API and try to get available probes f...
Usgfw2Lib::IUsgfw2 * m_UsgMainInterface
bool Activate()
Activates this device. After the activation process, the device will start to produce images...
A device holds information about it&#39;s model, make and the connected probes. It is the common super cl...
Definition: mitkUSDevice.h:73
itk::DataObject::Pointer MakeOutput(DataObjectPointerArraySizeType idx) override
Make a DataObject of the correct type to used as the specified output.
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
#define MITK_ERROR
Definition: mitkLogMacros.h:20
Usgfw2Lib::IUsgDataView * m_UsgDataView
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(const IID &riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid)
DataCollection - Class to facilitate loading/accessing structured data.
Usgfw2Lib::IProbe * m_Probe
bool Connect()
Connects this device. A connected device is ready to deliver images (i.e. be Activated). A Connected Device can be active. A disconnected Device cannot be active. Internally calls onConnect and then registers the device with the service. A device usually should override the OnConnection() method, but never the Connect() method, since this will possibly exclude the device from normal service management. The exact flow of events is: 0. Check if the device is already connected. If yes, return true anyway, but don&#39;t do anything.
Implementation of mitk::USControlInterfaceProbes for Telemed ultrasound devices. See documentation of...
USTelemedDopplerControls::Pointer m_ControlsDoppler
USTelemedImageSource::Pointer m_ImageSource
virtual HRESULT __stdcall raw_OnBeamformerRemove(IUnknown *pUsgBeamformer, ULONG *reserved)
Usgfw2Lib::IUsgfw2 * GetUsgMainInterface()
Getter for main Telemed API object. This method is for being called by Telemed control interfaces...
Implementation of mitk::USImageSource for Telemed API devices. The method mitk::USImageSource::GetNex...
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
#define MITK_WARN
Definition: mitkLogMacros.h:19
virtual USControlInterfaceProbes::Pointer GetControlInterfaceProbes()
Default getter for the probes control interface. Has to be implemented in a subclass if a probes cont...
virtual HRESULT __stdcall raw_OnProbeRemove(IUnknown *pUsgProbe, ULONG *reserved)
#define mitkThrow()
virtual bool OnDeactivation()
Is called during the deactivation process. After a call to this method the device is connected...
USTelemedDevice(std::string manufacturer, std::string model)
virtual std::string GetDeviceClass()
Returns the class of the device.
USTelemedProbesControls::Pointer m_ControlsProbes
virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
#define SAFE_RELEASE(x)
STDMETHODIMP_(ULONG) AddRef()
virtual HRESULT __stdcall raw_OnProbeArrive(IUnknown *pUsgProbe, ULONG *reserved)
USImageSource::Pointer GetUSImageSource()
void SetActiveDataView(Usgfw2Lib::IUsgDataView *)
Changes active IUsgDataView of the device. This method is for being called by Telemed control interfa...
virtual USControlInterfaceDoppler::Pointer GetControlInterfaceDoppler()
Default getter for the doppler control interface. Has to be implemented in a subclass if a doppler co...
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo)
virtual bool OnActivation()
Is called during the activation process. After this method is finished, the device is generating imag...
void Deactivate()
Deactivates this device. After the deactivation process, the device will no longer produce images...
virtual void OnFreeze(bool freeze)
Changes scan state of the device if freeze is toggeled in mitk::USDevice.
virtual bool OnDisconnection()
Is called during the disconnection process. Deactivate and remove all Telemed API controls...
Implementation of mitk::USControlInterfaceBMode for Telemed ultrasound devices. See documentation of ...
bool GetIsActive()
True, if the device is currently generating image data, false otherwise.
bool Disconnect()
Works analogously to mitk::USDevice::Connect(). Don&#39;t override this Method, but onDisconnection inste...
virtual bool OnInitialization()
Is called during the initialization process. There is nothing done on the initialization of a mik::US...
IConnectionPoint * m_UsgDeviceChangeCpnt
void StopScanning()
Stop ultrasound scanning by Telemed API call.
USTelemedBModeControls::Pointer m_ControlsBMode
virtual USControlInterfaceBMode::Pointer GetControlInterfaceBMode()
Default getter for the b mode control interface. Has to be implemented in a subclass if a b mode cont...
virtual HRESULT __stdcall raw_OnBeamformerArrive(IUnknown *pUsgBeamformer, ULONG *reserved)
Usgfw2Lib::IUsgCollection * m_ProbesCollection
Implementation of mitk::USControlInterfaceDoppler for Telemed ultrasound devices. See documentation o...