| @@ -0,0 +1,307 @@ |
| @@ -0,0 +1,307 @@ |
| |
1
| +#include "libusb_wrapper.h" |
| |
2
| + |
| |
3
| +void usbinit(libusb_context **context_ptr) { |
| |
4
| + // libusb_context *context; |
| |
5
| + int statusInit = libusb_init(context_ptr); |
| |
6
| + if (statusInit != LIBUSB_SUCCESS) { |
| |
7
| + perror("libusb_init"); |
| |
8
| + exit(-1); |
| |
9
| + } |
| |
10
| +} |
| |
11
| + |
| |
12
| +void usbclose(libusb_context *context) { libusb_exit(context); } |
| |
13
| + |
| |
14
| +void interfaceclaim(libusb_device_handle *handle, |
| |
15
| + struct libusb_interface *interface) { |
| |
16
| + const struct libusb_interface_descriptor *interface_desc = |
| |
17
| + &interface->altsetting[0]; // TODO enlever cette ligne, refactor |
| |
18
| + |
| |
19
| + if (interface_desc->bInterfaceClass == |
| |
20
| + LIBUSB_CLASS_VENDOR_SPEC) { // ON PEUT VERIFIER LA CLASS |
| |
21
| + printf("> vendor specific class\n"); |
| |
22
| + |
| |
23
| + int status = |
| |
24
| + libusb_claim_interface(handle, interface_desc->bInterfaceNumber); |
| |
25
| + if (status != 0) { |
| |
26
| + perror("libusb_claim_interface"); |
| |
27
| + exit(-1); |
| |
28
| + } |
| |
29
| + } |
| |
30
| +} |
| |
31
| + |
| |
32
| +void interfaceclose(libusb_device_handle *handle, |
| |
33
| + struct libusb_interface *interface) { |
| |
34
| + const struct libusb_interface_descriptor *interface_desc = |
| |
35
| + &interface->altsetting[0]; |
| |
36
| + int status = |
| |
37
| + libusb_release_interface(handle, interface_desc->bInterfaceNumber); |
| |
38
| + if (status != 0) { |
| |
39
| + perror("libusb_release_interface"); |
| |
40
| + exit(-1); |
| |
41
| + } |
| |
42
| +} |
| |
43
| + |
| |
44
| +// Si le méchant noyau est passé avant vous : |
| |
45
| +void getFromKernel(libusb_device_handle *handle, |
| |
46
| + int interface) { // private method for now |
| |
47
| + if (libusb_kernel_driver_active(handle, interface)) { |
| |
48
| + int statusKDriver = libusb_detach_kernel_driver(handle, interface); |
| |
49
| + if (statusKDriver != LIBUSB_SUCCESS) { |
| |
50
| + perror("libusb_detach_kernel_driver"); |
| |
51
| + exit(-1); |
| |
52
| + } |
| |
53
| + } |
| |
54
| +} |
| |
55
| + |
| |
56
| +ssize_t getListDevices(libusb_context *context, libusb_device ***list_ptr) { |
| |
57
| + ssize_t count = libusb_get_device_list(context, list_ptr); |
| |
58
| + if (count < 0) { |
| |
59
| + perror("libusb_get_device_list"); |
| |
60
| + exit(-1); |
| |
61
| + } |
| |
62
| + return count; |
| |
63
| +} |
| |
64
| + |
| |
65
| +void *_enumerateDevices(libusb_context *context, |
| |
66
| + void (*func)(libusb_device *device)) { |
| |
67
| + libusb_device **list; |
| |
68
| + ssize_t count = getListDevices(context, &list); |
| |
69
| + |
| |
70
| + ssize_t i = 0; |
| |
71
| + for (i = 0; i < count; i++) { |
| |
72
| + libusb_device *device = list[i]; |
| |
73
| + |
| |
74
| + func(device); |
| |
75
| + } |
| |
76
| + |
| |
77
| + libusb_free_device_list(list, 1); |
| |
78
| + |
| |
79
| + return NULL; // DBGONLY TEMP |
| |
80
| +} |
| |
81
| + |
| |
82
| +// print readable string, not asked for tutoring |
| |
83
| +void _printConfig(libusb_device *device) { // private method |
| |
84
| + // Ouverture du périphérique |
| |
85
| + libusb_device_handle *handle; |
| |
86
| + int statusDevice = libusb_open(device, &handle); |
| |
87
| + if (statusDevice != LIBUSB_SUCCESS) { |
| |
88
| + perror("libusb_open"); |
| |
89
| + // return; //exit(-1); |
| |
90
| + } |
| |
91
| + |
| |
92
| + int MAXLEN_DESCRIPTOR_STRING = 200; |
| |
93
| + uint8_t desc_idx = 2; |
| |
94
| + // uint16_t langid = 16; |
| |
95
| + unsigned char data[200]; |
| |
96
| + |
| |
97
| + // TEST 16 |
| |
98
| + for (desc_idx = 0; desc_idx < 16; desc_idx++) { |
| |
99
| + int statusAscii = libusb_get_string_descriptor_ascii( |
| |
100
| + handle, desc_idx, data, MAXLEN_DESCRIPTOR_STRING); |
| |
101
| + if (statusAscii == -9) // TEST seems to be LIBUSB_ERROR |
| |
102
| + break; |
| |
103
| + printf(" - Descriptor string : %s ; %i\n", data, statusAscii); |
| |
104
| + } |
| |
105
| + |
| |
106
| + libusb_close(handle); |
| |
107
| +} |
| |
108
| + |
| |
109
| +void _displayOneDevice(libusb_device *device) { |
| |
110
| + struct libusb_device_descriptor desc; |
| |
111
| + |
| |
112
| + int status = libusb_get_device_descriptor(device, &desc); |
| |
113
| + if (status != LIBUSB_SUCCESS) { |
| |
114
| + printf("Cannot get device desc : %s\n", |
| |
115
| + libusb_error_name(status)); // DBGONLY |
| |
116
| + perror("libusb_open"); |
| |
117
| + return; |
| |
118
| + } |
| |
119
| + |
| |
120
| + uint8_t bus = libusb_get_bus_number(device); |
| |
121
| + uint8_t address = libusb_get_device_address(device); |
| |
122
| + |
| |
123
| + printf("Device Found @ (Bus:Address) %d:%d\n", bus, address); |
| |
124
| + printf("Vendor ID 0x0%x\n", desc.idVendor); |
| |
125
| + printf("Product ID 0x0%x\n", desc.idProduct); |
| |
126
| + |
| |
127
| + // displayDeviceEndpoints(device); //Not really work on Axel@Alptop |
| |
128
| +} |
| |
129
| + |
| |
130
| +void displayDevices(libusb_context *context) { |
| |
131
| + _enumerateDevices(context, _displayOneDevice); |
| |
132
| +} |
| |
133
| + |
| |
134
| +void _displayOneDeviceMore(libusb_device *device) { |
| |
135
| + _displayOneDevice(device); |
| |
136
| + _printConfig(device); |
| |
137
| +} |
| |
138
| + |
| |
139
| +void displayDevicesMore(libusb_context *context) { |
| |
140
| + _enumerateDevices(context, _displayOneDeviceMore); |
| |
141
| +} |
| |
142
| + |
| |
143
| +// get device from iteration (and not from not recommanded function : |
| |
144
| +// ugly using global vars ?? Cannot communicate between getFirstDeviceFromID and |
| |
145
| +// _getFirstDeviceFromID |
| |
146
| +int g_vid; |
| |
147
| +int g_pid; |
| |
148
| +libusb_device *g_device = NULL; |
| |
149
| +void _getFirstDeviceFromID(libusb_device *device) { |
| |
150
| + struct libusb_device_descriptor desc; |
| |
151
| + |
| |
152
| + int status = libusb_get_device_descriptor(device, &desc); |
| |
153
| + if (status != LIBUSB_SUCCESS) { |
| |
154
| + printf("Cannot get device desc : %s\n", |
| |
155
| + libusb_error_name(status)); // DBGONLY |
| |
156
| + perror("libusb_open"); |
| |
157
| + return; |
| |
158
| + } |
| |
159
| + |
| |
160
| + if (desc.idVendor == g_vid && desc.idProduct == g_pid) { |
| |
161
| + g_device = device; |
| |
162
| + } |
| |
163
| +} |
| |
164
| + |
| |
165
| +void getFirstDeviceFromID(libusb_context *context, int vid, int pid, |
| |
166
| + libusb_device **device) { |
| |
167
| + g_vid = vid; // pass parameters for enumeration |
| |
168
| + g_pid = pid; // idem |
| |
169
| + _enumerateDevices(context, _getFirstDeviceFromID); |
| |
170
| + *device = g_device; // get return from enumeration |
| |
171
| +} |
| |
172
| + |
| |
173
| +// void getDevicesFromID(vid, pid) //return array |
| |
174
| + |
| |
175
| +void displayDeviceEndpoints(libusb_device_handle *handle) { |
| |
176
| + // recover pointer from handle |
| |
177
| + libusb_device *device; |
| |
178
| + device = libusb_get_device(handle); |
| |
179
| + |
| |
180
| + // lectures des configs => on prend la première configuration pour l'instant |
| |
181
| + /*int configuration = 0; // valueof("bConfigurationValue"); |
| |
182
| + int statusConfig = libusb_set_configuration(handle, configuration); |
| |
183
| + if (statusConfig != LIBUSB_SUCCESS) { |
| |
184
| + perror("libusb_set_configuration"); |
| |
185
| + return; |
| |
186
| + }*/ |
| |
187
| + |
| |
188
| + // 4.2 configuration du périph usb |
| |
189
| + struct libusb_config_descriptor *config; |
| |
190
| + int statusFetchConfig = libusb_get_active_config_descriptor(device, &config); |
| |
191
| + if (statusFetchConfig != LIBUSB_SUCCESS) { |
| |
192
| + perror("libusb_get_active_config_descriptor"); |
| |
193
| + return; |
| |
194
| + } |
| |
195
| + |
| |
196
| + // caractéristiques globales |
| |
197
| + printf("Config.bConfigurationValue : %d\n", config->bConfigurationValue); |
| |
198
| + printf("Config/ bLength:%d\nbDescriptorType:%d\nbNumInterfaces:%d\n", |
| |
199
| + config->bLength, config->bDescriptorType, config->bNumInterfaces); |
| |
200
| + |
| |
201
| + // itération des interfaces |
| |
202
| + printf("Itération de l'interface\n"); |
| |
203
| + for (int indexInterface = 0; indexInterface < config->bNumInterfaces; |
| |
204
| + indexInterface++) { |
| |
205
| + printf("-indexInterface=%d\n", indexInterface); |
| |
206
| + printf("-Altsetting=%d\n", |
| |
207
| + config->interface[indexInterface].num_altsetting); |
| |
208
| + |
| |
209
| + const struct libusb_interface *interface = |
| |
210
| + &config->interface[indexInterface]; |
| |
211
| + |
| |
212
| + // if 1 setting (or more) |
| |
213
| + if (interface->num_altsetting != 0) { |
| |
214
| + const struct libusb_interface_descriptor *interface_desc = |
| |
215
| + &interface->altsetting[0]; |
| |
216
| + |
| |
217
| + printf("--bNumEndpoints=%d\n", interface_desc->bNumEndpoints); |
| |
218
| + printf("--bDescriptorType=%d\n", interface_desc->bDescriptorType); |
| |
219
| + |
| |
220
| + for (int indexEndpoints = 0; |
| |
221
| + indexEndpoints < interface_desc->bNumEndpoints; indexEndpoints++) { |
| |
222
| + const struct libusb_endpoint_descriptor *endpoint_desc = |
| |
223
| + &interface_desc->endpoint[indexEndpoints]; |
| |
224
| + printf("---bDescriptorType=%d\n", endpoint_desc->bDescriptorType); |
| |
225
| + printf("---bEndpointAddress=%d\n", endpoint_desc->bEndpointAddress); |
| |
226
| + |
| |
227
| + if (endpoint_desc->extra != NULL) |
| |
228
| + printf("---extra: %s\n", endpoint_desc->extra); |
| |
229
| + if (endpoint_desc->bmAttributes == |
| |
230
| + LIBUSB_TRANSFER_TYPE_INTERRUPT) // TODO AJOUT MASQUE ? (voir doc) |
| |
231
| + printf("---is of type INTERRUPT\n"); |
| |
232
| + } |
| |
233
| + } |
| |
234
| + |
| |
235
| + // Affichez l’indice et le numéro de chaque interface détectée et réclamée. |
| |
236
| + // Affichez aussi les points d’accès trouvés en précisant ceux sauvés. |
| |
237
| + |
| |
238
| + /* |
| |
239
| + //int interface=valueof("bInterfaceNumber"); |
| |
240
| + int |
| |
241
| + status=libusb_claim_interface(handle,interface->bInterfaceNumber); |
| |
242
| + if(status!=0){ perror("libusb_claim_interface"); exit(-1); } |
| |
243
| + |
| |
244
| + status=libusb_release_interface(handle,interface->bInterfaceNumber); |
| |
245
| + if(status!=0){ perror("libusb_release_interface"); exit(-1); } |
| |
246
| + |
| |
247
| + //claim_interface(.., config interface altsetting bInterfaceNumber |
| |
248
| + //config interface altsetting endpoint bmAttributes == |
| |
249
| + LIBUSB_TRANSFER_TYPE_INTERRUPT |
| |
250
| + //add des enpoint unint8_t*/ |
| |
251
| + |
| |
252
| + // DESCRIPTOR.C /.H :décommenter |
| |
253
| + |
| |
254
| + // IL FAUT RELEASE UNIQUEMENT LES INTERFACES QUI NE SONT PAS DES HID |
| |
255
| + } |
| |
256
| + |
| |
257
| + printf("\n"); |
| |
258
| + |
| |
259
| + libusb_close(handle); |
| |
260
| +} |
| |
261
| + |
| |
262
| +void getOurInterfaces(libusb_device *device, |
| |
263
| + struct libusb_interface **int_hidjoy, |
| |
264
| + struct libusb_interface **int_leds, |
| |
265
| + struct libusb_interface **int_vibrators) { |
| |
266
| + struct libusb_config_descriptor *config; |
| |
267
| + int statusFetchConfig = libusb_get_active_config_descriptor(device, &config); |
| |
268
| + if (statusFetchConfig != LIBUSB_SUCCESS) { |
| |
269
| + perror("libusb_get_active_config_descriptor"); |
| |
270
| + return; |
| |
271
| + } |
| |
272
| + |
| |
273
| + // itération des interfaces |
| |
274
| + for (int indexInterface = 0; indexInterface < config->bNumInterfaces; |
| |
275
| + indexInterface++) { |
| |
276
| + |
| |
277
| + const struct libusb_interface *interface = |
| |
278
| + &config->interface[indexInterface]; |
| |
279
| + |
| |
280
| + // todo use le descriptor pour avoir bInterfaceNumber? |
| |
281
| + if (indexInterface == 0) { |
| |
282
| + *int_hidjoy = (struct libusb_interface *)interface; |
| |
283
| + } else if (indexInterface == 1) { |
| |
284
| + *int_leds = (struct libusb_interface *)interface; |
| |
285
| + } else if (indexInterface == 2) { |
| |
286
| + *int_vibrators = (struct libusb_interface *)interface; |
| |
287
| + } |
| |
288
| + |
| |
289
| + //#define pour les indices correspondants aux interfaces |
| |
290
| + // variables globales |
| |
291
| + } |
| |
292
| +} |
| |
293
| + |
| |
294
| +char getOnlyEndpoint(struct libusb_interface *interface) { |
| |
295
| + |
| |
296
| + const struct libusb_interface_descriptor *interface_desc = |
| |
297
| + &interface->altsetting[0]; |
| |
298
| + |
| |
299
| + const struct libusb_endpoint_descriptor *endpoint_desc = |
| |
300
| + &interface_desc->endpoint[0]; |
| |
301
| + |
| |
302
| + if (endpoint_desc->bmAttributes != |
| |
303
| + LIBUSB_TRANSFER_TYPE_INTERRUPT) // ON PEUT VERIFIER LE TRANSFER TYPE |
| |
304
| + printf("> is NOT of type INTERRUPT\n"); |
| |
305
| + |
| |
306
| + return (char)endpoint_desc->bEndpointAddress; |
| |
307
| +} |