检查某个USB端口以获取C Linux上的设备fd

时间:2017-10-27 14:01:18

标签: c linux ioctl input-devices

我正在编写一个程序来检查每个/dev/input/eventX并使用ioctl我可以获得它的功能并检查它是什么(鼠标,键盘,触摸屏)。

现在我需要检查某些USB输出(端口)是否连接了设备,我打开它并执行与/dev/input/eventX相同的操作。 我在/sys/bus/usb/devices/中找到了一些符号链接,其中似乎是关于USB端口的商店信息,但我不确定。我尝试用libudev打开它,但它寻找子系统中的所有文件" USB"但我只需要举例/sys/bus/usb/devices/3-2/

我需要什么:

  1. 检查某个USB端口(只有我在定义的某处硬编码或通过命令行)
  2. 如果设备已连接,请打开dev的fd并使用ioctl获取信息
  3. 如果它(例如鼠标)程序开始工作,则说它找不到设备......
  4. 这就足以说明如何做到这一点我不需要完整的代码。

    只需普通C就可以使用像libudev这样的lib

1 个答案:

答案 0 :(得分:3)

我找到一个适合我的任务的解决方案,可能也是对它的帮助,所以我在这里留下这个例子。 我使用libudev库

我找到了一些例子并稍作改动:

1)创建枚举并添加子系统:

enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "input");

您可以在ls /sys/class中查找该文件夹中的子系统我没有看到input,只是尝试添加其工作。

2)使用foreach获取列表条目和列表:

list = udev_enumerate_get_list_entry(enumerate);

    udev_list_entry_foreach(node, list) 
    {
        char *str = NULL;
        path = udev_list_entry_get_name(node);
        dev = udev_device_new_from_syspath(udev, path);
        if  (str = strstr(path, REQUESTED_USB_PORT))
        {
             if (str = strstr(str, "event"))
             {
                  dev_path = strdup(udev_device_get_devnode(dev));
                  udev_device_unref(dev);
                  break;
             }
        }
        udev_device_unref(dev);
    }

所以我们收到这样的路径:

/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/0003:046D:C31C.0005/input/input9
/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/0003:046D:C31C.0005/input/input9/event6

为什么我要告诉你两条路?因为你可以看到它的返回字符串看起来是一样的,但我们只需要一个,其中显示了eventX REQUESTED_USB_PORT它是一个定义端口,您需要检查我的案例"1-1.6:1.0"

找到你需要的东西很多方法我停在cat /proc/bus/input/devices

显示每个设备的输出:

I: Bus=0003 Vendor=046d Product=c31c Version=0110
N: Name="Logitech USB Keyboard"
P: Phys=usb-0000:00:1a.0-1.6/input0
S: Sysfs=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.6/1-1.6:1.0/0003:046D:C31C.0005/input/input9
U: Uniq=
H: Handlers=sysrq kbd event6 leds 
B: PROP=0
B: EV=120013
B: KEY=1000000000007 ff9f207ac14057ff febeffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=1f

另一步是让/dev/input/eventX使用udev_device_get_devnode()函数获取它,该函数返回带路径的字符串。

所以我写了我的get_devinfo_fromusb()代码我在上面发布了哪个返回字符串/dev/input/eventXNULL如果不是NULL我做了这样的事情:

调用另一个函数并将device_path作为参数传递

int get_dev_type(char *dev_event_path)
{
    int dev_fd;
    unsigned long eventBits = 0;

    if ((dev_fd = open(dev_event_path, O_RDONLY)) < 0)
    {
        puts("Dont have access to open file {%s}");
        puts("Run as root");
        exit(1);
    }
    ioctl(dev_fd, EVIOCGBIT(0, EV_MAX), &eventBits);

    if (((eventBits >> EV_KEY) & 1) &&
        ((eventBits >> EV_SYN) & 1) &&
        ((eventBits >> EV_REL) & 1) &&
        ((eventBits >> EV_MSC) & 1)) {
        puts("look like mouse");
        close(dev_fd);
        return (MOUSE_TYPE);
    }

    if (((eventBits >> EV_KEY) & 1) &&
        ((eventBits >> EV_LED) & 1) &&
        ((eventBits >> EV_REP) & 1)) {
        puts("looks like kbd");
        close(dev_fd);
        return (KBD_TYPE);
}

}

我认为这些小例子足以弄明白正在发生什么。因此,您可以检查某些USB端口并获取有关该设备(鼠标或键盘)的信息,您还可以检查耳机触摸屏等。