IntergatedCircuits / HidSharp

HIDSharp is a multiplatform C# library for USB HID devices by James F. Bellinger
https://www.zer7.com/software/hidsharp
Other
121 stars 34 forks source link

Linux ubuntu crash when trying to open stream #12

Open michael-gabbay opened 2 years ago

michael-gabbay commented 2 years ago

Hi, I have code uses the library, I successfully located and got the HidDevice instance. after I tried to open a connection and get the stream object, the machine crushes and reboots. the line of code which crush is _stream = device.Open(); I tried to run as root (using sudo su) . in windows my code works just fine.

NOTE - I compiled it using dotnet publish -f net5.0 -r linux-x64 any idea?

benedekkupper commented 2 years ago
  1. Does this happen with a specific device, or with any kind of HID device?
  2. Does this happen with HidSharp library only, or the same happens when you try to open /dev/hidrawN another way (either directly, or using another HID library)?
michael-gabbay commented 2 years ago

HI I tried with a specific device based on FTDI. I did work using python library 'hidapi'.

michael-gabbay commented 2 years ago

*Update I took latest from GH and compiled it locally and ran with my application. I did manage to connect and send few Write commands, but in a specific buffer I got the machine crushed. the buffer I sent is

image

crush made on the function CommonWrite

in this part ` while (true) { if (outputReport.Done) { if (!outputReport.DoneOK) { throw new IOException("I/O output report failed."); } return; }

                            timeout = GetTimeout(startTime, writeTimeout);
                            _rch.ThrowIfClosed();
                            if (!Monitor.Wait(queue, timeout)) { throw new TimeoutException(); }
                        }
                    }
                    else
                    {
                        timeout = GetTimeout(startTime, writeTimeout);
                        _rch.ThrowIfClosed();
                        if (!Monitor.Wait(queue, timeout)) { throw new TimeoutException(); }
                    }
                }
            }`

I must mention that the code works smooth on Windows. I hope this information can help to point on an issue. and if you think it is not related to the library, any direction what might cause this? Thanks!

benedekkupper commented 2 years ago

By crash you mean it throws an exception? At which statement exactly?

michael-gabbay commented 2 years ago

It didn't throw an exception, just the OS freeze somewhere inside the the loop. I think it is on the line if (!Monitor.Wait(queue, timeout)) { throw new TimeoutException(); } but no exception where thrown. BTW the buffer that make it freeze is a read request message.

benedekkupper commented 2 years ago

BTW the buffer that make it freeze is a read request message.

Can you elaborate on this? You are trying to send a buffer, that is interpreted as a read request message by this specific HID device? Or are you trying to pass USB control setup packet over the HID endpoint (which is a very bad idea, and you shouldn't be surprised if it doesn't work)?

Please send me the (raw if possible) HID report descriptor of this device. You can use this library to get it. If the report descriptor contains report IDs, then you must put the report ID on the first byte of every message you send or receive. In this case 0xc2 seems very off.

michael-gabbay commented 2 years ago

You are trying to send a buffer, that is interpreted as a read request message by this specific HID device? Exactly.

about the device descriptor, it is a device under development in our organization, if it is relevant i'll update the HID report descriptor soon. Also I'll check also about your note regarding to the report ID.

Just to make sure I understand correctly, in the example above, if the first byte is not the report ID, I should put it the correct report ID on the first byte and then the message? like this? 0xRepotID, 0xC2, 0x35, 0x07, 0x02, 0x00

benedekkupper commented 2 years ago

Yes, correct, the report ID should be put in the first byte, as long as the HID device defines report IDs in its report descriptor. Even if it's not the case, I'd give it a try (in this case just put 0 at the first byte), as it might be that the OS/kernel driver still expects it.

michael-gabbay commented 2 years ago

HI, after deep investigation, I found out that issue was on kernel version, I changed the OS and the code do work! thank you for your support!

I did found a minor issue that the return value on Linux Get Feature report is different than Windows one. since the Linux stream pushes the ReportId to buffer[offset+1] I received result buffer with double reportID for example, get feature report 0xb0: Linux - returns [0xb0,0xb0,data,data,data,0x0,0x0...] Windows - returns [0xb0,data,data,data,0x0,0x0...]

I shifted left all the values in a simple loop, and now all works great on windows and Linux.