URL: https://linuxfr.org/forums/programmation-c/posts/test-de-communication-avec-un-device-usb-en-utilisant-libusb
Title: Test de communication avec un device USB en utilisant libusb
Authors: fox
Date: 2015-04-30T21:42:15+02:00
License: CC By-SA
Tags: libusb, debian, interrupt et endpoint
Score: 1
Bonsoir tout le monde,
J'ai un device USB dont lsusb me renvoit la description suivante (c'est long, je suis désolé):
```
Bus 001 Device 004: ID 0fde:0105
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0fde
idProduct 0x0105
bcdDevice 1.00
iManufacturer 0
iProduct 2 Tenx Nonstandard Device
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 59
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 41
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 33 US
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 23
Report Descriptor: (length is 23)
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x03 ] 3
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x40 ] 64
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Global): Usage Page, data= [ 0x08 ] 8
LEDs
Item(Local ): Usage Minimum, data= [ 0x01 ] 1
NumLock
Item(Local ): Usage Maximum, data= [ 0x40 ] 64
Indicator Fast Blink
Item(Main ): Output, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Main ): End Collection, data=none
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
Device Status: 0x0000
(Bus Powered)
```
Si je lis bien, j'ai deux endpoints de type "Interrupt":
* Un sur l'interface 0 défini à 0x81
* Un deuxième sur l'interface 1 défini à 0x82
J'ai écrit un petit programme en C++ afin d'essayer de communiquer avec. Cependant, j'ai essayé sur les 2 endpoints en revendiquant ("claimant") bien l'interface correspondante.
Ce qui est étonnant, c'est que quand j'essai de taper sur le endpoint 0x82, ça crashe lors de l'appel de la fonction libusb_interrupt_transfer et je n'arrive pas du tout à savoir pourquoi. Par contre, j'ai une erreur dans le dmesg qui apparait:
```
[10011.039485] TestLibUSB[1794]: segfault at 0 ip 00007f0d5416331a sp 00007ffd61279ff0 error 6 in libusb-1.0.so.0.1.0[7f0d54159000+16000]
```
Et voici la sortie de mon application quand je définie libusb en debug:
[ 0.000691] [00000794] libusb: debug [libusb_get_device_list]
[ 0.000713] [00000794] libusb: debug [discovered_devs_append] need to increase capacity
[ 0.000716] [00000794] libusb: debug [libusb_get_device_list]
[ 0.000717] [00000794] libusb: debug [discovered_devs_append] need to increase capacity
[ 0.000719] [00000794] libusb: debug [libusb_get_device_descriptor]
[ 0.000720] [00000794] libusb: debug [libusb_get_device_descriptor]
[ 0.000720] [00000794] libusb: debug [libusb_get_device_descriptor]
[ 0.000721] [00000794] libusb: debug [libusb_get_device_descriptor]
[ 0.000721] [00000794] libusb: debug [libusb_get_device_descriptor]
[ 0.000722] [00000794] libusb: debug [libusb_get_device_descriptor]
[ 0.000722] [00000794] libusb: debug [libusb_get_device_descriptor]
[ 0.000723] [00000794] libusb: debug [libusb_get_device_descriptor]
[ 0.000724] [00000794] libusb: debug [libusb_open] open 1.4
[ 0.000734] [00000794] libusb: debug [usbi_add_pollfd] add fd 11 events 4
[ 0.000739] [00000794] libusb: debug [libusb_kernel_driver_active] interface 1
[ 0.000742] [00000794] libusb: debug [libusb_claim_interface] interface 0
[ 0.000743] [00000794] libusb: debug [libusb_claim_interface] interface 1
[ 0.000754] [00000794] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 8
[ 0.000763] [00000794] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.000764] [00000794] libusb: debug [handle_events] poll() 4 fds with timeout in 60000ms
[ 0.003052] [00000794] libusb: debug [handle_events] poll() returned 1
[ 0.003061] [00000794] libusb: debug [reap_for_handle] urb type=1 status=-71 transferred=0
[ 0.003063] [00000794] libusb: debug [handle_bulk_completion] handling completion status -71 of bulk urb 1/1
[ 0.003064] [00000794] libusb: debug [handle_bulk_completion] low level error -71
[ 0.003066] [00000794] libusb: debug [disarm_timerfd]
[ 0.003070] [00000794] libusb: debug [usbi_handle_transfer_completion] transfer 0x175fbc0 has callback 0x7f493c8c81d0
[ 0.003071] [00000794] libusb: debug [sync_transfer_cb] actual_length=0
The program has unexpectedly finished.
Alors que si j'essai de taper sur 0x81, j'ai bien le retour de la fonction dont le code d'erreur est LIBUSB_ERROR_IO. Même chose quand je veux taper vers d'autres endpoints qui n'apparaissent pas dans la sortie de lsusb. Par contre, voici la sortie de l'application quand je définie libusb en debug:
[ 0.000683] [00000780] libusb: debug [libusb_get_device_list]
[ 0.000705] [00000780] libusb: debug [discovered_devs_append] need to increase capacity
[ 0.000708] [00000780] libusb: debug [libusb_get_device_list]
[ 0.000709] [00000780] libusb: debug [discovered_devs_append] need to increase capacity
[ 0.000710] [00000780] libusb: debug [libusb_get_device_descriptor]
[ 0.000711] [00000780] libusb: debug [libusb_get_device_descriptor]
[ 0.000712] [00000780] libusb: debug [libusb_get_device_descriptor]
[ 0.000712] [00000780] libusb: debug [libusb_get_device_descriptor]
[ 0.000713] [00000780] libusb: debug [libusb_get_device_descriptor]
[ 0.000713] [00000780] libusb: debug [libusb_get_device_descriptor]
[ 0.000714] [00000780] libusb: debug [libusb_get_device_descriptor]
[ 0.000715] [00000780] libusb: debug [libusb_get_device_descriptor]
[ 0.000715] [00000780] libusb: debug [libusb_open] open 1.4
[ 0.000726] [00000780] libusb: debug [usbi_add_pollfd] add fd 11 events 4
[ 0.000731] [00000780] libusb: debug [libusb_kernel_driver_active] interface 1
[ 0.000734] [00000780] libusb: debug [libusb_claim_interface] interface 0
[ 0.000735] [00000780] libusb: debug [libusb_claim_interface] interface 1
[ 0.000745] [00000780] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 8
[ 0.000747] [00000780] libusb: error [submit_bulk_transfer] submiturb failed error -1 errno=2
[ 0.000748] [00000780] libusb: debug [submit_bulk_transfer] first URB failed, easy peasy
[ 0.000749] [00000780] libusb: debug [disarm_timerfd]
Failed to transfer data 0x0 0x7ffc305266f0 LIBUSB_ERROR_IO
[ 0.000848] [00000780] libusb: debug [libusb_release_interface] interface 0
[ 0.000850] [00000780] libusb: debug [libusb_release_interface] interface 1
[ 0.000856] [00000780] libusb: debug [libusb_close]
[ 0.000858] [00000780] libusb: debug [usbi_remove_pollfd] remove fd 11
[ 0.000861] [00000780] libusb: debug [libusb_exit]
[ 0.000862] [00000780] libusb: debug [libusb_exit] destroying default context
Voici un petit morceau de code afin d'effectuer mon appel:
```c
libusb_claim_interface(deviceHandle, 1);
unsigned char question[8];
int *actualLength = 0;
int ret = libusb_interrupt_transfer(deviceHandle, 0x81, question, 8, actualLength, 0); // ca crash ici
```
En sauriez-vous plus sur le problème ? Est-ce la bibliothèque qui est bugguée ? Ai-je fait quelque chose de mal dans le code ?