#include #include #include /* Caractéristiques du périphérique */ #define VENDOR_ID 0x2341 #define PRODUCT_ID 0x0001 #define TAB_PA_SIZE 10 libusb_device_handle *handle=NULL; libusb_device *device=NULL; libusb_device *found=NULL; //notre périphérique libusb_context *context; /* struct TABLEAU{ struct EP *tableau[3]; //tableau des points d'accès en interruption int dernier; }; struct EP { uint8_t ep; //adresse d'accès de l'endpoint unsigned char io; //décrit si c'est une entrée ou une sortie }; //init structure tableau struct TABLEAU tab_pa; void init_tableau(){ for (int i=0;i<3;i++){ tab_pa.tableau[i]=NULL; } tab_pa.dernier=0; } */ /*énumération des périphériques USB*/ void enum_periph(){ libusb_device **list; /* On compte le nombre de périphérique connectés... */ ssize_t count=libusb_get_device_list(context,&list); if(count<0) {perror("libusb_get_device_list"); exit(-1);} ssize_t i=0; /* et on en établit la liste complète */ for(i=0;ibConfigurationValue); int interface; /* Si le noyau est passé avant nous, On le détache pour chaque alternative d'interface numéro 0 */ for(int indice_intf=0;indice_intf < config_desc->bNumInterfaces ;indice_intf++){ interface=config_desc->interface[indice_intf].altsetting[0].bInterfaceNumber; if(libusb_kernel_driver_active(handle,interface)){ int status=libusb_detach_kernel_driver(handle,interface); if(status!=0){ perror("libusb_detach_kernel_driver"); exit(-1); } //erreur si status!=0 } //printf("indice intf trouvée %d\n",interface); } /* Utilisation de la configuration */ int dernier_PA=-1; int configuration=config_desc->bConfigurationValue; //printf("valeur config %d\n", configuration); // Affichage valeur de la configuration status=libusb_set_configuration(handle,configuration); if(status!=0){ perror("libusb_set_configuration"); exit(-1); } /* Appropriation de toutes les interfaces */ int num_intf; for(int indice_intf=0;indice_intf < config_desc->bNumInterfaces ;indice_intf++){ num_intf = config_desc->interface[indice_intf].altsetting[0].bInterfaceNumber; status=libusb_claim_interface(handle,indice_intf); if(status!=0){ perror("libusb_claim_interface"); exit(-1); } printf("\tInterface d'indice %d et de numéro %d réclamée\n",indice_intf,num_intf); /* Parcours des points d'accès (Endpoint) pour chaque interface*/ for(int num_PA=0;num_PAinterface[indice_intf].altsetting[0].bNumEndpoints ;num_PA++){ int type_PA = config_desc->interface[indice_intf].altsetting[0].endpoint[num_PA].bmAttributes; uint8_t adresse_PA = config_desc->interface[indice_intf].altsetting[0].endpoint[num_PA].bEndpointAddress; printf("\t\tPoint d'accès trouvé. Adresse : %d\n",adresse_PA); /* Regarde si le point d'accès est de type interruption. Si oui, on le sauvegarde. */ if((type_PA & 0b11)==LIBUSB_TRANSFER_TYPE_INTERRUPT){ //struct EP ep1; dernier_PA++; tab_PA[dernier_PA] = adresse_PA; printf("\t\tPoint d'accès numéro %d sauvegardé. Adresse : %d\n", dernier_PA, adresse_PA); /* ep1.ep=config_desc->interface[indice_intf].altsetting[0].endpoint->bEndpointAddress; if (indice_intf==0){ tab_pa.tableau[indice_intf]->ep=ep1.ep; tab_pa.tableau[indice_intf]->io=1; tab_pa.dernier++; } else{ tab_pa.tableau[indice_intf]->ep=ep1.ep; tab_pa.tableau[indice_intf]->io=0; tab_pa.dernier++; if (num_ep >2)break; //entrée => io=0 // Le if et else ci-dessus doivent pouvoir être simplifiés. */ } } } //printf("dernier indice tab_PA : %d\n", dernier_PA); } /* Libération des interfaces de la configuration active */ void liberer_interfaces(){ /* Récupération de la configuration active */ struct libusb_config_descriptor* config_desc; int status =libusb_get_active_config_descriptor(found,&config_desc); if(status!=0){perror("libusb_get_active_config_descriptor");exit(-1);} /* On parcourt toutes les interfaces*/ int num_intf; for(int indice_intf=0;indice_intf < config_desc->bNumInterfaces ;indice_intf++){ num_intf=config_desc->interface[indice_intf].altsetting[0].bInterfaceNumber; /* Libération de l'interface num_intf*/ status=libusb_release_interface(handle,num_intf); if(status!=0){ perror("libusb_release_interface"); exit(-1); } printf("\tL'interface numéro %d, d'indice %d a été libérée.\n", num_intf,indice_intf); } } /* Envoie un caractère (de commande de LED) sur le port USB */ void send_data(unsigned char tab_PA[TAB_PA_SIZE], unsigned char data){ unsigned char PA = tab_PA[0]; //LEDs sur le premier point d'accès printf("adresse PA %d\n", tab_PA[0]); int transferred = 1; //nombre d'octets transférés unsigned int timeout = 1000; //temps avant un timeout int status = libusb_interrupt_transfer(handle, PA, &data, sizeof(data), &transferred, timeout); if(status!=0){perror("libusb_interrupt_transfer");exit(-1);} } /* Lis le contenu des points d'accès de l'interface IN (boutons et joystick) */ void receive_data(unsigned char tab_PA[TAB_PA_SIZE], unsigned char *boutons, unsigned char *joystick_x, unsigned char *joystick_y){ /* Lecture du point d'accès des boutons */ unsigned char PA = tab_PA[1]; //LEDs sur le premier point d'accès printf("adresse PA %d\n", tab_PA[1]); int transferred = 1; //nombre d'octets transférés unsigned int timeout = 1000; //temps avant un timeout int status = libusb_interrupt_transfer(handle, PA, boutons, sizeof(boutons), &transferred, timeout); if(status!=0){perror("libusb_interrupt_transfer");printf("erreur lecture boutons, adresse PA %d\n",tab_PA[1]);exit(-1);} /* Lecture du point d'accès du joystick */ unsigned char *joystick_xy=NULL; //stocke la donnée du point d'accès (1 octet pour chaque axe) PA = tab_PA[2]; //LEDs sur le premier point d'accès printf("adresse PA %d\n", tab_PA[2]); transferred = 2; //nombre d'octets transférés timeout = 1000; //temps avant un timeout status = libusb_interrupt_transfer(handle, PA, joystick_xy, sizeof(joystick_xy), &transferred, timeout); if(status!=0){perror("libusb_interrupt_transfer");exit(-1);} //TODO Pas sûr !!! if (joystick_xy !=NULL){ *joystick_x = joystick_xy[0]; //On sépare la data de chaque axe *joystick_y = joystick_xy[1]; } } int main(){ //init_tableau(); // initialisation tableau point d'accès endpoint /* Initialisation de la bibliothèque libusb-1.0 */ int status=libusb_init(&context); if(status!=0) {perror("libusb_init"); exit(-1);} //fin inititialisation /* Enumération des périphériques USB */ enum_periph(); /* Ouverture de notre périphérique 'found' */ int status_ouv=libusb_open(found,&handle); if(status_ouv!=0){ perror("libusb_open"); exit(-1); } /* Configuration du périphérique et sauvegarde des points d'accès */ unsigned char tab_PA[TAB_PA_SIZE]; config_periph(tab_PA); unsigned char *boutons = NULL, *boutons_anc = NULL; unsigned char *joystick_x = NULL, *joystick_x_anc = NULL; unsigned char *joystick_y = NULL, *joystick_y_anc = NULL; unsigned char caractere; //TODO boucle while(pas d'arrêt), envoi et rcpt //TODO "pas d'arrêt" = appui sur 's' par exemple while(1){ /*if (appui sur une touche){ //récupération caractère send_data(tab_PA, caractere); //Envoi de la commande des leds } else { */ printf("début rcpt\n"); receive_data(tab_PA, boutons, joystick_x, joystick_y); //Réception des boutons et joystick printf("fin rcpt\n"); if ((boutons == NULL) || (joystick_x == NULL) || (joystick_y == NULL)) printf("Erreur réception : pointeurs boutons ou joystick nul\n"); if ((*boutons != *boutons_anc) || (joystick_x != joystick_x_anc) || (joystick_y != joystick_y_anc)) printf("Boutons : %c, Joystick_x : %c, Joystick_y :%c\n", *boutons, *joystick_x, *joystick_y); //Affichage si changement *boutons_anc = *boutons; *joystick_x_anc = *joystick_x; *joystick_y_anc = *joystick_y; //} } //*/ /* Libération des interfaces*/ liberer_interfaces(); /* Fermeture du périphérique */ libusb_close(handle); libusb_exit(context); //fermeture de la bibliothèque return 0; }