USBDriverKit driver doesn't match, instead uses standard HID drivers

I'm trying to built a USBDriverKit driver on the Mac. The driver loads properly but when my device is inserted the driver is ignored and instead the com.apple.AppleUserHIDDrivers driver is loaded. I do not understand what is causing this. The device both have USB and HID cababilities but I want it to work with USBDriverKit so that the driver can be used on the Ipad as well.

How can I get the driver to match properly?

Entitlements:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>com.apple.developer.driverkit</key>
  <true/>
    <key>com.apple.developer.driverkit.transport.usb</key>
    <array>
        <dict>
            <key>idVendor</key>
            <integer>1240</integer>
        </dict>
    </array>
  <key>com.apple.developer.driverkit.userclient-access</key>
  <true/>
  <key>com.apple.security.app-sandbox</key>
  <true/>
</dict>
</plist>

Info.plist:

...
<dict>
  <key>CFBundleIdentifier</key>
  <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  <key>IOKitPersonalities</key>
  <dict>
    <key>ClickerDriver</key>
    <dict>
      <key>IOKitDebug</key>
      <string>65535</string>
      <key>CFBundleIdentifier</key>
      <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
      <key>IOClass</key>
      <string>IOUserService</string>
      <key>IOProviderClass</key>
      <string>IOUSBHostInterface</string>
      <key>IOUserClass</key>
      <string>ClickerDriver</string>
      <key>IOUserServerName</key>
      <string>example.Clicker.driver</string>
      <key>bInterfaceClass</key>
      <string>3</string>
      <key>bInterfaceSubClass</key>
      <string>0</string>
      <key>bConfigurationValue</key>
      <string>1</string>
      <key>bInterfaceNumber</key>
      <string>0</string>
      <key>idProduct</key>
      <integer>63</integer>
      <key>idVendor</key>
      <integer>1240</integer>
      <key>UserClientProperties</key>
      <dict>
        <key>IOClass</key>
        <string>IOUserUserClient</string>
        <key>IOUserClass</key>
        <string>ClickerDriverUserClient</string>
      </dict>
    </dict>
  </dict>
  <key>OSBundleUsageDescription</key>
  <string>The app interprets monitors key presses. </string>
</dict>
</plist>

Output of ioreg -b -n "Simple HID Device Demo" -r -l is attacheded.

Replies

I think your IOKitPersonalities/ClickerDriver dictionary is overly specific. See https://developer.apple.com/library/archive/qa/qa1076/_index.html, which itself is linked from https://developer.apple.com/news/?id=zk5xdwbn.

Thanks for the reply. Yes I see that, but when I try with the following combinations I get the same result:

This should match at 100,000 instead com.apple.AppleUserHIDDrivers that matches at 50,001

<key>idVendor</key>
<integer>1240</integer>
<key>idProduct</key>
<integer>63</integer>
<key>bInterfaceNumber</key>
<string>0</string>
<key>bConfigurationValue</key>
<string>1</string>
<key>bcdDevice</key>
<string>2</string>

This should match at 90,000 instead com.apple.AppleUserHIDDrivers that matches at 50,001

<key>idVendor</key>
<integer>1240</integer>
<key>idProduct</key>
<integer>63</integer>
<key>bInterfaceNumber</key>
<string>0</string>
<key>bConfigurationValue</key>
<string>1</string>

This should match at 60,000 instead com.apple.AppleUserHIDDrivers that matches at 50,001

<key>bInterfaceClass</key>
<integer>3</integer>
<key>bInterfaceSubClass</key>
<integer>0</integer>
<key>bInterfaceProtocol</key>
<string>0</string>

