linux/samples/hidraw/hid-example.c
<<
>>
Prefs
   1/*
   2 * Hidraw Userspace Example
   3 *
   4 * Copyright (c) 2010 Alan Ott <alan@signal11.us>
   5 * Copyright (c) 2010 Signal 11 Software
   6 *
   7 * The code may be used by anyone for any purpose,
   8 * and can serve as a starting point for developing
   9 * applications using hidraw.
  10 */
  11
  12/* Linux */
  13#include <linux/types.h>
  14#include <linux/input.h>
  15#include <linux/hidraw.h>
  16
  17/*
  18 * Ugly hack to work around failing compilation on systems that don't
  19 * yet populate new version of hidraw.h to userspace.
  20 */
  21#ifndef HIDIOCSFEATURE
  22#warning Please have your distro update the userspace kernel headers
  23#define HIDIOCSFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
  24#define HIDIOCGFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
  25#endif
  26
  27/* Unix */
  28#include <sys/ioctl.h>
  29#include <sys/types.h>
  30#include <sys/stat.h>
  31#include <fcntl.h>
  32#include <unistd.h>
  33
  34/* C */
  35#include <stdio.h>
  36#include <string.h>
  37#include <stdlib.h>
  38#include <errno.h>
  39
  40const char *bus_str(int bus);
  41
  42int main(int argc, char **argv)
  43{
  44        int fd;
  45        int i, res, desc_size = 0;
  46        char buf[256];
  47        struct hidraw_report_descriptor rpt_desc;
  48        struct hidraw_devinfo info;
  49        char *device = "/dev/hidraw0";
  50
  51        if (argc > 1)
  52                device = argv[1];
  53
  54        /* Open the Device with non-blocking reads. In real life,
  55           don't use a hard coded path; use libudev instead. */
  56        fd = open(device, O_RDWR|O_NONBLOCK);
  57
  58        if (fd < 0) {
  59                perror("Unable to open device");
  60                return 1;
  61        }
  62
  63        memset(&rpt_desc, 0x0, sizeof(rpt_desc));
  64        memset(&info, 0x0, sizeof(info));
  65        memset(buf, 0x0, sizeof(buf));
  66
  67        /* Get Report Descriptor Size */
  68        res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
  69        if (res < 0)
  70                perror("HIDIOCGRDESCSIZE");
  71        else
  72                printf("Report Descriptor Size: %d\n", desc_size);
  73
  74        /* Get Report Descriptor */
  75        rpt_desc.size = desc_size;
  76        res = ioctl(fd, HIDIOCGRDESC, &rpt_desc);
  77        if (res < 0) {
  78                perror("HIDIOCGRDESC");
  79        } else {
  80                printf("Report Descriptor:\n");
  81                for (i = 0; i < rpt_desc.size; i++)
  82                        printf("%hhx ", rpt_desc.value[i]);
  83                puts("\n");
  84        }
  85
  86        /* Get Raw Name */
  87        res = ioctl(fd, HIDIOCGRAWNAME(256), buf);
  88        if (res < 0)
  89                perror("HIDIOCGRAWNAME");
  90        else
  91                printf("Raw Name: %s\n", buf);
  92
  93        /* Get Physical Location */
  94        res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);
  95        if (res < 0)
  96                perror("HIDIOCGRAWPHYS");
  97        else
  98                printf("Raw Phys: %s\n", buf);
  99
 100        /* Get Raw Info */
 101        res = ioctl(fd, HIDIOCGRAWINFO, &info);
 102        if (res < 0) {
 103                perror("HIDIOCGRAWINFO");
 104        } else {
 105                printf("Raw Info:\n");
 106                printf("\tbustype: %d (%s)\n",
 107                        info.bustype, bus_str(info.bustype));
 108                printf("\tvendor: 0x%04hx\n", info.vendor);
 109                printf("\tproduct: 0x%04hx\n", info.product);
 110        }
 111
 112        /* Set Feature */
 113        buf[0] = 0x9; /* Report Number */
 114        buf[1] = 0xff;
 115        buf[2] = 0xff;
 116        buf[3] = 0xff;
 117        res = ioctl(fd, HIDIOCSFEATURE(4), buf);
 118        if (res < 0)
 119                perror("HIDIOCSFEATURE");
 120        else
 121                printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
 122
 123        /* Get Feature */
 124        buf[0] = 0x9; /* Report Number */
 125        res = ioctl(fd, HIDIOCGFEATURE(256), buf);
 126        if (res < 0) {
 127                perror("HIDIOCGFEATURE");
 128        } else {
 129                printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
 130                printf("Report data (not containing the report number):\n\t");
 131                for (i = 0; i < res; i++)
 132                        printf("%hhx ", buf[i]);
 133                puts("\n");
 134        }
 135
 136        /* Send a Report to the Device */
 137        buf[0] = 0x1; /* Report Number */
 138        buf[1] = 0x77;
 139        res = write(fd, buf, 2);
 140        if (res < 0) {
 141                printf("Error: %d\n", errno);
 142                perror("write");
 143        } else {
 144                printf("write() wrote %d bytes\n", res);
 145        }
 146
 147        /* Get a report from the device */
 148        res = read(fd, buf, 16);
 149        if (res < 0) {
 150                perror("read");
 151        } else {
 152                printf("read() read %d bytes:\n\t", res);
 153                for (i = 0; i < res; i++)
 154                        printf("%hhx ", buf[i]);
 155                puts("\n");
 156        }
 157        close(fd);
 158        return 0;
 159}
 160
 161const char *
 162bus_str(int bus)
 163{
 164        switch (bus) {
 165        case BUS_USB:
 166                return "USB";
 167                break;
 168        case BUS_HIL:
 169                return "HIL";
 170                break;
 171        case BUS_BLUETOOTH:
 172                return "Bluetooth";
 173                break;
 174        case BUS_VIRTUAL:
 175                return "Virtual";
 176                break;
 177        default:
 178                return "Other";
 179                break;
 180        }
 181}
 182