Blame view

src/libusb_wrapper.c 9.8 KB
d6e16d2e   achemin1   Tout propre
1
  #include "libusb_wrapper.h"
b79c0c43   gperson   ajout de code,Ver...
2
  
b24d2980   achemin1   Nettoyage du code...
3
  
72cd0d89   achemin1   (Ré)Ajout 4.1 bonus
4
  
d6e16d2e   achemin1   Tout propre
5
6
7
8
9
10
11
  void usbinit(libusb_context **context_ptr) {
      //libusb_context *context;
      int statusInit = libusb_init(context_ptr);
      if (statusInit != LIBUSB_SUCCESS) {
          perror("libusb_init");
          exit(-1);
      }
b24d2980   achemin1   Nettoyage du code...
12
13
  }
  
d6e16d2e   achemin1   Tout propre
14
15
  void usbclose(libusb_context *context) {
      libusb_exit(context);
b24d2980   achemin1   Nettoyage du code...
16
17
  }
  
9424ae9a   achemin1   ajouts claim inte...
18
19
  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
47ec0d5e   achemin1   récupération des ...
20
  
0cd64dcd   gperson   communication ave...
21
22
      if(interface_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC){//ON PEUT VERIFIER LA CLASS
          printf("> vendor specific class\n");
47ec0d5e   achemin1   récupération des ...
23
  
0cd64dcd   gperson   communication ave...
24
25
26
      	int status=libusb_claim_interface(handle, interface_desc->bInterfaceNumber);
      	if(status!=0){ perror("libusb_claim_interface"); exit(-1); }
  	}
9424ae9a   achemin1   ajouts claim inte...
27
28
29
30
31
32
33
34
  }
  
  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); }
  }
  
d6e16d2e   achemin1   Tout propre
35
  // Si le méchant noyau est passé avant vous :
7d6f5a45   achemin1   add begin of main...
36
  void getFromKernel(libusb_device_handle *handle, int interface) { //private method for now
d6e16d2e   achemin1   Tout propre
37
38
39
40
41
42
43
      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);
          }
      }
b24d2980   achemin1   Nettoyage du code...
44
45
  }
  
d6e16d2e   achemin1   Tout propre
46
47
48
49
50
51
52
53
54
  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;
  }
  
6bd47a15   achemin1   Ajout du principe...
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  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
  }
  
d6e16d2e   achemin1   Tout propre
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
  //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);
b24d2980   achemin1   Nettoyage du code...
96
97
  }
  
533260c1   achemin1   Ajout des lecture...
98
  
6bd47a15   achemin1   Ajout du principe...
99
100
  void _displayOneDevice(libusb_device *device){
      struct libusb_device_descriptor desc;
533260c1   achemin1   Ajout des lecture...
101
  
6bd47a15   achemin1   Ajout du principe...
102
103
104
105
106
107
      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;
      }
533260c1   achemin1   Ajout des lecture...
108
  
6bd47a15   achemin1   Ajout du principe...
109
110
      uint8_t bus = libusb_get_bus_number(device);
      uint8_t address = libusb_get_device_address(device);
533260c1   achemin1   Ajout des lecture...
111
  
6bd47a15   achemin1   Ajout du principe...
112
113
114
      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);
533260c1   achemin1   Ajout des lecture...
115
  
6bd47a15   achemin1   Ajout du principe...
116
117
      //displayDeviceEndpoints(device); //Not really work on Axel@Alptop
  }
533260c1   achemin1   Ajout des lecture...
118
  
6bd47a15   achemin1   Ajout du principe...
119
120
121
  void displayDevices(libusb_context *context) {
      _enumerateDevices(context, _displayOneDevice);
  }
d6e16d2e   achemin1   Tout propre
122
  
72cd0d89   achemin1   (Ré)Ajout 4.1 bonus
123
124
125
126
127
128
129
130
131
  void _displayOneDeviceMore(libusb_device *device){
      _displayOneDevice(device);
      _printConfig(device);
  }
  
  void displayDevicesMore(libusb_context *context) {
      _enumerateDevices(context, _displayOneDeviceMore);
  }
  
7d6f5a45   achemin1   add begin of main...
132
133
134
135
136
137
138
  //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;
72cd0d89   achemin1   (Ré)Ajout 4.1 bonus
139
  
7d6f5a45   achemin1   add begin of main...
140
141
142
143
144
145
      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;
      }
d6e16d2e   achemin1   Tout propre
146
  
d6e16d2e   achemin1   Tout propre
147
  
7d6f5a45   achemin1   add begin of main...
148
149
150
151
152
153
154
155
156
      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);
6fbb050a   achemin1   correction, modif...
157
      *device = g_device; //get return from enumeration
7d6f5a45   achemin1   add begin of main...
158
159
160
  }
  
  //void getDevicesFromID(vid, pid) //return array
d6e16d2e   achemin1   Tout propre
161
  
533260c1   achemin1   Ajout des lecture...
162
  
