• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
2 /*
3  * darwin backend for libusb 1.0
4  * Copyright © 2008-2021 Nathan Hjelm <hjelmn@cs.unm.edu>
5  * Copyright © 2019-2021 Google LLC. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <config.h>
23 #include <assert.h>
24 #include <time.h>
25 #include <ctype.h>
26 #include <pthread.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <sys/sysctl.h>
34 
35 #include <mach/clock.h>
36 #include <mach/clock_types.h>
37 #include <mach/mach_host.h>
38 #include <mach/mach_port.h>
39 
40 /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
41  * function. Its use is also conditionalized to only older deployment targets. */
42 #define OBJC_SILENCE_GC_DEPRECATIONS 1
43 
44 /* Default timeout to 10s for reenumerate. This is needed because USBDeviceReEnumerate
45  * does not return error status on macOS. */
46 #define DARWIN_REENUMERATE_TIMEOUT_US (10 * USEC_PER_SEC)
47 
48 #include <AvailabilityMacros.h>
49 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
50   #include <objc/objc-auto.h>
51 #endif
52 
53 #include "darwin_usb.h"
54 
55 static int init_count = 0;
56 
57 /* Both kIOMasterPortDefault or kIOMainPortDefault are synonyms for 0. */
58 static const mach_port_t darwin_default_master_port = 0;
59 
60 /* async event thread */
61 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
62 static pthread_cond_t  libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
63 
64 #if !defined(HAVE_CLOCK_GETTIME)
65 static clock_serv_t clock_realtime;
66 static clock_serv_t clock_monotonic;
67 #endif
68 
69 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
70 
71 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
72 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
73 
74 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
75 static struct list_head darwin_cached_devices;
76 static const char *darwin_device_class = "IOUSBDevice";
77 
78 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
79 
80 /* async event thread */
81 static pthread_t libusb_darwin_at;
82 
83 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
84 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
85 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
86 static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bool capture);
87 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint);
88 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
89 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface);
90 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
91 
92 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
93 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
94                                              UInt64 old_session_id);
95 
96 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
97                                                   UInt64 *old_session_id);
98 
99 #if defined(ENABLE_LOGGING)
darwin_error_str(IOReturn result)100 static const char *darwin_error_str (IOReturn result) {
101   static char string_buffer[50];
102   switch (result) {
103   case kIOReturnSuccess:
104     return "no error";
105   case kIOReturnNotOpen:
106     return "device not opened for exclusive access";
107   case kIOReturnNoDevice:
108     return "no connection to an IOService";
109   case kIOUSBNoAsyncPortErr:
110     return "no async port has been opened for interface";
111   case kIOReturnExclusiveAccess:
112     return "another process has device opened for exclusive access";
113   case kIOUSBPipeStalled:
114 #if defined(kUSBHostReturnPipeStalled)
115   case kUSBHostReturnPipeStalled:
116 #endif
117     return "pipe is stalled";
118   case kIOReturnError:
119     return "could not establish a connection to the Darwin kernel";
120   case kIOUSBTransactionTimeout:
121     return "transaction timed out";
122   case kIOReturnBadArgument:
123     return "invalid argument";
124   case kIOReturnAborted:
125     return "transaction aborted";
126   case kIOReturnNotResponding:
127     return "device not responding";
128   case kIOReturnOverrun:
129     return "data overrun";
130   case kIOReturnCannotWire:
131     return "physical memory can not be wired down";
132   case kIOReturnNoResources:
133     return "out of resources";
134   case kIOUSBHighSpeedSplitError:
135     return "high speed split error";
136   case kIOUSBUnknownPipeErr:
137     return "pipe ref not recognized";
138   default:
139     snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
140     return string_buffer;
141   }
142 }
143 #endif
144 
darwin_to_libusb(IOReturn result)145 static enum libusb_error darwin_to_libusb (IOReturn result) {
146   switch (result) {
147   case kIOReturnUnderrun:
148   case kIOReturnSuccess:
149     return LIBUSB_SUCCESS;
150   case kIOReturnNotOpen:
151   case kIOReturnNoDevice:
152     return LIBUSB_ERROR_NO_DEVICE;
153   case kIOReturnExclusiveAccess:
154     return LIBUSB_ERROR_ACCESS;
155   case kIOUSBPipeStalled:
156 #if defined(kUSBHostReturnPipeStalled)
157   case kUSBHostReturnPipeStalled:
158 #endif
159     return LIBUSB_ERROR_PIPE;
160   case kIOReturnBadArgument:
161     return LIBUSB_ERROR_INVALID_PARAM;
162   case kIOUSBTransactionTimeout:
163     return LIBUSB_ERROR_TIMEOUT;
164   case kIOUSBUnknownPipeErr:
165     return LIBUSB_ERROR_NOT_FOUND;
166   case kIOReturnNotResponding:
167   case kIOReturnAborted:
168   case kIOReturnError:
169   case kIOUSBNoAsyncPortErr:
170   default:
171     return LIBUSB_ERROR_OTHER;
172   }
173 }
174 
175 /* this function must be called with the darwin_cached_devices_lock held */
darwin_deref_cached_device(struct darwin_cached_device * cached_dev)176 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
177   cached_dev->refcount--;
178   /* free the device and remove it from the cache */
179   if (0 == cached_dev->refcount) {
180     list_del(&cached_dev->list);
181 
182     if (cached_dev->device) {
183       (*(cached_dev->device))->Release(cached_dev->device);
184       cached_dev->device = NULL;
185     }
186     IOObjectRelease (cached_dev->service);
187     free (cached_dev);
188   }
189 }
190 
darwin_ref_cached_device(struct darwin_cached_device * cached_dev)191 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
192   cached_dev->refcount++;
193 }
194 
ep_to_pipeRef(struct libusb_device_handle * dev_handle,uint8_t ep,uint8_t * pipep,uint8_t * ifcp,struct darwin_interface ** interface_out)195 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) {
196   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
197 
198   /* current interface */
199   struct darwin_interface *cInterface;
200 
201   uint8_t i, iface;
202 
203   struct libusb_context *ctx = HANDLE_CTX(dev_handle);
204 
205   usbi_dbg (ctx, "converting ep address 0x%02x to pipeRef and interface", ep);
206 
207   for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
208     cInterface = &priv->interfaces[iface];
209 
210     if (dev_handle->claimed_interfaces & (1U << iface)) {
211       for (i = 0 ; i < cInterface->num_endpoints ; i++) {
212         if (cInterface->endpoint_addrs[i] == ep) {
213           *pipep = i + 1;
214 
215           if (ifcp)
216             *ifcp = iface;
217 
218           if (interface_out)
219             *interface_out = cInterface;
220 
221           usbi_dbg (ctx, "pipe %d on interface %d matches", *pipep, iface);
222           return LIBUSB_SUCCESS;
223         }
224       }
225     }
226   }
227 
228   /* No pipe found with the correct endpoint address */
229   usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
230 
231   return LIBUSB_ERROR_NOT_FOUND;
232 }
233 
usb_setup_device_iterator(io_iterator_t * deviceIterator,UInt32 location)234 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
235   CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
236 
237   if (!matchingDict)
238     return kIOReturnError;
239 
240   if (location) {
241     CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
242                                                                          &kCFTypeDictionaryKeyCallBacks,
243                                                                          &kCFTypeDictionaryValueCallBacks);
244 
245     /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
246          internally (CFNumberType of locationID is kCFNumberSInt32Type) */
247     CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
248 
249     if (propertyMatchDict && locationCF) {
250       CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
251       CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
252     }
253     /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
254 
255     /* release our references as per the Create Rule */
256     if (propertyMatchDict)
257       CFRelease (propertyMatchDict);
258     if (locationCF)
259       CFRelease (locationCF);
260   }
261 
262   return IOServiceGetMatchingServices(darwin_default_master_port, matchingDict, deviceIterator);
263 }
264 
265 /* Returns 1 on success, 0 on failure. */
get_ioregistry_value_number(io_service_t service,CFStringRef property,CFNumberType type,void * p)266 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
267   CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
268   Boolean success = 0;
269 
270   if (cfNumber) {
271     if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
272       success = CFNumberGetValue(cfNumber, type, p);
273     }
274 
275     CFRelease (cfNumber);
276   }
277 
278   return (success != 0);
279 }
280 
281 /* Returns 1 on success, 0 on failure. */
get_ioregistry_value_data(io_service_t service,CFStringRef property,ssize_t size,void * p)282 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
283   CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
284   bool success = false;
285 
286   if (cfData) {
287     if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
288       CFIndex length = CFDataGetLength (cfData);
289       if (length < size) {
290         size = length;
291       }
292 
293       CFDataGetBytes (cfData, CFRangeMake(0, size), p);
294       success = true;
295     }
296 
297     CFRelease (cfData);
298   }
299 
300   return success;
301 }
302 
darwin_device_from_service(struct libusb_context * ctx,io_service_t service)303 static usb_device_t **darwin_device_from_service (struct libusb_context *ctx, io_service_t service)
304 {
305   io_cf_plugin_ref_t *plugInInterface = NULL;
306   usb_device_t **device;
307   IOReturn kresult;
308   SInt32 score;
309   const int max_retries = 5;
310 
311   /* The IOCreatePlugInInterfaceForService function might consistently return
312      an "out of resources" error with certain USB devices the first time we run
313      it. The reason is still unclear, but retrying fixes the problem */
314   for (int count = 0; count < max_retries; count++) {
315     kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
316                                                 kIOCFPlugInInterfaceID, &plugInInterface,
317                                                 &score);
318     if (kIOReturnSuccess == kresult && plugInInterface) {
319       break;
320     }
321 
322     usbi_dbg (ctx, "set up plugin for service retry: %s", darwin_error_str (kresult));
323 
324     /* sleep for a little while before trying again */
325     nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
326   }
327 
328   if (kIOReturnSuccess != kresult || !plugInInterface) {
329     usbi_dbg (ctx, "could not set up plugin for service: %s", darwin_error_str (kresult));
330     return NULL;
331   }
332 
333   (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
334                                            (LPVOID)&device);
335   /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
336   (*plugInInterface)->Release (plugInInterface);
337 
338   return device;
339 }
340 
darwin_devices_attached(void * ptr,io_iterator_t add_devices)341 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
342   UNUSED(ptr);
343   struct darwin_cached_device *cached_device;
344   UInt64 old_session_id;
345   struct libusb_context *ctx;
346   io_service_t service;
347   int ret;
348 
349   usbi_mutex_lock(&active_contexts_lock);
350 
351   while ((service = IOIteratorNext(add_devices))) {
352     ret = darwin_get_cached_device (NULL, service, &cached_device, &old_session_id);
353     if (ret < 0 || !cached_device->can_enumerate) {
354       continue;
355     }
356 
357     /* add this device to each active context's device list */
358     for_each_context(ctx) {
359       process_new_device (ctx, cached_device, old_session_id);
360     }
361 
362     if (cached_device->in_reenumerate) {
363       usbi_dbg (NULL, "cached device in reset state. reset complete...");
364       cached_device->in_reenumerate = false;
365     }
366 
367     IOObjectRelease(service);
368   }
369 
370   usbi_mutex_unlock(&active_contexts_lock);
371 }
372 
darwin_devices_detached(void * ptr,io_iterator_t rem_devices)373 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
374   UNUSED(ptr);
375   struct libusb_device *dev = NULL;
376   struct libusb_context *ctx;
377   struct darwin_cached_device *old_device;
378 
379   io_service_t device;
380   UInt64 session, locationID;
381   int ret;
382 
383   usbi_mutex_lock(&active_contexts_lock);
384 
385   while ((device = IOIteratorNext (rem_devices)) != 0) {
386     bool is_reenumerating = false;
387 
388     /* get the location from the i/o registry */
389     ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
390     (void) get_ioregistry_value_number (device, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
391     IOObjectRelease (device);
392     if (!ret)
393       continue;
394 
395     /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
396        otherwise no cached device will ever get freed */
397     usbi_mutex_lock(&darwin_cached_devices_lock);
398     list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
399       if (old_device->session == session) {
400         if (old_device->in_reenumerate) {
401           /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
402            * will deref if needed. */
403           usbi_dbg (NULL, "detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64,
404                     session, locationID);
405 
406           /* the device object is no longer usable so go ahead and release it */
407           if (old_device->device) {
408             (*(old_device->device))->Release(old_device->device);
409             old_device->device = NULL;
410           }
411 
412           is_reenumerating = true;
413         } else {
414           darwin_deref_cached_device (old_device);
415         }
416 
417         break;
418       }
419     }
420 
421     usbi_mutex_unlock(&darwin_cached_devices_lock);
422     if (is_reenumerating) {
423       continue;
424     }
425 
426     for_each_context(ctx) {
427       usbi_dbg (ctx, "notifying context %p of device disconnect", ctx);
428 
429       dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
430       if (dev) {
431         /* signal the core that this device has been disconnected. the core will tear down this device
432            when the reference count reaches 0 */
433         usbi_disconnect_device(dev);
434         libusb_unref_device(dev);
435       }
436     }
437   }
438 
439   usbi_mutex_unlock(&active_contexts_lock);
440 }
441 
darwin_hotplug_poll(void)442 static void darwin_hotplug_poll (void)
443 {
444   /* not sure if 1 ms will be too long/short but it should work ok */
445   mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
446 
447   /* since a kernel thread may notify the IOIterators used for
448    * hotplug notification we can't just clear the iterators.
449    * instead just wait until all IOService providers are quiet */
450   (void) IOKitWaitQuiet (darwin_default_master_port, &timeout);
451 }
452 
darwin_clear_iterator(io_iterator_t iter)453 static void darwin_clear_iterator (io_iterator_t iter) {
454   io_service_t device;
455 
456   while ((device = IOIteratorNext (iter)) != 0)
457     IOObjectRelease (device);
458 }
459 
darwin_fail_startup(void)460 static void darwin_fail_startup(void) {
461   pthread_mutex_lock (&libusb_darwin_at_mutex);
462   libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
463   pthread_cond_signal (&libusb_darwin_at_cond);
464   pthread_mutex_unlock (&libusb_darwin_at_mutex);
465   pthread_exit (NULL);
466 }
467 
darwin_event_thread_main(void * arg0)468 static void *darwin_event_thread_main (void *arg0) {
469   IOReturn kresult;
470   struct libusb_context *ctx = (struct libusb_context *)arg0;
471   CFRunLoopRef runloop;
472   CFRunLoopSourceRef libusb_shutdown_cfsource;
473   CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
474 
475 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
476   /* Set this thread's name, so it can be seen in the debugger
477      and crash reports. */
478   pthread_setname_np ("org.libusb.device-hotplug");
479 #endif
480 
481 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
482   /* Tell the Objective-C garbage collector about this thread.
483      This is required because, unlike NSThreads, pthreads are
484      not automatically registered. Although we don't use
485      Objective-C, we use CoreFoundation, which does.
486      Garbage collection support was entirely removed in 10.12,
487      so don't bother there. */
488   objc_registerThreadWithCollector();
489 #endif
490 
491   /* hotplug (device arrival/removal) sources */
492   CFRunLoopSourceRef     libusb_notification_cfsource;
493   io_notification_port_t libusb_notification_port;
494   io_iterator_t          libusb_rem_device_iterator;
495   io_iterator_t          libusb_add_device_iterator;
496 
497   /* ctx must only be used for logging during thread startup */
498   usbi_dbg (ctx, "creating hotplug event source");
499 
500   runloop = CFRunLoopGetCurrent ();
501   CFRetain (runloop);
502 
503   /* add the shutdown cfsource to the run loop */
504   memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
505   libusb_shutdown_cfsourcectx.info = runloop;
506   libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
507   libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
508   CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
509 
510   /* add the notification port to the run loop */
511   libusb_notification_port     = IONotificationPortCreate (darwin_default_master_port);
512   libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
513   CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
514 
515   /* create notifications for removed devices */
516   kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
517                                               IOServiceMatching(darwin_device_class),
518                                               darwin_devices_detached,
519                                               NULL, &libusb_rem_device_iterator);
520 
521   if (kresult != kIOReturnSuccess) {
522     usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
523     CFRelease (libusb_shutdown_cfsource);
524     CFRelease (runloop);
525     darwin_fail_startup ();
526   }
527 
528   /* create notifications for attached devices */
529   kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
530                                               IOServiceMatching(darwin_device_class),
531                                               darwin_devices_attached,
532                                               NULL, &libusb_add_device_iterator);
533 
534   if (kresult != kIOReturnSuccess) {
535     usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
536     CFRelease (libusb_shutdown_cfsource);
537     CFRelease (runloop);
538     darwin_fail_startup ();
539   }
540 
541   /* arm notifiers */
542   darwin_clear_iterator (libusb_rem_device_iterator);
543   darwin_clear_iterator (libusb_add_device_iterator);
544 
545   usbi_dbg (ctx, "darwin event thread ready to receive events");
546 
547   /* signal the main thread that the hotplug runloop has been created. */
548   pthread_mutex_lock (&libusb_darwin_at_mutex);
549   libusb_darwin_acfl = runloop;
550   libusb_darwin_acfls = libusb_shutdown_cfsource;
551   pthread_cond_signal (&libusb_darwin_at_cond);
552   pthread_mutex_unlock (&libusb_darwin_at_mutex);
553 
554   /* run the runloop */
555   CFRunLoopRun();
556 
557   usbi_dbg (NULL, "darwin event thread exiting");
558 
559   /* signal the main thread that the hotplug runloop has finished. */
560   pthread_mutex_lock (&libusb_darwin_at_mutex);
561   libusb_darwin_acfls = NULL;
562   libusb_darwin_acfl = NULL;
563   pthread_cond_signal (&libusb_darwin_at_cond);
564   pthread_mutex_unlock (&libusb_darwin_at_mutex);
565 
566   /* remove the notification cfsource */
567   CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
568 
569   /* remove the shutdown cfsource */
570   CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
571 
572   /* delete notification port */
573   IONotificationPortDestroy (libusb_notification_port);
574 
575   /* delete iterators */
576   IOObjectRelease (libusb_rem_device_iterator);
577   IOObjectRelease (libusb_add_device_iterator);
578 
579   CFRelease (libusb_shutdown_cfsource);
580   CFRelease (runloop);
581 
582   pthread_exit (NULL);
583 }
584 
585 /* cleanup function to destroy cached devices */
darwin_cleanup_devices(void)586 static void darwin_cleanup_devices(void) {
587   struct darwin_cached_device *dev, *next;
588 
589   list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
590     darwin_deref_cached_device(dev);
591   }
592 }
593 
darwin_init(struct libusb_context * ctx)594 static int darwin_init(struct libusb_context *ctx) {
595   bool first_init;
596   int rc;
597 
598   first_init = (1 == ++init_count);
599 
600   do {
601     if (first_init) {
602       if (NULL == darwin_cached_devices.next) {
603         list_init (&darwin_cached_devices);
604       }
605       assert(list_empty(&darwin_cached_devices));
606 #if !defined(HAVE_CLOCK_GETTIME)
607       /* create the clocks that will be used if clock_gettime() is not available */
608       host_name_port_t host_self;
609 
610       host_self = mach_host_self();
611       host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
612       host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
613       mach_port_deallocate(mach_task_self(), host_self);
614 #endif
615     }
616 
617     rc = darwin_scan_devices (ctx);
618     if (LIBUSB_SUCCESS != rc)
619       break;
620 
621     if (first_init) {
622       rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
623       if (0 != rc) {
624         usbi_err (ctx, "could not create event thread, error %d", rc);
625         rc = LIBUSB_ERROR_OTHER;
626         break;
627       }
628 
629       pthread_mutex_lock (&libusb_darwin_at_mutex);
630       while (!libusb_darwin_acfl)
631         pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
632       if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
633         libusb_darwin_acfl = NULL;
634         rc = LIBUSB_ERROR_OTHER;
635       }
636       pthread_mutex_unlock (&libusb_darwin_at_mutex);
637 
638       if (0 != rc)
639         pthread_join (libusb_darwin_at, NULL);
640     }
641   } while (0);
642 
643   if (LIBUSB_SUCCESS != rc) {
644     if (first_init) {
645       darwin_cleanup_devices ();
646 #if !defined(HAVE_CLOCK_GETTIME)
647       mach_port_deallocate(mach_task_self(), clock_realtime);
648       mach_port_deallocate(mach_task_self(), clock_monotonic);
649 #endif
650     }
651     --init_count;
652   }
653 
654   return rc;
655 }
656 
darwin_exit(struct libusb_context * ctx)657 static void darwin_exit (struct libusb_context *ctx) {
658   UNUSED(ctx);
659 
660   if (0 == --init_count) {
661     /* stop the event runloop and wait for the thread to terminate. */
662     pthread_mutex_lock (&libusb_darwin_at_mutex);
663     CFRunLoopSourceSignal (libusb_darwin_acfls);
664     CFRunLoopWakeUp (libusb_darwin_acfl);
665     while (libusb_darwin_acfl)
666       pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
667     pthread_mutex_unlock (&libusb_darwin_at_mutex);
668     pthread_join (libusb_darwin_at, NULL);
669 
670     darwin_cleanup_devices ();
671 
672 #if !defined(HAVE_CLOCK_GETTIME)
673     mach_port_deallocate(mach_task_self(), clock_realtime);
674     mach_port_deallocate(mach_task_self(), clock_monotonic);
675 #endif
676   }
677 }
678 
get_configuration_index(struct libusb_device * dev,UInt8 config_value)679 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
680   struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
681   UInt8 i, numConfig;
682   IOUSBConfigurationDescriptorPtr desc;
683   IOReturn kresult;
684 
685   /* is there a simpler way to determine the index? */
686   kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
687   if (kresult != kIOReturnSuccess)
688     return darwin_to_libusb (kresult);
689 
690   for (i = 0 ; i < numConfig ; i++) {
691     (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
692 
693     if (desc->bConfigurationValue == config_value)
694       return i;
695   }
696 
697   /* configuration not found */
698   return LIBUSB_ERROR_NOT_FOUND;
699 }
700 
darwin_get_active_config_descriptor(struct libusb_device * dev,void * buffer,size_t len)701 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
702   struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
703   int config_index;
704 
705   if (0 == priv->active_config)
706     return LIBUSB_ERROR_NOT_FOUND;
707 
708   config_index = get_configuration_index (dev, priv->active_config);
709   if (config_index < 0)
710     return config_index;
711 
712   assert(config_index >= 0 && config_index <= UINT8_MAX);
713   return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
714 }
715 
darwin_get_config_descriptor(struct libusb_device * dev,uint8_t config_index,void * buffer,size_t len)716 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
717   struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
718   IOUSBConfigurationDescriptorPtr desc;
719   IOReturn kresult;
720   int ret;
721 
722   if (!priv || !priv->device)
723     return LIBUSB_ERROR_OTHER;
724 
725   kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
726   if (kresult == kIOReturnSuccess) {
727     /* copy descriptor */
728     if (libusb_le16_to_cpu(desc->wTotalLength) < len)
729       len = libusb_le16_to_cpu(desc->wTotalLength);
730 
731     memmove (buffer, desc, len);
732   }
733 
734   ret = darwin_to_libusb (kresult);
735   if (ret != LIBUSB_SUCCESS)
736     return ret;
737 
738   return (int) len;
739 }
740 
741 /* check whether the os has configured the device */
darwin_check_configuration(struct libusb_context * ctx,struct darwin_cached_device * dev)742 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
743   usb_device_t **darwin_device = dev->device;
744 
745   IOUSBConfigurationDescriptorPtr configDesc;
746   IOUSBFindInterfaceRequest request;
747   IOReturn                  kresult;
748   io_iterator_t             interface_iterator;
749   io_service_t              firstInterface;
750 
751   if (dev->dev_descriptor.bNumConfigurations < 1) {
752     usbi_err (ctx, "device has no configurations");
753     return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
754   }
755 
756   /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
757      not usable anyway */
758   if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
759       0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
760     usbi_dbg (ctx, "ignoring configuration on root hub simulation");
761     dev->active_config = 0;
762     return LIBUSB_SUCCESS;
763   }
764 
765   /* find the first configuration */
766   kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
767   dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
768 
769   /* check if the device is already configured. there is probably a better way than iterating over the
770      to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
771      might lock up on the device request) */
772 
773   /* Setup the Interface Request */
774   request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
775   request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
776   request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
777   request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;
778 
779   kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
780   if (kresult != kIOReturnSuccess)
781     return darwin_to_libusb (kresult);
782 
783   /* iterate once */
784   firstInterface = IOIteratorNext(interface_iterator);
785 
786   /* done with the interface iterator */
787   IOObjectRelease(interface_iterator);
788 
789   if (firstInterface) {
790     IOObjectRelease (firstInterface);
791 
792     /* device is configured */
793     if (dev->dev_descriptor.bNumConfigurations == 1)
794       /* to avoid problems with some devices get the configurations value from the configuration descriptor */
795       dev->active_config = dev->first_config;
796     else
797       /* devices with more than one configuration should work with GetConfiguration */
798       (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
799   } else
800     /* not configured */
801     dev->active_config = 0;
802 
803   usbi_dbg (ctx, "active config: %u, first config: %u", dev->active_config, dev->first_config);
804 
805   return LIBUSB_SUCCESS;
806 }
807 
darwin_request_descriptor(usb_device_t ** device,UInt8 desc,UInt8 desc_index,void * buffer,size_t buffer_size)808 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
809   IOUSBDevRequestTO req;
810 
811   assert(buffer_size <= UINT16_MAX);
812 
813   memset (buffer, 0, buffer_size);
814 
815   /* Set up request for descriptor/ */
816   req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
817   req.bRequest      = kUSBRqGetDescriptor;
818   req.wValue        = (UInt16)(desc << 8);
819   req.wIndex        = desc_index;
820   req.wLength       = (UInt16)buffer_size;
821   req.pData         = buffer;
822   req.noDataTimeout = 20;
823   req.completionTimeout = 100;
824 
825   return (*device)->DeviceRequestTO (device, &req);
826 }
827 
darwin_cache_device_descriptor(struct libusb_context * ctx,struct darwin_cached_device * dev)828 static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) {
829   usb_device_t **device = dev->device;
830   int retries = 1;
831   long delay = 30000; // microseconds
832   int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
833   int is_open = 0;
834   IOReturn ret = 0, ret2;
835   UInt8 bDeviceClass;
836   UInt16 idProduct, idVendor;
837 
838   dev->can_enumerate = 0;
839 
840   (*device)->GetDeviceClass (device, &bDeviceClass);
841   (*device)->GetDeviceProduct (device, &idProduct);
842   (*device)->GetDeviceVendor (device, &idVendor);
843 
844   /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
845    * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request.  Still,
846    * to follow the spec as closely as possible, try opening the device */
847   is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
848 
849   do {
850     /**** retrieve device descriptor ****/
851     ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
852 
853     if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
854       /* received an overrun error but we still received a device descriptor */
855       ret = kIOReturnSuccess;
856 
857     if (kIOUSBVendorIDAppleComputer == idVendor) {
858       /* NTH: don't bother retrying or unsuspending Apple devices */
859       break;
860     }
861 
862     if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
863                                     0 == dev->dev_descriptor.bcdUSB)) {
864       /* work around for incorrectly configured devices */
865       if (try_reconfigure && is_open) {
866         usbi_dbg(ctx, "descriptor appears to be invalid. resetting configuration before trying again...");
867 
868         /* set the first configuration */
869         (*device)->SetConfiguration(device, 1);
870 
871         /* don't try to reconfigure again */
872         try_reconfigure = 0;
873       }
874 
875       ret = kIOUSBPipeStalled;
876     }
877 
878     if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
879       /* device may be suspended. unsuspend it and try again */
880 #if DeviceVersion >= 320
881       UInt32 info = 0;
882 
883       /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
884       (void)(*device)->GetUSBDeviceInformation (device, &info);
885 
886       /* note that the device was suspended */
887       if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
888         try_unsuspend = 1;
889 #endif
890 
891       if (try_unsuspend) {
892         /* try to unsuspend the device */
893         ret2 = (*device)->USBDeviceSuspend (device, 0);
894         if (kIOReturnSuccess != ret2) {
895           /* prevent log spew from poorly behaving devices.  this indicates the
896              os actually had trouble communicating with the device */
897           usbi_dbg(ctx, "could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
898         } else
899           unsuspended = 1;
900 
901         try_unsuspend = 0;
902       }
903     }
904 
905     if (kIOReturnSuccess != ret) {
906       usbi_dbg(ctx, "kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
907       /* sleep for a little while before trying again */
908       nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
909     }
910   } while (kIOReturnSuccess != ret && retries--);
911 
912   if (unsuspended)
913     /* resuspend the device */
914     (void)(*device)->USBDeviceSuspend (device, 1);
915 
916   if (is_open)
917     (void) (*device)->USBDeviceClose (device);
918 
919   if (ret != kIOReturnSuccess) {
920     /* a debug message was already printed out for this error */
921     if (LIBUSB_CLASS_HUB == bDeviceClass)
922       usbi_dbg (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
923                 idVendor, idProduct, darwin_error_str (ret), ret);
924     else
925       usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
926                  idVendor, idProduct, darwin_error_str (ret), ret);
927     return darwin_to_libusb (ret);
928   }
929 
930   /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
931   if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
932     /* not a valid device */
933     usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
934                idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
935     return LIBUSB_ERROR_NO_DEVICE;
936   }
937 
938   usbi_dbg (ctx, "cached device descriptor:");
939   usbi_dbg (ctx, "  bDescriptorType:    0x%02x", dev->dev_descriptor.bDescriptorType);
940   usbi_dbg (ctx, "  bcdUSB:             0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
941   usbi_dbg (ctx, "  bDeviceClass:       0x%02x", dev->dev_descriptor.bDeviceClass);
942   usbi_dbg (ctx, "  bDeviceSubClass:    0x%02x", dev->dev_descriptor.bDeviceSubClass);
943   usbi_dbg (ctx, "  bDeviceProtocol:    0x%02x", dev->dev_descriptor.bDeviceProtocol);
944   usbi_dbg (ctx, "  bMaxPacketSize0:    0x%02x", dev->dev_descriptor.bMaxPacketSize0);
945   usbi_dbg (ctx, "  idVendor:           0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
946   usbi_dbg (ctx, "  idProduct:          0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
947   usbi_dbg (ctx, "  bcdDevice:          0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
948   usbi_dbg (ctx, "  iManufacturer:      0x%02x", dev->dev_descriptor.iManufacturer);
949   usbi_dbg (ctx, "  iProduct:           0x%02x", dev->dev_descriptor.iProduct);
950   usbi_dbg (ctx, "  iSerialNumber:      0x%02x", dev->dev_descriptor.iSerialNumber);
951   usbi_dbg (ctx, "  bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
952 
953   dev->can_enumerate = 1;
954 
955   return LIBUSB_SUCCESS;
956 }
957 
958 /* Returns 1 on success, 0 on failure. */
get_device_port(io_service_t service,UInt8 * port)959 static bool get_device_port (io_service_t service, UInt8 *port) {
960   IOReturn kresult;
961   io_service_t parent;
962   bool ret = false;
963 
964   if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
965     return true;
966   }
967 
968   kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
969   if (kIOReturnSuccess == kresult) {
970     ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
971     IOObjectRelease (parent);
972   }
973 
974   return ret;
975 }
976 
977 /* Returns 1 on success, 0 on failure. */
get_device_parent_sessionID(io_service_t service,UInt64 * parent_sessionID)978 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
979   IOReturn kresult;
980   io_service_t parent;
981 
982   /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
983   parent = service;
984   while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
985     if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
986         /* Success */
987         return true;
988     }
989   }
990 
991   /* We ran out of parents */
992   return false;
993 }
994 
darwin_get_cached_device(struct libusb_context * ctx,io_service_t service,struct darwin_cached_device ** cached_out,UInt64 * old_session_id)995 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
996                                                   UInt64 *old_session_id) {
997   struct darwin_cached_device *new_device;
998   UInt64 sessionID = 0, parent_sessionID = 0;
999   UInt32 locationID = 0;
1000   enum libusb_error ret = LIBUSB_SUCCESS;
1001   usb_device_t **device;
1002   UInt8 port = 0;
1003 
1004   /* assuming sessionID != 0 normally (never seen it be 0) */
1005   *old_session_id = 0;
1006   *cached_out = NULL;
1007 
1008   /* get some info from the io registry */
1009   (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
1010   (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
1011   if (!get_device_port (service, &port)) {
1012     usbi_dbg(ctx, "could not get connected port number");
1013   }
1014 
1015   usbi_dbg(ctx, "finding cached device for sessionID 0x%" PRIx64, sessionID);
1016 
1017   if (get_device_parent_sessionID(service, &parent_sessionID)) {
1018     usbi_dbg(ctx, "parent sessionID: 0x%" PRIx64, parent_sessionID);
1019   }
1020 
1021   usbi_mutex_lock(&darwin_cached_devices_lock);
1022   do {
1023     list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1024       usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1025                sessionID, locationID, new_device->session, new_device->location);
1026       if (new_device->location == locationID && new_device->in_reenumerate) {
1027         usbi_dbg (ctx, "found cached device with matching location that is being re-enumerated");
1028         *old_session_id = new_device->session;
1029         break;
1030       }
1031 
1032       if (new_device->session == sessionID) {
1033         usbi_dbg(ctx, "using cached device for device");
1034         *cached_out = new_device;
1035         break;
1036       }
1037     }
1038 
1039     if (*cached_out)
1040       break;
1041 
1042     usbi_dbg(ctx, "caching new device with sessionID 0x%" PRIx64, sessionID);
1043 
1044     device = darwin_device_from_service (ctx, service);
1045     if (!device) {
1046       ret = LIBUSB_ERROR_NO_DEVICE;
1047       break;
1048     }
1049 
1050     if (!(*old_session_id)) {
1051       new_device = calloc (1, sizeof (*new_device));
1052       if (!new_device) {
1053         ret = LIBUSB_ERROR_NO_MEM;
1054         break;
1055       }
1056 
1057       /* add this device to the cached device list */
1058       list_add(&new_device->list, &darwin_cached_devices);
1059 
1060       (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1061 
1062       /* keep a reference to this device */
1063       darwin_ref_cached_device(new_device);
1064 
1065       (*device)->GetLocationID (device, &new_device->location);
1066       new_device->port = port;
1067       new_device->parent_session = parent_sessionID;
1068     } else {
1069       /* release the ref to old device's service */
1070       IOObjectRelease (new_device->service);
1071     }
1072 
1073     /* keep track of devices regardless of if we successfully enumerate them to
1074        prevent them from being enumerated multiple times */
1075     *cached_out = new_device;
1076 
1077     new_device->session = sessionID;
1078     new_device->device = device;
1079     new_device->service = service;
1080 
1081     /* retain the service */
1082     IOObjectRetain (service);
1083 
1084     /* cache the device descriptor */
1085     ret = darwin_cache_device_descriptor(ctx, new_device);
1086     if (ret)
1087       break;
1088 
1089     if (new_device->can_enumerate) {
1090       snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1091                libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1092                libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1093                new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1094     }
1095   } while (0);
1096 
1097   usbi_mutex_unlock(&darwin_cached_devices_lock);
1098 
1099   return ret;
1100 }
1101 
process_new_device(struct libusb_context * ctx,struct darwin_cached_device * cached_device,UInt64 old_session_id)1102 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1103                                              UInt64 old_session_id) {
1104   struct darwin_device_priv *priv;
1105   struct libusb_device *dev = NULL;
1106   UInt8 devSpeed;
1107   enum libusb_error ret = LIBUSB_SUCCESS;
1108 
1109   do {
1110     /* check current active configuration (and cache the first configuration value--
1111        which may be used by claim_interface) */
1112     ret = darwin_check_configuration (ctx, cached_device);
1113     if (ret)
1114       break;
1115 
1116     if (0 != old_session_id) {
1117       usbi_dbg (ctx, "re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1118                 ctx, old_session_id, cached_device->session);
1119       /* save the libusb device before the session id is updated */
1120       dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1121     }
1122 
1123     if (!dev) {
1124       usbi_dbg (ctx, "allocating new device in context %p for with session 0x%" PRIx64,
1125                 ctx, cached_device->session);
1126 
1127       dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1128       if (!dev) {
1129         return LIBUSB_ERROR_NO_MEM;
1130       }
1131 
1132       priv = usbi_get_device_priv(dev);
1133 
1134       priv->dev = cached_device;
1135       darwin_ref_cached_device (priv->dev);
1136       dev->port_number    = cached_device->port;
1137       /* the location ID encodes the path to the device. the top byte of the location ID contains the bus number
1138          (numbered from 0). the remaining bytes can be used to construct the device tree for that bus. */
1139       dev->bus_number     = cached_device->location >> 24;
1140       assert(cached_device->address <= UINT8_MAX);
1141       dev->device_address = (uint8_t)cached_device->address;
1142     } else {
1143       priv = usbi_get_device_priv(dev);
1144     }
1145 
1146     static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1147                   "mismatch between libusb and IOKit device descriptor sizes");
1148     memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1149     usbi_localize_device_descriptor(&dev->device_descriptor);
1150     dev->session_data = cached_device->session;
1151 
1152     if (NULL != dev->parent_dev) {
1153       libusb_unref_device(dev->parent_dev);
1154       dev->parent_dev = NULL;
1155     }
1156 
1157     if (cached_device->parent_session > 0) {
1158       dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1159     }
1160 
1161     (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1162 
1163     switch (devSpeed) {
1164     case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1165     case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1166     case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1167 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
1168     case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1169 #endif
1170 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1171     case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1172 #endif
1173     default:
1174       usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1175     }
1176 
1177     ret = usbi_sanitize_device (dev);
1178     if (ret < 0)
1179       break;
1180 
1181     usbi_dbg (ctx, "found device with address %d port = %d parent = %p at %p", dev->device_address,
1182               dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1183 
1184   } while (0);
1185 
1186   if (!cached_device->in_reenumerate && 0 == ret) {
1187     usbi_connect_device (dev);
1188   } else {
1189     libusb_unref_device (dev);
1190   }
1191 
1192   return ret;
1193 }
1194 
darwin_scan_devices(struct libusb_context * ctx)1195 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1196   struct darwin_cached_device *cached_device;
1197   UInt64 old_session_id;
1198   io_iterator_t deviceIterator;
1199   io_service_t service;
1200   IOReturn kresult;
1201   int ret;
1202 
1203   kresult = usb_setup_device_iterator (&deviceIterator, 0);
1204   if (kresult != kIOReturnSuccess)
1205     return darwin_to_libusb (kresult);
1206 
1207   while ((service = IOIteratorNext (deviceIterator))) {
1208     ret = darwin_get_cached_device (ctx, service, &cached_device, &old_session_id);
1209     if (ret < 0 || !cached_device->can_enumerate) {
1210       continue;
1211     }
1212 
1213     (void) process_new_device (ctx, cached_device, old_session_id);
1214 
1215     IOObjectRelease(service);
1216   }
1217 
1218   IOObjectRelease(deviceIterator);
1219 
1220   return LIBUSB_SUCCESS;
1221 }
1222 
darwin_open(struct libusb_device_handle * dev_handle)1223 static int darwin_open (struct libusb_device_handle *dev_handle) {
1224   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1225   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1226   IOReturn kresult;
1227 
1228   if (0 == dpriv->open_count) {
1229     /* try to open the device */
1230     kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1231     if (kresult != kIOReturnSuccess) {
1232       usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1233 
1234       if (kIOReturnExclusiveAccess != kresult) {
1235         return darwin_to_libusb (kresult);
1236       }
1237 
1238       /* it is possible to perform some actions on a device that is not open so do not return an error */
1239       priv->is_open = false;
1240     } else {
1241       priv->is_open = true;
1242     }
1243 
1244     /* create async event source */
1245     kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1246     if (kresult != kIOReturnSuccess) {
1247       usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1248 
1249       if (priv->is_open) {
1250         (*(dpriv->device))->USBDeviceClose (dpriv->device);
1251       }
1252 
1253       priv->is_open = false;
1254 
1255       return darwin_to_libusb (kresult);
1256     }
1257 
1258     CFRetain (libusb_darwin_acfl);
1259 
1260     /* add the cfSource to the async run loop */
1261     CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1262   }
1263 
1264   /* device opened successfully */
1265   dpriv->open_count++;
1266 
1267   usbi_dbg (HANDLE_CTX(dev_handle), "device open for access");
1268 
1269   return 0;
1270 }
1271 
darwin_close(struct libusb_device_handle * dev_handle)1272 static void darwin_close (struct libusb_device_handle *dev_handle) {
1273   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1274   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1275   IOReturn kresult;
1276   int i;
1277 
1278   if (dpriv->open_count == 0) {
1279     /* something is probably very wrong if this is the case */
1280     usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1281     return;
1282   }
1283 
1284   dpriv->open_count--;
1285   if (NULL == dpriv->device) {
1286     usbi_warn (HANDLE_CTX (dev_handle), "darwin_close device missing IOService");
1287     return;
1288   }
1289 
1290   /* make sure all interfaces are released */
1291   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1292     if (dev_handle->claimed_interfaces & (1U << i))
1293       libusb_release_interface (dev_handle, i);
1294 
1295   if (0 == dpriv->open_count) {
1296     /* delete the device's async event source */
1297     if (priv->cfSource) {
1298       CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1299       CFRelease (priv->cfSource);
1300       priv->cfSource = NULL;
1301       CFRelease (libusb_darwin_acfl);
1302     }
1303 
1304     if (priv->is_open) {
1305       /* close the device */
1306       kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1307       if (kresult != kIOReturnSuccess) {
1308         /* Log the fact that we had a problem closing the file, however failing a
1309          * close isn't really an error, so return success anyway */
1310         usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1311       }
1312     }
1313   }
1314 }
1315 
darwin_get_configuration(struct libusb_device_handle * dev_handle,uint8_t * config)1316 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1317   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1318 
1319   *config = dpriv->active_config;
1320 
1321   return LIBUSB_SUCCESS;
1322 }
1323 
darwin_set_configuration(struct libusb_device_handle * dev_handle,int config)1324 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1325   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1326   IOReturn kresult;
1327   uint8_t i;
1328 
1329   if (config == -1)
1330     config = 0;
1331 
1332   /* Setting configuration will invalidate the interface, so we need
1333      to reclaim it. First, dispose of existing interfaces, if any. */
1334   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1335     if (dev_handle->claimed_interfaces & (1U << i))
1336       darwin_release_interface (dev_handle, i);
1337 
1338   kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1339   if (kresult != kIOReturnSuccess)
1340     return darwin_to_libusb (kresult);
1341 
1342   /* Reclaim any interfaces. */
1343   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1344     if (dev_handle->claimed_interfaces & (1U << i))
1345       darwin_claim_interface (dev_handle, i);
1346 
1347   dpriv->active_config = (UInt8)config;
1348 
1349   return LIBUSB_SUCCESS;
1350 }
1351 
darwin_get_interface(usb_device_t ** darwin_device,uint8_t ifc,io_service_t * usbInterfacep)1352 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1353   IOUSBFindInterfaceRequest request;
1354   IOReturn                  kresult;
1355   io_iterator_t             interface_iterator;
1356   UInt8                     bInterfaceNumber;
1357   bool                      ret;
1358 
1359   *usbInterfacep = IO_OBJECT_NULL;
1360 
1361   /* Setup the Interface Request */
1362   request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
1363   request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1364   request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1365   request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;
1366 
1367   kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1368   if (kresult != kIOReturnSuccess)
1369     return kresult;
1370 
1371   while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1372     /* find the interface number */
1373     ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1374                                        &bInterfaceNumber);
1375 
1376     if (ret && bInterfaceNumber == ifc) {
1377       break;
1378     }
1379 
1380     (void) IOObjectRelease (*usbInterfacep);
1381   }
1382 
1383   /* done with the interface iterator */
1384   IOObjectRelease(interface_iterator);
1385 
1386   return kIOReturnSuccess;
1387 }
1388 
get_endpoints(struct libusb_device_handle * dev_handle,uint8_t iface)1389 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1390   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1391 
1392   /* current interface */
1393   struct darwin_interface *cInterface = &priv->interfaces[iface];
1394 #if InterfaceVersion >= 550
1395   IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1396 #else
1397   UInt8 dont_care1, dont_care3;
1398   UInt16 dont_care2;
1399 #endif
1400 
1401   IOReturn kresult;
1402 
1403   UInt8 numep, direction, number;
1404   int rc;
1405   struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1406 
1407 
1408   usbi_dbg (ctx, "building table of endpoints.");
1409 
1410   /* retrieve the total number of endpoints on this interface */
1411   kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1412   if (kresult != kIOReturnSuccess) {
1413     usbi_err (ctx, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1414     return darwin_to_libusb (kresult);
1415   }
1416 
1417   /* iterate through pipe references */
1418   for (UInt8 i = 1 ; i <= numep ; i++) {
1419 #if InterfaceVersion >= 550
1420     kresult = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, i, &pipeProperties);
1421     number = pipeProperties.bEndpointNumber;
1422     direction = pipeProperties.bDirection;
1423 #else
1424     kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1425                                                             &dont_care2, &dont_care3);
1426 #endif
1427     if (kresult != kIOReturnSuccess) {
1428       /* probably a buggy device. try to get the endpoint address from the descriptors */
1429       struct libusb_config_descriptor *config;
1430       const struct libusb_endpoint_descriptor *endpoint_desc;
1431       UInt8 alt_setting;
1432 
1433       kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1434       if (kresult != kIOReturnSuccess) {
1435         usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1436         return darwin_to_libusb (kresult);
1437       }
1438 
1439       rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1440       if (LIBUSB_SUCCESS != rc) {
1441         return rc;
1442       }
1443 
1444       if (iface >= config->bNumInterfaces) {
1445         usbi_err (HANDLE_CTX (dev_handle), "interface %d out of range for device", iface);
1446         return LIBUSB_ERROR_NOT_FOUND;
1447       }
1448       endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1449 
1450       cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1451     } else {
1452       cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1453     }
1454 
1455     usbi_dbg (ctx, "interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1456               cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1457   }
1458 
1459   cInterface->num_endpoints = numep;
1460 
1461   return LIBUSB_SUCCESS;
1462 }
1463 
darwin_claim_interface(struct libusb_device_handle * dev_handle,uint8_t iface)1464 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1465   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1466   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1467   io_service_t          usbInterface = IO_OBJECT_NULL;
1468   IOReturn              kresult;
1469   enum libusb_error     ret;
1470   IOCFPlugInInterface **plugInInterface = NULL;
1471   SInt32                score;
1472 
1473   /* current interface */
1474   struct darwin_interface *cInterface = &priv->interfaces[iface];
1475 
1476   struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1477 
1478   kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1479   if (kresult != kIOReturnSuccess)
1480     return darwin_to_libusb (kresult);
1481 
1482   /* make sure we have an interface */
1483   if (!usbInterface && dpriv->first_config != 0) {
1484     usbi_info (ctx, "no interface found; setting configuration: %d", dpriv->first_config);
1485 
1486     /* set the configuration */
1487     ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1488     if (ret != LIBUSB_SUCCESS) {
1489       usbi_err (ctx, "could not set configuration");
1490       return ret;
1491     }
1492 
1493     kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1494     if (kresult != kIOReturnSuccess) {
1495       usbi_err (ctx, "darwin_get_interface: %s", darwin_error_str(kresult));
1496       return darwin_to_libusb (kresult);
1497     }
1498   }
1499 
1500   if (!usbInterface) {
1501     usbi_info (ctx, "interface not found");
1502     return LIBUSB_ERROR_NOT_FOUND;
1503   }
1504 
1505   /* get an interface to the device's interface */
1506   kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1507                                                kIOCFPlugInInterfaceID, &plugInInterface, &score);
1508 
1509   /* ignore release error */
1510   (void)IOObjectRelease (usbInterface);
1511 
1512   if (kresult != kIOReturnSuccess) {
1513     usbi_err (ctx, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1514     return darwin_to_libusb (kresult);
1515   }
1516 
1517   if (!plugInInterface) {
1518     usbi_err (ctx, "plugin interface not found");
1519     return LIBUSB_ERROR_NOT_FOUND;
1520   }
1521 
1522   /* Do the actual claim */
1523   kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1524                                                CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1525                                                (LPVOID)&cInterface->interface);
1526   /* We no longer need the intermediate plug-in */
1527   /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1528   (*plugInInterface)->Release (plugInInterface);
1529   if (kresult != kIOReturnSuccess || !cInterface->interface) {
1530     usbi_err (ctx, "QueryInterface: %s", darwin_error_str(kresult));
1531     return darwin_to_libusb (kresult);
1532   }
1533 
1534   /* claim the interface */
1535   kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1536   if (kresult != kIOReturnSuccess) {
1537     usbi_info (ctx, "USBInterfaceOpen: %s", darwin_error_str(kresult));
1538     return darwin_to_libusb (kresult);
1539   }
1540 
1541   /* update list of endpoints */
1542   ret = get_endpoints (dev_handle, iface);
1543   if (ret) {
1544     /* this should not happen */
1545     darwin_release_interface (dev_handle, iface);
1546     usbi_err (ctx, "could not build endpoint table");
1547     return ret;
1548   }
1549 
1550   cInterface->cfSource = NULL;
1551 
1552   /* create async event source */
1553   kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1554   if (kresult != kIOReturnSuccess) {
1555     usbi_err (ctx, "could not create async event source");
1556 
1557     /* can't continue without an async event source */
1558     (void)darwin_release_interface (dev_handle, iface);
1559 
1560     return darwin_to_libusb (kresult);
1561   }
1562 
1563   /* add the cfSource to the async thread's run loop */
1564   CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1565 
1566   usbi_dbg (ctx, "interface opened");
1567 
1568   return LIBUSB_SUCCESS;
1569 }
1570 
darwin_release_interface(struct libusb_device_handle * dev_handle,uint8_t iface)1571 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1572   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1573   IOReturn kresult;
1574 
1575   /* current interface */
1576   struct darwin_interface *cInterface = &priv->interfaces[iface];
1577 
1578   /* Check to see if an interface is open */
1579   if (!cInterface->interface)
1580     return LIBUSB_SUCCESS;
1581 
1582   /* clean up endpoint data */
1583   cInterface->num_endpoints = 0;
1584 
1585   /* delete the interface's async event source */
1586   if (cInterface->cfSource) {
1587     CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1588     CFRelease (cInterface->cfSource);
1589     cInterface->cfSource = NULL;
1590   }
1591 
1592   kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1593   if (kresult != kIOReturnSuccess)
1594     usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1595 
1596   kresult = (*(cInterface->interface))->Release(cInterface->interface);
1597   if (kresult != kIOReturnSuccess)
1598     usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1599 
1600   cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1601 
1602   return darwin_to_libusb (kresult);
1603 }
1604 
check_alt_setting_and_clear_halt(struct libusb_device_handle * dev_handle,uint8_t altsetting,struct darwin_interface * cInterface)1605 static int check_alt_setting_and_clear_halt(struct libusb_device_handle *dev_handle, uint8_t altsetting, struct darwin_interface *cInterface) {
1606   enum libusb_error ret;
1607   IOReturn kresult;
1608   uint8_t current_alt_setting;
1609 
1610   kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &current_alt_setting);
1611   if (kresult == kIOReturnSuccess && altsetting != current_alt_setting) {
1612     return LIBUSB_ERROR_PIPE;
1613   }
1614 
1615   for (int i = 0 ; i < cInterface->num_endpoints ; i++) {
1616     ret = darwin_clear_halt(dev_handle, cInterface->endpoint_addrs[i]);
1617     if (LIBUSB_SUCCESS != ret) {
1618       usbi_warn(HANDLE_CTX (dev_handle), "error clearing pipe halt for endpoint %d", i);
1619       if (LIBUSB_ERROR_NOT_FOUND == ret) {
1620         /* may need to re-open the interface */
1621         return ret;
1622       }
1623     }
1624   }
1625 
1626   return LIBUSB_SUCCESS;
1627 }
1628 
darwin_set_interface_altsetting(struct libusb_device_handle * dev_handle,uint8_t iface,uint8_t altsetting)1629 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1630   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1631   IOReturn kresult;
1632   enum libusb_error ret;
1633 
1634   /* current interface */
1635   struct darwin_interface *cInterface = &priv->interfaces[iface];
1636 
1637   if (!cInterface->interface)
1638     return LIBUSB_ERROR_NO_DEVICE;
1639 
1640   kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1641   if (kresult == kIOReturnSuccess) {
1642     /* update the list of endpoints */
1643     ret = get_endpoints (dev_handle, iface);
1644     if (ret) {
1645       /* this should not happen */
1646       darwin_release_interface (dev_handle, iface);
1647       usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1648     }
1649     return ret;
1650   }
1651 
1652   usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1653 
1654   ret = darwin_to_libusb(kresult);
1655   if (ret != LIBUSB_ERROR_PIPE) {
1656     return ret;
1657   }
1658 
1659   /* If a device only supports a default setting for the specified interface, then a STALL
1660      (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1661      Mimic the behaviour in e.g. the Linux kernel: in such case, reset all endpoints
1662      of the interface (as would have been done per 9.1.1.5) and return success. */
1663 
1664   ret = check_alt_setting_and_clear_halt(dev_handle, altsetting, cInterface);
1665   if (LIBUSB_ERROR_NOT_FOUND == ret) {
1666     /* For some reason we need to reclaim the interface after the pipe error with some versions of macOS */
1667     ret = darwin_claim_interface (dev_handle, iface);
1668     if (LIBUSB_SUCCESS != ret) {
1669       darwin_release_interface (dev_handle, iface);
1670       usbi_err (HANDLE_CTX (dev_handle), "could not reclaim interface: %s", darwin_error_str(kresult));
1671     }
1672     ret = check_alt_setting_and_clear_halt(dev_handle, altsetting, cInterface);
1673   }
1674 
1675   return ret;
1676 }
1677 
darwin_clear_halt(struct libusb_device_handle * dev_handle,unsigned char endpoint)1678 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1679   /* current interface */
1680   struct darwin_interface *cInterface;
1681   IOReturn kresult;
1682   uint8_t pipeRef;
1683 
1684   /* determine the interface/endpoint to use */
1685   if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1686     usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1687 
1688     return LIBUSB_ERROR_NOT_FOUND;
1689   }
1690 
1691   /* newer versions of darwin support clearing additional bits on the device's endpoint */
1692   kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1693   if (kresult != kIOReturnSuccess)
1694     usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1695 
1696   return darwin_to_libusb (kresult);
1697 }
1698 
darwin_restore_state(struct libusb_device_handle * dev_handle,int8_t active_config,unsigned long claimed_interfaces)1699 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1700                                  unsigned long claimed_interfaces) {
1701   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1702   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1703   int open_count = dpriv->open_count;
1704   int ret;
1705 
1706   struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1707 
1708   /* clear claimed interfaces temporarily */
1709   dev_handle->claimed_interfaces = 0;
1710 
1711   /* close and re-open the device */
1712   priv->is_open = false;
1713   dpriv->open_count = 1;
1714 
1715   /* clean up open interfaces */
1716   (void) darwin_close (dev_handle);
1717 
1718   /* re-open the device */
1719   ret = darwin_open (dev_handle);
1720   dpriv->open_count = open_count;
1721   if (LIBUSB_SUCCESS != ret) {
1722     /* could not restore configuration */
1723     return LIBUSB_ERROR_NOT_FOUND;
1724   }
1725 
1726   if (dpriv->active_config != active_config) {
1727     usbi_dbg (ctx, "darwin/restore_state: restoring configuration %d...", active_config);
1728 
1729     ret = darwin_set_configuration (dev_handle, active_config);
1730     if (LIBUSB_SUCCESS != ret) {
1731       usbi_dbg (ctx, "darwin/restore_state: could not restore configuration");
1732       return LIBUSB_ERROR_NOT_FOUND;
1733     }
1734   }
1735 
1736   usbi_dbg (ctx, "darwin/restore_state: reclaiming interfaces");
1737 
1738   if (claimed_interfaces) {
1739     for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1740       if (!(claimed_interfaces & (1U << iface))) {
1741         continue;
1742       }
1743 
1744       usbi_dbg (ctx, "darwin/restore_state: re-claiming interface %u", iface);
1745 
1746       ret = darwin_claim_interface (dev_handle, iface);
1747       if (LIBUSB_SUCCESS != ret) {
1748         usbi_dbg (ctx, "darwin/restore_state: could not claim interface %u", iface);
1749         return LIBUSB_ERROR_NOT_FOUND;
1750       }
1751 
1752       dev_handle->claimed_interfaces |= 1U << iface;
1753     }
1754   }
1755 
1756   usbi_dbg (ctx, "darwin/restore_state: device state restored");
1757 
1758   return LIBUSB_SUCCESS;
1759 }
1760 
darwin_reenumerate_device(struct libusb_device_handle * dev_handle,bool capture)1761 static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) {
1762   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1763   unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1764   int8_t active_config = dpriv->active_config;
1765   UInt32 options = 0;
1766   IOUSBDeviceDescriptor descriptor;
1767   IOUSBConfigurationDescriptorPtr cached_configuration;
1768   IOUSBConfigurationDescriptor *cached_configurations;
1769   IOReturn kresult;
1770   UInt8 i;
1771 
1772   struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1773 
1774   if (dpriv->in_reenumerate) {
1775     /* ack, two (or more) threads are trying to reset the device! abort! */
1776     return LIBUSB_ERROR_NOT_FOUND;
1777   }
1778 
1779   dpriv->in_reenumerate = true;
1780 
1781   /* store copies of descriptors so they can be compared after the reset */
1782   memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1783   cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1784 
1785   for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1786     (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1787     memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1788   }
1789 
1790   /* if we need to release capture */
1791   if (HAS_CAPTURE_DEVICE()) {
1792     if (capture) {
1793 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
1794       options |= kUSBReEnumerateCaptureDeviceMask;
1795 #endif
1796     }
1797   } else {
1798     capture = false;
1799   }
1800 
1801   /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1802   kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
1803   if (kresult != kIOReturnSuccess) {
1804     usbi_err (ctx, "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1805     dpriv->in_reenumerate = false;
1806     return darwin_to_libusb (kresult);
1807   }
1808 
1809   /* capture mode does not re-enumerate but it does require re-open */
1810   if (capture) {
1811     usbi_dbg (ctx, "darwin/reenumerate_device: restoring state...");
1812     dpriv->in_reenumerate = false;
1813     return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1814   }
1815 
1816   usbi_dbg (ctx, "darwin/reenumerate_device: waiting for re-enumeration to complete...");
1817 
1818   struct timespec start;
1819   usbi_get_monotonic_time(&start);
1820 
1821   while (dpriv->in_reenumerate) {
1822     struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1823     nanosleep (&delay, NULL);
1824 
1825     struct timespec now;
1826     usbi_get_monotonic_time(&now);
1827     unsigned long elapsed_us = (now.tv_sec - start.tv_sec) * USEC_PER_SEC +
1828                                 (now.tv_nsec - start.tv_nsec) / 1000;
1829 
1830     if (elapsed_us >= DARWIN_REENUMERATE_TIMEOUT_US) {
1831       usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate");
1832       dpriv->in_reenumerate = false;
1833       return LIBUSB_ERROR_TIMEOUT;
1834     }
1835   }
1836 
1837   /* compare descriptors */
1838   usbi_dbg (ctx, "darwin/reenumerate_device: checking whether descriptors changed");
1839 
1840   if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1841     /* device descriptor changed. need to return not found. */
1842     usbi_dbg (ctx, "darwin/reenumerate_device: device descriptor changed");
1843     return LIBUSB_ERROR_NOT_FOUND;
1844   }
1845 
1846   for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1847     (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1848     if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1849       usbi_dbg (ctx, "darwin/reenumerate_device: configuration descriptor %d changed", i);
1850       return LIBUSB_ERROR_NOT_FOUND;
1851     }
1852   }
1853 
1854   usbi_dbg (ctx, "darwin/reenumerate_device: device reset complete. restoring state...");
1855 
1856   return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1857 }
1858 
darwin_reset_device(struct libusb_device_handle * dev_handle)1859 static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
1860   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1861   IOReturn kresult;
1862   enum libusb_error ret;
1863 
1864 #if !defined(TARGET_OS_OSX) || TARGET_OS_OSX == 1
1865   if (dpriv->capture_count > 0) {
1866     /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
1867     kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
1868     ret = darwin_to_libusb (kresult);
1869   } else {
1870     ret = darwin_reenumerate_device (dev_handle, false);
1871   }
1872 #else
1873   /* ResetDevice() is missing on non-macOS platforms */
1874   ret = darwin_reenumerate_device (dev_handle, false);
1875   if ((ret == LIBUSB_SUCCESS || ret == LIBUSB_ERROR_NOT_FOUND) && dpriv->capture_count > 0) {
1876     int capture_count;
1877     int8_t active_config = dpriv->active_config;
1878     unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1879 
1880     /* save old capture_count */
1881     capture_count = dpriv->capture_count;
1882     /* reset capture count */
1883     dpriv->capture_count = 0;
1884     /* attempt to detach kernel driver again as it is now re-attached */
1885     ret = darwin_detach_kernel_driver (dev_handle, 0);
1886     if (ret != LIBUSB_SUCCESS) {
1887       return ret;
1888     }
1889     /* restore capture_count */
1890     dpriv->capture_count = capture_count;
1891     /* restore configuration */
1892     ret = darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1893   }
1894 #endif
1895   return ret;
1896 }
1897 
usb_find_interface_matching_location(const io_name_t class_name,UInt8 interface_number,UInt32 location)1898 static io_service_t usb_find_interface_matching_location (const io_name_t class_name, UInt8 interface_number, UInt32 location) {
1899   CFMutableDictionaryRef matchingDict = IOServiceMatching (class_name);
1900   CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault, 0,
1901                                                                         &kCFTypeDictionaryKeyCallBacks,
1902                                                                         &kCFTypeDictionaryValueCallBacks);
1903   CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
1904   CFTypeRef interfaceCF =  CFNumberCreate (NULL, kCFNumberSInt8Type, &interface_number);
1905 
1906   CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
1907   CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
1908   CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBHostMatchingPropertyInterfaceNumber), interfaceCF);
1909 
1910   CFRelease (interfaceCF);
1911   CFRelease (locationCF);
1912   CFRelease (propertyMatchDict);
1913 
1914   return IOServiceGetMatchingService (darwin_default_master_port, matchingDict);
1915 }
1916 
darwin_kernel_driver_active(struct libusb_device_handle * dev_handle,uint8_t interface)1917 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1918   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1919   io_service_t usb_interface, child = IO_OBJECT_NULL;
1920 
1921   /* locate the IO registry entry for this interface */
1922   usb_interface = usb_find_interface_matching_location (kIOUSBHostInterfaceClassName, interface, dpriv->location);
1923   if (0 == usb_interface) {
1924     /* check for the legacy class entry */
1925     usb_interface = usb_find_interface_matching_location (kIOUSBInterfaceClassName, interface, dpriv->location);
1926     if (0 == usb_interface) {
1927       return LIBUSB_ERROR_NOT_FOUND;
1928     }
1929   }
1930 
1931   /* if the IO object has a child entry in the IO Registry it has a kernel driver attached */
1932   (void) IORegistryEntryGetChildEntry (usb_interface, kIOServicePlane, &child);
1933   IOObjectRelease (usb_interface);
1934   if (IO_OBJECT_NULL != child) {
1935     IOObjectRelease (child);
1936     return 1;
1937   }
1938 
1939   /* no driver */
1940   return 0;
1941 }
1942 
darwin_destroy_device(struct libusb_device * dev)1943 static void darwin_destroy_device(struct libusb_device *dev) {
1944   struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1945 
1946   if (dpriv->dev) {
1947     /* need to hold the lock in case this is the last reference to the device */
1948     usbi_mutex_lock(&darwin_cached_devices_lock);
1949     darwin_deref_cached_device (dpriv->dev);
1950     dpriv->dev = NULL;
1951     usbi_mutex_unlock(&darwin_cached_devices_lock);
1952   }
1953 }
1954 
submit_bulk_transfer(struct usbi_transfer * itransfer)1955 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1956   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1957 
1958   IOReturn               ret;
1959   uint8_t                transferType;
1960   uint8_t                pipeRef;
1961   uint16_t               maxPacketSize;
1962 
1963   struct darwin_interface *cInterface;
1964 #if InterfaceVersion >= 550
1965   IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1966 #else
1967   /* None of the values below are used in libusb for bulk transfers */
1968   uint8_t                 direction, number, interval;
1969 #endif
1970 
1971   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1972     usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1973 
1974     return LIBUSB_ERROR_NOT_FOUND;
1975   }
1976 
1977 #if InterfaceVersion >= 550
1978   ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1979 
1980   transferType = pipeProperties.bTransferType;
1981   maxPacketSize = pipeProperties.wMaxPacketSize;
1982 #else
1983   ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1984                                                        &transferType, &maxPacketSize, &interval);
1985 #endif
1986 
1987   if (ret) {
1988     usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1989               darwin_error_str(ret), ret);
1990     return darwin_to_libusb (ret);
1991   }
1992 
1993   if (0 != (transfer->length % maxPacketSize)) {
1994     /* do not need a zero packet */
1995     transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1996   }
1997 
1998   /* submit the request */
1999   /* timeouts are unavailable on interrupt endpoints */
2000   if (transferType == kUSBInterrupt) {
2001     if (IS_XFERIN(transfer))
2002       ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
2003                                                       (UInt32)transfer->length, darwin_async_io_callback, itransfer);
2004     else
2005       ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
2006                                                        (UInt32)transfer->length, darwin_async_io_callback, itransfer);
2007   } else {
2008     itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2009 
2010     if (IS_XFERIN(transfer))
2011       ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
2012                                                         (UInt32)transfer->length, transfer->timeout, transfer->timeout,
2013                                                         darwin_async_io_callback, itransfer);
2014     else
2015       ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
2016                                                          (UInt32)transfer->length, transfer->timeout, transfer->timeout,
2017                                                          darwin_async_io_callback, itransfer);
2018   }
2019 
2020   if (ret)
2021     usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
2022                darwin_error_str(ret), ret);
2023 
2024   return darwin_to_libusb (ret);
2025 }
2026 
2027 #if InterfaceVersion >= 550
submit_stream_transfer(struct usbi_transfer * itransfer)2028 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
2029   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2030   struct darwin_interface *cInterface;
2031   uint8_t pipeRef;
2032   IOReturn ret;
2033 
2034   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2035     usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2036 
2037     return LIBUSB_ERROR_NOT_FOUND;
2038   }
2039 
2040   itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2041 
2042   if (IS_XFERIN(transfer))
2043     ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
2044                                                              transfer->buffer, (UInt32)transfer->length, transfer->timeout,
2045                                                              transfer->timeout, darwin_async_io_callback, itransfer);
2046   else
2047     ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
2048                                                               transfer->buffer, (UInt32)transfer->length, transfer->timeout,
2049                                                               transfer->timeout, darwin_async_io_callback, itransfer);
2050 
2051   if (ret)
2052     usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
2053                darwin_error_str(ret), ret);
2054 
2055   return darwin_to_libusb (ret);
2056 }
2057 #endif
2058 
submit_iso_transfer(struct usbi_transfer * itransfer)2059 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
2060   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2061   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2062 
2063   IOReturn kresult;
2064   uint8_t pipeRef, interval;
2065   UInt64 frame;
2066   AbsoluteTime atTime;
2067   int i;
2068 #if InterfaceVersion >= 550
2069   IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
2070 #else
2071   /* None of the values below are used in libusb for iso transfers */
2072   uint8_t direction, number, transferType;
2073   uint16_t maxPacketSize;
2074 #endif
2075 
2076   struct darwin_interface *cInterface;
2077 
2078   /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
2079   if (tpriv->num_iso_packets != transfer->num_iso_packets) {
2080     free(tpriv->isoc_framelist);
2081     tpriv->isoc_framelist = NULL;
2082   }
2083 
2084   if (!tpriv->isoc_framelist) {
2085     tpriv->num_iso_packets = transfer->num_iso_packets;
2086     tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
2087     if (!tpriv->isoc_framelist)
2088       return LIBUSB_ERROR_NO_MEM;
2089   }
2090 
2091   /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
2092   for (i = 0 ; i < transfer->num_iso_packets ; i++) {
2093     unsigned int length = transfer->iso_packet_desc[i].length;
2094     assert(length <= UINT16_MAX);
2095     tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
2096   }
2097 
2098   /* determine the interface/endpoint to use */
2099   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2100     usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2101 
2102     return LIBUSB_ERROR_NOT_FOUND;
2103   }
2104 
2105   /* determine the properties of this endpoint and the speed of the device */
2106 #if InterfaceVersion >= 550
2107   kresult = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
2108   interval = pipeProperties.bInterval;
2109 #else
2110   kresult = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
2111                                                  &transferType, &maxPacketSize, &interval);
2112 #endif
2113   if (kresult != kIOReturnSuccess) {
2114     usbi_err (TRANSFER_CTX (transfer), "failed to get pipe properties: %d", kresult);
2115     free(tpriv->isoc_framelist);
2116     tpriv->isoc_framelist = NULL;
2117 
2118     return darwin_to_libusb (kresult);
2119   }
2120 
2121   /* Last but not least we need the bus frame number */
2122   kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
2123   if (kresult != kIOReturnSuccess) {
2124     usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
2125     free(tpriv->isoc_framelist);
2126     tpriv->isoc_framelist = NULL;
2127 
2128     return darwin_to_libusb (kresult);
2129   }
2130 
2131   /* schedule for a frame a little in the future */
2132   frame += 4;
2133 
2134   if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
2135     frame = cInterface->frames[transfer->endpoint];
2136 
2137   /* submit the request */
2138   if (IS_XFERIN(transfer))
2139     kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2140                                                              (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2141                                                              itransfer);
2142   else
2143     kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2144                                                               (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2145                                                               itransfer);
2146 
2147   if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
2148     /* Full speed */
2149     cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
2150   else
2151     /* High/super speed */
2152     cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
2153 
2154   if (kresult != kIOReturnSuccess) {
2155     usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
2156                darwin_error_str(kresult));
2157     free (tpriv->isoc_framelist);
2158     tpriv->isoc_framelist = NULL;
2159   }
2160 
2161   return darwin_to_libusb (kresult);
2162 }
2163 
submit_control_transfer(struct usbi_transfer * itransfer)2164 static int submit_control_transfer(struct usbi_transfer *itransfer) {
2165   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2166   struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
2167   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2168   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2169 
2170   IOReturn               kresult;
2171 
2172   memset(&tpriv->req, 0, sizeof(tpriv->req));
2173 
2174   /* IOUSBDeviceInterface expects the request in cpu endianness */
2175   tpriv->req.bmRequestType     = setup->bmRequestType;
2176   tpriv->req.bRequest          = setup->bRequest;
2177   /* these values should be in bus order from libusb_fill_control_setup */
2178   tpriv->req.wValue            = OSSwapLittleToHostInt16 (setup->wValue);
2179   tpriv->req.wIndex            = OSSwapLittleToHostInt16 (setup->wIndex);
2180   tpriv->req.wLength           = OSSwapLittleToHostInt16 (setup->wLength);
2181   /* data is stored after the libusb control block */
2182   tpriv->req.pData             = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
2183   tpriv->req.completionTimeout = transfer->timeout;
2184   tpriv->req.noDataTimeout     = transfer->timeout;
2185 
2186   itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2187 
2188   /* all transfers in libusb-1.0 are async */
2189 
2190   if (transfer->endpoint) {
2191     struct darwin_interface *cInterface;
2192     uint8_t                 pipeRef;
2193 
2194     if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2195       usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2196 
2197       return LIBUSB_ERROR_NOT_FOUND;
2198     }
2199 
2200     kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2201   } else
2202     /* control request on endpoint 0 */
2203     kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2204 
2205   if (kresult != kIOReturnSuccess)
2206     usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2207 
2208   return darwin_to_libusb (kresult);
2209 }
2210 
darwin_submit_transfer(struct usbi_transfer * itransfer)2211 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2212   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2213 
2214   switch (transfer->type) {
2215   case LIBUSB_TRANSFER_TYPE_CONTROL:
2216     return submit_control_transfer(itransfer);
2217   case LIBUSB_TRANSFER_TYPE_BULK:
2218   case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2219     return submit_bulk_transfer(itransfer);
2220   case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2221     return submit_iso_transfer(itransfer);
2222   case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2223 #if InterfaceVersion >= 550
2224     return submit_stream_transfer(itransfer);
2225 #else
2226     usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2227     return LIBUSB_ERROR_NOT_SUPPORTED;
2228 #endif
2229   default:
2230     usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2231     return LIBUSB_ERROR_INVALID_PARAM;
2232   }
2233 }
2234 
cancel_control_transfer(struct usbi_transfer * itransfer)2235 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2236   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2237   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2238   IOReturn kresult;
2239 
2240   usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2241 
2242   if (!dpriv->device)
2243     return LIBUSB_ERROR_NO_DEVICE;
2244 
2245   kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2246 
2247   return darwin_to_libusb (kresult);
2248 }
2249 
darwin_abort_transfers(struct usbi_transfer * itransfer)2250 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2251   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2252   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2253   struct darwin_interface *cInterface;
2254   uint8_t pipeRef, iface;
2255   IOReturn kresult;
2256 
2257   struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2258 
2259   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2260     usbi_err (ctx, "endpoint not found on any open interface");
2261 
2262     return LIBUSB_ERROR_NOT_FOUND;
2263   }
2264 
2265   if (!dpriv->device)
2266     return LIBUSB_ERROR_NO_DEVICE;
2267 
2268   usbi_warn (ctx, "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2269 
2270   /* abort transactions */
2271 #if InterfaceVersion >= 550
2272   if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2273     (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2274   else
2275 #endif
2276     (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2277 
2278   usbi_dbg (ctx, "calling clear pipe stall to clear the data toggle bit");
2279 
2280   /* newer versions of darwin support clearing additional bits on the device's endpoint */
2281   kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2282 
2283   return darwin_to_libusb (kresult);
2284 }
2285 
darwin_cancel_transfer(struct usbi_transfer * itransfer)2286 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2287   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2288 
2289   switch (transfer->type) {
2290   case LIBUSB_TRANSFER_TYPE_CONTROL:
2291     return cancel_control_transfer(itransfer);
2292   case LIBUSB_TRANSFER_TYPE_BULK:
2293   case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2294   case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2295     return darwin_abort_transfers (itransfer);
2296   default:
2297     usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2298     return LIBUSB_ERROR_INVALID_PARAM;
2299   }
2300 }
2301 
darwin_async_io_callback(void * refcon,IOReturn result,void * arg0)2302 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2303   struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2304   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2305   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2306 
2307   usbi_dbg (TRANSFER_CTX(transfer), "an async io operation has completed");
2308 
2309   /* if requested write a zero packet */
2310   if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2311     struct darwin_interface *cInterface;
2312     uint8_t pipeRef;
2313 
2314     (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2315 
2316     (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2317   }
2318 
2319   tpriv->result = result;
2320   tpriv->size = (UInt32) (uintptr_t) arg0;
2321 
2322   /* signal the core that this transfer is complete */
2323   usbi_signal_transfer_completion(itransfer);
2324 }
2325 
darwin_transfer_status(struct usbi_transfer * itransfer,IOReturn result)2326 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2327   if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2328     result = kIOUSBTransactionTimeout;
2329 
2330   struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2331 
2332   switch (result) {
2333   case kIOReturnUnderrun:
2334   case kIOReturnSuccess:
2335     return LIBUSB_TRANSFER_COMPLETED;
2336   case kIOReturnAborted:
2337     return LIBUSB_TRANSFER_CANCELLED;
2338   case kIOUSBPipeStalled:
2339     usbi_dbg (ctx, "transfer error: pipe is stalled");
2340     return LIBUSB_TRANSFER_STALL;
2341   case kIOReturnOverrun:
2342     usbi_warn (ctx, "transfer error: data overrun");
2343     return LIBUSB_TRANSFER_OVERFLOW;
2344   case kIOUSBTransactionTimeout:
2345     usbi_warn (ctx, "transfer error: timed out");
2346     itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2347     return LIBUSB_TRANSFER_TIMED_OUT;
2348   default:
2349     usbi_warn (ctx, "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2350     return LIBUSB_TRANSFER_ERROR;
2351   }
2352 }
2353 
darwin_handle_transfer_completion(struct usbi_transfer * itransfer)2354 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2355   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2356   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2357   const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2358   const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2359   bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2360   struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2361 
2362   if (transfer->type > max_transfer_type) {
2363     usbi_err (ctx, "unknown endpoint type %d", transfer->type);
2364     return LIBUSB_ERROR_INVALID_PARAM;
2365   }
2366 
2367   if (NULL == tpriv) {
2368     usbi_err (ctx, "malformed request is missing transfer priv");
2369     return LIBUSB_ERROR_INVALID_PARAM;
2370   }
2371 
2372   usbi_dbg (ctx, "handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2373 
2374   if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
2375     if (is_isoc && tpriv->isoc_framelist) {
2376       /* copy isochronous results back */
2377 
2378       for (int i = 0; i < transfer->num_iso_packets ; i++) {
2379         struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2380         lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2381         lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2382       }
2383     } else if (!is_isoc) {
2384       itransfer->transferred += tpriv->size;
2385     }
2386   }
2387 
2388   /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2389   return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2390 }
2391 
2392 #if !defined(HAVE_CLOCK_GETTIME)
usbi_get_monotonic_time(struct timespec * tp)2393 void usbi_get_monotonic_time(struct timespec *tp) {
2394   mach_timespec_t sys_time;
2395 
2396   /* use system boot time as reference for the monotonic clock */
2397   clock_get_time (clock_monotonic, &sys_time);
2398 
2399   tp->tv_sec  = sys_time.tv_sec;
2400   tp->tv_nsec = sys_time.tv_nsec;
2401 }
2402 
usbi_get_real_time(struct timespec * tp)2403 void usbi_get_real_time(struct timespec *tp) {
2404   mach_timespec_t sys_time;
2405 
2406   /* CLOCK_REALTIME represents time since the epoch */
2407   clock_get_time (clock_realtime, &sys_time);
2408 
2409   tp->tv_sec  = sys_time.tv_sec;
2410   tp->tv_nsec = sys_time.tv_nsec;
2411 }
2412 #endif
2413 
2414 #if InterfaceVersion >= 550
darwin_alloc_streams(struct libusb_device_handle * dev_handle,uint32_t num_streams,unsigned char * endpoints,int num_endpoints)2415 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2416                                  int num_endpoints) {
2417   struct darwin_interface *cInterface;
2418   UInt32 supportsStreams;
2419   uint8_t pipeRef;
2420   int rc, i;
2421 
2422   /* find the minimum number of supported streams on the endpoint list */
2423   for (i = 0 ; i < num_endpoints ; ++i) {
2424     if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2425       return rc;
2426     }
2427 
2428     (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2429     if (num_streams > supportsStreams)
2430       num_streams = supportsStreams;
2431   }
2432 
2433   /* it is an error if any endpoint in endpoints does not support streams */
2434   if (0 == num_streams)
2435     return LIBUSB_ERROR_INVALID_PARAM;
2436 
2437   /* create the streams */
2438   for (i = 0 ; i < num_endpoints ; ++i) {
2439     (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2440 
2441     rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2442     if (kIOReturnSuccess != rc)
2443       return darwin_to_libusb(rc);
2444   }
2445 
2446   assert(num_streams <= INT_MAX);
2447   return (int)num_streams;
2448 }
2449 
darwin_free_streams(struct libusb_device_handle * dev_handle,unsigned char * endpoints,int num_endpoints)2450 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2451   struct darwin_interface *cInterface;
2452   UInt32 supportsStreams;
2453   uint8_t pipeRef;
2454   int rc;
2455 
2456   for (int i = 0 ; i < num_endpoints ; ++i) {
2457     if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2458       return rc;
2459 
2460     (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2461     if (0 == supportsStreams)
2462       return LIBUSB_ERROR_INVALID_PARAM;
2463 
2464     rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2465     if (kIOReturnSuccess != rc)
2466       return darwin_to_libusb(rc);
2467   }
2468 
2469   return LIBUSB_SUCCESS;
2470 }
2471 #endif
2472 
2473 #if InterfaceVersion >= 700
2474 
2475 /* macOS APIs for getting entitlement values */
2476 
2477 #if !defined(TARGET_OS_OSX) || TARGET_OS_OSX == 1
2478 #include <Security/Security.h>
2479 #else
2480 typedef struct __SecTask *SecTaskRef;
2481 extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator);
2482 extern CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error);
2483 #endif
2484 
darwin_has_capture_entitlements(void)2485 static bool darwin_has_capture_entitlements (void) {
2486   SecTaskRef task;
2487   CFTypeRef value;
2488   bool entitled;
2489 
2490   task = SecTaskCreateFromSelf (kCFAllocatorDefault);
2491   if (task == NULL) {
2492     return false;
2493   }
2494   value = SecTaskCopyValueForEntitlement(task, CFSTR("com.apple.vm.device-access"), NULL);
2495   CFRelease (task);
2496   entitled = value && (CFGetTypeID (value) == CFBooleanGetTypeID ()) && CFBooleanGetValue (value);
2497   if (value) {
2498     CFRelease (value);
2499   }
2500   return entitled;
2501 }
2502 
darwin_reload_device(struct libusb_device_handle * dev_handle)2503 static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
2504   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2505   enum libusb_error err;
2506 
2507   usbi_mutex_lock(&darwin_cached_devices_lock);
2508   (*(dpriv->device))->Release(dpriv->device);
2509   dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
2510   if (!dpriv->device) {
2511     err = LIBUSB_ERROR_NO_DEVICE;
2512   } else {
2513     err = LIBUSB_SUCCESS;
2514   }
2515   usbi_mutex_unlock(&darwin_cached_devices_lock);
2516 
2517   return err;
2518 }
2519 
2520 /* On macOS, we capture an entire device at once, not individual interfaces. */
2521 
darwin_detach_kernel_driver(struct libusb_device_handle * dev_handle,uint8_t interface)2522 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2523   UNUSED(interface);
2524   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2525   IOReturn kresult;
2526   enum libusb_error err;
2527   struct libusb_context *ctx = HANDLE_CTX (dev_handle);
2528 
2529   if (HAS_CAPTURE_DEVICE()) {
2530   } else {
2531     return LIBUSB_ERROR_NOT_SUPPORTED;
2532   }
2533 
2534   if (dpriv->capture_count == 0) {
2535     usbi_dbg (ctx, "attempting to detach kernel driver from device");
2536 
2537     if (darwin_has_capture_entitlements ()) {
2538       /* request authorization */
2539       kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
2540       if (kresult != kIOReturnSuccess) {
2541         usbi_warn (ctx, "IOServiceAuthorize: %s", darwin_error_str(kresult));
2542         return darwin_to_libusb (kresult);
2543       }
2544 
2545       /* we need start() to be called again for authorization status to refresh */
2546       err = darwin_reload_device (dev_handle);
2547       if (err != LIBUSB_SUCCESS) {
2548         return err;
2549       }
2550     } else {
2551       usbi_info (ctx, "no capture entitlements. may not be able to detach the kernel driver for this device");
2552       if (0 != geteuid()) {
2553         usbi_warn (ctx, "USB device capture requires either an entitlement (com.apple.vm.device-access) or root privilege");
2554         return LIBUSB_ERROR_ACCESS;
2555       }
2556     }
2557 
2558     /* reset device to release existing drivers */
2559     err = darwin_reenumerate_device (dev_handle, true);
2560     if (err != LIBUSB_SUCCESS) {
2561       return err;
2562     }
2563   }
2564   dpriv->capture_count++;
2565   return LIBUSB_SUCCESS;
2566 }
2567 
2568 
darwin_attach_kernel_driver(struct libusb_device_handle * dev_handle,uint8_t interface)2569 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2570   UNUSED(interface);
2571   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2572 
2573   if (HAS_CAPTURE_DEVICE()) {
2574   } else {
2575     return LIBUSB_ERROR_NOT_SUPPORTED;
2576   }
2577 
2578   dpriv->capture_count--;
2579   if (dpriv->capture_count > 0) {
2580     return LIBUSB_SUCCESS;
2581   }
2582 
2583   usbi_dbg (HANDLE_CTX (dev_handle), "reenumerating device for kernel driver attach");
2584 
2585   /* reset device to attach kernel drivers */
2586   return darwin_reenumerate_device (dev_handle, false);
2587 }
2588 
darwin_capture_claim_interface(struct libusb_device_handle * dev_handle,uint8_t iface)2589 static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2590   enum libusb_error ret;
2591   if (dev_handle->auto_detach_kernel_driver && darwin_kernel_driver_active(dev_handle, iface)) {
2592     ret = darwin_detach_kernel_driver (dev_handle, iface);
2593     if (ret != LIBUSB_SUCCESS) {
2594       usbi_info (HANDLE_CTX (dev_handle), "failed to auto-detach the kernel driver for this device, ret=%d", ret);
2595     }
2596   }
2597 
2598   return darwin_claim_interface (dev_handle, iface);
2599 }
2600 
darwin_capture_release_interface(struct libusb_device_handle * dev_handle,uint8_t iface)2601 static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2602   enum libusb_error ret;
2603   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2604 
2605   ret = darwin_release_interface (dev_handle, iface);
2606   if (ret != LIBUSB_SUCCESS) {
2607     return ret;
2608   }
2609 
2610   if (dev_handle->auto_detach_kernel_driver && dpriv->capture_count > 0) {
2611     ret = darwin_attach_kernel_driver (dev_handle, iface);
2612     if (LIBUSB_SUCCESS != ret) {
2613       usbi_info (HANDLE_CTX (dev_handle), "on attempt to reattach the kernel driver got ret=%d", ret);
2614     }
2615     /* ignore the error as the interface was successfully released */
2616   }
2617 
2618   return LIBUSB_SUCCESS;
2619 }
2620 
2621 #endif
2622 
2623 const struct usbi_os_backend usbi_backend = {
2624         .name = "Darwin",
2625         .caps = USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
2626         .init = darwin_init,
2627         .exit = darwin_exit,
2628         .get_active_config_descriptor = darwin_get_active_config_descriptor,
2629         .get_config_descriptor = darwin_get_config_descriptor,
2630         .hotplug_poll = darwin_hotplug_poll,
2631 
2632         .open = darwin_open,
2633         .close = darwin_close,
2634         .get_configuration = darwin_get_configuration,
2635         .set_configuration = darwin_set_configuration,
2636 
2637         .set_interface_altsetting = darwin_set_interface_altsetting,
2638         .clear_halt = darwin_clear_halt,
2639         .reset_device = darwin_reset_device,
2640 
2641 #if InterfaceVersion >= 550
2642         .alloc_streams = darwin_alloc_streams,
2643         .free_streams = darwin_free_streams,
2644 #endif
2645 
2646         .kernel_driver_active = darwin_kernel_driver_active,
2647 
2648 #if InterfaceVersion >= 700
2649         .detach_kernel_driver = darwin_detach_kernel_driver,
2650         .attach_kernel_driver = darwin_attach_kernel_driver,
2651         .claim_interface = darwin_capture_claim_interface,
2652         .release_interface = darwin_capture_release_interface,
2653 #else
2654         .claim_interface = darwin_claim_interface,
2655         .release_interface = darwin_release_interface,
2656 #endif
2657 
2658         .destroy_device = darwin_destroy_device,
2659 
2660         .submit_transfer = darwin_submit_transfer,
2661         .cancel_transfer = darwin_cancel_transfer,
2662 
2663         .handle_transfer_completion = darwin_handle_transfer_completion,
2664 
2665         .device_priv_size = sizeof(struct darwin_device_priv),
2666         .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2667         .transfer_priv_size = sizeof(struct darwin_transfer_priv),
2668 };
2669