android - 无法使用 C 读取 USB HID RFID 读取器

标签 android c linux input hid

我有一个便宜的 USB-RFID 阅读器。该阅读器是一个 HID 键盘(无按钮)。 我需要捕获读取器的输出而不将其写入任何控制台。 我在这里找到了这段代码: https://stackoverflow.com/a/7672324/4500123

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>

int main(int argc, char* argv[])
{
    struct input_event ev[64];
    int fevdev = -1;
    int result = 0;
    int size = sizeof(struct input_event);
    int rd;
    int value;
    char name[256] = "Unknown";
    char *device = "/dev/input/event3";


    fevdev = open(device, O_RDONLY);
    if (fevdev == -1) {
        printf("Failed to open event device.\n");
        exit(1);
    }

    result = ioctl(fevdev, EVIOCGNAME(sizeof(name)), name);
    printf ("Reading From : %s (%s)\n", device, name);

    printf("Getting exclusive access: ");
    result = ioctl(fevdev, EVIOCGRAB, 1);
    printf("%s\n", (result == 0) ? "SUCCESS" : "FAILURE");

   while (1)
    {
        if ((rd = read(fevdev, ev, size * 64)) < size) {
            break;
        }

        value = ev[0].value;

        if (value != ' ' && ev[1].value == 1 && ev[1].type == 1) {
            printf ("Code[%d]\n", (ev[1].code));
        }
    }

    printf("Exiting.\n");
    result = ioctl(fevdev, EVIOCGRAB, 1);
    close(fevdev);
    return 0;
}

这段代码应该可以工作。我让它在我的 RaspberryPI 上运行没有问题。 我现在尝试让这段代码在我的 Android 平板电脑(有 root)上运行。但我经常遗漏字母或代码不完整。

如果我写入文本文件,所有字母都可以毫无问题地传输。但是使用代码它无法正常工作。

我该怎么做才能找出问题所在?是时间问题吗?

最佳答案

当然,您偶尔会遗漏事件:您读取了多达 64 个事件结构,但假设您恰好有两个,无论 rd 是读取的数量。

您应该首先验证您是否具有完整的输入事件 ((rd % sizeof (struct input_event)) == 0)。如果没有,您当然应该提醒用户,因为这种情况非常罕见(因为永远不会发生),然后中止。

然后,检查您收到了多少实际输入事件。 (这将是 rd/sizeof (struct input_event)。)您不能依赖成对发生的事件,因为内核内部时序会影响事情,即使设备报告它们在连续的 HID 消息中。相反,您需要分别检查每个事件,并检查您阅读的每个事件。

就我个人而言,我建议使用 finite-state machine为了这。让您的外循环使用整个标识符。在外循环中,最初丢弃所有事件,但可能开始新标识符的事件除外。在内部循环中接收这些标识符,以终止标识符结束。我会尽量一次只读取单个事件,以使内部循环更简单。 (每秒最多有一千个事件左右,因此额外的系统调用开销在这里完全不相关。)

我有一个完整的条形码示例here - 您的用例几乎没有区别。仔细检查barcode_read()函数;它包括一个超时,而不是“挂起”(永远等待)如果一个新的输入事件序列(对于条形码,一个数字序列后跟一个非数字)在运行中被打断,比如因为阅读器出现故障或某物。我很确定您可以轻松修改它以适用于您的用例。

关于android - 无法使用 C 读取 USB HID RFID 读取器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33925582/

相关文章:

c - 如何查找C代码中的段错误?

c - 宏在计算其位后不会将预期值分配给变量

linux - BASH:Sudo Cat 对 Shell 脚本的多行命令

android - setText 后的 TextView 和 Size

android - 如何在 fragment 内实现 viewpager?

java - Opengl 旋转对象

Linux:如何将 USB 驱动程序分配给设备

Android studio 加载图片 url 到 listview

c - inotify_add_watch 用于几个掩码

linux - 如何让 Bash 自动将每个命令的输出传输到 tee 之类的东西?