Gain user-space access to hardware devices and drivers using IOKit.

Posts under IOKit tag

200 Posts

Post

Replies

Boosts

Views

Activity

MacOS 15.3: Unable to get IOUSBDeviceInterface object when IOKit notification is received for USB Device connection for USB Device monitoring.
Our product is using IOKit framework for monitoring USB device activities. We have used IOKit framework for getting the notification for USB plugin and un-plugins. With the macOS version 15.3 we are started seeing issue with it. When the notification is received during USB plugin/connection, we are unable to get IOUSBDeviceInterface object which will be used for further processing. Currently we are seeing the below error every time, while trying to create the IO plugin interface using IOCreatePlugInInterfaceForService API:
 create plugin Error: (0xe00002be): (iokit/common) resource shortage Due to this the we are unable to proceed with the flow further and the entire flow is broken. These logics work fine in macOS version 15.2 and lower versions without any issues. logic used: USBDevice::initInterfaceInterfaceByIOService(io_service_t entry) { IOCFPlugInInterface** plugInInterface = NULL; IOUSBInterfaceInterface** interface = NULL; SInt32 score = 0; mach_error_code err = IOCreatePlugInInterfaceForService(entry, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if ((err != 0) || (!plugInInterface)) { os_log_error(OS_LOG_DEFAULT, "Unable to create plugin \n"); return nullptr; } auto result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID*)&interface); (*plugInInterface)->Release(plugInInterface); if (result || !interface) { os_log_error(OS_LOG_DEFAULT, "Unable to create interface \n"); return nullptr; } return interface; }
