~mixxxdevelopers/mixxx/trunk

« back to all changes in this revision

Viewing changes to mixxx/lib/hidapi-0.7.0/linux/hid.c

Merging features_controllerAbstraction. Migration of mappings from .mixxx/midi/ to controllers/ only works on a version upgrade (end-users.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************
 
2
 HIDAPI - Multi-Platform library for
 
3
 communication with HID devices.
 
4
 
 
5
 Alan Ott
 
6
 Signal 11 Software
 
7
 
 
8
 8/22/2009
 
9
 Linux Version - 6/2/2009
 
10
 
 
11
 Copyright 2009, All Rights Reserved.
 
12
 
 
13
 At the discretion of the user of this library,
 
14
 this software may be licensed under the terms of the
 
15
 GNU Public License v3, a BSD-Style license, or the
 
16
 original HIDAPI license as outlined in the LICENSE.txt,
 
17
 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
 
18
 files located at the root of the source distribution.
 
19
 These files may also be found in the public source
 
20
 code repository located at:
 
21
        http://github.com/signal11/hidapi .
 
22
********************************************************/
 
23
 
 
24
/* C */
 
25
#include <stdio.h>
 
26
#include <string.h>
 
27
#include <stdlib.h>
 
28
#include <locale.h>
 
29
#include <errno.h>
 
30
 
 
31
/* Unix */
 
32
#include <unistd.h>
 
33
#include <sys/types.h>
 
34
#include <sys/stat.h>
 
35
#include <sys/ioctl.h>
 
36
#include <sys/utsname.h>
 
37
#include <fcntl.h>
 
38
#include <poll.h>
 
39
 
 
40
/* Linux */
 
41
#include <linux/hidraw.h>
 
42
#include <linux/version.h>
 
43
#include <libudev.h>
 
44
 
 
45
#include "hidapi.h"
 
46
 
 
47
/* Definitions from linux/hidraw.h. Since these are new, some distros
 
48
   may not have header files which contain them. */
 
49
#ifndef HIDIOCSFEATURE
 
50
#define HIDIOCSFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
 
51
#endif
 
52
#ifndef HIDIOCGFEATURE
 
53
#define HIDIOCGFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
 
54
#endif
 
55
 
 
56
struct hid_device_ {
 
57
        int device_handle;
 
58
        int blocking;
 
59
        int uses_numbered_reports;
 
60
};
 
61
 
 
62
 
 
63
static __u32 kernel_version = 0;
 
64
 
 
65
hid_device *new_hid_device()
 
66
{
 
67
        hid_device *dev = calloc(1, sizeof(hid_device));
 
68
        dev->device_handle = -1;
 
69
        dev->blocking = 1;
 
70
        dev->uses_numbered_reports = 0;
 
71
 
 
72
        return dev;
 
73
}
 
74
 
 
75
static void register_error(hid_device *device, const char *op)
 
76
{
 
77
 
 
78
}
 
79
 
 
80
/* Get an attribute value from a udev_device and return it as a whar_t
 
81
   string. The returned string must be freed with free() when done.*/
 
82
static wchar_t *copy_udev_string(struct udev_device *dev, const char *udev_name)
 
83
{
 
84
        const char *str;
 
85
        wchar_t *ret = NULL;
 
86
        str = udev_device_get_sysattr_value(dev, udev_name);
 
87
        if (str) {
 
88
                /* Convert the string from UTF-8 to wchar_t */
 
89
                size_t wlen = mbstowcs(NULL, str, 0);
 
90
                ret = calloc(wlen+1, sizeof(wchar_t));
 
91
                mbstowcs(ret, str, wlen+1);
 
92
                ret[wlen] = 0x0000;
 
93
        }
 
94
        
 
95
        return ret;
 
96
}
 
97
 
 
98
/* uses_numbered_reports() returns 1 if report_descriptor describes a device
 
99
   which contains numbered reports. */ 
 
100
static int uses_numbered_reports(__u8 *report_descriptor, __u32 size) {
 
101
        int i = 0;
 
102
        int size_code;
 
103
        int data_len, key_size;
 
104
        
 
105
        while (i < size) {
 
106
                int key = report_descriptor[i];
 
107
 
 
108
                /* Check for the Report ID key */
 
109
                if (key == 0x85/*Report ID*/) {
 
110
                        /* This device has a Report ID, which means it uses
 
111
                           numbered reports. */
 
112
                        return 1;
 
113
                }
 
114
                
 
115
                //printf("key: %02hhx\n", key);
 
116
                
 
117
                if ((key & 0xf0) == 0xf0) {
 
118
                        /* This is a Long Item. The next byte contains the
 
119
                           length of the data section (value) for this key.
 
120
                           See the HID specification, version 1.11, section
 
121
                           6.2.2.3, titled "Long Items." */
 
122
                        if (i+1 < size)
 
123
                                data_len = report_descriptor[i+1];
 
124
                        else
 
125
                                data_len = 0; /* malformed report */
 
126
                        key_size = 3;
 
127
                }
 
128
                else {
 
129
                        /* This is a Short Item. The bottom two bits of the
 
130
                           key contain the size code for the data section
 
131
                           (value) for this key.  Refer to the HID
 
132
                           specification, version 1.11, section 6.2.2.2,
 
133
                           titled "Short Items." */
 
134
                        size_code = key & 0x3;
 
135
                        switch (size_code) {
 
136
                        case 0:
 
137
                        case 1:
 
138
                        case 2:
 
139
                                data_len = size_code;
 
140
                                break;
 
141
                        case 3:
 
142
                                data_len = 4;
 
143
                                break;
 
144
                        default:
 
145
                                /* Can't ever happen since size_code is & 0x3 */
 
146
                                data_len = 0;
 
147
                                break;
 
148
                        };
 
149
                        key_size = 1;
 
150
                }
 
151
                
 
152
                /* Skip over this key and it's associated data */
 
153
                i += data_len + key_size;
 
154
        }
 
155
        
 
156
        /* Didn't find a Report ID key. Device doesn't use numbered reports. */
 
157
        return 0;
 
158
}
 
159
 
 
160
static int get_device_string(hid_device *dev, const char *key, wchar_t *string, size_t maxlen)
 
161
{
 
162
        struct udev *udev;
 
163
        struct udev_device *udev_dev, *parent;
 
164
        struct stat s;
 
165
        int ret = -1;
 
166
        
 
167
        setlocale(LC_ALL,"");
 
168
 
 
169
        /* Create the udev object */
 
170
        udev = udev_new();
 
171
        if (!udev) {
 
172
                printf("Can't create udev\n");
 
173
                return -1;
 
174
        }
 
175
 
 
176
        /* Get the dev_t (major/minor numbers) from the file handle. */
 
177
        fstat(dev->device_handle, &s);
 
178
        /* Open a udev device from the dev_t. 'c' means character device. */
 
179
        udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
 
180
        if (udev_dev) {
 
181
                const char *str;
 
182
                /* Find the parent USB Device */
 
183
                parent = udev_device_get_parent_with_subsystem_devtype(
 
184
                       udev_dev,
 
185
                       "usb",
 
186
                       "usb_device");
 
187
                if (parent) {
 
188
                        str = udev_device_get_sysattr_value(parent, key);
 
189
                        if (str) {
 
190
                                /* Convert the string from UTF-8 to wchar_t */
 
191
                                ret = mbstowcs(string, str, maxlen);
 
192
                                goto end;
 
193
                        }
 
194
                }
 
195
        }
 
196
 
 
197
end:
 
198
        udev_device_unref(udev_dev);
 
199
        // parent doesn't need to be (and can't be) unref'd.
 
200
        // I'm not sure why, but it'll throw double-free() errors.
 
201
        udev_unref(udev);
 
202
 
 
203
        return ret;
 
204
}
 
205
 
 
206
int HID_API_EXPORT hid_init(void)
 
207
{
 
208
        /* Nothing to do for this in the Linux/hidraw implementation. */
 
209
        return 0;
 
210
}
 
211
 
 
212
int HID_API_EXPORT hid_exit(void)
 
213
{
 
214
        /* Nothing to do for this in the Linux/hidraw implementation. */
 
215
        return 0;
 
216
}
 
217
 
 
218
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
 
219
{
 
220
        struct udev *udev;
 
221
        struct udev_enumerate *enumerate;
 
222
        struct udev_list_entry *devices, *dev_list_entry;
 
223
        
 
224
        struct hid_device_info *root = NULL; // return object
 
225
        struct hid_device_info *cur_dev = NULL;
 
226
        
 
227
        setlocale(LC_ALL,"");
 
228
 
 
229
        /* Create the udev object */
 
230
        udev = udev_new();
 
231
        if (!udev) {
 
232
                printf("Can't create udev\n");
 
233
                return NULL;
 
234
        }
 
235
 
 
236
        /* Create a list of the devices in the 'hidraw' subsystem. */
 
237
        enumerate = udev_enumerate_new(udev);
 
238
        udev_enumerate_add_match_subsystem(enumerate, "hidraw");
 
239
        udev_enumerate_scan_devices(enumerate);
 
240
        devices = udev_enumerate_get_list_entry(enumerate);
 
241
        /* For each item, see if it matches the vid/pid, and if so
 
242
           create a udev_device record for it */
 
243
        udev_list_entry_foreach(dev_list_entry, devices) {
 
244
                const char *sysfs_path;
 
245
                const char *dev_path;
 
246
                const char *str;
 
247
                struct udev_device *hid_dev; // The device's HID udev node.
 
248
                struct udev_device *dev; // The actual hardware device.
 
249
                struct udev_device *intf_dev; // The device's interface (in the USB sense).
 
250
                unsigned short dev_vid;
 
251
                unsigned short dev_pid;
 
252
                
 
253
                /* Get the filename of the /sys entry for the device
 
254
                   and create a udev_device object (dev) representing it */
 
255
                sysfs_path = udev_list_entry_get_name(dev_list_entry);
 
256
                hid_dev = udev_device_new_from_syspath(udev, sysfs_path);
 
257
                dev_path = udev_device_get_devnode(hid_dev);
 
258
                
 
259
                /* The device pointed to by hid_dev contains information about
 
260
                   the hidraw device. In order to get information about the
 
261
                   USB device, get the parent device with the
 
262
                   subsystem/devtype pair of "usb"/"usb_device". This will
 
263
                   be several levels up the tree, but the function will find
 
264
                   it.*/
 
265
                dev = udev_device_get_parent_with_subsystem_devtype(
 
266
                       hid_dev,
 
267
                       "usb",
 
268
                       "usb_device");
 
269
                if (!dev) {
 
270
                        /* Unable to find parent usb device. */
 
271
                        goto next;
 
272
                }
 
273
 
 
274
                /* Get the VID/PID of the device */
 
275
                str = udev_device_get_sysattr_value(dev,"idVendor");
 
276
                dev_vid = (str)? strtol(str, NULL, 16): 0x0;
 
277
                str = udev_device_get_sysattr_value(dev, "idProduct");
 
278
                dev_pid = (str)? strtol(str, NULL, 16): 0x0;
 
279
 
 
280
                /* Check the VID/PID against the arguments */
 
281
                if ((vendor_id == 0x0 && product_id == 0x0) ||
 
282
                    (vendor_id == dev_vid && product_id == dev_pid)) {
 
283
                        struct hid_device_info *tmp;
 
284
                        size_t len;
 
285
 
 
286
                        /* VID/PID match. Create the record. */
 
287
                        tmp = malloc(sizeof(struct hid_device_info));
 
288
                        if (cur_dev) {
 
289
                                cur_dev->next = tmp;
 
290
                        }
 
291
                        else {
 
292
                                root = tmp;
 
293
                        }
 
294
                        cur_dev = tmp;
 
295
                        
 
296
                        /* Fill out the record */
 
297
                        cur_dev->next = NULL;
 
298
                        str = dev_path;
 
299
                        if (str) {
 
300
                                len = strlen(str);
 
301
                                cur_dev->path = calloc(len+1, sizeof(char));
 
302
                                strncpy(cur_dev->path, str, len+1);
 
303
                                cur_dev->path[len] = '\0';
 
304
                        }
 
305
                        else
 
306
                                cur_dev->path = NULL;
 
307
                        
 
308
                        /* Serial Number */
 
309
                        cur_dev->serial_number
 
310
                                = copy_udev_string(dev, "serial");
 
311
 
 
312
                        /* Manufacturer and Product strings */
 
313
                        cur_dev->manufacturer_string
 
314
                                = copy_udev_string(dev, "manufacturer");
 
315
                        cur_dev->product_string
 
316
                                = copy_udev_string(dev, "product");
 
317
                        
 
318
                        /* VID/PID */
 
319
                        cur_dev->vendor_id = dev_vid;
 
320
                        cur_dev->product_id = dev_pid;
 
321
 
 
322
                        /* Release Number */
 
323
                        str = udev_device_get_sysattr_value(dev, "bcdDevice");
 
324
                        cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0;
 
325
                        
 
326
                        /* Interface Number */
 
327
                        cur_dev->interface_number = -1;
 
328
                        /* Get a handle to the interface's udev node. */
 
329
                        intf_dev = udev_device_get_parent_with_subsystem_devtype(
 
330
                                   hid_dev,
 
331
                                   "usb",
 
332
                                   "usb_interface");
 
333
                        if (intf_dev) {
 
334
                                str = udev_device_get_sysattr_value(intf_dev, "bInterfaceNumber");
 
335
                                cur_dev->interface_number = (str)? strtol(str, NULL, 16): -1;
 
336
                        }
 
337
                }
 
338
                else
 
339
                        goto next;
 
340
 
 
341
        next:
 
342
                udev_device_unref(hid_dev);
 
343
                /* dev and intf_dev don't need to be (and can't be)
 
344
                   unref()d.  It will cause a double-free() error.  I'm not
 
345
                   sure why.  */
 
346
        }
 
347
        /* Free the enumerator and udev objects. */
 
348
        udev_enumerate_unref(enumerate);
 
349
        udev_unref(udev);
 
350
        
 
351
        return root;
 
352
}
 
353
 
 
354
void  HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
 
355
{
 
356
        struct hid_device_info *d = devs;
 
357
        while (d) {
 
358
                struct hid_device_info *next = d->next;
 
359
                free(d->path);
 
360
                free(d->serial_number);
 
361
                free(d->manufacturer_string);
 
362
                free(d->product_string);
 
363
                free(d);
 
364
                d = next;
 
365
        }
 
366
}
 
367
 
 
368
hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number)
 
369
{
 
370
        struct hid_device_info *devs, *cur_dev;
 
371
        const char *path_to_open = NULL;
 
372
        hid_device *handle = NULL;
 
373
        
 
374
        devs = hid_enumerate(vendor_id, product_id);
 
375
        cur_dev = devs;
 
376
        while (cur_dev) {
 
377
                if (cur_dev->vendor_id == vendor_id &&
 
378
                    cur_dev->product_id == product_id) {
 
379
                        if (serial_number) {
 
380
                                if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
 
381
                                        path_to_open = cur_dev->path;
 
382
                                        break;
 
383
                                }
 
384
                        }
 
385
                        else {
 
386
                                path_to_open = cur_dev->path;
 
387
                                break;
 
388
                        }
 
389
                }
 
390
                cur_dev = cur_dev->next;
 
391
        }
 
392
 
 
393
        if (path_to_open) {
 
394
                /* Open the device */
 
395
                handle = hid_open_path(path_to_open);
 
396
        }
 
397
 
 
398
        hid_free_enumeration(devs);
 
399
        
 
400
        return handle;
 
401
}
 
402
 
 
403
hid_device * HID_API_EXPORT hid_open_path(const char *path)
 
404
{
 
405
        hid_device *dev = NULL;
 
406
 
 
407
        dev = new_hid_device();
 
408
 
 
409
        if (kernel_version == 0) {
 
410
                struct utsname name;
 
411
                int major, minor, release;
 
412
                int ret;
 
413
                uname(&name);
 
414
                ret = sscanf(name.release, "%d.%d.%d", &major, &minor, &release);
 
415
                if (ret == 3) {
 
416
                        kernel_version = major << 16 | minor << 8 | release;
 
417
                        //printf("Kernel Version: %d\n", kernel_version);
 
418
                }
 
419
                else {
 
420
                        printf("Couldn't sscanf() version string %s\n", name.release);
 
421
                }
 
422
        }
 
423
 
 
424
        // OPEN HERE //
 
425
        dev->device_handle = open(path, O_RDWR);
 
426
 
 
427
        // If we have a good handle, return it.
 
428
        if (dev->device_handle > 0) {
 
429
 
 
430
                /* Get the report descriptor */
 
431
                int res, desc_size = 0;
 
432
                struct hidraw_report_descriptor rpt_desc;
 
433
 
 
434
                memset(&rpt_desc, 0x0, sizeof(rpt_desc));
 
435
 
 
436
                /* Get Report Descriptor Size */
 
437
                res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
 
438
                if (res < 0)
 
439
                        perror("HIDIOCGRDESCSIZE");
 
440
 
 
441
 
 
442
                /* Get Report Descriptor */
 
443
                rpt_desc.size = desc_size;
 
444
                res = ioctl(dev->device_handle, HIDIOCGRDESC, &rpt_desc);
 
445
                if (res < 0) {
 
446
                        perror("HIDIOCGRDESC");
 
447
                } else {
 
448
                        /* Determine if this device uses numbered reports. */
 
449
                        dev->uses_numbered_reports =
 
450
                                uses_numbered_reports(rpt_desc.value,
 
451
                                                      rpt_desc.size);
 
452
                }
 
453
                
 
454
                return dev;
 
455
        }
 
456
        else {
 
457
                // Unable to open any devices.
 
458
                free(dev);
 
459
                return NULL;
 
460
        }
 
461
}
 
