I've submitted bug FB14290870
Thanks.
Post
Replies
Boosts
Views
Activity
Thank you for your comment.
This is an app we develop for iPadOS so I guess the IORegistryExplorer.app doesn't work in this case.
Just a bit more info on the problem we are facing.
When the USB device is connected before launching the app (with driver already enabled in iOS Settings), I notice my Driver Start() doesn't get called, which results in "MyDriver" not showing up when I try to get matching service with IOServiceMatching("IOUserService"). Others such as AppleBCMWLANBusInterfacePCIe, IO80211ReporterProxy, AppleBCMWLANCore are available but MyDriver. I tried using match notifications but got the same result as IOServiceGetMatchingServices.
If I launch the app first and then connect my USB device, MyDriver Start() is called and MyDriver is available. This allows me to find the driver and call IOServiceOpen on it. Everything then works as expected.
With the driver up and running, if I disabled and reenabled the driver in iOS settings without disconnecting/reconnecting the device, MyDriver Start() wouldn't get called, and get matching service with IOServiceMatching("IOUserService") wouldn't find it again.
I have no problem matching on the device using IOServiceMatching("IOUSBDevice") and idVendor + idProduct as keys. It doesn’t matter if the device is connected before or after launching the app, matching on the device always returns the correct value. It is the matching of the driver that I'm having problems with.
In the driver info.plist file we use IOUSBHostDevice for IOProviderClass since our device is a non-HID USB device. From what I’m seeing, looks like the device would need to be physically connected after launching the app for the driver to start and the matching to happen properly. I’m wondering if anything can be done to get it to work for the workflows I mentioned in #1 and #3 above.
Thanks!
MyDriver Info.plist file
<plist version="1.0">
<dict>
<key>IOKitPersonalities</key>
<dict>
<key>MyDriver</key>
<dict>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleIdentifierKernel</key>
<string>com.apple.kpi.iokit</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOMatchCategory</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOProviderClass</key>
<string>IOUserResources</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
<key>IOUserClass</key>
<string>MyDriver</string>
<key>IOUserServerName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>MyDriverUserClientProperties</key>
<dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOUserClass</key>
<string>MyDriverClient</string>
</dict>
<key>bConfigurationValue</key>
<integer>1</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>idProduct</key>
<integer>1234</integer>
<key>idVendor</key>
<integer>5678</integer>
</dict>
</dict>
</dict>
</plist>
MyDriver.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/>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>
code to get matching service and open service
io_service_t mService = IO_OBJECT_NULL;
kern_return_t ret = kIOReturnSuccess;
io_iterator_t iterator = IO_OBJECT_NULL;
//temporary checking for all services
//I refined it further using other keys
CFMutableDictionaryRef matchingDict = IOServiceMatching("IOUserService");
if (__builtin_available(iOS 15.0, *)) {
ret = IOServiceGetMatchingServices(kIOMainPortDefault, matchingDict, &iterator);
} else {
// Fallback on earlier versions
}
if (ret != kIOReturnSuccess)
{
printf("Unable to find service");
}
while ((mService = IOIteratorNext(iterator)) != IO_OBJECT_NULL)
{
//Only able to find "MyDriver" if launching the app first and then connecting the device
ret = IOServiceOpen(mService, mach_task_self_, 0, &mConnection);
..........
}
thanks a lot for the detailed answer!
I found a bug in our driver client free() function (double releasing a reference to a callback Action) that caused the driver to crash when the app was closed. Since the driver wasn't cleaned up properly, when I tried to relaunch the app with the usbc device still connected, my driver couldn’t reload.
Fixing this bug helped fix the issue we were seeing with the workflow in case #1.
Case #3 depends on exactly what drivers are actually loading when your DEXT isn't present. My guess is that this is either a variant of #1 (so fixing #1 will also resolve #3) or that the system driver can't unload (in which case, the user would need to hot plug the device before you DEXT will match).
If you managed to unload correctly, then it's possible that the system driver (which replace your DEXT) isn't unloading when you reenable your DEXT.
with the fix for case#1, case #3 still doesn't work properly. I tried to walk up the registry and noticed when I disabled my driver with the device still connected, AppleUSBHostCompositeDevice ended up matching with the device, and it didn't get unloaded when I reenabled my driver.
We display a message asking the user to disconnect and reconnect the device but just wondering if anything else can be done for this particular case.
Thanks a lot!
thanks for the info!