Problems with writing to HID InputDevice

I’m currently developing a system that revolves around connecting to a HID Device. I’ve correctly set up the device to be a recognised InputDevice in Unity, fit with the IInputStateTypeInfo etc…
However, I’m running into a problem when it comes to sending over a command to the device using ExecuteCommand(). I’m trying to send over an array of 33 bytes, with the second one being the letter ‘C’ represented as a byte, and the following 3 bytes representing R, G, and B values (with the rest being 0s). I’ve been looking around virtually everywhere to piece together how to create this command and to create multiple iterations, but my implementation still fails to work.

An example of what I’m sending over:

00 53 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

I’m able to also use the HIDAPI Library to send over the bytes using DeviceIoControl. However, using hid_write fails due to an overlapping I/O error, if that’s relevant or not.

I may be able to fall back onto using DevicoIoControl if it’s also possible to obtain the HID device path of an InputDevice or some other representation of it

Here is my code for the command:

[StructLayout(LayoutKind.Explicit, Size = kSize)]
struct SetColorCommand : IInputDeviceCommandInfo
{
    public static FourCC Type => new FourCC('H', 'I', 'D', 'O');
    internal const int kSize = InputDeviceCommand.BaseCommandSize + 33;

    [FieldOffset(0)]
    public InputDeviceCommand baseCommand;
    [FieldOffset(InputDeviceCommand.BaseCommandSize)]
    public byte reportID;
    [FieldOffset(InputDeviceCommand.BaseCommandSize + 1)]
    public byte command; // The command code 'C'
    [FieldOffset(InputDeviceCommand.BaseCommandSize + 2)]
    public byte red; // The red value
    [FieldOffset(InputDeviceCommand.BaseCommandSize + 3)]
    public byte green; // The green value
    [FieldOffset(InputDeviceCommand.BaseCommandSize + 4)]
    public byte blue; // The blue value

    public FourCC typeStatic => Type;

    public static SetColorCommand Create(byte r, byte g, byte b)
    {
        return new SetColorCommand
        {
            baseCommand = new InputDeviceCommand(Type, kSize),
            command = Convert.ToByte('C'),
            red = r,
            green = g,
            blue = b
        };
    }
}

Maybe it’s some problem with my device?

@Texthead - It looks like you have set up your command structure correctly, but the problem could be related to how you’re sending the command using ExecuteCommand(). Make sure you’re using the correct method signature and executing the command on the right device. Here’s an example of how you should be using ExecuteCommand():

InputDevice device = ...; // The HID device you want to send the command to
SetColorCommand command = SetColorCommand.Create(255, 255, 0); // Yellow color, for example
InputDeviceCommand.GenericCommandBuffer buffer = new InputDeviceCommand.GenericCommandBuffer(command);
device.ExecuteCommand(ref buffer);

Additionally, you may want to check if your HID device supports sending commands using ExecuteCommand(). You could do this by sending a dummy command and checking if the result is successful.

If you still face issues, consider falling back to using DeviceIoControl with the HIDAPI Library. To obtain the HID device path of an InputDevice, you can use the description property provided by Unity’s Input System:

string devicePath = device.description.devicePath;

Keep in mind that the devicePath might not be the exact same representation used by the HIDAPI Library, and you might need to modify it to match the expected format. Make sure to test the path before using it in the HIDAPI calls.

Lastly, ensure that your device is properly configured to receive and process the commands you’re sending. Consult your device’s documentation to verify the command format and communication protocol.

Thanks for the help