At the log I see the following:

  331 default kernelmanagerd  kernelmanagerd    <Description missing> symlink /Library/DriverExtensions/qbtech.Clicker.driver.dext -> /Library/SystemExtensions/E744CAAC-D320-459C-9DBD-5258C44D0000/qbtech.Clicker.driver.dext 10:49:25.429349+0200
  331 default kernelmanagerd  kernelmanagerd  com.apple.kernelmanagerd.logging  DextValidation  Realize dext qbtech.Clicker.driver  10:49:25.429466+0200
  331 default kernelmanagerd  kernelmanagerd    <Description missing> validating extension at /Library/SystemExtensions/E744CAAC-D320-459C-9DBD-5258C44D0000/qbtech.Clicker.driver.dext 10:49:25.433887+0200
  331 default kernelmanagerd  kernelmanagerd  com.apple.kernelmanagerd.logging  KernelClient  Loading codeless extension: Dext qbtech.Clicker.driver v1 in executable dext bundle qbtech.Clicker.driver at /Library/SystemExtensions/E744CAAC-D320-459C-9DBD-5258C44D0000/qbtech.Clicker.driver.dext  10:49:25.434437+0200
  478 default sysextd sysextd   <Description missing> extension point confirmed that extension qbtech.Clicker.driver is runnable  10:49:25.437382+0200
  478 default sysextd sysextd   <Description missing> changing state of extension qbtech.Clicker.driver to activated_enabled  10:49:25.437429+0200
  478 default sysextd sysextd com.apple.sx  StateChange extension <..none..> qbtech.Clicker.driver (1.0/1) advancing state from activated_enabling to activated_enabled 10:49:25.437460+0200

And then when the device is connected:

  0 default kernel  kernel    <Description missing> DK: AppleUserUSBHostHIDDevice-0x1000013cf using existing server IOUserServer(com.apple.driverkit.AppleUserHIDDrivers-0x100000c6b)-0x100000c71 10:49:33.106035+0200
  0 default kernel  kernel    <Description missing> DK: AppleUserUSBHostHIDDevice-0x1000013cf::start(IOUSBHostInterface-0x1000013cd) ok 10:49:33.121388+0200
  

Here's the full plist that I'm trying to get to match at 100,000:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
    
    <!-- required, see https://developer.apple.com/documentation/driverkit/creating_a_driver_using_the_driverkit_sdk -->
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>OSBundleUsageDescription</key>
    <string>Clicker driver</string>
    <!-- end required -->
    
    <key>IOKitPersonalities</key>
    <dict>
        <key>ClickerDriver</key>
        <dict>
            <key>IOKitDebug</key>
            <string>65535</string>
            
            <!--
            Required for each personality
            https://developer.apple.com/documentation/driverkit/creating_a_driver_using_the_driverkit_sdk -->
            <!-- The bundle ID of your driver -->
            <key>CFBundleIdentifier</key>
            <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
            <!-- The Apple class containing the base behavior -->
            <key>IOClass</key>
            <string>IOUserService</string>
            <!-- The name of your custom service class -->
            <key>IOUserClass</key>
            <string>ClickerDriver</string>
            <!-- The bundle identifier of your driver -->
            <key>IOUserServerName</key>
            <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
            <!--
            The class that your service requires as its provider object. IOKit provider class is
            IOUSBInterface, but in with USBDriverKit it is IOUSBHostInterface (or IOUSBHostDevice)
            https://developer.apple.com/documentation/usbdriverkit/iousbhostinterface
            -->
            <key>IOProviderClass</key>
            <string>IOUSBHostInterface</string>
            <!-- End Required for each personality -->
            
            <!--
            matching see https://developer.apple.com/library/archive/qa/qa1076/_index.html
            
            ioreg output for IOUSBHostInterface:
            |   "USB Vendor Name" = "Microchip Technology Inc."
            |   "bcdDevice" = 2
            |   "idProduct" = 63
            |   "bInterfaceSubClass" = 0
            |   "bConfigurationValue" = 1
            |   "bInterfaceProtocol" = 0
            |   "iInterface" = 0
            |   "bAlternateSetting" = 0
            |   "idVendor" = 1240
            |   "bInterfaceNumber" = 0
            |   "bInterfaceClass" = 3
            -->
            <key>idVendor</key>
            <integer>1240</integer>
            <key>idProduct</key>
            <integer>63</integer>
            <key>bInterfaceNumber</key>
            <string>0</string>
            <key>bConfigurationValue</key>
            <string>1</string>
            <key>bcdDevice</key>
            <string>2</string>
            <!-- end matching -->
                        
            <key>UserClientProperties</key>
            <dict>
                <key>IOClass</key>
                <string>IOUserUserClient</string>
                <key>IOUserClass</key>
                <string>ClickerDriverUserClient</string>
            </dict>
        </dict>
    </dict>
</dict>
</plist>

@jacob.wallstrom Did you ever figure this out? I have the same issue and the same goal - using USBDriverKit only and avoiding HID to enable deploying to the iPad.

@jacob.wallstrom @gojosh Did you find a solution for the matching issue?