Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows backend represents USB Composite Devices different than the other backends #287

Closed
JoergAtGithub opened this issue Jun 20, 2021 · 11 comments
Labels
documentation Improvements or additions to documentation Windows Related to Windows backend

Comments

@JoergAtGithub
Copy link
Contributor

To create cross-platform applications on top of HIDAPI, the API must behave the same on all platforms/backends. This is not the case for USB Composite Devices with multiple top level collections. The windows backend represents them as multiple HID devices, while othere backends represent them as one HID device.

This behavior was discussed and documented in the following unrelated issue here: #249 (comment)

A proper fix of the Windows backend would require, to group these virtual devices during device enumeration and represent them to the API as the same single HID device as on other platforms.

@Youw
Copy link
Member

Youw commented Jun 20, 2021

Please see my answed: #249 (comment)

@Youw
Copy link
Member

Youw commented Jun 20, 2021

The biggest problem is: even if you need to open only a single Top Level collection, HIDAPI probably would need to open all of the devices (and those might not be available) and check to which device send each report in runtime. Which is both a runtime overhead and so much complicated windows backend.

@mcuee mcuee added the Windows Related to Windows backend label Jun 20, 2021
@mcuee
Copy link
Member

mcuee commented Jun 20, 2021

@JoergAtGithub This is the exact problem with libusb windows backend which now becomes very complicated and lagging behind the Linux/macOS backend.

libusb/libusb#86 (comment)

Registering for notifications is trivial--it is fitting those notifications into the library that is "difficult". The whole situation is complicated by the fact that each interface of a composite device has its own driver and associated device interface path. The bookkeeping of mapping the individual interfaces to libusb's representation of a device while also maintaining the topology of the USB bus is why this is not in yet.

@mcuee
Copy link
Member

mcuee commented Jun 20, 2021

In the very beginning of libusb project, Pete Batard spent lots of effort to try to bridge Windows (individual interface) with Linux/macOS (whold device).

@mcuee
Copy link
Member

mcuee commented Jun 20, 2021

History posts: the following thread is worth reading.
https://marc.info/?l=libusb-devel&m=130903809709512&w=4

From Tim Roberts:

However, the bigger problem is that we are trying to shove a square peg
into a round hole. Libusb undeniably has a Linux heritage, and its
philosophy is strongly oriented towards the Linux way of doing things,
which are very different from the world of Windows devices. The concept
of "show me every device in the system so I can find mine," which is
found in the driver stack for virtually every Linux bus type, is foreign
to Windows. It does not scale well. It requires each
driver/application to have knowledge of the internal workings of its bus
-- information that it should not need to have. Windows abstracts all
that, so that a driver merely says "this is my device", and it's up to
PnP and the Device Manager to do the searching and the matching, and the
hotplug management. We are battling that abstraction.

I'm not saying I have an answer. There is an impedance mismatch here
that is, in large part, unresolvable. As long as libusb tries to
pretend that it is offers the Linux philosophy on Windows, there will be
ugliness underneath, and it's not going to get better.

You can read Pete's answer as well and he spent significant efforts to get libusb Windows working. But then you can see now it is not easy to maintain (Chris has done a good job here).

@JoergAtGithub
Copy link
Contributor Author

Let me add, that this issue is not important for myself, I just wanted to seperate the discussion from the Report Descriptor issue, which is important for me.

@mcuee
Copy link
Member

mcuee commented Jun 22, 2021

From #249 comments from Youw .

We're doing quite the opposite for other platforms: we report same device multiple times, so each such unique device has its own usage_page/usage filled up.

And it kind of bits off a general design of HIDAPI - to be as simple as possible and just be a thin proxy over an OS-specific API/implementation, just enough to keep the uniform API across different platforms. (libusb backend is kind-of the most complicated in this matter, as it practically implements its own USB HID driver, but let it be the only exception.)

@mcuee
Copy link
Member

mcuee commented Jun 22, 2021

And actually under Linux, I can see my USB Composite Device (Logitech Unifying Receiver) is also represented by multiple devices with hidapi hidraw backend.

mcuee@rpi400Ubuntu:~/build/libusb/hidapi$ ./hidtest/hidtest-hidraw 
hidapi test/example tool. Compiled with hidapi version 0.10.1, runtime version 0.10.1.
Compile-time version matches runtime version of hidapi.

Device Found
  type: 046d 101b
  path: /dev/hidraw5
  serial_number: 101b-ae-8a-0c-8c
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x2 (0x1)

Device Found
  type: 046d 101b
  path: /dev/hidraw5
  serial_number: 101b-ae-8a-0c-8c
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x1 (0x1)

Device Found
  type: 046d 101b
  path: /dev/hidraw5
  serial_number: 101b-ae-8a-0c-8c
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x1 (0xff00)

Device Found
  type: 046d 101b
  path: /dev/hidraw5
  serial_number: 101b-ae-8a-0c-8c
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x2 (0xff00)

Device Found
  type: 046d 101b
  path: /dev/hidraw5
  serial_number: 101b-ae-8a-0c-8c
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x4 (0xff00)

Device Found
  type: 046d 2008
  path: /dev/hidraw6
  serial_number: 2008-b6-b4-d3-96
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x6 (0x1)

Device Found
  type: 046d 2008
  path: /dev/hidraw6
  serial_number: 2008-b6-b4-d3-96
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x1 (0xc)

