0

I wrote the below code to access USB barcode scanners on a raspbian system and read scanned data from them using libusb. For the longest time I've had the problem that the call to libusb_bulk_transfer would not return; although the scanner was used, the call didn't return with data. If given a timeout argument, it did time out.

My company uses three different models of barcode scanners. Once I tried using a different model for testing, the program started working as expected, i.e. there was some output to stdout giving me the expected data.

Further testing revealed that it works with two of the three types of scanner we have. Whenever I use a scanner of the third kind, the program gets as far as the line where libusb_bulk_transfer is called, which then blocks.

All of the scanners were set to "keyboard" mode. I also tried using libusb to change the configuration of the scanners after detaching the kernel driver and prior to claiming the interface. Setting the configuration to 1 (I don't know yet how to determine which values are valid) works for the scanners for which the program works as expected, but the same call gave me a -6 (LIBUSB_ERROR_BUSY) for the devices that I couldn't get to work. Trying to release existing handles, as suggested in the documentation, gave me an error -5 (LIBUSB_ERROR_NOT_FOUND) for the interface id values I tried.

Am I forgetting something here? How can I figure out what is going wrong in more detail?

This is on raspbian 4.0.8-v7+, using libusb-1.0.19.

This is the code. Error handling and output removed for brevity.

#include <stdlib.h>
#include <stdio.h>
#include "libusb.h"

int main(void) {
    libusb_device_handle *dev_handle;
    libusb_context *ctx = NULL;

    libusb_init(&ctx);
    libusb_set_debug(ctx, 3);

    int vendorID = 0xXXXX, productID = 0xYYYY;

    dev_handle = libusb_open_device_with_vid_pid(ctx, vendorID, productID);

    if(libusb_kernel_driver_active(dev_handle, 0) == 1) {
        libusb_detach_kernel_driver(dev_handle, 0);
    }

    libusb_set_auto_detach_kernel_driver(dev_handle, 0);

    libusb_set_configuration(dev_handle, 1);

    libusb_claim_interface(dev_handle, 0);

    int bytes_read = 0;
    unsigned char data[8];
    int bytes_to_read = sizeof(data);
    int endpointID = 0x81;

    do {
        int r = libusb_bulk_transfer(
              dev_handle, 
              endpointID,
              data, 
              bytes_to_read, 
              &bytes_read, 
              0);

        for (int bi = 0; bi < bytes_read; ++bi) {
            printf("0x%02X  ", data[bi]);
        }
        printf("\n");
    } while (r == 0);

    libusb_release_interface(dev_handle, 0);

    libusb_close(dev_handle);
    libusb_exit(ctx);

    return 0;
}
waldrumpus
  • 2,540
  • 18
  • 44
  • I don't follow this in concept, but I notice you process the result of `libusb_bulk_transfer()` before you check its return status `r`. Instead of a `do` loop would it be better to write `while ((r=libusb_bulk_transfer(...)) == 0) {...}` ? – Weather Vane Aug 03 '15 at 15:07
  • @WeatherVane According to the [libusb documentation](http://libusb.sourceforge.net/api-1.0/group__syncio.html#gab8ae853ab492c22d707241dc26c8a805), the out parameter `transferred` (`bytes_read` in my example) will be initialized even if the function fails, so I think it's ok to do it like that. In any case, the call to `libusb_bulk_transfer` itself is where the program hangs. – waldrumpus Aug 04 '15 at 07:49
  • Did you get a chance to get the USB packet trace? That will be really helpful here. See whether the device is sending NAK continuously. – Shaibal Mar 12 '17 at 08:12

0 Answers0