/* -*- Mode: C; indent-tabs-mode:nil -*- */
/*
 * darwin backend for libusb 1.0
 * Copyright © 2008-2021 Nathan Hjelm <hjelmn@cs.unm.edu>
 * Copyright © 2019-2021 Google LLC. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <config.h>
#include <assert.h>
#include <time.h>
#include <ctype.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/sysctl.h>

#include <mach/clock.h>
#include <mach/clock_types.h>
#include <mach/mach_host.h>
#include <mach/mach_port.h>

/* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
 * function. Its use is also conditionalized to only older deployment targets. */
#define OBJC_SILENCE_GC_DEPRECATIONS 1

/* Default timeout to 10s for reenumerate. This is needed because USBDeviceReEnumerate
 * does not return error status on macOS. */
#define DARWIN_REENUMERATE_TIMEOUT_US 10000000

#include <AvailabilityMacros.h>
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
  #include <objc/objc-auto.h>
#endif

#include "darwin_usb.h"

static int init_count = 0;

/* Both kIOMasterPortDefault or kIOMainPortDefault are synonyms for 0. */
static const mach_port_t darwin_default_master_port = 0;

/* async event thread */
static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t  libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;

#if !defined(HAVE_CLOCK_GETTIME)
static clock_serv_t clock_realtime;
static clock_serv_t clock_monotonic;
#endif

#define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)

static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */

static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
static struct list_head darwin_cached_devices;
static const char *darwin_device_class = "IOUSBDevice";

#define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)

/* async event thread */
static pthread_t libusb_darwin_at;

static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bool capture);
static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint);
static int darwin_reset_device(struct libusb_device_handle *dev_handle);
static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);

static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
                                             UInt64 old_session_id);

static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
                                                  UInt64 *old_session_id);

#if defined(ENABLE_LOGGING)
static const char *darwin_error_str (IOReturn result) {
  static char string_buffer[50];
  switch (result) {
  case kIOReturnSuccess:
    return "no error";
  case kIOReturnNotOpen:
    return "device not opened for exclusive access";
  case kIOReturnNoDevice:
    return "no connection to an IOService";
  case kIOUSBNoAsyncPortErr:
    return "no async port has been opened for interface";
  case kIOReturnExclusiveAccess:
    return "another process has device opened for exclusive access";
  case kIOUSBPipeStalled:
#if defined(kUSBHostReturnPipeStalled)
  case kUSBHostReturnPipeStalled:
#endif
    return "pipe is stalled";
  case kIOReturnError:
    return "could not establish a connection to the Darwin kernel";
  case kIOUSBTransactionTimeout:
    return "transaction timed out";
  case kIOReturnBadArgument:
    return "invalid argument";
  case kIOReturnAborted:
    return "transaction aborted";
  case kIOReturnNotResponding:
    return "device not responding";
  case kIOReturnOverrun:
    return "data overrun";
  case kIOReturnCannotWire:
    return "physical memory can not be wired down";
  case kIOReturnNoResources:
    return "out of resources";
  case kIOUSBHighSpeedSplitError:
    return "high speed split error";
  case kIOUSBUnknownPipeErr:
    return "pipe ref not recognized";
  default:
    snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
    return string_buffer;
  }
}
#endif

static enum libusb_error darwin_to_libusb (IOReturn result) {
  switch (result) {
  case kIOReturnUnderrun:
  case kIOReturnSuccess:
    return LIBUSB_SUCCESS;
  case kIOReturnNotOpen:
  case kIOReturnNoDevice:
    return LIBUSB_ERROR_NO_DEVICE;
  case kIOReturnExclusiveAccess:
    return LIBUSB_ERROR_ACCESS;
  case kIOUSBPipeStalled:
#if defined(kUSBHostReturnPipeStalled)
  case kUSBHostReturnPipeStalled:
#endif
    return LIBUSB_ERROR_PIPE;
  case kIOReturnBadArgument:
    return LIBUSB_ERROR_INVALID_PARAM;
  case kIOUSBTransactionTimeout:
    return LIBUSB_ERROR_TIMEOUT;
  case kIOUSBUnknownPipeErr:
    return LIBUSB_ERROR_NOT_FOUND;
  case kIOReturnNotResponding:
  case kIOReturnAborted:
  case kIOReturnError:
  case kIOUSBNoAsyncPortErr:
  default:
    return LIBUSB_ERROR_OTHER;
  }
}

/* this function must be called with the darwin_cached_devices_lock held */
static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
  cached_dev->refcount--;
  /* free the device and remove it from the cache */
  if (0 == cached_dev->refcount) {
    list_del(&cached_dev->list);

    if (cached_dev->device) {
      (*(cached_dev->device))->Release(cached_dev->device);
      cached_dev->device = NULL;
    }
    IOObjectRelease (cached_dev->service);
    free (cached_dev);
  }
}

static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
  cached_dev->refcount++;
}

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) {
  struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);

  /* current interface */
  struct darwin_interface *cInterface;

  uint8_t i, iface;

  struct libusb_context *ctx = HANDLE_CTX(dev_handle);

  usbi_dbg (ctx, "converting ep address 0x%02x to pipeRef and interface", ep);

  for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
    cInterface = &priv->interfaces[iface];

    if (dev_handle->claimed_interfaces & (1U << iface)) {
      for (i = 0 ; i < cInterface->num_endpoints ; i++) {
        if (cInterface->endpoint_addrs[i] == ep) {
          *pipep = i + 1;

          if (ifcp)
            *ifcp = iface;

          if (interface_out)
            *interface_out = cInterface;

          usbi_dbg (ctx, "pipe %d on interface %d matches", *pipep, iface);
          return LIBUSB_SUCCESS;
        }
      }
    }
  }

  /* No pipe found with the correct endpoint address */
  usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);

  return LIBUSB_ERROR_NOT_FOUND;
}

static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
  CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);

  if (!matchingDict)
    return kIOReturnError;

  if (location) {
    CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                                                         &kCFTypeDictionaryKeyCallBacks,
                                                                         &kCFTypeDictionaryValueCallBacks);

    /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
         internally (CFNumberType of locationID is kCFNumberSInt32Type) */
    CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);

    if (propertyMatchDict && locationCF) {
      CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
      CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
    }
    /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */

    /* release our references as per the Create Rule */
    if (propertyMatchDict)
      CFRelease (propertyMatchDict);
    if (locationCF)
      CFRelease (locationCF);
  }

  return IOServiceGetMatchingServices(darwin_default_master_port, matchingDict, deviceIterator);
}

/* Returns 1 on success, 0 on failure. */
static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
  CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
  Boolean success = 0;

  if (cfNumber) {
    if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
      success = CFNumberGetValue(cfNumber, type, p);
    }

    CFRelease (cfNumber);
  }

  return (success != 0);
}

/* Returns 1 on success, 0 on failure. */
static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
  CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
  bool success = false;

  if (cfData) {
    if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
      CFIndex length = CFDataGetLength (cfData);
      if (length < size) {
        size = length;
      }

      CFDataGetBytes (cfData, CFRangeMake(0, size), p);
      success = true;
    }

    CFRelease (cfData);
  }

  return success;
}

static usb_device_t **darwin_device_from_service (struct libusb_context *ctx, io_service_t service)
{
  io_cf_plugin_ref_t *plugInInterface = NULL;
  usb_device_t **device;
  IOReturn kresult;
  SInt32 score;
  const int max_retries = 5;

  /* The IOCreatePlugInInterfaceForService function might consistently return
     an "out of resources" error with certain USB devices the first time we run 
     it. The reason is still unclear, but retrying fixes the problem */
  for (int count = 0; count < max_retries; count++) {
    kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
                                                kIOCFPlugInInterfaceID, &plugInInterface,
                                                &score);
    if (kIOReturnSuccess == kresult && plugInInterface) {
      break;
    }

    usbi_dbg (ctx, "set up plugin for service retry: %s", darwin_error_str (kresult));

    /* sleep for a little while before trying again */
    nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
  }

  if (kIOReturnSuccess != kresult || !plugInInterface) {
    usbi_dbg (ctx, "could not set up plugin for service: %s", darwin_error_str (kresult));
    return NULL;
  }

  (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
                                           (LPVOID)&device);
  /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
  (*plugInInterface)->Release (plugInInterface);

  return device;
}

static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
  UNUSED(ptr);
  struct darwin_cached_device *cached_device;
  UInt64 old_session_id;
  struct libusb_context *ctx;
  io_service_t service;
  int ret;

  usbi_mutex_lock(&active_contexts_lock);

  while ((service = IOIteratorNext(add_devices))) {
    ret = darwin_get_cached_device (NULL, service, &cached_device, &old_session_id);
    if (ret < 0 || !cached_device->can_enumerate) {
      continue;
    }

    /* add this device to each active context's device list */
    for_each_context(ctx) {
      process_new_device (ctx, cached_device, old_session_id);
    }

    if (cached_device->in_reenumerate) {
      usbi_dbg (NULL, "cached device in reset state. reset complete...");
      cached_device->in_reenumerate = false;
    }

    IOObjectRelease(service);
  }

  usbi_mutex_unlock(&active_contexts_lock);
}

static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
  UNUSED(ptr);
  struct libusb_device *dev = NULL;
  struct libusb_context *ctx;
  struct darwin_cached_device *old_device;

  io_service_t device;
  UInt64 session, locationID;
  int ret;

  usbi_mutex_lock(&active_contexts_lock);

  while ((device = IOIteratorNext (rem_devices)) != 0) {
    bool is_reenumerating = false;

    /* get the location from the i/o registry */
    ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
    (void) get_ioregistry_value_number (device, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
    IOObjectRelease (device);
    if (!ret)
      continue;

    /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
       otherwise no cached device will ever get freed */
    usbi_mutex_lock(&darwin_cached_devices_lock);
    list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
      if (old_device->session == session) {
        if (old_device->in_reenumerate) {
          /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
           * will deref if needed. */
          usbi_dbg (NULL, "detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64,
                    session, locationID);

          /* the device object is no longer usable so go ahead and release it */
          if (old_device->device) {
            (*(old_device->device))->Release(old_device->device);
            old_device->device = NULL;
          }

          is_reenumerating = true;
        } else {
          darwin_deref_cached_device (old_device);
        }

        break;
      }
    }

    usbi_mutex_unlock(&darwin_cached_devices_lock);
    if (is_reenumerating) {
      continue;
    }

    for_each_context(ctx) {
      usbi_dbg (ctx, "notifying context %p of device disconnect", ctx);

      dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
      if (dev) {
        /* signal the core that this device has been disconnected. the core will tear down this device
           when the reference count reaches 0 */
        usbi_disconnect_device(dev);
        libusb_unref_device(dev);
      }
    }
  }

  usbi_mutex_unlock(&active_contexts_lock);
}

static void darwin_hotplug_poll (void)
{
  /* not sure if 1 ms will be too long/short but it should work ok */
  mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};

  /* since a kernel thread may notify the IOIterators used for
   * hotplug notification we can't just clear the iterators.
   * instead just wait until all IOService providers are quiet */
  (void) IOKitWaitQuiet (darwin_default_master_port, &timeout);
}

static void darwin_clear_iterator (io_iterator_t iter) {
  io_service_t device;

  while ((device = IOIteratorNext (iter)) != 0)
    IOObjectRelease (device);
}

static void darwin_fail_startup(void) {
  pthread_mutex_lock (&libusb_darwin_at_mutex);
  libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
  pthread_cond_signal (&libusb_darwin_at_cond);
  pthread_mutex_unlock (&libusb_darwin_at_mutex);
  pthread_exit (NULL);
}

static void *darwin_event_thread_main (void *arg0) {
  IOReturn kresult;
  struct libusb_context *ctx = (struct libusb_context *)arg0;
  CFRunLoopRef runloop;
  CFRunLoopSourceRef libusb_shutdown_cfsource;
  CFRunLoopSourceContext libusb_shutdown_cfsourcectx;

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
  /* Set this thread's name, so it can be seen in the debugger
     and crash reports. */
  pthread_setname_np ("org.libusb.device-hotplug");
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
  /* Tell the Objective-C garbage collector about this thread.
     This is required because, unlike NSThreads, pthreads are
     not automatically registered. Although we don't use
     Objective-C, we use CoreFoundation, which does.
     Garbage collection support was entirely removed in 10.12,
     so don't bother there. */
  objc_registerThreadWithCollector();
#endif

  /* hotplug (device arrival/removal) sources */
  CFRunLoopSourceRef     libusb_notification_cfsource;
  io_notification_port_t libusb_notification_port;
  io_iterator_t          libusb_rem_device_iterator;
  io_iterator_t          libusb_add_device_iterator;

  usbi_dbg (ctx, "creating hotplug event source");

  runloop = CFRunLoopGetCurrent ();
  CFRetain (runloop);

  /* add the shutdown cfsource to the run loop */
  memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
  libusb_shutdown_cfsourcectx.info = runloop;
  libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
  libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
  CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);

  /* add the notification port to the run loop */
  libusb_notification_port     = IONotificationPortCreate (darwin_default_master_port);
  libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
  CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);

  /* create notifications for removed devices */
  kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
                                              IOServiceMatching(darwin_device_class),
                                              darwin_devices_detached,
                                              ctx, &libusb_rem_device_iterator);

  if (kresult != kIOReturnSuccess) {
    usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
    CFRelease (libusb_shutdown_cfsource);
    CFRelease (runloop);
    darwin_fail_startup ();
  }

  /* create notifications for attached devices */
  kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
                                              IOServiceMatching(darwin_device_class),
                                              darwin_devices_attached,
                                              ctx, &libusb_add_device_iterator);

  if (kresult != kIOReturnSuccess) {
    usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
    CFRelease (libusb_shutdown_cfsource);
    CFRelease (runloop);
    darwin_fail_startup ();
  }

  /* arm notifiers */
  darwin_clear_iterator (libusb_rem_device_iterator);
  darwin_clear_iterator (libusb_add_device_iterator);

  usbi_dbg (ctx, "darwin event thread ready to receive events");

  /* signal the main thread that the hotplug runloop has been created. */
  pthread_mutex_lock (&libusb_darwin_at_mutex);
  libusb_darwin_acfl = runloop;
  libusb_darwin_acfls = libusb_shutdown_cfsource;
  pthread_cond_signal (&libusb_darwin_at_cond);
  pthread_mutex_unlock (&libusb_darwin_at_mutex);

  /* run the runloop */
  CFRunLoopRun();

  usbi_dbg (ctx, "darwin event thread exiting");

  /* signal the main thread that the hotplug runloop has finished. */
  pthread_mutex_lock (&libusb_darwin_at_mutex);
  libusb_darwin_acfls = NULL;
  libusb_darwin_acfl = NULL;
  pthread_cond_signal (&libusb_darwin_at_cond);
  pthread_mutex_unlock (&libusb_darwin_at_mutex);

  /* remove the notification cfsource */
  CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);

  /* remove the shutdown cfsource */
  CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);

  /* delete notification port */
  IONotificationPortDestroy (libusb_notification_port);

  /* delete iterators */
  IOObjectRelease (libusb_rem_device_iterator);
  IOObjectRelease (libusb_add_device_iterator);

  CFRelease (libusb_shutdown_cfsource);
  CFRelease (runloop);

  pthread_exit (NULL);
}

/* cleanup function to destroy cached devices */
static void darwin_cleanup_devices(void) {
  struct darwin_cached_device *dev, *next;

  list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
    darwin_deref_cached_device(dev);
  }
}

static int darwin_init(struct libusb_context *ctx) {
  bool first_init;
  int rc;

  first_init = (1 == ++init_count);

  do {
    if (first_init) {
      if (NULL == darwin_cached_devices.next) {
        list_init (&darwin_cached_devices);
      }
      assert(list_empty(&darwin_cached_devices));
#if !defined(HAVE_CLOCK_GETTIME)
      /* create the clocks that will be used if clock_gettime() is not available */
      host_name_port_t host_self;

      host_self = mach_host_self();
      host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
      host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
      mach_port_deallocate(mach_task_self(), host_self);
#endif
    }

    rc = darwin_scan_devices (ctx);
    if (LIBUSB_SUCCESS != rc)
      break;

    if (first_init) {
      rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
      if (0 != rc) {
        usbi_err (ctx, "could not create event thread, error %d", rc);
        rc = LIBUSB_ERROR_OTHER;
        break;
      }

      pthread_mutex_lock (&libusb_darwin_at_mutex);
      while (!libusb_darwin_acfl)
        pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
      if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
        libusb_darwin_acfl = NULL;
        rc = LIBUSB_ERROR_OTHER;
      }
      pthread_mutex_unlock (&libusb_darwin_at_mutex);

      if (0 != rc)
        pthread_join (libusb_darwin_at, NULL);
    }
  } while (0);

  if (LIBUSB_SUCCESS != rc) {
    if (first_init) {
      darwin_cleanup_devices ();
#if !defined(HAVE_CLOCK_GETTIME)
      mach_port_deallocate(mach_task_self(), clock_realtime);
      mach_port_deallocate(mach_task_self(), clock_monotonic);
#endif
    }
    --init_count;
  }

  return rc;
}

static void darwin_exit (struct libusb_context *ctx) {
  UNUSED(ctx);

  if (0 == --init_count) {
    /* stop the event runloop and wait for the thread to terminate. */
    pthread_mutex_lock (&libusb_darwin_at_mutex);
    CFRunLoopSourceSignal (libusb_darwin_acfls);
    CFRunLoopWakeUp (libusb_darwin_acfl);
    while (libusb_darwin_acfl)
      pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
    pthread_mutex_unlock (&libusb_darwin_at_mutex);
    pthread_join (libusb_darwin_at, NULL);

    darwin_cleanup_devices ();

#if !defined(HAVE_CLOCK_GETTIME)
    mach_port_deallocate(mach_task_self(), clock_realtime);
    mach_port_deallocate(mach_task_self(), clock_monotonic);
#endif
  }
}

static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
  struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
  UInt8 i, numConfig;
  IOUSBConfigurationDescriptorPtr desc;
  IOReturn kresult;

  /* is there a simpler way to determine the index? */
  kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
  if (kresult != kIOReturnSuccess)
    return darwin_to_libusb (kresult);

  for (i = 0 ; i < numConfig ; i++) {
    (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);

    if (desc->bConfigurationValue == config_value)
      return i;
  }

  /* configuration not found */
  return LIBUSB_ERROR_NOT_FOUND;
}

static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
  struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
  int config_index;

  if (0 == priv->active_config)
    return LIBUSB_ERROR_NOT_FOUND;

  config_index = get_configuration_index (dev, priv->active_config);
  if (config_index < 0)
    return config_index;

  assert(config_index >= 0 && config_index <= UINT8_MAX);
  return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
}

static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
  struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
  IOUSBConfigurationDescriptorPtr desc;
  IOReturn kresult;
  int ret;

  if (!priv || !priv->device)
    return LIBUSB_ERROR_OTHER;

  kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
  if (kresult == kIOReturnSuccess) {
    /* copy descriptor */
    if (libusb_le16_to_cpu(desc->wTotalLength) < len)
      len = libusb_le16_to_cpu(desc->wTotalLength);

    memmove (buffer, desc, len);
  }

  ret = darwin_to_libusb (kresult);
  if (ret != LIBUSB_SUCCESS)
    return ret;

  return (int) len;
}

/* check whether the os has configured the device */
static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
  usb_device_t **darwin_device = dev->device;

  IOUSBConfigurationDescriptorPtr configDesc;
  IOUSBFindInterfaceRequest request;
  IOReturn                  kresult;
  io_iterator_t             interface_iterator;
  io_service_t              firstInterface;

  if (dev->dev_descriptor.bNumConfigurations < 1) {
    usbi_err (ctx, "device has no configurations");
    return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
  }

  /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
     not usable anyway */
  if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
      0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
    usbi_dbg (ctx, "ignoring configuration on root hub simulation");
    dev->active_config = 0;
    return LIBUSB_SUCCESS;
  }

  /* find the first configuration */
  kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
  dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;

  /* check if the device is already configured. there is probably a better way than iterating over the
     to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
     might lock up on the device request) */

  /* Setup the Interface Request */
  request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
  request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
  request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
  request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;

  kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
  if (kresult != kIOReturnSuccess)
    return darwin_to_libusb (kresult);

  /* iterate once */
  firstInterface = IOIteratorNext(interface_iterator);

  /* done with the interface iterator */
  IOObjectRelease(interface_iterator);

  if (firstInterface) {
    IOObjectRelease (firstInterface);

    /* device is configured */
    if (dev->dev_descriptor.bNumConfigurations == 1)
      /* to avoid problems with some devices get the configurations value from the configuration descriptor */
      dev->active_config = dev->first_config;
    else
      /* devices with more than one configuration should work with GetConfiguration */
      (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
  } else
    /* not configured */
    dev->active_config = 0;

  usbi_dbg (ctx, "active config: %u, first config: %u", dev->active_config, dev->first_config);

  return LIBUSB_SUCCESS;
}

static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
  IOUSBDevRequestTO req;

  assert(buffer_size <= UINT16_MAX);

  memset (buffer, 0, buffer_size);

  /* Set up request for descriptor/ */
  req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
  req.bRequest      = kUSBRqGetDescriptor;
  req.wValue        = (UInt16)(desc << 8);
  req.wIndex        = desc_index;
  req.wLength       = (UInt16)buffer_size;
  req.pData         = buffer;
  req.noDataTimeout = 20;
  req.completionTimeout = 100;

  return (*device)->DeviceRequestTO (device, &req);
}

static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) {
  usb_device_t **device = dev->device;
  int retries = 1;
  long delay = 30000; // microseconds
  int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
  int is_open = 0;
  IOReturn ret = 0, ret2;
  UInt8 bDeviceClass;
  UInt16 idProduct, idVendor;

  dev->can_enumerate = 0;

  (*device)->GetDeviceClass (device, &bDeviceClass);
  (*device)->GetDeviceProduct (device, &idProduct);
  (*device)->GetDeviceVendor (device, &idVendor);

  /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
   * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request.  Still,
   * to follow the spec as closely as possible, try opening the device */
  is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);

  do {
    /**** retrieve device descriptor ****/
    ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));

    if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
      /* received an overrun error but we still received a device descriptor */
      ret = kIOReturnSuccess;

    if (kIOUSBVendorIDAppleComputer == idVendor) {
      /* NTH: don't bother retrying or unsuspending Apple devices */
      break;
    }

    if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
                                    0 == dev->dev_descriptor.bcdUSB)) {
      /* work around for incorrectly configured devices */
      if (try_reconfigure && is_open) {
        usbi_dbg(ctx, "descriptor appears to be invalid. resetting configuration before trying again...");

        /* set the first configuration */
        (*device)->SetConfiguration(device, 1);

        /* don't try to reconfigure again */
        try_reconfigure = 0;
      }

      ret = kIOUSBPipeStalled;
    }

    if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
      /* device may be suspended. unsuspend it and try again */
#if DeviceVersion >= 320
      UInt32 info = 0;

      /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
      (void)(*device)->GetUSBDeviceInformation (device, &info);

      /* note that the device was suspended */
      if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
        try_unsuspend = 1;
#endif

      if (try_unsuspend) {
        /* try to unsuspend the device */
        ret2 = (*device)->USBDeviceSuspend (device, 0);
        if (kIOReturnSuccess != ret2) {
          /* prevent log spew from poorly behaving devices.  this indicates the
             os actually had trouble communicating with the device */
          usbi_dbg(ctx, "could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
        } else
          unsuspended = 1;

        try_unsuspend = 0;
      }
    }

    if (kIOReturnSuccess != ret) {
      usbi_dbg(ctx, "kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
      /* sleep for a little while before trying again */
      nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
    }
  } while (kIOReturnSuccess != ret && retries--);

  if (unsuspended)
    /* resuspend the device */
    (void)(*device)->USBDeviceSuspend (device, 1);

  if (is_open)
    (void) (*device)->USBDeviceClose (device);

  if (ret != kIOReturnSuccess) {
    /* a debug message was already printed out for this error */
    if (LIBUSB_CLASS_HUB == bDeviceClass)
      usbi_dbg (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
                idVendor, idProduct, darwin_error_str (ret), ret);
    else
      usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
                 idVendor, idProduct, darwin_error_str (ret), ret);
    return darwin_to_libusb (ret);
  }

  /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
  if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
    /* not a valid device */
    usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
               idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
    return LIBUSB_ERROR_NO_DEVICE;
  }

  usbi_dbg (ctx, "cached device descriptor:");
  usbi_dbg (ctx, "  bDescriptorType:    0x%02x", dev->dev_descriptor.bDescriptorType);
  usbi_dbg (ctx, "  bcdUSB:             0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
  usbi_dbg (ctx, "  bDeviceClass:       0x%02x", dev->dev_descriptor.bDeviceClass);
  usbi_dbg (ctx, "  bDeviceSubClass:    0x%02x", dev->dev_descriptor.bDeviceSubClass);
  usbi_dbg (ctx, "  bDeviceProtocol:    0x%02x", dev->dev_descriptor.bDeviceProtocol);
  usbi_dbg (ctx, "  bMaxPacketSize0:    0x%02x", dev->dev_descriptor.bMaxPacketSize0);
  usbi_dbg (ctx, "  idVendor:           0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
  usbi_dbg (ctx, "  idProduct:          0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
  usbi_dbg (ctx, "  bcdDevice:          0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
  usbi_dbg (ctx, "  iManufacturer:      0x%02x", dev->dev_descriptor.iManufacturer);
  usbi_dbg (ctx, "  iProduct:           0x%02x", dev->dev_descriptor.iProduct);
  usbi_dbg (ctx, "  iSerialNumber:      0x%02x", dev->dev_descriptor.iSerialNumber);
  usbi_dbg (ctx, "  bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);

  dev->can_enumerate = 1;

  return LIBUSB_SUCCESS;
}

/* Returns 1 on success, 0 on failure. */
static bool get_device_port (io_service_t service, UInt8 *port) {
  IOReturn kresult;
  io_service_t parent;
  bool ret = false;

  if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
    return true;
  }

  kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
  if (kIOReturnSuccess == kresult) {
    ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
    IOObjectRelease (parent);
  }

  return ret;
}

/* Returns 1 on success, 0 on failure. */
static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
  IOReturn kresult;
  io_service_t parent;

  /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
  parent = service;
  while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
    if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
        /* Success */
        return true;
    }
  }

  /* We ran out of parents */
  return false;
}

static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
                                                  UInt64 *old_session_id) {
  struct darwin_cached_device *new_device;
  UInt64 sessionID = 0, parent_sessionID = 0;
  UInt32 locationID = 0;
  enum libusb_error ret = LIBUSB_SUCCESS;
  usb_device_t **device;
  UInt8 port = 0;

  /* assuming sessionID != 0 normally (never seen it be 0) */
  *old_session_id = 0;
  *cached_out = NULL;

  /* get some info from the io registry */
  (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
  (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
  if (!get_device_port (service, &port)) {
    usbi_dbg(ctx, "could not get connected port number");
  }

  usbi_dbg(ctx, "finding cached device for sessionID 0x%" PRIx64, sessionID);

  if (get_device_parent_sessionID(service, &parent_sessionID)) {
    usbi_dbg(ctx, "parent sessionID: 0x%" PRIx64, parent_sessionID);
  }

  usbi_mutex_lock(&darwin_cached_devices_lock);
  do {
    list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
      usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
               sessionID, locationID, new_device->session, new_device->location);
      if (new_device->location == locationID && new_device->in_reenumerate) {
        usbi_dbg (ctx, "found cached device with matching location that is being re-enumerated");
        *old_session_id = new_device->session;
        break;
      }

      if (new_device->session == sessionID) {
        usbi_dbg(ctx, "using cached device for device");
        *cached_out = new_device;
        break;
      }
    }

    if (*cached_out)
      break;

    usbi_dbg(ctx, "caching new device with sessionID 0x%" PRIx64, sessionID);

    device = darwin_device_from_service (ctx, service);
    if (!device) {
      ret = LIBUSB_ERROR_NO_DEVICE;
      break;
    }

    if (!(*old_session_id)) {
      new_device = calloc (1, sizeof (*new_device));
      if (!new_device) {
        ret = LIBUSB_ERROR_NO_MEM;
        break;
      }

      /* add this device to the cached device list */
      list_add(&new_device->list, &darwin_cached_devices);

      (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);

      /* keep a reference to this device */
      darwin_ref_cached_device(new_device);

      (*device)->GetLocationID (device, &new_device->location);
      new_device->port = port;
      new_device->parent_session = parent_sessionID;
    } else {
      /* release the ref to old device's service */
      IOObjectRelease (new_device->service);
    }

    /* keep track of devices regardless of if we successfully enumerate them to
       prevent them from being enumerated multiple times */
    *cached_out = new_device;

    new_device->session = sessionID;
    new_device->device = device;
    new_device->service = service;

    /* retain the service */
    IOObjectRetain (service);

    /* cache the device descriptor */
    ret = darwin_cache_device_descriptor(ctx, new_device);
    if (ret)
      break;

    if (new_device->can_enumerate) {
      snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
               libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
               libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
               new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
    }
  } while (0);

  usbi_mutex_unlock(&darwin_cached_devices_lock);

  return ret;
}

static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
                                             UInt64 old_session_id) {
  struct darwin_device_priv *priv;
  struct libusb_device *dev = NULL;
  UInt8 devSpeed;
  enum libusb_error ret = LIBUSB_SUCCESS;

  do {
    /* check current active configuration (and cache the first configuration value--
       which may be used by claim_interface) */
    ret = darwin_check_configuration (ctx, cached_device);
    if (ret)
      break;

    if (0 != old_session_id) {
      usbi_dbg (ctx, "re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
                ctx, old_session_id, cached_device->session);
      /* save the libusb device before the session id is updated */
      dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
    }

    if (!dev) {
      usbi_dbg (ctx, "allocating new device in context %p for with session 0x%" PRIx64,
                ctx, cached_device->session);

      dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
      if (!dev) {
        return LIBUSB_ERROR_NO_MEM;
      }

      priv = usbi_get_device_priv(dev);

      priv->dev = cached_device;
      darwin_ref_cached_device (priv->dev);
      dev->port_number    = cached_device->port;
      /* the location ID encodes the path to the device. the top byte of the location ID contains the bus number
         (numbered from 0). the remaining bytes can be used to construct the device tree for that bus. */
      dev->bus_number     = cached_device->location >> 24;
      assert(cached_device->address <= UINT8_MAX);
      dev->device_address = (uint8_t)cached_device->address;
    } else {
      priv = usbi_get_device_priv(dev);
    }

    static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
                  "mismatch between libusb and IOKit device descriptor sizes");
    memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
    usbi_localize_device_descriptor(&dev->device_descriptor);
    dev->session_data = cached_device->session;

    if (NULL != dev->parent_dev) {
      libusb_unref_device(dev->parent_dev);
      dev->parent_dev = NULL;
    }

    if (cached_device->parent_session > 0) {
      dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
    }

    (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);

    switch (devSpeed) {
    case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
    case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
    case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
    case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
    case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
#endif
    default:
      usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
    }

    ret = usbi_sanitize_device (dev);
    if (ret < 0)
      break;

    usbi_dbg (ctx, "found device with address %d port = %d parent = %p at %p", dev->device_address,
              dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);

  } while (0);

  if (!cached_device->in_reenumerate && 0 == ret) {
    usbi_connect_device (dev);
  } else {
    libusb_unref_device (dev);
  }

  return ret;
}

static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
  struct darwin_cached_device *cached_device;
  UInt64 old_session_id;
  io_iterator_t deviceIterator;
  io_service_t service;
  IOReturn kresult;
  int ret;

  kresult = usb_setup_device_iterator (&deviceIterator, 0);
  if (kresult != kIOReturnSuccess)
    return darwin_to_libusb (kresult);

  while ((service = IOIteratorNext (deviceIterator))) {
    ret = darwin_get_cached_device (ctx, service, &cached_device, &old_session_id);
    if (ret < 0 || !cached_device->can_enumerate) {
      continue;
    }

    (void) process_new_device (ctx, cached_device, old_session_id);

    IOObjectRelease(service);
  }

  IOObjectRelease(deviceIterator);

  return LIBUSB_SUCCESS;
}

static int darwin_open (struct libusb_device_handle *dev_handle) {
  struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  IOReturn kresult;

  if (0 == dpriv->open_count) {
    /* try to open the device */
    kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
    if (kresult != kIOReturnSuccess) {
      usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));

      if (kIOReturnExclusiveAccess != kresult) {
        return darwin_to_libusb (kresult);
      }

      /* it is possible to perform some actions on a device that is not open so do not return an error */
      priv->is_open = false;
    } else {
      priv->is_open = true;
    }

    /* create async event source */
    kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
    if (kresult != kIOReturnSuccess) {
      usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));

      if (priv->is_open) {
        (*(dpriv->device))->USBDeviceClose (dpriv->device);
      }

      priv->is_open = false;

      return darwin_to_libusb (kresult);
    }

    CFRetain (libusb_darwin_acfl);

    /* add the cfSource to the async run loop */
    CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
  }

  /* device opened successfully */
  dpriv->open_count++;

  usbi_dbg (HANDLE_CTX(dev_handle), "device open for access");

  return 0;
}

static void darwin_close (struct libusb_device_handle *dev_handle) {
  struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  IOReturn kresult;
  int i;

  if (dpriv->open_count == 0) {
    /* something is probably very wrong if this is the case */
    usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
    return;
  }

  dpriv->open_count--;
  if (NULL == dpriv->device) {
    usbi_warn (HANDLE_CTX (dev_handle), "darwin_close device missing IOService");
    return;
  }

  /* make sure all interfaces are released */
  for (i = 0 ; i < USB_MAXINTERFACES ; i++)
    if (dev_handle->claimed_interfaces & (1U << i))
      libusb_release_interface (dev_handle, i);

  if (0 == dpriv->open_count) {
    /* delete the device's async event source */
    if (priv->cfSource) {
      CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
      CFRelease (priv->cfSource);
      priv->cfSource = NULL;
      CFRelease (libusb_darwin_acfl);
    }

    if (priv->is_open) {
      /* close the device */
      kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
      if (kresult != kIOReturnSuccess) {
        /* Log the fact that we had a problem closing the file, however failing a
         * close isn't really an error, so return success anyway */
        usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
      }
    }
  }
}

static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);

  *config = dpriv->active_config;

  return LIBUSB_SUCCESS;
}

static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  IOReturn kresult;
  uint8_t i;

  if (config == -1)
    config = 0;

  /* Setting configuration will invalidate the interface, so we need
     to reclaim it. First, dispose of existing interfaces, if any. */
  for (i = 0 ; i < USB_MAXINTERFACES ; i++)
    if (dev_handle->claimed_interfaces & (1U << i))
      darwin_release_interface (dev_handle, i);

  kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
  if (kresult != kIOReturnSuccess)
    return darwin_to_libusb (kresult);

  /* Reclaim any interfaces. */
  for (i = 0 ; i < USB_MAXINTERFACES ; i++)
    if (dev_handle->claimed_interfaces & (1U << i))
      darwin_claim_interface (dev_handle, i);

  dpriv->active_config = (UInt8)config;

  return LIBUSB_SUCCESS;
}

static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
  IOUSBFindInterfaceRequest request;
  IOReturn                  kresult;
  io_iterator_t             interface_iterator;
  UInt8                     bInterfaceNumber;
  bool                      ret;

  *usbInterfacep = IO_OBJECT_NULL;

  /* Setup the Interface Request */
  request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
  request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
  request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
  request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;

  kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
  if (kresult != kIOReturnSuccess)
    return kresult;

  while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
    /* find the interface number */
    ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
                                       &bInterfaceNumber);

    if (ret && bInterfaceNumber == ifc) {
      break;
    }

    (void) IOObjectRelease (*usbInterfacep);
  }

  /* done with the interface iterator */
  IOObjectRelease(interface_iterator);

  return kIOReturnSuccess;
}

static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
  struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);

  /* current interface */
  struct darwin_interface *cInterface = &priv->interfaces[iface];

  IOReturn kresult;

  UInt8 numep, direction, number;
  UInt8 dont_care1, dont_care3;
  UInt16 dont_care2;
  int rc;
  struct libusb_context *ctx = HANDLE_CTX (dev_handle);


  usbi_dbg (ctx, "building table of endpoints.");

  /* retrieve the total number of endpoints on this interface */
  kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
  if (kresult != kIOReturnSuccess) {
    usbi_err (ctx, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
    return darwin_to_libusb (kresult);
  }

  /* iterate through pipe references */
  for (UInt8 i = 1 ; i <= numep ; i++) {
    kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
                                                            &dont_care2, &dont_care3);

    if (kresult != kIOReturnSuccess) {
      /* probably a buggy device. try to get the endpoint address from the descriptors */
      struct libusb_config_descriptor *config;
      const struct libusb_endpoint_descriptor *endpoint_desc;
      UInt8 alt_setting;

      kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
      if (kresult != kIOReturnSuccess) {
        usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
        return darwin_to_libusb (kresult);
      }

      rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
      if (LIBUSB_SUCCESS != rc) {
        return rc;
      }

      endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;

      cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
    } else {
      cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
    }

    usbi_dbg (ctx, "interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
              cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
  }

  cInterface->num_endpoints = numep;

  return LIBUSB_SUCCESS;
}

static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
  io_service_t          usbInterface = IO_OBJECT_NULL;
  IOReturn              kresult;
  enum libusb_error     ret;
  IOCFPlugInInterface **plugInInterface = NULL;
  SInt32                score;

  /* current interface */
  struct darwin_interface *cInterface = &priv->interfaces[iface];

  struct libusb_context *ctx = HANDLE_CTX (dev_handle);

  kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
  if (kresult != kIOReturnSuccess)
    return darwin_to_libusb (kresult);

  /* make sure we have an interface */
  if (!usbInterface && dpriv->first_config != 0) {
    usbi_info (ctx, "no interface found; setting configuration: %d", dpriv->first_config);

    /* set the configuration */
    ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
    if (ret != LIBUSB_SUCCESS) {
      usbi_err (ctx, "could not set configuration");
      return ret;
    }

    kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
    if (kresult != kIOReturnSuccess) {
      usbi_err (ctx, "darwin_get_interface: %s", darwin_error_str(kresult));
      return darwin_to_libusb (kresult);
    }
  }

  if (!usbInterface) {
    usbi_info (ctx, "interface not found");
    return LIBUSB_ERROR_NOT_FOUND;
  }

  /* get an interface to the device's interface */
  kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
                                               kIOCFPlugInInterfaceID, &plugInInterface, &score);

  /* ignore release error */
  (void)IOObjectRelease (usbInterface);

  if (kresult != kIOReturnSuccess) {
    usbi_err (ctx, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
    return darwin_to_libusb (kresult);
  }

  if (!plugInInterface) {
    usbi_err (ctx, "plugin interface not found");
    return LIBUSB_ERROR_NOT_FOUND;
  }

  /* Do the actual claim */
  kresult = (*plugInInterface)->QueryInterface(plugInInterface,
                                               CFUUIDGetUUIDBytes(InterfaceInterfaceID),
                                               (LPVOID)&cInterface->interface);
  /* We no longer need the intermediate plug-in */
  /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
  (*plugInInterface)->Release (plugInInterface);
  if (kresult != kIOReturnSuccess || !cInterface->interface) {
    usbi_err (ctx, "QueryInterface: %s", darwin_error_str(kresult));
    return darwin_to_libusb (kresult);
  }

  /* claim the interface */
  kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
  if (kresult != kIOReturnSuccess) {
    usbi_info (ctx, "USBInterfaceOpen: %s", darwin_error_str(kresult));
    return darwin_to_libusb (kresult);
  }

  /* update list of endpoints */
  ret = get_endpoints (dev_handle, iface);
  if (ret) {
    /* this should not happen */
    darwin_release_interface (dev_handle, iface);
    usbi_err (ctx, "could not build endpoint table");
    return ret;
  }

  cInterface->cfSource = NULL;

  /* create async event source */
  kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
  if (kresult != kIOReturnSuccess) {
    usbi_err (ctx, "could not create async event source");

    /* can't continue without an async event source */
    (void)darwin_release_interface (dev_handle, iface);

    return darwin_to_libusb (kresult);
  }

  /* add the cfSource to the async thread's run loop */
  CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);

  usbi_dbg (ctx, "interface opened");

  return LIBUSB_SUCCESS;
}

static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
  struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
  IOReturn kresult;

  /* current interface */
  struct darwin_interface *cInterface = &priv->interfaces[iface];

  /* Check to see if an interface is open */
  if (!cInterface->interface)
    return LIBUSB_SUCCESS;

  /* clean up endpoint data */
  cInterface->num_endpoints = 0;

  /* delete the interface's async event source */
  if (cInterface->cfSource) {
    CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
    CFRelease (cInterface->cfSource);
    cInterface->cfSource = NULL;
  }

  kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
  if (kresult != kIOReturnSuccess)
    usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));

  kresult = (*(cInterface->interface))->Release(cInterface->interface);
  if (kresult != kIOReturnSuccess)
    usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));

  cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;

  return darwin_to_libusb (kresult);
}

static int check_alt_setting_and_clear_halt(struct libusb_device_handle *dev_handle, uint8_t altsetting, struct darwin_interface *cInterface) {
  enum libusb_error ret;
  IOReturn kresult;
  uint8_t current_alt_setting;

  kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &current_alt_setting);
  if (kresult == kIOReturnSuccess && altsetting != current_alt_setting) {
    return LIBUSB_ERROR_PIPE;
  }

  for (int i = 0 ; i < cInterface->num_endpoints ; i++) {
    ret = darwin_clear_halt(dev_handle, cInterface->endpoint_addrs[i]);
    if (LIBUSB_SUCCESS != ret) {
      usbi_warn(HANDLE_CTX (dev_handle), "error clearing pipe halt for endpoint %d", i);
      if (LIBUSB_ERROR_NOT_FOUND == ret) {
        /* may need to re-open the interface */
        return ret;
      }
    }
  }

  return LIBUSB_SUCCESS;
}

static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
  struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
  IOReturn kresult;
  enum libusb_error ret;

  /* current interface */
  struct darwin_interface *cInterface = &priv->interfaces[iface];

  if (!cInterface->interface)
    return LIBUSB_ERROR_NO_DEVICE;

  kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
  if (kresult == kIOReturnSuccess) {
    /* update the list of endpoints */
    ret = get_endpoints (dev_handle, iface);
    if (ret) {
      /* this should not happen */
      darwin_release_interface (dev_handle, iface);
      usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
    }
    return ret;
  }

  usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));

  ret = darwin_to_libusb(kresult);
  if (ret != LIBUSB_ERROR_PIPE) {
    return ret;
  }

  /* If a device only supports a default setting for the specified interface, then a STALL
     (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
     Mimic the behaviour in e.g. the Linux kernel: in such case, reset all endpoints
     of the interface (as would have been done per 9.1.1.5) and return success. */

  ret = check_alt_setting_and_clear_halt(dev_handle, altsetting, cInterface);
  if (LIBUSB_ERROR_NOT_FOUND == ret) {
    /* For some reason we need to reclaim the interface after the pipe error with some versions of macOS */
    ret = darwin_claim_interface (dev_handle, iface);
    if (LIBUSB_SUCCESS != ret) {
      darwin_release_interface (dev_handle, iface);
      usbi_err (HANDLE_CTX (dev_handle), "could not reclaim interface: %s", darwin_error_str(kresult));
    }
    ret = check_alt_setting_and_clear_halt(dev_handle, altsetting, cInterface);
  }

  return ret;
}

