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;
}