Search code examples
macosbluetoothhidiokitdriverkit

Should I use IOKit or DriverKIt (or HIDDriverKit) to write driver for USB or Bluetooth multi-touch device in macOS?


I am planning to write driver for USB or Bluetooth multi-touch device similar to Apple Magic Trackpad or Logitech trackpad for Mac.

The idea is that all macOS applications can use this multi-touch device. As the newly introduced DriverKit (or HIDDriverKit) is to be bundled with apps, should I still use IOKit or should I use DriverKit?

Thanks.


Solution

  • DriverKit is built around IOKit - it's just yet another interface to it. So I guess your question really is whether your driver should be implemented as:

    • A DriverKit System Extension (dext)
    • A kernel extension (kext)
    • Something else

    You won't escape IOKit either way, because USB devices are only accessible via IOKit, and the HID stack is built on it too.

    Bluetooth

    As far as I'm aware, there aren't Bluetooth APIs for use with DriverKit, at least not yet. (As of macOS 10.15.4)

    So if your device uses a custom Bluetooth protocol which needs to be turned into a HID event source from scratch, then I don't think you'll be able to use DriverKit, at least not exclusively.

    If your device already appears to the system as a HID device but your driver needs to rewrite HID reports, then I think it might be possible to implement using DriverKit - at the very least it's worth researching.

    Implementing it as a kext will definitely work for all cases, the trouble is any new kexts will have a very limited shelf life at this stage.

    USB

    For USB, it's more straightforward, there are direct DriverKit USB APIs. USB HID drivers are one of the well-supported scenarios by DriverKit. So you should definitely not use a kext to implement a USB HID driver targeting macOS 10.15+ at this point. In fact, if you did develop a USB HID kext, your users would periodically be presented with an awful warning popup.

    "Something Else?"

    That brings us to the "something else" category: you may be able to write the driver (almost) entirely in regular user space as a daemon using user space bluetooth and USB APIs, and then inject the HID events produced back into the system. The best way to do this might end up being via a DriverKit driver - so you'd have a user space daemon performing most of the driver logic, and a small DriverKit driver creating a "virtual" HID device which just ferries the events produced by the daemon into the HID stack. If you need to support older OS versions, the responsibility of the dext in this approach could be taken by a kext, with the daemon needing virtually no customisation to run on all OS versions.

    If your driver will be doing a lot of complicated processing on the raw input data, this might be the way forward, as implementing such logic in a dext or kext isn't ideal.

    To say which approach is best I'd really need to know a lot more about the device (and that might exceed the scope of a Stack Overflow question…).