Example #1
0
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;
    }
}
Example #2
0
unsigned int LJUSB_GetDevCount(unsigned long ProductID)
{
    libusb_device **devs = NULL;
    ssize_t cnt = 0;
    int r = 1;
    unsigned int i = 0;
    unsigned int ljFoundCount = 0;

    if (!gIsLibUSBInitialized) {
        r = libusb_init(&gLJContext);
        if (r < 0) {
            fprintf(stderr, "failed to initialize libusb\n");
            LJUSB_libusbError(r);
            return 0;
        }
        gIsLibUSBInitialized = true;
    }

    cnt = libusb_get_device_list(gLJContext, &devs);
    if (cnt < 0) {
        fprintf(stderr, "failed to get device list\n");
        LJUSB_libusbError(cnt);
        LJUSB_libusb_exit();
        return 0;
    }

    libusb_device *dev = NULL;

    // Loop over all USB devices and count the ones with the LabJack
    // vendor ID and the passed in product ID.
    while ((dev = devs[i++]) != NULL) {
        struct libusb_device_descriptor desc;
        r = libusb_get_device_descriptor(dev, &desc);
        if (r < 0) {
            fprintf(stderr, "failed to get device descriptor\n");
            LJUSB_libusbError(r);
            LJUSB_libusb_exit();
            return 0;
        }
        if (LJ_VENDOR_ID == desc.idVendor && ProductID == desc.idProduct) {
            ljFoundCount++;
        }
    }
    libusb_free_device_list(devs, 1);

    return ljFoundCount;
}
Example #3
0
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;
}
Example #4
0
unsigned long LJUSB_GetHIDReportDescriptor(HANDLE hDevice, BYTE *pBuff, unsigned long count)
{
    libusb_device *dev;
    struct libusb_device_descriptor desc;
    int r = 0;

    if (LJUSB_IsHandleValid(hDevice) == false) {
        if (LJ_DEBUG) {
            fprintf(stderr, "Calling LJUSB_GetHIDReportDescriptor returning 0 because handle is invalid. errno = %d.\n", errno);
        }
        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);
    }

    return r;
}
Example #5
0
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
}
Example #6
0
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;
}
Example #7
0
unsigned short LJUSB_GetDeviceDescriptorReleaseNumber(HANDLE hDevice)
{
    libusb_device *dev;
    struct libusb_device_descriptor desc;
    int r = 0;

    if (LJUSB_IsHandleValid(hDevice) == false) {
        if (LJ_DEBUG) {
            fprintf(stderr, "Calling LJUSB_GetDeviceDescriptorReleaseNumber returning 0 because handle is invalid. errno = %d.\n", errno);
        }
        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;
}
Example #8
0
// 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);
}
Example #9
0
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;
}
Example #10
0
int LJUSB_OpenAllDevices(HANDLE* devHandles, UINT* productIds, UINT maxDevices)
{
    libusb_device **devs = NULL, *dev = NULL;
    struct libusb_device_handle *devh = NULL;
    struct libusb_device_descriptor desc;
    ssize_t cnt = 0;
    int r = 1;
    unsigned int i = 0, ljFoundCount = 0;
    HANDLE handle = NULL;

    if (!gIsLibUSBInitialized) {
        r = libusb_init(&gLJContext);
        if (r < 0) {
            fprintf(stderr, "failed to initialize libusb\n");
            LJUSB_libusbError(r);
            return -1;
        }
        gIsLibUSBInitialized = true;
    }

    cnt = libusb_get_device_list(gLJContext, &devs);
    if (cnt < 0) {
        fprintf(stderr, "failed to get device list\n");
        LJUSB_libusbError(cnt);
        LJUSB_libusb_exit();
        return -1;
    }

    while ((dev = devs[i++]) != NULL) {
#if LJ_DEBUG
        fprintf(stderr, "LJUSB_OpenDevice: calling libusb_get_device_descriptor\n");
#endif
        r = libusb_get_device_descriptor(dev, &desc);
        if (r < 0) {
            fprintf(stderr, "failed to get device descriptor");
            LJUSB_libusbError(r);
            LJUSB_libusb_exit();
            return -1;
        }

        if (LJ_VENDOR_ID == desc.idVendor) {
            // Found a LabJack device
            r = libusb_open(dev, &devh);
            if (r < 0) {
                LJUSB_libusbError(r);
                continue;
            }

            // Test if the kernel driver has the device.
            // Should only be true for HIDs.
            if (libusb_kernel_driver_active(devh, 0) ) {
#if LJ_DEBUG
                fprintf(stderr, "Kernel Driver was active, detaching...\n");
#endif

                // Detaches U12s from kernel driver.
                r = libusb_detach_kernel_driver(devh, 0);

                // Check the return value
                if ( r != 0 ) {
                    fprintf(stderr, "failed to detach from kernel driver. Error Number: %i", r);
                    libusb_close(devh);
                    continue;
                }
            }

            r = libusb_claim_interface(devh, 0);
            if (r < 0) {
                //LJUSB_libusbError(r);
                libusb_close(devh);
                continue;
            }

            handle = (HANDLE) devh;

            if (handle == NULL) {
                // Not a valid handle
                continue;
            }
            else if (ljFoundCount < maxDevices) {
                if (LJUSB_isMinFirmware(handle, desc.idProduct)) {
                    devHandles[ljFoundCount] = handle;
                    productIds[ljFoundCount] = desc.idProduct;
                    ljFoundCount++;
                } else {
                    // Not high enough firmware, keep moving.
                    libusb_close(devh);
                    ljFoundCount--;
                }
            } else {
                // Too many devices have been found.
                libusb_close(devh);
                break;
            }
        }
    }
    libusb_free_device_list(devs, 1);

    return ljFoundCount;
}
Example #11
0
HANDLE LJUSB_OpenDevice(UINT DevNum, unsigned int dwReserved, unsigned long ProductID)
{
    (void)dwReserved;
    libusb_device **devs = NULL, *dev = NULL;
    struct libusb_device_handle *devh = NULL;
    struct libusb_device_descriptor desc;
    ssize_t cnt = 0;
    int r = 1;
    unsigned int i = 0;
    unsigned int ljFoundCount = 0;
    HANDLE handle = NULL;

    if (!gIsLibUSBInitialized) {
        r = libusb_init(&gLJContext);
        if (r < 0) {
            fprintf(stderr, "failed to initialize libusb\n");
            LJUSB_libusbError(r);
            return NULL;
        }
        gIsLibUSBInitialized = true;
    }

    cnt = libusb_get_device_list(gLJContext, &devs);
    if (cnt < 0) {
        fprintf(stderr, "failed to get device list\n");
        LJUSB_libusbError(cnt);
        LJUSB_libusb_exit();
        return NULL;
    }

    while ((dev = devs[i++]) != NULL) {
#if LJ_DEBUG
        fprintf(stderr, "LJUSB_OpenDevice: calling libusb_get_device_descriptor\n");
#endif
        r = libusb_get_device_descriptor(dev, &desc);
        if (r < 0) {
            fprintf(stderr, "failed to get device descriptor");
            LJUSB_libusbError(r);
            LJUSB_libusb_exit();
            return NULL;
        }

        if (LJ_VENDOR_ID == desc.idVendor && ProductID == desc.idProduct) {
            ljFoundCount++;
            if (ljFoundCount == DevNum) {
                // Found the one requested
                r = libusb_open(dev, &devh);
                if (r < 0) {
                    LJUSB_libusbError(r);
                    return NULL;
                }

                // Test if the kernel driver has the device.
                // Should only be true for HIDs.
                if (libusb_kernel_driver_active(devh, 0)) {
#if LJ_DEBUG
                    fprintf(stderr, "Kernel Driver was active, detaching...\n");
#endif

                    // Detaches U12s from kernel driver.
                    r = libusb_detach_kernel_driver(devh, 0);

                    // Check the return value
                    if ( r != 0 ) {
                        fprintf(stderr, "failed to detach from kernel driver. Error Number: %i", r);
                        return NULL;
                    }
                }

                r = libusb_claim_interface(devh, 0);
                if (r < 0) {
                    LJUSB_libusbError(r);
                    libusb_close(devh);
                    return NULL;
                }
                handle = (HANDLE) devh;
#if LJ_DEBUG
                fprintf(stderr, "LJUSB_OpenDevice: Found handle for product ID %ld\n", ProductID);
#endif
                break;
            }
        }
    }
    libusb_free_device_list(devs, 1);

    if (handle != NULL) {
        //We found a device, now check if it meets the minimum firmware requirement
        if (!LJUSB_isMinFirmware(handle, ProductID)) {
            //Does not meet the requirement.  Close device and return an invalid handle.
            LJUSB_CloseDevice(handle);
            return NULL;
        }
    }
#if LJ_DEBUG
    fprintf(stderr, "LJUSB_OpenDevice: Returning handle\n");
#endif
    return handle;
}
Example #12
0
unsigned int LJUSB_GetDevCounts(UINT *productCounts, UINT * productIds, UINT n)
{
    libusb_device **devs = NULL, *dev = NULL;
    ssize_t cnt = 0;
    int r = 1;
    unsigned int i = 0;
    unsigned int u3ProductCount = 0, u6ProductCount = 0;
    unsigned int ue9ProductCount = 0, u12ProductCount = 0;
    unsigned int bridgeProductCount = 0, t7ProductCount = 0;
    unsigned int digitProductCount = 0, allProductCount = 0;

    if (!gIsLibUSBInitialized) {
        r = libusb_init(&gLJContext);
        if (r < 0) {
            fprintf(stderr, "failed to initialize libusb\n");
            LJUSB_libusbError(r);
            return 0;
        }
        gIsLibUSBInitialized = true;
    }

    cnt = libusb_get_device_list(gLJContext, &devs);
    if (cnt < 0) {
        fprintf(stderr, "failed to get device list\n");
        LJUSB_libusbError(cnt);
        LJUSB_libusb_exit();
        return 0;
    }

    // Loop over all USB devices and count the ones with the LabJack
    // vendor ID and the passed in product ID.
    while ((dev = devs[i++]) != NULL) {
        struct libusb_device_descriptor desc;
        r = libusb_get_device_descriptor(dev, &desc);
        if (r < 0) {
            fprintf(stderr, "failed to get device descriptor\n");
            LJUSB_libusbError(r);
            LJUSB_libusb_exit();
            return 0;
        }
        if (LJ_VENDOR_ID == desc.idVendor) {
            switch (desc.idProduct) {
            case U3_PRODUCT_ID:
                u3ProductCount++;
                break;
            case U6_PRODUCT_ID:
                u6ProductCount++;
                break;
            case UE9_PRODUCT_ID:
                ue9ProductCount++;
                break;
            case U12_PRODUCT_ID:
                u12ProductCount++;
                break;
            case BRIDGE_PRODUCT_ID:
                bridgeProductCount++;
                break;
            case T7_PRODUCT_ID:
                t7ProductCount++;
                break;
            case DIGIT_PRODUCT_ID:
                digitProductCount++;
                break;
            }
        }
    }
    libusb_free_device_list(devs, 1);

    for (i = 0; i < n; i++) {
        switch (i) {
        case 0:
            productCounts[i] = u3ProductCount;
            productIds[i] = U3_PRODUCT_ID;
            allProductCount += u3ProductCount;
            break;
        case 1:
            productCounts[i] = u6ProductCount;
            productIds[i] = U6_PRODUCT_ID;
            allProductCount += u6ProductCount;
            break;
        case 2:
            productCounts[i] = ue9ProductCount;
            productIds[i] = UE9_PRODUCT_ID;
            allProductCount += ue9ProductCount;
            break;
        case 3:
            productCounts[i] = u12ProductCount;
            productIds[i] = U12_PRODUCT_ID;
            allProductCount += u12ProductCount;
            break;
        case 4:
            productCounts[i] = bridgeProductCount;
            productIds[i] = BRIDGE_PRODUCT_ID;
            allProductCount += bridgeProductCount;
            break;
        case 5:
            productCounts[i] = t7ProductCount;
            productIds[i] = T7_PRODUCT_ID;
            allProductCount += t7ProductCount;
            break;
        case 6:
            productCounts[i] = digitProductCount;
            productIds[i] = DIGIT_PRODUCT_ID;
            allProductCount += digitProductCount;
            break;
        }
    }

    return allProductCount;
}