All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
interface.cc
Go to the documentation of this file.
1 /*
2  * This file is part of the rc_genicam_api package.
3  *
4  * Copyright (c) 2017 Roboception GmbH
5  * All rights reserved
6  *
7  * Author: Heiko Hirschmueller
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the copyright holder nor the names of its contributors
20  * may be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include "interface.h"
37 #include "device.h"
38 
39 #include "gentl_wrapper.h"
40 #include "exception.h"
41 #include "cport.h"
42 
43 #include <iostream>
44 
45 namespace rcg
46 {
47 
48 Interface::Interface(const std::shared_ptr<System> &_parent,
49  const std::shared_ptr<const GenTLWrapper> &_gentl, const char *_id)
50 {
51  parent=_parent;
52  gentl=_gentl;
53  id=_id;
54 
55  n_open=0;
56  ifh=0;
57 }
58 
60 {
61  if (n_open > 0)
62  {
63  gentl->IFClose(ifh);
64  parent->close();
65  }
66 }
67 
68 std::shared_ptr<System> Interface::getParent() const
69 {
70  return parent;
71 }
72 
73 const std::string &Interface::getID() const
74 {
75  return id;
76 }
77 
79 {
80  std::lock_guard<std::mutex> lock(mtx);
81 
82  if (n_open == 0)
83  {
84  parent->open();
85 
86  // updating before opening is apparently necessary for some TLs
87 
88  gentl->TLUpdateInterfaceList(parent->getHandle(), 0, 10);
89 
90  if (gentl->TLOpenInterface(parent->getHandle(), id.c_str(), &ifh) != GenTL::GC_ERR_SUCCESS)
91  {
92  parent->close();
93  throw GenTLException("Interface::open()", gentl);
94  }
95  }
96 
97  n_open++;
98 }
99 
101 {
102  std::lock_guard<std::mutex> lock(mtx);
103 
104  if (n_open > 0)
105  {
106  n_open--;
107 
108  if (n_open == 0)
109  {
110  gentl->IFClose(ifh);
111  ifh=0;
112 
113  nodemap=0;
114  cport=0;
115 
116  parent->close();
117  }
118  }
119 }
120 
121 namespace
122 {
123 
124 int find(const std::vector<std::shared_ptr<Device> > &list, const std::string &id)
125 {
126  for (size_t i=0; i<list.size(); i++)
127  {
128  if (list[i]->getID() == id)
129  {
130  return static_cast<int>(i);
131  }
132  }
133 
134  return -1;
135 }
136 
137 }
138 
139 std::vector<std::shared_ptr<Device> > Interface::getDevices(uint64_t timeout)
140 {
141  std::lock_guard<std::mutex> lock(mtx);
142 
143  std::vector<std::shared_ptr<Device> > ret;
144 
145  if (ifh != 0)
146  {
147  // get list of previously requested devices that are still in use
148 
149  std::vector<std::shared_ptr<Device> > current;
150 
151  for (size_t i=0; i<dlist.size(); i++)
152  {
153  std::shared_ptr<Device> p=dlist[i].lock();
154  if (p)
155  {
156  current.push_back(p);
157  }
158  }
159 
160  // update available interfaces
161 
162  GenTL::GC_ERROR err=gentl->IFUpdateDeviceList(ifh, 0, timeout);
163 
164  if (err == GenTL::GC_ERR_INVALID_HANDLE)
165  {
166  // the interface handle is invalid, try to reopen the interface
167 
168  if (gentl->TLUpdateInterfaceList(parent->getHandle(), 0, 10) != GenTL::GC_ERR_SUCCESS)
169  {
170  throw GenTLException(std::string("Interface::getDevices() (recovery 1) ")+id, gentl);
171  }
172 
173  if (gentl->TLOpenInterface(parent->getHandle(), id.c_str(), &ifh) != GenTL::GC_ERR_SUCCESS)
174  {
175  throw GenTLException(std::string("Interface::getDevices() (recovery 2) ")+id, gentl);
176  }
177 
178  // try to repeat discovery of devices
179 
180  err=gentl->IFUpdateDeviceList(ifh, 0, timeout);
181  }
182 
183  if (err != GenTL::GC_ERR_SUCCESS)
184  {
185  throw GenTLException(std::string("Interface::getDevices() (1) ")+id+" "+std::to_string(err), gentl);
186  }
187 
188  // create list of devices, using either existing devices or
189  // instantiating new ones
190 
191  uint32_t n=0;
192  if (gentl->IFGetNumDevices(ifh, &n) != GenTL::GC_ERR_SUCCESS)
193  {
194  throw GenTLException(std::string("Interface::getDevices() (2) ")+id, gentl);
195  }
196 
197  for (uint32_t i=0; i<n; i++)
198  {
199  char tmp[256]="";
200  size_t size=sizeof(tmp);
201 
202  if (gentl->IFGetDeviceID(ifh, i, tmp, &size) != GenTL::GC_ERR_SUCCESS)
203  {
204  throw GenTLException(std::string("Interface::getDevices() (3) ")+id, gentl);
205  }
206 
207  int k=find(current, tmp);
208 
209  if (k >= 0)
210  {
211  ret.push_back(current[static_cast<size_t>(k)]);
212  }
213  else
214  {
215  ret.push_back(std::shared_ptr<Device>(new Device(shared_from_this(), gentl, tmp)));
216  }
217  }
218 
219  // update internal list of devices for reusage on next call
220 
221  dlist.clear();
222  for (size_t i=0; i<ret.size(); i++)
223  {
224  dlist.push_back(ret[i]);
225  }
226  }
227 
228  return ret;
229 }
230 
231 std::vector<std::shared_ptr<Device> > Interface::getDevices()
232 {
233  return getDevices(1000);
234 }
235 
236 std::shared_ptr<Device> Interface::getDevice(const char *devid, uint64_t timeout)
237 {
238  // get list of all devices
239 
240  std::vector<std::shared_ptr<Device> > list=getDevices(timeout);
241 
242  // find requested device by ID or user defined name
243 
244  std::shared_ptr<Device> ret;
245 
246  for (size_t i=0; i<list.size(); i++)
247  {
248  std::shared_ptr<Device> p=list[i];
249 
250  if (p && (p->getID() == devid || p->getDisplayName() == devid ||
251  p->getSerialNumber() == devid))
252  {
253  if (ret)
254  {
255  std::cerr << "There is more than one device with ID, serial number or user defined name: "
256  << devid << std::endl;
257  ret=0;
258  break;
259  }
260 
261  ret=p;
262  }
263  }
264 
265  if (!ret && ifh != 0)
266  {
267  // try to open the device in a last attempt to check if the producer is
268  // able to find it
269 
270  GenTL::DEV_HANDLE dev=0;
271 
272  GenTL::GC_ERROR err=gentl->IFOpenDevice(ifh, devid, GenTL::DEVICE_ACCESS_READONLY, &dev);
273 
274  if (err == GenTL::GC_ERR_SUCCESS)
275  {
276  gentl->DevClose(dev);
277  }
278 
281  {
282  ret=std::shared_ptr<Device>(new Device(shared_from_this(), gentl, devid));
283  }
284  }
285 
286  return ret;
287 }
288 
289 std::shared_ptr<Device> Interface::getDevice(const char *devid)
290 {
291  return getDevice(devid, 1000);
292 }
293 
294 namespace
295 {
296 
297 std::string cIFGetInfo(const Interface *obj,
298  const std::shared_ptr<const GenTLWrapper> &gentl,
300 {
301  std::string ret;
302 
304  char tmp[1024]="";
305  size_t tmp_size=sizeof(tmp);
307 
308  if (obj->getHandle() != 0)
309  {
310  err=gentl->IFGetInfo(obj->getHandle(), info, &type, tmp, &tmp_size);
311  }
312  else if (obj->getParent()->getHandle() != 0)
313  {
314  err=gentl->TLGetInterfaceInfo(obj->getParent()->getHandle(), obj->getID().c_str(), info,
315  &type, tmp, &tmp_size);
316  }
317 
319  {
320  for (size_t i=0; i<tmp_size && tmp[i] != '\0'; i++)
321  {
322  ret.push_back(tmp[i]);
323  }
324  }
325 
326  return ret;
327 }
328 
329 }
330 
332 {
333  std::lock_guard<std::mutex> lock(mtx);
334  return cIFGetInfo(this, gentl, GenTL::INTERFACE_INFO_DISPLAYNAME);
335 }
336 
337 std::string Interface::getTLType()
338 {
339  std::lock_guard<std::mutex> lock(mtx);
340  return cIFGetInfo(this, gentl, GenTL::INTERFACE_INFO_TLTYPE);
341 }
342 
343 std::shared_ptr<GenApi::CNodeMapRef> Interface::getNodeMap()
344 {
345  std::lock_guard<std::mutex> lock(mtx);
346  if (ifh != 0 && !nodemap)
347  {
348  cport=std::shared_ptr<CPort>(new CPort(gentl, &ifh));
350  }
351 
352  return nodemap;
353 }
354 
355 void *Interface::getHandle() const
356 {
357  return ifh;
358 }
359 
360 }
INFO_DATATYPE
int32_t INFO_DATATYPE
Definition: GenTL_v1_6.h:261
INFO_DATATYPE_STRING
@ INFO_DATATYPE_STRING
Definition: GenTL_v1_6.h:244
rcg::Interface::getDevice
std::shared_ptr< Device > getDevice(const char *devid, uint64_t timeout)
Returns a device with the given device id.
Definition: interface.cc:236
DEV_HANDLE
void * DEV_HANDLE
Definition: GenTL_v1_6.h:224
rcg::Interface::gentl
std::shared_ptr< const GenTLWrapper > gentl
Definition: interface.h:172
rcg::Interface::parent
std::shared_ptr< System > parent
Definition: interface.h:171
rcg::Interface::getParent
std::shared_ptr< System > getParent() const
Returns the pointer to the parent system object.
Definition: interface.cc:68
rcg::Interface::open
void open()
Opens the interface for working with it.
Definition: interface.cc:78
GC_ERR_INVALID_HANDLE
@ GC_ERR_INVALID_HANDLE
Definition: GenTL_v1_6.h:164
GC_ERROR
int32_t GC_ERROR
Definition: GenTL_v1_6.h:185
rcg
Definition: buffer.cc:47
device.h
rcg::Interface::close
void close()
Closes the interface.
Definition: interface.cc:100
GC_ERR_ERROR
@ GC_ERR_ERROR
Definition: GenTL_v1_6.h:159
rcg::Interface::nodemap
std::shared_ptr< GenApi::CNodeMapRef > nodemap
Definition: interface.h:181
rcg::CPort
This is the port definition that connects GenAPI to GenTL.
Definition: cport.h:52
rcg::Interface::id
std::string id
Definition: interface.h:173
GC_ERR_SUCCESS
@ GC_ERR_SUCCESS
Definition: GenTL_v1_6.h:158
rcg::Device
The device class encapsulates a Genicam device.
Definition: device.h:56
rcg::Interface::getHandle
void * getHandle() const
Get internal interace handle.
Definition: interface.cc:355
rcg::allocNodeMap
std::shared_ptr< GenApi::CNodeMapRef > allocNodeMap(std::shared_ptr< const GenTLWrapper > gentl, void *port, CPort *cport, const char *xml)
Convenience function that returns a GenICam node map from the given port.
Definition: cport.cc:156
rcg::Interface::~Interface
~Interface()
Definition: interface.cc:59
interface.h
rcg::Interface
The interface class encapsulates a Genicam interface.
Definition: interface.h:54
rcg::Interface::getDisplayName
std::string getDisplayName()
Returns the display name of the interface.
Definition: interface.cc:331
rcg::Interface::getID
const std::string & getID() const
Get the internal ID of this interface.
Definition: interface.cc:73
INTERFACE_INFO_DISPLAYNAME
@ INTERFACE_INFO_DISPLAYNAME
Definition: GenTL_v1_6.h:293
rcg::Interface::n_open
int n_open
Definition: interface.h:177
rcg::Interface::ifh
void * ifh
Definition: interface.h:178
rcg::Interface::mtx
std::mutex mtx
Definition: interface.h:175
rcg::Interface::dlist
std::vector< std::weak_ptr< Device > > dlist
Definition: interface.h:183
rcg::Interface::cport
std::shared_ptr< CPort > cport
Definition: interface.h:180
GC_ERR_RESOURCE_IN_USE
@ GC_ERR_RESOURCE_IN_USE
Definition: GenTL_v1_6.h:162
rcg::Interface::getDevices
std::vector< std::shared_ptr< Device > > getDevices()
Definition: interface.cc:231
INFO_DATATYPE_UNKNOWN
@ INFO_DATATYPE_UNKNOWN
Definition: GenTL_v1_6.h:243
DEVICE_ACCESS_READONLY
@ DEVICE_ACCESS_READONLY
Definition: GenTL_v1_6.h:304
rcg::Interface::getNodeMap
std::shared_ptr< GenApi::CNodeMapRef > getNodeMap()
Returns the node map of this object.
Definition: interface.cc:343
GC_ERR_ACCESS_DENIED
@ GC_ERR_ACCESS_DENIED
Definition: GenTL_v1_6.h:163
cport.h
rcg::Interface::Interface
Interface(const std::shared_ptr< System > &parent, const std::shared_ptr< const GenTLWrapper > &gentl, const char *id)
Constructs an interface class.
Definition: interface.cc:48
INTERFACE_INFO_TLTYPE
@ INTERFACE_INFO_TLTYPE
Definition: GenTL_v1_6.h:294
exception.h
rcg::Interface::getTLType
std::string getTLType()
Returns the transport layer type of the interface.
Definition: interface.cc:337
INTERFACE_INFO_CMD
int32_t INTERFACE_INFO_CMD
Definition: GenTL_v1_6.h:297
gentl_wrapper.h
rcg::GenTLException
Definition: exception.h:47


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Wed Dec 4 2024 03:10:11