getDetailedDeviceList method

List<UsbDeviceInfo> getDetailedDeviceList()

Implementation

List<UsbDeviceInfo> getDetailedDeviceList() {
  final deviceListPtr = calloc<Pointer<Pointer<libusb_device>>>();
  final count = _bindings.libusb_get_device_list(nullptr, deviceListPtr);

  List<UsbDeviceInfo> deviceInfoList = [];

  if (count > 0) {
    final deviceList = deviceListPtr.value;

    for (int i = 0; i < count; i++) {
      final device = deviceList[i];

      // Get device descriptor
      final deviceDescriptor = calloc<libusb_device_descriptor>();
      _bindings.libusb_get_device_descriptor(device, deviceDescriptor);

      // Get bus number and device address
      final busNumber = _bindings.libusb_get_bus_number(device);
      final deviceAddress = _bindings.libusb_get_device_address(device);

      // Try to open the device to get string information
      String? manufacturer;
      String? product;
      String? serialNumber;

      // Create a pointer for the device handle
      final handlePtr = calloc<Pointer<libusb_device_handle>>();

      // Try to open the device
      final result = _bindings.libusb_open(device, handlePtr);
      if (result != 0) {
        log("Error opening device: $result");
      } else {
        // Get the device handle
        final handle = handlePtr.value;
        log("Device opened successfully. ProductId: ${deviceDescriptor.ref.idProduct} - VendorId: ${deviceDescriptor.ref.idVendor}");
        // Read strings if available
        if (deviceDescriptor.ref.iManufacturer > 0) {
          manufacturer = _getStringDescriptor(
              handle, deviceDescriptor.ref.iManufacturer);
          //log("Manufacturer: $manufacturer");
        } else {
          //log("Device does not provide a manufacturer descriptor.");
        }

        if (deviceDescriptor.ref.iProduct > 0) {
          product =
              _getStringDescriptor(handle, deviceDescriptor.ref.iProduct);
        }

        if (deviceDescriptor.ref.iSerialNumber > 0) {
          serialNumber = _getStringDescriptor(
              handle, deviceDescriptor.ref.iSerialNumber);
        }

        // Close the device
        _bindings.libusb_close(handle);
      }

      // Free the handle pointer
      calloc.free(handlePtr);

      // Create an object with the device information
      final deviceInfo = UsbDeviceInfo(
        busNumber: busNumber,
        deviceAddress: deviceAddress,
        vendorId: deviceDescriptor.ref.idVendor,
        productId: deviceDescriptor.ref.idProduct,
        deviceClass: deviceDescriptor.ref.bDeviceClass,
        deviceSubClass: deviceDescriptor.ref.bDeviceSubClass,
        deviceProtocol: deviceDescriptor.ref.bDeviceProtocol,
        manufacturer: manufacturer,
        product: product,
        serialNumber: serialNumber,
      );

      log('Adding device: $deviceInfo');

      deviceInfoList.add(deviceInfo);

      // Free the device descriptor
      calloc.free(deviceDescriptor);
    }

    // Free the device list
    _bindings.libusb_free_device_list(deviceList, 1);
  }

  // Free the device list pointer
  calloc.free(deviceListPtr);
  return deviceInfoList;
}