177 lines · 3.8 KB · C
RawDownload
/* * Hidraw Userspace Example * * Copyright (c) 2010 Alan Ott <alan@signal11.us> * Copyright (c) 2010 Signal 11 Software * * The code may be used by anyone for any purpose, * and can serve as a starting point for developing * applications using hidraw. */ /* Linux */#include <linux/types.h>#include <linux/input.h>#include <linux/hidraw.h> /* * Ugly hack to work around failing compilation on systems that don't * yet populate new version of hidraw.h to userspace. */#ifndef HIDIOCSFEATURE#warning Please have your distro update the userspace kernel headers#define HIDIOCSFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)#define HIDIOCGFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)#endif /* Unix */#include <sys/ioctl.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h> /* C */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h> const char *bus_str(int bus); int main(int argc, char **argv){	int fd;	int i, res, desc_size = 0;	char buf[256];	struct hidraw_report_descriptor rpt_desc;	struct hidraw_devinfo info; 	/* Open the Device with non-blocking reads. In real life,	   don't use a hard coded path; use libudev instead. */	fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK); 	if (fd < 0) {		perror("Unable to open device");		return 1;	} 	memset(&rpt_desc, 0x0, sizeof(rpt_desc));	memset(&info, 0x0, sizeof(info));	memset(buf, 0x0, sizeof(buf)); 	/* Get Report Descriptor Size */	res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);	if (res < 0)		perror("HIDIOCGRDESCSIZE");	else		printf("Report Descriptor Size: %d\n", desc_size); 	/* Get Report Descriptor */	rpt_desc.size = desc_size;	res = ioctl(fd, HIDIOCGRDESC, &rpt_desc);	if (res < 0) {		perror("HIDIOCGRDESC");	} else {		printf("Report Descriptor:\n");		for (i = 0; i < rpt_desc.size; i++)			printf("%hhx ", rpt_desc.value[i]);		puts("\n");	} 	/* Get Raw Name */	res = ioctl(fd, HIDIOCGRAWNAME(256), buf);	if (res < 0)		perror("HIDIOCGRAWNAME");	else		printf("Raw Name: %s\n", buf); 	/* Get Physical Location */	res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);	if (res < 0)		perror("HIDIOCGRAWPHYS");	else		printf("Raw Phys: %s\n", buf); 	/* Get Raw Info */	res = ioctl(fd, HIDIOCGRAWINFO, &info);	if (res < 0) {		perror("HIDIOCGRAWINFO");	} else {		printf("Raw Info:\n");		printf("\tbustype: %d (%s)\n",			info.bustype, bus_str(info.bustype));		printf("\tvendor: 0x%04hx\n", info.vendor);		printf("\tproduct: 0x%04hx\n", info.product);	} 	/* Set Feature */	buf[0] = 0x9; /* Report Number */	buf[1] = 0xff;	buf[2] = 0xff;	buf[3] = 0xff;	res = ioctl(fd, HIDIOCSFEATURE(4), buf);	if (res < 0)		perror("HIDIOCSFEATURE");	else		printf("ioctl HIDIOCGFEATURE returned: %d\n", res); 	/* Get Feature */	buf[0] = 0x9; /* Report Number */	res = ioctl(fd, HIDIOCGFEATURE(256), buf);	if (res < 0) {		perror("HIDIOCGFEATURE");	} else {		printf("ioctl HIDIOCGFEATURE returned: %d\n", res);		printf("Report data (not containing the report number):\n\t");		for (i = 0; i < res; i++)			printf("%hhx ", buf[i]);		puts("\n");	} 	/* Send a Report to the Device */	buf[0] = 0x1; /* Report Number */	buf[1] = 0x77;	res = write(fd, buf, 2);	if (res < 0) {		printf("Error: %d\n", errno);		perror("write");	} else {		printf("write() wrote %d bytes\n", res);	} 	/* Get a report from the device */	res = read(fd, buf, 16);	if (res < 0) {		perror("read");	} else {		printf("read() read %d bytes:\n\t", res);		for (i = 0; i < res; i++)			printf("%hhx ", buf[i]);		puts("\n");	}	close(fd);	return 0;} const char *bus_str(int bus){	switch (bus) {	case BUS_USB:		return "USB";		break;	case BUS_HIL:		return "HIL";		break;	case BUS_BLUETOOTH:		return "Bluetooth";		break;	case BUS_VIRTUAL:		return "Virtual";		break;	default:		return "Other";		break;	}}