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 /* 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 30 const char *bus_str(int bus); 31 32 int 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 147 const char * 148 bus_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 } 168