#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); } void interfaceclaim(libusb_device_handle *handle, struct libusb_interface *interface){ const struct libusb_interface_descriptor * interface_desc = &interface->altsetting[0]; //TODO enlever cette ligne, refactor int status=libusb_claim_interface(handle, interface_desc->bInterfaceNumber); if(status!=0){ perror("libusb_claim_interface"); exit(-1); } } void interfaceclose(libusb_device_handle *handle, struct libusb_interface *interface){ const struct libusb_interface_descriptor * interface_desc = &interface->altsetting[0]; int status = libusb_release_interface(handle, interface_desc->bInterfaceNumber); if(status!=0){ perror("libusb_release_interface"); exit(-1); } } // 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); } //get device from iteration (and not from not recommanded function : //ugly using global vars ?? Cannot communicate between getFirstDeviceFromID and _getFirstDeviceFromID int g_vid; int g_pid; libusb_device *g_device = NULL; void _getFirstDeviceFromID(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; } if(desc.idVendor == g_vid && desc.idProduct == g_pid){ g_device = device; } } void getFirstDeviceFromID(libusb_context *context, int vid, int pid, libusb_device **device) { g_vid = vid; //pass parameters for enumeration g_pid = pid; //idem _enumerateDevices(context, _getFirstDeviceFromID); *device = g_device; //get return from enumeration } //void getDevicesFromID(vid, pid) //return array void displayDeviceEndpoints(libusb_device_handle* handle) { //recover pointer from handle libusb_device *device; device = libusb_get_device(handle); // lectures des configs => on prend la première configuration pour l'instant /*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; } //caractéristiques globales printf("Config.bConfigurationValue : %d\n", config->bConfigurationValue); printf("Config/ bLength:%d\nbDescriptorType:%d\nbNumInterfaces:%d\n", config->bLength, config->bDescriptorType, config->bNumInterfaces); //itération des interfaces 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"); } } //Affichez l’indice et le numéro de chaque interface détectée et réclamée. Affichez aussi les points d’accès trouvés en précisant ceux sauvés. /* //int interface=valueof("bInterfaceNumber"); int status=libusb_claim_interface(handle,interface->bInterfaceNumber); if(status!=0){ perror("libusb_claim_interface"); exit(-1); } status=libusb_release_interface(handle,interface->bInterfaceNumber); if(status!=0){ perror("libusb_release_interface"); exit(-1); } //claim_interface(.., config interface altsetting bInterfaceNumber //config interface altsetting endpoint bmAttributes == LIBUSB_TRANSFER_TYPE_INTERRUPT //add des enpoint unint8_t*/ //DESCRIPTOR.C /.H :décommenter //IL FAUT RELEASE UNIQUEMENT LES INTERFACES QUI NE SONT PAS DES HID } printf("\n"); libusb_close(handle); } void getOurInterfaces(libusb_device *device, struct libusb_interface **int_hidjoy, struct libusb_interface **int_leds, struct libusb_interface **int_vibrators ) { 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; } //itération des interfaces printf("Itération de l'interface\n"); for (int indexInterface = 0; indexInterface < config->bNumInterfaces; indexInterface++) { struct libusb_interface * interface = &config->interface[indexInterface]; //todo use le descriptor pour avoir bInterfaceNumber? if(indexInterface==0){ *int_hidjoy = interface; }else if(indexInterface==1){ *int_leds = interface; }else if(indexInterface==2){ *int_vibrators = interface; } //#define pour les indices correspondants aux interfaces //variables globales } }