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