0

I have made a C-program that should talk USB. But I have got an error -1 that says I have som Input/Output errors.

My C code is here below. I going to explain how it works. The function getDevices() print out the vendor ID and the product ID and also the device name. Remember those when you running the function getDevices().

Then you have to choose what device you want to connect. When you have choose the device, then you write in the vendor ID and product ID here.

#define USB_VENDOR_ID   1155
#define USB_PRODUCT_ID  14415 /* USB product ID used by the device */

After that, you need to run the function connectUSB(). It simply connect to your USB depening on which USB_VENDOR_ID and USB_PRODUCT_ID you have been written.

I have issues to read the incomming message. I got the error LIBUSB_ERROR_IO = -1 when I try to read.

So why does I get -1 error when I try to read? I have tried with:

  • Run the C-code as full administration rights, e.g root
  • Unmout the USB device inside the computer, not plug it out
  • Tested to have a USB reader software ON meanwhile I use this C-program

If you want to try my code, you have to install LibUSB. From debbased systems such as Debian, Ubuntu, Raspberry etc. it can be done by writing this command in the terminal.

sudo apt-get install libusb-1.0.0-dev libusb-1.0-0

My C-code below.

#include <stdio.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>
#include <string.h>

libusb_context *CONTEXT; //a libusb session
libusb_device_handle *DEVICEHANDLE; //a device handle
libusb_device * DEVICE_POINTER; // a pointer to a device
libusb_device **ARRAY_OF_POINTERS_TO_DEVICE; // an array of pointers to devices
ssize_t NUMBER_OF_USB_DEVICES; // Initial zero devices

static uint8_t receiveBuf[64];
uint8_t transferBuf[64];

uint16_t counter = 0;
#define USB_ENDPOINT_IN     0x80   /* endpoint address */
#define USB_ENDPOINT_OUT    0x01  /* endpoint address */
#define USB_TIMEOUT 3000 /* Connection timeout (in ms) */
#define USB_VENDOR_ID   1155
#define USB_PRODUCT_ID  14415 /* USB product ID used by the device */

/*
 * Here we are going to read the USB
 */
int readUSB() {
    int nread, r, counter = 0;
    nread = 4;
    int transfered;
    unsigned char data[4];

    r = libusb_bulk_transfer(DEVICEHANDLE, USB_ENDPOINT_IN, data, nread, &transfered, USB_TIMEOUT);
    if (LIBUSB_ERROR_TIMEOUT == r) {
        printf("LIBUSB_ERROR_TIMEOUT = %d\n", r);
        return -1;
    }else if(LIBUSB_ERROR_PIPE == r){
        printf("LIBUSB_ERROR_PIPE = %d\n", r);
        return -1;
    }else if(LIBUSB_ERROR_OVERFLOW == r){
        printf("LIBUSB_ERROR_OVERFLOW = %d\n", r);
        return -1;
    }else if(LIBUSB_ERROR_NO_DEVICE == r){
        printf("LIBUSB_ERROR_NO_DEVICE = %d\n", r);
        return -1;
    }else if(LIBUSB_ERROR_IO == r){
        printf("LIBUSB_ERROR_IO = %d\n", r);
        return -1;
    } else {
        printf("r = %d, %d receive %d bytes from device: %s\n", r, ++counter, nread, data);
        return 0;
    }


    return 0;
}

/*
 * Here are we going to write to the USB
 */
int writeUSB() {
    int n, ret;
    uint16_t count = 0;
    //count up
    n = sprintf(transferBuf, "%d\0", count++);
    //write transfer
    //probably unsafe to use n twice...
    ret = libusb_bulk_transfer(DEVICEHANDLE, USB_ENDPOINT_OUT, transferBuf, n,
            &n, USB_TIMEOUT);
    //Error handling
    switch (ret) {
    case 0:
        printf("send %d bytes to device\n", n);
        return 0;
    case LIBUSB_ERROR_TIMEOUT:
        printf("ERROR in bulk write: %d Timeout\n", ret);
        break;
    case LIBUSB_ERROR_PIPE:
        printf("ERROR in bulk write: %d Pipe\n", ret);
        break;
    case LIBUSB_ERROR_OVERFLOW:
        printf("ERROR in bulk write: %d Overflow\n", ret);
        break;
    case LIBUSB_ERROR_NO_DEVICE:
        printf("ERROR in bulk write: %d No Device\n", ret);
        break;
    default:
        printf("ERROR in bulk write: %d\n", ret);
        break;

    }
    return -1;
    return 0;
}

/*
 * This will connect to our USB device
 */
