#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 if (interface_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC) { // ON PEUT VERIFIER LA CLASS printf("> vendor specific class\n"); 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 for (int indexInterface = 0; indexInterface < config->bNumInterfaces; indexInterface++) { const struct libusb_interface *interface = &config->interface[indexInterface]; // todo use le descriptor pour avoir bInterfaceNumber? if (indexInterface == 0) { *int_hidjoy = (struct libusb_interface *)interface; } else if (indexInterface == 1) { *int_leds = (struct libusb_interface *)interface; } else if (indexInterface == 2) { *int_vibrators = (struct libusb_interface *)interface; } //#define pour les indices correspondants aux interfaces // variables globales } } char getOnlyEndpoint(struct libusb_interface *interface) { const struct libusb_interface_descriptor *interface_desc = &interface->altsetting[0]; const struct libusb_endpoint_descriptor *endpoint_desc = &interface_desc->endpoint[0]; if (endpoint_desc->bmAttributes != LIBUSB_TRANSFER_TYPE_INTERRUPT) // ON PEUT VERIFIER LE TRANSFER TYPE printf("> is NOT of type INTERRUPT\n"); return (char)endpoint_desc->bEndpointAddress; }