Bonjour,

J'essaie de me faire un petit driver pour communiquer avec un thermomètre usb en utilisant la librairie LibUsb (org.usb4java.LibUsb). Je voudrais l'utiliser depuis un Raspberry Pi (Model 3b, en os linux-arm, distribution noobs).

Je teste mon code sur le raspberry mais dès que je veux envoyer un Control Packet j'ai l'erreur : org.usb4java.LibUsbException: USB error 9: Control transfer failed: Pipe error


Voici mon code :

classe main :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
public class usbDriver {
 
	public static void main(String[] args) {
		Communication2 com = new Communication2();
		try {
			com.trouverDevice();
			com.preparerCom();
			com.testCom();
			com.terminerCom();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

classe communication 2 :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
 
public class Communication2 {
 
	/** vendor ID du thermometre */
    private static final short VENDOR_ID = 0x1941;
 
    /** product ID du thermometre  */
    private static final short PRODUCT_ID = (short) 0x8021;
 
    /** interface active du thermometre  */
    private static final byte INTERFACE_ID = 0x0;
 
    /** endpoint sur l'interface active du thermometre  */
    private static final byte ENDPOINT_ID = (byte) 0x81;
 
    private Context contexte = null;
    private Device device = null;
    DeviceHandle handle = null;
 
	private boolean pret;
	private boolean detach = false;
	private boolean trouve = false;
 
 
 
	public Communication2() {
		pret = false;
	}
 
 
 
	public void trouverDevice() throws SecurityException, UsbException{
		// avec libUsb
		// Create the libusb context
        Context context = new Context();
 
        // Initialize the libusb context
        int result = LibUsb.init(context);
        if (result < 0)
        {
            throw new LibUsbException("Unable to initialize libusb", result);
        }
        // Read the USB device list
        DeviceList list = new DeviceList();
        result = LibUsb.getDeviceList(context, list);
        if (result < 0)
        {
            throw new LibUsbException("Unable to get device list", result);
        }
        try
        {
            // Iterate over all devices and list them
            for (Device device: list)
            {
                int address = LibUsb.getDeviceAddress(device);
                int busNumber = LibUsb.getBusNumber(device);
                DeviceDescriptor descriptor = new DeviceDescriptor();
                result = LibUsb.getDeviceDescriptor(device, descriptor);
                if (result < 0)
                {
                    throw new LibUsbException(
                        "Unable to read device descriptor", result);
                }
                if (descriptor.idVendor() == VENDOR_ID && descriptor.idProduct() == PRODUCT_ID){
                	System.out.println("Thermometre Pearl NC-7004 detecté !");
                	System.out.println(descriptor.toString());
                	this.device = device;
                	this.trouve=true;
                } 
            }
        }
 
 
        finally
        {
            // Ensure the allocated device list is freed
            //LibUsb.freeDeviceList(list, true);
        }
        // Deinitialize the libusb context	
	}
 
		public boolean preparerCom() throws Exception{
 
			if (!this.trouve) return false;
 
			this.contexte = new Context();
			int result = LibUsb.init(contexte);
 
			// reclamer le handle
			System.out.println("claim device handle");
			this.handle = new DeviceHandle();
			result = LibUsb.open(this.device, handle);
			if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to open USB device", result);
 
 
			detach = LibUsb.hasCapability(LibUsb.CAP_SUPPORTS_DETACH_KERNEL_DRIVER);
			detach = true; // pour forcer le claim sur le kernel
			detach = detach && (LibUsb.kernelDriverActive(handle, INTERFACE_ID)==1?true:false);
 
			System.out.println(LibUsb.hasCapability(LibUsb.CAP_SUPPORTS_DETACH_KERNEL_DRIVER));
			System.out.println((LibUsb.kernelDriverActive(handle, INTERFACE_ID)));
			System.out.println(detach);
 
			// Detach the kernel driver
			if (detach)
			{
				System.out.println("tentative de detacher le kernel");
			    result = LibUsb.detachKernelDriver(handle,  INTERFACE_ID);
			    if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to detach kernel driver", result);
			}
			detach = true;	
 
 
			System.out.println("claim interface");
			result = LibUsb.claimInterface(handle, INTERFACE_ID);
			if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to claim interface", result);
 
 
			this.pret=false;
			return this.pret;
		}
 
 
 
		public void testCom(){
			if (!this.pret) return;
 
			ByteBuffer buffer = ByteBuffer.allocate(18);
 
 
			// LibUsb.fillControlSetup(buffer, (byte)0x80, (byte)0x6,
			//		(short)0x1, (short)0x0, (short)0x1200);
 
			ByteBuffer buffer2 = ByteBuffer.allocateDirect(18);
 
			int transfered = LibUsb.controlTransfer(handle,(byte)0x80,(byte)0x6,(short)0x1,(short)0x0,buffer2,2000L);
			if (transfered < 0) throw new LibUsbException("Control transfer failed", transfered);
			System.out.println(transfered + " bytes sent");
 
			String test;
			String test2;
			if (buffer2.hasArray()) {
				for(int i =0;i<buffer2.array().length;i++){
					System.out.format("%02x",buffer2.array()[i]);
				}
 
 
			     test=  new String(buffer.array(),
			    		buffer.arrayOffset() + buffer.position(),
			    		buffer.remaining());
			} else {
			    final byte[] b = new byte[buffer.remaining()];
			    buffer.duplicate().get(b);
			    test =  new String(b);
			}
			System.out.println(test);
 
 
		}
 
 
 
 
		public void terminerCom() throws Exception{
			if (this.pret){
				if (this.detach)
				{
				    int result = LibUsb.attachKernelDriver(handle,  INTERFACE_ID);
				    if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to re-attach kernel driver", result);
				}
 
 
 
				LibUsb.close(this.handle);
				this.trouve = false;
				this.pret = false;
			}
		}
 
 
 
	}
L'erreur se produit quand j'appelle LibUsb.ControlTransfer alors que je veux juste transférer le paquet de contrôle GET DEVICE DESCRIPTOR.

Je pense que la communication est bien initialisée à ce moment là (le handle est bien initialisé, ainsi que l'interface qui a été detachée du Kernel pour m'être attribuée).


Voici la sortie console totale :
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 Per Interface
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x1941
idProduct 0x8021
bcdDevice 1.00
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1

claim device handle
false
0
false
claim interface
org.usb4java.LibUsbException: USB error 9: Control transfer failed: Pipe error
at usbDriver.Communication2.testCom(Communication2.java:171)
at usbDriver.usbDriver.main(usbDriver.java:36)
root@raspberrypi:/home/pi/Desktop/execUsbDriver# java -jar usbDriver_executable.jar
java.lang.IllegalArgumentException: handle must not be null
at org.usb4java.LibUsb.controlTransfer(Native Method)
at usbDriver.Communication2.testCom(Communication2.java:170)
at usbDriver.usbDriver.main(usbDriver.java:36)