I'm trying to adapt this example to use it in iPadOS: https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/USBBook/USBDeviceInterfaces/USBDevInterfaces.html#//apple_ref/doc/uid/TP40002645-BBIDDHCI
I'm particularly having problem when I try to use IOUSBDeviceInterface.
I'm importing #include <IOKit/IOKitLib.h>
But when I'm trying to have a method like this:
IOReturn ConfigureDevice(IOUSBDeviceInterface **dev)
I've get the error:Unknown type name 'IOUSBDeviceInterface'
I'm using Xcode - Version 14.0 beta 3 (14A5270f)
Any ideas? Thanks
Post
Replies
Boosts
Views
Activity
I'm trying to create a driver for my usb device, using iOS and DriverKit.
I'm basing my code in the example used in WWDC: https://github.com/knightsc/USBApp
My driver starts fine when the device is connected and the readCompleted method is called fine, but the action->GetReference() gets only \0 characteres.
Also in order to know that the usb device is actually working I've connected it to my mac first and using PyUSB I can see that it's returning data in chunks of 1024 bytes in the interface 0.
This is the data I get in PyUSB:
array('B', [6, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16, 0, 17, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24, 0, 25, 0, 26, 0, 27, 0, 28, 0, 29, 0, 30, 0, 31, 0, 32, 0, 33, 0, 34, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40, 0, 41, 0, 42, 0, 43, 0, 44, 0, 45, 0, 46, 0, 47, 0, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 64, 0, 65, 0, 66, 0, 67, 0, 68, 0, 69, 0, 70, 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, 0, 76, 0, 77, 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, 0, 83, 0, 84, 0, 85, 0, 86, 0, 87, 0, 88, 0, 89, 0, 90, 0, 91, 0, 92, 0, 93, 0, 94, 0, 95, 0, 96, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 105, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113, 0, 114, 0, 115, 0, 116, 0, 117, 0, 118, 0, 119, 0, 120, 0, 121, 0, 122, 0, 123, 0, 124, 0, 125, 0, 126, 0, 127, 0, 128, 0, 129, 0, 130, 0, 131, 0, 132, 0, 133, 0, 134, 0, 135, 0, 136, 0, 137, 0, 138, 0, 139, 0, 140, 0, 141, 0, 142, 0, 143, 0, 144, 0, 145, 0, 146, 0, 147, 0, 148, 0, 149, 0, 150, 0, 151, 0, 152, 0, 153, 0, 154, 0, 155, 0, 156, 0, 157, 0, 158, 0, 159, 0, 160, 0, 161, 0, 162, 0, 163, 0, 164, 0, 165, 0, 166, 0, 167, 0, 168, 0, 169, 0, 170, 0, 171, 0, 172, 0, 173, 0, 174, 0, 175, 0, 176, 0, 177, 0, 178, 0, 179, 0, 180, 0, 181, 0, 182, 0, 183, 0, 184, 0, 185, 0, 186, 0, 187, 0, 188, 0, 189, 0, 190, 0, 191, 0, 192, 0, 193, 0, 194, 0, 195, 0, 196, 0, 197, 0, 198, 0, 199, 0, 200, 0, 201, 0, 202, 0, 203, 0, 204, 0, 205, 0, 206, 0, 207, 0, 208, 0, 209, 0, 210, 0, 211, 0, 212, 0, 213, 0, 214, 0, 215, 0, 216, 0, 217, 0, 218, 0, 219, 0, 220, 0, 221, 0, 222, 0, 223, 0, 224, 0, 225, 0, 226, 0, 227, 0, 228, 0, 229, 0, 230, 0, 231, 0, 232, 0, 233, 0, 234, 0, 235, 0, 236, 0, 237, 0, 238, 0, 239, 0, 240, 0, 241, 0, 242, 0, 243, 0, 244, 0, 245, 0, 246, 0, 247, 0, 248, 0, 249, 0, 250, 0, 251, 0, 252, 0, 253, 0, 254, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
This is the Ivars:
struct Mk1dDriver_IVars
{
IOUSBHostInterface *interface;
IOUSBHostPipe *inPipe;
OSAction *ioCompleteCallback;
IOBufferMemoryDescriptor *inData;
uint16_t maxPacketSize;
};
This is the Start method:
kern_return_t
IMPL(Mk1dDriver, Start)
{
kern_return_t ret;
IOUSBStandardEndpointDescriptors descriptors;
ret = Start(provider, SUPERDISPATCH);
__Require(kIOReturnSuccess == ret, Exit);
ret = RegisterService();
if (ret != kIOReturnSuccess)
{
Log("Start() - Failed to register service with error: 0x%08x.", ret);
goto Exit;
}
ivars->interface = OSDynamicCast(IOUSBHostInterface, provider);
__Require_Action(NULL != ivars->interface, Exit, ret = kIOReturnNoDevice);
ret = ivars->interface->Open(this, 0, NULL);
__Require(kIOReturnSuccess == ret, Exit);
ret = ivars->interface->CopyPipe(kMyEndpointAddress, &ivars->inPipe);
__Require(kIOReturnSuccess == ret, Exit);
ret = ivars->interface->CreateIOBuffer(kIOMemoryDirectionIn,
1024,
&ivars->inData);
__Require(kIOReturnSuccess == ret, Exit);
ret = OSAction::Create(this,
Mk1dDriver_ReadComplete_ID,
IOUSBHostPipe_CompleteAsyncIO_ID,
0,
&ivars->ioCompleteCallback);
__Require(kIOReturnSuccess == ret, Exit);
ret = ivars->inPipe->AsyncIO(ivars->inData,
ivars->maxPacketSize,
ivars->ioCompleteCallback,
0);
__Require(kIOReturnSuccess == ret, Exit);
os_log(OS_LOG_DEFAULT,"Finish");
// WWDC slides don't show the full function
// i.e. this is still unfinished
Exit:
return ret;
}
The only difference in this compared with the code from Apple is that I set capacity in the method CreateIOBuffer to 1024. This is because if I leave it to 0 it will return an error that memory could not be allocated: kIOReturnNoMemory
And the ReadComplete method:
void
IMPL(Mk1dDriver, ReadComplete)
{
char output[1024];
memcpy(action->GetReference(), &output, 1024);
os_log(OS_LOG_DEFAULT,"ReadComplete");
If I put a breakpoint in the log, I can see all the positions in output will be \0
Any idea what I'm doing wrong?
Could this be because the iPad is a device under Supervision?
Thanks
I'm building a driver in C++ for my iPad using DriverKit.
I'm trying to make a request to a control endpoint, so I'm trying to use DeviceRequest: https://developer.apple.com/documentation/usbdriverkit/iousbhostinterface/3182582-devicerequest
But the first parameter ask for USBmakebmRequestType which it's a macro defined in IOKit > USB.h
I tried to #include <IOKit/USB.h> and #include <IOKit/usb/USB.h> and but it doesn't find the header.
Any idea? thanks.
I wonder if it's possible to show a popup when a device is plugged in the iOS device but the driver/app is not installed.
I've seen this before when old days without DriverKit where a notification was shown to help the user. If the user accepted the popup the Apple store opened with the page download the particular app to install the driver for the device.
Thanks
After DriverKit being released last year, I wonder if the background mode External accessory communication in Background Modes applies also for drivers made with DriverKit.
Is this mode only for products in the MFi group? If so, is there any plans to include DriverKit in this group in order to get data from an external device in the background, which is not in the MFi group?
We got an app for iPad which has two targets one for the App itself (MainApp target ) and another one for the Driver ( Driver Target ) using DriverKit.
The app works fine in Development, but I'm trying to distribute it with adhoc.
I've requested the Distribution Entitlement to Apple, after getting it, the App Id for the Driver has the following Capabilities:
DriverKit, DriverKit (development), DriverKit USB Transport (development), DriverKit USB Transport - VendorID, In-App Purchase
Now in the profile section, I've created a adhoc profile for the Driver AppId (Identifier). Obviously I've also created an Adhoc profile for the Main AppId
Finally in the Signing & Capabilities Section I set up the profiles for MainApp target, int the Debug one I set up the Development one and int the Release one I set up the adhoc one.
I do the same in the Driver Target, but when I set up the Adhoc one in the Release, I've got a warning:
Xcode 14 and later requires a DriverKit development profile enabled for iOS and macOS. Visit the developer website to create or download a DriverKit profile
Also interestingly the Signing Certificate section says: None
I also set up the Capabilities for the Driver Target:
DriverKit USB Transport - VendorID
DriverKit USB Transport ( Development )
Inside these capabilities I set up the vendor ID as dictionary
The problem is, if I try to Archive the app I will get the previous Warning message as error:
Xcode 14 and later requires a DriverKit development profile enabled for iOS and macOS. Visit the developer website to create or download a DriverKit profile.
Any idea what I'm missing?
Thanks
We got an app that uses DriverKit. So we have the main target of the app and another target for DriverKit.
We would like to turn on code coverage for testing. To do so we enable it in the scheme settings.
Unfortunately this doesn't work because DriverKit doesn't support code coverage option. This happens because all settings set in the scheme settings get carry out for all the targets. So this the error you get:
File cannot be open)ed, errno=2 path=/Applications/code.app/Contents/Developer/Toolchains/XcodeDefault.ctoolchain/usr/lib/clang/15.0.0/ lib/darwin/libclang_rt.profile_driverkit.a in '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/
15.0.0/lib/darwin/libclang_rt.profile_driverkit.a'
After talking with a couple of Apple engineers ( thanks for your help btw :) ) about a similar problem related with Address Sanitiser, they helped me adding a custom setting in build settings for the main target so address sanitiser can be enabled only for the main target.
Unfortunately we didn't have enough time to cover the code coverage problem and they suggested to post a question in this forum to find out the KEY to set up code coverage in build settings
Thanks
I'm trying to use
#if hasFeature(ADDRESS_SANITIZER)
#endif
But it doesn't work.
Is there a way with a precompile directive to check if the Address Sanitizer is active?
Hi
We are developing a iPad accessory that connects to the USB-C port of an iPad Pro.
For debugging, we are using iPad pro M4 and iPad Pro 12.9 (fifth gen).
We are aware we can debug the app over wifi, but this process is slow and cumbersome.
Is there a USB-C hub ( I guess that supports thunderbolt ) that would allow us to connect the iPad to both our Mac and to the iPad accessory simultaneously ?
Thanks
We are currently building an app in Swift, reusing an internal C++ backend used in other platforms ( Linux/Windows/Mac ).
Current state of the project:
App W - ( Swift App )
Package X - Swift Package
Y.xcframework - Binary Target (ios-arm64 and ios-arm64-simulator)
Z.framework
Z - (C++ Backend as a library) Dynamic Library
Headers - Library header files
Frameworks (Folder) - Required .dylib’s for Z (
libA.dylib (Dependency of Z) [ 58 of them ]
libB.dylib (Runtime dependency of python) [ 123 of them ]
data - Supporting binary files for Z
conf - Supporting configuration files, both text and binary. for Z
python - Supporting .py scripts
C.py
D.py
Z.framework ( C++ ) contains 182 Dynamic Libraries.
Goal:
Validate the app for distribution with the Apple Store validation tool.
Learning when trying to solve the problem:
A framework can contain only one dynamic library (e.g. .dylib )
A framework cannot have nested frameworks within a Frameworks folder
Certain file types within a framework are not treated as resource files (e.g. .py files)
Possible solutions
Allow to have nested Frameworks in Z.framework.
It’s currently not allowed
Link 182 dynamic libraries into the project via SPM
Problem: Some of the libraries need to dynamically loaded at runtime (related to the python runtime)
Making the libraries static adds significantly technical challenges to the Z.framework.
Other questions:
What’s the best way to achieve this