📄 darwin.c
字号:
/* Set up transfer */ if ((pipeRef = ep_to_pipeRef(device, ep)) < 0) USB_ERROR_STR ( -EINVAL, "usb_bulk_transfer: Invalid pipe reference" ); (*(device->interface))->GetPipeProperties (device->interface, pipeRef, &direction, &number, &transferType, &maxPacketSize, &interval); (*(device->interface))->CreateInterfaceAsyncEventSource(device->interface, &cfSource); CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode); bzero((void *)&rw_arg, sizeof(struct rw_complete_arg)); rw_arg.cf_loop = CFRunLoopGetCurrent(); /* Transfer set up complete */ if (usb_debug > 0) fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: Transfering %i bytes of data on endpoint 0x%02x\n", size, ep); /* Bulk transfer */ if (transferType == kUSBInterrupt && usb_debug > 3) fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: USB pipe is an interrupt pipe. Timeouts will not be used.\n"); if ( transferType != kUSBInterrupt && rw_async_to != NULL) result = rw_async_to (device->interface, pipeRef, bytes, size, timeout, timeout, (IOAsyncCallback1)rw_completed, (void *)&rw_arg); else result = rw_async (device->interface, pipeRef, bytes, size, (IOAsyncCallback1)rw_completed, (void *)&rw_arg); if (result == kIOReturnSuccess) { /* wait for write to complete */ if (CFRunLoopRunInMode(kCFRunLoopDefaultMode, (timeout+999)/1000, true) == kCFRunLoopRunTimedOut) { (*(device->interface))->AbortPipe(device->interface, pipeRef); CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true); /* Pick up aborted callback */ if (usb_debug) fprintf(stderr, "usb_bulk_read: input timed out\n"); } } CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode); /* Check the return code of both the write and completion functions. */ if (result != kIOReturnSuccess || (rw_arg.result != kIOReturnSuccess && rw_arg.result != kIOReturnAborted) ) { int error_code; char *error_str; if (result == kIOReturnSuccess) { error_code = darwin_to_errno (rw_arg.result); error_str = darwin_error_str (rw_arg.result); } else { error_code = darwin_to_errno(result); error_str = darwin_error_str (result); } if (transferType != kUSBInterrupt && rw_async_to != NULL) USB_ERROR_STR(-error_code, "usb_bulk_transfer (w/ Timeout): %s", error_str); else USB_ERROR_STR(-error_code, "usb_bulk_transfer (No Timeout): %s", error_str); } return rw_arg.io_size;}int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout){ int result; rw_async_to_func_t to_func = NULL; struct darwin_dev_handle *device; if (dev == NULL || dev->impl_info == NULL) return -EINVAL; device = dev->impl_info;#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE) to_func = (*(device->interface))->WritePipeAsyncTO;#endif if ((result = usb_bulk_transfer (dev, ep, bytes, size, timeout, (*(device->interface))->WritePipeAsync, to_func)) < 0) USB_ERROR_STR (result, "usb_bulk_write: An error occured during write (see messages above)"); return result;}int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout){ int result; rw_async_to_func_t to_func = NULL; struct darwin_dev_handle *device; if (dev == NULL || dev->impl_info == NULL) return -EINVAL; ep |= 0x80; device = dev->impl_info;#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE) to_func = (*(device->interface))->ReadPipeAsyncTO;#endif if ((result = usb_bulk_transfer (dev, ep, bytes, size, timeout, (*(device->interface))->ReadPipeAsync, to_func)) < 0) USB_ERROR_STR (result, "usb_bulk_read: An error occured during read (see messages above)"); return result;}/* interrupt endpoints seem to be treated just like any other endpoint under OSX/Darwin */int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout){ return usb_bulk_write (dev, ep, bytes, size, timeout);}int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout){ return usb_bulk_read (dev, ep, bytes, size, timeout);}int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout){ struct darwin_dev_handle *device = dev->impl_info; io_return_t result;#if !defined (LIBUSB_NO_TIMEOUT_DEVICE) IOUSBDevRequestTO urequest;#else IOUSBDevRequest urequest;#endif if (usb_debug >= 3) fprintf(stderr, "usb_control_msg: %d %d %d %d %p %d %d\n", requesttype, request, value, index, bytes, size, timeout); bzero(&urequest, sizeof(urequest)); urequest.bmRequestType = requesttype; urequest.bRequest = request; urequest.wValue = value; urequest.wIndex = index; urequest.wLength = size; urequest.pData = bytes;#if !defined (LIBUSB_NO_TIMEOUT_DEVICE) urequest.completionTimeout = timeout; urequest.noDataTimeout = timeout; result = (*(device->device))->DeviceRequestTO(device->device, &urequest);#else result = (*(device->device))->DeviceRequest(device->device, &urequest);#endif if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "usb_control_msg(DeviceRequestTO): %s", darwin_error_str(result)); /* Bytes transfered is stored in the wLenDone field*/ return urequest.wLenDone;}int usb_os_find_busses(struct usb_bus **busses){ struct usb_bus *fbus = NULL; io_iterator_t deviceIterator; io_return_t result; usb_device_t **device; UInt32 location; char buf[20]; int i = 1; /* Create a master port for communication with IOKit (this should have been created if the user called usb_init() )*/ if (masterPort == MACH_PORT_NULL) { usb_init (); if (masterPort == MACH_PORT_NULL) USB_ERROR(-ENOENT); } if ((result = usb_setup_iterator (&deviceIterator)) < 0) return result; while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) { struct usb_bus *bus; if (location & 0x00ffffff) continue; bus = calloc(1, sizeof(struct usb_bus)); if (bus == NULL) USB_ERROR(-ENOMEM); sprintf(buf, "%03i", i++); bus->location = location; strncpy(bus->dirname, buf, sizeof(bus->dirname) - 1); bus->dirname[sizeof(bus->dirname) - 1] = 0; LIST_ADD(fbus, bus); if (usb_debug >= 2) fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname); (*(device))->Release(device); } IOObjectRelease(deviceIterator); *busses = fbus; return 0;}int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices){ struct usb_device *fdev = NULL; io_iterator_t deviceIterator; io_return_t result; usb_device_t **device; u_int16_t address; UInt32 location; UInt32 bus_loc = bus->location; /* for use in retrieving device description */ IOUSBDevRequest req; /* a master port should have been created by usb_os_init */ if (masterPort == MACH_PORT_NULL) USB_ERROR(-ENOENT); if ((result = usb_setup_iterator (&deviceIterator)) < 0) return result; /* Set up request for device descriptor */ req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); req.bRequest = kUSBRqGetDescriptor; req.wValue = kUSBDeviceDesc << 8; req.wIndex = 0; req.wLength = sizeof(IOUSBDeviceDescriptor); while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) { unsigned char device_desc[DEVICE_DESC_LENGTH]; result = (*(device))->GetDeviceAddress(device, (USBDeviceAddress *)&address); if (usb_debug >= 2) fprintf(stderr, "usb_os_find_devices: Found USB device at location 0x%08lx\n", location); /* first byte of location appears to be associated with the device's bus */ if (location >> 24 == bus_loc >> 24) { struct usb_device *dev; dev = calloc(1, sizeof(struct usb_device)); if (dev == NULL) USB_ERROR(-ENOMEM); dev->bus = bus; req.pData = device_desc; result = (*(device))->DeviceRequest(device, &req); usb_parse_descriptor(device_desc, "bbwbbbbwwwbbbb", &dev->descriptor); sprintf(dev->filename, "%03i-%04x-%04x-%02x-%02x", address, dev->descriptor.idVendor, dev->descriptor.idProduct, dev->descriptor.bDeviceClass, dev->descriptor.bDeviceSubClass); dev->dev = (USBDeviceAddress *)malloc(4); memcpy(dev->dev, &location, 4); LIST_ADD(fdev, dev); if (usb_debug >= 2) fprintf(stderr, "usb_os_find_devices: Found %s on %s at location 0x%08lx\n", dev->filename, bus->dirname, location); } /* release the device now */ (*(device))->Release(device); } IOObjectRelease(deviceIterator); *devices = fdev; return 0;}int usb_os_determine_children(struct usb_bus *bus){ /* Nothing yet */ return 0;}void usb_os_init(void){ if (masterPort == MACH_PORT_NULL) { IOMasterPort(masterPort, &masterPort); gNotifyPort = IONotificationPortCreate(masterPort); }}void usb_os_cleanup (void){ if (masterPort != MACH_PORT_NULL) darwin_cleanup ();}int usb_resetep(usb_dev_handle *dev, unsigned int ep){ struct darwin_dev_handle *device; io_return_t result = -1; int pipeRef; 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_resetep: interface used without being claimed"); if ((pipeRef = ep_to_pipeRef(device, ep)) == -1) USB_ERROR(-EINVAL); result = (*(device->interface))->ResetPipe(device->interface, pipeRef); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "usb_resetep(ResetPipe): %s", darwin_error_str(result)); return 0;}int usb_clear_halt(usb_dev_handle *dev, unsigned int ep){ struct darwin_dev_handle *device; io_return_t result = -1; int pipeRef; 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_clear_halt: interface used without being claimed"); if ((pipeRef = ep_to_pipeRef(device, ep)) == -1) USB_ERROR(-EINVAL); result = (*(device->interface))->ClearPipeStall(device->interface, pipeRef); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "usb_clear_halt(ClearPipeStall): %s", darwin_error_str(result)); return 0;}int usb_reset(usb_dev_handle *dev){ struct darwin_dev_handle *device; io_return_t result; if (!dev) USB_ERROR(-ENXIO); if ((device = dev->impl_info) == NULL) USB_ERROR(-ENOENT); if (!device->device) USB_ERROR_STR(-ENOENT, "usb_reset: no such device"); result = (*(device->device))->ResetDevice(device->device); if (result != kIOReturnSuccess) USB_ERROR_STR(-darwin_to_errno(result), "usb_reset(ResetDevice): %s", darwin_error_str(result)); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -