Blame view

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