📄 darwin.c
字号:
if ( usb_debug > 1 ) fprintf ( stderr, "get_endpoints: interface is %p\n", device->interface ); USB_ERROR_STR ( -ret, "get_endpoints: can't get number of endpoints for interface" ); } free (device->endpoint_addrs); device->endpoint_addrs = calloc (sizeof (unsigned char), numep); /* iterate through pipe references */ for (i = 1 ; i <= numep ; i++) { ret = (*(device->interface))->GetPipeProperties(device->interface, i, &direction, &number, &dont_care1, &dont_care2, &dont_care3); if (ret != kIOReturnSuccess) { fprintf (stderr, "get_endpoints: an error occurred getting pipe information on pipe %d\n", i ); USB_ERROR_STR(-darwin_to_errno(ret), "get_endpoints(GetPipeProperties): %s", darwin_error_str(ret)); } if (usb_debug > 1) fprintf (stderr, "get_endpoints: Pipe %i: DIR: %i number: %i\n", i, direction, number); device->endpoint_addrs[i - 1] = ((direction << 7 & USB_ENDPOINT_DIR_MASK) | (number & USB_ENDPOINT_ADDRESS_MASK)); } device->num_endpoints = numep; if (usb_debug > 1) fprintf(stderr, "libusb/darwin.c get_endpoints: complete.\n"); return 0;}static int claim_interface (usb_dev_handle *dev, int interface){ io_iterator_t interface_iterator; io_service_t usbInterface = IO_OBJECT_NULL; io_return_t result; io_cf_plugin_ref_t *plugInInterface = NULL; IOUSBFindInterfaceRequest request; struct darwin_dev_handle *device; long score; int current_interface; device = dev->impl_info; request.bInterfaceClass = kIOUSBFindInterfaceDontCare; request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; result = (*(device->device))->CreateInterfaceIterator(device->device, &request, &interface_iterator); if (result != kIOReturnSuccess) USB_ERROR_STR (-darwin_to_errno(result), "claim_interface(CreateInterfaceIterator): %s", darwin_error_str(result)); for ( current_interface=0 ; current_interface <= interface ; current_interface++ ) { usbInterface = IOIteratorNext(interface_iterator); if ( usb_debug > 3 ) fprintf ( stderr, "Interface %d of device is 0x%08x\n", current_interface, usbInterface ); } current_interface--; /* the interface iterator is no longer needed, release it */ IOObjectRelease(interface_iterator); if (!usbInterface) { u_int8_t nConfig; /* Index of configuration to use */ IOUSBConfigurationDescriptorPtr configDesc; /* to describe which configuration to select */ /* Only a composite class device with no vendor-specific driver will be configured. Otherwise, we need to do it ourselves, or there will be no interfaces for the device. */ if ( usb_debug > 3 ) fprintf ( stderr,"claim_interface: No interface found; selecting configuration\n" ); result = (*(device->device))->GetNumberOfConfigurations ( device->device, &nConfig ); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(GetNumberOfConfigurations): %s", darwin_error_str(result)); if (nConfig < 1) USB_ERROR_STR(-ENXIO ,"claim_interface(GetNumberOfConfigurations): no configurations"); else if ( nConfig > 1 && usb_debug > 0 ) fprintf ( stderr, "claim_interface: device has more than one" " configuration, using the first (warning)\n" ); if ( usb_debug > 3 ) fprintf ( stderr, "claim_interface: device has %d configuration%s\n", (int)nConfig, (nConfig>1?"s":"") ); /* Always use the first configuration */ result = (*(device->device))->GetConfigurationDescriptorPtr ( (device->device), 0, &configDesc ); if (result != kIOReturnSuccess) { if (device->open == 1) { (*(device->device))->USBDeviceClose ( (device->device) ); (*(device->device))->Release ( (device->device) ); } USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(GetConfigurationDescriptorPtr): %s", darwin_error_str(result)); } else if ( usb_debug > 3 ) fprintf ( stderr, "claim_interface: configuration value is %d\n", configDesc->bConfigurationValue ); if (device->open == 1) { result = (*(device->device))->SetConfiguration ( (device->device), configDesc->bConfigurationValue ); if (result != kIOReturnSuccess) { (*(device->device))->USBDeviceClose ( (device->device) ); (*(device->device))->Release ( (device->device) ); USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(SetConfiguration): %s", darwin_error_str(result)); } dev->config = configDesc->bConfigurationValue; } request.bInterfaceClass = kIOUSBFindInterfaceDontCare; request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; /* Now go back and get the chosen interface */ result = (*(device->device))->CreateInterfaceIterator(device->device, &request, &interface_iterator); if (result != kIOReturnSuccess) USB_ERROR_STR (-darwin_to_errno(result), "claim_interface(CreateInterfaceIterator): %s", darwin_error_str(result)); for (current_interface = 0 ; current_interface <= interface ; current_interface++) { usbInterface = IOIteratorNext(interface_iterator); if ( usb_debug > 3 ) fprintf ( stderr, "claim_interface: Interface %d of device is 0x%08x\n", current_interface, usbInterface ); } current_interface--; /* the interface iterator is no longer needed, release it */ IOObjectRelease(interface_iterator); if (!usbInterface) USB_ERROR_STR (-ENOENT, "claim_interface: interface iterator returned NULL"); } result = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); /* No longer need the usbInterface object after getting the plug-in */ result = IOObjectRelease(usbInterface); if (result || !plugInInterface) USB_ERROR(-ENOENT); /* Now create the device interface for the interface */ result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(InterfaceInterfaceID), (LPVOID) &device->interface); /* No longer need the intermediate plug-in */ (*plugInInterface)->Stop(plugInInterface); IODestroyPlugInInterface (plugInInterface); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(QueryInterface): %s", darwin_error_str(result)); if (!device->interface) USB_ERROR(-EACCES); if ( usb_debug > 3 ) fprintf ( stderr, "claim_interface: Interface %d of device from QueryInterface is %p\n", current_interface, device->interface); /* claim the interface */ result = (*(device->interface))->USBInterfaceOpen(device->interface); if (result) USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(USBInterfaceOpen): %s", darwin_error_str(result)); result = get_endpoints (device); if (result) { /* this should not happen */ usb_release_interface (dev, interface); USB_ERROR_STR ( result, "claim_interface: could not build endpoint table"); } return 0;}int usb_set_configuration (usb_dev_handle *dev, int configuration){ struct darwin_dev_handle *device; io_return_t result; int interface; if ( usb_debug > 3 ) fprintf ( stderr, "usb_set_configuration: called for config %x\n", configuration ); if (!dev) USB_ERROR_STR ( -ENXIO, "usb_set_configuration: called with null device\n" ); if ((device = dev->impl_info) == NULL) USB_ERROR_STR ( -ENOENT, "usb_set_configuration: device not properly initialized" ); /* Setting configuration will invalidate the interface, so we need to reclaim it. First, dispose of existing interface, if any. */ interface = dev->interface; if ( device->interface ) usb_release_interface(dev, dev->interface); result = (*(device->device))->SetConfiguration(device->device, configuration); if (result) USB_ERROR_STR(-darwin_to_errno(result), "usb_set_configuration(SetConfiguration): %s", darwin_error_str(result)); /* Reclaim interface */ if (interface != -1) result = usb_claim_interface (dev, interface); dev->config = configuration; return result;}int usb_claim_interface(usb_dev_handle *dev, int interface){ struct darwin_dev_handle *device = dev->impl_info; io_return_t result; if ( usb_debug > 3 ) fprintf ( stderr, "usb_claim_interface: called for interface %d\n", interface ); if (!device) USB_ERROR_STR ( -ENOENT, "usb_claim_interface: device is NULL" ); if (!(device->device)) USB_ERROR_STR ( -EINVAL, "usb_claim_interface: device->device is NULL" ); /* If we have already claimed an interface, release it */ if ( device->interface ) usb_release_interface(dev, dev->interface); result = claim_interface ( dev, interface ); if ( result ) USB_ERROR_STR ( result, "usb_claim_interface: couldn't claim interface" ); dev->interface = interface; /* interface is claimed and async IO is set up: return 0 */ return 0;}int usb_release_interface(usb_dev_handle *dev, int interface){ struct darwin_dev_handle *device; io_return_t result; if (!dev) USB_ERROR(-ENXIO); if ((device = dev->impl_info) == NULL) USB_ERROR(-ENOENT); /* interface is not open */ if (!device->interface) return 0; result = (*(device->interface))->USBInterfaceClose(device->interface); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "usb_release_interface(USBInterfaceClose): %s", darwin_error_str(result)); result = (*(device->interface))->Release(device->interface); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "usb_release_interface(Release): %s", darwin_error_str(result)); device->interface = NULL; free (device->endpoint_addrs); device->num_endpoints = 0; device->endpoint_addrs = NULL; dev->interface = -1; dev->altsetting = -1; return 0;}int usb_set_altinterface(usb_dev_handle *dev, int alternate){ struct darwin_dev_handle *device; io_return_t result; if (!dev) USB_ERROR(-ENXIO); if ((device = dev->impl_info) == NULL) USB_ERROR(-ENOENT); /* interface is not open */ if (!device->interface) USB_ERROR_STR(-EACCES, "usb_set_altinterface: interface used without being claimed"); result = (*(device->interface))->SetAlternateInterface(device->interface, alternate); if (result) USB_ERROR_STR(result, "usb_set_altinterface: could not set alternate interface"); dev->altsetting = alternate; result = get_endpoints (device); if (result) { /* this should not happen */ USB_ERROR_STR ( result, "usb_set_altinterface: could not build endpoint table"); } return 0;}/* simple function that figures out what pipeRef is associated with an endpoint */static int ep_to_pipeRef (struct darwin_dev_handle *device, int ep){ int i; if (usb_debug > 1) fprintf(stderr, "libusb/darwin.c ep_to_pipeRef: Converting ep address to pipeRef.\n"); for (i = 0 ; i < device->num_endpoints ; i++) if (device->endpoint_addrs[i] == ep) return i + 1; /* No pipe found with the correct endpoint address */ if (usb_debug > 1) fprintf(stderr, "libusb/darwin.c ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep); return -1;}/* argument to handle multiple parameters to rw_completed */struct rw_complete_arg { UInt32 io_size; IOReturn result; CFRunLoopRef cf_loop;};static void rw_completed(void *refcon, io_return_t result, void *io_size){ struct rw_complete_arg *rw_arg = (struct rw_complete_arg *)refcon; if (usb_debug > 2) fprintf(stderr, "io async operation completed: %s, size=%lu, result=0x%08x\n", darwin_error_str(result), (UInt32)io_size, result); rw_arg->io_size = (UInt32)io_size; rw_arg->result = result; CFRunLoopStop(rw_arg->cf_loop);}static int usb_bulk_transfer (usb_dev_handle *dev, int ep, char *bytes, int size, int timeout, rw_async_func_t rw_async, rw_async_to_func_t rw_async_to){ struct darwin_dev_handle *device; io_return_t result = -1; CFRunLoopSourceRef cfSource; int pipeRef; struct rw_complete_arg rw_arg; u_int8_t transferType; /* None of the values below are used in libusb for bulk transfers */ u_int8_t direction, number, interval; u_int16_t maxPacketSize; if (!dev) USB_ERROR_STR ( -ENXIO, "usb_bulk_transfer: Called with NULL device" ); if ((device = dev->impl_info) == NULL) USB_ERROR_STR ( -ENOENT, "usb_bulk_transfer: Device not open" ); /* interface is not open */ if (!device->interface) USB_ERROR_STR(-EACCES, "usb_bulk_transfer: Interface used before it was opened");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -