Back to home page

LXR

 
 

    


0001 /*
0002  * Hidraw Userspace Example
0003  *
0004  * Copyright (c) 2010 Alan Ott <alan@signal11.us>
0005  * Copyright (c) 2010 Signal 11 Software
0006  *
0007  * The code may be used by anyone for any purpose,
0008  * and can serve as a starting point for developing
0009  * applications using hidraw.
0010  */
0011 
0012 /* Linux */
0013 #include <linux/types.h>
0014 #include <linux/input.h>
0015 #include <linux/hidraw.h>
0016 
0017 /*
0018  * Ugly hack to work around failing compilation on systems that don't
0019  * yet populate new version of hidraw.h to userspace.
0020  */
0021 #ifndef HIDIOCSFEATURE
0022 #warning Please have your distro update the userspace kernel headers
0023 #define HIDIOCSFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
0024 #define HIDIOCGFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
0025 #endif
0026 
0027 /* Unix */
0028 #include <sys/ioctl.h>
0029 #include <sys/types.h>
0030 #include <sys/stat.h>
0031 #include <fcntl.h>
0032 #include <unistd.h>
0033 
0034 /* C */
0035 #include <stdio.h>
0036 #include <string.h>
0037 #include <stdlib.h>
0038 #include <errno.h>
0039 
0040 const char *bus_str(int bus);
0041 
0042 int main(int argc, char **argv)
0043 {
0044     int fd;
0045     int i, res, desc_size = 0;
0046     char buf[256];
0047     struct hidraw_report_descriptor rpt_desc;
0048     struct hidraw_devinfo info;
0049     char *device = "/dev/hidraw0";
0050 
0051     if (argc > 1)
0052         device = argv[1];
0053 
0054     /* Open the Device with non-blocking reads. In real life,
0055        don't use a hard coded path; use libudev instead. */
0056     fd = open(device, O_RDWR|O_NONBLOCK);
0057 
0058     if (fd < 0) {
0059         perror("Unable to open device");
0060         return 1;
0061     }
0062 
0063     memset(&rpt_desc, 0x0, sizeof(rpt_desc));
0064     memset(&info, 0x0, sizeof(info));
0065     memset(buf, 0x0, sizeof(buf));
0066 
0067     /* Get Report Descriptor Size */
0068     res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
0069     if (res < 0)
0070         perror("HIDIOCGRDESCSIZE");
0071     else
0072         printf("Report Descriptor Size: %d\n", desc_size);
0073 
0074     /* Get Report Descriptor */
0075     rpt_desc.size = desc_size;
0076     res = ioctl(fd, HIDIOCGRDESC, &rpt_desc);
0077     if (res < 0) {
0078         perror("HIDIOCGRDESC");
0079     } else {
0080         printf("Report Descriptor:\n");
0081         for (i = 0; i < rpt_desc.size; i++)
0082             printf("%hhx ", rpt_desc.value[i]);
0083         puts("\n");
0084     }
0085 
0086     /* Get Raw Name */
0087     res = ioctl(fd, HIDIOCGRAWNAME(256), buf);
0088     if (res < 0)
0089         perror("HIDIOCGRAWNAME");
0090     else
0091         printf("Raw Name: %s\n", buf);
0092 
0093     /* Get Physical Location */
0094     res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);
0095     if (res < 0)
0096         perror("HIDIOCGRAWPHYS");
0097     else
0098         printf("Raw Phys: %s\n", buf);
0099 
0100     /* Get Raw Info */
0101     res = ioctl(fd, HIDIOCGRAWINFO, &info);
0102     if (res < 0) {
0103         perror("HIDIOCGRAWINFO");
0104     } else {
0105         printf("Raw Info:\n");
0106         printf("\tbustype: %d (%s)\n",
0107             info.bustype, bus_str(info.bustype));
0108         printf("\tvendor: 0x%04hx\n", info.vendor);
0109         printf("\tproduct: 0x%04hx\n", info.product);
0110     }
0111 
0112     /* Set Feature */
0113     buf[0] = 0x9; /* Report Number */
0114     buf[1] = 0xff;
0115     buf[2] = 0xff;
0116     buf[3] = 0xff;
0117     res = ioctl(fd, HIDIOCSFEATURE(4), buf);
0118     if (res < 0)
0119         perror("HIDIOCSFEATURE");
0120     else
0121         printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
0122 
0123     /* Get Feature */
0124     buf[0] = 0x9; /* Report Number */
0125     res = ioctl(fd, HIDIOCGFEATURE(256), buf);
0126     if (res < 0) {
0127         perror("HIDIOCGFEATURE");
0128     } else {
0129         printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
0130         printf("Report data (not containing the report number):\n\t");
0131         for (i = 0; i < res; i++)
0132             printf("%hhx ", buf[i]);
0133         puts("\n");
0134     }
0135 
0136     /* Send a Report to the Device */
0137     buf[0] = 0x1; /* Report Number */
0138     buf[1] = 0x77;
0139     res = write(fd, buf, 2);
0140     if (res < 0) {
0141         printf("Error: %d\n", errno);
0142         perror("write");
0143     } else {
0144         printf("write() wrote %d bytes\n", res);
0145     }
0146 
0147     /* Get a report from the device */
0148     res = read(fd, buf, 16);
0149     if (res < 0) {
0150         perror("read");
0151     } else {
0152         printf("read() read %d bytes:\n\t", res);
0153         for (i = 0; i < res; i++)
0154             printf("%hhx ", buf[i]);
0155         puts("\n");
0156     }
0157     close(fd);
0158     return 0;
0159 }
0160 
0161 const char *
0162 bus_str(int bus)
0163 {
0164     switch (bus) {
0165     case BUS_USB:
0166         return "USB";
0167         break;
0168     case BUS_HIL:
0169         return "HIL";
0170         break;
0171     case BUS_BLUETOOTH:
0172         return "Bluetooth";
0173         break;
0174     case BUS_VIRTUAL:
0175         return "Virtual";
0176         break;
0177     default:
0178         return "Other";
0179         break;
0180     }
0181 }