Вопрос или проблема
У меня возникла проблема с клавиатурой, которую я купил в Китае, это клавиатура, предназначенная для osu! Однако производитель предоставляет драйверы только для Windows. Несмотря на нажатие клавиши, мне возвращается буква c
.
Я пробовал многие методы, такие как прослушивание необработанного ввода с клавиатуры, но он всегда возвращает мне 01 00 06 ...
(когда клавиша нажата) или 01 00 00 ...
(когда клавиша не нажата). Я не могу получить, какая клавиша нажата в момент прослушивания.
Я также пробовал evtest
, но когда я нажимаю, ничего не происходит, хотя evdev
возвращает мне, что присутствуют три клавиши:
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x1189 product 0x8890 version 0x110
Input device name: "HID 1189:8890"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 272 (BTN_LEFT)
Event code 273 (BTN_RIGHT)
Event code 274 (BTN_MIDDLE)
Event type 2 (EV_REL)
Event code 0 (REL_X)
Event code 1 (REL_Y)
Event code 8 (REL_WHEEL)
Event code 11 (REL_WHEEL_HI_RES)
Event type 4 (EV_MSC)
Event code 4 (MSC_SCAN)
Я также пробовал использовать hidapi
, но когда я пытаюсь проверить, нажата ли клавиша (с помощью if (event.type == EV_KEY
), это ничего не возвращает.
Также я пробовал получать необработанный ввод с помощью WireShark, и он возвращает мне некоторые разные байты при нажатии клавиши (поэтому я знаю, что клавиши распознаются как разные).
Что же я могу сделать? Мне действительно нужно запрограммировать эту клавиатуру, но большинство инструментов HID разочаровывают меня и всегда возвращают необработанный ввод без информации о том, какая клавиша нажата. Я пытаюсь написать драйвер для Linux для этой клавиатуры, но не знаю, с чего начать.
Вот вывод usbhid-dump
:
001:008:003:DESCRIPTOR 1736873035.175572
05 01 09 02 A1 01 09 01 A1 00 05 09 19 01 29 03
15 00 25 01 75 01 95 03 81 02 75 05 95 01 81 01
05 01 09 30 09 31 09 38 15 81 25 7F 75 08 95 03
81 06 C0 C0
001:008:002:DESCRIPTOR 1736873035.176839
05 01 09 06 A1 01 85 01 05 07 19 E0 29 E7 15 00
25 01 75 01 95 08 81 02 95 01 75 08 81 03 95 08
75 01 05 08 19 01 29 05 91 02 95 09 75 08 15 00
25 FF 05 07 19 00 29 FF 81 00 C0 05 0C 09 01 A1
01 85 02 95 01 75 10 16 00 00 26 FF 02 1A 00 00
2A FF 02 81 00 C0
001:008:000:DESCRIPTOR 1736873035.177888
05 01 09 06 A1 01 85 01 05 07 19 E0 29 E7 15 00
25 01 75 01 95 08 81 02 95 01 75 08 81 01 95 03
75 01 05 08 19 01 29 03 91 02 95 05 75 01 91 01
95 06 75 08 26 FF 00 05 07 19 00 29 91 81 00 C0
Я выяснил, что в клавиатуре есть четыре прерывания (0x02
, которое возвращает мне случайные байты, 0x81
, которое сообщает, нажата ли клавиша или нет, но без информации о том, какая клавиша нажата, 0x82
и 0x83
)
Вот вывод lsusb
:
Bus 001 Device 005: ID 1189:8890 Acer Communications & Multimedia
Negotiated speed: Full Speed (12Mbps)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 [unknown]
bDeviceSubClass 0 [unknown]
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x1189 Acer Communications & Multimedia
idProduct 0x8890
bcdDevice 0.00
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x006d
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 (null)
wDescriptorLength 64
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 [unknown]
bInterfaceProtocol 0
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 (null)
wDescriptorLength 36
Report Descriptor: (length is 36)
Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
(null)
Item(Local ): (null), data= [ 0x01 ] 1
(null)
Item(Main ): (null), data= [ 0x01 ] 1
Application
Item(Global): (null), data= [ 0x03 ] 3
Item(Local ): (null), data= [ 0x02 ] 2
(null)
Item(Global): (null), data= [ 0x00 ] 0
Item(Global): (null), data= [ 0x00 0xff ] 65280
Item(Global): (null), data= [ 0x08 ] 8
Item(Global): (null), data= [ 0x40 ] 64
Item(Main ): (null), data= [ 0x06 ] 6
Data Variable Relative No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Local ): (null), data= [ 0x02 ] 2
(null)
Item(Global): (null), data= [ 0x00 ] 0
Item(Global): (null), data= [ 0x00 0xff ] 65280
Item(Global): (null), data= [ 0x08 ] 8
Item(Global): (null), data= [ 0x40 ] 64
Item(Main ): (null), data= [ 0x06 ] 6
Data Variable Relative No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield
Item(Main ): (null), data=none
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 [unknown]
bInterfaceProtocol 0
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 (null)
wDescriptorLength 86
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 (null)
wDescriptorLength 52
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 10
Device Status: 0x0000
(Bus Powered)
И вот выводы, которые WireShark дает мне для выбранных клавиш:
Клавиша 1
: 00 01 03 00 00 00 09 21 00 01 00 01 22 56 00 07 05 83 03 04 00 0a 09 04 03 00 01 03 01 02 00 09 21 10 01 00 01 22 34 00 07 05 82 03 04 00 0a 0e 03 6b 00 65 00 79 00 35 00 35 00 32 00 04 03 09 04 0e 03 77 00 63 00 68 00 2e 00 63 00 6e 00 0c 03 43 00 48 00 35 00 35 00 39 00 90 01 32 e0 ff 75 f0 0e a4 24 2d f5 82 e4 34 01 f5 83 e0 64 03 70 5c 90 01 36 e0 70 56 ef 75 f0 0e a4 24 39
Клавиша 2
: 90 01 32 f0 22 90 01 37 e0 ff a3 e0 fe c3 9f 40 03 02 1d 1a ed 64 01 60 03 02 1c f8 ee 14 60 32 14 60 41 14 60 50 14 60 5f 24 04 70 75 90 01 35 e0 ff 75 f0 0e a4 24 3e f5 82 e4 34 01 f5 83 e0 90 01 d0 f0 ef 75 f0 0e a4 24 3f f5 82 e4 34 01 80 46 90 01 35 e0 ff 75 f0 0e a4 24 41 f5 82 e4 34 01 80 34 90 01 35 e0 ff 75 f0 0e a4 24 43 f5 82 e4 34 01 80 22 90 01 35 e0 ff 75 f0 0e a4
Клавиша 3
: e4 f0 90 01 47 75 f0 0e ed 12 0f ad ec 75 f0 0e a4 25 83 f5 83 e4 f0 0d bd 00 01 0c ed 64 09 4c 60 03 02 1d 29 22 48 01 c4 00 00 00 00 00 00 00 00 41 01 31 00 60 7e 01 3a 01 01 01 00 00 06 00 00 00 00 00 00 00 00 02 01 01 00 00 06 00 00 00 00 00 00 00 00 03 01 01 00 00 06 00 00 00 00 00 00 00 00 04 01 01 00 00 06 00 00 00 00 00 00 00 00 05 01 01 00 00 06 00 00 00 00 00 00 00 00
.
Ответ или решение
Чтобы решить проблему с клавиатурой, которую вы приобрели, и которая предназначена для игры osu!, но не имеет корректных драйверов под Linux, нужно глубже изучить взаимодействие с HID-устройством и рассмотреть возможность написания собственного драйвера. Ваши попытки, включая использование evtest
, hidapi
и анализа трафика через WireShark, дают определенные подсказки, но до конца не решают проблему.
Теория
Клавиатуры и другие периферийные устройства используют протоколы, основанные на Human Interface Device (HID), для взаимодействия с компьютером. Сообщения HID содержат отчеты с информацией о действиях пользователя, таких как нажатие клавиш. В частности, каждый отчет может содержать информацию о том, какая клавиша была нажата, но формат данных зависит от устройства.
В вашем случае, несмотря на детектирование трех клавиш (EV_KEY
272, 273 и 274), данные не соответствуют привычному формату компьютерных клавиатур. Вероятно, это связано с нестандартной реализацией протокола производителем.
Пример
Исходя из информации оdescriptor-ах, устройство предоставляет несколько интерфейсов, и один из них, вероятно, использует нестандартный формат отчетов, так как данные, захваченные в WireShark, показывают различия в байтах при нажатии различных клавиш. Заметьте, что общий формат описания включает в себя Page (65280), что может указывать на стороние назначения ввода.
Применение
-
Анализ захваченного трафика: Используйте WireShark, чтобы внимательнее рассмотреть данные, поступающие от каждого нажатия клавиши. Ищите паттерны. Например, если конкретный байт изменяется при нажатии определенной клавиши, то это может быть идентификатор этой клавиши.
-
Углубленный анализ через
hidapi
: Хотя вы уже пробовалиhidapi
, возможно, стоит углубиться в документацию и поискать примеры работы с нестандартными HID-устройствами. Попробуйте использоватьhid_read()
для считывания полного отчета с устройства и посимвольного анализа полученных данных. -
Написание кастомного драйвера: Если предыдущие шаги не помогают, стоит рассмотреть написание драйвера. В Linux драйверы для HID-устройств пишутся на C. Вы можете начать с базового драйвера, который просто считывает и выводит в syslog данные с устройства. Со временем, добавив логику интерпретации данных, вы сможете преобразовывать их в понятные нажатия клавиш.
-
Сообщество и библиотеки: Изучите, возможно, есть уже существующие проекты или фреймворки, которые могут работать с нестандартными HID-драйверами. Например, libusb может предоставить интерфейс для реализации низкоуровневого взаимодействия с устройством в случае, если стандартный драйвер не подходит.
Таким образом, для успешного решения проблемы с вашим устройством необходимо последовательно протестировать и проанализировать полученные данные, потенциально разрабатывая собственное решение на основе собранной информации. Обращение к сообществу экспертов может также предоставить ценные инсайты и готовые решения.