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



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

现在我需要检查某个USB输出(端口),如果设备连接到它上,我打开它,并像使用/dev/input/eventX一样进行操作。我在/sys/bus/usb/devices/中发现了一些符号链接,这里似乎是关于USB端口的存储信息,但我不确定。我试着用libudev打开它,但它在子系统"USB"中查找所有文件,但我只需要/sys/bus/usb/devices/3-2/

我需要什么:

  1. 检查特定的USB端口(仅限于我在define中硬编码的端口,或通过命令行)
  2. 如果设备连接在上面,打开dev的fd并使用ioctl获取信息
  3. 如果它(例如鼠标)程序开始工作,否则它会说找不到设备

这将是足够的描述如何做到这一点我不需要完整的代码。

只需要普通的C就可以使用一些类似libudev 的库

我找到了一个适合我任务的解决方案,它可能也会对某人有所帮助,所以我把这个例子留在这里。我使用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端口,并获得有关该设备(鼠标或键盘)的信息,你也可以检查耳机触摸屏等。

相关内容

  • 没有找到相关文章

最新更新