IOUSBHost

RSS for tag

Create host-mode user space drivers for USB devices using IOUSBHost.

Posts under IOUSBHost tag

79 Posts

Post

Replies

Boosts

Views

Activity

USB driver for MIDI keyboard
Greetings. I'm trying to build an Apple Silicon driver for a Roland keyboard which is no longer supported by the manufacturer. The most recent official driver is from 2010. From my limited understanding of the Apple documentation, it seems to be telling me that I need to build a codeless dext which overrides some sort of base class. The keyboard uses bog standard USB 1.0 to communicate with the host. Total newb in the driver area so if anyone could point me in the right direction on where to start I would be totally grateful.
0
0
785
Mar ’24
Determining the USB hub port to which an iPad is connected
Hi. I wish I'd found a way to determine the USB hub port to which an iPad is connected, even if it means creating a one-time mapping of identifiers and ports beforehand. I thought I'd find some hardware identifiers that might help, but they appear to fluctuate depending on how the iPad carts are connected to the Mac. Is there anything reliable to achieve the desired result? Thanks for your insights. Franck
0
0
669
Jan ’24
USB DriverKit returning large asynchronous data
Can anyone advise, or give example of, communicating large (>128 byte) incoming buffers from a dext to a user-space app? My specific situation is interrupt reads from a USB device. These return reports which are too large to fit into the asyncData field of an AsyncCompletion call. Apple's CommunicatingBetweenADriverKitExtensionAndAClientApp sample shows examples of returning a "large" struct, but the example is synchronous. The asynchronous example returns data by copying into a IOUserClientAsyncArgumentsArray, which isn't very big. I can allocate a single buffer larger than 4K in user space, and communicate that buffer to my driver as an IOMemoryDescriptor when I set up my async callback. The driver retains the descriptor, maps it into its memory space and can thus write into it when the hardware returns interrupt data. The driver then calls AsyncCompletion, which will cause my user-side callback to be called, so the user side software knows that there's new data available in the previously allocated buffer. That's fine, it works, but there are data race problems - since USB interrupt reads complete whenever the hardware has provided data, incoming completions happen at unpredictable times, so the shared buffer contents could change while the user side code is examining them. Is there an example somewhere of how to deal with this? Can I allocate memory on the driver side on demand, create an IOMemoryDescriptor for it and return that descriptor packed inside the asyncData? If so, how does the driver know when it can relinquish that memory? I have a feeling there's something here I just don't understand...
1
0
944
Jan ’24
USB DriverKit returning large asynchronous data
this is a repost with more appropriate tags. The original is here: https://developer.apple.com/forums/thread/744268 Can anyone advise, or give example of, communicating large (>128 byte) incoming buffers from a dext to a user-space app? My specific situation is interrupt reads from a USB device. These return reports which are too large to fit into the asyncData field of an AsyncCompletion call. Apple's CommunicatingBetweenADriverKitExtensionAndAClientApp sample shows examples of returning a "large" struct, but the example is synchronous. The asynchronous example returns data by copying into a IOUserClientAsyncArgumentsArray, which isn't very big. I can allocate a single buffer larger than 4K in user space, and communicate that buffer to my driver as an IOMemoryDescriptor when I set up my async callback. The driver retains the descriptor, maps it into its memory space and can thus write into it when the hardware returns interrupt data. The driver then calls AsyncCompletion, which will cause my user-side callback to be called, so the user side software knows that there's new data available in the previously allocated buffer. That's fine, it works, but there are data race problems - since USB interrupt reads complete whenever the hardware has provided data, incoming completions happen at unpredictable times, so the shared buffer contents could change while the user side code is examining them. Is there an example somewhere of how to deal with this? Can I allocate memory on the driver side on demand, create an IOMemoryDescriptor for it and return that descriptor packed inside the asyncData? If so, how does the driver know when it can relinquish that memory? I have a feeling there's something here I just don't understand...
0
0
924
Jan ’24
How to develop a driver extension for a USB mass storage device
I am currently in the process of developing a DEXT for a USB based external mass storage device using the USBDriverKit framework. IOUSBHostInterface is used as the provider to communicate with the interface's endpoints and I am successful in it. As per the IOUSBHostInterface documentation, To use a host interface object, call Open to create a new session between the interface and your driver. After successfully opening your session, you can request information from the interface and set up pipes to communicate with the interface's endpoints. Remember to close the session you opened in the Stop method of your driver. However, calling Open gains exclusive access to the USB interface and does not allow other services to access the interface. Also, to let go of the exclusive access, Close method can be called but in the Stop method which is called only once during the lifecycle of the extension (when the DEXT is unloaded). As a result of this, Apple's mass storage related KEXTs (media and partition related specifically) do not match the interface and so the filesystem of the drive in question does not get mounted whenever the DEXT has matched the interface. Is this exclusive access a limitation of USBDriverkit or is there any way to get around this issue in this case?
2
0
1.1k
Nov ’23
Get /dev file name from IOreg?
Hi. I have a class-compliant usb device which announces its serial number as m4121095, as per its kUSBSerialNumberString property. However, the file name it is provided is tty.usbmodemm41210951 – it's the serial number with an additional 1 at the end. What is the meaning of this appendage? (I'm tempted to believe that the 1 at the end is there in the unlikely case another device with the same SN is connected, but there's no way to test this possibility). In the end, I would like to obtain a filename that is guaranteed to be representing a connection to exactly this device. Can I assume that the filename of a device that follows the same protocol of serial numbering will be consistently appended with a number that can in some way be inferred? Thank you.
5
0
1.6k
Jul ’23
Mac M2 pro libusb read/write performance
I am writing a C program on Mac that calls the libUSB API. However, I found some performance differences between the same programs on MAC x64 and MAC M2 systems. Program on Mac m2 call libusb_control_transfer() function is much slower than programs on Mac x64. For example, running a program on Mac x64 takes 3 seconds to complete a function, while on Mac m2 it takes 10 seconds. I try to count the number of times a program calls libusb_control_transfer() and the time it takes each time, and finally calculate the average time it takes to call libusb_control_transfer(). The following figure shows the performance of the program on Mac m2.(Unit is us per time) The following figure shows the performance of the program on Mac x64. (Unit is us per time) The difference in average time spent calling a function has reached over 10 times. Is this performance gap caused by the USB driver or the libUSB library? Thanks.
2
0
1.2k
May ’23
Release ExclusiveAccess to an usb device taken by another application?
Seems like both Dropbox and Google Drive has a pretty sad implementation/bug that acquire exclusive access to USB devices that expose MTP (media transfer protocol). The way google and dropbox did it is just wrong as they 1) should ask for permission for reading data on new devices, 2) not open the usb device in exclusive mode... 3) make use of MTP's Multi-Session mode. Well, as it will take them about 4.5 years to correct this, I wonder if there is a way for a app-store/user-space application in macOS 11/12/13 (big sur, monterey, ventura) to do the following: Detect if there is another app that has exclusive lock to a specific usb device Get the name of the app so that an alert could say, "please quit google-drive for this to work..." Release the exclusive lock, i.e. hand over the usb peripheral to my application
0
0
1.1k
Apr ’23
How to write kernel driver for USB on macOS ?
I am creating a macOS app that will send commands to a USB device when it is plugged into a Mac. There are only two steps to accomplish this: send request commands to the USB and receive response messages from it. The USB has an attached SCSI, but I am unsure of how to send SCSI commands to macOS. Research has indicated that a kernel driver must be written for the USB to function on macOS. I have a .cpp file that can be converted into a .dll file to work on the Windows side. Is it possible to reuse this .cpp file and convert it into a .so file that can run on the macOS side? Is there someone interested in this project? I am looking to outsource it.
0
0
1k
Feb ’23
Different Drivers for Individual Interfaces
Hello We have a USB camera. My Mac can recognize it and we can get frames with any software. There is a physical button on it and the vendor says the camera is UVC-compliant. But button doesn't work anyway. I captured some USB traffic data and saw that it has two interfaces. One for streaming and other one for interrupting (like button click). I read UVC 1.5 standards to understand it and it is working like written in UVC 1.5. So, I can get a data with an interrupt transfer when clicking the button. I checked these two interfaces, they use UVCAssistant for driver(System Extension). I tried to use libusb, I can get data from button click. But for frames I had to use libuvc, but it wasn't work for my camera (I think it is related with USB descriptor parsing in libuvc). I thought that I should write a driver for single interface and so second interface will use same UVC assistant driver and first interface will use my driver. I wrote a driver and it matches with first interface. But second interface is empty (unhandled by any driver). I want to load UVCAssistant for second interface of USB port. How can I do this? Output before loading my driver After loading: IOKitPersonalities that I used:
2
0
1.7k
Dec ’22
IOKit or IOUSBHost for USB device acces from user space
USB-Devices without macOS support Every so often I find usefull USB consumer hardware without any macOS support. At best accompanied with some sample code aimed at Linux using libUSB and/or a datasheet [1]. Using code snippets from long since archived IOKit documentation I can deal with that. IOUSBHost Using working IOKit based ObjC Foundation command-line code[2] as reference I am attempting to use theIOUSBHost framework (ObjC Foundation tool). IOUSBHost documentation[3] has all the ingredients but lacks a recipy. Starting with a plugged-in USBDevice and using its idVendor and idProduct[4] I can initialize and destroy base class IOUSBObject and get notified when I unplug the USBDevice. initialize and destroy IOUSBHostDevice[5] and retrieve various descriptors [6] and configure with value: 0, and even do a vendor bmRequestType request without error. But since I already beforehand know the content of my descriptors I can start with IOUSBHostInterface?[7] , needed for my 3 pipes, interrupt, bulk in and out. But Error:Unable to open io_service_t object and create user client. with reason: Exclusive open of usb object failed, whether I asked for exclusive access or not. So I could do with some guidance on how to use IOUSBHost[8]. Let Any Pointer bring joy. Using: Apple M1 Max, MacOS 13.0.1 (22A400), Xcode 14.1 (14B47b) Alternatives considered: Raspberry Pi using UDP (JSON;) over wifi. [1] e.g. https://www.digchip.com/datasheets/parts/datasheet/280/DS2490-pdf.php [2] depending on usage this might need a runloop [3] including dec 2022 https://www.usb.org/sites/default/files/usb_32_202206.zip I failed to find the phrase 'Host-mode'. HINT start by inspecting chapter 9 to get a taste of the terms like function, class, address and value and number. Those wordings will also appear in Apple's documentation. NOTE Tables in chapter 9: Assuming D[n]: stands for bitNr[n] in a bitmap where D[0] is the least significant bit. USEFULL No. [4] use the IORegistryExplorer.app and/or ioreg in Terminal [5] IOUSBHostInterface.h tells me: CFMutableDictionaryRef to be used with IOService matching methods. To be released by caller. But as far a I know CFFoundation is now under ARC. [6] IOUSBInterfaceDescriptor * next = IOUSBGetNextInterfaceDescriptor(configurationDescriptor, nil); while (next != nil) // needs cast (IOUSBDescriptorHeader *)next [7] signed to run locally [8] My next step would be using Swift. Off topic but related and disturbing in a type safe world https://forums.swift.org/t/nsdata-data-vs-data-withunsafebytes/50231/5 Please please please never use NSData.bytes in Swift code. Is this why IOUSBHostObject ioDataWithCapacity uses NSMutableData? Quote: Because the kernel backs the NSMutableData object, the length and capacity aren’t mutable. Any changes to the length or capacity throws an exception. Effectively treating NSMutableData as NSData, only the compiler complains beforehand when an attempt is made to modify the length of NSData (data.bytes ARE mutable)
0
1
2.1k
Dec ’22
IOUSBHostDevice: Exclusive open of usb object failed
I have a command line tool and am trying to connect to a USB device using:    _device = [[IOUSBHostDevice alloc] initWithIOService:_service    options:IOUSBHostObjectInitOptionsDeviceCapture    queue:_queue    error:&error    interestHandler:^(IOUSBHostObject * _Nonnull hostObject, uint32_t messageType, void * _Nullable messageArgument) {     NSLog(@"Interest handler...");    }]; However, when I run this tool (even under sudo), I'm hitting the error: Error:Unable to open io\_service\_t object and create user client. with reason: Exclusive open of usb object failed. The documentation for IOUSBHostObjectInitOptionsDeviceCapture implies that using this option and having root privilege should gain exclusive access to the device. The alternative is to use an entitlement, but the executable is terminated immediately in that case probably due to code signing. I would have expected that running the tool under sudo would have been sufficient to avoid this issue. I just want to first get things working locally on my Mac for a proof of concept, so I don't really want to deal with code signing up front unless that is absolutely necessary. What do I need to do to get exclusive access to the USB device? Thanks in advance.
5
0
3.4k
Nov ’22
IOUSBHost framework - IOUSBHostErrorDomain which in turn has IOServiceOpen failed
// main.m // pnp // // Created by Sharath Menon on 22/09/22. // #import <Foundation/Foundation.h> #import <IOUSBHost/IOUSBHost.h> #include <IOKit/IOTypes.h> #include <dispatch/dispatch.h> #include <IOKit/usb/IOUSBLib.h> #ifdef __OBJC__ @class IOUSBHostDevice; typedef IOUSBHostDevice * USBHostDevPtr; #else typedef void * USBHostDevPtr; #endif USBHostDevPtr mUSBDevice; dispatch_queue_t mQueue; //boost::function<void()> mCallback; int captureDevice(io_service_t aService) { NSError* error = nil; IOUSBHostInterestHandler handler = ^void(IOUSBHostObject* hostObject, uint32_t messageType, void* _Nullable messageArgument) { if( messageType == kIOMessageServiceIsTerminated ) { // The callback will eventually take care of cleaning up the object // mCallback(); NSLog(@"if PNP device removed"); } NSLog(@"PNP device removed"); }; // Create the device with IOUSBHostObjectInitOptionsDeviceCapture to get exclusive access to the device IOUSBHostDevice* device = [[IOUSBHostDevice alloc] initWithIOService:aService options:IOUSBHostObjectInitOptionsDeviceCapture queue:mQueue error:&error interestHandler:handler]; if(device == NULL) { return -1; } mUSBDevice = device; // configureDevice(aService); return 0; } int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... mQueue = dispatch_queue_create("DeviceQueue", DISPATCH_QUEUE_SERIAL); NSLog(@"Hello, World!"); CFMutableDictionaryRef RefMatchingDict = IOServiceMatching( kIOUSBDeviceClassName ); io_iterator_t USBDevices; IOServiceGetMatchingServices( kIOMasterPortDefault, RefMatchingDict, &USBDevices ); // IOServiceGetMatchingServices( kIOMainPortDefault, RefMatchingDict, &USBDevices ); io_object_t USBDevice; while ( ( USBDevice = IOIteratorNext( USBDevices ) ) ) { io_string_t strDevPath; IORegistryEntryGetPath( USBDevice, kIOServicePlane, strDevPath ); captureDevice(USBDevice); IOObjectRelease( USBDevice ); } IOObjectRelease( USBDevices ); // USBDevices = NULL; } return 0; } Hey all, I have been seeing a weird issues while using IOUSBHost framework. Whenever i run the given sample code on M1 machine it works perfectly fine; but the same on an Intel machine is giving the below error. The weirdest part is when i run this on catalina with xcode 11.6 (Intel machine) it works again. My process is running as root and not sandboxed so i would not be requiring any entitlements as mentioned in the doc for using IOUSBHostObjectInitOptionsDeviceCapture. Thoughts??? * @enum IOUSBHostObjectInitOptions * @brief Options for <code>initWithIOService:options:queue:error:interestHandler</code> * @constant IOUSBHostObjectInitOptionsDeviceCapture Callers must have the "com.apple.vm.device-access" entitlement * and the IOUSBHostDevice IOService object needs to have successfully been authorized by IOServiceAuthorize(). * If the caller has root privelages the entitlement and authorization is not needed. Using this option * will terminate all clients and drivers of the IOUSBHostDevice and associated IOUSBHostInterface clients * besides the caller. * Upon <code>destroy</code> of the IOUSBHostDevice, the device will be reset and drivers will be re-registered * for matching. This option is only valid for macOS */ typedef NS_OPTIONS (NSUInteger, IOUSBHostObjectInitOptions) { IOUSBHostObjectInitOptionsNone = 0, IOUSBHostObjectInitOptionsDeviceCapture = (1 << 0) };
1
0
1.2k
Sep ’22
Fallback method for retrieving product name for USB devices
We have retired our old USB kext and reimplemented our new USB stack using the IOUSBHost API and the VM DeviceAccess entitlement in our product. Everything is going fine...except for this one edge case. We have a USB device that does not have a String Descriptor for the Product name. Apparently some USB devices will report an iProduct of 0 in their Device Descriptor, therefore Product String Descriptor failing. If I look at the output from system_profiler SPUSBDataType or ioreg -p IOUSB -l with the device attached, I can see that there is no Product name anywhere. I can combine the output of the two commands to narrow down the device based on its serial number. System profiler snippet: Miscellaneous Device: Product ID: 0x0990 Vendor ID: 0x046d (Logitech Inc.) Version: 0.08 Serial Number: 1345602E Speed: Up to 480 Mb/s Location ID: 0x14110000 / 21 Current Available (mA): 500 Current Required (mA): 500 Extra Operating Current (mA): 0 IOReg snippet: | +-o IOUSBHostDevice@14110000 <class AppleUSBDevice, id 0x100004897, registered, matched, active, busy 0 (4 ms), retain 20> | { | "sessionID" = 62015500304018 | "idProduct" = 2448 | "iManufacturer" = 0 | "bDeviceClass" = 239 | "bMaxPacketSize0" = 64 | "bcdDevice" = 8 | "iProduct" = 0 | "iSerialNumber" = 2 | "bNumConfigurations" = 1 | "Bus Power Available" = 250 | "USB Address" = 21 | "Built-In" = No | "locationID" = 336658432 | "bDeviceSubClass" = 2 | "bcdUSB" = 512 | "kUSBSerialNumberString" = "1345602E" | "PortNum" = 1 | "non-removable" = "no" | "AppleUSBAlternateServiceRegistryID" = 4294985877 | "bDeviceProtocol" = 1 | "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "IOPowerManagement" = {"DevicePowerState"=0,"CurrentPowerState"=3,"CapabilityFlags"=65536,"MaxPowerState"=4,"DriverPowerState"=3} | "kUSBCurrentConfiguration" = 1 | "Device Speed" = 2 | "idVendor" = 1133 | "IOGeneralInterest" = "IOCommand is not serializable" | "USB Serial Number" = "1345602E" | "IOClassNameOverride" = "IOUSBDevice" | } The solution I'm looking for is a fallback method to read the product name "QuickCam Pro 9000", as this is the string reported on other operating systems. I know a fallback is possible on at least Linux, using a table in /usr/share/misc/usb.ids. Is there any macOS API or command we can use to get the Product string for such devices?
0
0
1.2k
Aug ’22
IOUSBHostDevice fails and throws error in sandboxed app
I get the following errors when running the code below in a sandboxed app (it works when not sandboxed) and I have the com.apple.security.device.usb entitlement enabled. Error:Unable to open io_service_t object and create user client. with reason: IOServiceOpen failed. Error Domain=IOUSBHostErrorDomain Code=-536870174 "Failed to create IOUSBHostObject." UserInfo={NSLocalizedRecoverySuggestion=, NSLocalizedDescription=Failed to create IOUSBHostObject., NSLocalizedFailureReason=IOServiceOpen failed.} import Foundation import IOKit import IOKit.usb import IOKit.usb.IOUSBLib import IOKit.serial import IOUSBHost import IOUSBHost.IOUSBHostInterface class USBService {     enum UsbError: Error {         case noDeviceMatched         case deviceCriteriaNotUnique     }          init() {              }          func getDevice(idVendor: Int?, idProduct: Int?) throws {         let deviceSearchPattern: [IOUSBHostMatchingPropertyKey : Int] = [                    .vendorID : idVendor!,                    .productID : idProduct!,                ]                let deviceDomain = [ "IOProviderClass": "IOUSBHostDevice" ]                let searchRequest = (deviceSearchPattern as NSDictionary).mutableCopy() as! NSMutableDictionary                searchRequest.addEntries(from: deviceDomain)         let service = IOServiceGetMatchingService(kIOMasterPortDefault, searchRequest)         guard service != 0 else {                    throw UsbError.noDeviceMatched         }                       let device = try IOUSBHostDevice.init(__ioService: service, options: [], queue: nil, interestHandler: nil)                  print(device.deviceDescriptor?.pointee.idProduct)     } }
3
0
2.2k
May ’22
USB driver for MIDI keyboard
Greetings. I'm trying to build an Apple Silicon driver for a Roland keyboard which is no longer supported by the manufacturer. The most recent official driver is from 2010. From my limited understanding of the Apple documentation, it seems to be telling me that I need to build a codeless dext which overrides some sort of base class. The keyboard uses bog standard USB 1.0 to communicate with the host. Total newb in the driver area so if anyone could point me in the right direction on where to start I would be totally grateful.
Replies
0
Boosts
0
Views
785
Activity
Mar ’24
Determining the USB hub port to which an iPad is connected
Hi. I wish I'd found a way to determine the USB hub port to which an iPad is connected, even if it means creating a one-time mapping of identifiers and ports beforehand. I thought I'd find some hardware identifiers that might help, but they appear to fluctuate depending on how the iPad carts are connected to the Mac. Is there anything reliable to achieve the desired result? Thanks for your insights. Franck
Replies
0
Boosts
0
Views
669
Activity
Jan ’24
USB DriverKit returning large asynchronous data
Can anyone advise, or give example of, communicating large (>128 byte) incoming buffers from a dext to a user-space app? My specific situation is interrupt reads from a USB device. These return reports which are too large to fit into the asyncData field of an AsyncCompletion call. Apple's CommunicatingBetweenADriverKitExtensionAndAClientApp sample shows examples of returning a "large" struct, but the example is synchronous. The asynchronous example returns data by copying into a IOUserClientAsyncArgumentsArray, which isn't very big. I can allocate a single buffer larger than 4K in user space, and communicate that buffer to my driver as an IOMemoryDescriptor when I set up my async callback. The driver retains the descriptor, maps it into its memory space and can thus write into it when the hardware returns interrupt data. The driver then calls AsyncCompletion, which will cause my user-side callback to be called, so the user side software knows that there's new data available in the previously allocated buffer. That's fine, it works, but there are data race problems - since USB interrupt reads complete whenever the hardware has provided data, incoming completions happen at unpredictable times, so the shared buffer contents could change while the user side code is examining them. Is there an example somewhere of how to deal with this? Can I allocate memory on the driver side on demand, create an IOMemoryDescriptor for it and return that descriptor packed inside the asyncData? If so, how does the driver know when it can relinquish that memory? I have a feeling there's something here I just don't understand...
Replies
1
Boosts
0
Views
944
Activity
Jan ’24
USB DriverKit returning large asynchronous data
this is a repost with more appropriate tags. The original is here: https://developer.apple.com/forums/thread/744268 Can anyone advise, or give example of, communicating large (>128 byte) incoming buffers from a dext to a user-space app? My specific situation is interrupt reads from a USB device. These return reports which are too large to fit into the asyncData field of an AsyncCompletion call. Apple's CommunicatingBetweenADriverKitExtensionAndAClientApp sample shows examples of returning a "large" struct, but the example is synchronous. The asynchronous example returns data by copying into a IOUserClientAsyncArgumentsArray, which isn't very big. I can allocate a single buffer larger than 4K in user space, and communicate that buffer to my driver as an IOMemoryDescriptor when I set up my async callback. The driver retains the descriptor, maps it into its memory space and can thus write into it when the hardware returns interrupt data. The driver then calls AsyncCompletion, which will cause my user-side callback to be called, so the user side software knows that there's new data available in the previously allocated buffer. That's fine, it works, but there are data race problems - since USB interrupt reads complete whenever the hardware has provided data, incoming completions happen at unpredictable times, so the shared buffer contents could change while the user side code is examining them. Is there an example somewhere of how to deal with this? Can I allocate memory on the driver side on demand, create an IOMemoryDescriptor for it and return that descriptor packed inside the asyncData? If so, how does the driver know when it can relinquish that memory? I have a feeling there's something here I just don't understand...
Replies
0
Boosts
0
Views
924
Activity
Jan ’24
How to develop a driver extension for a USB mass storage device
I am currently in the process of developing a DEXT for a USB based external mass storage device using the USBDriverKit framework. IOUSBHostInterface is used as the provider to communicate with the interface's endpoints and I am successful in it. As per the IOUSBHostInterface documentation, To use a host interface object, call Open to create a new session between the interface and your driver. After successfully opening your session, you can request information from the interface and set up pipes to communicate with the interface's endpoints. Remember to close the session you opened in the Stop method of your driver. However, calling Open gains exclusive access to the USB interface and does not allow other services to access the interface. Also, to let go of the exclusive access, Close method can be called but in the Stop method which is called only once during the lifecycle of the extension (when the DEXT is unloaded). As a result of this, Apple's mass storage related KEXTs (media and partition related specifically) do not match the interface and so the filesystem of the drive in question does not get mounted whenever the DEXT has matched the interface. Is this exclusive access a limitation of USBDriverkit or is there any way to get around this issue in this case?
Replies
2
Boosts
0
Views
1.1k
Activity
Nov ’23
Get /dev file name from IOreg?
Hi. I have a class-compliant usb device which announces its serial number as m4121095, as per its kUSBSerialNumberString property. However, the file name it is provided is tty.usbmodemm41210951 – it's the serial number with an additional 1 at the end. What is the meaning of this appendage? (I'm tempted to believe that the 1 at the end is there in the unlikely case another device with the same SN is connected, but there's no way to test this possibility). In the end, I would like to obtain a filename that is guaranteed to be representing a connection to exactly this device. Can I assume that the filename of a device that follows the same protocol of serial numbering will be consistently appended with a number that can in some way be inferred? Thank you.
Replies
5
Boosts
0
Views
1.6k
Activity
Jul ’23
Mac M2 pro libusb read/write performance
I am writing a C program on Mac that calls the libUSB API. However, I found some performance differences between the same programs on MAC x64 and MAC M2 systems. Program on Mac m2 call libusb_control_transfer() function is much slower than programs on Mac x64. For example, running a program on Mac x64 takes 3 seconds to complete a function, while on Mac m2 it takes 10 seconds. I try to count the number of times a program calls libusb_control_transfer() and the time it takes each time, and finally calculate the average time it takes to call libusb_control_transfer(). The following figure shows the performance of the program on Mac m2.(Unit is us per time) The following figure shows the performance of the program on Mac x64. (Unit is us per time) The difference in average time spent calling a function has reached over 10 times. Is this performance gap caused by the USB driver or the libUSB library? Thanks.
Replies
2
Boosts
0
Views
1.2k
Activity
May ’23
Release ExclusiveAccess to an usb device taken by another application?
Seems like both Dropbox and Google Drive has a pretty sad implementation/bug that acquire exclusive access to USB devices that expose MTP (media transfer protocol). The way google and dropbox did it is just wrong as they 1) should ask for permission for reading data on new devices, 2) not open the usb device in exclusive mode... 3) make use of MTP's Multi-Session mode. Well, as it will take them about 4.5 years to correct this, I wonder if there is a way for a app-store/user-space application in macOS 11/12/13 (big sur, monterey, ventura) to do the following: Detect if there is another app that has exclusive lock to a specific usb device Get the name of the app so that an alert could say, "please quit google-drive for this to work..." Release the exclusive lock, i.e. hand over the usb peripheral to my application
Replies
0
Boosts
0
Views
1.1k
Activity
Apr ’23
Is there Anyway to Enable/Disable USB Storage Device in Mac?
Hi, I want to enable/disable my USB Storage stick with using MQTT server. I can connect my server, listen and publish some datas. Is it possible to do change USB status with Swift, in XCode? It should be only change storage device, because i don't want to disconnect my mouse or etc.
Replies
0
Boosts
0
Views
1k
Activity
Mar ’23
How to write kernel driver for USB on macOS ?
I am creating a macOS app that will send commands to a USB device when it is plugged into a Mac. There are only two steps to accomplish this: send request commands to the USB and receive response messages from it. The USB has an attached SCSI, but I am unsure of how to send SCSI commands to macOS. Research has indicated that a kernel driver must be written for the USB to function on macOS. I have a .cpp file that can be converted into a .dll file to work on the Windows side. Is it possible to reuse this .cpp file and convert it into a .so file that can run on the macOS side? Is there someone interested in this project? I am looking to outsource it.
Replies
0
Boosts
0
Views
1k
Activity
Feb ’23
Different Drivers for Individual Interfaces
Hello We have a USB camera. My Mac can recognize it and we can get frames with any software. There is a physical button on it and the vendor says the camera is UVC-compliant. But button doesn't work anyway. I captured some USB traffic data and saw that it has two interfaces. One for streaming and other one for interrupting (like button click). I read UVC 1.5 standards to understand it and it is working like written in UVC 1.5. So, I can get a data with an interrupt transfer when clicking the button. I checked these two interfaces, they use UVCAssistant for driver(System Extension). I tried to use libusb, I can get data from button click. But for frames I had to use libuvc, but it wasn't work for my camera (I think it is related with USB descriptor parsing in libuvc). I thought that I should write a driver for single interface and so second interface will use same UVC assistant driver and first interface will use my driver. I wrote a driver and it matches with first interface. But second interface is empty (unhandled by any driver). I want to load UVCAssistant for second interface of USB port. How can I do this? Output before loading my driver After loading: IOKitPersonalities that I used:
Replies
2
Boosts
0
Views
1.7k
Activity
Dec ’22
IOKit or IOUSBHost for USB device acces from user space
USB-Devices without macOS support Every so often I find usefull USB consumer hardware without any macOS support. At best accompanied with some sample code aimed at Linux using libUSB and/or a datasheet [1]. Using code snippets from long since archived IOKit documentation I can deal with that. IOUSBHost Using working IOKit based ObjC Foundation command-line code[2] as reference I am attempting to use theIOUSBHost framework (ObjC Foundation tool). IOUSBHost documentation[3] has all the ingredients but lacks a recipy. Starting with a plugged-in USBDevice and using its idVendor and idProduct[4] I can initialize and destroy base class IOUSBObject and get notified when I unplug the USBDevice. initialize and destroy IOUSBHostDevice[5] and retrieve various descriptors [6] and configure with value: 0, and even do a vendor bmRequestType request without error. But since I already beforehand know the content of my descriptors I can start with IOUSBHostInterface?[7] , needed for my 3 pipes, interrupt, bulk in and out. But Error:Unable to open io_service_t object and create user client. with reason: Exclusive open of usb object failed, whether I asked for exclusive access or not. So I could do with some guidance on how to use IOUSBHost[8]. Let Any Pointer bring joy. Using: Apple M1 Max, MacOS 13.0.1 (22A400), Xcode 14.1 (14B47b) Alternatives considered: Raspberry Pi using UDP (JSON;) over wifi. [1] e.g. https://www.digchip.com/datasheets/parts/datasheet/280/DS2490-pdf.php [2] depending on usage this might need a runloop [3] including dec 2022 https://www.usb.org/sites/default/files/usb_32_202206.zip I failed to find the phrase 'Host-mode'. HINT start by inspecting chapter 9 to get a taste of the terms like function, class, address and value and number. Those wordings will also appear in Apple's documentation. NOTE Tables in chapter 9: Assuming D[n]: stands for bitNr[n] in a bitmap where D[0] is the least significant bit. USEFULL No. [4] use the IORegistryExplorer.app and/or ioreg in Terminal [5] IOUSBHostInterface.h tells me: CFMutableDictionaryRef to be used with IOService matching methods. To be released by caller. But as far a I know CFFoundation is now under ARC. [6] IOUSBInterfaceDescriptor * next = IOUSBGetNextInterfaceDescriptor(configurationDescriptor, nil); while (next != nil) // needs cast (IOUSBDescriptorHeader *)next [7] signed to run locally [8] My next step would be using Swift. Off topic but related and disturbing in a type safe world https://forums.swift.org/t/nsdata-data-vs-data-withunsafebytes/50231/5 Please please please never use NSData.bytes in Swift code. Is this why IOUSBHostObject ioDataWithCapacity uses NSMutableData? Quote: Because the kernel backs the NSMutableData object, the length and capacity aren’t mutable. Any changes to the length or capacity throws an exception. Effectively treating NSMutableData as NSData, only the compiler complains beforehand when an attempt is made to modify the length of NSData (data.bytes ARE mutable)
Replies
0
Boosts
1
Views
2.1k
Activity
Dec ’22
IOUSBHostDevice: Exclusive open of usb object failed
I have a command line tool and am trying to connect to a USB device using:    _device = [[IOUSBHostDevice alloc] initWithIOService:_service    options:IOUSBHostObjectInitOptionsDeviceCapture    queue:_queue    error:&error    interestHandler:^(IOUSBHostObject * _Nonnull hostObject, uint32_t messageType, void * _Nullable messageArgument) {     NSLog(@"Interest handler...");    }]; However, when I run this tool (even under sudo), I'm hitting the error: Error:Unable to open io&#92;&#95;service&#92;&#95;t object and create user client. with reason: Exclusive open of usb object failed. The documentation for IOUSBHostObjectInitOptionsDeviceCapture implies that using this option and having root privilege should gain exclusive access to the device. The alternative is to use an entitlement, but the executable is terminated immediately in that case probably due to code signing. I would have expected that running the tool under sudo would have been sufficient to avoid this issue. I just want to first get things working locally on my Mac for a proof of concept, so I don't really want to deal with code signing up front unless that is absolutely necessary. What do I need to do to get exclusive access to the USB device? Thanks in advance.
Replies
5
Boosts
0
Views
3.4k
Activity
Nov ’22
Monterey: USB to serial not recognized
I connected the Prolific USB to Serial converter but it does not work, checking the driver does not appear after installation, could you help me Thank you
Replies
1
Boosts
0
Views
949
Activity
Oct ’22
IOUSBHost framework - IOUSBHostErrorDomain which in turn has IOServiceOpen failed
// main.m // pnp // // Created by Sharath Menon on 22/09/22. // #import <Foundation/Foundation.h> #import <IOUSBHost/IOUSBHost.h> #include <IOKit/IOTypes.h> #include <dispatch/dispatch.h> #include <IOKit/usb/IOUSBLib.h> #ifdef __OBJC__ @class IOUSBHostDevice; typedef IOUSBHostDevice * USBHostDevPtr; #else typedef void * USBHostDevPtr; #endif USBHostDevPtr mUSBDevice; dispatch_queue_t mQueue; //boost::function<void()> mCallback; int captureDevice(io_service_t aService) { NSError* error = nil; IOUSBHostInterestHandler handler = ^void(IOUSBHostObject* hostObject, uint32_t messageType, void* _Nullable messageArgument) { if( messageType == kIOMessageServiceIsTerminated ) { // The callback will eventually take care of cleaning up the object // mCallback(); NSLog(@"if PNP device removed"); } NSLog(@"PNP device removed"); }; // Create the device with IOUSBHostObjectInitOptionsDeviceCapture to get exclusive access to the device IOUSBHostDevice* device = [[IOUSBHostDevice alloc] initWithIOService:aService options:IOUSBHostObjectInitOptionsDeviceCapture queue:mQueue error:&error interestHandler:handler]; if(device == NULL) { return -1; } mUSBDevice = device; // configureDevice(aService); return 0; } int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... mQueue = dispatch_queue_create("DeviceQueue", DISPATCH_QUEUE_SERIAL); NSLog(@"Hello, World!"); CFMutableDictionaryRef RefMatchingDict = IOServiceMatching( kIOUSBDeviceClassName ); io_iterator_t USBDevices; IOServiceGetMatchingServices( kIOMasterPortDefault, RefMatchingDict, &USBDevices ); // IOServiceGetMatchingServices( kIOMainPortDefault, RefMatchingDict, &USBDevices ); io_object_t USBDevice; while ( ( USBDevice = IOIteratorNext( USBDevices ) ) ) { io_string_t strDevPath; IORegistryEntryGetPath( USBDevice, kIOServicePlane, strDevPath ); captureDevice(USBDevice); IOObjectRelease( USBDevice ); } IOObjectRelease( USBDevices ); // USBDevices = NULL; } return 0; } Hey all, I have been seeing a weird issues while using IOUSBHost framework. Whenever i run the given sample code on M1 machine it works perfectly fine; but the same on an Intel machine is giving the below error. The weirdest part is when i run this on catalina with xcode 11.6 (Intel machine) it works again. My process is running as root and not sandboxed so i would not be requiring any entitlements as mentioned in the doc for using IOUSBHostObjectInitOptionsDeviceCapture. Thoughts??? * @enum IOUSBHostObjectInitOptions * @brief Options for <code>initWithIOService:options:queue:error:interestHandler</code> * @constant IOUSBHostObjectInitOptionsDeviceCapture Callers must have the "com.apple.vm.device-access" entitlement * and the IOUSBHostDevice IOService object needs to have successfully been authorized by IOServiceAuthorize(). * If the caller has root privelages the entitlement and authorization is not needed. Using this option * will terminate all clients and drivers of the IOUSBHostDevice and associated IOUSBHostInterface clients * besides the caller. * Upon <code>destroy</code> of the IOUSBHostDevice, the device will be reset and drivers will be re-registered * for matching. This option is only valid for macOS */ typedef NS_OPTIONS (NSUInteger, IOUSBHostObjectInitOptions) { IOUSBHostObjectInitOptionsNone = 0, IOUSBHostObjectInitOptionsDeviceCapture = (1 << 0) };
Replies
1
Boosts
0
Views
1.2k
Activity
Sep ’22
How to get LUN id of SCSI connected devices
Hi all I needed some help in getting the LUN id of all devices connected to the system especially for SCSI devices. I'm not able to find any such system command or a SCSI command. Thanks in advance.
Replies
2
Boosts
0
Views
1.1k
Activity
Sep ’22
macOS Big Sur breaks Razer peripherals
For whatever reason, my Razer Huntsman keyboard does work for the most part but none of the audio controls do anything on the keyboard. In addition, I've tried two different razer mice and neither work at all. Everything worked perfectly before the beta.
Replies
80
Boosts
0
Views
60k
Activity
Sep ’22
Fallback method for retrieving product name for USB devices
We have retired our old USB kext and reimplemented our new USB stack using the IOUSBHost API and the VM DeviceAccess entitlement in our product. Everything is going fine...except for this one edge case. We have a USB device that does not have a String Descriptor for the Product name. Apparently some USB devices will report an iProduct of 0 in their Device Descriptor, therefore Product String Descriptor failing. If I look at the output from system_profiler SPUSBDataType or ioreg -p IOUSB -l with the device attached, I can see that there is no Product name anywhere. I can combine the output of the two commands to narrow down the device based on its serial number. System profiler snippet: Miscellaneous Device: Product ID: 0x0990 Vendor ID: 0x046d (Logitech Inc.) Version: 0.08 Serial Number: 1345602E Speed: Up to 480 Mb/s Location ID: 0x14110000 / 21 Current Available (mA): 500 Current Required (mA): 500 Extra Operating Current (mA): 0 IOReg snippet: | +-o IOUSBHostDevice@14110000 <class AppleUSBDevice, id 0x100004897, registered, matched, active, busy 0 (4 ms), retain 20> | { | "sessionID" = 62015500304018 | "idProduct" = 2448 | "iManufacturer" = 0 | "bDeviceClass" = 239 | "bMaxPacketSize0" = 64 | "bcdDevice" = 8 | "iProduct" = 0 | "iSerialNumber" = 2 | "bNumConfigurations" = 1 | "Bus Power Available" = 250 | "USB Address" = 21 | "Built-In" = No | "locationID" = 336658432 | "bDeviceSubClass" = 2 | "bcdUSB" = 512 | "kUSBSerialNumberString" = "1345602E" | "PortNum" = 1 | "non-removable" = "no" | "AppleUSBAlternateServiceRegistryID" = 4294985877 | "bDeviceProtocol" = 1 | "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | "IOPowerManagement" = {"DevicePowerState"=0,"CurrentPowerState"=3,"CapabilityFlags"=65536,"MaxPowerState"=4,"DriverPowerState"=3} | "kUSBCurrentConfiguration" = 1 | "Device Speed" = 2 | "idVendor" = 1133 | "IOGeneralInterest" = "IOCommand is not serializable" | "USB Serial Number" = "1345602E" | "IOClassNameOverride" = "IOUSBDevice" | } The solution I'm looking for is a fallback method to read the product name "QuickCam Pro 9000", as this is the string reported on other operating systems. I know a fallback is possible on at least Linux, using a table in /usr/share/misc/usb.ids. Is there any macOS API or command we can use to get the Product string for such devices?
Replies
0
Boosts
0
Views
1.2k
Activity
Aug ’22
Can iPhone or iPad as the USB audio source?
Hi . All We try to connect the USB UAC1.0 device to computer or andriod phone , is work well . the we try to connect to iphone or ipad use "Lightning to USB adapter “,it can find device then play the audio but the audio stream is not continuous. can you tell my iphone or ipad support usb uac1.0 or uac2.0 device ? Thank you! Isaac
Replies
0
Boosts
0
Views
899
Activity
Jul ’22
IOUSBHostDevice fails and throws error in sandboxed app
I get the following errors when running the code below in a sandboxed app (it works when not sandboxed) and I have the com.apple.security.device.usb entitlement enabled. Error:Unable to open io_service_t object and create user client. with reason: IOServiceOpen failed. Error Domain=IOUSBHostErrorDomain Code=-536870174 "Failed to create IOUSBHostObject." UserInfo={NSLocalizedRecoverySuggestion=, NSLocalizedDescription=Failed to create IOUSBHostObject., NSLocalizedFailureReason=IOServiceOpen failed.} import Foundation import IOKit import IOKit.usb import IOKit.usb.IOUSBLib import IOKit.serial import IOUSBHost import IOUSBHost.IOUSBHostInterface class USBService {     enum UsbError: Error {         case noDeviceMatched         case deviceCriteriaNotUnique     }          init() {              }          func getDevice(idVendor: Int?, idProduct: Int?) throws {         let deviceSearchPattern: [IOUSBHostMatchingPropertyKey : Int] = [                    .vendorID : idVendor!,                    .productID : idProduct!,                ]                let deviceDomain = [ "IOProviderClass": "IOUSBHostDevice" ]                let searchRequest = (deviceSearchPattern as NSDictionary).mutableCopy() as! NSMutableDictionary                searchRequest.addEntries(from: deviceDomain)         let service = IOServiceGetMatchingService(kIOMasterPortDefault, searchRequest)         guard service != 0 else {                    throw UsbError.noDeviceMatched         }                       let device = try IOUSBHostDevice.init(__ioService: service, options: [], queue: nil, interestHandler: nil)                  print(device.deviceDescriptor?.pointee.idProduct)     } }
Replies
3
Boosts
0
Views
2.2k
Activity
May ’22