VimbaSystem.cpp
Go to the documentation of this file.
00001 /*=============================================================================
00002   Copyright (C) 2012 Allied Vision Technologies.  All Rights Reserved.
00003 
00004   Redistribution of this file, in original or modified form, without
00005   prior written consent of Allied Vision Technologies is prohibited.
00006 
00007 -------------------------------------------------------------------------------
00008  
00009   File:        VimbaSystem.cpp
00010 
00011   Description: Implementation of class AVT::VmbAPI::VimbaSystem.
00012 
00013 -------------------------------------------------------------------------------
00014 
00015   THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
00016   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF TITLE,
00017   NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR  PURPOSE ARE
00018   DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 
00019   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00020   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00021   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  
00022   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
00023   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00024   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026 =============================================================================*/
00027 
00028 #include <cstring>
00029 #include <algorithm>
00030 
00031 #include <VimbaCPP/Include/VimbaSystem.h>
00032 
00033 #include <VimbaCPP/Include/SharedPointerDefines.h>
00034 #include <VimbaCPP/Source/ConditionHelper.h>
00035 #include <VimbaCPP/Source/Clock.h>
00036 #include <VimbaCPP/Source/DefaultCameraFactory.h>
00037 #include <VimbaCPP/Source/Helper.h>
00038 #include <VimbaCPP/Source/Version.h>
00039 
00040 namespace AVT {
00041 namespace VmbAPI {
00042 
00043 typedef std::map<std::string, CameraPtr> CameraPtrMap;
00044 typedef std::map<std::string, InterfacePtr> InterfacePtrMap;
00045 
00046 struct VimbaSystem::Impl
00047 {
00048     // Found cameras and interfaces
00049     LockableMap<std::string, CameraPtr>             m_cameras;
00050     ConditionHelper                                 m_camerasConditionHelper;
00051     LockableMap<std::string, InterfacePtr>          m_interfaces;
00052     ConditionHelper                                 m_interfacesConditionHelper;
00053     // Registered observers
00054     LockableVector<ICameraListObserverPtr>          m_cameraObservers;
00055     ConditionHelper                                 m_cameraObserversConditionHelper;
00056     LockableVector<IInterfaceListObserverPtr>       m_interfaceObservers;
00057     ConditionHelper                                 m_interfaceObserversConditionHelper;
00058     
00059     // GigE specifics
00060     bool                                            m_bGeVDiscoveryAutoOn;
00061     bool                                            m_bGeVTLPresent;
00062     // CameraFactory
00063     ICameraFactoryPtr                               m_pCameraFactory;
00064 
00065     // Logger
00066     Logger                                          m_pLogger;
00067 
00068     VmbErrorType UpdateCameraList();
00069     VmbErrorType UpdateInterfaceList();
00070     void AppendCamToMap( VmbCameraInfo_t camInfo );
00071     bool IsIPAddress( const char *pStrID );
00072 
00073     VmbErrorType GetInterfaceList( std::vector<VmbInterfaceInfo_t> &interfaceInfos );
00074 
00075     static void VMB_CALL CameraDiscoveryCallback( const VmbHandle_t handle, const char *name, void *context );
00076     static void VMB_CALL InterfaceDiscoveryCallback( const VmbHandle_t handle, const char *name, void *context );
00077 };
00078 
00079 VimbaSystem &VimbaSystem::GetInstance()
00080 {
00081     return _instance;
00082 }
00083 
00084 VmbErrorType VimbaSystem::QueryVersion( VmbVersionInfo_t &rVersion )
00085 {
00086     rVersion.major = VIMBACPP_VERSION_MAJOR;
00087     rVersion.minor = VIMBACPP_VERSION_MINOR;
00088     rVersion.patch = VIMBACPP_VERSION_PATCH;
00089 
00090     return VmbErrorSuccess;
00091 }
00092 
00093 VmbErrorType VimbaSystem::Startup()
00094 {
00095     VmbError_t res = VmbStartup();
00096 
00097     VmbFeatureBoolGet( gVimbaHandle, "GeVTLIsPresent", &m_pImpl->m_bGeVTLPresent );
00098 
00099     return (VmbErrorType)res;
00100 }
00101 
00102 VmbErrorType VimbaSystem::Shutdown()
00103 {
00104     m_pImpl->m_bGeVDiscoveryAutoOn = m_pImpl->m_bGeVTLPresent = false;
00105     
00106     // Begin exclusive write lock camera observer list
00107     if ( true == m_pImpl->m_cameraObserversConditionHelper.EnterWriteLock( m_pImpl->m_cameraObservers, true ))
00108     {
00109         m_pImpl->m_cameraObservers.Vector.clear();
00110 
00111         // End write lock camera observer list
00112         m_pImpl->m_cameraObserversConditionHelper.ExitWriteLock( m_pImpl->m_cameraObservers );
00113     }
00114         
00115     // Begin exclusive write lock interface observer list
00116     if ( true == m_pImpl->m_interfaceObserversConditionHelper.EnterWriteLock( m_pImpl->m_interfaceObservers, true ))
00117     {
00118         m_pImpl->m_interfaceObservers.Vector.clear();
00119 
00120         // End write lock interface observer list
00121         m_pImpl->m_interfaceObserversConditionHelper.ExitWriteLock( m_pImpl->m_interfaceObservers );
00122     }    
00123 
00124     // Begin exclusive write lock camera list
00125     if ( true == m_pImpl->m_camerasConditionHelper.EnterWriteLock( m_pImpl->m_cameras, true ))
00126     {
00127         for (   CameraPtrMap::iterator iter = m_pImpl->m_cameras.Map.begin();
00128                 m_pImpl->m_cameras.Map.end() != iter;
00129                 ++iter)
00130         {
00131             SP_ACCESS( iter->second )->Close();
00132         }
00133         m_pImpl->m_cameras.Map.clear();
00134 
00135         // End write lock camera list
00136         m_pImpl->m_camerasConditionHelper.ExitWriteLock( m_pImpl->m_cameras );
00137     }    
00138 
00139     // Begin exclusive write lock interface list
00140     if ( true == m_pImpl->m_interfacesConditionHelper.EnterWriteLock( m_pImpl->m_interfaces, true ))
00141     {
00142         for (   InterfacePtrMap::iterator iter = m_pImpl->m_interfaces.Map.begin();
00143                 m_pImpl->m_interfaces.Map.end() != iter;
00144                 ++iter)
00145         {
00146             SP_ACCESS( iter->second )->Close();
00147         }
00148         m_pImpl->m_interfaces.Map.clear();
00149 
00150         // End write lock interface list
00151         m_pImpl->m_interfacesConditionHelper.ExitWriteLock( m_pImpl->m_interfaces );
00152     }    
00153 
00154     VmbShutdown();
00155     
00156     return VmbErrorSuccess;
00157 }
00158 
00159 VmbErrorType VimbaSystem::GetInterfaces( InterfacePtr *pInterfaces, VmbUint32_t &rnSize )
00160 {
00161     VmbErrorType res = VmbErrorInternalFault;
00162 
00163     // Begin write lock interface list
00164     if ( true == m_pImpl->m_interfacesConditionHelper.EnterWriteLock( m_pImpl->m_interfaces ))
00165     {
00166         res = m_pImpl->UpdateInterfaceList();
00167 
00168         if ( VmbErrorSuccess == res)
00169         {
00170             if ( NULL == pInterfaces )
00171             {
00172                 rnSize = (VmbUint32_t)m_pImpl->m_interfaces.Map.size();
00173                 res = VmbErrorSuccess;
00174             }
00175             else if ( m_pImpl->m_interfaces.Map.size() <= rnSize )
00176             {
00177                 VmbUint32_t i = 0;
00178                 for (   InterfacePtrMap::iterator iter = m_pImpl->m_interfaces.Map.begin();
00179                         m_pImpl->m_interfaces.Map.end() != iter;
00180                         ++iter, ++i )
00181                 {
00182                     pInterfaces[i] = iter->second;
00183                 }
00184                 rnSize = (VmbUint32_t)m_pImpl->m_interfaces.Map.size();
00185                 res = VmbErrorSuccess;
00186             }
00187             else
00188             {
00189                 res = VmbErrorMoreData;
00190             }
00191         }
00192 
00193         // End write lock interface list
00194         m_pImpl->m_interfacesConditionHelper.ExitWriteLock( m_pImpl->m_interfaces );
00195     }
00196     
00197     return res;
00198 }
00199 
00200 VmbErrorType VimbaSystem::GetInterfaceByID( const char *pStrID, InterfacePtr &rInterface )
00201 {
00202     if ( NULL == pStrID )
00203     {
00204         return VmbErrorBadParameter;
00205     }
00206 
00207     VmbErrorType res = VmbErrorNotFound;
00208     
00209     // Begin write lock interface list
00210     if ( true == m_pImpl->m_interfacesConditionHelper.EnterWriteLock( m_pImpl->m_interfaces ))
00211     {
00212         InterfacePtrMap::iterator iter = m_pImpl->m_interfaces.Map.find( pStrID );
00213         if ( m_pImpl->m_interfaces.Map.end() != iter )
00214         {
00215             rInterface = iter->second;
00216             res = VmbErrorSuccess;
00217         }
00218         else
00219         {
00220             std::vector<VmbInterfaceInfo_t> interfaceInfos;
00221             res = m_pImpl->GetInterfaceList( interfaceInfos );
00222 
00223             if ( VmbErrorSuccess == res )
00224             {
00225                 for (   std::vector<VmbInterfaceInfo_t>::iterator iterInfo = interfaceInfos.begin();
00226                         interfaceInfos.end() != iterInfo;
00227                         ++iterInfo )
00228                 {
00229                     if ( 0 ==  strcmp( iterInfo->interfaceIdString, pStrID ))
00230                     {
00231                         SP_SET( m_pImpl->m_interfaces.Map[pStrID], new Interface( &(*iterInfo) ));
00232                         break;
00233                     }
00234                 }
00235 
00236                 iter = m_pImpl->m_interfaces.Map.find( pStrID );
00237                 if ( m_pImpl->m_interfaces.Map.end() != iter )
00238                 {
00239                     rInterface = iter->second;
00240                 }
00241                 else
00242                 {
00243                     res = VmbErrorNotFound;
00244                 }
00245             }
00246         }
00247 
00248         // End write lock interface list
00249         m_pImpl->m_interfacesConditionHelper.ExitWriteLock( m_pImpl->m_interfaces );
00250     }
00251 
00252     return res;
00253 }
00254 
00255 VmbErrorType VimbaSystem::OpenInterfaceByID( const char *pStrID, InterfacePtr &rInterface )
00256 {
00257     if ( NULL == pStrID )
00258     {
00259         return VmbErrorBadParameter;
00260     }
00261 
00262     VmbErrorType res = GetInterfaceByID( pStrID, rInterface );
00263     if ( VmbErrorSuccess == res )
00264     {
00265         return SP_ACCESS( rInterface )->Open();
00266     }
00267 
00268     return res;
00269 }
00270 
00271 VmbErrorType VimbaSystem::GetCameras( CameraPtr *pCameras, VmbUint32_t &rnSize )
00272 {
00273     VmbErrorType res = VmbErrorInternalFault;
00274 
00275     // Begin write lock camera list
00276     if ( true == m_pImpl->m_camerasConditionHelper.EnterWriteLock( m_pImpl->m_cameras ))
00277     {
00278         res = m_pImpl->UpdateCameraList();
00279 
00280         if ( VmbErrorSuccess == res )
00281         {
00282             if ( NULL == pCameras )
00283             {
00284                 rnSize = (VmbUint32_t)m_pImpl->m_cameras.Map.size();
00285                 res = VmbErrorSuccess;
00286             }
00287             else if ( m_pImpl->m_cameras.Map.size() <= rnSize )
00288             {
00289                 VmbUint32_t i = 0;
00290                 for (   CameraPtrMap::iterator iter = m_pImpl->m_cameras.Map.begin();
00291                         m_pImpl->m_cameras.Map.end() != iter;
00292                         ++iter, ++i )
00293                 {
00294                     pCameras[i] = iter->second;
00295                 }
00296                 rnSize = (VmbUint32_t)m_pImpl->m_cameras.Map.size();
00297                 res = VmbErrorSuccess;
00298             }
00299             else
00300             {
00301                 res = VmbErrorMoreData;
00302             }
00303         }
00304 
00305         // End write lock camera list
00306         m_pImpl->m_camerasConditionHelper.ExitWriteLock( m_pImpl->m_cameras );
00307     }    
00308 
00309     return res;
00310 }
00311 
00312 VmbErrorType VimbaSystem::GetCameraByID( const char *pStrID, CameraPtr &rCamera )
00313 {
00314     if ( NULL == pStrID )
00315     {
00316         return VmbErrorBadParameter;
00317     }
00318 
00319     VmbError_t res = VmbErrorNotFound;
00320 
00321     // Begin write lock camera list
00322     if ( true == m_pImpl->m_camerasConditionHelper.EnterWriteLock( m_pImpl->m_cameras ))
00323     {
00324         // Try to identify the desired camera by its ID (in the list of known cameras)
00325         CameraPtrMap::iterator iter = m_pImpl->m_cameras.Map.find( pStrID );
00326         if ( m_pImpl->m_cameras.Map.end() != iter )
00327         {
00328             rCamera = iter->second;
00329             res = VmbErrorSuccess;
00330         }
00331         else
00332         {
00333             // Try to identify the desired camera by IP or MAC address (in the list of known cameras)
00334             if (    true == m_pImpl->m_bGeVTLPresent
00335                  && false == m_pImpl->m_bGeVDiscoveryAutoOn
00336                  && false == m_pImpl->IsIPAddress(pStrID) )
00337             {
00338                 // HINT: We have to send one discovery packet in case we want to open a GigE cam (unless we open it by IP address)
00339                 res = VmbFeatureCommandRun( gVimbaHandle, "GeVDiscoveryAllOnce" );
00340                 if ( VmbErrorSuccess != res )
00341                 {
00342                     LOG_FREE_TEXT( "Could not ping camera over ethernet" )
00343                 }
00344             }
00345 
00346             VmbCameraInfo_t camInfo;
00347             res = VmbCameraInfoQuery( pStrID, &camInfo, sizeof camInfo );
00348             if ( VmbErrorSuccess == res )
00349             {
00350                 iter = m_pImpl->m_cameras.Map.find( camInfo.cameraIdString );
00351                 if ( m_pImpl->m_cameras.Map.end() != iter )
00352                 {
00353                     rCamera = iter->second;
00354                 }
00355                 else
00356                 {
00357                     // We don't know the camera because it is new or we have to
00358                     // try to identify it by IP or MAC address directly
00359                     std::string cameraIdString;
00360                     if ( std::strcmp( camInfo.cameraIdString, pStrID ))
00361                     {
00362                         // TODO: Remove this with interface change                        
00363                         cameraIdString.assign( camInfo.cameraIdString ).append( AVT_IP_OR_MAC_ADDRESS ).append( pStrID );
00364                         camInfo.cameraIdString = cameraIdString.c_str();
00365                     }
00366                     m_pImpl->AppendCamToMap( camInfo );
00367 
00368                     iter = m_pImpl->m_cameras.Map.find( camInfo.cameraIdString );
00369                     if ( m_pImpl->m_cameras.Map.end() != iter )
00370                     {
00371                         rCamera = iter->second;
00372                     }
00373                     else
00374                     {
00375                         res = VmbErrorNotFound;
00376                     }
00377                 }
00378             }
00379         }
00380 
00381         // End write lock camera list
00382         m_pImpl->m_camerasConditionHelper.ExitWriteLock( m_pImpl->m_cameras );
00383     }
00384 
00385     return (VmbErrorType)res;
00386 }
00387 
00388 VmbErrorType VimbaSystem::OpenCameraByID( const char *pStrID, VmbAccessModeType eAccessMode, CameraPtr &rCamera )
00389 {
00390     if ( NULL == pStrID )
00391     {
00392         return VmbErrorBadParameter;
00393     }
00394 
00395     VmbErrorType res = GetCameraByID( pStrID, rCamera );
00396     if ( VmbErrorSuccess == res )
00397     {
00398         return SP_ACCESS( rCamera )->Open( eAccessMode );
00399     }
00400 
00401     return res;
00402 }
00403 
00404 CameraPtr VimbaSystem::GetCameraPtrByHandle( const VmbHandle_t handle ) const
00405 {
00406     CameraPtr res;
00407 
00408     // Begin read lock camera list
00409     if ( true == m_pImpl->m_camerasConditionHelper.EnterReadLock( m_pImpl->m_cameras ) )
00410     {
00411         for (   CameraPtrMap::const_iterator iter = m_pImpl->m_cameras.Map.begin();
00412                 m_pImpl->m_cameras.Map.end() != iter;
00413                 ++iter)
00414         {
00415             if ( SP_ACCESS( iter->second )->GetHandle() == handle )
00416             {
00417                 res = iter->second;
00418                 break;
00419             }
00420         }
00421 
00422         // End read lock camera list
00423         m_pImpl->m_camerasConditionHelper.ExitReadLock( m_pImpl->m_cameras );
00424     }
00425     else
00426     {
00427         LOG_FREE_TEXT( "Could not lock camera list")
00428     }
00429 
00430     return res;
00431 }
00432 
00433 void VMB_CALL VimbaSystem::Impl::CameraDiscoveryCallback( const VmbHandle_t /*handle*/, const char* /*name*/, void* /*context*/ )
00434 {
00435     VmbError_t err;
00436     std::vector<char> strID;
00437     VmbUint32_t nCount = 0;
00438 
00439     // Get the ID of the camera that has triggered the callback
00440     err = VmbFeatureStringMaxlengthQuery( gVimbaHandle, "DiscoveryCameraIdent", &nCount );
00441     if (    0 < nCount
00442         &&  VmbErrorSuccess == err )
00443     {                    
00444         strID.resize( nCount );
00445         err = VmbFeatureStringGet( gVimbaHandle, "DiscoveryCameraIdent", &strID[0], nCount, &nCount );
00446         if ( VmbErrorSuccess == err )
00447         {
00448             UpdateTriggerType reason = (UpdateTriggerType)0;
00449             const char* pReason = NULL;
00450             VmbInt64_t nReason = 0;
00451 
00452             // Get the reason that has triggered the callback
00453             err = VmbFeatureEnumGet( gVimbaHandle, "DiscoveryCameraEvent", &pReason );
00454             if ( VmbErrorSuccess == err )
00455             {
00456                 err = VmbFeatureEnumAsInt( gVimbaHandle, "DiscoveryCameraEvent", pReason, &nReason );
00457                 if ( VmbErrorSuccess == err )
00458                 {
00459                     switch ( nReason )
00460                     {
00461                     case 0: reason = UpdateTriggerPluggedOut;
00462                         break;
00463                     case 1: reason = UpdateTriggerPluggedIn;
00464                         break;
00465                     default: reason = UpdateTriggerOpenStateChanged;
00466                     }
00467                     
00468                     // Begin read lock camera list
00469                     if ( true == _instance.m_pImpl->m_camerasConditionHelper.EnterReadLock( _instance.m_pImpl->m_cameras ))
00470                     {
00471                         CameraPtrMap::iterator iter = _instance.m_pImpl->m_cameras.Map.find( &strID[0] );
00472                         CameraPtr pCam;
00473 
00474                         bool bFound;
00475 
00476                         // Was the camera known before?
00477                         if ( _instance.m_pImpl->m_cameras.Map.end() != iter )
00478                         {
00479                             bFound = true;
00480                             pCam = iter->second;
00481                         }
00482                         else
00483                         {
00484                             bFound = false;
00485                         }
00486 
00487                         // End read lock camera list
00488                         _instance.m_pImpl->m_camerasConditionHelper.ExitReadLock( _instance.m_pImpl->m_cameras );
00489 
00490                         // If the camera was not known before we query for it
00491                         if ( false == bFound )
00492                         {
00493                             err = _instance.GetCameraByID( &strID[0], pCam );
00494                             if ( VmbErrorSuccess != err )
00495                             {
00496                                 err = VmbErrorInternalFault;
00497                                 LOG_FREE_TEXT( "Could not find a known camera in camera list")
00498                             }
00499                         }
00500 
00501                         // Now that we know about the reason for the callback and the camera we can call all registered observers
00502                         if ( VmbErrorSuccess == err )
00503                         {
00504                             // Begin read lock camera observer list
00505                             if ( true == _instance.m_pImpl->m_cameraObserversConditionHelper.EnterReadLock( _instance.m_pImpl->m_cameraObservers ))
00506                             {
00507                                 for (   ICameraListObserverPtrVector::iterator iter = _instance.m_pImpl->m_cameraObservers.Vector.begin();
00508                                         _instance.m_pImpl->m_cameraObservers.Vector.end() != iter;
00509                                         ++iter )
00510                                 {
00511                                     SP_ACCESS(( *iter ))->CameraListChanged( pCam, reason );
00512                                 }
00513 
00514                                 // End read lock camera observer list
00515                                 _instance.m_pImpl->m_cameraObserversConditionHelper.ExitReadLock( _instance.m_pImpl->m_cameraObservers );
00516                             }
00517                             else
00518                             {
00519                                 LOG_FREE_TEXT( "Could not lock camera observer list")
00520                             }
00521                         }
00522                     }
00523                     else
00524                     {
00525                         LOG_FREE_TEXT( "Could not lock camera list")
00526                     }
00527                 }
00528                 else
00529                 {
00530                     LOG_FREE_TEXT( "Could not get integer representation of enum string" )
00531                 }
00532             }
00533             else
00534             {
00535                 LOG_FREE_TEXT( "Could not get callback trigger" )
00536             }
00537         }
00538         else
00539         {
00540             LOG_FREE_TEXT( "Could not get camera ID" )
00541         }
00542     }
00543     else
00544     {
00545         LOG_FREE_TEXT( "Could not get length of camera ID or length is 0" )
00546     }
00547 }
00548 
00549 void VMB_CALL VimbaSystem::Impl::InterfaceDiscoveryCallback( const VmbHandle_t /*handle*/, const char * /*name*/, void * /*context*/ )
00550 {
00551     VmbError_t err;
00552     std::vector<char> strID;
00553     VmbUint32_t nCount = 0;
00554 
00555     // Get the ID of the interface that has triggered the callback
00556     err = VmbFeatureStringMaxlengthQuery( gVimbaHandle, "DiscoveryInterfaceIdent", &nCount );
00557     if (    0 < nCount
00558         &&  VmbErrorSuccess == err )
00559     {                    
00560         strID.resize( nCount );
00561         err = VmbFeatureStringGet( gVimbaHandle, "DiscoveryInterfaceIdent", &strID[0], nCount, &nCount );
00562     }
00563 
00564     if ( VmbErrorSuccess == err )
00565     {
00566         // Begin read lock interface list
00567         if ( true == _instance.m_pImpl->m_interfacesConditionHelper.EnterReadLock( _instance.m_pImpl->m_interfaces ))
00568         {
00569             InterfacePtrMap::iterator iter = _instance.m_pImpl->m_interfaces.Map.find( &strID[0] );
00570             InterfacePtr pInterface;
00571             UpdateTriggerType reason = (UpdateTriggerType)0;
00572             bool bFound;
00573 
00574             if ( _instance.m_pImpl->m_interfaces.Map.end() != iter )
00575             {
00576                 bFound = true;
00577                 pInterface = iter->second;
00578             }
00579             else
00580             {
00581                 bFound = false;
00582             }
00583 
00584             // End read lock interface list
00585             _instance.m_pImpl->m_interfacesConditionHelper.ExitReadLock( _instance.m_pImpl->m_interfaces );
00586 
00587             // Begin write lock interface list
00588             if ( true == _instance.m_pImpl->m_interfacesConditionHelper.EnterWriteLock( _instance.m_pImpl->m_interfaces ))
00589             {
00590                 err = _instance.m_pImpl->UpdateInterfaceList();
00591 
00592                 // End write lock interface list
00593                 _instance.m_pImpl->m_interfacesConditionHelper.ExitWriteLock( _instance.m_pImpl->m_interfaces );
00594                 
00595                 if ( VmbErrorSuccess == err )
00596                 {
00597                     // Begin read lock interface list
00598                     if ( true == _instance.m_pImpl->m_interfacesConditionHelper.EnterReadLock( _instance.m_pImpl->m_interfaces ))
00599                     {
00600                         iter = _instance.m_pImpl->m_interfaces.Map.find( &strID[0] );
00601 
00602                         // The interface was known before
00603                         if ( true == bFound )
00604                         {
00605                             // The interface now has been removed
00606                             if ( _instance.m_pImpl->m_interfaces.Map.end() == iter )
00607                             {
00608                                 reason = UpdateTriggerPluggedOut;
00609                             }
00610                             else
00611                             {
00612                                 reason = UpdateTriggerOpenStateChanged;
00613                             }
00614                         }
00615                         // The interface is new
00616                         else
00617                         {
00618                             if ( _instance.m_pImpl->m_interfaces.Map.end() != iter )
00619                             {
00620                                 pInterface = iter->second;
00621                                 reason = UpdateTriggerPluggedIn;
00622                             }
00623                             else
00624                             {
00625                                 err = VmbErrorInternalFault;
00626                                 // Do some logging
00627                                 LOG_FREE_TEXT( "Could not find interface in interface list." )
00628                             }
00629                         }
00630 
00631                         // End read lock interface list
00632                         _instance.m_pImpl->m_interfacesConditionHelper.ExitReadLock( _instance.m_pImpl->m_interfaces );
00633 
00634                         if ( VmbErrorSuccess == err )
00635                         {
00636                             // Begin read lock interface observer list
00637                             if ( true == _instance.m_pImpl->m_interfaceObserversConditionHelper.EnterReadLock( _instance.m_pImpl->m_interfaceObservers ))
00638                             {
00639                                 for (   IInterfaceListObserverPtrVector::iterator iter = _instance.m_pImpl->m_interfaceObservers.Vector.begin();
00640                                     _instance.m_pImpl->m_interfaceObservers.Vector.end() != iter;
00641                                     ++iter)
00642                                 {
00643                                     SP_ACCESS(( *iter ))->InterfaceListChanged( pInterface, reason );
00644                                 }
00645 
00646                                 // End read lock interface observer list
00647                                 _instance.m_pImpl->m_interfaceObserversConditionHelper.ExitReadLock( _instance.m_pImpl->m_interfaceObservers );
00648                             }
00649                             else
00650                             {
00651                                 LOG_FREE_TEXT( "Could not lock interface observer list")
00652                             }
00653                         }                        
00654                     }
00655                     else
00656                     {
00657                         LOG_FREE_TEXT( "Could not lock interface list")
00658                     }
00659                 }                
00660             }            
00661         }
00662         else
00663         {
00664             LOG_FREE_TEXT( "Could not lock interface list")
00665         }
00666     }
00667 }
00668 
00669 VmbErrorType VimbaSystem::RegisterCameraListObserver( const ICameraListObserverPtr &rObserver )
00670 {
00671     if ( SP_ISNULL( rObserver ))
00672     {
00673         return VmbErrorBadParameter;
00674     }
00675 
00676     VmbError_t res = VmbErrorSuccess;
00677 
00678     // Begin write lock camera observer list
00679     if ( true == _instance.m_pImpl->m_cameraObserversConditionHelper.EnterWriteLock( m_pImpl->m_cameraObservers ))
00680     {
00681         // The very same observer cannot be registered twice
00682         for ( size_t i=0; i<m_pImpl->m_cameraObservers.Vector.size(); ++i )
00683         {
00684             if ( SP_ISEQUAL( rObserver, m_pImpl->m_cameraObservers.Vector[i] ))
00685             {
00686                 res = VmbErrorInvalidCall;
00687                 break;
00688             }
00689         }
00690 
00691         if ( VmbErrorSuccess == res )
00692         {
00693             m_pImpl->m_cameraObservers.Vector.push_back( rObserver );
00694 
00695             if ( 1 == m_pImpl->m_cameraObservers.Vector.size() )
00696             {
00697                 res = VmbFeatureInvalidationRegister( gVimbaHandle, "DiscoveryCameraEvent", m_pImpl->CameraDiscoveryCallback, this );
00698                 if (    VmbErrorSuccess == res
00699                      && true == m_pImpl->m_bGeVTLPresent )
00700                 {
00701                     // HINT: Without enabling GEVDiscovery registering a device observer is pointless
00702                     res = VmbFeatureCommandRun( gVimbaHandle, "GeVDiscoveryAllAuto" );
00703                     if ( VmbErrorSuccess == res )
00704                     {
00705                         m_pImpl->m_bGeVDiscoveryAutoOn = true;
00706                     }
00707                 }
00708 
00709                 if ( VmbErrorSuccess != res )
00710                 {
00711                     // Rollback
00712                     m_pImpl->m_cameraObservers.Vector.pop_back();
00713                     // Do some logging
00714                     LOG_FREE_TEXT( "Could not register camera list observer" )
00715                 }
00716             }
00717         }
00718 
00719         // End write lock camera observer list
00720         _instance.m_pImpl->m_cameraObserversConditionHelper.ExitWriteLock( m_pImpl->m_cameraObservers );
00721     }    
00722     
00723     return (VmbErrorType)res;
00724 }
00725 
00726 VmbErrorType VimbaSystem::UnregisterCameraListObserver( const ICameraListObserverPtr &rObserver )
00727 {
00728     if ( SP_ISNULL( rObserver ))
00729     {
00730         return VmbErrorBadParameter;
00731     }
00732 
00733     VmbError_t res = VmbErrorNotFound;
00734 
00735     // Begin exclusive write lock camera observer list
00736     if ( true == m_pImpl->m_cameraObserversConditionHelper.EnterWriteLock( m_pImpl->m_cameraObservers, true ))
00737     {
00738         for (   ICameraListObserverPtrVector::iterator iter = m_pImpl->m_cameraObservers.Vector.begin();
00739                 m_pImpl->m_cameraObservers.Vector.end() != iter;)    
00740         {
00741             if ( SP_ISEQUAL( rObserver, *iter ))
00742             {
00743                 // If we are about to unregister the last observer we cancel all camera discovery notifications
00744                 if ( 1 == m_pImpl->m_cameraObservers.Vector.size() )
00745                 {
00746                     res = VmbFeatureInvalidationUnregister( gVimbaHandle, "DiscoveryCameraEvent", m_pImpl->CameraDiscoveryCallback );
00747                     if (    VmbErrorSuccess == res
00748                          && true == m_pImpl->m_bGeVTLPresent )
00749                     {
00750                         // HINT: After unregistering the last device observer we do not need to send discovery pings anymore
00751                         res = VmbFeatureCommandRun( gVimbaHandle, "GeVDiscoveryAllOff" );
00752                         if ( VmbErrorSuccess == res )
00753                         {
00754                             m_pImpl->m_bGeVDiscoveryAutoOn = false;
00755                         }
00756                         else
00757                         {
00758                             // Rollback
00759                             VmbFeatureInvalidationRegister( gVimbaHandle, "DiscoveryCameraEvent", m_pImpl->CameraDiscoveryCallback, this );
00760                         }
00761                     }
00762                 }
00763                 
00764                 if (    VmbErrorSuccess == res
00765                      || 1 < m_pImpl->m_cameraObservers.Vector.size() )
00766                 {
00767                     iter = m_pImpl->m_cameraObservers.Vector.erase( iter );
00768                     res = VmbErrorSuccess;
00769                 }
00770                 break;
00771             }
00772             else
00773             {
00774                 ++iter;
00775             }
00776         }
00777 
00778         // End write lock camera observer list
00779         m_pImpl->m_cameraObserversConditionHelper.ExitWriteLock( m_pImpl->m_cameraObservers );
00780     }
00781     else
00782     {
00783         LOG_FREE_TEXT( "Could not lock camera observer list.")
00784         res = VmbErrorInternalFault;
00785     }
00786 
00787     return (VmbErrorType)res;
00788 }
00789 
00790 VmbErrorType VimbaSystem::RegisterInterfaceListObserver( const IInterfaceListObserverPtr &rObserver )
00791 {
00792     if ( SP_ISNULL( rObserver ))
00793     {
00794         return VmbErrorBadParameter;
00795     }
00796 
00797     VmbError_t res = VmbErrorSuccess;
00798 
00799     // Begin write lock interface observer list
00800     if ( true == _instance.m_pImpl->m_interfaceObserversConditionHelper.EnterWriteLock( m_pImpl->m_interfaceObservers ))
00801     {
00802         // The very same observer cannot be registered twice
00803         for ( size_t i=0; i<m_pImpl->m_interfaceObservers.Vector.size(); ++i )
00804         {
00805             if ( SP_ISEQUAL( rObserver, m_pImpl->m_interfaceObservers.Vector[i] ))
00806             {
00807                 res = VmbErrorInvalidCall;
00808                 break;
00809             }
00810         }
00811 
00812         if ( VmbErrorSuccess == res )
00813         {
00814             m_pImpl->m_interfaceObservers.Vector.push_back( rObserver );
00815 
00816             if ( 1 == m_pImpl->m_interfaceObservers.Vector.size() )
00817             {
00818                 res = VmbFeatureInvalidationRegister( gVimbaHandle, "DiscoveryInterfaceEvent", m_pImpl->InterfaceDiscoveryCallback, this );
00819 
00820                 if ( VmbErrorSuccess != res )
00821                 {
00822                     // Rollback
00823                     m_pImpl->m_interfaceObservers.Vector.pop_back();
00824 
00825                     // Do some logging
00826                     LOG_FREE_TEXT( "Could not register interface list observer" )
00827                 }
00828             }
00829         }
00830 
00831         // End write lock interface observer list
00832         _instance.m_pImpl->m_interfaceObserversConditionHelper.ExitWriteLock( m_pImpl->m_interfaceObservers );
00833     }    
00834 
00835     return (VmbErrorType)res;
00836 }
00837 
00838 VmbErrorType VimbaSystem::UnregisterInterfaceListObserver( const IInterfaceListObserverPtr &rObserver )
00839 {
00840     if ( SP_ISNULL( rObserver ))
00841     {
00842         return VmbErrorBadParameter;
00843     }
00844 
00845     VmbError_t res = VmbErrorNotFound;
00846 
00847     // Begin exclusive write lock interface observer list
00848     if ( true == _instance.m_pImpl->m_interfaceObserversConditionHelper.EnterWriteLock( m_pImpl->m_interfaceObservers, true ))
00849     {
00850         for (   IInterfaceListObserverPtrVector::iterator iter = m_pImpl->m_interfaceObservers.Vector.begin();
00851                 m_pImpl->m_interfaceObservers.Vector.end() != iter;)
00852         {
00853             if ( SP_ISEQUAL( rObserver, *iter ))
00854             {
00855                 // If we are about to unregister the last observer we cancel all interface discovery notifications
00856                 if ( 1 == m_pImpl->m_interfaceObservers.Vector.size() )
00857                 {
00858                     res = VmbFeatureInvalidationUnregister( gVimbaHandle, "DiscoveryInterfaceEvent", m_pImpl->InterfaceDiscoveryCallback );
00859                 }
00860                 if (    VmbErrorSuccess == res
00861                      || 1 < m_pImpl->m_interfaceObservers.Vector.size() )
00862                 {
00863                     iter = m_pImpl->m_interfaceObservers.Vector.erase( iter );
00864                     res = VmbErrorSuccess;
00865                 }
00866                 break;
00867             }
00868             else
00869             {
00870                 ++iter;
00871             }
00872         }
00873 
00874         // End write lock interface observer list
00875         _instance.m_pImpl->m_interfaceObserversConditionHelper.ExitWriteLock( m_pImpl->m_interfaceObservers );
00876     }
00877     else
00878     {
00879         LOG_FREE_TEXT( "Could not lock interface observer list.")
00880         res = VmbErrorInternalFault;
00881     }
00882 
00883     return (VmbErrorType)res;
00884 }
00885 
00886 VmbErrorType VimbaSystem::RegisterCameraFactory( const ICameraFactoryPtr &cameraFactory )
00887 {
00888     if ( SP_ISNULL( cameraFactory ))
00889     {
00890         return VmbErrorBadParameter;
00891     }
00892 
00893     m_pImpl->m_pCameraFactory = cameraFactory;
00894     
00895     return VmbErrorSuccess;
00896 }
00897 
00898 VmbErrorType VimbaSystem::UnregisterCameraFactory()
00899 {
00900     m_pImpl->m_pCameraFactory = ICameraFactoryPtr( new DefaultCameraFactory() );
00901 
00902     if ( SP_ISNULL( m_pImpl->m_pCameraFactory ))
00903     {
00904         return VmbErrorInternalFault;
00905     }
00906 
00907     return VmbErrorSuccess;
00908 }
00909 
00910 // Singleton
00911 VimbaSystem::VimbaSystem()
00912     :   m_pImpl( new Impl() )
00913 {
00914     m_pImpl->m_bGeVDiscoveryAutoOn = false;
00915     m_pImpl->m_bGeVTLPresent = false;
00916     m_pImpl->m_pLogger = new LOGGER_DEF;
00917     m_pImpl->m_pCameraFactory = ICameraFactoryPtr( new DefaultCameraFactory() );
00918 }
00919 
00920 // Singleton
00921 VimbaSystem::VimbaSystem( const VimbaSystem& )
00922 {
00923     // No generated copy ctor
00924 }
00925 
00926 VimbaSystem& VimbaSystem::operator=( const VimbaSystem& )
00927 {
00928     // No assignment operator
00929     return *this;
00930 }
00931 
00932 VimbaSystem::~VimbaSystem()
00933 {
00934     delete m_pImpl->m_pLogger;
00935     delete m_pImpl;
00936 }
00937 
00938 // Instance
00939 VimbaSystem VimbaSystem::_instance;
00940 
00941 // Gets a list of all connected interfaces and updates the internal interfaces map accordingly.
00942 // Reference counting for removed interfaces is decreased,
00943 // new interfaces are added.
00944 VmbErrorType VimbaSystem::Impl::UpdateInterfaceList()
00945 {
00946     std::vector<VmbInterfaceInfo_t> interfaceInfos;
00947     VmbErrorType res = GetInterfaceList( interfaceInfos );
00948     VmbUint32_t nCount = (VmbUint32_t)interfaceInfos.size();
00949 
00950     if ( VmbErrorSuccess == res )
00951     {
00952         InterfacePtrMap::iterator iter = m_interfaces.Map.begin();
00953         std::vector<VmbInterfaceInfo_t>::iterator iterInfo = interfaceInfos.begin();
00954         bool bFound = false;
00955 
00956         // Delete removed Interfaces from m_interfaces
00957         while ( m_interfaces.Map.end() != iter )
00958         {
00959             for ( VmbUint32_t i=0; i<nCount; ++i, ++iterInfo )
00960             {
00961                 if ( iterInfo->interfaceIdString == iter->first )
00962                 {
00963                     bFound = true;
00964                     break;
00965                 }
00966             }
00967 
00968             if ( false == bFound )
00969             {
00970                 m_interfaces.Map.erase( iter++ );
00971             }
00972             else
00973             {
00974                 ++iter;
00975             }
00976 
00977             bFound = false;
00978             iterInfo = interfaceInfos.begin();
00979         }
00980 
00981         // Add new Interfaces to m_Interfaces
00982         while ( 0 < nCount-- )
00983         {
00984             iter = m_interfaces.Map.find( iterInfo->interfaceIdString );
00985 
00986             if ( m_interfaces.Map.end() == iter )
00987             {
00988                 SP_SET( m_interfaces.Map[iterInfo->interfaceIdString], new Interface( &(*iterInfo) ));
00989             }
00990 
00991             ++iterInfo;
00992         }
00993     }
00994 
00995     return res;
00996 }
00997 
00998 // Gets a list of all connected cameras and updates the internal cameras map accordingly.
00999 // Reference counting for removed cameras is decreased,
01000 // new cameras are added.
01001 VmbErrorType VimbaSystem::Impl::UpdateCameraList()
01002 {
01003     VmbError_t res = VmbErrorSuccess;
01004     VmbUint32_t nCount = 0;
01005     std::vector<VmbCameraInfo_t> cameraInfos( 10 );
01006 
01007     // HINT: We explicitly have to enable GeVDiscovery to be able to use UpdateCameraList.
01008     if (    true == m_bGeVTLPresent
01009         &&  false == m_bGeVDiscoveryAutoOn )
01010     {
01011         res = VmbFeatureCommandRun( gVimbaHandle, "GeVDiscoveryAllOnce" );
01012     }
01013     try
01014     {
01015         if ( VmbErrorSuccess == res )
01016         {
01017             // First get 10 cameras at most
01018             res = VmbCamerasList( &cameraInfos[0], (VmbUint32_t)cameraInfos.size(), &nCount, sizeof(VmbCameraInfo_t) );
01019             // If there are more get them eventually
01020             // If even more new cameras were discovered in between the function calls we increase the allocated memory consecutively
01021             while ( VmbErrorMoreData == res )
01022             {
01023                 cameraInfos.resize( nCount );
01024                 res = VmbCamerasList( &cameraInfos[0], (VmbUint32_t)cameraInfos.size(), &nCount, sizeof(VmbCameraInfo_t) );
01025             }
01026         }
01027 
01028         if ( VmbErrorSuccess == res )
01029         {
01030             if( 0 != nCount )
01031             {
01032                 if( nCount < cameraInfos.size() )
01033                 {
01034                     cameraInfos.resize( nCount );
01035                 }
01036                 CameraPtrMap::iterator  mapPos  = m_cameras.Map.begin();
01037                 typedef std::vector<VmbCameraInfo_t>::const_iterator const_info_iterator;
01038 
01039                 // Delete removed cameras from m_cameras
01040                 while ( m_cameras.Map.end() != mapPos )
01041                 {
01042                     bool bFound = false;
01043                     for( const_info_iterator infoPos = cameraInfos.begin(); cameraInfos.end() != infoPos; ++infoPos )
01044                     {
01045                         if ( infoPos->cameraIdString == mapPos->first )
01046                         {
01047                             bFound = true;
01048                             break;
01049                         }
01050                     }
01051 
01052                     if ( false == bFound )
01053                     {
01054                         m_cameras.Map.erase( mapPos++ );
01055                     }
01056                     else
01057                     {
01058                         ++mapPos;
01059                     }
01060                 }
01061 
01062                 // Add new cameras to m_cameras
01063                 for (const_info_iterator infoPos= cameraInfos.begin(); infoPos != cameraInfos.end(); ++infoPos )
01064                 {
01065                     CameraPtrMap::const_iterator findPos = m_cameras.Map.find( infoPos->cameraIdString );
01066             
01067                     if ( m_cameras.Map.end() == findPos )
01068                     {
01069                         AppendCamToMap( *infoPos );
01070                     }
01071                 }
01072             }
01073             else
01074             {
01075                 m_cameras.Map.clear();
01076             }
01077         }
01078     }
01079     catch( const std::bad_alloc& /*badAlloc*/ )
01080     {
01081         return VmbErrorResources;
01082     }
01083     
01084 
01085     return (VmbErrorType)res;
01086 }
01087 
01088 Logger VimbaSystem::GetLogger() const
01089 {
01090     return m_pImpl->m_pLogger;
01091 }
01092 
01093 bool VimbaSystem::Impl::IsIPAddress( const char *pStrID )
01094 {
01095     if( NULL == pStrID )
01096     {
01097         return false;
01098     }
01099 
01100     size_t nCount = 0;
01101     size_t nSize = 0;
01102     size_t nIndex = 0;
01103     while( pStrID[nIndex] != '\0' )
01104     {
01105         if( isdigit( pStrID[nIndex] ) != 0 )
01106         {
01107             if( nSize >= 3 )
01108             {
01109                 return false;
01110             }
01111             nSize++;
01112         }
01113         else if( '.' == pStrID[nIndex] )
01114         {
01115             if(     (nSize <= 0)
01116                 ||  (nSize > 3)
01117                 ||  (nCount >= 3) )
01118             {
01119                 return false;
01120             }
01121             nCount++;
01122             nSize = 0;
01123         }
01124         else
01125         {
01126             return false;
01127         }
01128 
01129         nIndex++;
01130     }
01131     if(     (nSize <= 0)
01132         ||  (nSize > 3)
01133         ||  (nCount != 3) )
01134     {
01135         return false;
01136     }
01137 
01138     return true;
01139 }
01140 
01141 void VimbaSystem::Impl::AppendCamToMap( VmbCameraInfo_t camInfo )
01142 {
01143     InterfacePtr        pInterface;
01144     std::string         strInterfaceName,
01145                         strInterfaceSerial;
01146     VmbAccessModeType   interfaceAccess;
01147     VmbInterfaceType    interfaceType;
01148 
01149     // HINT: Before inserting (and potentially overwriting) a camera, we check whether it is present already
01150     if ( m_cameras.Map.end() == m_cameras.Map.find( camInfo.cameraIdString ))
01151     {
01152         if ( VmbErrorSuccess == _instance.GetInterfaceByID( camInfo.interfaceIdString, pInterface ))
01153         {
01154             if (    VmbErrorSuccess == SP_ACCESS( pInterface )->GetName( strInterfaceName )
01155                  && VmbErrorSuccess == SP_ACCESS( pInterface )->GetSerialNumber( strInterfaceSerial )
01156                  && VmbErrorSuccess == SP_ACCESS( pInterface )->GetPermittedAccess( interfaceAccess )
01157                  && VmbErrorSuccess == SP_ACCESS( pInterface )->GetType( interfaceType ))
01158             {
01159                 try
01160                 {
01161                     // TODO: Remove pCam with Interface change
01162                     CameraPtr pCam = SP_ACCESS( m_pCameraFactory )->CreateCamera(   camInfo.cameraIdString,
01163                                                                                     camInfo.cameraName,
01164                                                                                     camInfo.modelName,
01165                                                                                     camInfo.serialString,
01166                                                                                     camInfo.interfaceIdString,
01167                                                                                     interfaceType,
01168                                                                                     strInterfaceName.c_str(),
01169                                                                                     strInterfaceSerial.c_str(),
01170                                                                                     interfaceAccess );
01171                     // TODO: Remove with interface change
01172                     char* strTemp = (char*)strstr( camInfo.cameraIdString, AVT_IP_OR_MAC_ADDRESS );
01173                     if ( strTemp )
01174                     {
01175                         *strTemp = '\0';
01176                     }
01177                     m_cameras.Map[camInfo.cameraIdString] = pCam;
01178                 }
01179                 catch( ... )
01180                 {
01181                     // Do some logging
01182                     LOG_FREE_TEXT( "Could not create camera" )
01183                 }
01184 
01185                 CameraPtrMap::iterator iter = m_cameras.Map.find( camInfo.cameraIdString );
01186                 if (    m_cameras.Map.end() != iter
01187                      && SP_ISNULL( iter->second ))
01188                 {
01189                     m_cameras.Map.erase( iter );
01190                     // Do some logging
01191                     LOG_FREE_TEXT( "NULL camera created" )
01192                 }
01193             }
01194             else // Could not get interface infos 
01195             {
01196                 // Do some logging
01197                 LOG_FREE_TEXT( "Could not get interface infos" )
01198             }
01199         }
01200         else // Could not get interface
01201         {
01202             // Do some logging
01203             LOG_FREE_TEXT( "Could not get interface" )
01204         }
01205     }
01206 }
01207 
01208 VmbErrorType VimbaSystem::Impl::GetInterfaceList( std::vector<VmbInterfaceInfo_t> &rInterfaceInfos )
01209 {
01210     VmbError_t res;
01211     VmbUint32_t nCount;
01212 
01213     res = VmbInterfacesList( NULL, 0, &nCount, sizeof(VmbInterfaceInfo_t));
01214     if ( VmbErrorSuccess == res )
01215     {
01216         rInterfaceInfos.resize( nCount );
01217         res = VmbInterfacesList( &rInterfaceInfos[0], nCount, &nCount, sizeof(VmbInterfaceInfo_t));
01218     }
01219 
01220     return (VmbErrorType)res;
01221 }
01222 
01223 }} // namespace AVT::VmbAPI


avt_vimba_camera
Author(s): Miquel Massot , Allied Vision Technologies
autogenerated on Thu Jun 6 2019 18:23:39