462
 
 
463
 
 
464
int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
 
465
{
 
466
        int bytes_written;
 
467
 
 
468
        bytes_written = write(dev->device_handle, data, length);
 
469
 
 
470
        return bytes_written;
 
471
}
 
472
 
 
473
 
 
474
int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
 
475
{
 
476
        int bytes_read;
 
477
 
 
478
        if (milliseconds != 0) {
 
479
                /* milliseconds is -1 or > 0. In both cases, we want to
 
480
                   call poll() and wait for data to arrive. -1 means
 
481
                   INFINITE. */
 
482
                int ret;
 
483
                struct pollfd fds;
 
484
 
 
485
                fds.fd = dev->device_handle;
 
486
                fds.events = POLLIN;
 
487
                fds.revents = 0;
 
488
                ret = poll(&fds, 1, milliseconds);
 
489
                if (ret == -1 || ret == 0)
 
490
                        /* Error or timeout */
 
491
                        return ret;
 
492
        }
 
493
 
 
494
        bytes_read = read(dev->device_handle, data, length);
 
495
        if (bytes_read < 0 && errno == EAGAIN)
 
496
                bytes_read = 0;
 
497
        
 
498
        if (bytes_read >= 0 &&
 
499
            kernel_version < KERNEL_VERSION(2,6,34) &&
 
500
            dev->uses_numbered_reports) {
 
501
                /* Work around a kernel bug. Chop off the first byte. */
 
502
                memmove(data, data+1, bytes_read);
 
503
                bytes_read--;
 
504
        }
 
505
 
 
506
        return bytes_read;
 
507
}
 
508
 
 
509
int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
 
510
{
 
511
        return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
 
512
}
 
513
 
 
514
int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
 
515
{
 
516
        int flags, res;
 
517
 
 
518
        flags = fcntl(dev->device_handle, F_GETFL, 0);
 
519
        if (flags >= 0) {
 
520
                if (nonblock)
 
521
                        res = fcntl(dev->device_handle, F_SETFL, flags | O_NONBLOCK);
 
522
                else
 
523
                        res = fcntl(dev->device_handle, F_SETFL, flags & ~O_NONBLOCK);
 
524
        }
 
525
        else
 
526
                return -1;
 
527
 
 
528
        if (res < 0) {
 
529
                return -1;
 
530
        }
 
531
        else {
 
532
                dev->blocking = !nonblock;
 
533
                return 0; /* Success */
 
534
        }
 
535
}
 
536
 
 
537
 
 
538
int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
 
539
{
 
540
        int res;
 
541
 
 
542
        res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data);
 
543
        if (res < 0)
 
544
                perror("ioctl (SFEATURE)");
 
545
 
 
546
        return res;
 
547
}
 
548
 
 
549
int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
 
550
{
 
551
        int res;
 
552
 
 
553
        res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
 
554
        if (res < 0)
 
555
                perror("ioctl (GFEATURE)");
 
556
 
 
557
 
 
558
        return res;
 
559
}
 
560
 
 
561
 
 
562
void HID_API_EXPORT hid_close(hid_device *dev)
 
563
{
 
564
        if (!dev)
 
565
                return;
 
566
        close(dev->device_handle);
 
567
        free(dev);
 
568
}
 
569
 
 
570
 
 
571
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
 
572
{
 
573
        return get_device_string(dev, "manufacturer", string, maxlen);
 
574
}
 
575
 
 
576
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
 
577
{
 
578
        return get_device_string(dev, "product", string, maxlen);
 
579
}
 
580
 
 
581
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
 
582
{
 
583
        return get_device_string(dev, "serial", string, maxlen);
 
584
}
 
585
 
 
586
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
 
587
{
 
588
        return -1;
 
589
}
 
590
 
 
591
 
 
592
HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
 
593
{
 
594
        return NULL;
 
595
}