static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
  /* current interface */
  struct darwin_interface *cInterface;
  IOReturn kresult;
  uint8_t pipeRef;

  /* determine the interface/endpoint to use */
  if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
    usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");

    return LIBUSB_ERROR_NOT_FOUND;
  }

  /* newer versions of darwin support clearing additional bits on the device's endpoint */
  kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
  if (kresult != kIOReturnSuccess)
    usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));

  return darwin_to_libusb (kresult);
}

static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
                                 unsigned long claimed_interfaces) {
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
  int open_count = dpriv->open_count;
  int ret;

  struct libusb_context *ctx = HANDLE_CTX (dev_handle);

  /* clear claimed interfaces temporarily */
  dev_handle->claimed_interfaces = 0;

  /* close and re-open the device */
  priv->is_open = false;
  dpriv->open_count = 1;

  /* clean up open interfaces */
  (void) darwin_close (dev_handle);

  /* re-open the device */
  ret = darwin_open (dev_handle);
  dpriv->open_count = open_count;
  if (LIBUSB_SUCCESS != ret) {
    /* could not restore configuration */
    return LIBUSB_ERROR_NOT_FOUND;
  }

  if (dpriv->active_config != active_config) {
    usbi_dbg (ctx, "darwin/restore_state: restoring configuration %d...", active_config);

    ret = darwin_set_configuration (dev_handle, active_config);
    if (LIBUSB_SUCCESS != ret) {
      usbi_dbg (ctx, "darwin/restore_state: could not restore configuration");
      return LIBUSB_ERROR_NOT_FOUND;
    }
  }

  usbi_dbg (ctx, "darwin/restore_state: reclaiming interfaces");

  if (claimed_interfaces) {
    for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
      if (!(claimed_interfaces & (1U << iface))) {
        continue;
      }

      usbi_dbg (ctx, "darwin/restore_state: re-claiming interface %u", iface);

      ret = darwin_claim_interface (dev_handle, iface);
      if (LIBUSB_SUCCESS != ret) {
        usbi_dbg (ctx, "darwin/restore_state: could not claim interface %u", iface);
        return LIBUSB_ERROR_NOT_FOUND;
      }

      dev_handle->claimed_interfaces |= 1U << iface;
    }
  }

  usbi_dbg (ctx, "darwin/restore_state: device state restored");

  return LIBUSB_SUCCESS;
}

static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) {
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
  int8_t active_config = dpriv->active_config;
  UInt32 options = 0;
  IOUSBDeviceDescriptor descriptor;
  IOUSBConfigurationDescriptorPtr cached_configuration;
  IOUSBConfigurationDescriptor *cached_configurations;
  IOReturn kresult;
  UInt8 i;
  UInt32 time;

  struct libusb_context *ctx = HANDLE_CTX (dev_handle);

  if (dpriv->in_reenumerate) {
    /* ack, two (or more) threads are trying to reset the device! abort! */
    return LIBUSB_ERROR_NOT_FOUND;
  }

  dpriv->in_reenumerate = true;

  /* store copies of descriptors so they can be compared after the reset */
  memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
  cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);

  for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
    (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
    memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
  }

  /* if we need to release capture */
  if (HAS_CAPTURE_DEVICE()) {
    if (capture) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
      options |= kUSBReEnumerateCaptureDeviceMask;
#endif
    }
  } else {
    capture = false;
  }

  /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
  kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
  if (kresult != kIOReturnSuccess) {
    usbi_err (ctx, "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
    dpriv->in_reenumerate = false;
    return darwin_to_libusb (kresult);
  }

  /* capture mode does not re-enumerate but it does require re-open */
  if (capture) {
    usbi_dbg (ctx, "darwin/reenumerate_device: restoring state...");
    dpriv->in_reenumerate = false;
    return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
  }

  usbi_dbg (ctx, "darwin/reenumerate_device: waiting for re-enumeration to complete...");

  time = 0;
  while (dpriv->in_reenumerate) {
    struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
    nanosleep (&delay, NULL);
    if (time++ >= DARWIN_REENUMERATE_TIMEOUT_US) {
      usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate");
      dpriv->in_reenumerate = false;
      return LIBUSB_ERROR_TIMEOUT;
    }
  }

  /* compare descriptors */
  usbi_dbg (ctx, "darwin/reenumerate_device: checking whether descriptors changed");

  if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
    /* device descriptor changed. need to return not found. */
    usbi_dbg (ctx, "darwin/reenumerate_device: device descriptor changed");
    return LIBUSB_ERROR_NOT_FOUND;
  }

  for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
    (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
    if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
      usbi_dbg (ctx, "darwin/reenumerate_device: configuration descriptor %d changed", i);
      return LIBUSB_ERROR_NOT_FOUND;
    }
  }

  usbi_dbg (ctx, "darwin/reenumerate_device: device reset complete. restoring state...");

  return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
}

static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  IOReturn kresult;

  if (dpriv->capture_count > 0) {
    /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
    kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
    return darwin_to_libusb (kresult);
  } else {
    return darwin_reenumerate_device (dev_handle, false);
  }
}

static io_service_t usb_find_interface_matching_location (const io_name_t class_name, UInt8 interface_number, UInt32 location) {
  CFMutableDictionaryRef matchingDict = IOServiceMatching (class_name);
  CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault, 0,
                                                                        &kCFTypeDictionaryKeyCallBacks,
                                                                        &kCFTypeDictionaryValueCallBacks);
  CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
  CFTypeRef interfaceCF =  CFNumberCreate (NULL, kCFNumberSInt8Type, &interface_number);

  CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
  CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
  CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBHostMatchingPropertyInterfaceNumber), interfaceCF);

  CFRelease (interfaceCF);
  CFRelease (locationCF);
  CFRelease (propertyMatchDict);

  return IOServiceGetMatchingService (darwin_default_master_port, matchingDict);
}

static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  io_service_t usb_interface, child = IO_OBJECT_NULL;

  /* locate the IO registry entry for this interface */
  usb_interface = usb_find_interface_matching_location (kIOUSBHostInterfaceClassName, interface, dpriv->location);
  if (0 == usb_interface) {
    /* check for the legacy class entry */
    usb_interface = usb_find_interface_matching_location (kIOUSBInterfaceClassName, interface, dpriv->location);
    if (0 == usb_interface) {
      return LIBUSB_ERROR_NOT_FOUND;
    }
  }

  /* if the IO object has a child entry in the IO Registry it has a kernel driver attached */
  (void) IORegistryEntryGetChildEntry (usb_interface, kIOServicePlane, &child);
  IOObjectRelease (usb_interface);
  if (IO_OBJECT_NULL != child) {
    IOObjectRelease (child);
    return 1;
  }

  /* no driver */
  return 0;
}

static void darwin_destroy_device(struct libusb_device *dev) {
  struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);

  if (dpriv->dev) {
    /* need to hold the lock in case this is the last reference to the device */
    usbi_mutex_lock(&darwin_cached_devices_lock);
    darwin_deref_cached_device (dpriv->dev);
    dpriv->dev = NULL;
    usbi_mutex_unlock(&darwin_cached_devices_lock);
  }
}

static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);

  IOReturn               ret;
  uint8_t                transferType;
  uint8_t                pipeRef;
  uint16_t               maxPacketSize;

  struct darwin_interface *cInterface;
#if InterfaceVersion >= 550
  IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
#else
  /* None of the values below are used in libusb for bulk transfers */
  uint8_t                 direction, number, interval;
#endif

  if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
    usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");

    return LIBUSB_ERROR_NOT_FOUND;
  }

#if InterfaceVersion >= 550
  ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);

  transferType = pipeProperties.bTransferType;
  maxPacketSize = pipeProperties.wMaxPacketSize;
#else
  ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
                                                       &transferType, &maxPacketSize, &interval);
