libusb_wrapper.c 5.59 KB
#include "libusb_wrapper.h"



void usbinit(libusb_context **context_ptr) {
    //libusb_context *context;
    int statusInit = libusb_init(context_ptr);
    if (statusInit != LIBUSB_SUCCESS) {
        perror("libusb_init");
        exit(-1);
    }
}

void usbclose(libusb_context *context) {
    libusb_exit(context);
}

// Si le méchant noyau est passé avant vous :
void _getFromKernel(libusb_device_handle *handle, int interface) { //private method for now
    if (libusb_kernel_driver_active(handle, interface)) {
        int statusKDriver = libusb_detach_kernel_driver(handle, interface);
        if (statusKDriver != LIBUSB_SUCCESS) {
            perror("libusb_detach_kernel_driver");
            exit(-1);
        }
    }
}

ssize_t getListDevices(libusb_context *context, libusb_device ***list_ptr) {
    ssize_t count = libusb_get_device_list(context, list_ptr);
    if (count < 0) {
        perror("libusb_get_device_list");
        exit(-1);
    }
    return count;
}

void* _enumerateDevices(libusb_context *context, void (*func)(libusb_device *device)){
    libusb_device **list;
    ssize_t count = getListDevices(context, &list);

    ssize_t i = 0;
    for (i = 0; i < count; i++) {
        libusb_device *device = list[i];

        func(device);
    }

    libusb_free_device_list(list, 1);

    return NULL; //DBGONLY TEMP
}

//print readable string, not asked for tutoring
void _printConfig(libusb_device *device) {//private method
    // Ouverture du périphérique
    libusb_device_handle *handle;
    int statusDevice = libusb_open(device, &handle);
    if (statusDevice != LIBUSB_SUCCESS) {
        perror("libusb_open");
        //return; //exit(-1);
    }

    int MAXLEN_DESCRIPTOR_STRING = 200;
    uint8_t desc_idx = 2;
    //uint16_t langid = 16;
    unsigned char data[200];

    // TEST 16
    for (desc_idx = 0; desc_idx < 16; desc_idx++) {
        int statusAscii = libusb_get_string_descriptor_ascii(
                handle, desc_idx, data, MAXLEN_DESCRIPTOR_STRING);
        if (statusAscii == -9) // TEST seems to be LIBUSB_ERROR
            break;
        printf(" - Descriptor string : %s ; %i\n", data, statusAscii);
    }

    libusb_close(handle);
}


void _displayOneDevice(libusb_device *device){
    struct libusb_device_descriptor desc;

    int status = libusb_get_device_descriptor(device, &desc);
    if (status != LIBUSB_SUCCESS){
        printf("Cannot get device desc : %s\n", libusb_error_name(status)); //DBGONLY
        perror("libusb_open");
        return;
    }

    uint8_t bus = libusb_get_bus_number(device);
    uint8_t address = libusb_get_device_address(device);

    printf("Device Found @ (Bus:Address) %d:%d\n", bus, address);
    printf("Vendor ID 0x0%x\n", desc.idVendor);
    printf("Product ID 0x0%x\n", desc.idProduct);

    //displayDeviceEndpoints(device); //Not really work on Axel@Alptop
}

void displayDevices(libusb_context *context) {
    _enumerateDevices(context, _displayOneDevice);
}

void _displayOneDeviceMore(libusb_device *device){
    _displayOneDevice(device);
    _printConfig(device);
}

void displayDevicesMore(libusb_context *context) {
    _enumerateDevices(context, _displayOneDeviceMore);
}


//void getFirstDeviceFromID(vid, pid)


//void getDevicesFromID(vid, pid)


void displayDeviceEndpoints(libusb_device_handle* handle) {
    //recover pointer from handle
    libusb_device *device;
    device = libusb_get_device(handle);


    // lectures des configs?
/*    int configuration = 0; // valueof("bConfigurationValue");
    int statusConfig = libusb_set_configuration(handle, configuration);
    if (statusConfig != LIBUSB_SUCCESS) {
        perror("libusb_set_configuration");
        return;
    }
*/

    // 4.2 configuration du périph usb
    struct libusb_config_descriptor *config;
    int statusFetchConfig = libusb_get_active_config_descriptor(device, &config);
    if (statusFetchConfig != LIBUSB_SUCCESS) {
        perror("libusb_get_active_config_descriptor");
        return;
    }
    printf("Config.bConfigurationValue : %d\n", config->bConfigurationValue);
    printf("Config/ bLength:%d;bDescriptorType:%d;bNumInterfaces:%d",
           config->bLength, config->bDescriptorType, config->bNumInterfaces);


        // itération de l'interface
    printf("Itération de l'interface\n");
    for (int indexInterface = 0; indexInterface < config->bNumInterfaces; indexInterface++) {
        printf("indexInterface=%d\n", indexInterface);
        printf("Altsetting=%d\n", config->interface[indexInterface].num_altsetting);

        const struct libusb_interface * interface = &config->interface[indexInterface];


        //if 1 setting (or more)
        if(interface->num_altsetting != 0) {
            const struct libusb_interface_descriptor * interface_desc = &interface->altsetting[0];

            printf("--bNumEndpoints=%d\n", interface_desc->bNumEndpoints);
            printf("--bDescriptorType=%d\n", interface_desc->bDescriptorType);

            for(int indexEndpoints = 0; indexEndpoints < interface_desc->bNumEndpoints ; indexEndpoints++){
                const struct libusb_endpoint_descriptor * endpoint_desc = &interface_desc->endpoint[indexEndpoints];
                printf("---bDescriptorType=%d\n", endpoint_desc->bDescriptorType);
                printf("---bEndpointAddress=%d\n", endpoint_desc->bEndpointAddress);
		
	        if(endpoint_desc->extra != NULL)
                    printf("---extra: %s\n", endpoint_desc->extra);
                if(endpoint_desc->bmAttributes == LIBUSB_TRANSFER_TYPE_INTERRUPT)//TODO AJOUT MASQUE ? (voir doc)
                    printf("---is of type INTERRUPT\n");

            }
        }


    }

    printf("\n");

    libusb_close(handle);

}