interface.cc
Go to the documentation of this file.
00001 /*
00002  * This file is part of the rc_genicam_api package.
00003  *
00004  * Copyright (c) 2017 Roboception GmbH
00005  * All rights reserved
00006  *
00007  * Author: Heiko Hirschmueller
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright notice,
00013  * this list of conditions and the following disclaimer.
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  * this list of conditions and the following disclaimer in the documentation
00017  * and/or other materials provided with the distribution.
00018  *
00019  * 3. Neither the name of the copyright holder nor the names of its contributors
00020  * may be used to endorse or promote products derived from this software without
00021  * specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  * POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 #include "interface.h"
00037 #include "device.h"
00038 
00039 #include "gentl_wrapper.h"
00040 #include "exception.h"
00041 #include "cport.h"
00042 
00043 #include <iostream>
00044 
00045 namespace rcg
00046 {
00047 
00048 Interface::Interface(const std::shared_ptr<System> &_parent,
00049                      const std::shared_ptr<const GenTLWrapper> &_gentl, const char *_id)
00050 {
00051   parent=_parent;
00052   gentl=_gentl;
00053   id=_id;
00054 
00055   n_open=0;
00056   ifh=0;
00057 }
00058 
00059 Interface::~Interface()
00060 {
00061   if (n_open > 0)
00062   {
00063     gentl->IFClose(ifh);
00064     parent->close();
00065   }
00066 }
00067 
00068 std::shared_ptr<System> Interface::getParent() const
00069 {
00070   return parent;
00071 }
00072 
00073 const std::string &Interface::getID() const
00074 {
00075   return id;
00076 }
00077 
00078 void Interface::open()
00079 {
00080   std::lock_guard<std::mutex> lock(mtx);
00081 
00082   if (n_open == 0)
00083   {
00084     parent->open();
00085 
00086     // updating before opening is apparently necessary for some TLs
00087 
00088     gentl->TLUpdateInterfaceList(parent->getHandle(), 0, 10);
00089 
00090     if (gentl->TLOpenInterface(parent->getHandle(), id.c_str(), &ifh) != GenTL::GC_ERR_SUCCESS)
00091     {
00092       parent->close();
00093       throw GenTLException("Interface::open()", gentl);
00094     }
00095   }
00096 
00097   n_open++;
00098 }
00099 
00100 void Interface::close()
00101 {
00102   std::lock_guard<std::mutex> lock(mtx);
00103 
00104   if (n_open > 0)
00105   {
00106     n_open--;
00107   }
00108 
00109   if (n_open == 0)
00110   {
00111     gentl->IFClose(ifh);
00112     ifh=0;
00113 
00114     nodemap=0;
00115     cport=0;
00116 
00117     parent->close();
00118   }
00119 }
00120 
00121 namespace
00122 {
00123 
00124 int find(const std::vector<std::shared_ptr<Device> > &list, const std::string &id)
00125 {
00126   for (size_t i=0; i<list.size(); i++)
00127   {
00128     if (list[i]->getID() == id)
00129     {
00130       return static_cast<int>(i);
00131     }
00132   }
00133 
00134   return -1;
00135 }
00136 
00137 }
00138 
00139 std::vector<std::shared_ptr<Device> > Interface::getDevices()
00140 {
00141   std::lock_guard<std::mutex> lock(mtx);
00142 
00143   std::vector<std::shared_ptr<Device> > ret;
00144 
00145   if (ifh != 0)
00146   {
00147     // get list of previously requested devices that are still in use
00148 
00149     std::vector<std::shared_ptr<Device> > current;
00150 
00151     for (size_t i=0; i<dlist.size(); i++)
00152     {
00153       std::shared_ptr<Device> p=dlist[i].lock();
00154       if (p)
00155       {
00156         current.push_back(p);
00157       }
00158     }
00159 
00160     // update available interfaces
00161 
00162     if (gentl->IFUpdateDeviceList(ifh, 0, 10) != GenTL::GC_ERR_SUCCESS)
00163     {
00164       throw GenTLException("Interface::getDevices()", gentl);
00165     }
00166 
00167     // create list of interfaces, using either existing interfaces or
00168     // instantiating new ones
00169 
00170     uint32_t n=0;
00171     if (gentl->IFGetNumDevices(ifh, &n) != GenTL::GC_ERR_SUCCESS)
00172     {
00173       throw GenTLException("Interface::getDevices()", gentl);
00174     }
00175 
00176     for (uint32_t i=0; i<n; i++)
00177     {
00178       char tmp[256]="";
00179       size_t size=sizeof(tmp);
00180 
00181       if (gentl->IFGetDeviceID(ifh, i, tmp, &size) != GenTL::GC_ERR_SUCCESS)
00182       {
00183         throw GenTLException("Interface::getDevices()", gentl);
00184       }
00185 
00186       int k=find(current, tmp);
00187 
00188       if (k >= 0)
00189       {
00190         ret.push_back(current[static_cast<size_t>(k)]);
00191       }
00192       else
00193       {
00194         ret.push_back(std::shared_ptr<Device>(new Device(shared_from_this(), gentl, tmp)));
00195       }
00196     }
00197 
00198     // update internal list of devices for reusage on next call
00199 
00200     dlist.clear();
00201     for (size_t i=0; i<ret.size(); i++)
00202     {
00203       dlist.push_back(ret[i]);
00204     }
00205   }
00206 
00207   return ret;
00208 }
00209 
00210 std::shared_ptr<Device> Interface::getDevice(const char *devid)
00211 {
00212   // get list of all devices
00213 
00214   std::vector<std::shared_ptr<Device> > list=getDevices();
00215 
00216   // find requested device by ID or user defined name
00217 
00218   std::shared_ptr<Device> ret;
00219 
00220   for (size_t i=0; i<list.size(); i++)
00221   {
00222     std::shared_ptr<Device> p=list[i];
00223 
00224     if (p && (p->getID() == devid || p->getDisplayName() == devid ||
00225               p->getSerialNumber() == devid))
00226     {
00227       if (ret)
00228       {
00229         std::cerr << "There is more than one device with ID, serial number or user defined name: "
00230                   << devid << std::endl;
00231         ret=0;
00232         break;
00233       }
00234 
00235       ret=p;
00236     }
00237   }
00238 
00239   return ret;
00240 }
00241 
00242 namespace
00243 {
00244 
00245 std::string cIFGetInfo(const Interface *obj,
00246                        const std::shared_ptr<const GenTLWrapper> &gentl,
00247                        GenTL::INTERFACE_INFO_CMD info)
00248 {
00249   std::string ret;
00250 
00251   GenTL::INFO_DATATYPE type=GenTL::INFO_DATATYPE_UNKNOWN;
00252   char tmp[1024]="";
00253   size_t tmp_size=sizeof(tmp);
00254   GenTL::GC_ERROR err=GenTL::GC_ERR_ERROR;
00255 
00256   if (obj->getHandle() != 0)
00257   {
00258     err=gentl->IFGetInfo(obj->getHandle(), info, &type, tmp, &tmp_size);
00259   }
00260   else if (obj->getParent()->getHandle() != 0)
00261   {
00262     err=gentl->TLGetInterfaceInfo(obj->getParent()->getHandle(), obj->getID().c_str(), info,
00263                                   &type, tmp, &tmp_size);
00264   }
00265 
00266   if (err == GenTL::GC_ERR_SUCCESS && type == GenTL::INFO_DATATYPE_STRING)
00267   {
00268     for (size_t i=0; i<tmp_size && tmp[i] != '\0'; i++)
00269     {
00270       ret.push_back(tmp[i]);
00271     }
00272   }
00273 
00274   return ret;
00275 }
00276 
00277 }
00278 
00279 std::string Interface::getDisplayName()
00280 {
00281   std::lock_guard<std::mutex> lock(mtx);
00282   return cIFGetInfo(this, gentl, GenTL::INTERFACE_INFO_DISPLAYNAME);
00283 }
00284 
00285 std::string Interface::getTLType()
00286 {
00287   std::lock_guard<std::mutex> lock(mtx);
00288   return cIFGetInfo(this, gentl, GenTL::INTERFACE_INFO_TLTYPE);
00289 }
00290 
00291 std::shared_ptr<GenApi::CNodeMapRef> Interface::getNodeMap()
00292 {
00293   std::lock_guard<std::mutex> lock(mtx);
00294   if (ifh != 0 && !nodemap)
00295   {
00296     cport=std::shared_ptr<CPort>(new CPort(gentl, &ifh));
00297     nodemap=allocNodeMap(gentl, ifh, cport.get());
00298   }
00299 
00300   return nodemap;
00301 }
00302 
00303 void *Interface::getHandle() const
00304 {
00305   return ifh;
00306 }
00307 
00308 }


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Thu Jun 6 2019 18:42:47