VimbaSystem.cpp
Go to the documentation of this file.
1 /*=============================================================================
2  Copyright (C) 2012 Allied Vision Technologies. All Rights Reserved.
3 
4  Redistribution of this file, in original or modified form, without
5  prior written consent of Allied Vision Technologies is prohibited.
6 
7 -------------------------------------------------------------------------------
8 
9  File: VimbaSystem.cpp
10 
11  Description: Implementation of class AVT::VmbAPI::VimbaSystem.
12 
13 -------------------------------------------------------------------------------
14 
15  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
16  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF TITLE,
17  NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
23  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 =============================================================================*/
27 
28 #include <cstring>
29 #include <algorithm>
30 
32 
35 #include <VimbaCPP/Source/Clock.h>
37 #include <VimbaCPP/Source/Helper.h>
39 
40 namespace AVT {
41 namespace VmbAPI {
42 
43 typedef std::map<std::string, CameraPtr> CameraPtrMap;
44 typedef std::map<std::string, InterfacePtr> InterfacePtrMap;
45 
47 {
48  // Found cameras and interfaces
53  // Registered observers
58 
59  // GigE specifics
62  // CameraFactory
63  ICameraFactoryPtr m_pCameraFactory;
64 
65  // Logger
67 
70  void AppendCamToMap( VmbCameraInfo_t camInfo );
71  bool IsIPAddress( const char *pStrID );
72 
73  VmbErrorType GetInterfaceList( std::vector<VmbInterfaceInfo_t> &interfaceInfos );
74 
75  static void VMB_CALL CameraDiscoveryCallback( const VmbHandle_t handle, const char *name, void *context );
76  static void VMB_CALL InterfaceDiscoveryCallback( const VmbHandle_t handle, const char *name, void *context );
77 };
78 
80 {
81  return _instance;
82 }
83 
85 {
86  rVersion.major = VIMBACPP_VERSION_MAJOR;
87  rVersion.minor = VIMBACPP_VERSION_MINOR;
88  rVersion.patch = VIMBACPP_VERSION_PATCH;
89 
90  return VmbErrorSuccess;
91 }
92 
94 {
96  VmbBool_t gevTL = false;
97 
98  res = VmbStartup();
99  if ( VmbErrorSuccess == res )
100  {
101  res = VmbFeatureBoolGet( gVimbaHandle, "GeVTLIsPresent", &gevTL );
102  if ( VmbErrorSuccess == res )
103  {
104  m_pImpl->m_bGeVTLPresent = gevTL;
105  }
106 
108  }
109 
110  return (VmbErrorType)res;
111 }
112 
114 {
116 
117  // Begin exclusive write lock camera observer list
119  {
121 
122  // End write lock camera observer list
124  }
125 
126  // Begin exclusive write lock interface observer list
128  {
130 
131  // End write lock interface observer list
133  }
134 
135  // Begin exclusive write lock camera list
137  {
138  for ( CameraPtrMap::iterator iter = m_pImpl->m_cameras.Map.begin();
139  m_pImpl->m_cameras.Map.end() != iter;
140  ++iter)
141  {
142  SP_ACCESS( iter->second )->Close();
143  }
144  m_pImpl->m_cameras.Map.clear();
145 
146  // End write lock camera list
148  }
149 
150  // Begin exclusive write lock interface list
152  {
153  for ( InterfacePtrMap::iterator iter = m_pImpl->m_interfaces.Map.begin();
154  m_pImpl->m_interfaces.Map.end() != iter;
155  ++iter)
156  {
157  SP_ACCESS( iter->second )->Close();
158  }
159  m_pImpl->m_interfaces.Map.clear();
160 
161  // End write lock interface list
163  }
164 
165  VmbShutdown();
166 
167  return VmbErrorSuccess;
168 }
169 
170 VmbErrorType VimbaSystem::GetInterfaces( InterfacePtr *pInterfaces, VmbUint32_t &rnSize )
171 {
173 
174  // Begin write lock interface list
176  {
177  res = m_pImpl->UpdateInterfaceList();
178 
179  if ( VmbErrorSuccess == res)
180  {
181  if ( NULL == pInterfaces )
182  {
183  rnSize = (VmbUint32_t)m_pImpl->m_interfaces.Map.size();
184  res = VmbErrorSuccess;
185  }
186  else if ( m_pImpl->m_interfaces.Map.size() <= rnSize )
187  {
188  VmbUint32_t i = 0;
189  for ( InterfacePtrMap::iterator iter = m_pImpl->m_interfaces.Map.begin();
190  m_pImpl->m_interfaces.Map.end() != iter;
191  ++iter, ++i )
192  {
193  pInterfaces[i] = iter->second;
194  }
195  rnSize = (VmbUint32_t)m_pImpl->m_interfaces.Map.size();
196  res = VmbErrorSuccess;
197  }
198  else
199  {
200  res = VmbErrorMoreData;
201  }
202  }
203 
204  // End write lock interface list
206  }
207 
208  return res;
209 }
210 
211 VmbErrorType VimbaSystem::GetInterfaceByID( const char *pStrID, InterfacePtr &rInterface )
212 {
213  if ( NULL == pStrID )
214  {
215  return VmbErrorBadParameter;
216  }
217 
219 
220  // Begin write lock interface list
222  {
223  InterfacePtrMap::iterator iter = m_pImpl->m_interfaces.Map.find( pStrID );
224  if ( m_pImpl->m_interfaces.Map.end() != iter )
225  {
226  rInterface = iter->second;
227  res = VmbErrorSuccess;
228  }
229  else
230  {
231  std::vector<VmbInterfaceInfo_t> interfaceInfos;
232  res = m_pImpl->GetInterfaceList( interfaceInfos );
233 
234  if ( VmbErrorSuccess == res )
235  {
236  for ( std::vector<VmbInterfaceInfo_t>::iterator iterInfo = interfaceInfos.begin();
237  interfaceInfos.end() != iterInfo;
238  ++iterInfo )
239  {
240  if ( 0 == strcmp( iterInfo->interfaceIdString, pStrID ))
241  {
242  SP_SET( m_pImpl->m_interfaces.Map[pStrID], new Interface( &(*iterInfo) ));
243  break;
244  }
245  }
246 
247  iter = m_pImpl->m_interfaces.Map.find( pStrID );
248  if ( m_pImpl->m_interfaces.Map.end() != iter )
249  {
250  rInterface = iter->second;
251  }
252  else
253  {
254  res = VmbErrorNotFound;
255  }
256  }
257  }
258 
259  // End write lock interface list
261  }
262 
263  return res;
264 }
265 
266 VmbErrorType VimbaSystem::OpenInterfaceByID( const char *pStrID, InterfacePtr &rInterface )
267 {
268  if ( NULL == pStrID )
269  {
270  return VmbErrorBadParameter;
271  }
272 
273  VmbErrorType res = GetInterfaceByID( pStrID, rInterface );
274  if ( VmbErrorSuccess == res )
275  {
276  return SP_ACCESS( rInterface )->Open();
277  }
278 
279  return res;
280 }
281 
282 VmbErrorType VimbaSystem::GetCameras( CameraPtr *pCameras, VmbUint32_t &rnSize )
283 {
285 
286  // Begin write lock camera list
288  {
289  res = m_pImpl->UpdateCameraList();
290 
291  if ( VmbErrorSuccess == res )
292  {
293  if ( NULL == pCameras )
294  {
295  rnSize = (VmbUint32_t)m_pImpl->m_cameras.Map.size();
296  res = VmbErrorSuccess;
297  }
298  else if ( m_pImpl->m_cameras.Map.size() <= rnSize )
299  {
300  VmbUint32_t i = 0;
301  for ( CameraPtrMap::iterator iter = m_pImpl->m_cameras.Map.begin();
302  m_pImpl->m_cameras.Map.end() != iter;
303  ++iter, ++i )
304  {
305  pCameras[i] = iter->second;
306  }
307  rnSize = (VmbUint32_t)m_pImpl->m_cameras.Map.size();
308  res = VmbErrorSuccess;
309  }
310  else
311  {
312  res = VmbErrorMoreData;
313  }
314  }
315 
316  // End write lock camera list
318  }
319 
320  return res;
321 }
322 
323 VmbErrorType VimbaSystem::GetCameraByID( const char *pStrID, CameraPtr &rCamera )
324 {
325  if ( NULL == pStrID )
326  {
327  return VmbErrorBadParameter;
328  }
329 
331 
332  // Begin write lock camera list
334  {
335  // Try to identify the desired camera by its ID (in the list of known cameras)
336  CameraPtrMap::iterator iter = m_pImpl->m_cameras.Map.find( pStrID );
337  if ( m_pImpl->m_cameras.Map.end() != iter )
338  {
339  rCamera = iter->second;
340  res = VmbErrorSuccess;
341  }
342  else
343  {
344  // Try to identify the desired camera by IP or MAC address (in the list of known cameras)
345  if ( true == m_pImpl->m_bGeVTLPresent
346  && false == m_pImpl->IsIPAddress(pStrID) )
347  {
348  // check if GeV discovery is enabled
349  const char *pDiscoveryStatus = NULL;
350  res = VmbFeatureEnumGet( gVimbaHandle, "GeVDiscoveryStatus", &pDiscoveryStatus );
351  if ( VmbErrorSuccess == res )
352  {
353  VmbInt64_t discoveryValue = 0;
354  res = VmbFeatureEnumAsInt( gVimbaHandle, "GeVDiscoveryStatus", pDiscoveryStatus, &discoveryValue );
355  if ( 1 != discoveryValue )
356  {
357  // HINT: We have to send one discovery packet in case we want to open a GigE cam (unless we open it by IP address)
358  res = VmbFeatureCommandRun( gVimbaHandle, "GeVDiscoveryAllOnce" );
359  if ( VmbErrorSuccess != res )
360  {
361  LOG_FREE_TEXT( "Could not ping camera over ethernet" )
362  }
363  }
364  }
365  }
366 
367  VmbCameraInfo_t camInfo;
368  res = VmbCameraInfoQuery( pStrID, &camInfo, sizeof camInfo );
369  if ( VmbErrorSuccess == res )
370  {
371  iter = m_pImpl->m_cameras.Map.find( camInfo.cameraIdString );
372  if ( m_pImpl->m_cameras.Map.end() != iter )
373  {
374  rCamera = iter->second;
375  }
376  else
377  {
378  // We don't know the camera because it is new or we have to
379  // try to identify it by IP or MAC address directly
380  std::string cameraIdString;
381  if ( std::strcmp( camInfo.cameraIdString, pStrID ))
382  {
383  // TODO: Remove this with interface change
384  cameraIdString.assign( camInfo.cameraIdString ).append( AVT_IP_OR_MAC_ADDRESS ).append( pStrID );
385  camInfo.cameraIdString = cameraIdString.c_str();
386  }
387  m_pImpl->AppendCamToMap( camInfo );
388 
389  iter = m_pImpl->m_cameras.Map.find( camInfo.cameraIdString );
390  if ( m_pImpl->m_cameras.Map.end() != iter )
391  {
392  rCamera = iter->second;
393  }
394  else
395  {
396  res = VmbErrorNotFound;
397  }
398  }
399  }
400  }
401 
402  // End write lock camera list
404  }
405 
406  return (VmbErrorType)res;
407 }
408 
409 VmbErrorType VimbaSystem::OpenCameraByID( const char *pStrID, VmbAccessModeType eAccessMode, CameraPtr &rCamera )
410 {
411  if ( NULL == pStrID )
412  {
413  return VmbErrorBadParameter;
414  }
415 
416  VmbErrorType res = GetCameraByID( pStrID, rCamera );
417  if ( VmbErrorSuccess == res )
418  {
419  return SP_ACCESS( rCamera )->Open( eAccessMode );
420  }
421 
422  return res;
423 }
424 
425 CameraPtr VimbaSystem::GetCameraPtrByHandle( const VmbHandle_t handle ) const
426 {
427  CameraPtr res;
428 
429  // Begin read lock camera list
431  {
432  for ( CameraPtrMap::const_iterator iter = m_pImpl->m_cameras.Map.begin();
433  m_pImpl->m_cameras.Map.end() != iter;
434  ++iter)
435  {
436  if ( SP_ACCESS( iter->second )->GetHandle() == handle )
437  {
438  res = iter->second;
439  break;
440  }
441  }
442 
443  // End read lock camera list
445  }
446  else
447  {
448  LOG_FREE_TEXT( "Could not lock camera list")
449  }
450 
451  return res;
452 }
453 
454 void VMB_CALL VimbaSystem::Impl::CameraDiscoveryCallback( const VmbHandle_t /*handle*/, const char* /*name*/, void* /*context*/ )
455 {
456  VmbError_t err;
457  std::vector<char> strID;
458  VmbUint32_t nCount = 0;
459 
460  // Get the ID of the camera that has triggered the callback
461  err = VmbFeatureStringMaxlengthQuery( gVimbaHandle, "DiscoveryCameraIdent", &nCount );
462  if ( 0 < nCount
463  && VmbErrorSuccess == err )
464  {
465  strID.resize( nCount );
466  err = VmbFeatureStringGet( gVimbaHandle, "DiscoveryCameraIdent", &strID[0], nCount, &nCount );
467  if ( VmbErrorSuccess == err )
468  {
470  const char* pReason = NULL;
471  VmbInt64_t nReason = 0;
472 
473  // Get the reason that has triggered the callback
474  err = VmbFeatureEnumGet( gVimbaHandle, "DiscoveryCameraEvent", &pReason );
475  if ( VmbErrorSuccess == err )
476  {
477  err = VmbFeatureEnumAsInt( gVimbaHandle, "DiscoveryCameraEvent", pReason, &nReason );
478  if ( VmbErrorSuccess == err )
479  {
480  switch ( nReason )
481  {
482  case 0: reason = UpdateTriggerPluggedOut;
483  break;
484  case 1: reason = UpdateTriggerPluggedIn;
485  break;
486  default: reason = UpdateTriggerOpenStateChanged;
487  }
488 
489  // Begin read lock camera list
491  {
492  CameraPtrMap::iterator iter = _instance.m_pImpl->m_cameras.Map.find( &strID[0] );
493  CameraPtr pCam;
494 
495  bool bFound;
496 
497  // Was the camera known before?
498  if ( _instance.m_pImpl->m_cameras.Map.end() != iter )
499  {
500  bFound = true;
501  pCam = iter->second;
502  }
503  else
504  {
505  bFound = false;
506  }
507 
508  // End read lock camera list
510 
511  // If the camera was not known before we query for it
512  if ( false == bFound )
513  {
514  err = _instance.GetCameraByID( &strID[0], pCam );
515  if ( VmbErrorSuccess != err )
516  {
517  err = VmbErrorInternalFault;
518  LOG_FREE_TEXT( "Could not find a known camera in camera list")
519  }
520  }
521 
522  // Now that we know about the reason for the callback and the camera we can call all registered observers
523  if ( VmbErrorSuccess == err )
524  {
525  // Begin read lock camera observer list
527  {
528  for ( ICameraListObserverPtrVector::iterator iter = _instance.m_pImpl->m_cameraObservers.Vector.begin();
529  _instance.m_pImpl->m_cameraObservers.Vector.end() != iter;
530  ++iter )
531  {
532  SP_ACCESS(( *iter ))->CameraListChanged( pCam, reason );
533  }
534 
535  // End read lock camera observer list
537  }
538  else
539  {
540  LOG_FREE_TEXT( "Could not lock camera observer list")
541  }
542  }
543  }
544  else
545  {
546  LOG_FREE_TEXT( "Could not lock camera list")
547  }
548  }
549  else
550  {
551  LOG_FREE_TEXT( "Could not get integer representation of enum string" )
552  }
553  }
554  else
555  {
556  LOG_FREE_TEXT( "Could not get callback trigger" )
557  }
558  }
559  else
560  {
561  LOG_FREE_TEXT( "Could not get camera ID" )
562  }
563  }
564  else
565  {
566  LOG_FREE_TEXT( "Could not get length of camera ID or length is 0" )
567  }
568 }
569 
570 void VMB_CALL VimbaSystem::Impl::InterfaceDiscoveryCallback( const VmbHandle_t /*handle*/, const char * /*name*/, void * /*context*/ )
571 {
572  VmbError_t err;
573  std::vector<char> strID;
574  VmbUint32_t nCount = 0;
575 
576  // Get the ID of the interface that has triggered the callback
577  err = VmbFeatureStringMaxlengthQuery( gVimbaHandle, "DiscoveryInterfaceIdent", &nCount );
578  if ( 0 < nCount
579  && VmbErrorSuccess == err )
580  {
581  strID.resize( nCount );
582  err = VmbFeatureStringGet( gVimbaHandle, "DiscoveryInterfaceIdent", &strID[0], nCount, &nCount );
583  }
584 
585  if ( VmbErrorSuccess == err )
586  {
587  // Begin read lock interface list
589  {
590  InterfacePtrMap::iterator iter = _instance.m_pImpl->m_interfaces.Map.find( &strID[0] );
591  InterfacePtr pInterface;
593  bool bFound;
594 
595  if ( _instance.m_pImpl->m_interfaces.Map.end() != iter )
596  {
597  bFound = true;
598  pInterface = iter->second;
599  }
600  else
601  {
602  bFound = false;
603  }
604 
605  // End read lock interface list
607 
608  // Begin write lock interface list
610  {
612 
613  // End write lock interface list
615 
616  if ( VmbErrorSuccess == err )
617  {
618  // Begin read lock interface list
620  {
621  iter = _instance.m_pImpl->m_interfaces.Map.find( &strID[0] );
622 
623  // The interface was known before
624  if ( true == bFound )
625  {
626  // The interface now has been removed
627  if ( _instance.m_pImpl->m_interfaces.Map.end() == iter )
628  {
629  reason = UpdateTriggerPluggedOut;
630  }
631  else
632  {
634  }
635  }
636  // The interface is new
637  else
638  {
639  if ( _instance.m_pImpl->m_interfaces.Map.end() != iter )
640  {
641  pInterface = iter->second;
642  reason = UpdateTriggerPluggedIn;
643  }
644  else
645  {
646  err = VmbErrorInternalFault;
647  // Do some logging
648  LOG_FREE_TEXT( "Could not find interface in interface list." )
649  }
650  }
651 
652  // End read lock interface list
654 
655  if ( VmbErrorSuccess == err )
656  {
657  // Begin read lock interface observer list
659  {
660  for ( IInterfaceListObserverPtrVector::iterator iter = _instance.m_pImpl->m_interfaceObservers.Vector.begin();
662  ++iter)
663  {
664  SP_ACCESS(( *iter ))->InterfaceListChanged( pInterface, reason );
665  }
666 
667  // End read lock interface observer list
669  }
670  else
671  {
672  LOG_FREE_TEXT( "Could not lock interface observer list")
673  }
674  }
675  }
676  else
677  {
678  LOG_FREE_TEXT( "Could not lock interface list")
679  }
680  }
681  }
682  }
683  else
684  {
685  LOG_FREE_TEXT( "Could not lock interface list")
686  }
687  }
688 }
689 
690 VmbErrorType VimbaSystem::RegisterCameraListObserver( const ICameraListObserverPtr &rObserver )
691 {
692  if ( SP_ISNULL( rObserver ))
693  {
694  return VmbErrorBadParameter;
695  }
696 
698 
699  // Begin write lock camera observer list
701  {
702  // The very same observer cannot be registered twice
703  for ( size_t i=0; i<m_pImpl->m_cameraObservers.Vector.size(); ++i )
704  {
705  if ( SP_ISEQUAL( rObserver, m_pImpl->m_cameraObservers.Vector[i] ))
706  {
707  res = VmbErrorInvalidCall;
708  break;
709  }
710  }
711 
712  if ( VmbErrorSuccess == res )
713  {
714  m_pImpl->m_cameraObservers.Vector.push_back( rObserver );
715 
716  if ( 1 == m_pImpl->m_cameraObservers.Vector.size() )
717  {
718  res = VmbFeatureInvalidationRegister( gVimbaHandle, "DiscoveryCameraEvent", m_pImpl->CameraDiscoveryCallback, this );
719  if ( VmbErrorSuccess == res
720  && true == m_pImpl->m_bGeVTLPresent )
721  {
722  // check if GeV discovery was already enabled
723  const char *pDiscoveryStatus = NULL;
724  res = VmbFeatureEnumGet( gVimbaHandle, "GeVDiscoveryStatus", &pDiscoveryStatus );
725  if ( VmbErrorSuccess == res )
726  {
727  VmbInt64_t discoveryValue = 0;
728  res = VmbFeatureEnumAsInt( gVimbaHandle, "GeVDiscoveryStatus", pDiscoveryStatus, &discoveryValue );
729  if ( VmbErrorSuccess == res )
730  {
731  if ( 1 != discoveryValue )
732  {
733  // HINT: Without enabling GEVDiscovery registering a device observer is pointless
734  res = VmbFeatureCommandRun( gVimbaHandle, "GeVDiscoveryAllAuto" );
735  if ( VmbErrorSuccess == res )
736  {
738  }
739  }
740  }
741  }
742  }
743 
744  if ( VmbErrorSuccess != res )
745  {
746  // Rollback
747  m_pImpl->m_cameraObservers.Vector.pop_back();
748  // Do some logging
749  LOG_FREE_TEXT( "Could not register camera list observer" )
750  }
751  }
752  }
753 
754  // End write lock camera observer list
756  }
757 
758  return (VmbErrorType)res;
759 }
760 
761 VmbErrorType VimbaSystem::UnregisterCameraListObserver( const ICameraListObserverPtr &rObserver )
762 {
763  if ( SP_ISNULL( rObserver ))
764  {
765  return VmbErrorBadParameter;
766  }
767 
769 
770  // Begin exclusive write lock camera observer list
772  {
773  for ( ICameraListObserverPtrVector::iterator iter = m_pImpl->m_cameraObservers.Vector.begin();
774  m_pImpl->m_cameraObservers.Vector.end() != iter;)
775  {
776  if ( SP_ISEQUAL( rObserver, *iter ))
777  {
778  // If we are about to unregister the last observer we cancel all camera discovery notifications
779  if ( 1 == m_pImpl->m_cameraObservers.Vector.size() )
780  {
782  if ( VmbErrorSuccess == res
783  && true == m_pImpl->m_bGeVTLPresent )
784  {
785  // check if GeV discovery was already enabled
786  const char *pDiscoveryStatus = NULL;
787  res = VmbFeatureEnumGet( gVimbaHandle, "GeVDiscoveryStatus", &pDiscoveryStatus );
788  if ( VmbErrorSuccess == res )
789  {
790  VmbInt64_t discoveryValue = 0;
791  res = VmbFeatureEnumAsInt( gVimbaHandle, "GeVDiscoveryStatus", pDiscoveryStatus, &discoveryValue );
792  if ( VmbErrorSuccess == res )
793  {
794  if ( 0 != discoveryValue )
795  {
796  // HINT: After unregistering the last device observer we do not need to send discovery pings anymore
797  res = VmbFeatureCommandRun( gVimbaHandle, "GeVDiscoveryAllOff" );
798  if ( VmbErrorSuccess == res )
799  {
801  }
802  else
803  {
804  // Rollback
806  }
807  }
808  }
809  }
810  }
811  }
812 
813  if ( VmbErrorSuccess == res
814  || 1 < m_pImpl->m_cameraObservers.Vector.size() )
815  {
816  iter = m_pImpl->m_cameraObservers.Vector.erase( iter );
817  res = VmbErrorSuccess;
818  }
819  break;
820  }
821  else
822  {
823  ++iter;
824  }
825  }
826 
827  // End write lock camera observer list
829  }
830  else
831  {
832  LOG_FREE_TEXT( "Could not lock camera observer list.")
833  res = VmbErrorInternalFault;
834  }
835 
836  return (VmbErrorType)res;
837 }
838 
839 VmbErrorType VimbaSystem::RegisterInterfaceListObserver( const IInterfaceListObserverPtr &rObserver )
840 {
841  if ( SP_ISNULL( rObserver ))
842  {
843  return VmbErrorBadParameter;
844  }
845 
847 
848  // Begin write lock interface observer list
850  {
851  // The very same observer cannot be registered twice
852  for ( size_t i=0; i<m_pImpl->m_interfaceObservers.Vector.size(); ++i )
853  {
854  if ( SP_ISEQUAL( rObserver, m_pImpl->m_interfaceObservers.Vector[i] ))
855  {
856  res = VmbErrorInvalidCall;
857  break;
858  }
859  }
860 
861  if ( VmbErrorSuccess == res )
862  {
863  m_pImpl->m_interfaceObservers.Vector.push_back( rObserver );
864 
865  if ( 1 == m_pImpl->m_interfaceObservers.Vector.size() )
866  {
867  res = VmbFeatureInvalidationRegister( gVimbaHandle, "DiscoveryInterfaceEvent", m_pImpl->InterfaceDiscoveryCallback, this );
868 
869  if ( VmbErrorSuccess != res )
870  {
871  // Rollback
872  m_pImpl->m_interfaceObservers.Vector.pop_back();
873 
874  // Do some logging
875  LOG_FREE_TEXT( "Could not register interface list observer" )
876  }
877  }
878  }
879 
880  // End write lock interface observer list
882  }
883 
884  return (VmbErrorType)res;
885 }
886 
887 VmbErrorType VimbaSystem::UnregisterInterfaceListObserver( const IInterfaceListObserverPtr &rObserver )
888 {
889  if ( SP_ISNULL( rObserver ))
890  {
891  return VmbErrorBadParameter;
892  }
893 
895 
896  // Begin exclusive write lock interface observer list
898  {
899  for ( IInterfaceListObserverPtrVector::iterator iter = m_pImpl->m_interfaceObservers.Vector.begin();
900  m_pImpl->m_interfaceObservers.Vector.end() != iter;)
901  {
902  if ( SP_ISEQUAL( rObserver, *iter ))
903  {
904  // If we are about to unregister the last observer we cancel all interface discovery notifications
905  if ( 1 == m_pImpl->m_interfaceObservers.Vector.size() )
906  {
908  }
909  if ( VmbErrorSuccess == res
910  || 1 < m_pImpl->m_interfaceObservers.Vector.size() )
911  {
912  iter = m_pImpl->m_interfaceObservers.Vector.erase( iter );
913  res = VmbErrorSuccess;
914  }
915  break;
916  }
917  else
918  {
919  ++iter;
920  }
921  }
922 
923  // End write lock interface observer list
925  }
926  else
927  {
928  LOG_FREE_TEXT( "Could not lock interface observer list.")
929  res = VmbErrorInternalFault;
930  }
931 
932  return (VmbErrorType)res;
933 }
934 
935 VmbErrorType VimbaSystem::RegisterCameraFactory( const ICameraFactoryPtr &cameraFactory )
936 {
937  if ( SP_ISNULL( cameraFactory ))
938  {
939  return VmbErrorBadParameter;
940  }
941 
942  m_pImpl->m_pCameraFactory = cameraFactory;
943 
944  return VmbErrorSuccess;
945 }
946 
948 {
949  m_pImpl->m_pCameraFactory = ICameraFactoryPtr( new DefaultCameraFactory() );
950 
952  {
953  return VmbErrorInternalFault;
954  }
955 
956  return VmbErrorSuccess;
957 }
958 
959 // Singleton
961  : m_pImpl( new Impl() )
962 {
964  m_pImpl->m_bGeVTLPresent = false;
966  m_pImpl->m_pCameraFactory = ICameraFactoryPtr( new DefaultCameraFactory() );
967 }
968 
969 // Singleton
971 {
972  // No generated copy ctor
973 }
974 
976 {
977  // No assignment operator
978  return *this;
979 }
980 
982 {
983  delete m_pImpl->m_pLogger;
984  m_pImpl->m_pLogger = NULL;
985  delete m_pImpl;
986  m_pImpl = NULL;
987 }
988 
989 // Instance
991 
992 // Gets a list of all connected interfaces and updates the internal interfaces map accordingly.
993 // Reference counting for removed interfaces is decreased,
994 // new interfaces are added.
996 {
997  std::vector<VmbInterfaceInfo_t> interfaceInfos;
998  VmbErrorType res = GetInterfaceList( interfaceInfos );
999  VmbUint32_t nCount = (VmbUint32_t)interfaceInfos.size();
1000 
1001  if ( VmbErrorSuccess == res )
1002  {
1003  InterfacePtrMap::iterator iter = m_interfaces.Map.begin();
1004  std::vector<VmbInterfaceInfo_t>::iterator iterInfo = interfaceInfos.begin();
1005  bool bFound = false;
1006 
1007  // Delete removed Interfaces from m_interfaces
1008  while ( m_interfaces.Map.end() != iter )
1009  {
1010  for ( VmbUint32_t i=0; i<nCount; ++i, ++iterInfo )
1011  {
1012  if ( iterInfo->interfaceIdString == iter->first )
1013  {
1014  bFound = true;
1015  break;
1016  }
1017  }
1018 
1019  if ( false == bFound )
1020  {
1021  m_interfaces.Map.erase( iter++ );
1022  }
1023  else
1024  {
1025  ++iter;
1026  }
1027 
1028  bFound = false;
1029  iterInfo = interfaceInfos.begin();
1030  }
1031 
1032  // Add new Interfaces to m_Interfaces
1033  while ( 0 < nCount-- )
1034  {
1035  iter = m_interfaces.Map.find( iterInfo->interfaceIdString );
1036 
1037  if ( m_interfaces.Map.end() == iter )
1038  {
1039  SP_SET( m_interfaces.Map[iterInfo->interfaceIdString], new Interface( &(*iterInfo) ));
1040  }
1041 
1042  ++iterInfo;
1043  }
1044  }
1045 
1046  return res;
1047 }
1048 
1049 // Gets a list of all connected cameras and updates the internal cameras map accordingly.
1050 // Reference counting for removed cameras is decreased,
1051 // new cameras are added.
1053 {
1055  VmbUint32_t nCount = 0;
1056  std::vector<VmbCameraInfo_t> cameraInfos( 10 );
1057 
1058  // HINT: We explicitly have to enable GeVDiscovery to be able to use UpdateCameraList.
1059  if ( true == m_bGeVTLPresent )
1060  {
1061  // check GeV discovery status
1062  const char *pDiscoveryStatus = NULL;
1063  res = VmbFeatureEnumGet( gVimbaHandle, "GeVDiscoveryStatus", &pDiscoveryStatus );
1064  if ( VmbErrorSuccess == res )
1065  {
1066  VmbInt64_t discoveryValue = 0;
1067  res = VmbFeatureEnumAsInt( gVimbaHandle, "GeVDiscoveryStatus", pDiscoveryStatus, &discoveryValue );
1068  if ( VmbErrorSuccess == res )
1069  {
1070  if ( 1 != discoveryValue )
1071  {
1072  res = VmbFeatureCommandRun( gVimbaHandle, "GeVDiscoveryAllOnce" );
1073  if ( VmbErrorSuccess == res )
1074  {
1075  m_bGeVDiscoveryAutoOn = true;
1076  }
1077  }
1078  }
1079  }
1080  }
1081  try
1082  {
1083  if ( VmbErrorSuccess == res )
1084  {
1085  // First get 10 cameras at most
1086  res = VmbCamerasList( &cameraInfos[0], (VmbUint32_t)cameraInfos.size(), &nCount, sizeof(VmbCameraInfo_t) );
1087  // If there are more get them eventually
1088  // If even more new cameras were discovered in between the function calls we increase the allocated memory consecutively
1089  while ( VmbErrorMoreData == res )
1090  {
1091  cameraInfos.resize( nCount );
1092  res = VmbCamerasList( &cameraInfos[0], (VmbUint32_t)cameraInfos.size(), &nCount, sizeof(VmbCameraInfo_t) );
1093  }
1094  }
1095 
1096  if ( VmbErrorSuccess == res )
1097  {
1098  if( 0 != nCount )
1099  {
1100  if( nCount < cameraInfos.size() )
1101  {
1102  cameraInfos.resize( nCount );
1103  }
1104  CameraPtrMap::iterator mapPos = m_cameras.Map.begin();
1105  typedef std::vector<VmbCameraInfo_t>::const_iterator const_info_iterator;
1106 
1107  // Delete removed cameras from m_cameras
1108  while ( m_cameras.Map.end() != mapPos )
1109  {
1110  bool bFound = false;
1111  for( const_info_iterator infoPos = cameraInfos.begin(); cameraInfos.end() != infoPos; ++infoPos )
1112  {
1113  if ( infoPos->cameraIdString == mapPos->first )
1114  {
1115  bFound = true;
1116  break;
1117  }
1118  }
1119 
1120  if ( false == bFound )
1121  {
1122  m_cameras.Map.erase( mapPos++ );
1123  }
1124  else
1125  {
1126  ++mapPos;
1127  }
1128  }
1129 
1130  // Add new cameras to m_cameras
1131  for (const_info_iterator infoPos= cameraInfos.begin(); infoPos != cameraInfos.end(); ++infoPos )
1132  {
1133  CameraPtrMap::const_iterator findPos = m_cameras.Map.find( infoPos->cameraIdString );
1134 
1135  if ( m_cameras.Map.end() == findPos )
1136  {
1137  AppendCamToMap( *infoPos );
1138  }
1139  }
1140  }
1141  else
1142  {
1143  m_cameras.Map.clear();
1144  }
1145  }
1146  }
1147  catch( const std::bad_alloc& /*badAlloc*/ )
1148  {
1149  return VmbErrorResources;
1150  }
1151 
1152 
1153  return (VmbErrorType)res;
1154 }
1155 
1157 {
1158  if(m_pImpl == NULL)
1159  return NULL;
1160  return m_pImpl->m_pLogger;
1161 }
1162 
1163 bool VimbaSystem::Impl::IsIPAddress( const char *pStrID )
1164 {
1165  if( NULL == pStrID )
1166  {
1167  return false;
1168  }
1169 
1170  size_t nCount = 0;
1171  size_t nSize = 0;
1172  size_t nIndex = 0;
1173  while( pStrID[nIndex] != '\0' )
1174  {
1175  if( isdigit( pStrID[nIndex] ) != 0 )
1176  {
1177  if( nSize >= 3 )
1178  {
1179  return false;
1180  }
1181  nSize++;
1182  }
1183  else if( '.' == pStrID[nIndex] )
1184  {
1185  if( (nSize <= 0)
1186  || (nSize > 3)
1187  || (nCount >= 3) )
1188  {
1189  return false;
1190  }
1191  nCount++;
1192  nSize = 0;
1193  }
1194  else
1195  {
1196  return false;
1197  }
1198 
1199  nIndex++;
1200  }
1201  if( (nSize <= 0)
1202  || (nSize > 3)
1203  || (nCount != 3) )
1204  {
1205  return false;
1206  }
1207 
1208  return true;
1209 }
1210 
1212 {
1213  InterfacePtr pInterface;
1214  std::string strInterfaceName,
1215  strInterfaceSerial;
1216  VmbAccessModeType interfaceAccess;
1217  VmbInterfaceType interfaceType;
1218 
1219  // HINT: Before inserting (and potentially overwriting) a camera, we check whether it is present already
1220  if ( m_cameras.Map.end() == m_cameras.Map.find( camInfo.cameraIdString ))
1221  {
1222  if ( VmbErrorSuccess == _instance.GetInterfaceByID( camInfo.interfaceIdString, pInterface ))
1223  {
1224  if ( VmbErrorSuccess == SP_ACCESS( pInterface )->GetName( strInterfaceName )
1225  && VmbErrorSuccess == SP_ACCESS( pInterface )->GetSerialNumber( strInterfaceSerial )
1226  && VmbErrorSuccess == SP_ACCESS( pInterface )->GetPermittedAccess( interfaceAccess )
1227  && VmbErrorSuccess == SP_ACCESS( pInterface )->GetType( interfaceType ))
1228  {
1229  try
1230  {
1231  // TODO: Remove pCam with Interface change
1232  CameraPtr pCam = SP_ACCESS( m_pCameraFactory )->CreateCamera( camInfo.cameraIdString,
1233  camInfo.cameraName,
1234  camInfo.modelName,
1235  camInfo.serialString,
1236  camInfo.interfaceIdString,
1237  interfaceType,
1238  strInterfaceName.c_str(),
1239  strInterfaceSerial.c_str(),
1240  interfaceAccess );
1241  // TODO: Remove with interface change
1242  char* strTemp = (char*)strstr( camInfo.cameraIdString, AVT_IP_OR_MAC_ADDRESS );
1243  if ( strTemp )
1244  {
1245  *strTemp = '\0';
1246  }
1247  m_cameras.Map[camInfo.cameraIdString] = pCam;
1248  }
1249  catch( ... )
1250  {
1251  // Do some logging
1252  LOG_FREE_TEXT( "Could not create camera" )
1253  }
1254 
1255  CameraPtrMap::iterator iter = m_cameras.Map.find( camInfo.cameraIdString );
1256  if ( m_cameras.Map.end() != iter
1257  && SP_ISNULL( iter->second ))
1258  {
1259  m_cameras.Map.erase( iter );
1260  // Do some logging
1261  LOG_FREE_TEXT( "NULL camera created" )
1262  }
1263  }
1264  else // Could not get interface infos
1265  {
1266  // Do some logging
1267  LOG_FREE_TEXT( "Could not get interface infos" )
1268  }
1269  }
1270  else // Could not get interface
1271  {
1272  // Do some logging
1273  LOG_FREE_TEXT( "Could not get interface" )
1274  }
1275  }
1276 }
1277 
1278 VmbErrorType VimbaSystem::Impl::GetInterfaceList( std::vector<VmbInterfaceInfo_t> &rInterfaceInfos )
1279 {
1280  VmbError_t res;
1281  VmbUint32_t nCount;
1282 
1283  res = VmbInterfacesList( NULL, 0, &nCount, sizeof(VmbInterfaceInfo_t));
1284  if ( VmbErrorSuccess == res )
1285  {
1286  rInterfaceInfos.resize( nCount );
1287  res = VmbInterfacesList( &rInterfaceInfos[0], nCount, &nCount, sizeof(VmbInterfaceInfo_t));
1288  }
1289 
1290  return (VmbErrorType)res;
1291 }
1292 
1293 }} // namespace AVT::VmbAPI
IMEXPORTC VmbError_t VMB_CALL VmbFeatureCommandRun(const VmbHandle_t handle, const char *name)
VmbInt32_t VmbError_t
IMEXPORT VmbErrorType GetCameraByID(const char *pID, CameraPtr &pCamera)
static IMEXPORT VimbaSystem & GetInstance()
Definition: VimbaSystem.cpp:79
std::map< std::string, CameraPtr > CameraPtrMap
Definition: VimbaSystem.cpp:43
bool EnterWriteLock(BasicLockable &rLockable, bool bExclusive=false)
#define SP_ISNULL(sp)
const char * cameraIdString
Definition: VimbaC.h:152
VmbErrorType GetInterfaceList(std::vector< VmbInterfaceInfo_t > &interfaceInfos)
char VmbBool_t
std::vector< T > Vector
Definition: Helper.h:41
IMEXPORTC VmbError_t VMB_CALL VmbFeatureStringMaxlengthQuery(const VmbHandle_t handle, const char *name, VmbUint32_t *pMaxLength)
#define VIMBACPP_VERSION_PATCH
Definition: Version.h:6
long long VmbInt64_t
IMEXPORTC VmbError_t VMB_CALL VmbFeatureStringGet(const VmbHandle_t handle, const char *name, char *buffer, VmbUint32_t bufferSize, VmbUint32_t *pSizeFilled)
#define SP_ACCESS(sp)
IMEXPORT VmbErrorType Startup()
Definition: VimbaSystem.cpp:93
IMEXPORT VmbErrorType RegisterCameraListObserver(const ICameraListObserverPtr &pObserver)
VmbUint32_t minor
VmbErrorType GetInterfaces(InterfacePtrVector &interfaces)
char const *const AVT_IP_OR_MAC_ADDRESS
Definition: Helper.h:51
static void VMB_CALL InterfaceDiscoveryCallback(const VmbHandle_t handle, const char *name, void *context)
LockableMap< std::string, InterfacePtr > m_interfaces
Definition: VimbaSystem.cpp:51
const char * cameraName
Definition: VimbaC.h:153
std::map< std::string, InterfacePtr > InterfacePtrMap
Definition: VimbaSystem.cpp:44
void ExitWriteLock(BasicLockable &rLockable)
IMEXPORT VmbErrorType OpenCameraByID(const char *pID, VmbAccessModeType eAccessMode, CameraPtr &pCamera)
LOGGER_DECL * Logger
Definition: LoggerDefines.h:46
VmbErrorType
static const VmbHandle_t gVimbaHandle
Definition: VimbaC.h:102
IMEXPORTC VmbError_t VMB_CALL VmbFeatureInvalidationRegister(const VmbHandle_t handle, const char *name, VmbInvalidationCallback callback, void *pUserContext)
VmbAccessModeType
Definition: VimbaC.h:123
static VimbaSystem _instance
Definition: VimbaSystem.h:363
#define LOG_FREE_TEXT(txt)
Definition: LoggerDefines.h:56
ConditionHelper m_cameraObserversConditionHelper
Definition: VimbaSystem.cpp:55
void * VmbHandle_t
VmbUint32_t major
VmbErrorType GetCameras(CameraPtrVector &cameras)
IMEXPORTC VmbError_t VMB_CALL VmbFeatureInvalidationUnregister(const VmbHandle_t handle, const char *name, VmbInvalidationCallback callback)
IMEXPORTC VmbError_t VMB_CALL VmbCameraInfoQuery(const char *idString, VmbCameraInfo_t *pInfo, VmbUint32_t sizeofCameraInfo)
VimbaSystem & operator=(const VimbaSystem &system)
IMEXPORT VmbErrorType RegisterInterfaceListObserver(const IInterfaceListObserverPtr &pObserver)
IMEXPORT VmbErrorType RegisterCameraFactory(const ICameraFactoryPtr &pCameraFactory)
const char * interfaceIdString
Definition: VimbaC.h:157
ConditionHelper m_interfaceObserversConditionHelper
Definition: VimbaSystem.cpp:57
std::map< T1, T2 > Map
Definition: Helper.h:48
VmbUint32_t patch
LockableMap< std::string, CameraPtr > m_cameras
Definition: VimbaSystem.cpp:49
void AppendCamToMap(VmbCameraInfo_t camInfo)
IMEXPORTC VmbError_t VMB_CALL VmbInterfacesList(VmbInterfaceInfo_t *pInterfaceInfo, VmbUint32_t listLength, VmbUint32_t *pNumFound, VmbUint32_t sizeofInterfaceInfo)
#define LOGGER_DEF
Definition: LoggerDefines.h:41
const char * serialString
Definition: VimbaC.h:155
IMEXPORTC VmbError_t VMB_CALL VmbStartup(void)
const char * modelName
Definition: VimbaC.h:154
IMEXPORT VmbErrorType UnregisterInterfaceListObserver(const IInterfaceListObserverPtr &pObserver)
IMEXPORTC VmbError_t VMB_CALL VmbFeatureEnumAsInt(const VmbHandle_t handle, const char *name, const char *value, VmbInt64_t *pIntVal)
IMEXPORT VmbErrorType QueryVersion(VmbVersionInfo_t &version)
Definition: VimbaSystem.cpp:84
#define SP_SET(sp, rawPtr)
#define SP_ISEQUAL(sp1, sp2)
VmbInterfaceType
Definition: VimbaC.h:107
void ExitReadLock(BasicLockable &rLockable)
ConditionHelper m_camerasConditionHelper
Definition: VimbaSystem.cpp:50
unsigned int VmbUint32_t
bool EnterReadLock(BasicLockable &rLockable)
IMEXPORTC VmbError_t VMB_CALL VmbFeatureEnumGet(const VmbHandle_t handle, const char *name, const char **pValue)
IMEXPORTC VmbError_t VMB_CALL VmbFeatureBoolGet(const VmbHandle_t handle, const char *name, VmbBool_t *pValue)
LockableVector< ICameraListObserverPtr > m_cameraObservers
Definition: VimbaSystem.cpp:54
IMEXPORTC VmbError_t VMB_CALL VmbCamerasList(VmbCameraInfo_t *pCameraInfo, VmbUint32_t listLength, VmbUint32_t *pNumFound, VmbUint32_t sizeofCameraInfo)
IMEXPORT VmbErrorType UnregisterCameraFactory()
IMEXPORTC void VMB_CALL VmbShutdown(void)
ConditionHelper m_interfacesConditionHelper
Definition: VimbaSystem.cpp:52
#define VIMBACPP_VERSION_MAJOR
Definition: Version.h:4
void SetHandle(const VmbHandle_t handle)
IMEXPORT VmbErrorType Shutdown()
IMEXPORT VmbErrorType UnregisterCameraListObserver(const ICameraListObserverPtr &pObserver)
static void VMB_CALL CameraDiscoveryCallback(const VmbHandle_t handle, const char *name, void *context)
#define VIMBACPP_VERSION_MINOR
Definition: Version.h:5
bool IsIPAddress(const char *pStrID)
ICameraFactoryPtr m_pCameraFactory
Definition: VimbaSystem.cpp:63
LockableVector< IInterfaceListObserverPtr > m_interfaceObservers
Definition: VimbaSystem.cpp:56
IMEXPORT VmbErrorType GetInterfaceByID(const char *pID, InterfacePtr &pInterface)
CameraPtr GetCameraPtrByHandle(const VmbHandle_t handle) const
IMEXPORT VmbErrorType OpenInterfaceByID(const char *pID, InterfacePtr &pInterface)


avt_vimba_camera
Author(s): Allied Vision Technologies, Miquel Massot
autogenerated on Fri Jun 2 2023 02:21:10