0

I am trying to port a C++ library to .NET, but I cannot get it to work and I don't understand what's wrong. The only big change I see is that in the C++ library with libusb, I have to set the alt interface setting to 1, but in LibUsbDotNet, this is not possible on Windows because WinUsbDevice doesn't have any setter for the alt interface, only a getter (which reports that it is 0, different from libusb).

Here is a minimal code, this fails on interruptEndpointWriter.Write, which returns Win32Error:

      foreach (UsbRegistry usbRegistry in UsbDevice.AllDevices)
            {
                if (usbRegistry.Pid == HELIOS_PID && usbRegistry.Vid == HELIOS_VID)
                {
                    if (usbRegistry.Open(out UsbDevice dac))
                    {
                        IUsbDevice libUsbDevice = dac as IUsbDevice;
                        if (libUsbDevice != null)
                        {
                            // (This code doesn't run because WinUsb devices do not implement these this interface, even though it's possible with C++ libusb)
                            libUsbDevice.ClaimInterface(0);
                            libUsbDevice.SetAltInterface(1);
                        }

                        using (var interruptEndpointWriter = dac.OpenEndpointWriter(WriteEndpointID.Ep06, EndpointType.Interrupt))
                        {
                            var errorCode = interruptEndpointWriter.Write(new byte[] { 0x03, 0 }, 16, out int writeTransferLength);
                            if (errorCode == ErrorCode.Ok && writeTransferLength == 2)
                            {
                                Console.WriteLine("OK");
                            }
                        }
                    }
                }
            }

Here is the original c++ code. This works fine.

      int result = libusb_init(NULL);

    libusb_device** devs;
    ssize_t cnt = libusb_get_device_list(NULL, &devs);
    if (cnt < 0)
        return (int)cnt;

    for (int i = 0; i < cnt; i++)
    {
        struct libusb_device_descriptor devDesc;
        int result = libusb_get_device_descriptor(devs[i], &devDesc);
        if (result < 0)
            continue;

        if ((devDesc.idProduct != HELIOS_PID) || (devDesc.idVendor != HELIOS_VID))
            continue;

        libusb_device_handle* devHandle;
        result = libusb_open(devs[i], &devHandle);
        if (result < 0)
            continue;

        result = libusb_claim_interface(devHandle, 0);
        if (result < 0)
            continue;

        result = libusb_set_interface_alt_setting(devHandle, 0, 1);
        if (result < 0)
            continue;

              int actualLength = 0;
           std::uint8_t ctrlBuffer[2] = { 0x03, 0 };
           int transferResult = libusb_interrupt_transfer(devHandle, 0x06, ctrlBuffer, 2, &actualLength, 16);
               if (transferResult == LIBUSB_SUCCESS)
              {
                     // ok
               }
    }

What am I doing wrong?

GrixM
  • 215
  • 2
  • 4
  • 20
  • Have you tried `ForceLibUsbWinBack = 1` ? Or enumerate `AllLibUsbDevices` instead of `AllUsbDevices` ? – Ben Voigt Mar 31 '21 at 21:14
  • @BenVoigt ForceLibUsbWinBack = 1 causes a build error, same as this: https://github.com/LibUsbDotNet/LibUsbDotNet/issues/67 I can try to find a workaround, thanks for the tip. AllLibUsbDevices, however, returns no devices. – GrixM Apr 01 '21 at 14:26

0 Answers0