ssize_t usbReadEndpoint ( UsbDevice *device, unsigned char endpointNumber, void *buffer, size_t length, int timeout ) { UsbEndpoint *endpoint; if ((endpoint = usbGetInputEndpoint(device, endpointNumber))) { UsbEndpointExtension *eptx = endpoint->extension; ssize_t count; doRead: if ((count = read(eptx->data, buffer, length)) == -1) { if (errno == EINTR) goto doRead; logSystemError("USB endpoint read"); } else if (!usbApplyInputFilters(endpoint, buffer, length, &count)) { errno = EIO; } else if (!count) { errno = EAGAIN; } else { return count; } } return -1; }
ssize_t usbReadEndpoint ( UsbDevice *device, unsigned char endpointNumber, void *buffer, size_t length, int timeout ) { UsbDeviceExtension *devx = device->extension; const UsbEndpoint *endpoint; if ((endpoint = usbGetInputEndpoint(device, endpointNumber))) { const UsbEndpointDescriptor *descriptor = endpoint->descriptor; UsbEndpointTransfer transfer = USB_ENDPOINT_TRANSFER(descriptor); ssize_t result = -1; switch (transfer) { case UsbEndpointTransfer_Bulk: result = usb_bulk_read(devx->handle, descriptor->bEndpointAddress, buffer, length, timeout); break; case UsbEndpointTransfer_Interrupt: result = usb_interrupt_read(devx->handle, descriptor->bEndpointAddress, buffer, length, timeout); break; default: logMessage(LOG_ERR, "USB endpoint input transfer not supported: 0X%02X", transfer); result = -ENOSYS; break; } if (result >= 0) { if (!usbApplyInputFilters(device, buffer, length, &result)) { result = -EIO; } } if (result >= 0) return result; errno = -result; } #if defined(__MINGW32__) && !defined(ETIMEDOUT) # define ETIMEDOUT 116 #endif /* __MINGW32__ && !ETIMEDOUT */ #ifdef ETIMEDOUT if (errno == ETIMEDOUT) errno = EAGAIN; #endif /* ETIMEDOUT */ if (errno != EAGAIN) logSystemError("USB endpoint read"); return -1; }
ssize_t usbReadEndpoint ( UsbDevice *device, unsigned char endpointNumber, void *buffer, size_t length, int timeout ) { UsbDeviceExtension *devx = device->extension; if (usbGetHandle(devx)) { const UsbEndpoint *endpoint; if ((endpoint = usbGetInputEndpoint(device, endpointNumber))) { const UsbEndpointDescriptor *descriptor = endpoint->descriptor; UsbEndpointTransfer transfer = USB_ENDPOINT_TRANSFER(descriptor); int actual_length; int result; switch (transfer) { case UsbEndpointTransfer_Bulk: result = libusb_bulk_transfer(devx->handle, descriptor->bEndpointAddress, buffer, length, &actual_length, timeout); break; case UsbEndpointTransfer_Interrupt: result = libusb_interrupt_transfer(devx->handle, descriptor->bEndpointAddress, buffer, length, &actual_length, timeout); break; default: logMessage(LOG_ERR, "USB endpoint input transfer not supported: 0X%02X", transfer); result = LIBUSB_ERROR_NOT_SUPPORTED; break; } if (result == LIBUSB_SUCCESS) { ssize_t count = result; if (usbApplyInputFilters(device, buffer, length, &count)) return count; result = LIBUSB_ERROR_IO; } usbSetErrno(result, NULL); } } if (errno != EAGAIN) logSystemError("USB endpoint read"); return -1; }
ssize_t usbReadEndpoint ( UsbDevice *device, unsigned char endpointNumber, void *buffer, size_t length, int timeout ) { ssize_t count = -1; UsbEndpoint *endpoint; if ((endpoint = usbGetInputEndpoint(device, endpointNumber))) { UsbEndpointTransfer transfer = USB_ENDPOINT_TRANSFER(endpoint->descriptor); switch (transfer) { case UsbEndpointTransfer_Bulk: count = usbBulkTransfer(endpoint, buffer, length, timeout); break; case UsbEndpointTransfer_Interrupt: { struct usbdevfs_urb *urb = usbInterruptTransfer(endpoint, NULL, length, timeout); if (urb) { count = urb->actual_length; if (count > length) count = length; memcpy(buffer, urb->buffer, count); free(urb); } break; } default: logMessage(LOG_ERR, "USB input transfer not supported: %d", transfer); errno = ENOSYS; break; } if (count != -1) { if (!usbApplyInputFilters(device, buffer, length, &count)) { errno = EIO; count = -1; } } } return count; }
void * usbReapResponse ( UsbDevice *device, unsigned char endpointAddress, UsbResponse *response, int wait ) { UsbEndpoint *endpoint; if ((endpoint = usbGetEndpoint(device, endpointAddress))) { UsbEndpointExtension *eptx = endpoint->extension; struct usbdevfs_urb *urb; while (!(urb = dequeueItem(eptx->completedRequests))) { if (!usbReapUrb(device, wait)) return NULL; } response->context = urb->usercontext; response->buffer = urb->buffer; response->size = urb->buffer_length; if ((response->error = urb->status)) { if (response->error < 0) response->error = -response->error; errno = response->error; logSystemError("USB URB status"); response->count = -1; } else { response->count = urb->actual_length; switch (USB_ENDPOINT_DIRECTION(endpoint->descriptor)) { case UsbEndpointDirection_Input: if (!usbApplyInputFilters(device, response->buffer, response->size, &response->count)) { response->error = EIO; response->count = -1; } break; } } return urb; } return NULL; }
void * usbReapResponse ( UsbDevice *device, unsigned char endpointAddress, UsbResponse *response, int wait ) { UsbEndpoint *endpoint; if ((endpoint = usbGetEndpoint(device, endpointAddress))) { UsbEndpointExtension *eptx = endpoint->extension; struct timeval timeout; UsbAsynchronousRequest *request; timeout.tv_sec = 0; timeout.tv_usec = 0; while (!(request = dequeueItem(eptx->requests))) { aio_result_t *result; doWait: if ((int)(result = aiowait(wait? NULL: &timeout)) == -1) { if (errno == EINTR) goto doWait; if (errno != EINVAL) { logSystemError("USB asynchronous wait"); return NULL; } result = NULL; } if (!result) { errno = EAGAIN; return NULL; } request = (UsbAsynchronousRequest *)result; { UsbEndpoint *ep = request->endpoint; UsbEndpointExtension *epx = ep->extension; if (!enqueueItem(epx->requests, request)) { logSystemError("USB asynchronous enqueue"); } } } response->context = request->context; response->buffer = request->buffer; response->size = request->length; response->count = request->result.aio_return; response->error = request->result.aio_errno; if (response->count == -1) { errno = response->error; logSystemError("USB asynchronous completion"); } else { switch (USB_ENDPOINT_DIRECTION(endpoint->descriptor)) { case UsbEndpointDirection_Input: if (!usbApplyInputFilters(endpoint, response->buffer, response->size, &response->count)) { response->error = EIO; response->count = -1; } break; } } return request; } return NULL; }