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

Posts under IOKit tag

31 Posts

Post

Replies

Boosts

Views

Activity

How can I locate a UVC camera for PTZ control by AVCaptureDevice.unique_id
I'm writing a program to control a PTZ camera connected via USB. I can get access to target camera's unique_id, and also other infos provided by AVFoundation. But I don't know how to locate my target USB device to send a UVC ControlRequest. There's many Cameras with same VendorID and ProductID connected at a time, so I need a more exact way to find out which device is my target. It looks that the unique_id provided is (locationID<<32|VendorID<<16|ProductID) as hex string, but I'm not sure if I can always assume this behavior won't change. Is there's a document declares how AVFoundation generate the unique_id for USB camera, so I can assume this convert will always work? Or is there's a way to send a PTZ control request to AVCaptureDevice? https://stackoverflow.com/questions/40006908/usb-interface-of-an-avcapturedevice I have seen this similar question. But I'm worrying that Exacting LocationID+VendorID+ProductID from unique_id seems like programming to implementation instead of interface. So, if there's any other better way to control my camera? here's my example code for getting unique_id: // // camera_unique_id_test.mm // // 测试代码:使用C++获取当前系统摄像头的AVCaptureDevice unique_id // // 编译命令: // clang++ -framework AVFoundation -framework CoreMedia -framework Foundation // camera_unique_id_test.mm -o camera_unique_id_test // #include <iostream> #include <string> #include <vector> #import <AVFoundation/AVFoundation.h> #import <Foundation/Foundation.h> struct CameraInfo { std::string uniqueId; }; std::vector<CameraInfo> getAllCameraDevices() { std::vector<CameraInfo> cameras; @autoreleasepool { NSArray<AVCaptureDevice*>* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; AVCaptureDevice* defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; // 遍历所有设备 for (AVCaptureDevice* device in devices) { CameraInfo info; // 获取unique_id info.uniqueId = std::string([device.uniqueID UTF8String]); cameras.push_back(info); } } return cameras; } int main(int argc, char* argv[]) { std::vector<CameraInfo> cameras = getAllCameraDevices(); for (size_t i = 0; i < cameras.size(); i++) { const CameraInfo& camera = cameras[i]; std::cout << " 设备 " << (i + 1) << ":" << std::endl; std::cout << " unique_id: " << camera.uniqueId << std::endl; } return 0; } and here's my code for UVC control: // clang++ -framework Foundation -framework IOKit uvc_test.cpp -o uvc_test #include <iostream> #include <CoreFoundation/CoreFoundation.h> #include <IOKit/IOCFPlugIn.h> #include <IOKit/IOKitLib.h> #include <IOKit/IOMessage.h> #include <IOKit/usb/IOUSBLib.h> #include <IOKit/usb/USB.h> CFStringRef CreateCFStringFromIORegistryKey(io_service_t ioService, const char* key) { CFStringRef keyString = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); if (!keyString) return nullptr; CFStringRef result = static_cast<CFStringRef>( IORegistryEntryCreateCFProperty(ioService, keyString, kCFAllocatorDefault, kIORegistryIterateRecursively)); CFRelease(keyString); return result; } std::string GetStringFromIORegistry(io_service_t ioService, const char* key) { CFStringRef cfString = CreateCFStringFromIORegistryKey(ioService, key); if (!cfString) return ""; char buffer[256]; Boolean success = CFStringGetCString(cfString, buffer, sizeof(buffer), kCFStringEncodingUTF8); CFRelease(cfString); return success ? std::string(buffer) : std::string(""); } uint32_t GetUInt32FromIORegistry(io_service_t ioService, const char* key) { CFStringRef keyString = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); if (!keyString) return 0; CFNumberRef number = static_cast<CFNumberRef>( IORegistryEntryCreateCFProperty(ioService, keyString, kCFAllocatorDefault, kIORegistryIterateRecursively)); CFRelease(keyString); if (!number) return 0; uint32_t value = 0; CFNumberGetValue(number, kCFNumberSInt32Type, &value); CFRelease(number); return value; } int main() { // Get matching dictionary for USB devices CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Get iterator for matching services io_iterator_t serviceIterator; IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &serviceIterator); // Iterate through matching devices io_service_t usbService; while ((usbService = IOIteratorNext(serviceIterator))) { uint32_t locationId = GetUInt32FromIORegistry(usbService, "locationID"); uint32_t vendorId = GetUInt32FromIORegistry(usbService, "idVendor"); uint32_t productId = GetUInt32FromIORegistry(usbService, "idProduct"); IOCFPlugInInterface** plugInInterface = nullptr; IOUSBDeviceInterface** deviceInterface = nullptr; SInt32 score; // Get device plugin interface IOCreatePlugInInterfaceForService(usbService, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); // Get device interface (*plugInInterface) ->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&deviceInterface); (*plugInInterface)->Release(plugInInterface); // Try to find UVC control interface using CreateInterfaceIterator io_iterator_t interfaceIterator; IOUSBFindInterfaceRequest interfaceRequest; interfaceRequest.bInterfaceClass = kUSBVideoInterfaceClass; // 14 interfaceRequest.bInterfaceSubClass = kUSBVideoControlSubClass; // 1 interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; interfaceRequest.bAlternateSetting = kIOUSBFindInterfaceDontCare; (*deviceInterface) ->CreateInterfaceIterator(deviceInterface, &interfaceRequest, &interfaceIterator); (*deviceInterface)->Release(deviceInterface); io_service_t usbInterface = IOIteratorNext(interfaceIterator); IOObjectRelease(interfaceIterator); if (usbInterface) { std::cout << "Get UVC device with:" << std::endl; std::cout << "locationId: " << std::hex << locationId << std::endl; std::cout << "vendorId: " << std::hex << vendorId << std::endl; std::cout << "productId: " << std::hex << productId << std::endl << std::endl; IOObjectRelease(usbInterface); } IOObjectRelease(usbService); } IOObjectRelease(serviceIterator); }
2
0
353
Oct ’25
Mac Catalyst: IOHID InputReportCallback not firing, USBInterfaceOpen returns kIOReturnNotPermitted (0xe00002e2) for custom HID device
Hi everyone, I am developing a .NET MAUI Mac Catalyst app (sandboxed) that communicates with a custom vendor-specific HID USB device. Within the Catalyst app, I am using a native iOS library (built with Objective-C and IOKit) and calling into it via P/Invoke from C#. The HID communication layer relies on IOHIDManager and IOUSBInterface APIs. The device is correctly detected and opened using IOHIDManager APIs. However, IOHIDDeviceRegisterInputReportCallback never triggers — I don’t receive any input reports. To investigate, I also tried using low-level IOKit USB APIs via P/Invoke from my Catalyst app, calling into a native iOS library. When attempting to open the USB interface using IOUSBInterfaceOpen() or IOUSBInterfaceOpenSeize(), both calls fail with: kIOReturnNotPermitted (0xe00002e2). — indicating an access denied error, even though the device enumerates and opens successfully. Interestingly, when I call IOHIDDeviceSetReport(), it returns status = 0, meaning I can successfully send feature reports to the device. Only input reports (via the InputReportCallback) fail to arrive. I’ve confirmed this is not a device issue — the same hardware and protocol work perfectly under Windows using the HIDSharp library, where both input and output reports function correctly. What I’ve verified •Disabling sandboxing doesn’t change the behavior. •The device uses a vendor-specific usage page (not a standard HID like keyboard/mouse). •Enumeration, open, and SetReport all succeed — only reading input reports fails. •Tried polling queues, in queues Input_Misc element failed to add to the queues. •Tried getting report in a loop but no use.
2
0
237
Oct ’25
Thermal management on iOS
I would like to inquire about Apple's recommended best practices for iPhone thermal management. Specifically, what actions are developers expected to take to prevent the device from overheating? I am aware that we should subscribe to Thermal State Notifications and throttle performance accordingly—such as by reducing streaming quality or temporarily disabling active features. Beyond these measures, are there any other strategies you recommend to mitigate thermal issues and help the device cool down?
1
0
183
Dec ’25
Thermal management on iOS
I would like to inquire about Apple's recommended best practices for iPhone thermal management. Specifically, what actions are developers expected to take to prevent the device from overheating? I am aware that we should subscribe to Thermal State Notifications and throttle performance accordingly—such as by reducing streaming quality or temporarily disabling active features. Beyond these measures, are there any other strategies you recommend to mitigate thermal issues and help the device cool down?
1
0
334
Dec ’25
Any alternative to use Private API's in mac App store Application
I understand that private APIs are not permitted under Apple’s App Review Guidelines. However, our application requires I²C communication, and we are currently using the following APIs: IOAVServiceReadI2C IOAVServiceWriteI2C IOI2CSendRequest.These api's are not permitted by apple. I didnt found any alternative public api to achieve I²C communication. please suggest any public api's for the same or any chance to use this private api.
3
0
462
Feb ’26
How to prevent the popup "The disk you attached was not readable by the computer" from appearing?
Hello! We develop a SAS driver and a service application for DAS devices. When users in our application create a RAID array on the device: On the 1st step, our dext driver mounts a new volume. At this step DiskUtil automatically tries to mount it. As there is no file system on the new volume - the MacOS system popup appears "The disk you attached was not readable by the computer" On the 2nd step our application creates the file system on this new volume. So we do not need this MacOS system popup to appear (as it may frustrate our users). We found a way to disable the global auto mount but this solution also impacts on other devices (which is not good). Are there any other possibilities to prevent the popup "The disk you attached was not readable by the computer" from appearing?
3
0
288
Jan ’26
MacOS(Apple Silicon) IOKit driver for FPGA DMA transmission, kernel panic.
MacOS(Apple Silicon) IOKit driver for FPGA DMA transmission, kernel panic. Hardware and software configuration: MAC mini M1 2020 16GB, macOS Ventura 13.0 or 13.7.8 FPGA device capability: 64-bit Complete description: We've developed a DMA driver for PCIe devices (FPGA) based on IOKit. The driver can start normally through kextload, and the bar mapping, DMA registers, etc. are all correct. I am testing DMA data transmission, but a kernel panic has occurred. The specific content of the panic is as follows: {"bug_type":"210","timestamp":"2026-01-28 14:35:30.00 +0800","os_version":"macOS 13.0 (22A380)","roots_installed":0,"incident_id":"61C9B820-8D1B-4E75-A4EB-10DC2558FA75"} { "build" : "macOS 13.0 (22A380)", "product" : "Macmini9,1", "socId" : "0x00008103", "kernel" : "Darwin Kernel Version 22.1.0: Sun Oct 9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103", "incident" : "61C9B820-8D1B-4E75-A4EB-10DC2558FA75", "crashReporterKey" : "6435F6BD-4138-412A-5142-83DD7E5B4F61", "date" : "2026-01-28 14:35:30.16 +0800", "panicString" : "panic(cpu 0 caller 0xfffffe0026c78c2c): "apciec[pcic0-bridge]::handleInterrupt: Request address is greater than 32 bits linksts=0x99000001 pcielint=0x02220060 linkcdmsts=0x00000000 (ltssm 0x11=L0)\n" @AppleT8103PCIeCPort.cpp:1301\nDebugger message: panic\nMemory ID: 0x6\nOS release type: User\nOS version: 22A380\nKernel version: Darwin Kernel Version 22.1.0: Sun Oct 9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103\nFileset Kernelcache UUID: C222B4132B9708E5E0E2E8B8C5896410\nKernel UUID: 0BFE6A5D-118B-3889-AE2B-D34A0117A062\nBoot session UUID: 61C9B820-8D1B-4E75-A4EB-10DC2558FA75\niBoot version: iBoot-8419.41.10\nsecure boot?: YES\nroots installed: 0\nPaniclog version: 14\nKernelCache slide: 0x000000001d1b4000\nKernelCache base: 0xfffffe00241b8000\nKernel slide: 0x000000001e3f8000\nKernel text base: 0xfffffe00253fc000\nKernel text exec slide: 0x000000001e4e0000\nKernel text exec base: 0xfffffe00254e4000\nmach_absolute_time: 0x907c3082\nEpoch Time: sec usec\n Boot : 0x6979adbb 0x00023a6a\n Sleep : 0x00000000 0x00000000\n Wake : 0x00000000 0x00000000\n Calendar: 0x6979ae1a 0x00064953\n\nZone info:\n Zone map: 0xfffffe1000834000 - 0xfffffe3000834000\n . VM : 0xfffffe1000834000 - 0xfffffe14cd500000\n . RO : 0xfffffe14cd500000 - 0xfffffe1666e98000\n . GEN0 : 0xfffffe1666e98000 - 0xfffffe1b33b64000\n . GEN1 : 0xfffffe1b33b64000 - 0xfffffe2000830000\n . GEN2 : 0xfffffe2000830000 - 0xfffffe24cd4fc000\n . GEN3 : 0xfffffe24cd4fc000 - 0xfffffe299a1c8000\n . DATA : 0xfffffe299a1c8000 - 0xfffffe3000834000\n Metadata: 0xfffffe3f4d1ac000 - 0xfffffe3f551ac000\n Bitmaps : 0xfffffe3f551ac000 - 0xfffffe3f5ac94000\n\nCORE 0 recently retired instr at 0xfffffe002569d7a0\nCORE 1 recently retired instr at 0xfffffe002569eea0\nCORE 2 recently retired instr at 0xfffffe002569eea0\nCORE 3 recently retired instr at 0xfffffe002569eea0\nCORE 4 recently retired instr at 0xfffffe002569eea0\nCORE 5 recently retired instr at 0xfffffe002569eea0\nCORE 6 recently retired instr at 0xfffffe002569eea0\nCORE 7 recently retired instr at 0xfffffe002569eea0\nTPIDRx_ELy = {1: 0xfffffe2000c23010 0: 0x0000000000000000 0ro: 0x0000000000000000 }\nCORE 0 PVH locks held: None\nCORE 1 PVH locks held: None\nCORE 2 PVH locks held: None\nCORE 3 PVH locks held: None\nCORE 4 PVH locks held: None\nCORE 5 PVH locks held: None\nCORE 6 PVH locks held: None\nCORE 7 PVH locks held: None\nCORE 0 is the one that panicked. Check the full backtrace for details.\nCORE 1: PC=0xfffffe00279db94c, LR=0xfffffe00260d5d9c, FP=0xfffffe8ffecaf850\nCORE 2: PC=0xfffffe0025be76b0, LR=0xfffffe0025be7628, FP=0xfffffe8fff08f5f0\nCORE 3: PC=0x00000001c7cacd78, LR=0x00000001c7cacd84, FP=0x000000016f485130\nCORE 4: PC=0xfffffe002557f55c, LR=0xfffffe002557f55c, FP=0xfffffe8ffe1dff00\nCORE 5: PC=0xfffffe002557f55c, LR=0xfffffe002557f55c, FP=0xfffffe8fff5eff00\nCORE 6: PC=0xfffffe002557f55c, LR=0xfffffe002557f55c, FP=0xfffffe8ffed8bf00\nCORE 7: PC=0xfffffe002557f55c, LR=0xfffffe002557f55c, FP=0xfffffe8fff11bf00\nCompressor Info: 0% of compressed pages limit (OK) and 0% of segments limit (OK) with 0 swapfiles and OK swap space\nPanicked task 0xfffffe1b33aad678: 0 pages, 470 threads: pid 0: kernel_task\nPanicked thread: 0xfffffe2000c23010, backtrace: 0xfffffe8fff6eb6a0, tid: 265\n\t\t ... Kernel Extensions in backtrace:\n com.apple.driver.AppleT8103PCIeC(1.0)[A595D104-026A-39E5-93AA-4C87CE8C14D2]@0xfffffe0026c619d0->0xfffffe0026c86c97\n dependency: com.apple.driver.AppleARMPlatform(1.0.2)[11A9713E-6739-3A4C-8571-2D8EAA062278]@0xfffffe0025f13ff0->0xfffffe0025f6255f\n dependency: com.apple.driver.AppleEmbeddedPCIE(1)[E71CBCCD-AEB8-3E7B-933D-4FED4241BF13]@0xfffffe002654e0b0->0xfffffe00265684c7\n dependency: com.apple.driver.ApplePIODMA(1)[A419BABC-A7A3-316D-A150-7C2C2D1F6D53]@0xfffffe00269a24b0->0xfffffe00269a6c3b\n dependency: com.apple.driver.IODARTFamily(1)[03997E20-8A3F-3412-A4E8-BD968A75A07D]@0xfffffe00275bcf50->0xfffffe00275d0a3f\n dependency: com.apple.iokit.IOPCIFamily(2.9)[EC78F47B-530B-3F87-854E-0A0A5FD9BBB2]@0xfffffe0027934350->0xfffffe002795f3d3\n dependency: com.apple.iokit.IOReportFamily(47)[843B39D3-146E-3992-B7C7-960148685DC8]@0xfffffe0027963010->0xfffffe0027965ffb\n dependency: com.apple.iokit.IOThunderboltFamily(9.3.3)[B22BC005-BB7B-32A3-99C0-39F3BDBD8E54]@0xfffffe0027a5e3f0->0xfffffe0027b9a1a3\n\nlast started kext at 1915345919: com.sobb.pcie-dma\t1.0.0d1 (addr 0xfffffe00240e47f0, size 9580)\nlast stopped kext at 1774866338: com.sobb.pcie-dma\t1.0.0d1 (addr 0xfffffe00240e47f0, size 9580)\nloaded It seems that the DMA request address initiated by FPGA exceeded 32 bits, which was intercepted by PCIe root port and resulted in a kernel panic.This is also the case on macOS (M2). I have tried the following code interface: IOBufferMemoryDescriptor: a. withCapacity(bufferSize, kIODirectionInOut, true); b. inTaskWithPhysicalMask(kernel_task, kIODirectionInOut, bufferSize, 0x00000000FFFFFFFFULL)。 The physical addresses of the constructed descriptors are all >32 bits; IODMACommand: a. withSpecification(kIODMACommandOutputHost64, 64, 0, IODMACommand::kMapped, 0, 0),gen64IOVMSegments() The allocated IOVM address must be>32 bits, which will generate a kernel panic when used later. b.withSpecification(kIODMACommandOutputHost32, 32, 0, IODMACommand::kMapped, 0, 0),gen32IOVMSegments() The allocation of IOVM failed with error code kIOReturnenMessageTooLarge. So after the above attempts, the analysis shows that the strategy of Dart+PCIe root port on macOS (Apple Silicon) is causing the failure of 64 bit DMA address transfer. I have two questions: a. Does Dart in macOS (Apple Silicon) definitely not allocate <=32-bit IOVM addresses? b. Is there any other way to achieve DMA transfer for FGPA devices on macOS (Apple Silicon)? Thanks!
9
0
467
Feb ’26
ioreg AVBControllerState - AVB/EAV Mode
Hello. To determine wether "AVB/EAV Mode" of a AV-capable network interfaces is turned on or off I query the IO registry and evaluate the property "AVBControllerState". I was wondering if this is the "correct" approach and if there is anything known about the values for this property? Network interfaces without AV capability may also carry this property (e.g.: for my WiFi adapter the value of 1) whereas the value for interfaces with AV capability can be 0 and 3. At least as far as I could observe with my limited amount of test devices at hand. Is it safe to assume that a value of 3 means this feature is turned on, 0 that it is turned off and ignore values of 1? Is there another approach to get to know the status of the "AVB/EAV Mode"? Thanks for any insight. Best regards, Ingo
0
0
113
Feb ’26
Can't get USBSerialDriverKit driver loaded
I am writing a DriverKit driver for the first that uses the USBSerialDriverKit. The driver its purpose is to expose the device as serial interface (/dev/cu.tetra-pei0 or something like this). My problem: I don't see any logs from that driver in the console and I tried like 40 different approaches and checked everything. The last message I see is that the driver get successfully added to the system it is in the list of active and enabled system driver extensions but when I plug the device in none of my logs appear and it doesn't show up in ioreg. So without my driver the target device looks like this: +-o TETRA PEI interface@02120000 <class IOUSBHostDevice, id 0x10000297d, registered, matched, active, busy 0 (13 ms), retain 30> | { | "sessionID" = 268696051410 | "USBSpeed" = 3 | "UsbLinkSpeed" = 480000000 | "idProduct" = 36886 | "iManufacturer" = 1 | "bDeviceClass" = 0 | "IOPowerManagement" = {"PowerOverrideOn"=Yes,"DevicePowerState"=2,"CurrentPowerState"=2,"CapabilityFlags"=32768,"MaxPowerState"=2,"DriverPowerState"=0} | "bcdDevice" = 9238 | "bMaxPacketSize0" = 64 | "iProduct" = 2 | "iSerialNumber" = 0 | "bNumConfigurations" = 1 | "UsbDeviceSignature" = <ad0c16901624000000ff0000> | "USB Product Name" = "TETRA PEI interface" | "locationID" = 34734080 | "bDeviceSubClass" = 0 | "bcdUSB" = 512 | "USB Address" = 6 | "kUSBCurrentConfiguration" = 1 | "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "UsbPowerSinkAllocation" = 500 | "bDeviceProtocol" = 0 | "USBPortType" = 0 | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | "USB Vendor Name" = "Motorola Solutions, Inc." | "Device Speed" = 2 | "idVendor" = 3245 | "kUSBProductString" = "TETRA PEI interface" | "kUSBAddress" = 6 | "kUSBVendorString" = "Motorola Solutions, Inc." | } | +-o AppleUSBHostCompositeDevice <class AppleUSBHostCompositeDevice, id 0x100002982, !registered, !matched, active, busy 0, retain 5> | { | "IOProbeScore" = 50000 | "CFBundleIdentifier" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "IOProviderClass" = "IOUSBHostDevice" | "IOClass" = "AppleUSBHostCompositeDevice" | "IOPersonalityPublisher" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "bDeviceSubClass" = 0 | "CFBundleIdentifierKernel" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "IOMatchedAtBoot" = Yes | "IOMatchCategory" = "IODefaultMatchCategory" | "IOPrimaryDriverTerminateOptions" = Yes | "bDeviceClass" = 0 | } | +-o lghub_agent <class AppleUSBHostDeviceUserClient, id 0x100002983, !registered, !matched, active, busy 0, retain 7> | { | "IOUserClientCreator" = "pid 1438, lghub_agent" | "IOUserClientDefaultLocking" = Yes | } | +-o IOUSBHostInterface@0 <class IOUSBHostInterface, id 0x100002986, registered, matched, active, busy 0 (5 ms), retain 9> | | { | | "USBPortType" = 0 | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | "USB Vendor Name" = "Motorola Solutions, Inc." | | "bcdDevice" = 9238 | | "USBSpeed" = 3 | | "idProduct" = 36886 | | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | | "bInterfaceSubClass" = 0 | | "bConfigurationValue" = 1 | | "locationID" = 34734080 | | "USB Product Name" = "TETRA PEI interface" | | "bInterfaceProtocol" = 0 | | "iInterface" = 0 | | "bAlternateSetting" = 0 | | "idVendor" = 3245 | | "bInterfaceNumber" = 0 | | "bInterfaceClass" = 255 | | "bNumEndpoints" = 2 | | } | | | +-o lghub_agent <class AppleUSBHostInterfaceUserClient, id 0x100002988, !registered, !matched, active, busy 0, retain 6> | { | "UsbUserClientBufferStatistics" = {"IOMemoryDescriptor"=0,"IOBufferMemoryDescriptor"=0,"IOSubMemoryDescriptor"=0} | "IOUserClientCreator" = "pid 1438, lghub_agent" | "UsbUserClientBufferAllocations" = {"Bytes"=0,"Descriptors"=0} | "IOUserClientDefaultLocking" = Yes | } | +-o IOUSBHostInterface@1 <class IOUSBHostInterface, id 0x100002987, registered, matched, active, busy 0 (5 ms), retain 9> | { | "USBPortType" = 0 | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "USB Vendor Name" = "Motorola Solutions, Inc." | "bcdDevice" = 9238 | "USBSpeed" = 3 | "idProduct" = 36886 | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | "bInterfaceSubClass" = 0 | "bConfigurationValue" = 1 | "locationID" = 34734080 | "USB Product Name" = "TETRA PEI interface" | "bInterfaceProtocol" = 0 | "iInterface" = 0 | "bAlternateSetting" = 0 | "idVendor" = 3245 | "bInterfaceNumber" = 1 | "bInterfaceClass" = 255 | "bNumEndpoints" = 2 | } | +-o lghub_agent <class AppleUSBHostInterfaceUserClient, id 0x10000298a, !registered, !matched, active, busy 0, retain 6> { "UsbUserClientBufferStatistics" = {"IOMemoryDescriptor"=0,"IOBufferMemoryDescriptor"=0,"IOSubMemoryDescriptor"=0} "IOUserClientCreator" = "pid 1438, lghub_agent" "UsbUserClientBufferAllocations" = {"Bytes"=0,"Descriptors"=0} "IOUserClientDefaultLocking" = Yes } more details in my comment.
6
0
214
Mar ’26
How can I locate a UVC camera for PTZ control by AVCaptureDevice.unique_id
I'm writing a program to control a PTZ camera connected via USB. I can get access to target camera's unique_id, and also other infos provided by AVFoundation. But I don't know how to locate my target USB device to send a UVC ControlRequest. There's many Cameras with same VendorID and ProductID connected at a time, so I need a more exact way to find out which device is my target. It looks that the unique_id provided is (locationID<<32|VendorID<<16|ProductID) as hex string, but I'm not sure if I can always assume this behavior won't change. Is there's a document declares how AVFoundation generate the unique_id for USB camera, so I can assume this convert will always work? Or is there's a way to send a PTZ control request to AVCaptureDevice? https://stackoverflow.com/questions/40006908/usb-interface-of-an-avcapturedevice I have seen this similar question. But I'm worrying that Exacting LocationID+VendorID+ProductID from unique_id seems like programming to implementation instead of interface. So, if there's any other better way to control my camera? here's my example code for getting unique_id: // // camera_unique_id_test.mm // // 测试代码:使用C++获取当前系统摄像头的AVCaptureDevice unique_id // // 编译命令: // clang++ -framework AVFoundation -framework CoreMedia -framework Foundation // camera_unique_id_test.mm -o camera_unique_id_test // #include <iostream> #include <string> #include <vector> #import <AVFoundation/AVFoundation.h> #import <Foundation/Foundation.h> struct CameraInfo { std::string uniqueId; }; std::vector<CameraInfo> getAllCameraDevices() { std::vector<CameraInfo> cameras; @autoreleasepool { NSArray<AVCaptureDevice*>* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; AVCaptureDevice* defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; // 遍历所有设备 for (AVCaptureDevice* device in devices) { CameraInfo info; // 获取unique_id info.uniqueId = std::string([device.uniqueID UTF8String]); cameras.push_back(info); } } return cameras; } int main(int argc, char* argv[]) { std::vector<CameraInfo> cameras = getAllCameraDevices(); for (size_t i = 0; i < cameras.size(); i++) { const CameraInfo& camera = cameras[i]; std::cout << " 设备 " << (i + 1) << ":" << std::endl; std::cout << " unique_id: " << camera.uniqueId << std::endl; } return 0; } and here's my code for UVC control: // clang++ -framework Foundation -framework IOKit uvc_test.cpp -o uvc_test #include <iostream> #include <CoreFoundation/CoreFoundation.h> #include <IOKit/IOCFPlugIn.h> #include <IOKit/IOKitLib.h> #include <IOKit/IOMessage.h> #include <IOKit/usb/IOUSBLib.h> #include <IOKit/usb/USB.h> CFStringRef CreateCFStringFromIORegistryKey(io_service_t ioService, const char* key) { CFStringRef keyString = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); if (!keyString) return nullptr; CFStringRef result = static_cast<CFStringRef>( IORegistryEntryCreateCFProperty(ioService, keyString, kCFAllocatorDefault, kIORegistryIterateRecursively)); CFRelease(keyString); return result; } std::string GetStringFromIORegistry(io_service_t ioService, const char* key) { CFStringRef cfString = CreateCFStringFromIORegistryKey(ioService, key); if (!cfString) return ""; char buffer[256]; Boolean success = CFStringGetCString(cfString, buffer, sizeof(buffer), kCFStringEncodingUTF8); CFRelease(cfString); return success ? std::string(buffer) : std::string(""); } uint32_t GetUInt32FromIORegistry(io_service_t ioService, const char* key) { CFStringRef keyString = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); if (!keyString) return 0; CFNumberRef number = static_cast<CFNumberRef>( IORegistryEntryCreateCFProperty(ioService, keyString, kCFAllocatorDefault, kIORegistryIterateRecursively)); CFRelease(keyString); if (!number) return 0; uint32_t value = 0; CFNumberGetValue(number, kCFNumberSInt32Type, &value); CFRelease(number); return value; } int main() { // Get matching dictionary for USB devices CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Get iterator for matching services io_iterator_t serviceIterator; IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &serviceIterator); // Iterate through matching devices io_service_t usbService; while ((usbService = IOIteratorNext(serviceIterator))) { uint32_t locationId = GetUInt32FromIORegistry(usbService, "locationID"); uint32_t vendorId = GetUInt32FromIORegistry(usbService, "idVendor"); uint32_t productId = GetUInt32FromIORegistry(usbService, "idProduct"); IOCFPlugInInterface** plugInInterface = nullptr; IOUSBDeviceInterface** deviceInterface = nullptr; SInt32 score; // Get device plugin interface IOCreatePlugInInterfaceForService(usbService, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); // Get device interface (*plugInInterface) ->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&deviceInterface); (*plugInInterface)->Release(plugInInterface); // Try to find UVC control interface using CreateInterfaceIterator io_iterator_t interfaceIterator; IOUSBFindInterfaceRequest interfaceRequest; interfaceRequest.bInterfaceClass = kUSBVideoInterfaceClass; // 14 interfaceRequest.bInterfaceSubClass = kUSBVideoControlSubClass; // 1 interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; interfaceRequest.bAlternateSetting = kIOUSBFindInterfaceDontCare; (*deviceInterface) ->CreateInterfaceIterator(deviceInterface, &interfaceRequest, &interfaceIterator); (*deviceInterface)->Release(deviceInterface); io_service_t usbInterface = IOIteratorNext(interfaceIterator); IOObjectRelease(interfaceIterator); if (usbInterface) { std::cout << "Get UVC device with:" << std::endl; std::cout << "locationId: " << std::hex << locationId << std::endl; std::cout << "vendorId: " << std::hex << vendorId << std::endl; std::cout << "productId: " << std::hex << productId << std::endl << std::endl; IOObjectRelease(usbInterface); } IOObjectRelease(usbService); } IOObjectRelease(serviceIterator); }
Replies
2
Boosts
0
Views
353
Activity
Oct ’25
Mac Catalyst: IOHID InputReportCallback not firing, USBInterfaceOpen returns kIOReturnNotPermitted (0xe00002e2) for custom HID device
Hi everyone, I am developing a .NET MAUI Mac Catalyst app (sandboxed) that communicates with a custom vendor-specific HID USB device. Within the Catalyst app, I am using a native iOS library (built with Objective-C and IOKit) and calling into it via P/Invoke from C#. The HID communication layer relies on IOHIDManager and IOUSBInterface APIs. The device is correctly detected and opened using IOHIDManager APIs. However, IOHIDDeviceRegisterInputReportCallback never triggers — I don’t receive any input reports. To investigate, I also tried using low-level IOKit USB APIs via P/Invoke from my Catalyst app, calling into a native iOS library. When attempting to open the USB interface using IOUSBInterfaceOpen() or IOUSBInterfaceOpenSeize(), both calls fail with: kIOReturnNotPermitted (0xe00002e2). — indicating an access denied error, even though the device enumerates and opens successfully. Interestingly, when I call IOHIDDeviceSetReport(), it returns status = 0, meaning I can successfully send feature reports to the device. Only input reports (via the InputReportCallback) fail to arrive. I’ve confirmed this is not a device issue — the same hardware and protocol work perfectly under Windows using the HIDSharp library, where both input and output reports function correctly. What I’ve verified •Disabling sandboxing doesn’t change the behavior. •The device uses a vendor-specific usage page (not a standard HID like keyboard/mouse). •Enumeration, open, and SetReport all succeed — only reading input reports fails. •Tried polling queues, in queues Input_Misc element failed to add to the queues. •Tried getting report in a loop but no use.
Replies
2
Boosts
0
Views
237
Activity
Oct ’25
Thermal management on iOS
I would like to inquire about Apple's recommended best practices for iPhone thermal management. Specifically, what actions are developers expected to take to prevent the device from overheating? I am aware that we should subscribe to Thermal State Notifications and throttle performance accordingly—such as by reducing streaming quality or temporarily disabling active features. Beyond these measures, are there any other strategies you recommend to mitigate thermal issues and help the device cool down?
Replies
1
Boosts
0
Views
183
Activity
Dec ’25
Thermal management on iOS
I would like to inquire about Apple's recommended best practices for iPhone thermal management. Specifically, what actions are developers expected to take to prevent the device from overheating? I am aware that we should subscribe to Thermal State Notifications and throttle performance accordingly—such as by reducing streaming quality or temporarily disabling active features. Beyond these measures, are there any other strategies you recommend to mitigate thermal issues and help the device cool down?
Replies
1
Boosts
0
Views
334
Activity
Dec ’25
Virtual Controllers on Mac via the Game Controller Framework
Hi fellow devs, I have a quick question is it possible to have virtual controllers on Mac. For instance can my app exclusively manage the controller and output it into the Game Controller framework? And create a virtual controller to allow for features such as controller emulation, haptic control, and others.
Replies
7
Boosts
0
Views
743
Activity
Jan ’26
Any alternative to use Private API's in mac App store Application
I understand that private APIs are not permitted under Apple’s App Review Guidelines. However, our application requires I²C communication, and we are currently using the following APIs: IOAVServiceReadI2C IOAVServiceWriteI2C IOI2CSendRequest.These api's are not permitted by apple. I didnt found any alternative public api to achieve I²C communication. please suggest any public api's for the same or any chance to use this private api.
Replies
3
Boosts
0
Views
462
Activity
Feb ’26
How to prevent the popup "The disk you attached was not readable by the computer" from appearing?
Hello! We develop a SAS driver and a service application for DAS devices. When users in our application create a RAID array on the device: On the 1st step, our dext driver mounts a new volume. At this step DiskUtil automatically tries to mount it. As there is no file system on the new volume - the MacOS system popup appears "The disk you attached was not readable by the computer" On the 2nd step our application creates the file system on this new volume. So we do not need this MacOS system popup to appear (as it may frustrate our users). We found a way to disable the global auto mount but this solution also impacts on other devices (which is not good). Are there any other possibilities to prevent the popup "The disk you attached was not readable by the computer" from appearing?
Replies
3
Boosts
0
Views
288
Activity
Jan ’26
MacOS(Apple Silicon) IOKit driver for FPGA DMA transmission, kernel panic.
MacOS(Apple Silicon) IOKit driver for FPGA DMA transmission, kernel panic. Hardware and software configuration: MAC mini M1 2020 16GB, macOS Ventura 13.0 or 13.7.8 FPGA device capability: 64-bit Complete description: We've developed a DMA driver for PCIe devices (FPGA) based on IOKit. The driver can start normally through kextload, and the bar mapping, DMA registers, etc. are all correct. I am testing DMA data transmission, but a kernel panic has occurred. The specific content of the panic is as follows: {"bug_type":"210","timestamp":"2026-01-28 14:35:30.00 +0800","os_version":"macOS 13.0 (22A380)","roots_installed":0,"incident_id":"61C9B820-8D1B-4E75-A4EB-10DC2558FA75"} { "build" : "macOS 13.0 (22A380)", "product" : "Macmini9,1", "socId" : "0x00008103", "kernel" : "Darwin Kernel Version 22.1.0: Sun Oct 9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103", "incident" : "61C9B820-8D1B-4E75-A4EB-10DC2558FA75", "crashReporterKey" : "6435F6BD-4138-412A-5142-83DD7E5B4F61", "date" : "2026-01-28 14:35:30.16 +0800", "panicString" : "panic(cpu 0 caller 0xfffffe0026c78c2c): "apciec[pcic0-bridge]::handleInterrupt: Request address is greater than 32 bits linksts=0x99000001 pcielint=0x02220060 linkcdmsts=0x00000000 (ltssm 0x11=L0)\n" @AppleT8103PCIeCPort.cpp:1301\nDebugger message: panic\nMemory ID: 0x6\nOS release type: User\nOS version: 22A380\nKernel version: Darwin Kernel Version 22.1.0: Sun Oct 9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103\nFileset Kernelcache UUID: C222B4132B9708E5E0E2E8B8C5896410\nKernel UUID: 0BFE6A5D-118B-3889-AE2B-D34A0117A062\nBoot session UUID: 61C9B820-8D1B-4E75-A4EB-10DC2558FA75\niBoot version: iBoot-8419.41.10\nsecure boot?: YES\nroots installed: 0\nPaniclog version: 14\nKernelCache slide: 0x000000001d1b4000\nKernelCache base: 0xfffffe00241b8000\nKernel slide: 0x000000001e3f8000\nKernel text base: 0xfffffe00253fc000\nKernel text exec slide: 0x000000001e4e0000\nKernel text exec base: 0xfffffe00254e4000\nmach_absolute_time: 0x907c3082\nEpoch Time: sec usec\n Boot : 0x6979adbb 0x00023a6a\n Sleep : 0x00000000 0x00000000\n Wake : 0x00000000 0x00000000\n Calendar: 0x6979ae1a 0x00064953\n\nZone info:\n Zone map: 0xfffffe1000834000 - 0xfffffe3000834000\n . VM : 0xfffffe1000834000 - 0xfffffe14cd500000\n . RO : 0xfffffe14cd500000 - 0xfffffe1666e98000\n . GEN0 : 0xfffffe1666e98000 - 0xfffffe1b33b64000\n . GEN1 : 0xfffffe1b33b64000 - 0xfffffe2000830000\n . GEN2 : 0xfffffe2000830000 - 0xfffffe24cd4fc000\n . GEN3 : 0xfffffe24cd4fc000 - 0xfffffe299a1c8000\n . DATA : 0xfffffe299a1c8000 - 0xfffffe3000834000\n Metadata: 0xfffffe3f4d1ac000 - 0xfffffe3f551ac000\n Bitmaps : 0xfffffe3f551ac000 - 0xfffffe3f5ac94000\n\nCORE 0 recently retired instr at 0xfffffe002569d7a0\nCORE 1 recently retired instr at 0xfffffe002569eea0\nCORE 2 recently retired instr at 0xfffffe002569eea0\nCORE 3 recently retired instr at 0xfffffe002569eea0\nCORE 4 recently retired instr at 0xfffffe002569eea0\nCORE 5 recently retired instr at 0xfffffe002569eea0\nCORE 6 recently retired instr at 0xfffffe002569eea0\nCORE 7 recently retired instr at 0xfffffe002569eea0\nTPIDRx_ELy = {1: 0xfffffe2000c23010 0: 0x0000000000000000 0ro: 0x0000000000000000 }\nCORE 0 PVH locks held: None\nCORE 1 PVH locks held: None\nCORE 2 PVH locks held: None\nCORE 3 PVH locks held: None\nCORE 4 PVH locks held: None\nCORE 5 PVH locks held: None\nCORE 6 PVH locks held: None\nCORE 7 PVH locks held: None\nCORE 0 is the one that panicked. Check the full backtrace for details.\nCORE 1: PC=0xfffffe00279db94c, LR=0xfffffe00260d5d9c, FP=0xfffffe8ffecaf850\nCORE 2: PC=0xfffffe0025be76b0, LR=0xfffffe0025be7628, FP=0xfffffe8fff08f5f0\nCORE 3: PC=0x00000001c7cacd78, LR=0x00000001c7cacd84, FP=0x000000016f485130\nCORE 4: PC=0xfffffe002557f55c, LR=0xfffffe002557f55c, FP=0xfffffe8ffe1dff00\nCORE 5: PC=0xfffffe002557f55c, LR=0xfffffe002557f55c, FP=0xfffffe8fff5eff00\nCORE 6: PC=0xfffffe002557f55c, LR=0xfffffe002557f55c, FP=0xfffffe8ffed8bf00\nCORE 7: PC=0xfffffe002557f55c, LR=0xfffffe002557f55c, FP=0xfffffe8fff11bf00\nCompressor Info: 0% of compressed pages limit (OK) and 0% of segments limit (OK) with 0 swapfiles and OK swap space\nPanicked task 0xfffffe1b33aad678: 0 pages, 470 threads: pid 0: kernel_task\nPanicked thread: 0xfffffe2000c23010, backtrace: 0xfffffe8fff6eb6a0, tid: 265\n\t\t ... Kernel Extensions in backtrace:\n com.apple.driver.AppleT8103PCIeC(1.0)[A595D104-026A-39E5-93AA-4C87CE8C14D2]@0xfffffe0026c619d0->0xfffffe0026c86c97\n dependency: com.apple.driver.AppleARMPlatform(1.0.2)[11A9713E-6739-3A4C-8571-2D8EAA062278]@0xfffffe0025f13ff0->0xfffffe0025f6255f\n dependency: com.apple.driver.AppleEmbeddedPCIE(1)[E71CBCCD-AEB8-3E7B-933D-4FED4241BF13]@0xfffffe002654e0b0->0xfffffe00265684c7\n dependency: com.apple.driver.ApplePIODMA(1)[A419BABC-A7A3-316D-A150-7C2C2D1F6D53]@0xfffffe00269a24b0->0xfffffe00269a6c3b\n dependency: com.apple.driver.IODARTFamily(1)[03997E20-8A3F-3412-A4E8-BD968A75A07D]@0xfffffe00275bcf50->0xfffffe00275d0a3f\n dependency: com.apple.iokit.IOPCIFamily(2.9)[EC78F47B-530B-3F87-854E-0A0A5FD9BBB2]@0xfffffe0027934350->0xfffffe002795f3d3\n dependency: com.apple.iokit.IOReportFamily(47)[843B39D3-146E-3992-B7C7-960148685DC8]@0xfffffe0027963010->0xfffffe0027965ffb\n dependency: com.apple.iokit.IOThunderboltFamily(9.3.3)[B22BC005-BB7B-32A3-99C0-39F3BDBD8E54]@0xfffffe0027a5e3f0->0xfffffe0027b9a1a3\n\nlast started kext at 1915345919: com.sobb.pcie-dma\t1.0.0d1 (addr 0xfffffe00240e47f0, size 9580)\nlast stopped kext at 1774866338: com.sobb.pcie-dma\t1.0.0d1 (addr 0xfffffe00240e47f0, size 9580)\nloaded It seems that the DMA request address initiated by FPGA exceeded 32 bits, which was intercepted by PCIe root port and resulted in a kernel panic.This is also the case on macOS (M2). I have tried the following code interface: IOBufferMemoryDescriptor: a. withCapacity(bufferSize, kIODirectionInOut, true); b. inTaskWithPhysicalMask(kernel_task, kIODirectionInOut, bufferSize, 0x00000000FFFFFFFFULL)。 The physical addresses of the constructed descriptors are all >32 bits; IODMACommand: a. withSpecification(kIODMACommandOutputHost64, 64, 0, IODMACommand::kMapped, 0, 0),gen64IOVMSegments() The allocated IOVM address must be>32 bits, which will generate a kernel panic when used later. b.withSpecification(kIODMACommandOutputHost32, 32, 0, IODMACommand::kMapped, 0, 0),gen32IOVMSegments() The allocation of IOVM failed with error code kIOReturnenMessageTooLarge. So after the above attempts, the analysis shows that the strategy of Dart+PCIe root port on macOS (Apple Silicon) is causing the failure of 64 bit DMA address transfer. I have two questions: a. Does Dart in macOS (Apple Silicon) definitely not allocate <=32-bit IOVM addresses? b. Is there any other way to achieve DMA transfer for FGPA devices on macOS (Apple Silicon)? Thanks!
Replies
9
Boosts
0
Views
467
Activity
Feb ’26
ioreg AVBControllerState - AVB/EAV Mode
Hello. To determine wether "AVB/EAV Mode" of a AV-capable network interfaces is turned on or off I query the IO registry and evaluate the property "AVBControllerState". I was wondering if this is the "correct" approach and if there is anything known about the values for this property? Network interfaces without AV capability may also carry this property (e.g.: for my WiFi adapter the value of 1) whereas the value for interfaces with AV capability can be 0 and 3. At least as far as I could observe with my limited amount of test devices at hand. Is it safe to assume that a value of 3 means this feature is turned on, 0 that it is turned off and ignore values of 1? Is there another approach to get to know the status of the "AVB/EAV Mode"? Thanks for any insight. Best regards, Ingo
Replies
0
Boosts
0
Views
113
Activity
Feb ’26
Can't get USBSerialDriverKit driver loaded
I am writing a DriverKit driver for the first that uses the USBSerialDriverKit. The driver its purpose is to expose the device as serial interface (/dev/cu.tetra-pei0 or something like this). My problem: I don't see any logs from that driver in the console and I tried like 40 different approaches and checked everything. The last message I see is that the driver get successfully added to the system it is in the list of active and enabled system driver extensions but when I plug the device in none of my logs appear and it doesn't show up in ioreg. So without my driver the target device looks like this: +-o TETRA PEI interface@02120000 <class IOUSBHostDevice, id 0x10000297d, registered, matched, active, busy 0 (13 ms), retain 30> | { | "sessionID" = 268696051410 | "USBSpeed" = 3 | "UsbLinkSpeed" = 480000000 | "idProduct" = 36886 | "iManufacturer" = 1 | "bDeviceClass" = 0 | "IOPowerManagement" = {"PowerOverrideOn"=Yes,"DevicePowerState"=2,"CurrentPowerState"=2,"CapabilityFlags"=32768,"MaxPowerState"=2,"DriverPowerState"=0} | "bcdDevice" = 9238 | "bMaxPacketSize0" = 64 | "iProduct" = 2 | "iSerialNumber" = 0 | "bNumConfigurations" = 1 | "UsbDeviceSignature" = <ad0c16901624000000ff0000> | "USB Product Name" = "TETRA PEI interface" | "locationID" = 34734080 | "bDeviceSubClass" = 0 | "bcdUSB" = 512 | "USB Address" = 6 | "kUSBCurrentConfiguration" = 1 | "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "UsbPowerSinkAllocation" = 500 | "bDeviceProtocol" = 0 | "USBPortType" = 0 | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | "USB Vendor Name" = "Motorola Solutions, Inc." | "Device Speed" = 2 | "idVendor" = 3245 | "kUSBProductString" = "TETRA PEI interface" | "kUSBAddress" = 6 | "kUSBVendorString" = "Motorola Solutions, Inc." | } | +-o AppleUSBHostCompositeDevice <class AppleUSBHostCompositeDevice, id 0x100002982, !registered, !matched, active, busy 0, retain 5> | { | "IOProbeScore" = 50000 | "CFBundleIdentifier" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "IOProviderClass" = "IOUSBHostDevice" | "IOClass" = "AppleUSBHostCompositeDevice" | "IOPersonalityPublisher" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "bDeviceSubClass" = 0 | "CFBundleIdentifierKernel" = "com.apple.driver.usb.AppleUSBHostCompositeDevice" | "IOMatchedAtBoot" = Yes | "IOMatchCategory" = "IODefaultMatchCategory" | "IOPrimaryDriverTerminateOptions" = Yes | "bDeviceClass" = 0 | } | +-o lghub_agent <class AppleUSBHostDeviceUserClient, id 0x100002983, !registered, !matched, active, busy 0, retain 7> | { | "IOUserClientCreator" = "pid 1438, lghub_agent" | "IOUserClientDefaultLocking" = Yes | } | +-o IOUSBHostInterface@0 <class IOUSBHostInterface, id 0x100002986, registered, matched, active, busy 0 (5 ms), retain 9> | | { | | "USBPortType" = 0 | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | "USB Vendor Name" = "Motorola Solutions, Inc." | | "bcdDevice" = 9238 | | "USBSpeed" = 3 | | "idProduct" = 36886 | | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | | "bInterfaceSubClass" = 0 | | "bConfigurationValue" = 1 | | "locationID" = 34734080 | | "USB Product Name" = "TETRA PEI interface" | | "bInterfaceProtocol" = 0 | | "iInterface" = 0 | | "bAlternateSetting" = 0 | | "idVendor" = 3245 | | "bInterfaceNumber" = 0 | | "bInterfaceClass" = 255 | | "bNumEndpoints" = 2 | | } | | | +-o lghub_agent <class AppleUSBHostInterfaceUserClient, id 0x100002988, !registered, !matched, active, busy 0, retain 6> | { | "UsbUserClientBufferStatistics" = {"IOMemoryDescriptor"=0,"IOBufferMemoryDescriptor"=0,"IOSubMemoryDescriptor"=0} | "IOUserClientCreator" = "pid 1438, lghub_agent" | "UsbUserClientBufferAllocations" = {"Bytes"=0,"Descriptors"=0} | "IOUserClientDefaultLocking" = Yes | } | +-o IOUSBHostInterface@1 <class IOUSBHostInterface, id 0x100002987, registered, matched, active, busy 0 (5 ms), retain 9> | { | "USBPortType" = 0 | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "USB Vendor Name" = "Motorola Solutions, Inc." | "bcdDevice" = 9238 | "USBSpeed" = 3 | "idProduct" = 36886 | "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb")) | "bInterfaceSubClass" = 0 | "bConfigurationValue" = 1 | "locationID" = 34734080 | "USB Product Name" = "TETRA PEI interface" | "bInterfaceProtocol" = 0 | "iInterface" = 0 | "bAlternateSetting" = 0 | "idVendor" = 3245 | "bInterfaceNumber" = 1 | "bInterfaceClass" = 255 | "bNumEndpoints" = 2 | } | +-o lghub_agent <class AppleUSBHostInterfaceUserClient, id 0x10000298a, !registered, !matched, active, busy 0, retain 6> { "UsbUserClientBufferStatistics" = {"IOMemoryDescriptor"=0,"IOBufferMemoryDescriptor"=0,"IOSubMemoryDescriptor"=0} "IOUserClientCreator" = "pid 1438, lghub_agent" "UsbUserClientBufferAllocations" = {"Bytes"=0,"Descriptors"=0} "IOUserClientDefaultLocking" = Yes } more details in my comment.
Replies
6
Boosts
0
Views
214
Activity
Mar ’26
How to get a IOSerialBSDClient attached?
I have a driver extending IOUserUSBSerial and I want the device to show up as /dev/tty.mycustombasename-123 and /dev/cu. respectively. How can I achieve that?
Replies
1
Boosts
0
Views
158
Activity
Feb ’26