Hi everyone, need USB-level protocol advice / knowledge!
I've been trying to make a keyboard adapter for the Nintendo Switch (
https://keyboard.gg/) for over a year now. Right now, I've been doing some USB-level sniffing of my NKRO keyboard (Corsair K65) and found out it has 3 interfaces:
- Interface 0: The "BOOT" protocol, 6-KRO (only used if the physical "BIOS" switch is on)
- Interface 1: The Multimedia keys (Volume, Mute, etc.)
- Interface 2: NKRO (From what I've gathered from testing, just enables certain bits if certain keys are pressed.)
I've made a video of me diving into all three of these points (around 1:46):
https://photos.app.goo.gl/7j98istA1GyRfbjE6My questions are these:
- How would one find out about the NKRO bitmappings and what keys they are assigned to? I can do trials myself, but that only covers my U.S. TKL keyboard.
- Is the NKRO format pretty universal (so I'd only have to code for it once) or does each keyboard implement it differently?
- Looking just at the HID Report Descriptors, how can I pick the "interface of interest"? Do I just need to listen to all of them? I feel like only the boot interface for keyboards is clearly defined (SubClass = 1, Protocol = 1) and I'd have to do some real deep logic to take advantage of the NKRO interfaces.
- Is there a term for what I'm doing now? Writing code to translate raw HID data into keyboard inputs?
Attaching some USB properties and pasting them below:
Connection Status Device connected
Current Configuration 1
Speed Full (12 Mbit/s)
Device Address 5
Number Of Open Pipes 3
Device Descriptor Corsair K65 Gaming Keyboard
Offset Field Size Value Description
0 bLength 1 12h
1 bDescriptorType 1 01h Device
2 bcdUSB 2 0200h USB Spec 2.0
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 08h 8 bytes
8 idVendor 2 1B1Ch
10 idProduct 2 1B07h
12 bcdDevice 2 0101h 1.01
14 iManufacturer 1 01h "Corsair"
15 iProduct 1 02h "Corsair K65 Gaming Keyboard"
16 iSerialNumber 1 00h
17 bNumConfigurations 1 01h
Configuration Descriptor 1 Bus Powered, 100 mA
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 02h Configuration
2 wTotalLength 2 0054h
4 bNumInterfaces 1 03h
5 bConfigurationValue 1 01h
6 iConfiguration 1 00h
7 bmAttributes 1 A0h Bus Powered, Remote Wakeup
4..0: Reserved ...00000
5: Remote Wakeup ..1..... Yes
6: Self Powered .0...... No, Bus Powered
7: Reserved (set to one)
(bus-powered for 1.0) 1.......
8 bMaxPower 1 32h 100 mA
Interface Descriptor 0/0 HID, 1 Endpoint
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 00h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 01h
5 bInterfaceClass 1 03h HID
6 bInterfaceSubClass 1 01h Boot Interface
7 bInterfaceProtocol 1 01h Keyboard
8 iInterface 1 00h
HID Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h HID
2 bcdHID 2 0111h 1.11
4 bCountryCode 1 00h
5 bNumDescriptors 1 01h
6 bDescriptorType 1 22h Report
7 wDescriptorLength 2 004Fh 79 bytes
Endpoint Descriptor 81 1 In, Interrupt, 8 ms
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 81h 1 In
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 0008h 8 bytes
6 bInterval 1 08h 8 ms
Interface Descriptor 1/0 HID, 1 Endpoint
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 01h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 01h
5 bInterfaceClass 1 03h HID
6 bInterfaceSubClass 1 00h
7 bInterfaceProtocol 1 00h
8 iInterface 1 00h
HID Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h HID
2 bcdHID 2 0111h 1.11
4 bCountryCode 1 00h
5 bNumDescriptors 1 01h
6 bDescriptorType 1 22h Report
7 wDescriptorLength 2 0017h 23 bytes
Endpoint Descriptor 82 2 In, Interrupt, 8 ms
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 82h 2 In
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 0002h 2 bytes
6 bInterval 1 08h 8 ms
Interface Descriptor 2/0 HID, 1 Endpoint
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 02h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 01h
5 bInterfaceClass 1 03h HID
6 bInterfaceSubClass 1 00h
7 bInterfaceProtocol 1 00h
8 iInterface 1 00h
HID Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h HID
2 bcdHID 2 0111h 1.11
4 bCountryCode 1 00h
5 bNumDescriptors 1 01h
6 bDescriptorType 1 22h Report
7 wDescriptorLength 2 0039h 57 bytes
Endpoint Descriptor 83 3 In, Interrupt, 1 ms
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 83h 3 In
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 000Fh 15 bytes
6 bInterval 1 01h 1 ms
Interface 0 HID Report Descriptor Keyboard
Item Tag (Value) Raw Data
Usage Page (Generic Desktop) 05 01
Usage (Keyboard) 09 06
Collection (Application) A1 01
Usage Page (Keyboard/Keypad) 05 07
Usage Minimum (Keyboard Left Control) 19 E0
Usage Maximum (Keyboard Right GUI) 29 E7
Logical Minimum (0) 15 00
Logical Maximum (1) 25 01
Report Size (1) 75 01
Report Count (8) 95 08
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Report Count (1) 95 01
Report Size (8) 75 08
Input (Cnst,Ary,Abs) 81 01
Report Count (5) 95 05
Report Size (1) 75 01
Usage Page (LEDs) 05 08
Usage Minimum (Num Lock) 19 01
Usage Maximum (Kana) 29 05
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
Report Count (1) 95 01
Report Size (3) 75 03
Output (Cnst,Ary,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 01
Report Count (6) 95 06
Report Size (8) 75 08
Logical Minimum (0) 15 00
Logical Maximum (255) 26 FF 00
Usage Page (Keyboard/Keypad) 05 07
Usage Minimum (Undefined) 19 00
Usage Maximum 2A FF 00
Input (Data,Ary,Abs) 81 00
Usage Page (Consumer Devices) 05 0C
Usage (Undefined) 09 00
Logical Minimum (-128) 15 80
Logical Maximum (127) 25 7F
Report Size (8) 75 08
Report Count (8) 95 08
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) B1 02
End Collection C0
Interface 1 HID Report Descriptor Consumer Control
Item Tag (Value) Raw Data
Usage Page (Consumer Devices) 05 0C
Usage (Consumer Control) 09 01
Collection (Application) A1 01
Usage Minimum (Undefined) 19 00
Usage Maximum 2A FF 0F
Logical Minimum (0) 15 00
Logical Maximum (4095) 26 FF 0F
Report Size (16) 75 10
Report Count (1) 95 01
Input (Data,Ary,Abs) 81 00
End Collection C0
Interface 2 HID Report Descriptor Keyboard
Item Tag (Value) Raw Data
Usage Page (Generic Desktop) 05 01
Usage (Keyboard) 09 06
Collection (Application) A1 01
Usage Page (Keyboard/Keypad) 05 07
Usage Minimum (Keyboard Left Control) 19 E0
Usage Maximum (Keyboard Right GUI) 29 E7
Logical Minimum (0) 15 00
Logical Maximum (1) 25 01
Report Size (1) 75 01
Report Count (8) 95 08
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Usage Minimum (Undefined) 19 00
Usage Maximum (Keypad =) 29 67
Logical Minimum (0) 15 00
Logical Maximum (1) 25 01
Report Size (1) 75 01
Report Count (104) 95 68
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Usage (Keypad Comma) 09 85
Usage Minimum (Keyboard International 1) 19 87
Usage Maximum (Keyboard International 5) 29 8B
Usage (Keyboard LANG1) 09 90
Usage (Keyboard LANG2) 09 91
Logical Minimum (0) 15 00
Logical Maximum (1) 25 01
Report Size (1) 75 01
Report Count (8) 95 08
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
End Collection C0