Search code examples
cmultithreadinglibusb-1.0

Is it possible to create multiple connection instances to same USB device using libusb?


I am considering how to create a multithreaded application to send non-sequential messages to a USB device using libusb.

The two options are:

  1. create a single USB device connection and have multiple threads share that single connection?

  2. create multiple libusb connections to the same device allowing each thread to have their own connection?

(1) should be possible with some synchronisation mutexes on the relevant libusb calls.

I'm not sure if (2) is possible - if it is it may be simpler to implement?

That is the context for the question, but the specific question is:

Is it possible to create multiple connection instances to the same USB device using libusb?


Solution

  • See below for a small but complete C program proving that it is possible to have multiple connections to the same USB device.

    If you want to use it you would have to modify the VID and PID values appropriately for your device. There is also the assumption that the device makes bulk transfers on a control request from the host.

    Inspection of the r_1 and r_2 libusb_bulk_transfer call buf values indicates that bulk transfers using both USB handles have completed successfully, i.e. the expected packet data is present in each.

    /**
     * \brief test whether it is possible to have two connections to same usb device
     */
    
    #include <stdio.h>
    #include <libusb-1.0/libusb.h>
    
    int main()
    {
        int r_1;
        int r_2;
    
        libusb_device_handle *handle_1;
        libusb_device_handle *handle_2;
    
        uint8_t bmRequestType = 0x40 | 0x00| 0x00;
        uint8_t bRequest = 0x90;
    
        unsigned char buf[12008];
        int n;
    
        r_1 = libusb_init(NULL);
        r_2 = libusb_init(NULL);
    
        handle_1 = libusb_open_device_with_vid_pid(NULL, 0xFFFF, 0x0001);
        handle_2 = libusb_open_device_with_vid_pid(NULL, 0xFFFF, 0x0001);    
    
        libusb_claim_interface(handle_1, 0);
        libusb_claim_interface(handle_2, 0);
    
        r_1 = libusb_control_transfer(handle_1, bmRequestType,
                                      bRequest, 0, 0, NULL,
                                      0, 5000);
    
        r_1 = libusb_bulk_transfer(handle_1, 129,
                                   buf, 12008, &n,
                                   5000);
    
        r_2 = libusb_control_transfer(handle_2, bmRequestType,
                                      bRequest, 0, 0, NULL,
                                      0, 5000);
    
        r_2 = libusb_bulk_transfer(handle_2, 129,
                                   buf, 12008, &n,
                                   5000);
    
        printf("All Done!\n");
        return 0;
    }