1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
3 * darwin backend for libusb 1.0
4 * Copyright © 2008-2021 Nathan Hjelm <hjelmn@cs.unm.edu>
5 * Copyright © 2019-2021 Google LLC. All rights reserved.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include <sys/types.h>
33 #include <sys/sysctl.h>
35 #include <mach/clock.h>
36 #include <mach/clock_types.h>
37 #include <mach/mach_host.h>
38 #include <mach/mach_port.h>
40 /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
41 * function. Its use is also conditionalized to only older deployment targets. */
42 #define OBJC_SILENCE_GC_DEPRECATIONS 1
44 /* Default timeout to 10s for reenumerate. This is needed because USBDeviceReEnumerate
45 * does not return error status on macOS. */
46 #define DARWIN_REENUMERATE_TIMEOUT_US 10000000
48 #include <AvailabilityMacros.h>
49 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
50 #include <objc/objc-auto.h>
53 #include "darwin_usb.h"
55 static int init_count = 0;
57 /* Both kIOMasterPortDefault or kIOMainPortDefault are synonyms for 0. */
58 static const mach_port_t darwin_default_master_port = 0;
60 /* async event thread */
61 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
62 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
64 #if !defined(HAVE_CLOCK_GETTIME)
65 static clock_serv_t clock_realtime;
66 static clock_serv_t clock_monotonic;
69 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
71 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
72 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
74 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
75 static struct list_head darwin_cached_devices;
76 static const char *darwin_device_class = "IOUSBDevice";
78 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
80 /* async event thread */
81 static pthread_t libusb_darwin_at;
83 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
84 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
85 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
86 static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bool capture);
87 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint);
88 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
89 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
91 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
92 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
93 UInt64 old_session_id);
95 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
96 UInt64 *old_session_id);
98 #if defined(ENABLE_LOGGING)
99 static const char *darwin_error_str (IOReturn result) {
100 static char string_buffer[50];
102 case kIOReturnSuccess:
104 case kIOReturnNotOpen:
105 return "device not opened for exclusive access";
106 case kIOReturnNoDevice:
107 return "no connection to an IOService";
108 case kIOUSBNoAsyncPortErr:
109 return "no async port has been opened for interface";
110 case kIOReturnExclusiveAccess:
111 return "another process has device opened for exclusive access";
112 case kIOUSBPipeStalled:
113 #if defined(kUSBHostReturnPipeStalled)
114 case kUSBHostReturnPipeStalled:
116 return "pipe is stalled";
118 return "could not establish a connection to the Darwin kernel";
119 case kIOUSBTransactionTimeout:
120 return "transaction timed out";
121 case kIOReturnBadArgument:
122 return "invalid argument";
123 case kIOReturnAborted:
124 return "transaction aborted";
125 case kIOReturnNotResponding:
126 return "device not responding";
127 case kIOReturnOverrun:
128 return "data overrun";
129 case kIOReturnCannotWire:
130 return "physical memory can not be wired down";
131 case kIOReturnNoResources:
132 return "out of resources";
133 case kIOUSBHighSpeedSplitError:
134 return "high speed split error";
135 case kIOUSBUnknownPipeErr:
136 return "pipe ref not recognized";
138 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
139 return string_buffer;
144 static enum libusb_error darwin_to_libusb (IOReturn result) {
146 case kIOReturnUnderrun:
147 case kIOReturnSuccess:
148 return LIBUSB_SUCCESS;
149 case kIOReturnNotOpen:
150 case kIOReturnNoDevice:
151 return LIBUSB_ERROR_NO_DEVICE;
152 case kIOReturnExclusiveAccess:
153 return LIBUSB_ERROR_ACCESS;
154 case kIOUSBPipeStalled:
155 #if defined(kUSBHostReturnPipeStalled)
156 case kUSBHostReturnPipeStalled:
158 return LIBUSB_ERROR_PIPE;
159 case kIOReturnBadArgument:
160 return LIBUSB_ERROR_INVALID_PARAM;
161 case kIOUSBTransactionTimeout:
162 return LIBUSB_ERROR_TIMEOUT;
163 case kIOUSBUnknownPipeErr:
164 return LIBUSB_ERROR_NOT_FOUND;
165 case kIOReturnNotResponding:
166 case kIOReturnAborted:
168 case kIOUSBNoAsyncPortErr:
170 return LIBUSB_ERROR_OTHER;
174 /* this function must be called with the darwin_cached_devices_lock held */
175 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
176 cached_dev->refcount--;
177 /* free the device and remove it from the cache */
178 if (0 == cached_dev->refcount) {
179 list_del(&cached_dev->list);
181 if (cached_dev->device) {
182 (*(cached_dev->device))->Release(cached_dev->device);
183 cached_dev->device = NULL;
185 IOObjectRelease (cached_dev->service);
190 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
191 cached_dev->refcount++;
194 static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, uint8_t *pipep, uint8_t *ifcp, struct darwin_interface **interface_out) {
195 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
197 /* current interface */
198 struct darwin_interface *cInterface;
202 struct libusb_context *ctx = HANDLE_CTX(dev_handle);
204 usbi_dbg (ctx, "converting ep address 0x%02x to pipeRef and interface", ep);
206 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
207 cInterface = &priv->interfaces[iface];
209 if (dev_handle->claimed_interfaces & (1U << iface)) {
210 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
211 if (cInterface->endpoint_addrs[i] == ep) {
218 *interface_out = cInterface;
220 usbi_dbg (ctx, "pipe %d on interface %d matches", *pipep, iface);
221 return LIBUSB_SUCCESS;
227 /* No pipe found with the correct endpoint address */
228 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
230 return LIBUSB_ERROR_NOT_FOUND;
233 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
234 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
237 return kIOReturnError;
240 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
241 &kCFTypeDictionaryKeyCallBacks,
242 &kCFTypeDictionaryValueCallBacks);
244 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
245 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
246 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
248 if (propertyMatchDict && locationCF) {
249 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
250 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
252 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
254 /* release our references as per the Create Rule */
255 if (propertyMatchDict)
256 CFRelease (propertyMatchDict);
258 CFRelease (locationCF);
261 return IOServiceGetMatchingServices(darwin_default_master_port, matchingDict, deviceIterator);
264 /* Returns 1 on success, 0 on failure. */
265 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
266 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
270 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
271 success = CFNumberGetValue(cfNumber, type, p);
274 CFRelease (cfNumber);
277 return (success != 0);
280 /* Returns 1 on success, 0 on failure. */
281 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
282 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
283 bool success = false;
286 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
287 CFIndex length = CFDataGetLength (cfData);
292 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
302 static usb_device_t **darwin_device_from_service (struct libusb_context *ctx, io_service_t service)
304 io_cf_plugin_ref_t *plugInInterface = NULL;
305 usb_device_t **device;
308 const int max_retries = 5;
310 /* The IOCreatePlugInInterfaceForService function might consistently return
311 an "out of resources" error with certain USB devices the first time we run
312 it. The reason is still unclear, but retrying fixes the problem */
313 for (int count = 0; count < max_retries; count++) {
314 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
315 kIOCFPlugInInterfaceID, &plugInInterface,
317 if (kIOReturnSuccess == kresult && plugInInterface) {
321 usbi_dbg (ctx, "set up plugin for service retry: %s", darwin_error_str (kresult));
323 /* sleep for a little while before trying again */
324 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
327 if (kIOReturnSuccess != kresult || !plugInInterface) {
328 usbi_dbg (ctx, "could not set up plugin for service: %s", darwin_error_str (kresult));
332 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
334 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
335 (*plugInInterface)->Release (plugInInterface);
340 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
342 struct darwin_cached_device *cached_device;
343 UInt64 old_session_id;
344 struct libusb_context *ctx;
345 io_service_t service;
348 usbi_mutex_lock(&active_contexts_lock);
350 while ((service = IOIteratorNext(add_devices))) {
351 ret = darwin_get_cached_device (NULL, service, &cached_device, &old_session_id);
352 if (ret < 0 || !cached_device->can_enumerate) {
356 /* add this device to each active context's device list */
357 for_each_context(ctx) {
358 process_new_device (ctx, cached_device, old_session_id);
361 if (cached_device->in_reenumerate) {
362 usbi_dbg (NULL, "cached device in reset state. reset complete...");
363 cached_device->in_reenumerate = false;
366 IOObjectRelease(service);
369 usbi_mutex_unlock(&active_contexts_lock);
372 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
374 struct libusb_device *dev = NULL;
375 struct libusb_context *ctx;
376 struct darwin_cached_device *old_device;
379 UInt64 session, locationID;
382 usbi_mutex_lock(&active_contexts_lock);
384 while ((device = IOIteratorNext (rem_devices)) != 0) {
385 bool is_reenumerating = false;
387 /* get the location from the i/o registry */
388 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
389 (void) get_ioregistry_value_number (device, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
390 IOObjectRelease (device);
394 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
395 otherwise no cached device will ever get freed */
396 usbi_mutex_lock(&darwin_cached_devices_lock);
397 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
398 if (old_device->session == session) {
399 if (old_device->in_reenumerate) {
400 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
401 * will deref if needed. */
402 usbi_dbg (NULL, "detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64,
403 session, locationID);
405 /* the device object is no longer usable so go ahead and release it */
406 if (old_device->device) {
407 (*(old_device->device))->Release(old_device->device);
408 old_device->device = NULL;
411 is_reenumerating = true;
413 darwin_deref_cached_device (old_device);
420 usbi_mutex_unlock(&darwin_cached_devices_lock);
421 if (is_reenumerating) {
425 for_each_context(ctx) {
426 usbi_dbg (ctx, "notifying context %p of device disconnect", ctx);
428 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
430 /* signal the core that this device has been disconnected. the core will tear down this device
431 when the reference count reaches 0 */
432 usbi_disconnect_device(dev);
433 libusb_unref_device(dev);
438 usbi_mutex_unlock(&active_contexts_lock);
441 static void darwin_hotplug_poll (void)
443 /* not sure if 1 ms will be too long/short but it should work ok */
444 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
446 /* since a kernel thread may notify the IOIterators used for
447 * hotplug notification we can't just clear the iterators.
448 * instead just wait until all IOService providers are quiet */
449 (void) IOKitWaitQuiet (darwin_default_master_port, &timeout);
452 static void darwin_clear_iterator (io_iterator_t iter) {
455 while ((device = IOIteratorNext (iter)) != 0)
456 IOObjectRelease (device);
459 static void darwin_fail_startup(void) {
460 pthread_mutex_lock (&libusb_darwin_at_mutex);
461 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
462 pthread_cond_signal (&libusb_darwin_at_cond);
463 pthread_mutex_unlock (&libusb_darwin_at_mutex);
467 static void *darwin_event_thread_main (void *arg0) {
469 struct libusb_context *ctx = (struct libusb_context *)arg0;
470 CFRunLoopRef runloop;
471 CFRunLoopSourceRef libusb_shutdown_cfsource;
472 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
474 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
475 /* Set this thread's name, so it can be seen in the debugger
476 and crash reports. */
477 pthread_setname_np ("org.libusb.device-hotplug");
480 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
481 /* Tell the Objective-C garbage collector about this thread.
482 This is required because, unlike NSThreads, pthreads are
483 not automatically registered. Although we don't use
484 Objective-C, we use CoreFoundation, which does.
485 Garbage collection support was entirely removed in 10.12,
486 so don't bother there. */
487 objc_registerThreadWithCollector();
490 /* hotplug (device arrival/removal) sources */
491 CFRunLoopSourceRef libusb_notification_cfsource;
492 io_notification_port_t libusb_notification_port;
493 io_iterator_t libusb_rem_device_iterator;
494 io_iterator_t libusb_add_device_iterator;
496 usbi_dbg (ctx, "creating hotplug event source");
498 runloop = CFRunLoopGetCurrent ();
501 /* add the shutdown cfsource to the run loop */
502 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
503 libusb_shutdown_cfsourcectx.info = runloop;
504 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
505 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
506 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
508 /* add the notification port to the run loop */
509 libusb_notification_port = IONotificationPortCreate (darwin_default_master_port);
510 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
511 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
513 /* create notifications for removed devices */
514 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
515 IOServiceMatching(darwin_device_class),
516 darwin_devices_detached,
517 ctx, &libusb_rem_device_iterator);
519 if (kresult != kIOReturnSuccess) {
520 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
521 CFRelease (libusb_shutdown_cfsource);
523 darwin_fail_startup ();
526 /* create notifications for attached devices */
527 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
528 IOServiceMatching(darwin_device_class),
529 darwin_devices_attached,
530 ctx, &libusb_add_device_iterator);
532 if (kresult != kIOReturnSuccess) {
533 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
534 CFRelease (libusb_shutdown_cfsource);
536 darwin_fail_startup ();
540 darwin_clear_iterator (libusb_rem_device_iterator);
541 darwin_clear_iterator (libusb_add_device_iterator);
543 usbi_dbg (ctx, "darwin event thread ready to receive events");
545 /* signal the main thread that the hotplug runloop has been created. */
546 pthread_mutex_lock (&libusb_darwin_at_mutex);
547 libusb_darwin_acfl = runloop;
548 libusb_darwin_acfls = libusb_shutdown_cfsource;
549 pthread_cond_signal (&libusb_darwin_at_cond);
550 pthread_mutex_unlock (&libusb_darwin_at_mutex);
552 /* run the runloop */
555 usbi_dbg (ctx, "darwin event thread exiting");
557 /* signal the main thread that the hotplug runloop has finished. */
558 pthread_mutex_lock (&libusb_darwin_at_mutex);
559 libusb_darwin_acfls = NULL;
560 libusb_darwin_acfl = NULL;
561 pthread_cond_signal (&libusb_darwin_at_cond);
562 pthread_mutex_unlock (&libusb_darwin_at_mutex);
564 /* remove the notification cfsource */
565 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
567 /* remove the shutdown cfsource */
568 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
570 /* delete notification port */
571 IONotificationPortDestroy (libusb_notification_port);
573 /* delete iterators */
574 IOObjectRelease (libusb_rem_device_iterator);
575 IOObjectRelease (libusb_add_device_iterator);
577 CFRelease (libusb_shutdown_cfsource);
583 /* cleanup function to destroy cached devices */
584 static void darwin_cleanup_devices(void) {
585 struct darwin_cached_device *dev, *next;
587 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
588 darwin_deref_cached_device(dev);
592 static int darwin_init(struct libusb_context *ctx) {
596 first_init = (1 == ++init_count);
600 if (NULL == darwin_cached_devices.next) {
601 list_init (&darwin_cached_devices);
603 assert(list_empty(&darwin_cached_devices));
604 #if !defined(HAVE_CLOCK_GETTIME)
605 /* create the clocks that will be used if clock_gettime() is not available */
606 host_name_port_t host_self;
608 host_self = mach_host_self();
609 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
610 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
611 mach_port_deallocate(mach_task_self(), host_self);
615 rc = darwin_scan_devices (ctx);
616 if (LIBUSB_SUCCESS != rc)
620 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
622 usbi_err (ctx, "could not create event thread, error %d", rc);
623 rc = LIBUSB_ERROR_OTHER;
627 pthread_mutex_lock (&libusb_darwin_at_mutex);
628 while (!libusb_darwin_acfl)
629 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
630 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
631 libusb_darwin_acfl = NULL;
632 rc = LIBUSB_ERROR_OTHER;
634 pthread_mutex_unlock (&libusb_darwin_at_mutex);
637 pthread_join (libusb_darwin_at, NULL);
641 if (LIBUSB_SUCCESS != rc) {
643 darwin_cleanup_devices ();
644 #if !defined(HAVE_CLOCK_GETTIME)
645 mach_port_deallocate(mach_task_self(), clock_realtime);
646 mach_port_deallocate(mach_task_self(), clock_monotonic);
655 static void darwin_exit (struct libusb_context *ctx) {
658 if (0 == --init_count) {
659 /* stop the event runloop and wait for the thread to terminate. */
660 pthread_mutex_lock (&libusb_darwin_at_mutex);
661 CFRunLoopSourceSignal (libusb_darwin_acfls);
662 CFRunLoopWakeUp (libusb_darwin_acfl);
663 while (libusb_darwin_acfl)
664 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
665 pthread_mutex_unlock (&libusb_darwin_at_mutex);
666 pthread_join (libusb_darwin_at, NULL);
668 darwin_cleanup_devices ();
670 #if !defined(HAVE_CLOCK_GETTIME)
671 mach_port_deallocate(mach_task_self(), clock_realtime);
672 mach_port_deallocate(mach_task_self(), clock_monotonic);
677 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
678 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
680 IOUSBConfigurationDescriptorPtr desc;
683 /* is there a simpler way to determine the index? */
684 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
685 if (kresult != kIOReturnSuccess)
686 return darwin_to_libusb (kresult);
688 for (i = 0 ; i < numConfig ; i++) {
689 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
691 if (desc->bConfigurationValue == config_value)
695 /* configuration not found */
696 return LIBUSB_ERROR_NOT_FOUND;
699 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
700 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
703 if (0 == priv->active_config)
704 return LIBUSB_ERROR_NOT_FOUND;
706 config_index = get_configuration_index (dev, priv->active_config);
707 if (config_index < 0)
710 assert(config_index >= 0 && config_index <= UINT8_MAX);
711 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
714 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
715 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
716 IOUSBConfigurationDescriptorPtr desc;
720 if (!priv || !priv->device)
721 return LIBUSB_ERROR_OTHER;
723 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
724 if (kresult == kIOReturnSuccess) {
725 /* copy descriptor */
726 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
727 len = libusb_le16_to_cpu(desc->wTotalLength);
729 memmove (buffer, desc, len);
732 ret = darwin_to_libusb (kresult);
733 if (ret != LIBUSB_SUCCESS)
739 /* check whether the os has configured the device */
740 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
741 usb_device_t **darwin_device = dev->device;
743 IOUSBConfigurationDescriptorPtr configDesc;
744 IOUSBFindInterfaceRequest request;
746 io_iterator_t interface_iterator;
747 io_service_t firstInterface;
749 if (dev->dev_descriptor.bNumConfigurations < 1) {
750 usbi_err (ctx, "device has no configurations");
751 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
754 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
756 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
757 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
758 usbi_dbg (ctx, "ignoring configuration on root hub simulation");
759 dev->active_config = 0;
760 return LIBUSB_SUCCESS;
763 /* find the first configuration */
764 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
765 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
767 /* check if the device is already configured. there is probably a better way than iterating over the
768 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
769 might lock up on the device request) */
771 /* Setup the Interface Request */
772 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
773 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
774 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
775 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
777 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
778 if (kresult != kIOReturnSuccess)
779 return darwin_to_libusb (kresult);
782 firstInterface = IOIteratorNext(interface_iterator);
784 /* done with the interface iterator */
785 IOObjectRelease(interface_iterator);
787 if (firstInterface) {
788 IOObjectRelease (firstInterface);
790 /* device is configured */
791 if (dev->dev_descriptor.bNumConfigurations == 1)
792 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
793 dev->active_config = dev->first_config;
795 /* devices with more than one configuration should work with GetConfiguration */
796 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
799 dev->active_config = 0;
801 usbi_dbg (ctx, "active config: %u, first config: %u", dev->active_config, dev->first_config);
803 return LIBUSB_SUCCESS;
806 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
807 IOUSBDevRequestTO req;
809 assert(buffer_size <= UINT16_MAX);
811 memset (buffer, 0, buffer_size);
813 /* Set up request for descriptor/ */
814 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
815 req.bRequest = kUSBRqGetDescriptor;
816 req.wValue = (UInt16)(desc << 8);
817 req.wIndex = desc_index;
818 req.wLength = (UInt16)buffer_size;
820 req.noDataTimeout = 20;
821 req.completionTimeout = 100;
823 return (*device)->DeviceRequestTO (device, &req);
826 static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) {
827 usb_device_t **device = dev->device;
829 long delay = 30000; // microseconds
830 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
832 IOReturn ret = 0, ret2;
834 UInt16 idProduct, idVendor;
836 dev->can_enumerate = 0;
838 (*device)->GetDeviceClass (device, &bDeviceClass);
839 (*device)->GetDeviceProduct (device, &idProduct);
840 (*device)->GetDeviceVendor (device, &idVendor);
842 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
843 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
844 * to follow the spec as closely as possible, try opening the device */
845 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
848 /**** retrieve device descriptor ****/
849 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
851 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
852 /* received an overrun error but we still received a device descriptor */
853 ret = kIOReturnSuccess;
855 if (kIOUSBVendorIDAppleComputer == idVendor) {
856 /* NTH: don't bother retrying or unsuspending Apple devices */
860 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
861 0 == dev->dev_descriptor.bcdUSB)) {
862 /* work around for incorrectly configured devices */
863 if (try_reconfigure && is_open) {
864 usbi_dbg(ctx, "descriptor appears to be invalid. resetting configuration before trying again...");
866 /* set the first configuration */
867 (*device)->SetConfiguration(device, 1);
869 /* don't try to reconfigure again */
873 ret = kIOUSBPipeStalled;
876 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
877 /* device may be suspended. unsuspend it and try again */
878 #if DeviceVersion >= 320
881 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
882 (void)(*device)->GetUSBDeviceInformation (device, &info);
884 /* note that the device was suspended */
885 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
890 /* try to unsuspend the device */
891 ret2 = (*device)->USBDeviceSuspend (device, 0);
892 if (kIOReturnSuccess != ret2) {
893 /* prevent log spew from poorly behaving devices. this indicates the
894 os actually had trouble communicating with the device */
895 usbi_dbg(ctx, "could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
903 if (kIOReturnSuccess != ret) {
904 usbi_dbg(ctx, "kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
905 /* sleep for a little while before trying again */
906 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
908 } while (kIOReturnSuccess != ret && retries--);
911 /* resuspend the device */
912 (void)(*device)->USBDeviceSuspend (device, 1);
915 (void) (*device)->USBDeviceClose (device);
917 if (ret != kIOReturnSuccess) {
918 /* a debug message was already printed out for this error */
919 if (LIBUSB_CLASS_HUB == bDeviceClass)
920 usbi_dbg (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
921 idVendor, idProduct, darwin_error_str (ret), ret);
923 usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
924 idVendor, idProduct, darwin_error_str (ret), ret);
925 return darwin_to_libusb (ret);
928 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
929 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
930 /* not a valid device */
931 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
932 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
933 return LIBUSB_ERROR_NO_DEVICE;
936 usbi_dbg (ctx, "cached device descriptor:");
937 usbi_dbg (ctx, " bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
938 usbi_dbg (ctx, " bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
939 usbi_dbg (ctx, " bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
940 usbi_dbg (ctx, " bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
941 usbi_dbg (ctx, " bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
942 usbi_dbg (ctx, " bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
943 usbi_dbg (ctx, " idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
944 usbi_dbg (ctx, " idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
945 usbi_dbg (ctx, " bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
946 usbi_dbg (ctx, " iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
947 usbi_dbg (ctx, " iProduct: 0x%02x", dev->dev_descriptor.iProduct);
948 usbi_dbg (ctx, " iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
949 usbi_dbg (ctx, " bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
951 dev->can_enumerate = 1;
953 return LIBUSB_SUCCESS;
956 /* Returns 1 on success, 0 on failure. */
957 static bool get_device_port (io_service_t service, UInt8 *port) {
962 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
966 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
967 if (kIOReturnSuccess == kresult) {
968 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
969 IOObjectRelease (parent);
975 /* Returns 1 on success, 0 on failure. */
976 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
980 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
982 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
983 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
989 /* We ran out of parents */
993 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
994 UInt64 *old_session_id) {
995 struct darwin_cached_device *new_device;
996 UInt64 sessionID = 0, parent_sessionID = 0;
997 UInt32 locationID = 0;
998 enum libusb_error ret = LIBUSB_SUCCESS;
999 usb_device_t **device;
1002 /* assuming sessionID != 0 normally (never seen it be 0) */
1003 *old_session_id = 0;
1006 /* get some info from the io registry */
1007 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
1008 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
1009 if (!get_device_port (service, &port)) {
1010 usbi_dbg(ctx, "could not get connected port number");
1013 usbi_dbg(ctx, "finding cached device for sessionID 0x%" PRIx64, sessionID);
1015 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1016 usbi_dbg(ctx, "parent sessionID: 0x%" PRIx64, parent_sessionID);
1019 usbi_mutex_lock(&darwin_cached_devices_lock);
1021 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1022 usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1023 sessionID, locationID, new_device->session, new_device->location);
1024 if (new_device->location == locationID && new_device->in_reenumerate) {
1025 usbi_dbg (ctx, "found cached device with matching location that is being re-enumerated");
1026 *old_session_id = new_device->session;
1030 if (new_device->session == sessionID) {
1031 usbi_dbg(ctx, "using cached device for device");
1032 *cached_out = new_device;
1040 usbi_dbg(ctx, "caching new device with sessionID 0x%" PRIx64, sessionID);
1042 device = darwin_device_from_service (ctx, service);
1044 ret = LIBUSB_ERROR_NO_DEVICE;
1048 if (!(*old_session_id)) {
1049 new_device = calloc (1, sizeof (*new_device));
1051 ret = LIBUSB_ERROR_NO_MEM;
1055 /* add this device to the cached device list */
1056 list_add(&new_device->list, &darwin_cached_devices);
1058 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1060 /* keep a reference to this device */
1061 darwin_ref_cached_device(new_device);
1063 (*device)->GetLocationID (device, &new_device->location);
1064 new_device->port = port;
1065 new_device->parent_session = parent_sessionID;
1067 /* release the ref to old device's service */
1068 IOObjectRelease (new_device->service);
1071 /* keep track of devices regardless of if we successfully enumerate them to
1072 prevent them from being enumerated multiple times */
1073 *cached_out = new_device;
1075 new_device->session = sessionID;
1076 new_device->device = device;
1077 new_device->service = service;
1079 /* retain the service */
1080 IOObjectRetain (service);
1082 /* cache the device descriptor */
1083 ret = darwin_cache_device_descriptor(ctx, new_device);
1087 if (new_device->can_enumerate) {
1088 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1089 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1090 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1091 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1095 usbi_mutex_unlock(&darwin_cached_devices_lock);
1100 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1101 UInt64 old_session_id) {
1102 struct darwin_device_priv *priv;
1103 struct libusb_device *dev = NULL;
1105 enum libusb_error ret = LIBUSB_SUCCESS;
1108 /* check current active configuration (and cache the first configuration value--
1109 which may be used by claim_interface) */
1110 ret = darwin_check_configuration (ctx, cached_device);
1114 if (0 != old_session_id) {
1115 usbi_dbg (ctx, "re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1116 ctx, old_session_id, cached_device->session);
1117 /* save the libusb device before the session id is updated */
1118 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1122 usbi_dbg (ctx, "allocating new device in context %p for with session 0x%" PRIx64,
1123 ctx, cached_device->session);
1125 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1127 return LIBUSB_ERROR_NO_MEM;
1130 priv = usbi_get_device_priv(dev);
1132 priv->dev = cached_device;
1133 darwin_ref_cached_device (priv->dev);
1134 dev->port_number = cached_device->port;
1135 /* the location ID encodes the path to the device. the top byte of the location ID contains the bus number
1136 (numbered from 0). the remaining bytes can be used to construct the device tree for that bus. */
1137 dev->bus_number = cached_device->location >> 24;
1138 assert(cached_device->address <= UINT8_MAX);
1139 dev->device_address = (uint8_t)cached_device->address;
1141 priv = usbi_get_device_priv(dev);
1144 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1145 "mismatch between libusb and IOKit device descriptor sizes");
1146 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1147 usbi_localize_device_descriptor(&dev->device_descriptor);
1148 dev->session_data = cached_device->session;
1150 if (NULL != dev->parent_dev) {
1151 libusb_unref_device(dev->parent_dev);
1152 dev->parent_dev = NULL;
1155 if (cached_device->parent_session > 0) {
1156 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1159 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1162 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1163 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1164 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1165 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
1166 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1168 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1169 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1172 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1175 ret = usbi_sanitize_device (dev);
1179 usbi_dbg (ctx, "found device with address %d port = %d parent = %p at %p", dev->device_address,
1180 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1184 if (!cached_device->in_reenumerate && 0 == ret) {
1185 usbi_connect_device (dev);
1187 libusb_unref_device (dev);
1193 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1194 struct darwin_cached_device *cached_device;
1195 UInt64 old_session_id;
1196 io_iterator_t deviceIterator;
1197 io_service_t service;
1201 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1202 if (kresult != kIOReturnSuccess)
1203 return darwin_to_libusb (kresult);
1205 while ((service = IOIteratorNext (deviceIterator))) {
1206 ret = darwin_get_cached_device (ctx, service, &cached_device, &old_session_id);
1207 if (ret < 0 || !cached_device->can_enumerate) {
1211 (void) process_new_device (ctx, cached_device, old_session_id);
1213 IOObjectRelease(service);
1216 IOObjectRelease(deviceIterator);
1218 return LIBUSB_SUCCESS;
1221 static int darwin_open (struct libusb_device_handle *dev_handle) {
1222 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1223 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1226 if (0 == dpriv->open_count) {
1227 /* try to open the device */
1228 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1229 if (kresult != kIOReturnSuccess) {
1230 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1232 if (kIOReturnExclusiveAccess != kresult) {
1233 return darwin_to_libusb (kresult);
1236 /* it is possible to perform some actions on a device that is not open so do not return an error */
1237 priv->is_open = false;
1239 priv->is_open = true;
1242 /* create async event source */
1243 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1244 if (kresult != kIOReturnSuccess) {
1245 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1247 if (priv->is_open) {
1248 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1251 priv->is_open = false;
1253 return darwin_to_libusb (kresult);
1256 CFRetain (libusb_darwin_acfl);
1258 /* add the cfSource to the async run loop */
1259 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1262 /* device opened successfully */
1263 dpriv->open_count++;
1265 usbi_dbg (HANDLE_CTX(dev_handle), "device open for access");
1270 static void darwin_close (struct libusb_device_handle *dev_handle) {
1271 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1272 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1276 if (dpriv->open_count == 0) {
1277 /* something is probably very wrong if this is the case */
1278 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1282 dpriv->open_count--;
1283 if (NULL == dpriv->device) {
1284 usbi_warn (HANDLE_CTX (dev_handle), "darwin_close device missing IOService");
1288 /* make sure all interfaces are released */
1289 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1290 if (dev_handle->claimed_interfaces & (1U << i))
1291 libusb_release_interface (dev_handle, i);
1293 if (0 == dpriv->open_count) {
1294 /* delete the device's async event source */
1295 if (priv->cfSource) {
1296 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1297 CFRelease (priv->cfSource);
1298 priv->cfSource = NULL;
1299 CFRelease (libusb_darwin_acfl);
1302 if (priv->is_open) {
1303 /* close the device */
1304 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1305 if (kresult != kIOReturnSuccess) {
1306 /* Log the fact that we had a problem closing the file, however failing a
1307 * close isn't really an error, so return success anyway */
1308 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1314 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1315 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1317 *config = dpriv->active_config;
1319 return LIBUSB_SUCCESS;
1322 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1323 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1330 /* Setting configuration will invalidate the interface, so we need
1331 to reclaim it. First, dispose of existing interfaces, if any. */
1332 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1333 if (dev_handle->claimed_interfaces & (1U << i))
1334 darwin_release_interface (dev_handle, i);
1336 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1337 if (kresult != kIOReturnSuccess)
1338 return darwin_to_libusb (kresult);
1340 /* Reclaim any interfaces. */
1341 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1342 if (dev_handle->claimed_interfaces & (1U << i))
1343 darwin_claim_interface (dev_handle, i);
1345 dpriv->active_config = (UInt8)config;
1347 return LIBUSB_SUCCESS;
1350 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1351 IOUSBFindInterfaceRequest request;
1353 io_iterator_t interface_iterator;
1354 UInt8 bInterfaceNumber;
1357 *usbInterfacep = IO_OBJECT_NULL;
1359 /* Setup the Interface Request */
1360 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1361 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1362 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1363 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1365 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1366 if (kresult != kIOReturnSuccess)
1369 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1370 /* find the interface number */
1371 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1374 if (ret && bInterfaceNumber == ifc) {
1378 (void) IOObjectRelease (*usbInterfacep);
1381 /* done with the interface iterator */
1382 IOObjectRelease(interface_iterator);
1384 return kIOReturnSuccess;
1387 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1388 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1390 /* current interface */
1391 struct darwin_interface *cInterface = &priv->interfaces[iface];
1395 UInt8 numep, direction, number;
1396 UInt8 dont_care1, dont_care3;
1399 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1402 usbi_dbg (ctx, "building table of endpoints.");
1404 /* retrieve the total number of endpoints on this interface */
1405 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1406 if (kresult != kIOReturnSuccess) {
1407 usbi_err (ctx, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1408 return darwin_to_libusb (kresult);
1411 /* iterate through pipe references */
1412 for (UInt8 i = 1 ; i <= numep ; i++) {
1413 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1414 &dont_care2, &dont_care3);
1416 if (kresult != kIOReturnSuccess) {
1417 /* probably a buggy device. try to get the endpoint address from the descriptors */
1418 struct libusb_config_descriptor *config;
1419 const struct libusb_endpoint_descriptor *endpoint_desc;
1422 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1423 if (kresult != kIOReturnSuccess) {
1424 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1425 return darwin_to_libusb (kresult);
1428 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1429 if (LIBUSB_SUCCESS != rc) {
1433 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1435 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1437 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1440 usbi_dbg (ctx, "interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1441 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1444 cInterface->num_endpoints = numep;
1446 return LIBUSB_SUCCESS;
1449 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1450 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1451 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1452 io_service_t usbInterface = IO_OBJECT_NULL;
1454 enum libusb_error ret;
1455 IOCFPlugInInterface **plugInInterface = NULL;
1458 /* current interface */
1459 struct darwin_interface *cInterface = &priv->interfaces[iface];
1461 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1463 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1464 if (kresult != kIOReturnSuccess)
1465 return darwin_to_libusb (kresult);
1467 /* make sure we have an interface */
1468 if (!usbInterface && dpriv->first_config != 0) {
1469 usbi_info (ctx, "no interface found; setting configuration: %d", dpriv->first_config);
1471 /* set the configuration */
1472 ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1473 if (ret != LIBUSB_SUCCESS) {
1474 usbi_err (ctx, "could not set configuration");
1478 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1479 if (kresult != kIOReturnSuccess) {
1480 usbi_err (ctx, "darwin_get_interface: %s", darwin_error_str(kresult));
1481 return darwin_to_libusb (kresult);
1485 if (!usbInterface) {
1486 usbi_info (ctx, "interface not found");
1487 return LIBUSB_ERROR_NOT_FOUND;
1490 /* get an interface to the device's interface */
1491 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1492 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1494 /* ignore release error */
1495 (void)IOObjectRelease (usbInterface);
1497 if (kresult != kIOReturnSuccess) {
1498 usbi_err (ctx, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1499 return darwin_to_libusb (kresult);
1502 if (!plugInInterface) {
1503 usbi_err (ctx, "plugin interface not found");
1504 return LIBUSB_ERROR_NOT_FOUND;
1507 /* Do the actual claim */
1508 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1509 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1510 (LPVOID)&cInterface->interface);
1511 /* We no longer need the intermediate plug-in */
1512 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1513 (*plugInInterface)->Release (plugInInterface);
1514 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1515 usbi_err (ctx, "QueryInterface: %s", darwin_error_str(kresult));
1516 return darwin_to_libusb (kresult);
1519 /* claim the interface */
1520 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1521 if (kresult != kIOReturnSuccess) {
1522 usbi_info (ctx, "USBInterfaceOpen: %s", darwin_error_str(kresult));
1523 return darwin_to_libusb (kresult);
1526 /* update list of endpoints */
1527 ret = get_endpoints (dev_handle, iface);
1529 /* this should not happen */
1530 darwin_release_interface (dev_handle, iface);
1531 usbi_err (ctx, "could not build endpoint table");
1535 cInterface->cfSource = NULL;
1537 /* create async event source */
1538 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1539 if (kresult != kIOReturnSuccess) {
1540 usbi_err (ctx, "could not create async event source");
1542 /* can't continue without an async event source */
1543 (void)darwin_release_interface (dev_handle, iface);
1545 return darwin_to_libusb (kresult);
1548 /* add the cfSource to the async thread's run loop */
1549 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1551 usbi_dbg (ctx, "interface opened");
1553 return LIBUSB_SUCCESS;
1556 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1557 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1560 /* current interface */
1561 struct darwin_interface *cInterface = &priv->interfaces[iface];
1563 /* Check to see if an interface is open */
1564 if (!cInterface->interface)
1565 return LIBUSB_SUCCESS;
1567 /* clean up endpoint data */
1568 cInterface->num_endpoints = 0;
1570 /* delete the interface's async event source */
1571 if (cInterface->cfSource) {
1572 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1573 CFRelease (cInterface->cfSource);
1574 cInterface->cfSource = NULL;
1577 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1578 if (kresult != kIOReturnSuccess)
1579 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1581 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1582 if (kresult != kIOReturnSuccess)
1583 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1585 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1587 return darwin_to_libusb (kresult);
1590 static int check_alt_setting_and_clear_halt(struct libusb_device_handle *dev_handle, uint8_t altsetting, struct darwin_interface *cInterface) {
1591 enum libusb_error ret;
1593 uint8_t current_alt_setting;
1595 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, ¤t_alt_setting);
1596 if (kresult == kIOReturnSuccess && altsetting != current_alt_setting) {
1597 return LIBUSB_ERROR_PIPE;
1600 for (int i = 0 ; i < cInterface->num_endpoints ; i++) {
1601 ret = darwin_clear_halt(dev_handle, cInterface->endpoint_addrs[i]);
1602 if (LIBUSB_SUCCESS != ret) {
1603 usbi_warn(HANDLE_CTX (dev_handle), "error clearing pipe halt for endpoint %d", i);
1604 if (LIBUSB_ERROR_NOT_FOUND == ret) {
1605 /* may need to re-open the interface */
1611 return LIBUSB_SUCCESS;
1614 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1615 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1617 enum libusb_error ret;
1619 /* current interface */
1620 struct darwin_interface *cInterface = &priv->interfaces[iface];
1622 if (!cInterface->interface)
1623 return LIBUSB_ERROR_NO_DEVICE;
1625 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1626 if (kresult == kIOReturnSuccess) {
1627 /* update the list of endpoints */
1628 ret = get_endpoints (dev_handle, iface);
1630 /* this should not happen */
1631 darwin_release_interface (dev_handle, iface);
1632 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1637 usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1639 ret = darwin_to_libusb(kresult);
1640 if (ret != LIBUSB_ERROR_PIPE) {
1644 /* If a device only supports a default setting for the specified interface, then a STALL
1645 (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1646 Mimic the behaviour in e.g. the Linux kernel: in such case, reset all endpoints
1647 of the interface (as would have been done per 9.1.1.5) and return success. */
1649 ret = check_alt_setting_and_clear_halt(dev_handle, altsetting, cInterface);
1650 if (LIBUSB_ERROR_NOT_FOUND == ret) {
1651 /* For some reason we need to reclaim the interface after the pipe error with some versions of macOS */
1652 ret = darwin_claim_interface (dev_handle, iface);
1653 if (LIBUSB_SUCCESS != ret) {
1654 darwin_release_interface (dev_handle, iface);
1655 usbi_err (HANDLE_CTX (dev_handle), "could not reclaim interface: %s", darwin_error_str(kresult));
1657 ret = check_alt_setting_and_clear_halt(dev_handle, altsetting, cInterface);
1663 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1664 /* current interface */
1665 struct darwin_interface *cInterface;
1669 /* determine the interface/endpoint to use */
1670 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1671 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1673 return LIBUSB_ERROR_NOT_FOUND;
1676 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1677 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1678 if (kresult != kIOReturnSuccess)
1679 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1681 return darwin_to_libusb (kresult);
1684 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1685 unsigned long claimed_interfaces) {
1686 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1687 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1688 int open_count = dpriv->open_count;
1691 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1693 /* clear claimed interfaces temporarily */
1694 dev_handle->claimed_interfaces = 0;
1696 /* close and re-open the device */
1697 priv->is_open = false;
1698 dpriv->open_count = 1;
1700 /* clean up open interfaces */
1701 (void) darwin_close (dev_handle);
1703 /* re-open the device */
1704 ret = darwin_open (dev_handle);
1705 dpriv->open_count = open_count;
1706 if (LIBUSB_SUCCESS != ret) {
1707 /* could not restore configuration */
1708 return LIBUSB_ERROR_NOT_FOUND;
1711 if (dpriv->active_config != active_config) {
1712 usbi_dbg (ctx, "darwin/restore_state: restoring configuration %d...", active_config);
1714 ret = darwin_set_configuration (dev_handle, active_config);
1715 if (LIBUSB_SUCCESS != ret) {
1716 usbi_dbg (ctx, "darwin/restore_state: could not restore configuration");
1717 return LIBUSB_ERROR_NOT_FOUND;
1721 usbi_dbg (ctx, "darwin/restore_state: reclaiming interfaces");
1723 if (claimed_interfaces) {
1724 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1725 if (!(claimed_interfaces & (1U << iface))) {
1729 usbi_dbg (ctx, "darwin/restore_state: re-claiming interface %u", iface);
1731 ret = darwin_claim_interface (dev_handle, iface);
1732 if (LIBUSB_SUCCESS != ret) {
1733 usbi_dbg (ctx, "darwin/restore_state: could not claim interface %u", iface);
1734 return LIBUSB_ERROR_NOT_FOUND;
1737 dev_handle->claimed_interfaces |= 1U << iface;
1741 usbi_dbg (ctx, "darwin/restore_state: device state restored");
1743 return LIBUSB_SUCCESS;
1746 static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) {
1747 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1748 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1749 int8_t active_config = dpriv->active_config;
1751 IOUSBDeviceDescriptor descriptor;
1752 IOUSBConfigurationDescriptorPtr cached_configuration;
1753 IOUSBConfigurationDescriptor *cached_configurations;
1757 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1759 if (dpriv->in_reenumerate) {
1760 /* ack, two (or more) threads are trying to reset the device! abort! */
1761 return LIBUSB_ERROR_NOT_FOUND;
1764 dpriv->in_reenumerate = true;
1766 /* store copies of descriptors so they can be compared after the reset */
1767 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1768 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1770 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1771 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1772 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1775 /* if we need to release capture */
1776 if (HAS_CAPTURE_DEVICE()) {
1778 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
1779 options |= kUSBReEnumerateCaptureDeviceMask;
1786 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1787 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
1788 if (kresult != kIOReturnSuccess) {
1789 usbi_err (ctx, "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1790 dpriv->in_reenumerate = false;
1791 return darwin_to_libusb (kresult);
1794 /* capture mode does not re-enumerate but it does require re-open */
1796 usbi_dbg (ctx, "darwin/reenumerate_device: restoring state...");
1797 dpriv->in_reenumerate = false;
1798 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1801 usbi_dbg (ctx, "darwin/reenumerate_device: waiting for re-enumeration to complete...");
1803 struct timespec start;
1804 clock_gettime(CLOCK_MONOTONIC, &start);
1806 while (dpriv->in_reenumerate) {
1807 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1808 nanosleep (&delay, NULL);
1810 struct timespec now;
1811 clock_gettime(CLOCK_MONOTONIC, &now);
1812 UInt32 elapsed = (now.tv_sec - start.tv_sec) * 1000000 + (now.tv_nsec - start.tv_nsec) / 1000;
1814 if (elapsed >= DARWIN_REENUMERATE_TIMEOUT_US) {
1815 usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate");
1816 dpriv->in_reenumerate = false;
1817 return LIBUSB_ERROR_TIMEOUT;
1821 /* compare descriptors */
1822 usbi_dbg (ctx, "darwin/reenumerate_device: checking whether descriptors changed");
1824 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1825 /* device descriptor changed. need to return not found. */
1826 usbi_dbg (ctx, "darwin/reenumerate_device: device descriptor changed");
1827 return LIBUSB_ERROR_NOT_FOUND;
1830 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1831 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1832 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1833 usbi_dbg (ctx, "darwin/reenumerate_device: configuration descriptor %d changed", i);
1834 return LIBUSB_ERROR_NOT_FOUND;
1838 usbi_dbg (ctx, "darwin/reenumerate_device: device reset complete. restoring state...");
1840 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1843 static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
1844 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1847 if (dpriv->capture_count > 0) {
1848 /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
1849 kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
1850 return darwin_to_libusb (kresult);
1852 return darwin_reenumerate_device (dev_handle, false);
1856 static io_service_t usb_find_interface_matching_location (const io_name_t class_name, UInt8 interface_number, UInt32 location) {
1857 CFMutableDictionaryRef matchingDict = IOServiceMatching (class_name);
1858 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault, 0,
1859 &kCFTypeDictionaryKeyCallBacks,
1860 &kCFTypeDictionaryValueCallBacks);
1861 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
1862 CFTypeRef interfaceCF = CFNumberCreate (NULL, kCFNumberSInt8Type, &interface_number);
1864 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
1865 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
1866 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBHostMatchingPropertyInterfaceNumber), interfaceCF);
1868 CFRelease (interfaceCF);
1869 CFRelease (locationCF);
1870 CFRelease (propertyMatchDict);
1872 return IOServiceGetMatchingService (darwin_default_master_port, matchingDict);
1875 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1876 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1877 io_service_t usb_interface, child = IO_OBJECT_NULL;
1879 /* locate the IO registry entry for this interface */
1880 usb_interface = usb_find_interface_matching_location (kIOUSBHostInterfaceClassName, interface, dpriv->location);
1881 if (0 == usb_interface) {
1882 /* check for the legacy class entry */
1883 usb_interface = usb_find_interface_matching_location (kIOUSBInterfaceClassName, interface, dpriv->location);
1884 if (0 == usb_interface) {
1885 return LIBUSB_ERROR_NOT_FOUND;
1889 /* if the IO object has a child entry in the IO Registry it has a kernel driver attached */
1890 (void) IORegistryEntryGetChildEntry (usb_interface, kIOServicePlane, &child);
1891 IOObjectRelease (usb_interface);
1892 if (IO_OBJECT_NULL != child) {
1893 IOObjectRelease (child);
1901 static void darwin_destroy_device(struct libusb_device *dev) {
1902 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1905 /* need to hold the lock in case this is the last reference to the device */
1906 usbi_mutex_lock(&darwin_cached_devices_lock);
1907 darwin_deref_cached_device (dpriv->dev);
1909 usbi_mutex_unlock(&darwin_cached_devices_lock);
1913 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1914 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1917 uint8_t transferType;
1919 uint16_t maxPacketSize;
1921 struct darwin_interface *cInterface;
1922 #if InterfaceVersion >= 550
1923 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1925 /* None of the values below are used in libusb for bulk transfers */
1926 uint8_t direction, number, interval;
1929 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1930 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1932 return LIBUSB_ERROR_NOT_FOUND;
1935 #if InterfaceVersion >= 550
1936 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1938 transferType = pipeProperties.bTransferType;
1939 maxPacketSize = pipeProperties.wMaxPacketSize;
1941 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1942 &transferType, &maxPacketSize, &interval);
1946 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1947 darwin_error_str(ret), ret);
1948 return darwin_to_libusb (ret);
1951 if (0 != (transfer->length % maxPacketSize)) {
1952 /* do not need a zero packet */
1953 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1956 /* submit the request */
1957 /* timeouts are unavailable on interrupt endpoints */
1958 if (transferType == kUSBInterrupt) {
1959 if (IS_XFERIN(transfer))
1960 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1961 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1963 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1964 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1966 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1968 if (IS_XFERIN(transfer))
1969 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1970 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1971 darwin_async_io_callback, itransfer);
1973 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1974 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1975 darwin_async_io_callback, itransfer);
1979 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1980 darwin_error_str(ret), ret);
1982 return darwin_to_libusb (ret);
1985 #if InterfaceVersion >= 550
1986 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1987 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1988 struct darwin_interface *cInterface;
1992 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1993 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1995 return LIBUSB_ERROR_NOT_FOUND;
1998 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2000 if (IS_XFERIN(transfer))
2001 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
2002 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
2003 transfer->timeout, darwin_async_io_callback, itransfer);
2005 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
2006 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
2007 transfer->timeout, darwin_async_io_callback, itransfer);
2010 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
2011 darwin_error_str(ret), ret);
2013 return darwin_to_libusb (ret);
2017 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
2018 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2019 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2022 uint8_t direction, number, interval, pipeRef, transferType;
2023 uint16_t maxPacketSize;
2025 AbsoluteTime atTime;
2028 struct darwin_interface *cInterface;
2030 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
2031 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
2032 free(tpriv->isoc_framelist);
2033 tpriv->isoc_framelist = NULL;
2036 if (!tpriv->isoc_framelist) {
2037 tpriv->num_iso_packets = transfer->num_iso_packets;
2038 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
2039 if (!tpriv->isoc_framelist)
2040 return LIBUSB_ERROR_NO_MEM;
2043 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
2044 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
2045 unsigned int length = transfer->iso_packet_desc[i].length;
2046 assert(length <= UINT16_MAX);
2047 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
2050 /* determine the interface/endpoint to use */
2051 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2052 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2054 return LIBUSB_ERROR_NOT_FOUND;
2057 /* determine the properties of this endpoint and the speed of the device */
2058 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
2059 &transferType, &maxPacketSize, &interval);
2061 /* Last but not least we need the bus frame number */
2062 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
2063 if (kresult != kIOReturnSuccess) {
2064 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
2065 free(tpriv->isoc_framelist);
2066 tpriv->isoc_framelist = NULL;
2068 return darwin_to_libusb (kresult);
2071 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
2072 &transferType, &maxPacketSize, &interval);
2074 /* schedule for a frame a little in the future */
2077 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
2078 frame = cInterface->frames[transfer->endpoint];
2080 /* submit the request */
2081 if (IS_XFERIN(transfer))
2082 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2083 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2086 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2087 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2090 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
2092 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
2094 /* High/super speed */
2095 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
2097 if (kresult != kIOReturnSuccess) {
2098 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
2099 darwin_error_str(kresult));
2100 free (tpriv->isoc_framelist);
2101 tpriv->isoc_framelist = NULL;
2104 return darwin_to_libusb (kresult);
2107 static int submit_control_transfer(struct usbi_transfer *itransfer) {
2108 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2109 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
2110 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2111 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2115 memset(&tpriv->req, 0, sizeof(tpriv->req));
2117 /* IOUSBDeviceInterface expects the request in cpu endianness */
2118 tpriv->req.bmRequestType = setup->bmRequestType;
2119 tpriv->req.bRequest = setup->bRequest;
2120 /* these values should be in bus order from libusb_fill_control_setup */
2121 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
2122 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
2123 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
2124 /* data is stored after the libusb control block */
2125 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
2126 tpriv->req.completionTimeout = transfer->timeout;
2127 tpriv->req.noDataTimeout = transfer->timeout;
2129 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2131 /* all transfers in libusb-1.0 are async */
2133 if (transfer->endpoint) {
2134 struct darwin_interface *cInterface;
2137 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2138 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2140 return LIBUSB_ERROR_NOT_FOUND;
2143 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2145 /* control request on endpoint 0 */
2146 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2148 if (kresult != kIOReturnSuccess)
2149 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2151 return darwin_to_libusb (kresult);
2154 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2155 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2157 switch (transfer->type) {
2158 case LIBUSB_TRANSFER_TYPE_CONTROL:
2159 return submit_control_transfer(itransfer);
2160 case LIBUSB_TRANSFER_TYPE_BULK:
2161 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2162 return submit_bulk_transfer(itransfer);
2163 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2164 return submit_iso_transfer(itransfer);
2165 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2166 #if InterfaceVersion >= 550
2167 return submit_stream_transfer(itransfer);
2169 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2170 return LIBUSB_ERROR_NOT_SUPPORTED;
2173 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2174 return LIBUSB_ERROR_INVALID_PARAM;
2178 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2179 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2180 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2183 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2186 return LIBUSB_ERROR_NO_DEVICE;
2188 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2190 return darwin_to_libusb (kresult);
2193 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2194 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2195 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2196 struct darwin_interface *cInterface;
2197 uint8_t pipeRef, iface;
2200 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2202 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2203 usbi_err (ctx, "endpoint not found on any open interface");
2205 return LIBUSB_ERROR_NOT_FOUND;
2209 return LIBUSB_ERROR_NO_DEVICE;
2211 usbi_warn (ctx, "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2213 /* abort transactions */
2214 #if InterfaceVersion >= 550
2215 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2216 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2219 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2221 usbi_dbg (ctx, "calling clear pipe stall to clear the data toggle bit");
2223 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2224 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2226 return darwin_to_libusb (kresult);
2229 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2230 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2232 switch (transfer->type) {
2233 case LIBUSB_TRANSFER_TYPE_CONTROL:
2234 return cancel_control_transfer(itransfer);
2235 case LIBUSB_TRANSFER_TYPE_BULK:
2236 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2237 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2238 return darwin_abort_transfers (itransfer);
2240 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2241 return LIBUSB_ERROR_INVALID_PARAM;
2245 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2246 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2247 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2248 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2250 usbi_dbg (TRANSFER_CTX(transfer), "an async io operation has completed");
2252 /* if requested write a zero packet */
2253 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2254 struct darwin_interface *cInterface;
2257 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2259 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2262 tpriv->result = result;
2263 tpriv->size = (UInt32) (uintptr_t) arg0;
2265 /* signal the core that this transfer is complete */
2266 usbi_signal_transfer_completion(itransfer);
2269 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2270 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2271 result = kIOUSBTransactionTimeout;
2273 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2276 case kIOReturnUnderrun:
2277 case kIOReturnSuccess:
2278 return LIBUSB_TRANSFER_COMPLETED;
2279 case kIOReturnAborted:
2280 return LIBUSB_TRANSFER_CANCELLED;
2281 case kIOUSBPipeStalled:
2282 usbi_dbg (ctx, "transfer error: pipe is stalled");
2283 return LIBUSB_TRANSFER_STALL;
2284 case kIOReturnOverrun:
2285 usbi_warn (ctx, "transfer error: data overrun");
2286 return LIBUSB_TRANSFER_OVERFLOW;
2287 case kIOUSBTransactionTimeout:
2288 usbi_warn (ctx, "transfer error: timed out");
2289 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2290 return LIBUSB_TRANSFER_TIMED_OUT;
2292 usbi_warn (ctx, "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2293 return LIBUSB_TRANSFER_ERROR;
2297 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2298 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2299 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2300 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2301 const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2302 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2303 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2305 if (transfer->type > max_transfer_type) {
2306 usbi_err (ctx, "unknown endpoint type %d", transfer->type);
2307 return LIBUSB_ERROR_INVALID_PARAM;
2310 if (NULL == tpriv) {
2311 usbi_err (ctx, "malformed request is missing transfer priv");
2312 return LIBUSB_ERROR_INVALID_PARAM;
2315 usbi_dbg (ctx, "handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2317 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
2318 if (is_isoc && tpriv->isoc_framelist) {
2319 /* copy isochronous results back */
2321 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2322 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2323 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2324 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2326 } else if (!is_isoc) {
2327 itransfer->transferred += tpriv->size;
2331 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2332 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2335 #if !defined(HAVE_CLOCK_GETTIME)
2336 void usbi_get_monotonic_time(struct timespec *tp) {
2337 mach_timespec_t sys_time;
2339 /* use system boot time as reference for the monotonic clock */
2340 clock_get_time (clock_monotonic, &sys_time);
2342 tp->tv_sec = sys_time.tv_sec;
2343 tp->tv_nsec = sys_time.tv_nsec;
2346 void usbi_get_real_time(struct timespec *tp) {
2347 mach_timespec_t sys_time;
2349 /* CLOCK_REALTIME represents time since the epoch */
2350 clock_get_time (clock_realtime, &sys_time);
2352 tp->tv_sec = sys_time.tv_sec;
2353 tp->tv_nsec = sys_time.tv_nsec;
2357 #if InterfaceVersion >= 550
2358 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2359 int num_endpoints) {
2360 struct darwin_interface *cInterface;
2361 UInt32 supportsStreams;
2365 /* find the minimum number of supported streams on the endpoint list */
2366 for (i = 0 ; i < num_endpoints ; ++i) {
2367 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2371 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2372 if (num_streams > supportsStreams)
2373 num_streams = supportsStreams;
2376 /* it is an error if any endpoint in endpoints does not support streams */
2377 if (0 == num_streams)
2378 return LIBUSB_ERROR_INVALID_PARAM;
2380 /* create the streams */
2381 for (i = 0 ; i < num_endpoints ; ++i) {
2382 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2384 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2385 if (kIOReturnSuccess != rc)
2386 return darwin_to_libusb(rc);
2389 assert(num_streams <= INT_MAX);
2390 return (int)num_streams;
2393 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2394 struct darwin_interface *cInterface;
2395 UInt32 supportsStreams;
2399 for (int i = 0 ; i < num_endpoints ; ++i) {
2400 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2403 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2404 if (0 == supportsStreams)
2405 return LIBUSB_ERROR_INVALID_PARAM;
2407 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2408 if (kIOReturnSuccess != rc)
2409 return darwin_to_libusb(rc);
2412 return LIBUSB_SUCCESS;
2416 #if InterfaceVersion >= 700
2418 /* macOS APIs for getting entitlement values */
2421 #include <Security/Security.h>
2423 typedef struct __SecTask *SecTaskRef;
2424 extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator);
2425 extern CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error);
2428 static bool darwin_has_capture_entitlements (void) {
2433 task = SecTaskCreateFromSelf (kCFAllocatorDefault);
2437 value = SecTaskCopyValueForEntitlement(task, CFSTR("com.apple.vm.device-access"), NULL);
2439 entitled = value && (CFGetTypeID (value) == CFBooleanGetTypeID ()) && CFBooleanGetValue (value);
2446 static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
2447 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2448 enum libusb_error err;
2450 usbi_mutex_lock(&darwin_cached_devices_lock);
2451 (*(dpriv->device))->Release(dpriv->device);
2452 dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
2453 if (!dpriv->device) {
2454 err = LIBUSB_ERROR_NO_DEVICE;
2456 err = LIBUSB_SUCCESS;
2458 usbi_mutex_unlock(&darwin_cached_devices_lock);
2463 /* On macOS, we capture an entire device at once, not individual interfaces. */
2465 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2467 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2469 enum libusb_error err;
2470 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
2472 if (HAS_CAPTURE_DEVICE()) {
2474 return LIBUSB_ERROR_NOT_SUPPORTED;
2477 if (dpriv->capture_count == 0) {
2478 usbi_dbg (ctx, "attempting to detach kernel driver from device");
2480 if (darwin_has_capture_entitlements ()) {
2481 /* request authorization */
2482 kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
2483 if (kresult != kIOReturnSuccess) {
2484 usbi_warn (ctx, "IOServiceAuthorize: %s", darwin_error_str(kresult));
2485 return darwin_to_libusb (kresult);
2488 /* we need start() to be called again for authorization status to refresh */
2489 err = darwin_reload_device (dev_handle);
2490 if (err != LIBUSB_SUCCESS) {
2494 usbi_info (ctx, "no capture entitlements. may not be able to detach the kernel driver for this device");
2495 if (0 != geteuid()) {
2496 usbi_warn (ctx, "USB device capture requires either an entitlement (com.apple.vm.device-access) or root privilege");
2497 return LIBUSB_ERROR_ACCESS;
2501 /* reset device to release existing drivers */
2502 err = darwin_reenumerate_device (dev_handle, true);
2503 if (err != LIBUSB_SUCCESS) {
2507 dpriv->capture_count++;
2508 return LIBUSB_SUCCESS;
2512 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2514 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2516 if (HAS_CAPTURE_DEVICE()) {
2518 return LIBUSB_ERROR_NOT_SUPPORTED;
2521 dpriv->capture_count--;
2522 if (dpriv->capture_count > 0) {
2523 return LIBUSB_SUCCESS;
2526 usbi_dbg (HANDLE_CTX (dev_handle), "reenumerating device for kernel driver attach");
2528 /* reset device to attach kernel drivers */
2529 return darwin_reenumerate_device (dev_handle, false);
2532 static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2533 enum libusb_error ret;
2534 if (dev_handle->auto_detach_kernel_driver && darwin_kernel_driver_active(dev_handle, iface)) {
2535 ret = darwin_detach_kernel_driver (dev_handle, iface);
2536 if (ret != LIBUSB_SUCCESS) {
2537 usbi_info (HANDLE_CTX (dev_handle), "failed to auto-detach the kernel driver for this device, ret=%d", ret);
2541 return darwin_claim_interface (dev_handle, iface);
2544 static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2545 enum libusb_error ret;
2546 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2548 ret = darwin_release_interface (dev_handle, iface);
2549 if (ret != LIBUSB_SUCCESS) {
2553 if (dev_handle->auto_detach_kernel_driver && dpriv->capture_count > 0) {
2554 ret = darwin_attach_kernel_driver (dev_handle, iface);
2555 if (LIBUSB_SUCCESS != ret) {
2556 usbi_info (HANDLE_CTX (dev_handle), "on attempt to reattach the kernel driver got ret=%d", ret);
2558 /* ignore the error as the interface was successfully released */
2561 return LIBUSB_SUCCESS;
2566 const struct usbi_os_backend usbi_backend = {
2568 .caps = USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
2569 .init = darwin_init,
2570 .exit = darwin_exit,
2571 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2572 .get_config_descriptor = darwin_get_config_descriptor,
2573 .hotplug_poll = darwin_hotplug_poll,
2575 .open = darwin_open,
2576 .close = darwin_close,
2577 .get_configuration = darwin_get_configuration,
2578 .set_configuration = darwin_set_configuration,
2580 .set_interface_altsetting = darwin_set_interface_altsetting,
2581 .clear_halt = darwin_clear_halt,
2582 .reset_device = darwin_reset_device,
2584 #if InterfaceVersion >= 550
2585 .alloc_streams = darwin_alloc_streams,
2586 .free_streams = darwin_free_streams,
2589 .kernel_driver_active = darwin_kernel_driver_active,
2591 #if InterfaceVersion >= 700
2592 .detach_kernel_driver = darwin_detach_kernel_driver,
2593 .attach_kernel_driver = darwin_attach_kernel_driver,
2594 .claim_interface = darwin_capture_claim_interface,
2595 .release_interface = darwin_capture_release_interface,
2597 .claim_interface = darwin_claim_interface,
2598 .release_interface = darwin_release_interface,
2601 .destroy_device = darwin_destroy_device,
2603 .submit_transfer = darwin_submit_transfer,
2604 .cancel_transfer = darwin_cancel_transfer,
2606 .handle_transfer_completion = darwin_handle_transfer_completion,
2608 .device_priv_size = sizeof(struct darwin_device_priv),
2609 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2610 .transfer_priv_size = sizeof(struct darwin_transfer_priv),