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 
109  if (n_open == 0)
110  {
111  gentl->IFClose(ifh);
112  ifh=0;
113 
114  nodemap=0;
115  cport=0;
116 
117  parent->close();
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()
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, 1000);
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, 1000);
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 interfaces, using either existing interfaces 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::shared_ptr<Device> Interface::getDevice(const char *devid)
232 {
233  // get list of all devices
234 
235  std::vector<std::shared_ptr<Device> > list=getDevices();
236 
237  // find requested device by ID or user defined name
238 
239  std::shared_ptr<Device> ret;
240 
241  for (size_t i=0; i<list.size(); i++)
242  {
243  std::shared_ptr<Device> p=list[i];
244 
245  if (p && (p->getID() == devid || p->getDisplayName() == devid ||
246  p->getSerialNumber() == devid))
247  {
248  if (ret)
249  {
250  std::cerr << "There is more than one device with ID, serial number or user defined name: "
251  << devid << std::endl;
252  ret=0;
253  break;
254  }
255 
256  ret=p;
257  }
258  }
259 
260  if (!ret && ifh != 0)
261  {
262  // try to open the device in a last attempt to check if the producer is
263  // able to find it
264 
265  GenTL::DEV_HANDLE dev=0;
266 
267  GenTL::GC_ERROR err=gentl->IFOpenDevice(ifh, devid, GenTL::DEVICE_ACCESS_READONLY, &dev);
268 
269  if (err == GenTL::GC_ERR_SUCCESS)
270  {
271  gentl->DevClose(dev);
272  }
273 
276  {
277  ret=std::shared_ptr<Device>(new Device(shared_from_this(), gentl, devid));
278  }
279  }
280 
281  return ret;
282 }
283 
284 namespace
285 {
286 
287 std::string cIFGetInfo(const Interface *obj,
288  const std::shared_ptr<const GenTLWrapper> &gentl,
290 {
291  std::string ret;
292 
294  char tmp[1024]="";
295  size_t tmp_size=sizeof(tmp);
297 
298  if (obj->getHandle() != 0)
299  {
300  err=gentl->IFGetInfo(obj->getHandle(), info, &type, tmp, &tmp_size);
301  }
302  else if (obj->getParent()->getHandle() != 0)
303  {
304  err=gentl->TLGetInterfaceInfo(obj->getParent()->getHandle(), obj->getID().c_str(), info,
305  &type, tmp, &tmp_size);
306  }
307 
309  {
310  for (size_t i=0; i<tmp_size && tmp[i] != '\0'; i++)
311  {
312  ret.push_back(tmp[i]);
313  }
314  }
315 
316  return ret;
317 }
318 
319 }
320 
322 {
323  std::lock_guard<std::mutex> lock(mtx);
324  return cIFGetInfo(this, gentl, GenTL::INTERFACE_INFO_DISPLAYNAME);
325 }
326 
327 std::string Interface::getTLType()
328 {
329  std::lock_guard<std::mutex> lock(mtx);
330  return cIFGetInfo(this, gentl, GenTL::INTERFACE_INFO_TLTYPE);
331 }
332 
333 std::shared_ptr<GenApi::CNodeMapRef> Interface::getNodeMap()
334 {
335  std::lock_guard<std::mutex> lock(mtx);
336  if (ifh != 0 && !nodemap)
337  {
338  cport=std::shared_ptr<CPort>(new CPort(gentl, &ifh));
340  }
341 
342  return nodemap;
343 }
344 
345 void *Interface::getHandle() const
346 {
347  return ifh;
348 }
349 
350 }
std::vector< std::weak_ptr< Device > > dlist
Definition: interface.h:176
std::string getDisplayName()
Returns the display name of the interface.
Definition: interface.cc:321
int32_t INTERFACE_INFO_CMD
Definition: GenTL_v1_5.h:295
std::vector< std::shared_ptr< Device > > getDevices()
Returns the currently available devices on this interface.
Definition: interface.cc:139
std::shared_ptr< CPort > cport
Definition: interface.h:173
This is the port definition that connects GenAPI to GenTL.
Definition: cport.h:52
const std::string & getID() const
Get the internal ID of this interface.
Definition: interface.cc:73
void * getHandle() const
Get internal interace handle.
Definition: interface.cc:345
std::mutex mtx
Definition: interface.h:168
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
std::string getTLType()
Returns the transport layer type of the interface.
Definition: interface.cc:327
int32_t GC_ERROR
Definition: GenTL_v1_5.h:181
std::shared_ptr< GenApi::CNodeMapRef > getNodeMap()
Returns the node map of this object.
Definition: interface.cc:333
std::shared_ptr< System > parent
Definition: interface.h:164
std::shared_ptr< Device > getDevice(const char *devid)
Returns a device with the given device id.
Definition: interface.cc:231
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:133
void close()
Closes the interface.
Definition: interface.cc:100
std::shared_ptr< GenApi::CNodeMapRef > nodemap
Definition: interface.h:174
void open()
Opens the interface for working with it.
Definition: interface.cc:78
std::shared_ptr< const GenTLWrapper > gentl
Definition: interface.h:165
Definition: buffer.cc:47
void * DEV_HANDLE
Definition: GenTL_v1_5.h:220
std::shared_ptr< System > getParent() const
Returns the pointer to the parent system object.
Definition: interface.cc:68
int32_t INFO_DATATYPE
Definition: GenTL_v1_5.h:258
The device class encapsulates a Genicam device.
Definition: device.h:54
std::string id
Definition: interface.h:166
The interface class encapsulates a Genicam interface.
Definition: interface.h:54


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Wed Mar 17 2021 02:48:40