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_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint);
85 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
86 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
88 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
89 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
90 UInt64 old_session_id);
92 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
93 UInt64 *old_session_id);
95 #if defined(ENABLE_LOGGING)
96 static const char *darwin_error_str (IOReturn result) {
97 static char string_buffer[50];
99 case kIOReturnSuccess:
101 case kIOReturnNotOpen:
102 return "device not opened for exclusive access";
103 case kIOReturnNoDevice:
104 return "no connection to an IOService";
105 case kIOUSBNoAsyncPortErr:
106 return "no async port has been opened for interface";
107 case kIOReturnExclusiveAccess:
108 return "another process has device opened for exclusive access";
109 case kIOUSBPipeStalled:
110 return "pipe is stalled";
112 return "could not establish a connection to the Darwin kernel";
113 case kIOUSBTransactionTimeout:
114 return "transaction timed out";
115 case kIOReturnBadArgument:
116 return "invalid argument";
117 case kIOReturnAborted:
118 return "transaction aborted";
119 case kIOReturnNotResponding:
120 return "device not responding";
121 case kIOReturnOverrun:
122 return "data overrun";
123 case kIOReturnCannotWire:
124 return "physical memory can not be wired down";
125 case kIOReturnNoResources:
126 return "out of resources";
127 case kIOUSBHighSpeedSplitError:
128 return "high speed split error";
129 case kIOUSBUnknownPipeErr:
130 return "pipe ref not recognized";
132 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
133 return string_buffer;
138 static enum libusb_error darwin_to_libusb (IOReturn result) {
140 case kIOReturnUnderrun:
141 case kIOReturnSuccess:
142 return LIBUSB_SUCCESS;
143 case kIOReturnNotOpen:
144 case kIOReturnNoDevice:
145 return LIBUSB_ERROR_NO_DEVICE;
146 case kIOReturnExclusiveAccess:
147 return LIBUSB_ERROR_ACCESS;
148 case kIOUSBPipeStalled:
149 return LIBUSB_ERROR_PIPE;
150 case kIOReturnBadArgument:
151 return LIBUSB_ERROR_INVALID_PARAM;
152 case kIOUSBTransactionTimeout:
153 return LIBUSB_ERROR_TIMEOUT;
154 case kIOReturnNotResponding:
155 case kIOReturnAborted:
157 case kIOUSBNoAsyncPortErr:
158 case kIOUSBUnknownPipeErr:
160 return LIBUSB_ERROR_OTHER;
164 /* this function must be called with the darwin_cached_devices_lock held */
165 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
166 cached_dev->refcount--;
167 /* free the device and remove it from the cache */
168 if (0 == cached_dev->refcount) {
169 list_del(&cached_dev->list);
171 if (cached_dev->device) {
172 (*(cached_dev->device))->Release(cached_dev->device);
173 cached_dev->device = NULL;
175 IOObjectRelease (cached_dev->service);
180 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
181 cached_dev->refcount++;
184 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) {
185 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
187 /* current interface */
188 struct darwin_interface *cInterface;
192 usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
194 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
195 cInterface = &priv->interfaces[iface];
197 if (dev_handle->claimed_interfaces & (1U << iface)) {
198 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
199 if (cInterface->endpoint_addrs[i] == ep) {
206 *interface_out = cInterface;
208 usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
209 return LIBUSB_SUCCESS;
215 /* No pipe found with the correct endpoint address */
216 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
218 return LIBUSB_ERROR_NOT_FOUND;
221 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
222 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
225 return kIOReturnError;
228 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
229 &kCFTypeDictionaryKeyCallBacks,
230 &kCFTypeDictionaryValueCallBacks);
232 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
233 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
234 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
236 if (propertyMatchDict && locationCF) {
237 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
238 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
240 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
242 /* release our references as per the Create Rule */
243 if (propertyMatchDict)
244 CFRelease (propertyMatchDict);
246 CFRelease (locationCF);
249 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
252 /* Returns 1 on success, 0 on failure. */
253 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
254 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
258 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
259 success = CFNumberGetValue(cfNumber, type, p);
262 CFRelease (cfNumber);
265 return (success != 0);
268 /* Returns 1 on success, 0 on failure. */
269 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
270 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
271 bool success = false;
274 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
275 CFIndex length = CFDataGetLength (cfData);
280 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
290 static usb_device_t **darwin_device_from_service (io_service_t service)
292 io_cf_plugin_ref_t *plugInInterface = NULL;
293 usb_device_t **device;
296 const int max_retries = 5;
298 /* The IOCreatePlugInInterfaceForService function might consistently return
299 an "out of resources" error with certain USB devices the first time we run
300 it. The reason is still unclear, but retrying fixes the problem */
301 for (int count = 0; count < max_retries; count++) {
302 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
303 kIOCFPlugInInterfaceID, &plugInInterface,
305 if (kIOReturnSuccess == kresult && plugInInterface) {
309 usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
311 /* sleep for a little while before trying again */
312 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
315 if (kIOReturnSuccess != kresult || !plugInInterface) {
316 usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
320 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
322 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
323 (*plugInInterface)->Release (plugInInterface);
328 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
330 struct darwin_cached_device *cached_device;
331 UInt64 old_session_id;
332 struct libusb_context *ctx;
333 io_service_t service;
336 usbi_mutex_lock(&active_contexts_lock);
338 while ((service = IOIteratorNext(add_devices))) {
339 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
340 if (ret < 0 || !cached_device->can_enumerate) {
344 /* add this device to each active context's device list */
345 for_each_context(ctx) {
346 process_new_device (ctx, cached_device, old_session_id);
349 if (cached_device->in_reenumerate) {
350 usbi_dbg ("cached device in reset state. reset complete...");
351 cached_device->in_reenumerate = false;
354 IOObjectRelease(service);
357 usbi_mutex_unlock(&active_contexts_lock);
360 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
362 struct libusb_device *dev = NULL;
363 struct libusb_context *ctx;
364 struct darwin_cached_device *old_device;
370 usbi_mutex_lock(&active_contexts_lock);
372 while ((device = IOIteratorNext (rem_devices)) != 0) {
373 bool is_reenumerating = false;
375 /* get the location from the i/o registry */
376 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
377 IOObjectRelease (device);
381 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
382 otherwise no cached device will ever get freed */
383 usbi_mutex_lock(&darwin_cached_devices_lock);
384 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
385 if (old_device->session == session) {
386 if (old_device->in_reenumerate) {
387 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
388 * will deref if needed. */
389 usbi_dbg ("detected device detached due to re-enumeration");
391 /* the device object is no longer usable so go ahead and release it */
392 if (old_device->device) {
393 (*(old_device->device))->Release(old_device->device);
394 old_device->device = NULL;
397 is_reenumerating = true;
399 darwin_deref_cached_device (old_device);
406 usbi_mutex_unlock(&darwin_cached_devices_lock);
407 if (is_reenumerating) {
411 for_each_context(ctx) {
412 usbi_dbg ("notifying context %p of device disconnect", ctx);
414 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
416 /* signal the core that this device has been disconnected. the core will tear down this device
417 when the reference count reaches 0 */
418 usbi_disconnect_device(dev);
419 libusb_unref_device(dev);
424 usbi_mutex_unlock(&active_contexts_lock);
427 static void darwin_hotplug_poll (void)
429 /* not sure if 1 ms will be too long/short but it should work ok */
430 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
432 /* since a kernel thread may notify the IOIterators used for
433 * hotplug notification we can't just clear the iterators.
434 * instead just wait until all IOService providers are quiet */
435 (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
438 static void darwin_clear_iterator (io_iterator_t iter) {
441 while ((device = IOIteratorNext (iter)) != 0)
442 IOObjectRelease (device);
445 static void darwin_fail_startup(void) {
446 pthread_mutex_lock (&libusb_darwin_at_mutex);
447 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
448 pthread_cond_signal (&libusb_darwin_at_cond);
449 pthread_mutex_unlock (&libusb_darwin_at_mutex);
453 static void *darwin_event_thread_main (void *arg0) {
455 struct libusb_context *ctx = (struct libusb_context *)arg0;
456 CFRunLoopRef runloop;
457 CFRunLoopSourceRef libusb_shutdown_cfsource;
458 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
460 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
461 /* Set this thread's name, so it can be seen in the debugger
462 and crash reports. */
463 pthread_setname_np ("org.libusb.device-hotplug");
466 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
467 /* Tell the Objective-C garbage collector about this thread.
468 This is required because, unlike NSThreads, pthreads are
469 not automatically registered. Although we don't use
470 Objective-C, we use CoreFoundation, which does.
471 Garbage collection support was entirely removed in 10.12,
472 so don't bother there. */
473 objc_registerThreadWithCollector();
476 /* hotplug (device arrival/removal) sources */
477 CFRunLoopSourceRef libusb_notification_cfsource;
478 io_notification_port_t libusb_notification_port;
479 io_iterator_t libusb_rem_device_iterator;
480 io_iterator_t libusb_add_device_iterator;
482 usbi_dbg ("creating hotplug event source");
484 runloop = CFRunLoopGetCurrent ();
487 /* add the shutdown cfsource to the run loop */
488 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
489 libusb_shutdown_cfsourcectx.info = runloop;
490 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
491 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
492 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
494 /* add the notification port to the run loop */
495 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
496 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
497 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
499 /* create notifications for removed devices */
500 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
501 IOServiceMatching(darwin_device_class),
502 darwin_devices_detached,
503 ctx, &libusb_rem_device_iterator);
505 if (kresult != kIOReturnSuccess) {
506 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
507 CFRelease (libusb_shutdown_cfsource);
509 darwin_fail_startup ();
512 /* create notifications for attached devices */
513 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
514 IOServiceMatching(darwin_device_class),
515 darwin_devices_attached,
516 ctx, &libusb_add_device_iterator);
518 if (kresult != kIOReturnSuccess) {
519 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
520 CFRelease (libusb_shutdown_cfsource);
522 darwin_fail_startup ();
526 darwin_clear_iterator (libusb_rem_device_iterator);
527 darwin_clear_iterator (libusb_add_device_iterator);
529 usbi_dbg ("darwin event thread ready to receive events");
531 /* signal the main thread that the hotplug runloop has been created. */
532 pthread_mutex_lock (&libusb_darwin_at_mutex);
533 libusb_darwin_acfl = runloop;
534 libusb_darwin_acfls = libusb_shutdown_cfsource;
535 pthread_cond_signal (&libusb_darwin_at_cond);
536 pthread_mutex_unlock (&libusb_darwin_at_mutex);
538 /* run the runloop */
541 usbi_dbg ("darwin event thread exiting");
543 /* signal the main thread that the hotplug runloop has finished. */
544 pthread_mutex_lock (&libusb_darwin_at_mutex);
545 libusb_darwin_acfls = NULL;
546 libusb_darwin_acfl = NULL;
547 pthread_cond_signal (&libusb_darwin_at_cond);
548 pthread_mutex_unlock (&libusb_darwin_at_mutex);
550 /* remove the notification cfsource */
551 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
553 /* remove the shutdown cfsource */
554 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
556 /* delete notification port */
557 IONotificationPortDestroy (libusb_notification_port);
559 /* delete iterators */
560 IOObjectRelease (libusb_rem_device_iterator);
561 IOObjectRelease (libusb_add_device_iterator);
563 CFRelease (libusb_shutdown_cfsource);
569 /* cleanup function to destroy cached devices */
570 static void darwin_cleanup_devices(void) {
571 struct darwin_cached_device *dev, *next;
573 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
574 darwin_deref_cached_device(dev);
578 static int darwin_init(struct libusb_context *ctx) {
582 first_init = (1 == ++init_count);
586 if (NULL == darwin_cached_devices.next) {
587 list_init (&darwin_cached_devices);
589 assert(list_empty(&darwin_cached_devices));
590 #if !defined(HAVE_CLOCK_GETTIME)
591 /* create the clocks that will be used if clock_gettime() is not available */
592 host_name_port_t host_self;
594 host_self = mach_host_self();
595 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
596 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
597 mach_port_deallocate(mach_task_self(), host_self);
601 rc = darwin_scan_devices (ctx);
602 if (LIBUSB_SUCCESS != rc)
606 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
608 usbi_err (ctx, "could not create event thread, error %d", rc);
609 rc = LIBUSB_ERROR_OTHER;
613 pthread_mutex_lock (&libusb_darwin_at_mutex);
614 while (!libusb_darwin_acfl)
615 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
616 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
617 libusb_darwin_acfl = NULL;
618 rc = LIBUSB_ERROR_OTHER;
620 pthread_mutex_unlock (&libusb_darwin_at_mutex);
623 pthread_join (libusb_darwin_at, NULL);
627 if (LIBUSB_SUCCESS != rc) {
629 darwin_cleanup_devices ();
630 #if !defined(HAVE_CLOCK_GETTIME)
631 mach_port_deallocate(mach_task_self(), clock_realtime);
632 mach_port_deallocate(mach_task_self(), clock_monotonic);
641 static void darwin_exit (struct libusb_context *ctx) {
644 if (0 == --init_count) {
645 /* stop the event runloop and wait for the thread to terminate. */
646 pthread_mutex_lock (&libusb_darwin_at_mutex);
647 CFRunLoopSourceSignal (libusb_darwin_acfls);
648 CFRunLoopWakeUp (libusb_darwin_acfl);
649 while (libusb_darwin_acfl)
650 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
651 pthread_mutex_unlock (&libusb_darwin_at_mutex);
652 pthread_join (libusb_darwin_at, NULL);
654 darwin_cleanup_devices ();
656 #if !defined(HAVE_CLOCK_GETTIME)
657 mach_port_deallocate(mach_task_self(), clock_realtime);
658 mach_port_deallocate(mach_task_self(), clock_monotonic);
663 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
664 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
666 IOUSBConfigurationDescriptorPtr desc;
669 /* is there a simpler way to determine the index? */
670 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
671 if (kresult != kIOReturnSuccess)
672 return darwin_to_libusb (kresult);
674 for (i = 0 ; i < numConfig ; i++) {
675 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
677 if (desc->bConfigurationValue == config_value)
681 /* configuration not found */
682 return LIBUSB_ERROR_NOT_FOUND;
685 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
686 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
689 if (0 == priv->active_config)
690 return LIBUSB_ERROR_NOT_FOUND;
692 config_index = get_configuration_index (dev, priv->active_config);
693 if (config_index < 0)
696 assert(config_index >= 0 && config_index <= UINT8_MAX);
697 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
700 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
701 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
702 IOUSBConfigurationDescriptorPtr desc;
706 if (!priv || !priv->device)
707 return LIBUSB_ERROR_OTHER;
709 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
710 if (kresult == kIOReturnSuccess) {
711 /* copy descriptor */
712 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
713 len = libusb_le16_to_cpu(desc->wTotalLength);
715 memmove (buffer, desc, len);
718 ret = darwin_to_libusb (kresult);
719 if (ret != LIBUSB_SUCCESS)
725 /* check whether the os has configured the device */
726 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
727 usb_device_t **darwin_device = dev->device;
729 IOUSBConfigurationDescriptorPtr configDesc;
730 IOUSBFindInterfaceRequest request;
732 io_iterator_t interface_iterator;
733 io_service_t firstInterface;
735 if (dev->dev_descriptor.bNumConfigurations < 1) {
736 usbi_err (ctx, "device has no configurations");
737 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
740 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
742 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
743 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
744 usbi_dbg ("ignoring configuration on root hub simulation");
745 dev->active_config = 0;
746 return LIBUSB_SUCCESS;
749 /* find the first configuration */
750 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
751 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
753 /* check if the device is already configured. there is probably a better way than iterating over the
754 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
755 might lock up on the device request) */
757 /* Setup the Interface Request */
758 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
759 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
760 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
761 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
763 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
764 if (kresult != kIOReturnSuccess)
765 return darwin_to_libusb (kresult);
768 firstInterface = IOIteratorNext(interface_iterator);
770 /* done with the interface iterator */
771 IOObjectRelease(interface_iterator);
773 if (firstInterface) {
774 IOObjectRelease (firstInterface);
776 /* device is configured */
777 if (dev->dev_descriptor.bNumConfigurations == 1)
778 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
779 dev->active_config = dev->first_config;
781 /* devices with more than one configuration should work with GetConfiguration */
782 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
785 dev->active_config = 0;
787 usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
789 return LIBUSB_SUCCESS;
792 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
793 IOUSBDevRequestTO req;
795 assert(buffer_size <= UINT16_MAX);
797 memset (buffer, 0, buffer_size);
799 /* Set up request for descriptor/ */
800 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
801 req.bRequest = kUSBRqGetDescriptor;
802 req.wValue = (UInt16)(desc << 8);
803 req.wIndex = desc_index;
804 req.wLength = (UInt16)buffer_size;
806 req.noDataTimeout = 20;
807 req.completionTimeout = 100;
809 return (*device)->DeviceRequestTO (device, &req);
812 static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
813 usb_device_t **device = dev->device;
815 long delay = 30000; // microseconds
816 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
818 IOReturn ret = 0, ret2;
820 UInt16 idProduct, idVendor;
822 dev->can_enumerate = 0;
824 (*device)->GetDeviceClass (device, &bDeviceClass);
825 (*device)->GetDeviceProduct (device, &idProduct);
826 (*device)->GetDeviceVendor (device, &idVendor);
828 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
829 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
830 * to follow the spec as closely as possible, try opening the device */
831 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
834 /**** retrieve device descriptor ****/
835 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
837 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
838 /* received an overrun error but we still received a device descriptor */
839 ret = kIOReturnSuccess;
841 if (kIOUSBVendorIDAppleComputer == idVendor) {
842 /* NTH: don't bother retrying or unsuspending Apple devices */
846 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
847 0 == dev->dev_descriptor.bcdUSB)) {
848 /* work around for incorrectly configured devices */
849 if (try_reconfigure && is_open) {
850 usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
852 /* set the first configuration */
853 (*device)->SetConfiguration(device, 1);
855 /* don't try to reconfigure again */
859 ret = kIOUSBPipeStalled;
862 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
863 /* device may be suspended. unsuspend it and try again */
864 #if DeviceVersion >= 320
867 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
868 (void)(*device)->GetUSBDeviceInformation (device, &info);
870 /* note that the device was suspended */
871 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
876 /* try to unsuspend the device */
877 ret2 = (*device)->USBDeviceSuspend (device, 0);
878 if (kIOReturnSuccess != ret2) {
879 /* prevent log spew from poorly behaving devices. this indicates the
880 os actually had trouble communicating with the device */
881 usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
889 if (kIOReturnSuccess != ret) {
890 usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
891 /* sleep for a little while before trying again */
892 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
894 } while (kIOReturnSuccess != ret && retries--);
897 /* resuspend the device */
898 (void)(*device)->USBDeviceSuspend (device, 1);
901 (void) (*device)->USBDeviceClose (device);
903 if (ret != kIOReturnSuccess) {
904 /* a debug message was already printed out for this error */
905 if (LIBUSB_CLASS_HUB == bDeviceClass)
906 usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
907 idVendor, idProduct, darwin_error_str (ret), ret);
909 usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
910 idVendor, idProduct, darwin_error_str (ret), ret);
911 return darwin_to_libusb (ret);
914 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
915 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
916 /* not a valid device */
917 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
918 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
919 return LIBUSB_ERROR_NO_DEVICE;
922 usbi_dbg ("cached device descriptor:");
923 usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
924 usbi_dbg (" bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
925 usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
926 usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
927 usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
928 usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
929 usbi_dbg (" idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
930 usbi_dbg (" idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
931 usbi_dbg (" bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
932 usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
933 usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct);
934 usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
935 usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
937 dev->can_enumerate = 1;
939 return LIBUSB_SUCCESS;
942 /* Returns 1 on success, 0 on failure. */
943 static bool get_device_port (io_service_t service, UInt8 *port) {
948 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
952 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
953 if (kIOReturnSuccess == kresult) {
954 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
955 IOObjectRelease (parent);
961 /* Returns 1 on success, 0 on failure. */
962 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
966 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
968 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
969 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
975 /* We ran out of parents */
979 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
980 UInt64 *old_session_id) {
981 struct darwin_cached_device *new_device;
982 UInt64 sessionID = 0, parent_sessionID = 0;
983 UInt32 locationID = 0;
984 enum libusb_error ret = LIBUSB_SUCCESS;
985 usb_device_t **device;
988 /* assuming sessionID != 0 normally (never seen it be 0) */
992 /* get some info from the io registry */
993 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
994 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
995 if (!get_device_port (service, &port)) {
996 usbi_dbg("could not get connected port number");
999 usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
1001 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1002 usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
1005 usbi_mutex_lock(&darwin_cached_devices_lock);
1007 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1008 usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1009 sessionID, locationID, new_device->session, new_device->location);
1010 if (new_device->location == locationID && new_device->in_reenumerate) {
1011 usbi_dbg ("found cached device with matching location that is being re-enumerated");
1012 *old_session_id = new_device->session;
1016 if (new_device->session == sessionID) {
1017 usbi_dbg("using cached device for device");
1018 *cached_out = new_device;
1026 usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
1028 device = darwin_device_from_service (service);
1030 ret = LIBUSB_ERROR_NO_DEVICE;
1034 if (!(*old_session_id)) {
1035 new_device = calloc (1, sizeof (*new_device));
1037 ret = LIBUSB_ERROR_NO_MEM;
1041 /* add this device to the cached device list */
1042 list_add(&new_device->list, &darwin_cached_devices);
1044 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1046 /* keep a reference to this device */
1047 darwin_ref_cached_device(new_device);
1049 (*device)->GetLocationID (device, &new_device->location);
1050 new_device->port = port;
1051 new_device->parent_session = parent_sessionID;
1053 /* release the ref to old device's service */
1054 IOObjectRelease (new_device->service);
1057 /* keep track of devices regardless of if we successfully enumerate them to
1058 prevent them from being enumerated multiple times */
1059 *cached_out = new_device;
1061 new_device->session = sessionID;
1062 new_device->device = device;
1063 new_device->service = service;
1065 /* retain the service */
1066 IOObjectRetain (service);
1068 /* cache the device descriptor */
1069 ret = darwin_cache_device_descriptor(new_device);
1073 if (new_device->can_enumerate) {
1074 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1075 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1076 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1077 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1081 usbi_mutex_unlock(&darwin_cached_devices_lock);
1086 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1087 UInt64 old_session_id) {
1088 struct darwin_device_priv *priv;
1089 struct libusb_device *dev = NULL;
1091 enum libusb_error ret = LIBUSB_SUCCESS;
1094 /* check current active configuration (and cache the first configuration value--
1095 which may be used by claim_interface) */
1096 ret = darwin_check_configuration (ctx, cached_device);
1100 if (0 != old_session_id) {
1101 usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1102 ctx, old_session_id, cached_device->session);
1103 /* save the libusb device before the session id is updated */
1104 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1108 usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
1109 ctx, cached_device->session);
1111 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1113 return LIBUSB_ERROR_NO_MEM;
1116 priv = usbi_get_device_priv(dev);
1118 priv->dev = cached_device;
1119 darwin_ref_cached_device (priv->dev);
1120 dev->port_number = cached_device->port;
1121 dev->bus_number = cached_device->location >> 24;
1122 assert(cached_device->address <= UINT8_MAX);
1123 dev->device_address = (uint8_t)cached_device->address;
1125 priv = usbi_get_device_priv(dev);
1128 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1129 "mismatch between libusb and IOKit device descriptor sizes");
1130 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1131 usbi_localize_device_descriptor(&dev->device_descriptor);
1132 dev->session_data = cached_device->session;
1134 if (NULL != dev->parent_dev) {
1135 libusb_unref_device(dev->parent_dev);
1136 dev->parent_dev = NULL;
1139 if (cached_device->parent_session > 0) {
1140 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1143 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1146 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1147 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1148 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1149 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
1150 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1152 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1153 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1156 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1159 ret = usbi_sanitize_device (dev);
1163 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1164 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1168 if (!cached_device->in_reenumerate && 0 == ret) {
1169 usbi_connect_device (dev);
1171 libusb_unref_device (dev);
1177 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1178 struct darwin_cached_device *cached_device;
1179 UInt64 old_session_id;
1180 io_iterator_t deviceIterator;
1181 io_service_t service;
1185 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1186 if (kresult != kIOReturnSuccess)
1187 return darwin_to_libusb (kresult);
1189 while ((service = IOIteratorNext (deviceIterator))) {
1190 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1191 if (ret < 0 || !cached_device->can_enumerate) {
1195 (void) process_new_device (ctx, cached_device, old_session_id);
1197 IOObjectRelease(service);
1200 IOObjectRelease(deviceIterator);
1202 return LIBUSB_SUCCESS;
1205 static int darwin_open (struct libusb_device_handle *dev_handle) {
1206 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1207 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1210 if (0 == dpriv->open_count) {
1211 /* try to open the device */
1212 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1213 if (kresult != kIOReturnSuccess) {
1214 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1216 if (kIOReturnExclusiveAccess != kresult) {
1217 return darwin_to_libusb (kresult);
1220 /* it is possible to perform some actions on a device that is not open so do not return an error */
1221 priv->is_open = false;
1223 priv->is_open = true;
1226 /* create async event source */
1227 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1228 if (kresult != kIOReturnSuccess) {
1229 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1231 if (priv->is_open) {
1232 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1235 priv->is_open = false;
1237 return darwin_to_libusb (kresult);
1240 CFRetain (libusb_darwin_acfl);
1242 /* add the cfSource to the aync run loop */
1243 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1246 /* device opened successfully */
1247 dpriv->open_count++;
1249 usbi_dbg ("device open for access");
1254 static void darwin_close (struct libusb_device_handle *dev_handle) {
1255 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1256 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1260 if (dpriv->open_count == 0) {
1261 /* something is probably very wrong if this is the case */
1262 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1266 dpriv->open_count--;
1268 /* make sure all interfaces are released */
1269 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1270 if (dev_handle->claimed_interfaces & (1U << i))
1271 libusb_release_interface (dev_handle, i);
1273 if (0 == dpriv->open_count) {
1274 /* delete the device's async event source */
1275 if (priv->cfSource) {
1276 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1277 CFRelease (priv->cfSource);
1278 priv->cfSource = NULL;
1279 CFRelease (libusb_darwin_acfl);
1282 if (priv->is_open) {
1283 /* close the device */
1284 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1285 if (kresult != kIOReturnSuccess) {
1286 /* Log the fact that we had a problem closing the file, however failing a
1287 * close isn't really an error, so return success anyway */
1288 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1294 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1295 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1297 *config = dpriv->active_config;
1299 return LIBUSB_SUCCESS;
1302 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1303 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1310 /* Setting configuration will invalidate the interface, so we need
1311 to reclaim it. First, dispose of existing interfaces, if any. */
1312 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1313 if (dev_handle->claimed_interfaces & (1U << i))
1314 darwin_release_interface (dev_handle, i);
1316 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1317 if (kresult != kIOReturnSuccess)
1318 return darwin_to_libusb (kresult);
1320 /* Reclaim any interfaces. */
1321 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1322 if (dev_handle->claimed_interfaces & (1U << i))
1323 darwin_claim_interface (dev_handle, i);
1325 dpriv->active_config = (UInt8)config;
1327 return LIBUSB_SUCCESS;
1330 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1331 IOUSBFindInterfaceRequest request;
1333 io_iterator_t interface_iterator;
1334 UInt8 bInterfaceNumber;
1337 *usbInterfacep = IO_OBJECT_NULL;
1339 /* Setup the Interface Request */
1340 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1341 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1342 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1343 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1345 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1346 if (kresult != kIOReturnSuccess)
1349 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1350 /* find the interface number */
1351 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1354 if (ret && bInterfaceNumber == ifc) {
1358 (void) IOObjectRelease (*usbInterfacep);
1361 /* done with the interface iterator */
1362 IOObjectRelease(interface_iterator);
1364 return kIOReturnSuccess;
1367 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1368 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1370 /* current interface */
1371 struct darwin_interface *cInterface = &priv->interfaces[iface];
1375 UInt8 numep, direction, number;
1376 UInt8 dont_care1, dont_care3;
1380 usbi_dbg ("building table of endpoints.");
1382 /* retrieve the total number of endpoints on this interface */
1383 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1384 if (kresult != kIOReturnSuccess) {
1385 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1386 return darwin_to_libusb (kresult);
1389 /* iterate through pipe references */
1390 for (UInt8 i = 1 ; i <= numep ; i++) {
1391 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1392 &dont_care2, &dont_care3);
1394 if (kresult != kIOReturnSuccess) {
1395 /* probably a buggy device. try to get the endpoint address from the descriptors */
1396 struct libusb_config_descriptor *config;
1397 const struct libusb_endpoint_descriptor *endpoint_desc;
1400 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1401 if (kresult != kIOReturnSuccess) {
1402 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1403 return darwin_to_libusb (kresult);
1406 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1407 if (LIBUSB_SUCCESS != rc) {
1411 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1413 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1415 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1418 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1419 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1422 cInterface->num_endpoints = numep;
1424 return LIBUSB_SUCCESS;
1427 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1428 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1429 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1430 io_service_t usbInterface = IO_OBJECT_NULL;
1432 enum libusb_error ret;
1433 IOCFPlugInInterface **plugInInterface = NULL;
1436 /* current interface */
1437 struct darwin_interface *cInterface = &priv->interfaces[iface];
1439 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1440 if (kresult != kIOReturnSuccess)
1441 return darwin_to_libusb (kresult);
1443 /* make sure we have an interface */
1444 if (!usbInterface && dpriv->first_config != 0) {
1445 usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1447 /* set the configuration */
1448 ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1449 if (ret != LIBUSB_SUCCESS) {
1450 usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1454 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1455 if (kresult != kIOReturnSuccess) {
1456 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1457 return darwin_to_libusb (kresult);
1461 if (!usbInterface) {
1462 usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1463 return LIBUSB_ERROR_NOT_FOUND;
1466 /* get an interface to the device's interface */
1467 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1468 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1470 /* ignore release error */
1471 (void)IOObjectRelease (usbInterface);
1473 if (kresult != kIOReturnSuccess) {
1474 usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1475 return darwin_to_libusb (kresult);
1478 if (!plugInInterface) {
1479 usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1480 return LIBUSB_ERROR_NOT_FOUND;
1483 /* Do the actual claim */
1484 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1485 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1486 (LPVOID)&cInterface->interface);
1487 /* We no longer need the intermediate plug-in */
1488 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1489 (*plugInInterface)->Release (plugInInterface);
1490 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1491 usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1492 return darwin_to_libusb (kresult);
1495 /* claim the interface */
1496 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1497 if (kresult != kIOReturnSuccess) {
1498 usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1499 return darwin_to_libusb (kresult);
1502 /* update list of endpoints */
1503 ret = get_endpoints (dev_handle, iface);
1505 /* this should not happen */
1506 darwin_release_interface (dev_handle, iface);
1507 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1511 cInterface->cfSource = NULL;
1513 /* create async event source */
1514 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1515 if (kresult != kIOReturnSuccess) {
1516 usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1518 /* can't continue without an async event source */
1519 (void)darwin_release_interface (dev_handle, iface);
1521 return darwin_to_libusb (kresult);
1524 /* add the cfSource to the async thread's run loop */
1525 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1527 usbi_dbg ("interface opened");
1529 return LIBUSB_SUCCESS;
1532 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1533 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1536 /* current interface */
1537 struct darwin_interface *cInterface = &priv->interfaces[iface];
1539 /* Check to see if an interface is open */
1540 if (!cInterface->interface)
1541 return LIBUSB_SUCCESS;
1543 /* clean up endpoint data */
1544 cInterface->num_endpoints = 0;
1546 /* delete the interface's async event source */
1547 if (cInterface->cfSource) {
1548 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1549 CFRelease (cInterface->cfSource);
1552 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1553 if (kresult != kIOReturnSuccess)
1554 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1556 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1557 if (kresult != kIOReturnSuccess)
1558 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1560 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1562 return darwin_to_libusb (kresult);
1565 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1566 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1568 enum libusb_error ret;
1570 uint8_t old_alt_setting;
1572 /* current interface */
1573 struct darwin_interface *cInterface = &priv->interfaces[iface];
1575 if (!cInterface->interface)
1576 return LIBUSB_ERROR_NO_DEVICE;
1578 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1579 if (kresult != kIOReturnSuccess)
1580 usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1582 if (kresult != kIOUSBPipeStalled)
1583 return darwin_to_libusb (kresult);
1585 /* If a device only supports a default setting for the specified interface, then a STALL
1586 (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1587 Mimick the behaviour in e.g. the Linux kernel: in such case, reset all endpoints
1588 of the interface (as would have been done per 9.1.1.5) and return success. */
1590 /* For some reason we need to reclaim the interface after the pipe error */
1591 ret = darwin_claim_interface (dev_handle, iface);
1594 darwin_release_interface (dev_handle, iface);
1595 usbi_err (HANDLE_CTX (dev_handle), "could not reclaim interface");
1598 /* Return error if a change to another value was attempted */
1599 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &old_alt_setting);
1600 if (kresult == kIOReturnSuccess && altsetting != old_alt_setting)
1601 return LIBUSB_ERROR_PIPE;
1603 for (i = 0 ; i < cInterface->num_endpoints ; i++)
1604 darwin_clear_halt(dev_handle, cInterface->endpoint_addrs[i]);
1606 return LIBUSB_SUCCESS;
1609 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1610 /* current interface */
1611 struct darwin_interface *cInterface;
1615 /* determine the interface/endpoint to use */
1616 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1617 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1619 return LIBUSB_ERROR_NOT_FOUND;
1622 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1623 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1624 if (kresult != kIOReturnSuccess)
1625 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1627 return darwin_to_libusb (kresult);
1630 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1631 unsigned long claimed_interfaces) {
1632 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1633 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1634 int open_count = dpriv->open_count;
1637 /* clear claimed interfaces temporarily */
1638 dev_handle->claimed_interfaces = 0;
1640 /* close and re-open the device */
1641 priv->is_open = false;
1642 dpriv->open_count = 1;
1644 /* clean up open interfaces */
1645 (void) darwin_close (dev_handle);
1647 /* re-open the device */
1648 ret = darwin_open (dev_handle);
1649 dpriv->open_count = open_count;
1650 if (LIBUSB_SUCCESS != ret) {
1651 /* could not restore configuration */
1652 return LIBUSB_ERROR_NOT_FOUND;
1655 if (dpriv->active_config != active_config) {
1656 usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1658 ret = darwin_set_configuration (dev_handle, active_config);
1659 if (LIBUSB_SUCCESS != ret) {
1660 usbi_dbg ("darwin/restore_state: could not restore configuration");
1661 return LIBUSB_ERROR_NOT_FOUND;
1665 usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1667 if (claimed_interfaces) {
1668 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1669 if (!(claimed_interfaces & (1U << iface))) {
1673 usbi_dbg ("darwin/restore_state: re-claiming interface %u", iface);
1675 ret = darwin_claim_interface (dev_handle, iface);
1676 if (LIBUSB_SUCCESS != ret) {
1677 usbi_dbg ("darwin/restore_state: could not claim interface %u", iface);
1678 return LIBUSB_ERROR_NOT_FOUND;
1681 dev_handle->claimed_interfaces |= 1U << iface;
1685 usbi_dbg ("darwin/restore_state: device state restored");
1687 return LIBUSB_SUCCESS;
1690 static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) {
1691 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1692 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1693 int8_t active_config = dpriv->active_config;
1695 IOUSBDeviceDescriptor descriptor;
1696 IOUSBConfigurationDescriptorPtr cached_configuration;
1697 IOUSBConfigurationDescriptor *cached_configurations;
1702 if (dpriv->in_reenumerate) {
1703 /* ack, two (or more) threads are trying to reset the device! abort! */
1704 return LIBUSB_ERROR_NOT_FOUND;
1707 dpriv->in_reenumerate = true;
1709 /* store copies of descriptors so they can be compared after the reset */
1710 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1711 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1713 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1714 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1715 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1718 /* if we need to release capture */
1719 if (HAS_CAPTURE_DEVICE()) {
1721 options |= kUSBReEnumerateCaptureDeviceMask;
1727 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1728 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
1729 if (kresult != kIOReturnSuccess) {
1730 usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1731 dpriv->in_reenumerate = false;
1732 return darwin_to_libusb (kresult);
1735 /* capture mode does not re-enumerate but it does require re-open */
1737 usbi_dbg ("darwin/reenumerate_device: restoring state...");
1738 dpriv->in_reenumerate = false;
1739 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1742 usbi_dbg ("darwin/reenumerate_device: waiting for re-enumeration to complete...");
1745 while (dpriv->in_reenumerate) {
1746 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1747 nanosleep (&delay, NULL);
1748 if (time++ >= DARWIN_REENUMERATE_TIMEOUT_US) {
1749 usbi_err (HANDLE_CTX (dev_handle), "darwin/reenumerate_device: timeout waiting for reenumerate");
1750 dpriv->in_reenumerate = false;
1751 return LIBUSB_ERROR_TIMEOUT;
1755 /* compare descriptors */
1756 usbi_dbg ("darwin/reenumerate_device: checking whether descriptors changed");
1758 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1759 /* device descriptor changed. need to return not found. */
1760 usbi_dbg ("darwin/reenumerate_device: device descriptor changed");
1761 return LIBUSB_ERROR_NOT_FOUND;
1764 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1765 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1766 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1767 usbi_dbg ("darwin/reenumerate_device: configuration descriptor %d changed", i);
1768 return LIBUSB_ERROR_NOT_FOUND;
1772 usbi_dbg ("darwin/reenumerate_device: device reset complete. restoring state...");
1774 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1777 static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
1778 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1781 if (dpriv->capture_count > 0) {
1782 /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
1783 kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
1784 return darwin_to_libusb (kresult);
1786 return darwin_reenumerate_device (dev_handle, false);
1790 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1791 enum libusb_error ret = darwin_claim_interface (dev_handle, interface);
1792 if (ret == LIBUSB_SUCCESS) {
1793 darwin_release_interface (dev_handle, interface);
1795 return (ret == LIBUSB_ERROR_ACCESS);
1798 static void darwin_destroy_device(struct libusb_device *dev) {
1799 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1802 /* need to hold the lock in case this is the last reference to the device */
1803 usbi_mutex_lock(&darwin_cached_devices_lock);
1804 darwin_deref_cached_device (dpriv->dev);
1806 usbi_mutex_unlock(&darwin_cached_devices_lock);
1810 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1811 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1814 uint8_t transferType;
1816 uint16_t maxPacketSize;
1818 struct darwin_interface *cInterface;
1819 #if InterfaceVersion >= 550
1820 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1822 /* None of the values below are used in libusb for bulk transfers */
1823 uint8_t direction, number, interval;
1826 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1827 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1829 return LIBUSB_ERROR_NOT_FOUND;
1832 #if InterfaceVersion >= 550
1833 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1835 transferType = pipeProperties.bTransferType;
1836 maxPacketSize = pipeProperties.wMaxPacketSize;
1838 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1839 &transferType, &maxPacketSize, &interval);
1843 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1844 darwin_error_str(ret), ret);
1845 return darwin_to_libusb (ret);
1848 if (0 != (transfer->length % maxPacketSize)) {
1849 /* do not need a zero packet */
1850 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1853 /* submit the request */
1854 /* timeouts are unavailable on interrupt endpoints */
1855 if (transferType == kUSBInterrupt) {
1856 if (IS_XFERIN(transfer))
1857 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1858 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1860 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1861 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1863 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1865 if (IS_XFERIN(transfer))
1866 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1867 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1868 darwin_async_io_callback, itransfer);
1870 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1871 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1872 darwin_async_io_callback, itransfer);
1876 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1877 darwin_error_str(ret), ret);
1879 return darwin_to_libusb (ret);
1882 #if InterfaceVersion >= 550
1883 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1884 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1885 struct darwin_interface *cInterface;
1889 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1890 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1892 return LIBUSB_ERROR_NOT_FOUND;
1895 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1897 if (IS_XFERIN(transfer))
1898 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1899 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1900 transfer->timeout, darwin_async_io_callback, itransfer);
1902 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1903 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1904 transfer->timeout, darwin_async_io_callback, itransfer);
1907 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1908 darwin_error_str(ret), ret);
1910 return darwin_to_libusb (ret);
1914 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1915 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1916 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1919 uint8_t direction, number, interval, pipeRef, transferType;
1920 uint16_t maxPacketSize;
1922 AbsoluteTime atTime;
1925 struct darwin_interface *cInterface;
1927 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1928 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1929 free(tpriv->isoc_framelist);
1930 tpriv->isoc_framelist = NULL;
1933 if (!tpriv->isoc_framelist) {
1934 tpriv->num_iso_packets = transfer->num_iso_packets;
1935 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1936 if (!tpriv->isoc_framelist)
1937 return LIBUSB_ERROR_NO_MEM;
1940 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1941 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1942 unsigned int length = transfer->iso_packet_desc[i].length;
1943 assert(length <= UINT16_MAX);
1944 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1947 /* determine the interface/endpoint to use */
1948 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1949 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1951 return LIBUSB_ERROR_NOT_FOUND;
1954 /* determine the properties of this endpoint and the speed of the device */
1955 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1956 &transferType, &maxPacketSize, &interval);
1958 /* Last but not least we need the bus frame number */
1959 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1960 if (kresult != kIOReturnSuccess) {
1961 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1962 free(tpriv->isoc_framelist);
1963 tpriv->isoc_framelist = NULL;
1965 return darwin_to_libusb (kresult);
1968 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1969 &transferType, &maxPacketSize, &interval);
1971 /* schedule for a frame a little in the future */
1974 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1975 frame = cInterface->frames[transfer->endpoint];
1977 /* submit the request */
1978 if (IS_XFERIN(transfer))
1979 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1980 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1983 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1984 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1987 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1989 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1991 /* High/super speed */
1992 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1994 if (kresult != kIOReturnSuccess) {
1995 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1996 darwin_error_str(kresult));
1997 free (tpriv->isoc_framelist);
1998 tpriv->isoc_framelist = NULL;
2001 return darwin_to_libusb (kresult);
2004 static int submit_control_transfer(struct usbi_transfer *itransfer) {
2005 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2006 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
2007 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2008 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2012 memset(&tpriv->req, 0, sizeof(tpriv->req));
2014 /* IOUSBDeviceInterface expects the request in cpu endianness */
2015 tpriv->req.bmRequestType = setup->bmRequestType;
2016 tpriv->req.bRequest = setup->bRequest;
2017 /* these values should be in bus order from libusb_fill_control_setup */
2018 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
2019 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
2020 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
2021 /* data is stored after the libusb control block */
2022 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
2023 tpriv->req.completionTimeout = transfer->timeout;
2024 tpriv->req.noDataTimeout = transfer->timeout;
2026 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2028 /* all transfers in libusb-1.0 are async */
2030 if (transfer->endpoint) {
2031 struct darwin_interface *cInterface;
2034 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2035 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2037 return LIBUSB_ERROR_NOT_FOUND;
2040 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2042 /* control request on endpoint 0 */
2043 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2045 if (kresult != kIOReturnSuccess)
2046 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2048 return darwin_to_libusb (kresult);
2051 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2052 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2054 switch (transfer->type) {
2055 case LIBUSB_TRANSFER_TYPE_CONTROL:
2056 return submit_control_transfer(itransfer);
2057 case LIBUSB_TRANSFER_TYPE_BULK:
2058 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2059 return submit_bulk_transfer(itransfer);
2060 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2061 return submit_iso_transfer(itransfer);
2062 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2063 #if InterfaceVersion >= 550
2064 return submit_stream_transfer(itransfer);
2066 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2067 return LIBUSB_ERROR_NOT_SUPPORTED;
2070 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2071 return LIBUSB_ERROR_INVALID_PARAM;
2075 static int cancel_control_transfer(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);
2080 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2083 return LIBUSB_ERROR_NO_DEVICE;
2085 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2087 return darwin_to_libusb (kresult);
2090 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2091 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2092 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2093 struct darwin_interface *cInterface;
2094 uint8_t pipeRef, iface;
2097 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2098 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2100 return LIBUSB_ERROR_NOT_FOUND;
2104 return LIBUSB_ERROR_NO_DEVICE;
2106 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2108 /* abort transactions */
2109 #if InterfaceVersion >= 550
2110 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2111 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2114 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2116 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2118 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2119 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2121 return darwin_to_libusb (kresult);
2124 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2125 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2127 switch (transfer->type) {
2128 case LIBUSB_TRANSFER_TYPE_CONTROL:
2129 return cancel_control_transfer(itransfer);
2130 case LIBUSB_TRANSFER_TYPE_BULK:
2131 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2132 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2133 return darwin_abort_transfers (itransfer);
2135 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2136 return LIBUSB_ERROR_INVALID_PARAM;
2140 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2141 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2142 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2143 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2145 usbi_dbg ("an async io operation has completed");
2147 /* if requested write a zero packet */
2148 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2149 struct darwin_interface *cInterface;
2152 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2154 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2157 tpriv->result = result;
2158 tpriv->size = (UInt32) (uintptr_t) arg0;
2160 /* signal the core that this transfer is complete */
2161 usbi_signal_transfer_completion(itransfer);
2164 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2165 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2166 result = kIOUSBTransactionTimeout;
2169 case kIOReturnUnderrun:
2170 case kIOReturnSuccess:
2171 return LIBUSB_TRANSFER_COMPLETED;
2172 case kIOReturnAborted:
2173 return LIBUSB_TRANSFER_CANCELLED;
2174 case kIOUSBPipeStalled:
2175 usbi_dbg ("transfer error: pipe is stalled");
2176 return LIBUSB_TRANSFER_STALL;
2177 case kIOReturnOverrun:
2178 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2179 return LIBUSB_TRANSFER_OVERFLOW;
2180 case kIOUSBTransactionTimeout:
2181 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2182 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2183 return LIBUSB_TRANSFER_TIMED_OUT;
2185 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2186 return LIBUSB_TRANSFER_ERROR;
2190 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2191 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2192 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2193 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2194 const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2195 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2197 if (transfer->type > max_transfer_type) {
2198 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2199 return LIBUSB_ERROR_INVALID_PARAM;
2202 if (NULL == tpriv) {
2203 usbi_err (TRANSFER_CTX(transfer), "malformed request is missing transfer priv");
2204 return LIBUSB_ERROR_INVALID_PARAM;
2207 usbi_dbg ("handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2209 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
2210 if (is_isoc && tpriv->isoc_framelist) {
2211 /* copy isochronous results back */
2213 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2214 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2215 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2216 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2218 } else if (!is_isoc) {
2219 itransfer->transferred += tpriv->size;
2223 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2224 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2227 #if !defined(HAVE_CLOCK_GETTIME)
2228 void usbi_get_monotonic_time(struct timespec *tp) {
2229 mach_timespec_t sys_time;
2231 /* use system boot time as reference for the monotonic clock */
2232 clock_get_time (clock_monotonic, &sys_time);
2234 tp->tv_sec = sys_time.tv_sec;
2235 tp->tv_nsec = sys_time.tv_nsec;
2238 void usbi_get_real_time(struct timespec *tp) {
2239 mach_timespec_t sys_time;
2241 /* CLOCK_REALTIME represents time since the epoch */
2242 clock_get_time (clock_realtime, &sys_time);
2244 tp->tv_sec = sys_time.tv_sec;
2245 tp->tv_nsec = sys_time.tv_nsec;
2249 #if InterfaceVersion >= 550
2250 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2251 int num_endpoints) {
2252 struct darwin_interface *cInterface;
2253 UInt32 supportsStreams;
2257 /* find the minimum number of supported streams on the endpoint list */
2258 for (i = 0 ; i < num_endpoints ; ++i) {
2259 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2263 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2264 if (num_streams > supportsStreams)
2265 num_streams = supportsStreams;
2268 /* it is an error if any endpoint in endpoints does not support streams */
2269 if (0 == num_streams)
2270 return LIBUSB_ERROR_INVALID_PARAM;
2272 /* create the streams */
2273 for (i = 0 ; i < num_endpoints ; ++i) {
2274 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2276 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2277 if (kIOReturnSuccess != rc)
2278 return darwin_to_libusb(rc);
2281 assert(num_streams <= INT_MAX);
2282 return (int)num_streams;
2285 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2286 struct darwin_interface *cInterface;
2287 UInt32 supportsStreams;
2291 for (int i = 0 ; i < num_endpoints ; ++i) {
2292 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2295 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2296 if (0 == supportsStreams)
2297 return LIBUSB_ERROR_INVALID_PARAM;
2299 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2300 if (kIOReturnSuccess != rc)
2301 return darwin_to_libusb(rc);
2304 return LIBUSB_SUCCESS;
2308 #if InterfaceVersion >= 700
2310 /* macOS APIs for getting entitlement values */
2313 #include <Security/Security.h>
2315 typedef struct __SecTask *SecTaskRef;
2316 extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator);
2317 extern CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error);
2320 static bool darwin_has_capture_entitlements (void) {
2325 task = SecTaskCreateFromSelf (kCFAllocatorDefault);
2329 value = SecTaskCopyValueForEntitlement(task, CFSTR("com.apple.vm.device-access"), NULL);
2331 entitled = value && (CFGetTypeID (value) == CFBooleanGetTypeID ()) && CFBooleanGetValue (value);
2338 static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
2339 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2340 enum libusb_error err;
2342 usbi_mutex_lock(&darwin_cached_devices_lock);
2343 (*(dpriv->device))->Release(dpriv->device);
2344 dpriv->device = darwin_device_from_service (dpriv->service);
2345 if (!dpriv->device) {
2346 err = LIBUSB_ERROR_NO_DEVICE;
2348 err = LIBUSB_SUCCESS;
2350 usbi_mutex_unlock(&darwin_cached_devices_lock);
2355 /* On macOS, we capture an entire device at once, not individual interfaces. */
2357 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2359 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2361 enum libusb_error err;
2363 if (HAS_CAPTURE_DEVICE()) {
2365 return LIBUSB_ERROR_NOT_SUPPORTED;
2368 if (dpriv->capture_count == 0) {
2369 /* request authorization */
2370 if (darwin_has_capture_entitlements ()) {
2371 kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
2372 if (kresult != kIOReturnSuccess) {
2373 usbi_err (HANDLE_CTX (dev_handle), "IOServiceAuthorize: %s", darwin_error_str(kresult));
2374 return darwin_to_libusb (kresult);
2376 /* we need start() to be called again for authorization status to refresh */
2377 err = darwin_reload_device (dev_handle);
2378 if (err != LIBUSB_SUCCESS) {
2382 /* reset device to release existing drivers */
2383 err = darwin_reenumerate_device (dev_handle, true);
2384 if (err != LIBUSB_SUCCESS) {
2388 dpriv->capture_count++;
2389 return LIBUSB_SUCCESS;
2393 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2395 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2397 if (HAS_CAPTURE_DEVICE()) {
2399 return LIBUSB_ERROR_NOT_SUPPORTED;
2402 dpriv->capture_count--;
2403 if (dpriv->capture_count > 0) {
2404 return LIBUSB_SUCCESS;
2406 dpriv->capture_count = 0;
2408 /* reset device to attach kernel drivers */
2409 return darwin_reenumerate_device (dev_handle, false);
2412 static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2413 enum libusb_error ret;
2414 if (dev_handle->auto_detach_kernel_driver) {
2415 ret = darwin_detach_kernel_driver (dev_handle, iface);
2416 if (ret != LIBUSB_SUCCESS) {
2420 return darwin_claim_interface (dev_handle, iface);
2423 static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2424 enum libusb_error ret;
2426 ret = darwin_release_interface (dev_handle, iface);
2427 if (ret != LIBUSB_SUCCESS) {
2430 if (dev_handle->auto_detach_kernel_driver) {
2431 ret = darwin_attach_kernel_driver (dev_handle, iface);
2438 const struct usbi_os_backend usbi_backend = {
2440 .caps = USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
2441 .init = darwin_init,
2442 .exit = darwin_exit,
2443 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2444 .get_config_descriptor = darwin_get_config_descriptor,
2445 .hotplug_poll = darwin_hotplug_poll,
2447 .open = darwin_open,
2448 .close = darwin_close,
2449 .get_configuration = darwin_get_configuration,
2450 .set_configuration = darwin_set_configuration,
2452 .set_interface_altsetting = darwin_set_interface_altsetting,
2453 .clear_halt = darwin_clear_halt,
2454 .reset_device = darwin_reset_device,
2456 #if InterfaceVersion >= 550
2457 .alloc_streams = darwin_alloc_streams,
2458 .free_streams = darwin_free_streams,
2461 .kernel_driver_active = darwin_kernel_driver_active,
2463 #if InterfaceVersion >= 700
2464 .detach_kernel_driver = darwin_detach_kernel_driver,
2465 .attach_kernel_driver = darwin_attach_kernel_driver,
2466 .claim_interface = darwin_capture_claim_interface,
2467 .release_interface = darwin_capture_release_interface,
2469 .claim_interface = darwin_claim_interface,
2470 .release_interface = darwin_release_interface,
2473 .destroy_device = darwin_destroy_device,
2475 .submit_transfer = darwin_submit_transfer,
2476 .cancel_transfer = darwin_cancel_transfer,
2478 .handle_transfer_completion = darwin_handle_transfer_completion,
2480 .device_priv_size = sizeof(struct darwin_device_priv),
2481 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2482 .transfer_priv_size = sizeof(struct darwin_transfer_priv),