Blame view

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