1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
3 * darwin backend for libusb 1.0
4 * Copyright © 2008-2020 Nathan Hjelm <hjelmn@cs.unm.edu>
5 * Copyright © 2019-2020 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 /* async event thread */
58 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
59 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
61 #if !defined(HAVE_CLOCK_GETTIME)
62 static clock_serv_t clock_realtime;
63 static clock_serv_t clock_monotonic;
66 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
68 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
69 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
71 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
72 static struct list_head darwin_cached_devices;
73 static const char *darwin_device_class = "IOUSBDevice";
75 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
77 /* async event thread */
78 static pthread_t libusb_darwin_at;
80 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
81 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
82 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
83 static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bool capture);
84 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
85 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
87 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
88 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
89 UInt64 old_session_id);
91 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
92 UInt64 *old_session_id);
94 #if defined(ENABLE_LOGGING)
95 static const char *darwin_error_str (IOReturn result) {
96 static char string_buffer[50];
98 case kIOReturnSuccess:
100 case kIOReturnNotOpen:
101 return "device not opened for exclusive access";
102 case kIOReturnNoDevice:
103 return "no connection to an IOService";
104 case kIOUSBNoAsyncPortErr:
105 return "no async port has been opened for interface";
106 case kIOReturnExclusiveAccess:
107 return "another process has device opened for exclusive access";
108 case kIOUSBPipeStalled:
109 return "pipe is stalled";
111 return "could not establish a connection to the Darwin kernel";
112 case kIOUSBTransactionTimeout:
113 return "transaction timed out";
114 case kIOReturnBadArgument:
115 return "invalid argument";
116 case kIOReturnAborted:
117 return "transaction aborted";
118 case kIOReturnNotResponding:
119 return "device not responding";
120 case kIOReturnOverrun:
121 return "data overrun";
122 case kIOReturnCannotWire:
123 return "physical memory can not be wired down";
124 case kIOReturnNoResources:
125 return "out of resources";
126 case kIOUSBHighSpeedSplitError:
127 return "high speed split error";
128 case kIOUSBUnknownPipeErr:
129 return "pipe ref not recognized";
131 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
132 return string_buffer;
137 static enum libusb_error darwin_to_libusb (IOReturn result) {
139 case kIOReturnUnderrun:
140 case kIOReturnSuccess:
141 return LIBUSB_SUCCESS;
142 case kIOReturnNotOpen:
143 case kIOReturnNoDevice:
144 return LIBUSB_ERROR_NO_DEVICE;
145 case kIOReturnExclusiveAccess:
146 return LIBUSB_ERROR_ACCESS;
147 case kIOUSBPipeStalled:
148 return LIBUSB_ERROR_PIPE;
149 case kIOReturnBadArgument:
150 return LIBUSB_ERROR_INVALID_PARAM;
151 case kIOUSBTransactionTimeout:
152 return LIBUSB_ERROR_TIMEOUT;
153 case kIOReturnNotResponding:
154 case kIOReturnAborted:
156 case kIOUSBNoAsyncPortErr:
157 case kIOUSBUnknownPipeErr:
159 return LIBUSB_ERROR_OTHER;
163 /* this function must be called with the darwin_cached_devices_lock held */
164 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
165 cached_dev->refcount--;
166 /* free the device and remove it from the cache */
167 if (0 == cached_dev->refcount) {
168 list_del(&cached_dev->list);
170 if (cached_dev->device) {
171 (*(cached_dev->device))->Release(cached_dev->device);
172 cached_dev->device = NULL;
174 IOObjectRelease (cached_dev->service);
179 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
180 cached_dev->refcount++;
183 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) {
184 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
186 /* current interface */
187 struct darwin_interface *cInterface;
191 usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
193 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
194 cInterface = &priv->interfaces[iface];
196 if (dev_handle->claimed_interfaces & (1U << iface)) {
197 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
198 if (cInterface->endpoint_addrs[i] == ep) {
205 *interface_out = cInterface;
207 usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
208 return LIBUSB_SUCCESS;
214 /* No pipe found with the correct endpoint address */
215 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
217 return LIBUSB_ERROR_NOT_FOUND;
220 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
221 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
224 return kIOReturnError;
227 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
228 &kCFTypeDictionaryKeyCallBacks,
229 &kCFTypeDictionaryValueCallBacks);
231 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
232 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
233 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
235 if (propertyMatchDict && locationCF) {
236 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
237 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
239 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
241 /* release our references as per the Create Rule */
242 if (propertyMatchDict)
243 CFRelease (propertyMatchDict);
245 CFRelease (locationCF);
248 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
251 /* Returns 1 on success, 0 on failure. */
252 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
253 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
257 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
258 success = CFNumberGetValue(cfNumber, type, p);
261 CFRelease (cfNumber);
264 return (success != 0);
267 /* Returns 1 on success, 0 on failure. */
268 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
269 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
270 bool success = false;
273 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
274 CFIndex length = CFDataGetLength (cfData);
279 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
289 static usb_device_t **darwin_device_from_service (io_service_t service)
291 io_cf_plugin_ref_t *plugInInterface = NULL;
292 usb_device_t **device;
295 const int max_retries = 5;
297 /* The IOCreatePlugInInterfaceForService function might consistently return
298 an "out of resources" error with certain USB devices the first time we run
299 it. The reason is still unclear, but retrying fixes the problem */
300 for (int count = 0; count < max_retries; count++) {
301 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
302 kIOCFPlugInInterfaceID, &plugInInterface,
304 if (kIOReturnSuccess == kresult && plugInInterface) {
308 usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
310 /* sleep for a little while before trying again */
311 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
314 if (kIOReturnSuccess != kresult || !plugInInterface) {
315 usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
319 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
321 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
322 (*plugInInterface)->Release (plugInInterface);
327 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
329 struct darwin_cached_device *cached_device;
330 UInt64 old_session_id;
331 struct libusb_context *ctx;
332 io_service_t service;
335 usbi_mutex_lock(&active_contexts_lock);
337 while ((service = IOIteratorNext(add_devices))) {
338 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
339 if (ret < 0 || !cached_device->can_enumerate) {
343 /* add this device to each active context's device list */
344 for_each_context(ctx) {
345 process_new_device (ctx, cached_device, old_session_id);
348 if (cached_device->in_reenumerate) {
349 usbi_dbg ("cached device in reset state. reset complete...");
350 cached_device->in_reenumerate = false;
353 IOObjectRelease(service);
356 usbi_mutex_unlock(&active_contexts_lock);
359 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
361 struct libusb_device *dev = NULL;
362 struct libusb_context *ctx;
363 struct darwin_cached_device *old_device;
369 usbi_mutex_lock(&active_contexts_lock);
371 while ((device = IOIteratorNext (rem_devices)) != 0) {
372 bool is_reenumerating = false;
374 /* get the location from the i/o registry */
375 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
376 IOObjectRelease (device);
380 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
381 otherwise no cached device will ever get freed */
382 usbi_mutex_lock(&darwin_cached_devices_lock);
383 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
384 if (old_device->session == session) {
385 if (old_device->in_reenumerate) {
386 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
387 * will deref if needed. */
388 usbi_dbg ("detected device detached due to re-enumeration");
390 /* the device object is no longer usable so go ahead and release it */
391 if (old_device->device) {
392 (*(old_device->device))->Release(old_device->device);
393 old_device->device = NULL;
396 is_reenumerating = true;
398 darwin_deref_cached_device (old_device);
405 usbi_mutex_unlock(&darwin_cached_devices_lock);
406 if (is_reenumerating) {
410 for_each_context(ctx) {
411 usbi_dbg ("notifying context %p of device disconnect", ctx);
413 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
415 /* signal the core that this device has been disconnected. the core will tear down this device
416 when the reference count reaches 0 */
417 usbi_disconnect_device(dev);
418 libusb_unref_device(dev);
423 usbi_mutex_unlock(&active_contexts_lock);
426 static void darwin_hotplug_poll (void)
428 /* not sure if 1 ms will be too long/short but it should work ok */
429 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
431 /* since a kernel thread may notify the IOIterators used for
432 * hotplug notification we can't just clear the iterators.
433 * instead just wait until all IOService providers are quiet */
434 (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
437 static void darwin_clear_iterator (io_iterator_t iter) {
440 while ((device = IOIteratorNext (iter)) != 0)
441 IOObjectRelease (device);
444 static void darwin_fail_startup(void) {
445 pthread_mutex_lock (&libusb_darwin_at_mutex);
446 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
447 pthread_cond_signal (&libusb_darwin_at_cond);
448 pthread_mutex_unlock (&libusb_darwin_at_mutex);
452 static void *darwin_event_thread_main (void *arg0) {
454 struct libusb_context *ctx = (struct libusb_context *)arg0;
455 CFRunLoopRef runloop;
456 CFRunLoopSourceRef libusb_shutdown_cfsource;
457 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
459 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
460 /* Set this thread's name, so it can be seen in the debugger
461 and crash reports. */
462 pthread_setname_np ("org.libusb.device-hotplug");
465 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
466 /* Tell the Objective-C garbage collector about this thread.
467 This is required because, unlike NSThreads, pthreads are
468 not automatically registered. Although we don't use
469 Objective-C, we use CoreFoundation, which does.
470 Garbage collection support was entirely removed in 10.12,
471 so don't bother there. */
472 objc_registerThreadWithCollector();
475 /* hotplug (device arrival/removal) sources */
476 CFRunLoopSourceRef libusb_notification_cfsource;
477 io_notification_port_t libusb_notification_port;
478 io_iterator_t libusb_rem_device_iterator;
479 io_iterator_t libusb_add_device_iterator;
481 usbi_dbg ("creating hotplug event source");
483 runloop = CFRunLoopGetCurrent ();
486 /* add the shutdown cfsource to the run loop */
487 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
488 libusb_shutdown_cfsourcectx.info = runloop;
489 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
490 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
491 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
493 /* add the notification port to the run loop */
494 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
495 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
496 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
498 /* create notifications for removed devices */
499 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
500 IOServiceMatching(darwin_device_class),
501 darwin_devices_detached,
502 ctx, &libusb_rem_device_iterator);
504 if (kresult != kIOReturnSuccess) {
505 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
506 CFRelease (libusb_shutdown_cfsource);
508 darwin_fail_startup ();
511 /* create notifications for attached devices */
512 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
513 IOServiceMatching(darwin_device_class),
514 darwin_devices_attached,
515 ctx, &libusb_add_device_iterator);
517 if (kresult != kIOReturnSuccess) {
518 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
519 CFRelease (libusb_shutdown_cfsource);
521 darwin_fail_startup ();
525 darwin_clear_iterator (libusb_rem_device_iterator);
526 darwin_clear_iterator (libusb_add_device_iterator);
528 usbi_dbg ("darwin event thread ready to receive events");
530 /* signal the main thread that the hotplug runloop has been created. */
531 pthread_mutex_lock (&libusb_darwin_at_mutex);
532 libusb_darwin_acfl = runloop;
533 libusb_darwin_acfls = libusb_shutdown_cfsource;
534 pthread_cond_signal (&libusb_darwin_at_cond);
535 pthread_mutex_unlock (&libusb_darwin_at_mutex);
537 /* run the runloop */
540 usbi_dbg ("darwin event thread exiting");
542 /* signal the main thread that the hotplug runloop has finished. */
543 pthread_mutex_lock (&libusb_darwin_at_mutex);
544 libusb_darwin_acfls = NULL;
545 libusb_darwin_acfl = NULL;
546 pthread_cond_signal (&libusb_darwin_at_cond);
547 pthread_mutex_unlock (&libusb_darwin_at_mutex);
549 /* remove the notification cfsource */
550 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
552 /* remove the shutdown cfsource */
553 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
555 /* delete notification port */
556 IONotificationPortDestroy (libusb_notification_port);
558 /* delete iterators */
559 IOObjectRelease (libusb_rem_device_iterator);
560 IOObjectRelease (libusb_add_device_iterator);
562 CFRelease (libusb_shutdown_cfsource);
568 /* cleanup function to destroy cached devices */
569 static void darwin_cleanup_devices(void) {
570 struct darwin_cached_device *dev, *next;
572 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
573 darwin_deref_cached_device(dev);
577 static int darwin_init(struct libusb_context *ctx) {
581 first_init = (1 == ++init_count);
585 if (NULL == darwin_cached_devices.next) {
586 list_init (&darwin_cached_devices);
588 assert(list_empty(&darwin_cached_devices));
589 #if !defined(HAVE_CLOCK_GETTIME)
590 /* create the clocks that will be used if clock_gettime() is not available */
591 host_name_port_t host_self;
593 host_self = mach_host_self();
594 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
595 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
596 mach_port_deallocate(mach_task_self(), host_self);
600 rc = darwin_scan_devices (ctx);
601 if (LIBUSB_SUCCESS != rc)
605 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
607 usbi_err (ctx, "could not create event thread, error %d", rc);
608 rc = LIBUSB_ERROR_OTHER;
612 pthread_mutex_lock (&libusb_darwin_at_mutex);
613 while (!libusb_darwin_acfl)
614 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
615 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
616 libusb_darwin_acfl = NULL;
617 rc = LIBUSB_ERROR_OTHER;
619 pthread_mutex_unlock (&libusb_darwin_at_mutex);
622 pthread_join (libusb_darwin_at, NULL);
626 if (LIBUSB_SUCCESS != rc) {
628 darwin_cleanup_devices ();
629 #if !defined(HAVE_CLOCK_GETTIME)
630 mach_port_deallocate(mach_task_self(), clock_realtime);
631 mach_port_deallocate(mach_task_self(), clock_monotonic);
640 static void darwin_exit (struct libusb_context *ctx) {
643 if (0 == --init_count) {
644 /* stop the event runloop and wait for the thread to terminate. */
645 pthread_mutex_lock (&libusb_darwin_at_mutex);
646 CFRunLoopSourceSignal (libusb_darwin_acfls);
647 CFRunLoopWakeUp (libusb_darwin_acfl);
648 while (libusb_darwin_acfl)
649 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
650 pthread_mutex_unlock (&libusb_darwin_at_mutex);
651 pthread_join (libusb_darwin_at, NULL);
653 darwin_cleanup_devices ();
655 #if !defined(HAVE_CLOCK_GETTIME)
656 mach_port_deallocate(mach_task_self(), clock_realtime);
657 mach_port_deallocate(mach_task_self(), clock_monotonic);
662 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
663 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
665 IOUSBConfigurationDescriptorPtr desc;
668 /* is there a simpler way to determine the index? */
669 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
670 if (kresult != kIOReturnSuccess)
671 return darwin_to_libusb (kresult);
673 for (i = 0 ; i < numConfig ; i++) {
674 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
676 if (desc->bConfigurationValue == config_value)
680 /* configuration not found */
681 return LIBUSB_ERROR_NOT_FOUND;
684 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
685 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
688 if (0 == priv->active_config)
689 return LIBUSB_ERROR_NOT_FOUND;
691 config_index = get_configuration_index (dev, priv->active_config);
692 if (config_index < 0)
695 assert(config_index >= 0 && config_index <= UINT8_MAX);
696 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
699 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
700 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
701 IOUSBConfigurationDescriptorPtr desc;
705 if (!priv || !priv->device)
706 return LIBUSB_ERROR_OTHER;
708 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
709 if (kresult == kIOReturnSuccess) {
710 /* copy descriptor */
711 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
712 len = libusb_le16_to_cpu(desc->wTotalLength);
714 memmove (buffer, desc, len);
717 ret = darwin_to_libusb (kresult);
718 if (ret != LIBUSB_SUCCESS)
724 /* check whether the os has configured the device */
725 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
726 usb_device_t **darwin_device = dev->device;
728 IOUSBConfigurationDescriptorPtr configDesc;
729 IOUSBFindInterfaceRequest request;
731 io_iterator_t interface_iterator;
732 io_service_t firstInterface;
734 if (dev->dev_descriptor.bNumConfigurations < 1) {
735 usbi_err (ctx, "device has no configurations");
736 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
739 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
741 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
742 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
743 usbi_dbg ("ignoring configuration on root hub simulation");
744 dev->active_config = 0;
745 return LIBUSB_SUCCESS;
748 /* find the first configuration */
749 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
750 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
752 /* check if the device is already configured. there is probably a better way than iterating over the
753 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
754 might lock up on the device request) */
756 /* Setup the Interface Request */
757 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
758 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
759 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
760 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
762 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
763 if (kresult != kIOReturnSuccess)
764 return darwin_to_libusb (kresult);
767 firstInterface = IOIteratorNext(interface_iterator);
769 /* done with the interface iterator */
770 IOObjectRelease(interface_iterator);
772 if (firstInterface) {
773 IOObjectRelease (firstInterface);
775 /* device is configured */
776 if (dev->dev_descriptor.bNumConfigurations == 1)
777 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
778 dev->active_config = dev->first_config;
780 /* devices with more than one configuration should work with GetConfiguration */
781 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
784 dev->active_config = 0;
786 usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
788 return LIBUSB_SUCCESS;
791 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
792 IOUSBDevRequestTO req;
794 assert(buffer_size <= UINT16_MAX);
796 memset (buffer, 0, buffer_size);
798 /* Set up request for descriptor/ */
799 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
800 req.bRequest = kUSBRqGetDescriptor;
801 req.wValue = (UInt16)(desc << 8);
802 req.wIndex = desc_index;
803 req.wLength = (UInt16)buffer_size;
805 req.noDataTimeout = 20;
806 req.completionTimeout = 100;
808 return (*device)->DeviceRequestTO (device, &req);
811 static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
812 usb_device_t **device = dev->device;
814 long delay = 30000; // microseconds
815 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
817 IOReturn ret = 0, ret2;
819 UInt16 idProduct, idVendor;
821 dev->can_enumerate = 0;
823 (*device)->GetDeviceClass (device, &bDeviceClass);
824 (*device)->GetDeviceProduct (device, &idProduct);
825 (*device)->GetDeviceVendor (device, &idVendor);
827 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
828 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
829 * to follow the spec as closely as possible, try opening the device */
830 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
833 /**** retrieve device descriptor ****/
834 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
836 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
837 /* received an overrun error but we still received a device descriptor */
838 ret = kIOReturnSuccess;
840 if (kIOUSBVendorIDAppleComputer == idVendor) {
841 /* NTH: don't bother retrying or unsuspending Apple devices */
845 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
846 0 == dev->dev_descriptor.bcdUSB)) {
847 /* work around for incorrectly configured devices */
848 if (try_reconfigure && is_open) {
849 usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
851 /* set the first configuration */
852 (*device)->SetConfiguration(device, 1);
854 /* don't try to reconfigure again */
858 ret = kIOUSBPipeStalled;
861 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
862 /* device may be suspended. unsuspend it and try again */
863 #if DeviceVersion >= 320
866 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
867 (void)(*device)->GetUSBDeviceInformation (device, &info);
869 /* note that the device was suspended */
870 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
875 /* try to unsuspend the device */
876 ret2 = (*device)->USBDeviceSuspend (device, 0);
877 if (kIOReturnSuccess != ret2) {
878 /* prevent log spew from poorly behaving devices. this indicates the
879 os actually had trouble communicating with the device */
880 usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
888 if (kIOReturnSuccess != ret) {
889 usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
890 /* sleep for a little while before trying again */
891 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
893 } while (kIOReturnSuccess != ret && retries--);
896 /* resuspend the device */
897 (void)(*device)->USBDeviceSuspend (device, 1);
900 (void) (*device)->USBDeviceClose (device);
902 if (ret != kIOReturnSuccess) {
903 /* a debug message was already printed out for this error */
904 if (LIBUSB_CLASS_HUB == bDeviceClass)
905 usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
906 idVendor, idProduct, darwin_error_str (ret), ret);
908 usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
909 idVendor, idProduct, darwin_error_str (ret), ret);
910 return darwin_to_libusb (ret);
913 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
914 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
915 /* not a valid device */
916 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
917 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
918 return LIBUSB_ERROR_NO_DEVICE;
921 usbi_dbg ("cached device descriptor:");
922 usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
923 usbi_dbg (" bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
924 usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
925 usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
926 usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
927 usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
928 usbi_dbg (" idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
929 usbi_dbg (" idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
930 usbi_dbg (" bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
931 usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
932 usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct);
933 usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
934 usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
936 dev->can_enumerate = 1;
938 return LIBUSB_SUCCESS;
941 /* Returns 1 on success, 0 on failure. */
942 static bool get_device_port (io_service_t service, UInt8 *port) {
947 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
951 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
952 if (kIOReturnSuccess == kresult) {
953 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
954 IOObjectRelease (parent);
960 /* Returns 1 on success, 0 on failure. */
961 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
965 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
967 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
968 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
974 /* We ran out of parents */
978 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
979 UInt64 *old_session_id) {
980 struct darwin_cached_device *new_device;
981 UInt64 sessionID = 0, parent_sessionID = 0;
982 UInt32 locationID = 0;
983 enum libusb_error ret = LIBUSB_SUCCESS;
984 usb_device_t **device;
987 /* assuming sessionID != 0 normally (never seen it be 0) */
991 /* get some info from the io registry */
992 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
993 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
994 if (!get_device_port (service, &port)) {
995 usbi_dbg("could not get connected port number");
998 usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
1000 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1001 usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
1004 usbi_mutex_lock(&darwin_cached_devices_lock);
1006 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1007 usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1008 sessionID, locationID, new_device->session, new_device->location);
1009 if (new_device->location == locationID && new_device->in_reenumerate) {
1010 usbi_dbg ("found cached device with matching location that is being re-enumerated");
1011 *old_session_id = new_device->session;
1015 if (new_device->session == sessionID) {
1016 usbi_dbg("using cached device for device");
1017 *cached_out = new_device;
1025 usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
1027 device = darwin_device_from_service (service);
1029 ret = LIBUSB_ERROR_NO_DEVICE;
1033 if (!(*old_session_id)) {
1034 new_device = calloc (1, sizeof (*new_device));
1036 ret = LIBUSB_ERROR_NO_MEM;
1040 /* add this device to the cached device list */
1041 list_add(&new_device->list, &darwin_cached_devices);
1043 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1045 /* keep a reference to this device */
1046 darwin_ref_cached_device(new_device);
1048 (*device)->GetLocationID (device, &new_device->location);
1049 new_device->port = port;
1050 new_device->parent_session = parent_sessionID;
1052 /* release the ref to old device's service */
1053 IOObjectRelease (new_device->service);
1056 /* keep track of devices regardless of if we successfully enumerate them to
1057 prevent them from being enumerated multiple times */
1058 *cached_out = new_device;
1060 new_device->session = sessionID;
1061 new_device->device = device;
1062 new_device->service = service;
1064 /* retain the service */
1065 IOObjectRetain (service);
1067 /* cache the device descriptor */
1068 ret = darwin_cache_device_descriptor(new_device);
1072 if (new_device->can_enumerate) {
1073 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1074 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1075 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1076 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1080 usbi_mutex_unlock(&darwin_cached_devices_lock);
1085 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1086 UInt64 old_session_id) {
1087 struct darwin_device_priv *priv;
1088 struct libusb_device *dev = NULL;
1090 enum libusb_error ret = LIBUSB_SUCCESS;
1093 /* check current active configuration (and cache the first configuration value--
1094 which may be used by claim_interface) */
1095 ret = darwin_check_configuration (ctx, cached_device);
1099 if (0 != old_session_id) {
1100 usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1101 ctx, old_session_id, cached_device->session);
1102 /* save the libusb device before the session id is updated */
1103 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1107 usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
1108 ctx, cached_device->session);
1110 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1112 return LIBUSB_ERROR_NO_MEM;
1115 priv = usbi_get_device_priv(dev);
1117 priv->dev = cached_device;
1118 darwin_ref_cached_device (priv->dev);
1119 dev->port_number = cached_device->port;
1120 dev->bus_number = cached_device->location >> 24;
1121 assert(cached_device->address <= UINT8_MAX);
1122 dev->device_address = (uint8_t)cached_device->address;
1124 priv = usbi_get_device_priv(dev);
1127 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1128 "mismatch between libusb and IOKit device descriptor sizes");
1129 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1130 usbi_localize_device_descriptor(&dev->device_descriptor);
1131 dev->session_data = cached_device->session;
1133 if (cached_device->parent_session > 0) {
1134 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1136 dev->parent_dev = NULL;
1139 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1142 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1143 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1144 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1145 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
1146 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1148 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1149 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1152 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1155 ret = usbi_sanitize_device (dev);
1159 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1160 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1164 if (!cached_device->in_reenumerate && 0 == ret) {
1165 usbi_connect_device (dev);
1167 libusb_unref_device (dev);
1173 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1174 struct darwin_cached_device *cached_device;
1175 UInt64 old_session_id;
1176 io_iterator_t deviceIterator;
1177 io_service_t service;
1181 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1182 if (kresult != kIOReturnSuccess)
1183 return darwin_to_libusb (kresult);
1185 while ((service = IOIteratorNext (deviceIterator))) {
1186 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1187 if (ret < 0 || !cached_device->can_enumerate) {
1191 (void) process_new_device (ctx, cached_device, old_session_id);
1193 IOObjectRelease(service);
1196 IOObjectRelease(deviceIterator);
1198 return LIBUSB_SUCCESS;
1201 static int darwin_open (struct libusb_device_handle *dev_handle) {
1202 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1203 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1206 if (0 == dpriv->open_count) {
1207 /* try to open the device */
1208 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1209 if (kresult != kIOReturnSuccess) {
1210 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1212 if (kIOReturnExclusiveAccess != kresult) {
1213 return darwin_to_libusb (kresult);
1216 /* it is possible to perform some actions on a device that is not open so do not return an error */
1217 priv->is_open = false;
1219 priv->is_open = true;
1222 /* create async event source */
1223 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1224 if (kresult != kIOReturnSuccess) {
1225 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1227 if (priv->is_open) {
1228 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1231 priv->is_open = false;
1233 return darwin_to_libusb (kresult);
1236 CFRetain (libusb_darwin_acfl);
1238 /* add the cfSource to the aync run loop */
1239 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1242 /* device opened successfully */
1243 dpriv->open_count++;
1245 usbi_dbg ("device open for access");
1250 static void darwin_close (struct libusb_device_handle *dev_handle) {
1251 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1252 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1256 if (dpriv->open_count == 0) {
1257 /* something is probably very wrong if this is the case */
1258 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1262 dpriv->open_count--;
1264 /* make sure all interfaces are released */
1265 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1266 if (dev_handle->claimed_interfaces & (1U << i))
1267 libusb_release_interface (dev_handle, i);
1269 if (0 == dpriv->open_count) {
1270 /* delete the device's async event source */
1271 if (priv->cfSource) {
1272 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1273 CFRelease (priv->cfSource);
1274 priv->cfSource = NULL;
1275 CFRelease (libusb_darwin_acfl);
1278 if (priv->is_open) {
1279 /* close the device */
1280 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1281 if (kresult != kIOReturnSuccess) {
1282 /* Log the fact that we had a problem closing the file, however failing a
1283 * close isn't really an error, so return success anyway */
1284 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1290 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1291 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1293 *config = dpriv->active_config;
1295 return LIBUSB_SUCCESS;
1298 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1299 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1306 /* Setting configuration will invalidate the interface, so we need
1307 to reclaim it. First, dispose of existing interfaces, if any. */
1308 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1309 if (dev_handle->claimed_interfaces & (1U << i))
1310 darwin_release_interface (dev_handle, i);
1312 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1313 if (kresult != kIOReturnSuccess)
1314 return darwin_to_libusb (kresult);
1316 /* Reclaim any interfaces. */
1317 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1318 if (dev_handle->claimed_interfaces & (1U << i))
1319 darwin_claim_interface (dev_handle, i);
1321 dpriv->active_config = (UInt8)config;
1323 return LIBUSB_SUCCESS;
1326 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1327 IOUSBFindInterfaceRequest request;
1329 io_iterator_t interface_iterator;
1330 UInt8 bInterfaceNumber;
1333 *usbInterfacep = IO_OBJECT_NULL;
1335 /* Setup the Interface Request */
1336 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1337 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1338 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1339 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1341 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1342 if (kresult != kIOReturnSuccess)
1345 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1346 /* find the interface number */
1347 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1350 if (ret && bInterfaceNumber == ifc) {
1354 (void) IOObjectRelease (*usbInterfacep);
1357 /* done with the interface iterator */
1358 IOObjectRelease(interface_iterator);
1360 return kIOReturnSuccess;
1363 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1364 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1366 /* current interface */
1367 struct darwin_interface *cInterface = &priv->interfaces[iface];
1371 UInt8 numep, direction, number;
1372 UInt8 dont_care1, dont_care3;
1376 usbi_dbg ("building table of endpoints.");
1378 /* retrieve the total number of endpoints on this interface */
1379 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1380 if (kresult != kIOReturnSuccess) {
1381 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1382 return darwin_to_libusb (kresult);
1385 /* iterate through pipe references */
1386 for (UInt8 i = 1 ; i <= numep ; i++) {
1387 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1388 &dont_care2, &dont_care3);
1390 if (kresult != kIOReturnSuccess) {
1391 /* probably a buggy device. try to get the endpoint address from the descriptors */
1392 struct libusb_config_descriptor *config;
1393 const struct libusb_endpoint_descriptor *endpoint_desc;
1396 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1397 if (kresult != kIOReturnSuccess) {
1398 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1399 return darwin_to_libusb (kresult);
1402 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1403 if (LIBUSB_SUCCESS != rc) {
1407 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1409 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1411 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1414 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1415 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1418 cInterface->num_endpoints = numep;
1420 return LIBUSB_SUCCESS;
1423 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1424 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1425 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1426 io_service_t usbInterface = IO_OBJECT_NULL;
1428 enum libusb_error ret;
1429 IOCFPlugInInterface **plugInInterface = NULL;
1432 /* current interface */
1433 struct darwin_interface *cInterface = &priv->interfaces[iface];
1435 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1436 if (kresult != kIOReturnSuccess)
1437 return darwin_to_libusb (kresult);
1439 /* make sure we have an interface */
1440 if (!usbInterface && dpriv->first_config != 0) {
1441 usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1443 /* set the configuration */
1444 ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1445 if (ret != LIBUSB_SUCCESS) {
1446 usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1450 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1451 if (kresult != kIOReturnSuccess) {
1452 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1453 return darwin_to_libusb (kresult);
1457 if (!usbInterface) {
1458 usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1459 return LIBUSB_ERROR_NOT_FOUND;
1462 /* get an interface to the device's interface */
1463 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1464 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1466 /* ignore release error */
1467 (void)IOObjectRelease (usbInterface);
1469 if (kresult != kIOReturnSuccess) {
1470 usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1471 return darwin_to_libusb (kresult);
1474 if (!plugInInterface) {
1475 usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1476 return LIBUSB_ERROR_NOT_FOUND;
1479 /* Do the actual claim */
1480 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1481 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1482 (LPVOID)&cInterface->interface);
1483 /* We no longer need the intermediate plug-in */
1484 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1485 (*plugInInterface)->Release (plugInInterface);
1486 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1487 usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1488 return darwin_to_libusb (kresult);
1491 /* claim the interface */
1492 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1493 if (kresult != kIOReturnSuccess) {
1494 usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1495 return darwin_to_libusb (kresult);
1498 /* update list of endpoints */
1499 ret = get_endpoints (dev_handle, iface);
1501 /* this should not happen */
1502 darwin_release_interface (dev_handle, iface);
1503 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1507 cInterface->cfSource = NULL;
1509 /* create async event source */
1510 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1511 if (kresult != kIOReturnSuccess) {
1512 usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1514 /* can't continue without an async event source */
1515 (void)darwin_release_interface (dev_handle, iface);
1517 return darwin_to_libusb (kresult);
1520 /* add the cfSource to the async thread's run loop */
1521 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1523 usbi_dbg ("interface opened");
1525 return LIBUSB_SUCCESS;
1528 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1529 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1532 /* current interface */
1533 struct darwin_interface *cInterface = &priv->interfaces[iface];
1535 /* Check to see if an interface is open */
1536 if (!cInterface->interface)
1537 return LIBUSB_SUCCESS;
1539 /* clean up endpoint data */
1540 cInterface->num_endpoints = 0;
1542 /* delete the interface's async event source */
1543 if (cInterface->cfSource) {
1544 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1545 CFRelease (cInterface->cfSource);
1548 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1549 if (kresult != kIOReturnSuccess)
1550 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1552 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1553 if (kresult != kIOReturnSuccess)
1554 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1556 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1558 return darwin_to_libusb (kresult);
1561 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1562 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1564 enum libusb_error ret;
1566 /* current interface */
1567 struct darwin_interface *cInterface = &priv->interfaces[iface];
1569 if (!cInterface->interface)
1570 return LIBUSB_ERROR_NO_DEVICE;
1572 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1573 /* If a device only supports a default setting for the specified interface, then a STALL
1574 (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1575 Mimick the behaviour in e.g. the Linux kernel: in such case, reset all endpoints,
1576 and hide errors.Current implementation resets the entire device, instead of single
1577 interface, due to historic reasons. */
1578 if (kresult != kIOReturnSuccess) {
1579 usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1580 darwin_reset_device (dev_handle);
1583 /* update list of endpoints */
1584 ret = get_endpoints (dev_handle, iface);
1586 /* this should not happen */
1587 darwin_release_interface (dev_handle, iface);
1588 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1594 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1595 /* current interface */
1596 struct darwin_interface *cInterface;
1600 /* determine the interface/endpoint to use */
1601 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1602 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1604 return LIBUSB_ERROR_NOT_FOUND;
1607 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1608 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1609 if (kresult != kIOReturnSuccess)
1610 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1612 return darwin_to_libusb (kresult);
1615 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1616 unsigned long claimed_interfaces) {
1617 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1618 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1619 int open_count = dpriv->open_count;
1622 /* clear claimed interfaces temporarily */
1623 dev_handle->claimed_interfaces = 0;
1625 /* close and re-open the device */
1626 priv->is_open = false;
1627 dpriv->open_count = 1;
1629 /* clean up open interfaces */
1630 (void) darwin_close (dev_handle);
1632 /* re-open the device */
1633 ret = darwin_open (dev_handle);
1634 dpriv->open_count = open_count;
1635 if (LIBUSB_SUCCESS != ret) {
1636 /* could not restore configuration */
1637 return LIBUSB_ERROR_NOT_FOUND;
1640 if (dpriv->active_config != active_config) {
1641 usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1643 ret = darwin_set_configuration (dev_handle, active_config);
1644 if (LIBUSB_SUCCESS != ret) {
1645 usbi_dbg ("darwin/restore_state: could not restore configuration");
1646 return LIBUSB_ERROR_NOT_FOUND;
1650 usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1652 if (claimed_interfaces) {
1653 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1654 if (!(claimed_interfaces & (1U << iface))) {
1658 usbi_dbg ("darwin/restore_state: re-claiming interface %u", iface);
1660 ret = darwin_claim_interface (dev_handle, iface);
1661 if (LIBUSB_SUCCESS != ret) {
1662 usbi_dbg ("darwin/restore_state: could not claim interface %u", iface);
1663 return LIBUSB_ERROR_NOT_FOUND;
1666 dev_handle->claimed_interfaces |= 1U << iface;
1670 usbi_dbg ("darwin/restore_state: device state restored");
1672 return LIBUSB_SUCCESS;
1675 static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) {
1676 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1677 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1678 int8_t active_config = dpriv->active_config;
1680 IOUSBDeviceDescriptor descriptor;
1681 IOUSBConfigurationDescriptorPtr cached_configuration;
1682 IOUSBConfigurationDescriptor *cached_configurations;
1687 if (dpriv->in_reenumerate) {
1688 /* ack, two (or more) threads are trying to reset the device! abort! */
1689 return LIBUSB_ERROR_NOT_FOUND;
1692 dpriv->in_reenumerate = true;
1694 /* store copies of descriptors so they can be compared after the reset */
1695 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1696 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1698 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1699 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1700 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1703 /* if we need to release capture */
1704 if (HAS_CAPTURE_DEVICE()) {
1706 options |= kUSBReEnumerateCaptureDeviceMask;
1712 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1713 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
1714 if (kresult != kIOReturnSuccess) {
1715 usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1716 dpriv->in_reenumerate = false;
1717 return darwin_to_libusb (kresult);
1720 /* capture mode does not re-enumerate but it does require re-open */
1722 usbi_dbg ("darwin/reenumerate_device: restoring state...");
1723 dpriv->in_reenumerate = false;
1724 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1727 usbi_dbg ("darwin/reenumerate_device: waiting for re-enumeration to complete...");
1730 while (dpriv->in_reenumerate) {
1731 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1732 nanosleep (&delay, NULL);
1733 if (time++ >= DARWIN_REENUMERATE_TIMEOUT_US) {
1734 usbi_err (HANDLE_CTX (dev_handle), "darwin/reenumerate_device: timeout waiting for reenumerate");
1735 dpriv->in_reenumerate = false;
1736 return LIBUSB_ERROR_TIMEOUT;
1740 /* compare descriptors */
1741 usbi_dbg ("darwin/reenumerate_device: checking whether descriptors changed");
1743 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1744 /* device descriptor changed. need to return not found. */
1745 usbi_dbg ("darwin/reenumerate_device: device descriptor changed");
1746 return LIBUSB_ERROR_NOT_FOUND;
1749 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1750 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1751 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1752 usbi_dbg ("darwin/reenumerate_device: configuration descriptor %d changed", i);
1753 return LIBUSB_ERROR_NOT_FOUND;
1757 usbi_dbg ("darwin/reenumerate_device: device reset complete. restoring state...");
1759 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1762 static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
1763 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1766 if (dpriv->capture_count > 0) {
1767 /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
1768 kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
1769 return darwin_to_libusb (kresult);
1771 return darwin_reenumerate_device (dev_handle, false);
1775 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1776 enum libusb_error ret = darwin_claim_interface (dev_handle, interface);
1777 if (ret == LIBUSB_SUCCESS) {
1778 darwin_release_interface (dev_handle, interface);
1780 return (ret == LIBUSB_ERROR_ACCESS);
1783 static void darwin_destroy_device(struct libusb_device *dev) {
1784 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1787 /* need to hold the lock in case this is the last reference to the device */
1788 usbi_mutex_lock(&darwin_cached_devices_lock);
1789 darwin_deref_cached_device (dpriv->dev);
1791 usbi_mutex_unlock(&darwin_cached_devices_lock);
1795 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1796 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1799 uint8_t transferType;
1801 uint16_t maxPacketSize;
1803 struct darwin_interface *cInterface;
1804 #if InterfaceVersion >= 550
1805 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1807 /* None of the values below are used in libusb for bulk transfers */
1808 uint8_t direction, number, interval;
1811 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1812 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1814 return LIBUSB_ERROR_NOT_FOUND;
1817 #if InterfaceVersion >= 550
1818 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1820 transferType = pipeProperties.bTransferType;
1821 maxPacketSize = pipeProperties.wMaxPacketSize;
1823 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1824 &transferType, &maxPacketSize, &interval);
1828 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1829 darwin_error_str(ret), ret);
1830 return darwin_to_libusb (ret);
1833 if (0 != (transfer->length % maxPacketSize)) {
1834 /* do not need a zero packet */
1835 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1838 /* submit the request */
1839 /* timeouts are unavailable on interrupt endpoints */
1840 if (transferType == kUSBInterrupt) {
1841 if (IS_XFERIN(transfer))
1842 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1843 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1845 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1846 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1848 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1850 if (IS_XFERIN(transfer))
1851 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1852 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1853 darwin_async_io_callback, itransfer);
1855 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1856 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1857 darwin_async_io_callback, itransfer);
1861 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1862 darwin_error_str(ret), ret);
1864 return darwin_to_libusb (ret);
1867 #if InterfaceVersion >= 550
1868 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1869 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1870 struct darwin_interface *cInterface;
1874 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1875 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1877 return LIBUSB_ERROR_NOT_FOUND;
1880 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1882 if (IS_XFERIN(transfer))
1883 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1884 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1885 transfer->timeout, darwin_async_io_callback, itransfer);
1887 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1888 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1889 transfer->timeout, darwin_async_io_callback, itransfer);
1892 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1893 darwin_error_str(ret), ret);
1895 return darwin_to_libusb (ret);
1899 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1900 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1901 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1904 uint8_t direction, number, interval, pipeRef, transferType;
1905 uint16_t maxPacketSize;
1907 AbsoluteTime atTime;
1910 struct darwin_interface *cInterface;
1912 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1913 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1914 free(tpriv->isoc_framelist);
1915 tpriv->isoc_framelist = NULL;
1918 if (!tpriv->isoc_framelist) {
1919 tpriv->num_iso_packets = transfer->num_iso_packets;
1920 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1921 if (!tpriv->isoc_framelist)
1922 return LIBUSB_ERROR_NO_MEM;
1925 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1926 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1927 unsigned int length = transfer->iso_packet_desc[i].length;
1928 assert(length <= UINT16_MAX);
1929 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1932 /* determine the interface/endpoint to use */
1933 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1934 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1936 return LIBUSB_ERROR_NOT_FOUND;
1939 /* determine the properties of this endpoint and the speed of the device */
1940 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1941 &transferType, &maxPacketSize, &interval);
1943 /* Last but not least we need the bus frame number */
1944 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1945 if (kresult != kIOReturnSuccess) {
1946 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1947 free(tpriv->isoc_framelist);
1948 tpriv->isoc_framelist = NULL;
1950 return darwin_to_libusb (kresult);
1953 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1954 &transferType, &maxPacketSize, &interval);
1956 /* schedule for a frame a little in the future */
1959 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1960 frame = cInterface->frames[transfer->endpoint];
1962 /* submit the request */
1963 if (IS_XFERIN(transfer))
1964 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1965 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1968 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1969 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1972 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1974 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1976 /* High/super speed */
1977 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1979 if (kresult != kIOReturnSuccess) {
1980 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1981 darwin_error_str(kresult));
1982 free (tpriv->isoc_framelist);
1983 tpriv->isoc_framelist = NULL;
1986 return darwin_to_libusb (kresult);
1989 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1990 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1991 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1992 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1993 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1997 memset(&tpriv->req, 0, sizeof(tpriv->req));
1999 /* IOUSBDeviceInterface expects the request in cpu endianness */
2000 tpriv->req.bmRequestType = setup->bmRequestType;
2001 tpriv->req.bRequest = setup->bRequest;
2002 /* these values should be in bus order from libusb_fill_control_setup */
2003 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
2004 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
2005 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
2006 /* data is stored after the libusb control block */
2007 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
2008 tpriv->req.completionTimeout = transfer->timeout;
2009 tpriv->req.noDataTimeout = transfer->timeout;
2011 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2013 /* all transfers in libusb-1.0 are async */
2015 if (transfer->endpoint) {
2016 struct darwin_interface *cInterface;
2019 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2020 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2022 return LIBUSB_ERROR_NOT_FOUND;
2025 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2027 /* control request on endpoint 0 */
2028 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2030 if (kresult != kIOReturnSuccess)
2031 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2033 return darwin_to_libusb (kresult);
2036 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2037 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2039 switch (transfer->type) {
2040 case LIBUSB_TRANSFER_TYPE_CONTROL:
2041 return submit_control_transfer(itransfer);
2042 case LIBUSB_TRANSFER_TYPE_BULK:
2043 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2044 return submit_bulk_transfer(itransfer);
2045 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2046 return submit_iso_transfer(itransfer);
2047 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2048 #if InterfaceVersion >= 550
2049 return submit_stream_transfer(itransfer);
2051 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2052 return LIBUSB_ERROR_NOT_SUPPORTED;
2055 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2056 return LIBUSB_ERROR_INVALID_PARAM;
2060 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2061 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2062 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2065 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2068 return LIBUSB_ERROR_NO_DEVICE;
2070 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2072 return darwin_to_libusb (kresult);
2075 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2076 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2077 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2078 struct darwin_interface *cInterface;
2079 uint8_t pipeRef, iface;
2082 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2083 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2085 return LIBUSB_ERROR_NOT_FOUND;
2089 return LIBUSB_ERROR_NO_DEVICE;
2091 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2093 /* abort transactions */
2094 #if InterfaceVersion >= 550
2095 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2096 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2099 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2101 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2103 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2104 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2106 return darwin_to_libusb (kresult);
2109 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2110 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2112 switch (transfer->type) {
2113 case LIBUSB_TRANSFER_TYPE_CONTROL:
2114 return cancel_control_transfer(itransfer);
2115 case LIBUSB_TRANSFER_TYPE_BULK:
2116 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2117 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2118 return darwin_abort_transfers (itransfer);
2120 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2121 return LIBUSB_ERROR_INVALID_PARAM;
2125 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2126 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2127 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2128 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2130 usbi_dbg ("an async io operation has completed");
2132 /* if requested write a zero packet */
2133 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2134 struct darwin_interface *cInterface;
2137 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2139 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2142 tpriv->result = result;
2143 tpriv->size = (UInt32) (uintptr_t) arg0;
2145 /* signal the core that this transfer is complete */
2146 usbi_signal_transfer_completion(itransfer);
2149 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2150 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2151 result = kIOUSBTransactionTimeout;
2154 case kIOReturnUnderrun:
2155 case kIOReturnSuccess:
2156 return LIBUSB_TRANSFER_COMPLETED;
2157 case kIOReturnAborted:
2158 return LIBUSB_TRANSFER_CANCELLED;
2159 case kIOUSBPipeStalled:
2160 usbi_dbg ("transfer error: pipe is stalled");
2161 return LIBUSB_TRANSFER_STALL;
2162 case kIOReturnOverrun:
2163 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2164 return LIBUSB_TRANSFER_OVERFLOW;
2165 case kIOUSBTransactionTimeout:
2166 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2167 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2168 return LIBUSB_TRANSFER_TIMED_OUT;
2170 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2171 return LIBUSB_TRANSFER_ERROR;
2175 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2176 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2177 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2178 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2179 const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2180 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2182 if (transfer->type > max_transfer_type) {
2183 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2184 return LIBUSB_ERROR_INVALID_PARAM;
2187 if (NULL == tpriv) {
2188 usbi_err (TRANSFER_CTX(transfer), "malformed request is missing transfer priv");
2189 return LIBUSB_ERROR_INVALID_PARAM;
2192 usbi_dbg ("handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2194 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
2195 if (is_isoc && tpriv->isoc_framelist) {
2196 /* copy isochronous results back */
2198 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2199 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2200 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2201 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2203 } else if (!is_isoc) {
2204 itransfer->transferred += tpriv->size;
2208 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2209 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2212 #if !defined(HAVE_CLOCK_GETTIME)
2213 void usbi_get_monotonic_time(struct timespec *tp) {
2214 mach_timespec_t sys_time;
2216 /* use system boot time as reference for the monotonic clock */
2217 clock_get_time (clock_monotonic, &sys_time);
2219 tp->tv_sec = sys_time.tv_sec;
2220 tp->tv_nsec = sys_time.tv_nsec;
2223 void usbi_get_real_time(struct timespec *tp) {
2224 mach_timespec_t sys_time;
2226 /* CLOCK_REALTIME represents time since the epoch */
2227 clock_get_time (clock_realtime, &sys_time);
2229 tp->tv_sec = sys_time.tv_sec;
2230 tp->tv_nsec = sys_time.tv_nsec;
2234 #if InterfaceVersion >= 550
2235 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2236 int num_endpoints) {
2237 struct darwin_interface *cInterface;
2238 UInt32 supportsStreams;
2242 /* find the minimum number of supported streams on the endpoint list */
2243 for (i = 0 ; i < num_endpoints ; ++i) {
2244 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2248 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2249 if (num_streams > supportsStreams)
2250 num_streams = supportsStreams;
2253 /* it is an error if any endpoint in endpoints does not support streams */
2254 if (0 == num_streams)
2255 return LIBUSB_ERROR_INVALID_PARAM;
2257 /* create the streams */
2258 for (i = 0 ; i < num_endpoints ; ++i) {
2259 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2261 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2262 if (kIOReturnSuccess != rc)
2263 return darwin_to_libusb(rc);
2266 assert(num_streams <= INT_MAX);
2267 return (int)num_streams;
2270 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2271 struct darwin_interface *cInterface;
2272 UInt32 supportsStreams;
2276 for (int i = 0 ; i < num_endpoints ; ++i) {
2277 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2280 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2281 if (0 == supportsStreams)
2282 return LIBUSB_ERROR_INVALID_PARAM;
2284 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2285 if (kIOReturnSuccess != rc)
2286 return darwin_to_libusb(rc);
2289 return LIBUSB_SUCCESS;
2293 #if InterfaceVersion >= 700
2295 /* macOS APIs for getting entitlement values */
2298 #include <Security/Security.h>
2300 typedef struct __SecTask *SecTaskRef;
2301 extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator);
2302 extern CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error);
2305 static bool darwin_has_capture_entitlements (void) {
2310 task = SecTaskCreateFromSelf (kCFAllocatorDefault);
2314 value = SecTaskCopyValueForEntitlement(task, CFSTR("com.apple.vm.device-access"), NULL);
2316 entitled = value && (CFGetTypeID (value) == CFBooleanGetTypeID ()) && CFBooleanGetValue (value);
2323 static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
2324 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2325 enum libusb_error err;
2327 usbi_mutex_lock(&darwin_cached_devices_lock);
2328 (*(dpriv->device))->Release(dpriv->device);
2329 dpriv->device = darwin_device_from_service (dpriv->service);
2330 if (!dpriv->device) {
2331 err = LIBUSB_ERROR_NO_DEVICE;
2333 err = LIBUSB_SUCCESS;
2335 usbi_mutex_unlock(&darwin_cached_devices_lock);
2340 /* On macOS, we capture an entire device at once, not individual interfaces. */
2342 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2344 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2346 enum libusb_error err;
2348 if (HAS_CAPTURE_DEVICE()) {
2350 return LIBUSB_ERROR_NOT_SUPPORTED;
2353 if (dpriv->capture_count == 0) {
2354 /* request authorization */
2355 if (darwin_has_capture_entitlements ()) {
2356 kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
2357 if (kresult != kIOReturnSuccess) {
2358 usbi_err (HANDLE_CTX (dev_handle), "IOServiceAuthorize: %s", darwin_error_str(kresult));
2359 return darwin_to_libusb (kresult);
2361 /* we need start() to be called again for authorization status to refresh */
2362 err = darwin_reload_device (dev_handle);
2363 if (err != LIBUSB_SUCCESS) {
2367 /* reset device to release existing drivers */
2368 err = darwin_reenumerate_device (dev_handle, true);
2369 if (err != LIBUSB_SUCCESS) {
2373 dpriv->capture_count++;
2374 return LIBUSB_SUCCESS;
2378 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2380 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2382 if (HAS_CAPTURE_DEVICE()) {
2384 return LIBUSB_ERROR_NOT_SUPPORTED;
2387 dpriv->capture_count--;
2388 if (dpriv->capture_count > 0) {
2389 return LIBUSB_SUCCESS;
2391 dpriv->capture_count = 0;
2393 /* reset device to attach kernel drivers */
2394 return darwin_reenumerate_device (dev_handle, false);
2397 static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2398 enum libusb_error ret;
2399 if (dev_handle->auto_detach_kernel_driver) {
2400 ret = darwin_detach_kernel_driver (dev_handle, iface);
2401 if (ret != LIBUSB_SUCCESS) {
2405 return darwin_claim_interface (dev_handle, iface);
2408 static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2409 enum libusb_error ret;
2411 ret = darwin_release_interface (dev_handle, iface);
2412 if (ret != LIBUSB_SUCCESS) {
2415 if (dev_handle->auto_detach_kernel_driver) {
2416 ret = darwin_attach_kernel_driver (dev_handle, iface);
2423 const struct usbi_os_backend usbi_backend = {
2425 .caps = USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
2426 .init = darwin_init,
2427 .exit = darwin_exit,
2428 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2429 .get_config_descriptor = darwin_get_config_descriptor,
2430 .hotplug_poll = darwin_hotplug_poll,
2432 .open = darwin_open,
2433 .close = darwin_close,
2434 .get_configuration = darwin_get_configuration,
2435 .set_configuration = darwin_set_configuration,
2437 .set_interface_altsetting = darwin_set_interface_altsetting,
2438 .clear_halt = darwin_clear_halt,
2439 .reset_device = darwin_reset_device,
2441 #if InterfaceVersion >= 550
2442 .alloc_streams = darwin_alloc_streams,
2443 .free_streams = darwin_free_streams,
2446 .kernel_driver_active = darwin_kernel_driver_active,
2448 #if InterfaceVersion >= 700
2449 .detach_kernel_driver = darwin_detach_kernel_driver,
2450 .attach_kernel_driver = darwin_attach_kernel_driver,
2451 .claim_interface = darwin_capture_claim_interface,
2452 .release_interface = darwin_capture_release_interface,
2454 .claim_interface = darwin_claim_interface,
2455 .release_interface = darwin_release_interface,
2458 .destroy_device = darwin_destroy_device,
2460 .submit_transfer = darwin_submit_transfer,
2461 .cancel_transfer = darwin_cancel_transfer,
2463 .handle_transfer_completion = darwin_handle_transfer_completion,
2465 .device_priv_size = sizeof(struct darwin_device_priv),
2466 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2467 .transfer_priv_size = sizeof(struct darwin_transfer_priv),