6bd47a15   achemin1   Ajout du principe...
163
164
165
166
  void displayDeviceEndpoints(libusb_device_handle* handle) {
      //recover pointer from handle
      libusb_device *device;
      device = libusb_get_device(handle);
c8f6b178   achemin1   Affichage valeur ...
167
  
3d1c6506   achemin1   Affichage de l'ex...
168
  
7d6f5a45   achemin1   add begin of main...
169
170
      // lectures des configs => on prend la première configuration pour l'instant
      /*int configuration = 0; // valueof("bConfigurationValue");
3d1c6506   achemin1   Affichage de l'ex...
171
      int statusConfig = libusb_set_configuration(handle, configuration);
d6e16d2e   achemin1   Tout propre
172
173
174
      if (statusConfig != LIBUSB_SUCCESS) {
          perror("libusb_set_configuration");
          return;
7d6f5a45   achemin1   add begin of main...
175
      }*/
d6e16d2e   achemin1   Tout propre
176
  
3d1c6506   achemin1   Affichage de l'ex...
177
178
      // 4.2 configuration du périph usb
      struct libusb_config_descriptor *config;
d6e16d2e   achemin1   Tout propre
179
180
181
182
      int statusFetchConfig = libusb_get_active_config_descriptor(device, &config);
      if (statusFetchConfig != LIBUSB_SUCCESS) {
          perror("libusb_get_active_config_descriptor");
          return;
c8f6b178   achemin1   Affichage valeur ...
183
      }
7d6f5a45   achemin1   add begin of main...
184
185
  
      //caractéristiques globales
c8f6b178   achemin1   Affichage valeur ...
186
      printf("Config.bConfigurationValue : %d\n", config->bConfigurationValue);
7d6f5a45   achemin1   add begin of main...
187
      printf("Config/ bLength:%d\nbDescriptorType:%d\nbNumInterfaces:%d\n",
3d1c6506   achemin1   Affichage de l'ex...
188
189
             config->bLength, config->bDescriptorType, config->bNumInterfaces);
  
3d1c6506   achemin1   Affichage de l'ex...
190
  
7d6f5a45   achemin1   add begin of main...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
      //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");
7d6f5a45   achemin1   add begin of main...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
              }
          }
  
  
  
          //Affichez lindice et le numéro de chaque interface détectée et réclamée. Affichez aussi les points daccè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
3d1c6506   achemin1   Affichage de l'ex...
240
241
242
      }
  
      printf("\n");
b79c0c43   gperson   ajout de code,Ver...
243
  
d6e16d2e   achemin1   Tout propre
244
      libusb_close(handle);
b79c0c43   gperson   ajout de code,Ver...
245
  
f8fc88aa   gperson   avancement juste ...
246
  }
9424ae9a   achemin1   ajouts claim inte...
247
248
249
250
251
252
  
  void getOurInterfaces(libusb_device *device,
                        struct libusb_interface **int_hidjoy,
                        struct libusb_interface **int_leds,
                        struct libusb_interface **int_vibrators
  ) {
9424ae9a   achemin1   ajouts claim inte...
253
254
255
256
257
258
      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;
      }
f492428d   achemin1   meilleurs printf
259
  
9424ae9a   achemin1   ajouts claim inte...
260
      //itération des interfaces
9424ae9a   achemin1   ajouts claim inte...
261
      for (int indexInterface = 0; indexInterface < config->bNumInterfaces; indexInterface++) {
9424ae9a   achemin1   ajouts claim inte...
262
  
5c076d06   achemin1   rm le warning de ...
263
          const struct libusb_interface * interface = &config->interface[indexInterface];
9424ae9a   achemin1   ajouts claim inte...
264
265
266
  
          //todo use le descriptor pour avoir bInterfaceNumber?
          if(indexInterface==0){
5c076d06   achemin1   rm le warning de ...
267
              *int_hidjoy = (struct libusb_interface *)interface;
9424ae9a   achemin1   ajouts claim inte...
268
          }else if(indexInterface==1){
5c076d06   achemin1   rm le warning de ...
269
              *int_leds = (struct libusb_interface *)interface;
9424ae9a   achemin1   ajouts claim inte...
270
          }else if(indexInterface==2){
5c076d06   achemin1   rm le warning de ...
271
              *int_vibrators = (struct libusb_interface *)interface;
9424ae9a   achemin1   ajouts claim inte...
272
273
274
275
276
277
          }
  
          //#define pour les indices correspondants aux interfaces
          //variables globales
      }
  
47ec0d5e   achemin1   récupération des ...
278
279
280
281
282
283
  }
  
  char getOnlyEndpoint(struct libusb_interface * interface){
  
      const struct libusb_interface_descriptor * interface_desc = &interface->altsetting[0];
  
47ec0d5e   achemin1   récupération des ...
284
285
286
287
288
289
      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;
0cd64dcd   gperson   communication ave...
290
  }