📄 darwin.c
字号:
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)); } } 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%x\n", current_interface, (void *)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 0x%x\n", current_interface, (void *)(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)); return 0;}int usb_set_configuration(usb_dev_handle *dev, int configuration){ struct darwin_dev_handle *device; io_return_t result; 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. */ 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: assume zero */ if (dev->interface != -1) result = claim_interface(dev, 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; 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; 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){ u_int8_t numep, direction, number; u_int8_t dont_care1, dont_care3; u_int16_t dont_care2; int i, ret; if (usb_debug > 1) fprintf(stderr, "Converting ep address to pipeRef.\n"); /* retrieve the total number of endpoints on this interface */ ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep); if ( ret ) { if ( usb_debug > 1 ) fprintf ( stderr, "ep_to_pipeRef: interface is %x\n", device->interface ); USB_ERROR_STR ( -ret, "ep_to_pipeRef: can't get number of endpoints for interface" ); } /* iterate through the pipeRefs until we find the correct one */ 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, "ep_to_pipeRef: an error occurred getting pipe information on pipe %d\n", i ); USB_ERROR_STR(-darwin_to_errno(ret), "ep_to_pipeRef(GetPipeProperties): %s", darwin_error_str(ret)); } if (usb_debug > 1) fprintf (stderr, "ep_to_pipeRef: Pipe %i: DIR: %i number: %i\n", i, direction, number); /* calculate the endpoint of the pipe and check it versus the requested endpoint */ if ( ((direction << 7 & USB_ENDPOINT_DIR_MASK) | (number & USB_ENDPOINT_ADDRESS_MASK)) == ep ) { if (usb_debug > 1) fprintf(stderr, "ep_to_pipeRef: pipeRef for ep address 0x%02x found: 0x%02x\n", ep, i); return i; } } if (usb_debug > 1) fprintf(stderr, "ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep); /* none of the found pipes match the requested endpoint */ return -1;}static void write_completed(void *dummy, io_return_t result, void *arg0){ if (usb_debug > 2) fprintf(stderr, "write completed\n"); CFRunLoopStop(CFRunLoopGetCurrent());}int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout){ struct darwin_dev_handle *device; CFRunLoopSourceRef cfSource; io_return_t result = -1; int pipeRef; UInt8 direction, number, transferType, interval; UInt16 maxPacketSize; 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_bulk_write: interface used without being claimed"); if ((pipeRef = ep_to_pipeRef(device, ep)) < 0) USB_ERROR(-EINVAL); if (usb_debug > 3) fprintf(stderr, "usb_bulk_write: endpoint=0x%02x size=%i TO=%i\n", ep, size, timeout); (*(device->interface))->GetPipeProperties ( device->interface, pipeRef, &direction, &number, &transferType, &maxPacketSize, &interval ); (*(device->interface))->CreateInterfaceAsyncEventSource(device->interface, &cfSource); CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode); /* there seems to be no way to determine how many bytes are actually written */#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE) if ( transferType == kUSBInterrupt ) result = (*(device->interface))->WritePipeAsyncTO(device->interface, pipeRef, bytes, size, 0, timeout, write_completed, NULL); else#endif result = (*(device->interface))->WritePipeAsync(device->interface, pipeRef, bytes, size, write_completed, NULL); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "usb_bulk_write(WritePipeAsyncTO): %s", darwin_error_str(result)); else /* wait for write to complete */ CFRunLoopRun(); CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode); return size;}int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout){ struct darwin_dev_handle *device; int pipeRef; u_int32_t ret_size = size; u_int32_t retrieved = 0; io_return_t result = -1; UInt8 direction, number, transferType, interval; UInt16 maxPacketSize; if (usb_debug) fprintf (stderr, "usb_bulk_read: ep addr = 0x%02x\n", ep); ep |= 0x80; /* USB_DIR_OUT */ if (!dev) USB_ERROR_STR ( -ENXIO, "usb_bulk_read: called with null device" ); if ((device = dev->impl_info) == NULL) USB_ERROR_STR ( -ENOENT, "usb_bulk_read: device not initialized" ); /* interface is not open */ if (!device->interface) USB_ERROR_STR(-EACCES, "usb_bulk_read: interface used without being claimed"); if ((pipeRef = ep_to_pipeRef(device, ep)) == -1) USB_ERROR_STR ( -EINVAL, "usb_bulk_read: invalid pipe reference" ); if (usb_debug > 3) fprintf(stderr, "usb_bulk_read: endpoint=0x%02x size=%i timeout=%fsec\n" , ep, size, (double)timeout/1000 ); (*(device->interface))->GetPipeProperties ( device->interface, pipeRef, &direction, &number, &transferType, &maxPacketSize, &interval );#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE) if ( transferType == kUSBInterrupt ) {#endif /* This is an interrupt pipe. We can't specify a timeout. */ if (usb_debug > 3) fprintf(stderr, "usb_bulk_read: interrupt pipe\n" ); result = (*(device->interface))->ReadPipe(device->interface, pipeRef, bytes, (UInt32 *)&ret_size); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "usb_bulk_read(ReadPipe): error reading from bulk endpoint %02x: %s", ep, darwin_error_str(result)); retrieved = ret_size;#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE) } else { result = (*(device->interface))->ReadPipeTO(device->interface, pipeRef,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -