#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <pthread.h>
// 定义要打开的VID/PID, 若无需匹配PID则定义PID为0
uint16_t VID = 0x28e1;
uint16_t PID = 0;
struct hidraw_devinfo {
unsigned int bustype;
unsigned short vendor;
unsigned short product;
};
#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
int fds[10] = {0};
int fds_max = 0;
int router = 0;
// 按整齐的格式输出到stdout
void printArr(uint8_t *arr, int len) {
static char output[1024];
int i, off = 0;
for(i = 0; i < len; i++) {
if (i%16==0)
off += sprintf(output+off, "\n\t");
if (i%4==0)
off += sprintf(output+off, " ");
off += sprintf(output+off, "%02x ", arr[i]);
{ // ==> characters
static char str[20] = {0};
sprintf(str+i%16, "%c", isprint(arr[i])?arr[i]:'.');
if (i%16==15 || i==len-1) {
off += sprintf(output+off, " > %s", str);
memset(str, 0, 20);
}
}
}
printf("%s\n\t------\n", output);
}
void hid_open_dev(uint16_t vendor_id, uint16_t product_id)
{
int i, fd = 0;
char node[100];
fds_max = 0;
for (i = 0; i < 20; i++) {
sprintf(node, "/dev/hidraw%d", i);
fd = open(node, O_RDWR | O_NONBLOCK);
if (fd > 0) {
struct hidraw_devinfo rawinfo;
ioctl(fd, HIDIOCGRAWINFO, &rawinfo);
if ((vendor_id == 0 || vendor_id == rawinfo.vendor) &&
(product_id == 0 || product_id == rawinfo.product)) {
fds[fds_max++] = fd;
printf("...... found hidraw%d, opened as fd=%d\n", i, fd);
} else {
close(fd);
fd = 0;
}
}
}
}
void hid_write_hidraw(uint8_t *cmd, int len)
{
int fd = fds[0];
int ret = write(fd, cmd, 64);
if (ret > 0) {
printf("↓↓ raw[0] write %d bytes:", ret);
printArr(cmd, ret);
} else {
printf("↓↓ raw[0] write fail? ret=%d.", ret);
}
}
void * hid_read_hidraw(void *arg)
{
int i = (long)arg, fd = fds[i];
uint8_t redir[64] = {0xa1, 0x18};
while(1) {
uint8_t buf[64] = {0};
int ret;
usleep(1000);
ret = read(fd, buf, 64);
if (ret > 0) {
printf("↑↑ raw[%d] read %d bytes:", i, ret);
printArr(buf, ret);
}
if (errno == 5) {
printf("dev disconnected.\n");
exit(0);
}
}
}