hid-example.c 3.9 KB

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