We followed WWDC Session: System Extensions and DriverKit and recreated a code to do USB device communication via IOUSBHostPipe:
struct MyDriver_IVars {
IOUSBHostInterface *interface;
IOUSBHostPipe *inPipe;
OSAction *ioCompleteCallback;
IOBufferMemoryDescriptor *inData;
uint16_t maxPacketSize;
};
kern_return_t
IMPL(MyDriver, Start)
{
...
ivars->maxPacketSize = 64;
ret = ivars->interface->CreateIOBuffer(
kIOMemoryDirectionInOut,
ivars->maxPacketSize,
&ivars->inData);
ret = CreateActionReadComplete(0, &ivars->ioCompleteCallback);
ret = ivars->inPipe->AsyncIO(ivars->inData,
ivars->maxPacketSize,
ivars->ioCompleteCallback,
0);
...
}
Our Driver is started by OS when device is connected. We see that ReadComplete callback is called:
void IMPL(MyDriver, ReadComplete)
{
Log("ReadComplete() - status - %d; bytes count - %d", status, actualByteCount);
}
However it's not obvious how to read data received in this callback. I suspect that we should use IOBufferMemoryDescriptor *inData but we didn't find any good example/sample and documentation is poor.
Our callback is called only once. It's not clear how to read a series of data from device? Should we create some loop and call inPipe->AsyncIO from callback?
Also it would be helpful to see how to pass data to device. I hope we should fill IOBufferMemoryDescriptor *inData.
-
—
MobileTen
-
—
MobileTen
-
I think it is more or less your implementation of the ioCompleteCallback function that is missing.
—
myurik2
Add a CommentI think it is more or less your implementation of the ioCompleteCallback function that is missing. Any async callback data is passed to this function.
Take a look here https://developer.apple.com/documentation/driverkit/communicating_between_a_driverkit_extension_and_a_client_app on the call back logic
It's because we don't know how to read data. Here is method declaration in MyDriver.iig:
virtual void ReadComplete(OSAction *action, IOReturn status, uint32_t actualByteCount, uint64_t completionTimestamp) TYPE(IOUSBHostPipe::CompleteAsyncIO);No data is passed