#endif

  if (ret) {
    usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
              darwin_error_str(ret), ret);
    return darwin_to_libusb (ret);
  }

  if (0 != (transfer->length % maxPacketSize)) {
    /* do not need a zero packet */
    transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
  }

  /* submit the request */
  /* timeouts are unavailable on interrupt endpoints */
  if (transferType == kUSBInterrupt) {
    if (IS_XFERIN(transfer))
      ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
                                                      (UInt32)transfer->length, darwin_async_io_callback, itransfer);
    else
      ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
                                                       (UInt32)transfer->length, darwin_async_io_callback, itransfer);
  } else {
    itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;

    if (IS_XFERIN(transfer))
      ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
                                                        (UInt32)transfer->length, transfer->timeout, transfer->timeout,
                                                        darwin_async_io_callback, itransfer);
    else
      ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
                                                         (UInt32)transfer->length, transfer->timeout, transfer->timeout,
                                                         darwin_async_io_callback, itransfer);
  }

  if (ret)
    usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
               darwin_error_str(ret), ret);

  return darwin_to_libusb (ret);
}

#if InterfaceVersion >= 550
static int submit_stream_transfer(struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
  struct darwin_interface *cInterface;
  uint8_t pipeRef;
  IOReturn ret;

  if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
    usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");

    return LIBUSB_ERROR_NOT_FOUND;
  }

  itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;

  if (IS_XFERIN(transfer))
    ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
                                                             transfer->buffer, (UInt32)transfer->length, transfer->timeout,
                                                             transfer->timeout, darwin_async_io_callback, itransfer);
  else
    ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
                                                              transfer->buffer, (UInt32)transfer->length, transfer->timeout,
                                                              transfer->timeout, darwin_async_io_callback, itransfer);

  if (ret)
    usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
               darwin_error_str(ret), ret);

  return darwin_to_libusb (ret);
}
#endif

static int submit_iso_transfer(struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
  struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);

  IOReturn kresult;
  uint8_t direction, number, interval, pipeRef, transferType;
  uint16_t maxPacketSize;
  UInt64 frame;
  AbsoluteTime atTime;
  int i;

  struct darwin_interface *cInterface;

  /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
  if (tpriv->num_iso_packets != transfer->num_iso_packets) {
    free(tpriv->isoc_framelist);
    tpriv->isoc_framelist = NULL;
  }

  if (!tpriv->isoc_framelist) {
    tpriv->num_iso_packets = transfer->num_iso_packets;
    tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
    if (!tpriv->isoc_framelist)
      return LIBUSB_ERROR_NO_MEM;
  }

  /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
  for (i = 0 ; i < transfer->num_iso_packets ; i++) {
    unsigned int length = transfer->iso_packet_desc[i].length;
    assert(length <= UINT16_MAX);
    tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
  }

  /* determine the interface/endpoint to use */
  if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
    usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");

    return LIBUSB_ERROR_NOT_FOUND;
  }

  /* determine the properties of this endpoint and the speed of the device */
  (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
                                                 &transferType, &maxPacketSize, &interval);

  /* Last but not least we need the bus frame number */
  kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
  if (kresult != kIOReturnSuccess) {
    usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
    free(tpriv->isoc_framelist);
    tpriv->isoc_framelist = NULL;

    return darwin_to_libusb (kresult);
  }

  (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
                                                 &transferType, &maxPacketSize, &interval);

  /* schedule for a frame a little in the future */
  frame += 4;

  if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
    frame = cInterface->frames[transfer->endpoint];

  /* submit the request */
  if (IS_XFERIN(transfer))
    kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
                                                             (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
                                                             itransfer);
  else
    kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
                                                              (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
                                                              itransfer);

  if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
    /* Full speed */
    cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
  else
    /* High/super speed */
    cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;

  if (kresult != kIOReturnSuccess) {
    usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
               darwin_error_str(kresult));
    free (tpriv->isoc_framelist);
    tpriv->isoc_framelist = NULL;
  }

  return darwin_to_libusb (kresult);
}

static int submit_control_transfer(struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
  struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
  struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);

  IOReturn               kresult;

  memset(&tpriv->req, 0, sizeof(tpriv->req));

  /* IOUSBDeviceInterface expects the request in cpu endianness */
  tpriv->req.bmRequestType     = setup->bmRequestType;
  tpriv->req.bRequest          = setup->bRequest;
  /* these values should be in bus order from libusb_fill_control_setup */
  tpriv->req.wValue            = OSSwapLittleToHostInt16 (setup->wValue);
  tpriv->req.wIndex            = OSSwapLittleToHostInt16 (setup->wIndex);
  tpriv->req.wLength           = OSSwapLittleToHostInt16 (setup->wLength);
  /* data is stored after the libusb control block */
  tpriv->req.pData             = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
  tpriv->req.completionTimeout = transfer->timeout;
  tpriv->req.noDataTimeout     = transfer->timeout;

  itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;

  /* all transfers in libusb-1.0 are async */

  if (transfer->endpoint) {
    struct darwin_interface *cInterface;
    uint8_t                 pipeRef;

    if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
      usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");

      return LIBUSB_ERROR_NOT_FOUND;
    }

    kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
  } else
    /* control request on endpoint 0 */
    kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);

  if (kresult != kIOReturnSuccess)
    usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));

  return darwin_to_libusb (kresult);
}

static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);

  switch (transfer->type) {
  case LIBUSB_TRANSFER_TYPE_CONTROL:
    return submit_control_transfer(itransfer);
  case LIBUSB_TRANSFER_TYPE_BULK:
  case LIBUSB_TRANSFER_TYPE_INTERRUPT:
    return submit_bulk_transfer(itransfer);
  case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
    return submit_iso_transfer(itransfer);
  case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
#if InterfaceVersion >= 550
    return submit_stream_transfer(itransfer);
#else
    usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
    return LIBUSB_ERROR_NOT_SUPPORTED;
#endif
  default:
    usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
    return LIBUSB_ERROR_INVALID_PARAM;
  }
}

static int cancel_control_transfer(struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
  IOReturn kresult;

  usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");

  if (!dpriv->device)
    return LIBUSB_ERROR_NO_DEVICE;

  kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);

  return darwin_to_libusb (kresult);
}

static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
  struct darwin_interface *cInterface;
  uint8_t pipeRef, iface;
  IOReturn kresult;

  struct libusb_context *ctx = ITRANSFER_CTX (itransfer);

  if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
    usbi_err (ctx, "endpoint not found on any open interface");

    return LIBUSB_ERROR_NOT_FOUND;
  }

  if (!dpriv->device)
    return LIBUSB_ERROR_NO_DEVICE;

  usbi_warn (ctx, "aborting all transactions on interface %d pipe %d", iface, pipeRef);

  /* abort transactions */
#if InterfaceVersion >= 550
  if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
    (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
  else
#endif
    (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);

  usbi_dbg (ctx, "calling clear pipe stall to clear the data toggle bit");

  /* newer versions of darwin support clearing additional bits on the device's endpoint */
  kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);

  return darwin_to_libusb (kresult);
}

static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);

  switch (transfer->type) {
  case LIBUSB_TRANSFER_TYPE_CONTROL:
    return cancel_control_transfer(itransfer);
  case LIBUSB_TRANSFER_TYPE_BULK:
  case LIBUSB_TRANSFER_TYPE_INTERRUPT:
  case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
    return darwin_abort_transfers (itransfer);
  default:
    usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
    return LIBUSB_ERROR_INVALID_PARAM;
  }
}

static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
  struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
  struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);

  usbi_dbg (TRANSFER_CTX(transfer), "an async io operation has completed");

  /* if requested write a zero packet */
  if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
    struct darwin_interface *cInterface;
    uint8_t pipeRef;

    (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);

    (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
  }

  tpriv->result = result;
  tpriv->size = (UInt32) (uintptr_t) arg0;

  /* signal the core that this transfer is complete */
  usbi_signal_transfer_completion(itransfer);
}

static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
  if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
    result = kIOUSBTransactionTimeout;

  struct libusb_context *ctx = ITRANSFER_CTX (itransfer);

  switch (result) {
  case kIOReturnUnderrun:
  case kIOReturnSuccess:
    return LIBUSB_TRANSFER_COMPLETED;
  case kIOReturnAborted:
    return LIBUSB_TRANSFER_CANCELLED;
  case kIOUSBPipeStalled:
    usbi_dbg (ctx, "transfer error: pipe is stalled");
    return LIBUSB_TRANSFER_STALL;
  case kIOReturnOverrun:
    usbi_warn (ctx, "transfer error: data overrun");
    return LIBUSB_TRANSFER_OVERFLOW;
  case kIOUSBTransactionTimeout:
    usbi_warn (ctx, "transfer error: timed out");
    itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
    return LIBUSB_TRANSFER_TIMED_OUT;
  default:
    usbi_warn (ctx, "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
    return LIBUSB_TRANSFER_ERROR;
  }
}

