AdvancedEnumeration#

/***********************************************************************************
*
* Itala API - Copyright (C) 2022 Opto Engineering
*
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY SUFFERED BY LICENSE AS
* A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
***********************************************************************************/

/**
 * @example AdvancedEnumeration.cpp
 *
 * @brief "AdvancedEnumeration" provides a more granular approach to device
 * enumeration. It shows how devices can be enumerated under a single (or multiple)
 * specific network interface.
 * 
 * Suggested examples:
 * @see Grab.cpp
 */

 // Include the entire Itala API 
#include "ItalaApi/Itala.h"

// Include the GenICam library (for strings and exceptions)
#include "GenICam.h"

#define INDENT "\t"

void AdvancedEnumeration_Sample()
{
  std::cout << "***** AdvancedEnumeration example started. *****" << std::endl << std::endl;

  Itala::ISystem* pSystem = Itala::CreateSystem();

  // The goal is to open the first correctly configured device found for
  // each available interface. To do so, when a suitable device is found, it is
  // created and pushed to this vector.
  std::vector<Itala::IDevice*> openDevices;

  // Look for available network interfaces on the host and retrieve a list of
  // InterfaceInfo objects. Each info object uniquely identifies a detected
  // network interface and provides a set of useful information about it.
  Itala::InterfaceInfoList interfaceInfos = pSystem->EnumerateInterfaces();

  if (interfaceInfos.size() == 0)
    throw GENERIC_EXCEPTION("No network interfaces found. Example canceled.");

  // Let's print some data..
  std::cout << interfaceInfos.size() << " interfaces discovered." << std::endl << std::endl;

  // For every interface found, some information is printed. Note that
  // InterfaceInfo objects are nothing more than information containers having
  // no influence on the interface state. 
  // Each InterfaceInfo object is also used to enumerate the available devices
  // under the interface it uniquely identifies. Then, the information set of
  // each discovered device is printed.
  for (size_t i = 0; i < interfaceInfos.size(); i++)
  {
    Itala::InterfaceInfo currentInfo = interfaceInfos[i];
    std::cout << "Interface " << i << " is " << currentInfo.DisplayName() << std::endl;
    std::cout << INDENT << "MAC Address: " << Itala::MacAddressToString(currentInfo.MacAddress()) << std::endl;
    std::cout << INDENT << "IP Address: " << Itala::AddressToString(currentInfo.IpAddress()) << std::endl;
    std::cout << INDENT << "Subnet mask: " << Itala::AddressToString(currentInfo.SubnetMask()) << std::endl;

    // Discover the available devices under the current interface, with a time
    // limit of 700ms to show up.
    Itala::DeviceInfoList deviceInfosCurrentInterface = pSystem->EnumerateDevices(interfaceInfos[i], 700);

    // Flag used to determine if a device suitable for initialization have
    // already been found and initialized under the current interface.
    bool suitableDeviceFound = false;
    for (size_t j = 0; j < deviceInfosCurrentInterface.size(); j++)
    {
      std::cout << std::endl;
      // Print some information..
      Itala::DeviceInfo currentInfo = deviceInfosCurrentInterface[j];
      std::cout << INDENT << INDENT << "Device " << j << " is " << currentInfo.SerialNumber() << std::endl;
      std::cout << INDENT << INDENT << "Display name: " << currentInfo.DisplayName() << std::endl;
      std::cout << INDENT << INDENT << "MAC Address: " << Itala::MacAddressToString(currentInfo.MacAddress()) << std::endl;
      std::cout << INDENT << INDENT << "IP Address: " << Itala::AddressToString(currentInfo.IpAddress()) << std::endl;
      std::cout << INDENT << INDENT << "Model: " << currentInfo.Model() << std::endl;
      std::cout << INDENT << INDENT << "Access status: " << Itala::AccessStatusToString(currentInfo.AccessStatus()) << std::endl;

      // Open the current device if accessible and no other devices are open under the current
      // interface.
      if (!suitableDeviceFound)
      {
        if (currentInfo.AccessStatus() == Itala::DeviceAccessStatus::AvailableReadWrite)
        {
          openDevices.push_back(pSystem->CreateDevice(currentInfo));
          suitableDeviceFound = true;
          std::cout << INDENT << INDENT << "Device created! " << std::endl;
        }
        else
        {
          std::cout << INDENT << INDENT << "Device misconfigured, skipped. " << std::endl;
        }
      }
    }

    std::cout << std::endl;
  }

  // Do something with the devices..

  for (size_t i = 0; i < openDevices.size(); i++)
  {
    openDevices[i]->Dispose();
    openDevices[i] = nullptr;
    std::cout << "Device instance " << i << " disposed." << std::endl;
  }

  pSystem->Dispose();
  pSystem = nullptr;
  std::cout << "System instance disposed." << std::endl;
}

int main(int /*argc*/, char** /*argv*/)
{
  try
  {
    AdvancedEnumeration_Sample();
  }
  catch (GenICam::GenericException& e)
  {
    std::cout << e.what() << std::endl;
  }
}