blob: 40e3d62005823d78ea5132d8fa81c9bf07621894 [file] [log] [blame]
Alan Ottc54ea492011-03-19 20:29:44 -04001/*
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/* Unix */
18#include <sys/ioctl.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <fcntl.h>
22#include <unistd.h>
23
24/* C */
25#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
28#include <errno.h>
29
30const char *bus_str(int bus);
31
32int main(int argc, char **argv)
33{
34 int fd;
35 int i, res, desc_size = 0;
36 char buf[256];
37 struct hidraw_report_descriptor rpt_desc;
38 struct hidraw_devinfo info;
39
40 /* Open the Device with non-blocking reads. In real life,
41 don't use a hard coded path; use libudev instead. */
42 fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK);
43
44 if (fd < 0) {
45 perror("Unable to open device");
46 return 1;
47 }
48
49 memset(&rpt_desc, 0x0, sizeof(rpt_desc));
50 memset(&info, 0x0, sizeof(info));
51 memset(buf, 0x0, sizeof(buf));
52
53 /* Get Report Descriptor Size */
54 res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
55 if (res < 0)
56 perror("HIDIOCGRDESCSIZE");
57 else
58 printf("Report Descriptor Size: %d\n", desc_size);
59
60 /* Get Report Descriptor */
61 rpt_desc.size = desc_size;
62 res = ioctl(fd, HIDIOCGRDESC, &rpt_desc);
63 if (res < 0) {
64 perror("HIDIOCGRDESC");
65 } else {
66 printf("Report Descriptor:\n");
67 for (i = 0; i < rpt_desc.size; i++)
68 printf("%hhx ", rpt_desc.value[i]);
69 puts("\n");
70 }
71
72 /* Get Raw Name */
73 res = ioctl(fd, HIDIOCGRAWNAME(256), buf);
74 if (res < 0)
75 perror("HIDIOCGRAWNAME");
76 else
77 printf("Raw Name: %s\n", buf);
78
79 /* Get Physical Location */
80 res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);
81 if (res < 0)
82 perror("HIDIOCGRAWPHYS");
83 else
84 printf("Raw Phys: %s\n", buf);
85
86 /* Get Raw Info */
87 res = ioctl(fd, HIDIOCGRAWINFO, &info);
88 if (res < 0) {
89 perror("HIDIOCGRAWINFO");
90 } else {
91 printf("Raw Info:\n");
92 printf("\tbustype: %d (%s)\n",
93 info.bustype, bus_str(info.bustype));
94 printf("\tvendor: 0x%04hx\n", info.vendor);
95 printf("\tproduct: 0x%04hx\n", info.product);
96 }
97
98 /* Set Feature */
99 buf[0] = 0x9; /* Report Number */
100 buf[1] = 0xff;
101 buf[2] = 0xff;
102 buf[3] = 0xff;
103 res = ioctl(fd, HIDIOCSFEATURE(4), buf);
104 if (res < 0)
105 perror("HIDIOCSFEATURE");
106 else
107 printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
108
109 /* Get Feature */
110 buf[0] = 0x9; /* Report Number */
111 res = ioctl(fd, HIDIOCGFEATURE(256), buf);
112 if (res < 0) {
113 perror("HIDIOCGFEATURE");
114 } else {
115 printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
116 printf("Report data (not containing the report number):\n\t");
117 for (i = 0; i < res; i++)
118 printf("%hhx ", buf[i]);
119 puts("\n");
120 }
121
122 /* Send a Report to the Device */
123 buf[0] = 0x1; /* Report Number */
124 buf[1] = 0x77;
125 res = write(fd, buf, 2);
126 if (res < 0) {
127 printf("Error: %d\n", errno);
128 perror("write");
129 } else {
130 printf("write() wrote %d bytes\n", res);
131 }
132
133 /* Get a report from the device */
134 res = read(fd, buf, 16);
135 if (res < 0) {
136 perror("read");
137 } else {
138 printf("read() read %d bytes:\n\t", res);
139 for (i = 0; i < res; i++)
140 printf("%hhx ", buf[i]);
141 puts("\n");
142 }
143 close(fd);
144 return 0;
145}
146
147const char *
148bus_str(int bus)
149{
150 switch (bus) {
151 case BUS_USB:
152 return "USB";
153 break;
154 case BUS_HIL:
155 return "HIL";
156 break;
157 case BUS_BLUETOOTH:
158 return "Bluetooth";
159 break;
160 case BUS_VIRTUAL:
161 return "Virtual";
162 break;
163 default:
164 return "Other";
165 break;
166 }
167}