0
1
1.1k
Feb ’25
IOKit on iOS
The Developer documentation for IOKit marks it as available for iOS 16+ but I had a hard time finding a way to import it into an iOS project. I finally managed to do that using a bridging header file and iokit_linking.hpp. Why is it that hard to make it work on iOS? Is it okay to do it this way? If I use any IOKit methods and/or properties in my app will I be able to submit it to the App Store? Thanks.
3
0
782
Feb ’25
Sending NVMe Admin Commands
Hi, I’m currently working on a project to sanitize data (Remove customer data) on MacBook storage devices (Refurbish). The NVMe SSD is embedded on the motherboard. I’ve created a simple proof-of-concept code (Running in terminal) with the following steps: Check and Match the NVMe Device: Verify that the physical drive (disk0) exists on the system. Open the Connection: Establish a connection to the device (disk0). Send NVMe Admin Commands: For testing, I sent the IDENTIFY (0x06) command to confirm that the connection to the device works. Close the Service and Connection: Terminate the connection after the test. However, during runtime, I encountered an error when sending the command: Error: Failed to send NVMe Admin Command with error: -536870206 ((iokit/common) invalid argument) I’m unsure why this results in an "Invalid argument" error. Is the method I’m using to send the Admin Command incorrect? If so, what is the proper function call to use in the IOKit framework? Alternatively, are there any other recommended methods to achieve this? In the future, I also need to send commands like ‘Sanitize (84h)’ and ‘Format NVM (80h).’ Since I’m new to macOS development, I’d greatly appreciate any advice or guidance from experts in this area. I have attached the source code and related ioreg file for 'IOMedia' and 'IONVMeController' for you guy reference. IOMedia IONVMeController sendAdminCommands.cpp Thank you so much for your help! Regards, Winson
4
0
1.4k
Jan ’25
Missing calls to L2CAP Stream Delegate
I have a C++/Objective-C command line application, running on MacOs (15.1.1 (24B91)), that communicates with a Bluetooth LE peripheral. The application is build with Apple clang 16.0.0 and CMake as build system using Boost.Asio. I'm able to establish a L2CAP channel and after the channel is established, the peripheral sends a first (quite small) SDU on that channel to the application. The PSM is 0x80 and was chosen by the peripherals BLE stack. The application receives the PSM via GATT notification. I can see the SDU being send in a single LL PDU with Wireshark. I can also see the SDU being received in Apples PacketLogger. But I miss the corresponding call to a stream event handler. For all other GATT related events, the corresponding delegates / callbacks are called. The code that creates a dispatch queue and passes it to the CBCentralManager looks like this: dispatch_queue = dispatch_queue_create("de.torrox.ble_event_queue", NULL); manager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_queue options:nil]; When the L2CAP channel is established, the didOpenL2CAPChannel callback gets called from a thread within the dispatch_queue (has been verified with lldb): - (void)peripheral:(CBPeripheral *)peripheral didOpenL2CAPChannel:(CBL2CAPChannel *)channel error:(NSError *)error { [channel inputStream].delegate = self; [channel outputStream].delegate = self; [[channel inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [[channel outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [[channel inputStream] open]; [[channel outputStream] open]; ... // a reference to the channel is stored in the outside channel object [channel retain]; ... } Yet, not a single stream event is generated: - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event_code { Log( @"stream:handleEvent %@, %lu", stream, event_code ); ... } When I add a functionality, to poll the input stream, the stream will report the expected L2CAP input. But no event is generated. The main thread of execution is usually blocking on a boost::asio::io_context::run() call. The design is, to have the stream callback stream:handleEvent to post call back invocations on that io_context, and thus to wake up the main thread and get that callbacks being invoked on the main thread. All asynchronous GATT delegate calls are working as expected. The only missing events, are the events from the L2CAP streams. The same code worked in an older project on an older version of MacOs and an older version of Boost. How can I find out, why the stream delegates are not called?
0
0
750
Dec ’24
The curious case of the "IOKit Driver" Xcode target.
Firstly, I realise that Kexts are deprecated. And for my needs, user-space IOKit from an application might be more than I’ll ever need, but I can’t help ensuring I’ve got all my ducks in a row while I’m designing an app. I noticed in the above Kext deprecation notice that it’s more about specific APIs that are deprecated rather than the kext mechanism itself (no mention of IOKit kernel APIs there). Along with the fact that a reboot would be required and various other policy changes. While reading up on System Extensions and the various newer tools, DriverKit, Endpoint Security etc, I’ve noticed there’s no mention of this “IOKit Driver” target/deliverable in the Xcode template chooser. It looks like, from the requirements, that DriverKit is aimed at hardware manufacturers, with a need to request the DriverKit entitlement for development. With respect to Apple’s internal Kext deprecation roadmap, how safe is it to build a product that relies on using an IOKit Driver and are there any requirements similar to DriverKit? Would a developer need to request an entitlement? If I developed an app using user-space IOKit and, for illustration purposes let’s say I also included an IOKit Driver in the app bundle. If I used the IOKit API, including header file constants only (no digging around in the IORegistryExplorer for non-public keys), as Apple intends them to be used, would this fall foul of any App Store rules that anyone is aware of? Put another way, would making use of an IOKit Driver disqualify my app from being distributed via the App Store, similar to an Endpoint Security extension? As an aside, there are a lot of API in the ES Framework that could be used to build apps that have nothing to do with Endpoint Security. File system related apps for example. It’s a shame there isn’t an enhanced middle ground between FSEvents and Endpoint Security framework.
3
0
1.4k
Dec ’24
Use IOKit to access usb in MacOS
Hi, I am trying to develop MacOS application which will be connecting to USB devices and should be available in AppStore. So it must be Sandbox and probably I've to use permission com.apple.security.device.usb. I've following requirements: I need to detect USB devices with file system I need to have ability to upload & download files from this device I need to read device serial number I wonder if I can use IOKit for this and it will be compliant with AppStore rules or not?
6
0
2.5k
Nov ’24
Proper way to use IOKit in iOS app?
Hello, forum, I'm trying to build connection between a non-MFi HID device (like keyboard) and iOS app with IOKit and Swift. Thanks to this post, I have manage to import the IOKit into objc header. IOKit on iOS/iPadOS 16.0+ #import <IOKit/IOKitLib.h> However, I have this compiler error when I try to imitate same methods in the SerialPortSaple project from following article, but the IOKit can not be imported to Swift at first place. Communicating with a Modem on a Serial Port The screen shot of the sample project: It looks like the complier unable to reach the io_object_t type somehow, is there any workaround or approach?
6
1
2.6k
Oct ’24
Are there any updates on communicating with iPhones via USB-C without an MFi chip?
Hi everyone, Are there any new updates on communicating with iPhones via USB-C without needing an MFi chip, especially with the iPhone 15 or upcoming iPhone 16? I'm developing a custom accessory and wondering if the switch to USB-C has introduced any new possibilities for data communication without going through the MFi program. Thanks!
1
0
1.5k
Oct ’24
get properties of device in kIOTerminatedNotification handler
Hello, I am facing with misunderstanding how to read usb device properties correctly. The notification 'kIOTerminatedNotification' is delivered after an IOService has been terminated. Can I use IORegistryEntryCreateCFProperties() to get properties of terminated device? I am asking because I/O Registry is a dynamic database that captures the connections of all driver and nub objects currently active. Howerver, can we say that terminated device is still active? If IORegistryEntryCreateCFProperties() can not be used, are there any other way? (e.g. using Device Interface) Thank you in advance!
0
0
699
Oct ’24
Programatically changing the brightness of your Macbook
Hi all, I was wondering if anyone knew a way to change the brightness of your MacBook screen in Swift without using an overlay that changes the colours? I want the effect of just pressing the F1 and F2 brightness controls but done without using system events/ Applescript popping up windows on the screen. I think the UIScreen.brightness is something similar to what I want but it is not available for NSscreen. I can't figure out a way to do it with IOKit either. Things like ddccl doesn't work as the screen is not an external monitor. If there is a solution using Swift or terminal commands any help is much appreciated. Thanks, James
1
0
1.4k
Sep ’24
matching dictionary to find particular IOUSBInterface
Hello, I am trying to get value of InterfaceClass for particular USB Device. I modified matching dictionary and added the property locationID property. CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIOUSBInterfaceClassName); if (!matchingDictionary) { return -1; } int32_t locationID = 0xffff; CFNumberRef cfLocationID = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &locationID); CFDictionaryAddValue(matchingDictionary, CFSTR(kUSBHostPropertyLocationID), cfLocationID); CFRelease(cfLocationID); io_service_t ioService = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDictionary); if (!ioService) { return -1; } CFNumberRef cfInterfaceClass = (CFNumberRef)IORegistryEntrySearchCFProperty(ioService, kIOServicePlane, CFSTR(kUSBHostMatchingPropertyInterfaceClass), kCFAllocatorDefault, kNilOptions); ... Unfortunately nothing is found and ioService is NULL. What can be wrong here? Thank you in advance!
2
0
1.2k
Aug ’24
How to implement NVMESMARTLib for USB-NVMe bridge chip?
Many USB storage devices are NVMe devices accessed through a USB-NVMe bridge chip, such as those by JMicron and Asmedia. These chipsets do not forward SMART data requests to the devices, but do have the capability to forward raw NVMe commands to the devices using vendor specific requests. How can we provide access to SMART data for NVMe devices accessed through a bridge chip like this? Many people used the OSX SAT SMART kext driver to provide access to SMART data for devices using USB-SATA chips, but it is a kext and doesn't support NVMe. See https://binaryfruit.com/drivedx/usb-drive-support#install-instructions Would we need to implement a kext like that to make this work? Is there a DriverKit way to do this?
4
0
1.7k
Jul ’24
"SYSTEM EXTENSION" entitlements in framework
Hello everyone! I'm developing framework and app for macOS for PCI devices. For communication with driverkit, I'm verifying by giving userclient access entities of system extension to app. However, the app is just a sample program, and our customer is trying to develop the app using a framework with PCI communication part. Is there a way to build a framework with my company's signature, and to build and execute it without acquiring userclient access elements by any chance by a customer developer? Moreover, userclient access is only available to developers who have subscribed to the Apple Developer Program, so I hope that client/developers do not need to obtain separate entries.
3
0
1.3k
Jul ’24
Access NVMe SMART on iPad
When using external NVMe devices on iOS / iPadOS I cannot tell how to access the disk SMART data. On macOS I can use NVMeSMARTLibExternal.h to access this information but the same system does not seem to work on iPadOS (even with Thunderbolt NVMe devices). When using M series iPads with professional Thunderbolt storage this woudlbe very useful.
2
0
1.6k
Jul ’24
kIOReturnNotPermitted from IOHIDManagerOpen under lldb
I'm writing a C/C++ command line program which, at some point, calls IOHIDManagerOpen. I've added both my program executable and lldb as permitted for input monitoring (as far as I remember, my program was added after showing up a permission prompt, I've added lldb manually later, trying to resolve the problem). My problem is that when I run my program from within lldb in Terminal, the call to IOHIDManagerOpen returns kIOReturnNotPermitted. When I run my program directly in the terminal session (without lldb), this call returns kIOReturnSuccess. Such behaviour means it will be impractical to use lldb for any debugging of this program. What can be done to make lldb session behave the same way, the normal execution works? I'm on: 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:55:06 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6020 arm64 and: lldb-1500.0.200.58 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
2
0
1.9k
Jun ’24
How to communicate with smart card readers conncetd to USB-C port in iOS?
Hello All, I am new to iOS development and would like to detect the smart card readers connected to USB-C port on iOS (16+) devices. The smart card reader is a custom hardware and not MFi certified. So as per my understanding, I cannot use ExternalAccessory.framework without MFi certification. Correct? How else can I achieve this? Does TKSmartCardSlotManager works for this purpose (or is it only for NFC devices?)? Is there any example for how to use this interface? I couldn't find any example for this as a starting point... Thanks in advance.
4
0
2.5k
Jun ’24
How to get Magic Mouse/Trackpad InputValueCallback
I confirmed that I had successfully turned on the device and registered the callback method, but the callback method was not successfully invoked when moving with Magic mouse. What method does the Magic Mouse and Magic Trackpad need to use to get the input value of the device? IOReturn ioReturn = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); if ( kIOReturnSuccess == ioReturn ) { IOHIDDeviceRegisterInputValueCallback(deviceRef, mouseInputValueCallback, NULL); } static void mouseInputValueCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) { NSLog(@"handle input value"); } I passed the __IOHIDDeviceCopyMatchingInputElements get magic mouse input element <__NSArrayM 0x6000012c4900>( timestamp: 0 type: 1 usagePage: 1 usage: 48 reportID: 16 value: 0, timestamp: 0 type: 1 usagePage: 1 usage: 49 reportID: 16 value: 0, timestamp: 0 type: 2 usagePage: 9 usage: 1 reportID: 16 value: 0, timestamp: 0 type: 2 usagePage: 9 usage: 2 reportID: 16 value: 0 ) (NSArray *)getHIDReprots { if (!deviceRef) { return nil; } NSMutableArray *reports = [[NSMutableArray alloc] init]; CFArrayRef elements; CFIndex i; elements = IOHIDDeviceCopyMatchingElements(deviceRef, NULL, kIOHIDOptionsTypeNone); for (i = 0; i<CFArrayGetCount(elements); i++) { const IOHIDElementRef element = (void*)CFArrayGetValueAtIndex(elements, i); IOHIDElementType eleType = IOHIDElementGetType(element); NSString *eleTypeStr = @""; switch (eleType) { case kIOHIDElementTypeInput_Misc: eleTypeStr = @"kIOHIDElementTypeInput_Misc"; break; case kIOHIDElementTypeInput_Button: eleTypeStr = @"kIOHIDElementTypeInput_Button"; break; case kIOHIDElementTypeInput_Axis: eleTypeStr = @"kIOHIDElementTypeInput_Axis"; break; case kIOHIDElementTypeInput_ScanCodes: eleTypeStr = @"kIOHIDElementTypeInput_ScanCodes"; break; case kIOHIDElementTypeInput_NULL: eleTypeStr = @"kIOHIDElementTypeInput_NULL"; break; case kIOHIDElementTypeOutput: eleTypeStr = @"kIOHIDElementTypeOutput"; break; case kIOHIDElementTypeFeature: eleTypeStr = @"kIOHIDElementTypeFeature"; break; case kIOHIDElementTypeCollection: eleTypeStr = @"kIOHIDElementTypeCollection"; break; default: break; } uint32_t page = IOHIDElementGetUsagePage(element); uint32_t usage = IOHIDElementGetUsage(element); uint32_t reportID = IOHIDElementGetReportID(element); uint32_t reportSize = IOHIDElementGetReportSize(element); uint32_t reportCount = IOHIDElementGetReportCount(element); NSString *elementStr = [[NSString alloc] initWithFormat:@" reportID:%d, reportSize:%d, type:%@, UsagePage:%d, usage:%d, reportCount:%d\n\n",reportID, reportSize, eleTypeStr, page, usage, reportCount]; [reports addObject:elementStr]; } return reports; } reportID:0, reportSize:0, type:kIOHIDElementTypeCollection, UsagePage:1, usage:2, reportCount:1 reportID:0, reportSize:0, type:kIOHIDElementTypeCollection, UsagePage:1, usage:1, reportCount:1 reportID:16, reportSize:16, type:kIOHIDElementTypeInput_Misc, UsagePage:1, usage:48, reportCount:1 reportID:16, reportSize:16, type:kIOHIDElementTypeInput_Misc, UsagePage:1, usage:49, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_Button, UsagePage:9, usage:1, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_Button, UsagePage:9, usage:2, reportCount:1 reportID:71, reportSize:8, type:kIOHIDElementTypeFeature, UsagePage:6, usage:32, reportCount:1 reportID:85, reportSize:512, type:kIOHIDElementTypeFeature, UsagePage:65282, usage:85, reportCount:64 reportID:0, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:0, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:16, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:71, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:71, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:85, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:85, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 Devices: VendorID ProductID LocationID UsagePage Usage RegistryID Transport Class Product UserClass Built-In 0x4c 0x265 0x3bab3ec3 1 2 0x100001ec4 Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 0 1 0x100001eb2 Bluetooth AppleHSBluetoothDevice Magic Trackpad (null) 0 0x5ac 0x30d 0x5abbb32b 1 2 0x100001221 Bluetooth BNBMouseDevice Magic Mouse (null) 0 0x4c 0x265 0x3bab3ec3 65280 3 0x100001ed2 Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 65280 13 0x100001ecc Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 65280 11 0x100001eba Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0
5
0
1.3k
Jun ’24
MacOS 15.3: Unable to get IOUSBDeviceInterface object when IOKit notification is received for USB Device connection for USB Device monitoring.
Our product is using IOKit framework for monitoring USB device activities. We have used IOKit framework for getting the notification for USB plugin and un-plugins. With the macOS version 15.3 we are started seeing issue with it. When the notification is received during USB plugin/connection, we are unable to get IOUSBDeviceInterface object which will be used for further processing. Currently we are seeing the below error every time, while trying to create the IO plugin interface using IOCreatePlugInInterfaceForService API:
 create plugin Error: (0xe00002be): (iokit/common) resource shortage Due to this the we are unable to proceed with the flow further and the entire flow is broken. These logics work fine in macOS version 15.2 and lower versions without any issues. logic used: USBDevice::initInterfaceInterfaceByIOService(io_service_t entry) { IOCFPlugInInterface** plugInInterface = NULL; IOUSBInterfaceInterface** interface = NULL; SInt32 score = 0; mach_error_code err = IOCreatePlugInInterfaceForService(entry, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if ((err != 0) || (!plugInInterface)) { os_log_error(OS_LOG_DEFAULT, "Unable to create plugin \n"); return nullptr; } auto result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID*)&interface); (*plugInInterface)->Release(plugInInterface); if (result || !interface) { os_log_error(OS_LOG_DEFAULT, "Unable to create interface \n"); return nullptr; } return interface; }
Replies
0
Boosts
1
Views
1.1k
Activity
Feb ’25
IOKit on iOS
The Developer documentation for IOKit marks it as available for iOS 16+ but I had a hard time finding a way to import it into an iOS project. I finally managed to do that using a bridging header file and iokit_linking.hpp. Why is it that hard to make it work on iOS? Is it okay to do it this way? If I use any IOKit methods and/or properties in my app will I be able to submit it to the App Store? Thanks.
Replies
3
Boosts
0
Views
782
Activity
Feb ’25
Sending NVMe Admin Commands
Hi, I’m currently working on a project to sanitize data (Remove customer data) on MacBook storage devices (Refurbish). The NVMe SSD is embedded on the motherboard. I’ve created a simple proof-of-concept code (Running in terminal) with the following steps: Check and Match the NVMe Device: Verify that the physical drive (disk0) exists on the system. Open the Connection: Establish a connection to the device (disk0). Send NVMe Admin Commands: For testing, I sent the IDENTIFY (0x06) command to confirm that the connection to the device works. Close the Service and Connection: Terminate the connection after the test. However, during runtime, I encountered an error when sending the command: Error: Failed to send NVMe Admin Command with error: -536870206 ((iokit/common) invalid argument) I’m unsure why this results in an "Invalid argument" error. Is the method I’m using to send the Admin Command incorrect? If so, what is the proper function call to use in the IOKit framework? Alternatively, are there any other recommended methods to achieve this? In the future, I also need to send commands like ‘Sanitize (84h)’ and ‘Format NVM (80h).’ Since I’m new to macOS development, I’d greatly appreciate any advice or guidance from experts in this area. I have attached the source code and related ioreg file for 'IOMedia' and 'IONVMeController' for you guy reference. IOMedia IONVMeController sendAdminCommands.cpp Thank you so much for your help! Regards, Winson
Replies
4
Boosts
0
Views
1.4k
Activity
Jan ’25
Missing calls to L2CAP Stream Delegate
I have a C++/Objective-C command line application, running on MacOs (15.1.1 (24B91)), that communicates with a Bluetooth LE peripheral. The application is build with Apple clang 16.0.0 and CMake as build system using Boost.Asio. I'm able to establish a L2CAP channel and after the channel is established, the peripheral sends a first (quite small) SDU on that channel to the application. The PSM is 0x80 and was chosen by the peripherals BLE stack. The application receives the PSM via GATT notification. I can see the SDU being send in a single LL PDU with Wireshark. I can also see the SDU being received in Apples PacketLogger. But I miss the corresponding call to a stream event handler. For all other GATT related events, the corresponding delegates / callbacks are called. The code that creates a dispatch queue and passes it to the CBCentralManager looks like this: dispatch_queue = dispatch_queue_create("de.torrox.ble_event_queue", NULL); manager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_queue options:nil]; When the L2CAP channel is established, the didOpenL2CAPChannel callback gets called from a thread within the dispatch_queue (has been verified with lldb): - (void)peripheral:(CBPeripheral *)peripheral didOpenL2CAPChannel:(CBL2CAPChannel *)channel error:(NSError *)error { [channel inputStream].delegate = self; [channel outputStream].delegate = self; [[channel inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [[channel outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [[channel inputStream] open]; [[channel outputStream] open]; ... // a reference to the channel is stored in the outside channel object [channel retain]; ... } Yet, not a single stream event is generated: - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event_code { Log( @"stream:handleEvent %@, %lu", stream, event_code ); ... } When I add a functionality, to poll the input stream, the stream will report the expected L2CAP input. But no event is generated. The main thread of execution is usually blocking on a boost::asio::io_context::run() call. The design is, to have the stream callback stream:handleEvent to post call back invocations on that io_context, and thus to wake up the main thread and get that callbacks being invoked on the main thread. All asynchronous GATT delegate calls are working as expected. The only missing events, are the events from the L2CAP streams. The same code worked in an older project on an older version of MacOs and an older version of Boost. How can I find out, why the stream delegates are not called?
Replies
0
Boosts
0
Views
750
Activity
Dec ’24
The curious case of the "IOKit Driver" Xcode target.
Firstly, I realise that Kexts are deprecated. And for my needs, user-space IOKit from an application might be more than I’ll ever need, but I can’t help ensuring I’ve got all my ducks in a row while I’m designing an app. I noticed in the above Kext deprecation notice that it’s more about specific APIs that are deprecated rather than the kext mechanism itself (no mention of IOKit kernel APIs there). Along with the fact that a reboot would be required and various other policy changes. While reading up on System Extensions and the various newer tools, DriverKit, Endpoint Security etc, I’ve noticed there’s no mention of this “IOKit Driver” target/deliverable in the Xcode template chooser. It looks like, from the requirements, that DriverKit is aimed at hardware manufacturers, with a need to request the DriverKit entitlement for development. With respect to Apple’s internal Kext deprecation roadmap, how safe is it to build a product that relies on using an IOKit Driver and are there any requirements similar to DriverKit? Would a developer need to request an entitlement? If I developed an app using user-space IOKit and, for illustration purposes let’s say I also included an IOKit Driver in the app bundle. If I used the IOKit API, including header file constants only (no digging around in the IORegistryExplorer for non-public keys), as Apple intends them to be used, would this fall foul of any App Store rules that anyone is aware of? Put another way, would making use of an IOKit Driver disqualify my app from being distributed via the App Store, similar to an Endpoint Security extension? As an aside, there are a lot of API in the ES Framework that could be used to build apps that have nothing to do with Endpoint Security. File system related apps for example. It’s a shame there isn’t an enhanced middle ground between FSEvents and Endpoint Security framework.
Replies
3
Boosts
0
Views
1.4k
Activity
Dec ’24
Use IOKit to access usb in MacOS
Hi, I am trying to develop MacOS application which will be connecting to USB devices and should be available in AppStore. So it must be Sandbox and probably I've to use permission com.apple.security.device.usb. I've following requirements: I need to detect USB devices with file system I need to have ability to upload & download files from this device I need to read device serial number I wonder if I can use IOKit for this and it will be compliant with AppStore rules or not?
Replies
6
Boosts
0
Views
2.5k
Activity
Nov ’24
Proper way to use IOKit in iOS app?
Hello, forum, I'm trying to build connection between a non-MFi HID device (like keyboard) and iOS app with IOKit and Swift. Thanks to this post, I have manage to import the IOKit into objc header. IOKit on iOS/iPadOS 16.0+ #import <IOKit/IOKitLib.h> However, I have this compiler error when I try to imitate same methods in the SerialPortSaple project from following article, but the IOKit can not be imported to Swift at first place. Communicating with a Modem on a Serial Port The screen shot of the sample project: It looks like the complier unable to reach the io_object_t type somehow, is there any workaround or approach?
Replies
6
Boosts
1
Views
2.6k
Activity
Oct ’24
Are there any updates on communicating with iPhones via USB-C without an MFi chip?
Hi everyone, Are there any new updates on communicating with iPhones via USB-C without needing an MFi chip, especially with the iPhone 15 or upcoming iPhone 16? I'm developing a custom accessory and wondering if the switch to USB-C has introduced any new possibilities for data communication without going through the MFi program. Thanks!
Replies
1
Boosts
0
Views
1.5k
Activity
Oct ’24
get properties of device in kIOTerminatedNotification handler
Hello, I am facing with misunderstanding how to read usb device properties correctly. The notification 'kIOTerminatedNotification' is delivered after an IOService has been terminated. Can I use IORegistryEntryCreateCFProperties() to get properties of terminated device? I am asking because I/O Registry is a dynamic database that captures the connections of all driver and nub objects currently active. Howerver, can we say that terminated device is still active? If IORegistryEntryCreateCFProperties() can not be used, are there any other way? (e.g. using Device Interface) Thank you in advance!
Replies
0
Boosts
0
Views
699
Activity
Oct ’24
Programatically changing the brightness of your Macbook
Hi all, I was wondering if anyone knew a way to change the brightness of your MacBook screen in Swift without using an overlay that changes the colours? I want the effect of just pressing the F1 and F2 brightness controls but done without using system events/ Applescript popping up windows on the screen. I think the UIScreen.brightness is something similar to what I want but it is not available for NSscreen. I can't figure out a way to do it with IOKit either. Things like ddccl doesn't work as the screen is not an external monitor. If there is a solution using Swift or terminal commands any help is much appreciated. Thanks, James
Replies
1
Boosts
0
Views
1.4k
Activity
Sep ’24
matching dictionary to find particular IOUSBInterface
Hello, I am trying to get value of InterfaceClass for particular USB Device. I modified matching dictionary and added the property locationID property. CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIOUSBInterfaceClassName); if (!matchingDictionary) { return -1; } int32_t locationID = 0xffff; CFNumberRef cfLocationID = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &locationID); CFDictionaryAddValue(matchingDictionary, CFSTR(kUSBHostPropertyLocationID), cfLocationID); CFRelease(cfLocationID); io_service_t ioService = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDictionary); if (!ioService) { return -1; } CFNumberRef cfInterfaceClass = (CFNumberRef)IORegistryEntrySearchCFProperty(ioService, kIOServicePlane, CFSTR(kUSBHostMatchingPropertyInterfaceClass), kCFAllocatorDefault, kNilOptions); ... Unfortunately nothing is found and ioService is NULL. What can be wrong here? Thank you in advance!
Replies
2
Boosts
0
Views
1.2k
Activity
Aug ’24
How to implement NVMESMARTLib for USB-NVMe bridge chip?
Many USB storage devices are NVMe devices accessed through a USB-NVMe bridge chip, such as those by JMicron and Asmedia. These chipsets do not forward SMART data requests to the devices, but do have the capability to forward raw NVMe commands to the devices using vendor specific requests. How can we provide access to SMART data for NVMe devices accessed through a bridge chip like this? Many people used the OSX SAT SMART kext driver to provide access to SMART data for devices using USB-SATA chips, but it is a kext and doesn't support NVMe. See https://binaryfruit.com/drivedx/usb-drive-support#install-instructions Would we need to implement a kext like that to make this work? Is there a DriverKit way to do this?
Replies
4
Boosts
0
Views
1.7k
Activity
Jul ’24
"SYSTEM EXTENSION" entitlements in framework
Hello everyone! I'm developing framework and app for macOS for PCI devices. For communication with driverkit, I'm verifying by giving userclient access entities of system extension to app. However, the app is just a sample program, and our customer is trying to develop the app using a framework with PCI communication part. Is there a way to build a framework with my company's signature, and to build and execute it without acquiring userclient access elements by any chance by a customer developer? Moreover, userclient access is only available to developers who have subscribed to the Apple Developer Program, so I hope that client/developers do not need to obtain separate entries.
Replies
3
Boosts
0
Views
1.3k
Activity
Jul ’24
Access NVMe SMART on iPad
When using external NVMe devices on iOS / iPadOS I cannot tell how to access the disk SMART data. On macOS I can use NVMeSMARTLibExternal.h to access this information but the same system does not seem to work on iPadOS (even with Thunderbolt NVMe devices). When using M series iPads with professional Thunderbolt storage this woudlbe very useful.
Replies
2
Boosts
0
Views
1.6k
Activity
Jul ’24
kIOReturnNotPermitted from IOHIDManagerOpen under lldb
I'm writing a C/C++ command line program which, at some point, calls IOHIDManagerOpen. I've added both my program executable and lldb as permitted for input monitoring (as far as I remember, my program was added after showing up a permission prompt, I've added lldb manually later, trying to resolve the problem). My problem is that when I run my program from within lldb in Terminal, the call to IOHIDManagerOpen returns kIOReturnNotPermitted. When I run my program directly in the terminal session (without lldb), this call returns kIOReturnSuccess. Such behaviour means it will be impractical to use lldb for any debugging of this program. What can be done to make lldb session behave the same way, the normal execution works? I'm on: 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:55:06 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6020 arm64 and: lldb-1500.0.200.58 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
Replies
2
Boosts
0
Views
1.9k
Activity
Jun ’24
How to communicate with smart card readers conncetd to USB-C port in iOS?
Hello All, I am new to iOS development and would like to detect the smart card readers connected to USB-C port on iOS (16+) devices. The smart card reader is a custom hardware and not MFi certified. So as per my understanding, I cannot use ExternalAccessory.framework without MFi certification. Correct? How else can I achieve this? Does TKSmartCardSlotManager works for this purpose (or is it only for NFC devices?)? Is there any example for how to use this interface? I couldn't find any example for this as a starting point... Thanks in advance.
Replies
4
Boosts
0
Views
2.5k
Activity
Jun ’24
How to get Magic Mouse/Trackpad InputValueCallback
I confirmed that I had successfully turned on the device and registered the callback method, but the callback method was not successfully invoked when moving with Magic mouse. What method does the Magic Mouse and Magic Trackpad need to use to get the input value of the device? IOReturn ioReturn = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); if ( kIOReturnSuccess == ioReturn ) { IOHIDDeviceRegisterInputValueCallback(deviceRef, mouseInputValueCallback, NULL); } static void mouseInputValueCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) { NSLog(@"handle input value"); } I passed the __IOHIDDeviceCopyMatchingInputElements get magic mouse input element <__NSArrayM 0x6000012c4900>( timestamp: 0 type: 1 usagePage: 1 usage: 48 reportID: 16 value: 0, timestamp: 0 type: 1 usagePage: 1 usage: 49 reportID: 16 value: 0, timestamp: 0 type: 2 usagePage: 9 usage: 1 reportID: 16 value: 0, timestamp: 0 type: 2 usagePage: 9 usage: 2 reportID: 16 value: 0 ) (NSArray *)getHIDReprots { if (!deviceRef) { return nil; } NSMutableArray *reports = [[NSMutableArray alloc] init]; CFArrayRef elements; CFIndex i; elements = IOHIDDeviceCopyMatchingElements(deviceRef, NULL, kIOHIDOptionsTypeNone); for (i = 0; i<CFArrayGetCount(elements); i++) { const IOHIDElementRef element = (void*)CFArrayGetValueAtIndex(elements, i); IOHIDElementType eleType = IOHIDElementGetType(element); NSString *eleTypeStr = @""; switch (eleType) { case kIOHIDElementTypeInput_Misc: eleTypeStr = @"kIOHIDElementTypeInput_Misc"; break; case kIOHIDElementTypeInput_Button: eleTypeStr = @"kIOHIDElementTypeInput_Button"; break; case kIOHIDElementTypeInput_Axis: eleTypeStr = @"kIOHIDElementTypeInput_Axis"; break; case kIOHIDElementTypeInput_ScanCodes: eleTypeStr = @"kIOHIDElementTypeInput_ScanCodes"; break; case kIOHIDElementTypeInput_NULL: eleTypeStr = @"kIOHIDElementTypeInput_NULL"; break; case kIOHIDElementTypeOutput: eleTypeStr = @"kIOHIDElementTypeOutput"; break; case kIOHIDElementTypeFeature: eleTypeStr = @"kIOHIDElementTypeFeature"; break; case kIOHIDElementTypeCollection: eleTypeStr = @"kIOHIDElementTypeCollection"; break; default: break; } uint32_t page = IOHIDElementGetUsagePage(element); uint32_t usage = IOHIDElementGetUsage(element); uint32_t reportID = IOHIDElementGetReportID(element); uint32_t reportSize = IOHIDElementGetReportSize(element); uint32_t reportCount = IOHIDElementGetReportCount(element); NSString *elementStr = [[NSString alloc] initWithFormat:@" reportID:%d, reportSize:%d, type:%@, UsagePage:%d, usage:%d, reportCount:%d\n\n",reportID, reportSize, eleTypeStr, page, usage, reportCount]; [reports addObject:elementStr]; } return reports; } reportID:0, reportSize:0, type:kIOHIDElementTypeCollection, UsagePage:1, usage:2, reportCount:1 reportID:0, reportSize:0, type:kIOHIDElementTypeCollection, UsagePage:1, usage:1, reportCount:1 reportID:16, reportSize:16, type:kIOHIDElementTypeInput_Misc, UsagePage:1, usage:48, reportCount:1 reportID:16, reportSize:16, type:kIOHIDElementTypeInput_Misc, UsagePage:1, usage:49, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_Button, UsagePage:9, usage:1, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_Button, UsagePage:9, usage:2, reportCount:1 reportID:71, reportSize:8, type:kIOHIDElementTypeFeature, UsagePage:6, usage:32, reportCount:1 reportID:85, reportSize:512, type:kIOHIDElementTypeFeature, UsagePage:65282, usage:85, reportCount:64 reportID:0, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:0, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:16, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:16, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:71, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:71, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 reportID:85, reportSize:0, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:-1, reportCount:1 reportID:85, reportSize:1, type:kIOHIDElementTypeInput_NULL, UsagePage:0, usage:0, reportCount:1 Devices: VendorID ProductID LocationID UsagePage Usage RegistryID Transport Class Product UserClass Built-In 0x4c 0x265 0x3bab3ec3 1 2 0x100001ec4 Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 0 1 0x100001eb2 Bluetooth AppleHSBluetoothDevice Magic Trackpad (null) 0 0x5ac 0x30d 0x5abbb32b 1 2 0x100001221 Bluetooth BNBMouseDevice Magic Mouse (null) 0 0x4c 0x265 0x3bab3ec3 65280 3 0x100001ed2 Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 65280 13 0x100001ecc Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0 0x4c 0x265 0x3bab3ec3 65280 11 0x100001eba Bluetooth AppleHSBluetoothHIDDriver Magic Trackpad (null) 0
Replies
5
Boosts
0
Views
1.3k
Activity
Jun ’24