macOS: implement kernel driver detach #911

macOS: implement kernel driver detach #911

 
Closed
wants to merge 5 commits into
 
+281 −71

Conversation 52 Commits 5 Checks 0

Conversation

@osy
 
 
Contributor

osy commented on Apr 24

It's a well known issue on macOS that you cannot use libusb to attach to an interface already claimed by an KEXT for exclusive access. The common workaround is to do sudo kextunload or inject a codeless KEXT. Both require admin permissions, and does not work for all devices on latest macOS. Additionally, SIP has to be disabled to inject a codeless KEXT, making it a pain to work with USB devices.

The original implementation relied on a new option but that has been superseded by a new implementation which uses the libusb_detach_kernel_driver() and libusb_set_auto_detach_kernel_driver() APIs. However there are a few caveats.

First, the libusb_detach_kernel_driver APIs expect a single USB interface to be detachable. On macOS, we can only "capture" an entire USB device (and force all interfaces to be released by any existing driver). To keep compatibility with existing code, we count the number of (successful) calls to libusb_detach_kernel_driver and when that number is balanced by libusb_attach_kernel_driver, the entire device is re-enumerated and the original kernel driver is allowed to re-attach.

Second, libusb_detach_kernel_driver is expected to be called after libusb_open (this doesn't seem to be documented but I see that is the usage from existing code). This is problematic because the effect of USBDeviceReEnumerate with kUSBReEnumerateCaptureDeviceMask doesn't seem to take place until after USBDeviceOpen. So we call darwin_restore_state to close and re-open the device.

Third, libusb_reset_device uses USBDeviceReEnumerate which will release the capture flag and allow the driver to re-claim the interfaces. I'm not sure what the reasoning for avoiding ResetDevice (I see a comment "from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate" but it seems to work fine in 10.15...). If we are currently capturing a USB device, then ResetDevice is used instead of USBDeviceReEnumerate.

kUSBReEnumerateCaptureDeviceMask requires either the application to be running as root OR the application has the entitlement com.apple.vm.device-access AND the user has accepted the authorization for the capture with IOServiceAuthorize. To get the second part to work, we detect when the entitlement com.apple.vm.device-access is available and then call IOServiceAuthorize in darwin_detach_kernel_driver before darwin_reenumerate_device. However, as the authorization decision is cached in the plugin's start() call, it is necessary to stop and start the USB plugin again.

I've only tested this with hidtest (modified to use libusb on OSX) and with libusbredir (in spice-gtk). More testing is needed specifically with calling libusb_detach_kernel_driver on multiple interfaces. On calling libusb_detach_kernel_driver before libusb_open or libusb_attach_kernel_driver after libusb_close (I'm not sure if this should be a supported use case but the APIs don't prescribe the usage order...). I'm also not sure why ResetDevice was avoided so there may be subtle issues in darwin_reset_device. Finally, there should be some testing with multiple calls to libusb_open/libusb_close.

 
 
@mcuee mcuee added the macOS label on Apr 26
 
 
Closed
@hjelmn
 
 
Member

hjelmn commented on Apr 26

The issue is that for since time ResetDevice has been a noop in macOS. If I remember correctly we even confirmed that with a wireshark. Do we know if that has changed? If not we may need to figure out how to make this work with reenumerate.

hjelmn
 
 
 
 
hjelmn
 
 
 

if (dpriv->capture_count > 0) {
/* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
 
 
Member

@hjelmn hjelmn on Apr 30

This is ok for now but if possible it would be better if we can be consistent and always re-enumerate the device. This ensures that the device is actually reset. I am surprised we can't just specify capture again on reset but I have to assume you have already tried this. We may want to call this out somewhere in the docs so that users are aware that reset may not actually reset when capturing a device.

 
 
Contributor Author

@osy osy on May 1

Yup I tried that the main problem is if you need authorization (it’s not running as root and it shows the user a pop-up to approve the device), it will need it again after calling re-enumerate (with or without the release flag). This means the user needs to click “approve” after every re-enum.

Perhaps someone with a usb sniffer can check the behaviour of the reset call again?

@hjelmn
 
 
Member

hjelmn commented on Apr 30

LGTM. Please squash into a minimal set of commits and we will merge.

@osy
 
 
Contributor Author

osy commented on May 3

LGTM. Please squash into a minimal set of commits and we will merge.

Can we wait for someone to test USB reset with a sniffer?

 
 
osy added 5 commits 7 months ago
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@osy osy force-pushed the macos-force-capture branch from 2cc9c38 to e31c9ad 7 months ago
@programmingkidx
 
 
 

programmingkidx commented on May 16

I use libusb with a computer emulator called QEMU. I was able to test out the changes in the above patches. They do work. I was able to listen to MP3 files in several of my VM's using a real attached USB sound card. Good job everyone.

 
 
 
@hjelmn hjelmn closed this in 00688d0 on May 17
@osy
 
 
Contributor Author

osy commented on May 17

 

@hjelmn was USB reset tested? I’m still having some issues that I think might be related to reset but I don’t have any sniffer to test.

I’ve been locally experimenting with a patch that implements the reenumeration but the kernel drivers always reattach as soon as you re-enumerate and then you can re-capture but there is a period of time when the kernel drivers take control and can possibly modify the device state. I’m still not sure how to do a “clean” reset while keeping capture state.

@hjelmn
 
 
Member

hjelmn commented on May 17

@hjelmn was USB reset tested? I’m still having some issues that I think might be related to reset but I don’t have any sniffer to test.

I’ve been locally experimenting with a patch that implements the reenumeration but the kernel drivers always reattach as soon as you re-enumerate and then you can re-capture but there is a period of time when the kernel drivers take control and can possibly modify the device state. I’m still not sure how to do a “clean” reset while keeping capture state.

I would like to get these changes up in a 1.0.25 RC so a wider audience can start testing. I don't have the equipment to test that reset works as expected. If there is a known issue we can add a known issues list while a fix is developed. Given how capture works I don't think we can easily fix it if it is broken.

@supercairos
 
 
 

supercairos commented on May 18

I tested this with various devices (gamepads, mouse, kbd, camera, USB Disk, ...) and it works like a charm! Thanks a lot.

 
 
Closed
 
 
Open
 
 
Closed
 
 
Closed
@mcuee
 
 
Member

mcuee commented on Jul 5

This pull request seems to cause regression as mentioned in #945 .

 
 
Open
 
 
Open
@mcuee
 
 
Member

mcuee commented on Aug 8

 

#945 has been fixed. Another improvement #961 has been merged as well.

@mcuee
 
 
Member

mcuee commented on Aug 8

 

Ref: Device Capture
https://developer.apple.com/documentation/iousbhost/iousbhostobjectinitoptions/3181672-devicecapture

Declaration
static var deviceCapture: IOUSBHostObjectInitOptions { get }

Discussion
Callers must have either the com.apple.vm.device-access entitlement and the IOUSBHostDevice object from IOServiceAuthorize(::) authorization, or have root privileges. Using this option terminates all clients and drivers of the IOUSBHostDevice and associated IOUSBHostInterface clients, as well as the caller. Upon destroy() of the IOUSBHostDevice, the device resets and IOUSBHostInterface reregisters for IOKit matching.

@mcuee
 
 
Member

mcuee commented on Aug 8

Ref:
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_vm_device-access

Property List Key: com.apple.vm.device-access
A Boolean value that indicates whether the app captures USB devices and uses them in the guest-operating system.
Availability

Discussion
The entitlement is required to use the IOUSBHost APIs for USB device capture.

@mcuee
 
 
Member

mcuee commented on Aug 8

https://developer.apple.com/documentation/bundleresources/entitlements

Discussion
An entitlement is a right or privilege that grants an executable particular capabilities. For example, an app needs the HomeKit Entitlement — along with explicit user consent — to access a user’s home automation network. An app stores its entitlements as key-value pairs embedded in the code signature of its binary executable.

You configure entitlements for your app by declaring capabilities for a target in Xcode. Xcode records capabilities that you add in a property list file with the .entitlements extension. You can also edit the entitlements file directly. When code signing your app, Xcode combines the entitlements file, information from your developer account, and other project information to apply a final set of entitlements to your app.

@mcuee
 
 
Member

mcuee commented on Aug 8

@osy Could you provide more details how you modify hidtest (HIDAPI test application) to use libusb and use this new feature under macOS? Thanks.

 
@mcuee
 
 
Member

mcuee commented on Aug 8

 

After changing that line, it still does not work, strange.

[ 0.029417] [00015301] libusb: debug [darwin_detach_kernel_driver] attempting to detach kernel driver from device
[ 0.029449] [00015301] libusb: info [darwin_detach_kernel_driver] no capture entitlements. can not detach the kernel driver for this device
[ 0.032554] [00015301] libusb: warning [darwin_detach_kernel_driver] IOServiceAuthorize: unknown error (0xe00002c6)

Full debug log.

click to expand
@osy
 
 
Contributor Author

osy commented on Aug 8

You can't call IOServiceAuthorize either without the entitlement.

@mcuee
 
 
Member

mcuee commented on Aug 8

You can't call IOServiceAuthorize either without the entitlement.

Even with sudo? Supposed that should work.

@osy
 
 
Contributor Author

osy commented on Aug 8

It's because IOServiceAuthorize launches a GUI popup. I don't think it works with sudo.

 
@mcuee
 
 
Member

mcuee commented on Aug 8

@osy Still I am not 100% sure if this is true. It seems to me claiming interface can work with your pull request.

libusb on  HEAD (6a902c3) [?] ❯ sudo ./examples/xusb 04d8:003f
Password:
Using libusb v1.0.24.11613

Opening device 04D8:003F...

Reading device descriptor:
            length: 18
      device class: 0
               S/N: 0
           VID:PID: 04D8:003F
         bcdDevice: 0002
   iMan:iProd:iSer: 1:2:0
          nb confs: 1

Reading BOS descriptor: no descriptor

Reading first configuration descriptor:
             nb interfaces: 1
              interface[0]: id = 0
interface[0].altsetting[0]: num endpoints = 2
   Class.SubClass.Protocol: 03.00.00
       endpoint[0].address: 81
           max packet size: 0040
          polling interval: 01
       endpoint[1].address: 01
           max packet size: 0040
          polling interval: 01

Claiming interface 0...

Reading string descriptors:
   String (0x01): "Microchip Technology Inc."
   String (0x02): "Simple HID Device Demo"

Releasing interface 0...
libusb: error [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
Closing device...
libusb: warning [libusb_exit] device 2.6 still referenced
libusb: warning [libusb_exit] device 2.4 still referenced
libusb: warning [libusb_exit] device 2.2 still referenced
@mcuee
 
 
Member

mcuee commented on Aug 8

Running with sudo.


Claiming interface 0...
[ 0.005855] [00018e80] libusb: debug [libusb_claim_interface] interface 0
[ 0.009932] [00018e80] libusb: debug [darwin_reenumerate_device] darwin/reenumerate_device: restoring state...
[ 0.009943] [00018e80] libusb: debug [darwin_open] device open for access
[ 0.009944] [00018e80] libusb: debug [darwin_restore_state] darwin/restore_state: reclaiming interfaces
[ 0.009945] [00018e80] libusb: debug [darwin_restore_state] darwin/restore_state: device state restored
[ 0.010311] [00018e80] libusb: debug [get_endpoints] building table of endpoints.
[ 0.010318] [00018e80] libusb: debug [get_endpoints] interface: 0 pipe 1: dir: 1 number: 1
[ 0.010321] [00018e80] libusb: debug [get_endpoints] interface: 0 pipe 2: dir: 0 number: 1
[ 0.010333] [00018e80] libusb: debug [darwin_claim_interface] interface opened

Full debug log.

click to expand
@mcuee
 
 
Member

mcuee commented on Aug 8

So sudo does work with commit 6a902c3

Late commits somehow make running sudo not working anymore.

Here is with a USB Flash disk.

libusb on  HEAD (6a902c3) [?] ❯ sudo ./examples/xusb 0781:5595 
Using libusb v1.0.24.11613

Opening device 0781:5595...

Reading device descriptor:
            length: 18
      device class: 0
               S/N: 3
           VID:PID: 0781:5595
         bcdDevice: 0100
   iMan:iProd:iSer: 1:2:3
          nb confs: 1

Reading BOS descriptor: 2 caps
    USB 2.0 extension:
      attributes             : 02
    USB 3.0 capabilities:
      attributes             : 00
      supported speeds       : 000E
      supported functionality: 01

Reading first configuration descriptor:
             nb interfaces: 1
              interface[0]: id = 0
interface[0].altsetting[0]: num endpoints = 2
   Class.SubClass.Protocol: 08.06.50
       endpoint[0].address: 81
           max packet size: 0200
          polling interval: 00
       endpoint[1].address: 02
           max packet size: 0200
          polling interval: 00

Claiming interface 0...

Reading string descriptors:
   String (0x01): "SanDisk"
   String (0x02): "Ultra USB 3.0"
   String (0x03): "0101e6a66ef16708e075e3c49050ce3f9585a63516548d5130a8c0815d0296f0a86e0000000000000000000062f48ad4ff1b71009555810739a8d6f9"
Reading Max LUN:
   Max LUN = 0
Sending Inquiry:
   sent 6 CDB bytes
   received 36 bytes
   VID:PID:REV " SanDisk":"Ultra US":"1.00"
   Mass Storage Status: 00 (Success)
Reading Capacity:
   sent 10 CDB bytes
   received 8 bytes
   Max LBA: 0729BFFF, Block Size: 00000200 (57.30 GB)
   Mass Storage Status: 00 (Success)
Attempting to read 512 bytes:
   sent 10 CDB bytes
   READ: received 512 bytes
   Mass Storage Status: 00 (Success)

  00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000080  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000a0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000b0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000c0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000d0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000e0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000f0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000100  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000110  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000120  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000130  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000140  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000150  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000160  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000170  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000180  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000190  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000001a0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000001b0  00 00 00 00 00 00 00 00 3b e2 ae 66 00 00 00 00  ........;..f....
  000001c0  21 00 0c fe ff ff 20 00 00 00 e0 bf 29 07 00 00  !..... .....)...
  000001d0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000001e0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000001f0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa  ..............U.

Releasing interface 0...
libusb: error [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
Closing device...
libusb: warning [libusb_exit] device 2.6 still referenced
libusb: warning [libusb_exit] device 2.4 still referenced
libusb: warning [libusb_exit] device 2.2 still referenced
@mcuee
 
 
Member

mcuee commented on Aug 8

I can see macOS complained about ejecting the disk (so the kernel driver detach is working). And the disk disappeared from my desktop. Later the disk reappears (so the kernel driver re-attach seems to work as well).

BTW, ignore the error message after releasing interface, that was fixed later.

@hjelmn
 
 
Member

hjelmn commented on Aug 8

Think I know how I broke it. Fixing...

@hjelmn
 
 
Member

hjelmn commented on Aug 8

 

Ok. Should work again...

./examples/xusb 05ac:024f
Using libusb v1.0.24.11647

Opening device 05AC:024F...

Reading device descriptor:
            length: 18
      device class: 0
               S/N: 0
           VID:PID: 05AC:024F
         bcdDevice: 0105
   iMan:iProd:iSer: 1:2:0
          nb confs: 1

Reading BOS descriptor: no descriptor

Reading first configuration descriptor:
             nb interfaces: 2
              interface[0]: id = 0
interface[0].altsetting[0]: num endpoints = 1
   Class.SubClass.Protocol: 03.01.01
       endpoint[0].address: 81
           max packet size: 0010
          polling interval: 01
              interface[1]: id = 1
interface[1].altsetting[0]: num endpoints = 1
   Class.SubClass.Protocol: 03.01.02
       endpoint[0].address: 82
           max packet size: 0010
          polling interval: 01

Kernel driver attached for interface 0: 1

Claiming interface 0...
libusb: info [darwin_detach_kernel_driver] no capture entitlements. can not detach the kernel driver for this device
libusb: info [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
   Failed.

Kernel driver attached for interface 1: 1

Claiming interface 1...
libusb: info [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
   Failed.

Reading string descriptors:
   String (0x01): "Keychron"
   String (0x02): "Keychron K1"

Releasing interface 0...
Releasing interface 1...
Closing device...
sudo ./examples/xusb 05ac:024f
Using libusb v1.0.24.11647

Opening device 05AC:024F...

Reading device descriptor:
            length: 18
      device class: 0
               S/N: 0
           VID:PID: 05AC:024F
         bcdDevice: 0105
   iMan:iProd:iSer: 1:2:0
          nb confs: 1

Reading BOS descriptor: no descriptor

Reading first configuration descriptor:
             nb interfaces: 2
              interface[0]: id = 0
interface[0].altsetting[0]: num endpoints = 1
   Class.SubClass.Protocol: 03.01.01
       endpoint[0].address: 81
           max packet size: 0010
          polling interval: 01
              interface[1]: id = 1
interface[1].altsetting[0]: num endpoints = 1
   Class.SubClass.Protocol: 03.01.02
       endpoint[0].address: 82
           max packet size: 0010
          polling interval: 01

Kernel driver attached for interface 0: 1

Claiming interface 0...
libusb: info [darwin_detach_kernel_driver] no capture entitlements. can not detach the kernel driver for this device

Kernel driver attached for interface 1: 0

Claiming interface 1...

Reading string descriptors:
   String (0x01): "Keychron"
   String (0x02): "Keychron K1"

Releasing interface 0...
libusb: info [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
libusb: info [darwin_capture_release_interface] on attempt to reattach the kernel driver got ret=-5
Releasing interface 1...
Closing device...

 
@mcuee
 
 
Member

mcuee commented on Aug 8

Yes latest git head is good.

libusb on  master [?] took 9s ❯ sudo ./examples/xusb 0781:5595
Password:
Using libusb v1.0.24.11648

Opening device 0781:5595...

Reading device descriptor:
            length: 18
      device class: 0
               S/N: 3
           VID:PID: 0781:5595
         bcdDevice: 0100
   iMan:iProd:iSer: 1:2:3
          nb confs: 1

Reading BOS descriptor: 2 caps
    USB 2.0 extension:
      attributes             : 02
    USB 3.0 capabilities:
      attributes             : 00
      supported speeds       : 000E
      supported functionality: 01

Reading first configuration descriptor:
             nb interfaces: 1
              interface[0]: id = 0
interface[0].altsetting[0]: num endpoints = 2
   Class.SubClass.Protocol: 08.06.50
       endpoint[0].address: 81
           max packet size: 0200
          polling interval: 00
       endpoint[1].address: 02
           max packet size: 0200
          polling interval: 00

Kernel driver attached for interface 0: 1

Claiming interface 0...
libusb: info [darwin_detach_kernel_driver] no capture entitlements. may not be able to detach the kernel driver for this device

Reading string descriptors:
   String (0x01): "SanDisk"
   String (0x02): "Ultra USB 3.0"
   String (0x03): "0101e6a66ef16708e075e3c49050ce3f9585a63516548d5130a8c0815d0296f0a86e0000000000000000000062f48ad4ff1b71009555810739a8d6f9"
Reading Max LUN:
   Max LUN = 0
Sending Inquiry:
   sent 6 CDB bytes
   received 36 bytes
   VID:PID:REV " SanDisk":"Ultra US":"1.00"
   Mass Storage Status: 00 (Success)
Reading Capacity:
   sent 10 CDB bytes
   received 8 bytes
   Max LBA: 0729BFFF, Block Size: 00000200 (57.30 GB)
   Mass Storage Status: 00 (Success)
Attempting to read 512 bytes:
   sent 10 CDB bytes
   READ: received 512 bytes
   Mass Storage Status: 00 (Success)

  00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000080  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000a0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000b0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000c0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000d0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000e0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000000f0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000100  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000110  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000120  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000130  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000140  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000150  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000160  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000170  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000180  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00000190  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000001a0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000001b0  00 00 00 00 00 00 00 00 3b e2 ae 66 00 00 00 00  ........;..f....
  000001c0  21 00 0c fe ff ff 20 00 00 00 e0 bf 29 07 00 00  !..... .....)...
  000001d0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000001e0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  000001f0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa  ..............U.

Releasing interface 0...
libusb: info [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
libusb: info [darwin_capture_release_interface] on attempt to reattach the kernel driver got ret=-5
Closing device...

@mcuee
 
 
Member

mcuee commented on Aug 8

And hidtest works as well.

hidapi_test/libusb on  master [!?] ❯ sudo ./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: 04d8 003f
  path: 0002:001e:00
  serial_number: (null)
  Manufacturer: Microchip Technology Inc.
  Product:      Simple HID Device Demo
  Release:      2
  Interface:    0
  Usage (page): 0x0 (0x0)

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

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

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

Device Found
  type: 047f c025
  path: 0002:0008:03
  serial_number: CB13A3E40E8E47D6A40769C27E90A38E
  Manufacturer: Plantronics
  Product:      Plantronics C320-M
  Release:      135
  Interface:    3
  Usage (page): 0x0 (0x0)

Manufacturer String: Microchip Technology Inc.
Product String: Simple HID Device Demo
Serial Number String: (208) ?
Indexed String 1: Microchip Technology Inc.
Unable to send a feature report.
Unable to get a feature report.
hid_error is not implemented yetwaiting...
waiting...
waiting...
Unable to read()
Data read:
@mcuee
 
 
Member

mcuee commented on Aug 8

And it is also okay with USB Composite Devices.


libusb on  master [!+?] took 5s ❯ sudo ./examples/xusb 046d:c52b
Password:
Using libusb v1.0.24.11648

Opening device 046D:C52B...

Reading device descriptor:
            length: 18
      device class: 0
               S/N: 0
           VID:PID: 046D:C52B
         bcdDevice: 2410
   iMan:iProd:iSer: 1:2:0
          nb confs: 1

Reading BOS descriptor: no descriptor

Reading first configuration descriptor:
             nb interfaces: 3
              interface[0]: id = 0
interface[0].altsetting[0]: num endpoints = 1
   Class.SubClass.Protocol: 03.01.01
       endpoint[0].address: 81
           max packet size: 0008
          polling interval: 08
              interface[1]: id = 1
interface[1].altsetting[0]: num endpoints = 1
   Class.SubClass.Protocol: 03.01.02
       endpoint[0].address: 82
           max packet size: 0008
          polling interval: 02
              interface[2]: id = 2
interface[2].altsetting[0]: num endpoints = 1
   Class.SubClass.Protocol: 03.00.00
       endpoint[0].address: 83
           max packet size: 0020
          polling interval: 02

Kernel driver attached for interface 0: 1

Claiming interface 0...
libusb: info [darwin_detach_kernel_driver] no capture entitlements. may not be able to detach the kernel driver for this device

Kernel driver attached for interface 1: 0

Claiming interface 1...

Kernel driver attached for interface 2: 0

Claiming interface 2...

Reading string descriptors:
   String (0x01): "Logitech"
   String (0x02): "USB Receiver"

Releasing interface 0...
libusb: info [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
libusb: info [darwin_capture_release_interface] on attempt to reattach the kernel driver got ret=-5
Releasing interface 1...
Releasing interface 2...
Closing device...
@mcuee
 
 
Member

mcuee commented on Aug 8

@hjelmn @osy
BTW, initially I thought there is a regression for the libusb_kernel_driver_active (#959) in the above output since there is no driver attached to interface 1/2. However, I realized that the driver detach is per device and not per interface.

We may need to improve the documentation here.

The other thing is to document how to get the entitlement (I am not using Xcode so I have not tried it myself).

@osy
 
 
Contributor Author

osy commented on Aug 8

There actually isn’t a documented way. I had to manually contact Apple to get them. They are included with the VM entitlements and there’s no signup form or anything. You just have to purchase an Apple Developer membership and contact their technical support.

 
@mcuee
 
 
Member

mcuee commented on Aug 8

There actually isn’t a documented way. I had to manually contact Apple to get them. They are included with the VM entitlements and there’s no signup form or anything. You just have to purchase an Apple Developer membership and contact their technical support.

I see. Thanks. Maybe I will just mention this in the wiki.

@mcuee
 
 
Member

mcuee commented on Aug 8

@osy I think the Developer provisioning profile process should be similar to the following. Is that correct?
https://github.com/pqrs-org/Karabiner-DriverKit-VirtualHIDDevice

@osy
 
 
Contributor Author

osy commented on Aug 8

You need com.apple.vm.device-access and if you search across the web for how to obtain it, you'll find there's no page on Apple's site to do so.

@mcuee
 
 
Member

mcuee commented on Aug 8

You need com.apple.vm.device-access and if you search across the web for how to obtain it, you'll find there's no page on Apple's site to do so.

A bit of mentioning in Apple websites. But I agree it is not well documented.
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_vm_device-access

https://developer.apple.com/documentation/bundleresources/entitlements
You configure entitlements for your app by declaring capabilities for a target in Xcode. Xcode records capabilities that you add in a property list file with the .entitlements extension. You can also edit the entitlements file directly. When code signing your app, Xcode combines the entitlements file, information from your developer account, and other project information to apply a final set of entitlements to your app.

 
 
Open
@hjelmn
 
 
Member

hjelmn commented on Aug 8

Improved the error message a bit:

Claiming interface 0...
libusb: info [darwin_detach_kernel_driver] no capture entitlements. may not be able to detach the kernel driver for this device
libusb: warning [darwin_detach_kernel_driver] device capture requires either an entitlement (com.apple.vm.device-access) or root privilege
libusb: info [darwin_capture_claim_interface] failed to auto-detach the kernel driver for this device, ret=-3
libusb: info [darwin_claim_interface] USBInterfaceOpen: another process has device opened for exclusive access
   Failed.
 
@mcuee
 
 
Member

mcuee commented on Aug 9

Yes, the new warning and info message are good.

 
 
Open
 
 
Open
 
 
@mcuee mcuee mentioned this pull request on Aug 30
Open
 
 
Open
@llinshenzhen
 
 
 

llinshenzhen commented 29 days ago

Yes, the new warning and info message are good.

It's took me a while for reading history above, and a little bit confused. Is there any solution? macOS12 has released its official version, the libuvc still can't access camera anyhow. I did use the com.apple.vm.device-access in the entitlements.

 
 
Open
@mcuee
 
 
Member

mcuee commented 28 days ago

 

Yes, the new warning and info message are good.

It's took me a while for reading history above, and a little bit confused. Is there any solution? macOS12 has released its official version, the libuvc still can't access camera anyhow. I did use the com.apple.vm.device-access in the entitlements.

@llinshenzhen
I will create a new ticket on this topic. Please continue in the new ticket here, thanks.
#1014

@mcuee
 
 
Member

mcuee commented 28 days ago

This is probably not a good place to continue the discussion as it has already been closed.

posted @ 2021-11-27 11:13  jiftle  阅读(752)  评论(0编辑  收藏  举报