Blame view

src/libusb_wrapper.c 9.71 KB
d6e16d2e   achemin1   Tout propre
1
  #include "libusb_wrapper.h"
b79c0c43   gperson   ajout de code,Ver...
2
  
d6e16d2e   achemin1   Tout propre
3
  void usbinit(libusb_context **context_ptr) {
dd886d58   achemin1   refactor du code ...
4
5
6
7
8
9
    // libusb_context *context;
    int statusInit = libusb_init(context_ptr);
    if (statusInit != LIBUSB_SUCCESS) {
      perror("libusb_init");
      exit(-1);
    }
b24d2980   achemin1   Nettoyage du code...
10
11
  }
  
dd886d58   achemin1   refactor du code ...
12
  void usbclose(libusb_context *context) { libusb_exit(context); }
b24d2980   achemin1   Nettoyage du code...
13
  
dd886d58   achemin1   refactor du code ...
14
15
16
17
  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 ...
18
  
dd886d58   achemin1   refactor du code ...
19
20
21
    if (interface_desc->bInterfaceClass ==
        LIBUSB_CLASS_VENDOR_SPEC) { // ON PEUT VERIFIER LA CLASS
      printf("> vendor specific class\n");
47ec0d5e   achemin1   récupération des ...
22
  
dd886d58   achemin1   refactor du code ...
23
24
25
26
27
28
29
      int status =
          libusb_claim_interface(handle, interface_desc->bInterfaceNumber);
      if (status != 0) {
        perror("libusb_claim_interface");
        exit(-1);
      }
    }
9424ae9a   achemin1   ajouts claim inte...
30
31
  }
  
dd886d58   achemin1   refactor du code ...
32
33
34
35
36
37
38
39
40
41
  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);
    }
9424ae9a   achemin1   ajouts claim inte...
42
43
  }
  
d6e16d2e   achemin1   Tout propre
44
  // Si le méchant noyau est passé avant vous :
dd886d58   achemin1   refactor du code ...
45
46
47
48
49
50
51
  void getFromKernel(libusb_device_handle *handle,
                     int interface) { // private method for now
    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);
d6e16d2e   achemin1   Tout propre
52
      }
dd886d58   achemin1   refactor du code ...
53
    }
b24d2980   achemin1   Nettoyage du code...
54
55
  }
  
d6e16d2e   achemin1   Tout propre
56
  ssize_t getListDevices(libusb_context *context, libusb_device ***list_ptr) {
dd886d58   achemin1   refactor du code ...
57
58
59
60
61
62
    ssize_t count = libusb_get_device_list(context, list_ptr);
    if (count < 0) {
      perror("libusb_get_device_list");
      exit(-1);
    }
    return count;
d6e16d2e   achemin1   Tout propre
63
64
  }
  
dd886d58   achemin1   refactor du code ...
65
66
67
68
  void *_enumerateDevices(libusb_context *context,
                          void (*func)(libusb_device *device)) {
    libusb_device **list;
    ssize_t count = getListDevices(context, &list);
6bd47a15   achemin1   Ajout du principe...
69
  
dd886d58   achemin1   refactor du code ...
70
71
72
    ssize_t i = 0;
    for (i = 0; i < count; i++) {
      libusb_device *device = list[i];
6bd47a15   achemin1   Ajout du principe...
73
  
dd886d58   achemin1   refactor du code ...
74
75
      func(device);
    }
6bd47a15   achemin1   Ajout du principe...
76
  
dd886d58   achemin1   refactor du code ...
77
    libusb_free_device_list(list, 1);
6bd47a15   achemin1   Ajout du principe...
78
  
dd886d58   achemin1   refactor du code ...
79
    return NULL; // DBGONLY TEMP
6bd47a15   achemin1   Ajout du principe...
80
81
  }
  
dd886d58   achemin1   refactor du code ...
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
  // 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...
107
108
  }
  
dd886d58   achemin1   refactor du code ...
109
110
  void _displayOneDevice(libusb_device *device) {
    struct libusb_device_descriptor desc;
533260c1   achemin1   Ajout des lecture...
111
  
dd886d58   achemin1   refactor du code ...
112
113
114
115
116
117
118
    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...
119
  
dd886d58   achemin1   refactor du code ...
120
121
    uint8_t bus = libusb_get_bus_number(device);
    uint8_t address = libusb_get_device_address(device);
533260c1   achemin1   Ajout des lecture...
122
  
dd886d58   achemin1   refactor du code ...
123
124
125
    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...
126
  
dd886d58   achemin1   refactor du code ...
127
    // displayDeviceEndpoints(device); //Not really work on Axel@Alptop
6bd47a15   achemin1   Ajout du principe...
128
  }
533260c1   achemin1   Ajout des lecture...
129
  
6bd47a15   achemin1   Ajout du principe...
130
  void displayDevices(libusb_context *context) {
dd886d58   achemin1   refactor du code ...
131
    _enumerateDevices(context, _displayOneDevice);
6bd47a15   achemin1   Ajout du principe...
132
  }
d6e16d2e   achemin1   Tout propre
133
  
dd886d58   achemin1   refactor du code ...
134
135
136
  void _displayOneDeviceMore(libusb_device *device) {
    _displayOneDevice(device);
    _printConfig(device);
72cd0d89   achemin1   (Ré)Ajout 4.1 bonus
137
138
139
  }
  
  void displayDevicesMore(libusb_context *context) {
dd886d58   achemin1   refactor du code ...
140
    _enumerateDevices(context, _displayOneDeviceMore);
72cd0d89   achemin1   (Ré)Ajout 4.1 bonus
141
142
  }
  
dd886d58   achemin1   refactor du code ...
143
144
145
  // get device from iteration (and not from not recommanded function :
  // ugly using global vars ?? Cannot communicate between getFirstDeviceFromID and
  // _getFirstDeviceFromID
7d6f5a45   achemin1   add begin of main...
146
147
148
149
  int g_vid;
  int g_pid;
  libusb_device *g_device = NULL;
  void _getFirstDeviceFromID(libusb_device *device) {
dd886d58   achemin1   refactor du code ...
150
151
152
153
154
155
156
157
158
159
160
161
162
    struct libusb_device_descriptor desc;
  
    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;
    }
  
    if (desc.idVendor == g_vid && desc.idProduct == g_pid) {
      g_device = device;
    }
7d6f5a45   achemin1   add begin of main...
163
164
  }
  
dd886d58   achemin1   refactor du code ...
165
166
167
168
169
170
  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);
    *device = g_device; // get return from enumeration
7d6f5a45   achemin1   add begin of main...
171
172
  }
  
dd886d58   achemin1   refactor du code ...
173
174
175
176
177
178
179
180
181
182
183
184
185
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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  // void getDevicesFromID(vid, pid) //return array
  
  void displayDeviceEndpoints(libusb_device_handle *handle) {
    // recover pointer from handle
    libusb_device *device;
    device = libusb_get_device(handle);
  
    // lectures des configs => on prend la première configuration pour l'instant
    /*int configuration = 0; // valueof("bConfigurationValue");
    int statusConfig = libusb_set_configuration(handle, configuration);
    if (statusConfig != LIBUSB_SUCCESS) {
        perror("libusb_set_configuration");
        return;
    }*/
  
    // 4.2 configuration du périph usb
    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;
    }
  
    // caractéristiques globales
    printf("Config.bConfigurationValue : %d\n", config->bConfigurationValue);
    printf("Config/ bLength:%d\nbDescriptorType:%d\nbNumInterfaces:%d\n",
           config->bLength, config->bDescriptorType, config->bNumInterfaces);
  
    // 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");
        }
c8f6b178   achemin1   Affichage valeur ...
233
      }
7d6f5a45   achemin1   add begin of main...
234
  
dd886d58   achemin1   refactor du code ...
235
236
      // 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.
7d6f5a45   achemin1   add begin of main...
237
  