static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
  struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
  const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
  const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
  bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
  struct libusb_context *ctx = ITRANSFER_CTX (itransfer);

  if (transfer->type > max_transfer_type) {
    usbi_err (ctx, "unknown endpoint type %d", transfer->type);
    return LIBUSB_ERROR_INVALID_PARAM;
  }

  if (NULL == tpriv) {
    usbi_err (ctx, "malformed request is missing transfer priv");
    return LIBUSB_ERROR_INVALID_PARAM;
  }

  usbi_dbg (ctx, "handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);

  if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
    if (is_isoc && tpriv->isoc_framelist) {
      /* copy isochronous results back */

      for (int i = 0; i < transfer->num_iso_packets ; i++) {
        struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
        lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
        lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
      }
    } else if (!is_isoc) {
      itransfer->transferred += tpriv->size;
    }
  }

  /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
  return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
}

#if !defined(HAVE_CLOCK_GETTIME)
void usbi_get_monotonic_time(struct timespec *tp) {
  mach_timespec_t sys_time;

  /* use system boot time as reference for the monotonic clock */
  clock_get_time (clock_monotonic, &sys_time);

  tp->tv_sec  = sys_time.tv_sec;
  tp->tv_nsec = sys_time.tv_nsec;
}

void usbi_get_real_time(struct timespec *tp) {
  mach_timespec_t sys_time;

  /* CLOCK_REALTIME represents time since the epoch */
  clock_get_time (clock_realtime, &sys_time);

  tp->tv_sec  = sys_time.tv_sec;
  tp->tv_nsec = sys_time.tv_nsec;
}
#endif

#if InterfaceVersion >= 550
static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
                                 int num_endpoints) {
  struct darwin_interface *cInterface;
  UInt32 supportsStreams;
  uint8_t pipeRef;
  int rc, i;

  /* find the minimum number of supported streams on the endpoint list */
  for (i = 0 ; i < num_endpoints ; ++i) {
    if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
      return rc;
    }

    (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
    if (num_streams > supportsStreams)
      num_streams = supportsStreams;
  }

  /* it is an error if any endpoint in endpoints does not support streams */
  if (0 == num_streams)
    return LIBUSB_ERROR_INVALID_PARAM;

  /* create the streams */
  for (i = 0 ; i < num_endpoints ; ++i) {
    (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);

    rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
    if (kIOReturnSuccess != rc)
      return darwin_to_libusb(rc);
  }

  assert(num_streams <= INT_MAX);
  return (int)num_streams;
}

static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
  struct darwin_interface *cInterface;
  UInt32 supportsStreams;
  uint8_t pipeRef;
  int rc;

  for (int i = 0 ; i < num_endpoints ; ++i) {
    if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
      return rc;

    (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
    if (0 == supportsStreams)
      return LIBUSB_ERROR_INVALID_PARAM;

    rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
    if (kIOReturnSuccess != rc)
      return darwin_to_libusb(rc);
  }

  return LIBUSB_SUCCESS;
}
#endif

#if InterfaceVersion >= 700

/* macOS APIs for getting entitlement values */

#if TARGET_OS_OSX
#include <Security/Security.h>
#else
typedef struct __SecTask *SecTaskRef;
extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator);
extern CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error);
#endif

static bool darwin_has_capture_entitlements (void) {
  SecTaskRef task;
  CFTypeRef value;
  bool entitled;

  task = SecTaskCreateFromSelf (kCFAllocatorDefault);
  if (task == NULL) {
    return false;
  }
  value = SecTaskCopyValueForEntitlement(task, CFSTR("com.apple.vm.device-access"), NULL);
  CFRelease (task);
  entitled = value && (CFGetTypeID (value) == CFBooleanGetTypeID ()) && CFBooleanGetValue (value);
  if (value) {
    CFRelease (value);
  }
  return entitled;
}

static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  enum libusb_error err;

  usbi_mutex_lock(&darwin_cached_devices_lock);
  (*(dpriv->device))->Release(dpriv->device);
  dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
  if (!dpriv->device) {
    err = LIBUSB_ERROR_NO_DEVICE;
  } else {
    err = LIBUSB_SUCCESS;
  }
  usbi_mutex_unlock(&darwin_cached_devices_lock);

  return err;
}

/* On macOS, we capture an entire device at once, not individual interfaces. */

static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
  UNUSED(interface);
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  IOReturn kresult;
  enum libusb_error err;
  struct libusb_context *ctx = HANDLE_CTX (dev_handle);

  if (HAS_CAPTURE_DEVICE()) {
  } else {
    return LIBUSB_ERROR_NOT_SUPPORTED;
  }

  if (dpriv->capture_count == 0) {
    usbi_dbg (ctx, "attempting to detach kernel driver from device");

    if (darwin_has_capture_entitlements ()) {
      /* request authorization */
      kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
      if (kresult != kIOReturnSuccess) {
        usbi_warn (ctx, "IOServiceAuthorize: %s", darwin_error_str(kresult));
        return darwin_to_libusb (kresult);
      }

      /* we need start() to be called again for authorization status to refresh */
      err = darwin_reload_device (dev_handle);
      if (err != LIBUSB_SUCCESS) {
        return err;
      }
    } else {
      usbi_info (ctx, "no capture entitlements. may not be able to detach the kernel driver for this device");
      if (0 != geteuid()) {
        usbi_warn (ctx, "USB device capture requires either an entitlement (com.apple.vm.device-access) or root privilege");
        return LIBUSB_ERROR_ACCESS;
      }
    }

    /* reset device to release existing drivers */
    err = darwin_reenumerate_device (dev_handle, true);
    if (err != LIBUSB_SUCCESS) {
      return err;
    }
  }
  dpriv->capture_count++;
  return LIBUSB_SUCCESS;
}


static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
  UNUSED(interface);
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);

  if (HAS_CAPTURE_DEVICE()) {
  } else {
    return LIBUSB_ERROR_NOT_SUPPORTED;
  }

  dpriv->capture_count--;
  if (dpriv->capture_count > 0) {
    return LIBUSB_SUCCESS;
  }

  usbi_dbg (HANDLE_CTX (dev_handle), "reenumerating device for kernel driver attach");

  /* reset device to attach kernel drivers */
  return darwin_reenumerate_device (dev_handle, false);
}

static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
  enum libusb_error ret;
  if (dev_handle->auto_detach_kernel_driver && darwin_kernel_driver_active(dev_handle, iface)) {
    ret = darwin_detach_kernel_driver (dev_handle, iface);
    if (ret != LIBUSB_SUCCESS) {
      usbi_info (HANDLE_CTX (dev_handle), "failed to auto-detach the kernel driver for this device, ret=%d", ret);
    }
  }

  return darwin_claim_interface (dev_handle, iface);
}

static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
  enum libusb_error ret;
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);

  ret = darwin_release_interface (dev_handle, iface);
  if (ret != LIBUSB_SUCCESS) {
    return ret;
  }

  if (dev_handle->auto_detach_kernel_driver && dpriv->capture_count > 0) {
    ret = darwin_attach_kernel_driver (dev_handle, iface);
    if (LIBUSB_SUCCESS != ret) {
      usbi_info (HANDLE_CTX (dev_handle), "on attempt to reattach the kernel driver got ret=%d", ret);
    }
    /* ignore the error as the interface was successfully released */
  }

  return LIBUSB_SUCCESS;
}

#endif

const struct usbi_os_backend usbi_backend = {
        .name = "Darwin",
        .caps = USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
        .init = darwin_init,
        .exit = darwin_exit,
        .get_active_config_descriptor = darwin_get_active_config_descriptor,
        .get_config_descriptor = darwin_get_config_descriptor,
        .hotplug_poll = darwin_hotplug_poll,

        .open = darwin_open,
        .close = darwin_close,
        .get_configuration = darwin_get_configuration,
        .set_configuration = darwin_set_configuration,

        .set_interface_altsetting = darwin_set_interface_altsetting,
        .clear_halt = darwin_clear_halt,
        .reset_device = darwin_reset_device,

#if InterfaceVersion >= 550
        .alloc_streams = darwin_alloc_streams,
        .free_streams = darwin_free_streams,
#endif

        .kernel_driver_active = darwin_kernel_driver_active,

#if InterfaceVersion >= 700
        .detach_kernel_driver = darwin_detach_kernel_driver,
        .attach_kernel_driver = darwin_attach_kernel_driver,
        .claim_interface = darwin_capture_claim_interface,
        .release_interface = darwin_capture_release_interface,
#else
        .claim_interface = darwin_claim_interface,
        .release_interface = darwin_release_interface,
#endif

        .destroy_device = darwin_destroy_device,

        .submit_transfer = darwin_submit_transfer,
        .cancel_transfer = darwin_cancel_transfer,

        .handle_transfer_completion = darwin_handle_transfer_completion,

        .device_priv_size = sizeof(struct darwin_device_priv),
        .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
        .transfer_priv_size = sizeof(struct darwin_transfer_priv),
};
