Проверьте определенный порт USB, чтобы получить устройство FD на C Linux
Я пишу программу, которая проверяет каждый /dev/input/eventX
и с помощью ioctl я могу получить его возможности и проверить, что это такое (мышь, клавиатура, сенсорный экран).
Теперь мне нужно проверить определенный USB-выход (порт), если к нему подключено устройство, я открываю его и делаю то же, что и с /dev/input/eventX
, Я нахожу некоторую символическую ссылку в /sys/bus/usb/devices/
Похоже, здесь хранится информация о портах USB, но я не уверен. Я пытаюсь открыть это с libudev
но он ищет все файлы в подсистеме "USB", но мне нужно только для примера /sys/bus/usb/devices/3-2/
Что мне нужно:
- Проверьте определенный USB-порт (только тот, который я жестко запрограммировал где-то в define, или пропустите через командную строку)
- Если к нему подключено устройство, откройте fd of dev и получите информацию с помощью ioctl
- если это (например, мышь) программа начинает работать, иначе он говорит, что устройство не найдено...
Было бы достаточно описания, как это сделать, мне не нужен полный код.
Нужен только простой C, можно использовать какой-нибудь lib вроде libudev
1 ответ
Я нахожу решение, которое подходит для моих задач, может быть, кому-то тоже поможет, поэтому я оставлю этот пример здесь. Я использую библиотеку 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/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 и получить информацию об этом устройстве (мышь или клавиатура), а также проверить сенсорный экран наушников и так далее.