1 (edited by KTrenholm 2019-05-29 13:06:01)

Topic: HIDSharp: Cannot open datastream, TryOpen() always returns false?

Hello all,

I'm fairly new to working with HID, especially from the host side.  I usually stick to microcontrollers but in this case I need to write an application to monitor the traffic from my microcontroller based HID devices for testing purposes.

I've dabbled in C# .NET so HIDSharp seems perfect for whipping something up quickly with WinForms.  It's strange to me that MS doesn't just have libraries in .NET for this but that's not my problem today.

I'm working with HIDSharp v2.0.2.0 attempting to monitor traffic from a composite HID device.  The composite device consists of a Keyboard with LEDs and a 3-Button mouse.  Both are HID.  Keyboard Codes on EP1, Mouse is on EP2.  The device works with the standard windows HID Mouse and Keyboard drivers.

First things first, I want to have a look at the keyboard traffic, since I have a few weird custom scancodes I need to ensure are coming through correctly.

I am able to find the device based on the VID/PID and confirm based on the name if I am seeing the Keyboard:

HidDevice KeyboardDevice;
HidStream KeyboardStream;

HidSharp.Reports.ReportDescriptor KeyboardRptDescriptor;
HidSharp.Reports.Report KeyboardReport;
HidSharp.Reports.Input.HidDeviceInputReceiver InputReceiver;

OpenConfiguration KbdConnectCfg = new OpenConfiguration();

if (d.VendorID == 0x0000 && d.ProductID == 0xA0A0)
{

    if (d.GetProductName() == "Keyboard")
    {
         KeyboardDevice = d;
         KeyboardRptDescriptor =KeyboardDevice.GetReportDescriptor();            
     }

}

if (KeyboardDevice != null)
{
    /*Device Found*/
    if (KeyboardDevice.TryOpen(out KeyboardStream))    //This always returns false
    {
        KeyboardReport = KeyboardRptDescriptor.InputReports.FirstOrDefault();
        keyboardBuffer = new byte[KeyboardDevice.GetMaxInputReportLength()];
        InputParser = KeyboardReport.DeviceItem.CreateDeviceItemInputParser();
        InputReceiver = KeyboardRptDescriptor.CreateHidDeviceInputReceiver();
        InputReceiver.Start(KeyboardStream);
        InputReceiver.Received -= new EventHandler(HidInputReceived);
        InputReceiver.Received += new EventHandler(HidInputReceived);
    } 
    else
    {
        rtb_hidLog.AppendText("Unable to open Datastream\r\n");
    }
                
}
else
{
    rtb_hidLog.AppendText("No Device Found\r\n");
}

The device is found with no problem and my KeyboardDevice object populates, but when I use TryOpen(), it always returns false and I don't get a datastream.  Might someone be able to point out why this might be, or maybe how to get some more information to determine why I can't open the datastream to this device?  The only thing I've really tried is opening the device with the Exclusive and Transient options set:

KbdConnectCfg.SetOption(OpenOption.Exclusive, true);
KbdConnectCfg.SetOption(OpenOption.Transient, true);
KeyboardDevice.TryOpen(KbdConnectCfg,out KeyboardStream)

but it appears to have no effect, I still cannot get the datastream.

I'm probably just missing something due to not really being familiar with HID from the host side.  If there's any additional information I can provide that would be of help, let me know.  Any thoughts are appreciated.

Thanks!

2

Re: HIDSharp: Cannot open datastream, TryOpen() always returns false?

Windows does not allow you to open keyboard HID devices for security reasons. Extra keys like volume controls, etc. often show up separately and can be opened. Those OpenOptions are a HIDSharp feature to allow coordinating opening the device between different HIDSharp instances on the same PC (the OS doesn't prevent opening HID devices twice).

3

Re: HIDSharp: Cannot open datastream, TryOpen() always returns false?

Oh wow, I had no idea about HID keyboards being essentially "Locked" in Windows like that. 

In my case there can be no separate device for these "extra" keys as the customer is expecting the presses from the HID keyboard device. 

It's USB codes 0x68 through to 0x77 I need to confirm are being sent, and  unfortunately the .NET Keypress/Keydown/KeyPreview events do not seem to trigger on these codes which is why I wanted to capture the bytes right from the keyboard.  I can confirm they are being sent via a USB Analyzer.  Perhaps I need to look past .NET then and see if I have any better luck.

Back to the drawing board I suppose. 

Thank you for the information, I don't think I would have ever figured that out!

4

Re: HIDSharp: Cannot open datastream, TryOpen() always returns false?

I am trying to connect to a barcode scanner and I'm having the same problem when I try to open the stream.

If I understand correctly, does this mean that I can't read the text produced by a bar code scanner with the HidSharp library because the scanner is interpreted as a keyboard and it is blocked by Windows?

Do I have any alternatives? Can I read the input buffer without "opening" the device?

5 (edited by KTrenholm 2019-06-03 13:03:21)

Re: HIDSharp: Cannot open datastream, TryOpen() always returns false?

regisls wrote:

I am trying to connect to a barcode scanner and I'm having the same problem when I try to open the stream.

If I understand correctly, does this mean that I can't read the text produced by a bar code scanner with the HidSharp library because the scanner is interpreted as a keyboard and it is blocked by Windows?

Do I have any alternatives? Can I read the input buffer without "opening" the device?

There are barcode scanners that act as a keyboard (Keyboard Wedge Device).  I'd drop a link here explaining but I don't appear to have permissions.

So it's possible that's the reason.  Do you have a manual/datasheet for your scanner that would confirm what the interface is?

You may not even need HIDSharp to read it.  You can probably use the KeyDown event in .NET if it's all Alphanumeric.

In my case the codes I need aren't seen by the keydown or keypreview events so I was hoping HIDSharp would just let me see the codes directly.

6

Re: HIDSharp: Cannot open datastream, TryOpen() always returns false?

I'm new to HID and I think I'm having the exact same problem with the aux buttons of my graphics tablet. Does it matter which driver I install in Device Manager? I've tried changing it from HID Keyboard to HID-compliant device and it still does not open the stream.

But with USB analysing software like USB Analyzer from eltima it seems to receive the input. I'm wondering why this program is able to receive the input, and HIDSharp isn't.

7

Re: HIDSharp: Cannot open datastream, TryOpen() always returns false?

var list = DeviceList.Local;
            var device = list.GetHidDevices(vendorId, productId).FirstOrDefault();
     
            using (var stream = device.Open())
                {
                    Console.WriteLine($"Listening to {device.GetFriendlyName()}...");
                    byte[] buffer = new byte[device.GetMaxInputReportLength()];
                    while (true)
                    {
                        int bytesRead = stream.Read(buffer);
                        if (bytesRead > 0)
                        {
                            // Process the keypress data from the buffer
                            // You'll need to interpret the data to determine which keys were pressed
                            Console.WriteLine($"Received {bytesRead} bytes: {BitConverter.ToString(buffer)}");
                        }
                    }
                }


getting 'Can't read from this device'

can anyone help please