int connectUSB() {
    int r;
    r = libusb_init(&CONTEXT);
    if(r > 0){
        printf("Libusb_init error %d\n", r);
        return -1;
    }
    //libusb_set_debug(CONTEXT, 0);

    //Open Device with VendorID and ProductID
    DEVICEHANDLE = libusb_open_device_with_vid_pid(CONTEXT, USB_VENDOR_ID, USB_PRODUCT_ID);
    if (DEVICEHANDLE == NULL) {
        perror("DEVICEHANDLE == NULL");
        return -1;
    }

    //Claim Interface 0 from the device
    r = libusb_claim_interface(DEVICEHANDLE, 0);
    if (r == LIBUSB_ERROR_NOT_FOUND) {
        fprintf(stderr, "LIBUSB_ERROR_NOT_FOUND = %d\n", r);
        return -1;
    }else if(r == LIBUSB_ERROR_BUSY){
        fprintf(stderr, "LIBUSB_ERROR_BUSY = %d\n", r);
        return -1;
    }else if(r == LIBUSB_ERROR_NO_DEVICE){
        fprintf(stderr, "LIBUSB_ERROR_NO_DEVICE = %d\n", r);
        return -1;
    }

    printf("Interface claimed\n");
    return 0;
}

/*
 * This will show all the devices for USB and send it thru sockets
 */
int getDevices() {

    /*
     * Special local device handle for only get the name of the USB device
     */
    libusb_device_handle *DEVICEHANDLE_NULL; //a device handle

    /*
     * Compute the number of USB
     */
    int returnValue = libusb_init(NULL);
    NUMBER_OF_USB_DEVICES = libusb_get_device_list(NULL,
            &ARRAY_OF_POINTERS_TO_DEVICE);

    /*
     * Create our list of Vendor, Product and device
     * Vendor and product are important for connect the USB and device is important for the user to see which USB to connect
     */
    uint16_t vendor[NUMBER_OF_USB_DEVICES];
    uint16_t product[NUMBER_OF_USB_DEVICES];
    char device[NUMBER_OF_USB_DEVICES][256 * 2];

    /*
     * Loop thru all USB devices
     */
    ssize_t deviceIndex = 0;
    while (deviceIndex < NUMBER_OF_USB_DEVICES) {

        /*
         * Get the description of the USB device
         */
        DEVICE_POINTER = ARRAY_OF_POINTERS_TO_DEVICE[deviceIndex];
        struct libusb_device_descriptor deviceDescriptor;
        returnValue = libusb_get_device_descriptor(DEVICE_POINTER,
                &deviceDescriptor);
        if (returnValue != LIBUSB_SUCCESS)
            break;

        /*
         * Open the USB device with NULL. It's only because we want the name of the USB device
         */
        DEVICEHANDLE_NULL = NULL;
        returnValue = libusb_open(DEVICE_POINTER, &DEVICEHANDLE_NULL);
        if (returnValue != LIBUSB_SUCCESS) {
            /*
             * There was an error. Not success.
             */

            if (DEVICEHANDLE_NULL != NULL) {
                libusb_close(DEVICEHANDLE_NULL);
                DEVICEHANDLE_NULL = NULL;
            }

            /*
             * Write as there was no info at all to display
             */
            product[deviceIndex] = 0;
            vendor[deviceIndex] = 0;
            memcpy(device[deviceIndex], "-", 256 * 2 * sizeof(char));
            deviceIndex++;
            continue;

        }

        /*
         * Get the string associated with iManufacturer index.
         */
        const int STRING_LENGTH = 256;
        unsigned char stringManufacturer[STRING_LENGTH];
        unsigned char stringProduct[STRING_LENGTH];
        char stringDeviceName[STRING_LENGTH * 2];
        if (DEVICEHANDLE_NULL != NULL && deviceDescriptor.iManufacturer > 0) {
            returnValue = libusb_get_string_descriptor_ascii(DEVICEHANDLE_NULL,
                    deviceDescriptor.iManufacturer, stringManufacturer,
                    STRING_LENGTH);
            if (returnValue < 0)
                break;
        }

        /*
         * Get string associated with iProduct index.
         */
        if (DEVICEHANDLE_NULL != NULL && deviceDescriptor.iProduct > 0) {
            returnValue = libusb_get_string_descriptor_ascii(DEVICEHANDLE_NULL,
                    deviceDescriptor.iProduct, stringProduct, STRING_LENGTH);
            if (returnValue < 0)
                break;
        }

        /*
         * Combine manufacturer and product
         */
        strcpy(stringDeviceName, (char*) stringManufacturer);
        strcat(stringDeviceName, " "); // a space only
        strcat(stringDeviceName, (char*) stringProduct);
        //printf("%s\n", stringDeviceName);

        /*
         * Save them all into arrays
         */
        product[deviceIndex] = deviceDescriptor.idProduct;
        vendor[deviceIndex] = deviceDescriptor.idVendor;
        memcpy(device[deviceIndex], stringDeviceName, 256 * 2 * sizeof(char));

        /*
         * Close and try next one.
         */
        if (DEVICEHANDLE_NULL != NULL) {
            libusb_close(DEVICEHANDLE_NULL);
            DEVICEHANDLE_NULL = NULL;
        }

        /*
         * Next USB device
         */
        deviceIndex++;
    }

    /*
     * Print our result what we found and send them to socket
     */
    for (int i = 0; i < 11; i++) {
        printf("Name: %s\n", device[i]);
        printf("Vendor: %u\n", vendor[i]);
        printf("Product: %u\n\n", product[i]);
    }

    libusb_exit(NULL);

    return 0;
}
euraad
  • 2,467
  • 5
  • 30
  • 51

0 Answers0