Device Found
  type: 046d 2008
  path: /dev/hidraw6
  serial_number: 2008-b6-b4-d3-96
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x80 (0x1)

Device Found
  type: 046d 2008
  path: /dev/hidraw6
  serial_number: 2008-b6-b4-d3-96
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x88 (0xffbc)

Device Found
  type: 046d 2008
  path: /dev/hidraw6
  serial_number: 2008-b6-b4-d3-96
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x1 (0xff00)

Device Found
  type: 046d 2008
  path: /dev/hidraw6
  serial_number: 2008-b6-b4-d3-96
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x2 (0xff00)

Device Found
  type: 046d 2008
  path: /dev/hidraw6
  serial_number: 2008-b6-b4-d3-96
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x4 (0xff00)

Device Found
  type: 046d c52b
  path: /dev/hidraw4
  serial_number: 
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x1 (0xff00)

Device Found
  type: 046d c52b
  path: /dev/hidraw4
  serial_number: 
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x2 (0xff00)

Device Found
  type: 046d c52b
  path: /dev/hidraw4
  serial_number: 
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x4 (0xff00)

Device Found
  type: 1915 1025
  path: /dev/hidraw3
  serial_number: 
  Manufacturer: ZY.Ltd
  Product:      ZY Control Mic
  Release:      173
  Interface:    2
  Usage (page): 0x6 (0x1)

Device Found
  type: 1915 1025
  path: /dev/hidraw2
  serial_number: 
  Manufacturer: ZY.Ltd
  Product:      ZY Control Mic
  Release:      173
  Interface:    3
  Usage (page): 0x2 (0x1)

Device Found
  type: 1915 1025
  path: /dev/hidraw2
  serial_number: 
  Manufacturer: ZY.Ltd
  Product:      ZY Control Mic
  Release:      173
  Interface:    3
  Usage (page): 0x1 (0x1)

Device Found
  type: 1915 1025
  path: /dev/hidraw2
  serial_number: 
  Manufacturer: ZY.Ltd
  Product:      ZY Control Mic
  Release:      173
  Interface:    3
  Usage (page): 0x1 (0xc)

Device Found
  type: 1915 1025
  path: /dev/hidraw2
  serial_number: 
  Manufacturer: ZY.Ltd
  Product:      ZY Control Mic
  Release:      173
  Interface:    3
  Usage (page): 0x80 (0x1)

Device Found
  type: 1915 1025
  path: /dev/hidraw2
  serial_number: 
  Manufacturer: ZY.Ltd
  Product:      ZY Control Mic
  Release:      173
  Interface:    3
  Usage (page): 0x0 (0xff00)

Device Found
  type: 04d9 0007
  path: /dev/hidraw1
  serial_number: 
  Manufacturer:  
  Product:      Raspberry Pi Internal Keyboard
  Release:      161
  Interface:    0
  Usage (page): 0x6 (0x1)

Device Found
  type: 04d9 0007
  path: /dev/hidraw0
  serial_number: 
  Manufacturer:  
  Product:      Raspberry Pi Internal Keyboard
  Release:      161
  Interface:    1
  Usage (page): 0x1 (0xc)

unable to open device

@mcuee
Copy link
Member

mcuee commented Jun 22, 2021

libusb backend is a bit different.

mcuee@rpi400Ubuntu:~/build/libusb/hidapi$ sudo ./hidtest/hidtest-libusb 
hidapi test/example tool. Compiled with hidapi version 0.10.1, runtime version 0.10.1.
Compile-time version matches runtime version of hidapi.

Device Found
  type: 04d9 0007
  path: 0001:0004:00
  serial_number: (null)
  Manufacturer:  
  Product:      Raspberry Pi Internal Keyboard
  Release:      161
  Interface:    0
  Usage (page): 0x0 (0x0)

Device Found
  type: 04d9 0007
  path: 0001:0004:01
  serial_number: (null)
  Manufacturer:  
  Product:      Raspberry Pi Internal Keyboard
  Release:      161
  Interface:    1
  Usage (page): 0x0 (0x0)

Device Found
  type: 1915 1025
  path: 0001:0007:02
  serial_number: (null)
  Manufacturer: ZY.Ltd
  Product:      ZY Control Mic
  Release:      173
  Interface:    2
  Usage (page): 0x0 (0x0)

Device Found
  type: 1915 1025
  path: 0001:0007:03
  serial_number: (null)
  Manufacturer: ZY.Ltd
  Product:      ZY Control Mic
  Release:      173
  Interface:    3
  Usage (page): 0x0 (0x0)

Device Found
  type: 046d c52b
  path: 0001:0005:00
  serial_number: (null)
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    0
  Usage (page): 0x0 (0x0)

Device Found
  type: 046d c52b
  path: 0001:0005:01
  serial_number: (null)
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    1
  Usage (page): 0x0 (0x0)

Device Found
  type: 046d c52b
  path: 0001:0005:02
  serial_number: (null)
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      2410
  Interface:    2
  Usage (page): 0x0 (0x0)

unable to open device

@Youw
Copy link
Member

Youw commented Jun 22, 2021

libusb backend is a bit different.

We haven't implemented the "split by usage_page/usage" for libusb yet.

@mcuee
Copy link
Member

mcuee commented Jul 13, 2021

I think we can close this issue now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation Windows Related to Windows backend
Projects
None yet
Development

No branches or pull requests

3 participants