检查某些 USB 端口以在 C Linux 上获取设备 fd
Check certain USB port to get device fd on C Linux
我正在编写一个程序来检查每个 /dev/input/eventX
并使用 ioctl 我可以获得它的功能并检查它是什么(鼠标、键盘、触摸屏)。
现在我需要检查某些 USB 输出(端口)是否连接了设备,我打开它并执行与 /dev/input/eventX
相同的操作。
我在 /sys/bus/usb/devices/
中找到了一些符号链接,它似乎是关于 USB 端口的存储信息,但我不确定。我尝试用 libudev
打开它,但它寻找子系统 "USB" 中的所有文件,但我只需要 /sys/bus/usb/devices/3-2/
我需要的:
- 检查特定的 USB 端口(只有我在定义中硬编码的端口,或者通过命令行)
- 如果设备连接在上面,打开 dev 的 fd 并使用 ioctl 获取信息
- 如果它(例如鼠标)程序开始工作,否则它说找不到设备...
描述如何操作就足够了我不需要完整的代码。
只需要纯 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
为什么我给你两条路?因为如您所见,return 字符串看起来一样,但我们只需要一个,其中显示了 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()
函数获取它,其中 return 带有路径的字符串。
所以我用代码 i post 写了我的 get_devinfo_fromusb()
,上面的 return 字符串带有 /dev/input/eventX
或 NULL
如果不是 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 端口并获取有关该设备(鼠标或键盘)的信息,您还可以检查耳机触摸屏等。
我正在编写一个程序来检查每个 /dev/input/eventX
并使用 ioctl 我可以获得它的功能并检查它是什么(鼠标、键盘、触摸屏)。
现在我需要检查某些 USB 输出(端口)是否连接了设备,我打开它并执行与 /dev/input/eventX
相同的操作。
我在 /sys/bus/usb/devices/
中找到了一些符号链接,它似乎是关于 USB 端口的存储信息,但我不确定。我尝试用 libudev
打开它,但它寻找子系统 "USB" 中的所有文件,但我只需要 /sys/bus/usb/devices/3-2/
我需要的:
- 检查特定的 USB 端口(只有我在定义中硬编码的端口,或者通过命令行)
- 如果设备连接在上面,打开 dev 的 fd 并使用 ioctl 获取信息
- 如果它(例如鼠标)程序开始工作,否则它说找不到设备...
描述如何操作就足够了我不需要完整的代码。
只需要纯 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
为什么我给你两条路?因为如您所见,return 字符串看起来一样,但我们只需要一个,其中显示了 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()
函数获取它,其中 return 带有路径的字符串。
所以我用代码 i post 写了我的 get_devinfo_fromusb()
,上面的 return 字符串带有 /dev/input/eventX
或 NULL
如果不是 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 端口并获取有关该设备(鼠标或键盘)的信息,您还可以检查耳机触摸屏等。