dd886d58   achemin1   refactor du code ...
238
239
240
241
242
      /*
              //int interface=valueof("bInterfaceNumber");
              int
         status=libusb_claim_interface(handle,interface->bInterfaceNumber);
              if(status!=0){ perror("libusb_claim_interface"); exit(-1); }
7d6f5a45   achemin1   add begin of main...
243
  
dd886d58   achemin1   refactor du code ...
244
245
              status=libusb_release_interface(handle,interface->bInterfaceNumber);
              if(status!=0){ perror("libusb_release_interface"); exit(-1); }
7d6f5a45   achemin1   add begin of main...
246
  
dd886d58   achemin1   refactor du code ...
247
248
249
250
              //claim_interface(.., config interface altsetting bInterfaceNumber
              //config interface altsetting endpoint bmAttributes ==
         LIBUSB_TRANSFER_TYPE_INTERRUPT
              //add des enpoint unint8_t*/
7d6f5a45   achemin1   add begin of main...
251
  
dd886d58   achemin1   refactor du code ...
252
      // DESCRIPTOR.C /.H :décommenter
7d6f5a45   achemin1   add begin of main...
253
  
dd886d58   achemin1   refactor du code ...
254
255
      // IL FAUT RELEASE UNIQUEMENT LES INTERFACES QUI NE SONT PAS DES HID
    }
7d6f5a45   achemin1   add begin of main...
256
  
dd886d58   achemin1   refactor du code ...
257
    printf("\n");
b79c0c43   gperson   ajout de code,Ver...
258
  
dd886d58   achemin1   refactor du code ...
259
    libusb_close(handle);
f8fc88aa   gperson   avancement juste ...
260
  }
9424ae9a   achemin1   ajouts claim inte...
261
262
263
264
  
  void getOurInterfaces(libusb_device *device,
                        struct libusb_interface **int_hidjoy,
                        struct libusb_interface **int_leds,
dd886d58   achemin1   refactor du code ...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
                        struct libusb_interface **int_vibrators) {
    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;
    }
  
    // itération des interfaces
    for (int indexInterface = 0; indexInterface < config->bNumInterfaces;
         indexInterface++) {
  
      const struct libusb_interface *interface =
          &config->interface[indexInterface];
  
      // todo use le descriptor pour avoir bInterfaceNumber?
      if (indexInterface == 0) {
        *int_hidjoy = (struct libusb_interface *)interface;
      } else if (indexInterface == 1) {
        *int_leds = (struct libusb_interface *)interface;
      } else if (indexInterface == 2) {
        *int_vibrators = (struct libusb_interface *)interface;
9424ae9a   achemin1   ajouts claim inte...
287
288
      }
  
dd886d58   achemin1   refactor du code ...
289
290
291
      //#define pour les indices correspondants aux interfaces
      // variables globales
    }
47ec0d5e   achemin1   récupération des ...
292
293
  }
  
dd886d58   achemin1   refactor du code ...
294
  char getOnlyEndpoint(struct libusb_interface *interface) {
47ec0d5e   achemin1   récupération des ...
295
  
dd886d58   achemin1   refactor du code ...
296
297
    const struct libusb_interface_descriptor *interface_desc =
        &interface->altsetting[0];
47ec0d5e   achemin1   récupération des ...
298
  
dd886d58   achemin1   refactor du code ...
299
300
    const struct libusb_endpoint_descriptor *endpoint_desc =
        &interface_desc->endpoint[0];
47ec0d5e   achemin1   récupération des ...
301
  
dd886d58   achemin1   refactor du code ...
302
303
304
    if (endpoint_desc->bmAttributes !=
        LIBUSB_TRANSFER_TYPE_INTERRUPT) // ON PEUT VERIFIER LE TRANSFER TYPE
      printf("> is NOT of type INTERRUPT\n");
47ec0d5e   achemin1   récupération des ...
305
  
dd886d58   achemin1   refactor du code ...
306
    return (char)endpoint_desc->bEndpointAddress;
0cd64dcd   gperson   communication ave...
307
  }