Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Hidraw Userspace Example
0004  *
0005  * Copyright (c) 2010 Alan Ott <alan@signal11.us>
0006  * Copyright (c) 2010 Signal 11 Software
0007  *
0008  * The code may be used by anyone for any purpose,
0009  * and can serve as a starting point for developing
0010  * applications using hidraw.
0011  */
0012 
0013 /* Linux */
0014 #include <linux/types.h>
0015 #include <linux/input.h>
0016 #include <linux/hidraw.h>
0017 
0018 /*
0019  * Ugly hack to work around failing compilation on systems that don't
0020  * yet populate new version of hidraw.h to userspace.
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 /* Unix */
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 /* C */
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     /* Open the Device with non-blocking reads. In real life,
0056        don't use a hard coded path; use libudev instead. */
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     /* Get Report Descriptor Size */
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     /* Get Report Descriptor */
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     /* Get Raw Name */
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     /* Get Physical Location */
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     /* Get Raw Info */
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     /* Set Feature */
0114     buf[0] = 0x9; /* Report Number */
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     /* Get Feature */
0125     buf[0] = 0x9; /* Report Number */
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     /* Send a Report to the Device */
0138     buf[0] = 0x1; /* Report Number */
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     /* Get a report from the device */
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 }