AdvancedEnumeration#

#include <stdio.h>
#include <stdlib.h>
#include "ItalaApiC/ItalaC.h"

#define DEVICES_COUNT 5
#define STRING_LENGTH 200

ItalaError ErrorManager(ItalaError e) {
  size_t sizeMessage = 255;
  char* message = (char*)malloc(sizeof(char) * sizeMessage);
  ERR_GetLastErrorMessage(message, &sizeMessage);
  printf("\nITALA ERROR (%d):\t%s, %zu char", ERR_GetLastErrorCode(), message, sizeMessage);
  free(message);
  return e;
}

int main(int argc, char** argv) {
  printf("***** AdvancedEnumeration example started. *****\n");
  ItalaError error = ItalaErrorSuccess;
  error = SYS_Initialize();
  if (error) return ErrorManager(error);

  // 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 array.
  H_DEVICE openDevices[DEVICES_COUNT];
  size_t indexOpenDevicesFilled = 0;

  // Look for available network interfaces on the host.
  // Each info uniquely identifies a detected
  // network interface and provides a set of useful information about it.
  size_t interfacesInfoSize = 0;
  error = SYS_EnumerateInterfaces();
  if (error) return ErrorManager(error);
  error = SYS_GetInterfaceCount(&interfacesInfoSize);
  if (error) return ErrorManager(error);
  if (interfacesInfoSize == 0) {
    printf("No network interfaces found. Example canceled.\n");
    return ItalaErrorError;
  }

  // Let's print some data..
  printf("%zu interfaces discovered.\n\n", interfacesInfoSize);

  // For every interface found, some information is printed. Note that
  // InterfaceInfo are nothing more than information containers having
  // no influence on the interface state.
  // Each InterfaceInfo 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 < interfacesInfoSize; i++) {
    // Retrive the InterfaceInfo
    InterfaceInfo currentInterface;
    error = SYS_GetInterfaceByIndex(i, &currentInterface);
    printf("Interface %zu is %s\n", i, currentInterface.DisplayName);

    char macAddressString[STRING_LENGTH];
    size_t macAddressStringSize = STRING_LENGTH;
    error = STR_MacAddressToString(currentInterface.MacAddress, macAddressString,
                                   &macAddressStringSize);
    if (error) return ErrorManager(error);
    printf("\tMAC Address: %s\n", macAddressString);

    char ipAddressString[STRING_LENGTH];
    size_t ipAddressStringSize = STRING_LENGTH;
    error = STR_AddressToString(currentInterface.IpAddress, ipAddressString, &ipAddressStringSize);
    if (error) return ErrorManager(error);
    printf("\tIP Address: %s\n", ipAddressString);

    char subnetAddressString[STRING_LENGTH];
    size_t subnetAddressStringSize = STRING_LENGTH;
    error = STR_AddressToString(currentInterface.SubnetMask, subnetAddressString,
                                &subnetAddressStringSize);
    if (error) return ErrorManager(error);
    printf("\tSubnet mask: %s\n", subnetAddressString);

    // Discover the available devices under the current interface, with a time
    // limit of 700ms to show up.
    size_t devicesInfoSize = 0;
    error = SYS_EnumerateDevicesByInterface(currentInterface, 700);
    if (error) return ErrorManager(error);
    error = SYS_GetDeviceCount(&devicesInfoSize);
    if (error) return ErrorManager(error);

    // 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 < devicesInfoSize; j++) {
      // Retrive the DeviceInfo
      DeviceInfo currentDevice;
      error = SYS_GetDeviceByIndex(j, &currentDevice);

      printf("\n");
      printf("\t\tDevice: %zu is %s\n", j, currentDevice.SerialNumber);
      printf("\t\ttDisplay name: %s\n", currentDevice.DisplayName);

      char macAddressDevString[STRING_LENGTH];
      size_t macAddressDevStringSize = STRING_LENGTH;
      error = STR_MacAddressToString(currentDevice.MacAddress, macAddressDevString,
                                     &macAddressDevStringSize);
      if (error) return ErrorManager(error);
      printf("\t\tMAC Address: %s\n", macAddressDevString);

      char ipAddressDevString[STRING_LENGTH];
      size_t ipAddressDevStringSize = STRING_LENGTH;
      error =
          STR_AddressToString(currentDevice.IpAddress, ipAddressDevString, &ipAddressDevStringSize);
      if (error) return ErrorManager(error);
      printf("\t\tIP Address: %s\n", ipAddressDevString);

      printf("\t\tModel: %s\n", currentDevice.Model);
      printf("\t\tAccess status: %d\n", currentDevice.AccessStatus);

      // Open the current device if accessible and no other devices are open under the current
      // interface.
      if (!suitableDeviceFound) {
        if (currentDevice.AccessStatus == AvailableReadWrite) {
          H_DEVICE hDevice = NULL;
          error = SYS_CreateDevice(currentDevice, &hDevice);
          if (error) return ErrorManager(error);
          suitableDeviceFound = true;
          if (indexOpenDevicesFilled < DEVICES_COUNT) {
            openDevices[indexOpenDevicesFilled] = hDevice;
            indexOpenDevicesFilled++;
          } else {
            DEV_Dispose(hDevice);
            hDevice = NULL;
            printf("\t\tNot available space for store handle device. Device instance disposed.\n");
          }
          printf("\t\tDevice created.\n");
        } else {
          printf("\t\tDevice misconfigured, skipped.\n");
        }
      }
    }
    printf("\n");
  }

  // Do something with the devices...

  for (size_t i = 0; i < indexOpenDevicesFilled; i++) {
    error = DEV_Dispose(openDevices[i]);
    if (error) return ErrorManager(error);
    openDevices[i] = NULL;
    printf("Device instance %zu disposed.\n", i);
  }

  error = SYS_Dispose();
  if (error) return ErrorManager(error);
  printf("System instance disposed.\n");
  return 0;
}