bool LJUSB_IsHandleValid(HANDLE hDevice) { uint8_t config = 0; int r = 1; if (LJUSB_isNullHandle(hDevice)) { #if LJ_DEBUG fprintf(stderr, "LJUSB_IsHandleValid: returning false. hDevice is NULL.\n"); #endif return false; } // If we can call get configuration without getting an error, // the handle is still valid. // Note that libusb_get_configuration() will return a cached value, // so we replace this call // r = libusb_get_configuration(hDevice, &config); // to the actual control tranfser, from the libusb source r = libusb_control_transfer(hDevice, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_CONFIGURATION, 0, 0, &config, 1, LJ_LIBUSB_TIMEOUT_DEFAULT); if (r < 0) { #if LJ_DEBUG fprintf(stderr, "LJUSB_IsHandleValid: returning false. Return value from libusb_get_configuration was: %d\n", r); #endif LJUSB_libusbError(r); return false; } else { #if LJ_DEBUG fprintf(stderr, "LJUSB_IsHandleValid: returning true.\n"); #endif return true; } }
void LJUSB_CloseDevice(HANDLE hDevice) { #if LJ_DEBUG fprintf(stderr, "LJUSB_CloseDevice\n"); #endif if (LJUSB_isNullHandle(hDevice)) { return; } //Release libusb_release_interface(hDevice, 0); //Close libusb_close(hDevice); #if LJ_DEBUG fprintf(stderr, "LJUSB_CloseDevice: closed\n"); #endif }
bool LJUSB_ResetConnection(HANDLE hDevice) { int r; if (LJUSB_isNullHandle(hDevice)) { #if LJ_DEBUG fprintf(stderr, "LJUSB_ResetConnection: returning false. hDevice is NULL.\n"); #endif return false; } r = libusb_reset_device(hDevice); if (r != 0) { LJUSB_libusbError(r); return false; } return true; //Success }
unsigned long LJUSB_GetHIDReportDescriptor(HANDLE hDevice, BYTE *pBuff, unsigned long count) { libusb_device *dev = NULL; struct libusb_device_descriptor desc; int r = 0; if (LJUSB_isNullHandle(hDevice)) { #if LJ_DEBUG fprintf(stderr, "LJUSB_GetHIDReportDescriptor: returning 0. hDevice is NULL.\n"); #endif return 0; } //Determine the device from handle. dev = libusb_get_device(hDevice); r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { LJUSB_libusbError(r); return 0; } if (desc.idProduct != U12_PRODUCT_ID) { //Only U12 supported errno = EINVAL; return 0; } r = libusb_control_transfer(hDevice, 0x81, 0x06, 0x2200, 0x0000, pBuff, count, LJ_LIBUSB_TIMEOUT_DEFAULT); if (r < 0) { LJUSB_libusbError(r); return 0; } #if LJ_DEBUG fprintf(stderr, "LJUSB_GetHIDReportDescriptor: returning control transferred = %d.\n", r); #endif return r; }
unsigned short LJUSB_GetDeviceDescriptorReleaseNumber(HANDLE hDevice) { libusb_device *dev = NULL; struct libusb_device_descriptor desc; int r = 0; if (LJUSB_isNullHandle(hDevice)) { #if LJ_DEBUG fprintf(stderr, "LJUSB_GetDeviceDescriptorReleaseNumber: returning 0. hDevice is NULL.\n"); #endif return 0; } dev = libusb_get_device(hDevice); r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { LJUSB_libusbError(r); return 0; } return desc.bcdDevice; }
bool LJUSB_IsHandleValid(HANDLE hDevice) { uint8_t config = 0; int r = 1; if (LJUSB_isNullHandle(hDevice)) { if (LJ_DEBUG) { fprintf(stderr, "LJUSB_IsHandleValid: returning 0. hDevice is NULL.\n"); } // TODO: Consider different errno here and in LJUSB_isNullHandle errno = EINVAL; return false; } // If we can call get configuration without getting an error, // the handle is still valid. // Note that libusb_get_configuration() will return a cached value, // so we replace this call // r = libusb_get_configuration(hDevice, &config); // to the actual control tranfser, from the libusb source r = libusb_control_transfer(hDevice, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_CONFIGURATION, 0, 0, &config, 1, 1000); if (r < 0) { if (LJ_DEBUG) { fprintf(stderr, "LJUSB_IsHandleValid: returning 0. Return value from libusb_get_configuration was: %d\n", r); } // TODO: Consider different errno here and in LJUSB_isNullHandle errno = EINVAL; return false; } else { if (LJ_DEBUG) { fprintf(stderr, "LJUSB_IsHandleValid: returning 1.\n"); } return true; } }
// Automatically uses the correct endpoint and transfer method (bulk or interrupt) static unsigned long LJUSB_SetupTransfer(HANDLE hDevice, BYTE *pBuff, unsigned long count, unsigned int timeout, enum LJUSB_TRANSFER_OPERATION operation) { libusb_device *dev = NULL; struct libusb_device_descriptor desc; bool isBulk = true; unsigned char endpoint = 0; int r = 0; #if LJ_DEBUG fprintf(stderr, "Calling LJUSB_SetupTransfer with count = %lu and operation = %d.\n", count, operation); #endif if (LJUSB_isNullHandle(hDevice)) { #if LJ_DEBUG fprintf(stderr, "LJUSB_SetupTransfer: returning 0. hDevice is NULL.\n"); #endif return 0; } //First determine the device from handle. dev = libusb_get_device(hDevice); r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { LJUSB_libusbError(r); return 0; } switch (desc.idProduct) { /* These devices use bulk transfers */ case UE9_PRODUCT_ID: isBulk = true; switch (operation) { case LJUSB_WRITE: endpoint = UE9_PIPE_EP1_OUT; break; case LJUSB_READ: endpoint = UE9_PIPE_EP1_IN; break; case LJUSB_STREAM: endpoint = UE9_PIPE_EP2_IN; break; default: errno = EINVAL; return 0; } break; case U3_PRODUCT_ID: isBulk = true; switch (operation) { case LJUSB_WRITE: endpoint = U3_PIPE_EP1_OUT; break; case LJUSB_READ: endpoint = U3_PIPE_EP2_IN; break; case LJUSB_STREAM: endpoint = U3_PIPE_EP3_IN; break; default: errno = EINVAL; return 0; } break; case U6_PRODUCT_ID: isBulk = true; switch (operation) { case LJUSB_WRITE: endpoint = U6_PIPE_EP1_OUT; break; case LJUSB_READ: endpoint = U6_PIPE_EP2_IN; break; case LJUSB_STREAM: endpoint = U6_PIPE_EP3_IN; break; default: errno = EINVAL; return 0; } break; case BRIDGE_PRODUCT_ID: isBulk = true; switch (operation) { case LJUSB_WRITE: endpoint = BRIDGE_PIPE_EP1_OUT; break; case LJUSB_READ: endpoint = BRIDGE_PIPE_EP2_IN; break; case LJUSB_STREAM: endpoint = BRIDGE_PIPE_EP3_IN; break; default: errno = EINVAL; return 0; } break; case T7_PRODUCT_ID: isBulk = true; switch (operation) { case LJUSB_WRITE: endpoint = T7_PIPE_EP1_OUT; break; case LJUSB_READ: endpoint = T7_PIPE_EP2_IN; break; case LJUSB_STREAM: endpoint = T7_PIPE_EP3_IN; break; default: errno = EINVAL; return 0; } break; case DIGIT_PRODUCT_ID: isBulk = true; switch (operation) { case LJUSB_WRITE: endpoint = DIGIT_PIPE_EP1_OUT; break; case LJUSB_READ: endpoint = DIGIT_PIPE_EP2_IN; break; case LJUSB_STREAM: default: //No streaming interface errno = EINVAL; return 0; } break; /* These devices use interrupt transfers */ case U12_PRODUCT_ID: isBulk = false; switch (operation) { case LJUSB_READ: endpoint = U12_PIPE_EP1_IN; break; case LJUSB_WRITE: endpoint = U12_PIPE_EP2_OUT; break; case LJUSB_STREAM: endpoint = U12_PIPE_EP0; break; default: errno = EINVAL; return 0; } break; default: // Error, not a labjack device errno = EINVAL; return 0; } return LJUSB_DoTransfer(hDevice, endpoint, pBuff, count, timeout, isBulk); }
static unsigned long LJUSB_DoTransfer(HANDLE hDevice, unsigned char endpoint, BYTE *pBuff, unsigned long count, unsigned int timeout, bool isBulk) { int r = 0; int transferred = 0; #if LJ_DEBUG fprintf(stderr, "Calling LJUSB_DoTransfer with endpoint = 0x%x, count = %lu, and isBulk = %d.\n", endpoint, count, isBulk); #endif if (LJUSB_isNullHandle(hDevice)) { #if LJ_DEBUG fprintf(stderr, "LJUSB_DoTransfer: returning 0. hDevice is NULL.\n"); #endif return 0; } if (isBulk && endpoint != 1 && endpoint < 0x81 ) { fprintf(stderr, "LJUSB_DoTransfer warning: Got endpoint = %d, however this not a known endpoint. Please verify you are using the header file provided in /usr/local/include/labjackusb.h and not an older header file.\n", endpoint); } if (isBulk) { r = libusb_bulk_transfer(hDevice, endpoint, pBuff, (int)count, &transferred, timeout); } else { if (endpoint == 0) { //HID feature request. r = libusb_control_transfer(hDevice, 0xa1 , 0x01, 0x0300, 0x0000, pBuff, count, timeout); if (r < 0) { LJUSB_libusbError(r); return 0; } #if LJ_DEBUG fprintf(stderr, "LJUSB_DoTransfer: returning control transferred = %d.\n", r); #endif return r; } else { r = libusb_interrupt_transfer(hDevice, endpoint, pBuff, count, &transferred, timeout); } } if (r == LIBUSB_ERROR_TIMEOUT) { //Timeout occured but may have received partial data. Setting errno but //returning the number of bytes transferred which may be > 0. #if LJ_DEBUG fprintf(stderr, "LJUSB_DoTransfer: Transfer timed out. Returning.\n"); #endif errno = ETIMEDOUT; return transferred; } else if (r != 0) { LJUSB_libusbError(r); return 0; } #if LJ_DEBUG fprintf(stderr, "LJUSB_DoTransfer: returning transferred = %d.\n", transferred); #endif return transferred; }